特易招,招聘小程序
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

533 lines
12 KiB

10 months ago
8 months ago
10 months ago
8 months ago
10 months ago
8 months ago
10 months ago
8 months ago
8 months ago
10 months ago
2 months ago
2 months ago
10 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
10 months ago
8 months ago
10 months ago
8 months ago
10 months ago
8 months ago
10 months ago
8 months ago
2 months ago
10 months ago
8 months ago
2 months ago
10 months ago
2 months ago
2 months ago
10 months ago
8 months ago
10 months ago
8 months ago
10 months ago
8 months ago
8 months ago
10 months ago
8 months ago
2 months ago
10 months ago
8 months ago
8 months ago
10 months ago
8 months ago
10 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
10 months ago
8 months ago
10 months ago
8 months ago
8 months ago
2 months ago
10 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
10 months ago
8 months ago
8 months ago
2 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
2 months ago
8 months ago
8 months ago
8 months ago
2 months ago
2 months ago
2 months ago
2 months ago
8 months ago
10 months ago
2 months ago
10 months ago
2 months ago
2 months ago
10 months ago
8 months ago
8 months ago
8 months ago
10 months ago
  1. <template>
  2. <view class="page">
  3. <navbar title="在线简历"
  4. leftClick
  5. @leftClick="$utils.navigateBack"/>
  6. <view class="box">
  7. <view class="list">
  8. <view class="item"
  9. v-for="(item, index) in list"
  10. :key="index">
  11. <view class="title">
  12. {{ item.title }}
  13. </view>
  14. <!-- 工种选择器模式 -->
  15. <view class="job-type-selector" v-if="item.useJobTypePicker" @click="openJobTypePicker">
  16. <view class="selected-job-type">
  17. {{ selectedJobType || form.typeId_dictText || '请选择工种' }}
  18. </view>
  19. <uv-icon name="arrow-right" size="30rpx"></uv-icon>
  20. </view>
  21. <view class="tagList" v-else-if="!item.useAddressPicker">
  22. <view :class="{act : i == item.index}"
  23. @click="clickTag(item, i)" v-for="(t, i) in item.tag"
  24. :key="t.id">
  25. {{ t.name || t.adress }}
  26. </view>
  27. </view>
  28. <!-- 地址选择器模式 -->
  29. <view class="address-selector" v-else @click="openAddressPicker">
  30. <view class="selected-address">
  31. {{ selectedAddress || form.expectAddress_dictText || '请选择工作地区' }}
  32. </view>
  33. <uv-icon name="arrow-right" size="30rpx"></uv-icon>
  34. </view>
  35. </view>
  36. </view>
  37. <view class="form-sheet-cell">
  38. <view class="label">
  39. 求职岗位
  40. </view>
  41. <input placeholder="请输入求职岗位"
  42. v-model="form.title" />
  43. </view>
  44. <view class="form-sheet-cell">
  45. <view class="label">
  46. 您的年龄
  47. </view>
  48. <input placeholder="请输入年龄"
  49. type="number"
  50. v-model="form.age" />
  51. </view>
  52. <view class="form-sheet-cell">
  53. <view class="label">
  54. 您的工龄
  55. </view>
  56. <input placeholder="请输入年龄"
  57. type="number"
  58. v-model="form.workTime" />
  59. </view>
  60. <view class="form-sheet-cell">
  61. <view class="label">
  62. 您的性别
  63. </view>
  64. <uv-radio-group v-model="form.sex">
  65. <view style="display: flex;justify-content: center;">
  66. <uv-radio
  67. :customStyle="{margin: '8px'}"
  68. v-for="(item, index) in sexList"
  69. :key="index"
  70. iconSize="30rpx"
  71. size="40rpx"
  72. labelSize="26rpx"
  73. :label="item.name"
  74. :name="item.name">
  75. </uv-radio>
  76. </view>
  77. </uv-radio-group>
  78. </view>
  79. <view class="form-sheet-cell">
  80. <view class="label">
  81. 您的民族
  82. </view>
  83. <input placeholder="请输入民族"
  84. v-model="form.nation" />
  85. </view>
  86. <view class="form-sheet-cell">
  87. <view class="label">
  88. 期望薪资
  89. </view>
  90. <view class="price">
  91. <input placeholder="下限" v-model="form.salaryLow" />
  92. ~
  93. <input placeholder="上限" v-model="form.salaryUp" />
  94. </view>
  95. </view>
  96. <view class="form-sheet-cell"
  97. @click="openPicker('qualification')">
  98. <view class="label">
  99. 您的学历
  100. </view>
  101. <input placeholder="请选择学历"
  102. disabled
  103. v-model="form.qualification" />
  104. </view>
  105. <!-- <view class="form-sheet-cell">
  106. <view class="label">
  107. 您的学历
  108. </view>
  109. <input placeholder="请输入您的学历"
  110. v-model="form.qualification" />
  111. </view> -->
  112. <uv-textarea
  113. v-model="form.brief"
  114. count
  115. :maxlength="300"
  116. autoHeight
  117. placeholder="请输入个人介绍"></uv-textarea>
  118. <view class="uni-color-btn"
  119. @click="submit">
  120. 发布
  121. </view>
  122. </view>
  123. <uv-picker ref="picker"
  124. :columns="columns"
  125. @confirm="pickerConfirm"></uv-picker>
  126. <!-- 地址选择组件 -->
  127. <AddressPicker ref="addressPicker" :multiple="true" :showSelectWholeCity="true" :onlyCity="false" @confirm="onAddressConfirm" />
  128. <!-- 工种选择组件 -->
  129. <JobTypePicker ref="jobTypePicker" @confirm="onJobTypeConfirm" />
  130. </view>
  131. </template>
  132. <script>
  133. import { mapState } from 'vuex'
  134. import AddressPicker from '@/components/AddressPicker.vue'
  135. import JobTypePicker from '@/components/JobTypePicker.vue'
  136. export default {
  137. components: {
  138. AddressPicker,
  139. JobTypePicker
  140. },
  141. data() {
  142. return {
  143. list: [
  144. {
  145. title: '您希望从事的工种',
  146. tag: [],
  147. index: 0,
  148. type : 'typeId',
  149. useJobTypePicker: true, // 标记使用工种选择器
  150. },
  151. {
  152. title: '您希望从事工作的地区',
  153. tag: [],
  154. index: 0,
  155. type : 'expectAddress',
  156. useAddressPicker: true, // 标记使用地址选择器
  157. },
  158. {
  159. title: '您希望从事工作的性质',
  160. tag: [],
  161. index: 0,
  162. type : 'natureId',
  163. },
  164. ],
  165. form : {
  166. sex : '男',
  167. qulification : '',
  168. title: '',
  169. typeId : '',
  170. expectAddress : '',
  171. natureId : '',
  172. age : '',
  173. nation : '',
  174. salaryLow : '',
  175. salaryUp : '',
  176. qualification : '',
  177. brief: '',
  178. },
  179. sexList : [
  180. {
  181. name : '男',
  182. },
  183. {
  184. name : '女',
  185. },
  186. ],
  187. picker : {
  188. qualification : [
  189. '初中',
  190. '高中',
  191. '专科',
  192. '本科',
  193. '研究生',
  194. '博士',
  195. ],
  196. },
  197. pickerKey : 'workAge',
  198. selectedAddress: '', // 选中的地址文本
  199. selectedJobType: '', // 选中的工种文本
  200. }
  201. },
  202. computed : {
  203. ...mapState(['natureList', 'jobTypeList', 'addressList']),
  204. columns(){
  205. return [this.picker[this.pickerKey]]
  206. },
  207. },
  208. onLoad() {
  209. this.list[0].tag = this.jobTypeList
  210. this.list[1].tag = this.addressList
  211. this.list[2].tag = this.natureList
  212. this.queryResumeByUserId()
  213. },
  214. methods: {
  215. clickTag(item, index){
  216. item.index = index
  217. },
  218. openPicker(key, picker){
  219. this.pickerKey = key
  220. if(picker){
  221. picker.open()
  222. }else{
  223. this.$refs.picker.open()
  224. }
  225. },
  226. pickerConfirm(e){
  227. console.log(e);
  228. let data = e.value[0]
  229. if(data && data.id){
  230. this.form[this.pickerKey] = data.id
  231. this.form[this.pickerKey + '_dictText'] = data.name || data.adress
  232. }else{
  233. this.form[this.pickerKey] = data
  234. }
  235. },
  236. // 提交
  237. submit(){
  238. // if(this.fileList.length == 0){
  239. // return uni.showToast({
  240. // title: '请上传图片',
  241. // icon : 'none'
  242. // })
  243. // }
  244. this.list.forEach(n => {
  245. // 如果使用地址选择器或工种选择器,跳过从tag获取值
  246. if(!n.useAddressPicker && !n.useJobTypePicker) {
  247. this.form[n.type] = n.tag[n.index].id
  248. }
  249. })
  250. if (this.$utils.verificationAll(this.form, {
  251. title: '请输入求职岗位',
  252. typeId : '请选择工种',
  253. expectAddress : '请选择工作的地区',
  254. natureId : '请选择工作的性质',
  255. age : '请输入您的年龄',
  256. workTime : '请输入您的工龄',
  257. sex : '请选择性别',
  258. nation : '请输入您的民族',
  259. salaryLow : '请输入期望薪资下限',
  260. salaryUp : '请输入期望薪资上限',
  261. qualification : '请选择您的学历',
  262. brief: '请输入个人介绍',
  263. })) {
  264. return
  265. }
  266. let data = {
  267. title: this.form.title,
  268. typeId : this.form.typeId,
  269. expectAddress : this.form.expectAddress,
  270. natureId : this.form.natureId,
  271. age : this.form.age,
  272. workTime : this.form.workTime,
  273. nation : this.form.nation,
  274. salaryLow : this.form.salaryLow,
  275. salaryUp : this.form.salaryUp,
  276. qualification : this.form.qualification,
  277. brief: this.form.brief,
  278. sex: this.form.sex,
  279. }
  280. if(this.form.id){
  281. data.id = this.form.id
  282. }
  283. this.$api('addResume', data, res => {
  284. if(res.code == 200){
  285. uni.showToast({
  286. title: '保存成功!',
  287. icon: 'none'
  288. })
  289. setTimeout(uni.navigateBack, 1000, -1)
  290. }
  291. })
  292. },
  293. queryResumeByUserId(){
  294. this.$api('queryResumeByUserId', res => {
  295. if(res.code == 200 && res.result && res.result.records[0]){
  296. this.form = res.result.records[0]
  297. this.list.forEach((n, i) => {
  298. // 如果是地址选择器,需要根据ID找到对应的地址文本
  299. if(n.useAddressPicker && this.form[n.type]) {
  300. // 回显地址:根据存储的ID找到对应的地址文本
  301. this.selectedAddress = this.getAddressTextById(this.form[n.type])
  302. } else if(n.useJobTypePicker && this.form[n.type]) {
  303. // 回显工种:根据存储的ID找到对应的工种文本
  304. this.selectedJobType = this.getJobTypeTextById(this.form[n.type])
  305. } else {
  306. n.tag.forEach((e, index) => {
  307. if(this.form[n.type] == e.id){
  308. n.index = index
  309. }
  310. })
  311. }
  312. })
  313. }
  314. })
  315. },
  316. // 打开地址选择器
  317. openAddressPicker() {
  318. this.$refs.addressPicker.open()
  319. },
  320. // 根据ID获取地址文本(用于回显)
  321. getAddressTextById(idOrIds) {
  322. if (!idOrIds) return ''
  323. // 如果是多个ID(逗号分隔)
  324. if (typeof idOrIds === 'string' && idOrIds.includes(',')) {
  325. const ids = idOrIds.split(',')
  326. const addressTexts = []
  327. ids.forEach(id => {
  328. const address = this.findAddressById(id.trim())
  329. if (address) {
  330. addressTexts.push(address.adress)
  331. }
  332. })
  333. return addressTexts.join(',')
  334. } else {
  335. // 单个ID
  336. const address = this.findAddressById(idOrIds)
  337. return address ? address.adress : ''
  338. }
  339. },
  340. // 递归查找地址
  341. findAddressById(id) {
  342. // 在省级地址中查找
  343. for (let province of this.addressList) {
  344. if (province.id == id) {
  345. return province
  346. }
  347. }
  348. // 如果没找到,需要异步获取下级地址进行查找
  349. // 这里简化处理,实际项目中可能需要更复杂的缓存机制
  350. return null
  351. },
  352. // 地址选择确认回调
  353. onAddressConfirm(addressResult) {
  354. // 显示地址文本给用户看
  355. this.selectedAddress = addressResult.fullAddress
  356. // 传给后端的是ID或ID数组
  357. if (addressResult.selectedIds && addressResult.selectedIds.length > 0) {
  358. // 多选模式,传ID数组的字符串形式
  359. this.form.expectAddress = addressResult.selectedIds.join(',')
  360. } else {
  361. // 单选模式,传单个ID
  362. this.form.expectAddress = addressResult.selectedId
  363. }
  364. },
  365. // 打开工种选择器
  366. openJobTypePicker() {
  367. this.$refs.jobTypePicker.open()
  368. },
  369. // 工种选择确认回调
  370. onJobTypeConfirm(jobTypeResult) {
  371. // 显示工种文本给用户看
  372. this.selectedJobType = jobTypeResult.selectedJobType.name
  373. // 传给后端的是ID
  374. this.form.typeId = jobTypeResult.selectedId
  375. this.form.typeId_dictText = jobTypeResult.selectedJobType.name
  376. },
  377. // 根据ID获取工种文本(用于回显)
  378. getJobTypeTextById(id) {
  379. if (!id) return ''
  380. // 在一级工种中查找
  381. for (let jobType of this.jobTypeList) {
  382. if (jobType.id == id) {
  383. return jobType.name
  384. }
  385. }
  386. // 如果没找到,返回空字符串
  387. // 实际项目中可能需要异步获取下级工种进行查找
  388. return ''
  389. },
  390. },
  391. }
  392. </script>
  393. <style scoped lang="scss">
  394. .page{
  395. background-color: #fff;
  396. min-height: 100vh;
  397. .box{
  398. padding: 30rpx;
  399. .list {
  400. .item {
  401. margin-top: 20rpx;
  402. .title {
  403. font-weight: 900;
  404. font-size: 30rpx;
  405. }
  406. .tagList {
  407. display: flex;
  408. flex-wrap: wrap;
  409. padding: 10rpx 0;
  410. view {
  411. background: rgba($uni-color, 0.1);
  412. padding: 10rpx 20rpx;
  413. margin: 10rpx;
  414. border-radius: 10rpx;
  415. font-size: 26rpx;
  416. }
  417. .act {
  418. color: #fff;
  419. background: $uni-color;
  420. }
  421. }
  422. .address-selector {
  423. display: flex;
  424. justify-content: space-between;
  425. align-items: center;
  426. background: rgba($uni-color, 0.1);
  427. padding: 20rpx;
  428. margin: 10rpx;
  429. border-radius: 10rpx;
  430. font-size: 26rpx;
  431. .selected-address {
  432. flex: 1;
  433. color: #333;
  434. }
  435. }
  436. .job-type-selector {
  437. display: flex;
  438. justify-content: space-between;
  439. align-items: center;
  440. background: rgba($uni-color, 0.1);
  441. padding: 20rpx;
  442. margin: 10rpx;
  443. border-radius: 10rpx;
  444. font-size: 26rpx;
  445. .selected-job-type {
  446. flex: 1;
  447. color: #333;
  448. }
  449. }
  450. }
  451. }
  452. .form-sheet-cell{
  453. display: flex;
  454. background-color: #fff;
  455. padding: 20rpx;
  456. align-items: center;
  457. .label{
  458. width: 160rpx;
  459. font-weight: 900;
  460. }
  461. .price{
  462. display: flex;
  463. text-align: center;
  464. input{
  465. width: 150rpx;
  466. border: 1px solid $uni-color;
  467. margin: 0 10rpx;
  468. }
  469. }
  470. input{
  471. flex: 1;
  472. background-color: rgba($uni-color, 0.1);
  473. padding: 10rpx 20rpx;
  474. border-radius: 10rpx;
  475. }
  476. .right-icon{
  477. margin-left: auto;
  478. }
  479. }
  480. /deep/ .uv-textarea{
  481. background-color: rgba($uni-color, 0.1) !important;
  482. min-height: 400rpx;
  483. }
  484. }
  485. }
  486. </style>