/** * 数据处理工具类 * 用于统一处理前后端数据结构差异 * * 创建日期:2026-01-09 * 用途:避免重复的数据解析代码,提高开发效率 */ /** * 统一解析列表数据 * 兼容多种响应格式: * - 直接数组:[...] * - 带records:{ records: [...] } * - 嵌套data:{ data: { records: [...] } } * * @param {*} res - 接口响应数据 * @returns {Array} 解析后的数组 */ export function getRecords(res) { // 1. 直接是数组 if (Array.isArray(res)) { return res } // 2. res.records if (res && res.records) { return Array.isArray(res.records) ? res.records : [] } // 3. res.data.records if (res && res.data && res.data.records) { return Array.isArray(res.data.records) ? res.data.records : [] } // 4. res.data 是数组 if (res && res.data && Array.isArray(res.data)) { return res.data } // 5. 都不是,返回空数组 console.warn('无法解析records,返回空数组', res) return [] } /** * 获取字段值(兼容多种命名方式) * 支持驼峰、下划线、首字母大写等多种命名 * * @param {Object} obj - 对象 * @param {...string} keys - 可能的字段名(按优先级) * @returns {*} 字段值,如果都不存在返回 null * * @example * const orderNo = getField(order, 'orderNo', 'order_no', 'OrderNo') */ export function getField(obj, ...keys) { if (!obj) return null for (let key of keys) { if (obj[key] !== undefined && obj[key] !== null) { return obj[key] } } return null } /** * 获取字段值(带默认值) * * @param {Object} obj - 对象 * @param {*} defaultValue - 默认值 * @param {...string} keys - 可能的字段名 * @returns {*} 字段值或默认值 * * @example * const name = getFieldOr(user, '未知', 'name', 'userName', 'user_name') */ export function getFieldOr(obj, defaultValue, ...keys) { const value = getField(obj, ...keys) return value !== null ? value : defaultValue } /** * 格式化日期时间 * * @param {string|Date} datetime - 日期时间 * @param {string} format - 格式(默认:'YYYY-MM-DD HH:mm:ss') * @returns {string} 格式化后的字符串 */ export function formatDateTime(datetime, format = 'YYYY-MM-DD HH:mm:ss') { if (!datetime) return '' const d = new Date(datetime) if (isNaN(d.getTime())) return '' const year = d.getFullYear() const month = String(d.getMonth() + 1).padStart(2, '0') const day = String(d.getDate()).padStart(2, '0') const hours = String(d.getHours()).padStart(2, '0') const minutes = String(d.getMinutes()).padStart(2, '0') const seconds = String(d.getSeconds()).padStart(2, '0') return format .replace('YYYY', year) .replace('MM', month) .replace('DD', day) .replace('HH', hours) .replace('mm', minutes) .replace('ss', seconds) } /** * 格式化金额 * * @param {number|string} amount - 金额 * @param {number} decimals - 小数位数(默认:2) * @returns {string} 格式化后的金额 * * @example * formatAmount(1234.5) // '1,234.50' */ export function formatAmount(amount, decimals = 2) { if (amount === null || amount === undefined) return '0.00' const num = parseFloat(amount) if (isNaN(num)) return '0.00' return num.toFixed(decimals).replace(/\B(?=(\d{3})+(?!\d))/g, ',') } /** * 安全的数字转换 * * @param {*} value - 值 * @param {number} defaultValue - 默认值(默认:0) * @returns {number} 数字 */ export function toNumber(value, defaultValue = 0) { if (value === null || value === undefined) return defaultValue const num = parseFloat(value) return isNaN(num) ? defaultValue : num } /** * 安全的整数转换 * * @param {*} value - 值 * @param {number} defaultValue - 默认值(默认:0) * @returns {number} 整数 */ export function toInt(value, defaultValue = 0) { if (value === null || value === undefined) return defaultValue const num = parseInt(value) return isNaN(num) ? defaultValue : num } /** * 解析订单数据(标准化) * * @param {Object} order - 原始订单数据 * @returns {Object} 标准化的订单数据 */ export function parseOrder(order) { if (!order) return null return { id: order.id, orderNo: getFieldOr(order, `ORD${order.id}`, 'orderNo', 'order_no'), serviceName: getFieldOr(order, '陪伴服务', 'serviceName', 'service_name', 'packageName', 'package_name'), serviceDate: getField(order, 'serviceDate', 'service_date'), serviceTime: getField(order, 'serviceTime', 'service_time', 'timeSlot', 'time_slot'), studentName: getFieldOr(order, '学生', 'studentName', 'student_name', 'userName', 'user_name'), grade: getFieldOr(order, '', 'grade'), price: toNumber(getField(order, 'payAmount', 'pay_amount', 'price', 'amount')), status: toInt(getField(order, 'status')), createTime: getField(order, 'createTime', 'create_time'), updateTime: getField(order, 'updateTime', 'update_time') } } /** * 解析排班数据(标准化) * * @param {Object} schedule - 原始排班数据 * @returns {Object} 标准化的排班数据 */ export function parseSchedule(schedule) { if (!schedule) return null // 解析时间段 const timeSlot = getField(schedule, 'timeSlot', 'time_slot', 'timeRange', 'time_range') || '' const parts = timeSlot.split('-') const startTime = parts[0] ? parts[0].trim() : getField(schedule, 'startTime', 'start_time') || '' const endTime = parts[1] ? parts[1].trim() : getField(schedule, 'endTime', 'end_time') || '' // 解析状态 const status = toInt(getField(schedule, 'status')) const statusMap = { 0: { text: '不可用', class: 'unavailable' }, 1: { text: '可预约', class: 'available' }, 2: { text: '已预约', class: 'booked' } } const statusInfo = statusMap[status] || { text: '未知', class: '' } return { id: schedule.id, scheduleDate: getField(schedule, 'scheduleDate', 'schedule_date'), startTime: startTime, endTime: endTime, status: statusInfo.class, statusText: statusInfo.text, statusValue: status } } /** * 解析收益数据(标准化) * * @param {Object} salary - 原始收益数据 * @returns {Object} 标准化的收益数据 */ export function parseSalary(salary) { if (!salary) return null // 解析状态 const status = toInt(getField(salary, 'status')) const statusMap = { 0: '待结算', 1: '已结算', 2: '已发放' } return { id: salary.id, amount: toNumber(getField(salary, 'amount')), actualAmount: toNumber(getField(salary, 'actualAmount', 'actual_amount')), serviceDuration: toInt(getField(salary, 'serviceDuration', 'service_duration', 'duration')), status: status, statusText: statusMap[status] || '未知', workOrderId: getField(salary, 'workOrderId', 'work_order_id'), orderId: getField(salary, 'orderId', 'order_id'), createTime: getField(salary, 'createTime', 'create_time'), settlementTime: getField(salary, 'settlementTime', 'settlement_time') } } /** * 批量解析数据 * * @param {Array} list - 原始数据列表 * @param {Function} parser - 解析函数 * @returns {Array} 解析后的列表 */ export function parseList(list, parser) { if (!Array.isArray(list)) return [] return list.map(item => parser(item)).filter(item => item !== null) } /** * 调试日志(带时间戳和样式) * * @param {string} title - 标题 * @param {*} data - 数据 */ export function debugLog(title, data) { const timestamp = new Date().toLocaleTimeString() console.log(`%c[${timestamp}] ${title}`, 'color: #4CAF50; font-weight: bold;', data) } /** * 错误日志(带时间戳和样式) * * @param {string} title - 标题 * @param {*} error - 错误 */ export function errorLog(title, error) { const timestamp = new Date().toLocaleTimeString() console.error(`%c[${timestamp}] ${title}`, 'color: #F44336; font-weight: bold;', error) } // 默认导出所有方法 export default { getRecords, getField, getFieldOr, formatDateTime, formatAmount, toNumber, toInt, parseOrder, parseSchedule, parseSalary, parseList, debugLog, errorLog }