diff --git a/schoolNewsServ/.bin/mysql/sql/createTableSystem.sql b/schoolNewsServ/.bin/mysql/sql/createTableSystem.sql index c979ff1..2d97c5e 100644 --- a/schoolNewsServ/.bin/mysql/sql/createTableSystem.sql +++ b/schoolNewsServ/.bin/mysql/sql/createTableSystem.sql @@ -32,10 +32,20 @@ DROP TABLE IF EXISTS `tb_sys_config`; CREATE TABLE `tb_sys_config` ( `id` VARCHAR(50) NOT NULL COMMENT '配置ID', `config_key` VARCHAR(100) NOT NULL COMMENT '配置键', + `config_name` VARCHAR(100) DEFAULT NULL COMMENT '配置显示名称', `config_value` TEXT COMMENT '配置值', - `config_type` VARCHAR(50) DEFAULT 'string' COMMENT '配置类型(string/number/boolean/json)', + `config_type` VARCHAR(50) DEFAULT 'string' COMMENT '数据类型(string/number/boolean/json)', + `render_type` VARCHAR(20) DEFAULT NULL COMMENT '前端渲染类型(input/textarea/number/switch/select/password)', `config_group` VARCHAR(50) DEFAULT NULL COMMENT '配置分组', `description` VARCHAR(255) DEFAULT NULL COMMENT '配置描述', + `placeholder` VARCHAR(200) DEFAULT NULL COMMENT '输入框占位符', + `remark` VARCHAR(500) DEFAULT NULL COMMENT '备注说明(显示在表单项下方)', + `rows` INT DEFAULT NULL COMMENT '文本框行数(textarea用)', + `min_value` INT DEFAULT NULL COMMENT '最小值(number用)', + `max_value` INT DEFAULT NULL COMMENT '最大值(number用)', + `unit` VARCHAR(20) DEFAULT NULL COMMENT '单位(number用)', + `options` TEXT COMMENT '下拉选项(select用,JSON格式)', + `order_num` INT DEFAULT 0 COMMENT '排序号', `is_system` TINYINT(1) DEFAULT 0 COMMENT '是否系统配置', `creator` VARCHAR(50) DEFAULT NULL COMMENT '创建者', `updater` VARCHAR(50) DEFAULT NULL COMMENT '更新者', @@ -45,7 +55,8 @@ CREATE TABLE `tb_sys_config` ( `deleted` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否删除', PRIMARY KEY (`id`), UNIQUE KEY `uk_config_key` (`config_key`), - KEY `idx_group` (`config_group`) + KEY `idx_group` (`config_group`), + KEY `idx_order` (`order_num`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='系统配置表'; diff --git a/schoolNewsServ/.bin/mysql/sql/initAllData.sql b/schoolNewsServ/.bin/mysql/sql/initAllData.sql index 4046c9a..f155b8b 100644 --- a/schoolNewsServ/.bin/mysql/sql/initAllData.sql +++ b/schoolNewsServ/.bin/mysql/sql/initAllData.sql @@ -25,22 +25,9 @@ INSERT INTO `tb_tag` (id, tag_id, name, color, description, tag_type, creator, c ('tag205', 'tag_task_005', '阶段任务', '#2d98da', '阶段性学习任务', 3, '1', now()); -- 插入系统配置数据 -INSERT INTO `tb_sys_config` (id, config_key, config_value, config_type, config_group, description, is_system, creator, create_time) VALUES -('1', 'system.platform.name', '思政学习平台', 'string', 'platform', '平台名称', 1, '1', now()), -('2', 'system.platform.logo', '/assets/logo.png', 'string', 'platform', '平台Logo', 1, '1', now()), -('3', 'system.platform.school_badge', '/assets/school_badge.png', 'string', 'platform', '学校校徽', 1, '1', now()), -('4', 'system.menu.home', '首页', 'string', 'menu', '首页菜单名称', 0, '1', now()), -('5', 'system.menu.resource', '资源中心', 'string', 'menu', '资源中心菜单名称', 0, '1', now()), -('6', 'system.menu.learning', '学习计划', 'string', 'menu', '学习计划菜单名称', 0, '1', now()), -('7', 'system.menu.activity', '专题活动', 'string', 'menu', '专题活动菜单名称', 0, '1', now()), -('8', 'system.menu.culture', '红色常信', 'string', 'menu', '红色常信菜单名称', 0, '1', now()), -('9', 'system.banner.auto_play', 'true', 'boolean', 'banner', 'Banner自动播放', 0, '1', now()), -('10', 'system.banner.interval', '5000', 'number', 'banner', 'Banner切换间隔(毫秒)', 0, '1', now()), -('11', 'system.resource.auto_publish', 'false', 'boolean', 'resource', '资源自动发布', 0, '1', now()), -('12', 'system.resource.auto_publish_time', '08:00', 'string', 'resource', '自动发布时间', 0, '1', now()), -('13', 'system.ai.enabled', 'true', 'boolean', 'ai', '是否启用智能体', 0, '1', now()), -('14', 'crawler.pythonPath', 'F:/Environment/Conda/envs/schoolNewsCrawler/python.exe', 'string', 'crawler', 'Python可执行文件路径', 1, '1', now()), -('15', 'crawler.basePath', 'F:/Project/schoolNews/schoolNewsCrawler', 'string', 'crawler', '爬虫脚本根目录', 1, '1', now()); +INSERT INTO `tb_sys_config` (`id`, `config_key`, `config_name`, `config_value`, `config_type`, `render_type`, `config_group`, `description`, `placeholder`, `remark`, `rows`, `min_value`, `max_value`, `unit`, `options`, `order_num`, `is_system`, `creator`, `create_time`) VALUES +('1', 'crawler.pythonPath', 'Python路径', 'F:/Environment/Conda/envs/schoolNewsCrawler/python.exe', 'string', 'input', '爬虫配置', 'Python可执行文件路径', '请输入Python可执行文件完整路径', '爬虫使用的Python解释器路径', NULL, NULL, NULL, NULL, NULL, 1, 1, '1', now()), +('2', 'crawler.basePath', '爬虫根目录', 'F:/Project/schoolNews/schoolNewsCrawler', 'string', 'input', '爬虫配置', '爬虫脚本根目录', '请输入爬虫脚本根目录路径', '爬虫脚本文件的根目录', NULL, NULL, NULL, NULL, NULL, 2, 1, '1', now()); -- 注意:默认superadmin用户已在 initMenuData.sql 中创建,此处无需重复创建 diff --git a/schoolNewsServ/.bin/mysql/sql/initMenuData.sql b/schoolNewsServ/.bin/mysql/sql/initMenuData.sql index 86f5213..ab660c0 100644 --- a/schoolNewsServ/.bin/mysql/sql/initMenuData.sql +++ b/schoolNewsServ/.bin/mysql/sql/initMenuData.sql @@ -157,12 +157,11 @@ INSERT INTO `tb_sys_menu` VALUES ('6000', 'menu_admin_ai_manage', '智能体管理', NULL, '', '', 'admin/agent.svg', 6, 0, 'SidebarLayout', '1', NULL, '2025-10-27 17:26:06', '2025-10-29 11:52:50', NULL, 0), ('6002', 'menu_admin_ai_config', 'AI配置', 'menu_admin_ai_manage', '/admin/manage/ai/config', 'admin/manage/ai/AIConfigView', NULL, 2, 0, 'SidebarLayout', '1', NULL, '2025-10-27 17:26:06', '2025-10-29 11:48:39', NULL, 0), ('6003', 'menu_admin_knowledge', '知识库管理', 'menu_admin_ai_manage', '/admin/manage/ai/knowledge', 'admin/manage/ai/KnowledgeManagementView', NULL, 3, 0, 'SidebarLayout', '1', NULL, '2025-10-27 17:26:06', '2025-10-29 11:48:39', NULL, 0), -('7000', 'menu_admin_logs_manage', '系统日志', NULL, '', '', 'admin/logs.svg', 7, 0, 'SidebarLayout', '1', NULL, '2025-10-27 17:26:06', '2025-10-29 11:52:53', NULL, 0), +('7000', 'menu_admin_logs_manage', '系统日志', 'menu_sys_manage', '', '', NULL, 6, 0, 'SidebarLayout', '1', NULL, '2025-10-27 17:26:06', '2025-10-29 11:52:53', NULL, 0), ('7001', 'menu_admin_system_logs', '系统日志', 'menu_admin_logs_manage', '/admin/manage/logs/system', 'admin/manage/logs/SystemLogsView', NULL, 1, 0, 'SidebarLayout', '1', NULL, '2025-10-27 17:26:06', '2025-10-29 11:48:39', NULL, 0), ('7002', 'menu_admin_login_logs', '登录日志', 'menu_admin_logs_manage', '/admin/manage/logs/login', 'admin/manage/logs/LoginLogsView', NULL, 2, 0, 'SidebarLayout', '1', NULL, '2025-10-27 17:26:06', '2025-10-29 11:48:39', NULL, 0), --- ('7003', 'menu_admin_operation_logs', '操作日志', 'menu_admin_logs_manage', '/admin/manage/logs/operation', 'admin/manage/logs/OperationLogsView', NULL, 3, 0, 'SidebarLayout', '1', NULL, '2025-10-27 17:26:06', '2025-10-29 11:48:39', NULL, 0), --- ('7004', 'menu_admin_system_config', '系统配置', 'menu_admin_logs_manage', '/admin/manage/logs/config', 'admin/manage/logs/SystemConfigView', NULL, 4, 0, 'SidebarLayout', '1', NULL, '2025-10-27 17:26:06', '2025-10-29 11:48:39', NULL, 0), -('8000', 'menu_admin_crontab_manage', '定时任务管理', NULL, '', '', NULL, 8, 0, 'SidebarLayout', '1', '/admin/crontab.svg', '2025-10-27 17:26:06', '2025-10-29 11:48:39', NULL, 0), +('7003', 'menu_admin_system_config', '系统配置', 'menu_sys_manage', '/admin/manage/system/config', 'admin/manage/system/SystemConfigView', NULL, 7, 0, 'SidebarLayout', '1', NULL, '2025-10-27 17:26:06', '2025-10-29 11:48:39', NULL, 0), +('8000', 'menu_admin_crontab_manage', '定时任务管理', NULL, '', '', 'admin/crontab.svg', 8, 0, 'SidebarLayout', '1', NULL, '2025-10-27 17:26:06', '2025-10-29 11:48:39', NULL, 0), ('8002', 'menu_admin_crontab_log', '执行日志', 'menu_admin_crontab_manage', '/admin/manage/crontab/log', 'admin/manage/crontab/LogManagementView', NULL, 2, 0, 'SidebarLayout', '1', NULL, '2025-10-27 17:26:06', '2025-10-29 11:48:39', NULL, 0), ('8003', 'menu_admin_news_crawler', '新闻爬虫配置', 'menu_admin_crontab_manage', '/admin/manage/crontab/news-crawler', 'admin/manage/crontab/NewsCrawlerView', NULL, 3, 0, 'SidebarLayout', '1', NULL, '2025-10-27 17:26:06', '2025-10-29 11:48:39', NULL, 0), -- 消息通知模块菜单 (9000-9999) @@ -170,6 +169,7 @@ INSERT INTO `tb_sys_menu` VALUES -- 用户端消息中心菜单 (650-699) ('650', 'menu_user_message_center', '消息中心', NULL, '/user/message', 'user/message/MyMessageListView', NULL, 7, 1, 'NavigationLayout', '1', NULL, '2025-11-13 10:00:00', '2025-11-13 10:00:00', NULL, 0), ('651', 'menu_user_message_detail', '消息详情', 'menu_user_message_center', '/user/message/detail/:messageID', 'user/message/MyMessageDetailView', NULL, 1, 3, 'NavigationLayout', '1', NULL, '2025-11-13 10:00:00', '2025-11-13 10:00:00', NULL, 0); + -- 插入菜单权限关联数据 INSERT INTO `tb_sys_menu_permission` (id, permission_id, menu_id, creator, create_time) VALUES -- 前端菜单权限关联 @@ -223,7 +223,6 @@ INSERT INTO `tb_sys_menu_permission` (id, permission_id, menu_id, creator, creat ('227', 'perm_system_manage', 'menu_admin_logs_manage', '1', now()), ('228', 'perm_system_manage', 'menu_admin_system_logs', '1', now()), ('229', 'perm_system_manage', 'menu_admin_login_logs', '1', now()), -('230', 'perm_system_manage', 'menu_admin_operation_logs', '1', now()), ('231', 'perm_system_manage', 'menu_admin_system_config', '1', now()), -- 定时任务管理菜单权限关联 diff --git a/schoolNewsServ/api/api-system/src/main/java/org/xyzh/api/system/config/SysConfigService.java b/schoolNewsServ/api/api-system/src/main/java/org/xyzh/api/system/config/SysConfigService.java index 96eb9a3..2b8ee82 100644 --- a/schoolNewsServ/api/api-system/src/main/java/org/xyzh/api/system/config/SysConfigService.java +++ b/schoolNewsServ/api/api-system/src/main/java/org/xyzh/api/system/config/SysConfigService.java @@ -1,5 +1,12 @@ package org.xyzh.api.system.config; +import org.xyzh.common.core.domain.ResultDomain; +import org.xyzh.common.core.page.PageParam; +import org.xyzh.common.dto.system.TbSysConfig; + +import java.util.List; +import java.util.Map; + /** * @description 系统配置服务 * @filename SysConfigService.java @@ -9,6 +16,8 @@ package org.xyzh.api.system.config; */ public interface SysConfigService { + // ==================== 配置读取接口(业务代码使用) ==================== + Object getSysConfig(String key); /** @@ -45,4 +54,62 @@ public interface SysConfigService { * @return 配置值,如果不存在或解析失败返回null */ Long getLongConfig(String key); + + // ==================== 配置管理接口(管理界面使用) ==================== + + /** + * 获取所有配置项 + * @return 配置项列表 + */ + ResultDomain getAllConfigs(); + + /** + * 根据分组获取配置项 + * @param groupKey 分组键 + * @return 配置项列表 + */ + ResultDomain getConfigsByGroup(String groupKey); + + /** + * 批量保存配置项(仅更新值) + * @param configs 配置项列表 + * @return 保存结果 + */ + ResultDomain batchSaveConfigs(List> configs); + + /** + * 创建配置项 + * @param config 配置项 + * @return 创建结果 + */ + ResultDomain createConfig(TbSysConfig config); + + /** + * 更新配置项 + * @param config 配置项 + * @return 更新结果 + */ + ResultDomain updateConfig(TbSysConfig config); + + /** + * 删除配置项 + * @param id 配置ID + * @return 删除结果 + */ + ResultDomain deleteConfig(String id); + + /** + * 分页查询配置项 + * @param filter 查询条件 + * @param pageParam 分页参数 + * @return 配置项分页列表 + */ + ResultDomain getConfigPage(TbSysConfig filter, PageParam pageParam); + + /** + * 根据ID获取配置项 + * @param id 配置ID + * @return 配置项详情 + */ + ResultDomain getConfigById(String id); } diff --git a/schoolNewsServ/common/common-dto/src/main/java/org/xyzh/common/dto/system/TbSysConfig.java b/schoolNewsServ/common/common-dto/src/main/java/org/xyzh/common/dto/system/TbSysConfig.java index 3daf0a0..46519e4 100644 --- a/schoolNewsServ/common/common-dto/src/main/java/org/xyzh/common/dto/system/TbSysConfig.java +++ b/schoolNewsServ/common/common-dto/src/main/java/org/xyzh/common/dto/system/TbSysConfig.java @@ -18,16 +18,26 @@ public class TbSysConfig extends BaseDTO { */ private String configKey; + /** + * @description 配置显示名称 + */ + private String configName; + /** * @description 配置值 */ private String configValue; /** - * @description 配置类型(string/number/boolean/json) + * @description 数据类型(string/number/boolean/json) */ private String configType; + /** + * @description 前端渲染类型(input/textarea/number/switch/select/password) + */ + private String renderType; + /** * @description 配置分组 */ @@ -38,6 +48,46 @@ public class TbSysConfig extends BaseDTO { */ private String description; + /** + * @description 输入框占位符 + */ + private String placeholder; + + /** + * @description 备注说明(显示在表单项下方) + */ + private String remark; + + /** + * @description 文本框行数(textarea用) + */ + private Integer rows; + + /** + * @description 最小值(number用) + */ + private Integer minValue; + + /** + * @description 最大值(number用) + */ + private Integer maxValue; + + /** + * @description 单位(number用) + */ + private String unit; + + /** + * @description 下拉选项(select用,JSON格式) + */ + private String options; + + /** + * @description 排序号 + */ + private Integer orderNum; + /** * @description 是否系统配置 */ @@ -117,14 +167,97 @@ public class TbSysConfig extends BaseDTO { this.updater = updater; } + public String getConfigName() { + return configName; + } + + public void setConfigName(String configName) { + this.configName = configName; + } + + public String getRenderType() { + return renderType; + } + + public void setRenderType(String renderType) { + this.renderType = renderType; + } + + public String getPlaceholder() { + return placeholder; + } + + public void setPlaceholder(String placeholder) { + this.placeholder = placeholder; + } + + public String getRemark() { + return remark; + } + + public void setRemark(String remark) { + this.remark = remark; + } + + public Integer getRows() { + return rows; + } + + public void setRows(Integer rows) { + this.rows = rows; + } + + public Integer getMinValue() { + return minValue; + } + + public void setMinValue(Integer minValue) { + this.minValue = minValue; + } + + public Integer getMaxValue() { + return maxValue; + } + + public void setMaxValue(Integer maxValue) { + this.maxValue = maxValue; + } + + public String getUnit() { + return unit; + } + + public void setUnit(String unit) { + this.unit = unit; + } + + public String getOptions() { + return options; + } + + public void setOptions(String options) { + this.options = options; + } + + public Integer getOrderNum() { + return orderNum; + } + + public void setOrderNum(Integer orderNum) { + this.orderNum = orderNum; + } + @Override public String toString() { return "TbSysConfig{" + "id=" + getID() + ", configKey='" + configKey + '\'' + + ", configName='" + configName + '\'' + ", configValue='" + configValue + '\'' + ", configType='" + configType + '\'' + + ", renderType='" + renderType + '\'' + ", configGroup='" + configGroup + '\'' + + ", orderNum=" + orderNum + ", isSystem=" + isSystem + '}'; } diff --git a/schoolNewsServ/system/src/main/java/org/xyzh/system/controller/ConfigController.java b/schoolNewsServ/system/src/main/java/org/xyzh/system/controller/ConfigController.java new file mode 100644 index 0000000..90ec2f3 --- /dev/null +++ b/schoolNewsServ/system/src/main/java/org/xyzh/system/controller/ConfigController.java @@ -0,0 +1,107 @@ +package org.xyzh.system.controller; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import org.xyzh.api.system.config.SysConfigService; +import org.xyzh.common.core.domain.ResultDomain; +import org.xyzh.common.core.page.PageParam; +import org.xyzh.common.core.page.PageRequest; +import org.xyzh.common.dto.system.TbSysConfig; + +import java.util.List; +import java.util.Map; + +/** + * @description 系统配置管理控制器 + * @filename ConfigController.java + * @author yslg + * @copyright xyzh + * @since 2025-11-18 + */ +@RestController +@RequestMapping("/system/config") +public class ConfigController { + + @Autowired + private SysConfigService sysConfigService; + + /** + * @description 获取所有配置项(前端配置视图使用) + * @return ResultDomain 配置项列表 + */ + @GetMapping("/list") + public ResultDomain getAllConfigs() { + return sysConfigService.getAllConfigs(); + } + + /** + * @description 根据分组获取配置项 + * @param groupKey 分组键 + * @return ResultDomain 配置项列表 + */ + @GetMapping("/group/{groupKey}") + public ResultDomain getConfigsByGroup(@PathVariable String groupKey) { + return sysConfigService.getConfigsByGroup(groupKey); + } + + + /** + * @description 保存配置项(批量保存) + * @param configs 配置项列表 + * @return ResultDomain 保存结果 + */ + @PostMapping("/save") + public ResultDomain saveConfigs(@RequestBody List> configs) { + return sysConfigService.batchSaveConfigs(configs); + } + + /** + * @description 创建单个配置项 + * @param config 配置项 + * @return ResultDomain 创建结果 + */ + @PostMapping("/create") + public ResultDomain createConfig(@RequestBody TbSysConfig config) { + return sysConfigService.createConfig(config); + } + + /** + * @description 更新单个配置项 + * @param config 配置项 + * @return ResultDomain 更新结果 + */ + @PutMapping("/update") + public ResultDomain updateConfig(@RequestBody TbSysConfig config) { + return sysConfigService.updateConfig(config); + } + + /** + * @description 删除配置项 + * @param id 配置ID + * @return ResultDomain 删除结果 + */ + @DeleteMapping("/{id}") + public ResultDomain deleteConfig(@PathVariable String id) { + return sysConfigService.deleteConfig(id); + } + + /** + * @description 分页查询配置项 + * @param pageRequest 分页请求 + * @return ResultDomain 配置项分页列表 + */ + @PostMapping("/page") + public ResultDomain getConfigPage(@RequestBody PageRequest pageRequest) { + return sysConfigService.getConfigPage(pageRequest.getFilter(), pageRequest.getPageParam()); + } + + /** + * @description 根据ID获取配置项详情 + * @param id 配置ID + * @return ResultDomain 配置项详情 + */ + @GetMapping("/{id}") + public ResultDomain getConfigById(@PathVariable String id) { + return sysConfigService.getConfigById(id); + } +} diff --git a/schoolNewsServ/system/src/main/java/org/xyzh/system/service/config/impl/SysConfigServiceImpl.java b/schoolNewsServ/system/src/main/java/org/xyzh/system/service/config/impl/SysConfigServiceImpl.java index 182aeac..f5a6ad0 100644 --- a/schoolNewsServ/system/src/main/java/org/xyzh/system/service/config/impl/SysConfigServiceImpl.java +++ b/schoolNewsServ/system/src/main/java/org/xyzh/system/service/config/impl/SysConfigServiceImpl.java @@ -5,9 +5,16 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.xyzh.api.system.config.SysConfigService; +import org.xyzh.common.core.domain.ResultDomain; +import org.xyzh.common.core.page.PageDomain; +import org.xyzh.common.core.page.PageParam; import org.xyzh.common.dto.system.TbSysConfig; import org.xyzh.system.mapper.SysConfigMapper; +import java.util.List; +import java.util.Map; +import java.util.UUID; + /** * @description 系统配置服务实现 * @author AI Assistant @@ -205,4 +212,163 @@ public class SysConfigServiceImpl implements SysConfigService { return null; } } + + // ==================== 配置管理接口实现 ==================== + + @Override + public ResultDomain getAllConfigs() { + ResultDomain resultDomain = new ResultDomain<>(); + try { + List configs = sysConfigMapper.selectAllSysConfig(); + resultDomain.success("查询成功", configs); + return resultDomain; + } catch (Exception e) { + logger.error("获取所有配置失败", e); + resultDomain.fail("获取配置失败: " + e.getMessage()); + return resultDomain; + } + } + + @Override + public ResultDomain getConfigsByGroup(String groupKey) { + ResultDomain resultDomain = new ResultDomain<>(); + try { + List configs = sysConfigMapper.selectSysConfigByGroup(groupKey); + resultDomain.success("查询成功", configs); + return resultDomain; + } catch (Exception e) { + logger.error("根据分组获取配置失败: {}", groupKey, e); + resultDomain.fail("获取配置失败: " + e.getMessage()); + return resultDomain; + } + } + + @Override + public ResultDomain batchSaveConfigs(List> configs) { + ResultDomain resultDomain = new ResultDomain<>(); + try { + for (Map configMap : configs) { + String configKey = configMap.get("configKey"); + String configValue = configMap.get("configValue"); + + TbSysConfig existingConfig = sysConfigMapper.selectSysConfigByKey(configKey); + if (existingConfig != null) { + existingConfig.setConfigValue(configValue); + sysConfigMapper.updateSysConfig(existingConfig); + } else { + logger.warn("配置项不存在,跳过: {}", configKey); + } + } + resultDomain.success("保存成功", true); + return resultDomain; + } catch (Exception e) { + logger.error("批量保存配置失败", e); + resultDomain.fail("保存配置失败: " + e.getMessage()); + return resultDomain; + } + } + + @Override + public ResultDomain createConfig(TbSysConfig config) { + ResultDomain resultDomain = new ResultDomain<>(); + try { + TbSysConfig existingConfig = sysConfigMapper.selectSysConfigByKey(config.getConfigKey()); + if (existingConfig != null) { + resultDomain.fail("配置键已存在: " + config.getConfigKey()); + return resultDomain; + } + + if (config.getID() == null || config.getID().isEmpty()) { + config.setID(UUID.randomUUID().toString()); + } + + int result = sysConfigMapper.insertSysConfig(config); + if (result > 0) { + resultDomain.success("创建成功", true); + return resultDomain; + } else { + resultDomain.fail("创建配置失败"); + return resultDomain; + } + } catch (Exception e) { + logger.error("创建配置失败", e); + resultDomain.fail("创建配置失败: " + e.getMessage()); + return resultDomain; + } + } + + @Override + public ResultDomain updateConfig(TbSysConfig config) { + ResultDomain resultDomain = new ResultDomain<>(); + try { + int result = sysConfigMapper.updateSysConfig(config); + if (result > 0) { + resultDomain.success("更新成功", true); + return resultDomain; + } else { + resultDomain.fail("更新配置失败"); + return resultDomain; + } + } catch (Exception e) { + logger.error("更新配置失败", e); + resultDomain.fail("更新配置失败: " + e.getMessage()); + return resultDomain; + } + } + + @Override + public ResultDomain deleteConfig(String id) { + ResultDomain resultDomain = new ResultDomain<>(); + try { + int result = sysConfigMapper.deleteSysConfig(id); + if (result > 0) { + resultDomain.success("删除成功", true); + return resultDomain; + } else { + resultDomain.fail("删除配置失败"); + return resultDomain; + } + } catch (Exception e) { + logger.error("删除配置失败: {}", id, e); + resultDomain.fail("删除配置失败: " + e.getMessage()); + return resultDomain; + } + } + + @Override + public ResultDomain getConfigPage(TbSysConfig filter, PageParam pageParam) { + ResultDomain resultDomain = new ResultDomain<>(); + try { + int total = sysConfigMapper.countSelectSysConfig(filter); + List configs = sysConfigMapper.selectSysConfigPage(filter, pageParam); + pageParam.setTotalElements(total); + pageParam.setTotalPages((int) Math.ceil((double) total / pageParam.getPageSize())); + PageDomain pageDomain = new PageDomain<>(pageParam,configs); + resultDomain.success("查询成功", pageDomain); + return resultDomain; + } catch (Exception e) { + logger.error("分页查询配置失败", e); + resultDomain.fail("查询配置失败: " + e.getMessage()); + return resultDomain; + } + } + + @Override + public ResultDomain getConfigById(String id) { + ResultDomain resultDomain = new ResultDomain<>(); + try { + TbSysConfig config = sysConfigMapper.selectSysConfigById(id); + if (config != null) { + resultDomain.success("查询成功", config); + return resultDomain; + } else { + resultDomain.fail("配置不存在"); + return resultDomain; + } + } catch (Exception e) { + logger.error("根据ID获取配置失败: {}", id, e); + resultDomain.fail("获取配置失败: " + e.getMessage()); + return resultDomain; + } + } } diff --git a/schoolNewsServ/system/src/main/resources/mapper/SysConfigMapper.xml b/schoolNewsServ/system/src/main/resources/mapper/SysConfigMapper.xml index b813ffe..5b50131 100644 --- a/schoolNewsServ/system/src/main/resources/mapper/SysConfigMapper.xml +++ b/schoolNewsServ/system/src/main/resources/mapper/SysConfigMapper.xml @@ -6,10 +6,20 @@ + + + + + + + + + + @@ -21,7 +31,8 @@ - id, config_key, config_value, config_type, config_group, description, + id, config_key, config_name, config_value, config_type, render_type, config_group, + description, placeholder, remark, `rows`, min_value, max_value, unit, `options`, order_num, is_system, creator, updater, create_time, update_time, delete_time, deleted @@ -47,22 +58,35 @@ INSERT INTO tb_sys_config ( - id, config_key, config_value, config_type, config_group, description, + id, config_key, config_name, config_value, config_type, render_type, config_group, + description, placeholder, remark, `rows`, min_value, max_value, unit, `options`, order_num, is_system, creator, create_time ) VALUES ( - #{config.ID}, #{config.configKey}, #{config.configValue}, #{config.configType}, - #{config.configGroup}, #{config.description}, #{config.isSystem}, - #{config.creator}, NOW() + #{config.ID}, #{config.configKey}, #{config.configName}, #{config.configValue}, + #{config.configType}, #{config.renderType}, #{config.configGroup}, #{config.description}, + #{config.placeholder}, #{config.remark}, #{config.rows}, #{config.minValue}, + #{config.maxValue}, #{config.unit}, #{config.options}, #{config.orderNum}, + #{config.isSystem}, #{config.creator}, NOW() ) UPDATE tb_sys_config - SET config_value = #{config.configValue}, + SET config_name = #{config.configName}, + config_value = #{config.configValue}, config_type = #{config.configType}, + render_type = #{config.renderType}, config_group = #{config.configGroup}, description = #{config.description}, + placeholder = #{config.placeholder}, + remark = #{config.remark}, + `rows` = #{config.rows}, + min_value = #{config.minValue}, + max_value = #{config.maxValue}, + unit = #{config.unit}, + `options` = #{config.options}, + order_num = #{config.orderNum}, is_system = #{config.isSystem}, updater = #{config.updater}, update_time = NOW() @@ -100,7 +124,7 @@ SELECT FROM tb_sys_config WHERE deleted = 0 - ORDER BY config_group, config_key + ORDER BY config_group, order_num, config_key @@ -109,7 +133,7 @@ FROM tb_sys_config WHERE config_group = #{configGroup} AND deleted = 0 - ORDER BY config_key + ORDER BY order_num, config_key @@ -117,7 +141,7 @@ SELECT FROM tb_sys_config - ORDER BY config_group, config_key + ORDER BY config_group, order_num, config_key @@ -125,7 +149,7 @@ SELECT FROM tb_sys_config - ORDER BY config_group, config_key + ORDER BY config_group, order_num, config_key LIMIT #{pageParam.offset}, #{pageParam.pageSize} diff --git a/schoolNewsWeb/src/apis/system/config.ts b/schoolNewsWeb/src/apis/system/config.ts new file mode 100644 index 0000000..a47661f --- /dev/null +++ b/schoolNewsWeb/src/apis/system/config.ts @@ -0,0 +1,62 @@ +/** + * @description 系统配置相关API + * @author yslg + * @since 2025-11-18 + */ + +import { api } from '@/apis/index'; +import type { ResultDomain } from '@/types'; +import type { ConfigItem, SaveConfigParam } from '@/types/system/config'; +/** + * 系统配置API服务 + */ +export const configApi = { + /** + * 获取所有配置项 + * @returns Promise> + */ + async getConfigs(): Promise> { + const response = await api.get('/system/config/list'); + return response.data; + }, + + /** + * 根据分组获取配置项 + * @param groupKey 配置分组key + * @returns Promise> + */ + async getConfigsByGroup(groupKey: string): Promise> { + const response = await api.get(`/system/config/group/${groupKey}`); + return response.data; + }, + + /** + * 保存配置项 + * @param configs 配置项列表 + * @returns Promise> + */ + async saveConfigs(configs: SaveConfigParam[]): Promise> { + const response = await api.post('/system/config/save', configs); + return response.data; + }, + + /** + * 根据配置键获取配置值 + * @param configKey 配置键 + * @returns Promise> + */ + async getConfigValue(configKey: string): Promise> { + const response = await api.get(`/system/config/value/${configKey}`); + return response.data; + }, + + /** + * 删除配置项 + * @param configKey 配置键 + * @returns Promise> + */ + async deleteConfig(configKey: string): Promise> { + const response = await api.delete(`/system/config/${configKey}`); + return response.data; + } +}; diff --git a/schoolNewsWeb/src/apis/system/index.ts b/schoolNewsWeb/src/apis/system/index.ts index 62b8d46..8af8ceb 100644 --- a/schoolNewsWeb/src/apis/system/index.ts +++ b/schoolNewsWeb/src/apis/system/index.ts @@ -14,4 +14,5 @@ export { authApi } from './auth'; export { fileApi } from './file'; export { moduleApi } from './module'; export { logApi } from './log'; +export { configApi} from './config'; diff --git a/schoolNewsWeb/src/types/auth/index.ts b/schoolNewsWeb/src/types/auth/index.ts index 4be66c8..440b326 100644 --- a/schoolNewsWeb/src/types/auth/index.ts +++ b/schoolNewsWeb/src/types/auth/index.ts @@ -4,10 +4,10 @@ * @since 2025-10-06 */ -import { SysUser, SysUserInfo } from '../user'; +import { SysUser, SysUserInfo } from '../system/user'; import { UserDeptRoleVO } from '../dept'; -import { SysPermission } from '../permission'; -import { SysMenu } from '../menu'; +import { SysPermission } from '../system/permission'; +import { SysMenu } from '../system/menu'; import { LoginType } from '../enums'; /** diff --git a/schoolNewsWeb/src/types/dept/index.ts b/schoolNewsWeb/src/types/dept/index.ts index 078ed55..36c87d5 100644 --- a/schoolNewsWeb/src/types/dept/index.ts +++ b/schoolNewsWeb/src/types/dept/index.ts @@ -5,8 +5,8 @@ */ import { BaseDTO } from '../base'; -import { SysRole } from '../role'; -import { SysUserDeptRole } from '../user'; +import { SysRole } from '../system/role'; +import { SysUserDeptRole } from '../system/user'; /** * 系统部门 diff --git a/schoolNewsWeb/src/types/index.ts b/schoolNewsWeb/src/types/index.ts index 8bdd5ed..f7e54e7 100644 --- a/schoolNewsWeb/src/types/index.ts +++ b/schoolNewsWeb/src/types/index.ts @@ -8,22 +8,22 @@ export * from './base'; // 用户相关 -export * from './user'; +export * from './system/user'; // 角色相关 -export * from './role'; +export * from './system/role'; // 部门相关 export * from './dept'; // 菜单相关 -export * from './menu'; +export * from './system/menu'; // 权限相关 -export * from './permission'; +export * from './system/permission'; // 系统相关 -export * from './module'; +export * from './system/module'; export * from './achievement'; diff --git a/schoolNewsWeb/src/types/system/config.ts b/schoolNewsWeb/src/types/system/config.ts new file mode 100644 index 0000000..1ec236f --- /dev/null +++ b/schoolNewsWeb/src/types/system/config.ts @@ -0,0 +1,37 @@ +import type { ResultDomain } from '@/types'; + +/** + * 配置项接口定义(对应后端 TbSysConfig) + */ +export interface ConfigItem { + // 后端 TbSysConfig 字段(完全匹配) + configKey: string; // 配置键 + configName?: string; // 配置显示名称 + configValue: string; // 配置值 + configType: string; // 数据类型:string/number/boolean/json + renderType?: string; // 前端渲染类型:input/textarea/number/switch/select/password + configGroup: string; // 配置分组 + description?: string; // 配置描述 + placeholder?: string; // 输入框占位符 + remark?: string; // 备注说明(显示在表单项下方) + rows?: number; // 文本框行数(textarea用) + minValue?: number; // 最小值(number用) + maxValue?: number; // 最大值(number用) + unit?: string; // 单位(number用) + options?: string; // 下拉选项(select用,JSON字符串) + orderNum?: number; // 排序号 + isSystem?: boolean; // 是否系统配置 + creator?: string; // 创建者 + updater?: string; // 更新者 + createTime?: string; // 创建时间 + updateTime?: string; // 更新时间 +} + +/** + * 保存配置项参数 + */ +export interface SaveConfigParam { + configKey: string; + configValue: string; + configGroup: string; +} diff --git a/schoolNewsWeb/src/types/system/index.ts b/schoolNewsWeb/src/types/system/index.ts new file mode 100644 index 0000000..9d9ff98 --- /dev/null +++ b/schoolNewsWeb/src/types/system/index.ts @@ -0,0 +1,6 @@ +export * from './config'; +export * from './menu'; +export * from './module'; +export * from './permission'; +export * from './role'; +export * from './user' \ No newline at end of file diff --git a/schoolNewsWeb/src/types/menu/index.ts b/schoolNewsWeb/src/types/system/menu.ts similarity index 100% rename from schoolNewsWeb/src/types/menu/index.ts rename to schoolNewsWeb/src/types/system/menu.ts diff --git a/schoolNewsWeb/src/types/module/index.ts b/schoolNewsWeb/src/types/system/module.ts similarity index 100% rename from schoolNewsWeb/src/types/module/index.ts rename to schoolNewsWeb/src/types/system/module.ts diff --git a/schoolNewsWeb/src/types/permission/index.ts b/schoolNewsWeb/src/types/system/permission.ts similarity index 89% rename from schoolNewsWeb/src/types/permission/index.ts rename to schoolNewsWeb/src/types/system/permission.ts index 81d1318..980ff6c 100644 --- a/schoolNewsWeb/src/types/permission/index.ts +++ b/schoolNewsWeb/src/types/system/permission.ts @@ -5,9 +5,9 @@ */ import { BaseDTO } from '../base'; -import { SysMenu } from '../menu'; -import { SysRole } from '../role'; -import { SysModule } from '../module'; +import { SysMenu } from './menu'; +import { SysRole } from './role'; +import { SysModule } from './module'; /** * 系统权限 diff --git a/schoolNewsWeb/src/types/role/index.ts b/schoolNewsWeb/src/types/system/role.ts similarity index 100% rename from schoolNewsWeb/src/types/role/index.ts rename to schoolNewsWeb/src/types/system/role.ts diff --git a/schoolNewsWeb/src/types/user/index.ts b/schoolNewsWeb/src/types/system/user.ts similarity index 100% rename from schoolNewsWeb/src/types/user/index.ts rename to schoolNewsWeb/src/types/system/user.ts diff --git a/schoolNewsWeb/src/views/admin/manage/system/SystemConfigView.vue b/schoolNewsWeb/src/views/admin/manage/system/SystemConfigView.vue new file mode 100644 index 0000000..315c1e5 --- /dev/null +++ b/schoolNewsWeb/src/views/admin/manage/system/SystemConfigView.vue @@ -0,0 +1,390 @@ + + + + + diff --git a/schoolNewsWeb/src/views/public/task/LearningTaskAdd.vue b/schoolNewsWeb/src/views/public/task/LearningTaskAdd.vue index a36a393..54c58e2 100644 --- a/schoolNewsWeb/src/views/public/task/LearningTaskAdd.vue +++ b/schoolNewsWeb/src/views/public/task/LearningTaskAdd.vue @@ -314,7 +314,7 @@ import { resourceTagApi } from '@/apis/resource'; import { GenericSelector } from '@/components/base'; import type { TaskVO, Course, TaskItemVO } from '@/types/study'; import type { Resource, Tag } from '@/types/resource'; -import type { SysUser } from '@/types/user'; +import type { SysUser } from '@/types/system/user'; defineOptions({ name: 'LearningTaskAdd' diff --git a/schoolNewsWeb/src/views/user/user-center/UserCenterLayout.vue b/schoolNewsWeb/src/views/user/user-center/UserCenterLayout.vue index 611342d..ca56855 100644 --- a/schoolNewsWeb/src/views/user/user-center/UserCenterLayout.vue +++ b/schoolNewsWeb/src/views/user/user-center/UserCenterLayout.vue @@ -20,7 +20,7 @@ import { useRoute } from 'vue-router'; import { FloatingSidebar } from '@/components/base'; import { UserCard } from '@/views/user/user-center/components'; import { getParentChildrenRoutes } from '@/utils/routeUtils'; -import type { SysMenu } from '@/types/menu'; +import type { SysMenu } from '@/types/system/menu'; const route = useRoute();