request.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. /**
  2. * 网络请求封装
  3. */
  4. import { t } from './i18n.js'
  5. // 固定的 clientid
  6. const CLIENT_ID = '2f847927afb2b3ebeefc870c13d623f2'
  7. // 基础 URL(从环境变量读取)
  8. const BASE_URL = import.meta.env.VITE_API_BASE_URL
  9. /**
  10. * 获取当前语言环境
  11. * @returns {String} 语言代码(转换为下划线格式,如 zh_CN)
  12. */
  13. const getLanguage = () => {
  14. try {
  15. // 从本地存储获取语言设置,默认为 zh-CN
  16. const locale = uni.getStorageSync('locale') || 'zh-CN'
  17. // 将连字符转换为下划线格式(zh-CN -> zh_CN)
  18. return locale.replace('-', '_')
  19. } catch (e) {
  20. return 'zh_CN'
  21. }
  22. }
  23. /**
  24. * 封装的请求方法
  25. * @param {Object} options - 请求配置
  26. * @param {String} options.url - 请求地址
  27. * @param {String} options.method - 请求方法,默认 GET
  28. * @param {Object} options.data - 请求参数
  29. * @param {Object} options.header - 额外的请求头
  30. * @returns {Promise}
  31. */
  32. const request = (options) => {
  33. return new Promise((resolve, reject) => {
  34. // 获取存储的 token
  35. const token = uni.getStorageSync('token') || ''
  36. // 获取当前语言环境
  37. const language = getLanguage()
  38. // 清理请求参数,移除 undefined、null 和空字符串
  39. const cleanData = {}
  40. if (options.data) {
  41. Object.keys(options.data).forEach(key => {
  42. const value = options.data[key]
  43. // 只添加有效值(非 undefined、非 null、非空字符串)
  44. if (value !== undefined && value !== null && value !== '') {
  45. cleanData[key] = value
  46. }
  47. })
  48. }
  49. uni.request({
  50. url: BASE_URL + options.url,
  51. method: options.method || 'GET',
  52. data: cleanData,
  53. header: {
  54. 'Content-Type': 'application/json',
  55. 'Content-Language': language,
  56. 'clientid': CLIENT_ID,
  57. 'Authorization': 'Bearer ' + token,
  58. ...options.header
  59. },
  60. success: (res) => {
  61. const { code, msg, data, total, rows } = res.data
  62. // 根据状态码处理
  63. switch (code) {
  64. case 200:
  65. // 操作成功,返回数据
  66. if (total !== undefined && rows !== undefined) {
  67. // 分页查询返回体
  68. resolve({
  69. total,
  70. rows,
  71. code,
  72. msg
  73. })
  74. } else {
  75. // 一般返回体
  76. resolve({
  77. code,
  78. msg,
  79. data
  80. })
  81. }
  82. break
  83. case 401:
  84. // 登录失效
  85. uni.showToast({
  86. title: t('common.error.unauthorized'),
  87. icon: 'none',
  88. duration: 2000
  89. })
  90. // 清除 token
  91. uni.removeStorageSync('token')
  92. // 跳转到登录页
  93. setTimeout(() => {
  94. uni.reLaunch({
  95. url: '/pages/login/login'
  96. })
  97. }, 2000)
  98. reject({ code, msg: t('common.error.unauthorized') })
  99. break
  100. case 500:
  101. // 系统错误 - 直接显示后端返回的 msg
  102. uni.showToast({
  103. title: msg || t('common.error.serverError'),
  104. icon: 'none',
  105. duration: 2000
  106. })
  107. reject({ code, msg: msg || t('common.error.serverError') })
  108. break
  109. case 501:
  110. // 提示返回的 msg
  111. uni.showToast({
  112. title: msg || t('common.error.requestFailed'),
  113. icon: 'none',
  114. duration: 2000
  115. })
  116. reject({ code, msg })
  117. break
  118. default:
  119. // 其他状态码
  120. uni.showToast({
  121. title: msg || t('common.error.requestFailed'),
  122. icon: 'none',
  123. duration: 2000
  124. })
  125. reject({ code, msg })
  126. break
  127. }
  128. },
  129. fail: (err) => {
  130. uni.showToast({
  131. title: t('common.error.networkFailed'),
  132. icon: 'none',
  133. duration: 2000
  134. })
  135. reject(err)
  136. }
  137. })
  138. })
  139. }
  140. export default request