- 新增 utils/formDataGroups.ts:groups 顺序展示、schema 外字段归「其他信息」、无 schema 回落按 key - ApplyManage 详情抽屉改按分组渲染;ApplyVo 类型补 formSchemaJson
This commit is contained in:
@@ -182,6 +182,8 @@ export interface ApplyVo {
|
||||
itemSnapshotJson?: string;
|
||||
formVersion?: number;
|
||||
formDataJson?: string;
|
||||
/** 办理表单 schema(仅详情出参;「申请内容」按 groups/fields 显示中文 label 与分组的唯一事实源) */
|
||||
formSchemaJson?: string;
|
||||
attachmentsJson?: string;
|
||||
submitterId: number;
|
||||
submitterName: string;
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
/**
|
||||
* 「申请内容」展示整形(2026-09-17):办件的 formDataJson 以英文 key 存储,
|
||||
* 展示层以办理表单 schemaJson(详情出参 formSchemaJson,版本=提交时 formVersion)为
|
||||
* key→中文 label 与分组的唯一事实源:
|
||||
* groups[{title, fields[{key,label}]}] 顺序即展示顺序,只保留有填报值的字段;
|
||||
* schema 里没有而数据里有的 key(历史数据/字段下架)归入「其他信息」兜底组;
|
||||
* 无 schema 时整体回落按 key 展示(老数据不报错)。
|
||||
*/
|
||||
export interface FormDataRow {
|
||||
key: string;
|
||||
label: string;
|
||||
value: any;
|
||||
}
|
||||
|
||||
export interface FormDataGroup {
|
||||
title: string;
|
||||
rows: FormDataRow[];
|
||||
}
|
||||
|
||||
function safeParse(json?: string): any {
|
||||
try {
|
||||
return JSON.parse(json || "{}") ?? {};
|
||||
} catch {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
export function buildFormDataGroups(schemaJson?: string, formDataJson?: string): FormDataGroup[] {
|
||||
const data = safeParse(formDataJson);
|
||||
if (typeof data !== "object" || Array.isArray(data) || data === null) return [];
|
||||
const schema = safeParse(schemaJson);
|
||||
const groups: any[] = Array.isArray(schema.groups) ? schema.groups : [];
|
||||
const used = new Set<string>();
|
||||
const out: FormDataGroup[] = [];
|
||||
groups.forEach((g, i) => {
|
||||
const rows: FormDataRow[] = [];
|
||||
for (const f of Array.isArray(g.fields) ? g.fields : []) {
|
||||
const key = f?.key;
|
||||
if (!key || !(key in data)) continue;
|
||||
used.add(key);
|
||||
rows.push({ key, label: f.label || key, value: data[key] });
|
||||
}
|
||||
if (rows.length) {
|
||||
out.push({ title: g.title || (groups.length > 1 ? `第 ${i + 1} 部分` : "申请内容"), rows });
|
||||
}
|
||||
});
|
||||
const rest = Object.keys(data)
|
||||
.filter((k) => !used.has(k))
|
||||
.map((key) => ({ key, label: key, value: data[key] }));
|
||||
if (rest.length) out.push({ title: "其他信息", rows: rest });
|
||||
if (!out.length) out.push({ title: "申请内容", rows: Object.keys(data).map((key) => ({ key, label: key, value: data[key] })) });
|
||||
return out;
|
||||
}
|
||||
@@ -12,6 +12,7 @@ import { Message } from "view-ui-plus";
|
||||
import { applyApi } from "@/api/module/svc";
|
||||
import type { ApplyVo, FlowProgressVo } from "@/types/svc";
|
||||
import { useSite } from "@/utils/site";
|
||||
import { buildFormDataGroups, FormDataGroup } from "@/utils/formDataGroups";
|
||||
|
||||
const { currentSiteCode, sites, loadSites, setSite } = useSite();
|
||||
const loading = ref(false);
|
||||
@@ -44,6 +45,9 @@ const SNAPSHOT_LABEL: Record<string, string> = {
|
||||
contactPhone: "咨询电话",
|
||||
};
|
||||
|
||||
/** 申请内容:按办理表单 schema 显示中文 label 与分组(详情出参 formSchemaJson) */
|
||||
const contentGroups = ref<FormDataGroup[]>([]);
|
||||
|
||||
const cols = [
|
||||
{ title: "办件号", key: "id", width: 90 },
|
||||
{ title: "事项", key: "itemTitle", minWidth: 180 },
|
||||
@@ -99,6 +103,7 @@ async function openDetail(row: ApplyVo) {
|
||||
progress.value = null;
|
||||
try {
|
||||
detail.value = (await applyApi.detail(row.id).send()) as any;
|
||||
contentGroups.value = buildFormDataGroups(detail.value?.formSchemaJson, detail.value?.formDataJson);
|
||||
} catch (e: any) {
|
||||
Message.error(e?.message || "加载办件详情失败");
|
||||
} finally {
|
||||
@@ -179,10 +184,13 @@ onMounted(async () => {
|
||||
|
||||
<template v-if="detail.formDataJson">
|
||||
<Divider orientation="left">申请内容</Divider>
|
||||
<div class="kv" v-for="(v, k) in parse(detail.formDataJson)" :key="String(k)">
|
||||
<span class="k">{{ k }}</span>
|
||||
<span class="v">{{ displayValue(v) }}</span>
|
||||
</div>
|
||||
<template v-for="g in contentGroups" :key="g.title">
|
||||
<p v-if="g.title !== '申请内容'" class="group-title">{{ g.title }}</p>
|
||||
<div class="kv" v-for="row in g.rows" :key="row.key">
|
||||
<span class="k">{{ row.label }}</span>
|
||||
<span class="v">{{ displayValue(row.value) }}</span>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<Divider orientation="left">审批轨迹</Divider>
|
||||
@@ -233,6 +241,12 @@ onMounted(async () => {
|
||||
font-size: 13px;
|
||||
border-bottom: 1px dashed #eee;
|
||||
}
|
||||
.group-title {
|
||||
font-weight: 600;
|
||||
font-size: 13px;
|
||||
color: #515a6e;
|
||||
margin: 10px 0 2px;
|
||||
}
|
||||
.k {
|
||||
width: 110px;
|
||||
color: #999;
|
||||
|
||||
Reference in New Issue
Block a user