cl
3 小时以前 ab08f2e28057e226ba42b3268ed36ac489cef34e
大屏接口
5个文件已添加
5个文件已修改
674 ■■■■ 已修改文件
src/main/java/com/zy/asrs/controller/MonitorController.java 133 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/ViewLocMapDto.java 125 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/mapper/ReportQueryMapper.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/MonitorReportService.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/MainServiceImpl.java 25 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/MonitorReportServiceImpl.java 192 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/task/ClearMonitorLocMapCacheScheduler.java 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/common/config/RedisConfig.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/thread/SiemensDevpThread.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/ReportQueryMapper.xml 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/MonitorController.java
@@ -1,17 +1,11 @@
package com.zy.asrs.controller;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.core.common.Arith;
import com.core.common.Cools;
import com.core.common.R;
import com.zy.asrs.domain.dto.AxisBean;
import com.zy.asrs.domain.dto.WorkChartAxis;
import com.zy.asrs.domain.vo.LocChartPie;
import com.zy.asrs.entity.BasCrnError;
import com.zy.asrs.entity.LocMast;
import com.zy.asrs.mapper.BasCrnErrorMapper;
import com.zy.asrs.mapper.ReportQueryMapper;
import com.zy.asrs.service.LocMastService;
import com.zy.asrs.service.MonitorReportService;
import com.zy.common.model.annotations.RateLimit;
import com.zy.common.service.CommonService;
import com.zy.core.CrnThread;
@@ -30,8 +24,13 @@
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
 * Created by vincent on 2020/11/16
@@ -43,13 +42,11 @@
    private static final String[] WEEK = {"星期日","星期一","星期二","星期三","星期四","星期五","星期六"};
    @Autowired
    private ReportQueryMapper reportQueryMapper;
    private MonitorReportService monitorReportService;
    @Autowired
    private SlaveProperties slaveProperties;
    @Autowired
    private BasCrnErrorMapper basCrnErrorMapper;
    @Autowired
    private LocMastService locMastService;
    /**
     * 获取当前时间
@@ -149,114 +146,38 @@
//    @RateLimit(2)
    @GetMapping("/pakin/rep")
    public R monitorPakinRep(){
        // 入库
        List<Map<String, Object>> pakinRep = reportQueryMapper.queryPakinRep();
        for (Map<String, Object> map : pakinRep) {
            if (map.get("node")!=null) {
                map.put("node", String.valueOf(map.get("node")).substring(5, 10));
            }
        }
        // 出库
        List<Map<String, Object>> pakoutRep = reportQueryMapper.queryPakinRep();
        return R.ok(pakinRep);
        return R.ok(monitorReportService.getPakinRepData());
    }
    @GetMapping("/line/charts")
    public R locIoLineCharts(){
        Map<String,Object> map=new HashMap<String, Object>();
        List<AxisBean> list = new ArrayList<AxisBean>();
        List<WorkChartAxis> listChart = reportQueryMapper.getChartAxis();
        if(listChart!=null) {
            ArrayList<Integer> data1 = new ArrayList<Integer>();
            ArrayList<Integer> data2 = new ArrayList<Integer>();
            SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
            Calendar calendar = Calendar.getInstance();
            calendar.add(Calendar.DATE, -12);
            for(int i=0;i<12;i++) {
                boolean flag = true;
                calendar.add(Calendar.DATE, 1);
                String str = sf.format(calendar.getTime());
                for(WorkChartAxis workChart : listChart) {
                    if(str.equals(workChart.getYmd())) {
                        data1.add(workChart.getInqty());
                        data2.add(workChart.getOutqty());
                        flag = false;
                        break;
                    }
                }
                if(flag) {
                    data1.add(0);
                    data2.add(0);
                }
            }
            AxisBean inqty = new AxisBean();
            inqty.setName("入库数量");
            Integer[] array1 = new Integer[data1.size()];
            inqty.setData(data1.toArray(array1));
            list.add(inqty);
            AxisBean outqty = new AxisBean();
            outqty.setName("出库数量");
            Integer[] array2 = new Integer[data2.size()];
            outqty.setData(data2.toArray(array2));
            list.add(outqty);
        }
        map.put("rows",list);
        return R.ok(map);
        return R.ok(monitorReportService.getLocIoLineChartsData());
    }
    /**
     * 库位使用情况统计
     */
