Compare commits
16 Commits
af8ed90ab3
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| bae8275b11 | |||
| 0a0ffbdb23 | |||
| 557cd99b20 | |||
| 8b4312782d | |||
| f8af24506b | |||
| f1024941ed | |||
| 98c8a2ad86 | |||
| 8ac11bbd28 | |||
| 05f0373834 | |||
| e0bf83f062 | |||
| fdf6d3ac0a | |||
| 54672a5574 | |||
| 9ba45c37c2 | |||
| 24f091ac79 | |||
| a457dbabe9 | |||
| c546ad2459 |
65
.gitignore
vendored
65
.gitignore
vendored
@@ -1,5 +1,66 @@
|
||||
dist
|
||||
node_modules
|
||||
|
||||
# mac
|
||||
.DS_Store
|
||||
.env
|
||||
|
||||
.env*
|
||||
!.env*example
|
||||
|
||||
dist
|
||||
build
|
||||
logs
|
||||
|
||||
.turbo
|
||||
|
||||
pack-dist
|
||||
|
||||
# astro
|
||||
.astro
|
||||
|
||||
# next
|
||||
.next
|
||||
|
||||
# nuxt
|
||||
.nuxt
|
||||
|
||||
# vercel
|
||||
.vercel
|
||||
|
||||
# vuepress
|
||||
.vuepress/dist
|
||||
|
||||
# coverage
|
||||
coverage/
|
||||
|
||||
# typescript
|
||||
*.tsbuildinfo
|
||||
|
||||
# debug logs
|
||||
*.log
|
||||
*.tmp
|
||||
|
||||
# vscode
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
|
||||
# idea
|
||||
.idea
|
||||
|
||||
# system
|
||||
Thumbs.db
|
||||
ehthumbs.db
|
||||
Desktop.ini
|
||||
|
||||
# temp files
|
||||
*.tmp
|
||||
*.temp
|
||||
|
||||
# local development
|
||||
*.local
|
||||
|
||||
public/r
|
||||
|
||||
.pnpm-store
|
||||
24
.turbo/turbo-build.log
Normal file
24
.turbo/turbo-build.log
Normal file
@@ -0,0 +1,24 @@
|
||||
|
||||
[33m[43m[30m WARN [39m[49m Issue while reading "/home/ubuntu/kevisual/center/submodules/query-login/.npmrc". Failed to replace env in config: ${ME_NPM_TOKEN}
|
||||
[43m[30m WARN [39m[49m Issue while reading "/home/ubuntu/kevisual/center/.npmrc". Failed to replace env in config: ${ME_NPM_TOKEN}[39m
|
||||
|
||||
> @kevisual/query-login@0.0.2 build /home/ubuntu/kevisual/center/submodules/query-login
|
||||
> tsup
|
||||
|
||||
[34mCLI[39m Building entry: src/query-login-browser.ts, src/query-login-node.ts, src/query-login.ts
|
||||
[34mCLI[39m Using tsconfig: tsconfig.json
|
||||
[34mCLI[39m tsup v8.4.0
|
||||
[34mCLI[39m Using tsup config: /home/ubuntu/kevisual/center/submodules/query-login/tsup.config.ts
|
||||
[34mCLI[39m Target: esnext
|
||||
[34mCLI[39m Cleaning output folder
|
||||
[34mESM[39m Build start
|
||||
[33mESM[39m [33mYou have emitDecoratorMetadata enabled but @swc/core was not installed, skipping swc plugin[39m
|
||||
[32mESM[39m [1mdist/query-login-node.js [22m[32m15.31 KB[39m
|
||||
[32mESM[39m [1mdist/query-login-browser.js [22m[32m11.80 KB[39m
|
||||
[32mESM[39m [1mdist/query-login.js [22m[32m11.58 KB[39m
|
||||
[32mESM[39m ⚡️ Build success in 10ms
|
||||
DTS Build start
|
||||
DTS ⚡️ Build success in 873ms
|
||||
DTS dist/query-login-browser.d.ts 332.00 B
|
||||
DTS dist/query-login-node.d.ts 701.00 B
|
||||
DTS dist/query-login.d.ts 4.80 KB
|
||||
14
package.json
14
package.json
@@ -1,12 +1,14 @@
|
||||
{
|
||||
"name": "@kevisual/query-login",
|
||||
"version": "0.0.2",
|
||||
"version": "0.0.6",
|
||||
"description": "",
|
||||
"main": "dist/query-login.js",
|
||||
"types": "dist/query-login.d.ts",
|
||||
"scripts": {
|
||||
"build": "tsup",
|
||||
"watch": "tsup --watch"
|
||||
"watch": "tsup --watch",
|
||||
"dev": "tsup --watch",
|
||||
"dev:lib": "pnpm run dev"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "abearxiong <xiongxiao@xiongxiao.me>",
|
||||
@@ -16,10 +18,10 @@
|
||||
"access": "public"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@kevisual/query": "^0.0.12"
|
||||
"@kevisual/query": "^0.0.17"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^22.13.11",
|
||||
"@types/node": "^22.14.1",
|
||||
"tsup": "^8.4.0"
|
||||
},
|
||||
"exports": {
|
||||
@@ -29,7 +31,7 @@
|
||||
"./browser": "./dist/query-login-browser.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@kevisual/cache": "^0.0.1",
|
||||
"dotenv": "^16.4.7"
|
||||
"@kevisual/cache": "^0.0.2",
|
||||
"dotenv": "^16.5.0"
|
||||
}
|
||||
}
|
||||
@@ -11,10 +11,23 @@ export interface Cache {
|
||||
* @update 删除缓存
|
||||
*/
|
||||
del(): Promise<void>;
|
||||
/**
|
||||
* 初始化
|
||||
*/
|
||||
init?: () => Promise<any>;
|
||||
}
|
||||
type User = {
|
||||
avatar?: string;
|
||||
description?: string;
|
||||
id?: string;
|
||||
needChangePassword?: boolean;
|
||||
orgs?: string[];
|
||||
type?: string;
|
||||
username?: string;
|
||||
};
|
||||
|
||||
export type CacheLoginUser = {
|
||||
user?: any;
|
||||
user?: User;
|
||||
id?: string;
|
||||
accessToken?: string;
|
||||
refreshToken?: string;
|
||||
@@ -23,11 +36,15 @@ type CacheLogin = {
|
||||
loginUsers: CacheLoginUser[];
|
||||
} & CacheLoginUser;
|
||||
|
||||
export type CacheStore<T = any> = {
|
||||
export type CacheStore<T = Cache> = {
|
||||
name: string;
|
||||
/**
|
||||
* 缓存数据
|
||||
* @important 需要先调用init
|
||||
*/
|
||||
cacheData: CacheLogin;
|
||||
/**
|
||||
* 实际操作的cache
|
||||
* 实际操作的cache, 需要先调用init
|
||||
*/
|
||||
cache: T;
|
||||
|
||||
@@ -38,7 +55,7 @@ export type CacheStore<T = any> = {
|
||||
/**
|
||||
* 获取当前用户
|
||||
*/
|
||||
getCurrentUser(): Promise<CacheLoginUser>;
|
||||
getCurrentUser(): Promise<User>;
|
||||
/**
|
||||
* 获取当前用户列表
|
||||
*/
|
||||
@@ -51,10 +68,6 @@ export type CacheStore<T = any> = {
|
||||
* 获取缓存的accessToken
|
||||
*/
|
||||
getAccessToken(): Promise<string>;
|
||||
/**
|
||||
* 初始化
|
||||
*/
|
||||
init(): Promise<void>;
|
||||
/**
|
||||
* 清除当前用户
|
||||
*/
|
||||
@@ -63,9 +76,14 @@ export type CacheStore<T = any> = {
|
||||
* 清除所有用户
|
||||
*/
|
||||
clearAll(): Promise<void>;
|
||||
} & Cache;
|
||||
|
||||
type LoginCacheStoreOpts = {
|
||||
getValue(): Promise<CacheLogin>;
|
||||
setValue(value: CacheLogin): Promise<CacheLogin>;
|
||||
delValue(): Promise<void>;
|
||||
init(): Promise<any>;
|
||||
};
|
||||
|
||||
export type LoginCacheStoreOpts = {
|
||||
name: string;
|
||||
cache: Cache;
|
||||
};
|
||||
@@ -94,28 +112,41 @@ export class LoginCacheStore implements CacheStore<any> {
|
||||
* @param value
|
||||
* @returns
|
||||
*/
|
||||
async set(key: string, value: CacheLogin) {
|
||||
await this.cache.set(key, value);
|
||||
async setValue(value: CacheLogin) {
|
||||
await this.cache.set(this.name, value);
|
||||
this.cacheData = value;
|
||||
return value;
|
||||
}
|
||||
/**
|
||||
* 删除缓存
|
||||
*/
|
||||
async del() {
|
||||
async delValue() {
|
||||
await this.cache.del();
|
||||
}
|
||||
get(key: string): Promise<CacheLogin> {
|
||||
return this.cache.get(key);
|
||||
getValue(): Promise<CacheLogin> {
|
||||
return this.cache.get(this.name);
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化,设置默认值
|
||||
*/
|
||||
async init() {
|
||||
this.cacheData = (await this.get(this.name)) || {
|
||||
const defaultData = {
|
||||
loginUsers: [],
|
||||
user: null,
|
||||
id: null,
|
||||
accessToken: null,
|
||||
refreshToken: null,
|
||||
};
|
||||
if (this.cache.init) {
|
||||
try {
|
||||
const cacheData = await this.cache.init();
|
||||
this.cacheData = cacheData || defaultData;
|
||||
} catch (error) {
|
||||
console.log('cacheInit error', error);
|
||||
}
|
||||
} else {
|
||||
this.cacheData = (await this.getValue()) || defaultData;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 设置当前用户
|
||||
@@ -131,7 +162,7 @@ export class LoginCacheStore implements CacheStore<any> {
|
||||
this.cacheData.id = user.id;
|
||||
this.cacheData.accessToken = user.accessToken;
|
||||
this.cacheData.refreshToken = user.refreshToken;
|
||||
await this.set(this.name, this.cacheData);
|
||||
await this.setValue(this.cacheData);
|
||||
}
|
||||
|
||||
getCurrentUser(): Promise<CacheLoginUser> {
|
||||
@@ -160,7 +191,7 @@ export class LoginCacheStore implements CacheStore<any> {
|
||||
this.cacheData.id = undefined;
|
||||
this.cacheData.accessToken = undefined;
|
||||
this.cacheData.refreshToken = undefined;
|
||||
await this.set(this.name, this.cacheData);
|
||||
await this.setValue(this.cacheData);
|
||||
}
|
||||
async clearAll() {
|
||||
this.cacheData.loginUsers = [];
|
||||
@@ -168,6 +199,6 @@ export class LoginCacheStore implements CacheStore<any> {
|
||||
this.cacheData.id = undefined;
|
||||
this.cacheData.accessToken = undefined;
|
||||
this.cacheData.refreshToken = undefined;
|
||||
await this.set(this.name, this.cacheData);
|
||||
await this.setValue(this.cacheData);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,21 @@
|
||||
import { Cache } from './login-cache.ts';
|
||||
import { homedir } from 'node:os';
|
||||
import { join, dirname } from 'node:path';
|
||||
import { readFileSync } from 'node:fs';
|
||||
import { readFile, writeFile, unlink, stat, mkdir } from 'node:fs/promises';
|
||||
export const fileExists = async (filePath: string, createIfNotExists = false) => {
|
||||
import fs from 'node:fs';
|
||||
import { readFileSync, writeFileSync, accessSync } from 'node:fs';
|
||||
import { readFile, writeFile, unlink, mkdir } from 'node:fs/promises';
|
||||
export const fileExists = async (
|
||||
filePath: string,
|
||||
{ createIfNotExists = true, isFile = true, isDir = false }: { createIfNotExists?: boolean; isFile?: boolean; isDir?: boolean } = {},
|
||||
) => {
|
||||
try {
|
||||
await stat(filePath);
|
||||
accessSync(filePath, fs.constants.F_OK);
|
||||
return true;
|
||||
} catch (error) {
|
||||
if (createIfNotExists) {
|
||||
if (createIfNotExists && isDir) {
|
||||
await mkdir(filePath, { recursive: true });
|
||||
return true;
|
||||
} else if (createIfNotExists && isFile) {
|
||||
await mkdir(dirname(filePath), { recursive: true });
|
||||
return false;
|
||||
}
|
||||
@@ -24,6 +31,9 @@ export const readConfigFile = (filePath: string) => {
|
||||
return {};
|
||||
}
|
||||
};
|
||||
export const writeConfigFile = (filePath: string, data: any) => {
|
||||
writeFileSync(filePath, JSON.stringify(data, null, 2));
|
||||
};
|
||||
export const getHostName = () => {
|
||||
const configDir = join(homedir(), '.config', 'envision');
|
||||
const configFile = join(configDir, 'config.json');
|
||||
@@ -40,14 +50,13 @@ export class StorageNode implements Storage {
|
||||
const configDir = join(homedir(), '.config', 'envision');
|
||||
const hostname = getHostName();
|
||||
this.filePath = join(configDir, 'config', `${hostname}-storage.json`);
|
||||
fileExists(this.filePath, true);
|
||||
fileExists(this.filePath, { isFile: true });
|
||||
}
|
||||
async loadCache() {
|
||||
const filePath = this.filePath;
|
||||
try {
|
||||
const data = await readFile(filePath, 'utf-8');
|
||||
const jsonData = JSON.parse(data);
|
||||
this.cacheData = jsonData;
|
||||
const data = await readConfigFile(filePath);
|
||||
this.cacheData = data;
|
||||
} catch (error) {
|
||||
this.cacheData = {};
|
||||
await writeFile(filePath, JSON.stringify(this.cacheData, null, 2));
|
||||
@@ -76,37 +85,48 @@ export class StorageNode implements Storage {
|
||||
}
|
||||
}
|
||||
export class LoginNodeCache implements Cache {
|
||||
name: string;
|
||||
cacheData: any;
|
||||
filePath: string;
|
||||
constructor(name: string) {
|
||||
this.name = name;
|
||||
const hostname = getHostName();
|
||||
this.filePath = join(homedir(), '.config', 'envision', 'config', `${hostname}-${name}.json`);
|
||||
fileExists(this.filePath, true);
|
||||
this.loadCache(this.filePath);
|
||||
}
|
||||
filepath: string;
|
||||
|
||||
constructor(filepath?: string) {
|
||||
this.filepath = filepath || join(homedir(), '.config', 'envision', 'config', `${getHostName()}-login.json`);
|
||||
fileExists(this.filepath, { isFile: true });
|
||||
}
|
||||
async get(_key: string) {
|
||||
try {
|
||||
const filePath = this.filepath;
|
||||
const data = readConfigFile(filePath);
|
||||
return data;
|
||||
} catch (error) {
|
||||
console.log('get error', error);
|
||||
return {};
|
||||
}
|
||||
}
|
||||
async set(_key: string, value: any) {
|
||||
try {
|
||||
const data = readConfigFile(this.filepath);
|
||||
const newData = { ...data, ...value };
|
||||
writeConfigFile(this.filepath, newData);
|
||||
} catch (error) {
|
||||
console.log('set error', error);
|
||||
}
|
||||
}
|
||||
async del() {
|
||||
await unlink(this.filepath);
|
||||
}
|
||||
async loadCache(filePath: string) {
|
||||
try {
|
||||
const data = await readFile(filePath, 'utf-8');
|
||||
const jsonData = JSON.parse(data);
|
||||
this.cacheData = jsonData;
|
||||
return jsonData;
|
||||
} catch (error) {
|
||||
// console.log('loadCache error', error);
|
||||
console.log('create new cache file:', filePath);
|
||||
const defaultData = { loginUsers: [] };
|
||||
this.cacheData = defaultData;
|
||||
await writeFile(filePath, JSON.stringify(defaultData, null, 2));
|
||||
writeConfigFile(filePath, defaultData);
|
||||
return defaultData;
|
||||
}
|
||||
}
|
||||
|
||||
async get() {
|
||||
return this.cacheData;
|
||||
}
|
||||
async set(key: string, value: any) {
|
||||
this.cacheData = value;
|
||||
await writeFile(this.filePath, JSON.stringify(this.cacheData, null, 2));
|
||||
}
|
||||
async del() {
|
||||
await unlink(this.filePath);
|
||||
async init() {
|
||||
return await this.loadCache(this.filepath);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ export class QueryLoginNode extends QueryLogin {
|
||||
super({
|
||||
...opts,
|
||||
storage,
|
||||
cache: new LoginNodeCache('login'),
|
||||
cache: new LoginNodeCache(),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Query } from '@kevisual/query';
|
||||
import { Query, BaseQuery } from '@kevisual/query';
|
||||
import type { Result, DataOpts } from '@kevisual/query/query';
|
||||
import { setBaseResponse } from '@kevisual/query/query';
|
||||
import { LoginCacheStore, CacheStore } from './login-cache.ts';
|
||||
@@ -21,20 +21,21 @@ export type QueryLoginResult = {
|
||||
refreshToken: string;
|
||||
};
|
||||
|
||||
export class QueryLogin {
|
||||
query: Query;
|
||||
export class QueryLogin extends BaseQuery {
|
||||
/**
|
||||
* query login cache, 非实际操作, 一个cache的包裹模块
|
||||
*/
|
||||
cache: CacheStore;
|
||||
cacheStore: CacheStore;
|
||||
isBrowser: boolean;
|
||||
load?: boolean;
|
||||
storage: Storage;
|
||||
onLoad?: () => void;
|
||||
|
||||
constructor(opts?: QueryLoginOpts) {
|
||||
this.query = opts?.query || new Query();
|
||||
this.cache = new LoginCacheStore({ name: 'login', cache: opts.cache });
|
||||
super({
|
||||
query: opts?.query || new Query(),
|
||||
});
|
||||
this.cacheStore = new LoginCacheStore({ name: 'login', cache: opts.cache });
|
||||
this.isBrowser = opts?.isBrowser ?? true;
|
||||
this.init();
|
||||
this.onLoad = opts?.onLoad;
|
||||
@@ -44,12 +45,19 @@ export class QueryLogin {
|
||||
this.query = query;
|
||||
}
|
||||
private async init() {
|
||||
await this.cache.init();
|
||||
await this.cacheStore.init();
|
||||
this.load = true;
|
||||
this.onLoad?.();
|
||||
}
|
||||
async post<T = any>(data: any, opts?: DataOpts) {
|
||||
return this.query.post<T>({ path: 'user', ...data }, opts);
|
||||
try {
|
||||
return this.query.post<T>({ path: 'user', ...data }, opts);
|
||||
} catch (error) {
|
||||
console.log('error', error);
|
||||
return {
|
||||
code: 400,
|
||||
} as any;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 登录,
|
||||
@@ -79,6 +87,41 @@ export class QueryLogin {
|
||||
}
|
||||
return res;
|
||||
}
|
||||
/**
|
||||
* 设置token
|
||||
* @param token
|
||||
*/
|
||||
async setLoginToken(token: { accessToken: string; refreshToken: string }) {
|
||||
const { accessToken, refreshToken } = token;
|
||||
this.storage.setItem('token', accessToken || '');
|
||||
await this.beforeSetLoginUser({ accessToken, refreshToken });
|
||||
}
|
||||
async loginByWechat(data: { code: string }) {
|
||||
const res = await this.post<QueryLoginResult>({ path: 'wx', key: 'open-login', code: data.code });
|
||||
if (res.code === 200) {
|
||||
const { accessToken, refreshToken } = res?.data || {};
|
||||
this.storage.setItem('token', accessToken || '');
|
||||
await this.beforeSetLoginUser({ accessToken, refreshToken });
|
||||
}
|
||||
return res;
|
||||
}
|
||||
/**
|
||||
* 检测微信登录,登陆成功后,调用onSuccess,否则调用onError
|
||||
* @param param0
|
||||
*/
|
||||
async checkWechat({ onSuccess, onError }: { onSuccess?: (res: QueryLoginResult) => void; onError?: (res: any) => void }) {
|
||||
const url = new URL(window.location.href);
|
||||
const code = url.searchParams.get('code');
|
||||
const state = url.searchParams.get('state');
|
||||
if (code && state) {
|
||||
const res = await this.loginByWechat({ code });
|
||||
if (res.code === 200) {
|
||||
onSuccess?.(res.data);
|
||||
} else {
|
||||
onError?.(res);
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 登陆成功,需要获取用户信息进行缓存
|
||||
* @param param0
|
||||
@@ -89,7 +132,7 @@ export class QueryLogin {
|
||||
if (resUser.code === 200) {
|
||||
const user = resUser.data;
|
||||
if (user) {
|
||||
this.cache.setLoginUser({
|
||||
this.cacheStore.setLoginUser({
|
||||
user,
|
||||
id: user.id,
|
||||
accessToken,
|
||||
@@ -107,10 +150,10 @@ export class QueryLogin {
|
||||
* @returns
|
||||
*/
|
||||
async queryRefreshToken(refreshToken?: string) {
|
||||
const _refreshToken = refreshToken || this.cache.getRefreshToken();
|
||||
const _refreshToken = refreshToken || this.cacheStore.getRefreshToken();
|
||||
let data = { refreshToken: _refreshToken };
|
||||
if (!_refreshToken) {
|
||||
await this.cache.clearCurrentUser();
|
||||
await this.cacheStore.clearCurrentUser();
|
||||
return {
|
||||
code: 401,
|
||||
message: '请先登录',
|
||||
@@ -129,6 +172,7 @@ export class QueryLogin {
|
||||
}
|
||||
/**
|
||||
* 检查401错误,并刷新token, 如果refreshToken存在,则刷新token, 否则返回401
|
||||
* 拦截请求,请使用run401Action, 不要直接使用 afterCheck401ToRefreshToken
|
||||
* @param response
|
||||
* @param ctx
|
||||
* @param refetch
|
||||
@@ -137,7 +181,7 @@ export class QueryLogin {
|
||||
async afterCheck401ToRefreshToken(response: Result, ctx?: { req?: any; res?: any; fetch?: any }, refetch?: boolean) {
|
||||
const that = this;
|
||||
if (response?.code === 401) {
|
||||
const hasRefreshToken = await that.cache.getRefreshToken();
|
||||
const hasRefreshToken = await that.cacheStore.getRefreshToken();
|
||||
if (hasRefreshToken) {
|
||||
const res = await that.queryRefreshToken(hasRefreshToken);
|
||||
if (res.code === 200) {
|
||||
@@ -159,13 +203,58 @@ export class QueryLogin {
|
||||
}
|
||||
} else {
|
||||
that.storage.removeItem('token');
|
||||
await that.cache.clearCurrentUser();
|
||||
await that.cacheStore.clearCurrentUser();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
return response as any;
|
||||
}
|
||||
/**
|
||||
* 一个简单的401处理, 如果401,则刷新token, 如果refreshToken不存在,则返回401
|
||||
* refetch 是否重新请求, 会有bug,无限循环,按需要使用
|
||||
* TODO:
|
||||
* @param response
|
||||
* @param ctx
|
||||
* @param opts
|
||||
* @returns
|
||||
*/
|
||||
async run401Action(
|
||||
response: Result,
|
||||
ctx?: { req?: any; res?: any; fetch?: any },
|
||||
opts?: {
|
||||
/**
|
||||
* 是否重新请求, 会有bug,无限循环,按需要使用
|
||||
*/
|
||||
refetch?: boolean;
|
||||
/**
|
||||
* check之后的回调
|
||||
*/
|
||||
afterCheck?: (res: Result) => any;
|
||||
/**
|
||||
* 401处理后, 还是401, 则回调
|
||||
*/
|
||||
afterAlso401?: (res: Result) => any;
|
||||
},
|
||||
) {
|
||||
const that = this;
|
||||
const refetch = opts?.refetch ?? false;
|
||||
if (response?.code === 401) {
|
||||
if (that.query.stop === true) {
|
||||
return { code: 500, success: false, message: 'refresh token loading...' };
|
||||
}
|
||||
that.query.stop = true;
|
||||
const res = await that.afterCheck401ToRefreshToken(response, ctx, refetch);
|
||||
that.query.stop = false;
|
||||
opts?.afterCheck?.(res);
|
||||
if (res.code === 401) {
|
||||
opts?.afterAlso401?.(res);
|
||||
}
|
||||
return res;
|
||||
} else {
|
||||
return response as any;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 获取用户信息
|
||||
* @param token
|
||||
@@ -181,10 +270,13 @@ export class QueryLogin {
|
||||
if (config.headers) {
|
||||
config.headers['Authorization'] = `Bearer ${_token}`;
|
||||
}
|
||||
if (!_token) {
|
||||
// TODO: 取消请求,因为没有登陆
|
||||
}
|
||||
return config;
|
||||
},
|
||||
afterResponse: async (response, ctx) => {
|
||||
if (response?.code === 401 && check401) {
|
||||
if (response?.code === 401 && check401 && !token) {
|
||||
return await that.afterCheck401ToRefreshToken(response, ctx);
|
||||
}
|
||||
return response as any;
|
||||
@@ -192,6 +284,25 @@ export class QueryLogin {
|
||||
},
|
||||
);
|
||||
}
|
||||
/**
|
||||
* 检查本地用户,如果本地用户存在,则返回本地用户,否则返回null
|
||||
* @returns
|
||||
*/
|
||||
async checkLocalUser() {
|
||||
const user = await this.cacheStore.getCurrentUser();
|
||||
if (user) {
|
||||
return user;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* 检查本地token是否存在,简单的判断是否已经属于登陆状态
|
||||
* @returns
|
||||
*/
|
||||
async checkLocalToken() {
|
||||
const token = this.storage.getItem('token');
|
||||
return !!token;
|
||||
}
|
||||
/**
|
||||
* 请求更新,切换用户, 使用switchUser
|
||||
* @param username
|
||||
@@ -206,7 +317,7 @@ export class QueryLogin {
|
||||
* @returns
|
||||
*/
|
||||
async switchUser(username: string) {
|
||||
const localUserList = await this.cache.getCurrentUserList();
|
||||
const localUserList = await this.cacheStore.getCurrentUserList();
|
||||
const user = localUserList.find((userItem) => userItem.user.username === username);
|
||||
if (user) {
|
||||
this.storage.setItem('token', user.accessToken || '');
|
||||
@@ -230,11 +341,20 @@ export class QueryLogin {
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 退出登陆,去掉token, 并删除缓存
|
||||
* @returns
|
||||
*/
|
||||
async logout() {
|
||||
this.storage.removeItem('token');
|
||||
this.cache.del();
|
||||
return this.post<Result>({ key: 'logout' });
|
||||
const users = await this.cacheStore.getCurrentUserList();
|
||||
const tokens = users
|
||||
.map((user) => {
|
||||
return user?.accessToken;
|
||||
})
|
||||
.filter(Boolean);
|
||||
this.cacheStore.delValue();
|
||||
return this.post<Result>({ key: 'logout', data: { tokens } });
|
||||
}
|
||||
/**
|
||||
* 检查用户名的组,这个用户是否存在
|
||||
|
||||
Reference in New Issue
Block a user