207 lines
5.9 KiB
JavaScript
207 lines
5.9 KiB
JavaScript
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 };
|