Parcourir la source

feat(policy): 政策详情面板的「政策名称」支持点击跳转

由库条目的 data.市级政策id 拼出政策详情页地址:
https://zwdt.sh.gov.cn/qykj/shell_oc_policy_zq/policy/policy-detail?id=<id>

背景:库里 apply_link 字段 262 条全为空。此前考察的两个替代来源都不可用——
资源申请备注里的 URL 只有 46 条有、其中 25 条指向内网登录页
(http://10.235.238.34:7202/imanage/login),且同名政策下的 URL 是按申报事项
分别对应的、不能互借。市级政策id 则有 261/262 条,可靠。

新增 buildPolicyDetailUrl() 到 policy-library-utils.ts(纯逻辑,供验证脚本引用);
没有 id 时返回空串——不猜,宁可没有链接也不给打不开的地址。
接入 normalizePolicy 的 apply_link 兜底链(卡片自带地址优先)。

验证脚本扩到 21 项断言全通过,含真实库覆盖率断言(261/262)。

Co-Authored-By: Claude Code <noreply@anthropic.com>
gongtianxiao il y a 3 jours
Parent
commit
cd6d9b0898
3 fichiers modifiés avec 33 ajouts et 1 suppressions
  1. 6 0
      README.md
  2. 8 1
      src/components/Chat/PolicyMatch.vue
  3. 19 0
      src/components/Chat/policy-library-utils.ts

+ 6 - 0
README.md

@@ -68,3 +68,9 @@
   - 新增回归脚本 `harness/tools/verify-empty-content-agreement.mjs`,
     断言的不变量就是「两处必须一致」,30 项断言
 - 删除政策详情面板的「原文引用」板块(条件核验、匹配依据保留)
+- 政策详情面板的「政策名称」支持点击跳转:由库条目的 `data.市级政策id`
+  拼出 `https://zwdt.sh.gov.cn/qykj/shell_oc_policy_zq/policy/policy-detail?id=<id>`
+  - 背景:库里 `apply_link` 字段 262 条**全为空**;`资源申请备注` 里的 URL 是按申报事项
+    零散对应、且混有内网地址(25 条指向 `http://10.235.238.34:7202/imanage/login`),
+    不能作为来源。`市级政策id` 有 261/262 条,可靠
+  - 没有 id 时不给链接(**不猜**),宁可没有也不指向打不开的地址

+ 8 - 1
src/components/Chat/PolicyMatch.vue

@@ -459,6 +459,7 @@ import { parsePolicyTableContent } from "@/utils/stream-xml-filter";
 import { isZhaoshangLLM as isZhaoshangLLMModel } from "@/utils";
 import {
   buildLibraryNameSet,
+  buildPolicyDetailUrl,
   collectMatchedLibraryNames,
   isPolicyLibraryItem,
   pinMatchedFirst,
@@ -824,7 +825,13 @@ const normalizePolicy = (item: RawPolicyItem): PolicyItem => {
       item.date || item?.declaration_end_time ||
         (item.declaration_start_time && item.declaration_end_time) ? `${item.declaration_start_time || ""} 至 ${item.declaration_end_time || ""}` : "",
     end_date: item.declaration_end_time || item.date || item?.['申报结束时间'] || "",
-    apply_link: item.apply_link || item?.['政策原文地址'] || item.data?.['政策原文地址'] || "",
+    apply_link:
+      item.apply_link ||
+      item?.['政策原文地址'] ||
+      item.data?.['政策原文地址'] ||
+      // 库里 apply_link 全空,用「市级政策id」拼政策详情页地址(261/262 条有该 id)
+      buildPolicyDetailUrl(item) ||
+      "",
     originalData: item,
   };
 };

+ 19 - 0
src/components/Chat/policy-library-utils.ts

@@ -8,6 +8,25 @@
  * 而不是复制一份——复制会漂移,测的就不是真代码了。
  */
 
+/** 政策详情页地址前缀(一网通办·青浦惠企政策专区) */
+export const POLICY_DETAIL_URL_BASE =
+  "https://zwdt.sh.gov.cn/qykj/shell_oc_policy_zq/policy/policy-detail";
+
+/**
+ * 由库条目的「市级政策id」拼出政策详情页地址。
+ *
+ * 背景:`policies_public.v1.json` 里 `apply_link` 字段 262 条**全为空**,
+ * 而 `资源申请备注` 里的 URL 是按申报事项零散对应、且混有内网地址,不能作为主要来源。
+ * `data.市级政策id` 则有 261/262 条(40 个不同 id),是可靠来源。
+ *
+ * 没有 id 时返回空串 —— **不猜**:宁可没有链接,也不给一个打不开的地址。
+ */
+export const buildPolicyDetailUrl = (item: any): string => {
+  const id = item?.data?.["市级政策id"];
+  const value = String(id ?? "").trim();
+  return value ? `${POLICY_DETAIL_URL_BASE}?id=${encodeURIComponent(value)}` : "";
+};
+
 /** 政策名归一化:库里带《》,卡片标题不带,另有全半角括号、连接符、空白等差异 */
 export const normPolicyName = (text: unknown): string =>
   String(text || "")