diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/doc/代码修改日志 b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/doc/代码修改日志 index 2b2ee4be..b34ad88d 100644 --- a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/doc/代码修改日志 +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/doc/代码修改日志 @@ -1034,3 +1034,19 @@ jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules jeecgboot-vue3/src/views/xslmes/mesXslEquipPartMapping/MesXslEquipPartMappingList.vue jeecgboot-vue3/src/views/xslmes/mesXslEquipPartMapping/MesXslEquipPartMapping.data.ts jeecgboot-vue3/src/views/xslmes/mesXslEquipPartMapping/MesXslEquipPartMapping.api.ts + +-- author:GHT---date:20260616--for: 【MES上辅机】SQL Server中间库可视化配置(第三方配置页+读写开关+热刷新数据源) --- +jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/flyway/sql/mysql/V3.9.2_150__mes_xsl_mcs_db_config.sql +jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/entity/MesXslMcsDbConfig.java +jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/mapper/MesXslMcsDbConfigMapper.java +jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/service/IMesXslMcsDbConfigService.java +jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/service/impl/MesXslMcsDbConfigServiceImpl.java +jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/datasource/McsDataSourceManager.java +jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/datasource/McsDataSourceGuardAspect.java +jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/config/McsDataSourceInitializer.java +jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/controller/MesXslMcsDbConfigController.java +jeecgboot-vue3/src/views/system/appconfig/ThirdAppConfigList.vue +jeecgboot-vue3/src/views/system/appconfig/ThirdAppMcsDbConfigForm.vue +jeecgboot-vue3/src/views/system/appconfig/McsDbConfigModal.vue +jeecgboot-vue3/src/views/system/appconfig/McsDbConfig.data.ts +jeecgboot-vue3/src/views/system/appconfig/McsDbConfig.api.ts diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/approval/callback/ApprovalCallbackDispatcher.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/approval/callback/ApprovalCallbackDispatcher.java index 6e779459..a5d497f7 100644 --- a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/approval/callback/ApprovalCallbackDispatcher.java +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/approval/callback/ApprovalCallbackDispatcher.java @@ -133,24 +133,18 @@ public class ApprovalCallbackDispatcher { DING_LOG_TAG, callbackName, ctx.getAction(), ctx.getBizTable(), ctx.getBizDataId()); } try { - switch (ctx.getAction()) { - case NODE_APPROVED: - cb.onNodeApproved(ctx); - break; - case APPROVED: - cb.onApproved(ctx); - break; - case REJECTED: - cb.onRejected(ctx); - break; - //update-begin---author:GHT ---date:2026-06-08 for:【风险修复-R5】分发撤销回调----------- - case CANCELLED: - cb.onCancelled(ctx); - break; - //update-end---author:GHT ---date:2026-06-08 for:【风险修复-R5】分发撤销回调----------- - default: - break; + //update-begin---author:cursor ---date:20260615 for:【XSLMES-20260615-A05】审批回调分发改用if-else,避免调试热更新缺失switch合成类----------- + ApprovalCallbackContext.Action action = ctx.getAction(); + if (action == ApprovalCallbackContext.Action.NODE_APPROVED) { + cb.onNodeApproved(ctx); + } else if (action == ApprovalCallbackContext.Action.APPROVED) { + cb.onApproved(ctx); + } else if (action == ApprovalCallbackContext.Action.REJECTED) { + cb.onRejected(ctx); + } else if (action == ApprovalCallbackContext.Action.CANCELLED) { + cb.onCancelled(ctx); } + //update-end---author:cursor ---date:20260615 for:【XSLMES-20260615-A05】审批回调分发改用if-else,避免调试热更新缺失switch合成类----------- if (dingTalk) { log.info("{} 业务回调完成 {} action={} bizTable={} bizDataId={}", DING_LOG_TAG, callbackName, ctx.getAction(), ctx.getBizTable(), ctx.getBizDataId()); diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/config/McsDataSourceInitializer.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/config/McsDataSourceInitializer.java new file mode 100644 index 00000000..aedf39fb --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/config/McsDataSourceInitializer.java @@ -0,0 +1,48 @@ +package org.jeecg.modules.xslmes.mcs.config; + +import lombok.extern.slf4j.Slf4j; +import org.jeecg.modules.xslmes.mcs.datasource.McsDataSourceManager; +import org.jeecg.modules.xslmes.mcs.entity.MesXslMcsDbConfig; +import org.jeecg.modules.xslmes.mcs.service.IMesXslMcsDbConfigService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.ApplicationArguments; +import org.springframework.boot.ApplicationRunner; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +/** + * 启动时加载中间库配置,覆盖 application.yml 中的 sqlserver_mcs 连接 + */ +@Slf4j +@Component +@Order(100) +public class McsDataSourceInitializer implements ApplicationRunner { + + @Autowired + private IMesXslMcsDbConfigService mcsDbConfigService; + + @Autowired + private McsDataSourceManager mcsDataSourceManager; + + //update-begin---author:GHT ---date:20260616 for:【MES上辅机】启动时加载中间库可视化配置----------- + @Override + public void run(ApplicationArguments args) { + try { + MesXslMcsDbConfig config = mcsDbConfigService.getOne( + new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper() + .eq(MesXslMcsDbConfig::getTenantId, 0) + .orderByDesc(MesXslMcsDbConfig::getUpdateTime) + .last("LIMIT 1"), + false); + if (config != null) { + mcsDataSourceManager.applyConfig(config); + log.info("[MCS中间库] 已加载数据库中的中间库配置(含读写开关)"); + } else { + log.info("[MCS中间库] 未找到已启用的数据库配置,继续使用 application.yml 中的 sqlserver_mcs"); + } + } catch (Exception e) { + log.warn("[MCS中间库] 启动加载配置失败,将使用 yml 默认连接: {}", e.getMessage()); + } + } + //update-end---author:GHT ---date:20260616 for:【MES上辅机】启动时加载中间库可视化配置----------- +} diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/config/McsWebMvcConfig.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/config/McsWebMvcConfig.java new file mode 100644 index 00000000..82238153 --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/config/McsWebMvcConfig.java @@ -0,0 +1,64 @@ +package org.jeecg.modules.xslmes.mcs.config; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.jeecg.common.exception.JeecgBootException; +import org.jeecg.modules.xslmes.mcs.datasource.McsDataSourceManager; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.HandlerInterceptor; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +/** + * 注册 MCS 中间库 HTTP 拦截器(读取/写入开关在接口层生效) + */ +@Configuration +public class McsWebMvcConfig implements WebMvcConfigurer { + + @Autowired + private McsDataSourceManager mcsDataSourceManager; + + @Override + public void addInterceptors(InterceptorRegistry registry) { + registry.addInterceptor(mcsReadWriteInterceptor()) + .addPathPatterns("/xslmes/mcs/**") + .excludePathPatterns("/xslmes/mcs/dbConfig/**"); + } + + //update-begin---author:GHT ---date:20260616 for:【MES上辅机】HTTP层拦截中间库读写请求----------- + private HandlerInterceptor mcsReadWriteInterceptor() { + return new HandlerInterceptor() { + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { + if (!mcsDataSourceManager.hasSavedConfig()) { + return true; + } + String uri = request.getRequestURI(); + if (uri.contains("/mcs/dbConfig")) { + return true; + } + if ("OPTIONS".equalsIgnoreCase(request.getMethod())) { + return true; + } + if (!mcsDataSourceManager.isReadEnabled()) { + throw new JeecgBootException("中间库读取已关闭,请在「中间库连接配置」中开启读取开关并保存"); + } + if (isWriteRequest(request, uri) && !mcsDataSourceManager.isWriteEnabled()) { + throw new JeecgBootException("中间库写入已关闭,请在「中间库连接配置」中开启写入开关并保存"); + } + return true; + } + + private boolean isWriteRequest(HttpServletRequest request, String uri) { + String method = request.getMethod(); + boolean mutating = "POST".equalsIgnoreCase(method) + || "PUT".equalsIgnoreCase(method) + || "DELETE".equalsIgnoreCase(method) + || "PATCH".equalsIgnoreCase(method); + return mutating && uri.toLowerCase().contains("mestomcs"); + } + }; + } + //update-end---author:GHT ---date:20260616 for:【MES上辅机】HTTP层拦截中间库读写请求----------- +} diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/controller/MesXslMcsDbConfigController.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/controller/MesXslMcsDbConfigController.java new file mode 100644 index 00000000..7bbb9188 --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/controller/MesXslMcsDbConfigController.java @@ -0,0 +1,85 @@ +package org.jeecg.modules.xslmes.mcs.controller; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.jeecg.common.api.vo.Result; +import org.jeecg.common.config.TenantContext; +import org.jeecg.common.util.oConvertUtils; +import org.jeecg.config.mybatis.MybatisPlusSaasConfig; +import org.jeecg.modules.xslmes.mcs.datasource.McsDataSourceManager; +import org.jeecg.modules.xslmes.mcs.entity.MesXslMcsDbConfig; +import org.jeecg.modules.xslmes.mcs.service.IMesXslMcsDbConfigService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * MES上辅机 SQL Server 中间库连接配置 + */ +@Tag(name = "MES上辅机中间库配置") +@RestController +@RequestMapping("/xslmes/mcs/dbConfig") +public class MesXslMcsDbConfigController { + + @Autowired + private IMesXslMcsDbConfigService mcsDbConfigService; + + @Autowired + private McsDataSourceManager mcsDataSourceManager; + + private Integer resolveTenantId(Integer tenantId) { + if (MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL) { + if (tenantId == null) { + tenantId = oConvertUtils.getInt(TenantContext.getTenant(), -1); + } + } else if (tenantId == null) { + tenantId = oConvertUtils.getInt(TenantContext.getTenant(), 0); + } + return tenantId; + } + + @Operation(summary = "获取中间库配置") + @GetMapping("/get") + public Result getConfig(@RequestParam(name = "tenantId", required = false) Integer tenantId) { + return Result.OK(mcsDbConfigService.getCurrentConfig(resolveTenantId(tenantId))); + } + + @Operation(summary = "保存中间库配置") + @PostMapping("/save") + public Result saveConfig(@RequestBody MesXslMcsDbConfig config) { + if (config.getTenantId() == null) { + config.setTenantId(resolveTenantId(null)); + } + return mcsDbConfigService.saveOrUpdateConfig(config); + } + + @Operation(summary = "测试中间库连接") + @GetMapping("/testConnect") + public Result testConnect(@RequestParam(name = "tenantId", required = false) Integer tenantId) { + return mcsDbConfigService.testConnection(resolveTenantId(tenantId)); + } + + @Operation(summary = "删除中间库配置") + @DeleteMapping("/delete") + public Result deleteConfig(@RequestParam(name = "id") String id) { + return mcsDbConfigService.deleteConfig(id); + } + + @Operation(summary = "获取中间库连接状态") + @GetMapping("/status") + public Result> status() { + Map data = new LinkedHashMap<>(); + MesXslMcsDbConfig cfg = mcsDataSourceManager.getCachedConfig(); + data.put("dbConfigActive", mcsDataSourceManager.isDbConfigActive()); + data.put("readEnabled", mcsDataSourceManager.isReadEnabled()); + data.put("writeEnabled", mcsDataSourceManager.isWriteEnabled()); + if (cfg != null) { + data.put("serverHost", cfg.getServerHost()); + data.put("serverPort", cfg.getServerPort()); + data.put("dbName", cfg.getDbName()); + } + return Result.OK(data); + } +} diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/datasource/McsDataSourceGuardAspect.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/datasource/McsDataSourceGuardAspect.java new file mode 100644 index 00000000..48b1dcfc --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/datasource/McsDataSourceGuardAspect.java @@ -0,0 +1,48 @@ +package org.jeecg.modules.xslmes.mcs.datasource; + +import lombok.extern.slf4j.Slf4j; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.jeecg.common.exception.JeecgBootException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +/** + * MCS 中间库读写开关守卫 + *
    + *
  • 读取开关:拦截所有中间表查询(McsToMes + MesToMcs 列表/详情等)
  • + *
  • 写入开关:仅拦截 MES→MCS 方向的增删改
  • + *
+ */ +@Slf4j +@Aspect +@Component +@Order(1) +public class McsDataSourceGuardAspect { + + @Autowired + private McsDataSourceManager mcsDataSourceManager; + + //update-begin---author:GHT ---date:20260616 for:【MES上辅机】读取开关拦截全部中间表查询----------- + @Before("(execution(* com.baomidou.mybatisplus.extension.service.IService+.*(..)) " + + "&& (target(org.jeecg.modules.xslmes.mcs.service.impl.McsToMes*) " + + "|| target(org.jeecg.modules.xslmes.mcs.service.impl.MesToMcs*)))") + public void guardRead(JoinPoint joinPoint) { + if (!mcsDataSourceManager.isReadEnabled()) { + throw new JeecgBootException("中间库读取已关闭,请在「中间库连接配置」中开启读取开关并保存"); + } + } + + @Before("execution(* org.jeecg.modules.xslmes.mcs.service.impl.MesToMcs*.save*(..)) || " + + "execution(* org.jeecg.modules.xslmes.mcs.service.impl.MesToMcs*.update*(..)) || " + + "execution(* org.jeecg.modules.xslmes.mcs.service.impl.MesToMcs*.remove*(..)) || " + + "execution(* org.jeecg.modules.xslmes.mcs.service.impl.MesToMcs*.delete*(..))") + public void guardWrite(JoinPoint joinPoint) { + if (!mcsDataSourceManager.isWriteEnabled()) { + throw new JeecgBootException("中间库写入已关闭,请在「中间库连接配置」中开启写入开关并保存"); + } + } + //update-end---author:GHT ---date:20260616 for:【MES上辅机】读取开关拦截全部中间表查询----------- +} diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/datasource/McsDataSourceManager.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/datasource/McsDataSourceManager.java new file mode 100644 index 00000000..99b1e3ec --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/datasource/McsDataSourceManager.java @@ -0,0 +1,229 @@ +package org.jeecg.modules.xslmes.mcs.datasource; + +import com.alibaba.druid.pool.DruidDataSource; +import com.baomidou.dynamic.datasource.DynamicRoutingDataSource; +import com.baomidou.dynamic.datasource.creator.DataSourceProperty; +import com.baomidou.dynamic.datasource.creator.druid.DruidDataSourceCreator; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang.StringUtils; +import org.jeecg.common.util.dynamic.db.DataSourceCachePool; +import org.jeecg.modules.system.util.SecurityUtil; +import org.jeecg.modules.xslmes.mcs.entity.MesXslMcsDbConfig; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import javax.sql.DataSource; +import java.sql.Connection; +import java.sql.DriverManager; +import java.util.concurrent.atomic.AtomicReference; + +/** + * MCS SQL Server 动态数据源管理器 + *

配置保存后热刷新 sqlserver_mcs 数据源,无需改 application.yml

+ */ +@Slf4j +@Component +public class McsDataSourceManager { + + public static final String DS_KEY = "sqlserver_mcs"; + + private final AtomicReference cachedConfig = new AtomicReference<>(); + + @Autowired + private DataSource dataSource; + + @Autowired + private DruidDataSourceCreator dataSourceCreator; + + @Value("${spring.datasource.dynamic.datasource.sqlserver_mcs.url:}") + private String ymlUrl; + + @Value("${spring.datasource.dynamic.datasource.sqlserver_mcs.username:}") + private String ymlUsername; + + @Value("${spring.datasource.dynamic.datasource.sqlserver_mcs.password:}") + private String ymlPassword; + + @Value("${spring.datasource.dynamic.datasource.sqlserver_mcs.driver-class-name:com.microsoft.sqlserver.jdbc.SQLServerDriver}") + private String ymlDriverClassName; + + public MesXslMcsDbConfig getCachedConfig() { + return cachedConfig.get(); + } + + public boolean hasSavedConfig() { + return cachedConfig.get() != null; + } + + public boolean isDbConfigActive() { + MesXslMcsDbConfig cfg = cachedConfig.get(); + return cfg != null && Integer.valueOf(1).equals(cfg.getStatus()); + } + + public boolean isReadEnabled() { + MesXslMcsDbConfig cfg = cachedConfig.get(); + if (cfg == null) { + return true; + } + return Integer.valueOf(1).equals(cfg.getReadEnabled()); + } + + public boolean isWriteEnabled() { + MesXslMcsDbConfig cfg = cachedConfig.get(); + if (cfg == null) { + return true; + } + return Integer.valueOf(1).equals(cfg.getWriteEnabled()); + } + + //update-begin---author:GHT ---date:20260616 for:【MES上辅机】SQL Server中间库可视化配置----------- + /** + * 将配置应用到动态数据源(启用时注册/更新,禁用时移除) + */ + public void applyConfig(MesXslMcsDbConfig config) { + cachedConfig.set(config); + DynamicRoutingDataSource routing = (DynamicRoutingDataSource) dataSource; + closeAndRemoveDataSource(routing); + DataSourceCachePool.removeCache(DS_KEY); + if (config == null) { + restoreYmlDataSource(routing); + log.info("[MCS中间库] 已清除页面配置"); + return; + } + if (Integer.valueOf(1).equals(config.getStatus())) { + try { + String plainPassword = decryptPassword(config.getDbPassword()); + DataSourceProperty property = buildDataSourceProperty(config, plainPassword); + DataSource mcsDs = dataSourceCreator.createDataSource(property); + routing.addDataSource(DS_KEY, mcsDs); + log.info("[MCS中间库] 动态数据源 {} 已热刷新(无需重启): {}:{}/{}", DS_KEY, + config.getServerHost(), config.getServerPort(), config.getDbName()); + } catch (Exception e) { + cachedConfig.set(config); + log.error("[MCS中间库] 刷新动态数据源失败", e); + throw new RuntimeException("刷新中间库数据源失败:" + e.getMessage(), e); + } + return; + } + restoreYmlDataSource(routing); + log.info("[MCS中间库] 连接未启用,读写开关仍按页面配置生效"); + } + + private void closeAndRemoveDataSource(DynamicRoutingDataSource routing) { + if (!routing.getDataSources().containsKey(DS_KEY)) { + return; + } + DataSource old = routing.getDataSource(DS_KEY); + routing.removeDataSource(DS_KEY); + closeDataSourceQuietly(old); + } + + private void closeDataSourceQuietly(DataSource ds) { + if (ds instanceof DruidDataSource druid && druid.isEnable()) { + try { + druid.close(); + } catch (Exception e) { + log.warn("[MCS中间库] 关闭旧连接池失败: {}", e.getMessage()); + } + } + } + + /** + * 测试 JDBC 连通性(不写入动态数据源) + */ + public String testConnection(MesXslMcsDbConfig config, String plainPassword) { + if (config == null) { + return "配置为空"; + } + String jdbcUrl = buildJdbcUrl(config); + try { + Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver"); + try (Connection conn = DriverManager.getConnection(jdbcUrl, config.getDbUsername(), plainPassword)) { + if (conn.isValid(5)) { + return null; + } + return "连接无效"; + } + } catch (Exception e) { + log.warn("[MCS中间库] 连接测试失败: {}", e.getMessage()); + return e.getMessage(); + } + } + + public String buildJdbcUrl(MesXslMcsDbConfig config) { + int loginTimeout = config.getLoginTimeout() != null ? config.getLoginTimeout() : 120; + int connectTimeout = config.getConnectTimeout() != null ? config.getConnectTimeout() : 120000; + String host = resolveHost(config); + int port = config.getServerPort() != null ? config.getServerPort() : 1433; + String dbName = StringUtils.isNotBlank(config.getDbName()) ? config.getDbName() : "MES_ShareDB"; + return "jdbc:sqlserver://" + host + ":" + port + + ";DatabaseName=" + dbName + + ";encrypt=false;trustServerCertificate=true;SelectMethod=cursor" + + ";loginTimeout=" + loginTimeout + + ";connectTimeout=" + connectTimeout + ";"; + } + + private DataSourceProperty buildDataSourceProperty(MesXslMcsDbConfig config, String plainPassword) { + DataSourceProperty property = new DataSourceProperty(); + property.setPoolName(DS_KEY); + property.setDriverClassName("com.microsoft.sqlserver.jdbc.SQLServerDriver"); + property.setUrl(buildJdbcUrl(config)); + property.setUsername(config.getDbUsername()); + property.setPassword(plainPassword); + return property; + } + + private void restoreYmlDataSource(DynamicRoutingDataSource routing) { + if (StringUtils.isBlank(ymlUrl)) { + log.warn("[MCS中间库] yml 中未配置 sqlserver_mcs,无法恢复默认数据源"); + return; + } + try { + DataSourceProperty property = new DataSourceProperty(); + property.setPoolName(DS_KEY); + property.setDriverClassName(ymlDriverClassName); + property.setUrl(ymlUrl); + property.setUsername(ymlUsername); + property.setPassword(ymlPassword); + routing.addDataSource(DS_KEY, dataSourceCreator.createDataSource(property)); + } catch (Exception e) { + log.error("[MCS中间库] 恢复 yml 默认数据源失败", e); + } + } + + private String resolveHost(MesXslMcsDbConfig config) { + String host = config.getServerHost() == null ? "" : config.getServerHost().trim(); + if (host.contains(":")) { + String[] parts = host.split(":", 2); + host = parts[0]; + if (config.getServerPort() == null || config.getServerPort() == 1433) { + try { + config.setServerPort(Integer.parseInt(parts[1])); + } catch (NumberFormatException ignored) { + // 端口解析失败时保留原端口 + } + } + } + return host; + } + + public String decryptPassword(String encrypted) { + if (StringUtils.isBlank(encrypted)) { + return ""; + } + try { + return SecurityUtil.jiemi(encrypted); + } catch (Exception e) { + return encrypted; + } + } + + public String encryptPassword(String plain) { + if (StringUtils.isBlank(plain)) { + return plain; + } + return SecurityUtil.jiami(plain); + } + //update-end---author:GHT ---date:20260616 for:【MES上辅机】SQL Server中间库可视化配置----------- +} diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/entity/MesXslMcsDbConfig.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/entity/MesXslMcsDbConfig.java new file mode 100644 index 00000000..ebda2f5a --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/entity/MesXslMcsDbConfig.java @@ -0,0 +1,80 @@ +package org.jeecg.modules.xslmes.mcs.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; +import org.springframework.format.annotation.DateTimeFormat; + +import java.io.Serializable; +import java.util.Date; + +/** + * MES上辅机 SQL Server 中间库配置 + */ +@Data +@TableName("mes_xsl_mcs_db_config") +@Accessors(chain = true) +@EqualsAndHashCode(callSuper = false) +@Schema(description = "MES上辅机SQL Server中间库配置") +public class MesXslMcsDbConfig implements Serializable { + private static final long serialVersionUID = 1L; + + @TableId(type = IdType.ASSIGN_ID) + @Schema(description = "主键") + private String id; + + @Schema(description = "租户ID") + private Integer tenantId; + + @Schema(description = "服务器地址") + private String serverHost; + + @Schema(description = "端口") + private Integer serverPort; + + @Schema(description = "数据库名") + private String dbName; + + @Schema(description = "用户名") + private String dbUsername; + + @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) + @Schema(description = "密码") + private String dbPassword; + + @Schema(description = "读取开关(0-关,1-开)") + private Integer readEnabled; + + @Schema(description = "写入开关(0-关,1-开)") + private Integer writeEnabled; + + @Schema(description = "启用状态(0-关,1-开)") + private Integer status; + + @Schema(description = "登录超时(秒)") + private Integer loginTimeout; + + @Schema(description = "连接超时(毫秒)") + private Integer connectTimeout; + + @Schema(description = "备注") + private String remark; + + private String createBy; + + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date createTime; + + private String updateBy; + + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date updateTime; +} diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/mapper/MesXslMcsDbConfigMapper.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/mapper/MesXslMcsDbConfigMapper.java new file mode 100644 index 00000000..5c2d6911 --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/mapper/MesXslMcsDbConfigMapper.java @@ -0,0 +1,10 @@ +package org.jeecg.modules.xslmes.mcs.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.jeecg.modules.xslmes.mcs.entity.MesXslMcsDbConfig; + +/** + * MES上辅机 SQL Server 中间库配置 Mapper + */ +public interface MesXslMcsDbConfigMapper extends BaseMapper { +} diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/service/IMesXslMcsDbConfigService.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/service/IMesXslMcsDbConfigService.java new file mode 100644 index 00000000..0373b41a --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/service/IMesXslMcsDbConfigService.java @@ -0,0 +1,31 @@ +package org.jeecg.modules.xslmes.mcs.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import org.jeecg.common.api.vo.Result; +import org.jeecg.modules.xslmes.mcs.entity.MesXslMcsDbConfig; + +/** + * MES上辅机 SQL Server 中间库配置 Service + */ +public interface IMesXslMcsDbConfigService extends IService { + + /** + * 获取当前租户配置(无则返回 null) + */ + MesXslMcsDbConfig getCurrentConfig(Integer tenantId); + + /** + * 保存或更新配置并刷新动态数据源 + */ + Result saveOrUpdateConfig(MesXslMcsDbConfig config); + + /** + * 测试数据库连接 + */ + Result testConnection(Integer tenantId); + + /** + * 删除配置并移除动态数据源 + */ + Result deleteConfig(String id); +} diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/service/impl/MesXslMcsDbConfigServiceImpl.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/service/impl/MesXslMcsDbConfigServiceImpl.java new file mode 100644 index 00000000..9845803d --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/service/impl/MesXslMcsDbConfigServiceImpl.java @@ -0,0 +1,186 @@ +package org.jeecg.modules.xslmes.mcs.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang.StringUtils; +import org.apache.shiro.SecurityUtils; +import org.jeecg.common.api.vo.Result; +import org.jeecg.common.system.vo.LoginUser; +import org.jeecg.modules.xslmes.mcs.datasource.McsDataSourceManager; +import org.jeecg.modules.xslmes.mcs.entity.MesXslMcsDbConfig; +import org.jeecg.modules.xslmes.mcs.mapper.MesXslMcsDbConfigMapper; +import org.jeecg.modules.xslmes.mcs.service.IMesXslMcsDbConfigService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.transaction.support.TransactionSynchronization; +import org.springframework.transaction.support.TransactionSynchronizationManager; + +import java.util.Date; + +/** + * MES上辅机 SQL Server 中间库配置 Service 实现 + */ +@Slf4j +@Service +public class MesXslMcsDbConfigServiceImpl extends ServiceImpl + implements IMesXslMcsDbConfigService { + + @Autowired + private McsDataSourceManager mcsDataSourceManager; + + @Override + public MesXslMcsDbConfig getCurrentConfig(Integer tenantId) { + int tid = tenantId != null ? tenantId : 0; + LambdaQueryWrapper qw = new LambdaQueryWrapper<>(); + qw.eq(MesXslMcsDbConfig::getTenantId, tid); + qw.orderByDesc(MesXslMcsDbConfig::getUpdateTime); + qw.last("LIMIT 1"); + MesXslMcsDbConfig config = getOne(qw, false); + if (config != null) { + config.setDbPassword(null); + } + return config; + } + + //update-begin---author:GHT ---date:20260616 for:【MES上辅机】SQL Server中间库可视化配置----------- + @Override + @Transactional(rollbackFor = Exception.class) + public Result saveOrUpdateConfig(MesXslMcsDbConfig config) { + if (config == null) { + return Result.error("配置不能为空"); + } + if (StringUtils.isBlank(config.getServerHost())) { + return Result.error("服务器地址不能为空"); + } + if (StringUtils.isBlank(config.getDbUsername())) { + return Result.error("用户名不能为空"); + } + if (config.getTenantId() == null) { + config.setTenantId(0); + } + if (config.getServerPort() == null) { + config.setServerPort(1433); + } + if (StringUtils.isBlank(config.getDbName())) { + config.setDbName("MES_ShareDB"); + } + if (config.getReadEnabled() == null) { + config.setReadEnabled(1); + } + if (config.getWriteEnabled() == null) { + config.setWriteEnabled(1); + } + if (config.getStatus() == null) { + config.setStatus(0); + } + if (config.getLoginTimeout() == null) { + config.setLoginTimeout(120); + } + if (config.getConnectTimeout() == null) { + config.setConnectTimeout(120000); + } + + String plainPassword = resolvePlainPassword(config); + if (StringUtils.isBlank(plainPassword)) { + return Result.error("密码不能为空"); + } + + String err = mcsDataSourceManager.testConnection(config, plainPassword); + if (err != null && Integer.valueOf(1).equals(config.getStatus())) { + return Result.error("连接测试失败:" + err); + } + + LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + String username = user != null ? user.getUsername() : "system"; + Date now = new Date(); + + if (StringUtils.isNotBlank(config.getId())) { + MesXslMcsDbConfig old = getById(config.getId()); + if (old == null) { + return Result.error("配置不存在"); + } + config.setDbPassword(mcsDataSourceManager.encryptPassword(plainPassword)); + config.setUpdateBy(username); + config.setUpdateTime(now); + updateById(config); + } else { + config.setDbPassword(mcsDataSourceManager.encryptPassword(plainPassword)); + config.setCreateBy(username); + config.setCreateTime(now); + config.setUpdateBy(username); + config.setUpdateTime(now); + save(config); + } + + MesXslMcsDbConfig applied = getById(config.getId()); + scheduleApplyAfterCommit(applied); + return Result.OK("保存成功,中间库连接已热刷新,无需重启后端"); + } + + /** + * 事务提交后再刷新数据源,避免库未落盘就切换连接 + */ + private void scheduleApplyAfterCommit(MesXslMcsDbConfig applied) { + if (TransactionSynchronizationManager.isSynchronizationActive()) { + TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() { + @Override + public void afterCommit() { + mcsDataSourceManager.applyConfig(applied); + } + }); + } else { + mcsDataSourceManager.applyConfig(applied); + } + } + + @Override + public Result testConnection(Integer tenantId) { + MesXslMcsDbConfig config = getOneByTenant(tenantId); + if (config == null) { + return Result.error("尚未配置中间库连接"); + } + String plainPassword = mcsDataSourceManager.decryptPassword(config.getDbPassword()); + String err = mcsDataSourceManager.testConnection(config, plainPassword); + if (err == null) { + return Result.OK("连接成功"); + } + return Result.error("连接失败:" + err); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public Result deleteConfig(String id) { + MesXslMcsDbConfig config = getById(id); + if (config == null) { + return Result.error("配置不存在"); + } + removeById(id); + mcsDataSourceManager.applyConfig(null); + return Result.OK("已删除配置,中间库连接已断开(无需重启后端)"); + } + + private MesXslMcsDbConfig getOneByTenant(Integer tenantId) { + int tid = tenantId != null ? tenantId : 0; + LambdaQueryWrapper qw = new LambdaQueryWrapper<>(); + qw.eq(MesXslMcsDbConfig::getTenantId, tid); + qw.orderByDesc(MesXslMcsDbConfig::getUpdateTime); + qw.last("LIMIT 1"); + return getOne(qw, false); + } + + private String resolvePlainPassword(MesXslMcsDbConfig config) { + if (StringUtils.isNotBlank(config.getDbPassword())) { + return config.getDbPassword(); + } + if (StringUtils.isNotBlank(config.getId())) { + MesXslMcsDbConfig old = getById(config.getId()); + if (old != null) { + return mcsDataSourceManager.decryptPassword(old.getDbPassword()); + } + } + return null; + } + //update-end---author:GHT ---date:20260616 for:【MES上辅机】SQL Server中间库可视化配置----------- +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/application-dev.yml b/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/application-dev.yml index ee936a35..343834b3 100644 --- a/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/application-dev.yml +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/application-dev.yml @@ -167,21 +167,22 @@ spring: username: root password: 123456 driver-class-name: com.mysql.cj.jdbc.Driver + # 中间库连接已改为「第三方配置 → 上辅机中间库」页面维护,此处保留示例供参考 #update-begin---author:geh ---date:2026-06-02 for:【MES上辅机】新增 SQL Server 中间表数据源(MES_ShareDB)----------- - sqlserver_mcs: - driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver - # loginTimeout/connectTimeout:花生壳映射不稳定时延长 TCP/登录等待(单位:秒 / 毫秒) - url: jdbc:sqlserver://1lo04860wn636.vicp.fun:31601;DatabaseName=MES_ShareDB;encrypt=false;trustServerCertificate=true;SelectMethod=cursor;loginTimeout=120;connectTimeout=120000; - username: sa - password: 123456 - druid: - initial-size: 0 - min-idle: 0 - max-wait: 120000 - connect-timeout: 120000 - connection-error-retry-attempts: 10 - time-between-connect-error-millis: 3000 - break-after-acquire-failure: false +# sqlserver_mcs: +# driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver +# # loginTimeout/connectTimeout:花生壳映射不稳定时延长 TCP/登录等待(单位:秒 / 毫秒) +# url: jdbc:sqlserver://1lo04860wn636.vicp.fun:31601;DatabaseName=MES_ShareDB;encrypt=false;trustServerCertificate=true;SelectMethod=cursor;loginTimeout=120;connectTimeout=120000; +# username: sa +# password: 123456 +# druid: +# initial-size: 0 +# min-idle: 0 +# max-wait: 120000 +# connect-timeout: 120000 +# connection-error-retry-attempts: 10 +# time-between-connect-error-millis: 3000 +# break-after-acquire-failure: false #update-end---author:geh ---date:2026-06-02 for:【MES上辅机】新增 SQL Server 中间表数据源(MES_ShareDB)----------- # # shardingjdbc数据源 # sharding-db: diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/flyway/sql/mysql/V3.9.2_150__mes_xsl_mcs_db_config.sql b/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/flyway/sql/mysql/V3.9.2_150__mes_xsl_mcs_db_config.sql new file mode 100644 index 00000000..99e717e6 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/flyway/sql/mysql/V3.9.2_150__mes_xsl_mcs_db_config.sql @@ -0,0 +1,36 @@ +-- 【MES上辅机】SQL Server 中间库可视化配置(替代 application.yml 手工改连接) +CREATE TABLE IF NOT EXISTS `mes_xsl_mcs_db_config` ( + `id` varchar(36) NOT NULL COMMENT '主键', + `tenant_id` int DEFAULT 0 COMMENT '租户ID', + `server_host` varchar(200) NOT NULL COMMENT '服务器地址(IP或域名,可含端口)', + `server_port` int DEFAULT 1433 COMMENT '端口', + `db_name` varchar(100) NOT NULL DEFAULT 'MES_ShareDB' COMMENT '数据库名', + `db_username` varchar(100) NOT NULL COMMENT '用户名', + `db_password` varchar(500) DEFAULT NULL COMMENT '密码(AES加密)', + `read_enabled` tinyint(1) DEFAULT 1 COMMENT '读取开关(0-关,1-开) MCS→MES方向', + `write_enabled` tinyint(1) DEFAULT 1 COMMENT '写入开关(0-关,1-开) MES→MCS方向', + `status` tinyint(1) DEFAULT 0 COMMENT '启用状态(0-关,1-开)', + `login_timeout` int DEFAULT 120 COMMENT '登录超时(秒)', + `connect_timeout` int DEFAULT 120000 COMMENT '连接超时(毫秒)', + `remark` varchar(500) DEFAULT NULL COMMENT '备注', + `create_by` varchar(50) DEFAULT NULL COMMENT '创建人', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(50) DEFAULT NULL COMMENT '更新人', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + PRIMARY KEY (`id`), + KEY `idx_mcs_db_tenant` (`tenant_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='MES上辅机SQL Server中间库配置'; + +-- 菜单:MES上辅机数据 -> 中间库连接配置 +INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`) +SELECT '1900000000000000848', '1900000000000000830', '中间库连接配置', '/third/app?tab=mcs', 'system/appconfig/ThirdAppConfigList', 1, NULL, NULL, 1, NULL, '0', 0.50, 0, 'ant-design:database-outlined', 1, 1, 0, 0, 'SQL Server中间库连接与读写开关', 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0 +FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_permission` WHERE `id` = '1900000000000000848'); + +INSERT INTO `sys_role_permission` (`id`, `role_id`, `permission_id`, `data_rule_ids`, `operate_date`, `operate_ip`) +SELECT REPLACE(UUID(), '-', ''), r.id, '1900000000000000848', NULL, NOW(), '127.0.0.1' +FROM `sys_role` r +WHERE r.`role_code` = 'admin' + AND NOT EXISTS ( + SELECT 1 FROM `sys_role_permission` rp + WHERE rp.`role_id` = r.id AND rp.`permission_id` = '1900000000000000848' + ); diff --git a/jeecgboot-vue3/src/views/system/appconfig/McsDbConfig.api.ts b/jeecgboot-vue3/src/views/system/appconfig/McsDbConfig.api.ts new file mode 100644 index 00000000..4142cacc --- /dev/null +++ b/jeecgboot-vue3/src/views/system/appconfig/McsDbConfig.api.ts @@ -0,0 +1,19 @@ +import { defHttp } from '/@/utils/http/axios'; + +enum Api { + getConfig = '/xslmes/mcs/dbConfig/get', + saveConfig = '/xslmes/mcs/dbConfig/save', + testConnect = '/xslmes/mcs/dbConfig/testConnect', + deleteConfig = '/xslmes/mcs/dbConfig/delete', + status = '/xslmes/mcs/dbConfig/status', +} + +export const getMcsDbConfig = (params?) => defHttp.get({ url: Api.getConfig, params }); + +export const saveMcsDbConfig = (params) => defHttp.post({ url: Api.saveConfig, params }); + +export const testMcsDbConnect = (params?) => defHttp.get({ url: Api.testConnect, params }, { isTransformResponse: false }); + +export const deleteMcsDbConfig = (params) => defHttp.delete({ url: Api.deleteConfig, params }, { joinParamsToUrl: true }); + +export const getMcsDbStatus = () => defHttp.get({ url: Api.status }); diff --git a/jeecgboot-vue3/src/views/system/appconfig/McsDbConfig.data.ts b/jeecgboot-vue3/src/views/system/appconfig/McsDbConfig.data.ts new file mode 100644 index 00000000..213b9d37 --- /dev/null +++ b/jeecgboot-vue3/src/views/system/appconfig/McsDbConfig.data.ts @@ -0,0 +1,100 @@ +import { FormSchema } from '/@/components/Form'; + +export const mcsDbConfigFormSchema: FormSchema[] = [ + { label: 'id', field: 'id', component: 'Input', show: false }, + { label: 'tenantId', field: 'tenantId', component: 'InputNumber', show: false }, + { + label: '服务器地址', + field: 'serverHost', + component: 'Input', + required: true, + componentProps: { placeholder: 'IP 或域名,例如 192.168.1.10 或 xxx.vicp.fun' }, + }, + { + label: '端口', + field: 'serverPort', + component: 'InputNumber', + defaultValue: 1433, + required: true, + componentProps: { min: 1, max: 65535, style: { width: '100%' } }, + }, + { + label: '数据库名', + field: 'dbName', + component: 'Input', + defaultValue: 'MES_ShareDB', + required: true, + }, + { + label: '用户名', + field: 'dbUsername', + component: 'Input', + required: true, + componentProps: { placeholder: '例如 sa' }, + }, + { + label: '密码', + field: 'dbPassword', + component: 'InputPassword', + componentProps: { placeholder: '编辑时留空表示不修改密码' }, + }, + { + label: '读取开关', + field: 'readEnabled', + component: 'Switch', + helpMessage: '关闭后所有中间表列表/详情查询将被拦截(含 MCS→MES 与 MES→MCS 方向)', + componentProps: { + checkedChildren: '开启', + checkedValue: 1, + unCheckedChildren: '关闭', + unCheckedValue: 0, + }, + defaultValue: 1, + }, + { + label: '写入开关', + field: 'writeEnabled', + component: 'Switch', + helpMessage: '关闭后 MES→MCS 方向的增删改将被拦截(不影响列表查询,查询由读取开关控制)', + componentProps: { + checkedChildren: '开启', + checkedValue: 1, + unCheckedChildren: '关闭', + unCheckedValue: 0, + }, + defaultValue: 1, + }, + { + label: '启用连接', + field: 'status', + component: 'Switch', + helpMessage: '开启后立即连接中间库并热刷新数据源,无需重启后端', + componentProps: { + checkedChildren: '启用', + checkedValue: 1, + unCheckedChildren: '停用', + unCheckedValue: 0, + }, + defaultValue: 0, + }, + { + label: '登录超时(秒)', + field: 'loginTimeout', + component: 'InputNumber', + defaultValue: 120, + componentProps: { min: 10, max: 600, style: { width: '100%' } }, + }, + { + label: '连接超时(毫秒)', + field: 'connectTimeout', + component: 'InputNumber', + defaultValue: 120000, + componentProps: { min: 5000, max: 600000, style: { width: '100%' } }, + }, + { + label: '备注', + field: 'remark', + component: 'InputTextArea', + componentProps: { rows: 2 }, + }, +]; diff --git a/jeecgboot-vue3/src/views/system/appconfig/McsDbConfigModal.vue b/jeecgboot-vue3/src/views/system/appconfig/McsDbConfigModal.vue new file mode 100644 index 00000000..b6c745fb --- /dev/null +++ b/jeecgboot-vue3/src/views/system/appconfig/McsDbConfigModal.vue @@ -0,0 +1,62 @@ + + + diff --git a/jeecgboot-vue3/src/views/system/appconfig/ThirdAppConfigList.vue b/jeecgboot-vue3/src/views/system/appconfig/ThirdAppConfigList.vue index 12eff09f..a0b238d9 100644 --- a/jeecgboot-vue3/src/views/system/appconfig/ThirdAppConfigList.vue +++ b/jeecgboot-vue3/src/views/system/appconfig/ThirdAppConfigList.vue @@ -5,6 +5,7 @@
  • 钉钉集成
  • 企业微信集成
  • 金蝶集成
  • +
  • 上辅机中间库
  • @@ -16,14 +17,19 @@
    +
    + +
    + +