新增MES审批流设计功能,包括审批流定义、审批实例管理及审批办理接口,支持可视化设计与业务单据联动,提升审批流程的灵活性与用户体验。
This commit is contained in:
154
jeecgboot-vue3/src/views/system/im/ImApprovalDetailModal.vue
Normal file
154
jeecgboot-vue3/src/views/system/im/ImApprovalDetailModal.vue
Normal file
@@ -0,0 +1,154 @@
|
||||
<!--
|
||||
IM 审批卡片「查看详情」弹窗:展示单据全部字段 + 审批进度/历史
|
||||
@author GHT
|
||||
@date 2026-05-29 for:【QH-MES审批流设计】审批办理-查看详情
|
||||
-->
|
||||
<template>
|
||||
<a-modal v-model:open="open" title="审批单据详情" :width="640" :footer="null" :destroyOnClose="true">
|
||||
<a-spin :spinning="loading">
|
||||
<div class="im-appr-detail">
|
||||
<div class="im-appr-detail-head">
|
||||
<a-descriptions :column="2" size="small" bordered>
|
||||
<a-descriptions-item label="审批流">{{ info.flowName }}</a-descriptions-item>
|
||||
<a-descriptions-item label="状态">
|
||||
<a-tag :color="statusColor">{{ info.statusText }}</a-tag>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="发起人">{{ info.applyUserName }}</a-descriptions-item>
|
||||
<a-descriptions-item label="当前节点">{{ info.currentNodeName || '-' }}</a-descriptions-item>
|
||||
<a-descriptions-item label="当前处理人" :span="2">{{ info.currentHandlersText || '-' }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</div>
|
||||
|
||||
<div class="im-appr-detail-section-title">单据数据</div>
|
||||
<table class="im-appr-detail-table">
|
||||
<tbody>
|
||||
<tr v-for="f in fields" :key="f.label">
|
||||
<th>{{ f.label }}</th>
|
||||
<td>{{ f.value }}</td>
|
||||
</tr>
|
||||
<tr v-if="!fields.length">
|
||||
<td class="im-appr-detail-empty">暂无单据数据</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<template v-if="history.length">
|
||||
<div class="im-appr-detail-section-title">审批历史</div>
|
||||
<a-timeline class="im-appr-detail-timeline">
|
||||
<a-timeline-item v-for="(h, i) in history" :key="i" :color="h.actionText === '驳回' ? 'red' : 'green'">
|
||||
<div class="im-appr-his-line">
|
||||
<b>{{ h.nodeName }}</b>
|
||||
<span>{{ h.name }} {{ h.actionText }}</span>
|
||||
<span class="im-appr-his-time">{{ h.time }}</span>
|
||||
</div>
|
||||
<div v-if="h.comment" class="im-appr-his-comment">意见:{{ h.comment }}</div>
|
||||
</a-timeline-item>
|
||||
</a-timeline>
|
||||
</template>
|
||||
</div>
|
||||
</a-spin>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, ref } from 'vue';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
import { getApprovalDetail } from '/@/views/approval/flow/approvalHandle.api';
|
||||
|
||||
defineOptions({ name: 'ImApprovalDetailModal' });
|
||||
|
||||
const { createMessage } = useMessage();
|
||||
|
||||
const open = ref(false);
|
||||
const loading = ref(false);
|
||||
const info = ref<any>({});
|
||||
const fields = ref<{ label: string; value: string }[]>([]);
|
||||
const history = ref<any[]>([]);
|
||||
|
||||
const statusColor = computed(() => {
|
||||
const s = info.value?.status;
|
||||
if (s === '1') return 'green';
|
||||
if (s === '2') return 'red';
|
||||
if (s === '3') return 'default';
|
||||
return 'blue';
|
||||
});
|
||||
|
||||
async function openModal(instanceId: string) {
|
||||
open.value = true;
|
||||
info.value = {};
|
||||
fields.value = [];
|
||||
history.value = [];
|
||||
if (!instanceId) return;
|
||||
try {
|
||||
loading.value = true;
|
||||
const data: any = await getApprovalDetail(instanceId);
|
||||
info.value = data || {};
|
||||
fields.value = data?.fields || [];
|
||||
history.value = data?.history || [];
|
||||
} catch (e: any) {
|
||||
createMessage.error(e?.message || '获取详情失败');
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
defineExpose({ openModal });
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.im-appr-detail-section-title {
|
||||
margin: 16px 0 8px;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
border-left: 3px solid #1677ff;
|
||||
padding-left: 8px;
|
||||
}
|
||||
|
||||
.im-appr-detail-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
font-size: 13px;
|
||||
border: 1px solid #f0f0f0;
|
||||
|
||||
th,
|
||||
td {
|
||||
padding: 8px 10px;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
text-align: left;
|
||||
vertical-align: top;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
th {
|
||||
width: 32%;
|
||||
background: #fafafa;
|
||||
color: #595959;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.im-appr-detail-empty {
|
||||
color: #999;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.im-appr-his-line {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
align-items: center;
|
||||
font-size: 13px;
|
||||
|
||||
.im-appr-his-time {
|
||||
color: #999;
|
||||
font-size: 12px;
|
||||
margin-left: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.im-appr-his-comment {
|
||||
margin-top: 2px;
|
||||
font-size: 12px;
|
||||
color: #888;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user