2003a72a765234d8a116b7d2b768ef752bf75b5c..8280c9eee52dd9fa3501305dfd4d1cab1564a73b
2025-12-20 Junjie
#
8280c9 对比 | 目录
2025-12-20 Junjie
#
4afa88 对比 | 目录
2025-12-20 Junjie
#
0c146e 对比 | 目录
2025-12-20 Junjie
#
d12843 对比 | 目录
1个文件已添加
15个文件已修改
429 ■■■■ 已修改文件
src/main/java/com/zy/asrs/entity/BasDevp.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/utils/Utils.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/common/config/MethodTimingAspect.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/common/model/NavigateNode.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/common/utils/NavigateSolution.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/common/utils/NavigateUtils.java 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/network/fake/ZyStationFakeConnect.java 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/plugin/FakeProcess.java 153 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/task/DeviceLogScheduler.java 72 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/utils/CrnOperateProcessUtils.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/utils/StationOperateProcessUtils.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/utils/WmsOperateUtils.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application.yml 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/BasDevpMapper.xml 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/static/js/basDevp/basDevp.js 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/views/basDevp/basDevp.html 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/BasDevp.java
@@ -113,13 +113,6 @@
    @TableField("run_block_reassign_loc_station_list")
    private String runBlockReassignLocStationList;
    /**
     *  顶升移栽站点数据
     */
    @ApiModelProperty(value= "顶升移栽站点数据")
    @TableField("lift_transfer_station_list")
    private String liftTransferStationList;
    public BasDevp() {}
    public BasDevp(Integer devpNo,Integer status,Long createBy,Date createTime,Long updateBy,Date updateTime,String memo,String stationList,String barcodeStationList,String inStationList,String outStationList) {
src/main/java/com/zy/asrs/utils/Utils.java
@@ -141,11 +141,11 @@
    //获取入库任务可用排
    public static List<Integer> getInTaskEnableRow() {
        return getInTaskEnableRow(new ArrayList<>());
        return getInTaskEnableRow(new ArrayList<>(), true);
    }
    //获取入库任务可用排
    public static List<Integer> getInTaskEnableRow(List<Integer> excludeCrnList) {
    public static List<Integer> getInTaskEnableRow(List<Integer> excludeCrnList, boolean maxInTaskControl) {
        List<Integer> list = new ArrayList<>();
        try {
            RedisUtil redisUtil = SpringUtils.getBean(RedisUtil.class);
@@ -202,7 +202,7 @@
                        .eq("io_type", WrkIoType.IN.id)
                );
                // 检查是否超过最大入库任务数
                if(inWrkMasts.size() >= basCrnp.getMaxInTask()){
                if (maxInTaskControl && inWrkMasts.size() >= basCrnp.getMaxInTask()) {
                    News.info("堆垛机:{} 已达最大入库任务数,当前任务数:{}", basCrnp.getCrnNo(), inWrkMasts.size());
                    continue;
                }
@@ -220,7 +220,7 @@
                    list.addAll(rows);
                }
            }
        }catch (Exception e){
        } catch (Exception e) {
            e.printStackTrace();
        }
        return list;
src/main/java/com/zy/common/config/MethodTimingAspect.java
New file
@@ -0,0 +1,46 @@
package com.zy.common.config;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
@Component
@Aspect
@Slf4j
@Order(Ordered.LOWEST_PRECEDENCE)
@ConditionalOnProperty(prefix = "perf.methodTiming", name = "enabled", havingValue = "true")
public class MethodTimingAspect {
    @Value("${perf.methodTiming.thresholdMs:50}")
    private long thresholdMs;
    @Value("${perf.methodTiming.sampleRate:1.0}")
    private double sampleRate;
    @Around("execution(public * com.zy.core..*(..))")
    public Object timeCorePublicMethods(ProceedingJoinPoint joinPoint) throws Throwable {
        if (sampleRate < 1.0d && ThreadLocalRandom.current().nextDouble() > sampleRate) {
            return joinPoint.proceed();
        }
        long startNs = System.nanoTime();
        try {
            return joinPoint.proceed();
        } finally {
            long costMs = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNs);
            if (costMs >= thresholdMs) {
                log.warn("SLOW {} took {} ms (thread={})", joinPoint.getSignature().toShortString(), costMs, Thread.currentThread().getName());
            }
        }
    }
}
src/main/java/com/zy/common/model/NavigateNode.java
@@ -20,7 +20,9 @@
    private int value;
    @ToString.Exclude
    private NavigateNode Father;//父节点
    private List<String> directionList;//行走方向
    private List<String> directionList;//允许行走方向
    private Boolean isInflectionPoint;//是否为拐点
    private String direction;//行走方向
    private String nodeValue;//节点数据
    private String nodeType;//节点类型
