|
|
|
|
@ -56,7 +56,7 @@
|
|
|
|
|
</el-col>
|
|
|
|
|
|
|
|
|
|
<!-- 总体事由 -->
|
|
|
|
|
<el-col :span="12">
|
|
|
|
|
<el-col :span="12" v-if="form.tripType !== '2' && form.tripType !== '3'">
|
|
|
|
|
<el-form-item label="出差事由" prop="tripReason">
|
|
|
|
|
<el-input
|
|
|
|
|
v-model="form.tripReason"
|
|
|
|
|
@ -75,8 +75,8 @@
|
|
|
|
|
v-model="form.startTime"
|
|
|
|
|
type="date"
|
|
|
|
|
value-format="YYYY-MM-DD"
|
|
|
|
|
placeholder="由明细自动计算"
|
|
|
|
|
:disabled="true"
|
|
|
|
|
placeholder="请选择开始日期"
|
|
|
|
|
:disabled="isFormDisabled"
|
|
|
|
|
style="width: 100%"
|
|
|
|
|
/>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
@ -87,8 +87,8 @@
|
|
|
|
|
v-model="form.endTime"
|
|
|
|
|
type="date"
|
|
|
|
|
value-format="YYYY-MM-DD"
|
|
|
|
|
placeholder="由明细自动计算"
|
|
|
|
|
:disabled="true"
|
|
|
|
|
placeholder="请选择结束日期"
|
|
|
|
|
:disabled="isFormDisabled"
|
|
|
|
|
style="width: 100%"
|
|
|
|
|
/>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
@ -280,25 +280,9 @@
|
|
|
|
|
</el-table-column>
|
|
|
|
|
|
|
|
|
|
<el-table-column prop="startTime" width="170">
|
|
|
|
|
<template #header> <span style="color: #f56c6c; margin-right: 4px">*</span>开始日期 </template>
|
|
|
|
|
<template #header> 开始日期 </template>
|
|
|
|
|
<template #default="scope">
|
|
|
|
|
<el-form-item
|
|
|
|
|
:prop="'crmBusinessTripDetailsList.' + scope.$index + '.startTime'"
|
|
|
|
|
:rules="[
|
|
|
|
|
{
|
|
|
|
|
required: true,
|
|
|
|
|
validator: (rule, value, callback) => {
|
|
|
|
|
const item = form.crmBusinessTripDetailsList?.[scope.$index];
|
|
|
|
|
if (!item || !item.startTime) {
|
|
|
|
|
callback(new Error('开始日期不能为空'));
|
|
|
|
|
} else {
|
|
|
|
|
callback();
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
trigger: ['blur', 'change']
|
|
|
|
|
}
|
|
|
|
|
]"
|
|
|
|
|
>
|
|
|
|
|
<el-form-item :prop="'crmBusinessTripDetailsList.' + scope.$index + '.startTime'">
|
|
|
|
|
<el-date-picker
|
|
|
|
|
v-model="scope.row.startTime"
|
|
|
|
|
type="date"
|
|
|
|
|
@ -318,25 +302,9 @@
|
|
|
|
|
</el-table-column>
|
|
|
|
|
|
|
|
|
|
<el-table-column prop="endTime" width="170">
|
|
|
|
|
<template #header> <span style="color: #f56c6c; margin-right: 4px">*</span>结束日期 </template>
|
|
|
|
|
<template #header> 结束日期 </template>
|
|
|
|
|
<template #default="scope">
|
|
|
|
|
<el-form-item
|
|
|
|
|
:prop="'crmBusinessTripDetailsList.' + scope.$index + '.endTime'"
|
|
|
|
|
:rules="[
|
|
|
|
|
{
|
|
|
|
|
required: true,
|
|
|
|
|
validator: (rule, value, callback) => {
|
|
|
|
|
const item = form.crmBusinessTripDetailsList?.[scope.$index];
|
|
|
|
|
if (!item || !item.endTime) {
|
|
|
|
|
callback(new Error('结束日期不能为空'));
|
|
|
|
|
} else {
|
|
|
|
|
callback();
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
trigger: ['blur', 'change']
|
|
|
|
|
}
|
|
|
|
|
]"
|
|
|
|
|
>
|
|
|
|
|
<el-form-item :prop="'crmBusinessTripDetailsList.' + scope.$index + '.endTime'">
|
|
|
|
|
<el-date-picker
|
|
|
|
|
v-model="scope.row.endTime"
|
|
|
|
|
type="date"
|
|
|
|
|
@ -617,10 +585,9 @@ onMounted(async () => {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 如果落到“申请人确认”节点,将固定注入陈海军和张东辉,以及业务负责人作为后台流转变量
|
|
|
|
|
// 不直接侵入公共底层弹窗组件显示,而是随表单变量潜行,配合画图里的 @@businessTripCopyUsers@@ 取值
|
|
|
|
|
if (routeParams.value.type === 'approval' && String(useUserStore().userId) === String(form.value.applicantId)) {
|
|
|
|
|
const confirmCopyIds: string[] = [];
|
|
|
|
|
['张东辉', '陈海军'].forEach((name) => {
|
|
|
|
|
['张东辉', '陈海军', '米兰', '张兰艳'].forEach((name) => {
|
|
|
|
|
const matchedUser = userList.value.find((u: any) => u.nickName === name);
|
|
|
|
|
if (matchedUser) {
|
|
|
|
|
confirmCopyIds.push(String(matchedUser.userId));
|
|
|
|
|
@ -642,7 +609,7 @@ onMounted(async () => {
|
|
|
|
|
|
|
|
|
|
// 兼容原有的手工可选抄送并做个去重合并
|
|
|
|
|
form.value.copyUserIds = Array.from(new Set([...(form.value.copyUserIds || []), ...confirmCopyIds]));
|
|
|
|
|
// 关键挂载:将整理完的抄送群放入该次提交时的全局工作流上下文引擎变量中
|
|
|
|
|
// 将整理完的抄送群放入该次提交时的全局工作流上下文引擎变量中
|
|
|
|
|
taskVariables.value.businessTripCopyUsers = form.value.copyUserIds.join(',');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -772,12 +739,7 @@ watch(
|
|
|
|
|
() => form.value.crmBusinessTripDetailsList,
|
|
|
|
|
(newList) => {
|
|
|
|
|
if (newList && newList.length > 0) {
|
|
|
|
|
let totalDays = 0;
|
|
|
|
|
let minStart = newList[0].startTime;
|
|
|
|
|
let maxEnd = newList[0].endTime;
|
|
|
|
|
|
|
|
|
|
newList.forEach((item) => {
|
|
|
|
|
// 1. 自动计算单行动动态时长
|
|
|
|
|
if (item.startTime && item.endTime) {
|
|
|
|
|
const start = dayjs(item.startTime);
|
|
|
|
|
const end = dayjs(item.endTime);
|
|
|
|
|
@ -786,21 +748,8 @@ watch(
|
|
|
|
|
} else {
|
|
|
|
|
item.durationDays = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 2. 汇总数据
|
|
|
|
|
if (item.durationDays) {
|
|
|
|
|
totalDays += Number(item.durationDays);
|
|
|
|
|
}
|
|
|
|
|
if (item.startTime && (!minStart || dayjs(item.startTime).isBefore(dayjs(minStart)))) {
|
|
|
|
|
minStart = item.startTime;
|
|
|
|
|
}
|
|
|
|
|
if (item.endTime && (!maxEnd || dayjs(item.endTime).isAfter(dayjs(maxEnd)))) {
|
|
|
|
|
maxEnd = item.endTime;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
form.value.durationDays = totalDays;
|
|
|
|
|
form.value.startTime = minStart;
|
|
|
|
|
form.value.endTime = maxEnd;
|
|
|
|
|
|
|
|
|
|
// 辅助归集第一行明细数据到主表,用于列表页展示
|
|
|
|
|
form.value.tripLocation = newList[0].tripLocation;
|
|
|
|
|
form.value.customerId = newList[0].customerId;
|
|
|
|
|
@ -808,15 +757,26 @@ watch(
|
|
|
|
|
form.value.exchangeFeedback = newList[0].exchangeFeedback;
|
|
|
|
|
form.value.meetingName = newList[0].meetingName;
|
|
|
|
|
form.value.projectId = newList[0].projectId;
|
|
|
|
|
} else {
|
|
|
|
|
form.value.durationDays = 0;
|
|
|
|
|
form.value.startTime = undefined;
|
|
|
|
|
form.value.endTime = undefined;
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
{ deep: true }
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// 主卡片选择日期时,独立计算主卡片的总时长
|
|
|
|
|
watch(
|
|
|
|
|
() => [form.value.startTime, form.value.endTime],
|
|
|
|
|
([newStart, newEnd]) => {
|
|
|
|
|
if (newStart && newEnd) {
|
|
|
|
|
const start = dayjs(newStart);
|
|
|
|
|
const end = dayjs(newEnd);
|
|
|
|
|
const diff = end.diff(start, 'day');
|
|
|
|
|
form.value.durationDays = diff >= 0 ? diff + 1 : 0;
|
|
|
|
|
} else {
|
|
|
|
|
form.value.durationDays = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// 审批人选择变更
|
|
|
|
|
const handleApproverSelectChange = (val: any) => {
|
|
|
|
|
const user = userList.value.find((u) => u.userId === val);
|
|
|
|
|
@ -853,25 +813,7 @@ const aggregateDetailsToForm = (): boolean => {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let totalDays = 0;
|
|
|
|
|
let minStart = details[0].startTime;
|
|
|
|
|
let maxEnd = details[0].endTime;
|
|
|
|
|
form.value.tripLocation = details[0].tripLocation; // 取第一个行程地点作为主地点
|
|
|
|
|
|
|
|
|
|
details.forEach((item) => {
|
|
|
|
|
if (item.durationDays) {
|
|
|
|
|
totalDays += Number(item.durationDays);
|
|
|
|
|
}
|
|
|
|
|
if (item.startTime && (!minStart || dayjs(item.startTime).isBefore(dayjs(minStart)))) {
|
|
|
|
|
minStart = item.startTime;
|
|
|
|
|
}
|
|
|
|
|
if (item.endTime && (!maxEnd || dayjs(item.endTime).isAfter(dayjs(maxEnd)))) {
|
|
|
|
|
maxEnd = item.endTime;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
form.value.durationDays = totalDays;
|
|
|
|
|
form.value.startTime = minStart;
|
|
|
|
|
form.value.endTime = maxEnd;
|
|
|
|
|
return true;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|