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主动通知企业系统