// 根据小程序版本自动选择后端地址 function _getBaseUrls() { let envType = 'release'; try { const accountInfo = wx.getAccountInfoSync(); envType = accountInfo.miniProgram.envVersion || 'release'; } catch (e) { // 低版本基础库不支持时默认线上环境 envType = 'release'; } switch (envType) { case 'develop': // 开发版:本地服务 return { baseUrl: 'https://test.muguaclub.cn/clock', staticUrl: 'https://test.muguaclub.cn', h5Url: 'https://test.muguaclub.cn' }; case 'trial': // 体验版:测试环境 return { baseUrl: 'https://test.muguaclub.cn/clock', staticUrl: 'https://test.muguaclub.cn', h5Url: 'https://test.muguaclub.cn' }; case 'release': default: // 线上版:正式环境 return { baseUrl: 'https://m.muguaclub.cn/clock', staticUrl: 'https://m.muguaclub.cn', h5Url: 'https://m.muguaclub.cn' }; } } const _urls = _getBaseUrls(); const BASE_URL = _urls.baseUrl; const STATIC_BASE_URL = _urls.staticUrl; const H5_BASE_URL = _urls.h5Url; let redirectingProfile = false; function goProfile() { if (redirectingProfile) { return; } const pages = getCurrentPages(); const current = pages.length ? pages[pages.length - 1] : null; const route = current && current.route; if (route === 'pages/profile/profile') { return; } redirectingProfile = true; wx.switchTab({ url: '/pages/profile/profile', complete() { setTimeout(() => { redirectingProfile = false; }, 1200); } }); } function request(options) { const { url, method = 'GET', data = {}, auth = true } = options; const isIdempotent = method === 'GET' || method === 'DELETE'; let retried = false; return new Promise((resolve, reject) => { const doRequest = () => { const header = { 'Content-Type': 'application/json' }; const token = wx.getStorageSync('token'); if (auth && token) { header['Authorization'] = 'Bearer ' + token; } wx.request({ url: BASE_URL + url, method, data, header, success(res) { if (res.statusCode >= 200 && res.statusCode < 300) { resolve(res.data); } else if (res.statusCode === 401) { wx.removeStorageSync('token'); if (auth) { goProfile(); } reject(res.data || { error: '未登录' }); } else { reject(res.data || { error: '请求失败' }); } }, fail(err) { // 冷启动时首个请求可能因网络栈未就绪而失败,空闲时对幂等请求自动重试一次 const msg = (err && err.errMsg) || ''; const domainError = /url not in domain list|domain not/i.test(msg); if (!retried && isIdempotent && !domainError) { retried = true; setTimeout(doRequest, 800); return; } reject(err); } }); }; doRequest(); }); } /** * 把计划附件的相对路径转为完整的静态资源 URL。 * 路径格式:attachments/{user_id}/{plan_type}/{period_key}/{filename} */ function planFileUrl(path) { if (!path) return ''; if (/^https?:\/\//i.test(path)) return path; const parts = String(path).replace(/^attachments\//, '').split('/'); if (parts.length < 4) return ''; return STATIC_BASE_URL + '/clock/static/plan/' + parts.slice(0, 4).map(encodeURIComponent).join('/'); } module.exports = { request, planFileUrl, BASE_URL, STATIC_BASE_URL, H5_BASE_URL };