api.ts 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600
  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, latitude?: number, longitude?: number) => 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, latitude?: number, longitude?: number) => {
  48. try {
  49. const response = await axios.post(`${API_BASE_URL}/auth/login`, {
  50. username,
  51. password,
  52. latitude,
  53. longitude
  54. });
  55. return response.data;
  56. } catch (error) {
  57. throw error;
  58. }
  59. },
  60. // 注册API
  61. register: async (username: string, email: string, password: string) => {
  62. try {
  63. const response = await axios.post(`${API_BASE_URL}/auth/register`, { username, email, password });
  64. return response.data;
  65. } catch (error) {
  66. throw error;
  67. }
  68. },
  69. // 登出API
  70. logout: async () => {
  71. try {
  72. const response = await axios.post(`${API_BASE_URL}/auth/logout`);
  73. return response.data;
  74. } catch (error) {
  75. throw error;
  76. }
  77. },
  78. // 获取当前用户信息
  79. getCurrentUser: async () => {
  80. try {
  81. const response = await axios.get(`${API_BASE_URL}/auth/me`);
  82. return response.data;
  83. } catch (error) {
  84. throw error;
  85. }
  86. },
  87. // 更新用户信息
  88. updateUser: async (userId: number, userData: Partial<User>) => {
  89. try {
  90. const response = await axios.put(`${API_BASE_URL}/auth/users/${userId}`, userData);
  91. return response.data;
  92. } catch (error) {
  93. throw error;
  94. }
  95. },
  96. // 修改密码
  97. changePassword: async (oldPassword: string, newPassword: string) => {
  98. try {
  99. const response = await axios.post(`${API_BASE_URL}/auth/change-password`, { oldPassword, newPassword });
  100. return response.data;
  101. } catch (error) {
  102. throw error;
  103. }
  104. },
  105. // 请求重置密码
  106. requestPasswordReset: async (email: string) => {
  107. try {
  108. const response = await axios.post(`${API_BASE_URL}/auth/request-password-reset`, { email });
  109. return response.data;
  110. } catch (error) {
  111. throw error;
  112. }
  113. },
  114. // 重置密码
  115. resetPassword: async (token: string, newPassword: string) => {
  116. try {
  117. const response = await axios.post(`${API_BASE_URL}/auth/reset-password`, { token, newPassword });
  118. return response.data;
  119. } catch (error) {
  120. throw error;
  121. }
  122. }
  123. };
  124. // 为UserAPI添加的接口响应类型
  125. interface UsersResponse {
  126. data: User[];
  127. pagination: {
  128. total: number;
  129. current: number;
  130. pageSize: number;
  131. totalPages: number;
  132. };
  133. }
  134. interface UserResponse {
  135. data: User;
  136. message?: string;
  137. }
  138. interface UserCreateResponse {
  139. message: string;
  140. data: User;
  141. }
  142. interface UserUpdateResponse {
  143. message: string;
  144. data: User;
  145. }
  146. interface UserDeleteResponse {
  147. message: string;
  148. id: number;
  149. }
  150. // 用户管理API
  151. export const UserAPI = {
  152. // 获取用户列表
  153. getUsers: async (params?: { page?: number, limit?: number, search?: string }): Promise<UsersResponse> => {
  154. try {
  155. const response = await axios.get(`${API_BASE_URL}/users`, { params });
  156. return response.data;
  157. } catch (error) {
  158. throw error;
  159. }
  160. },
  161. // 获取单个用户详情
  162. getUser: async (userId: number): Promise<UserResponse> => {
  163. try {
  164. const response = await axios.get(`${API_BASE_URL}/users/${userId}`);
  165. return response.data;
  166. } catch (error) {
  167. throw error;
  168. }
  169. },
  170. // 创建用户
  171. createUser: async (userData: Partial<User>): Promise<UserCreateResponse> => {
  172. try {
  173. const response = await axios.post(`${API_BASE_URL}/users`, userData);
  174. return response.data;
  175. } catch (error) {
  176. throw error;
  177. }
  178. },
  179. // 更新用户信息
  180. updateUser: async (userId: number, userData: Partial<User>): Promise<UserUpdateResponse> => {
  181. try {
  182. const response = await axios.put(`${API_BASE_URL}/users/${userId}`, userData);
  183. return response.data;
  184. } catch (error) {
  185. throw error;
  186. }
  187. },
  188. // 删除用户
  189. deleteUser: async (userId: number): Promise<UserDeleteResponse> => {
  190. try {
  191. const response = await axios.delete(`${API_BASE_URL}/users/${userId}`);
  192. return response.data;
  193. } catch (error) {
  194. throw error;
  195. }
  196. }
  197. };
  198. // 定义文件相关接口类型
  199. interface FileUploadPolicyResponse {
  200. message: string;
  201. data: MinioUploadPolicy | OSSUploadPolicy;
  202. }
  203. interface FileListResponse {
  204. message: string;
  205. data: {
  206. list: FileLibrary[];
  207. pagination: {
  208. current: number;
  209. pageSize: number;
  210. total: number;
  211. };
  212. };
  213. }
  214. interface FileSaveResponse {
  215. message: string;
  216. data: FileLibrary;
  217. }
  218. interface FileInfoResponse {
  219. message: string;
  220. data: FileLibrary;
  221. }
  222. interface FileDeleteResponse {
  223. message: string;
  224. }
  225. interface FileCategoryListResponse {
  226. data: FileCategory[];
  227. total: number;
  228. page: number;
  229. pageSize: number;
  230. }
  231. interface FileCategoryCreateResponse {
  232. message: string;
  233. data: FileCategory;
  234. }
  235. interface FileCategoryUpdateResponse {
  236. message: string;
  237. data: FileCategory;
  238. }
  239. interface FileCategoryDeleteResponse {
  240. message: string;
  241. }
  242. // 文件API接口定义
  243. export const FileAPI = {
  244. // 获取文件上传策略
  245. getUploadPolicy: async (filename: string, prefix: string = 'uploads/', maxSize: number = 10 * 1024 * 1024): Promise<FileUploadPolicyResponse> => {
  246. try {
  247. const response = await axios.get(`${API_BASE_URL}/upload/policy`, {
  248. params: { filename, prefix, maxSize }
  249. });
  250. return response.data;
  251. } catch (error) {
  252. throw error;
  253. }
  254. },
  255. // 保存文件信息
  256. saveFileInfo: async (fileData: Partial<FileLibrary>): Promise<FileSaveResponse> => {
  257. try {
  258. const response = await axios.post(`${API_BASE_URL}/upload/save`, fileData);
  259. return response.data;
  260. } catch (error) {
  261. throw error;
  262. }
  263. },
  264. // 获取文件列表
  265. getFileList: async (params?: {
  266. page?: number,
  267. pageSize?: number,
  268. category_id?: number,
  269. fileType?: string,
  270. keyword?: string
  271. }): Promise<FileListResponse> => {
  272. try {
  273. const response = await axios.get(`${API_BASE_URL}/upload/list`, { params });
  274. return response.data;
  275. } catch (error) {
  276. throw error;
  277. }
  278. },
  279. // 获取单个文件信息
  280. getFileInfo: async (id: number): Promise<FileInfoResponse> => {
  281. try {
  282. const response = await axios.get(`${API_BASE_URL}/upload/${id}`);
  283. return response.data;
  284. } catch (error) {
  285. throw error;
  286. }
  287. },
  288. // 更新文件下载计数
  289. updateDownloadCount: async (id: number): Promise<FileDeleteResponse> => {
  290. try {
  291. const response = await axios.post(`${API_BASE_URL}/upload/${id}/download`);
  292. return response.data;
  293. } catch (error) {
  294. throw error;
  295. }
  296. },
  297. // 删除文件
  298. deleteFile: async (id: number): Promise<FileDeleteResponse> => {
  299. try {
  300. const response = await axios.delete(`${API_BASE_URL}/upload/${id}`);
  301. return response.data;
  302. } catch (error) {
  303. throw error;
  304. }
  305. },
  306. // 获取文件分类列表
  307. getCategories: async (params?: {
  308. page?: number,
  309. pageSize?: number,
  310. search?: string
  311. }): Promise<FileCategoryListResponse> => {
  312. try {
  313. const response = await axios.get(`${API_BASE_URL}/file-categories`, { params });
  314. return response.data;
  315. } catch (error) {
  316. throw error;
  317. }
  318. },
  319. // 创建文件分类
  320. createCategory: async (data: Partial<FileCategory>): Promise<FileCategoryCreateResponse> => {
  321. try {
  322. const response = await axios.post(`${API_BASE_URL}/file-categories`, data);
  323. return response.data;
  324. } catch (error) {
  325. throw error;
  326. }
  327. },
  328. // 更新文件分类
  329. updateCategory: async (id: number, data: Partial<FileCategory>): Promise<FileCategoryUpdateResponse> => {
  330. try {
  331. const response = await axios.put(`${API_BASE_URL}/file-categories/${id}`, data);
  332. return response.data;
  333. } catch (error) {
  334. throw error;
  335. }
  336. },
  337. // 删除文件分类
  338. deleteCategory: async (id: number): Promise<FileCategoryDeleteResponse> => {
  339. try {
  340. const response = await axios.delete(`${API_BASE_URL}/file-categories/${id}`);
  341. return response.data;
  342. } catch (error) {
  343. throw error;
  344. }
  345. }
  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. };