platform-assistant/docs/devbox-requirements/MCP-publish_rfq-字段升级需求.md
Sisyphus afac18e843 feat(F002): W26 + W29.x + W30 + W31 平台助手全部改动首次 commit
- W26: NestJS API + Next.js Web + Prisma + SQLite scaffold
- W26: Lead 模型 + Crawler + 询价发布助手 (线索池 + 一键发布)
- W29.x: MCP 集成 (Integration 模型 + connectMcp + publish_rfq 5 工具端到端跑通)
- W30: 3 字段补充 (notes / quotationType / quotationDemand)
- W31 P1: 自动填 enterpriseId / userId (Prisma companyUserId 字段 + get_app_identity tool + lead.service.ts publishArgs)
- W31: detail 详情页 + admin UI 集成管理 (OpenAppListView + AuditLogListView)

关联: ~/Documents/02-平台开发/产品开发/F002-W31-交接文档.md
GIT-AUDIT-REPORT-2026-06-24.md
2026-06-24 11:07:11 +08:00

8.2 KiB
Raw Blame History

需求:F002 MCP publish_rfq 补全商务字段

提出方:平台助手(nest-api) 接收方:devbox 产品网络(renren-supplier-server) 优先级:P1 时间:2026-06-22

一、背景

平台助手正在用 MCP 协议替换旧的 Playwright GUI 流程(direv-publish skill),自动把抓取的招标线索发布到 B2B 平台。当前 MCP publish_rfq tool(对应 supplier/inquiry/publish 接口)只设了 5 个字段,丢失了 11 个关键商务字段,导致发布的询价质量远低于旧 GUI 流程。

二、当前 F002 publish 实现的问题

renren-supplier-server 的 InquiryServiceImpl.publish() 当前只设了这些字段:

✅ 已设 ❌ 未设(旧 GUI 流程里有)
title inquiryValidDate(截止日期)
note(来自 description) deliverDate(要求交货日期)
purchaseQuantity shippingAddress(收货地址)
userId contactName(联系人)
inquiryEnterpriseId contactPhone(联系电话)
inquiryEnterpriseName freightFlag(报价含运费)
orderId paymentMethod(付款方式)
publishDate invoiceType(开票要求)
quotationType quotationDemand(报价要求)
apprStatus name/mobile(询价人姓名/电话)
auditDate inquiryParty(询价主体)
urls(附件) procurementType(采购类型)

对比:旧 GUI 流程有 18 个字段 + 商品封面图。

三、需求:补全 11 个核心商务字段

3.1 MCP publish_rfq tool schema 升级

在 product_network_mcp/src/tools/inquiry.ts 的 publish_rfq zod schema 里增加:

{
  title: z.string(),
  description: z.string().optional(),
  qty: z.number().positive().optional(),
  // ===== 新增字段 =====
  deadline: z.string().optional().describe("询价截止日期 YYYY-MM-DD(映射 inquiryValidDate)"),
  deliveryDate: z.string().optional().describe("要求交货日期 YYYY-MM-DD(映射 deliverDate)"),
  shippingAddress: z.string().optional().describe("收货地址(映射 shippingAddress)"),
  contactName: z.string().optional().describe("联系人(映射 contactName)"),
  contactPhone: z.string().optional().describe("联系电话(映射 contactPhone)"),
  freightFlag: z.enum(["含运费", "不含运费"]).optional().describe("报价是否含运费"),
  paymentMethod: z.string().optional().describe("付款方式名称,如 货到付款(映射 paymentMethod 字典)"),
  invoiceType: z.enum(["增值税专票", "增值税普票", "不开发票"]).optional().describe("开票要求(1/2/3)"),
  procurementType: z.string().optional().describe("采购类型:定量采购/议价采购(映射 procurementType 字典)"),
  inquiryParty: z.string().optional().describe("询价主体(公司名,如 郑州巨变网络科技有限公司)"),
  // ===== 现有字段保留 =====
  userId: z.number().optional(),
  enterpriseId: z.number().optional(),
  enterpriseName: z.string().optional(),
  attachments: z.array(z.string()).optional(),
}

3.2 Java 后端 InquiryServiceImpl.publish() 升级

renren-supplier-server/src/main/java/io/renren/service/impl/InquiryServiceImpl.java

当前实现(F002 简化版)只设了 6 个字段,需要补:

public Result<Map<String, Object>> publish(Map<String, Object> params) {
    InquiryEntity inquiryEntity = new InquiryEntity();

    // ===== 已有字段 =====
    inquiryEntity.setTitle((String) params.get("title"));
    inquiryEntity.setNote((String) params.get("description"));
    // qty / userId / enterpriseId / enterpriseName / urls / 系统字段...

    // ===== 新增字段映射 =====

    // 截止日期(YYYY-MM-DD 字符串 → Date)
    String deadline = (String) params.get("deadline");
    if (StringUtils.isNotBlank(deadline)) {
        inquiryEntity.setInquiryValidDate(DateUtil.parse(deadline, "yyyy-MM-dd"));
    }

    // 要求交货日期
    String deliveryDate = (String) params.get("deliveryDate");
    if (StringUtils.isNotBlank(deliveryDate)) {
        inquiryEntity.setDeliverDate(DateUtil.parse(deliveryDate, "yyyy-MM-dd"));
    }

    // 收货地址
    String shippingAddress = (String) params.get("shippingAddress");
    if (StringUtils.isNotBlank(shippingAddress)) {
        inquiryEntity.setShippingAddress(shippingAddress);
    }

    // 联系人/电话
    String contactName = (String) params.get("contactName");
    if (StringUtils.isNotBlank(contactName)) {
        inquiryEntity.setContactName(contactName);
    }
    String contactPhone = (String) params.get("contactPhone");
    if (StringUtils.isNotBlank(contactPhone)) {
        inquiryEntity.setContactPhone(contactPhone);
    }

    // 询价主体
    String inquiryParty = (String) params.get("inquiryParty");
    if (StringUtils.isNotBlank(inquiryParty)) {
        inquiryEntity.setInquiryParty(inquiryParty);
    }

    // 报价含运费(0=不含/1=含)
    String freightFlag = (String) params.get("freightFlag");
    if ("含运费".equals(freightFlag)) {
        inquiryEntity.setFreightFlag("1");
    } else if ("不含运费".equals(freightFlag)) {
        inquiryEntity.setFreightFlag("0");
    }

    // 采购类型(字典映射:定量采购/议价采购 → procurementType 枚举值)
    // 需要确认现有字典值

    // 付款方式(字符串 → paymentMethod 字典 ID,需要查 supplier-server 的字典表)
    // 建议:先按字符串存,Java 后端查表映射

    // 发票要求(1/2/3)
    String invoiceType = (String) params.get("invoiceType");
    if ("增值税专票".equals(invoiceType)) {
        inquiryEntity.setInvoiceType(1);
    } else if ("增值税普票".equals(invoiceType)) {
        inquiryEntity.setInvoiceType(2);
    } else if ("不开发票".equals(invoiceType)) {
        inquiryEntity.setInvoiceType(3);
    }

    // ... 系统字段保持不变
    insert(inquiryEntity);

    // 返回不变
    Map<String, Object> result = new HashMap<>();
    result.put("rfqId", inquiryEntity.getId());
    result.put("orderId", orderId);
    result.put("status", "published");
    return new Result<Map<String, Object>>().ok(result);
}

四、验收标准

升级后,平台助手通过 MCP publish_rfq 发布一条询价,在 B2B 平台 list_my_rfqs 接口查询时,能看到以下字段都正确填充:

  • ✅ note(备注)
  • ✅ purchaseQuantity(数量)
  • ✅ inquiryValidDate(截止日期,非 null)
  • ✅ deliverDate(交货日期,非 null)
  • ✅ shippingAddress(收货地址)
  • ✅ contactName(联系人)
  • ✅ contactPhone(电话)
  • ✅ inquiryParty(询价主体)
  • ✅ freightFlag(运费标识)
  • ✅ invoiceType(发票类型)
  • ✅ quotationType(报价方式)

五、不在本次升级范围

下列字段有特殊复杂度,不在本次升级中处理:

  • ❌ match_category 智能匹配(API 暂未实现,等 devbox 后端补齐)
  • ❌ 商品封面图(MCP 无对应机制,旧 GUI 用 AI 生图,新 MCP 不支持)
  • ❌ 多商品(询价单 → 询价明细 1:N,旧 GUI 是单商品)

六、测试用例

升级后请用以下 payload 测试:

{
  "title": "【测试】新疆水泥采购 100 吨",
  "description": "P.O 42.5 普通硅酸盐水泥",
  "qty": 100,
  "deadline": "2026-12-31",
  "deliveryDate": "2027-01-30",
  "shippingAddress": "新疆乌鲁木齐市新市区XX路XX号",
  "contactName": "郑钊",
  "contactPhone": "15532027557",
  "freightFlag": "含运费",
  "paymentMethod": "货到付款",
  "invoiceType": "增值税专票",
  "inquiryParty": "郑州巨变网络科技有限公司",
  "attachments": ["https://example.com/notice.pdf"]
}

调用 list_my_rfqs 验证上述字段都被持久化。

七、平台助手这边的改动(已完成)

✅ Lead 模型已加 4 个新字段:quantity、unit、regionDetail、attachments ✅ publishToDirev 参数拼接逻辑已改:只传 schema 接受的字段(不传 unknown 字段) ✅ 端到端验证:当前新 schema 下能成功创建询价并拿到真 rfqId

待 devbox 升级 schema 后,平台助手这边只需把新参数加进 publishToDirev 的 publishArgs 对象即可,无需改 schema/迁移数据。