//    @RateLimit(60)
//    预留限流配置(60)
    @GetMapping("/loc/rep")
    public R monitorLocRep(){
        List<Map<String, Object>> pie = new ArrayList<>();
        return R.ok(monitorReportService.getLocRepData());
    }
        LocChartPie locUseRate = reportQueryMapper.getLocUseRate();
        int i = locMastService.selectCount(new EntityWrapper<LocMast>().eq("loc_sts", "D"));
        if(locUseRate!=null) {
            Map<String, Object> map = new HashMap<>();
            map.put("name", "在库");
            map.put("value", locUseRate.getFqty());
            pie.add(map);
    /**
     * 库位热力图排号列表
     */
    @GetMapping("/loc/map/rows")
    public R monitorLocMapRows() {
        return R.ok(monitorReportService.getLocMapRows());
    }
            Map<String, Object> map1 = new HashMap<>();
            map1.put("name", "空");
            map1.put("value", locUseRate.getOqty());
            pie.add(map1);
            Map<String, Object> map2 = new HashMap<>();
            map2.put("name", "使用");
            map2.put("value", locUseRate.getUqty());
            pie.add(map2);
            Map<String, Object> map3 = new HashMap<>();
            map3.put("name", "空板");
            map3.put("value", i);
            pie.add(map3);
        }
        // 总库位数
        Integer total = (int) Arith.add(0, locUseRate.getFqty(), locUseRate.getOqty(), locUseRate.getUqty(), locUseRate.getXqty());
        // 使用中
        Integer used = locUseRate.getFqty() + locUseRate.getUqty();
        // 库位使用率
        double usedDivides = Arith.divides(3, used, total);
        double usedPr = Arith.multiplys(1, usedDivides, 100);
        return R.ok(
                Cools.add("pie", pie)
                .add("stockCunt", locUseRate.getFqty() - i)
                .add("emptyCount", locUseRate.getOqty())
                .add("noneCount", i)
                .add("total", total)
                .add("used", used)
                .add("usedPr", usedPr)
        );
    /**
     * 库位热力图单排数据
     */
    @GetMapping("/loc/map")
    public R monitorLocMap(@RequestParam(defaultValue = "1") Integer row) {
        return R.ok(monitorReportService.getLocMapData(row));
    }
    /**
src/main/java/com/zy/asrs/entity/ViewLocMapDto.java
New file
@@ -0,0 +1,125 @@
package com.zy.asrs.entity;
/**
 * 库位热力图单元
 */
public class ViewLocMapDto {
    private String locNo;
    private Integer bay1;
    private String locSts;
    private String maktx;
    private String itemBarcodes;
    private String pltBarcodes;
    private String bgc = "#fff";
    private String color = "#666";
    public ViewLocMapDto() {
    }
    public ViewLocMapDto(String locNo, Integer bay1, String locSts) {
        this.locNo = locNo;
        this.bay1 = bay1;
        this.locSts = locSts;
    }
    public String getLocNo() {
        return locNo;
    }
    public void setLocNo(String locNo) {
        this.locNo = locNo;
    }
    public Integer getBay1() {
        return bay1;
    }
    public void setBay1(Integer bay1) {
        this.bay1 = bay1;
    }
    public String getLocSts() {
        return locSts;
    }
    public String getMaktx() {
        return maktx;
    }
    public void setMaktx(String maktx) {
        this.maktx = maktx;
    }
    public String getItemBarcodes() {
        return itemBarcodes;
    }
    public void setItemBarcodes(String itemBarcodes) {
        this.itemBarcodes = itemBarcodes;
    }
    public String getPltBarcodes() {
        return pltBarcodes;
    }
    public void setPltBarcodes(String pltBarcodes) {
        this.pltBarcodes = pltBarcodes;
    }
    public void setLocSts(String locSts) {
        this.locSts = locSts;
        switch (locSts) {
            case "D":
                this.bgc = "#00B271";
                this.color = "#fff";
                break;
            case "F":
                this.bgc = "#479AC7";
                this.color = "#fff";
                break;
            case "O":
                this.bgc = "#B45B3E";
                this.color = "#fff";
                break;
            case "P":
                this.bgc = "#66CCCC";
                this.color = "#fff";
                break;
            case "Q":
                this.bgc = "#5172ef";
                this.color = "#fff";
                break;
            case "R":
                this.bgc = "#D7FFF0";
                this.color = "#000";
                break;
            case "S":
                this.bgc = "#F0DAD2";
                this.color = "#000";
                break;
            case "X":
                this.bgc = "#bac296";
                this.color = "#fff";
                break;
            default:
                break;
        }
    }
    public String getBgc() {
        return bgc;
    }
    public void setBgc(String bgc) {
        this.bgc = bgc;
    }
    public String getColor() {
        return color;
    }
    public void setColor(String color) {
        this.color = color;
    }
}
src/main/java/com/zy/asrs/mapper/ReportQueryMapper.java
@@ -2,7 +2,9 @@
import com.zy.asrs.domain.dto.WorkChartAxis;
import com.zy.asrs.domain.vo.LocChartPie;
import com.zy.asrs.entity.ViewLocMapDto;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.springframework.stereotype.Repository;
@@ -50,4 +52,15 @@
    @Select("select count(1) as totalLoc from asr_loc_mast")
    Integer getTotalLocByCrnId();
    @Select("select distinct row1 from asr_loc_mast order by row1 asc")
    List<Integer> getViewLocRowTotal();
    @Select("select distinct lev1 from asr_loc_mast where row1=#{row1} order by lev1 desc")
    List<String> getViewLocLevCount(@Param("row1") int row1);
    @Select("select distinct bay1 from asr_loc_mast where row1=#{row1} order by bay1")
    List<String> getViewLocBayCount(@Param("row1") int row1);
    List<ViewLocMapDto> getViewLocBays(@Param("row1") int row1, @Param("lev1") int lev1);
}
src/main/java/com/zy/asrs/service/MonitorReportService.java
New file
@@ -0,0 +1,20 @@
package com.zy.asrs.service;
import java.util.List;
import java.util.Map;
/**
 * 监控大屏报表查询
 */
