index.vue 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. <template>
  2. <div class="px-3">
  3. <div class="resume-header mb-3">
  4. <div class="resume-title">学生信息编辑</div>
  5. </div>
  6. <div class="d-flex flex-column align-center pt-5">
  7. <CtForm ref="CtFormRef" :items="items" style="width: 900px;"></CtForm>
  8. <v-btn class="buttons mt-5 elevation-5" color="primary" @click.stop="handleSubmit">{{ $t('common.save') }}</v-btn>
  9. </div>
  10. </div>
  11. <Loading :visible="overlay"></Loading>
  12. </template>
  13. <script setup>
  14. defineOptions({name: 'personal-personCenter-studentInformation-index'})
  15. import { ref, onMounted } from 'vue'
  16. import { saveStudentSimpleInfo } from '@/api/recruit/personal/shareJob'
  17. import { useI18n } from '@/hooks/web/useI18n'
  18. import Snackbar from '@/plugins/snackbar'
  19. import { isValidIdCard18 } from '@/utils/validate'
  20. import { useUserStore } from '@/store/user'
  21. import { getSchoolList, getDepartmentListBySchoolId, getMajorList } from '@/api/recruit/personal/student'
  22. const { t } = useI18n()
  23. const userStore = useUserStore()
  24. const overlay = ref(false)
  25. const CtFormRef = ref()
  26. // 专业名称下拉列表
  27. let majorName = null
  28. const getMajorData = async (name) => {
  29. const item = items.value.options.find(e => e.key === 'majorId')
  30. if (!item) return
  31. if (item.items?.length && (majorName === name)) return // 防抖
  32. majorName = name
  33. if (name) {
  34. const data = await getMajorList({ name })
  35. item.items = data
  36. }
  37. }
  38. const items = ref({
  39. options: [
  40. {
  41. type: 'autocomplete',
  42. key: 'schoolId',
  43. value: null,
  44. default: null,
  45. label: '就读学校 *',
  46. outlined: true,
  47. itemText: 'name',
  48. itemValue: 'schoolId',
  49. rules: [v => !!v || '请选择就读学校'],
  50. items: [],
  51. change: e => getDepartmentList(e, 'schoolDeptId', 0, true),
  52. },
  53. {
  54. type: 'autocomplete',
  55. key: 'schoolDeptId',
  56. value: null,
  57. default: null,
  58. label: '所在院系 *',
  59. outlined: true,
  60. itemText: 'name',
  61. itemValue: 'id',
  62. rules: [v => !!v || '请选择所在院系'],
  63. change: e => getDepartmentList(e, 'schoolClassId', 2, true),
  64. items: []
  65. },
  66. {
  67. type: 'combobox',
  68. key: 'schoolClassId',
  69. value: null,
  70. label: '所在班级 *',
  71. outlined: true,
  72. clearable: true,
  73. canBeInputted: true,
  74. itemTextName: 'schoolClassName',
  75. itemText: 'name',
  76. itemValue: 'id',
  77. rules: [v => !!v || '请选择所在班级'],
  78. items: []
  79. },
  80. {
  81. type: 'autocomplete',
  82. key: 'majorId',
  83. value: null,
  84. label: '所学专业 *',
  85. outlined: true,
  86. itemText: 'nameCn',
  87. itemValue: 'id',
  88. rules: [v => !!v || '请选择所学专业'],
  89. search: e => getMajorData(e),
  90. items: []
  91. },
  92. {
  93. type: 'text',
  94. key: 'studentNo',
  95. value: '',
  96. default: null,
  97. label: '学号 *',
  98. outlined: true,
  99. rules: [v => !!v || '请填写学号']
  100. },
  101. {
  102. type: 'text',
  103. key: 'idCardNo',
  104. value: '',
  105. label: '身份证号码 *',
  106. rules: [
  107. value => {
  108. if (!value) {
  109. return '请输入您的身份证号码'
  110. }
  111. return true
  112. },
  113. value => {
  114. if (!isValidIdCard18(value)) {
  115. return '请输入正确的身份证号码'
  116. }
  117. return true
  118. }
  119. ]
  120. },
  121. {
  122. type: 'text',
  123. key: 'emergencyContactName',
  124. value: '',
  125. default: null,
  126. label: '紧急联系人姓名 *',
  127. outlined: true,
  128. rules: [v => !!v || '请填写紧急联系人姓名']
  129. },
  130. {
  131. type: 'phoneNumber',
  132. key: 'emergencyContactPhone',
  133. value: '',
  134. label: '紧急联系人手机号 *',
  135. rules: [v => !!v || '请填写紧急联系人手机号']
  136. }
  137. ]
  138. })
  139. // 左侧加mr
  140. items.value.options.forEach((e, index) => {
  141. e.col = 6
  142. if ((index + 2) % 2 === 0) e.flexStyle = 'mr-3'
  143. })
  144. // 学校下拉列表
  145. const getSchoolListData = async () => {
  146. const item = items.value.options.find(e => e.key === 'schoolId')
  147. if (!item) return
  148. const data = await getSchoolList()
  149. item.items = data || []
  150. }
  151. // 根据学校id获取院系、班级列表
  152. const getDepartmentList = async (id, key, type, isRefreshValue = false) => {
  153. const item = items.value.options.find(e => e.key === key)
  154. if (!item) return
  155. let params = { type } // type: 0院系|1专业|2班级
  156. // 查院系用schoolId,查班级用parentId
  157. if (key === 'schoolDeptId') params.schoolId = id
  158. else params.parentId = id
  159. const data = await getDepartmentListBySchoolId(params)
  160. item.items = data || []
  161. // 下拉框选择时需清空下级value
  162. if (isRefreshValue) item.value = null
  163. }
  164. // 获取学生基本信息
  165. const studentInfoFun = async () => {
  166. // await userStore.getStudentInformation()
  167. const data = JSON.parse(localStorage.getItem('studentInfo') || '{}')
  168. if (data.schoolId) getDepartmentList(data.schoolId, 'schoolDeptId', 0)
  169. if (data?.schoolClassId) getDepartmentList(data.schoolDeptId, 'schoolClassId', 2)
  170. if (data?.majorId) {
  171. getMajorData(data?.major?.nameCn)
  172. }
  173. // 回显
  174. items.value.options.forEach(e => {
  175. if (data[e.key]) {
  176. e.value = data[e.key]
  177. }
  178. })
  179. }
  180. onMounted(() => {
  181. // 获取学校列表
  182. getSchoolListData()
  183. // 获取学生基本信息
  184. studentInfoFun()
  185. })
  186. // 提交
  187. const handleSubmit = async () => {
  188. const { valid } = await CtFormRef.value.formRef.validate()
  189. if (!valid) return
  190. overlay.value = true
  191. const params = {}
  192. items.value.options.forEach(item => {
  193. // 班级有下拉选择的,需要根据选择的值赋值
  194. if (item.key === 'schoolClassId') {
  195. const classObj = item.items.find(e => e[item.itemValue] === item.value)
  196. if (!classObj) {
  197. params[item.key] = null
  198. params[item.itemTextName] = item.value
  199. } else params[item.key] = item.value
  200. } else params[item.key] = item.value
  201. })
  202. await saveStudentSimpleInfo(params)
  203. setTimeout(async () => {
  204. await userStore.getStudentInformation()
  205. studentInfoFun()
  206. Snackbar.success(t('common.submittedSuccessfully'))
  207. overlay.value = false
  208. }, 1000)
  209. }
  210. </script>
  211. <style scoped lang="scss">
  212. </style>