1 当前在售商品
+ +套餐由授权系统实时拉取,显示的就是当前在售的商品。
+2 选择支付方式
+ +点击后会打开支付页面,付款完成回到本页会自动显示激活结果。
+From ec8bfda853c222fc78ba4d2e49f90985e0edd5dd Mon Sep 17 00:00:00 2001 From: jinghui <181050043@qq.com> Date: Tue, 20 Oct 2026 18:55:05 +0800 Subject: [PATCH] =?UTF-8?q?v1.10.0:=20=E6=96=B0=E5=A2=9E=E3=80=8C=E5=BD=93?= =?UTF-8?q?=E5=89=8D=E5=95=86=E5=93=81=E9=80=89=E6=8B=A9=E9=A1=B5=E3=80=8D?= =?UTF-8?q?=E2=80=94=E2=80=94=E4=BE=A7=E8=BE=B9=E6=A0=8F=E8=B4=AD=E4=B9=B0?= =?UTF-8?q?=E5=85=A5=E5=8F=A3=E6=94=B9=E4=B8=BA=E6=8F=92=E4=BB=B6=E5=86=85?= =?UTF-8?q?=E7=BD=AE=20buy.html?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - buy.html/css/js:实时拉取授权系统当前在售商品 → 选商品 → 选支付方式 → 下单 - background.js:新增 getCardTypes / authCreateOrder / authQueryOrder 三个消息与实现 - 支付成功自动发卡并激活本机;新增 alarms 权限做后台订单轮询(关页仍完成),12 小时未完成自动停 - sidepanel.js:licBuy 从跳 https://auth.88531.cn 改为打开内置 buy.html(不改服务端) - manifest 1.9.0 → 1.10.0 + alarms 权限 - CHANGELOG/README 同步:新增条目、文件结构、内置购买页说明、Gitea 源 --- CHANGELOG.md | 15 ++++++ README.md | 3 ++ background.js | 118 +++++++++++++++++++++++++++++++++++++++++++ buy.css | 136 +++++++++++++++++++++++++++++++++++++++++++++++++ buy.html | 48 ++++++++++++++++++ buy.js | 137 ++++++++++++++++++++++++++++++++++++++++++++++++++ manifest.json | 4 +- sidepanel.js | 2 +- 8 files changed, 460 insertions(+), 3 deletions(-) create mode 100644 buy.css create mode 100644 buy.html create mode 100644 buy.js diff --git a/CHANGELOG.md b/CHANGELOG.md index eec454f..8fc157c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,21 @@ B站评论助手 版本历史。下载:https://dl.88531.cn/bili.html · --- +## v1.10.0 · 2026-10-20 + +### ✨ 新功能 +- **新增「当前商品选择页」`buy.html`**:侧边栏「购买授权 →」不再跳外部授权站点,改为在插件内打开新标签页,实时展示授权系统**当前在售的商品**(名称 / 价格 / 时长),选中后进入下一步 +- **三步购买流程**:选当前商品 → 选支付方式(支付宝 / 微信)→ 完成支付后**自动发卡并激活本机**,全程无需手动输入卡密 +- **后台订单轮询**(新增 `alarms` 权限):购买页或侧边栏被关掉,后台仍继续轮询,支付成功后自动完成激活;超过 12 小时未完成的订单自动停止轮询,不会永久占用 +- 订单状态区分「等待支付 / 支付成功 / 激活失败 / 超时」,等待时实时显示已等待秒数,超时给出订单号供人工补发 + +### 🔧 调整 +- 购买入口从 `https://auth.88531.cn` 改为插件内置页 `buy.html`(B站蓝 `#00A1D6` 配色),页脚保留官网 `dl.88531.cn/bili.html`、GitHub、Telegram 入口 +- 商品列表由授权系统实时下发:显示的就是当前在售商品,下架商品不会出现在页面上 +- 本版本只调用授权系统的公开读写接口,**不改动服务端任何配置** + +--- + ## v1.9.0 · 2026-10-14 ### ✨ 新功能 diff --git a/README.md b/README.md index 20eba1c..e13bb38 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,7 @@ Chrome/Edge 浏览器插件(Manifest V3):按**搜索关键词**找 B站视 ### 授权与运维 - 🔑 3 天免费试用 / 30 条评论(任一先到即止,倒计时精确到秒并显示剩余条数),卡密激活绑定本机永久可用、不限量;试用到期后 24 小时内购买享 8 折;**过期只锁自动评论,搜索/AI 生成/下载视频不受影响** +- 🛒 **内置当前商品选择页**:点「购买授权 →」在插件内打开新标签页,实时展示授权系统当前在售商品 → 选商品 → 选支付方式(支付宝/微信)→ 支付成功**自动发卡并激活本机**;购买页关掉后台仍会轮询完成激活 - 📊 安装统计上报(仅机器码 + 版本,不碰B站账号),后台可看安装数与版本分布 - 📢 公告推送到面板顶部,有新版本时提示并跳官网 - 🔁 可中断:随时 ⏹ 停止,停止标记跨页面刷新保留,发送前二次检查 @@ -80,6 +81,7 @@ AI 模式需填 LLM 配置(已预填 `https://ai.88531.cn/v1` + `mimo-v2.6-fla | `background.js` | Service worker:LLM 代理、API 兜底、评论历史、运行编排、授权、安装上报 | | `content.js` / `content.css` | 页面内执行:搜索 → 生成 → 发布/私信 + 进度浮层 + 视频下载取址 | | `sidepanel.html` / `sidepanel.js` | 侧边栏 UI(含视频下载落盘) | +| `buy.html` / `buy.css` / `buy.js` | 当前商品选择页(选商品 → 选支付方式 → 下单 → 支付后自动激活本机) | | `icons/` | 16/32/48/128 图标 | ## 关键技术点(踩坑记录) @@ -100,6 +102,7 @@ AI 模式需填 LLM 配置(已预填 `https://ai.88531.cn/v1` + `mimo-v2.6-fla - GitHub:https://github.com/personal82555/bili-auto-comment - Gitee:https://gitee.com/jinghui111/bili-auto-comment +- Gitea(自建):http://192.168.68.19:3200/jinghui/bili-auto-comment ## 免责声明 diff --git a/background.js b/background.js index 647a1f8..ac0c358 100644 --- a/background.js +++ b/background.js @@ -552,6 +552,111 @@ async function handleGetDownloadInfo(p, sendResponse) { } } +// ============ 购买:当前商品(套餐)→ 订单 → 支付 → 自动激活本机 ============ +// 只调用授权系统的公开接口读取在售商品、创建订单,不改动服务端任何配置。 + +// 当前在售商品:由授权系统实时下发(页面显示的就是当前在售的) +async function getCardTypes() { + try { + const r = await authFetch("/public/projects/" + PROJECT_ID + "/card-types", {}, 8000); + if (r && r.code === 200 && Array.isArray(r.data)) return { ok: true, data: r.data }; + return { ok: false, data: [], message: (r && r.message) || "商品加载失败" }; + } catch (e) { + return { ok: false, data: [], message: String(e && e.message || e) }; + } +} + +// 创建订单:contact_info 带机器码 → 支付成功后服务端自动发卡并绑定本机 +async function authCreateOrder(payType, cardTypeId) { + const pay = payType === "wxpay" ? "wxpay" : "alipay"; + const types = await getCardTypes(); + if (!types.ok || !types.data.length) return { ok: false, message: types.message || "当前暂无在售商品" }; + const cardType = types.data.find(t => String(t.id) === String(cardTypeId)) + || types.data.find(t => Number(t.price) > 0) + || types.data[0]; + if (!cardType) return { ok: false, message: "商品不存在,请重新选择" }; + + const machine = await getMachineId(); + const price = Number(cardType.price); + const r = await authFetch("/public/orders", { + method: "POST", + headers: { "Content-Type": "application/json", "X-Api-Key": CARD_API_KEY }, + body: JSON.stringify({ + project_id: PROJECT_ID, + card_type_id: cardType.id, + amount: price, + pay_type: pay, + contact_info: "MACHINE:" + machine + }) + }, 15000); + + if (!r || r.code !== 200 || !r.data) return { ok: false, message: (r && r.message) || "创建订单失败" }; + + // 记住进行中的订单,供后台轮询恢复 + const pendingOrder = { + orderNo: r.data.order_no, + payType: pay, + amount: r.data.pay_amount != null ? Number(r.data.pay_amount) : price, + originalPrice: price, + packageName: cardType.name || "", + createdAt: Date.now() + }; + await chrome.storage.local.set({ pendingOrder }); + scheduleOrderPolling(); + + return { ok: true, order: pendingOrder, payUrl: r.data.pay_url || "", cardTypeName: cardType.name }; +} + +// 查询订单:服务端发卡后返回 card_key,拿到即自动激活本机 +async function authQueryOrder(orderNo) { + const r = await authFetch("/public/orders/query?order_no=" + encodeURIComponent(orderNo), {}, 8000); + if (!r || r.code !== 200 || !r.data) return { ok: false, message: (r && r.message) || "订单查询失败" }; + const d = r.data; + const out = { + ok: true, + paid: d.status === "paid" || !!d.card_key, + status: d.status || "", + cardKey: d.card_key || "", + expireTime: d.expire_time || "" + }; + if (out.cardKey) { + const act = await activateCard(out.cardKey); + out.activated = !!(act && act.ok); + out.message = (act && act.message) || ""; + if (out.activated) { + await chrome.storage.local.remove(["pendingOrder"]); + await clearOrderAlarm(); + } + } + return out; +} + +// 后台轮询:购买页被关掉也能走完「支付 → 发卡 → 激活」 +async function scheduleOrderPolling() { + try { if (chrome.alarms) await chrome.alarms.create("orderPoll", { periodInMinutes: 1 }); } catch (e) {} +} +async function clearOrderAlarm() { + try { if (chrome.alarms) await chrome.alarms.clear("orderPoll"); } catch (e) {} +} +if (chrome.alarms && chrome.alarms.onAlarm) { + chrome.alarms.onAlarm.addListener(async (alarm) => { + if (!alarm || alarm.name !== "orderPoll") return; + try { + const st = await chrome.storage.local.get("pendingOrder"); + const po = st.pendingOrder; + if (!po || !po.orderNo) { await clearOrderAlarm(); return; } + // 超过 12 小时未完成就不再追问,避免永久轮询 + if (Date.now() - (Number(po.createdAt) || 0) > 12 * 3600 * 1000) { + await chrome.storage.local.remove(["pendingOrder"]); + await clearOrderAlarm(); + return; + } + const res = await authQueryOrder(po.orderNo); + if (res && res.activated) await clearOrderAlarm(); + } catch (e) { /* 单次轮询失败不影响下次 */ } + }); +} + // ============ 消息路由 ============ chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => { @@ -593,6 +698,19 @@ chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => { })(); return true; } + // 当前商品选择页(buy.html)用 + if (msg.action === "getCardTypes") { + getCardTypes().then(sendResponse).catch(e => sendResponse({ ok: false, data: [], message: String(e && e.message || e) })); + return true; + } + if (msg.action === "authCreateOrder") { + authCreateOrder(msg.payType, msg.cardTypeId).then(sendResponse).catch(e => sendResponse({ ok: false, message: String(e && e.message || e) })); + return true; + } + if (msg.action === "authQueryOrder") { + authQueryOrder(msg.orderNo).then(sendResponse).catch(e => sendResponse({ ok: false, message: String(e && e.message || e) })); + return true; + } if (msg.action === "setTask") { ACTIVE_TASK = msg.task || null; sendResponse({ ok: true }); diff --git a/buy.css b/buy.css new file mode 100644 index 0000000..7e7335b --- /dev/null +++ b/buy.css @@ -0,0 +1,136 @@ +/* 当前商品选择页 —— B站评论助手(B站蓝 #00A1D6) */ +* { margin: 0; padding: 0; box-sizing: border-box; } + +body { + font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Microsoft YaHei", sans-serif; + background: #f6f7f9; + color: #222; + min-height: 100vh; +} + +.page { max-width: 720px; margin: 0 auto; padding: 28px 18px 40px; } + +.head { text-align: center; margin-bottom: 26px; } + +.logo { + display: inline-block; + font-size: 12px; + color: #fff; + background: #00a1d6; + border-radius: 20px; + padding: 4px 14px; + margin-bottom: 12px; +} + +.head h1 { font-size: 26px; margin-bottom: 10px; } +.flow { font-size: 13px; color: #888; } + +section { + background: #fff; + border-radius: 12px; + padding: 20px; + margin-bottom: 16px; + box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05); +} + +h2 { + font-size: 17px; + margin-bottom: 16px; + display: flex; + align-items: center; + gap: 10px; +} + +.num { + display: inline-flex; + align-items: center; + justify-content: center; + width: 24px; + height: 24px; + border-radius: 50%; + background: #00a1d6; + color: #fff; + font-size: 13px; + flex: none; +} + +.package-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 14px; } + +.package { + border: 2px solid #eee; + border-radius: 10px; + padding: 16px 14px; + text-align: center; + cursor: pointer; + transition: all 0.18s ease; +} + +.package:hover { border-color: #a8ddf0; transform: translateY(-2px); } +.package.active { border-color: #00a1d6; background: #f2fbff; } + +.pkg-name { font-size: 15px; font-weight: 600; margin-bottom: 8px; } +.pkg-price { font-size: 24px; font-weight: 700; color: #00a1d6; margin-bottom: 6px; } +.pkg-dur { font-size: 12px; color: #999; margin-bottom: 12px; } + +.pkg-btn { + width: 100%; + padding: 8px 0; + border: none; + border-radius: 6px; + background: #00a1d6; + color: #fff; + font-size: 13px; + cursor: pointer; + transition: background 0.18s ease; +} + +.pkg-btn:hover { background: #0089ba; } +.package.active .pkg-btn { background: #0089ba; } + +.loading, .empty { grid-column: 1 / -1; text-align: center; color: #999; font-size: 13px; padding: 24px 0; } + +.chosen { font-size: 13px; color: #666; margin-bottom: 14px; } +.chosen b { color: #00a1d6; } + +.pay-methods { display: flex; gap: 14px; } + +.pay-btn { + flex: 1; + padding: 14px 0; + border: 2px solid #eee; + border-radius: 10px; + background: #fff; + font-size: 15px; + cursor: pointer; + transition: all 0.18s ease; +} + +.pay-btn.alipay { color: #1677ff; border-color: #bcd6ff; } +.pay-btn.wxpay { color: #09bb07; border-color: #b6e6b8; } +.pay-btn:hover { transform: translateY(-2px); box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08); } +.pay-btn.alipay:hover { border-color: #1677ff; } +.pay-btn.wxpay:hover { border-color: #09bb07; } + +.tip { margin-top: 12px; font-size: 12px; color: #999; } + +.order-status { + font-size: 14px; + line-height: 1.8; + padding: 14px; + border-radius: 8px; + background: #f6f7f9; + word-break: break-all; +} + +.order-status.pending { color: #b26a00; background: #fff8e6; } +.order-status.error { color: #c62828; background: #fdecea; } +.order-status.success { color: #1b5e20; background: #eef7ee; } + +.ok-title { font-size: 16px; font-weight: 700; margin-bottom: 8px; } +.ok-line { font-size: 13px; margin-bottom: 4px; } +.ok-line b { color: #1b5e20; } +.muted { color: #999; font-size: 12px; } + +.foot { text-align: center; font-size: 12px; color: #999; line-height: 1.9; } +.foot a { color: #00a1d6; text-decoration: none; } +.foot a:hover { text-decoration: underline; } diff --git a/buy.html b/buy.html new file mode 100644 index 0000000..1e3acb9 --- /dev/null +++ b/buy.html @@ -0,0 +1,48 @@ + + +
+ + +① 选择套餐 → ② 选择支付方式 → ③ 完成支付(支付成功自动激活本机)
+套餐由授权系统实时拉取,显示的就是当前在售的商品。
+点击后会打开支付页面,付款完成回到本页会自动显示激活结果。
+