#
zhou zhou
2 天以前 523365960513f297024a419f94b2b42eccd9456f
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/AsnOrderServiceImpl.java
@@ -8,6 +8,7 @@
import com.vincent.rsf.framework.exception.CoolException;
import com.vincent.rsf.server.api.entity.dto.PoItemsDto;
import com.vincent.rsf.server.api.service.ReportMsgService;
import com.vincent.rsf.server.common.service.RedisService;
import com.vincent.rsf.server.common.utils.DateUtils;
import com.vincent.rsf.server.manager.controller.dto.DashboardDto;
import com.vincent.rsf.server.manager.controller.dto.StockTrandDto;
@@ -17,12 +18,14 @@
import com.vincent.rsf.server.manager.entity.*;
import com.vincent.rsf.server.manager.enums.*;
import com.vincent.rsf.server.manager.mapper.AsnOrderMapper;
import com.vincent.rsf.server.manager.mapper.TaskLogMapper;
import com.vincent.rsf.server.manager.mapper.TaskMapper;
import com.vincent.rsf.server.manager.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.vincent.rsf.server.system.constant.SerialRuleCode;
import com.vincent.rsf.server.system.mapper.SerialRuleMapper;
import com.vincent.rsf.server.system.utils.SerialRuleUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
@@ -30,6 +33,9 @@
import org.springframework.transaction.annotation.Transactional;
import jakarta.annotation.Resource;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.text.DateFormat;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
@@ -43,8 +49,16 @@
 * @return
 * @time 2025/3/7 08:02
 */
