diff --git a/bun.lockb b/bun.lockb index 39bd45c..326abcc 100644 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/package.json b/package.json index be66cf8..6916c23 100644 --- a/package.json +++ b/package.json @@ -73,7 +73,6 @@ "unplugin-vue-markdown": "^28.3.1", "uuid": "^11.1.0", "vite": "6.3.3", - "vite-plugin-monaco-editor": "^1.1.0", "vite-plugin-oxlint": "^1.3.1", "vite-svg-loader": "^5.1.0", "vue": "3.5.13", diff --git a/src/api/account.ts b/src/api/account.ts index a02fbac..fe29fde 100644 --- a/src/api/account.ts +++ b/src/api/account.ts @@ -1,5 +1,5 @@ import { QueryGetAPI, QueryPostAPI, QueryPostAPIWithParams } from '@/api/query'; -import { ACCOUNT_API_URL, VTSURU_API_URL } from '@/data/constants'; +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'; @@ -184,7 +184,7 @@ export async function DelBlackList(id: number): Promise> { }); } export function downloadConfigDirect(name: string) { - return QueryGetAPI(VTSURU_API_URL + 'get-config', { + return QueryGetAPI(USER_CONFIG_API_URL + 'get', { name: name }); } @@ -202,7 +202,7 @@ export async function DownloadConfig(name: string, id?: number): Promise< } > { try { - const resp = await QueryGetAPI(VTSURU_API_URL + (id ? 'get-user-config' : 'get-config'), { + const resp = await QueryGetAPI(USER_CONFIG_API_URL + (id ? 'user-get' : 'get'), { name: name, id: id }); @@ -237,11 +237,12 @@ export async function DownloadConfig(name: string, id?: number): Promise< }; } } -export async function UploadConfig(name: string, data: unknown) { +export async function UploadConfig(name: string, data: unknown, isPublic: boolean = false) { try { - const resp = await QueryPostAPI(VTSURU_API_URL + 'set-config', { + const resp = await QueryPostAPI(USER_CONFIG_API_URL + 'set', { name: name, - json: JSON.stringify(data) + json: JSON.stringify(data), + public: isPublic }); if (resp.code == 200) { console.log('已保存配置文件至服务器:' + name); @@ -256,7 +257,7 @@ export async function UploadConfig(name: string, data: unknown) { } export async function GetConfigHash(name: string) { try { - const resp = await QueryGetAPI(VTSURU_API_URL + 'get-config-hash', { + const resp = await QueryGetAPI(USER_CONFIG_API_URL + 'hash', { name: name }); if (resp.code == 200) { diff --git a/src/api/api-models.ts b/src/api/api-models.ts index 031c728..d50c5f2 100644 --- a/src/api/api-models.ts +++ b/src/api/api-models.ts @@ -41,6 +41,7 @@ export interface UserInfo extends UserBasicInfo { templateTypes: { [key: string]: string } streamerInfo?: StreamerModel allowCheckInRanking?: boolean // 是否允许查看签到排行 + allowQuestionBoxUploadImage?: boolean // 是否允许问题箱上传图片 } } export interface EventFetcherStateModel { @@ -119,8 +120,8 @@ export enum SaftyLevels { } export interface Setting_QuestionBox { allowUnregistedUser: boolean - saftyLevel: SaftyLevels + allowImageUpload: boolean } export interface UserSetting { sendEmail: Setting_SendEmail @@ -371,8 +372,8 @@ export interface QAInfo { id: number sender: UserBasicInfo target: UserBasicInfo - question: { message: string; image?: string } - answer?: { message: string; image?: string, createdAt: number } + question: { message: string; } + answer?: { message: string; createdAt: number } isReaded?: boolean isSenderRegisted: boolean isPublic: boolean @@ -380,6 +381,9 @@ export interface QAInfo { sendAt: number isAnonymous: boolean + answerImages?: UploadFileResponse[] + questionImages?: UploadFileResponse[] + tag?: string reviewResult?: QAReviewInfo } @@ -683,7 +687,7 @@ export interface ResponsePointGoodModel { count?: number price: number tags: string[] - cover?: string + cover?: UploadFileResponse images: string[] status: GoodsStatus type: GoodsTypes @@ -702,17 +706,13 @@ export interface ResponsePointGoodModel { keySelectionMode?: KeySelectionMode currentKeyIndex?: number } -export interface ImageUploadModel { - existImages: string[] - newImagesBase64: string[] -} export interface UploadPointGoodsModel { id?: number name: string count?: number price: number tags: string[] - cover?: ImageUploadModel + cover?: UploadFileResponse status: GoodsStatus type: GoodsTypes collectUrl?: string @@ -844,3 +844,42 @@ export interface CheckInResult { consecutiveDays: number todayRank: number } + +/** + * 文件类型枚举 + */ +export enum UserFileTypes { + Image = 0, + Audio = 1, + Video = 2, + Document = 3, + Other = 4 +} + +/** + * 文件存储位置枚举 + */ +export enum UserFileLocation { + Local = 0 +} + +/** + * 文件上传响应接口 + */ +export interface UploadFileResponse { + 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; // 可选的文件对象 +} \ No newline at end of file diff --git a/src/api/query.ts b/src/api/query.ts index a10dfee..c7c65cc 100644 --- a/src/api/query.ts +++ b/src/api/query.ts @@ -7,13 +7,14 @@ import { cookie } from './account'; export async function QueryPostAPI( urlString: string, body?: unknown, - headers?: [string, string][] + headers?: [string, string][], + contentType?: string ): Promise> { return await QueryPostAPIWithParams( urlString, undefined, body, - 'application/json', + contentType || 'application/json', headers ) } @@ -59,11 +60,15 @@ async function QueryPostAPIWithParamsInternal( }) if (cookie.value.cookie) h['Authorization'] = `Bearer ${cookie.value.cookie}` - h['Content-Type'] = contentType + // 当使用FormData时,不手动设置Content-Type,让浏览器自动添加boundary + if (!(body instanceof FormData)) { + h['Content-Type'] = contentType + } + return await QueryAPIInternal(url, { method: 'post', headers: h, - body: typeof body === 'string' ? body : JSON.stringify(body) + body: body instanceof FormData ? body : typeof body === 'string' ? body : JSON.stringify(body) }) } async function QueryAPIInternal(url: URL, init: RequestInit) { diff --git a/src/components.d.ts b/src/components.d.ts index d86be7e..e20602c 100644 --- a/src/components.d.ts +++ b/src/components.d.ts @@ -34,6 +34,7 @@ declare module 'vue' { NPopconfirm: typeof import('naive-ui')['NPopconfirm'] NScrollbar: typeof import('naive-ui')['NScrollbar'] NSpace: typeof import('naive-ui')['NSpace'] + NSpin: typeof import('naive-ui')['NSpin'] NTag: typeof import('naive-ui')['NTag'] NText: typeof import('naive-ui')['NText'] NTime: typeof import('naive-ui')['NTime'] diff --git a/src/components/DynamicForm.vue b/src/components/DynamicForm.vue index 7a94a67..4c4fa0f 100644 --- a/src/components/DynamicForm.vue +++ b/src/components/DynamicForm.vue @@ -1,14 +1,11 @@