schoolForm.vue 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. <template>
  2. <div class="box" style="overflow-x: hidden;" :style="{'background-image': 'url(' + webContent.loginBgUrl + ')'}">
  3. <navBar :showLoginBtn="false" class="navBar"></navBar>
  4. <div class="content pa-5">
  5. <div class="mb-10 mt-5" style="font-size: 22px; font-family: 'MiSans-Bold'; text-align: center;">
  6. {{ isUpdate ? '注册信息修改' : '老师注册'}}
  7. </div>
  8. <CtForm class="mt-5" ref="CtFormRef" :items="formItems">
  9. <template #authDept>
  10. <div class="pa-5 mb-3" style="width: 100%; border: 1px dashed #ccc; border-radius: 4px;">
  11. <p class="color-999 font-size-14 mb-3">
  12. <span class="color-error">*</span>
  13. 负责院系
  14. </p>
  15. <div v-for="(k, index) in departmentList" :key="index" class="d-flex align-center mb-5">
  16. <TextInput v-model="k.name" :item="textItem" />
  17. <v-icon v-if="index > 0" class="ml-3 cursor-pointer" @click="handleDeleteDepartment(index)" color="error">mdi-close-circle</v-icon>
  18. </div>
  19. <v-btn class="mt-3" color="primary" prepend-icon="mdi-plus" size="small" @click="handleAddDepartment">添加院系</v-btn>
  20. </div>
  21. </template>
  22. <template #tips>
  23. <p class="font-size-14 color-warning mb-3">图片上传提示:支持jpg、jpeg、png格式,图片大小不得超过20M</p>
  24. </template>
  25. <template #employmentCertificate="{ item }">
  26. <div class="d-flex flex-column">
  27. <p class="color-999 font-size-14 mb-3">
  28. <span class="color-error">*</span>
  29. 在岗证明图片
  30. </p>
  31. <Img
  32. class="upload-box"
  33. tips="上传图片"
  34. :value="item.value"
  35. :showSnackbar="false"
  36. @imgClick="handlePreview"
  37. :showCursor="true"
  38. @success="url => item.value = url"
  39. @delete="item.value = null"
  40. />
  41. </div>
  42. </template>
  43. </CtForm>
  44. <div class="text-center my-10">
  45. <v-btn color="primary" width="250" @click.stop="handleSubmit">提 交</v-btn>
  46. </div>
  47. </div>
  48. </div>
  49. <PreviewImage v-if="showPreview" :initialIndex="0" :urlList="[previewUrl]" @close="showPreview = !showPreview, previewUrl = ''" />
  50. </template>
  51. <script setup>
  52. defineOptions({ name: 'register-schoolForm'})
  53. import { ref, onMounted } from 'vue'
  54. import { webContentStore } from '@/store/webContent'
  55. import { getDict } from '@/hooks/web/useDictionaries'
  56. import Snackbar from '@/plugins/snackbar'
  57. import navBar from '@/layout/personal/navBar.vue'
  58. import { schoolRegister } from '@/api/school'
  59. import { useRouter } from 'vue-router'
  60. const router = useRouter()
  61. const webContent = webContentStore()
  62. const previewUrl = ref('')
  63. const showPreview = ref(false)
  64. const departmentList = ref([{ name: '' }])
  65. const textItem = {
  66. type: 'text',
  67. key: 'name',
  68. width: 450,
  69. label: '院系名称 *',
  70. hideDetails: true,
  71. rules: [v => !!v || '请输入您负责的院系名称']
  72. }
  73. const isUpdate = ref(false)
  74. const CtFormRef = ref()
  75. const formItems = ref({
  76. options: [
  77. {
  78. type: 'text',
  79. key: 'name',
  80. value: '',
  81. label: '姓名 *',
  82. col: 6,
  83. outlined: true,
  84. rules: [v => !!v || '请输入您的姓名']
  85. },
  86. {
  87. type: 'ifRadio',
  88. key: 'sex',
  89. value: '1',
  90. defaultValue: '1',
  91. label: '性别 *',
  92. col: 6,
  93. flexStyle: 'ml-5',
  94. width: 50,
  95. dictTypeName: 'menduner_sex',
  96. rules: [v => !!v || '请选择您的性别'],
  97. items: []
  98. },
  99. {
  100. type: 'phoneNumber',
  101. key: 'phone',
  102. value: localStorage.getItem('schoolLoginAccount') ? JSON.parse(localStorage.getItem('schoolLoginAccount')).phone : '',
  103. label: '联系电话 *',
  104. col: 6,
  105. outlined: true,
  106. rules: [v => !!v || '请填写您的联系电话']
  107. },
  108. {
  109. type: 'autocomplete',
  110. key: 'schoolId',
  111. value: null,
  112. label: '所在学校 *',
  113. col: 6,
  114. itemText: 'name',
  115. itemValue: 'id',
  116. flexStyle: 'ml-5',
  117. outlined: true,
  118. items: [],
  119. rules: [v => !!v || '请选择您所在的学校名称']
  120. },
  121. {
  122. slotName: 'authDept',
  123. key: 'authDept',
  124. noParam: true,
  125. label: '负责院系 *',
  126. rules: [v => !!v || '请填写您在学校负责的院系']
  127. },
  128. {
  129. slotName: 'tips',
  130. noParam: true
  131. },
  132. {
  133. slotName: 'employmentCertificate',
  134. key: 'employmentCertificate',
  135. value: '',
  136. col: 4,
  137. rules: [v => !!v || '请上传您的在岗证明图片']
  138. }
  139. ]
  140. })
  141. const formData = ref({})
  142. onMounted(async () => {
  143. await webContent.getSystemWebContent()
  144. // 获取性别字典数据
  145. const sexItem = formItems.value.options.find(e => e.key === 'sex')
  146. if (!sexItem || !Object.keys(sexItem).length) return
  147. const { data } = await getDict(sexItem.dictTypeName)
  148. sexItem.items = data || []
  149. // 获取学校列表
  150. const schoolItem = formItems.value.options.find(e => e.key === 'schoolId')
  151. if (!schoolItem || !Object.keys(schoolItem).length) return
  152. getDict('schoolList', {}, 'schoolList').then(({ data }) => {
  153. schoolItem.items = data || []
  154. })
  155. // 重新提交,数据回显
  156. formData.value = localStorage.getItem('registerSchoolInfo') ? JSON.parse(localStorage.getItem('registerSchoolInfo')) : {}
  157. if (formData.value && formData.value && formData.value?.authStatus === '2') {
  158. isUpdate.value = true
  159. departmentList.value = formData.value?.authDept || [{ name: '' }]
  160. formItems.value.options.forEach(item => {
  161. if (item.key !== 'authDept' && !item.noParam) item.value = formData.value[item.key] || item?.defaultValue
  162. })
  163. }
  164. })
  165. // 图片预览
  166. const handlePreview = (url) => {
  167. previewUrl.value = url
  168. showPreview.value = true
  169. }
  170. // 添加院系
  171. const handleAddDepartment = () => {
  172. departmentList.value.push({ name: '' })
  173. }
  174. // 删除院系
  175. const handleDeleteDepartment = (index) => {
  176. departmentList.value.splice(index, 1)
  177. }
  178. // 提交注册
  179. const handleSubmit = async () => {
  180. const { valid } = await CtFormRef.value.formRef.validate()
  181. if (!valid) return
  182. const isCheck = departmentList.value.every(item => item.name)
  183. if (!isCheck) return Snackbar.warning('请将院系信息填写完整')
  184. let obj = {
  185. authDept: departmentList.value
  186. }
  187. formItems.value.options.forEach(item => {
  188. if (item.noParam) return
  189. obj[item.key] = item.value
  190. })
  191. if (!obj.employmentCertificate) return Snackbar.warning('请上传在岗证明')
  192. // 修改信息需提交原始数据
  193. if (isUpdate.value) obj = Object.assign(formData.value, obj)
  194. try {
  195. await schoolRegister(obj)
  196. console.log(obj, 'submit-data提交成功,等待系统管理员审核')
  197. Snackbar.success('提交成功,等待系统管理员审核!')
  198. // 重新提交审核的需将authStatus改为0(待审核状态)
  199. localStorage.setItem('registerSchoolInfo', JSON.stringify({ ...obj, authStatus: '0' }))
  200. isUpdate.value = false
  201. router.push('/register/school/inReview')
  202. } catch {}
  203. }
  204. </script>
  205. <style scoped lang="scss">
  206. .navBar {
  207. position: absolute;
  208. top: 0;
  209. }
  210. .box {
  211. position: relative;
  212. width: 100%;
  213. height: 100%;
  214. background-size: cover;
  215. background-repeat: no-repeat;
  216. background-position: center center;
  217. }
  218. .content {
  219. position: absolute;
  220. top: 50%;
  221. left: 50%;
  222. translate: -50% -50%;
  223. width: 600px;
  224. height: 80%;
  225. overflow: auto;
  226. background-color: #fff;
  227. border-radius: 10px;
  228. }
  229. .upload-box {
  230. width: 100px;
  231. }
  232. </style>