new-erp-mcp 0.0.0-stage → 0.2.2

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.
Files changed (40) hide show
  1. package/README.md +214 -2
  2. package/docs/api.md +166 -0
  3. package/docs/erp-asin-contract.md +25 -0
  4. package/docs/mcp.md +96 -0
  5. package/index.mjs +168 -0
  6. package/package.json +31 -4
  7. package/scripts/catalog-list.js +130 -0
  8. package/scripts/category-summary.js +165 -0
  9. package/scripts/erp-options.js +23 -0
  10. package/scripts/game-product-batch.js +135 -0
  11. package/scripts/game-product-list.js +118 -0
  12. package/scripts/inventory-list.js +27 -0
  13. package/scripts/local-session.js +62 -0
  14. package/scripts/login.js +49 -0
  15. package/scripts/logistics-channel-list.js +10 -0
  16. package/scripts/logout.js +9 -0
  17. package/scripts/market-order-list.js +37 -0
  18. package/scripts/mcp.js +83 -0
  19. package/scripts/new-erp.js +91 -0
  20. package/scripts/outer-package-list.js +22 -0
  21. package/scripts/packing-batch-detail.js +23 -0
  22. package/scripts/packing-batch-list.js +31 -0
  23. package/scripts/packing-detail-export.js +112 -0
  24. package/scripts/packing-detail.js +32 -0
  25. package/scripts/packing-order-list.js +87 -0
  26. package/scripts/packing-order-pages.js +24 -0
  27. package/scripts/plan-delivery-order-list.js +26 -0
  28. package/scripts/product-asin.js +53 -0
  29. package/scripts/product-declaration-list.js +19 -0
  30. package/scripts/product-detail.js +136 -0
  31. package/scripts/query.js +106 -0
  32. package/scripts/sales-volume-export.js +114 -0
  33. package/scripts/sales-volume-ranking.js +417 -0
  34. package/scripts/setup.js +33 -0
  35. package/scripts/shared.js +448 -0
  36. package/scripts/stocking-assembly-inbound.js +62 -0
  37. package/scripts/supply-evidence.js +91 -0
  38. package/skills/new-erp-scripts/SKILL.md +62 -0
  39. package/skills/new-erp-scripts/agents/openai.yaml +3 -0
  40. package/skills/new-erp-scripts/references/query-guide.md +111 -0
