app添加工作经历开发

This commit is contained in:
冯辉
2025-10-13 16:01:49 +08:00
parent 3d7cb0c561
commit 3d2c26650c
12 changed files with 840 additions and 74 deletions

View File

@@ -0,0 +1,388 @@
<template>
<AppLayout
title="添加工作经历"
border
back-gorund-color="#ffffff"
:show-bg-image="false"
>
<template #headerleft>
<view class="btn mar_le20 button-click" @click="navBack">取消</view>
</template>
<template #headerright>
<view class="btn mar_ri20 button-click" @click="handleConfirm">确认</view>
</template>
<view class="content">
<view class="content-input">
<view class="input-titile">公司名称</view>
<input class="input-con" v-model="formData.companyName" maxlength="200" placeholder-style="font-size: 16px" placeholder="请输入公司名称" />
</view>
<view class="content-input">
<view class="input-titile">职位名称</view>
<input class="input-con" v-model="formData.position" maxlength="100" placeholder-style="font-size: 16px" placeholder="请输入职位名称" />
</view>
<view class="content-input">
<view class="input-titile">工作时间</view>
<view class="date-range-container">
<picker mode="date" :value="startDate === '至今' ? currentDate : startDate" :start="minDate" :end="currentDate" @change="bindStartDateChange">
<view class="date-picker-item">
<text class="date-label">开始时间</text>
<view class="date-display" :class="{ 'current-text': startDate === '至今' }">{{startDate || '请选择开始时间'}}</view>
</view>
</picker>
<view class="date-separator"></view>
<picker mode="date" :value="endDate === '至今' ? currentDate : endDate" :start="startDate === '至今' ? minDate : startDate" :end="currentDate" @change="bindEndDateChange">
<view class="date-picker-item">
<text class="date-label">结束时间</text>
<view class="date-display" :class="{ 'current-text': endDate === '至今' }">{{endDate}}</view>
</view>
</picker>
</view>
</view>
<view class="content-input">
<view class="input-titile">工作描述</view>
<!-- <input class="input-con" placeholder="请输入工作描述" /> -->
<textarea class="textarea-con" v-model="formData.description" placeholder-style="font-size: 16px" maxlength="500" placeholder="请输入工作描述"/>
</view>
</view>
</AppLayout>
</template>
<script setup>
import { reactive, inject, watch, ref, onMounted, computed } from 'vue';
import { onLoad, onShow } from '@dcloudio/uni-app';
import SelectJobs from '@/components/selectJobs/selectJobs.vue';
import useUserStore from '@/stores/useUserStore';
const { $api, navTo, navBack, config } = inject('globalFunction');
const { userInfo } = useUserStore();
// 页面参数
const pageType = ref('add'); // add: 添加, edit: 编辑
const editData = ref(null); // 编辑时的数据
// 获取当前日期
const getDate = (options = {}) => {
const date = new Date();
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
if (options.format) {
return `${year}-${month}-${day}`;
}
return date;
};
const currentDate = getDate({ format: true });
const minDate = '1990-01-01'; // 开始时间最早只能选择到1990年
// 定义响应式数据
const startDate = ref(''); // 开始时间需要选择
const endDate = ref('至今'); // 结束时间默认为"至今"
// 表单数据
const formData = reactive({
companyName: '',
position: '',
userId: '', // 将在确认时动态获取
startDate: '',
endDate: '至今', // 设置默认值为"至今"
description: ''
});
// 页面加载时解析参数
onLoad((options) => {
console.log('页面参数:', options);
// 解析页面类型
if (options.type) {
pageType.value = options.type;
}
// 如果是编辑模式,解析传递的数据
if (options.type === 'edit' && options.data) {
try {
editData.value = JSON.parse(decodeURIComponent(options.data));
console.log('编辑数据:', editData.value);
// 回显数据到表单
if (editData.value) {
formData.companyName = editData.value.companyName || '';
formData.position = editData.value.position || '';
formData.startDate = editData.value.startDate || '';
formData.endDate = editData.value.endDate || '至今';
formData.description = editData.value.description || '';
// 同步日期选择器的显示
startDate.value = editData.value.startDate || '';
endDate.value = editData.value.endDate || '至今';
}
} catch (error) {
console.error('解析编辑数据失败:', error);
$api.msg('数据解析失败');
}
}
});
const state = reactive({
lfsalay: [2, 5, 10, 15, 20, 25, 30, 50],
risalay: [2, 5, 10, 15, 20, 25, 30, 50], // 修复未定义的salay变量
salayText: '',
areaText: '',
jobsText: []
});
// 开始日期选择器变化事件
const bindStartDateChange = (e) => {
const selectedDate = e.detail.value;
if (selectedDate === currentDate) {
// 如果选择的是今天,设置为"至今"
startDate.value = '至今';
formData.startDate = '至今';
} else {
startDate.value = selectedDate;
formData.startDate = selectedDate;
}
// 如果结束日期早于开始日期且结束日期不是"至今",清空结束日期
if (endDate.value && endDate.value !== '至今' && endDate.value < startDate.value) {
endDate.value = '至今';
formData.endDate = '至今';
}
};
// 结束日期选择器变化事件
const bindEndDateChange = (e) => {
const selectedDate = e.detail.value;
if (selectedDate === currentDate) {
// 如果选择的是今天,设置为"至今"
endDate.value = '至今';
formData.endDate = '至今';
} else {
endDate.value = selectedDate;
formData.endDate = selectedDate;
}
};
// 确认保存工作经历
const handleConfirm = async () => {
// 表单验证
if (!formData.companyName.trim()) {
$api.msg('请输入公司名称');
return;
}
if (!formData.position.trim()) {
$api.msg('请输入职位名称');
return;
}
if (!formData.startDate) {
$api.msg('请选择开始时间');
return;
}
if (!formData.description.trim()) {
$api.msg('请输入工作描述');
return;
}
console.log(userInfo.userId)
// 动态获取用户ID
const currentUserId = userInfo.userId;
if (!currentUserId) {
$api.msg('用户信息获取失败,请重新登录');
return;
}
// 调试:打印表单数据
console.log('表单数据:', formData);
console.log('结束时间:', formData.endDate);
try {
// 处理结束时间:如果是"至今",则使用当前日期
const endDateValue = formData.endDate === '至今' ? currentDate : formData.endDate;
console.log('处理后的结束时间:', endDateValue);
// 准备请求参数
const params = {
companyName: formData.companyName.trim(),
position: formData.position.trim(),
userId: currentUserId, // 使用动态获取的用户ID
startDate: formData.startDate,
endDate: endDateValue, // 使用处理后的结束时间
description: formData.description.trim()
};
console.log('请求参数:', params);
console.log('页面类型:', pageType.value);
let resData;
// 根据页面类型调用不同的接口
if (pageType.value === 'edit' && editData.value?.id) {
// 编辑模式:调用更新接口
resData = await $api.createRequest(`/app/userworkexperiences/${editData.value.id}`, params, 'put');
console.log('编辑接口响应:', resData);
} else {
// 添加模式:调用新增接口
resData = await $api.createRequest('/app/userworkexperiences/add', params, 'post');
console.log('新增接口响应:', resData);
}
if (resData.code === 200) {
$api.msg(pageType.value === 'edit' ? '工作经历更新成功' : '工作经历保存成功');
// 返回上一页
navBack();
} else {
$api.msg(resData.msg || '操作失败');
}
} catch (error) {
console.error('保存工作经历失败:', error);
$api.msg('保存失败,请重试');
}
};
</script>
<style lang="stylus" scoped>
.content{
padding: 28rpx;
display: flex;
flex-direction: column;
justify-content: flex-start
height: calc(100% - 120rpx)
}
.content-input
margin-bottom: 52rpx
.input-titile
font-weight: 400;
font-size: 28rpx;
color: #6A6A6A;
.input-con
font-weight: 400;
font-size: 32rpx;
color: #333333;
line-height: 80rpx;
height: 80rpx;
border-bottom: 2rpx solid #EBEBEB
position: relative;
.triangle::before
position: absolute;
right: 20rpx;
top: calc(50% - 2rpx);
content: '';
width: 4rpx;
height: 18rpx;
border-radius: 2rpx
background: #697279;
transform: translate(0, -50%) rotate(-45deg) ;
.triangle::after
position: absolute;
right: 20rpx;
top: 50%;
content: '';
width: 4rpx;
height: 18rpx;
border-radius: 2rpx
background: #697279;
transform: rotate(45deg)
.textarea-con
border: 2rpx solid #EBEBEB
width: 95%
height: 400rpx
margin-top: 20rpx
padding: 15rpx
.date-range-container
display: flex
align-items: flex-end
justify-content: space-between
margin-top: 20rpx
position: relative
border-bottom: 2rpx solid #EBEBEB
.date-picker-item
flex: 1
display: flex
flex-direction: column
align-items: center
.date-label
font-size: 24rpx
color: #999999
margin-bottom: 10rpx
.date-display
width: 100%
height: 80rpx
line-height: 80rpx
font-size: 32rpx
color: #333333
text-align: center
position: relative
&.current-text
color: #256BFA
font-weight: 500
.date-separator
position: absolute
left: 50%
bottom: 40rpx
transform: translateX(-50%)
font-size: 28rpx
color: #666666
background-color: #ffffff
padding: 0 10rpx
z-index: 2
height: 20rpx
line-height: 20rpx
display: flex
align-items: center
// .content-sex
// height: 110rpx;
// display: flex
// justify-content: space-between;
// align-items: flex-start;
// border-bottom: 2rpx solid #EBEBEB
// margin-bottom: 52rpx
// .sex-titile
// line-height: 80rpx;
// .sext-ri
// display: flex
// align-items: center;
// .sext-box
// height: 76rpx;
// width: 152rpx;
// text-align: center;
// line-height: 80rpx;
// border-radius: 12rpx 12rpx 12rpx 12rpx
// border: 2rpx solid #E8EAEE;
// margin-left: 28rpx
// font-weight: 400;
// font-size: 28rpx;
// .sext-boxactive
// color: #256BFA
// background: rgba(37,107,250,0.1);
// border: 2rpx solid #256BFA;
// .next-btn
// width: 100%;
// height: 90rpx;
// background: #256BFA;
// border-radius: 12rpx 12rpx 12rpx 12rpx;
// font-weight: 500;
// font-size: 32rpx;
// color: #FFFFFF;
// text-align: center;
// line-height: 90rpx
// .input-nx
// position: relative
// border-bottom: 2rpx solid #EBEBEB
// padding-bottom: 30rpx
// display: flex
// flex-wrap: wrap
// .nx-item
// padding: 20rpx 28rpx
// width: fit-content
// border-radius: 12rpx 12rpx 12rpx 12rpx;
// border: 2rpx solid #E8EAEE;
// margin-right: 24rpx
// margin-top: 24rpx
</style>

