diff --git a/src/App.vue b/src/App.vue index f9c0111..56594f9 100644 --- a/src/App.vue +++ b/src/App.vue @@ -93,7 +93,7 @@ - + diff --git a/src/api/account.ts b/src/api/account.ts index 9da94d0..69f61e3 100644 --- a/src/api/account.ts +++ b/src/api/account.ts @@ -1,80 +1,84 @@ -import { QueryGetAPI, QueryPostAPI, QueryPostAPIWithParams } from '@/api/query' -import { ACCOUNT_API_URL, VTSURU_API_URL } from '@/data/constants' -import { useLocalStorage } from '@vueuse/core' -import { isSameDay } from 'date-fns' -import { createDiscreteApi } from 'naive-ui' -import { ref } from 'vue' -import { APIRoot, AccountInfo, FunctionTypes } from './api-models' +import { QueryGetAPI, QueryPostAPI, QueryPostAPIWithParams } from '@/api/query'; +import { ACCOUNT_API_URL, VTSURU_API_URL } from '@/data/constants'; +import { isSameDay } from 'date-fns'; +import { createDiscreteApi } from 'naive-ui'; +import { ref } from 'vue'; +import { APIRoot, AccountInfo, FunctionTypes } from './api-models'; +import { StorageSerializers } from '@vueuse/core'; -export const ACCOUNT = ref({} as AccountInfo) -export const isLoadingAccount = ref(true) +export const ACCOUNT = ref({} as AccountInfo); +export const isLoadingAccount = ref(true); export const isLoggedIn = computed(() => { - return ACCOUNT.value.id > 0 -}) + return ACCOUNT.value.id > 0; +}); -const { message } = createDiscreteApi(['message']) -const cookie = useLocalStorage('JWT_Token', '') -const cookieRefreshDate = useLocalStorage('JWT_Token_Last_Refresh', 0) +const { message } = createDiscreteApi(['message']); +export const cookie = useLocalStorage('Cookie', {cookie: '', refreshDate: 0}, { serializer: StorageSerializers.object }); export async function GetSelfAccount(token?: string) { - if (cookie.value || token) { - const result = await Self(token) + if (cookie.value.cookie || token) { + const result = await Self(token); if (result.code == 200) { if (!ACCOUNT.value.id) { - ACCOUNT.value = result.data + ACCOUNT.value = result.data; } else { - result.data.settings = ACCOUNT.value.settings - ACCOUNT.value = result.data + result.data.settings = ACCOUNT.value.settings; + ACCOUNT.value = result.data; } - isLoadingAccount.value = false + isLoadingAccount.value = false; //console.log('[vtsuru] 已获取账户信息') - if (!isSameDay(new Date(), cookieRefreshDate.value)) { - refreshCookie(token) + if (!cookie.value.cookie || !isSameDay(new Date(), cookie.value!.refreshDate)) { + refreshCookie(token); } - return result.data + return result.data; } else if (result.code == 401) { - localStorage.removeItem('JWT_Token') - console.warn('[vtsuru] Cookie 已失效, 需要重新登陆') - message.error('Cookie 已失效, 需要重新登陆') - setTimeout(() => { - location.reload() - }, 1500) + localStorage.removeItem('JWT_Token'); + if (!token) { + cookie.value = undefined; + console.warn('[vtsuru] Cookie 已失效, 需要重新登陆'); + message.error('Cookie 已失效, 需要重新登陆'); + setTimeout(() => { + location.reload(); + }, 1500); + } } else { - console.warn('[vtsuru] ' + result.message) - message.error(result.message) + console.warn('[vtsuru] ' + result.message); + message.error(result.message); } } - isLoadingAccount.value = false + isLoadingAccount.value = false; } export function UpdateAccountLoop() { setInterval(() => { if (ACCOUNT.value && window.$route?.name != 'question-display') { // 防止在问题详情页刷新 - GetSelfAccount() + GetSelfAccount(); } - }, 60 * 1000) + }, 60 * 1000); } function refreshCookie(token?: string) { QueryPostAPIWithParams(`${ACCOUNT_API_URL}refresh-token`, { token }).then((data) => { if (data.code == 200) { - cookie.value = data.data - cookieRefreshDate.value = Date.now() - console.log('[vtsuru] 已刷新Cookie') + cookie.value = { + cookie: data.data, + refreshDate: new Date().getTime() + }; + console.log('[vtsuru] 已刷新Cookie'); } - }) + }); } export async function SaveAccountSettings() { return await QueryPostAPI( ACCOUNT_API_URL + 'update-setting', ACCOUNT.value?.settings - ) + ); } export async function SaveEnableFunctions(functions: FunctionTypes[]) { return await QueryPostAPI( ACCOUNT_API_URL + 'update-enable-functions', functions - ) + ); } export async function SaveSetting( name: @@ -94,44 +98,44 @@ export async function SaveSetting( name }, setting - ) - return result.message + ); + return result.message; } export async function UpdateFunctionEnable(func: FunctionTypes) { if (ACCOUNT.value) { const oldValue = JSON.parse( JSON.stringify(ACCOUNT.value.settings.enableFunctions) - ) + ); if (ACCOUNT.value?.settings.enableFunctions.includes(func)) { ACCOUNT.value.settings.enableFunctions = - ACCOUNT.value.settings.enableFunctions.filter((f) => f != func) + ACCOUNT.value.settings.enableFunctions.filter((f) => f != func); } else { - ACCOUNT.value.settings.enableFunctions.push(func) + ACCOUNT.value.settings.enableFunctions.push(func); } await SaveEnableFunctions(ACCOUNT.value?.settings.enableFunctions) .then((data) => { if (data.code == 200) { message.success( `已${ACCOUNT.value?.settings.enableFunctions.includes(func) ? '启用' : '禁用'}` - ) + ); } else { if (ACCOUNT.value) { - ACCOUNT.value.settings.enableFunctions = oldValue + ACCOUNT.value.settings.enableFunctions = oldValue; } message.error( `${ACCOUNT.value?.settings.enableFunctions.includes(func) ? '启用' : '禁用'}失败: ${data.message}` - ) + ); } }) .catch((err) => { message.error( `${ACCOUNT.value?.settings.enableFunctions.includes(func) ? '启用' : '禁用'}失败: ${err}` - ) - }) + ); + }); } } export function useAccount() { - return ACCOUNT + return ACCOUNT; } export async function Register( @@ -145,7 +149,7 @@ export async function Register( email, password, token - }) + }); } export async function Login( @@ -155,10 +159,10 @@ export async function Login( return QueryPostAPI(`${ACCOUNT_API_URL}login`, { nameOrEmail, password - }) + }); } export async function Self(token?: string): Promise> { - return QueryPostAPIWithParams(`${ACCOUNT_API_URL}self`, token ? { token } : undefined) + return QueryPostAPIWithParams(`${ACCOUNT_API_URL}self`, token ? { token } : undefined); } export async function AddBiliBlackList( id: number, @@ -167,70 +171,70 @@ export async function AddBiliBlackList( return QueryGetAPI(`${ACCOUNT_API_URL}black-list/add-bili`, { id: id, name: name - }) + }); } export async function DelBiliBlackList(id: number): Promise> { return QueryGetAPI(`${ACCOUNT_API_URL}black-list/del-bili`, { id: id - }) + }); } export async function DelBlackList(id: number): Promise> { return QueryGetAPI(`${ACCOUNT_API_URL}black-list/del`, { id: id - }) + }); } export function downloadConfigDirect(name: string) { return QueryGetAPI(VTSURU_API_URL + 'get-config', { name: name - }) + }); } -export type ConfigStatus = 'success' | 'error' | 'notfound' +export type ConfigStatus = 'success' | 'error' | 'notfound'; export async function DownloadConfig(name: string, id?: number): Promise< | { - msg: undefined - status: ConfigStatus - data: T - } + msg: undefined; + status: ConfigStatus; + data: T; + } | { - msg: string - status: ConfigStatus - data: undefined - } + msg: string; + status: ConfigStatus; + data: undefined; + } > { try { const resp = await QueryGetAPI(VTSURU_API_URL + (id ? 'get-user-config' : 'get-config'), { name: name, id: id - }) + }); if (resp.code == 200) { - console.log('已获取配置文件: ' + name) + console.log('已获取配置文件: ' + name); return { msg: undefined, status: 'success', data: JSON.parse(resp.data) as T - } + }; } else if (resp.code == 404) { - console.error(`未找到名为 ${name} 的配置文件`) + console.error(`未找到名为 ${name} 的配置文件`); return { msg: `未找到名为 ${name} 的配置文件, 需要先上传`, status: 'notfound', data: undefined - } + }; } else { - console.error(`无法获取配置文件 [${name}]: ` + resp.message) + console.error(`无法获取配置文件 [${name}]: ` + resp.message); return { msg: `无法获取配置文件 [${name}]: ` + resp.message, status: 'error', data: undefined - } + }; } } catch (err) { - console.error(`无法获取配置文件 [${name}]: ` + err) + console.error(`无法获取配置文件 [${name}]: ` + err); return { msg: `无法获取配置文件 [${name}]: ` + err, status: 'error', data: undefined - } + }; } } export async function UploadConfig(name: string, data: unknown) { @@ -238,70 +242,70 @@ export async function UploadConfig(name: string, data: unknown) { const resp = await QueryPostAPI(VTSURU_API_URL + 'set-config', { name: name, json: JSON.stringify(data) - }) + }); if (resp.code == 200) { - console.log('已保存配置文件至服务器:' + name) - return true + console.log('已保存配置文件至服务器:' + name); + return true; } else { - console.error('保存失败: ' + resp.message) + console.error('保存失败: ' + resp.message); } } catch (err) { - console.error(`保存配置文件失败: ` + err) + console.error(`保存配置文件失败: ` + err); } - return false + return false; } export async function EnableFunction(func: FunctionTypes) { if (ACCOUNT.value) { if (ACCOUNT.value.settings.enableFunctions.includes(func)) { - return true + return true; } else { - ACCOUNT.value.settings.enableFunctions.push(func) + ACCOUNT.value.settings.enableFunctions.push(func); if (await updateFunctionEnable()) { - return true + return true; } else { ACCOUNT.value.settings.enableFunctions.splice( ACCOUNT.value.settings.enableFunctions.indexOf(func), 1 - ) - return false + ); + return false; } } } - return false + return false; } export async function DisableFunction(func: FunctionTypes) { if (ACCOUNT.value) { if (!ACCOUNT.value.settings.enableFunctions.includes(func)) { - return true + return true; } else { ACCOUNT.value.settings.enableFunctions.splice( ACCOUNT.value.settings.enableFunctions.indexOf(func), 1 - ) + ); if (await updateFunctionEnable()) { - return true + return true; } else { - ACCOUNT.value.settings.enableFunctions.push(func) - return false + ACCOUNT.value.settings.enableFunctions.push(func); + return false; } } } - return false + return false; } async function updateFunctionEnable() { if (ACCOUNT.value) { try { const data = await SaveEnableFunctions( ACCOUNT.value.settings.enableFunctions - ) + ); if (data.code == 200) { - return true + return true; } else { - return false + return false; } } catch (err) { - console.log(err) - return false + console.log(err); + return false; } } } diff --git a/src/api/query.ts b/src/api/query.ts index 45c8031..618913b 100644 --- a/src/api/query.ts +++ b/src/api/query.ts @@ -2,8 +2,7 @@ import { apiFail } from '@/data/constants' import { useLocalStorage } from '@vueuse/core' import { APIRoot, PaginationResponse } from './api-models' - -const cookie = useLocalStorage('JWT_Token', '') +import { cookie } from './account'; export async function QueryPostAPI( urlString: string, @@ -58,7 +57,7 @@ async function QueryPostAPIWithParamsInternal( headers.forEach((header) => { h[header[0]] = header[1] }) - if (cookie.value) h['Authorization'] = `Bearer ${cookie.value}` + if (cookie.value.cookie) h['Authorization'] = `Bearer ${cookie.value.cookie}` h['Content-Type'] = contentType return await QueryAPIInternal(url, { @@ -112,8 +111,8 @@ async function QueryGetAPIInternal( headers.forEach((header) => { h[header[0]] = header[1] }) - if (cookie.value) { - h['Authorization'] = `Bearer ${cookie.value}` + if (cookie.value.cookie) { + h['Authorization'] = `Bearer ${cookie.value.cookie}` } return await QueryAPIInternal(url, { method: 'get', headers: h }) } catch (err) { @@ -163,5 +162,5 @@ export async function QueryGetPaginationAPI( return await QueryGetAPIInternal>(urlString, params) } export function GetHeaders(): [string, string][] { - return [['Authorization', `Bearer ${cookie.value}`]] + return [['Authorization', `Bearer ${cookie.value?.cookie}`]] } diff --git a/src/client/ClientFetcher.vue b/src/client/ClientFetcher.vue index 5465b82..338b49a 100644 --- a/src/client/ClientFetcher.vue +++ b/src/client/ClientFetcher.vue @@ -219,7 +219,7 @@ data: [{ value: eventsPerSecond.value, name: '事件/秒' }] }] }; - gaugeOption.value = option; // 保留原始option用于初始化 + gaugeOption.value ??= option; // 保留原始option用于初始化 if (gaugeChart.value) { gaugeChart.value.setOption(option, false); } @@ -239,7 +239,7 @@ markLine: { data: [{ type: 'average', name: '平均值' }] } }] }; - //historyOption.value = option; // 保留原始option用于初始化 + historyOption.value ??= option; // 保留原始option用于初始化 if (historyChart.value) { historyChart.value.setOption(option, false); } @@ -259,7 +259,7 @@ labelLine: { show: false }, data: typeData }] }; - typeDistributionOption.value = option; // 保留原始option用于初始化 + typeDistributionOption.value ??= option; // 保留原始option用于初始化 if (typeDistributionChart.value) { typeDistributionChart.value.setOption(option, false); } diff --git a/src/client/ClientIndex.vue b/src/client/ClientIndex.vue index 449a21f..44eb919 100644 --- a/src/client/ClientIndex.vue +++ b/src/client/ClientIndex.vue @@ -1,12 +1,11 @@