Files
nxxmdata/backend/config/api-config.js
2025-09-17 19:01:52 +08:00

204 lines
5.3 KiB
JavaScript

/**
* API接口统一配置
* 确保所有接口遵循统一的响应格式和错误处理
*/
const { createSuccessResponse, createErrorResponse, ERROR_CODES } = require('../utils/apiResponse');
// API接口统一配置
const API_CONFIG = {
// 响应格式
responseFormat: {
success: {
status: 'success',
message: '',
data: null
},
error: {
status: 'error',
message: '',
data: null
}
},
// 分页配置
pagination: {
defaultPage: 1,
defaultLimit: 20,
maxLimit: 100
},
// 筛选条件配置
filters: {
// 支持的运算符
operators: ['=', '!=', '>', '>=', '<', '<=', 'LIKE', 'IN', 'BETWEEN'],
// 支持的字段映射
fieldMappings: {
// 动物相关字段
animals: ['name', 'category', 'status', 'birthDate', 'weight', 'penId'],
// 设备相关字段
devices: ['name', 'type', 'status', 'location', 'installDate'],
// 告警相关字段
alerts: ['type', 'level', 'status', 'createTime', 'deviceId', 'animalId']
}
},
// 排序配置
sort: {
defaultField: 'createTime',
defaultOrder: 'DESC',
allowedOrders: ['ASC', 'DESC']
}
};
/**
* 构建统一的API响应
* @param {Object} res - Express响应对象
* @param {*} data - 响应数据
* @param {string} message - 响应消息
* @param {Object} options - 其他选项
*/
const buildSuccessResponse = (res, data = null, message = '操作成功', options = {}) => {
const response = createSuccessResponse(data, message, options);
// 转换为微信小程序兼容格式
const formattedResponse = {
status: 'success',
data: response.data,
message: response.message,
...(options.total !== undefined && { total: options.total }),
...(options.page !== undefined && { page: options.page }),
...(options.limit !== undefined && { limit: options.limit })
};
res.json(formattedResponse);
};
/**
* 构建统一的错误响应
* @param {Object} res - Express响应对象
* @param {string} message - 错误消息
* @param {string} code - 错误代码
* @param {number} statusCode - HTTP状态码
*/
const buildErrorResponse = (res, message = '操作失败', code = 'UNKNOWN_ERROR', statusCode = 500) => {
const response = createErrorResponse(message, code);
// 转换为微信小程序兼容格式
const formattedResponse = {
status: 'error',
message: response.message,
code: response.code,
data: null
};
res.status(statusCode).json(formattedResponse);
};
/**
* 处理分页参数
* @param {Object} req - Express请求对象
* @returns {Object} 分页参数
*/
const handlePagination = (req) => {
const page = Math.max(parseInt(req.query.page) || API_CONFIG.pagination.defaultPage, 1);
const limit = Math.min(
Math.max(parseInt(req.query.limit) || API_CONFIG.pagination.defaultLimit, 1),
API_CONFIG.pagination.maxLimit
);
const offset = (page - 1) * limit;
return { page, limit, offset };
};
/**
* 处理筛选条件
* @param {Object} req - Express请求对象
* @param {Array} allowedFields - 允许筛选的字段
* @returns {Object} 筛选条件
*/
const handleFilters = (req, allowedFields = []) => {
const filters = {};
const queryParams = { ...req.query };
// 移除分页和排序参数
delete queryParams.page;
delete queryParams.limit;
delete queryParams.sort;
delete queryParams.order;
// 处理筛选条件
Object.keys(queryParams).forEach(key => {
if (allowedFields.includes(key) && queryParams[key] !== undefined && queryParams[key] !== '') {
filters[key] = queryParams[key];
}
});
return filters;
};
/**
* 处理排序参数
* @param {Object} req - Express请求对象
* @param {Array} allowedFields - 允许排序的字段
* @returns {Array} 排序数组
*/
const handleSorting = (req, allowedFields = []) => {
const sortField = req.query.sort || API_CONFIG.sort.defaultField;
const sortOrder = req.query.order || API_CONFIG.sort.defaultOrder;
if (allowedFields.includes(sortField) &&
API_CONFIG.sort.allowedOrders.includes(sortOrder.toUpperCase())) {
return [[sortField, sortOrder.toUpperCase()]];
}
return [[API_CONFIG.sort.defaultField, API_CONFIG.sort.defaultOrder]];
};
/**
* 构建MySQL查询条件
* @param {Object} filters - 筛选条件
* @returns {Object} MySQL查询条件
*/
const buildQueryConditions = (filters = {}) => {
const where = {};
const params = [];
Object.keys(filters).forEach(key => {
const value = filters[key];
if (value !== undefined && value !== '') {
// 处理LIKE查询
if (typeof value === 'string' && value.includes('%')) {
where[key] = { [Op.like]: value };
}
// 处理范围查询
else if (typeof value === 'string' && value.includes(',')) {
const [min, max] = value.split(',').map(v => v.trim());
where[key] = { [Op.between]: [min, max] };
}
// 处理IN查询
else if (typeof value === 'string' && value.includes('|')) {
const values = value.split('|').map(v => v.trim());
where[key] = { [Op.in]: values };
}
// 普通等于查询
else {
where[key] = value;
}
}
});
return { where, params };
};
module.exports = {
API_CONFIG,
buildSuccessResponse,
buildErrorResponse,
handlePagination,
handleFilters,
handleSorting,
buildQueryConditions
};