@round2ai/r2-cli 1.0.15 → 1.0.17

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 PURESNAKE
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -5,9 +5,9 @@
5
5
 
6
6
  R2-CLI — 二手潮奢交易命令行工具,由 [Round2AI](https://github.com/Round2AI) 团队维护 — 让人类和 AI Agent 都能在终端中完成商品上架等交易操作。
7
7
 
8
- 覆盖商品上架、挂售、商品信息修改、认证登录等核心业务域,提供 19 个命令及 3 个 AI Agent [Skills](./skills/)。
8
+ 覆盖闲鱼/淘宝双平台商品上架、挂售、商品信息修改、认证登录等核心业务域,提供 20+ 命令及 3 个 AI Agent [Skills](./skills/)。
9
9
 
10
- [安装](#安装与快速开始) · [AI Agent 快速开始](#快速开始ai-agent) · [Agent Skills](#agent-skills) · [认证](#认证) · [命令](#命令参考) · [安全](#安全与风险提示)
10
+ [安装](#安装与快速开始) · [AI Agent 快速开始](#快速开始ai-agent) · [Agent Skills](#agent-skills) · [认证](#认证) · [命令](#命令参考) · [进阶用法](#进阶用法) · [安全](#安全与风险提示使用前必读) · [反馈](#反馈与支持)
11
11
 
12
12
  ## 为什么选 R2-CLI?
13
13
 
@@ -21,8 +21,9 @@ R2-CLI — 二手潮奢交易命令行工具,由 [Round2AI](https://github.com
21
21
  | 类别 | 能力 |
22
22
  |------|------|
23
23
  | 认证登录 | 扫码登录(第二回合 APP / 微信 / 支付宝)、闲鱼店铺授权、状态查询、登出(Agent 一步式流程) |
24
- | 商品管理 | 商品上架(4 步流程:获取店铺获取仓库获取选品商品提交上架 + 自动轮询上架结果)、商品信息修改(AI 读图识别自动匹配类目/属性提交修改)、店铺查看、仓库查看、选品商品查看、上架列表查询、下架、改价 |
25
- | 闲鱼挂售 | 图片上传(自动压缩大图、并行上传、失败重试)→ AI 读图识别商品信息自动匹配类目/属性提交挂售 |
24
+ | 商品管理(闲鱼) | 商品上架(4 步流程)、商品信息修改(AI 读图识别 自动匹配类目/属性提交修改)、挂售上架(图片上传 → AI 识别类目/属性匹配提交)、上架列表查询、下架、改价(支持同时修改运费和验货宝) |
25
+ | 商品管理(淘宝) | 阿里资产上架(SPU 查询 SKU 详情 选择 + 价格 申请上架)、已上架列表查询、改价、改库存、下架 |
26
+ | 跨平台查询 | 店铺查看、仓库查看、选品商品查看(共享命令,无需指定平台) |
26
27
 
27
28
  ---
28
29
 
@@ -45,8 +46,8 @@ r2-cli auth login
45
46
  # 2. 查看授权店铺
46
47
  r2-cli goods shops
47
48
 
48
- # 3. 交互式上架
49
- r2-cli goods up
49
+ # 3. 交互式上架(闲鱼)
50
+ r2-cli goods xianyu up
50
51
  ```
51
52
 
52
53
  ---
@@ -96,8 +97,8 @@ r2-cli goods stocks --json
96
97
  r2-cli goods list --stock-id <stockId> --json # 按仓库过滤
97
98
  r2-cli goods list --stock-goods-id <id> --json # 或按商品 ID 查询
98
99
 
99
- # 4. 提交上架(自动轮询上架结果)
100
- r2-cli goods up --stock-goods-id <id> --shop-id <id> --price <amount> --json
100
+ # 4. 提交上架(闲鱼,自动轮询上架结果)
101
+ r2-cli goods xianyu up --stock-goods-id <id> --shop-id <id> --price <amount> --json
101
102
  ```
102
103
 
103
104
  ---
@@ -117,7 +118,7 @@ npx skills add Round2AI/r2-cli --all -y
117
118
  |-------|------|
118
119
  | `r2-shared` | 共享基础:安装、统一错误格式、命令概览 |
119
120
  | `r2-auth` | 认证登录:一步式扫码登录(生成二维码 + 自动轮询,支持第二回合 APP / 微信 / 支付宝)、闲鱼店铺授权、状态查询、登出 |
120
- | `r2-goods` | 商品管理:4 步上架流程、挂售流程、商品信息修改(AI 读图识别 → 自动匹配类目/属性 → 提交)、下架、改价、店铺/仓库/商品/上架列表查看 |
121
+ | `r2-goods` | 商品管理:闲鱼 4 步上架流程、挂售流程、商品信息修改(AI 读图识别 → 自动匹配类目/属性 → 提交)、下架、改价(运费+验货宝)、淘宝阿里资产上架(SPU/SKU)、店铺/仓库/商品/上架列表查看 |
121
122
 
122
123
  ---
123
124
 
@@ -130,7 +131,10 @@ npx skills add Round2AI/r2-cli --all -y
130
131
  | `r2-cli auth login poll --token <>` | 手动轮询登录状态(备选,不推荐) |
131
132
  | `r2-cli auth xianyu` | 闲鱼店铺授权(自动打开浏览器,人类使用) |
132
133
  | `r2-cli auth xianyu --json` | 闲鱼店铺授权(自动打开浏览器 + JSON 输出,Agent 推荐) |
133
- | `r2-cli auth xianyu poll --state <>` | 轮询授权状态 JSON(备选,不推荐) |
134
+ | `r2-cli auth xianyu poll --state <>` | 轮询闲鱼授权状态 JSON(备选,不推荐) |
135
+ | `r2-cli auth taobao` | 淘宝店铺授权(自动打开浏览器,人类使用) |
136
+ | `r2-cli auth taobao --json` | 淘宝店铺授权(自动打开浏览器 + JSON 输出,Agent 推荐) |
137
+ | `r2-cli auth taobao poll --state <>` | 轮询淘宝授权状态 JSON(备选,不推荐) |
134
138
  | `r2-cli auth status` | 查看登录状态 |
135
139
  | `r2-cli auth logout` | 退出登录 |
136
140
 
@@ -140,41 +144,53 @@ Token 存储在 `~/.r2-cli/config.json`(原子写入防丢失),过期后
140
144
 
141
145
  ## 命令参考
142
146
 
143
- ### 商品查询
147
+ ### 商品查询(跨平台)
144
148
 
145
149
  | 命令 | 说明 |
146
150
  |------|------|
147
- | `r2-cli goods shops [--json]` | 查看所有已授权店铺(跨平台) |
151
+ | `r2-cli goods shops [--json]` | 查看所有已授权店铺(闲鱼 + 淘宝) |
148
152
  | `r2-cli goods stocks [--json]` | 查看所有仓库 |
149
153
  | `r2-cli goods list [--stock-id <id>] [--stock-goods-id <id>] [--json]` | 查看选品商品(可按仓库或商品 ID 过滤,支持 `--page` 和 `--size`,最大 50) |
150
- | `r2-cli goods listing [--json]` | 查询上架列表(支持 `--id` / `--shop-id` / `--stock-goods-id` / `--stock-id` / `--status <init|up|down|fail|sold>` / `--platform` 过滤,支持 `--page` / `--size` 分页) |
151
154
 
152
- ### 商品上架/下架/改价
155
+ ### 闲鱼上架/下架/改价
153
156
 
154
157
  | 命令 | 说明 |
155
158
  |------|------|
156
- | `r2-cli goods up` | 交互式上架(自动轮询上架结果) |
157
- | `r2-cli goods up --stock-goods-id <id> --shop-id <id> --price <amount> --json` | Agent 直接上架(自动轮询上架结果) |
158
- | `r2-cli goods down --id <id> [--json]` | 下架商品(也可用 `--stock-goods-id <id> --shop-id <id>`) |
159
- | `r2-cli goods price --id <id> --price <amount> [--json]` | 修改上架价格(也可用 `--stock-goods-id <id> --shop-id <id>`) |
159
+ | `r2-cli goods xianyu up` | 交互式上架(自动轮询上架结果) |
160
+ | `r2-cli goods xianyu up --stock-goods-id <id> --shop-id <id> --price <amount> --json` | Agent 直接上架 |
161
+ | `r2-cli goods xianyu down --id <id> [--json]` | 下架商品(也可用 `--stock-goods-id <id> --shop-id <id>`) |
162
+ | `r2-cli goods xianyu price --id <id> --price <amount> [--transport-fee <amount>] [--json]` | 改价(可同时修改运费) |
163
+ | `r2-cli goods xianyu listing [--json]` | 查询上架列表(支持 `--status <init|up|down|fail|sold>` / `--shop-id` / `--page` / `--size` 过滤) |
160
164
 
161
- ### 修改商品信息
165
+ ### 淘宝阿里资产管理
162
166
 
163
- 修改已上架商品的标题、描述、品牌、类目、图片、属性等。Agent 可自动读图识别并填充商品信息。
167
+ | 命令 | 说明 |
168
+ |------|------|
169
+ | `r2-cli goods taobao alzc spu-query --shop-id <id> --goods-no <no> [--json]` | 查询可申请的 SPU |
170
+ | `r2-cli goods taobao alzc spu-detail --shop-id <id> --jbp-spu-id <id> [--json]` | 查询 SPU 详情(含可申请 SKU) |
171
+ | `r2-cli goods taobao alzc apply --shop-id <id> --jbp-spu-id <id> --apply-skus '<json>' [--json]` | 申请上架 SKU |
172
+ | `r2-cli goods taobao listing --shop-id <id> [--json]` | 查询淘宝已上架列表 |
173
+ | `r2-cli goods taobao price --jbp-spu-id <id> --jbp-sku-id <id> --shop-id <id> --price <amount> --json` | 修改 SKU 价格 |
174
+ | `r2-cli goods taobao down --jbp-spu-id <id> --shop-id <id> [--json]` | 下架阿里资产商品 |
175
+
176
+ ### 闲鱼修改商品信息
177
+
178
+ 修改已上架商品的标题、描述、品牌、类目、图片、属性、运费、验货宝等。Agent 可自动读图识别并填充商品信息。
164
179
 
165
180
  | 命令 | 说明 |
166
181
  |------|------|
167
- | `r2-cli goods edit --id <id> --category-id <id> --channel-cat-id <id> --json` | 修改商品信息(必填:定位参数 + 类目) |
168
- | `r2-cli goods edit --id <id> --category-id <id> --channel-cat-id <id> --image-ids <ids> --item-attrs <json> --brand-name <name> --json` | 带图片和属性修改 |
182
+ | `r2-cli goods xianyu edit --id <id> --category-id <id> --channel-cat-id <id> --json` | 修改商品信息(必填:定位参数 + 类目) |
183
+ | `r2-cli goods xianyu edit --id <id> --category-id <id> --channel-cat-id <id> --image-ids <ids> --item-attrs <json> --brand-name <name> --json` | 带图片和属性修改 |
184
+ | `r2-cli goods xianyu edit --id <id> --category-id <id> --channel-cat-id <id> --transport-fee <amount> --yhb --json` | 修改运费和验货宝 |
169
185
 
170
186
  **定位商品**:优先使用 `--id <goodsListingId>`(从上架列表 `id` 字段获取),也可用 `--stock-goods-id <id> --account <shopId>`。**必填参数**:定位参数(二选一)+ `--category-id` + `--channel-cat-id`(后端必填)
171
187
 
172
188
  **关键约束**:
173
189
  - **类目 ID 必须传**:即使不改类目也要传 `--category-id` 和 `--channel-cat-id`,后端复用挂售 DTO,缺少会报 `getCategoryId() is null`
174
- - **`--item-attrs` 必须包含所有属性**:后端替换整个属性列表,漏传的属性会被清除。从 `goods hang-up props --channel-cat-id <id> --json` 获取全部属性后,修改目标值,其他保持原样一并传入
190
+ - **`--item-attrs` 必须包含所有属性**:后端替换整个属性列表,漏传的属性会被清除。从 `goods xianyu hang-up props --channel-cat-id <id> --json` 获取全部属性后,修改目标值,其他保持原样一并传入
175
191
  - **品牌必须双传**:`--brand-name`(文本字段)+ itemAttrs 中的品牌项(含 propId/valueId/valueName/propName/channelCatId 五个字段),缺一不可
176
192
 
177
- **可选参数**:`--title`、`--desc`、`--image-ids`(需先通过 `hang-up upload-images` 上传)、`--item-attrs`(JSON,5 字段格式)、`--brand-name`、`--stuff-status`、`--goods-no`、`--original-price`、`--size`
193
+ **可选参数**:`--title`、`--desc`、`--image-ids`(需先通过 `hang-up upload-images` 上传)、`--item-attrs`(JSON,5 字段格式)、`--brand-name`、`--stuff-status`、`--goods-no`、`--original-price`、`--size`、`--transport-fee`(运费,默认 0 包邮)、`--yhb`(验货宝)
178
194
 
179
195
  ### 闲鱼挂售(完整商品信息模式)
180
196
 
@@ -182,14 +198,16 @@ Token 存储在 `~/.r2-cli/config.json`(原子写入防丢失),过期后
182
198
 
183
199
  | 命令 | 说明 |
184
200
  |------|------|
185
- | `r2-cli goods hang-up categories [--json]` | 获取闲鱼类目列表(大分类 → 小分类) |
186
- | `r2-cli goods hang-up props --channel-cat-id <id> [--json]` | 获取指定类目下的属性列表(含可选值) |
187
- | `r2-cli goods hang-up brands --channel-cat-id <id> --prop-id <id> --key <keyword> [--json]` | 品牌搜索 |
188
- | `r2-cli goods hang-up upload-images --shop-id <id> --files <paths> --json` | 批量上传图片到闲鱼(挂售前必须先上传) |
189
- | `r2-cli goods hang-up submit --shop-id <id> --title <> --price <> --category-id <> --channel-cat-id <> --image-ids <> --stuff-status <> --desc <> --out-item-no <> --json` | 提交挂售上架 |
201
+ | `r2-cli goods xianyu hang-up categories [--json]` | 获取闲鱼类目列表(大分类 → 小分类) |
202
+ | `r2-cli goods xianyu hang-up props --channel-cat-id <id> [--json]` | 获取指定类目下的属性列表(含可选值) |
203
+ | `r2-cli goods xianyu hang-up brands --channel-cat-id <id> --prop-id <id> --key <keyword> [--json]` | 品牌搜索 |
204
+ | `r2-cli goods xianyu hang-up upload-images --shop-id <id> --files <paths> --json` | 批量上传图片到闲鱼(挂售前必须先上传) |
205
+ | `r2-cli goods xianyu hang-up submit --shop-id <id> --title <> --price <> --category-id <> --channel-cat-id <> --image-ids <> --stuff-status <> --desc <> --out-item-no <> --json` | 提交挂售上架 |
190
206
 
191
207
  **挂售必填参数**:`--shop-id`、`--title`、`--price`、`--category-id`(大分类 ID)、`--channel-cat-id`(小分类 ID)、`--image-ids`(图片 ID,逗号分隔)、`--stuff-status`(成色:100 全新 / -1 准新 / 99 99新 / 95 95新 / 90 9新)、`--desc`(商品描述)、`--out-item-no`(商家编码,同店铺唯一)
192
208
 
209
+ **校验规则**:标题最长 30 单位(半角字符 0.5、全角字符 1,约 30 汉字或 60 英文),售价上限 99,999,999 元,超长/超限提交时自动报错。
210
+
193
211
  **挂售可选参数**:`--brand-name`、`--size`、`--goods-no`、`--original-price`、`--item-attrs`(属性列表 JSON)、`--trade-type`(默认 0 仅在线)、`--transport-fee`(默认 0 包邮)、`--yhb`(验货宝)、`--division-id`(默认 330100 杭州)
194
212
 
195
213
  **售后服务**(默认关闭):提交时自动附带售后服务配置,默认全部关闭。卖家需在闲鱼 APP 开通对应服务后才能开启(我的 → 设置 → 卖家服务 → 保障服务)。
@@ -200,17 +218,74 @@ Token 存储在 `~/.r2-cli/config.json`(原子写入防丢失),过期后
200
218
  |------|------|
201
219
  | `r2-cli update` | 一键更新 CLI 和技能 |
202
220
  | `r2-cli uninstall` | 卸载 R2-CLI 并清除所有配置 |
221
+ | `r2-cli install` | 交互式引导安装(含 Skills 自动安装) |
222
+
223
+ ---
224
+
225
+ ## 进阶用法
226
+
227
+ ### 输出格式
228
+
229
+ 所有命令支持双模输出:
230
+
231
+ - **人类模式**(默认):交互式向导 + 终端表格,适合直接操作
232
+ - **Agent 模式**(`--json`):结构化 JSON 输出,适合 AI Agent 解析
233
+
234
+ ### 分页查询
235
+
236
+ 查询类命令(`goods list`、`goods xianyu listing`、`goods taobao listing`)支持分页:
237
+
238
+ ```bash
239
+ # 每页 50 条(最大)
240
+ r2-cli goods list --stock-id <id> --page 1 --size 50 --json
241
+ r2-cli goods xianyu listing --status up --page 2 --size 50 --json
242
+ ```
243
+
244
+ ### 状态过滤
245
+
246
+ ```bash
247
+ r2-cli goods xianyu listing --status up # 已上架
248
+ r2-cli goods xianyu listing --status sold # 已售出
249
+ r2-cli goods xianyu listing --status down # 已下架
250
+ ```
251
+
252
+ ### 跨店铺操作
253
+
254
+ 同一商品可上架到多个店铺,每个操作独立执行:
255
+
256
+ ```bash
257
+ r2-cli goods xianyu up --stock-goods-id <id> --shop-id <shopA> --price <n> --json
258
+ r2-cli goods xianyu up --stock-goods-id <id> --shop-id <shopB> --price <n> --json
259
+ ```
260
+
261
+ ### 批量操作
262
+
263
+ 批量上架/下架/改价时每个操作独立执行,一个失败不影响其他。批量操作间隔至少 1 秒,避免触发限流。
203
264
 
204
265
  ---
205
266
 
206
- ## 安全与风险提示
267
+ ## 安全与风险提示(使用前必读)
268
+
269
+ 本工具可供 AI Agent 调用以自动化操作二手潮奢交易。Agent 将以您的用户身份在授权范围内执行操作,可能导致商品误上架、价格错误、属性错误等风险,请谨慎操作。
270
+
271
+ ### Agent 操作约束
207
272
 
208
- 本工具可供 AI Agent 调用以自动化操作二手潮奢交易,Agent 将以您的用户身份在授权范围内执行操作,可能导致商品误上架、价格错误等风险,请谨慎操作。
273
+ 上架过程中 Agent 必须遵守以下安全规则:
209
274
 
210
- 建议:
211
- - Agent 收到"上架"指令时,若用户未明确指定方式(选品上架/挂售上架),**必须询问用户**选择哪种上架方式
212
- - Agent 自动识别图片并填充商品信息,售价必问用户;商家编码优先让用户自定义,不填则自动生成推荐
213
- - Token 存储在本地 `~/.r2-cli/config.json`(原子写入,防止中断导致配置丢失),注意保护
275
+ - **上架方式必须确认**:Agent 收到"上架"指令时,若用户未明确指定方式(选品上架/挂售上架),必须询问用户
276
+ - **售价必须询问**:Agent 自动识别图片并填充商品信息后,售价仍需用户确认,不能自行决定
277
+ - **商家编码优先自定义**:Agent 应先询问用户商家编码,用户不填时再自动生成推荐
278
+
279
+ ### 凭证安全
280
+
281
+ Token 存储在 `~/.r2-cli/config.json`(原子写入防丢失),过期后需重新登录。扫码登录自动打开浏览器展示品牌化扫码页面,支持第二回合 APP、微信、支付宝扫码。
282
+
283
+ ### 默认安全保护
284
+
285
+ - 所有 `--json` 命令统一错误格式,通过 `success` 字段判断成败
286
+ - 查询输出自动过滤敏感字段(accessToken、refreshExpireIn)
287
+ - 挂售提交默认关闭所有售后服务,避免未开通服务导致提交失败
288
+ - 网络错误自动重试(最多 2 次),认证错误不重试直接引导重新登录
214
289
 
215
290
  ---
216
291
 
@@ -234,6 +309,7 @@ PURESNAKE 深耕二手潮奢交易流通 6 年,累计鉴定超 400 万单,
234
309
  | 协议 | MIT |
235
310
  | 安装 | `npm install -g @round2ai/r2-cli` |
236
311
  | 授权 | `r2-cli auth login` |
312
+ | 输出格式 | 人类友好(默认) / `--json`(Agent) |
237
313
  | AI Agent Skills | 3 |
238
314
  | 数据源 | 通过 ERP 对接各电商平台、线下 POS、自营仓储 WMS |
239
315
 
@@ -241,6 +317,17 @@ PURESNAKE 深耕二手潮奢交易流通 6 年,累计鉴定超 400 万单,
241
317
 
242
318
  Already used by merchants in production.
243
319
 
320
+ ## 反馈与支持
321
+
322
+ 问题反馈或功能建议请通过以下渠道联系:
323
+
324
+ - 提交 GitHub Issue:https://github.com/Round2AI/r2-cli/issues
325
+ - 内部反馈:联系 Round2AI 团队
326
+
327
+ ## 许可证
328
+
329
+ 本项目基于 MIT 许可证开源。
330
+
244
331
  _Round2AI — 让潮奢循环交易没有摩擦。_
245
332
 
246
333
  _Reduce friction in circular commerce._
@@ -3,7 +3,7 @@
3
3
  <head>
4
4
  <meta charset="utf-8" />
5
5
  <meta name="viewport" content="width=device-width,initial-scale=1" />
6
- <title>闲鱼店铺授权</title>
6
+ <title>店铺授权</title>
7
7
  <style>
8
8
  * {
9
9
  box-sizing: border-box;
@@ -11,16 +11,16 @@
11
11
  padding: 0;
12
12
  }
13
13
  :root {
14
- --primary: #ffe60f;
15
- --primary-light: #ffe60f1a;
16
- --primary-dark: #ffe60fcc;
14
+ --primary: #999;
15
+ --primary-light: #9999991a;
16
+ --primary-dark: #999999cc;
17
17
  --text: #1a1a1a;
18
18
  --text-muted: #8c8c8c;
19
19
  --bg: #f7f8fa;
20
20
  --card: #fff;
21
21
  --border: #e8e8e8;
22
22
  --radius: 16px;
23
- --shadow: 0 2px 16px #ffe60f1a;
23
+ --shadow: 0 2px 16px #9999991a;
24
24
  --success: #52c41a;
25
25
  --error: #ff4d4f;
26
26
  --info: #1890ff;
@@ -110,7 +110,7 @@
110
110
  .auth-btn:hover {
111
111
  background: var(--primary-dark);
112
112
  transform: translateY(-1px);
113
- box-shadow: 0 4px 12px #ffe60f33;
113
+ box-shadow: 0 4px 12px #99999933;
114
114
  }
115
115
  .status-icon {
116
116
  font-size: 56px;
@@ -177,34 +177,48 @@
177
177
  <body>
178
178
  <div class="card" id="app">
179
179
  <div class="brand">
180
- <div class="brand-name">闲鱼授权</div>
180
+ <div class="brand-name" id="brandName">店铺授权</div>
181
181
  <div class="brand-sub">Round2AI</div>
182
182
  </div>
183
- <img id="qr" src="./qr.png" alt="闲鱼店铺授权" />
183
+ <img id="qr" src="./qr.png" alt="店铺授权" />
184
184
  <p class="status-text" id="statusText">请扫码授权</p>
185
185
  <p class="scan-hint">支持 浏览器 / 微信 扫码</p>
186
186
  <a class="auth-btn" id="auth-btn" style="display: none" href="#" target="_blank">点击授权</a>
187
187
  <p class="hint" id="hint"></p>
188
188
  </div>
189
189
  <script>
190
- const qr = document.getElementById("qr"),
190
+ var brandTitle = "店铺授权";
191
+ var qr = document.getElementById("qr"),
191
192
  st = document.getElementById("statusText"),
192
193
  ht = document.getElementById("hint"),
193
194
  app = document.getElementById("app"),
194
195
  bd = document.body;
195
- const states = {
196
+ var states = {
196
197
  waiting: { icon: "", text: "请扫码授权", hint: "", bg: "", dim: false },
197
198
  scanning: { icon: "", text: '<span class="pulse"></span>处理中...', hint: "等待确认中...", bg: "scanning-bg", dim: true },
198
199
  success: { icon: "✅", text: "授权成功!", hint: "可关闭此页面", bg: "success-bg", dim: true },
199
200
  expired: { icon: "⏰", text: "二维码已过期", hint: "请重新获取", bg: "expired-bg", dim: true },
200
201
  };
202
+ function applyBranding(color, title) {
203
+ if (color) {
204
+ document.documentElement.style.setProperty("--primary", color);
205
+ document.documentElement.style.setProperty("--primary-light", color + "1a");
206
+ document.documentElement.style.setProperty("--primary-dark", color + "cc");
207
+ document.documentElement.style.setProperty("--shadow", "0 2px 16px " + color + "1a");
208
+ }
209
+ if (title) {
210
+ brandTitle = title;
211
+ document.getElementById("brandName").textContent = title;
212
+ document.title = title;
213
+ }
214
+ }
201
215
  function render(s) {
202
- const d = states[s] || states.waiting;
216
+ var d = states[s] || states.waiting;
203
217
  bd.className = d.bg;
204
218
  if (d.icon) {
205
219
  qr.style.display = "none";
206
220
  app.innerHTML =
207
- '<div class="brand"><div class="brand-name">闲鱼授权</div><div class="brand-sub">Round2AI</div></div><div class="status-icon">' +
221
+ '<div class="brand"><div class="brand-name">' + brandTitle + '</div><div class="brand-sub">Round2AI</div></div><div class="status-icon">' +
208
222
  d.icon +
209
223
  '</div><p class="status-text">' +
210
224
  d.text +
@@ -222,6 +236,7 @@
222
236
  return r.json();
223
237
  })
224
238
  .then(function (data) {
239
+ applyBranding(data.primaryColor, data.title);
225
240
  if (data.authUrl) {
226
241
  var btn = document.getElementById("auth-btn");
227
242
  btn.href = data.authUrl;
@@ -229,10 +244,10 @@
229
244
  }
230
245
  })
231
246
  .catch(function () {});
232
- const es = new EventSource("./events");
247
+ var es = new EventSource("./events");
233
248
  es.onmessage = function (e) {
234
249
  try {
235
- const d = JSON.parse(e.data);
250
+ var d = JSON.parse(e.data);
236
251
  if (d.status) render(d.status);
237
252
  } catch (ex) {}
238
253
  };