# 平台助手 — 项目交接文档 **交接日期:** 2026-09-30 **交接对象:** 接手继续开发的智能体 / 开发者 **文档目标:** 让接手方无需历史对话即可完整了解项目现状、架构、业务逻辑、已知问题与待办事项,可直接开始开发。 --- ## 1. 项目是什么 **平台助手(内部代号 pingtai)** 是面向 B2B 采购场景的智能询比价工作台: - **采集**:自动抓取 3 家央企招标公告(中电建 / 新矿集团 / 中核集团),关键词+AI 双通道分类入库 - **线索管理**:线索列表 / 详情 / 星级评分 / 状态流转(待复核 → 询价中 → 协作中)/ 跟进日志 - **询价发布**:勾选线索一键发布到外部 B2B 产业平台(通过 MCP 通道调 `publish_rfq`),含发布前确认弹窗(补联系人/电话/地址)、物料清单 AI 提取、超长标题 AI 压缩 - **比价**:供应商报价 Excel/CSV 上传 → 自动解析 → 商品对齐去重 → 三种采购策略对比(集中/拆分/限 K 家)→ 采购建议报告 + CSV 导出 - **生图**:商品图片三阶段生成(图库 → Bing 搜索 → MiniMax AI 生成) - **品类库**:关键词优先 + AI 反哺的品类字典(ProductCategory) - **管理后台**:租户/用户/系统配置/计划/MCP 对接配置 **在线地址(生产):** https://direv.cloud(Nginx → Next.js 3001 / NestJS 4000) **演示账号:** `admin` / `admin123`(username + password,**不是 email**) --- ## 2. 技术栈与架构 | 层 | 技术 | 说明 | |----|------|------| | 前端 | Next.js 14 App Router + React 18 + Tailwind CSS 3 | **SPA 无路由**,useState 切换 14 个页面组件 | | 后端 | NestJS 10 + TypeScript | 13 个子模块,端口 4000 | | 数据库 | SQLite + Prisma ORM | `apps/api/prisma/dev.db`,15 个模型 | | 采集脚本 | Node.js / Python | `scripts/tender-fetcher/`,CrawlerService 用 `execSync` 调度 | | AI | MiniMax M2.7 (推理模型) | 品类分类 / 物料提取 / 标题压缩,endpoint `https://api.minimaxi.com/v1/chat/completions` | | 外部对接 | MCP (Streamable HTTP, POST) | 集成 Integration 表 → product_network B2B 平台 | | 部署 | 腾讯云 172.81.241.109 + PM2 + Nginx + certbot | `scripts/deploy.sh` 一键部署 | ### 架构图 ``` ┌─────────────────────────────┐ 浏览器(3001) ←│ Next.js 14 (pingtai-web) │ └─────────────────────────────┘ │ /api/* ┌────────▼─────────────────────┐ │ NestJS 10 (pingtai-api:4000) │ │ ├─ crawler: execSync 调脚本 │ │ ├─ lead: 评分/状态/发布 │ │ ├─ integration: MCP client │ │ └─ comparison/image/... │ └────────┬─────────┬───────────┘ │ │ SQLite(dev.db) MiniMax API │ ┌────────▼─────────────────────┐ │ MCP server (devbox:3002/8095)│ │ → product_network B2B 平台 │ └──────────────────────────────┘ ``` > ⚠️ MCP server 端口 **3002(Node)/8095(Java)** 都在 devbox 开发机上,不是本地端口。平台助手本地 web 是 **3001**、API 是 **4000**。两套 MCP server 后端数据库不同,appId/appSecret 互不通用。 --- ## 3. 目录结构 ``` 平台助手/ ├── apps/ │ ├── web/ # Next.js 14 SPA │ │ └── src/ │ │ ├── app/page.tsx # SPA 根,useState 切换页面 │ │ ├── components/ # 14 个页面 + AuthProvider/Sidebar/Providers/ErrorBoundary │ │ └── lib/apiBase.ts# API_BASE (NEXT_PUBLIC_API_URL,本地回退 localhost:4000) │ └── api/ # NestJS 10 │ ├── prisma/ │ │ ├── schema.prisma # 15 个模型 │ │ └── dev.db # SQLite │ └── src/ │ ├── admin/ audit-log/ auth/ common/ comparison/ crawler/ │ ├── image/ inquiry/ integration/ lead/ product/ product-category/ │ ├── reports/ rules/ users/ prisma/ │ └── app.module.ts / main.ts ├── packages/shared/ # 共享 TS 类型(编译型,无运行时依赖) └── scripts/ ├── tender-fetcher/ # fetch-v1.2.js(中电建) fetch-xkgroup.py(新矿) fetch-cnncecp.py(中核) ├── direv-publish/ # direv 平台发布脚本(10 个 .py,历史保留) ├── parse_products.py # Excel/CSV → JSON(比价用) ├── search_image.py / process_image.py # 生图辅助 ├── backfill_category.js / clean_category.js / reclassify_leads.js 等 # 数据维护 └── deploy.sh # 一键部署 ``` --- ## 4. 开发环境搭建 ```bash npm run setup # npm install + db:init(prisma generate → migrate → seed) npm run dev # 同时启动前端(3001)和后端(4000) npm run dev:api # 仅后端(nest start --watch,用 dist/ 编译产物) npm run dev:web # 仅前端 npm run db:init # 改 schema 后必跑 npm run db:reset # 删 db 重来 npm run build # nest build + next build npm run typecheck # tsc --noEmit 所有包(无 root tsconfig,各包独立) npm run lint npm run dev:daemon # nohup 后台启动(PID 写入 .dev-api.pid / .dev-web.pid) npm run dev:stop # kill PID 文件记录的进程 ``` **端口速查(本地):** web=3001, api=4000。⚠️ 本地 `next dev` 偶发 fallback 到 3000(3001 被 `admin_new` Vite 项目占用时),以终端实际打印为准。 ### 后端陷阱 - `nest start --watch` 用 `dist/` 编译产物:Prisma schema 变更后必须 `npm run build -w apps/api` 重建 dist 再重启,单纯 `prisma generate` 不够 - 端口 4000 残留进程:`dev:stop` 只杀 PID 文件进程,多余进程 `lsof -ti:4000 | xargs kill -9` - Prisma 变更流程:改 schema → `npm run db:init` - 后端无测试框架 ### 前端陷阱 - SPA 无路由:`page.tsx` 用 `useState` 切换,导航走 `onNavigate` prop,参数走 props - 路径别名 `@/` → `src/` - Prettier: noSemi, singleQuote, trailingComma: all, printWidth: 100 - Tailwind Token:`secondary(#0051d5)`, `border-subtle(#E2E8F0)`, `surface-container` 系 --- ## 5. 数据库模型(15 个) | 模型 | 用途 | 关键字段 | |------|------|----------| | **Lead** | 线索核心表 | title/noticeId/detailUrl/level(C-B-A)/status/star/amount/category/organization/region/regionDetail/source/contact/phone/deadline/quantity/unit/notes/aiScore/scoringDetails/publish/publishTime/inquiryNo/direvUrl/assignedTo/followLogs;`@@unique([source, noticeId])` 去重键 | | **Rule** | 规则中心 | name/type/config(JSON)/enabled | | **RuleVersion** | 规则版本 | ruleId/version/config/userId | | **Report** | 报表 | title/type/status/config/channels/fileUrl | | **AuditLog** | 审计日志 | action/detail/operator/ip | | **CrawlerConfig** | 采集器配置 | name/targetUrl/status/type(bid_xxx)/sourceName/scriptPath/schedule(cron)/keywords/categories(JSON品类名数组)/lastRunAt/totalRuns/successRuns/failedRuns | | **Inquiry** | 询价(历史表) | 类似 Lead,冗余保留 | | **Product** | 供应商报价条目(比价) | name/spec/unit/price/quantity/category/brand/supplier/minOrder/imageUrl | | **Tenant** | 租户 | companyName/plan/status/validUntil/platformUrl/apiKey | | **User** | 用户 | email/username/password/role/tenantId | | **GeneratedImage** | 生成图片 | productName/url/status/style/sourceHash | | **ImageLibrary** | 图库 | productName/keyword/filePath/source(baidu)/style/ratio | | **SystemConfig** | 系统配置 | key(unique)/value/group | | **Integration** | MCP 对接配置 | name/endpoint/appId/apiKey(AES-256-GCM 加密)/customerCode/status/tools/companyUserId | | **ProductCategory** | 品类字典 | name(unique)/keywords(JSON数组)/isAIGenerated | ### 种子数据(seed.ts) - 15 电缆型号 × 5 供应商 = 75 Product + 管理用户(admin/admin123) - crawlerConfig 3 条:中电建 + 新矿集团 + 中核集团(中核默认 paused) --- ## 6. API 端点总览 ### 认证 `/api/auth` | POST /api/auth/login | 登录(username+password,JWT 存 localStorage `auth`) | | GET /api/auth/profile | 当前用户 | ### 线索 `/api/leads`(核心) | GET /api/leads | 列表(query: status/level/search/star/source/category/assignedTo/timeRange + 分页) | | GET /api/leads/stats | 统计(OverviewPage 用) | | GET/PUT/DELETE /api/leads/:id | 详情/更新/删除 | | POST /api/leads/:id/to-rfq, /to-collab | 状态流转:转询价 / 转协作 | | POST /api/leads/:id/publish | **发布到 B2B 平台**,可选 body `{contactPhone?, contactName?, deliveryAddress?}` | | POST /api/leads/batch-publish | body `{ids: string[]}`,循环调 publish | | POST /api/leads/:id/follow-up (+ /:index/delete) | 跟进日志 | | POST /api/leads/:id/level | 改优先级 | | POST /api/leads/calculate-score | 重算 AI 评分 | ### 采集器 `/api/crawlers` GET/POST/PUT /api/crawlers(:id) | CRUD POST /api/crawlers/:id/run, /pause, /resume | 运行/暂停/恢复(联动 cron 注册) ### 比价 `/api/comparison` GET /api/comparison | 商品分组比价数据 POST /api/comparison/upload | multipart file+supplier 上传报价 POST /api/comparison/suggestion | 生成采购建议报告 ### 品类 `/api/categories` GET/POST/PUT/DELETE | ProductCategory CRUD(InquiryPage 筛选项动态加载) ### 其他 - `/api/products` + upload-image(商品管理) - `/api/images` generate/parse/approve/regenerate(生图) - `/api/integrations` + :id/connect/disconnect/call-tool + test(MCP 配置) - `/api/admin` tenants/users/plan-config/configs/stats(管理后台) - `/api/rules` + versions/rollback - `/api/reports` + :id/send - `/api/inquiries` / `/api/users` / `/api/audit-logs` / `/api/health` - `/api/lead-notes/extract/:leadId`(notes 提取) --- ## 7. 前端页面清单(14 个) | 页面组件 | 功能 | 数据对接状态 | |----------|------|---------------| | LoginPage | 登录 | ✅ POST /api/auth/login | | OverviewPage | 概览(统计卡片+线索列表) | ✅ Promise.all([leads/stats, leads]) | | InquiryPage | 询价列表 + 筛选/搜索/星级/批量发布 + **发布前确认弹窗** | ✅ leads + publish(含弹窗传 overrides) | | LeadDetailPage | 线索详情 + 状态流转 + 跟进日志 | ✅ leads/:id + 各流转端点 | | ComparisonPage | 比价三步向导(上传→对比→建议) | ✅ comparison 三端点 | | ProductPage | 商品管理 + 生图 | ✅ products + upload-image | | ImagePage | 图片库/生成 | ✅ images | | RuleCenterPage | 规则中心 + **采集器配置 Tab**(品类多选框) | ✅ crawlers + categories | | ReportCenterPage | 报表 | ⚠️ 纯 mock | | SystemMonitorPage | 系统监控 | ⚠️ 纯 mock | | AdminPage | 管理后台(5 子区块:租户/用户/统计/configs/计划,configs 含 MCP 对接配置) | ✅ 已实现 | | Sidebar / Providers / AuthProvider / ErrorBoundary | 框架 | — | --- ## 8. 核心业务流程 ### 8.1 采集入库(crawler.service.ts) ``` CrawlerService.run(config) ├─ type=bid_powerchina → runPowerChina(): execSync('node fetch-v1.2.js --keyword "X"') ├─ type=bid_xkgroup → runGenericScript(): execSync('python3 fetch-xkgroup.py') └─ 其他 bid_xxx → runGenericScript()(脚本名从 type 推断) ↓ results → categoryInference.batchInfer() # 品类推断(关键词匹配 → 未命中走 MiniMax) ↓ upsert 到 Lead(去重键 @@unique([source, noticeId])) ``` **关键词解析(resolveKeywords,最近重构):** 1. 优先 `config.categories`(品类名数组)→ 查 ProductCategory 表把每个品类的 keywords 展开合并 2. 兜底 `config.keywords`(旧字段,直接解析) 3. 都没有 → `['']`(抓全部) **中电建特殊处理:** 每个关键词有独立状态文件 `downloaded_.json`(不是只有一个 downloaded.json);结果从 `~/Desktop/招标公告//downloaded_.json` 读取。`~/desktop` 是 symlink → `/data/pingtai`(生产持久化)。 **公告 ID 提取坑:** `substr(summary, instr(summary, '公告ID:') + 6, 32)`(`+6` 而非 `+8`,字节/字符偏移曾出 bug)。 ### 8.2 品类分类(品类方案 C:关键词优先 + AI 反哺) ``` 采集入库/手动回填时对线索标题: 1. 关键词匹配 ProductCategory.keywords contains 标题 → 命中直接写 2. 未命中 → MiniMax API 分类 → 写品类 + 反写关键词到 ProductCategory 3. 同类标题下次直接走关键词,不再调 AI ``` - 关键文件:`product-category/category-inference.service.ts`(AI 推断+反写)、`crawler.service.ts batchInfer()`、`notes-extractor.service.ts`(PDF/HTML 提取要点) - **MiniMax 配置**:endpoint `https://api.minimaxi.com/v1/chat/completions`,model `MiniMax-M2.7`(env `MINIMAX_MODEL` 可覆盖),key 在 `apps/api/.env` 的 `MINIMAX_API_KEY` - **⚠️ M2.7 是推理模型**:max_tokens 要够(物料提取正文 2000、标题提取 800),否则输出全被 `` 吃掉;输出常混 ``、`让我分析`、`**加粗**` 等解释文字,需要清洗 - 历史经验:AI 不可全信,2026-07-01 曾批量回填 507 条,结果 AI 新建 ~25 个细分类需人工 review。决策:新数据走关键词,老数据人工 review ### 8.3 发布询价到 B2B 平台(lead.service.ts publishToDirev) ``` POST /api/leads/:id/publish { contactPhone?, contactName?, deliveryAddress? } → publishToDirev(id, overrides) 1. 组装 publishArgs(title/description/qty/notes/attachments/deadline/deliveryDate/contact...) 2. 企业级硬编码字段: inquiryParty='郑州巨变网络科技有限公司', freightFlag=1(含运费), procurementType=1(公开采购), invoiceType=2(增值税专票), quotationDemand=1(需要报价), validDays=7 ⚠️ paymentMethod 不传(传了报"企业字典找不到") ⚠️ 上述 flag 必须 int,传字符串会报错(已修复过的坑) 3. 超长标题(>50字)→ TitleCompressorService.compress() AI 压缩 → 失败硬截断兜底 4. MaterialExtractorService.extractItems() 实时提取物料清单 items 5. integrationService.executeTool('publish_rfq', publishArgs)(retries:2) 6. 成功 → 更新 lead 状态(published/inquiryNo/direvUrl);失败 → ServiceUnavailableException ``` **publishArgs 字段映射细节:** | 字段 | 来源 | 备注 | |------|------|------| | title | lead.title(>50 字先 AI 压缩) | 平台 varchar(50) 限制 | | description | lead.notes → summary → title | W31 P1 | | qty | lead.quantity \|\| 1 | | | notes | lead.notes | 商家报价时看到 | | attachments | lead.attachments(JSON) \|\| [detailUrl] | | | deadline | lead.deadline 前 10 位 | YYYY-MM-DD | | deliveryDate | deadline + 30 天 | | | contactName | overrides.contactName → lead.contact → '待补充' | 弹窗可编辑 | | contactPhone | overrides.contactPhone → lead.phone → '待补充' | 必填,弹窗补全 | | deliveryAddress | overrides.deliveryAddress → regionDetail → region | 弹窗可编辑 | | userId/enterpriseId | Integration.companyUserId | MCP connect 时获取 | ### 8.4 MCP 集成(integration.service.ts) - **协议**:Streamable HTTP(`StreamableHTTPClientTransport`),POST 方法 - **认证头**:`x-app-id` + `x-app-secret`(多租户 APIKey,替代旧 `x-api-key`),AES-256-GCM 加密存储(`ENCRYPT_KEY` in .env,32 bytes hex) - **Session 管理(已实现)**:`buildSessionAwareFetch(integrationId)` 自定义 fetch wrapper——从 initialize 响应头提取 `mcp-session-id` 缓存 → 后续请求自动注入 → disconnect/重连清理 - **charset 修复(已实现)**:wrapper 检测 content-type 缺 charset 时补 `application/json; charset=utf-8`(否则 Java 解析器中文 Content-Length 不匹配报 JSON 错误) - 17 个 MCP tool(询价5/商品4/比价4/推理4),发布调 `publish_rfq` ### 8.5 标题压缩(TitleCompressorService,新增) - 位置:`apps/api/src/lead/title-compressor.service.ts`(已注册到 LeadModule) - 逻辑:`compress(title, maxLength)`: 1. `title.length <= maxLength` 直接返回(**≤50 字不调 AI**) 2. 未配 `MINIMAX_API_KEY` → 硬截断 `title.slice(0, maxLength)` 3. 调 MiniMax,**要求 JSON 结构化输出** `{"title":"..."}`(对抗 M2.7 多变思考噪音,行级正则过滤不可靠) 4. `extractJsonTitle()` 正则提取 title 字段;解析不到 → 硬截断 5. 结果仍超长 → slice 截断兜底 - max_tokens 800(400 会被明文思考耗尽导致答案截断) - 生产验证:6 个真实标题全部压缩达标(62字→25字等) ### 8.6 比价(comparison.service.ts) ``` 上传报价 (POST upload: file+supplier) → parse_products.py 解析 Excel/CSV → Product 入库 → GET /api/comparison: 按 name.trim().toLowerCase() 分组 → 组内按 supplier 去重留最低价 → 每组算 bestPrice/bestSupplier/savings/priceSpread → POST /api/comparison/suggestion: 三种策略对比: A. 无限制拆分(每 SKU 选最低总价供应商) B. 单一供应商(Σ 全 SKU 总价排名,取第 1) C. 限制 K 家(C(n,K) 组合枚举 + 每 SKU 取组合内最低价,K=2/3/4) → recommendations 自然语言建议 + CSV 导出 ``` ### 8.7 生图(image.service.ts) 三阶段:图库(ImageLibrary) → Bing 搜索(search_image.py) → MiniMax AI 生成;`process_image.py` 去水印+裁剪+白底合成。 --- ## 9. 已知问题 / 坑(接手必读) ### 9.1 生产部署相关(⚠️ 最近出现) 1. **页面打开报"服务器内部错误" / `Failed to find Server Action`**(web 日志常见): - 根因:**本地 build 的 `.next/` 直接 rsync 到生产**,生产 `node_modules` 版本与本地不一致 → Server Action ID 对不上 → 页面交互报错 - **解决办法(AGENTS.md 明确记录)**:在生产服务器上执行 `cd /opt/pingtai/apps/web && npx next build` 重建 `.next`,再 `pm2 restart pingtai-web` - 若浏览器缓存旧 HTML 导致,提示用户强刷(Cmd+Shift+R) 2. **deploy.sh 不含 DB 迁移**:Prisma 变更部署前,需在生产 `apps/api/` 下手动 `npx prisma migrate deploy && npx prisma generate`,否则 schema 不同步 3. `pm2 restart` 默认不更新环境变量,需 `--update-env`(deploy.sh 已带) ### 9.2 数据质量(采集器只抓列表页) | 字段 | 填写率(2026-07-16 生产统计 815 条) | 说明 | |------|------|------| | contact | 0% | 采集器未访问详情页 | | phone | 0% | 同上 | | quantity | 0% | 同上 | | unit | 0% | 同上 | | notes | 0% | 同上 | 当前应对:发布前弹窗手动补全。自动化提取(类似 notes-extractor 的详情页 AI 提取)**待实现**。 ### 9.3 MiniMax / AI - M2.7 输出噪音(``、`让我分析`、`**加粗**`)——所有 AI 调用都要清洗 - 生产 `.env` 已配 `MINIMAX_API_KEY` + `MINIMAX_MODEL`;本地 `.env` 需自行配置,否则走兜底 - 若 `MAX_COMPRESS_LEN` 等常量调整,注意 PROMPT 里 `'45'` 是字符串 replace,保持一致 ### 9.4 采集器 - 中电建 state 文件 key:`systemId_招采公告`,**不要手动删除** - 新矿集团脚本偶尔 `ReadTimeout`(日志见 Python traceback),不影响页面,重跑即可 - 新增采集器通用流程:放脚本到 `tender-fetcher/`,输出 `~/Desktop/招标公告//xxx_downloaded.json`,前端新建 CrawlerConfig(type=`bid_xxx`、sourceName、scriptPath),无需改代码 - cron 用 6 字段格式(兼容 cron@4.4.0) ### 9.5 MCP / B2B 发布 - `code:10021 "未获取到用户信息"`:产业平台修复中(创建 APIKey 已关联 companyUserId,后端直接使用) - `paymentMethod` 传 "23" 报"企业字典找不到" → **不传**,后端用默认 - 字段类型必须是 int(freightFlag/procurementType/invoiceType),字符串会报错 - title 超 50 字已由 TitleCompressorService 前置处理 --- ## 10. 当前工作区状态(未提交改动,2026-09-30) > ⚠️ **接手第一件事:决定这些改动是否保留/提交/继续开发。** ### 已改文件(未 commit) | 文件 | 改动内容 | 状态 | |------|----------|------| | `apps/api/src/lead/title-compressor.service.ts` | **新文件**:标题 AI 压缩服务(JSON 结构化输出方案) | ✅ 已实现+生产实测通过 | | `apps/api/src/lead/lead.module.ts` | 注册 TitleCompressorService | ✅ | | `apps/api/src/lead/lead.service.ts` | publishToDirev 集成标题压缩(>50 字先压缩再校验) | ✅ | | `apps/api/src/crawler/crawler.service.ts` | resolveKeywords(品类→关键词展开)+ 每关键词独立状态文件 + 日志增强 | ✅ | | `apps/web/src/components/InquiryPage.tsx` | 新增搜索框 fSearch → GET /api/leads?search= | ✅ | | `apps/web/src/components/RuleCenterPage.tsx` | 采集器配置从 keywords 改为 **品类多选框**(categories JSON 数组) | ✅ | | `scripts/tender-fetcher/fetch-v1.2.js` | 中电建脚本增强(过滤/回溯) | ✅ | ### 未跟踪文件 - `scripts/cleanup_garbage_categories.sql` — 清理 AI 垃圾品类 - `scripts/fix_corrupted_titles.sql` — 修复损坏标题 - `scripts/reclassify_leads.js` / `scripts/refetch_corrupted.js` — 历史数据维护 - `PRD-智能比价助手.md` — 比价功能 PRD(供外部平台参考) ### 工作区 vs 生产差异 - **本地有大量未提交改动,生产未部署**(生产 `.next/` 构建于 2026-09-03) - 若需上线这些改动:`npm run typecheck` → `bash scripts/deploy.sh` → **生产重建 web `.next`**(见 9.1) --- ## 11. 生产部署与运维 - **服务器**:172.81.241.109(`SSH_HOST` 在 deploy.sh,如 IP 变更改这里) - **SSH**:`sshpass -p 'Jubianshuzi@2026' ssh ubuntu@172.81.241.109` - **一键部署**:`bash scripts/deploy.sh`(build + rsync dist/.next/源码 + pm2 restart --update-env) - **路径**:代码 `/opt/pingtai/`,数据 `/data/pingtai/`(dev.db / uploads / library / 招标公告) - **进程**:pm2 托管 `pingtai-api`(4000) + `pingtai-web`(3001),systemd 自启 - **反代**:Nginx 80/443 → 3001;`/api/*` → 4000;`/uploads/*` → `/data/pingtai/uploads/` - **HTTPS**:Let's Encrypt,certbot 自动续期 timer 已开 - **常用操作**: ```bash pm2 list / pm2 logs pingtai-api / pm2 restart pingtai-api --update-env tail -f /var/log/pingtai/api.out-1.log sqlite3 /data/pingtai/dev.db # 直接查 DB tar czf pingtai-backup-$(date +%Y%m%d).tgz /data/pingtai/ ``` - **历史包袱**:服务器上旧 Postgres/Redis 部署备份在 `/home/ubuntu/platform-assistant.bak-*`,旧 nginx conf 在 `/etc/nginx/conf.d/platform.conf.bak-*`,可回退 - **采集目录 symlink**:`~/desktop -> /data/pingtai`(必须指向 `/data/pingtai`,不是 `/data/pingtai/招标公告`,否则双层嵌套) --- ## 12. 待办事项 / 建议的下一步 1. **决策未提交改动**:title-compressor + crawler 品类化 + InquiryPage 搜索 + RuleCenterPage 品类多选框,是否继续/提交/部署 2. **修复生产页面 500**:若线上仍有 Server Action 报错,生产 `npx next build` 重建(见 9.1) 3. **详情页内容提取**(P1 数据质量):采集器入库后加类似 notes-extractor 的 AI 提取步骤,补 contact/phone/quantity/unit(当前全缺) 4. **空品类历史线索 review**:AdminPage 品类管理人工 review AI 新建的细分类(合并/删除) 5. **ReportCenterPage / SystemMonitorPage**:仍是 mock,可接真实数据 6. **比价模块增强**(参考 PRD-智能比价助手.md):报价有效期、供应商画像权重、多租户 7. **MCP 发布卡点跟进**:`code:10021` 等产业平台修复状态 --- ## 13. 协作约定(对后续智能体) - 语言:中文(对话/注释/文档/commit) - **改动前必须对齐**:涉及具体修改按 AGENTS.md 协作流程(7 个技术维度:场景/触发/重要程度/数据/边界/样式/部署),不擅自开干 - 例外:拼写错误、单文件 typo、用户明确"按你判断做"、紧急 bug - 改完必须端到端验证,不只"代码看起来对" - 涉及数据库结构、生产配置、依赖升级要明确告知用户 - 提交信息用中文 --- **结束语:** 本项目最核心的链路是 **采集 → 分类 → 询价 → MCP 发布**,接手时建议先跑通这条链路的本地/生产实测,再动其他模块。祝顺利!