Просмотр исходного кода

Merge branch 'development' into uat

LuTong 6 дней назад
Родитель
Сommit
2f205a040c
52 измененных файлов с 17542 добавлено и 410 удалено
  1. 3 1
      .env.development
  2. 5 0
      .env.production
  3. 672 0
      src/api/modules/aiImageUpload.ts
  4. 64 0
      src/api/modules/businessInfo.ts
  5. 1 1
      src/api/modules/contractManagement.ts
  6. 112 74
      src/api/modules/newLoginApi.ts
  7. 1 1
      src/api/modules/scheduledService.ts
  8. 11 2
      src/api/modules/storeDecoration.ts
  9. 7 2
      src/api/modules/upload.ts
  10. 23 2
      src/api/upload.js
  11. 4 0
      src/assets/images/aliIcon.svg
  12. 4 0
      src/assets/images/wechartIcon.svg
  13. BIN
      src/assets/images/yyzz.jpg
  14. 185 16
      src/assets/json/authMenuList.json
  15. 3422 0
      src/assets/json/city.json
  16. 15 9
      src/components/Upload/Imgs.vue
  17. 6 20
      src/stores/modules/auth.ts
  18. 8 0
      src/typings/global.d.ts
  19. 29 0
      src/utils/commonCommentList.ts
  20. 20 0
      src/utils/config.ts
  21. 7 7
      src/views/accountRoleManagement/roleManagement/create.vue
  22. 31 21
      src/views/appoinmentManagement/appoinmentInfo.vue
  23. 7 4
      src/views/appoinmentManagement/classifyManagement.vue
  24. 6 1
      src/views/appoinmentManagement/tableManagement.vue
  25. 2 2
      src/views/businessData/compare.vue
  26. 493 0
      src/views/businessInfo/accountInfo.vue
  27. 461 0
      src/views/businessInfo/adminInfo.vue
  28. 4383 0
      src/views/businessInfo/category.json
  29. 154 0
      src/views/businessInfo/createApply.vue
  30. 356 0
      src/views/businessInfo/dataEntry.vue
  31. 257 0
      src/views/businessInfo/industryQualifications.vue
  32. 1114 0
      src/views/businessInfo/manageInfo.vue
  33. 1149 0
      src/views/businessInfo/subjectInfo.vue
  34. 266 0
      src/views/businessInfo/weChartExamine.vue
  35. 15 0
      src/views/businessInfo/weChartIndex.vue
  36. 253 0
      src/views/businessInfo/zfbExamine.vue
  37. 2458 0
      src/views/businessInfo/zfbIndex.vue
  38. 928 0
      src/views/businessInfo/zfbIndexTwo.vue
  39. 30 26
      src/views/dynamicManagement/index.vue
  40. 23 24
      src/views/dynamicManagement/myDynamic.vue
  41. 1 1
      src/views/dynamicManagement/reviewAppeal.vue
  42. 23 22
      src/views/dynamicManagement/userDynamic.vue
  43. 220 3
      src/views/home/components/go-flow.vue
  44. 14 14
      src/views/operationManagement/activityList.vue
  45. 52 16
      src/views/operationManagement/newActivity.vue
  46. 11 1
      src/views/storeDecoration/basicStoreInformation/index.vue
  47. 0 1
      src/views/storeDecoration/businessHours/index.vue
  48. 37 24
      src/views/storeDecoration/officialPhotoAlbum/index.vue
  49. 45 22
      src/views/storeDecoration/personnelConfig/index.vue
  50. 70 43
      src/views/storeDecoration/storeHeadMap/index.vue
  51. 80 46
      src/views/storeDecoration/storeLabel/index.vue
  52. 4 4
      src/views/ticketManagement/index.vue

+ 3 - 1
.env.development

@@ -24,7 +24,9 @@ VITE_API_URL_PLATFORM = /api/alienStorePlatform
 
 # 开发环境跨域代理,支持配置多个
 # VITE_PROXY = [["/api","https://api.ailien.shop"]] #生产环境
-VITE_PROXY = [["/api","http://120.26.186.130:8000"]] # 邹建宇
+# /ai-upload、/ai-moderate 供 Tus 上传与 AI 审核(见 src/utils/config.ts、src/api/modules/aiImageUpload.ts)
+# 图片上传默认走 AI 审核;若需恢复仅 OSS/uploadMore,设置 VITE_UPLOAD_IMAGE_AI_MODERATE=false
+VITE_PROXY = [["/api","http://120.26.186.130:8000"],["/ai-upload","https://upload.ailien.shop:8443"],["/ai-moderate","https://verify.ailien.shop:8444"]] # 邹建宇
 
 
 # WebSocket 基础地址(分享等能力,与商家端一致)

+ 5 - 0
.env.production

@@ -37,6 +37,11 @@ VITE_PROXY = [["/alienStore","http://120.26.186.130:8000/alienStore"]]
 # AI接口
 VITE_PROXY_AI = [["/ai-api","http://124.93.18.180:9000"]]
 
+# Tus 上传与内容审核(生产构建默认见 src/utils/config.ts;同源反代时可覆盖)
+# VITE_AI_UPLOAD_BASE = https://upload.ailien.shop:8443
+# VITE_AI_MODERATE_BASE = https://verify.ailien.shop:8444
+# VITE_AI_FILES_PUBLIC_BASE = https://upload.ailien.shop:8443/files
+
 # 接口加密配置
 # 加密功能总开关
 VITE_API_ENCRYPTION_ENABLED = false

+ 672 - 0
src/api/modules/aiImageUpload.ts

@@ -0,0 +1,672 @@
+/**
+ * Web 端:Tus 分片上传 + AI 图片审核(与 Apifox / uni 版协议对齐)
+ */
+import { useUserStore } from "@/stores/modules/user";
+import { ResultEnum } from "@/enums/httpEnum";
+import { AI_UPLOAD_FILES_PUBLIC_BASE, BASE_AI_MODERATE_URL, BASE_AI_URL } from "@/utils/config";
+
+const TUS_VERSION = "1.0.0";
+const TUS_CHUNK_SIZE = 1024 * 1024;
+
+const DEFAULT_MODERATE_USER_TIP = "图片未通过内容审核,请更换后重试";
+
+function authHeader(): string {
+  try {
+    return useUserStore().token || "";
+  } catch {
+    return "";
+  }
+}
+
+function mapModerateReasonToUserMessage(raw?: string | null): string {
+  const s = raw == null ? "" : String(raw).trim();
+  if (!s) return DEFAULT_MODERATE_USER_TIP;
+
+  if (/赌|赌博|casino|gambl/i.test(s)) return "图片涉及赌博等违规内容,请更换后重试";
+  if (/色情|淫秽|porn|sex/i.test(s)) return "图片涉及色情等违规内容,请更换后重试";
+  if (/暴力|血腥|violence|gore/i.test(s)) return "图片涉及暴力等违规内容,请更换后重试";
+  if (/辱骂|谩骂|人身攻击|abuse|insult/i.test(s)) return "图片涉及不文明内容,请更换后重试";
+  if (/政治|谣言/i.test(s)) return "图片涉及违规信息,请更换后重试";
+  if (/广告|spam|营销/i.test(s)) return "图片涉及违规推广内容,请更换后重试";
+  if (/违法|违禁|illegal/i.test(s)) return "图片含违法违规内容,请更换后重试";
+  if (/黄赌毒/i.test(s)) return "请勿上传涉黄、涉赌、涉毒等违规内容";
+  if (/审核|moderat|vlm|violation|flagged/i.test(s)) return DEFAULT_MODERATE_USER_TIP;
+
+  return DEFAULT_MODERATE_USER_TIP;
+}
+
+function pickPayload(res: unknown): unknown {
+  if (res == null) return null;
+  if (typeof res === "object" && !Array.isArray(res) && (res as any).data !== undefined) {
+    return (res as any).data;
+  }
+  return res;
+}
+
+function headerGet(headers: Headers, name: string): string {
+  const v = headers.get(name) || headers.get(name.toLowerCase());
+  return v ? String(v).trim() : "";
+}
+
+function pickUploadIdFromLocation(loc: string): string {
+  if (!loc) return "";
+  const m = String(loc).match(/\/files\/([^/?#]+)/);
+  return m ? decodeURIComponent(m[1]) : "";
+}
+
+export function pickUploadIdFromResponse(res: Response, body?: unknown): string {
+  const h = res.headers;
+  const idHdr = headerGet(h, "upload-id") || headerGet(h, "x-upload-id");
+  if (idHdr) return idHdr;
+  const fromLoc = pickUploadIdFromLocation(headerGet(h, "location"));
+  if (fromLoc) return fromLoc;
+
+  const d = pickPayload(body ?? null);
+  const inner = d && typeof d === "object" && (d as any).data !== undefined ? (d as any).data : d;
+  const x = inner && typeof inner === "object" ? (inner as Record<string, unknown>) : {};
+  const id =
+    (x.upload_id as string) || (x.uploadId as string) || (x.id as string) || (typeof inner === "string" ? inner : "") || "";
+  return id || "";
+}
+
+function pickFileUrlFromBody(body: unknown): string {
+  const fromObj = (o: unknown): string => {
+    if (!o || typeof o !== "object" || Array.isArray(o)) return "";
+    const r = o as Record<string, string>;
+    return r.url || r.file_url || r.fileUrl || r.access_url || r.accessUrl || r.ossUrl || r.cdnUrl || "";
+  };
+  const d = pickPayload(body);
+  let inner = d && typeof d === "object" && (d as any).data !== undefined ? (d as any).data : d;
+  let u = fromObj(inner);
+  if (u) return u;
+  if (inner && typeof inner === "object" && (inner as any).data !== undefined) {
+    u = fromObj((inner as any).data);
+  }
+  if (u) return u;
+  if (typeof inner === "string" && inner.startsWith("http")) return inner;
+  return typeof d === "string" && d.startsWith("http") ? d : "";
+}
+
+/** 创建上传会话 POST /upload */
+export async function createUploadSession(data: {
+  filename: string;
+  size: number;
+}): Promise<{ response: Response; body: unknown }> {
+  const res = await fetch(`${BASE_AI_URL}/upload`, {
+    method: "POST",
+    headers: {
+      "Content-Type": "application/json",
+      "Tus-Resumable": TUS_VERSION,
+      Authorization: authHeader()
+    },
+    body: JSON.stringify(data)
+  });
+  let body: unknown = null;
+  const ct = res.headers.get("content-type") || "";
+  if (ct.includes("application/json")) {
+    try {
+      body = await res.json();
+    } catch {
+      body = null;
+    }
+  } else {
+    const t = await res.text();
+    body = t || null;
+  }
+  if (res.status < 200 || res.status >= 300) {
+    const msg =
+      body && typeof body === "object" && (body as any).message
+        ? String((body as any).message)
+        : `创建上传会话失败(${res.status})`;
+    throw new Error(msg);
+  }
+  if (body && typeof body === "object" && (body as any).code !== undefined) {
+    const c = (body as any).code;
+    if (c !== 200 && c !== 0) {
+      throw new Error((body as any).msg || (body as any).message || "创建上传会话失败");
+    }
+  }
+  return { response: res, body };
+}
+
+/** PATCH 二进制分片 */
+export async function patchBinaryToUpload(uploadId: string, arrayBuffer: ArrayBuffer, uploadOffset = 0): Promise<Response> {
+  const url = `${BASE_AI_URL}/files/${encodeURIComponent(uploadId)}`;
+  const res = await fetch(url, {
+    method: "PATCH",
+    headers: {
+      Authorization: authHeader(),
+      "Tus-Resumable": TUS_VERSION,
+      "Content-Type": "application/offset+octet-stream",
+      "Upload-Offset": String(uploadOffset)
+    },
+    body: arrayBuffer
+  });
+  if (res.status >= 200 && res.status < 300) {
+    return res;
+  }
+  const t = await res.text().catch(() => "");
+  throw new Error(`上传失败(${res.status})${t ? ` ${t.slice(0, 200)}` : ""}`);
+}
+
+export async function patchBinaryToUploadChunked(
+  uploadId: string,
+  arrayBuffer: ArrayBuffer,
+  onProgress?: (ratio: number) => void
+): Promise<void> {
+  const total = arrayBuffer.byteLength;
+  if (total === 0) {
+    await patchBinaryToUpload(uploadId, new ArrayBuffer(0), 0);
+    onProgress?.(1);
+    return;
+  }
+  let offset = 0;
+  while (offset < total) {
+    const end = Math.min(offset + TUS_CHUNK_SIZE, total);
+    const chunk = arrayBuffer.slice(offset, end);
+    await patchBinaryToUpload(uploadId, chunk, offset);
+    offset = end;
+    onProgress?.(offset / total);
+  }
+}
+
+/** HEAD /files/{id} */
+export async function getUploadProgress(uploadId: string): Promise<Response> {
+  return fetch(`${BASE_AI_URL}/files/${encodeURIComponent(uploadId)}`, {
+    method: "HEAD",
+    headers: {
+      Authorization: authHeader(),
+      "Tus-Resumable": TUS_VERSION,
+      "Content-Type": "application/octet-stream"
+    }
+  });
+}
+
+/** DELETE /files/{id} */
+export async function deleteUploadSession(uploadId: string): Promise<void> {
+  await fetch(`${BASE_AI_URL}/files/${encodeURIComponent(uploadId)}`, {
+    method: "DELETE",
+    headers: {
+      Authorization: authHeader(),
+      "Tus-Resumable": TUS_VERSION
+    }
+  });
+}
+
+/** POST /upload/{id}/finalize */
+export async function finalizeUploadSession(uploadId: string, data: Record<string, unknown> = {}): Promise<unknown> {
+  const res = await fetch(`${BASE_AI_URL}/upload/${encodeURIComponent(uploadId)}/finalize`, {
+    method: "POST",
+    headers: {
+      "Content-Type": "application/json",
+      "Tus-Resumable": TUS_VERSION,
+      Authorization: authHeader()
+    },
+    body: JSON.stringify(data)
+  });
+  let body: unknown = null;
+  const ct = res.headers.get("content-type") || "";
+  if (ct.includes("application/json")) {
+    try {
+      body = await res.json();
+    } catch {
+      body = null;
+    }
+  } else {
+    body = await res.text();
+  }
+  if (res.status < 200 || res.status >= 300) {
+    throw new Error(`上传完成确认失败(${res.status})`);
+  }
+  if (body && typeof body === "object" && (body as any).code !== undefined) {
+    const c = (body as any).code;
+    if (c !== 200 && c !== 0) {
+      throw new Error((body as any).msg || (body as any).message || "上传完成确认失败");
+    }
+  }
+  return body;
+}
+
+export interface ModerateImageParams {
+  text?: string;
+  image_urls?: string | string[];
+  file?: File | null;
+}
+
+/** POST multipart /api/v1/moderate,文件字段名 files */
+export async function moderateImage(params: ModerateImageParams = {}): Promise<any> {
+  const urlsStr = Array.isArray(params.image_urls)
+    ? params.image_urls.filter(Boolean).join(",")
+    : String(params.image_urls ?? "");
+
+  const fd = new FormData();
+  fd.append("text", String(params.text ?? ""));
+  fd.append("image_urls", urlsStr);
+  if (params.file) {
+    fd.append("files", params.file, params.file.name);
+  }
+
+  const res = await fetch(`${BASE_AI_MODERATE_URL}/api/v1/moderate`, {
+    method: "POST",
+    headers: {
+      Authorization: authHeader()
+    },
+    body: fd
+  });
+
+  let body: any = null;
+  const ct = res.headers.get("content-type") || "";
+  if (ct.includes("application/json")) {
+    try {
+      body = await res.json();
+    } catch {
+      body = null;
+    }
+  } else {
+    const t = await res.text();
+    try {
+      body = t ? JSON.parse(t) : null;
+    } catch {
+      body = { raw: t };
+    }
+  }
+
+  if (res.status < 200 || res.status >= 300) {
+    throw new Error(`审核请求失败(${res.status})`);
+  }
+  if (body && typeof body === "object" && body.code !== undefined && body.code !== 200 && body.code !== 0) {
+    throw new Error(body.msg || body.message || "审核请求失败");
+  }
+  return body;
+}
+
+export interface ModerateVideoParams {
+  /** 可选;与图片同一套 Tus 上传后应只传 `video_url`,不在此再传文件 */
+  file?: File | null;
+  filePath?: string;
+  path?: string;
+  /** 服务端视频地址,无 Tus 时可传空字符串 */
+  video_path?: string;
+  /** 标题/简介等 */
+  text?: string;
+  /** 远程 http(s) 视频地址 */
+  video_url?: string;
+}
+
+/**
+ * 仅提交「已上传视频」的审核任务:POST `/api/v1/video/submit`
+ * 与图片共用 Tus 上传拿到地址后,传 `video_url`;`getVideoModerateResult` 查询审核进度/结果。
+ */
+export async function moderateVideo(params: ModerateVideoParams = {}): Promise<any> {
+  const fd = new FormData();
+  fd.append("video_path", String(params.video_path ?? ""));
+  fd.append("text", String(params.text ?? ""));
+  fd.append("video_url", String(params.video_url ?? ""));
+
+  const file = params.file ?? null;
+  if (file) {
+    fd.append("file", file, file.name);
+  }
+
+  const res = await fetch(`${BASE_AI_MODERATE_URL}/api/v1/video/submit`, {
+    method: "POST",
+    headers: {
+      Authorization: authHeader()
+    },
+    body: fd
+  });
+
+  let body: any = null;
+  const ct = res.headers.get("content-type") || "";
+  if (ct.includes("application/json")) {
+    try {
+      body = await res.json();
+    } catch {
+      body = null;
+    }
+  } else {
+    const t = await res.text();
+    try {
+      body = t ? JSON.parse(t) : null;
+    } catch {
+      body = { raw: t };
+    }
+  }
+
+  if (res.status < 200 || res.status >= 300) {
+    throw new Error(`视频审核提交失败(${res.status})`);
+  }
+  if (body && typeof body === "object" && body.code !== undefined && body.code !== 200 && body.code !== 0) {
+    throw new Error(body.msg || body.message || "视频审核提交失败");
+  }
+  return body;
+}
+
+/**
+ * 查询视频审核进度与结果:GET `/api/v1/video/status/{task_id}`
+ * @param data.task_id 或传入字符串即 task_id
+ */
+export async function getVideoModerateResult(data: { task_id?: string } | string): Promise<any> {
+  const taskId = typeof data === "string" ? data : String(data?.task_id ?? "").trim();
+  if (!taskId) {
+    throw new Error("缺少 task_id");
+  }
+
+  const res = await fetch(`${BASE_AI_MODERATE_URL}/api/v1/video/status/${encodeURIComponent(taskId)}`, {
+    method: "GET",
+    headers: {
+      Authorization: authHeader()
+    }
+  });
+
+  let body: any = null;
+  const ct = res.headers.get("content-type") || "";
+  if (ct.includes("application/json")) {
+    try {
+      body = await res.json();
+    } catch {
+      body = null;
+    }
+  } else {
+    const t = await res.text();
+    try {
+      body = t ? JSON.parse(t) : null;
+    } catch {
+      body = { raw: t };
+    }
+  }
+
+  if (res.status < 200 || res.status >= 300) {
+    throw new Error(`查询视频审核状态失败(${res.status})`);
+  }
+  if (body && typeof body === "object" && body.code !== undefined && body.code !== 200 && body.code !== 0) {
+    throw new Error(body.msg || body.message || "查询视频审核状态失败");
+  }
+  return body;
+}
+
+function mapVideoModerateReasonToUserMessage(raw?: string | null): string {
+  return mapModerateReasonToUserMessage(raw).replace(/图片/g, "视频");
+}
+
+function pickVideoTaskIdFromSubmit(res: unknown): string {
+  const r = res as Record<string, any> | null | undefined;
+  if (!r || typeof r !== "object") return "";
+  let cur: any = r.data !== undefined ? r.data : r;
+  if (cur && typeof cur === "object" && cur.data !== undefined) cur = cur.data;
+  if (cur && typeof cur === "object") {
+    return String(cur.task_id ?? cur.taskId ?? cur.taskID ?? "").trim();
+  }
+  return "";
+}
+
+function flattenVideoStatusPayload(body: Record<string, any>): Record<string, any> {
+  const d = body?.data;
+  if (d && typeof d === "object" && !Array.isArray(d)) {
+    return { ...body, ...d };
+  }
+  return body;
+}
+
+function isVideoModerationStatusTerminal(payload: Record<string, any>): boolean {
+  const p = flattenVideoStatusPayload(payload);
+  const s = String(p?.status ?? p?.state ?? "").toLowerCase();
+  const terminal = [
+    "completed",
+    "complete",
+    "success",
+    "succeeded",
+    "done",
+    "finished",
+    "failed",
+    "fail",
+    "rejected",
+    "error",
+    "cancelled",
+    "canceled"
+  ];
+  if (terminal.includes(s)) return true;
+  const r = p?.result;
+  if (r && typeof r === "object" && (r.flagged !== undefined || r.passed !== undefined || r.approved !== undefined)) {
+    return true;
+  }
+  return false;
+}
+
+function isVideoModerationRejectedPayload(payload: Record<string, any>): boolean {
+  const p = flattenVideoStatusPayload(payload);
+  if (p?.flagged === true) return true;
+  const r = p?.result;
+  if (r && typeof r === "object" && r.flagged === true) return true;
+  const s = String(p?.status ?? "").toLowerCase();
+  if (["failed", "fail", "rejected", "error"].includes(s)) return true;
+  return false;
+}
+
+function pickVideoRejectReason(payload: Record<string, any>): string | null {
+  const p = flattenVideoStatusPayload(payload);
+  const r = p?.result;
+  const fromResult = r && typeof r === "object" ? (r.reason ?? r.message) : null;
+  const raw = fromResult ?? p?.reason ?? p?.message ?? p?.msg;
+  return raw != null && typeof raw === "string" ? raw : null;
+}
+
+/**
+ * 是否为视频(MIME 或后缀)。上传与图片同走 Tus;通过后以 `moderateVideo({ video_url })` + 轮询区分审核链路。
+ */
+export function isLikelyVideoFileForAiUpload(file: File): boolean {
+  if (!(file instanceof File)) return false;
+  if (typeof file.type === "string" && file.type.startsWith("video/")) return true;
+  const n = file.name || "";
+  return /\.(mp4|m4v|webm|ogg|mov)(\?.*)?$/i.test(n);
+}
+
+/**
+ * Tus 上传 → finalize → 返回公网 URL(图片/视频同一套上传;不含审核)
+ */
+async function uploadViaTusToPublicUrl(file: File, onProgress?: (p: number) => void): Promise<string> {
+  const report = (n: number) => onProgress?.(Math.min(100, Math.max(0, Math.round(n))));
+  report(5);
+  const buf = await file.arrayBuffer();
+  const size = buf.byteLength;
+  report(18);
+
+  const defaultName = isLikelyVideoFileForAiUpload(file) ? `video_${Date.now()}.mp4` : `img_${Date.now()}.jpg`;
+  const { response: sessionRes, body: sessionBody } = await createUploadSession({
+    filename: file.name || defaultName,
+    size
+  });
+  const uploadId = pickUploadIdFromResponse(sessionRes, sessionBody);
+  if (!uploadId) {
+    throw new Error("创建上传会话失败:未返回 upload_id");
+  }
+
+  const publicUrl = `${AI_UPLOAD_FILES_PUBLIC_BASE}/${uploadId}`;
+
+  report(35);
+  await patchBinaryToUploadChunked(uploadId, buf, ratio => {
+    report(35 + ratio * (82 - 35));
+  });
+  report(82);
+
+  const finalizeBody = await finalizeUploadSession(uploadId, {});
+  report(90);
+
+  const urlFromApi = pickFileUrlFromBody(finalizeBody);
+  const fileUrl = urlFromApi || publicUrl;
+  if (!fileUrl) {
+    throw new Error("上传完成确认失败:未返回文件地址");
+  }
+  return fileUrl;
+}
+
+/**
+ * Tus 已得到视频 URL:`moderateVideo` 仅提交审核(video_url),`getVideoModerateResult` 轮询至结束。
+ */
+async function submitAndAwaitVideoModeration(fileUrl: string, onProgress?: (p: number) => void): Promise<void> {
+  const report = (n: number) => onProgress?.(Math.min(100, Math.max(0, Math.round(n))));
+  const submitRes: any = await moderateVideo({ video_url: fileUrl, text: "", video_path: "" });
+  report(92);
+  const taskId = pickVideoTaskIdFromSubmit(submitRes);
+  const submitFlat =
+    submitRes && typeof submitRes === "object" ? flattenVideoStatusPayload(submitRes as Record<string, any>) : {};
+
+  if (!taskId) {
+    if (isVideoModerationStatusTerminal(submitFlat)) {
+      if (isVideoModerationRejectedPayload(submitFlat)) {
+        throw new Error(mapVideoModerateReasonToUserMessage(pickVideoRejectReason(submitFlat)));
+      }
+      return;
+    }
+    const c = submitRes?.code;
+    if (c === 200 || c === 0) return;
+    throw new Error("视频审核提交未返回任务信息,请稍后重试");
+  }
+
+  const maxMs = 5 * 60 * 1000;
+  const step = 2000;
+  const t0 = Date.now();
+  let pollCount = 0;
+  while (Date.now() - t0 < maxMs) {
+    const raw: any = await getVideoModerateResult(taskId);
+    const flat = raw && typeof raw === "object" ? flattenVideoStatusPayload(raw as Record<string, any>) : {};
+    pollCount += 1;
+    report(Math.min(98, 92 + Math.min(6, pollCount)));
+
+    if (isVideoModerationStatusTerminal(flat)) {
+      if (isVideoModerationRejectedPayload(flat)) {
+        throw new Error(mapVideoModerateReasonToUserMessage(pickVideoRejectReason(flat)));
+      }
+      return;
+    }
+    await new Promise<void>(resolve => setTimeout(resolve, step));
+  }
+  throw new Error("视频审核等待超时,请稍后重试");
+}
+
+export interface UploadFileViaAiOptions {
+  /** 0~100 */
+  onProgress?: (progress: number) => void;
+  /** 为 true 时跳过审核(仅上传) */
+  skipModerate?: boolean;
+}
+
+/**
+ * 图片与视频均:Tus 上传 → finalize 得同一套访问 URL。
+ * 图片再 `moderateImage`;视频再 `moderateVideo({ video_url })` + `getVideoModerateResult` 轮询。`skipModerate` 则只上传不审。
+ */
+export async function uploadFileViaAi(file: File, options: UploadFileViaAiOptions = {}): Promise<string> {
+  const { onProgress, skipModerate } = options;
+
+  const report = (p: number) => {
+    onProgress?.(Math.min(100, Math.max(0, Math.round(p))));
+  };
+
+  try {
+    const fileUrl = await uploadViaTusToPublicUrl(file, onProgress);
+
+    if (!skipModerate) {
+      if (isLikelyVideoFileForAiUpload(file)) {
+        await submitAndAwaitVideoModeration(fileUrl, onProgress);
+      } else {
+        const moderateRes = await moderateImage({
+          text: "",
+          image_urls: fileUrl,
+          file
+        });
+        const first = moderateRes?.results?.[0];
+        if (first?.flagged) {
+          if (first.reason) console.warn("[AI审核]", first.reason);
+          throw new Error(mapModerateReasonToUserMessage(first.reason));
+        }
+      }
+    }
+
+    report(100);
+    return fileUrl;
+  } catch (e) {
+    throw e;
+  }
+}
+
+/** 与 /file/uploadMore 成功态兼容,供 Upload 组件、http 封装统一消费 */
+export type UploadMoreLikeResponse = {
+  code: number;
+  msg: string;
+  data: { fileUrl: string };
+  /** 部分组件直接读顶层 fileUrl */
+  fileUrl: string;
+};
+
+export function isAiImageModerationEnabled(): boolean {
+  return import.meta.env.VITE_UPLOAD_IMAGE_AI_MODERATE !== "false";
+}
+
+/** 图/视频均 Tus 上传;图 moderateImage、视频 moderateVideo(url)+轮询;返回与 uploadMore 相近结构 */
+export async function uploadImageAsUploadMoreResponse(file: File): Promise<UploadMoreLikeResponse> {
+  const fileUrl = await uploadFileViaAi(file);
+  return {
+    code: ResultEnum.SUCCESS,
+    msg: "success",
+    data: { fileUrl },
+    fileUrl
+  };
+}
+
+/**
+ * FormData 内含字段 `file` 且为图片或视频时走 Tus + 对应审核(图 moderateImage,视频 moderateVideo 的 video_url + 轮询),否则走原接口
+ */
+export function runUploadMoreWithOptionalAi<T = UploadMoreLikeResponse>(
+  params: FormData,
+  fallback: () => Promise<T>
+): Promise<T> {
+  if (!isAiImageModerationEnabled()) {
+    return fallback();
+  }
+  const file = params.get("file");
+  if (!(file instanceof File)) {
+    return fallback();
+  }
+  const isImage = typeof file.type === "string" && file.type.startsWith("image/");
+  const isVideo = isLikelyVideoFileForAiUpload(file);
+  if (isImage || isVideo) {
+    return uploadImageAsUploadMoreResponse(file) as Promise<T>;
+  }
+  return fallback();
+}
+
+/** 多文件顺序上传,整体进度 0~100 */
+export async function uploadFilesViaAi(files: File[], options: UploadFileViaAiOptions = {}): Promise<string[]> {
+  const list = files.filter(f => f instanceof File);
+  if (!list.length) return [];
+
+  const n = list.length;
+  const urls: string[] = [];
+  for (let i = 0; i < n; i++) {
+    const u = await uploadFileViaAi(list[i], {
+      ...options,
+      onProgress: p => {
+        const overall = (i / n) * 100 + (p / 100) * (100 / n);
+        options.onProgress?.(overall);
+      }
+    });
+    urls.push(u);
+  }
+  return urls;
+}
+
+/** 与 uni 版 aiApi 命名对齐的聚合对象,便于按需解构 */
+export const aiImageApi = {
+  createUploadSession: (data: { filename: string; size: number }) => createUploadSession(data),
+  patchBinaryToUpload,
+  getUploadProgress,
+  deleteUploadSession,
+  finalizeUploadSession,
+  moderateImage,
+  moderateVideo,
+  getVideoModerateResult,
+  uploadFileViaAi,
+  uploadFilesViaAi
+};
+
+export default aiImageApi;

+ 64 - 0
src/api/modules/businessInfo.ts

@@ -0,0 +1,64 @@
+import httpLogin from "@/api/indexApi";
+
+/**
+ * @name 商家信息
+ */
+
+// 营业执照上传
+export const getUpload = (params: any) => {
+  return httpLogin.post(`alienStore/payment/wechatPartner/v3/merchant/media/upload`, params);
+};
+
+export const getOcrRequestByBase64 = (params: any) => {
+  return httpLogin.post(`alienStore/ali/ocrRequestByBase64`, params);
+};
+
+/** POST,storeId 走 URL 查询参数,请求体为 JSON */
+export const applyment = (data: Record<string, unknown> | object, storeId: string | number) => {
+  return httpLogin.post(`alienStore/payment/wechatPartner/v3/applyment4sub/applyment`, data, {
+    params: { storeId },
+    headers: { "Content-Type": "application/json;charset=UTF-8" }
+  });
+};
+
+/** GET,storeId 为路径参数 */
+export const applymentExamine = (storeId: string | number) => {
+  const id = encodeURIComponent(String(storeId).trim());
+  return httpLogin.get(`alienStore/payment/wechatPartner/applyment/store/${id}`);
+};
+
+export const getPaymentApplyment = (applymentId: string | number) => {
+  const id = encodeURIComponent(String(applymentId).trim());
+  return httpLogin.get(`alienStore/payment/wechatPartner/v3/applyment4sub/applyment/applyment_id/${id}`);
+};
+
+/** 支付宝直付通图片上传:multipart,字段 image_type + image_content(二进制) */
+export interface UploadAlipayImageParams {
+  /** 图片格式扩展名,3~16 字符,如 jpg、png(支持 bmp、jpg、jpeg、png、gif) */
+  imageType: string;
+  /** 图片原始二进制流 */
+  imageContent: Blob | File;
+  storeId?: string | number | null;
+}
+
+export const uploadAlipayImage = (params: UploadAlipayImageParams, axiosConfig?: object) => {
+  const fd = new FormData();
+  const { imageType, imageContent, storeId } = params;
+  if (storeId !== undefined && storeId !== null && String(storeId).trim() !== "") {
+    fd.append("storeId", String(storeId));
+  }
+  fd.append("imageType", imageType);
+  fd.append("imageContent", imageContent);
+  return httpLogin.post(`alienStore/store/alipay/zft/image/upload`, fd, {
+    encrypt: false,
+    ...axiosConfig
+  });
+};
+
+export const getAlipayZftCreate = (params: any) => {
+  return httpLogin.post(`alienStore/store/alipay/zft/create`, params);
+};
+
+export const getAlipayExamine = (params: any) => {
+  return httpLogin.post(`alienStore/store/alipay/zft/order/query`, params);
+};

+ 1 - 1
src/api/modules/contractManagement.ts

@@ -10,7 +10,7 @@ import { LOGIN_URL } from "@/config";
 import router from "@/routers";
 
 // 合同接口专用配置 - 使用不同的端口
-const CONTRACT_BASE_URL = "http://120.26.186.130:33333";
+const CONTRACT_BASE_URL = "https://120.26.186.130";
 
 // 创建专门用于合同接口的 axios 实例
 // 注意:不使用 withCredentials,因为认证通过 Authorization header 传递,且服务器 CORS 配置为通配符

+ 112 - 74
src/api/modules/newLoginApi.ts

@@ -1,6 +1,7 @@
 import type { Login } from "@/api/interface";
 import httpLogin from "@/api/indexApi";
 import { Upload } from "@/api/interface/index";
+import { runUploadMoreWithOptionalAi } from "@/api/modules/aiImageUpload";
 // 获取图片验证码
 export const getImgCode = () => {
   return httpLogin.get(
@@ -61,9 +62,11 @@ export const getInputPrompt = params => {
 export const getDistrict = params => {
   return httpLogin.get(`/alienStore/gaode/getDistrict`, params);
 };
-//文件上传
+//文件上传(图片默认走 Tus + AI 审核,可设 VITE_UPLOAD_IMAGE_AI_MODERATE=false 关闭)
 export const uploadImg = (params: FormData) => {
-  return httpLogin.post<Upload.ResFileUrl>(`/alienStore/file/uploadMore`, params, { cancel: false });
+  return runUploadMoreWithOptionalAi(params, () =>
+    httpLogin.post<Upload.ResFileUrl>(`/alienStore/file/uploadMore`, params, { cancel: false })
+  );
 };
 // 发布/更新动态(新接口)
 export const addOrUpdateDynamic = (params: {
@@ -208,86 +211,121 @@ export const addAppealNew = (params: FormData | Record<string, unknown>) => {
 };
 
 // 动态-------------------------------------------------------------------------------------
-/** 商家端 commonComment/addComment:发表评论/回复(评价回复 sourceType=1,动态评论 sourceType=2) */
-// 发表评论 - 表单形式提交(字符串键值对,非 JSON 对象)
-export const addComment = (data: {
-  commentContent: string;
-  businessType: number;
-  businessId: string | number;
-  storeId: string;
-  phoneId: string;
-  replyId: string;
-  commentStar: string;
-  multipartRequest: string;
-}) => {
-  const formData = new FormData();
-  formData.append("commentContent", data.commentContent);
-  formData.append("businessType", String(data.businessType));
-  formData.append("businessId", String(data.businessId));
-  formData.append("storeId", data.storeId);
-  formData.append("phoneId", data.phoneId);
-  formData.append("replyId", data.replyId);
-  formData.append("commentStar", data.commentStar);
-  formData.append("multipartRequest", data.multipartRequest);
-  return httpLogin.post(`/alienStore/storeComment/saveComment`, formData);
+/** commonComment/addComment 请求体(与接口模型一致;新增评论一般只传部分字段) */
+export interface AddCommonCommentBody {
+  auditReason?: string;
+  /** 0-待审核 1-通过 2-驳回 */
+  auditStatus?: number;
+  /** 1-用户评论 2-商户评论(仅回复) */
+  commentType?: number;
+  content?: string;
+  createdTime?: string;
+  /** 0-未删除 1-已删除 */
+  deleteFlag?: number;
+  extInfo?: string;
+  id?: number;
+  imageUrls?: string;
+  /** 0-否 1-是(仅用户评论生效) */
+  isAnonymous?: number;
+  /** 0-隐藏 1-展示 */
+  isShow?: number;
+  likeCount?: number;
+  /** commentType=2 时必填 */
+  merchantId?: number;
+  /** 0=根评论,>0=回复某条评论 */
+  parentId?: number;
+  replyCount?: number;
+  /** sourceType=1 rating.id;=2 动态ID;=3 打卡;=4 二手商品 */
+  sourceId?: number;
+  /** 1-评价的评论 2-动态 3-打卡 4-二手商品 */
+  sourceType?: number;
+  updatedTime?: string;
+  /** 用户=用户ID,商户=商户运营账号ID */
+  userId?: number;
+}
+
+function omitUndefinedRecord(obj: Record<string, unknown>): Record<string, unknown> {
+  return Object.fromEntries(Object.entries(obj).filter(([, v]) => v !== undefined && v !== null));
+}
+
+/** 将可转为整型的 id 字段转为 number,无法转换则返回 undefined */
+function toInt64(v: unknown): number | undefined {
+  if (v === undefined || v === null || v === "") return undefined;
+  const n = Number(v);
+  return Number.isFinite(n) ? Math.trunc(n) : undefined;
+}
+
+function buildSaveCommentBody(params: any): AddCommonCommentBody {
+  const businessType = Number(params.businessType ?? 2);
+  const isRating = businessType === 1;
+  const sourceType = isRating ? 1 : 2;
+  const sourceIdRaw = isRating ? (params.replyId ?? params.businessId) : (params.businessId ?? params.sourceId);
+  const parentId = isRating ? 0 : Number(params.replyId || 0);
+  const merchantRaw = params.merchantId ?? params.storeId ?? (isRating ? params.businessId : undefined);
+
+  const body: AddCommonCommentBody = {
+    userId: toInt64(params.userId ?? params.phoneId),
+    sourceType,
+    sourceId: toInt64(sourceIdRaw),
+    parentId,
+    content: String(params.commentContent ?? params.content ?? ""),
+    commentType: Number(params.commentType ?? 2),
+    merchantId: toInt64(merchantRaw),
+    isAnonymous: params.isAnonymous !== undefined ? Number(params.isAnonymous) : 0
+  };
+
+  if (params.auditReason != null && params.auditReason !== "") body.auditReason = String(params.auditReason);
+  if (params.auditStatus !== undefined) body.auditStatus = Number(params.auditStatus);
+  if (params.createdTime) body.createdTime = String(params.createdTime);
+  if (params.deleteFlag !== undefined) body.deleteFlag = Number(params.deleteFlag);
+  if (params.extInfo != null && params.extInfo !== "") body.extInfo = String(params.extInfo);
+  if (params.id !== undefined && params.id !== null && params.id !== "") {
+    const idNum = toInt64(params.id);
+    if (idNum !== undefined) body.id = idNum;
+  }
+  if (params.imageUrls != null && params.imageUrls !== "") body.imageUrls = String(params.imageUrls);
+  if (params.isShow !== undefined) body.isShow = Number(params.isShow);
+  if (params.likeCount !== undefined) body.likeCount = Number(params.likeCount);
+  if (params.replyCount !== undefined) body.replyCount = Number(params.replyCount);
+  if (params.updatedTime) body.updatedTime = String(params.updatedTime);
+
+  return body;
+}
+
+/** 商家端 commonComment/addComment,请求体字段与接口一致 */
+export const addComment = (data: AddCommonCommentBody) => {
+  const raw: Record<string, unknown> = { ...data };
+  return httpLogin.post(`/alienStore/commonComment/addComment`, omitUndefinedRecord(raw));
 };
 
 /**
- * 发表评论/回复(兼容旧参数,内部转为 addComment)
- * - 评价回复:businessType=1,replyId=评价ID → sourceType=1, sourceId=replyId, parentId=0
- * - 动态评论:businessType=2,businessId=动态ID,replyId 有值为回复评论ID → sourceType=2, sourceId=businessId, parentId=replyId||0
+ * 发表评论/回复(兼容旧入参:businessId、replyId、commentContent、phoneId/userId、businessType、storeId
+ * - businessType=1:评价相关,sourceType=1,sourceId 取 replyId/businessId,parentId=0
+ * - businessType=2:动态,sourceType=2,sourceId=动态 id,parentId=回复的评论 id 或 0
  */
 export const saveComment = (params: any) => {
-  const businessType = Number(params.businessType ?? 0);
-  const isRating = businessType === 1;
-  const payload = {
-    commentContent: String(params.commentContent ?? params.content ?? ""),
-    businessType: 2,
-    businessId: isRating ? params.replyId : params.businessId,
-    storeId: String(params.storeId ?? ""),
-    phoneId: String(params.userId ?? params.phoneId ?? ""),
-    replyId: String(params.replyId ?? ""),
-    commentStar: "",
-    multipartRequest: ""
-  };
-  return addComment(payload);
+  return addComment(buildSaveCommentBody(params));
 };
 
 // 评价-------------------------------------------------------------------------------------
-export const addComment2 = (data: {
-  sourceType: number; // 1-评价的评论 2-动态等
-  sourceId: string | number; // 评价ID或动态ID
-  userId: string;
-  parentId: number; // 0-根评论
-  content: string;
-  commentType: number; // 2-商户评论
-  merchantId: string;
-  isAnonymous?: number;
-}) => {
-  return httpLogin.post(`/alienStore/commonComment/addComment`, {
-    ...data,
-    isAnonymous: data.isAnonymous ?? 0
-  });
-};
-export const saveComment2 = (params: any) => {
-  const businessType = Number(params.businessType ?? 0);
-  const isRating = businessType === 1;
-  const payload = {
-    sourceType: isRating ? 1 : 2,
-    sourceId: isRating ? params.replyId : params.businessId,
-    userId: String(params.userId ?? params.phoneId ?? ""),
-    parentId: isRating ? 0 : Number(params.replyId || 0),
-    content: String(params.commentContent ?? params.content ?? ""),
-    commentType: 2,
-    merchantId: String(params.merchantId ?? params.storeId ?? params.businessId ?? ""),
-    isAnonymous: 0
-  };
-  return addComment2(payload);
-};
-
-//评论列表
-export const commentList = (params: any) => {
-  return httpLogin.get(`/alienStore/storeComment/getList`, params);
+export const addComment2 = (data: AddCommonCommentBody) => addComment(data);
+
+export const saveComment2 = (params: any) => saveComment(params);
+
+/** 评论列表查询(getListBySourceType) */
+export interface CommentListParams {
+  pageNum: number;
+  pageSize: number;
+  /** 来源 id,如动态 id */
+  sourceId: number | string;
+  /** 1-评价 2-动态 3-打卡 4-二手商品 */
+  sourceType: number;
+  /** 可选,评论发布者/当前用户 id */
+  userId?: number;
+}
+
+export const commentList = (params: CommentListParams) => {
+  return httpLogin.get(`/alienStore/commonComment/getListBySourceType`, params);
 };
 
 //我的动态

+ 1 - 1
src/api/modules/scheduledService.ts

@@ -148,7 +148,7 @@ export const reservationCancel = (params: {
 };
 
 /** 删除预约 */
-export const reservationDelete = (params: { id: number | string }) => {
+export const reservationDelete = (params: { reservationId: number | string }) => {
   const formData = Object.keys(params)
     .map(key => `${encodeURIComponent(key)}=${encodeURIComponent(String(params[key as keyof typeof params]))}`)
     .join("&");

+ 11 - 2
src/api/modules/storeDecoration.ts

@@ -3,6 +3,7 @@ import { PORT_NONE } from "@/api/config/servicePort";
 import http from "@/api";
 import httpApi from "@/api/indexApi";
 import { Upload } from "@/api/interface/index";
+import { runUploadMoreWithOptionalAi } from "@/api/modules/aiImageUpload";
 
 /**
  * @name 商铺用户模块
@@ -64,12 +65,16 @@ export const saveOrUpdateDecoration = (params: any) => {
 
 // 上传房屋图纸 - 使用 /alienStore/file/uploadMore 接口
 export const uploadDecorationImage = (params: FormData) => {
-  return httpApi.post<Upload.ResFileUrl>(`/alienStore/file/uploadMore`, params, { cancel: false });
+  return runUploadMoreWithOptionalAi(params, () =>
+    httpApi.post<Upload.ResFileUrl>(`/alienStore/file/uploadMore`, params, { cancel: false })
+  );
 };
 
 // 聊天图片/视频上传(与商家端一致,使用同一接口)
 export const uploadChatFile = (params: FormData) => {
-  return httpApi.post<Upload.ResFileUrl>(`/alienStore/file/uploadMore`, params, { cancel: false });
+  return runUploadMoreWithOptionalAi(params, () =>
+    httpApi.post<Upload.ResFileUrl>(`/alienStore/file/uploadMore`, params, { cancel: false })
+  );
 };
 
 // 删除装修需求
@@ -200,6 +205,10 @@ export const importBarMenuExcel = (formData: FormData, storeId: string | number)
 export const getAllTagType = (params?: any) => {
   return httpApi.get(`/alienStorePlatform/storePlatformTag/getBusinessRelationTagList`, params);
 };
+/** 门店标签列表/数据:GET /alienStore/store/tag/getTagList */
+export const getTagList = (params?: Record<string, any>) => {
+  return httpApi.get(`/alienStore/store/tag/getTagList`, params, { loading: false });
+};
 //获取所有所选标签
 export const getAllTag = (params: any) => {
   return httpApi.get(`/alienStorePlatform/storePlatformTag/getTagStoreRelationByStoreId`, params);

+ 7 - 2
src/api/modules/upload.ts

@@ -1,4 +1,5 @@
 import { Upload } from "@/api/interface/index";
+import { runUploadMoreWithOptionalAi } from "@/api/modules/aiImageUpload";
 import { PORT1 } from "@/api/config/servicePort";
 import { PORT_NONE } from "@/api/config/servicePort";
 import httpStore from "@/api/indexStore";
@@ -48,12 +49,16 @@ httpStoreAlienStore.interceptors.response.use(
  */
 // 图片上传(默认使用 alienStorePlatform)
 export const uploadImg = (params: FormData) => {
-  return httpStore.post<Upload.ResFileUrl>(PORT_NONE + `/file/uploadMore`, params, { cancel: false });
+  return runUploadMoreWithOptionalAi(params, () =>
+    httpStore.post<Upload.ResFileUrl>(PORT_NONE + `/file/uploadMore`, params, { cancel: false })
+  );
 };
 
 // 图片上传(使用 alienStore 前缀,用于价目表等页面)
 export const uploadImgStore = (params: FormData) => {
-  return httpStoreAlienStore.post<Upload.ResFileUrl>(PORT_NONE + `/file/uploadMore`, params, { cancel: false });
+  return runUploadMoreWithOptionalAi(params, () =>
+    httpStoreAlienStore.post<Upload.ResFileUrl>(PORT_NONE + `/file/uploadMore`, params, { cancel: false })
+  );
 };
 
 // 视频上传

+ 23 - 2
src/api/upload.js

@@ -1,5 +1,6 @@
 import { useUserStore } from "@/stores/modules/user";
 import { ElMessage } from "element-plus";
+import { isAiImageModerationEnabled, uploadFileViaAi, isLikelyVideoFileForAiUpload } from "@/api/modules/aiImageUpload";
 
 /**
  * 门店/文件相关接口基址(与 src/api/modules/upload.ts 中 httpStoreAlienStore 一致)
@@ -113,7 +114,8 @@ async function postFileToOss(signRes, file, key) {
 }
 
 /**
- * 上传文件到 OSS:先 GET 获取签名,再 POST 到 OSS host(与 src/api/1.js 逻辑一致,Web 使用 File / FormData)
+ * 上传文件:视频一律走 Tus + moderateVideo / 轮询(uploadFileViaAi),不走 OSS;
+ * 开启 AI 时图片走 Tus+审核,否则图片与其它类型走 OSS 直传。
  * @param {File | File[] | FileList} files 浏览器文件对象;支持单个 File、数组或 FileList
  * @param {string} [fileType] 文件类型(如 'image' | 'video'),用于在文件名无后缀时推断格式
  * @param {{ showLoading?: boolean }} [options] showLoading 为 true 时用 ElMessage 提示上传中(非阻塞)
@@ -133,11 +135,30 @@ export async function uploadFilesToOss(files, fileType, options = {}) {
   }
 
   try {
-    const signRes = await fetchOssSignature();
+    let signRes = null;
     const uploadedUrls = [];
+    const useAiImage = isAiImageModerationEnabled();
 
     for (let i = 0; i < fileArr.length; i++) {
       const file = fileArr[i];
+      const isImageBranch = fileType === "image" || (!fileType && file.type && String(file.type).startsWith("image/"));
+      const isVideoBranch = fileType === "video" || isLikelyVideoFileForAiUpload(file);
+
+      if (isVideoBranch) {
+        const url = await uploadFileViaAi(file, { skipModerate: !useAiImage });
+        uploadedUrls.push(url);
+        continue;
+      }
+
+      if (useAiImage && isImageBranch) {
+        const url = await uploadFileViaAi(file);
+        uploadedUrls.push(url);
+        continue;
+      }
+
+      if (!signRes) {
+        signRes = await fetchOssSignature();
+      }
       const filePath = file.name || "";
       const ext = getFileExtension(filePath, fileType);
       const rawBase = filePath.split("/").pop() || "";

+ 4 - 0
src/assets/images/aliIcon.svg

@@ -0,0 +1,4 @@
+<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
+<rect width="20" height="20" rx="4" fill="#3386FF"/>
+<path d="M10.5571 10.6307C4.93455 8.36098 3.27909 9.70237 2.82724 9.96026C-0.936511 12.6944 2.57633 15.7896 3.17853 15.9959C7.14401 16.9245 9.75374 15.1705 11.5108 13.0039C11.6613 13.1062 11.7115 13.1062 11.8119 13.1586C13.0165 13.8293 18.8891 16.6666 18.8891 16.6666V13.2618C17.9856 13.2618 14.8235 12.1269 12.4642 11.353C13.6688 9.08325 14.1207 6.91664 14.1207 6.91664H10.0552V5.31736H14.924V4.64667H10.0552V2.22217H7.84678V4.59509H3.42964V5.31736H7.84678V6.91664H4.08302V7.58734H11.6615M9.55321 12.3328C6.79253 15.9443 3.48082 14.8092 2.92761 14.6029C1.62264 14.1388 1.17079 11.7658 2.82724 10.992C5.58793 10.0634 8.04731 11.0943 9.80413 12.0237C9.72697 12.1321 9.64316 12.2353 9.55321 12.3328Z" fill="white"/>
+</svg>

+ 4 - 0
src/assets/images/wechartIcon.svg

@@ -0,0 +1,4 @@
+<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
+<rect width="20" height="20" rx="4" fill="#04DC00"/>
+<path d="M9.1038 11.4409C8.37226 11.8425 8.26376 11.2155 8.26376 11.2155L7.34693 9.10871C6.99416 8.1076 7.65225 8.65732 7.65225 8.65732C7.65225 8.65732 8.21691 9.07797 8.64546 9.3343C9.07378 9.59063 9.562 9.40955 9.562 9.40955L15.5558 6.68528C14.4499 5.33031 12.6232 4.44434 10.5551 4.44434C7.18006 4.44434 4.44434 6.80212 4.44434 9.71077C4.44434 11.3838 5.35022 12.8728 6.76124 13.838L6.50677 15.2784C6.50677 15.2784 6.38273 15.6989 6.81264 15.5038C7.10558 15.3708 7.85241 14.8943 8.29697 14.6043C8.99586 14.8441 9.75728 14.9773 10.5555 14.9773C13.9303 14.9773 16.6666 12.6195 16.6666 9.71078C16.6666 8.86829 16.436 8.07265 16.0276 7.36643C14.1179 8.49784 9.67621 11.1272 9.1038 11.4409Z" fill="white"/>
+</svg>

BIN
src/assets/images/yyzz.jpg


+ 185 - 16
src/assets/json/authMenuList.json

@@ -410,7 +410,7 @@
           "component": "/storeDecoration/officialPhotoAlbum/index",
           "meta": {
             "icon": "Files",
-            "title": "官方相册",
+            "title": "相册",
             "isLink": "",
             "isHide": false,
             "isFull": false,
@@ -1318,20 +1318,6 @@
           }
         },
         {
-          "path": "/appoinmentManagement/appoinmentInfo",
-          "name": "appoinmentInfo",
-          "component": "/appoinmentManagement/appoinmentInfo",
-          "meta":{
-            "icon": "ChatDotSquare",
-            "title": "预定信息",
-            "isLink": "",
-            "isHide": false,
-            "isFull": false,
-            "isAffix": false,
-            "isKeepAlive": false
-          }
-        },
-        {
           "path": "/appoinmentManagement/infoManagement",
           "name": "infoManagement",
           "component": "/appoinmentManagement/infoManagement",
@@ -1347,7 +1333,7 @@
         }
       ]
     },
-     {
+      {
       "path": "/appoinmentManagement/appoinmentInfo",
       "name": "appoinmentInfo",
       "component": "/appoinmentManagement/appoinmentInfo",
@@ -1360,7 +1346,190 @@
         "isAffix": false,
         "isKeepAlive": false
       }
+    },{
+      "path": "/businessInfo",
+      "name": "businessInfo",
+      "component": "/businessInfo",
+      "meta":{
+        "icon": "ChatDotSquare",
+        "title": "设置收款账号",
+        "isLink": "",
+        "isHide": false,
+        "isFull": false,
+        "isAffix": false,
+        "isKeepAlive": false
+      },
+      "children": [
+        {
+          "path": "/businessInfo/weChartIndex",
+          "name": "/businessInfo/weChartIndex",
+          "component": "/businessInfo/weChartIndex",
+          "meta":{
+            "icon": "ChatDotSquare",
+            "title": "绑定微信账号",
+            "isLink": "",
+            "isHide": false,
+            "isFull": false,
+            "isAffix": false,
+            "isKeepAlive": false
+          }
+        },
+        {
+          "path": "/businessInfo/weChartExamine",
+          "name": "/businessInfo/weChartExamine",
+          "component": "/businessInfo/weChartExamine",
+          "meta":{
+            "icon": "ChatDotSquare",
+            "title": "查看微信审核状态",
+            "isLink": "",
+            "isHide": false,
+            "isFull": false,
+            "isAffix": false,
+            "isKeepAlive": false
+          }
+        },
+        {
+          "path": "/businessInfo/createApply",
+          "name": "/businessInfo/createApply",
+          "component": "/businessInfo/createApply",
+          "meta":{
+            "icon": "Document",
+            "title": "选择主体类型",
+            "isLink": "",
+            "isHide": true,
+            "isFull": false,
+            "isAffix": false,
+            "isKeepAlive": false
+          }
+        },{
+          "path": "/businessInfo/dataEntry",
+          "name": "/businessInfo/dataEntry",
+          "component": "/businessInfo/dataEntry",
+          "meta":{
+            "icon": "Document",
+            "title": "选择主体类型",
+            "isLink": "",
+            "isHide": true,
+            "isFull": false,
+            "isAffix": false,
+            "isKeepAlive": false
+          }
+        },
+        {
+          "path": "/businessInfo/subjectInfo",
+          "name": "/businessInfo/subjectInfo",
+          "component": "/businessInfo/subjectInfo",
+          "meta":{
+            "icon": "User",
+            "title": "主体信息",
+            "isLink": "",
+            "isHide": true,
+            "isFull": false,
+            "isAffix": false,
+            "isKeepAlive": false
+          }
+        },
+        {
+          "path": "/businessInfo/manageInfo",
+          "name": "/businessInfo/manageInfo",
+          "component": "/businessInfo/manageInfo",
+          "meta":{
+            "icon": "OfficeBuilding",
+            "title": "经营信息",
+            "isLink": "",
+            "isHide": true,
+            "isFull": false,
+            "isAffix": false,
+            "isKeepAlive": false
+          }
+        },
+        {
+          "path": "/businessInfo/industryQualifications",
+          "name": "/businessInfo/industryQualifications",
+          "component": "/businessInfo/industryQualifications",
+          "meta":{
+            "icon": "Document",
+            "title": "行业资质",
+            "isLink": "",
+            "isHide": true,
+            "isFull": false,
+            "isAffix": false,
+            "isKeepAlive": false
+          }
+        },
+        {
+          "path": "/businessInfo/accountInfo",
+          "name": "/businessInfo/accountInfo",
+          "component": "/businessInfo/accountInfo",
+          "meta":{
+            "icon": "Wallet",
+            "title": "结算账户",
+            "isLink": "",
+            "isHide": true,
+            "isFull": false,
+            "isAffix": false,
+            "isKeepAlive": false
+          }
+        },
+        {
+          "path": "/businessInfo/adminInfo",
+          "name": "/businessInfo/adminInfo",
+          "component": "/businessInfo/adminInfo",
+          "meta":{
+            "icon": "UserFilled",
+            "title": "超级管理员",
+            "isLink": "",
+            "isHide": true,
+            "isFull": false,
+            "isAffix": false,
+            "isKeepAlive": false
+          }
+        },
+         {
+          "path": "/businessInfo/zfbIndex",
+          "name": "/businessInfo/zfbIndex",
+          "component": "/businessInfo/zfbIndex",
+          "meta":{
+            "icon": "ChatDotSquare",
+            "title": "绑定支付宝账号",
+            "isLink": "",
+            "isHide": false,
+            "isFull": false,
+            "isAffix": false,
+            "isKeepAlive": false
+          }
+        },
+       {
+          "path": "/businessInfo/zfbIndexTwo",
+          "name": "/businessInfo/zfbIndexTwo",
+          "component": "/businessInfo/zfbIndexTwo",
+          "meta":{
+            "icon": "ChatDotSquare",
+            "title": "完善结算信息",
+            "isLink": "",
+            "isHide": true,
+            "isFull": false,
+            "isAffix": false,
+            "isKeepAlive": false
+          }
+        },
+        {
+          "path": "/businessInfo/zfbExamine",
+          "name": "/businessInfo/zfbExamine",
+          "component": "/businessInfo/zfbExamine",
+          "meta":{
+            "icon": "ChatDotSquare",
+            "title": "查看支付宝审核状态",
+            "isLink": "",
+            "isHide": false,
+            "isFull": false,
+            "isAffix": false,
+            "isKeepAlive": false
+          }
+        }
+      ]
     }
   ],
   "msg": "成功"
 }
+

+ 3422 - 0
src/assets/json/city.json

@@ -0,0 +1,3422 @@
+{
+    "cityList": [
+        {
+            "letter": "A",
+            "list": [
+                {
+                    "name": "阿克苏市",
+                    "adCode": "652901",
+                    "cityCode": "0997"
+                },
+                {
+                    "name": "阿拉尔市",
+                    "adCode": "659002",
+                    "cityCode": "1997"
+                },
+                {
+                    "name": "阿拉山口市",
+                    "adCode": "652702",
+                    "cityCode": "0909"
+                },
+                {
+                    "name": "阿勒泰市",
+                    "adCode": "654301",
+                    "cityCode": "0906"
+                },
+                {
+                    "name": "阿图什市",
+                    "adCode": "653001",
+                    "cityCode": "0908"
+                },
+                {
+                    "name": "安达市",
+                    "adCode": "231281",
+                    "cityCode": "0455"
+                },
+                {
+                    "name": "安国市",
+                    "adCode": "130683",
+                    "cityCode": "0312"
+                },
+                {
+                    "name": "安康市",
+                    "adCode": "610900",
+                    "cityCode": "0915"
+                },
+                {
+                    "name": "安陆市",
+                    "adCode": "420982",
+                    "cityCode": "0712"
+                },
+                {
+                    "name": "安宁市",
+                    "adCode": "530181",
+                    "cityCode": "0871"
+                },
+                {
+                    "name": "安庆市",
+                    "adCode": "340800",
+                    "cityCode": "0556"
+                },
+                {
+                    "name": "安丘市",
+                    "adCode": "370784",
+                    "cityCode": "0536"
+                },
+                {
+                    "name": "安顺市",
+                    "adCode": "520400",
+                    "cityCode": "0853"
+                },
+                {
+                    "name": "安阳市",
+                    "adCode": "410500",
+                    "cityCode": "0372"
+                },
+                {
+                    "name": "鞍山市",
+                    "adCode": "210300",
+                    "cityCode": "0412"
+                }
+            ]
+        },
+        {
+            "letter": "B",
+            "list": [
+                {
+                    "name": "巴彦淖尔市",
+                    "adCode": "150800",
+                    "cityCode": "0478"
+                },
+                {
+                    "name": "巴中市",
+                    "adCode": "511900",
+                    "cityCode": "0827"
+                },
+                {
+                    "name": "霸州市",
+                    "adCode": "131081",
+                    "cityCode": "0316"
+                },
+                {
+                    "name": "白城市",
+                    "adCode": "220800",
+                    "cityCode": "0436"
+                },
+                {
+                    "name": "白山市",
+                    "adCode": "220600",
+                    "cityCode": "0439"
+                },
+                {
+                    "name": "白银市",
+                    "adCode": "620400",
+                    "cityCode": "0943"
+                },
+                {
+                    "name": "百色市",
+                    "adCode": "451000",
+                    "cityCode": "0776"
+                },
+                {
+                    "name": "蚌埠市",
+                    "adCode": "340300",
+                    "cityCode": "0552"
+                },
+                {
+                    "name": "包头市",
+                    "adCode": "150200",
+                    "cityCode": "0472"
+                },
+                {
+                    "name": "宝鸡市",
+                    "adCode": "610300",
+                    "cityCode": "0917"
+                },
+                {
+                    "name": "保定市",
+                    "adCode": "130600",
+                    "cityCode": "0312"
+                },
+                {
+                    "name": "保山市",
+                    "adCode": "530500",
+                    "cityCode": "0875"
+                },
+                {
+                    "name": "北安市",
+                    "adCode": "231181",
+                    "cityCode": "0456"
+                },
+                {
+                    "name": "北海市",
+                    "adCode": "450500",
+                    "cityCode": "0779"
+                },
+                {
+                    "name": "北京市",
+                    "adCode": "110000",
+                    "cityCode": "010",
+                    "type": "hot"
+                },
+                {
+                    "name": "北流市",
+                    "adCode": "450981",
+                    "cityCode": "0775"
+                },
+                {
+                    "name": "北票市",
+                    "adCode": "211381",
+                    "cityCode": "0421"
+                },
+                {
+                    "name": "北屯市",
+                    "adCode": "659005",
+                    "cityCode": "1906"
+                },
+                {
+                    "name": "北镇市",
+                    "adCode": "210782",
+                    "cityCode": "0416"
+                },
+                {
+                    "name": "本溪市",
+                    "adCode": "210500",
+                    "cityCode": "0414"
+                },
+                {
+                    "name": "毕节市",
+                    "adCode": "520500",
+                    "cityCode": "0857"
+                },
+                {
+                    "name": "滨州市",
+                    "adCode": "371600",
+                    "cityCode": "0543"
+                },
+                {
+                    "name": "泊头市",
+                    "adCode": "130981",
+                    "cityCode": "0317"
+                },
+                {
+                    "name": "亳州市",
+                    "adCode": "341600",
+                    "cityCode": "0558"
+                },
+                {
+                    "name": "博乐市",
+                    "adCode": "652701",
+                    "cityCode": "0909"
+                }
+            ]
+        },
+        {
+            "letter": "C",
+            "list": [
+                {
+                    "name": "沧州市",
+                    "adCode": "130900",
+                    "cityCode": "0317"
+                },
+                {
+                    "name": "岑溪市",
+                    "adCode": "450481",
+                    "cityCode": "0774"
+                },
+                {
+                    "name": "昌都市",
+                    "adCode": "540300",
+                    "cityCode": "0895"
+                },
+                {
+                    "name": "昌吉市",
+                    "adCode": "652301",
+                    "cityCode": "0994"
+                },
+                {
+                    "name": "昌邑市",
+                    "adCode": "370786",
+                    "cityCode": "0536"
+                },
+                {
+                    "name": "常德市",
+                    "adCode": "430700",
+                    "cityCode": "0736"
+                },
+                {
+                    "name": "常宁市",
+                    "adCode": "430482",
+                    "cityCode": "0734"
+                },
+                {
+                    "name": "常熟市",
+                    "adCode": "320581",
+                    "cityCode": "0512"
+                },
+                {
+                    "name": "常州市",
+                    "adCode": "320400",
+                    "cityCode": "0519"
+                },
+                {
+                    "name": "巢湖市",
+                    "adCode": "340181",
+                    "cityCode": "0551"
+                },
+                {
+                    "name": "朝阳市",
+                    "adCode": "211300",
+                    "cityCode": "0421"
+                },
+                {
+                    "name": "潮州市",
+                    "adCode": "445100",
+                    "cityCode": "0768"
+                },
+                {
+                    "name": "郴州市",
+                    "adCode": "431000",
+                    "cityCode": "0735"
+                },
+                {
+                    "name": "成都市",
+                    "adCode": "510100",
+                    "cityCode": "028",
+                    "type": "hot"
+                },
+                {
+                    "name": "承德市",
+                    "adCode": "130800",
+                    "cityCode": "0314"
+                },
+                {
+                    "name": "池州市",
+                    "adCode": "341700",
+                    "cityCode": "0566"
+                },
+                {
+                    "name": "赤壁市",
+                    "adCode": "421281",
+                    "cityCode": "0715"
+                },
+                {
+                    "name": "赤峰市",
+                    "adCode": "150400",
+                    "cityCode": "0476"
+                },
+                {
+                    "name": "赤水市",
+                    "adCode": "520381",
+                    "cityCode": "0852"
+                },
+                {
+                    "name": "崇州市",
+                    "adCode": "510184",
+                    "cityCode": "028"
+                },
+                {
+                    "name": "崇左市",
+                    "adCode": "451400",
+                    "cityCode": "1771"
+                },
+                {
+                    "name": "滁州市",
+                    "adCode": "341100",
+                    "cityCode": "0550"
+                },
+                {
+                    "name": "楚雄市",
+                    "adCode": "532301",
+                    "cityCode": "0878"
+                },
+                {
+                    "name": "慈溪市",
+                    "adCode": "330282",
+                    "cityCode": "0574"
+                },
+                {
+                    "name": "长春市",
+                    "adCode": "220100",
+                    "cityCode": "0431",
+                    "type": "hot"
+                },
+                {
+                    "name": "长葛市",
+                    "adCode": "411082",
+                    "cityCode": "0374"
+                },
+                {
+                    "name": "长乐市",
+                    "adCode": "350182",
+                    "cityCode": "0591"
+                },
+                {
+                    "name": "长沙市",
+                    "adCode": "430100",
+                    "cityCode": "0731",
+                    "type": "hot"
+                },
+                {
+                    "name": "长治市",
+                    "adCode": "140400",
+                    "cityCode": "0355"
+                },
+                {
+                    "name": "重庆市",
+                    "adCode": "500000",
+                    "cityCode": "023",
+                    "type": "hot"
+                }
+            ]
+        },
+        {
+            "letter": "D",
+            "list": [
+                {
+                    "name": "达州市",
+                    "adCode": "511700",
+                    "cityCode": "0818"
+                },
+                {
+                    "name": "大安市",
+                    "adCode": "220882",
+                    "cityCode": "0436"
+                },
+                {
+                    "name": "大理市",
+                    "adCode": "532901",
+                    "cityCode": "0872"
+                },
+                {
+                    "name": "大连市",
+                    "adCode": "210200",
+                    "cityCode": "0411",
+                    "type": "hot"
+                },
+                {
+                    "name": "大庆市",
+                    "adCode": "230600",
+                    "cityCode": "0459"
+                },
+                {
+                    "name": "大石桥市",
+                    "adCode": "210882",
+                    "cityCode": "0417"
+                },
+                {
+                    "name": "大同市",
+                    "adCode": "140200",
+                    "cityCode": "0352"
+                },
+                {
+                    "name": "大冶市",
+                    "adCode": "420281",
+                    "cityCode": "0714"
+                },
+                {
+                    "name": "丹东市",
+                    "adCode": "210600",
+                    "cityCode": "0415"
+                },
+                {
+                    "name": "丹江口市",
+                    "adCode": "420381",
+                    "cityCode": "0719"
+                },
+                {
+                    "name": "丹阳市",
+                    "adCode": "321181",
+                    "cityCode": "0511"
+                },
+                {
+                    "name": "儋州市",
+                    "adCode": "460400",
+                    "cityCode": "0805"
+                },
+                {
+                    "name": "当阳市",
+                    "adCode": "420582",
+                    "cityCode": "0717"
+                },
+                {
+                    "name": "德惠市",
+                    "adCode": "220183",
+                    "cityCode": "0431"
+                },
+                {
+                    "name": "德令哈市",
+                    "adCode": "632802",
+                    "cityCode": "0977"
+                },
+                {
+                    "name": "德兴市",
+                    "adCode": "361181",
+                    "cityCode": "0793"
+                },
+                {
+                    "name": "德阳市",
+                    "adCode": "510600",
+                    "cityCode": "0838"
+                },
+                {
+                    "name": "德州市",
+                    "adCode": "371400",
+                    "cityCode": "0534"
+                },
+                {
+                    "name": "灯塔市",
+                    "adCode": "211081",
+                    "cityCode": "0419"
+                },
+                {
+                    "name": "登封市",
+                    "adCode": "410185",
+                    "cityCode": "0371"
+                },
+                {
+                    "name": "邓州市",
+                    "adCode": "411381",
+                    "cityCode": "0377"
+                },
+                {
+                    "name": "定西市",
+                    "adCode": "621100",
+                    "cityCode": "0932"
+                },
+                {
+                    "name": "定州市",
+                    "adCode": "130682",
+                    "cityCode": "0312"
+                },
+                {
+                    "name": "东方市",
+                    "adCode": "469007",
+                    "cityCode": "0807"
+                },
+                {
+                    "name": "东港市",
+                    "adCode": "210681",
+                    "cityCode": "0415"
+                },
+                {
+                    "name": "东莞市",
+                    "adCode": "441900",
+                    "cityCode": "0769"
+                },
+                {
+                    "name": "东宁市",
+                    "adCode": "231086",
+                    "cityCode": "0453"
+                },
+                {
+                    "name": "东台市",
+                    "adCode": "320981",
+                    "cityCode": "0515"
+                },
+                {
+                    "name": "东兴市",
+                    "adCode": "450681",
+                    "cityCode": "0770"
+                },
+                {
+                    "name": "东阳市",
+                    "adCode": "330783",
+                    "cityCode": "0579"
+                },
+                {
+                    "name": "东营市",
+                    "adCode": "370500",
+                    "cityCode": "0546"
+                },
+                {
+                    "name": "都江堰市",
+                    "adCode": "510181",
+                    "cityCode": "028"
+                },
+                {
+                    "name": "都匀市",
+                    "adCode": "522701",
+                    "cityCode": "0854"
+                },
+                {
+                    "name": "敦化市",
+                    "adCode": "222403",
+                    "cityCode": "1433"
+                },
+                {
+                    "name": "敦煌市",
+                    "adCode": "620982",
+                    "cityCode": "0937"
+                }
+            ]
+        },
+        {
+            "letter": "E",
+            "list": [
+                {
+                    "name": "峨眉山市",
+                    "adCode": "511181",
+                    "cityCode": "0833"
+                },
+                {
+                    "name": "额尔古纳市",
+                    "adCode": "150784",
+                    "cityCode": "0470"
+                },
+                {
+                    "name": "鄂尔多斯市",
+                    "adCode": "150600",
+                    "cityCode": "0477"
+                },
+                {
+                    "name": "鄂州市",
+                    "adCode": "420700",
+                    "cityCode": "0711"
+                },
+                {
+                    "name": "恩平市",
+                    "adCode": "440785",
+                    "cityCode": "0750"
+                },
+                {
+                    "name": "恩施市",
+                    "adCode": "422801",
+                    "cityCode": "0718"
+                },
+                {
+                    "name": "二连浩特市",
+                    "adCode": "152501",
+                    "cityCode": "0479"
+                }
+            ]
+        },
+        {
+            "letter": "F",
+            "list": [
+                {
+                    "name": "防城港市",
+                    "adCode": "450600",
+                    "cityCode": "0770"
+                },
+                {
+                    "name": "肥城市",
+                    "adCode": "370983",
+                    "cityCode": "0538"
+                },
+                {
+                    "name": "汾阳市",
+                    "adCode": "141182",
+                    "cityCode": "0358"
+                },
+                {
+                    "name": "丰城市",
+                    "adCode": "360981",
+                    "cityCode": "0795"
+                },
+                {
+                    "name": "丰镇市",
+                    "adCode": "150981",
+                    "cityCode": "0474"
+                },
+                {
+                    "name": "凤城市",
+                    "adCode": "210682",
+                    "cityCode": "0415"
+                },
+                {
+                    "name": "佛山市",
+                    "adCode": "440600",
+                    "cityCode": "0757",
+                    "type": "hot"
+                },
+                {
+                    "name": "扶余市",
+                    "adCode": "220781",
+                    "cityCode": "0438"
+                },
+                {
+                    "name": "福安市",
+                    "adCode": "350981",
+                    "cityCode": "0593"
+                },
+                {
+                    "name": "福鼎市",
+                    "adCode": "350982",
+                    "cityCode": "0593"
+                },
+                {
+                    "name": "福清市",
+                    "adCode": "350181",
+                    "cityCode": "0591"
+                },
+                {
+                    "name": "福泉市",
+                    "adCode": "522702",
+                    "cityCode": "0854"
+                },
+                {
+                    "name": "福州市",
+                    "adCode": "350100",
+                    "cityCode": "0591"
+                },
+                {
+                    "name": "抚顺市",
+                    "adCode": "210400",
+                    "cityCode": "0413"
+                },
+                {
+                    "name": "抚远市",
+                    "adCode": "230883",
+                    "cityCode": "0454"
+                },
+                {
+                    "name": "抚州市",
+                    "adCode": "361000",
+                    "cityCode": "0794"
+                },
+                {
+                    "name": "阜康市",
+                    "adCode": "652302",
+                    "cityCode": "0994"
+                },
+                {
+                    "name": "阜新市",
+                    "adCode": "210900",
+                    "cityCode": "0418"
+                },
+                {
+                    "name": "阜阳市",
+                    "adCode": "341200",
+                    "cityCode": "1558"
+                },
+                {
+                    "name": "富锦市",
+                    "adCode": "230882",
+                    "cityCode": "0454"
+                }
+            ]
+        },
+        {
+            "letter": "G",
+            "list": [
+                {
+                    "name": "盖州市",
+                    "adCode": "210881",
+                    "cityCode": "0417"
+                },
+                {
+                    "name": "赣州市",
+                    "adCode": "360700",
+                    "cityCode": "0797"
+                },
+                {
+                    "name": "高安市",
+                    "adCode": "360983",
+                    "cityCode": "0795"
+                },
+                {
+                    "name": "高碑店市",
+                    "adCode": "130684",
+                    "cityCode": "0312"
+                },
+                {
+                    "name": "高密市",
+                    "adCode": "370785",
+                    "cityCode": "0536"
+                },
+                {
+                    "name": "高平市",
+                    "adCode": "140581",
+                    "cityCode": "0356"
+                },
+                {
+                    "name": "高邮市",
+                    "adCode": "321084",
+                    "cityCode": "0514"
+                },
+                {
+                    "name": "高州市",
+                    "adCode": "440981",
+                    "cityCode": "0668"
+                },
+                {
+                    "name": "格尔木市",
+                    "adCode": "632801",
+                    "cityCode": "0977"
+                },
+                {
+                    "name": "个旧市",
+                    "adCode": "532501",
+                    "cityCode": "0873"
+                },
+                {
+                    "name": "根河市",
+                    "adCode": "150785",
+                    "cityCode": "0470"
+                },
+                {
+                    "name": "公主岭市",
+                    "adCode": "220381",
+                    "cityCode": "0434"
+                },
+                {
+                    "name": "巩义市",
+                    "adCode": "410181",
+                    "cityCode": "0371"
+                },
+                {
+                    "name": "共青城市",
+                    "adCode": "360482",
+                    "cityCode": "0792"
+                },
+                {
+                    "name": "古交市",
+                    "adCode": "140181",
+                    "cityCode": "0351"
+                },
+                {
+                    "name": "固原市",
+                    "adCode": "640400",
+                    "cityCode": "0954"
+                },
+                {
+                    "name": "广安市",
+                    "adCode": "511600",
+                    "cityCode": "0826"
+                },
+                {
+                    "name": "广汉市",
+                    "adCode": "510681",
+                    "cityCode": "0838"
+                },
+                {
+                    "name": "广水市",
+                    "adCode": "421381",
+                    "cityCode": "0722"
+                },
+                {
+                    "name": "广元市",
+                    "adCode": "510800",
+                    "cityCode": "0839"
+                },
+                {
+                    "name": "广州市",
+                    "adCode": "440100",
+                    "cityCode": "020",
+                    "type": "hot"
+                },
+                {
+                    "name": "贵港市",
+                    "adCode": "450800",
+                    "cityCode": "1755"
+                },
+                {
+                    "name": "贵溪市",
+                    "adCode": "360681",
+                    "cityCode": "0701"
+                },
+                {
+                    "name": "贵阳市",
+                    "adCode": "520100",
+                    "cityCode": "0851",
+                    "type": "hot"
+                },
+                {
+                    "name": "桂林市",
+                    "adCode": "450300",
+                    "cityCode": "0773"
+                },
+                {
+                    "name": "桂平市",
+                    "adCode": "450881",
+                    "cityCode": "1755"
+                }
+            ]
+        },
+        {
+            "letter": "H",
+            "list": [
+                {
+                    "name": "哈尔滨市",
+                    "adCode": "230100",
+                    "cityCode": "0451"
+                },
+                {
+                    "name": "哈密市",
+                    "adCode": "650500",
+                    "cityCode": "0902"
+                },
+                {
+                    "name": "海城市",
+                    "adCode": "210381",
+                    "cityCode": "0412"
+                },
+                {
+                    "name": "海东市",
+                    "adCode": "630200",
+                    "cityCode": "0972"
+                },
+                {
+                    "name": "海口市",
+                    "adCode": "460100",
+                    "cityCode": "0898",
+                    "type": "hot"
+                },
+                {
+                    "name": "海林市",
+                    "adCode": "231083",
+                    "cityCode": "0453"
+                },
+                {
+                    "name": "海伦市",
+                    "adCode": "231283",
+                    "cityCode": "0455"
+                },
+                {
+                    "name": "海门市",
+                    "adCode": "320684",
+                    "cityCode": "0513"
+                },
+                {
+                    "name": "海宁市",
+                    "adCode": "330481",
+                    "cityCode": "0573"
+                },
+                {
+                    "name": "海阳市",
+                    "adCode": "370687",
+                    "cityCode": "0535"
+                },
+                {
+                    "name": "邯郸市",
+                    "adCode": "130400",
+                    "cityCode": "0310"
+                },
+                {
+                    "name": "韩城市",
+                    "adCode": "610581",
+                    "cityCode": "0913"
+                },
+                {
+                    "name": "汉川市",
+                    "adCode": "420984",
+                    "cityCode": "0712"
+                },
+                {
+                    "name": "汉中市",
+                    "adCode": "610700",
+                    "cityCode": "0916"
+                },
+                {
+                    "name": "杭州市",
+                    "adCode": "330100",
+                    "cityCode": "0571",
+                    "type": "hot"
+                },
+                {
+                    "name": "合肥市",
+                    "adCode": "340100",
+                    "cityCode": "0551",
+                    "type": "hot"
+                },
+                {
+                    "name": "合山市",
+                    "adCode": "451381",
+                    "cityCode": "1772"
+                },
+                {
+                    "name": "合作市",
+                    "adCode": "623001",
+                    "cityCode": "0941"
+                },
+                {
+                    "name": "和龙市",
+                    "adCode": "222406",
+                    "cityCode": "1433"
+                },
+                {
+                    "name": "和田市",
+                    "adCode": "653201",
+                    "cityCode": "0903"
+                },
+                {
+                    "name": "河池市",
+                    "adCode": "451200",
+                    "cityCode": "0778"
+                },
+                {
+                    "name": "河间市",
+                    "adCode": "130984",
+                    "cityCode": "0317"
+                },
+                {
+                    "name": "河津市",
+                    "adCode": "140882",
+                    "cityCode": "0359"
+                },
+                {
+                    "name": "河源市",
+                    "adCode": "441600",
+                    "cityCode": "0762"
+                },
+                {
+                    "name": "菏泽市",
+                    "adCode": "371700",
+                    "cityCode": "0530"
+                },
+                {
+                    "name": "贺州市",
+                    "adCode": "451100",
+                    "cityCode": "1774"
+                },
+                {
+                    "name": "鹤壁市",
+                    "adCode": "410600",
+                    "cityCode": "0392"
+                },
+                {
+                    "name": "鹤岗市",
+                    "adCode": "230400",
+                    "cityCode": "0468"
+                },
+                {
+                    "name": "鹤山市",
+                    "adCode": "440784",
+                    "cityCode": "0750"
+                },
+                {
+                    "name": "黑河市",
+                    "adCode": "231100",
+                    "cityCode": "0456"
+                },
+                {
+                    "name": "衡水市",
+                    "adCode": "131100",
+                    "cityCode": "0318"
+                },
+                {
+                    "name": "衡阳市",
+                    "adCode": "430400",
+                    "cityCode": "0734"
+                },
+                {
+                    "name": "洪湖市",
+                    "adCode": "421083",
+                    "cityCode": "0716"
+                },
+                {
+                    "name": "洪江市",
+                    "adCode": "431281",
+                    "cityCode": "0745"
+                },
+                {
+                    "name": "侯马市",
+                    "adCode": "141081",
+                    "cityCode": "0357"
+                },
+                {
+                    "name": "呼和浩特市",
+                    "adCode": "150100",
+                    "cityCode": "0471"
+                },
+                {
+                    "name": "呼伦贝尔市",
+                    "adCode": "150700",
+                    "cityCode": "0470"
+                },
+                {
+                    "name": "葫芦岛市",
+                    "adCode": "211400",
+                    "cityCode": "0429"
+                },
+                {
+                    "name": "湖州市",
+                    "adCode": "330500",
+                    "cityCode": "0572"
+                },
+                {
+                    "name": "虎林市",
+                    "adCode": "230381",
+                    "cityCode": "0467"
+                },
+                {
+                    "name": "华阴市",
+                    "adCode": "610582",
+                    "cityCode": "0913"
+                },
+                {
+                    "name": "华蓥市",
+                    "adCode": "511681",
+                    "cityCode": "0826"
+                },
+                {
+                    "name": "化州市",
+                    "adCode": "440982",
+                    "cityCode": "0668"
+                },
+                {
+                    "name": "桦甸市",
+                    "adCode": "220282",
+                    "cityCode": "0432"
+                },
+                {
+                    "name": "怀化市",
+                    "adCode": "431200",
+                    "cityCode": "0745"
+                },
+                {
+                    "name": "淮安市",
+                    "adCode": "320800",
+                    "cityCode": "0517"
+                },
+                {
+                    "name": "淮北市",
+                    "adCode": "340600",
+                    "cityCode": "0561"
+                },
+                {
+                    "name": "淮南市",
+                    "adCode": "340400",
+                    "cityCode": "0554"
+                },
+                {
+                    "name": "黄冈市",
+                    "adCode": "421100",
+                    "cityCode": "0713"
+                },
+                {
+                    "name": "黄骅市",
+                    "adCode": "130983",
+                    "cityCode": "0317"
+                },
+                {
+                    "name": "黄山市",
+                    "adCode": "341000",
+                    "cityCode": "0559"
+                },
+                {
+                    "name": "黄石市",
+                    "adCode": "420200",
+                    "cityCode": "0714"
+                },
+                {
+                    "name": "珲春市",
+                    "adCode": "222404",
+                    "cityCode": "1433"
+                },
+                {
+                    "name": "辉县市",
+                    "adCode": "410782",
+                    "cityCode": "0373"
+                },
+                {
+                    "name": "惠州市",
+                    "adCode": "441300",
+                    "cityCode": "0752"
+                },
+                {
+                    "name": "霍尔果斯市",
+                    "adCode": "654004",
+                    "cityCode": "0999"
+                },
+                {
+                    "name": "霍林郭勒市",
+                    "adCode": "150581",
+                    "cityCode": "0475"
+                },
+                {
+                    "name": "霍州市",
+                    "adCode": "141082",
+                    "cityCode": "0357"
+                }
+            ]
+        },
+        {
+            "letter": "J",
+            "list": [
+                {
+                    "name": "鸡西市",
+                    "adCode": "230300",
+                    "cityCode": "0467"
+                },
+                {
+                    "name": "吉安市",
+                    "adCode": "360800",
+                    "cityCode": "0796"
+                },
+                {
+                    "name": "吉林市",
+                    "adCode": "220200",
+                    "cityCode": "0432"
+                },
+                {
+                    "name": "吉首市",
+                    "adCode": "433101",
+                    "cityCode": "0743"
+                },
+                {
+                    "name": "即墨市",
+                    "adCode": "370282",
+                    "cityCode": "0532"
+                },
+                {
+                    "name": "集安市",
+                    "adCode": "220582",
+                    "cityCode": "0435"
+                },
+                {
+                    "name": "济南市",
+                    "adCode": "370100",
+                    "cityCode": "0531"
+                },
+                {
+                    "name": "济宁市",
+                    "adCode": "370800",
+                    "cityCode": "0537"
+                },
+                {
+                    "name": "济源市",
+                    "adCode": "419001",
+                    "cityCode": "1391"
+                },
+                {
+                    "name": "佳木斯市",
+                    "adCode": "230800",
+                    "cityCode": "0454"
+                },
+                {
+                    "name": "嘉兴市",
+                    "adCode": "330400",
+                    "cityCode": "0573"
+                },
+                {
+                    "name": "嘉峪关市",
+                    "adCode": "620200",
+                    "cityCode": "1937"
+                },
+                {
+                    "name": "简阳市",
+                    "adCode": "510180",
+                    "cityCode": "028"
+                },
+                {
+                    "name": "建德市",
+                    "adCode": "330182",
+                    "cityCode": "0571"
+                },
+                {
+                    "name": "建瓯市",
+                    "adCode": "350783",
+                    "cityCode": "0599"
+                },
+                {
+                    "name": "江门市",
+                    "adCode": "440700",
+                    "cityCode": "0750"
+                },
+                {
+                    "name": "江山市",
+                    "adCode": "330881",
+                    "cityCode": "0570"
+                },
+                {
+                    "name": "江阴市",
+                    "adCode": "320281",
+                    "cityCode": "0510"
+                },
+                {
+                    "name": "江油市",
+                    "adCode": "510781",
+                    "cityCode": "0816"
+                },
+                {
+                    "name": "胶州市",
+                    "adCode": "370281",
+                    "cityCode": "0532"
+                },
+                {
+                    "name": "蛟河市",
+                    "adCode": "220281",
+                    "cityCode": "0432"
+                },
+                {
+                    "name": "焦作市",
+                    "adCode": "410800",
+                    "cityCode": "0391"
+                },
+                {
+                    "name": "揭阳市",
+                    "adCode": "445200",
+                    "cityCode": "0663"
+                },
+                {
+                    "name": "介休市",
+                    "adCode": "140781",
+                    "cityCode": "0354"
+                },
+                {
+                    "name": "界首市",
+                    "adCode": "341282",
+                    "cityCode": "1558"
+                },
+                {
+                    "name": "金昌市",
+                    "adCode": "620300",
+                    "cityCode": "0935"
+                },
+                {
+                    "name": "金华市",
+                    "adCode": "330700",
+                    "cityCode": "0579"
+                },
+                {
+                    "name": "津市市",
+                    "adCode": "430781",
+                    "cityCode": "0736"
+                },
+                {
+                    "name": "锦州市",
+                    "adCode": "210700",
+                    "cityCode": "0416"
+                },
+                {
+                    "name": "晋城市",
+                    "adCode": "140500",
+                    "cityCode": "0356"
+                },
+                {
+                    "name": "晋江市",
+                    "adCode": "350582",
+                    "cityCode": "0595"
+                },
+                {
+                    "name": "晋中市",
+                    "adCode": "140700",
+                    "cityCode": "0354"
+                },
+                {
+                    "name": "晋州市",
+                    "adCode": "130183",
+                    "cityCode": "0311"
+                },
+                {
+                    "name": "荆门市",
+                    "adCode": "420800",
+                    "cityCode": "0724"
+                },
+                {
+                    "name": "荆州市",
+                    "adCode": "421000",
+                    "cityCode": "0716"
+                },
+                {
+                    "name": "井冈山市",
+                    "adCode": "360881",
+                    "cityCode": "0796"
+                },
+                {
+                    "name": "景德镇市",
+                    "adCode": "360200",
+                    "cityCode": "0798"
+                },
+                {
+                    "name": "景洪市",
+                    "adCode": "532801",
+                    "cityCode": "0691"
+                },
+                {
+                    "name": "靖江市",
+                    "adCode": "321282",
+                    "cityCode": "0523"
+                },
+                {
+                    "name": "靖西市",
+                    "adCode": "451081",
+                    "cityCode": "0776"
+                },
+                {
+                    "name": "九江市",
+                    "adCode": "360400",
+                    "cityCode": "0792"
+                },
+                {
+                    "name": "酒泉市",
+                    "adCode": "620900",
+                    "cityCode": "0937"
+                },
+                {
+                    "name": "句容市",
+                    "adCode": "321183",
+                    "cityCode": "0511"
+                }
+            ]
+        },
+        {
+            "letter": "K",
+            "list": [
+                {
+                    "name": "喀什市",
+                    "adCode": "653101",
+                    "cityCode": "0998"
+                },
+                {
+                    "name": "开封市",
+                    "adCode": "410200",
+                    "cityCode": "0378"
+                },
+                {
+                    "name": "开平市",
+                    "adCode": "440783",
+                    "cityCode": "0750"
+                },
+                {
+                    "name": "开原市",
+                    "adCode": "211282",
+                    "cityCode": "0410"
+                },
+                {
+                    "name": "开远市",
+                    "adCode": "532502",
+                    "cityCode": "0873"
+                },
+                {
+                    "name": "凯里市",
+                    "adCode": "522601",
+                    "cityCode": "0855"
+                },
+                {
+                    "name": "康定市",
+                    "adCode": "513301",
+                    "cityCode": "0836"
+                },
+                {
+                    "name": "可克达拉市",
+                    "adCode": "659008",
+                    "cityCode": "1999"
+                },
+                {
+                    "name": "克拉玛依市",
+                    "adCode": "650200",
+                    "cityCode": "0990"
+                },
+                {
+                    "name": "库尔勒市",
+                    "adCode": "652801",
+                    "cityCode": "0996"
+                },
+                {
+                    "name": "奎屯市",
+                    "adCode": "654003",
+                    "cityCode": "0999"
+                },
+                {
+                    "name": "昆明市",
+                    "adCode": "530100",
+                    "cityCode": "0871",
+                    "type": "hot"
+                },
+                {
+                    "name": "昆山市",
+                    "adCode": "320583",
+                    "cityCode": "0512"
+                },
+                {
+                    "name": "昆玉市",
+                    "adCode": "659009",
+                    "cityCode": "1903"
+                }
+            ]
+        },
+        {
+            "letter": "L",
+            "list": [
+                {
+                    "name": "拉萨市",
+                    "adCode": "540100",
+                    "cityCode": "0891"
+                },
+                {
+                    "name": "来宾市",
+                    "adCode": "451300",
+                    "cityCode": "1772"
+                },
+                {
+                    "name": "莱芜市",
+                    "adCode": "371200",
+                    "cityCode": "0634"
+                },
+                {
+                    "name": "莱西市",
+                    "adCode": "370285",
+                    "cityCode": "0532"
+                },
+                {
+                    "name": "莱阳市",
+                    "adCode": "370682",
+                    "cityCode": "0535"
+                },
+                {
+                    "name": "莱州市",
+                    "adCode": "370683",
+                    "cityCode": "0535"
+                },
+                {
+                    "name": "兰溪市",
+                    "adCode": "330781",
+                    "cityCode": "0579"
+                },
+                {
+                    "name": "兰州市",
+                    "adCode": "620100",
+                    "cityCode": "0931"
+                },
+                {
+                    "name": "阆中市",
+                    "adCode": "511381",
+                    "cityCode": "0817"
+                },
+                {
+                    "name": "廊坊市",
+                    "adCode": "131000",
+                    "cityCode": "0316"
+                },
+                {
+                    "name": "老河口市",
+                    "adCode": "420682",
+                    "cityCode": "0710"
+                },
+                {
+                    "name": "乐昌市",
+                    "adCode": "440281",
+                    "cityCode": "0751"
+                },
+                {
+                    "name": "乐陵市",
+                    "adCode": "371481",
+                    "cityCode": "0534"
+                },
+                {
+                    "name": "乐平市",
+                    "adCode": "360281",
+                    "cityCode": "0798"
+                },
+                {
+                    "name": "乐清市",
+                    "adCode": "330382",
+                    "cityCode": "0577"
+                },
+                {
+                    "name": "乐山市",
+                    "adCode": "511100",
+                    "cityCode": "0833"
+                },
+                {
+                    "name": "雷州市",
+                    "adCode": "440882",
+                    "cityCode": "0759"
+                },
+                {
+                    "name": "耒阳市",
+                    "adCode": "430481",
+                    "cityCode": "0734"
+                },
+                {
+                    "name": "冷水江市",
+                    "adCode": "431381",
+                    "cityCode": "0738"
+                },
+                {
+                    "name": "醴陵市",
+                    "adCode": "430281",
+                    "cityCode": "0733"
+                },
+                {
+                    "name": "丽江市",
+                    "adCode": "530700",
+                    "cityCode": "0888"
+                },
+                {
+                    "name": "丽水市",
+                    "adCode": "331100",
+                    "cityCode": "0578"
+                },
+                {
+                    "name": "利川市",
+                    "adCode": "422802",
+                    "cityCode": "0718"
+                },
+                {
+                    "name": "溧阳市",
+                    "adCode": "320481",
+                    "cityCode": "0519"
+                },
+                {
+                    "name": "连云港市",
+                    "adCode": "320700",
+                    "cityCode": "0518"
+                },
+                {
+                    "name": "连州市",
+                    "adCode": "441882",
+                    "cityCode": "0763"
+                },
+                {
+                    "name": "涟源市",
+                    "adCode": "431382",
+                    "cityCode": "0738"
+                },
+                {
+                    "name": "廉江市",
+                    "adCode": "440881",
+                    "cityCode": "0759"
+                },
+                {
+                    "name": "辽阳市",
+                    "adCode": "211000",
+                    "cityCode": "0419"
+                },
+                {
+                    "name": "辽源市",
+                    "adCode": "220400",
+                    "cityCode": "0437"
+                },
+                {
+                    "name": "聊城市",
+                    "adCode": "371500",
+                    "cityCode": "0635"
+                },
+                {
+                    "name": "林芝市",
+                    "adCode": "540400",
+                    "cityCode": "0894"
+                },
+                {
+                    "name": "林州市",
+                    "adCode": "410581",
+                    "cityCode": "0372"
+                },
+                {
+                    "name": "临安市",
+                    "adCode": "330185",
+                    "cityCode": "0571"
+                },
+                {
+                    "name": "临沧市",
+                    "adCode": "530900",
+                    "cityCode": "0883"
+                },
+                {
+                    "name": "临汾市",
+                    "adCode": "141000",
+                    "cityCode": "0357"
+                },
+                {
+                    "name": "临海市",
+                    "adCode": "331082",
+                    "cityCode": "0576"
+                },
+                {
+                    "name": "临江市",
+                    "adCode": "220681",
+                    "cityCode": "0439"
+                },
+                {
+                    "name": "临清市",
+                    "adCode": "371581",
+                    "cityCode": "0635"
+                },
+                {
+                    "name": "临夏市",
+                    "adCode": "622901",
+                    "cityCode": "0930"
+                },
+                {
+                    "name": "临湘市",
+                    "adCode": "430682",
+                    "cityCode": "0730"
+                },
+                {
+                    "name": "临沂市",
+                    "adCode": "371300",
+                    "cityCode": "0539"
+                },
+                {
+                    "name": "灵宝市",
+                    "adCode": "411282",
+                    "cityCode": "0398"
+                },
+                {
+                    "name": "灵武市",
+                    "adCode": "640181",
+                    "cityCode": "0951"
+                },
+                {
+                    "name": "凌海市",
+                    "adCode": "210781",
+                    "cityCode": "0416"
+                },
+                {
+                    "name": "凌源市",
+                    "adCode": "211382",
+                    "cityCode": "0421"
+                },
+                {
+                    "name": "浏阳市",
+                    "adCode": "430181",
+                    "cityCode": "0731"
+                },
+                {
+                    "name": "柳州市",
+                    "adCode": "450200",
+                    "cityCode": "0772"
+                },
+                {
+                    "name": "六安市",
+                    "adCode": "341500",
+                    "cityCode": "0564"
+                },
+                {
+                    "name": "六盘水市",
+                    "adCode": "520200",
+                    "cityCode": "0858"
+                },
+                {
+                    "name": "龙海市",
+                    "adCode": "350681",
+                    "cityCode": "0596"
+                },
+                {
+                    "name": "龙井市",
+                    "adCode": "222405",
+                    "cityCode": "1433"
+                },
+                {
+                    "name": "龙口市",
+                    "adCode": "370681",
+                    "cityCode": "0535"
+                },
+                {
+                    "name": "龙泉市",
+                    "adCode": "331181",
+                    "cityCode": "0578"
+                },
+                {
+                    "name": "龙岩市",
+                    "adCode": "350800",
+                    "cityCode": "0597"
+                },
+                {
+                    "name": "陇南市",
+                    "adCode": "621200",
+                    "cityCode": "2935"
+                },
+                {
+                    "name": "娄底市",
+                    "adCode": "431300",
+                    "cityCode": "0738"
+                },
+                {
+                    "name": "庐山市",
+                    "adCode": "360427",
+                    "cityCode": "0792"
+                },
+                {
+                    "name": "泸水市",
+                    "adCode": "533301",
+                    "cityCode": "0886"
+                },
+                {
+                    "name": "泸州市",
+                    "adCode": "510500",
+                    "cityCode": "0830"
+                },
+                {
+                    "name": "陆丰市",
+                    "adCode": "441581",
+                    "cityCode": "0660"
+                },
+                {
+                    "name": "潞城市",
+                    "adCode": "140481",
+                    "cityCode": "0355"
+                },
+                {
+                    "name": "罗定市",
+                    "adCode": "445381",
+                    "cityCode": "0766"
+                },
+                {
+                    "name": "洛阳市",
+                    "adCode": "410300",
+                    "cityCode": "0379"
+                },
+                {
+                    "name": "漯河市",
+                    "adCode": "411100",
+                    "cityCode": "0395"
+                },
+                {
+                    "name": "吕梁市",
+                    "adCode": "141100",
+                    "cityCode": "0358"
+                }
+            ]
+        },
+        {
+            "letter": "M",
+            "list": [
+                {
+                    "name": "麻城市",
+                    "adCode": "421181",
+                    "cityCode": "0713"
+                },
+                {
+                    "name": "马鞍山市",
+                    "adCode": "340500",
+                    "cityCode": "0555"
+                },
+                {
+                    "name": "马尔康市",
+                    "adCode": "513201",
+                    "cityCode": "0837"
+                },
+                {
+                    "name": "满洲里市",
+                    "adCode": "150781",
+                    "cityCode": "0470"
+                },
+                {
+                    "name": "芒市",
+                    "adCode": "533103",
+                    "cityCode": "0692"
+                },
+                {
+                    "name": "茂名市",
+                    "adCode": "440900",
+                    "cityCode": "0668"
+                },
+                {
+                    "name": "眉山市",
+                    "adCode": "511400",
+                    "cityCode": "1833"
+                },
+                {
+                    "name": "梅河口市",
+                    "adCode": "220581",
+                    "cityCode": "0435"
+                },
+                {
+                    "name": "梅州市",
+                    "adCode": "441400",
+                    "cityCode": "0753"
+                },
+                {
+                    "name": "蒙自市",
+                    "adCode": "532503",
+                    "cityCode": "0873"
+                },
+                {
+                    "name": "孟州市",
+                    "adCode": "410883",
+                    "cityCode": "0391"
+                },
+                {
+                    "name": "弥勒市",
+                    "adCode": "532504",
+                    "cityCode": "0873"
+                },
+                {
+                    "name": "汨罗市",
+                    "adCode": "430681",
+                    "cityCode": "0730"
+                },
+                {
+                    "name": "密山市",
+                    "adCode": "230382",
+                    "cityCode": "0467"
+                },
+                {
+                    "name": "绵阳市",
+                    "adCode": "510700",
+                    "cityCode": "0816"
+                },
+                {
+                    "name": "绵竹市",
+                    "adCode": "510683",
+                    "cityCode": "0838"
+                },
+                {
+                    "name": "明光市",
+                    "adCode": "341182",
+                    "cityCode": "0550"
+                },
+                {
+                    "name": "牡丹江市",
+                    "adCode": "231000",
+                    "cityCode": "0453"
+                },
+                {
+                    "name": "穆棱市",
+                    "adCode": "231085",
+                    "cityCode": "0453"
+                }
+            ]
+        },
+        {
+            "letter": "N",
+            "list": [
+                {
+                    "name": "南安市",
+                    "adCode": "350583",
+                    "cityCode": "0595"
+                },
+                {
+                    "name": "南昌市",
+                    "adCode": "360100",
+                    "cityCode": "0791"
+                },
+                {
+                    "name": "南充市",
+                    "adCode": "511300",
+                    "cityCode": "0817"
+                },
+                {
+                    "name": "南宫市",
+                    "adCode": "130581",
+                    "cityCode": "0319"
+                },
+                {
+                    "name": "南京市",
+                    "adCode": "320100",
+                    "cityCode": "025",
+                    "type": "hot"
+                },
+                {
+                    "name": "南宁市",
+                    "adCode": "450100",
+                    "cityCode": "0771"
+                },
+                {
+                    "name": "南平市",
+                    "adCode": "350700",
+                    "cityCode": "0599"
+                },
+                {
+                    "name": "南通市",
+                    "adCode": "320600",
+                    "cityCode": "0513"
+                },
+                {
+                    "name": "南雄市",
+                    "adCode": "440282",
+                    "cityCode": "0751"
+                },
+                {
+                    "name": "南阳市",
+                    "adCode": "411300",
+                    "cityCode": "0377"
+                },
+                {
+                    "name": "讷河市",
+                    "adCode": "230281",
+                    "cityCode": "0452"
+                },
+                {
+                    "name": "内江市",
+                    "adCode": "511000",
+                    "cityCode": "1832"
+                },
+                {
+                    "name": "宁安市",
+                    "adCode": "231084",
+                    "cityCode": "0453"
+                },
+                {
+                    "name": "宁波市",
+                    "adCode": "330200",
+                    "cityCode": "0574"
+                },
+                {
+                    "name": "宁德市",
+                    "adCode": "350900",
+                    "cityCode": "0593"
+                },
+                {
+                    "name": "宁国市",
+                    "adCode": "341881",
+                    "cityCode": "0563"
+                }
+            ]
+        },
+        {
+            "letter": "P",
+            "list": [
+                {
+                    "name": "攀枝花市",
+                    "adCode": "510400",
+                    "cityCode": "0812"
+                },
+                {
+                    "name": "盘锦市",
+                    "adCode": "211100",
+                    "cityCode": "0427"
+                },
+                {
+                    "name": "磐石市",
+                    "adCode": "220284",
+                    "cityCode": "0432"
+                },
+                {
+                    "name": "彭州市",
+                    "adCode": "510182",
+                    "cityCode": "028"
+                },
+                {
+                    "name": "蓬莱市",
+                    "adCode": "370684",
+                    "cityCode": "0535"
+                },
+                {
+                    "name": "邳州市",
+                    "adCode": "320382",
+                    "cityCode": "0516"
+                },
+                {
+                    "name": "平顶山市",
+                    "adCode": "410400",
+                    "cityCode": "0375"
+                },
+                {
+                    "name": "平度市",
+                    "adCode": "370283",
+                    "cityCode": "0532"
+                },
+                {
+                    "name": "平湖市",
+                    "adCode": "330482",
+                    "cityCode": "0573"
+                },
+                {
+                    "name": "平凉市",
+                    "adCode": "620800",
+                    "cityCode": "0933"
+                },
+                {
+                    "name": "凭祥市",
+                    "adCode": "451481",
+                    "cityCode": "1771"
+                },
+                {
+                    "name": "萍乡市",
+                    "adCode": "360300",
+                    "cityCode": "0799"
+                },
+                {
+                    "name": "莆田市",
+                    "adCode": "350300",
+                    "cityCode": "0594"
+                },
+                {
+                    "name": "濮阳市",
+                    "adCode": "410900",
+                    "cityCode": "0393"
+                },
+                {
+                    "name": "普洱市",
+                    "adCode": "530800",
+                    "cityCode": "0879"
+                },
+                {
+                    "name": "普宁市",
+                    "adCode": "445281",
+                    "cityCode": "0663"
+                }
+            ]
+        },
+        {
+            "letter": "Q",
+            "list": [
+                {
+                    "name": "七台河市",
+                    "adCode": "230900",
+                    "cityCode": "0464"
+                },
+                {
+                    "name": "栖霞市",
+                    "adCode": "370686",
+                    "cityCode": "0535"
+                },
+                {
+                    "name": "齐齐哈尔市",
+                    "adCode": "230200",
+                    "cityCode": "0452"
+                },
+                {
+                    "name": "启东市",
+                    "adCode": "320681",
+                    "cityCode": "0513"
+                },
+                {
+                    "name": "迁安市",
+                    "adCode": "130283",
+                    "cityCode": "0315"
+                },
+                {
+                    "name": "潜江市",
+                    "adCode": "429005",
+                    "cityCode": "2728"
+                },
+                {
+                    "name": "钦州市",
+                    "adCode": "450700",
+                    "cityCode": "0777"
+                },
+                {
+                    "name": "秦皇岛市",
+                    "adCode": "130300",
+                    "cityCode": "0335"
+                },
+                {
+                    "name": "沁阳市",
+                    "adCode": "410882",
+                    "cityCode": "0391"
+                },
+                {
+                    "name": "青岛市",
+                    "adCode": "370200",
+                    "cityCode": "0532",
+                    "type": "hot"
+                },
+                {
+                    "name": "青铜峡市",
+                    "adCode": "640381",
+                    "cityCode": "0953"
+                },
+                {
+                    "name": "青州市",
+                    "adCode": "370781",
+                    "cityCode": "0536"
+                },
+                {
+                    "name": "清远市",
+                    "adCode": "441800",
+                    "cityCode": "0763"
+                },
+                {
+                    "name": "清镇市",
+                    "adCode": "520181",
+                    "cityCode": "0851"
+                },
+                {
+                    "name": "庆阳市",
+                    "adCode": "621000",
+                    "cityCode": "0934"
+                },
+                {
+                    "name": "邛崃市",
+                    "adCode": "510183",
+                    "cityCode": "028"
+                },
+                {
+                    "name": "琼海市",
+                    "adCode": "469002",
+                    "cityCode": "1894"
+                },
+                {
+                    "name": "衢州市",
+                    "adCode": "330800",
+                    "cityCode": "0570"
+                },
+                {
+                    "name": "曲阜市",
+                    "adCode": "370881",
+                    "cityCode": "0537"
+                },
+                {
+                    "name": "曲靖市",
+                    "adCode": "530300",
+                    "cityCode": "0874"
+                },
+                {
+                    "name": "泉州市",
+                    "adCode": "350500",
+                    "cityCode": "0595"
+                }
+            ]
+        },
+        {
+            "letter": "R",
+            "list": [
+                {
+                    "name": "仁怀市",
+                    "adCode": "520382",
+                    "cityCode": "0852"
+                },
+                {
+                    "name": "任丘市",
+                    "adCode": "130982",
+                    "cityCode": "0317"
+                },
+                {
+                    "name": "日喀则市",
+                    "adCode": "540200",
+                    "cityCode": "0892"
+                },
+                {
+                    "name": "日照市",
+                    "adCode": "371100",
+                    "cityCode": "0633"
+                },
+                {
+                    "name": "荣成市",
+                    "adCode": "371082",
+                    "cityCode": "0631"
+                },
+                {
+                    "name": "如皋市",
+                    "adCode": "320682",
+                    "cityCode": "0513"
+                },
+                {
+                    "name": "汝州市",
+                    "adCode": "410482",
+                    "cityCode": "0375"
+                },
+                {
+                    "name": "乳山市",
+                    "adCode": "371083",
+                    "cityCode": "0631"
+                },
+                {
+                    "name": "瑞安市",
+                    "adCode": "330381",
+                    "cityCode": "0577"
+                },
+                {
+                    "name": "瑞昌市",
+                    "adCode": "360481",
+                    "cityCode": "0792"
+                },
+                {
+                    "name": "瑞金市",
+                    "adCode": "360781",
+                    "cityCode": "0797"
+                },
+                {
+                    "name": "瑞丽市",
+                    "adCode": "533102",
+                    "cityCode": "0692"
+                }
+            ]
+        },
+        {
+            "letter": "S",
+            "list": [
+                {
+                    "name": "三河市",
+                    "adCode": "131082",
+                    "cityCode": "0316"
+                },
+                {
+                    "name": "三门峡市",
+                    "adCode": "411200",
+                    "cityCode": "0398"
+                },
+                {
+                    "name": "三明市",
+                    "adCode": "350400",
+                    "cityCode": "0598"
+                },
+                {
+                    "name": "三沙市",
+                    "adCode": "460300",
+                    "cityCode": "2898"
+                },
+                {
+                    "name": "三亚市",
+                    "adCode": "460200",
+                    "cityCode": "0899"
+                },
+                {
+                    "name": "沙河市",
+                    "adCode": "130582",
+                    "cityCode": "0319"
+                },
+                {
+                    "name": "厦门市",
+                    "adCode": "350200",
+                    "cityCode": "0592",
+                    "type": "hot"
+                },
+                {
+                    "name": "山南市",
+                    "adCode": "540500",
+                    "cityCode": "0893"
+                },
+                {
+                    "name": "汕头市",
+                    "adCode": "440500",
+                    "cityCode": "0754"
+                },
+                {
+                    "name": "汕尾市",
+                    "adCode": "441500",
+                    "cityCode": "0660"
+                },
+                {
+                    "name": "商洛市",
+                    "adCode": "611000",
+                    "cityCode": "0914"
+                },
+                {
+                    "name": "商丘市",
+                    "adCode": "411400",
+                    "cityCode": "0370"
+                },
+                {
+                    "name": "上海市",
+                    "adCode": "310000",
+                    "cityCode": "021",
+                    "type": "hot"
+                },
+                {
+                    "name": "上饶市",
+                    "adCode": "361100",
+                    "cityCode": "0793"
+                },
+                {
+                    "name": "尚志市",
+                    "adCode": "230183",
+                    "cityCode": "0451"
+                },
+                {
+                    "name": "韶关市",
+                    "adCode": "440200",
+                    "cityCode": "0751"
+                },
+                {
+                    "name": "韶山市",
+                    "adCode": "430382",
+                    "cityCode": "0732"
+                },
+                {
+                    "name": "邵武市",
+                    "adCode": "350781",
+                    "cityCode": "0599"
+                },
+                {
+                    "name": "邵阳市",
+                    "adCode": "430500",
+                    "cityCode": "0739"
+                },
+                {
+                    "name": "绍兴市",
+                    "adCode": "330600",
+                    "cityCode": "0575"
+                },
+                {
+                    "name": "深圳市",
+                    "adCode": "440300",
+                    "cityCode": "0755",
+                    "type": "hot"
+                },
+                {
+                    "name": "深州市",
+                    "adCode": "131182",
+                    "cityCode": "0318"
+                },
+                {
+                    "name": "什邡市",
+                    "adCode": "510682",
+                    "cityCode": "0838"
+                },
+                {
+                    "name": "沈阳市",
+                    "adCode": "210100",
+                    "cityCode": "024"
+                },
+                {
+                    "name": "嵊州市",
+                    "adCode": "330683",
+                    "cityCode": "0575"
+                },
+                {
+                    "name": "十堰市",
+                    "adCode": "420300",
+                    "cityCode": "0719"
+                },
+                {
+                    "name": "石河子市",
+                    "adCode": "659001",
+                    "cityCode": "0993"
+                },
+                {
+                    "name": "石家庄市",
+                    "adCode": "130100",
+                    "cityCode": "0311"
+                },
+                {
+                    "name": "石狮市",
+                    "adCode": "350581",
+                    "cityCode": "0595"
+                },
+                {
+                    "name": "石首市",
+                    "adCode": "421081",
+                    "cityCode": "0716"
+                },
+                {
+                    "name": "石嘴山市",
+                    "adCode": "640200",
+                    "cityCode": "0952"
+                },
+                {
+                    "name": "寿光市",
+                    "adCode": "370783",
+                    "cityCode": "0536"
+                },
+                {
+                    "name": "舒兰市",
+                    "adCode": "220283",
+                    "cityCode": "0432"
+                },
+                {
+                    "name": "双河市",
+                    "adCode": "659007",
+                    "cityCode": "1909"
+                },
+                {
+                    "name": "双辽市",
+                    "adCode": "220382",
+                    "cityCode": "0434"
+                },
+                {
+                    "name": "双鸭山市",
+                    "adCode": "230500",
+                    "cityCode": "0469"
+                },
+                {
+                    "name": "朔州市",
+                    "adCode": "140600",
+                    "cityCode": "0349"
+                },
+                {
+                    "name": "四会市",
+                    "adCode": "441284",
+                    "cityCode": "0758"
+                },
+                {
+                    "name": "四平市",
+                    "adCode": "220300",
+                    "cityCode": "0434"
+                },
+                {
+                    "name": "松原市",
+                    "adCode": "220700",
+                    "cityCode": "0438"
+                },
+                {
+                    "name": "松滋市",
+                    "adCode": "421087",
+                    "cityCode": "0716"
+                },
+                {
+                    "name": "苏州市",
+                    "adCode": "320500",
+                    "cityCode": "0512"
+                },
+                {
+                    "name": "绥芬河市",
+                    "adCode": "231081",
+                    "cityCode": "0453"
+                },
+                {
+                    "name": "绥化市",
+                    "adCode": "231200",
+                    "cityCode": "0455"
+                },
+                {
+                    "name": "随州市",
+                    "adCode": "421300",
+                    "cityCode": "0722"
+                },
+                {
+                    "name": "遂宁市",
+                    "adCode": "510900",
+                    "cityCode": "0825"
+                }
+            ]
+        },
+        {
+            "letter": "T",
+            "list": [
+                {
+                    "name": "塔城市",
+                    "adCode": "654201",
+                    "cityCode": "0901"
+                },
+                {
+                    "name": "台山市",
+                    "adCode": "440781",
+                    "cityCode": "0750"
+                },
+                {
+                    "name": "台州市",
+                    "adCode": "331000",
+                    "cityCode": "0576"
+                },
+                {
+                    "name": "太仓市",
+                    "adCode": "320585",
+                    "cityCode": "0512"
+                },
+                {
+                    "name": "太原市",
+                    "adCode": "140100",
+                    "cityCode": "0351"
+                },
+                {
+                    "name": "泰安市",
+                    "adCode": "370900",
+                    "cityCode": "0538"
+                },
+                {
+                    "name": "泰兴市",
+                    "adCode": "321283",
+                    "cityCode": "0523"
+                },
+                {
+                    "name": "泰州市",
+                    "adCode": "321200",
+                    "cityCode": "0523"
+                },
+                {
+                    "name": "唐山市",
+                    "adCode": "130200",
+                    "cityCode": "0315"
+                },
+                {
+                    "name": "洮南市",
+                    "adCode": "220881",
+                    "cityCode": "0436"
+                },
+                {
+                    "name": "腾冲市",
+                    "adCode": "530581",
+                    "cityCode": "0875"
+                },
+                {
+                    "name": "滕州市",
+                    "adCode": "370481",
+                    "cityCode": "0632"
+                },
+                {
+                    "name": "天津市",
+                    "adCode": "120000",
+                    "cityCode": "022",
+                    "type": "hot"
+                },
+                {
+                    "name": "天门市",
+                    "adCode": "429006",
+                    "cityCode": "1728"
+                },
+                {
+                    "name": "天水市",
+                    "adCode": "620500",
+                    "cityCode": "0938"
+                },
+                {
+                    "name": "天长市",
+                    "adCode": "341181",
+                    "cityCode": "0550"
+                },
+                {
+                    "name": "调兵山市",
+                    "adCode": "211281",
+                    "cityCode": "0410"
+                },
+                {
+                    "name": "铁力市",
+                    "adCode": "230781",
+                    "cityCode": "0458"
+                },
+                {
+                    "name": "铁岭市",
+                    "adCode": "211200",
+                    "cityCode": "0410"
+                },
+                {
+                    "name": "铁门关市",
+                    "adCode": "659006",
+                    "cityCode": "1996"
+                },
+                {
+                    "name": "通化市",
+                    "adCode": "220500",
+                    "cityCode": "0435"
+                },
+                {
+                    "name": "通辽市",
+                    "adCode": "150500",
+                    "cityCode": "0475"
+                },
+                {
+                    "name": "同江市",
+                    "adCode": "230881",
+                    "cityCode": "0454"
+                },
+                {
+                    "name": "桐城市",
+                    "adCode": "340881",
+                    "cityCode": "0556"
+                },
+                {
+                    "name": "桐乡市",
+                    "adCode": "330483",
+                    "cityCode": "0573"
+                },
+                {
+                    "name": "铜川市",
+                    "adCode": "610200",
+                    "cityCode": "0919"
+                },
+                {
+                    "name": "铜陵市",
+                    "adCode": "340700",
+                    "cityCode": "0562"
+                },
+                {
+                    "name": "铜仁市",
+                    "adCode": "520600",
+                    "cityCode": "0856"
+                },
+                {
+                    "name": "图们市",
+                    "adCode": "222402",
+                    "cityCode": "1433"
+                },
+                {
+                    "name": "图木舒克市",
+                    "adCode": "659003",
+                    "cityCode": "1998"
+                },
+                {
+                    "name": "吐鲁番市",
+                    "adCode": "650400",
+                    "cityCode": "0995"
+                }
+            ]
+        },
+        {
+            "letter": "W",
+            "list": [
+                {
+                    "name": "瓦房店市",
+                    "adCode": "210281",
+                    "cityCode": "0411"
+                },
+                {
+                    "name": "万宁市",
+                    "adCode": "469006",
+                    "cityCode": "1898"
+                },
+                {
+                    "name": "万源市",
+                    "adCode": "511781",
+                    "cityCode": "0818"
+                },
+                {
+                    "name": "威海市",
+                    "adCode": "371000",
+                    "cityCode": "0631"
+                },
+                {
+                    "name": "潍坊市",
+                    "adCode": "370700",
+                    "cityCode": "0536"
+                },
+                {
+                    "name": "卫辉市",
+                    "adCode": "410781",
+                    "cityCode": "0373"
+                },
+                {
+                    "name": "渭南市",
+                    "adCode": "610500",
+                    "cityCode": "0913"
+                },
+                {
+                    "name": "温岭市",
+                    "adCode": "331081",
+                    "cityCode": "0576"
+                },
+                {
+                    "name": "温州市",
+                    "adCode": "330300",
+                    "cityCode": "0577"
+                },
+                {
+                    "name": "文昌市",
+                    "adCode": "469005",
+                    "cityCode": "1893"
+                },
+                {
+                    "name": "文山市",
+                    "adCode": "532601",
+                    "cityCode": "0876"
+                },
+                {
+                    "name": "乌海市",
+                    "adCode": "150300",
+                    "cityCode": "0473"
+                },
+                {
+                    "name": "乌兰察布市",
+                    "adCode": "150900",
+                    "cityCode": "0474"
+                },
+                {
+                    "name": "乌兰浩特市",
+                    "adCode": "152201",
+                    "cityCode": "0482"
+                },
+                {
+                    "name": "乌鲁木齐市",
+                    "adCode": "650100",
+                    "cityCode": "0991",
+                    "type": "hot"
+                },
+                {
+                    "name": "乌苏市",
+                    "adCode": "654202",
+                    "cityCode": "0901"
+                },
+                {
+                    "name": "无锡市",
+                    "adCode": "320200",
+                    "cityCode": "0510"
+                },
+                {
+                    "name": "芜湖市",
+                    "adCode": "340200",
+                    "cityCode": "0553"
+                },
+                {
+                    "name": "吴川市",
+                    "adCode": "440883",
+                    "cityCode": "0759"
+                },
+                {
+                    "name": "吴忠市",
+                    "adCode": "640300",
+                    "cityCode": "0953"
+                },
+                {
+                    "name": "梧州市",
+                    "adCode": "450400",
+                    "cityCode": "0774"
+                },
+                {
+                    "name": "五常市",
+                    "adCode": "230184",
+                    "cityCode": "0451"
+                },
+                {
+                    "name": "五大连池市",
+                    "adCode": "231182",
+                    "cityCode": "0456"
+                },
+                {
+                    "name": "五家渠市",
+                    "adCode": "659004",
+                    "cityCode": "1994"
+                },
+                {
+                    "name": "五指山市",
+                    "adCode": "469001",
+                    "cityCode": "1897"
+                },
+                {
+                    "name": "武安市",
+                    "adCode": "130481",
+                    "cityCode": "0310"
+                },
+                {
+                    "name": "武冈市",
+                    "adCode": "430581",
+                    "cityCode": "0739"
+                },
+                {
+                    "name": "武汉市",
+                    "adCode": "420100",
+                    "cityCode": "027",
+                    "type": "hot"
+                },
+                {
+                    "name": "武威市",
+                    "adCode": "620600",
+                    "cityCode": "1935"
+                },
+                {
+                    "name": "武穴市",
+                    "adCode": "421182",
+                    "cityCode": "0713"
+                },
+                {
+                    "name": "武夷山市",
+                    "adCode": "350782",
+                    "cityCode": "0599"
+                },
+                {
+                    "name": "舞钢市",
+                    "adCode": "410481",
+                    "cityCode": "0375"
+                }
+            ]
+        },
+        {
+            "letter": "X",
+            "list": [
+                {
+                    "name": "西安市",
+                    "adCode": "610100",
+                    "cityCode": "029",
+                    "type": "hot"
+                },
+                {
+                    "name": "西昌市",
+                    "adCode": "513401",
+                    "cityCode": "0834"
+                },
+                {
+                    "name": "西宁市",
+                    "adCode": "630100",
+                    "cityCode": "0971"
+                },
+                {
+                    "name": "锡林浩特市",
+                    "adCode": "152502",
+                    "cityCode": "0479"
+                },
+                {
+                    "name": "仙桃市",
+                    "adCode": "429004",
+                    "cityCode": "0728"
+                },
+                {
+                    "name": "咸宁市",
+                    "adCode": "421200",
+                    "cityCode": "0715"
+                },
+                {
+                    "name": "咸阳市",
+                    "adCode": "610400",
+                    "cityCode": "0910"
+                },
+                {
+                    "name": "香格里拉市",
+                    "adCode": "533401",
+                    "cityCode": "0887"
+                },
+                {
+                    "name": "湘潭市",
+                    "adCode": "430300",
+                    "cityCode": "0732"
+                },
+                {
+                    "name": "湘乡市",
+                    "adCode": "430381",
+                    "cityCode": "0732"
+                },
+                {
+                    "name": "襄阳市",
+                    "adCode": "420600",
+                    "cityCode": "0710"
+                },
+                {
+                    "name": "项城市",
+                    "adCode": "411681",
+                    "cityCode": "0394"
+                },
+                {
+                    "name": "孝感市",
+                    "adCode": "420900",
+                    "cityCode": "0712"
+                },
+                {
+                    "name": "孝义市",
+                    "adCode": "141181",
+                    "cityCode": "0358"
+                },
+                {
+                    "name": "辛集市",
+                    "adCode": "130181",
+                    "cityCode": "0311"
+                },
+                {
+                    "name": "忻州市",
+                    "adCode": "140900",
+                    "cityCode": "0350"
+                },
+                {
+                    "name": "新乐市",
+                    "adCode": "130184",
+                    "cityCode": "0311"
+                },
+                {
+                    "name": "新密市",
+                    "adCode": "410183",
+                    "cityCode": "0371"
+                },
+                {
+                    "name": "新民市",
+                    "adCode": "210181",
+                    "cityCode": "024"
+                },
+                {
+                    "name": "新泰市",
+                    "adCode": "370982",
+                    "cityCode": "0538"
+                },
+                {
+                    "name": "新乡市",
+                    "adCode": "410700",
+                    "cityCode": "0373"
+                },
+                {
+                    "name": "新沂市",
+                    "adCode": "320381",
+                    "cityCode": "0516"
+                },
+                {
+                    "name": "新余市",
+                    "adCode": "360500",
+                    "cityCode": "0790"
+                },
+                {
+                    "name": "新郑市",
+                    "adCode": "410184",
+                    "cityCode": "0371"
+                },
+                {
+                    "name": "信阳市",
+                    "adCode": "411500",
+                    "cityCode": "0376"
+                },
+                {
+                    "name": "信宜市",
+                    "adCode": "440983",
+                    "cityCode": "0668"
+                },
+                {
+                    "name": "邢台市",
+                    "adCode": "130500",
+                    "cityCode": "0319"
+                },
+                {
+                    "name": "兴城市",
+                    "adCode": "211481",
+                    "cityCode": "0429"
+                },
+                {
+                    "name": "兴化市",
+                    "adCode": "321281",
+                    "cityCode": "0523"
+                },
+                {
+                    "name": "兴宁市",
+                    "adCode": "441481",
+                    "cityCode": "0753"
+                },
+                {
+                    "name": "兴平市",
+                    "adCode": "610481",
+                    "cityCode": "0910"
+                },
+                {
+                    "name": "兴义市",
+                    "adCode": "522301",
+                    "cityCode": "0859"
+                },
+                {
+                    "name": "宿迁市",
+                    "adCode": "321300",
+                    "cityCode": "0527"
+                },
+                {
+                    "name": "宿州市",
+                    "adCode": "341300",
+                    "cityCode": "0557"
+                },
+                {
+                    "name": "徐州市",
+                    "adCode": "320300",
+                    "cityCode": "0516"
+                },
+                {
+                    "name": "许昌市",
+                    "adCode": "411000",
+                    "cityCode": "0374"
+                },
+                {
+                    "name": "宣城市",
+                    "adCode": "341800",
+                    "cityCode": "0563"
+                },
+                {
+                    "name": "宣威市",
+                    "adCode": "530381",
+                    "cityCode": "0874"
+                }
+            ]
+        },
+        {
+            "letter": "Y",
+            "list": [
+                {
+                    "name": "牙克石市",
+                    "adCode": "150782",
+                    "cityCode": "0470"
+                },
+                {
+                    "name": "雅安市",
+                    "adCode": "511800",
+                    "cityCode": "0835"
+                },
+                {
+                    "name": "烟台市",
+                    "adCode": "370600",
+                    "cityCode": "0535"
+                },
+                {
+                    "name": "延安市",
+                    "adCode": "610600",
+                    "cityCode": "0911"
+                },
+                {
+                    "name": "延吉市",
+                    "adCode": "222401",
+                    "cityCode": "1433"
+                },
+                {
+                    "name": "盐城市",
+                    "adCode": "320900",
+                    "cityCode": "0515"
+                },
+                {
+                    "name": "偃师市",
+                    "adCode": "410381",
+                    "cityCode": "0379"
+                },
+                {
+                    "name": "扬中市",
+                    "adCode": "321182",
+                    "cityCode": "0511"
+                },
+                {
+                    "name": "扬州市",
+                    "adCode": "321000",
+                    "cityCode": "0514"
+                },
+                {
+                    "name": "阳春市",
+                    "adCode": "441781",
+                    "cityCode": "0662"
+                },
+                {
+                    "name": "阳江市",
+                    "adCode": "441700",
+                    "cityCode": "0662"
+                },
+                {
+                    "name": "阳泉市",
+                    "adCode": "140300",
+                    "cityCode": "0353"
+                },
+                {
+                    "name": "伊春市",
+                    "adCode": "230700",
+                    "cityCode": "0458"
+                },
+                {
+                    "name": "伊宁市",
+                    "adCode": "654002",
+                    "cityCode": "0999"
+                },
+                {
+                    "name": "仪征市",
+                    "adCode": "321081",
+                    "cityCode": "0514"
+                },
+                {
+                    "name": "宜宾市",
+                    "adCode": "511500",
+                    "cityCode": "0831"
+                },
+                {
+                    "name": "宜昌市",
+                    "adCode": "420500",
+                    "cityCode": "0717"
+                },
+                {
+                    "name": "宜城市",
+                    "adCode": "420684",
+                    "cityCode": "0710"
+                },
+                {
+                    "name": "宜春市",
+                    "adCode": "360900",
+                    "cityCode": "0795"
+                },
+                {
+                    "name": "宜都市",
+                    "adCode": "420581",
+                    "cityCode": "0717"
+                },
+                {
+                    "name": "宜兴市",
+                    "adCode": "320282",
+                    "cityCode": "0510"
+                },
+                {
+                    "name": "宜州市",
+                    "adCode": "451281",
+                    "cityCode": "0778"
+                },
+                {
+                    "name": "义马市",
+                    "adCode": "411281",
+                    "cityCode": "0398"
+                },
+                {
+                    "name": "义乌市",
+                    "adCode": "330782",
+                    "cityCode": "0579"
+                },
+                {
+                    "name": "益阳市",
+                    "adCode": "430900",
+                    "cityCode": "0737"
+                },
+                {
+                    "name": "银川市",
+                    "adCode": "640100",
+                    "cityCode": "0951"
+                },
+                {
+                    "name": "英德市",
+                    "adCode": "441881",
+                    "cityCode": "0763"
+                },
+                {
+                    "name": "鹰潭市",
+                    "adCode": "360600",
+                    "cityCode": "0701"
+                },
+                {
+                    "name": "荥阳市",
+                    "adCode": "410182",
+                    "cityCode": "0371"
+                },
+                {
+                    "name": "营口市",
+                    "adCode": "210800",
+                    "cityCode": "0417"
+                },
+                {
+                    "name": "应城市",
+                    "adCode": "420981",
+                    "cityCode": "0712"
+                },
+                {
+                    "name": "永安市",
+                    "adCode": "350481",
+                    "cityCode": "0598"
+                },
+                {
+                    "name": "永城市",
+                    "adCode": "411481",
+                    "cityCode": "0370"
+                },
+                {
+                    "name": "永济市",
+                    "adCode": "140881",
+                    "cityCode": "0359"
+                },
+                {
+                    "name": "永康市",
+                    "adCode": "330784",
+                    "cityCode": "0579"
+                },
+                {
+                    "name": "永州市",
+                    "adCode": "431100",
+                    "cityCode": "0746"
+                },
+                {
+                    "name": "余姚市",
+                    "adCode": "330281",
+                    "cityCode": "0574"
+                },
+                {
+                    "name": "榆林市",
+                    "adCode": "610800",
+                    "cityCode": "0912"
+                },
+                {
+                    "name": "榆树市",
+                    "adCode": "220182",
+                    "cityCode": "0431"
+                },
+                {
+                    "name": "禹城市",
+                    "adCode": "371482",
+                    "cityCode": "0534"
+                },
+                {
+                    "name": "禹州市",
+                    "adCode": "411081",
+                    "cityCode": "0374"
+                },
+                {
+                    "name": "玉林市",
+                    "adCode": "450900",
+                    "cityCode": "0775"
+                },
+                {
+                    "name": "玉门市",
+                    "adCode": "620981",
+                    "cityCode": "0937"
+                },
+                {
+                    "name": "玉树市",
+                    "adCode": "632701",
+                    "cityCode": "0976"
+                },
+                {
+                    "name": "玉溪市",
+                    "adCode": "530400",
+                    "cityCode": "0877"
+                },
+                {
+                    "name": "沅江市",
+                    "adCode": "430981",
+                    "cityCode": "0737"
+                },
+                {
+                    "name": "原平市",
+                    "adCode": "140981",
+                    "cityCode": "0350"
+                },
+                {
+                    "name": "岳阳市",
+                    "adCode": "430600",
+                    "cityCode": "0730"
+                },
+                {
+                    "name": "云浮市",
+                    "adCode": "445300",
+                    "cityCode": "0766"
+                },
+                {
+                    "name": "运城市",
+                    "adCode": "140800",
+                    "cityCode": "0359"
+                }
+            ]
+        },
+        {
+            "letter": "Z",
+            "list": [
+                {
+                    "name": "枣阳市",
+                    "adCode": "420683",
+                    "cityCode": "0710"
+                },
+                {
+                    "name": "枣庄市",
+                    "adCode": "370400",
+                    "cityCode": "0632"
+                },
+                {
+                    "name": "扎兰屯市",
+                    "adCode": "150783",
+                    "cityCode": "0470"
+                },
+                {
+                    "name": "湛江市",
+                    "adCode": "440800",
+                    "cityCode": "0759"
+                },
+                {
+                    "name": "张家港市",
+                    "adCode": "320582",
+                    "cityCode": "0512"
+                },
+                {
+                    "name": "张家界市",
+                    "adCode": "430800",
+                    "cityCode": "0744"
+                },
+                {
+                    "name": "张家口市",
+                    "adCode": "130700",
+                    "cityCode": "0313"
+                },
+                {
+                    "name": "张掖市",
+                    "adCode": "620700",
+                    "cityCode": "0936"
+                },
+                {
+                    "name": "漳平市",
+                    "adCode": "350881",
+                    "cityCode": "0597"
+                },
+                {
+                    "name": "漳州市",
+                    "adCode": "350600",
+                    "cityCode": "0596"
+                },
+                {
+                    "name": "樟树市",
+                    "adCode": "360982",
+                    "cityCode": "0795"
+                },
+                {
+                    "name": "招远市",
+                    "adCode": "370685",
+                    "cityCode": "0535"
+                },
+                {
+                    "name": "昭通市",
+                    "adCode": "530600",
+                    "cityCode": "0870"
+                },
+                {
+                    "name": "肇东市",
+                    "adCode": "231282",
+                    "cityCode": "0455"
+                },
+                {
+                    "name": "肇庆市",
+                    "adCode": "441200",
+                    "cityCode": "0758"
+                },
+                {
+                    "name": "镇江市",
+                    "adCode": "321100",
+                    "cityCode": "0511"
+                },
+                {
+                    "name": "郑州市",
+                    "adCode": "410100",
+                    "cityCode": "0371",
+                    "type": "hot"
+                },
+                {
+                    "name": "枝江市",
+                    "adCode": "420583",
+                    "cityCode": "0717"
+                },
+                {
+                    "name": "中山市",
+                    "adCode": "442000",
+                    "cityCode": "0760"
+                },
+                {
+                    "name": "中卫市",
+                    "adCode": "640500",
+                    "cityCode": "1953"
+                },
+                {
+                    "name": "钟祥市",
+                    "adCode": "420881",
+                    "cityCode": "0724"
+                },
+                {
+                    "name": "舟山市",
+                    "adCode": "330900",
+                    "cityCode": "0580"
+                },
+                {
+                    "name": "周口市",
+                    "adCode": "411600",
+                    "cityCode": "0394"
+                },
+                {
+                    "name": "珠海市",
+                    "adCode": "440400",
+                    "cityCode": "0756"
+                },
+                {
+                    "name": "株洲市",
+                    "adCode": "430200",
+                    "cityCode": "0733"
+                },
+                {
+                    "name": "诸城市",
+                    "adCode": "370782",
+                    "cityCode": "0536"
+                },
+                {
+                    "name": "诸暨市",
+                    "adCode": "330681",
+                    "cityCode": "0575"
+                },
+                {
+                    "name": "驻马店市",
+                    "adCode": "411700",
+                    "cityCode": "0396"
+                },
+                {
+                    "name": "庄河市",
+                    "adCode": "210283",
+                    "cityCode": "0411"
+                },
+                {
+                    "name": "涿州市",
+                    "adCode": "130681",
+                    "cityCode": "0312"
+                },
+                {
+                    "name": "资兴市",
+                    "adCode": "431081",
+                    "cityCode": "0735"
+                },
+                {
+                    "name": "资阳市",
+                    "adCode": "512000",
+                    "cityCode": "0832"
+                },
+                {
+                    "name": "淄博市",
+                    "adCode": "370300",
+                    "cityCode": "0533"
+                },
+                {
+                    "name": "自贡市",
+                    "adCode": "510300",
+                    "cityCode": "0813"
+                },
+                {
+                    "name": "邹城市",
+                    "adCode": "370883",
+                    "cityCode": "0537"
+                },
+                {
+                    "name": "遵化市",
+                    "adCode": "130281",
+                    "cityCode": "0315"
+                },
+                {
+                    "name": "遵义市",
+                    "adCode": "520300",
+                    "cityCode": "0852"
+                }
+            ]
+        }
+    ]
+}

+ 15 - 9
src/components/Upload/Imgs.vue

@@ -69,7 +69,7 @@ interface UploadFileProps {
   disabled?: boolean; // 是否禁用上传组件 ==> 非必传(默认为 false)
   limit?: number; // 最大图片上传数 ==> 非必传(默认为 5张)
   fileSize?: number; // 图片大小限制 ==> 非必传(默认为 5M)
-  fileType?: File.ImageMimeType[]; // 图片类型限制 ==> 非必传(默认为 ["image/jpeg", "image/png", "image/gif"])
+  fileType?: string[]; // 接受的 MIME(图片 + 可选视频)==> 非必传
   height?: string; // 组件高度 ==> 非必传(默认为 150px)
   width?: string; // 组件宽度 ==> 非必传(默认为 150px)
   borderRadius?: string; // 组件边框圆角 ==> 非必传(默认为 8px)
@@ -85,7 +85,7 @@ const props = withDefaults(defineProps<UploadFileProps>(), {
   disabled: false,
   limit: 5,
   fileSize: 5,
-  fileType: () => ["image/jpeg", "image/png", "image/gif"],
+  fileType: () => ["image/jpeg", "image/png", "image/gif", "video/mp4", "video/webm", "video/quicktime", "video/ogg"],
   height: "150px",
   width: "150px",
   borderRadius: "8px",
@@ -160,22 +160,28 @@ const isVideoFile = (file: UploadFile) => {
  * */
 const beforeUpload: UploadProps["beforeUpload"] = rawFile => {
   const imgSize = rawFile.size / 1024 / 1024 < props.fileSize;
-  const imgType = props.fileType.includes(rawFile.type as File.ImageMimeType);
-  if (!imgType)
+  const acceptVideo = props.fileType.some(t => String(t).startsWith("video/"));
+  const byNameVideo = /\.(mp4|m4v|webm|ogg|mov)(\?.*)?$/i.test(rawFile.name || "");
+  const mimeVideo = typeof rawFile.type === "string" && rawFile.type.startsWith("video/");
+  const looseVideoMime =
+    acceptVideo && byNameVideo && (!rawFile.type || rawFile.type === "application/octet-stream" || mimeVideo);
+  const typeListed = props.fileType.includes(rawFile.type);
+  const okType = typeListed || looseVideoMime;
+  if (!okType)
     ElNotification({
       title: "温馨提示",
-      message: "上传图片不符合所需的格式!",
+      message: "上传文件不符合所需的格式!",
       type: "warning"
     });
   if (!imgSize)
     setTimeout(() => {
       ElNotification({
         title: "温馨提示",
-        message: `上传图片大小不能超过 ${props.fileSize}M!`,
+        message: `上传文件大小不能超过 ${props.fileSize}M!`,
         type: "warning"
       });
     }, 0);
-  return imgType && imgSize;
+  return okType && imgSize;
 };
 
 /**
@@ -333,7 +339,7 @@ const handleImageLoad = (event: Event) => {
 const uploadError = () => {
   ElNotification({
     title: "温馨提示",
-    message: "图片上传失败,请您重新上传!",
+    message: "上传失败,请您重新上传!",
     type: "error"
   });
 };
@@ -344,7 +350,7 @@ const uploadError = () => {
 const handleExceed = () => {
   ElNotification({
     title: "温馨提示",
-    message: `当前最多只能上传 ${props.limit} 张图片,请移除后上传!`,
+    message: `当前最多只能上传 ${props.limit} 个文件,请移除后上传!`,
     type: "warning"
   });
 };

+ 6 - 20
src/stores/modules/auth.ts

@@ -75,8 +75,8 @@ export const useAuthStore = defineStore({
                 menu.meta.isHide = businessSection !== 2;
                 break;
               case "设施与服务":
-                // 只在洗浴汗蒸(4) 和 运动健身(7) 时显示设施与服务
-                menu.meta.isHide = ![4, 7].includes(businessSection);
+                // 特色美食(1) 不显示设施与服务
+                menu.meta.isHide = businessSection !== 1;
                 break;
               case "门店基础信息":
               case "门店头图":
@@ -136,24 +136,10 @@ export const useAuthStore = defineStore({
             }
           }
 
-          // 处理子菜单
-          // if (menu.children && menu.children.length > 0) {
-          //   // 检查子菜单中是否有需要显示的菜单项
-          //   let hasVisibleChild = false;
-          //   menu.children.forEach((child: any) => {
-          //     if (!child.meta?.isHide) {
-          //       hasVisibleChild = true;
-          //     }
-          //   });
-
-          //   // 如果父菜单基础信息、头图、相册本身被隐藏,但有可见子菜单,则显示父菜单
-          //   if (menu.meta?.isHide && hasVisibleChild) {
-          //     menu.meta.isHide = false;
-          //   }
-
-          //   // 递归处理子菜单
-          //   processMenus(menu.children);
-          // }
+          // 递归处理子菜单:switch 按 meta.title 匹配,子级(如「设施与服务」在「基础设施服务」下)否则永远走不到
+          if (menu.children?.length) {
+            processMenus(menu.children);
+          }
         });
       };
 

+ 8 - 0
src/typings/global.d.ts

@@ -62,6 +62,14 @@ declare interface ViteEnv {
   VITE_CRYPTO_KEY: string;
   VITE_CRYPTO_IV: string;
   VITE_WS_BASE?: string;
+  /** Tus 上传服务根(可选,不配则开发走 /ai-upload 代理、生产走 upload.ailien.shop) */
+  VITE_AI_UPLOAD_BASE?: string;
+  /** AI 审核服务根(可选,不配则开发走 /ai-moderate 代理) */
+  VITE_AI_MODERATE_BASE?: string;
+  /** 上传完成后对外访问 URL 前缀,默认 http://upload.ailien.shop:8088/files */
+  VITE_AI_FILES_PUBLIC_BASE?: string;
+  /** 设为 false 时图片仍走原 OSS / uploadMore,不经过 Tus + AI 审核 */
+  VITE_UPLOAD_IMAGE_AI_MODERATE?: string;
 }
 
 interface ImportMetaEnv extends ViteEnv {

+ 29 - 0
src/utils/commonCommentList.ts

@@ -0,0 +1,29 @@
+/** 将 commonComment/getListBySourceType 等接口的单条评论转为列表展示用结构(兼容旧 storeComment 模板字段) */
+export function normalizeCommonCommentListItem(row: any): any {
+  if (!row || typeof row !== "object") return row;
+  const children = row.childCommonComments ?? row.storeComment ?? [];
+  const normalizedChildren = Array.isArray(children) ? children.map(normalizeCommonCommentListItem) : [];
+  return {
+    ...row,
+    userAvatar: row.userAvatar ?? row.headImg,
+    userName: row.userName ?? row.headName ?? row.headPhone ?? "用户",
+    commentContent: row.commentContent ?? row.content ?? "",
+    isLiked: row.isLiked === true || row.isLiked === 1 || row.isLike === "1" || row.isLike === 1,
+    userImage: row.userImage ?? row.headImg,
+    storeComment: normalizedChildren
+  };
+}
+
+/**
+ * 解析列表接口 data:支持 data 为数组,或分页 records
+ */
+export function normalizeCommonCommentListResponse(resData: unknown): any[] {
+  if (Array.isArray(resData)) return resData.map(normalizeCommonCommentListItem);
+  const rec = (resData as { records?: unknown })?.records;
+  if (Array.isArray(rec)) return rec.map(normalizeCommonCommentListItem);
+  return [];
+}
+
+export function countTopAndNestedComments(list: { storeComment?: unknown[] }[]): number {
+  return list.reduce((n, c) => n + 1 + (Array.isArray(c.storeComment) ? c.storeComment.length : 0), 0);
+}

+ 20 - 0
src/utils/config.ts

@@ -0,0 +1,20 @@
+/**
+ * AI Tus 上传与内容审核服务基址(与 uni 端逻辑对齐,适配 Web)
+ * 开发环境默认走 Vite 代理前缀,需在 .env.development 的 VITE_PROXY 中配置 /ai-upload、/ai-moderate
+ */
+const trimSlash = (s: string) => s.replace(/\/$/, "");
+
+export const BASE_AI_URL = trimSlash(
+  String(import.meta.env.VITE_AI_UPLOAD_BASE || "").trim() ||
+    (import.meta.env.DEV ? "/ai-upload" : "https://upload.ailien.shop:8443")
+);
+
+export const BASE_AI_MODERATE_URL = trimSlash(
+  String(import.meta.env.VITE_AI_MODERATE_BASE || "").trim() ||
+    (import.meta.env.DEV ? "/ai-moderate" : "https://verify.ailien.shop:8444")
+);
+
+/** 上传完成后对外可访问的文件 URL:`${AI_UPLOAD_FILES_PUBLIC_BASE}/${uploadId}` */
+export const AI_UPLOAD_FILES_PUBLIC_BASE = trimSlash(
+  String(import.meta.env.VITE_AI_FILES_PUBLIC_BASE || "").trim() || "https://upload.ailien.shop:8443/files"
+);

+ 7 - 7
src/views/accountRoleManagement/roleManagement/create.vue

@@ -146,13 +146,13 @@ const transformMenuData = (menuList: MenuItem[]): any[] => {
       node.children = transformMenuData(menu.children);
     }
     // 判断是否是门店装修
-    if (localGet("storeTickets") == 0) {
-      if (menu.menuName === "门店装修") {
-        node.disabled = true;
-        node.disableByStoreDecorate = true;
-        if (node.children?.length) setStoreDecorateDisabledRecursive(node.children);
-      }
-    }
+    // if (localGet("storeTickets") == 0) {
+    //   if (menu.menuName === "门店装修") {
+    //     node.disabled = true;
+    //     node.disableByStoreDecorate = true;
+    //     if (node.children?.length) setStoreDecorateDisabledRecursive(node.children);
+    //   }
+    // }
 
     return node;
   });

+ 31 - 21
src/views/appoinmentManagement/appoinmentInfo.vue

@@ -6,7 +6,12 @@
         <span class="filter-label">姓名</span>
         <el-input v-model="searchForm.reservationUserName" placeholder="请输入姓名" clearable style="width: 160px" />
         <span class="filter-label">状态</span>
-        <el-select v-model="searchForm.orderStatus" placeholder="请选择" clearable style="width: 180px">
+        <el-select
+          v-model="searchForm.orderStatus"
+          clearable
+          style="width: 180px"
+          @clear="searchForm.orderStatus = STATUS_FILTER_ALL"
+        >
           <el-option
             v-for="opt in statusOptions"
             :key="`${opt.label}-${String(opt.value)}`"
@@ -65,21 +70,17 @@
           >
             <el-button link type="primary" @click="handleDelete(scope.row)"> 删除 </el-button>
           </template>
+          <!-- 已过期(3) 且结束未超 3 小时:付费先判断(退款+删除),否则仅删除;顺序不可颠倒,否则宽条件会吃掉窄条件 -->
           <template
-            v-else-if="
-              (isOrderStatus(scope.row, 2) || isOrderStatus(scope.row, 7) || isOrderStatus(scope.row, 3)) &&
-              !isMoreThanThreeHoursAfterEnd(scope.row)
-            "
+            v-else-if="isOrderStatus(scope.row, 3) && !isMoreThanThreeHoursAfterEnd(scope.row) && orderCostTypeIsPaid(scope.row)"
           >
+            <el-button link type="primary" @click="handleRefund(scope.row)"> 退款 </el-button>
             <el-button link type="primary" @click="handleDelete(scope.row)"> 删除 </el-button>
           </template>
-          <template v-else-if="isOrderStatus(scope.row, 7) && !isMoreThanThreeHoursAfterEnd(scope.row)">
+          <template v-else-if="isOrderStatus(scope.row, 3) && !isMoreThanThreeHoursAfterEnd(scope.row)">
             <el-button link type="primary" @click="handleDelete(scope.row)"> 删除 </el-button>
           </template>
-          <template
-            v-else-if="isOrderStatus(scope.row, 3) && !isMoreThanThreeHoursAfterEnd(scope.row) && orderCostTypeIsPaid(scope.row)"
-          >
-            <el-button link type="primary" @click="handleRefund(scope.row)"> 退款 </el-button>
+          <template v-else-if="isOrderStatus(scope.row, 7) && !isMoreThanThreeHoursAfterEnd(scope.row)">
             <el-button link type="primary" @click="handleDelete(scope.row)"> 删除 </el-button>
           </template>
           <template v-else-if="isOrderStatus(scope.row, 4) && !orderCostTypeIsPaid(scope.row)">
@@ -97,13 +98,19 @@
     </ProTable>
 
     <!-- 查看原因 -->
-    <el-dialog v-model="reasonDialogVisible" title="原因" width="420px" append-to-body destroy-on-close>
-      <div class="reason-dialog-body">取消原因:</div>
-      <div class="reason-dialog-body">
+    <el-dialog
+      v-model="reasonDialogVisible"
+      title="取消原因"
+      width="420px"
+      append-to-body
+      destroy-on-close
+      class="cancel-reason-dialog"
+    >
+      <div class="reason-dialog-body" style="padding-left: 20px">
         {{ reasonDialogText || "—" }}
       </div>
       <template #footer>
-        <el-button type="primary" @click="reasonDialogVisible = false"> 知道了 </el-button>
+        <el-button type="primary" @click="reasonDialogVisible = false"> 返回 </el-button>
       </template>
     </el-dialog>
 
@@ -237,9 +244,11 @@ const columns: ColumnProps<ReservationRow>[] = [
  */
 const STATUS_FILTER_MERCHANT_CANCEL = "merchant_cancel";
 const STATUS_FILTER_USER_CANCEL = "user_cancel";
+/** 占位选项值:勿用 "",el-select 常无法匹配空串而不显示「全部」 */
+const STATUS_FILTER_ALL = "__all__";
 
 const statusOptions: { label: string; value: number | string }[] = [
-  { label: "全部", value: "" },
+  { label: "全部", value: STATUS_FILTER_ALL },
   { label: "待使用", value: 1 },
   { label: "退款成功", value: 7 },
   { label: "商家取消", value: STATUS_FILTER_MERCHANT_CANCEL },
@@ -281,14 +290,14 @@ const initParam = reactive({
 /** 已生效的查询条件(点击搜索后写入;接口字段 reservationUserName、orderStatus) */
 const listFilter = reactive({
   reservationUserName: "",
-  orderStatus: "" as number | string,
+  orderStatus: STATUS_FILTER_ALL as number | string,
   startDate: "",
   endDate: ""
 });
 
 const searchForm = reactive({
   reservationUserName: "",
-  orderStatus: "" as number | string,
+  orderStatus: STATUS_FILTER_ALL as number | string,
   dateRange: [] as string[]
 });
 
@@ -478,7 +487,7 @@ async function getTableList(params: any) {
     req.reservationUserName = listFilter.reservationUserName.trim();
   }
   const sf = listFilter.orderStatus;
-  if (sf !== undefined && sf !== "" && sf !== null) {
+  if (sf !== undefined && sf !== "" && sf !== null && sf !== STATUS_FILTER_ALL) {
     if (sf === STATUS_FILTER_USER_CANCEL || sf === STATUS_FILTER_MERCHANT_CANCEL) {
       req.orderStatus = 4;
     } else {
@@ -529,10 +538,10 @@ function handleSearch() {
 
 function handleReset() {
   searchForm.reservationUserName = "";
-  searchForm.orderStatus = "";
+  searchForm.orderStatus = STATUS_FILTER_ALL;
   searchForm.dateRange = [];
   listFilter.reservationUserName = "";
-  listFilter.orderStatus = "";
+  listFilter.orderStatus = STATUS_FILTER_ALL;
   listFilter.startDate = "";
   listFilter.endDate = "";
   proTable.value?.getTableList();
@@ -654,7 +663,7 @@ function handleDelete(row: ReservationRow) {
   })
     .then(async () => {
       try {
-        await reservationDelete({ id: row.id });
+        await reservationDelete({ reservationId: row.id });
         ElMessage.success("删除成功");
         proTable.value?.getTableList();
       } catch (e: any) {
@@ -766,6 +775,7 @@ function handleRefund(row: ReservationRow) {
   color: #606266;
 }
 .cancel-reason-dialog.el-dialog .el-dialog__body {
+  height: 300px;
   padding-top: 8px;
 }
 .cancel-reason-form {

+ 7 - 4
src/views/appoinmentManagement/classifyManagement.vue

@@ -33,6 +33,7 @@
       v-model="dialogVisible"
       :title="editId == null ? '新建分类' : '编辑分类'"
       width="480px"
+      class="classify-edit-dialog"
       append-to-body
       destroy-on-close
       @close="onDialogClose"
@@ -438,12 +439,14 @@ async function submitForm() {
   }
 }
 </script>
-
-<style scoped lang="scss">
-:deep(.el-dialog__body) {
+<!-- append-to-body 时弹窗在 body 下,不是 .classify-management 子节点,需用 dialog 自身 class 命中 -->
+<style lang="scss">
+.classify-edit-dialog .el-dialog__body {
+  box-sizing: border-box;
   height: 400px;
-  border: 1px solid red;
 }
+</style>
+<style scoped lang="scss">
 .classify-management {
   padding: 0;
 }

+ 6 - 1
src/views/appoinmentManagement/tableManagement.vue

@@ -544,7 +544,12 @@ onMounted(() => {
   loadCategories();
 });
 </script>
-
+<style lang="scss">
+.table-management-dialog .el-dialog__body {
+  box-sizing: border-box;
+  height: 300px;
+}
+</style>
 <style scoped lang="scss">
 .table-management {
   padding: 0;

+ 2 - 2
src/views/businessData/compare.vue

@@ -148,7 +148,7 @@
               </div>
             </div>
           </el-tab-pane>
-          <el-tab-pane label="代金券" name="voucher">
+          <!-- <el-tab-pane label="代金券1" name="voucher">
             <div class="compare-cards">
               <div v-for="item in voucherCompareList" :key="item.key" class="compare-card">
                 <div class="card-title">
@@ -181,7 +181,7 @@
                 </div>
               </div>
             </div>
-          </el-tab-pane>
+          </el-tab-pane> -->
           <el-tab-pane label="服务质量" name="service">
             <div class="compare-cards">
               <div v-for="item in serviceCompareList" :key="item.key" class="compare-card">

+ 493 - 0
src/views/businessInfo/accountInfo.vue

@@ -0,0 +1,493 @@
+<template>
+  <div class="account-info-page">
+    <h1 class="page-title">结算账户</h1>
+
+    <section class="form-block">
+      <h2 class="section-head">
+        <span class="section-bar" aria-hidden="true" />
+        结算账户
+      </h2>
+
+      <el-form
+        ref="formRef"
+        class="account-form"
+        :model="form"
+        :rules="rules"
+        label-width="120px"
+        require-asterisk-position="right"
+        label-position="right"
+      >
+        <el-form-item label="账户户名" prop="accountName">
+          <el-input v-model="form.accountName" placeholder="请输入账户户名" clearable maxlength="64" style="max-width: 480px" />
+        </el-form-item>
+
+        <el-form-item label="账户类型" prop="accountType">
+          <el-radio-group v-model="form.accountType" class="account-type-radio">
+            <el-radio :value="BANK_ACCOUNT_TYPE_CORPORATE"> 对公账户 </el-radio>
+            <el-radio :value="BANK_ACCOUNT_TYPE_PERSONAL"> 个人储蓄卡 </el-radio>
+          </el-radio-group>
+        </el-form-item>
+
+        <el-form-item label="银行账号" prop="bankAccountNo">
+          <div class="field-stack">
+            <el-input
+              v-model="form.bankAccountNo"
+              placeholder="请输入开户银行账号"
+              clearable
+              maxlength="32"
+              style="max-width: 480px"
+            />
+            <p class="field-tip">
+              {{ bankAccountTip }}
+            </p>
+          </div>
+        </el-form-item>
+
+        <el-form-item label="开户银行" prop="bankCode">
+          <div class="field-stack">
+            <el-popover
+              v-model:visible="bankPickerVisible"
+              placement="bottom-start"
+              :width="580"
+              trigger="click"
+              popper-class="bank-picker-popper"
+            >
+              <template #reference>
+                <el-input
+                  readonly
+                  :model-value="selectedBankLabel"
+                  placeholder="请选择开户银行"
+                  style="max-width: 480px"
+                  class="bank-trigger-input"
+                  :class="{ 'is-focus-like': bankPickerVisible }"
+                >
+                  <template #suffix>
+                    <el-icon class="el-select__caret">
+                      <ArrowDown />
+                    </el-icon>
+                  </template>
+                </el-input>
+              </template>
+              <div class="bank-picker" @click.stop>
+                <el-radio-group v-model="bankTab" size="small" class="bank-tab-group">
+                  <el-radio-button value="common"> 常用银行 </el-radio-button>
+                  <el-radio-button value="A-F"> ABCDEF </el-radio-button>
+                  <el-radio-button value="G-L"> GHJKL </el-radio-button>
+                  <el-radio-button value="M-P"> MNOP </el-radio-button>
+                  <el-radio-button value="Q-U"> QRSTU </el-radio-button>
+                  <el-radio-button value="V-Z"> VWXYZ </el-radio-button>
+                </el-radio-group>
+                <div class="bank-grid-wrap">
+                  <div class="bank-grid">
+                    <button
+                      v-for="b in filteredBanks"
+                      :key="b.code"
+                      type="button"
+                      class="bank-cell"
+                      :class="{ 'is-active': form.bankCode === b.code }"
+                      @click="selectBank(b)"
+                    >
+                      <span class="bank-logo" :style="{ background: b.color }">{{ b.logoText }}</span>
+                      <span class="bank-name">{{ b.shortName }}</span>
+                    </button>
+                  </div>
+                </div>
+              </div>
+            </el-popover>
+          </div>
+        </el-form-item>
+      </el-form>
+    </section>
+
+    <div class="footer-actions">
+      <el-button @click="onBack"> 返回 </el-button>
+      <el-button type="primary" class="btn-next" :loading="submitLoading" @click="onSubmit"> 确定 </el-button>
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { computed, nextTick, onMounted, reactive, ref, watch } from "vue";
+import { useRoute, useRouter } from "vue-router";
+import { ElMessage } from "element-plus";
+import type { FormInstance, FormRules } from "element-plus";
+import { ArrowDown } from "@element-plus/icons-vue";
+import { localGet, localSet } from "@/utils/index";
+
+const BUSINESS_DATA_CACHE_KEY = "businessData";
+
+const BANK_ACCOUNT_TYPE_CORPORATE = "BANK_ACCOUNT_TYPE_CORPORATE" as const;
+const BANK_ACCOUNT_TYPE_PERSONAL = "BANK_ACCOUNT_TYPE_PERSONAL" as const;
+
+const formRef = ref<FormInstance>();
+const submitLoading = ref(false);
+const bankPickerVisible = ref(false);
+const bankTab = ref("common");
+const route = useRoute();
+const router = useRouter();
+
+export interface BankItem {
+  code: string;
+  shortName: string;
+  tabKey: "common" | "A-F" | "G-L" | "M-P" | "Q-U" | "V-Z";
+  logoText: string;
+  color: string;
+}
+
+/** 演示数据:常用 + 按首字母分组(与示意图「标签 + 网格」一致) */
+const BANK_LIST: BankItem[] = [
+  { code: "ICBC", shortName: "工商银行", tabKey: "common", logoText: "工", color: "#c62828" },
+  { code: "ABC", shortName: "农业银行", tabKey: "common", logoText: "农", color: "#2e7d32" },
+  { code: "BOC", shortName: "中国银行", tabKey: "common", logoText: "中", color: "#b71c1c" },
+  { code: "CCB", shortName: "建设银行", tabKey: "common", logoText: "建", color: "#1565c0" },
+  { code: "COMM", shortName: "交通银行", tabKey: "common", logoText: "交", color: "#283593" },
+  { code: "PSBC", shortName: "邮储银行", tabKey: "common", logoText: "邮", color: "#00695c" },
+  { code: "CMB", shortName: "招商银行", tabKey: "common", logoText: "招", color: "#c62828" },
+  { code: "SPDB", shortName: "浦发银行", tabKey: "common", logoText: "浦", color: "#0d47a1" },
+  { code: "CIB", shortName: "兴业银行", tabKey: "common", logoText: "兴", color: "#1565c0" },
+  { code: "CMBC", shortName: "民生银行", tabKey: "common", logoText: "民", color: "#4e342e" },
+  { code: "HXB", shortName: "华夏银行", tabKey: "G-L", logoText: "华", color: "#d84315" },
+  { code: "GDB", shortName: "广发银行", tabKey: "G-L", logoText: "广", color: "#c62828" },
+  { code: "PAB", shortName: "平安银行", tabKey: "M-P", logoText: "平", color: "#f57f17" },
+  { code: "CITIC", shortName: "中信银行", tabKey: "M-P", logoText: "信", color: "#c62828" },
+  { code: "CEB", shortName: "光大银行", tabKey: "G-L", logoText: "光", color: "#6a1b9a" },
+  { code: "BOSH", shortName: "上海银行", tabKey: "G-L", logoText: "上", color: "#283593" },
+  { code: "BRCB", shortName: "北京银行", tabKey: "A-F", logoText: "京", color: "#c62828" },
+  { code: "NJCB", shortName: "南京银行", tabKey: "M-P", logoText: "宁", color: "#c62828" },
+  { code: "HZCB", shortName: "杭州银行", tabKey: "G-L", logoText: "杭", color: "#1565c0" },
+  { code: "ASB", shortName: "鞍山银行", tabKey: "A-F", logoText: "鞍", color: "#37474f" },
+  { code: "BSB", shortName: "包商银行", tabKey: "A-F", logoText: "包", color: "#455a64" },
+  { code: "QDCCB", shortName: "青岛银行", tabKey: "M-P", logoText: "青", color: "#0d47a1" },
+  { code: "WFCB", shortName: "潍坊银行", tabKey: "V-Z", logoText: "潍", color: "#1565c0" },
+  { code: "WZCB", shortName: "温州银行", tabKey: "V-Z", logoText: "温", color: "#c62828" },
+  { code: "XMBANK", shortName: "厦门银行", tabKey: "Q-U", logoText: "厦", color: "#00695c" },
+  { code: "YTBANK", shortName: "烟台银行", tabKey: "V-Z", logoText: "烟", color: "#37474f" },
+  { code: "ZZBANK", shortName: "郑州银行", tabKey: "V-Z", logoText: "郑", color: "#c62828" }
+];
+
+const form = reactive({
+  accountName: "",
+  accountType: "BANK_ACCOUNT_TYPE_CORPORATE" as "BANK_ACCOUNT_TYPE_CORPORATE" | "BANK_ACCOUNT_TYPE_PERSONAL",
+  bankAccountNo: "",
+  bankCode: ""
+});
+
+const selectedBankLabel = computed(() => {
+  if (!form.bankCode) return "";
+  const b = BANK_LIST.find(x => x.code === form.bankCode);
+  return b ? b.shortName : "";
+});
+
+const bankAccountTip = computed(() => {
+  if (form.accountType === "BANK_ACCOUNT_TYPE_CORPORATE") {
+    return "请务必填写与账户户名一致的对公银行账户。";
+  }
+  return "请务必填写与账户户名一致的个人储蓄卡账号。";
+});
+
+const tabToKey = computed<BankItem["tabKey"] | "common">(() => {
+  const m: Record<string, BankItem["tabKey"] | "common"> = {
+    common: "common",
+    "A-F": "A-F",
+    "G-L": "G-L",
+    "M-P": "M-P",
+    "Q-U": "Q-U",
+    "V-Z": "V-Z"
+  };
+  return m[bankTab.value] ?? "common";
+});
+
+const filteredBanks = computed(() => {
+  const k = tabToKey.value;
+  if (k === "common") return BANK_LIST.filter(b => b.tabKey === "common");
+  return BANK_LIST.filter(b => b.tabKey === k);
+});
+
+const rules: FormRules = {
+  accountName: [{ required: true, message: "请输入账户户名", trigger: "blur" }],
+  accountType: [{ required: true, message: "请选择账户类型", trigger: "change" }],
+  bankAccountNo: [
+    { required: true, message: "请输入银行账号", trigger: "blur" },
+    { pattern: /^[\d\s-]{8,40}$/, message: "请输入有效的银行账号", trigger: "blur" }
+  ],
+  bankCode: [{ required: true, message: "请选择开户银行", trigger: "change" }]
+};
+
+function selectBank(b: BankItem) {
+  form.bankCode = b.code;
+  bankPickerVisible.value = false;
+  formRef.value?.validateField("bankCode").catch(() => {});
+}
+
+function onBack() {
+  router.push({ path: "/businessInfo/industryQualifications", query: { ...route.query } });
+}
+
+function onSaveDraft() {
+  ElMessage.success("草稿已保存(可对接接口)");
+}
+
+/** 账户户名:subject_info.business_license_info.merchant_name */
+function readMerchantNameFromSubjectInfo(): string {
+  const raw = localGet(BUSINESS_DATA_CACHE_KEY) as Record<string, unknown> | null | undefined;
+  if (!raw || typeof raw !== "object" || Array.isArray(raw)) return "";
+  const si = raw.subject_info as Record<string, unknown> | undefined;
+  if (!si || typeof si !== "object" || Array.isArray(si)) return "";
+  const bli = si.business_license_info as Record<string, unknown> | undefined;
+  if (!bli || typeof bli !== "object" || Array.isArray(bli)) return "";
+  return String(bli.merchant_name ?? "").trim();
+}
+
+function resolveBankCodeFromAccountBank(accountBank: string): string {
+  const s = accountBank.trim();
+  if (!s) return "";
+  const byCode = BANK_LIST.find(b => b.code === s);
+  if (byCode) return byCode.code;
+  const byShort = BANK_LIST.find(b => b.shortName === s);
+  if (byShort) return byShort.code;
+  return "";
+}
+
+/** 从缓存 bank_account_info 反显;无户名时用 subject_info 营业执照商户名 */
+function hydrateAccountFormFromBusinessDataCache() {
+  const raw = localGet(BUSINESS_DATA_CACHE_KEY) as Record<string, unknown> | null | undefined;
+  if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
+    const m = readMerchantNameFromSubjectInfo();
+    if (m) form.accountName = m;
+    return;
+  }
+  const ba = raw.bank_account_info as Record<string, unknown> | undefined;
+  if (!ba || typeof ba !== "object" || Array.isArray(ba)) {
+    const m = readMerchantNameFromSubjectInfo();
+    if (m) form.accountName = m;
+    return;
+  }
+
+  const accName = String(ba.account_name ?? "").trim();
+  form.accountName = accName || readMerchantNameFromSubjectInfo();
+
+  const t = String(ba.bank_account_type ?? "").trim();
+  if (t === BANK_ACCOUNT_TYPE_CORPORATE || t === BANK_ACCOUNT_TYPE_PERSONAL) {
+    form.accountType = t;
+  }
+
+  form.bankAccountNo = String(ba.account_number ?? "").trim();
+
+  const bankLabel = String(ba.account_bank ?? "").trim();
+  form.bankCode = resolveBankCodeFromAccountBank(bankLabel);
+}
+
+onMounted(() => {
+  hydrateAccountFormFromBusinessDataCache();
+  nextTick(() => formRef.value?.clearValidate());
+});
+
+function mergeBankAccountIntoBusinessDataCache() {
+  const prev = localGet(BUSINESS_DATA_CACHE_KEY);
+  const base = prev && typeof prev === "object" && !Array.isArray(prev) ? { ...(prev as Record<string, unknown>) } : {};
+  const prevBa =
+    base.bank_account_info && typeof base.bank_account_info === "object" && !Array.isArray(base.bank_account_info)
+      ? { ...(base.bank_account_info as Record<string, unknown>) }
+      : {};
+
+  const accountBankName = selectedBankLabel.value || String(form.bankCode || "").trim();
+
+  base.bank_account_info = {
+    ...prevBa,
+    bank_account_type: form.accountType,
+    account_bank: accountBankName,
+    account_number: String(form.bankAccountNo || "")
+      .replace(/\s+/g, "")
+      .trim(),
+    account_name: String(form.accountName || "").trim()
+  };
+  localSet(BUSINESS_DATA_CACHE_KEY, base);
+}
+
+async function onSubmit() {
+  if (!formRef.value) return;
+  submitLoading.value = true;
+  try {
+    await formRef.value.validate();
+    mergeBankAccountIntoBusinessDataCache();
+    await router.push({
+      path: "/businessInfo/adminInfo",
+      query: { ...route.query }
+    });
+  } catch {
+    ElMessage.warning("请完善必填信息");
+  } finally {
+    submitLoading.value = false;
+  }
+}
+
+watch(
+  () => form.accountType,
+  () => {
+    formRef.value?.validateField("bankAccountNo").catch(() => {});
+  }
+);
+</script>
+
+<style scoped lang="scss">
+$wechat-green: #07c160;
+.account-info-page {
+  box-sizing: border-box;
+  min-height: 100%;
+  padding: 24px 32px 40px;
+  margin: 0 auto;
+  background: #ffffff;
+}
+.page-title {
+  margin: 0 0 24px;
+  font-size: 20px;
+  font-weight: 600;
+  color: #303133;
+}
+.form-block {
+  margin-bottom: 24px;
+}
+.section-head {
+  display: flex;
+  align-items: center;
+  margin: 0 0 20px;
+  font-size: 16px;
+  font-weight: 600;
+  color: #303133;
+}
+.section-bar {
+  display: inline-block;
+  flex-shrink: 0;
+  width: 4px;
+  height: 16px;
+  margin-right: 8px;
+  background: $wechat-green;
+  border-radius: 2px;
+}
+.account-form {
+  :deep(.el-form-item__label) {
+    font-weight: 500;
+    color: #606266;
+  }
+}
+.field-stack {
+  width: 100%;
+}
+.field-tip {
+  margin: 8px 0 0;
+  font-size: 12px;
+  line-height: 1.65;
+  color: #909399;
+}
+.account-type-radio {
+  :deep(.el-radio__input.is-checked .el-radio__inner) {
+    background: $wechat-green;
+    border-color: $wechat-green;
+  }
+  :deep(.el-radio__input.is-checked + .el-radio__label) {
+    color: #303133;
+  }
+}
+.bank-trigger-input {
+  cursor: pointer;
+  &.is-focus-like {
+    :deep(.el-input__wrapper) {
+      box-shadow: 0 0 0 1px $wechat-green inset;
+    }
+  }
+}
+.footer-actions {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  padding-top: 24px;
+  margin-top: 16px;
+  border-top: 1px solid #ebeef5;
+}
+.footer-center {
+  display: flex;
+  flex: 1;
+  justify-content: center;
+}
+.btn-next {
+  min-width: 100px;
+  background: $wechat-green;
+  border-color: $wechat-green;
+  &:hover {
+    background: #06ad56;
+    border-color: #06ad56;
+  }
+}
+</style>
+
+<style lang="scss">
+$wechat-green: #07c160;
+.bank-picker-popper {
+  padding: 0 !important;
+}
+.bank-picker {
+  .bank-tab-group {
+    display: flex;
+    flex-wrap: wrap;
+    gap: 6px;
+    padding: 8px 4px 4px;
+    :deep(.el-radio-button__inner) {
+      padding: 6px 10px;
+      font-size: 12px;
+    }
+    :deep(.el-radio-button.is-active .el-radio-button__inner) {
+      color: #ffffff;
+      background: $wechat-green;
+      border-color: $wechat-green;
+      box-shadow: -1px 0 0 0 $wechat-green;
+    }
+  }
+  .bank-grid-wrap {
+    max-height: 280px;
+    padding: 8px 4px 12px;
+    overflow: auto;
+  }
+  .bank-grid {
+    display: grid;
+    grid-template-columns: repeat(3, 1fr);
+    gap: 8px 12px;
+  }
+  .bank-cell {
+    display: flex;
+    gap: 8px;
+    align-items: center;
+    padding: 8px 10px;
+    margin: 0;
+    text-align: left;
+    cursor: pointer;
+    background: #ffffff;
+    border: 1px solid transparent;
+    border-radius: 6px;
+    transition: background 0.15s;
+    &:hover {
+      background: #f5f7fa;
+    }
+    &.is-active {
+      background: #e8f5e9;
+      border-color: $wechat-green;
+    }
+  }
+  .bank-logo {
+    display: inline-flex;
+    flex-shrink: 0;
+    align-items: center;
+    justify-content: center;
+    width: 28px;
+    height: 28px;
+    font-size: 12px;
+    font-weight: 600;
+    color: #ffffff;
+    border-radius: 4px;
+  }
+  .bank-name {
+    font-size: 13px;
+    line-height: 1.3;
+    color: #303133;
+  }
+}
+</style>

+ 461 - 0
src/views/businessInfo/adminInfo.vue

@@ -0,0 +1,461 @@
+<template>
+  <div class="admin-info-page">
+    <h1 class="page-title">超级管理员</h1>
+
+    <section class="form-block">
+      <h2 class="section-head">
+        <span class="section-bar" aria-hidden="true" />
+        超级管理员信息
+      </h2>
+      <p class="section-intro">
+        超级管理员将接收开户信息及完成签约,并可进行商户号日常重要管理及资金操作。请确定超级管理员为商户法定代表人或经办人。
+      </p>
+
+      <el-form
+        ref="formRef"
+        class="admin-form"
+        :model="form"
+        :rules="rules"
+        label-width="140px"
+        require-asterisk-position="right"
+        label-position="right"
+      >
+        <el-form-item label="超管身份" prop="managerIdentity">
+          <el-radio-group v-model="form.managerIdentity" class="identity-radio">
+            <el-radio value="LEGAL"> 法定代表人/经营者 </el-radio>
+            <el-radio value="SUPER"> 经办人 </el-radio>
+          </el-radio-group>
+        </el-form-item>
+
+        <el-form-item label="超管姓名" prop="managerName">
+          <el-input v-model="form.managerName" placeholder="请输入超管姓名" clearable style="max-width: 420px" />
+        </el-form-item>
+
+        <el-form-item label="超管资料类型" prop="managerDocType">
+          <el-select v-model="form.managerDocType" placeholder="请选择" clearable style="max-width: 420px">
+            <el-option label="身份证" value="IDENTIFICATION_TYPE_IDCARD" />
+            <el-option label="护照" value="IDENTIFICATION_TYPE_OVERSEA_PASSPORT" />
+            <el-option label="香港居民来往内地通行证" value="IDENTIFICATION_TYPE_HONGKONG_PASSPORT" />
+            <el-option label="台湾居民来往大陆通行证" value="IDENTIFICATION_TYPE_TAIWAN_PASSPORT" />
+          </el-select>
+        </el-form-item>
+
+        <el-form-item label="证件号码" prop="managerDocNo">
+          <el-input v-model="form.managerDocNo" placeholder="请输入证件号码" clearable style="max-width: 420px" />
+        </el-form-item>
+
+        <el-form-item label="手机号码" prop="mobile">
+          <div class="field-stack">
+            <el-input v-model="form.mobile" placeholder="请输入手机号" clearable maxlength="11" style="max-width: 420px" />
+            <p class="field-tip">用于接收微信支付的重要管理信息及日常操作验证码,超管签约时可自助修改手机号,并进行短信验证</p>
+          </div>
+        </el-form-item>
+
+        <el-form-item label="邮箱" prop="email">
+          <div class="field-stack">
+            <el-input v-model="form.email" placeholder="请输入邮箱" clearable style="max-width: 420px" />
+            <p class="field-tip">用于接收微信支付的开户邮件及日常业务通知</p>
+          </div>
+        </el-form-item>
+      </el-form>
+    </section>
+
+    <div class="footer-actions">
+      <el-button @click="onBack"> 返回 </el-button>
+      <el-button type="danger" class="btn-next" :loading="submitLoading" @click="onSubmit"> 提交 </el-button>
+    </div>
+
+    <el-dialog
+      v-model="signDialogVisible"
+      title="签约链接"
+      width="480px"
+      align-center
+      destroy-on-close
+      @closed="onSignDialogClosed"
+    >
+      <div class="sign-dialog">
+        <div v-if="signQrImageUrl && !signQrError" class="sign-dialog__qr-wrap">
+          <img class="sign-dialog__qr" :src="signQrImageUrl" alt="签约二维码" @error="signQrError = true" />
+        </div>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { computed, nextTick, onMounted, reactive, ref } from "vue";
+import { useRoute, useRouter } from "vue-router";
+import { ElMessage } from "element-plus";
+import type { FormInstance, FormRules } from "element-plus";
+import { localGet, localSet } from "@/utils/index";
+import { applyment, getPaymentApplyment } from "@/api/modules/businessInfo";
+
+const BUSINESS_DATA_CACHE_KEY = "businessData";
+const GEEKER_USER_KEY = "geeker-user";
+
+function resolveApplymentStoreId(): string | number | null {
+  const geeker = localGet(GEEKER_USER_KEY) as { userInfo?: { storeId?: string | number | null } } | null | undefined;
+  const sid = geeker?.userInfo?.storeId ?? localGet("createdId");
+  if (sid === undefined || sid === null || sid === "") return null;
+  return sid;
+}
+
+const formRef = ref<FormInstance>();
+const submitLoading = ref(false);
+const signDialogVisible = ref(false);
+const signUrlText = ref("");
+const signQrError = ref(false);
+const route = useRoute();
+const router = useRouter();
+
+const signQrImageUrl = computed(() => {
+  const u = signUrlText.value.trim();
+  if (!/^https?:\/\//i.test(u)) return "";
+  return `https://api.qrserver.com/v1/create-qr-code/?size=280x280&data=${encodeURIComponent(u)}`;
+});
+
+function pickApplymentIdFromApplymentResponse(res: unknown): string {
+  const r = res as Record<string, unknown> | null | undefined;
+  const top = r?.data !== undefined ? r.data : r;
+  if (!top || typeof top !== "object" || Array.isArray(top)) return "";
+  const t = top as Record<string, unknown>;
+  const inner =
+    t.data !== undefined && t.data !== null && typeof t.data === "object" && !Array.isArray(t.data)
+      ? (t.data as Record<string, unknown>)
+      : t;
+  const id = inner.applyment_id ?? inner.applymentId;
+  return String(id ?? "").trim();
+}
+
+function pickSignUrlFromPaymentApplymentResponse(res: unknown): string {
+  const r = res as Record<string, unknown> | null | undefined;
+  const top = r?.data !== undefined ? r.data : r;
+  if (!top || typeof top !== "object" || Array.isArray(top)) return "";
+  const t = top as Record<string, unknown>;
+  const inner =
+    t.data !== undefined && t.data !== null && typeof t.data === "object" && !Array.isArray(t.data)
+      ? (t.data as Record<string, unknown>)
+      : t;
+  const url = inner.sign_url ?? inner.signUrl;
+  return String(url ?? "").trim();
+}
+
+function onSignDialogClosed() {
+  signUrlText.value = "";
+  signQrError.value = false;
+}
+
+async function copySignUrl() {
+  const u = signUrlText.value.trim();
+  if (!u) return;
+  try {
+    await navigator.clipboard.writeText(u);
+    ElMessage.success("链接已复制");
+  } catch {
+    ElMessage.warning("复制失败,请手动选中复制");
+  }
+}
+
+const form = reactive({
+  managerIdentity: "LEGAL" as "SUPER" | "LEGAL",
+  managerName: "",
+  managerDocType: "",
+  managerDocNo: "",
+  mobile: "",
+  email: ""
+});
+
+const rules: FormRules = {
+  managerIdentity: [{ required: true, message: "请选择超管身份", trigger: "change" }],
+  managerName: [{ required: true, message: "请输入超管姓名", trigger: "blur" }],
+  managerDocType: [{ required: true, message: "请选择超管资料类型", trigger: "change" }],
+  managerDocNo: [{ required: true, message: "请输入证件号码", trigger: "blur" }],
+  mobile: [
+    { required: true, message: "请输入手机号", trigger: "blur" },
+    { pattern: /^1[3-9]\d{9}$/, message: "请输入正确的手机号", trigger: "blur" }
+  ],
+  email: [
+    { required: true, message: "请输入邮箱", trigger: "blur" },
+    { type: "email", message: "请输入正确的邮箱格式", trigger: ["blur", "change"] }
+  ]
+};
+
+function openMobileGuide() {
+  ElMessage.info("超管修改手机号指引(可对接文档)");
+}
+
+function onBack() {
+  router.push({ path: "/businessInfo/accountInfo", query: { ...route.query } });
+}
+
+function onSaveDraft() {
+  ElMessage.success("草稿已保存(可对接接口)");
+}
+
+/** 与 mergeContactInfoIntoBusinessDataCache 字段互逆;并从未填写的 subject_info 补全超管姓名/证件/类型 */
+function hydrateAdminFormFromBusinessDataCache() {
+  const raw = localGet(BUSINESS_DATA_CACHE_KEY) as Record<string, unknown> | null | undefined;
+  if (!raw || typeof raw !== "object" || Array.isArray(raw)) return;
+
+  const ci = raw.contact_info as Record<string, unknown> | undefined;
+  if (ci && typeof ci === "object" && !Array.isArray(ci)) {
+    const ct = String(ci.contact_type ?? "").trim();
+    if (ct === "LEGAL" || ct === "SUPER") {
+      form.managerIdentity = ct;
+    }
+    form.managerName = String(ci.contact_name ?? "").trim();
+    form.managerDocType = String(ci.contact_id_doc_type ?? "").trim();
+    form.managerDocNo = String(ci.contact_id_number ?? "").trim();
+    form.mobile = String(ci.mobile_phone ?? "").trim();
+    form.email = String(ci.contact_email ?? "").trim();
+  }
+
+  const hadContactTypeFromCi = !!(
+    ci &&
+    typeof ci === "object" &&
+    !Array.isArray(ci) &&
+    ["LEGAL", "SUPER"].includes(String(ci.contact_type ?? "").trim())
+  );
+
+  const si = raw.subject_info as Record<string, unknown> | undefined;
+  if (!si || typeof si !== "object" || Array.isArray(si)) {
+    return;
+  }
+
+  if (!hadContactTypeFromCi) {
+    const ctSi = String(si.contact_type ?? "").trim();
+    if (ctSi === "LEGAL" || ctSi === "SUPER") {
+      form.managerIdentity = ctSi;
+    }
+  }
+
+  const ii = si.identity_info as Record<string, unknown> | undefined;
+  const docType = ii && typeof ii === "object" && !Array.isArray(ii) ? String(ii.id_doc_type ?? "").trim() : "";
+  const ici =
+    ii && typeof ii === "object" && !Array.isArray(ii) ? (ii.id_card_info as Record<string, unknown> | undefined) : undefined;
+  const idNum = ici && typeof ici === "object" && !Array.isArray(ici) ? String(ici.id_card_number ?? "").trim() : "";
+  const idName = ici && typeof ici === "object" && !Array.isArray(ici) ? String(ici.id_card_name ?? "").trim() : "";
+
+  const bli = si.business_license_info as Record<string, unknown> | undefined;
+  const legalPerson = bli && typeof bli === "object" && !Array.isArray(bli) ? String(bli.legal_person ?? "").trim() : "";
+
+  if (!String(form.managerName || "").trim()) {
+    form.managerName = idName || legalPerson;
+  }
+  if (!String(form.managerDocNo || "").trim()) {
+    form.managerDocNo = idNum;
+  }
+  if (!String(form.managerDocType || "").trim()) {
+    form.managerDocType = docType || (idNum ? "IDENTIFICATION_TYPE_IDCARD" : "");
+  }
+}
+
+onMounted(() => {
+  hydrateAdminFormFromBusinessDataCache();
+  nextTick(() => formRef.value?.clearValidate());
+});
+
+function mergeContactInfoIntoBusinessDataCache() {
+  const prev = localGet(BUSINESS_DATA_CACHE_KEY);
+  const base = prev && typeof prev === "object" && !Array.isArray(prev) ? { ...(prev as Record<string, unknown>) } : {};
+  const prevCi =
+    base.contact_info && typeof base.contact_info === "object" && !Array.isArray(base.contact_info)
+      ? { ...(base.contact_info as Record<string, unknown>) }
+      : {};
+
+  base.contact_info = {
+    ...prevCi,
+    contact_type: form.managerIdentity,
+    contact_name: String(form.managerName || "").trim(),
+    contact_id_doc_type: String(form.managerDocType || "").trim(),
+    contact_id_number: String(form.managerDocNo || "").trim(),
+    mobile_phone: String(form.mobile || "").trim(),
+    contact_email: String(form.email || "").trim()
+  };
+  localSet(BUSINESS_DATA_CACHE_KEY, base);
+}
+
+async function onSubmit() {
+  if (!formRef.value) return;
+  try {
+    await formRef.value.validate();
+  } catch {
+    ElMessage.warning("请完善必填信息");
+    return;
+  }
+
+  submitLoading.value = true;
+  try {
+    mergeContactInfoIntoBusinessDataCache();
+    const businessData = localGet(BUSINESS_DATA_CACHE_KEY);
+    if (!businessData || typeof businessData !== "object" || Array.isArray(businessData)) {
+      ElMessage.warning("未找到进件数据,请重新填写");
+      return;
+    }
+    const storeIdRaw = resolveApplymentStoreId();
+    if (storeIdRaw === null) {
+      ElMessage.warning("未获取到门店 storeId,请重新登录");
+      return;
+    }
+    const n = Number(storeIdRaw);
+    const storeId = Number.isNaN(n) ? storeIdRaw : n;
+    const payload = { ...(businessData as Record<string, unknown>) };
+    const res: unknown = await applyment(payload, storeId);
+    const r = res as Record<string, unknown> | undefined;
+    if (r?.code === 200 || r?.code === "200") {
+      const applymentId = pickApplymentIdFromApplymentResponse(res);
+      if (applymentId) {
+        try {
+          const detailRes: unknown = await getPaymentApplyment(applymentId);
+          const dr = detailRes as Record<string, unknown> | undefined;
+          const nested = dr?.data as Record<string, unknown> | undefined;
+          const dCode = dr?.code ?? nested?.code;
+          if (dCode === 200 || dCode === "200") {
+            const signUrl = pickSignUrlFromPaymentApplymentResponse(detailRes);
+            if (/^https?:\/\//i.test(signUrl)) {
+              signUrlText.value = signUrl;
+              signQrError.value = false;
+              signDialogVisible.value = true;
+            }
+          }
+        } catch (e) {
+          console.warn("[adminInfo] getPaymentApplyment", e);
+        }
+      }
+      ElMessage.success((r?.msg as string) || "提交成功");
+    } else {
+      ElMessage.warning((r?.msg as string) || "提交失败,请稍后重试");
+    }
+  } catch {
+    ElMessage.error("提交失败,请稍后重试");
+  } finally {
+    submitLoading.value = false;
+  }
+}
+</script>
+
+<style scoped lang="scss">
+$wechat-green: #07c160;
+.admin-info-page {
+  box-sizing: border-box;
+  min-height: 100%;
+  padding: 24px 32px 40px;
+  margin: 0 auto;
+  background: #ffffff;
+}
+.page-title {
+  margin: 0 0 24px;
+  font-size: 20px;
+  font-weight: 600;
+  color: #303133;
+}
+.form-block {
+  margin-bottom: 24px;
+}
+.section-head {
+  display: flex;
+  align-items: center;
+  margin: 0 0 12px;
+  font-size: 16px;
+  font-weight: 600;
+  color: #303133;
+}
+.section-bar {
+  display: inline-block;
+  flex-shrink: 0;
+  width: 4px;
+  height: 16px;
+  margin-right: 8px;
+  background: $wechat-green;
+  border-radius: 2px;
+}
+.section-intro {
+  margin: 0 0 20px;
+  font-size: 12px;
+  line-height: 1.65;
+  color: #909399;
+}
+.admin-form {
+  :deep(.el-form-item__label) {
+    font-weight: 500;
+    color: #606266;
+  }
+}
+.identity-radio {
+  :deep(.el-radio__input.is-checked .el-radio__inner) {
+    background: $wechat-green;
+    border-color: $wechat-green;
+  }
+  :deep(.el-radio__input.is-checked + .el-radio__label) {
+    color: #303133;
+  }
+}
+.tip-icon {
+  margin-left: 4px;
+  color: #c0c4cc;
+}
+.field-stack {
+  width: 100%;
+}
+.field-tip {
+  margin: 8px 0 0;
+  font-size: 12px;
+  line-height: 1.65;
+  color: #909399;
+}
+.footer-actions {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  padding-top: 24px;
+  margin-top: 16px;
+  border-top: 1px solid #ebeef5;
+}
+.footer-center {
+  display: flex;
+  flex: 1;
+  justify-content: center;
+}
+.btn-next {
+  min-width: 100px;
+  background: $wechat-green;
+  border-color: $wechat-green;
+  &:hover {
+    background: #06ad56;
+    border-color: #06ad56;
+  }
+}
+.sign-dialog {
+  padding: 0 4px 8px;
+}
+.sign-dialog__qr-wrap {
+  display: flex;
+  justify-content: center;
+  margin-bottom: 16px;
+}
+.sign-dialog__qr {
+  width: 240px;
+  height: 240px;
+  object-fit: contain;
+  background: #fafafa;
+}
+.sign-dialog__fail {
+  margin: 0 0 12px;
+  font-size: 13px;
+  line-height: 1.6;
+  color: #909399;
+}
+.sign-dialog__hint {
+  margin: 0 0 12px;
+  font-size: 14px;
+  color: #606266;
+  text-align: center;
+}
+.sign-dialog__url {
+  margin-bottom: 16px;
+}
+.sign-dialog__actions {
+  display: flex;
+  justify-content: center;
+}
+</style>

+ 4383 - 0
src/views/businessInfo/category.json

@@ -0,0 +1,4383 @@
+{
+    "data": {
+        "childrenNodes": [
+            {
+                "childrenNodes": [
+                    {
+                        "childrenNodes": [],
+                        "code": "B0150",
+                        "creator": "john.wy",
+                        "description": "适用于提供眼科医疗相关服务的场所申请",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1724913433000,
+                        "level": 2,
+                        "modifier": "zxl01535939",
+                        "name": "眼科医疗服务",
+                        "needSpecialQual": true,
+                        "parentCode": "A0009",
+                        "parentName": "医疗卫生",
+                        "sortNum": 11,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0151",
+                        "creator": "john.wy",
+                        "description": "适用于提供口腔医疗相关服务的场所申请",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1724896295000,
+                        "level": 2,
+                        "modifier": "zxl01535939",
+                        "name": "口腔医疗服务",
+                        "needSpecialQual": true,
+                        "parentCode": "A0009",
+                        "parentName": "医疗卫生",
+                        "sortNum": 12,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0140",
+                        "creator": "john.wy",
+                        "description": "适用于药品的销售、配送等服务。如药店、药品生产商、销售商等。",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1713922706000,
+                        "level": 2,
+                        "modifier": "zxl01535939",
+                        "name": "医药销售",
+                        "needSpecialQual": true,
+                        "parentCode": "A0009",
+                        "parentName": "医疗卫生",
+                        "sortNum": 1,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0149",
+                        "creator": "john.wy",
+                        "description": "适用于提供医疗美容相关服务的场所申请",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1724900615000,
+                        "level": 2,
+                        "modifier": "zxl01535939",
+                        "name": "医疗美容",
+                        "needSpecialQual": true,
+                        "parentCode": "A0009",
+                        "parentName": "医疗卫生",
+                        "sortNum": 10,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0152",
+                        "creator": "john.wy",
+                        "description": "适用于提供医学实验室及诊断中心的场所申请",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767822000,
+                        "gmtModified": 1609816623000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "医学实验室及诊断中心",
+                        "needSpecialQual": true,
+                        "parentCode": "A0009",
+                        "parentName": "医疗卫生",
+                        "sortNum": 13,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0141",
+                        "creator": "john.wy",
+                        "description": "适用于医疗器械的销售等服务。",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1609816623000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "医疗器械销售",
+                        "needSpecialQual": true,
+                        "parentCode": "A0009",
+                        "parentName": "医疗卫生",
+                        "sortNum": 2,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0153",
+                        "creator": "john.wy",
+                        "description": "适用于互联网医院主体/医疗服务平台提供在线看诊、疾病咨询等综合性线上医疗服务。",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1631672817000,
+                        "level": 2,
+                        "modifier": "size.lsz",
+                        "name": "线上医疗服务",
+                        "needSpecialQual": true,
+                        "parentCode": "A0009",
+                        "parentName": "医疗卫生",
+                        "sortNum": 14,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0142",
+                        "creator": "john.wy",
+                        "description": "适用于保健辅助治疗器材的销售等服务。",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1723192335000,
+                        "level": 2,
+                        "modifier": "zxl01535939",
+                        "name": "健康食品/设备",
+                        "needSpecialQual": true,
+                        "parentCode": "A0009",
+                        "parentName": "医疗卫生",
+                        "sortNum": 3,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0154",
+                        "creator": "john.wy",
+                        "description": "适用于养老、医疗护理等相关的服务。",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1602767922000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "护理机构服务",
+                        "needSpecialQual": false,
+                        "parentCode": "A0009",
+                        "parentName": "医疗卫生",
+                        "sortNum": 15,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0143",
+                        "creator": "john.wy",
+                        "description": "适用于主体为公立医院提供的就医、健康咨询/问诊、医疗保健信息等服务。",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1680162439000,
+                        "level": 2,
+                        "modifier": "swl01119956",
+                        "name": "公立医院",
+                        "needSpecialQual": true,
+                        "parentCode": "A0009",
+                        "parentName": "医疗卫生",
+                        "sortNum": 4,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0155",
+                        "creator": "john.wy",
+                        "description": "适用于健康体检预约、专业体检机构、健康咨询等服务。",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1622187068000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "体检/健康咨询",
+                        "needSpecialQual": true,
+                        "parentCode": "A0009",
+                        "parentName": "医疗卫生",
+                        "sortNum": 16,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0144",
+                        "creator": "john.wy",
+                        "description": "适用于主体为社区卫生服务中心提供的就医、健康咨询/问诊、医疗保健信息等服务。",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767822000,
+                        "gmtModified": 1716961342000,
+                        "level": 2,
+                        "modifier": "zxl01535939",
+                        "name": "社区卫生服务中心/乡镇卫生院",
+                        "needSpecialQual": true,
+                        "parentCode": "A0009",
+                        "parentName": "医疗卫生",
+                        "sortNum": 5,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0156",
+                        "creator": "john.wy",
+                        "description": "其他医疗保健服务",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1609816623000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "其他医疗保健服务",
+                        "needSpecialQual": true,
+                        "parentCode": "A0009",
+                        "parentName": "医疗卫生",
+                        "sortNum": 17,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0145",
+                        "creator": "john.wy",
+                        "description": "适用于各级卫生行政机构、疾病控制机构,卫生监督机构、妇幼保健机构、慢性病防治机构、社区卫生服务机构及公共卫生研究机构",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1716965619000,
+                        "level": 2,
+                        "modifier": "zxl01535939",
+                        "name": "专业公共卫生机构",
+                        "needSpecialQual": true,
+                        "parentCode": "A0009",
+                        "parentName": "医疗卫生",
+                        "sortNum": 6,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0146",
+                        "creator": "john.wy",
+                        "description": "适用于主体为民营医院提供的就医、健康咨询/问诊、医疗保健信息等服务。",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1609816623000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "民营医院",
+                        "needSpecialQual": true,
+                        "parentCode": "A0009",
+                        "parentName": "医疗卫生",
+                        "sortNum": 7,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0147",
+                        "creator": "john.wy",
+                        "description": "适用于私人开业的医生诊治病人的场所申请使用",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1713926965000,
+                        "level": 2,
+                        "modifier": "zxl01535939",
+                        "name": "诊所",
+                        "needSpecialQual": true,
+                        "parentCode": "A0009",
+                        "parentName": "医疗卫生",
+                        "sortNum": 8,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0148",
+                        "creator": "john.wy",
+                        "description": "适用于个体行医的医护人员申请",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1609816623000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "个体医生",
+                        "needSpecialQual": true,
+                        "parentCode": "A0009",
+                        "parentName": "医疗卫生",
+                        "sortNum": 9,
+                        "special": true,
+                        "status": "VALID"
+                    }
+                ],
+                "code": "A0009",
+                "creator": "john.wy",
+                "description": "医疗卫生",
+                "display": true,
+                "door": true,
+                "gmtCreate": 1602767921000,
+                "gmtModified": 1602767922000,
+                "level": 1,
+                "modifier": "john.wy",
+                "name": "医疗卫生",
+                "needSpecialQual": false,
+                "parentCode": "ROOT",
+                "parentName": "根节点",
+                "sortNum": 9,
+                "special": false,
+                "status": "VALID"
+            },
+            {
+                "childrenNodes": [
+                    {
+                        "childrenNodes": [],
+                        "code": "B0127",
+                        "creator": "john.wy",
+                        "description": "适用于国内三大运营商以及获得虚拟运营商牌照的电信公司申请",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1723448663000,
+                        "level": 2,
+                        "modifier": "zxl01535939",
+                        "name": "电信运营商",
+                        "needSpecialQual": true,
+                        "parentCode": "A0007",
+                        "parentName": "网络通讯",
+                        "sortNum": 20,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0128",
+                        "creator": "john.wy",
+                        "description": "适用于付费电视服务申请",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1609816623000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "付费电视",
+                        "needSpecialQual": true,
+                        "parentCode": "A0007",
+                        "parentName": "网络通讯",
+                        "sortNum": 21,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0129",
+                        "creator": "john.wy",
+                        "description": "适用于网络电话、传真服务申请",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767822000,
+                        "gmtModified": 1602767823000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "网络电话、传真服务",
+                        "needSpecialQual": false,
+                        "parentCode": "A0007",
+                        "parentName": "网络通讯",
+                        "sortNum": 22,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0120",
+                        "creator": "john.wy",
+                        "description": "适用于提供互联网基础平台服务(服务器托管、虚拟主机、邮件缓存、虚拟邮件等)以及各种增值服务(场地的租用服务、域名系统服务、负载均衡系统、数据库系统、数据备份服务等)。",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1602767922000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "互联网数据服务",
+                        "needSpecialQual": false,
+                        "parentCode": "A0007",
+                        "parentName": "网络通讯",
+                        "sortNum": 13,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0121",
+                        "creator": "john.wy",
+                        "description": "提供域名注册、网站建设等服务的公司申请",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1602767922000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "软件开发服务",
+                        "needSpecialQual": false,
+                        "parentCode": "A0007",
+                        "parentName": "网络通讯",
+                        "sortNum": 14,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0113",
+                        "creator": "john.wy",
+                        "description": "提供网站论坛、咨询信息等服务的公司",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1602767922000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "信息检索服务/网络论坛",
+                        "needSpecialQual": false,
+                        "parentCode": "A0007",
+                        "parentName": "网络通讯",
+                        "sortNum": 6,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0125",
+                        "creator": "john.wy",
+                        "description": "适用于提供其他在线应用或综合类服务的公司申请",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1602767922000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "其他在线应用或综合类服务",
+                        "needSpecialQual": false,
+                        "parentCode": "A0007",
+                        "parentName": "网络通讯",
+                        "sortNum": 18,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0126",
+                        "creator": "john.wy",
+                        "description": "适用于提供网络广告制作、网络视频制作、搜索引擎的广告位等服务的公司",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1602767922000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "网络推广/网络广告",
+                        "needSpecialQual": false,
+                        "parentCode": "A0007",
+                        "parentName": "网络通讯",
+                        "sortNum": 19,
+                        "special": false,
+                        "status": "VALID"
+                    }
+                ],
+                "code": "A0007",
+                "creator": "john.wy",
+                "description": "网络和通讯",
+                "display": true,
+                "door": true,
+                "gmtCreate": 1602767921000,
+                "gmtModified": 1612260356000,
+                "level": 1,
+                "modifier": "john.wy",
+                "name": "网络通讯",
+                "needSpecialQual": false,
+                "parentCode": "ROOT",
+                "parentName": "根节点",
+                "sortNum": 7,
+                "special": false,
+                "status": "VALID"
+            },
+            {
+                "childrenNodes": [
+                    {
+                        "childrenNodes": [],
+                        "code": "B0138",
+                        "creator": "john.wy",
+                        "description": "适用于少年宫及青少年发展中心等主体,提供教育相关服务。",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1663772383000,
+                        "level": 2,
+                        "modifier": "yan.zhouzy",
+                        "name": "少年宫及青少年发展中心",
+                        "needSpecialQual": true,
+                        "parentCode": "A0008",
+                        "parentName": "教育服务",
+                        "sortNum": 9,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0139",
+                        "creator": "john.wy",
+                        "description": "适用于提供教育相关服务。",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1665645259000,
+                        "level": 2,
+                        "modifier": "yan.zhouzy",
+                        "name": "其他教育/培训",
+                        "needSpecialQual": true,
+                        "parentCode": "A0008",
+                        "parentName": "教育服务",
+                        "sortNum": 10,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0130",
+                        "creator": "john.wy",
+                        "description": "适用于校园场景下的学前教育服务,如公立幼儿园等。",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1664163627000,
+                        "level": 2,
+                        "modifier": "yan.zhouzy",
+                        "name": "儿童保育服务(公立,含学前教育)",
+                        "needSpecialQual": true,
+                        "parentCode": "A0008",
+                        "parentName": "教育服务",
+                        "sortNum": 1,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0131",
+                        "creator": "john.wy",
+                        "description": "适用于校园场景下的学前教育服务,如民办幼儿园等。",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1664170806000,
+                        "level": 2,
+                        "modifier": "yan.zhouzy",
+                        "name": "儿童保育服务(民办,含学前教育)",
+                        "needSpecialQual": true,
+                        "parentCode": "A0008",
+                        "parentName": "教育服务",
+                        "sortNum": 2,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0132",
+                        "creator": "john.wy",
+                        "description": "适用于校园场景下的公立小学、初中、高中学历教育等服务。",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1663675003000,
+                        "level": 2,
+                        "modifier": "yan.zhouzy",
+                        "name": "中小学校(公立)",
+                        "needSpecialQual": true,
+                        "parentCode": "A0008",
+                        "parentName": "教育服务",
+                        "sortNum": 3,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0133",
+                        "creator": "john.wy",
+                        "description": "适用于校园场景下的民办小学、初中、高中学历教育等服务。",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1663928786000,
+                        "level": 2,
+                        "modifier": "yan.zhouzy",
+                        "name": "中小学校(民办)",
+                        "needSpecialQual": true,
+                        "parentCode": "A0008",
+                        "parentName": "教育服务",
+                        "sortNum": 4,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0134",
+                        "creator": "john.wy",
+                        "description": "适用于校园场景下的公立大学学历教育等服务",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1663901535000,
+                        "level": 2,
+                        "modifier": "yan.zhouzy",
+                        "name": "大学与学院(公立)",
+                        "needSpecialQual": true,
+                        "parentCode": "A0008",
+                        "parentName": "教育服务",
+                        "sortNum": 5,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0135",
+                        "creator": "john.wy",
+                        "description": "适用于校园场景下的民办大学学历教育等服务",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1663909973000,
+                        "level": 2,
+                        "modifier": "yan.zhouzy",
+                        "name": "大学与学院(民办)",
+                        "needSpecialQual": true,
+                        "parentCode": "A0008",
+                        "parentName": "教育服务",
+                        "sortNum": 6,
+                        "special": true,
+                        "status": "VALID"
+                    }
+                ],
+                "code": "A0008",
+                "creator": "john.wy",
+                "description": "教育",
+                "display": true,
+                "door": true,
+                "gmtCreate": 1602767822000,
+                "gmtModified": 1628663807000,
+                "level": 1,
+                "modifier": "size.lsz",
+                "name": "教育服务",
+                "needSpecialQual": false,
+                "parentCode": "ROOT",
+                "parentName": "根节点",
+                "sortNum": 8,
+                "special": false,
+                "status": "VALID"
+            },
+            {
+                "childrenNodes": [
+                    {
+                        "childrenNodes": [],
+                        "code": "B0180",
+                        "creator": "john.wy",
+                        "description": "适用于可开展保险业务、保险代理业务的公司",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1663134412000,
+                        "level": 2,
+                        "modifier": "yan.zhouzy",
+                        "name": "保险业务/保险代理",
+                        "needSpecialQual": true,
+                        "parentCode": "A0012",
+                        "parentName": "金融理财",
+                        "sortNum": 15,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0181",
+                        "creator": "john.wy",
+                        "description": "适用于可开展典当业务的公司",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1609816623000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "典当",
+                        "needSpecialQual": true,
+                        "parentCode": "A0012",
+                        "parentName": "金融理财",
+                        "sortNum": 16,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0170",
+                        "creator": "john.wy",
+                        "description": "适用于小额贷款公司",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1609816623000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "小贷公司",
+                        "needSpecialQual": true,
+                        "parentCode": "A0012",
+                        "parentName": "金融理财",
+                        "sortNum": 5,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0171",
+                        "creator": "john.wy",
+                        "description": "适用于与持牌的消费金融公司、小贷公司、银行等持牌机构的有业务合作,且合作协议内容需要体现平台用户的放款由对应合作机构发放的平台类公司",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1609816623000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "借贷消费平台",
+                        "needSpecialQual": true,
+                        "parentCode": "A0012",
+                        "parentName": "金融理财",
+                        "sortNum": 6,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0172",
+                        "creator": "john.wy",
+                        "description": "适用于可开展融资租赁业务的公司",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1609816623000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "融资租赁公司",
+                        "needSpecialQual": true,
+                        "parentCode": "A0012",
+                        "parentName": "金融理财",
+                        "sortNum": 7,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0173",
+                        "creator": "john.wy",
+                        "description": "适用于可开展金融租赁业务的公司",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1609816623000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "金融租赁公司",
+                        "needSpecialQual": true,
+                        "parentCode": "A0012",
+                        "parentName": "金融理财",
+                        "sortNum": 8,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0174",
+                        "creator": "john.wy",
+                        "description": "适用于可开展汽车金融业务的公司",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767822000,
+                        "gmtModified": 1609816623000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "汽车金融公司",
+                        "needSpecialQual": true,
+                        "parentCode": "A0012",
+                        "parentName": "金融理财",
+                        "sortNum": 9,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0175",
+                        "creator": "john.wy",
+                        "description": "适用于可开展消费金融业务的公司",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1609816623000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "消费金融公司",
+                        "needSpecialQual": true,
+                        "parentCode": "A0012",
+                        "parentName": "金融理财",
+                        "sortNum": 10,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0176",
+                        "creator": "john.wy",
+                        "description": "适用于可开展信托业务的公司",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1609816623000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "信托公司",
+                        "needSpecialQual": true,
+                        "parentCode": "A0012",
+                        "parentName": "金融理财",
+                        "sortNum": 11,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0177",
+                        "creator": "john.wy",
+                        "description": "适用于可开展支付业务的公司",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1724828448000,
+                        "level": 2,
+                        "modifier": "zxl01535939",
+                        "name": "支付机构",
+                        "needSpecialQual": true,
+                        "parentCode": "A0012",
+                        "parentName": "金融理财",
+                        "sortNum": 12,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0166",
+                        "creator": "john.wy",
+                        "description": "适用于可开展个人贷款业务、信用卡业务的机构",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1609816623000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "金融机构",
+                        "needSpecialQual": true,
+                        "parentCode": "A0012",
+                        "parentName": "金融理财",
+                        "sortNum": 1,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0178",
+                        "creator": "john.wy",
+                        "description": "适用于可开展融资担保业务的公司",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1609816623000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "融资担保公司",
+                        "needSpecialQual": true,
+                        "parentCode": "A0012",
+                        "parentName": "金融理财",
+                        "sortNum": 13,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0167",
+                        "creator": "john.wy",
+                        "description": "适用于可开展其他金融服务业务的机构",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767822000,
+                        "gmtModified": 1609816623000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "金融机构-其他服务",
+                        "needSpecialQual": true,
+                        "parentCode": "A0012",
+                        "parentName": "金融理财",
+                        "sortNum": 2,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0179",
+                        "creator": "john.wy",
+                        "description": "适用于其他金融服务的公司",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1602767922000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "其他金融服务",
+                        "needSpecialQual": false,
+                        "parentCode": "A0012",
+                        "parentName": "金融理财",
+                        "sortNum": 14,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0168",
+                        "creator": "john.wy",
+                        "description": "适用于经营本、外币业务的机构或个人",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1609816623000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "外币汇兑",
+                        "needSpecialQual": true,
+                        "parentCode": "A0012",
+                        "parentName": "金融理财",
+                        "sortNum": 3,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0169",
+                        "creator": "john.wy",
+                        "description": "适用于拥有证监会关于同意开展证券经营业务的批复、证监会及其派出机构颁布的基金类业务相关资格证书的提供股票基金服务的机构",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1609816623000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "股票基金服务",
+                        "needSpecialQual": true,
+                        "parentCode": "A0012",
+                        "parentName": "金融理财",
+                        "sortNum": 4,
+                        "special": true,
+                        "status": "VALID"
+                    }
+                ],
+                "code": "A0012",
+                "creator": "john.wy",
+                "description": "金融",
+                "display": true,
+                "door": true,
+                "gmtCreate": 1602767921000,
+                "gmtModified": 1612260432000,
+                "level": 1,
+                "modifier": "john.wy",
+                "name": "金融理财",
+                "needSpecialQual": false,
+                "parentCode": "ROOT",
+                "parentName": "根节点",
+                "sortNum": 12,
+                "special": false,
+                "status": "VALID"
+            },
+            {
+                "childrenNodes": [
+                    {
+                        "childrenNodes": [],
+                        "code": "B0006",
+                        "creator": "john.wy",
+                        "description": "适用于正式饭菜以外的熟食或点心铺出售的熟食或饭馆中的经济膳食的商家申请",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1693275211000,
+                        "level": 2,
+                        "modifier": "zhize.zy",
+                        "name": "小吃/熟食",
+                        "needSpecialQual": false,
+                        "parentCode": "A0001",
+                        "parentName": "餐饮",
+                        "sortNum": 6,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0117",
+                        "creator": "john.wy",
+                        "description": "提供订餐服务的信息服务平台。如平台参与餐饮的加工服务,建议选择“餐饮”",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1612260112000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "订餐服务平台",
+                        "needSpecialQual": false,
+                        "parentCode": "A0001",
+                        "parentName": "餐饮",
+                        "sortNum": 10,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0007",
+                        "creator": "john.wy",
+                        "description": "适用于校园食堂申请",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1661837595000,
+                        "level": 2,
+                        "modifier": "yan.zhouzy",
+                        "name": "校园团餐",
+                        "needSpecialQual": true,
+                        "parentCode": "A0001",
+                        "parentName": "餐饮",
+                        "sortNum": 7,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0008",
+                        "creator": "john.wy",
+                        "description": "适用于以一定的服务标准和模式提供定量的餐饮产品和与之配套的现场服务门店",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1657522537000,
+                        "level": 2,
+                        "modifier": "mingyang.gmy",
+                        "name": "综合团餐",
+                        "needSpecialQual": true,
+                        "parentCode": "A0001",
+                        "parentName": "餐饮",
+                        "sortNum": 8,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0009",
+                        "creator": "john.wy",
+                        "description": "适用于奶茶/甜品店铺申请",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767822000,
+                        "gmtModified": 1602767823000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "饮品/甜品",
+                        "needSpecialQual": false,
+                        "parentCode": "A0001",
+                        "parentName": "餐饮",
+                        "sortNum": 9,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0010",
+                        "creator": "john.wy",
+                        "description": "适用于拥有烘焙糕点生产场所的商户",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1602767922000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "烘焙糕点",
+                        "needSpecialQual": false,
+                        "parentCode": "A0001",
+                        "parentName": "餐饮",
+                        "sortNum": 10,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0011",
+                        "creator": "john.wy",
+                        "description": "适用于多种类酒调制,现场消费的商户",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1602767922000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "酒吧/清吧",
+                        "needSpecialQual": false,
+                        "parentCode": "A0001",
+                        "parentName": "餐饮",
+                        "sortNum": 11,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0012",
+                        "creator": "john.wy",
+                        "description": "适用于多种类咖啡、茶水现场消费的商户",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1602767922000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "咖啡馆/茶馆",
+                        "needSpecialQual": false,
+                        "parentCode": "A0001",
+                        "parentName": "餐饮",
+                        "sortNum": 12,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0001",
+                        "creator": "john.wy",
+                        "description": "适用于经营场所经营多品种的中式餐品,出餐或用餐时间均较长的商家申请",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1602767922000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "中式正餐",
+                        "needSpecialQual": false,
+                        "parentCode": "A0001",
+                        "parentName": "餐饮",
+                        "sortNum": 1,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0199",
+                        "creator": "john.wy",
+                        "description": "适用于经营火锅的商家申请",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1609322097000,
+                        "gmtModified": 1622187153000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "火锅",
+                        "needSpecialQual": false,
+                        "parentCode": "A0001",
+                        "parentName": "餐饮",
+                        "sortNum": 1,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0002",
+                        "creator": "john.wy",
+                        "description": "适用于经营场所经营多品种的西式餐品,出餐或用餐时间均较长的商家申请",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767822000,
+                        "gmtModified": 1622186907000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "西式正餐",
+                        "needSpecialQual": false,
+                        "parentCode": "A0001",
+                        "parentName": "餐饮",
+                        "sortNum": 2,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0200",
+                        "creator": "john.wy",
+                        "description": "适用于餐食宴会供应商申请使用",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1609322153000,
+                        "gmtModified": 1609322154000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "宴会提供商",
+                        "needSpecialQual": false,
+                        "parentCode": "A0001",
+                        "parentName": "餐饮",
+                        "sortNum": 13,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0003",
+                        "creator": "john.wy",
+                        "description": "适用于经营场所经营日式、韩式、东南亚菜的商家申请",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1622186903000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "日韩/东南亚菜",
+                        "needSpecialQual": false,
+                        "parentCode": "A0001",
+                        "parentName": "餐饮",
+                        "sortNum": 3,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0004",
+                        "creator": "john.wy",
+                        "description": "适用于经营场所经营中式的仅做食材简单的加工处理即可出餐,面条类、盖饭、面点类的商家申请",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1602767922000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "中式快餐",
+                        "needSpecialQual": false,
+                        "parentCode": "A0001",
+                        "parentName": "餐饮",
+                        "sortNum": 4,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0005",
+                        "creator": "john.wy",
+                        "description": "适用于经营场所经营西式的仅做食材简单的加工处理即可出餐的商家申请",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1622186898000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "西式快餐",
+                        "needSpecialQual": false,
+                        "parentCode": "A0001",
+                        "parentName": "餐饮",
+                        "sortNum": 5,
+                        "special": false,
+                        "status": "VALID"
+                    }
+                ],
+                "code": "A0001",
+                "creator": "john.wy",
+                "description": "餐饮",
+                "display": true,
+                "door": true,
+                "gmtCreate": 1602767822000,
+                "gmtModified": 1602767823000,
+                "level": 1,
+                "modifier": "john.wy",
+                "name": "餐饮",
+                "needSpecialQual": false,
+                "parentCode": "ROOT",
+                "parentName": "根节点",
+                "sortNum": 1,
+                "special": false,
+                "status": "VALID"
+            },
+            {
+                "childrenNodes": [
+                    {
+                        "childrenNodes": [],
+                        "code": "B0190",
+                        "creator": "john.wy",
+                        "description": "适用于***法院",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1673577670000,
+                        "level": 2,
+                        "modifier": "zxl01535939",
+                        "name": "法庭费用",
+                        "needSpecialQual": true,
+                        "parentCode": "A0013",
+                        "parentName": "公共管理和社会组织",
+                        "sortNum": 9,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0191",
+                        "creator": "john.wy",
+                        "description": "适用于***公安局(厅)",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1673938030000,
+                        "level": 2,
+                        "modifier": "zxl01535939",
+                        "name": "保释金",
+                        "needSpecialQual": true,
+                        "parentCode": "A0013",
+                        "parentName": "公共管理和社会组织",
+                        "sortNum": 10,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0192",
+                        "creator": "john.wy",
+                        "description": "适用于***税务局",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1673510129000,
+                        "level": 2,
+                        "modifier": "zxl01535939",
+                        "name": "税务",
+                        "needSpecialQual": true,
+                        "parentCode": "A0013",
+                        "parentName": "公共管理和社会组织",
+                        "sortNum": 11,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0182",
+                        "creator": "john.wy",
+                        "description": "适用于***财政局(厅)/公安局(厅)/行政执法队/警察总队/人民政府(办公厅、室)/***人力资源和社会保障****中心(局、办公室)/***公积金管理中心/***医保局/**医疗保障局",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1674012064000,
+                        "level": 2,
+                        "modifier": "zxl01535939",
+                        "name": "政府机构",
+                        "needSpecialQual": true,
+                        "parentCode": "A0013",
+                        "parentName": "公共管理和社会组织",
+                        "sortNum": 1,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0193",
+                        "creator": "john.wy",
+                        "description": "适用于慈善和社会公益机构",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767822000,
+                        "gmtModified": 1662607673000,
+                        "level": 2,
+                        "modifier": "sisi.fss",
+                        "name": "慈善和社会公益服务",
+                        "needSpecialQual": true,
+                        "parentCode": "A0013",
+                        "parentName": "公共管理和社会组织",
+                        "sortNum": 12,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0183",
+                        "creator": "john.wy",
+                        "description": "适用于***财政局(厅)",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1673857964000,
+                        "level": 2,
+                        "modifier": "zxl01535939",
+                        "name": "行政费用和罚款(非税)",
+                        "needSpecialQual": true,
+                        "parentCode": "A0013",
+                        "parentName": "公共管理和社会组织",
+                        "sortNum": 2,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0194",
+                        "creator": "john.wy",
+                        "description": "适用于使领馆申请",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1680154051000,
+                        "level": 2,
+                        "modifier": "yumai.cw",
+                        "name": "使领馆",
+                        "needSpecialQual": false,
+                        "parentCode": "A0013",
+                        "parentName": "公共管理和社会组织",
+                        "sortNum": 13,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0184",
+                        "creator": "john.wy",
+                        "description": "适用于***公积金管理中心",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1673849973000,
+                        "level": 2,
+                        "modifier": "zxl01535939",
+                        "name": "公积金",
+                        "needSpecialQual": true,
+                        "parentCode": "A0013",
+                        "parentName": "公共管理和社会组织",
+                        "sortNum": 3,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0195",
+                        "creator": "john.wy",
+                        "description": "适用于各行业协会或专业社团申请",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1609816623000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "行业协会和专业社团",
+                        "needSpecialQual": true,
+                        "parentCode": "A0013",
+                        "parentName": "公共管理和社会组织",
+                        "sortNum": 14,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0226",
+                        "creator": "size.lsz",
+                        "description": "适用于“一网通办”服务机构使用",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1635218130000,
+                        "gmtModified": 1673338973000,
+                        "level": 2,
+                        "modifier": "zxl01535939",
+                        "name": "一网通办",
+                        "needSpecialQual": true,
+                        "parentCode": "A0013",
+                        "parentName": "公共管理和社会组织",
+                        "sortNum": 20,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0196",
+                        "creator": "john.wy",
+                        "description": "适用于汽车协会申请",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1602767922000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "汽车协会",
+                        "needSpecialQual": false,
+                        "parentCode": "A0013",
+                        "parentName": "公共管理和社会组织",
+                        "sortNum": 15,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0185",
+                        "creator": "john.wy",
+                        "description": "适用于***公安局(厅)/行政执法队/警察总队/**交通管理局",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1673921878000,
+                        "level": 2,
+                        "modifier": "zxl01535939",
+                        "name": "公安交管",
+                        "needSpecialQual": true,
+                        "parentCode": "A0013",
+                        "parentName": "公共管理和社会组织",
+                        "sortNum": 4,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0197",
+                        "creator": "john.wy",
+                        "description": "适用于宗教组织申请",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1609816623000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "宗教组织",
+                        "needSpecialQual": true,
+                        "parentCode": "A0013",
+                        "parentName": "公共管理和社会组织",
+                        "sortNum": 16,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0186",
+                        "creator": "john.wy",
+                        "description": "适用于***医保局/**医疗保障局",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767822000,
+                        "gmtModified": 1721281709000,
+                        "level": 2,
+                        "modifier": "zxl01535939",
+                        "name": "医保",
+                        "needSpecialQual": true,
+                        "parentCode": "A0013",
+                        "parentName": "公共管理和社会组织",
+                        "sortNum": 5,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0198",
+                        "creator": "john.wy",
+                        "description": "适用于其他会员组织申请",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1602767922000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "其他会员组织",
+                        "needSpecialQual": false,
+                        "parentCode": "A0013",
+                        "parentName": "公共管理和社会组织",
+                        "sortNum": 17,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0187",
+                        "creator": "john.wy",
+                        "description": "适用于***人力资源和社会保障****中心/局/办公室",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1673493388000,
+                        "level": 2,
+                        "modifier": "zxl01535939",
+                        "name": "社会保障服务",
+                        "needSpecialQual": true,
+                        "parentCode": "A0013",
+                        "parentName": "公共管理和社会组织",
+                        "sortNum": 6,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0188",
+                        "creator": "john.wy",
+                        "description": "适用于政府采购相关服务",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1680147626000,
+                        "level": 2,
+                        "modifier": "yumai.cw",
+                        "name": "政府采购",
+                        "needSpecialQual": false,
+                        "parentCode": "A0013",
+                        "parentName": "公共管理和社会组织",
+                        "sortNum": 7,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0222",
+                        "creator": "john.wy",
+                        "description": "适用于***文化局、***体育局申请",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1609328692000,
+                        "gmtModified": 1622187075000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "文体机构",
+                        "needSpecialQual": false,
+                        "parentCode": "A0013",
+                        "parentName": "公共管理和社会组织",
+                        "sortNum": 7,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0189",
+                        "creator": "john.wy",
+                        "description": "适用于政府贷款相关服务",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1622187135000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "政府贷款",
+                        "needSpecialQual": false,
+                        "parentCode": "A0013",
+                        "parentName": "公共管理和社会组织",
+                        "sortNum": 8,
+                        "special": false,
+                        "status": "VALID"
+                    }
+                ],
+                "code": "A0013",
+                "creator": "john.wy",
+                "description": "公共管理和社会组织",
+                "display": true,
+                "door": true,
+                "gmtCreate": 1602767921000,
+                "gmtModified": 1602767922000,
+                "level": 1,
+                "modifier": "john.wy",
+                "name": "公共管理和社会组织",
+                "needSpecialQual": false,
+                "parentCode": "ROOT",
+                "parentName": "根节点",
+                "sortNum": 13,
+                "special": false,
+                "status": "VALID"
+            },
+            {
+                "childrenNodes": [
+                    {
+                        "childrenNodes": [],
+                        "code": "B0040",
+                        "creator": "john.wy",
+                        "description": "适用于主售危险化工产品的商户申请",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1609816623000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "危险化工产品",
+                        "needSpecialQual": true,
+                        "parentCode": "A0002",
+                        "parentName": "零售批发",
+                        "sortNum": 28,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0041",
+                        "creator": "john.wy",
+                        "description": "适用于主售石油及石油产品的商户申请",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1622186878000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "石油及石油产品",
+                        "needSpecialQual": true,
+                        "parentCode": "A0002",
+                        "parentName": "零售批发",
+                        "sortNum": 29,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0039",
+                        "creator": "john.wy",
+                        "description": "适用于主售烟花爆竹的商户申请",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767822000,
+                        "gmtModified": 1609816623000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "烟花爆竹",
+                        "needSpecialQual": true,
+                        "parentCode": "A0002",
+                        "parentName": "零售批发",
+                        "sortNum": 27,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0017",
+                        "creator": "john.wy",
+                        "description": "适用于集中收银台收银的购物商场",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767822000,
+                        "gmtModified": 1602767823000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "百货商场",
+                        "needSpecialQual": false,
+                        "parentCode": "A0002",
+                        "parentName": "零售批发",
+                        "sortNum": 5,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0018",
+                        "creator": "john.wy",
+                        "description": "适用于商家独立分散收银的购物商场",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1602767922000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "购物中心",
+                        "needSpecialQual": false,
+                        "parentCode": "A0002",
+                        "parentName": "零售批发",
+                        "sortNum": 6,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0216",
+                        "creator": "john.wy",
+                        "description": "适用于家居、家具、家纺类商户申请",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1609322390000,
+                        "gmtModified": 1609322388000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "家居家纺",
+                        "needSpecialQual": false,
+                        "parentCode": "A0002",
+                        "parentName": "零售批发",
+                        "sortNum": 24,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0118",
+                        "creator": "john.wy",
+                        "description": "提供团购服务信息的平台,平台不参与生产销售。如涉及加工,建议选择餐饮类目",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1622187036000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "社区团购服务平台",
+                        "needSpecialQual": false,
+                        "parentCode": "A0002",
+                        "parentName": "零售批发",
+                        "sortNum": 11,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0019",
+                        "creator": "john.wy",
+                        "description": "适用于品牌折扣店集中的购物商场",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1622186887000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "奥特莱斯",
+                        "needSpecialQual": false,
+                        "parentCode": "A0002",
+                        "parentName": "零售批发",
+                        "sortNum": 7,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0031",
+                        "creator": "john.wy",
+                        "description": "适用于主售图书、文具、音乐影像制品、工艺美术制品、乐器的商户申请",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1602767922000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "图文音像/工美乐器",
+                        "needSpecialQual": false,
+                        "parentCode": "A0002",
+                        "parentName": "零售批发",
+                        "sortNum": 19,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0032",
+                        "creator": "john.wy",
+                        "description": "适用于主售母婴用品、儿童玩具的商户申请",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767822000,
+                        "gmtModified": 1609816623000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "母婴用品/儿童玩具",
+                        "needSpecialQual": true,
+                        "parentCode": "A0002",
+                        "parentName": "零售批发",
+                        "sortNum": 20,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0033",
+                        "creator": "john.wy",
+                        "description": "适用于主售宠物本体、宠物日用品的商户申请",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1602767922000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "宠物/宠物用品",
+                        "needSpecialQual": false,
+                        "parentCode": "A0002",
+                        "parentName": "零售批发",
+                        "sortNum": 21,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0034",
+                        "creator": "john.wy",
+                        "description": "适用于主售户外装备、运动器材的商户申请",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1602767922000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "户外运动器材",
+                        "needSpecialQual": false,
+                        "parentCode": "A0002",
+                        "parentName": "零售批发",
+                        "sortNum": 22,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0232",
+                        "creator": "pxy02075401",
+                        "description": "适用于B2B电商市场,包括企业采购批发、供应链金融及综合生活消费场景。",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1739931917000,
+                        "gmtModified": 1739931917000,
+                        "level": 2,
+                        "modifier": "pxy02075401",
+                        "name": "商品批发/企业采购/供应链服务",
+                        "needSpecialQual": false,
+                        "parentCode": "A0002",
+                        "parentName": "零售批发",
+                        "sortNum": 40,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0035",
+                        "creator": "john.wy",
+                        "description": "适用于主售五金建材的商户申请",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1602767922000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "五金建材",
+                        "needSpecialQual": false,
+                        "parentCode": "A0002",
+                        "parentName": "零售批发",
+                        "sortNum": 23,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0013",
+                        "creator": "john.wy",
+                        "description": "适用于个人商户的小型零售店",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1612260445000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "杂货店",
+                        "needSpecialQual": false,
+                        "parentCode": "A0002",
+                        "parentName": "零售批发",
+                        "sortNum": 1,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0036",
+                        "creator": "john.wy",
+                        "description": "适用于主售鲜花绿植的商户申请",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1602767922000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "鲜花/绿植",
+                        "needSpecialQual": false,
+                        "parentCode": "A0002",
+                        "parentName": "零售批发",
+                        "sortNum": 24,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0014",
+                        "creator": "john.wy",
+                        "description": "适用于标准装修、自选式购物的小型零售店",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1622186891000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "连锁便利店",
+                        "needSpecialQual": false,
+                        "parentCode": "A0002",
+                        "parentName": "零售批发",
+                        "sortNum": 2,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0037",
+                        "creator": "john.wy",
+                        "description": "适用于主售文物、文物复制品的商户申请",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1609816623000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "文物经营/文物复制品",
+                        "needSpecialQual": true,
+                        "parentCode": "A0002",
+                        "parentName": "零售批发",
+                        "sortNum": 25,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0114",
+                        "creator": "john.wy",
+                        "description": "适用于综合类网上商城",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767822000,
+                        "gmtModified": 1612260128000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "互联网综合电商平台",
+                        "needSpecialQual": false,
+                        "parentCode": "A0002",
+                        "parentName": "零售批发",
+                        "sortNum": 7,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0015",
+                        "creator": "john.wy",
+                        "description": "适用于线下实体,千平、交易量大的超市",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1629254004000,
+                        "level": 2,
+                        "modifier": "size.lsz",
+                        "name": "超市",
+                        "needSpecialQual": false,
+                        "parentCode": "A0002",
+                        "parentName": "零售批发",
+                        "sortNum": 3,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0038",
+                        "creator": "john.wy",
+                        "description": "适用于主售计生类用品的商户申请",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1602767922000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "计生用品",
+                        "needSpecialQual": false,
+                        "parentCode": "A0002",
+                        "parentName": "零售批发",
+                        "sortNum": 26,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0115",
+                        "creator": "john.wy",
+                        "description": "适用于垂直类网上商城",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1622187010000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "互联网垂直电商平台",
+                        "needSpecialQual": false,
+                        "parentCode": "A0002",
+                        "parentName": "零售批发",
+                        "sortNum": 8,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0016",
+                        "creator": "john.wy",
+                        "description": "适用于以超市为主体辐射多个小商家的综合卖场",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1602767922000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "大卖场",
+                        "needSpecialQual": false,
+                        "parentCode": "A0002",
+                        "parentName": "零售批发",
+                        "sortNum": 4,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0030",
+                        "creator": "john.wy",
+                        "description": "适用于主售数码3C、电脑、家用电器的商户申请",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1602767922000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "3C数码/家用电器",
+                        "needSpecialQual": false,
+                        "parentCode": "A0002",
+                        "parentName": "零售批发",
+                        "sortNum": 18,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0028",
+                        "creator": "john.wy",
+                        "description": "适用于主售黄金首饰、珠宝首饰、钟表、各类时尚饰品的商户申请",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1602767922000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "黄金珠宝/钟表饰品",
+                        "needSpecialQual": false,
+                        "parentCode": "A0002",
+                        "parentName": "零售批发",
+                        "sortNum": 16,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0029",
+                        "creator": "john.wy",
+                        "description": "适用于主售近视眼镜、隐形眼镜、太阳眼镜及其他眼镜的商户申请",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1602767922000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "眼镜店",
+                        "needSpecialQual": false,
+                        "parentCode": "A0002",
+                        "parentName": "零售批发",
+                        "sortNum": 17,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0020",
+                        "creator": "john.wy",
+                        "description": "适用于各地特殊的商业街,含美食、购物、休闲娱乐等服务",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1622186882000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "商业街",
+                        "needSpecialQual": false,
+                        "parentCode": "A0002",
+                        "parentName": "零售批发",
+                        "sortNum": 8,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0042",
+                        "creator": "john.wy",
+                        "description": "适用于主售工业制成品的商户申请",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1602767922000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "工业产品",
+                        "needSpecialQual": false,
+                        "parentCode": "A0002",
+                        "parentName": "零售批发",
+                        "sortNum": 30,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0021",
+                        "creator": "john.wy",
+                        "description": "适用水果的售卖场所",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1602767922000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "水果店",
+                        "needSpecialQual": false,
+                        "parentCode": "A0002",
+                        "parentName": "零售批发",
+                        "sortNum": 9,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0043",
+                        "creator": "john.wy",
+                        "description": "其他专业零售店",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1602767922000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "其他专业零售店",
+                        "needSpecialQual": false,
+                        "parentCode": "A0002",
+                        "parentName": "零售批发",
+                        "sortNum": 31,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0022",
+                        "creator": "john.wy",
+                        "description": "适用于主售茶叶的商户申请",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1602767922000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "茶叶",
+                        "needSpecialQual": false,
+                        "parentCode": "A0002",
+                        "parentName": "零售批发",
+                        "sortNum": 10,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0023",
+                        "creator": "john.wy",
+                        "description": "适用于主售酒类的商户申请",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1653548586000,
+                        "level": 2,
+                        "modifier": "size.lsz",
+                        "name": "酒类",
+                        "needSpecialQual": true,
+                        "parentCode": "A0002",
+                        "parentName": "零售批发",
+                        "sortNum": 11,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0024",
+                        "creator": "john.wy",
+                        "description": "适用于主售烟草制品/雪茄的商户申请",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767822000,
+                        "gmtModified": 1609816623000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "烟草/雪茄",
+                        "needSpecialQual": true,
+                        "parentCode": "A0002",
+                        "parentName": "零售批发",
+                        "sortNum": 12,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0025",
+                        "creator": "john.wy",
+                        "description": "适用于主售营养保健类的商户申请",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1602767922000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "营养品/保健品",
+                        "needSpecialQual": false,
+                        "parentCode": "A0002",
+                        "parentName": "零售批发",
+                        "sortNum": 13,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0201",
+                        "creator": "john.wy",
+                        "description": "适用于零食、食品经营场所申请",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1609322234000,
+                        "gmtModified": 1609322235000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "食品零售",
+                        "needSpecialQual": false,
+                        "parentCode": "A0002",
+                        "parentName": "零售批发",
+                        "sortNum": 11,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0026",
+                        "creator": "john.wy",
+                        "description": "适用于主售服饰类、鞋类、箱包类的商户申请",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1602767922000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "服饰鞋包",
+                        "needSpecialQual": false,
+                        "parentCode": "A0002",
+                        "parentName": "零售批发",
+                        "sortNum": 14,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0202",
+                        "creator": "john.wy",
+                        "description": "适用于蔬菜、肉、蛋、海鲜水产销售经营场所申请",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1609322316000,
+                        "gmtModified": 1609322316000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "蔬菜/肉蛋/水产",
+                        "needSpecialQual": false,
+                        "parentCode": "A0002",
+                        "parentName": "零售批发",
+                        "sortNum": 11,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0027",
+                        "creator": "john.wy",
+                        "description": "适用于主售化妆品、护理品的商户申请",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1602767922000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "美妆个护",
+                        "needSpecialQual": false,
+                        "parentCode": "A0002",
+                        "parentName": "零售批发",
+                        "sortNum": 15,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0203",
+                        "creator": "john.wy",
+                        "description": "适用于主售办公用品的商户申请",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1609322345000,
+                        "gmtModified": 1609322346000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "办公用品",
+                        "needSpecialQual": false,
+                        "parentCode": "A0002",
+                        "parentName": "零售批发",
+                        "sortNum": 20,
+                        "special": false,
+                        "status": "VALID"
+                    }
+                ],
+                "code": "A0002",
+                "creator": "john.wy",
+                "description": "零售和批发",
+                "display": true,
+                "door": true,
+                "gmtCreate": 1602767921000,
+                "gmtModified": 1612260314000,
+                "level": 1,
+                "modifier": "john.wy",
+                "name": "零售批发",
+                "needSpecialQual": false,
+                "parentCode": "ROOT",
+                "parentName": "根节点",
+                "sortNum": 2,
+                "special": false,
+                "status": "VALID"
+            },
+            {
+                "childrenNodes": [
+                    {
+                        "childrenNodes": [],
+                        "code": "B0119",
+                        "creator": "john.wy",
+                        "description": "提供旅游信息服务的平台",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1612260295000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "旅游服务平台(OTA)",
+                        "needSpecialQual": false,
+                        "parentCode": "A0010",
+                        "parentName": "酒旅景区",
+                        "sortNum": 12,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0219",
+                        "creator": "john.wy",
+                        "description": "适用于风景区系统开发维护服务商申请",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1609328459000,
+                        "gmtModified": 1622187166000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "风景区系统商",
+                        "needSpecialQual": false,
+                        "parentCode": "A0010",
+                        "parentName": "酒旅景区",
+                        "sortNum": 5,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0160",
+                        "creator": "john.wy",
+                        "description": "适用于旅游相关服务直销的公司申请",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1609816623000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "旅游相关服务直销",
+                        "needSpecialQual": true,
+                        "parentCode": "A0010",
+                        "parentName": "酒旅景区",
+                        "sortNum": 4,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0220",
+                        "creator": "john.wy",
+                        "description": "适用于景区内游览观光车经营主体公司申请",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1609328489000,
+                        "gmtModified": 1622187172000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "观光车",
+                        "needSpecialQual": false,
+                        "parentCode": "A0010",
+                        "parentName": "酒旅景区",
+                        "sortNum": 6,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0221",
+                        "creator": "john.wy",
+                        "description": "适用于景区内游船码头服务主体公司申请",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1609328489000,
+                        "gmtModified": 1609328519000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "游船码头",
+                        "needSpecialQual": false,
+                        "parentCode": "A0010",
+                        "parentName": "酒旅景区",
+                        "sortNum": 7,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0157",
+                        "creator": "john.wy",
+                        "description": "适用于提供酒店、旅馆、民宿等住宿场景服务。",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1602767922000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "酒店/旅馆/民宿",
+                        "needSpecialQual": false,
+                        "parentCode": "A0010",
+                        "parentName": "酒旅景区",
+                        "sortNum": 1,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0158",
+                        "creator": "john.wy",
+                        "description": "适用于景区管理公司申请",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1663746196000,
+                        "level": 2,
+                        "modifier": "yan.zhouzy",
+                        "name": "景区",
+                        "needSpecialQual": true,
+                        "parentCode": "A0010",
+                        "parentName": "酒旅景区",
+                        "sortNum": 2,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0159",
+                        "creator": "john.wy",
+                        "description": "适用于旅行社、旅游咨询等公司的申请",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767822000,
+                        "gmtModified": 1609816623000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "旅行社和旅游服务",
+                        "needSpecialQual": true,
+                        "parentCode": "A0010",
+                        "parentName": "酒旅景区",
+                        "sortNum": 3,
+                        "special": true,
+                        "status": "VALID"
+                    }
+                ],
+                "code": "A0010",
+                "creator": "john.wy",
+                "description": "旅游",
+                "display": true,
+                "door": true,
+                "gmtCreate": 1602767921000,
+                "gmtModified": 1612260391000,
+                "level": 1,
+                "modifier": "john.wy",
+                "name": "酒旅景区",
+                "needSpecialQual": false,
+                "parentCode": "ROOT",
+                "parentName": "根节点",
+                "sortNum": 10,
+                "special": false,
+                "status": "VALID"
+            },
+            {
+                "childrenNodes": [
+                    {
+                        "childrenNodes": [],
+                        "code": "B0204",
+                        "creator": "john.wy",
+                        "description": "适用于电力缴费管理公司申请",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1609816623000,
+                        "gmtModified": 1609816623000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "公共事业-电力缴费",
+                        "needSpecialQual": true,
+                        "parentCode": "A0011",
+                        "parentName": "生活缴费",
+                        "sortNum": 2,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0206",
+                        "creator": "john.wy",
+                        "description": "适用于煤气缴费管理公司申请",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1609328618000,
+                        "gmtModified": 1636359338000,
+                        "level": 2,
+                        "modifier": "size.lsz",
+                        "name": "公共事业-煤气缴费",
+                        "needSpecialQual": true,
+                        "parentCode": "A0011",
+                        "parentName": "生活缴费",
+                        "sortNum": 4,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0207",
+                        "creator": "john.wy",
+                        "description": "适用于清洁服务缴费公司申请",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1609328641000,
+                        "gmtModified": 1609328655000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "公共事业-清洁服务缴费",
+                        "needSpecialQual": false,
+                        "parentCode": "A0011",
+                        "parentName": "生活缴费",
+                        "sortNum": 6,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0161",
+                        "creator": "john.wy",
+                        "description": "适用于自来水公司、电力公司申请",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1609816623000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "公共事业(电、气、水)",
+                        "needSpecialQual": true,
+                        "parentCode": "A0011",
+                        "parentName": "生活缴费",
+                        "sortNum": 1,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0162",
+                        "creator": "john.wy",
+                        "description": "适用于有线电视缴费代理公司申请",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1622187081000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "公共事业-有线电视缴费",
+                        "needSpecialQual": true,
+                        "parentCode": "A0011",
+                        "parentName": "生活缴费",
+                        "sortNum": 2,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0163",
+                        "creator": "john.wy",
+                        "description": "其他生活缴费类服务",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1602767922000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "公共事业-其他缴费",
+                        "needSpecialQual": false,
+                        "parentCode": "A0011",
+                        "parentName": "生活缴费",
+                        "sortNum": 3,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0164",
+                        "creator": "john.wy",
+                        "description": "移动、联通、电信公司授权的第三方经营话费充值、流量充值等业务的公司",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1602767922000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "话费充值与缴费",
+                        "needSpecialQual": false,
+                        "parentCode": "A0011",
+                        "parentName": "生活缴费",
+                        "sortNum": 4,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0211",
+                        "creator": "john.wy",
+                        "description": "适用于自来水缴费管理公司申请",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1609328576000,
+                        "gmtModified": 1635929466000,
+                        "level": 2,
+                        "modifier": "size.lsz",
+                        "name": "公共事业-自来水缴费",
+                        "needSpecialQual": true,
+                        "parentCode": "A0011",
+                        "parentName": "生活缴费",
+                        "sortNum": 3,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0225",
+                        "creator": "size.lsz",
+                        "description": "供供暖缴费相关商户申请使用",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1632377565000,
+                        "gmtModified": 1632625395000,
+                        "level": 2,
+                        "modifier": "size.lsz",
+                        "name": "供暖缴费",
+                        "needSpecialQual": true,
+                        "parentCode": "A0011",
+                        "parentName": "生活缴费",
+                        "sortNum": 9,
+                        "special": true,
+                        "status": "VALID"
+                    }
+                ],
+                "code": "A0011",
+                "creator": "john.wy",
+                "description": "生活缴费",
+                "display": true,
+                "door": true,
+                "gmtCreate": 1602767921000,
+                "gmtModified": 1602767922000,
+                "level": 1,
+                "modifier": "john.wy",
+                "name": "生活缴费",
+                "needSpecialQual": false,
+                "parentCode": "ROOT",
+                "parentName": "根节点",
+                "sortNum": 11,
+                "special": false,
+                "status": "VALID"
+            },
+            {
+                "childrenNodes": [
+                    {
+                        "childrenNodes": [],
+                        "code": "B0080",
+                        "creator": "john.wy",
+                        "description": "适用于ETC办理、充值、缴费等业务。",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1658714457000,
+                        "level": 2,
+                        "modifier": "mingyang.gmy",
+                        "name": "ETC不停车自动缴费",
+                        "needSpecialQual": true,
+                        "parentCode": "A0005",
+                        "parentName": "车主生活",
+                        "sortNum": 10,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0081",
+                        "creator": "john.wy",
+                        "description": "适用于MTC收费业务。",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1609816623000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "MTC半自动车道收费",
+                        "needSpecialQual": true,
+                        "parentCode": "A0005",
+                        "parentName": "车主生活",
+                        "sortNum": 11,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0082",
+                        "creator": "john.wy",
+                        "description": "适用于高速服务区申请",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1622186941000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "高速服务区",
+                        "needSpecialQual": false,
+                        "parentCode": "A0005",
+                        "parentName": "车主生活",
+                        "sortNum": 12,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0071",
+                        "creator": "john.wy",
+                        "description": "适用于主售汽车摩托车零配件、汽车摩托车用品精品的商家申请。",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1602767922000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "车辆零配件/用品精品",
+                        "needSpecialQual": false,
+                        "parentCode": "A0005",
+                        "parentName": "车主生活",
+                        "sortNum": 1,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0083",
+                        "creator": "john.wy",
+                        "description": "适用于提供交通紧急救援服务。",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1602767922000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "道路救援",
+                        "needSpecialQual": false,
+                        "parentCode": "A0005",
+                        "parentName": "车主生活",
+                        "sortNum": 13,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0072",
+                        "creator": "john.wy",
+                        "description": "适用于提供汽车维修/汽车美容/汽车养护等服务。",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1602767922000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "汽车洗美/维修养护",
+                        "needSpecialQual": false,
+                        "parentCode": "A0005",
+                        "parentName": "车主生活",
+                        "sortNum": 2,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0073",
+                        "creator": "john.wy",
+                        "description": "适用于销售新车的商家申请。",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1602767922000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "车辆销售",
+                        "needSpecialQual": false,
+                        "parentCode": "A0005",
+                        "parentName": "车主生活",
+                        "sortNum": 3,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0074",
+                        "creator": "john.wy",
+                        "description": "适用于销售二手车的商家申请。",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1622186871000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "二手车销售",
+                        "needSpecialQual": false,
+                        "parentCode": "A0005",
+                        "parentName": "车主生活",
+                        "sortNum": 4,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0075",
+                        "creator": "john.wy",
+                        "description": "适用于车辆停车使用相关的服务",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1602767922000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "停车服务",
+                        "needSpecialQual": false,
+                        "parentCode": "A0005",
+                        "parentName": "车主生活",
+                        "sortNum": 5,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0076",
+                        "creator": "john.wy",
+                        "description": "适用于提供专业驾驶协助相关的服务",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1622186923000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "代驾服务",
+                        "needSpecialQual": false,
+                        "parentCode": "A0005",
+                        "parentName": "车主生活",
+                        "sortNum": 6,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0077",
+                        "creator": "john.wy",
+                        "description": "适用于提供电动汽车充换电相关的服务",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767822000,
+                        "gmtModified": 1609816623000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "电动汽车充换电",
+                        "needSpecialQual": true,
+                        "parentCode": "A0005",
+                        "parentName": "车主生活",
+                        "sortNum": 7,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0078",
+                        "creator": "john.wy",
+                        "description": "适用于提供两轮电瓶车充换电相关的服务",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1722829204000,
+                        "level": 2,
+                        "modifier": "zxl01535939",
+                        "name": "两轮电瓶车充换电",
+                        "needSpecialQual": false,
+                        "parentCode": "A0005",
+                        "parentName": "车主生活",
+                        "sortNum": 8,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0079",
+                        "creator": "john.wy",
+                        "description": "适用于租车公司,提供汽车租赁、人工咨询、在线预约、在线下单、在线/当面付费等服务。",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1602767922000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "汽车租赁",
+                        "needSpecialQual": false,
+                        "parentCode": "A0005",
+                        "parentName": "车主生活",
+                        "sortNum": 9,
+                        "special": false,
+                        "status": "VALID"
+                    }
+                ],
+                "code": "A0005",
+                "creator": "john.wy",
+                "description": "车生活服务",
+                "display": true,
+                "door": true,
+                "gmtCreate": 1602767921000,
+                "gmtModified": 1612260327000,
+                "level": 1,
+                "modifier": "john.wy",
+                "name": "车主生活",
+                "needSpecialQual": false,
+                "parentCode": "ROOT",
+                "parentName": "根节点",
+                "sortNum": 5,
+                "special": false,
+                "status": "VALID"
+            },
+            {
+                "childrenNodes": [
+                    {
+                        "childrenNodes": [],
+                        "code": "B0090",
+                        "creator": "john.wy",
+                        "description": "适用于提供加油卡相关资讯、销售、充值服务。",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1609816623000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "加油卡、加油服务",
+                        "needSpecialQual": true,
+                        "parentCode": "A0006",
+                        "parentName": "交通出行",
+                        "sortNum": 7,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0091",
+                        "creator": "john.wy",
+                        "description": "适用于提供加油、高速公路休息等服务。",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1609816623000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "加油站、加气站",
+                        "needSpecialQual": true,
+                        "parentCode": "A0006",
+                        "parentName": "交通出行",
+                        "sortNum": 8,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0084",
+                        "creator": "john.wy",
+                        "description": "适用于提供公路客运的服务",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767822000,
+                        "gmtModified": 1664248639000,
+                        "level": 2,
+                        "modifier": "yan.zhouzy",
+                        "name": "公路客运",
+                        "needSpecialQual": true,
+                        "parentCode": "A0006",
+                        "parentName": "交通出行",
+                        "sortNum": 1,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0085",
+                        "creator": "john.wy",
+                        "description": "适用于提供出租车客运的服务",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1664196666000,
+                        "level": 2,
+                        "modifier": "yan.zhouzy",
+                        "name": "出租车客运",
+                        "needSpecialQual": true,
+                        "parentCode": "A0006",
+                        "parentName": "交通出行",
+                        "sortNum": 2,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0097",
+                        "creator": "john.wy",
+                        "description": "适用于提供航空客运服务。",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1675240439000,
+                        "level": 2,
+                        "modifier": "zxl01535939",
+                        "name": "航空公司",
+                        "needSpecialQual": true,
+                        "parentCode": "A0006",
+                        "parentName": "交通出行",
+                        "sortNum": 14,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0086",
+                        "creator": "john.wy",
+                        "description": "适用于提供快车、专车或其他网约车在线预约/支付、出行交通行程信息展示等服务。",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1724998178000,
+                        "level": 2,
+                        "modifier": "zxl01535939",
+                        "name": "网约车客运",
+                        "needSpecialQual": true,
+                        "parentCode": "A0006",
+                        "parentName": "交通出行",
+                        "sortNum": 3,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0098",
+                        "creator": "john.wy",
+                        "description": "适用于机场申请",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1602767922000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "机场",
+                        "needSpecialQual": false,
+                        "parentCode": "A0006",
+                        "parentName": "交通出行",
+                        "sortNum": 15,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0087",
+                        "creator": "john.wy",
+                        "description": "适用于提供地铁客运的服务",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1609816623000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "地铁",
+                        "needSpecialQual": true,
+                        "parentCode": "A0006",
+                        "parentName": "交通出行",
+                        "sortNum": 4,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0099",
+                        "creator": "john.wy",
+                        "description": "适用于提供中国民用航空运输销售代理业务服务的公司申请",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767822000,
+                        "gmtModified": 1648192281000,
+                        "level": 2,
+                        "modifier": "size.lsz",
+                        "name": "机票代理人",
+                        "needSpecialQual": true,
+                        "parentCode": "A0006",
+                        "parentName": "交通出行",
+                        "sortNum": 16,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0088",
+                        "creator": "john.wy",
+                        "description": "适用于提供公共交通客运的服务",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1665458996000,
+                        "level": 2,
+                        "modifier": "yan.zhouzy",
+                        "name": "公共交通",
+                        "needSpecialQual": true,
+                        "parentCode": "A0006",
+                        "parentName": "交通出行",
+                        "sortNum": 5,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0100",
+                        "creator": "john.wy",
+                        "description": "适用于提供航空客运资讯查询、人工咨询服务、在线预约、在线购票、值机等服务。",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1602767922000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "航空系统商",
+                        "needSpecialQual": false,
+                        "parentCode": "A0006",
+                        "parentName": "交通出行",
+                        "sortNum": 17,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0089",
+                        "creator": "john.wy",
+                        "description": "适用于提供两轮车出行的服务",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1622186996000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "共享两轮车服务",
+                        "needSpecialQual": false,
+                        "parentCode": "A0006",
+                        "parentName": "交通出行",
+                        "sortNum": 6,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0101",
+                        "creator": "john.wy",
+                        "description": "适用于提供火车票预定、购票、退票、火车出行资讯或人工服务等服务。",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1609816623000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "铁路旅客运输",
+                        "needSpecialQual": true,
+                        "parentCode": "A0006",
+                        "parentName": "交通出行",
+                        "sortNum": 18,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0102",
+                        "creator": "john.wy",
+                        "description": "适用于游轮及巡游航线的服务",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1602767922000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "游轮及巡游航线服务",
+                        "needSpecialQual": false,
+                        "parentCode": "A0006",
+                        "parentName": "交通出行",
+                        "sortNum": 19,
+                        "special": false,
+                        "status": "VALID"
+                    }
+                ],
+                "code": "A0006",
+                "creator": "john.wy",
+                "description": "出行物流运输",
+                "display": true,
+                "door": true,
+                "gmtCreate": 1602767921000,
+                "gmtModified": 1612260340000,
+                "level": 1,
+                "modifier": "john.wy",
+                "name": "交通出行",
+                "needSpecialQual": false,
+                "parentCode": "ROOT",
+                "parentName": "根节点",
+                "sortNum": 6,
+                "special": false,
+                "status": "VALID"
+            },
+            {
+                "childrenNodes": [
+                    {
+                        "childrenNodes": [],
+                        "code": "B0060",
+                        "creator": "john.wy",
+                        "description": "适用于提供拍卖、收藏的服务。",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1621324651000,
+                        "level": 2,
+                        "modifier": "yumai.cw",
+                        "name": "拍卖/收藏",
+                        "needSpecialQual": true,
+                        "parentCode": "A0003",
+                        "parentName": "商业生活服务",
+                        "sortNum": 17,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0061",
+                        "creator": "john.wy",
+                        "description": "其他商业及生活服务",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1602767922000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "其他商业及生活服务",
+                        "needSpecialQual": false,
+                        "parentCode": "A0003",
+                        "parentName": "商业生活服务",
+                        "sortNum": 18,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0116",
+                        "creator": "john.wy",
+                        "description": "提供本地综合类生活信息服务的平台",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1622187023000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "生活服务平台",
+                        "needSpecialQual": false,
+                        "parentCode": "A0003",
+                        "parentName": "商业生活服务",
+                        "sortNum": 9,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0053",
+                        "creator": "john.wy",
+                        "description": "适用于个人提供婚介、婚庆周边、丽人摄影等相关服务。",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1602767922000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "婚介/婚庆/摄影服务",
+                        "needSpecialQual": false,
+                        "parentCode": "A0003",
+                        "parentName": "商业生活服务",
+                        "sortNum": 10,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0054",
+                        "creator": "john.wy",
+                        "description": "适用于提供商业广告、会展设计、图文印刷等相关等服务。",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767822000,
+                        "gmtModified": 1602767823000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "广告/会展/图文印刷",
+                        "needSpecialQual": false,
+                        "parentCode": "A0003",
+                        "parentName": "商业生活服务",
+                        "sortNum": 11,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0230",
+                        "creator": "zxl01535939",
+                        "description": "适用场景包括但不限于,场站(机场/高铁/公交等)、场域(商圈/运动场馆/滑雪场等)、门店等提供实物及相关配套租赁服务的商家申请",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1717567450000,
+                        "gmtModified": 1717567450000,
+                        "level": 2,
+                        "modifier": "zxl01535939",
+                        "name": "目的地租赁",
+                        "needSpecialQual": true,
+                        "parentCode": "A0003",
+                        "parentName": "商业生活服务",
+                        "sortNum": 29,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0055",
+                        "creator": "john.wy",
+                        "description": "适用于提供法律咨询、付费法律协助等服务。",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1609816623000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "法律咨询/律师事务所",
+                        "needSpecialQual": true,
+                        "parentCode": "A0003",
+                        "parentName": "商业生活服务",
+                        "sortNum": 12,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0231",
+                        "creator": "zxl01535939",
+                        "description": "适用于长租/短租,住房、商铺和企业办公场地租赁等商家申请",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1717643244000,
+                        "gmtModified": 1717643244000,
+                        "level": 2,
+                        "modifier": "zxl01535939",
+                        "name": "房产租赁",
+                        "needSpecialQual": true,
+                        "parentCode": "A0003",
+                        "parentName": "商业生活服务",
+                        "sortNum": 30,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0056",
+                        "creator": "john.wy",
+                        "description": "适用于提供证券、基金、期货投资等在线咨询、培训服务。",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1602767922000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "会计/金融咨询服务",
+                        "needSpecialQual": false,
+                        "parentCode": "A0003",
+                        "parentName": "商业生活服务",
+                        "sortNum": 13,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0057",
+                        "creator": "john.wy",
+                        "description": "适用于提供征信和信用报告咨询服务。",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1609816623000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "征信和信用报告咨询服务",
+                        "needSpecialQual": true,
+                        "parentCode": "A0003",
+                        "parentName": "商业生活服务",
+                        "sortNum": 14,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0112",
+                        "creator": "john.wy",
+                        "description": "适用于提供在线工具类服务公司申请,如网盘、下载软件等",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1622187017000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "在线工具",
+                        "needSpecialQual": false,
+                        "parentCode": "A0003",
+                        "parentName": "商业生活服务",
+                        "sortNum": 5,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0058",
+                        "creator": "john.wy",
+                        "description": "适用于提供猎头、职业中介等招聘服务。",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1602767922000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "人才招聘服务",
+                        "needSpecialQual": false,
+                        "parentCode": "A0003",
+                        "parentName": "商业生活服务",
+                        "sortNum": 15,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0212",
+                        "creator": "john.wy",
+                        "description": "适用于提供共享充电宝及共享雨伞等信用借还服务",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1609322436000,
+                        "gmtModified": 1609322438000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "共享充电宝及其他共享租赁",
+                        "needSpecialQual": false,
+                        "parentCode": "A0003",
+                        "parentName": "商业生活服务",
+                        "sortNum": 10,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0059",
+                        "creator": "john.wy",
+                        "description": "适用于提供丧仪殡葬的服务。",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1609816623000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "丧葬服务",
+                        "needSpecialQual": true,
+                        "parentCode": "A0003",
+                        "parentName": "商业生活服务",
+                        "sortNum": 16,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0213",
+                        "creator": "john.wy",
+                        "description": "适用于提供自助售卖机等零售相关服务",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1609322481000,
+                        "gmtModified": 1609322482000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "无人值守自助零售",
+                        "needSpecialQual": false,
+                        "parentCode": "A0003",
+                        "parentName": "商业生活服务",
+                        "sortNum": 11,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0214",
+                        "creator": "john.wy",
+                        "description": "适用于提供自助KTV、夹娃娃机等娱乐服务",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1609322528000,
+                        "gmtModified": 1609322527000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "无人值守自助娱乐",
+                        "needSpecialQual": false,
+                        "parentCode": "A0003",
+                        "parentName": "商业生活服务",
+                        "sortNum": 12,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0050",
+                        "creator": "john.wy",
+                        "description": "适用于宠物医院提供宠物、家禽治疗预约,宠物美容、宠物资讯等服务。",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1622186875000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "宠物医院/其他宠物服务",
+                        "needSpecialQual": false,
+                        "parentCode": "A0003",
+                        "parentName": "商业生活服务",
+                        "sortNum": 7,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0051",
+                        "creator": "john.wy",
+                        "description": "适用于3C数码,如手机、电脑、相机、无人机、游戏机、智能配件等;时尚生活,如奢侈品包、珠宝首饰(含门店);居家生活,如家具、家电、母婴医疗器械(含门店);运动健康,如自行车(含门店);教育艺术,如乐器(含门店)等场景经营的商家申请",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1722235304000,
+                        "level": 2,
+                        "modifier": "wb-zh854279",
+                        "name": "消费品租赁",
+                        "needSpecialQual": false,
+                        "parentCode": "A0003",
+                        "parentName": "商业生活服务",
+                        "sortNum": 8,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0052",
+                        "creator": "john.wy",
+                        "description": "适用于提供自助按摩椅、自助洗衣机等服务",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1602767922000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "无人值守自助服务",
+                        "needSpecialQual": false,
+                        "parentCode": "A0003",
+                        "parentName": "商业生活服务",
+                        "sortNum": 9,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0227",
+                        "creator": "swl01119956",
+                        "description": "适用于提供送水订奶相关服务的商户",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1677652205000,
+                        "gmtModified": 1681985780000,
+                        "level": 2,
+                        "modifier": "swl01119956",
+                        "name": "送水订奶",
+                        "needSpecialQual": true,
+                        "parentCode": "A0003",
+                        "parentName": "商业生活服务",
+                        "sortNum": 26,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0229",
+                        "creator": "zxl01535939",
+                        "description": "适用于以企业为承租主体,开展租赁业务的模式;主要涵盖办公设备租赁、商用设备租赁、工程器械租赁三大业务场景的商家申请",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1717556662000,
+                        "gmtModified": 1717556662000,
+                        "level": 2,
+                        "modifier": "zxl01535939",
+                        "name": "企业租赁",
+                        "needSpecialQual": false,
+                        "parentCode": "A0003",
+                        "parentName": "商业生活服务",
+                        "sortNum": 28,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0044",
+                        "creator": "john.wy",
+                        "description": "适用于美容美体场所,提供美甲、美容、美睫、美发、纹身、祛斑、祛痘、纤体瘦身等服务。",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1602767922000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "美发/美容/美甲服务",
+                        "needSpecialQual": false,
+                        "parentCode": "A0003",
+                        "parentName": "商业生活服务",
+                        "sortNum": 1,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0165",
+                        "creator": "john.wy",
+                        "description": "适用于物业公司申请",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1655117190000,
+                        "level": 2,
+                        "modifier": "size.lsz",
+                        "name": "物业管理",
+                        "needSpecialQual": false,
+                        "parentCode": "A0003",
+                        "parentName": "商业生活服务",
+                        "sortNum": 5,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0045",
+                        "creator": "john.wy",
+                        "description": "适用于提供洗浴/保健养生等服务。",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1602767922000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "洗浴/保健养生服务",
+                        "needSpecialQual": false,
+                        "parentCode": "A0003",
+                        "parentName": "商业生活服务",
+                        "sortNum": 2,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0046",
+                        "creator": "john.wy",
+                        "description": "适用于提供家政服务,衣物干洗清洁的服务。",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1602767922000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "家政/清洁服务",
+                        "needSpecialQual": false,
+                        "parentCode": "A0003",
+                        "parentName": "商业生活服务",
+                        "sortNum": 3,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0047",
+                        "creator": "john.wy",
+                        "description": "适用于提供家电维修、数码电器维修等服务。",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767822000,
+                        "gmtModified": 1602767823000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "电器/家具/其他维修",
+                        "needSpecialQual": false,
+                        "parentCode": "A0003",
+                        "parentName": "商业生活服务",
+                        "sortNum": 4,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0048",
+                        "creator": "john.wy",
+                        "description": "适用于提供房屋设计、装修相关的服务。",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1602767922000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "建筑装饰/装修服务",
+                        "needSpecialQual": false,
+                        "parentCode": "A0003",
+                        "parentName": "商业生活服务",
+                        "sortNum": 5,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0049",
+                        "creator": "john.wy",
+                        "description": "适用于提供租房、新房、二手房等房源信息等服务。",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1602767922000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "地产/房屋中介代理",
+                        "needSpecialQual": false,
+                        "parentCode": "A0003",
+                        "parentName": "商业生活服务",
+                        "sortNum": 6,
+                        "special": false,
+                        "status": "VALID"
+                    }
+                ],
+                "code": "A0003",
+                "creator": "john.wy",
+                "description": "商业生活服务",
+                "display": true,
+                "door": true,
+                "gmtCreate": 1602767921000,
+                "gmtModified": 1602767922000,
+                "level": 1,
+                "modifier": "john.wy",
+                "name": "商业生活服务",
+                "needSpecialQual": false,
+                "parentCode": "ROOT",
+                "parentName": "根节点",
+                "sortNum": 3,
+                "special": false,
+                "status": "VALID"
+            },
+            {
+                "childrenNodes": [
+                    {
+                        "childrenNodes": [],
+                        "code": "B0106",
+                        "creator": "john.wy",
+                        "description": "适用于国际货运代理和报关服务",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1612259870000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "国际货运代理和报关行",
+                        "needSpecialQual": false,
+                        "parentCode": "A0015",
+                        "parentName": "物流运输",
+                        "sortNum": 11,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0107",
+                        "creator": "john.wy",
+                        "description": "其他运输代理业",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767822000,
+                        "gmtModified": 1612259889000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "其他运输代理业",
+                        "needSpecialQual": false,
+                        "parentCode": "A0015",
+                        "parentName": "物流运输",
+                        "sortNum": 12,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0092",
+                        "creator": "john.wy",
+                        "description": "适用于公司主体的物流/快递申请",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767822000,
+                        "gmtModified": 1612683420000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "物流/快递公司",
+                        "needSpecialQual": true,
+                        "parentCode": "A0015",
+                        "parentName": "物流运输",
+                        "sortNum": 9,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0093",
+                        "creator": "john.wy",
+                        "description": "适用于个人商户集合多家快递的收发服务申请",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1664243692000,
+                        "level": 2,
+                        "modifier": "yan.zhouzy",
+                        "name": "快递服务(个人商户)",
+                        "needSpecialQual": false,
+                        "parentCode": "A0015",
+                        "parentName": "物流运输",
+                        "sortNum": 2,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0094",
+                        "creator": "john.wy",
+                        "description": "适用于***邮政管理局(非快递公司,中国邮政不属于国家邮政)申请",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1612259754000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "邮政基本服务",
+                        "needSpecialQual": false,
+                        "parentCode": "A0015",
+                        "parentName": "物流运输",
+                        "sortNum": 5,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0095",
+                        "creator": "john.wy",
+                        "description": "适用于公司主体的驿站、自提柜服务申请",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1669702063000,
+                        "level": 2,
+                        "modifier": "yan.zhouzy",
+                        "name": "驿站/自提柜",
+                        "needSpecialQual": true,
+                        "parentCode": "A0015",
+                        "parentName": "物流运输",
+                        "sortNum": 6,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0103",
+                        "creator": "john.wy",
+                        "description": "适用于提供铁路货物运输的服务",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1612259809000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "铁路货物运输",
+                        "needSpecialQual": true,
+                        "parentCode": "A0015",
+                        "parentName": "物流运输",
+                        "sortNum": 8,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0104",
+                        "creator": "john.wy",
+                        "description": "适用于船舶、海运的服务",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1612259841000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "船舶、海运服务提供商",
+                        "needSpecialQual": true,
+                        "parentCode": "A0015",
+                        "parentName": "物流运输",
+                        "sortNum": 9,
+                        "special": true,
+                        "status": "VALID"
+                    }
+                ],
+                "code": "A0015",
+                "creator": "john.wy",
+                "description": "物流运输",
+                "display": true,
+                "door": true,
+                "gmtCreate": 1612259245000,
+                "gmtModified": 1612259245000,
+                "level": 1,
+                "modifier": "john.wy",
+                "name": "物流运输",
+                "needSpecialQual": false,
+                "parentCode": "ROOT",
+                "parentName": "根节点",
+                "sortNum": 15,
+                "special": false,
+                "status": "VALID"
+            },
+            {
+                "childrenNodes": [
+                    {
+                        "childrenNodes": [],
+                        "code": "B0062",
+                        "creator": "john.wy",
+                        "description": "适用于歌舞厅、夜店、休闲会所、KTV等场所申请",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767822000,
+                        "gmtModified": 1602767823000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "歌舞厅/休闲会所/KTV",
+                        "needSpecialQual": false,
+                        "parentCode": "A0004",
+                        "parentName": "休闲娱乐",
+                        "sortNum": 1,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0063",
+                        "creator": "john.wy",
+                        "description": "适用于棋牌桌游/电玩网吧等场所申请",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1602767922000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "棋牌桌游/电玩网吧",
+                        "needSpecialQual": false,
+                        "parentCode": "A0004",
+                        "parentName": "休闲娱乐",
+                        "sortNum": 2,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0205",
+                        "creator": "john.wy",
+                        "description": "适用于游戏充值平台、游戏金币交易的公司等申请",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1609322703000,
+                        "gmtModified": 1631095459000,
+                        "level": 2,
+                        "modifier": "size.lsz",
+                        "name": "游戏周边服务/交易平台",
+                        "needSpecialQual": true,
+                        "parentCode": "A0004",
+                        "parentName": "休闲娱乐",
+                        "sortNum": 4,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0108",
+                        "creator": "john.wy",
+                        "description": "适用于在线社交类服务提供公司申请",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1612260220000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "网络社交",
+                        "needSpecialQual": false,
+                        "parentCode": "A0004",
+                        "parentName": "休闲娱乐",
+                        "sortNum": 1,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0109",
+                        "creator": "john.wy",
+                        "description": "适用于提供在线视频点播、在线小说、图书以及音乐等下载服务等公司申请",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1612260237000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "网络图书/视频/音乐",
+                        "needSpecialQual": true,
+                        "parentCode": "A0004",
+                        "parentName": "休闲娱乐",
+                        "sortNum": 2,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0064",
+                        "creator": "john.wy",
+                        "description": "适用于健身场所、瑜伽房、舞蹈室等场所申请",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1602767922000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "健身房/瑜伽/舞蹈",
+                        "needSpecialQual": false,
+                        "parentCode": "A0004",
+                        "parentName": "休闲娱乐",
+                        "sortNum": 3,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0065",
+                        "creator": "john.wy",
+                        "description": "适用于话剧演出、体育赛事、演唱会等场所申请",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1602767922000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "院线影城/演出赛事",
+                        "needSpecialQual": false,
+                        "parentCode": "A0004",
+                        "parentName": "休闲娱乐",
+                        "sortNum": 4,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0110",
+                        "creator": "john.wy",
+                        "description": "适用于游戏开发、运营公司申请使用",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1633757690000,
+                        "level": 2,
+                        "modifier": "size.lsz",
+                        "name": "游戏",
+                        "needSpecialQual": true,
+                        "parentCode": "A0004",
+                        "parentName": "休闲娱乐",
+                        "sortNum": 3,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0066",
+                        "creator": "john.wy",
+                        "description": "适用于游乐园/嘉年华等场所申请",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1602767922000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "游乐园/嘉年华",
+                        "needSpecialQual": false,
+                        "parentCode": "A0004",
+                        "parentName": "休闲娱乐",
+                        "sortNum": 5,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0111",
+                        "creator": "john.wy",
+                        "description": "适用于提供在线直播等服务",
+                        "display": true,
+                        "door": false,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1622187003000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "网络直播",
+                        "needSpecialQual": true,
+                        "parentCode": "A0004",
+                        "parentName": "休闲娱乐",
+                        "sortNum": 4,
+                        "special": true,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0067",
+                        "creator": "john.wy",
+                        "description": "适用于图书馆、档案馆、美术馆等场所申请",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1602767922000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "文化场馆",
+                        "needSpecialQual": false,
+                        "parentCode": "A0004",
+                        "parentName": "休闲娱乐",
+                        "sortNum": 6,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0068",
+                        "creator": "john.wy",
+                        "description": "适用于体育场馆等场所申请",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767921000,
+                        "gmtModified": 1602767922000,
+                        "level": 2,
+                        "modifier": "john.wy",
+                        "name": "体育场馆",
+                        "needSpecialQual": false,
+                        "parentCode": "A0004",
+                        "parentName": "休闲娱乐",
+                        "sortNum": 7,
+                        "special": false,
+                        "status": "VALID"
+                    },
+                    {
+                        "childrenNodes": [],
+                        "code": "B0069",
+                        "creator": "john.wy",
+                        "description": "适用于体育/福利彩票售卖点等场所申请",
+                        "display": true,
+                        "door": true,
+                        "gmtCreate": 1602767822000,
+                        "gmtModified": 1671096732000,
+                        "level": 2,
+                        "modifier": "yan.zhouzy",
+                        "name": "彩票",
+                        "needSpecialQual": true,
+                        "parentCode": "A0004",
+                        "parentName": "休闲娱乐",
+                        "sortNum": 8,
+                        "special": true,
+                        "status": "VALID"
+                    }
+                ],
+                "code": "A0004",
+                "creator": "john.wy",
+                "description": "休闲娱乐",
+                "display": true,
+                "door": true,
+                "gmtCreate": 1602767921000,
+                "gmtModified": 1602767922000,
+                "level": 1,
+                "modifier": "john.wy",
+                "name": "休闲娱乐",
+                "needSpecialQual": false,
+                "parentCode": "ROOT",
+                "parentName": "根节点",
+                "sortNum": 4,
+                "special": false,
+                "status": "VALID"
+            }
+        ],
+        "code": "ROOT",
+        "description": "根节点",
+        "display": true,
+        "door": false,
+        "level": 1,
+        "name": "根节点",
+        "needSpecialQual": false,
+        "sortNum": 0,
+        "special": false,
+        "status": "VALID"
+    },
+    "success": true,
+    "traceId": "21d562b217755422801731698e7173"
+}

+ 154 - 0
src/views/businessInfo/createApply.vue

@@ -0,0 +1,154 @@
+<template>
+  <div class="create-apply-page">
+    <div class="page-header">
+      <h1 class="page-title">选择主体类型</h1>
+    </div>
+
+    <div class="card-grid">
+      <div v-for="item in entityTypeList" :key="item.key" class="entity-card">
+        <h3 class="card-title">
+          {{ item.title }}
+        </h3>
+        <p class="card-desc">
+          {{ item.desc }}
+        </p>
+        <el-button class="btn-select" @click="onSelectEntity(item)"> 选择 </el-button>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { useRouter } from "vue-router";
+import { ElMessage } from "element-plus";
+import { localSet } from "@/utils/index";
+
+const router = useRouter();
+
+const BUSINESS_DATA_CACHE_KEY = "businessData";
+
+type EntityTypeKey = "individual" | "enterprise" | "publicInstitution" | "socialOrganization" | "government" | "type";
+
+interface EntityTypeItem {
+  key: EntityTypeKey;
+  title: string;
+  desc: string;
+  type: "SUPER" | "LEGAL";
+}
+
+const entityTypeList: EntityTypeItem[] = [
+  {
+    key: "individual",
+    type: "SUPER",
+    title: "个体工商户",
+    desc: "营业执照上的主体类型一般为个体户、个体工商户、个体经营"
+  },
+  {
+    key: "enterprise",
+    title: "企业",
+    type: "LEGAL",
+    desc: "营业执照上的主体类型一般为有限公司、有限责任公司"
+  }
+];
+
+function openEntityGuide() {
+  ElMessage.info("主体指引说明可在此接入文档或弹窗");
+}
+
+function onSelectEntity(item: EntityTypeItem) {
+  const businessData = {
+    entityType: item.key,
+    contact_type: item.type
+  };
+  localSet(BUSINESS_DATA_CACHE_KEY, businessData);
+  router.push({
+    path: "/businessInfo/dataEntry",
+    query: { entityType: item.key }
+  });
+}
+</script>
+
+<style scoped lang="scss">
+.create-apply-page {
+  box-sizing: border-box;
+  min-height: 100%;
+  padding: 24px 32px 48px;
+  background: #ffffff;
+}
+.page-header {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 12px;
+  align-items: center;
+  justify-content: space-between;
+  margin: 0 auto 28px;
+}
+.page-title {
+  margin: 0;
+  font-size: 22px;
+  font-weight: 600;
+  color: #303133;
+  letter-spacing: 0.02em;
+}
+.guide-link {
+  font-size: 14px;
+}
+.card-grid {
+  display: grid;
+  grid-template-columns: repeat(3, 1fr);
+  gap: 20px;
+  margin: 0 auto;
+}
+
+@media (width <= 1100px) {
+  .card-grid {
+    grid-template-columns: repeat(2, 1fr);
+  }
+}
+
+@media (width <= 640px) {
+  .card-grid {
+    grid-template-columns: 1fr;
+  }
+}
+.entity-card {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: flex-start;
+  min-height: 220px;
+  padding: 24px 20px 20px;
+  text-align: center;
+  background: #ffffff;
+  border: 1px solid #e4e7ed;
+  border-radius: 8px;
+  box-shadow: 0 1px 2px rgb(0 0 0 / 4%);
+}
+.card-title {
+  margin: 0 0 12px;
+  font-size: 16px;
+  font-weight: 600;
+  line-height: 1.4;
+  color: #303133;
+}
+.card-desc {
+  flex: 1;
+  margin: 0 0 20px;
+  font-size: 13px;
+  line-height: 1.65;
+  color: #909399;
+}
+.btn-select {
+  min-width: 120px;
+  height: 34px;
+  padding: 0 20px;
+  font-size: 14px;
+  color: #ffffff !important;
+  background: #00c05b !important;
+  border: none !important;
+  border-radius: 4px;
+  &:hover {
+    background: #00a850 !important;
+  }
+}
+</style>

+ 356 - 0
src/views/businessInfo/dataEntry.vue

@@ -0,0 +1,356 @@
+<template>
+  <div class="data-entry-page">
+    <h1 class="page-main-title">资料填写</h1>
+
+    <!-- 申请单信息 -->
+    <section class="content-block">
+      <h2 class="section-head">
+        <span class="section-bar" aria-hidden="true" />
+        申请单信息
+      </h2>
+      <div class="app-info-row">
+        <div class="app-info-item">
+          <span class="label">已选主体类型</span>
+          <span class="value">{{ entityTypeLabel }}</span>
+          <el-link type="primary" :underline="false" class="modify-link" @click="onModifyEntityType"> 修改 </el-link>
+        </div>
+        <div class="app-info-item">
+          <span class="label">创建时间</span>
+          <span class="value mono">{{ applicationMeta.createdAt }}</span>
+        </div>
+        <div class="app-info-item">
+          <span class="label">申请单编号</span>
+          <span class="value mono">{{ applicationMeta.applicationNo }}</span>
+        </div>
+      </div>
+    </section>
+
+    <!-- 必填信息 -->
+    <section class="content-block">
+      <h2 class="section-head">
+        <span class="section-bar" aria-hidden="true" />
+        必填信息
+      </h2>
+      <ul class="step-list" role="list">
+        <li v-for="step in requiredSteps" :key="step.key" class="step-item">
+          <div class="step-indicator" :class="{ 'is-current': step.active }" aria-hidden="true">
+            <span v-if="step.active" class="dot-inner" />
+          </div>
+          <div class="step-main">
+            <div class="step-title-row">
+              <span class="step-title">{{ step.title }}</span>
+              <el-link v-if="step.showAction" type="info" :underline="false" class="step-action" @click="onGoFill(step.key)">
+                去填写 &gt;
+              </el-link>
+            </div>
+            <p class="step-desc">
+              {{ step.desc }}
+            </p>
+          </div>
+        </li>
+      </ul>
+    </section>
+
+    <!-- 选填信息 -->
+    <section class="content-block">
+      <h2 class="section-head">
+        <span class="section-bar" aria-hidden="true" />
+        选填信息
+      </h2>
+      <div class="optional-block">
+        <div class="optional-title">补充材料</div>
+        <p class="optional-desc">根据实际审核情况,额外要求商家提供指定的补充资料</p>
+      </div>
+    </section>
+
+    <!-- 协议 -->
+    <div class="agreement-block">
+      <el-checkbox v-model="agreementChecked" class="agreement-checkbox">
+        <span class="agreement-text">
+          商户自愿申请微信支付商户号,以上申请单资料由商户整理并委托本机构代为填写;最终提交资料以商户确认信息为准。
+        </span>
+      </el-checkbox>
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { computed, reactive, ref } from "vue";
+import { useRoute, useRouter } from "vue-router";
+import { ElMessage } from "element-plus";
+
+/** 与 createApply 主体类型 key 对齐,便于路由 query 传入 */
+export type EntityTypeKey = "individual" | "enterprise" | "publicInstitution" | "socialOrganization" | "government";
+
+const ENTITY_LABEL: Record<EntityTypeKey, string> = {
+  individual: "个体工商户",
+  enterprise: "企业",
+  publicInstitution: "事业单位",
+  socialOrganization: "社会组织",
+  government: "政府机关"
+};
+
+const props = withDefaults(
+  defineProps<{
+    /** 路由或父组件传入的主体类型 */
+    entityType?: EntityTypeKey | string;
+  }>(),
+  {
+    entityType: undefined
+  }
+);
+
+const route = useRoute();
+const router = useRouter();
+
+const entityTypeLabel = computed(() => {
+  const k = (props.entityType ?? route.query.entityType ?? "individual") as EntityTypeKey;
+  return ENTITY_LABEL[k] ?? "个体工商户";
+});
+
+const applicationMeta = reactive({
+  createdAt: "2026-03-30 16:59:12",
+  applicationNo: "2000002773599273"
+});
+
+interface RequiredStep {
+  key: string;
+  title: string;
+  desc: string;
+  active: boolean;
+  showAction: boolean;
+}
+
+const requiredSteps = ref<RequiredStep[]>([
+  {
+    key: "entity",
+    title: "主体信息",
+    desc: "请填写商家的营业执照/登记证书、经营者/法人的证件等信息",
+    active: true,
+    showAction: true
+  },
+  {
+    key: "business",
+    title: "经营信息",
+    desc: "请填写商家的经营业务信息、售卖商品/提供服务场景信息",
+    active: false,
+    showAction: false
+  },
+  {
+    key: "industry",
+    title: "行业资质",
+    desc: "请填写商家所属行业、特殊资质等信息",
+    active: false,
+    showAction: false
+  },
+  {
+    key: "settlement",
+    title: "结算账户",
+    desc: "请填写商家提现收款的银行账户信息",
+    active: false,
+    showAction: false
+  },
+  {
+    key: "admin",
+    title: "超级管理员",
+    desc: "请填写商家的超级管理员信息,超级管理员需在开户后进行签约,并接收日常重要管理信息和进行资金操作,请确定其为商户法定代表人或负责人",
+    active: false,
+    showAction: false
+  }
+]);
+
+const agreementChecked = ref(true);
+
+function onModifyEntityType() {
+  router.push({
+    path: "/businessInfo/weChartIndex"
+  });
+}
+
+function onGoFill(stepKey: string) {
+  if (stepKey === "entity") {
+    router.push({
+      path: "/businessInfo/subjectInfo",
+      query: { ...route.query }
+    });
+    return;
+  }
+  ElMessage.info(`进入填写:${stepKey}(可接路由)`);
+}
+</script>
+
+<style scoped lang="scss">
+$wechat-green: #07c160;
+.data-entry-page {
+  box-sizing: border-box;
+  min-height: 100%;
+  padding: 24px 32px 48px;
+  margin: 0 auto;
+  background: #ffffff;
+}
+.page-main-title {
+  margin: 0 0 28px;
+  font-size: 20px;
+  font-weight: 600;
+  color: #303133;
+}
+.content-block {
+  padding-bottom: 28px;
+  margin-bottom: 32px;
+  border-bottom: 1px solid #ebeef5;
+  &:last-of-type {
+    padding-bottom: 0;
+    margin-bottom: 24px;
+    border-bottom: none;
+  }
+}
+.section-head {
+  display: flex;
+  align-items: center;
+  margin: 0 0 16px;
+  font-size: 16px;
+  font-weight: 600;
+  color: #303133;
+}
+.section-bar {
+  display: inline-block;
+  flex-shrink: 0;
+  width: 4px;
+  height: 16px;
+  margin-right: 8px;
+  background: $wechat-green;
+  border-radius: 2px;
+}
+.app-info-row {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 16px 32px;
+  align-items: baseline;
+  font-size: 14px;
+  line-height: 1.6;
+  color: #606266;
+}
+.app-info-item {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 6px 8px;
+  align-items: center;
+}
+.app-info-item .label {
+  color: #909399;
+}
+.app-info-item .value {
+  color: #303133;
+}
+.app-info-item .value.mono {
+  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
+  font-size: 13px;
+}
+.modify-link {
+  margin-left: 4px;
+  font-size: 14px;
+}
+.step-list {
+  padding: 0;
+  margin: 0;
+  list-style: none;
+}
+.step-item {
+  display: flex;
+  gap: 12px;
+  padding: 16px 0;
+  border-bottom: 1px solid #f0f2f5;
+  &:last-child {
+    padding-bottom: 0;
+    border-bottom: none;
+  }
+}
+.step-indicator {
+  flex-shrink: 0;
+  width: 14px;
+  height: 14px;
+  margin-top: 4px;
+  border: 2px solid #dcdfe6;
+  border-radius: 50%;
+  &.is-current {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    background: $wechat-green;
+    border-color: $wechat-green;
+  }
+}
+.dot-inner {
+  width: 5px;
+  height: 5px;
+  background: #ffffff;
+  border-radius: 50%;
+}
+.step-main {
+  flex: 1;
+  min-width: 0;
+}
+.step-title-row {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 8px 16px;
+  align-items: center;
+  justify-content: space-between;
+  margin-bottom: 6px;
+}
+.step-title {
+  font-size: 15px;
+  font-weight: 600;
+  color: #303133;
+}
+.step-desc {
+  margin: 0;
+  font-size: 13px;
+  line-height: 1.65;
+  color: #909399;
+}
+.step-action {
+  flex-shrink: 0;
+  font-size: 13px;
+  color: #909399 !important;
+  &:hover {
+    color: #606266 !important;
+  }
+}
+.optional-block {
+  padding: 4px 0 0;
+}
+.optional-title {
+  margin-bottom: 8px;
+  font-size: 15px;
+  font-weight: 600;
+  color: #303133;
+}
+.optional-desc {
+  margin: 0;
+  font-size: 13px;
+  line-height: 1.65;
+  color: #909399;
+}
+.agreement-block {
+  padding-top: 8px;
+}
+.agreement-checkbox {
+  align-items: flex-start;
+  :deep(.el-checkbox__label) {
+    line-height: 1.65;
+    white-space: normal;
+  }
+  :deep(.el-checkbox__input.is-checked .el-checkbox__inner) {
+    background-color: $wechat-green;
+    border-color: $wechat-green;
+  }
+  :deep(.el-checkbox__input.is-checked + .el-checkbox__label) {
+    color: #606266;
+  }
+}
+.agreement-text {
+  font-size: 13px;
+  color: #606266;
+}
+</style>

+ 257 - 0
src/views/businessInfo/industryQualifications.vue

@@ -0,0 +1,257 @@
+<template>
+  <div class="industry-qual-page">
+    <h1 class="page-title">行业资质</h1>
+
+    <section class="form-block">
+      <h2 class="section-head">
+        <span class="section-bar" aria-hidden="true" />
+        行业资质
+        <span class="section-intro">请填写商家的所属行业、特殊资质等信息</span>
+      </h2>
+
+      <el-form
+        ref="formRef"
+        class="industry-form"
+        :model="form"
+        :rules="rules"
+        label-width="160px"
+        require-asterisk-position="right"
+        label-position="right"
+      >
+        <el-form-item label="所属行业" prop="industry">
+          <el-select
+            v-model="form.industry"
+            placeholder="请选择"
+            filterable
+            clearable
+            style="max-width: 480px"
+            @change="onIndustryChange"
+          >
+            <el-option v-for="o in industryOptions" :key="o.value" :label="o.label" :value="o.value" />
+          </el-select>
+        </el-form-item>
+
+        <el-form-item label="结算费率">
+          <span class="settlement-rate-text">{{ settlementRateText }}</span>
+        </el-form-item>
+
+        <!-- <el-form-item label="优惠费率活动(选填)" prop="discountActivity">
+          <div class="field-stack">
+            <el-select
+              v-model="form.discountActivity"
+              placeholder="请选择"
+              clearable
+              style="max-width: 480px"
+            >
+              <el-option
+                v-for="o in discountActivityOptions"
+                :key="o.value"
+                :label="o.label"
+                :value="o.value"
+              />
+            </el-select>
+            <p class="field-tip">
+              部分行业可报名优惠费率活动,活动介绍请查看
+              <el-link type="primary" :underline="false" @click="openDiscountDetail">查看详情</el-link>
+            </p>
+          </div>
+        </el-form-item> -->
+      </el-form>
+    </section>
+
+    <div class="footer-actions">
+      <el-button @click="onBack"> 返回 </el-button>
+      <el-button type="primary" class="btn-next" :loading="submitLoading" @click="onSubmit"> 确定 </el-button>
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { computed, reactive, ref } from "vue";
+import { useRoute, useRouter } from "vue-router";
+import { ElMessage } from "element-plus";
+import type { FormInstance, FormRules } from "element-plus";
+import { localGet, localSet } from "@/utils/index";
+
+const BUSINESS_DATA_CACHE_KEY = "businessData";
+
+const formRef = ref<FormInstance>();
+const submitLoading = ref(false);
+const route = useRoute();
+const router = useRouter();
+
+/** 演示选项,可对接字典/接口 */
+const industryOptions = [
+  { label: "餐饮", value: "716" },
+  { label: "零售", value: "catering_retail_retail" },
+  { label: "生活服务", value: "life_service" },
+  { label: "电商平台", value: "ecommerce" }
+];
+
+const discountActivityOptions = [
+  { label: "活动一:新商户费率优惠", value: "act_1" },
+  { label: "活动二:行业专项优惠", value: "act_2" }
+];
+
+/** 按行业展示结算费率(演示:默认与示意图一致) */
+const industryRateMap: Record<string, string> = {
+  "716": "0.6%",
+  catering_retail_catering: "0.6%",
+  catering_retail_retail: "0.6%",
+  life_service: "0.6%",
+  ecommerce: "0.6%"
+};
+
+const form = reactive({
+  industry: "716",
+  discountActivity: "" as string
+});
+
+const settlementRateText = computed(() => {
+  if (!form.industry) return "—";
+  return industryRateMap[form.industry] ?? "0.6%";
+});
+
+const rules: FormRules = {
+  industry: [{ required: true, message: "请选择所属行业", trigger: "change" }]
+};
+
+function onIndustryChange() {
+  formRef.value?.validateField("industry").catch(() => {});
+}
+
+function openDiscountDetail() {
+  ElMessage.info("优惠费率活动说明(可对接文档或外链)");
+}
+
+function onBack() {
+  router.push({ path: "/businessInfo/manageInfo", query: { ...route.query } });
+}
+
+function onSaveDraft() {
+  ElMessage.success("草稿已保存(可对接接口)");
+}
+
+function mergeSettlementIntoBusinessDataCache() {
+  const prev = localGet(BUSINESS_DATA_CACHE_KEY);
+  const base = prev && typeof prev === "object" && !Array.isArray(prev) ? { ...(prev as Record<string, unknown>) } : {};
+  const prevSt =
+    base.settlement_info && typeof base.settlement_info === "object" && !Array.isArray(base.settlement_info)
+      ? { ...(base.settlement_info as Record<string, unknown>) }
+      : {};
+
+  const selected = industryOptions.find(o => o.value === form.industry);
+  const industryLabel = (selected?.label ?? "").trim();
+  const settlementId = selected != null ? String(selected.value).trim() : "";
+
+  base.settlement_info = {
+    ...prevSt,
+    qualification_type: industryLabel,
+    settlement_id: settlementId
+  };
+  localSet(BUSINESS_DATA_CACHE_KEY, base);
+}
+
+async function onSubmit() {
+  if (!formRef.value) return;
+  submitLoading.value = true;
+  try {
+    await formRef.value.validate();
+    mergeSettlementIntoBusinessDataCache();
+    await router.push({
+      path: "/businessInfo/accountInfo",
+      query: { ...route.query }
+    });
+  } catch {
+    ElMessage.warning("请完善必填信息");
+  } finally {
+    submitLoading.value = false;
+  }
+}
+</script>
+
+<style scoped lang="scss">
+$wechat-green: #07c160;
+.industry-qual-page {
+  box-sizing: border-box;
+  min-height: 100%;
+  padding: 24px 32px 40px;
+  margin: 0 auto;
+  background: #ffffff;
+}
+.page-title {
+  margin: 0 0 24px;
+  font-size: 20px;
+  font-weight: 600;
+  color: #303133;
+}
+.form-block {
+  margin-bottom: 24px;
+}
+.section-head {
+  display: flex;
+  flex-wrap: wrap;
+  align-items: center;
+  margin: 0 0 20px;
+  font-size: 16px;
+  font-weight: 600;
+  color: #303133;
+}
+.section-bar {
+  display: inline-block;
+  flex-shrink: 0;
+  width: 4px;
+  height: 16px;
+  margin-right: 8px;
+  background: $wechat-green;
+  border-radius: 2px;
+}
+.section-intro {
+  margin-left: 12px;
+  font-size: 13px;
+  font-weight: 400;
+  line-height: 1.65;
+  color: #909399;
+}
+.industry-form {
+  :deep(.el-form-item__label) {
+    font-weight: 500;
+    color: #606266;
+  }
+}
+.settlement-rate-text {
+  font-size: 14px;
+  color: #303133;
+}
+.field-stack {
+  width: 100%;
+}
+.field-tip {
+  margin: 8px 0 0;
+  font-size: 12px;
+  line-height: 1.65;
+  color: #909399;
+}
+.footer-actions {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  padding-top: 24px;
+  margin-top: 16px;
+  border-top: 1px solid #ebeef5;
+}
+.footer-center {
+  display: flex;
+  flex: 1;
+  justify-content: center;
+}
+.btn-next {
+  min-width: 100px;
+  background: $wechat-green;
+  border-color: $wechat-green;
+  &:hover {
+    background: #06ad56;
+    border-color: #06ad56;
+  }
+}
+</style>

+ 1114 - 0
src/views/businessInfo/manageInfo.vue

@@ -0,0 +1,1114 @@
+<template>
+  <div class="manage-info-page">
+    <h1 class="page-title">经营信息</h1>
+
+    <el-form
+      ref="formRef"
+      class="manage-form"
+      :model="form"
+      :rules="rules"
+      label-width="200px"
+      require-asterisk-position="right"
+      label-position="right"
+    >
+      <!-- 基础经营信息 -->
+      <section class="form-block">
+        <h2 class="section-head">
+          <span class="section-bar" aria-hidden="true" />
+          经营信息
+        </h2>
+
+        <el-form-item prop="merchantShortName">
+          <template #label>
+            <span class="label-with-icon">
+              商户简称
+              <el-tooltip placement="top" content="简称将展示给消费者,需与营业执照或品牌一致,勿使用无关或违规词汇。">
+                <el-icon class="info-icon" :size="16"><InfoFilled /></el-icon>
+              </el-tooltip>
+            </span>
+          </template>
+          <div class="field-stack">
+            <el-input
+              v-model="form.merchantShortName"
+              placeholder="请输入商户简称"
+              clearable
+              maxlength="64"
+              show-word-limit
+              style="max-width: 480px"
+            />
+            <p class="field-tip">
+              1. 在支付完成页向买家展示,需与微信经营类目相关。<br />
+              2.简称要求:<br />
+              不支持单纯以人名来命名,若为个体户经营,可用“个体户+经营者名称”或“经营者名称+业务”命名,如个体户“张三”或“张三餐饮店”;<br />
+              不支持无实际意义的文案,如“XX”特约商户,“800”,“XX客服电话XXX”;
+            </p>
+          </div>
+        </el-form-item>
+
+        <el-form-item prop="servicePhone">
+          <template #label>
+            <span class="label-with-icon">
+              客服电话
+              <el-tooltip placement="top" content="用于用户咨询与平台联系,请填写真实可接通号码。">
+                <el-icon class="info-icon" :size="16"><InfoFilled /></el-icon>
+              </el-tooltip>
+            </span>
+          </template>
+          <div class="field-stack">
+            <el-input
+              v-model="form.servicePhone"
+              placeholder="请输入客服电话"
+              clearable
+              maxlength="20"
+              style="max-width: 480px"
+            />
+            <p class="field-tip">
+              1.请填写真实、可接通的客服电话,以便用户咨询。<br />
+              2.请确保电话畅通,以便入驻平台回拨确认。<br />
+            </p>
+          </div>
+        </el-form-item>
+
+        <el-form-item label="经营场景" prop="scenarioBits" required>
+          <div class="field-stack">
+            <div class="scenario-checks">
+              <el-checkbox v-model="form.scenarios.offline"> 线下场景 </el-checkbox>
+              <el-checkbox v-model="form.scenarios.miniProgram"> 小程序 </el-checkbox>
+              <el-checkbox v-model="form.scenarios.app"> APP </el-checkbox>
+              <el-checkbox v-model="form.scenarios.wechatAccount"> 服务号或订阅号 </el-checkbox>
+              <el-checkbox v-model="form.scenarios.website"> 互联网网站 </el-checkbox>
+              <el-checkbox v-model="form.scenarios.wecom"> 企业微信 </el-checkbox>
+            </div>
+            <p class="field-tip">
+              请勾选实际售卖商品/提供服务场景(至少一项),以便为你开通需要的支付权限<br />
+              建议只勾选目前必须的尝尽,以便尽快通过入驻审核,其他支付权限你可在入驻后再根据实际需要发起申请
+            </p>
+          </div>
+        </el-form-item>
+      </section>
+
+      <!-- 线下场景 -->
+      <section v-if="form.scenarios.offline" class="form-block sub-section">
+        <h2 class="section-head">
+          <span class="section-bar" aria-hidden="true" />
+          线下场所
+          <span class="section-intro"
+            >你选择了“线下场所”场景,入驻成功后,服务商可帮商户发起付款码支付,JSAPI支付,同时系统将会对地址等信息进行核实</span
+          >
+        </h2>
+
+        <el-form-item label="线下场所名称" prop="offlineVenueName">
+          <el-input v-model="form.offlineVenueName" placeholder="请输入线下场所名称" clearable style="max-width: 480px" />
+        </el-form-item>
+
+        <el-form-item label="线下场所省市" prop="offlineProvinceCity">
+          <el-select v-model="form.offlineProvince" placeholder="请选择省" filterable style="width: 200px">
+            <el-option v-for="p in provinceOptions" :key="p.value" :label="p.label" :value="p.value" />
+          </el-select>
+          <el-select
+            v-model="form.offlineCity"
+            placeholder="请选择市"
+            filterable
+            style="width: 200px; margin-left: 12px"
+            :disabled="!form.offlineProvince"
+          >
+            <el-option v-for="c in cityOptions" :key="c.value" :label="c.label" :value="c.value" />
+          </el-select>
+        </el-form-item>
+
+        <el-form-item label="线下场所地址" prop="offlineAddress">
+          <div class="field-stack">
+            <el-input
+              v-model="form.offlineAddress"
+              type="textarea"
+              :rows="2"
+              placeholder="请输入详细地址"
+              maxlength="200"
+              show-word-limit
+              style="max-width: 480px"
+            />
+            <p class="field-tip">如有多个经营场所,请填写主要营业地址。</p>
+          </div>
+        </el-form-item>
+
+        <el-form-item prop="offlineStorefrontUrls">
+          <template #label>
+            <span class="label-with-icon">
+              线下场所门头照片
+              <el-tooltip placement="top" content="需清晰展示门头招牌与店名。">
+                <el-icon class="info-icon" :size="16"><InfoFilled /></el-icon>
+              </el-tooltip>
+            </span>
+          </template>
+          <div class="field-stack">
+            <el-upload
+              v-model:file-list="form.offlineStorefrontFileList"
+              list-type="picture-card"
+              :limit="5"
+              accept=".jpg,.jpeg,.png,.bmp,image/jpeg,image/png,image/bmp"
+              :before-upload="beforeImageUpload"
+              :http-request="opt => handleMultiUpload(opt, 'storefront')"
+              :on-remove="(f, fl) => onMultiRemove(f, fl, 'storefront')"
+            >
+              <el-icon><Plus /></el-icon>
+            </el-upload>
+            <p class="field-tip">
+              1.场景图片正面拍摄且清晰,完整,图片不得有遮挡;<br />
+              2.门店招牌清晰,招牌名称,文字可辨识,门框完整,且店面显示在营,若为停车场等无固定门头照片的经营场所,可上传岗亭/出入闸口。
+            </p>
+          </div>
+        </el-form-item>
+
+        <el-form-item prop="offlineInteriorUrls">
+          <template #label>
+            <span class="label-with-icon">
+              线下场所内部照片
+              <el-tooltip placement="top" content="展示店内经营环境。">
+                <el-icon class="info-icon" :size="16"><InfoFilled /></el-icon>
+              </el-tooltip>
+            </span>
+          </template>
+          <div class="field-stack">
+            <el-upload
+              v-model:file-list="form.offlineInteriorFileList"
+              list-type="picture-card"
+              :limit="5"
+              accept=".jpg,.jpeg,.png,.bmp,image/jpeg,image/png,image/bmp"
+              :before-upload="beforeImageUpload"
+              :http-request="opt => handleMultiUpload(opt, 'interior')"
+              :on-remove="(f, fl) => onMultiRemove(f, fl, 'interior')"
+            >
+              <el-icon><Plus /></el-icon>
+            </el-upload>
+            <p class="field-tip">
+              1.场景图片正面拍摄且清晰,完整,图片不得有遮挡;<br />
+              2.门店招牌清晰,招牌名称,文字可辨识,门框完整,且店面显示在营,若为停车场等无固定门头照片的经营场所,可上传岗亭/出入闸口。
+            </p>
+          </div>
+        </el-form-item>
+
+        <el-form-item label="线下场所对应的服务号或公众号 APPID">
+          <div class="field-stack">
+            <el-input v-model="form.offlineMpAppId" placeholder="选填" clearable style="max-width: 480px" />
+            <p class="field-tip">
+              1.可填写已认领的服务号或公众号(需时已认证的服务号,政府或媒体类型的公众号),小程序,应用的APPID.<br />
+              2.完成进件后,系统发起特约商户号与该APPID的绑定(即配置为sub_appid,可在发起支付时传入)<br />
+              (1)若APPID主体与商家主体一致,则直接完成绑定;<br />
+              (2)若APPID主体与商家主体不一致,则需商户提供主体变更证明材料,审核通过后完成绑定。
+            </p>
+          </div>
+        </el-form-item>
+      </section>
+
+      <!-- 小程序 -->
+      <section v-if="form.scenarios.miniProgram" class="form-block sub-section">
+        <h2 class="section-head">
+          <span class="section-bar" aria-hidden="true" />
+          小程序<span class="section-intro">你选择了“小程序”场景,入驻成功后,服务商可帮商户发起JSAPI支付</span>
+        </h2>
+
+        <el-form-item label="小程序 APPID" prop="miniProgramAppId">
+          <div class="field-stack">
+            <el-input v-model="form.miniProgramAppId" placeholder="请输入小程序 APPID" clearable style="max-width: 480px" />
+            <p class="field-tip">
+              1.请填写已认证小程序的 APPID。<br />
+              2.完成进件后,系统发起特约商户号与该APPID的绑定(即配置为sub_appid,可在发起支付时传入)<br />
+              (1)若APPID主体与商家主体一致,则直接完成绑定;<br />
+              (2)若APPID主体与商家主体不一致,则需商户提供主体变更证明材料,审核通过后完成绑定。
+            </p>
+          </div>
+        </el-form-item>
+
+        <el-form-item label="小程序截图">
+          <div class="field-stack">
+            <el-upload
+              v-model:file-list="form.miniProgramShotFileList"
+              list-type="picture-card"
+              :limit="5"
+              accept=".jpg,.jpeg,.png,.bmp,image/jpeg,image/png,image/bmp"
+              :before-upload="beforeImageUpload"
+              :http-request="opt => handleMultiUpload(opt, 'miniShot')"
+              :on-remove="(f, fl) => onMultiRemove(f, fl, 'miniShot')"
+            >
+              <el-icon><Plus /></el-icon>
+            </el-upload>
+            <p class="field-tip">请提供展示商品/服务的页面截图/设计稿(最多5张),若小程序胃建设完善或未上线请务必提供。</p>
+          </div>
+        </el-form-item>
+      </section>
+
+      <!-- APP -->
+      <section v-if="form.scenarios.app" class="form-block sub-section">
+        <h2 class="section-head">
+          <span class="section-bar" aria-hidden="true" />
+          APP<span class="section-intro">你选择了“APP”场景,入驻成功后,服务商可帮商户发起APP支付</span>
+        </h2>
+
+        <el-form-item label="AppID 来源" prop="appIdSource" required>
+          <el-radio-group v-model="form.appIdSource">
+            <el-radio value="provider"> 服务商应用 AppID </el-radio>
+            <el-radio value="merchant"> 商家应用 AppID </el-radio>
+          </el-radio-group>
+        </el-form-item>
+
+        <el-form-item v-if="form.appIdSource === 'provider'" label="服务商应用 AppID" prop="providerAppId">
+          <div class="field-stack">
+            <el-select v-model="form.providerAppId" placeholder="请选择" filterable style="max-width: 480px">
+              <el-option v-for="o in providerAppOptions" :key="o.value" :label="o.label" :value="o.value" />
+            </el-select>
+          </div>
+        </el-form-item>
+
+        <el-form-item prop="appShotUrls">
+          <template #label>
+            <span class="label-with-icon">
+              APP 截图
+              <el-tooltip placement="top" content="首页、商品列表、详情、支付等相关页面。">
+                <el-icon class="info-icon" :size="16"><InfoFilled /></el-icon>
+              </el-tooltip>
+            </span>
+          </template>
+          <div class="field-stack">
+            <el-upload
+              v-model:file-list="form.appShotFileList"
+              list-type="picture-card"
+              :limit="5"
+              accept=".jpg,.jpeg,.png,.bmp,image/jpeg,image/png,image/bmp"
+              :before-upload="beforeImageUpload"
+              :http-request="opt => handleMultiUpload(opt, 'appShot')"
+              :on-remove="(f, fl) => onMultiRemove(f, fl, 'appShot')"
+            >
+              <el-icon><Plus /></el-icon>
+            </el-upload>
+            <p class="field-tip">请提供APP首页截图,尾页截图,应用内截图,支付页截图各1张</p>
+          </div>
+        </el-form-item>
+      </section>
+    </el-form>
+
+    <div class="footer-actions">
+      <el-button @click="onBack"> 返回 </el-button>
+      <el-button type="primary" class="btn-next" :loading="submitLoading" @click="onSubmit"> 确定 </el-button>
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { computed, nextTick, onMounted, reactive, ref, watch } from "vue";
+import { useRoute, useRouter } from "vue-router";
+import { ElMessage } from "element-plus";
+import type { FormInstance, FormRules } from "element-plus";
+import type { UploadRequestOptions, UploadUserFile } from "element-plus";
+import { Plus, InfoFilled } from "@element-plus/icons-vue";
+import { getUpload } from "@/api/modules/businessInfo";
+import { localGet, localSet } from "@/utils/index";
+import cityJson from "@/assets/json/city.json";
+
+const BUSINESS_DATA_CACHE_KEY = "businessData";
+
+const formRef = ref<FormInstance>();
+const submitLoading = ref(false);
+const route = useRoute();
+const router = useRouter();
+
+type UploadKind = "storefront" | "interior" | "miniShot" | "appShot";
+
+const form = reactive({
+  merchantShortName: "",
+  servicePhone: "",
+  scenarios: {
+    offline: true,
+    miniProgram: true,
+    app: true,
+    wechatAccount: false,
+    website: false,
+    wecom: false
+  },
+  offlineVenueName: "",
+  offlineProvince: "",
+  offlineCity: "",
+  offlineAddress: "",
+  offlineStorefrontFileList: [] as UploadUserFile[],
+  offlineStorefrontUrls: [] as string[],
+  offlineInteriorFileList: [] as UploadUserFile[],
+  offlineInteriorUrls: [] as string[],
+  offlineMpAppId: "",
+  miniProgramAppId: "",
+  miniProgramShotFileList: [] as UploadUserFile[],
+  miniProgramShotUrls: [] as string[],
+  appIdSource: "provider" as "provider" | "merchant",
+  providerAppId: "",
+  merchantAppId: "",
+  appShotFileList: [] as UploadUserFile[],
+  appShotUrls: [] as string[],
+  /** 用于校验至少选一种经营场景 */
+  scenarioBits: "1"
+});
+
+/** 与进件文档 business_info.sales_info.sales_scenes_type 枚举对应 */
+function buildSalesScenesType(): string[] {
+  const s = form.scenarios;
+  const types: string[] = [];
+  if (s.offline) types.push("SALES_SCENES_STORE");
+  if (s.miniProgram) types.push("SALES_SCENES_MINI_PROGRAM");
+  if (s.app) types.push("SALES_SCENES_APP");
+  if (s.wechatAccount) types.push("SALES_SCENES_MP");
+  if (s.website) types.push("SALES_SCENES_WEB");
+  if (s.wecom) types.push("SALES_SCENES_WEWORK");
+  return types;
+}
+
+/** 上传组件更新 file-list 时可能丢 response,用 uid 备份 media_id */
+const wechatMediaIdByFileUid = new Map<number, string>();
+
+function getMediaIdFromUploadFile(f: UploadUserFile): string {
+  const tagged = String((f as UploadUserFile & { __wxMediaId?: string }).__wxMediaId ?? "").trim();
+  if (tagged) return tagged;
+  const uid = (f as UploadUserFile & { uid?: number }).uid;
+  if (uid != null && wechatMediaIdByFileUid.has(uid)) {
+    return wechatMediaIdByFileUid.get(uid) ?? "";
+  }
+  const r = (f as UploadUserFile & { response?: unknown }).response;
+  if (r && typeof r === "object" && !Array.isArray(r)) {
+    const o = r as Record<string, unknown>;
+    const direct = String(o.media_id ?? o.mediaId ?? "").trim();
+    if (direct) return direct;
+    const nested = extractMediaUploadMeta(r).mediaId;
+    if (nested) return nested;
+  }
+  return "";
+}
+
+/** 写入进件缓存的四处图片字段均为微信 media/upload 返回的 media_id */
+function collectMediaIdsForMerge(list: UploadUserFile[]): string[] {
+  return list
+    .filter(f => f.status === "success")
+    .map(f => getMediaIdFromUploadFile(f))
+    .filter(Boolean);
+}
+
+function mergeManageInfoIntoBusinessDataCache() {
+  const prev = localGet(BUSINESS_DATA_CACHE_KEY);
+  const base = prev && typeof prev === "object" && !Array.isArray(prev) ? { ...(prev as Record<string, unknown>) } : {};
+  const prevBi =
+    base.business_info && typeof base.business_info === "object" && !Array.isArray(base.business_info)
+      ? { ...(base.business_info as Record<string, unknown>) }
+      : {};
+  const prevSales =
+    prevBi.sales_info && typeof prevBi.sales_info === "object" && !Array.isArray(prevBi.sales_info)
+      ? { ...(prevBi.sales_info as Record<string, unknown>) }
+      : {};
+
+  const sales_info: Record<string, unknown> = {
+    ...prevSales,
+    sales_scenes_type: buildSalesScenesType()
+  };
+  if (form.scenarios.offline) {
+    sales_info.biz_store_info = {
+      biz_store_name: String(form.offlineVenueName || "").trim(),
+      biz_address_code: String(form.offlineCity || "").trim(),
+      biz_store_address: String(form.offlineAddress || "").trim(),
+      store_entrance_pic: collectMediaIdsForMerge(form.offlineStorefrontFileList),
+      indoor_pic: collectMediaIdsForMerge(form.offlineInteriorFileList),
+      biz_sub_appid: String(form.offlineMpAppId || "").trim()
+    };
+  } else {
+    delete sales_info.biz_store_info;
+  }
+
+  if (form.scenarios.miniProgram) {
+    sales_info.mini_program_info = {
+      mini_program_sub_appid: String(form.miniProgramAppId || "").trim(),
+      mini_program_pics: collectMediaIdsForMerge(form.miniProgramShotFileList)
+    };
+  } else {
+    delete sales_info.mini_program_info;
+  }
+
+  if (form.scenarios.app) {
+    sales_info.app_info = {
+      app_appid: String(form.providerAppId || "").trim(),
+      app_sub_appid: String(form.merchantAppId || "").trim(),
+      app_pics: collectMediaIdsForMerge(form.appShotFileList)
+    };
+  } else {
+    delete sales_info.app_info;
+  }
+
+  base.business_info = {
+    ...prevBi,
+    merchant_shortname: String(form.merchantShortName || "").trim(),
+    service_phone: String(form.servicePhone || "").trim(),
+    sales_info
+  };
+  localSet(BUSINESS_DATA_CACHE_KEY, base);
+}
+
+type CityJsonEntry = { name: string; adCode: string; cityCode: string; type?: string };
+type CityJsonRoot = { cityList: { letter: string; list: CityJsonEntry[] }[] };
+
+/** GB 行政区划代码前两位 → 省级名称(与 city.json 中 adCode 对应) */
+const PROVINCE_ROWS: [string, string][] = [
+  ["11", "北京市"],
+  ["12", "天津市"],
+  ["13", "河北省"],
+  ["14", "山西省"],
+  ["15", "内蒙古自治区"],
+  ["21", "辽宁省"],
+  ["22", "吉林省"],
+  ["23", "黑龙江省"],
+  ["31", "上海市"],
+  ["32", "江苏省"],
+  ["33", "浙江省"],
+  ["34", "安徽省"],
+  ["35", "福建省"],
+  ["36", "江西省"],
+  ["37", "山东省"],
+  ["41", "河南省"],
+  ["42", "湖北省"],
+  ["43", "湖南省"],
+  ["44", "广东省"],
+  ["45", "广西壮族自治区"],
+  ["46", "海南省"],
+  ["50", "重庆市"],
+  ["51", "四川省"],
+  ["52", "贵州省"],
+  ["53", "云南省"],
+  ["54", "西藏自治区"],
+  ["61", "陕西省"],
+  ["62", "甘肃省"],
+  ["63", "青海省"],
+  ["64", "宁夏回族自治区"],
+  ["65", "新疆维吾尔自治区"],
+  ["71", "台湾省"],
+  ["81", "香港特别行政区"],
+  ["82", "澳门特别行政区"]
+];
+const PROVINCE_BY_PREFIX = Object.fromEntries(PROVINCE_ROWS) as Record<string, string>;
+const PROVINCE_PREFIX_ORDER = PROVINCE_ROWS.map(([k]) => k);
+
+function buildProvinceCityOptions(): {
+  label: string;
+  value: string;
+  cities: { label: string; value: string }[];
+}[] {
+  const root = cityJson as CityJsonRoot;
+  const flat = root.cityList.flatMap(g => g.list);
+  const bucket = new Map<string, Map<string, CityJsonEntry>>();
+  for (const c of flat) {
+    const digits = String(c.adCode ?? "").replace(/\D/g, "");
+    const code = digits.length >= 6 ? digits.slice(-6) : digits.padStart(6, "0");
+    if (code.length !== 6) continue;
+    const prefix = code.slice(0, 2);
+    if (!PROVINCE_BY_PREFIX[prefix]) continue;
+    if (!bucket.has(prefix)) bucket.set(prefix, new Map());
+    bucket.get(prefix)!.set(c.adCode, c);
+  }
+  const out = [...bucket.entries()].map(([prefix, cityMap]) => ({
+    value: prefix,
+    label: PROVINCE_BY_PREFIX[prefix],
+    cities: [...cityMap.values()]
+      .sort((a, b) => a.name.localeCompare(b.name, "zh-CN"))
+      .map(ci => ({ label: ci.name, value: ci.adCode }))
+  }));
+  out.sort((a, b) => {
+    const ia = PROVINCE_PREFIX_ORDER.indexOf(a.value);
+    const ib = PROVINCE_PREFIX_ORDER.indexOf(b.value);
+    return (ia === -1 ? 999 : ia) - (ib === -1 ? 999 : ib);
+  });
+  return out;
+}
+
+const provinceOptions = buildProvinceCityOptions();
+
+const cityOptions = ref<{ label: string; value: string }[]>([]);
+
+watch(
+  () => form.offlineProvince,
+  code => {
+    form.offlineCity = "";
+    const p = provinceOptions.find(x => x.value === code);
+    cityOptions.value = p?.cities ?? [];
+  }
+);
+
+const providerAppOptions = [
+  { label: "请选择", value: "" },
+  { label: "wxf5f1efe3a9f5012e", value: "wxf5f1efe3a9f5012e" }
+];
+
+const scenarioChecked = computed(() => {
+  const s = form.scenarios;
+  return s.offline || s.miniProgram || s.app || s.wechatAccount || s.website || s.wecom;
+});
+
+watch(
+  () => form.scenarios,
+  () => {
+    form.scenarioBits = scenarioChecked.value ? "1" : "";
+  },
+  { deep: true }
+);
+
+function asStringArray(v: unknown): string[] {
+  if (!Array.isArray(v)) return [];
+  return v.map(x => String(x ?? "").trim()).filter(Boolean);
+}
+
+/** 从 localStorage businessData.business_info 回显经营信息表单 */
+function hydrateManageFormFromBusinessDataCache() {
+  const raw = localGet(BUSINESS_DATA_CACHE_KEY) as Record<string, unknown> | null | undefined;
+  if (!raw || typeof raw !== "object" || Array.isArray(raw)) return;
+  const bi = raw.business_info as Record<string, unknown> | undefined;
+  if (!bi || typeof bi !== "object" || Array.isArray(bi)) return;
+
+  form.merchantShortName = String(bi.merchant_shortname ?? "").trim();
+  form.servicePhone = String(bi.service_phone ?? "").trim();
+
+  let pendingOfflineCity = "";
+
+  const si = bi.sales_info as Record<string, unknown> | undefined;
+  if (si && typeof si === "object" && !Array.isArray(si)) {
+    const sceneTypes = si.sales_scenes_type;
+    if (Array.isArray(sceneTypes)) {
+      const set = new Set(sceneTypes.map(t => String(t)));
+      form.scenarios.offline = set.has("SALES_SCENES_STORE");
+      form.scenarios.miniProgram = set.has("SALES_SCENES_MINI_PROGRAM");
+      form.scenarios.app = set.has("SALES_SCENES_APP");
+      form.scenarios.wechatAccount = set.has("SALES_SCENES_MP");
+      form.scenarios.website = set.has("SALES_SCENES_WEB");
+      form.scenarios.wecom = set.has("SALES_SCENES_WEWORK");
+      form.scenarioBits = scenarioChecked.value ? "1" : "";
+    }
+
+    const bzs = si.biz_store_info as Record<string, unknown> | undefined;
+    if (bzs && typeof bzs === "object" && !Array.isArray(bzs)) {
+      form.offlineVenueName = String(bzs.biz_store_name ?? "").trim();
+      const digits = String(bzs.biz_address_code ?? "").replace(/\D/g, "");
+      const code6 = digits.length >= 6 ? digits.slice(-6) : digits;
+      if (code6.length >= 2) {
+        const prefix = code6.slice(0, 2);
+        form.offlineProvince = prefix;
+        const p = provinceOptions.find(x => x.value === prefix);
+        cityOptions.value = p?.cities ?? [];
+        if (code6.length >= 6) pendingOfflineCity = code6;
+      }
+      form.offlineAddress = String(bzs.biz_store_address ?? "").trim();
+      const se = asStringArray(bzs.store_entrance_pic);
+      const indoor = asStringArray(bzs.indoor_pic);
+      form.offlineStorefrontUrls = [...se];
+      form.offlineInteriorUrls = [...indoor];
+      form.offlineStorefrontFileList = se.map(
+        (url, i) =>
+          ({
+            name: `storefront-${i + 1}.jpg`,
+            url,
+            status: "success",
+            response: { url, media_id: url, mediaId: url },
+            __wxMediaId: url
+          }) as UploadUserFile
+      );
+      form.offlineInteriorFileList = indoor.map(
+        (url, i) =>
+          ({
+            name: `interior-${i + 1}.jpg`,
+            url,
+            status: "success",
+            response: { url, media_id: url, mediaId: url },
+            __wxMediaId: url
+          }) as UploadUserFile
+      );
+      form.offlineMpAppId = String(bzs.biz_sub_appid ?? "").trim();
+    }
+
+    const mpi = si.mini_program_info as Record<string, unknown> | undefined;
+    if (mpi && typeof mpi === "object" && !Array.isArray(mpi)) {
+      form.miniProgramAppId = String(mpi.mini_program_sub_appid ?? "").trim();
+      const pics = asStringArray(mpi.mini_program_pics);
+      form.miniProgramShotUrls = [...pics];
+      form.miniProgramShotFileList = pics.map(
+        (url, i) =>
+          ({
+            name: `mini-${i + 1}.jpg`,
+            url,
+            status: "success",
+            response: { url, media_id: url, mediaId: url },
+            __wxMediaId: url
+          }) as UploadUserFile
+      );
+    }
+
+    const appInf = si.app_info as Record<string, unknown> | undefined;
+    if (appInf && typeof appInf === "object" && !Array.isArray(appInf)) {
+      form.providerAppId = String(appInf.app_appid ?? "").trim();
+      form.merchantAppId = String(appInf.app_sub_appid ?? "").trim();
+      form.appIdSource = form.providerAppId ? "provider" : "merchant";
+      const pics = asStringArray(appInf.app_pics);
+      form.appShotUrls = [...pics];
+      form.appShotFileList = pics.map(
+        (url, i) =>
+          ({
+            name: `app-${i + 1}.jpg`,
+            url,
+            status: "success",
+            response: { url, media_id: url, mediaId: url },
+            __wxMediaId: url
+          }) as UploadUserFile
+      );
+    }
+  }
+
+  nextTick(() => {
+    if (pendingOfflineCity) form.offlineCity = pendingOfflineCity;
+    formRef.value?.clearValidate();
+  });
+}
+
+onMounted(() => {
+  hydrateManageFormFromBusinessDataCache();
+});
+
+const rules: FormRules = {
+  merchantShortName: [{ required: true, message: "请输入商户简称", trigger: "blur" }],
+  servicePhone: [
+    { required: true, message: "请输入客服电话", trigger: "blur" },
+    { pattern: /^[\d\-+\s]{5,20}$/, message: "请输入有效电话号码", trigger: "blur" }
+  ],
+  scenarioBits: [{ required: true, message: "请至少选择一种经营场景", trigger: "change" }],
+  offlineVenueName: [
+    {
+      validator: (_r, _v, cb) => {
+        if (form.scenarios.offline && !String(form.offlineVenueName).trim()) {
+          cb(new Error("请输入线下场所名称"));
+        } else cb();
+      },
+      trigger: "blur"
+    }
+  ],
+  offlineProvinceCity: [
+    {
+      validator: (_r, _v, cb) => {
+        if (form.scenarios.offline && (!form.offlineProvince || !form.offlineCity)) {
+          cb(new Error("请选择线下场所省市"));
+        } else cb();
+      },
+      trigger: "change"
+    }
+  ],
+  offlineAddress: [
+    {
+      validator: (_r, _v, cb) => {
+        if (form.scenarios.offline && !String(form.offlineAddress).trim()) {
+          cb(new Error("请输入线下场所地址"));
+        } else cb();
+      },
+      trigger: "blur"
+    }
+  ],
+  offlineStorefrontUrls: [
+    {
+      validator: (_r, _v, cb) => {
+        if (form.scenarios.offline && form.offlineStorefrontUrls.length < 1) {
+          cb(new Error("请上传门头照片"));
+        } else cb();
+      },
+      trigger: "change"
+    }
+  ],
+  offlineInteriorUrls: [
+    {
+      validator: (_r, _v, cb) => {
+        if (form.scenarios.offline && form.offlineInteriorUrls.length < 1) {
+          cb(new Error("请上传内部照片"));
+        } else cb();
+      },
+      trigger: "change"
+    }
+  ],
+  miniProgramAppId: [
+    {
+      validator: (_r, _v, cb) => {
+        if (form.scenarios.miniProgram && !String(form.miniProgramAppId).trim()) {
+          cb(new Error("请输入小程序 APPID"));
+        } else cb();
+      },
+      trigger: "blur"
+    }
+  ],
+  providerAppId: [
+    {
+      validator: (_r, _v, cb) => {
+        if (form.scenarios.app && form.appIdSource === "provider" && !String(form.providerAppId).trim()) {
+          cb(new Error("请选择服务商应用 AppID"));
+        } else cb();
+      },
+      trigger: "change"
+    }
+  ],
+  appShotUrls: [
+    {
+      validator: (_r, _v, cb) => {
+        if (form.scenarios.app && form.appShotUrls.length < 1) {
+          cb(new Error("请上传 APP 截图"));
+        } else cb();
+      },
+      trigger: "change"
+    }
+  ]
+};
+
+const MAX_IMG_MB = 5;
+
+function beforeImageUpload(file: File) {
+  const name = file.name?.toLowerCase() || "";
+  const okExt = /\.(jpe?g|png|bmp)$/i.test(name);
+  const okMime = ["image/jpeg", "image/png", "image/bmp"].includes(file.type);
+  if (!okExt && !okMime) {
+    ElMessage.error("图片只支持 JPG、BMP、PNG 格式");
+    return false;
+  }
+  if (file.size / 1024 / 1024 > MAX_IMG_MB) {
+    ElMessage.error(`文件大小不能超过 ${MAX_IMG_MB}M`);
+    return false;
+  }
+  return true;
+}
+
+function urlListKey(kind: UploadKind): "offlineStorefrontUrls" | "offlineInteriorUrls" | "miniProgramShotUrls" | "appShotUrls" {
+  const map = {
+    storefront: "offlineStorefrontUrls",
+    interior: "offlineInteriorUrls",
+    miniShot: "miniProgramShotUrls",
+    appShot: "appShotUrls"
+  } as const;
+  return map[kind];
+}
+
+/** 解析 getUpload 响应:兼容 data 为字符串、双层 data、嵌套对象等 */
+function extractMediaUploadMeta(res: any): { fileUrl: string; mediaId: string; errMsg: string } {
+  const errMsg = String(res?.msg ?? res?.message ?? res?.data?.msg ?? res?.data?.message ?? "").trim();
+
+  const pickFromObject = (node: any): { fileUrl: string; mediaId: string } => {
+    if (!node || typeof node !== "object" || Array.isArray(node)) return { fileUrl: "", mediaId: "" };
+    const mediaId = String(node.media_id ?? node.mediaId ?? node.MediaId ?? "").trim();
+    const fileUrl = String(node.url ?? node.fileUrl ?? node.mediaUrl ?? node.picUrl ?? "").trim();
+    return { fileUrl, mediaId };
+  };
+
+  let root = res;
+  const rawData = root?.data;
+  if (rawData != null && typeof rawData === "string") {
+    const s = rawData.trim();
+    if (s.startsWith("{") || s.startsWith("[")) {
+      try {
+        root = { ...(root && typeof root === "object" ? root : {}), data: JSON.parse(s) };
+      } catch {
+        return { fileUrl: "", mediaId: s, errMsg };
+      }
+    } else if (s) {
+      return { fileUrl: "", mediaId: s, errMsg };
+    }
+  }
+
+  const candidates: any[] = [];
+  const push = (x: any) => {
+    if (x != null) candidates.push(x);
+  };
+  push(root);
+  push(root?.data);
+  if (root?.data != null && typeof root.data === "object" && !Array.isArray(root.data)) {
+    push(root.data.data);
+    for (const v of Object.values(root.data)) {
+      if (v && typeof v === "object" && !Array.isArray(v)) push(v);
+    }
+  }
+
+  let fileUrl = "";
+  let mediaId = "";
+  for (const c of candidates) {
+    if (typeof c === "string" && c.trim()) {
+      mediaId = c.trim();
+      break;
+    }
+    if (!c || typeof c !== "object") continue;
+    const p = pickFromObject(c);
+    if (p.mediaId) {
+      mediaId = p.mediaId;
+      fileUrl = p.fileUrl || fileUrl;
+      break;
+    }
+    for (const v of Object.values(c)) {
+      if (v && typeof v === "object" && !Array.isArray(v)) {
+        const p2 = pickFromObject(v);
+        if (p2.mediaId) {
+          mediaId = p2.mediaId;
+          fileUrl = p2.fileUrl || fileUrl;
+          break;
+        }
+      }
+    }
+    if (mediaId) break;
+  }
+
+  return { fileUrl, mediaId, errMsg };
+}
+
+async function handleMultiUpload(options: UploadRequestOptions, kind: UploadKind) {
+  const uploadFileItem = options.file as UploadUserFile;
+  const raw = uploadFileItem.raw || uploadFileItem;
+  const file = raw instanceof File ? raw : null;
+  if (!file) return;
+
+  uploadFileItem.status = "uploading";
+  try {
+    const fd = new FormData();
+    fd.append("file", file);
+    const res: any = await getUpload(fd);
+    const { fileUrl, mediaId, errMsg } = extractMediaUploadMeta(res);
+    if (mediaId) {
+      uploadFileItem.status = "success";
+      if (fileUrl) uploadFileItem.url = fileUrl;
+      uploadFileItem.response = { media_id: mediaId, url: fileUrl };
+      const uid = (uploadFileItem as UploadUserFile & { uid?: number }).uid;
+      if (uid != null) wechatMediaIdByFileUid.set(uid, mediaId);
+      (uploadFileItem as UploadUserFile & { __wxMediaId?: string }).__wxMediaId = mediaId;
+    } else {
+      uploadFileItem.status = "fail";
+      ElMessage.error(errMsg || "上传失败,未返回 media_id");
+    }
+  } catch {
+    uploadFileItem.status = "fail";
+  }
+  syncUrlsFromFileList(kind);
+  validateKind(kind);
+}
+
+function syncUrlsFromFileList(kind: UploadKind) {
+  const key = urlListKey(kind);
+  let list: UploadUserFile[] = [];
+  if (kind === "storefront") list = form.offlineStorefrontFileList;
+  else if (kind === "interior") list = form.offlineInteriorFileList;
+  else if (kind === "miniShot") list = form.miniProgramShotFileList;
+  else list = form.appShotFileList;
+
+  form[key] = list
+    .map(f => {
+      const fu = f as UploadUserFile & { url?: string; response?: { url?: string } };
+      const mid = getMediaIdFromUploadFile(f);
+      const url = String(fu.url ?? fu.response?.url ?? "").trim();
+      return mid || url;
+    })
+    .filter(Boolean) as string[];
+}
+
+function onMultiRemove(file: UploadUserFile, _fileList: UploadUserFile[], kind: UploadKind) {
+  const uid = (file as UploadUserFile & { uid?: number }).uid;
+  if (uid != null) wechatMediaIdByFileUid.delete(uid);
+  delete (file as UploadUserFile & { __wxMediaId?: string }).__wxMediaId;
+  syncUrlsFromFileList(kind);
+  validateKind(kind);
+}
+
+function syncAllUploadUrlArrays() {
+  syncUrlsFromFileList("storefront");
+  syncUrlsFromFileList("interior");
+  syncUrlsFromFileList("miniShot");
+  syncUrlsFromFileList("appShot");
+}
+
+function assertActiveScenarioPicsHaveMediaId(): boolean {
+  const groups: { label: string; list: UploadUserFile[] }[] = [];
+  if (form.scenarios.offline) {
+    groups.push({ label: "门头照片", list: form.offlineStorefrontFileList });
+    groups.push({ label: "内部照片", list: form.offlineInteriorFileList });
+  }
+  if (form.scenarios.miniProgram) {
+    groups.push({ label: "小程序截图", list: form.miniProgramShotFileList });
+  }
+  if (form.scenarios.app) {
+    groups.push({ label: "APP 截图", list: form.appShotFileList });
+  }
+  for (const g of groups) {
+    for (const f of g.list) {
+      if (f.status !== "success") continue;
+      if (!getMediaIdFromUploadFile(f)) {
+        ElMessage.warning(`「${g.label}」须使用微信素材上传接口返回的 media_id,请删除后重新上传`);
+        return false;
+      }
+    }
+  }
+  return true;
+}
+
+function validateKind(kind: UploadKind) {
+  const map: Partial<Record<UploadKind, string>> = {
+    storefront: "offlineStorefrontUrls",
+    interior: "offlineInteriorUrls",
+    appShot: "appShotUrls"
+  };
+  const f = map[kind];
+  if (f) formRef.value?.validateField(f).catch(() => {});
+}
+
+function openScenarioGuide() {
+  ElMessage.info("经营场景填写指引(可对接文档)");
+}
+function openStorefrontGuide() {
+  ElMessage.info("门头照片拍摄指引");
+}
+function openAppidGuide() {
+  ElMessage.info("公众号 APPID 查找说明");
+}
+function openMiniAppidGuide() {
+  ElMessage.info("小程序 APPID 说明");
+}
+function openProviderAppGuide() {
+  ElMessage.info("服务商应用说明");
+}
+function openMerchantAppGuide() {
+  ElMessage.info("商家应用说明");
+}
+function openAppShotExample() {
+  ElMessage.info("APP 截图示例");
+}
+
+function onBack() {
+  router.push({ path: "/businessInfo/dataEntry", query: { ...route.query } });
+}
+
+function onSaveDraft() {
+  ElMessage.success("草稿已保存(可对接接口)");
+}
+
+async function onSubmit() {
+  if (!formRef.value) return;
+  submitLoading.value = true;
+  try {
+    await formRef.value.validate();
+    syncAllUploadUrlArrays();
+    if (!assertActiveScenarioPicsHaveMediaId()) return;
+    mergeManageInfoIntoBusinessDataCache();
+    await router.push({
+      path: "/businessInfo/industryQualifications",
+      query: { ...route.query }
+    });
+  } catch {
+    ElMessage.warning("请完善必填信息");
+  } finally {
+    submitLoading.value = false;
+  }
+}
+</script>
+
+<style scoped lang="scss">
+$wechat-green: #07c160;
+.manage-info-page {
+  box-sizing: border-box;
+  min-height: 100%;
+  padding: 24px 32px 40px;
+  margin: 0 auto;
+  background: #ffffff;
+}
+.page-title {
+  margin: 0 0 24px;
+  font-size: 20px;
+  font-weight: 600;
+  color: #303133;
+}
+.manage-form {
+  :deep(.el-form-item__label) {
+    font-weight: 500;
+    color: #606266;
+  }
+}
+.form-block {
+  padding-bottom: 16px;
+  margin-bottom: 28px;
+  border-bottom: 1px solid #ebeef5;
+  &:last-of-type {
+    border-bottom: none;
+  }
+}
+.sub-section {
+  padding: 8px 16px 20px;
+  margin-top: 8px;
+  background: #fafafa;
+  border: 1px solid #ebeef5;
+  border-radius: 8px;
+}
+.section-head {
+  display: flex;
+  align-items: center;
+  margin: 16px 0 20px;
+  font-size: 16px;
+  font-weight: 600;
+  color: #303133;
+}
+.section-bar {
+  display: inline-block;
+  flex-shrink: 0;
+  width: 4px;
+  height: 16px;
+  margin-right: 8px;
+  background: $wechat-green;
+  border-radius: 2px;
+}
+.section-intro {
+  padding-left: 20px;
+  font-size: 12px;
+  color: #999999;
+}
+.field-stack {
+  width: 100%;
+}
+.field-tip {
+  margin: 8px 0 0;
+  font-size: 12px;
+  line-height: 1.65;
+  color: #909399;
+}
+.scenario-checks {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 12px 20px;
+  margin-bottom: 8px;
+}
+.label-with-icon {
+  display: inline-flex;
+  gap: 4px;
+  align-items: center;
+}
+.info-icon {
+  color: #909399;
+  cursor: help;
+}
+:deep(.el-upload--picture-card) {
+  --el-upload-picture-card-size: 120px;
+}
+:deep(.el-upload-list--picture-card .el-upload-list__item) {
+  width: 120px;
+  height: 120px;
+}
+.footer-actions {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  padding-top: 24px;
+  margin-top: 16px;
+  border-top: 1px solid #ebeef5;
+}
+.footer-center {
+  display: flex;
+  flex: 1;
+  justify-content: center;
+}
+.btn-next {
+  min-width: 100px;
+  background: $wechat-green;
+  border-color: $wechat-green;
+  &:hover {
+    background: #06ad56;
+    border-color: #06ad56;
+  }
+}
+</style>

+ 1149 - 0
src/views/businessInfo/subjectInfo.vue

@@ -0,0 +1,1149 @@
+<template>
+  <div class="subject-info-page">
+    <h1 class="page-title">主体信息</h1>
+
+    <el-form
+      ref="formRef"
+      class="subject-form"
+      :model="form"
+      :rules="rules"
+      label-width="140px"
+      require-asterisk-position="right"
+      label-position="right"
+    >
+      <!-- 主体身份 -->
+      <section class="form-block">
+        <h2 class="section-head">
+          <span class="section-bar" aria-hidden="true" />
+          主体身份 <span class="section-intro">请上传「营业执照」,需年检章齐全,当年注册除外</span>
+        </h2>
+
+        <!-- <el-form-item label="是否金融机构" prop="isFinancialInstitution">
+          <div class="field-stack">
+            <el-select v-model="form.isFinancialInstitution" placeholder="请选择" style="width: 260px">
+              <el-option label="否" :value="0" />
+              <el-option label="是" :value="1" />
+            </el-select>
+            <p class="field-tip">
+              金融机构是指从事金融类业务的机构,如信贷、融资、理财、担保、信托、货币兑换等。
+            </p>
+          </div>
+        </el-form-item> -->
+
+        <el-form-item prop="businessLicenseUrl">
+          <template #label>
+            <span class="label-with-icon">
+              营业执照照片
+              <el-tooltip placement="top" content="请上传清晰、完整的营业执照照片,需与后续填写信息一致。">
+                <el-icon class="info-icon" :size="16"><InfoFilled /></el-icon>
+              </el-tooltip>
+            </span>
+          </template>
+          <div class="license-upload-wrap">
+            <el-upload
+              v-model:file-list="form.businessLicenseFileList"
+              list-type="picture-card"
+              :limit="1"
+              accept=".jpg,.jpeg,.png,.bmp,image/jpeg,image/png,image/bmp"
+              :before-upload="beforeLicenseUpload"
+              :http-request="handleLicenseUpload"
+              :on-remove="onLicenseRemove"
+            >
+              <el-icon><Plus /></el-icon>
+            </el-upload>
+            <!-- <div class="license-example" aria-hidden="true" style="border:1px solid red;">
+              <div class="license-example-thumb">
+                <span class="license-example-placeholder">营业执照</span>
+              </div>
+            </div> -->
+          </div>
+          <div class="upload-rules">
+            <p>
+              1.
+              请上传彩色照片或彩色扫描件或加盖公章鲜章的复印件,要求正面拍摄,露出证件四角且清晰、完整,所有字符清晰可识别,不得反光或遮挡。不得翻拍、截图、镜像、PS。
+            </p>
+            <p>2. 图片只支持 JPG、BMP、PNG 格式,文件大小不能超过 5M。</p>
+          </div>
+        </el-form-item>
+        <div v-if="hasBusinessLicenseOcr" class="license-ocr-result">
+          <div v-if="businessLicenseOcr.creditCode" class="license-ocr-row">
+            <span class="license-ocr-label">统一社会信用代码</span>
+            <span class="license-ocr-value">{{ businessLicenseOcr.creditCode }}</span>
+          </div>
+          <div v-if="businessLicenseOcr.companyName" class="license-ocr-row">
+            <span class="license-ocr-label">企业名称</span>
+            <span class="license-ocr-value">{{ businessLicenseOcr.companyName }}</span>
+          </div>
+          <div v-if="businessLicenseOcr.legalPerson" class="license-ocr-row">
+            <span class="license-ocr-label">法定代表人</span>
+            <span class="license-ocr-value">{{ businessLicenseOcr.legalPerson }}</span>
+          </div>
+        </div>
+      </section>
+
+      <!-- 法定代表人证件 -->
+      <section class="form-block">
+        <h2 class="section-head">
+          <span class="section-bar" aria-hidden="true" />
+          法定代表人证件
+          <span class="section-intro">请上传法定代表人的证件信息</span>
+        </h2>
+
+        <el-form-item label="证件类型" prop="legalIdType">
+          <div class="field-stack">
+            <el-select v-model="form.legalIdType" placeholder="请选择" clearable style="width: 260px">
+              <el-option label="居民身份证" value="id_card" />
+              <el-option label="护照" value="passport" />
+              <el-option label="港澳居民来往内地通行证" value="hk_macau_pass" />
+              <el-option label="台湾居民来往大陆通行证" value="taiwan_pass" />
+            </el-select>
+          </div>
+        </el-form-item>
+
+        <!-- 居民身份证:人像面 / 国徽面 -->
+        <template v-if="form.legalIdType === 'id_card'">
+          <el-form-item prop="idPortraitUrl">
+            <template #label>
+              <span class="label-with-icon">
+                身份证人像面照片
+                <el-tooltip placement="top" content="请上传身份证人像面(带头像一面)清晰彩色照片。">
+                  <el-icon class="info-icon" :size="16"><InfoFilled /></el-icon>
+                </el-tooltip>
+              </span>
+            </template>
+            <div class="license-upload-wrap">
+              <el-upload
+                v-model:file-list="form.idPortraitFileList"
+                list-type="picture-card"
+                :limit="1"
+                accept=".jpg,.jpeg,.png,.bmp,image/jpeg,image/png,image/bmp"
+                :before-upload="beforeLicenseUpload"
+                :http-request="opt => handleIdCardUpload(opt, 'portrait')"
+                :on-remove="(_f, fl) => onIdCardRemove(fl, 'portrait')"
+              >
+                <el-icon><Plus /></el-icon>
+              </el-upload>
+              <!-- <div class="license-example" aria-hidden="true">
+                <div class="license-example-thumb id-example-thumb">
+                  <span class="license-example-badge">示例</span>
+                  <span class="license-example-placeholder">人像面</span>
+                </div>
+              </div> -->
+            </div>
+            <div class="upload-rules">
+              <p>
+                1. 请上传彩色照片 or 彩色扫描件 or
+                加盖公章鲜章的复印件,要求正面拍摄,露出证件四角且清晰、完整,所有字符清晰可识别,不得反光或遮挡。不得翻拍、截图、镜像、PS。
+              </p>
+              <p>2. 图片只支持 JPG、BMP、PNG 格式,文件大小不能超过 5M。</p>
+            </div>
+          </el-form-item>
+
+          <el-form-item prop="idEmblemUrl">
+            <template #label>
+              <span class="label-with-icon">
+                身份证国徽面照片
+                <el-tooltip placement="top" content="请上传身份证国徽面清晰彩色照片。">
+                  <el-icon class="info-icon" :size="16"><InfoFilled /></el-icon>
+                </el-tooltip>
+              </span>
+            </template>
+            <div class="license-upload-wrap">
+              <el-upload
+                v-model:file-list="form.idEmblemFileList"
+                list-type="picture-card"
+                :limit="1"
+                accept=".jpg,.jpeg,.png,.bmp,image/jpeg,image/png,image/bmp"
+                :before-upload="beforeLicenseUpload"
+                :http-request="opt => handleIdCardUpload(opt, 'emblem')"
+                :on-remove="(_f, fl) => onIdCardRemove(fl, 'emblem')"
+              >
+                <el-icon><Plus /></el-icon>
+              </el-upload>
+              <!-- <div class="license-example" aria-hidden="true">
+                <div class="license-example-thumb id-example-thumb">
+                  <span class="license-example-badge">示例</span>
+                  <span class="license-example-placeholder">国徽面</span>
+                </div>
+              </div> -->
+            </div>
+            <div class="upload-rules">
+              <p>
+                1. 请上传彩色照片 or 彩色扫描件 or
+                加盖公章鲜章的复印件,要求正面拍摄,露出证件四角且清晰、完整,所有字符清晰可识别,不得反光或遮挡。不得翻拍、截图、镜像、PS。
+              </p>
+              <p>2. 图片只支持 JPG、BMP、PNG 格式,文件大小不能超过 5M。</p>
+            </div>
+
+            <div v-if="showIdPortraitOcrBlock" class="ocr-result-container">
+              <div v-if="isIdPortraitOcrProcessing" class="ocr-result-item">
+                <span class="label">识别中:</span>
+                <span class="value">正在识别身份证信息,请稍候...</span>
+              </div>
+              <template v-else>
+                <div v-if="idPortraitOcr.name" class="ocr-result-item">
+                  <span class="label">姓名:</span>
+                  <span class="value">{{ idPortraitOcr.name }}</span>
+                </div>
+                <div v-if="idPortraitOcr.idNumber" class="ocr-result-item">
+                  <span class="label">身份证号:</span>
+                  <span class="value">{{ idPortraitOcr.idNumber }}</span>
+                </div>
+                <div v-if="idCardValidityDisplay" class="ocr-result-item">
+                  <span class="label">身份证有效期:</span>
+                  <span class="value">{{ idCardValidityDisplay }}</span>
+                </div>
+                <div v-if="!idPortraitOcr.name && !idPortraitOcr.idNumber && !idCardValidityDisplay" class="ocr-result-tip">
+                  请等待身份证识别完成
+                </div>
+              </template>
+            </div>
+          </el-form-item>
+
+          <p class="ubo-footer-tip">
+            平台将通过外部渠道核验该法人是否为受益人,若通过,将使用法人信息作为该主体的受益人(UBO)信息
+          </p>
+        </template>
+      </section>
+    </el-form>
+
+    <div class="footer-actions">
+      <el-button @click="onBack"> 返回 </el-button>
+      <el-button type="primary" class="btn-next" :loading="nextLoading" @click="onNext"> 确定 </el-button>
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { computed, nextTick, onMounted, reactive, ref, watch } from "vue";
+import { useRoute, useRouter } from "vue-router";
+import { ElMessage } from "element-plus";
+import type { FormInstance, FormRules } from "element-plus";
+import type { UploadRequestOptions, UploadUserFile } from "element-plus";
+import { Plus, InfoFilled } from "@element-plus/icons-vue";
+import { getOcrRequestByBase64, getUpload } from "@/api/modules/businessInfo";
+import { localGet, localSet } from "@/utils/index";
+
+const BUSINESS_DATA_CACHE_KEY = "businessData";
+
+const formRef = ref<FormInstance>();
+const nextLoading = ref(false);
+const route = useRoute();
+const router = useRouter();
+
+const businessLicenseOcr = reactive({
+  creditCode: "",
+  companyName: "",
+  legalPerson: ""
+});
+
+const hasBusinessLicenseOcr = computed(
+  () => !!(businessLicenseOcr.creditCode || businessLicenseOcr.companyName || businessLicenseOcr.legalPerson)
+);
+
+function clearBusinessLicenseOcr() {
+  businessLicenseOcr.creditCode = "";
+  businessLicenseOcr.companyName = "";
+  businessLicenseOcr.legalPerson = "";
+}
+
+/** 从 ocrRequestByBase64 成功响应中取出 creditCode / companyName / legalPerson */
+function pickBusinessLicenseOcrFields(res: any) {
+  const raw = res?.data ?? res;
+  let node: any = raw;
+  if (node && typeof node === "object" && "data" in node && node.data !== undefined) {
+    node = node.data;
+  }
+  const item = Array.isArray(node) ? node[0] : node;
+  if (!item || typeof item !== "object") {
+    return { creditCode: "", companyName: "", legalPerson: "" };
+  }
+  return {
+    creditCode: String(item.creditCode ?? item.credit_code ?? "").trim(),
+    companyName: String(item.companyName ?? item.company_name ?? "").trim(),
+    legalPerson: String(item.legalPerson ?? item.legal_person ?? "").trim()
+  };
+}
+
+/** 身份证有效期文案 → YYYY-MM-DD */
+function splitIdCardValidPeriod(raw: string): { begin: string; end: string } {
+  const s = (raw || "").trim();
+  if (!s) return { begin: "", end: "" };
+  if (/长期|长期有效/.test(s)) return { begin: "", end: "长期" };
+  const norm = s
+    .replace(/年|月|日/g, ".")
+    .replace(/\.+/g, ".")
+    .trim();
+  const parts = norm.split(/[-至~~]/);
+  const normOne = (p: string) => {
+    const m = p.trim().match(/(\d{4})\D*(\d{1,2})\D*(\d{1,2})/);
+    if (m) return `${m[1]}-${m[2].padStart(2, "0")}-${m[3].padStart(2, "0")}`;
+    return p.trim();
+  };
+  if (parts.length >= 2) {
+    return { begin: normOne(parts[0]), end: normOne(parts[1]) };
+  }
+  return { begin: "", end: "" };
+}
+
+/** 人像面 getOcrRequestByBase64(ID_CARD) 成功响应 */
+function pickIdCardPortraitOcrFields(res: any): {
+  name: string;
+  idNumber: string;
+  idCardAddress: string;
+  cardPeriodBegin: string;
+  cardPeriodEnd: string;
+} {
+  const raw = res?.data ?? res;
+  let node: any = raw;
+  if (node && typeof node === "object" && "data" in node && node.data !== undefined) {
+    node = node.data;
+  }
+  const arr = Array.isArray(node) ? node : [node];
+  const item = arr[0];
+  const item2 = arr[1];
+  if (!item || typeof item !== "object") {
+    return { name: "", idNumber: "", idCardAddress: "", cardPeriodBegin: "", cardPeriodEnd: "" };
+  }
+  let name = String(item.name ?? item.userName ?? "").trim();
+  let idNumber = String(item.idNumber ?? item.id_number ?? item.idCard ?? item.id_card ?? "").trim();
+  const faceData = item.face?.data || item2?.face?.data;
+  const backData = item.back?.data || item2?.back?.data;
+  if (faceData && typeof faceData === "object") {
+    if (!name) name = String(faceData.name ?? "").trim();
+    if (!idNumber) idNumber = String(faceData.idNumber ?? faceData.id_number ?? "").trim();
+  }
+  let idCardAddress = "";
+  if (backData && typeof backData === "object") {
+    idCardAddress = String(backData.address ?? backData.registeredAddress ?? backData.issueAuthority ?? "").trim();
+  }
+  if (faceData && typeof faceData === "object" && !idCardAddress) {
+    idCardAddress = String(faceData.address ?? "").trim();
+  }
+  const faceKv = item.face?.prism_keyValueInfo || item2?.face?.prism_keyValueInfo;
+  if (Array.isArray(faceKv)) {
+    for (const row of faceKv) {
+      if (row?.key === "name" && row?.value && !name) name = String(row.value).trim();
+      if (row?.key === "idNumber" && row?.value && !idNumber) idNumber = String(row.value).trim();
+      if (row?.key === "address" && row?.value && !idCardAddress) {
+        idCardAddress = String(row.value).trim();
+      }
+    }
+  }
+  const backKv = item.back?.prism_keyValueInfo || item2?.back?.prism_keyValueInfo;
+  let validPeriodFromKv = "";
+  if (Array.isArray(backKv)) {
+    for (const row of backKv) {
+      if (row?.key === "address" && row?.value && !idCardAddress) {
+        idCardAddress = String(row.value).trim();
+      }
+      if (row?.value) {
+        const keyRaw = String(row.key || "");
+        if (/有效期限|有效期|失效日期|签发日期|validPeriod|validDate|valid_period/i.test(keyRaw)) {
+          const v = String(row.value).trim();
+          if (v && !validPeriodFromKv) validPeriodFromKv = v;
+        }
+      }
+    }
+  }
+  let vp = String(
+    (backData && (backData.validPeriod ?? backData.validDate)) ||
+      (faceData && (faceData.validPeriod ?? faceData.validDate)) ||
+      (item && (item.validPeriod ?? item.validDate)) ||
+      (item2 && (item2.validPeriod ?? item2.validDate)) ||
+      ""
+  ).trim();
+  if (!vp && validPeriodFromKv) vp = validPeriodFromKv;
+  const { begin: cardPeriodBegin, end: cardPeriodEnd } = splitIdCardValidPeriod(vp);
+  return { name, idNumber, idCardAddress, cardPeriodBegin, cardPeriodEnd };
+}
+
+const form = reactive<{
+  isFinancialInstitution: number;
+  businessLicenseFileList: UploadUserFile[];
+  businessLicenseUrl: string;
+  legalIdType: string;
+  idPortraitFileList: UploadUserFile[];
+  idEmblemFileList: UploadUserFile[];
+  idPortraitUrl: string;
+  idEmblemUrl: string;
+}>({
+  isFinancialInstitution: 0,
+  businessLicenseFileList: [],
+  businessLicenseUrl: "",
+  legalIdType: "id_card",
+  idPortraitFileList: [],
+  idEmblemFileList: [],
+  idPortraitUrl: "",
+  idEmblemUrl: ""
+});
+
+const idPortraitOcr = reactive({
+  name: "",
+  idNumber: "",
+  idCardAddress: "",
+  cardPeriodBegin: "",
+  cardPeriodEnd: ""
+});
+
+const isIdPortraitOcrProcessing = ref(false);
+
+const hasPortraitUploadSuccess = computed(() => {
+  const f = form.idPortraitFileList[0];
+  return f?.status === "success";
+});
+
+const hasEmblemUploadSuccess = computed(() => {
+  const f = form.idEmblemFileList[0];
+  return f?.status === "success";
+});
+
+/** 身份证有效期展示(国徽面 OCR 主要提供) */
+const idCardValidityDisplay = computed(() => {
+  const b = (idPortraitOcr.cardPeriodBegin || "").trim();
+  const e = (idPortraitOcr.cardPeriodEnd || "").trim();
+  if (b && e) return e === "长期" ? `${b} 至 长期` : `${b} 至 ${e}`;
+  if (e === "长期" && !b) return "长期";
+  if (b && !e) return b;
+  if (!b && e) return e;
+  return "";
+});
+
+const hasIdPortraitOcrDisplay = computed(() => !!(idPortraitOcr.name || idPortraitOcr.idNumber || idCardValidityDisplay.value));
+
+const showIdPortraitOcrBlock = computed(
+  () =>
+    form.legalIdType === "id_card" &&
+    (hasPortraitUploadSuccess.value ||
+      hasEmblemUploadSuccess.value ||
+      isIdPortraitOcrProcessing.value ||
+      hasIdPortraitOcrDisplay.value)
+);
+
+function clearIdPortraitOcr() {
+  idPortraitOcr.name = "";
+  idPortraitOcr.idNumber = "";
+  idPortraitOcr.idCardAddress = "";
+  idPortraitOcr.cardPeriodBegin = "";
+  idPortraitOcr.cardPeriodEnd = "";
+}
+
+function buildSubjectInfoForBusinessData(): {
+  contact_type: "LEGAL";
+  subject_type: "SUBJECT_TYPE_ENTERPRISE" | "SUBJECT_TYPE_INDIVIDUAL";
+  business_license_info: {
+    license_copy: string;
+    license_number: string;
+    merchant_name: string;
+    legal_person: string;
+  };
+  identity_info: {
+    id_doc_type: string;
+    id_holder_type: "LEGAL";
+    id_card_info: {
+      id_card_copy: string;
+      id_card_national: string;
+      id_card_name: string;
+      id_card_number: string;
+      id_card_address: string;
+      card_period_begin: string;
+      card_period_end: string;
+    };
+  };
+} {
+  const cached = localGet(BUSINESS_DATA_CACHE_KEY) as { entityType?: string } | null | undefined;
+  const entityType = String(
+    (cached && typeof cached === "object" && cached.entityType) ||
+      (typeof route.query.entityType === "string" ? route.query.entityType : "") ||
+      ""
+  ).trim();
+  /** 企业 → SUBJECT_TYPE_ENTERPRISE;个体工商户(entityType=individual)及其他默认 → SUBJECT_TYPE_INDIVIDUAL */
+  const subject_type = entityType === "enterprise" ? ("SUBJECT_TYPE_ENTERPRISE" as const) : ("SUBJECT_TYPE_INDIVIDUAL" as const);
+
+  return {
+    contact_type: "LEGAL" as const,
+    subject_type,
+    business_license_info: {
+      license_copy: (form.businessLicenseUrl || "").trim(),
+      license_number: (businessLicenseOcr.creditCode || "").trim(),
+      merchant_name: (businessLicenseOcr.companyName || "").trim(),
+      legal_person: (businessLicenseOcr.legalPerson || "").trim()
+    },
+    identity_info: {
+      id_doc_type: "IDENTIFICATION_TYPE_IDCARD",
+      id_holder_type: "LEGAL" as const,
+      id_card_info: {
+        id_card_copy: (form.idPortraitUrl || "").trim(),
+        id_card_national: (form.idEmblemUrl || "").trim(),
+        id_card_name: (idPortraitOcr.name || "").trim(),
+        id_card_number: (idPortraitOcr.idNumber || "").trim(),
+        id_card_address: (idPortraitOcr.idCardAddress || "").trim(),
+        card_period_begin: (idPortraitOcr.cardPeriodBegin || "").trim(),
+        card_period_end: (idPortraitOcr.cardPeriodEnd || "").trim()
+      }
+    }
+  };
+}
+
+function mergeSubjectInfoIntoBusinessDataCache() {
+  const prev = localGet(BUSINESS_DATA_CACHE_KEY);
+  const base = prev && typeof prev === "object" && !Array.isArray(prev) ? { ...(prev as Record<string, unknown>) } : {};
+  base.subject_info = buildSubjectInfoForBusinessData();
+  localSet(BUSINESS_DATA_CACHE_KEY, base);
+}
+
+function mapApiIdDocTypeToLegalId(apiType: unknown): string {
+  const s = String(apiType || "").trim();
+  switch (s) {
+    case "IDENTIFICATION_TYPE_IDCARD":
+      return "id_card";
+    case "IDENTIFICATION_TYPE_OVERSEA_PASSPORT":
+      return "passport";
+    case "IDENTIFICATION_TYPE_HONGKONG_PASSPORT":
+    case "IDENTIFICATION_TYPE_MACAO_PASSPORT":
+      return "hk_macau_pass";
+    case "IDENTIFICATION_TYPE_TAIWAN_PASSPORT":
+      return "taiwan_pass";
+    default:
+      if (/IDCARD|ID_CARD/i.test(s)) return "id_card";
+      return "id_card";
+  }
+}
+
+/** 从 localStorage businessData.subject_info 回显本页表单与 OCR 展示 */
+function hydrateSubjectFormFromBusinessDataCache() {
+  const raw = localGet(BUSINESS_DATA_CACHE_KEY) as Record<string, unknown> | null | undefined;
+  if (!raw || typeof raw !== "object" || Array.isArray(raw)) return;
+  const si = raw.subject_info as Record<string, unknown> | undefined;
+  if (!si || typeof si !== "object" || Array.isArray(si)) return;
+
+  const bli = si.business_license_info as Record<string, unknown> | undefined;
+  if (bli && typeof bli === "object" && !Array.isArray(bli)) {
+    const lic = String(bli.license_copy ?? "").trim();
+    if (lic) {
+      form.businessLicenseUrl = lic;
+      form.businessLicenseFileList = [{ name: "license.jpg", url: lic, status: "success" } as UploadUserFile];
+    } else {
+      form.businessLicenseUrl = "";
+      form.businessLicenseFileList = [];
+    }
+    businessLicenseOcr.creditCode = String(bli.license_number ?? "").trim();
+    businessLicenseOcr.companyName = String(bli.merchant_name ?? "").trim();
+    businessLicenseOcr.legalPerson = String(bli.legal_person ?? "").trim();
+  }
+
+  const ii = si.identity_info as Record<string, unknown> | undefined;
+  if (ii && typeof ii === "object" && !Array.isArray(ii)) {
+    if (String(ii.id_doc_type ?? "").trim()) {
+      form.legalIdType = mapApiIdDocTypeToLegalId(ii.id_doc_type);
+    }
+    const ici = ii.id_card_info as Record<string, unknown> | undefined;
+    if (ici && typeof ici === "object" && !Array.isArray(ici)) {
+      const copy = String(ici.id_card_copy ?? "").trim();
+      const nat = String(ici.id_card_national ?? "").trim();
+      if (copy) {
+        form.idPortraitUrl = copy;
+        form.idPortraitFileList = [{ name: "id-portrait.jpg", url: copy, status: "success" } as UploadUserFile];
+      } else {
+        form.idPortraitUrl = "";
+        form.idPortraitFileList = [];
+      }
+      if (nat) {
+        form.idEmblemUrl = nat;
+        form.idEmblemFileList = [{ name: "id-emblem.jpg", url: nat, status: "success" } as UploadUserFile];
+      } else {
+        form.idEmblemUrl = "";
+        form.idEmblemFileList = [];
+      }
+      idPortraitOcr.name = String(ici.id_card_name ?? "").trim();
+      idPortraitOcr.idNumber = String(ici.id_card_number ?? "").trim();
+      idPortraitOcr.idCardAddress = String(ici.id_card_address ?? "").trim();
+      idPortraitOcr.cardPeriodBegin = String(ici.card_period_begin ?? "").trim();
+      idPortraitOcr.cardPeriodEnd = String(ici.card_period_end ?? "").trim();
+    }
+  }
+
+  nextTick(() => {
+    formRef.value?.clearValidate();
+  });
+}
+
+const rules: FormRules = {
+  businessLicenseUrl: [
+    {
+      required: true,
+      validator: (_r, _v, cb) => {
+        if (!form.businessLicenseUrl?.trim()) {
+          cb(new Error("请上传营业执照照片"));
+        } else {
+          cb();
+        }
+      },
+      trigger: "change"
+    }
+  ],
+  legalIdType: [{ required: true, message: "请选择证件类型", trigger: "change" }],
+  idPortraitUrl: [
+    {
+      validator: (_r, _v, cb) => {
+        if (form.legalIdType === "id_card" && !form.idPortraitUrl?.trim()) {
+          cb(new Error("请上传身份证人像面照片"));
+        } else {
+          cb();
+        }
+      },
+      trigger: "change"
+    }
+  ],
+  idEmblemUrl: [
+    {
+      validator: (_r, _v, cb) => {
+        if (form.legalIdType === "id_card" && !form.idEmblemUrl?.trim()) {
+          cb(new Error("请上传身份证国徽面照片"));
+        } else {
+          cb();
+        }
+      },
+      trigger: "change"
+    }
+  ]
+};
+
+watch(
+  () => form.legalIdType,
+  v => {
+    if (v !== "id_card") {
+      form.idPortraitUrl = "";
+      form.idEmblemUrl = "";
+      form.idPortraitFileList = [];
+      form.idEmblemFileList = [];
+      clearIdPortraitOcr();
+    }
+  }
+);
+
+const MAX_LICENSE_MB = 5;
+
+function beforeLicenseUpload(file: File) {
+  const name = file.name?.toLowerCase() || "";
+  const okExt = /\.(jpe?g|png|bmp)$/i.test(name);
+  const okMime = ["image/jpeg", "image/png", "image/bmp"].includes(file.type);
+  if (!okExt && !okMime) {
+    ElMessage.error("图片只支持 JPG、BMP、PNG 格式");
+    return false;
+  }
+  const sizeMb = file.size / 1024 / 1024;
+  if (sizeMb > MAX_LICENSE_MB) {
+    ElMessage.error(`文件大小不能超过 ${MAX_LICENSE_MB}M`);
+    return false;
+  }
+  return true;
+}
+
+/** 与 getUpload(微信 media/upload)返回结构对齐 */
+function parseMediaUploadResult(res: any): { fileUrl: string; mediaId: string; errMsg: string } {
+  const envelope = res?.data ?? res;
+  const body = envelope?.data !== undefined ? envelope.data : envelope;
+  const fileUrl =
+    body?.url ??
+    body?.fileUrl ??
+    envelope?.url ??
+    envelope?.data?.url ??
+    envelope?.data?.fileUrl ??
+    body?.mediaUrl ??
+    body?.data?.mediaUrl ??
+    "";
+  const mediaId =
+    body?.media_id ?? body?.mediaId ?? envelope?.media_id ?? envelope?.data?.media_id ?? envelope?.data?.mediaId ?? "";
+  const errMsg = envelope?.msg ?? body?.msg ?? res?.msg ?? "";
+  return { fileUrl, mediaId, errMsg };
+}
+
+function mergeIdCardOcrFromFields(fields: ReturnType<typeof pickIdCardPortraitOcrFields>, mode: "portrait" | "emblem") {
+  if (mode === "portrait") {
+    if (fields.name) idPortraitOcr.name = fields.name;
+    if (fields.idNumber) idPortraitOcr.idNumber = fields.idNumber;
+    if (fields.idCardAddress) idPortraitOcr.idCardAddress = fields.idCardAddress;
+    if (fields.cardPeriodBegin) idPortraitOcr.cardPeriodBegin = fields.cardPeriodBegin;
+    if (fields.cardPeriodEnd) idPortraitOcr.cardPeriodEnd = fields.cardPeriodEnd;
+  } else {
+    if (fields.cardPeriodBegin) idPortraitOcr.cardPeriodBegin = fields.cardPeriodBegin;
+    if (fields.cardPeriodEnd) idPortraitOcr.cardPeriodEnd = fields.cardPeriodEnd;
+    if (fields.idCardAddress) idPortraitOcr.idCardAddress = fields.idCardAddress;
+  }
+}
+
+async function requestIdCardPortraitOcr(file: File) {
+  const formData = new FormData();
+  formData.append("imageFile", file, file.name || "id-portrait.jpg");
+  formData.append("ocrType", "ID_CARD");
+  isIdPortraitOcrProcessing.value = true;
+  try {
+    const res: any = await getOcrRequestByBase64(formData);
+    if (res?.code === 200 || res?.code === "200") {
+      const fields = pickIdCardPortraitOcrFields(res);
+      mergeIdCardOcrFromFields(fields, "portrait");
+      ElMessage.success("身份证人像面识别成功");
+    } else {
+      clearIdPortraitOcr();
+      ElMessage.warning(res?.msg || "身份证人像面识别未通过,请核对照片清晰度");
+    }
+  } finally {
+    isIdPortraitOcrProcessing.value = false;
+  }
+}
+
+/** 国徽面单独 OCR,合并有效期限(及背面地址等),不清空人像面已识别字段 */
+async function requestIdCardEmblemOcr(file: File) {
+  const formData = new FormData();
+  formData.append("imageFile", file, file.name || "id-emblem.jpg");
+  formData.append("ocrType", "ID_CARD");
+  isIdPortraitOcrProcessing.value = true;
+  try {
+    const res: any = await getOcrRequestByBase64(formData);
+    if (res?.code === 200 || res?.code === "200") {
+      const fields = pickIdCardPortraitOcrFields(res);
+      mergeIdCardOcrFromFields(fields, "emblem");
+      if (fields.cardPeriodBegin || fields.cardPeriodEnd) {
+        ElMessage.success("身份证国徽面识别成功");
+      } else {
+        ElMessage.warning("未识别到有效期限,请确认国徽面照片清晰完整");
+      }
+    } else {
+      ElMessage.warning(res?.msg || "身份证国徽面识别未通过,请核对照片清晰度");
+    }
+  } finally {
+    isIdPortraitOcrProcessing.value = false;
+  }
+}
+
+async function requestBusinessLicenseOcr(file: File) {
+  const formData = new FormData();
+  formData.append("imageFile", file, file.name || "license.jpg");
+  formData.append("ocrType", "BUSINESS_LICENSE");
+  const res: any = await getOcrRequestByBase64(formData);
+  if (res?.code === 200 || res?.code === "200") {
+    const fields = pickBusinessLicenseOcrFields(res);
+    businessLicenseOcr.creditCode = fields.creditCode;
+    businessLicenseOcr.companyName = fields.companyName;
+    businessLicenseOcr.legalPerson = fields.legalPerson;
+    ElMessage.success("营业执照识别成功");
+  } else {
+    clearBusinessLicenseOcr();
+    ElMessage.warning(res?.msg || "营业执照识别未通过,请核对照片清晰度");
+  }
+}
+
+async function handleLicenseUpload(options: UploadRequestOptions) {
+  const uploadFileItem = options.file as UploadUserFile;
+  const raw = uploadFileItem.raw || uploadFileItem;
+  const file = raw instanceof File ? raw : null;
+  if (!file) return;
+
+  uploadFileItem.status = "uploading";
+  try {
+    const formData = new FormData();
+    formData.append("file", file);
+    const res: any = await getUpload(formData);
+    const { fileUrl, mediaId, errMsg } = parseMediaUploadResult(res);
+
+    if (fileUrl || mediaId) {
+      uploadFileItem.status = "success";
+      if (fileUrl) {
+        uploadFileItem.url = fileUrl;
+      }
+      uploadFileItem.response = { media_id: mediaId, url: fileUrl };
+      form.businessLicenseUrl = fileUrl || mediaId;
+      try {
+        await requestBusinessLicenseOcr(file);
+      } catch {
+        clearBusinessLicenseOcr();
+        ElMessage.warning("营业执照识别服务暂时不可用,请稍后重试");
+      }
+    } else {
+      uploadFileItem.status = "fail";
+      ElMessage.error(errMsg || "上传失败,未返回可用结果");
+    }
+  } catch {
+    uploadFileItem.status = "fail";
+  }
+  formRef.value?.validateField("businessLicenseUrl").catch(() => {});
+}
+
+function onLicenseRemove(_file: UploadUserFile, fileList: UploadUserFile[]) {
+  if (!fileList.length) {
+    form.businessLicenseUrl = "";
+    clearBusinessLicenseOcr();
+  } else {
+    const first = fileList[0] as UploadUserFile & { url?: string; response?: { url?: string } };
+    form.businessLicenseUrl = first?.url || first?.response?.url || "";
+  }
+  formRef.value?.validateField("businessLicenseUrl").catch(() => {});
+}
+
+type IdCardSide = "portrait" | "emblem";
+
+async function handleIdCardUpload(options: UploadRequestOptions, side: IdCardSide) {
+  const uploadFileItem = options.file as UploadUserFile;
+  const raw = uploadFileItem.raw || uploadFileItem;
+  const file = raw instanceof File ? raw : null;
+  if (!file) return;
+
+  uploadFileItem.status = "uploading";
+  try {
+    const formData = new FormData();
+    formData.append("file", file);
+    const res: any = await getUpload(formData);
+    const { fileUrl, mediaId, errMsg } = parseMediaUploadResult(res);
+
+    if (fileUrl || mediaId) {
+      uploadFileItem.status = "success";
+      if (fileUrl) {
+        uploadFileItem.url = fileUrl;
+      }
+      uploadFileItem.response = { media_id: mediaId, url: fileUrl };
+      const stored = fileUrl || mediaId;
+      if (side === "portrait") {
+        form.idPortraitUrl = stored;
+        try {
+          await requestIdCardPortraitOcr(file);
+        } catch {
+          clearIdPortraitOcr();
+          ElMessage.warning("身份证识别服务暂时不可用,请稍后重试");
+        }
+      } else {
+        form.idEmblemUrl = stored;
+        try {
+          await requestIdCardEmblemOcr(file);
+        } catch {
+          ElMessage.warning("身份证国徽面识别服务暂时不可用,请稍后重试");
+        }
+      }
+    } else {
+      uploadFileItem.status = "fail";
+      ElMessage.error(errMsg || "上传失败,未返回可用结果");
+    }
+  } catch {
+    uploadFileItem.status = "fail";
+  }
+  const field = side === "portrait" ? "idPortraitUrl" : "idEmblemUrl";
+  formRef.value?.validateField(field).catch(() => {});
+}
+
+function onIdCardRemove(fileList: UploadUserFile[], side: IdCardSide) {
+  if (!fileList.length) {
+    if (side === "portrait") {
+      form.idPortraitUrl = "";
+      clearIdPortraitOcr();
+    } else {
+      form.idEmblemUrl = "";
+      idPortraitOcr.cardPeriodBegin = "";
+      idPortraitOcr.cardPeriodEnd = "";
+    }
+  } else {
+    const first = fileList[0] as UploadUserFile & {
+      url?: string;
+      response?: { url?: string; media_id?: string; mediaId?: string };
+    };
+    const r = first?.response;
+    const stored = first?.url || r?.url || r?.media_id || r?.mediaId || "";
+    if (side === "portrait") form.idPortraitUrl = stored;
+    else form.idEmblemUrl = stored;
+  }
+  const field = side === "portrait" ? "idPortraitUrl" : "idEmblemUrl";
+  formRef.value?.validateField(field).catch(() => {});
+}
+
+/** 从草稿/详情接口 URL 还原身份证上传展示(可在外部拉取数据后调用) */
+function restoreIdCardFromUrls(portraitUrl?: string | null, emblemUrl?: string | null) {
+  if (portraitUrl) {
+    form.idPortraitUrl = portraitUrl;
+    form.idPortraitFileList = [{ name: "id-portrait.jpg", url: portraitUrl, status: "success" } as UploadUserFile];
+  }
+  if (emblemUrl) {
+    form.idEmblemUrl = emblemUrl;
+    form.idEmblemFileList = [{ name: "id-emblem.jpg", url: emblemUrl, status: "success" } as UploadUserFile];
+  }
+}
+
+onMounted(() => {
+  hydrateSubjectFormFromBusinessDataCache();
+  const q = route.query as Record<string, string | string[] | undefined>;
+  const pu = typeof q.idPortraitUrl === "string" ? q.idPortraitUrl : undefined;
+  const eu = typeof q.idEmblemUrl === "string" ? q.idEmblemUrl : undefined;
+  if (pu && !form.idPortraitUrl?.trim()) {
+    form.legalIdType = "id_card";
+    restoreIdCardFromUrls(pu, undefined);
+  }
+  if (eu && !form.idEmblemUrl?.trim()) {
+    form.legalIdType = "id_card";
+    restoreIdCardFromUrls(undefined, eu);
+  }
+});
+
+defineExpose({ restoreIdCardFromUrls, hydrateSubjectFormFromBusinessDataCache });
+
+function onModifyUbo() {
+  ElMessage.info("受益人信息修改入口可在此对接");
+}
+
+function onBack() {
+  router.push({
+    path: "/businessInfo/dataEntry",
+    query: { ...route.query }
+  });
+}
+
+function onSaveDraft() {
+  ElMessage.success("草稿已保存(可对接接口)");
+}
+
+async function onNext() {
+  if (!formRef.value) return;
+  nextLoading.value = true;
+  try {
+    await formRef.value.validate();
+    mergeSubjectInfoIntoBusinessDataCache();
+    await router.push({
+      path: "/businessInfo/manageInfo",
+      query: { ...route.query }
+    });
+  } catch {
+    ElMessage.warning("请完善必填信息");
+  } finally {
+    nextLoading.value = false;
+  }
+}
+</script>
+
+<style scoped lang="scss">
+$wechat-green: #07c160;
+.subject-info-page {
+  box-sizing: border-box;
+  min-height: 100%;
+  padding: 24px 32px 40px;
+  margin: 0 auto;
+  background: #ffffff;
+}
+.page-title {
+  margin: 0 0 24px;
+  font-size: 20px;
+  font-weight: 600;
+  color: #303133;
+}
+.subject-form {
+  :deep(.el-form-item__label) {
+    font-weight: 500;
+    color: #606266;
+  }
+}
+.form-block {
+  padding-bottom: 8px;
+  margin-bottom: 28px;
+  border-bottom: 1px solid #ebeef5;
+  &:last-of-type {
+    border-bottom: none;
+  }
+}
+.section-head {
+  display: flex;
+  align-items: center;
+  margin: 0 0 16px;
+  font-size: 16px;
+  font-weight: 600;
+  color: #303133;
+}
+.section-bar {
+  display: inline-block;
+  flex-shrink: 0;
+  width: 4px;
+  height: 16px;
+  margin-right: 8px;
+  background: $wechat-green;
+  border-radius: 2px;
+}
+.section-intro {
+  padding-left: 20px;
+  font-size: 13px;
+  line-height: 1.65;
+  color: #909399;
+}
+.field-stack {
+  width: 100%;
+}
+.field-tip {
+  margin: 8px 0 0;
+  font-size: 12px;
+  line-height: 1.65;
+  color: #909399;
+}
+.label-with-icon {
+  display: inline-flex;
+  gap: 4px;
+  align-items: center;
+}
+.info-icon {
+  color: #909399;
+  cursor: help;
+}
+.license-upload-wrap {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 16px;
+  align-items: flex-start;
+}
+.license-example {
+  display: flex;
+  flex-direction: column;
+  gap: 6px;
+}
+.license-example-label {
+  font-size: 12px;
+  color: #909399;
+}
+.license-example-thumb {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  width: 148px;
+  height: 148px;
+  background: #f5f7fa;
+  border: 1px dashed #dcdfe6;
+  border-radius: 6px;
+}
+.license-example-placeholder {
+  font-size: 12px;
+  color: #c0c4cc;
+}
+.id-example-thumb {
+  position: relative;
+}
+.license-example-badge {
+  position: absolute;
+  top: 6px;
+  right: 6px;
+  padding: 2px 6px;
+  font-size: 11px;
+  color: #ffffff;
+  background: rgb(0 0 0 / 45%);
+  border-radius: 4px;
+}
+.ubo-footer-tip {
+  padding: 12px 0 0;
+  margin: 8px 0 0;
+  font-size: 12px;
+  line-height: 1.65;
+  color: #909399;
+  border-top: 1px dashed #ebeef5;
+}
+:deep(.el-form-item__content) {
+  display: block;
+}
+.upload-rules {
+  margin-top: 12px;
+  font-size: 12px;
+  line-height: 1.65;
+  color: #909399;
+  p {
+    margin: 0 0 6px;
+    &:last-child {
+      margin-bottom: 0;
+    }
+  }
+}
+.ocr-result-container {
+  max-width: 640px;
+  padding: 14px 16px;
+  margin-top: 12px;
+  background: #f5f7fa;
+  border: 1px solid #ebeef5;
+  border-radius: 6px;
+}
+.ocr-result-item {
+  display: flex;
+  gap: 12px;
+  align-items: flex-start;
+  margin-bottom: 10px;
+  font-size: 13px;
+  line-height: 1.5;
+  &:last-child {
+    margin-bottom: 0;
+  }
+  .label {
+    flex-shrink: 0;
+    min-width: 88px;
+    font-weight: 600;
+    color: #606266;
+  }
+  .value {
+    flex: 1;
+    color: #303133;
+    word-break: break-all;
+  }
+}
+.ocr-result-tip {
+  font-size: 13px;
+  line-height: 1.5;
+  color: #909399;
+}
+.license-ocr-result {
+  max-width: 640px;
+  padding: 14px 16px;
+  margin-top: 12px;
+  margin-left: 140px;
+  background: #f5f7fa;
+  border: 1px solid #ebeef5;
+  border-radius: 6px;
+}
+.license-ocr-row {
+  display: flex;
+  gap: 12px;
+  align-items: flex-start;
+  margin-bottom: 10px;
+  font-size: 13px;
+  line-height: 1.5;
+  &:last-child {
+    margin-bottom: 0;
+  }
+}
+.license-ocr-label {
+  flex-shrink: 0;
+  width: 132px;
+  font-weight: 600;
+  color: #606266;
+}
+.license-ocr-value {
+  flex: 1;
+  color: #303133;
+  word-break: break-all;
+}
+:deep(.el-upload--picture-card) {
+  --el-upload-picture-card-size: 148px;
+}
+:deep(.el-upload-list--picture-card .el-upload-list__item) {
+  width: 148px;
+  height: 148px;
+}
+.footer-actions {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  padding-top: 24px;
+  margin-top: 8px;
+  border-top: 1px solid #ebeef5;
+}
+.footer-center {
+  display: flex;
+  flex: 1;
+  justify-content: center;
+}
+.btn-next {
+  min-width: 100px;
+  background: $wechat-green;
+  border-color: $wechat-green;
+  &:hover {
+    background: #06ad56;
+    border-color: #06ad56;
+  }
+}
+</style>

+ 266 - 0
src/views/businessInfo/weChartExamine.vue

@@ -0,0 +1,266 @@
+<template>
+  <div class="table-box we-chart-examine-page">
+    <h1 class="page-title">查看微信审核</h1>
+
+    <el-alert v-if="loadError" class="mb-16" type="warning" :closable="false" show-icon :title="loadError" />
+
+    <ProTable row-key="_rowKey" :columns="columns" :request-api="getExamineList" :init-param="initParam" :pagination="false">
+      <template #signUrl="scope">
+        <el-link v-if="isHttpUrl(scope.row.signUrl)" :href="scope.row.signUrl" target="_blank" type="primary">
+          {{ scope.row.signUrl }}
+        </el-link>
+        <span v-else>{{ scope.row.signUrl }}</span>
+      </template>
+    </ProTable>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { reactive, ref } from "vue";
+import { useRoute } from "vue-router";
+import ProTable from "@/components/ProTable/index.vue";
+import type { ColumnProps } from "@/components/ProTable/interface";
+import { localGet } from "@/utils/index";
+import { applymentExamine } from "@/api/modules/businessInfo";
+
+const GEEKER_USER_KEY = "geeker-user";
+
+type ExamineDisplayRow = {
+  id: string;
+  applymentNo: string;
+  signUrl: string;
+  applymentState: string;
+  rejectReason: string;
+  _rowKey: string;
+};
+
+const KEY_ID = ["id", "Id", "_id"];
+const KEY_APPLYMENT_NO = ["applyment_id", "applymentId", "out_request_no", "outRequestNo", "business_code", "businessCode"];
+const KEY_SIGN = ["sign_url", "signUrl"];
+const KEY_REJECT = ["reject_reason", "rejectReason"];
+
+/** 微信支付子商户进件申请单状态 → 中文 */
+const APPLYMENT_STATE_LABEL: Record<string, string> = {
+  APPLYMENT_STATE_EDITTING: "编辑中",
+  APPLYMENT_STATE_EDITING: "编辑中",
+  APPLYMENT_STATE_AUDITING: "审核中",
+  APPLYMENT_STATE_REJECTED: "已驳回",
+  APPLYMENT_STATE_TO_BE_CONFIRMED: "待账户验证",
+  APPLYMENT_STATE_TO_BE_SIGNED: "待签约",
+  APPLYMENT_STATE_SIGNING: "开通权限中",
+  APPLYMENT_STATE_FINISHED: "已完成",
+  APPLYMENT_STATE_CANCELED: "已作废"
+};
+
+function formatApplymentStateLabel(raw: string): string {
+  const t = String(raw ?? "").trim();
+  if (!t || t === "—") return "—";
+  const upper = t.toUpperCase().replace(/\s+/g, "_");
+  if (APPLYMENT_STATE_LABEL[upper]) return APPLYMENT_STATE_LABEL[upper];
+  if (APPLYMENT_STATE_LABEL[t]) return APPLYMENT_STATE_LABEL[t];
+  return t;
+}
+
+function pickApplymentStateRaw(row: Record<string, unknown>): string {
+  const codeKeys = ["applyment_state", "applymentState"] as const;
+  for (const k of codeKeys) {
+    if (Object.prototype.hasOwnProperty.call(row, k)) {
+      const v = row[k];
+      if (v !== undefined && v !== null && v !== "") {
+        return String(v).trim();
+      }
+    }
+  }
+  const descKeys = ["applyment_state_desc", "applymentStateDesc"] as const;
+  for (const k of descKeys) {
+    if (Object.prototype.hasOwnProperty.call(row, k)) {
+      const v = row[k];
+      if (v !== undefined && v !== null && v !== "") {
+        return String(v).trim();
+      }
+    }
+  }
+  return "";
+}
+
+function resolveApplymentStoreId(): string | number | null {
+  const geeker = localGet(GEEKER_USER_KEY) as { userInfo?: { storeId?: string | number | null } } | null | undefined;
+  const sid = geeker?.userInfo?.storeId ?? localGet("createdId");
+  if (sid === undefined || sid === null || sid === "") return null;
+  return sid;
+}
+
+const route = useRoute();
+
+function resolveStoreIdParam(): string | number | null {
+  const q = route.query.storeId;
+  if (q !== undefined && q !== null && q !== "") {
+    const s = (Array.isArray(q) ? q[0] : q) as string;
+    if (s) {
+      const n = Number(s);
+      return Number.isNaN(n) ? s : n;
+    }
+  }
+  return resolveApplymentStoreId();
+}
+
+const loadError = ref("");
+
+const initParam = reactive({
+  storeId: localGet(GEEKER_USER_KEY)?.userInfo?.storeId ?? localGet("createdId") ?? ""
+});
+
+const columns: ColumnProps<ExamineDisplayRow>[] = [
+  { prop: "id", label: "ID", width: 100, align: "center" },
+  { prop: "applymentNo", label: "申请单编号", minWidth: 180 },
+  { prop: "signUrl", label: "签约链接", minWidth: 220 },
+  { prop: "applymentState", label: "申请状态", minWidth: 140 },
+  { prop: "rejectReason", label: "驳回原因", minWidth: 200 }
+];
+
+function formatCell(v: unknown): string {
+  if (v === null || v === undefined || v === "") return "—";
+  if (typeof v === "object") {
+    try {
+      return JSON.stringify(v);
+    } catch {
+      return String(v);
+    }
+  }
+  return String(v);
+}
+
+function isHttpUrl(s: string): boolean {
+  if (!s || s === "—") return false;
+  return /^https?:\/\//i.test(s.trim());
+}
+
+function pickField(row: Record<string, unknown>, keys: string[]): string {
+  for (const k of keys) {
+    if (Object.prototype.hasOwnProperty.call(row, k)) {
+      const v = row[k];
+      if (v !== undefined && v !== null && v !== "") {
+        return formatCell(v);
+      }
+    }
+  }
+  return "—";
+}
+
+function normalizeRow(row: Record<string, unknown>): Omit<ExamineDisplayRow, "_rowKey"> {
+  const stateRaw = pickApplymentStateRaw(row);
+  return {
+    id: pickField(row, KEY_ID),
+    applymentNo: pickField(row, KEY_APPLYMENT_NO),
+    signUrl: pickField(row, KEY_SIGN),
+    applymentState: stateRaw ? formatApplymentStateLabel(stateRaw) : "—",
+    rejectReason: pickField(row, KEY_REJECT)
+  };
+}
+
+function unwrapPayload(raw: unknown): unknown {
+  if (raw === null || raw === undefined) return null;
+  if (Array.isArray(raw)) return raw;
+  if (typeof raw !== "object") return raw;
+  const o = raw as Record<string, unknown>;
+  if (Array.isArray(o.list)) return o.list;
+  if (Array.isArray(o.records)) return o.records;
+  if (Array.isArray(o.rows)) return o.rows;
+  if (o.data !== undefined && o.data !== null) {
+    const inner = o.data;
+    if (Array.isArray(inner)) return inner;
+    if (typeof inner === "object" && !Array.isArray(inner)) {
+      const obj = inner as Record<string, unknown>;
+      if (Array.isArray(obj.list)) return obj.list;
+      if (Array.isArray(obj.records)) return obj.records;
+    }
+    return inner;
+  }
+  return raw;
+}
+
+function isPlainObjectRow(x: unknown): x is Record<string, unknown> {
+  return x !== null && typeof x === "object" && !Array.isArray(x);
+}
+
+function buildDisplayRows(payload: unknown): Omit<ExamineDisplayRow, "_rowKey">[] {
+  if (payload === null || payload === undefined) return [];
+
+  if (Array.isArray(payload)) {
+    if (payload.length === 0) return [];
+    if (isPlainObjectRow(payload[0])) {
+      return (payload as Record<string, unknown>[]).map(normalizeRow);
+    }
+    return [
+      {
+        id: "—",
+        applymentNo: "—",
+        signUrl: "—",
+        applymentState: "—",
+        rejectReason: formatCell(payload)
+      }
+    ];
+  }
+
+  if (isPlainObjectRow(payload)) {
+    return [normalizeRow(payload)];
+  }
+
+  return [
+    {
+      id: "—",
+      applymentNo: "—",
+      signUrl: "—",
+      applymentState: "—",
+      rejectReason: formatCell(payload)
+    }
+  ];
+}
+
+function withRowKeys(rows: Omit<ExamineDisplayRow, "_rowKey">[]): ExamineDisplayRow[] {
+  return rows.map((r, i) => ({
+    ...r,
+    _rowKey: `examine-${i}-${r.id}-${r.applymentNo}`.replace(/\s/g, "")
+  }));
+}
+
+/**
+ * 与 tableManagement.vue 中 ProTable 约定一致:返回 { data }。
+ * 无分页时 useTable 将 data 视为列表(见 useTable 无分页分支)。
+ */
+async function getExamineList(_params: any) {
+  const storeId = resolveStoreIdParam();
+  if (storeId === null) {
+    loadError.value = "未获取到门店 storeId,请重新登录或通过路由传入 storeId。";
+    return { data: [] as ExamineDisplayRow[] };
+  }
+
+  loadError.value = "";
+  try {
+    const res = (await applymentExamine(storeId)) as { data?: unknown };
+    const payload = unwrapPayload(res?.data ?? res);
+    const list = withRowKeys(buildDisplayRows(payload));
+    return { data: list };
+  } catch (e: unknown) {
+    const msg = e && typeof e === "object" && "msg" in e ? String((e as { msg?: string }).msg) : "";
+    loadError.value = msg || "获取审核信息失败";
+    return { data: [] as ExamineDisplayRow[] };
+  }
+}
+</script>
+
+<style scoped lang="scss">
+.we-chart-examine-page {
+  padding: 24px 32px 40px;
+  background: #ffffff;
+}
+.page-title {
+  margin: 0 0 20px;
+  font-size: 20px;
+  font-weight: 600;
+  color: #303133;
+}
+.mb-16 {
+  margin-bottom: 16px;
+}
+</style>

+ 15 - 0
src/views/businessInfo/weChartIndex.vue

@@ -0,0 +1,15 @@
+<template>
+  <div class="we-chart-index">
+    <CreateApply />
+  </div>
+</template>
+
+<script setup lang="ts">
+import CreateApply from "./createApply.vue";
+</script>
+
+<style scoped>
+.we-chart-index {
+  min-height: 100%;
+}
+</style>

+ 253 - 0
src/views/businessInfo/zfbExamine.vue

@@ -0,0 +1,253 @@
+<template>
+  <div class="table-box zfb-examine-page">
+    <h1 class="page-title">查看支付宝审核</h1>
+
+    <el-alert v-if="loadError" class="mb-16" type="warning" :closable="false" show-icon :title="loadError" />
+
+    <ProTable row-key="_rowKey" :columns="columns" :request-api="getExamineList" :init-param="initParam" :pagination="false">
+      <template #signUrl="scope">
+        <el-link v-if="isHttpUrl(scope.row.signUrl)" :href="scope.row.signUrl" target="_blank" type="primary">
+          {{ scope.row.signUrl }}
+        </el-link>
+        <span v-else>{{ scope.row.signUrl }}</span>
+      </template>
+    </ProTable>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { reactive, ref } from "vue";
+import ProTable from "@/components/ProTable/index.vue";
+import type { ColumnProps } from "@/components/ProTable/interface";
+import { getAlipayExamine } from "@/api/modules/businessInfo";
+
+/** 与产品约定:查询指定进件订单 */
+const ALIPAY_EXAMINE_ORDER = "2026040700502000000050184000";
+
+type ExamineDisplayRow = {
+  id: string;
+  applymentNo: string;
+  signUrl: string;
+  applymentState: string;
+  rejectReason: string;
+  _rowKey: string;
+};
+
+const KEY_ID = ["id", "Id", "_id"];
+const KEY_APPLYMENT_NO = [
+  "order",
+  "order_id",
+  "orderId",
+  "applyment_id",
+  "applymentId",
+  "out_request_no",
+  "outRequestNo",
+  "business_code",
+  "businessCode"
+];
+const KEY_SIGN = ["sign_url", "signUrl", "signing_url", "signingUrl", "agreement_url", "agreementUrl"];
+const KEY_REJECT = ["reject_reason", "rejectReason", "fail_reason", "failReason", "reason", "sub_msg", "subMsg"];
+
+/** 支付宝 / 直付通常见状态码(接口若返回英文枚举可在此补充) */
+const APPLYMENT_STATE_LABEL: Record<string, string> = {
+  AUDITING: "审核中",
+  AUDIT_PASS: "审核通过",
+  AUDIT_REJECT: "审核驳回",
+  AUDITING_WAIT_FOR_CONFIRM: "待确认",
+  CANCEL: "已撤销",
+  SUCCESS: "成功",
+  FAIL: "失败",
+  PROCESSING: "处理中"
+};
+
+function formatApplymentStateLabel(raw: string): string {
+  const t = String(raw ?? "").trim();
+  if (!t || t === "—") return "—";
+  const upper = t.toUpperCase().replace(/\s+/g, "_");
+  if (APPLYMENT_STATE_LABEL[upper]) return APPLYMENT_STATE_LABEL[upper];
+  if (APPLYMENT_STATE_LABEL[t]) return APPLYMENT_STATE_LABEL[t];
+  return t;
+}
+
+function pickApplymentStateRaw(row: Record<string, unknown>): string {
+  const codeKeys = [
+    "applyment_state",
+    "applymentState",
+    "order_status",
+    "orderStatus",
+    "status",
+    "audit_status",
+    "auditStatus",
+    "state"
+  ] as const;
+  for (const k of codeKeys) {
+    if (Object.prototype.hasOwnProperty.call(row, k)) {
+      const v = row[k];
+      if (v !== undefined && v !== null && v !== "") {
+        return String(v).trim();
+      }
+    }
+  }
+  const descKeys = ["applyment_state_desc", "applymentStateDesc", "status_desc", "statusDesc", "msg", "message"] as const;
+  for (const k of descKeys) {
+    if (Object.prototype.hasOwnProperty.call(row, k)) {
+      const v = row[k];
+      if (v !== undefined && v !== null && v !== "") {
+        return String(v).trim();
+      }
+    }
+  }
+  return "";
+}
+
+const loadError = ref("");
+
+const initParam = reactive({ order: ALIPAY_EXAMINE_ORDER });
+
+const columns: ColumnProps<ExamineDisplayRow>[] = [
+  { prop: "id", label: "ID", width: 100, align: "center" },
+  { prop: "applymentNo", label: "订单号 / 申请单号", minWidth: 200 },
+  { prop: "signUrl", label: "签约链接", minWidth: 220 },
+  { prop: "applymentState", label: "状态", minWidth: 140 },
+  { prop: "rejectReason", label: "驳回 / 失败原因", minWidth: 200 }
+];
+
+function formatCell(v: unknown): string {
+  if (v === null || v === undefined || v === "") return "—";
+  if (typeof v === "object") {
+    try {
+      return JSON.stringify(v);
+    } catch {
+      return String(v);
+    }
+  }
+  return String(v);
+}
+
+function isHttpUrl(s: string): boolean {
+  if (!s || s === "—") return false;
+  return /^https?:\/\//i.test(s.trim());
+}
+
+function pickField(row: Record<string, unknown>, keys: string[]): string {
+  for (const k of keys) {
+    if (Object.prototype.hasOwnProperty.call(row, k)) {
+      const v = row[k];
+      if (v !== undefined && v !== null && v !== "") {
+        return formatCell(v);
+      }
+    }
+  }
+  return "—";
+}
+
+function normalizeRow(row: Record<string, unknown>): Omit<ExamineDisplayRow, "_rowKey"> {
+  const stateRaw = pickApplymentStateRaw(row);
+  return {
+    id: pickField(row, KEY_ID),
+    applymentNo: pickField(row, KEY_APPLYMENT_NO),
+    signUrl: pickField(row, KEY_SIGN),
+    applymentState: stateRaw ? formatApplymentStateLabel(stateRaw) : "—",
+    rejectReason: pickField(row, KEY_REJECT)
+  };
+}
+
+function unwrapPayload(raw: unknown): unknown {
+  if (raw === null || raw === undefined) return null;
+  if (Array.isArray(raw)) return raw;
+  if (typeof raw !== "object") return raw;
+  const o = raw as Record<string, unknown>;
+  if (Array.isArray(o.list)) return o.list;
+  if (Array.isArray(o.records)) return o.records;
+  if (Array.isArray(o.rows)) return o.rows;
+  if (o.data !== undefined && o.data !== null) {
+    const inner = o.data;
+    if (Array.isArray(inner)) return inner;
+    if (typeof inner === "object" && !Array.isArray(inner)) {
+      const obj = inner as Record<string, unknown>;
+      if (Array.isArray(obj.list)) return obj.list;
+      if (Array.isArray(obj.records)) return obj.records;
+    }
+    return inner;
+  }
+  return raw;
+}
+
+function isPlainObjectRow(x: unknown): x is Record<string, unknown> {
+  return x !== null && typeof x === "object" && !Array.isArray(x);
+}
+
+function buildDisplayRows(payload: unknown): Omit<ExamineDisplayRow, "_rowKey">[] {
+  if (payload === null || payload === undefined) return [];
+
+  if (Array.isArray(payload)) {
+    if (payload.length === 0) return [];
+    if (isPlainObjectRow(payload[0])) {
+      return (payload as Record<string, unknown>[]).map(normalizeRow);
+    }
+    return [
+      {
+        id: "—",
+        applymentNo: "—",
+        signUrl: "—",
+        applymentState: "—",
+        rejectReason: formatCell(payload)
+      }
+    ];
+  }
+
+  if (isPlainObjectRow(payload)) {
+    return [normalizeRow(payload)];
+  }
+
+  return [
+    {
+      id: "—",
+      applymentNo: "—",
+      signUrl: "—",
+      applymentState: "—",
+      rejectReason: formatCell(payload)
+    }
+  ];
+}
+
+function withRowKeys(rows: Omit<ExamineDisplayRow, "_rowKey">[]): ExamineDisplayRow[] {
+  return rows.map((r, i) => ({
+    ...r,
+    _rowKey: `zfb-examine-${i}-${r.id}-${r.applymentNo}`.replace(/\s/g, "")
+  }));
+}
+
+/**
+ * 与 ProTable 约定一致:返回 { data }。
+ */
+async function getExamineList(_params: unknown) {
+  loadError.value = "";
+  try {
+    const res = (await getAlipayExamine({ order: ALIPAY_EXAMINE_ORDER })) as { data?: unknown };
+    const payload = unwrapPayload(res?.data ?? res);
+    const list = withRowKeys(buildDisplayRows(payload));
+    return { data: list };
+  } catch (e: unknown) {
+    const msg = e && typeof e === "object" && "msg" in e ? String((e as { msg?: string }).msg) : "";
+    loadError.value = msg || "获取支付宝审核信息失败";
+    return { data: [] as ExamineDisplayRow[] };
+  }
+}
+</script>
+
+<style scoped lang="scss">
+.zfb-examine-page {
+  padding: 24px 32px 40px;
+  background: #ffffff;
+}
+.page-title {
+  margin: 0 0 20px;
+  font-size: 20px;
+  font-weight: 600;
+  color: #303133;
+}
+.mb-16 {
+  margin-bottom: 16px;
+}
+</style>

+ 2458 - 0
src/views/businessInfo/zfbIndex.vue

@@ -0,0 +1,2458 @@
+<template>
+  <div class="zfb-step-page">
+    <header class="step-header">
+      <el-steps :active="zfbStepActive" align-center finish-status="process" class="zfb-steps">
+        <el-step title="第一步 完善商家信息" />
+        <el-step title="第二步 完善结算信息" />
+        <el-step title="第三步 提交审核" />
+      </el-steps>
+    </header>
+
+    <div class="page-layout">
+      <div class="main-column">
+        <el-form
+          ref="formRef"
+          class="zfb-form"
+          :model="form"
+          :rules="rules"
+          label-width="200px"
+          require-asterisk-position="left"
+          label-position="right"
+        >
+          <!-- 主体信息 -->
+          <section id="zfb-subject" class="form-block anchor-section">
+            <h2 class="section-head">
+              <span class="section-bar" aria-hidden="true" />
+              主体信息
+            </h2>
+
+            <el-form-item label="主体类型" prop="subjectType">
+              <el-radio-group v-model="form.subjectType" class="radio-stack" @change="onSubjectTypeChange">
+                <el-radio v-for="opt in subjectTypeOptions" :key="opt.value" :value="opt.value">
+                  {{ opt.label }}
+                </el-radio>
+              </el-radio-group>
+            </el-form-item>
+
+            <el-form-item prop="licenseUrl" v-if="form.subjectType === '01'">
+              <template #label>
+                <span class="label-with-icon"> 营业执照 </span>
+              </template>
+              <div class="license-upload-wrap">
+                <el-upload
+                  v-model:file-list="form.licenseFileList"
+                  list-type="picture-card"
+                  :limit="1"
+                  accept=".jpg,.jpeg,.png,.bmp,.gif,image/jpeg,image/png,image/bmp,image/gif"
+                  :before-upload="beforeImageUpload"
+                  :http-request="opt => handleSingleUpload(opt, 'license')"
+                  :on-remove="(_f, fl) => onSingleRemove(fl, 'license')"
+                >
+                  <el-icon><Plus /></el-icon>
+                </el-upload>
+              </div>
+              <div class="upload-rules">
+                <p>只支持.jpg、.png格式。</p>
+              </div>
+            </el-form-item>
+
+            <el-form-item label="营业执照号" prop="creditCode" v-if="form.subjectType === '01'">
+              <el-input
+                v-model="form.creditCode"
+                placeholder="请输入统一社会信用代码"
+                clearable
+                maxlength="32"
+                style="max-width: 480px"
+              />
+            </el-form-item>
+
+            <el-form-item prop="merchantShortName" v-if="form.subjectType === '01'">
+              <template #label>
+                <span class="label-with-icon"> 商户简称 </span>
+              </template>
+              <el-input v-model="form.merchantShortName" placeholder="请输入商户简称" clearable style="max-width: 480px" />
+            </el-form-item>
+            <el-form-item prop="businessCategory" v-if="form.subjectType === '01'">
+              <template #label>
+                <span class="label-with-icon"> 经营类目 </span>
+              </template>
+              <el-cascader
+                v-model="form.businessCategory"
+                :options="categoryCascaderOptions"
+                :props="categoryCascaderProps"
+                placeholder="请选择经营类目"
+                clearable
+                filterable
+                style="width: 480px"
+              />
+            </el-form-item>
+            <!-- 
+            <template v-if="form.subjectType === '02'">
+              <el-form-item prop="institutionCertUrl">
+                <template #label>事业单位法人证书</template>
+                <div class="license-upload-wrap">
+                  <el-upload
+                    v-model:file-list="form.institutionCertFileList"
+                    list-type="picture-card"
+                    :limit="1"
+                    accept=".jpg,.jpeg,.png,image/jpeg,image/png"
+                    :before-upload="beforeImageUploadInstJpgPng"
+                    :http-request="opt => handleSingleUpload(opt, 'institutionCert')"
+                    :on-remove="(_f, fl) => onSingleRemove(fl, 'institutionCert')"
+                  >
+                    <el-icon><Plus /></el-icon>
+                  </el-upload>
+                </div>
+                <div class="upload-rules">
+                  <p>仅支持 jpg、png 格式。</p>
+                </div>
+              </el-form-item>
+
+              <el-form-item label="事业单位法人证书编号" prop="institutionCertNumber">
+                <el-input
+                  v-model="form.institutionCertNumber"
+                  placeholder="请输入证书编号"
+                  clearable
+                  maxlength="64"
+                  style="max-width: 480px"
+                />
+              </el-form-item>
+
+              <el-form-item prop="merchantShortName">
+                <template #label>
+                  <span class="label-with-icon">
+                    商户简称
+                    <el-tooltip placement="top" content="简称将展示给消费者,需与法人证书或品牌一致。">
+                      <el-icon class="info-icon" :size="16"><InfoFilled /></el-icon>
+                    </el-tooltip>
+                  </span>
+                </template>
+                <el-input
+                  v-model="form.merchantShortName"
+                  placeholder="请输入商户简称"
+                  clearable
+                  maxlength="64"
+                  show-word-limit
+                  style="max-width: 480px"
+                />
+              </el-form-item>
+
+              <el-form-item label="经营类目" prop="businessCategory">
+                <el-cascader
+                  v-model="form.businessCategory"
+                  :options="categoryCascaderOptions"
+                  :props="categoryCascaderProps"
+                  placeholder="请选择经营类目"
+                  clearable
+                  filterable
+                  style="width: 480px"
+                />
+              </el-form-item>
+            </template> -->
+
+            <!-- <template v-if="form.subjectType === '03'">
+              <el-form-item prop="otherOrgCertUrl">
+                <template #label>民办非企业单位登记证书</template>
+                <div class="license-upload-wrap">
+                  <el-upload
+                    v-model:file-list="form.otherOrgCertFileList"
+                    list-type="picture-card"
+                    :limit="1"
+                    accept=".jpg,.jpeg,.png,image/jpeg,image/png"
+                    :before-upload="beforeImageUploadInstJpgPng"
+                    :http-request="opt => handleSingleUpload(opt, 'otherOrgCert')"
+                    :on-remove="(_f, fl) => onSingleRemove(fl, 'otherOrgCert')"
+                  >
+                    <el-icon><Plus /></el-icon>
+                  </el-upload>
+                </div>
+                <div class="upload-rules">
+                  <p>只支持 jpg、png 格式。</p>
+                </div>
+              </el-form-item>
+
+              <el-form-item label="民办非企业单位登记证书编号" prop="otherOrgCertNumber">
+                <el-input
+                  v-model="form.otherOrgCertNumber"
+                  placeholder="请输入证书编号"
+                  clearable
+                  maxlength="64"
+                  style="max-width: 480px"
+                />
+              </el-form-item>
+
+              <el-form-item prop="merchantShortName">
+                <template #label>
+                  <span class="label-with-icon">
+                    商户简称
+                    <el-tooltip placement="top" content="简称将展示给消费者,需与登记证书或品牌一致。">
+                      <el-icon class="info-icon" :size="16"><InfoFilled /></el-icon>
+                    </el-tooltip>
+                  </span>
+                </template>
+                <el-input
+                  v-model="form.merchantShortName"
+                  placeholder="请输入商户简称"
+                  clearable
+                  maxlength="64"
+                  show-word-limit
+                  style="max-width: 480px"
+                />
+              </el-form-item>
+
+              <el-form-item label="经营类目" prop="businessCategory">
+                <el-cascader
+                  v-model="form.businessCategory"
+                  :options="categoryCascaderOptions"
+                  :props="categoryCascaderProps"
+                  placeholder="请选择经营类目"
+                  clearable
+                  filterable
+                  style="width: 480px"
+                />
+              </el-form-item>
+            </template> -->
+
+            <!-- <template v-if="form.subjectType === '04'">
+              <el-form-item prop="socialCertUrl">
+                <template #label>社会团体法人登记证书</template>
+                <div class="license-upload-wrap">
+                  <el-upload
+                    v-model:file-list="form.socialCertFileList"
+                    list-type="picture-card"
+                    :limit="1"
+                    accept=".jpg,.jpeg,.png,image/jpeg,image/png"
+                    :before-upload="beforeImageUploadInstJpgPng"
+                    :http-request="opt => handleSingleUpload(opt, 'socialCert')"
+                    :on-remove="(_f, fl) => onSingleRemove(fl, 'socialCert')"
+                  >
+                    <el-icon><Plus /></el-icon>
+                  </el-upload>
+                </div>
+                <div class="upload-rules">
+                  <p>只支持 jpg、png 格式。</p>
+                </div>
+              </el-form-item>
+
+              <el-form-item label="社会团体法人登记证书编号" prop="socialCertNumber">
+                <el-input
+                  v-model="form.socialCertNumber"
+                  placeholder="请输入证书编号"
+                  clearable
+                  maxlength="64"
+                  style="max-width: 480px"
+                />
+              </el-form-item>
+
+              <el-form-item prop="merchantShortName">
+                <template #label>
+                  <span class="label-with-icon">
+                    商户简称
+                    <el-tooltip placement="top" content="简称将展示给消费者,需与法人登记证书或品牌一致。">
+                      <el-icon class="info-icon" :size="16"><InfoFilled /></el-icon>
+                    </el-tooltip>
+                  </span>
+                </template>
+                <el-input
+                  v-model="form.merchantShortName"
+                  placeholder="请输入商户简称"
+                  clearable
+                  maxlength="64"
+                  show-word-limit
+                  style="max-width: 480px"
+                />
+              </el-form-item>
+
+              <el-form-item label="经营类目" prop="businessCategory">
+                <el-cascader
+                  v-model="form.businessCategory"
+                  :options="categoryCascaderOptions"
+                  :props="categoryCascaderProps"
+                  placeholder="请选择经营类目"
+                  clearable
+                  filterable
+                  style="width: 480px"
+                />
+              </el-form-item>
+            </template> -->
+
+            <!-- <template v-if="form.subjectType === '05'">
+              <el-form-item prop="govCertUrl">
+                <template #label>
+                  <span class="label-wrap-multiline">党政机关批准设立文件/行政执法主体资格证</span>
+                </template>
+                <div class="license-upload-wrap">
+                  <el-upload
+                    v-model:file-list="form.govCertFileList"
+                    list-type="picture-card"
+                    :limit="1"
+                    accept=".jpg,.jpeg,.png,image/jpeg,image/png"
+                    :before-upload="beforeImageUploadInstJpgPng"
+                    :http-request="opt => handleSingleUpload(opt, 'govCert')"
+                    :on-remove="(_f, fl) => onSingleRemove(fl, 'govCert')"
+                  >
+                    <el-icon><Plus /></el-icon>
+                  </el-upload>
+                </div>
+                <div class="upload-rules">
+                  <p>只支持 jpg、png 格式。</p>
+                </div>
+              </el-form-item>
+
+              <el-form-item prop="govCertNumber">
+                <template #label>
+                  <span class="label-wrap-multiline">党政机关批准设立文件/行政执法主体资格证编号</span>
+                </template>
+                <el-input
+                  v-model="form.govCertNumber"
+                  placeholder="请输入编号"
+                  clearable
+                  maxlength="128"
+                  style="max-width: 480px"
+                />
+              </el-form-item>
+
+              <el-form-item prop="merchantShortName">
+                <template #label>
+                  <span class="label-with-icon">
+                    商户简称
+                    <el-tooltip placement="top" content="简称将展示给消费者,需与批准文件或主体名称一致。">
+                      <el-icon class="info-icon" :size="16"><InfoFilled /></el-icon>
+                    </el-tooltip>
+                  </span>
+                </template>
+                <el-input
+                  v-model="form.merchantShortName"
+                  placeholder="请输入商户简称"
+                  clearable
+                  maxlength="64"
+                  show-word-limit
+                  style="max-width: 480px"
+                />
+              </el-form-item>
+
+              <el-form-item label="经营类目" prop="businessCategory">
+                <el-cascader
+                  v-model="form.businessCategory"
+                  :options="categoryCascaderOptions"
+                  :props="categoryCascaderProps"
+                  placeholder="请选择经营类目"
+                  clearable
+                  filterable
+                  style="width: 480px"
+                />
+              </el-form-item>
+            </template> -->
+
+            <!-- <template v-if="form.subjectType === '06'">
+              <el-alert
+                class="individual-merchant-alert"
+                type="info"
+                :closable="false"
+                show-icon
+              >
+                使用当面付服务时,选择个人类型会有收款额度限制
+              </el-alert>
+
+              <el-form-item prop="idFrontUrl">
+                <template #label>个人身份证</template>
+                <div class="id-upload-row id-upload-row--four">
+                  <div class="id-upload-cell">
+                    <span class="id-side-label">上传人像面</span>
+                    <el-upload
+                      v-model:file-list="form.idFrontFileList"
+                      list-type="picture-card"
+                      :limit="1"
+                      accept=".jpg,.jpeg,.png,image/jpeg,image/png"
+                      :before-upload="beforeImageUploadInstJpgPng"
+                      :http-request="opt => handleSingleUpload(opt, 'idFront')"
+                      :on-remove="(_f, fl) => onSingleRemove(fl, 'idFront')"
+                    >
+                      <el-icon><Plus /></el-icon>
+                    </el-upload>
+                  </div>
+                  <div class="id-upload-cell">
+                    <span class="id-side-label">上传国徽面</span>
+                    <el-upload
+                      v-model:file-list="form.idBackFileList"
+                      list-type="picture-card"
+                      :limit="1"
+                      accept=".jpg,.jpeg,.png,image/jpeg,image/png"
+                      :before-upload="beforeImageUploadInstJpgPng"
+                      :http-request="opt => handleSingleUpload(opt, 'idBack')"
+                      :on-remove="(_f, fl) => onSingleRemove(fl, 'idBack')"
+                    >
+                      <el-icon><Plus /></el-icon>
+                    </el-upload>
+                  </div>
+                </div>
+                <div class="upload-rules">
+                  <p>
+                    说明:仅支持 jpg、png 格式。如果没有证件原件照片,可以上传证件照片复印件。
+                  </p>
+                </div>
+              </el-form-item>
+
+              <el-form-item label="个人身份证号码" prop="idNumber">
+                <el-input v-model="form.idNumber" placeholder="请输入身份证号码" clearable style="max-width: 480px" />
+              </el-form-item>
+
+              <el-form-item prop="merchantShortName">
+                <template #label>
+                  <span class="label-with-icon">
+                    商户简称
+                    <el-tooltip placement="top" content="简称将展示给消费者,需与身份证或品牌一致。">
+                      <el-icon class="info-icon" :size="16"><InfoFilled /></el-icon>
+                    </el-tooltip>
+                  </span>
+                </template>
+                <el-input
+                  v-model="form.merchantShortName"
+                  placeholder="请输入商户简称"
+                  clearable
+                  maxlength="64"
+                  show-word-limit
+                  style="max-width: 480px"
+                />
+              </el-form-item>
+
+              <el-form-item label="经营类目" prop="businessCategory">
+                <el-cascader
+                  v-model="form.businessCategory"
+                  :options="categoryCascaderOptions"
+                  :props="categoryCascaderProps"
+                  placeholder="请选择经营类目"
+                  clearable
+                  filterable
+                  style="width: 480px"
+                />
+              </el-form-item>
+            </template> -->
+
+            <template v-if="form.subjectType === '07'">
+              <el-form-item prop="licenseUrl">
+                <template #label> 营业执照 </template>
+                <div class="license-upload-wrap">
+                  <el-upload
+                    v-model:file-list="form.licenseFileList"
+                    list-type="picture-card"
+                    :limit="1"
+                    accept=".jpg,.jpeg,.png,image/jpeg,image/png"
+                    :before-upload="beforeImageUploadInstJpgPng"
+                    :http-request="opt => handleSingleUpload(opt, 'license')"
+                    :on-remove="(_f, fl) => onSingleRemove(fl, 'license')"
+                  >
+                    <el-icon><Plus /></el-icon>
+                  </el-upload>
+                </div>
+                <div class="upload-rules">
+                  <p>只支持 jpg、png 格式。</p>
+                </div>
+              </el-form-item>
+
+              <el-form-item label="营业执照编号" prop="creditCode">
+                <el-input
+                  v-model="form.creditCode"
+                  placeholder="请输入营业执照编号"
+                  clearable
+                  maxlength="32"
+                  style="max-width: 480px"
+                />
+              </el-form-item>
+
+              <el-form-item label="营业执照名称" prop="householdLicenseName">
+                <el-input
+                  v-model="form.householdLicenseName"
+                  placeholder="请输入营业执照名称"
+                  clearable
+                  maxlength="128"
+                  style="max-width: 480px"
+                />
+              </el-form-item>
+
+              <el-form-item prop="merchantShortName">
+                <template #label>
+                  <span class="label-with-icon">
+                    商户简称
+                    <el-tooltip placement="top" content="简称将展示给消费者,需与营业执照或品牌一致。">
+                      <el-icon class="info-icon" :size="16"><InfoFilled /></el-icon>
+                    </el-tooltip>
+                  </span>
+                </template>
+                <el-input v-model="form.merchantShortName" placeholder="请输入商户简称" clearable style="max-width: 480px" />
+              </el-form-item>
+
+              <el-form-item label="经营类目" prop="businessCategory">
+                <el-cascader
+                  v-model="form.businessCategory"
+                  :options="categoryCascaderOptions"
+                  :props="categoryCascaderProps"
+                  placeholder="请选择经营类目"
+                  clearable
+                  filterable
+                  style="width: 480px"
+                />
+              </el-form-item>
+            </template>
+          </section>
+
+          <!-- 法人信息 -->
+          <section id="zfb-legal" class="form-block anchor-section" v-if="form.subjectType === '01' || form.subjectType === '07'">
+            <h2 class="section-head">
+              <span class="section-bar" aria-hidden="true" />
+              法人信息
+            </h2>
+
+            <el-form-item label="法定代表人/负责人证件类型" prop="legalIdType">
+              <el-select v-model="form.legalIdType" placeholder="请选择" clearable style="width: 260px">
+                <el-option label="居民身份证" value="id_card" />
+                <el-option label="护照" value="passport" />
+                <el-option label="港澳居民来往内地通行证" value="hk_macau_pass" />
+                <el-option label="台湾居民来往大陆通行证" value="taiwan_pass" />
+              </el-select>
+            </el-form-item>
+
+            <el-form-item prop="idFrontUrl">
+              <template #label> 上传证件照片 </template>
+              <div class="id-upload-row">
+                <div class="id-upload-cell">
+                  <div class="license-upload-wrap">
+                    <el-upload
+                      v-model:file-list="form.idFrontFileList"
+                      list-type="picture-card"
+                      :limit="1"
+                      accept=".jpg,.jpeg,.png,.bmp,.gif,image/jpeg,image/png,image/bmp,image/gif"
+                      :before-upload="beforeImageUpload"
+                      :http-request="opt => handleSingleUpload(opt, 'idFront')"
+                      :on-remove="(_f, fl) => onSingleRemove(fl, 'idFront')"
+                    >
+                      <div class="id-upload-trigger">
+                        <el-icon><Plus /></el-icon>
+                        <div class="id-side-label">上传证件正面</div>
+                      </div>
+                    </el-upload>
+                  </div>
+                </div>
+                <div class="id-upload-cell">
+                  <div class="license-upload-wrap">
+                    <el-upload
+                      v-model:file-list="form.idBackFileList"
+                      list-type="picture-card"
+                      :limit="1"
+                      accept=".jpg,.jpeg,.png,.bmp,.gif,image/jpeg,image/png,image/bmp,image/gif"
+                      :before-upload="beforeImageUpload"
+                      :http-request="opt => handleSingleUpload(opt, 'idBack')"
+                      :on-remove="(_f, fl) => onSingleRemove(fl, 'idBack')"
+                    >
+                      <div class="id-upload-trigger">
+                        <el-icon><Plus /></el-icon>
+                        <div class="id-side-label">上传证件反面</div>
+                      </div>
+                    </el-upload>
+                  </div>
+                </div>
+              </div>
+              <div class="upload-rules">
+                <p>说明:仅支持.jpg、.png格式,如果没有证件原件照片,可以上传证件照片复印件。</p>
+              </div>
+            </el-form-item>
+
+            <el-form-item label="证件号" prop="idNumber">
+              <el-input v-model="form.idNumber" placeholder="请输入证件号码" clearable style="max-width: 480px" />
+            </el-form-item>
+
+            <el-form-item label="法定代表人/负责人姓名" prop="legalName">
+              <el-input v-model="form.legalName" placeholder="请输入姓名" clearable style="max-width: 480px" />
+            </el-form-item>
+          </section>
+
+          <!-- 经营信息 -->
+          <section id="zfb-business" class="form-block anchor-section">
+            <h2 class="section-head">
+              <span class="section-bar" aria-hidden="true" />
+              经营信息
+            </h2>
+
+            <el-form-item label="接入服务类型" prop="serviceTypes">
+              <div class="field-stack">
+                <el-checkbox-group v-model="form.serviceTypes" class="service-checks">
+                  <el-checkbox v-for="s in serviceTypeOptions" :key="s.value" :label="s.value">
+                    {{ s.label }}
+                  </el-checkbox>
+                </el-checkbox-group>
+                <p class="field-tip">
+                  请勾选实际售卖商品/提供服务场景(至少一项),已便为你开通所需支付权限。建议只勾选目前必须的场景,以便尽快通过入驻审核,其他支付权限可在入驻后再根据需要发起申请
+                </p>
+              </div>
+            </el-form-item>
+
+            <el-form-item prop="storefrontUrl" v-if="form.serviceTypes.includes('当面付')">
+              <template #label> 上传门头照 </template>
+              <div class="license-upload-wrap">
+                <el-upload
+                  v-model:file-list="form.storefrontFileList"
+                  list-type="picture-card"
+                  :limit="1"
+                  accept=".jpg,.jpeg,.png,.bmp,.gif,image/jpeg,image/png,image/bmp,image/gif"
+                  :before-upload="beforeImageUpload"
+                  :http-request="opt => handleSingleUpload(opt, 'storefront')"
+                  :on-remove="(_f, fl) => onSingleRemove(fl, 'storefront')"
+                >
+                  <el-icon><Plus /></el-icon>
+                </el-upload>
+              </div>
+              <div class="upload-rules">
+                <p>说明:仅支持jpg、png格式,图片需清晰完整,最多上传3张。</p>
+              </div>
+            </el-form-item>
+
+            <el-form-item prop="interiorUrl" v-if="form.serviceTypes.includes('当面付')">
+              <template #label> 上传内景照 </template>
+              <div class="license-upload-wrap">
+                <el-upload
+                  v-model:file-list="form.interiorFileList"
+                  list-type="picture-card"
+                  :limit="1"
+                  accept=".jpg,.jpeg,.png,.bmp,.gif,image/jpeg,image/png,image/bmp,image/gif"
+                  :before-upload="beforeImageUpload"
+                  :http-request="opt => handleSingleUpload(opt, 'interior')"
+                  :on-remove="(_f, fl) => onSingleRemove(fl, 'interior')"
+                >
+                  <el-icon><Plus /></el-icon>
+                </el-upload>
+              </div>
+              <div class="upload-rules">
+                <p>说明:仅支持jpg、png格式,图片需清晰完整,最多上传3张。</p>
+              </div>
+            </el-form-item>
+
+            <el-form-item label="店铺地址" prop="region" v-if="form.serviceTypes.includes('当面付')">
+              <div class="address-row">
+                <el-cascader
+                  v-model="form.region"
+                  :options="regionCascaderOptions"
+                  placeholder="省 / 市"
+                  filterable
+                  clearable
+                  style="width: 320px"
+                />
+                <el-input
+                  v-model="form.detailAddress"
+                  class="address-detail"
+                  placeholder="街道、门牌号等"
+                  clearable
+                  maxlength="200"
+                />
+              </div>
+            </el-form-item>
+
+            <el-form-item label="APP名称" prop="appName" v-if="form.serviceTypes.includes('App支付')">
+              <el-input
+                v-model="form.appName"
+                placeholder="请输入APP名称"
+                clearable
+                maxlength="64"
+                show-word-limit
+                style="max-width: 480px"
+              />
+            </el-form-item>
+
+            <el-form-item label="联系人姓名" prop="contactName">
+              <el-input v-model="form.contactName" placeholder="请输入联系人姓名" clearable style="max-width: 480px" />
+            </el-form-item>
+
+            <el-form-item label="联系人手机号" prop="contactPhone">
+              <el-input
+                v-model="form.contactPhone"
+                placeholder="请输入手机号"
+                clearable
+                maxlength="11"
+                style="max-width: 480px"
+              />
+            </el-form-item>
+
+            <el-form-item label="联系人邮箱" prop="contactEmail">
+              <el-input v-model="form.contactEmail" placeholder="请输入邮箱" clearable style="max-width: 480px" />
+            </el-form-item>
+
+            <el-form-item label="客服电话" prop="servicePhone">
+              <el-input
+                v-model="form.servicePhone"
+                placeholder="请输入客服电话"
+                clearable
+                maxlength="20"
+                style="max-width: 480px"
+              />
+            </el-form-item>
+
+            <el-form-item prop="settlementAlipayAccount">
+              <template #label> 签约支付宝账号 </template>
+              <div class="field-stack">
+                <el-input
+                  v-model="form.settlementAlipayAccount"
+                  placeholder="请输入用于收款的支付宝账号"
+                  clearable
+                  style="max-width: 480px"
+                />
+                <p class="field-tip">如商家无支付宝账号,请引导商家至支付宝注册。</p>
+              </div>
+            </el-form-item>
+          </section>
+        </el-form>
+
+        <div class="footer-actions">
+          <el-button type="primary" class="btn-primary-zfb" :loading="nextLoading" @click="onNext"> 下一步 </el-button>
+        </div>
+      </div>
+
+      <aside class="anchor-column">
+        <el-affix :offset="88">
+          <div class="anchor-card">
+            <el-anchor container=".el-main" :offset="72" :bound="48" direction="vertical">
+              <el-anchor-link href="#zfb-subject" title="主体信息" />
+              <el-anchor-link href="#zfb-legal" title="法人信息" />
+              <el-anchor-link href="#zfb-business" title="经营信息" />
+            </el-anchor>
+          </div>
+        </el-affix>
+      </aside>
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { computed, nextTick, onMounted, reactive, ref, watch } from "vue";
+import { useRoute, useRouter } from "vue-router";
+import { ElMessage } from "element-plus";
+import type { FormInstance, FormRules } from "element-plus";
+import type { UploadRequestOptions, UploadUserFile } from "element-plus";
+import { Plus, InfoFilled } from "@element-plus/icons-vue";
+import { getOcrRequestByBase64, uploadAlipayImage } from "@/api/modules/businessInfo";
+import { localGet, localSet } from "@/utils/index";
+import cityJson from "@/assets/json/city.json";
+import categoryJson from "@/views/businessInfo/category.json";
+
+const ALIPAY_JSON_KEY = "alipayJson";
+const GEEKER_USER_KEY = "geeker-user";
+
+/** 同时勾选当面付 + App 支付时,APP 名称默认与进件 sites[0].SiteName 一致 */
+const DEFAULT_ALIPAY_APP_SITE_NAME = "应用2.0签约2025092468860692";
+
+/** 进件 externalId:16 位随机数字(0–9) */
+function randomAlipayExternalId16(): string {
+  const buf = new Uint8Array(16);
+  crypto.getRandomValues(buf);
+  let s = "";
+  for (let i = 0; i < 16; i++) {
+    s += String(buf[i]! % 10);
+  }
+  return s;
+}
+
+const formRef = ref<FormInstance>();
+const nextLoading = ref(false);
+const router = useRouter();
+const route = useRoute();
+
+function resolveAlipayUploadStoreId(): string | number | null {
+  const q = route.query.storeId;
+  if (q !== undefined && q !== null && String(q).trim() !== "") {
+    return Array.isArray(q) ? q[0]! : q;
+  }
+  const geeker = localGet(GEEKER_USER_KEY) as { userInfo?: { storeId?: string | number | null } } | null | undefined;
+  const sid = geeker?.userInfo?.storeId ?? localGet("createdId");
+  if (sid === undefined || sid === null || sid === "") return null;
+  return sid;
+}
+/** 支付宝进件步骤:0 商家信息 / 1 结算信息 / 2 提交审核 */
+const zfbStepActive = ref(0);
+
+type CategoryJsonNode = {
+  code?: string;
+  name?: string;
+  parentCode?: string;
+  parentName?: string;
+  level?: number;
+  display?: boolean;
+  status?: string;
+  sortNum?: number;
+  childrenNodes?: CategoryJsonNode[];
+};
+
+type CategoryCascaderNode = { value: string; label: string; children?: CategoryCascaderNode[] };
+
+/**
+ * 二级经营类目:一级为 level=1(name/code),二级为其 childrenNodes 中 level=2 的 name/code
+ */
+function buildCategoryCascaderOptions(root: unknown): CategoryCascaderNode[] {
+  const list = (root as { data?: { childrenNodes?: CategoryJsonNode[] } })?.data?.childrenNodes;
+  if (!Array.isArray(list)) return [];
+  return list
+    .filter(n => n && typeof n === "object" && n.level === 1 && n.code && n.name && n.status === "VALID" && n.display !== false)
+    .sort((a, b) => (a.sortNum ?? 0) - (b.sortNum ?? 0))
+    .map(parent => {
+      const children = (parent.childrenNodes || [])
+        .filter(
+          ch =>
+            ch && typeof ch === "object" && ch.level === 2 && ch.code && ch.name && ch.status === "VALID" && ch.display !== false
+        )
+        .sort((a, b) => (a.sortNum ?? 0) - (b.sortNum ?? 0))
+        .map(ch => ({
+          value: String(ch.code),
+          label: String(ch.name)
+        }));
+      return {
+        value: String(parent.code),
+        label: String(parent.name),
+        children
+      };
+    })
+    .filter(p => p.children && p.children.length > 0);
+}
+
+const categoryCascaderOptions = buildCategoryCascaderOptions(categoryJson);
+
+const categoryCascaderProps = {
+  value: "value",
+  label: "label",
+  children: "children",
+  emitPath: true
+};
+
+const subjectTypeOptions = [
+  { label: "企业", value: "01" },
+  // { label: "事业单位", value: "02" },
+  // { label: "民办非企业组织", value: "03" },
+  // { label: "社会团体", value: "04" },
+  // { label: "党政及国家机关", value: "05" },
+  // { label: "个人商户", value: "06" },
+  { label: "个体工商户", value: "07" }
+];
+
+const serviceTypeOptions = [
+  { label: "当面付", value: "当面付" },
+  { label: "App支付", value: "App支付" }
+];
+
+type CityJsonEntry = { name: string; adCode: string; cityCode: string };
+type CityJsonRoot = { cityList: { letter: string; list: CityJsonEntry[] }[] };
+
+const PROVINCE_ROWS: [string, string][] = [
+  ["11", "北京市"],
+  ["12", "天津市"],
+  ["13", "河北省"],
+  ["14", "山西省"],
+  ["15", "内蒙古自治区"],
+  ["21", "辽宁省"],
+  ["22", "吉林省"],
+  ["23", "黑龙江省"],
+  ["31", "上海市"],
+  ["32", "江苏省"],
+  ["33", "浙江省"],
+  ["34", "安徽省"],
+  ["35", "福建省"],
+  ["36", "江西省"],
+  ["37", "山东省"],
+  ["41", "河南省"],
+  ["42", "湖北省"],
+  ["43", "湖南省"],
+  ["44", "广东省"],
+  ["45", "广西壮族自治区"],
+  ["46", "海南省"],
+  ["50", "重庆市"],
+  ["51", "四川省"],
+  ["52", "贵州省"],
+  ["53", "云南省"],
+  ["54", "西藏自治区"],
+  ["61", "陕西省"],
+  ["62", "甘肃省"],
+  ["63", "青海省"],
+  ["64", "宁夏回族自治区"],
+  ["65", "新疆维吾尔自治区"],
+  ["71", "台湾省"],
+  ["81", "香港特别行政区"],
+  ["82", "澳门特别行政区"]
+];
+const PROVINCE_BY_PREFIX = Object.fromEntries(PROVINCE_ROWS) as Record<string, string>;
+const PROVINCE_PREFIX_ORDER = PROVINCE_ROWS.map(([k]) => k);
+
+function buildProvinceCityOptions(): {
+  label: string;
+  value: string;
+  cities: { label: string; value: string }[];
+}[] {
+  const root = cityJson as CityJsonRoot;
+  const flat = root.cityList.flatMap(g => g.list);
+  const bucket = new Map<string, Map<string, CityJsonEntry>>();
+  for (const c of flat) {
+    const digits = String(c.adCode ?? "").replace(/\D/g, "");
+    const code = digits.length >= 6 ? digits.slice(-6) : digits.padStart(6, "0");
+    if (code.length !== 6) continue;
+    const prefix = code.slice(0, 2);
+    if (!PROVINCE_BY_PREFIX[prefix]) continue;
+    if (!bucket.has(prefix)) bucket.set(prefix, new Map());
+    bucket.get(prefix)!.set(c.adCode, c);
+  }
+  const out = [...bucket.entries()].map(([prefix, cityMap]) => ({
+    value: prefix,
+    label: PROVINCE_BY_PREFIX[prefix],
+    cities: [...cityMap.values()]
+      .sort((a, b) => a.name.localeCompare(b.name, "zh-CN"))
+      .map(ci => ({ label: ci.name, value: ci.adCode }))
+  }));
+  out.sort((a, b) => {
+    const ia = PROVINCE_PREFIX_ORDER.indexOf(a.value);
+    const ib = PROVINCE_PREFIX_ORDER.indexOf(b.value);
+    return (ia === -1 ? 999 : ia) - (ib === -1 ? 999 : ib);
+  });
+  return out;
+}
+
+const provinceCityOptions = buildProvinceCityOptions();
+
+const regionCascaderOptions = computed(() =>
+  provinceCityOptions.map(p => ({
+    value: p.value,
+    label: p.label,
+    children: p.cities.map(c => ({ value: c.value, label: c.label }))
+  }))
+);
+
+type UploadKind =
+  | "license"
+  | "idFront"
+  | "idBack"
+  | "storefront"
+  | "interior"
+  | "institutionCert"
+  | "otherOrgCert"
+  | "socialCert"
+  | "govCert";
+
+const form = reactive<{
+  subjectType: string;
+  licenseFileList: UploadUserFile[];
+  licenseUrl: string;
+  /** 营业执照上传接口返回的 image_id,供 alipayJson.certImage */
+  licenseImageId: string;
+  creditCode: string;
+  householdLicenseName: string;
+  merchantShortName: string;
+  businessTermRange: [string, string] | undefined;
+  institutionCertFileList: UploadUserFile[];
+  institutionCertUrl: string;
+  institutionCertNumber: string;
+  otherOrgCertFileList: UploadUserFile[];
+  otherOrgCertUrl: string;
+  otherOrgCertNumber: string;
+  socialCertFileList: UploadUserFile[];
+  socialCertUrl: string;
+  socialCertNumber: string;
+  govCertFileList: UploadUserFile[];
+  govCertUrl: string;
+  govCertNumber: string;
+  businessCategory: string[];
+  legalIdType: string;
+  idFrontFileList: UploadUserFile[];
+  idFrontUrl: string;
+  idBackFileList: UploadUserFile[];
+  idBackUrl: string;
+  idNumber: string;
+  legalName: string;
+  serviceTypes: string[];
+  storefrontFileList: UploadUserFile[];
+  storefrontUrl: string;
+  /** 上传接口返回的 image_id,供 alipayJson.outDoorImages */
+  storefrontImageId: string;
+  interiorFileList: UploadUserFile[];
+  interiorUrl: string;
+  /** 上传接口返回的 image_id,供 alipayJson.inDoorImages */
+  interiorImageId: string;
+  institutionStorefrontFileList: UploadUserFile[];
+  institutionStorefrontUrls: string[];
+  institutionInteriorFileList: UploadUserFile[];
+  institutionInteriorUrls: string[];
+  region: string[];
+  detailAddress: string;
+  appName: string;
+  contactName: string;
+  contactPhone: string;
+  contactEmail: string;
+  servicePhone: string;
+  settlementAlipayAccount: string;
+}>({
+  subjectType: "01",
+  licenseFileList: [],
+  licenseUrl: "",
+  licenseImageId: "",
+  creditCode: "",
+  householdLicenseName: "",
+  merchantShortName: "",
+  businessTermRange: undefined,
+  institutionCertFileList: [],
+  institutionCertUrl: "",
+  institutionCertNumber: "",
+  otherOrgCertFileList: [],
+  otherOrgCertUrl: "",
+  otherOrgCertNumber: "",
+  socialCertFileList: [],
+  socialCertUrl: "",
+  socialCertNumber: "",
+  govCertFileList: [],
+  govCertUrl: "",
+  govCertNumber: "",
+  businessCategory: [],
+  legalIdType: "",
+  idFrontFileList: [],
+  idFrontUrl: "",
+  idBackFileList: [],
+  idBackUrl: "",
+  idNumber: "",
+  legalName: "",
+  serviceTypes: [],
+  storefrontFileList: [],
+  storefrontUrl: "",
+  storefrontImageId: "",
+  interiorFileList: [],
+  interiorUrl: "",
+  interiorImageId: "",
+  institutionStorefrontFileList: [],
+  institutionStorefrontUrls: [],
+  institutionInteriorFileList: [],
+  institutionInteriorUrls: [],
+  region: [],
+  detailAddress: "",
+  appName: "",
+  contactName: "",
+  contactPhone: "",
+  contactEmail: "",
+  servicePhone: "",
+  settlementAlipayAccount: ""
+});
+
+watch(
+  () => form.serviceTypes.slice().sort().join("\0"),
+  () => {
+    const hasFace = form.serviceTypes.includes("当面付");
+    const hasApp = form.serviceTypes.includes("App支付");
+    if (hasFace && hasApp && !String(form.appName || "").trim()) {
+      form.appName = DEFAULT_ALIPAY_APP_SITE_NAME;
+    }
+  }
+);
+
+/** 用户切换到个体工商户时清空本页字段,避免企业侧已填数据带入个体户(与初始 form 一致,不改 subjectType) */
+function clearZfbFormExceptSubjectType() {
+  form.licenseFileList = [];
+  form.licenseUrl = "";
+  form.licenseImageId = "";
+  form.creditCode = "";
+  form.householdLicenseName = "";
+  form.merchantShortName = "";
+  form.businessTermRange = undefined;
+  form.institutionCertFileList = [];
+  form.institutionCertUrl = "";
+  form.institutionCertNumber = "";
+  form.otherOrgCertFileList = [];
+  form.otherOrgCertUrl = "";
+  form.otherOrgCertNumber = "";
+  form.socialCertFileList = [];
+  form.socialCertUrl = "";
+  form.socialCertNumber = "";
+  form.govCertFileList = [];
+  form.govCertUrl = "";
+  form.govCertNumber = "";
+  form.businessCategory = [];
+  form.legalIdType = "";
+  form.idFrontFileList = [];
+  form.idFrontUrl = "";
+  form.idBackFileList = [];
+  form.idBackUrl = "";
+  form.idNumber = "";
+  form.legalName = "";
+  form.serviceTypes = [];
+  form.storefrontFileList = [];
+  form.storefrontUrl = "";
+  form.storefrontImageId = "";
+  form.interiorFileList = [];
+  form.interiorUrl = "";
+  form.interiorImageId = "";
+  form.institutionStorefrontFileList = [];
+  form.institutionStorefrontUrls = [];
+  form.institutionInteriorFileList = [];
+  form.institutionInteriorUrls = [];
+  form.region = [];
+  form.detailAddress = "";
+  form.appName = "";
+  form.contactName = "";
+  form.contactPhone = "";
+  form.contactEmail = "";
+  form.servicePhone = "";
+  form.settlementAlipayAccount = "";
+}
+
+function onSubjectTypeChange(val: string | number | boolean | undefined) {
+  if (String(val ?? "") !== "07") return;
+  clearZfbFormExceptSubjectType();
+  nextTick(() => formRef.value?.clearValidate());
+}
+
+/** 支付宝图片上传接口:原始二进制最大 10MB(与接口文档一致) */
+const MAX_ALIPAY_IMAGE_BYTES = 10 * 1024 * 1024;
+
+/** 事业单位材料:仅 jpg / png(与页面说明一致) */
+function beforeImageUploadInstJpgPng(file: File) {
+  const name = file.name?.toLowerCase() || "";
+  const okExt = /\.(jpe?g|png)$/i.test(name);
+  const okMime = ["image/jpeg", "image/png"].includes(file.type);
+  if (!okExt && !okMime) {
+    ElMessage.error("仅支持 jpg、png 格式");
+    return false;
+  }
+  if (file.size > MAX_ALIPAY_IMAGE_BYTES) {
+    ElMessage.error("文件大小不能超过 10M");
+    return false;
+  }
+  return true;
+}
+
+function beforeImageUpload(file: File) {
+  const name = file.name?.toLowerCase() || "";
+  const okExt = /\.(jpe?g|png|bmp|gif)$/i.test(name);
+  const okMime = ["image/jpeg", "image/png", "image/bmp", "image/gif"].includes(file.type);
+  if (!okExt && !okMime) {
+    ElMessage.error("图片只支持 JPG、BMP、PNG、GIF 格式");
+    return false;
+  }
+  if (file.size > MAX_ALIPAY_IMAGE_BYTES) {
+    ElMessage.error("文件大小不能超过 10M");
+    return false;
+  }
+  return true;
+}
+
+/** 解析 image_type:扩展名 3~16 字符,jpeg 归一为 jpg */
+function resolveAlipayImageType(file: File): string | null {
+  const name = file.name || "";
+  const extMatch = /\.([a-zA-Z0-9]{1,16})$/i.exec(name);
+  let ext = extMatch ? extMatch[1].toLowerCase() : "";
+  if (ext === "jpeg") ext = "jpg";
+  if (ext && ext.length >= 3 && ext.length <= 16) return ext;
+  const mime = file.type;
+  if (mime === "image/jpeg") return "jpg";
+  if (mime === "image/png") return "png";
+  if (mime === "image/gif") return "gif";
+  if (mime === "image/bmp") return "bmp";
+  return null;
+}
+
+/** 解析支付宝/通用上传返回;兼容 data 为 JSON 字符串(直付通 ant_merchant_expand_indirect_image_upload_response) */
+function parseMediaUploadResult(res: any): { fileUrl: string; mediaId: string; errMsg: string } {
+  const errMsg = String(res?.msg ?? "").trim();
+  let payload = res?.data;
+  if (payload === undefined) payload = res;
+
+  if (typeof payload === "string") {
+    const s = payload.trim();
+    if (/^https?:\/\//i.test(s)) return { fileUrl: s, mediaId: "", errMsg };
+    if ((s.startsWith("{") || s.startsWith("[")) && s.length > 1) {
+      try {
+        payload = JSON.parse(s);
+      } catch {
+        if (s) return { fileUrl: "", mediaId: s, errMsg };
+        return { fileUrl: "", mediaId: "", errMsg };
+      }
+    } else if (s) {
+      return { fileUrl: "", mediaId: s, errMsg };
+    } else {
+      return { fileUrl: "", mediaId: "", errMsg };
+    }
+  }
+
+  if (!payload || typeof payload !== "object") {
+    return { fileUrl: "", mediaId: "", errMsg };
+  }
+
+  let body: any = payload;
+  if ("data" in payload && payload.data !== undefined) {
+    if (typeof payload.data === "string") {
+      const inner = payload.data.trim();
+      if (/^https?:\/\//i.test(inner)) return { fileUrl: inner, mediaId: "", errMsg };
+      if ((inner.startsWith("{") || inner.startsWith("[")) && inner.length > 1) {
+        try {
+          body = JSON.parse(inner);
+        } catch {
+          if (inner) return { fileUrl: "", mediaId: inner, errMsg };
+          body = payload;
+        }
+      } else if (inner) {
+        return { fileUrl: "", mediaId: inner, errMsg };
+      }
+    } else if (payload.data && typeof payload.data === "object") {
+      body = payload.data;
+    }
+  }
+
+  if (body && typeof body === "object" && "data" in body && body.data !== undefined) {
+    if (typeof body.data === "string") {
+      const inner = body.data.trim();
+      if (/^https?:\/\//i.test(inner)) return { fileUrl: inner, mediaId: "", errMsg };
+      if ((inner.startsWith("{") || inner.startsWith("[")) && inner.length > 1) {
+        try {
+          body = JSON.parse(inner);
+        } catch {
+          if (inner) return { fileUrl: "", mediaId: inner, errMsg };
+        }
+      } else if (inner) {
+        return { fileUrl: "", mediaId: inner, errMsg };
+      }
+    } else if (body.data && typeof body.data === "object") {
+      body = body.data;
+    }
+  }
+
+  const antUpload =
+    body?.ant_merchant_expand_indirect_image_upload_response ?? body?.antMerchantExpandIndirectImageUploadResponse;
+
+  const fileUrl = String(
+    body?.url ?? body?.fileUrl ?? body?.imageUrl ?? body?.image_url ?? body?.picUrl ?? body?.ossUrl ?? body?.file_path ?? ""
+  ).trim();
+  const mediaId = String(
+    antUpload?.image_id ??
+      antUpload?.imageId ??
+      body?.image_id ??
+      body?.imageId ??
+      body?.resource_id ??
+      body?.resourceId ??
+      body?.media_id ??
+      body?.mediaId ??
+      body?.outBizNo ??
+      body?.pictureId ??
+      ""
+  ).trim();
+  return { fileUrl, mediaId, errMsg };
+}
+
+/** 与支付宝上传返回常见的 object / 文件名一致 */
+const ALIPAY_UPLOAD_IMAGE_FILE_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\.(jpe?g|png)$/i;
+
+function extractAlipayFilenameFromImageUrl(url: string): string {
+  const s = String(url || "").trim();
+  if (!s || !/^https?:\/\//i.test(s)) return "";
+  try {
+    const seg = decodeURIComponent(new URL(s).pathname.split("/").filter(Boolean).pop() || "");
+    if (ALIPAY_UPLOAD_IMAGE_FILE_RE.test(seg) || /\.(jpe?g|png)$/i.test(seg)) return seg;
+  } catch {
+    /* ignore */
+  }
+  return "";
+}
+
+/** 深度遍历响应,取 image_id 等字段(兼容多层 data / 字段名差异) */
+function deepPickAlipayImageId(node: any, depth = 0): string {
+  if (depth > 14 || node === null || node === undefined) return "";
+  if (typeof node === "string") {
+    const t = node.trim();
+    if (ALIPAY_UPLOAD_IMAGE_FILE_RE.test(t)) return t;
+    if (t.startsWith("{") && t.includes("image")) {
+      try {
+        return deepPickAlipayImageId(JSON.parse(t), depth + 1);
+      } catch {
+        return "";
+      }
+    }
+    return "";
+  }
+  if (typeof node !== "object") return "";
+  if (Array.isArray(node)) {
+    for (const x of node) {
+      const r = deepPickAlipayImageId(x, depth + 1);
+      if (r) return r;
+    }
+    return "";
+  }
+  const keys = ["image_id", "imageId", "ImageId", "fileName", "file_name", "objectName", "object_name", "key", "picName"];
+  for (const k of keys) {
+    if (!(k in node) || node[k] == null) continue;
+    const v = String(node[k]).trim();
+    if (!v) continue;
+    if (/^https?:\/\//i.test(v)) {
+      const fromUrl = extractAlipayFilenameFromImageUrl(v);
+      if (fromUrl) return fromUrl;
+    } else {
+      const base = v.split(/[/\\]/).pop() || v;
+      if (base) return base.trim();
+    }
+  }
+  for (const v of Object.values(node)) {
+    const r = deepPickAlipayImageId(v, depth + 1);
+    if (r) return r;
+  }
+  return "";
+}
+
+/** 上传成功后得到进件用图片名:扁平解析 → 深度查找 → 从返回的图片 URL 截取 */
+function resolveAlipayUploadImageId(res: any, fileUrl: string, mediaId: string): string {
+  let id = String(mediaId || "").trim();
+  if (id) return id.split(/[/\\]/).pop() || id;
+  id = deepPickAlipayImageId(res);
+  if (id) return id.split(/[/\\]/).pop() || id;
+  return extractAlipayFilenameFromImageUrl(fileUrl);
+}
+
+function isAlipayUploadHttpSuccess(res: any): boolean {
+  return res?.code === 200 || res?.code === "200";
+}
+
+/** 与 subjectInfo:营业执照 OCR 响应解析 */
+function pickBusinessLicenseOcrFields(res: any) {
+  const raw = res?.data ?? res;
+  let node: any = raw;
+  if (node && typeof node === "object" && "data" in node && node.data !== undefined) {
+    node = node.data;
+  }
+  const item = Array.isArray(node) ? node[0] : node;
+  if (!item || typeof item !== "object") {
+    return { creditCode: "", companyName: "", legalPerson: "" };
+  }
+  return {
+    creditCode: String(item.creditCode ?? item.credit_code ?? "").trim(),
+    companyName: String(item.companyName ?? item.company_name ?? "").trim(),
+    legalPerson: String(item.legalPerson ?? item.legal_person ?? "").trim()
+  };
+}
+
+/** 事业单位法人证书 OCR:证书编号、单位名称(回显商户简称) */
+function pickInstitutionCertOcrFields(res: any): { certNumber: string; orgName: string } {
+  const base = pickBusinessLicenseOcrFields(res);
+  const raw = res?.data ?? res;
+  let node: any = raw;
+  if (node && typeof node === "object" && "data" in node && node.data !== undefined) {
+    node = node.data;
+  }
+  const item = Array.isArray(node) ? node[0] : node;
+  let certNumber = base.creditCode;
+  let orgName = base.companyName;
+  if (item && typeof item === "object") {
+    if (!certNumber) {
+      certNumber = String(
+        item.certNumber ??
+          item.certificateNumber ??
+          item.cert_no ??
+          item.certificateNo ??
+          item.registrationNumber ??
+          item.registration_no ??
+          ""
+      ).trim();
+    }
+    if (!orgName) {
+      orgName = String(item.companyName ?? item.company_name ?? item.orgName ?? item.unitName ?? item.name ?? "").trim();
+    }
+  }
+  return { certNumber, orgName };
+}
+
+/** 身份证有效期 → YYYY-MM-DD(与 subjectInfo 一致) */
+function splitIdCardValidPeriod(raw: string): { begin: string; end: string } {
+  const s = (raw || "").trim();
+  if (!s) return { begin: "", end: "" };
+  if (/长期|长期有效/.test(s)) return { begin: "", end: "长期" };
+  const norm = s
+    .replace(/年|月|日/g, ".")
+    .replace(/\.+/g, ".")
+    .trim();
+  const parts = norm.split(/[-至~~]/);
+  const normOne = (p: string) => {
+    const m = p.trim().match(/(\d{4})\D*(\d{1,2})\D*(\d{1,2})/);
+    if (m) return `${m[1]}-${m[2].padStart(2, "0")}-${m[3].padStart(2, "0")}`;
+    return p.trim();
+  };
+  if (parts.length >= 2) {
+    return { begin: normOne(parts[0]), end: normOne(parts[1]) };
+  }
+  return { begin: "", end: "" };
+}
+
+/** 与 subjectInfo:身份证 OCR 响应解析 */
+function pickIdCardPortraitOcrFields(res: any): {
+  name: string;
+  idNumber: string;
+  idCardAddress: string;
+  cardPeriodBegin: string;
+  cardPeriodEnd: string;
+} {
+  const raw = res?.data ?? res;
+  let node: any = raw;
+  if (node && typeof node === "object" && "data" in node && node.data !== undefined) {
+    node = node.data;
+  }
+  const arr = Array.isArray(node) ? node : [node];
+  const item = arr[0];
+  const item2 = arr[1];
+  if (!item || typeof item !== "object") {
+    return { name: "", idNumber: "", idCardAddress: "", cardPeriodBegin: "", cardPeriodEnd: "" };
+  }
+  let name = String(item.name ?? item.userName ?? "").trim();
+  let idNumber = String(item.idNumber ?? item.id_number ?? item.idCard ?? item.id_card ?? "").trim();
+  const faceData = item.face?.data || item2?.face?.data;
+  const backData = item.back?.data || item2?.back?.data;
+  if (faceData && typeof faceData === "object") {
+    if (!name) name = String(faceData.name ?? "").trim();
+    if (!idNumber) idNumber = String(faceData.idNumber ?? faceData.id_number ?? "").trim();
+  }
+  let idCardAddress = "";
+  if (backData && typeof backData === "object") {
+    idCardAddress = String(backData.address ?? backData.registeredAddress ?? backData.issueAuthority ?? "").trim();
+  }
+  if (faceData && typeof faceData === "object" && !idCardAddress) {
+    idCardAddress = String(faceData.address ?? "").trim();
+  }
+  const faceKv = item.face?.prism_keyValueInfo || item2?.face?.prism_keyValueInfo;
+  if (Array.isArray(faceKv)) {
+    for (const row of faceKv) {
+      if (row?.key === "name" && row?.value && !name) name = String(row.value).trim();
+      if (row?.key === "idNumber" && row?.value && !idNumber) idNumber = String(row.value).trim();
+      if (row?.key === "address" && row?.value && !idCardAddress) {
+        idCardAddress = String(row.value).trim();
+      }
+    }
+  }
+  const backKv = item.back?.prism_keyValueInfo || item2?.back?.prism_keyValueInfo;
+  let validPeriodFromKv = "";
+  if (Array.isArray(backKv)) {
+    for (const row of backKv) {
+      if (row?.key === "address" && row?.value && !idCardAddress) {
+        idCardAddress = String(row.value).trim();
+      }
+      if (row?.value) {
+        const keyRaw = String(row.key || "");
+        if (/有效期限|有效期|失效日期|签发日期|validPeriod|validDate|valid_period/i.test(keyRaw)) {
+          const v = String(row.value).trim();
+          if (v && !validPeriodFromKv) validPeriodFromKv = v;
+        }
+      }
+    }
+  }
+  let vp = String(
+    (backData && (backData.validPeriod ?? backData.validDate)) ||
+      (faceData && (faceData.validPeriod ?? faceData.validDate)) ||
+      (item && (item.validPeriod ?? item.validDate)) ||
+      (item2 && (item2.validPeriod ?? item2.validDate)) ||
+      ""
+  ).trim();
+  if (!vp && validPeriodFromKv) vp = validPeriodFromKv;
+  const { begin: cardPeriodBegin, end: cardPeriodEnd } = splitIdCardValidPeriod(vp);
+  return { name, idNumber, idCardAddress, cardPeriodBegin, cardPeriodEnd };
+}
+
+function isOcrSuccess(res: any): boolean {
+  return res?.code === 200 || res?.code === "200";
+}
+
+/** 上传成功后按类型调用 OCR 并写入表单(与 subjectInfo 请求体一致:imageFile + ocrType) */
+async function runOcrAfterZfbUpload(kind: UploadKind, file: File) {
+  if (kind === "license") {
+    const formData = new FormData();
+    formData.append("imageFile", file, file.name || "license.jpg");
+    formData.append("ocrType", "BUSINESS_LICENSE");
+    const res: any = await getOcrRequestByBase64(formData);
+    if (isOcrSuccess(res)) {
+      const fields = pickBusinessLicenseOcrFields(res);
+      if (fields.creditCode) form.creditCode = fields.creditCode;
+      if (form.subjectType === "07") {
+        if (fields.companyName) {
+          form.householdLicenseName = fields.companyName;
+          form.merchantShortName = fields.companyName;
+        }
+      } else {
+        if (fields.companyName) form.merchantShortName = fields.companyName;
+        if (fields.legalPerson) form.legalName = fields.legalPerson;
+      }
+      ElMessage.success("营业执照识别成功");
+    } else {
+      ElMessage.warning(res?.msg || "营业执照识别未通过,请核对照片清晰度");
+    }
+    return;
+  }
+  if (kind === "institutionCert") {
+    const formData = new FormData();
+    formData.append("imageFile", file, file.name || "institution-cert.jpg");
+    formData.append("ocrType", "BUSINESS_LICENSE");
+    const res: any = await getOcrRequestByBase64(formData);
+    if (isOcrSuccess(res)) {
+      const f = pickInstitutionCertOcrFields(res);
+      if (f.certNumber) form.institutionCertNumber = f.certNumber;
+      if (f.orgName) form.merchantShortName = f.orgName;
+      ElMessage.success("事业单位法人证书识别成功");
+    } else {
+      ElMessage.warning(res?.msg || "事业单位法人证书识别未通过,请核对照片清晰度");
+    }
+    return;
+  }
+  if (kind === "idFront") {
+    const formData = new FormData();
+    formData.append("imageFile", file, file.name || "id-portrait.jpg");
+    formData.append("ocrType", "ID_CARD");
+    const res: any = await getOcrRequestByBase64(formData);
+    if (isOcrSuccess(res)) {
+      const f = pickIdCardPortraitOcrFields(res);
+      if (f.name) form.legalName = f.name;
+      if (f.idNumber) form.idNumber = f.idNumber;
+      if (f.cardPeriodBegin && f.cardPeriodEnd) {
+        form.businessTermRange = [f.cardPeriodBegin, f.cardPeriodEnd];
+      }
+      ElMessage.success("身份证人像面识别成功");
+    } else {
+      ElMessage.warning(res?.msg || "身份证人像面识别未通过,请核对照片清晰度");
+    }
+    return;
+  }
+  if (kind === "idBack") {
+    const formData = new FormData();
+    formData.append("imageFile", file, file.name || "id-emblem.jpg");
+    formData.append("ocrType", "ID_CARD");
+    const res: any = await getOcrRequestByBase64(formData);
+    if (isOcrSuccess(res)) {
+      const f = pickIdCardPortraitOcrFields(res);
+      if (f.cardPeriodBegin && f.cardPeriodEnd) {
+        form.businessTermRange = [f.cardPeriodBegin, f.cardPeriodEnd];
+      }
+      if (f.cardPeriodBegin || f.cardPeriodEnd) {
+        ElMessage.success("身份证国徽面识别成功");
+      } else {
+        ElMessage.warning("未识别到有效期限,请确认国徽面照片清晰完整");
+      }
+    } else {
+      ElMessage.warning(res?.msg || "身份证国徽面识别未通过,请核对照片清晰度");
+    }
+  }
+}
+
+function urlFieldFor(kind: UploadKind): keyof typeof form {
+  const map: Record<UploadKind, keyof typeof form> = {
+    license: "licenseUrl",
+    idFront: "idFrontUrl",
+    idBack: "idBackUrl",
+    storefront: "storefrontUrl",
+    interior: "interiorUrl",
+    institutionCert: "institutionCertUrl",
+    otherOrgCert: "otherOrgCertUrl",
+    socialCert: "socialCertUrl",
+    govCert: "govCertUrl"
+  };
+  return map[kind];
+}
+
+async function handleSingleUpload(options: UploadRequestOptions, kind: UploadKind) {
+  const uploadFileItem = options.file as UploadUserFile;
+  const raw = uploadFileItem.raw || uploadFileItem;
+  const file = raw instanceof File ? raw : null;
+  if (!file) return;
+
+  const field = urlFieldFor(kind);
+  uploadFileItem.status = "uploading";
+  try {
+    if (file.size > MAX_ALIPAY_IMAGE_BYTES) {
+      uploadFileItem.status = "fail";
+      ElMessage.error("文件大小不能超过 10M");
+      return;
+    }
+    const imageType = resolveAlipayImageType(file);
+    if (!imageType) {
+      uploadFileItem.status = "fail";
+      ElMessage.error("无法识别图片格式,请使用带扩展名的文件(如 .jpg、.png)");
+      return;
+    }
+    const storeId = resolveAlipayUploadStoreId();
+    // if (storeId === null) {
+    //   uploadFileItem.status = "fail";
+    //   ElMessage.error("未获取到门店 storeId,请重新登录或通过链接传入 storeId");
+    //   return;
+    // }
+    const res: any = await uploadAlipayImage({
+      storeId,
+      imageType,
+      imageContent: file
+    });
+    const { fileUrl, mediaId, errMsg } = parseMediaUploadResult(res);
+    const httpOk = isAlipayUploadHttpSuccess(res);
+    const hasMediaRef = !!(fileUrl || mediaId);
+    const resolvedImageId = resolveAlipayUploadImageId(res, fileUrl, mediaId);
+
+    if (hasMediaRef || httpOk) {
+      uploadFileItem.status = "success";
+      if (fileUrl) {
+        uploadFileItem.url = fileUrl;
+      } else {
+        uploadFileItem.url = URL.createObjectURL(file);
+      }
+      uploadFileItem.response = { media_id: resolvedImageId, url: fileUrl };
+      (form as any)[field] = fileUrl || mediaId || (httpOk ? uploadFileItem.url : "");
+      if (kind === "storefront") {
+        form.storefrontImageId = resolvedImageId;
+      }
+      if (kind === "interior") {
+        form.interiorImageId = resolvedImageId;
+      }
+      if (kind === "license") {
+        form.licenseImageId = resolvedImageId;
+      }
+
+      const needOcr = kind === "license" || kind === "idFront" || kind === "idBack" || kind === "institutionCert";
+      if (needOcr) {
+        try {
+          await runOcrAfterZfbUpload(kind, file);
+          nextTick(() => {
+            const f = formRef.value;
+            if (!f) return;
+            if (kind === "license") {
+              f.validateField("creditCode").catch(() => {});
+              f.validateField("merchantShortName").catch(() => {});
+              if (form.subjectType === "07") {
+                f.validateField("householdLicenseName").catch(() => {});
+              } else {
+                f.validateField("legalName").catch(() => {});
+              }
+            } else if (kind === "institutionCert") {
+              f.validateField("institutionCertNumber").catch(() => {});
+              f.validateField("merchantShortName").catch(() => {});
+            } else if (kind === "idFront") {
+              f.validateField("legalName").catch(() => {});
+              f.validateField("idNumber").catch(() => {});
+              f.validateField("businessTermRange").catch(() => {});
+            } else if (kind === "idBack") {
+              f.validateField("businessTermRange").catch(() => {});
+            }
+          });
+        } catch {
+          ElMessage.warning("识别服务暂时不可用,请稍后重试或手动填写");
+        }
+      }
+    } else {
+      uploadFileItem.status = "fail";
+      ElMessage.error(errMsg || res?.msg || "上传失败,未返回可用结果");
+    }
+  } catch {
+    uploadFileItem.status = "fail";
+    ElMessage.error("上传失败,请稍后重试");
+  }
+  formRef.value?.validateField(field as string).catch(() => {});
+}
+
+function onSingleRemove(fileList: UploadUserFile[], kind: UploadKind) {
+  const field = urlFieldFor(kind);
+  if (!fileList.length) {
+    (form as any)[field] = "";
+    if (kind === "storefront") form.storefrontImageId = "";
+    if (kind === "interior") form.interiorImageId = "";
+    if (kind === "license") form.licenseImageId = "";
+  } else {
+    const first = fileList[0] as UploadUserFile & {
+      url?: string;
+      response?: { url?: string; media_id?: string };
+    };
+    (form as any)[field] = first?.url || first?.response?.url || "";
+    if (kind === "storefront") {
+      form.storefrontImageId = String(first?.response?.media_id || "").trim();
+    }
+    if (kind === "interior") {
+      form.interiorImageId = String(first?.response?.media_id || "").trim();
+    }
+    if (kind === "license") {
+      form.licenseImageId = String(first?.response?.media_id || "").trim();
+    }
+  }
+  formRef.value?.validateField(field as string).catch(() => {});
+}
+
+/** alipayJson.service 仅传接入类型的 value(当面付 / App支付),不把 face_to_face、app 等内部码传给接口 */
+function serviceValuesForAlipayPayload(selected: string[]): string[] {
+  const codeToValue: Record<string, string> = {
+    face_to_face: "当面付",
+    app: "App支付"
+  };
+  const allowed = new Set(serviceTypeOptions.map(o => o.value));
+  const out: string[] = [];
+  const seen = new Set<string>();
+  for (const s of selected) {
+    const v = codeToValue[s] ?? (allowed.has(s) ? s : "");
+    if (v && !seen.has(v)) {
+      seen.add(v);
+      out.push(v);
+    }
+  }
+  return out;
+}
+
+/** 店铺地址写入 alipayJson;行政区划码由省前缀、市 adCode 推导(仅省/市二级时 DistrictCode 与 CityCode 相同) */
+function buildBusinessAddressForAlipayJson():
+  | {
+      address: string;
+      districtCode: string;
+      cityCode: string;
+      provinceCode: string;
+    }
+  | undefined {
+  const region = form.region;
+  if (!Array.isArray(region) || region.length < 2) return undefined;
+  const provPrefix = String(region[0] ?? "").replace(/\D/g, "");
+  const cityAd = String(region[1] ?? "").replace(/\D/g, "");
+  if (!provPrefix || cityAd.length < 6) return undefined;
+
+  const prov = provinceCityOptions.find(p => p.value === region[0]);
+  const provinceName = prov?.label ?? "";
+  const cityName = prov?.cities.find(c => c.value === region[1])?.label ?? "";
+  const detail = String(form.detailAddress || "").trim();
+  const address = `${provinceName}${cityName}${detail}`.trim();
+
+  const provinceCode = provPrefix.padEnd(6, "0").slice(0, 6);
+  const cityCode = cityAd.padStart(6, "0").slice(0, 6);
+  const districtCode = cityCode;
+
+  return { address, districtCode, cityCode, provinceCode };
+}
+
+/** 仅使用上传成功接口里保存的 image_id;且只认 .jpg / .jpeg / .png(不从 URL 等其它字段截取) */
+function alipayImageIdFromUploadOnly(imageIdField: string): string {
+  const s = String(imageIdField || "").trim();
+  if (!s) return "";
+  const lower = s.toLowerCase();
+  if (lower.endsWith(".jpg") || lower.endsWith(".jpeg") || lower.endsWith(".png")) return s;
+  return "";
+}
+
+/** 进件接口要求数组:有图为单元素数组,无图为 [] */
+function alipayImageIdArrayForPayload(imageIdField: string): string[] {
+  const id = alipayImageIdFromUploadOnly(imageIdField);
+  return id ? [id] : [];
+}
+
+/** 从 localStorage 读取的 alipayJson 可能是对象或历史字符串 */
+function normalizeAlipayJsonFromStorage(raw: unknown): Record<string, unknown> | null {
+  if (raw == null || raw === "") return null;
+  if (typeof raw === "string") {
+    try {
+      const o = JSON.parse(raw) as unknown;
+      return typeof o === "object" && o !== null && !Array.isArray(o) ? (o as Record<string, unknown>) : null;
+    } catch {
+      return null;
+    }
+  }
+  if (typeof raw === "object" && !Array.isArray(raw)) return raw as Record<string, unknown>;
+  return null;
+}
+
+function findCategoryPathByMcc(mcc: string): string[] | undefined {
+  const m = String(mcc || "").trim();
+  if (!m) return undefined;
+  for (const p of categoryCascaderOptions) {
+    const ch = p.children?.find(c => c.value === m);
+    if (ch) return [p.value, ch.value];
+  }
+  return undefined;
+}
+
+function firstImageIdFromAlipayField(val: unknown): string {
+  if (Array.isArray(val) && val.length > 0) return String(val[0] ?? "").trim();
+  if (typeof val === "string") return val.trim();
+  return "";
+}
+
+/** 将 businessAddress 反填为省市区 cascader + 详细地址(与 buildBusinessAddressForAlipayJson 对称) */
+function regionAndDetailFromBusinessAddress(ba: unknown): { region: string[]; detailAddress: string } | undefined {
+  if (!ba || typeof ba !== "object") return undefined;
+  const o = ba as Record<string, unknown>;
+  const provinceCode = String(o.provinceCode ?? "").replace(/\D/g, "");
+  const cityCode = String(o.cityCode ?? "").replace(/\D/g, "");
+  const address = String(o.address ?? "").trim();
+  if (provinceCode.length < 2 || cityCode.length < 6) return undefined;
+  const prefix = provinceCode.slice(0, 2);
+  const prov = provinceCityOptions.find(p => p.value === prefix);
+  if (!prov) return undefined;
+  const normCity = cityCode.padStart(6, "0").slice(0, 6);
+  const city = prov.cities.find(c => {
+    const ad = String(c.value ?? "").replace(/\D/g, "");
+    const tail = ad.length >= 6 ? ad.slice(-6) : ad;
+    return tail.padStart(6, "0") === normCity;
+  });
+  if (!city) return undefined;
+  let detail = address;
+  const prefixStr = `${prov.label}${city.label}`;
+  if (address.startsWith(prefixStr)) detail = address.slice(prefixStr.length).trim();
+  return { region: [prefix, city.value], detailAddress: detail };
+}
+
+/** alipayJson.service 为「当面付」「App支付」等;兼容旧内部码 */
+function serviceTypesFromAlipayService(val: unknown): string[] {
+  const allowed = new Set(serviceTypeOptions.map(o => o.value));
+  const legacy: Record<string, string> = {
+    face_to_face: "当面付",
+    app: "App支付"
+  };
+  const arr = Array.isArray(val) ? val : typeof val === "string" && val.trim() ? [val] : [];
+  const out: string[] = [];
+  const seen = new Set<string>();
+  for (const item of arr) {
+    let s = String(item ?? "").trim();
+    if (s.toLowerCase() === "app 支付") s = "App支付";
+    const mapped = legacy[s] ?? s;
+    if (mapped && allowed.has(mapped) && !seen.has(mapped)) {
+      seen.add(mapped);
+      out.push(mapped);
+    }
+  }
+  return out;
+}
+
+/** 进入本页时把缓存中的 alipayJson 写回第一步表单 */
+function applyAlipayJsonCacheToForm(data: Record<string, unknown>) {
+  const st = String(data.merchantType ?? "").trim();
+  if (st) form.subjectType = st;
+
+  const name = String(data.name ?? data.aliasName ?? "").trim();
+  if (name) form.merchantShortName = name;
+
+  const mcc = String(data.mcc ?? "").trim();
+  const path = findCategoryPathByMcc(mcc);
+  if (path) form.businessCategory = path;
+
+  const certNo = String(data.certNo ?? "").trim();
+  if (certNo) form.creditCode = certNo;
+
+  const certImage = String(data.certImage ?? "").trim();
+  if (certImage) form.licenseImageId = certImage;
+
+  const legalName = String(data.legalName ?? "").trim();
+  if (legalName) form.legalName = legalName;
+
+  const legalCertNo = String(data.legalCertNo ?? "").trim();
+  if (legalCertNo) form.idNumber = legalCertNo;
+
+  const certName = String(data.certName ?? "").trim();
+  if (certName && form.subjectType === "07") form.householdLicenseName = certName;
+
+  const alipayId = String(data.alipayLogonId ?? data.bindingAlipayLogonId ?? data.BindingAlipayLogonId ?? "").trim();
+  if (alipayId) form.settlementAlipayAccount = alipayId;
+
+  const ci = data.contactInfos;
+  if (Array.isArray(ci) && ci.length > 0) {
+    const c0 = ci[0] as Record<string, unknown>;
+    const cn = String(c0?.name ?? "").trim();
+    const cm = String(c0?.mobile ?? "").trim();
+    if (cn) form.contactName = cn;
+    if (cm) form.contactPhone = cm;
+  }
+
+  const svc = serviceTypesFromAlipayService(data.service);
+  if (svc.length) form.serviceTypes = svc;
+
+  const inId = firstImageIdFromAlipayField(data.inDoorImages);
+  if (inId) form.interiorImageId = inId;
+
+  const outId = firstImageIdFromAlipayField(data.outDoorImages);
+  if (outId) form.storefrontImageId = outId;
+
+  const ba = regionAndDetailFromBusinessAddress(data.businessAddress);
+  if (ba) {
+    form.region = ba.region;
+    form.detailAddress = ba.detailAddress;
+  }
+
+  const sites = data.sites;
+  if (Array.isArray(sites) && sites.length > 0) {
+    const s0 = sites[0] as Record<string, unknown>;
+    const sn = String(s0?.siteName ?? s0?.siteName ?? "").trim();
+    if (sn) form.appName = sn;
+  }
+}
+
+/** 下一步写入 localStorage,供后续支付宝进件等使用 */
+function buildAlipayJsonPayload() {
+  const mcc =
+    Array.isArray(form.businessCategory) && form.businessCategory.length >= 2
+      ? form.businessCategory[1]
+      : Array.isArray(form.businessCategory) && form.businessCategory.length === 1
+        ? form.businessCategory[0]
+        : "";
+  const businessAddress = buildBusinessAddressForAlipayJson();
+  const certName = form.subjectType === "07" ? String(form.householdLicenseName || "").trim() : "";
+  const alipayLogonIdVal = String(form.settlementAlipayAccount || "").trim();
+  const hasFaceToFace = form.serviceTypes.includes("当面付");
+  const hasAppPay = form.serviceTypes.includes("App支付");
+  const siteNameForPayload = String(form.appName || "").trim() || DEFAULT_ALIPAY_APP_SITE_NAME;
+  return {
+    type: 0,
+    externalId: randomAlipayExternalId16(),
+    name: form.merchantShortName,
+    aliasName: form.merchantShortName,
+    merchantType: form.subjectType,
+    mcc,
+    certNo: form.creditCode,
+    certType: 201,
+    certImage: alipayImageIdFromUploadOnly(form.licenseImageId),
+    legalName: form.legalName,
+    legalCertNo: form.idNumber,
+    certName,
+    alipayLogonId: alipayLogonIdVal,
+    contactInfos: [
+      {
+        name: String(form.contactName || "").trim(),
+        mobile: String(form.contactPhone || "").trim()
+      }
+    ],
+    service: serviceValuesForAlipayPayload(form.serviceTypes),
+    inDoorImages: alipayImageIdArrayForPayload(form.interiorImageId),
+    outDoorImages: alipayImageIdArrayForPayload(form.storefrontImageId),
+    ...(businessAddress ? { businessAddress } : {}),
+    ...(hasFaceToFace && hasAppPay
+      ? {
+          sites: [{ siteType: "02", siteName: siteNameForPayload }]
+        }
+      : {})
+  };
+}
+
+onMounted(async () => {
+  const cached = normalizeAlipayJsonFromStorage(localGet(ALIPAY_JSON_KEY));
+  if (cached) applyAlipayJsonCacheToForm(cached);
+  await nextTick();
+  formRef.value?.clearValidate();
+});
+
+const rules: FormRules = {
+  subjectType: [{ required: true, message: "请选择主体类型", trigger: "change" }],
+  serviceTypes: [
+    {
+      type: "array",
+      required: true,
+      min: 1,
+      message: "请选择接入服务类型",
+      trigger: "change"
+    }
+  ],
+  licenseUrl: [
+    {
+      validator: (_r, _v, cb) => {
+        if (form.subjectType !== "01" && form.subjectType !== "07") return cb();
+        if (!String(form.licenseUrl || "").trim()) cb(new Error("请上传营业执照"));
+        else cb();
+      },
+      trigger: "change"
+    }
+  ],
+  creditCode: [
+    {
+      validator: (_r, _v, cb) => {
+        if (form.subjectType !== "01" && form.subjectType !== "07") return cb();
+        const v = String(form.creditCode || "").trim();
+        if (!v) {
+          cb(new Error(form.subjectType === "07" ? "请输入营业执照编号" : "请输入营业执照号"));
+        } else if (v.length < 15 || v.length > 32) cb(new Error("长度一般为 18 位统一社会信用代码"));
+        else cb();
+      },
+      trigger: "blur"
+    }
+  ],
+  householdLicenseName: [
+    {
+      validator: (_r, _v, cb) => {
+        if (form.subjectType !== "07") return cb();
+        if (!String(form.householdLicenseName || "").trim()) cb(new Error("请输入营业执照名称"));
+        else cb();
+      },
+      trigger: "blur"
+    }
+  ],
+  merchantShortName: [
+    {
+      validator: (_r, _v, cb) => {
+        if (!["01", "02", "03", "04", "05", "06", "07"].includes(form.subjectType)) return cb();
+        if (!String(form.merchantShortName || "").trim()) cb(new Error("请输入商户简称"));
+        else cb();
+      },
+      trigger: "blur"
+    }
+  ],
+  institutionCertUrl: [
+    {
+      validator: (_r, _v, cb) => {
+        if (form.subjectType !== "institution") return cb();
+        if (!String(form.institutionCertUrl || "").trim()) cb(new Error("请上传事业单位法人证书"));
+        else cb();
+      },
+      trigger: "change"
+    }
+  ],
+  institutionCertNumber: [
+    {
+      validator: (_r, _v, cb) => {
+        if (form.subjectType !== "institution") return cb();
+        if (!String(form.institutionCertNumber || "").trim()) cb(new Error("请输入事业单位法人证书编号"));
+        else cb();
+      },
+      trigger: "blur"
+    }
+  ],
+  otherOrgCertUrl: [
+    {
+      validator: (_r, _v, cb) => {
+        if (form.subjectType !== "other_org") return cb();
+        if (!String(form.otherOrgCertUrl || "").trim()) cb(new Error("请上传民办非企业单位登记证书"));
+        else cb();
+      },
+      trigger: "change"
+    }
+  ],
+  otherOrgCertNumber: [
+    {
+      validator: (_r, _v, cb) => {
+        if (form.subjectType !== "other_org") return cb();
+        if (!String(form.otherOrgCertNumber || "").trim()) cb(new Error("请输入民办非企业单位登记证书编号"));
+        else cb();
+      },
+      trigger: "blur"
+    }
+  ],
+  socialCertUrl: [
+    {
+      validator: (_r, _v, cb) => {
+        if (form.subjectType !== "social") return cb();
+        if (!String(form.socialCertUrl || "").trim()) cb(new Error("请上传社会团体法人登记证书"));
+        else cb();
+      },
+      trigger: "change"
+    }
+  ],
+  socialCertNumber: [
+    {
+      validator: (_r, _v, cb) => {
+        if (form.subjectType !== "social") return cb();
+        if (!String(form.socialCertNumber || "").trim()) cb(new Error("请输入社会团体法人登记证书编号"));
+        else cb();
+      },
+      trigger: "blur"
+    }
+  ],
+  govCertUrl: [
+    {
+      validator: (_r, _v, cb) => {
+        if (form.subjectType !== "gov") return cb();
+        if (!String(form.govCertUrl || "").trim()) {
+          cb(new Error("请上传党政机关批准设立文件/行政执法主体资格证"));
+        } else cb();
+      },
+      trigger: "change"
+    }
+  ],
+  govCertNumber: [
+    {
+      validator: (_r, _v, cb) => {
+        if (form.subjectType !== "gov") return cb();
+        if (!String(form.govCertNumber || "").trim()) {
+          cb(new Error("请输入党政机关批准设立文件/行政执法主体资格证编号"));
+        } else cb();
+      },
+      trigger: "blur"
+    }
+  ],
+  businessCategory: [
+    {
+      validator: (_r, _v, cb) => {
+        if (!["01", "02", "03", "04", "05", "06", "07"].includes(form.subjectType)) return cb();
+        const bc = form.businessCategory;
+        if (!Array.isArray(bc) || bc.length < 2 || !String(bc[0] || "").trim() || !String(bc[1] || "").trim()) {
+          cb(new Error("请选择经营类目(需选择到二级分类)"));
+        } else cb();
+      },
+      trigger: "change"
+    }
+  ],
+  legalIdType: [
+    {
+      validator: (_r, _v, cb) => {
+        if (!["01", "institution", "other_org", "social"].includes(form.subjectType)) return cb();
+        if (!String(form.legalIdType || "").trim()) cb(new Error("请选择证件类型"));
+        else cb();
+      },
+      trigger: "change"
+    }
+  ],
+  idFrontUrl: [
+    {
+      validator: (_r, _v, cb) => {
+        if (!["01", "institution", "other_org", "social", "individual_merchant"].includes(form.subjectType)) return cb();
+        if (!String(form.idFrontUrl || "").trim()) {
+          cb(new Error(form.subjectType === "individual_merchant" ? "请上传身份证人像面" : "请上传证件正面"));
+        } else cb();
+      },
+      trigger: "change"
+    }
+  ],
+  idBackUrl: [
+    {
+      validator: (_r, _v, cb) => {
+        if (!["01", "institution", "other_org", "social", "individual_merchant"].includes(form.subjectType)) return cb();
+        if (!String(form.idBackUrl || "").trim()) {
+          cb(new Error(form.subjectType === "individual_merchant" ? "请上传身份证国徽面" : "请上传证件反面"));
+        } else cb();
+      },
+      trigger: "change"
+    }
+  ],
+  idNumber: [
+    {
+      validator: (_r, _v, cb) => {
+        if (!["01", "institution", "other_org", "social", "individual_merchant"].includes(form.subjectType)) return cb();
+        if (!String(form.idNumber || "").trim()) {
+          cb(new Error(form.subjectType === "individual_merchant" ? "请输入个人身份证号码" : "请输入证件号"));
+        } else cb();
+      },
+      trigger: "blur"
+    }
+  ],
+  legalName: [
+    {
+      validator: (_r, _v, cb) => {
+        if (!["01", "institution", "other_org", "social"].includes(form.subjectType)) return cb();
+        if (!String(form.legalName || "").trim()) cb(new Error("请输入法定代表人/负责人姓名"));
+        else cb();
+      },
+      trigger: "blur"
+    }
+  ],
+  storefrontUrl: [{ required: true, message: "请上传门头照", trigger: "change" }],
+  interiorUrl: [{ required: true, message: "请上传内景照", trigger: "change" }],
+  region: [{ type: "array", required: true, min: 2, message: "请选择省、市", trigger: "change" }],
+  detailAddress: [{ required: true, message: "请输入详细地址", trigger: "blur" }],
+  contactName: [{ required: true, message: "请输入联系人姓名", trigger: "blur" }],
+  contactPhone: [
+    { required: true, message: "请输入联系人手机号", trigger: "blur" },
+    { pattern: /^1\d{10}$/, message: "请输入有效手机号", trigger: "blur" }
+  ],
+  contactEmail: [
+    { required: true, message: "请输入联系人邮箱", trigger: "blur" },
+    { type: "email", message: "邮箱格式不正确", trigger: "blur" }
+  ],
+  servicePhone: [
+    { required: true, message: "请输入客服电话", trigger: "blur" },
+    { pattern: /^[\d\-+\s]{5,20}$/, message: "请输入有效电话号码", trigger: "blur" }
+  ],
+  settlementAlipayAccount: [{ required: true, message: "请输入签约支付宝账号", trigger: "blur" }]
+};
+
+async function onNext() {
+  if (!formRef.value) return;
+  nextLoading.value = true;
+  try {
+    localSet(ALIPAY_JSON_KEY, buildAlipayJsonPayload());
+    await router.push({ path: "/businessInfo/zfbIndexTwo", query: { ...route.query } });
+  } catch {
+    ElMessage.warning("请完善必填信息");
+  } finally {
+    nextLoading.value = false;
+  }
+}
+</script>
+
+<style scoped lang="scss">
+$zfb-blue: #1677ff;
+.zfb-step-page {
+  box-sizing: border-box;
+  min-height: 100%;
+  padding: 24px 24px 48px;
+  margin: 0 auto;
+  background: #ffffff;
+}
+.step-header {
+  margin-right: -24px;
+  margin-bottom: 28px;
+  margin-left: -24px;
+}
+.zfb-steps {
+  width: 100%;
+  margin: 0;
+}
+.step-header :deep(.zfb-steps.el-steps--horizontal) {
+  .el-step__icon {
+    width: 36px;
+    height: 36px;
+    font-size: 16px;
+    font-weight: 600;
+    background: #ffffff !important;
+  }
+  .el-step__head.is-process .el-step__icon {
+    color: #ffffff !important;
+    background: #1677ff !important;
+    border-color: $zfb-blue !important;
+  }
+  .el-step__head.is-wait .el-step__icon {
+    color: #c0c4cc !important;
+    background: #ffffff !important;
+    border: 2px solid #dcdfe6 !important;
+  }
+  .el-step__head.is-finish .el-step__icon {
+    color: #ffffff !important;
+    background: $zfb-blue !important;
+    border-color: $zfb-blue !important;
+  }
+  .el-step__line {
+    background-color: #e4e7ed !important;
+  }
+  .el-step__line-inner {
+    border-width: 1px !important;
+  }
+  .el-step__title {
+    font-size: 14px;
+    line-height: 36px;
+    color: #606266;
+  }
+  .el-step__head.is-process + .el-step__main .el-step__title {
+    font-weight: 600;
+    color: #303133;
+  }
+  .el-step__head.is-wait + .el-step__main .el-step__title {
+    color: #c0c4cc;
+  }
+  .el-step__head.is-finish + .el-step__main .el-step__title {
+    font-weight: 500;
+    color: #606266;
+  }
+}
+.page-layout {
+  display: flex;
+  gap: 32px;
+  align-items: flex-start;
+}
+.main-column {
+  flex: 1;
+  min-width: 0;
+
+  /* 滚到底时 max(scrollTop) 往往仍小于「经营信息」的锚点判定线,侧栏会一直停在前一节;底部留白增大可滚动距离 */
+  padding-bottom: clamp(140px, 22vh, 400px);
+}
+.anchor-column {
+  flex-shrink: 0;
+  width: 160px;
+}
+.anchor-card {
+  padding: 16px 12px;
+}
+:deep(.el-anchor__list) {
+  border-left: 1px solid #ebeef5;
+}
+.anchor-title {
+  margin-bottom: 12px;
+  font-size: 13px;
+  font-weight: 600;
+  color: #303133;
+}
+.zfb-form {
+  :deep(.el-form-item__label) {
+    font-weight: 500;
+    color: #606266;
+  }
+}
+.form-block {
+  padding-bottom: 8px;
+  margin-bottom: 28px;
+  scroll-margin-top: 72px;
+  border-bottom: 1px solid #ebeef5;
+  &:last-of-type {
+    border-bottom: none;
+  }
+}
+.section-head {
+  display: flex;
+  align-items: center;
+  margin: 0 0 16px;
+  font-size: 16px;
+  font-weight: 600;
+  color: #303133;
+}
+.section-bar {
+  display: inline-block;
+  flex-shrink: 0;
+  width: 4px;
+  height: 16px;
+  margin-right: 8px;
+  background: $zfb-blue;
+  border-radius: 2px;
+}
+.radio-stack {
+  display: flex;
+  gap: 10px;
+  align-items: flex-start;
+}
+.label-with-icon {
+  display: inline-flex;
+  gap: 4px;
+  align-items: center;
+}
+.label-wrap-multiline {
+  display: inline-block;
+  max-width: 196px;
+  line-height: 1.45;
+  white-space: normal;
+  vertical-align: middle;
+}
+.individual-merchant-alert {
+  max-width: 410px;
+  margin-bottom: 20px;
+  margin-left: 200px;
+}
+.info-icon {
+  color: #909399;
+  cursor: help;
+}
+.license-upload-wrap {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 16px;
+  align-items: flex-start;
+}
+.license-example {
+  display: flex;
+  flex-direction: column;
+  gap: 6px;
+}
+.license-example-label {
+  font-size: 12px;
+  color: #909399;
+}
+.license-example-thumb {
+  position: relative;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  width: 148px;
+  height: 148px;
+  overflow: hidden;
+  background: #f5f7fa;
+  border: 1px dashed #dcdfe6;
+  border-radius: 6px;
+}
+.license-example-placeholder {
+  font-size: 12px;
+  color: #c0c4cc;
+}
+.id-example-thumb {
+  position: relative;
+}
+.license-example-badge {
+  position: absolute;
+  top: 6px;
+  right: 6px;
+  padding: 2px 6px;
+  font-size: 11px;
+  color: #ffffff;
+  background: rgb(0 0 0 / 45%);
+  border-radius: 4px;
+}
+.id-upload-row {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 24px;
+}
+.id-upload-cell {
+  display: flex;
+  flex-direction: column;
+  gap: 8px;
+}
+.id-upload-trigger {
+  display: flex;
+  flex-direction: column;
+  gap: 6px;
+  align-items: center;
+  justify-content: center;
+  line-height: 1.2;
+}
+.id-side-label {
+  margin-top: 10px;
+  font-size: 13px;
+  color: #606266;
+}
+.id-upload-trigger .id-side-label {
+  font-size: 12px;
+  line-height: 1.3;
+  text-align: center;
+}
+.upload-rules {
+  margin-top: 12px;
+  font-size: 12px;
+  line-height: 1.65;
+  color: #909399;
+  p {
+    margin: 0;
+  }
+}
+.field-stack {
+  width: 100%;
+}
+.field-tip {
+  margin: 8px 0 0;
+  font-size: 12px;
+  line-height: 1.65;
+  color: #909399;
+}
+.service-checks {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 12px 20px;
+}
+.address-row {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 12px;
+  align-items: center;
+  width: 100%;
+  max-width: 720px;
+}
+.address-detail {
+  flex: 1;
+  min-width: 200px;
+}
+.footer-actions {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 16px;
+  align-items: center;
+  justify-content: center;
+  padding-top: 24px;
+  margin-top: 8px;
+  border-top: 1px solid #ebeef5;
+}
+.btn-primary-zfb {
+  min-width: 120px;
+  background: $zfb-blue;
+  border-color: $zfb-blue;
+  &:hover {
+    background: #4096ff;
+    border-color: #4096ff;
+  }
+}
+:deep(.el-upload--picture-card) {
+  --el-upload-picture-card-size: 148px;
+}
+:deep(.el-upload-list--picture-card .el-upload-list__item) {
+  width: 148px;
+  height: 148px;
+}
+:deep(.el-form-item__content) {
+  display: block;
+}
+:deep(.anchor-card .el-anchor) {
+  /* 实际滚动在 layout 的 el-main 上,不设 container 时监听 window,高亮不会随滚动更新 */
+  --el-anchor-color: #606266;
+  --el-anchor-active-color: #{$zfb-blue};
+  --el-anchor-marker-bg-color: #{$zfb-blue};
+
+  background: transparent;
+}
+:deep(.anchor-card .el-anchor__link) {
+  padding: 6px 0;
+  font-size: 13px;
+}
+:deep(.anchor-card .el-anchor__link.is-active) {
+  font-weight: 600;
+}
+</style>

+ 928 - 0
src/views/businessInfo/zfbIndexTwo.vue

@@ -0,0 +1,928 @@
+<template>
+  <div class="zfb-step-page">
+    <header class="step-header">
+      <el-steps :active="zfbStepActive" align-center finish-status="success" class="zfb-steps">
+        <el-step title="第一步 完善商家信息" />
+        <el-step title="第二步 完善结算信息" />
+        <el-step title="第三步 提交审核" />
+      </el-steps>
+    </header>
+
+    <div class="page-layout">
+      <div class="main-column">
+        <el-form
+          ref="formRef"
+          class="zfb-form"
+          :model="form"
+          :rules="rules"
+          label-width="200px"
+          require-asterisk-position="right"
+          label-position="right"
+        >
+          <section id="zfb-settlement" class="form-block anchor-section">
+            <h2 class="section-head">
+              <span class="section-bar" aria-hidden="true" />
+              结算信息
+            </h2>
+
+            <el-form-item label="请选择结算方式" prop="settlementMethod">
+              <el-radio-group v-model="form.settlementMethod" class="radio-stack">
+                <el-radio value="alipay"> 结算到支付宝 </el-radio>
+                <el-radio value="bank"> 结算到银行卡 </el-radio>
+              </el-radio-group>
+            </el-form-item>
+
+            <template v-if="form.settlementMethod === 'alipay'">
+              <el-form-item label="支付宝账号" prop="alipayAccount">
+                <el-input v-model="form.alipayAccount" placeholder="请输入支付宝账号" clearable style="max-width: 480px" />
+                <el-alert class="settlement-tip-alert" type="info" :closable="false" show-icon>
+                  注:账号主体名称需与营业执照同名
+                </el-alert>
+              </el-form-item>
+            </template>
+
+            <template v-if="form.settlementMethod === 'bank'">
+              <el-form-item label="开户名称" prop="bankAccountName" required>
+                <el-input v-model="form.bankAccountName" clearable maxlength="64" style="max-width: 480px" />
+              </el-form-item>
+              <el-form-item label="银行卡号" prop="bankCardNo" required>
+                <el-input
+                  v-model="form.bankCardNo"
+                  placeholder="暂时只支持借记卡"
+                  clearable
+                  maxlength="24"
+                  style="max-width: 480px"
+                />
+              </el-form-item>
+              <el-form-item label="联行号" prop="cnapsCode">
+                <el-input v-model="form.cnapsCode" placeholder="非必填" clearable maxlength="32" style="max-width: 480px" />
+              </el-form-item>
+              <el-form-item prop="bankBranch">
+                <template #label>
+                  <span class="bank-branch-required-label">开户银行</span>
+                </template>
+                <div class="bank-select-row">
+                  <el-select
+                    v-model="form.depositBankCode"
+                    placeholder="请选择开户银行"
+                    clearable
+                    filterable
+                    class="bank-select-cell"
+                    @change="onDepositBankChange"
+                  >
+                    <el-option v-for="b in depositBankOptions" :key="b.value" :label="b.label" :value="b.value" />
+                  </el-select>
+                  <el-cascader
+                    v-model="form.branchRegion"
+                    :options="invoiceRegionCascaderOptions"
+                    :props="{ emitPath: true }"
+                    placeholder="请选择省 / 市"
+                    clearable
+                    filterable
+                    class="bank-select-cell bank-region-cascader"
+                    @change="onBranchRegionChange"
+                  />
+                  <el-input
+                    v-model="form.branchName"
+                    placeholder="请输入支行名称"
+                    clearable
+                    maxlength="80"
+                    class="bank-select-cell bank-branch-input"
+                    :disabled="!branchRegionCitySelected"
+                    @blur="touchBankBranchValidate"
+                    @clear="touchBankBranchValidate"
+                  />
+                </div>
+              </el-form-item>
+              <el-form-item label="账号使用类型" prop="accountUsageType" required>
+                <el-radio-group v-model="form.accountUsageType" class="radio-stack" disabled>
+                  <el-radio value="public"> 对公 </el-radio>
+                  <el-radio value="private"> 对私 </el-radio>
+                </el-radio-group>
+              </el-form-item>
+            </template>
+
+            <!-- <el-form-item label="是否开票" prop="needInvoicing">
+              <el-radio-group v-model="form.needInvoicing" class="radio-stack">
+                <el-radio value="yes">是</el-radio>
+                <el-radio value="no">否</el-radio>
+              </el-radio-group>
+            </el-form-item> -->
+
+            <!-- <template v-if="form.needInvoicing === 'yes'">
+              <div id="zfb-invoice" class="invoice-extra-wrap anchor-section">
+                <div class="invoice-section-divider" />
+
+                <el-form-item label="纳税人种类" prop="taxpayerType" required>
+                  <el-radio-group v-model="form.taxpayerType" class="radio-stack">
+                    <el-radio value="general">一般纳税人</el-radio>
+                    <el-radio value="small_scale">小规模纳税人</el-radio>
+                  </el-radio-group>
+                </el-form-item>
+
+                <div class="invoice-section-divider" />
+                <h3 class="invoice-subsection-title">开票信息</h3>
+
+                <el-form-item label="发票抬头" prop="invoiceTitle" required>
+                  <el-input v-model="form.invoiceTitle" clearable maxlength="128" style="max-width: 480px" />
+                </el-form-item>
+                <el-form-item label="纳税人识别号" prop="taxpayerIdNo" required>
+                  <el-input v-model="form.taxpayerIdNo" clearable maxlength="32" style="max-width: 480px" />
+                </el-form-item>
+                <el-form-item label="纳税人资格开始时间" prop="qualificationStartDate" required>
+                  <el-date-picker
+                    v-model="form.qualificationStartDate"
+                    type="date"
+                    placeholder="请选择日期"
+                    value-format="YYYY-MM-DD"
+                    style="width: 320px; max-width: 100%"
+                    clearable
+                    @change="touchQualificationDateValidate"
+                  />
+                </el-form-item>
+                <template v-if="form.taxpayerType === 'general'">
+                  <el-form-item label="开票地址" prop="invoiceAddress" required>
+                    <el-input v-model="form.invoiceAddress" clearable maxlength="200" style="max-width: 480px" />
+                  </el-form-item>
+                  <el-form-item label="开票电话" prop="invoicePhone" required>
+                    <el-input v-model="form.invoicePhone" clearable maxlength="20" style="max-width: 480px" />
+                  </el-form-item>
+                  <el-form-item label="银行卡号" prop="invoiceBankCardNo" required>
+                    <el-input v-model="form.invoiceBankCardNo" clearable maxlength="24" style="max-width: 480px" />
+                  </el-form-item>
+                  <el-form-item label="开户银行" prop="invoiceOpeningBank" required>
+                    <el-input v-model="form.invoiceOpeningBank" clearable maxlength="64" style="max-width: 480px" />
+                  </el-form-item>
+                </template>
+
+                <div id="zfb-invoice-mail" class="invoice-section-divider" />
+                <h3 class="invoice-subsection-title">发票寄送信息</h3>
+
+                <el-form-item label="发票寄送地址" prop="invoiceMailSuite" required>
+                  <div class="mail-address-stack">
+                    <el-cascader
+                      v-model="form.invoiceMailRegion"
+                      :options="invoiceRegionCascaderOptions"
+                      :placeholder="
+                        form.taxpayerType === 'small_scale' ? '请输入具体门牌号等' : '请选择省 / 市'
+                      "
+                      filterable
+                      clearable
+                      class="mail-cascader"
+                      @change="touchInvoiceMailSuiteValidate"
+                    />
+                    <el-input
+                      v-model="form.invoiceMailAddressDetail"
+                      placeholder="请输入具体门牌号等"
+                      clearable
+                      maxlength="200"
+                      class="mail-detail-input"
+                      @blur="touchInvoiceMailSuiteValidate"
+                    />
+                  </div>
+                </el-form-item>
+                <el-form-item label="收件人姓名" prop="invoiceRecipientName" required>
+                  <el-input v-model="form.invoiceRecipientName" clearable maxlength="32" style="max-width: 480px" />
+                </el-form-item>
+                <el-form-item label="收件人手机号" prop="invoiceRecipientPhone" required>
+                  <el-input v-model="form.invoiceRecipientPhone" clearable maxlength="11" style="max-width: 480px" />
+                </el-form-item>
+              </div>
+            </template> -->
+          </section>
+        </el-form>
+
+        <div class="footer-actions">
+          <el-button type="primary" class="btn-primary-zfb" :loading="submitLoading" @click="onConfirmSubmit">
+            确认提交
+          </el-button>
+        </div>
+      </div>
+
+      <aside class="anchor-column">
+        <el-affix :offset="88">
+          <div class="anchor-card">
+            <el-anchor :offset="72" direction="vertical">
+              <el-anchor-link href="#zfb-settlement" title="结算信息" />
+              <el-anchor-link v-if="form.needInvoicing === 'yes'" href="#zfb-invoice" title="开票信息" />
+              <el-anchor-link v-if="form.needInvoicing === 'yes'" href="#zfb-invoice-mail" title="发票寄送" />
+            </el-anchor>
+          </div>
+        </el-affix>
+      </aside>
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { computed, nextTick, onMounted, reactive, ref, watch } from "vue";
+import { ElMessage } from "element-plus";
+import type { FormInstance, FormRules } from "element-plus";
+import { localGet, localSet } from "@/utils/index";
+import { getAlipayZftCreate } from "@/api/modules/businessInfo";
+import cityJson from "@/assets/json/city.json";
+
+type CityJsonEntry = { name: string; adCode: string; cityCode: string };
+type CityJsonRoot = { cityList: { letter: string; list: CityJsonEntry[] }[] };
+
+const PROVINCE_ROWS: [string, string][] = [
+  ["11", "北京市"],
+  ["12", "天津市"],
+  ["13", "河北省"],
+  ["14", "山西省"],
+  ["15", "内蒙古自治区"],
+  ["21", "辽宁省"],
+  ["22", "吉林省"],
+  ["23", "黑龙江省"],
+  ["31", "上海市"],
+  ["32", "江苏省"],
+  ["33", "浙江省"],
+  ["34", "安徽省"],
+  ["35", "福建省"],
+  ["36", "江西省"],
+  ["37", "山东省"],
+  ["41", "河南省"],
+  ["42", "湖北省"],
+  ["43", "湖南省"],
+  ["44", "广东省"],
+  ["45", "广西壮族自治区"],
+  ["46", "海南省"],
+  ["50", "重庆市"],
+  ["51", "四川省"],
+  ["52", "贵州省"],
+  ["53", "云南省"],
+  ["54", "西藏自治区"],
+  ["61", "陕西省"],
+  ["62", "甘肃省"],
+  ["63", "青海省"],
+  ["64", "宁夏回族自治区"],
+  ["65", "新疆维吾尔自治区"],
+  ["71", "台湾省"],
+  ["81", "香港特别行政区"],
+  ["82", "澳门特别行政区"]
+];
+const PROVINCE_BY_PREFIX = Object.fromEntries(PROVINCE_ROWS) as Record<string, string>;
+const PROVINCE_PREFIX_ORDER = PROVINCE_ROWS.map(([k]) => k);
+
+function buildProvinceCityOptions(): {
+  label: string;
+  value: string;
+  cities: { label: string; value: string }[];
+}[] {
+  const root = cityJson as CityJsonRoot;
+  const flat = root.cityList.flatMap(g => g.list);
+  const bucket = new Map<string, Map<string, CityJsonEntry>>();
+  for (const c of flat) {
+    const digits = String(c.adCode ?? "").replace(/\D/g, "");
+    const code = digits.length >= 6 ? digits.slice(-6) : digits.padStart(6, "0");
+    if (code.length !== 6) continue;
+    const prefix = code.slice(0, 2);
+    if (!PROVINCE_BY_PREFIX[prefix]) continue;
+    if (!bucket.has(prefix)) bucket.set(prefix, new Map());
+    bucket.get(prefix)!.set(c.adCode, c);
+  }
+  const out = [...bucket.entries()].map(([prefix, cityMap]) => ({
+    value: prefix,
+    label: PROVINCE_BY_PREFIX[prefix],
+    cities: [...cityMap.values()]
+      .sort((a, b) => a.name.localeCompare(b.name, "zh-CN"))
+      .map(ci => ({ label: ci.name, value: ci.adCode }))
+  }));
+  out.sort((a, b) => {
+    const ia = PROVINCE_PREFIX_ORDER.indexOf(a.value);
+    const ib = PROVINCE_PREFIX_ORDER.indexOf(b.value);
+    return (ia === -1 ? 999 : ia) - (ib === -1 ? 999 : ib);
+  });
+  return out;
+}
+
+const provinceCityOptions = buildProvinceCityOptions();
+
+const invoiceRegionCascaderOptions = computed(() =>
+  provinceCityOptions.map(p => ({
+    value: p.value,
+    label: p.label,
+    children: p.cities.map(c => ({ value: c.value, label: c.label }))
+  }))
+);
+
+const depositBankOptions = [
+  { label: "工商银行", value: "ICBC" },
+  { label: "农业银行", value: "ABC" },
+  { label: "中国银行", value: "BOC" },
+  { label: "建设银行", value: "CCB" },
+  { label: "交通银行", value: "COMM" },
+  { label: "邮储银行", value: "PSBC" },
+  { label: "招商银行", value: "CMB" },
+  { label: "浦发银行", value: "SPDB" },
+  { label: "兴业银行", value: "CIB" },
+  { label: "民生银行", value: "CMBC" },
+  { label: "华夏银行", value: "HXB" },
+  { label: "广发银行", value: "GDB" },
+  { label: "平安银行", value: "PAB" },
+  { label: "中信银行", value: "CITIC" },
+  { label: "光大银行", value: "CEB" },
+  { label: "上海银行", value: "BOSH" },
+  { label: "北京银行", value: "BRCB" },
+  { label: "其他银行", value: "OTHER" }
+];
+
+const formRef = ref<FormInstance>();
+const submitLoading = ref(false);
+
+/** 第二步:索引为 1 */
+const zfbStepActive = ref(1);
+
+const form = reactive({
+  settlementMethod: "alipay" as "alipay" | "bank",
+  alipayAccount: "",
+  bankAccountName: "",
+  bankCardNo: "",
+  cnapsCode: "",
+  /** 联表校验占位,不绑定输入 */
+  bankBranch: "",
+  depositBankCode: "",
+  /** 支行地区 [省前缀, 市 adCode],与第一步店铺地址级联一致 */
+  branchRegion: [] as string[],
+  branchName: "",
+  accountUsageType: "public" as "public" | "private",
+  needInvoicing: "no" as "yes" | "no",
+  taxpayerType: "general" as "general" | "small_scale",
+  invoiceTitle: "",
+  taxpayerIdNo: "",
+  qualificationStartDate: "" as string,
+  invoiceAddress: "",
+  invoicePhone: "",
+  invoiceBankCardNo: "",
+  invoiceOpeningBank: "",
+  /** 级联 [省前缀, 市 adCode] */
+  invoiceMailRegion: [] as string[],
+  invoiceMailAddressDetail: "",
+  /** 发票寄送地址联校占位 */
+  invoiceMailSuite: "",
+  invoiceRecipientName: "",
+  invoiceRecipientPhone: ""
+});
+
+/** 已选省、市后可填写支行名称 */
+const branchRegionCitySelected = computed(
+  () => Array.isArray(form.branchRegion) && form.branchRegion.length >= 2 && !!String(form.branchRegion[1] || "").trim()
+);
+
+function touchBankBranchValidate() {
+  nextTick(() => formRef.value?.validateField("bankBranch"));
+}
+
+function onDepositBankChange() {
+  form.branchRegion = [];
+  form.branchName = "";
+  touchBankBranchValidate();
+}
+
+function onBranchRegionChange() {
+  form.branchName = "";
+  touchBankBranchValidate();
+}
+
+function touchInvoiceMailSuiteValidate() {
+  nextTick(() => formRef.value?.validateField("invoiceMailSuite"));
+}
+
+function touchQualificationDateValidate() {
+  nextTick(() => formRef.value?.validateField("qualificationStartDate"));
+}
+
+const rules: FormRules = {
+  settlementMethod: [{ required: true, message: "请选择结算方式", trigger: "change" }],
+  alipayAccount: [
+    {
+      validator: (_r, _v, cb) => {
+        if (form.settlementMethod !== "alipay") return cb();
+        if (!String(form.alipayAccount || "").trim()) cb(new Error("请输入支付宝账号"));
+        else cb();
+      },
+      trigger: "blur"
+    }
+  ],
+  bankAccountName: [
+    {
+      validator: (_r, _v, cb) => {
+        if (form.settlementMethod !== "bank") return cb();
+        if (!String(form.bankAccountName || "").trim()) cb(new Error("请输入开户名称"));
+        else cb();
+      },
+      trigger: "blur"
+    }
+  ],
+  bankCardNo: [
+    {
+      validator: (_r, _v, cb) => {
+        if (form.settlementMethod !== "bank") return cb();
+        const v = String(form.bankCardNo || "")
+          .replace(/\s+/g, "")
+          .trim();
+        if (!v) cb(new Error("请输入银行卡号"));
+        else if (!/^\d{16,24}$/.test(v)) cb(new Error("请输入正确的借记卡卡号(16~24 位数字)"));
+        else cb();
+      },
+      trigger: "blur"
+    }
+  ],
+  cnapsCode: [
+    {
+      validator: (_r, _v, cb) => {
+        if (form.settlementMethod !== "bank") return cb();
+        const v = String(form.cnapsCode || "").trim();
+        if (!v) return cb();
+        if (!/^\d{8,14}$/.test(v)) cb(new Error("联行号格式不正确"));
+        else cb();
+      },
+      trigger: "blur"
+    }
+  ],
+  bankBranch: [
+    {
+      validator: (_r, _v, cb) => {
+        if (form.settlementMethod !== "bank") return cb();
+        if (!form.depositBankCode) cb(new Error("请选择开户银行"));
+        else if (!Array.isArray(form.branchRegion) || form.branchRegion.length < 2) {
+          cb(new Error("请选择支行地区(省、市)"));
+        } else if (!String(form.branchName || "").trim()) cb(new Error("请输入支行名称"));
+        else cb();
+      },
+      trigger: "change"
+    }
+  ],
+  accountUsageType: [
+    {
+      validator: (_r, _v, cb) => {
+        if (form.settlementMethod !== "bank") return cb();
+        if (form.accountUsageType !== "public" && form.accountUsageType !== "private") {
+          cb(new Error("请选择账号使用类型"));
+        } else cb();
+      },
+      trigger: "change"
+    }
+  ],
+  needInvoicing: [{ required: true, message: "请选择是否开票", trigger: "change" }],
+  taxpayerType: [
+    {
+      validator: (_r, _v, cb) => {
+        if (form.needInvoicing !== "yes") return cb();
+        if (form.taxpayerType !== "general" && form.taxpayerType !== "small_scale") {
+          cb(new Error("请选择纳税人种类"));
+        } else cb();
+      },
+      trigger: "change"
+    }
+  ],
+  invoiceTitle: [
+    {
+      validator: (_r, _v, cb) => {
+        if (form.needInvoicing !== "yes") return cb();
+        if (!String(form.invoiceTitle || "").trim()) cb(new Error("请输入发票抬头"));
+        else cb();
+      },
+      trigger: "blur"
+    }
+  ],
+  taxpayerIdNo: [
+    {
+      validator: (_r, _v, cb) => {
+        if (form.needInvoicing !== "yes") return cb();
+        const v = String(form.taxpayerIdNo || "")
+          .trim()
+          .toUpperCase();
+        if (!v) cb(new Error("请输入纳税人识别号"));
+        else if (v.length < 15 || v.length > 20) cb(new Error("纳税人识别号长度应为 15~20 位"));
+        else if (!/^[0-9A-Z]+$/.test(v)) cb(new Error("纳税人识别号仅含数字与字母"));
+        else cb();
+      },
+      trigger: "blur"
+    }
+  ],
+  qualificationStartDate: [
+    {
+      validator: (_r, _v, cb) => {
+        if (form.needInvoicing !== "yes") return cb();
+        if (!String(form.qualificationStartDate || "").trim()) cb(new Error("请选择纳税人资格开始时间"));
+        else cb();
+      },
+      trigger: "change"
+    }
+  ],
+  invoiceAddress: [
+    {
+      validator: (_r, _v, cb) => {
+        if (form.needInvoicing !== "yes" || form.taxpayerType !== "general") return cb();
+        if (!String(form.invoiceAddress || "").trim()) cb(new Error("请输入开票地址"));
+        else cb();
+      },
+      trigger: "blur"
+    }
+  ],
+  invoicePhone: [
+    {
+      validator: (_r, _v, cb) => {
+        if (form.needInvoicing !== "yes" || form.taxpayerType !== "general") return cb();
+        const v = String(form.invoicePhone || "").trim();
+        if (!v) cb(new Error("请输入开票电话"));
+        else if (!/^[\d\-+\s]{5,20}$/.test(v)) cb(new Error("请输入有效的开票电话"));
+        else cb();
+      },
+      trigger: "blur"
+    }
+  ],
+  invoiceBankCardNo: [
+    {
+      validator: (_r, _v, cb) => {
+        if (form.needInvoicing !== "yes" || form.taxpayerType !== "general") return cb();
+        const v = String(form.invoiceBankCardNo || "")
+          .replace(/\s+/g, "")
+          .trim();
+        if (!v) cb(new Error("请输入银行卡号"));
+        else if (!/^\d{16,24}$/.test(v)) cb(new Error("请输入正确的银行卡号(16~24 位数字)"));
+        else cb();
+      },
+      trigger: "blur"
+    }
+  ],
+  invoiceOpeningBank: [
+    {
+      validator: (_r, _v, cb) => {
+        if (form.needInvoicing !== "yes" || form.taxpayerType !== "general") return cb();
+        if (!String(form.invoiceOpeningBank || "").trim()) cb(new Error("请输入开户银行"));
+        else cb();
+      },
+      trigger: "blur"
+    }
+  ],
+  invoiceMailSuite: [
+    {
+      validator: (_r, _v, cb) => {
+        if (form.needInvoicing !== "yes") return cb();
+        const reg = form.invoiceMailRegion;
+        if (!Array.isArray(reg) || reg.length < 2 || !String(reg[0] || "").trim() || !String(reg[1] || "").trim()) {
+          cb(new Error("请选择发票寄送省/市"));
+        } else if (!String(form.invoiceMailAddressDetail || "").trim()) {
+          cb(new Error("请输入具体门牌号等"));
+        } else cb();
+      },
+      trigger: "change"
+    }
+  ],
+  invoiceRecipientName: [
+    {
+      validator: (_r, _v, cb) => {
+        if (form.needInvoicing !== "yes") return cb();
+        if (!String(form.invoiceRecipientName || "").trim()) cb(new Error("请输入收件人姓名"));
+        else cb();
+      },
+      trigger: "blur"
+    }
+  ],
+  invoiceRecipientPhone: [
+    {
+      validator: (_r, _v, cb) => {
+        if (form.needInvoicing !== "yes") return cb();
+        const v = String(form.invoiceRecipientPhone || "").trim();
+        if (!v) cb(new Error("请输入收件人手机号"));
+        else if (!/^1\d{10}$/.test(v)) cb(new Error("请输入正确的手机号"));
+        else cb();
+      },
+      trigger: "blur"
+    }
+  ]
+};
+
+const ALIPAY_JSON_KEY = "alipayJson";
+
+/** 结算到银行卡时写入 alipayJson.bizCards[](与直付通字段约定一致) */
+type AlipayBizCardPayload = {
+  accountHolderName: string;
+  accountNo: string;
+  accountInstProvince: string;
+  accountInstCity: string;
+  accountBranchName: string;
+  /** 对公 01,对私 02 */
+  usageType: string;
+  accountType: "DC";
+  accountInstName: string;
+  /** 开户行缩写,与 depositBankCode 一致(如 ICBC) */
+  accountInstId: string;
+};
+
+/** 由支行地区级联 [省前缀, 市 adCode] 解析省名、市名 */
+function resolveBranchRegionProvinceCity(): { province: string; city: string } {
+  const reg = form.branchRegion;
+  if (!Array.isArray(reg) || reg.length < 2) return { province: "", city: "" };
+  const prov = provinceCityOptions.find(p => p.value === reg[0]);
+  const cityAd = String(reg[1] || "").trim();
+  const city = prov?.cities.find(c => c.value === cityAd);
+  return {
+    province: prov?.label ?? "",
+    city: city?.label ?? ""
+  };
+}
+
+function buildBizCardsForPayload(): AlipayBizCardPayload[] {
+  if (form.settlementMethod !== "bank") return [];
+  const bankMeta = depositBankOptions.find(b => b.value === form.depositBankCode);
+  const { province, city } = resolveBranchRegionProvinceCity();
+  const usageType = form.accountUsageType === "public" ? "01" : "02";
+  return [
+    {
+      accountHolderName: String(form.bankAccountName || "").trim(),
+      accountNo: String(form.bankCardNo || "")
+        .replace(/\s+/g, "")
+        .trim(),
+      accountInstProvince: province,
+      accountInstCity: city,
+      accountBranchName: String(form.branchName || "").trim(),
+      usageType,
+      accountType: "DC",
+      accountInstName: bankMeta?.label ?? "",
+      accountInstId: String(form.depositBankCode || "").trim()
+    }
+  ];
+}
+
+async function onConfirmSubmit() {
+  if (!formRef.value) return;
+  submitLoading.value = true;
+  try {
+    await formRef.value.validate();
+  } catch {
+    ElMessage.warning("请完善必填信息");
+    submitLoading.value = false;
+    return;
+  }
+  try {
+    const alipayJson = localGet(ALIPAY_JSON_KEY) as Record<string, unknown> | null | undefined;
+    if (!alipayJson || typeof alipayJson !== "object" || Array.isArray(alipayJson)) {
+      ElMessage.warning("缺少步骤一提交数据,请先完成主体信息并点击下一步");
+      return;
+    }
+    const payload: Record<string, unknown> = { ...alipayJson };
+    const alipayLogonId =
+      form.settlementMethod === "alipay" ? String(form.alipayAccount || "").trim() : String(payload.alipayLogonId ?? "").trim();
+    payload.alipayLogonId = alipayLogonId;
+
+    if (form.settlementMethod === "bank") {
+      payload.bizCards = buildBizCardsForPayload();
+    } else {
+      delete payload.bizCards;
+    }
+
+    localSet(ALIPAY_JSON_KEY, payload);
+    await getAlipayZftCreate(payload);
+    ElMessage.success("提交成功");
+  } catch {
+    ElMessage.error("提交失败,请稍后重试");
+  } finally {
+    submitLoading.value = false;
+  }
+}
+
+const invoiceFieldProps = [
+  "taxpayerType",
+  "invoiceTitle",
+  "taxpayerIdNo",
+  "qualificationStartDate",
+  "invoiceAddress",
+  "invoicePhone",
+  "invoiceBankCardNo",
+  "invoiceOpeningBank",
+  "invoiceMailSuite",
+  "invoiceRecipientName",
+  "invoiceRecipientPhone"
+] as const;
+
+watch(
+  () => form.settlementMethod,
+  v => {
+    if (v === "bank") form.accountUsageType = "public";
+    nextTick(() => {
+      formRef.value?.clearValidate([
+        "alipayAccount",
+        "bankAccountName",
+        "bankCardNo",
+        "cnapsCode",
+        "bankBranch",
+        "accountUsageType"
+      ]);
+    });
+  }
+);
+
+watch(
+  () => form.needInvoicing,
+  v => {
+    nextTick(() => {
+      if (v !== "yes") {
+        formRef.value?.clearValidate([...invoiceFieldProps]);
+      }
+    });
+  }
+);
+
+const generalTaxpayerInvoiceExtraProps = ["invoiceAddress", "invoicePhone", "invoiceBankCardNo", "invoiceOpeningBank"] as const;
+
+watch(
+  () => form.taxpayerType,
+  () => {
+    if (form.needInvoicing !== "yes") return;
+    nextTick(() => {
+      formRef.value?.clearValidate([...generalTaxpayerInvoiceExtraProps]);
+    });
+  }
+);
+
+onMounted(() => {
+  formRef.value?.clearValidate();
+});
+</script>
+
+<style scoped lang="scss">
+$zfb-blue: #1677ff;
+.zfb-step-page {
+  box-sizing: border-box;
+  min-height: 100%;
+  padding: 24px 32px 48px;
+  background: #ffffff;
+}
+.step-header {
+  max-width: 960px;
+  margin: 0 auto 32px;
+}
+.zfb-steps {
+  :deep(.el-step__head.is-process) {
+    color: $zfb-blue;
+    border-color: $zfb-blue;
+  }
+  :deep(.el-step__head.is-finish) {
+    color: $zfb-blue;
+    border-color: $zfb-blue;
+  }
+  :deep(.el-step__title.is-process) {
+    font-weight: 600;
+    color: $zfb-blue;
+  }
+  :deep(.el-step__title.is-finish) {
+    font-weight: 500;
+    color: #606266;
+  }
+  :deep(.el-step__title.is-wait) {
+    color: #c0c4cc;
+  }
+}
+.page-layout {
+  display: flex;
+  gap: 32px;
+  align-items: flex-start;
+  max-width: 1100px;
+  margin: 0 auto;
+}
+.main-column {
+  flex: 1;
+  min-width: 0;
+}
+.anchor-column {
+  flex-shrink: 0;
+  width: 160px;
+}
+.anchor-card {
+  padding: 16px 12px;
+}
+.anchor-title {
+  margin-bottom: 12px;
+  font-size: 13px;
+  font-weight: 600;
+  color: #303133;
+}
+.zfb-form {
+  :deep(.el-form-item__label) {
+    font-weight: 500;
+    color: #606266;
+  }
+}
+
+/* 开户银行 prop 为联校占位 bankBranch,不能用 el-form-item required,否则恒校验失败 */
+.bank-branch-required-label::after {
+  margin-left: 4px;
+  color: var(--el-color-danger);
+  content: "*";
+}
+.form-block {
+  padding-bottom: 8px;
+  margin-bottom: 8px;
+  scroll-margin-top: 72px;
+}
+.section-head {
+  display: flex;
+  align-items: center;
+  margin: 0 0 20px;
+  font-size: 16px;
+  font-weight: 600;
+  color: #303133;
+}
+.section-bar {
+  display: inline-block;
+  flex-shrink: 0;
+  width: 4px;
+  height: 16px;
+  margin-right: 8px;
+  background: $zfb-blue;
+  border-radius: 2px;
+}
+.radio-stack {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 10px 20px;
+  align-items: flex-start;
+}
+.settlement-tip-alert {
+  max-width: 480px;
+  margin-top: 12px;
+  color: #1677ff;
+  background: rgb(22 119 255 / 10%);
+  border: 1px solid #1677ff;
+}
+:deep(.el-alert__description) {
+  color: #333333 !important;
+}
+.bank-select-row {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 12px;
+  align-items: center;
+  max-width: 100%;
+}
+.bank-select-cell {
+  width: 200px;
+  min-width: 160px;
+}
+.bank-region-cascader {
+  width: 260px;
+  min-width: 220px;
+}
+.bank-branch-input {
+  width: 280px;
+  min-width: 200px;
+}
+.invoice-extra-wrap {
+  padding-top: 8px;
+  margin-top: 8px;
+}
+.invoice-section-divider {
+  height: 1px;
+  margin: 24px 0 20px;
+  background: #ebeef5;
+}
+.invoice-subsection-title {
+  margin: 0 0 16px;
+  font-size: 15px;
+  font-weight: 600;
+  color: #303133;
+}
+.mail-address-stack {
+  display: flex;
+  flex-direction: column;
+  gap: 12px;
+  width: 100%;
+  max-width: 480px;
+}
+.mail-cascader {
+  width: 100%;
+}
+.mail-detail-input {
+  width: 100%;
+}
+.footer-actions {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 16px;
+  align-items: center;
+  justify-content: center;
+  padding-top: 24px;
+  margin-top: 16px;
+  border-top: 1px solid #ebeef5;
+}
+.btn-primary-zfb {
+  min-width: 120px;
+  background: $zfb-blue;
+  border-color: $zfb-blue;
+  &:hover {
+    background: #4096ff;
+    border-color: #4096ff;
+  }
+}
+:deep(.anchor-card .el-anchor) {
+  background: transparent;
+  border-left: 1px solid #ebeef5;
+}
+:deep(.anchor-card .el-anchor__link) {
+  padding: 6px 0;
+  font-size: 13px;
+}
+</style>

+ 30 - 26
src/views/dynamicManagement/index.vue

@@ -156,7 +156,7 @@
                 </div>
               </div>
             </div>
-            <div style=" padding-bottom: 10px;color: #ffffff">
+            <div style="padding-bottom: 10px; color: #ffffff">
               {{ currentDetail.title }}
             </div>
             <div class="detail-description">
@@ -283,7 +283,7 @@
         <div v-if="commentListData.length > 0" class="comment-list">
           <div v-for="comment in commentListData" :key="comment.id" class="comment-item">
             <div class="comment-avatar">
-              <img v-if="comment.userAvatar" :src="comment.userAvatar" :alt="comment.userName" />
+              <img v-if="comment.userImage" :src="comment.userImage" :alt="comment.userName" />
               <el-icon v-else :size="32">
                 <Avatar />
               </el-icon>
@@ -522,6 +522,7 @@ import {
   uploadImg,
   saveComment,
   commentList,
+  type CommentListParams,
   getMutualAttention,
   addTransferCount,
   deleteDynamicsById,
@@ -533,6 +534,7 @@ import {
 } from "@/api/modules/newLoginApi";
 
 // import { uploadImg } from "@/api/modules/upload";
+import { normalizeCommonCommentListResponse, countTopAndNestedComments } from "@/utils/commonCommentList";
 import { useUserStore } from "@/stores/modules/user";
 import { useWebSocketStore } from "@/stores/modules/websocket";
 
@@ -646,7 +648,6 @@ const handleVideoPlay = (currentIndex: number) => {
     }
   });
 };
-
 // 举报对话框相关
 const reportDialogVisible = ref(false);
 const reportSubmitting = ref(false);
@@ -1014,6 +1015,10 @@ const handleShowComments = () => {
   if (!currentDetail.value) return;
   commentDrawerVisible.value = true;
   currentCommentDynamicId.value = currentDetail.value.id;
+  // 清空评论输入框
+  commentInput.value = "";
+  // 清空回复评论
+  replyingComment.value = null;
 };
 
 // 加载评论列表
@@ -1021,31 +1026,31 @@ const loadCommentList = async () => {
   if (!currentDetail.value) return;
 
   try {
-    let params = {
-      businessId: String(currentDetail.value.id),
-      businessType: "2",
-      replyStatus: 0,
+    const params: CommentListParams = {
       pageNum: 1,
-      pageSize: 10,
-      commentType: 0,
-      days: "",
-      phoneId: `store_${userStore.userInfo?.phone}`
+      pageSize: 100,
+      sourceId: currentDetail.value.id,
+      sourceType: 2
     };
+    const uid = userStore.userInfo?.userId ?? userStore.userInfo?.id;
+    if (uid !== undefined && uid !== null && uid !== "") {
+      const n = Number(uid);
+      if (Number.isFinite(n)) params.userId = Math.trunc(n);
+    }
     const res: any = await commentList(params);
     if (res.code === 200) {
-      commentListData.value = res.data.records || [];
-      // 更新评论总数(包括回复数)
+      const list = normalizeCommonCommentListResponse(res.data);
+      commentListData.value = list;
       if (currentDetail.value) {
-        const baseCommentCount = res.data.total || 0;
-        // 计算所有回复的总数
-        const replyCount = commentListData.value.reduce((total, comment) => {
-          return total + (comment.storeComment?.length || 0);
-        }, 0);
-        // 评论总数 = 评论数 + 回复数
-        currentDetail.value.commentCount = baseCommentCount + replyCount;
+        const raw = res.data;
+        const pageTotal =
+          raw && typeof raw === "object" && !Array.isArray(raw) && typeof (raw as { total?: number }).total === "number"
+            ? (raw as { total: number }).total
+            : undefined;
+        currentDetail.value.commentCount =
+          pageTotal !== undefined && pageTotal >= 0 ? pageTotal : countTopAndNestedComments(list);
       }
       console.log("评论列表:", commentListData.value);
-      console.log("评论总数:", res.data.total);
     }
   } catch (error) {
     console.error("加载评论列表失败:", error);
@@ -1423,11 +1428,11 @@ const handleReportUpload = async (options: any) => {
 
     const response: any = await uploadImg(uploadFormData);
 
-    // 处理返回格式:{ code, success, data: string[], msg }
-    if (response && response.code === 200 && response.data && Array.isArray(response.data) && response.data.length > 0) {
-      // 上传成功,返回图片URL(取数组第一个元素)
+    const url =
+      response?.data && (Array.isArray(response.data) && response.data.length > 0 ? response.data[0] : response.data.fileUrl);
+    if (response && response.code === 200 && url) {
       onSuccess({
-        url: response.data[0]
+        url
       });
     } else {
       ElMessage.error(response?.msg || "图片上传失败");
@@ -1552,7 +1557,6 @@ watch(
     }
   }
 );
-
 // 拉黑用户(点击菜单项)
 const handleBlockUserClick = () => {
   handleBlockUser(false);

+ 23 - 24
src/views/dynamicManagement/myDynamic.vue

@@ -740,6 +740,7 @@ import {
   getDianZanList,
   saveComment,
   commentList,
+  type CommentListParams,
   getMutualAttention,
   getMyFollowed,
   addTransferCount,
@@ -756,6 +757,7 @@ import {} from "@/api/modules/dynamicManagement";
 import { useUserStore } from "@/stores/modules/user";
 import FriendCoupon from "./friendCoupon.vue";
 import { localGet } from "@/utils";
+import { normalizeCommonCommentListResponse, countTopAndNestedComments } from "@/utils/commonCommentList";
 const router = useRouter();
 const userStore = useUserStore();
 
@@ -1273,34 +1275,31 @@ const loadCommentList = async () => {
   if (!currentDetail.value) return;
 
   try {
-    const phone = userStore.userInfo?.phone || "";
-    const phoneId = phone.startsWith("store_") ? phone : `store_${phone}`;
-
-    let params = {
-      businessId: String(currentDetail.value.id),
-      businessType: "2",
-      replyStatus: 0,
+    const params: CommentListParams = {
       pageNum: 1,
       pageSize: 100,
-      commentType: 0,
-      days: "",
-      phoneId: phoneId
+      sourceId: currentDetail.value.id,
+      sourceType: 2
     };
+    const uid = userStore.userInfo?.userId ?? userStore.userInfo?.id;
+    if (uid !== undefined && uid !== null && uid !== "") {
+      const n = Number(uid);
+      if (Number.isFinite(n)) params.userId = Math.trunc(n);
+    }
     const res: any = await commentList(params);
     if (res.code === 200) {
-      commentListData.value = res.data.records || [];
-      // 更新评论总数(包括回复数)
+      const list = normalizeCommonCommentListResponse(res.data);
+      commentListData.value = list;
       if (currentDetail.value) {
-        const baseCommentCount = res.data.total || 0;
-        // 计算所有回复的总数
-        const replyCount = commentListData.value.reduce((total, comment) => {
-          return total + (comment.storeComment?.length || 0);
-        }, 0);
-        // 评论总数 = 评论数 + 回复数
-        currentDetail.value.commentCount = baseCommentCount + replyCount;
+        const raw = res.data;
+        const pageTotal =
+          raw && typeof raw === "object" && !Array.isArray(raw) && typeof (raw as { total?: number }).total === "number"
+            ? (raw as { total: number }).total
+            : undefined;
+        currentDetail.value.commentCount =
+          pageTotal !== undefined && pageTotal >= 0 ? pageTotal : countTopAndNestedComments(list);
       }
       console.log("评论列表:", commentListData.value);
-      console.log("评论总数:", res.data.total);
     }
   } catch (error) {
     console.error("加载评论列表失败:", error);
@@ -1382,12 +1381,12 @@ const handleSubmitComment = async () => {
     const isReply = !!replyingComment.value;
 
     const params: any = {
-      replyId: isReply ? replyingComment.value.id : "", // 回复评论时传评论ID,否则为空
+      replyId: isReply ? replyingComment.value.id : "", // 回复评论时传 parentId,否则为 0
       commentContent: commentInput.value,
       businessType: "2",
-      businessId: String(currentDetail.value.id),
-      storeId: userStore.userInfo?.storeId || userStore.userInfo?.createdId,
-      commentStar: "",
+      businessId: String(currentDetail.value.id), // 对应请求体 sourceId(动态 id)
+      storeId: userStore.userInfo?.storeId || userStore.userInfo?.createdId, // 对应 merchantId
+      userId: userStore.userInfo?.userId ?? userStore.userInfo?.id ?? "",
       phoneId: phoneId
     };
 

+ 1 - 1
src/views/dynamicManagement/reviewAppeal.vue

@@ -22,7 +22,7 @@
           </div>
         </div>
         <div class="stat-card">
-          <div class="stat-label">差评中评数</div>
+          <div class="stat-label">新增中评数</div>
           <div class="stat-value">
             {{ statistics.neutralReviews }}
           </div>

+ 23 - 22
src/views/dynamicManagement/userDynamic.vue

@@ -598,6 +598,7 @@ import {
   setFriendCoupon,
   saveComment,
   commentList,
+  type CommentListParams,
   getUserByPhone,
   reportUserViolation,
   uploadImg,
@@ -607,6 +608,7 @@ import {
 } from "@/api/modules/newLoginApi";
 import { useUserStore } from "@/stores/modules/user";
 import { localGet } from "@/utils";
+import { normalizeCommonCommentListResponse, countTopAndNestedComments } from "@/utils/commonCommentList";
 
 const route = useRoute();
 const router = useRouter();
@@ -872,34 +874,31 @@ const loadCommentList = async () => {
   if (!currentDetail.value) return;
 
   try {
-    const phone = userStore.userInfo?.phone || "";
-    const phoneId = phone.startsWith("store_") ? phone : `store_${phone}`;
-
-    let params = {
-      businessId: String(currentDetail.value.id),
-      businessType: "2",
-      replyStatus: 0,
+    const params: CommentListParams = {
       pageNum: 1,
       pageSize: 100,
-      commentType: 0,
-      days: "",
-      phoneId: phoneId
+      sourceId: currentDetail.value.id,
+      sourceType: 2
     };
+    const uid = userStore.userInfo?.userId ?? userStore.userInfo?.id;
+    if (uid !== undefined && uid !== null && uid !== "") {
+      const n = Number(uid);
+      if (Number.isFinite(n)) params.userId = Math.trunc(n);
+    }
     const res: any = await commentList(params);
     if (res.code === 200) {
-      commentListData.value = res.data.records || [];
-      // 更新评论总数(包括回复数)
+      const list = normalizeCommonCommentListResponse(res.data);
+      commentListData.value = list;
       if (currentDetail.value) {
-        const baseCommentCount = res.data.total || 0;
-        // 计算所有回复的总数
-        const replyCount = commentListData.value.reduce((total, comment) => {
-          return total + (comment.storeComment?.length || 0);
-        }, 0);
-        // 评论总数 = 评论数 + 回复数
-        currentDetail.value.commentCount = baseCommentCount + replyCount;
+        const raw = res.data;
+        const pageTotal =
+          raw && typeof raw === "object" && !Array.isArray(raw) && typeof (raw as { total?: number }).total === "number"
+            ? (raw as { total: number }).total
+            : undefined;
+        currentDetail.value.commentCount =
+          pageTotal !== undefined && pageTotal >= 0 ? pageTotal : countTopAndNestedComments(list);
       }
       console.log("评论列表:", commentListData.value);
-      console.log("评论总数:", res.data.total);
     }
   } catch (error) {
     console.error("加载评论列表失败:", error);
@@ -1490,9 +1489,11 @@ const handleReportUpload = async (options: any) => {
 
     const response: any = await uploadImg(uploadFormData);
 
-    if (response && response.code === 200 && response.data && Array.isArray(response.data) && response.data.length > 0) {
+    const url =
+      response?.data && (Array.isArray(response.data) && response.data.length > 0 ? response.data[0] : response.data.fileUrl);
+    if (response && response.code === 200 && url) {
       onSuccess({
-        url: response.data[0]
+        url
       });
     } else {
       ElMessage.error(response?.msg || "图片上传失败");

+ 220 - 3
src/views/home/components/go-flow.vue

@@ -264,6 +264,13 @@
                   </template>
                 </el-upload>
               </el-form-item>
+              <el-form-item label="设置收款账号" @click="handleSetPayAccount" style="cursor: pointer">
+                <div class="pay-account-trigger">
+                  <el-icon color="#666" class="pay-account-trigger__arrow">
+                    <ArrowRightBold />
+                  </el-icon>
+                </div>
+              </el-form-item>
             </div>
           </div>
         </el-form>
@@ -282,6 +289,41 @@
     @success="hasBusinessHoursConfig = true"
     @has-config="(v: boolean) => (hasBusinessHoursConfig = v)"
   />
+
+  <el-dialog
+    v-model="payAccountDialogVisible"
+    width="420px"
+    align-center
+    append-to-body
+    destroy-on-close
+    class="pay-account-setup-dialog"
+    :show-close="true"
+    @open="onPayAccountDialogOpen"
+  >
+    <template #header>
+      <div class="pay-account-setup-dialog__title">设置收款账号</div>
+    </template>
+    <div class="pay-account-option-list">
+      <button
+        v-for="opt in payAccountOptions"
+        :key="opt.value"
+        type="button"
+        class="pay-account-option"
+        :class="{ 'is-active': payAccountTemp === opt.value }"
+        @click="payAccountTemp = opt.value"
+      >
+        <span class="pay-account-option__icon" :class="`pay-account-option__icon--${opt.value}`" aria-hidden="true" />
+        <span class="pay-account-option__label">{{ opt.label }}</span>
+        <span class="pay-account-option__radio" :class="{ 'is-checked': payAccountTemp === opt.value }">
+          <el-icon v-if="payAccountTemp === opt.value" class="pay-account-option__check"><Check /></el-icon>
+        </span>
+      </button>
+    </div>
+    <template #footer>
+      <el-button type="primary" class="pay-account-setup-dialog__confirm" @click="confirmPayAccount"> 确定 </el-button>
+    </template>
+  </el-dialog>
+
   <!-- 图片预览 -->
   <el-image-viewer
     v-if="imageViewerVisible"
@@ -294,15 +336,17 @@
 <script setup lang="ts">
 import { ref, reactive, watch, onMounted, computed, toRaw } from "vue";
 import { ElMessage, ElMessageBox, type FormInstance, type FormRules, UploadUserFile, UploadRequestOptions } from "element-plus";
-import { Plus } from "@element-plus/icons-vue";
+import { Plus, ArrowRightBold, Check } from "@element-plus/icons-vue";
 
 import { applyStore, getMerchantByPhone, getThirdLevelList, verifyIdInfo } from "@/api/modules/homeEntry";
 import { getInputPrompt, getDistrict, uploadImg, ocrRequestUrl, getAiapprovestoreInfo } from "@/api/modules/newLoginApi";
 import GoBusinessHours from "./go-businessHours.vue";
 import { localGet, localSet } from "@/utils/index";
 import { useAuthStore } from "@/stores/modules/auth";
+import { useRouter } from "vue-router";
 
 const authStore = useAuthStore();
+const router = useRouter();
 const userInfo = localGet("geeker-user")?.userInfo || {};
 const latShow = ref(false);
 const showDisportLicence = ref(false);
@@ -316,6 +360,16 @@ const hasBusinessHoursConfig = ref(false);
 const openBusinessHours = () => {
   businessHoursDialogVisible.value = true;
 };
+
+/** 收款方式:与弹窗选项一致,默认支付宝(与设计稿一致) */
+type ReceivePayType = "alipay" | "wechat" | "bank";
+const payAccountOptions: { value: ReceivePayType; label: string }[] = [
+  { value: "alipay", label: "支付宝支付" },
+  { value: "wechat", label: "微信支付" }
+];
+const payAccountDialogVisible = ref(false);
+const payAccountTemp = ref<ReceivePayType>("alipay");
+
 const entryList = ref([
   {
     title: "个人实名"
@@ -668,9 +722,34 @@ const step2Form = reactive({
   // 经营类目
   businessCategoryName: "",
   // 店铺评价(三项,与 prop="storePj" 对应,校验规则会检查此数组)
-  storePj: ["", "", ""] as string[]
+  storePj: ["", "", ""] as string[],
+  /** 设置收款账号(弹窗选择,提交时带给 saveStoreInfo,后端可按需接收) */
+  receivePayType: "alipay" as ReceivePayType
 });
 
+const payAccountLabel = computed(() => {
+  const v = step2Form.receivePayType;
+  return payAccountOptions.find(o => o.value === v)?.label ?? "支付宝支付";
+});
+
+const handleSetPayAccount = () => {
+  payAccountDialogVisible.value = true;
+};
+
+const onPayAccountDialogOpen = () => {
+  payAccountTemp.value = step2Form.receivePayType;
+};
+
+const confirmPayAccount = () => {
+  step2Form.receivePayType = payAccountTemp.value;
+  payAccountDialogVisible.value = false;
+  if (payAccountTemp.value === "alipay") {
+    router.push({ path: "/businessInfo/zfbIndex" });
+  } else if (payAccountTemp.value === "wechat") {
+    router.push({ path: "/businessInfo/weChartIndex" });
+  }
+};
+
 // 返回按钮
 const handleBack = () => {
   if (currentStep.value === 1) {
@@ -1304,7 +1383,8 @@ const handleSubmit = async () => {
         foodLicenceUrl: foodLicenceUrls.join(","),
         mealsFlag: step2Form.businessSecondMeal === 1 ? 1 : 0,
         createdUserId: userInfo.id || "",
-        storeBusinessTime: storeBusinessTime.length > 0 ? storeBusinessTime : undefined
+        storeBusinessTime: storeBusinessTime.length > 0 ? storeBusinessTime : undefined,
+        receivePayType: step2Form.receivePayType
       };
 
       ElMessageBox.confirm("确认提交入驻申请吗?", "提示", {
@@ -1553,5 +1633,142 @@ const handleExceed = () => {
       outline: none;
     }
   }
+  .pay-account-trigger {
+    display: inline-flex;
+    gap: 10px;
+    align-items: center;
+    &__text {
+      font-size: 14px;
+      color: #303133;
+    }
+    &__arrow {
+      cursor: pointer;
+    }
+  }
+}
+</style>
+
+<style lang="scss">
+/* 弹窗挂到 body,需非 scoped;并抵消本页全局 .el-dialog__body { height: 600px } */
+.pay-account-setup-dialog.el-dialog {
+  padding: 0;
+  overflow: hidden;
+  border-radius: 12px;
+  box-shadow: 0 8px 32px rgb(0 0 0 / 12%);
+}
+.pay-account-setup-dialog .el-dialog__header {
+  padding: 20px 24px 12px;
+  margin: 0;
+}
+.pay-account-setup-dialog .el-dialog__headerbtn {
+  top: 16px;
+  right: 16px;
+  font-size: 18px;
+}
+.pay-account-setup-dialog .el-dialog__body {
+  height: auto !important;
+  max-height: none !important;
+  padding: 4px 24px 8px !important;
+  overflow: visible !important;
+}
+.pay-account-setup-dialog .el-dialog__footer {
+  padding: 16px 24px 24px;
+}
+.pay-account-setup-dialog__title {
+  width: 100%;
+  font-size: 17px;
+  font-weight: 600;
+  color: #303133;
+  text-align: center;
+}
+.pay-account-option-list {
+  display: flex;
+  flex-direction: column;
+}
+.pay-account-option {
+  display: flex;
+  gap: 14px;
+  align-items: center;
+  width: 100%;
+  padding: 16px 0;
+  margin: 0;
+  font: inherit;
+  text-align: left;
+  cursor: pointer;
+  background: transparent;
+  border: none;
+  border-bottom: 1px solid #ebeef5;
+  outline: none;
+}
+.pay-account-option:last-of-type {
+  border-bottom: none;
+}
+.pay-account-option__icon {
+  flex-shrink: 0;
+  width: 36px;
+  height: 36px;
+  border-radius: 8px;
+}
+.pay-account-option__icon--alipay {
+  background: #1677ff;
+  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23fff' d='M8.5 7.2h2.2v1.9H8.5V7.2zm0 3.1h2.2v5.4H8.5v-5.4zm3.8-3.1h4.6c1.4 0 2.4 1 2.4 2.3 0 1.1-.7 2-1.7 2.3l1.9 3.8h-2.5l-1.6-3.2h-1.4v3.2h-2.2V7.2zm2.2 3.6h2.1c.6 0 1-.4 1-.9 0-.5-.4-.9-1-.9h-2.1v1.8z'/%3E%3C/svg%3E");
+  background-repeat: no-repeat;
+  background-position: center;
+  background-size: 26px 26px;
+}
+.pay-account-option__icon--wechat {
+  background: #07c160;
+  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23fff' d='M8.5 10.5c-.8 0-1.5-.7-1.5-1.5S7.7 7.5 8.5 7.5 10 8.2 10 9s-.7 1.5-1.5 1.5zm7 0c-.8 0-1.5-.7-1.5-1.5S14.7 7.5 15.5 7.5 17 8.2 17 9s-.7 1.5-1.5 1.5z'/%3E%3Cpath fill='%23fff' d='M9 14.5c-2.5 0-4.5-1.6-4.5-3.5 0-1 .5-1.9 1.3-2.6-.1-.3-.2-.7-.2-1C5.6 5.8 8.9 4 13 4s7.4 1.8 7.4 4c0 .4-.1.8-.2 1 .8.7 1.3 1.6 1.3 2.6 0 1.9-2 3.5-4.5 3.5-.6 0-1.2-.1-1.8-.3l-2 1.1.5-1.8c-.9-.5-1.6-1.2-2-2z'/%3E%3C/svg%3E");
+  background-repeat: no-repeat;
+  background-position: center;
+  background-size: 24px 24px;
+}
+.pay-account-option__icon--bank {
+  background-color: #3b7cff;
+  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Crect x='3' y='7' width='18' height='11' rx='2' fill='%23fff' opacity='.95'/%3E%3Crect x='3' y='10' width='18' height='2' fill='%233b7cff'/%3E%3C/svg%3E");
+  background-repeat: no-repeat;
+  background-position: center;
+  background-size: 28px 22px;
+}
+.pay-account-option__label {
+  flex: 1;
+  font-size: 15px;
+  color: #303133;
+}
+.pay-account-option__radio {
+  display: flex;
+  flex-shrink: 0;
+  align-items: center;
+  justify-content: center;
+  width: 22px;
+  height: 22px;
+  border: 2px solid #dcdfe6;
+  border-radius: 50%;
+  transition:
+    border-color 0.2s,
+    background 0.2s;
+}
+.pay-account-option__radio.is-checked {
+  background: #7395ff;
+  border-color: #7395ff;
+}
+.pay-account-option__check {
+  font-size: 14px;
+  font-weight: 700;
+  color: #ffffff;
+}
+.pay-account-setup-dialog__confirm {
+  width: 100%;
+  height: 44px;
+  font-size: 16px;
+  font-weight: 500;
+  color: #ffffff;
+  background: #7395ff !important;
+  border-color: #7395ff !important;
+  border-radius: 8px;
+}
+.pay-account-setup-dialog__confirm:hover {
+  background: #5f82f0 !important;
+  border-color: #5f82f0 !important;
 }
 </style>

+ 14 - 14
src/views/operationManagement/activityList.vue

@@ -323,20 +323,20 @@ const columns = reactive<ColumnProps<any>[]>([
       return activityType == "MARKETING" ? "营销活动" : "评论有礼";
     }
   },
-  {
-    prop: "signupStartTime",
-    label: "报名开始时间/结束时间",
-    width: 300,
-    render: (scope: any) => {
-      const formatDate = (dateStr: string) => {
-        if (!dateStr) return "--";
-        // 只取日期部分(去掉时分秒)
-        const datePart = dateStr.split(" ")[0];
-        return datePart?.replace(/-/g, "/") || "--";
-      };
-      return `${formatDate(scope.row.signupStartTime)} - ${formatDate(scope.row.signupEndTime)}`;
-    }
-  },
+  // {
+  //   prop: "signupStartTime",
+  //   label: "报名开始时间/结束时间",
+  //   width: 300,
+  //   render: (scope: any) => {
+  //     const formatDate = (dateStr: string) => {
+  //       if (!dateStr) return "--";
+  //       // 只取日期部分(去掉时分秒)
+  //       const datePart = dateStr.split(" ")[0];
+  //       return datePart?.replace(/-/g, "/") || "--";
+  //     };
+  //     return `${formatDate(scope.row.signupStartTime)} - ${formatDate(scope.row.signupEndTime)}`;
+  //   }
+  // },
   {
     prop: "startTime",
     label: "活动开始时间/结束时间",

+ 52 - 16
src/views/operationManagement/newActivity.vue

@@ -81,8 +81,8 @@
           </div>
         </div>
 
-        <!-- 4. 活动详情图 -->
-        <div class="form-item-card">
+        <!-- 4. 活动详情图(仅营销活动需要) -->
+        <div v-if="activityModel.activityType === 'MARKETING'" class="form-item-card">
           <div class="form-item card-item">
             <div class="form-label form-label-col">活动详情图 <span class="required">*</span></div>
             <div class="detail-upload-wrapper upload-slot-dashed">
@@ -401,10 +401,11 @@ const imageViewerInitialIndex = ref(0);
 
 // 是否有未上传的图片
 const hasUnuploadedImages = computed(() => {
-  return (
-    titleFileList.value.some(file => file.status === "ready" || file.status === "uploading") ||
-    detailFileList.value.some(file => file.status === "ready" || file.status === "uploading")
-  );
+  const titlePending = titleFileList.value.some(file => file.status === "ready" || file.status === "uploading");
+  const detailPending =
+    activityModel.value.activityType === "MARKETING" &&
+    detailFileList.value.some(file => file.status === "ready" || file.status === "uploading");
+  return titlePending || detailPending;
 });
 
 // ==================== 表单验证规则 ====================
@@ -646,6 +647,10 @@ const rules = reactive({
     {
       required: true,
       validator: (_rule: any, _value: any, callback: any) => {
+        if (activityModel.value.activityType !== "MARKETING") {
+          callback();
+          return;
+        }
         const successFiles = detailFileList.value.filter((f: any) => f.status === "success" && f.url);
         if (successFiles.length === 0) {
           callback(new Error("请上传活动详情图"));
@@ -1204,9 +1209,10 @@ const handlegetTime = (val: string) => {
   return val || "";
 };
 
-/** 将 AI 接口返回写入 banner / 详情图 */
+/** 将 AI 接口返回写入 banner / 详情图(评价有礼仅写入 banner) */
 const applyPromotionImagesFromResponse = (data: any) => {
   if (!data || typeof data !== "object") return;
+  const isMarketing = activityModel.value.activityType === "MARKETING";
 
   const titleObj = data.activityTitleImg;
   if (titleObj && titleObj.imgUrl) {
@@ -1231,6 +1237,13 @@ const applyPromotionImagesFromResponse = (data: any) => {
     }
   }
 
+  if (!isMarketing) {
+    nextTick(() => {
+      ruleFormRef.value?.validateField(["activityTitleImage"]);
+    });
+    return;
+  }
+
   const detailObj = data.activityDetailImg;
   if (detailObj) {
     let urls: string[] = [];
@@ -1282,7 +1295,11 @@ const handleAiGenerate = async () => {
     if (res && res.code == 200) {
       applyPromotionImagesFromResponse(res.data);
       nextTick(() => {
-        ruleFormRef.value?.validateField(["activityTitleImage", "activityDetailImage"]);
+        const fields: string[] =
+          activityModel.value.activityType === "MARKETING"
+            ? ["activityTitleImage", "activityDetailImage"]
+            : ["activityTitleImage"];
+        ruleFormRef.value?.validateField(fields);
       });
       ElMessage.success(res.msg || "图片生成成功");
     } else {
@@ -1340,13 +1357,22 @@ watch(
           "voucherQuantity"
         ]);
       } else if (typeValue === "COMMENT") {
-        // 切换到评论有礼:清除营销活动相关字段
+        // 切换到评论有礼:清除营销活动相关字段(含活动详情图,评价有礼不需要)
         activityModel.value.signupTimeRange = [];
         activityModel.value.activityLimitPeople = "";
         activityModel.value.activityDetails = "";
+        const detailUids = new Set(detailFileList.value.map((f: any) => f.uid));
+        detailFileList.value.forEach((f: any) => {
+          if (f?.url && String(f.url).startsWith("blob:")) URL.revokeObjectURL(f.url);
+        });
+        detailFileList.value = [];
+        detailImageUrl.value = "";
+        activityModel.value.activityDetailImg = null;
+        activityModel.value.activityDetailImage = "";
+        pendingUploadFiles.value = pendingUploadFiles.value.filter((f: any) => !detailUids.has(f.uid));
         activityModel.value.discountCouponType = activityModel.value.rewardType === "VOUCHER" ? 1 : 2;
         // 清除营销活动字段的验证状态
-        ruleFormRef.value?.clearValidate(["signupTimeRange", "activityLimitPeople", "activityDetails"]);
+        ruleFormRef.value?.clearValidate(["signupTimeRange", "activityLimitPeople", "activityDetails", "activityDetailImage"]);
         // 加载优惠券列表
         loadCouponList();
       }
@@ -1579,10 +1605,9 @@ onMounted(async () => {
             titleFileList.value = [titleFile];
           }
         }
-        // 如果有详情图片,添加到文件列表(支持多张图片,可能是字符串或数组
-        if (res.data.activityDetailImgUrl) {
+        // 营销活动:加载详情图(评价有礼不需要
+        if (activityModel.value.activityType === "MARKETING" && res.data.activityDetailImgUrl) {
           let detailImgUrls: string[] = [];
-          // 如果是字符串,可能是逗号分隔的多张图片
           if (typeof res.data.activityDetailImgUrl === "string") {
             detailImgUrls = res.data.activityDetailImgUrl.split(",").filter((url: string) => url.trim());
           } else if (Array.isArray(res.data.activityDetailImgUrl)) {
@@ -1593,9 +1618,13 @@ onMounted(async () => {
             detailImageUrl.value = detailImgUrls.join(",");
             activityModel.value.activityDetailImg = res.data.activityDetailImgUrl;
             activityModel.value.activityDetailImage = detailImgUrls.join(",");
-            // 将多张图片添加到文件列表
             detailFileList.value = detailImgUrls.map((url: string) => handleImageParam(url));
           }
+        } else if (activityModel.value.activityType === "COMMENT") {
+          detailFileList.value = [];
+          detailImageUrl.value = "";
+          activityModel.value.activityDetailImg = null;
+          activityModel.value.activityDetailImage = "";
         }
       }
     } catch (error) {
@@ -1650,11 +1679,18 @@ const handleSubmit = async () => {
       // 活动时间:开始日期传当天 00:00:00,结束日期传当天 23:59:59
       const startTime = activityStartDate ? `${activityStartDate} 00:00:00` : "";
       const endTime = activityEndDate ? `${activityEndDate} 23:59:59` : "";
+      const detailUrls =
+        activityModel.value.activityType === "MARKETING" && detailImageUrl.value
+          ? detailImageUrl.value
+              .split(",")
+              .map((s: string) => s.trim())
+              .filter(Boolean)
+          : [];
       const auditParam = {
         text: activityModel.value.imgDescribe?.trim()
           ? `${activityModel.value.activityName},${activityModel.value.imgDescribe.trim()}`
           : activityModel.value.activityName,
-        image_urls: [titleImageUrl.value, ...(detailImageUrl.value ? detailImageUrl.value.split(",") : [])].filter(Boolean)
+        image_urls: [titleImageUrl.value, ...detailUrls].filter(Boolean)
       };
       const params: any = {
         activityType: activityModel.value.activityType,
@@ -1696,7 +1732,7 @@ const handleSubmit = async () => {
         storeId: localGet("createdId")
       };
       params.activityDetailImg = {
-        imgUrl: detailImageUrl.value,
+        imgUrl: activityModel.value.activityType === "MARKETING" ? detailImageUrl.value : "",
         imgSort: 0,
         storeId: localGet("createdId")
       };

+ 11 - 1
src/views/storeDecoration/basicStoreInformation/index.vue

@@ -200,6 +200,12 @@
           <el-form-item label="经营类目" prop="businessCategoryName">
             <el-input v-model="formData.businessCategoryName" placeholder="请输入经营类目" clearable maxlength="50" />
           </el-form-item>
+          <el-form-item label="预定服务" prop="bookingService">
+            <el-radio-group v-model="formData.bookingService">
+              <el-radio :value="1"> 提供 </el-radio>
+              <el-radio :value="0"> 不提供 </el-radio>
+            </el-radio-group>
+          </el-form-item>
           <el-form-item label="营业时间">
             <div style="color: #6c8ff8; cursor: pointer" @click="handleViewBusinessHours">查看</div>
           </el-form-item>
@@ -857,7 +863,9 @@ const formData = reactive({
   storePositionLongitude: "",
   storePositionLatitude: "",
   isChain: 0,
-  storeTickets: "" as number | ""
+  storeTickets: "" as number | "",
+  /** 预定服务:1 提供 / 0 不提供(与 go-flow 入驻 bookingService 一致) */
+  bookingService: 0 as 0 | 1
 });
 
 // 经纬度查询
@@ -1171,6 +1179,7 @@ const handleSubmit = async () => {
         businessSectionName: selectedSection ? selectedSection.dictDetail : "",
         businessTypeName: formData.businessTypeName,
         businessCategoryName: formData.businessCategoryName,
+        bookingService: formData.bookingService,
         // 标签选择(仅当经营板块为生活服务时)
         storeTickets:
           formData.businessSection === 3 ? (formData.storeTickets !== "" ? formData.storeTickets : undefined) : undefined
@@ -1280,6 +1289,7 @@ const getStoreDetailData = async () => {
       // 如果 businessCategoryName 是 0,转换为空字符串
       const categoryName = storeData.businessCategoryName;
       formData.businessCategoryName = categoryName === 0 || categoryName === "0" ? "" : categoryName || "";
+      formData.bookingService = storeData.bookingService === 1 || storeData.bookingService === "1" ? 1 : 0;
     }
   } catch (error) {
     console.error("获取店铺详情失败:", error);

+ 0 - 1
src/views/storeDecoration/businessHours/index.vue

@@ -232,7 +232,6 @@ function getListTitle(item: NormalHoursItem | SpecialHoursItem, type: 1 | 2) {
   if (type === 1) {
     const n = item as NormalHoursItem;
     const sorted = [...n.days].sort((a, b) => a - b);
-    if (sorted.length === 7) return "周一至周日";
     return sorted
       .map(d => weekDays.find(w => w.value === d)?.label)
       .filter(Boolean)

+ 37 - 24
src/views/storeDecoration/officialPhotoAlbum/index.vue

@@ -3,8 +3,8 @@
     <!-- 头部:环境/视频/相册 Tab和新建按钮 -->
     <div class="header-section">
       <el-tabs v-model="activeTab" @tab-click="handleTabClick">
-        <el-tab-pane label="环境" name="environment" />
-        <el-tab-pane label="视频" name="video" />
+        <!-- <el-tab-pane label="环境" name="environment" />
+        <el-tab-pane label="视频" name="video" /> -->
         <el-tab-pane v-for="album in albumList" :key="album.id" :label="album.name" :name="String(album.id)">
           <template #label>
             <span class="album-tab-label">
@@ -187,12 +187,22 @@ import {
 } from "@/api/modules/storeDecoration";
 import { uploadFilesToOss } from "@/api/upload.js";
 
+/** 普通官方相册图 */
+const OFFICIAL_IMG_TYPE_ALBUM = 2;
+/** 环境 Tab 及约定走环境图类型的相册 Tab(如 id=182) */
+const OFFICIAL_IMG_TYPE_ENV_OR_SPECIAL_ALBUM = 4;
+
+/** 相册 Tab 的 name 为相册 id 字符串;列入此集合的 Tab 拉列表、保存时 imgType 均为 4 */
+const albumTabNamesWithImgType4 = new Set<string>(["182"]);
+
+const isAlbumTabImgType4 = (tabKey: string) => albumTabNamesWithImgType4.has(String(tabKey));
+
 // 扩展图片类型
 interface AlbumImage extends UploadUserFile {
   isCover?: boolean;
   businessId?: number; // 相册ID
   imgSort?: number; // 排序
-  imgType?: number; // 图片类型,固定为2
+  imgType?: number; // 相册默认 2;环境 / 特殊相册 Tab 为 4
   imgId?: number; // 图片ID(从服务器返回)
 }
 
@@ -217,7 +227,8 @@ interface Album {
 
 const createDialogVisible = ref(false);
 const createFormRef = ref<FormInstance>();
-const activeTab = ref("environment"); // 当前选中的tab:environment、video 或 相册ID
+// 环境 / 视频 / 相册 id(字符串);初始为空,相册列表加载后默认选中第一项
+const activeTab = ref("");
 const previewVisible = ref(false);
 const previewImageUrl = ref("");
 const previewVideoUrl = ref("");
@@ -538,11 +549,16 @@ const saveImageToServer = async (imgUrl: string) => {
 
     const imgSort = currentImages.filter((img: AlbumImage) => img.imgId).length + 1; // 排序为已保存图片数量+1
 
+    const imgType =
+      activeTab.value === "environment" || isAlbumTabImgType4(activeTab.value)
+        ? OFFICIAL_IMG_TYPE_ENV_OR_SPECIAL_ALBUM
+        : OFFICIAL_IMG_TYPE_ALBUM;
+
     const params = [
       {
         businessId: businessId,
         imgSort: imgSort,
-        imgType: 2, // 图片类型为2
+        imgType,
         imgUrl: imgUrl,
         storeId: Number(storeId)
       }
@@ -755,14 +771,8 @@ const handleDeleteAlbum = async () => {
       createDialogVisible.value = false;
       resetCreateForm();
 
-      // 重新获取相册列表
+      // 重新获取相册列表(当前 tab 若已不存在会自动选中第一项或清空)
       await getAlbumList();
-
-      // 如果删除的是当前选中的相册,切换到环境tab
-      if (String(editId.value) === activeTab.value) {
-        activeTab.value = "environment";
-        await loadEnvironmentImages();
-      }
     } else {
       ElMessage.error(res?.msg || "删除相册失败");
     }
@@ -1076,10 +1086,17 @@ const getAlbumList = async () => {
         videos: reactive<AlbumVideo[]>([]),
         coverImageId: album.coverImageId
       }));
-      // 默认选中"环境"tab
-      if (!activeTab.value || activeTab.value === "") {
-        activeTab.value = "environment";
-        await loadEnvironmentImages();
+      // 默认选中第一个相册;若当前 tab 仍有效则保留(如刷新列表、新建后切到最后一个)
+      const prev = activeTab.value;
+      const idSet = new Set(albumList.value.map(a => String(a.id)));
+      if (albumList.value.length > 0) {
+        const keepSpecial = prev === "environment" || prev === "video";
+        const keepAlbum = Boolean(prev && idSet.has(String(prev)));
+        if (!keepSpecial && !keepAlbum) {
+          activeTab.value = String(albumList.value[0].id);
+        }
+      } else if (prev !== "environment" && prev !== "video") {
+        activeTab.value = "";
       }
     }
   } catch (error) {
@@ -1100,7 +1117,7 @@ const loadEnvironmentImages = async () => {
     // 环境图片:使用 storeId 作为 businessId(需要根据实际API调整)
     // 或者如果环境图片不需要 businessId,可能需要使用其他API
     // 这里先使用 storeId 作为 businessId
-    const imageRes: any = await getOfficialImgList(Number(storeId), Number(storeId), 2);
+    const imageRes: any = await getOfficialImgList(Number(storeId), Number(storeId), OFFICIAL_IMG_TYPE_ENV_OR_SPECIAL_ALBUM);
 
     if (imageRes && (imageRes.code === 200 || imageRes.code === "200") && imageRes.data) {
       const imageList = Array.isArray(imageRes.data) ? imageRes.data : [];
@@ -1194,8 +1211,8 @@ const loadAlbumImages = async (albumId: string) => {
       return;
     }
 
-    // 加载图片(imgType = 2)
-    const imageRes: any = await getOfficialImgList(Number(albumId), Number(storeId), 2);
+    const listImgType = isAlbumTabImgType4(albumId) ? OFFICIAL_IMG_TYPE_ENV_OR_SPECIAL_ALBUM : OFFICIAL_IMG_TYPE_ALBUM;
+    const imageRes: any = await getOfficialImgList(Number(albumId), Number(storeId), listImgType);
 
     const current = albumList.value.find(album => String(album.id) === albumId);
     if (!current) {
@@ -1253,13 +1270,9 @@ const loadAlbumImages = async (albumId: string) => {
   }
 };
 
-// 页面初始化
+// 页面初始化:拉相册列表后默认第一项,图片由 watch(activeTab) 加载
 onMounted(async () => {
   await getAlbumList();
-  // 默认加载环境图片
-  if (activeTab.value === "environment") {
-    await loadEnvironmentImages();
-  }
 });
 </script>
 

+ 45 - 22
src/views/storeDecoration/personnelConfig/index.vue

@@ -416,6 +416,23 @@ const approvalStatusEnum = [
   { label: "已驳回", value: 2 }
 ];
 
+/** 列表/详情:统一为 YYYY-MM-DD HH:mm:ss */
+const formatTime = (time: string | null | undefined) => {
+  if (!time) return "";
+  try {
+    const date = new Date(time);
+    const y = date.getFullYear();
+    const m = String(date.getMonth() + 1).padStart(2, "0");
+    const d = String(date.getDate()).padStart(2, "0");
+    const h = String(date.getHours()).padStart(2, "0");
+    const min = String(date.getMinutes()).padStart(2, "0");
+    const s = String(date.getSeconds()).padStart(2, "0");
+    return `${y}-${m}-${d} ${h}:${min}:${s}`;
+  } catch {
+    return time;
+  }
+};
+
 // 表格配置项
 const columns = reactive<ColumnProps<any>[]>([
   {
@@ -496,7 +513,24 @@ const columns = reactive<ColumnProps<any>[]>([
   {
     prop: "createdTime",
     label: "提交时间",
-    width: 180
+    width: 190,
+    render: (scope: any) => {
+      const t = scope.row.submissionTime || scope.row.createdTime;
+      return t ? formatTime(t) : "—";
+    },
+    search: {
+      el: "date-picker",
+      props: {
+        type: "datetimerange",
+        "range-separator": "至",
+        "start-placeholder": "开始时间",
+        "end-placeholder": "结束时间",
+        format: "YYYY-MM-DD HH:mm:ss",
+        "value-format": "YYYY-MM-DD HH:mm:ss"
+      },
+      order: 5,
+      span: 2
+    }
   },
   { prop: "operation", label: "操作", fixed: "right", minWidth: 350 }
 ]);
@@ -586,10 +620,16 @@ const getTableList = (params: any) => {
   if (params.approvalStatus !== undefined && params.approvalStatus !== null && params.approvalStatus !== "") {
     newParams.status = params.approvalStatus; // 审核状态 -> status
   }
-  // 处理日期范围 - 使用 startCreatedTime 和 endCreatedTime
-  if (params.dateRange && Array.isArray(params.dateRange) && params.dateRange.length === 2) {
-    newParams.startCreatedTime = params.dateRange[0];
-    newParams.endCreatedTime = params.dateRange[1];
+  // 提交时间:ProTable 搜索项 prop 为 createdTime,值为 [start, end]
+  const submissionRange =
+    params.createdTime && Array.isArray(params.createdTime) && params.createdTime.length === 2
+      ? params.createdTime
+      : params.dateRange && Array.isArray(params.dateRange) && params.dateRange.length === 2
+        ? params.dateRange
+        : null;
+  if (submissionRange) {
+    newParams.startCreatedTime = submissionRange[0];
+    newParams.endCreatedTime = submissionRange[1];
   }
 
   // 使用新的搜索接口
@@ -600,7 +640,6 @@ const getTableList = (params: any) => {
   });
 };
 
-// 格式化时间
 // 获取背景图片/视频列表
 const getBackgroundImageList = (backgroundUrl: string | null | undefined): string[] => {
   if (!backgroundUrl) return [];
@@ -630,22 +669,6 @@ const handleVideoPreviewInForm = (url: string) => {
   previewVideoVisible.value = true;
 };
 
-const formatTime = (time: string | null | undefined) => {
-  if (!time) return "";
-  try {
-    const date = new Date(time);
-    const y = date.getFullYear();
-    const m = String(date.getMonth() + 1).padStart(2, "0");
-    const d = String(date.getDate()).padStart(2, "0");
-    const h = String(date.getHours()).padStart(2, "0");
-    const min = String(date.getMinutes()).padStart(2, "0");
-    const s = String(date.getSeconds()).padStart(2, "0");
-    return `${y}-${m}-${d} ${h}:${min}:${s}`;
-  } catch {
-    return time;
-  }
-};
-
 // 弹窗标题
 const dialogTitle = computed(() => (editId.value !== null ? "编辑" : "新建"));
 

+ 70 - 43
src/views/storeDecoration/storeHeadMap/index.vue

@@ -5,12 +5,21 @@
       <div class="mode-preview-section">
         <div class="preview-box">
           <div class="preview-card">
-            <div class="preview-images-multiple">
-              <div v-for="(img, index) in displayImages" :key="index" class="preview-image-small">
-                <img v-if="img" :src="img" alt="头图" />
-                <div v-else class="preview-placeholder">示例图</div>
-              </div>
-              <div v-if="displayImages.length < 3" class="preview-image-small">
+            <div class="preview-images-carousel">
+              <el-carousel
+                v-if="carouselPreviewImages.length > 0"
+                height="250px"
+                :autoplay="carouselPreviewImages.length > 1"
+                :interval="4000"
+                indicator-position="none"
+                :arrow="carouselPreviewImages.length > 1 ? 'hover' : 'never'"
+                class="head-preview-carousel"
+              >
+                <el-carousel-item v-for="(url, index) in carouselPreviewImages" :key="index">
+                  <img :src="url" alt="头图" class="carousel-preview-img" />
+                </el-carousel-item>
+              </el-carousel>
+              <div v-else class="carousel-preview-empty">
                 <div class="preview-placeholder">示例图</div>
               </div>
               <div class="overlay-button">
@@ -63,9 +72,7 @@
                 :show-success-notification="false"
               >
                 <template #tip>
-                  <div class="upload-tip">
-                    上传图片{{ formData.multipleImages.length }} ({{ formData.multipleImages.length }}/6)
-                  </div>
+                  <div class="upload-tip">上传图片({{ formData.multipleImages.length }}/6)</div>
                 </template>
               </UploadImgs>
             </div>
@@ -86,6 +93,9 @@ import { ref, reactive, computed, onMounted, watch, nextTick } from "vue";
 import { ElMessage, ElNotification } from "element-plus";
 import type { FormInstance, FormRules } from "element-plus";
 import type { UploadUserFile } from "element-plus";
+
+/** 服务端图片主键,用于 saveOrUpdateImg 区分更新与新增 */
+type HeadMapUploadFile = UploadUserFile & { serverImgId?: number | string };
 import { ArrowRight } from "@element-plus/icons-vue";
 import Sortable from "sortablejs";
 import UploadImgs from "@/components/Upload/Imgs.vue";
@@ -147,7 +157,7 @@ const handleStoreOcr = async (params: { imageUrl: string }) => {
 };
 
 const formData = reactive({
-  multipleImages: [] as UploadUserFile[]
+  multipleImages: [] as HeadMapUploadFile[]
 });
 
 const previewData = reactive({
@@ -155,8 +165,9 @@ const previewData = reactive({
   reviews: 1853
 });
 
-const displayImages = computed(() => {
-  return formData.multipleImages.slice(0, 3).map(item => item.url || "");
+/** 预览轮播:展示已上传头图,一次一张 */
+const carouselPreviewImages = computed(() => {
+  return formData.multipleImages.map(item => item.url || "").filter((url): url is string => Boolean(url));
 });
 
 /**
@@ -234,16 +245,17 @@ const getStoreHeadImgData = async () => {
       return;
     }
 
-    const res: any = await getStoreHeadImg(storeId, 21);
+    const res: any = await getStoreHeadImg(storeId, 20);
     if (res && (res.code === 200 || res.code === "200") && res.data) {
       const dataAny = res.data as any;
       const imgList = Array.isArray(dataAny) ? dataAny : dataAny.storeImgList || [];
       if (imgList.length > 0) {
         formData.multipleImages = imgList.map((item: any, index: number) => ({
-          uid: item.id || index,
+          uid: item.id != null ? item.id : `loaded-${index}-${Date.now()}`,
           name: `image-${index + 1}`,
           url: item.imgUrl,
-          status: "success"
+          status: "success",
+          serverImgId: item.id != null ? item.id : undefined
         }));
         nextTick(() => {
           initDragSort();
@@ -279,12 +291,6 @@ onMounted(async () => {
 
 const handleSave = async () => {
   if (!multipleFormRef.value) return;
-  try {
-    await multipleFormRef.value.validate();
-  } catch {
-    ElMessage.warning("至少上传3张图片");
-    return;
-  }
 
   const userInfo: any = localGet("geeker-user")?.userInfo || {};
   const storeId = userInfo.storeId;
@@ -295,16 +301,23 @@ const handleSave = async () => {
 
   loading.value = true;
   try {
-    const storeImgList = formData.multipleImages.map((item, index) => ({
-      imgType: 21,
-      imgUrl: item.url || "",
-      imgSort: index + 1,
-      storeId: Number(storeId)
-    }));
+    const storeImgList = formData.multipleImages.map((item, index) => {
+      const row: Record<string, unknown> = {
+        imgType: 20,
+        imgUrl: item.url || "",
+        imgSort: index + 1,
+        storeId: Number(storeId)
+      };
+      const sid = (item as HeadMapUploadFile).serverImgId;
+      if (sid != null && sid !== "") {
+        row.id = typeof sid === "string" ? Number(sid) || sid : sid;
+      }
+      return row;
+    });
 
     const params = {
       imgMode: 1,
-      imgType: 21,
+      imgType: 20,
       storeId: Number(storeId),
       storeImgList
     };
@@ -350,30 +363,42 @@ const handleSave = async () => {
         border-radius: 8px;
         box-shadow: 0 2px 12px 0 rgb(0 0 0 / 10%);
         transition: all 0.3s;
-        .preview-images-multiple {
+        .preview-images-carousel {
           position: relative;
-          display: flex;
-          gap: 4px;
           width: 100%;
-          height: 200px;
           margin-bottom: 16px;
-          overflow: hidden;
+          overflow: visible;
           background-color: #f0f0f0;
           border-radius: 8px;
-          .preview-image-small {
+          .head-preview-carousel {
+            width: 100%;
+            :deep(.el-carousel__container) {
+              height: 200px;
+              border-radius: 8px;
+            }
+            :deep(.el-carousel__item) {
+              display: flex;
+              align-items: center;
+              justify-content: center;
+              overflow: hidden;
+              background-color: #e4e7ed;
+            }
+            :deep(.el-carousel__arrow) {
+              background-color: rgb(0 0 0 / 35%);
+            }
+          }
+          .carousel-preview-img {
+            width: 100%;
+            height: 100%;
+            object-fit: cover;
+          }
+          .carousel-preview-empty {
             display: flex;
-            flex: 1;
             align-items: center;
             justify-content: center;
-            height: 100%;
-            overflow: hidden;
+            height: 200px;
             background-color: #e4e7ed;
-            border-radius: 4px;
-            img {
-              width: 100%;
-              height: 100%;
-              object-fit: cover;
-            }
+            border-radius: 8px;
             .preview-placeholder {
               font-size: 12px;
               color: #909399;
@@ -383,12 +408,14 @@ const handleSave = async () => {
             position: absolute;
             right: 12px;
             bottom: 12px;
+            z-index: 2;
             display: flex;
             gap: 4px;
             align-items: center;
             padding: 6px 12px;
             font-size: 12px;
             color: white;
+            pointer-events: none;
             background-color: rgb(0 0 0 / 60%);
             border-radius: 4px;
           }

+ 80 - 46
src/views/storeDecoration/storeLabel/index.vue

@@ -252,7 +252,7 @@ import { ref, reactive, computed, onMounted } from "vue";
 import { ElMessage } from "element-plus";
 import type { FormInstance, FormRules } from "element-plus";
 import { localGet } from "@/utils";
-import { getAllTagType, getAllTag, saveTag } from "@/api/modules/storeDecoration";
+import { getTagList, getAllTag, saveTag } from "@/api/modules/storeDecoration";
 
 const loading = ref(false);
 const formRef = ref<FormInstance>();
@@ -359,7 +359,72 @@ const handleSave = async () => {
   }
 };
 
-// 初始化表单数据(从接口获取已保存的数据)
+/** 解析 getTagList 记录里的 labelButtonOptionOne / Two(JSON 字符串) */
+function parseLabelButtonOptions(jsonStr: unknown): Array<{ name: string; value: string | number }> {
+  if (jsonStr == null || jsonStr === "") return [];
+  if (typeof jsonStr !== "string") return [];
+  try {
+    const arr = JSON.parse(jsonStr);
+    if (!Array.isArray(arr)) return [];
+    return arr.map((o: any) => ({
+      name: o?.name ?? "",
+      value: o?.value ?? ""
+    }));
+  } catch {
+    return [];
+  }
+}
+
+const FORM_BUTTON_TYPES = ["radioDouble", "radio", "radios", "checkbox"] as const;
+
+/** 将 getTagList 单条 record 转为模板使用的 list 项 */
+function mapTagListRecordToItem(raw: Record<string, any>) {
+  const bt = raw.labelButtonType;
+  const labelButtonType = (FORM_BUTTON_TYPES as readonly string[]).includes(bt) ? bt : "radio";
+  const opt2 = parseLabelButtonOptions(raw.labelButtonOptionTwo);
+  const item: {
+    label: string;
+    labelButtonType: (typeof FORM_BUTTON_TYPES)[number];
+    field_1: string;
+    field_2?: string;
+    field_5?: string;
+    field_7?: string;
+    field_11?: string;
+    tips?: string;
+    labelButtonOption_1: Array<{ name: string; value: string | number }>;
+    labelButtonOption_2?: Array<{ name: string; value: string | number }>;
+  } = {
+    label: raw.label ?? "",
+    labelButtonType: labelButtonType as (typeof FORM_BUTTON_TYPES)[number],
+    field_1: raw.field_1 ?? "",
+    tips: raw.labelDescribe || "",
+    labelButtonOption_1: parseLabelButtonOptions(raw.labelButtonOptionOne)
+  };
+  if (raw.field_2) item.field_2 = raw.field_2;
+  if (opt2.length) item.labelButtonOption_2 = opt2;
+  return item;
+}
+
+/** 根据 getTagList 分页 data 构建 tagGroups(左:基础设施 / 右:门店介绍) */
+function buildTagGroupsFromListPageData(data: Record<string, any> | null | undefined) {
+  const records = Array.isArray(data?.records) ? [...data!.records] : [];
+  records.sort((a: any, b: any) => (Number(a?.tagSort) || 0) - (Number(b?.tagSort) || 0));
+  const infraList: ReturnType<typeof mapTagListRecordToItem>[] = [];
+  const introList: ReturnType<typeof mapTagListRecordToItem>[] = [];
+  for (const r of records) {
+    if (!r || typeof r !== "object") continue;
+    const item = mapTagListRecordToItem(r as Record<string, any>);
+    const lt = (r as Record<string, any>).labelType;
+    if (lt === "infrastructure") infraList.push(item);
+    else if (lt === "storeIntroduction") introList.push(item);
+  }
+  const groups: typeof tagGroups.value = [];
+  if (infraList.length) groups.push({ labelName: "基础设施", list: infraList });
+  if (introList.length) groups.push({ labelName: "门店介绍", list: introList });
+  return groups;
+}
+
+// 初始化表单数据(门店已选值:与标签定义分离,仍走原门店关系接口)
 const initFormData = async () => {
   try {
     const userInfo: any = localGet("geeker-user")?.userInfo || {};
@@ -369,12 +434,9 @@ const initFormData = async () => {
       return;
     }
 
-    // 调用获取门店标签数据接口 getAllTag API
     const res: any = await getAllTag({ storeId: Number(storeId) });
     if (res && (res.code === 200 || res.code === "200") && res.data) {
-      // 将接口返回的数据合并到formData中
       Object.assign(formData, res.data);
-      // 处理checkbox类型的数据(如果是字符串,需要转换为数组)
       tagGroups.value.forEach(group => {
         group.list.forEach(item => {
           if (item.labelButtonType === "checkbox" && item.field_1) {
@@ -383,11 +445,9 @@ const initFormData = async () => {
             if (value && typeof value === "string") {
               formData[fieldName] = value.split(",").filter(Boolean);
             } else if (!value) {
-              // 如果字段不存在,初始化为空数组
               formData[fieldName] = [];
             }
           } else if (item.field_1 && formData[item.field_1] === undefined) {
-            // 其他类型字段如果不存在,初始化为空值
             formData[item.field_1] = "";
           }
         });
@@ -398,50 +458,24 @@ const initFormData = async () => {
   }
 };
 
-// 初始化标签选项(从接口获取标签列表)
+// 初始化标签结构(渲染用):来自 getTagList 的 records
 const initTagOptions = async () => {
   try {
-    // 从userInfo中获取businessSection
-    const userInfo: any = localGet("geeker-user")?.userInfo || {};
-    const businessSection = userInfo.businessSection || localGet("businessSection") || "";
-
-    if (!businessSection) {
-      console.warn("未找到businessSection参数");
+    const first: any = await getTagList({ pageNum: 1, pageSize: 1 });
+    if (!(first && (first.code === 200 || first.code === "200") && first.data)) {
       return;
     }
-
-    // 调用获取标签列表接口 getAllTagType API
-    const res: any = await getAllTagType({ businessSection });
-    if (res && (res.code === 200 || res.code === "200") && res.data) {
-      const dataList = Array.isArray(res.data) ? res.data : [];
-
-      // 处理checkbox类型的已选状态
-      dataList.forEach((item: any) => {
-        if (item.labelButtonType === "checkbox") {
-          item.labelButtonOption_1.forEach((option: any) => {
-            if (formData[item.field_1] && formData[item.field_1].indexOf(option.value) !== -1) {
-              option.isChecked = true;
-            }
-          });
-        }
-      });
-
-      // 按labelName分组
-      const grouped = dataList.reduce((acc: any[], current: any) => {
-        const existing = acc.find(item => item.labelName === current.labelName);
-        if (existing) {
-          existing.list.push(current);
-        } else {
-          acc.push({
-            labelName: current.labelName,
-            list: [current]
-          });
-        }
-        return acc;
-      }, []);
-
-      tagGroups.value = grouped;
+    const recLen = first.data.records?.length ?? 0;
+    const apiTotal = Number(first.data.total);
+    const targetSize = Number.isFinite(apiTotal) && apiTotal > 0 ? Math.min(apiTotal, 500) : Math.min(Math.max(recLen, 1), 500);
+    let pageData = first.data;
+    if (targetSize > recLen) {
+      const full: any = await getTagList({ pageNum: 1, pageSize: targetSize });
+      if (full && (full.code === 200 || full.code === "200") && full.data) {
+        pageData = full.data;
+      }
     }
+    tagGroups.value = buildTagGroupsFromListPageData(pageData);
   } catch (error) {
     console.error("获取标签列表失败:", error);
   }

+ 4 - 4
src/views/ticketManagement/index.vue

@@ -240,10 +240,10 @@ const voucherColumns = reactive<ColumnProps<any>[]>([
     }
   },
   {
-    prop: "endDate",
+    prop: "validDate",
     label: "结束时间",
     render: (scope: any) => {
-      return scope.row.endDate?.replace(/-/g, "/") || "--";
+      return scope.row.validDate?.replace(/-/g, "/") || "--";
     }
   },
   {
@@ -279,10 +279,10 @@ const couponColumns = reactive<ColumnProps<any>[]>([
     }
   },
   {
-    prop: "endGetDate",
+    prop: "validDate",
     label: "结束时间",
     render: (scope: any) => {
-      return scope.row.endGetDate?.replace(/-/g, "/") || "--";
+      return scope.row.validDate?.replace(/-/g, "/") || "--";
     }
   },
   {