/** * 系统配置管理API - 后台管理 * 提供系统配置的CRUD操作 */ const Framework = require("../../framework/node-core-framework.js"); const normalizeConfigValue = (config) => { if (!config) { return config; } const normalized = { ...config }; if (normalized.configType === 'json' && normalized.configValue) { normalized.configValue = JSON.parse(normalized.configValue); } else if (normalized.configType === 'boolean') { normalized.configValue = normalized.configValue === 'true' || normalized.configValue === '1'; } else if (normalized.configType === 'number') { normalized.configValue = parseFloat(normalized.configValue) || 0; } return normalized; }; const formatConfigValueForSave = (configType, configValue) => { if (configType === 'json' && typeof configValue === 'object') { return JSON.stringify(configValue); } if (configType === 'boolean') { return configValue ? 'true' : 'false'; } return String(configValue); }; module.exports = { /** * @swagger * /admin_api/config/list: * post: * summary: 获取配置列表 * description: 分页获取系统配置列表 * tags: [后台-系统配置] * requestBody: * required: true * content: * application/json: * schema: * type: object * properties: * page: * type: integer * description: 页码 * pageSize: * type: integer * description: 每页数量 * category: * type: string * description: 配置分类(可选) * responses: * 200: * description: 获取成功 */ 'POST /config/list': async (ctx) => { const models = Framework.getModels(); const { system_config, op } = models; const body = ctx.getBody(); const { category, searchText} = ctx.getBody(); // 获取分页参数 const { limit, offset, page, pageSize } = ctx.getPageSize(); const where = {}; if (category) where.category = category; // 支持搜索配置键或名称 if (searchText) { where[op.or] = [ { configKey: { [op.like]: `%${searchText}%` } }, { configName: { [op.like]: `%${searchText}%` } } ]; } const result = await system_config.findAndCountAll({ where, limit, offset, order: [ ['category', 'ASC'], ['sortOrder', 'ASC'], ['id', 'ASC'] ] }); const list = result.rows.map(item => normalizeConfigValue(item.toJSON())); return ctx.success({ total: result.count, page, pageSize, list }); }, /** * @swagger * /admin_api/config/get: * get: * summary: 获取配置详情 * description: 根据配置键获取配置详情 * tags: [后台-系统配置] * parameters: * - in: query * name: configKey * required: true * schema: * type: string * description: 配置键 * responses: * 200: * description: 获取成功 */ 'GET /config/get': async (ctx) => { const models = Framework.getModels(); const { system_config } = models; const { configKey } = ctx.query; if (!configKey) { return ctx.fail('配置键不能为空'); } const config = await system_config.findOne({ where: { configKey } }); if (!config) { return ctx.fail('配置不存在'); } const configData = normalizeConfigValue(config.toJSON()); return ctx.success(configData); }, /** * @swagger * /admin_api/config/add: * post: * summary: 添加配置 * description: 添加新的系统配置 * tags: [后台-系统配置] * requestBody: * required: true * content: * application/json: * schema: * type: object * required: * - configKey * - configValue * - category * properties: * configKey: * type: string * description: 配置键 * configValue: * type: string * description: 配置值 * configType: * type: string * description: 配置类型 * category: * type: string * description: 配置分类 * configName: * type: string * description: 配置名称 * description: * type: string * description: 配置描述 * responses: * 200: * description: 添加成功 */ 'POST /config/add': async (ctx) => { const models = Framework.getModels(); const { system_config } = models; const body = ctx.getBody(); const { configKey, configValue, configType = 'string', category, configName, description, defaultValue, sortOrder = 0, isActive = true, isSystem = false } = body; if (!configKey || configValue === undefined || !category) { return ctx.fail('配置键、配置值和分类不能为空'); } const existingConfig = await system_config.findOne({ where: { configKey } }); if (existingConfig) { return ctx.fail('配置键已存在'); } const finalValue = formatConfigValueForSave(configType, configValue); await system_config.create({ configKey, configValue: finalValue, configType, category, configName: configName || configKey, description: description || '', defaultValue: defaultValue || finalValue, sortOrder, isActive, isSystem, isVisible: true, }); return ctx.success({ message: '配置添加成功' }); }, /** * @swagger * /admin_api/config/update: * post: * summary: 更新配置 * description: 更新系统配置 * tags: [后台-系统配置] * requestBody: * required: true * content: * application/json: * schema: * type: object * required: * - configKey * properties: * configKey: * type: string * description: 配置键 * configValue: * type: string * description: 配置值 * description: * type: string * description: 配置描述 * responses: * 200: * description: 更新成功 */ 'POST /config/update': async (ctx) => { const models = Framework.getModels(); const { system_config } = models; const body = ctx.getBody(); const { configKey, configValue, configName, description, sortOrder, isActive } = body; if (!configKey) { return ctx.fail('配置键不能为空'); } const config = await system_config.findOne({ where: { configKey } }); if (!config) { return ctx.fail('配置不存在'); } const updateData = {}; if (configValue !== undefined) { updateData.configValue = formatConfigValueForSave(config.configType, configValue); } if (configName) updateData.configName = configName; if (description) updateData.description = description; if (sortOrder !== undefined) updateData.sortOrder = sortOrder; if (isActive !== undefined) updateData.isActive = isActive; await system_config.update(updateData, { where: { configKey } }); return ctx.success({ message: '配置更新成功' }); }, /** * @swagger * /admin_api/config/delete: * post: * summary: 删除配置 * description: 删除系统配置(系统配置不可删除) * tags: [后台-系统配置] * requestBody: * required: true * content: * application/json: * schema: * type: object * required: * - configKey * properties: * configKey: * type: string * description: 配置键 * responses: * 200: * description: 删除成功 */ 'POST /config/delete': async (ctx) => { const models = Framework.getModels(); const { system_config } = models; const body = ctx.getBody(); const { configKey } = body; if (!configKey) { return ctx.fail('配置键不能为空'); } const config = await system_config.findOne({ where: { configKey } }); if (!config) { return ctx.fail('配置不存在'); } if (config.isSystem) { return ctx.fail('系统配置不可删除'); } await system_config.destroy({ where: { configKey } }); return ctx.success({ message: '配置删除成功' }); }, /** * @swagger * /admin_api/config/categories: * get: * summary: 获取配置分类列表 * description: 获取所有配置分类 * tags: [后台-系统配置] * responses: * 200: * description: 获取成功 */ 'GET /config/categories': async (ctx) => { const models = Framework.getModels(); const { system_config } = models; const categories = await system_config.findAll({ attributes: [ 'category', [models.sequelize.fn('COUNT', models.sequelize.col('*')), 'count'] ], group: ['category'], raw: true }); return ctx.success(categories); }, /** * @swagger * /admin_api/config/reset: * post: * summary: 重置配置为默认值 * description: 将配置重置为默认值 * tags: [后台-系统配置] * requestBody: * required: true * content: * application/json: * schema: * type: object * required: * - configKey * properties: * configKey: * type: string * description: 配置键 * responses: * 200: * description: 重置成功 */ 'POST /config/reset': async (ctx) => { const models = Framework.getModels(); const { system_config } = models; const body = ctx.getBody(); const { configKey } = body; if (!configKey) { return ctx.fail('配置键不能为空'); } const config = await system_config.findOne({ where: { configKey } }); if (!config) { return ctx.fail('配置不存在'); } if (!config.defaultValue) { return ctx.fail('该配置没有默认值'); } await system_config.update({ configValue: config.defaultValue, }, { where: { configKey } }); return ctx.success({ message: '配置已重置为默认值' }); }, /** * @swagger * /admin_api/config/batch-update: * post: * summary: 批量更新配置 * description: 批量更新多个配置 * tags: [后台-系统配置] * requestBody: * required: true * content: * application/json: * schema: * type: object * required: * - configs * properties: * configs: * type: array * description: 配置数组 * responses: * 200: * description: 更新成功 */ 'POST /config/batch-update': async (ctx) => { const models = Framework.getModels(); const { system_config } = models; const body = ctx.getBody(); const { configs } = body; if (!configs || !Array.isArray(configs) || configs.length === 0) { return ctx.fail('配置数组不能为空'); } let successCount = 0; let failedCount = 0; for (const item of configs) { const { configKey, configValue } = item; if (!configKey || configValue === undefined) { failedCount++; continue; } const config = await system_config.findOne({ where: { configKey } }); if (!config) { failedCount++; continue; } const finalValue = formatConfigValueForSave(config.configType, configValue); await system_config.update({ configValue: finalValue, }, { where: { configKey } }); successCount++; } return ctx.success({ message: '批量更新完成', total: configs.length, success: successCount, failed: failedCount }); } };