From ac5dac41df2b75de998a79701d846b33a47ce64c Mon Sep 17 00:00:00 2001
From: liding <756868258@qq.com>
Date: 星期五, 05 六月 2026 16:59:06 +0800
Subject: [PATCH] feat(approve): 优化审批详情面板显示逻辑并增加附件功能
---
src/views/officeProcessAutomation/ApproveManage/approve-list/approveListConstants.js | 33 +++++++++++++++-
src/views/officeProcessAutomation/ApproveManage/approve-list/components/ApproveDetailPanel.vue | 76 +++++++++++++++++++++++++++++++++++++-
2 files changed, 105 insertions(+), 4 deletions(-)
diff --git a/src/views/officeProcessAutomation/ApproveManage/approve-list/approveListConstants.js b/src/views/officeProcessAutomation/ApproveManage/approve-list/approveListConstants.js
index 938a787..d4a7570 100644
--- a/src/views/officeProcessAutomation/ApproveManage/approve-list/approveListConstants.js
+++ b/src/views/officeProcessAutomation/ApproveManage/approve-list/approveListConstants.js
@@ -362,10 +362,36 @@
});
}
+/** 浠庢ā鏉垮瓧娈典腑鎵惧埌鐢宠浜哄瓧娈� */
+function findApplicantField(fields) {
+ if (!Array.isArray(fields)) return null;
+ return (
+ fields.find((f) => String(f?.label || "").includes("鐢宠浜�")) ||
+ fields.find((f) => f?.type === "select" && f?.optionSource === "user") ||
+ null
+ );
+}
+
+/** 浠� formPayload 鐨勭敵璇蜂汉瀛楁瑙f瀽 applicantId / applicantName */
+function resolveApplicantFromFormPayload(payload, fields) {
+ const field = findApplicantField(fields);
+ if (!field) return {};
+ const val = payload?.[field.key];
+ if (val == null || val === "") return {};
+ const result = { applicantId: val };
+ const opts = field.options;
+ if (Array.isArray(opts) && opts.length) {
+ const hit = opts.find((o) => String(o.value) === String(val));
+ if (hit?.label) result.applicantName = hit.label;
+ }
+ return result;
+}
+
/** 缁勮淇濆瓨/鏇存柊瀹℃壒 DTO */
export function buildInstanceDto({ submitForm, activeTemplate, userStore, flowNodes, existingRow }) {
const payload = submitForm?.formPayload || {};
const tpl = activeTemplate || {};
+ const fields = tpl.fields || submitForm?.formFieldDefs || [];
const title =
String(payload.summary || payload.title || "").trim() ||
tpl.label ||
@@ -378,6 +404,7 @@
templateId,
});
const isUpdate = Boolean(instanceId);
+ const fromPayload = resolveApplicantFromFormPayload(payload, fields);
const dto = {
templateId,
@@ -408,8 +435,9 @@
} else {
dto.status = submitForm?.saveStatusApi || "PENDING";
dto.currentLevel = 1;
- dto.applicantId = userStore?.id;
- dto.applicantName = userStore?.nickName || userStore?.name || "";
+ dto.applicantId = fromPayload.applicantId || submitForm?.applicantId || userStore?.id;
+ dto.applicantName = fromPayload.applicantName || submitForm?.applicantName
+ || (fromPayload.applicantId ? "" : (userStore?.nickName || userStore?.name || ""));
}
return dto;
}
@@ -502,6 +530,7 @@
approvalRecords,
rejectReason:
approvalRecords.find((r) => r.result === "rejected")?.opinion || "",
+ storageBlobVOList: row.storageBlobVOList || row.storageBlobDTOs || row.attachmentList || [],
};
}
diff --git a/src/views/officeProcessAutomation/ApproveManage/approve-list/components/ApproveDetailPanel.vue b/src/views/officeProcessAutomation/ApproveManage/approve-list/components/ApproveDetailPanel.vue
index f54c167..6d8c9de 100644
--- a/src/views/officeProcessAutomation/ApproveManage/approve-list/components/ApproveDetailPanel.vue
+++ b/src/views/officeProcessAutomation/ApproveManage/approve-list/components/ApproveDetailPanel.vue
@@ -16,7 +16,7 @@
</span>
</el-descriptions-item>
<el-descriptions-item label="鐢宠浜虹紪鍙�">{{ row.applicantNo || "鈥�" }}</el-descriptions-item>
- <el-descriptions-item label="鐢宠浜哄悕绉�">{{ row.applicantName || "鈥�" }}</el-descriptions-item>
+ <el-descriptions-item label="鐢宠浜哄悕绉�">{{ applicantNameDisplay }}</el-descriptions-item>
<el-descriptions-item label="鐢宠鎽樿">{{ row.summary || "鈥�" }}</el-descriptions-item>
<el-descriptions-item v-if="row.rejectReason" label="椹冲洖鍘熷洜" :span="2">
<span class="reject-text">{{ row.rejectReason }}</span>
@@ -35,18 +35,30 @@
readonly
/>
</div>
+
+ <div class="detail-block">
+ <div class="detail-block-title">闄勪欢</div>
+ <template v-if="attachmentFiles.length">
+ <el-tag v-for="(f, i) in attachmentFiles" :key="i" class="file-tag" type="info" @click="openFile(f)">
+ {{ f.name || f.originalFilename }}
+ </el-tag>
+ </template>
+ <el-empty v-else description="鏆傛棤闄勪欢" :image-size="48" />
+ </div>
</div>
</template>
<script setup>
-import { computed } from "vue";
+import { computed, onMounted, watch } from "vue";
import { formatDisplayTime } from "../../approve-template/approveTemplateConstants.js";
+import { useSelectOptionSources } from "../../approve-template/useSelectOptionSources.js";
import {
approvalTypeLabel,
approvalTypeStyle,
approvalStatusLabel,
approvalStatusTagType,
resolveInstanceFormFields,
+ formatFieldDisplayValue,
} from "../approveListConstants.js";
import FormPayloadFields from "./FormPayloadFields.vue";
@@ -54,7 +66,63 @@
row: { type: Object, default: () => ({}) },
});
+const { ensureForFields, getDisplayLabel } = useSelectOptionSources();
+
const formResolved = computed(() => resolveInstanceFormFields(props.row));
+
+const applicantField = computed(() => {
+ const fields = formResolved.value.fields || [];
+ return (
+ fields.find((f) => String(f?.label || "").includes("鐢宠浜�")) ||
+ fields.find((f) => f?.type === "select" && f?.optionSource === "user") ||
+ null
+ );
+});
+
+const applicantNameDisplay = computed(() => {
+ if (!applicantField.value) return props.row?.applicantName || "鈥�";
+ const val = formResolved.value.formPayload?.[applicantField.value.key];
+ if (val == null || val === "") return props.row?.applicantName || "鈥�";
+ if (applicantField.value.optionSource && applicantField.value.optionSource !== "static") {
+ const label = getDisplayLabel(applicantField.value, val);
+ if (label && label !== "鈥�") return label;
+ }
+ const formatted = formatFieldDisplayValue(applicantField.value, val);
+ if (formatted && formatted !== "鈥�") return formatted;
+ return props.row?.applicantName || "鈥�";
+});
+
+async function loadOptionCaches() {
+ await ensureForFields(formResolved.value.fields || []);
+}
+
+onMounted(() => {
+ loadOptionCaches();
+});
+
+watch(
+ () => formResolved.value.fields,
+ () => {
+ loadOptionCaches();
+ },
+ { deep: true }
+);
+
+const attachmentFiles = computed(() => {
+ const list =
+ props.row?.storageBlobVOList ||
+ props.row?.storageBlobDTOs ||
+ props.row?.storageBlobDTOS ||
+ props.row?.storageBlobVOS ||
+ props.row?.attachmentList ||
+ [];
+ return Array.isArray(list) ? list : [];
+});
+
+function openFile(f) {
+ const url = f?.url || f?.previewURL || f?.downloadURL;
+ if (url) window.open(url, "_blank");
+}
</script>
<style scoped>
@@ -82,4 +150,8 @@
.reject-text {
color: var(--el-color-danger);
}
+.file-tag {
+ margin: 0 8px 8px 0;
+ cursor: pointer;
+}
</style>
--
Gitblit v1.9.3