index.tsx 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. import AsyncStorage from '@react-native-async-storage/async-storage';
  2. import { useRouter } from 'expo-router';
  3. import React, { useEffect, useState } from 'react';
  4. import {
  5. Alert,
  6. ImageBackground,
  7. ScrollView,
  8. StatusBar,
  9. StyleSheet,
  10. Switch,
  11. Text,
  12. TouchableOpacity,
  13. View,
  14. } from 'react-native';
  15. import { useSafeAreaInsets } from 'react-native-safe-area-context';
  16. import { Images } from '@/constants/images';
  17. import { useAuth } from '@/contexts/AuthContext';
  18. import { logoff } from '@/services/user';
  19. export default function SettingScreen() {
  20. const router = useRouter();
  21. const insets = useSafeAreaInsets();
  22. const { logout } = useAuth();
  23. const [animalChecked, setAnimalChecked] = useState(true);
  24. const [vibratorChecked, setVibratorChecked] = useState(true);
  25. useEffect(() => {
  26. loadSettings();
  27. }, []);
  28. const loadSettings = async () => {
  29. try {
  30. const animal = await AsyncStorage.getItem('closeAnimal');
  31. const vibrator = await AsyncStorage.getItem('closeVibrator');
  32. setAnimalChecked(animal !== 'true');
  33. setVibratorChecked(vibrator !== 'true');
  34. } catch (error) {
  35. console.error('加载设置失败:', error);
  36. }
  37. };
  38. const handleBack = () => {
  39. router.back();
  40. };
  41. const handleAnimalChange = async (value: boolean) => {
  42. setAnimalChecked(value);
  43. await AsyncStorage.setItem('closeAnimal', (!value).toString());
  44. };
  45. const handleVibratorChange = async (value: boolean) => {
  46. setVibratorChecked(value);
  47. await AsyncStorage.setItem('closeVibrator', (!value).toString());
  48. };
  49. const handleLogout = () => {
  50. Alert.alert('提示', '确定要退出登录吗?', [
  51. { text: '取消', style: 'cancel' },
  52. {
  53. text: '确定',
  54. onPress: async () => {
  55. await logout();
  56. router.back();
  57. }
  58. }
  59. ]);
  60. };
  61. const handleLogoff = () => {
  62. Alert.alert('提示', '确定要注销当前账号吗?', [
  63. { text: '取消', style: 'cancel' },
  64. {
  65. text: '确定',
  66. style: 'destructive',
  67. onPress: async () => {
  68. try {
  69. const res = await logoff();
  70. if (res) {
  71. await logout();
  72. router.back();
  73. }
  74. } catch (error) {
  75. console.error('注销失败:', error);
  76. Alert.alert('提示', '注销失败');
  77. }
  78. }
  79. }
  80. ]);
  81. };
  82. const handleShowAgreement = (type: string) => {
  83. const agreementType = type === 'user' ? 'user.html' : 'privacy.html';
  84. console.log('跳转到协议页面:', agreementType);
  85. router.push(`/agreement?type=${agreementType}` as any);
  86. };
  87. return (
  88. <ImageBackground
  89. source={{ uri: Images.mine.kaixinMineBg }}
  90. style={styles.container}
  91. resizeMode="cover"
  92. >
  93. <StatusBar barStyle="light-content" />
  94. {/* 顶部导航 */}
  95. <View style={[styles.header, { paddingTop: insets.top }]}>
  96. <TouchableOpacity style={styles.backBtn} onPress={handleBack}>
  97. <Text style={styles.backIcon}>‹</Text>
  98. </TouchableOpacity>
  99. <Text style={styles.headerTitle}>设置</Text>
  100. <View style={styles.placeholder} />
  101. </View>
  102. <ScrollView style={styles.scrollView} showsVerticalScrollIndicator={false}>
  103. {/* 通知设置 */}
  104. <Text style={styles.sectionTitle}>通知</Text>
  105. <View style={styles.card}>
  106. <View style={styles.menuItem}>
  107. <Text style={styles.menuText}>开箱动画</Text>
  108. <Switch
  109. value={animalChecked}
  110. onValueChange={handleAnimalChange}
  111. trackColor={{ false: '#e0e0e0', true: '#FC7D2E' }}
  112. thumbColor="#fff"
  113. />
  114. </View>
  115. <View style={styles.divider} />
  116. <View style={styles.menuItem}>
  117. <Text style={styles.menuText}>开箱震动</Text>
  118. <Switch
  119. value={vibratorChecked}
  120. onValueChange={handleVibratorChange}
  121. trackColor={{ false: '#e0e0e0', true: '#FC7D2E' }}
  122. thumbColor="#fff"
  123. />
  124. </View>
  125. </View>
  126. {/* 关于 */}
  127. <Text style={styles.sectionTitle}>关于</Text>
  128. <View style={styles.card}>
  129. <TouchableOpacity
  130. style={styles.menuItem}
  131. onPress={() => handleShowAgreement('user')}
  132. >
  133. <Text style={styles.menuText}>用户协议</Text>
  134. <Text style={styles.arrow}>›</Text>
  135. </TouchableOpacity>
  136. <View style={styles.divider} />
  137. <TouchableOpacity
  138. style={styles.menuItem}
  139. onPress={() => handleShowAgreement('privacy')}
  140. >
  141. <Text style={styles.menuText}>隐私协议</Text>
  142. <Text style={styles.arrow}>›</Text>
  143. </TouchableOpacity>
  144. </View>
  145. {/* 登录相关按钮 - 始终显示 */}
  146. <View style={styles.btnSection}>
  147. <TouchableOpacity style={styles.logoutBtn} onPress={handleLogout}>
  148. <Text style={styles.logoutBtnText}>退出登录</Text>
  149. </TouchableOpacity>
  150. <TouchableOpacity style={styles.logoffBtn} onPress={handleLogoff}>
  151. <Text style={styles.logoffBtnText}>注销账号</Text>
  152. </TouchableOpacity>
  153. </View>
  154. <View style={{ height: 50 }} />
  155. </ScrollView>
  156. </ImageBackground>
  157. );
  158. }
  159. const styles = StyleSheet.create({
  160. container: {
  161. flex: 1,
  162. },
  163. header: {
  164. flexDirection: 'row',
  165. alignItems: 'center',
  166. justifyContent: 'space-between',
  167. paddingHorizontal: 10,
  168. height: 80,
  169. },
  170. backBtn: {
  171. width: 40,
  172. height: 40,
  173. justifyContent: 'center',
  174. alignItems: 'center',
  175. },
  176. backIcon: {
  177. fontSize: 32,
  178. color: '#fff',
  179. fontWeight: 'bold',
  180. },
  181. headerTitle: {
  182. fontSize: 16,
  183. fontWeight: 'bold',
  184. color: '#fff',
  185. },
  186. placeholder: {
  187. width: 40,
  188. },
  189. scrollView: {
  190. flex: 1,
  191. paddingHorizontal: 15,
  192. },
  193. sectionTitle: {
  194. fontSize: 14,
  195. color: '#fff',
  196. marginTop: 20,
  197. marginBottom: 10,
  198. marginLeft: 5,
  199. },
  200. card: {
  201. backgroundColor: '#fff',
  202. borderRadius: 10,
  203. overflow: 'hidden',
  204. },
  205. menuItem: {
  206. flexDirection: 'row',
  207. alignItems: 'center',
  208. justifyContent: 'space-between',
  209. paddingHorizontal: 15,
  210. paddingVertical: 15,
  211. },
  212. menuText: {
  213. fontSize: 14,
  214. color: '#666',
  215. },
  216. arrow: {
  217. fontSize: 20,
  218. color: '#ccc',
  219. },
  220. divider: {
  221. height: 1,
  222. backgroundColor: '#f0f0f0',
  223. marginLeft: 15,
  224. },
  225. btnSection: {
  226. marginTop: 30,
  227. paddingHorizontal: 20,
  228. },
  229. logoutBtn: {
  230. backgroundColor: '#FC7D2E',
  231. height: 44,
  232. borderRadius: 22,
  233. justifyContent: 'center',
  234. alignItems: 'center',
  235. marginBottom: 15,
  236. },
  237. logoutBtnText: {
  238. fontSize: 16,
  239. color: '#fff',
  240. },
  241. logoffBtn: {
  242. backgroundColor: 'transparent',
  243. height: 44,
  244. borderRadius: 22,
  245. borderWidth: 1,
  246. borderColor: '#999',
  247. justifyContent: 'center',
  248. alignItems: 'center',
  249. },
  250. logoffBtnText: {
  251. fontSize: 16,
  252. color: '#999',
  253. },
  254. });