@Slf4j
@Service("asnOrderService")
public class AsnOrderServiceImpl extends ServiceImpl<AsnOrderMapper, WkOrder> implements AsnOrderService {
    private static final String DASHBOARD_HEADER_CACHE_FLAG = "DASHBOARD_HEADER";
    private static final String DASHBOARD_HEADER_CACHE_FRESH_SUFFIX = "FRESH";
    private static final String DASHBOARD_HEADER_CACHE_STALE_SUFFIX = "STALE";
    private static final int DASHBOARD_HEADER_CACHE_FRESH_TTL_SECONDS = 300;
    private static final int DASHBOARD_HEADER_CACHE_STALE_TTL_SECONDS = 86400;
    private static final DateTimeFormatter DASHBOARD_CACHE_DATE_FORMATTER = DateTimeFormatter.BASIC_ISO_DATE;
    @Autowired
    private ReportMsgService reportMsgService;
@@ -65,6 +79,10 @@
    private PurchaseItemService purchaseItemService;
    @Autowired
    private TaskMapper taskMapper;
    @Autowired
    private TaskLogMapper taskLogMapper;
    @Autowired
    private RedisService redisService;
    @Override
    public boolean notifyInspect(List<WkOrder> orders) {
@@ -430,21 +448,29 @@
     */
    @Override
    public R getDashbord() {
        DashboardDto dto = new DashboardDto();
        //获取入库数量
        DashboardDto trandDto = this.baseMapper.getDashbord(OrderType.ORDER_IN.type, TaskType.TASK_TYPE_IN.type + "");
        dto.setInAnf(trandDto.getAnfme()).setTaskIn(trandDto.getRealAnfme()).setTotalIn(trandDto.getAnfme() + trandDto.getRealAnfme());
        //获取出库单数量
        DashboardDto outTrand = this.baseMapper.getDashbord(OrderType.ORDER_OUT.type, TaskType.TASK_TYPE_OUT.type + "");
        dto.setOutAnf(outTrand.getAnfme()).setTaskOut(outTrand.getRealAnfme()).setTotalOut(outTrand.getAnfme() + outTrand.getRealAnfme());
        //获取执行中任务数量
        List<Task> tasks = taskMapper.selectList(new LambdaQueryWrapper<>());
        if (!tasks.isEmpty()) {
            dto.setTaskQty(tasks.size());
        String freshCacheKey = buildDashboardCacheKey(DASHBOARD_HEADER_CACHE_FRESH_SUFFIX);
        DashboardDto freshSnapshot = getDashboardCache(freshCacheKey);
        if (freshSnapshot != null) {
            return R.ok().add(freshSnapshot);
        }
        return R.ok().add(dto);
        String staleCacheKey = buildDashboardCacheKey(DASHBOARD_HEADER_CACHE_STALE_SUFFIX);
        Exception dbException = null;
        try {
            DashboardDto snapshot = buildDashboardSnapshot();
            cacheDashboard(freshCacheKey, snapshot, DASHBOARD_HEADER_CACHE_FRESH_TTL_SECONDS);
            cacheDashboard(staleCacheKey, snapshot, DASHBOARD_HEADER_CACHE_STALE_TTL_SECONDS);
            return R.ok().add(snapshot);
        } catch (Exception ex) {
            dbException = ex;
            log.warn("Load dashboard snapshot from database failed, fallback to stale cache. message={}", ex.getMessage(), ex);
        }
        DashboardDto staleSnapshot = getDashboardCache(staleCacheKey);
        if (staleSnapshot != null) {
            return R.ok().add(staleSnapshot);
        }
        log.error("Load dashboard snapshot failed, returning empty snapshot.", dbException);
        return R.ok().add(emptyDashboardSnapshot());
    }
    /**
@@ -454,9 +480,7 @@
    @Override
    public R getStockTrand() {
        List<String> days = DateUtils.getLastMonthDays("yyyy-MM-dd");
        LambdaQueryWrapper<StockStatistic> queryWrapper = new LambdaQueryWrapper<StockStatistic>()
                .in(StockStatistic::getTaskType, Arrays.asList(TaskType.TASK_TYPE_IN.type, TaskType.TASK_TYPE_OUT.type));
       List<StockTransItemDto> items = this.baseMapper.getStockTrand(queryWrapper);
       List<StockTransItemDto> items = this.baseMapper.getStockTrand();
       if (items.isEmpty()) {
           return R.ok();
       }
@@ -542,4 +566,86 @@
            throw new CoolException("原单据删除失败!!");
        }
    }
    private DashboardDto buildDashboardSnapshot() {
        Date[] todayRange = buildTodayRange();
        Date todayStart = todayRange[0];
        Date tomorrowStart = todayRange[1];
        int inAnf = safeToInt(this.count(new LambdaQueryWrapper<WkOrder>()
                .eq(WkOrder::getType, OrderType.ORDER_IN.type)
                .ge(WkOrder::getCreateTime, todayStart)
                .lt(WkOrder::getCreateTime, tomorrowStart)));
        int outAnf = safeToInt(this.count(new LambdaQueryWrapper<WkOrder>()
                .eq(WkOrder::getType, OrderType.ORDER_OUT.type)
                .ge(WkOrder::getCreateTime, todayStart)
                .lt(WkOrder::getCreateTime, tomorrowStart)));
        int taskIn = safeToInt(taskLogMapper.selectCount(new LambdaQueryWrapper<TaskLog>()
                .eq(TaskLog::getTaskType, TaskType.TASK_TYPE_IN.type)
                .ge(TaskLog::getCreateTime, todayStart)
                .lt(TaskLog::getCreateTime, tomorrowStart)));
        int taskOut = safeToInt(taskLogMapper.selectCount(new LambdaQueryWrapper<TaskLog>()
                .eq(TaskLog::getTaskType, TaskType.TASK_TYPE_OUT.type)
                .ge(TaskLog::getCreateTime, todayStart)
                .lt(TaskLog::getCreateTime, tomorrowStart)));
        int taskQty = safeToInt(taskMapper.selectCount(new LambdaQueryWrapper<Task>()));
        return new DashboardDto()
                .setInAnf(inAnf)
                .setOutAnf(outAnf)
                .setTaskIn(taskIn)
                .setTaskOut(taskOut)
                .setTaskQty(taskQty)
                .setTotalIn(inAnf + taskIn)
                .setTotalOut(outAnf + taskOut);
    }
    private DashboardDto getDashboardCache(String cacheKey) {
        try {
            String cacheValue = redisService.getValue(DASHBOARD_HEADER_CACHE_FLAG, cacheKey);
            if (StringUtils.isBlank(cacheValue)) {
                return null;
            }
            return JSONObject.parseObject(cacheValue, DashboardDto.class);
        } catch (Exception ex) {
            log.warn("Read dashboard cache failed, key={}, message={}", cacheKey, ex.getMessage(), ex);
            return null;
        }
    }
    private void cacheDashboard(String cacheKey, DashboardDto dto, int ttlSeconds) {
        try {
            redisService.setValue(DASHBOARD_HEADER_CACHE_FLAG, cacheKey, JSONObject.toJSONString(dto), ttlSeconds);
        } catch (Exception ex) {
            log.warn("Write dashboard cache failed, key={}, message={}", cacheKey, ex.getMessage(), ex);
        }
    }
    private String buildDashboardCacheKey(String suffix) {
        String dateBucket = LocalDate.now().format(DASHBOARD_CACHE_DATE_FORMATTER);
        return dateBucket + "." + suffix;
    }
    private Date[] buildTodayRange() {
        ZoneId zoneId = ZoneId.systemDefault();
        LocalDate today = LocalDate.now(zoneId);
        Date todayStart = Date.from(today.atStartOfDay(zoneId).toInstant());
        Date tomorrowStart = Date.from(today.plusDays(1).atStartOfDay(zoneId).toInstant());
        return new Date[]{todayStart, tomorrowStart};
    }
    private DashboardDto emptyDashboardSnapshot() {
        return new DashboardDto()
                .setInAnf(0)
                .setOutAnf(0)
                .setTaskIn(0)
                .setTaskOut(0)
                .setTaskQty(0)
                .setTotalIn(0)
                .setTotalOut(0);
    }
    private int safeToInt(Long count) {
        return count == null ? 0 : count.intValue();
    }
}