Skip to Content

L4层:接口层(NestJS实现)

L4层技术定位: L4层作为接口层,由NestJS实现,是采购平台对外暴露的企业集成接口层。所有接口以采购意图为中心设计,NestJS接收企业系统的API请求后,通过内部HTTP接口调用Next.js Server的L1-L3层功能完成业务处理。

技术架构:

  • NestJS API:对外提供REST API接口,处理认证、鉴权、请求验证、响应封装
  • 服务编排:协调Next.js Server的各层服务,实现企业级接口能力
  • Webhook通知:主动推送状态变更通知给企业系统,支持重试和签名验证

说明:这种架构设计将企业对接接口(NestJS)与核心业务逻辑(Next.js)分离,NestJS专注于企业级API规范、安全认证、流量控制等企业集成关注点,而Next.js专注于核心采购业务逻辑。两者通过HTTP接口通信,保持技术栈的清晰分工。

核心设计原则:

  • 意图为中心:所有接口围绕采购意图数据模型设计
  • 内部服务隐藏:L1-L3层服务不对外暴露,由Next.js Server内部实现
  • 职责边界清晰:平台不关注企业内部审批、财务等逻辑
  • 标准集成:企业系统通过标准REST API集成,保持系统解耦

6.1 REST API设计

6.1.1 API架构设计

接口分层架构:

6.1.2 意图接口总览

采购平台对外提供以下以意图为中心的标准接口:

接口名称HTTP方法路径说明
创建采购意图POST/api/v1/intents提交新的采购意图
查询意图详情GET/api/v1/intents/{id}获取指定意图的详细信息
查询意图列表GET/api/v1/intents批量查询意图(支持筛选)
执行采购意图POST/api/v1/intents/{id}/execute触发意图执行(审批通过后调用)
取消采购意图POST/api/v1/intents/{id}/cancel取消意图执行
状态变更通知Webhook企业配置的回调地址平台主动推送状态变更事件

6.2 核心接口定义

所有接口均基于L2层的数据模型设计,围绕采购意图(Intent)进行操作。

6.2.1 创建采购意图接口

企业系统(或浏览器插件)通过此接口提交采购意图:

POST /api/v1/intents Content-Type: application/json Authorization: Bearer {token} Request Body: { "userId": "user_123", "platform": "TAOBAO", "productUrl": "https://item.taobao.com/item.htm?id=123456", "title": "Apple iPhone 15 Pro 256GB 深空黑色", "price": 8999.00, "quantity": 2, "recipientName": "张三", "address": "北京市朝阳区望京SOHO T1 1001", "phone": "13800138000", "remarks": "急用,请优先处理" } Response: { "code": 200, "message": "意图创建成功", "data": { "intentId": "INT_20260101_001", "status": "DRAFT", "createdAt": "2026-01-01T10:00:00Z" } }

6.2.2 查询意图详情接口

企业系统通过此接口查询意图的详细信息和当前状态:

GET /api/v1/intents/{intentId} Authorization: Bearer {token} Response: { "code": 200, "message": "查询成功", "data": { "intentId": "INT_20260101_001", "userId": "user_123", "platform": "TAOBAO", "productUrl": "https://item.taobao.com/item.htm?id=123456", "title": "Apple iPhone 15 Pro 256GB 深空黑色", "price": 8999.00, "quantity": 2, "recipientName": "张三", "address": "北京市朝阳区望京SOHO T1 1001", "phone": "13800138000", "remarks": "急用,请优先处理", "status": "PROCESSING", "createdAt": "2026-01-01T10:00:00Z", "updatedAt": "2026-01-01T10:15:00Z", "execution": { "orderId": "ORD_001", "assignedAgent": "agent_taobao_01", "startedAt": "2026-01-01T10:10:00Z", "progress": 65 }, "receipt": null } }

6.2.3 查询意图列表接口

支持按条件筛选和分页查询采购意图:

