index.vue 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. <route lang="json5">
  2. {
  3. style: {
  4. navigationBarTitleText: '个人资料',
  5. },
  6. }
  7. </route>
  8. <template>
  9. <view class="profile-info-container">
  10. <view class="profile-card">
  11. <view class="form-wrapper">
  12. <wd-form ref="formRef" :model="formData" label-width="160rpx" class="profile-form">
  13. <wd-cell-group class="form-group">
  14. <!-- 昵称 -->
  15. <view class="sex-field">
  16. <text class="field-label">昵称</text>
  17. <wd-input
  18. prop="name"
  19. clearable
  20. v-model="formData.name"
  21. placeholder="请输入昵称"
  22. :rules="[{ required: true, message: '请填写昵称' }]"
  23. class="form-input"
  24. />
  25. </view>
  26. <!-- 性别 -->
  27. <view class="sex-field">
  28. <text class="field-label">性别</text>
  29. <wd-radio-group
  30. v-model="formData.sex"
  31. shape="button"
  32. :rules="[{ required: true, message: '请选择性别' }]"
  33. >
  34. <wd-radio :value="'1'">男</wd-radio>
  35. <wd-radio :value="'0'">女</wd-radio>
  36. </wd-radio-group>
  37. </view>
  38. </wd-cell-group>
  39. </wd-form>
  40. <!-- 操作按钮 -->
  41. <view class="form-actions">
  42. <wd-button type="primary" size="large" @click="handleSubmit">保存修改</wd-button>
  43. </view>
  44. </view>
  45. </view>
  46. </view>
  47. </template>
  48. <script lang="ts" setup>
  49. import { ref } from 'vue'
  50. import { useUserStore } from '@/store'
  51. import { storeToRefs } from 'pinia'
  52. import { toast } from '@/utils/toast'
  53. import { updateInfo } from '@/api/login'
  54. // 表单引用
  55. const formRef = ref()
  56. // 用户信息
  57. const userStore = useUserStore()
  58. const { userInfo } = storeToRefs(userStore)
  59. // 表单数据
  60. const formData = ref({
  61. id: userInfo.value.id,
  62. name: userInfo.value.name,
  63. sex: userInfo.value.sex,
  64. })
  65. // 提交表单
  66. const handleSubmit = async () => {
  67. // 表单验证
  68. const valid = await formRef.value.validate()
  69. if (!valid) return
  70. const { message } = await updateInfo(formData.value)
  71. await useUserStore().getUserInfo()
  72. toast.success(message)
  73. }
  74. </script>
  75. <style lang="scss" scoped>
  76. .profile-info-container {
  77. min-height: 100vh;
  78. background-color: #f5f7fa;
  79. padding: 30rpx;
  80. }
  81. .profile-card {
  82. background-color: #ffffff;
  83. border-radius: 24rpx;
  84. box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.04);
  85. overflow: hidden;
  86. }
  87. .card-header {
  88. padding: 40rpx 30rpx 20rpx;
  89. border-bottom: 2rpx solid #f0f0f0;
  90. }
  91. .card-title {
  92. font-size: 36rpx;
  93. font-weight: 600;
  94. color: #333;
  95. position: relative;
  96. display: inline-block;
  97. padding-bottom: 16rpx;
  98. &::after {
  99. content: '';
  100. position: absolute;
  101. bottom: 0;
  102. left: 0;
  103. width: 60rpx;
  104. height: 6rpx;
  105. background: linear-gradient(90deg, #4a7bff, #6a5acd);
  106. border-radius: 6rpx;
  107. }
  108. }
  109. .form-wrapper {
  110. padding: 30rpx;
  111. }
  112. .form-group {
  113. border-radius: 16rpx;
  114. overflow: hidden;
  115. margin-bottom: 40rpx;
  116. }
  117. .form-input {
  118. font-size: 30rpx;
  119. }
  120. .sex-field {
  121. display: flex;
  122. align-items: center;
  123. padding: 24rpx 30rpx;
  124. background-color: #ffffff;
  125. }
  126. .field-label {
  127. width: 160rpx;
  128. font-size: 30rpx;
  129. color: #333;
  130. }
  131. .radio-group {
  132. flex: 1;
  133. display: flex;
  134. gap: 20rpx;
  135. }
  136. .radio-btn {
  137. flex: 1;
  138. height: 80rpx;
  139. line-height: 80rpx;
  140. text-align: center;
  141. font-size: 30rpx;
  142. border-radius: 12rpx;
  143. background-color: #f5f7fa;
  144. &:active {
  145. opacity: 0.8;
  146. }
  147. }
  148. .form-actions {
  149. display: flex;
  150. flex-direction: row;
  151. gap: 20rpx;
  152. }
  153. .submit-btn {
  154. height: 90rpx;
  155. border-radius: 45rpx;
  156. font-size: 32rpx;
  157. font-weight: 500;
  158. background: linear-gradient(135deg, #4a7bff, #6a5acd);
  159. box-shadow: 0 8rpx 16rpx rgba(74, 123, 255, 0.2);
  160. transition: all 0.3s ease;
  161. &:active {
  162. transform: translateY(2rpx);
  163. box-shadow: 0 4rpx 8rpx rgba(74, 123, 255, 0.15);
  164. }
  165. }
  166. </style>