src/main/java/com/zy/common/utils/NavigateSolution.java
@@ -11,7 +11,6 @@
import com.zy.core.enums.MapNodeType;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BiFunction;
/**
 * A*算法实现类
src/main/java/com/zy/common/utils/NavigateUtils.java
@@ -65,6 +65,20 @@
            }
        }
        for (int i = 0; i < fitlerList.size(); i++) {
            NavigateNode currentNode = fitlerList.get(i);
            currentNode.setIsInflectionPoint(false);
            NavigateNode nextNode = (i + 1 < fitlerList.size()) ? fitlerList.get(i + 1) : null;
            NavigateNode prevNode = (i - 1 >= 0) ? fitlerList.get(i - 1) : null;
            HashMap<String, Object> result = searchInflectionPoint(currentNode, nextNode, prevNode);
            if (Boolean.parseBoolean(result.get("result").toString())) {
                currentNode.setIsInflectionPoint(true);
                currentNode.setDirection(result.get("direction").toString());
            }
        }
        return fitlerList;
    }
@@ -95,8 +109,22 @@
        HashSet<NavigateNode> visited = new HashSet<>();
        int maxSteps = rgvTrackMap.size() * rgvTrackMap.get(0).size() + 5; // 安全上限
        int steps = 0;
        NavigateNode fatherNode = null;//当前循环上一节点,用于拐点计算
        while (res_node != null && visited.add(res_node) && steps++ < maxSteps) {
            res_node.setIsInflectionPoint(false);
            //寻找拐点
            HashMap<String, Object> result = searchInflectionPoint(res_node, fatherNode, res_node.getFather());//分别传入当前节点、父节点、下一节点
            //判断当前节点是否为拐点
            if (Boolean.parseBoolean(result.get("result").toString())) {
                //当前为拐点
                res_node.setIsInflectionPoint(true);
                //拐点方向
                res_node.setDirection(result.get("direction").toString());
            }
            list.add(res_node);
            fatherNode = res_node;//把当前节点保存成一个父节点
            res_node = res_node.getFather();//迭代操作
        }
        if (steps >= maxSteps) {
@@ -284,4 +312,56 @@
        }
        return best;
    }
    //判断当前节点到下一个节点是否为拐点
    public HashMap<String,Object> searchInflectionPoint(NavigateNode currentNode, NavigateNode fatherNode, NavigateNode nextNode) {
        HashMap<String, Object> map = new HashMap<>();
        map.put("result", false);//是否为拐点,true:拐点,false:直线
        // 第一个点或直线点
        if (fatherNode == null || nextNode == null || nextNode.getX() == fatherNode.getX() || nextNode.getY() == fatherNode.getY()) {
            return map;//不是拐点直接返回
        }
        //拐点方向
        String direction = calcDirection(currentNode, fatherNode);
        map.put("result", true);//拐点
        map.put("direction", direction);//拐点方向(从当前节点视角看的方向)
        return map;
    }
    /**
     * 计算方向
     */
    public String calcDirection(NavigateNode currentNode, NavigateNode fatherNode) {
        //拐点方向
        String direction = "";
        // 普通拐点
        //计算拐点方向
        if (fatherNode.getX() != currentNode.getX()) {
            //x轴数据有差异,判断x轴方向
            //当前节点X - 父节点X
            if (currentNode.getX() - fatherNode.getX() > 0) {
                //大于0,方向top
                direction = "top";
            }else {
                //小于0,方向bottom
                direction = "bottom";
            }
        }
        if (fatherNode.getY() != currentNode.getY()) {
            //y轴数据有差异,判断y轴方向
            //当前节点Y - 父节点Y
            if (currentNode.getY() - fatherNode.getY() > 0) {
                //大于0,方向left
                direction = "left";
            }else {
                //小于0,方向right
                direction = "right";
            }
        }
        return direction;
    }
}
src/main/java/com/zy/core/network/fake/ZyStationFakeConnect.java
@@ -18,6 +18,7 @@
import java.util.HashMap;
import java.util.List;
import java.util.Random;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@@ -305,8 +306,9 @@
            Integer nextStationId = null;
            Integer nextStationDeviceNo = null;
            NavigateNode nextNode = null;
            try {
                NavigateNode nextNode = navigateNodes.get(i + 1);
                nextNode = navigateNodes.get(i + 1);
                JSONObject nextValueObject = JSON.parseObject(nextNode.getNodeValue());
                nextStationId = nextValueObject.getInteger("stationId");
                nextStationDeviceNo = nextValueObject.getInteger("deviceNo");
@@ -351,6 +353,10 @@
                    continue;
                }
                lastStationId = currentStationId;
                if (nextNode.getIsInflectionPoint()) {
                    sleep(4000);
                }
            }
            i++;
