edit.vue 43 KB

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