api.ts 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595
  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 const ThemeAPI = {
  344. // 获取主题设置
  345. getThemeSettings: async (): Promise<ThemeSettings> => {
  346. try {
  347. const response = await axios.get(`${API_BASE_URL}/theme`);
  348. return response.data.data;
  349. } catch (error) {
  350. throw error;
  351. }
  352. },
  353. // 更新主题设置
  354. updateThemeSettings: async (themeData: Partial<ThemeSettings>): Promise<ThemeSettings> => {
  355. try {
  356. const response = await axios.put(`${API_BASE_URL}/theme`, themeData);
  357. return response.data.data;
  358. } catch (error) {
  359. throw error;
  360. }
  361. },
  362. // 重置主题设置
  363. resetThemeSettings: async (): Promise<ThemeSettings> => {
  364. try {
  365. const response = await axios.post(`${API_BASE_URL}/theme/reset`);
  366. return response.data.data;
  367. } catch (error) {
  368. throw error;
  369. }
  370. }
  371. };
  372. // 图表数据API接口类型
  373. interface ChartDataResponse<T> {
  374. message: string;
  375. data: T;
  376. }
  377. interface UserActivityData {
  378. date: string;
  379. count: number;
  380. }
  381. interface FileUploadsData {
  382. month: string;
  383. count: number;
  384. }
  385. interface FileTypesData {
  386. type: string;
  387. value: number;
  388. }
  389. interface DashboardOverviewData {
  390. userCount: number;
  391. fileCount: number;
  392. articleCount: number;
  393. todayLoginCount: number;
  394. }
  395. // 图表数据API
  396. export const ChartAPI = {
  397. // 获取用户活跃度数据
  398. getUserActivity: async (): Promise<ChartDataResponse<UserActivityData[]>> => {
  399. try {
  400. const response = await axios.get(`${API_BASE_URL}/charts/user-activity`);
  401. return response.data;
  402. } catch (error) {
  403. throw error;
  404. }
  405. },
  406. // 获取文件上传统计数据
  407. getFileUploads: async (): Promise<ChartDataResponse<FileUploadsData[]>> => {
  408. try {
  409. const response = await axios.get(`${API_BASE_URL}/charts/file-uploads`);
  410. return response.data;
  411. } catch (error) {
  412. throw error;
  413. }
  414. },
  415. // 获取文件类型分布数据
  416. getFileTypes: async (): Promise<ChartDataResponse<FileTypesData[]>> => {
  417. try {
  418. const response = await axios.get(`${API_BASE_URL}/charts/file-types`);
  419. return response.data;
  420. } catch (error) {
  421. throw error;
  422. }
  423. },
  424. // 获取仪表盘概览数据
  425. getDashboardOverview: async (): Promise<ChartDataResponse<DashboardOverviewData>> => {
  426. try {
  427. const response = await axios.get(`${API_BASE_URL}/charts/dashboard-overview`);
  428. return response.data;
  429. } catch (error) {
  430. throw error;
  431. }
  432. }
  433. };
  434. // 地图相关API的接口类型定义
  435. export interface LoginLocationResponse {
  436. message: string;
  437. data: LoginLocation[];
  438. }
  439. export interface LoginLocationDetailResponse {
  440. message: string;
  441. data: LoginLocationDetail;
  442. }
  443. export interface LoginLocationUpdateResponse {
  444. message: string;
  445. data: LoginLocationDetail;
  446. }
  447. // 地图相关API
  448. export const MapAPI = {
  449. // 获取地图标记点数据
  450. getMarkers: async (params?: {
  451. startTime?: string;
  452. endTime?: string;
  453. userId?: number
  454. }): Promise<LoginLocationResponse> => {
  455. try {
  456. const response = await axios.get(`${API_BASE_URL}/map/markers`, { params });
  457. return response.data;
  458. } catch (error) {
  459. throw error;
  460. }
  461. },
  462. // 获取登录位置详情
  463. getLocationDetail: async (locationId: number): Promise<LoginLocationDetailResponse> => {
  464. try {
  465. const response = await axios.get(`${API_BASE_URL}/map/location/${locationId}`);
  466. return response.data;
  467. } catch (error) {
  468. throw error;
  469. }
  470. },
  471. // 更新登录位置信息
  472. updateLocation: async (locationId: number, data: {
  473. longitude: number;
  474. latitude: number;
  475. location_name?: string;
  476. }): Promise<LoginLocationUpdateResponse> => {
  477. try {
  478. const response = await axios.put(`${API_BASE_URL}/map/location/${locationId}`, data);
  479. return response.data;
  480. } catch (error) {
  481. throw error;
  482. }
  483. }
  484. };
  485. // 系统设置API
  486. export const SystemAPI = {
  487. // 获取所有系统设置
  488. getSettings: async (): Promise<SystemSettingGroupData[]> => {
  489. try {
  490. const response = await axios.get(`${API_BASE_URL}/settings`);
  491. return response.data.data;
  492. } catch (error) {
  493. throw error;
  494. }
  495. },
  496. // 获取指定分组的系统设置
  497. getSettingsByGroup: async (group: string): Promise<SystemSetting[]> => {
  498. try {
  499. const response = await axios.get(`${API_BASE_URL}/settings/group/${group}`);
  500. return response.data.data;
  501. } catch (error) {
  502. throw error;
  503. }
  504. },
  505. // 更新系统设置
  506. updateSettings: async (settings: Partial<SystemSetting>[]): Promise<SystemSetting[]> => {
  507. try {
  508. const response = await axios.put(`${API_BASE_URL}/settings`, settings);
  509. return response.data.data;
  510. } catch (error) {
  511. throw error;
  512. }
  513. },
  514. // 重置系统设置
  515. resetSettings: async (): Promise<SystemSetting[]> => {
  516. try {
  517. const response = await axios.post(`${API_BASE_URL}/settings/reset`);
  518. return response.data.data;
  519. } catch (error) {
  520. throw error;
  521. }
  522. }
  523. };