refactor(xispeak): 默认审批意见改为节点配置 + 新增用户名解析

- 移除前端写死的 handleReasonTemplateMap,改为走 BPM_NODE_PERMISSIONS 节点配置的 defaultOpinion
- 新增 useSelectNameResolver 翻译 responsiblePerson/implDept/sdwLeaderList 为 Names 字段
- 新增 subApproveUserNames 变量,@confirm 事件即时获取经办人 realname
- 新增 isEnd 反向同步到 formData.vars,供 conditionalDefaultOpinion 条件变量判断
- 监察按钮文案条件改为 showJiJianFields && nonJiJianFieldsReadonly

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
wsm
2026-07-02 16:36:47 +08:00
co-authored by Claude Opus 4.7
parent 747084586b
commit 058344d99e
@@ -58,7 +58,7 @@
</a-col>
<a-col :span="12">
<a-form-item label="责任人" name="responsiblePerson">
<j-select-user v-model:value="mainForm.responsiblePerson" :disabled="mainDisabled" allow-clear />
<j-select-user v-model:value="mainForm.responsiblePerson" :disabled="mainDisabled" allow-clear @select="selectHandler('responsiblePerson')" />
</a-form-item>
</a-col>
<a-col :span="12">
@@ -213,7 +213,7 @@
<span v-else>-</span>
</template>
<template v-if="column.key === 'feedbackAction'">
<a-button type="link" size="small" @click="handleEditFeedback(record)">{{ showJiJianFields ? '监察' : '编辑' }}</a-button>
<a-button type="link" size="small" @click="handleEditFeedback(record)">{{ showJiJianFields && nonJiJianFieldsReadonly ? '监察' : '编辑' }}</a-button>
<a-popconfirm title="确定删除该反馈吗?" @confirm="handleDeleteFeedback(record)">
<a-button type="link" size="small" danger>删除</a-button>
</a-popconfirm>
@@ -246,7 +246,7 @@
</a-col>
<a-col v-if="showSubApproveUserSelector" :span="12">
<a-form-item label="部门经办人" :labelCol="wideLabelCol" :wrapperCol="wideWrapperCol">
<sz-dept-user-modal v-model:value="subApproveUser" :disabled="savingSubApproveUser" />
<sz-dept-user-modal v-model:value="subApproveUser" :disabled="savingSubApproveUser" @confirm="onSubApproveUserConfirm" />
</a-form-item>
</a-col>
</a-row>
@@ -256,7 +256,6 @@
:claim="claim"
:showSelnextUser="showSelnextUser"
:beforeHandle="saveMainFormBeforeProcessHandle"
:defaultReason="defaultHandleReason"
@success="handleProcessSuccess"
@claimSuccess="handleClaimSuccess"
/>
@@ -285,16 +284,8 @@
import SUploadFile from '/@/components/semri/fileComponent/SUploadFile.vue';
import DeptRoleUserSelectRadioGroup from '/@/components/semri/userComponent/DeptRoleUserSelectRadioGroup.vue';
import { PARTY_COMMITTEE_DEPT_ID, SDW_LEADER_ROLE_ID } from '/@/constant/supervision';
import {
buildApproveReason,
buildDeptHandlerFeedbackReason,
buildDeptLeaderAssignReason,
buildDeptLeaderDirectFeedbackReason,
buildSuperviseConfirmAllReason,
buildSuperviseCheckReason,
buildJiJianCheckReason,
normalizeDeptNames,
} from '/@/composables/useDefaultApprovalReason';
import { normalizeDeptNames } from '/@/composables/useDefaultApprovalReason';
import { useSelectNameResolver } from '/@/composables/useSelectNameResolver';
const { isDisabledAuth, hasPermission, initBpmFormData } = usePermission();
const userStore = useUserStore();
@@ -329,7 +320,7 @@ import {
const showFeedbackDetail = ref(true);
const feedbackList = ref<any[]>([]);
const subApproveUser = ref('');
const subApproveUserNameText = ref('');
const subApproveUserNames = ref('');
const userResolveVersion = ref(0);
const isEnd = ref(0);
@@ -342,8 +333,10 @@ import {
status: '',
secretLevel: '',
responsiblePerson: '',
responsiblePersonNames: '',
needSdwApproval: 0,
sdwLeaderList: '',
sdwLeaderListNames: '',
implPlan: '',
implMeasures: '',
numberOfResolutions: undefined,
@@ -356,12 +349,19 @@ import {
completionStatus: undefined,
deadline: '',
implDept: '',
implDeptNames: '',
treeDepth: undefined,
sortOrder: undefined,
bpmStatus: '',
supervisionCount: undefined,
});
const { resolveAll, selectHandler } = useSelectNameResolver(mainForm, [
{ field: 'responsiblePerson', type: 'user' },
{ field: 'implDept', type: 'dept' },
{ field: 'sdwLeaderList', type: 'user' },
]);
const feedbackColumns = computed(() => {
const cols: any[] = [
{ title: '序号', key: 'seq', align: 'center', width: 60 },
@@ -445,59 +445,19 @@ import {
processTableName: props.formData?.processTableName,
}));
// ==================== 默认审批意见 ====================
const handleReasonTemplateMap: Record<string, () => string> = {
// 部门负责人审批 / 所党委审批 / 督办部门负责人审批 / 纪检负责人审批
Task_15sm4w5: buildApproveReason,
Task_00i7rrp: buildApproveReason,
Task_04bazej: buildApproveReason,
Task_0bj578x: buildApproveReason,
Task_0mf32ge: buildApproveReason,
Task_0zmn6ik: buildApproveReason,
Task_133caii: buildApproveReason,
Task_175afz2: buildApproveReason,
Task_1ogk921: buildApproveReason,
Task_1w4vxgc: buildApproveReason,
Task_1wfkrvj: buildApproveReason,
// 反馈流程节点
Task_005iiwi: buildApproveReason,
Task_06di2wf: buildApproveReason,
Task_1l650tz: buildApproveReason,
// 部门经办人反馈完成情况 / 收集流程部门经办人填写 / 反馈流程部门经办人填写反馈
Task_00v3pcv: buildDeptHandlerFeedbackReason,
Task_08zb04x: buildDeptHandlerFeedbackReason,
Task_0jrgrzs: buildDeptHandlerFeedbackReason,
Task_12vdqzv: buildDeptHandlerFeedbackReason,
// 部门负责人接受任务并分配
Task_1v9ce78: () => buildDeptLeaderAssignReason(
normalizeDeptNames(subApproveUserNameText.value || subApproveUser.value),
),
// 部门负责人直接反馈
Task_0sialna: buildDeptLeaderDirectFeedbackReason,
// 督办部门经办人确认全部反馈事项
// (暂无映射,预留 buildSuperviseConfirmAllReason)
// 督办经办人核查 / 反馈流程督办经办人核查
Task_13olnz1: buildSuperviseCheckReason,
// 纪检经办人监察
Task_0bahwr8: buildJiJianCheckReason,
};
const defaultHandleReason = computed(() => {
const builder = handleReasonTemplateMap[String(processInfo.value.taskDefKey || '')];
return builder ? builder() : '';
});
// 合并 mainForm + 表单局部变量,供占位符 ${变量名} 解析
const formScope = computed(() => ({
...mainForm,
isEnd: isEnd.value,
subApproveUser: subApproveUser.value,
subApproveUserNameText: subApproveUserNameText.value,
subApproveUserNames: subApproveUserNames.value,
responsiblePersonNames: mainForm.responsiblePersonNames,
implDeptNames: mainForm.implDeptNames,
sdwLeaderListNames: mainForm.sdwLeaderListNames,
}));
provide('extraVars', formScope);
provide('flowVars', computed(() => props.formData?.vars || {}));
provide('formDefaultReason', defaultHandleReason);
onMounted(() => {
initFormData();
@@ -525,6 +485,14 @@ import {
},
{ immediate: true }
);
// 反向同步:本地切换 isEnd 时更新 formData.vars,使 conditionalDefaultOpinion 响应
watch(isEnd, (val) => {
const vars = props.formData?.vars;
if (vars) {
vars.is_end = String(val);
vars.isEnd = String(val);
}
});
watch(
subApproveUser,
@@ -544,6 +512,7 @@ import {
try {
const data = await defHttp.get({ url: queryByIdUrl, params: { id: dataId } });
setMainForm(data || {});
await resolveAll();
await loadFeedbackList();
} finally {
loading.value = false;
@@ -771,15 +740,19 @@ import {
.join(',');
}
function onSubApproveUserConfirm(userIds: string, realnames: string) {
subApproveUserNames.value = normalizeDeptNames(realnames || '');
}
async function resolveSubApproveUserName(value: any) {
const resolveVersion = ++userResolveVersion.value;
const usernames = normalizeUsernameList(value);
if (!usernames) {
subApproveUserNameText.value = '';
subApproveUserNames.value = '';
return;
}
subApproveUserNameText.value = normalizeDeptNames(usernames);
subApproveUserNames.value = normalizeDeptNames(usernames);
try {
const res = await getUserList({ username: usernames, isMultiTranslate: 'true', pageNo: 1, pageSize: 999 });
if (resolveVersion !== userResolveVersion.value) {
@@ -800,10 +773,10 @@ import {
.split(',')
.map((username) => userNameMap[username] || username)
.filter(Boolean);
subApproveUserNameText.value = normalizeDeptNames(names.join(','));
subApproveUserNames.value = normalizeDeptNames(names.join(','));
} catch {
if (resolveVersion === userResolveVersion.value) {
subApproveUserNameText.value = normalizeDeptNames(usernames);
subApproveUserNames.value = normalizeDeptNames(usernames);
}
}
}