public interface MonitorReportService {
    List<Map<String, Object>> getPakinRepData();
    Map<String, Object> getLocIoLineChartsData();
    Map<String, Object> getLocRepData();
    List<Integer> getLocMapRows();
    Map<String, Object> getLocMapData(Integer row);
}
src/main/java/com/zy/asrs/service/impl/MainServiceImpl.java
@@ -561,24 +561,25 @@
        if (waitPakinNotIn > 0) {
            return;
        }
        // 存在进行中/在途任务(2,3,12,13,14)则不下发出库,避免冲突
        // 2 待执行(入库)
        //3 设备执行中(入库)
        //12 设备执行中(出库)
        //13 出库到站点上
        //14 出库等待确认
        int activeCount = wrkMastService.selectCount(new EntityWrapper<WrkMast>()
                .in("wrk_sts", 2, 3, 12, 13, 14));
        if (activeCount > 0) {
            return;
        }
        List<WrkMast> wrkMasts = wrkMastService.selectList(new EntityWrapper<WrkMast>().eq("wrk_sts", 11).orderBy("create_time"));
        if (wrkMasts.isEmpty()) {
            return;
        }
        WrkMast wrkMast = wrkMasts.get(0);
        // 存在进行中/在途任务(2,3,12,13,14)则不下发出库,避免冲突(排除当前任务)
        // 2 待执行(入库)
        // 3 设备执行中(入库)
        // 12 设备执行中(出库)
        // 13 出库到站点上
        // 14 出库等待确认
        int activeCount = wrkMastService.selectCount(new EntityWrapper<WrkMast>()
                .in("wrk_sts", 2, 3, 12, 13, 14)
                .ne("wrk_no", wrkMast.getWrkNo()));
        if (activeCount > 0) {
            return;
        }
        Integer sourceStaNo = Utils.getStaNoByLocNo(wrkMast.getSourceLocNo());
        LiftCommand command = new LiftCommand();
