| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293 |
- /**
- * 政策库的**远端(DMS 里那份)与本地副本**是否一致 —— 保证前端"远端优先"拿到的是同一份数据。
- *
- * 背景沿革:
- * 2026-09-17 这个脚本比的是「本地副本 vs 厂商远端(VITE_DOWNLOAD_URL)」,用来判断
- * 「开发环境本地优先」那个开关还有没有必要(当年厂商远端 327 条全都没有 `data.市级政策id`,
- * 导致政策详情点不开,所以开发环境一度本地优先)。
- * 2026-09-24 用户把政策库的远端换成 **DMS 文件服务里的那份**
- * (`node harness/tools/upload-policy-library.mjs` 上传,路径记在 `VITE_POLICY_REMOTE_URL`),
- * 顺序也固定成"先远端、取不到再用本地兜底",那个开关随之删除。
- * 于是本脚本的职责变成:**核对两边内容是否一致**(远端上传后忘了同步、或本地被换过,这里会报)。
- *
- * 怎么跑(需要 dev server 起着;远端地址从 .env.development 读,不写死在脚本里):
- * node harness/tools/check-policy-sources.mjs
- *
- * 退出码:0 = 两边一致;1 = 不一致或取不到远端(需要有人看一眼)
- */
- process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'; // dev server 是自签证书
- import { readFileSync } from 'node:fs';
- const LOCAL_PATH = 'public/merchant-agent/policies_public.v2.json';
- const ENV_PATH = '.env.development';
- /** 从 .env.development 读 VITE_POLICY_REMOTE_URL(只取路径,脚本不关心 host) */
- const readRemoteUrl = () => {
- const env = readFileSync(ENV_PATH, 'utf8');
- const line = env.split(/\r?\n/).find((l) => l.trim().startsWith('VITE_POLICY_REMOTE_URL'));
- const raw = line?.split('=').slice(1).join('=').trim().replace(/^["']|["']$/g, '');
- return raw;
- };
- const toList = (json) => (Array.isArray(json) ? json : json?.data) || [];
- const nameOf = (item) => String(item?.['政策名称'] ?? item?.name ?? '').trim();
- const deptOf = (item) => String(item?.['政策所属部门'] ?? item?.department ?? '').trim();
- const localList = toList(JSON.parse(readFileSync(LOCAL_PATH, 'utf8')));
- const remoteUrl = readRemoteUrl();
- console.log('本地 ' + LOCAL_PATH);
- console.log(' 条数: ' + localList.length + ' | 政策名去重: ' + new Set(localList.map(nameOf)).size + ' 个');
- let remoteList = [];
- let remoteError = '';
- console.log('\n远端 ' + (remoteUrl || '(未在 ' + ENV_PATH + ' 找到 VITE_POLICY_REMOTE_URL)'));
- if (remoteUrl) {
- // 环境变量里存的是同源相对路径(dev 由 vite 代理),脚本里补上 dev server 的 origin 再取
- const absolute = /^https?:\/\//.test(remoteUrl) ? remoteUrl : 'https://localhost:8083' + remoteUrl;
- try {
- const res = await fetch(absolute);
- const text = await res.text();
- if (!res.ok) throw new Error('HTTP ' + res.status);
- remoteList = toList(JSON.parse(text));
- console.log(' 条数: ' + remoteList.length + ' | 政策名去重: ' + new Set(remoteList.map(nameOf)).size + ' 个');
- } catch (err) {
- remoteError = err instanceof Error ? err.message : String(err);
- console.log(' 拉取失败: ' + remoteError);
- }
- }
- console.log('\n结论:');
- let exitCode = 0;
- if (!remoteUrl) {
- console.log(' ⚠️ 没有配 VITE_POLICY_REMOTE_URL —— 前端会走本地兜底(功能可用,但没有"远端优先"了)');
- exitCode = 1;
- } else if (remoteError) {
- console.log(' ⚠️ 远端取不到(' + remoteError + ')—— 前端会退回本地副本;检查 DMS/代理是否正常');
- exitCode = 1;
- } else if (localList.length !== remoteList.length) {
- console.log(' ⚠️ 两边条数不同(本地 ' + localList.length + ' / 远端 ' + remoteList.length + ')');
- const localNames = new Set(localList.map(nameOf));
- const remoteNames = new Set(remoteList.map(nameOf));
- console.log(' 仅远端有的政策名 ' + [...remoteNames].filter((n) => !localNames.has(n)).length + ' 个,' +
- '仅本地有的 ' + [...localNames].filter((n) => !remoteNames.has(n)).length + ' 个');
- exitCode = 1;
- } else {
- const localDepts = [...new Set(localList.map(deptOf))].sort().join('、');
- const remoteDepts = [...new Set(remoteList.map(deptOf))].sort().join('、');
- if (localDepts !== remoteDepts) {
- console.log(' ⚠️ 部门取值不同:本地 ' + localDepts + ' / 远端 ' + remoteDepts);
- exitCode = 1;
- } else {
- console.log(' ✅ 远端与本地内容一致(' + localList.length + ' 条,部门 ' +
- [...new Set(localList.map(deptOf))].filter(Boolean).length + ' 个)—— 远端优先拿到的就是这份');
- }
- }
- if (exitCode && remoteList.length && localList.length === remoteList.length) {
- console.log(' (内容有差异时:重新上传本地这份即可 —— node harness/tools/upload-policy-library.mjs)');
- }
- process.exit(exitCode);
|