Files
NapCatQQ/packages/napcat-webui-backend/src/helper/Data.ts
时瑾 0ca68010a5 feat: 优化离线重连机制,支持通过前端实现重新登录
* feat: 优化离线重连机制,增加前端登录错误提示与二维码刷新功能

- 增加全局掉线检测弹窗
- 增强登录错误解析,支持显示 serverErrorCode 和 message
- 优化二维码登录 UI,错误时显示详细原因并提供大按钮重新获取
- 核心层解耦,通过事件抛出 KickedOffLine 通知
- 支持前端点击刷新二维码接口

* feat: 新增看门狗汪汪汪

* cp napcat-shell-loader/launcher-win.bat

* refactor: 重构重启流程,移除旧的重启逻辑,新增基于 WebUI 的重启请求处理

* fix: 刷新二维码清楚错误信息
2026-01-17 15:38:24 +08:00

203 lines
5.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import store from 'napcat-common/src/store';
import { napCatVersion } from 'napcat-common/src/version';
import { NapCatCoreWorkingEnv, type LoginRuntimeType } from '../types';
const LoginRuntime: LoginRuntimeType = {
workingEnv: NapCatCoreWorkingEnv.Unknown,
LoginCurrentTime: Date.now(),
LoginCurrentRate: 0,
QQLoginStatus: false, // 已实现 但太傻了 得去那边注册个回调刷新
QQQRCodeURL: '',
QQLoginUin: '',
QQLoginInfo: {
uid: '',
uin: '',
nick: '',
},
QQLoginError: '',
QQVersion: 'unknown',
OneBotContext: null,
onQQLoginStatusChange: async (status: boolean) => {
LoginRuntime.QQLoginStatus = status;
},
onWebUiTokenChange: async (_token: string) => {
},
onRefreshQRCode: async () => {
// 默认空实现,由 shell 注册真实回调
},
NapCatHelper: {
onOB11ConfigChanged: async () => {
},
onQuickLoginRequested: async () => {
return { result: false, message: '' };
},
onRestartProcessRequested: async () => {
return { result: false, message: '重启功能未初始化' };
},
QQLoginList: [],
NewQQLoginList: [],
},
NapCatVersion: napCatVersion,
WebUiConfigQuickFunction: async () => {
},
};
export const WebUiDataRuntime = {
setWorkingEnv (env: NapCatCoreWorkingEnv): void {
LoginRuntime.workingEnv = env;
},
getWorkingEnv (): NapCatCoreWorkingEnv {
return LoginRuntime.workingEnv;
},
setWebUiTokenChangeCallback (func: (token: string) => Promise<void>): void {
LoginRuntime.onWebUiTokenChange = func;
},
getWebUiTokenChangeCallback (): (token: string) => Promise<void> {
return LoginRuntime.onWebUiTokenChange;
},
checkLoginRate (ip: string, RateLimit: number): boolean {
const key = `login_rate:${ip}`;
const count = store.get<number>(key) || 0;
if (count === 0) {
// 第一次访问设置计数器为1并设置60秒过期
store.set(key, 1, 60);
return true;
}
if (count >= RateLimit) {
return false;
}
store.set(key, count + 1);
return true;
},
getQQLoginStatus (): LoginRuntimeType['QQLoginStatus'] {
return LoginRuntime.QQLoginStatus;
},
setQQLoginCallback (func: (status: boolean) => Promise<void>): void {
LoginRuntime.onQQLoginStatusChange = func;
},
getQQLoginCallback (): (status: boolean) => Promise<void> {
return LoginRuntime.onQQLoginStatusChange;
},
setQQLoginStatus (status: LoginRuntimeType['QQLoginStatus']): void {
LoginRuntime.QQLoginStatus = status;
},
setQQLoginQrcodeURL (url: LoginRuntimeType['QQQRCodeURL']): void {
LoginRuntime.QQQRCodeURL = url;
},
getQQLoginQrcodeURL (): LoginRuntimeType['QQQRCodeURL'] {
return LoginRuntime.QQQRCodeURL;
},
setQQLoginInfo (info: LoginRuntimeType['QQLoginInfo']): void {
LoginRuntime.QQLoginInfo = info;
LoginRuntime.QQLoginUin = info.uin.toString();
},
getQQLoginInfo (): LoginRuntimeType['QQLoginInfo'] {
return LoginRuntime.QQLoginInfo;
},
getQQLoginUin (): LoginRuntimeType['QQLoginUin'] {
return LoginRuntime.QQLoginUin;
},
getQQQuickLoginList (): LoginRuntimeType['NapCatHelper']['QQLoginList'] {
return LoginRuntime.NapCatHelper.QQLoginList;
},
setQQQuickLoginList (list: LoginRuntimeType['NapCatHelper']['QQLoginList']): void {
LoginRuntime.NapCatHelper.QQLoginList = list;
},
getQQNewLoginList (): LoginRuntimeType['NapCatHelper']['NewQQLoginList'] {
return LoginRuntime.NapCatHelper.NewQQLoginList;
},
setQQNewLoginList (list: LoginRuntimeType['NapCatHelper']['NewQQLoginList']): void {
LoginRuntime.NapCatHelper.NewQQLoginList = list;
},
setQuickLoginCall (func: LoginRuntimeType['NapCatHelper']['onQuickLoginRequested']): void {
LoginRuntime.NapCatHelper.onQuickLoginRequested = func;
},
requestQuickLogin: function (uin) {
return LoginRuntime.NapCatHelper.onQuickLoginRequested(uin);
} as LoginRuntimeType['NapCatHelper']['onQuickLoginRequested'],
setOnOB11ConfigChanged (func: LoginRuntimeType['NapCatHelper']['onOB11ConfigChanged']): void {
LoginRuntime.NapCatHelper.onOB11ConfigChanged = func;
},
setOB11Config: function (ob11) {
return LoginRuntime.NapCatHelper.onOB11ConfigChanged(ob11);
} as LoginRuntimeType['NapCatHelper']['onOB11ConfigChanged'],
GetNapCatVersion () {
return LoginRuntime.NapCatVersion;
},
setQQVersion (version: string) {
LoginRuntime.QQVersion = version;
},
getQQVersion () {
return LoginRuntime.QQVersion;
},
setWebUiConfigQuickFunction (func: LoginRuntimeType['WebUiConfigQuickFunction']): void {
LoginRuntime.WebUiConfigQuickFunction = func;
},
runWebUiConfigQuickFunction: async function () {
await LoginRuntime.WebUiConfigQuickFunction();
},
setOneBotContext (context: any): void {
LoginRuntime.OneBotContext = context;
},
getOneBotContext (): any | null {
return LoginRuntime.OneBotContext;
},
setRestartProcessCall (func: () => Promise<{ result: boolean; message: string; }>): void {
LoginRuntime.NapCatHelper.onRestartProcessRequested = func;
},
requestRestartProcess: async function () {
return await LoginRuntime.NapCatHelper.onRestartProcessRequested();
},
setQQLoginError (error: string): void {
LoginRuntime.QQLoginError = error;
},
getQQLoginError (): string {
return LoginRuntime.QQLoginError;
},
setRefreshQRCodeCallback (func: () => Promise<void>): void {
LoginRuntime.onRefreshQRCode = func;
},
getRefreshQRCodeCallback (): () => Promise<void> {
return LoginRuntime.onRefreshQRCode;
},
refreshQRCode: async function () {
LoginRuntime.QQLoginError = '';
await LoginRuntime.onRefreshQRCode();
},
};