import { log, pops, QRCodeJS, utils } from "@/env"; import { GM_getValue, GM_setValue } from "ViteGM"; import Qmsg from "qmsg"; import { BilibiliLoginApi } from "../api/BilibiliLoginApi"; export const BilibiliQrCodeLogin = { async init() { Qmsg.info("正在申请二维码..."); const qrcodeInfo = await this.getQRCodeInfo(); if (!qrcodeInfo) { return; } this.confirmScanQrcode(qrcodeInfo); }, /**' * 获取二维码信息 */ getQRCodeInfo: async function () { log.info("正在申请二维码..."); const qrcodeInfo = await BilibiliLoginApi.getQrCodeInfo(); log.info("获取到二维码信息", qrcodeInfo); return qrcodeInfo; }, /** * 确认扫码 * @param qrcodeInfo */ async confirmScanQrcode(qrcodeInfo: { url: string; auth_code: string }) { const $alert = pops.alert({ title: { text: "请扫描二维码登录", position: "center", html: false, style: "", }, content: { text: /*html*/ `
`, html: true, }, btn: { ok: { enable: false, }, close: { enable: true, callback(event) { isUserCloseScanDialog = true; event.close(); }, }, }, mask: { enable: true, clickEvent: { toClose: false, toHide: false, }, }, only: true, width: "310px", height: "365px", drag: true, dragLimit: true, style: /*css*/ ` #bili-qrcode-canvas{ display: flex; align-items: center; justify-content: center; width: 100%; height: 100%; } `, }); const $biliQrcodeCanvas = $alert.$shadowRoot.querySelector("#bili-qrcode-canvas")!; const qrcode = new QRCodeJS($biliQrcodeCanvas, { text: qrcodeInfo.url, width: 300, height: 300, colorDark: "#000000", colorLight: "#ffffff", correctLevel: QRCodeJS.CorrectLevel.H, }); /** 是否成功登录 */ let isSuccessLogin = false; /** 用户是否取消登录弹窗 */ let isUserCloseScanDialog = false; while (true) { if (isUserCloseScanDialog) { log.error("用户关闭扫码登录弹窗、取消扫码登录"); break; } log.info("正在等待扫码登录..."); const pollInfo = await BilibiliLoginApi.poll(qrcodeInfo.auth_code); if (pollInfo?.success) { this.setAccessTokenInfo({ access_token: pollInfo.accessKey, expireAt: pollInfo.accessKeyExpireAt as any, }); isSuccessLogin = true; log.info("扫码登录成功", pollInfo); Qmsg.success("扫码登录成功"); break; } else { if (pollInfo?.action === "refresh") { // 刷新二维码 log.info("刷新二维码"); Qmsg.info("刷新二维码"); const qrcodeInfo = await this.getQRCodeInfo(); if (qrcodeInfo) { qrcode.clear(); qrcode.makeCode(qrcodeInfo.url); } } else if (pollInfo.action === "wait") { if (pollInfo.message === "二维码已扫码未确认") { // 等待确认 log.info("已扫码,等待确认..."); pops.loading({ $parent: $biliQrcodeCanvas, content: { text: "已扫码,等待确认", }, mask: { enable: true, }, }); } else { // 尚未扫码 } } else { // 失败返回 isSuccessLogin = false; log.error(pollInfo.message); Qmsg.error(pollInfo.message); break; } } await utils.sleep(1500); } $alert.close(); return { isSuccessLogin, isUserCloseScanDialog, }; }, /** * 生成过期时间 * @param monthNumber xx月后过期 * @returns */ generateExpireAt(monthNumber: number = 6) { // 6个月过期 return new Date().getTime() + 1000 * 60 * 60 * 24 * 30 * monthNumber; }, /** * 设置获取到的access_token和过期时间 * @param data */ setAccessTokenInfo(data: { access_token: string; expireAt: number }) { GM_setValue("bili-accessTokenInfo", data); }, /** * 获取access_token和过期时间 * 自动根据过期时间处理数据 * @returns */ getAccessTokenInfo() { const data = GM_getValue("bili-accessTokenInfo") as null | { access_token: string; expireAt: number; }; if (data && data.expireAt > Date.now()) { return data; } else { return null; } }, /** * 获取access_token * @returns */ getAccessToken() { return this.getAccessTokenInfo()?.access_token || ""; }, };