workExperience.vue 26 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042
  1. <template>
  2. <view class="work-experience">
  3. <!-- 自定义导航栏 -->
  4. <view class="custom-navbar" :style="{ paddingTop: (12 + statusBarHeight) + 'px' }">
  5. <view class="navbar-content">
  6. <view class="nav-left" @click="goBack">
  7. <u-icon name="arrow-leftward" color="#333" size="42"></u-icon>
  8. </view>
  9. <view class="nav-title">工作经历</view>
  10. <view class="nav-right"></view>
  11. </view>
  12. </view>
  13. <!-- 主要内容 -->
  14. <view class="main-content">
  15. <!-- 公司信息 -->
  16. <view class="form-section">
  17. <!-- 公司名称 -->
  18. <view class="form-item">
  19. <view class="form-label">公司名称</view>
  20. <view class="form-input">
  21. <input v-model="formData.companyName" placeholder="请填写公司名称" maxlength="50" />
  22. <u-icon v-if="formData.companyName" name="close-circle-fill" color="#C9CDD4" size="28"
  23. @click="formData.companyName = ''" class="clear-icon"></u-icon>
  24. </view>
  25. </view>
  26. <!-- 公司业务类型 -->
  27. <view class="form-item">
  28. <view class="form-label" style="margin-bottom: 20rpx;">
  29. <text class="required-mark">*</text>
  30. <text class="label-text">公司业务类型</text>
  31. </view>
  32. <view class="checkbox-container">
  33. <u-checkbox-group @change="checkboxGroupChange" :wrap="false" shape="square"
  34. active-color="#007AFF">
  35. <u-checkbox v-for="(option, index) in businessTypeOptions" :key="index" :name="option.value"
  36. v-model="option.checked" class="checkbox-item">
  37. {{ option.label }}
  38. </u-checkbox>
  39. </u-checkbox-group>
  40. </view>
  41. </view>
  42. </view>
  43. <!-- 岗位履历 -->
  44. <view class="form-section" v-for="(resume, index) in formData.resumes" :key="index">
  45. <!-- <view class="section-title" v-if="hasCrossBorderExperience"><text>岗位履历 ({{ index + 1 }})</text> -->
  46. <view class="section-title"><text>岗位履历 ({{ index + 1 }})</text>
  47. <image src="@/static/images/index/delete.svg" style="width: 40rpx;height: 40rpx;"
  48. @click="deleteResume(index)" v-if="formData.resumes && formData.resumes.length > 1" />
  49. </view>
  50. <!-- 任职时间 -->
  51. <view class="form-item">
  52. <view class="form-label">
  53. <text class="required-mark">*</text>
  54. <text class="label-text">{{ hasCrossBorderExperience ? '任职时间' : '在职时间' }}</text>
  55. </view>
  56. <view class="form-input time-range">
  57. <view class="time-input">
  58. <uni-datetime-picker v-model="resume.employmentTime[0]" type="date"
  59. :border="false" placeholder="开始时间" />
  60. <!-- <image src="../../static/images/index/Iconly_Light_Calendar.svg"
  61. style="width: 48rpx; height: 48rpx;" mode="aspectFit"></image> -->
  62. </view>
  63. <view class="time-separator">至</view>
  64. <view class="time-input">
  65. <uni-datetime-picker v-model="resume.employmentTime[1]" type="date"
  66. :border="false" placeholder="结束时间" />
  67. <image src="../../static/images/index/Iconly_Light_Calendar.svg"
  68. style="width: 48rpx; height: 48rpx;" mode="aspectFit"></image>
  69. </view>
  70. </view>
  71. </view>
  72. <!-- 所在部门 -->
  73. <view class="form-item">
  74. <view class="form-label">
  75. <text class="required-mark">*</text>
  76. <text class="label-text">所在部门</text>
  77. </view>
  78. <view class="form-input">
  79. <picker class="picker" :data-index="index" mode="selector" :range="departments"
  80. @change="selectDepartment">
  81. <text>{{ departments.length > 0 ? departments[resume.departmentIndex] : '请选择部门' }}</text>
  82. </picker>
  83. <u-icon name="arrow-down" color="#999" size="36"></u-icon>
  84. </view>
  85. </view>
  86. <!-- 岗位 -->
  87. <view class="form-item">
  88. <view class="form-label">
  89. <text class="required-mark">*</text>
  90. <text class="label-text">岗位</text>
  91. </view>
  92. <view class="form-input" @click="selectPosition(index)">
  93. <text v-if="resume.position">{{ resume.position }}</text>
  94. <text v-else class="placeholder">请选择岗位</text>
  95. <u-icon name="arrow-right" color="#999" size="36"></u-icon>
  96. </view>
  97. </view>
  98. <!-- 岗位职级 -->
  99. <view class="form-item">
  100. <view class="form-label">岗位职级</view>
  101. <view class="form-input">
  102. <picker class="picker" :data-index="index" mode="selector" :range="positionLevels"
  103. @change="selectPositionLevel">
  104. <text>{{ resume.positionLevel || '请选择' }}</text>
  105. </picker>
  106. <u-icon name="arrow-down" color="#999" size="36"></u-icon>
  107. </view>
  108. </view>
  109. <!-- 岗位职业技能 -->
  110. <view class="form-item">
  111. <view class="form-label">
  112. <text class="required-mark">*</text>
  113. <text class="label-text">跨境职业技能</text>
  114. </view>
  115. <view class="skills-input-container">
  116. <view class="skills-tags">
  117. <view v-for="(skill, skillIndex) in resume.skills" :key="skillIndex" class="skill-tag">
  118. <text>{{ skill }}</text>
  119. <u-icon name="close" color="#999" size="16"
  120. @click="removeSkill(index, skillIndex)"></u-icon>
  121. </view>
  122. </view>
  123. <view class="add-skill-btn" @click="addSkill(index)">
  124. <u-icon name="plus" color="rgba(102, 102, 102, 1)" size="28"></u-icon>
  125. </view>
  126. </view>
  127. </view>
  128. <!-- 工作内容 -->
  129. <view class="form-item">
  130. <view class="form-label">
  131. 工作内容
  132. <text class="word-count">{{ resume.workContent && resume.workContent.length || 0 }}/1000</text>
  133. </view>
  134. <view class="form-input">
  135. <textarea v-model="resume.workContent" placeholder="选填,请输入" maxlength="1000" auto-height
  136. @input="handleTextareaInput($event, 'workContent', index)" class="form-textarea"></textarea>
  137. <view class="textarea-clear" v-if="resume.workContent"
  138. @click="clearTextarea('workContent', index)">
  139. <u-icon name="close-circle-fill" color="#C9CDD4" size="28"></u-icon>
  140. </view>
  141. </view>
  142. </view>
  143. <!-- 工作业绩 -->
  144. <view class="form-item">
  145. <view class="form-label">
  146. 工作业绩
  147. <text class="word-count">{{ resume.workPerformance && resume.workPerformance.length || 0 }}/1000</text>
  148. </view>
  149. <view class="form-input">
  150. <textarea v-model="resume.workPerformance" placeholder="选填,请输入" maxlength="1000" auto-height
  151. @input="handleTextareaInput($event, 'workPerformance', index)"
  152. class="form-textarea"></textarea>
  153. <view class="textarea-clear" v-if="resume.workPerformance"
  154. @click="clearTextarea('workPerformance', index)">
  155. <u-icon name="close-circle-fill" color="#C9CDD4" size="28"></u-icon>
  156. </view>
  157. </view>
  158. </view>
  159. <!-- 添加岗位履历按钮 -->
  160. <view class="add-resume-btn" @click="addResume"
  161. v-if="index === formData.resumes.length - 1">
  162. <text>添加岗位履历</text>
  163. </view>
  164. </view>
  165. <!-- 底部保存按钮 -->
  166. <view class="bottom-btn-container">
  167. <view class="save-btn" @click="saveWorkExperience">
  168. <text>保存</text>
  169. </view>
  170. </view>
  171. </view>
  172. <!-- 添加技能弹窗 -->
  173. <u-popup v-model="showAddSkill" mode="center" border-radius="24" width="80%">
  174. <view class="add-skill-popup">
  175. <view class="popup-title">添加技能</view>
  176. <view class="popup-content">
  177. <input v-model="newSkillName" placeholder="请输入技能名称" class="skill-input" maxlength="10" />
  178. </view>
  179. <view class="popup-buttons">
  180. <view class="popup-btn cancel-btn" @click="cancelAddSkill">取消</view>
  181. <view class="popup-btn confirm-btn" @click="confirmAddSkill">确定</view>
  182. </view>
  183. </view>
  184. </u-popup>
  185. <!-- 清除确认弹窗 -->
  186. <u-modal v-model="showClearConfirm" :content="'确定要清除所有填写的内容吗?'" show-cancel-button confirm-text="确定清除"
  187. cancel-text="取消" @confirm="clearAllContent" confirm-color="#FF4444"></u-modal>
  188. </view>
  189. </template>
  190. <script>
  191. var id = '';
  192. export default {
  193. data() {
  194. return {
  195. statusBarHeight: 0, // 状态栏高度
  196. showAddSkill: false,
  197. newSkillName: '',
  198. currentResumeIndex: 0,
  199. showClearConfirm: false, // 清除确认弹窗
  200. businessTypeOptions: [{
  201. label: '跨境电商',
  202. value: '0',
  203. checked: false
  204. },
  205. {
  206. label: '国内电商',
  207. value: '1',
  208. checked: false
  209. },
  210. {
  211. label: '外贸',
  212. value: '2',
  213. checked: false
  214. },
  215. {
  216. label: '其他',
  217. value: '3',
  218. checked: false
  219. }
  220. ],
  221. formData: {
  222. companyName: '',
  223. businessTypes: [],
  224. resumes: [{
  225. workExpDetailId: "",
  226. workExpId: "",
  227. employmentTime: [],
  228. department: '',
  229. departmentId: 0,
  230. departmentIndex: 0,
  231. position: '',
  232. positionId: 0,
  233. positionLevel: '初级',
  234. skills: [],
  235. workContent: '',
  236. workPerformance: ''
  237. }]
  238. },
  239. departments: [],
  240. departmentsIds: [],
  241. positionLevels: ['初级', '中级','高级','资深','其它'],
  242. operateKey: 0,
  243. isWork: false
  244. }
  245. },
  246. onLoad(options) {
  247. // 获取状态栏高度
  248. let systemInfo = uni.getSystemInfoSync();
  249. this.statusBarHeight = systemInfo.statusBarHeight || 0;
  250. // 接收从在线简历页面传递的业务类型参数
  251. if (options.businessTypes) {
  252. try {
  253. const businessTypes = JSON.parse(decodeURIComponent(options.businessTypes))
  254. this.formData.businessTypes = businessTypes
  255. console.log('接收到的业务类型:', businessTypes)
  256. // console.log('是否有跨境经验:', this.hasCrossBorderExperience)
  257. // if (this.hasCrossBorderExperience)
  258. // this.businessTypeOptions[0].checked = true
  259. } catch (e) {
  260. console.error('解析业务类型参数失败:', e)
  261. }
  262. }
  263. this.getDepartment()
  264. id = options && options.id ? options.id : ''
  265. // 监听技能设置更新
  266. uni.$on('jobs', (data) => {
  267. console.log('岗位设置已更新:', data)
  268. // 这里可以更新对应的技能显示
  269. this.formData.resumes[this.operateKey].position = data.ruleClassifyName
  270. this.formData.resumes[this.operateKey].positionId = data.ruleClassifyId;
  271. // 更新以后给岗位职业技能设置默认值
  272. this.getDataInfo(this.formData.resumes[this.operateKey].positionId);
  273. })
  274. uni.$on('skillsUpdated', (data) => {
  275. console.log('技能设置已更新:', data)
  276. // 这里可以更新对应的技能显示
  277. this.formData.resumes[this.operateKey].skills = data.selectedTags
  278. })
  279. },
  280. beforeDestroy() {
  281. // 移除事件监听
  282. uni.$off('jobs')
  283. uni.$off('skillsUpdated')
  284. },
  285. computed: {
  286. hasCrossBorderExperience() {
  287. return this.formData.businessTypes.includes('0')
  288. },
  289. hasContentToClear() {
  290. // 检查是否有内容可以清除
  291. return this.formData.companyName ||
  292. this.formData.businessTypes.length > 0 ||
  293. this.formData.resumes.some(resume =>
  294. resume.position ||
  295. resume.workContent ||
  296. resume.workPerformance ||
  297. resume.skills.length > 0
  298. )
  299. }
  300. },
  301. methods: {
  302. getDataInfo(jobId) {
  303. let data = {
  304. ruleClassifyId: jobId
  305. }
  306. this.$Request.getT('/app/userFirst/getPostSkill', data).then(res => {
  307. if (res.code == 0) {
  308. if (res.data.length > 0 && res.data[0]?.childrenList[0]?.postSkillName)
  309. this.formData.resumes[this.operateKey].skills = []
  310. this.formData.resumes[this.operateKey].skills.push(res.data[0]?.childrenList[0]?.postSkillName)
  311. }
  312. })
  313. },
  314. goBack() {
  315. uni.navigateBack()
  316. },
  317. getDepartment() {
  318. var that = this
  319. this.$Request.postJson("/app/userFirst/getDepartment", {}).then((res) => {
  320. if (res.code == 0) {
  321. that.departments = that.$queue.array_column(res.data, 'departmentName')
  322. that.departmentsIds = that.$queue.array_column(res.data, 'departmentId')
  323. that.formData.resumes.forEach(function (item) {
  324. item.departmentId = that.departmentsIds[item.departmentIndex]
  325. item.department = that.departments[item.departmentIndex]
  326. })
  327. if (id != '' && id != 0)
  328. that.getData()
  329. } else {
  330. uni.showToast({
  331. title: res.msg,
  332. icon: "none",
  333. });
  334. }
  335. });
  336. },
  337. getData() {
  338. var that = this
  339. this.$Request.getT("/app/userFirst/getWorkExpDetailOne", {
  340. workExpId: id
  341. }).then((res) => {
  342. if (res.code == 0) {
  343. res = res.data
  344. that.formData.companyName = res.workExp.companyName
  345. that.formData.businessTypes = JSON.parse(res.workExp.type)
  346. // 设置公司业务类型回显
  347. if (this.formData.businessTypes.length) {
  348. for (let i = 0; i < this.formData.businessTypes.length; i++) {
  349. for (let opt = 0; i < this.businessTypeOptions.length; opt++) {
  350. const option = this.businessTypeOptions[opt]
  351. if (this.formData.businessTypes[i] == option.value) {
  352. this.businessTypeOptions[opt].checked = true
  353. break
  354. }
  355. }
  356. }
  357. }
  358. console.log(that.formData.businessTypes)
  359. res.workExpDetails.forEach(function (item) {
  360. item.skills = JSON.parse(item.skills)
  361. item.employmentTime = item.startTime == '' ? [] : [item.startTime, item
  362. .endTime],
  363. item.departmentIndex = that.departmentsIds.indexOf(item.departmentId) < 0 ?
  364. 0 : that.departmentsIds.indexOf(item.departmentId)
  365. })
  366. that.formData.resumes = res.workExpDetails
  367. } else {
  368. uni.showToast({
  369. title: res.msg,
  370. icon: "none",
  371. });
  372. }
  373. });
  374. },
  375. selectDepartment(e) {
  376. var key = Number(e.currentTarget.dataset.index)
  377. this.formData.resumes[key].departmentId = this.departmentsIds[e.detail.value]
  378. this.formData.resumes[key].departmentIndex = e.detail.value
  379. this.formData.resumes[key].department = this.departments[e.detail.value]
  380. },
  381. formatter(type, value) {
  382. if (type === 'year') {
  383. return `${value}年`
  384. }
  385. if (type === 'month') {
  386. return `${value}月`
  387. }
  388. if (type === 'day') {
  389. return `${value}日`
  390. }
  391. return value
  392. },
  393. checkboxGroupChange(e) {
  394. console.log('选中的业务类型:', e)
  395. // 更新 formData.businessTypes 以保持数据同步
  396. this.formData.businessTypes = e
  397. },
  398. selectEmploymentTime(index) {
  399. // 选择任职时间
  400. uni.showToast({
  401. title: '选择任职时间',
  402. icon: 'none'
  403. })
  404. },
  405. selectPosition(index) {
  406. this.operateKey = index
  407. // 选择岗位
  408. uni.navigateTo({
  409. url: '/package/jobIntention/jobList'
  410. })
  411. },
  412. selectPositionLevel(e) {
  413. var key = Number(e.currentTarget.dataset.index)
  414. this.formData.resumes[key].positionLevel = this.positionLevels[e.detail.value]
  415. },
  416. addSkill(index) {
  417. this.operateKey = index
  418. //this.currentResumeIndex = index
  419. //this.showAddSkill = true
  420. //this.newSkillName = ''
  421. if (this.formData.resumes[index].positionId == '' || this.formData.resumes[index].positionId == 0)
  422. return this.$queue.showToast('请先选择岗位')
  423. uni.navigateTo({
  424. url: '/package/jobIntention/jobSkills?jobId=' + this.formData.resumes[index].positionId +
  425. '&jobTitle=' + this.formData.resumes[index].position + '&skill=' + encodeURIComponent(JSON
  426. .stringify(this.formData.resumes[index].skills))
  427. })
  428. },
  429. removeSkill(resumeIndex, skillIndex) {
  430. this.formData.resumes[resumeIndex].skills.splice(skillIndex, 1)
  431. },
  432. cancelAddSkill() {
  433. this.showAddSkill = false
  434. this.newSkillName = ''
  435. },
  436. confirmAddSkill() {
  437. if (this.newSkillName.trim()) {
  438. this.formData.resumes[this.currentResumeIndex].skills.push(this.newSkillName.trim())
  439. this.showAddSkill = false
  440. this.newSkillName = ''
  441. } else {
  442. uni.showToast({
  443. title: '请输入技能名称',
  444. icon: 'none'
  445. })
  446. }
  447. },
  448. selectWorkContent(index) {
  449. // 选择工作内容
  450. uni.showToast({
  451. title: '选择工作内容',
  452. icon: 'none'
  453. })
  454. },
  455. selectWorkPerformance(index) {
  456. // 选择工作业绩
  457. uni.showToast({
  458. title: '选择工作业绩',
  459. icon: 'none'
  460. })
  461. },
  462. addResume() {
  463. this.formData.resumes.push({
  464. workExpDetailId: "",
  465. workExpId: "",
  466. employmentTime: [],
  467. department: this.departments[0],
  468. departmentId: this.departmentsIds[0],
  469. departmentIndex: 0,
  470. position: '',
  471. positionId: 0,
  472. positionLevel: '初级',
  473. skills: [],
  474. workContent: '',
  475. workPerformance: ''
  476. })
  477. },
  478. deleteResume(index) {
  479. this.formData.resumes.splice(index, 1)
  480. },
  481. // 处理文本域输入
  482. handleTextareaInput(e, field, index) {
  483. const value = e.detail.value;
  484. // 如果超过1000字,截断
  485. if (value.length > 1000) {
  486. this.formData.resumes[index][field] = value.substring(0, 1000);
  487. }
  488. },
  489. // 清除单个文本域
  490. clearTextarea(field, index) {
  491. this.formData.resumes[index][field] = '';
  492. },
  493. // 显示清除确认弹窗
  494. showClearAllConfirm() {
  495. this.showClearConfirm = true;
  496. },
  497. // 清除所有内容
  498. clearAllContent() {
  499. // 清空公司名称
  500. this.formData.companyName = '';
  501. // 清空业务类型选择
  502. this.formData.businessTypes = [];
  503. this.businessTypeOptions.forEach(option => {
  504. option.checked = false;
  505. });
  506. // 清空所有履历
  507. this.formData.resumes = [{
  508. workExpDetailId: "",
  509. workExpId: "",
  510. employmentTime: [],
  511. department: this.departments.length > 0 ? this.departments[0] : '',
  512. departmentId: this.departmentsIds.length > 0 ? this.departmentsIds[0] : 0,
  513. departmentIndex: 0,
  514. position: '',
  515. positionId: 0,
  516. positionLevel: '初级',
  517. skills: [],
  518. workContent: '',
  519. workPerformance: ''
  520. }];
  521. this.showClearConfirm = false;
  522. uni.showToast({
  523. title: '已清除所有内容',
  524. icon: 'success'
  525. });
  526. },
  527. saveWorkExperience() {
  528. console.log(this.formData.resumes)
  529. if (!this.formData.companyName) {
  530. uni.showToast({
  531. title: "请输入公司名称",
  532. icon: "none"
  533. });
  534. return;
  535. }
  536. if (this.formData.businessTypes.length <= 0) {
  537. uni.showToast({
  538. title: "请选择公司业务类型",
  539. icon: "none"
  540. });
  541. return;
  542. }
  543. if (this.formData.resumes.length <= 0) {
  544. uni.showToast({
  545. title: "请至少填写一份履历",
  546. icon: "none"
  547. });
  548. return;
  549. }
  550. for (let i = 0; i < this.formData.resumes.length; i++) {
  551. const item = this.formData.resumes[i];
  552. const timeArr = item.employmentTime.filter(time => {
  553. if (time) {
  554. return time
  555. }
  556. });
  557. if (timeArr.length <= 0) {
  558. this.$queue.showToast('任职时间不能为空')
  559. return false;
  560. }
  561. if (timeArr.length < 2) {
  562. this.$queue.showToast('请选择完整的任职时间')
  563. return false;
  564. }
  565. // 判断开始时间是否大于结束时间
  566. let startTime = ''
  567. let endTime = ''
  568. if (item.employmentTime.length == 2) {
  569. startTime = item.employmentTime[0].split(' ')[0]
  570. endTime = item.employmentTime[1].split(' ')[0]
  571. }
  572. if (startTime && endTime && startTime > endTime) {
  573. this.$queue.showToast('任职开始时间不能大于任职结束时间')
  574. return false;
  575. }
  576. if (item.position == '') {
  577. this.$queue.showToast('岗位不能为空')
  578. return false;
  579. }
  580. if (item.skills.length <= 0) {
  581. this.$queue.showToast('岗位技能不能为空')
  582. return false;
  583. }
  584. }
  585. let postData = this.formData.resumes.map(({
  586. employmentTime,
  587. departmentIndex,
  588. ...rest
  589. }) => {
  590. return {
  591. ...rest,
  592. skills: JSON.stringify(rest.skills),
  593. startTime: employmentTime?.[0] || '',
  594. endTime: employmentTime?.[1] || ''
  595. }
  596. })
  597. // this.formData.resumes.forEach(function(item){
  598. // console.log(item.skills)
  599. // item.skills=JSON.stringify(item.skills);
  600. // console.log(item.skills)
  601. // item.startTime=item.employmentTime[0]?item.employmentTime[0]:'';
  602. // item.endTime=item.employmentTime[1]?item.employmentTime[1]:'';
  603. // delete item.employmentTime;
  604. // delete item.departmentIndex;
  605. // })
  606. let data = {
  607. workExp: {
  608. workExpId: id,
  609. companyName: this.formData.companyName,
  610. type: JSON.stringify(this.formData.businessTypes),
  611. },
  612. workExpDetails: postData
  613. }
  614. if (this.isWork)
  615. return
  616. this.isWork = true
  617. uni.showLoading({
  618. title: "提交中..."
  619. });
  620. this.$Request.postJson("/app/userFirst/addWorkExp", data).then((res) => {
  621. uni.hideLoading();
  622. this.isWork = false
  623. this.formData.companyName == ''
  624. if (res.code == 0) {
  625. uni.showToast({
  626. title: "保存成功",
  627. icon: "none"
  628. });
  629. // 实际开发中可以在这里添加跳转逻辑
  630. uni.$emit('updateResume')
  631. setTimeout(() => {
  632. uni.navigateBack()
  633. }, 1000);
  634. } else {
  635. uni.showToast({
  636. title: res.msg,
  637. icon: "none",
  638. });
  639. }
  640. });
  641. },
  642. }
  643. }
  644. </script>
  645. <style lang="scss" scoped>
  646. .work-experience {
  647. height: 100vh;
  648. padding-bottom: 120rpx;
  649. display: flex;
  650. flex-direction: column;
  651. }
  652. .custom-navbar {
  653. // position: fixed;
  654. // top: 0;
  655. // left: 0;
  656. // right: 0;
  657. background-color: #ffffff;
  658. // z-index: 9999;
  659. .navbar-content {
  660. display: flex;
  661. align-items: center;
  662. justify-content: space-between;
  663. height: 100%;
  664. padding: 0 40rpx;
  665. .nav-left,
  666. .nav-right {
  667. width: 60rpx;
  668. height: 60rpx;
  669. display: flex;
  670. align-items: center;
  671. justify-content: center;
  672. }
  673. .nav-title {
  674. color: rgba(51, 51, 51, 1);
  675. font-family: DM Sans;
  676. font-size: 36rpx;
  677. font-weight: 700;
  678. line-height: 26px;
  679. letter-spacing: 0px;
  680. text-align: center;
  681. }
  682. }
  683. }
  684. .main-content {
  685. margin-top: 68rpx;
  686. padding: 0 20rpx 40rpx 20rpx;
  687. flex: 1;
  688. overflow: auto;
  689. }
  690. .form-section {
  691. background: #fff;
  692. border-radius: 16rpx;
  693. padding: 0rpx 10rpx;
  694. .section-title {
  695. color: rgba(23, 23, 37, 1);
  696. font-family: Inter;
  697. font-size: 32rpx;
  698. font-weight: 600;
  699. line-height: 48rpx;
  700. letter-spacing: 0%;
  701. text-align: left;
  702. padding: 16rpx 0 32rpx 0;
  703. display: flex;
  704. justify-content: space-between;
  705. align-items: center;
  706. }
  707. }
  708. .form-item {
  709. margin-bottom: 32rpx;
  710. .form-label {
  711. color: rgba(31, 44, 55, 1);
  712. font-family: DM Sans;
  713. font-size: 32rpx;
  714. font-weight: 500;
  715. line-height: 22px;
  716. letter-spacing: 0%;
  717. text-align: left;
  718. margin-bottom: 20rpx;
  719. position: relative;
  720. .word-count {
  721. font-size: 24rpx;
  722. color: #aaa;
  723. position: absolute;
  724. bottom: 0;
  725. right: 0;
  726. }
  727. .required-mark {
  728. color: #FF3B30;
  729. font-size: 18px;
  730. font-weight: 500;
  731. margin-right: 4rpx;
  732. }
  733. .label-text {
  734. color: rgba(31, 44, 55, 1);
  735. font-family: DM Sans;
  736. font-size: 16px;
  737. font-weight: 500;
  738. line-height: 22px;
  739. letter-spacing: 0%;
  740. text-align: left;
  741. }
  742. }
  743. .form-input {
  744. width: 100%;
  745. min-height: 80rpx;
  746. padding: 0 40rpx;
  747. border: 1px solid rgba(227, 231, 236, 1);
  748. border-radius: 24px;
  749. background: rgba(255, 255, 255, 1);
  750. display: flex;
  751. align-items: center;
  752. justify-content: space-between;
  753. .placeholder {
  754. color: #999999;
  755. }
  756. picker {
  757. width: 100%;
  758. }
  759. textarea {
  760. width: 100%;
  761. padding: 20rpx 0;
  762. height: auto !important;
  763. // min-height: 40rpx;
  764. resize: none;
  765. line-height: 1.5;
  766. overflow-y: hidden;
  767. }
  768. .form-textarea {
  769. width: 100%;
  770. min-height: 80rpx;
  771. padding: 20rpx 0;
  772. line-height: 1.5;
  773. resize: none;
  774. background: transparent;
  775. }
  776. }
  777. }
  778. .skills-input-container {
  779. width: 100%;
  780. min-height: 80rpx;
  781. padding: 0rpx 40rpx;
  782. border: 1px solid rgba(227, 231, 236, 1);
  783. border-radius: 32px;
  784. background: rgba(255, 255, 255, 1);
  785. display: flex;
  786. align-items: center;
  787. justify-content: space-between;
  788. .skills-tags {
  789. display: flex;
  790. flex-wrap: wrap;
  791. gap: 12rpx;
  792. flex: 1;
  793. .skill-tag {
  794. padding: 8rpx 16rpx;
  795. background: #F5F5F5;
  796. border-radius: 8rpx;
  797. display: flex;
  798. align-items: center;
  799. gap: 8rpx;
  800. text {
  801. font-size: 24rpx;
  802. color: #666666;
  803. }
  804. }
  805. }
  806. .add-skill-btn {
  807. width: 40rpx;
  808. height: 40rpx;
  809. border: 1rpx solid rgba(102, 102, 102, 1);
  810. border-radius: 8rpx;
  811. display: flex;
  812. align-items: center;
  813. justify-content: center;
  814. background: #fff;
  815. flex-shrink: 0;
  816. }
  817. }
  818. .add-resume-btn {
  819. width: 100%;
  820. height: 80rpx;
  821. border: 1rpx solid #007AFF;
  822. border-radius: 60rpx;
  823. display: flex;
  824. align-items: center;
  825. justify-content: center;
  826. margin-top: 20rpx;
  827. text {
  828. color: #007AFF;
  829. font-size: 28rpx;
  830. font-weight: 500;
  831. }
  832. }
  833. .bottom-btn-container {
  834. position: fixed;
  835. bottom: 0;
  836. left: 0;
  837. right: 0;
  838. padding: 30rpx 20rpx;
  839. background: #fff;
  840. border-top: 1px solid #f0f0f0;
  841. z-index: 98;
  842. }
  843. .save-btn {
  844. width: 100%;
  845. height: 88rpx;
  846. background: linear-gradient(90deg, rgba(13, 39, 247, 1), rgba(19, 193, 234, 1) 100%);
  847. border-radius: 44rpx;
  848. display: flex;
  849. align-items: center;
  850. justify-content: center;
  851. text {
  852. font-size: 32rpx;
  853. font-weight: 600;
  854. color: #fff;
  855. }
  856. }
  857. .add-skill-popup {
  858. background: #fff;
  859. border-radius: 24rpx;
  860. padding: 40rpx;
  861. .popup-title {
  862. color: rgba(34, 37, 42, 1);
  863. font-size: 36rpx;
  864. font-weight: 500;
  865. text-align: center;
  866. margin-bottom: 30rpx;
  867. }
  868. .popup-content {
  869. margin-bottom: 30rpx;
  870. .skill-input {
  871. width: 100%;
  872. height: 80rpx;
  873. padding: 0 20rpx;
  874. border: 1rpx solid #E5E5EA;
  875. border-radius: 12rpx;
  876. font-size: 28rpx;
  877. color: rgba(34, 37, 42, 1);
  878. background: #F7F8FA;
  879. }
  880. }
  881. .popup-buttons {
  882. display: flex;
  883. gap: 20rpx;
  884. .popup-btn {
  885. flex: 1;
  886. height: 80rpx;
  887. border-radius: 12rpx;
  888. display: flex;
  889. align-items: center;
  890. justify-content: center;
  891. font-size: 28rpx;
  892. font-weight: 500;
  893. }
  894. .cancel-btn {
  895. background: #F7F8FA;
  896. color: rgba(102, 102, 102, 1);
  897. }
  898. .confirm-btn {
  899. background: #007AFF;
  900. color: #fff;
  901. }
  902. }
  903. }
  904. .checkbox-container {
  905. display: flex;
  906. flex-wrap: nowrap;
  907. gap: 10rpx;
  908. /deep/ .u-checkbox-group {
  909. display: flex;
  910. flex-wrap: nowrap;
  911. width: 100%;
  912. }
  913. /deep/ .u-checkbox {
  914. flex: 1;
  915. min-width: 0;
  916. margin-right: 0;
  917. }
  918. /deep/ .u-checkbox__label {
  919. color: var(--Grayscale/Grayscale 100, rgba(23, 23, 37, 1));
  920. font-family: DM Sans;
  921. font-size: 24rpx;
  922. font-weight: 400;
  923. line-height: 48rpx;
  924. letter-spacing: 0%;
  925. text-align: left;
  926. }
  927. }
  928. .form-textarea {
  929. height: auto;
  930. }
  931. /* 时间选择器样式 */
  932. .time-range {
  933. display: flex;
  934. align-items: center;
  935. justify-content: space-between;
  936. }
  937. .time-input {
  938. flex: 1;
  939. display: flex;
  940. align-items: center;
  941. justify-content: space-between;
  942. // border-bottom: 1rpx solid #E5E5EA;
  943. // padding-bottom: 10rpx;
  944. text-align: center;
  945. }
  946. .time-input:first-child {
  947. margin-right: 20rpx;
  948. }
  949. .time-input:last-child {
  950. margin-left: 20rpx;
  951. }
  952. .time-separator {
  953. font-size: 28rpx;
  954. color: #666;
  955. }
  956. /* 调整日期选择器输入框样式 */
  957. .time-input /deep/ .uni-datetime-picker__input {
  958. width: 100%;
  959. font-size: 28rpx;
  960. color: #333;
  961. }
  962. .time-input /deep/ .uni-datetime-picker__placeholder {
  963. color: #999;
  964. font-size: 28rpx;
  965. }
  966. </style>