View File

@@ -161,63 +161,111 @@ const { getDictData, oneDictData } = useDictStore();
const isUploading = ref(false); // 上传中状态
const uploadedResumeName = ref(''); // 已上传简历文件名
const uploadedResumeUrl = ref(''); // 已上传
const workExperiences = ref([
{
id: 1, // 唯一标识实际项目用后端返回ID
companyName: 'XX科技有限公司', // 公司名称
position: '前端开发工程师', // 职位
startDate: '2021-07', // 开始日期格式YYYY-MM
endDate: '2023-09', // 结束日期(空/undefined 表示“至今”)
description:
'1. 负责公司小程序及H5页面开发基于UniApp+Vue3技术栈2. 优化前端性能首屏加载时间减少30%3. 参与封装通用组件库,提升团队开发效率。', // 工作描述
},
{
id: 2,
companyName: 'YY互联网公司',
position: '实习前端工程师',
startDate: '2020-12',
endDate: '2021-06',
description: '1. 协助完成后台管理系统页面开发2. 修复页面兼容性问题适配多浏览器3. 整理前端开发文档。',
},
]);
const workExperiences = ref([]); // 工作经历列表
const isLoading = ref(false); // 加载状态
// 页面加载时可从接口拉取数据
// 获取工作经历列表
const getWorkExperiences = async () => {
try {
isLoading.value = true;
console.log('完整用户信息:', userInfo.value);
// 获取用户ID - 使用可选链操作符避免错误
const userId = userInfo.value?.userId;
console.log('用户ID:', userId);
if (!userId) {
console.log('用户ID为空等待用户信息加载...');
// 如果用户ID为空不执行任何操作避免触发退出登录
return;
}
// 只传递userId参数
console.log('请求参数:', { userId });
// 使用try-catch包装请求避免自动退出登录
try {
// 参数拼接到URL后面
const resData = await $api.createRequest(`/app/userworkexperiences/list?userId=${userId}`, {}, 'get');
console.log('工作经历列表响应:', resData);
if (resData.code === 200 && resData.rows) {
workExperiences.value = resData.rows;
console.log('工作经历数据设置成功:', resData.rows);
console.log('总数量:', resData.total);
} else {
console.log('接口返回非200状态或无数据:', resData);
// 如果接口返回错误,不显示错误提示,避免用户困惑
workExperiences.value = []; // 设置为空数组
}
} catch (requestError) {
console.error('接口请求失败:', requestError);
// 接口请求失败时,不显示错误提示,静默处理
workExperiences.value = []; // 设置为空数组
}
} catch (error) {
console.error('获取工作经历失败:', error);
// 静默处理错误,不显示错误提示
workExperiences.value = [];
} finally {
isLoading.value = false;
}
};
// 页面加载时获取数据
onLoad(() => {
// 实际项目中替换为接口请求:
// getWorkExperiences().then(res => {
// workExperiences.value = res.data;
// }).catch(err => {
// showToast({ title: '数据加载失败', icon: 'none' });
// });
// 延迟获取数据,确保用户信息完全加载
setTimeout(() => {
if (userInfo.value?.userId) {
getWorkExperiences();
}
}, 1000);
});
// 页面显示时刷新数据
onShow(() => {
// 延迟获取数据,确保用户信息完全加载
setTimeout(() => {
if (userInfo.value?.userId) {
getWorkExperiences();
}
}, 1000);
});
// 整体编辑/添加(跳转编辑页)
const handleEditOrAdd = () => {
// 跳转至“批量编辑”或“添加经历页面(根据实际需求设计编辑页)
// router.push({
// path: '/pages/workExperience/edit',
// query: { type: workExperiences.value.length > 0 ? 'edit' : 'add' }
// });
// 跳转添加经历页面,传递添加标识
navTo('/packageA/pages/addWorkExperience/addWorkExperience?type=add');
};
// 编辑单个经历
const handleEditItem = (item) => {
// 跳转至单个编辑页,并携带当前经历数据
// router.push({
// path: '/pages/workExperience/editItem',
// query: { item: JSON.stringify(item) } // 复杂数据需转JSON字符串UniApp路由query不支持直接传对象
// });
// 跳转到编辑页面,传递编辑标识和数据
const itemData = encodeURIComponent(JSON.stringify(item));
navTo(`/packageA/pages/addWorkExperience/addWorkExperience?type=edit&data=${itemData}`);
};
// 删除单个经历(带确认弹窗)
const handleDeleteItem = (index) => {
const handleDeleteItem = async (item, index) => {
uni.showModal({
title: '确认删除',
content: '此操作将删除该工作经历,是否继续?',
success: (res) => {
success: async (res) => {
if (res.confirm) {
workExperiences.value.splice(index, 1); // 删除本地数据
$api.msg('删除成功');
try {
// 调用删除接口
const deleteRes = await $api.createRequest(`/cms/userworkexperiences/${item.id}`, {}, 'delete');
if (deleteRes.code === 200) {
workExperiences.value.splice(index, 1); // 删除本地数据
$api.msg('删除成功');
} else {
$api.msg(deleteRes.msg || '删除失败');
}
} catch (error) {
console.error('删除工作经历失败:', error);
$api.msg('删除失败,请重试');
}
}
},
});