Junjie
2026-04-24 aef500a5cebed741c69e2bc3426bc8342db30bf1
src/main/java/com/zy/asrs/controller/OpenController.java
@@ -1,10 +1,12 @@
package com.zy.asrs.controller;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.core.common.Cools;
import com.core.common.R;
import com.core.exception.CoolException;
import com.zy.asrs.domain.Result.CancelTaskBatchResult;
import com.zy.asrs.domain.param.*;
import com.core.annotations.ManagerAuth;
import com.zy.asrs.entity.DeviceConfig;
import com.zy.asrs.entity.LocMast;
import com.zy.asrs.entity.WrkMast;
@@ -20,6 +22,7 @@
import com.zy.core.model.protocol.DualCrnProtocol;
import com.zy.core.model.protocol.RgvProtocol;
import com.zy.core.model.protocol.StationProtocol;
import com.zy.core.network.fake.FakeConfigKeys;
import com.zy.core.thread.CrnThread;
import com.zy.core.thread.DualCrnThread;
import com.zy.core.thread.RgvThread;
@@ -34,8 +37,11 @@
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
@Slf4j
@RestController
@@ -109,19 +115,11 @@
        if (param == null) {
            return R.error("参数不能为空");
        }
        List<CreateOutTaskParam> taskList = param.getTaskList();
        if (taskList == null || taskList.size() == 0) {
            return R.error("任务列表不能为空");
        boolean result = commonService.createOutTaskBatch(param);
        if (result) {
            return R.ok();
        }
        for (CreateOutTaskParam createOutTaskParam : taskList) {
            if (createOutTaskParam == null) {
                throw new CoolException("任务参数不能为空");
            }
            commonService.createOutTask(createOutTaskParam);
        }
        return R.ok();
        return R.error("生成批量出库任务失败");
    }
    @PostMapping("/completeTask")
