!74 fix(bpm): 修复选人组件 Name 翻译使用错误字段及查询顺序问题
* fix(bpm): 修复选人组件 Name 翻译使用错误字段及查询顺序问题 * feat(bpm): 默认审批意见改为完全由后端节点配置驱动,移除所有写死模板 * fix(bpm): 修复节点默认审批意见配置 UI 绑定错误,支持 extraVars 变量解析 * feat(bpm): 新增条件变量默认审批意见,支持按流程变量值动态预填审批意见
This commit is contained in:
@@ -56,7 +56,7 @@
|
|||||||
},
|
},
|
||||||
//update-end---author:wangshuai ---date:20230703 for:【QQYUN-5685】5、离职人员可以选自己------------
|
//update-end---author:wangshuai ---date:20230703 for:【QQYUN-5685】5、离职人员可以选自己------------
|
||||||
},
|
},
|
||||||
emits: ['options-change', 'change', 'update:value'],
|
emits: ['options-change', 'change', 'select', 'update:value'],
|
||||||
setup(props, { emit }) {
|
setup(props, { emit }) {
|
||||||
const emitData = ref<any[]>();
|
const emitData = ref<any[]>();
|
||||||
//注册model
|
//注册model
|
||||||
@@ -99,6 +99,15 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 监听selectOptions变化,对外暴露选中的 option 对象
|
||||||
|
*/
|
||||||
|
watch(selectOptions, () => {
|
||||||
|
if (selectOptions.value) {
|
||||||
|
emit('select', toRaw(unref(selectOptions)), toRaw(unref(selectValues)));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 监听selectValues变化
|
* 监听selectValues变化
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -0,0 +1,108 @@
|
|||||||
|
import { queryDepartTreeSync, getUserList } from '/@/api/common/api';
|
||||||
|
|
||||||
|
interface NameFieldConfig {
|
||||||
|
/** Names 后缀的基础字段名,如 'measureResDept' → 写入 target['measureResDeptNames'] */
|
||||||
|
field: string;
|
||||||
|
/** 'dept' | 'user' */
|
||||||
|
type: 'dept' | 'user';
|
||||||
|
/** 自定义取值器,默认读取 target[field] */
|
||||||
|
getValue?: () => string;
|
||||||
|
}
|
||||||
|
|
||||||
|
function flatDeptTree(list: any[]): Record<string, string> {
|
||||||
|
const map: Record<string, string> = {};
|
||||||
|
for (const item of list) {
|
||||||
|
if (item.id && item.departName) {
|
||||||
|
map[item.id] = item.departName;
|
||||||
|
}
|
||||||
|
if (item.children?.length) {
|
||||||
|
Object.assign(map, flatDeptTree(item.children));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 选人/选部门字段名称翻译器。
|
||||||
|
* - resolveAll() 通过 API 批量翻译,在表单数据加载后调用
|
||||||
|
* - selectHandler(field) 生成 @select 事件处理器,用于运行时更新
|
||||||
|
*/
|
||||||
|
export function useSelectNameResolver(
|
||||||
|
target: Record<string, any>,
|
||||||
|
configs: NameFieldConfig[]
|
||||||
|
) {
|
||||||
|
async function resolveAll() {
|
||||||
|
try {
|
||||||
|
const deptConfigs = configs.filter(c => c.type === 'dept');
|
||||||
|
const userConfigs = configs.filter(c => c.type === 'user');
|
||||||
|
|
||||||
|
if (deptConfigs.length) {
|
||||||
|
// 收集所有 dept IDs
|
||||||
|
const allDeptIds = new Set<string>();
|
||||||
|
for (const c of deptConfigs) {
|
||||||
|
const val = c.getValue ? c.getValue() : target[c.field];
|
||||||
|
const ids = String(val || '').split(',').map((s: string) => s.trim()).filter(Boolean);
|
||||||
|
ids.forEach(id => allDeptIds.add(id));
|
||||||
|
}
|
||||||
|
if (allDeptIds.size) {
|
||||||
|
const tree = await queryDepartTreeSync({ ids: [...allDeptIds].join(',') });
|
||||||
|
const deptMap = flatDeptTree(tree || []);
|
||||||
|
for (const c of deptConfigs) {
|
||||||
|
const val = c.getValue ? c.getValue() : target[c.field];
|
||||||
|
const ids = String(val || '').split(',').map((s: string) => s.trim()).filter(Boolean);
|
||||||
|
target[c.field + 'Names'] = ids.map(id => deptMap[id] || id).join('、');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (userConfigs.length) {
|
||||||
|
const allUserIds = new Set<string>();
|
||||||
|
for (const c of userConfigs) {
|
||||||
|
const val = c.getValue ? c.getValue() : target[c.field];
|
||||||
|
const ids = String(val || '').split(',').map((s: string) => s.trim()).filter(Boolean);
|
||||||
|
ids.forEach(id => allUserIds.add(id));
|
||||||
|
}
|
||||||
|
if (allUserIds.size) {
|
||||||
|
const idList = [...allUserIds];
|
||||||
|
const userMap: Record<string, string> = {};
|
||||||
|
|
||||||
|
// 先按 id 查
|
||||||
|
const idRes = await getUserList({ id: idList.join(','), isMultiTranslate: 'true', pageNo: 1, pageSize: 999 });
|
||||||
|
const idRecords = idRes?.records || idRes?.result?.records || [];
|
||||||
|
for (const u of idRecords) {
|
||||||
|
if (u.id && u.realname) userMap[String(u.id)] = u.realname;
|
||||||
|
if (u.username && u.realname) userMap[u.username] = u.realname;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 未匹配到的再按 username 查
|
||||||
|
const unmatched = idList.filter(id => !userMap[id]);
|
||||||
|
if (unmatched.length) {
|
||||||
|
const nameRes = await getUserList({ username: unmatched.join(','), isMultiTranslate: 'true', pageNo: 1, pageSize: 999 });
|
||||||
|
const nameRecords = nameRes?.records || nameRes?.result?.records || [];
|
||||||
|
for (const u of nameRecords) {
|
||||||
|
if (u.username && u.realname) userMap[u.username] = u.realname;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const c of userConfigs) {
|
||||||
|
const val = c.getValue ? c.getValue() : target[c.field];
|
||||||
|
const ids = String(val || '').split(',').map((s: string) => s.trim()).filter(Boolean);
|
||||||
|
target[c.field + 'Names'] = ids.map(id => userMap[id] || id).join('、');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.warn('【Name解析】resolveAll 翻译失败,占位符将显示 ID:', e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function selectHandler(field: string) {
|
||||||
|
const cfg = configs.find(c => c.field === field);
|
||||||
|
const nameKey = cfg?.type === 'user' ? 'realname' : cfg?.type === 'dept' ? 'departName' : 'label';
|
||||||
|
return (options: Array<Record<string, any>>) => {
|
||||||
|
target[field + 'Names'] = options?.length ? options.map(o => o[nameKey] || o.label || '').join('、') : '';
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return { resolveAll, selectHandler };
|
||||||
|
}
|
||||||
@@ -266,7 +266,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, onMounted, reactive, ref, watch } from 'vue';
|
import { computed, onMounted, reactive, ref, watch, provide } from 'vue';
|
||||||
import { defHttp } from '/@/utils/http/axios';
|
import { defHttp } from '/@/utils/http/axios';
|
||||||
|
|
||||||
import { useMessage } from '/@/hooks/web/useMessage';
|
import { useMessage } from '/@/hooks/web/useMessage';
|
||||||
@@ -487,6 +487,18 @@ import {
|
|||||||
return builder ? builder() : '';
|
return builder ? builder() : '';
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 合并 mainForm + 表单局部变量,供占位符 ${变量名} 解析
|
||||||
|
const formScope = computed(() => ({
|
||||||
|
...mainForm,
|
||||||
|
isEnd: isEnd.value,
|
||||||
|
subApproveUser: subApproveUser.value,
|
||||||
|
subApproveUserNameText: subApproveUserNameText.value,
|
||||||
|
}));
|
||||||
|
|
||||||
|
provide('extraVars', formScope);
|
||||||
|
provide('flowVars', computed(() => props.formData?.vars || {}));
|
||||||
|
provide('formDefaultReason', defaultHandleReason);
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
initFormData();
|
initFormData();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -72,17 +72,17 @@
|
|||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="12">
|
<a-col :span="12">
|
||||||
<a-form-item label="措施责任领导" name="measureResLeader">
|
<a-form-item label="措施责任领导" name="measureResLeader">
|
||||||
<j-select-user v-model:value="mainForm.measureResLeader" :disabled="mainDisabled" allow-clear />
|
<j-select-user v-model:value="mainForm.measureResLeader" :disabled="mainDisabled" allow-clear @select="selectHandler('measureResLeader')" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="12">
|
<a-col :span="12">
|
||||||
<a-form-item label="措施责任部门" name="measureResDept">
|
<a-form-item label="措施责任部门" name="measureResDept">
|
||||||
<j-select-dept v-model:value="mainForm.measureResDept" :disabled="mainDisabled" :multiple="true" checkStrictly allow-clear />
|
<j-select-dept v-model:value="mainForm.measureResDept" :disabled="mainDisabled" :multiple="true" checkStrictly allow-clear @select="selectHandler('measureResDept')" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="12">
|
<a-col :span="12">
|
||||||
<a-form-item label="分管所领导" name="chargeLeaderId">
|
<a-form-item label="分管所领导" name="chargeLeaderId">
|
||||||
<j-select-user v-model:value="mainForm.chargeLeaderId" :disabled="mainDisabled" allow-clear />
|
<j-select-user v-model:value="mainForm.chargeLeaderId" :disabled="mainDisabled" allow-clear @select="selectHandler('chargeLeaderId')" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="12">
|
<a-col :span="12">
|
||||||
@@ -102,7 +102,7 @@
|
|||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="12">
|
<a-col :span="12">
|
||||||
<a-form-item label="党群领导" name="supDeptleaderid">
|
<a-form-item label="党群领导" name="supDeptleaderid">
|
||||||
<j-select-user v-model:value="mainForm.supDeptleaderid" :disabled="mainDisabled" allow-clear />
|
<j-select-user v-model:value="mainForm.supDeptleaderid" :disabled="mainDisabled" allow-clear @select="selectHandler('supDeptleaderid')" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="12">
|
<a-col :span="12">
|
||||||
@@ -194,34 +194,33 @@
|
|||||||
</a-col>
|
</a-col>
|
||||||
<a-col v-if="showSubApproveUserSelector" :span="12">
|
<a-col v-if="showSubApproveUserSelector" :span="12">
|
||||||
<a-form-item label="部门经办人" :labelCol="wideLabelCol" :wrapperCol="wideWrapperCol">
|
<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>
|
|
||||||
</a-form>
|
|
||||||
<a-form v-if="showIsNeedLeaderApprove" class="process-variable-form" labelAlign="left" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
|
||||||
<a-row :gutter="16">
|
|
||||||
<a-col :span="12">
|
|
||||||
<a-form-item label="是否需要所领导审批" :labelCol="wideLabelCol" :wrapperCol="wideWrapperCol">
|
|
||||||
<a-radio-group v-model:value="isNeedLeaderApprove" :disabled="savingIsNeedLeaderApprove">
|
|
||||||
<a-radio :value="0">否(不需要)</a-radio>
|
|
||||||
<a-radio :value="1">是(需要所领导审批)</a-radio>
|
|
||||||
</a-radio-group>
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
<a-col v-if="showIsNeedLeaderApproveSelector" :span="12">
|
|
||||||
<a-form-item label="分管所领导" :labelCol="wideLabelCol" :wrapperCol="wideWrapperCol">
|
|
||||||
<j-select-user v-model:value="leaderApproveUser" :disabled="savingIsNeedLeaderApprove" allow-clear />
|
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
</a-form>
|
</a-form>
|
||||||
|
<!-- <a-form v-if="showIsNeedLeaderApprove" class="process-variable-form" labelAlign="left" :labelCol="labelCol" :wrapperCol="wrapperCol">-->
|
||||||
|
<!-- <a-row :gutter="16">-->
|
||||||
|
<!-- <a-col :span="12">-->
|
||||||
|
<!-- <a-form-item label="是否需要所领导审批" :labelCol="wideLabelCol" :wrapperCol="wideWrapperCol">-->
|
||||||
|
<!-- <a-radio-group v-model:value="isNeedLeaderApprove" :disabled="savingIsNeedLeaderApprove">-->
|
||||||
|
<!-- <a-radio :value="0">否(不需要)</a-radio>-->
|
||||||
|
<!-- <a-radio :value="1">是(需要所领导审批)</a-radio>-->
|
||||||
|
<!-- </a-radio-group>-->
|
||||||
|
<!-- </a-form-item>-->
|
||||||
|
<!-- </a-col>-->
|
||||||
|
<!-- <a-col v-if="showIsNeedLeaderApproveSelector" :span="12">-->
|
||||||
|
<!-- <a-form-item label="分管所领导" :labelCol="wideLabelCol" :wrapperCol="wideWrapperCol">-->
|
||||||
|
<!-- <j-select-user v-model:value="leaderApproveUser" :disabled="savingIsNeedLeaderApprove" allow-clear @select="selectHandler('leaderApproveUser')" />-->
|
||||||
|
<!-- </a-form-item>-->
|
||||||
|
<!-- </a-col>-->
|
||||||
|
<!-- </a-row>-->
|
||||||
|
<!-- </a-form>-->
|
||||||
<TaskHandleInnerContent
|
<TaskHandleInnerContent
|
||||||
:form-data="formData"
|
:form-data="formData"
|
||||||
:claim="claim"
|
:claim="claim"
|
||||||
:showSelnextUser="showSelnextUser"
|
:showSelnextUser="showSelnextUser"
|
||||||
:beforeHandle="saveMainFormBeforeProcessHandle"
|
:beforeHandle="saveMainFormBeforeProcessHandle"
|
||||||
:defaultReason="defaultHandleReason"
|
|
||||||
:defaultCc="defaultCcUsers"
|
:defaultCc="defaultCcUsers"
|
||||||
@success="handleProcessSuccess"
|
@success="handleProcessSuccess"
|
||||||
@claimSuccess="handleClaimSuccess"
|
@claimSuccess="handleClaimSuccess"
|
||||||
@@ -232,7 +231,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, onMounted, reactive, ref, watch } from 'vue';
|
import { computed, onMounted, reactive, ref, watch, provide } from 'vue';
|
||||||
import { defHttp } from '/@/utils/http/axios';
|
import { defHttp } from '/@/utils/http/axios';
|
||||||
import { useMessage } from '/@/hooks/web/useMessage';
|
import { useMessage } from '/@/hooks/web/useMessage';
|
||||||
import { useUserStore } from '/@/store/modules/user';
|
import { useUserStore } from '/@/store/modules/user';
|
||||||
@@ -245,23 +244,7 @@ import SzDeptUserModal from '/@/components/semri/deptUserComponent/SzDeptUserMod
|
|||||||
import { list as progressList, deleteOne as progressDelete } from '../../inspectProgress/DqInspectProgress.api';
|
import { list as progressList, deleteOne as progressDelete } from '../../inspectProgress/DqInspectProgress.api';
|
||||||
import { usePermission } from '/@/hooks/web/usePermission';
|
import { usePermission } from '/@/hooks/web/usePermission';
|
||||||
import { PARTY_COMMITTEE_DEPT_ID, SDW_LEADER_ROLE_ID } from '/@/constant/supervision';
|
import { PARTY_COMMITTEE_DEPT_ID, SDW_LEADER_ROLE_ID } from '/@/constant/supervision';
|
||||||
import {
|
import { useSelectNameResolver } from '/@/composables/useSelectNameResolver';
|
||||||
buildApproveReason,
|
|
||||||
buildDeptHandlerFeedbackReason,
|
|
||||||
buildCollectDoneReason,
|
|
||||||
buildSecretaryApprovedReason,
|
|
||||||
buildDisciplineSecretaryApprovedReason,
|
|
||||||
buildDeptLeaderApprovedReason,
|
|
||||||
buildChargeDeptApprovedReason,
|
|
||||||
buildChargeLeaderApprovedReason,
|
|
||||||
buildAlreadyApprovedReason,
|
|
||||||
buildAlreadyReviewedReason,
|
|
||||||
buildPleaseDeptHandleReason,
|
|
||||||
buildLaunchSupervisionReason,
|
|
||||||
buildPartyMassesConfirmedReason,
|
|
||||||
buildAssignProcessReason,
|
|
||||||
buildJiJianCheckedReason,
|
|
||||||
} from '/@/composables/useDefaultApprovalReason';
|
|
||||||
import TaskHandleInnerContent from '/@/views/super/bpm/process/personalOffice/myHandleTask/content/TaskHandleInnerContent.vue';
|
import TaskHandleInnerContent from '/@/views/super/bpm/process/personalOffice/myHandleTask/content/TaskHandleInnerContent.vue';
|
||||||
import DqInspectTaskBPMFeedbackModal from './DqInspectTaskBPMFeedbackModal.vue';
|
import DqInspectTaskBPMFeedbackModal from './DqInspectTaskBPMFeedbackModal.vue';
|
||||||
import SUploadFile from '/@/components/semri/fileComponent/SUploadFile.vue';
|
import SUploadFile from '/@/components/semri/fileComponent/SUploadFile.vue';
|
||||||
@@ -297,6 +280,7 @@ import {
|
|||||||
const showFeedbackDetail = ref(true);
|
const showFeedbackDetail = ref(true);
|
||||||
const feedbackList = ref<any[]>([]);
|
const feedbackList = ref<any[]>([]);
|
||||||
const subApproveUser = ref('');
|
const subApproveUser = ref('');
|
||||||
|
const subApproveUserNames = ref('');
|
||||||
const isEnd = ref(0);
|
const isEnd = ref(0);
|
||||||
const problemTreeData = ref<any[]>([]);
|
const problemTreeData = ref<any[]>([]);
|
||||||
const loadingProblemOptions = ref(false);
|
const loadingProblemOptions = ref(false);
|
||||||
@@ -305,32 +289,6 @@ import {
|
|||||||
const savingIsNeedLeaderApprove = ref(false);
|
const savingIsNeedLeaderApprove = ref(false);
|
||||||
const defaultCcUsers = ref<Array<{ username: string; realname: string }>>([]);
|
const defaultCcUsers = ref<Array<{ username: string; realname: string }>>([]);
|
||||||
|
|
||||||
const handleReasonTemplateMap: Record<string, () => string> = {
|
|
||||||
Task_0g8sc6n: buildApproveReason,
|
|
||||||
Task_0ixi1rs: buildCollectDoneReason,
|
|
||||||
Task_0l5ik22: buildApproveReason,
|
|
||||||
Task_0mbr735: buildDeptHandlerFeedbackReason,
|
|
||||||
Task_0mxtg05: buildAlreadyApprovedReason,
|
|
||||||
Task_14226iy: buildAlreadyReviewedReason,
|
|
||||||
Task_1c64uvl: buildPleaseDeptHandleReason,
|
|
||||||
Task_1i99s6v: buildApproveReason,
|
|
||||||
Task_1nj4k7b: buildLaunchSupervisionReason,
|
|
||||||
|
|
||||||
Task_09qxoto: buildDisciplineSecretaryApprovedReason,
|
|
||||||
Task_0cfjknn: buildSecretaryApprovedReason,
|
|
||||||
Task_0r2vutj: buildChargeDeptApprovedReason,
|
|
||||||
Task_1azpeqj: buildJiJianCheckedReason,
|
|
||||||
Task_1cvft2f: buildPartyMassesConfirmedReason,
|
|
||||||
Task_1k1zt37: buildChargeLeaderApprovedReason,
|
|
||||||
Task_1k36lmv: buildDeptLeaderApprovedReason,
|
|
||||||
Task_1k6n75g: buildAssignProcessReason,
|
|
||||||
};
|
|
||||||
|
|
||||||
const defaultHandleReason = computed(() => {
|
|
||||||
const builder = handleReasonTemplateMap[String(processInfo.value.taskDefKey || '')];
|
|
||||||
return builder ? builder() : '';
|
|
||||||
});
|
|
||||||
|
|
||||||
const mainForm = reactive<Record<string, any>>({
|
const mainForm = reactive<Record<string, any>>({
|
||||||
id: '',
|
id: '',
|
||||||
problemId: '',
|
problemId: '',
|
||||||
@@ -339,12 +297,16 @@ import {
|
|||||||
deadline: '',
|
deadline: '',
|
||||||
targetNode: '',
|
targetNode: '',
|
||||||
measureResLeader: '',
|
measureResLeader: '',
|
||||||
|
measureResLeaderNames: '',
|
||||||
measureResDept: '',
|
measureResDept: '',
|
||||||
|
measureResDeptNames: '',
|
||||||
chargeLeaderId: '',
|
chargeLeaderId: '',
|
||||||
|
chargeLeaderIdNames: '',
|
||||||
rectificationEvidence: '',
|
rectificationEvidence: '',
|
||||||
evaluationCriterion: '',
|
evaluationCriterion: '',
|
||||||
isNeedAppro: '',
|
isNeedAppro: '',
|
||||||
supDeptleaderid: '',
|
supDeptleaderid: '',
|
||||||
|
supDeptleaderidNames: '',
|
||||||
inspectionStatus: '',
|
inspectionStatus: '',
|
||||||
supervisoryOpinion: '',
|
supervisoryOpinion: '',
|
||||||
measureCount: undefined,
|
measureCount: undefined,
|
||||||
@@ -353,8 +315,28 @@ import {
|
|||||||
taskStatus: '',
|
taskStatus: '',
|
||||||
superviseCount: '',
|
superviseCount: '',
|
||||||
sortNo: undefined,
|
sortNo: undefined,
|
||||||
|
leaderApproveUserNames: '',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 选人/选部门 ID→Name 翻译
|
||||||
|
const { resolveAll, selectHandler } = useSelectNameResolver(mainForm, [
|
||||||
|
{ field: 'measureResDept', type: 'dept' },
|
||||||
|
{ field: 'measureResLeader', type: 'user' },
|
||||||
|
{ field: 'chargeLeaderId', type: 'user' },
|
||||||
|
{ field: 'supDeptleaderid', type: 'user' },
|
||||||
|
{ field: 'leaderApproveUser', type: 'user', getValue: () => leaderApproveUser.value },
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 合并 mainForm + 表单局部变量,供占位符 ${变量名} 解析
|
||||||
|
const formScope = computed(() => ({
|
||||||
|
...mainForm,
|
||||||
|
isEnd: isEnd.value,
|
||||||
|
subApproveUser: subApproveUser.value,
|
||||||
|
subApproveUserNames: subApproveUserNames.value,
|
||||||
|
isNeedLeaderApprove: isNeedLeaderApprove.value,
|
||||||
|
leaderApproveUser: leaderApproveUser.value,
|
||||||
|
}));
|
||||||
|
|
||||||
const feedbackColumns = computed(() => {
|
const feedbackColumns = computed(() => {
|
||||||
const cols: any[] = [
|
const cols: any[] = [
|
||||||
{ title: '序号', key: 'seq', align: 'center', width: 60 },
|
{ title: '序号', key: 'seq', align: 'center', width: 60 },
|
||||||
@@ -426,6 +408,9 @@ import {
|
|||||||
processTableName: props.formData?.processTableName,
|
processTableName: props.formData?.processTableName,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
provide('extraVars', formScope);
|
||||||
|
provide('flowVars', computed(() => props.formData?.vars || {}));
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
initFormData();
|
initFormData();
|
||||||
});
|
});
|
||||||
@@ -443,6 +428,14 @@ import {
|
|||||||
},
|
},
|
||||||
{ immediate: true }
|
{ 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(
|
watch(
|
||||||
() => props.formData?.vars?.isNeedLeaderApprove,
|
() => props.formData?.vars?.isNeedLeaderApprove,
|
||||||
@@ -451,6 +444,14 @@ import {
|
|||||||
},
|
},
|
||||||
{ immediate: true }
|
{ immediate: true }
|
||||||
);
|
);
|
||||||
|
// 反向同步:本地切换 isNeedLeaderApprove 时更新 formData.vars
|
||||||
|
watch(isNeedLeaderApprove, (val) => {
|
||||||
|
const vars = props.formData?.vars;
|
||||||
|
if (vars) {
|
||||||
|
vars.is_need_leader_approve = String(val);
|
||||||
|
vars.isNeedLeaderApprove = String(val);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
async function fetchDefaultCcUsers() {
|
async function fetchDefaultCcUsers() {
|
||||||
try {
|
try {
|
||||||
@@ -503,6 +504,7 @@ import {
|
|||||||
const data = await defHttp.get({ url: queryByIdUrl, params: { id: dataId } });
|
const data = await defHttp.get({ url: queryByIdUrl, params: { id: dataId } });
|
||||||
setMainForm(data || {});
|
setMainForm(data || {});
|
||||||
leaderApproveUser.value = mainForm.chargeLeaderId || '';
|
leaderApproveUser.value = mainForm.chargeLeaderId || '';
|
||||||
|
await resolveAll();
|
||||||
await loadFeedbackList();
|
await loadFeedbackList();
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
@@ -614,6 +616,10 @@ import {
|
|||||||
await progressDelete({ id: record.id }, loadFeedbackList);
|
await progressDelete({ id: record.id }, loadFeedbackList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onSubApproveUserConfirm(userIds: string, realnames: string) {
|
||||||
|
subApproveUserNames.value = realnames || '';
|
||||||
|
}
|
||||||
|
|
||||||
async function saveSubApproveUserVariable(options: { showSuccessMessage?: boolean } = {}) {
|
async function saveSubApproveUserVariable(options: { showSuccessMessage?: boolean } = {}) {
|
||||||
const { showSuccessMessage = true } = options;
|
const { showSuccessMessage = true } = options;
|
||||||
const processInstanceId = processInfo.value.processInstanceId;
|
const processInstanceId = processInfo.value.processInstanceId;
|
||||||
|
|||||||
+24
-3
@@ -114,7 +114,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { ref, reactive, computed, toRaw, unref, watch, watchEffect } from 'vue';
|
import { ref, reactive, computed, toRaw, unref, watch, watchEffect, inject } from 'vue';
|
||||||
import { initDictOptions } from '/@/utils/dict';
|
import { initDictOptions } from '/@/utils/dict';
|
||||||
import { useMessage } from '/@/hooks/web/useMessage';
|
import { useMessage } from '/@/hooks/web/useMessage';
|
||||||
import { taskComplaint, taskComplete, beforeAddSignTask, afterAddSignTask, addMultiInstance} from "../task.handle.api";
|
import { taskComplaint, taskComplete, beforeAddSignTask, afterAddSignTask, addMultiInstance} from "../task.handle.api";
|
||||||
@@ -216,6 +216,19 @@
|
|||||||
*/
|
*/
|
||||||
const selectUserType = ref('');
|
const selectUserType = ref('');
|
||||||
const remarksDictOptions = ref([]);
|
const remarksDictOptions = ref([]);
|
||||||
|
const extraVars = inject('extraVars', ref({}));
|
||||||
|
const flowVars = inject('flowVars', ref({}));
|
||||||
|
|
||||||
|
function resolvePlaceholders(text) {
|
||||||
|
if (!text) return '';
|
||||||
|
const extra = extraVars.value || {};
|
||||||
|
const flow = flowVars.value || {};
|
||||||
|
return text.replace(/\$\{(\w+)\}/g, (_, key) => {
|
||||||
|
if (key in extra) return String(extra[key] ?? '');
|
||||||
|
return String(flow[key] ?? '');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const historyCount = computed(() => {
|
const historyCount = computed(() => {
|
||||||
return props.historyList.length;
|
return props.historyList.length;
|
||||||
});
|
});
|
||||||
@@ -264,9 +277,17 @@
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const formDefaultReason = inject('formDefaultReason', ref(''));
|
||||||
|
|
||||||
|
// 表单写死 > 节点配置(props.defaultReason 来自 TaskHandleInnerContent 的节点优先级链)
|
||||||
|
const resolvedDefaultReason = computed(() => {
|
||||||
|
const opinion = formDefaultReason.value || props.defaultReason;
|
||||||
|
return resolvePlaceholders(opinion);
|
||||||
|
});
|
||||||
|
|
||||||
// 默认处理意见只在空值或仍为上一条自动意见时刷新,避免覆盖用户手动输入。
|
// 默认处理意见只在空值或仍为上一条自动意见时刷新,避免覆盖用户手动输入。
|
||||||
watch(
|
watch(
|
||||||
() => props.defaultReason,
|
resolvedDefaultReason,
|
||||||
(value) => {
|
(value) => {
|
||||||
if (isRejectProcessModel(model.processModel)) {
|
if (isRejectProcessModel(model.processModel)) {
|
||||||
return;
|
return;
|
||||||
@@ -279,7 +300,7 @@
|
|||||||
() => model.processModel,
|
() => model.processModel,
|
||||||
(value) => {
|
(value) => {
|
||||||
const isReject = isRejectProcessModel(value);
|
const isReject = isRejectProcessModel(value);
|
||||||
applyAutoReason(isReject ? REJECT_DEFAULT_REASON : props.defaultReason, [
|
applyAutoReason(isReject ? REJECT_DEFAULT_REASON : resolvedDefaultReason.value, [
|
||||||
isReject ? props.defaultReason : REJECT_DEFAULT_REASON,
|
isReject ? props.defaultReason : REJECT_DEFAULT_REASON,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|||||||
+29
-3
@@ -20,7 +20,7 @@
|
|||||||
:allowCounterSignAddUser="allowCounterSignAddUser"
|
:allowCounterSignAddUser="allowCounterSignAddUser"
|
||||||
:allowReject="allowReject"
|
:allowReject="allowReject"
|
||||||
:beforeHandle="beforeHandle"
|
:beforeHandle="beforeHandle"
|
||||||
:defaultReason="defaultReason"
|
:defaultReason="conditionalDefaultOpinion || nodeDefaultOpinion || defaultReason"
|
||||||
:defaultCc="defaultCc"
|
:defaultCc="defaultCc"
|
||||||
:currentTaskName="currentNode.taskName">
|
:currentTaskName="currentNode.taskName">
|
||||||
</my-handle-content>
|
</my-handle-content>
|
||||||
@@ -34,7 +34,7 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { taskTransInfo, taskComplete, taskClaim } from '../task.handle.api';
|
import { taskTransInfo, taskComplete, taskClaim } from '../task.handle.api';
|
||||||
import { ref, watch } from 'vue';
|
import { ref, watch, computed } from 'vue';
|
||||||
import TaskNodeStepList from './TaskNodeStepList.vue';
|
import TaskNodeStepList from './TaskNodeStepList.vue';
|
||||||
import TaskCommentList from './TaskCommentList.vue';
|
import TaskCommentList from './TaskCommentList.vue';
|
||||||
import MyHandleContent from './MyHandleContent.vue';
|
import MyHandleContent from './MyHandleContent.vue';
|
||||||
@@ -102,6 +102,24 @@
|
|||||||
const selnextUserStatus = ref(true);
|
const selnextUserStatus = ref(true);
|
||||||
// 选择抄送人
|
// 选择抄送人
|
||||||
const ccStatus = ref(true);
|
const ccStatus = ref(true);
|
||||||
|
// 节点配置的默认审批意见
|
||||||
|
const nodeDefaultOpinion = ref('');
|
||||||
|
// 条件变量默认审批意见
|
||||||
|
const condOpinionVar = ref(''); // 条件变量名 — API: data.defaultOpinionVar
|
||||||
|
const condOpinionWhen0 = ref(''); // 变量=0时的意见 — API: data.defaultOpinionCond0
|
||||||
|
const condOpinionWhen1 = ref(''); // 变量=1时的意见 — API: data.defaultOpinionCond1
|
||||||
|
|
||||||
|
// 条件变量 > 节点默认 > 表单传入
|
||||||
|
const conditionalDefaultOpinion = computed(() => {
|
||||||
|
const varName = condOpinionVar.value;
|
||||||
|
if (!varName) return '';
|
||||||
|
const vars = props.formData?.vars;
|
||||||
|
if (!vars) return '';
|
||||||
|
const varValue = String(vars[varName] ?? '');
|
||||||
|
if (varValue === '0') return condOpinionWhen0.value;
|
||||||
|
if (varValue === '1') return condOpinionWhen1.value;
|
||||||
|
return '';
|
||||||
|
});
|
||||||
|
|
||||||
getTaskTransInfo();
|
getTaskTransInfo();
|
||||||
|
|
||||||
@@ -139,6 +157,12 @@
|
|||||||
allowReject.value = data?.rejectStatus == '1';
|
allowReject.value = data?.rejectStatus == '1';
|
||||||
//是否多实例- 会签加签 是否允许会签节点加人0否、1允许
|
//是否多实例- 会签加签 是否允许会签节点加人0否、1允许
|
||||||
allowCounterSignAddUser.value = (data?.allowCounterSignAddUser && data.allowCounterSignAddUser =='1');
|
allowCounterSignAddUser.value = (data?.allowCounterSignAddUser && data.allowCounterSignAddUser =='1');
|
||||||
|
//节点配置的默认审批意见
|
||||||
|
nodeDefaultOpinion.value = data?.defaultOpinion || '';
|
||||||
|
//条件变量默认审批意见
|
||||||
|
condOpinionVar.value = data?.defaultOpinionVar || '';
|
||||||
|
condOpinionWhen0.value = data?.defaultOpinionCond0 || '';
|
||||||
|
condOpinionWhen1.value = data?.defaultOpinionCond1 || '';
|
||||||
taskStepList.value = data.bpmLogStepList;
|
taskStepList.value = data.bpmLogStepList;
|
||||||
bpmLogList.value = data.bpmLogList;
|
bpmLogList.value = data.bpmLogList;
|
||||||
|
|
||||||
@@ -204,7 +228,9 @@
|
|||||||
allowCounterSignAddUser,
|
allowCounterSignAddUser,
|
||||||
allowReject,
|
allowReject,
|
||||||
selnextUserStatus,
|
selnextUserStatus,
|
||||||
turnbackTaskId
|
turnbackTaskId,
|
||||||
|
nodeDefaultOpinion,
|
||||||
|
conditionalDefaultOpinion
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -67,7 +67,7 @@
|
|||||||
const [registerNodeModal, { openModal: openNodeModal }] = useModal();
|
const [registerNodeModal, { openModal: openNodeModal }] = useModal();
|
||||||
|
|
||||||
const [registerNodeAuthModal, { openModal: openNodeAuthModal }] = useModal();
|
const [registerNodeAuthModal, { openModal: openNodeAuthModal }] = useModal();
|
||||||
|
|
||||||
|
|
||||||
function addQueryParams(params) {
|
function addQueryParams(params) {
|
||||||
params.processId = props.processId;
|
params.processId = props.processId;
|
||||||
@@ -145,7 +145,7 @@
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
function openAuthModal(isNewAuthModal, row) {
|
function openAuthModal(isNewAuthModal, row) {
|
||||||
if(isNewAuthModal===true){
|
if(isNewAuthModal===true){
|
||||||
openNodeAuthModal(true, row);
|
openNodeAuthModal(true, row);
|
||||||
|
|||||||
@@ -36,7 +36,24 @@
|
|||||||
<question-circle-outlined style="color: rgb(110 110 110)"/>
|
<question-circle-outlined style="color: rgb(110 110 110)"/>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<template #defaultOpinionBlock="{ model, field }">
|
||||||
|
<div class="opinion-block">
|
||||||
|
<div class="opinion-switch-row">
|
||||||
|
<span>是否生成默认审批意见</span>
|
||||||
|
<a-switch v-model:checked="model.enableDefaultOpinion" checked-children="是" un-checked-children="否" />
|
||||||
|
</div>
|
||||||
|
<template v-if="model.enableDefaultOpinion">
|
||||||
|
<div class="opinion-cond-label">条件变量名</div>
|
||||||
|
<a-input v-model:value="model.defaultOpinionVar" placeholder="条件变量名,如 approval_result,值为 0 或 1" style="margin-bottom: 12px;" />
|
||||||
|
<div class="opinion-cond-label">默认审批意见(变量 = 0)</div>
|
||||||
|
<a-textarea v-model:value="model.defaultOpinion" :rows="2" placeholder="变量值=0 时的默认审批意见" style="margin-bottom: 12px;" />
|
||||||
|
<div class="opinion-cond-label">默认审批意见(变量 = 1)</div>
|
||||||
|
<a-textarea v-model:value="model.defaultOpinion2" :rows="2" placeholder="变量值=1 时的默认审批意见" />
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
</BasicForm>
|
</BasicForm>
|
||||||
</BasicModal>
|
</BasicModal>
|
||||||
</template>
|
</template>
|
||||||
@@ -48,7 +65,7 @@
|
|||||||
import { nodeFormSchema } from './process.node.data';
|
import { nodeFormSchema } from './process.node.data';
|
||||||
import { saveOrUpdate } from './process.node.api';
|
import { saveOrUpdate } from './process.node.api';
|
||||||
import { QuestionCircleOutlined } from '@ant-design/icons-vue';
|
import { QuestionCircleOutlined } from '@ant-design/icons-vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ProcessNodeModal',
|
name: 'ProcessNodeModal',
|
||||||
components: {
|
components: {
|
||||||
@@ -94,7 +111,7 @@
|
|||||||
//update-end-author:taoyan date:2023-2-14 for: QQYUN-4266【老版流程】新增节点 节点名称和编码不能输入,子流程无法添加start节点
|
//update-end-author:taoyan date:2023-2-14 for: QQYUN-4266【老版流程】新增节点 节点名称和编码不能输入,子流程无法添加start节点
|
||||||
} else {
|
} else {
|
||||||
delete data.isUpdate;
|
delete data.isUpdate;
|
||||||
setFieldsValue({ ...data });
|
setFieldsValue({ ...data, enableDefaultOpinion: !!(data.defaultOpinion || data.defaultOpinionVar) });
|
||||||
//update-begin-author:taoyan date:2023-2-14 for: QQYUN-4266【老版流程】新增节点 节点名称和编码不能输入,子流程无法添加start节点
|
//update-begin-author:taoyan date:2023-2-14 for: QQYUN-4266【老版流程】新增节点 节点名称和编码不能输入,子流程无法添加start节点
|
||||||
await updateSchema([
|
await updateSchema([
|
||||||
{
|
{
|
||||||
@@ -119,7 +136,7 @@
|
|||||||
emit('success');
|
emit('success');
|
||||||
closeModal();
|
closeModal();
|
||||||
}
|
}
|
||||||
|
|
||||||
const designerUrl = "3.表单设计器:{{DOMAIN_URL}}/desform/edit/设计器编码/${BPM_DES_DATA_ID}?token={{TOKEN}}&taskId={{TASKID}}"
|
const designerUrl = "3.表单设计器:{{DOMAIN_URL}}/desform/edit/设计器编码/${BPM_DES_DATA_ID}?token={{TOKEN}}&taskId={{TASKID}}"
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -142,9 +159,28 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<style scoped>
|
<style scoped lang="less">
|
||||||
:deep(.ant-modal-body) {
|
:deep(.ant-modal-body) {
|
||||||
padding-bottom: 5px !important;
|
padding-bottom: 5px !important;
|
||||||
padding-top: 5px !important;
|
padding-top: 5px !important;
|
||||||
}
|
}
|
||||||
|
.opinion-block {
|
||||||
|
background-color: #eee;
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 10px;
|
||||||
|
.opinion-switch-row {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
span {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.opinion-cond-label {
|
||||||
|
font-size: 13px;
|
||||||
|
color: #4b4a4a;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -104,4 +104,29 @@ export const nodeFormSchema: FormSchema[] = [
|
|||||||
component: 'Input',
|
component: 'Input',
|
||||||
slot: 'nodeTimeout',
|
slot: 'nodeTimeout',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: '是否生成默认审批意见',
|
||||||
|
field: 'enableDefaultOpinion',
|
||||||
|
component: 'Switch',
|
||||||
|
defaultValue: false,
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '条件变量名',
|
||||||
|
field: 'defaultOpinionVar',
|
||||||
|
component: 'Input',
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '默认审批意见(变量=1)',
|
||||||
|
field: 'defaultOpinion2',
|
||||||
|
component: 'InputTextArea',
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '默认审批意见',
|
||||||
|
field: 'defaultOpinion',
|
||||||
|
component: 'InputTextArea',
|
||||||
|
slot: 'defaultOpinionBlock',
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -132,6 +132,7 @@
|
|||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</a-tab-pane>
|
</a-tab-pane>
|
||||||
</a-tabs>
|
</a-tabs>
|
||||||
</a-spin>
|
</a-spin>
|
||||||
|
|||||||
Reference in New Issue
Block a user