Junjie
2026-04-25 b06e3fc3f04d03ed37e5106d4aef69b89acffcc0
#增加外部修改系统参数接口V3.0.1.0
4个文件已添加
3个文件已修改
246 ■■■■■ 已修改文件
.gitignore 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/OpenController.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/domain/param/RuntimeConfigUpdateParam.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/RuntimeConfigService.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/RuntimeConfigServiceImpl.java 211 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application.yml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/docs/WCS外部HTTP API接口V2.1.docx 补丁 | 查看 | 原始文档 | blame | 历史
.gitignore
@@ -29,7 +29,7 @@
build/
output/
tmp/
docs/
/docs/
.playwright-cli/
.claude/
.superpowers/
src/main/java/com/zy/asrs/controller/OpenController.java
@@ -12,6 +12,7 @@
import com.zy.asrs.entity.WrkMast;
import com.zy.asrs.service.DeviceConfigService;
import com.zy.asrs.service.LocMastService;
import com.zy.asrs.service.RuntimeConfigService;
import com.zy.asrs.service.WrkMastService;
import com.zy.common.annotations.OpenApiLog;
import com.zy.common.service.CommonService;
@@ -64,6 +65,8 @@
    private ConfigService configService;
    @Autowired
    private DeviceConfigService deviceConfigService;
    @Autowired
    private RuntimeConfigService runtimeConfigService;
    // ç§»åº“任务
    @PostMapping("/createLocMoveTask")