@@ -150,13 +148,59 @@
        return R.error("任务取消失败");
    }
    @RequestMapping("/deviceStatus")
    @PostMapping("/manualRollbackTask")
    @OpenApiLog(memo = "任务人工回滚")
    public R manualRollbackTask(@RequestBody ManualRollbackTaskParam param) {
        if (param == null) {
            return R.error("参数不能为空");
        }
        boolean rollback = commonService.manualRollbackTask(param);
        if (rollback) {
            return R.ok();
        }
        return R.error("任务人工回滚失败");
    }
    @PostMapping("/cancelTaskBatch")
    @OpenApiLog(memo = "任务批量取消")
    public R cancelTaskBatch(@RequestBody CancelTaskBatchParam param) {
        if (param == null) {
            return R.error("参数不能为空");
        }
        CancelTaskBatchResult result = commonService.cancelTaskBatch(param);
        return R.ok().add(result);
    }
    @PostMapping("/updateTaskPriorityAndBatchSeq")
    @OpenApiLog(memo = "修改任务优先级和批次序号")
    public R updateTaskPriorityAndBatchSeq(@RequestBody UpdateTaskPriorityAndBatchSeqParam param) {
        if (param == null) {
            return R.error("参数不能为空");
        }
        boolean result = commonService.updateTaskPriorityAndBatchSeq(param);
        if (result) {
            return R.ok();
        }
        return R.error("修改任务优先级和批次序号失败");
    }
    @PostMapping("/cancelOutTaskBatchInfo")
    @OpenApiLog(memo = "取消出库任务批次和批次序号")
    public R cancelOutTaskBatchInfo(@RequestBody CancelTaskBatchParam param) {
        if (param == null) {
            return R.error("参数不能为空");
        }
        CancelTaskBatchResult result = commonService.cancelOutTaskBatchInfo(param);
        return R.ok().add(result);
    }
    @PostMapping("/deviceStatus")
    // @OpenApiLog(memo = "获取设备状态")
    public R getDeviceStatus() {
        HashMap<String, Object> map = new HashMap<>();
        // 获取堆垛机数据
        ArrayList<CrnProtocol> crnProtocols = new ArrayList<>();
        List<DeviceConfig> crnList = deviceConfigService.selectList(new EntityWrapper<DeviceConfig>()
        List<DeviceConfig> crnList = deviceConfigService.list(new QueryWrapper<DeviceConfig>()
                .eq("device_type", String.valueOf(SlaveType.Crn)));
        for (DeviceConfig device : crnList) {
            CrnThread crnThread = (CrnThread) SlaveConnection.get(SlaveType.Crn, device.getDeviceNo());
@@ -173,7 +217,7 @@
        // 获取RGV数据
        ArrayList<RgvProtocol> rgvProtocols = new ArrayList<>();
        List<DeviceConfig> rgvList = deviceConfigService.selectList(new EntityWrapper<DeviceConfig>()
        List<DeviceConfig> rgvList = deviceConfigService.list(new QueryWrapper<DeviceConfig>()
                .eq("device_type", String.valueOf(SlaveType.Rgv)));
        for (DeviceConfig device : rgvList) {
            RgvThread rgvThread = (RgvThread) SlaveConnection.get(SlaveType.Rgv, device.getDeviceNo());
@@ -190,7 +234,7 @@
        // 获取双工位堆垛机数据
        ArrayList<DualCrnProtocol> dualCrnProtocols = new ArrayList<>();
        List<DeviceConfig> dualCrnList = deviceConfigService.selectList(new EntityWrapper<DeviceConfig>()
        List<DeviceConfig> dualCrnList = deviceConfigService.list(new QueryWrapper<DeviceConfig>()
                .eq("device_type", String.valueOf(SlaveType.DualCrn)));
        for (DeviceConfig device : dualCrnList) {
            DualCrnThread dualCrnThread = (DualCrnThread) SlaveConnection.get(SlaveType.DualCrn, device.getDeviceNo());
@@ -207,7 +251,7 @@
        // 获取输送站点数据
        ArrayList<StationProtocol> stationProtocols = new ArrayList<>();
        List<DeviceConfig> stationList = deviceConfigService.selectList(new EntityWrapper<DeviceConfig>()
        List<DeviceConfig> stationList = deviceConfigService.list(new QueryWrapper<DeviceConfig>()
                .eq("device_type", String.valueOf(SlaveType.Devp)));
        for (DeviceConfig device : stationList) {
            StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, device.getDeviceNo());
@@ -227,6 +271,38 @@
        map.put("dualCrnList", dualCrnProtocols);
        map.put("stationList", stationProtocols);
        return R.ok().add(map);
    }
    @PostMapping("/stationStatus")
    public R getStationStatus(@RequestBody GetStationStatusParam param) {
        // 获取输送站点数据
        List<StationProtocol> stationProtocols = new ArrayList<>();
        List<DeviceConfig> devpList = deviceConfigService.list(new QueryWrapper<DeviceConfig>()
                .eq("device_type", String.valueOf(SlaveType.Devp))
        );
        for (DeviceConfig device : devpList) {
            StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, device.getDeviceNo());
            if (stationThread == null) {
                continue;
            }
            List<StationProtocol> tmp = new ArrayList<>();
            if(param.getStationIds() == null || param.getStationIds().isEmpty()) {
                tmp.addAll(stationThread.getStatus());
            }else {
                Map<Integer, StationProtocol> statusMap = stationThread.getStatusMap();
                for (Integer stationId : param.getStationIds()) {
                    StationProtocol stationProtocol = statusMap.get(stationId);
                    if (stationProtocol == null) {
                        continue;
                    }
                    tmp.add(stationProtocol);
                }
            }
            stationProtocols.addAll(tmp);
        }
        return R.ok().add(stationProtocols);
    }
    @PostMapping("/getLocInformation")
@@ -251,7 +327,7 @@
    @OpenApiLog(memo = "获取全部库位信息")
    public R getAllLocInformation(@RequestBody GetAllLocInformationParam param) {
        List<HashMap<String, Object>> list = new ArrayList<>();
        EntityWrapper<LocMast> wrapper = new EntityWrapper<>();
        QueryWrapper<LocMast> wrapper = new QueryWrapper<>();
        if (!Cools.isEmpty(param.getRow())) {
            wrapper.eq("row1", param.getRow());
@@ -261,7 +337,7 @@
            wrapper.eq("lev1", param.getLev());
        }
        List<LocMast> locMasts = locMastService.selectList(wrapper);
        List<LocMast> locMasts = locMastService.list(wrapper);
        if (locMasts.isEmpty()) {
            return R.ok().add(list);
        }
@@ -283,7 +359,7 @@
    @PostMapping("/queryTask")
    @OpenApiLog(memo = "查询任务")
    public R queryTask(@RequestBody QueryTaskParam param) {
        EntityWrapper<WrkMast> wrapper = new EntityWrapper<>();
        QueryWrapper<WrkMast> wrapper = new QueryWrapper<>();
        if (param.getTaskNo() != null) {
            wrapper.eq("wms_wrk_no", param.getTaskNo());
        }
@@ -295,7 +371,7 @@
            }
            wrapper.eq("io_type", ioType.id);
        }
        List<WrkMast> wrkMasts = wrkMastService.selectList(wrapper);
        List<WrkMast> wrkMasts = wrkMastService.list(wrapper);
        return R.ok().add(wrkMasts);
    }
@@ -318,7 +394,7 @@
        if (mainProcessPlugin.contains("Fake")) {
            map.put("running", false);
            map.put("isFake", true);
            Config config = configService.selectOne(new EntityWrapper<Config>().eq("code", "enableFake"));
            Config config = configService.getOne(new QueryWrapper<Config>().eq("code", "enableFake"));
            if (config != null) {
                if (config.getValue().equals("Y")) {
                    map.put("running", true);
@@ -333,7 +409,7 @@
    @PostMapping("/startFakeSystem")
    @OpenApiLog(memo = "启动仿真模拟")
    public R startFakeSystem() {
        Config config = configService.selectOne(new EntityWrapper<Config>().eq("code", "enableFake"));
        Config config = configService.getOne(new QueryWrapper<Config>().eq("code", "enableFake"));
        if (config != null) {
            config.setValue("Y");
            configService.updateById(config);
@@ -344,7 +420,7 @@
    @PostMapping("/stopFakeSystem")
    @OpenApiLog(memo = "停止仿真模拟")
    public R stopFakeSystem() {
        Config config = configService.selectOne(new EntityWrapper<Config>().eq("code", "enableFake"));
        Config config = configService.getOne(new QueryWrapper<Config>().eq("code", "enableFake"));
        if (config != null) {
            config.setValue("N");
            configService.updateById(config);
@@ -352,4 +428,87 @@
        return R.ok();
    }
    @GetMapping("/fakeConfig/auth")
    @ManagerAuth
    public R getFakeConfig() {
        LinkedHashMap<String, Object> map = new LinkedHashMap<>();
        for (String key : FakeConfigKeys.ALL_KEYS) {
            String defaultValue = FakeConfigKeys.DEFAULTS.get(key);
            map.put(key, configService.getConfigValue(key, defaultValue));
        }
        return R.ok().add(map);
    }
    @PostMapping("/fakeConfig/save/auth")
    @ManagerAuth
    public R saveFakeConfig(@RequestBody FakeConfigSaveParam param) {
        if (param == null || param.getConfigMap() == null || param.getConfigMap().isEmpty()) {
            return R.error("参数不能为空");
        }
        Set<String> allowKeys = FakeConfigKeys.ALL_KEYS;
        Map<String, String> normalizedMap = new LinkedHashMap<>();
        for (Map.Entry<String, Object> entry : param.getConfigMap().entrySet()) {
            String key = entry.getKey();
            if (!allowKeys.contains(key)) {
                return R.error("不支持的配置项: " + key);
            }
            normalizedMap.put(key, normalizeFakeConfigValue(key, entry.getValue()));
        }
        validateFakeCrnLaserConfig(normalizedMap);
        for (Map.Entry<String, String> entry : normalizedMap.entrySet()) {
            if (!configService.saveConfigValue(entry.getKey(), entry.getValue())) {
                return R.error("保存失败: " + entry.getKey());
            }
        }
        configService.refreshSystemConfigCache();
        return getFakeConfig();
    }
    private void validateFakeCrnLaserConfig(Map<String, String> normalizedMap) {
        long bayMin = resolveFakeLongValue(normalizedMap, FakeConfigKeys.FAKE_CRN_BAY_MIN);
        long bayMax = resolveFakeLongValue(normalizedMap, FakeConfigKeys.FAKE_CRN_BAY_MAX);
        long laserMin = resolveFakeLongValue(normalizedMap, FakeConfigKeys.FAKE_CRN_LASER_MIN);
        long laserMax = resolveFakeLongValue(normalizedMap, FakeConfigKeys.FAKE_CRN_LASER_MAX);
        if (bayMax <= bayMin) {
            throw new CoolException("堆垛机 bay 最大值必须大于最小值");
        }
        if (laserMax <= laserMin) {
            throw new CoolException("堆垛机镭射最大值必须大于最小值");
        }
    }
    private long resolveFakeLongValue(Map<String, String> normalizedMap, String key) {
        String value = normalizedMap.get(key);
        if (value == null) {
            value = configService.getConfigValue(key, FakeConfigKeys.DEFAULTS.get(key));
        }
        return Long.parseLong(value);
    }
    private String normalizeFakeConfigValue(String key, Object rawValue) {
        if (rawValue == null) {
            throw new CoolException(key + " 参数不能为空");
        }
        String value = String.valueOf(rawValue).trim();
        if (FakeConfigKeys.BOOLEAN_KEYS.contains(key)) {
            if (!"Y".equalsIgnoreCase(value) && !"N".equalsIgnoreCase(value)) {
                throw new CoolException(key + " 仅支持 Y/N");
            }
            return value.toUpperCase();
        }
        if (FakeConfigKeys.LONG_KEYS.contains(key)) {
            long parsed;
            try {
                parsed = Long.parseLong(value);
            } catch (Exception e) {
                throw new CoolException(key + " 必须为非负整数");
            }
            if (parsed < 0) {
                throw new CoolException(key + " 必须为非负整数");
            }
            return String.valueOf(parsed);
        }
        throw new CoolException("不支持的配置项: " + key);
    }
}