basicInfo.vue 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  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: '2000-01-01',
  87. defaultValue: new Date(2000, 1, 1),
  88. label: '出生日期 *',
  89. disabledFutureDates: true,
  90. col: 6,
  91. format: 'YYYY/MM/DD',
  92. flexStyle: 'mb-7',
  93. outlined: true,
  94. rules: [v => !!v || '请选择出生日期']
  95. },
  96. {
  97. type: 'datePicker',
  98. mode: 'month',
  99. key: 'firstWorkTime',
  100. value: '2000-01',
  101. disabledFutureDates: true,
  102. defaultValue: new Date(2000, 1),
  103. format: 'YYYY/MM',
  104. labelWidth: 90,
  105. flexStyle: 'mb-7',
  106. label: '首次工作时间',
  107. col: 6,
  108. outlined: true
  109. },
  110. {
  111. type: 'text',
  112. key: 'email',
  113. value: null,
  114. default: null,
  115. label: '常用邮箱 *',
  116. col: 6,
  117. outlined: true,
  118. rules: [
  119. value => {
  120. if (value) return true
  121. return '请输入联系邮箱'
  122. },
  123. value => {
  124. if (value && !checkEmail(value)) return '请输入正确的电子邮箱'
  125. return true
  126. }
  127. ]
  128. },
  129. {
  130. type: 'autocomplete',
  131. key: 'expType',
  132. value: null,
  133. default: null,
  134. label: '工作年限 *',
  135. col: 6,
  136. outlined: true,
  137. itemText: 'label',
  138. itemValue: 'value',
  139. dictTypeName: 'menduner_exp_type',
  140. rules: [v => !!v || '请选择工作年限'],
  141. items: []
  142. },
  143. {
  144. type: 'autocomplete',
  145. key: 'eduType',
  146. value: null,
  147. default: null,
  148. label: '最高学历 *',
  149. col: 6,
  150. outlined: true,
  151. itemText: 'label',
  152. itemValue: 'value',
  153. dictTypeName: 'menduner_education_type',
  154. rules: [v => !!v || '请选择最高学历'],
  155. items: []
  156. },
  157. {
  158. type: 'autocomplete',
  159. key: 'jobType',
  160. value: null,
  161. default: null,
  162. label: '求职类型 *',
  163. col: 6,
  164. outlined: true,
  165. itemText: 'label',
  166. itemValue: 'value',
  167. dictTypeName: 'menduner_job_type',
  168. rules: [v => !!v || '请选择求职类型'],
  169. items: []
  170. },
  171. {
  172. type: 'autocomplete',
  173. key: 'jobStatus',
  174. value: null,
  175. default: null,
  176. label: '求职状态 *',
  177. col: 6,
  178. outlined: true,
  179. itemText: 'label',
  180. itemValue: 'value',
  181. dictTypeName: 'menduner_job_seek_status',
  182. rules: [v => !!v || '请选择求职状态'],
  183. items: []
  184. },
  185. {
  186. type: 'autocomplete',
  187. key: 'maritalStatus',
  188. value: null,
  189. default: null,
  190. label: '婚姻状况',
  191. col: 6,
  192. outlined: true,
  193. itemText: 'label',
  194. itemValue: 'value',
  195. dictTypeName: 'menduner_marital_status',
  196. items: []
  197. },
  198. {
  199. type: 'cascade',
  200. key: 'areaId',
  201. value: null,
  202. default: null,
  203. label: '所在城市',
  204. itemText: 'name',
  205. itemValue: 'id',
  206. required: true,
  207. checkStrictly: true,
  208. clearable: false,
  209. col: 6,
  210. items: [],
  211. },
  212. {
  213. type: 'cascade',
  214. key: 'regId',
  215. value: null,
  216. default: null,
  217. label: '户籍地',
  218. itemText: 'name',
  219. itemValue: 'id',
  220. checkStrictly: true,
  221. required: false,
  222. clearable: true,
  223. col: 6,
  224. items: [],
  225. },
  226. ]
  227. })
  228. items.value.options.forEach(async (e, index) => {
  229. if ((index + 2) % 2 === 0) e.flexStyle = 'mr-3'
  230. if (e.dictTypeName) {
  231. const { data } = await getDict(e.dictTypeName)
  232. e.items = data
  233. }
  234. })
  235. watch(
  236. () => props.data,
  237. (newVal) => {
  238. if (newVal && Object.keys(newVal)) {
  239. items.value.options.forEach(e => {
  240. if (newVal[e.key]) e.value = newVal[e.key]
  241. else e.value = e.default || null
  242. })
  243. }
  244. },
  245. { immediate: true },
  246. )
  247. const submit = async () => {
  248. const { valid } = await CtFormRef.value.formRef.validate()
  249. if (!valid) return { id: props.id, data: null}
  250. const obj = {}
  251. items.value.options.forEach(e => obj[e.key] = e.value)
  252. return { id: props.id, data: obj}
  253. }
  254. defineExpose({
  255. id: props.id,
  256. submit
  257. })
  258. getDict('areaTreeData', null, 'areaTreeData').then(({ data }) => {
  259. data = data?.length && data || []
  260. if (!data?.length) return console.error('areaTreeData获取失败!')
  261. const chinaTreeData = data
  262. if (!chinaTreeData?.length) return console.error('chinaTreeData获取失败!')
  263. const workAreaProvince = items.value.options.find(e => e.key === 'areaId')
  264. const regAreaProvince = items.value.options.find(e => e.key === 'regId')
  265. if (workAreaProvince?.items) workAreaProvince.items = chinaTreeData
  266. if (regAreaProvince?.items) regAreaProvince.items = chinaTreeData
  267. })
  268. </script>
  269. <style lang="scss" scoped>
  270. </style>