chore: format code style and update linting configuration

This commit is contained in:
Megghy
2025-10-02 10:38:23 +08:00
parent 6fd046adcd
commit 758549d29d
253 changed files with 16258 additions and 15833 deletions

View File

@@ -1,84 +1,84 @@
import { QueryGetAPI, QueryPostAPI, QueryPostAPIWithParams } from '@/api/query';
import { ACCOUNT_API_URL, USER_CONFIG_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';
import type { AccountInfo, APIRoot, FunctionTypes } from './api-models'
import { StorageSerializers } from '@vueuse/core'
import { isSameDay } from 'date-fns'
import { createDiscreteApi } from 'naive-ui'
import { ref } from 'vue'
import { QueryGetAPI, QueryPostAPI, QueryPostAPIWithParams } from '@/api/query'
import { ACCOUNT_API_URL, USER_CONFIG_API_URL } from '@/data/constants'
export const ACCOUNT = ref<AccountInfo>({} as AccountInfo);
export const isLoadingAccount = ref(true);
export const ACCOUNT = ref<AccountInfo>({} as AccountInfo)
export const isLoadingAccount = ref(true)
export const isLoggedIn = computed<boolean>(() => {
return ACCOUNT.value.id > 0;
});
return ACCOUNT.value.id > 0
})
const { message } = createDiscreteApi(['message']);
export const cookie = useLocalStorage<{ cookie: string; refreshDate: number }>('Cookie', {cookie: '', refreshDate: 0}, { serializer: StorageSerializers.object });
const { message } = createDiscreteApi(['message'])
export const cookie = useLocalStorage<{ cookie: string, refreshDate: number }>('Cookie', { cookie: '', refreshDate: 0 }, { serializer: StorageSerializers.object })
export async function GetSelfAccount(token?: string) {
if (cookie.value.cookie || token) {
const result = await Self(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;
//console.log('[vtsuru] 已获取账户信息')
if (!cookie.value.cookie || !isSameDay(new Date(), cookie.value!.refreshDate)) {
refreshCookie(token);
isLoadingAccount.value = false
// console.log('[vtsuru] 已获取账户信息')
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');
localStorage.removeItem('JWT_Token')
if (!token) {
cookie.value = undefined;
console.warn('[vtsuru] Cookie 已失效, 需要重新登陆');
message.error('Cookie 已失效, 需要重新登陆');
cookie.value = undefined
console.warn('[vtsuru] Cookie 已失效, 需要重新登陆')
message.error('Cookie 已失效, 需要重新登陆')
setTimeout(() => {
location.reload();
}, 1500);
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<string>(`${ACCOUNT_API_URL}refresh-token`, { token }).then((data) => {
if (data.code == 200) {
cookie.value = {
cookie: data.data,
refreshDate: new Date().getTime()
};
console.log('[vtsuru] 已刷新Cookie');
refreshDate: new Date().getTime(),
}
console.log('[vtsuru] 已刷新Cookie')
}
});
})
}
export async function SaveAccountSettings() {
return await QueryPostAPI(
ACCOUNT_API_URL + 'update-setting',
ACCOUNT.value?.settings
);
return 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
);
return QueryPostAPI(
`${ACCOUNT_API_URL}update-enable-functions`,
functions,
)
}
export async function SaveSetting(
name:
@@ -90,239 +90,239 @@ export async function SaveSetting(
| 'SongRequest'
| 'QuestionBox'
| 'SendEmail',
setting: unknown
setting: unknown,
) {
const result = await QueryPostAPIWithParams(
ACCOUNT_API_URL + 'update-single-setting',
`${ACCOUNT_API_URL}update-single-setting`,
{
name
name,
},
setting
);
return result.message;
setting,
)
return result.message
}
export async function UpdateFunctionEnable(func: FunctionTypes) {
if (ACCOUNT.value) {
const oldValue = JSON.parse(
JSON.stringify(ACCOUNT.value.settings.enableFunctions)
);
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
= 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) ? '启用' : '禁用'}`
);
`${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}`
);
`${ACCOUNT.value?.settings.enableFunctions.includes(func) ? '启用' : '禁用'}失败: ${data.message}`,
)
}
})
.catch((err) => {
message.error(
`${ACCOUNT.value?.settings.enableFunctions.includes(func) ? '启用' : '禁用'}失败: ${err}`
);
});
`${ACCOUNT.value?.settings.enableFunctions.includes(func) ? '启用' : '禁用'}失败: ${err}`,
)
})
}
}
export function useAccount() {
return ACCOUNT;
return ACCOUNT
}
export async function Register(
name: string,
email: string,
password: string,
token: string
token: string,
): Promise<APIRoot<string>> {
return QueryPostAPI<string>(`${ACCOUNT_API_URL}register`, {
name,
email,
password,
token
});
token,
})
}
export async function Login(
nameOrEmail: string,
password: string
password: string,
): Promise<APIRoot<string>> {
return QueryPostAPI<string>(`${ACCOUNT_API_URL}login`, {
nameOrEmail,
password
});
password,
})
}
export async function Self(token?: string): Promise<APIRoot<AccountInfo>> {
return QueryPostAPIWithParams<AccountInfo>(`${ACCOUNT_API_URL}self`, token ? { token } : undefined);
return QueryPostAPIWithParams<AccountInfo>(`${ACCOUNT_API_URL}self`, token ? { token } : undefined)
}
export async function AddBiliBlackList(
id: number,
name: string
name: string,
): Promise<APIRoot<unknown>> {
return QueryGetAPI<AccountInfo>(`${ACCOUNT_API_URL}black-list/add-bili`, {
id: id,
name: name
});
id,
name,
})
}
export async function DelBiliBlackList(id: number): Promise<APIRoot<unknown>> {
return QueryGetAPI<AccountInfo>(`${ACCOUNT_API_URL}black-list/del-bili`, {
id: id
});
id,
})
}
export async function DelBlackList(id: number): Promise<APIRoot<unknown>> {
return QueryGetAPI<AccountInfo>(`${ACCOUNT_API_URL}black-list/del`, {
id: id
});
id,
})
}
export function downloadConfigDirect(name: string) {
return QueryGetAPI<string>(USER_CONFIG_API_URL + 'get', {
name: name
});
export async function downloadConfigDirect(name: string) {
return QueryGetAPI<string>(`${USER_CONFIG_API_URL}get`, {
name,
})
}
export type ConfigStatus = 'success' | 'error' | 'notfound';
export type ConfigStatus = 'success' | 'error' | 'notfound'
export async function DownloadConfig<T>(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<string>(USER_CONFIG_API_URL + (id ? 'get-user' : 'get'), {
name: name,
id: id
});
name,
id,
})
if (resp.code == 200) {
console.log('已获取配置文件: ' + name);
console.log(`已获取配置文件: ${name}`)
return {
msg: undefined,
status: 'success',
data: JSON.parse(resp.data) as T
};
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
};
data: undefined,
}
} else {
console.error(`无法获取配置文件 [${name}]: ` + resp.message);
console.error(`无法获取配置文件 [${name}]: ${resp.message}`)
return {
msg: `无法获取配置文件 [${name}]: ` + resp.message,
msg: `无法获取配置文件 [${name}]: ${resp.message}`,
status: 'error',
data: undefined
};
data: undefined,
}
}
} catch (err) {
console.error(`无法获取配置文件 [${name}]: ` + err);
console.error(`无法获取配置文件 [${name}]: ${err}`)
return {
msg: `无法获取配置文件 [${name}]: ` + err,
msg: `无法获取配置文件 [${name}]: ${err}`,
status: 'error',
data: undefined
};
data: undefined,
}
}
}
export async function UploadConfig(name: string, data: unknown, isPublic: boolean = false) {
try {
const resp = await QueryPostAPI(USER_CONFIG_API_URL + 'set', {
name: name,
const resp = await QueryPostAPI(`${USER_CONFIG_API_URL}set`, {
name,
json: JSON.stringify(data),
public: isPublic
});
public: isPublic,
})
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 GetConfigHash(name: string) {
try {
const resp = await QueryGetAPI<string>(USER_CONFIG_API_URL + 'hash', {
name: name
});
const resp = await QueryGetAPI<string>(`${USER_CONFIG_API_URL}hash`, {
name,
})
if (resp.code == 200) {
return resp.data;
return resp.data
} else {
console.error(`获取配置文件hash失败: ` + resp.message);
return null;
console.error(`获取配置文件hash失败: ${resp.message}`)
return null
}
} catch (err) {
console.error(`获取配置文件hash失败: ` + err);
return null;
console.error(`获取配置文件hash失败: ${err}`)
return null
}
}
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;
1,
)
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
);
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
);
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
}
}
}

View File

@@ -1,5 +1,4 @@
import { ExtendedDock24Filled } from '@vicons/fluent'
import { UserConsumptionSetting } from './models/consumption'
import type { UserConsumptionSetting } from './models/consumption'
export interface APIRoot<T> {
code: number
@@ -13,16 +12,16 @@ export interface PaginationResponse<T> extends APIRoot<T> {
more: boolean
}
export enum IndexTypes {
Default
Default,
}
export enum SongListTypes {
Default
Default,
}
export enum GuardLevel {
None = 0,
Zongdu = 1,
Tidu = 2,
Jianzhang = 3
Jianzhang = 3,
}
export interface UserBasicInfo {
name: string
@@ -40,7 +39,7 @@ export interface UserInfo extends UserBasicInfo {
isInBlackList: boolean
templateTypes: { [key: string]: string }
streamerInfo?: StreamerModel
allowCheckInRanking?: boolean // 是否允许查看签到排行
allowCheckInRanking?: boolean // 是否允许查看签到排行
allowQuestionBoxUploadImage?: boolean // 是否允许问题箱上传图片
}
}
@@ -57,7 +56,7 @@ export enum EventFetcherType {
Application,
OBS,
Tauri,
Server
Server,
}
export interface AccountInfo extends UserInfo {
isEmailVerified: boolean
@@ -105,7 +104,7 @@ export enum BiliAuthCodeStatusType {
NotBind,
Active,
Notfound,
Inactive
Inactive,
}
export interface Setting_SendEmail {
recieveQA: boolean
@@ -116,7 +115,7 @@ export enum SaftyLevels {
Disabled,
Low,
Medium,
High
High,
}
export interface Setting_QuestionBox {
allowUnregistedUser: boolean
@@ -236,15 +235,15 @@ export interface Setting_Point {
shouldDiscontinueWhenSoldOut: boolean
// 签到系统设置
enableCheckIn: boolean // 是否启用签到功能
checkInKeyword: string // 签到关键词
givePointsForCheckIn: boolean // 是否为签到提供积分
baseCheckInPoints: number // 基础签到积分
enableConsecutiveBonus: boolean // 是否启用连续签到奖励
bonusPointsPerDay: number // 每天额外奖励积分
maxBonusPoints: number // 最大奖励积分
allowSelfCheckIn: boolean // 是否允许自己签到
requireAuth: boolean // 是否需要认证
enableCheckIn: boolean // 是否启用签到功能
checkInKeyword: string // 签到关键词
givePointsForCheckIn: boolean // 是否为签到提供积分
baseCheckInPoints: number // 基础签到积分
enableConsecutiveBonus: boolean // 是否启用连续签到奖励
bonusPointsPerDay: number // 每天额外奖励积分
maxBonusPoints: number // 最大奖励积分
allowSelfCheckIn: boolean // 是否允许自己签到
requireAuth: boolean // 是否需要认证
}
export interface Setting_QuestionDisplay {
font?: string // Optional string, with a maximum length of 30 characters
@@ -271,28 +270,28 @@ export interface Setting_QuestionDisplay {
export enum QuestionDisplayAlign {
Left,
Right,
Center
Center,
}
export enum SettingPointGiftAllowType {
All,
WhiteList
WhiteList,
}
export enum KeywordMatchType {
Full,
Contains,
Regex
Regex,
}
export enum QueueSortType {
GuardFirst,
PaymentFist,
TimeFirst,
FansMedalFirst
FansMedalFirst,
}
export enum QueueGiftFilterType {
Or,
And
And,
}
export enum FunctionTypes {
SongList,
@@ -312,7 +311,7 @@ export enum SongFrom {
Custom,
Netease,
FiveSing,
Kugou
Kugou,
}
export interface SongsInfo {
id: number
@@ -327,7 +326,7 @@ export interface SongsInfo {
tags?: string[]
createTime: number
updateTime: number
//paidSong: boolean
// paidSong: boolean
options?: SongRequestOption
cover?: string
}
@@ -344,13 +343,13 @@ export enum SongLanguage {
Japanese, // 日文
Spanish, // 西班牙文
French, // 法文
Other //其他
Other, // 其他
}
export enum LevelTypes {
Info,
Success,
Warn,
Error
Error,
}
export interface NotifactionInfo {
id: string
@@ -359,7 +358,7 @@ export interface NotifactionInfo {
message: string
type: LevelTypes
}
//SENSITIVE_TERM, HATE, VIOLENCE, PORNOGRAPHY, POLITICS, ADVERTISING, AGGRESSION
// SENSITIVE_TERM, HATE, VIOLENCE, PORNOGRAPHY, POLITICS, ADVERTISING, AGGRESSION
export enum ViolationTypes {
SENSITIVE_TERM,
HATE,
@@ -367,9 +366,9 @@ export enum ViolationTypes {
PORNOGRAPHY,
POLITICS,
ADVERTISING,
AGGRESSION
AGGRESSION,
}
export type QAReviewInfo = {
export interface QAReviewInfo {
isApproved: boolean
saftyScore: number
violationType: ViolationTypes[]
@@ -378,8 +377,8 @@ export interface QAInfo {
id: number
sender: UserBasicInfo
target: UserBasicInfo
question: { message: string; }
answer?: { message: string; createdAt: number }
question: { message: string }
answer?: { message: string, createdAt: number }
isReaded?: boolean
isSenderRegisted: boolean
isPublic: boolean
@@ -433,7 +432,7 @@ export interface BatchScheduleRequest {
export enum ThemeType {
Auto = 'auto',
Light = 'light',
Dark = 'dark'
Dark = 'dark',
}
export interface VideoCollectCreateModel {
id?: string
@@ -467,12 +466,12 @@ export interface VideoCollectVideo {
}
export enum VideoFrom {
Collect,
Spam
Spam,
}
export enum VideoStatus {
Pending,
Accepted,
Rejected
Rejected,
}
export interface VideoSender {
sendAt: number
@@ -488,7 +487,7 @@ export interface VideoInfo {
}
export interface VideoCollectDetail {
table: VideoCollectTable
videos: { info: VideoInfo; video: VideoCollectVideo }[]
videos: { info: VideoInfo, video: VideoCollectVideo }[]
}
export interface GameInfo {
game_id: string
@@ -519,13 +518,13 @@ export interface OpenLiveLotteryUserInfo {
level?: number
avatar: string
fans_medal_level: number
fans_medal_name: string //粉丝勋章名
fans_medal_wearing_status: boolean //该房间粉丝勋章佩戴情况
fans_medal_name: string // 粉丝勋章名
fans_medal_wearing_status: boolean // 该房间粉丝勋章佩戴情况
guard_level: number
}
export enum OpenLiveLotteryType {
Waiting,
Result
Result,
}
export interface UpdateLiveLotteryUsersModel {
users: OpenLiveLotteryUserInfo[]
@@ -560,26 +559,26 @@ export enum SongRequestFrom {
Danmaku,
SC,
Web,
Gift
Gift,
}
export enum QueueFrom {
Manual,
Danmaku,
Gift,
Web
Web,
}
export enum SongRequestStatus {
Waiting,
Singing,
Finish,
Cancel
Cancel,
}
export enum QueueStatus {
Waiting,
Progressing,
Finish,
Cancel
Cancel,
}
export interface EventModel {
type: EventDataTypes
@@ -606,7 +605,7 @@ export enum EventDataTypes {
Like,
SCDel,
Enter,
Follow
Follow,
}
export interface ResponseQueueModel {
id: number
@@ -659,7 +658,7 @@ export enum FeedbackType {
Opinion,
Bug,
FunctionRequest,
Other
Other,
}
export enum FeedbackStatus {
Padding,
@@ -667,7 +666,7 @@ export enum FeedbackStatus {
Finish,
Todo,
Reject,
Developing
Developing,
}
export interface TagInfo {
name: string
@@ -675,23 +674,23 @@ export interface TagInfo {
}
export enum GoodsStatus {
Normal, // 商品正常
//OutOfStock, // 商品无货
Discontinued // 商品下架
// OutOfStock, // 商品无货
Discontinued, // 商品下架
}
export enum GoodsTypes {
Physical,
Virtual
Virtual,
}
// 添加密钥选择模式枚举
export enum KeySelectionMode {
None,
Random, // 随机选择
Sequential // 顺序选择
Random, // 随机选择
Sequential, // 顺序选择
}
export interface PointGoodsSetting {
guardFree?: { year: number; month: number }
guardFree?: { year: number, month: number }
allowGuardLevel?: GuardLevel
}
export interface ResponsePointGoodModel {
@@ -814,7 +813,7 @@ export interface ResponsePointOrder2UserModel {
export enum PointOrderStatus {
Pending, // 订单正在等待处理
Shipped, // 订单已发货
Completed // 订单已完成
Completed, // 订单已完成
}
export interface ResponsePointHisrotyModel {
point: number
@@ -831,7 +830,7 @@ export enum PointFrom {
Danmaku,
Manual,
Use,
CheckIn
CheckIn,
}
export interface ResponseUserIndexModel {
@@ -850,7 +849,7 @@ export interface CheckInRankingInfo {
lastCheckInTime: number
isAuthed: boolean
monthlyCheckInCount?: number // 本月签到次数
totalCheckInCount?: number // 总签到次数
totalCheckInCount?: number // 总签到次数
}
// 签到结果
@@ -870,108 +869,108 @@ export enum UserFileTypes {
Audio = 1,
Video = 2,
Document = 3,
Other = 4
Other = 4,
}
/**
* 文件存储位置枚举
*/
export enum UserFileLocation {
Local = 0
Local = 0,
}
/**
* 文件上传响应接口
*/
export interface UploadFileResponse {
id: number;
path: string;
name: string;
hash: string;
id: number
path: string
name: string
hash: string
}
/**
* 扩展的文件信息接口,用于文件上传组件
*/
export interface ExtendedUploadFileInfo {
id: string; // 文件唯一标识符
name: string; // 文件名称
status: 'uploading' | 'finished' | 'error' | 'removed'; // 上传状态
thumbnailUrl?: string; // 缩略图URL
file?: File; // 可选的文件对象
id: string // 文件唯一标识符
name: string // 文件名称
status: 'uploading' | 'finished' | 'error' | 'removed' // 上传状态
thumbnailUrl?: string // 缩略图URL
file?: File // 可选的文件对象
}
// 弹幕投票相关类型定义
export enum VoteResultMode {
ByCount = 0, // 按人数计票
ByGiftValue = 1 // 按礼物价值计票
ByCount = 0, // 按人数计票
ByGiftValue = 1, // 按礼物价值计票
}
export interface APIFileModel {
id: number;
path: string;
name: string;
hash: string;
id: number
path: string
name: string
hash: string
}
export interface VoteConfig {
isEnabled: boolean;
showResults: boolean;
voteDurationSeconds: number;
voteCommand: string;
voteEndCommand: string;
voteTitle: string;
allowMultipleOptions: boolean;
allowMultipleVotes: boolean;
allowCustomOptions: boolean;
logVotes: boolean;
defaultOptions: string[];
backgroundFile?: APIFileModel;
backgroundColor: string;
textColor: string;
optionColor: string;
roundedCorners: boolean;
displayPosition: string;
allowGiftVoting: boolean;
minGiftPrice?: number;
voteResultMode: VoteResultMode;
isEnabled: boolean
showResults: boolean
voteDurationSeconds: number
voteCommand: string
voteEndCommand: string
voteTitle: string
allowMultipleOptions: boolean
allowMultipleVotes: boolean
allowCustomOptions: boolean
logVotes: boolean
defaultOptions: string[]
backgroundFile?: APIFileModel
backgroundColor: string
textColor: string
optionColor: string
roundedCorners: boolean
displayPosition: string
allowGiftVoting: boolean
minGiftPrice?: number
voteResultMode: VoteResultMode
}
export interface VoteOption {
text: string;
count: number;
voters: string[];
percentage?: number; // 用于OBS显示
text: string
count: number
voters: string[]
percentage?: number // 用于OBS显示
}
export interface ResponseVoteSession {
id: number;
title: string;
options: VoteOption[];
startTime: number;
endTime?: number;
isActive: boolean;
totalVotes: number;
creator?: UserBasicInfo;
id: number
title: string
options: VoteOption[]
startTime: number
endTime?: number
isActive: boolean
totalVotes: number
creator?: UserBasicInfo
}
export interface RequestCreateBulletVote {
title: string;
options: string[];
allowMultipleVotes: boolean;
durationSeconds?: number;
title: string
options: string[]
allowMultipleVotes: boolean
durationSeconds?: number
}
export interface VoteOBSData {
title: string;
options: VoteOption[];
totalVotes: number;
showResults: boolean;
isEnding: boolean;
backgroundImage?: string;
backgroundColor: string;
textColor: string;
optionColor: string;
roundedCorners: boolean;
displayPosition: string;
}
title: string
options: VoteOption[]
totalVotes: number
showResults: boolean
isEnding: boolean
backgroundImage?: string
backgroundColor: string
textColor: string
optionColor: string
roundedCorners: boolean
displayPosition: string
}

View File

@@ -1,16 +1,16 @@
export enum ConsumptionTypes{
export enum ConsumptionTypes {
DanmakuStorage,
}
export interface IDeductionSetting {
isEnabled: boolean
}
}
export interface UserConsumptionSetting {
danmakuStorage: DanmakuStorageDeductionSetting
}
export enum DeductionStorageType {
Time,
Count
Count,
}
export interface DanmakuStorageDeductionSetting extends IDeductionSetting {
storageType: DeductionStorageType

View File

@@ -1,4 +1,4 @@
import { UserBasicInfo } from '../api-models'
import type { UserBasicInfo } from '../api-models'
export enum ForumTopicSortTypes {
Time,
@@ -26,9 +26,9 @@ export interface ForumSetting {
sendTopicDelay: number // Assuming the default value is handled elsewhere
}
export interface ForumUserModel extends UserBasicInfo {
isAdmin: boolean
isAdmin: boolean
}
export type ForumModel = {
export interface ForumModel {
id: number
name: string
owner: ForumUserModel
@@ -51,7 +51,7 @@ export type ForumModel = {
isAdmin: boolean
isMember: boolean
}
export type ForumSectionModel = {
export interface ForumSectionModel {
id: number
name: string
description: string
@@ -61,7 +61,7 @@ export enum ForumTopicTypes {
Default,
Vote,
}
export type ForumTopicSetting = {
export interface ForumTopicSetting {
canReply?: boolean
}
export interface ForumTopicBaseModel {

View File

@@ -1,21 +1,19 @@
/* eslint-disable indent */
import type { APIRoot, PaginationResponse } from './api-models'
import { apiFail } from '@/data/constants'
import { useLocalStorage } from '@vueuse/core'
import { APIRoot, PaginationResponse } from './api-models'
import { cookie } from './account';
import { cookie } from './account'
export async function QueryPostAPI<T>(
urlString: string,
body?: unknown,
headers?: [string, string][],
contentType?: string
contentType?: string,
): Promise<APIRoot<T>> {
return await QueryPostAPIWithParams<T>(
return QueryPostAPIWithParams<T>(
urlString,
undefined,
body,
contentType || 'application/json',
headers
headers,
)
}
export async function QueryPostAPIWithParams<T>(
@@ -23,15 +21,15 @@ export async function QueryPostAPIWithParams<T>(
params?: any,
body?: any,
contentType?: string,
headers?: [string, string][]
headers?: [string, string][],
): Promise<APIRoot<T>> {
// @ts-expect-error 忽略
return await QueryPostAPIWithParamsInternal<APIRoot<T>>(
return QueryPostAPIWithParamsInternal<APIRoot<T>>(
urlString,
params,
body,
contentType,
headers
headers,
)
}
async function QueryPostAPIWithParamsInternal<T>(
@@ -39,36 +37,36 @@ async function QueryPostAPIWithParamsInternal<T>(
params?: any,
body?: any,
contentType: string = 'application/json',
headers: [string, string][] = []
headers: [string, string][] = [],
) {
let url: URL
try {
url = new URL(urlString.toString())
} catch (e) {
console.error('尝试解析API地址失败: ' + urlString, e)
console.error(`尝试解析API地址失败: ${urlString}`, e)
return {
code: 400,
message: '无效的API地址: ' + urlString,
data: {} as T
message: `无效的API地址: ${urlString}`,
data: {} as T,
}
}
url.search = getParams(params)
headers ??= []
let h = {} as { [key: string]: string }
const h = {} as { [key: string]: string }
headers.forEach((header) => {
h[header[0]] = header[1]
})
if (cookie.value.cookie) h['Authorization'] = `Bearer ${cookie.value.cookie}`
if (cookie.value.cookie) h.Authorization = `Bearer ${cookie.value.cookie}`
// 当使用FormData时不手动设置Content-Type让浏览器自动添加boundary
if (!(body instanceof FormData)) {
h['Content-Type'] = contentType
}
return await QueryAPIInternal<T>(url, {
return QueryAPIInternal<T>(url, {
method: 'post',
headers: h,
body: body instanceof FormData ? body : typeof body === 'string' ? body : JSON.stringify(body)
body: body instanceof FormData ? body : typeof body === 'string' ? body : JSON.stringify(body),
})
}
async function QueryAPIInternal<T>(url: URL, init: RequestInit) {
@@ -88,36 +86,36 @@ async function QueryAPIInternal<T>(url: URL, init: RequestInit) {
export async function QueryGetAPI<T>(
urlString: string,
params?: any,
headers?: [string, string][]
headers?: [string, string][],
): Promise<APIRoot<T>> {
// @ts-expect-error 忽略
return await QueryGetAPIInternal<APIRoot<T>>(urlString, params, headers)
return QueryGetAPIInternal<APIRoot<T>>(urlString, params, headers)
}
async function QueryGetAPIInternal<T>(
urlString: string,
params?: any,
headers?: [string, string][]
headers?: [string, string][],
) {
try {
let url: URL
try {
url = new URL(urlString.toString())
} catch (e) {
console.error('尝试解析API地址失败: ' + urlString, e)
console.error(`尝试解析API地址失败: ${urlString}`, e)
return {
code: 400,
message: '无效的API地址: ' + urlString,
data: {} as T
message: `无效的API地址: ${urlString}`,
data: {} as T,
}
}
url.search = getParams(params)
headers ??= []
let h = {} as { [key: string]: string }
const h = {} as { [key: string]: string }
headers.forEach((header) => {
h[header[0]] = header[1]
})
if (cookie.value.cookie) {
h['Authorization'] = `Bearer ${cookie.value.cookie}`
h.Authorization = `Bearer ${cookie.value.cookie}`
}
return await QueryAPIInternal<T>(url, { method: 'get', headers: h })
} catch (err) {
@@ -151,21 +149,21 @@ function getParams(params: any) {
}
export async function QueryPostPaginationAPI<T>(
url: string,
body?: unknown
body?: unknown,
): Promise<PaginationResponse<T>> {
// @ts-expect-error 忽略
return await QueryPostAPIWithParamsInternal<PaginationResponse<T>>(
return QueryPostAPIWithParamsInternal<PaginationResponse<T>>(
url,
undefined,
body
body,
)
}
export async function QueryGetPaginationAPI<T>(
urlString: string,
params?: unknown
params?: unknown,
): Promise<PaginationResponse<T>> {
// @ts-expect-error 忽略
return await QueryGetAPIInternal<PaginationResponse<T>>(urlString, params)
return QueryGetAPIInternal<PaginationResponse<T>>(urlString, params)
}
export function GetHeaders(): [string, string][] {
return [['Authorization', `Bearer ${cookie.value?.cookie}`]]

View File

@@ -1,8 +1,8 @@
import { QueryGetAPI } from '@/api/query'
import { USER_API_URL, apiFail } from '@/data/constants'
import type { APIRoot, UserBasicInfo, UserInfo } from './api-models'
import { ref } from 'vue'
import { useRoute } from 'vue-router'
import { APIRoot, UserBasicInfo, UserInfo } from './api-models'
import { QueryGetAPI } from '@/api/query'
import { apiFail, USER_API_URL } from '@/data/constants'
export const USERS = ref<{ [id: string]: UserInfo }>({})
@@ -24,7 +24,7 @@ export async function useUser(id: string | undefined = undefined) {
}
return USERS.value[id]
} else {
console.error('指定id: ' + id + ' 无效')
console.error(`指定id: ${id} 无效`)
}
}
export async function useUserWithUId(id: number) {
@@ -45,6 +45,6 @@ export async function getUserBasicInfo(id: string | number | undefined) {
export async function GetInfo(id: string): Promise<APIRoot<UserInfo>> {
return QueryGetAPI<UserInfo>(`${USER_API_URL}info`, {
id: id,
id,
})
}