|
|
@@ -0,0 +1,203 @@
|
|
|
+import config from '../config.js'
|
|
|
+
|
|
|
+const BASE_URL = config.API_BASE_URL
|
|
|
+var _dedupMap = {}
|
|
|
+var DEDUP_WINDOW_MS = 3000
|
|
|
+
|
|
|
+function _makeDedupKey(method, url, body) {
|
|
|
+ var bodyStr = ''
|
|
|
+ try { bodyStr = JSON.stringify(body || {}) } catch (e) { bodyStr = '' }
|
|
|
+ return method + '|' + url + '|' + bodyStr
|
|
|
+}
|
|
|
+
|
|
|
+function _tryDedup(method, fullUrl, body) {
|
|
|
+ var key = _makeDedupKey(method, fullUrl, body)
|
|
|
+ var cached = _dedupMap[key]
|
|
|
+ if (cached && Date.now() - cached.ts < DEDUP_WINDOW_MS) {
|
|
|
+ return cached.promise
|
|
|
+ }
|
|
|
+ return null
|
|
|
+}
|
|
|
+
|
|
|
+function _registerDedup(method, fullUrl, body, promise) {
|
|
|
+ var key = _makeDedupKey(method, fullUrl, body)
|
|
|
+ _dedupMap[key] = { promise: promise, ts: Date.now() }
|
|
|
+ var _cleanup = function() {
|
|
|
+ setTimeout(function() {
|
|
|
+ if (_dedupMap[key] && _dedupMap[key].promise === promise) {
|
|
|
+ delete _dedupMap[key]
|
|
|
+ }
|
|
|
+ }, DEDUP_WINDOW_MS)
|
|
|
+ }
|
|
|
+ promise.then(_cleanup, _cleanup)
|
|
|
+}
|
|
|
+
|
|
|
+function _clearDedup() {
|
|
|
+ _dedupMap = {}
|
|
|
+}
|
|
|
+export { _clearDedup as clearApiDedup }
|
|
|
+
|
|
|
+function request(url, method = 'POST', data = {}, options = {}) {
|
|
|
+ var fullUrl = BASE_URL + url
|
|
|
+ const token = uni.getStorageSync('token')
|
|
|
+ var key = _makeDedupKey(method, fullUrl, data)
|
|
|
+ if (!options._skipDedup) {
|
|
|
+ var cached = _tryDedup(method, fullUrl, data)
|
|
|
+ if (cached) {
|
|
|
+ return cached
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ var _promise = new Promise((resolve, reject) => {
|
|
|
+ uni.request({
|
|
|
+ url: fullUrl,
|
|
|
+ method: method,
|
|
|
+ data: data,
|
|
|
+ header: {
|
|
|
+ 'Content-Type': 'application/json',
|
|
|
+ 'Authorization': token ? 'Bearer ' + token : ''
|
|
|
+ },
|
|
|
+ success: function(res) {
|
|
|
+ if (res.statusCode === 401) {
|
|
|
+ uni.login({
|
|
|
+ provider: 'weixin',
|
|
|
+ success: function(loginRes) {
|
|
|
+ if (loginRes && loginRes.code) {
|
|
|
+ silentLogin(loginRes.code).then(function(sr) {
|
|
|
+ if (sr && sr.data && sr.data.token) {
|
|
|
+ uni.setStorageSync('token', sr.data.token)
|
|
|
+ uni.setStorageSync('openid', sr.data.openid)
|
|
|
+ resolve(sr.data)
|
|
|
+ } else {
|
|
|
+ uni.showToast({ title: '登录已过期,请重新进入', icon: 'none' })
|
|
|
+ reject(res.data)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if (res.data && res.data.code === 200) {
|
|
|
+ resolve(res.data)
|
|
|
+ } else {
|
|
|
+ var msg = res.data && res.data.message ? res.data.message : '请求失败'
|
|
|
+ uni.showToast({ title: msg, icon: 'none' })
|
|
|
+ reject(res.data)
|
|
|
+ }
|
|
|
+ },
|
|
|
+ fail: function(err) {
|
|
|
+ console.error('[API] 网络错误 ' + method + ' ' + fullUrl, err)
|
|
|
+ uni.showToast({ title: '网络请求失败', icon: 'none' })
|
|
|
+ reject(err)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ })
|
|
|
+
|
|
|
+ if (!options._skipDedup) {
|
|
|
+ _registerDedup(method, fullUrl, data, _promise)
|
|
|
+ }
|
|
|
+
|
|
|
+ return _promise
|
|
|
+}
|
|
|
+
|
|
|
+// ===== 认证 =====
|
|
|
+export const silentLogin = (code, options) => {
|
|
|
+ return request('/api/auth/silent-login', 'POST', { code }, options || {})
|
|
|
+}
|
|
|
+
|
|
|
+export const wechatLogin = (code, userInfo) => {
|
|
|
+ return request('/api/auth/wechat-login', 'POST', { code, nickname: userInfo.nickname, avatar: userInfo.avatar })
|
|
|
+}
|
|
|
+
|
|
|
+export const getUserInfo = () => {
|
|
|
+ return request('/api/user/info', 'POST', {})
|
|
|
+}
|
|
|
+
|
|
|
+// ===== 减脂专题 API =====
|
|
|
+// 体重
|
|
|
+export const getWeightList = (memberId, startDate, endDate) => {
|
|
|
+ var data = {}
|
|
|
+ if (memberId) data.memberId = memberId
|
|
|
+ if (startDate) data.startDate = startDate
|
|
|
+ if (endDate) data.endDate = endDate
|
|
|
+ return request('/api/fatloss/weight/list', 'POST', data)
|
|
|
+}
|
|
|
+
|
|
|
+export const createWeightRecord = (data) => {
|
|
|
+ return request('/api/fatloss/weight/create', 'POST', data)
|
|
|
+}
|
|
|
+
|
|
|
+export const updateWeightRecord = (data) => {
|
|
|
+ return request('/api/fatloss/weight/update', 'POST', data)
|
|
|
+}
|
|
|
+
|
|
|
+export const deleteWeightRecord = (id) => {
|
|
|
+ return request('/api/fatloss/weight/delete', 'POST', { id: id })
|
|
|
+}
|
|
|
+
|
|
|
+// 饮食
|
|
|
+export const getDietList = (memberId, startDate, endDate) => {
|
|
|
+ var data = {}
|
|
|
+ if (memberId) data.memberId = memberId
|
|
|
+ if (startDate) data.startDate = startDate
|
|
|
+ if (endDate) data.endDate = endDate
|
|
|
+ return request('/api/fatloss/diet/list', 'POST', data)
|
|
|
+}
|
|
|
+
|
|
|
+export const createDietRecord = (data) => {
|
|
|
+ return request('/api/fatloss/diet/create', 'POST', data)
|
|
|
+}
|
|
|
+
|
|
|
+export const deleteDietRecord = (id) => {
|
|
|
+ return request('/api/fatloss/diet/delete', 'POST', { id: id })
|
|
|
+}
|
|
|
+
|
|
|
+export const getCaloriesSummary = (date) => {
|
|
|
+ var data = {}
|
|
|
+ if (date) data.date = date
|
|
|
+ return request('/api/fatloss/diet/calories-summary', 'POST', data)
|
|
|
+}
|
|
|
+
|
|
|
+// 运动
|
|
|
+export const getExerciseList = (memberId, startDate, endDate) => {
|
|
|
+ var data = {}
|
|
|
+ if (memberId) data.memberId = memberId
|
|
|
+ if (startDate) data.startDate = startDate
|
|
|
+ if (endDate) data.endDate = endDate
|
|
|
+ return request('/api/fatloss/exercise/list', 'POST', data)
|
|
|
+}
|
|
|
+
|
|
|
+export const createExerciseRecord = (data) => {
|
|
|
+ return request('/api/fatloss/exercise/create', 'POST', data)
|
|
|
+}
|
|
|
+
|
|
|
+export const deleteExerciseRecord = (id) => {
|
|
|
+ return request('/api/fatloss/exercise/delete', 'POST', { id: id })
|
|
|
+}
|
|
|
+
|
|
|
+// 目标
|
|
|
+export const getActiveGoal = () => {
|
|
|
+ return request('/api/fatloss/goal/active', 'POST', {})
|
|
|
+}
|
|
|
+
|
|
|
+export const createGoal = (data) => {
|
|
|
+ return request('/api/fatloss/goal/create', 'POST', data)
|
|
|
+}
|
|
|
+
|
|
|
+export const updateGoal = (data) => {
|
|
|
+ return request('/api/fatloss/goal/update', 'POST', data)
|
|
|
+}
|
|
|
+
|
|
|
+export const completeGoal = (id) => {
|
|
|
+ return request('/api/fatloss/goal/complete', 'POST', { id: id })
|
|
|
+}
|
|
|
+
|
|
|
+export const abandonGoal = (id) => {
|
|
|
+ return request('/api/fatloss/goal/abandon', 'POST', { id: id })
|
|
|
+}
|
|
|
+
|
|
|
+// ===== AI 教练(走主系统 AiGateway) =====
|
|
|
+export const aiCoachSend = (data) => {
|
|
|
+ return request('/api/ai/health-coach/send', 'POST', data)
|
|
|
+}
|