502 lines
15 KiB
Markdown
502 lines
15 KiB
Markdown
# Merchant AI HTTP API 调用说明
|
||
|
||
本文档用于喂给外部“解读 AI”或其他服务平台,让 AI 在对话中正确调用本项目的 HTTP JSON API 进行订单统计、线下订单分析和商户排行分析。
|
||
|
||
## 1. 服务定位
|
||
|
||
本项目是一个中间层 HTTP JSON API 服务。AI 不直接请求后台订单系统,也不直接拼接后台订单接口参数。
|
||
|
||
本项目负责:
|
||
|
||
- 接收 AI 的结构化分析请求
|
||
- 解析时间意图
|
||
- 调用后台订单接口
|
||
- 复用本项目内部统计逻辑
|
||
- 返回适合 AI 解读的 JSON 结果
|
||
|
||
## 2. 启动方式
|
||
|
||
本地开发启动:
|
||
|
||
```bash
|
||
php -S 127.0.0.1:8080 -t public public/index.php
|
||
```
|
||
|
||
健康检查:
|
||
|
||
```http
|
||
GET http://127.0.0.1:8080/health
|
||
```
|
||
|
||
正常返回:
|
||
|
||
```json
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"status": "ok",
|
||
"service": "merchant-ai-api"
|
||
}
|
||
}
|
||
```
|
||
|
||
## 3. 接口列表
|
||
|
||
### 3.1 订单汇总
|
||
|
||
```http
|
||
POST /api/order-summary
|
||
```
|
||
|
||
对应工具:`get_order_summary`
|
||
|
||
用途:订单总数、活跃商户数、成功订单数、订单金额合计、实付金额合计。
|
||
|
||
### 3.2 线下订单分析
|
||
|
||
```http
|
||
POST /api/offline-stats
|
||
```
|
||
|
||
对应工具:`get_offline_stats`
|
||
|
||
用途:订单状态分布、支付方式分布、订单类型分布、营销中台分布、退款状态分布、抵扣金额、抵扣红包/抵扣券、平台让利、`diamond` 字段代币值汇总、平均订单金额、平均实付金额、最大订单金额、活跃商户数、实付金额 Top 商户。
|
||
|
||
### 3.3 商户排行榜
|
||
|
||
```http
|
||
POST /api/merchant-ranking
|
||
```
|
||
|
||
对应工具:`get_merchant_ranking`
|
||
|
||
用途:按订单数、成功订单数、订单金额或实付金额生成商户排行。
|
||
|
||
## 4. 请求格式
|
||
|
||
所有统计接口都使用:
|
||
|
||
```http
|
||
Content-Type: application/json
|
||
```
|
||
|
||
如果调用方请求头中传入:
|
||
|
||
```http
|
||
Authorization: Bearer <后台订单接口 token>
|
||
```
|
||
|
||
本服务会优先使用该 token 请求后台订单接口;如果没有传 `Authorization`,则使用服务器 `.env` 中的 `MERCHANT_API_TOKEN`。
|
||
|
||
注意:只有可信后端服务可以传该 header,不建议在浏览器前端或公开客户端暴露后台 token。
|
||
|
||
统一请求示例:
|
||
|
||
```json
|
||
{
|
||
"timePreset": "today",
|
||
"status": -1,
|
||
"keyword": "",
|
||
"fieldKey": "all",
|
||
"payType": "",
|
||
"type": "",
|
||
"btcId": null
|
||
}
|
||
```
|
||
|
||
## 5. 时间参数规则
|
||
|
||
AI 应优先传 `timePreset`,不要直接传自然语言时间。
|
||
|
||
推荐:
|
||
|
||
```json
|
||
{
|
||
"timePreset": "today"
|
||
}
|
||
```
|
||
|
||
支持的 `timePreset`:
|
||
|
||
| 值 | 含义 |
|
||
| --- | --- |
|
||
| `today` | 今天 |
|
||
| `yesterday` | 昨天 |
|
||
| `last_7_days` | 最近 7 天,包含今天 |
|
||
| `last_30_days` | 最近 30 天,包含今天 |
|
||
| `this_week` | 本周,周一到今天 |
|
||
| `last_week` | 上周,周一到周日 |
|
||
| `this_month` | 本月,1 号到今天 |
|
||
| `last_month` | 上月,1 号到月末 |
|
||
| `custom` | 自定义时间范围 |
|
||
|
||
自定义时间:
|
||
|
||
```json
|
||
{
|
||
"timePreset": "custom",
|
||
"startDate": "2026-06-01",
|
||
"endDate": "2026-06-23"
|
||
}
|
||
```
|
||
|
||
自定义时间约束:
|
||
|
||
- `startDate` 格式必须是 `YYYY-MM-DD`
|
||
- `endDate` 格式必须是 `YYYY-MM-DD`
|
||
- `startDate` 不能晚于 `endDate`
|
||
- 不要传 `2026/06/01`,自定义日期统一使用 `2026-06-01`
|
||
|
||
兼容旧字段:
|
||
|
||
```json
|
||
{
|
||
"date": "2026/06/01-2026/06/23"
|
||
}
|
||
```
|
||
|
||
AI 默认不要使用 `date`,除非调用平台只能传固定后台日期格式。
|
||
|
||
## 6. AI 对话到接口参数映射
|
||
|
||
### 6.1 工具选择规则
|
||
|
||
- 用户问“订单汇总”“多少单”“订单金额合计”“实付金额合计”“活跃商户数量”时,选择 `order_summary`。
|
||
- 用户问“状态分布”“支付类型分布”“订单类型分布”“抵扣金额”“抵扣红包”“抵扣券”“平台让利”“手续费”“diamond/钻石/绿宝石/算力统计”时,选择 `offline_stats`。
|
||
- 用户问“排行”“排名”“Top 商家”“商户排行”时,选择 `merchant_ranking`。
|
||
- 用户问“活跃商户有哪些”“活跃商户名称”“商户列表”“有哪些商家”“店铺名称”时,必须选择 `merchant_ranking`,不要选择 `order_summary`。
|
||
- `order_summary` 只返回活跃商户数量 `activeMerchantCount`,不返回商户名称。
|
||
- `merchant_ranking` 返回 `ranking[].merchantName`,可用于回答商户名称、商户列表、店铺名称相关问题。
|
||
|
||
### 6.2 对话示例
|
||
|
||
用户说“今天订单怎么样?”时调用:
|
||
|
||
```json
|
||
{
|
||
"timePreset": "today"
|
||
}
|
||
```
|
||
|
||
推荐接口:`POST /api/order-summary`
|
||
|
||
用户说“分析一下昨天线下订单”时调用:
|
||
|
||
```json
|
||
{
|
||
"timePreset": "yesterday"
|
||
}
|
||
```
|
||
|
||
推荐接口:`POST /api/offline-stats`
|
||
|
||
用户说“看本月商户排行”时调用:
|
||
|
||
```json
|
||
{
|
||
"timePreset": "this_month",
|
||
"sortBy": "totalRealPay",
|
||
"limit": 10
|
||
}
|
||
```
|
||
|
||
推荐接口:`POST /api/merchant-ranking`
|
||
|
||
用户说“2026 年 6 月 25 日活跃商户名称有哪些?”时调用:
|
||
|
||
```json
|
||
{
|
||
"timePreset": "custom",
|
||
"startDate": "2026-06-25",
|
||
"endDate": "2026-06-25",
|
||
"status": -1,
|
||
"sortBy": "totalRealPay",
|
||
"limit": 100
|
||
}
|
||
```
|
||
|
||
推荐接口:`POST /api/merchant-ranking`
|
||
|
||
注意:不要用 `POST /api/order-summary` 回答这个问题,因为它只返回活跃商户数量,不返回商户名称。
|
||
|
||
用户说“查 6 月 1 日到 6 月 23 日订单统计”时调用:
|
||
|
||
```json
|
||
{
|
||
"timePreset": "custom",
|
||
"startDate": "2026-06-01",
|
||
"endDate": "2026-06-23"
|
||
}
|
||
```
|
||
|
||
推荐接口:`POST /api/order-summary`
|
||
|
||
## 7. 常用筛选参数
|
||
|
||
| 参数 | 类型 | 说明 |
|
||
| --- | --- | --- |
|
||
| `status` | integer | 订单状态,默认 `-1` 表示全部 |
|
||
| `keyword` | string | 搜索关键词,当前会传给后台接口的 `real_name` |
|
||
| `fieldKey` | string | 搜索字段,默认 `all` |
|
||
| `payType` | string | 支付方式,对应后台 `pay_type` |
|
||
| `type` | string | 订单类型,对应后台 `type` |
|
||
| `btcId` | integer | 商户分类 ID,对应后台 `btc_id` |
|
||
|
||
### 7.1 `diamond` 字段与 `btc_id` 的关系
|
||
|
||
后台订单里存在 `diamond` 字段。该字段不是固定只表示“钻石”,需要结合 `btc_id` 判断业务含义:
|
||
|
||
| btc_id | `diamond` 字段含义 |
|
||
| --- | --- |
|
||
| `1` | 钻石值 |
|
||
| `3` | 绿宝石值 |
|
||
| `4` | 算力值 |
|
||
|
||
`/api/offline-stats` 会返回:
|
||
|
||
| 字段 | 含义 |
|
||
| --- | --- |
|
||
| `totalTokenValue` | 所有订单 `diamond` 字段本身的合计 |
|
||
| `tokenValueSummary` | 按 `btc_id` 解释后的 `diamond` 字段汇总,例如钻石值、绿宝石值、算力值 |
|
||
|
||
注意:
|
||
|
||
- `diamond` 表示本单关联/附赠/记录的代币值。
|
||
- `diamond_ded` 表示消费券/钻石抵扣金额。
|
||
- 两者不是同一个字段,不要混淆。
|
||
|
||
### 7.2 财务统计字段映射
|
||
|
||
`/api/offline-stats` 中几个容易混淆的财务字段定义如下:
|
||
|
||
| 返回字段 | 计算/来源 | 含义 |
|
||
| --- | --- | --- |
|
||
| `totalPreferentialAmount` | `pr_amount` 合计 | 抵扣红包/抵扣券金额 |
|
||
| `totalMerchantRatePrice` | `merchant_rate_price` 合计 | 商户让利金额 |
|
||
| `totalIntegral` | `integral` 合计 | 积分/平台让利积分值 |
|
||
| `totalPlatformConcessionAmount` | `merchant_rate_price + integral` 合计 | 平台让利合计 |
|
||
| `totalDeductionAmount` | `coin_ded + broker_ded + diamond_ded + pr_amount` 合计 | 抵扣类金额合计,不包含平台让利 |
|
||
|
||
AI 解读规则:
|
||
|
||
- 用户问“平台让利多少”时,读取 `totalPlatformConcessionAmount`。
|
||
- 用户问“抵扣红包”“抵扣券金额”时,读取 `totalPreferentialAmount`。
|
||
- 不要把 `pr_amount` 当作平台让利。
|
||
- 不要把 `merchant_rate_price` 单独等同于完整平台让利,完整平台让利是 `merchant_rate_price + integral`。
|
||
|
||
### 7.3 订单状态 `status` 取值
|
||
|
||
| status | 含义 | 用户常见说法 |
|
||
| --- | --- | --- |
|
||
| `-1` | 全部订单 | 全部、所有订单、不限状态 |
|
||
| `0` | 待支付 | 待支付、未付款、未支付订单 |
|
||
| `1` | 已完成/成功 | 已完成、成功订单、已支付完成 |
|
||
| `2` | 已取消 | 已取消、取消订单 |
|
||
| `3` | 待核销/待使用 | 待核销、待使用、未使用 |
|
||
| `4` | 已退款 | 已退款、退款订单 |
|
||
|
||
AI 选择规则:
|
||
|
||
- 用户没有提到订单状态时,必须传 `status=-1`。
|
||
- 用户问“成功订单”“已完成订单”时,传 `status=1`。
|
||
- 用户问“待支付订单”“未付款订单”时,传 `status=0`。
|
||
- 用户问“取消订单”时,传 `status=2`。
|
||
- 用户问“待核销”“待使用”时,传 `status=3`。
|
||
- 用户问“退款订单”时,传 `status=4`。
|
||
- 如果用户说“订单汇总”“今日数据”“最近7天数据”但没有限定状态,传 `status=-1`。
|
||
|
||
示例:
|
||
|
||
用户说“今天成功订单有多少?”时调用:
|
||
|
||
```json
|
||
{
|
||
"timePreset": "today",
|
||
"status": 1
|
||
}
|
||
```
|
||
|
||
用户说“最近7天退款订单金额是多少?”时调用:
|
||
|
||
```json
|
||
{
|
||
"timePreset": "last_7_days",
|
||
"status": 4
|
||
}
|
||
```
|
||
|
||
用户说“本月所有订单汇总”时调用:
|
||
|
||
```json
|
||
{
|
||
"timePreset": "this_month",
|
||
"status": -1
|
||
}
|
||
```
|
||
|
||
## 8. 商户排行参数
|
||
|
||
`/api/merchant-ranking` 额外支持:
|
||
|
||
| 参数 | 类型 | 说明 |
|
||
| --- | --- | --- |
|
||
| `sortBy` | string | 排序字段 |
|
||
| `limit` | integer | 返回商户数量,默认 `10`,最大 `100` |
|
||
|
||
`/api/merchant-ranking` 返回中会包含:
|
||
|
||
| 字段 | 含义 |
|
||
| --- | --- |
|
||
| `merchantCount` | 当前筛选条件下聚合出的商户总数 |
|
||
| `returnedCount` | 本次实际返回的排行条数 |
|
||
| `limit` | 本次排行返回上限 |
|
||
| `ranking` | 排行列表 |
|
||
|
||
AI 解读时不要把 `returnedCount` 当成总商户数。应使用 `merchantCount` 表示“共有多少家活跃商户”,使用 `returnedCount` 表示“本次展示多少家”。
|
||
|
||
`sortBy` 可选值:
|
||
|
||
| 值 | 含义 |
|
||
| --- | --- |
|
||
| `orderCount` | 按订单数排序 |
|
||
| `successOrderCount` | 按成功订单数排序 |
|
||
| `totalOrderAmount` | 按订单金额排序 |
|
||
| `totalRealPay` | 按实付金额排序,默认值 |
|
||
|
||
## 9. 响应格式
|
||
|
||
成功响应:
|
||
|
||
```json
|
||
{
|
||
"success": true,
|
||
"data": {}
|
||
}
|
||
```
|
||
|
||
失败响应:
|
||
|
||
```json
|
||
{
|
||
"success": false,
|
||
"error": {
|
||
"code": "server_error",
|
||
"message": "错误信息"
|
||
}
|
||
}
|
||
```
|
||
|
||
常见错误:
|
||
|
||
| code | 含义 | 处理方式 |
|
||
| --- | --- | --- |
|
||
| `not_found` | 路由不存在 | 检查 URL |
|
||
| `method_not_allowed` | 请求方法错误 | 统计接口必须使用 POST |
|
||
| `server_error` | 服务端或后台接口异常 | 根据 message 排查 |
|
||
|
||
## 10. 返回数据解读规则
|
||
|
||
AI 必须严格按照接口返回的 JSON 数据解读,不允许编造、放大、补全或推测不存在的数据。
|
||
|
||
例如接口返回:
|
||
|
||
```json
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"orderCount": 100,
|
||
"activeMerchantCount": 5,
|
||
"successOrderCount": 47,
|
||
"totalOrderAmount": 882.89,
|
||
"totalRealPay": 662.39,
|
||
"_debug_query": {
|
||
"time": "2026/06/18-2026/06/24"
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
AI 只能解读为:
|
||
|
||
- 查询时间范围:`2026/06/18-2026/06/24`
|
||
- 当前接口返回订单数:`100`
|
||
- 活跃商户数:`5`
|
||
- 成功订单数:`47`
|
||
- 订单总金额:`882.89`
|
||
- 实付总金额:`662.39`
|
||
|
||
AI 可以基于已返回字段做简单计算,但必须说明是“根据当前返回数据计算”:
|
||
|
||
- 成功率:`47 / 100 = 47%`
|
||
- 实付占比:`662.39 / 882.89 ≈ 75.03%`
|
||
- 平均订单金额:`882.89 / 100 ≈ 8.83`
|
||
- 平均实付金额:`662.39 / 100 ≈ 6.62`
|
||
|
||
AI 禁止输出以下内容,除非接口明确返回:
|
||
|
||
- 禁止把 `100` 改写成 `3850`
|
||
- 禁止编造 `3427` 个成功订单
|
||
- 禁止编造 `186` 家商户
|
||
- 禁止编造 `日均订单 550 单`
|
||
- 禁止编造 `日均流水 38.5 万元`
|
||
- 禁止编造“整体交易状况良好”等过度结论
|
||
- 禁止把未返回的后台总数当作事实
|
||
|
||
注意:当前接口会根据后台返回的 `data.count` 自动分页拉取订单列表,直到取完当前筛选条件下的订单数据后再统计。`_debug_query` 只表示筛选条件,不再表示只统计第 1 页。
|
||
|
||
## 11. AI 调用约束
|
||
|
||
AI 必须遵守以下规则:
|
||
|
||
1. 统计接口必须使用 `POST`。
|
||
2. 不要用浏览器 `GET` 方式访问统计接口。
|
||
3. 时间优先使用 `timePreset`。
|
||
4. 只有用户明确给出起止日期时,才使用 `timePreset=custom`。
|
||
5. 自定义日期必须使用 `YYYY-MM-DD`。
|
||
6. 不要传 `今天`、`昨天`、`本月` 这类中文自然语言给接口。
|
||
7. 不要伪造不存在的筛选字段。
|
||
8. 不要把后台系统 token 暴露给用户。
|
||
9. 不要直接调用后台订单接口,只调用本项目 HTTP API。
|
||
10. 如果用户问题不包含时间,默认使用 `timePreset=today`。
|
||
11. 解读结果时只能使用接口返回的字段,不允许编造不存在的订单数、金额、商户数、日均值或趋势结论。
|
||
12. 如果要计算成功率、平均值、占比,必须基于接口返回字段计算,并说明“根据当前返回数据计算”。
|
||
13. 如果接口返回 `_debug_query.time`,可以把它作为本次查询时间范围。
|
||
|
||
## 12. PowerShell 调用示例
|
||
|
||
订单汇总:
|
||
|
||
```powershell
|
||
Invoke-RestMethod `
|
||
-Uri "http://127.0.0.1:8080/api/order-summary" `
|
||
-Method POST `
|
||
-ContentType "application/json" `
|
||
-Body '{"timePreset":"today"}'
|
||
```
|
||
|
||
线下订单分析:
|
||
|
||
```powershell
|
||
Invoke-RestMethod `
|
||
-Uri "http://127.0.0.1:8080/api/offline-stats" `
|
||
-Method POST `
|
||
-ContentType "application/json" `
|
||
-Body '{"timePreset":"yesterday"}'
|
||
```
|
||
|
||
商户排行:
|
||
|
||
```powershell
|
||
Invoke-RestMethod `
|
||
-Uri "http://127.0.0.1:8080/api/merchant-ranking" `
|
||
-Method POST `
|
||
-ContentType "application/json" `
|
||
-Body '{"timePreset":"this_month","sortBy":"totalRealPay","limit":10}'
|
||
```
|
||
|
||
## 13. 推荐给 AI 的简短系统提示词
|
||
|
||
```text
|
||
你需要通过 Merchant AI HTTP API 分析订单数据。统计接口只能使用 POST。不要直接请求后台订单接口,不要暴露 token。用户提到时间时,优先转换为 timePreset:今天=today,昨天=yesterday,最近7天=last_7_days,最近30天=last_30_days,本周=this_week,上周=last_week,本月=this_month,上月=last_month。只有明确起止日期时使用 custom,并传 startDate/endDate,格式 YYYY-MM-DD。不要把“今天”“昨天”“本月”等自然语言直接作为参数传给接口。如果用户没说时间,默认 timePreset=today。订单状态 status:全部=-1,待支付=0,已完成/成功=1,已取消=2,待核销/待使用=3,已退款=4;如果用户没有限定状态,默认 status=-1。工具选择:问订单汇总、多少单、金额合计、活跃商户数量,选择 order_summary;问状态分布、支付类型、订单类型、抵扣、抵扣红包、抵扣券、平台让利、diamond/钻石/绿宝石/算力统计,选择 offline_stats;问排行、排名、Top 商家、商户名称、活跃商户有哪些、商户列表、店铺名称,选择 merchant_ranking。平台让利读取 totalPlatformConcessionAmount,它等于 merchant_rate_price + integral;抵扣红包/抵扣券读取 totalPreferentialAmount,它来自 pr_amount;不要把 pr_amount 当作平台让利。注意 order_summary 只返回 activeMerchantCount,不返回商户名称;需要商户名称时必须用 merchant_ranking。解读接口返回时,必须只使用 JSON 中真实存在的字段和数值,不允许编造订单数、成功订单数、商户数、金额、日均值、趋势或业务结论。可以基于返回字段做简单计算,但必须说明“根据当前返回数据计算”。如果返回 _debug_query.time,可以作为查询时间范围。当前接口会自动分页拉取当前筛选条件下的订单数据后再统计,_debug_query 只表示筛选条件。
|
||
```
|