api.ts 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. import Taro from '@tarojs/taro'
  2. import { hc } from 'hono/client'
  3. import type { AuthRoutes, UserRoutes, RoleRoutes, FileRoutes } from '@/server/api'
  4. // API配置
  5. const API_BASE_URL = process.env.TARO_APP_API_BASE_URL || 'http://localhost:3000'
  6. // 完整的API地址
  7. // const BASE_URL = `${API_BASE_URL}/api/${API_VERSION}`
  8. // 创建自定义fetch函数,适配Taro.request
  9. const taroFetch: typeof fetch = async (input, init) => {
  10. const url = typeof input === 'string' ? input : input.url
  11. const method = init?.method || 'GET'
  12. // 构建Taro请求选项
  13. const options: Taro.request.Option = {
  14. url,
  15. method: method as any,
  16. data: init?.body,
  17. header: {
  18. 'Content-Type': 'application/json',
  19. ...Object.fromEntries(new Headers(init?.headers || {}))
  20. }
  21. }
  22. // 添加token
  23. const token = Taro.getStorageSync('token')
  24. if (token) {
  25. options.header = {
  26. ...options.header,
  27. 'Authorization': `Bearer ${token}`
  28. }
  29. }
  30. try {
  31. const response = await Taro.request(options)
  32. const responseHeaders = new Headers();
  33. if (response.header) {
  34. for (const [key, value] of Object.entries(response.header)) {
  35. responseHeaders.set(key, value);
  36. }
  37. }
  38. // 处理204 No Content响应,不设置body
  39. const body = response.statusCode === 204
  40. ? null
  41. : responseHeaders.get('content-type')?.includes('application/json')
  42. ? JSON.stringify(response.data)
  43. : response.data;
  44. return new Response(
  45. body,
  46. {
  47. status: response.statusCode,
  48. statusText: response.errMsg || 'OK',
  49. headers: responseHeaders
  50. }
  51. )
  52. } catch (error) {
  53. console.error('API Error:', error)
  54. Taro.showToast({
  55. title: error.message || '网络错误',
  56. icon: 'none'
  57. })
  58. throw error
  59. }
  60. }
  61. // 创建Hono RPC客户端
  62. const createRpcClient = <T>(basePath: string) => {
  63. return hc<T>(`${API_BASE_URL}`, {
  64. fetch: taroFetch
  65. })
  66. }
  67. // 创建各个模块的RPC客户端
  68. export const authClient = createRpcClient<AuthRoutes>('/').api.v1.auth
  69. export const userClient = createRpcClient<UserRoutes>('/').api.v1.users
  70. export const roleClient = createRpcClient<RoleRoutes>('/').api.v1.roles
  71. export const fileClient = createRpcClient<FileRoutes>('/').api.v1.files