@@ -553,8 +559,10 @@
                return false;
            }
            Random random = new Random();
            String barcodeTime = String.valueOf(System.currentTimeMillis());
            String barcode = barcodeTime.substring(5);
            String barcode = String.valueOf(random.nextInt(10)) + String.valueOf(random.nextInt(10)) + barcodeTime.substring(7);
            boolean result = updateStationData(lockTaskNo, currentStationId, currentStationDeviceNo, null, null, null, barcode, null);
            if (!result) {
@@ -614,7 +622,7 @@
        return executeResult;
    }
    public synchronized boolean lockExecute(Integer taskNo, Supplier<Boolean> function) {
    public boolean lockExecute(Integer taskNo, Supplier<Boolean> function) {
        if (!setLockStation(taskNo)) {
            return false;
        }
@@ -624,7 +632,7 @@
        return result;
    }
    private synchronized boolean checkTaskNoInArea(Integer taskNo) {
    private boolean checkTaskNoInArea(Integer taskNo) {
        Object fakeTaskNoAreaObj = redisUtil.get(RedisKeyType.FAKE_TASK_NO_AREA.key);
        if (fakeTaskNoAreaObj == null) {
            return false;
src/main/java/com/zy/core/plugin/FakeProcess.java
@@ -21,6 +21,7 @@
import com.zy.core.model.command.StationCommand;
import com.zy.core.model.protocol.CrnProtocol;
import com.zy.core.model.protocol.StationProtocol;
import com.zy.core.properties.SystemProperties;
import com.zy.core.thread.CrnThread;
import com.zy.core.thread.StationThread;
import com.zy.core.utils.CrnOperateProcessUtils;
@@ -43,6 +44,9 @@
    private static String fakeRealTaskRequestWms = "N";
    private static String fakeGenerateInTask = "Y";
    private static String fakeGenerateOutTask = "Y";
    private Thread asyncRunThread = null;
    private Thread asyncFakeRunThread = null;
    @Autowired
    private WrkMastService wrkMastService;
@@ -67,41 +71,9 @@
    @Override
    public void run() {
        Config enableFakeConfig = configService.selectOne(new EntityWrapper<Config>().eq("code", "enableFake"));
        if (enableFakeConfig != null) {
            enableFake = enableFakeConfig.getValue();
        }
        asyncRun();
        asyncFakeRun();
        Config fakeRealTaskRequestWmsConfig = configService.selectOne(new EntityWrapper<Config>().eq("code", "fakeRealTaskRequestWms"));
        if (fakeRealTaskRequestWmsConfig != null) {
            fakeRealTaskRequestWms = fakeRealTaskRequestWmsConfig.getValue();
        }
        Config fakeGenerateInTaskConfig = configService.selectOne(new EntityWrapper<Config>().eq("code", "fakeGenerateInTask"));
        if (fakeGenerateInTaskConfig != null) {
            fakeGenerateInTask = fakeGenerateInTaskConfig.getValue();
        }
        Config fakeGenerateOutTaskConfig = configService.selectOne(new EntityWrapper<Config>().eq("code", "fakeGenerateOutTask"));
        if (fakeGenerateOutTaskConfig != null) {
            fakeGenerateOutTask = fakeGenerateOutTaskConfig.getValue();
        }
        //检测入库站是否有任务生成,并仿真生成模拟入库站点数据
        checkInStationHasTask();
        //生成仿真模拟入库任务
        generateFakeInTask();
        //生成仿真模拟出库任务
        generateFakeOutTask();
        //计算所有站点停留时间
        calcAllStationStayTime();
        //检测出库站点停留是否超时
        checkOutStationStayTimeOut();
        //检测入库站点堆垛机是否取走货物
        checkInStationCrnTake();
        //请求生成入库任务
        generateStoreWrkFile();
        //执行堆垛机任务
        crnOperateUtils.crnIoExecute();
        //堆垛机任务执行完成-具备仿真能力
@@ -112,8 +84,101 @@
        stationOperateProcessUtils.stationOutExecute();
        //检测输送站点出库任务执行完成
        stationOperateProcessUtils.stationOutExecuteFinish();
        //检测输送站点是否运行堵塞
        stationOperateProcessUtils.checkStationRunBlock();
    }
    public void asyncRun() {
        if (asyncRunThread != null) {
            return;
        }
        asyncRunThread = new Thread(() -> {
            while (!Thread.currentThread().isInterrupted()) {
                try {
                    // 系统运行状态判断
                    if (!SystemProperties.WCS_RUNNING_STATUS.get()) {
                        continue;
                    }
                    //请求生成入库任务
                    generateStoreWrkFile();
                    // 间隔
                    Thread.sleep(50);
                } catch (InterruptedException ie) {
                    Thread.currentThread().interrupt();
                    break;
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
        asyncRunThread.setName("asyncRunProcess");
        asyncRunThread.setDaemon(true);
        asyncRunThread.start();
    }
    public void asyncFakeRun() {
        if (asyncFakeRunThread != null) {
            return;
        }
        asyncFakeRunThread = new Thread(() -> {
            while (!Thread.currentThread().isInterrupted()) {
                try {
                    Config enableFakeConfig = configService.selectOne(new EntityWrapper<Config>().eq("code", "enableFake"));
                    if (enableFakeConfig != null) {
                        enableFake = enableFakeConfig.getValue();
                    }
                    Config fakeRealTaskRequestWmsConfig = configService.selectOne(new EntityWrapper<Config>().eq("code", "fakeRealTaskRequestWms"));
                    if (fakeRealTaskRequestWmsConfig != null) {
                        fakeRealTaskRequestWms = fakeRealTaskRequestWmsConfig.getValue();
                    }
                    Config fakeGenerateInTaskConfig = configService.selectOne(new EntityWrapper<Config>().eq("code", "fakeGenerateInTask"));
                    if (fakeGenerateInTaskConfig != null) {
                        fakeGenerateInTask = fakeGenerateInTaskConfig.getValue();
                    }
                    Config fakeGenerateOutTaskConfig = configService.selectOne(new EntityWrapper<Config>().eq("code", "fakeGenerateOutTask"));
                    if (fakeGenerateOutTaskConfig != null) {
                        fakeGenerateOutTask = fakeGenerateOutTaskConfig.getValue();
                    }
                    // 系统运行状态判断
                    if (!SystemProperties.WCS_RUNNING_STATUS.get()) {
                        continue;
                    }
                    //检测入库站是否有任务生成,并仿真生成模拟入库站点数据
                    checkInStationHasTask();
                    //生成仿真模拟入库任务
                    generateFakeInTask();
                    //生成仿真模拟出库任务
                    generateFakeOutTask();
                    //计算所有站点停留时间
                    calcAllStationStayTime();
                    //检测出库站点停留是否超时
                    checkOutStationStayTimeOut();
                    //检测入库站点堆垛机是否取走货物
                    checkInStationCrnTake();
                    //检测输送站点是否运行堵塞
                    stationOperateProcessUtils.checkStationRunBlock();
                    // 间隔
                    Thread.sleep(50);
                } catch (InterruptedException ie) {
                    Thread.currentThread().interrupt();
                    break;
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
        asyncFakeRunThread.setName("asyncFakeRunProcess");
        asyncFakeRunThread.setDaemon(true);
        asyncFakeRunThread.start();
    }
    //检测入库站是否有任务生成,并仿真生成模拟入库站点数据
@@ -202,7 +267,7 @@
                Object object = redisUtil.get(RedisKeyType.GENERATE_FAKE_IN_TASK_LIMIT.key + stationId);
                if (object != null) {
                    return;
                    continue;
                }
                //满足自动、有物、有工作号,生成入库数据
@@ -375,9 +440,13 @@
                    if (lock != null) {
                        continue;
                    }
                    redisUtil.set(RedisKeyType.GENERATE_IN_TASK_LIMIT.key + stationId, "lock", 5);
                    redisUtil.set(RedisKeyType.GENERATE_IN_TASK_LIMIT.key + stationId, "lock", 2);
                    String response = wmsOperateUtils.applyInTask(stationProtocol.getBarcode(), stationProtocol.getStationId(), stationProtocol.getPalletHeight());
                    if (response == null) {
                        News.error("请求WMS入库接口失败,接口未响应!!!response:{}", response);
                        continue;
                    }
                    JSONObject jsonObject = JSON.parseObject(response);
                    if (jsonObject.getInteger("code").equals(200)) {
                        StartupDto dto = jsonObject.getObject("data", StartupDto.class);
@@ -457,7 +526,7 @@
                    MessageQueue.offer(SlaveType.Devp, stationObjModel.getDeviceNo(), new Task(2, command));
                    redisUtil.set(RedisKeyType.CHECK_OUT_STATION_STAY_TIME_OUT_LIMIT.key + stationObjModel.getStationId(), "lock",10);
                    News.info("输送站点重置命令下发成功,站点号={},命令数据={}", stationObjModel.getStationId(), JSON.toJSONString(command));
                    News.info("输送站点出库重置命令下发成功,站点号={},命令数据={}", stationObjModel.getStationId(), JSON.toJSONString(command));
                }
            }
        }
@@ -500,7 +569,7 @@
                    if (wrkMast == null) {
                        MessageQueue.offer(SlaveType.Devp, stationObjModel.getDeviceNo(), new Task(2, command));
                        redisUtil.set(RedisKeyType.CHECK_IN_STATION_STAY_TIME_OUT_LIMIT.key + stationObjModel.getStationId(), "lock",10);
                        News.info("输送站点重置命令下发成功,站点号={},命令数据={}", stationObjModel.getStationId(), JSON.toJSONString(command));
                        News.info("输送站点重置命令下发成功(task_over),站点号={},命令数据={}", stationObjModel.getStationId(), JSON.toJSONString(command));
                    }else {
                        if (wrkMast.getWrkSts() != WrkStsType.NEW_INBOUND.sts && wrkMast.getWrkSts() != WrkStsType.INBOUND_DEVICE_RUN.sts) {
                            Integer crnNo = wrkMast.getCrnNo();
@@ -509,13 +578,13 @@
                                continue;
                            }
                            CrnProtocol crnProtocol = crnThread.getStatus();
                            if (crnProtocol.getStatusType().equals(CrnStatusType.FETCH_MOVING) || crnProtocol.getStatusType().equals(CrnStatusType.FETCHING)) {
                            if (!crnProtocol.getStatusType().equals(CrnStatusType.PUT_MOVING) && !crnProtocol.getStatusType().equals(CrnStatusType.PUTTING)) {
                                continue;
                            }
                            MessageQueue.offer(SlaveType.Devp, stationObjModel.getDeviceNo(), new Task(2, command));
                            redisUtil.set(RedisKeyType.CHECK_IN_STATION_STAY_TIME_OUT_LIMIT.key + stationObjModel.getStationId(), "lock",10);
                            News.info("输送站点重置命令下发成功,站点号={},命令数据={}", stationObjModel.getStationId(), JSON.toJSONString(command));
                            News.info("输送站点重置命令下发成功(crn_fetch),站点号={},命令数据={}", stationObjModel.getStationId(), JSON.toJSONString(command));
                        }
                    }
                }
src/main/java/com/zy/core/task/DeviceLogScheduler.java
@@ -14,10 +14,13 @@
import org.springframework.stereotype.Component;
import java.nio.charset.StandardCharsets;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.text.SimpleDateFormat;
import java.util.Comparator;
import java.util.Date;
@@ -26,6 +29,8 @@
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Stream;
import java.util.stream.Collectors;
@Slf4j
@@ -43,12 +48,21 @@
    @Autowired
    private RedisUtil redisUtil;
    private static final ReentrantLock FILE_OP_LOCK = new ReentrantLock();
    @Scheduled(cron = "0/3 * * * * ? ")
    public void delDeviceLog() {
        if ("mysql".equals(storageType)) {
            deviceDataLogService.clearLog(expireDays == null ? 1 : expireDays);
        }else if ("file".equals(storageType)) {
            clearFileLog(expireDays == null ? 1 : expireDays);
            if (!FILE_OP_LOCK.tryLock()) {
                return;
            }
            try {
                clearFileLog(expireDays == null ? 1 : expireDays);
            } finally {
                FILE_OP_LOCK.unlock();
            }
        }else {
            log.error("未定义的存储类型:{}", storageType);
        }
@@ -72,7 +86,14 @@
            if ("mysql".equals(storageType)) {
                mysqlSave(keys, list);
            }else if ("file".equals(storageType)) {
                fileSave(keys, list);
                if (!FILE_OP_LOCK.tryLock()) {
                    return;
                }
                try {
                    fileSave(keys, list);
                } finally {
                    FILE_OP_LOCK.unlock();
                }
            }else {
                log.error("未定义的存储类型:{}", storageType);
            }
@@ -119,7 +140,9 @@
                        if (size + line.length > max) {
                            index++;
                            current = dayDir.resolve(prefix + index + ".log");
                            Files.createFile(current);
                            if (!Files.exists(current)) {
                                Files.createFile(current);
                            }
                            size = 0;
                        }
                        Files.write(current, line, StandardOpenOption.CREATE, StandardOpenOption.APPEND);
@@ -134,12 +157,15 @@
    }
    private int findStartIndex(Path baseDir, String prefix) throws Exception {
        List<Path> matched = Files.list(baseDir)
                .filter(p -> {
                    String n = p.getFileName().toString();
                    return n.startsWith(prefix) && n.endsWith(".log");
                })
                .collect(Collectors.toList());
        List<Path> matched;
        try (Stream<Path> stream = Files.list(baseDir)) {
            matched = stream
                    .filter(p -> {
                        String n = p.getFileName().toString();
                        return n.startsWith(prefix) && n.endsWith(".log");
                    })
                    .collect(Collectors.toList());
        }
        int maxIdx = 0;
        for (Path p : matched) {
            String name = p.getFileName().toString();
@@ -172,18 +198,32 @@
            }
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
            long cutoff = System.currentTimeMillis() - (long) days * 24 * 60 * 60 * 1000;
            List<Path> dirs = Files.list(baseDir).filter(Files::isDirectory).collect(Collectors.toList());
            List<Path> dirs;
            try (Stream<Path> stream = Files.list(baseDir)) {
                dirs = stream.filter(Files::isDirectory).collect(Collectors.toList());
            }
            for (Path dir : dirs) {
                String name = dir.getFileName().toString();
                if (name.length() == 8 && name.chars().allMatch(Character::isDigit)) {
                    Date d = sdf.parse(name);
                    if (d.getTime() < cutoff) {
                        List<Path> all = Files.walk(dir).sorted(Comparator.reverseOrder()).collect(Collectors.toList());
                        for (Path p : all) {
                            try {
                                Files.deleteIfExists(p);
                            } catch (Exception ignored) {}
                        }
                        Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
                            @Override
                            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
                                try {
                                    Files.deleteIfExists(file);
                                } catch (Exception ignored) {}
                                return FileVisitResult.CONTINUE;
                            }
                            @Override
                            public FileVisitResult postVisitDirectory(Path dir, java.io.IOException exc) {
                                try {
                                    Files.deleteIfExists(dir);
                                } catch (Exception ignored) {}
                                return FileVisitResult.CONTINUE;
                            }
                        });
                    }
                }
            }
src/main/java/com/zy/core/utils/CrnOperateProcessUtils.java
@@ -425,6 +425,10 @@
        if (shallowLocMast.getLocSts().equals("F")) {
            //浅库位状态有货,申请更换库位
            String response = wmsOperateUtils.applyChangeLocNo(shallowLocNo);
            if (response == null) {
                News.taskError(taskNo, "WCS申请在库库位更换库位失败,WMS接口未响应!!!response:{}", response);
                return false;
            }
            JSONObject jsonObject = JSON.parseObject(response);
            if (jsonObject.getInteger("code").equals(200)) {
                StartupDto dto = jsonObject.getObject("data", StartupDto.class);
src/main/java/com/zy/core/utils/StationOperateProcessUtils.java
@@ -247,6 +247,10 @@
                        //站点处于重新分配库位区域
                        //运行堵塞,重新申请任务
                        String response = wmsOperateUtils.applyReassignTaskLocNo(wrkMast.getWrkNo());
                        if (response == null) {
                            News.taskError(wrkMast.getWrkNo(), "请求WMS重新分配库位接口失败,接口未响应!!!response:{}", response);
                            continue;
                        }
                        JSONObject jsonObject = JSON.parseObject(response);
                        if (jsonObject.getInteger("code").equals(200)) {
                            StartupDto dto = jsonObject.getObject("data", StartupDto.class);
src/main/java/com/zy/core/utils/WmsOperateUtils.java
@@ -24,6 +24,7 @@
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.TimeUnit;
@Component
public class WmsOperateUtils {
@@ -75,11 +76,12 @@
                    .setUri(wmsUrl)
                    .setPath(wmsSystemInUrl)
                    .setJson(JSON.toJSONString(requestParam))
                    .setTimeout(360, TimeUnit.SECONDS)
                    .build()
                    .doPost();
            News.info("请求WMS接口成功!!!url:{};request:{};response:{}", wmsUrl + wmsSystemInUrl, JSON.toJSONString(requestParam), response);
            News.info("请求WMS入库接口成功!!!url:{};request:{};response:{}", wmsUrl + wmsSystemInUrl, JSON.toJSONString(requestParam), response);
        } catch (Exception e) {
            News.error("请求WMS接口异常!!!url:{};request:{};response:{}", wmsUrl + wmsSystemInUrl, JSON.toJSONString(requestParam), response, e);
            News.error("请求WMS入库接口异常!!!url:{};request:{};response:{}", wmsUrl + wmsSystemInUrl, JSON.toJSONString(requestParam), response, e);
        } finally {
            HttpRequestLog httpRequestLog = new HttpRequestLog();
            httpRequestLog.setName(wmsUrl + wmsSystemInUrl);
@@ -125,17 +127,18 @@
        String response = null;
        try {
            requestParam.put("taskNo", wrkMast.getWmsWrkNo());
            requestParam.put("row", Utils.getInTaskEnableRow(new ArrayList<>(wrkMast.getCrnNo())));
            requestParam.put("row", Utils.getInTaskEnableRow(new ArrayList<>(wrkMast.getCrnNo()), false));
            response = new HttpHandler.Builder()
                    .setUri(wmsUrl)
                    .setPath(wmsSystemReassignInTaskUrl)
                    .setJson(JSON.toJSONString(requestParam))
                    .setTimeout(360, TimeUnit.SECONDS)
                    .build()
                    .doPost();
            News.info("请求WMS接口成功!!!url:{};request:{};response:{}", wmsUrl + wmsSystemReassignInTaskUrl, JSON.toJSONString(requestParam), response);
            News.info("请求申请任务重新分配入库接口成功!!!url:{};request:{};response:{}", wmsUrl + wmsSystemReassignInTaskUrl, JSON.toJSONString(requestParam), response);
        } catch (Exception e) {
            News.error("请求WMS接口异常!!!url:{};request:{}; response:{}", wmsUrl + wmsSystemReassignInTaskUrl, JSON.toJSONString(requestParam), response, e);
            News.error("请求申请任务重新分配入库接口异常!!!url:{};request:{}; response:{}", wmsUrl + wmsSystemReassignInTaskUrl, JSON.toJSONString(requestParam), response, e);
        } finally {
            HttpRequestLog httpRequestLog = new HttpRequestLog();
            httpRequestLog.setName(wmsUrl + wmsSystemReassignInTaskUrl);
@@ -196,13 +199,14 @@
                    .setUri(wmsUrl)
                    .setPath(wmsSystemChangeLocNoUrl)
                    .setJson(JSON.toJSONString(requestParam))
                    .setTimeout(360, TimeUnit.SECONDS)
                    .build()
                    .doPost();
            News.info("请求WMS接口成功!!!url:{};request:{};response:{}", wmsUrl + wmsSystemChangeLocNoUrl, JSON.toJSONString(requestParam), response);
            News.info("请求WMS申请更换库位接口成功!!!url:{};request:{};response:{}", wmsUrl + wmsSystemChangeLocNoUrl, JSON.toJSONString(requestParam), response);
            return response;
        } catch (Exception e) {
            News.error("请求WMS接口异常!!!url:{};request:{};response:{}", wmsUrl + wmsSystemChangeLocNoUrl, JSON.toJSONString(requestParam), response, e);
            News.error("请求WMS申请更换库位接口异常!!!url:{};request:{};response:{}", wmsUrl + wmsSystemChangeLocNoUrl, JSON.toJSONString(requestParam), response, e);
        } finally {
            HttpRequestLog httpRequestLog = new HttpRequestLog();
            httpRequestLog.setName(wmsUrl + wmsSystemChangeLocNoUrl);
src/main/resources/application.yml
@@ -71,7 +71,7 @@
deviceLogStorage:
  # 设备日志存储方式 mysql file
  type: mysql
  type: file
  # file类型存储地址
  loggingPath: /stock/out/@pom.build.finalName@/deviceLogs
  # 日志过期时间 单位天
@@ -87,3 +87,9 @@
#  base-url: http://34.2.134.223:3000/v1
#  api-key: sk-WabrmtOezCFwVo7XvVOrO3QkmfcKG7T7jy0BaVnmQTWm5GXh
#  model: gemini-3-pro-preview
perf:
  methodTiming:
    enabled: false
    thresholdMs: 50
    sampleRate: 1.0
src/main/resources/mapper/BasDevpMapper.xml
@@ -17,7 +17,6 @@
        <result column="in_station_list" property="inStationList" />
        <result column="out_station_list" property="outStationList" />
        <result column="run_block_reassign_loc_station_list" property="runBlockReassignLocStationList" />
        <result column="lift_transfer_station_list" property="liftTransferStationList" />
    </resultMap>
src/main/webapp/static/js/basDevp/basDevp.js
@@ -38,7 +38,6 @@
          { field: "inStationList", align: "center", title: "入库站点数据" },
          { field: "outStationList", align: "center", title: "出库站点数据" },
          { field: "runBlockReassignLocStationList", align: "center", title: "运行堵塞重新分配库位站点数据" },
          { field: "liftTransferStationList", align: "center", title: "顶升移栽站点数据" },
          {
            fixed: "right",
src/main/webapp/views/basDevp/basDevp.html
@@ -149,12 +149,6 @@
                        <input class="layui-input" name="runBlockReassignLocStationList" placeholder="请输入运行堵塞重新分配库位站点数据">
                    </div>
                </div>
                <div class="layui-form-item">
                    <label class="layui-form-label">顶升移栽站点数据: </label>
                    <div class="layui-input-block">
                        <input class="layui-input" name="liftTransferStationList" placeholder="请输入顶升移栽站点数据">
                    </div>
                </div>
             </div>
        </div>