Browse Source

feat:新增删除岗位履历功能

jianghaili 7 tháng trước cách đây
mục cha
commit
deab8a8aad
3 tập tin đã thay đổi với 1828 bổ sung1129 xóa
  1. 768 239
      package/deliveryRecord/deliveryRecord.vue
  2. 529 484
      pages/my/onlineResume.vue
  3. 531 406
      pages/my/workExperience.vue

+ 768 - 239
package/deliveryRecord/deliveryRecord.vue

@@ -1,301 +1,830 @@
 <template>
-	<view>
-		<!-- #ifdef H5 -->
-		<u-sticky h5-nav-height="0">
-		<!-- #endif -->
-			<!-- #ifndef H5 -->
-			<u-sticky>
-			<!-- #endif -->
-				<u-tabs :list="list" active-color="#016bf6" :is-scroll="false" :current="current"
-					@change="change"></u-tabs>
-			</u-sticky>
-			<!-- 简历列表 -->
-			<view class="qyList flex justify-center">
-				<view class="qyList-box">
-					<view class="qyList-box-item flex justify-center" v-for="(item,index) in datasList" :key="index"
-						@click="goNav(item,index)">
-						<view class="qyList-box-item-box">
-							<view v-if="item.isSee == 1" class="flex align-center justify-end"
-								style="margin-top: 40rpx;color: #016bf6;">
-								已读
-							</view>
-							<view class="qyList-box-item-info flex justify-between align-center">
-								<view class="qyList-box-item-info-l">
-									<view class="" style="color: #212121;font-size: 38rpx;font-weight: 800;">
-										{{item.resumesName?item.resumesName:''}}
-									</view>
-									<view class="flex align-center flex-wrap"
-										style="color: #999999;font-size: 26rpx;margin-top: 10rpx;">
-										<text>{{item.resumesAge?item.resumesAge:''}}岁</text>
-										<text style="margin-left: 20rpx;margin-right: 20rpx;">|</text>
-										<text>{{item.resumesWorkExperience?item.resumesWorkExperience:''}}</text>
-										<text style="margin-left: 20rpx;margin-right: 20rpx;">|</text>
-										<text>{{item.school?item.school:''}}</text>
-										<text style="margin-left: 20rpx;margin-right: 20rpx;">|</text>
-										<text>期望{{item.resumesCompensation?item.resumesCompensation:''}}</text>
-									</view>
-								</view>
-								<view class="qyList-box-item-info-r">
-									<image :src="item.avatar?item.avatar:'../../static/logo.png'"
-										style="width: 95rpx;height: 95rpx;border-radius: 50%;" mode=""></image>
-								</view>
-							</view>
-							<view class="qyList-box-item-job flex align-center">
-								<u-icon name="heart-fill" color="#016BF6" size="30" style="margin-right: 16rpx;">
-								</u-icon>
-								期望岗位:{{item.resumesPost?item.resumesPost:''}}
-							</view>
-							<view class="qyList-box-item-job flex align-center"
-								v-if="item.resumesCompanyList && item.resumesCompanyList.length>0">
-								<image src="../../static/images/qi.png"
-									style="width: 30rpx;height: 32rpx;margin-right: 16rpx;" mode=""></image>
-								{{item.resumesCompanyList[0].resumesTitle}}
-								/
-								{{item.resumesCompanyList[0].resumesPost}}
-							</view>
-							<view class="qyList-box-item-rem" v-if="item.resumesDetails">
-								优势:{{item.resumesDetails}}
-							</view>
-							<view class="line"></view>
-							<view class="qyList-box-item-box-ti flex justify-between align-center">
-								<text>投递岗位</text>
-								<text>{{item.stationName?item.stationName:''}}--{{item.ruleClassifyName?item.ruleClassifyName:''}}</text>
+	<view class="work-experience">
+		<!-- 自定义导航栏 -->
+		<view class="custom-navbar" :style="{ paddingTop: (12 + statusBarHeight) + 'px' }">
+			<view class="navbar-content">
+				<view class="nav-left" @click="goBack">
+					<u-icon name="arrow-leftward" color="#333" size="42"></u-icon>
+				</view>
+				<view class="nav-title">工作经历</view>
+				<view class="nav-right"></view>
+			</view>
+		</view>
+
+		<!-- 主要内容 -->
+		<view class="main-content">
+			<!-- 公司信息 -->
+			<view class="form-section">
+				<!-- 公司名称 -->
+				<view class="form-item">
+					<view class="form-label">公司名称</view>
+					<input v-model="formData.companyName" placeholder="请填写公司名称" class="form-input" />
+				</view>
+
+				<!-- 公司业务类型 -->
+				<view class="form-item">
+					<view class="form-label" style="margin-bottom: 20rpx;">
+						<text class="required-mark">*</text>
+						<text class="label-text">公司业务类型</text>
+					</view>
+					<view class="checkbox-container">
+						<u-checkbox-group @change="checkboxGroupChange" :wrap="false" shape="square"
+							active-color="#007AFF">
+							<u-checkbox v-for="(option, index) in businessTypeOptions" :key="index" :name="option.value"
+								v-model="option.checked" class="checkbox-item">
+								{{ option.label }}
+							</u-checkbox>
+						</u-checkbox-group>
+					</view>
+				</view>
+			</view>
+
+			<!-- 岗位履历 -->
+			<view class="form-section" v-for="(resume, index) in formData.resumes" :key="index">
+				<view class="section-title" v-if="hasCrossBorderExperience">岗位履历 ({{ index + 1 }})</view>
+
+				<!-- 任职时间 -->
+				<view class="form-item">
+					<view class="form-label">
+						<text class="required-mark">*</text>
+						<text class="label-text">{{ hasCrossBorderExperience ? '任职时间' : '在职时间' }}</text>
+					</view>
+					<view class="form-input">
+						<uni-datetime-picker v-model="resume.employmentTime" type="daterange" rangeSeparator="至"
+							:border="false" :startPlaceholder="hasCrossBorderExperience ? '选择任职时间' : '选择在职时间'"
+							endPlaceholder="选择离职时间" />
+						<!-- <text v-if="resume.employmentTime">{{ resume.employmentTime }}</text> -->
+						<!-- <text v-else class="placeholder">{{ hasCrossBorderExperience ? '选择任职时间&离职时间' : '选择在职时间&离职时间' }}</text> -->
+						<image src="../../static/images/index/Iconly_Light_Calendar.svg"
+							style="width: 48rpx; height: 48rpx;" mode="aspectFit"></image>
+					</view>
+				</view>
+
+				<!-- 所在部门 -->
+				<view class="form-item">
+					<view class="form-label">
+						<text class="required-mark">*</text>
+						<text class="label-text">所在部门</text>
+					</view>
+					<view class="form-input">
+						<picker class="picker" :data-index="index" mode="selector" :range="departments"
+							@change="selectDepartment">
+							<text>{{departments.length>0?departments[resume.departmentIndex]:'请选择部门'}}</text>
+						</picker>
+						<u-icon name="arrow-down" color="#999" size="36"></u-icon>
+					</view>
+				</view>
+
+				<!-- 岗位 -->
+				<view class="form-item">
+					<view class="form-label">
+						<text class="required-mark">*</text>
+						<text class="label-text">岗位</text>
+					</view>
+					<view class="form-input" @click="selectPosition(index)">
+						<text v-if="resume.position">{{ resume.position }}</text>
+						<text v-else class="placeholder">请选择岗位</text>
+						<u-icon name="arrow-right" color="#999" size="36"></u-icon>
+					</view>
+				</view>
+
+				<!-- 岗位职级 -->
+				<view class="form-item">
+					<view class="form-label">岗位职级</view>
+					<view class="form-input">
+						<picker class="picker" :data-index="index" mode="selector" :range="positionLevels"
+							@change="selectPositionLevel">
+							<text>{{resume.positionLevel||'请选择'}}</text>
+						</picker>
+						<u-icon name="arrow-down" color="#999" size="36"></u-icon>
+					</view>
+				</view>
+
+				<!-- 岗位职业技能 -->
+				<view class="form-item">
+					<view class="form-label">
+						<text class="required-mark">*</text>
+						<text class="label-text">岗位职业技能</text>
+					</view>
+					<view class="skills-input-container">
+						<view class="skills-tags">
+							<view v-for="(skill, skillIndex) in resume.skills" :key="skillIndex" class="skill-tag">
+								<text>{{ skill }}</text>
+								<u-icon name="close" color="#999" size="16"
+									@click="removeSkill(index, skillIndex)"></u-icon>
 							</view>
 						</view>
