api.ts 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601
  1. import axios from 'axios';
  2. import type { MinioUploadPolicy, OSSUploadPolicy } from '@d8d-appcontainer/types';
  3. import 'dayjs/locale/zh-cn';
  4. import type {
  5. User, FileLibrary, FileCategory, KnowInfo,
  6. AuthContextType, ThemeContextType, Attachment, ThemeSettings,
  7. SystemSetting, SystemSettingGroupData
  8. } from '../share/types.ts';
  9. // 定义API基础URL
  10. const API_BASE_URL = '/api';
  11. // 获取OSS完整URL
  12. export const getOssUrl = (path: string): string => {
  13. // 获取全局配置中的OSS_HOST,如果不存在使用默认值
  14. const ossHost = (window.CONFIG?.OSS_BASE_URL) || '';
  15. // 确保path不以/开头
  16. const ossPath = path.startsWith('/') ? path.substring(1) : path;
  17. return `${ossHost}/${ossPath}`;
  18. };
  19. // ===================
  20. // Auth API 定义部分
  21. // ===================
  22. // 定义API返回数据类型
  23. interface AuthLoginResponse {
  24. message: string;
  25. token: string;
  26. refreshToken?: string;
  27. user: User;
  28. }
  29. interface AuthResponse {
  30. message: string;
  31. [key: string]: any;
  32. }
  33. // 定义Auth API接口类型
  34. interface AuthAPIType {
  35. login: (username: string, password: string) => Promise<AuthLoginResponse>;
  36. register: (username: string, email: string, password: string) => Promise<AuthResponse>;
  37. logout: () => Promise<AuthResponse>;
  38. getCurrentUser: () => Promise<User>;
  39. updateUser: (userId: number, userData: Partial<User>) => Promise<User>;
  40. changePassword: (oldPassword: string, newPassword: string) => Promise<AuthResponse>;
  41. requestPasswordReset: (email: string) => Promise<AuthResponse>;
  42. resetPassword: (token: string, newPassword: string) => Promise<AuthResponse>;
  43. }
  44. // Auth相关API
  45. export const AuthAPI: AuthAPIType = {
  46. // 登录API
  47. login: async (username: string, password: string) => {
  48. try {
  49. const response = await axios.post(`${API_BASE_URL}/auth/login`, { username, password });
  50. return response.data;
  51. } catch (error) {
  52. throw error;
  53. }
  54. },
  55. // 注册API
  56. register: async (username: string, email: string, password: string) => {
  57. try {
  58. const response = await axios.post(`${API_BASE_URL}/auth/register`, { username, email, password });
  59. return response.data;
  60. } catch (error) {
  61. throw error;
  62. }
  63. },
  64. // 登出API
  65. logout: async () => {
  66. try {
  67. const response = await axios.post(`${API_BASE_URL}/auth/logout`);
  68. return response.data;
  69. } catch (error) {
  70. throw error;
  71. }
  72. },
  73. // 获取当前用户信息
  74. getCurrentUser: async () => {
  75. try {
  76. const response = await axios.get(`${API_BASE_URL}/auth/me`);
  77. return response.data;
  78. } catch (error) {
  79. throw error;
  80. }
  81. },
  82. // 更新用户信息
  83. updateUser: async (userId: number, userData: Partial<User>) => {
  84. try {
  85. const response = await axios.put(`${API_BASE_URL}/auth/users/${userId}`, userData);
  86. return response.data;
  87. } catch (error) {
  88. throw error;
  89. }
  90. },
  91. // 修改密码
  92. changePassword: async (oldPassword: string, newPassword: string) => {
  93. try {
  94. const response = await axios.post(`${API_BASE_URL}/auth/change-password`, { oldPassword, newPassword });
  95. return response.data;
  96. } catch (error) {
  97. throw error;
  98. }
  99. },
  100. // 请求重置密码
  101. requestPasswordReset: async (email: string) => {
  102. try {
  103. const response = await axios.post(`${API_BASE_URL}/auth/request-password-reset`, { email });
  104. return response.data;
  105. } catch (error) {
  106. throw error;
  107. }
  108. },
  109. // 重置密码
  110. resetPassword: async (token: string, newPassword: string) => {
  111. try {
  112. const response = await axios.post(`${API_BASE_URL}/auth/reset-password`, { token, newPassword });
  113. return response.data;
  114. } catch (error) {
  115. throw error;
  116. }
  117. }
  118. };
  119. // 为UserAPI添加的接口响应类型
  120. interface UsersResponse {
  121. data: User[];
  122. pagination: {
  123. total: number;
  124. current: number;
  125. pageSize: number;
  126. totalPages: number;
  127. };
  128. }
  129. interface UserResponse {
  130. data: User;
  131. message?: string;
  132. }
  133. interface UserCreateResponse {
  134. message: string;
  135. data: User;
  136. }
  137. interface UserUpdateResponse {
  138. message: string;
  139. data: User;
  140. }
  141. interface UserDeleteResponse {
  142. message: string;
  143. id: number;
  144. }
  145. // 用户管理API
  146. export const UserAPI = {
  147. // 获取用户列表
  148. getUsers: async (params?: { page?: number, limit?: number, search?: string }): Promise<UsersResponse> => {
  149. try {
  150. const response = await axios.get(`${API_BASE_URL}/users`, { params });
  151. return response.data;
  152. } catch (error) {
  153. throw error;
  154. }
  155. },
  156. // 获取单个用户详情
  157. getUser: async (userId: number): Promise<UserResponse> => {
  158. try {
  159. const response = await axios.get(`${API_BASE_URL}/users/${userId}`);
  160. return response.data;
  161. } catch (error) {
  162. throw error;
  163. }
  164. },
  165. // 创建用户
  166. createUser: async (userData: Partial<User>): Promise<UserCreateResponse> => {
  167. try {
  168. const response = await axios.post(`${API_BASE_URL}/users`, userData);
  169. return response.data;
  170. } catch (error) {
  171. throw error;
  172. }
  173. },
  174. // 更新用户信息
  175. updateUser: async (userId: number, userData: Partial<User>): Promise<UserUpdateResponse> => {
  176. try {
  177. const response = await axios.put(`${API_BASE_URL}/users/${userId}`, userData);
  178. return response.data;
  179. } catch (error) {
  180. throw error;
  181. }
  182. },
  183. // 删除用户
  184. deleteUser: async (userId: number): Promise<UserDeleteResponse> => {
  185. try {
  186. const response = await axios.delete(`${API_BASE_URL}/users/${userId}`);
  187. return response.data;
  188. } catch (error) {
  189. throw error;
  190. }
  191. }
  192. };
  193. // 定义文件相关接口类型
  194. interface FileUploadPolicyResponse {
  195. message: string;
  196. data: MinioUploadPolicy | OSSUploadPolicy;
  197. }
  198. interface FileListResponse {
  199. message: string;
  200. data: {
  201. list: FileLibrary[];
  202. pagination: {
  203. current: number;
  204. pageSize: number;
  205. total: number;
  206. };
  207. };
  208. }
  209. interface FileSaveResponse {
  210. message: string;
  211. data: FileLibrary;
  212. }
  213. interface FileInfoResponse {
  214. message: string;
  215. data: FileLibrary;
  216. }
  217. interface FileDeleteResponse {
  218. message: string;
  219. }
  220. interface FileCategoryListResponse {
  221. data: FileCategory[];
  222. total: number;
  223. page: number;
  224. pageSize: number;
  225. }
  226. interface FileCategoryCreateResponse {
  227. message: string;
  228. data: FileCategory;
  229. }
  230. interface FileCategoryUpdateResponse {
  231. message: string;
  232. data: FileCategory;
  233. }
  234. interface FileCategoryDeleteResponse {
  235. message: string;
  236. }
  237. // 文件API接口定义
  238. export const FileAPI = {
  239. // 获取文件上传策略
  240. getUploadPolicy: async (filename: string, prefix: string = 'uploads/', maxSize: number = 10 * 1024 * 1024): Promise<FileUploadPolicyResponse> => {
  241. try {
  242. const response = await axios.get(`${API_BASE_URL}/upload/policy`, {
  243. params: { filename, prefix, maxSize }
  244. });
  245. return response.data;
  246. } catch (error) {
  247. throw error;
  248. }
  249. },
  250. // 保存文件信息
  251. saveFileInfo: async (fileData: Partial<FileLibrary>): Promise<FileSaveResponse> => {
  252. try {
  253. const response = await axios.post(`${API_BASE_URL}/upload/save`, fileData);
  254. return response.data;
  255. } catch (error) {
  256. throw error;
  257. }
  258. },
  259. // 获取文件列表
  260. getFileList: async (params?: {
  261. page?: number,
  262. pageSize?: number,
  263. category_id?: number,
  264. fileType?: string,
  265. keyword?: string
  266. }): Promise<FileListResponse> => {
  267. try {
  268. const response = await axios.get(`${API_BASE_URL}/upload/list`, { params });
  269. return response.data;
  270. } catch (error) {
  271. throw error;
  272. }
  273. },
  274. // 获取单个文件信息
  275. getFileInfo: async (id: number): Promise<FileInfoResponse> => {
  276. try {
  277. const response = await axios.get(`${API_BASE_URL}/upload/${id}`);
  278. return response.data;
  279. } catch (error) {
  280. throw error;
  281. }
  282. },
  283. // 更新文件下载计数
  284. updateDownloadCount: async (id: number): Promise<FileDeleteResponse> => {
  285. try {
  286. const response = await axios.post(`${API_BASE_URL}/upload/${id}/download`);
  287. return response.data;
  288. } catch (error) {
  289. throw error;
  290. }
  291. },
  292. // 删除文件
  293. deleteFile: async (id: number): Promise<FileDeleteResponse> => {
  294. try {
  295. const response = await axios.delete(`${API_BASE_URL}/upload/${id}`);
  296. return response.data;
  297. } catch (error) {
  298. throw error;
  299. }
  300. },
  301. // 获取文件分类列表
  302. getCategories: async (params?: {
  303. page?: number,
  304. pageSize?: number,
  305. search?: string
  306. }): Promise<FileCategoryListResponse> => {
  307. try {
  308. const response = await axios.get(`${API_BASE_URL}/file-categories`, { params });
  309. return response.data;
  310. } catch (error) {
  311. throw error;
  312. }
  313. },
  314. // 创建文件分类
  315. createCategory: async (data: Partial<FileCategory>): Promise<FileCategoryCreateResponse> => {
  316. try {
  317. const response = await axios.post(`${API_BASE_URL}/file-categories`, data);
  318. return response.data;
  319. } catch (error) {
  320. throw error;
  321. }
  322. },
  323. // 更新文件分类
  324. updateCategory: async (id: number, data: Partial<FileCategory>): Promise<FileCategoryUpdateResponse> => {
  325. try {
  326. const response = await axios.put(`${API_BASE_URL}/file-categories/${id}`, data);
  327. return response.data;
  328. } catch (error) {
  329. throw error;
  330. }
  331. },
  332. // 删除文件分类
  333. deleteCategory: async (id: number): Promise<FileCategoryDeleteResponse> => {
  334. try {
  335. const response = await axios.delete(`${API_BASE_URL}/file-categories/${id}`);
  336. return response.data;
  337. } catch (error) {
  338. throw error;
  339. }
  340. }
  341. };
  342. // Theme API 响应类型
  343. export interface ThemeSettingsResponse {
  344. message: string;
  345. data: ThemeSettings;
  346. }
  347. // Theme API 定义
  348. export const ThemeAPI = {
  349. // 获取主题设置
  350. getThemeSettings: async (): Promise<ThemeSettings> => {
  351. try {
  352. const response = await axios.get(`${API_BASE_URL}/theme`);
  353. return response.data.data;
  354. } catch (error) {
  355. throw error;
  356. }
  357. },
  358. // 更新主题设置
  359. updateThemeSettings: async (themeData: Partial<ThemeSettings>): Promise<ThemeSettings> => {
  360. try {
  361. const response = await axios.put(`${API_BASE_URL}/theme`, themeData);
  362. return response.data.data;
  363. } catch (error) {
  364. throw error;
  365. }
  366. },
  367. // 重置主题设置
  368. resetThemeSettings: async (): Promise<ThemeSettings> => {
  369. try {
  370. const response = await axios.post(`${API_BASE_URL}/theme/reset`);
  371. return response.data.data;
  372. } catch (error) {
  373. throw error;
  374. }
  375. }
  376. };
  377. // 图表数据API接口类型
  378. interface ChartDataResponse<T> {
  379. message: string;
  380. data: T;
  381. }
  382. interface UserActivityData {
  383. date: string;
  384. count: number;
  385. }
  386. interface FileUploadsData {
  387. month: string;
  388. count: number;
  389. }
  390. interface FileTypesData {
  391. type: string;
  392. value: number;
  393. }
  394. interface DashboardOverviewData {
  395. userCount: number;
  396. fileCount: number;
  397. articleCount: number;
  398. todayLoginCount: number;
  399. }
  400. // 图表数据API
  401. export const ChartAPI = {
  402. // 获取用户活跃度数据
  403. getUserActivity: async (): Promise<ChartDataResponse<UserActivityData[]>> => {
  404. try {
  405. const response = await axios.get(`${API_BASE_URL}/charts/user-activity`);
  406. return response.data;
  407. } catch (error) {
  408. throw error;
  409. }
  410. },
  411. // 获取文件上传统计数据
  412. getFileUploads: async (): Promise<ChartDataResponse<FileUploadsData[]>> => {
  413. try {
  414. const response = await axios.get(`${API_BASE_URL}/charts/file-uploads`);
  415. return response.data;
  416. } catch (error) {
  417. throw error;
  418. }
  419. },
  420. // 获取文件类型分布数据
  421. getFileTypes: async (): Promise<ChartDataResponse<FileTypesData[]>> => {
  422. try {
  423. const response = await axios.get(`${API_BASE_URL}/charts/file-types`);
  424. return response.data;
  425. } catch (error) {
  426. throw error;
  427. }
  428. },
  429. // 获取仪表盘概览数据
  430. getDashboardOverview: async (): Promise<ChartDataResponse<DashboardOverviewData>> => {
  431. try {
  432. const response = await axios.get(`${API_BASE_URL}/charts/dashboard-overview`);
  433. return response.data;
  434. } catch (error) {
  435. throw error;
  436. }
  437. }
  438. };
  439. // 地图相关API的接口类型定义
  440. export interface LoginLocationResponse {
  441. message: string;
  442. data: LoginLocation[];
  443. }
  444. export interface LoginLocationDetailResponse {
  445. message: string;
  446. data: LoginLocationDetail;
  447. }
  448. export interface LoginLocationUpdateResponse {
  449. message: string;
  450. data: LoginLocationDetail;
  451. }
  452. // 地图相关API
  453. export const MapAPI = {
  454. // 获取地图标记点数据
  455. getMarkers: async (params?: {
  456. startTime?: string;
  457. endTime?: string;
  458. userId?: number
  459. }): Promise<LoginLocationResponse> => {
  460. try {
  461. const response = await axios.get(`${API_BASE_URL}/map/markers`, { params });
  462. return response.data;
  463. } catch (error) {
  464. throw error;
  465. }
  466. },
  467. // 获取登录位置详情
  468. getLocationDetail: async (locationId: number): Promise<LoginLocationDetailResponse> => {
  469. try {
  470. const response = await axios.get(`${API_BASE_URL}/map/location/${locationId}`);
  471. return response.data;
  472. } catch (error) {
  473. throw error;
  474. }
  475. },
  476. // 更新登录位置信息
  477. updateLocation: async (locationId: number, data: {
  478. longitude: number;
  479. latitude: number;
  480. location_name?: string;
  481. }): Promise<LoginLocationUpdateResponse> => {
  482. try {
  483. const response = await axios.put(`${API_BASE_URL}/map/location/${locationId}`, data);
  484. return response.data;
  485. } catch (error) {
  486. throw error;
  487. }
  488. }
  489. };
  490. // 系统设置API
  491. export const SystemAPI = {
  492. // 获取所有系统设置
  493. getSettings: async (): Promise<SystemSettingGroupData[]> => {
  494. try {
  495. const response = await axios.get(`${API_BASE_URL}/settings`);
  496. return response.data.data;
  497. } catch (error) {
  498. throw error;
  499. }
  500. },
  501. // 获取指定分组的系统设置
  502. getSettingsByGroup: async (group: string): Promise<SystemSetting[]> => {
  503. try {
  504. const response = await axios.get(`${API_BASE_URL}/settings/group/${group}`);
  505. return response.data.data;
  506. } catch (error) {
  507. throw error;
  508. }
  509. },
  510. // 更新系统设置
  511. updateSettings: async (settings: Partial<SystemSetting>[]): Promise<SystemSetting[]> => {
  512. try {
  513. const response = await axios.put(`${API_BASE_URL}/settings`, settings);
  514. return response.data.data;
  515. } catch (error) {
  516. throw error;
  517. }
  518. },
  519. // 重置系统设置
  520. resetSettings: async (): Promise<SystemSetting[]> => {
  521. try {
  522. const response = await axios.post(`${API_BASE_URL}/settings/reset`);
  523. return response.data.data;
  524. } catch (error) {
  525. throw error;
  526. }
  527. }
  528. };