GET /api/v1/intents?page=1&pageSize=20&status=completed&startDate=2026-01-01&endDate=2026-01-31&userId=user_123 Authorization: Bearer {token} Response: { "code": 200, "message": "查询成功", "data": { "total": 156, "page": 1, "pageSize": 20, "items": [ { "intentId": "INT_20260101_001", "userId": "user_123", "platform": "TAOBAO", "title": "Apple iPhone 15 Pro 256GB", "price": 8999.00, "quantity": 2, "status": "COMPLETED", "createdAt": "2026-01-01T10:00:00Z", "updatedAt": "2026-01-01T10:30:00Z" } // ... 更多意图 ] } }

6.2.4 执行采购意图接口

企业系统在审批通过后,调用此接口触发意图执行:

POST /api/v1/intents/{intentId}/execute Content-Type: application/json Authorization: Bearer {token} Request Body: { "priceTolerance": 10.00, "executionNote": "审批通过,可以执行" } Response: { "code": 200, "message": "执行任务已创建", "data": { "intentId": "INT_20260101_001", "orderId": "ORD_001", "status": "PROCESSING", "estimatedTime": 1800 } }

说明:

  • 调用此接口后,内部服务会创建执行工单(Order)
  • 状态自动从 submitted 变更为 processing
  • AI执行引擎会自动开始执行采购任务
  • 状态变更会通过 Webhook 通知企业系统

6.2.5 取消采购意图接口

企业系统可以在执行前或执行中取消意图:

POST /api/v1/intents/{intentId}/cancel Content-Type: application/json Authorization: Bearer {token} Request Body: { "reason": "需求变更,不再需要采购" } Response: { "code": 200, "message": "意图已取消", "data": { "intentId": "INT_20260101_001", "status": "CANCELLED", "cancelledAt": "2026-01-01T10:05:00Z" } }

说明:

  • 如果意图正在执行中,会尝试中止执行
  • 状态自动变更为 cancelled
  • 状态变更会通过 Webhook 通知企业系统

6.2.6 状态变更通知(Webhook)

当意图状态发生变化时,平台会主动推送事件到企业配置的 Webhook 地址:

POST {企业配置的回调地址} Content-Type: application/json X-Signature: {请求签名} Request Body: { "event": "intent.status.changed", "intentId": "INT_20260101_001", "timestamp": "2026-01-01T10:30:00Z", "data": { "oldStatus": "processing", "newStatus": "completed", "intent": { "intentId": "INT_20260101_001", "userId": "user_123", "platform": "TAOBAO", "title": "Apple iPhone 15 Pro 256GB", "price": 8999.00, "quantity": 2, "status": "COMPLETED", "updatedAt": "2026-01-01T10:30:00Z" }, "receipt": { "platformOrderNo": "TB2026010112345", "paymentId": "2026010821001001570", "paidAmount": 17998.00, "invoiceNumber": "23442000000123456", "invoiceUrl": "https://storage.example.com/invoices/INV001.pdf", "orderTime": "2026-01-01T10:25:00Z" } } } 企业系统预期响应: { "code": 200, "message": "接收成功" }

支持的事件类型:

事件类型说明触发时机
intent.status.changed意图状态变更状态从一个阶段变更到另一个阶段
intent.execution.started开始执行Order 创建并开始执行
intent.execution.progress执行进度更新执行过程中的关键步骤完成
intent.execution.completed执行完成AI执行成功,Receipt 已创建
intent.execution.failed执行失败AI执行遇到不可恢复的错误
intent.cancelled意图取消意图被取消

6.3 接口安全与认证

6.3.1 认证授权机制

OAuth 2.0 认证流程:

// 1. 获取访问令牌 POST /api/v1/oauth/token Content-Type: application/json Request Body: { "grant_type": "client_credentials", "client_id": "your_client_id", "client_secret": "your_client_secret" } Response: { "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "token_type": "Bearer", "expires_in": 3600 } // 2. 使用令牌访问API GET /api/v1/intents/INT_20260101_001 Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

6.3.2 安全控制策略

安全措施实现方式配置示例
HTTPS强制TLS 1.3加密传输拒绝HTTP请求
JWT认证Bearer Token验证1小时过期
请求签名HMAC-SHA256签名Webhook通知签名验证
频率限制基于token的限流100次/分钟
IP白名单限制访问来源IP可选配置

6.4 集成指南

6.4.1 快速集成步骤

企业系统集成采购平台只需三步:

步骤1:获取认证凭证

  • 联系平台获取 Client ID 和 Client Secret
  • 使用凭证获取 Access Token

步骤2:配置Webhook地址

  • 提供企业系统的 Webhook 回调地址
  • 配置接收状态变更通知

步骤3:调用意图接口

  • 调用 POST /api/v1/intents 创建意图
  • 审批后调用 POST /api/v1/intents/{id}/execute 触发执行
  • 接收 Webhook 通知获取状态更新

6.4.2 集成示例代码

创建采购意图:

// 1. 获取 Access Token const tokenResponse = await fetch('https://api.procure-core.com/oauth/token', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ grant_type: 'client_credentials', client_id: 'your_client_id', client_secret: 'your_client_secret' }) }); const { access_token } = await tokenResponse.json(); // 2. 创建采购意图 const intentResponse = await fetch('https://api.procure-core.com/api/v1/intents', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${access_token}` }, body: JSON.stringify({ userId: 'user_123', platform: 'TAOBAO', productUrl: 'https://item.taobao.com/item.htm?id=123456', title: 'Apple iPhone 15 Pro', price: 8999.00, quantity: 2, recipientName: '张三', address: '北京市朝阳区望京SOHO', phone: '13800138000', remarks: '急用' }) }); const intent = await intentResponse.json(); console.log('意图ID:', intent.data.intentId);

触发执行:

// 3. 审批通过后,触发执行 const executeResponse = await fetch( `https://api.procure-core.com/api/v1/intents/${intent.data.intentId}/execute`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${access_token}` }, body: JSON.stringify({ priceTolerance: 10.00 }) } ); const execution = await executeResponse.json(); console.log('执行状态:', execution.data.status);

接收Webhook通知:

// 企业系统提供的 Webhook 端点 app.post('/webhooks/procurebot', (req, res) => { const { event, intentId, data } = req.body; // 验证签名 const signature = req.headers['x-signature']; if (!verifySignature(req.body, signature)) { return res.status(401).json({ error: '签名验证失败' }); } // 处理不同事件 switch (event) { case 'intent.execution.completed': console.log('执行完成:', { intentId, platformOrderNo: data.receipt.platformOrderNo, paidAmount: data.receipt.paidAmount, invoiceUrl: data.receipt.invoiceUrl }); // 更新企业系统内部状态 updateInternalStatus(intentId, 'completed', data); break; case 'intent.execution.failed': console.log('执行失败:', { intentId, error: data.errorMessage }); // 通知相关人员处理 notifyFailure(intentId, data); break; } // 返回 200 表示接收成功 res.json({ code: 200, message: '接收成功' }); });

6.5 状态流转说明

6.5.1 意图状态流转

基于L2层的数据模型,意图状态流转如下:

状态说明:

状态说明触发方式Webhook事件
draft草稿状态创建意图时自动设置-
submitted已提交内部自动流转intent.status.changed
processing执行中调用execute接口intent.execution.started
completed已完成AI执行成功后自动设置intent.execution.completed
failed执行失败AI执行失败后自动设置intent.execution.failed
cancelled已取消调用cancel接口intent.cancelled

关键说明:

  • 企业系统不能直接修改状态
  • 只能通过操作接口(execute、cancel)触发状态变更
  • 状态变更由内部服务自动完成(L2层的IntentService)
  • 状态变更后通过Webhook主动通知企业系统