@@ -388,6 +391,15 @@
        return R.ok().add(map);
    }
    @PostMapping("/runtimeConfig/update")
    @OpenApiLog(memo = "修改运行参数")
    public R updateRuntimeConfig(@RequestBody RuntimeConfigUpdateParam param) {
        if (param == null || param.getConfigMap() == null || param.getConfigMap().isEmpty()) {
            return R.error("参数不能为空");
        }
        return R.ok().add(runtimeConfigService.updateRuntimeConfig(param.getConfigMap()));
    }
    @GetMapping("/getFakeSystemRunStatus")
    public R getFakeSystemRunStatus() {
        HashMap<String, Object> map = new HashMap<>();
src/main/java/com/zy/asrs/domain/param/RuntimeConfigUpdateParam.java
New file
@@ -0,0 +1,11 @@
package com.zy.asrs.domain.param;
import lombok.Data;
import java.util.Map;
@Data
public class RuntimeConfigUpdateParam {
    private Map<String, Object> configMap;
}
src/main/java/com/zy/asrs/service/RuntimeConfigService.java
New file
@@ -0,0 +1,8 @@
package com.zy.asrs.service;
import java.util.Map;
public interface RuntimeConfigService {
    Map<String, Object> updateRuntimeConfig(Map<String, Object> configMap);
}
src/main/java/com/zy/asrs/service/impl/RuntimeConfigServiceImpl.java
New file
@@ -0,0 +1,211 @@
package com.zy.asrs.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.core.exception.CoolException;
import com.zy.asrs.service.RuntimeConfigService;
import com.zy.system.entity.Config;
import com.zy.system.service.ConfigService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
@Service("runtimeConfigService")
public class RuntimeConfigServiceImpl implements RuntimeConfigService {
    private static final LinkedHashMap<String, RuntimeConfigRule> RUNTIME_CONFIG_RULE_MAP = buildRuntimeConfigRuleMap();
    @Autowired
    private ConfigService configService;
    @Override
    @Transactional
    public Map<String, Object> updateRuntimeConfig(Map<String, Object> configMap) {
        if (configMap == null || configMap.isEmpty()) {
            throw new CoolException("参数不能为空");
        }
        LinkedHashMap<String, String> normalizedMap = new LinkedHashMap<>();
        for (Map.Entry<String, Object> entry : configMap.entrySet()) {
            String code = entry.getKey();
            RuntimeConfigRule rule = RUNTIME_CONFIG_RULE_MAP.get(code);
            if (rule == null) {
                throw new CoolException("不支持的运行参数: " + code);
            }
            Config config = getConfig(code);
            if (config == null) {
                throw new CoolException("运行参数不存在: " + code);
            }
            if (!Short.valueOf((short) 1).equals(config.getStatus())) {
                throw new CoolException("运行参数已禁用: " + code);
            }
            normalizedMap.put(code, rule.normalize(code, entry.getValue()));
        }
        LinkedHashMap<String, String> changedMap = saveChangedConfig(normalizedMap);
        if (!changedMap.isEmpty()) {
            configService.refreshSystemConfigCache();
        }
        LinkedHashMap<String, Object> result = new LinkedHashMap<>();
        result.put("changed", changedMap);
        result.put("current", buildRuntimeConfigSnapshot(normalizedMap.keySet()));
        return result;
    }
    private LinkedHashMap<String, String> saveChangedConfig(LinkedHashMap<String, String> normalizedMap) {
        LinkedHashMap<String, String> changedMap = new LinkedHashMap<>();
        for (Map.Entry<String, String> entry : normalizedMap.entrySet()) {
            Config config = getConfig(entry.getKey());
            if (config == null) {
                throw new CoolException("运行参数不存在: " + entry.getKey());
            }
            if (Objects.equals(config.getValue(), entry.getValue())) {
                continue;
            }
            config.setValue(entry.getValue());
            if (!configService.updateById(config)) {
                throw new CoolException("保存失败: " + entry.getKey());
            }
            changedMap.put(entry.getKey(), entry.getValue());
        }
        return changedMap;
    }
    private LinkedHashMap<String, String> buildRuntimeConfigSnapshot(Set<String> codeSet) {
        LinkedHashMap<String, String> result = new LinkedHashMap<>();
        for (String code : codeSet) {
            Config config = getConfig(code);
            if (config != null) {
                result.put(code, config.getValue());
            }
        }
        return result;
    }
    private Config getConfig(String code) {
        return configService.getOne(new QueryWrapper<Config>().eq("code", code).last("limit 1"));
    }
    private static LinkedHashMap<String, RuntimeConfigRule> buildRuntimeConfigRuleMap() {
        LinkedHashMap<String, RuntimeConfigRule> ruleMap = new LinkedHashMap<>();
        putIntRule(ruleMap, "conveyorStationTaskLimit", 1, 1000);
        putIntRule(ruleMap, "stationMaxTaskCountLimit", 0, 1000);
        putIntRule(ruleMap, "stationCommandSendLength", 1, 200);
        putRatioRule(ruleMap, "stationCommandSegmentAdvanceRatio");
        putIntRule(ruleMap, "stationCommandConfigRefreshSeconds", 5, 300);
        putIntRule(ruleMap, "stationV5SegmentExecutorPoolSize", 16, 512);
        putIntRule(ruleMap, "stationV5SegmentExecutorQueueCapacity", 64, 4096);
        putIntRule(ruleMap, "crnOutBatchRunningLimit", 0, 1000);
        putBooleanRule(ruleMap, "crnOutRequireStationOutEnable");
        putIntRule(ruleMap, "deviceCommandAutoRollbackLimit", 1, 100);
        putBooleanRule(ruleMap, "checkDeepLocOutTaskBlockReport");
        return ruleMap;
    }
    private static void putIntRule(LinkedHashMap<String, RuntimeConfigRule> ruleMap,
                                   String code,
                                   int min,
                                   int max) {
        ruleMap.put(code, new RuntimeConfigRule(RuntimeConfigValueType.INT, min, max));
    }
    private static void putRatioRule(LinkedHashMap<String, RuntimeConfigRule> ruleMap, String code) {
        ruleMap.put(code, new RuntimeConfigRule(RuntimeConfigValueType.RATIO, 0, 100));
    }
    private static void putBooleanRule(LinkedHashMap<String, RuntimeConfigRule> ruleMap, String code) {
        ruleMap.put(code, new RuntimeConfigRule(RuntimeConfigValueType.BOOLEAN, 0, 0));
    }
    private enum RuntimeConfigValueType {
        INT,
        RATIO,
        BOOLEAN
    }
    private static class RuntimeConfigRule {
        private final RuntimeConfigValueType valueType;
        private final int min;
        private final int max;
        private RuntimeConfigRule(RuntimeConfigValueType valueType, int min, int max) {
            this.valueType = valueType;
            this.min = min;
            this.max = max;
        }
        private String normalize(String code, Object rawValue) {
            if (rawValue == null) {
                throw new CoolException(code + " å‚数不能为空");
            }
            String value = String.valueOf(rawValue).trim();
            if (value.isEmpty()) {
                throw new CoolException(code + " å‚数不能为空");
            }
            if (RuntimeConfigValueType.BOOLEAN.equals(valueType)) {
                return normalizeBoolean(code, value);
            }
            if (RuntimeConfigValueType.RATIO.equals(valueType)) {
                return normalizeRatio(code, value);
            }
            return normalizeInt(code, value);
        }
        private String normalizeBoolean(String code, String value) {
            if ("Y".equalsIgnoreCase(value) || "true".equalsIgnoreCase(value) || "1".equals(value)) {
                return "Y";
            }
            if ("N".equalsIgnoreCase(value) || "false".equalsIgnoreCase(value) || "0".equals(value)) {
                return "N";
            }
            throw new CoolException(code + " ä»…支持 Y/N、true/false æˆ– 1/0");
        }
        private String normalizeRatio(String code, String value) {
            String text = value;
            boolean percentText = text.endsWith("%");
            if (percentText) {
                text = text.substring(0, text.length() - 1).trim();
            }
            double parsed;
            try {
                parsed = Double.parseDouble(text);
            } catch (Exception e) {
                throw new CoolException(code + " å¿…须为 0~1 æ¯”例或 0~100 ç™¾åˆ†æ¯”");
            }
            if (parsed < 0d || parsed > 100d) {
                throw new CoolException(code + " å¿…须为 0~1 æ¯”例或 0~100 ç™¾åˆ†æ¯”");
            }
            if (percentText || parsed > 1d) {
                parsed = parsed / 100d;
            }
            return stripTrailingZero(parsed);
        }
        private String normalizeInt(String code, String value) {
            int parsed;
            try {
                parsed = Integer.parseInt(value);
            } catch (Exception e) {
                throw new CoolException(code + " å¿…须为整数");
            }
            if (parsed < min || parsed > max) {
                throw new CoolException(code + " å¿…须在 " + min + "~" + max + " èŒƒå›´å†…");
            }
            return String.valueOf(parsed);
        }
        private String stripTrailingZero(double value) {
            String text = java.math.BigDecimal.valueOf(value).stripTrailingZeros().toPlainString();
            return "-0".equals(text) ? "0" : text;
        }
    }
}
src/main/resources/application.yml
@@ -1,6 +1,6 @@
# ç³»ç»Ÿç‰ˆæœ¬ä¿¡æ¯
app:
  version: 3.0.0.9
  version: 3.0.1.0
  version-type: prd  # prd æˆ– dev
  i18n:
    default-locale: zh-CN
src/main/resources/docs/WCSÍⲿHTTP API½Ó¿ÚV2.1.docx
Binary files differ