+						<view class="add-skill-btn" @click="addSkill(index)">
+							<u-icon name="plus" color="rgba(102, 102, 102, 1)" size="28"></u-icon>
+						</view>
+					</view>
+				</view>
+
+				<!-- 工作内容 -->
+				<view class="form-item">
+					<view class="form-label">工作内容</view>
+					<view class="form-input">
+						<textarea auto-height v-model="resume.workContent" placeholder="选填,请输入"></textarea>
 					</view>
-					<empty v-if="datasList.length==0" />
+				</view>
+				<!-- 工作业绩 -->
+				<view class="form-item">
+					<view class="form-label">工作业绩</view>
+					<view class="form-input">
+						<textarea auto-height v-model="resume.workPerformance" placeholder="选填,请输入"></textarea>
+					</view>
+				</view>
+
+				<!-- 添加岗位履历按钮 -->
+				<view class="add-resume-btn" @click="addResume"
+					v-if="index === formData.resumes.length - 1 && hasCrossBorderExperience">
+					<text>添加岗位履历</text>
 				</view>
 			</view>
-			<!-- 筛选悬浮 -->
-			<view class="filterSe" @click="goScreen()">
-				<image src="../../static/images/my/filterSe.png" mode=""></image>
+			<!-- 底部保存按钮 -->
+			<view class="bottom-btn-container">
+				<view class="save-btn" @click="saveWorkExperience">
+					<text>保存</text>
+				</view>
 			</view>
