index.vue 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368
  1. <route lang="json5">
  2. {
  3. style: {
  4. navigationBarTitleText: '我的',
  5. },
  6. }
  7. </route>
  8. <template>
  9. <view class="profile-container">
  10. {{ JSON.stringify(userStore.userInfo) }}
  11. <!-- 用户信息区域 -->
  12. <view class="user-info-section">
  13. <!-- #ifdef MP-WEIXIN -->
  14. <button class="avatar-button" open-type="chooseAvatar" @chooseavatar="onChooseAvatar">
  15. <wd-img :src="userStore.userInfo.avatar" width="80px" height="80px" radius="50%"></wd-img>
  16. </button>
  17. <!-- #endif -->
  18. <!-- #ifndef MP-WEIXIN -->
  19. <view class="avatar-wrapper" @click="run">
  20. <wd-img :src="userStore.userInfo.avatar" width="100%" height="100%" radius="50%"></wd-img>
  21. </view>
  22. <!-- #endif -->
  23. <view class="user-details">
  24. <!-- #ifdef MP-WEIXIN -->
  25. <input
  26. type="nickname"
  27. class="weui-input"
  28. placeholder="请输入昵称"
  29. v-model="userStore.userInfo.username"
  30. />
  31. <!-- #endif -->
  32. <!-- #ifndef MP-WEIXIN -->
  33. <view class="username">{{ userStore.userInfo.username }}</view>
  34. <!-- #endif -->
  35. <view class="user-id">ID: {{ userStore.userInfo.id }}</view>
  36. </view>
  37. </view>
  38. <!-- 功能区块 -->
  39. <view class="function-section">
  40. <view class="cell-group">
  41. <view class="group-title">账号管理</view>
  42. <wd-cell title="个人资料" is-link @click="handleProfileInfo">
  43. <template #icon>
  44. <wd-icon name="user" size="20px"></wd-icon>
  45. </template>
  46. </wd-cell>
  47. <wd-cell title="账号安全" is-link @click="handlePassword">
  48. <template #icon>
  49. <wd-icon name="lock-on" size="20px"></wd-icon>
  50. </template>
  51. </wd-cell>
  52. </view>
  53. <view class="cell-group">
  54. <view class="group-title">通用设置</view>
  55. <wd-cell title="消息通知" is-link @click="handleInform">
  56. <template #icon>
  57. <wd-icon name="notification" size="20px"></wd-icon>
  58. </template>
  59. </wd-cell>
  60. <wd-cell title="清理缓存" is-link @click="handleClearCache">
  61. <template #icon>
  62. <wd-icon name="clear" size="20px"></wd-icon>
  63. </template>
  64. </wd-cell>
  65. <wd-cell title="应用更新" is-link @click="handleAppUpdate">
  66. <template #icon>
  67. <wd-icon name="refresh1" size="20px"></wd-icon>
  68. </template>
  69. </wd-cell>
  70. <wd-cell title="关于我们" is-link @click="handleAbout">
  71. <template #icon>
  72. <wd-icon name="info-circle" size="20px"></wd-icon>
  73. </template>
  74. </wd-cell>
  75. </view>
  76. <view class="logout-button-wrapper">
  77. <wd-button type="error" v-if="hasLogin" block @click="handleLogout">退出登录</wd-button>
  78. <wd-button type="primary" v-else block @click="handleLogin">登录</wd-button>
  79. </view>
  80. </view>
  81. </view>
  82. </template>
  83. <script lang="ts" setup>
  84. import { useUserStore } from '@/store'
  85. import { useToast } from 'wot-design-uni'
  86. import { uploadFileUrl, useUpload } from '@/utils/uploadFile'
  87. import { storeToRefs } from 'pinia'
  88. import { IUploadSuccessInfo } from '@/api/login.typings'
  89. const userStore = useUserStore()
  90. const toast = useToast()
  91. const hasLogin = ref(false)
  92. onShow((options) => {
  93. hasLogin.value = !!uni.getStorageSync('token')
  94. console.log('个人中心onShow', hasLogin.value, options)
  95. hasLogin.value && useUserStore().getUserInfo()
  96. })
  97. // #ifndef MP-WEIXIN
  98. // 上传头像
  99. const { run } = useUpload<IUploadSuccessInfo>(
  100. uploadFileUrl.USER_AVATAR,
  101. {},
  102. {
  103. onSuccess: (res) => useUserStore().getUserInfo(),
  104. },
  105. )
  106. // #endif
  107. // 微信小程序下登录
  108. const handleLogin = async () => {
  109. // #ifdef MP-WEIXIN
  110. // 微信登录
  111. await userStore.wxLogin()
  112. hasLogin.value = true
  113. // #endif
  114. // #ifndef MP-WEIXIN
  115. uni.navigateTo({ url: '/pages/login/index' })
  116. // #endif
  117. }
  118. // #ifdef MP-WEIXIN
  119. // 微信小程序下选择头像事件
  120. const onChooseAvatar = (e: any) => {
  121. console.log('选择头像', e.detail)
  122. const { avatarUrl } = e.detail
  123. const { run } = useUpload<IUploadSuccessInfo>(
  124. uploadFileUrl.USER_AVATAR,
  125. {},
  126. {
  127. onSuccess: (res) => useUserStore().getUserInfo(),
  128. },
  129. avatarUrl,
  130. )
  131. run()
  132. }
  133. // #endif
  134. // #ifdef MP-WEIXIN
  135. // 微信小程序下设置用户名
  136. const getUserInfo = (e: any) => {
  137. console.log(e.detail)
  138. }
  139. // #endif
  140. // 个人资料
  141. const handleProfileInfo = () => {
  142. uni.navigateTo({ url: `/pages/mine/info/index` })
  143. }
  144. // 账号安全
  145. const handlePassword = () => {
  146. uni.navigateTo({ url: `/pages/mine/password/index` })
  147. }
  148. // 消息通知
  149. const handleInform = () => {
  150. // uni.navigateTo({ url: `/pages/mine/inform/index` })
  151. toast.success('功能开发中')
  152. }
  153. // 应用更新
  154. const handleAppUpdate = () => {
  155. // #ifdef MP
  156. // #ifndef MP-HARMONY
  157. const updateManager = uni.getUpdateManager()
  158. updateManager.onCheckForUpdate(function (res) {
  159. // 请求完新版本信息的回调
  160. // console.log(res.hasUpdate)
  161. if (res.hasUpdate) {
  162. toast.success('检测到新版本,正在下载中...')
  163. } else {
  164. toast.success('已是最新版本')
  165. }
  166. })
  167. updateManager.onUpdateReady(function (res) {
  168. uni.showModal({
  169. title: '更新提示',
  170. content: '新版本已经准备好,是否重启应用?',
  171. success(res) {
  172. if (res.confirm) {
  173. // 新的版本已经下载好,调用 applyUpdate 应用新版本并重启
  174. updateManager.applyUpdate()
  175. }
  176. },
  177. })
  178. })
  179. updateManager.onUpdateFailed(function (res) {
  180. // 新的版本下载失败
  181. toast.error('新版本下载失败')
  182. })
  183. // #endif
  184. // #endif
  185. // #ifndef MP
  186. toast.success('功能开发中')
  187. // #endif
  188. }
  189. // 关于我们
  190. const handleAbout = () => {
  191. uni.navigateTo({ url: `/pages/mine/about/index` })
  192. }
  193. // 清除缓存
  194. const handleClearCache = () => {
  195. uni.showModal({
  196. title: '清除缓存',
  197. content: '确定要清除所有缓存吗?\n清除后需要重新登录',
  198. success: (res) => {
  199. if (res.confirm) {
  200. try {
  201. // 清除所有缓存
  202. uni.clearStorageSync()
  203. // 清除用户信息并跳转到登录页
  204. useUserStore().logout()
  205. toast.success('清除缓存成功')
  206. } catch (err) {
  207. console.error('清除缓存失败:', err)
  208. toast.error('清除缓存失败')
  209. }
  210. }
  211. },
  212. })
  213. }
  214. // 退出登录
  215. const handleLogout = () => {
  216. uni.showModal({
  217. title: '提示',
  218. content: '确定要退出登录吗?',
  219. success: (res) => {
  220. if (res.confirm) {
  221. // 清空用户信息
  222. useUserStore().logout()
  223. hasLogin.value = false
  224. // 执行退出登录逻辑
  225. toast.success('退出登录成功')
  226. // #ifdef MP-WEIXIN
  227. // 微信小程序,去首页
  228. // uni.reLaunch({ url: '/pages/index/index' })
  229. // #endif
  230. // #ifndef MP-WEIXIN
  231. // 非微信小程序,去登录页
  232. // uni.reLaunch({ url: '/pages/login/index' })
  233. // #endif
  234. }
  235. },
  236. })
  237. }
  238. </script>
  239. <style lang="scss" scoped>
  240. /* 基础样式 */
  241. .profile-container {
  242. overflow: hidden;
  243. font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', sans-serif;
  244. background-color: #f7f8fa;
  245. }
  246. /* 用户信息区域 */
  247. .user-info-section {
  248. display: flex;
  249. align-items: center;
  250. padding: 40rpx;
  251. margin: 30rpx 30rpx 20rpx;
  252. background-color: #fff;
  253. border-radius: 24rpx;
  254. box-shadow: 0 6rpx 20rpx rgba(0, 0, 0, 0.08);
  255. transition: all 0.3s ease;
  256. }
  257. .avatar-wrapper {
  258. width: 160rpx;
  259. height: 160rpx;
  260. margin-right: 40rpx;
  261. overflow: hidden;
  262. border: 4rpx solid #f5f5f5;
  263. border-radius: 50%;
  264. box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08);
  265. }
  266. .avatar-button {
  267. height: 160rpx;
  268. padding: 0;
  269. margin-right: 40rpx;
  270. overflow: hidden;
  271. border: 4rpx solid #f5f5f5;
  272. border-radius: 50%;
  273. box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08);
  274. }
  275. .user-details {
  276. flex: 1;
  277. }
  278. .username {
  279. margin-bottom: 12rpx;
  280. font-size: 38rpx;
  281. font-weight: 600;
  282. color: #333;
  283. letter-spacing: 0.5rpx;
  284. }
  285. .user-id {
  286. font-size: 28rpx;
  287. color: #666;
  288. }
  289. .user-created {
  290. margin-top: 8rpx;
  291. font-size: 24rpx;
  292. color: #999;
  293. }
  294. /* 功能区块 */
  295. .function-section {
  296. padding: 0 20rpx;
  297. margin-top: 20rpx;
  298. }
  299. .cell-group {
  300. margin-bottom: 20rpx;
  301. overflow: hidden;
  302. background-color: #fff;
  303. border-radius: 16rpx;
  304. box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
  305. }
  306. .group-title {
  307. padding: 24rpx 30rpx 16rpx;
  308. font-size: 30rpx;
  309. font-weight: 500;
  310. color: #999;
  311. background-color: #fafafa;
  312. }
  313. :deep(.wd-cell) {
  314. border-bottom: 1rpx solid #f5f5f5;
  315. &:last-child {
  316. border-bottom: none;
  317. }
  318. .wd-cell__title {
  319. margin-left: 5px;
  320. font-size: 32rpx;
  321. color: #333;
  322. }
  323. .cell-icon {
  324. margin-right: 20rpx;
  325. font-size: 36rpx;
  326. }
  327. }
  328. /* 退出登录按钮 */
  329. .logout-button-wrapper {
  330. padding: 40rpx 30rpx;
  331. }
  332. :deep(.wd-button--danger) {
  333. height: 88rpx;
  334. font-size: 32rpx;
  335. line-height: 88rpx;
  336. color: #fff;
  337. background-color: #f53f3f;
  338. border-radius: 44rpx;
  339. }
  340. </style>