api.js 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. import config from '../config.js'
  2. const BASE_URL = config.API_BASE_URL
  3. var _dedupMap = {}
  4. var DEDUP_WINDOW_MS = 3000
  5. function _makeDedupKey(method, url, body) {
  6. var bodyStr = ''
  7. try { bodyStr = JSON.stringify(body || {}) } catch (e) { bodyStr = '' }
  8. return method + '|' + url + '|' + bodyStr
  9. }
  10. function _tryDedup(method, fullUrl, body) {
  11. var key = _makeDedupKey(method, fullUrl, body)
  12. var cached = _dedupMap[key]
  13. if (cached && Date.now() - cached.ts < DEDUP_WINDOW_MS) {
  14. return cached.promise
  15. }
  16. return null
  17. }
  18. function _registerDedup(method, fullUrl, body, promise) {
  19. var key = _makeDedupKey(method, fullUrl, body)
  20. _dedupMap[key] = { promise: promise, ts: Date.now() }
  21. var _cleanup = function() {
  22. setTimeout(function() {
  23. if (_dedupMap[key] && _dedupMap[key].promise === promise) {
  24. delete _dedupMap[key]
  25. }
  26. }, DEDUP_WINDOW_MS)
  27. }
  28. promise.then(_cleanup, _cleanup)
  29. }
  30. function _clearDedup() {
  31. _dedupMap = {}
  32. }
  33. export { _clearDedup as clearApiDedup }
  34. function request(url, method = 'POST', data = {}, options = {}) {
  35. var fullUrl = BASE_URL + url
  36. const token = uni.getStorageSync('token')
  37. var key = _makeDedupKey(method, fullUrl, data)
  38. if (!options._skipDedup) {
  39. var cached = _tryDedup(method, fullUrl, data)
  40. if (cached) {
  41. return cached
  42. }
  43. }
  44. var _promise = new Promise((resolve, reject) => {
  45. uni.request({
  46. url: fullUrl,
  47. method: method,
  48. data: data,
  49. header: {
  50. 'Content-Type': 'application/json',
  51. 'Authorization': token ? 'Bearer ' + token : ''
  52. },
  53. success: function(res) {
  54. if (res.statusCode === 401) {
  55. uni.login({
  56. provider: 'weixin',
  57. success: function(loginRes) {
  58. if (loginRes && loginRes.code) {
  59. silentLogin(loginRes.code).then(function(sr) {
  60. if (sr && sr.data && sr.data.token) {
  61. uni.setStorageSync('token', sr.data.token)
  62. uni.setStorageSync('openid', sr.data.openid)
  63. resolve(sr.data)
  64. } else {
  65. uni.showToast({ title: '登录已过期,请重新进入', icon: 'none' })
  66. reject(res.data)
  67. }
  68. })
  69. }
  70. }
  71. })
  72. return
  73. }
  74. if (res.data && res.data.code === 200) {
  75. resolve(res.data)
  76. } else {
  77. var msg = res.data && res.data.message ? res.data.message : '请求失败'
  78. uni.showToast({ title: msg, icon: 'none' })
  79. reject(res.data)
  80. }
  81. },
  82. fail: function(err) {
  83. console.error('[API] 网络错误 ' + method + ' ' + fullUrl, err)
  84. uni.showToast({ title: '网络请求失败', icon: 'none' })
  85. reject(err)
  86. }
  87. })
  88. })
  89. if (!options._skipDedup) {
  90. _registerDedup(method, fullUrl, data, _promise)
  91. }
  92. return _promise
  93. }
  94. // ===== 认证 =====
  95. export const silentLogin = (code, options) => {
  96. return request('/api/auth/silent-login', 'POST', { code }, options || {})
  97. }
  98. export const wechatLogin = (code, userInfo) => {
  99. return request('/api/auth/wechat-login', 'POST', { code, nickname: userInfo.nickname, avatar: userInfo.avatar })
  100. }
  101. export const getUserInfo = () => {
  102. return request('/api/user/info', 'POST', {})
  103. }
  104. // ===== 减脂专题 API =====
  105. // 体重
  106. export const getWeightList = (memberId, startDate, endDate) => {
  107. var data = {}
  108. if (memberId) data.memberId = memberId
  109. if (startDate) data.startDate = startDate
  110. if (endDate) data.endDate = endDate
  111. return request('/api/fatloss/weight/list', 'POST', data)
  112. }
  113. export const createWeightRecord = (data) => {
  114. return request('/api/fatloss/weight/create', 'POST', data)
  115. }
  116. export const updateWeightRecord = (data) => {
  117. return request('/api/fatloss/weight/update', 'POST', data)
  118. }
  119. export const deleteWeightRecord = (id) => {
  120. return request('/api/fatloss/weight/delete', 'POST', { id: id })
  121. }
  122. // 饮食
  123. export const getDietList = (memberId, startDate, endDate) => {
  124. var data = {}
  125. if (memberId) data.memberId = memberId
  126. if (startDate) data.startDate = startDate
  127. if (endDate) data.endDate = endDate
  128. return request('/api/fatloss/diet/list', 'POST', data)
  129. }
  130. export const createDietRecord = (data) => {
  131. return request('/api/fatloss/diet/create', 'POST', data)
  132. }
  133. export const deleteDietRecord = (id) => {
  134. return request('/api/fatloss/diet/delete', 'POST', { id: id })
  135. }
  136. export const getCaloriesSummary = (date) => {
  137. var data = {}
  138. if (date) data.date = date
  139. return request('/api/fatloss/diet/calories-summary', 'POST', data)
  140. }
  141. // 运动
  142. export const getExerciseList = (memberId, startDate, endDate) => {
  143. var data = {}
  144. if (memberId) data.memberId = memberId
  145. if (startDate) data.startDate = startDate
  146. if (endDate) data.endDate = endDate
  147. return request('/api/fatloss/exercise/list', 'POST', data)
  148. }
  149. export const createExerciseRecord = (data) => {
  150. return request('/api/fatloss/exercise/create', 'POST', data)
  151. }
  152. export const deleteExerciseRecord = (id) => {
  153. return request('/api/fatloss/exercise/delete', 'POST', { id: id })
  154. }
  155. // 目标
  156. export const getActiveGoal = () => {
  157. return request('/api/fatloss/goal/active', 'POST', {})
  158. }
  159. export const createGoal = (data) => {
  160. return request('/api/fatloss/goal/create', 'POST', data)
  161. }
  162. export const updateGoal = (data) => {
  163. return request('/api/fatloss/goal/update', 'POST', data)
  164. }
  165. export const completeGoal = (id) => {
  166. return request('/api/fatloss/goal/complete', 'POST', { id: id })
  167. }
  168. export const abandonGoal = (id) => {
  169. return request('/api/fatloss/goal/abandon', 'POST', { id: id })
  170. }
  171. // ===== AI 教练(走主系统 AiGateway) =====
  172. export const aiCoachSend = (data) => {
  173. return request('/api/ai/health-coach/send', 'POST', data)
  174. }