diff --git a/HISTORY.md b/HISTORY.md index d16fc32..692f97c 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -3,5 +3,6 @@ 迁移管理页面,在正式环境中,需要验证env中配置的密码参数才能打开 2025.05.13 0.1.0 -首页添加了迁移管理入口按钮, 无需登录即可访问 -打开迁移管理页面时,将迁移历史读取出来 \ No newline at end of file +将admin api.ts 拆开 +打开迁移管理页面时,将迁移历史读取出来 +首页添加了迁移管理入口按钮, 无需登录即可访问 \ No newline at end of file diff --git a/client/admin/api.ts b/client/admin/api.ts deleted file mode 100644 index 852a365..0000000 --- a/client/admin/api.ts +++ /dev/null @@ -1,782 +0,0 @@ -import axios from 'axios'; -import { getGlobalConfig } from './utils.ts'; -import type { MinioUploadPolicy, OSSUploadPolicy } from '@d8d-appcontainer/types'; -import 'dayjs/locale/zh-cn'; -import type { - User, FileLibrary, FileCategory, ThemeSettings, - SystemSetting, SystemSettingGroupData, - LoginLocation, LoginLocationDetail, - Message, UserMessage, KnowInfo -} from '../share/types.ts'; - - - -// 定义API基础URL -const API_BASE_URL = '/api'; - -// 获取OSS完整URL -export const getOssUrl = (path: string): string => { - // 获取全局配置中的OSS_HOST,如果不存在使用默认值 - const ossHost = getGlobalConfig('OSS_BASE_URL') || ''; - // 确保path不以/开头 - const ossPath = path.startsWith('/') ? path.substring(1) : path; - return `${ossHost}/${ossPath}`; -}; - -// =================== -// Auth API 定义部分 -// =================== - -// 定义API返回数据类型 -interface AuthLoginResponse { - message: string; - token: string; - refreshToken?: string; - user: User; -} - -interface AuthResponse { - message: string; - [key: string]: any; -} - -// 定义Auth API接口类型 -interface AuthAPIType { - login: (username: string, password: string, latitude?: number, longitude?: number) => Promise; - register: (username: string, email: string, password: string) => Promise; - logout: () => Promise; - getCurrentUser: () => Promise; - updateUser: (userId: number, userData: Partial) => Promise; - changePassword: (oldPassword: string, newPassword: string) => Promise; - requestPasswordReset: (email: string) => Promise; - resetPassword: (token: string, newPassword: string) => Promise; -} - - -// Auth相关API -export const AuthAPI: AuthAPIType = { - // 登录API - login: async (username: string, password: string, latitude?: number, longitude?: number) => { - try { - const response = await axios.post(`${API_BASE_URL}/auth/login`, { - username, - password, - latitude, - longitude - }); - return response.data; - } catch (error) { - throw error; - } - }, - - // 注册API - register: async (username: string, email: string, password: string) => { - try { - const response = await axios.post(`${API_BASE_URL}/auth/register`, { username, email, password }); - return response.data; - } catch (error) { - throw error; - } - }, - - // 登出API - logout: async () => { - try { - const response = await axios.post(`${API_BASE_URL}/auth/logout`); - return response.data; - } catch (error) { - throw error; - } - }, - - // 获取当前用户信息 - getCurrentUser: async () => { - try { - const response = await axios.get(`${API_BASE_URL}/auth/me`); - return response.data; - } catch (error) { - throw error; - } - }, - - // 更新用户信息 - updateUser: async (userId: number, userData: Partial) => { - try { - const response = await axios.put(`${API_BASE_URL}/auth/users/${userId}`, userData); - return response.data; - } catch (error) { - throw error; - } - }, - - // 修改密码 - changePassword: async (oldPassword: string, newPassword: string) => { - try { - const response = await axios.post(`${API_BASE_URL}/auth/change-password`, { oldPassword, newPassword }); - return response.data; - } catch (error) { - throw error; - } - }, - - // 请求重置密码 - requestPasswordReset: async (email: string) => { - try { - const response = await axios.post(`${API_BASE_URL}/auth/request-password-reset`, { email }); - return response.data; - } catch (error) { - throw error; - } - }, - - // 重置密码 - resetPassword: async (token: string, newPassword: string) => { - try { - const response = await axios.post(`${API_BASE_URL}/auth/reset-password`, { token, newPassword }); - return response.data; - } catch (error) { - throw error; - } - } -}; - -// 为UserAPI添加的接口响应类型 -interface UsersResponse { - data: User[]; - pagination: { - total: number; - current: number; - pageSize: number; - totalPages: number; - }; -} - -interface UserResponse { - data: User; - message?: string; -} - -interface UserCreateResponse { - message: string; - data: User; -} - -interface UserUpdateResponse { - message: string; - data: User; -} - -interface UserDeleteResponse { - message: string; - id: number; -} - -// 用户管理API -export const UserAPI = { - // 获取用户列表 - getUsers: async (params?: { page?: number, limit?: number, search?: string }): Promise => { - try { - const response = await axios.get(`${API_BASE_URL}/users`, { params }); - return response.data; - } catch (error) { - throw error; - } - }, - - // 获取单个用户详情 - getUser: async (userId: number): Promise => { - try { - const response = await axios.get(`${API_BASE_URL}/users/${userId}`); - return response.data; - } catch (error) { - throw error; - } - }, - - // 创建用户 - createUser: async (userData: Partial): Promise => { - try { - const response = await axios.post(`${API_BASE_URL}/users`, userData); - return response.data; - } catch (error) { - throw error; - } - }, - - // 更新用户信息 - updateUser: async (userId: number, userData: Partial): Promise => { - try { - const response = await axios.put(`${API_BASE_URL}/users/${userId}`, userData); - return response.data; - } catch (error) { - throw error; - } - }, - - // 删除用户 - deleteUser: async (userId: number): Promise => { - try { - const response = await axios.delete(`${API_BASE_URL}/users/${userId}`); - return response.data; - } catch (error) { - throw error; - } - } -}; - - -// 定义文件相关接口类型 -interface FileUploadPolicyResponse { - message: string; - data: MinioUploadPolicy | OSSUploadPolicy; -} - -interface FileListResponse { - message: string; - data: { - list: FileLibrary[]; - pagination: { - current: number; - pageSize: number; - total: number; - }; - }; -} - -interface FileSaveResponse { - message: string; - data: FileLibrary; -} - -interface FileInfoResponse { - message: string; - data: FileLibrary; -} - -interface FileDeleteResponse { - message: string; -} - - -interface FileCategoryListResponse { - data: FileCategory[]; - total: number; - page: number; - pageSize: number; -} - -interface FileCategoryCreateResponse { - message: string; - data: FileCategory; -} - -interface FileCategoryUpdateResponse { - message: string; - data: FileCategory; -} - -interface FileCategoryDeleteResponse { - message: string; -} - -// 文件API接口定义 -export const FileAPI = { - // 获取文件上传策略 - getUploadPolicy: async (filename: string, prefix: string = 'uploads/', maxSize: number = 10 * 1024 * 1024): Promise => { - try { - const response = await axios.get(`${API_BASE_URL}/upload/policy`, { - params: { filename, prefix, maxSize } - }); - return response.data; - } catch (error) { - throw error; - } - }, - - // 保存文件信息 - saveFileInfo: async (fileData: Partial): Promise => { - try { - const response = await axios.post(`${API_BASE_URL}/upload/save`, fileData); - return response.data; - } catch (error) { - throw error; - } - }, - - // 获取文件列表 - getFileList: async (params?: { - page?: number, - pageSize?: number, - category_id?: number, - fileType?: string, - keyword?: string - }): Promise => { - try { - const response = await axios.get(`${API_BASE_URL}/upload/list`, { params }); - return response.data; - } catch (error) { - throw error; - } - }, - - // 获取单个文件信息 - getFileInfo: async (id: number): Promise => { - try { - const response = await axios.get(`${API_BASE_URL}/upload/${id}`); - return response.data; - } catch (error) { - throw error; - } - }, - - // 更新文件下载计数 - updateDownloadCount: async (id: number): Promise => { - try { - const response = await axios.post(`${API_BASE_URL}/upload/${id}/download`); - return response.data; - } catch (error) { - throw error; - } - }, - - // 删除文件 - deleteFile: async (id: number): Promise => { - try { - const response = await axios.delete(`${API_BASE_URL}/upload/${id}`); - return response.data; - } catch (error) { - throw error; - } - }, - - // 获取文件分类列表 - getCategories: async (params?: { - page?: number, - pageSize?: number, - search?: string - }): Promise => { - try { - const response = await axios.get(`${API_BASE_URL}/file-categories`, { params }); - return response.data; - } catch (error) { - throw error; - } - }, - - // 创建文件分类 - createCategory: async (data: Partial): Promise => { - try { - const response = await axios.post(`${API_BASE_URL}/file-categories`, data); - return response.data; - } catch (error) { - throw error; - } - }, - - // 更新文件分类 - updateCategory: async (id: number, data: Partial): Promise => { - try { - const response = await axios.put(`${API_BASE_URL}/file-categories/${id}`, data); - return response.data; - } catch (error) { - throw error; - } - }, - - // 删除文件分类 - deleteCategory: async (id: number): Promise => { - try { - const response = await axios.delete(`${API_BASE_URL}/file-categories/${id}`); - return response.data; - } catch (error) { - throw error; - } - } -}; - -// Theme API 响应类型 -export interface ThemeSettingsResponse { - message: string; - data: ThemeSettings; -} - -// Theme API 定义 -export const ThemeAPI = { - // 获取主题设置 - getThemeSettings: async (): Promise => { - try { - const response = await axios.get(`${API_BASE_URL}/theme`); - return response.data.data; - } catch (error) { - throw error; - } - }, - - // 更新主题设置 - updateThemeSettings: async (themeData: Partial): Promise => { - try { - const response = await axios.put(`${API_BASE_URL}/theme`, themeData); - return response.data.data; - } catch (error) { - throw error; - } - }, - - // 重置主题设置 - resetThemeSettings: async (): Promise => { - try { - const response = await axios.post(`${API_BASE_URL}/theme/reset`); - return response.data.data; - } catch (error) { - throw error; - } - } -}; - -// 图表数据API接口类型 -interface ChartDataResponse { - message: string; - data: T; -} - -interface UserActivityData { - date: string; - count: number; -} - -interface FileUploadsData { - month: string; - count: number; -} - -interface FileTypesData { - type: string; - value: number; -} - -interface DashboardOverviewData { - userCount: number; - fileCount: number; - articleCount: number; - todayLoginCount: number; -} - -// 图表数据API -export const ChartAPI = { - // 获取用户活跃度数据 - getUserActivity: async (): Promise> => { - try { - const response = await axios.get(`${API_BASE_URL}/charts/user-activity`); - return response.data; - } catch (error) { - throw error; - } - }, - - // 获取文件上传统计数据 - getFileUploads: async (): Promise> => { - try { - const response = await axios.get(`${API_BASE_URL}/charts/file-uploads`); - return response.data; - } catch (error) { - throw error; - } - }, - - // 获取文件类型分布数据 - getFileTypes: async (): Promise> => { - try { - const response = await axios.get(`${API_BASE_URL}/charts/file-types`); - return response.data; - } catch (error) { - throw error; - } - }, - - // 获取仪表盘概览数据 - getDashboardOverview: async (): Promise> => { - try { - const response = await axios.get(`${API_BASE_URL}/charts/dashboard-overview`); - return response.data; - } catch (error) { - throw error; - } - } -}; - -// 消息API接口类型 -interface MessagesResponse { - data: UserMessage[]; - pagination: { - total: number; - current: number; - pageSize: number; - totalPages: number; - }; -} - -interface MessageResponse { - data: Message; - message?: string; -} - -interface MessageCountResponse { - count: number; -} - -// 消息API -export const MessageAPI = { - // 获取消息列表 - getMessages: async (params?: { - page?: number, - pageSize?: number, - type?: string, - status?: string, - search?: string - }): Promise => { - try { - const response = await axios.get(`${API_BASE_URL}/messages`, { params }); - return response.data; - } catch (error) { - throw error; - } - }, - - // 发送消息 - sendMessage: async (data: { - title: string, - content: string, - type: string, - receiver_ids: number[] - }): Promise => { - try { - const response = await axios.post(`${API_BASE_URL}/messages`, data); - return response.data; - } catch (error) { - throw error; - } - }, - - // 获取未读消息数 - getUnreadCount: async (): Promise => { - try { - const response = await axios.get(`${API_BASE_URL}/messages/count/unread`); - return response.data; - } catch (error) { - throw error; - } - }, - - // 标记消息为已读 - markAsRead: async (id: number): Promise => { - try { - const response = await axios.post(`${API_BASE_URL}/messages/${id}/read`); - return response.data; - } catch (error) { - throw error; - } - }, - - // 删除消息 - deleteMessage: async (id: number): Promise => { - try { - const response = await axios.delete(`${API_BASE_URL}/messages/${id}`); - return response.data; - } catch (error) { - throw error; - } - } -}; - -// 地图相关API的接口类型定义 -export interface LoginLocationResponse { - message: string; - data: LoginLocation[]; -} - -export interface LoginLocationDetailResponse { - message: string; - data: LoginLocationDetail; -} - -export interface LoginLocationUpdateResponse { - message: string; - data: LoginLocationDetail; -} - -// 知识库相关接口类型定义 -export interface KnowInfoListResponse { - data: KnowInfo[]; - pagination: { - total: number; - current: number; - pageSize: number; - totalPages: number; - }; -} - -interface KnowInfoResponse { - data: KnowInfo; - message?: string; -} - -interface KnowInfoCreateResponse { - message: string; - data: KnowInfo; -} - -interface KnowInfoUpdateResponse { - message: string; - data: KnowInfo; -} - -interface KnowInfoDeleteResponse { - message: string; - id: number; -} - - -// 地图相关API -export const MapAPI = { - // 获取地图标记点数据 - getMarkers: async (params?: { - startTime?: string; - endTime?: string; - userId?: number - }): Promise => { - try { - const response = await axios.get(`${API_BASE_URL}/map/markers`, { params }); - return response.data; - } catch (error) { - throw error; - } - }, - - // 获取登录位置详情 - getLocationDetail: async (locationId: number): Promise => { - try { - const response = await axios.get(`${API_BASE_URL}/map/location/${locationId}`); - return response.data; - } catch (error) { - throw error; - } - }, - - // 更新登录位置信息 - updateLocation: async (locationId: number, data: { - longitude: number; - latitude: number; - location_name?: string; - }): Promise => { - try { - const response = await axios.put(`${API_BASE_URL}/map/location/${locationId}`, data); - return response.data; - } catch (error) { - throw error; - } - } -}; - -// 系统设置API -// 知识库API -export const KnowInfoAPI = { - // 获取知识库列表 - getKnowInfos: async (params?: { - page?: number; - pageSize?: number; - title?: string; - category?: string; - tags?: string; - }): Promise => { - try { - const response = await axios.get(`${API_BASE_URL}/know-infos`, { params }); - return response.data; - } catch (error) { - throw error; - } - }, - - // 获取单个知识详情 - getKnowInfo: async (id: number): Promise => { - try { - const response = await axios.get(`${API_BASE_URL}/know-infos/${id}`); - return response.data; - } catch (error) { - throw error; - } - }, - - // 创建知识 - createKnowInfo: async (data: Partial): Promise => { - try { - const response = await axios.post(`${API_BASE_URL}/know-infos`, data); - return response.data; - } catch (error) { - throw error; - } - }, - - // 更新知识 - updateKnowInfo: async (id: number, data: Partial): Promise => { - try { - const response = await axios.put(`${API_BASE_URL}/know-infos/${id}`, data); - return response.data; - } catch (error) { - throw error; - } - }, - - // 删除知识 - deleteKnowInfo: async (id: number): Promise => { - try { - const response = await axios.delete(`${API_BASE_URL}/know-infos/${id}`); - return response.data; - } catch (error) { - throw error; - } - } -}; - -export const SystemAPI = { - // 获取所有系统设置 - getSettings: async (): Promise => { - try { - const response = await axios.get(`${API_BASE_URL}/settings`); - return response.data.data; - } catch (error) { - throw error; - } - }, - - // 获取指定分组的系统设置 - getSettingsByGroup: async (group: string): Promise => { - try { - const response = await axios.get(`${API_BASE_URL}/settings/group/${group}`); - return response.data.data; - } catch (error) { - throw error; - } - }, - - // 更新系统设置 - updateSettings: async (settings: Partial[]): Promise => { - try { - const response = await axios.put(`${API_BASE_URL}/settings`, settings); - return response.data.data; - } catch (error) { - throw error; - } - }, - - // 重置系统设置 - resetSettings: async (): Promise => { - try { - const response = await axios.post(`${API_BASE_URL}/settings/reset`); - return response.data.data; - } catch (error) { - throw error; - } - } -}; - diff --git a/client/admin/api/auth.ts b/client/admin/api/auth.ts new file mode 100644 index 0000000..999fce3 --- /dev/null +++ b/client/admin/api/auth.ts @@ -0,0 +1,106 @@ +import axios from 'axios'; +import type { User } from '../../share/types.ts'; + +const API_BASE_URL = '/api'; + +interface AuthLoginResponse { + message: string; + token: string; + refreshToken?: string; + user: User; +} + +interface AuthResponse { + message: string; + [key: string]: any; +} + +interface AuthAPIType { + login: (username: string, password: string, latitude?: number, longitude?: number) => Promise; + register: (username: string, email: string, password: string) => Promise; + logout: () => Promise; + getCurrentUser: () => Promise; + updateUser: (userId: number, userData: Partial) => Promise; + changePassword: (oldPassword: string, newPassword: string) => Promise; + requestPasswordReset: (email: string) => Promise; + resetPassword: (token: string, newPassword: string) => Promise; +} + +export const AuthAPI: AuthAPIType = { + login: async (username: string, password: string, latitude?: number, longitude?: number) => { + try { + const response = await axios.post(`${API_BASE_URL}/auth/login`, { + username, + password, + latitude, + longitude + }); + return response.data; + } catch (error) { + throw error; + } + }, + + register: async (username: string, email: string, password: string) => { + try { + const response = await axios.post(`${API_BASE_URL}/auth/register`, { username, email, password }); + return response.data; + } catch (error) { + throw error; + } + }, + + logout: async () => { + try { + const response = await axios.post(`${API_BASE_URL}/auth/logout`); + return response.data; + } catch (error) { + throw error; + } + }, + + getCurrentUser: async () => { + try { + const response = await axios.get(`${API_BASE_URL}/auth/me`); + return response.data; + } catch (error) { + throw error; + } + }, + + updateUser: async (userId: number, userData: Partial) => { + try { + const response = await axios.put(`${API_BASE_URL}/auth/users/${userId}`, userData); + return response.data; + } catch (error) { + throw error; + } + }, + + changePassword: async (oldPassword: string, newPassword: string) => { + try { + const response = await axios.post(`${API_BASE_URL}/auth/change-password`, { oldPassword, newPassword }); + return response.data; + } catch (error) { + throw error; + } + }, + + requestPasswordReset: async (email: string) => { + try { + const response = await axios.post(`${API_BASE_URL}/auth/request-password-reset`, { email }); + return response.data; + } catch (error) { + throw error; + } + }, + + resetPassword: async (token: string, newPassword: string) => { + try { + const response = await axios.post(`${API_BASE_URL}/auth/reset-password`, { token, newPassword }); + return response.data; + } catch (error) { + throw error; + } + } +}; \ No newline at end of file diff --git a/client/admin/api/charts.ts b/client/admin/api/charts.ts new file mode 100644 index 0000000..0fa23ce --- /dev/null +++ b/client/admin/api/charts.ts @@ -0,0 +1,68 @@ +import axios from 'axios'; + +const API_BASE_URL = '/api'; + +interface ChartDataResponse { + message: string; + data: T; +} + +interface UserActivityData { + date: string; + count: number; +} + +interface FileUploadsData { + month: string; + count: number; +} + +interface FileTypesData { + type: string; + value: number; +} + +interface DashboardOverviewData { + userCount: number; + fileCount: number; + articleCount: number; + todayLoginCount: number; +} + +export const ChartAPI = { + getUserActivity: async (): Promise> => { + try { + const response = await axios.get(`${API_BASE_URL}/charts/user-activity`); + return response.data; + } catch (error) { + throw error; + } + }, + + getFileUploads: async (): Promise> => { + try { + const response = await axios.get(`${API_BASE_URL}/charts/file-uploads`); + return response.data; + } catch (error) { + throw error; + } + }, + + getFileTypes: async (): Promise> => { + try { + const response = await axios.get(`${API_BASE_URL}/charts/file-types`); + return response.data; + } catch (error) { + throw error; + } + }, + + getDashboardOverview: async (): Promise> => { + try { + const response = await axios.get(`${API_BASE_URL}/charts/dashboard-overview`); + return response.data; + } catch (error) { + throw error; + } + } +}; \ No newline at end of file diff --git a/client/admin/api/files.ts b/client/admin/api/files.ts new file mode 100644 index 0000000..3ab56bd --- /dev/null +++ b/client/admin/api/files.ts @@ -0,0 +1,161 @@ +import axios from 'axios'; +import type { FileLibrary, FileCategory } from '../../share/types.ts'; +import type { MinioUploadPolicy, OSSUploadPolicy } from '@d8d-appcontainer/types'; + +const API_BASE_URL = '/api'; + +interface FileUploadPolicyResponse { + message: string; + data: MinioUploadPolicy | OSSUploadPolicy; +} + +interface FileListResponse { + message: string; + data: { + list: FileLibrary[]; + pagination: { + current: number; + pageSize: number; + total: number; + }; + }; +} + +interface FileSaveResponse { + message: string; + data: FileLibrary; +} + +interface FileInfoResponse { + message: string; + data: FileLibrary; +} + +interface FileDeleteResponse { + message: string; +} + +interface FileCategoryListResponse { + data: FileCategory[]; + total: number; + page: number; + pageSize: number; +} + +interface FileCategoryCreateResponse { + message: string; + data: FileCategory; +} + +interface FileCategoryUpdateResponse { + message: string; + data: FileCategory; +} + +interface FileCategoryDeleteResponse { + message: string; +} + +export const FileAPI = { + getUploadPolicy: async (filename: string, prefix: string = 'uploads/', maxSize: number = 10 * 1024 * 1024): Promise => { + try { + const response = await axios.get(`${API_BASE_URL}/upload/policy`, { + params: { filename, prefix, maxSize } + }); + return response.data; + } catch (error) { + throw error; + } + }, + + saveFileInfo: async (fileData: Partial): Promise => { + try { + const response = await axios.post(`${API_BASE_URL}/upload/save`, fileData); + return response.data; + } catch (error) { + throw error; + } + }, + + getFileList: async (params?: { + page?: number, + pageSize?: number, + category_id?: number, + fileType?: string, + keyword?: string + }): Promise => { + try { + const response = await axios.get(`${API_BASE_URL}/upload/list`, { params }); + return response.data; + } catch (error) { + throw error; + } + }, + + getFileInfo: async (id: number): Promise => { + try { + const response = await axios.get(`${API_BASE_URL}/upload/${id}`); + return response.data; + } catch (error) { + throw error; + } + }, + + updateDownloadCount: async (id: number): Promise => { + try { + const response = await axios.post(`${API_BASE_URL}/upload/${id}/download`); + return response.data; + } catch (error) { + throw error; + } + }, + + deleteFile: async (id: number): Promise => { + try { + const response = await axios.delete(`${API_BASE_URL}/upload/${id}`); + return response.data; + } catch (error) { + throw error; + } + }, + + getCategories: async (params?: { + page?: number, + pageSize?: number, + search?: string + }): Promise => { + try { + const response = await axios.get(`${API_BASE_URL}/file-categories`, { params }); + return response.data; + } catch (error) { + throw error; + } + }, + + createCategory: async (data: Partial): Promise => { + try { + const response = await axios.post(`${API_BASE_URL}/file-categories`, data); + return response.data; + } catch (error) { + throw error; + } + }, + + updateCategory: async (id: number, data: Partial): Promise => { + try { + const response = await axios.put(`${API_BASE_URL}/file-categories/${id}`, data); + return response.data; + } catch (error) { + throw error; + } + }, + + deleteCategory: async (id: number): Promise => { + try { + const response = await axios.delete(`${API_BASE_URL}/file-categories/${id}`); + return response.data; + } catch (error) { + throw error; + } + } +}; \ No newline at end of file diff --git a/client/admin/api/index.ts b/client/admin/api/index.ts new file mode 100644 index 0000000..bf427ab --- /dev/null +++ b/client/admin/api/index.ts @@ -0,0 +1,9 @@ +export * from './auth.ts'; +export * from './users.ts'; +export * from './files.ts'; +export * from './theme.ts'; +export * from './charts.ts'; +export * from './messages.ts'; +export * from './sys.ts'; +export * from './know_info.ts'; +export * from './maps.ts'; \ No newline at end of file diff --git a/client/admin/api/know_info.ts b/client/admin/api/know_info.ts new file mode 100644 index 0000000..f199261 --- /dev/null +++ b/client/admin/api/know_info.ts @@ -0,0 +1,95 @@ +import axios from 'axios'; +import type { KnowInfo } from '../../share/types.ts'; + +export interface KnowInfoListResponse { + data: KnowInfo[]; + pagination: { + current: number; + pageSize: number; + total: number; + totalPages: number; + }; +} + +interface KnowInfoResponse { + data: KnowInfo; + message?: string; +} + +interface KnowInfoCreateResponse { + message: string; + data: KnowInfo; +} + +interface KnowInfoUpdateResponse { + message: string; + data: KnowInfo; +} + +interface KnowInfoDeleteResponse { + message: string; + id: number; +} + + +const API_BASE_URL = '/api'; + + +// 知识库API +export const KnowInfoAPI = { + // 获取知识库列表 + getKnowInfos: async (params?: { + page?: number; + pageSize?: number; + title?: string; + category?: string; + tags?: string; + }): Promise => { + try { + const response = await axios.get(`${API_BASE_URL}/know-infos`, { params }); + return response.data; + } catch (error) { + throw error; + } + }, + + // 获取单个知识详情 + getKnowInfo: async (id: number): Promise => { + try { + const response = await axios.get(`${API_BASE_URL}/know-infos/${id}`); + return response.data; + } catch (error) { + throw error; + } + }, + + // 创建知识 + createKnowInfo: async (data: Partial): Promise => { + try { + const response = await axios.post(`${API_BASE_URL}/know-infos`, data); + return response.data; + } catch (error) { + throw error; + } + }, + + // 更新知识 + updateKnowInfo: async (id: number, data: Partial): Promise => { + try { + const response = await axios.put(`${API_BASE_URL}/know-infos/${id}`, data); + return response.data; + } catch (error) { + throw error; + } + }, + + // 删除知识 + deleteKnowInfo: async (id: number): Promise => { + try { + const response = await axios.delete(`${API_BASE_URL}/know-infos/${id}`); + return response.data; + } catch (error) { + throw error; + } + } +}; \ No newline at end of file diff --git a/client/admin/api/maps.ts b/client/admin/api/maps.ts new file mode 100644 index 0000000..540345c --- /dev/null +++ b/client/admin/api/maps.ts @@ -0,0 +1,64 @@ +import axios from 'axios'; +import type { + LoginLocation, LoginLocationDetail, +} from '../../share/types.ts'; + +const API_BASE_URL = '/api'; + + +// 地图相关API的接口类型定义 +export interface LoginLocationResponse { + message: string; + data: LoginLocation[]; +} + +export interface LoginLocationDetailResponse { + message: string; + data: LoginLocationDetail; +} + +export interface LoginLocationUpdateResponse { + message: string; + data: LoginLocationDetail; +} + +// 地图相关API +export const MapAPI = { + // 获取地图标记点数据 + getMarkers: async (params?: { + startTime?: string; + endTime?: string; + userId?: number + }): Promise => { + try { + const response = await axios.get(`${API_BASE_URL}/map/markers`, { params }); + return response.data; + } catch (error) { + throw error; + } + }, + + // 获取登录位置详情 + getLocationDetail: async (locationId: number): Promise => { + try { + const response = await axios.get(`${API_BASE_URL}/map/location/${locationId}`); + return response.data; + } catch (error) { + throw error; + } + }, + + // 更新登录位置信息 + updateLocation: async (locationId: number, data: { + longitude: number; + latitude: number; + location_name?: string; + }): Promise => { + try { + const response = await axios.put(`${API_BASE_URL}/map/location/${locationId}`, data); + return response.data; + } catch (error) { + throw error; + } + } +}; \ No newline at end of file diff --git a/client/admin/api/messages.ts b/client/admin/api/messages.ts new file mode 100644 index 0000000..a5d5fa2 --- /dev/null +++ b/client/admin/api/messages.ts @@ -0,0 +1,81 @@ +import axios from 'axios'; +import type { UserMessage, Message } from '../../share/types.ts'; + +const API_BASE_URL = '/api'; + +interface MessagesResponse { + data: UserMessage[]; + pagination: { + total: number; + current: number; + pageSize: number; + totalPages: number; + }; +} + +interface MessageResponse { + data: Message; + message?: string; +} + +interface MessageCountResponse { + count: number; +} + +export const MessageAPI = { + getMessages: async (params?: { + page?: number, + pageSize?: number, + type?: string, + status?: string, + search?: string + }): Promise => { + try { + const response = await axios.get(`${API_BASE_URL}/messages`, { params }); + return response.data; + } catch (error) { + throw error; + } + }, + + sendMessage: async (data: { + title: string, + content: string, + type: string, + receiver_ids: number[] + }): Promise => { + try { + const response = await axios.post(`${API_BASE_URL}/messages`, data); + return response.data; + } catch (error) { + throw error; + } + }, + + getUnreadCount: async (): Promise => { + try { + const response = await axios.get(`${API_BASE_URL}/messages/count/unread`); + return response.data; + } catch (error) { + throw error; + } + }, + + markAsRead: async (id: number): Promise => { + try { + const response = await axios.post(`${API_BASE_URL}/messages/${id}/read`); + return response.data; + } catch (error) { + throw error; + } + }, + + deleteMessage: async (id: number): Promise => { + try { + const response = await axios.delete(`${API_BASE_URL}/messages/${id}`); + return response.data; + } catch (error) { + throw error; + } + } +}; \ No newline at end of file diff --git a/client/admin/api/sys.ts b/client/admin/api/sys.ts new file mode 100644 index 0000000..f7dc7ff --- /dev/null +++ b/client/admin/api/sys.ts @@ -0,0 +1,49 @@ +import axios from 'axios'; + +import type { + SystemSetting, SystemSettingGroupData, +} from '../../share/types.ts'; + +const API_BASE_URL = '/api'; + +export const SystemAPI = { + // 获取所有系统设置 + getSettings: async (): Promise => { + try { + const response = await axios.get(`${API_BASE_URL}/settings`); + return response.data.data; + } catch (error) { + throw error; + } + }, + + // 获取指定分组的系统设置 + getSettingsByGroup: async (group: string): Promise => { + try { + const response = await axios.get(`${API_BASE_URL}/settings/group/${group}`); + return response.data.data; + } catch (error) { + throw error; + } + }, + + // 更新系统设置 + updateSettings: async (settings: Partial[]): Promise => { + try { + const response = await axios.put(`${API_BASE_URL}/settings`, settings); + return response.data.data; + } catch (error) { + throw error; + } + }, + + // 重置系统设置 + resetSettings: async (): Promise => { + try { + const response = await axios.post(`${API_BASE_URL}/settings/reset`); + return response.data.data; + } catch (error) { + throw error; + } + } +}; \ No newline at end of file diff --git a/client/admin/api/theme.ts b/client/admin/api/theme.ts new file mode 100644 index 0000000..863a6b2 --- /dev/null +++ b/client/admin/api/theme.ts @@ -0,0 +1,38 @@ +import axios from 'axios'; +import type { ThemeSettings } from '../../share/types.ts'; + +const API_BASE_URL = '/api'; + +export interface ThemeSettingsResponse { + message: string; + data: ThemeSettings; +} + +export const ThemeAPI = { + getThemeSettings: async (): Promise => { + try { + const response = await axios.get(`${API_BASE_URL}/theme`); + return response.data.data; + } catch (error) { + throw error; + } + }, + + updateThemeSettings: async (themeData: Partial): Promise => { + try { + const response = await axios.put(`${API_BASE_URL}/theme`, themeData); + return response.data.data; + } catch (error) { + throw error; + } + }, + + resetThemeSettings: async (): Promise => { + try { + const response = await axios.post(`${API_BASE_URL}/theme/reset`); + return response.data.data; + } catch (error) { + throw error; + } + } +}; \ No newline at end of file diff --git a/client/admin/api/users.ts b/client/admin/api/users.ts new file mode 100644 index 0000000..8e6c018 --- /dev/null +++ b/client/admin/api/users.ts @@ -0,0 +1,81 @@ +import axios from 'axios'; +import type { User } from '../../share/types.ts'; + +const API_BASE_URL = '/api'; + +interface UsersResponse { + data: User[]; + pagination: { + total: number; + current: number; + pageSize: number; + totalPages: number; + }; +} + +interface UserResponse { + data: User; + message?: string; +} + +interface UserCreateResponse { + message: string; + data: User; +} + +interface UserUpdateResponse { + message: string; + data: User; +} + +interface UserDeleteResponse { + message: string; + id: number; +} + +export const UserAPI = { + getUsers: async (params?: { page?: number, limit?: number, search?: string }): Promise => { + try { + const response = await axios.get(`${API_BASE_URL}/users`, { params }); + return response.data; + } catch (error) { + throw error; + } + }, + + getUser: async (userId: number): Promise => { + try { + const response = await axios.get(`${API_BASE_URL}/users/${userId}`); + return response.data; + } catch (error) { + throw error; + } + }, + + createUser: async (userData: Partial): Promise => { + try { + const response = await axios.post(`${API_BASE_URL}/users`, userData); + return response.data; + } catch (error) { + throw error; + } + }, + + updateUser: async (userId: number, userData: Partial): Promise => { + try { + const response = await axios.put(`${API_BASE_URL}/users/${userId}`, userData); + return response.data; + } catch (error) { + throw error; + } + }, + + deleteUser: async (userId: number): Promise => { + try { + const response = await axios.delete(`${API_BASE_URL}/users/${userId}`); + return response.data; + } catch (error) { + throw error; + } + } +}; \ No newline at end of file diff --git a/client/admin/components_uploader.tsx b/client/admin/components_uploader.tsx index bf9785e..0671b05 100644 --- a/client/admin/components_uploader.tsx +++ b/client/admin/components_uploader.tsx @@ -16,7 +16,7 @@ import type { MinioUploadPolicy, OSSUploadPolicy } from '@d8d-appcontainer/types import 'dayjs/locale/zh-cn'; import { OssType } from '../share/types.ts'; -import { FileAPI } from './api.ts'; +import { FileAPI } from './api/index.ts'; // MinIO文件上传组件 export const Uploader = ({ diff --git a/client/admin/hooks_sys.tsx b/client/admin/hooks_sys.tsx index c0245f9..a222c66 100644 --- a/client/admin/hooks_sys.tsx +++ b/client/admin/hooks_sys.tsx @@ -24,7 +24,7 @@ import { import { AuthAPI, ThemeAPI -} from './api.ts'; +} from './api/index.ts'; // 配置 dayjs 插件 diff --git a/client/admin/pages_chart.tsx b/client/admin/pages_chart.tsx index 5de33e0..ac084e2 100644 --- a/client/admin/pages_chart.tsx +++ b/client/admin/pages_chart.tsx @@ -1,11 +1,6 @@ import React from 'react'; import { - Layout, Menu, Button, Table, Space, - Form, Input, Select, message, Modal, - Card, Spin, Row, Col, Breadcrumb, Avatar, - Dropdown, ConfigProvider, theme, Typography, - Switch, Badge, Image, Upload, Divider, Descriptions, - Popconfirm, Tag, Statistic, DatePicker, Radio, Progress, Tabs, List, Alert, Collapse, Empty, Drawer + Card, Spin, Row, Col, Statistic, } from 'antd'; import { @@ -15,13 +10,10 @@ import { Line , Pie, Column} from "@ant-design/plots"; import 'dayjs/locale/zh-cn'; -import { ChartAPI } from './api.ts'; +import { ChartAPI } from './api/index.ts'; import { useTheme } from './hooks_sys.tsx'; -interface ChartTooltipInfo { - items: Array>; - title: string; -} + // 用户活跃度图表组件 const UserActivityChart: React.FC = () => { @@ -49,7 +41,7 @@ const UserActivityChart: React.FC = () => { }; return ( - + ); @@ -92,7 +84,7 @@ const FileUploadsChart: React.FC = () => { }; return ( - + ); @@ -130,7 +122,7 @@ const FileTypesChart: React.FC = () => { }; return ( - + ); @@ -151,7 +143,7 @@ const DashboardOverview: React.FC = () => { return ( - + { - + { - + { - + { const queryClient = useQueryClient(); const [form] = Form.useForm(); - const [selectedRowKeys, setSelectedRowKeys] = useState([]); const [isModalVisible, setIsModalVisible] = useState(false); const [searchParams, setSearchParams] = useState({ page: 1, diff --git a/client/admin/pages_settings.tsx b/client/admin/pages_settings.tsx index dfa3061..d86a4b4 100644 --- a/client/admin/pages_settings.tsx +++ b/client/admin/pages_settings.tsx @@ -1,20 +1,14 @@ -import React, { useState, useEffect } from 'react'; +import React, { useEffect } from 'react'; import { - Layout, Menu, Button, Table, Space, + Button,Space, Form, Input, Select, message, Modal, - Card, Spin, Row, Col, Breadcrumb, Avatar, - Dropdown, ConfigProvider, theme, Typography, - Switch, Badge, Image, Upload, Divider, Descriptions, - Popconfirm, Tag, Statistic, DatePicker, Radio, Progress, Tabs, List, Alert, Collapse, Empty, Drawer, InputNumber,ColorPicker, - Popover + Card, Spin, Typography, + Switch, Tabs, Alert, InputNumber } from 'antd'; import { - UploadOutlined, ReloadOutlined, SaveOutlined, - BgColorsOutlined } from '@ant-design/icons'; -import { debounce } from 'lodash'; import { useQuery, useMutation, @@ -25,25 +19,20 @@ import weekday from 'dayjs/plugin/weekday'; import localeData from 'dayjs/plugin/localeData'; import 'dayjs/locale/zh-cn'; import type { - FileLibrary, FileCategory, KnowInfo, SystemSetting, SystemSettingValue, - ColorScheme + SystemSetting, SystemSettingValue } from '../share/types.ts'; -import { ThemeMode } from '../share/types.ts'; import { SystemSettingGroup, SystemSettingKey, - FontSize, - CompactMode, AllowedFileType } from '../share/types.ts'; -import { getEnumOptions } from './utils.ts'; import { - SystemAPI, -} from './api.ts'; + SystemAPI +} from './api/index.ts'; import { useTheme } from './hooks_sys.tsx'; @@ -241,44 +230,44 @@ export const SettingsPage = () => { items={Object.values(SystemSettingGroup).map(group => ({ key: group, label: String(GROUP_TITLES[group]), - children: ( -
- + -
+ type="info" + showIcon + style={{ marginBottom: 24 }} + /> + {settingsData ?.find(g => g.name === group) ?.settings.map(setting => ( - {renderSettingInput(setting)} - + ))} - - - -
-
- ) + + + + + + ) }))} /> diff --git a/client/admin/pages_sys.tsx b/client/admin/pages_sys.tsx index 64cad76..dacae58 100644 --- a/client/admin/pages_sys.tsx +++ b/client/admin/pages_sys.tsx @@ -25,20 +25,15 @@ import { uploadMinIOWithPolicy,uploadOSSWithPolicy } from '@d8d-appcontainer/api import type { MinioUploadPolicy, OSSUploadPolicy } from '@d8d-appcontainer/types'; import 'dayjs/locale/zh-cn'; import type { - FileLibrary, FileCategory, KnowInfo + FileLibrary, FileCategory } from '../share/types.ts'; import { - AuditStatus,AuditStatusNameMap, OssType, } from '../share/types.ts'; -import { getEnumOptions } from './utils.ts'; -import { - FileAPI, - UserAPI, -} from './api.ts'; +import { FileAPI , UserAPI } from './api/index.ts'; // 配置 dayjs 插件 diff --git a/client/admin/pages_theme_settings.tsx b/client/admin/pages_theme_settings.tsx index 613d10d..a6f6e12 100644 --- a/client/admin/pages_theme_settings.tsx +++ b/client/admin/pages_theme_settings.tsx @@ -1,53 +1,30 @@ import React, { useState, useEffect } from 'react'; import { - Layout, Menu, Button, Table, Space, - Form, Input, Select, message, Modal, - Card, Spin, Row, Col, Breadcrumb, Avatar, - Dropdown, ConfigProvider, theme, Typography, - Switch, Badge, Image, Upload, Divider, Descriptions, - Popconfirm, Tag, Statistic, DatePicker, Radio, Progress, Tabs, List, Alert, Collapse, Empty, Drawer, InputNumber,ColorPicker, - Popover + Button, Space, + Form, message, + Card, Spin, Typography, + Switch, + Popconfirm, Radio, InputNumber,ColorPicker, } from 'antd'; -import { - UploadOutlined, - ReloadOutlined, - SaveOutlined, - BgColorsOutlined -} from '@ant-design/icons'; -import { debounce } from 'lodash'; -import { - useQuery, - useMutation, - useQueryClient, -} from '@tanstack/react-query'; import dayjs from 'dayjs'; import weekday from 'dayjs/plugin/weekday'; import localeData from 'dayjs/plugin/localeData'; import 'dayjs/locale/zh-cn'; import type { - FileLibrary, FileCategory, KnowInfo, SystemSetting, SystemSettingValue, ColorScheme } from '../share/types.ts'; import { ThemeMode } from '../share/types.ts'; import { - SystemSettingGroup, - SystemSettingKey, FontSize, CompactMode, - AllowedFileType } from '../share/types.ts'; -import { getEnumOptions } from './utils.ts'; -import { - SystemAPI, -} from './api.ts'; import { useTheme } from './hooks_sys.tsx'; -import { Uploader } from './components_uploader.tsx'; // 配置 dayjs 插件 dayjs.extend(weekday);