qmai-cli-public 0.1.2 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -1
- package/package.json +2 -1
- package/skills/qmai-delivery/SKILL.md +52 -0
- package/skills/qmai-delivery/references/qmai-delivery-order.md +23 -0
- package/skills/qmai-delivery/references/qmai-delivery-status.md +19 -0
- package/skills/qmai-finance/SKILL.md +53 -0
- package/skills/qmai-finance/references/qmai-finance-statement.md +22 -0
- package/skills/qmai-finance/references/qmai-finance-stats.md +22 -0
- package/skills/qmai-inventory/SKILL.md +72 -0
- package/skills/qmai-inventory/references/qmai-inventory-master.md +29 -0
- package/skills/qmai-inventory/references/qmai-inventory-sales.md +25 -0
- package/skills/qmai-inventory/references/qmai-inventory-stock.md +29 -0
- package/skills/qmai-marketing/SKILL.md +80 -0
- package/skills/qmai-marketing/references/qmai-marketing-card-pricing.md +29 -0
- package/skills/qmai-marketing/references/qmai-marketing-coupon.md +27 -0
- package/skills/qmai-member/SKILL.md +175 -0
- package/skills/qmai-member/references/qmai-member-asset.md +35 -0
- package/skills/qmai-member/references/qmai-member-profile-tag.md +51 -0
- package/skills/qmai-order/SKILL.md +64 -0
- package/skills/qmai-order/references/qmai-order-query.md +26 -0
- package/skills/qmai-order/references/qmai-order-write.md +21 -0
- package/skills/qmai-product/SKILL.md +183 -0
- package/skills/qmai-product/references/qmai-product-advanced.md +92 -0
- package/skills/qmai-product/references/qmai-product-batch.md +113 -0
- package/skills/qmai-product/references/qmai-product-category.md +67 -0
- package/skills/qmai-product/references/qmai-product-crud.md +126 -0
- package/skills/qmai-queue/SKILL.md +38 -0
- package/skills/qmai-queue/references/qmai-queue-read.md +21 -0
- package/skills/qmai-shared/SKILL.md +155 -0
- package/skills/qmai-shared/references/qmai-shared-auth.md +54 -0
- package/skills/qmai-shared/references/qmai-shared-config.md +69 -0
- package/skills/qmai-store/SKILL.md +90 -0
- package/skills/qmai-store/references/qmai-store-read.md +45 -0
- package/skills/qmai-store/references/qmai-store-write.md +44 -0
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# 批量操作指南
|
|
2
|
+
|
|
3
|
+
## 批量导入(通过 Sync API)
|
|
4
|
+
|
|
5
|
+
### CSV 格式
|
|
6
|
+
|
|
7
|
+
首行表头,后续为数据行:
|
|
8
|
+
```csv
|
|
9
|
+
trade_name,trade_price,trade_no,class_name,stock
|
|
10
|
+
美式咖啡,28.00,P001,饮品,100
|
|
11
|
+
拿铁,32.00,P002,饮品,100
|
|
12
|
+
抹茶拿铁,35.00,P003,饮品,50
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
### JSON 格式
|
|
16
|
+
|
|
17
|
+
```json
|
|
18
|
+
[
|
|
19
|
+
{"tradeName": "美式咖啡", "tradePrice": 28.00, "tradeNo": "P001", "className": "饮品"},
|
|
20
|
+
{"tradeName": "拿铁", "tradePrice": 32.00, "tradeNo": "P002", "className": "饮品"}
|
|
21
|
+
]
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
> 用户只需提供 5 个字段,`Sync()` 方法会自动补全所有 API 必填字段(pictureUrlList、categoryList、skuList、saleTime 等)
|
|
25
|
+
|
|
26
|
+
### 导入命令
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
# 先预览
|
|
30
|
+
qmai product import --file products.csv --dry-run
|
|
31
|
+
|
|
32
|
+
# 确认后执行(调用 shopGoodsSync)
|
|
33
|
+
qmai product import --file products.csv
|
|
34
|
+
|
|
35
|
+
# 跳过错误行继续
|
|
36
|
+
qmai product import --file products.csv --skip-errors
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
> **注意**: Sync API 是异步的,导入成功后商品不会立即出现在列表中
|
|
40
|
+
|
|
41
|
+
## 批量导出
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
# 导出为 CSV
|
|
45
|
+
qmai product export --file backup.csv
|
|
46
|
+
|
|
47
|
+
# 导出为 JSON
|
|
48
|
+
qmai product export --file backup.json
|
|
49
|
+
|
|
50
|
+
# 按名称筛选
|
|
51
|
+
qmai product export --file drinks.csv --name 咖啡
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
导出 CSV 表头为: `id,name,price,status,inventory,category`
|
|
55
|
+
|
|
56
|
+
> 注意: 导出最多一次获取 50 条(API 分页限制)
|
|
57
|
+
|
|
58
|
+
## 批量调价
|
|
59
|
+
|
|
60
|
+
### 百分比调价
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
# 全品涨价 10%(先预览)
|
|
64
|
+
qmai product batch-price --adjust +10% --dry-run
|
|
65
|
+
|
|
66
|
+
# 降价 5%
|
|
67
|
+
qmai product batch-price --adjust -5%
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### 固定金额调价
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
# 所有商品涨 2 元
|
|
74
|
+
qmai product batch-price --adjust +2.00
|
|
75
|
+
|
|
76
|
+
# 降 1.5 元
|
|
77
|
+
qmai product batch-price --adjust -1.50
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Dry-run 输出示例
|
|
81
|
+
|
|
82
|
+
```
|
|
83
|
+
[dry-run] 将要调整 5 个商品价格:
|
|
84
|
+
美式咖啡: 28.00 → 30.80
|
|
85
|
+
拿铁: 32.00 → 35.20
|
|
86
|
+
卡布奇诺: 30.00 → 33.00
|
|
87
|
+
摩卡: 35.00 → 38.50
|
|
88
|
+
冰美式: 25.00 → 27.50
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
> 批量调价内部流程:先通过 List API 查询当前价格(单位:分,/100 转为元),计算新价格后通过 Sync API 更新
|
|
92
|
+
|
|
93
|
+
## 批量上下架
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
# 批量上架(调用 externalUp API)
|
|
97
|
+
qmai product batch-status --action up --trade-marks TM001,TM002 [--sale-channel 1]
|
|
98
|
+
|
|
99
|
+
# 批量下架(调用 externalDown API)
|
|
100
|
+
qmai product batch-status --action down --trade-marks TM001 --dry-run
|
|
101
|
+
|
|
102
|
+
# 预览
|
|
103
|
+
qmai product batch-status --action up --trade-marks TM001,TM002 --dry-run
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
> `--trade-marks` 的值来自商品 SKU 的 tradeMark 字段(可通过 `qmai product list --format json` 查看 goodsSkuList[].tradeMark)
|
|
107
|
+
|
|
108
|
+
## 安全建议
|
|
109
|
+
|
|
110
|
+
1. **操作前备份**: `qmai product export --file backup.json`
|
|
111
|
+
2. **先 Dry-run**: 所有批量操作先 `--dry-run` 预览
|
|
112
|
+
3. **调价不可撤回**: 价格修改后无法自动回滚,保留备份
|
|
113
|
+
4. **分步执行**: 大批量操作建议按分类分步执行
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# 分类管理
|
|
2
|
+
|
|
3
|
+
## 概述
|
|
4
|
+
|
|
5
|
+
开放平台的分类通过 `className` 字段在商品同步(Sync API)时自动关联,**无独立的分类 CRUD API**。
|
|
6
|
+
|
|
7
|
+
## 工作方式
|
|
8
|
+
|
|
9
|
+
1. 在创建/同步商品时通过 `--class` 参数或 CSV 的 `class_name` 列指定分类名称
|
|
10
|
+
2. `Sync()` 方法自动构建 `categoryList`,包含 `name`/`mark`/`categoryName`/`isRequired`/`isBackend`/`isFront`/`sort`/`type` 等必填字段
|
|
11
|
+
3. 平台会自动匹配已有分类或创建新分类
|
|
12
|
+
4. 分类信息可在商品列表返回结果的 `categoryNameList` 字段中查看
|
|
13
|
+
|
|
14
|
+
## Sync API 的分类结构
|
|
15
|
+
|
|
16
|
+
用户只需提供 `className`(字符串),代码自动生成完整的分类对象:
|
|
17
|
+
|
|
18
|
+
```json
|
|
19
|
+
{
|
|
20
|
+
"categoryList": [{
|
|
21
|
+
"name": "饮品",
|
|
22
|
+
"categoryName": "饮品",
|
|
23
|
+
"mark": "饮品",
|
|
24
|
+
"isRequired": 0,
|
|
25
|
+
"isBackend": 0,
|
|
26
|
+
"isFront": 0,
|
|
27
|
+
"sort": 0,
|
|
28
|
+
"type": 0
|
|
29
|
+
}]
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## 使用示例
|
|
34
|
+
|
|
35
|
+
### 同步时指定分类
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
# 创建商品时指定分类
|
|
39
|
+
qmai product create --name "美式咖啡" --price 28.00 --class 饮品
|
|
40
|
+
|
|
41
|
+
# 批量导入时在 CSV 中指定
|
|
42
|
+
trade_name,trade_price,trade_no,class_name,stock
|
|
43
|
+
美式咖啡,28.00,P001,饮品,100
|
|
44
|
+
拿铁,32.00,P002,饮品,100
|
|
45
|
+
三明治,15.00,P003,小食,50
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### 查看分类
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
# 列表中查看分类列
|
|
52
|
+
qmai product list
|
|
53
|
+
|
|
54
|
+
# JSON 输出查看分类
|
|
55
|
+
qmai product list --format json
|
|
56
|
+
|
|
57
|
+
# 分类提示命令
|
|
58
|
+
qmai product category
|
|
59
|
+
# → 提示: 通过 --class 参数在创建/同步时指定分类
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## 注意事项
|
|
63
|
+
|
|
64
|
+
- `className` 为字符串,平台按名称匹配
|
|
65
|
+
- 不支持分类的独立创建、删除、排序操作
|
|
66
|
+
- 修改商品分类 = 同步时传入新的 `className`
|
|
67
|
+
- 不指定分类时,`categoryList` 传空数组 `[]`
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# 商品增删改查操作指南
|
|
2
|
+
|
|
3
|
+
## 数据结构
|
|
4
|
+
|
|
5
|
+
### 列表返回 (OpenProduct)
|
|
6
|
+
|
|
7
|
+
| 字段 | 类型 | 说明 |
|
|
8
|
+
|------|------|------|
|
|
9
|
+
| id | int64 | 商品列表 ID |
|
|
10
|
+
| goodsId | int64 | 底层商品 ID |
|
|
11
|
+
| name | string | 商品名称 |
|
|
12
|
+
| status | int | 10=上架, 20=下架 |
|
|
13
|
+
| showPriceLow | int | 最低价(**单位:分**) |
|
|
14
|
+
| showPriceHigh | int | 最高价(**单位:分**) |
|
|
15
|
+
| saleChannel | int | 销售渠道: 1=堂食, 2=外卖, 11=堂食+外卖 |
|
|
16
|
+
| categoryNameList | []string | 分类名称数组 |
|
|
17
|
+
| goodsSkuList | []GoodsSku | SKU 列表 |
|
|
18
|
+
|
|
19
|
+
### SKU (GoodsSku)
|
|
20
|
+
|
|
21
|
+
| 字段 | 类型 | 说明 |
|
|
22
|
+
|------|------|------|
|
|
23
|
+
| skuId | string | SKU ID |
|
|
24
|
+
| tradeMark | string | 商品编码(用于上下架) |
|
|
25
|
+
| salePrice | float64 | 销售价(元) |
|
|
26
|
+
| inventory | float64 | 库存(API 可能返回 int 或 float) |
|
|
27
|
+
|
|
28
|
+
### 同步输入 (ShopGoods)
|
|
29
|
+
|
|
30
|
+
用户只需填写以下 5 个字段,`Sync()` 自动补全 20+ 个 API 必填字段:
|
|
31
|
+
|
|
32
|
+
| 字段 | 类型 | 说明 |
|
|
33
|
+
|------|------|------|
|
|
34
|
+
| tradeName | string | 商品名称(必填) |
|
|
35
|
+
| tradePrice | float64 | 价格(必填,> 0) |
|
|
36
|
+
| tradeNo | string | 商户自定义编号 |
|
|
37
|
+
| className | string | 分类名称 |
|
|
38
|
+
| stock | int | 库存(默认 9999) |
|
|
39
|
+
|
|
40
|
+
## 创建商品(通过 Sync API)
|
|
41
|
+
|
|
42
|
+
### 命令行方式
|
|
43
|
+
```bash
|
|
44
|
+
qmai product create --name "美式咖啡" --price 28.00 --trade-no P001 --class 饮品
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### JSON 文件方式
|
|
48
|
+
```bash
|
|
49
|
+
qmai product create --from-json goods.json
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
`goods.json` 示例(只需包含用户关心的字段):
|
|
53
|
+
```json
|
|
54
|
+
[
|
|
55
|
+
{"tradeName": "美式咖啡", "tradePrice": 28.00, "tradeNo": "P001", "className": "饮品"},
|
|
56
|
+
{"tradeName": "拿铁", "tradePrice": 32.00, "tradeNo": "P002", "className": "饮品"}
|
|
57
|
+
]
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Dry-run 预览
|
|
61
|
+
```bash
|
|
62
|
+
$ qmai product create --name "拿铁" --price 32.00 --dry-run
|
|
63
|
+
[dry-run] 将要同步 1 个商品:
|
|
64
|
+
拿铁 (32.00)
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
> **注意**: Sync API 是异步的,创建成功后商品不会立即出现在列表中
|
|
68
|
+
|
|
69
|
+
## 查询商品
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
# 全部商品(默认每页 20 条,最大 50)
|
|
73
|
+
qmai product list
|
|
74
|
+
|
|
75
|
+
# 按名称搜索
|
|
76
|
+
qmai product list --name 咖啡
|
|
77
|
+
|
|
78
|
+
# 按销售渠道
|
|
79
|
+
qmai product list --sale-channel 1
|
|
80
|
+
|
|
81
|
+
# 按类型
|
|
82
|
+
qmai product list --sale-type 1
|
|
83
|
+
|
|
84
|
+
# 分页
|
|
85
|
+
qmai product list --page 1 --page-size 50
|
|
86
|
+
|
|
87
|
+
# JSON 输出
|
|
88
|
+
qmai product list --format json
|
|
89
|
+
|
|
90
|
+
# 商品详情(按 ID 或名称)
|
|
91
|
+
qmai product get <id|name>
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### 列表输出示例
|
|
95
|
+
```
|
|
96
|
+
ID 名称 价格 状态 库存 分类
|
|
97
|
+
-- ------ ------ ------ ------ ------
|
|
98
|
+
1185299121892380796 桃花落拿铁 21.00 上架 9999 咖啡系列
|
|
99
|
+
1185299121892380733 春樱拿铁 21.00 上架 9999 咖啡系列
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## 更新商品(通过 Sync API)
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
# 改名(--name 必填)
|
|
106
|
+
qmai product update <tradeNo> --name "新品名" --price 35.00
|
|
107
|
+
|
|
108
|
+
# 改分类
|
|
109
|
+
qmai product update <tradeNo> --name "原名称" --class 饮品
|
|
110
|
+
|
|
111
|
+
# 多字段更新
|
|
112
|
+
qmai product update <tradeNo> --name "新品" --price 30.00 --class 小食
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## 下架商品
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
# 需要 --force 确认(通过 BatchDown API)
|
|
119
|
+
qmai product delete <tradeMark> --force --sale-channel 1
|
|
120
|
+
|
|
121
|
+
# 不带 --force 只提示
|
|
122
|
+
$ qmai product delete <tradeMark>
|
|
123
|
+
确定要下架商品 <tradeMark> 吗?使用 --force 确认
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
> 下架通过 BatchDown API 实现,将商品 status 从 10 改为 20
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: qmai-queue
|
|
3
|
+
version: 1.0.0
|
|
4
|
+
description: "排队服务:查询门店排队进度、订单排队进度和叫号列表"
|
|
5
|
+
metadata:
|
|
6
|
+
bins: [qmai]
|
|
7
|
+
help: "qmai queue --help"
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
> 前置条件: 请先阅读 ../qmai-shared/SKILL.md 了解认证和配置
|
|
11
|
+
|
|
12
|
+
## 核心概念
|
|
13
|
+
|
|
14
|
+
- **shop-progress**: 批量查询门店当前排队进度
|
|
15
|
+
- **order-progress**: 查询单笔订单的排队进度
|
|
16
|
+
- **shop-queue-nos**: 查询门店叫号列表
|
|
17
|
+
|
|
18
|
+
## 命令概览
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
qmai queue shop-progress --shop-type 1 --shop-ids 1001,1002
|
|
22
|
+
qmai queue order-progress --order-no O20260407001
|
|
23
|
+
qmai queue shop-queue-nos --shop-code S001 --page 1 --size 10
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## 开放平台 API 端点
|
|
27
|
+
|
|
28
|
+
| 操作 | 端点 |
|
|
29
|
+
| --- | --- |
|
|
30
|
+
| 查询门店排队进度 | POST /v3/queuing/queryShopQueueCup |
|
|
31
|
+
| 查询订单排队进度 | POST /v3/queuing/queryOrderQueueCup |
|
|
32
|
+
| 查询门店排队叫号列表 | POST /v3/queuing/queueNo/queryShopQueueNoList |
|
|
33
|
+
|
|
34
|
+
## 注意事项(Agent 必读)
|
|
35
|
+
|
|
36
|
+
- `shop-progress` 的 `shopIdList` 官方最多支持 20 个
|
|
37
|
+
- `shop-queue-nos` 的 `size` 官方限制在 1 到 20 之间
|
|
38
|
+
- 这个模块目前只有读接口,没有写操作
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# qmai-queue 查询参考
|
|
2
|
+
|
|
3
|
+
## 适用场景
|
|
4
|
+
|
|
5
|
+
- 查询门店当前排队压力
|
|
6
|
+
- 查询单笔订单还要等多久
|
|
7
|
+
- 查询门店当前叫号列表
|
|
8
|
+
|
|
9
|
+
## 推荐命令
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
qmai queue shop-progress --shop-type 1 --shop-ids 1001,1002
|
|
13
|
+
qmai queue order-progress --order-no O20260407001
|
|
14
|
+
qmai queue shop-queue-nos --shop-code S001 --page 1 --size 10
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## 排查建议
|
|
18
|
+
|
|
19
|
+
- `order-progress` 中 `order-no` 和 `source-no` 至少传一个,同时传时以 `order-no` 为准
|
|
20
|
+
- `shop-queue-nos` 默认可不传 `status-list`,官方会按待制作、制作中、待取餐查询
|
|
21
|
+
- 如果要保留完整原始字段,优先使用 `--format json`
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: qmai-shared
|
|
3
|
+
version: 3.0.0
|
|
4
|
+
description: "基础能力:开放平台认证、配置管理、安全规则、通用约定"
|
|
5
|
+
metadata:
|
|
6
|
+
bins: [qmai]
|
|
7
|
+
help: "qmai --help"
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## 概述
|
|
11
|
+
|
|
12
|
+
qmai CLI 是门店经营命令行工具。通过企迈开放平台 (`openapi.qmai.cn`) 管理门店商品、门店与组织、会员、营销、订单、财务、聚合配送、进销存和排队。本 Skill 描述认证、配置和安全相关的基础能力。
|
|
13
|
+
|
|
14
|
+
## 认证流程
|
|
15
|
+
|
|
16
|
+
### 凭证配置
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
qmai auth login [--profile <name>]
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
流程:
|
|
23
|
+
1. 交互式输入 openId、grantCode、openKey、shopCode
|
|
24
|
+
2. openKey 存入 OS keychain(敏感凭证)
|
|
25
|
+
3. openId/grantCode/shopCode 写入 config profile
|
|
26
|
+
4. 设为 active_profile
|
|
27
|
+
|
|
28
|
+
### 认证管理命令
|
|
29
|
+
|
|
30
|
+
| 命令 | 说明 |
|
|
31
|
+
|------|------|
|
|
32
|
+
| `qmai auth login` | 配置开放平台凭证 |
|
|
33
|
+
| `qmai auth logout` | 清除凭证(keychain + config) |
|
|
34
|
+
|
|
35
|
+
### 凭证存储
|
|
36
|
+
|
|
37
|
+
- **openKey**: macOS Keychain(service: `qmai-cli`),Linux: libsecret
|
|
38
|
+
- **openId/grantCode/shopCode**: `~/.config/qmai/config.yaml` profile 中
|
|
39
|
+
|
|
40
|
+
### 请求签名
|
|
41
|
+
|
|
42
|
+
每个 API 请求自动签名,无需手动操作:
|
|
43
|
+
1. 生成随机 nonce + 当前时间戳
|
|
44
|
+
2. 按字典序拼接 `grantCode=xx&nonce=xx&openId=xx×tamp=xx`
|
|
45
|
+
3. HmacSHA1(拼接串, openKey) → Base64 → URL Encode → token
|
|
46
|
+
4. 请求体: `{openId, grantCode, nonce, timestamp, token, params}`
|
|
47
|
+
|
|
48
|
+
## 配置管理
|
|
49
|
+
|
|
50
|
+
### 配置文件
|
|
51
|
+
|
|
52
|
+
位置:`~/.config/qmai/config.yaml`
|
|
53
|
+
|
|
54
|
+
```yaml
|
|
55
|
+
active_profile: default
|
|
56
|
+
default_format: table
|
|
57
|
+
debug: false
|
|
58
|
+
profiles:
|
|
59
|
+
default:
|
|
60
|
+
name: default
|
|
61
|
+
shop_code: "S001"
|
|
62
|
+
open_id: "d14c1559..."
|
|
63
|
+
grant_code: "ba67d4fa46"
|
|
64
|
+
store2:
|
|
65
|
+
name: store2
|
|
66
|
+
shop_code: "S002"
|
|
67
|
+
open_id: "..."
|
|
68
|
+
grant_code: "..."
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### 配置优先级
|
|
72
|
+
|
|
73
|
+
flags → profile 配置 → 默认值
|
|
74
|
+
|
|
75
|
+
### 配置命令
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
qmai config init # 交互式初始化
|
|
79
|
+
qmai config set <key> <val> # 设置配置项
|
|
80
|
+
qmai config get <key> # 读取配置项
|
|
81
|
+
qmai config list # 查看所有配置
|
|
82
|
+
qmai config profile add <name> --shop-code xxx # 添加 profile
|
|
83
|
+
qmai config profile remove <name> # 删除 profile
|
|
84
|
+
qmai config profile list # 列出 profiles
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## 输出格式
|
|
88
|
+
|
|
89
|
+
所有命令支持 `--format` flag:
|
|
90
|
+
|
|
91
|
+
| 格式 | 说明 |
|
|
92
|
+
|------|------|
|
|
93
|
+
| `table` | 对齐的文本表格(默认,终端友好) |
|
|
94
|
+
| `json` | JSON 输出(脚本友好) |
|
|
95
|
+
| `csv` | CSV 输出(Excel/导入友好) |
|
|
96
|
+
|
|
97
|
+
## Debug 模式
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
qmai product list --debug
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
启用后在 `Client.Call` 层输出完整日志(一行包含全部信息):
|
|
104
|
+
```
|
|
105
|
+
[DEBUG] POST <url> | req=<完整请求JSON> | resp=<完整响应JSON> | <耗时>ms
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
用于排查 API 对接问题,查看实际请求参数和响应结构。
|
|
109
|
+
|
|
110
|
+
## 安全规则(Agent 必读)
|
|
111
|
+
|
|
112
|
+
1. **openKey 安全**: openKey 仅存储在 OS keychain,不写入配置文件或日志
|
|
113
|
+
2. **不存储敏感信息**: config 中不保存 openKey
|
|
114
|
+
3. **Dry-run 优先**: 所有变更操作建议先使用 `--dry-run` 预览
|
|
115
|
+
4. **确认机制**: 删除/下架操作需要 `--force` 确认
|
|
116
|
+
5. **批量操作安全**: 批量操作前务必备份(`export`),建议先 `--dry-run`
|
|
117
|
+
|
|
118
|
+
## API 基础
|
|
119
|
+
|
|
120
|
+
- Base URL: `https://openapi.qmai.cn/`
|
|
121
|
+
- 协议: 全部 HTTP POST,Content-Type: application/json
|
|
122
|
+
- QPS 限制: 单接口最高 10
|
|
123
|
+
- 分页限制: pageSize 最大 50
|
|
124
|
+
- 认证: 请求体签名(自动注入)
|
|
125
|
+
- 响应格式:
|
|
126
|
+
```json
|
|
127
|
+
{
|
|
128
|
+
"status": true,
|
|
129
|
+
"code": 0,
|
|
130
|
+
"message": "请求成功",
|
|
131
|
+
"data": { ... },
|
|
132
|
+
"traceId": "..."
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## 可用命令
|
|
137
|
+
|
|
138
|
+
```
|
|
139
|
+
qmai
|
|
140
|
+
├── auth 认证管理
|
|
141
|
+
├── config 配置管理
|
|
142
|
+
├── product 商品管理
|
|
143
|
+
├── store 门店与组织管理
|
|
144
|
+
├── member 会员服务
|
|
145
|
+
├── marketing 营销服务
|
|
146
|
+
├── order 订单服务
|
|
147
|
+
├── finance 财务服务
|
|
148
|
+
├── delivery 聚合配送
|
|
149
|
+
├── inventory 进销存
|
|
150
|
+
├── queue 排队服务
|
|
151
|
+
├── api Raw API 请求透传
|
|
152
|
+
├── doctor 诊断检查
|
|
153
|
+
├── completion Shell 自动补全
|
|
154
|
+
└── version 版本信息
|
|
155
|
+
```
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# 开放平台认证详情
|
|
2
|
+
|
|
3
|
+
## 凭证配置流程
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
$ qmai auth login
|
|
7
|
+
请输入 openId: d14c1559e87b747d577c834b275a4310
|
|
8
|
+
请输入 grantCode: ba67d4fa46
|
|
9
|
+
请输入 openKey: LyvrkvkxRkG2R6aM55bXpPwjYAbkEXTbVnKwfDYvVHjNwNFAmx
|
|
10
|
+
请输入门店编码 (shopCode): S001
|
|
11
|
+
✓ 凭证已保存 (profile: default)
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## 凭证说明
|
|
15
|
+
|
|
16
|
+
| 凭证 | 说明 | 存储位置 |
|
|
17
|
+
|------|------|----------|
|
|
18
|
+
| openId | 开放平台应用 ID | config yaml |
|
|
19
|
+
| grantCode | 授权码 | config yaml |
|
|
20
|
+
| openKey | 签名密钥(敏感) | OS keychain |
|
|
21
|
+
| shopCode | 门店编码 | config yaml |
|
|
22
|
+
|
|
23
|
+
## 请求签名算法 (HmacSHA1)
|
|
24
|
+
|
|
25
|
+
1. 取 openId, grantCode, nonce, timestamp 四个字段
|
|
26
|
+
2. 按 key 字典序升序排列
|
|
27
|
+
3. 拼接为 `grantCode=xx&nonce=xx&openId=xx×tamp=xx`
|
|
28
|
+
4. HmacSHA1(拼接串, openKey) → Base64 → URL Encode
|
|
29
|
+
5. 得到 token,一次性使用
|
|
30
|
+
|
|
31
|
+
示例签名验证:
|
|
32
|
+
- openKey: `LyvrkvkxRkG2R6aM55bXpPwjYAbkEXTbVnKwfDYvVHjNwNFAmx`
|
|
33
|
+
- openId: `d14c1559e87b747d577c834b275a4310`
|
|
34
|
+
- grantCode: `ba67d4fa46`
|
|
35
|
+
- timestamp: `1465185768`, nonce: `11886`
|
|
36
|
+
- 期望 token: `cFw0t9IuvL9jVo9qAzk0qMcw5BM%3D`
|
|
37
|
+
|
|
38
|
+
## AES 加解密(敏感字段)
|
|
39
|
+
|
|
40
|
+
部分接口的敏感字段需要 AES 加密传输:
|
|
41
|
+
|
|
42
|
+
- 算法: AES-256/CBC/PKCS5Padding
|
|
43
|
+
- Key: MD5(openKey) → 32 hex chars 作为字节
|
|
44
|
+
- IV: MD5(openId)[8:24] → 16 hex chars 作为字节
|
|
45
|
+
|
|
46
|
+
## 多门店支持
|
|
47
|
+
|
|
48
|
+
每个 profile 独立存储凭证:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
qmai auth login --profile store1
|
|
52
|
+
qmai auth login --profile store2
|
|
53
|
+
qmai config set active_profile store1 # 切换到 store1
|
|
54
|
+
```
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# 配置管理详情
|
|
2
|
+
|
|
3
|
+
## 配置文件结构
|
|
4
|
+
|
|
5
|
+
```yaml
|
|
6
|
+
# ~/.config/qmai/config.yaml
|
|
7
|
+
active_profile: default
|
|
8
|
+
default_format: table # json | table | csv
|
|
9
|
+
debug: false
|
|
10
|
+
|
|
11
|
+
profiles:
|
|
12
|
+
default:
|
|
13
|
+
name: default
|
|
14
|
+
shop_code: "S001"
|
|
15
|
+
open_id: "d14c1559e87b747d577c834b275a4310"
|
|
16
|
+
grant_code: "ba67d4fa46"
|
|
17
|
+
base_url: "" # 空则使用默认值
|
|
18
|
+
|
|
19
|
+
test-store:
|
|
20
|
+
name: test-store
|
|
21
|
+
shop_code: "S002"
|
|
22
|
+
open_id: "..."
|
|
23
|
+
grant_code: "..."
|
|
24
|
+
base_url: "https://openapi.qmai.co/" # 沙箱环境
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## 初始化流程
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
$ qmai config init
|
|
31
|
+
qmai CLI 配置初始化
|
|
32
|
+
------------------------------
|
|
33
|
+
Profile 名称 (default): my-store
|
|
34
|
+
门店编码 shopCode (可选): S001
|
|
35
|
+
API Base URL (https://openapi.qmai.cn/):
|
|
36
|
+
默认输出格式 [table/json/csv] (table): json
|
|
37
|
+
|
|
38
|
+
✓ 配置已保存到 ~/.config/qmai/config.yaml
|
|
39
|
+
Active profile: my-store
|
|
40
|
+
|
|
41
|
+
下一步: 运行 'qmai auth login' 配置开放平台凭证
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## 配置键列表
|
|
45
|
+
|
|
46
|
+
| 键 | 说明 | 默认值 |
|
|
47
|
+
|---|------|--------|
|
|
48
|
+
| `active_profile` | 当前活动 profile | `default` |
|
|
49
|
+
| `default_format` | 默认输出格式 | `table` |
|
|
50
|
+
| `debug` | 调试模式 | `false` |
|
|
51
|
+
| `base_url` | API 基础 URL(per profile) | `https://openapi.qmai.cn/` |
|
|
52
|
+
| `shop_code` | 门店编码(per profile) | - |
|
|
53
|
+
| `open_id` | 开放平台 openId(per profile) | - |
|
|
54
|
+
| `grant_code` | 开放平台 grantCode(per profile) | - |
|
|
55
|
+
|
|
56
|
+
## Profile 管理
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
# 添加 profile
|
|
60
|
+
qmai config profile add new-store --shop-code S003 --base-url https://...
|
|
61
|
+
|
|
62
|
+
# 列出所有 profiles
|
|
63
|
+
qmai config profile list
|
|
64
|
+
# * default (shop: S001)
|
|
65
|
+
# test-store (shop: S002) [https://openapi.qmai.co/]
|
|
66
|
+
|
|
67
|
+
# 删除 profile
|
|
68
|
+
qmai config profile remove test-store
|
|
69
|
+
```
|