155 lines
4.4 KiB
Vue
155 lines
4.4 KiB
Vue
<!--
|
||
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>
|