edit.vue 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927
  1. <template>
  2. <ion-page class="list-page">
  3. <ion-header class="header-theme2">
  4. <ion-toolbar>
  5. <ion-buttons slot="start">
  6. <ion-icon :icon="arrowBackOutline" @click="onBack" style="padding-left:10px;width:24px;height:24px;"></ion-icon>
  7. </ion-buttons>
  8. <ion-title>求职人员信息登记</ion-title>
  9. </ion-toolbar>
  10. </ion-header>
  11. <ion-content>
  12. <div class="stepFlex">
  13. <div v-for="(record,key) in stepList" :key="key" class="stepFlex-item">
  14. <div
  15. :class="[(record.val < curStepData?.statusVal || curStepData?.statusVal == stepList.val) ? 'greenCircle' :record.val == curStepData?.statusVal ? 'now' : 'grayCircle']"></div>
  16. <div v-if="key !== stepList.length - 1"
  17. :class="[record.val < curStepData?.statusVal ? 'greenLine' : 'grayLine']"></div>
  18. <div class="stepFlex-item-label">
  19. <p class="stepFlex-item-label-title">{{ record.title }}</p>
  20. <p class="stepFlex-item-label-desc">{{ record.desc }}</p>
  21. </div>
  22. </div>
  23. </div>
  24. <form autocomplete="off">
  25. <div class="bw-vue-form">
  26. <ion-list v-if="curStepData.statusVal==1">
  27. <div class="form-title">基本信息</div>
  28. <div class="form-input">
  29. <ion-label>姓名<span class="danger">*</span></ion-label>
  30. <ion-input name="name" id="name" class="custom" :clear-input="true"
  31. placeholder="请输入姓名" v-model="baseData.name" >
  32. </ion-input>
  33. <!-- <ion-note slot="error">姓名不能为空</ion-note>-->
  34. </div>
  35. <div class="form-input">
  36. <ion-label>公民身份号码<span class="danger">*</span></ion-label>
  37. <ion-input name="identityNumber" id="identityNumber" class="custom" :clear-input="true"
  38. placeholder="请输入身份证号码" v-model="baseData.identityNumber" ></ion-input>
  39. <!-- <ion-note slot="error">公民身份号码不能为空</ion-note>-->
  40. </div>
  41. <div class="form-select">
  42. <ion-label>性别<span class="danger">*</span></ion-label>
  43. <ion-select name="sex" id="sex" okText="确定" cancelText="取消" v-model="baseData.sex"
  44. interface="action-sheet" placeholder="请选择性别" style="width:100%;text-align:left;" >
  45. <ion-select-option v-for=" (it,key) in genderList" :key="key" :value="it.value" >{{ it.name }}</ion-select-option>
  46. </ion-select>
  47. <!-- <ion-note slot="error">性别不能为空</ion-note>-->
  48. </div>
  49. <div class="form-input">
  50. <ion-label>联系电话<span class="danger">*</span></ion-label>
  51. <ion-input name="userMobile" id="userMobile" style="text-align: left;" class="custom" :clear-input="true"
  52. placeholder="请输入联系电话" v-model="baseData.userMobile" ></ion-input>
  53. <!-- <ion-note slot="error">联系电话不能为空</ion-note>-->
  54. </div>
  55. <div class="form-select">
  56. <ion-label>所属驿站<span class="danger">*</span></ion-label>
  57. <ion-select disabled name="siteID" id="siteID" okText="确定" cancelText="取消" v-model="baseData.siteID"
  58. interface="action-sheet" placeholder="请选择所属驿站" style="width:100%;text-align:left;">
  59. <ion-select-option v-for=" (it,key) in siteInfoList" :key="key" :value="it.value">
  60. {{ it.text }}
  61. </ion-select-option>
  62. </ion-select>
  63. <!-- <ion-note slot="error">所属驿站不能为空</ion-note>-->
  64. </div>
  65. <div class="form-select">
  66. <ion-label>市/县<span class="danger">*</span></ion-label>
  67. <ion-select name="regionCode" id="regionCode" okText="确定" cancelText="取消" v-model="baseData.regionCode"
  68. interface="action-sheet" placeholder="请选择市/县" style="width:100%;text-align:left;" @ionChange="regionChange()" >
  69. <ion-select-option v-for=" (it,key) in regionList" :key="key" :value="it.code">
  70. {{ it.name }}
  71. </ion-select-option>
  72. </ion-select>
  73. </div>
  74. <div class="form-select">
  75. <ion-label>所在街道<span class="danger">*</span></ion-label>
  76. <ion-select name="streetCode" id="streetCode" okText="确定" cancelText="取消" v-model="baseData.streetCode"
  77. interface="action-sheet" placeholder="请选择镇/街" style="width:100%;text-align:left;">
  78. <ion-select-option v-for=" (it,key) in streetList" :key="key" :value="it.code">
  79. {{ it.name }}
  80. </ion-select-option>
  81. </ion-select>
  82. </div>
  83. <div class="form-input">
  84. <ion-label>住址<span class="danger">*</span></ion-label>
  85. <ion-input name="address" id="address" style="text-align: left;" class="custom" :clear-input="true"
  86. placeholder="请输入住址" v-model="baseData.address" ></ion-input>
  87. <!-- <ion-note slot="error">地址不能为空</ion-note>-->
  88. </div>
  89. <div class="form-select">
  90. <ion-label>就业状态<span class="danger">*</span></ion-label>
  91. <ion-select name="jobStatusID" id="jobStatusID" okText="确定" cancelText="取消" v-model="baseData.jobStatusID"
  92. interface="action-sheet" placeholder="请选择就业状态" style="width:100%;text-align:left;" >
  93. <ion-select-option v-for=" (it,key) in jobUserStatusList" :key="key" :value="it.value">{{ it.name }}</ion-select-option>
  94. </ion-select>
  95. <!-- <ion-note slot="error">就业状态不能为空</ion-note>-->
  96. </div>
  97. <div class="form-select">
  98. <ion-label>重点人员类别<span class="danger">*</span></ion-label>
  99. <ion-select name="keyPersonTypeID" id="keyPersonTypeID" okText="确定" cancelText="取消" v-model="baseData.keyPersonTypeID"
  100. interface="action-sheet" placeholder="请选择重点人员类别" style="width:100%;text-align:left;" >
  101. <ion-select-option v-for=" (it,key) in keyPersonTypeList" :key="key" :value="it.value">
  102. {{ it.name }}
  103. </ion-select-option>
  104. </ion-select>
  105. <!-- <ion-note slot="error">重点人员类别不能为空</ion-note>-->
  106. </div>
  107. <div class="form-title">
  108. 其他信息
  109. <div style="float: right;">
  110. <ion-icon :icon="chevronDownOutline" @click="expandChange" v-if="!expand"
  111. style="font-size: 24px;"></ion-icon>
  112. <ion-icon :icon="chevronUpOutline" @click="expandChange" v-if="expand"
  113. style="font-size: 24px;"></ion-icon>
  114. </div>
  115. </div>
  116. <div v-if="expand">
  117. <div class="form-select">
  118. <ion-label>民族</ion-label>
  119. <ion-select name="nationID" id="nationID" okText="确定" cancelText="取消" v-model="baseData.nation"
  120. interface="action-sheet" placeholder="请选择民族" style="width:100%;text-align:left;" >
  121. <ion-select-option v-for=" (it,key) in nationTypeList" :key="key" :value="it.name">
  122. {{ it.name }}
  123. </ion-select-option>
  124. </ion-select>
  125. <!-- <ion-input name="nation" id="nation" style="text-align: left;" class="custom" :clear-input="true"
  126. v-model="baseData.nation" placeholder="请输入民族" ></ion-input>-->
  127. </div>
  128. <div class="form-select">
  129. <ion-label>政治面貌</ion-label>
  130. <ion-select name="politicsStatusID" id="politicsStatusID" okText="确定" cancelText="取消" v-model="baseData.politicsStatusID"
  131. interface="action-sheet" placeholder="请选择政治面貌" style="width:100%;text-align:left;" >
  132. <ion-select-option v-for=" (it,key) in politicsStatusList" :key="key" :value="it.value">
  133. {{ it.name }}
  134. </ion-select-option>
  135. </ion-select>
  136. </div>
  137. <div class="form-input">
  138. <ion-label>出生地</ion-label>
  139. <ion-input name="birthPlace" id="birthPlace" style="text-align: left;" class="custom" :clear-input="true"
  140. v-model="baseData.birthPlace" placeholder="请输入出生地" ></ion-input>
  141. </div>
  142. <!-- <div class="form-input">
  143. <ion-label>出生日期</ion-label>
  144. <ion-datetime-button datetime="birthDay" style="position:relative;right:110px;"></ion-datetime-button>
  145. <ion-modal :keep-contents-mounted="true">
  146. <ion-datetime name="birthDay" id="birthDay" placeholder="日期"
  147. v-model="baseData.birthDay" :prefer-wheel="true"
  148. dataformatas="YYYY-MM-DD" presentation="date" cancel-text="取消" done-text="确定"
  149. :show-default-buttons="true">
  150. </ion-datetime>
  151. </ion-modal>
  152. </div>-->
  153. <div class="form-select">
  154. <ion-label>户口性质</ion-label>
  155. <ion-select name="familyNatureID" id="familyNatureID" okText="确定" cancelText="取消" v-model="baseData.familyNatureID"
  156. interface="action-sheet" placeholder="请选择户口性质" style="width:100%;text-align:left;">
  157. <ion-select-option v-for=" (it,key) in familyNatureList" :key="key" :value="it.value">
  158. {{ it.name }}
  159. </ion-select-option>
  160. </ion-select>
  161. </div>
  162. <div class="form-select">
  163. <ion-label>文化程度</ion-label>
  164. <ion-select name="cultureRank" id="cultureRank" okText="确定" cancelText="取消" v-model="baseData.cultureRank"
  165. interface="action-sheet" placeholder="请选择文化程度" style="width:100%;text-align:left;">
  166. <ion-select-option v-for=" (it,key) in cultureRankList" :key="key" :value="it.value">
  167. {{ it.name }}
  168. </ion-select-option>
  169. </ion-select>
  170. </div>
  171. <div class="form-select">
  172. <ion-label>健康状况</ion-label>
  173. <ion-select name="healthID" id="healthID" okText="确定" cancelText="取消" v-model="baseData.healthID"
  174. interface="action-sheet" placeholder="请选择健康状况" style="width:100%;text-align:left;">
  175. <ion-select-option v-for=" (it,key) in userHealthList" :key="key" :value="it.value">
  176. {{ it.name }}
  177. </ion-select-option>
  178. </ion-select>
  179. </div>
  180. <div class="form-select">
  181. <ion-label>血型</ion-label>
  182. <ion-select name="bloodTypeID" id="bloodTypeID" okText="确定" cancelText="取消" v-model="baseData.bloodTypeID"
  183. interface="action-sheet" placeholder="请选择血型" style="width:100%;text-align:left;">
  184. <ion-select-option v-for=" (it,key) in bloodTypeList" :key="key" :value="it.value">
  185. {{ it.name }}
  186. </ion-select-option>
  187. </ion-select>
  188. </div>
  189. <div class="form-input">
  190. <ion-label>身高(cm)</ion-label>
  191. <ion-input name="height" id="height" style="text-align: left;" class="custom" :clear-input="true"
  192. placeholder="请输入身高" v-model="baseData.height" ></ion-input>
  193. </div>
  194. <div class="form-input">
  195. <ion-label>视力</ion-label>
  196. <ion-input name="vision" id="vision" style="text-align: left;" class="custom" :clear-input="true"
  197. placeholder="如1.0" v-model="baseData.vision" ></ion-input>
  198. </div>
  199. <div class="form-input">
  200. <ion-label>体重(kg)</ion-label>
  201. <ion-input name="weight" id="weight" style="text-align: left;" class="custom" :clear-input="true"
  202. placeholder="请输入体重" v-model="baseData.weight" ></ion-input>
  203. </div>
  204. <div class="form-select">
  205. <ion-label>婚姻状况</ion-label>
  206. <ion-select name="maritalStatusID" id="maritalStatusID" okText="确定" cancelText="取消" v-model="baseData.maritalStatusID"
  207. interface="action-sheet" placeholder="请选择婚姻状况" style="width:100%;text-align:left;">
  208. <ion-select-option v-for=" (it,key) in maritalStatusList" :key="key" :value="it.value">
  209. {{ it.name }}
  210. </ion-select-option>
  211. </ion-select>
  212. </div>
  213. <!-- <div class="form-select">
  214. <ion-label>省份</ion-label>
  215. <ion-select name="provinceCode" id="provinceCode" okText="确定" cancelText="取消" v-model="baseData.provinceCode"
  216. interface="action-sheet" placeholder="请选择省份" style="width:100%;text-align:left;" @change="provinceChange()" >
  217. <ion-select-option v-for=" (it,key) in provinceList" :key="key" :value="it.value">
  218. {{ it.name }}
  219. </ion-select-option>
  220. </ion-select>
  221. </div>-->
  222. <div class="form-input">
  223. <ion-label>联系人员</ion-label>
  224. <ion-input name="userName" id="userName" style="text-align: left;" class="custom" :clear-input="true"
  225. placeholder="请输入联系人员" v-model="baseData.userName" ></ion-input>
  226. </div>
  227. <div class="form-input">
  228. <ion-label>电子邮箱</ion-label>
  229. <ion-input name="email" id="email" style="text-align: left;" class="custom" :clear-input="true"
  230. placeholder="请输入电子邮箱" v-model="baseData.email" ></ion-input>
  231. </div>
  232. <div class="form-input">
  233. <ion-label>家庭住址</ion-label>
  234. <ion-textarea name="familyAddress" id="familyAddress" class="custom" rows="4"
  235. placeholder="请输入家庭住址" v-model="baseData.familyAddress" style="border-bottom: 1px solid #fff2e8;"></ion-textarea>
  236. </div>
  237. <div class="form-input">
  238. <ion-label>兴趣爱好</ion-label>
  239. <ion-textarea name="hobby" id="hobby" class="custom" rows="4"
  240. placeholder="请输入兴趣爱好" v-model="baseData.hobby" style="border-bottom: 1px solid #fff2e8;" ></ion-textarea>
  241. </div>
  242. </div>
  243. </ion-list>
  244. <ion-list v-if="curStepData.statusVal==2" >
  245. <div class="form-title">
  246. 教育经历
  247. <ion-icon :icon="addCircleOutline" class="iconBtn" style="float:right;"
  248. @click="onPathForward('./educationEdit',null,null,null,2)"></ion-icon>
  249. </div>
  250. <div class="bw-vue-list">
  251. <div class="list-content" v-if="!loading">
  252. <ion-list>
  253. <div v-for="(record,key) in educationList" :key="key" >
  254. <ion-item-sliding>
  255. <ion-item detail @click="onPathForward('./educationEdit',record.educationID,null,null,2)">
  256. <ion-label>
  257. <h2>{{record.schoolName}}</h2>
  258. <p>{{dayjs(record.schoolTime).format("YYYY-MM-DD")}}至{{dayjs(record.overTime).format("YYYY-MM-DD")}}</p>
  259. </ion-label>
  260. </ion-item>
  261. <ion-item-options>
  262. <ion-item-option color="danger" @click="setDelAlertOpen(true, record.educationID)">
  263. <ion-icon :icon="trashOutline"></ion-icon>
  264. </ion-item-option>
  265. </ion-item-options>
  266. </ion-item-sliding>
  267. </div>
  268. </ion-list>
  269. </div>
  270. </div>
  271. <b-empty v-if="educationList.length==0" :loading="loading" />
  272. </ion-list>
  273. <ion-list v-if="curStepData.statusVal==3" >
  274. <div class="form-title">
  275. 工作经验
  276. <ion-icon :icon="addCircleOutline" class="iconBtn" style="float:right;"
  277. @click="onPathForward('./experienceEdit',null,null,null,3)"></ion-icon>
  278. </div>
  279. <div class="bw-vue-list">
  280. <div class="list-content" v-if="!loading">
  281. <ion-list>
  282. <div v-for="(record,key) in experienceList" :key="key">
  283. <ion-item-sliding>
  284. <ion-item detail @click="onPathForward('./experienceEdit',null,record.experienceID,null,3)">
  285. <ion-label>
  286. <h2>{{record.workAddress}}</h2>
  287. <p>{{dayjs(record.startTime).format("YYYY-MM-DD")}}至{{dayjs(record.endTime).format("YYYY-MM-DD")}}</p>
  288. </ion-label>
  289. </ion-item>
  290. <ion-item-options>
  291. <ion-item-option color="danger" @click="setDelAlertOpen(true, record.experienceID)">
  292. <ion-icon :icon="trashOutline"></ion-icon>
  293. </ion-item-option>
  294. </ion-item-options>
  295. </ion-item-sliding>
  296. </div>
  297. </ion-list>
  298. </div>
  299. </div>
  300. <b-empty v-if="experienceList.length==0" :loading="loading" />
  301. </ion-list>
  302. <ion-list v-if="curStepData.statusVal==4">
  303. <div class="form-title">
  304. 求职意向
  305. <ion-icon :icon="addCircleOutline" class="iconBtn" style="float:right;"
  306. @click="onPathForward('./jobHuntEdit',null,null,null,4)"></ion-icon>
  307. </div>
  308. <div class="bw-vue-list">
  309. <div class="list-content" v-if="!loading">
  310. <ion-list>
  311. <div v-for="(record,key) in jobHuntList" :key="key">
  312. <ion-item-sliding>
  313. <ion-item detail @click="onPathForward('./jobHuntEdit',null,null,record.jobHuntID,4)">
  314. <ion-label>
  315. <h2>{{record.professionName}}</h2>
  316. <p>期望薪资:{{record.minSalary}}-{{record.maxSalary}}</p>
  317. </ion-label>
  318. </ion-item>
  319. <ion-item-options>
  320. <ion-item-option color="danger" @click="setDelAlertOpen(true, record.jobHuntID)">
  321. <ion-icon :icon="trashOutline"></ion-icon>
  322. </ion-item-option>
  323. </ion-item-options>
  324. </ion-item-sliding>
  325. </div>
  326. </ion-list>
  327. </div>
  328. </div>
  329. <b-empty v-if="jobHuntList.length==0" :loading="loading" />
  330. </ion-list>
  331. <!--<ion-refresher pulling-text="下拉刷新" @ionRefresh="onRefresh"></ion-refresher>-->
  332. <ion-infinite-scroll v-if="curStepData.statusVal!=1" threshold="100px" @ionInfinite="onScroll($event)">
  333. <ion-infinite-scroll-content
  334. :loadingText="pageParams.total>pageParams.pageIndex*pageParams.pageSize?'正在加载...':'暂无更多'"
  335. loadingSpinner="bubbles">
  336. </ion-infinite-scroll-content>
  337. </ion-infinite-scroll>
  338. </div>
  339. </form>
  340. </ion-content>
  341. <ion-footer>
  342. <ion-toolbar>
  343. <ion-button style="width: 100%;" @click="onSave" v-if="curStepData.statusVal==1">保存并下一步</ion-button>
  344. <div v-if="curStepData.statusVal!=1" >
  345. <ion-button style="width: 48%;float:left;margin-left: 1%;" @click="onBack" >上一步</ion-button>
  346. <ion-button style="width: 48%;margin-right: 1%;" @click="onSave" v-if="curStepData.statusVal!=4">下一步</ion-button>
  347. <ion-button style="width: 48%;margin-right: 1%;" @click="onFinish" v-if="curStepData.statusVal==4">完 成</ion-button>
  348. </div>
  349. </ion-toolbar>
  350. </ion-footer>
  351. <ion-alert
  352. :is-open="delAlertOpen"
  353. header="删除确认"
  354. message="确定要删除该信息吗?"
  355. :buttons="delAlertButtons"
  356. @didDismiss="setDelAlertOpen(false, null)"
  357. ></ion-alert>
  358. <ion-alert
  359. :is-open="infoAlertOpen"
  360. :header="infoAlterData.title"
  361. :message="infoAlterData.message"
  362. :buttons="infoAlertButtons"
  363. @didDismiss="setInfoAlertOpen(false)"
  364. ></ion-alert>
  365. <ion-loading
  366. :is-open="delLoading"
  367. message="删除中..."
  368. @didDismiss="setDelLoadingOpen(false)" >
  369. </ion-loading>
  370. </ion-page>
  371. </template>
  372. <script lang="ts">
  373. import {chevronDownOutline, chevronUpOutline,arrowBackOutline,addCircleOutline,trashOutline} from 'ionicons/icons';
  374. import {reactive,defineComponent, computed,watch,ref,toRefs} from "vue";
  375. import {useRoute, useRouter} from "vue-router";
  376. import {required} from "@vuelidate/validators";
  377. import {useVuelidate} from "@vuelidate/core";
  378. import {getRegionCodeList,getStreetCodeList} from "@/api/system/area";
  379. import {getJobUserById,baseInfoSave} from "@/api/jobUserInfo";
  380. import {getEducationListByJobUserID} from "@/api/education";
  381. import {getExperienceListByJobUserID} from "@/api/experience";
  382. import {getJobHuntListByJobUserID} from "@/api/jobHuntInfo";
  383. import {getSiteDataList} from "@/api/siteInfo";
  384. import {getSysDictionaryList} from '@/api/system/dictionary';
  385. import {alertController, onIonViewDidEnter} from "@ionic/vue";
  386. import dayjs from "dayjs";
  387. import {post} from "@/api/common";
  388. interface SelectProps {
  389. name: string,
  390. value: string
  391. }
  392. interface StepParams{
  393. name: string,
  394. statusVal: number
  395. }
  396. export default defineComponent({
  397. name: 'jobUserEdit',
  398. setup() {
  399. const router = useRouter();
  400. const route = useRoute();
  401. const isAllowCommit = ref(true);
  402. const expand = ref<boolean>(false);
  403. const loading = ref(true);
  404. const siteInfoList = ref<SelectProps[]>([]);
  405. const curStepData = ref<StepParams>({
  406. name:"",
  407. statusVal: 1
  408. });
  409. const stepList = ref([
  410. {title: '基础信息', desc: '个人基础信息', val: 1},
  411. {title: '教育经历', desc: '完善教育经历',val: 2},
  412. {title: '工作经验', desc: '完善工作经验', val: 3},
  413. {title: '求职意向', desc: '个人求职意向', val: 4},
  414. ]);
  415. const genderList = ref<SelectProps[]>([]);
  416. const jobUserStatusList = ref<SelectProps[]>([]);
  417. const keyPersonTypeList = ref<SelectProps[]>([]);
  418. const cultureRankList = ref<SelectProps[]>([]);
  419. const userHealthList = ref<SelectProps[]>([]);
  420. const bloodTypeList = ref<SelectProps[]>([]);
  421. const maritalStatusList = ref<SelectProps[]>([]);
  422. const provinceList = ref<SelectProps[]>([{name:'广东省',value:'440000000000000'}]);
  423. const nationTypeList = ref<SelectProps[]>([]);
  424. const familyNatureList = ref([]);
  425. const politicsStatusList = ref([]);
  426. const regionList = ref<SelectProps[]>([]);
  427. const streetList = ref<SelectProps[]>([]);
  428. const educationList = ref([]);
  429. const experienceList = ref([]);
  430. const jobHuntList = ref([]);
  431. const baseInfoData = reactive({
  432. baseData:{
  433. jobUserID:null,
  434. siteID:null,
  435. name:null,
  436. identityNumber: null,
  437. sex: null,
  438. userMobile: null,
  439. address: null,
  440. jobStatusID: null,
  441. keyPersonTypeID: null,
  442. nation:null,
  443. politicsStatusID:null,
  444. birthPlace:null,
  445. birthDay:null,
  446. familyNatureID:null,
  447. cultureRank:null,
  448. healthID:null,
  449. boolTypeID:null,
  450. height:null,
  451. vision:null,
  452. weight:null,
  453. maritalStatusID:null,
  454. provinceCode:null,
  455. regionCode:null,
  456. streetCode:null,
  457. userName:null,
  458. familyAddress:null,
  459. postalCode:null,
  460. email:'',
  461. hobby:null,
  462. personalSkills:null,
  463. }});
  464. const pageParams = reactive({
  465. pageIndex: 1,
  466. pageSize: 5,
  467. total:0,
  468. jobUserID:''
  469. });
  470. const baseDataRule = computed(()=>{
  471. return {baseData:{
  472. siteID:{required},
  473. name:{required},
  474. identityNumber:{required:true,},
  475. sex:{required},
  476. userMobile:{required},
  477. address:{required},
  478. jobStatusID:{required},
  479. keyPersonTypeID:{required},
  480. }}
  481. });
  482. const baseDataValid = useVuelidate(baseDataRule,baseInfoData);
  483. const expandChange= ()=>{
  484. expand.value = !expand.value;
  485. }
  486. // 删除警告弹窗开关
  487. const delAlertOpen = ref(false);
  488. // 删除数据
  489. const delID = ref("");
  490. const postUrl = ref("jobUserService/education/deleteEducation");
  491. const actionName = ref("删除教育经历信息");
  492. // 删除加载
  493. const delLoading = ref(false);
  494. // 信息弹窗开关
  495. const infoAlertOpen = ref(false);
  496. // 删除警告弹窗按钮定义
  497. const infoAlertButtons = [
  498. {
  499. text: '确定',
  500. role: 'confirm',
  501. handler: () => {
  502. reload(baseInfoData.baseData.jobUserID,curStepData.value.statusVal);
  503. },
  504. },
  505. ];
  506. // 设置要删除的教育经历
  507. function setDelAlertOpen(value: boolean, id: any) {
  508. delAlertOpen.value = value;
  509. if(id != null) {
  510. delID.value = id;
  511. }
  512. }
  513. // 设置信息提示弹窗开关
  514. function setInfoAlertOpen(value: boolean) {
  515. infoAlertOpen.value = value;
  516. }
  517. // 设置删除弹窗开启关闭
  518. function setDelLoadingOpen(value: boolean) {
  519. delLoading.value = value;
  520. }
  521. // 信息弹窗内容
  522. const infoAlterData = reactive({
  523. title:"",
  524. message:""
  525. });
  526. // 删除警告弹窗按钮定义
  527. const delAlertButtons = [
  528. {
  529. text: '取消',
  530. role: 'cancel',
  531. handler: () => {
  532. console.log("取消了删除");
  533. },
  534. },
  535. {
  536. text: '确定',
  537. role: 'confirm',
  538. handler: () => {
  539. delLoading.value = true;
  540. postUrl.value = "jobUserService/education/deleteEducation";
  541. actionName.value = "删除教育经历";
  542. if(curStepData.value.statusVal!=2){
  543. postUrl.value = curStepData.value.statusVal==3 ?"jobUserService/experience/deleteExperience":"jobUserService/jobHunt/delete";
  544. actionName.value = curStepData.value.statusVal==3 ?"删除工作经验":"删除求职意向";
  545. }
  546. post(postUrl.value,[delID.value],actionName.value).then((res) => {
  547. /*infoAlterData.title = "提示";
  548. infoAlterData.message = "删除成功";
  549. setInfoAlertOpen(true);*/
  550. }).finally(()=>{
  551. delLoading.value = false;
  552. reload(baseInfoData.baseData.jobUserID,curStepData.value.statusVal);
  553. });
  554. },
  555. },
  556. ];
  557. const presentAlert = async (message: string) => {
  558. const alert = await alertController.create({
  559. header: '错误!',
  560. message: message,
  561. buttons: [
  562. '确定'
  563. ],
  564. });
  565. await alert.present();
  566. }
  567. const onBack = () => {
  568. curStepData.value.statusVal-=1;
  569. if(curStepData.value.statusVal > 0){
  570. router.push({path:"./edit", query: {reload:0,educationID:null,jobHuntID:null,jobUserID: baseInfoData.baseData.jobUserID,status:curStepData.value.statusVal}});
  571. }else{
  572. router.push("./list");
  573. }
  574. }
  575. const inputDataValidate = () =>{
  576. isAllowCommit.value = true;
  577. const identReg = /^[1-9]{1}[0-9]{14}$|^[1-9]{1}[0-9]{16}([0-9]|[xX])$/;
  578. if(baseInfoData.baseData.identityNumber != null){
  579. if(!identReg.test(baseInfoData.baseData.identityNumber)){
  580. presentAlert("输入的身份证号码有误!");
  581. isAllowCommit.value = false;
  582. }
  583. }
  584. const mobileReg = /^1[3|4|5|6|7|8|9]\d{9}$/;
  585. if(baseInfoData.baseData.userMobile != null){
  586. if(!mobileReg.test(baseInfoData.baseData.userMobile)){
  587. presentAlert("输入的联系电话有误!");
  588. isAllowCommit.value = false;
  589. }
  590. }
  591. const emailReg = /^[a-z0-9]+([._\\-]*[a-z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$/;
  592. if(baseInfoData.baseData.email!=""&&baseInfoData.baseData.email!=null){
  593. if(!emailReg.test(baseInfoData.baseData.email)){
  594. presentAlert("输入的电子邮箱有误!");
  595. isAllowCommit.value = false;
  596. }
  597. }
  598. };
  599. const onSave = async function (){
  600. if (curStepData.value.statusVal==1){
  601. const isFormCorrect = await baseDataValid.value.$validate();
  602. if(!isFormCorrect){
  603. await presentAlert("请填写完整的信息!");
  604. return null;
  605. }
  606. inputDataValidate();
  607. if(isAllowCommit.value){
  608. baseInfoSave(baseInfoData.baseData).then(result => {
  609. if (result) {
  610. router.push({path: './edit', query: {reload:0,jobUserID: baseInfoData.baseData.jobUserID,status:2}});
  611. }
  612. });
  613. }
  614. }
  615. else if (curStepData.value.statusVal==2){
  616. await router.push({path: './edit', query: {reload:0,jobUserID: baseInfoData.baseData.jobUserID,status:3}});
  617. }else if (curStepData.value.statusVal==3){
  618. await router.push({path: './edit', query: {reload:0,jobUserID: baseInfoData.baseData.jobUserID,status:4}});
  619. }
  620. }
  621. const onPathForward = (pathValue:string,educationIDValue:any,experienceIDValue:any,jobHuntIDValue:any,statusValue:any)=>{
  622. console.log("userid",baseInfoData.baseData.jobUserID);
  623. router.push({path: pathValue, query: {reload:1,educationID:educationIDValue,experienceID:experienceIDValue,jobHuntID:jobHuntIDValue,jobUserID: baseInfoData.baseData.jobUserID,status:statusValue}});
  624. }
  625. const onScroll = (e: any) => {
  626. setTimeout(() => {
  627. e.target.complete();
  628. if (pageParams.total > pageParams.pageIndex * pageParams.pageSize) {
  629. pageParams.pageSize += 5;
  630. loadData(pageParams.jobUserID,curStepData.value.statusVal);
  631. }
  632. }, 500);
  633. }
  634. const onFinish = () => {
  635. router.push("./list");
  636. }
  637. /*下拉字典查询*/
  638. const getSelectorDataList = async function(){
  639. const genderResult :any = await getSysDictionaryList("Gender");
  640. genderList.value = genderResult;
  641. const jobUserStatusResult :any = await getSysDictionaryList("JobStatus");
  642. jobUserStatusList.value = jobUserStatusResult;
  643. const keyPersonTypeResult :any = await getSysDictionaryList("KeyPersonType");
  644. keyPersonTypeList.value = keyPersonTypeResult;
  645. const cultureRankResult :any = await getSysDictionaryList("CultureLevel");
  646. cultureRankList.value = cultureRankResult;
  647. const userHealthResult :any = await getSysDictionaryList("Health");
  648. userHealthList.value = userHealthResult;
  649. const bloodTypeResult :any = await getSysDictionaryList("BloodType");
  650. bloodTypeList.value = bloodTypeResult;
  651. const maritalStatusResult :any = await getSysDictionaryList("MaritalStatus");
  652. maritalStatusList.value = maritalStatusResult;
  653. const politicsStatusResult :any = await getSysDictionaryList("PoliticsStatus");
  654. politicsStatusList.value = politicsStatusResult;
  655. const familyNatureResult :any = await getSysDictionaryList("FamilyNature");
  656. familyNatureList.value = familyNatureResult;
  657. const nationTypeListResult :any = await getSysDictionaryList("NationType");
  658. nationTypeList.value = nationTypeListResult;
  659. }
  660. const getSiteInfoList = async function(){
  661. const siteInfoResult :any = await getSiteDataList();
  662. siteInfoList.value = siteInfoResult;
  663. }
  664. const getRegionList = async function(){
  665. const regionResult: any = await getRegionCodeList();
  666. regionList.value = regionResult;
  667. }
  668. const getStreetList = async function(){
  669. if (baseInfoData.baseData.regionCode != null){
  670. const streetResult: any = await getStreetCodeList(baseInfoData.baseData.regionCode);
  671. streetList.value = streetResult;
  672. }
  673. }
  674. const regionChange = async function(){
  675. baseInfoData.baseData.streetCode = null;
  676. await getStreetList();
  677. }
  678. const provinceChange = async function(){
  679. baseInfoData.baseData.regionCode = null;
  680. await getRegionList();
  681. await regionChange();
  682. }
  683. const loadData = async (jobUserID: any,status:any) => {
  684. loading.value = true;
  685. pageParams.jobUserID = jobUserID;
  686. baseInfoData.baseData.jobUserID = jobUserID;
  687. curStepData.value.statusVal = status;
  688. console.log("当前jobUserID",jobUserID);
  689. if(curStepData.value.statusVal==1){
  690. const reqData = await getJobUserById(jobUserID);
  691. baseInfoData.baseData = reqData;
  692. console.log('baseData',baseInfoData.baseData);
  693. await getStreetList();
  694. }
  695. else if(curStepData.value.statusVal==2){
  696. const reqData :any = await getEducationListByJobUserID(pageParams);
  697. educationList.value = reqData.list;
  698. pageParams.total = reqData.total;
  699. console.log("educationList",educationList.value);
  700. }
  701. else if(curStepData.value.statusVal==3){
  702. const reqData = await getExperienceListByJobUserID(pageParams);
  703. experienceList.value= reqData.list;
  704. pageParams.total = reqData.total;
  705. console.log("experienceList",experienceList.value);
  706. }
  707. else if(curStepData.value.statusVal==4){
  708. const reqData = await getJobHuntListByJobUserID(pageParams);
  709. jobHuntList.value= reqData.list;
  710. pageParams.total = reqData.total;
  711. console.log("jobHuntList",jobHuntList.value);
  712. }
  713. loading.value = false;
  714. };
  715. watch(() => route.query, () => {
  716. if (route.query.reload) {
  717. loadData(route.query.jobUserID,route.query.status);
  718. }
  719. });
  720. const reload = (jobUserID:any,status:any) => {
  721. pageParams.pageIndex = 1;
  722. expand.value = false;
  723. loadData(jobUserID,status);
  724. }
  725. onIonViewDidEnter(() => {
  726. if (route.query.reload)
  727. reload(route.query.jobUserID,route.query.status);
  728. });
  729. return {
  730. ...toRefs(baseInfoData),
  731. chevronDownOutline,
  732. chevronUpOutline,
  733. arrowBackOutline,
  734. addCircleOutline,
  735. trashOutline,
  736. route,
  737. router,
  738. expand,
  739. loading,
  740. stepList,
  741. curStepData,
  742. baseDataValid,
  743. siteInfoList,
  744. genderList,
  745. nationTypeList,
  746. familyNatureList,
  747. politicsStatusList,
  748. pageParams,
  749. jobUserStatusList,
  750. keyPersonTypeList,
  751. cultureRankList,
  752. userHealthList,
  753. bloodTypeList,
  754. maritalStatusList,
  755. provinceList,
  756. regionList,
  757. streetList,
  758. educationList,
  759. experienceList,
  760. jobHuntList,
  761. delID,
  762. delAlertButtons,
  763. infoAlertButtons,
  764. delAlertOpen,
  765. infoAlertOpen,
  766. delLoading,
  767. infoAlterData,
  768. expandChange,
  769. provinceChange,
  770. regionChange,
  771. onSave,
  772. onBack,
  773. onFinish,
  774. onScroll,
  775. onPathForward,
  776. loadData,
  777. reload,
  778. setDelAlertOpen,
  779. setInfoAlertOpen,
  780. setDelLoadingOpen,
  781. getSiteInfoList,
  782. getSelectorDataList,
  783. getRegionList,
  784. getStreetList,
  785. dayjs
  786. }
  787. },
  788. mounted(){
  789. this.getSiteInfoList();
  790. this.getSelectorDataList();
  791. this.getRegionList();
  792. this.getStreetList();
  793. }
  794. });
  795. </script>
  796. <style lang="less">
  797. .custom{
  798. --placeholder-color: gray;
  799. --placeholder-opacity: 0.5;
  800. }
  801. .title-item{
  802. margin-left: 15px;
  803. color:#1c3d70 !important;
  804. font-size: 14px !important;
  805. font-weight: bold;
  806. }
  807. .next-btn {
  808. width: 80px;
  809. border-radius: 5px;
  810. background-color:#3a7be0;
  811. color: #363432;
  812. font-size: 14px;
  813. }
  814. .iconBtn{
  815. width:24px;
  816. height:24px;
  817. }
  818. .stepFlex {
  819. margin: 0;
  820. display: flex;
  821. width: 100%;
  822. .stepFlex-item {
  823. position: relative;
  824. flex: 1;
  825. text-align: center;
  826. margin-top: -10px;
  827. .stepFlex-item-label {
  828. padding-top: 60px;
  829. font-size: 14px;
  830. .stepFlex-item-label-title{
  831. margin-top:30px;
  832. }
  833. .stepFlex-item-label-desc{
  834. margin-top:5px;color: #b9b9bd;
  835. }
  836. }
  837. }
  838. .greenCircle {
  839. top: calc(50% - 15px);
  840. left: calc(50% - 4px);
  841. position: absolute;
  842. z-index: 2;
  843. width: 10px;
  844. height: 10px;
  845. border-radius: 50%;
  846. background-color: #31A2FE;
  847. }
  848. .now {
  849. top: calc(50% - 18px);
  850. left: calc(50% - 8px);
  851. position: absolute;
  852. z-index: 3;
  853. width: 16px;
  854. height: 16px;
  855. border-radius: 50%;
  856. background-color: #31A2FE;
  857. border: 4px solid #c5e8f9;
  858. }
  859. .grayCircle {
  860. top: calc(50% - 15px);
  861. left: calc(50% - 4px);
  862. position: absolute;
  863. z-index: 2;
  864. width: 10px;
  865. height: 10px;
  866. border-radius: 50%;
  867. background-color: #ccc;
  868. }
  869. .greenLine {
  870. width: 100%;
  871. top: calc(50% - 11px);
  872. left: calc(50% - 2px);
  873. height: 2px;
  874. background-color: #31A2FE;
  875. position: absolute;
  876. }
  877. .grayLine {
  878. height: 0;
  879. border: 1px dashed #ccc;
  880. width: 100%;
  881. top: calc(50% - 11px);
  882. left: calc(50% - 2px);
  883. position: absolute;
  884. }
  885. }
  886. </style>