@round2ai/r2-cli 1.0.12-beta.0 → 1.0.12-beta.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.
- package/README.md +24 -7
- package/dist/README.md +24 -7
- package/dist/pages/login.html +219 -57
- package/dist/pages/xianyu-auth.html +244 -67
- package/dist/r2-cli.js +2160 -46
- package/package.json +3 -3
- package/scripts/install-skills.js +11 -26
- package/skills/r2-auth/SKILL.md +1 -1
- package/skills/r2-goods/SKILL.md +82 -352
- package/skills/r2-goods/references/r2-goods-hangup.md +285 -0
- package/skills/r2-goods/references/r2-goods-listing.md +137 -0
- package/skills/r2-goods/references/r2-goods-query.md +63 -0
- package/skills/r2-shared/SKILL.md +40 -17
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
R2-CLI — 二手潮奢交易命令行工具,由 [Round2AI](https://github.com/Round2AI) 团队维护 — 让人类和 AI Agent 都能在终端中完成商品上架等交易操作。
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
覆盖商品上架、挂售、商品信息修改、认证登录等核心业务域,提供 16 个命令及 3 个 AI Agent [Skills](./skills/)。
|
|
9
9
|
|
|
10
10
|
[安装](#安装与快速开始) · [AI Agent 快速开始](#快速开始ai-agent) · [Agent Skills](#agent-skills) · [认证](#认证) · [命令](#命令参考) · [安全](#安全与风险提示)
|
|
11
11
|
|
|
@@ -21,8 +21,8 @@ R2-CLI — 二手潮奢交易命令行工具,由 [Round2AI](https://github.com
|
|
|
21
21
|
| 类别 | 能力 |
|
|
22
22
|
|------|------|
|
|
23
23
|
| 认证登录 | 扫码登录(第二回合 APP / 微信 / 支付宝)、闲鱼店铺授权、状态查询、登出(Agent 一步式流程) |
|
|
24
|
-
| 商品管理 | 商品上架(4 步流程:获取店铺 → 获取仓库 → 获取选品商品 → 提交上架 +
|
|
25
|
-
| 闲鱼挂售 |
|
|
24
|
+
| 商品管理 | 商品上架(4 步流程:获取店铺 → 获取仓库 → 获取选品商品 → 提交上架 + 自动轮询上架结果)、商品信息修改(AI 读图识别 → 自动匹配类目/属性 → 提交修改)、店铺查看、仓库查看、选品商品查看、上架列表查询、下架、改价 |
|
|
25
|
+
| 闲鱼挂售 | 图片上传 → AI 读图识别商品信息 → 自动匹配类目/属性 → 提交挂售 |
|
|
26
26
|
|
|
27
27
|
---
|
|
28
28
|
|
|
@@ -117,7 +117,7 @@ npx skills add Round2AI/r2-cli --all -y
|
|
|
117
117
|
|-------|------|
|
|
118
118
|
| `r2-shared` | 共享基础:安装、统一错误格式、命令概览 |
|
|
119
119
|
| `r2-auth` | 认证登录:一步式扫码登录(生成二维码 + 自动轮询,支持第二回合 APP / 微信 / 支付宝)、闲鱼店铺授权、状态查询、登出 |
|
|
120
|
-
| `r2-goods` | 商品管理:4
|
|
120
|
+
| `r2-goods` | 商品管理:4 步上架流程、挂售流程、商品信息修改(AI 读图识别 → 自动匹配类目/属性 → 提交)、下架、改价、店铺/仓库/商品/上架列表查看 |
|
|
121
121
|
|
|
122
122
|
---
|
|
123
123
|
|
|
@@ -149,7 +149,7 @@ Token 存储在 `~/.r2-cli/config.json`(原子写入防丢失),过期后
|
|
|
149
149
|
| `r2-cli goods list [--stock-id <id>] [--stock-goods-id <id>] [--json]` | 查看选品商品(可按仓库或商品 ID 过滤,支持 `--page` 和 `--size`) |
|
|
150
150
|
| `r2-cli goods listing [--json]` | 查询上架列表(支持 `--id` / `--shop-id` / `--stock-goods-id` / `--stock-id` / `--status` / `--platform` 过滤) |
|
|
151
151
|
|
|
152
|
-
###
|
|
152
|
+
### 商品上架/下架/改价
|
|
153
153
|
|
|
154
154
|
| 命令 | 说明 |
|
|
155
155
|
|------|------|
|
|
@@ -158,9 +158,22 @@ Token 存储在 `~/.r2-cli/config.json`(原子写入防丢失),过期后
|
|
|
158
158
|
| `r2-cli goods down --id <id> [--json]` | 下架商品(也可用 `--stock-goods-id <id> --shop-id <id>`) |
|
|
159
159
|
| `r2-cli goods price --id <id> --price <amount> [--json]` | 修改上架价格(也可用 `--stock-goods-id <id> --shop-id <id>`) |
|
|
160
160
|
|
|
161
|
+
### 修改商品信息
|
|
162
|
+
|
|
163
|
+
修改已上架商品的标题、描述、品牌、类目、图片、属性等。Agent 可自动读图识别并填充商品信息。
|
|
164
|
+
|
|
165
|
+
| 命令 | 说明 |
|
|
166
|
+
|------|------|
|
|
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` | 带图片和属性修改 |
|
|
169
|
+
|
|
170
|
+
**定位商品**:优先使用 `--id <goodsListingId>`(从上架列表 `id` 字段获取),也可用 `--stock-goods-id <id> --account <shopId>`。**必填参数**:定位参数(二选一)+ `--category-id` + `--channel-cat-id`(后端必填)
|
|
171
|
+
|
|
172
|
+
**可选参数**:`--title`、`--desc`、`--image-ids`(需先通过 `hang-up upload-images` 上传)、`--item-attrs`(JSON)、`--brand-name`、`--stuff-status`、`--goods-no`、`--original-price`、`--size`
|
|
173
|
+
|
|
161
174
|
### 闲鱼挂售(完整商品信息模式)
|
|
162
175
|
|
|
163
|
-
|
|
176
|
+
挂售模式支持完整的商品信息:图片、类目、属性、品牌等。Agent 可自动识别图片内容填充商品信息,流程:上传图片 → AI 识别 → 匹配类目/属性 → 提交。
|
|
164
177
|
|
|
165
178
|
| 命令 | 说明 |
|
|
166
179
|
|------|------|
|
|
@@ -174,10 +187,13 @@ Token 存储在 `~/.r2-cli/config.json`(原子写入防丢失),过期后
|
|
|
174
187
|
|
|
175
188
|
**挂售可选参数**:`--brand-name`、`--size`、`--goods-no`、`--original-price`、`--item-attrs`(属性列表 JSON)、`--trade-type`(默认 0 仅在线)、`--transport-fee`(默认 0 包邮)、`--yhb`(验货宝)、`--division-id`(默认 330100 杭州)
|
|
176
189
|
|
|
190
|
+
**售后服务**(默认关闭):提交时自动附带售后服务配置,默认全部关闭。卖家需在闲鱼 APP 开通对应服务后才能开启(我的 → 设置 → 卖家服务 → 保障服务)。
|
|
191
|
+
|
|
177
192
|
### 其他命令
|
|
178
193
|
|
|
179
194
|
| 命令 | 说明 |
|
|
180
195
|
|------|------|
|
|
196
|
+
| `r2-cli update` | 一键更新 CLI 和技能 |
|
|
181
197
|
| `r2-cli uninstall` | 卸载 R2-CLI 并清除所有配置 |
|
|
182
198
|
|
|
183
199
|
---
|
|
@@ -187,7 +203,8 @@ Token 存储在 `~/.r2-cli/config.json`(原子写入防丢失),过期后
|
|
|
187
203
|
本工具可供 AI Agent 调用以自动化操作二手潮奢交易,Agent 将以您的用户身份在授权范围内执行操作,可能导致商品误上架、价格错误等风险,请谨慎操作。
|
|
188
204
|
|
|
189
205
|
建议:
|
|
190
|
-
- Agent
|
|
206
|
+
- Agent 收到"上架"指令时,若用户未明确指定方式(选品上架/挂售上架),**必须询问用户**选择哪种上架方式
|
|
207
|
+
- Agent 自动识别图片并填充商品信息,缺少必填字段(售价、商家编码)时会向用户询问
|
|
191
208
|
- Token 存储在本地 `~/.r2-cli/config.json`(原子写入,防止中断导致配置丢失),注意保护
|
|
192
209
|
|
|
193
210
|
---
|
package/dist/README.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
R2-CLI — 二手潮奢交易命令行工具,由 [Round2AI](https://github.com/Round2AI) 团队维护 — 让人类和 AI Agent 都能在终端中完成商品上架等交易操作。
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
覆盖商品上架、挂售、商品信息修改、认证登录等核心业务域,提供 16 个命令及 3 个 AI Agent [Skills](./skills/)。
|
|
9
9
|
|
|
10
10
|
[安装](#安装与快速开始) · [AI Agent 快速开始](#快速开始ai-agent) · [Agent Skills](#agent-skills) · [认证](#认证) · [命令](#命令参考) · [安全](#安全与风险提示)
|
|
11
11
|
|
|
@@ -21,8 +21,8 @@ R2-CLI — 二手潮奢交易命令行工具,由 [Round2AI](https://github.com
|
|
|
21
21
|
| 类别 | 能力 |
|
|
22
22
|
|------|------|
|
|
23
23
|
| 认证登录 | 扫码登录(第二回合 APP / 微信 / 支付宝)、闲鱼店铺授权、状态查询、登出(Agent 一步式流程) |
|
|
24
|
-
| 商品管理 | 商品上架(4 步流程:获取店铺 → 获取仓库 → 获取选品商品 → 提交上架 +
|
|
25
|
-
| 闲鱼挂售 |
|
|
24
|
+
| 商品管理 | 商品上架(4 步流程:获取店铺 → 获取仓库 → 获取选品商品 → 提交上架 + 自动轮询上架结果)、商品信息修改(AI 读图识别 → 自动匹配类目/属性 → 提交修改)、店铺查看、仓库查看、选品商品查看、上架列表查询、下架、改价 |
|
|
25
|
+
| 闲鱼挂售 | 图片上传 → AI 读图识别商品信息 → 自动匹配类目/属性 → 提交挂售 |
|
|
26
26
|
|
|
27
27
|
---
|
|
28
28
|
|
|
@@ -117,7 +117,7 @@ npx skills add Round2AI/r2-cli --all -y
|
|
|
117
117
|
|-------|------|
|
|
118
118
|
| `r2-shared` | 共享基础:安装、统一错误格式、命令概览 |
|
|
119
119
|
| `r2-auth` | 认证登录:一步式扫码登录(生成二维码 + 自动轮询,支持第二回合 APP / 微信 / 支付宝)、闲鱼店铺授权、状态查询、登出 |
|
|
120
|
-
| `r2-goods` | 商品管理:4
|
|
120
|
+
| `r2-goods` | 商品管理:4 步上架流程、挂售流程、商品信息修改(AI 读图识别 → 自动匹配类目/属性 → 提交)、下架、改价、店铺/仓库/商品/上架列表查看 |
|
|
121
121
|
|
|
122
122
|
---
|
|
123
123
|
|
|
@@ -149,7 +149,7 @@ Token 存储在 `~/.r2-cli/config.json`(原子写入防丢失),过期后
|
|
|
149
149
|
| `r2-cli goods list [--stock-id <id>] [--stock-goods-id <id>] [--json]` | 查看选品商品(可按仓库或商品 ID 过滤,支持 `--page` 和 `--size`) |
|
|
150
150
|
| `r2-cli goods listing [--json]` | 查询上架列表(支持 `--id` / `--shop-id` / `--stock-goods-id` / `--stock-id` / `--status` / `--platform` 过滤) |
|
|
151
151
|
|
|
152
|
-
###
|
|
152
|
+
### 商品上架/下架/改价
|
|
153
153
|
|
|
154
154
|
| 命令 | 说明 |
|
|
155
155
|
|------|------|
|
|
@@ -158,9 +158,22 @@ Token 存储在 `~/.r2-cli/config.json`(原子写入防丢失),过期后
|
|
|
158
158
|
| `r2-cli goods down --id <id> [--json]` | 下架商品(也可用 `--stock-goods-id <id> --shop-id <id>`) |
|
|
159
159
|
| `r2-cli goods price --id <id> --price <amount> [--json]` | 修改上架价格(也可用 `--stock-goods-id <id> --shop-id <id>`) |
|
|
160
160
|
|
|
161
|
+
### 修改商品信息
|
|
162
|
+
|
|
163
|
+
修改已上架商品的标题、描述、品牌、类目、图片、属性等。Agent 可自动读图识别并填充商品信息。
|
|
164
|
+
|
|
165
|
+
| 命令 | 说明 |
|
|
166
|
+
|------|------|
|
|
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` | 带图片和属性修改 |
|
|
169
|
+
|
|
170
|
+
**定位商品**:优先使用 `--id <goodsListingId>`(从上架列表 `id` 字段获取),也可用 `--stock-goods-id <id> --account <shopId>`。**必填参数**:定位参数(二选一)+ `--category-id` + `--channel-cat-id`(后端必填)
|
|
171
|
+
|
|
172
|
+
**可选参数**:`--title`、`--desc`、`--image-ids`(需先通过 `hang-up upload-images` 上传)、`--item-attrs`(JSON)、`--brand-name`、`--stuff-status`、`--goods-no`、`--original-price`、`--size`
|
|
173
|
+
|
|
161
174
|
### 闲鱼挂售(完整商品信息模式)
|
|
162
175
|
|
|
163
|
-
|
|
176
|
+
挂售模式支持完整的商品信息:图片、类目、属性、品牌等。Agent 可自动识别图片内容填充商品信息,流程:上传图片 → AI 识别 → 匹配类目/属性 → 提交。
|
|
164
177
|
|
|
165
178
|
| 命令 | 说明 |
|
|
166
179
|
|------|------|
|
|
@@ -174,10 +187,13 @@ Token 存储在 `~/.r2-cli/config.json`(原子写入防丢失),过期后
|
|
|
174
187
|
|
|
175
188
|
**挂售可选参数**:`--brand-name`、`--size`、`--goods-no`、`--original-price`、`--item-attrs`(属性列表 JSON)、`--trade-type`(默认 0 仅在线)、`--transport-fee`(默认 0 包邮)、`--yhb`(验货宝)、`--division-id`(默认 330100 杭州)
|
|
176
189
|
|
|
190
|
+
**售后服务**(默认关闭):提交时自动附带售后服务配置,默认全部关闭。卖家需在闲鱼 APP 开通对应服务后才能开启(我的 → 设置 → 卖家服务 → 保障服务)。
|
|
191
|
+
|
|
177
192
|
### 其他命令
|
|
178
193
|
|
|
179
194
|
| 命令 | 说明 |
|
|
180
195
|
|------|------|
|
|
196
|
+
| `r2-cli update` | 一键更新 CLI 和技能 |
|
|
181
197
|
| `r2-cli uninstall` | 卸载 R2-CLI 并清除所有配置 |
|
|
182
198
|
|
|
183
199
|
---
|
|
@@ -187,7 +203,8 @@ Token 存储在 `~/.r2-cli/config.json`(原子写入防丢失),过期后
|
|
|
187
203
|
本工具可供 AI Agent 调用以自动化操作二手潮奢交易,Agent 将以您的用户身份在授权范围内执行操作,可能导致商品误上架、价格错误等风险,请谨慎操作。
|
|
188
204
|
|
|
189
205
|
建议:
|
|
190
|
-
- Agent
|
|
206
|
+
- Agent 收到"上架"指令时,若用户未明确指定方式(选品上架/挂售上架),**必须询问用户**选择哪种上架方式
|
|
207
|
+
- Agent 自动识别图片并填充商品信息,缺少必填字段(售价、商家编码)时会向用户询问
|
|
191
208
|
- Token 存储在本地 `~/.r2-cli/config.json`(原子写入,防止中断导致配置丢失),注意保护
|
|
192
209
|
|
|
193
210
|
---
|
package/dist/pages/login.html
CHANGED
|
@@ -1,57 +1,219 @@
|
|
|
1
|
-
<!
|
|
2
|
-
<html lang="zh-CN"
|
|
3
|
-
<
|
|
4
|
-
<
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="zh-CN">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
|
6
|
+
<title>第二回合 - 扫码登录</title>
|
|
7
|
+
<style>
|
|
8
|
+
* {
|
|
9
|
+
box-sizing: border-box;
|
|
10
|
+
margin: 0;
|
|
11
|
+
padding: 0;
|
|
12
|
+
}
|
|
13
|
+
:root {
|
|
14
|
+
--primary: #06d290;
|
|
15
|
+
--primary-light: #06d2901a;
|
|
16
|
+
--primary-dark: #06d290cc;
|
|
17
|
+
--text: #1a1a1a;
|
|
18
|
+
--text-muted: #8c8c8c;
|
|
19
|
+
--bg: #f7f8fa;
|
|
20
|
+
--card: #fff;
|
|
21
|
+
--border: #e8e8e8;
|
|
22
|
+
--radius: 16px;
|
|
23
|
+
--shadow: 0 2px 16px #06d2901a;
|
|
24
|
+
--success: #52c41a;
|
|
25
|
+
--error: #ff4d4f;
|
|
26
|
+
--info: #1890ff;
|
|
27
|
+
}
|
|
28
|
+
body {
|
|
29
|
+
display: flex;
|
|
30
|
+
flex-direction: column;
|
|
31
|
+
align-items: center;
|
|
32
|
+
justify-content: center;
|
|
33
|
+
min-height: 100vh;
|
|
34
|
+
font-family:
|
|
35
|
+
system-ui,
|
|
36
|
+
-apple-system,
|
|
37
|
+
"Segoe UI",
|
|
38
|
+
Roboto,
|
|
39
|
+
sans-serif;
|
|
40
|
+
background: var(--bg);
|
|
41
|
+
color: var(--text);
|
|
42
|
+
}
|
|
43
|
+
.card {
|
|
44
|
+
background: var(--card);
|
|
45
|
+
border-radius: var(--radius);
|
|
46
|
+
padding: 40px 32px 32px;
|
|
47
|
+
box-shadow: var(--shadow);
|
|
48
|
+
border: 1px solid var(--border);
|
|
49
|
+
text-align: center;
|
|
50
|
+
max-width: 360px;
|
|
51
|
+
width: 90%;
|
|
52
|
+
transition: all 0.3s ease;
|
|
53
|
+
}
|
|
54
|
+
.brand {
|
|
55
|
+
margin-bottom: 24px;
|
|
56
|
+
}
|
|
57
|
+
.brand-name {
|
|
58
|
+
font-size: 22px;
|
|
59
|
+
font-weight: 700;
|
|
60
|
+
color: var(--text);
|
|
61
|
+
letter-spacing: 2px;
|
|
62
|
+
}
|
|
63
|
+
.brand-sub {
|
|
64
|
+
font-size: 10px;
|
|
65
|
+
color: var(--text-muted);
|
|
66
|
+
margin-top: 4px;
|
|
67
|
+
letter-spacing: 3px;
|
|
68
|
+
text-transform: uppercase;
|
|
69
|
+
font-weight: 500;
|
|
70
|
+
}
|
|
71
|
+
img#qr {
|
|
72
|
+
max-width: 200px;
|
|
73
|
+
border-radius: 12px;
|
|
74
|
+
transition: all 0.3s ease;
|
|
75
|
+
}
|
|
76
|
+
img#qr.dimmed {
|
|
77
|
+
opacity: 0.15;
|
|
78
|
+
filter: blur(4px);
|
|
79
|
+
transform: scale(0.95);
|
|
80
|
+
}
|
|
81
|
+
.status-text {
|
|
82
|
+
font-size: 16px;
|
|
83
|
+
font-weight: 600;
|
|
84
|
+
color: var(--text);
|
|
85
|
+
margin-top: 16px;
|
|
86
|
+
}
|
|
87
|
+
.hint {
|
|
88
|
+
color: var(--text-muted);
|
|
89
|
+
font-size: 13px;
|
|
90
|
+
margin-top: 6px;
|
|
91
|
+
}
|
|
92
|
+
.scan-hint {
|
|
93
|
+
color: var(--text-muted);
|
|
94
|
+
font-size: 12px;
|
|
95
|
+
margin-top: 16px;
|
|
96
|
+
}
|
|
97
|
+
.status-icon {
|
|
98
|
+
font-size: 56px;
|
|
99
|
+
margin-bottom: 8px;
|
|
100
|
+
animation: popIn 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275);
|
|
101
|
+
}
|
|
102
|
+
@keyframes popIn {
|
|
103
|
+
0% {
|
|
104
|
+
transform: scale(0);
|
|
105
|
+
opacity: 0;
|
|
106
|
+
}
|
|
107
|
+
100% {
|
|
108
|
+
transform: scale(1);
|
|
109
|
+
opacity: 1;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
.success-bg .card {
|
|
113
|
+
border-color: var(--success);
|
|
114
|
+
box-shadow: 0 2px 16px rgba(82, 196, 26, 0.12);
|
|
115
|
+
}
|
|
116
|
+
.success-bg .status-text {
|
|
117
|
+
color: var(--success);
|
|
118
|
+
}
|
|
119
|
+
.expired-bg .card {
|
|
120
|
+
border-color: var(--error);
|
|
121
|
+
box-shadow: 0 2px 16px rgba(255, 77, 79, 0.1);
|
|
122
|
+
}
|
|
123
|
+
.expired-bg .status-text {
|
|
124
|
+
color: var(--error);
|
|
125
|
+
}
|
|
126
|
+
.scanning-bg .card {
|
|
127
|
+
border-color: var(--info);
|
|
128
|
+
box-shadow: 0 2px 16px rgba(24, 144, 255, 0.1);
|
|
129
|
+
}
|
|
130
|
+
.scanning-bg .status-text {
|
|
131
|
+
color: var(--info);
|
|
132
|
+
}
|
|
133
|
+
.pulse {
|
|
134
|
+
display: inline-block;
|
|
135
|
+
width: 6px;
|
|
136
|
+
height: 6px;
|
|
137
|
+
border-radius: 50%;
|
|
138
|
+
background: var(--info);
|
|
139
|
+
animation: pulse 1.4s infinite;
|
|
140
|
+
margin-right: 6px;
|
|
141
|
+
vertical-align: middle;
|
|
142
|
+
}
|
|
143
|
+
@keyframes pulse {
|
|
144
|
+
0% {
|
|
145
|
+
opacity: 1;
|
|
146
|
+
transform: scale(1);
|
|
147
|
+
}
|
|
148
|
+
50% {
|
|
149
|
+
opacity: 0.4;
|
|
150
|
+
transform: scale(0.8);
|
|
151
|
+
}
|
|
152
|
+
100% {
|
|
153
|
+
opacity: 1;
|
|
154
|
+
transform: scale(1);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
</style>
|
|
158
|
+
</head>
|
|
159
|
+
<body>
|
|
160
|
+
<div class="card" id="app">
|
|
161
|
+
<div class="brand">
|
|
162
|
+
<div class="brand-name">第二回合</div>
|
|
163
|
+
<div class="brand-sub">Round2AI</div>
|
|
164
|
+
</div>
|
|
165
|
+
<img id="qr" src="./qr.png" alt="第二回合 - 扫码登录" />
|
|
166
|
+
<p class="status-text" id="statusText">请扫码登录</p>
|
|
167
|
+
<p class="scan-hint">支持 第二回合 APP / 微信 / 支付宝 扫码</p>
|
|
168
|
+
<p class="hint" id="hint"></p>
|
|
169
|
+
</div>
|
|
170
|
+
<script>
|
|
171
|
+
const qr = document.getElementById("qr"),
|
|
172
|
+
st = document.getElementById("statusText"),
|
|
173
|
+
ht = document.getElementById("hint"),
|
|
174
|
+
app = document.getElementById("app"),
|
|
175
|
+
bd = document.body;
|
|
176
|
+
const states = {
|
|
177
|
+
waiting: { icon: "", text: "请扫码登录", hint: "", bg: "", dim: false },
|
|
178
|
+
scanning: {
|
|
179
|
+
icon: "",
|
|
180
|
+
text: '<span class="pulse"></span>已扫码,请在手机上确认',
|
|
181
|
+
hint: "等待确认中...",
|
|
182
|
+
bg: "scanning-bg",
|
|
183
|
+
dim: true,
|
|
184
|
+
},
|
|
185
|
+
success: { icon: "✅", text: "登录成功!", hint: "可关闭此页面", bg: "success-bg", dim: true },
|
|
186
|
+
expired: { icon: "⏰", text: "二维码已过期", hint: "请重新获取", bg: "expired-bg", dim: true },
|
|
187
|
+
};
|
|
188
|
+
function render(s) {
|
|
189
|
+
const d = states[s] || states.waiting;
|
|
190
|
+
bd.className = d.bg;
|
|
191
|
+
if (d.icon) {
|
|
192
|
+
qr.style.display = "none";
|
|
193
|
+
app.innerHTML =
|
|
194
|
+
'<div class="brand"><div class="brand-name">第二回合</div><div class="brand-sub">Round2AI</div></div><div class="status-icon">' +
|
|
195
|
+
d.icon +
|
|
196
|
+
'</div><p class="status-text">' +
|
|
197
|
+
d.text +
|
|
198
|
+
"</p>" +
|
|
199
|
+
(d.hint ? '<p class="hint">' + d.hint + "</p>" : "");
|
|
200
|
+
} else {
|
|
201
|
+
qr.style.display = "";
|
|
202
|
+
qr.classList.toggle("dimmed", d.dim);
|
|
203
|
+
st.innerHTML = d.text;
|
|
204
|
+
ht.textContent = d.hint;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
const es = new EventSource("./events");
|
|
208
|
+
es.onmessage = function (e) {
|
|
209
|
+
try {
|
|
210
|
+
const d = JSON.parse(e.data);
|
|
211
|
+
if (d.status) render(d.status);
|
|
212
|
+
} catch (ex) {}
|
|
213
|
+
};
|
|
214
|
+
es.onerror = function () {
|
|
215
|
+
es.close();
|
|
216
|
+
};
|
|
217
|
+
</script>
|
|
218
|
+
</body>
|
|
219
|
+
</html>
|