myProfile.vue 3.7 KB

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