index.vue 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. <template>
  2. <view class="profile-page">
  3. <nav-bar title="个人信息" bgColor="#fff" color="#000"></nav-bar>
  4. <view class="form-container" v-if="!loading">
  5. <uni-forms ref="formRef" :model="formData" :rules="rules">
  6. <view class="form-group">
  7. <uni-forms-item label="用户昵称" name="nickName" required label-width="160rpx">
  8. <uni-easyinput v-model="formData.nickName" placeholder="请输入昵称" :inputBorder="false" />
  9. </uni-forms-item>
  10. <view class="line"></view>
  11. <uni-forms-item label="手机号码" name="phonenumber" required label-width="160rpx">
  12. <uni-easyinput type="number" v-model="formData.phonenumber" placeholder="请输入手机号码" :inputBorder="false" />
  13. </uni-forms-item>
  14. <view class="line"></view>
  15. <uni-forms-item label="邮箱" name="email" label-width="160rpx">
  16. <uni-easyinput v-model="formData.email" placeholder="请输入邮箱" :inputBorder="false" />
  17. </uni-forms-item>
  18. <view class="line"></view>
  19. <uni-forms-item label="性别" name="sex" label-width="160rpx">
  20. <picker :range="sexOptions" range-key="label" @change="onSexChange">
  21. <view class="picker-value" :class="{'placeholder': formData.sex === undefined || formData.sex === ''}">
  22. {{ getSexLabel }}
  23. </view>
  24. </picker>
  25. </uni-forms-item>
  26. </view>
  27. </uni-forms>
  28. <view class="btn-group">
  29. <button class="submit-btn" @click="submit">保存修改</button>
  30. </view>
  31. </view>
  32. </view>
  33. </template>
  34. <script setup>
  35. // @Author: Antigravity
  36. import { ref, reactive, computed } from 'vue'
  37. import { onLoad } from '@dcloudio/uni-app'
  38. import navBar from '@/components/nav-bar/index.vue'
  39. import { getInfo, updateUserProfile } from '@/api/system/user'
  40. const loading = ref(true)
  41. const formRef = ref(null)
  42. const formData = reactive({
  43. nickName: '',
  44. phonenumber: '',
  45. email: '',
  46. sex: '' // 0男 1女 2未知
  47. })
  48. const sexOptions = [
  49. { label: '男', value: '0' },
  50. { label: '女', value: '1' },
  51. { label: '未知', value: '2' }
  52. ]
  53. const rules = {
  54. nickName: {
  55. rules: [{ required: true, errorMessage: '请输入昵称' }]
  56. },
  57. phonenumber: {
  58. rules: [
  59. { required: true, errorMessage: '请输入手机号码' },
  60. { pattern: /^1[3-9]\d{9}$/, errorMessage: '请输入正确的手机号码' }
  61. ]
  62. },
  63. email: {
  64. rules: [{ format: 'email', errorMessage: '请输入正确的邮箱格式' }]
  65. }
  66. }
  67. onLoad(async () => {
  68. try {
  69. const res = await getInfo()
  70. if (res && res.user) {
  71. formData.nickName = res.user.nickName || ''
  72. formData.phonenumber = res.user.phonenumber || ''
  73. formData.email = res.user.email || ''
  74. formData.sex = res.user.sex || '2'
  75. }
  76. } catch (e) {
  77. console.error('获取个人信息失败', e)
  78. } finally {
  79. loading.value = false
  80. }
  81. })
  82. const getSexLabel = computed(() => {
  83. const opt = sexOptions.find(o => o.value === String(formData.sex))
  84. return opt ? opt.label : '请选择'
  85. })
  86. const onSexChange = (e) => {
  87. formData.sex = sexOptions[e.detail.value].value
  88. }
  89. const submit = async () => {
  90. try {
  91. await formRef.value.validate()
  92. uni.showLoading({ title: '保存中...' })
  93. await updateUserProfile(formData)
  94. uni.hideLoading()
  95. uni.showToast({ title: '个人信息修改成功', icon: 'success' })
  96. setTimeout(() => {
  97. uni.navigateBack()
  98. }, 1000)
  99. } catch (err) {
  100. uni.hideLoading()
  101. console.log('保存失败', err)
  102. }
  103. }
  104. </script>
  105. <style lang="scss" scoped>
  106. .profile-page {
  107. min-height: 100vh;
  108. background-color: #f7f8fa;
  109. }
  110. .form-container {
  111. padding-top: 20rpx;
  112. }
  113. .form-group {
  114. background: #fff;
  115. margin: 0 24rpx;
  116. border-radius: 20rpx;
  117. padding: 0 32rpx;
  118. }
  119. .line {
  120. height: 1rpx;
  121. background: #f5f5f5;
  122. margin: 0;
  123. }
  124. .btn-group {
  125. margin: 60rpx 32rpx 32rpx;
  126. }
  127. .submit-btn {
  128. height: 88rpx;
  129. line-height: 88rpx;
  130. background: linear-gradient(90deg, #ffd53f, #ff9500);
  131. color: #333;
  132. border: none;
  133. border-radius: 44rpx;
  134. font-size: 30rpx;
  135. font-weight: bold;
  136. }
  137. .picker-value {
  138. flex: 1;
  139. font-size: 26rpx;
  140. color: #666;
  141. text-align: right;
  142. min-height: 40rpx;
  143. line-height: 72rpx;
  144. padding-right: 20rpx;
  145. }
  146. .picker-value.placeholder {
  147. color: #999;
  148. }
  149. :deep(.uni-forms-item) {
  150. border: none !important;
  151. padding: 10rpx 0;
  152. }
  153. :deep(.uni-forms-item__label) {
  154. font-size: 28rpx;
  155. color: #333;
  156. }
  157. :deep(.uni-easyinput__content-input) {
  158. text-align: right;
  159. font-size: 26rpx;
  160. }
  161. </style>