|
|
|
|
@ -12,7 +12,7 @@
|
|
|
|
|
:mode="false"
|
|
|
|
|
>
|
|
|
|
|
<!-- 提交完成/评分关闭按钮已移除,统一由审批按钮触发 approvalVerifyOpen 拦截 execute/leader_final 节点 -->
|
|
|
|
|
<!-- <el-button v-if="canSubmitFinish" type="success" icon="CircleCheck" @click="handleSubmitFinish" v-hasPermi="['oa/erp:tempTask:submitFinish']">
|
|
|
|
|
<!-- <el-button v-if="canSubmitFinish" type="success" icon="CircleCheck" @click="handleSubmitFinish" v-hasPermi="['oa/erp:tempTask:submitFinish']">
|
|
|
|
|
提交完成
|
|
|
|
|
</el-button>
|
|
|
|
|
<el-button v-if="canScoreClose" type="warning" icon="Star" @click="openScoreDialog" v-hasPermi="['oa/erp:tempTask:edit']">
|
|
|
|
|
@ -93,17 +93,17 @@
|
|
|
|
|
</el-select>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</el-col>
|
|
|
|
|
<!-- <el-col :span="12" v-if="form.taskType === '1'">
|
|
|
|
|
<!-- <el-col :span="12" v-if="form.taskType === '1'">
|
|
|
|
|
<el-form-item label="归集部门名称" prop="deptName">
|
|
|
|
|
<el-input v-model="form.deptName" disabled placeholder="选择部门后自动填充" />
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</el-col>-->
|
|
|
|
|
<!-- <el-col :span="8">
|
|
|
|
|
<!-- <el-col :span="8">
|
|
|
|
|
<el-form-item label="发起人" prop="requesterName">
|
|
|
|
|
<el-input v-model="form.requesterName" disabled placeholder="后端按当前用户回填" />
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</el-col>-->
|
|
|
|
|
<el-col :span="8">
|
|
|
|
|
<!-- <el-col :span="8">
|
|
|
|
|
<el-form-item label="实际需求人" prop="realRequesterName">
|
|
|
|
|
<el-input v-model="form.realRequesterName" readonly placeholder="默认可为空,代发起时选择">
|
|
|
|
|
<template #suffix>
|
|
|
|
|
@ -111,6 +111,19 @@
|
|
|
|
|
</template>
|
|
|
|
|
</el-input>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</el-col>-->
|
|
|
|
|
<el-col :span="8">
|
|
|
|
|
<el-form-item label="实际需求人" prop="realRequesterId">
|
|
|
|
|
<el-select
|
|
|
|
|
v-model="form.realRequesterId"
|
|
|
|
|
placeholder="默认可为空,代发起时选择"
|
|
|
|
|
clearable
|
|
|
|
|
filterable
|
|
|
|
|
@change="handleRealRequesterChange"
|
|
|
|
|
>
|
|
|
|
|
<el-option v-for="user in userList" :key="user.userId" :label="user.nickName" :value="user.userId" />
|
|
|
|
|
</el-select>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</el-col>
|
|
|
|
|
<el-col :span="8">
|
|
|
|
|
<el-form-item label="实际需求部门" prop="realRequestDeptId">
|
|
|
|
|
@ -119,7 +132,7 @@
|
|
|
|
|
</el-select>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</el-col>
|
|
|
|
|
<el-col :span="8">
|
|
|
|
|
<!-- <el-col :span="8">
|
|
|
|
|
<el-form-item label="主执行人" prop="assigneeName">
|
|
|
|
|
<el-input v-model="form.assigneeName" readonly placeholder="请选择主执行人">
|
|
|
|
|
<template #suffix>
|
|
|
|
|
@ -127,9 +140,16 @@
|
|
|
|
|
</template>
|
|
|
|
|
</el-input>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</el-col>-->
|
|
|
|
|
<el-col :span="8">
|
|
|
|
|
<el-form-item label="主执行人" prop="assigneeId">
|
|
|
|
|
<el-select v-model="form.assigneeId" placeholder="请选择主执行人" clearable filterable @change="handleAssigneeChange">
|
|
|
|
|
<el-option v-for="user in userList" :key="user.userId" :label="user.nickName" :value="user.userId" />
|
|
|
|
|
</el-select>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</el-col>
|
|
|
|
|
<!-- Why actualStartTime 始终 disabled:由后端流程引擎在 leader_review 通过后自动落库,前端不可手动编辑 -->
|
|
|
|
|
<!-- <el-col :span="8">
|
|
|
|
|
<!-- <el-col :span="8">
|
|
|
|
|
<el-form-item label="实际开始" prop="actualStartTime">
|
|
|
|
|
<el-date-picker v-model="form.actualStartTime" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" disabled placeholder="流程自动记录" />
|
|
|
|
|
</el-form-item>
|
|
|
|
|
@ -234,7 +254,7 @@
|
|
|
|
|
<div class="flex justify-between items-center">
|
|
|
|
|
<span>评分结果</span>
|
|
|
|
|
<!-- 评分关闭按钮已移除,统一由审批按钮触发 approvalVerifyOpen → openScoreDialog -->
|
|
|
|
|
<!-- <el-button
|
|
|
|
|
<!-- <el-button
|
|
|
|
|
v-if="canScoreClose"
|
|
|
|
|
type="warning"
|
|
|
|
|
plain
|
|
|
|
|
@ -263,12 +283,17 @@
|
|
|
|
|
|
|
|
|
|
<el-dialog v-model="memberDialog.visible" title="新增协作人" width="620px" append-to-body>
|
|
|
|
|
<el-form ref="memberFormRef" :model="memberForm" :rules="memberRules" label-width="120px">
|
|
|
|
|
<el-form-item label="协作人" prop="userName">
|
|
|
|
|
<!-- <el-form-item label="协作人" prop="userName">
|
|
|
|
|
<el-input v-model="memberForm.userName" readonly placeholder="请选择协作人">
|
|
|
|
|
<template #suffix>
|
|
|
|
|
<el-icon class="cursor-pointer" @click="openUserSelect('member')"><Search /></el-icon>
|
|
|
|
|
</template>
|
|
|
|
|
</el-input>
|
|
|
|
|
</el-form-item>-->
|
|
|
|
|
<el-form-item label="协作人" prop="userId">
|
|
|
|
|
<el-select v-model="memberForm.userId" placeholder="请选择协作人" clearable filterable @change="handleMemberUserChange">
|
|
|
|
|
<el-option v-for="user in userList" :key="user.userId" :label="user.nickName" :value="user.userId" />
|
|
|
|
|
</el-select>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item label="协作说明" prop="joinRemark">
|
|
|
|
|
<el-input v-model="memberForm.joinRemark" type="textarea" :rows="3" placeholder="请输入协作事项说明" />
|
|
|
|
|
@ -351,7 +376,7 @@
|
|
|
|
|
<submitVerify ref="submitVerifyRef" :task-variables="taskVariables" @submit-callback="submitCallback" />
|
|
|
|
|
<approvalRecord ref="approvalRecordRef" />
|
|
|
|
|
<ProjectSelect ref="projectSelectRef" :multiple="false" @confirm-call-back="handleProjectSelect" />
|
|
|
|
|
<UserSelect ref="userSelectRef" :multiple="userSelectMode === 'cc'" @confirm-call-back="handleUserSelect" />
|
|
|
|
|
<!-- <UserSelect ref="userSelectRef" :multiple="userSelectMode === 'cc'" @confirm-call-back="handleUserSelect" />-->
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
@ -386,17 +411,18 @@ import type {
|
|
|
|
|
import type { ProjectInfoVO } from '@/api/oa/erp/projectInfo/types';
|
|
|
|
|
import type { DeptVO } from '@/api/system/dept/types';
|
|
|
|
|
import { allListDept } from '@/api/system/dept';
|
|
|
|
|
import { getUserList } from '@/api/system/user';
|
|
|
|
|
import { getTask } from '@/api/workflow/task';
|
|
|
|
|
import { FlowCodeEnum } from '@/enums/OAEnum';
|
|
|
|
|
import ApprovalButton from '@/components/Process/approvalButton.vue';
|
|
|
|
|
import SubmitVerify from '@/components/Process/submitVerify.vue';
|
|
|
|
|
import ApprovalRecord from '@/components/Process/approvalRecord.vue';
|
|
|
|
|
import ProjectSelect from '@/components/ProjectSelect/index.vue';
|
|
|
|
|
import UserSelect from '@/components/UserSelect/index.vue';
|
|
|
|
|
// import UserSelect from '@/components/UserSelect/index.vue';
|
|
|
|
|
import FileUpload from '@/components/FileUpload/index.vue';
|
|
|
|
|
import OssFilePreview from '@/components/OssFilePreview/index.vue';
|
|
|
|
|
|
|
|
|
|
type UserSelectMode = 'assignee' | 'realRequester' | 'member' | 'cc';
|
|
|
|
|
// type UserSelectMode = 'assignee' | 'realRequester' | 'member' | 'cc';
|
|
|
|
|
|
|
|
|
|
const { proxy } = getCurrentInstance() as any;
|
|
|
|
|
const route = useRoute();
|
|
|
|
|
@ -416,9 +442,11 @@ const scoreFormRef = ref<ElFormInstance>();
|
|
|
|
|
const submitVerifyRef = ref<InstanceType<typeof SubmitVerify>>();
|
|
|
|
|
const approvalRecordRef = ref<InstanceType<typeof ApprovalRecord>>();
|
|
|
|
|
const projectSelectRef = ref<InstanceType<typeof ProjectSelect>>();
|
|
|
|
|
const userSelectRef = ref<InstanceType<typeof UserSelect>>();
|
|
|
|
|
|
|
|
|
|
const userSelectMode = ref<UserSelectMode>('assignee');
|
|
|
|
|
// const userSelectRef = ref<InstanceType<typeof UserSelect>>();
|
|
|
|
|
// const userSelectMode = ref<UserSelectMode>('assignee');
|
|
|
|
|
const userList = ref<Array<Record<string, any>>>([]);
|
|
|
|
|
|
|
|
|
|
const taskVariables = ref<Record<string, unknown>>({});
|
|
|
|
|
const currentNodeCode = ref<string>('');
|
|
|
|
|
const deptList = ref<DeptVO[]>([]);
|
|
|
|
|
@ -469,7 +497,7 @@ const rules: ElFormRules = {
|
|
|
|
|
taskTitle: [{ required: true, message: '任务标题不能为空', trigger: 'blur' }],
|
|
|
|
|
taskDesc: [{ required: true, message: '任务描述不能为空', trigger: 'blur' }],
|
|
|
|
|
taskType: [{ required: true, message: '任务类型不能为空', trigger: 'change' }],
|
|
|
|
|
realRequesterName: [{ required: true, message: '实际需求人不能为空', trigger: 'change' }],
|
|
|
|
|
realRequesterId: [{ required: true, message: '实际需求人不能为空', trigger: 'change' }],
|
|
|
|
|
planStartTime: [{ required: true, message: '计划开始时间不能为空', trigger: 'change' }],
|
|
|
|
|
planEndTime: [{ required: true, message: '计划完成时间不能为空', trigger: 'change' }],
|
|
|
|
|
realRequestDeptId: [{ required: true, message: '实际需求部门不能为空', trigger: 'change' }],
|
|
|
|
|
@ -502,7 +530,7 @@ const rules: ElFormRules = {
|
|
|
|
|
const memberDialog = reactive({ visible: false });
|
|
|
|
|
const memberForm = ref<TempTaskMemberForm>({});
|
|
|
|
|
const memberRules: ElFormRules = {
|
|
|
|
|
userName: [{ required: true, message: '协作人不能为空', trigger: 'change' }]
|
|
|
|
|
userId: [{ required: true, message: '协作人不能为空', trigger: 'change' }]
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const worklogDialog = reactive({ visible: false });
|
|
|
|
|
@ -538,9 +566,10 @@ const scoreForm = ref<TempTaskScoreSubmitForm>({
|
|
|
|
|
// leader_review/assignee_review 节点审批人可修正业务数据;
|
|
|
|
|
// execute 工作流节点同样保持可编辑。
|
|
|
|
|
const isFormReadOnly = computed(
|
|
|
|
|
() => pageType.value === 'view'
|
|
|
|
|
|| pageType.value === 'execute'
|
|
|
|
|
|| (pageType.value === 'approval' && !['leader_review', 'assignee_review', 'execute'].includes(currentNodeCode.value))
|
|
|
|
|
() =>
|
|
|
|
|
pageType.value === 'view' ||
|
|
|
|
|
pageType.value === 'execute' ||
|
|
|
|
|
(pageType.value === 'approval' && !['leader_review', 'assignee_review', 'execute'].includes(currentNodeCode.value))
|
|
|
|
|
);
|
|
|
|
|
/**
|
|
|
|
|
* 是否允许管理协作人(新增/移除)。
|
|
|
|
|
@ -624,10 +653,20 @@ const getDeptList = async () => {
|
|
|
|
|
deptList.value = res.data || [];
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/** 查询用户列表,用于下拉选人 */
|
|
|
|
|
const getUserSelectList = async () => {
|
|
|
|
|
const res = await getUserList({} as any);
|
|
|
|
|
userList.value = res.data || [];
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const findDept = (deptId?: string | number) => {
|
|
|
|
|
return deptList.value.find((dept) => dept.deptId === deptId);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const findUser = (userId?: string | number) => {
|
|
|
|
|
return userList.value.find((user) => String(user.userId) === String(userId));
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handleTaskDeptChange = (deptId?: string | number) => {
|
|
|
|
|
form.value.deptName = findDept(deptId)?.deptName;
|
|
|
|
|
};
|
|
|
|
|
@ -636,6 +675,29 @@ const handleRealDeptChange = (deptId?: string | number) => {
|
|
|
|
|
form.value.realRequestDeptName = findDept(deptId)?.deptName;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/** 实际需求人下拉变更:回填姓名和部门 */
|
|
|
|
|
const handleRealRequesterChange = (userId?: string | number) => {
|
|
|
|
|
const user = findUser(userId);
|
|
|
|
|
form.value.realRequesterName = user?.nickName;
|
|
|
|
|
if (user?.deptId) {
|
|
|
|
|
form.value.realRequestDeptId = user.deptId;
|
|
|
|
|
form.value.realRequestDeptName = user.deptName;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/** 主执行人下拉变更:回填姓名 */
|
|
|
|
|
const handleAssigneeChange = (userId?: string | number) => {
|
|
|
|
|
const user = findUser(userId);
|
|
|
|
|
form.value.assigneeName = user?.nickName;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/** 协作人下拉变更:回填姓名和部门 */
|
|
|
|
|
const handleMemberUserChange = (userId?: string | number) => {
|
|
|
|
|
const user = findUser(userId);
|
|
|
|
|
memberForm.value.userName = user?.nickName;
|
|
|
|
|
memberForm.value.memberDeptId = user?.deptId;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 监听 taskType 切换,联动清除不适用的表单字段。
|
|
|
|
|
* - 切换到非项目类型(taskType !== '3'):清除项目相关字段,避免脏数据带入提交
|
|
|
|
|
@ -674,15 +736,15 @@ const handleProjectSelect = (data: ProjectInfoVO[]) => {
|
|
|
|
|
form.value.projectName = project.projectName;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const openUserSelect = (mode: UserSelectMode) => {
|
|
|
|
|
if (isFormReadOnly.value && mode !== 'member') {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
userSelectMode.value = mode;
|
|
|
|
|
userSelectRef.value?.open();
|
|
|
|
|
};
|
|
|
|
|
// const openUserSelect = (mode: UserSelectMode) => {
|
|
|
|
|
// if (isFormReadOnly.value && mode !== 'member') {
|
|
|
|
|
// return;
|
|
|
|
|
// }
|
|
|
|
|
// userSelectMode.value = mode;
|
|
|
|
|
// userSelectRef.value?.open();
|
|
|
|
|
// };
|
|
|
|
|
|
|
|
|
|
const handleUserSelect = (users: Array<Record<string, any>>) => {
|
|
|
|
|
/*const handleUserSelect = (users: Array<Record<string, any>>) => {
|
|
|
|
|
const selected = users?.[0];
|
|
|
|
|
if (!selected) {
|
|
|
|
|
return;
|
|
|
|
|
@ -706,7 +768,7 @@ const handleUserSelect = (users: Array<Record<string, any>>) => {
|
|
|
|
|
} else {
|
|
|
|
|
form.value.ccUserIds = users.map((item) => item.userId).join(',');
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
};*/
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 从专用子表端点加载参与人/工时/评分列表(AD-13/AD-16)。
|
|
|
|
|
@ -1135,6 +1197,7 @@ onMounted(async () => {
|
|
|
|
|
try {
|
|
|
|
|
pageType.value = (route.query.type as string) || 'add';
|
|
|
|
|
await getDeptList();
|
|
|
|
|
await getUserSelectList();
|
|
|
|
|
await loadCurrentWorkflowTask();
|
|
|
|
|
const id = route.query.id as string | number | undefined;
|
|
|
|
|
const taskId = route.query.taskId as string | number | undefined;
|
|
|
|
|
|