current-api-call-sites.md 24 KB

接口清点(在用 / 死代码)

核对时间:2026-09-24(用户要求「查看当前项目的接口情况,列出来我来判断哪些可以删」) 核对方法:全仓库 grep 网络调用点(fetch / WebSocket / EventSource)+ 逐个数 VITE_* 环境变量的引用数 → 逐个反查调用方。复核命令见文末。

下面 §0 是一张全量表(含"建议"列);§一/§二 是旧版按功能写的细节,仍有效,保留。

0. 全量接口清单(2026-09-24)

A. 在用(核心链路,别删)

# 接口 用途 调用点
1 POST {VITE_CHAT_API}/api/chat(SSE) 对话主链路 src/components/api-chat-coordinator.ts
2 POST {同一后端}/api/company/classify 企业多标签分类 src/network/api/company-classification.ts
3 {VITE_DMS_API}/content/* DMS 读写(1886/1887/1888/1889 会话·问答·反馈·企业信息)。2026-09-29 起 token 由前端自己带(未登录访客用服务账号现换,见 #17) src/network/api/dms/client.ts
4 POST {VITE_DMS_API}/file/uploadFile 附件上传到 DMS 文件服务 src/network/api/dms/file-upload.ts
5 GET {VITE_NLS_TOKEN_API}(→ http://121.43.55.7:10011/proxy/verify/getALYToken) 语音识别的 token(后端网关签发) src/network/api/nls-token.ts
6 wss://nls-gateway-cn-shanghai.aliyuncs.com/ws/v1 实时语音识别(阿里云 NLS) src/asr/nls.ts
7 GET {VITE_IP_API}/proxy/verify/getIPByBrowser(→ 同上 10011) 取本机 IP(DMS 访客归属) src/utils/client-ip.ts
8 POST {VITE_API}/enterprise/login、GET {VITE_API}/fta_ent_policy/enterprise_info 企业登录换码 / 拉企业信息(老接口) src/network/api/enterprise.ts
9 GET {VITE_POLICY_REMOTE_URL}(= /dms/static/file/1889-c_question-83859739-….json) 惠企政策库:先取 DMS 里的那份,取不到再用本地副本(/merchant-agent/policies_public.v2.json)。原厂商 VITE_DOWNLOAD_URL 与 VITE_POLICY_LOCAL_FIRST 开关已随本次改动删除(2026-09-24 用户要求) index.html + Chat/PolicyMatch.vue
10 GET {VITE_MODEL_SERVER}/v1/policies?… ✅ 2026-09-28 已删(政策列表的"第三档":库与卡片都为空才走到,实测从未触发)——连带删掉 4 个 helper 与两份 env 的 VITE_MODEL_SERVER —
11 GET <后端在正文里给的 link> ✅ 2026-09-28 已删(「政策列表(更新版)」:旧协议正文里 <policy-list-updated>{link,payload}</policy-list-updated> 给出地址、前端照着取 json)。与 #10 是同一个接口,只是地址由后端下发;用户同日确认「老对话仅测试、后续会全部清空」→ 唯一的触发源消失,组件与标签规则一并删除(见 legacy-content-markers.md) —
12 postMessage(…, VITE_PARENT_ORIGIN) 与父页面通信(嵌 iframe 场景) index.html
13 VITE_REDIRECT_MAP 跳转映射页(纯本地,不发请求) redirect.html
14 GET https://hm.baidu.com/hm.js?d6307cb… ✅ 2026-09-28 已删(百度统计第三方脚本)。理由:数据进的是厂商账号(站点配置 dm:["demo.heijingai.com"])、本项目从未用过它的数据(git log -S '_hmt.push' 全历史为空)、且它是全站唯一往第三方发请求、并在青浦域名上写 cookie 的东西 —— 用户当日确认「删掉」 —
15 GET https://zwdt.sh.gov.cn/qykj/…/policy-detail?id=<市级政策id> 政策详情页(外部导航,target=_blank,不是接口) Chat/policy-library-utils.ts 的 buildPolicyDetailUrl
16 https://zwdtuser.sh.gov.cn/uc/login/login.jsp?redirect_uri=… 企业登录(外部导航,跳一网通办,登录后经 redirect.html 回来) components/useEnterpriseAuth.ts 的 redirectToLogin
17 POST {VITE_OAUTH_LOGIN_URL}(= /oauth/api/user/login → 121.43.55.7:10086) 未登录访客换 DMS token(前端用内置服务账号换,2026-09-29 起) src/network/api/dms/service-token.ts

📌 2026-09-28 按代码重核时补的三条(此前清单漏记,复核方法见 §四):

  • #14 百度统计(已删,原始排查记录留在这里备查):它是唯一会加载第三方脚本、 把页面访问数据发给外部服务的东西,且没有环境开关(index.html 底部无条件插入,dev 也一样发请求)。 它和 2026-09-18 删掉的自家「使用统计埋点」不是一回事,之前清点时漏了。
    • 删除时间/范围:2026-09-28 用户确认删;index.html 里那 9 行整块移除(原位留一条 [已删] 说明), 全仓库无其它引用。复核:grep -rn 'hm\.baidu\|_hmt' 只剩注释;产物里也只剩注释。
    • 站点 id d6307cb011c91628ce6be043f40d510a 抓下来的 hm.js 里写着 dm:["demo.heijingai.com"](厂商演示站的域名,不是青浦的域), etrk/cetrk/cptrk/ctrk 全空 ⇒ 没有配置任何事件/转化跟踪,只有默认 PV/UV; 数据进的是那个厂商账号。
    • 2026-09-28 用 jsdom 实测三个域(拦了 img/xhr/sendBeacon、不真发请求): aixq.shqp.gov.cn / demo.heijingai.com / localhost 都会写 cookie (Hm_lvt_<id> / Hm_lpvt_<id> / HMACCOUNT,写在当前域上)并尝试上报 https://hm.baidu.com/hm.gif?hca=…&cl=24-bit&ds=…&vl=… ⇒ dm 白名单不阻止客户端上报(若有校验也在服务端,未验证)。
    • 脚本 CDN 有个观察:请求不带 Referer 时返回 0 字节(curl 实测两次),带 Referer 才给 ~30 KB。
  • #15 / #16 是浏览器导航、不是 XHR:前者由政策库条目的 data.市级政策id 拼出(261/262 有该字段, 见 policy-library-utils.ts);后者是把当前地址交给一网通办做 redirect_uri, 所以 redirect.html 必须是一个能直接打开的静态页(见 §一 的说明)。
  • ⚠️ VITE_DOWNLOAD_URL 是死配置 → ✅ 2026-09-28 已删:它只定义在 .env.production, 全仓库没有任何读者(index.html 的本地兜底早写死 /merchant-agent/policies_public.v2.json)。 现在两份 env 都没有它,生产侧 nginx 也不再需要转发 /api/download/。 护栏:harness/tools/verify-policy-library.mjs §10(变异测试:放回去立刻变红)

📌 2026-09-24 的两处更正(都因为只 grep src/ 会误判): ① VITE_APP_KEY 曾被我写成"死配置",其实 index.html 的 openid_to_token 在用 —— 后来那条 openid 引导链整段删除(两个环境都走不到,见 §6),VITE_APP_KEY 随之删除; ② VITE_USE_KNOWLEDGE_API 当时也不是死配置 —— index.html 在用它切「政策解读」卡片; 但那段的产物(硬编码 cardInfo)全仓库无读者、document.title 上面已设过 → 2026-09-28 连同 globalThis.isKnowledgeApi / globalThis.modelServer / cardURL 一起删除。

B. 已停用 / 死代码 —— ✅ 2026-09-24 已按用户要求全部删除

删除清单与验证见 progress.md 续 37。删掉的东西(想看旧实现翻 git 历史): 厂商 OSS 上传(含 VITE_UPLOAD_SIGN_URL)· 旧厂商 ASR(three-libs/asr/index.ts + VITE_ASR

  • VITE_XF_ASR + vite /asr/ 代理 + index.html 的 globalThis.isXF)· stream-message-coordinator.ts 整个类(MessageState 枚举已搬到 src/types/record.ts)· utils/scope-stream-boundary.ts · updateSessionInfo · getModelServerUrl / isKnowledgeApi · 三个空目录 · syncSessionTitleToServer 注释块 · 变成孤儿的 npm 依赖 qs / @microsoft/fetch-event-source(components/utils.ts 一度被误删,因为 ScrollList.vue / BusinessRecord.vue 直接用它导出的 sleep / getQueryObj / computedOriginContentPosition,已恢复)。
原清单(2026-09-24 早些时候列的,留作对照) | # | 东西 | 现状 | 删了会怎样 | |---|---|---|---| | 14 | 厂商 OSS 上传:`POST {VITE_UPLOAD_SIGN_URL}` + 直传 host | 已被 DMS 文件服务取代;实现整段**块注释**保留,`VITE_UPLOAD_SIGN_URL` 仍在四份 env 里 | 只会失去"翻旧实现"的便利;`uploadDmsAttachment` 不受影响 | | 15 | 旧厂商 ASR:`wss://{VITE_ASR host}/common/asr_hub`、讯飞分支 `VITE_XF_ASR` + vite `/asr/` 代理 | 已被 NLS 取代;`src/three-libs/asr/index.ts` 保留 | **删了就不能"一键切回"**(那正是当初保留它的理由) | | 16 | `stream-message-coordinator.ts` 整个类(含 `TTSURL=//llm-api.test.metamaker.cn/knowledge/tts`、老 SSE 地址、`{VITE_MODEL_SERVER}/v1/chat/completions`、`CensorURL`) | **没有任何活引用**;只有 `MessageState` 枚举被 `BusinessRecord.vue` / `types/record.ts` 引用 | 需要先把 `MessageState` 挪到别处(枚举本身**不能删**) | | 17 | `updateSessionInfo()`(1887 标题同步的包装) | 已停用,只有注释引用 | 无 | | 18 | `getModelServerUrl()` / `isKnowledgeApi()`(`utils/runtime-config.ts`) | 无活调用点(后者只被 #16 用) | 无 | | 19 | 空目录:`src/three-libs/metamaker`(0 文件)、`global`、`cache`、`assets` | 空壳 | 无 | | 20 | `syncSessionTitleToServer()` | 已停用(注释保留) | 无 |

C. 已经删干净的(只作提示,不用动)

  • 使用统计埋点(assistant-statistics.ts + VITE_ASSISTANT_STATISTICS_BASE_URL,2026-09-18 删)
  • 数字人视频流:/stream/ 代理 + VITE_STREAM_SERVER / VITE_STREAM_TOKEN / VITE_HUMAN_IDLE_MP4_URL (只剩 vite.config.ts 里一条说明注释)
  • dev 期自签 NLS token 的 /nls-token/ 中间件(2026-09-24 被网关端点取代)

D. 仍在用、别误删的环境变量

VITE_API(#8 企业登录在用)· VITE_CHAT_API · VITE_DMS_API · VITE_IP_API · VITE_NLS_TOKEN_API · VITE_NLS_APPKEY(2026-09-28 起已内置进代码,本变量只作可选覆盖) · VITE_POLICY_REMOTE_URL(政策库远端,2026-09-24 新增) · VITE_PARENT_ORIGIN · VITE_REDIRECT_MAP(redirect.html 用)· VITE_VERSION · VITE_OAUTH_LOGIN_URL(#17 换 token 用,2026-09-29 新增)。 (原有的四个 *_TARGET 已于 2026-09-29 删除 —— 代理 target 直接写在 vite.config.ts 里,见下。)

📌 同源前缀(2026-09-29 统一):/oauth/** → 10086(直通)· /dms/** → 10081(直通 + 注入 token)· /api/** → 10011(剥前缀;语音 token 与取 IP 共用)· /chat-api/** → 聊天后端(剥前缀)。 注意 /api 这条不是 #8 的企业登录网关(那个走 VITE_API 的绝对地址)。 已删:VITE_ASR / VITE_XF_ASR(随旧 ASR)、VITE_APP_KEY(随 §6 的 openid 链)、 VITE_MODEL_SERVER(随 #10 的第三条腿)、VITE_USE_KNOWLEDGE_API(随 index.html 那段死枝, 见 #6)—— 两者都是 2026-09-28 删的。

环境只剩两份(2026-09-24 用户要求):.env.development + .env.development.local(本机凭据, gitignored)+ .env.production。qingpu / test 两个模式已删除,脚本也随之调整 (npm run build 出生产包,npm run zip 打部署 zip,npm run deploy:qingpu = 两者串起来)。

一、已经迁到新接口的(不用管)

⚠️ 下面这段是 2026-09-17 的版本 + 后续更正,细节仍有效;未完成/待删的项以 §0 为准。

老接口 = {VITE_API}(//qingpu-data-api.metamaker.cn)。

功能 接口 备注
对话(SSE) POST {VITE_CHAT_API}/api/chat
问答记录(历史)写入 + 读取 DMS 栏目 1889 一问一答一条;title = 问题文本
点赞/点踩/取消 DMS 1889 的 c_feedback_*
删除会话 DMS(清 1889 记录 + 1887 旧行)
政策卡片与协议内容 随 /api/chat 下发
惠企政策库数据 静态 json policies_public.v2.json(2026-09-24:170 条、中文键;远端换成 DMS 文件服务里的那份,取不到退回打包进 dist 的本地副本)

⚠️ 1887 助手会话的写入范围(2026-09-23 时的准)

  • 仍然写,但只有一处:回答正常完成(totalResponse)时写一次,见 useBusinessAssistantChat.ts 的 void upsertDmsSession(...);有源码级断言钉着「活跃调用点只有 1 处、且在 totalResponse 内」 (verify-dms-payload-fields.mjs 第 4 节)。中断/报错的轮次不写。
  • 新建会话、改名不再同步(2026-09-18 的决定只废了这两条),所以前端会话列表仍是纯本地为主, 登录后另按 c_credit_code 拉远端会话合并(读侧会排除 c_is_login="0" 的访客行)。
  • 建行策略:2026-09-18 曾是「访客且本轮没有企业信息就不建行」,2026-09-23 由用户推翻—— 只要对话就建行;那种情况下行里放 c_ip / c_is_login="0" / 时间戳 / 标题与四个必填运营位, c_credit_code 留空(不写访客标签)。
  • 停用的调用点(updateSessionInfo / syncSessionTitleToServer)按约定注释保留在 useBusinessAssistantChat.ts。

二、还在用老接口的功能

1. 企业身份识别(登录 + 拉企业信息)—— 在用,且牵连最广

用户看到什么:右上角账号区。未登录显示「青浦区区内企业登录」(可点,跳一网通办), 登录后显示企业名 + 首字母头像 + 退出登录,还会飘一个气泡「识别到您为我们区内企业,推荐登录」。

怎么走到老接口: | 入口 | 接口 | |---|---| | 从一网通办带 ?access_token= 跳回来 | POST /enterprise/login 换 credit_code + authToken | | 带 ?credit_code= 跳回来 | GET /fta_ent_policy/enterprise_info 直接拉企业信息 |

这个身份一共被 5 处依赖(所以它不只是"显示个名字"):

  1. 账号区显示企业名与头像
  2. 判断"是否登录"(isEnterpriseLoggedIn)
  3. 历史数据分家:登录 → ba_chat_history;访客 → ba_temp_chat_history
  4. 会话列表:登录后按 credit_code 拉远端会话(现走 DMS)
  5. DMS 记录归属:c_credit_code = 企业信用代码,未登录则 访客_<访客id>

⚠️ 前端只用企业信息的 name 与 credit_code 两个字段(其余 19 个字段零引用)—— 所以真要用 DMS 的企业信息(栏目 1888)替换它,成本很低。

2. 使用统计(页面浏览 / 回答反馈) —— 已删除(2026-09-18)

用户要求删掉统计埋点的老接口。已删除:

  • 调用点:BusinessAssistant.vue(页面浏览)、BusinessRecord.vue(反馈统计)
  • 整个模块 src/network/api/assistant-statistics.ts(连同 VITE_ASSISTANT_STATISTICS_BASE_URL 这个已无人用的 env)
  • ⚠️ 只留下了访客 id 的读写(getOrCreateAssistantVisitorId),因为 DMS 记录访客归属 (访客_<id>)在用它 —— 已搬进 src/network/api/dms/chat-sessions-dms.ts。 localStorage 的 key 字符串保持原样(assistant_statistics_visitor_id): 改了会让已存在的访客全部换新 id,同一浏览器在 DMS 里就变成两个访客了。
  • 现在点赞只写 DMS(原先双写)

3. 语音输入 —— 在用 2026-09-23 起换成阿里云 NLS,见 asr-nls.md

下面这段是换之前的实现记录(厂商 asr_hub 中转)。旧实现代码仍在 src/three-libs/asr/index.ts(切回去的退路) —— 该文件已于 2026-09-24 删除 (连同 three-libs/ 目录),本节只是历史记录;它已不在链路上。

  • 触发:点输入框的麦克风 实际只依赖 1 个接口:

    wss://qingpu-data-api.metamaker.cn/common/asr_hub
    ?project=qingpu&engine=aliyun_dashscope&is_long_connection=true&heartbeat=true
    (移动端多一个 &max_sentence_silence=5000)
    
  • host 取自 VITE_ASR;引擎是 aliyun_dashscope(阿里云百炼),不是讯飞

  • 鉴权不需要调接口:token 硬编码在 asr/index.ts(已删) 里 (JWT iss: human-large-screen,exp 2034-12-29)—— 所以 ASR 没有 DMS 那种每天换 token 的问题

  • 调用方还硬编码传了一个 appKey(new ASR("<key>", {audio:true,video:false})), 但它在当前分支用不到(只在讯飞分支的 gen_auth 里用)

未启用的讯飞分支(index.html 硬编码 globalThis.isXF = false,走不到):

POST {VITE_XF_ASR}/api/human_asr/v2/asr/gen_auth     取鉴权
wss://{VITE_XF_ASR}/api/human_asr/v2/asr?Authorization=...

与对话协议无关,历次迁移没碰它。

📋 ASR 协议契约(从 asr/index.ts(已删) 反推,供「换成自建服务」时照做)

连接:wss://<host>/common/asr_hub?project=qingpu&engine=aliyun_dashscope&is_long_connection=true&heartbeat=true

步骤 内容
1. 握手 客户端发一帧 JSON 文本:{"card_id": <id>}(注意:不是上面 XF 分支那套 business/data 参数)
2. 上行 二进制帧,裸 PCM:格式声明为 audio/L16;rate=16000、encoding: raw,按 CHUNK_LENGTH 切片、CHECK_INTERVAL 定时发(new Int8Array(data) 直接 send)
3. 下行 JSON:{"data": {"result": {…}}},关键字段 text(识别文本)、pgs("apd" 等分段标识)、command("start" / "stop")、is_sentence、is_quit、ls、ws
4. 收尾 非讯飞分支用 {"command": "close"};讯飞分支用 {"data": {"status": 2}}

要实现自建网关,照这张表实现即可——前端不用改,只要把 VITE_ASR 指向新地址。 引擎侧可以接你自己的阿里云百炼 / 讯飞 / 本地模型。

4. 图片 / 附件上传 —— 用户触发不到(入口被注释)

  • 原设计:输入框的上传按钮(图片、pdf/doc/xlsx 等)→ POST /common/qp_signed_url 取 OSS 签名 → 直传 OSS
  • 现状:新协议 /api/chat 只收 {thread_id, question},附件传不上去, 上传入口整块被注释(BusinessAssistantMobileInputShell.vue 里有说明)
  • 但代码与 OSS 地址仍活着(地址还是硬编码在 useBusinessAssistantUpload.ts 里的), 等后端定了附件契约才能接上

5. 政策事项列表的「远端查询」 —— ✅ 2026-09-28 已删

  • 原设计:列表数据本地都没有时,去模型服务查 {VITE_MODEL_SERVER}/v1/policies
  • 现状:fetchPolicyList 里前面两档(惠企政策库 / 本轮卡片兜底)几乎总能命中, 第三档基本走不到 —— 用户 2026-09-28 要求「不再依赖原来的政策相关接口」→ 整条删除 (连带 policy-match-utils.ts 的 4 个 helper 与两份 env 的 VITE_MODEL_SERVER)
  • ⚠️ 注意 #11 也同日删了:后端在正文里下发的 <policy-list-updated> 给的也是这个接口的地址, 它一度仍在用、由 PolicyListUpdatedMatch.vue 按 link 取;同日晚些时候用户确认 「老对话仅测试、后续会全部清空」→ 那条也删掉了。现在前端没有任何"后端给地址再去取"的路径。

6. openid 换 token —— ✅ 2026-09-24 已删除

用户要求「判断删除后是否会对现用功能造成影响,没有影响就删掉」。评估结论:无影响 —— 它挂在 if (isKnowledgeApi) {…} else { initToken(); } 的 else 上,而两个环境都是 VITE_USE_KNOWLEDGE_API=true;产物 globalThis.token / cardInfo 全仓库无读者; 那段本身还是坏的(调用从未挂到 globalThis 的 changeLoadingText / showReloadView)。 删除范围:initToken / initCardInfo / else 分支 + randomString / changeLoadingText / showReloadView + VITE_APP_KEY。详见 progress.md 续 39/40。

6b. 附件上传 —— 已改走 DMS 文件服务(2026-09-23)

  • 现在:POST {VITE_DMS_API}/file/uploadFile(→ http://121.43.55.7:10081/dms/file/uploadFile, 经 /dms 代理)。multipart/form-data,五个字段都必填: file / type(0 图·1 音·2 视·3 文件)/ columnId(1889) / contentId(0) / paraName(c_question)。 返回 {"code":200,"content":"/static/photo/1889-c_question-<uuid>.png"} —— 相对路径, 它随聊天请求体的 pictures / files 发给后端(见 api-chat.md 的多模态节)
    • 缩略图预览:相对路径本身取不到,要拼代理前缀 → {VITE_DMS_API}/static/photo/… 实测 200(buildDmsFileDisplayUrl() 干这个)
    • 验证脚本:harness/tools/verify-dms-file-upload.mjs
  • [已停用] 原路:厂商 metamaker 的 OSS 直传 —— POST {VITE_UPLOAD_SIGN_URL}/common/qp_signed_url 取签名 → 直传 OSS → 得到绝对地址。2026-09-23 用户要求改用 DMS 存储,代码整段注释保留 (useBusinessAssistantUpload.ts),VITE_UPLOAD_SIGN_URL 这个 env 也一并未用

7. 取本机 IP(DMS 访客归属用)—— 在用(2026-09-22 新增)

  • 触发:应用启动时预热一次(main.ts),写 DMS 前会 await 一次(内部缓存 + 并发去重)
  • 接口:GET {VITE_IP_API}/proxy/verify/getIPByBrowser → 纯文本 IP (响应头 Content-Type 标的是 application/json,但正文就是裸 IP —— 按 text 读,别 JSON.parse)
  • 必须走同源代理:接口是 http://121.43.55.7:10011,页面是 HTTPS —— 接口带 Access-Control-Allow-Origin: *(跨域没问题),但混合内容会被浏览器拦掉。 dev 见 vite.config.ts 的 /api/;生产需要 nginx 把 /api/ 转发到 http://121.43.55.7:10011/(去掉前缀)
  • 用途:DMS 1887 的 c_ip 存这个 IP;访客身份(1889 的 c_credit_code)用 访客_<IP>
  • 拿不到 IP 不致命:退回 访客_<浏览器随机 id>,只是归属不稳定(见 src/utils/client-ip.ts)

三、已经没有人调用的(死代码,只标注未删)

位置 原本支撑的功能 处置
src/network/api/card/index.js(getMediaList / giveFeedback / appendHistory) 卡片媒体信息、点赞点踩的旧接口版落库、追加服务端历史 ✅ 2026-09-18 整文件删除(连同 useBusinessAssistantChat.ts 里那个未使用的 import cardAPI)
src/network/api/assistant-statistics.ts 使用统计埋点 ✅ 2026-09-18 整文件删除(访客 id 那部分已搬进 DMS 模块,见第二节)
PolicyListUpdatedMatch.vue 旧协议 <policy-list-updated> 卡片列表 ✅ 2026-09-28 已删 —— 它一度被"有意保留"(对旧历史仍有效),但用户当日确认「老对话仅测试、后续会全部清空」,保留理由消失。连带删除:BusinessRecord 的挂载点/import、StreamXMLFilter 的枚举成员与标签规则。副作用:清空前打开旧测试会话会看到那串原始 JSON 文本(用户已确认接受)

删除的代码都在 git 历史里(git log --diff-filter=D --name-only 可查)。 上一条曾是「保留」——现在已删;其余旧协议标记的存活情况见 legacy-content-markers.md(只读清单,未动代码)。

四、复核方法(可重跑)

# 1. 列出所有网络调用点
grep -rn "fetch(\|new WebSocket\|new EventSource\|axios" src/ index.html \
  --include=*.ts --include=*.vue --include=*.js --include=*.html

# 2. 对每个点反查调用方(以 card/index.js 为例)
grep -rn "getMediaList\|giveFeedback\|appendHistory\|network/api/card" src/ \
  --include=*.ts --include=*.vue --include=*.js | grep -v "^src/network/api/card/index.js"

判据:出现在第 1 步 ≠ 还在用。必须做第 2 步——没有调用方的就是死代码。 第二节每条的「触发条件」也是这么查的(例如第 5 条要看 fetchPolicyList 前面两档 return 才能判断它几乎走不到)。