addOperation.vue 41 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120
  1. <template>
  2. <div>
  3. <el-form
  4. :model="operationForm"
  5. ref="OperationFormRef"
  6. :rules="operationRules"
  7. label-width="120"
  8. >
  9. <el-descriptions title="基本信息">
  10. <el-descriptions-item>
  11. <template #default>
  12. <el-row :gutter="20">
  13. <el-col :span="10">
  14. <el-form-item prop="typeAttr" label="业务员类型">
  15. <el-select v-model="operationForm.typeAttr" placeholder="请选择业务员类型">
  16. <el-option key="1" value="0" label="个代"></el-option>
  17. <el-option key="2" value="1" label="渠道"></el-option>
  18. <el-option key="3" value="2" label="团队"></el-option>
  19. <el-option key="4" value="3" label="电销组"></el-option>
  20. <!-- <el-option key="1" value="1" label="前线人员"></el-option>
  21. <el-option key="2" value="2" label="后线人员"></el-option>
  22. <el-option key="3" value="3" label="合伙人"></el-option>
  23. <el-option key="4" value="4" label="工作室管理员"></el-option>
  24. <el-option key="5" value="5" label="团队"></el-option>
  25. <el-option key="6" value="6" label="个代"></el-option>
  26. <el-option key="7" value="7" label="电销"></el-option>
  27. <el-option key="8" value="8" label="渠道"></el-option>-->
  28. </el-select>
  29. </el-form-item>
  30. </el-col>
  31. <el-col :span="10">
  32. <el-form-item prop="deptId" label="所属团队">
  33. <el-select v-model="operationForm.organizationId" placeholder="请选择所属团队" @change="deptChange">
  34. <el-option v-for="item in teamList" :key="item.id" :value="item.id" :label="item.name"></el-option>
  35. </el-select>
  36. </el-form-item>
  37. </el-col>
  38. </el-row>
  39. <el-row :gutter="20">
  40. <el-col :span="10">
  41. <el-form-item prop="name" label="姓名">
  42. <el-input v-model="operationForm.name" placeholder="请填写姓名"></el-input>
  43. </el-form-item>
  44. </el-col>
  45. <el-col :span="10">
  46. <el-form-item prop="mobile" label="手机号">
  47. <el-input v-model="operationForm.mobile" placeholder="请填写手机号"></el-input>
  48. </el-form-item>
  49. </el-col>
  50. </el-row>
  51. <el-row :gutter="20">
  52. <el-col :span="10">
  53. <el-form-item prop="organization" label="所属机构">
  54. <el-input disabled v-model="operationForm.organization"></el-input>
  55. <!-- <el-cascader style="width: 100%" v-model="operationForm.organization" placeholder="请选择所属机构" :options="option" :props="cascaderProps"></el-cascader>-->
  56. </el-form-item>
  57. </el-col>
  58. <el-col :span="10">
  59. <el-form-item prop="identity" label="证件号">
  60. <el-input v-model="operationForm.identity" placeholder="请填写身份证号"></el-input>
  61. </el-form-item>
  62. </el-col>
  63. </el-row>
  64. <el-row :gutter="20">
  65. <el-col :span="10">
  66. <el-form-item prop="identityTimeStart" label="证件有效期始">
  67. <el-date-picker
  68. v-model="operationForm.identityTimeStart"
  69. type="date"
  70. placeholder="请选择"
  71. format="YYYY-MM-DD"
  72. value-format="YYYY-MM-DD"
  73. style="width: 100%"
  74. />
  75. </el-form-item>
  76. </el-col>
  77. <el-col :span="10">
  78. <el-form-item prop="identityTimeEnd" label="证件有效期止">
  79. <el-date-picker
  80. v-model="operationForm.identityTimeEnd"
  81. type="date"
  82. placeholder="请选择"
  83. format="YYYY-MM-DD"
  84. value-format="YYYY-MM-DD"
  85. style="width: 100%"
  86. />
  87. </el-form-item>
  88. </el-col>
  89. </el-row>
  90. </template>
  91. </el-descriptions-item>
  92. </el-descriptions>
  93. <el-descriptions title="其他信息">
  94. <el-descriptions-item>
  95. <template #default>
  96. <el-row :gutter="20">
  97. <el-col :span="10">
  98. <el-form-item prop="leaderId" label="管理人">
  99. <el-select v-model="operationForm.leaderId" filterable placeholder="请选择管理人" @change="(e) => {operationForm.leaderNumber = e}">
  100. <el-option v-for="(item, index) in userList" :key="item.id" :value="item.id" :label="item.name"></el-option>
  101. </el-select>
  102. </el-form-item>
  103. </el-col>
  104. <el-col :span="10">
  105. <el-form-item prop="leaderNumber" label="管理人工号">
  106. <el-input readonly v-model="operationForm.leaderNumber" placeholder="请填写管理人工号"></el-input>
  107. </el-form-item>
  108. </el-col>
  109. </el-row>
  110. <el-row :gutter="20">
  111. <el-col :span="10">
  112. <el-form-item prop="referrerId" label="推荐人">
  113. <el-select v-model="operationForm.referrerId" filterable placeholder="请选择推荐人" @change="(e) => {operationForm.referrerNumber = e}">
  114. <el-option v-for="(item, index) in userList" :key="item.id" :value="item.id" :label="item.name"></el-option>
  115. </el-select>
  116. </el-form-item>
  117. </el-col>
  118. <el-col :span="10">
  119. <el-form-item prop="referrerNumber" label="推荐人工号">
  120. <el-input readonly v-model="operationForm.referrerNumber" placeholder="请填写推荐人工号"></el-input>
  121. </el-form-item>
  122. </el-col>
  123. </el-row>
  124. </template>
  125. </el-descriptions-item>
  126. </el-descriptions>
  127. <el-descriptions title="资料附件">
  128. <el-descriptions-item>
  129. <template #default>
  130. <el-form-item prop="" label="身份证(人像面)" label-width="150">
  131. <el-upload action="" v-if="!IDCardFront" :auto-upload="false" :show-file-list="false" accept=".png, .jpg, .jpeg" @change="uploadImage($event, 1)">
  132. <el-button link type="primary">上传</el-button>
  133. </el-upload>
  134. <div class="fileInfo" v-else>
  135. <div class="fileName">{{ IDCardFrontName }}</div>
  136. <div class="fileBtn">
  137. <el-upload :show-file-list="false" :auto-upload="false" accept=".png, .jpg, .jpeg" @change="uploadImage($event, 1)" style="display: flex; align-items: center">
  138. <el-icon class="btn-icon"><Upload /></el-icon>
  139. </el-upload>
  140. <el-icon class="btn-icon" @click="imageView(1)"><View /></el-icon>
  141. <el-icon class="btn-icon" @click="downloadImage(1)"><Download /></el-icon>
  142. <el-icon class="btn-icon" @click="deleteImage(1)"><Delete /></el-icon>
  143. </div>
  144. </div>
  145. </el-form-item>
  146. <el-form-item prop="" label="身份证(国徽面)" label-width="150">
  147. <el-upload v-if="!IDCardBack" :auto-upload="false" :show-file-list="false" accept=".png, .jpg, .jpeg" @change="uploadImage($event, 2)">
  148. <el-button link type="primary">上传</el-button>
  149. </el-upload>
  150. <div class="fileInfo" v-else>
  151. <div class="fileName">{{ IDCardBackName }}</div>
  152. <div class="fileBtn">
  153. <el-upload :auto-upload="false" :show-file-list="false" accept=".png, .jpg, .jpeg" @change="uploadImage($event, 2)" style="display: flex; align-items: center">
  154. <el-icon class="btn-icon"><Upload /></el-icon>
  155. </el-upload>
  156. <el-icon class="btn-icon" @click="imageView(2)"><View /></el-icon>
  157. <el-icon class="btn-icon" @click="downloadImage(2)"><Download /></el-icon>
  158. <el-icon class="btn-icon" @click="deleteImage(2)"><Delete /></el-icon>
  159. </div>
  160. </div>
  161. </el-form-item>
  162. <el-form-item prop="" label="展业资格证" label-width="150">
  163. <el-upload :auto-upload="false" v-if="!certification" :show-file-list="false" accept=".png, .jpg, .jpeg" @change="uploadImage($event, 3)">
  164. <el-button link type="primary">上传</el-button>
  165. </el-upload>
  166. <div class="fileInfo" v-else>
  167. <div class="fileName">{{ certificationName }}</div>
  168. <div class="fileBtn">
  169. <el-upload :auto-upload="false" :show-file-list="false" accept=".png, .jpg, .jpeg" @change="uploadImage($event, 3)" style="display: flex; align-items: center">
  170. <el-icon class="btn-icon"><Upload /></el-icon>
  171. </el-upload>
  172. <el-icon class="btn-icon" @click="imageView(3)"><View /></el-icon>
  173. <el-icon class="btn-icon" @click="downloadImage(3)"><Download /></el-icon>
  174. <el-icon class="btn-icon" @click="deleteImage(3)"><Delete /></el-icon>
  175. </div>
  176. </div>
  177. </el-form-item>
  178. </template>
  179. </el-descriptions-item>
  180. </el-descriptions>
  181. <el-divider />
  182. <el-button v-if="!recordShow" link type="primary" icon="plus" @click="recordShow = !recordShow">填写人事档案(选填)</el-button>
  183. <el-button v-else link type="primary" icon="ArrowUp" @click="recordShow = !recordShow">收起人事档案(选填)</el-button>
  184. <br/><br/>
  185. <el-descriptions title="个人信息" v-show="recordShow">
  186. <el-descriptions-item>
  187. <template #default>
  188. <el-row :gutter="20">
  189. <el-col :span="10">
  190. <el-form-item prop="sex" label="性别">
  191. <el-select v-model="operationForm.sex" placeholder="请选择性别">
  192. <el-option v-for="item in options[0]" :key="item.value" :value="item.value" :label="item.label"></el-option>
  193. </el-select>
  194. </el-form-item>
  195. </el-col>
  196. <el-col :span="10">
  197. <el-form-item prop="birthday" label="出生日期">
  198. <el-date-picker
  199. v-model="operationForm.birthday"
  200. type="date"
  201. placeholder="请选择"
  202. format="YYYY-MM-DD"
  203. value-format="YYYY-MM-DD"
  204. style="width: 100%"
  205. />
  206. </el-form-item>
  207. </el-col>
  208. </el-row>
  209. <el-row :gutter="20">
  210. <el-col :span="10">
  211. <el-form-item prop="nations" label="民族">
  212. <el-select v-model="operationForm.nations" placeholder="请选择业务员类型">
  213. <el-option v-for="item in options[1]" :key="item.value" :value="item.value" :label="item.label"></el-option>
  214. </el-select>
  215. </el-form-item>
  216. </el-col>
  217. <el-col :span="10">
  218. <el-form-item prop="koseki" label="户籍">
  219. <el-input v-model="operationForm.koseki" placeholder="请填写户籍"></el-input>
  220. </el-form-item>
  221. </el-col>
  222. </el-row>
  223. <el-row :gutter="20">
  224. <el-col :span="10">
  225. <el-form-item prop="maritalStatus" label="婚姻状况">
  226. <el-select v-model="operationForm.maritalStatus" placeholder="请选择婚姻状况">
  227. <el-option v-for="item in options[2]" :key="item.value" :value="item.value" :label="item.label"></el-option>
  228. </el-select>
  229. </el-form-item>
  230. </el-col>
  231. <el-col :span="10">
  232. <el-form-item prop="politicsStatus" label="政治面貌">
  233. <el-select v-model="operationForm.politicsStatus" placeholder="请选择政治面貌">
  234. <el-option v-for="item in options[3]" :key="item.value" :value="item.value" :label="item.label"></el-option>
  235. </el-select>
  236. </el-form-item>
  237. </el-col>
  238. </el-row>
  239. <el-row :gutter="20">
  240. <el-col :span="10">
  241. <el-form-item prop="health" label="健康状况">
  242. <el-select v-model="operationForm.health" placeholder="请选择健康状况">
  243. <el-option v-for="item in options[4]" :key="item.value" :value="item.value" :label="item.label"></el-option>
  244. </el-select>
  245. </el-form-item>
  246. </el-col>
  247. <el-col :span="10">
  248. <el-form-item prop="address" label="居住地区">
  249. <el-cascader
  250. clearable
  251. style="width: 100%"
  252. v-model="operationForm.address"
  253. :options="areaOptions"
  254. :props="areaProps"
  255. />
  256. </el-form-item>
  257. </el-col>
  258. </el-row>
  259. <el-row :gutter="20">
  260. <el-col :span="10">
  261. <el-form-item prop="liveAddress" label="详细地址">
  262. <el-input v-model="operationForm.liveAddress" placeholder="请填写详细地址"></el-input>
  263. </el-form-item>
  264. </el-col>
  265. <el-col :span="10">
  266. <el-form-item prop="postalCode" label="邮政编码">
  267. <el-input v-model="operationForm.postalCode" placeholder="请填写邮政编码"></el-input>
  268. </el-form-item>
  269. </el-col>
  270. </el-row>
  271. </template>
  272. </el-descriptions-item>
  273. </el-descriptions>
  274. <el-descriptions title="学历信息" v-show="recordShow">
  275. <el-descriptions-item>
  276. <template #default>
  277. <el-row :gutter="20">
  278. <el-col :span="10">
  279. <el-form-item prop="education" label="学历">
  280. <el-select v-model="operationForm.education" placeholder="请选择学历">
  281. <el-option v-for="item in options[5]" :key="item.value" :value="item.value" :label="item.label"></el-option>
  282. </el-select>
  283. </el-form-item>
  284. </el-col>
  285. <el-col :span="10">
  286. <el-form-item prop="graduationTime" label="毕业时间">
  287. <el-date-picker
  288. v-model="operationForm.graduationTime"
  289. type="date"
  290. placeholder="请选择"
  291. format="YYYY-MM-DD"
  292. value-format="YYYY-MM-DD"
  293. style="width: 100%"
  294. />
  295. </el-form-item>
  296. </el-col>
  297. </el-row>
  298. <el-row :gutter="20">
  299. <el-col :span="10">
  300. <el-form-item prop="school" label="毕业院校">
  301. <el-input v-model="operationForm.school" placeholder="请填写毕业院校"></el-input>
  302. </el-form-item>
  303. </el-col>
  304. <el-col :span="10">
  305. <el-form-item prop="isComputer" label="是否计算机专业">
  306. <el-select v-model="operationForm.isComputer" placeholder="请选择是否计算机专业">
  307. <el-option key="1" value="1" label="是"></el-option>
  308. <el-option key="0" value="0" label="否"></el-option>
  309. </el-select>
  310. </el-form-item>
  311. </el-col>
  312. </el-row>
  313. </template>
  314. </el-descriptions-item>
  315. </el-descriptions>
  316. <el-descriptions title="紧急联系人信息" v-show="recordShow">
  317. <el-descriptions-item>
  318. <template #default>
  319. <el-row :gutter="20">
  320. <el-col :span="10">
  321. <el-form-item prop="emergencyContactName" label="姓名">
  322. <el-input v-model="operationForm.emergencyContactName" placeholder="请填写姓名"></el-input>
  323. </el-form-item>
  324. </el-col>
  325. <el-col :span="10">
  326. <el-form-item prop="emergencyContactTel" label="手机号">
  327. <el-input v-model="operationForm.emergencyContactTel" placeholder="请填写手机号"></el-input>
  328. </el-form-item>
  329. </el-col>
  330. </el-row>
  331. </template>
  332. </el-descriptions-item>
  333. </el-descriptions>
  334. <el-descriptions title="工资信息" v-show="recordShow">
  335. <el-descriptions-item>
  336. <template #default>
  337. <el-row :gutter="20">
  338. <el-col :span="10">
  339. <el-form-item prop="salary" label="工资">
  340. <el-input v-model="operationForm.salary" placeholder="请填写工资"></el-input>
  341. </el-form-item>
  342. </el-col>
  343. <el-col :span="10">
  344. <el-form-item prop="salaryLevel" label="工资等级">
  345. <el-input v-model="operationForm.salaryLevel" placeholder="请填写工资等级"></el-input>
  346. </el-form-item>
  347. </el-col>
  348. </el-row>
  349. <el-row :gutter="20">
  350. <el-col :span="10">
  351. <el-form-item prop="bankCardId" label="银行卡号">
  352. <el-input v-model="operationForm.bankCardId" placeholder="请填写银行卡号"></el-input>
  353. </el-form-item>
  354. </el-col>
  355. <el-col :span="10">
  356. <el-form-item prop="bankName" label="开户行">
  357. <el-select v-model="operationForm.bankName" placeholder="请选择开户行">
  358. <el-option v-for="item in bankOption" :key="item.id" :value="item.id" :label="item.label"></el-option>
  359. </el-select>
  360. </el-form-item>
  361. </el-col>
  362. </el-row>
  363. </template>
  364. </el-descriptions-item>
  365. </el-descriptions>
  366. <el-divider v-show="recordShow" />
  367. <el-descriptions v-show="recordShow" title="其它附件">
  368. <el-descriptions-item>
  369. <template #default>
  370. <el-form-item prop="" label="劳动合同" label-width="150">
  371. <el-upload v-if="!contract" :auto-upload="false" :show-file-list="false" accept=".png, .jpg, .jpeg" @change="uploadImage($event, 4)">
  372. <el-button link type="primary">上传</el-button>
  373. </el-upload>
  374. <div class="fileInfo" v-else>
  375. <div class="fileName">{{ contractName }}</div>
  376. <div class="fileBtn">
  377. <el-upload :auto-upload="false" :show-file-list="false" accept=".png, .jpg, .jpeg" @change="uploadImage($event, 4)" style="display: flex; align-items: center">
  378. <el-icon class="btn-icon"><Upload /></el-icon>
  379. </el-upload>
  380. <el-icon class="btn-icon" @click="imageView(4)"><View /></el-icon>
  381. <el-icon class="btn-icon" @click="downloadImage(4)"><Download /></el-icon>
  382. <el-icon class="btn-icon" @click="deleteImage(4)"><Delete /></el-icon>
  383. </div>
  384. </div>
  385. </el-form-item>
  386. <el-form-item prop="" label="应聘表" label-width="150">
  387. <el-upload v-if="!applicant" :auto-upload="false" :show-file-list="false" accept=".png, .jpg, .jpeg" @change="uploadImage($event, 5)">
  388. <el-button link type="primary">上传</el-button>
  389. </el-upload>
  390. <div class="fileInfo" v-else>
  391. <div class="fileName">{{ applicantName }}</div>
  392. <div class="fileBtn">
  393. <el-upload :auto-upload="false" :show-file-list="false" accept=".png, .jpg, .jpeg" @change="uploadImage($event, 5)" style="display: flex; align-items: center">
  394. <el-icon class="btn-icon"><Upload /></el-icon>
  395. </el-upload>
  396. <el-icon class="btn-icon" @click="imageView(5)"><View /></el-icon>
  397. <el-icon class="btn-icon" @click="downloadImage(5)"><Download /></el-icon>
  398. <el-icon class="btn-icon" @click="deleteImage(5)"><Delete /></el-icon>
  399. </div>
  400. </div>
  401. </el-form-item>
  402. <el-form-item prop="" label="定薪表" label-width="150">
  403. <el-upload :auto-upload="false" v-if="!decidePay" :show-file-list="false" accept=".png, .jpg, .jpeg" @change="uploadImage($event, 6)">
  404. <el-button link type="primary">上传</el-button>
  405. </el-upload>
  406. <div class="fileInfo" v-else>
  407. <div class="fileName">{{ decidePayName }}</div>
  408. <div class="fileBtn">
  409. <el-upload :auto-upload="false" :show-file-list="false" accept=".png, .jpg, .jpeg" @change="uploadImage($event, 6)" style="display: flex; align-items: center">
  410. <el-icon class="btn-icon"><Upload /></el-icon>
  411. </el-upload>
  412. <el-icon class="btn-icon" @click="imageView(6)"><View /></el-icon>
  413. <el-icon class="btn-icon" @click="downloadImage(6)"><Download /></el-icon>
  414. <el-icon class="btn-icon" @click="deleteImage(6)"><Delete /></el-icon>
  415. </div>
  416. </div>
  417. </el-form-item>
  418. <el-form-item prop="" label="离职表" label-width="150">
  419. <el-upload :auto-upload="false" v-if="!dimission" :show-file-list="false" accept=".png, .jpg, .jpeg" @change="uploadImage($event, 7)">
  420. <el-button link type="primary">上传</el-button>
  421. </el-upload>
  422. <div class="fileInfo" v-else>
  423. <div class="fileName">{{ dimissionName }}</div>
  424. <div class="fileBtn">
  425. <el-upload :auto-upload="false" :show-file-list="false" accept=".png, .jpg, .jpeg" @change="uploadImage($event, 7)" style="display: flex; align-items: center">
  426. <el-icon class="btn-icon"><Upload /></el-icon>
  427. </el-upload>
  428. <el-icon class="btn-icon" @click="imageView(7)"><View /></el-icon>
  429. <el-icon class="btn-icon" @click="downloadImage(7)"><Download /></el-icon>
  430. <el-icon class="btn-icon" @click="deleteImage(7)"><Delete /></el-icon>
  431. </div>
  432. </div>
  433. </el-form-item>
  434. </template>
  435. </el-descriptions-item>
  436. </el-descriptions>
  437. <div style="display: flex; justify-content: flex-end">
  438. <el-button @click="onSubmit(OperationFormRef, 0)">取消</el-button>
  439. <el-button type="primary" @click="onSubmit(OperationFormRef, 1)">确定</el-button>
  440. </div>
  441. </el-form>
  442. <div class="image-view" v-if="imageShow" @click="imageShow = false">
  443. <img :src="imageUrl" />
  444. </div>
  445. </div>
  446. </template>
  447. <script setup lang="ts">
  448. import { ref, reactive, defineEmits, onMounted } from 'vue'
  449. import type { AddOperation } from '@/api/modules/operation.ts'
  450. import type { FormRules, FormInstance } from "element-plus";
  451. import api from "@/api";
  452. import { ElMessage } from "element-plus";
  453. interface OperationFormProps extends AddOperation {
  454. organization: string
  455. leaderNumber: string,
  456. referrerNumber: string,
  457. address?: string[],
  458. id?: string
  459. }
  460. let emits = defineEmits(['closeDialog'])
  461. let option = ref([])
  462. const OperationFormRef = ref<FormInstance>()
  463. // 添加/编辑业务员表单
  464. let operationForm = ref<OperationFormProps>({
  465. typeAttr: '',
  466. deptId: '',
  467. organizationId: '',
  468. name: '',
  469. mobile: '',
  470. identity: '',
  471. identityTimeStart: '',
  472. identityTimeEnd: '',
  473. leaderId: '',
  474. leaderNumber: '',
  475. referrerId: '',
  476. referrerNumber: '',
  477. sex: null,
  478. birthday: null,
  479. nations: null,
  480. koseki: null,
  481. maritalStatus: null,
  482. politicsStatus: null,
  483. health: null,
  484. province: null,
  485. city: null,
  486. district: null,
  487. address: [],
  488. liveAddress: null,
  489. postalCode: null,
  490. education: null,
  491. graduationTime: null,
  492. school: null,
  493. isComputer: null,
  494. emergencyContactName: null,
  495. emergencyContactTel: null,
  496. salary: null,
  497. salaryLevel: null,
  498. bankCardId: null,
  499. bankName: null,
  500. sfz1: null,
  501. sfz2: null,
  502. qualification: null,
  503. contract: null,
  504. applicant: null,
  505. salaryTable: null,
  506. leaveTable: null
  507. })
  508. // 机构数据渲染格式
  509. const cascaderProps = {
  510. value: 'id',
  511. label: 'name',
  512. children: 'children'
  513. }
  514. // 添加/编辑业务员表单校验
  515. const operationRules = ref<FormRules>({
  516. typeAttr: [
  517. { required: true, trigger: "change", message: "请选择业务员类型" }
  518. ],
  519. deptId: [
  520. { required: true, trigger: "change", message: "请选择所属团队" }
  521. ],
  522. name: [
  523. { required: true, trigger: "blur", message: "请填写姓名" }
  524. ],
  525. mobile: [
  526. { required: true, trigger: "blur", message: "请填写手机号" },
  527. {
  528. pattern: /^1[345678][0-9]{9}$/,
  529. message: '请填写正确的手机号',
  530. trigger: 'blur'
  531. }
  532. ],
  533. organization: [
  534. { required: true, trigger: "change", message: "请选择所属机构" }
  535. ],
  536. identity: [
  537. { required: true, trigger: "blur", message: "请填写证件号" },
  538. {
  539. pattern: /^[1-9]\d{5}(19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9X]$/,
  540. message: '请填写正确的身份证号',
  541. trigger: 'blur'
  542. }
  543. ],
  544. identityTimeStart: [
  545. { required: true, trigger: "change", message: "请选择证件有效期始" }
  546. ],
  547. identityTimeEnd: [
  548. { required: true, trigger: "change", message: "请选择证件有效期止" }
  549. ],
  550. leaderId: [
  551. { required: true, trigger: "change", message: "请选择管理人" }
  552. ],
  553. leaderNumber: [
  554. { required: true, trigger: "blur", message: "请填写管理人工号" }
  555. ],
  556. referrerId: [
  557. { required: true, trigger: "change", message: "请选择推荐人" }
  558. ],
  559. referrerNumber: [
  560. { required: true, trigger: "blur", message: "请填写推荐人工号" }
  561. ],
  562. bankCardId: [
  563. {
  564. pattern: /^([1-9]{1})(\d{15}|\d{16}|\d{18})$/,
  565. message: '请填写正确的银行卡号',
  566. trigger: 'blur'
  567. }
  568. ],
  569. emergencyContactTel: [
  570. {
  571. pattern: /^1[34578][0-9]{9}$/,
  572. message: '请填写正确的手机号',
  573. trigger: 'blur'
  574. }
  575. ],
  576. postalCode: [
  577. {
  578. pattern: /^\d{6}$/,
  579. message: '请填写正确的邮政编码',
  580. trigger: 'blur'
  581. }
  582. ]
  583. })
  584. // 身份证人像面
  585. let IDCardFrontName = ref('')
  586. let IDCardFront = ref('')
  587. // 身份证国徽面
  588. let IDCardBackName = ref('')
  589. let IDCardBack = ref('')
  590. // 展业资格证
  591. let certificationName = ref('')
  592. let certification = ref('')
  593. // 劳务合同
  594. let contractName = ref('')
  595. let contract = ref('')
  596. // 应聘表
  597. let applicantName = ref('')
  598. let applicant = ref('')
  599. // 定薪表
  600. let decidePayName = ref('')
  601. let decidePay = ref('')
  602. // 离职表
  603. let dimissionName = ref('')
  604. let dimission = ref('')
  605. // 图片预览地址
  606. let imageShow = ref(false)
  607. let imageUrl = ref('')
  608. // 编辑时初始化数据
  609. // 编辑的id
  610. let editId = ref('')
  611. const initEditData = (id) => {
  612. if(id) {
  613. editId.value = id
  614. api.operationApi.operationDetail(id).then(res => {
  615. if(res?.code == 200) {
  616. let formData = res.data
  617. operationForm.value = formData
  618. operationForm.value.organization = formData.deptName
  619. operationForm.value.deptId = formData.deptId
  620. operationForm.value.leaderNumber = formData.leaderId
  621. operationForm.value.referrerNumber = formData.referrerId
  622. let address = []
  623. if(formData.province&&formData.city&&formData.district) {
  624. address = [formData.province, formData.city, formData.district]
  625. }
  626. if(formData.province&&!formData.city&&!formData.district) {
  627. address = [formData.province]
  628. }
  629. if(formData.fileList) {
  630. let sfz1 = formData.fileList.find(item => item.fileType == 'sfz1')
  631. let sfz2 = formData.fileList.find(item => item.fileType == 'sfz2')
  632. let qualification = formData.fileList.find(item => item.fileType == 'qualification')
  633. let contractImg = formData.fileList.find(item => item.fileType == 'contract')
  634. let applicantImg = formData.fileList.find(item => item.fileType == 'applicant')
  635. let salaryTable = formData.fileList.find(item => item.fileType == 'salary')
  636. let leaveTable = formData.fileList.find(item => item.fileType == 'leave')
  637. if(sfz1) {
  638. operationForm.value.sfz1 = sfz1.id
  639. IDCardFrontName.value = sfz1.fileName
  640. IDCardFront.value = sfz1.fileUrl
  641. }
  642. if(sfz2) {
  643. operationForm.value.sfz2 = sfz2.id
  644. IDCardBackName.value = sfz2.fileName
  645. IDCardBack.value = sfz2.fileUrl
  646. }
  647. if(qualification) {
  648. operationForm.value.qualification = qualification.id
  649. certificationName.value = qualification.fileName
  650. certification.value = qualification.fileUrl
  651. }
  652. if(contractImg) {
  653. operationForm.value.contract = contract.id
  654. contractName.value = contractImg.fileName
  655. contract.value = contractImg.fileUrl
  656. }
  657. if(applicantImg) {
  658. operationForm.value.applicant = applicant.id
  659. applicantName.value = applicantImg.fileName
  660. applicant.value = applicantImg.fileUrl
  661. }
  662. if(salaryTable) {
  663. operationForm.value.salaryTable = salaryTable.id
  664. decidePayName.value = salaryTable.fileName
  665. decidePay.value = salaryTable.fileUrl
  666. }
  667. if(leaveTable) {
  668. operationForm.value.leaveTable = leaveTable.id
  669. dimissionName.value = leaveTable.fileName
  670. dimission.value = leaveTable.fileUrl
  671. }
  672. }
  673. operationForm.value.address = address
  674. getUser(operationForm.value.deptId)
  675. } else {
  676. ElMessage({
  677. message: res.msg,
  678. type: 'warning'
  679. })
  680. }
  681. })
  682. }
  683. }
  684. // 上传接口
  685. let postUrl = ref(`${import.meta.env.VITE_APP_API_BASEURL}/file/upload`)
  686. // 上传图片
  687. const uploadImage = async (file, type) => {
  688. let files = file.raw
  689. const params = new FormData(); // 声明formData数据类型
  690. params.append("file", files);
  691. params.append("type", "image");
  692. const { code, data, msg } = await api.commonApi.fileUpload(params)
  693. if(code == 200) {
  694. let result = {...data}
  695. switch (type) {
  696. case 1:
  697. IDCardFrontName.value = result.fileName
  698. IDCardFront.value = result.downloadUrl
  699. operationForm.value.sfz1 = result.id
  700. break;
  701. case 2:
  702. IDCardBackName.value = result.fileName
  703. IDCardBack.value = result.downloadUrl
  704. operationForm.value.sfz2 = result.id
  705. break;
  706. case 3:
  707. certificationName.value = result.fileName
  708. certification.value = result.downloadUrl
  709. operationForm.value.qualification = result.id
  710. break;
  711. case 4:
  712. contractName.value = result.fileName
  713. contract.value = result.downloadUrl
  714. operationForm.value.contract = result.id
  715. break;
  716. case 5:
  717. applicantName.value = result.fileName
  718. applicant.value = result.downloadUrl
  719. operationForm.value.applicant = result.id
  720. break;
  721. case 6:
  722. decidePayName.value = result.fileName
  723. decidePay.value = result.downloadUrl
  724. operationForm.value.salaryTable = result.id
  725. break;
  726. case 7:
  727. dimissionName.value = result.fileName
  728. dimission.value = result.downloadUrl
  729. operationForm.value.leaveTable = result.id
  730. break;
  731. }
  732. } else {
  733. ElMessage({
  734. message: msg,
  735. type: 'error'
  736. })
  737. }
  738. }
  739. // 人事档案
  740. let recordShow = ref(false)
  741. // 图片预览
  742. const imageView = (type) => {
  743. imageShow.value = true
  744. switch (type) {
  745. case 1:
  746. imageUrl.value = IDCardFront.value
  747. break;
  748. case 2:
  749. imageUrl.value = IDCardBack.value
  750. break;
  751. case 3:
  752. imageUrl.value = certification.value
  753. break;
  754. case 4:
  755. imageUrl.value = contract.value
  756. break;
  757. case 5:
  758. imageUrl.value = applicant.value
  759. break;
  760. case 6:
  761. imageUrl.value = decidePay.value
  762. break;
  763. case 7:
  764. imageUrl.value = dimission.value
  765. break;
  766. }
  767. }
  768. // 图片下载
  769. const download = (url, name) => {
  770. let image = new Image();
  771. // 解决跨域 Canvas 污染问题
  772. image.setAttribute("crossOrigin", "anonymous");
  773. image.onload = function () {
  774. let canvas = document.createElement("canvas");
  775. canvas.width = image.width;
  776. canvas.height = image.height;
  777. let context = canvas.getContext("2d");
  778. context.drawImage(image, 0, 0, image.width, image.height);
  779. let url = canvas.toDataURL("image/png"); //得到图片的base64编码数据
  780. let a = document.createElement("a"); // 生成一个a元素
  781. let event = new MouseEvent("click"); // 创建一个单击事件
  782. a.download = name; // 设置图片名称
  783. a.href = url; // 将生成的URL设置为a.href属性
  784. a.dispatchEvent(event); // 触发a的单击事件
  785. }
  786. image.src = url
  787. }
  788. const downloadImage = (type) => {
  789. switch (type) {
  790. case 1:
  791. download(IDCardFront.value,IDCardFrontName.value)
  792. break;
  793. case 2:
  794. download(IDCardBack.value,IDCardBackName.value)
  795. break;
  796. case 3:
  797. download(certification.value,certificationName.value)
  798. break;
  799. case 4:
  800. download(contract.value,contractName.value)
  801. break;
  802. case 5:
  803. download(applicant.value,applicantName.value)
  804. break;
  805. case 6:
  806. download(decidePay.value,decidePayName.value)
  807. break;
  808. case 7:
  809. download(dimission.value,dimissionName.value)
  810. break;
  811. }
  812. }
  813. // 图片删除
  814. const deleteImage = (type) => {
  815. switch (type) {
  816. case 1:
  817. IDCardFront.value = ''
  818. IDCardFrontName.value = ''
  819. break;
  820. case 2:
  821. IDCardBack.value = ''
  822. IDCardBackName.value = ''
  823. break;
  824. case 3:
  825. certification.value = ''
  826. certificationName.value = ''
  827. break;
  828. case 4:
  829. contract.value = ''
  830. contractName.value = ''
  831. break;
  832. case 5:
  833. applicant.value = ''
  834. applicantName.value = ''
  835. break;
  836. case 6:
  837. decidePay.value = ''
  838. decidePayName.value = ''
  839. break;
  840. case 7:
  841. dimission.value = ''
  842. dimissionName.value = ''
  843. break;
  844. }
  845. }
  846. // 管理人/推荐人
  847. let userList = ref([])
  848. const getUser = (id) => {
  849. api.operationApi.getUser(id).then(res => {
  850. if(res?.code == 200) {
  851. userList.value = res.data
  852. } else {
  853. ElMessage({
  854. message: res.msg,
  855. type: 'warning'
  856. })
  857. }
  858. })
  859. }
  860. // 确定
  861. const onSubmit = async (OperationFormRef: FormInstance, type: number) => {
  862. if(!OperationFormRef) {
  863. emits('closeDialog', '取消')
  864. recordShow.value = false
  865. OperationFormRef.resetFields()
  866. return
  867. }
  868. if(type) {
  869. await OperationFormRef.validate((valid, error) => {
  870. if(valid) {
  871. let formData = {...operationForm.value}
  872. // formData.organization = operationForm.value.organization[operationForm.value.organization.length - 1]
  873. formData.systemCode = localStorage.getItem('login_system')?localStorage.getItem('login_system'):''
  874. formData.province = operationForm.value.address?operationForm.value.address[0]:''
  875. formData.city = operationForm.value.address?operationForm.value.address[1]?operationForm.value.address[1]:'':''
  876. formData.district = operationForm.value.address?operationForm.value.address[2]?operationForm.value.address[2]:'':''
  877. if(editId.value) {
  878. api.operationApi.updateOperation(formData).then(res => {
  879. if(res.code == 200) {
  880. ElMessage({
  881. message: res.msg,
  882. type: 'success'
  883. })
  884. emits('closeDialog', '确定')
  885. } else {
  886. ElMessage({
  887. message: res.msg,
  888. type: 'error'
  889. })
  890. }
  891. IDCardFrontName.value = ''
  892. IDCardFront.value = ''
  893. IDCardBackName.value = ''
  894. IDCardBack.value = ''
  895. certificationName.value = ''
  896. certification.value = ''
  897. contractName.value = ''
  898. contract.value = ''
  899. applicantName.value = ''
  900. applicant.value = ''
  901. decidePayName.value = ''
  902. decidePay.value = ''
  903. dimissionName.value = ''
  904. dimission.value = ''
  905. recordShow.value = false
  906. OperationFormRef.resetFields()
  907. emits('closeDialog', '取消')
  908. })
  909. } else {
  910. api.operationApi.addOperation(formData).then(res => {
  911. if(res.code == 200) {
  912. ElMessage({
  913. message: res.msg,
  914. type: 'success'
  915. })
  916. emits('closeDialog', '确定')
  917. } else {
  918. ElMessage({
  919. message: res.msg,
  920. type: 'error'
  921. })
  922. }
  923. IDCardFrontName.value = ''
  924. IDCardFront.value = ''
  925. IDCardBackName.value = ''
  926. IDCardBack.value = ''
  927. certificationName.value = ''
  928. certification.value = ''
  929. contractName.value = ''
  930. contract.value = ''
  931. applicantName.value = ''
  932. applicant.value = ''
  933. decidePayName.value = ''
  934. decidePay.value = ''
  935. dimissionName.value = ''
  936. dimission.value = ''
  937. recordShow.value = false
  938. OperationFormRef.resetFields()
  939. emits('closeDialog', '取消')
  940. })
  941. }
  942. } else {
  943. Object.keys(error).forEach((key,i)=>{
  944. if(i==0){
  945. const firstFiled = error[key][0].field
  946. OperationFormRef.scrollToField(firstFiled)
  947. }
  948. })
  949. ElMessage({
  950. message: '请正确填写相关信息!',
  951. type: 'warning'
  952. })
  953. }
  954. })
  955. } else {
  956. IDCardFrontName.value = ''
  957. IDCardFront.value = ''
  958. IDCardBackName.value = ''
  959. IDCardBack.value = ''
  960. certificationName.value = ''
  961. certification.value = ''
  962. contractName.value = ''
  963. contract.value = ''
  964. applicantName.value = ''
  965. applicant.value = ''
  966. decidePayName.value = ''
  967. decidePay.value = ''
  968. dimissionName.value = ''
  969. dimission.value = ''
  970. recordShow.value = false
  971. emits('closeDialog', '取消')
  972. OperationFormRef.resetFields()
  973. }
  974. }
  975. // 初始化个人信息
  976. let options = ref([])
  977. const initInfo = () => {
  978. /*
  979. * 性别 gender
  980. 民族 nation
  981. 婚姻状况 marriage
  982. 政治面貌 political_status
  983. 健康状况 health_status
  984. 学历 educational
  985. * */
  986. let infoList = ['gender', 'nation', 'marriage', 'political_status', 'health_status', 'educational']
  987. infoList.forEach((item: string, index: number) => {
  988. api.commonApi.personInfo(item).then((res) => {
  989. if(res?.code == 200) {
  990. options.value[index] = [...res.data]
  991. } else {
  992. ElMessage({
  993. message: res.msg,
  994. type: 'warning'
  995. })
  996. }
  997. })
  998. })
  999. }
  1000. // 获取地区数据
  1001. const areaOptions = ref([]);
  1002. const areaProps = ref({
  1003. value: "areaCode",
  1004. label: "areaCname",
  1005. children: "child",
  1006. });
  1007. const getArea = () => {
  1008. api.areaApi.areaList({}).then((res) => {
  1009. areaOptions.value = res.data;
  1010. });
  1011. }
  1012. // 团队数据
  1013. let teamList = ref([])
  1014. const getTeamList = async () => {
  1015. const { code, data, msg } = await api.teamApi.teamList({})
  1016. if(code == 200) {
  1017. teamList.value = data
  1018. } else {
  1019. ElMessage({
  1020. message: msg,
  1021. type: 'warning'
  1022. })
  1023. }
  1024. }
  1025. const deptChange = (e) => {
  1026. const obj = teamList.value.find(item => item.id == e)
  1027. operationForm.value.organization = obj.deptName
  1028. operationForm.value.deptId = obj.deptId
  1029. getUser(obj.deptId)
  1030. }
  1031. // 初始化银行数据
  1032. let bankOption = ref([])
  1033. const initBankCard = () => {
  1034. api.commonApi.personInfo('bank_info').then(res => {
  1035. if(res.code == 200) {
  1036. bankOption.value = res.data
  1037. } else {
  1038. ElMessage({
  1039. message: res.msg,
  1040. type: 'warning'
  1041. })
  1042. }
  1043. })
  1044. }
  1045. onMounted(() => {
  1046. initInfo()
  1047. getArea()
  1048. getTeamList()
  1049. initBankCard()
  1050. })
  1051. defineExpose({
  1052. initEditData
  1053. })
  1054. </script>
  1055. <style scoped lang="scss">
  1056. .fileInfo{
  1057. display: flex;
  1058. align-items: center;
  1059. justify-content: flex-start;
  1060. padding: 2px 20px;
  1061. border-radius: 5px;
  1062. margin: 0 10px;
  1063. &:hover{
  1064. background: #ccc;
  1065. }
  1066. .fileName{
  1067. width: 200px;
  1068. overflow: hidden;
  1069. text-overflow: ellipsis;
  1070. white-space: nowrap;
  1071. }
  1072. .fileBtn{
  1073. display: flex;
  1074. align-items: center;
  1075. .btn-icon{
  1076. margin: 0 10px;
  1077. font-size: 16px;
  1078. cursor: pointer;
  1079. &:hover{
  1080. color: #00a0f4;
  1081. }
  1082. }
  1083. }
  1084. }
  1085. .image-view{
  1086. position: absolute;
  1087. top: 0;
  1088. left: 0;
  1089. width: 100%;
  1090. height: 100%;
  1091. background: rgba(0,0,0,.6);
  1092. display: flex;
  1093. align-items: center;
  1094. justify-content: center;
  1095. z-index: 9999;
  1096. img{
  1097. width: 800px;
  1098. height: 800px;
  1099. border-radius: 5px;
  1100. }
  1101. }
  1102. </style>