204 lines
5.3 KiB
JavaScript
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
|
|
}; |