const { API_BASE_URL } = require('../config'); function buildUrl(path) { if (!path) return ''; if (/^https?:\/\//i.test(path)) return path; if (API_BASE_URL) return API_BASE_URL + path; return path; } function getToken() { return wx.getStorageSync('token') || ''; } function request(options) { const { url, method = 'GET', data, header = {} } = options || {}; return new Promise((resolve, reject) => { wx.request({ url: buildUrl(url), method, data, header: { 'Content-Type': 'application/json', Authorization: getToken() ? `Bearer ${getToken()}` : '', ...header }, success(res) { if (res.statusCode === 401 || res.statusCode === 403) { wx.removeStorageSync('token'); wx.reLaunch({ url: '/pages/login/login' }); } resolve(res.data || { success: false, message: '响应为空' }); }, fail(err) { reject(err); } }); }); } function uploadFile(options) { const { url, filePath, name = 'file', formData = {} } = options || {}; return new Promise((resolve, reject) => { wx.uploadFile({ url: buildUrl(url), filePath, name, formData, header: { Authorization: getToken() ? `Bearer ${getToken()}` : '' }, success(res) { try { const data = JSON.parse(res.data || '{}'); resolve(data); } catch (e) { resolve({ success: false, message: '解析响应失败' }); } }, fail(err) { reject(err); } }); }); } function downloadFile(options) { const { url } = options || {}; return new Promise((resolve, reject) => { wx.downloadFile({ url: buildUrl(url), header: { Authorization: getToken() ? `Bearer ${getToken()}` : '' }, success(res) { if (res.statusCode === 200) { resolve(res.tempFilePath); return; } reject(new Error('下载失败')); }, fail(err) { reject(err); } }); }); } function normalizeResponse(raw) { if (raw && typeof raw === 'object' && !Array.isArray(raw)) { const hasData = Object.prototype.hasOwnProperty.call(raw, 'data'); const hasCode = typeof raw.code === 'number'; const hasSuccess = typeof raw.success === 'boolean'; const hasMessage = typeof raw.message === 'string'; if (hasData && (hasCode || hasSuccess || hasMessage)) { return { payload: raw.data, meta: { code: raw.code, success: raw.success, message: raw.message } }; } } return { payload: raw, meta: null }; } function pickArray(obj) { if (!obj || typeof obj !== 'object') return null; const keys = ['list', 'items', 'records', 'rows', 'data', 'result']; for (let i = 0; i < keys.length; i += 1) { const value = obj[keys[i]]; if (Array.isArray(value)) return value; } return null; } function buildListCards(list, limit) { return list.slice(0, limit).map((item, index) => { if (item && typeof item === 'object') { const keys = Object.keys(item); const titleKey = keys.find(k => /name|title|id|task_id|book_id|book_name/i.test(k)) || keys[0] || `item_${index + 1}`; const titleValue = item[titleKey] !== undefined && item[titleKey] !== null ? item[titleKey] : titleKey; return { label: String(titleValue), value: `#${index + 1}` }; } return { label: `item_${index + 1}`, value: String(item) }; }); } function buildResultView(raw) { const result = { text: '', cards: [] }; if (raw === null || raw === undefined) return result; const normalized = normalizeResponse(raw); const payload = normalized.payload; if (payload === undefined && normalized.meta && normalized.meta.message) { result.text = normalized.meta.message; } else if (typeof payload === 'string') { result.text = payload; } else { try { result.text = JSON.stringify(payload, null, 2); } catch (e) { result.text = String(payload); } } let parsed = payload; if (typeof payload === 'string') { try { parsed = JSON.parse(payload); } catch (e) { parsed = null; } } if (parsed && typeof parsed === 'object') { const metaCards = []; if (normalized.meta) { if (typeof normalized.meta.code === 'number') { metaCards.push({ label: 'code', value: String(normalized.meta.code) }); } if (typeof normalized.meta.success === 'boolean') { metaCards.push({ label: 'success', value: String(normalized.meta.success) }); } if (normalized.meta.message) { metaCards.push({ label: 'message', value: String(normalized.meta.message) }); } } if (Array.isArray(parsed)) { result.cards = metaCards.concat(buildListCards(parsed, 6)); return result; } const list = pickArray(parsed); if (list) { const headerCards = []; if (parsed.total !== undefined && parsed.total !== null) { headerCards.push({ label: 'total', value: String(parsed.total) }); } if (parsed.page !== undefined && parsed.page !== null) { headerCards.push({ label: 'page', value: String(parsed.page) }); } if (parsed.page_size !== undefined && parsed.page_size !== null) { headerCards.push({ label: 'page_size', value: String(parsed.page_size) }); } if (parsed.pageSize !== undefined && parsed.pageSize !== null) { headerCards.push({ label: 'pageSize', value: String(parsed.pageSize) }); } result.cards = metaCards.concat(headerCards, buildListCards(list, 6)); return result; } const keys = Object.keys(parsed); result.cards = metaCards.concat(keys.slice(0, 8).map(key => ({ label: key, value: typeof parsed[key] === 'object' ? '对象' : String(parsed[key]) }))); } return result; } module.exports = { request, uploadFile, downloadFile, buildUrl, buildResultView, normalizeResponse };