basicInfo.vue 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. <template>
  2. <CtForm ref="CtFormRef" :items="items" style="width: 100%;"></CtForm>
  3. </template>
  4. <script setup>
  5. defineOptions({ name: 'resumeAnalysis-basicInfo'})
  6. import { ref, watch } from 'vue'
  7. import { checkEmail } from '@/utils/validate'
  8. import { getDict } from '@/hooks/web/useDictionaries'
  9. const props = defineProps({
  10. id: {
  11. type: String,
  12. default: ''
  13. },
  14. data: {
  15. type: Object,
  16. default: () => ({})
  17. }
  18. })
  19. const CtFormRef = ref()
  20. const userInfo = ref(JSON.parse(localStorage.getItem('userInfo')))
  21. const items = ref({
  22. options: [
  23. {
  24. type: 'text',
  25. key: 'name',
  26. value: null,
  27. default: null,
  28. label: '中文名 *',
  29. col: 6,
  30. outlined: true,
  31. rules: [
  32. value => {
  33. if (value) return true
  34. return '请输入您的中文名'
  35. },
  36. value => {
  37. var regex = /^[\u4e00-\u9fa5]+$/
  38. if (regex.test(value)) return true
  39. return '请输入正确的中文名'
  40. }
  41. ]
  42. },
  43. {
  44. type: 'text',
  45. key: 'foreignName',
  46. value: null,
  47. label: '英文名',
  48. col: 6,
  49. outlined: true,
  50. clearable: true,
  51. rules: [
  52. value => {
  53. if (!value) return true
  54. var regex = /^[A-Za-z]+(?:\s[A-Za-z]+)?$/
  55. if (regex.test(value)) return true
  56. return '请输入正确的英文名'
  57. }
  58. ]
  59. },
  60. {
  61. type: 'ifRadio',
  62. key: 'sex',
  63. value: null, // '1' ? '男' : '女'
  64. default: '1',
  65. label: '性别 *',
  66. col: 6,
  67. width: 50,
  68. dictTypeName: 'menduner_sex',
  69. items: [],
  70. },
  71. {
  72. type: 'phoneNumber',
  73. key: 'phone',
  74. value: null,
  75. default: userInfo?.value?.phone || '',
  76. label: '电话号码 *',
  77. col: 6,
  78. outlined: true,
  79. rules: [v => !!v || '请填写联系手机号']
  80. },
  81. {
  82. type: 'datePicker',
  83. mode: 'date',
  84. labelWidth: 80,
  85. key: 'birthday',
  86. value: new Date(2000, 0, 1).getTime(), // 月份是从 0 开始的
  87. label: '出生日期 *',
  88. disabledFutureDates: true,
  89. col: 6,
  90. format: 'YYYY/MM/DD',
  91. flexStyle: 'mb-7',
  92. outlined: true,
  93. rules: [v => !!v || '请选择出生日期']
  94. },
  95. {
  96. type: 'datePicker',
  97. mode: 'month',
  98. key: 'firstWorkTime',
  99. value: new Date(2000, 0).getTime(), // 月份是从 0 开始的
  100. disabledFutureDates: true,
  101. format: 'YYYY/MM',
  102. labelWidth: 90,
  103. flexStyle: 'mb-7',
  104. label: '首次工作时间',
  105. col: 6,
  106. outlined: true
  107. },
  108. {
  109. type: 'text',
  110. key: 'email',
  111. value: null,
  112. default: null,
  113. label: '常用邮箱 *',
  114. col: 6,
  115. outlined: true,
  116. rules: [
  117. value => {
  118. if (value) return true
  119. return '请输入联系邮箱'
  120. },
  121. value => {
  122. if (value && !checkEmail(value)) return '请输入正确的电子邮箱'
  123. return true
  124. }
  125. ]
  126. },
  127. {
  128. type: 'autocomplete',
  129. key: 'expType',
  130. value: null,
  131. default: null,
  132. label: '工作年限 *',
  133. col: 6,
  134. outlined: true,
  135. itemText: 'label',
  136. itemValue: 'value',
  137. dictTypeName: 'menduner_exp_type',
  138. rules: [v => !!v || '请选择工作年限'],
  139. items: []
  140. },
  141. {
  142. type: 'autocomplete',
  143. key: 'eduType',
  144. value: null,
  145. default: null,
  146. label: '最高学历 *',
  147. col: 6,
  148. outlined: true,
  149. itemText: 'label',
  150. itemValue: 'value',
  151. dictTypeName: 'menduner_education_type',
  152. rules: [v => !!v || '请选择最高学历'],
  153. items: []
  154. },
  155. {
  156. type: 'autocomplete',
  157. key: 'jobType',
  158. value: null,
  159. default: null,
  160. label: '求职类型 *',
  161. col: 6,
  162. outlined: true,
  163. itemText: 'label',
  164. itemValue: 'value',
  165. dictTypeName: 'menduner_job_type',
  166. rules: [v => !!v || '请选择求职类型'],
  167. items: []
  168. },
  169. {
  170. type: 'autocomplete',
  171. key: 'jobStatus',
  172. value: null,
  173. default: null,
  174. label: '求职状态 *',
  175. col: 6,
  176. outlined: true,
  177. itemText: 'label',
  178. itemValue: 'value',
  179. dictTypeName: 'menduner_job_seek_status',
  180. rules: [v => !!v || '请选择求职状态'],
  181. items: []
  182. },
  183. {
  184. type: 'autocomplete',
  185. key: 'maritalStatus',
  186. value: null,
  187. default: null,
  188. label: '婚姻状况',
  189. col: 6,
  190. outlined: true,
  191. itemText: 'label',
  192. itemValue: 'value',
  193. dictTypeName: 'menduner_marital_status',
  194. items: []
  195. },
  196. {
  197. type: 'cascade',
  198. key: 'areaId',
  199. value: null,
  200. default: null,
  201. label: '所在城市',
  202. itemText: 'name',
  203. itemValue: 'id',
  204. required: true,
  205. checkStrictly: true,
  206. clearable: false,
  207. col: 6,
  208. items: [],
  209. },
  210. {
  211. type: 'cascade',
  212. key: 'regId',
  213. value: null,
  214. default: null,
  215. label: '户籍地',
  216. itemText: 'name',
  217. itemValue: 'id',
  218. checkStrictly: true,
  219. required: false,
  220. clearable: true,
  221. col: 6,
  222. items: [],
  223. },
  224. ]
  225. })
  226. items.value.options.forEach(async (e, index) => {
  227. if ((index + 2) % 2 === 0) e.flexStyle = 'mr-3'
  228. if (e.dictTypeName) {
  229. const { data } = await getDict(e.dictTypeName)
  230. e.items = data
  231. }
  232. })
  233. watch(
  234. () => props.data,
  235. (newVal) => {
  236. if (newVal && Object.keys(newVal)) {
  237. items.value.options.forEach(e => {
  238. if (newVal[e.key]) e.value = newVal[e.key]
  239. else e.value = e.default || null
  240. })
  241. }
  242. },
  243. { immediate: true },
  244. )
  245. const submit = async () => {
  246. const { valid } = await CtFormRef.value.formRef.validate()
  247. if (!valid) return { id: props.id, data: null}
  248. const obj = {}
  249. items.value.options.forEach(e => obj[e.key] = e.value)
  250. return { id: props.id, data: obj}
  251. }
  252. defineExpose({
  253. id: props.id,
  254. submit
  255. })
  256. getDict('areaTreeData', null, 'areaTreeData').then(({ data }) => {
  257. data = data?.length && data || []
  258. if (!data?.length) return console.error('areaTreeData获取失败!')
  259. const chinaTreeData = data
  260. if (!chinaTreeData?.length) return console.error('chinaTreeData获取失败!')
  261. const workAreaProvince = items.value.options.find(e => e.key === 'areaId')
  262. const regAreaProvince = items.value.options.find(e => e.key === 'regId')
  263. if (workAreaProvince?.items) workAreaProvince.items = chinaTreeData
  264. if (regAreaProvince?.items) regAreaProvince.items = chinaTreeData
  265. })
  266. </script>
  267. <style lang="scss" scoped>
  268. </style>