const { getApiBaseUrl } = require('./constants') function isPublicRequest(url) { return url === '/auth/wx-login' || url === '/auth/public-config' } function normalizeError(message, detail) { const error = new Error(message) error.detail = detail return error } function getFieldLabel(field) { const labels = { nickname: '昵称', real_name: '真实姓名', gender: '性别', birth_year: '出生年份', city: '所在城市', height: '身高', education: '学历', job_industry: '行业', job_company: '公司', income_range: '收入范围', personality_tags: '性格标签', hobbies: '兴趣爱好', wechat_id: '微信号', phone: '手机号', prefer_city: '期望城市', self_intro: '个人介绍', } return labels[field] || field } function normalizeFieldErrorMessage(item) { const fieldLabel = getFieldLabel(item.field) const message = item.message || '参数不合法' if (message.includes('at most') && message.includes('characters')) { const matched = message.match(/at most\s+(\d+)\s+characters/i) if (matched) { return `${fieldLabel}不能超过${matched[1]}个字符` } } if (message.includes('must be') && message.includes('list')) { return `${fieldLabel}必须是数组` } if (message.includes('array') || message.includes('list')) { return `${fieldLabel}必须是数组` } if (message.includes('string')) { return `${fieldLabel}格式不正确` } return `${fieldLabel}${message}` } function executeRequest(options, resolve, reject) { const app = getApp() const token = wx.getStorageSync('token') wx.request({ url: `${getApiBaseUrl()}${options.url}`, method: options.method || 'GET', data: options.data || {}, timeout: options.timeout || 10000, header: { 'Content-Type': 'application/json', Authorization: token ? `Bearer ${token}` : '' }, success(res) { if (res.statusCode === 401) { wx.removeStorageSync('token') wx.removeStorageSync('refresh_token') if (app && typeof app.ensureLogin === 'function' && !options._retry && !isPublicRequest(options.url)) { app.ensureLogin() .then(() => request({ ...options, _retry: true }).then(resolve).catch(reject)) .catch((err) => { wx.showToast({ title: '登录已过期', icon: 'none' }) reject(err || normalizeError('登录已过期')) }) return } wx.showToast({ title: '登录已过期', icon: 'none' }) reject(normalizeError('登录已过期')) return } if (!res.data || res.data.code !== 0) { const detail = res.data || {} const fieldErrors = detail?.data?.field_errors || [] const fieldErrorMessage = fieldErrors.length > 0 ? fieldErrors.map((item) => normalizeFieldErrorMessage(item)).join(';') : '' const message = fieldErrorMessage || detail.message || detail.detail || '请求失败' wx.showToast({ title: message.slice(0, 60), icon: 'none' }) reject(normalizeError(message, detail)) return } resolve(res.data.data) }, fail(err) { const message = err && err.errMsg && err.errMsg.includes('url not in domain list') ? '域名未配置,请到后台系统设置修改' : '网络异常,请重试' wx.showToast({ title: message, icon: 'none' }) reject(normalizeError(message, err)) } }) } function request(options) { return new Promise((resolve, reject) => { const app = getApp() if (!isPublicRequest(options.url) && app && typeof app.ensureLogin === 'function' && !wx.getStorageSync('token')) { app.ensureLogin() .then(() => executeRequest(options, resolve, reject)) .catch((err) => reject(err)) return } executeRequest(options, resolve, reject) }) } module.exports = request