完善MES审批流设计功能,新增审批可选回调动作、发起人撤销及催办接口,支持审批状态恢复与联动回退,提升审批流程的灵活性与用户体验。

This commit is contained in:
geht
2026-05-29 18:57:09 +08:00
parent aefa44b8a9
commit 0ff4a201b0
33 changed files with 1617 additions and 250 deletions

View File

@@ -35,6 +35,13 @@
</template>
<!-- 不可办理(已处理/已流转/非当前处理人)置灰提示 -->
<span v-else-if="!props.mine && disabledText" class="im-biz-record-disabled">{{ disabledText }}</span>
<!-- 发起人审批中可撤销 -->
<a-button v-if="canCancel" size="small" danger :loading="cancelling" @click="openCancel(singleItem)">
<Icon icon="ant-design:rollback-outlined" />
<span>撤销</span>
</a-button>
<!-- 发起人审批已结束的状态提示 -->
<span v-else-if="mineEndedText" class="im-biz-record-disabled">{{ mineEndedText }}</span>
<a v-if="canLocate" class="im-biz-record-link" @click.prevent="handleLinkClick(singleItem.linkPath)">
<Icon icon="ant-design:unordered-list-outlined" />
<span>跳转至列表</span>
@@ -90,17 +97,30 @@
</a-form-item>
</a-form>
</a-modal>
<!-- 撤销弹窗 -->
<a-modal v-model:open="cancelOpen" title="撤销审批" :confirmLoading="cancelling" okText="确认撤销" @ok="confirmCancel">
<a-alert type="warning" show-icon :message="'撤销后流程将终止,单据将恢复到发起审批前的状态。'" style="margin-bottom: 12px" />
<a-form layout="vertical">
<a-form-item label="撤销原因">
<a-textarea v-model:value="cancelReason" :rows="3" placeholder="可选填写撤销原因" :maxlength="500" show-count />
</a-form-item>
</a-form>
</a-modal>
</div>
</template>
<script lang="ts" setup>
import { computed, ref, onMounted, watch } from 'vue';
import { computed, ref, onMounted, onBeforeUnmount, watch } from 'vue';
import type { ImBizRecordItem, ImBizRecordPayload } from './imBizRecordMessage';
import { getImBizRecordFieldValueByLabel, resolveImBizRecordItemFields, resolveImBizRecordListColumnLabels } from './imBizRecordMessage';
import { navigateImBizRecordLink } from './imRecordLocate';
import { hasImBizRecordPagePermission } from './imBizRecordPermission';
// update-begin---author:GHT ---date:2026-05-29 for【QH-MES审批流完善】订阅会话消息更新,撤销/流转后处理人卡片按钮实时置灰-----
import { onImMessagesUpdated } from './imCache';
// update-end---author:GHT ---date:2026-05-29 for【QH-MES审批流完善】订阅会话消息更新,撤销/流转后处理人卡片按钮实时置灰-----
import { useMessage } from '/@/hooks/web/useMessage';
import { approveApproval, rejectApproval, getApprovalStatus } from '/@/views/approval/flow/approvalHandle.api';
import { approveApproval, rejectApproval, cancelApproval, getApprovalStatus } from '/@/views/approval/flow/approvalHandle.api';
import ImApprovalDetailModal from './ImApprovalDetailModal.vue';
defineOptions({ name: 'ImBizRecordMessageContent' });
@@ -122,8 +142,14 @@
const rejectOpen = ref(false);
const rejectReason = ref('');
const rejectItem = ref<ImBizRecordItem | null>(null);
// 本地办理结果approved / rejected卡片消息为静态办理后本地标记
const actionDone = ref<'' | 'approved' | 'rejected'>('');
// 本地办理结果approved / rejected / cancelled(卡片消息为静态,办理后本地标记)
const actionDone = ref<'' | 'approved' | 'rejected' | 'cancelled'>('');
// update-begin---author:GHT ---date:2026-05-29 for【QH-MES审批流设计】发起人撤销-----
const cancelling = ref(false);
const cancelOpen = ref(false);
const cancelReason = ref('');
const cancelItem = ref<ImBizRecordItem | null>(null);
// update-end---author:GHT ---date:2026-05-29 for【QH-MES审批流设计】发起人撤销-----
// 审批实例实时状态(用于旧节点卡片置灰)
interface LiveStatus {
@@ -184,11 +210,38 @@
return '等待他人处理';
});
// update-begin---author:GHT ---date:2026-05-29 for【QH-MES审批流设计】发起人撤销-----
// 是否可撤销:审批卡片 且 本人发起(mine) 且 审批中 且 本地未撤销
const canCancel = computed(() => {
if (!isApprovalCard.value || !props.mine || actionDone.value) {
return false;
}
const s = liveStatus.value;
return !!s && s.exists === true && s.status === '0';
});
// 发起人视角的结束态提示
const mineEndedText = computed(() => {
if (!isApprovalCard.value || !props.mine) {
return '';
}
if (actionDone.value === 'cancelled') return '已撤销';
const s = liveStatus.value;
if (!s || !s.exists) return '';
if (s.status === '1') return '已通过';
if (s.status === '2') return '已驳回';
if (s.status === '3') return '已撤销';
return '';
});
// update-end---author:GHT ---date:2026-05-29 for【QH-MES审批流设计】发起人撤销-----
async function loadLiveStatus() {
const id = singleItem.value?.instanceId;
if (!isApprovalCard.value || props.mine || !id) {
// update-begin---author:GHT ---date:2026-05-29 for【QH-MES审批流设计】发起人卡片也需加载状态以支持撤销-----
if (!isApprovalCard.value || !id) {
return;
}
// update-end---author:GHT ---date:2026-05-29 for【QH-MES审批流设计】发起人卡片也需加载状态以支持撤销-----
try {
const res: any = await getApprovalStatus(id);
liveStatus.value = (res || { exists: false }) as LiveStatus;
@@ -202,6 +255,33 @@
onMounted(loadLiveStatus);
watch(() => singleItem.value?.instanceId, loadLiveStatus);
// update-begin---author:GHT ---date:2026-05-29 for【QH-MES审批流完善】订阅会话消息更新,撤销/流转后处理人卡片按钮实时置灰-----
// 撤销/驳回/流转时后端会向处理人推送IM消息WS到达会触发 onImMessagesUpdated
// 借此实时重新拉取实例状态,使本卡片的「审批/拒绝」按钮即时置灰、不可点击。
let unsubscribeMsgUpdated: (() => void) | null = null;
onMounted(() => {
if (!isApprovalCard.value) {
return;
}
unsubscribeMsgUpdated = onImMessagesUpdated(() => {
// 本地已办理的卡片无需再刷新,避免覆盖本地置灰文案
if (actionDone.value) {
return;
}
// 已是终态(已通过/已驳回/已撤销/已失效)的卡片无需重复拉取
const s = liveStatus.value;
if (s && (s.exists === false || (!!s.status && s.status !== '0'))) {
return;
}
loadLiveStatus();
});
});
onBeforeUnmount(() => {
unsubscribeMsgUpdated?.();
unsubscribeMsgUpdated = null;
});
// update-end---author:GHT ---date:2026-05-29 for【QH-MES审批流完善】订阅会话消息更新,撤销/流转后处理人卡片按钮实时置灰-----
const hasPagePermission = computed(() => hasImBizRecordPagePermission(props.payload.pagePath));
// 审批卡片即使无列表页权限也应可办理/查看详情,仅"跳转至列表"受页面权限约束
const showNoPermission = computed(() => !props.mine && !hasPagePermission.value && !isApprovalCard.value);
@@ -231,6 +311,13 @@
async function handleApprove(item: ImBizRecordItem) {
if (!item.instanceId || approving.value) return;
// update-begin---author:GHT ---date:2026-05-29 for【QH-MES审批流完善】办理前二次校验最新状态,撤销后防误点击-----
await loadLiveStatus();
if (!liveActionable.value) {
createMessage.warning(disabledText.value || '该审批已无法办理');
return;
}
// update-end---author:GHT ---date:2026-05-29 for【QH-MES审批流完善】办理前二次校验最新状态,撤销后防误点击-----
try {
approving.value = true;
const res: any = await approveApproval({ instanceId: item.instanceId });
@@ -257,6 +344,14 @@
createMessage.warning('请填写驳回理由');
return;
}
// update-begin---author:GHT ---date:2026-05-29 for【QH-MES审批流完善】办理前二次校验最新状态,撤销后防误点击-----
await loadLiveStatus();
if (!liveActionable.value) {
createMessage.warning(disabledText.value || '该审批已无法办理');
rejectOpen.value = false;
return;
}
// update-end---author:GHT ---date:2026-05-29 for【QH-MES审批流完善】办理前二次校验最新状态,撤销后防误点击-----
try {
rejecting.value = true;
await rejectApproval({ instanceId: item.instanceId, reason: rejectReason.value.trim() });
@@ -269,6 +364,30 @@
rejecting.value = false;
}
}
// update-begin---author:GHT ---date:2026-05-29 for【QH-MES审批流设计】发起人撤销-----
function openCancel(item: ImBizRecordItem) {
cancelItem.value = item;
cancelReason.value = '';
cancelOpen.value = true;
}
async function confirmCancel() {
const item = cancelItem.value;
if (!item?.instanceId || cancelling.value) return;
try {
cancelling.value = true;
await cancelApproval({ instanceId: item.instanceId, reason: cancelReason.value.trim() });
createMessage.success('已撤销,单据已恢复到发起前状态');
actionDone.value = 'cancelled';
cancelOpen.value = false;
await loadLiveStatus();
emit('handled');
} finally {
cancelling.value = false;
}
}
// update-end---author:GHT ---date:2026-05-29 for【QH-MES审批流设计】发起人撤销-----
</script>
<style lang="less" scoped>