@youzan-cloud/zan-saas-cli 0.1.0-beta.4 → 0.1.0-beta.8
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/bin/zan-saas-cli.js +8 -11
- package/internal/registry/manifest.json +25 -20
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
- package/skills/zan-saas/SKILL.md +3 -3
- package/skills/zan-saas/references/host-entry.md +8 -0
- package/skills/zan-saas-order/SKILL.md +12 -1
- package/skills/zan-saas-order/references/branch-counts.md +45 -0
- package/skills/zan-saas-order/references/order-get.md +2 -0
- package/skills/zan-saas-order/references/order-list.md +2 -0
- package/skills/zan-saas-order/references/order-scan.md +2 -0
- package/skills/zan-saas-org/SKILL.md +6 -0
- package/skills/zan-saas-org/references/unit-list.md +2 -0
- package/skills/zan-saas-shared/SKILL.md +20 -5
- package/skills/zan-saas-shared/references/authentication.md +9 -4
- package/skills/zan-saas-shared/references/gateway-errors.md +29 -0
- package/skills/zan-saas-shared/references/shop-context.md +39 -0
- package/skills/zan-saas-valuecard/SKILL.md +8 -2
- package/skills/zan-saas-valuecard/references/transaction-list.md +25 -0
- package/skills/zan-saas-valuecard/references/transaction-scan.md +23 -0
- package/src/auth/credential-source.js +26 -0
- package/src/auth/credential-store.js +61 -5
- package/src/auth/session.js +80 -27
- package/src/cli/command-paths.js +3 -2
- package/src/cli/context-help.js +3 -1
- package/src/cli/program.js +20 -4
- package/src/commands/native/access/commands.index.json +1 -1
- package/src/commands/native/access/role/list/command.js +4 -32
- package/src/commands/native/customer/commands.index.json +1 -1
- package/src/commands/native/customer/customer-tag/list/command.js +2 -2
- package/src/commands/native/member/commands.index.json +1 -1
- package/src/commands/native/order/commands.index.json +3 -3
- package/src/commands/native/order/order/get/command.js +14 -9
- package/src/commands/native/order/order/get/schema.json +197 -41
- package/src/commands/native/order/order/list/command.js +9 -6
- package/src/commands/native/order/order/list/schema.json +140 -10
- package/src/commands/native/order/order/scan/command.js +8 -5
- package/src/commands/native/order/order/scan/scan.js +1 -1
- package/src/commands/native/order/order/scan/schema.json +135 -8
- package/src/commands/native/order/shared/query.js +57 -9
- package/src/commands/native/order/shared/search.js +1 -1
- package/src/commands/native/org/commands.index.json +4 -4
- package/src/commands/native/valuecard/commands.index.json +20 -2
- package/src/commands/native/valuecard/domain.json +1 -1
- package/src/commands/native/valuecard/transaction/list/command.js +110 -0
- package/src/commands/native/valuecard/transaction/list/projection.js +71 -0
- package/src/commands/native/valuecard/transaction/list/schema.json +888 -0
- package/src/commands/native/valuecard/transaction/scan/command.js +130 -0
- package/src/commands/native/valuecard/transaction/scan/projection.js +58 -0
- package/src/commands/native/valuecard/transaction/scan/scan.js +70 -0
- package/src/commands/native/valuecard/transaction/scan/schema.json +954 -0
- package/src/commands/system/api.js +1 -1
- package/src/commands/system/auth.js +13 -2
- package/src/commands/system/contracts.js +27 -19
- package/src/commands/system/shop-contracts.js +97 -0
- package/src/commands/system/shop.js +128 -27
- package/src/execution/error-details.js +13 -18
- package/src/execution/gateway-guidance.js +43 -0
- package/src/execution/shop-query.js +6 -3
- package/src/identity/context-store.js +14 -10
- package/src/identity/file-store.js +147 -0
- package/src/identity/session-store.js +261 -0
- package/src/identity/shop-location.js +158 -0
- package/src/identity/unit-membership.js +42 -0
- package/src/transport/api.js +78 -11
- package/src/transport/shop-app.js +8 -1
|
@@ -10,7 +10,7 @@ const { readContext } = require('../../../../../identity/context');
|
|
|
10
10
|
const { queryDefinition, validateCommandValue } = require('../../../../../execution/command-schema');
|
|
11
11
|
const { object } = require('../../../../../execution/query-api');
|
|
12
12
|
const { discloseFields, validReason } = require('../../../../../execution/privacy');
|
|
13
|
-
const {
|
|
13
|
+
const { bindingPreview, targetScope, createOrderQuery, reject, serialize } = require('../../shared/query');
|
|
14
14
|
const projection = require('../../shared/projection');
|
|
15
15
|
const schema = require('./schema.json');
|
|
16
16
|
|
|
@@ -43,9 +43,9 @@ function normalizedInput(options, target) {
|
|
|
43
43
|
return input;
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
function preview(input) {
|
|
46
|
+
function preview(input, context) {
|
|
47
47
|
const result = { requests: [
|
|
48
|
-
|
|
48
|
+
...bindingPreview(input.scope, context),
|
|
49
49
|
{ method: 'POST', path: schema.api.path, body: { tid: input.scope.orderNo } }
|
|
50
50
|
] };
|
|
51
51
|
if (input.decrypt) result.privacy = {
|
|
@@ -96,12 +96,14 @@ function createCommand({ context, privacyProvider } = {}) {
|
|
|
96
96
|
.option('--reason <text>', '仅解密时必填:1 至 200 个 Unicode 码点,无控制字符或换行,不含个人信息')
|
|
97
97
|
.addOption(new Option('--format <format>', 'json 或 pretty,仅改变缩进')
|
|
98
98
|
.choices(['json', 'pretty']).default('json'))
|
|
99
|
-
.option('--dry-run', '
|
|
99
|
+
.option('--dry-run', '纯本地校验和条件请求计划,不读凭证、不联网')
|
|
100
100
|
.addHelpText('after', `
|
|
101
101
|
固定返回 data.order、items、payment,include 只能追加模块,不能移除基础视图。
|
|
102
102
|
订单号通常为 E/V/C 开头加 23 位数字,仅供核对;不按该格式拒绝输入或响应,不改写订单号。
|
|
103
|
-
|
|
104
|
-
|
|
103
|
+
省略 --kdt-id 只查 context.shopId,总部默认只查总部本身,不含分店。非总部目标须等于 context.shopId。
|
|
104
|
+
总部普通读取可显式指定同连锁门店或网店,先核实总部sid及角色、下级目录成员,再绑定分店sid;已返回的总部字段须一致。查询不保存位置。
|
|
105
|
+
同店最多两请求;总部显式分店含总部1次、目录每页50条最多20页、分店绑定1次、详情1次,共最多23次,均计入累计响应预算。
|
|
106
|
+
目录读完未命中与预算内未读完分别拒绝;接口拒绝、字段异常与归属冲突保留实际阶段。不初始化分店应用,不重试;执行需要有效四字段上下文。
|
|
105
107
|
ID 输出十进制字符串,交易行 oid 不是商品 ID。元金额仅无损补齐两位,不再除以 100。
|
|
106
108
|
payment 是整单应付,realPayment 是实付,不扣退款或推导到账;按用户确认默认以 CNY 计价。
|
|
107
109
|
基础 order 可返回支付时间 paidAt 和支付标记 isPaid;缺失不推断,零实付不等于未支付。
|
|
@@ -123,7 +125,10 @@ payment 是整单应付,realPayment 是实付,不扣退款或推导到账;
|
|
|
123
125
|
.action(async options => {
|
|
124
126
|
const state = readContext(context);
|
|
125
127
|
const input = buildInput(options, context);
|
|
126
|
-
|
|
128
|
+
if (input.decrypt && state.status === 'ready' && input.scope.kdtId !== state.context.shopId) {
|
|
129
|
+
throw reject(command, 'permission', 'sensitive-authorization', input.scope);
|
|
130
|
+
}
|
|
131
|
+
const plan = preview(input, state.context);
|
|
127
132
|
let output = plan;
|
|
128
133
|
if (!input.dryRun) {
|
|
129
134
|
if (input.decrypt) {
|
|
@@ -142,8 +147,8 @@ payment 是整单应付,realPayment 是实付,不扣退款或推导到账;
|
|
|
142
147
|
});
|
|
143
148
|
output = disclosedOutput(result, input, state.context, sourceFacts);
|
|
144
149
|
} else {
|
|
145
|
-
const read = await createOrderQuery(input.scope, command, { shopApp: false });
|
|
146
|
-
const request = plan.requests
|
|
150
|
+
const read = await createOrderQuery(input.scope, command, { shopApp: false, context: state.context });
|
|
151
|
+
const request = plan.requests.at(-1);
|
|
147
152
|
const { data, facts } = await read(request.path, request.body);
|
|
148
153
|
output = adapt(data, input, state.context, facts);
|
|
149
154
|
}
|
|
@@ -179,61 +179,112 @@
|
|
|
179
179
|
"description": "仅显式解密时出现。只列字段和调用上限,不含用途、凭证或密文,不表示权限已通过。"
|
|
180
180
|
},
|
|
181
181
|
"requests": {
|
|
182
|
-
"
|
|
183
|
-
"
|
|
184
|
-
"maxItems": 2,
|
|
185
|
-
"additionalItems": false,
|
|
186
|
-
"items": [
|
|
182
|
+
"description": "同店保留原计划;总部显式分店先核实总部、在其目录中有界核实成员、绑定分店,再读订单。目录项展示第一页模板,最多20页,不表示已核实。",
|
|
183
|
+
"anyOf": [
|
|
187
184
|
{
|
|
188
|
-
"type": "
|
|
189
|
-
"
|
|
190
|
-
"
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
"
|
|
185
|
+
"type": "array",
|
|
186
|
+
"minItems": 2,
|
|
187
|
+
"maxItems": 2,
|
|
188
|
+
"additionalItems": false,
|
|
189
|
+
"items": [
|
|
190
|
+
{
|
|
191
|
+
"type": "object",
|
|
192
|
+
"additionalProperties": false,
|
|
193
|
+
"properties": {
|
|
194
|
+
"method": {
|
|
195
|
+
"const": "POST"
|
|
196
|
+
},
|
|
197
|
+
"path": {
|
|
198
|
+
"const": "youzan.shop.basic.get/3.0.0"
|
|
199
|
+
},
|
|
200
|
+
"body": {
|
|
201
|
+
"type": "object",
|
|
202
|
+
"additionalProperties": false,
|
|
203
|
+
"properties": {},
|
|
204
|
+
"required": []
|
|
205
|
+
}
|
|
206
|
+
},
|
|
207
|
+
"required": [
|
|
208
|
+
"method",
|
|
209
|
+
"path",
|
|
210
|
+
"body"
|
|
211
|
+
]
|
|
196
212
|
},
|
|
197
|
-
|
|
213
|
+
{
|
|
198
214
|
"type": "object",
|
|
199
215
|
"additionalProperties": false,
|
|
200
|
-
"properties": {
|
|
201
|
-
|
|
216
|
+
"properties": {
|
|
217
|
+
"method": {
|
|
218
|
+
"const": "POST"
|
|
219
|
+
},
|
|
220
|
+
"path": {
|
|
221
|
+
"const": "youzan.trade.get/4.0.2"
|
|
222
|
+
},
|
|
223
|
+
"body": {
|
|
224
|
+
"type": "object",
|
|
225
|
+
"additionalProperties": false,
|
|
226
|
+
"properties": {
|
|
227
|
+
"tid": {
|
|
228
|
+
"$ref": "#/definitions/orderNo"
|
|
229
|
+
}
|
|
230
|
+
},
|
|
231
|
+
"required": [
|
|
232
|
+
"tid"
|
|
233
|
+
]
|
|
234
|
+
}
|
|
235
|
+
},
|
|
236
|
+
"required": [
|
|
237
|
+
"method",
|
|
238
|
+
"path",
|
|
239
|
+
"body"
|
|
240
|
+
]
|
|
202
241
|
}
|
|
203
|
-
},
|
|
204
|
-
"required": [
|
|
205
|
-
"method",
|
|
206
|
-
"path",
|
|
207
|
-
"body"
|
|
208
242
|
]
|
|
209
243
|
},
|
|
210
244
|
{
|
|
211
|
-
"type": "
|
|
212
|
-
"
|
|
213
|
-
"
|
|
214
|
-
|
|
215
|
-
|
|
245
|
+
"type": "array",
|
|
246
|
+
"minItems": 4,
|
|
247
|
+
"maxItems": 4,
|
|
248
|
+
"additionalItems": false,
|
|
249
|
+
"items": [
|
|
250
|
+
{
|
|
251
|
+
"$ref": "#/definitions/headquartersBindingRequest"
|
|
216
252
|
},
|
|
217
|
-
|
|
218
|
-
"
|
|
253
|
+
{
|
|
254
|
+
"$ref": "#/definitions/membershipRequest"
|
|
255
|
+
},
|
|
256
|
+
{
|
|
257
|
+
"$ref": "#/definitions/targetBindingRequest"
|
|
219
258
|
},
|
|
220
|
-
|
|
259
|
+
{
|
|
221
260
|
"type": "object",
|
|
222
261
|
"additionalProperties": false,
|
|
223
262
|
"properties": {
|
|
224
|
-
"
|
|
225
|
-
"
|
|
263
|
+
"method": {
|
|
264
|
+
"const": "POST"
|
|
265
|
+
},
|
|
266
|
+
"path": {
|
|
267
|
+
"const": "youzan.trade.get/4.0.2"
|
|
268
|
+
},
|
|
269
|
+
"body": {
|
|
270
|
+
"type": "object",
|
|
271
|
+
"additionalProperties": false,
|
|
272
|
+
"properties": {
|
|
273
|
+
"tid": {
|
|
274
|
+
"$ref": "#/definitions/orderNo"
|
|
275
|
+
}
|
|
276
|
+
},
|
|
277
|
+
"required": [
|
|
278
|
+
"tid"
|
|
279
|
+
]
|
|
226
280
|
}
|
|
227
281
|
},
|
|
228
282
|
"required": [
|
|
229
|
-
"
|
|
283
|
+
"method",
|
|
284
|
+
"path",
|
|
285
|
+
"body"
|
|
230
286
|
]
|
|
231
287
|
}
|
|
232
|
-
},
|
|
233
|
-
"required": [
|
|
234
|
-
"method",
|
|
235
|
-
"path",
|
|
236
|
-
"body"
|
|
237
288
|
]
|
|
238
289
|
}
|
|
239
290
|
]
|
|
@@ -308,7 +359,9 @@
|
|
|
308
359
|
"ciphertext-verification",
|
|
309
360
|
"decryption",
|
|
310
361
|
"sensitive-audit",
|
|
311
|
-
"output-model"
|
|
362
|
+
"output-model",
|
|
363
|
+
"headquarters-binding",
|
|
364
|
+
"target-membership"
|
|
312
365
|
]
|
|
313
366
|
},
|
|
314
367
|
"command": {
|
|
@@ -1075,6 +1128,106 @@
|
|
|
1075
1128
|
"description": "本地已进入发送边界的观测次数下界,不是服务端执行次数。"
|
|
1076
1129
|
}
|
|
1077
1130
|
}
|
|
1131
|
+
},
|
|
1132
|
+
"headquartersBindingRequest": {
|
|
1133
|
+
"type": "object",
|
|
1134
|
+
"additionalProperties": false,
|
|
1135
|
+
"properties": {
|
|
1136
|
+
"method": {
|
|
1137
|
+
"const": "POST"
|
|
1138
|
+
},
|
|
1139
|
+
"path": {
|
|
1140
|
+
"const": "youzan.shop.basic.get/3.0.0"
|
|
1141
|
+
},
|
|
1142
|
+
"body": {
|
|
1143
|
+
"type": "object",
|
|
1144
|
+
"additionalProperties": false,
|
|
1145
|
+
"properties": {},
|
|
1146
|
+
"required": []
|
|
1147
|
+
},
|
|
1148
|
+
"stage": {
|
|
1149
|
+
"const": "headquarters-binding"
|
|
1150
|
+
},
|
|
1151
|
+
"kdtId": {
|
|
1152
|
+
"$ref": "#/definitions/shopId"
|
|
1153
|
+
}
|
|
1154
|
+
},
|
|
1155
|
+
"required": [
|
|
1156
|
+
"method",
|
|
1157
|
+
"path",
|
|
1158
|
+
"body",
|
|
1159
|
+
"stage",
|
|
1160
|
+
"kdtId"
|
|
1161
|
+
]
|
|
1162
|
+
},
|
|
1163
|
+
"targetBindingRequest": {
|
|
1164
|
+
"type": "object",
|
|
1165
|
+
"additionalProperties": false,
|
|
1166
|
+
"properties": {
|
|
1167
|
+
"method": {
|
|
1168
|
+
"const": "POST"
|
|
1169
|
+
},
|
|
1170
|
+
"path": {
|
|
1171
|
+
"const": "youzan.shop.basic.get/3.0.0"
|
|
1172
|
+
},
|
|
1173
|
+
"body": {
|
|
1174
|
+
"type": "object",
|
|
1175
|
+
"additionalProperties": false,
|
|
1176
|
+
"properties": {},
|
|
1177
|
+
"required": []
|
|
1178
|
+
},
|
|
1179
|
+
"stage": {
|
|
1180
|
+
"const": "shop-binding"
|
|
1181
|
+
},
|
|
1182
|
+
"kdtId": {
|
|
1183
|
+
"$ref": "#/definitions/shopId"
|
|
1184
|
+
}
|
|
1185
|
+
},
|
|
1186
|
+
"required": [
|
|
1187
|
+
"method",
|
|
1188
|
+
"path",
|
|
1189
|
+
"body",
|
|
1190
|
+
"stage",
|
|
1191
|
+
"kdtId"
|
|
1192
|
+
]
|
|
1193
|
+
},
|
|
1194
|
+
"membershipRequest": {
|
|
1195
|
+
"type": "object",
|
|
1196
|
+
"additionalProperties": false,
|
|
1197
|
+
"properties": {
|
|
1198
|
+
"method": {
|
|
1199
|
+
"const": "POST"
|
|
1200
|
+
},
|
|
1201
|
+
"path": {
|
|
1202
|
+
"const": "youzan.shop.chain.descendent.organization.list/1.0.1"
|
|
1203
|
+
},
|
|
1204
|
+
"body": {
|
|
1205
|
+
"const": {
|
|
1206
|
+
"page_num": 1,
|
|
1207
|
+
"page_size": 50,
|
|
1208
|
+
"with_dept_info": false,
|
|
1209
|
+
"with_shop_status_and_lifecycle_end_time": false,
|
|
1210
|
+
"with_crm_shop": false
|
|
1211
|
+
}
|
|
1212
|
+
},
|
|
1213
|
+
"stage": {
|
|
1214
|
+
"const": "target-membership"
|
|
1215
|
+
},
|
|
1216
|
+
"kdtId": {
|
|
1217
|
+
"$ref": "#/definitions/shopId"
|
|
1218
|
+
},
|
|
1219
|
+
"maxPages": {
|
|
1220
|
+
"const": 20
|
|
1221
|
+
}
|
|
1222
|
+
},
|
|
1223
|
+
"required": [
|
|
1224
|
+
"method",
|
|
1225
|
+
"path",
|
|
1226
|
+
"body",
|
|
1227
|
+
"stage",
|
|
1228
|
+
"kdtId",
|
|
1229
|
+
"maxPages"
|
|
1230
|
+
]
|
|
1078
1231
|
}
|
|
1079
1232
|
},
|
|
1080
1233
|
"modules": {
|
|
@@ -1153,8 +1306,8 @@
|
|
|
1153
1306
|
"notes": [
|
|
1154
1307
|
"--kdt-id 省略时使用本次有效上下文 shopId;显式提供的非法值不回退。两者都缺失时拒绝;目标范围、同店核验和服务端权限仍按本命令校验。",
|
|
1155
1308
|
"订单号通常为 E/V/C 开头加 23 位数字,仅供核对,不限定前缀、数字组合或 24 位长度;按原值传递。仅保留非空、无空白或控制字符和最多 128 字符的文本保护;服务端仍判断支持范围和对象归属。",
|
|
1156
|
-
"必须提供 --order-no;--kdt-id 省略时使用当前上下文店铺,显式非法值不回退;非总部目标须等于 context.shopId
|
|
1157
|
-
"输出 ID 是字符串;只有请求适配在安全范围转为 number。include
|
|
1309
|
+
"必须提供 --order-no;--kdt-id 省略时使用当前上下文店铺,显式非法值不回退;非总部目标须等于 context.shopId;总部普通读取支持经本次目录核验的同连锁显式分店目标,不保存位置;at:all 不免除核验。",
|
|
1310
|
+
"输出 ID 是字符串;只有请求适配在安全范围转为 number。include 仅投影,同店普通读取最多两请求,无关联详情或重试;总部显式分店增加有界成员前置。显式 decrypt 时最多四次有赞业务请求,禁用 1106 自动初始化及重发。",
|
|
1158
1311
|
"累计业务响应 10MiB、最终序列化 UTF-8 输出含换行 5MiB,超限整体失败;不承诺全链路恒定内存。",
|
|
1159
1312
|
"默认不主动解密。decrypt 仅收货姓名、联系方式和详细地址,必须 include address 并提供 reason。打星值不能恢复;字段缺失、空值或平台未确认为密文均整体拒绝。所有选定字段和可靠审计完成后才原位输出;失败 stdout 为空。",
|
|
1160
1313
|
"当前安装版尚未接通可信员工字段授权、来源绑定和可靠审计服务,实际解密拒绝,不能以应用 token、订单读取成功或本地上下文代替;普通读取与离线预览不受影响。",
|
|
@@ -1162,6 +1315,9 @@
|
|
|
1162
1315
|
"本地上下文与查询成功不替代服务端业务授权或权限隔离验证。",
|
|
1163
1316
|
"本批默认以 CNY 计价,金额保留两位小数字符串,不新增币种字段或换汇;该默认不用于确认上游逐订单币种或跨币种结算事实。",
|
|
1164
1317
|
"商品行 item_id/sku_id 为OneID,channel_item_id/channel_sku_id 为历史渠道身份;oid仍为交易行,不用当前档案重写历史。",
|
|
1165
|
-
"历史统一商品或规格字段为空字符串时,省略对应OneID并保留明确渠道身份,不用渠道ID补造;null和其他错型仍失败。"
|
|
1318
|
+
"历史统一商品或规格字段为空字符串时,省略对应OneID并保留明确渠道身份,不用渠道ID补造;null和其他错型仍失败。",
|
|
1319
|
+
"省略 --kdt-id 只查 context.shopId,总部默认仅总部本身,不包含分店。总部显式分店目标先核验总部角色及sid,再查下级组织目录,最后绑定分店sid;已返回的总部字段必须一致。查询不保存位置,不扩大解密权限。",
|
|
1320
|
+
"成员核验每页50条、最多20页。目录完整未命中为permission,未读完为scope_unresolved,字段异常为protocol;接口拒绝保留阶段与安全诊断。空订单也不能绕过前置。新增请求共享累计响应预算,同店请求保持兼容。",
|
|
1321
|
+
"总部显式分店最多23次业务请求,含总部1次、目录最多20次、分店绑定1次、订单1次;前置失败不发订单,不初始化分店应用,不重试。"
|
|
1166
1322
|
]
|
|
1167
1323
|
}
|
|
@@ -10,7 +10,7 @@ const { readContext } = require('../../../../../identity/context');
|
|
|
10
10
|
const { parseDateTime } = require('../../../../../execution/datetime');
|
|
11
11
|
const { parseDateTimeRange } = require('../../../../../execution/range');
|
|
12
12
|
const { queryDefinition, validateCommandValue } = require('../../../../../execution/command-schema');
|
|
13
|
-
const {
|
|
13
|
+
const { bindingPreview, targetScope, reject, serialize } = require('../../shared/query');
|
|
14
14
|
const { toRequestBody, toPreviewBody, adaptPage: adapt, createOrderPageReader } = require('../../shared/search');
|
|
15
15
|
const schema = require('./schema.json');
|
|
16
16
|
|
|
@@ -156,9 +156,9 @@ function normalizedInput(options, target) {
|
|
|
156
156
|
return input;
|
|
157
157
|
}
|
|
158
158
|
|
|
159
|
-
function preview(input) {
|
|
159
|
+
function preview(input, context) {
|
|
160
160
|
const result = { requests: [
|
|
161
|
-
|
|
161
|
+
...bindingPreview(input.scope, context),
|
|
162
162
|
{ method: 'POST', path: listPath, body: toPreviewBody(input) }
|
|
163
163
|
] };
|
|
164
164
|
validateCommandValue(schema, 'preview', result);
|
|
@@ -195,11 +195,14 @@ function createCommand({ context } = {}) {
|
|
|
195
195
|
.option('--page-size <n>', '每页条数,1 至 100', '20')
|
|
196
196
|
.addOption(new Option('--format <format>', 'json 或 pretty,仅改变缩进')
|
|
197
197
|
.choices(['json', 'pretty']).default('json'))
|
|
198
|
-
.option('--dry-run', '
|
|
198
|
+
.option('--dry-run', '纯本地条件计划,收货电话、姓名及关键词全部遮盖为 ***;不读凭证、不联网')
|
|
199
199
|
.addHelpText('after', `
|
|
200
200
|
商品行 item_id/sku_id 是OneID,channel_item_id/channel_sku_id 为历史渠道身份。
|
|
201
201
|
--item-id沿用统一商品筛选,不把上游goods_id机械视为旧item_id,不增加渠道映射查询。
|
|
202
|
-
|
|
202
|
+
省略 --kdt-id 只查 context.shopId,总部默认只查总部本身,不含分店;非总部不可跨店。
|
|
203
|
+
总部可显式指定同连锁门店或网店,先核实总部、目录成员、分店sid及已返回的总部字段,不保存新位置。
|
|
204
|
+
同店核验及列表共两请求;总部显式分店目录每页50条最多20页,总请求最多23次,均计入累计响应预算,不初始化分店应用或重试。
|
|
205
|
+
至少提供一个明确筛选条件;一次只读取一页,最多一次列表请求,默认第1页20条,页码和每页条数上限100。只查数量时第1页、每页1条且不追加模块,以可靠pagination.total计数,缺失不补零。
|
|
203
206
|
订单号通常为 E/V/C 开头加 23 位数字,仅供核对;不按该格式拒绝筛选值或返回订单,不改写订单号。
|
|
204
207
|
基础每行固定返回 order,include 可追加 items、payment、buyer、address、remark、source、aftersale、fulfillment。
|
|
205
208
|
order 默认含可取得的 paidAt/isPaid,不需 include payment;缺失不表示未支付,不从状态或金额推算。
|
|
@@ -214,7 +217,7 @@ order 默认含可取得的 paidAt/isPaid,不需 include payment;缺失不
|
|
|
214
217
|
.action(async options => {
|
|
215
218
|
const state = readContext(context);
|
|
216
219
|
const input = buildInput(options, context);
|
|
217
|
-
const plan = preview(input);
|
|
220
|
+
const plan = preview(input, state.context);
|
|
218
221
|
let output = plan;
|
|
219
222
|
if (!input.dryRun) {
|
|
220
223
|
const readPage = await createOrderPageReader(input.scope, state.context, command);
|
|
@@ -225,19 +225,44 @@
|
|
|
225
225
|
},
|
|
226
226
|
"preview": {
|
|
227
227
|
"type": "object",
|
|
228
|
-
"description": "
|
|
228
|
+
"description": "纯本地条件请求计划;receiver_phone、receiver_name、keywords 若存在均替换为 ***。不读取凭证、不联网,不修改规范化输入或实际请求筛选。",
|
|
229
229
|
"additionalProperties": false,
|
|
230
230
|
"properties": {
|
|
231
231
|
"requests": {
|
|
232
|
-
"
|
|
233
|
-
"
|
|
234
|
-
"maxItems": 2,
|
|
235
|
-
"items": [
|
|
232
|
+
"description": "同店保留原计划;总部显式分店先核实总部、在其目录中有界核实成员、绑定分店,再读订单。目录项展示第一页模板,最多20页,不表示已核实。",
|
|
233
|
+
"anyOf": [
|
|
236
234
|
{
|
|
237
|
-
"
|
|
235
|
+
"type": "array",
|
|
236
|
+
"minItems": 2,
|
|
237
|
+
"maxItems": 2,
|
|
238
|
+
"items": [
|
|
239
|
+
{
|
|
240
|
+
"$ref": "#/definitions/bindingRequest"
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
"$ref": "#/definitions/listRequest"
|
|
244
|
+
}
|
|
245
|
+
]
|
|
238
246
|
},
|
|
239
247
|
{
|
|
240
|
-
"
|
|
248
|
+
"type": "array",
|
|
249
|
+
"minItems": 4,
|
|
250
|
+
"maxItems": 4,
|
|
251
|
+
"additionalItems": false,
|
|
252
|
+
"items": [
|
|
253
|
+
{
|
|
254
|
+
"$ref": "#/definitions/headquartersBindingRequest"
|
|
255
|
+
},
|
|
256
|
+
{
|
|
257
|
+
"$ref": "#/definitions/membershipRequest"
|
|
258
|
+
},
|
|
259
|
+
{
|
|
260
|
+
"$ref": "#/definitions/targetBindingRequest"
|
|
261
|
+
},
|
|
262
|
+
{
|
|
263
|
+
"$ref": "#/definitions/listRequest"
|
|
264
|
+
}
|
|
265
|
+
]
|
|
241
266
|
}
|
|
242
267
|
]
|
|
243
268
|
}
|
|
@@ -306,7 +331,9 @@
|
|
|
306
331
|
"order",
|
|
307
332
|
"orders",
|
|
308
333
|
"scan",
|
|
309
|
-
"output-model"
|
|
334
|
+
"output-model",
|
|
335
|
+
"headquarters-binding",
|
|
336
|
+
"target-membership"
|
|
310
337
|
]
|
|
311
338
|
},
|
|
312
339
|
"command": {
|
|
@@ -1278,6 +1305,106 @@
|
|
|
1278
1305
|
"description": "本地已进入发送边界的观测次数下界,不是服务端执行次数。"
|
|
1279
1306
|
}
|
|
1280
1307
|
}
|
|
1308
|
+
},
|
|
1309
|
+
"headquartersBindingRequest": {
|
|
1310
|
+
"type": "object",
|
|
1311
|
+
"additionalProperties": false,
|
|
1312
|
+
"properties": {
|
|
1313
|
+
"method": {
|
|
1314
|
+
"const": "POST"
|
|
1315
|
+
},
|
|
1316
|
+
"path": {
|
|
1317
|
+
"const": "youzan.shop.basic.get/3.0.0"
|
|
1318
|
+
},
|
|
1319
|
+
"body": {
|
|
1320
|
+
"type": "object",
|
|
1321
|
+
"additionalProperties": false,
|
|
1322
|
+
"properties": {},
|
|
1323
|
+
"required": []
|
|
1324
|
+
},
|
|
1325
|
+
"stage": {
|
|
1326
|
+
"const": "headquarters-binding"
|
|
1327
|
+
},
|
|
1328
|
+
"kdtId": {
|
|
1329
|
+
"$ref": "#/definitions/shopId"
|
|
1330
|
+
}
|
|
1331
|
+
},
|
|
1332
|
+
"required": [
|
|
1333
|
+
"method",
|
|
1334
|
+
"path",
|
|
1335
|
+
"body",
|
|
1336
|
+
"stage",
|
|
1337
|
+
"kdtId"
|
|
1338
|
+
]
|
|
1339
|
+
},
|
|
1340
|
+
"targetBindingRequest": {
|
|
1341
|
+
"type": "object",
|
|
1342
|
+
"additionalProperties": false,
|
|
1343
|
+
"properties": {
|
|
1344
|
+
"method": {
|
|
1345
|
+
"const": "POST"
|
|
1346
|
+
},
|
|
1347
|
+
"path": {
|
|
1348
|
+
"const": "youzan.shop.basic.get/3.0.0"
|
|
1349
|
+
},
|
|
1350
|
+
"body": {
|
|
1351
|
+
"type": "object",
|
|
1352
|
+
"additionalProperties": false,
|
|
1353
|
+
"properties": {},
|
|
1354
|
+
"required": []
|
|
1355
|
+
},
|
|
1356
|
+
"stage": {
|
|
1357
|
+
"const": "shop-binding"
|
|
1358
|
+
},
|
|
1359
|
+
"kdtId": {
|
|
1360
|
+
"$ref": "#/definitions/shopId"
|
|
1361
|
+
}
|
|
1362
|
+
},
|
|
1363
|
+
"required": [
|
|
1364
|
+
"method",
|
|
1365
|
+
"path",
|
|
1366
|
+
"body",
|
|
1367
|
+
"stage",
|
|
1368
|
+
"kdtId"
|
|
1369
|
+
]
|
|
1370
|
+
},
|
|
1371
|
+
"membershipRequest": {
|
|
1372
|
+
"type": "object",
|
|
1373
|
+
"additionalProperties": false,
|
|
1374
|
+
"properties": {
|
|
1375
|
+
"method": {
|
|
1376
|
+
"const": "POST"
|
|
1377
|
+
},
|
|
1378
|
+
"path": {
|
|
1379
|
+
"const": "youzan.shop.chain.descendent.organization.list/1.0.1"
|
|
1380
|
+
},
|
|
1381
|
+
"body": {
|
|
1382
|
+
"const": {
|
|
1383
|
+
"page_num": 1,
|
|
1384
|
+
"page_size": 50,
|
|
1385
|
+
"with_dept_info": false,
|
|
1386
|
+
"with_shop_status_and_lifecycle_end_time": false,
|
|
1387
|
+
"with_crm_shop": false
|
|
1388
|
+
}
|
|
1389
|
+
},
|
|
1390
|
+
"stage": {
|
|
1391
|
+
"const": "target-membership"
|
|
1392
|
+
},
|
|
1393
|
+
"kdtId": {
|
|
1394
|
+
"$ref": "#/definitions/shopId"
|
|
1395
|
+
},
|
|
1396
|
+
"maxPages": {
|
|
1397
|
+
"const": 20
|
|
1398
|
+
}
|
|
1399
|
+
},
|
|
1400
|
+
"required": [
|
|
1401
|
+
"method",
|
|
1402
|
+
"path",
|
|
1403
|
+
"body",
|
|
1404
|
+
"stage",
|
|
1405
|
+
"kdtId",
|
|
1406
|
+
"maxPages"
|
|
1407
|
+
]
|
|
1281
1408
|
}
|
|
1282
1409
|
},
|
|
1283
1410
|
"modules": {
|
|
@@ -1350,7 +1477,7 @@
|
|
|
1350
1477
|
"notes": [
|
|
1351
1478
|
"基础 order 可返回 paidAt、isPaid。paidAt 未取得、空文本或 null 时省略,不证明未支付;非空错型、非法日期或非零毫秒失败。isPaid 未取得时省略,false 原样保留,非 boolean 失败;两者不从状态或金额推算。",
|
|
1352
1479
|
"订单号通常为 E/V/C 开头加 23 位数字,仅供核对,不限定前缀、数字组合或 24 位长度;按原值传递。仅保留非空、无空白或控制字符和最多 128 字符的文本保护;服务端仍判断支持范围和对象归属。",
|
|
1353
|
-
"省略 --kdt-id 时使用当前上下文店铺;显式目标须满足当前店铺范围约束。至少一个明确筛选;include
|
|
1480
|
+
"省略 --kdt-id 时使用当前上下文店铺;显式目标须满足当前店铺范围约束。至少一个明确筛选;include仅投影,同店一次核验加一次列表请求。不自动重试、翻页、换身份或逐单详情补齐。",
|
|
1354
1481
|
"本批默认以 CNY 计价,源为元的金额无损补齐两位十进制字符串,不新增币种字段、不换汇或跨币种汇总;这是用户确认的批次约定,不是官方币种保证。",
|
|
1355
1482
|
"payment保留列表应付/支付价格含义,不提供详情realPayment、优惠或独立退款集合。",
|
|
1356
1483
|
"累计响应10MiB、最终UTF-8输出含换行5MiB,超限整体失败;非流式内存保证。",
|
|
@@ -1358,6 +1485,9 @@
|
|
|
1358
1485
|
"应用凭证实测不证明店铺员工身份授权与权限隔离。",
|
|
1359
1486
|
"商品行 item_id/sku_id 为OneID,channel_item_id/channel_sku_id 为历史渠道身份;oid仍为交易行,不用当前档案重写历史。",
|
|
1360
1487
|
"历史统一商品或规格字段为空字符串时,省略对应OneID并保留明确渠道身份,不用渠道ID补造;null和其他错型仍失败。",
|
|
1361
|
-
"时间区间必须包含 .. 并显式两端;不接受旧成对参数或裸时间等值,非零毫秒在请求前拒绝。"
|
|
1488
|
+
"时间区间必须包含 .. 并显式两端;不接受旧成对参数或裸时间等值,非零毫秒在请求前拒绝。",
|
|
1489
|
+
"省略 --kdt-id 只查 context.shopId,总部默认仅总部本身,不包含分店。总部显式分店目标先核验总部角色及sid,再查下级组织目录,最后绑定分店sid;已返回的总部字段必须一致。查询不保存位置,不扩大解密权限。",
|
|
1490
|
+
"成员核验每页50条、最多20页。目录完整未命中为permission,未读完为scope_unresolved,字段异常为protocol;接口拒绝保留阶段与安全诊断。空订单也不能绕过前置。新增请求共享累计响应预算,同店请求保持兼容。",
|
|
1491
|
+
"总部显式分店最多23次业务请求,含总部1次、目录最多20次、分店绑定1次、订单1次;前置失败不发订单,不初始化分店应用,不重试。"
|
|
1362
1492
|
]
|
|
1363
1493
|
}
|
|
@@ -10,7 +10,7 @@ const { readContext } = require('../../../../../identity/context');
|
|
|
10
10
|
const { parseDateTime } = require('../../../../../execution/datetime');
|
|
11
11
|
const { parseDateTimeRange } = require('../../../../../execution/range');
|
|
12
12
|
const { queryDefinition, validateCommandValue } = require('../../../../../execution/command-schema');
|
|
13
|
-
const {
|
|
13
|
+
const { bindingPreview, targetScope, reject, serialize } = require('../../shared/query');
|
|
14
14
|
const { listPath, toPreviewBody, filterOptions } = require('../../shared/search');
|
|
15
15
|
const { scan, initialRanges, pageInput, addCalendarMonths } = require('./scan');
|
|
16
16
|
const schema = require('./schema.json');
|
|
@@ -76,10 +76,10 @@ function normalizedInput(options, scope) {
|
|
|
76
76
|
return input;
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
-
function preview(input) {
|
|
79
|
+
function preview(input, context) {
|
|
80
80
|
const ranges = initialRanges(input.range);
|
|
81
81
|
const output = {
|
|
82
|
-
requests:
|
|
82
|
+
requests: bindingPreview(input.scope, context),
|
|
83
83
|
initialRanges: ranges.map(({ start, end }) => ({ start, end })),
|
|
84
84
|
requestTemplate: { method: 'POST', path: listPath, body: toPreviewBody(pageInput(input, ranges[0])) },
|
|
85
85
|
limits: { ...input.limits, pageSize: Math.min(100, input.limits.maxItems) }
|
|
@@ -109,11 +109,14 @@ function createCommand({ context } = {}) {
|
|
|
109
109
|
.option('--keyword <text>', '订单号、收货人手机或后四位搜索')
|
|
110
110
|
.option('--include <modules>', `追加模块:${includeModules.join(', ')};仅投影,不增加请求`)
|
|
111
111
|
.option('--max-items <n>', '去重结果上限,1至10000,不裁切整页', '1000')
|
|
112
|
-
.option('--max-requests <n>', '总请求预算,2至500
|
|
112
|
+
.option('--max-requests <n>', '总请求预算,2至500,含总部/目录/分店核验、探测和翻页', '100')
|
|
113
113
|
.addOption(new Option('--format <format>', 'json 或 pretty,仅改变缩进').choices(['json', 'pretty']).default('json'))
|
|
114
114
|
.option('--dry-run', '纯本地预览,收货电话、姓名及关键词全部遮盖为 ***;不读凭证、不联网')
|
|
115
115
|
.addHelpText('after', `
|
|
116
116
|
商品行 item_id/sku_id 是OneID,channel_item_id/channel_sku_id 为历史渠道身份。
|
|
117
|
+
省略 --kdt-id 只查 context.shopId,总部默认仅总部本身,不含分店;非总部不可跨店。
|
|
118
|
+
总部可显式指定同连锁门店或网店,先核实总部、目录成员及分店sid,已返回的总部字段须一致,查询不保存位置。
|
|
119
|
+
目录每页50条最多20页,全部前置共享maxRequests与累计响应预算,每次发送前检查;前置未完成即耗尽预算时失败,不输出未核实订单。不初始化分店应用或重试。
|
|
117
120
|
--item-id沿用统一商品筛选,不把上游goods_id机械视为旧item_id,不增加渠道映射查询。
|
|
118
121
|
示例:zan-saas order order scan --kdt-id 63077 --created-at "2026-10-01 00:00:00..2026-10-02 00:00:00" --max-requests 2 --dry-run
|
|
119
122
|
创建时间或支付时间必须二选一,用 .. 分隔且包含两端,开始早于结束;结束不晚于当前时刻,跨度最多一日历年,非零毫秒拒绝。
|
|
@@ -134,7 +137,7 @@ range_exhausted 只表示本次观测的范围走完,不保证端点开闭、
|
|
|
134
137
|
.action(async options => {
|
|
135
138
|
const state = readContext(context);
|
|
136
139
|
const input = buildInput(options, context);
|
|
137
|
-
const plan = preview(input);
|
|
140
|
+
const plan = preview(input, state.context);
|
|
138
141
|
const output = input.dryRun ? plan : await scan(input, state.context);
|
|
139
142
|
if (!input.dryRun) {
|
|
140
143
|
try { validateCommandValue(schema, 'output', output); }
|
|
@@ -43,7 +43,7 @@ async function scan(input, context, readerFactory = createOrderPageReader) {
|
|
|
43
43
|
let requests = 0;
|
|
44
44
|
let halt;
|
|
45
45
|
const read = await readerFactory(input.scope, context, 'order.order.scan', {
|
|
46
|
-
responseLimit: 20 * 1024 * 1024, bounded: true,
|
|
46
|
+
responseLimit: 20 * 1024 * 1024, bounded: true, maxRequests,
|
|
47
47
|
onRequest: () => { requests++; }
|
|
48
48
|
});
|
|
49
49
|
while (true) {
|