myProfile.vue 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. <route lang="json5" type="page">
  2. {
  3. layout: 'default',
  4. needLogin: true,
  5. style: {
  6. navigationBarTitleText: '%myProfile.title%',
  7. navigationBarBackgroundColor: '#fff',
  8. },
  9. }
  10. </route>
  11. <script lang="ts" setup>
  12. import { updateInfo } from '@/api/login'
  13. import { t } from '@/locale'
  14. import { useUserStore } from '@/store'
  15. import { getEnvBaseUploadUrl } from '@/utils'
  16. import { toast } from '@/utils/toast'
  17. defineOptions({
  18. name: 'MyProfile', // 我的资料
  19. })
  20. const userStore = useUserStore()
  21. const userInfo = computed(() => {
  22. return getUserInfoHook()
  23. })
  24. const uploading = ref(false)
  25. // 更新头像
  26. async function updateAvatar() {
  27. try {
  28. // 微信小程序从基础库 2.21.0 开始,wx.chooseImage 停止维护,请使用 uni.chooseMedia 代替。
  29. const res: any = await new Promise((resolve, reject) => {
  30. // #ifdef MP-WEIXIN
  31. uni.chooseMedia({
  32. count: 1,
  33. mediaType: ['image'],
  34. sourceType: ['album', 'camera'],
  35. success: resolve,
  36. fail: reject,
  37. })
  38. // #endif
  39. // #ifndef MP-WEIXIN
  40. uni.chooseImage({
  41. count: 1,
  42. sourceType: ['album', 'camera'],
  43. success: resolve,
  44. fail: reject,
  45. })
  46. // #endif
  47. })
  48. let tempFilePath = ''
  49. let size = 0
  50. // #ifdef MP-WEIXIN
  51. if (!res.tempFiles || res.tempFiles.length === 0)
  52. return
  53. tempFilePath = res.tempFiles[0].tempFilePath
  54. size = res.tempFiles[0].size
  55. // #endif
  56. // #ifndef MP-WEIXIN
  57. if (!res.tempFilePaths || res.tempFilePaths.length === 0)
  58. return
  59. tempFilePath = res.tempFilePaths[0]
  60. size = res.tempFiles?.[0]?.size || 0
  61. // #endif
  62. // 检查文件大小(限制为5MB)
  63. const maxSize = 5 * 1024 * 1024
  64. if (size > maxSize) {
  65. toast.error(t('myProfile.upload.sizeLimit'))
  66. return
  67. }
  68. uploading.value = true
  69. await uni.showLoading({
  70. title: t('myProfile.upload.uploading'),
  71. mask: true,
  72. })
  73. // 上传图片
  74. const uploadRes: any = await new Promise((resolve, reject) => {
  75. uni.uploadFile({
  76. url: `${getEnvBaseUploadUrl()}`,
  77. filePath: tempFilePath,
  78. name: 'file',
  79. success: resolve,
  80. fail: reject,
  81. })
  82. })
  83. console.log('uploadRes', uploadRes)
  84. // 解析上传结果
  85. const uploadData = JSON.parse(uploadRes.data)
  86. if (uploadData.code !== '200') {
  87. throw new Error(uploadData.message)
  88. }
  89. const avatarUrl = uploadData.data
  90. // 调用更新用户信息接口
  91. await updateInfo({
  92. headPic: avatarUrl,
  93. })
  94. // 更新本地用户信息
  95. const newUserInfo = { ...userInfo.value, headPic: avatarUrl }
  96. userStore.setUserInfo(newUserInfo)
  97. userStore.getUserInfo()
  98. uni.hideLoading()
  99. toast.success(t('myProfile.upload.success'))
  100. }
  101. catch (error: any) {
  102. uni.hideLoading()
  103. console.error('Update avatar failed:', error)
  104. toast.error(error.message || t('myProfile.upload.error'))
  105. }
  106. finally {
  107. uploading.value = false
  108. }
  109. }
  110. onLoad(() => {
  111. // 页面加载时的逻辑
  112. userStore.getUserInfo()
  113. })
  114. </script>
  115. <template>
  116. <z-paging>
  117. <view class="py-20rpx">
  118. <wd-cell-group custom-class="mb-20rpx" border>
  119. <wd-cell :title="t('myProfile.avatar')" center>
  120. <view class="flex items-center justify-end" @click="updateAvatar">
  121. <view class="relative flex items-center justify-center">
  122. <wd-img width="64rpx" height="64rpx" round :src="userInfo.headPic" />
  123. <view v-if="uploading" class="absolute inset-0 flex items-center justify-center rounded-full bg-black bg-opacity-50">
  124. <wd-loading size="20rpx" color="#fff" />
  125. </view>
  126. </view>
  127. <wd-icon name="arrow-right" custom-class="ml-10rpx" size="36rpx" />
  128. </view>
  129. </wd-cell>
  130. <wd-cell :title="$t('myProfile.userId')" :value="userInfo.userNo" />
  131. <wd-cell :title="$t('myProfile.userName')" :value="userInfo.name" />
  132. <wd-cell :title="$t('myProfile.mobileNumber')" :value="userInfo.phoneNo" />
  133. </wd-cell-group>
  134. <wd-cell-group custom-class="mb-20rpx" border>
  135. <wd-cell :title="$t('myProfile.bankName')" :value="userInfo.bank" />
  136. <wd-cell :title="$t('myProfile.bankAccountName')" :value="userInfo.bankAccountName" />
  137. <wd-cell :title="$t('myProfile.bankAccountNo')" :value="userInfo.bankAccount" />
  138. </wd-cell-group>
  139. </view>
  140. </z-paging>
  141. </template>
  142. <style lang="scss" scoped>
  143. //
  144. </style>