addPartner.vue 57 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643
  1. <template>
  2. <div>
  3. <el-form :model="operationForm" ref="OperationFormRef" :rules="operationRules" label-width="120">
  4. <el-descriptions title="基本信息">
  5. <el-descriptions-item>
  6. <template #default>
  7. <el-row :gutter="20">
  8. <el-col :span="10">
  9. <el-form-item prop="grade" label="合伙人等级">
  10. <el-select v-model="operationForm.gradeList" :disabled="editId" placeholder="请选择合伙人等级" multiple
  11. @change="handleGradeChange">
  12. <el-option v-for="item in userGradeList" :key="item.grade" :value="item.grade"
  13. :label="item.gradeName"></el-option>
  14. </el-select>
  15. </el-form-item>
  16. </el-col>
  17. <el-col :span="10">
  18. <el-form-item label="上级推荐人" :prop="mingrade == 1 ? '' : 'referrerId'">
  19. <el-select v-model="operationForm.referrerId" filterable
  20. :disabled="!operationForm.gradeList || operationForm.gradeList.includes('1') || editId" placeholder="请选择上级推荐人"
  21. @focus="searchRecommend" @change="handleReferrerChange">
  22. <el-option v-for="item in referrerList" :key="item.userId" :value="item.userId" :label="item.name">
  23. <span>{{ item.name }}-</span>
  24. <span> {{ item.mobile }}-</span>
  25. <span class="typeAttrMap mr-1" v-for="typeAttritem in typeAttrMap(item.typeAttr)"
  26. :key="typeAttritem">{{ typeAttritem }}</span>
  27. </el-option>
  28. </el-select>
  29. </el-form-item>
  30. </el-col>
  31. </el-row>
  32. <el-row :gutter="20">
  33. <el-col :span="10">
  34. <el-form-item prop="name" label="姓名">
  35. <el-input v-model="operationForm.name" placeholder="请填写姓名" maxlength="20"></el-input>
  36. </el-form-item>
  37. </el-col>
  38. <el-col :span="10">
  39. <el-form-item prop="mobile" label="手机号">
  40. <el-input type="text" :maxlength="11" :disabled="editId" show-word-limit v-model="operationForm.mobile"
  41. placeholder="请填写手机号" @input="mobileInput"></el-input>
  42. </el-form-item>
  43. </el-col>
  44. </el-row>
  45. <el-row :gutter="20">
  46. <el-col :span="10">
  47. <el-form-item prop="deptId" label="所属机构">
  48. <el-cascader style="width: 100%" v-model="operationForm.deptId" :disabled="editId || disabledProperty"
  49. placeholder="请选择所属机构" :options="deptOption" :props="optionProps"
  50. @change="deptIdChange"></el-cascader>
  51. </el-form-item>
  52. </el-col>
  53. <el-col :span="10">
  54. <el-form-item prop="identity" label="证件号">
  55. <el-input v-model="operationForm.identity" placeholder="请填写身份证号"></el-input>
  56. </el-form-item>
  57. </el-col>
  58. </el-row>
  59. <el-row :gutter="20">
  60. <el-col :span="10">
  61. <el-form-item prop="identityTimeStart" label="证件有效期始">
  62. <el-date-picker v-model="operationForm.identityTimeStart" type="date" placeholder="请选择"
  63. format="YYYY-MM-DD" value-format="YYYY-MM-DD" :disabled-date="disabledDateStart"
  64. style="width: 100%" />
  65. </el-form-item>
  66. </el-col>
  67. <el-col :span="10">
  68. <el-form-item prop="identityTimeEnd" label="证件有效期止">
  69. <el-date-picker v-model="operationForm.identityTimeEnd" type="date" placeholder="请选择"
  70. format="YYYY-MM-DD" value-format="YYYY-MM-DD" :disabled-date="disabledDateEnd"
  71. style="width: 100%" />
  72. </el-form-item>
  73. </el-col>
  74. </el-row>
  75. </template>
  76. </el-descriptions-item>
  77. </el-descriptions>
  78. <el-descriptions title="其他信息">
  79. <el-descriptions-item>
  80. <template #default>
  81. <el-row :gutter="20">
  82. <el-col :span="10">
  83. <el-form-item prop="leaderId" label="管理人">
  84. <el-select v-model="operationForm.leaderId" filterable placeholder="请选择管理人"
  85. @change="(e) => { operationForm.leaderNumber = e }">
  86. <el-option v-for="(item, index) in recommendList" :key="index" :value="item.id"
  87. :label="item.name"></el-option>
  88. </el-select>
  89. </el-form-item>
  90. </el-col>
  91. <el-col :span="10">
  92. <el-form-item prop="leaderId" label="管理人工号">
  93. <el-input disabled v-model="operationForm.leaderId" placeholder="请填写管理人工号"></el-input>
  94. </el-form-item>
  95. </el-col>
  96. </el-row>
  97. <!-- <el-row :gutter="20">
  98. <el-col :span="10">
  99. <el-form-item prop="referrerId" label="推荐人">
  100. <el-select v-model="operationForm.referrerId" filterable placeholder="请选择推荐人"
  101. @change="(e) => { operationForm.referrerNumber = e }">
  102. <el-option v-for="(item, index) in userList" :key="item.id" :value="item.id"
  103. :label="item.name"></el-option>
  104. </el-select>
  105. </el-form-item>
  106. </el-col>
  107. <el-col :span="10">
  108. <el-form-item prop="referrerNumber" label="推荐人工号">
  109. <el-input readonly v-model="operationForm.referrerNumber" placeholder="请填写推荐人工号"></el-input>
  110. </el-form-item>
  111. </el-col>
  112. </el-row> -->
  113. </template>
  114. </el-descriptions-item>
  115. </el-descriptions>
  116. <el-descriptions title="资料附件">
  117. <el-descriptions-item>
  118. <template #default>
  119. <el-form-item prop="IDCardFront" label-width="150">
  120. <template #label>
  121. <span style="color: #f56c6c">*</span>身份证(人像面)
  122. </template>
  123. <el-upload action="" v-if="!IDCardFront" :auto-upload="false" :show-file-list="false"
  124. accept=".png, .jpg, .jpeg" @change="uploadImage($event, 1)">
  125. <el-button link type="primary" icon="Upload">上传</el-button>
  126. </el-upload>
  127. <div class="fileInfo" v-else>
  128. <div class="file-box">
  129. <div class="btn-top">
  130. <img class="image-close" @click="deleteImage(1)" src="@/assets/images/close.png" />
  131. <!-- <el-icon class="btn-icon"><Delete /></el-icon>-->
  132. </div>
  133. <img class="file-img" :src="IDCardFront" />
  134. <div class="btn-bottom">
  135. <el-upload class="width-50" :show-file-list="false" :auto-upload="false" accept=".png, .jpg, .jpeg"
  136. @change="uploadImage($event, 1)"
  137. style="display: flex; align-items: center; justify-content: center; color: white">
  138. <el-icon>
  139. <Upload />
  140. </el-icon>重新上传
  141. </el-upload>
  142. <div class="width-50"
  143. style="display: flex; align-items: center; justify-content: center; color: white; cursor:pointer;"
  144. @click="downloadImage(1)">
  145. <el-icon>
  146. <Download />
  147. </el-icon>下载资料
  148. </div>
  149. </div>
  150. </div>
  151. <!-- <div class="fileName">{{ IDCardFrontName }}</div>
  152. <div class="fileBtn">
  153. <el-upload :show-file-list="false" :auto-upload="false" accept=".png, .jpg, .jpeg" @change="uploadImage($event, 1)" 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(1)"><View /></el-icon>
  157. <el-icon class="btn-icon" @click="downloadImage(1)"><Download /></el-icon>
  158. <el-icon class="btn-icon" @click="deleteImage(1)"><Delete /></el-icon>
  159. </div>-->
  160. </div>
  161. </el-form-item>
  162. <el-form-item prop="IDCardBack" label-width="150">
  163. <template #label>
  164. <span style="color: #f56c6c">*</span>身份证(国徽面)
  165. </template>
  166. <el-upload v-if="!IDCardBack" :auto-upload="false" :show-file-list="false" accept=".png, .jpg, .jpeg"
  167. @change="uploadImage($event, 2)">
  168. <el-button link type="primary" icon="Upload">上传</el-button>
  169. </el-upload>
  170. <div class="fileInfo" v-else>
  171. <div class="file-box">
  172. <div class="btn-top">
  173. <img class="image-close" @click="deleteImage(2)" src="@/assets/images/close.png" />
  174. <!-- <el-icon class="btn-icon"><Delete /></el-icon>-->
  175. </div>
  176. <img class="file-img" :src="IDCardBack" />
  177. <div class="btn-bottom">
  178. <el-upload class="width-50" :show-file-list="false" :auto-upload="false" accept=".png, .jpg, .jpeg"
  179. @change="uploadImage($event, 2)"
  180. style="display: flex; align-items: center; justify-content: center; color: white">
  181. <el-icon>
  182. <Upload />
  183. </el-icon>重新上传
  184. </el-upload>
  185. <div class="width-50"
  186. style="display: flex; align-items: center; justify-content: center; color: white; cursor:pointer;"
  187. @click="downloadImage(2)">
  188. <el-icon>
  189. <Download />
  190. </el-icon>下载资料
  191. </div>
  192. </div>
  193. </div>
  194. <!-- <div class="fileName">{{ IDCardBackName }}</div>
  195. <div class="fileBtn">
  196. <el-upload :auto-upload="false" :show-file-list="false" accept=".png, .jpg, .jpeg" @change="uploadImage($event, 2)" style="display: flex; align-items: center">
  197. <el-icon class="btn-icon"><Upload /></el-icon>
  198. </el-upload>
  199. <el-icon class="btn-icon" @click="imageView(2)"><View /></el-icon>
  200. <el-icon class="btn-icon" @click="downloadImage(2)"><Download /></el-icon>
  201. <el-icon class="btn-icon" @click="deleteImage(2)"><Delete /></el-icon>
  202. </div>-->
  203. </div>
  204. </el-form-item>
  205. <el-form-item prop="" label="展业资格证" label-width="150">
  206. <el-upload :auto-upload="false" v-if="!certification" :show-file-list="false" accept=".png, .jpg, .jpeg"
  207. @change="uploadImage($event, 3)">
  208. <el-button link type="primary" icon="Upload">上传</el-button>
  209. </el-upload>
  210. <div class="fileInfo" v-else>
  211. <div class="file-box">
  212. <div class="btn-top">
  213. <img class="image-close" @click="deleteImage(3)" src="@/assets/images/close.png" />
  214. <!-- <el-icon class="btn-icon"><Delete /></el-icon>-->
  215. </div>
  216. <img class="file-img" :src="certification" />
  217. <div class="btn-bottom">
  218. <el-upload class="width-50" :show-file-list="false" :auto-upload="false" accept=".png, .jpg, .jpeg"
  219. @change="uploadImage($event, 3)"
  220. style="display: flex; align-items: center; justify-content: center; color: white">
  221. <el-icon>
  222. <Upload />
  223. </el-icon>重新上传
  224. </el-upload>
  225. <div class="width-50"
  226. style="display: flex; align-items: center; justify-content: center; color: white; cursor:pointer;"
  227. @click="downloadImage(3)">
  228. <el-icon>
  229. <Download />
  230. </el-icon>下载资料
  231. </div>
  232. </div>
  233. </div>
  234. <!-- <div class="fileName">{{ certificationName }}</div>
  235. <div class="fileBtn">
  236. <el-upload :auto-upload="false" :show-file-list="false" accept=".png, .jpg, .jpeg" @change="uploadImage($event, 3)" style="display: flex; align-items: center">
  237. <el-icon class="btn-icon"><Upload /></el-icon>
  238. </el-upload>
  239. <el-icon class="btn-icon" @click="imageView(3)"><View /></el-icon>
  240. <el-icon class="btn-icon" @click="downloadImage(3)"><Download /></el-icon>
  241. <el-icon class="btn-icon" @click="deleteImage(3)"><Delete /></el-icon>
  242. </div>-->
  243. </div>
  244. </el-form-item>
  245. </template>
  246. </el-descriptions-item>
  247. </el-descriptions>
  248. <el-divider />
  249. <el-button v-if="!recordShow" link type="primary" icon="plus"
  250. @click="recordShow = !recordShow">填写人事档案(选填)</el-button>
  251. <el-button v-else link type="primary" icon="ArrowUp" @click="recordShow = !recordShow">收起人事档案(选填)</el-button>
  252. <br /><br />
  253. <el-descriptions title="个人信息" v-show="recordShow">
  254. <el-descriptions-item>
  255. <template #default>
  256. <el-row :gutter="20">
  257. <el-col :span="10">
  258. <el-form-item prop="sex" label="性别">
  259. <el-select v-model="operationForm.sex" placeholder="请选择性别">
  260. <el-option v-for="item in options[0]" :key="item.value" :value="item.value"
  261. :label="item.label"></el-option>
  262. </el-select>
  263. </el-form-item>
  264. </el-col>
  265. <el-col :span="10">
  266. <el-form-item prop="birthday" label="出生日期">
  267. <el-date-picker v-model="operationForm.birthday" type="date" placeholder="请选择" format="YYYY-MM-DD"
  268. value-format="YYYY-MM-DD" style="width: 100%" />
  269. </el-form-item>
  270. </el-col>
  271. </el-row>
  272. <el-row :gutter="20">
  273. <el-col :span="10">
  274. <el-form-item prop="nations" label="民族">
  275. <el-select v-model="operationForm.nations" placeholder="请选择业务员类型">
  276. <el-option v-for="item in options[1]" :key="item.value" :value="item.value"
  277. :label="item.label"></el-option>
  278. </el-select>
  279. </el-form-item>
  280. </el-col>
  281. <el-col :span="10">
  282. <el-form-item prop="koseki" label="户籍">
  283. <el-input v-model="operationForm.koseki" placeholder="请填写户籍"></el-input>
  284. </el-form-item>
  285. </el-col>
  286. </el-row>
  287. <el-row :gutter="20">
  288. <el-col :span="10">
  289. <el-form-item prop="maritalStatus" label="婚姻状况">
  290. <el-select v-model="operationForm.maritalStatus" placeholder="请选择婚姻状况">
  291. <el-option v-for="item in options[2]" :key="item.value" :value="item.value"
  292. :label="item.label"></el-option>
  293. </el-select>
  294. </el-form-item>
  295. </el-col>
  296. <el-col :span="10">
  297. <el-form-item prop="politicsStatus" label="政治面貌">
  298. <el-select v-model="operationForm.politicsStatus" placeholder="请选择政治面貌">
  299. <el-option v-for="item in options[3]" :key="item.value" :value="item.value"
  300. :label="item.label"></el-option>
  301. </el-select>
  302. </el-form-item>
  303. </el-col>
  304. </el-row>
  305. <el-row :gutter="20">
  306. <el-col :span="10">
  307. <el-form-item prop="health" label="健康状况">
  308. <el-select v-model="operationForm.health" placeholder="请选择健康状况">
  309. <el-option v-for="item in options[4]" :key="item.value" :value="item.value"
  310. :label="item.label"></el-option>
  311. </el-select>
  312. </el-form-item>
  313. </el-col>
  314. <el-col :span="10">
  315. <el-form-item prop="address" label="居住地区">
  316. <el-cascader clearable style="width: 100%" v-model="operationForm.address" :options="areaOptions"
  317. :props="areaProps" />
  318. </el-form-item>
  319. </el-col>
  320. </el-row>
  321. <el-row :gutter="20">
  322. <el-col :span="10">
  323. <el-form-item prop="liveAddress" label="详细地址">
  324. <el-input v-model="operationForm.liveAddress" placeholder="请填写详细地址"></el-input>
  325. </el-form-item>
  326. </el-col>
  327. <el-col :span="10">
  328. <el-form-item prop="postalCode" label="邮政编码">
  329. <el-input v-model="operationForm.postalCode" placeholder="请填写邮政编码"></el-input>
  330. </el-form-item>
  331. </el-col>
  332. </el-row>
  333. </template>
  334. </el-descriptions-item>
  335. </el-descriptions>
  336. <el-descriptions title="学历信息" v-show="recordShow">
  337. <el-descriptions-item>
  338. <template #default>
  339. <el-row :gutter="20">
  340. <el-col :span="10">
  341. <el-form-item prop="education" label="学历">
  342. <el-select v-model="operationForm.education" placeholder="请选择学历">
  343. <el-option v-for="item in options[5]" :key="item.value" :value="item.value"
  344. :label="item.label"></el-option>
  345. </el-select>
  346. </el-form-item>
  347. </el-col>
  348. <el-col :span="10">
  349. <el-form-item prop="graduationTime" label="毕业时间">
  350. <el-date-picker v-model="operationForm.graduationTime" type="date" placeholder="请选择"
  351. format="YYYY-MM-DD" value-format="YYYY-MM-DD" style="width: 100%" />
  352. </el-form-item>
  353. </el-col>
  354. </el-row>
  355. <el-row :gutter="20">
  356. <el-col :span="10">
  357. <el-form-item prop="school" label="毕业院校">
  358. <el-input v-model="operationForm.school" placeholder="请填写毕业院校"></el-input>
  359. </el-form-item>
  360. </el-col>
  361. <el-col :span="10">
  362. <el-form-item prop="isComputer" label="是否计算机专业">
  363. <el-select v-model="operationForm.isComputer" placeholder="请选择是否计算机专业">
  364. <el-option key="1" value="1" label="是"></el-option>
  365. <el-option key="0" value="0" label="否"></el-option>
  366. </el-select>
  367. </el-form-item>
  368. </el-col>
  369. </el-row>
  370. </template>
  371. </el-descriptions-item>
  372. </el-descriptions>
  373. <el-descriptions title="紧急联系人信息" v-show="recordShow">
  374. <el-descriptions-item>
  375. <template #default>
  376. <el-row :gutter="20">
  377. <el-col :span="10">
  378. <el-form-item prop="emergencyContactName" label="姓名">
  379. <el-input v-model="operationForm.emergencyContactName" placeholder="请填写姓名"></el-input>
  380. </el-form-item>
  381. </el-col>
  382. <el-col :span="10">
  383. <el-form-item prop="emergencyContactTel" label="手机号">
  384. <el-input v-model="operationForm.emergencyContactTel" placeholder="请填写手机号"></el-input>
  385. </el-form-item>
  386. </el-col>
  387. </el-row>
  388. </template>
  389. </el-descriptions-item>
  390. </el-descriptions>
  391. <el-descriptions title="工资信息" v-show="recordShow">
  392. <el-descriptions-item>
  393. <template #default>
  394. <el-row :gutter="20">
  395. <el-col :span="10">
  396. <el-form-item prop="salary" label="工资">
  397. <el-input v-model="operationForm.salary" placeholder="请填写工资"></el-input>
  398. </el-form-item>
  399. </el-col>
  400. <el-col :span="10">
  401. <el-form-item prop="salaryLevel" label="工资等级">
  402. <el-input v-model="operationForm.salaryLevel" placeholder="请填写工资等级"></el-input>
  403. </el-form-item>
  404. </el-col>
  405. </el-row>
  406. <el-row :gutter="20">
  407. <el-col :span="10">
  408. <el-form-item prop="bankCardId" label="银行卡号">
  409. <el-input v-model="operationForm.bankCardId" placeholder="请填写银行卡号"></el-input>
  410. </el-form-item>
  411. </el-col>
  412. <el-col :span="10">
  413. <el-form-item prop="bankName" label="开户行">
  414. <el-select v-model="operationForm.bankName" placeholder="请选择开户行">
  415. <el-option v-for="item in bankOption" :key="item.id" :value="item.id"
  416. :label="item.label"></el-option>
  417. </el-select>
  418. </el-form-item>
  419. </el-col>
  420. </el-row>
  421. </template>
  422. </el-descriptions-item>
  423. </el-descriptions>
  424. <el-divider v-show="recordShow" />
  425. <el-descriptions v-show="recordShow" title="其它附件">
  426. <el-descriptions-item>
  427. <template #default>
  428. <el-form-item prop="" label="劳动合同" label-width="150">
  429. <el-upload v-if="!contract" :auto-upload="false" :show-file-list="false"
  430. accept=".png, .jpg, .jpeg, .pdf, .doc, .docx" @change="uploadImage($event, 4)">
  431. <el-button link type="primary" icon="Upload">上传</el-button>
  432. </el-upload>
  433. <div class="fileInfo" v-else>
  434. <img style="width: 40px; height: 40px"
  435. :src="contractName.includes('.png') || contractName.includes('.jpg') || contractName.includes('.jpeg') ? image : contractName.includes('.pdf') ? pdf : contractName.includes('.doc') || contractName.includes('.docx') ? word : ''" />
  436. <div class="fileName">{{ contractName }}</div>
  437. <div class="fileBtn">
  438. <el-upload :auto-upload="false" :show-file-list="false" accept=".png, .jpg, .jpeg, .pdf, .doc, .docx"
  439. @change="uploadImage($event, 4)" style="display: flex; align-items: center">
  440. <el-icon class="btn-icon">
  441. <Upload />
  442. </el-icon>
  443. </el-upload>
  444. <el-icon class="btn-icon" @click="imageView(4)">
  445. <View />
  446. </el-icon>
  447. <el-icon class="btn-icon" @click="downloadImage(4)">
  448. <Download />
  449. </el-icon>
  450. <el-icon class="btn-icon" @click="deleteImage(4)">
  451. <Delete />
  452. </el-icon>
  453. </div>
  454. </div>
  455. </el-form-item>
  456. <el-form-item prop="" label="应聘表" label-width="150">
  457. <el-upload v-if="!applicant" :auto-upload="false" :show-file-list="false"
  458. accept=".png, .jpg, .jpeg, .pdf, .doc, .docx" @change="uploadImage($event, 5)">
  459. <el-button link type="primary" icon="Upload">上传</el-button>
  460. </el-upload>
  461. <div class="fileInfo" v-else>
  462. <img style="width: 40px; height: 40px"
  463. :src="applicantName.includes('.png') || applicantName.includes('.jpg') || applicantName.includes('.jpeg') ? image : applicantName.includes('.pdf') ? pdf : applicantName.includes('.doc') || applicantName.includes('.docx') ? word : ''" />
  464. <div class="fileName">{{ applicantName }}</div>
  465. <div class="fileBtn">
  466. <el-upload :auto-upload="false" :show-file-list="false" accept=".png, .jpg, .jpeg, .pdf, .doc, .docx"
  467. @change="uploadImage($event, 5)" style="display: flex; align-items: center">
  468. <el-icon class="btn-icon">
  469. <Upload />
  470. </el-icon>
  471. </el-upload>
  472. <el-icon class="btn-icon" @click="imageView(5)">
  473. <View />
  474. </el-icon>
  475. <el-icon class="btn-icon" @click="downloadImage(5)">
  476. <Download />
  477. </el-icon>
  478. <el-icon class="btn-icon" @click="deleteImage(5)">
  479. <Delete />
  480. </el-icon>
  481. </div>
  482. </div>
  483. </el-form-item>
  484. <el-form-item prop="" label="定薪表" label-width="150">
  485. <el-upload :auto-upload="false" v-if="!decidePay" :show-file-list="false"
  486. accept=".png, .jpg, .jpeg, .pdf, .doc, .docx" @change="uploadImage($event, 6)">
  487. <el-button link type="primary" icon="Upload">上传</el-button>
  488. </el-upload>
  489. <div class="fileInfo" v-else>
  490. <img style="width: 40px; height: 40px"
  491. :src="decidePayName.includes('.png') || decidePayName.includes('.jpg') || decidePayName.includes('.jpeg') ? image : decidePayName.includes('.pdf') ? pdf : decidePayName.includes('.doc') || decidePayName.includes('.docx') ? word : ''" />
  492. <div class="fileName">{{ decidePayName }}</div>
  493. <div class="fileBtn">
  494. <el-upload :auto-upload="false" :show-file-list="false" accept=".png, .jpg, .jpeg, .pdf, .doc, .docx"
  495. @change="uploadImage($event, 6)" style="display: flex; align-items: center">
  496. <el-icon class="btn-icon">
  497. <Upload />
  498. </el-icon>
  499. </el-upload>
  500. <el-icon class="btn-icon" @click="imageView(6)">
  501. <View />
  502. </el-icon>
  503. <el-icon class="btn-icon" @click="downloadImage(6)">
  504. <Download />
  505. </el-icon>
  506. <el-icon class="btn-icon" @click="deleteImage(6)">
  507. <Delete />
  508. </el-icon>
  509. </div>
  510. </div>
  511. </el-form-item>
  512. <el-form-item prop="" label="离职表" label-width="150">
  513. <el-upload :auto-upload="false" v-if="!dimission" :show-file-list="false"
  514. accept=".png, .jpg, .jpeg, .pdf, .doc, .docx" @change="uploadImage($event, 7)">
  515. <el-button link type="primary" icon="Upload">上传</el-button>
  516. </el-upload>
  517. <div class="fileInfo" v-else>
  518. <img style="width: 40px; height: 40px"
  519. :src="dimissionName.includes('.png') || dimissionName.includes('.jpg') || dimissionName.includes('.jpeg') ? image : dimissionName.includes('.pdf') ? pdf : dimissionName.includes('.doc') || dimissionName.includes('.docx') ? word : ''" />
  520. <div class="fileName">{{ dimissionName }}</div>
  521. <div class="fileBtn">
  522. <el-upload :auto-upload="false" :show-file-list="false" accept=".png, .jpg, .jpeg, .pdf, .doc, .docx"
  523. @change="uploadImage($event, 7)" style="display: flex; align-items: center">
  524. <el-icon class="btn-icon">
  525. <Upload />
  526. </el-icon>
  527. </el-upload>
  528. <el-icon class="btn-icon" @click="imageView(7)">
  529. <View />
  530. </el-icon>
  531. <el-icon class="btn-icon" @click="downloadImage(7)">
  532. <Download />
  533. </el-icon>
  534. <el-icon class="btn-icon" @click="deleteImage(7)">
  535. <Delete />
  536. </el-icon>
  537. </div>
  538. </div>
  539. </el-form-item>
  540. </template>
  541. </el-descriptions-item>
  542. </el-descriptions>
  543. <div style="display: flex; justify-content: flex-end">
  544. <el-button @click="onSubmit(OperationFormRef, 0)">取消</el-button>
  545. <el-button type="primary" @click="onSubmit(OperationFormRef, 1)">确定</el-button>
  546. </div>
  547. </el-form>
  548. <!-- <div class="image-view" v-if="imageShow" @click="imageShow = false">
  549. <img :src="imageUrl" />
  550. </div>-->
  551. <el-dialog title="图片预览" v-model="imageShow">
  552. <img class="image-view" :src="imageUrl" />
  553. </el-dialog>
  554. <el-dialog title="文件预览" v-model="fileShow">
  555. <vue-office-docx :src="fileUrl" style="height: 600px; margin: 0; padding: 0"></vue-office-docx>
  556. </el-dialog>
  557. </div>
  558. </template>
  559. <script setup lang="ts">
  560. import { ref, onMounted, } from 'vue'
  561. import type { FormRules, FormInstance } from "element-plus";
  562. import VueOfficeDocx from "@vue-office/docx";
  563. import api from "@/api";
  564. import { ElMessage } from "element-plus";
  565. import image from '@/assets/images/image.png'
  566. import word from '@/assets/images/word.png'
  567. import pdf from '@/assets/images/pdf.png'
  568. // 计算属性:根据等级列表获取等级名称
  569. // 获取人员等级列表
  570. // 机构是否可选
  571. const disabledProperty = ref(false);//机构是否可选
  572. const mingrade = ref();//最小等级
  573. const userGradeList = ref<any[]>([]);//用户等级列表
  574. const referrerList = ref<any[]>([]);//上级推荐人列表
  575. const getGradeOptions = () => {
  576. api.partnerApi.queryGradeName().then((res: any) => {
  577. if (res.code === 200) {
  578. userGradeList.value = res.data;
  579. }
  580. })
  581. }
  582. // 手机号查询上级推荐人
  583. const searchRecommend = () => {
  584. api.partnerApi.selectByUserNameAndMobile(Number(mingrade.value - 1)).then((res: any) => {
  585. if (res.code === 200) {
  586. referrerList.value = res.data;
  587. } else {
  588. ElMessage.error(res.msg);
  589. }
  590. })
  591. }
  592. // 处理等级变化
  593. const handleGradeChange = (val: any) => {
  594. mingrade.value = getMinValueFromStrArray(val)
  595. console.log(mingrade.value)
  596. }
  597. const typeAttrMap = (val: string): string => {
  598. // 定义类型映射表
  599. const map: any = {
  600. '6': '个代',
  601. '7': '渠道',
  602. '5': '团队',
  603. '8': '电销组',
  604. '3': '合伙人',
  605. };
  606. if (!val) return '';
  607. const typeCodes = val.split(',');
  608. const result = typeCodes.map((code: any) => {
  609. return map[code] || code;
  610. });
  611. return result as any;
  612. };
  613. // 处理上级推荐人变化
  614. const handleReferrerChange = (val: any) => {
  615. let info = referrerList.value.find((item: any) => item.userId == val)
  616. operationForm.referrerName = info.name;
  617. operationForm.deptId = info.deptId;
  618. if (info.deptId) {
  619. disabledProperty.value = true;
  620. }
  621. getRecommend(info.deptId)//获取机构下管理人列表
  622. }
  623. const mobileInput = (val: any) => {
  624. if (val.length >= 11) {
  625. api.partnerApi.selectByMobile(val).then((res: any) => {
  626. if (res.code === 200) {
  627. console.log(operationForm)
  628. // 只合并res.data中存在且不为空的值
  629. if (res.data) {
  630. Object.keys(res.data).forEach(key => {
  631. const value = res.data[key];
  632. // 只合并非null、非undefined的值
  633. if (value !== null && value !== undefined) {
  634. operationForm[key] = value;
  635. }
  636. });
  637. operationForm.deptId = res.data.deptId;
  638. if (res.data.deptId) {
  639. disabledProperty.value = true;
  640. }
  641. getRecommend(res.data.deptId)
  642. }
  643. } else {
  644. ElMessage.error('未查询到该业务员信息');
  645. }
  646. })
  647. }
  648. }
  649. let emits = defineEmits(['closeDialog'])
  650. const OperationFormRef = ref<FormInstance>()
  651. // 添加/编辑业务员表单
  652. let operationForm = reactive({
  653. gradeList: '',//合伙人等级列表
  654. typeAttr: '',
  655. deptId: '',
  656. name: '',
  657. mobile: '',
  658. identity: '',
  659. identityTimeStart: '',
  660. identityTimeEnd: '',
  661. leaderId: '',
  662. referrerId: '',
  663. referrerName: '',//上级推荐人姓名
  664. sex: '',
  665. birthday: '',
  666. nations: '',
  667. koseki: '',
  668. maritalStatus: '',
  669. politicsStatus: '',
  670. health: '',
  671. province: '',
  672. city: '',
  673. district: '',
  674. liveAddress: '',
  675. postalCode: '',
  676. education: '',
  677. graduationTime: '',
  678. school: '',
  679. isComputer: '',
  680. emergencyContactName: '',
  681. emergencyContactTel: '',
  682. salary: '',
  683. salaryLevel: '',
  684. bankCardId: '',
  685. bankName: '',
  686. sfz1: '',
  687. sfz2: '',
  688. qualification: '',
  689. contract: '',
  690. applicant: '',
  691. salaryTable: '',
  692. leaveTable: '',
  693. organizationId: '',
  694. organization: '',
  695. leaderNumber: '',
  696. referrerNumber: '',
  697. address: [],
  698. })
  699. // 机构数据渲染格式
  700. const cascaderProps = {
  701. value: 'id',
  702. label: 'name',
  703. children: 'children'
  704. }
  705. // 添加/编辑业务员表单校验
  706. const operationRules = ref<FormRules>({
  707. typeAttr: [
  708. { required: true, trigger: "change", message: "请选择业务员类型" }
  709. ],
  710. name: [
  711. { required: true, trigger: "blur", message: "请填写姓名" }
  712. ],
  713. mobile: [
  714. { required: true, trigger: "blur", message: "请填写手机号" },
  715. {
  716. pattern: /^1[0-9]{10}$/,
  717. message: '请填写正确的手机号',
  718. trigger: 'blur'
  719. }
  720. ],
  721. deptId: [
  722. { required: true, trigger: "change", message: "请选择所属机构" }
  723. ],
  724. identity: [
  725. { required: true, trigger: "blur", message: "请填写证件号" },
  726. {
  727. 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]$/,
  728. message: '请填写正确的身份证号',
  729. trigger: 'blur'
  730. }
  731. ],
  732. identityTimeStart: [
  733. { required: true, trigger: "change", message: "请选择证件有效期始" }
  734. ],
  735. identityTimeEnd: [
  736. { required: true, trigger: "change", message: "请选择证件有效期止" }
  737. ],
  738. leaderId: [
  739. { required: true, trigger: "blur", message: "请选择管理人" }
  740. ],
  741. referrerId: [
  742. { required: true, trigger: "blur", message: "请选择推荐人" }
  743. ],
  744. referrerNumber: [
  745. { required: true, trigger: "blur", message: "请填写推荐人工号" }
  746. ],
  747. // IDCardFront: [
  748. // { required: true, trigger: "change", message: "请上传身份(人像面)" }
  749. // ],
  750. // IDCardBack: [
  751. // { required: true, trigger: "change", message: "请上传身份(国徽面)" }
  752. // ],
  753. bankCardId: [
  754. {
  755. pattern: /^([1-9]{1})(\d{15}|\d{16}|\d{18})$/,
  756. message: '请填写正确的银行卡号',
  757. trigger: 'blur'
  758. }
  759. ],
  760. emergencyContactTel: [
  761. {
  762. pattern: /^1[34578][0-9]{9}$/,
  763. message: '请填写正确的手机号',
  764. trigger: 'blur'
  765. }
  766. ],
  767. postalCode: [
  768. {
  769. pattern: /^\d{6}$/,
  770. message: '请填写正确的邮政编码',
  771. trigger: 'blur'
  772. }
  773. ]
  774. })
  775. // 身份证人像面
  776. let IDCardFrontName = ref('')
  777. let IDCardFront = ref('')
  778. // 身份证国徽面
  779. let IDCardBackName = ref('')
  780. let IDCardBack = ref('')
  781. // 展业资格证
  782. let certificationName = ref('')
  783. let certification = ref('')
  784. // 劳务合同
  785. let contractName = ref('')
  786. let contract = ref('')
  787. // 应聘表
  788. let applicantName = ref('')
  789. let applicant = ref('')
  790. // 定薪表
  791. let decidePayName = ref('')
  792. let decidePay = ref('')
  793. // 离职表
  794. let dimissionName = ref('')
  795. let dimission = ref('')
  796. // 图片预览地址
  797. let imageShow = ref(false)
  798. let imageUrl = ref('')
  799. // word
  800. let fileShow = ref(false)
  801. // 限制证件日期
  802. const disabledDateStart = (time: Date) => {
  803. return time.getTime() > new Date()
  804. }
  805. const disabledDateEnd = (time: Date) => {
  806. return time.getTime() < new Date(operationForm.identityTimeStart)
  807. }
  808. // 编辑时初始化数据
  809. // 编辑的id
  810. let editId = ref()
  811. const initEditData = (id: any) => {
  812. editId.value = id
  813. api.operationApi.operationDetail(id).then((res: any) => {
  814. if (res?.code == 200) {
  815. let formData = res.data
  816. Object.assign(operationForm, formData)
  817. console.log(operationForm)
  818. mingrade.value = getMinValueFromStrArray(formData.gradeList)
  819. searchRecommend();//编辑回显查询上级推荐人列表
  820. operationForm.deptId = formData.deptId
  821. let address = [] as any
  822. if (formData.province && formData.city && formData.district) {
  823. address = [formData.province, formData.city, formData.district]
  824. }
  825. if (formData.province && !formData.city && !formData.district) {
  826. address = [formData.province]
  827. }
  828. if (formData.fileList) {
  829. let sfz1 = formData.fileList.find((item: any) => item.fileType == 'sfz1')
  830. let sfz2 = formData.fileList.find((item: any) => item.fileType == 'sfz2')
  831. let qualification = formData.fileList.find((item: any) => item.fileType == 'qualification')
  832. let contractImg = formData.fileList.find((item: any) => item.fileType == 'contract')
  833. let applicantImg = formData.fileList.find((item: any) => item.fileType == 'applicant')
  834. let salaryTable = formData.fileList.find((item: any) => item.fileType == 'salary')
  835. let leaveTable = formData.fileList.find((item: any) => item.fileType == 'leave')
  836. if (sfz1) {
  837. operationForm.sfz1 = sfz1.id
  838. IDCardFrontName.value = sfz1.fileName
  839. IDCardFront.value = sfz1.fileUrl
  840. }
  841. if (sfz2) {
  842. operationForm.sfz2 = sfz2.id
  843. IDCardBackName.value = sfz2.fileName
  844. IDCardBack.value = sfz2.fileUrl
  845. }
  846. if (qualification) {
  847. operationForm.qualification = qualification.id
  848. certificationName.value = qualification.fileName
  849. certification.value = qualification.fileUrl
  850. }
  851. if (contractImg) {
  852. operationForm.contract = contractImg.id
  853. contractName.value = contractImg.fileName
  854. contract.value = contractImg.fileUrl
  855. }
  856. if (applicantImg) {
  857. operationForm.applicant = applicantImg.id
  858. applicantName.value = applicantImg.fileName
  859. applicant.value = applicantImg.fileUrl
  860. }
  861. if (salaryTable) {
  862. operationForm.salaryTable = salaryTable.id
  863. decidePayName.value = salaryTable.fileName
  864. decidePay.value = salaryTable.fileUrl
  865. }
  866. if (leaveTable) {
  867. operationForm.leaveTable = leaveTable.id
  868. dimissionName.value = leaveTable.fileName
  869. dimission.value = leaveTable.fileUrl
  870. }
  871. }
  872. operationForm.address = address
  873. getUser(operationForm.deptId)
  874. getRecommend(operationForm.deptId)
  875. } else {
  876. ElMessage({
  877. message: res.msg,
  878. type: 'warning'
  879. })
  880. }
  881. })
  882. }
  883. // 新增数据初始化
  884. const initAddData = () => {
  885. Object.assign(operationForm, {
  886. typeAttr: '',
  887. deptId: '',
  888. name: '',
  889. mobile: '',
  890. identity: '',
  891. identityTimeStart: '',
  892. identityTimeEnd: '',
  893. leaderId: '',
  894. referrerId: '',
  895. sex: '',
  896. birthday: '',
  897. nations: '',
  898. koseki: '',
  899. maritalStatus: '',
  900. politicsStatus: '',
  901. health: '',
  902. province: '',
  903. city: '',
  904. district: '',
  905. liveAddress: '',
  906. postalCode: '',
  907. education: '',
  908. graduationTime: '',
  909. school: '',
  910. isComputer: '',
  911. emergencyContactName: '',
  912. emergencyContactTel: '',
  913. salary: '',
  914. salaryLevel: '',
  915. bankCardId: '',
  916. bankName: '',
  917. sfz1: '',
  918. sfz2: '',
  919. qualification: '',
  920. contract: '',
  921. applicant: '',
  922. salaryTable: '',
  923. leaveTable: '',
  924. organizationId: '',
  925. organization: '',
  926. leaderNumber: '',
  927. referrerNumber: '',
  928. address: [],
  929. })
  930. IDCardFrontName.value = ''
  931. IDCardFront.value = ''
  932. IDCardBackName.value = ''
  933. IDCardBack.value = ''
  934. certificationName.value = ''
  935. certification.value = ''
  936. contractName.value = ''
  937. contract.value = ''
  938. applicantName.value = ''
  939. applicant.value = ''
  940. decidePayName.value = ''
  941. decidePay.value = ''
  942. }
  943. // 上传接口
  944. let postUrl = ref(`${import.meta.env.VITE_APP_API_BASEURL}/file/upload`)
  945. // 上传图片
  946. const uploadImage = async (file: any, type: any) => {
  947. // const img = new Image();
  948. // img.onload = () => {
  949. // console.log('图片尺寸:', img.width, 'x', img.height);
  950. // // 可以在这里处理尺寸信息
  951. // };
  952. // img.src = URL.createObjectURL(file.raw)
  953. let files = file.raw
  954. const params = new FormData(); // 声明formData数据类型
  955. params.append("file", files);
  956. params.append("type", "image");
  957. const { code, data, msg }: any = await api.commonApi.fileUpload(params)
  958. if (code == 200) {
  959. let result = { ...data }
  960. switch (type) {
  961. case 1:
  962. IDCardFrontName.value = result.fileName
  963. IDCardFront.value = result.downloadUrl
  964. operationForm.sfz1 = result.id
  965. break;
  966. case 2:
  967. IDCardBackName.value = result.fileName
  968. IDCardBack.value = result.downloadUrl
  969. operationForm.sfz2 = result.id
  970. break;
  971. case 3:
  972. certificationName.value = result.fileName
  973. certification.value = result.downloadUrl
  974. operationForm.qualification = result.id
  975. break;
  976. case 4:
  977. contractName.value = result.fileName
  978. contract.value = result.downloadUrl
  979. operationForm.contract = result.id
  980. break;
  981. case 5:
  982. applicantName.value = result.fileName
  983. applicant.value = result.downloadUrl
  984. operationForm.applicant = result.id
  985. break;
  986. case 6:
  987. decidePayName.value = result.fileName
  988. decidePay.value = result.downloadUrl
  989. operationForm.salaryTable = result.id
  990. break;
  991. case 7:
  992. dimissionName.value = result.fileName
  993. dimission.value = result.downloadUrl
  994. operationForm.leaveTable = result.id
  995. break;
  996. }
  997. } else {
  998. ElMessage({
  999. message: msg,
  1000. type: 'error'
  1001. })
  1002. }
  1003. }
  1004. // 人事档案
  1005. let recordShow = ref(false)
  1006. let fileUrl = ref('')
  1007. // word预览
  1008. const filePreview = (file: any) => {
  1009. nextTick(() => {
  1010. fileUrl.value = file
  1011. })
  1012. }
  1013. // 图片预览
  1014. const imageView = (type: any) => {
  1015. switch (type) {
  1016. case 1:
  1017. imageShow.value = true
  1018. imageUrl.value = IDCardFront.value
  1019. break;
  1020. case 2:
  1021. imageShow.value = true
  1022. imageUrl.value = IDCardBack.value
  1023. break;
  1024. case 3:
  1025. imageShow.value = true
  1026. imageUrl.value = certification.value
  1027. break;
  1028. case 4:
  1029. imageUrl.value = contract.value
  1030. nextTick(() => {
  1031. // loadPdf(contract.value)
  1032. if (contract.value.includes('.pdf')) {
  1033. window.open(contract.value, '_blank')
  1034. } else if (contract.value.includes('.doc') || contract.value.includes('.docx')) {
  1035. fileShow.value = true
  1036. nextTick(() => {
  1037. filePreview(contract.value)
  1038. })
  1039. } else if (contract.value.includes('.jpg') || contract.value.includes('.jpeg') || contract.value.includes('.png')) {
  1040. imageShow.value = true
  1041. }
  1042. })
  1043. break;
  1044. case 5:
  1045. imageUrl.value = applicant.value
  1046. nextTick(() => {
  1047. // loadPdf(applicant.value)
  1048. if (applicant.value.includes('.pdf')) {
  1049. window.open(applicant.value, '_blank')
  1050. } else if (applicant.value.includes('.doc') || applicant.value.includes('.docx')) {
  1051. fileShow.value = true
  1052. filePreview(applicant.value)
  1053. } else if (applicant.value.includes('.jpg') || applicant.value.includes('.jpeg') || applicant.value.includes('.png')) {
  1054. imageShow.value = true
  1055. }
  1056. })
  1057. break;
  1058. case 6:
  1059. imageUrl.value = decidePay.value
  1060. nextTick(() => {
  1061. // loadPdf(decidePay.value)
  1062. if (decidePay.value.includes('.pdf')) {
  1063. window.open(decidePay.value, '_blank')
  1064. } else if (decidePay.value.includes('.doc') || decidePay.value.includes('.docx')) {
  1065. fileShow.value = true
  1066. filePreview(decidePay.value)
  1067. } else if (decidePay.value.includes('.jpg') || decidePay.value.includes('.jpeg') || decidePay.value.includes('.png')) {
  1068. imageShow.value = true
  1069. }
  1070. })
  1071. break;
  1072. case 7:
  1073. imageUrl.value = dimission.value
  1074. nextTick(() => {
  1075. // loadPdf(dimission.value)
  1076. if (dimission.value.includes('.pdf')) {
  1077. window.open(dimission.value, '_blank')
  1078. } else if (dimission.value.includes('.doc') || dimission.value.includes('.docx')) {
  1079. fileShow.value = true
  1080. filePreview(dimission.value)
  1081. } else if (dimission.value.includes('.jpg') || dimission.value.includes('.jpeg') || dimission.value.includes('.png')) {
  1082. imageShow.value = true
  1083. }
  1084. })
  1085. break;
  1086. }
  1087. }
  1088. // 图片下载
  1089. const download = (url: any, name: any) => {
  1090. let a_link = document.createElement('a') as any
  1091. fetch(url).then((res: any) => res.blob())
  1092. .then((blob: any) => {
  1093. // 将链接地址字符内容转变成blob地址
  1094. a_link.href = URL.createObjectURL(blob)
  1095. console.log(a_link.href)
  1096. a_link.download = name //下载的文件的名字
  1097. document.body.appendChild(a_link)
  1098. a_link.click()
  1099. })
  1100. // let image = new Image();
  1101. // // 解决跨域 Canvas 污染问题
  1102. // image.setAttribute("crossOrigin", "anonymous");
  1103. // image.onload = function () {
  1104. // let canvas = document.createElement("canvas");
  1105. // canvas.width = image.width;
  1106. // canvas.height = image.height;
  1107. // let context = canvas.getContext("2d");
  1108. // context.drawImage(image, 0, 0, image.width, image.height);
  1109. // let url = canvas.toDataURL("image/png"); //得到图片的base64编码数据
  1110. // let a = document.createElement("a"); // 生成一个a元素
  1111. // let event = new MouseEvent("click"); // 创建一个单击事件
  1112. // a.download = name; // 设置图片名称
  1113. // a.href = url; // 将生成的URL设置为a.href属性
  1114. // a.dispatchEvent(event); // 触发a的单击事件
  1115. // }
  1116. // image.src = url
  1117. }
  1118. const downloadImage = (type: any) => {
  1119. switch (type) {
  1120. case 1:
  1121. download(IDCardFront.value, IDCardFrontName.value)
  1122. break;
  1123. case 2:
  1124. download(IDCardBack.value, IDCardBackName.value)
  1125. break;
  1126. case 3:
  1127. download(certification.value, certificationName.value)
  1128. break;
  1129. case 4:
  1130. download(contract.value, contractName.value)
  1131. break;
  1132. case 5:
  1133. download(applicant.value, applicantName.value)
  1134. break;
  1135. case 6:
  1136. download(decidePay.value, decidePayName.value)
  1137. break;
  1138. case 7:
  1139. download(dimission.value, dimissionName.value)
  1140. break;
  1141. }
  1142. }
  1143. // 图片删除
  1144. const deleteImage = (type: any) => {
  1145. switch (type) {
  1146. case 1:
  1147. IDCardFront.value = ''
  1148. IDCardFrontName.value = ''
  1149. break;
  1150. case 2:
  1151. IDCardBack.value = ''
  1152. IDCardBackName.value = ''
  1153. break;
  1154. case 3:
  1155. certification.value = ''
  1156. certificationName.value = ''
  1157. break;
  1158. case 4:
  1159. contract.value = ''
  1160. contractName.value = ''
  1161. break;
  1162. case 5:
  1163. applicant.value = ''
  1164. applicantName.value = ''
  1165. break;
  1166. case 6:
  1167. decidePay.value = ''
  1168. decidePayName.value = ''
  1169. break;
  1170. case 7:
  1171. dimission.value = ''
  1172. dimissionName.value = ''
  1173. break;
  1174. }
  1175. }
  1176. // 管理人/推荐人
  1177. let userList = ref()
  1178. let recommendList = ref()
  1179. const getUser = (id: any) => {
  1180. api.operationApi.getUser({
  1181. id: id
  1182. }).then((res: any) => {
  1183. if (res?.code == 200) {
  1184. userList.value = res.data
  1185. } else {
  1186. ElMessage({
  1187. message: res.msg,
  1188. type: 'warning'
  1189. })
  1190. }
  1191. })
  1192. }
  1193. // 推荐人
  1194. const getRecommend = (id: any) => {
  1195. api.operationApi.getUser({
  1196. id: id,
  1197. typeAttr: 2
  1198. }).then((res: any) => {
  1199. if (res.code == 200) {
  1200. recommendList.value = res.data
  1201. } else {
  1202. ElMessage({
  1203. message: res.msg,
  1204. type: 'warning'
  1205. })
  1206. }
  1207. })
  1208. }
  1209. // 确定
  1210. const onSubmit = async (OperationFormRef: any, type: any) => {
  1211. console.log(operationForm)
  1212. if (!OperationFormRef) {
  1213. emits('closeDialog', '取消')
  1214. recordShow.value = false
  1215. OperationFormRef.resetFields()
  1216. return
  1217. }
  1218. if (type) {
  1219. await OperationFormRef.validate((valid: any, error: any) => {
  1220. if (valid) {
  1221. if (IDCardFront.value && IDCardBack.value) {
  1222. let formData = { ...operationForm }
  1223. // formData.organization = operationForm.value.organization[operationForm.value.organization.length - 1]
  1224. formData.systemCode = localStorage.getItem('login_system') ? localStorage.getItem('login_system') : ''
  1225. formData.province = operationForm.address ? operationForm.address[0] : ''
  1226. formData.city = operationForm.address ? operationForm.address[1] ? operationForm.address[1] : '' : ''
  1227. formData.district = operationForm.address ? operationForm.address[2] ? operationForm.address[2] : '' : ''
  1228. if (editId.value) {
  1229. api.operationApi.updateOperation(formData).then((res: any) => {
  1230. if (res.code == 200) {
  1231. ElMessage({
  1232. message: res.msg,
  1233. type: 'success'
  1234. })
  1235. emits('closeDialog', '确定')
  1236. } else {
  1237. ElMessage({
  1238. message: res.msg,
  1239. type: 'error'
  1240. })
  1241. }
  1242. IDCardFrontName.value = ''
  1243. IDCardFront.value = ''
  1244. IDCardBackName.value = ''
  1245. IDCardBack.value = ''
  1246. certificationName.value = ''
  1247. certification.value = ''
  1248. contractName.value = ''
  1249. contract.value = ''
  1250. applicantName.value = ''
  1251. applicant.value = ''
  1252. decidePayName.value = ''
  1253. decidePay.value = ''
  1254. dimissionName.value = ''
  1255. dimission.value = ''
  1256. recordShow.value = false
  1257. OperationFormRef.resetFields()
  1258. emits('closeDialog', '取消')
  1259. })
  1260. } else {
  1261. console.log(formData)
  1262. api.partnerApi.saveByPartner({
  1263. ...formData,
  1264. }).then((res: any) => {
  1265. if (res.code == 200) {
  1266. ElMessage({
  1267. message: res.msg,
  1268. type: 'success'
  1269. })
  1270. emits('closeDialog', '确定')
  1271. } else {
  1272. ElMessage({
  1273. message: res.msg,
  1274. type: 'error'
  1275. })
  1276. }
  1277. IDCardFrontName.value = ''
  1278. IDCardFront.value = ''
  1279. IDCardBackName.value = ''
  1280. IDCardBack.value = ''
  1281. certificationName.value = ''
  1282. certification.value = ''
  1283. contractName.value = ''
  1284. contract.value = ''
  1285. applicantName.value = ''
  1286. applicant.value = ''
  1287. decidePayName.value = ''
  1288. decidePay.value = ''
  1289. dimissionName.value = ''
  1290. dimission.value = ''
  1291. recordShow.value = false
  1292. OperationFormRef.resetFields()
  1293. emits('closeDialog', '取消')
  1294. })
  1295. }
  1296. } else {
  1297. ElMessage({
  1298. message: '请上传必传附件!',
  1299. type: 'warning'
  1300. })
  1301. }
  1302. } else {
  1303. Object.keys(error).forEach((key, i) => {
  1304. if (i == 0) {
  1305. const firstFiled = error[key][0].field
  1306. OperationFormRef.scrollToField(firstFiled)
  1307. }
  1308. })
  1309. ElMessage({
  1310. message: '请正确填写相关信息!',
  1311. type: 'warning'
  1312. })
  1313. }
  1314. })
  1315. } else {
  1316. IDCardFrontName.value = ''
  1317. IDCardFront.value = ''
  1318. IDCardBackName.value = ''
  1319. IDCardBack.value = ''
  1320. certificationName.value = ''
  1321. certification.value = ''
  1322. contractName.value = ''
  1323. contract.value = ''
  1324. applicantName.value = ''
  1325. applicant.value = ''
  1326. decidePayName.value = ''
  1327. decidePay.value = ''
  1328. dimissionName.value = ''
  1329. dimission.value = ''
  1330. recordShow.value = false
  1331. emits('closeDialog', '取消')
  1332. OperationFormRef.resetFields()
  1333. }
  1334. }
  1335. const getMinValueFromStrArray = (strArray: string[]): number | null => {
  1336. // 检查数组是否为空
  1337. if (!strArray || strArray.length === 0) {
  1338. console.warn('数组为空');
  1339. return null;
  1340. }
  1341. try {
  1342. // 将字符串转换为数字
  1343. const numArray = strArray.map(str => {
  1344. const num = Number(str);
  1345. // 检查是否为有效数字
  1346. if (isNaN(num)) {
  1347. throw new Error(`字符串 "${str}" 无法转换为数字`);
  1348. }
  1349. return num;
  1350. });
  1351. // 获取最小值
  1352. const minValue = Math.min(...numArray);
  1353. return minValue;
  1354. } catch (error) {
  1355. console.error('获取最小值失败:', error);
  1356. return null;
  1357. }
  1358. };
  1359. // 初始化个人信息
  1360. let options = ref([])
  1361. const initInfo = () => {
  1362. /*
  1363. * 性别 gender
  1364. 民族 nation
  1365. 婚姻状况 marriage
  1366. 政治面貌 political_status
  1367. 健康状况 health_status
  1368. 学历 educational
  1369. * */
  1370. let infoList = ['gender', 'nation', 'marriage', 'political_status', 'health_status', 'educational', 'team']
  1371. infoList.forEach((item: string, index: number) => {
  1372. api.commonApi.personInfo(item).then((res: any) => {
  1373. if (res.code == 200) {
  1374. options.value[index] = [...res.data]
  1375. } else {
  1376. ElMessage({
  1377. message: res.msg,
  1378. type: 'warning'
  1379. })
  1380. }
  1381. })
  1382. })
  1383. }
  1384. // 获取地区数据
  1385. const areaOptions = ref([]);
  1386. const areaProps = ref({
  1387. value: "areaCode",
  1388. label: "areaCname",
  1389. children: "child",
  1390. });
  1391. const getArea = () => {
  1392. api.areaApi.areaList({}).then((res) => {
  1393. areaOptions.value = res.data;
  1394. });
  1395. }
  1396. // 团队数据
  1397. const initTeamData = async (e: any) => {
  1398. const { code, data, msg }: any = await api.teamApi.teamList({
  1399. attribute: e,
  1400. param: ''
  1401. })
  1402. if (code == 200) {
  1403. teamList.value = data
  1404. } else {
  1405. ElMessage({
  1406. message: msg,
  1407. type: 'warning'
  1408. })
  1409. }
  1410. }
  1411. let teamList = ref([])
  1412. // 机构切换
  1413. const deptIdChange = (e: any) => {
  1414. if (e) {
  1415. operationForm.deptId = e[e.length - 1]
  1416. getUser(e[e.length - 1])
  1417. getRecommend(e[e.length - 1])
  1418. }
  1419. }
  1420. // 初始化银行数据
  1421. let bankOption = ref()
  1422. const initBankCard = () => {
  1423. api.commonApi.personInfo('bank_info').then((res: any) => {
  1424. if (res.code == 200) {
  1425. bankOption.value = res.data
  1426. } else {
  1427. ElMessage({
  1428. message: res.msg,
  1429. type: 'warning'
  1430. })
  1431. }
  1432. })
  1433. }
  1434. let deptOption = ref([])
  1435. const optionProps = {
  1436. value: 'id',
  1437. label: 'name',
  1438. children: 'children',
  1439. checkStrictly: true,
  1440. }
  1441. // 获取机构数据
  1442. const institutionList = () => {
  1443. api.institutionApi.institutionList({ name: '', system: '' }).then((res: any) => {
  1444. if (res?.code == 200) {
  1445. deptOption.value = res.data
  1446. } else {
  1447. ElMessage({
  1448. message: res.msg,
  1449. type: 'warning'
  1450. })
  1451. }
  1452. })
  1453. }
  1454. onMounted(() => {
  1455. initInfo()
  1456. getArea()
  1457. initBankCard()
  1458. institutionList()
  1459. getGradeOptions()//获取用户等级列表
  1460. })
  1461. defineExpose({
  1462. initEditData,
  1463. operationForm,
  1464. initAddData
  1465. })
  1466. </script>
  1467. <style scoped lang="scss">
  1468. .typeAttrMap {
  1469. padding: 2px 4px;
  1470. box-sizing: border-box;
  1471. background-color: #00a0f4;
  1472. color: #fff;
  1473. border-radius: 3px;
  1474. }
  1475. .fileInfo {
  1476. display: flex;
  1477. align-items: center;
  1478. justify-content: flex-start;
  1479. //padding: 2px 20px;
  1480. border-radius: 5px;
  1481. margin: 0 10px;
  1482. //&:hover{
  1483. // background: #ccc;
  1484. //}
  1485. .fileName {
  1486. width: 200px;
  1487. overflow: hidden;
  1488. text-overflow: ellipsis;
  1489. white-space: nowrap;
  1490. }
  1491. .fileBtn {
  1492. display: flex;
  1493. align-items: center;
  1494. .btn-icon {
  1495. margin: 0 10px;
  1496. font-size: 16px;
  1497. cursor: pointer;
  1498. &:hover {
  1499. color: #00a0f4;
  1500. }
  1501. }
  1502. }
  1503. .file-box {
  1504. position: relative;
  1505. .btn-top {
  1506. width: 100%;
  1507. display: flex;
  1508. align-items: center;
  1509. justify-content: flex-end;
  1510. position: absolute;
  1511. top: 0;
  1512. left: 0;
  1513. .image-close {
  1514. display: block;
  1515. width: 12px;
  1516. height: 12px;
  1517. }
  1518. }
  1519. .file-img {
  1520. display: block;
  1521. width: 208px;
  1522. height: 130px;
  1523. border-radius: 5px;
  1524. }
  1525. .btn-bottom {
  1526. position: absolute;
  1527. left: 0;
  1528. bottom: 0;
  1529. z-index: 1000;
  1530. display: flex;
  1531. align-items: center;
  1532. height: 24px;
  1533. width: 100%;
  1534. background: url("@/assets/images/btn-bg.png") no-repeat;
  1535. background-size: 100% 100%;
  1536. .width-50 {
  1537. width: 50%;
  1538. }
  1539. }
  1540. }
  1541. }
  1542. .image-view {
  1543. display: block;
  1544. width: 400px;
  1545. height: 260px;
  1546. border-radius: 5px;
  1547. margin: 0 auto;
  1548. }
  1549. :deep(.el-input__inner[type=number]::-webkit-outer-spin-button) {
  1550. -webkit-appearance: none;
  1551. margin: 0;
  1552. }
  1553. :deep(.el-input__inner[type=number]::-webkit-inner-spin-button) {
  1554. -webkit-appearance: none;
  1555. margin: 0;
  1556. }
  1557. :deep(.el-input__inner[type=number]) {
  1558. -moz-appearance: textfield;
  1559. }
  1560. :deep(.vue-office-docx-main) {
  1561. height: 600px;
  1562. overflow-y: auto;
  1563. }
  1564. :deep(.docx-wrapper) {
  1565. background: white;
  1566. }
  1567. </style>