src/main/java/com/zy/asrs/service/impl/MonitorReportServiceImpl.java
New file
@@ -0,0 +1,192 @@
package com.zy.asrs.service.impl;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.core.common.Arith;
import com.zy.asrs.domain.dto.AxisBean;
import com.zy.asrs.domain.dto.WorkChartAxis;
import com.zy.asrs.domain.vo.LocChartPie;
import com.zy.asrs.entity.LocMast;
import com.zy.asrs.entity.ViewLocMapDto;
import com.zy.asrs.mapper.ReportQueryMapper;
import com.zy.asrs.service.LocMastService;
import com.zy.asrs.service.MonitorReportService;
import com.zy.common.utils.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Slf4j
@Service
public class MonitorReportServiceImpl implements MonitorReportService {
    private static final String LOC_MAP_CACHE_KEY_PREFIX = "monitor:loc:map:row:";
    private static final long LOC_MAP_CACHE_SECONDS = 1800L;
    @Autowired
    private ReportQueryMapper reportQueryMapper;
    @Autowired
    private LocMastService locMastService;
    @Autowired(required = false)
    private RedisUtil redisUtil;
    @Override
    public List<Map<String, Object>> getPakinRepData() {
        List<Map<String, Object>> pakinRep = reportQueryMapper.queryPakinRep();
        for (Map<String, Object> map : pakinRep) {
            if (map.get("node") != null) {
                map.put("node", String.valueOf(map.get("node")).substring(5, 10));
            }
        }
        return pakinRep;
    }
    @Override
    public Map<String, Object> getLocIoLineChartsData() {
        Map<String, Object> map = new HashMap<>();
        List<AxisBean> list = new ArrayList<>();
        List<WorkChartAxis> listChart = reportQueryMapper.getChartAxis();
        if (listChart != null) {
            ArrayList<Integer> data1 = new ArrayList<>();
            ArrayList<Integer> data2 = new ArrayList<>();
            SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
            Calendar calendar = Calendar.getInstance();
            calendar.add(Calendar.DATE, -12);
            for (int i = 0; i < 12; i++) {
                boolean flag = true;
                calendar.add(Calendar.DATE, 1);
                String str = sf.format(calendar.getTime());
                for (WorkChartAxis workChart : listChart) {
                    if (str.equals(workChart.getYmd())) {
                        data1.add(workChart.getInqty());
                        data2.add(workChart.getOutqty());
                        flag = false;
                        break;
                    }
                }
                if (flag) {
                    data1.add(0);
                    data2.add(0);
                }
            }
            AxisBean inqty = new AxisBean();
            inqty.setName("入库数量");
            Integer[] array1 = new Integer[data1.size()];
            inqty.setData(data1.toArray(array1));
            list.add(inqty);
            AxisBean outqty = new AxisBean();
            outqty.setName("出库数量");
            Integer[] array2 = new Integer[data2.size()];
            outqty.setData(data2.toArray(array2));
            list.add(outqty);
        }
        map.put("rows", list);
        return map;
    }
    @Override
    public Map<String, Object> getLocRepData() {
        List<Map<String, Object>> pie = new ArrayList<>();
        LocChartPie locUseRate = reportQueryMapper.getLocUseRate();
        int i = locMastService.selectCount(new EntityWrapper<LocMast>().eq("loc_sts", "D"));
        if (locUseRate != null) {
            Map<String, Object> map = new HashMap<>();
            map.put("name", "在库");
            map.put("value", locUseRate.getFqty());
            pie.add(map);
            Map<String, Object> map1 = new HashMap<>();
            map1.put("name", "空");
            map1.put("value", locUseRate.getOqty());
            pie.add(map1);
            Map<String, Object> map2 = new HashMap<>();
            map2.put("name", "使用");
            map2.put("value", locUseRate.getUqty());
            pie.add(map2);
            Map<String, Object> map3 = new HashMap<>();
            map3.put("name", "空板");
            map3.put("value", i);
            pie.add(map3);
        }
        Integer total = (int) Arith.add(0, locUseRate.getFqty(), locUseRate.getOqty(), locUseRate.getUqty(), locUseRate.getXqty());
        Integer used = locUseRate.getFqty() + locUseRate.getUqty();
        double usedDivides = Arith.divides(3, used, total);
        double usedPr = Arith.multiplys(1, usedDivides, 100);
        Map<String, Object> result = new HashMap<>();
        result.put("pie", pie);
        result.put("stockCunt", locUseRate.getFqty() - i);
        result.put("emptyCount", locUseRate.getOqty());
        result.put("noneCount", i);
        result.put("total", total);
        result.put("used", used);
        result.put("usedPr", usedPr);
        return result;
    }
    @Override
    public List<Integer> getLocMapRows() {
        List<Integer> rows = reportQueryMapper.getViewLocRowTotal();
        if (rows == null) {
            rows = new ArrayList<>();
        }
        return rows;
    }
    @Override
    public Map<String, Object> getLocMapData(Integer row) {
        String cacheDataKey = LOC_MAP_CACHE_KEY_PREFIX + row;
        if (redisUtil != null) {
            try {
                Object redisData = redisUtil.get(cacheDataKey);
                if (redisData instanceof Map) {
                    return (Map<String, Object>) redisData;
                }
            } catch (Exception e) {
                log.warn("Redis读缓存失败,改查数据库,key={}", cacheDataKey, e);
            }
        }
        List<String> bays = reportQueryMapper.getViewLocBayCount(row);
        if (bays == null) {
            bays = new ArrayList<>();
        }
        bays.add(0, "");
        List<String> levs = reportQueryMapper.getViewLocLevCount(row);
        if (levs == null) {
            levs = new ArrayList<>();
        }
        List<Map<String, Object>> body = new ArrayList<>();
        for (String lev : levs) {
            List<ViewLocMapDto> dtos = reportQueryMapper.getViewLocBays(row, Integer.parseInt(lev.trim()));
            if (dtos == null) {
                dtos = new ArrayList<>();
            }
            dtos.add(0, new ViewLocMapDto(null, null, lev));
            Map<String, Object> map = new HashMap<>();
            map.put("loc", dtos);
            body.add(map);
        }
        Map<String, Object> result = new HashMap<>();
        result.put("title", bays);
        result.put("body", body);
        if (redisUtil != null) {
            try {
                redisUtil.set(cacheDataKey, result, LOC_MAP_CACHE_SECONDS);
            } catch (Exception e) {
                log.warn("Redis写缓存失败,key={}", cacheDataKey, e);
            }
        }
        return result;
    }
}
src/main/java/com/zy/asrs/task/ClearMonitorLocMapCacheScheduler.java
New file
@@ -0,0 +1,72 @@
package com.zy.asrs.task;
import com.zy.asrs.mapper.ReportQueryMapper;
import com.zy.common.utils.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@Component
@Slf4j
public class ClearMonitorLocMapCacheScheduler {
    private static final String LOC_MAP_CACHE_KEY_PREFIX = "monitor:loc:map:row:";
    private static final String[] LOC_MAP_CACHE_PATTERNS = {
            "monitor:loc:map:*",
            "*monitor:loc:map:*",
    };
    @Autowired(required = false)
    private RedisUtil redisUtil;
    @Autowired(required = false)
    private ReportQueryMapper reportQueryMapper;
    /**
     * 每小时清理一次热力图缓存
     */
    @Scheduled(cron = "0 0 * * * ?")
    public void clearLocMapCache() {
        if (redisUtil == null) {
            return;
        }
        try {
            Set<String> toDelete = new HashSet<>();
            for (String pattern : LOC_MAP_CACHE_PATTERNS) {
                Set<?> keys = redisUtil.keys(pattern);
                if (keys == null || keys.isEmpty()) {
                    continue;
                }
                for (Object key : keys) {
                    if (key != null) {
                        toDelete.add(String.valueOf(key));
                    }
                }
            }
            toDelete.add(LOC_MAP_CACHE_KEY_PREFIX + "1");
            if (reportQueryMapper != null) {
                List<Integer> rows = reportQueryMapper.getViewLocRowTotal();
                if (rows != null) {
                    for (Integer row : rows) {
                        if (row != null) {
                            toDelete.add(LOC_MAP_CACHE_KEY_PREFIX + row);
                        }
                    }
                }
            }
            if (toDelete.isEmpty()) {
                return;
            }
            String[] cacheKeys = toDelete.toArray(new String[0]);
            redisUtil.del(cacheKeys);
            log.info("清理库位热力图缓存数量={}", cacheKeys.length);
        } catch (Exception e) {
            log.error("清理库位热力图缓存失败", e);
        }
    }
}
src/main/java/com/zy/common/config/RedisConfig.java
@@ -3,11 +3,17 @@
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisPassword;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.*;
import org.springframework.util.StringUtils;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@@ -19,6 +25,18 @@
//@EnableCaching // 开启数据缓存机制
public class RedisConfig extends CachingConfigurerSupport {
    @Bean
    @Primary
    public LettuceConnectionFactory redisConnectionFactory(RedisProperties redisProperties) {
        RedisStandaloneConfiguration standalone = new RedisStandaloneConfiguration();
        standalone.setHostName(redisProperties.getHost());
        standalone.setPort(redisProperties.getPort());
        standalone.setDatabase(redisProperties.getDatabase());
        if (StringUtils.hasText(redisProperties.getPassword())) {
            standalone.setPassword(RedisPassword.of(redisProperties.getPassword()));
        }
        return new LettuceConnectionFactory(standalone);
    }
    /**
     * RedisTemplate相关配置
src/main/java/com/zy/core/thread/SiemensDevpThread.java
@@ -238,6 +238,28 @@
                    staProtocol.setPakMk(true);
                }
            }
            // 100、101、122 站点 StaProtocol 全量监测日志(2026-03-25 之后不再打印)
            if (result.IsSuccess) {
                try {
                    Calendar cutoff = Calendar.getInstance();
                    cutoff.set(2026, Calendar.MARCH, 25, 0, 0, 0);
                    cutoff.set(Calendar.MILLISECOND, 0);
                    if (System.currentTimeMillis() < cutoff.getTimeInMillis()) {
                        String time = DateUtils.convert(new Date());
                        for (int staNo : new int[]{100, 101, 122}) {
                            StaProtocol p = station.get(staNo);
                            if (p != null) {
                                String msg = String.format("[%s] %s 站点编号=%s 工作号=%s 目标站=%s 自动=%s 有物=%s 可入=%s 可出=%s 空板信号=%s 满托盘=%s 高度=%s 锁定标记=%s 报警=%s",
                                        staNo, time, p.getSiteId(), p.getWorkNo(), p.getStaNo(), p.isAutoing(), p.isLoading(), p.isInEnable(), p.isOutEnable(),
                                        p.isEmptyMk(), p.isFullPlt(), p.getLocHeight(), p.isPakMk(), p.getError());
                                log.info("站点监测 {}", msg);
                            }
                        }
                    }
                } catch (Exception e) {
                    log.warn("站点监测日志打印异常", e);
                }
            }
        }
        //任务信息反馈
src/main/resources/mapper/ReportQueryMapper.xml
New file
@@ -0,0 +1,54 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zy.asrs.mapper.ReportQueryMapper">
    <select id="getViewLocBays" resultType="com.zy.asrs.entity.ViewLocMapDto">
        SELECT m.loc_no  AS locNo,
               m.bay1    AS bay1,
               m.loc_sts AS locSts,
               STUFF((
                   SELECT ',' + t.maktx
                   FROM (
                            SELECT DISTINCT LTRIM(RTRIM(ISNULL(d.maktx, ''))) AS maktx
                            FROM asr_loc_detl d
                            WHERE d.loc_no = m.loc_no
                              AND LTRIM(RTRIM(ISNULL(d.maktx, ''))) &lt;&gt; ''
                        ) t
                   FOR XML PATH(''), TYPE
               ).value('.', 'nvarchar(max)'), 1, 1, '') AS maktx,
               CASE WHEN m.loc_sts = 'D'
                    THEN NULLIF(LTRIM(RTRIM(ISNULL(m.barcode, ''))), '')
                    ELSE STUFF((
                             SELECT ',' + t.code
                             FROM (
                                      SELECT DISTINCT LTRIM(RTRIM(ISNULL(d.barcode, ''))) AS code
                                      FROM asr_loc_detl d
                                      WHERE d.loc_no = m.loc_no
                                        AND LTRIM(RTRIM(ISNULL(d.barcode, ''))) &lt;&gt; ''
                                        AND NOT (LEN(LTRIM(RTRIM(ISNULL(d.barcode, '')))) = 6
                                             AND LTRIM(RTRIM(d.barcode)) LIKE 'Z__-__')
                                  ) t
                             FOR XML PATH(''), TYPE
                         ).value('.', 'nvarchar(max)'), 1, 1, '')
               END AS itemBarcodes,
               CASE WHEN m.loc_sts = 'D'
                    THEN NULL
                    ELSE STUFF((
                             SELECT ',' + t.code
                             FROM (
                                      SELECT DISTINCT LTRIM(RTRIM(ISNULL(d.zpallet, ''))) AS code
                                      FROM asr_loc_detl d
                                      WHERE d.loc_no = m.loc_no
                                        AND LTRIM(RTRIM(ISNULL(d.zpallet, ''))) &lt;&gt; ''
                                        AND NOT (LEN(LTRIM(RTRIM(ISNULL(d.zpallet, '')))) = 6
                                             AND LTRIM(RTRIM(d.zpallet)) LIKE 'Z__-__')
                                  ) t
                             FOR XML PATH(''), TYPE
                         ).value('.', 'nvarchar(max)'), 1, 1, '')
               END AS pltBarcodes
        FROM asr_loc_mast m
        WHERE m.row1 = #{row1}
          AND m.lev1 = #{lev1}
        ORDER BY m.bay1
    </select>
</mapper>