edit-student-profile.vue 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. <template>
  2. <ie-page bg-color="#F6F8FA" :safeAreaInsetBottom="false">
  3. <ie-navbar title="基本信息" />
  4. <view class="">
  5. <uv-form labelPosition="left" :model="form" labelWidth="70px" ref="formRef">
  6. <content-card :title="userStore.isStudent ? '考生信息' : '个人信息'">
  7. <uv-form-item :label="nameLabel" prop="name" borderBottom>
  8. <uv-input v-model="form.nickName" border="none" :readonly="!userStore.isStudent" placeholder="请输入姓名"
  9. placeholderClass="text-30" font-size="30rpx" :custom-style="customStyle">
  10. </uv-input>
  11. </uv-form-item>
  12. <uv-form-item v-if="userStore.isStudent" label="手机号码" prop="name" borderBottom>
  13. <uv-input v-model="form.phonenumber" border="none" placeholder="请输入手机号码" maxlength="11" type="number"
  14. placeholderClass="text-30" font-size="30rpx" :custom-style="customStyle" readonly>
  15. </uv-input>
  16. <text slot="right" class="text-30 text-primary" @click="handleBindPhone">换绑</text>
  17. </uv-form-item>
  18. <uv-form-item label="所在省份" prop="name" borderBottom>
  19. <uv-input v-model="form.location" border="none" placeholder="" placeholderClass="text-30" font-size="30rpx"
  20. :custom-style="customStyle" readonly>
  21. </uv-input>
  22. <ie-image slot="right" src="/pagesSystem/static/image/icon/icon-lock.png" custom-class="w-24 h-30"
  23. mode="aspectFill" />
  24. </uv-form-item>
  25. <uv-form-item label="考试类别" prop="name" borderBottom>
  26. <view class="flex-1 pl-[26px]">
  27. <ie-dict :dictName="EnumDictName.EXAM_TYPE" :dictValue="form.examType" />
  28. </view>
  29. <ie-image slot="right" src="/pagesSystem/static/image/icon/icon-lock.png" custom-class="w-24 h-30"
  30. mode="aspectFill" />
  31. </uv-form-item>
  32. <uv-form-item label="毕业年份" prop="name">
  33. <uv-input v-model="form.endYear" border="none" placeholder="" placeholderClass="text-30" font-size="30rpx"
  34. :custom-style="customStyle" readonly>
  35. </uv-input>
  36. <ie-image slot="right" src="/pagesSystem/static/image/icon/icon-lock.png" custom-class="w-24 h-30"
  37. mode="aspectFill" />
  38. </uv-form-item>
  39. </content-card>
  40. <content-card v-if="userStore.isStudent" title="文化素质">
  41. <uv-form-item label="语文" prop="name" borderBottom>
  42. <uv-input v-model="scores.chinese" border="none" placeholder="请输入" placeholderClass="text-30"
  43. font-size="30rpx" :custom-style="customStyle" :readonly="form.examType === 'OHS'">
  44. </uv-input>
  45. <ie-image v-if="form.examType === 'OHS'" slot="right" src="/pagesSystem/static/image/icon/icon-lock.png"
  46. custom-class="w-24 h-30" mode="aspectFill" />
  47. </uv-form-item>
  48. <uv-form-item label="数学" prop="name" borderBottom>
  49. <uv-input v-model="scores.mathematics" border="none" placeholder="请输入" placeholderClass="text-30"
  50. font-size="30rpx" :custom-style="customStyle" :readonly="form.examType === 'OHS'">
  51. </uv-input>
  52. <ie-image v-if="form.examType === 'OHS'" slot="right" src="/pagesSystem/static/image/icon/icon-lock.png"
  53. custom-class="w-24 h-30" mode="aspectFill" />
  54. </uv-form-item>
  55. <uv-form-item label="外语" prop="name" :borderBottom="form.examType !== 'VHS'">
  56. <uv-input v-model="scores.foreign" border="none" placeholder="请输入" placeholderClass="text-30"
  57. font-size="30rpx" :custom-style="customStyle" :readonly="form.examType === 'OHS'">
  58. </uv-input>
  59. <ie-image v-if="form.examType === 'OHS'" slot="right" src="/pagesSystem/static/image/icon/icon-lock.png"
  60. custom-class="w-24 h-30" mode="aspectFill" />
  61. </uv-form-item>
  62. <block v-if="['OHS', 'SVS'].includes(form.examType)">
  63. <uv-form-item label="物理" prop="name" borderBottom>
  64. <uv-input v-model="scores.physics" border="none" placeholder="请输入" placeholderClass="text-30"
  65. font-size="30rpx" :custom-style="customStyle" :readonly="form.examType === 'OHS'">
  66. </uv-input>
  67. <ie-image v-if="form.examType === 'OHS'" slot="right" src="/pagesSystem/static/image/icon/icon-lock.png"
  68. custom-class="w-24 h-30" mode="aspectFill" />
  69. </uv-form-item>
  70. <uv-form-item label="政治" prop="name">
  71. <uv-input v-model="scores.political" border="none" placeholder="请输入" placeholderClass="text-30"
  72. font-size="30rpx" :custom-style="customStyle" :readonly="form.examType === 'OHS'">
  73. </uv-input>
  74. <ie-image v-if="form.examType === 'OHS'" slot="right" src="/pagesSystem/static/image/icon/icon-lock.png"
  75. custom-class="w-24 h-30" mode="aspectFill" />
  76. </uv-form-item>
  77. </block>
  78. </content-card>
  79. <content-card v-if="userStore.isStudent && (form.examType === 'OHS' || form.examType === 'SVS')" title="职业技能成绩">
  80. <uv-form-item label="职业技能" prop="name">
  81. <uv-input v-model.number="scores.skill" border="none" placeholder="请输入" placeholderClass="text-30"
  82. font-size="30rpx" :custom-style="customStyle">
  83. </uv-input>
  84. </uv-form-item>
  85. </content-card>
  86. <content-card v-if="userStore.isLogin && userStore.isStudent" title="学校信息">
  87. <uv-form-item label="学校名称" prop="form.name" borderBottom>
  88. <uv-input v-model="form.schoolName" border="none" placeholder="" placeholderClass="text-30"
  89. font-size="30rpx" :custom-style="customStyle" readonly>
  90. </uv-input>
  91. <ie-image slot="right" src="/pagesSystem/static/image/icon/icon-lock.png" custom-class="w-24 h-30"
  92. mode="aspectFill" />
  93. </uv-form-item>
  94. <uv-form-item label="所在班级" prop="form.name">
  95. <ie-picker ref="pickerRef" v-model="form.classId" :list="classList" title="选择班级" placeholder="请选择所在班级"
  96. :custom-style="customStyle" key-label="name" key-value="classId"></ie-picker>
  97. </uv-form-item>
  98. </content-card>
  99. </uv-form>
  100. </view>
  101. <ie-safe-toolbar v-if="userStore.isStudent" :height="84" :shadow="false">
  102. <view class="px-30 py-16">
  103. <ie-button @click="handleSubmit">确认保存</ie-button>
  104. </view>
  105. </ie-safe-toolbar>
  106. </ie-page>
  107. <uv-popup ref="popupRef" title="换绑手机号" mode="bottom" :round="16">
  108. <view class="theme-ie popup-content pt-100 py-30 px-30">
  109. <ie-input v-model="phoneForm.phone" type="number" :maxlength="11" placeholder="请输入新手机号" />
  110. <ie-input custom-class="mt-28" type="number" :maxlength="6" v-model="phoneForm.code" placeholder="请输入验证码">
  111. <ie-sms :phone="phoneForm.phone" :sms-api-type="EnumSmsApiType.NO_TOKEN" :beforeSend="handleBeforeSend"
  112. @send="handleSendSuccess" />
  113. </ie-input>
  114. <view class="mt-80 mb-16">
  115. <ie-button @click="handleChangePhone">确认更换</ie-button>
  116. </view>
  117. </view>
  118. </uv-popup>
  119. </template>
  120. <script lang="ts" setup>
  121. import ContentCard from '@/pagesSystem/components/content-card.vue';
  122. import { updateUserInfo } from '@/api/modules/login';
  123. import { useUserStore } from '@/store/userStore';
  124. import { useSchool } from '@/composables/useSchool';
  125. import { BindCardInfo, UserInfo } from '@/types/user';
  126. import { EnumDictName, EnumSmsApiType } from '@/common/enum';
  127. import { validatePhone } from '@/hooks/useValidation';
  128. import { validateSms } from '@/api/modules/system';
  129. const userStore = useUserStore();
  130. const userInfo = computed(() => userStore.userInfo);
  131. const cardInfo = computed(() => userStore.card);
  132. const { classList, loadClassData } = useSchool();
  133. type SchoolInfo = {
  134. schoolName: string;
  135. classId: number | null;
  136. className: string;
  137. schoolId: number | null;
  138. }
  139. type UserProfile = Pick<UserInfo, 'nickName' | 'phonenumber' | 'location' | 'endYear' | 'examType'> & SchoolInfo;
  140. const form = ref<UserProfile>({
  141. ...userInfo.value,
  142. schoolName: cardInfo.value?.schoolName || '',
  143. classId: cardInfo.value?.classId || null,
  144. className: cardInfo.value?.className || '',
  145. schoolId: cardInfo.value?.schoolId || null
  146. });
  147. const scores = ref({
  148. ...userInfo.value.scores
  149. })
  150. const nameLabel = computed(() => userStore.isStudent ? '学生姓名' : '姓名');
  151. const customStyle = {
  152. paddingLeft: '26px'
  153. };
  154. const handleSubmit = async () => {
  155. uni.$ie.showLoading();
  156. const params = {
  157. ...userInfo.value,
  158. ...form.value,
  159. scores: scores.value,
  160. } as UserInfo;
  161. await updateUserInfo(params);
  162. await userStore.getUserInfo();
  163. uni.$ie.hideLoading();
  164. uni.$ie.showToast('保存成功');
  165. }
  166. const popupRef = ref();
  167. const phoneForm = ref({
  168. phone: '',
  169. code: '',
  170. uuid: ''
  171. });
  172. const handleBeforeSend = () => {
  173. if (phoneForm.value.phone === userInfo.value.phonenumber) {
  174. uni.$ie.showToast('新手机号不能与旧手机号相同');
  175. return false;
  176. }
  177. return true;
  178. }
  179. const handleBindPhone = () => {
  180. popupRef.value.open();
  181. }
  182. const handleSendSuccess = (_phone: string, _code: string, _uuid: string) => {
  183. phoneForm.value.uuid = _uuid;
  184. }
  185. const handleChangePhone = async () => {
  186. if (phoneForm.value.phone.trim() === '') {
  187. uni.$ie.showToast('请输入新手机号');
  188. return;
  189. }
  190. if (phoneForm.value.code.trim() === '') {
  191. uni.$ie.showToast('请输入验证码');
  192. return;
  193. }
  194. if (phoneForm.value.phone === userInfo.value.phonenumber) {
  195. uni.$ie.showToast('新手机号不能与旧手机号相同');
  196. return;
  197. }
  198. uni.$ie.showLoading();
  199. const valid = await validateSms({
  200. code: phoneForm.value.code,
  201. uuid: phoneForm.value.uuid,
  202. mobile: phoneForm.value.phone
  203. });
  204. uni.$ie.hideLoading();
  205. if (!valid) {
  206. uni.$ie.showToast('请输入正确的验证码');
  207. return;
  208. }
  209. form.value.phonenumber = phoneForm.value.phone;
  210. popupRef.value.close();
  211. }
  212. onLoad(() => {
  213. loadClassData(cardInfo.value?.schoolId);
  214. });
  215. </script>
  216. <style lang="scss" scoped></style>