mirror of
https://github.com/Megghy/vtsuru.live.git
synced 2025-12-07 02:46:55 +08:00
particularly complete forum function, add point order export and user delete
This commit is contained in:
@@ -9,7 +9,6 @@ import { useRoute } from 'vue-router'
|
||||
|
||||
export const ACCOUNT = ref<AccountInfo>({} as AccountInfo)
|
||||
export const isLoadingAccount = ref(true)
|
||||
const route = useRoute()
|
||||
|
||||
const { message } = createDiscreteApi(['message'])
|
||||
const cookie = useLocalStorage('JWT_Token', '')
|
||||
@@ -42,6 +41,7 @@ export async function GetSelfAccount() {
|
||||
}
|
||||
export function UpdateAccountLoop() {
|
||||
setInterval(() => {
|
||||
const route = useRoute()
|
||||
if (ACCOUNT.value && route?.name != 'question-display') {
|
||||
// 防止在问题详情页刷新
|
||||
GetSelfAccount()
|
||||
@@ -67,18 +67,14 @@ 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 = ACCOUNT.value.settings.enableFunctions.filter((f) => f != func)
|
||||
} else {
|
||||
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) ? '启用' : '禁用'}`,
|
||||
)
|
||||
message.success(`已${ACCOUNT.value?.settings.enableFunctions.includes(func) ? '启用' : '禁用'}`)
|
||||
} else {
|
||||
if (ACCOUNT.value) {
|
||||
ACCOUNT.value.settings.enableFunctions = oldValue
|
||||
@@ -89,9 +85,7 @@ export async function UpdateFunctionEnable(func: FunctionTypes) {
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
message.error(
|
||||
`${ACCOUNT.value?.settings.enableFunctions.includes(func) ? '启用' : '禁用'}失败: ${err}`,
|
||||
)
|
||||
message.error(`${ACCOUNT.value?.settings.enableFunctions.includes(func) ? '启用' : '禁用'}失败: ${err}`)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,12 +3,11 @@ export interface APIRoot<T> {
|
||||
message: string
|
||||
data: T
|
||||
}
|
||||
export interface PaginationResponse<T> {
|
||||
export interface PaginationResponse<T> extends APIRoot<T> {
|
||||
total: number
|
||||
index: number
|
||||
size: number
|
||||
hasMore: boolean
|
||||
datas: T
|
||||
pn: number
|
||||
ps: number
|
||||
more: boolean
|
||||
}
|
||||
export enum IndexTypes {
|
||||
Default,
|
||||
@@ -661,7 +660,9 @@ export interface ResponsePointOrder2OwnerModel {
|
||||
customer: BiliAuthModel
|
||||
address?: AddressInfo
|
||||
goodsId: number
|
||||
count: number
|
||||
createAt: number
|
||||
updateAt: number
|
||||
status: PointOrderStatus
|
||||
|
||||
trackingNumber?: string
|
||||
@@ -692,6 +693,7 @@ export interface ResponsePointHisrotyModel {
|
||||
type: EventDataTypes
|
||||
from: PointFrom
|
||||
createAt: number
|
||||
count: number
|
||||
|
||||
extra?: any
|
||||
}
|
||||
|
||||
122
src/api/models/forum.ts
Normal file
122
src/api/models/forum.ts
Normal file
@@ -0,0 +1,122 @@
|
||||
import { UserBasicInfo } from '../api-models'
|
||||
|
||||
export enum ForumTopicSortTypes {
|
||||
Time,
|
||||
Comment,
|
||||
Like,
|
||||
}
|
||||
export enum ForumCommentSortTypes {
|
||||
Time,
|
||||
Like,
|
||||
}
|
||||
export enum ForumUserLevels {
|
||||
Guest,
|
||||
User,
|
||||
Member,
|
||||
AuthedMember,
|
||||
Admin,
|
||||
}
|
||||
|
||||
export interface ForumSetting {
|
||||
allowedViewerLevel: ForumUserLevels // Assuming the default value is handled elsewhere
|
||||
allowPost: boolean // Assuming the default value is handled elsewhere
|
||||
allowedPostLevel: ForumUserLevels // Assuming the default value is handled elsewhere
|
||||
requireApply: boolean // Assuming the default value is handled elsewhere
|
||||
requireAuthedToJoin: boolean // Assuming the default value is handled elsewhere
|
||||
sendTopicDelay: number // Assuming the default value is handled elsewhere
|
||||
}
|
||||
export interface ForumUserModel extends UserBasicInfo {
|
||||
isAdmin: boolean
|
||||
}
|
||||
export type ForumModel = {
|
||||
id: number
|
||||
name: string
|
||||
owner: ForumUserModel
|
||||
description: string
|
||||
topicCount: number
|
||||
|
||||
settings: ForumSetting
|
||||
|
||||
admins: ForumUserModel[]
|
||||
members: ForumUserModel[]
|
||||
applying: ForumUserModel[]
|
||||
blackList: ForumUserModel[]
|
||||
|
||||
level: ForumUserLevels
|
||||
isApplied: boolean
|
||||
|
||||
sections: ForumSectionModel[]
|
||||
createAt: number
|
||||
|
||||
isAdmin: boolean
|
||||
}
|
||||
export type ForumSectionModel = {
|
||||
id: number
|
||||
name: string
|
||||
description: string
|
||||
createAt: number
|
||||
}
|
||||
export enum ForumTopicTypes {
|
||||
Default,
|
||||
Vote,
|
||||
}
|
||||
export type ForumTopicSetting = {
|
||||
canReply?: boolean
|
||||
}
|
||||
export interface ForumTopicBaseModel {
|
||||
id: number // Primary and identity fields in C# typically correspond to required fields in TS
|
||||
user: UserBasicInfo
|
||||
section: ForumSectionModel
|
||||
title: string
|
||||
content: string
|
||||
|
||||
latestRepliedBy?: UserBasicInfo
|
||||
repliedAt?: number
|
||||
|
||||
likeCount: number // Assuming the default value is handled elsewhere
|
||||
commentCount: number // Assuming the default value is handled elsewhere
|
||||
viewCount: number // Assuming the default value is handled elsewhere
|
||||
sampleLikedBy: number[]
|
||||
|
||||
createAt: Date // DateTime in C# translates to Date in TS
|
||||
editAt?: Date | null // Nullable DateTime in C# is optional or null in TS
|
||||
|
||||
isLiked: boolean
|
||||
isLocked?: boolean // Assuming the default value is handled elsewhere
|
||||
isPinned?: boolean // Assuming the default value is handled elsewhere
|
||||
isHighlighted?: boolean // Assuming the default value is handled elsewhere
|
||||
}
|
||||
export interface ForumTopicModel extends ForumTopicBaseModel {
|
||||
isLocked?: boolean // Assuming the default value is handled elsewhere
|
||||
isDeleted?: boolean // Assuming the default value is handled elsewhere
|
||||
|
||||
isHidden?: boolean // Assuming the default value is handled elsewhere
|
||||
|
||||
type?: ForumTopicTypes // Assuming the default value is handled elsewhere
|
||||
extraTypeId?: number | null // Nullable int in C# is optional or null in TS
|
||||
likedBy?: number[] // Assuming the default value is handled elsewhere
|
||||
}
|
||||
export interface ForumCommentModel {
|
||||
id: number
|
||||
user: UserBasicInfo
|
||||
content: string
|
||||
replies: ForumReplyModel[]
|
||||
sendAt: Date
|
||||
|
||||
likeCount: number
|
||||
isLiked: boolean
|
||||
}
|
||||
export interface ForumReplyModel {
|
||||
id: number
|
||||
user: UserBasicInfo
|
||||
content: string
|
||||
replyTo?: number
|
||||
sendAt: Date
|
||||
}
|
||||
export interface ForumPostTopicModel {
|
||||
section?: number
|
||||
title: string
|
||||
content: string
|
||||
owner: number
|
||||
type?: ForumTopicTypes
|
||||
}
|
||||
@@ -19,23 +19,34 @@ export async function QueryPostAPIWithParams<T>(
|
||||
contentType?: string,
|
||||
headers?: [string, string][],
|
||||
): Promise<APIRoot<T>> {
|
||||
return await QueryPostAPIWithParamsInternal<APIRoot<T>>(urlString, params, body, contentType, headers)
|
||||
}
|
||||
async function QueryPostAPIWithParamsInternal<T>(
|
||||
urlString: string,
|
||||
params?: any,
|
||||
body?: any,
|
||||
contentType: string = 'application/json',
|
||||
headers: [string, string][] = [],
|
||||
) {
|
||||
const url = new URL(urlString)
|
||||
url.search = getParams(params)
|
||||
headers ??= []
|
||||
if (cookie.value) headers?.push(['Authorization', `Bearer ${cookie.value}`])
|
||||
|
||||
if (contentType) headers?.push(['Content-Type', contentType])
|
||||
|
||||
return await QueryAPIInternal<T>(url, {
|
||||
method: 'post',
|
||||
headers: headers,
|
||||
body: typeof body === 'string' ? body : JSON.stringify(body),
|
||||
})
|
||||
}
|
||||
async function QueryAPIInternal<T>(url: URL, init: RequestInit) {
|
||||
try {
|
||||
const data = await fetch(url, {
|
||||
method: 'post',
|
||||
headers: headers,
|
||||
body: typeof body === 'string' ? body : JSON.stringify(body),
|
||||
})
|
||||
const result = (await data.json()) as APIRoot<T>
|
||||
const data = await fetch(url, init)
|
||||
const result = (await data.json()) as T
|
||||
return result
|
||||
} catch (e) {
|
||||
console.error(`[POST] API调用失败: ${e}`)
|
||||
console.error(`[${init.method}] API调用失败: ${e}`)
|
||||
if (!apiFail.value) {
|
||||
apiFail.value = true
|
||||
console.log('默认API异常, 切换至故障转移节点')
|
||||
@@ -48,30 +59,34 @@ export async function QueryGetAPI<T>(
|
||||
params?: any,
|
||||
headers?: [string, string][],
|
||||
): Promise<APIRoot<T>> {
|
||||
return await QueryGetAPIInternal<APIRoot<T>>(urlString, params, headers)
|
||||
}
|
||||
async function QueryGetAPIInternal<T>(urlString: string, params?: any, headers?: [string, string][]) {
|
||||
const url = new URL(urlString)
|
||||
url.search = getParams(params)
|
||||
if (cookie.value) {
|
||||
headers ??= []
|
||||
if (cookie.value) headers?.push(['Authorization', `Bearer ${cookie.value}`])
|
||||
}
|
||||
try {
|
||||
const data = await fetch(url.toString(), {
|
||||
method: 'get',
|
||||
headers: headers,
|
||||
})
|
||||
const result = (await data.json()) as APIRoot<T>
|
||||
return result
|
||||
} catch (e) {
|
||||
console.error(`[GET] API调用失败: ${e}`)
|
||||
if (!apiFail.value) {
|
||||
apiFail.value = true
|
||||
console.log('默认API异常, 切换至故障转移节点')
|
||||
}
|
||||
throw e
|
||||
}
|
||||
return await QueryAPIInternal<T>(url, {
|
||||
method: 'get',
|
||||
headers: headers,
|
||||
})
|
||||
}
|
||||
function getParams(params?: [string, string][]) {
|
||||
function getParams(params: any) {
|
||||
const urlParams = new URLSearchParams(window.location.search)
|
||||
|
||||
if (params) {
|
||||
const keys = Object.keys(params)
|
||||
if (keys.length > 0) {
|
||||
keys.forEach((k) => {
|
||||
if (params[k] == undefined) {
|
||||
delete params[k]
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const resultParams = new URLSearchParams(params)
|
||||
if (urlParams.has('as')) {
|
||||
resultParams.set('as', urlParams.get('as') || '')
|
||||
@@ -81,12 +96,12 @@ function getParams(params?: [string, string][]) {
|
||||
}
|
||||
return resultParams.toString()
|
||||
}
|
||||
export async function QueryPostPaginationAPI<T>(url: string, body?: unknown): Promise<APIRoot<PaginationResponse<T>>> {
|
||||
return await QueryPostAPI<PaginationResponse<T>>(url, body)
|
||||
export async function QueryPostPaginationAPI<T>(url: string, body?: unknown): Promise<PaginationResponse<T>> {
|
||||
return await QueryPostAPIWithParamsInternal<PaginationResponse<T>>(url, undefined, body)
|
||||
}
|
||||
export async function QueryGetPaginationAPI<T>(
|
||||
urlString: string,
|
||||
params?: unknown,
|
||||
): Promise<APIRoot<PaginationResponse<T>>> {
|
||||
return await QueryGetAPI<PaginationResponse<T>>(urlString, params)
|
||||
export async function QueryGetPaginationAPI<T>(urlString: string, params?: unknown): Promise<PaginationResponse<T>> {
|
||||
return await QueryGetAPIInternal<PaginationResponse<T>>(urlString, params)
|
||||
}
|
||||
export function GetHeaders(): [string, string][] {
|
||||
return [['Authorization', `Bearer ${cookie.value}`]]
|
||||
}
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import { QueryGetAPI } from '@/api/query'
|
||||
import { BASE_API, USER_API_URL, apiFail } from '@/data/constants'
|
||||
import { APIRoot, UserInfo } from './api-models'
|
||||
import { USER_API_URL, apiFail } from '@/data/constants'
|
||||
import { ref } from 'vue'
|
||||
import { useRouteParams } from '@vueuse/router'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { APIRoot, UserInfo } from './api-models'
|
||||
|
||||
export const USERS = ref<{ [id: string]: UserInfo }>({})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user