refactor(oa/erp/tempTask): 优化任务编辑页面选人组件实现

1.  将原有的只读输入框切换为下拉选择器,替换旧的UserSelect组件
2.  新增用户列表查询与选人逻辑,优化实际需求人、主执行人、协作人选择体验
3.  注释并移除冗余的旧选人相关代码,调整表单校验规则
4.  调整查询表单中任务描述项的展示状态
dev^2
zch 4 days ago
parent 51456dba5c
commit 196a2f3a3e

@ -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;

@ -7,9 +7,9 @@
<el-form-item label="任务编号" prop="tempTaskCode">
<el-input v-model="queryParams.tempTaskCode" placeholder="请输入任务编号" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="任务描述" prop="taskDesc">
<!-- <el-form-item label="任务描述" prop="taskDesc">
<el-input v-model="queryParams.taskDesc" placeholder="请输入任务描述" clearable @keyup.enter="handleQuery" />
</el-form-item>
</el-form-item>-->
<el-form-item label="任务类型" prop="taskType">
<el-select v-model="queryParams.taskType" placeholder="请选择任务类型" clearable>
<el-option v-for="dict in temp_task_type" :key="dict.value" :label="dict.label" :value="dict.value" />

Loading…
Cancel
Save