api.ts 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. import Taro from '@tarojs/taro'
  2. // API配置
  3. const API_BASE_URL = process.env.TARO_APP_API_BASE_URL || 'http://localhost:3000'
  4. const API_VERSION = process.env.TARO_APP_API_VERSION || 'v1'
  5. // 完整的API地址
  6. const BASE_URL = `${API_BASE_URL}/api/${API_VERSION}`
  7. // 请求拦截器
  8. const requestInterceptor = (options: Taro.request.Option) => {
  9. // 添加token
  10. const token = Taro.getStorageSync('token')
  11. if (token) {
  12. options.header = {
  13. ...options.header,
  14. 'Authorization': `Bearer ${token}`
  15. }
  16. }
  17. // 设置基础URL
  18. options.url = `${BASE_URL}${options.url}`
  19. // 设置默认header
  20. options.header = {
  21. 'Content-Type': 'application/json',
  22. ...options.header
  23. }
  24. return options
  25. }
  26. // 响应拦截器
  27. const responseInterceptor = (response: Taro.request.SuccessCallbackResult<any>) => {
  28. const { statusCode, data } = response
  29. if (statusCode === 200 || statusCode === 201) {
  30. // 检查数据结构,支持后端返回的格式
  31. if (data && data.data) {
  32. return data.data
  33. }
  34. return data
  35. } else if (statusCode === 401) {
  36. // 未授权,清除token并跳转到登录页
  37. Taro.removeStorageSync('token')
  38. Taro.removeStorageSync('userInfo')
  39. Taro.navigateTo({ url: '/pages/login/index' })
  40. throw new Error('请重新登录')
  41. } else {
  42. throw new Error(data.message || '请求失败')
  43. }
  44. }
  45. // 错误处理
  46. const errorHandler = (error: any) => {
  47. console.error('API Error:', error)
  48. Taro.showToast({
  49. title: error.message || '网络错误',
  50. icon: 'none'
  51. })
  52. throw error
  53. }
  54. // 封装请求方法
  55. class ApiClient {
  56. async request(options: Taro.request.Option) {
  57. try {
  58. const finalOptions = requestInterceptor(options)
  59. const response = await Taro.request(finalOptions)
  60. return responseInterceptor(response)
  61. } catch (error) {
  62. errorHandler(error)
  63. }
  64. }
  65. async get(url: string, params?: any) {
  66. return this.request({
  67. url,
  68. method: 'GET',
  69. data: params
  70. })
  71. }
  72. async post(url: string, data?: any) {
  73. return this.request({
  74. url,
  75. method: 'POST',
  76. data
  77. })
  78. }
  79. async put(url: string, data?: any) {
  80. return this.request({
  81. url,
  82. method: 'PUT',
  83. data
  84. })
  85. }
  86. async delete(url: string) {
  87. return this.request({
  88. url,
  89. method: 'DELETE'
  90. })
  91. }
  92. }
  93. // 创建单例实例
  94. export const apiClient = new ApiClient()
  95. // 认证相关API
  96. export const authApi = {
  97. // 密码登录
  98. login: (data: { username: string; password: string }) =>
  99. apiClient.post('/auth/login', data),
  100. // 用户注册
  101. register: (data: { username: string; password: string; email?: string }) =>
  102. apiClient.post('/auth/register', data),
  103. // 获取当前用户信息
  104. getCurrentUser: () =>
  105. apiClient.get('/auth/me'),
  106. // 退出登录
  107. logout: () =>
  108. apiClient.post('/auth/logout')
  109. }
  110. // 用户相关API
  111. export const userApi = {
  112. // 获取用户列表
  113. getUsers: (params?: any) =>
  114. apiClient.get('/users', params),
  115. // 获取单个用户信息
  116. getUser: (id: number) =>
  117. apiClient.get(`/users/${id}`),
  118. // 更新用户信息
  119. updateUser: (id: number, data: any) =>
  120. apiClient.put(`/users/${id}`, data),
  121. // 删除用户
  122. deleteUser: (id: number) =>
  123. apiClient.delete(`/users/${id}`)
  124. }
  125. export default apiClient