package/README.md CHANGED
@@ -1,3 +1,215 @@
1
- # Temporary Holding Version
1
+ # new-erp-mcp
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ > 通过命令行、JavaScript 和本地 MCP 查询 new-erp 数据,供人和 AI Agent 使用。
4
+
5
+ 覆盖商品、销量、市场订单、库存、配货、装箱和物流申报。商品图片来自 ERP。查询结果可直接处理为 JSON,批量导出保留 ERP 原生 CSV/XLSX;支持完整分页、逐页读取和装箱导出任务恢复。
6
+
7
+ 业务命令只查询或导出数据,不创建或修改业务单据。导出会在 ERP 下载中心创建任务;登录和客户端接入命令仅修改本机文件。
8
+
9
+ ## 快速开始
10
+
11
+ 以下 SKU、ID、项目及仓库均为脱敏示例;使用时替换为有权限访问的真实值。项目和仓库代码可通过 `new-erp options` 查询。
12
+
13
+ ### 1. 安装命令行工具
14
+
15
+ 需要 Node.js 20+。npm 包名为 `new-erp-mcp`,安装后使用 `new-erp` 命令。也支持 `npm install -g ./new-erp-mcp-0.2.2.tgz` 安装下载的 npm 包。
16
+
17
+ ```sh
18
+ node --version
19
+ npm install -g new-erp-mcp
20
+ new-erp game-product-list --help
21
+ ```
22
+
23
+ 也可以通过 `npx` 直接运行,替换末尾命令和选项即可:
24
+
25
+ ```sh
26
+ npx --package=new-erp-mcp new-erp game-product-list --help
27
+ ```
28
+
29
+ 需要固定版本时使用 `new-erp-mcp@0.2.2`。
30
+
31
+ ### 2. 配置 ERP
32
+
33
+ 推荐用自己的 ERP 账号登录,密码在终端中隐藏输入:
34
+
35
+ ```sh
36
+ new-erp login --baseUrl https://your-erp.example.com
37
+ ```
38
+
39
+ 登录只保存 token,不保存密码,后续 CLI 与本地 MCP 均可使用。运行 `new-erp logout` 删除本机登录会话。
40
+
41
+ 已有 token 时,也可在运行命令的目录创建不提交到版本库的 `config.json`:
42
+
43
+ ```json
44
+ {
45
+ "baseUrl": "https://your-erp.example.com",
46
+ "token": "your-token"
47
+ }
48
+ ```
49
+
50
+ 也可通过环境变量或其他配置文件提供,见 [配置与认证](#配置与认证)。不要把真实 token、密码放进聊天、命令行历史或版本库。
51
+
52
+ ### 3. 执行查询
53
+
54
+ ```sh
55
+ new-erp game-product-list --sku DEMO-SKU-001
56
+ new-erp product-detail --id 12345
57
+ new-erp product-detail --asin B012345678
58
+ new-erp sales-volume-ranking --startDate 2026-01-01 --endDate 2026-01-31
59
+ ```
60
+
61
+ ## 命令行使用
62
+
63
+ 所有已安装命令统一通过 `new-erp <subcommand>` 调用。运行 `new-erp --help` 查看可用命令和简要说明,运行 `new-erp <subcommand> --help` 查看具体参数。迁移提示:原来独立调用 `new-erp-foo` 的方式改为 `new-erp foo`;安装包仅提供统一入口。
64
+
65
+ 每个命令都支持 `--help`、`--option value` 和 `--option=value`。先查看帮助确认所需参数。
66
+
67
+ ```sh
68
+ # 批量查商品
69
+ new-erp game-product-batch --skus 'SKU-A,SKU-B'
70
+
71
+ # 查市场订单:默认搜索系统单号;searchType 6 按 SKU 搜索
72
+ new-erp market-order-list --searchValue DEMO-ORDER-ID
73
+ new-erp market-order-list --searchType 6 --searchValue DEMO-SKU-001 --fetchAll
74
+
75
+ # 查国内仓的库存批次与 BOM
76
+ new-erp inventory-list --sku DEMO-SKU-003 --stockCode DEMO-STOCK --fetchAll
77
+
78
+ # 按总单号查询装箱列表
79
+ new-erp packing-order-list --packingNo YOUR-ORDER --stockFrom DEMO-FROM --fetchAll
80
+
81
+ # 导出平台销量,保留 ERP 的 GBK CSV
82
+ new-erp sales-volume-export --startDate 2026-01-01 --endDate 2026-01-31 --aggregateBy platform --output ./platform-2026-01.csv
83
+ ```
84
+
85
+ 成功结果写入 stdout,通常为 JSON 数组或对象;错误写入 stderr,并以非零状态退出。`new-erp packing-order-pages` 每页输出一行 JSON(NDJSON),需按行处理。
86
+
87
+ 市场订单、装箱、配货、库存等列表默认第1页20条,返回 `list/totalCount/fetchedCount/complete/source`。完整查询使用 `--fetchAll` 并从第1页开始;`--pageSize` 最多100,`--maxPages` 默认100、最多1000。分页截断、重复记录或总数变化会报错。
88
+
89
+ 大范围装箱历史可逐页读取,按项目和月份拆分:
90
+
91
+ ```sh
92
+ new-erp packing-order-pages --project DEMO-PROJECT --warehouses DEMO-DEST --startDate 2026-07-01 --endDate 2026-07-31 --pageSize 100
93
+ new-erp packing-detail-export --project DEMO-PROJECT --warehouses DEMO-DEST --startDate 2026-07-01 --endDate 2026-07-31 --output ./packing-2026-07.xlsx
94
+ ```
95
+
96
+ 装箱列表支持精确总单号查询;批量明细导出仍需完整的项目、目的仓、开始和结束日期。导出不覆盖已有文件,装箱导出可用 `--taskId` 恢复原任务。范围限制和数据口径见 [查询指南](./skills/new-erp-scripts/references/query-guide.md)。
97
+
98
+ ## 按 ASIN 查询 ERP 商品和图片
99
+
100
+ `B012345678` 是示例值,替换为实际 ASIN:
101
+
102
+ ```sh
103
+ new-erp product-detail --asin B012345678
104
+ ```
105
+
106
+ `--id` 与 `--asin` 二选一。ASIN 查询先读取 ERP 的 Listing 搜索枚举,再搜索匹配的 ERP SKU,最后获取商品详情;图片来自 ERP 的 `imageUrl`。所有请求使用 ERP 登录凭据,不访问亚马逊商品网页。
107
+
108
+ 同一 ASIN 对应多个 SKU 或店铺时保留全部匹配;商品详情附带 `asinListings` 和 `asinSource`。没有匹配、未配对 ERP SKU、权限不足或分页不完整时直接报错。ASIN 和 SKU 搜索默认各自最多100页,每页100条,可用 `--maxPages` 调整,上限1000页。接口和字段见 [ASIN 查询 API](./docs/api.md#按-asin-查询-erp-商品)。
109
+
110
+ ## 在 Codex 中使用本地 MCP
111
+
112
+ 全局安装本包并完成 ERP 登录后,运行:
113
+
114
+ ```sh
115
+ new-erp setup --client codex
116
+ ```
117
+
118
+ 该命令调用本机 `codex mcp add`,将当前 Node.js 和 MCP 入口的绝对路径注册到 Codex,无需手动编辑配置。需要先安装 Codex CLI;会替换同名的 `new-erp` MCP 配置,可用 `--name` 改名或用 `--dryRun` 预览。重启 Codex 后即可在对话中查询。
119
+
120
+ `new-erp mcp` 提供本地 stdio MCP,工具为 `game_product_list`、`product_detail`、`inventory_list` 和 `erp_options`。所有工具只使用 `new-erp login` 保存的会话;缺失或失效时要求重新登录,不读取项目或环境中的共享 token。
121
+
122
+ 安装、登录保存位置、手动配置和更新方法见 [本地 MCP 指南](./docs/mcp.md)。
123
+
124
+ ## 供 AI Agent 使用
125
+
126
+ 安装技能,让 Agent 按需选命令、处理分页并核对数据口径:
127
+
128
+ ```sh
129
+ npx skills add PIZZAxBOY/new-erp-scripts --skill new-erp-scripts --agent codex
130
+ ```
131
+
132
+ 本地仓库可用 `npx skills add . --skill new-erp-scripts --agent codex`。公开仓库可直接远程安装;安装方式见 [skills.sh 文档](https://www.skills.sh/docs)。
133
+
134
+ 安装后可直接向 Agent 描述需求,例如:
135
+
136
+ > 查询 DEMO-SKU-001 的商品信息。
137
+ >
138
+ > 导出 DEMO-PROJECT 项目 DEMO-DEST 仓在 2026 年 7 月扫描出库的装箱明细,保存为 XLSX。
139
+
140
+ 技能只包含调用说明,运行代码需独立安装或通过 `npx` 获取。技能入口见 [SKILL.md](./skills/new-erp-scripts/SKILL.md),完整命令及数据口径见 [查询指南](./skills/new-erp-scripts/references/query-guide.md)。
141
+
142
+ ## JavaScript API
143
+
144
+ 在使用方项目中安装:
145
+
146
+ ```sh
147
+ npm install new-erp-mcp
148
+ ```
149
+
150
+ 通过 ES module 导入,选项与 CLI 同名:
151
+
152
+ ```js
153
+ import { gameProductList, salesVolumeRanking } from 'new-erp-mcp';
154
+
155
+ const products = await gameProductList({ sku: 'DEMO-SKU-001' });
156
+ const sales = await salesVolumeRanking({
157
+ startDate: '2026-01-01',
158
+ endDate: '2026-01-31',
159
+ fetchAll: true,
160
+ });
161
+ ```
162
+
163
+ `packingOrderPages(options)` 提供逐页异步迭代,`exportPackingDetails(options)` 可返回 XLSX Buffer,并通过 `onProgress` 保存任务 ID。底层 `erpClient` 可用于自定义查询。参数、返回值和恢复示例见 [API 文档](./docs/api.md)。
164
+
165
+ ## 配置与认证
166
+
167
+ | 环境变量 | 配置文件字段 | 用途 |
168
+ | --- | --- | --- |
169
+ | `NEW_ERP_BASE_URL` | `baseUrl` | ERP 地址 |
170
+ | `NEW_ERP_TOKEN` | `token` | 已有 token |
171
+ | `NEW_ERP_USERNAME` | `username` | 登录用户名 |
172
+ | `NEW_ERP_PASSWORD` | `password` | 登录密码 |
173
+ | `NEW_ERP_CONFIG` | 无 | 指定配置文件路径,默认读取当前目录的 `config.json` |
174
+ | `NEW_ERP_SESSION_FILE` | 无 | 指定本机登录会话文件路径;默认位于当前系统用户的配置目录 |
175
+
176
+ 环境变量覆盖项目配置文件中的同名值。CLI/API 的 ERP 地址最后回退到本机登录会话;认证先使用显式 token,再使用环境变量或项目配置中的 token,然后使用地址匹配且未过期的本机会话,最后才尝试账号密码登录。MCP 的 ERP 查询始终绑定本机登录会话,不使用上述共享配置回退。
177
+
178
+ 错误信息对认证字段做脱敏,不回显非 JSON 响应正文或配置解析原文。查询结果及导出文件保留 ERP 业务原文,对外分享前需另行脱敏。
179
+
180
+ 认证请求和文件下载拒绝 HTTP 重定向。JSON 请求默认最多等待120秒,包含正文读取;装箱导出任务默认等待20分钟,可通过 `timeoutMs` 调整。具体轮询和超时边界见 [API 文档](./docs/api.md#装箱历史与批量导出)。
181
+
182
+ ## 命令一览
183
+
184
+ | 范围 | 命令 |
185
+ | --- | --- |
186
+ | 商品与分类 | `new-erp catalog-list`、`new-erp game-product-list`、`new-erp game-product-batch`、`new-erp product-detail --id/--asin` |
187
+ | 登录与本地 MCP | `new-erp login`、`new-erp logout`、`new-erp setup`、`new-erp mcp` |
188
+ | 销量与汇总 | `new-erp sales-volume-ranking`、`new-erp sales-volume-export`、`new-erp category-summary` |
189
+ | 单据与实际入库 | `new-erp supply-evidence`、`new-erp stocking-assembly-inbound` |
190
+ | 装箱历史与导出 | `new-erp packing-order-list`、`new-erp packing-order-pages`、`new-erp packing-detail`、`new-erp packing-detail-export` |
191
+ | 配货批次与历史明细 | `new-erp packing-batch-list`、`new-erp packing-batch-detail`、`new-erp plan-delivery-order-list` |
192
+ | 库存与包装 | `new-erp inventory-list`、`new-erp outer-package-list` |
193
+ | 物流、申报与枚举 | `new-erp logistics-channel-list`、`new-erp product-declaration-list`、`new-erp options` |
194
+
195
+ 各命令的必填选项和适用场景见 [查询指南](./skills/new-erp-scripts/references/query-guide.md#命令选择)。库存预测量、计划单据、BOM 版本和重量单位各有不同口径,汇总前请核对来源。
196
+
197
+ ## 开发与验证
198
+
199
+ ```text
200
+ scripts/ # CLI 与共享客户端
201
+ index.mjs # JavaScript API 导出
202
+ skills/new-erp-scripts/ # Agent 技能与查询指南
203
+ docs/ # API 与数据口径
204
+ test/ # 自动化测试
205
+ ```
206
+
207
+ 在仓库根目录可用 `node scripts/new-erp.js <command>` 运行,或用 `npm install -g .` 安装本地版本。验证命令:
208
+
209
+ ```sh
210
+ npm ci
211
+ npm test
212
+ npm run check:package
213
+ node --check index.mjs
214
+ for file in scripts/*.js; do node --check "$file"; done
215
+ ```
package/docs/api.md ADDED
@@ -0,0 +1,166 @@
1
+ # JavaScript API 与数据口径
2
+
3
+ 安装与配置见 [README](../README.md#javascript-api)。函数接收与 CLI 同名的选项对象,返回结果或抛出错误;配置从调用时的当前工作目录或环境变量读取。
4
+
5
+ ## 基础查询与客户端
6
+
7
+ 基础查询导出 `catalogList`、`categorySummary`、`gameProductList`、`gameProductBatch`、`productDetail`、`salesVolumeRanking`、`salesVolumeExport`、`supplyEvidence` 和 `stockingAssemblyInbound`。
8
+
9
+ 底层 ERP API 客户端通过 `erpClient` 导出,包含 `loginToken`、`getBaseUrl` 和 `requestJson`,供需要分页采集自定义 ERP 接口的项目复用。
10
+ `exportGameProducts({ token, fields })` 使用 ERP 商品导出任务,等待下载中心完成并返回 `{ taskId, file }`;`file` 是 XLSX Buffer,字段默认是 SKU、品名、单价。导出文件不含商品 ID。
11
+
12
+ `exportOuterPackages({ token, flowStatus })` 使用 ERP 外包装导出任务;`flowStatus` 为 1–5,返回 `{ taskId, file }`,其中 `file` 是 XLSX Buffer。
13
+
14
+ `exportGameProducts({ disused: true })` 使用游戏类淘汰产品原生导出接口 `/products/game-product-list/disuse-product-export`;返回下载中心任务 ID 和 XLSX,默认字段为 SKU、品名、单价。
15
+
16
+ ## 按 ASIN 查询 ERP 商品
17
+
18
+ `productDetail({ asin, token?, maxPages?, raw? })` 返回 ERP 商品详情数组;也支持原有的 `productDetail({ id })`。`id` 与 `asin` 必须二选一,在认证和网络请求前校验。ASIN 必须为10位字母或数字,去除首尾空白并转大写。
19
+
20
+ ```js
21
+ import { productDetail } from 'new-erp-mcp';
22
+
23
+ const products = await productDetail({ asin: 'B012345678' });
24
+ for (const product of products) {
25
+ console.log(product.sku, product.imageUrl, product.asinListings);
26
+ }
27
+ ```
28
+
29
+ 示例 ASIN 需替换为实际值。CLI 为 `new-erp product-detail --asin B012345678`,MCP 为 `product_detail({ asin: 'B012345678' })`。
30
+
31
+ 查询仅访问当前配置的 ERP:
32
+
33
+ 1. `GET /sales/ling-xing/jy-amazon-selected-option` 获取 `other_select_name1_arr`,选择唯一标为 `ASIN` 的字段值,不硬编码字段编号。
34
+ 2. `GET /sales/ling-xing/jy-amazon-list-data` 使用 `other_select_name1` 和 `other_select_value1` 搜索,完整分页后按返回的 `asin` 精确核对。
35
+ 3. 按每个匹配的 ERP `sku` 查询 `/products/game-product-list/index`,完整分页后精确匹配 SKU;没有精确匹配时再查询 `/products/game-product-list/game-disuse-product-list`,取得停用商品的产品 ID。
36
+ 4. `/products/product-basic/detail` 查询详情,核对 ID 和 SKU 后返回,不将 Listing 行 ID 当作产品基础 ID。
37
+
38
+ 这些接口由 [ERP 前端模块](./erp-asin-contract.md) 确认。ASIN 查询覆盖该 ERP 的 `jyAmazon` Listing 数据范围;未自动混入其他 Listing 接口或外部 ERP 数据。接口权限由登录账号决定。
39
+
40
+ ASIN 查询在原商品详情字段之外提供:
41
+
42
+ | 字段 | 含义 |
43
+ | --- | --- |
44
+ | `asin` | 规范化后的查询 ASIN。 |
45
+ | `asinListings` | 此 ERP SKU 对应的全部精确匹配 Listing 原始记录,保留店铺、MSKU 等差异。 |
46
+ | `asinSource` | Listing 查询路由、参数、采集时间、`totalCount/fetchedCount/complete/matchedCount`;不包含凭据。 |
47
+
48
+ `imageUrl` 保持 ERP 原始值;相对路径需结合 ERP 地址使用,空值不补造。ASIN 查询不保证存在主图或附图全集。重复店铺匹配同一产品时详情只读取一次;多个 SKU 或产品 ID 全部返回,不自动取首条。
49
+
50
+ `maxPages` 默认100,最多1000,适用于每次 ASIN Listing 和 SKU 搜索;每页100条。列表截断、重复记录、总数变化、无法确认 ASIN、未配对 ERP SKU、无商品映射或详情 ID/SKU 不匹配均抛错,不返回部分结果,也不回退到公开亚马逊页面。`raw` 仍只附带商品详情原始 JSON。
51
+
52
+ ## 销量与单据
53
+
54
+ `salesVolumeRanking` 默认返回一个分页;`fetchAll: true` 获取完整范围并重新排序。指定 `sku` 时抓取全部匹配页,再按 SKU 精确过滤;`aggregateBy: 'sku-platform'` 按平台拆分。`categorySummary` 统计完整范围内的记录行数,不是销售数量。日期未带时间时,开始使用 `00:00:00`,结束使用 `23:59:59`;父级分类 ID 使用实时分类树展开。
55
+
56
+ `supplyEvidence({ source })` 支持 `plan`、`move`、`inventory`、`assembly`、`cargo`。单据查询默认只取一页;完整核对请传 `fetchAll: true`。`plan` 和 `move` 的数量来自单据明细,不使用列表行的 `num`;搬运计划不代表调库完成。`salesVolumeExport` 通过下载中心异步导出,保留 ERP 的 GBK CSV。
57
+
58
+ `stockingAssemblyInbound` 按精确 SKU 和入库时间汇总备货拼装实际入库流水,用拼装单号核对生产任务。它只统计备货拼装,不包含采购进货或调库。
59
+
60
+ 销量导出只复用查询条件完全匹配且没有额外非空筛选的任务。商品、外包装和装箱导出拒绝多个匹配的新任务,并在识别任务后固定任务ID,避免后续轮询切换到其他任务。
61
+
62
+ ## 市场订单
63
+
64
+ `marketOrderList(options)` / `new-erp market-order-list` 只读 `GET /index.php?r=/marketing/market-order/index`,不创建、更新或导出订单。路由与响应结构由 ERP 接口文档及前端 `evaluationOrder` 模块交叉确认,搜索字段依据前端请求映射;未使用生产凭据实测。
65
+
66
+ | 选项 | ERP 参数与含义 |
67
+ | --- | --- |
68
+ | `searchValue` | `search_value`,搜索内容;有值时 `searchType` 默认为 `3` |
69
+ | `searchType` | `search_type`:`1` 跟踪号、`2` 转单号、`3` 系统单号(订单 `id`)、`4` 红人编码、`5` 邮箱、`6` SKU;指定时必须提供非空 `searchValue` |
70
+ | `project` | `auction_site`,ERP 项目代码 |
71
+ | `status` | `order_status`,默认 `''` 查询全部状态;支持数字或数字字符串,包括 `0` 和负值;具体含义读取响应的 `order_status_map`,不推断状态 |
72
+ | `transactionId` | `transaction_id`,交易号,不是系统单号 `id` 或平台单号 `item_no` |
73
+
74
+ 未传筛选条件时查询全部状态的第一页;匹配方式遵循 ERP 原生搜索规则,不额外承诺精确匹配或在本地过滤。支持标准 `page/pageSize/fetchAll/maxPages`:默认第1页20条、每页最多100条,全量从第1页开始,默认最多100页、上限1000页。返回 `{ list, totalCount, fetchedCount, complete, source, ...ERP元数据 }`,按订单 `id` 检查重复,缺少 ID、分页截断或总数变化时报错。空列表正常返回;认证或权限失败不当作空列表。
75
+
76
+ 订单原字段(含 `sku_qty`、`product_all_info`、`track_number`、`order_status` 等)及实时枚举保持原样,不展开 SKU、不转换金额或空值。ERP 元数据保留首页值,不重新计算汇总。订单可能包含买家地址、邮箱等个人信息,查询结果和 `source.query` 中的搜索内容对外分享前须脱敏。
77
+
78
+ ```js
79
+ import { marketOrderList } from 'new-erp-mcp';
80
+
81
+ const orders = await marketOrderList({ searchType: '6', searchValue: 'DEMO-SKU-001', fetchAll: true });
82
+ const order = await marketOrderList({ searchValue: 'DEMO-ORDER-ID' });
83
+ ```
84
+
85
+ ## 装箱历史与批量导出
86
+
87
+ `packingOrderList(options)` 支持两种范围:完整的 `project + warehouses + startDate + endDate`(扫描出库时间),或单独的精确总单号 `packingNo`。两种范围可叠加,`stockFrom` 只用于收窄,不能单独查询。传入任何历史范围字段时四项都必须完整;显式传入空的 `packingNo` 或 `stockFrom` 会报错,不忽略条件。`warehouses` 是完整目的仓名称数组或逗号分隔字符串,必须非空、不重复且无空白,允许指定非 FBA 仓。目的仓完整枚举由 `erpOptions({ source: 'packing' })` 的 `data.site_type_list` 提供,项目枚举为 `data.auction_site_list`。
88
+
89
+ 列表保留 `{ ...ERP数据, list, totalCount, query }`,补充 `page/pageSize/fetchedCount/complete/source`。默认单页20条,上限100;可用 `fetchAll: true` 从第1页收集所有行,或用异步生成器 `packingOrderPages(options)` 逐页消费。后者同样从第1页开始,省略 `fetchAll`,每次返回 `{ ...ERP数据, list: 当前页, totalCount, query, page, pageSize, fetchedCount: 累计行数, complete: 是否末页, source }`。空结果也返回一页。每页严格检查数量、总数稳定及重复箱号(无箱号时用ID),核对指定的总单号、发货仓和目的仓;错误直接抛出。
90
+
91
+ 两个全量入口都有 `maxPages` 保护(默认100,最多1000),第一请求发现超限即报错。逐页读取没有预取,消费方处理完当前页才发下一请求,提前结束迭代不再请求;内存保留当前页和本次查询的去重键,不保留全部箱记录。去重键随已读行数增长,受页数上限约束。大范围回放应按项目和月份拆分,显式用 `pageSize: 100`;单页 `page` 查询可用于调用方自己的检查点。`fetchAll` 会保留全部行,不适合大批历史回放。
92
+
93
+ `exportPackingDetails({ project, warehouses, startDate, endDate, packingNo?, stockFrom?, status?, token?, output?, onProgress?, pollMs?, timeoutMs?, taskId? })` 优先使用 `/warehouse/packing-order/down-packing-detail` 原生批量导出。完整历史四项仍必填,`packingNo`、`stockFrom` 只能额外收窄;总单号映射为 `number_field=packing_num`、`number_value`。验证中仅传总单号和发货仓时 ERP 返回 `code=0, msg=请选择项目`,因此未开放仅总单号导出。
94
+
95
+ 默认返回 `{ taskId, file, boxes, query }`,`file` 为 XLSX Buffer,可直接交给解析器,不必落盘;`boxes` 为本次列表箱数。无数据时 `taskId=""`、`file=null`、`boxes=0`,不创建任务。传 `output` 时以不覆盖模式保存文件,返回 `{ taskId, output, bytes, boxes, query }`;空结果不创建空文件。轮询默认 `pollMs: 3000`、`timeoutMs: 1200000`(等待任务的时限,不含前置查询和文件下载);兼容 `pollMs: 2000, timeoutMs: 600000`。两项必须为正整数。
96
+
97
+ 默认只匹配本次新任务,不复用旧快照。识别任务后,`onProgress` 先收到 `{ stage: 'waiting', boxes, taskId }`,可立即保存ID;下载前收到同形的 `stage: 'download'`。只有显式 `taskId` 才恢复轮询和下载,不创建新任务;恢复同样要求完整查询,逐次核对任务路由和全部筛选条件,拒绝额外非空条件、失败、消失或不匹配的任务。必要时串行查找下载中心后续页,最多1000页,每页100条,并受等待时限限制。显式恢复的是原任务快照,`boxes` 是恢复时的列表计数,调用方仍需核对文件内容;它不证明快照仍与当前业务一致。
98
+
99
+ 已出库箱优先从批量文件读取 SKU、数量和销售包装;仅为未出库箱或导出缺失的必要字段补读 `packingDetail`。需复核采集期间的SKU、包装变化时,可做两次新导出比较完整清单,调用时都不传 `taskId`。批量主数据已有 `exportGameProducts({ token, fields, disused? })`、`exportOuterPackages({ token, flowStatus })`,都返回 XLSX Buffer;前者保留 ERP 指定导出字段,不能替代包含全部版本的 `productDetail`,后者可按包装类型建立本地快照。
100
+
101
+ ```js
102
+ import { packingOrderPages, exportPackingDetails } from 'new-erp-mcp';
103
+
104
+ const selection = {
105
+ project: 'DEMO-PROJECT', warehouses: ['DEMO-DEST'],
106
+ startDate: '2026-07-01', endDate: '2026-09-30',
107
+ };
108
+ for await (const page of packingOrderPages({ ...selection, pageSize: 100 })) {
109
+ await consumePage(page); // 写入调用方的检查点或逐页处理
110
+ }
111
+ const detail = await exportPackingDetails({ ...selection, packingNo: 'YOUR-ORDER', stockFrom: 'DEMO-FROM',
112
+ pollMs: 2000, timeoutMs: 600000,
113
+ onProgress: async ({ taskId }) => { await saveTaskId(taskId); },
114
+ });
115
+ // 用保存的ID恢复:exportPackingDetails({ ...selection, packingNo: 'YOUR-ORDER', stockFrom: 'DEMO-FROM', taskId })
116
+ ```
117
+
118
+ 对应 CLI 为 `new-erp packing-order-list`、`new-erp packing-order-pages` 和 `new-erp packing-detail-export`。逐页命令每页输出一行 JSON(NDJSON),遵守标准输出背压;导出命令须传 `--output ./packing.xlsx`,可用 `--taskId` 恢复。导出保持 ERP 原文,包含 SKU、数量、渠道、箱实重kg和尺寸cm,不直接返回四种运输占比或货代最终结算重量。
119
+
120
+ ### 请求数验证
121
+
122
+ 请求数自检:`node --test --test-name-pattern='pageSize 100' test/packing-history.test.js`。固定1000箱的本地数据,默认每页20条发50次请求,每页100条发10次,减少80%,所得记录计数和ID校验和一致。按120000箱计算分别为6000次和1200次(需按月拆分满足分页上限);这是请求数推算,不是ERP实测速率。
123
+
124
+ ## 配货、库存与包装
125
+
126
+ 以下接口均支持 ES module 导入,同时提供同名连字符 CLI(如 `packingBatchList` 对应 `new-erp packing-batch-list`)。只读取 ERP 数据,不创建或修改业务单据。
127
+
128
+ | API | 必填选项 | 返回内容 |
129
+ | --- | --- | --- |
130
+ | `packingBatchList` | `stockFrom` | 配货批次列表,默认 `status: '5'`(已配货待装箱);`status: ''` 查询全部。可按 `batchNo`、`warehouse` 搜索,`packingNo` 精确收窄总单。 |
131
+ | `packingBatchDetail` | `stockFrom`、`batchNo` | 批次明细,保留原始 `provider` 分组、SKU、`num/can_num/now_num`、`version_number/bom_number`。这些数量和版本字段不自动互相替代。 |
132
+ | `packingDetail` | `packingNumNo`、`stockFrom`、`status`、`siteType` | `/warehouse/transfer-order-packing/packing-detail` 原箱明细,返回 `{ ...ERP数据, source }`。`status` 取列表原值,允许0;核对箱号、发货仓及返回的目的仓,保留 `packing_sku`、尺寸和重量原值,不补造销售包装或BOM。 |
133
+ | `planDeliveryOrderList` | `stockFrom`、`packingNo` | `/sales/plan-delivery-order/list` 历史配货明细,支持标准分页和 `fetchAll`;精确核对总单和发货仓,按ID检查重复,保留版本、跟单和已装数量。 |
134
+ | `outerPackageList` | `flowStatus` | 1=外包装SKU、2=方装头程、3=异装头程、4=无BZ版本SKU、5=无BZ版本头程;可按 `sku`、`project` 搜索,保留所有返回版本、箱规、单箱数量和实时枚举。 |
135
+ | `inventoryList` | `sku`、`stockCode` | 国内仓库存;默认 `groupBy: 'batch'` 保留库存批次/BOM;`groupBy: 'warehouse'` 按 SKU+仓库汇总。精确核验返回的 SKU 和仓库。 |
136
+ | `logisticsChannelList` | 无 | 渠道ID、运输方式、材积除数、状态等原始配置;不额外推断运价或限重。 |
137
+ | `productDeclarationList` | 无 | 可按 `sku`、`country`(如 `US/IT`)搜索申报品名、材质、用途、HS编码、价格和币种。保留空白字段。 |
138
+ | `erpOptions` | `source` | `inventory`=库存枚举,`packing`=装箱状态/目的仓/渠道等,`batchWarehouses`=配货发货仓列表;返回 `{ data, source }`。 |
139
+
140
+ 列表 API 返回 `{ list, totalCount, fetchedCount, complete, source, ...ERP元数据 }`,默认第1页20条。支持 `page`、`pageSize`(最多100)、`fetchAll` 和 `maxPages`(默认100,最多1000)。`fetchAll: true` 必须从第1页开始,校验每页数量及总数稳定;发生截断或总数变化时抛错。空结果返回空列表,不补造记录。`source` 包含路由、查询参数和采集时间,不包含认证信息;其他 ERP 元数据(如汇总值)保持首页原样,不作为包重新计算的全量汇总。
141
+
142
+ 分页出现重复记录时抛错,不静默去重;库存和外包装按完整记录检测重复,保留同一商品的不同批次、BOM和包装版本。`supplyEvidence` 和实际入库查询也使用相同的分页数量校验,入库数量缺失或空白时抛错,不补零。
143
+
144
+ ```js
145
+ import { packingBatchList, packingBatchDetail, outerPackageList, inventoryList } from 'new-erp-mcp';
146
+
147
+ const batches = await packingBatchList({ stockFrom: 'DEMO-FROM', fetchAll: true });
148
+ if (batches.list.length) {
149
+ const detail = await packingBatchDetail({ stockFrom: 'DEMO-FROM', batchNo: batches.list[0].confirmed_no });
150
+ }
151
+ const packaging = await outerPackageList({ flowStatus: 2, sku: 'DEMO-SKU-003', fetchAll: true });
152
+ const inventory = await inventoryList({ sku: 'DEMO-SKU-003', stockCode: 'DEMO-STOCK', fetchAll: true });
153
+ ```
154
+
155
+ `productDetail` 在原有返回字段之外,直接提供 `fatherId`、`packingId`、`packWeight`、`trueWeight`、`productAttributeInfo`、`skuVersions`(全部版本)和 `exportLogisticsDeclaration`,不再需要开启 `raw` 才能读取这些数据。旧的 `firstVersion*` 字段保留;不能据此替具体批次选择版本。
156
+
157
+ 注意数据口径:
158
+
159
+ - 库存 `stock_count.num` 是即时库存,`yg_can_stock_count.num` 是预计可用库存。后者包含预计入库、预计出库和预留量,不代表已签收可装箱数量。库存批次 `advice_id` 与配货批次 `confirmed_no` 属于不同标识。
160
+ - 批次 `version_number`、BOM编号与商品 `pack_version` 的关联,以及父编号含义和国家适用规则,尚不能只凭字段名确定。
161
+ - 外包装记录会包含禁用BOM和多版本,SKU搜索可能匹配多个SKU;调用方需按精确SKU、BOM状态、包装版本和箱型核对,不自动取首条。
162
+ - 尺寸重量保留各来源原值。同一SKU在商品详情与外包装列表中的 `pure_weight` 可能使用不同单位,不能直接跨接口相加。箱内尺寸、空箱皮重、承重上限、混装规则及单位仍需业务核定。
163
+
164
+ ## 验证范围
165
+
166
+ 已验证配货批次、批次明细、外包装、库存、物流渠道和申报查询。真实 SKU、批次号、仓库名称及返回数量已省略;结果数量随业务变化,不能据此推断上游调拨已签收。搬运计划接口可能受账号权限限制,遇到403应报告权限缺口,不绕过权限。
@@ -0,0 +1,25 @@
1
+ # ERP ASIN 查询接口依据
2
+
3
+ 接口行为已从实际 ERP 前端静态资源核对。公开文档省略部署域名、构建文件名和构建哈希;以下仅保留接入所需的接口及字段。业务数据请求需要用户自己的 ERP 登录。
4
+
5
+ ## Listing 搜索
6
+
7
+ ERP 前端的 `jyAmazon` API 模块声明:
8
+
9
+ - `GET /sales/ling-xing/jy-amazon-selected-option` 返回搜索枚举。
10
+ - `GET /sales/ling-xing/jy-amazon-list-data` 返回 Listing 数据。
11
+ - 搜索枚举使用 `other_select_name1_arr`。
12
+
13
+ `views/sales/listTing/jyAmazon/index.vue` 对应的页面模块使用 `other_select_name1` 选择字段,`other_select_value1` 传搜索内容。请求携带 `page/pageSize`,响应使用 `list/totalCount`。表格的 `sku` 列标为 ERPSKU,另有 `seller_sku`(MSKU)、`fnsku`、`asin` 及 `domain_arr`(店铺信息)。
14
+
15
+ 公共入口模块的 `combinedDataFu` 把原始枚举的键作为选项值,值作为显示标签。实现据此在运行时寻找唯一标签为 `ASIN` 的项,使用其键作为 `other_select_name1`,不猜测编号。
16
+
17
+ ## 商品详情关联
18
+
19
+ `gameProductList` API 模块声明 `GET /products/game-product-list/index` 和 `GET /products/game-product-list/game-disuse-product-list`。ASIN 搜索返回 ERP SKU 后,先查询在售商品;没有精确匹配时再查询停用商品。两者都使用 SKU 查询参数、完整分页和精确匹配,取得产品基础 ID。
20
+
21
+ 详情继续使用本项目既有 `/products/product-basic/detail?id=...`。Listing 行 ID、ERP SKU 和产品基础 ID 分别保留,不互相代替。
22
+
23
+ ## 验证边界
24
+
25
+ 已核对真实前端的路由、字段映射及使用方式,并以本地接口响应验证 CLI/MCP 的完整调用链、分页、账号隔离、模糊匹配过滤和异常处理。已使用登录账号通过 MCP 实测 ASIN 查询,验证停用商品详情及图片获取;公开文档不记录业务标识和结果。实际账号未开放该菜单或搜索枚举时直接报错,不转接领星外部接口或公开亚马逊商品页。
package/docs/mcp.md ADDED
@@ -0,0 +1,96 @@
1
+ # 通过 npm 安装本地 MCP
2
+
3
+ 本包提供本地 stdio MCP,不需要部署在线服务。每位用户在自己的电脑上安装并登录 ERP,电脑需能访问 ERP。需要 Node.js 20+;自动接入 Codex 还需要 Codex CLI。
4
+
5
+ ## 安装与登录
6
+
7
+ 从 npm 安装:
8
+
9
+ ```sh
10
+ npm install -g new-erp-mcp
11
+ ```
12
+
13
+ 也可以下载打包生成的 `.tgz`,通过 npm 安装:
14
+
15
+ ```sh
16
+ npm install -g ./new-erp-mcp-0.2.2.tgz
17
+ ```
18
+
19
+ 在自己的终端完成登录,ERP 地址替换为实际地址:
20
+
21
+ ```sh
22
+ new-erp login --baseUrl https://your-erp.example.com
23
+ new-erp setup --client codex
24
+ ```
25
+
26
+ `login` 提示输入账号和密码,密码不回显。也可用 `--username` 提供账号。非交互环境使用 `NEW_ERP_USERNAME` 和 `NEW_ERP_PASSWORD`;不要把密码放进命令参数或聊天。登录失败不会覆盖原会话。
27
+
28
+ 重启 Codex 后即可使用,例如“查询某个 SKU 的产品图片”。`codex mcp list` 可查看注册配置;Codex 终端界面中的 `/mcp` 可查看连接状态。所有工具都要求有效的本机 ERP 会话。
29
+
30
+ ## Codex 配置
31
+
32
+ `setup` 调用 `codex mcp add`,注册当前安装的 Node.js 和 `scripts/mcp.js` 的绝对路径,不将账号、密码或 token 写入 Codex 配置。它会替换同名配置,其他名称的 MCP 不受影响。
33
+
34
+ ```sh
35
+ new-erp setup --client codex --dryRun
36
+ new-erp setup --client codex --name my-erp
37
+ ```
38
+
39
+ 其他支持本地 stdio 的客户端可以使用 `new-erp mcp` 作为启动命令,也可使用 Node.js 和 MCP 脚本的绝对路径。先独立完成登录,MCP 进程的标准输入与输出只传输协议,不能用于交互输入密码。
40
+
41
+ 不要通过临时的 `npx` 安装目录运行 `setup`;全局安装能提供持久的脚本路径。移动包目录、切换 Node.js 安装位置或更新包后重新运行 `setup`。Codex 的接入方式见 [OpenAI 官方 MCP 文档](https://learn.chatgpt.com/docs/extend/mcp)。
42
+
43
+ ## 更新版本
44
+
45
+ ```sh
46
+ npm install -g new-erp-mcp@latest
47
+ new-erp setup --client codex
48
+ ```
49
+
50
+ 更新后重启 MCP 客户端以加载新代码。本机登录会话保存在包目录之外,更新包不会删除会话;同一系统用户、ERP 地址和会话路径下,有效 token 可继续使用,无需重新登录。token 失效、主动退出或更换上述配置后,重新运行 `new-erp login`。
51
+
52
+ ## 可用工具
53
+
54
+ | MCP 工具 | 用途 |
55
+ | --- | --- |
56
+ | `game_product_list` | 按 SKU、品名、分类和类型查询 ERP 商品及图片,每次返回一页。 |
57
+ | `product_detail` | 按 ERP 产品基础 ID 或 ASIN 查询详情、ERP 图片和全部 SKU/BOM 版本;`id/asin` 二选一。ASIN 先查 ERP Listing,再按匹配的 SKU 获取详情。 |
58
+ | `inventory_list` | 按精确 SKU、仓库代码查询库存批次或仓库汇总,每次返回一页。 |
59
+ | `erp_options` | 查询库存、装箱或配货仓库的实时枚举。 |
60
+
61
+ 工具直接调用已有 JavaScript 函数。数组结果封装为 `{ list }`,对象结果保持原结构;同时返回 MCP 文本和 `structuredContent`。工具参数不接受账号、密码、token 或自定义 ERP 地址。
62
+
63
+ 商品列表和库存支持 `page`、`pageSize`,默认第1页20条,每页最多100条。`product_detail` 的 ASIN 解析会完整读取相关 Listing 和 SKU 搜索,每页100条,`maxPages` 默认100、上限1000,保留全部精确匹配及店铺信息。批量导出和其他全量查询可继续使用 CLI/API。库存预测量不是已签收库存,保留批次与 BOM 差异。
64
+
65
+ ## 本机登录会话
66
+
67
+ 会话仅包含 ERP 地址、账号、token、用户 ID 和上游返回的过期时间,不保存密码,也不会上传到额外的服务。位置为:
68
+
69
+ - macOS/Linux:`${XDG_CONFIG_HOME:-~/.config}/new-erp/session.json`。
70
+ - Windows:`%LOCALAPPDATA%\new-erp\session.json`,缺少该变量时使用用户目录下的 `AppData\Local`。
71
+ - 设置 `NEW_ERP_SESSION_FILE` 可指定其他位置,适合隔离不同本地环境。
72
+
73
+ token 以明文保存在本机文件,macOS/Linux 文件权限为 `0600`,应用新建的目录为 `0700`;Windows 使用当前用户目录的文件权限。不要分享或提交会话文件。登录写入采用临时文件后原子替换,读到的会话对应一次完整登录。
74
+
75
+ MCP 每次 ERP 调用读取当前会话,并把 ERP 地址及 token 绑定到该次调用;不回退到当前目录的 `config.json` 或 `NEW_ERP_TOKEN`。切换账号或退出后,后续调用使用新的状态,已开始的调用继续使用开始时的会话。
76
+
77
+ 可识别的过期时间到期,或 ERP 返回登录失效时,需要重新运行 `new-erp login`。目前没有自动刷新 ERP token 的实现。权限不足保留为权限错误,不换用其他账号。
78
+
79
+ ```sh
80
+ new-erp logout
81
+ ```
82
+
83
+ `logout` 删除本机保存的会话,不撤销上游 token,也不修改项目配置或环境变量。旧 CLI/API 显式配置的认证仍按原方式生效;MCP 的 ERP 工具要求重新登录。
84
+
85
+ ## 打包与验证
86
+
87
+ ```sh
88
+ npm ci
89
+ npm test
90
+ npm run check:package
91
+ npm pack
92
+ ```
93
+
94
+ `npm pack` 生成可供 npm 安装的 `.tgz`。可作为 Release 附件分发;上传 Release 或发布 npm registry 是单独的发布操作。包中不包含本机会话、项目配置或测试数据。
95
+
96
+ `npm run check:package` 检查实际发布文件清单,阻止内部服务地址、个人路径、凭据和业务导出文件进入包。检查已生成的包可用 `node test/check-package-privacy.js ./new-erp-mcp-0.2.2.tgz`;检查结果只输出文件、行号和类别,不输出匹配到的敏感值。