--添加测试模块

This commit is contained in:
2025-10-13 11:53:54 +08:00
parent c3c93fe308
commit e1326c7ce8
146 changed files with 11171 additions and 807 deletions

View File

@ -10,38 +10,32 @@
</slot>
关闭
</a-button>
<a-button @click="saveDraft" v-if="!readonly">
暂存
</a-button>
<a-button @click="setDraft" v-if="rDraftsId && !readonly">
从草稿导入
</a-button>
<a-button v-if="!readonly && hasBtnApprove" type="primary" @click="onApproveClick()">
<slot name="icon">
<check-circle-outlined />
</slot>
同意
</a-button>
<a-button v-if="!readonly && hasBtnReject" @click="onDenyClick">
<slot name="icon">
<stop-outlined />
</slot>
拒绝
</a-button>
<a-dropdown>
<template #overlay>
<a-menu @click="onMoreClick">
<a-menu-item v-if="!readonly && hasBtnFinish" key="finish">终止</a-menu-item>
<a-menu-item v-if="!readonly" key="transfer">转办</a-menu-item>
<a-menu-item v-if="readonly && drawNode" key="drawBack">撤回</a-menu-item>
<a-menu-item key="flowchart">查看流程图</a-menu-item>
</a-menu>
</template>
<a-button>
更多
<down-outlined />
<template v-for="(btn, index) in buttonMap.normal">
<a-button @click="onClickBtn(btn)" :type="btn.buttonCode === ApproveCode.AGREE ? 'primary' : ''">
<slot name="icon" v-if="btn.buttonCode === ApproveCode.AGREE">
<check-circle-outlined />
</slot>
<slot name="icon" v-if="btn.buttonCode === ApproveCode.REJECT">
<stop-outlined />
</slot>
{{btn.buttonName}}
</a-button>
</a-dropdown>
</template>
<template v-for="(btnGroup, btnGroupKey) in buttonMap">
<a-dropdown v-if="btnGroupKey!=='normal' && btnGroup.length">
<template #overlay>
<a-menu>
<a-menu-item v-for="(btn, index) in btnGroup" :key="btn.buttonCode" @click="onClickBtn(btn)">
{{btn.buttonName}}
</a-menu-item>
</a-menu>
</template>
<a-button>
{{btnGroupKey}}
<down-outlined />
</a-button>
</a-dropdown>
</template>
</a-space>
</div>
<FormInformation
@ -67,6 +61,15 @@
<a-button type="primary" @click="closeFlowChart">关闭</a-button>
</template>
</a-modal>
<a-modal :closable="false" v-if="showRecord" visible="true" centered class="geg" title="流程记录" width="1200px" @cancel="closeFlowRecord">
<div class="flow-record-box">
<FlowRecord :list="data.taskRecords" :processId="processId"/>
</div>
<template #footer>
<a-button type="primary" @click="closeFlowRecord">关闭</a-button>
</template>
</a-modal>
<SelectUserV2 ref="selectUser" v-model:value="addStepUser" @change="changeAddStepUser" just-dialog title="加签减签"/>
</div>
</div>
</a-spin>
@ -74,14 +77,15 @@
<script setup>
import { useRouter } from 'vue-router';
import { onMounted, reactive, ref, unref, createVNode } from 'vue';
import { onMounted, reactive, ref, unref, createVNode, provide } from 'vue';
import FormInformation from '/@/views/secondDev/FormInformation.vue';
import userTaskItem from '/@/views/workflow/task/hooks/userTaskItem';
import { getApprovalProcess, postApproval, postGetNextTaskMaybeArrival, postTransfer, getDrawNode, withdraw } from '/@/api/workflow/task';
import { ApproveCode, ApproveType } from '/@/enums/workflowEnum';
import { ApproveCode, ApproveType, ButtonType } from '/@/enums/workflowEnum';
import { CheckCircleOutlined, StopOutlined, CloseOutlined, DownOutlined, ExclamationCircleOutlined } from '@ant-design/icons-vue';
import OpinionDialog from '/@/components/SecondDev/OpinionDialog.vue';
import TransferDialog from '/@/components/SecondDev/TransferDialog.vue';
import SelectUserV2 from '/@/components/Form/src/components/SelectUserV2.vue';
import { separator } from '/@bpmn/config/info';
import { useMultipleTabStore } from '/@/store/modules/multipleTab';
import Title from '/@/components/Title/src/Title.vue';
@ -94,6 +98,8 @@
import { useUserStore } from '/@/store/modules/user';
import { deleteDraft, postDraft, putDraft, getDraftInfo } from '/@/api/workflow/process';
import { TaskTypeUrl } from '/@/enums/workflowEnum';
import { postSetSign, postSetSignV2 } from '/@/api/workflow/task';
import FlowRecord from '/@/views/workflow/task/components/flow/FlowRecord.vue';
const spinning = ref(false);
@ -121,10 +127,29 @@
const transferDlg = ref();
const validateSuccess = ref(false);
const formInformation = ref();
const selectUser = ref()
const addStepUser = ref('')
const lastAddStepUser = ref('')
const hasBtnAddStep = ref(false)
const hasBtnTransfer = ref(false)
const showFlowChart = ref(false);
const hasBtnApprove = ref(true);
const showRecord = ref(false)
const hasBtnApprove = ref(false);
const hasBtnDisagree = ref(false)
const hasBtnReject = ref(false);
const hasBtnFinish = ref(false);
const hasBtnDraft = ref(false)
const approveBtnName = ref('同意')
const transferBtnName = ref('转办')
const addStepBtnName = ref('会签')
const finishBtnName = ref('终止')
const rejectBtnName = ref('拒绝')
const drawBackBtnName = ref('撤回')
const draftBtnName = ref('暂存')
const disagreeBtnName = ref('不同意')
const buttonMap = ref({
normal: []
})
let draftData = {}
const drawNode = ref('');
const props = defineProps({
@ -132,6 +157,8 @@
type: String
}
});
const processInfo = ref();
provide("processInfo", processInfo);
let approvalData = reactive({
isCountersign: false,
@ -151,21 +178,51 @@
nextTaskUser: {} // 格式为taskKey: 用户id逗号分隔
});
let approvedType = ref(ApproveType.AGREE);
function showButton(btn) {
// 撤回有drawNode才显示流程图任何情况下都显示
let show = (btn.checked && ((!readonly.value && btn.buttonCode !== ApproveCode.DRAWBACK) || (readonly.value && btn.buttonCode === ApproveCode.DRAWBACK && drawNode.value))) || (btn.buttonCode === ApproveCode.FLOWBPMN || btn.buttonCode === ApproveCode.FLOWRECORD)
return show
}
function onClickBtn(btn) {
const key = btn.buttonCode;
if(btn.buttonType === ButtonType.DEFAULT) {
let funName = `handle${key}`
methods[funName](btn)
} else if(btn.buttonType === ButtonType.SCRIPT) {
handleFunction(btn)
}
}
function onMoreClick(e) {
const key = e.key;
if (key === 'flowchart') {
openFlowChart();
} else if (key === 'finish') {
Modal.confirm({
title: () => '提示',
content: () => '确定终止吗?',
onOk: () => {
onFinishClick();
}
});
} else if (key === 'transfer') {
onTransferClick();
} else if (key === 'drawBack') {
if(btn.buttonType === ButtonType.DEFAULT) {
let funName = `handle${key}`
methods[funName](btn)
} else if(btn.buttonType === ButtonType.SCRIPT) {
handleFunction(btn)
}
}
function handleFunction(btn) {
// eval(script)
if (btn.handleFuncName) {
formInformation.value?.handleInnerFun(btn.handleFuncName)
}
}
const methods = {
handlesetDraft() {
setDraft()
},
handledraft() {
saveDraft();
},
handleaddStep() {
selectUser.value.show()
},
handledrawBack() {
Modal.confirm({
title: t('提示'),
icon: createVNode(ExclamationCircleOutlined),
@ -195,19 +252,49 @@
},
onCancel() {}
});
}
},
handlefinish(btn) {
Modal.confirm({
title: () => '提示',
content: () => `确定${btn.buttonName}吗?`,
onOk: () => {
onFinishClick();
}
});
},
handleflowBpmn() {
showFlowChart.value = true;
},
handletransfer() {
onTransferClick();
},
handleagree() {
onApproveClick()
},
handledisagree() {
onDisagreeClick()
},
handlereject() {
onDenyClick()
},
handleflowRecord() {
showRecord.value = true;
},
}
function closeFlowChart() {
showFlowChart.value = false;
}
function openFlowChart() {
showFlowChart.value = true;
function closeFlowRecord() {
showRecord.value = false
}
function close() {
tabStore.closeTab(currentRoute, router);
if(window?.isOnlyShowContent=='Y') {
window.close();
}
}
async function setDraft(needModal = true) {
let formData = [];
@ -259,35 +346,103 @@
notificationError(title);
}
}
async function changeAddStepUser (ids, memberList) {
try {
spinning.value = true;
let idList = memberList.map(item => {
return item.id
})
let lastIdList = lastAddStepUser.value.split(',')
let addUserIds = idList.filter(item => {
return lastIdList.indexOf(item) == -1
})
let subUserIds = lastIdList.filter(item => {
return idList.indexOf(item) == -1
})
let data = {
addUserIds,
subUserIds,
schemaId: schemaId.value,
taskId: taskId.value
}
await postSetSignV2(data);
let res = await getApprovalProcess(unref(taskId), unref(processId));
initProcessData(res);
spinning.value = false;
message.success('操作成功');
} catch (e) {
message.error(e)
spinning.value = false;
message.error('操作失败,请稍后再试');
}
}
async function onApproveClick(isAutoAgreeBreak = false) {
openSpinning();
if (!isAutoAgreeBreak) {
await submit();
}
if (!validateSuccess.value) {
closeSpinning();
return;
}
const params = await getApproveParams();
const nextNodes = await postGetNextTaskMaybeArrival(params);
approvalData.approvedType = ApproveType.AGREE;
approvalData.approvedResult = ApproveCode.AGREE;
//如果是自动同意触发的关闭弹层的loading
if (isAutoAgreeBreak) {
opinionDlg.value.stopLoading()
}
closeSpinning();
opinionDlg.value.toggleDialog({
action: 'agree',
nextNodes,
callback: (args) => {
approvalData.approvedContent = args.opinion;
approvalData.nextTaskUser = args.nextTaskUser;
approvalData.isEnd=args.isEnd;
onFinish('approve');
try {
openSpinning();
if (!isAutoAgreeBreak) {
await submit();
}
});
if (!validateSuccess.value) {
closeSpinning();
return;
}
const params = await getApproveParams();
const nextNodes = await postGetNextTaskMaybeArrival(params);
approvalData.approvedType = ApproveType.AGREE;
approvalData.approvedResult = ApproveCode.AGREE;
//如果是自动同意触发的关闭弹层的loading
if (isAutoAgreeBreak) {
opinionDlg.value.stopLoading()
}
closeSpinning();
opinionDlg.value.toggleDialog({
action: 'agree',
nextNodes,
callback: (args) => {
approvalData.approvedContent = args.opinion;
approvalData.nextTaskUser = args.nextTaskUser;
approvalData.isEnd=args.isEnd;
onFinish('approve');
}
});
} catch (e) {
console.error(e)
closeSpinning();
throw new Error(e);
}
}
async function onDisagreeClick() {
try {
openSpinning();
await submit();
if (!validateSuccess.value) {
closeSpinning();
return;
}
const params = await getApproveParams();
const nextNodes = await postGetNextTaskMaybeArrival(params);
approvalData.approvedType = ApproveType.DISAGREE;
approvalData.approvedResult = ApproveCode.DISAGREE;
closeSpinning();
opinionDlg.value.toggleDialog({
action: 'disagree',
nextNodes,
callback: (args) => {
approvalData.approvedContent = args.opinion;
onFinish('disagree');
}
});
} catch (e) {
console.error(e)
closeSpinning();
throw new Error(e);
}
}
async function onDenyClick() {
@ -379,12 +534,37 @@
function setBtnStatus() {
const btnConfigs = approvalData.buttonConfigs;
let draftBtn = btnConfigs.find((item) => item.buttonCode === ApproveCode.DRAFT)
if(draftBtn && rDraftsId.value) {
btnConfigs.push({
...draftBtn,
buttonName: t('从草稿导入'),
buttonCode: 'setDraft',
approveType: ApproveType.DRAFT,
index: 1
})
}
btnConfigs.forEach((btn) => {
const code = btn.buttonCode;
if (code === 'reject') {
hasBtnReject.value = true;
} else if (code === 'finish') {
hasBtnFinish.value = true;
const index = btn.index
const buttonGroup = btn?.buttonGroup
if(buttonGroup) {
if(!buttonMap.value[buttonGroup]) {
buttonMap.value[buttonGroup] = []
}
if(showButton(btn)) {
buttonMap.value[buttonGroup].push(btn)
}
} else {
if(showButton(btn)) {
buttonMap.value['normal'].push(btn)
}
}
for(let key in buttonMap.value) {
buttonMap.value[key].sort((a, b) => {
let aIndex = a?.index || 0
let bIndex = b?.index || 0
return aIndex - bIndex
})
}
});
}
@ -399,16 +579,26 @@
try {
let res = await getApprovalProcess(unref(taskId), unref(processId));
initProcessData(res);
await getBackNode();
processInfo.value = res;
const title = res?.schemaInfo?.name;
if (title) {
const tabPrefix = readonly.value ? '查看' : '审批';
tabStore.changeTitle(fullPath, `${tabPrefix}${title}`);
}
if(taskId.value) {
let ids = ''
res.currentTaskAssignees[res.taskInfo.taskDefinitionKey].forEach((item, index) => {
ids = `${ids}${index == 0 ? '' : ','}${item.assigneeIdStr}`
})
addStepUser.value = ids
lastAddStepUser.value = ids
}
if (res.buttonConfigs) {
approvalData.buttonConfigs = res.buttonConfigs;
setBtnStatus();
}
if (!readonly.value) {
if (res.buttonConfigs) {
approvalData.buttonConfigs = res.buttonConfigs;
setBtnStatus();
}
if (res.relationTasks) {
data.predecessorTasks = res.relationTasks;
}
@ -424,13 +614,12 @@
approvalData.circulateConfigs = [];
}
renderKey.value = Math.random() + '';
getBackNode();
setDraft()
} catch (error) {}
});
function getBackNode() {
getDrawNode(processId.value).then((res) => {
async function getBackNode() {
await getDrawNode(processId.value).then((res) => {
if (res.length) {
drawNode.value = res[0].activityId;
} else {
@ -481,29 +670,33 @@
}
async function getApproveParams() {
let formModels = await formInformation.value.getFormModels();
let system = formInformation.value.getSystemType();
let fileFolderIds = getUploadFileFolderIds(formModels);
return {
approvedType: approvalData.approvedType,
approvedResult: approvalData.approvedResult, // approvalData.approvedType 审批结果 如果为 4 就需要传buttonCode
approvedContent: approvalData.approvedContent,
formData: formModels,
rejectNodeActivityId: approvalData.rejectNodeActivityId,
taskId: taskId.value,
fileFolderIds,
circulateConfigs: approvalData.circulateConfigs,
/*stampId: values.stampId,
stampPassword: values.password,*/
isOldSystem: system,
isEnd:approvalData.isEnd,
nextTaskUser: approvalData.nextTaskUser
};
try {
let formModels = await formInformation.value.getFormModels();
let system = formInformation.value.getSystemType();
let fileFolderIds = getUploadFileFolderIds(formModels);
return {
approvedType: approvalData.approvedType,
approvedResult: approvalData.approvedResult, // approvalData.approvedType 审批结果 如果为 4 就需要传buttonCode
approvedContent: approvalData.approvedContent,
formData: formModels,
rejectNodeActivityId: approvalData.rejectNodeActivityId,
taskId: taskId.value,
fileFolderIds,
circulateConfigs: approvalData.circulateConfigs,
/*stampId: values.stampId,
stampPassword: values.password,*/
isOldSystem: system,
isEnd:approvalData.isEnd,
nextTaskUser: approvalData.nextTaskUser
};
} catch (e) {
console.error(e)
}
}
async function onFinish(values) {
try {
if (validateSuccess.value || values === 'reject' || values === 'finish') {
if (validateSuccess.value || values === 'reject' || values === 'finish' || values === 'disagree') {
let params = await getApproveParams();
let response = await postApproval(params);
// 判断返回值是否带有isAutoAgree 来判断中间是否有自动审批的业务如有再执行判断待审人员是否包含自己不包含就直接flowSuccess
@ -513,6 +706,7 @@
}
} catch (error) {
flowFail();
throw new Error(error);
}
}
@ -525,7 +719,6 @@
&& response.length != 0
&& response[0].isAutoAgree == true //
&& response[0].approveUserIds.includes(userStore.getUserInfo.id)) {
console.error('will reSelect user=', response[0].taskId);
// 注入新得taskId
taskId.value = response[0].taskId;
data.submitLoading = false;
@ -544,3 +737,10 @@
spinning.value = false;
}
</script>
<style lang="less" scoped>
.flow-record-box {
height: 500px;
overflow: auto;
}
</style>