合并人才集团代码

This commit is contained in:
2025-11-03 12:30:37 +08:00
parent 233e5fecdc
commit 1c6d5c7a15
118 changed files with 12562 additions and 14 deletions

View File

@@ -0,0 +1,795 @@
<!--
* @Date: 2024-10-08 14:29:36
* @LastEditors: lip
* @LastEditTime: 2025-05-07 09:33:39
-->
<template>
<view class="container">
<scroll-view scroll-y="true" :style="{height: edit?'calc(90vh - 150px)':'calc(100vh - 144px)', backgroundColor: '#eef1f5'}">
<view class="inner">
<view class="part-title" style="display: flex;justify-content: space-between;">培训需求信息
<view v-if="!edit&&formData.id&&formData.currentStatus!=3" class="btn"
style="font-weight: normal;display: flex;" @click="edit=true">编辑<view class="icon-right"></view></view>
</view>
<view class="inner-part">
<view class="self-form">
<view class="form-item">
<view class="form-label">姓名 <text class="required">*</text></view>
<view v-if="name" style="width: 100%;"
class="disabledLine">
{{ formData.personName || '请选择' }}
</view>
<view v-else style="width: 100%;" @click="openPersonChooser"
:class="{disabledLine: !edit||!canChoosePerson, noValue: !formData.personName}">
{{ formData.personName || '请选择' }}
</view>
<view class="icon-right"></view>
</view>
<view class="form-item">
<view class="form-label">培训意愿工种 <text class="required">*</text></view>
<picker
mode="multiSelector"
:range="workTypeColumns"
range-key="workTypeName"
:value="workTypeIndexes"
@change="onWorkTypePickerChange"
@columnchange="onWorkTypeColumnChange"
v-if="workTypeColumns[0] && workTypeColumns[0].length"
>
<view class="picker-view">
<view class="picker-view-text">{{ formData.qwpxgzName || '请选择工种' }}</view>
<view class="icon-right"></view>
</view>
</picker>
<view v-else class="picker-view">
<view class="picker-view-text">工种数据加载中...</view>
</view>
</view>
<view class="form-item">
<view class="form-label">期望培训时间 <text class="required">*</text></view>
<picker mode="date" :value="formData.qwpxsj" start="1900-01-01" end="2100-12-31" @change="onDateChange">
<view class="date-picker-wrapper" :class="{ noValue: !formData.qwpxsj }">
<view v-if="formData.qwpxsj" class="date-value">{{ formData.qwpxsj }}</view>
<view v-else>请选择</view>
<view class="icon-right"></view>
</view>
</picker>
</view>
<view class="form-item">
<view class="form-label">需求说明 <text class="required">*</text></view>
<textarea :disabled="!edit" v-model="formData.jobDescription" placeholder="请输入" :class="['form-textarea', { 'form-textarea-disabled': !edit }]"></textarea>
</view>
</view>
</view>
</view>
<!-- 办理完成后 需求说明 -->
<req-comp :form="{
actualSolveDate: formData.actualSolveDate,
actualSolvePeople: formData.actualSolvePeople,
solveDesc: formData.solveDesc,
fileUrl: formData.fileUrl
}" />
</scroll-view>
<view class="button-area" v-if="edit">
<view class="btn" @click="cancelPage">取消</view>
<view class="btn reset" @click="getDetail(formData.id)">重置</view>
<view class="btn save" @click="saveInfo">保存</view>
</view>
</view>
</template>
<script>
import { getPersonBase } from "@/packageRc/api/personinfo/index";
import { addPersonDemand, updatePersonDemand, getPersonDemand } from "@/packageRc/api/needs/personDemand";
import { listJobType } from "@/packageRc/api/jobType/index";
import uniDateformat from '@/uni_modules/uni-dateformat/components/uni-dateformat/uni-dateformat.vue';
export default {
components: {
// ChoosePerson
},
props: {
needId: {
type: String,
default: ''
},
name: {
type: String,
default: ''
}
},
data() {
return {
edit: true,
personBase: {},
formData: {
userId:"",
personName:"",
demandType: "3",
personName: '',
personId: "",
userId: "",
demandTitle: '',
qwpxsj: '',
qwpxgz: '',
qwpxgzName: '',
jobDescription: ''
},
rules: {
personName: [{
required: true,
message: '请填写姓名',
trigger: ['blur', 'change'],
}, ],
qwpxgz: [{
required: true,
message: '请选择培训意愿工种',
trigger: ['blur', 'change'],
validator: (rule, value) => {
// 允许数组且有值,或字符串有值
return (Array.isArray(value) && value.length > 0) || (!!value);
}
}, ],
qwpxsj: [{
required: true,
message: '请选择期望培训时间',
trigger: ['blur', 'change'],
}, ],
},
dict: {},
show: {},
currentCityArr: [],
originalDept: [],
currentCity: '请选择',
bysj: '',
loading: false,
jobTypeList: [],
route: {},
canChoosePerson: false,
workTypeTreeList: [],
searchKeyword: '',
workTypeList: [],
workTypeColumns: [[], [], []],
workTypeIndexes: [0, 0, 0],
}
},
onReady() {
this.$refs.uForm.setRules(this.rules)
},
created() {
this.setName();
this.loading = true;
this.workTypeRemoteMethod('');
},
methods: {
setName() {
// 直接设置人员信息
this.formData.personName = this.name;
this.formData.personId = this.needId;
this.formData.userId = this.needId;
// 设置需求标题
if (this.formData.personName) {
const today = new Date();
const year = today.getFullYear();
const month = String(today.getMonth() + 1).padStart(2, '0');
const day = String(today.getDate()).padStart(2, '0');
const formattedDate = `${year}-${month}-${day}`;
this.formData.demandTitle = `${this.formData.personName}_于${formattedDate}_提出培训需求`;
}
},
cancelPage() {
if (this.formData.id) {
this.edit = false;
this.getDetail(this.formData.id)
} else {
uni.navigateBack()
}
},
openPersonChooser() {
if (this.edit && this.canChoosePerson) {
this.$refs.personChooser.open();
}
},
personNameConfirm(event) {
this.formData.personName = event.name
this.formData.personId = event.id
this.formData.userId = event.userId
this.formNameChange();
this.$forceUpdate();
},
// 使用picker组件的日期选择
onDateChange(e) {
this.formData.qwpxsj = e.detail.value;
},
changeFile(e) {
// 清空当前的 fileUrl 数组
this.formData.fileUrl = [];
// 如果 e 有长度(即用户选择了文件)
if (e.length) {
// 遍历每个文件对象并获取其 url
for (let data of e) {
const url = data.data ? data.data.url : data.url;
this.formData.fileUrl.push(url);
}
}
this.formData.fileUrl = this.$arrayToString(this.formData.fileUrl)
},
addOne() {
this.formData = {}
this.getPersonInfo()
if(this.name){
this.formData.personName = this.name
this.formData.userId = this.needId
}
this.edit = true
},
workTypeRemoteMethod(key) {
listJobType({
workTypeName: key,
pageNum: 1,
pageSize: 50
}).then(
(res) => {
console.log('工种数据加载成功:', res.rows);
this.jobTypeList = res.rows;
// 处理树形数据为级联选择器格式
this.processWorkTypeTree(res.rows);
}
).catch(error => {
console.error('获取工种列表失败:', error);
this.workTypeList = [];
this.workTypeColumns = [[], [], []];
});
},
jobTypeConfirm(type, event) {
this.show[type] = false
this.formData[type] = event.value[0].id
this.formData.qwpxgzName = event.value[0].workTypeName
this.$forceUpdate();
},
getDetail(id) {
getPersonDemand(id).then(res => {
this.formData = res.data;
// 设置工种索引(需要等工种数据加载完成后)
if (this.formData.qwpxgz && this.workTypeColumns[0].length) {
this.setWorkTypeIndexes(this.formData.qwpxgz);
}
this.edit = false;
}).catch(error => {
console.error('Error fetching training detail:', error);
});
},
goBack() {
uni.navigateBack();
},
cancelPicker(type) {
this.$set(this.show, type, false)
this.$forceUpdate()
},
getDictLabel(value, list) {
if (list) {
let arr = list.filter(ele => ele.dictValue == value)
if (arr.length) {
return arr[0].dictLabel
} else {
return '请选择'
}
}
},
pickerConfirm(type, event) {
this.show[type] = false
this.formData[type] = event.value[0].dictValue
this.$forceUpdate();
},
showPicker(type) {
if (this.edit) {
this.show[type] = true
this.$forceUpdate()
}
},
getPersonInfo() {
this.loading = true;
this.$store.dispatch("GetInfo").then((res) => {
if (res.data.roles.indexOf('qunzhong') == -1) {
this.canChoosePerson = true;
this.setName() // 确保非群众角色也能获取姓名
} else {
this.canChoosePerson = false;
getPersonBase(res.data.user.userId).then(resp => {
this.formData.personId = resp.data.id
this.formData.userId = resp.data.userId
this.formData.personName = resp.data.name
this.formNameChange();
this.$forceUpdate();
})
}
})
},
setName() {
this.formData.personName = this.name;
this.formData.personId = this.needId;
this.formData.userId = this.needId;
let date = new Date();
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
const dayNew = `${year}-${month}-${day}`;
this.formData.demandTitle = `${this.formData.personName}_于${dayNew}_提出培训需求`;
},
async saveInfo() {
try {
this.setName();
console.log("执行保存,表单数据:", this.formData);
console.log("personName:", this.formData.personName);
console.log("personId:", this.formData.personId);
console.log("userId:", this.formData.userId);
// 手动检查培训意愿工种是否已选择
if (!this.formData.qwpxgz || (typeof this.formData.qwpxgz === 'string' && this.formData.qwpxgz.trim() === '')) {
uni.showToast({
title: '请选择培训意愿工种!',
icon: 'none'
});
return;
}
// 手动检查期望培训时间是否已选择
if (!this.formData.qwpxsj || (typeof this.formData.qwpxsj === 'string' && this.formData.qwpxsj.trim() === '')) {
uni.showToast({
title: '请选择期望培训时间!',
icon: 'none'
});
return;
}
// 表单字段已通过手动检查,无需额外验证
uni.showLoading({
title: '加载中...'
});
let response;
let successMessage;
this.formData.demandType = 3;
if (this.formData.id) {
response = await updatePersonDemand(this.formData);
successMessage = '修改成功';
} else {
response = await addPersonDemand(this.formData);
successMessage = '保存成功';
}
// 检查响应码是否为200
if (response.code === 200) {
uni.showToast({
title: successMessage,
icon: 'success'
});
// 如果是编辑模式,关闭编辑状态;否则返回上一页
if (this.formData.id) {
this.edit = false;
} else {
setTimeout(() => {
uni.navigateBack();
}, 1000);
}
} else {
// 响应码不为200时显示服务器返回的错误信息或默认错误信息
uni.showToast({
title: response.msg || '操作失败,请重试!',
icon: 'none'
});
}
} catch (error) {
console.error('保存失败:', error);
// 检查错误是否为字符串类型或有特定消息
if(typeof error === 'string' || (error && error.message && error.message.includes('请检查'))){
uni.showToast({
title: '请填写完整信息!',
icon: 'none'
});
} else {
uni.showToast({
title: '系统错误,请联系管理员!',
icon: 'none'
});
}
} finally {
// 确保加载页总是会被隐藏
uni.hideLoading();
}
},
// getWorkTypeTree() {
// listJobType({
// workTypeName: '',
// pageNum: 1,
// pageSize: 9999
// }).then(res => {
// console.log("11111",this.workTypeTreeList)
// this.workTypeTreeList = Array.isArray(res.rows) ? res.rows : [];
// });
// },
// 处理树形数据为级联选择器格式
processWorkTypeTree(treeData) {
if (!treeData || !Array.isArray(treeData)) {
this.workTypeColumns = [[], [], []];
return;
}
// 第一级
const level1 = treeData.filter(item => item.level === "1");
// 第二级
const level2 = treeData.filter(item => item.level === "2");
// 第三级
const level3 = treeData.filter(item => item.level === "3");
// 构建级联数据
const columns = [];
columns[0] = level1;
// 根据第一级选择,过滤第二级
if (level1.length > 0) {
const firstLevelId = level1[0].id;
columns[1] = level2.filter(item => item.parentId === firstLevelId);
} else {
columns[1] = [];
}
// 根据第二级选择,过滤第三级
if (columns[1].length > 0) {
const secondLevelId = columns[1][0].id;
columns[2] = level3.filter(item => item.parentId === secondLevelId);
} else {
columns[2] = [];
}
this.workTypeColumns = columns;
console.log('级联数据构建完成:', this.workTypeColumns);
},
// 级联选择器列变化事件
onWorkTypeColumnChange(e) {
const { column, value } = e.detail;
const newIndexes = [...this.workTypeIndexes];
newIndexes[column] = value;
// 重置后续列的数据
if (column === 0) {
// 第一列变化,重置第二、三列
const selectedLevel1 = this.workTypeColumns[0][value];
if (selectedLevel1) {
const level2 = this.jobTypeList.filter(item =>
item.level === "2" && item.parentId === selectedLevel1.id
);
this.workTypeColumns[1] = level2;
this.workTypeColumns[2] = [];
newIndexes[1] = 0;
newIndexes[2] = 0;
}
} else if (column === 1) {
// 第二列变化,重置第三列
const selectedLevel2 = this.workTypeColumns[1][value];
if (selectedLevel2) {
const level3 = this.jobTypeList.filter(item =>
item.level === "3" && item.parentId === selectedLevel2.id
);
this.workTypeColumns[2] = level3;
newIndexes[2] = 0;
}
}
this.workTypeIndexes = newIndexes;
},
// 级联选择器确认事件
onWorkTypePickerChange(e) {
const indexes = e.detail.value;
const selectedLevel1 = this.workTypeColumns[0][indexes[0]];
const selectedLevel2 = this.workTypeColumns[1][indexes[1]];
const selectedLevel3 = this.workTypeColumns[2][indexes[2]];
// 直接赋值确保响应式更新
if (selectedLevel3) {
// 选择第三级
this.formData.qwpxgz = selectedLevel3.id;
this.formData.qwpxgzName = `${selectedLevel1.workTypeName}/${selectedLevel2.workTypeName}/${selectedLevel3.workTypeName}`;
} else if (selectedLevel2) {
// 选择第二级
this.formData.qwpxgz = selectedLevel2.id;
this.formData.qwpxgzName = `${selectedLevel1.workTypeName}/${selectedLevel2.workTypeName}`;
} else if (selectedLevel1) {
// 选择第一级
this.formData.qwpxgz = selectedLevel1.id;
this.formData.qwpxgzName = selectedLevel1.workTypeName;
}
this.workTypeIndexes = indexes;
// 强制重新渲染组件
this.$forceUpdate();
},
// 根据工种ID设置索引
setWorkTypeIndexes(workTypeId) {
// 在工种列表中查找对应的工种
const targetWorkType = this.jobTypeList.find(item => item.id == workTypeId);
if (!targetWorkType) return;
// 根据level确定是哪一级
if (targetWorkType.level === "1") {
const index = this.workTypeColumns[0].findIndex(item => item.id == workTypeId);
if (index !== -1) {
this.workTypeIndexes = [index, 0, 0];
}
} else if (targetWorkType.level === "2") {
// 需要先找到父级
const parent = this.jobTypeList.find(item => item.id == targetWorkType.parentId);
if (parent) {
const parentIndex = this.workTypeColumns[0].findIndex(item => item.id == parent.id);
const childIndex = this.workTypeColumns[1].findIndex(item => item.id == workTypeId);
if (parentIndex !== -1 && childIndex !== -1) {
this.workTypeIndexes = [parentIndex, childIndex, 0];
}
}
} else if (targetWorkType.level === "3") {
// 需要找到祖父级和父级
const parent = this.jobTypeList.find(item => item.id == targetWorkType.parentId);
const grandparent = this.jobTypeList.find(item => item.id == parent.parentId);
if (parent && grandparent) {
const grandparentIndex = this.workTypeColumns[0].findIndex(item => item.id == grandparent.id);
const parentIndex = this.workTypeColumns[1].findIndex(item => item.id == parent.id);
const childIndex = this.workTypeColumns[2].findIndex(item => item.id == workTypeId);
if (grandparentIndex !== -1 && parentIndex !== -1 && childIndex !== -1) {
this.workTypeIndexes = [grandparentIndex, parentIndex, childIndex];
}
}
}
},
}
}
</script>
<style lang="scss">
.date-picker-wrapper {
width: 100%;
padding: 10px;
box-sizing: border-box;
display: flex;
justify-content: space-between;
align-items: center;
border: 1px solid #ddd;
border-radius: 4px;
}
.date-picker-wrapper.noValue {
color: #999;
}
.date-value {
color: #333;
}
.page ::v-deep .u-navbar__content {
background-color: transparent !important;
}
.container {
height: 100vh;
overflow: hidden;
background-color: #f7f7f7;
}
.page {
background-color: #3161c7;
height: 100vh;
background-image: url('https://rc.jinan.gov.cn/qcwjyH5/static/images/top.png');
background-repeat: no-repeat;
background-size: 100% auto;
}
.inner {
background: #eef1f5;
border-radius: 16rpx;
padding: 32rpx;
margin-bottom: 24rpx;
}
.inner-part {
width: 100%;
}
/* 为表单元素添加一些间距 */
.self-form {
width: 100%;
}
/* 表单项目样式 */
.form-item {
display: flex;
align-items: flex-start;
margin-bottom: 24rpx;
background-color: #fff;
border-radius: 8rpx;
padding: 24rpx;
}
.form-label {
width: 200rpx;
font-size: 28rpx;
color: #333;
flex-shrink: 0;
line-height: 48rpx;
}
.required {
color: #f56c6c;
margin-left: 4rpx;
}
.form-input {
flex: 1;
border: none;
outline: none;
font-size: 28rpx;
color: #333;
background: none;
height: 48rpx;
line-height: 48rpx;
}
.form-input-disabled {
color: #909399;
background-color: #f5f7fa;
}
.form-textarea {
flex: 1;
border: none;
outline: none;
font-size: 28rpx;
color: #333;
background: none;
min-height: 120rpx;
line-height: 40rpx;
}
.form-textarea-disabled {
color: #909399;
background-color: #f5f7fa;
}
.icon-right {
width: 40rpx;
height: 40rpx;
display: flex;
align-items: center;
justify-content: center;
color: #A6A6A6;
margin-left: 16rpx;
}
/* 单选框样式 */
.radio-group {
flex: 1;
display: flex;
align-items: center;
}
.radio-item {
display: flex;
align-items: center;
margin-right: 32rpx;
cursor: pointer;
}
.radio-item.radio-disabled {
cursor: not-allowed;
}
.radio {
width: 28rpx;
height: 28rpx;
border-radius: 50%;
border: 2rpx solid #dcdfe6;
margin-right: 12rpx;
position: relative;
}
.radio.radio-checked {
border-color: #409eff;
background-color: #409eff;
}
.radio.radio-checked::after {
content: '';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 12rpx;
height: 12rpx;
border-radius: 50%;
background-color: #fff;
}
/* 调整按钮区域样式 */
.button-area {
margin-top: 24rpx;
}
.picker-cover {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.5);
z-index: 99;
}
.button-area {
padding: 24rpx 32rpx 68rpx;
width: calc(100% + 64rpx);
margin-left: -32rpx;
background: #fff;
display: flex;
box-sizing: border-box;
margin-top: 40rpx;
border-radius: 16px 16px 0px 0px;
.btn {
line-height: 72rpx;
width: 176rpx;
margin-right: 16rpx;
font-size: 28rpx;
border: 1px solid #B8C5D4;
color: #282828;
text-align: center;
border-radius: 8rpx;
}
.reset {
background: #DCE2E9;
}
.save {
background: linear-gradient(103deg, #1D64CF 0%, #1590D4 99%);
color: #fff;
border: 0;
flex-grow: 1;
}
}
.noValue {
color: rgb(192, 196, 204);
}
.disabledLine {
background: rgb(245, 247, 250);
cursor: not-allowed;
}
.bordered {
border: 1rpx solid #dadbde;
padding: 9px;
border-radius: 4px;
}
.picker-view {
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
}
.picker-view-text {
color: #333333;
flex: 1;
text-align: left; font-size: 28rpx;
flex: 1;
}
</style>