初始化
This commit is contained in:
parent
8484851bd9
commit
404260f9d7
|
|
@ -66,7 +66,10 @@ Returns merchant ranking by `orderCount`, `successOrderCount`, `totalOrderAmount
|
||||||
|
|
||||||
## Common Parameters
|
## Common Parameters
|
||||||
|
|
||||||
- `date`: date range, for example `2026/06/23-2026/06/23`; defaults to today.
|
- `timePreset`: preferred AI time intent. Supported values: `today`, `yesterday`, `last_7_days`, `last_30_days`, `this_week`, `last_week`, `this_month`, `last_month`, `custom`. Defaults to `today`.
|
||||||
|
- `startDate`: custom start date, required when `timePreset=custom`, format `YYYY-MM-DD`.
|
||||||
|
- `endDate`: custom end date, required when `timePreset=custom`, format `YYYY-MM-DD`.
|
||||||
|
- `date`: legacy compatible date range, for example `2026/06/23-2026/06/23`; if provided, it is sent to the upstream order API as-is.
|
||||||
- `status`: order status; defaults to `-1`.
|
- `status`: order status; defaults to `-1`.
|
||||||
- `keyword`: search keyword, sent to upstream API as `real_name`.
|
- `keyword`: search keyword, sent to upstream API as `real_name`.
|
||||||
- `fieldKey`: upstream `field_key`; defaults to `all`.
|
- `fieldKey`: upstream `field_key`; defaults to `all`.
|
||||||
|
|
@ -84,5 +87,5 @@ Returns merchant ranking by `orderCount`, `successOrderCount`, `totalOrderAmount
|
||||||
```bash
|
```bash
|
||||||
curl -X POST http://127.0.0.1:8080/api/merchant-ranking \
|
curl -X POST http://127.0.0.1:8080/api/merchant-ranking \
|
||||||
-H "Content-Type: application/json" \
|
-H "Content-Type: application/json" \
|
||||||
-d '{"date":"2026/06/23-2026/06/23","sortBy":"totalRealPay","limit":10}'
|
-d '{"timePreset":"today","sortBy":"totalRealPay","limit":10}'
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,307 @@
|
||||||
|
# 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`
|
||||||
|
|
||||||
|
用途:订单状态分布、支付方式分布、订单类型分布、平均订单金额、平均实付金额、最大订单金额。
|
||||||
|
|
||||||
|
### 3.3 商户排行榜
|
||||||
|
|
||||||
|
```http
|
||||||
|
POST /api/merchant-ranking
|
||||||
|
```
|
||||||
|
|
||||||
|
对应工具:`get_merchant_ranking`
|
||||||
|
|
||||||
|
用途:按订单数、成功订单数、订单金额或实付金额生成商户排行。
|
||||||
|
|
||||||
|
## 4. 请求格式
|
||||||
|
|
||||||
|
所有统计接口都使用:
|
||||||
|
|
||||||
|
```http
|
||||||
|
Content-Type: application/json
|
||||||
|
```
|
||||||
|
|
||||||
|
统一请求示例:
|
||||||
|
|
||||||
|
```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 对话到接口参数映射
|
||||||
|
|
||||||
|
用户说“今天订单怎么样?”时调用:
|
||||||
|
|
||||||
|
```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`
|
||||||
|
|
||||||
|
用户说“查 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` |
|
||||||
|
|
||||||
|
## 8. 商户排行参数
|
||||||
|
|
||||||
|
`/api/merchant-ranking` 额外支持:
|
||||||
|
|
||||||
|
| 参数 | 类型 | 说明 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `sortBy` | string | 排序字段 |
|
||||||
|
| `limit` | integer | 返回商户数量,默认 `10`,最大 `100` |
|
||||||
|
|
||||||
|
`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 调用约束
|
||||||
|
|
||||||
|
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. 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}'
|
||||||
|
```
|
||||||
|
|
||||||
|
## 12. 推荐给 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。
|
||||||
|
```
|
||||||
|
|
@ -10,6 +10,7 @@ use App\Controller\StatsController;
|
||||||
use App\Http\MerchantApiClient;
|
use App\Http\MerchantApiClient;
|
||||||
use App\Repositories\OfflineOrderRepository;
|
use App\Repositories\OfflineOrderRepository;
|
||||||
use App\Service\StatsService;
|
use App\Service\StatsService;
|
||||||
|
use App\Service\TimeRangeResolver;
|
||||||
use App\Tools\AnalyzeOfflineOrdersTool;
|
use App\Tools\AnalyzeOfflineOrdersTool;
|
||||||
use App\Tools\MerchantRankingTool;
|
use App\Tools\MerchantRankingTool;
|
||||||
use App\Tools\OrderSummaryTool;
|
use App\Tools\OrderSummaryTool;
|
||||||
|
|
@ -24,6 +25,7 @@ final class ApiFactory
|
||||||
new OrderSummaryTool($orders),
|
new OrderSummaryTool($orders),
|
||||||
new AnalyzeOfflineOrdersTool($orders),
|
new AnalyzeOfflineOrdersTool($orders),
|
||||||
new MerchantRankingTool($orders),
|
new MerchantRankingTool($orders),
|
||||||
|
new TimeRangeResolver(),
|
||||||
);
|
);
|
||||||
|
|
||||||
return new ApiKernel(
|
return new ApiKernel(
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ final readonly class StatsService
|
||||||
private OrderSummaryTool $orderSummaryTool,
|
private OrderSummaryTool $orderSummaryTool,
|
||||||
private AnalyzeOfflineOrdersTool $offlineStatsTool,
|
private AnalyzeOfflineOrdersTool $offlineStatsTool,
|
||||||
private MerchantRankingTool $merchantRankingTool,
|
private MerchantRankingTool $merchantRankingTool,
|
||||||
|
private TimeRangeResolver $timeRangeResolver,
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -24,7 +25,7 @@ final readonly class StatsService
|
||||||
public function getOrderSummary(HttpRequest $request): array
|
public function getOrderSummary(HttpRequest $request): array
|
||||||
{
|
{
|
||||||
return ($this->orderSummaryTool)(
|
return ($this->orderSummaryTool)(
|
||||||
$request->string('date'),
|
$this->date($request),
|
||||||
$request->int('status'),
|
$request->int('status'),
|
||||||
$request->string('keyword'),
|
$request->string('keyword'),
|
||||||
$request->string('fieldKey'),
|
$request->string('fieldKey'),
|
||||||
|
|
@ -40,7 +41,7 @@ final readonly class StatsService
|
||||||
public function getOfflineStats(HttpRequest $request): array
|
public function getOfflineStats(HttpRequest $request): array
|
||||||
{
|
{
|
||||||
return ($this->offlineStatsTool)(
|
return ($this->offlineStatsTool)(
|
||||||
$request->string('date'),
|
$this->date($request),
|
||||||
$request->int('status'),
|
$request->int('status'),
|
||||||
$request->string('keyword'),
|
$request->string('keyword'),
|
||||||
$request->string('fieldKey'),
|
$request->string('fieldKey'),
|
||||||
|
|
@ -56,7 +57,7 @@ final readonly class StatsService
|
||||||
public function getMerchantRanking(HttpRequest $request): array
|
public function getMerchantRanking(HttpRequest $request): array
|
||||||
{
|
{
|
||||||
return ($this->merchantRankingTool)(
|
return ($this->merchantRankingTool)(
|
||||||
$request->string('date'),
|
$this->date($request),
|
||||||
$request->int('status'),
|
$request->int('status'),
|
||||||
$request->string('keyword'),
|
$request->string('keyword'),
|
||||||
$request->string('fieldKey'),
|
$request->string('fieldKey'),
|
||||||
|
|
@ -67,4 +68,14 @@ final readonly class StatsService
|
||||||
$request->int('limit'),
|
$request->int('limit'),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function date(HttpRequest $request): string
|
||||||
|
{
|
||||||
|
return $this->timeRangeResolver->resolve(
|
||||||
|
$request->string('date'),
|
||||||
|
$request->string('timePreset'),
|
||||||
|
$request->string('startDate'),
|
||||||
|
$request->string('endDate'),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,64 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Service;
|
||||||
|
|
||||||
|
final class TimeRangeResolver
|
||||||
|
{
|
||||||
|
private const DATE_FORMAT = 'Y/m/d';
|
||||||
|
|
||||||
|
public function __construct(private readonly string $timezone = 'Asia/Shanghai')
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function resolve(?string $date, ?string $timePreset, ?string $startDate, ?string $endDate): string
|
||||||
|
{
|
||||||
|
if ($this->filled($date)) {
|
||||||
|
return $date;
|
||||||
|
}
|
||||||
|
|
||||||
|
$now = new \DateTimeImmutable('now', new \DateTimeZone($this->timezone));
|
||||||
|
$preset = $this->filled($timePreset) ? $timePreset : 'today';
|
||||||
|
|
||||||
|
[$start, $end] = match ($preset) {
|
||||||
|
'today' => [$now, $now],
|
||||||
|
'yesterday' => [$now->modify('-1 day'), $now->modify('-1 day')],
|
||||||
|
'last_7_days' => [$now->modify('-6 days'), $now],
|
||||||
|
'last_30_days' => [$now->modify('-29 days'), $now],
|
||||||
|
'this_week' => [$now->modify('monday this week'), $now],
|
||||||
|
'last_week' => [$now->modify('monday last week'), $now->modify('sunday last week')],
|
||||||
|
'this_month' => [$now->modify('first day of this month'), $now],
|
||||||
|
'last_month' => [$now->modify('first day of last month'), $now->modify('last day of last month')],
|
||||||
|
'custom' => [$this->parseDate($startDate), $this->parseDate($endDate)],
|
||||||
|
default => throw new \InvalidArgumentException('Unsupported timePreset: ' . $preset),
|
||||||
|
};
|
||||||
|
|
||||||
|
if ($start > $end) {
|
||||||
|
throw new \InvalidArgumentException('startDate cannot be later than endDate.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $start->format(self::DATE_FORMAT) . '-' . $end->format(self::DATE_FORMAT);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function parseDate(?string $date): \DateTimeImmutable
|
||||||
|
{
|
||||||
|
if (!$this->filled($date)) {
|
||||||
|
throw new \InvalidArgumentException('startDate and endDate are required when timePreset is custom.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$normalized = str_replace('/', '-', $date);
|
||||||
|
$parsed = \DateTimeImmutable::createFromFormat('!Y-m-d', $normalized, new \DateTimeZone($this->timezone));
|
||||||
|
|
||||||
|
if (!$parsed instanceof \DateTimeImmutable) {
|
||||||
|
throw new \InvalidArgumentException('Invalid date format, expected YYYY-MM-DD.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $parsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function filled(?string $value): bool
|
||||||
|
{
|
||||||
|
return $value !== null && trim($value) !== '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -75,7 +75,20 @@ final readonly class OrderSummaryTool
|
||||||
return [
|
return [
|
||||||
'date' => [
|
'date' => [
|
||||||
'type' => 'string',
|
'type' => 'string',
|
||||||
'description' => '查询日期,格式如 2026/06/23-2026/06/23(起止日期用 - 连接)。不传默认当天。',
|
'description' => '兼容旧参数:后台接口日期范围,格式如 2026/06/23-2026/06/23。不建议 AI 优先传此字段;建议传 timePreset 或 custom + startDate/endDate。',
|
||||||
|
],
|
||||||
|
'timePreset' => [
|
||||||
|
'type' => 'string',
|
||||||
|
'description' => '推荐给 AI 使用的时间意图。支持:today(今天)、yesterday(昨天)、last_7_days(最近7天)、last_30_days(最近30天)、this_week(本周)、last_week(上周)、this_month(本月)、last_month(上月)、custom(自定义)。不传默认 today。',
|
||||||
|
'enum' => ['today', 'yesterday', 'last_7_days', 'last_30_days', 'this_week', 'last_week', 'this_month', 'last_month', 'custom'],
|
||||||
|
],
|
||||||
|
'startDate' => [
|
||||||
|
'type' => 'string',
|
||||||
|
'description' => '自定义开始日期,仅 timePreset=custom 时需要,格式 YYYY-MM-DD,例如 2026-06-01。',
|
||||||
|
],
|
||||||
|
'endDate' => [
|
||||||
|
'type' => 'string',
|
||||||
|
'description' => '自定义结束日期,仅 timePreset=custom 时需要,格式 YYYY-MM-DD,例如 2026-06-23。',
|
||||||
],
|
],
|
||||||
'status' => [
|
'status' => [
|
||||||
'type' => 'integer',
|
'type' => 'integer',
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue