diff --git a/Web/src/api/albumApi.ts b/Web/src/api/albumApi.ts index a0867e5..b65a911 100644 --- a/Web/src/api/albumApi.ts +++ b/Web/src/api/albumApi.ts @@ -1,13 +1,42 @@ -import type { - PaginatedResult, - AlbumResponse, - CreateAlbumRequest, - UpdateAlbumRequest, - AlbumPictureRequest, - AlbumPicturesRequest, - BaseResult -} from './types'; -import { fetchApi, BASE_URL } from './fetchClient'; +import { fetchApi, type PaginatedResult, type BaseResult } from './fetchClient'; + +// 相册响应数据 +export interface AlbumResponse { + id: number; + name: string; + description: string; + coverImageUrl?: string; + pictureCount: number; + userId: number; + username?: string; + createdAt: Date; + updatedAt: Date; +} + +// 创建相册请求 +export interface CreateAlbumRequest { + name: string; + description: string; +} + +// 更新相册请求 +export interface UpdateAlbumRequest { + id: number; + name: string; + description: string; +} + +// 相册图片操作请求 +export interface AlbumPictureRequest { + albumId: number; + pictureId: number; +} + +// 批量添加图片到相册请求 +export interface AlbumPicturesRequest { + albumId: number; + pictureIds: number[]; +} // 获取相册列表 export async function getAlbums( @@ -16,14 +45,6 @@ export async function getAlbums( userId?: number ): Promise> { try { - const token = localStorage.getItem('token'); - const headers: Record = { - 'Content-Type': 'application/json', - }; - if (token) { - headers['Authorization'] = `Bearer ${token}`; - } - const queryParams = new URLSearchParams(); queryParams.append('page', page.toString()); queryParams.append('pageSize', pageSize.toString()); @@ -31,19 +52,31 @@ export async function getAlbums( queryParams.append('userId', userId.toString()); } - const url = `${BASE_URL}/album/get_albums?${queryParams.toString()}`; - const response = await fetch(url, { headers }); - const data = await response.json(); - - return data as PaginatedResult; + const url = `/album/get_albums?${queryParams.toString()}`; + const result = await fetchApi>(url); + if (result.success) { + return result as unknown as PaginatedResult; + } else { + console.error('获取相册列表失败:', result.message); + return { + success: false, + message: result.message || '获取相册列表失败', + data: [], + page: page, + pageSize: pageSize, + totalCount: 0, + totalPages: 0, + code: result.code || 500, + }; + } } catch (error) { - console.error('获取相册列表失败:', error); + console.error('获取相册列表时发生意外错误:', error); return { success: false, message: '网络请求失败,请检查您的网络连接', data: [], - page: 1, - pageSize: 10, + page: page, + pageSize: pageSize, totalCount: 0, totalPages: 0, code: 500, diff --git a/Web/src/api/authApi.ts b/Web/src/api/authApi.ts index a7bd08f..1ca35f5 100644 --- a/Web/src/api/authApi.ts +++ b/Web/src/api/authApi.ts @@ -1,10 +1,58 @@ -import {type BaseResult, type AuthResponse, type LoginRequest, type RegisterRequest, type UserProfile, type UpdateUserRequest, type BindAccountRequest} from './types'; -import {fetchApi, BASE_URL} from './fetchClient'; +import {fetchApi, BASE_URL, type BaseResult} from './fetchClient'; +import { type UserRole } from './userManagementApi'; // 认证数据本地存储键 const TOKEN_KEY = 'token'; const USER_KEY = 'user'; +// 登录请求参数 +export interface LoginRequest { + email: string; + password: string; +} + +// 注册请求参数 +export interface RegisterRequest { + username: string; + email: string; + password: string; +} + +// 用户信息 +export interface UserProfile { + id: number; + userName: string; + email: string; + roleName: UserRole | string; // roleName can be UserRole or a string from server +} + +// 认证响应 +export interface AuthResponse { + token: string; + user: UserProfile; +} + +export interface UpdateUserRequest { + userName?: string; + email?: string; + currentPassword?: string; + newPassword?: string; +} + +export type BindType = 0 | 1; + +export const BindType = { + GitHub: 0 as BindType, + LinuxDo: 1 as BindType, +}; + +export interface BindAccountRequest { + email: string; + password: string; + bindType: BindType; + thirdPartyUserId: string; +} + // 用户注册 export async function register(data: RegisterRequest): Promise> { return fetchApi('/auth/register', { diff --git a/Web/src/api/backgroundTaskApi.ts b/Web/src/api/backgroundTaskApi.ts index ec4052f..df94eef 100644 --- a/Web/src/api/backgroundTaskApi.ts +++ b/Web/src/api/backgroundTaskApi.ts @@ -1,5 +1,17 @@ -import { fetchApi } from './fetchClient'; -import type { BaseResult, PictureProcessingTask } from './types'; +import { fetchApi, type BaseResult } from './fetchClient'; +import type { ProcessingStatus } from './pictureApi'; + +// 图片处理任务 +export interface PictureProcessingTask { + pictureId: number; + taskId: string; + pictureName: string; + status: ProcessingStatus; + progress: number; // 0-100 + error?: string; + createdAt: Date; + completedAt?: Date; +} /** * 获取当前用户的所有处理任务 diff --git a/Web/src/api/configApi.ts b/Web/src/api/configApi.ts index 847c7f2..43473eb 100644 --- a/Web/src/api/configApi.ts +++ b/Web/src/api/configApi.ts @@ -1,5 +1,23 @@ -import { UserRole, type BaseResult, type ConfigResponse, type SetConfigRequest } from './types'; -import { fetchApi } from './fetchClient'; +import { fetchApi, type BaseResult } from './fetchClient'; +import { UserRole } from './userManagementApi'; + + +// 配置响应数据 +export interface ConfigResponse { + id: number; + key: string; + value: string; + description: string; + isSecret: boolean; + createdAt: Date; + updatedAt?: Date; +} + +export interface SetConfigRequest { + key: string; + value: string; + description?: string; +} // 获取所有配置 export const getAllConfigs = async (): Promise> => { diff --git a/Web/src/api/fetchClient.ts b/Web/src/api/fetchClient.ts index 29f4621..c5a5331 100644 --- a/Web/src/api/fetchClient.ts +++ b/Web/src/api/fetchClient.ts @@ -1,5 +1,25 @@ -import type { BaseResult } from './types'; import { clearAuthData } from './index'; + +// API响应的基础结构 +export interface BaseResult { + success: boolean; + message: string; + data?: T; + code: number; +} + +// 分页结果通用结构 +export interface PaginatedResult { + success: boolean; + message: string; + data: T[]; + page: number; + pageSize: number; + totalCount: number; + totalPages: number; + code: number; +} + export const BASE_URL = import.meta.env.PROD ? '/api' : 'http://localhost:5153/api'; export async function fetchApi( diff --git a/Web/src/api/index.ts b/Web/src/api/index.ts index 1c4b43c..24f1c9d 100644 --- a/Web/src/api/index.ts +++ b/Web/src/api/index.ts @@ -1,100 +1,11 @@ -// 重新导出类型 export * from './authApi'; -export * from './types'; - -// 导出fetch客户端 -export { fetchApi, BASE_URL } from './fetchClient'; - -// 导出Auth API -export { - register, - login, - getCurrentUser, - updateUserInfo, - saveAuthData, - clearAuthData, - isAuthenticated, - getStoredUser, - bindAccount, - getGitHubLoginUrl, - getLinuxDoLoginUrl -} from './authApi'; - -// 导出Picture API -export { - getPictures, - favoritePicture, - unfavoritePicture, - getUserFavorites, - uploadPicture, - deleteMultiplePictures, - updatePicture, -} from './pictureApi'; - -// 导出Album API -export { - getAlbums, - getAlbumById, - createAlbum, - updateAlbum, - deleteAlbum, - addPictureToAlbum, - addPicturesToAlbum, - removePictureFromAlbum -} from './albumApi'; - -// 导出BackgroundTask API -export { - getUserTasks, - getPictureProcessingStatus, -} from './backgroundTaskApi'; - -// 导出Config API -export { - getAllConfigs, - getConfig, - setConfig, - deleteConfig, - hasRole, - backupConfigs, - restoreConfigs -} from './configApi'; - -// 导出UserManagement API -export { - getUsers, - getUserById, - createUser, - updateUser, - deleteUser, - batchDeleteUsers, - getUserDetail -} from './userManagementApi'; - -// 导出PictureManagement API -export { - getManagementPictures, - getManagementPictureById, - deleteManagementPicture, - batchDeleteManagementPictures, - getManagementPicturesByUserId -} from './pictureManagementApi'; - -// 导出向量数据库 API -export { - getCurrentVectorDb, - switchVectorDb, - clearVectors, - rebuildVectors -} from './vectorDbApi'; - -// 导出LogManagement API -export { - getLogs, - getLogById, - deleteLog, - batchDeleteLogs, - clearLogs, - getLogStatistics -} from './logManagementApi'; - +export * from './albumApi'; +export * from './backgroundTaskApi'; +export * from './configApi'; +export * from './fetchClient'; +export * from './logManagementApi'; +export * from './pictureApi'; +export * from './pictureManagementApi'; +export * from './tagApi'; +export * from './userManagementApi'; +export * from './vectorDbApi'; \ No newline at end of file diff --git a/Web/src/api/logManagementApi.ts b/Web/src/api/logManagementApi.ts index 2068601..2076db3 100644 --- a/Web/src/api/logManagementApi.ts +++ b/Web/src/api/logManagementApi.ts @@ -1,13 +1,60 @@ -import { fetchApi } from './fetchClient'; -import { - type BaseResult, - type PaginatedResult, - type LogResponse, - type LogFilterRequest, - type ClearLogsRequest, - type BatchDeleteResult, - type LogStatistics -} from './types'; +import { fetchApi, type BaseResult, type PaginatedResult } from './fetchClient'; +import { type BatchDeleteResult } from './userManagementApi'; + + +// 日志级别枚举 +export type LogLevel = 'Trace' | 'Debug' | 'Information' | 'Warning' | 'Error' | 'Critical'; + +export const LogLevel = { + Trace: 'Trace' as LogLevel, + Debug: 'Debug' as LogLevel, + Information: 'Information' as LogLevel, + Warning: 'Warning' as LogLevel, + Error: 'Error' as LogLevel, + Critical: 'Critical' as LogLevel +}; + +// 日志响应数据 +export interface LogResponse { + id: number; + level: LogLevel | number; // 支持数字和字符串两种形式 + message: string; + category: string; + eventId?: number; + timestamp: Date; + exception?: string; + requestPath?: string; + requestMethod?: string; + statusCode?: number; + ipAddress?: string; + userId?: string; + properties?: string; +} + +// 日志筛选请求参数 +export interface LogFilterRequest { + page?: number; + pageSize?: number; + searchQuery?: string; + level?: LogLevel | number; // 支持数字和字符串两种形式 + startDate?: string; + endDate?: string; +} + +// 清空日志请求 +export interface ClearLogsRequest { + clearAll?: boolean; + beforeDate?: Date; +} + +// 日志统计信息 +export interface LogStatistics { + totalCount: number; + todayCount: number; + errorCount: number; + warningCount: number; +} + // 获取日志列表 export const getLogs = async ( diff --git a/Web/src/api/pictureApi.ts b/Web/src/api/pictureApi.ts index eb67d83..71e70cf 100644 --- a/Web/src/api/pictureApi.ts +++ b/Web/src/api/pictureApi.ts @@ -1,11 +1,108 @@ -import type { PaginatedResult, PictureResponse, FilteredPicturesRequest, BaseResult, UpdatePictureRequest } from './types'; -import { fetchApi, BASE_URL } from './fetchClient'; +import { fetchApi, BASE_URL, type PaginatedResult, type BaseResult } from './fetchClient'; + +// 图片请求参数 +export interface FilteredPicturesRequest { + page?: number; + pageSize?: number; + searchQuery?: string; + tags?: string; + startDate?: string; + endDate?: string; + userId?: number; + sortBy?: string; + onlyWithGps?: boolean; + useVectorSearch?: boolean; + similarityThreshold?: number; + excludeAlbumId?: number; + albumId?: number; + onlyFavorites?: boolean; + ownerId?: number; + includeAllPublic?: boolean; +} + +// 将类型定义改为枚举,这样既可以作为类型也可以作为值使用 +export type ProcessingStatus = 'Pending' | 'Processing' | 'Completed' | 'Failed'; + +// 添加常量对象提供运行时值 +export const ProcessingStatus = { + Pending: 'Pending' as ProcessingStatus, + Processing: 'Processing' as ProcessingStatus, + Completed: 'Completed' as ProcessingStatus, + Failed: 'Failed' as ProcessingStatus +}; + +// 图片响应数据 +export interface PictureResponse { + id: number; + name: string; + path: string; + thumbnailPath: string; + description: string; + takenAt?: Date; + createdAt: Date; + exifInfo?: any; + tags?: string[]; + userId: number; + username?: string; + isFavorited: boolean; + favoriteCount: number; + permission: number; + albumId?: number; + albumName?: string; + processingStatus: ProcessingStatus; + processingError?: string; + processingProgress: number; +} + +// 收藏请求 +export interface FavoriteRequest { + pictureId: number; +} + +// 上传队列中的文件项 +export interface UploadFile { + id: string; // 本地ID,用于跟踪状态 + file: File; // 原始文件 + status: 'pending' | 'uploading' | 'success' | 'error'; // 上传状态 + percent: number; // 上传进度百分比 0-100 + error?: string; // 错误信息 + response?: PictureResponse; // 上传成功后的响应 +} + +// 图片格式类型 +export type ImageFormat = 0 | 1 | 2 | 3; + +// 添加常量对象提供运行时值 +export const ImageFormat = { + Original: 0 as ImageFormat, + Jpeg: 1 as ImageFormat, + Png: 2 as ImageFormat, + WebP: 3 as ImageFormat +}; + +// 上传图片参数 +export interface UploadPictureParams { + permission?: number; + albumId?: number; + convertToFormat?: ImageFormat; + quality?: number; + onProgress?: (percent: number) => void; +} + +// 删除多张图片请求 +export interface DeleteMultiplePicturesRequest { + pictureIds: number[]; +} + +export interface UpdatePictureRequest { + id: number; + name?: string; + description?: string; + tags?: string[]; +} // 获取图片列表 export async function getPictures(params: FilteredPicturesRequest = {}): Promise> { - // 添加调试日志 - console.log("Search API 请求参数:", params); - // 构建查询参数 const queryParams = new URLSearchParams(); @@ -27,38 +124,34 @@ export async function getPictures(params: FilteredPicturesRequest = {}): Promise if (params.ownerId !== undefined) queryParams.append('ownerId', params.ownerId.toString()); if (params.includeAllPublic !== undefined) queryParams.append('includeAllPublic', params.includeAllPublic.toString()); - // 最终URL调试日志 - const url = `${BASE_URL}/picture/get_pictures?${queryParams.toString()}`; - console.log("发送API请求:", url); + const url = `/picture/get_pictures?${queryParams.toString()}`; try { - const token = localStorage.getItem('token'); - const headers: Record = { - 'Content-Type': 'application/json', - }; - if (token) { - headers['Authorization'] = `Bearer ${token}`; + const result = await fetchApi>(url); + + if (result.success) { + return result as unknown as PaginatedResult; + } else { + console.error('获取图片列表失败:', result.message); + return { + success: false, + message: result.message || '获取图片列表失败', + data: [], + page: params.page || 1, + pageSize: params.pageSize || 10, + totalCount: 0, + totalPages: 0, + code: result.code || 500, + }; } - - const response = await fetch(url, { headers }); - const data = await response.json(); - - // 添加结果日志 - console.log("API 响应结果:", { - success: data.success, - totalCount: data.totalCount, - resultsCount: data.data?.length || 0 - }); - - return data as PaginatedResult; } catch (error) { - console.error('获取图片列表失败:', error); + console.error('获取图片列表时发生意外错误:', error); return { success: false, message: '网络请求失败,请检查您的网络连接', data: [], - page: 1, - pageSize: 10, + page: params.page || 1, + pageSize: params.pageSize || 10, totalCount: 0, totalPages: 0, code: 500, @@ -85,27 +178,33 @@ export async function unfavoritePicture(pictureId: number): Promise> { try { - const token = localStorage.getItem('token'); - const headers: Record = { - 'Content-Type': 'application/json', - }; - if (token) { - headers['Authorization'] = `Bearer ${token}`; + const url = `/picture/favorites?page=${page}&pageSize=${pageSize}`; + // 使用 fetchApi 替换原生 fetch + const result = await fetchApi>(url); + + if (result.success) { + return result as unknown as PaginatedResult; + } else { + console.error('获取收藏图片失败:', result.message); + return { + success: false, + message: result.message || '获取收藏图片失败', + data: [], + page: page, + pageSize: pageSize, + totalCount: 0, + totalPages: 0, + code: result.code || 500, + }; } - - const url = `${BASE_URL}/picture/favorites?page=${page}&pageSize=${pageSize}`; - const response = await fetch(url, { headers }); - const data = await response.json(); - - return data as PaginatedResult; } catch (error) { - console.error('获取收藏图片失败:', error); + console.error('获取收藏图片时发生意外错误:', error); return { success: false, message: '网络请求失败,请检查您的网络连接', data: [], - page: 1, - pageSize: 10, + page: page, + pageSize: pageSize, totalCount: 0, totalPages: 0, code: 500, diff --git a/Web/src/api/pictureManagementApi.ts b/Web/src/api/pictureManagementApi.ts index be3effc..c1d4b21 100644 --- a/Web/src/api/pictureManagementApi.ts +++ b/Web/src/api/pictureManagementApi.ts @@ -1,10 +1,7 @@ -import { fetchApi } from './fetchClient'; -import { - type BaseResult, - type PaginatedResult, - type PictureResponse, - type BatchDeleteResult -} from './types'; +import { fetchApi, type BaseResult, type PaginatedResult } from './fetchClient'; +import { type PictureResponse } from './pictureApi'; +import { type BatchDeleteResult } from './userManagementApi'; + // 获取图片列表 export const getManagementPictures = async ( diff --git a/Web/src/api/tagApi.ts b/Web/src/api/tagApi.ts index 8b883c0..3daa530 100644 --- a/Web/src/api/tagApi.ts +++ b/Web/src/api/tagApi.ts @@ -1,5 +1,4 @@ -import type { BaseResult, PaginatedResult } from './types'; -import { fetchApi, BASE_URL } from './fetchClient'; +import { fetchApi, type BaseResult, type PaginatedResult } from './fetchClient'; // 标签响应类型 export interface TagResponse { @@ -50,28 +49,31 @@ export async function getFilteredTags(params: FilteredTagsRequest = {}): Promise if (params.sortDirection) queryParams.append('sortDirection', params.sortDirection); try { - const token = localStorage.getItem('token'); - const headers: Record = { - 'Content-Type': 'application/json', - }; - - if (token) { - headers['Authorization'] = `Bearer ${token}`; + const url = `/tag/get_tags?${queryParams.toString()}`; + const result = await fetchApi>(url); + if (result.success) { + return result as unknown as PaginatedResult; + } else { + console.error('获取标签列表失败:', result.message); + return { + success: false, + message: result.message || '获取标签列表失败', + data: [], + page: params.page || 1, + pageSize: params.pageSize || 10, + totalCount: 0, + totalPages: 0, + code: result.code || 500, + }; } - - const url = `${BASE_URL}/tag/get_tags?${queryParams.toString()}`; - const response = await fetch(url, { headers }); - const data = await response.json(); - - return data as PaginatedResult; } catch (error) { - console.error('获取标签列表失败:', error); + console.error('获取标签列表时发生意外错误:', error); return { success: false, message: '网络请求失败,请检查您的网络连接', data: [], - page: 1, - pageSize: 10, + page: params.page || 1, + pageSize: params.pageSize || 10, totalCount: 0, totalPages: 0, code: 500, diff --git a/Web/src/api/types.ts b/Web/src/api/types.ts deleted file mode 100644 index 76ba1ea..0000000 --- a/Web/src/api/types.ts +++ /dev/null @@ -1,370 +0,0 @@ -// API响应的基础结构 -export interface BaseResult { - success: boolean; - message: string; - data?: T; - code: number; -} - -// 分页结果通用结构 -export interface PaginatedResult { - success: boolean; - message: string; - data: T[]; - page: number; - pageSize: number; - totalCount: number; - totalPages: number; - code: number; -} - -// 登录请求参数 -export interface LoginRequest { - email: string; - password: string; -} - -// 注册请求参数 -export interface RegisterRequest { - username: string; - email: string; - password: string; -} - -// 用户信息 -export interface UserProfile { - id: number; - userName: string; - email: string; - roleName: string; -} - -// 认证响应 -export interface AuthResponse { - token: string; - user: UserProfile; -} - -// 图片请求参数 -export interface FilteredPicturesRequest { - page?: number; - pageSize?: number; - searchQuery?: string; - tags?: string; - startDate?: string; - endDate?: string; - userId?: number; - sortBy?: string; - onlyWithGps?: boolean; - useVectorSearch?: boolean; - similarityThreshold?: number; - excludeAlbumId?: number; - albumId?: number; - onlyFavorites?: boolean; - ownerId?: number; - includeAllPublic?: boolean; -} - -// 图片响应数据 -export interface PictureResponse { - id: number; - name: string; - path: string; - thumbnailPath: string; - description: string; - takenAt?: Date; - createdAt: Date; - exifInfo?: any; - tags?: string[]; - userId: number; - username?: string; - isFavorited: boolean; - favoriteCount: number; - permission: number; - albumId?: number; - albumName?: string; - processingStatus: ProcessingStatus; - processingError?: string; - processingProgress: number; -} - -// 收藏请求 -export interface FavoriteRequest { - pictureId: number; -} - -// 上传队列中的文件项 -export interface UploadFile { - id: string; // 本地ID,用于跟踪状态 - file: File; // 原始文件 - status: 'pending' | 'uploading' | 'success' | 'error'; // 上传状态 - percent: number; // 上传进度百分比 0-100 - error?: string; // 错误信息 - response?: PictureResponse; // 上传成功后的响应 -} - -// 图片格式类型 -export type ImageFormat = 0 | 1 | 2 | 3; - -// 添加常量对象提供运行时值 -export const ImageFormat = { - Original: 0 as ImageFormat, - Jpeg: 1 as ImageFormat, - Png: 2 as ImageFormat, - WebP: 3 as ImageFormat -}; - -// 上传图片参数 -export interface UploadPictureParams { - permission?: number; - albumId?: number; - convertToFormat?: ImageFormat; - quality?: number; - onProgress?: (percent: number) => void; -} - -// 相册响应数据 -export interface AlbumResponse { - id: number; - name: string; - description: string; - coverImageUrl?: string; - pictureCount: number; - userId: number; - username?: string; - createdAt: Date; - updatedAt: Date; -} - -// 创建相册请求 -export interface CreateAlbumRequest { - name: string; - description: string; -} - -// 更新相册请求 -export interface UpdateAlbumRequest { - id: number; - name: string; - description: string; -} - -// 相册图片操作请求 -export interface AlbumPictureRequest { - albumId: number; - pictureId: number; -} - -// 批量添加图片到相册请求 -export interface AlbumPicturesRequest { - albumId: number; - pictureIds: number[]; -} - -// 删除多张图片请求 -export interface DeleteMultiplePicturesRequest { - pictureIds: number[]; -} - -// 将类型定义改为枚举,这样既可以作为类型也可以作为值使用 -export type ProcessingStatus = 'Pending' | 'Processing' | 'Completed' | 'Failed'; - -// 添加常量对象提供运行时值 -export const ProcessingStatus = { - Pending: 'Pending' as ProcessingStatus, - Processing: 'Processing' as ProcessingStatus, - Completed: 'Completed' as ProcessingStatus, - Failed: 'Failed' as ProcessingStatus -}; - -// 图片处理任务 -export interface PictureProcessingTask { - pictureId: number; - taskId: string; - pictureName: string; - status: ProcessingStatus; - progress: number; // 0-100 - error?: string; - createdAt: Date; - completedAt?: Date; -} - -// 配置响应数据 -export interface ConfigResponse { - id: number; - key: string; - value: string; - description: string; - isSecret: boolean; - createdAt: Date; - updatedAt?: Date; -} - -export interface SetConfigRequest { - key: string; - value: string; - description?: string; -} - -export type UserRole = "Administrator" | "User" | ""; - -export const UserRole = { - Administrator: "Administrator" as UserRole, - User: "User" as UserRole, - Guest: "" as UserRole -}; - -export interface UpdateUserRequest { - userName?: string; - email?: string; - currentPassword?: string; - newPassword?: string; -} - -export interface UpdatePictureRequest { - id: number; - name?: string; - description?: string; - tags?: string[]; -} - -// 用户管理相关类型 -export interface UserResponse { - id: number; - userName: string; - email: string; - role: string; - createdAt: Date; - lastLoginAt?: Date; -} - -// 管理员创建用户请求 -export interface CreateUserRequest { - userName: string; - email: string; - password: string; - role: string; -} - -// 管理员更新用户请求 -export interface AdminUpdateUserRequest { - id: number; - userName?: string; - email?: string; - role?: string; -} - -// 批量删除结果 -export interface BatchDeleteResult { - successCount: number; - failedCount: number; - failedIds?: number[]; -} - -export type VectorDbType = "InMemory" | "Qdrant"; - -export const VectorDbType = { - InMemory: "InMemory" as VectorDbType, - Qdrant: "Qdrant" as VectorDbType, -}; - -export interface VectorDbInfo { - type: string; -} - -export type BindType = 0 | 1; - -export const BindType = { - GitHub: 0 as BindType, - LinuxDo: 1 as BindType, -}; - -export interface BindAccountRequest { - email: string; - password: string; - bindType: BindType; - thirdPartyUserId: string; -} - -// 用户筛选请求参数 -export interface UserFilterRequest { - page?: number; - pageSize?: number; - searchQuery?: string; - role?: string; - startDate?: string; - endDate?: string; -} - -// 用户统计信息 -export interface UserStatistics { - totalPictures: number; - totalAlbums: number; - totalFavorites: number; - favoriteReceivedCount: number; - diskUsageMB: number; - accountAgeDays: number; -} - -// 用户详情响应 -export interface UserDetailResponse { - id: number; - userName: string; - email: string; - role: string; - createdAt: Date; - statistics: UserStatistics; -} - -// 日志级别枚举 -export type LogLevel = 'Trace' | 'Debug' | 'Information' | 'Warning' | 'Error' | 'Critical'; - -export const LogLevel = { - Trace: 'Trace' as LogLevel, - Debug: 'Debug' as LogLevel, - Information: 'Information' as LogLevel, - Warning: 'Warning' as LogLevel, - Error: 'Error' as LogLevel, - Critical: 'Critical' as LogLevel -}; - -// 日志响应数据 -export interface LogResponse { - id: number; - level: LogLevel | number; // 支持数字和字符串两种形式 - message: string; - category: string; - eventId?: number; - timestamp: Date; - exception?: string; - requestPath?: string; - requestMethod?: string; - statusCode?: number; - ipAddress?: string; - userId?: string; - properties?: string; -} - -// 日志筛选请求参数 -export interface LogFilterRequest { - page?: number; - pageSize?: number; - searchQuery?: string; - level?: LogLevel | number; // 支持数字和字符串两种形式 - startDate?: string; - endDate?: string; -} - -// 清空日志请求 -export interface ClearLogsRequest { - clearAll?: boolean; - beforeDate?: Date; -} - -// 日志统计信息 -export interface LogStatistics { - totalCount: number; - todayCount: number; - errorCount: number; - warningCount: number; -} diff --git a/Web/src/api/userManagementApi.ts b/Web/src/api/userManagementApi.ts index 59ede97..37a07aa 100644 --- a/Web/src/api/userManagementApi.ts +++ b/Web/src/api/userManagementApi.ts @@ -1,14 +1,75 @@ -import { fetchApi } from './fetchClient'; -import { - type BaseResult, - type PaginatedResult, - type UserResponse, - type CreateUserRequest, - type AdminUpdateUserRequest, - type BatchDeleteResult, - type UserFilterRequest, - type UserDetailResponse -} from './types'; +import { fetchApi, type BaseResult, type PaginatedResult } from './fetchClient'; + +export type UserRole = "Administrator" | "User" | ""; + +export const UserRole = { + Administrator: "Administrator" as UserRole, + User: "User" as UserRole, + Guest: "" as UserRole +}; + +// 用户管理相关类型 +export interface UserResponse { + id: number; + userName: string; + email: string; + role: string; + createdAt: Date; + lastLoginAt?: Date; +} + +// 管理员创建用户请求 +export interface CreateUserRequest { + userName: string; + email: string; + password: string; + role: string; +} + +// 管理员更新用户请求 +export interface AdminUpdateUserRequest { + id: number; + userName?: string; + email?: string; + role?: string; +} + +// 批量删除结果 +export interface BatchDeleteResult { + successCount: number; + failedCount: number; + failedIds?: number[]; +} + +// 用户筛选请求参数 +export interface UserFilterRequest { + page?: number; + pageSize?: number; + searchQuery?: string; + role?: string; + startDate?: string; + endDate?: string; +} + +// 用户统计信息 +export interface UserStatistics { + totalPictures: number; + totalAlbums: number; + totalFavorites: number; + favoriteReceivedCount: number; + diskUsageMB: number; + accountAgeDays: number; +} + +// 用户详情响应 +export interface UserDetailResponse { + id: number; + userName: string; + email: string; + role: string; + createdAt: Date; + statistics: UserStatistics; +} // 获取用户列表 export const getUsers = async ( diff --git a/Web/src/api/vectorDbApi.ts b/Web/src/api/vectorDbApi.ts index bb1cfab..f159e36 100644 --- a/Web/src/api/vectorDbApi.ts +++ b/Web/src/api/vectorDbApi.ts @@ -1,5 +1,15 @@ -import { type BaseResult, type VectorDbInfo, VectorDbType } from './types'; -import { fetchApi } from './fetchClient'; +import { fetchApi, type BaseResult } from './fetchClient'; + +export type VectorDbType = "InMemory" | "Qdrant"; + +export const VectorDbType = { + InMemory: "InMemory" as VectorDbType, + Qdrant: "Qdrant" as VectorDbType, +}; + +export interface VectorDbInfo { + type: string; +} // 获取当前向量数据库类型 export const getCurrentVectorDb = async (): Promise> => { diff --git a/Web/src/auth/AuthContext.tsx b/Web/src/auth/AuthContext.tsx index 01a81bf..64c0f6f 100644 --- a/Web/src/auth/AuthContext.tsx +++ b/Web/src/auth/AuthContext.tsx @@ -1,7 +1,7 @@ import React, { createContext, useState, useEffect, useContext, useCallback } from 'react'; import { getCurrentUser, isAuthenticated, clearAuthData, getStoredUser } from '../api/index'; -import type { UserProfile } from '../api/types'; -import { UserRole } from '../api/types'; +import type { UserProfile } from '../api'; +import { UserRole } from '../api'; interface AuthContextType { user: UserProfile | null; diff --git a/Web/src/components/TaskProgressBar.tsx b/Web/src/components/TaskProgressBar.tsx index 839b907..9fa7202 100644 --- a/Web/src/components/TaskProgressBar.tsx +++ b/Web/src/components/TaskProgressBar.tsx @@ -6,7 +6,7 @@ import { CheckCircleOutlined, CloseCircleOutlined } from '@ant-design/icons'; -import { ProcessingStatus } from '../api/types'; +import { ProcessingStatus } from '../api'; interface TaskProgressBarProps { status: ProcessingStatus; diff --git a/Web/src/components/image/ImageInfo.tsx b/Web/src/components/image/ImageInfo.tsx index d1aff60..a9ecd8a 100644 --- a/Web/src/components/image/ImageInfo.tsx +++ b/Web/src/components/image/ImageInfo.tsx @@ -1,7 +1,7 @@ import React, { useState } from 'react'; import { Divider } from 'antd'; import { CloseOutlined, DownOutlined, UpOutlined } from '@ant-design/icons'; -import type { PictureResponse } from '../../api/types'; +import type { PictureResponse } from '../../api'; import './ImageViewer.css'; interface ImageInfoProps { diff --git a/Web/src/components/image/ImageViewer.tsx b/Web/src/components/image/ImageViewer.tsx index 5b77a6b..23256db 100644 --- a/Web/src/components/image/ImageViewer.tsx +++ b/Web/src/components/image/ImageViewer.tsx @@ -6,7 +6,7 @@ import { RotateRightOutlined, HeartOutlined, HeartFilled, DownloadOutlined, ShareAltOutlined, FolderAddOutlined } from '@ant-design/icons'; -import type { PictureResponse, AlbumResponse } from '../../api/types'; +import type { PictureResponse, AlbumResponse } from '../../api'; import { getAlbums, addPicturesToAlbum, favoritePicture, unfavoritePicture } from '../../api'; import ImageInfo from './ImageInfo'; import ShareImageDialog from './ShareImageDialog'; diff --git a/Web/src/components/image/ShareImageDialog.tsx b/Web/src/components/image/ShareImageDialog.tsx index 7396425..00fb9a0 100644 --- a/Web/src/components/image/ShareImageDialog.tsx +++ b/Web/src/components/image/ShareImageDialog.tsx @@ -1,7 +1,7 @@ import React, { useState, useRef } from 'react'; import { Modal, Tabs, Input, Button, message, Radio, Space, Typography } from 'antd'; import { CopyOutlined, CheckOutlined } from '@ant-design/icons'; -import type { PictureResponse } from '../../api/types'; +import type { PictureResponse } from '../../api'; import './ShareImageDialog.css'; const { Text } = Typography; diff --git a/Web/src/layouts/AdminLayout.tsx b/Web/src/layouts/AdminLayout.tsx index cc13a21..02b5cb8 100644 --- a/Web/src/layouts/AdminLayout.tsx +++ b/Web/src/layouts/AdminLayout.tsx @@ -7,7 +7,7 @@ import { useAuth } from '../auth/AuthContext'; import Sidebar from './components/Sidebar'; import Header from './components/Header'; import Footer from './components/Footer'; -import { UserRole } from '../api/types'; +import { UserRole } from '../api'; import { getAdminRoutes, type RouteConfig } from '../routes'; const { Content } = Layout; diff --git a/Web/src/pages/admin/dashboard/Index.tsx b/Web/src/pages/admin/dashboard/Index.tsx index d42c816..78b80dd 100644 --- a/Web/src/pages/admin/dashboard/Index.tsx +++ b/Web/src/pages/admin/dashboard/Index.tsx @@ -12,7 +12,7 @@ import type { ColumnsType } from 'antd/es/table'; import { useOutletContext } from 'react-router'; import { useNavigate } from 'react-router'; import { getUsers, getManagementPictures } from '../../../api'; -import type { UserResponse, PictureResponse } from '../../../api/types'; +import type { UserResponse, PictureResponse } from '../../../api'; const { Title, Text } = Typography; diff --git a/Web/src/pages/admin/log/Index.tsx b/Web/src/pages/admin/log/Index.tsx index 9e9d23b..c1df80c 100644 --- a/Web/src/pages/admin/log/Index.tsx +++ b/Web/src/pages/admin/log/Index.tsx @@ -38,7 +38,7 @@ import {useOutletContext} from 'react-router'; import dayjs from 'dayjs'; import type {Dayjs} from 'dayjs'; import {getLogs, deleteLog, batchDeleteLogs, clearLogs, getLogById, getLogStatistics} from '../../../api'; -import type {LogResponse, LogLevel, LogFilterRequest, LogStatistics} from '../../../api/types'; +import type {LogResponse, LogLevel, LogFilterRequest, LogStatistics} from '../../../api'; const {Title, Text, Paragraph} = Typography; const {RangePicker} = DatePicker; diff --git a/Web/src/pages/admin/pictures/Index.tsx b/Web/src/pages/admin/pictures/Index.tsx index b57fed6..bbcc545 100644 --- a/Web/src/pages/admin/pictures/Index.tsx +++ b/Web/src/pages/admin/pictures/Index.tsx @@ -13,7 +13,7 @@ import { getManagementPictures, deleteManagementPicture, batchDeleteManagementPictures, getUsers } from '../../../api'; -import type { PictureResponse } from '../../../api/types'; +import type { PictureResponse } from '../../../api'; import { useOutletContext } from 'react-router'; import type { Breakpoint } from 'antd'; diff --git a/Web/src/pages/admin/system/VectorDbConfig.tsx b/Web/src/pages/admin/system/VectorDbConfig.tsx index d1454e7..f3d028b 100644 --- a/Web/src/pages/admin/system/VectorDbConfig.tsx +++ b/Web/src/pages/admin/system/VectorDbConfig.tsx @@ -2,7 +2,7 @@ import React, { useState, useEffect } from 'react'; import { Card, Radio, Button, message, Spin, Space, Typography, notification, Form, Input, Modal } from 'antd'; import { DatabaseOutlined, SyncOutlined, CheckCircleOutlined, InfoCircleOutlined, SaveOutlined, DeleteOutlined, ReloadOutlined } from '@ant-design/icons'; import { getCurrentVectorDb, switchVectorDb, setConfig, clearVectors, rebuildVectors } from '../../../api'; -import { VectorDbType } from '../../../api/types'; +import { VectorDbType } from '../../../api'; const { Title, Paragraph } = Typography; diff --git a/Web/src/pages/admin/users/Index.tsx b/Web/src/pages/admin/users/Index.tsx index 0132c0f..c8a47c1 100644 --- a/Web/src/pages/admin/users/Index.tsx +++ b/Web/src/pages/admin/users/Index.tsx @@ -13,7 +13,7 @@ import { import { getUsers, deleteUser, createUser, updateUser, batchDeleteUsers, UserRole } from '../../../api'; -import type { UserResponse, CreateUserRequest, AdminUpdateUserRequest, UserFilterRequest } from '../../../api/types'; +import type { UserResponse, CreateUserRequest, AdminUpdateUserRequest, UserFilterRequest } from '../../../api'; import { useOutletContext } from 'react-router'; import { useNavigate } from 'react-router'; import type { Breakpoint } from 'antd'; diff --git a/Web/src/pages/admin/users/UserDetail.tsx b/Web/src/pages/admin/users/UserDetail.tsx index 348f800..197cacf 100644 --- a/Web/src/pages/admin/users/UserDetail.tsx +++ b/Web/src/pages/admin/users/UserDetail.tsx @@ -11,7 +11,7 @@ import { } from '@ant-design/icons'; import { useParams, useNavigate } from 'react-router'; import { getUserDetail } from '../../../api'; -import type { UserDetailResponse } from '../../../api/types'; +import type { UserDetailResponse } from '../../../api'; import UserAvatar from '../../../components/UserAvatar'; const { Title, Text } = Typography; diff --git a/Web/src/pages/anonymous/Index.tsx b/Web/src/pages/anonymous/Index.tsx index 2458fe2..5cf4490 100644 --- a/Web/src/pages/anonymous/Index.tsx +++ b/Web/src/pages/anonymous/Index.tsx @@ -24,7 +24,7 @@ import { Link } from 'react-router'; import ShareImageDialog from '../../components/image/ShareImageDialog'; import { uploadPicture } from '../../api/pictureApi'; -import type { PictureResponse } from '../../api/types'; +import type { PictureResponse } from '../../api'; const { Title, Text } = Typography; const { Dragger } = Upload; diff --git a/Web/src/pages/backgroundTasks/Index.tsx b/Web/src/pages/backgroundTasks/Index.tsx index 13145a0..4a1b7cd 100644 --- a/Web/src/pages/backgroundTasks/Index.tsx +++ b/Web/src/pages/backgroundTasks/Index.tsx @@ -2,7 +2,7 @@ import React, { useState, useEffect, useCallback } from 'react'; import { Typography, Table, Card, Tag, Space, Button, Empty, message, Modal } from 'antd'; import { SyncOutlined, EyeOutlined } from '@ant-design/icons'; import { getUserTasks } from '../../api'; -import { type PictureProcessingTask, ProcessingStatus } from '../../api/types'; +import { type PictureProcessingTask, ProcessingStatus } from '../../api'; import TaskProgressBar from '../../components/TaskProgressBar'; import dayjs from 'dayjs'; import { Link } from 'react-router'; diff --git a/Web/src/pages/pixHub/Index.tsx b/Web/src/pages/pixHub/Index.tsx index 7268260..1cf6170 100644 --- a/Web/src/pages/pixHub/Index.tsx +++ b/Web/src/pages/pixHub/Index.tsx @@ -17,7 +17,7 @@ import { } from '@ant-design/icons'; import ImageGrid from '../../components/image/ImageGrid/ImageGrid'; -import type { PictureResponse } from '../../api/types'; +import type { PictureResponse } from '../../api'; import { getFilteredTags } from '../../api/tagApi'; import useIsMobile from '../../hooks/useIsMobile';