workExperience.vue 26 KB

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