- 新增 utils/formDataGroups.ts:groups 顺序展示、schema 外字段归「其他信息」、无 schema 回落按 key - ApplyManage 详情抽屉改按分组渲染;ApplyVo 类型补 formSchemaJson
This commit is contained in:
@@ -182,6 +182,8 @@ export interface ApplyVo {
|
|||||||
itemSnapshotJson?: string;
|
itemSnapshotJson?: string;
|
||||||
formVersion?: number;
|
formVersion?: number;
|
||||||
formDataJson?: string;
|
formDataJson?: string;
|
||||||
|
/** 办理表单 schema(仅详情出参;「申请内容」按 groups/fields 显示中文 label 与分组的唯一事实源) */
|
||||||
|
formSchemaJson?: string;
|
||||||
attachmentsJson?: string;
|
attachmentsJson?: string;
|
||||||
submitterId: number;
|
submitterId: number;
|
||||||
submitterName: string;
|
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 { applyApi } from "@/api/module/svc";
|
||||||
import type { ApplyVo, FlowProgressVo } from "@/types/svc";
|
import type { ApplyVo, FlowProgressVo } from "@/types/svc";
|
||||||
import { useSite } from "@/utils/site";
|
import { useSite } from "@/utils/site";
|
||||||
|
import { buildFormDataGroups, FormDataGroup } from "@/utils/formDataGroups";
|
||||||
|
|
||||||
const { currentSiteCode, sites, loadSites, setSite } = useSite();
|
const { currentSiteCode, sites, loadSites, setSite } = useSite();
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
@@ -44,6 +45,9 @@ const SNAPSHOT_LABEL: Record<string, string> = {
|
|||||||
contactPhone: "咨询电话",
|
contactPhone: "咨询电话",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** 申请内容:按办理表单 schema 显示中文 label 与分组(详情出参 formSchemaJson) */
|
||||||
|
const contentGroups = ref<FormDataGroup[]>([]);
|
||||||
|
|
||||||
const cols = [
|
const cols = [
|
||||||
{ title: "办件号", key: "id", width: 90 },
|
{ title: "办件号", key: "id", width: 90 },
|
||||||
{ title: "事项", key: "itemTitle", minWidth: 180 },
|
{ title: "事项", key: "itemTitle", minWidth: 180 },
|
||||||
@@ -99,6 +103,7 @@ async function openDetail(row: ApplyVo) {
|
|||||||
progress.value = null;
|
progress.value = null;
|
||||||
try {
|
try {
|
||||||
detail.value = (await applyApi.detail(row.id).send()) as any;
|
detail.value = (await applyApi.detail(row.id).send()) as any;
|
||||||
|
contentGroups.value = buildFormDataGroups(detail.value?.formSchemaJson, detail.value?.formDataJson);
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
Message.error(e?.message || "加载办件详情失败");
|
Message.error(e?.message || "加载办件详情失败");
|
||||||
} finally {
|
} finally {
|
||||||
@@ -179,11 +184,14 @@ onMounted(async () => {
|
|||||||
|
|
||||||
<template v-if="detail.formDataJson">
|
<template v-if="detail.formDataJson">
|
||||||
<Divider orientation="left">申请内容</Divider>
|
<Divider orientation="left">申请内容</Divider>
|
||||||
<div class="kv" v-for="(v, k) in parse(detail.formDataJson)" :key="String(k)">
|
<template v-for="g in contentGroups" :key="g.title">
|
||||||
<span class="k">{{ k }}</span>
|
<p v-if="g.title !== '申请内容'" class="group-title">{{ g.title }}</p>
|
||||||
<span class="v">{{ displayValue(v) }}</span>
|
<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>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
</template>
|
||||||
|
|
||||||
<Divider orientation="left">审批轨迹</Divider>
|
<Divider orientation="left">审批轨迹</Divider>
|
||||||
<div v-if="!progress || !progress.steps || !progress.steps.length" style="color: #999">
|
<div v-if="!progress || !progress.steps || !progress.steps.length" style="color: #999">
|
||||||
@@ -233,6 +241,12 @@ onMounted(async () => {
|
|||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
border-bottom: 1px dashed #eee;
|
border-bottom: 1px dashed #eee;
|
||||||
}
|
}
|
||||||
|
.group-title {
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 13px;
|
||||||
|
color: #515a6e;
|
||||||
|
margin: 10px 0 2px;
|
||||||
|
}
|
||||||
.k {
|
.k {
|
||||||
width: 110px;
|
width: 110px;
|
||||||
color: #999;
|
color: #999;
|
||||||
|
|||||||
Reference in New Issue
Block a user