settings.vue 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  1. <template>
  2. <view class="container">
  3. <!-- 顶部导航栏 -->
  4. <view class="header">
  5. <view class="back-btn" @click="goBack">
  6. <text class="back-icon">←</text>
  7. </view>
  8. <text class="header-title">设置</text>
  9. <view class="header-right"></view>
  10. </view>
  11. <scroll-view class="scroll-content" scroll-y>
  12. <!-- 开关设置项 -->
  13. <view class="settings-section">
  14. <view class="setting-item" v-for="(setting, index) in toggleSettings" :key="index">
  15. <text class="setting-label">{{ setting.label }}</text>
  16. <switch
  17. class="setting-switch"
  18. :checked="setting.value"
  19. @change="handleToggleChange(index, $event)"
  20. color="#4FC3F7"
  21. />
  22. </view>
  23. </view>
  24. <!-- 分隔线 -->
  25. <view class="divider"></view>
  26. <!-- 信息项 -->
  27. <view class="info-section">
  28. <view class="info-item" @click="handleInfoClick('clearCache')">
  29. <text class="info-label">清理缓存</text>
  30. <view class="info-right">
  31. <text class="info-value">{{ cacheSize }}</text>
  32. <text class="info-arrow">></text>
  33. </view>
  34. </view>
  35. <view class="info-item" @click="handleInfoClick('about')">
  36. <text class="info-label">关于我们</text>
  37. <text class="info-arrow">></text>
  38. </view>
  39. <view class="info-item" @click="handleInfoClick('contact')">
  40. <text class="info-label">联系我们</text>
  41. <text class="info-arrow">></text>
  42. </view>
  43. </view>
  44. <!-- 分隔线 -->
  45. <view class="divider"></view>
  46. <!-- 退出登录按钮 -->
  47. <view class="logout-section">
  48. <button class="logout-btn" @click="handleLogout">退出登录</button>
  49. </view>
  50. </scroll-view>
  51. </view>
  52. </template>
  53. <script>
  54. export default {
  55. data() {
  56. return {
  57. toggleSettings: [
  58. {
  59. label: '阅读时不自动锁屏',
  60. value: false,
  61. key: 'noAutoLock'
  62. },
  63. {
  64. label: '阅读时隐藏别人的笔记',
  65. value: false,
  66. key: 'hideOthersNotes'
  67. },
  68. {
  69. label: '阅读时显示时间和电量',
  70. value: true,
  71. key: 'showTimeBattery'
  72. },
  73. {
  74. label: '阅读时允许横屏',
  75. value: false,
  76. key: 'allowLandscape'
  77. },
  78. {
  79. label: '点赞提醒',
  80. value: true,
  81. key: 'likeReminder'
  82. }
  83. ],
  84. cacheSize: '20M'
  85. }
  86. },
  87. onLoad() {
  88. // 加载保存的设置
  89. this.loadSettings()
  90. // 加载缓存大小
  91. this.loadCacheSize()
  92. },
  93. methods: {
  94. goBack() {
  95. uni.navigateBack()
  96. },
  97. handleToggleChange(index, event) {
  98. this.toggleSettings[index].value = event.detail.value
  99. // 保存设置到本地存储
  100. this.saveSettings()
  101. },
  102. handleInfoClick(type) {
  103. switch(type) {
  104. case 'clearCache':
  105. this.clearCache()
  106. break
  107. case 'about':
  108. this.showAbout()
  109. break
  110. case 'contact':
  111. this.showContact()
  112. break
  113. }
  114. },
  115. clearCache() {
  116. uni.showModal({
  117. title: '提示',
  118. content: `确定要清理 ${this.cacheSize} 缓存吗?`,
  119. success: (res) => {
  120. if (res.confirm) {
  121. // 清理缓存
  122. uni.clearStorageSync()
  123. this.cacheSize = '0M'
  124. uni.showToast({
  125. title: '缓存已清理',
  126. icon: 'success'
  127. })
  128. }
  129. }
  130. })
  131. },
  132. showAbout() {
  133. uni.navigateTo({
  134. url: '/pages/about/about'
  135. })
  136. },
  137. showContact() {
  138. uni.showModal({
  139. title: '联系我们',
  140. content: '邮箱: support@yunread.com\n电话: 400-123-4567',
  141. showCancel: false
  142. })
  143. },
  144. handleLogout() {
  145. uni.showModal({
  146. title: '提示',
  147. content: '确定要退出登录吗?',
  148. success: (res) => {
  149. if (res.confirm) {
  150. // 清除登录信息
  151. uni.removeStorageSync('token')
  152. uni.removeStorageSync('userInfo')
  153. uni.showToast({
  154. title: '已退出登录',
  155. icon: 'success'
  156. })
  157. // 跳转到登录页
  158. setTimeout(() => {
  159. uni.reLaunch({
  160. url: '/pages/login/login'
  161. })
  162. }, 1500)
  163. }
  164. }
  165. })
  166. },
  167. loadSettings() {
  168. // 从本地存储加载设置
  169. const savedSettings = uni.getStorageSync('appSettings')
  170. if (savedSettings) {
  171. this.toggleSettings.forEach((setting, index) => {
  172. if (savedSettings[setting.key] !== undefined) {
  173. this.toggleSettings[index].value = savedSettings[setting.key]
  174. }
  175. })
  176. }
  177. },
  178. saveSettings() {
  179. // 保存设置到本地存储
  180. const settings = {}
  181. this.toggleSettings.forEach(setting => {
  182. settings[setting.key] = setting.value
  183. })
  184. uni.setStorageSync('appSettings', settings)
  185. },
  186. loadCacheSize() {
  187. // 计算缓存大小
  188. try {
  189. const info = uni.getStorageInfoSync()
  190. const size = (info.keys.length * 2).toFixed(0) // 简单估算
  191. this.cacheSize = size + 'M'
  192. } catch (e) {
  193. this.cacheSize = '20M'
  194. }
  195. }
  196. }
  197. }
  198. </script>
  199. <style scoped>
  200. .container {
  201. width: 100%;
  202. height: 100vh;
  203. min-height: 100vh;
  204. background-color: #FFFFFF;
  205. display: flex;
  206. padding-top: 30px;
  207. box-sizing: border-box;
  208. flex-direction: column;
  209. box-sizing: border-box;
  210. overflow: hidden;
  211. }
  212. .header {
  213. display: flex;
  214. align-items: center;
  215. justify-content: space-between;
  216. padding: 20rpx 30rpx;
  217. padding-top: calc(20rpx + env(safe-area-inset-top));
  218. background-color: #FFFFFF;
  219. border-bottom: 1rpx solid #F0F0F0;
  220. position: relative;
  221. flex-shrink: 0;
  222. box-sizing: border-box;
  223. }
  224. .back-btn {
  225. width: 60rpx;
  226. height: 60rpx;
  227. display: flex;
  228. align-items: center;
  229. justify-content: center;
  230. z-index: 10;
  231. }
  232. .back-icon {
  233. font-size: 40rpx;
  234. color: #333333;
  235. font-weight: bold;
  236. }
  237. .header-title {
  238. position: absolute;
  239. left: 50%;
  240. transform: translateX(-50%);
  241. font-size: 36rpx;
  242. font-weight: bold;
  243. color: #333333;
  244. }
  245. .header-right {
  246. width: 60rpx;
  247. }
  248. .scroll-content {
  249. flex: 1;
  250. width: 100%;
  251. height: 0;
  252. overflow: hidden;
  253. padding-bottom: calc(env(safe-area-inset-bottom));
  254. background-color: #FFFFFF;
  255. box-sizing: border-box;
  256. }
  257. .settings-section {
  258. background-color: #FFFFFF;
  259. padding: 0 30rpx;
  260. }
  261. .setting-item {
  262. display: flex;
  263. align-items: center;
  264. justify-content: space-between;
  265. padding: 30rpx 0;
  266. border-bottom: 1rpx solid #F0F0F0;
  267. }
  268. .setting-item:last-child {
  269. border-bottom: none;
  270. }
  271. .setting-label {
  272. font-size: 30rpx;
  273. color: #333333;
  274. flex: 1;
  275. }
  276. .setting-switch {
  277. transform: scale(0.9);
  278. }
  279. .divider {
  280. height: 20rpx;
  281. background-color: #F5F5F5;
  282. }
  283. .info-section {
  284. background-color: #FFFFFF;
  285. padding: 0 30rpx;
  286. }
  287. .info-item {
  288. display: flex;
  289. align-items: center;
  290. justify-content: space-between;
  291. padding: 30rpx 0;
  292. border-bottom: 1rpx solid #F0F0F0;
  293. }
  294. .info-item:last-child {
  295. border-bottom: none;
  296. }
  297. .info-label {
  298. font-size: 30rpx;
  299. color: #333333;
  300. flex: 1;
  301. }
  302. .info-right {
  303. display: flex;
  304. align-items: center;
  305. gap: 20rpx;
  306. }
  307. .info-value {
  308. font-size: 28rpx;
  309. color: #999999;
  310. }
  311. .info-arrow {
  312. font-size: 32rpx;
  313. color: #CCCCCC;
  314. }
  315. .logout-section {
  316. padding: 40rpx 30rpx;
  317. background-color: #FFFFFF;
  318. }
  319. .logout-btn {
  320. width: 100%;
  321. height: 88rpx;
  322. background-color: transparent;
  323. color: #FF1744;
  324. font-size: 32rpx;
  325. border: none;
  326. border-radius: 44rpx;
  327. display: flex;
  328. align-items: center;
  329. justify-content: center;
  330. }
  331. .logout-btn::after {
  332. border: none;
  333. }
  334. </style>