+		</view>
+		<!-- 添加技能弹窗 -->
+		<u-popup v-model="showAddSkill" mode="center" border-radius="24" width="80%">
+			<view class="add-skill-popup">
+				<view class="popup-title">添加技能</view>
+				<view class="popup-content">
+					<input v-model="newSkillName" placeholder="请输入技能名称" class="skill-input" maxlength="10" />
+				</view>
+				<view class="popup-buttons">
+					<view class="popup-btn cancel-btn" @click="cancelAddSkill">取消</view>
+					<view class="popup-btn confirm-btn" @click="confirmAddSkill">确定</view>
+				</view>
+			</view>
+		</u-popup>
 	</view>
 </template>
 
 <script>
-	import empty from '../../components/empty.vue'
+	var id = '';
 	export default {
-		components: {
-			empty
-		},
 		data() {
 			return {
-				list: [{
-					name: '全部',
-					isSee: '',
-				}, {
-					name: '已读',
-					isSee: 1
-				}, {
-					name: '未读',
-					isSee: 0
-				}],
-				current: 0,
-				datasList: [],
-				page: 1,
-				limit: 10,
-				totlo: 0,
-				filter: {
-					resumesCompensation: '', //薪资
-					resumesEducation: '', //学历
-					resumesWorkExperience: '', //经验
-					industryName: '', //行业
+				statusBarHeight: 0, // 状态栏高度
+				showAddSkill: false,
+				newSkillName: '',
+				currentResumeIndex: 0,
+				businessTypeOptions: [{
+						label: '跨境电商',
+						value: '0',
+						checked: false
+					},
+					{
+						label: '国内电商',
+						value: '1',
+						checked: false
+					},
+					{
+						label: '外贸',
+						value: '2',
+						checked: false
+					},
+					{
+						label: '其他',
+						value: '3',
+						checked: false
+					}
+				],
+				formData: {
+					companyName: '',
+					businessTypes: [],
+					resumes: [{
+						workExpDetailId: "",
+						workExpId: "",
+						employmentTime: [],
+						department: '',
+						departmentId: 0,
+						departmentIndex: 0,
+						position: '',
+						positionId: 0,
+						positionLevel: '初级',
+						skills: [],
+						workContent: '',
+						workPerformance: ''
+					}]
+				},
+				departments: [],
+				departmentsIds: [],
+				positionLevels: ['初级', '资深'],
+				operateKey: 0,
+				isWork: false
+			}
+		},
+		onLoad(options) {
+			// 获取状态栏高度
+			let systemInfo = uni.getSystemInfoSync();
+			this.statusBarHeight = systemInfo.statusBarHeight || 0;
+			// 接收从在线简历页面传递的业务类型参数
+			if (options.businessTypes) {
+				try {
+					const businessTypes = JSON.parse(decodeURIComponent(options.businessTypes))
+					this.formData.businessTypes = businessTypes
+					console.log('接收到的业务类型:', businessTypes)
+					console.log('是否有跨境经验:', this.hasCrossBorderExperience)
+					if (this.hasCrossBorderExperience)
+						this.businessTypeOptions[0].checked = true
+				} catch (e) {
+					console.error('解析业务类型参数失败:', e)
 				}
-			};
+			}
+			this.getDepartment()
+			id = options && options.id ? options.id : ''
+			// 监听技能设置更新
+			uni.$on('jobs', (data) => {
+				console.log('岗位设置已更新:', data)
+				// 这里可以更新对应的技能显示
+				this.formData.resumes[this.operateKey].position = data.ruleClassifyName
+				this.formData.resumes[this.operateKey].positionId = data.ruleClassifyId;
+				// 更新以后给岗位职业技能设置默认值
+				this.getDataInfo(this.formData.resumes[this.operateKey].positionId);
+			})
+			uni.$on('skillsUpdated', (data) => {
+				console.log('技能设置已更新:', data)
+				// 这里可以更新对应的技能显示
+				this.formData.resumes[this.operateKey].skills = data.selectedTags
+			})
 		},
-		onLoad() {
-			this.getDataList()
+		beforeDestroy() {
+			// 移除事件监听
+			uni.$off('jobs')
+			uni.$off('skillsUpdated')
 		},
-		onReachBottom() {
-			if (this.page < this.totlo) {
-				this.page += 1
-				this.getDataList()
+		computed: {
+			hasCrossBorderExperience() {
+				return this.formData.businessTypes.includes('0')
 			}
 		},
-		onPullDownRefresh() {
-			this.page = 1
-			this.getDataList()
-		},
-		onShow() {
-			if (uni.getStorageSync('isCompyHistory') && (uni.getStorageSync('isCompyHistory')).length > 0) {
-				let isCompyHistory = uni.getStorageSync('isCompyHistory')
-				isCompyHistory.map(item => {
-					let arr = []
-					item.list.map(ite => {
-						if (ite.value != '不限') {
-							arr.push(ite.value)
-						}
-					})
-					switch (item.name) {
-						case '学历':
-							this.filter.resumesEducation = arr.join(',')
-							break;
-						case '薪资':
-							this.filter.resumesCompensation = arr.join(',')
-							break;
-						case '经验':
-							this.filter.resumesWorkExperience = arr.join(',')
-							break;
-						case '行业':
-							this.filter.industryName = arr.join(',')
-							break;
+		methods: {
+			getDataInfo(jobId) {
+				let data = {
+					ruleClassifyId: jobId
+				}
+				this.$Request.getT('/app/userFirst/getPostSkill', data).then(res => {
+					if (res.code == 0) {
+						if(res.data.length>0&&res.data[0]?.childrenList[0]?.postSkillName)
+						this.formData.resumes[this.operateKey].skills.push(res.data[0]?.childrenList[0]?.postSkillName)
 					}
+				})
+			},
+			goBack() {
+				uni.navigateBack()
+			},
+			getDepartment() {
+				var that = this
+				this.$Request.postJson("/app/userFirst/getDepartment", {}).then((res) => {
+					if (res.code == 0) {
+						that.departments = that.$queue.array_column(res.data, 'departmentName')
+						that.departmentsIds = that.$queue.array_column(res.data, 'departmentId')
+						that.formData.resumes.forEach(function(item) {
+							item.departmentId = that.departmentsIds[item.departmentIndex]
+							item.department = that.departments[item.departmentIndex]
+						})
+						if (id != '' && id != 0)
+							that.getData()
+					} else {
+						uni.showToast({
+							title: res.msg,
+							icon: "none",
+						});
+					}
+				});
+
+			},
+			getData() {
+				var that = this
+				this.$Request.getT("/app/userFirst/getWorkExpDetailOne", {
+					workExpId: id
+				}).then((res) => {
+					if (res.code == 0) {
+						res = res.data
+						that.formData.companyName = res.workExp.companyName
+						that.formData.businessTypes = JSON.parse(res.workExp.type)
+						res.workExpDetails.forEach(function(item) {
+							item.skills = JSON.parse(item.skills)
+							item.employmentTime = item.startTime == '' ? [] : [item.startTime, item
+									.endTime],
+								item.departmentIndex = that.departmentsIds.indexOf(item.departmentId) < 0 ?
+								0 : that.departmentsIds.indexOf(item.departmentId)
+						})
+						that.formData.resumes = res.workExpDetails
+					} else {
+						uni.showToast({
+							title: res.msg,
+							icon: "none",
+						});
+					}
+				});
+			},
+			selectDepartment(e) {
+				var key = Number(e.currentTarget.dataset.index)
+				this.formData.resumes[key].departmentId = this.departmentsIds[e.detail.value]
+				this.formData.resumes[key].departmentIndex = e.detail.value
+				this.formData.resumes[key].department = this.departments[e.detail.value]
+			},
+			formatter(type, value) {
+				if (type === 'year') {
+					return `${value}年`
+				}
+				if (type === 'month') {
+					return `${value}月`
+				}
+				if (type === 'day') {
+					return `${value}日`
+				}
+				return value
+			},
+			checkboxGroupChange(e) {
+				console.log('选中的业务类型:', e)
+				// 更新 formData.businessTypes 以保持数据同步
+				this.formData.businessTypes = e
+			},
 
+			selectEmploymentTime(index) {
+				// 选择任职时间
+				uni.showToast({
+					title: '选择任职时间',
+					icon: 'none'
 				})
-			} else {
-				this.filter.resumesEducation = '' //学历
-				this.filter.resumesWorkExperience = '' //经验
-				this.filter.industryName = '' //行业
-				this.filter.resumesCompensation = '' //薪资
-			}
-		},
-		watch: {
-			filter: {
-				handler() {
-					this.page = 1
-					this.getDataList()
-				},
-				deep: true,
-				immediate: true
-			}
-		},
-		onUnload() {
-			uni.removeStorageSync('isCompyHistory')
-		},
-		methods: {
-			change(index) {
-				this.current = index;
-				this.page = 1
-				this.getDataList()
 			},
-			// 去筛选
-			goScreen() {
+
+			selectPosition(index) {
+				this.operateKey = index
+				// 选择岗位
 				uni.navigateTo({
-					url: '/package/screen/screen?isCompyHistory=1'
+					url: '/package/jobIntention/jobList'
 				})
 			},
-			// 标记为已读
-			setIsSee(recordId, index) {
-				let data = {
-					recordId: recordId
-				}
-				this.$Request.getT('/app/sendRecord/seeRecord', data).then(res => {
-					if (res.code == 0) {
-						this.datasList[index].isSee = 1
-					}
+			selectPositionLevel(e) {
+				var key = Number(e.currentTarget.dataset.index)
+				this.formData.resumes[key].positionLevel = this.positionLevels[e.detail.value]
+			},
+			addSkill(index) {
+				this.operateKey = index
+				//this.currentResumeIndex = index
+				//this.showAddSkill = true
+				//this.newSkillName = ''
+				if (this.formData.resumes[index].positionId == '' || this.formData.resumes[index].positionId == 0)
+					return this.$queue.showToast('请先选择岗位')
+				uni.navigateTo({
+					url: '/package/jobIntention/jobSkills?jobId=' + this.formData.resumes[index].positionId +
+						'&jobTitle=' + this.formData.resumes[index].position + '&skill=' + encodeURIComponent(JSON
+							.stringify(this.formData.resumes[index].skills))
 				})
 			},
-			goNav(item, index) {
-				if (item.resumesId) {
-					this.setIsSee(item.recordId, index)
-					uni.navigateTo({
-						url: '/pages/index/game/orderDet?resumesId=' + item.resumesId + '&isSee=' + item.isSee
-					})
+			removeSkill(resumeIndex, skillIndex) {
+				this.formData.resumes[resumeIndex].skills.splice(skillIndex, 1)
+			},
+			cancelAddSkill() {
+				this.showAddSkill = false
+				this.newSkillName = ''
+			},
+			confirmAddSkill() {
+				if (this.newSkillName.trim()) {
+					this.formData.resumes[this.currentResumeIndex].skills.push(this.newSkillName.trim())
+					this.showAddSkill = false
+					this.newSkillName = ''
 				} else {
 					uni.showToast({
-						title: '该用户简历不存在',
+						title: '请输入技能名称',
 						icon: 'none'
 					})
 				}
-				console.log(url, '1111')
-
 			},
-			//获取已投递简历的列表
-			getDataList() {
+			selectWorkContent(index) {
+				// 选择工作内容
+				uni.showToast({
+					title: '选择工作内容',
+					icon: 'none'
+				})
+			},
+			selectWorkPerformance(index) {
+				// 选择工作业绩
+				uni.showToast({
+					title: '选择工作业绩',
+					icon: 'none'
+				})
+			},
+			addResume() {
+				this.formData.resumes.push({
+					workExpDetailId: "",
+					workExpId: "",
+					employmentTime: [],
+					department: this.departments[0],
+					departmentId: this.departmentsIds[0],
+					departmentIndex: 0,
+					position: '',
+					positionId: 0,
+					positionLevel: '初级',
+					skills: [],
+					workContent: '',
+					workPerformance: ''
+				})
+			},
+
+			saveWorkExperience() {
+				console.log(this.formData.resumes)
+				if (!this.formData.companyName) {
+					uni.showToast({
+						title: "请输入公司名称",
+						icon: "none"
+					});
+					return;
+				}
+				if (this.formData.businessTypes.length <= 0) {
+					uni.showToast({
+						title: "请选择公司业务类型",
+						icon: "none"
+					});
+					return;
+				}
+				if (this.formData.resumes.length <= 0) {
+					uni.showToast({
+						title: "请至少填写一份履历",
+						icon: "none"
+					});
+					return;
+				}
+				for (let i = 0; i < this.formData.resumes.length; i++) {
+				        const item = this.formData.resumes[i];
+					if (item.employmentTime.length <= 0) {
+						this.$queue.showToast('任职时间不能为空')
+						return false;
+					}
+					if (item.position == '') {
+						this.$queue.showToast('岗位不能为空')
+						return false;
+					}
+					if (item.skills.length <= 0) {
+						this.$queue.showToast('岗位技能不能为空')
+						return false;
+					}
+				}
+				let postData = this.formData.resumes.map(({
+					employmentTime,
+					departmentIndex,
+					...rest
+				}) => {
+					return {
+						...rest,
+						skills: JSON.stringify(rest.skills),
+						startTime: employmentTime?.[0] || '',
+						endTime: employmentTime?.[1] || ''
+					}
+				})
+				//  this.formData.resumes.forEach(function(item){
+				//   console.log(item.skills)
+				//  	item.skills=JSON.stringify(item.skills);
+				// console.log(item.skills)
+				// item.startTime=item.employmentTime[0]?item.employmentTime[0]:'';
+				// item.endTime=item.employmentTime[1]?item.employmentTime[1]:'';
+				// delete item.employmentTime; 
+				// delete item.departmentIndex; 
+				//  })
 				let data = {
-					page: this.page,
-					limit: this.limit,
-					resumesCompensation: this.filter.resumesCompensation, //薪资
-					resumesEducation: this.filter.resumesEducation, //学历
-					resumesWorkExperience: this.filter.resumesWorkExperience, //经验
-					industryName: this.filter.industryName, //行业
-					isSee: this.list[this.current].isSee
+					workExp: {
+						workExpId: id,
+						companyName: this.formData.companyName,
+						type: JSON.stringify(this.formData.businessTypes),
+					},
+					workExpDetails: postData
 				}
-				this.$Request.getT('/app/sendRecord/getCompanyRecordListV2', data).then(res => {
+				if (this.isWork)
+					return
+				this.isWork = true
+				uni.showLoading({
+					title: "提交中..."
+				});
+				this.$Request.postJson("/app/userFirst/addWorkExp", data).then((res) => {
+					uni.hideLoading();
+					this.isWork = false
+					this.formData.companyName == ''
 					if (res.code == 0) {
-						this.totlo = res.data.pages //记录总页数
-						if (this.page == 1) {
-							this.datasList = res.data.records
-						} else {
-							this.datasList = [...this.datasList, ...res.data.records]
-						}
+						uni.showToast({
+							title: "保存成功",
+							icon: "none"
+						});
+						// 实际开发中可以在这里添加跳转逻辑
+						uni.$emit('updateResume')
+						setTimeout(() => {
+							uni.navigateBack()
+						}, 1000);
+					} else {
+						uni.showToast({
+							title: res.msg,
+							icon: "none",
+						});
 					}
-				}).finally(()=>{
-					uni.stopPullDownRefresh();
-				})
+				});
 			},
 		}
 	}
 </script>
 
-<style lang="scss">
-	page {
-		background: #F2F2F7;
+<style lang="scss" scoped>
+	.work-experience {
+		height: 100vh;
+		padding-bottom: 120rpx;
+		display: flex;
+		flex-direction: column;
 	}
 
-	.filterSe {
-		position: fixed;
-		bottom: 10vh;
-		right: 30rpx;
+	.custom-navbar {
+		// position: fixed;
+		// top: 0;
+		// left: 0;
+		// right: 0;
+		background-color: #ffffff;
+		// z-index: 9999;
+
+		.navbar-content {
+			display: flex;
+			align-items: center;
+			justify-content: space-between;
+			height: 100%;
+			padding: 0 40rpx;
+
+			.nav-left,
+			.nav-right {
+				width: 60rpx;
+				height: 60rpx;
+				display: flex;
+				align-items: center;
+				justify-content: center;
+			}
+
+			.nav-title {
+				color: rgba(51, 51, 51, 1);
+				font-family: DM Sans;
+				font-size: 36rpx;
+				font-weight: 700;
+				line-height: 26px;
+				letter-spacing: 0px;
+				text-align: center;
+			}
+		}
+	}
+
+	.main-content {
+		margin-top: 68rpx;
+		padding: 0 20rpx 40rpx 20rpx;
+		flex: 1;
+		overflow: auto;
+	}
+
+	.form-section {
+		background: #fff;
+		border-radius: 16rpx;
+		padding: 0rpx 10rpx;
 
-		image {
-			width: 100rpx;
-			height: 100rpx;
-			// border-radius: 50%;
+		.section-title {
+			color: rgba(23, 23, 37, 1);
+			font-family: Inter;
+			font-size: 32rpx;
+			font-weight: 600;
+			line-height: 48rpx;
+			letter-spacing: 0%;
+			text-align: left;
+			padding: 16rpx 0 32rpx 0;
 		}
 	}
 
-	.qyList {
-		width: 100%;
-		height: auto;
-		margin-top: 20rpx;
+	.form-item {
+		margin-bottom: 32rpx;
 
-		.qyList-box {
-			width: 686rpx;
-			height: 100%;
+		.form-label {
+			color: rgba(31, 44, 55, 1);
+			font-family: DM Sans;
+			font-size: 16px;
+			font-weight: 500;
+			line-height: 22px;
+			letter-spacing: 0%;
+			text-align: left;
+			margin-bottom: 20rpx;
 
-			.qyList-box-item {
+			.required-mark {
+				color: #FF3B30;
+				font-size: 18px;
+				font-weight: 500;
+				margin-right: 4rpx;
+			}
+
+			.label-text {
+				color: rgba(31, 44, 55, 1);
+				font-family: DM Sans;
+				font-size: 16px;
+				font-weight: 500;
+				line-height: 22px;
+				letter-spacing: 0%;
+				text-align: left;
+			}
+		}
+
+		.form-input {
+			width: 100%;
+			min-height: 80rpx;
+			padding: 0 40rpx;
+			border: 1px solid rgba(227, 231, 236, 1);
+			border-radius: 24px;
+			background: rgba(255, 255, 255, 1);
+			display: flex;
+			align-items: center;
+			justify-content: space-between;
+
+			.placeholder {
+				color: #999999;
+			}
+
+			picker {
 				width: 100%;
-				// height: 400rpx;
-				padding-bottom: 40rpx;
-				background-color: #ffffff;
-				border-radius: 24rpx;
-				margin-bottom: 20rpx;
-
-				.qyList-box-item-box {
-					width: 626rpx;
-					height: 100%;
-				}
+			}
 
-				.line {
-					width: 100%;
-					border-bottom: 1rpx solid #F2F2F7;
-					margin-top: 20rpx;
-				}
+			textarea {
+				width: 100%;
+				padding: 20rpx 0;
+				height: fit-content;
+				min-height: 40rpx;
+			}
+		}
+	}
 
-				.qyList-box-item-box-ti {
-					margin-top: 20rpx;
-				}
+	.skills-input-container {
+		width: 100%;
+		min-height: 80rpx;
+		padding: 0rpx 40rpx;
+		border: 1px solid rgba(227, 231, 236, 1);
+		border-radius: 32px;
+		background: rgba(255, 255, 255, 1);
+		display: flex;
+		align-items: center;
+		justify-content: space-between;
 
-				.qyList-box-item-info {
-					margin-top: 20rpx;
-					// margin-top: 40rpx;
-				}
+		.skills-tags {
+			display: flex;
+			flex-wrap: wrap;
+			gap: 12rpx;
+			flex: 1;
 
-				.qyList-box-item-job {
-					color: #121212;
-					font-size: 28rpx;
-					font-weight: 500;
-					margin-top: 20rpx;
-				}
+			.skill-tag {
+				padding: 8rpx 16rpx;
+				background: #F5F5F5;
+				border-radius: 8rpx;
+				display: flex;
+				align-items: center;
+				gap: 8rpx;
 
-				.qyList-box-item-rem {
-					color: #999999;
-					font-size: 26rpx;
-					margin-top: 20rpx;
+				text {
+					font-size: 24rpx;
+					color: #666666;
 				}
 			}
 		}
+
+		.add-skill-btn {
+			width: 40rpx;
+			height: 40rpx;
+			border: 1rpx solid rgba(102, 102, 102, 1);
+			border-radius: 8rpx;
+			display: flex;
+			align-items: center;
+			justify-content: center;
+			background: #fff;
+			flex-shrink: 0;
+		}
+	}
+
+	.add-resume-btn {
+		width: 100%;
+		height: 80rpx;
+		border: 1rpx solid #007AFF;
+		border-radius: 60rpx;
+		display: flex;
+		align-items: center;
+		justify-content: center;
+		margin-top: 20rpx;
+
+		text {
+			color: #007AFF;
+			font-size: 28rpx;
+			font-weight: 500;
+		}
+	}
+
+	.bottom-btn-container {
+		position: fixed;
+		bottom: 0;
+		left: 0;
+		right: 0;
+		padding: 30rpx 20rpx;
+		background: #fff;
+		border-top: 1px solid #f0f0f0;
+		z-index: 98;
+	}
+
+	.save-btn {
+		width: 100%;
+		height: 88rpx;
+		background: linear-gradient(90deg, rgba(13, 39, 247, 1), rgba(19, 193, 234, 1) 100%);
+		border-radius: 44rpx;
+		display: flex;
+		align-items: center;
+		justify-content: center;
+
+		text {
+			font-size: 32rpx;
+			font-weight: 600;
+			color: #fff;
+		}
+	}
+
+	.add-skill-popup {
+		background: #fff;
+		border-radius: 24rpx;
+		padding: 40rpx;
+
+		.popup-title {
+			color: rgba(34, 37, 42, 1);
+			font-size: 36rpx;
+			font-weight: 500;
+			text-align: center;
+			margin-bottom: 30rpx;
+		}
+
+		.popup-content {
+			margin-bottom: 30rpx;
+
+			.skill-input {
+				width: 100%;
+				height: 80rpx;
+				padding: 0 20rpx;
+				border: 1rpx solid #E5E5EA;
+				border-radius: 12rpx;
+				font-size: 28rpx;
+				color: rgba(34, 37, 42, 1);
+				background: #F7F8FA;
+			}
+		}
+
+		.popup-buttons {
+			display: flex;
+			gap: 20rpx;
+
+			.popup-btn {
+				flex: 1;
+				height: 80rpx;
+				border-radius: 12rpx;
+				display: flex;
+				align-items: center;
+				justify-content: center;
+				font-size: 28rpx;
+				font-weight: 500;
+			}
+
+			.cancel-btn {
+				background: #F7F8FA;
+				color: rgba(102, 102, 102, 1);
+			}
+
+			.confirm-btn {
+				background: #007AFF;
+				color: #fff;
+			}
+		}
+	}
+
+	.checkbox-container {
+		display: flex;
+		flex-wrap: nowrap;
+		gap: 10rpx;
+
+		/deep/ .u-checkbox-group {
+			display: flex;
+			flex-wrap: nowrap;
+			width: 100%;
+		}
+
+		/deep/ .u-checkbox {
+			flex: 1;
+			min-width: 0;
+			margin-right: 0;
+		}
+
+		/deep/ .u-checkbox__label {
+			color: var(--Grayscale/Grayscale 100, rgba(23, 23, 37, 1));
+			font-family: DM Sans;
+			font-size: 24rpx;
+			font-weight: 400;
+			line-height: 48rpx;
+			letter-spacing: 0%;
+			text-align: left;
+		}
 	}
 </style>

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 529 - 484
pages/my/onlineResume.vue


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 531 - 406
pages/my/workExperience.vue


Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác