package com.zbf.web.controller.system;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.zbf.common.annotation.Log;
import com.zbf.common.core.controller.BaseController;
import com.zbf.common.core.domain.AjaxResult;
import com.zbf.common.core.domain.entity.SysDept;
import com.zbf.common.core.domain.entity.SysDictData;
import com.zbf.common.core.domain.entity.SysUser;
import com.zbf.common.core.domain.model.LoginUser;
import com.zbf.common.enums.BusinessType;
import com.zbf.common.utils.DateUtils;
import com.zbf.common.utils.OrderCodeFactory;
import com.zbf.common.utils.SecurityUtils;
import com.zbf.common.utils.StringUtils;
import com.zbf.common.utils.bean.BeanUtils;
import com.zbf.system.domain.*;
import com.zbf.system.domain.vo.Quest;
import com.zbf.system.domain.vo.Types;
import com.zbf.system.mapper.*;
import com.zbf.system.service.*;
import com.zbf.system.service.impl.TCkOrdersServiceImpl;
import com.zbf.system.service.impl.TCkPickingwavegoodsBakServiceImpl;
import com.zbf.system.service.impl.TCkPickingwavegoodsServiceImpl;
import com.zbf.system.service.impl.TckOrdersBakServiceImpl;
import com.zbf.system.utils.HttpUtils;
import com.zbf.web.mqtt.MqttMessageSender;
import liquibase.pro.packaged.O;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.validation.Validator;
import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;


/**
 * 大屏数据
 */
@CrossOrigin
@RestController
@RequestMapping("/system/LargeScreen")
public class LargeScreenController extends BaseController {
    private static final Logger logger = LoggerFactory.getLogger(TCkOrdersServiceImpl.class);

    @Autowired
    private LargeScreenService largeScreenService;


    @Autowired
    private ITRkWareNoticeService tRkWareNoticeService;


    @Autowired
    private TRkWareNoticeMapper tRkWareNoticeMapper;

    @Autowired
    private TRkWareNoticeBakMapper tRkWareNoticeBakMapper;

    @Autowired
    private TOngoodsshelfMapper tOngoodsshelfMapper;

    @Autowired
    private TOngoodsshelfBakMapper tOngoodsshelfBakMapper;

    @Autowired
    private TRkReceivingGoodsMapper tRkReceivingGoodsMapper;

    @Autowired
    private TBaseStorageMapper tBaseStorageMapper;

    @Autowired
    private TMiStockMapper tMiStockMapper;

    @Autowired
    private TMiStockFMapper tMiStockFMapper;

    @Autowired
    private SysConfigMapper sysConfigMapper;

    @Autowired
    private IPlcService plcService;

    @Autowired
    private ITCallNoticeService tNoticeService;

    @Autowired
    private TBaseStorageAreaLocationMapper tBaseStorageAreaLocationMapper;

    @Autowired
    private ISysConfigService configService;
    @Autowired
    protected Validator validator;
    @Autowired
    private TRkWareNoticeTabMapper tRkWareNoticeTabMapper;

    @Autowired
    private PlcMapper plcMapper;

    @Autowired
    private TBasePalletMapper palletMapper;

    @Autowired
    private TBaseStorageAreaLocationMapper service;

    @Autowired
    private TRkWareNoticeTabMapper mapper;

    @Autowired
    private ITCallNoticeOrderService tNoticeOrderService;

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private  SysDictDataMapper sysDictDataMapper;


    @Autowired
    @Qualifier("defaultRestTemplate")
    private RestTemplate restClientConfig;

    @Autowired
    private TCkOrdersMapper tCkOrdersMapper;
    @Autowired
    private TCkOrderdetailMapper tCkOrderdetailMapper;

    @Autowired
    private TCkPickingwavegoodsMapper tCkPickingwavegoodsMapper;

    @Autowired
    private TRkWareNoticeMapper rkWareNoticeMapper;

    @Autowired
    private TRkWareNoticeTabBakMapper tRkWareNoticeTabBakMapper;

    @Autowired
    private ITBaseStorageService baseStorageService;

    @Autowired
    private TCkOrderdetailMapper orderdetailMapper;

    @Autowired
    private TckOrderdetailBakMapper tckOrderdetailBakMapper;

    @Autowired
    private TCallNoticeMapper tCallNoticeMapper;
    @Resource
    private IOutBoundService outBoundService;

    @Autowired
    private TckOrdersBakServiceImpl tckOrdersBakService;


    @Autowired
    private ITCkOrdersService tCkOrdersService;

    @Autowired
    private TBaseGoodsMapper goodsMapper;

    @Autowired
    private TCkPickingwavegoodsServiceImpl tCkPickingwavegoodsService;

    @Autowired
    private TCkPickingwavegoodsBakServiceImpl tCkPickingwavegoodsBakService;


    @Autowired
    private TBaseGoodsMapper tBaseGoodsMapper;


    @Autowired
    private MqttMessageSender mqttMessageSender;

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private TBasePalletMapper basePalletMapper;

    @Autowired
    private SysDeptMapper sysDeptMapper;

    @Autowired
    private TBasePalletMapper tBasePalletMapper;


   /* @Autowired
    private RedissonClient redissonClient; // 直接注入RedissonClient*/


    private final ReentrantLock lock = new ReentrantLock();

    @GetMapping("/chart")
    @Log(title = "利用率")
    public List<List<Object>> chart() {
        List<List<Object>> resultList = new ArrayList<>();

        // 获取所有托盘信息并筛选有效数据
        List<TBasePallet> allPallets = tBasePalletMapper.selectTBasePalletList(new TBasePallet());
        List<TBasePallet> validPallets = allPallets.stream()
                .filter(pallet -> ObjectUtils.isNotEmpty(pallet.getType()) && ObjectUtils.isNotEmpty(pallet.getStatus()))
                .collect(Collectors.toList());

        // 获取“占用”的状态值
        List<SysDictData> locationType = sysDictDataMapper.selectDictDataByType("location_type");
        String occupiedStatus = locationType.stream()
                .filter(data -> "占用".equals(data.getDictLabel()))
                .map(SysDictData::getDictValue)
                .findFirst()
                .orElse(null);

        if (occupiedStatus == null) {
            throw new IllegalStateException("无法获取占用状态值");
        }

        // 托盘数据处理
        List<SysDictData> containerType = sysDictDataMapper.selectDictDataByType("container_type");

        // 处理重型料箱
        resultList.add(processContainerData(validPallets, containerType, "重型料箱", occupiedStatus));

        // 处理轻型料箱
        resultList.add(processContainerData(validPallets, containerType, "轻型料箱", occupiedStatus));

        // 库位数据处理
        List<Object> storageLocationData = processStorageLocationData(occupiedStatus);
        resultList.add(storageLocationData);

        return resultList;
    }

    private List<Object> processContainerData(List<TBasePallet> pallets, List<SysDictData> containerType, String containerLabel, String occupiedStatus) {
        List<Object> dataList = new ArrayList<>();

        // 获取指定类型的字典值
        String typeValue = containerType.stream()
                .filter(data -> containerLabel.equals(data.getDictLabel()))
                .map(SysDictData::getDictValue)
                .findFirst()
                .orElse(null);

        if (typeValue == null) {
            // 如果字典值未找到，默认返回 0
            dataList.add(0);
            dataList.add(0);
            return dataList;
        }

        // 获取指定类型的托盘
        List<TBasePallet> filteredPallets = pallets.stream()
                .filter(pallet -> typeValue.equals(pallet.getType()))
                .collect(Collectors.toList());

        if (filteredPallets.isEmpty()) {
            // 如果没有该类型的托盘，默认返回 0
            dataList.add(0);
            dataList.add(0);
        } else {
            // 获取占用状态的托盘
            long occupiedCount = filteredPallets.stream()
                    .filter(pallet -> occupiedStatus.equals(pallet.getStatus()))
                    .count();
            dataList.add((int) occupiedCount);
            dataList.add(filteredPallets.size());
        }

        return dataList;
    }

    private List<Object> processStorageLocationData(String occupiedStatus) {
        List<Object> dataList = new ArrayList<>();

        // 获取所有库位信息
        List<TBaseStorageAreaLocation> allLocations = tBaseStorageAreaLocationMapper.selectTBaseStorageAreaLocationList(new TBaseStorageAreaLocation());

        // 获取占用状态的库位
        long occupiedCount = allLocations.stream()
                .filter(location -> occupiedStatus.equals(location.getStatus()))
                .count();

        dataList.add((int) occupiedCount);
        dataList.add(allLocations.size());

        return dataList;
    }
    @GetMapping("/ckRkData")
    @Log(title = "出入库通知单")
    public List<Object> ckRkData() {
        List<Object> list = new ArrayList<>();
        int size = tOngoodsshelfMapper.selectTOngoodsshelfList(new TOngoodsshelf()).size();
        //入库
        list.add(size);

        int size1 = tCkPickingwavegoodsMapper.selectTCkPickingwavegoodsList(new TCkPickingwavegoods()).size();
        //出库
        list.add(size1);

        int size2 = tRkWareNoticeTabMapper.selectTRkWareNoticeTabList(new TRkWareNoticeTab()).size();
        //入库通知单
        list.add(size2);

        int size3 = tCkOrdersMapper.selectTCkOrdersList(new TCkOrders()).size();
        //出库通知单
        list.add(size3);

        int size4 = tCkOrdersMapper.selectTCkOrdersList(new TCkOrders()).stream().filter(f -> f.getIsAudit().equals("2")).collect(Collectors.toList()).size();
        //出库通知单待审核
        list.add(size4);
        return list;
    }
    @GetMapping("/dayAMonthCk")
    @Log(title = "今日本月出库")
    public List<Object> dayAMonthCk() {
        List<Object> list = new ArrayList<>();

        try {
            LocalDate today = LocalDate.now(ZoneId.systemDefault());
            Date startOfDay = Date.from(today.atStartOfDay(ZoneId.systemDefault()).toInstant());
            Date endOfDay = Date.from(today.plusDays(1).atStartOfDay(ZoneId.systemDefault()).toInstant());

            List<TckOrderdetailBak> tckOrderdetailBaks = tckOrderdetailBakMapper.selectTckOrderdetailBakList(new TckOrderdetailBak());
            List<TCkOrderdetail> tCkOrderdetails = tCkOrderdetailMapper.selectTCkOrderdetailList(new TCkOrderdetail());

            // 1. 过滤创建时间为空的元素 (Stream 操作)
            List<TckOrderdetailBak> filteredByCreateTime = tckOrderdetailBaks != null ? tckOrderdetailBaks.stream()
                    .filter(f -> f != null && f.getCreateTime() != null)
                    .collect(Collectors.toList()) : new ArrayList<>();

            List<TCkOrderdetail> filteredByCreateTime1 = tCkOrderdetails != null ? tCkOrderdetails.stream()
                    .filter(f -> f != null && f.getCreateTime() != null)
                    .collect(Collectors.toList()) : new ArrayList<>();

            // 2. 判断是否有数据，避免空指针
            if (filteredByCreateTime.isEmpty() && filteredByCreateTime1.isEmpty()) {
                list.add(0);
                list.add(BigDecimal.ZERO);
                list.add(BigDecimal.ZERO);
                return list;
            }

            // 3. 筛选当天数据 (Stream 操作)
            List<TckOrderdetailBak> todayOrders = filteredByCreateTime.stream()
                    .filter(f -> f.getCreateTime().compareTo(startOfDay) >= 0 && f.getCreateTime().compareTo(endOfDay) < 0)
                    .collect(Collectors.toList());

            List<TCkOrderdetail> todayOrders1 = filteredByCreateTime1.stream()
                    .filter(f -> f.getCreateTime().compareTo(startOfDay) >= 0 && f.getCreateTime().compareTo(endOfDay) < 0)
                    .collect(Collectors.toList());

            // 4. 计算每日条数
            int dailyCount = (todayOrders != null ? todayOrders.size() : 0) + (todayOrders1 != null ? todayOrders1.size() : 0);
            list.add(dailyCount);

            // 5. 筛选当天有金额数据的订单 (Stream 操作)
            List<TckOrderdetailBak> todayOrdersWithMoney = todayOrders != null ? todayOrders.stream()
                    .filter(f -> f != null && f.getToMoney() != null)
                    .collect(Collectors.toList()) : new ArrayList<>();

            List<TCkOrderdetail> todayOrdersWithMoney1 = todayOrders1 != null ? todayOrders1.stream()
                    .filter(f -> f != null && f.getToMoney() != null)
                    .collect(Collectors.toList()) : new ArrayList<>();

            // 6. 计算每日金额
            BigDecimal totalTomoney = todayOrdersWithMoney.stream()
                    .map(TckOrderdetailBak::getToMoney)
                    .filter(Objects::nonNull)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);

            BigDecimal totalTomoney1 = todayOrdersWithMoney1.stream()
                    .map(TCkOrderdetail::getToMoney)
                    .filter(Objects::nonNull)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);

            list.add(totalTomoney);

            // 7. 筛选本月数据 (Stream 操作)
            YearMonth currentYearMonth = YearMonth.now();
            List<TckOrderdetailBak> thisMonthOrders = filteredByCreateTime.stream()
                    .filter(f -> {
                        if (f != null && f.getCreateTime() != null) {
                            LocalDate createTimeLocalDate = f.getCreateTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
                            YearMonth yearMonth = YearMonth.of(createTimeLocalDate.getYear(), createTimeLocalDate.getMonth());
                            return yearMonth.equals(currentYearMonth);
                        }
                        return false;
                    })
                    .collect(Collectors.toList());

            List<TCkOrderdetail> thisMonthOrders1 = filteredByCreateTime1.stream()
                    .filter(f -> {
                        if (f != null && f.getCreateTime() != null) {
                            LocalDate createTimeLocalDate = f.getCreateTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
                            YearMonth yearMonth = YearMonth.of(createTimeLocalDate.getYear(), createTimeLocalDate.getMonth());
                            return yearMonth.equals(currentYearMonth);
                        }
                        return false;
                    })
                    .collect(Collectors.toList());

            // 8. 计算月总金额
            BigDecimal monthlyTotalTomoney = thisMonthOrders.stream()
                    .filter(f -> f != null && f.getToMoney() != null)
                    .map(TckOrderdetailBak::getToMoney)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);

            BigDecimal monthlyTotalTomoney1 = thisMonthOrders1.stream()
                    .filter(f -> f != null && f.getToMoney() != null)
                    .map(TCkOrderdetail::getToMoney)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);

            list.add(monthlyTotalTomoney);

        } catch (Exception e) {
            // 异常处理
            e.printStackTrace();
            // 如果发生异常，添加默认值
            list.clear();
            list.add(0);
            list.add(BigDecimal.ZERO);
            list.add(BigDecimal.ZERO);
        }

        return list;
    }

    @GetMapping("/dayAMonthRk")
    @Log(title = "今日本月入库")
    public List<Object> dayAMonthRk() {
        List<Object> list = new ArrayList<>();

        try {
            LocalDate today = LocalDate.now(ZoneId.systemDefault());
            Date startOfDay = Date.from(today.atStartOfDay(ZoneId.systemDefault()).toInstant());
            Date endOfDay = Date.from(today.plusDays(1).atStartOfDay(ZoneId.systemDefault()).toInstant());

            List<TRkWareNoticeTabBak> tckOrderdetailBaks = tRkWareNoticeTabBakMapper.selectTRkWareNoticeTabBakList(new TRkWareNoticeTabBak());
            List<TRkWareNoticeTab> tCkOrderdetails = tRkWareNoticeTabMapper.selectTRkWareNoticeTabList(new TRkWareNoticeTab());

            // 1. 过滤创建时间为空的元素 (Stream 操作)
            List<TRkWareNoticeTabBak> filteredByCreateTime = tckOrderdetailBaks != null ? tckOrderdetailBaks.stream()
                    .filter(f -> f != null && f.getCreateTime() != null)
                    .collect(Collectors.toList()) : new ArrayList<>();

            List<TRkWareNoticeTab> filteredByCreateTime1 = tCkOrderdetails != null ? tCkOrderdetails.stream()
                    .filter(f -> f != null && f.getCreateTime() != null)
                    .collect(Collectors.toList()) : new ArrayList<>();

            // 2. 判断是否有数据，避免空指针
            if (filteredByCreateTime.isEmpty() && filteredByCreateTime1.isEmpty()) {
                list.add(0);
                list.add(BigDecimal.ZERO);
                list.add(BigDecimal.ZERO);
                return list;
            }

            // 3. 筛选当天数据 (Stream 操作)
            List<TRkWareNoticeTabBak> todayOrders = filteredByCreateTime.stream()
                    .filter(f -> f.getCreateTime().compareTo(startOfDay) >= 0 && f.getCreateTime().compareTo(endOfDay) < 0)
                    .collect(Collectors.toList());

            List<TRkWareNoticeTab> todayOrders1 = filteredByCreateTime1.stream()
                    .filter(f -> f.getCreateTime().compareTo(startOfDay) >= 0 && f.getCreateTime().compareTo(endOfDay) < 0)
                    .collect(Collectors.toList());

            // 4. 计算每日条数
            int dailyCount = (todayOrders != null ? todayOrders.size() : 0) + (todayOrders1 != null ? todayOrders1.size() : 0);
            list.add(dailyCount);

            // 5. 筛选当天有金额数据的订单 (Stream 操作)
            List<TRkWareNoticeTabBak> todayOrdersWithMoney = todayOrders != null ? todayOrders.stream()
                    .filter(f -> f != null && f.getTotalMoney() != null)
                    .collect(Collectors.toList()) : new ArrayList<>();

            List<TRkWareNoticeTab> todayOrdersWithMoney1 = todayOrders1 != null ? todayOrders1.stream()
                    .filter(f -> f != null && f.getTotalMoney() != null)
                    .collect(Collectors.toList()) : new ArrayList<>();

            // 6. 计算每日金额
            BigDecimal totalTomoney = todayOrdersWithMoney.stream()
                    .map(TRkWareNoticeTabBak::getTotalMoney)
                    .filter(Objects::nonNull)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);

            BigDecimal totalTomoney1 = todayOrdersWithMoney1.stream()
                    .map(TRkWareNoticeTab::getTotalMoney)
                    .filter(Objects::nonNull)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);

            list.add(totalTomoney);

            // 7. 筛选本月数据 (Stream 操作)
            YearMonth currentYearMonth = YearMonth.now();
            List<TRkWareNoticeTabBak> thisMonthOrders = filteredByCreateTime.stream()
                    .filter(f -> {
                        if (f != null && f.getCreateTime() != null) {
                            LocalDate createTimeLocalDate = f.getCreateTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
                            YearMonth yearMonth = YearMonth.of(createTimeLocalDate.getYear(), createTimeLocalDate.getMonth());
                            return yearMonth.equals(currentYearMonth);
                        }
                        return false;
                    })
                    .collect(Collectors.toList());

            List<TRkWareNoticeTab> thisMonthOrders1 = filteredByCreateTime1.stream()
                    .filter(f -> {
                        if (f != null && f.getCreateTime() != null) {
                            LocalDate createTimeLocalDate = f.getCreateTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
                            YearMonth yearMonth = YearMonth.of(createTimeLocalDate.getYear(), createTimeLocalDate.getMonth());
                            return yearMonth.equals(currentYearMonth);
                        }
                        return false;
                    })
                    .collect(Collectors.toList());

            // 8. 计算月总金额
            BigDecimal monthlyTotalTomoney = thisMonthOrders.stream()
                    .filter(f -> f != null && f.getTotalMoney() != null)
                    .map(TRkWareNoticeTabBak::getTotalMoney)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);

            BigDecimal monthlyTotalTomoney1 = thisMonthOrders1.stream()
                    .filter(f -> f != null && f.getTotalMoney() != null)
                    .map(TRkWareNoticeTab::getTotalMoney)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);

            list.add(monthlyTotalTomoney);

        } catch (Exception e) {
            // 异常处理
            e.printStackTrace();
            // 如果发生异常，添加默认值
            list.clear();
            list.add(0);
            list.add(BigDecimal.ZERO);
            list.add(BigDecimal.ZERO);
        }

        return list;
    }

    @GetMapping("/sixMonthCk")
    @Log(title = "近六个月出库数量金额")
    public Map<Object,List<Object>> sixMonthCk() {
        Map<Object,List<Object>> map = new LinkedHashMap<>();
        List<TckOrderdetailBak> tckOrderdetailBaks = tckOrderdetailBakMapper.selectTckOrderdetailBakList(new TckOrderdetailBak());
        List<TckOrderdetailBak> tckOrderdetailBak = tckOrderdetailBaks.stream().filter(f -> ObjectUtils.isNotEmpty(f.getCreateTime())).collect(Collectors.toList());
        // 获取当前时间
        YearMonth currentMonth = YearMonth.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy.MM");
        // 遍历当前月及前五个月
        for (int i = 5; i >= 0; i--) {
            List<Object> list = new ArrayList<>();
            // 获取当前月向前推 i 个月的 YearMonth
            YearMonth yearMonth = currentMonth.minusMonths(1);
            YearMonth targetMonth = yearMonth.minusMonths(i);
            LocalDate monthStart = targetMonth.atDay(1); // 月初
            LocalDate monthEnd = targetMonth.atEndOfMonth(); // 月末
            String date = targetMonth.format(formatter);

            // 将 LocalDate 转换为 Date
            Date startDate = Date.from(monthStart.atStartOfDay(ZoneId.systemDefault()).toInstant());
            Date endDate = Date.from(monthEnd.atStartOfDay(ZoneId.systemDefault()).toInstant());

            // 筛选出 createtime 在当前月份范围内的数据
            List<TckOrderdetailBak> filteredList = tckOrderdetailBak.stream()
                    .filter(item -> item.getCreateTime() != null)
                    .filter(item -> item.getCreateTime().compareTo(startDate) >= 0 &&
                            item.getCreateTime().compareTo(endDate) <= 0)
                    .collect(Collectors.toList());

            if(filteredList.isEmpty()){
                list.add(0);
                list.add(0);
            }else{
                BigDecimal goodNums = filteredList.stream()
                        .map(TckOrderdetailBak::getGoodsNum)
                        .reduce(BigDecimal.ZERO, BigDecimal::add);
                list.add(goodNums);
                List<TckOrderdetailBak> collect = filteredList.stream().filter(f -> ObjectUtils.isNotEmpty(f.getToMoney())).collect(Collectors.toList());
                if(collect.isEmpty()){
                    list.add(0);
                }else {
                    BigDecimal toMoney = collect.stream()
                            .map(TckOrderdetailBak::getToMoney)
                            .reduce(BigDecimal.ZERO, BigDecimal::add);
                    list.add(toMoney);
                }
            }
            map.put(date,list);
        }
        return map;
    }

    @GetMapping("/sixMonthOutAndIn")
    @Log(title = "近六个月出库入库金额")
    public Map<Object,List<Object>> sixMonthOutAndIn() {
        Map<Object,List<Object>> map = new LinkedHashMap<>();
        List<TckOrderdetailBak> tckOrderdetailBaks = tckOrderdetailBakMapper.selectTckOrderdetailBakList(new TckOrderdetailBak());
        List<TckOrderdetailBak> tckOrderdetailBak = tckOrderdetailBaks.stream().filter(f -> ObjectUtils.isNotEmpty(f.getCreateTime())).collect(Collectors.toList());

        List<TRkWareNoticeTabBak> tckOrderdetailBaks1 = tRkWareNoticeTabBakMapper.selectTRkWareNoticeTabBakList(new TRkWareNoticeTabBak());
        List<TRkWareNoticeTabBak> tckOrderdetailBak1 = tckOrderdetailBaks1.stream().filter(f -> ObjectUtils.isNotEmpty(f.getCreateTime())).collect(Collectors.toList());


        // 获取当前时间
        YearMonth currentMonth = YearMonth.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy.MM");
        // 遍历前6个月
        for (int i = 6; i >= 1; i--) {
            List<Object> list = new ArrayList<>();
            // 获取当前月向前推 i 个月的 YearMonth
            YearMonth targetMonth = currentMonth.minusMonths(i);
            LocalDate monthStart = targetMonth.atDay(1); // 月初
            LocalDate monthEnd = targetMonth.atEndOfMonth(); // 月末
            String date = targetMonth.format(formatter);

            // 将 LocalDate 转换为 Date
            Date startDate = Date.from(monthStart.atStartOfDay(ZoneId.systemDefault()).toInstant());
            Date endDate = Date.from(monthEnd.atStartOfDay(ZoneId.systemDefault()).toInstant());

            // 筛选出 createtime 在当前月份范围内的数据
            List<TckOrderdetailBak> filteredList = tckOrderdetailBak.stream()
                    .filter(item -> item.getCreateTime() != null)
                    .filter(item -> item.getCreateTime().compareTo(startDate) >= 0 &&
                            item.getCreateTime().compareTo(endDate) <= 0)
                    .collect(Collectors.toList());

            if(filteredList.isEmpty()){
                list.add(0);

            }else{
                List<TckOrderdetailBak> collect = filteredList.stream().filter(f -> ObjectUtils.isNotEmpty(f.getToMoney())).collect(Collectors.toList());
                if(collect.isEmpty()){
                    list.add(0);
                }else {
                    BigDecimal toMoney = collect.stream()
                            .map(TckOrderdetailBak::getToMoney)
                            .reduce(BigDecimal.ZERO, BigDecimal::add);
                    if(toMoney == BigDecimal.ZERO){
                        list.add(toMoney);
                    }else{
                        BigDecimal divide = toMoney.divide(new BigDecimal(10000), 2, BigDecimal.ROUND_HALF_UP);
                        list.add(divide);
                    }
                }
            }

            List<TRkWareNoticeTabBak> filteredList1 = tckOrderdetailBak1.stream()
                    .filter(item -> item.getCreateTime() != null)
                    .filter(item -> item.getCreateTime().compareTo(startDate) >= 0 &&
                            item.getCreateTime().compareTo(endDate) <= 0)
                    .collect(Collectors.toList());

            if(filteredList1.isEmpty()){
                list.add(0);

            }else{
                List<TRkWareNoticeTabBak> collect = filteredList1.stream().filter(f -> ObjectUtils.isNotEmpty(f.getTotalMoney())).collect(Collectors.toList());
                if(collect.isEmpty()){
                    list.add(0);
                }else {
                    BigDecimal toMoney = collect.stream()
                            .map(TRkWareNoticeTabBak::getTotalMoney)
                            .reduce(BigDecimal.ZERO, BigDecimal::add);
                    if(toMoney == BigDecimal.ZERO){
                        list.add(toMoney);
                    }else{
                        BigDecimal divide = toMoney.divide(new BigDecimal(10000), 2, BigDecimal.ROUND_HALF_UP);
                        list.add(divide);
                    }

                }
            }
            map.put(date,list);
        }
        return map;
    }

    @GetMapping("/sixMonthRk")
    @Log(title = "近六个月入库数量金额")
    public Map<Object,List<Object>> sixMonthRk() {
        Map<Object,List<Object>> map = new LinkedHashMap<>();
        List<TRkWareNoticeTabBak> tckOrderdetailBaks = tRkWareNoticeTabBakMapper.selectTRkWareNoticeTabBakList(new TRkWareNoticeTabBak());
        List<TRkWareNoticeTabBak> tckOrderdetailBak = tckOrderdetailBaks.stream().filter(f -> ObjectUtils.isNotEmpty(f.getCreateTime())).collect(Collectors.toList());
        // 获取当前时间
        YearMonth currentMonth = YearMonth.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy.MM");
        // 遍历当前月及前五个月
        for (int i = 5; i >= 0; i--) {
            List<Object> list = new ArrayList<>();
            // 获取当前月向前推 i 个月的 YearMonth
            YearMonth yearMonth = currentMonth.minusMonths(1);
            YearMonth targetMonth = yearMonth.minusMonths(i);
            LocalDate monthStart = targetMonth.atDay(1); // 月初
            LocalDate monthEnd = targetMonth.atEndOfMonth(); // 月末
            String date = targetMonth.format(formatter);

            // 将 LocalDate 转换为 Date
            Date startDate = Date.from(monthStart.atStartOfDay(ZoneId.systemDefault()).toInstant());
            Date endDate = Date.from(monthEnd.atStartOfDay(ZoneId.systemDefault()).toInstant());

            // 筛选出 createtime 在当前月份范围内的数据
            List<TRkWareNoticeTabBak> filteredList = tckOrderdetailBak.stream()
                    .filter(item -> item.getCreateTime() != null)
                    .filter(item -> item.getCreateTime().compareTo(startDate) >= 0 &&
                            item.getCreateTime().compareTo(endDate) <= 0)
                    .collect(Collectors.toList());

            if(filteredList.isEmpty()){
                list.add(0);
                list.add(0);
            }else{
                List<TRkWareNoticeTabBak> collect1 = filteredList.stream().filter(f -> ObjectUtils.isNotEmpty(f.getAcceNum())).collect(Collectors.toList());
                if(collect1.isEmpty()){
                    list.add(0);
                }else{
                    BigDecimal goodNums = collect1.stream()
                            .map(TRkWareNoticeTabBak::getAcceNum)
                            .reduce(BigDecimal.ZERO, BigDecimal::add);
                    list.add(goodNums);
                }
                List<TRkWareNoticeTabBak> collect = filteredList.stream().filter(f -> ObjectUtils.isNotEmpty(f.getTotalMoney())).collect(Collectors.toList());
                if(collect.isEmpty()){
                    list.add(0);
                }else {
                    BigDecimal toMoney = collect.stream()
                            .map(TRkWareNoticeTabBak::getTotalMoney)
                            .reduce(BigDecimal.ZERO, BigDecimal::add);
                    list.add(toMoney);
                }
            }
            map.put(date,list);
        }
        return map;
    }

    @GetMapping("/ckMoneyVS")
    @Log(title = "出库金额同比")
    public Map<Object, List<Object>> ckMoneyVS() {
        Map<Object, List<Object>> map = new LinkedHashMap<>();
        List<TckOrderdetailBak> tckOrderdetailBaks = tckOrderdetailBakMapper.selectTckOrderdetailBakList(new TckOrderdetailBak());
        List<TckOrderdetailBak> tckOrderdetailBak = tckOrderdetailBaks.stream()
                .filter(f -> ObjectUtils.isNotEmpty(f.getCreateTime()))
                .collect(Collectors.toList());

        // 获取当前时间
        YearMonth currentMonth = YearMonth.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy.MM");

        for (int i = 6; i >= 1; i--) {
            List<Object> list = new ArrayList<>();

            // 获取当前月向前推 i 个月的 YearMonth
            YearMonth targetMonth = currentMonth.minusMonths(i);
            LocalDate monthStart = targetMonth.atDay(1); // 月初
            LocalDate monthEnd = targetMonth.atEndOfMonth(); // 月末
            String date = targetMonth.format(formatter);

            // 定义时间范围
            Date startDate = Date.from(monthStart.atStartOfDay(ZoneId.systemDefault()).toInstant());
            Date endDate = Date.from(monthEnd.atStartOfDay(ZoneId.systemDefault()).toInstant());

            // 筛选出 createtime 在当前月份范围内的数据
            list.add(getSumForMonth(tckOrderdetailBak, startDate, endDate));

            // 添加去年同月数据
            YearMonth lastYearMonth = targetMonth.minusYears(1);
            LocalDate lastYearStart = lastYearMonth.atDay(1);
            LocalDate lastYearEnd = lastYearMonth.atEndOfMonth();
            Date lastYearStartDate = Date.from(lastYearStart.atStartOfDay(ZoneId.systemDefault()).toInstant());
            Date lastYearEndDate = Date.from(lastYearEnd.atStartOfDay(ZoneId.systemDefault()).toInstant());
            list.add(getSumForMonth(tckOrderdetailBak, lastYearStartDate, lastYearEndDate));

            // 添加前年同月数据
            YearMonth twoYearsAgoMonth = targetMonth.minusYears(2);
            LocalDate twoYearsAgoStart = twoYearsAgoMonth.atDay(1);
            LocalDate twoYearsAgoEnd = twoYearsAgoMonth.atEndOfMonth();
            Date twoYearsAgoStartDate = Date.from(twoYearsAgoStart.atStartOfDay(ZoneId.systemDefault()).toInstant());
            Date twoYearsAgoEndDate = Date.from(twoYearsAgoEnd.atStartOfDay(ZoneId.systemDefault()).toInstant());
            list.add(getSumForMonth(tckOrderdetailBak, twoYearsAgoStartDate, twoYearsAgoEndDate));

            // 将结果存入 map
            map.put(date, list);
        }
        return map;
    }

    @GetMapping("/monthOutTo")
    @Log(title = "本月物资流向")
    public Map<Object, BigDecimal> monthOutTo() {
        Map<Object,BigDecimal> map = new LinkedHashMap<>();
        LocalDate today = LocalDate.now(ZoneId.systemDefault());
        //筛选日期不为空
        List<TckOrderdetailBak> tckOrderdetailBaks = tckOrderdetailBakMapper.selectTckOrderdetailBakList(new TckOrderdetailBak());
        List<TckOrderdetailBak> tckOrderdetailBak = tckOrderdetailBaks.stream()
                .filter(f -> ObjectUtils.isNotEmpty(f.getCreateTime()) && ObjectUtils.isNotEmpty(f.getApplicant()))
                .collect(Collectors.toList());
        //筛选本月
        List<TckOrderdetailBak> thisMonthOrders = tckOrderdetailBak.stream()
                .filter(f -> {
                    LocalDate createTimeLocalDate = f.getCreateTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
                    YearMonth yearMonth = YearMonth.of(createTimeLocalDate.getYear(), createTimeLocalDate.getMonth());
                    YearMonth currentYearMonth = YearMonth.now();
                    return yearMonth.equals(currentYearMonth);
                })
                .collect(Collectors.toList());
        //根据申请人分组
        Map<String, List<TckOrderdetailBak>> groupedByApplicant = thisMonthOrders.stream()
                .collect(Collectors.groupingBy(TckOrderdetailBak::getApplicant));

        Map<String, List<TckOrderdetailBak>> filteredMap = new HashMap<>();
        groupedByApplicant.forEach((applicant, group) -> {
            SysUser sysUser = sysUserMapper.selectUserByNickName(applicant);
            Long deptId = null;
            if(sysUser != null){
                deptId = sysUser.getDeptId();
            }

            if(deptId == null){
                return;
            }

            String ancestors = sysDeptMapper.selectDeptById(deptId).getAncestors();
            String[] split = ancestors.split(",");
            if (split.length > 3 ||split.length==3) {
                filteredMap.put(applicant, group);
            }
        });
        groupedByApplicant = filteredMap;
        groupedByApplicant.forEach((applicant, group) -> {

            SysUser sysUser = sysUserMapper.selectUserByNickName(applicant);
            Long deptId = null;
            if(sysUser != null){
                deptId = sysUser.getDeptId();
            }
            if(deptId == null){
                return;
            }
            String ancestors = sysDeptMapper.selectDeptById(deptId).getAncestors();
            String[] split = ancestors.split(",");
            String deptName;
            if(split.length==3){
                deptName= sysDeptMapper.selectDeptById(deptId).getDeptName();
            }else {
                deptName= sysDeptMapper.selectDeptById(Long.valueOf(split[3])).getDeptName();
            }
            System.out.println("Applicant: " + applicant);
            //筛选空值
            List<TckOrderdetailBak> collect = group.stream().filter(f -> ObjectUtils.isNotEmpty(f.getToMoney())).collect(Collectors.toList());
            BigDecimal toMoney;
            if(collect.isEmpty()){
                toMoney= BigDecimal.ZERO;
            }else{
                toMoney = collect.stream()
                        .map(TckOrderdetailBak::getToMoney)
                        .reduce(BigDecimal.ZERO, BigDecimal::add);
            }
            if(toMoney.compareTo(BigDecimal.ZERO) != 0){
                toMoney = toMoney.divide(new BigDecimal(10000), 2, BigDecimal.ROUND_HALF_UP);
            }
            BigDecimal bigDecimal = map.get(deptName);
            if(ObjectUtils.isEmpty(bigDecimal)){
                map.put(deptName,toMoney);
            }else{
                BigDecimal add = bigDecimal.add(toMoney);
                map.put(deptName,add);
            }

        });

        return map;
    }

    @GetMapping("/sixMonthOutTo")
    @Log(title = "近6个月物资流向")
    public List<Map<Object,BigDecimal>> sixMonthOutTo() {
        List<Map<Object,BigDecimal>> list = new LinkedList<>();
//        Map<Object,Map<Object, BigDecimal>> maps = new LinkedHashMap<>();
        LocalDate today = LocalDate.now(ZoneId.systemDefault());
        //筛选日期不为空
        List<TckOrderdetailBak> tckOrderdetailBaks = tckOrderdetailBakMapper.selectTckOrderdetailBakList(new TckOrderdetailBak());
        List<TckOrderdetailBak> tckOrderdetailBak = tckOrderdetailBaks.stream()
                .filter(f -> ObjectUtils.isNotEmpty(f.getCreateTime()) && ObjectUtils.isNotEmpty(f.getApplicant()))
                .collect(Collectors.toList());
        // 获取当前时间
        YearMonth currentMonth = YearMonth.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy.MM");
        // 遍历当前月及前五个月
        for (int i = 6; i >= 1; i--) {
            Map<Object,BigDecimal> map = new LinkedHashMap<>();

            // 获取当前月向前推 i 个月的 YearMonth
            YearMonth targetMonth = currentMonth.minusMonths(i);
            LocalDate monthStart = targetMonth.atDay(1); // 月初
            LocalDate monthEnd = targetMonth.atEndOfMonth(); // 月末
            String date = targetMonth.format(formatter);

            // 将 LocalDate 转换为 Date
            Date startDate = Date.from(monthStart.atStartOfDay(ZoneId.systemDefault()).toInstant());
            Date endDate = Date.from(monthEnd.atStartOfDay(ZoneId.systemDefault()).toInstant());

            // 筛选出 createtime 在当前月份范围内的数据
            List<TckOrderdetailBak> thisMonthOrders = tckOrderdetailBak.stream()
                    .filter(item -> item.getCreateTime() != null)
                    .filter(item -> item.getCreateTime().compareTo(startDate) >= 0 &&
                            item.getCreateTime().compareTo(endDate) <= 0)
                    .collect(Collectors.toList());


            //筛选本月
            if(thisMonthOrders.isEmpty()){
                map.put("其他",BigDecimal.ZERO);
                list.add(map);
                continue;
            }
            List<TckOrderdetailBak> collect1 = thisMonthOrders.stream().filter(f -> ObjectUtils.isNotEmpty(f.getApplicant())).collect(Collectors.toList());
            if(collect1.isEmpty()){
                map.put("其他",BigDecimal.ZERO);
                list.add(map);
                continue;
            }
            //根据申请人分组
            Map<String, List<TckOrderdetailBak>> groupedByApplicant = collect1.stream()
                    .collect(Collectors.groupingBy(TckOrderdetailBak::getApplicant));
            Map<String, List<TckOrderdetailBak>> filteredMap = new HashMap<>();
            groupedByApplicant.forEach((applicant, group) -> {
                SysUser sysUser = sysUserMapper.selectUserByNickName(applicant);
                Long deptId = null;
                if(sysUser != null){
                    deptId = sysUser.getDeptId();
                }
                if(deptId == null){
                    return;
                }
                String ancestors = sysDeptMapper.selectDeptById(deptId).getAncestors();
                String[] split = ancestors.split(",");
                if (split.length > 3 ||split.length==3) {
                    filteredMap.put(applicant, group);
                }
            });
            groupedByApplicant = filteredMap;
            groupedByApplicant.forEach((applicant, group) -> {
                SysUser sysUser = sysUserMapper.selectUserByNickName(applicant);
                Long deptId = null;
                if(sysUser != null){
                    deptId = sysUser.getDeptId();
                }
                if(deptId == null){
                    return;
                }
                String ancestors = sysDeptMapper.selectDeptById(deptId).getAncestors();
                String[] split = ancestors.split(",");
                String deptName;
                if(split.length==3){
                    deptName= sysDeptMapper.selectDeptById(deptId).getDeptName();
                }else {
                    deptName= sysDeptMapper.selectDeptById(Long.valueOf(split[3])).getDeptName();
                }
                System.out.println("Applicant: " + applicant);
                //筛选空值
                List<TckOrderdetailBak> collect = group.stream().filter(f -> ObjectUtils.isNotEmpty(f.getToMoney())).collect(Collectors.toList());
                BigDecimal toMoney;
                if (collect.isEmpty()) {
                    toMoney = BigDecimal.ZERO;
                } else {
                    toMoney = collect.stream()
                            .map(TckOrderdetailBak::getToMoney)
                            .reduce(BigDecimal.ZERO, BigDecimal::add);
                }
                BigDecimal bigDecimal = map.get(deptName);
                if (ObjectUtils.isEmpty(bigDecimal)) {
                    map.put(deptName, toMoney);
                } else {
                    BigDecimal add = bigDecimal.add(toMoney);
                    map.put(deptName, add);
                }

            });
            list.add(map);
        }

        return list;
    }


    @GetMapping("/groupCk")
    @Log(title = "小组出库金额")
    public Map<Object, BigDecimal> groupCk() {
        Map<Object,BigDecimal> map = new LinkedHashMap<>();
        LocalDate today = LocalDate.now(ZoneId.systemDefault());
// 筛选日期不为空和申请人不为空
        List<TckOrderdetailBak> tckOrderdetailBaks = tckOrderdetailBakMapper.selectTckOrderdetailBakList(new TckOrderdetailBak());
        List<TckOrderdetailBak> tckOrderdetailBak = tckOrderdetailBaks.stream()
                .filter(f -> ObjectUtils.isNotEmpty(f.getCreateTime()) && ObjectUtils.isNotEmpty(f.getApplicant()))
                .collect(Collectors.toList());
// 筛选本年
        List<TckOrderdetailBak> thisYearOrders = tckOrderdetailBak.stream()
                .filter(f -> {
                    LocalDate createTimeLocalDate = f.getCreateTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
                    int createTimeYear = createTimeLocalDate.getYear();
                    int currentYear = Year.now().getValue();
                    return createTimeYear == currentYear; // 判断年份是否为当前年份
                })
                .collect(Collectors.toList());
        //根据申请人分组
        Map<String, List<TckOrderdetailBak>> groupedByApplicant = thisYearOrders.stream()
                .collect(Collectors.groupingBy(TckOrderdetailBak::getApplicant));

        Map<String, List<TckOrderdetailBak>> filteredMap = new HashMap<>();
        groupedByApplicant.forEach((applicant, group) -> {
            SysUser sysUser = sysUserMapper.selectUserByNickName(applicant);
            Long deptId = null;
            if(sysUser != null){
                deptId = sysUser.getDeptId();
            }
            if(deptId == null){
                return;
            }
            String ancestors = sysDeptMapper.selectDeptById(deptId).getAncestors();
            String[] split = ancestors.split(",");
            if (split.length > 3 ||split.length==3) {
                filteredMap.put(applicant, group);
            }
        });
        groupedByApplicant = filteredMap;
        groupedByApplicant.forEach((applicant, group) -> {

            SysUser sysUser = sysUserMapper.selectUserByNickName(applicant);
            Long deptId = null;
            if(sysUser != null){
                deptId = sysUser.getDeptId();
            }
            if(deptId == null){
                return;
            }

            String ancestors = sysDeptMapper.selectDeptById(deptId).getAncestors();
            String[] split = ancestors.split(",");
            String deptName;
            if(split.length==3){
                deptName= sysDeptMapper.selectDeptById(deptId).getDeptName();
            }else {
                deptName= sysDeptMapper.selectDeptById(Long.valueOf(split[3])).getDeptName();
            }
            System.out.println("Applicant: " + applicant);
            //筛选空值
            List<TckOrderdetailBak> collect = group.stream().filter(f -> ObjectUtils.isNotEmpty(f.getToMoney())).collect(Collectors.toList());
            BigDecimal toMoney;
            if(collect.isEmpty()){
                toMoney= BigDecimal.ZERO;
            }else{
                toMoney = collect.stream()
                        .map(TckOrderdetailBak::getToMoney)
                        .reduce(BigDecimal.ZERO, BigDecimal::add);
            }
            BigDecimal bigDecimal = map.get(deptName);
            if(ObjectUtils.isEmpty(bigDecimal)){
                map.put(deptName,toMoney);
            }else{
                BigDecimal add = bigDecimal.add(toMoney);
                map.put(deptName,add);
            }

        });

        return map;
    }


    @GetMapping("/monthYsOut/{deptId}")
    @Log(title = "近6月预算支出")
    public Map<Object, BigDecimal> monthYsOut(@PathVariable String deptId) {
        System.out.println(deptId);
        Map<Object,BigDecimal> map = new LinkedHashMap<>();
        List<TckOrderdetailBak> tckOrderdetailBaks = tckOrderdetailBakMapper.selectTckOrderdetailBakList(new TckOrderdetailBak());
        List<TckOrderdetailBak> tckOrderdetailBak = tckOrderdetailBaks.stream().filter(f -> ObjectUtils.isNotEmpty(f.getCreateTime())).collect(Collectors.toList());
        // 获取当前时间
        YearMonth currentMonth = YearMonth.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy.MM");
        // 遍历当前月及前五个月
        for (int i = 6; i >= 1; i--) {
            List<Object> list = new ArrayList<>();
            // 获取当前月向前推 i 个月的 YearMonth
            YearMonth targetMonth = currentMonth.minusMonths(i);
            LocalDate monthStart = targetMonth.atDay(1); // 月初
            LocalDate monthEnd = targetMonth.atEndOfMonth(); // 月末
            String date = targetMonth.format(formatter);

            // 将 LocalDate 转换为 Date
            Date startDate = Date.from(monthStart.atStartOfDay(ZoneId.systemDefault()).toInstant());
            Date endDate = Date.from(monthEnd.atStartOfDay(ZoneId.systemDefault()).toInstant());

            // 筛选出 createtime 在当前月份范围内的数据
            List<TckOrderdetailBak> filteredList = tckOrderdetailBak.stream()
                    .filter(item -> item.getCreateTime() != null)
                    .filter(item -> item.getCreateTime().compareTo(startDate) >= 0 &&
                            item.getCreateTime().compareTo(endDate) <= 0)
                    .collect(Collectors.toList());
            BigDecimal toMoney;
            if(filteredList.isEmpty()){
                toMoney=BigDecimal.ZERO;

            }else{
//                List<TckOrderdetailBak> collect = filteredList.stream().filter(f -> ObjectUtils.isNotEmpty(f.getToMoney())).collect(Collectors.toList());
//                if(collect.isEmpty()){
//                    toMoney=BigDecimal.ZERO;
//                }else {
//                     toMoney = collect.stream()
//                            .map(TckOrderdetailBak::getToMoney)
//                            .reduce(BigDecimal.ZERO, BigDecimal::add);
//                    list.add(toMoney);
//                }
                List<Object> ck = ck(filteredList, deptId);

                Object  o = ck.get(0);
                BigDecimal bigDecimalValue = new BigDecimal(String.valueOf(o));
                toMoney = bigDecimalValue;
            }
            map.put(date,toMoney);
        }
        return map;
    }


    @GetMapping("/totalUse")
    @Log(title = "累计使用率")
    public BigDecimal totalUse() {
        BigDecimal total;
        List<TckOrderdetailBak> tckOrderdetailBaks = tckOrderdetailBakMapper.selectTckOrderdetailBakList(new TckOrderdetailBak());
        List<TckOrderdetailBak> tckOrderdetailBak = tckOrderdetailBaks.stream().filter(f -> ObjectUtils.isNotEmpty(f.getCreateTime())).collect(Collectors.toList());
        if(tckOrderdetailBak.isEmpty()){
            total = BigDecimal.ZERO;
        }else{
            int currentYear = LocalDate.now(ZoneId.systemDefault()).getYear();

            // 筛选 createTime 字段为本年的数据
            List<TckOrderdetailBak> collect = tckOrderdetailBak.stream()
                    .filter(item -> {
                        LocalDate createTimeLocalDate = item.getCreateTime()
                                .toInstant()
                                .atZone(ZoneId.systemDefault())
                                .toLocalDate(); // 将 Date 转换为 LocalDate
                        return createTimeLocalDate.getYear() == currentYear; // 比较年份
                    })
                    .collect(Collectors.toList());
            if(collect.isEmpty()){
                total = BigDecimal.ZERO;
            }else{
                List<TckOrderdetailBak> collect1 = collect.stream().filter(f -> ObjectUtils.isNotEmpty(f.getToMoney())).collect(Collectors.toList());
                if(collect1.isEmpty()){
                    total = BigDecimal.ZERO;
                }else{
                    total = collect1.stream()
                            .map(TckOrderdetailBak::getToMoney)
                            .reduce(BigDecimal.ZERO, BigDecimal::add);
                }
            }
        }
        return total;
    }


    @GetMapping("/yearCkRk")
    @Log(title = "出入库单数趋势")
    public Map<Object,Object> yearCkRk() {
        Map<Object,Object> map =new LinkedHashMap<>();
        List<TckOrderdetailBak> tckOrderdetailBaks = tckOrderdetailBakMapper.selectTckOrderdetailBakList(new TckOrderdetailBak());
        List<TckOrderdetailBak> tckOrderdetailBak = tckOrderdetailBaks.stream().filter(f -> ObjectUtils.isNotEmpty(f.getCreateTime())).collect(Collectors.toList());

        List<TRkWareNoticeTabBak> tRkWareNoticeTabBaks = tRkWareNoticeTabBakMapper.selectTRkWareNoticeTabBakList(new TRkWareNoticeTabBak());
        List<TRkWareNoticeTabBak> tRkWareNoticeTabBak = tRkWareNoticeTabBaks.stream().filter(f -> ObjectUtils.isNotEmpty(f.getCreateTime())).collect(Collectors.toList());

        int currentYear = LocalDate.now().getYear();

        List dong1 = new LinkedList();
        List xi1 = new LinkedList();
        List nan1 = new LinkedList();
        List ccd1 = new LinkedList();

        // 遍历本年每个月
        for (int month = 1; month <= 12; month++) {
            YearMonth yearMonth = YearMonth.of(currentYear, month);

            LocalDate startDate = yearMonth.atDay(1); // Start of the month
            LocalDate endDate = yearMonth.atEndOfMonth(); // End of the month (inclusive)

            List<TckOrderdetailBak> monthlyData = tckOrderdetailBak.stream()
                    .filter(order -> {
                        LocalDate orderDate = order.getCreateTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
                        return orderDate.isAfter(startDate.minusDays(1)) && orderDate.isBefore(endDate.plusDays(1));
                    })
                    .collect(Collectors.toList());

            List<TRkWareNoticeTabBak> monthlyDatas = tRkWareNoticeTabBak.stream()
                    .filter(order -> {
                        LocalDate orderDate = order.getCreateTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
                        return orderDate.isAfter(startDate.minusDays(1)) && orderDate.isBefore(endDate.plusDays(1));
                    })
                    .collect(Collectors.toList());
            int dong = location(monthlyData, monthlyDatas, 101, "东区维修中心");
            int xi = location(monthlyData, monthlyDatas, 128, "西区维修中心");
            int nan = location(monthlyData, monthlyDatas, 129, "南区维修中心");
            int ccd = location(monthlyData, monthlyDatas, 120, "仓储队");
            dong1.add(dong);
            xi1.add(xi);
            nan1.add(nan);
            ccd1.add(ccd);

        }
        map.put("东区维修中心",dong1);
        map.put("西区维修中心",xi1);
        map.put("南区维修中心",nan1);
        map.put("仓储队",ccd1);
        return map;
    }
    public  int location(List<TckOrderdetailBak> monthlyData,List<TRkWareNoticeTabBak> monthlyDatas,int i,String location){
        int totalsize;
        int ck;
        int rk;
        if(monthlyData.isEmpty()){
            ck = 0;
        }
        else {
            List<TckOrderdetailBak> ckList = monthlyData.stream().filter(f -> ObjectUtils.isNotEmpty(f.getApplicant())).collect(Collectors.toList());
            if(ckList.isEmpty()){
                ck=0;
            }
            else{
                Map<String, List<TckOrderdetailBak>> groupedByApplicant = ckList.stream()
                        .collect(Collectors.groupingBy(TckOrderdetailBak::getApplicant));
                Map<String, List<TckOrderdetailBak>> filteredMap = new HashMap<>();
                groupedByApplicant.forEach((applicant, group) -> {
                    SysUser sysUser = sysUserMapper.selectUserByNickName(applicant);
                    Long deptId = null;
                    if(sysUser != null){
                        deptId = sysUser.getDeptId();
                    }
                    if(deptId == null){
                        return;
                    }
                    String ancestors = sysDeptMapper.selectDeptById(deptId).getAncestors();
                    if(deptId == i || ancestors.contains(String.valueOf(i))){
                        filteredMap.put(applicant, group);
                    }


                });
                if(filteredMap.isEmpty()){
                    ck = 0;
                }else{
                    groupedByApplicant = filteredMap;
                    ck = groupedByApplicant.size();
                }

            }
        }

        if(monthlyDatas.isEmpty()){
            rk = 0;
        }else{
            List<TRkWareNoticeTabBak> rks = monthlyDatas.stream().filter(f -> ObjectUtils.isNotEmpty(f.getNeedDept()) && f.getNeedDept().equals(location)).collect(Collectors.toList());
            if(rks.isEmpty()){
                rk = 0;
            }else{
                rk = rks.size();
            }
        }
        totalsize = ck + rk;
        return  totalsize;
    }


    /**
     * 获取指定时间段内的金额总和
     */
    private Object getSumForMonth(List<TckOrderdetailBak> tckOrderdetailBak, Date startDate, Date endDate) {
        // 筛选出 createtime 在指定范围内的数据
        List<TckOrderdetailBak> filteredList = tckOrderdetailBak.stream()
                .filter(item -> item.getCreateTime() != null)
                .filter(item -> item.getCreateTime().compareTo(startDate) >= 0 &&
                        item.getCreateTime().compareTo(endDate) <= 0)
                .collect(Collectors.toList());

        // 如果没有符合条件的数据，返回 0
        if (filteredList.isEmpty()) {
            return 0;
        }

        // 筛选出 toMoney 非空的数据并计算总和
        List<TckOrderdetailBak> collect = filteredList.stream()
                .filter(f -> ObjectUtils.isNotEmpty(f.getToMoney()))
                .collect(Collectors.toList());
        if (collect.isEmpty()) {
            return 0;
        } else {
            return collect.stream()
                    .map(TckOrderdetailBak::getToMoney)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
        }
    }




    /**
     * 出入库任务数量统计
     *
     * @return
     */
    @GetMapping("/task")
    public List<Map<String, Object>> task() {
        return largeScreenService.task();
    }

    @GetMapping("/tmistockFB")
    @Log(title = "库存分布")
    public List<Map<String, Object>> tmistockFB() {
        List<Map<String, Object>> list = new ArrayList<>();
        List<TMiStock> tMiStocks = tMiStockMapper.selectTMiStockList(new TMiStock());
        List<TMiStock> tMiStock = tMiStocks.stream().filter(f -> ObjectUtils.isNotEmpty(f.getCreateTime()) && ObjectUtils.isNotEmpty(f.getTotalMoney())).collect(Collectors.toList());
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime oneMonthAgo = now.minusMonths(1);
        Map<String,Object> map = new LinkedHashMap<>();
        BigDecimal total = total(tMiStock, oneMonthAgo);
        map.put("1个月",total);

        List<TMiStock> collect = tMiStock.stream()
                .filter(f -> LocalDateTime.ofInstant(f.getCreateTime().toInstant(), ZoneId.systemDefault())
                        .isBefore(oneMonthAgo))
                .collect(Collectors.toList());
        LocalDateTime oneMonthAgo3 = now.minusMonths(3);
        BigDecimal total3 = total(collect, oneMonthAgo3);
        map.put("3个月",total3);


        List<TMiStock> collect1 = tMiStock.stream()
                .filter(f -> LocalDateTime.ofInstant(f.getCreateTime().toInstant(), ZoneId.systemDefault())
                        .isBefore(oneMonthAgo3))
                .collect(Collectors.toList());
        LocalDateTime oneMonthAgo6 = now.minusMonths(6);
        BigDecimal total6 = total(collect1, oneMonthAgo6);
        map.put("6个月",total6);


        List<TMiStock> collect2 = tMiStock.stream()
                .filter(f -> LocalDateTime.ofInstant(f.getCreateTime().toInstant(), ZoneId.systemDefault())
                        .isBefore(oneMonthAgo6))
                .collect(Collectors.toList());
        LocalDateTime oneMonthAgo12 = now.minusMonths(12);
        BigDecimal total12 = total(collect2, oneMonthAgo12);
        map.put("12个月",total12);


        List<TMiStock> collect3 = tMiStock.stream()
                .filter(f -> LocalDateTime.ofInstant(f.getCreateTime().toInstant(), ZoneId.systemDefault())
                        .isBefore(oneMonthAgo12))
                .collect(Collectors.toList());
        LocalDateTime oneMonthAgo24 = now.minusMonths(24);
        BigDecimal total24 = total(collect3, oneMonthAgo24);
        map.put("24个月",total24);

        List<TMiStock> collect4 = tMiStock.stream()
                .filter(f -> LocalDateTime.ofInstant(f.getCreateTime().toInstant(), ZoneId.systemDefault())
                        .isBefore(oneMonthAgo24))
                .collect(Collectors.toList());
        LocalDateTime oneMonthAgo36 = now.minusMonths(36);
        BigDecimal total36 = total(collect4, oneMonthAgo36);
        map.put("36个月",total36);


        LocalDateTime thirtySixMonthsAgo = now.minusMonths(36);

        List<TMiStock> collect5 = tMiStocks.stream()
                .filter(f -> {
                    LocalDateTime createTime = LocalDateTime.ofInstant(f.getCreateTime().toInstant(), ZoneId.systemDefault());
                    return createTime.isBefore(thirtySixMonthsAgo);
                })
                .collect(Collectors.toList());
        BigDecimal totalMoney;
        if(collect5.isEmpty()){
            totalMoney = BigDecimal.ZERO;
        }else{
            totalMoney = collect.stream()
                    .map(TMiStock::getTotalMoney) // 提取 getMoney 字段
                    .filter(java.util.Objects::nonNull) // 排除 null 值
                    .reduce(BigDecimal.ZERO, BigDecimal::add); // 累加
            BigDecimal num2 = new BigDecimal("10000");
            totalMoney = totalMoney.divide(num2, 2, RoundingMode.HALF_UP);

        }
        map.put("36个月以上",totalMoney);
        list.add(map);


        return list;
    }

    public BigDecimal total( List<TMiStock> tMiStock , LocalDateTime oneMonthAgo) {

        List<TMiStock> collect = tMiStock.stream()
                .filter(f -> LocalDateTime.ofInstant(f.getCreateTime().toInstant(), ZoneId.systemDefault())
                        .isBefore(oneMonthAgo))
                .collect(Collectors.toList());
        BigDecimal totalMoney;
        if(collect.isEmpty()){
            totalMoney = BigDecimal.ZERO;
        }else{
            totalMoney = collect.stream()
                    .map(TMiStock::getTotalMoney) // 提取 getMoney 字段
                    .filter(java.util.Objects::nonNull) // 排除 null 值
                    .reduce(BigDecimal.ZERO, BigDecimal::add); // 累加
            BigDecimal num2 = new BigDecimal("10000");
            totalMoney = totalMoney.divide(num2, 2, RoundingMode.HALF_UP);

        }
        return totalMoney;
    }


    @GetMapping("/ys")
    @Log(title = "五大维修中心预算使用率")
    public List<Task> ys() {
        int currentYear = Year.now().getValue();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

//        CompletableFuture<List<TMiStock>> tMiStocksFuture = CompletableFuture.supplyAsync(() ->
//                tMiStockMapper.selectTMiStockList(new TMiStock()));

        CompletableFuture<List<TckOrderdetailBak>> tckOrderdetailBaksFuture = CompletableFuture.supplyAsync(() ->
                tckOrderdetailBakMapper.selectTckOrderdetailBakList(new TckOrderdetailBak()));

        try {
//            List<TMiStock> tMiStocks = tMiStocksFuture.get();
            List<TckOrderdetailBak> tckOrderdetailBaks = tckOrderdetailBaksFuture.get();

//            List<TMiStock> filteredList = tMiStocks.parallelStream()
//                    .filter(t -> {
//                        try {
//                            LocalDate wareDate = LocalDate.parse(t.getWareDate(), formatter);
//                            return wareDate.getYear() == currentYear;
//                        } catch (DateTimeParseException e) {
//                            return false;
//                        }
//                    })
//                    .collect(Collectors.toList());

//            BigDecimal totalMoney = filteredList.parallelStream()
//                    .map(TMiStock::getTotalMoney)
//                    .filter(Objects::nonNull)
//                    .reduce(BigDecimal.ZERO, BigDecimal::add)
//                    .divide(new BigDecimal("10000"), 2, RoundingMode.HALF_UP);

            List<TckOrderdetailBak> filteredList1 = tckOrderdetailBaks.parallelStream()
                    .filter(order -> order.getCreateTime() != null &&
                            order.getCreateTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate().getYear() == currentYear)
                    .collect(Collectors.toList());

            List<String> centers = new ArrayList<>();
            SysDictData sysDictDatas =new SysDictData();
            sysDictDatas.setDictType("sys_ys");
            List<SysDictData> sysDictData4 = sysDictDataMapper.selectDictDataList(sysDictDatas);
            for(SysDictData t : sysDictData4){
                centers.add(t.getDictLabel());
            }
            centers.remove("总预算");
            //全年出库金额
            List<Task> lists = centers.parallelStream().map(center -> {
                List<Object> centerData = ck(filteredList1, center);
                BigDecimal centerValue = new BigDecimal(centerData.get(0).toString());
                BigDecimal result;
                SysDictData sysDictData =new SysDictData();
                sysDictData.setDictType("sys_ys");
                sysDictData.setDictLabel(center);
                List<SysDictData> sysDictData1 = sysDictDataMapper.selectDictDataList(sysDictData);
                String dictValue = sysDictData1.get(0).getDictValue();
                BigDecimal bigDecimal = new BigDecimal(dictValue);

                if (centerValue.compareTo(BigDecimal.ZERO) != 0 && bigDecimal.compareTo(BigDecimal.ZERO) != 0) {
                    result = centerValue.divide(bigDecimal, new MathContext(2, RoundingMode.HALF_UP))
                            .multiply(new BigDecimal("100"));
                } else {
                    result = BigDecimal.ZERO;
                }
                YearMonth yearMonth = YearMonth.now();
                // 每个月出库金额
                List<Object> value =new ArrayList<>();
                for (int month = 0; month < yearMonth.getMonthValue(); month++) {
                    int m = yearMonth.getMonthValue() - month - 1;
                    YearMonth previousMonth = yearMonth.minusMonths(m);
                    LocalDate startOfMonth = previousMonth.atDay(1);
                    LocalDate endOfMonth = previousMonth.atEndOfMonth();

                    List<TckOrderdetailBak> filteredLists = tckOrderdetailBaks.stream()
                            .filter(order -> ObjectUtils.isNotEmpty(order.getCreateTime()))
                            .filter(order -> {
                                LocalDate orderDate = order.getCreateTime().toInstant()
                                        .atZone(ZoneId.systemDefault())
                                        .toLocalDate();
                                return orderDate.getYear() == currentYear &&
                                        orderDate.isAfter(startOfMonth.minusDays(1)) &&
                                        orderDate.isBefore(endOfMonth.plusDays(1));
                            })
                            .collect(Collectors.toList());

                    List<Object> centerData1 = ck(filteredLists, center);
                    BigDecimal centerValue1 = new BigDecimal(centerData1.get(0).toString());
                    BigDecimal result1;
                    SysDictData sysDictData2 =new SysDictData();
                    sysDictData2.setDictType("sys_ys");
                    sysDictData2.setDictLabel(center);
                    List<SysDictData> sysDictData3 = sysDictDataMapper.selectDictDataList(sysDictData2);
                    String dictValue1 = sysDictData3.get(0).getDictValue();
                    BigDecimal bigDecimal1 = new BigDecimal(dictValue1);

                    if (centerValue1.compareTo(BigDecimal.ZERO) != 0 && bigDecimal1.compareTo(BigDecimal.ZERO) != 0) {
                        result1 = centerValue1.divide(bigDecimal1, new MathContext(2, RoundingMode.HALF_UP))
                                .multiply(new BigDecimal("100"));
                    } else {
                        result1 = BigDecimal.ZERO;
                    }
                    value.add(result1);
                }

                Task task = new Task();
                task.setName(center);
                task.setRate(result);
                task.setValues(value);
                return task;
            }).collect(Collectors.toList());

            return lists;
        } catch (Exception e) {
            e.printStackTrace();
            return Collections.emptyList();
        }
    }

    @GetMapping("/ys/other")
    @Log(title = "五大维修中心预算使用率")
    public List<Task> ys1() {
        int currentYear = Year.now().getValue();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

//        CompletableFuture<List<TMiStock>> tMiStocksFuture = CompletableFuture.supplyAsync(() ->
//                tMiStockMapper.selectTMiStockList(new TMiStock()));

        CompletableFuture<List<TckOrderdetailBak>> tckOrderdetailBaksFuture = CompletableFuture.supplyAsync(() ->
                tckOrderdetailBakMapper.selectTckOrderdetailBakList(new TckOrderdetailBak()));

        try {
//            List<TMiStock> tMiStocks = tMiStocksFuture.get();
            List<TckOrderdetailBak> collect = tckOrderdetailBaksFuture.get();
            List<TckOrderdetailBak> tckOrderdetailBaks = (collect != null && !collect.isEmpty()) ?
                    collect.stream()
                            .filter(f -> f != null && f.getLevelType() != null && !f.getLevelType().equals("1"))
                            .collect(Collectors.toList()) :
                    Collections.emptyList();

//            List<TMiStock> filteredList = tMiStocks.parallelStream()
//                    .filter(t -> {
//                        try {
//                            LocalDate wareDate = LocalDate.parse(t.getWareDate(), formatter);
//                            return wareDate.getYear() == currentYear;
//                        } catch (DateTimeParseException e) {
//                            return false;
//                        }
//                    })
//                    .collect(Collectors.toList());

//            BigDecimal totalMoney = filteredList.parallelStream()
//                    .map(TMiStock::getTotalMoney)
//                    .filter(Objects::nonNull)
//                    .reduce(BigDecimal.ZERO, BigDecimal::add)
//                    .divide(new BigDecimal("10000"), 2, RoundingMode.HALF_UP);

            List<TckOrderdetailBak> filteredList1 = tckOrderdetailBaks.parallelStream()
                    .filter(order -> order.getCreateTime() != null &&
                            order.getCreateTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate().getYear() == currentYear)
                    .collect(Collectors.toList());

            List<String> centers = new ArrayList<>();
            SysDictData sysDictDatas =new SysDictData();
            sysDictDatas.setDictType("sys_ys");
            List<SysDictData> sysDictData4 = sysDictDataMapper.selectDictDataList(sysDictDatas);
            for(SysDictData t : sysDictData4){
                centers.add(t.getDictLabel());
            }
            centers.remove("总预算");
            //全年出库金额
            List<Task> lists = centers.parallelStream().map(center -> {
                List<Object> centerData = ck(filteredList1, center);
                BigDecimal centerValue = new BigDecimal(centerData.get(0).toString());
                BigDecimal result;
                SysDictData sysDictData =new SysDictData();
                sysDictData.setDictType("sys_ys");
                sysDictData.setDictLabel(center);
                List<SysDictData> sysDictData1 = sysDictDataMapper.selectDictDataList(sysDictData);
                String dictValue = sysDictData1.get(0).getDictValue();
                BigDecimal bigDecimal = new BigDecimal(dictValue);

                if (centerValue.compareTo(BigDecimal.ZERO) != 0 && bigDecimal.compareTo(BigDecimal.ZERO) != 0) {
                    result = centerValue.divide(bigDecimal, new MathContext(2, RoundingMode.HALF_UP))
                            .multiply(new BigDecimal("100"));
                } else {
                    result = BigDecimal.ZERO;
                }
                YearMonth yearMonth = YearMonth.now();
                // 每个月出库金额
                List<Object> value =new ArrayList<>();
                for (int month = 0; month < yearMonth.getMonthValue(); month++) {
                    int m = yearMonth.getMonthValue() - month - 1;
                    YearMonth previousMonth = yearMonth.minusMonths(m);
                    LocalDate startOfMonth = previousMonth.atDay(1);
                    LocalDate endOfMonth = previousMonth.atEndOfMonth();

                    List<TckOrderdetailBak> filteredLists = tckOrderdetailBaks.stream()
                            .filter(order -> ObjectUtils.isNotEmpty(order.getCreateTime()))
                            .filter(order -> {
                                LocalDate orderDate = order.getCreateTime().toInstant()
                                        .atZone(ZoneId.systemDefault())
                                        .toLocalDate();
                                return orderDate.getYear() == currentYear &&
                                        orderDate.isAfter(startOfMonth.minusDays(1)) &&
                                        orderDate.isBefore(endOfMonth.plusDays(1));
                            })
                            .collect(Collectors.toList());

                    List<Object> centerData1 = ck(filteredLists, center);
                    BigDecimal centerValue1 = new BigDecimal(centerData1.get(0).toString());
                    BigDecimal result1;
                    SysDictData sysDictData2 =new SysDictData();
                    sysDictData2.setDictType("sys_ys");
                    sysDictData2.setDictLabel(center);
                    List<SysDictData> sysDictData3 = sysDictDataMapper.selectDictDataList(sysDictData2);
                    String dictValue1 = sysDictData3.get(0).getDictValue();
                    BigDecimal bigDecimal1 = new BigDecimal(dictValue1);

                    if (centerValue1.compareTo(BigDecimal.ZERO) != 0 && bigDecimal1.compareTo(BigDecimal.ZERO) != 0) {
                        result1 = centerValue1.divide(bigDecimal1, new MathContext(2, RoundingMode.HALF_UP))
                                .multiply(new BigDecimal("100"));
                    } else {
                        result1 = BigDecimal.ZERO;
                    }
                    value.add(result1);
                }

                Task task = new Task();
                task.setName(center);
                task.setRate(result);
                task.setValues(value);
                return task;
            }).collect(Collectors.toList());

            return lists;
        } catch (Exception e) {
            e.printStackTrace();
            return Collections.emptyList();
        }
    }

    @GetMapping("/ys/global")
    @Log(title = "五大维修中心预算使用率")
    public List<Task> ys2() {
        int currentYear = Year.now().getValue();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

//        CompletableFuture<List<TMiStock>> tMiStocksFuture = CompletableFuture.supplyAsync(() ->
//                tMiStockMapper.selectTMiStockList(new TMiStock()));

        CompletableFuture<List<TckOrderdetailBak>> tckOrderdetailBaksFuture = CompletableFuture.supplyAsync(() ->
                tckOrderdetailBakMapper.selectTckOrderdetailBakList(new TckOrderdetailBak()));

        try {
//            List<TMiStock> tMiStocks = tMiStocksFuture.get();
            List<TckOrderdetailBak> collect = tckOrderdetailBaksFuture.get();
            List<TckOrderdetailBak> tckOrderdetailBaks = (collect != null && !collect.isEmpty()) ?
                    collect.stream()
                            .filter(f -> f != null && f.getLevelType() != null && f.getLevelType().equals("1"))
                            .collect(Collectors.toList()) :
                    Collections.emptyList();
            //            List<TMiStock> filteredList = tMiStocks.parallelStream()
//                    .filter(t -> {
//                        try {
//                            LocalDate wareDate = LocalDate.parse(t.getWareDate(), formatter);
//                            return wareDate.getYear() == currentYear;
//                        } catch (DateTimeParseException e) {
//                            return false;
//                        }
//                    })
//                    .collect(Collectors.toList());

//            BigDecimal totalMoney = filteredList.parallelStream()
//                    .map(TMiStock::getTotalMoney)
//                    .filter(Objects::nonNull)
//                    .reduce(BigDecimal.ZERO, BigDecimal::add)
//                    .divide(new BigDecimal("10000"), 2, RoundingMode.HALF_UP);

            List<TckOrderdetailBak> filteredList1 = tckOrderdetailBaks.parallelStream()
                    .filter(order -> order.getCreateTime() != null &&
                            order.getCreateTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate().getYear() == currentYear)
                    .collect(Collectors.toList());

            List<String> centers = new ArrayList<>();
            SysDictData sysDictDatas =new SysDictData();
            sysDictDatas.setDictType("sys_ys");
            List<SysDictData> sysDictData4 = sysDictDataMapper.selectDictDataList(sysDictDatas);
            for(SysDictData t : sysDictData4){
                centers.add(t.getDictLabel());
            }
            centers.remove("总预算");
            //全年出库金额
            List<Task> lists = centers.parallelStream().map(center -> {
                List<Object> centerData = ck(filteredList1, center);
                BigDecimal centerValue = new BigDecimal(centerData.get(0).toString());
                BigDecimal result;
                SysDictData sysDictData =new SysDictData();
                sysDictData.setDictType("sys_ys");
                sysDictData.setDictLabel(center);
                List<SysDictData> sysDictData1 = sysDictDataMapper.selectDictDataList(sysDictData);
                String dictValue = sysDictData1.get(0).getDictValue();
                BigDecimal bigDecimal = new BigDecimal(dictValue);

                if (centerValue.compareTo(BigDecimal.ZERO) != 0 && bigDecimal.compareTo(BigDecimal.ZERO) != 0) {
                    result = centerValue.divide(bigDecimal, new MathContext(2, RoundingMode.HALF_UP))
                            .multiply(new BigDecimal("100"));
                } else {
                    result = BigDecimal.ZERO;
                }
                YearMonth yearMonth = YearMonth.now();
                // 每个月出库金额
                List<Object> value =new ArrayList<>();
                for (int month = 0; month < yearMonth.getMonthValue(); month++) {
                    int m = yearMonth.getMonthValue() - month - 1;
                    YearMonth previousMonth = yearMonth.minusMonths(m);
                    LocalDate startOfMonth = previousMonth.atDay(1);
                    LocalDate endOfMonth = previousMonth.atEndOfMonth();

                    List<TckOrderdetailBak> filteredLists = tckOrderdetailBaks.stream()
                            .filter(order -> ObjectUtils.isNotEmpty(order.getCreateTime()))
                            .filter(order -> {
                                LocalDate orderDate = order.getCreateTime().toInstant()
                                        .atZone(ZoneId.systemDefault())
                                        .toLocalDate();
                                return orderDate.getYear() == currentYear &&
                                        orderDate.isAfter(startOfMonth.minusDays(1)) &&
                                        orderDate.isBefore(endOfMonth.plusDays(1));
                            })
                            .collect(Collectors.toList());

                    List<Object> centerData1 = ck(filteredLists, center);
                    BigDecimal centerValue1 = new BigDecimal(centerData1.get(0).toString());
                    BigDecimal result1;
                    SysDictData sysDictData2 =new SysDictData();
                    sysDictData2.setDictType("sys_ys");
                    sysDictData2.setDictLabel(center);
                    List<SysDictData> sysDictData3 = sysDictDataMapper.selectDictDataList(sysDictData2);
                    String dictValue1 = sysDictData3.get(0).getDictValue();
                    BigDecimal bigDecimal1 = new BigDecimal(dictValue1);

                    if (centerValue1.compareTo(BigDecimal.ZERO) != 0 && bigDecimal1.compareTo(BigDecimal.ZERO) != 0) {
                        result1 = centerValue1.divide(bigDecimal1, new MathContext(2, RoundingMode.HALF_UP))
                                .multiply(new BigDecimal("100"));
                    } else {
                        result1 = BigDecimal.ZERO;
                    }
                    value.add(result1);
                }

                Task task = new Task();
                task.setName(center);
                task.setRate(result);
                task.setValues(value);
                return task;
            }).collect(Collectors.toList());

            return lists;
        } catch (Exception e) {
            e.printStackTrace();
            return Collections.emptyList();
        }
    }

    public List<BigDecimal> month(List<TckOrderdetailBak> collect, String location) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss z yyyy", Locale.ENGLISH);

        LocalDate now = LocalDate.now();
        YearMonth currentMonth = YearMonth.from(now);
        List<BigDecimal> list = new ArrayList<>(6);

        Map<YearMonth, List<TckOrderdetailBak>> groupedData = collect.parallelStream()
                .collect(Collectors.groupingBy(item -> {
                    try {
                        return YearMonth.from(LocalDateTime.parse(item.getCreateTime().toString(), formatter));
                    } catch (Exception e) {
                        return YearMonth.of(1900, 1);
                    }
                }));

        for (int i = 1; i <= 6; i++) {
            YearMonth startMonth = currentMonth.minusMonths(i);
            YearMonth endMonth = startMonth.plusMonths(1);

            List<TckOrderdetailBak> monthData = new ArrayList<>();
            for (YearMonth month = startMonth; month.isBefore(endMonth); month = month.plusMonths(1)) {
                monthData.addAll(groupedData.getOrDefault(month, Collections.emptyList()));
            }

            if (monthData.isEmpty()) {
                list.add(BigDecimal.ZERO);
            } else {
                List<Object> ck = ck(monthData, location);
                Object o = ck.get(0);
                list.add(convertToBigDecimal(o));
            }
        }

        return list;
    }

    private BigDecimal convertToBigDecimal(Object o) {
        if (o instanceof BigDecimal) {
            return (BigDecimal) o;
        } else if (o instanceof Number) {
            return new BigDecimal(o.toString());
        } else if (o instanceof String) {
            try {
                return new BigDecimal((String) o);
            } catch (NumberFormatException e) {
                System.err.println("Invalid number format: " + o);
                return BigDecimal.ZERO;
            }
        } else {
            System.err.println("Unsupported object type: " + (o != null ? o.getClass() : "null"));
            return BigDecimal.ZERO;
        }
    }

    @GetMapping("/Outbound")
    @Log(title = "各仓本月出库分布(万元)")
    public Map<Object, Object> Outbound() {
        YearMonth currentMonth = YearMonth.from(LocalDateTime.now());
        List<TckOrderdetailBak> filteredList = tckOrderdetailBakMapper.selectTckOrderdetailBakList(new TckOrderdetailBak()).parallelStream()
                .filter(f -> {
                    Date createTimeDate = f.getCreateTime();
                    return createTimeDate != null && YearMonth.from(createTimeDate.toInstant()
                            .atZone(ZoneId.systemDefault())
                            .toLocalDateTime()).equals(currentMonth);
                })
                .collect(Collectors.toList());

        Map<String, List<TckOrderdetailBak>> groupedByStorage = filteredList.parallelStream()
                .collect(Collectors.groupingBy(TckOrderdetailBak::getStorageId));
        if(ObjectUtils.isEmpty(groupedByStorage)){
            Map<Object, Object> map = new LinkedHashMap<>();
            map.put("东区维修中心",0);
            map.put("西区维修中心",0);
            map.put("南区维修中心",0);
            map.put("仓储队",0);
            return map;
        }else{
            return groupedByStorage.entrySet().parallelStream()
                    .collect(Collectors.toMap(
                            entry -> {
                                TckOrderdetailBak bak = new TckOrderdetailBak();
                                bak.setStorageId(entry.getKey());
                                List<TckOrderdetailBak> list = tckOrderdetailBakMapper.selectTckOrderdetailBakList(bak);
                                return list.isEmpty() ? "Unknown" : list.get(0).getStorageShortName();
                            },
                            entry -> calculateTotalMoneys(entry.getValue()),
                            (v1, v2) -> v1,
                            HashMap::new
                    ));
        }


    }

    @GetMapping("/Outbound/other")
    @Log(title = "各仓本月出库分布(万元)")
    public Map<Object, Object> Outbound1() {
        YearMonth currentMonth = YearMonth.from(LocalDateTime.now());
        List<TckOrderdetailBak> filteredList = tckOrderdetailBakMapper.selectTckOrderdetailBakList(new TckOrderdetailBak()).parallelStream()
                .filter(f -> {
                    // 添加判空处理
                    String levelType = f != null ? f.getLevelType() : null;
                    if (levelType != null && !levelType.equals("1")) {
                        return false; // 如果 levelType 为 "1"，则过滤掉
                    }

                    Date createTimeDate = f != null ? f.getCreateTime() : null;
                    return createTimeDate != null && YearMonth.from(createTimeDate.toInstant()
                            .atZone(ZoneId.systemDefault())
                            .toLocalDateTime()).equals(currentMonth);
                })
                .collect(Collectors.toList());

        Map<String, List<TckOrderdetailBak>> groupedByStorage = filteredList.parallelStream()
                .collect(Collectors.groupingBy(TckOrderdetailBak::getStorageId));
        if(ObjectUtils.isEmpty(groupedByStorage)){
            Map<Object, Object> map = new LinkedHashMap<>();
            map.put("东区维修中心",0);
            map.put("西区维修中心",0);
            map.put("南区维修中心",0);
            map.put("仓储队",0);
            return map;
        }else{
            return groupedByStorage.entrySet().parallelStream()
                    .collect(Collectors.toMap(
                            entry -> {
                                TckOrderdetailBak bak = new TckOrderdetailBak();
                                bak.setStorageId(entry.getKey());
                                List<TckOrderdetailBak> list = tckOrderdetailBakMapper.selectTckOrderdetailBakList(bak);
                                return list.isEmpty() ? "Unknown" : list.get(0).getStorageShortName();
                            },
                            entry -> calculateTotalMoneys(entry.getValue()),
                            (v1, v2) -> v1,
                            HashMap::new
                    ));
        }


    }

    @GetMapping("/Outbound/global")
    @Log(title = "各仓本月出库分布(万元)")
    public Map<Object, Object> Outbound2() {
        YearMonth currentMonth = YearMonth.from(LocalDateTime.now());
        List<TckOrderdetailBak> filteredList = tckOrderdetailBakMapper.selectTckOrderdetailBakList(new TckOrderdetailBak()).parallelStream()
                .filter(f -> {
                    // 添加判空处理
                    String levelType = f != null ? f.getLevelType() : null;
                    if (levelType != null && levelType.equals("1")) {
                        return false; // 如果 levelType 为 "1"，则过滤掉
                    }

                    Date createTimeDate = f != null ? f.getCreateTime() : null;
                    return createTimeDate != null && YearMonth.from(createTimeDate.toInstant()
                            .atZone(ZoneId.systemDefault())
                            .toLocalDateTime()).equals(currentMonth);
                })
                .collect(Collectors.toList());

        Map<String, List<TckOrderdetailBak>> groupedByStorage = filteredList.parallelStream()
                .collect(Collectors.groupingBy(TckOrderdetailBak::getStorageId));
        if(ObjectUtils.isEmpty(groupedByStorage)){
            Map<Object, Object> map = new LinkedHashMap<>();
            map.put("东区维修中心",0);
            map.put("西区维修中心",0);
            map.put("南区维修中心",0);
            map.put("仓储队",0);
            return map;
        }else{
            return groupedByStorage.entrySet().parallelStream()
                    .collect(Collectors.toMap(
                            entry -> {
                                TckOrderdetailBak bak = new TckOrderdetailBak();
                                bak.setStorageId(entry.getKey());
                                List<TckOrderdetailBak> list = tckOrderdetailBakMapper.selectTckOrderdetailBakList(bak);
                                return list.isEmpty() ? "Unknown" : list.get(0).getStorageShortName();
                            },
                            entry -> calculateTotalMoneys(entry.getValue()),
                            (v1, v2) -> v1,
                            HashMap::new
                    ));
        }


    }

    @GetMapping("/CLMoney")
    @Log(title = "五大维修中心本月采领金额（万元）")
    public Map<Object, Object> CLMoney() {
        YearMonth currentMonth = YearMonth.from(LocalDateTime.now());

        CompletableFuture<List<TRkWareNoticeTabBak>> filteredListFuture = CompletableFuture.supplyAsync(() ->
                tRkWareNoticeTabBakMapper.selectTRkWareNoticeTabBakList(new TRkWareNoticeTabBak()).parallelStream()
                        .filter(f -> isCurrentMonth(f.getCreateTime(), currentMonth))
                        .collect(Collectors.toList())
        );

        CompletableFuture<List<TckOrderdetailBak>> filteredList1Future = CompletableFuture.supplyAsync(() ->
                tckOrderdetailBakMapper.selectTckOrderdetailBakList(new TckOrderdetailBak()).parallelStream()
                        .filter(f -> isCurrentMonth(f.getCreateTime(), currentMonth))
                        .collect(Collectors.toList())
        );


        try {
            List<TRkWareNoticeTabBak> filteredList = filteredListFuture.get();
            List<TckOrderdetailBak> filteredList1 = filteredList1Future.get();

            Map<Object, Object> map = new HashMap<>();
            List<String> centers = Arrays.asList("东区维修中心", "西区维修中心", "南区维修中心", "仓储队");

            centers.parallelStream().filter(Objects::nonNull).forEach(center -> {
                if(ObjectUtils.isNotEmpty(center)) {
                    List<Object> list = new ArrayList<>();
                    list.add(filteredList.isEmpty() ? 0 : rk(filteredList, center));
                    list.add(filteredList1.isEmpty() ? 0 : ck(filteredList1, center));
                    map.put(center, list);
                }});

            return map;
        } catch (Exception e) {
            e.printStackTrace();
            return Collections.emptyMap();
        }
    }

    @GetMapping("/CLMoney/other")
    @Log(title = "五大维修中心本月采领金额（万元）")
    public Map<Object, Object> CLMoney1() {
        YearMonth currentMonth = YearMonth.from(LocalDateTime.now());

        CompletableFuture<List<TRkWareNoticeTabBak>> filteredListFuture = CompletableFuture.supplyAsync(() ->
                tRkWareNoticeTabBakMapper.selectTRkWareNoticeTabBakList(new TRkWareNoticeTabBak()).parallelStream()
                        .filter(f -> {
                            // leveltype 判空和条件判断
                            if (f.getLevelType() == null || f.getLevelType().equals("1")) {
                                return false; // leveltype 为 null 或不为 "1" 时，过滤掉
                            }

                            // createTime 条件判断
                            return isCurrentMonth(f.getCreateTime(), currentMonth);
                        })
                        .collect(Collectors.toList())
        );

        CompletableFuture<List<TckOrderdetailBak>> filteredList1Future = CompletableFuture.supplyAsync(() ->
                tckOrderdetailBakMapper.selectTckOrderdetailBakList(new TckOrderdetailBak()).parallelStream()
                        .filter(f -> {
                            // leveltype 判空和条件判断
                            if (f.getLevelType() == null || f.getLevelType().equals("1")) {
                                return false; // leveltype 为 null 或不为 "1" 时，过滤掉
                            }

                            // createTime 条件判断
                            return isCurrentMonth(f.getCreateTime(), currentMonth);
                        })
                        .collect(Collectors.toList())
        );


        try {
            List<TRkWareNoticeTabBak> filteredList = filteredListFuture.get();
            List<TckOrderdetailBak> filteredList1 = filteredList1Future.get();

            Map<Object, Object> map = new HashMap<>();
            List<String> centers = Arrays.asList("东区维修中心", "西区维修中心", "南区维修中心", "仓储队");

            centers.parallelStream().filter(Objects::nonNull).forEach(center -> {
                if(ObjectUtils.isNotEmpty(center)) {
                    List<Object> list = new ArrayList<>();
                    list.add(filteredList.isEmpty() ? 0 : rk(filteredList, center));
                    list.add(filteredList1.isEmpty() ? 0 : ck(filteredList1, center));
                    map.put(center, list);
                }});

            return map;
        } catch (Exception e) {
            e.printStackTrace();
            return Collections.emptyMap();
        }
    }

    @GetMapping("/CLMoney/global")
    @Log(title = "五大维修中心本月采领金额（万元）")
    public Map<Object, Object> CLMoney2() {
        YearMonth currentMonth = YearMonth.from(LocalDateTime.now());

        CompletableFuture<List<TRkWareNoticeTabBak>> filteredListFuture = CompletableFuture.supplyAsync(() ->
                tRkWareNoticeTabBakMapper.selectTRkWareNoticeTabBakList(new TRkWareNoticeTabBak()).parallelStream()
                        .filter(f -> {
                            // leveltype 判空和条件判断
                            if (f.getLevelType() == null || !f.getLevelType().equals("1")) {
                                return false; // leveltype 为 null 或不为 "1" 时，过滤掉
                            }

                            // createTime 条件判断
                            return isCurrentMonth(f.getCreateTime(), currentMonth);
                        })
                        .collect(Collectors.toList())
        );

        CompletableFuture<List<TckOrderdetailBak>> filteredList1Future = CompletableFuture.supplyAsync(() ->
                tckOrderdetailBakMapper.selectTckOrderdetailBakList(new TckOrderdetailBak()).parallelStream()
                        .filter(f -> {
                            // leveltype 判空和条件判断
                            if (f.getLevelType() == null || !f.getLevelType().equals("1")) {
                                return false; // leveltype 为 null 或不为 "1" 时，过滤掉
                            }

                            // createTime 条件判断
                            return isCurrentMonth(f.getCreateTime(), currentMonth);
                        })
                        .collect(Collectors.toList())
        );

        try {
            List<TRkWareNoticeTabBak> filteredList = filteredListFuture.get();
            List<TckOrderdetailBak> filteredList1 = filteredList1Future.get();

            Map<Object, Object> map = new HashMap<>();
            List<String> centers = Arrays.asList("东区维修中心", "西区维修中心", "南区维修中心", "仓储队");

            centers.parallelStream().filter(Objects::nonNull).forEach(center -> {
                if(ObjectUtils.isNotEmpty(center)) {
                    List<Object> list = new ArrayList<>();
                    list.add(filteredList.isEmpty() ? 0 : rk(filteredList, center));
                    list.add(filteredList1.isEmpty() ? 0 : ck(filteredList1, center));
                    map.put(center, list);
                }});

            return map;
        } catch (Exception e) {
            e.printStackTrace();
            return Collections.emptyMap();
        }
    }


    private BigDecimal calculateTotalMoneys(List<TckOrderdetailBak> list) {
        return list.parallelStream()
                .map(TckOrderdetailBak::getToMoney)
                .filter(Objects::nonNull)
                .reduce(BigDecimal.ZERO, BigDecimal::add)
                .divide(new BigDecimal("10000"), 2, RoundingMode.HALF_UP);
    }
    public List<Object> ck(List<TckOrderdetailBak>filteredList1,String location){
        List<Object> list =new ArrayList<>();
        List<String> dong1 = name(location);
        if(dong1.isEmpty()){
            list.add(0);
        }else {
            List<TckOrderdetailBak> dong2 = filteredList1.stream()
                    .filter(f -> f.getApplicant() != null) // 筛选 applicant 不为空
                    .filter(f -> dong1.contains(f.getApplicant())) // 筛选 applicant 在 dong1 中
                    .collect(Collectors.toList());
            if (dong2.isEmpty()) {
                list.add(0);
            } else {
                BigDecimal totalMoney = dong2.stream()
                        .map(TckOrderdetailBak::getToMoney) // 提取 getMoney 字段
                        .filter(java.util.Objects::nonNull) // 排除 null 值
                        .reduce(BigDecimal.ZERO, BigDecimal::add); // 累加
                BigDecimal num2 = new BigDecimal("10000");
                totalMoney = totalMoney.divide(num2, 2, RoundingMode.HALF_UP);
                list.add(totalMoney);
            }
        }
        return list;
    }
    private boolean isCurrentMonth(Date date, YearMonth currentMonth) {
        return date != null && YearMonth.from(date.toInstant()
                .atZone(ZoneId.systemDefault())
                .toLocalDateTime()).equals(currentMonth);
    }
    public List<Object> rk(List<TRkWareNoticeTabBak>filteredList,String location){
        List<Object> list =new ArrayList<>();
        if(ObjectUtils.isNotEmpty(filteredList)){
            List<TRkWareNoticeTabBak> collect = filteredList.stream().filter(f -> ObjectUtils.isNotEmpty(f.getNeedDept())).collect(Collectors.toList());
            if(ObjectUtils.isNotEmpty(collect)){
            List<TRkWareNoticeTabBak> dong = collect.stream().filter(f -> f.getNeedDept().equals(location)).collect(Collectors.toList());
        if(dong.isEmpty()){
            list.add(0);
        }else{
            BigDecimal totalMoney = dong.stream()
                    .map(TRkWareNoticeTabBak::getTotalMoney) // 提取 getMoney 字段
                    .filter(java.util.Objects::nonNull) // 排除 null 值
                    .reduce(BigDecimal.ZERO, BigDecimal::add); // 累加
            BigDecimal num2 =new BigDecimal("10000");
            totalMoney = totalMoney.divide(num2, 2, RoundingMode.HALF_UP);
            list.add(totalMoney);
        }
        }else {
            list.add(0);
        }
        }else {
            list.add(0);
        }
        return list;
    }

    public List<String> name (String dept){
        SysDept sysDept = sysDeptMapper.selectDeptByName(dept);
        List<Long> longs = sysDeptMapper.selectDeptId(sysDept.getDeptId());
        System.out.println(longs);
        List<String> list = sysUserMapper.selectByDepeId(longs);
        return list;
    }

    @GetMapping("/tmistockTotal")
    @Log(title = "仓库总览")
    public CompletableFuture<List<Object>> tmistockTotal() {
        LocalDate now = LocalDate.now();
        int currentYear = now.getYear();
        Month currentMonth = now.getMonth();

        CompletableFuture<BigDecimal> totalMoneyFuture = CompletableFuture.supplyAsync(() ->
                tMiStockMapper.getTotalMoney().divide(new BigDecimal("10000"), 2, RoundingMode.HALF_UP));

        CompletableFuture<BigDecimal> totalMoneyThisMonthFuture = CompletableFuture.supplyAsync(() ->
                tckOrderdetailBakMapper.getTotalMoneyForYearMonth(currentYear, currentMonth.getValue())
                        .divide(new BigDecimal("10000"), 2, RoundingMode.HALF_UP));

        CompletableFuture<BigDecimal> totalMoneyThisMonth1Future = CompletableFuture.supplyAsync(() ->
                tRkWareNoticeTabBakMapper.getTotalMoneyForYearMonth(currentYear, currentMonth.getValue())
                        .divide(new BigDecimal("10000"), 2, RoundingMode.HALF_UP));

        CompletableFuture<Integer> tBaseStoragesSizeFuture = CompletableFuture.supplyAsync(() ->
                tBaseStorageMapper.getCount());

        CompletableFuture<BigDecimal> totalMoneyThisYearFuture = CompletableFuture.supplyAsync(() ->
                tckOrderdetailBakMapper.getTotalMoneyForYear(currentYear)
                        .divide(new BigDecimal("10000"), 2, RoundingMode.HALF_UP));
        SysDictData sysDictData = new SysDictData();
        sysDictData.setDictLabel("总预算");
        sysDictData.setDictType("sys_ys");
        String dictValue = sysDictDataMapper.selectDictDataList(sysDictData).get(0).getDictValue();

        return CompletableFuture.allOf(
                totalMoneyFuture,
                totalMoneyThisMonthFuture,
                totalMoneyThisMonth1Future,
                tBaseStoragesSizeFuture,
                totalMoneyThisYearFuture
        ).thenApply(v -> {
            List<Object> list = new ArrayList<>();
            try {
                list.add(totalMoneyFuture.get());
                list.add(totalMoneyThisMonthFuture.get());
                list.add(totalMoneyThisMonth1Future.get());
                list.add(tBaseStoragesSizeFuture.get());
                list.add(totalMoneyThisYearFuture.get());
                list.add(dictValue);
            } catch (InterruptedException | ExecutionException e) {
                e.printStackTrace();
            }
            return list;
        });
    }

    @GetMapping("/tmistockTotal/other")
    @Log(title = "仓库总览")
    public CompletableFuture<List<Object>> tmistockTotal1() {
        LocalDate now = LocalDate.now();
        int currentYear = now.getYear();
        Month currentMonth = now.getMonth();

        CompletableFuture<BigDecimal> totalMoneyFuture = CompletableFuture.supplyAsync(() ->
                tMiStockMapper.getTotalMoney1().divide(new BigDecimal("10000"), 2, RoundingMode.HALF_UP));

        CompletableFuture<BigDecimal> totalMoneyThisMonthFuture = CompletableFuture.supplyAsync(() ->
                tckOrderdetailBakMapper.getTotalMoneyForYearMonth1(currentYear, currentMonth.getValue())
                        .divide(new BigDecimal("10000"), 2, RoundingMode.HALF_UP));

        CompletableFuture<BigDecimal> totalMoneyThisMonth1Future = CompletableFuture.supplyAsync(() ->
                tRkWareNoticeTabBakMapper.getTotalMoneyForYearMonth1(currentYear, currentMonth.getValue())
                        .divide(new BigDecimal("10000"), 2, RoundingMode.HALF_UP));

        CompletableFuture<Integer> tBaseStoragesSizeFuture = CompletableFuture.supplyAsync(() ->
                tBaseStorageMapper.getCount());

        CompletableFuture<BigDecimal> totalMoneyThisYearFuture = CompletableFuture.supplyAsync(() ->
                tckOrderdetailBakMapper.getTotalMoneyForYear1(currentYear)
                        .divide(new BigDecimal("10000"), 2, RoundingMode.HALF_UP));
        SysDictData sysDictData = new SysDictData();
        sysDictData.setDictLabel("总预算");
        sysDictData.setDictType("sys_ys");
        String dictValue = sysDictDataMapper.selectDictDataList(sysDictData).get(0).getDictValue();

        return CompletableFuture.allOf(
                totalMoneyFuture,
                totalMoneyThisMonthFuture,
                totalMoneyThisMonth1Future,
                tBaseStoragesSizeFuture,
                totalMoneyThisYearFuture
        ).thenApply(v -> {
            List<Object> list = new ArrayList<>();
            try {
                list.add(totalMoneyFuture.get());
                list.add(totalMoneyThisMonthFuture.get());
                list.add(totalMoneyThisMonth1Future.get());
                list.add(tBaseStoragesSizeFuture.get());
                list.add(totalMoneyThisYearFuture.get());
                list.add(dictValue);
            } catch (InterruptedException | ExecutionException e) {
                e.printStackTrace();
            }
            return list;
        });
    }

    @GetMapping("/tmistockTotal/global")
    @Log(title = "仓库总览")
    public CompletableFuture<List<Object>> tmistockTotal2() {
        LocalDate now = LocalDate.now();
        int currentYear = now.getYear();
        Month currentMonth = now.getMonth();

        CompletableFuture<BigDecimal> totalMoneyFuture = CompletableFuture.supplyAsync(() ->
                tMiStockMapper.getTotalMoney2().divide(new BigDecimal("10000"), 2, RoundingMode.HALF_UP));

        CompletableFuture<BigDecimal> totalMoneyThisMonthFuture = CompletableFuture.supplyAsync(() ->
                tckOrderdetailBakMapper.getTotalMoneyForYearMonth2(currentYear, currentMonth.getValue())
                        .divide(new BigDecimal("10000"), 2, RoundingMode.HALF_UP));

        CompletableFuture<BigDecimal> totalMoneyThisMonth1Future = CompletableFuture.supplyAsync(() ->
                tRkWareNoticeTabBakMapper.getTotalMoneyForYearMonth2(currentYear, currentMonth.getValue())
                        .divide(new BigDecimal("10000"), 2, RoundingMode.HALF_UP));

        CompletableFuture<Integer> tBaseStoragesSizeFuture = CompletableFuture.supplyAsync(() ->
                tBaseStorageMapper.getCount());

        CompletableFuture<BigDecimal> totalMoneyThisYearFuture = CompletableFuture.supplyAsync(() ->
                tckOrderdetailBakMapper.getTotalMoneyForYear2(currentYear)
                        .divide(new BigDecimal("10000"), 2, RoundingMode.HALF_UP));
        SysDictData sysDictData = new SysDictData();
        sysDictData.setDictLabel("总预算");
        sysDictData.setDictType("sys_ys");
        String dictValue = sysDictDataMapper.selectDictDataList(sysDictData).get(0).getDictValue();

        return CompletableFuture.allOf(
                totalMoneyFuture,
                totalMoneyThisMonthFuture,
                totalMoneyThisMonth1Future,
                tBaseStoragesSizeFuture,
                totalMoneyThisYearFuture
        ).thenApply(v -> {
            List<Object> list = new ArrayList<>();
            try {
                list.add(totalMoneyFuture.get());
                list.add(totalMoneyThisMonthFuture.get());
                list.add(totalMoneyThisMonth1Future.get());
                list.add(tBaseStoragesSizeFuture.get());
                list.add(totalMoneyThisYearFuture.get());
                list.add(dictValue);
            } catch (InterruptedException | ExecutionException e) {
                e.printStackTrace();
            }
            return list;
        });
    }

    @GetMapping("/sendTotal")
    @Log(title = "本月各仓出入库金额(万元)")
    public Map<Object, List<Object>> sendTotal() {
        LocalDate now = LocalDate.now();
        YearMonth currentMonth = YearMonth.from(now);

        CompletableFuture<List<TckOrderdetailBak>> ckFuture = CompletableFuture.supplyAsync(() -> {
            List<TckOrderdetailBak> tckOrderdetailBaks = tckOrderdetailBakMapper.selectTckOrderdetailBakList(new TckOrderdetailBak());
            return tckOrderdetailBaks.parallelStream()
                    .filter(f -> ObjectUtils.isNotEmpty(f.getCreateTime()))
                    .filter(f -> YearMonth.from(f.getCreateTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate()).equals(currentMonth))
                    .collect(Collectors.toList());
        });

        CompletableFuture<List<TRkWareNoticeTabBak>> rkFuture = CompletableFuture.supplyAsync(() -> {
            List<TRkWareNoticeTabBak> tRkWareNoticeTabBaks = tRkWareNoticeTabBakMapper.selectTRkWareNoticeTabBakList(new TRkWareNoticeTabBak());
            return tRkWareNoticeTabBaks.parallelStream()
                    .filter(f -> ObjectUtils.isNotEmpty(f.getCreateTime()))
                    .filter(f -> YearMonth.from(f.getCreateTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate()).equals(currentMonth))
                    .collect(Collectors.toList());
        });

        try {
            List<TckOrderdetailBak> ck = ckFuture.get();
            List<TRkWareNoticeTabBak> rk = rkFuture.get();

            Set<String> storageIds = new HashSet<>();
            ck.forEach(t -> {
                String storageId = t.getStorageId();
                if (!StringUtils.isEmpty(storageId)) { // 使用 StringUtils.isEmpty 判断空字符串
                    storageIds.add(storageId);
                }
            });
            rk.forEach(t ->{
                String storageId = t.getStorageId();
                if (!StringUtils.isEmpty(storageId)) { // 使用 StringUtils.isEmpty 判断空字符串
                    storageIds.add(storageId);
                }
            });

            Map<Object, List<Object>> map = new ConcurrentHashMap<>();
            if(ObjectUtils.isEmpty(storageIds)){
                List list =new ArrayList();
                list.add(0);
                list.add(0);
                map.put("东区维修中心", list);
                map.put("西区维修中心", list);
                map.put("南区维修中心", list);
                map.put("仓储队", list);
            }else{
                for(String t:storageIds){
                    if (ObjectUtils.isNotEmpty(t)){
                        List<Object> list = new ArrayList<>();
                        String storageShortName;
                        List<TckOrderdetailBak> collect1 = ck.stream().filter(f -> ObjectUtils.isNotEmpty(f.getStorageId()) &&  f.getStorageId().equals(t)).collect(Collectors.toList());
                        if(collect1.isEmpty()){
                            list.add(0);
                        }else{
                            BigDecimal totalMoney = collect1.parallelStream()
                                    .map(f -> f.getToMoney() == null ? BigDecimal.ZERO : f.getToMoney())
                                    .reduce(BigDecimal::add)
                                    .orElse(BigDecimal.ZERO)
                                    .divide(new BigDecimal("10000"), 2, RoundingMode.HALF_UP);
                            if(ObjectUtils.isEmpty(totalMoney)){
                                System.out.println(totalMoney);
                                System.out.println("2222222");
                            }
                            list.add(totalMoney);
                        }
                        List<TRkWareNoticeTabBak> collect = rk.stream().filter(f -> ObjectUtils.isNotEmpty(f.getStorageId()) && f.getStorageId().equals(t)).collect(Collectors.toList());
                        if(collect.isEmpty()){
                            list.add(0);
                        }else{
                            BigDecimal totalMoney1 = collect.parallelStream()
                                    .map(f -> ObjectUtils.isEmpty(f.getTotalMoney()) ? BigDecimal.ZERO : f.getTotalMoney())
                                    .reduce(BigDecimal::add)
                                    .orElse(BigDecimal.ZERO)
                                    .divide(new BigDecimal("10000"), 2, RoundingMode.HALF_UP);
                            if(!ObjectUtils.isEmpty(totalMoney1)){
                                System.out.println(totalMoney1);
                            }
                            list.add(totalMoney1);
                        }


//                        storageShortName = ck.stream()
//                                .filter(f -> f.getStorageId().equals(t))
//                                .findFirst()
//                                .map(TckOrderdetailBak::getStorageShortName)
//                                .orElseGet(() -> rk.stream()
//                                        .filter(f -> f.getStorageId().equals(t))
//                                        .findFirst()
//                                        .map(TRkWareNoticeTabBak::getStorageShortName)
//                                        .orElse("Unknown"));
                        TBaseStorage tBaseStorage = new TBaseStorage();
                        tBaseStorage.setStorageId(t);
                        storageShortName = tBaseStorageMapper.selectTBaseStorageList(tBaseStorage).get(0).getStorageShortName();
                        map.put(storageShortName, list);
                    }else{


                    }
                };
            }



            return map;
        } catch (Exception e) {
            e.printStackTrace();
            return Collections.emptyMap();
        }
    }

    @GetMapping("/sendTotal/other")
    @Log(title = "本月各仓出入库金额(万元)")
    public Map<Object, List<Object>> sendTotal1() {
        LocalDate now = LocalDate.now();
        YearMonth currentMonth = YearMonth.from(now);

//        CompletableFuture<List<TckOrderdetailBak>> ckFuture = CompletableFuture.supplyAsync(() -> {
//            List<TckOrderdetailBak> tckOrderdetailBaks = tckOrderdetailBakMapper.selectTckOrderdetailBakList(new TckOrderdetailBak());
//            return tckOrderdetailBaks.parallelStream()
//                    .filter(f -> ObjectUtils.isNotEmpty(f.getCreateTime()))
//                    .filter(f -> YearMonth.from(f.getCreateTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate()).equals(currentMonth))
//                    .collect(Collectors.toList());
//        });
        CompletableFuture<List<TckOrderdetailBak>> ckFuture = CompletableFuture.supplyAsync(() -> {
            List<TckOrderdetailBak> tckOrderdetailBaks = tckOrderdetailBakMapper.selectTckOrderdetailBakList(new TckOrderdetailBak());
            return tckOrderdetailBaks.parallelStream()
                    .filter(f -> ObjectUtils.isNotEmpty(f.getLevelType())  && !f.getLevelType().equals("1"))//leveltype判空和条件
                    .filter(f -> ObjectUtils.isNotEmpty(f.getCreateTime()))
                    .filter(f -> YearMonth.from(f.getCreateTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate()).equals(currentMonth))
                    .collect(Collectors.toList());
        });

        CompletableFuture<List<TRkWareNoticeTabBak>> rkFuture = CompletableFuture.supplyAsync(() -> {
            List<TRkWareNoticeTabBak> tRkWareNoticeTabBaks = tRkWareNoticeTabBakMapper.selectTRkWareNoticeTabBakList(new TRkWareNoticeTabBak());
            return tRkWareNoticeTabBaks.parallelStream()
                    .filter(f -> ObjectUtils.isNotEmpty(f.getLevelType())  && !f.getLevelType().equals("1"))//leveltype判空和条件
                    .filter(f -> ObjectUtils.isNotEmpty(f.getCreateTime()))
                    .filter(f -> YearMonth.from(f.getCreateTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate()).equals(currentMonth))
                    .collect(Collectors.toList());
        });

        try {
            List<TckOrderdetailBak> ck = ckFuture.get();
            List<TRkWareNoticeTabBak> rk = rkFuture.get();

            Set<String> storageIds = new HashSet<>();
            ck.forEach(t -> {
                String storageId = t.getStorageId();
                if (!StringUtils.isEmpty(storageId)) { // 使用 StringUtils.isEmpty 判断空字符串
                    storageIds.add(storageId);
                }
            });
            rk.forEach(t ->{
                String storageId = t.getStorageId();
                if (!StringUtils.isEmpty(storageId)) { // 使用 StringUtils.isEmpty 判断空字符串
                    storageIds.add(storageId);
                }
            });

            Map<Object, List<Object>> map = new ConcurrentHashMap<>();
            if(ObjectUtils.isEmpty(storageIds)){
                List list =new ArrayList();
                list.add(0);
                list.add(0);
                map.put("东区维修中心", list);
                map.put("西区维修中心", list);
                map.put("南区维修中心", list);
                map.put("仓储队", list);
            }else{
                for(String t:storageIds){
                    if (ObjectUtils.isNotEmpty(t)){
                        List<Object> list = new ArrayList<>();
                        String storageShortName;
                        List<TckOrderdetailBak> collect1 = ck.stream().filter(f -> ObjectUtils.isNotEmpty(f.getStorageId()) &&  f.getStorageId().equals(t)).collect(Collectors.toList());
                        if(collect1.isEmpty()){
                            list.add(0);
                        }else{
                            BigDecimal totalMoney = collect1.parallelStream()
                                    .map(f -> f.getToMoney() == null ? BigDecimal.ZERO : f.getToMoney())
                                    .reduce(BigDecimal::add)
                                    .orElse(BigDecimal.ZERO)
                                    .divide(new BigDecimal("10000"), 2, RoundingMode.HALF_UP);
                            if(ObjectUtils.isEmpty(totalMoney)){
                                System.out.println(totalMoney);
                                System.out.println("2222222");
                            }
                            list.add(totalMoney);
                        }
                        List<TRkWareNoticeTabBak> collect = rk.stream().filter(f -> ObjectUtils.isNotEmpty(f.getStorageId()) && f.getStorageId().equals(t)).collect(Collectors.toList());
                        if(collect.isEmpty()){
                            list.add(0);
                        }else{
                            BigDecimal totalMoney1 = collect.parallelStream()
                                    .map(f -> ObjectUtils.isEmpty(f.getTotalMoney()) ? BigDecimal.ZERO : f.getTotalMoney())
                                    .reduce(BigDecimal::add)
                                    .orElse(BigDecimal.ZERO)
                                    .divide(new BigDecimal("10000"), 2, RoundingMode.HALF_UP);
                            if(!ObjectUtils.isEmpty(totalMoney1)){
                                System.out.println(totalMoney1);
                            }
                            list.add(totalMoney1);
                        }


//                        storageShortName = ck.stream()
//                                .filter(f -> f.getStorageId().equals(t))
//                                .findFirst()
//                                .map(TckOrderdetailBak::getStorageShortName)
//                                .orElseGet(() -> rk.stream()
//                                        .filter(f -> f.getStorageId().equals(t))
//                                        .findFirst()
//                                        .map(TRkWareNoticeTabBak::getStorageShortName)
//                                        .orElse("Unknown"));
                        TBaseStorage tBaseStorage = new TBaseStorage();
                        tBaseStorage.setStorageId(t);
                        storageShortName = tBaseStorageMapper.selectTBaseStorageList(tBaseStorage).get(0).getStorageShortName();
                        map.put(storageShortName, list);
                    }else{


                    }
                };
            }



            return map;
        } catch (Exception e) {
            e.printStackTrace();
            return Collections.emptyMap();
        }
    }

    @GetMapping("/sendTotal/global")
    @Log(title = "本月各仓出入库金额(万元)")
    public Map<Object, List<Object>> sendTotal2() {
        LocalDate now = LocalDate.now();
        YearMonth currentMonth = YearMonth.from(now);

//        CompletableFuture<List<TckOrderdetailBak>> ckFuture = CompletableFuture.supplyAsync(() -> {
//            List<TckOrderdetailBak> tckOrderdetailBaks = tckOrderdetailBakMapper.selectTckOrderdetailBakList(new TckOrderdetailBak());
//            return tckOrderdetailBaks.parallelStream()
//                    .filter(f -> ObjectUtils.isNotEmpty(f.getCreateTime()))
//                    .filter(f -> YearMonth.from(f.getCreateTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate()).equals(currentMonth))
//                    .collect(Collectors.toList());
//        });
        CompletableFuture<List<TckOrderdetailBak>> ckFuture = CompletableFuture.supplyAsync(() -> {
            List<TckOrderdetailBak> tckOrderdetailBaks = tckOrderdetailBakMapper.selectTckOrderdetailBakList(new TckOrderdetailBak());
            return tckOrderdetailBaks.parallelStream()
                    .filter(f -> ObjectUtils.isNotEmpty(f.getLevelType())  && f.getLevelType().equals("1"))//leveltype判空和条件
                    .filter(f -> ObjectUtils.isNotEmpty(f.getCreateTime()))
                    .filter(f -> YearMonth.from(f.getCreateTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate()).equals(currentMonth))
                    .collect(Collectors.toList());
        });

        CompletableFuture<List<TRkWareNoticeTabBak>> rkFuture = CompletableFuture.supplyAsync(() -> {
            List<TRkWareNoticeTabBak> tRkWareNoticeTabBaks = tRkWareNoticeTabBakMapper.selectTRkWareNoticeTabBakList(new TRkWareNoticeTabBak());
            return tRkWareNoticeTabBaks.parallelStream()
                    .filter(f -> ObjectUtils.isNotEmpty(f.getLevelType())  && f.getLevelType().equals("1"))//leveltype判空和条件
                    .filter(f -> ObjectUtils.isNotEmpty(f.getCreateTime()))
                    .filter(f -> YearMonth.from(f.getCreateTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate()).equals(currentMonth))
                    .collect(Collectors.toList());
        });

        try {
            List<TckOrderdetailBak> ck = ckFuture.get();
            List<TRkWareNoticeTabBak> rk = rkFuture.get();

            Set<String> storageIds = new HashSet<>();
            ck.forEach(t -> {
                String storageId = t.getStorageId();
                if (!StringUtils.isEmpty(storageId)) { // 使用 StringUtils.isEmpty 判断空字符串
                    storageIds.add(storageId);
                }
            });
            rk.forEach(t ->{
                String storageId = t.getStorageId();
                if (!StringUtils.isEmpty(storageId)) { // 使用 StringUtils.isEmpty 判断空字符串
                    storageIds.add(storageId);
                }
            });

            Map<Object, List<Object>> map = new ConcurrentHashMap<>();
            if(ObjectUtils.isEmpty(storageIds)){
                List list =new ArrayList();
                list.add(0);
                list.add(0);
                map.put("东区维修中心", list);
                map.put("西区维修中心", list);
                map.put("南区维修中心", list);
                map.put("仓储队", list);
            }else{
                for(String t:storageIds){
                    if (ObjectUtils.isNotEmpty(t)){
                        List<Object> list = new ArrayList<>();
                        String storageShortName;
                        List<TckOrderdetailBak> collect1 = ck.stream().filter(f -> ObjectUtils.isNotEmpty(f.getStorageId()) &&  f.getStorageId().equals(t)).collect(Collectors.toList());
                        if(collect1.isEmpty()){
                            list.add(0);
                        }else{
                            BigDecimal totalMoney = collect1.parallelStream()
                                    .map(f -> f.getToMoney() == null ? BigDecimal.ZERO : f.getToMoney())
                                    .reduce(BigDecimal::add)
                                    .orElse(BigDecimal.ZERO)
                                    .divide(new BigDecimal("10000"), 2, RoundingMode.HALF_UP);
                            if(ObjectUtils.isEmpty(totalMoney)){
                                System.out.println(totalMoney);
                                System.out.println("2222222");
                            }
                            list.add(totalMoney);
                        }
                        List<TRkWareNoticeTabBak> collect = rk.stream().filter(f -> ObjectUtils.isNotEmpty(f.getStorageId()) && f.getStorageId().equals(t)).collect(Collectors.toList());
                        if(collect.isEmpty()){
                            list.add(0);
                        }else{
                            BigDecimal totalMoney1 = collect.parallelStream()
                                    .map(f -> ObjectUtils.isEmpty(f.getTotalMoney()) ? BigDecimal.ZERO : f.getTotalMoney())
                                    .reduce(BigDecimal::add)
                                    .orElse(BigDecimal.ZERO)
                                    .divide(new BigDecimal("10000"), 2, RoundingMode.HALF_UP);
                            if(!ObjectUtils.isEmpty(totalMoney1)){
                                System.out.println(totalMoney1);
                            }
                            list.add(totalMoney1);
                        }


//                        storageShortName = ck.stream()
//                                .filter(f -> f.getStorageId().equals(t))
//                                .findFirst()
//                                .map(TckOrderdetailBak::getStorageShortName)
//                                .orElseGet(() -> rk.stream()
//                                        .filter(f -> f.getStorageId().equals(t))
//                                        .findFirst()
//                                        .map(TRkWareNoticeTabBak::getStorageShortName)
//                                        .orElse("Unknown"));
                        TBaseStorage tBaseStorage = new TBaseStorage();
                        tBaseStorage.setStorageId(t);
                        storageShortName = tBaseStorageMapper.selectTBaseStorageList(tBaseStorage).get(0).getStorageShortName();
                        map.put(storageShortName, list);
                    }else{


                    }
                };
            }



            return map;
        } catch (Exception e) {
            e.printStackTrace();
            return Collections.emptyMap();
        }
    }

    @GetMapping("/tCk")
    @Log(title = "近6个月出库金额(万元)")
    public List<BigDecimal> tck() {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss z yyyy", Locale.ENGLISH);
        LocalDate now = LocalDate.now();
        YearMonth currentMonth = YearMonth.from(now);

        List<TckOrderdetailBak> tCkOrderdetails = tckOrderdetailBakMapper.selectTckOrderdetailBakList(new TckOrderdetailBak());

        List<TckOrderdetailBak> collect = tCkOrderdetails.parallelStream()
                .filter(f -> ObjectUtils.isNotEmpty(f.getCreateTime()))
                .collect(Collectors.toList());

        return IntStream.rangeClosed(1, 6)
                .mapToObj(i -> {
                    YearMonth endMonth = currentMonth;
                    YearMonth startMonth = endMonth.minusMonths(i);
                    YearMonth yearMonth = startMonth.plusMonths(1);

                    BigDecimal totalMoney = collect.parallelStream()
                            .filter(f -> {
                                try {
                                    LocalDateTime createTime = LocalDateTime.parse(f.getCreateTime().toString(), formatter);
                                    YearMonth wareMonth = YearMonth.from(createTime);
                                    return !wareMonth.isBefore(startMonth) && wareMonth.isBefore(yearMonth);
                                } catch (Exception e) {
                                    System.err.println("Error parsing date: " + e.getMessage());
                                    return false;
                                }
                            })
                            .map(TckOrderdetailBak::getToMoney)
                            .filter(Objects::nonNull)
                            .reduce(BigDecimal.ZERO, BigDecimal::add)
                            .divide(new BigDecimal("10000"), 2, RoundingMode.HALF_UP);

                    return totalMoney;
                })
                .collect(Collectors.toList());
    }

    @GetMapping("/tCk/other")
    @Log(title = "近6个月出库金额(万元)")
    public List<BigDecimal> tck1() {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss z yyyy", Locale.ENGLISH);
        LocalDate now = LocalDate.now();
        YearMonth currentMonth = YearMonth.from(now);

        List<TckOrderdetailBak> tCkOrderdetails = tckOrderdetailBakMapper.selectTckOrderdetailBakList(new TckOrderdetailBak());

        List<TckOrderdetailBak> collect1 = tCkOrderdetails.parallelStream()
                .filter(f -> ObjectUtils.isNotEmpty(f.getCreateTime()) )
                .collect(Collectors.toList());


        List<TckOrderdetailBak> collect = (collect1 != null && !collect1.isEmpty()) ?
                collect1.stream()
                        .filter(f -> f != null && f.getLevelType() != null && !f.getLevelType().equals("1"))
                        .collect(Collectors.toList()) :
                Collections.emptyList();
        return IntStream.rangeClosed(1, 6)
                .mapToObj(i -> {
                    YearMonth endMonth = currentMonth;
                    YearMonth startMonth = endMonth.minusMonths(i);
                    YearMonth yearMonth = startMonth.plusMonths(1);

                    BigDecimal totalMoney = collect.parallelStream()
                            .filter(f -> {
                                try {
                                    LocalDateTime createTime = LocalDateTime.parse(f.getCreateTime().toString(), formatter);
                                    YearMonth wareMonth = YearMonth.from(createTime);
                                    return !wareMonth.isBefore(startMonth) && wareMonth.isBefore(yearMonth);
                                } catch (Exception e) {
                                    System.err.println("Error parsing date: " + e.getMessage());
                                    return false;
                                }
                            })
                            .map(TckOrderdetailBak::getToMoney)
                            .filter(Objects::nonNull)
                            .reduce(BigDecimal.ZERO, BigDecimal::add)
                            .divide(new BigDecimal("10000"), 2, RoundingMode.HALF_UP);

                    return totalMoney;
                })
                .collect(Collectors.toList());
    }

    @GetMapping("/tCk/global")
    @Log(title = "近6个月出库金额(万元)")
    public List<BigDecimal> tck2() {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss z yyyy", Locale.ENGLISH);
        LocalDate now = LocalDate.now();
        YearMonth currentMonth = YearMonth.from(now);

        List<TckOrderdetailBak> tCkOrderdetails = tckOrderdetailBakMapper.selectTckOrderdetailBakList(new TckOrderdetailBak());

        List<TckOrderdetailBak> collect1 = tCkOrderdetails.parallelStream()
                .filter(f -> ObjectUtils.isNotEmpty(f.getCreateTime()) )
                .collect(Collectors.toList());
        List<TckOrderdetailBak> collect = (collect1 != null && !collect1.isEmpty()) ?
                collect1.stream()
                        .filter(f -> f != null && f.getLevelType() != null && f.getLevelType().equals("1"))
                        .collect(Collectors.toList()) :
                Collections.emptyList();
        return IntStream.rangeClosed(1, 6)
                .mapToObj(i -> {
                    YearMonth endMonth = currentMonth;
                    YearMonth startMonth = endMonth.minusMonths(i);
                    YearMonth yearMonth = startMonth.plusMonths(1);

                    BigDecimal totalMoney = collect.parallelStream()
                            .filter(f -> {
                                try {
                                    LocalDateTime createTime = LocalDateTime.parse(f.getCreateTime().toString(), formatter);
                                    YearMonth wareMonth = YearMonth.from(createTime);
                                    return !wareMonth.isBefore(startMonth) && wareMonth.isBefore(yearMonth);
                                } catch (Exception e) {
                                    System.err.println("Error parsing date: " + e.getMessage());
                                    return false;
                                }
                            })
                            .map(TckOrderdetailBak::getToMoney)
                            .filter(Objects::nonNull)
                            .reduce(BigDecimal.ZERO, BigDecimal::add)
                            .divide(new BigDecimal("10000"), 2, RoundingMode.HALF_UP);

                    return totalMoney;
                })
                .collect(Collectors.toList());
    }



    //库存列表
    @GetMapping("/tmistock")
    @Log(title = "库存趋势(万元)")
    public CompletableFuture<List<BigDecimal>> tmistock() {
        YearMonth currentMonth = YearMonth.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

        return CompletableFuture.supplyAsync(() ->
                IntStream.rangeClosed(1, 6)
                        .mapToObj(i -> {
                            YearMonth startMonth = currentMonth.minusMonths(i);
                            YearMonth endMonth = startMonth.plusMonths(1);
                            String startDate = startMonth.atDay(1).format(formatter);
                            String endDate = endMonth.atDay(1).format(formatter);
                            return CompletableFuture.supplyAsync(() ->
                                    tMiStockMapper.getTotalMoneyForMonth(startDate, endDate)
                            );
                        })
                        .collect(Collectors.toList())
        ).thenCompose(futures ->
                CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
                        .thenApply(v -> futures.stream()
                                .map(CompletableFuture::join)
                                .map(total -> total.divide(BigDecimal.valueOf(10000),2, RoundingMode.HALF_UP)) // 转换为万元
                                .collect(Collectors.toList())
                        )
        );
    }

    @GetMapping("/tmistock/other")
    @Log(title = "库存趋势(万元)")
    public CompletableFuture<List<BigDecimal>> tmistock1() {
        YearMonth currentMonth = YearMonth.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

        return CompletableFuture.supplyAsync(() ->
                IntStream.rangeClosed(1, 6)
                        .mapToObj(i -> {
                            YearMonth startMonth = currentMonth.minusMonths(i);
                            YearMonth endMonth = startMonth.plusMonths(1);
                            String startDate = startMonth.atDay(1).format(formatter);
                            String endDate = endMonth.atDay(1).format(formatter);
                            return CompletableFuture.supplyAsync(() ->
                                    tMiStockMapper.getTotalMoneyForMonth3(startDate, endDate)
                            );
                        })
                        .collect(Collectors.toList())
        ).thenCompose(futures ->
                CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
                        .thenApply(v -> futures.stream()
                                .map(CompletableFuture::join)
                                .map(total -> total.divide(BigDecimal.valueOf(10000),2, RoundingMode.HALF_UP)) // 转换为万元
                                .collect(Collectors.toList())
                        )
        );
    }

    @GetMapping("/tmistock/global")
    @Log(title = "库存趋势(万元)")
    public CompletableFuture<List<BigDecimal>> tmistock2() {
        YearMonth currentMonth = YearMonth.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

        return CompletableFuture.supplyAsync(() ->
                IntStream.rangeClosed(1, 6)
                        .mapToObj(i -> {
                            YearMonth startMonth = currentMonth.minusMonths(i);
                            YearMonth endMonth = startMonth.plusMonths(1);
                            String startDate = startMonth.atDay(1).format(formatter);
                            String endDate = endMonth.atDay(1).format(formatter);
                            return CompletableFuture.supplyAsync(() ->
                                    tMiStockMapper.getTotalMoneyForMonth1(startDate, endDate)
                            );
                        })
                        .collect(Collectors.toList())
        ).thenCompose(futures ->
                CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
                        .thenApply(v -> futures.stream()
                                .map(CompletableFuture::join)
                                .map(total -> total.divide(BigDecimal.valueOf(10000),2, RoundingMode.HALF_UP)) // 转换为万元
                                .collect(Collectors.toList())
                        )
        );
    }


    @GetMapping("/tmistockSix")
    @Log(title = "近6个月各级库存趋势(万元)")
    public CompletableFuture<List<BigDecimal>> tmistockSix() {
        YearMonth currentMonth = YearMonth.now();

        return CompletableFuture.supplyAsync(() ->
                IntStream.rangeClosed(1, 6)
                        .mapToObj(i -> {
                            YearMonth targetMonth = currentMonth.minusMonths(i);
                            return CompletableFuture.supplyAsync(() ->
                                    tMiStockMapper.getTotalMoneyForSpecificMonth(targetMonth.getYear(), targetMonth.getMonthValue())
                            );
                        })
                        .collect(Collectors.toList())
        ).thenCompose(futures ->
                CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
                        .thenApply(v -> futures.stream()
                                .map(CompletableFuture::join)
                                .map(total -> total.divide(BigDecimal.valueOf(10000), 2, RoundingMode.HALF_UP)) // 转换为万元
                                .collect(Collectors.toList())
                        )
        );
    }

    @GetMapping("/tmistockSix1")
    @Log(title = "近6个月1级库存趋势(万元)")
    public CompletableFuture<List<BigDecimal>> tmistockSix1() {
        YearMonth currentMonth = YearMonth.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        List<CompletableFuture<List<BigDecimal>>> list = new ArrayList<>();
        return CompletableFuture.supplyAsync(() ->
                IntStream.rangeClosed(1, 6)
                        .mapToObj(i -> {
                            YearMonth startMonth = currentMonth.minusMonths(i);
                            YearMonth endMonth = startMonth.plusMonths(1);
                            String startDate = startMonth.atDay(1).format(formatter);
                            String endDate = endMonth.atDay(1).format(formatter);
                            return CompletableFuture.supplyAsync(() ->
                                    tMiStockMapper.getTotalMoneyForMonth1(startDate, endDate)
                            );
                        })
                        .collect(Collectors.toList())
        ).thenCompose(futures ->
                CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
                        .thenApply(v -> futures.stream()
                                .map(CompletableFuture::join)
                                .map(total -> total.divide(BigDecimal.valueOf(10000),2, RoundingMode.HALF_UP)) // 转换为万元
                                .collect(Collectors.toList())
                        )
        );

    }

    @GetMapping("/tmistockSix2")
    @Log(title = "近6个月2级库存趋势(万元)")
    public CompletableFuture<List<BigDecimal>> tmistockSix2() {
        YearMonth currentMonth = YearMonth.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        List<CompletableFuture<List<BigDecimal>>> list = new ArrayList<>();
        return CompletableFuture.supplyAsync(() ->
                IntStream.rangeClosed(1, 6)
                        .mapToObj(i -> {
                            YearMonth startMonth = currentMonth.minusMonths(i);
                            YearMonth endMonth = startMonth.plusMonths(1);
                            String startDate = startMonth.atDay(1).format(formatter);
                            String endDate = endMonth.atDay(1).format(formatter);
                            return CompletableFuture.supplyAsync(() ->
                                    tMiStockMapper.getTotalMoneyForMonth2(startDate, endDate)
                            );
                        })
                        .collect(Collectors.toList())
        ).thenCompose(futures ->
                CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
                        .thenApply(v -> futures.stream()
                                .map(CompletableFuture::join)
                                .map(total -> total.divide(BigDecimal.valueOf(10000),2, RoundingMode.HALF_UP)) // 转换为万元
                                .collect(Collectors.toList())
                        )
        );

    }

    private BigDecimal calculateTotalMoney(List<TMiStock> stocks) {
        if (stocks == null || stocks.isEmpty()) {
            return BigDecimal.ZERO;
        }

        BigDecimal totalMoneys = stocks.parallelStream()
                .filter(Objects::nonNull)
                .map(tmiStock -> Optional.ofNullable(tmiStock.getTotalMoney()).orElse(BigDecimal.ZERO))
                .reduce(BigDecimal::add)
                .orElse(BigDecimal.ZERO);

        return totalMoneys.divide(new BigDecimal("10000"), 2, RoundingMode.HALF_UP);
    }

    @GetMapping("/tmistockPie")
    @Log(title = "全年存货总值")
    public Map<Object, Object> tmistockPie() {
        int currentYear = Year.now().getValue();

        CompletableFuture<List<TMiStock>> groupFuture = CompletableFuture.supplyAsync(() ->
                tMiStockMapper.selectGroupForYear());

        try {
            List<TMiStock> list = groupFuture.get();
            Map<Object, Object> map = new HashMap<>();

            if (!list.isEmpty()) {
                list.parallelStream().forEach(tMiStock -> {
                    TMiStock tMiStock1 = new TMiStock();
                    tMiStock1.setStorageId(tMiStock.getStorageId());
                    List<TMiStock> tMiStocks = tMiStockMapper.selectTMiStockListForYear(tMiStock1);

                    BigDecimal totalMoney = calculateTotalMoneyss(tMiStocks);
                    if(totalMoney.compareTo(BigDecimal.ZERO) == 0 ){
                        map.put(tMiStock.getStorageShortName(), totalMoney);
                    }else{
                        BigDecimal divide = totalMoney.divide(BigDecimal.valueOf(10000), 2, RoundingMode.HALF_UP);
                        map.put(tMiStock.getStorageShortName(), divide);
                    }

                });
            }

            return map;
        } catch (Exception e) {
            e.printStackTrace();
            return Collections.emptyMap();
        }
    }

    @GetMapping("/tmistockPie/other")
    @Log(title = "全年存货总值")
    public Map<Object, Object> tmistockPieOther() {
        int currentYear = Year.now().getValue();

        CompletableFuture<List<TMiStock>> groupFuture = CompletableFuture.supplyAsync(() ->
                tMiStockMapper.selectGroupForYear());

        try {
            List<TMiStock> list = groupFuture.get();
            Map<Object, Object> map = new HashMap<>();

            if (!list.isEmpty()) {
                list.parallelStream().forEach(tMiStock -> {
                    TMiStock tMiStock1 = new TMiStock();
                    tMiStock1.setStorageId(tMiStock.getStorageId());
                    List<TMiStock> tMiStocks = tMiStockMapper.selectTMiStockListForYear(tMiStock1);
                    List<TMiStock> collect = tMiStocks.stream().filter(t -> !t.getLevelType().equals("1")).collect(Collectors.toList());
                    BigDecimal totalMoney = calculateTotalMoneyss(collect);
                    if(totalMoney.compareTo(BigDecimal.ZERO) == 0 ){
                        map.put(tMiStock.getStorageShortName(), totalMoney);
                    }else{
                        BigDecimal divide = totalMoney.divide(BigDecimal.valueOf(10000), 2, RoundingMode.HALF_UP);
                        map.put(tMiStock.getStorageShortName(), divide);
                    }

                });
            }

            return map;
        } catch (Exception e) {
            e.printStackTrace();
            return Collections.emptyMap();
        }
    }

    @GetMapping("/tmistockPie/global")
    @Log(title = "全年存货总值")
    public Map<Object, Object> tmistockPieOtherGlobal() {
        int currentYear = Year.now().getValue();

        CompletableFuture<List<TMiStock>> groupFuture = CompletableFuture.supplyAsync(() ->
                tMiStockMapper.selectGroupForYear());

        try {
            List<TMiStock> list = groupFuture.get();
            Map<Object, Object> map = new HashMap<>();

            if (!list.isEmpty()) {
                list.parallelStream().forEach(tMiStock -> {
                    TMiStock tMiStock1 = new TMiStock();
                    tMiStock1.setStorageId(tMiStock.getStorageId());
                    List<TMiStock> tMiStocks = tMiStockMapper.selectTMiStockListForYear(tMiStock1);
                    List<TMiStock> collect = tMiStocks.stream().filter(t -> t.getLevelType().equals("1")).collect(Collectors.toList());
                    BigDecimal totalMoney = calculateTotalMoneyss(collect);
                    if(totalMoney.compareTo(BigDecimal.ZERO) == 0 ){
                        map.put(tMiStock.getStorageShortName(), totalMoney);
                    }else{
                        BigDecimal divide = totalMoney.divide(BigDecimal.valueOf(10000), 2, RoundingMode.HALF_UP);
                        map.put(tMiStock.getStorageShortName(), divide);
                    }

                });
            }

            return map;
        } catch (Exception e) {
            e.printStackTrace();
            return Collections.emptyMap();
        }
    }

    private BigDecimal calculateTotalMoneyss(List<TMiStock> tMiStocks) {
        return tMiStocks.stream()
                .map(TMiStock::getTotalMoney)
                .filter(Objects::nonNull)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
    }


    /**
     * 出库入库任务表格
     *
     * @return
     */
    @GetMapping("/quest")
    public List<Quest> quest() {
        return largeScreenService.quest();
    }


    //折线图
    @GetMapping("/line")
    public List<List<Object>> line() {
        return largeScreenService.line();

    }


    /**
     * 仓位统计
     *
     * @return
     */
    @GetMapping("/pieChart")
    public Map<String, Object> pieChart() {
        return largeScreenService.pieChart();
    }

    /**
     * 设备状态
     */
    @GetMapping("/equipmentStatu")
    public List<TAgv> equipmentStatu() {
        return largeScreenService.equipmentStatu();
    }


    @GetMapping("/police")
    public List<Map<String, Long>> police() {
        return largeScreenService.police();
    }

    /**
     * 货值分布
     *
     * @return
     */
    @GetMapping("/distribution")
    public List<Map<String, Object>> distribution() {
        return largeScreenService.distribution();
    }

    @GetMapping("/child")
    public List<Map<String, Object>> child() {
        return largeScreenService.child();
    }

    /**
     * 首页报警数据
     *
     * @return
     */
    @GetMapping("/alarmData")
    public Map<String, Integer> alarmData() {
        return largeScreenService.alarmData();
    }


    @GetMapping("/tasks/{location}")
    public AjaxResult tasks(@PathVariable("location") String location) {
        final String url = "https://172.18.29.101/rcs/rtas/api/robot/controller/task/submit";
        ObjectMapper objectMapper = new ObjectMapper();

        // 构建请求体
        Map<String, Object> taskData = new HashMap<>();
        List<Map<String, Object>> targetRoute = new ArrayList<>();
        Map<String, Object> site1 = new HashMap<>();
        site1.put("type", "SITE");
        site1.put("code", location);
        targetRoute.add(site1);

        Map<String, Object> site2 = new HashMap<>();
        site2.put("type", "SITE");

        if (location.equals("111")) {
            site2.put("code", "222");
            targetRoute.add(site2);
        } else if (location.equals("222")) {
            site2.put("code", "111");
            targetRoute.add(site2);
        }

        taskData.put("targetRoute", targetRoute);
        taskData.put("taskType", "PF-LMR-COMMON");
        taskData.put("deadline", "");
        taskData.put("initPriority", 1);
        taskData.put("extra", new HashMap<>());
        taskData.put("interrupt", "");
        taskData.put("groupCode", "");
        taskData.put("robotType", "");
        taskData.put("robotTaskCode", "");

        String requestBody = "";
        try {
            requestBody = objectMapper.writeValueAsString(taskData);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
            return AjaxResult.error("JSON processing failed");
        }

        try (CloseableHttpClient httpClient = createHttpClient()) {
            HttpPost httpPost = new HttpPost(url);
            httpPost.setHeader("Accept", "application/json");
            httpPost.setHeader("Content-type", "application/json");


            // 生成一个类似于给定字符串的随机字符串
            String hexChars = "0123456789abcdef"; // 十六进制字符集
            int len = 32; // 与给定字符串相同的长度
            StringBuilder sb = new StringBuilder(len);
            SecureRandom random = new SecureRandom();

            for (int i = 0; i < len; i++) {
                int index = random.nextInt(hexChars.length());
                sb.append(hexChars.charAt(index));
            }

            String randomHexString = sb.toString();


            //生成id
            httpPost.setHeader("X-Lr-Request-Id", randomHexString);


            /*httpPost.setHeader("Authorization", "Bearer 7a9623b5ad554ab49fbc42a270e620cb");*/

            httpPost.setEntity(new StringEntity(requestBody));

            HttpResponse response = httpClient.execute(httpPost);
            String responseString = EntityUtils.toString(response.getEntity(), "UTF-8");

            return AjaxResult.success(responseString);
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error("Failed to send POST request");
        }
    }


    private SSLContext createTrustAllSslContext() throws Exception {
        TrustManager[] trustAllCerts = new TrustManager[]{
                new X509TrustManager() {
                    public void checkClientTrusted(X509Certificate[] chain, String authType) {
                    }

                    public void checkServerTrusted(X509Certificate[] chain, String authType) {
                    }


                    public X509Certificate[] getAcceptedIssuers() {
                        return new X509Certificate[]{};
                    }
                }
        };

        SSLContext sslContext = SSLContext.getInstance("SSL");
        sslContext.init(null, trustAllCerts, new SecureRandom());
        return sslContext;
    }


    private CloseableHttpClient createHttpClient() throws Exception {
        return HttpClients.custom()
                .setSslcontext(createTrustAllSslContext())
                .setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
                .build();
    }

    private final ObjectMapper objectMapper = new ObjectMapper();


    @Log(title = "入库过账", businessType = BusinessType.OTHER)
    @PostMapping(value = "/accountIntoOrder")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult sendIwms(@RequestBody JSONObject jsonObject) {
        /* RLock lock = redissonClient.getLock("sendIwmsLock"); // 创建锁对象*/
        /*try {
            // 尝试获取锁，等待最多10秒，锁自动释放时间30秒
            if (!lock.tryLock(10, 30, TimeUnit.SECONDS)) {
                return new AjaxResult(99, "系统繁忙，请稍后再试", null);
            }*/


        logger.info("接收到callback：{}",jsonObject.getJSONArray("data").toString());

        JSONArray dataArray = jsonObject.getJSONArray("data");

        for (int i = 0; i < dataArray.size(); i++) {
            JSONObject item = dataArray.getJSONObject(i);
            //仓位号
            String binCode = item.getStr("binCode");
            //物料编码
            String matCode = item.getStr("matCode");
            //数量
            double matQty = item.getDouble("matQty");
            //单位
            String matUnit = item.getStr("matUnit");
            //明细单号
            String orderItem = item.getStr("orderItem");
            //明细子需求编号
            String orderKeyThird = item.getStr("orderKeyThird");
            //通知单号
            String orderNum = item.getStr("orderNum");
            //入库类型
            String orderType = item.getStr("orderType");
            // 申请人
//            String username = item.getStr("username");
            //仓库
            String whCode = item.getStr("whCode");
//            //需求人
//            String needPerson = item.getStr("needPerson");
//            //需求人联系方式
//            String needTel = item.getStr("needTel");
//            //操作人
//            String createBy = item.getStr("createBy");
            if ("RZ01".equalsIgnoreCase(whCode)) {
                whCode = "FJQR01";
            }

            //容器号
            String traceCode = item.getStr("traceCode");
            // 处理这些数据，例如保存到数据库或进行其他业务逻辑

            //入库通知单和明细
            TRkWareNotice wareNotice = tRkWareNoticeService.selectTRkWareNoticeById(orderNum);
            if (wareNotice == null) {
                return new AjaxResult(99, "未查询出数据", null);
            }
            List<TRkWareNoticeTab> tabList = wareNotice.getTRkWareNoticeTabList();


            //确认上架数据组装
            TRkWareNoticeTabUpdate update = new TRkWareNoticeTabUpdate();
            update.setCtlNo(traceCode);
            update.setId(wareNotice.getId());
            update.setNoticeId(wareNotice.getNoticeId());
            update.setDeliveryId(wareNotice.getDeliveryId());
            update.setStorageId(whCode);
            update.setStorageLocation(binCode);
            update.setStorageMode("3");
            update.setReceiveNum((int) matQty);
            update.setRkMxId(orderItem);
            update.setTrkWareNoticeTabList(tabList);
            //库位
            update.setFictitious("0");
            //确认收货
            Map<String, String> map = shelvesConfirm(update);
            String success = map.get("success");
            if (StringUtils.isNotBlank(success) && "上架成功".equals(success)) {
                return new AjaxResult(0, "过账成功", null);
            }
        }
        return new AjaxResult(99, "失败", null);
//        }
//        catch (InterruptedException e) {
//            Thread.currentThread().interrupt();
//            return new AjaxResult(99, "请求中断", null);
//        } finally {
//            lock.unlock(); // 释放锁
//        }
    }

    @Transactional
    public Map<String, String> shelvesConfirm(TRkWareNoticeTabUpdate params) {
        // 返回结果
        Map<String, String> resultMap = new HashMap<>();
        /*LambdaQueryWrapper<TBaseStorageAreaLocation> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TBaseStorageAreaLocation::getLocationId, params.getStorageLocation());
        List<TBaseStorageAreaLocation> areaLocations = service.selectList(wrapper);
        if (areaLocations.isEmpty()) {
            throw new RuntimeException("库位号错误");
        }*/

        //校验托盘容器是否正确
        LambdaQueryWrapper<TBasePallet> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TBasePallet::getPalletId, params.getCtlNo());
        List<TBasePallet> plcs = palletMapper.selectList(wrapper);
        if (!plcs.isEmpty()) {
            TBasePallet palletChk = plcs.get(0);
            if("0".equals(palletChk.getStatus()) || StringUtils.isBlank(palletChk.getStatus())){
                TBasePallet tBasePallet = new TBasePallet();
                tBasePallet.setStatus("1");
                tBasePallet.setId(palletChk.getId());
                tBasePallet.setUpdateTime(new Date());
                palletMapper.updateTBasePallet(tBasePallet);
            }
        }


        // 超期呆滞时间获取
        SysConfig sysConfig = new SysConfig();
        sysConfig.setConfigKey("overdue.stagnation");
        List<SysConfig> sList = sysConfigMapper.selectConfigList(sysConfig);

        if (sList.size() > 0) {
            params.getExtras().put("extraTime", sList.get(0).getConfigValue());
        } else {
            params.getExtras().put("extraTime", "");
        }

//        if (StringUtils.isBlank(params.getUserName())) {
//            params.setUserName(getUsername());
//        }

        List<TRkWareNoticeTab> updateNoticeTabs = new ArrayList<TRkWareNoticeTab>();
        List<TMiStock> insertTMiStocks = new ArrayList<TMiStock>();
        List<TMiStockF> insertTMiStockFs = new ArrayList<TMiStockF>();

        // 判断通知单明细是否存在为完成的
        Boolean allReceive = true;

        String noticeId = "";
        TRkWareNotice tRkWareNotice = null;
        List<TRkWareNoticeTab> tabList = params.getTrkWareNoticeTabList();
        if (tabList == null || tabList.size() == 0) {
            resultMap.put("error", "物料的通知单明细不存在");
            return resultMap;
        }
        for (TRkWareNoticeTab tRkWareNoticeTab : tabList) {
            if (params.getRkMxId().equals(tRkWareNoticeTab.getId())) {
                tRkWareNotice = tRkWareNoticeMapper.selectTRkWareNoticeById(tRkWareNoticeTab.getNoticeId());

                if ("2".equals(tRkWareNotice.getReceivingStatus())) {
                    resultMap.put("error", "入库通知单已全部收货，请刷新");
                    return resultMap;
                }


                // 库位
                String storageLocation = params.getStorageLocation();
                if (ObjectUtils.isEmpty(storageLocation)) {
                    resultMap.put("error", "库位不能为空");
                    return resultMap;
                }


                if ("2".equals(tRkWareNoticeTab.getReceivingStatus())) {
                    continue;
                }


                // 累计收货数量
                BigDecimal recNum = tRkWareNoticeTab.getRecNum() == null ? BigDecimal.ZERO : tRkWareNoticeTab.getRecNum();
                //累计入库数量
                BigDecimal acceNum = tRkWareNoticeTab.getAcceNum() == null ? BigDecimal.ZERO : tRkWareNoticeTab.getAcceNum();
                // 本次上架数量
                BigDecimal acceNumNew = BigDecimal.valueOf(params.getReceiveNum());

                if (acceNumNew.compareTo(BigDecimal.ZERO) == 0) {
                    resultMap.put("error", "物料【" + tRkWareNoticeTab.getGoodsName() + "】的上架数量不能为0");
                    return resultMap;
                }


                // 收货状态：全部收货
                String receiveStatus = "2";

                BigDecimal acceTotalNum = acceNum.add(acceNumNew);

                if (acceTotalNum.compareTo(recNum) < 0) {
                    /** 部分收货 */
                    receiveStatus = "1";
                }
                // 设置更新信息
                tRkWareNoticeTab.setReceivingStatus(receiveStatus);
                // 本次上架数量
                tRkWareNoticeTab.setAmount(acceNumNew);
                // 累计上架数量
                tRkWareNoticeTab.setAcceNum(acceTotalNum);
                // 库位
                tRkWareNoticeTab.setStorageLocation(storageLocation);
                // 托盘
                tRkWareNoticeTab.setStorageId(params.getStorageId());

                LambdaQueryWrapper<TBaseStorage> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(TBaseStorage::getStorageId, params.getStorageId());
                TBaseStorage storage = tBaseStorageMapper.selectOne(queryWrapper);
                tRkWareNoticeTab.setStorageShortName(storage.getStorageShortName());
                tRkWareNoticeTab.setCtl(params.getCtlNo());
                tRkWareNoticeTab.setUpdateTime(new Date());
                updateNoticeTabs.add(tRkWareNoticeTab);
                tRkWareNoticeTabMapper.updateTRkWareNoticeTab(tRkWareNoticeTab);
                // 入库时间
//                DateFormat df = new SimpleDateFormat("yyyy-MM-dd hh:MM:ss");

                // 生成库存信息
                if ("0".equals(params.getFictitious())) {
                    insertTMiStocks.add(makeTMiStock(tRkWareNotice, tRkWareNoticeTab, params));
                } else {
                    insertTMiStockFs.add(makeTMiStockF(tRkWareNotice, tRkWareNoticeTab, params));
                }
            }
        }


        if ("0".equals(params.getFictitious())) {
            // 更新库存信息
            if (insertTMiStocks.size() > 0) {
                for (TMiStock tMiStock1 : insertTMiStocks) {
                    String goodsId = tMiStock1.getGoodsId();
                    LambdaQueryWrapper<TBaseGoods> queryWrapper = new LambdaQueryWrapper<>();
                    queryWrapper.eq(TBaseGoods::getGoodsId, goodsId);
                    TBaseGoods tBaseGoods = goodsMapper.selectOne(queryWrapper);
                    //原来仓库
                    //总价
                    /*BigDecimal shelvesNum = tMiStock1.getShelvesNum();
                    BigDecimal price = tBaseGoods.getPrice();
                    // 设置默认值
                    if (price == null || price.compareTo(BigDecimal.ZERO) == 0) {
                        price = BigDecimal.ZERO; // 默认值为 1
                    }

                    BigDecimal totalPrice = price.multiply(shelvesNum);
                    tMiStock1.setPrice(String.valueOf(price));
                    tMiStock1.setTotalMoney(totalPrice);*/
                    tMiStock1.setOriginal(tBaseGoods.getStorageId());
                    tMiStockMapper.insertTMiStock(tMiStock1);
                }
            }
        } else {
            // 更新虚拟库存信息
            if (insertTMiStockFs.size() > 0) {
                for (TMiStockF tMiStock1 : insertTMiStockFs) {
                    tMiStockFMapper.insertTMiStock(tMiStock1);
                }
            }
        }

        // 更新库位信息 已占用
        String storageLocation = params.getStorageLocation();
        if (StringUtils.isNotBlank(storageLocation)) {
            TBaseStorageAreaLocation tBaseStorageAreaLocation = new TBaseStorageAreaLocation();
            tBaseStorageAreaLocation.setLocationId(storageLocation);
            tBaseStorageAreaLocation.setStatus("1");
            tBaseStorageAreaLocationMapper.updateLocationSts(tBaseStorageAreaLocation);
        }

        // 查询是否存在收货表数据
//        if (updateNoticeTabs.size() > 0) {
//            // 更新入库通知单明细
//            tRkWareNoticeMapper.updateForeach(updateNoticeTabs);
//        }

        // 获取最新的通知单信息，判断是否全部完成
        tRkWareNotice = tRkWareNoticeMapper.selectTRkWareNoticeByNoticeId(params.getNoticeId());



        // 查询存货表数据
        TRkReceivingGoods tRkReceivingGoods = tRkReceivingGoodsMapper
                .selectTRkReceivingGoodsByNoticeId(tRkWareNotice.getNoticeId());

        String trkReceivingGoodsId = OrderCodeFactory.getOrderCode("R", "");
        if (tRkReceivingGoods != null) {
            tRkReceivingGoods.setReceivingStatus(tRkWareNotice.getReceivingStatus());
            tRkReceivingGoods.setUpdateTime(new Date());
            tRkReceivingGoodsMapper.updateTRkReceivingGoods(tRkReceivingGoods);

            trkReceivingGoodsId = tRkReceivingGoods.getId();
        } else {
            TRkReceivingGoods tGoods = new TRkReceivingGoods();
            BeanUtils.copyProperties(tRkWareNotice, tGoods);
            tGoods.setId(trkReceivingGoodsId);
            tGoods.setUpdateTime(new Date());
            tGoods.setCreateTime(new Date());
            tRkReceivingGoodsMapper.insertTRkReceivingGoods(tGoods);
        }

        // 查询是否存在收货表数据
        if (updateNoticeTabs.size() > 0) {

            Map<String, TRkReceivingGoodsTab> trkReceiveGoodsTabMap = new HashMap<String, TRkReceivingGoodsTab>();

            if (tRkReceivingGoods != null) {
                for (TRkReceivingGoodsTab goodsTab : tRkReceivingGoods.getTRkReceivingGoodsTabList()) {
                    trkReceiveGoodsTabMap.put(goodsTab.getSalesOrderNumber() + goodsTab.getGoodsId(), goodsTab);
                }
            }

            List<TRkReceivingGoodsTab> insertGoodsTabs = new ArrayList<>();
            // 存货表更新集合
            List<TRkReceivingGoodsTab> tReceivingGoodsTabs = new ArrayList<TRkReceivingGoodsTab>();

            for (TRkWareNoticeTab noticeTab : updateNoticeTabs) {
                TRkReceivingGoodsTab goodsTab = trkReceiveGoodsTabMap
                        .get(noticeTab.getSalesOrderNumber() + noticeTab.getGoodsId());
                if (goodsTab != null) {
                    goodsTab.setRecNum(noticeTab.getRecNum());
                    goodsTab.setReceivingStatus(noticeTab.getReceivingStatus());
                    goodsTab.setUpdateBy(params.getUserName());
                    goodsTab.setUpdateTime(new Date());
                    tReceivingGoodsTabs.add(goodsTab);
                } else {
                    goodsTab = new TRkReceivingGoodsTab();
                    BeanUtils.copyProperties(noticeTab, goodsTab);
                    goodsTab.setNoticeId(trkReceivingGoodsId);
//                    goodsTab.setId(OrderCodeFactory.getOrderCode("RTAB", ""));
                    insertGoodsTabs.add(goodsTab);
                }
            }

            if (tReceivingGoodsTabs.size() > 0) {
                // 批量更新存货明细表
                tRkReceivingGoodsMapper.updateForeach(tReceivingGoodsTabs);
            }

            if (insertGoodsTabs.size() > 0) {
                tRkReceivingGoodsMapper.batchTRkReceivingGoodsTab(insertGoodsTabs);
            }
        }

        for (TRkWareNoticeTab trkNoticeTab : tRkWareNotice.getTRkWareNoticeTabList()) {
            if (!"2".equals(trkNoticeTab.getReceivingStatus())) {
                allReceive = false;
                break;
            }
        }
        // 入库通知单及明细数据 移到 bak表
        if (allReceive) {
            try {
                // 查询入库通知单明细
//                tRkWareNotice = tRkWareNoticeMapper.selectTRkWareNoticeByNoticeId(tRkWareNotice.getNoticeId());
                TRkWareNoticeBak tRkWareNoticeBak = new TRkWareNoticeBak();
                BeanUtils.copyProperties(tRkWareNotice, tRkWareNoticeBak);
//                String tRkWareNoticeBakId = OrderCodeFactory.getOrderCode("TRKBAK", "");
//                tRkWareNoticeBak.setId(tRkWareNoticeBakId);

                // 插入 t_rk_ware_notice_bak 表的数据
                tRkWareNoticeBak.setReceivingStatus("2");
                tRkWareNoticeBakMapper.insertTRkWareNoticeBak(tRkWareNoticeBak);

                List<TRkWareNoticeTabBak> tRkWareNoticeTabBaks = new ArrayList<>();
                for (TRkWareNoticeTab trWareNoticeTab : tRkWareNotice.getTRkWareNoticeTabList()) {
                    TRkWareNoticeTabBak tRkWareNoticeTabBak = new TRkWareNoticeTabBak();
//                    tRkWareNoticeTabBak.setId(OrderCodeFactory.getOrderCode("TRKTABBAK", ""));
//                    tRkWareNoticeTabBak.setNoticeId(tRkWareNoticeBakId);
                    BeanUtils.copyProperties(trWareNoticeTab, tRkWareNoticeTabBak);
                    tRkWareNoticeTabBak.setPurchaser(tRkWareNotice.getPurchaser());
                    tRkWareNoticeTabBak.setSendeDate(tRkWareNotice.getSendeDate());
                    tRkWareNoticeTabBak.setProviderName(tRkWareNotice.getProviderName());
                    tRkWareNoticeTabBak.setRecPerson(tRkWareNotice.getRecPerson());
                    tRkWareNoticeTabBaks.add(tRkWareNoticeTabBak);
                }

                // 批量插入 t_rk_ware_notice_tab_bak 表的数据
                if (!tRkWareNoticeTabBaks.isEmpty()) {
                    tRkWareNoticeBakMapper.batchTRkWareNoticeTabBak(tRkWareNoticeTabBaks);
                }

                // 删除入库通知单和明细
                tRkWareNoticeMapper.deleteTRkWareNoticeById(tRkWareNotice.getId());
                //单子id 就是明细的 Notice id
                tRkWareNoticeMapper.deleteNoticeTabByNoticeId(tRkWareNotice.getId());

                // 关闭入库通知单任务消息
                TCallNoticeOrder tCallNotice = new TCallNoticeOrder();
                tCallNotice.setTaskId(tRkWareNotice.getId());
                tCallNotice.setTaskType("0");
                tCallNotice.setUpdateBy(params.getUserName());
                tCallNotice.setUpdateTime(new Date());
                tNoticeOrderService.updateTaskStatus(tCallNotice);
            } catch (Exception e) {
                // 记录异常，并抛出运行时异常以触发事务回滚
               e.printStackTrace();
                throw new RuntimeException("处理全部接收失败", e);
            }
        }

        resultMap.put("success", "上架成功");

        return resultMap;
    }


    private TMiStock makeTMiStock(TRkWareNotice notice, TRkWareNoticeTab noticeTab, TRkWareNoticeTabUpdate params) {
        TMiStock tMiStock = new TMiStock();

        // 需求数量 TODO
        // tMiStock.setStoNum();

        tMiStock.setId(OrderCodeFactory.getOrderCode("TMI", ""));

        // 上架数量
        tMiStock.setShelvesNum(noticeTab.getAmount());
        // 中标供应商
        tMiStock.setProviderId(notice.getProviderId());
        // 单位
        tMiStock.setUnit(noticeTab.getUnit());
        // 子需求编号
        tMiStock.setSalesOrderNumber(noticeTab.getSalesOrderNumber());
        // 物料名称
        tMiStock.setGoodsName(noticeTab.getGoodsName());
        // 规格型号
        tMiStock.setSpecification(noticeTab.getSpecification());
        // 物料描述
        tMiStock.setRecoil(noticeTab.getRecoil());
        // 招标员
        tMiStock.setCustomerId(notice.getTenderer());
        tMiStock.setStorageShortName(noticeTab.getStorageShortName());
        // 需求组织
        tMiStock.setOperatorId(notice.getOperatorId());
        // 申请部门
        tMiStock.setSupplier(noticeTab.getSupplier());
        // 创建时间
        tMiStock.setOperateDate(noticeTab.getOperateDate());
        // 上报时间
        // 上报时间
        if (StringUtils.isNotBlank(noticeTab.getReportTime())) {
            tMiStock.setReportTime(noticeTab.getReportTime());
        } else {
            tMiStock.setReportTime(DateUtils.getDate());
        }
        // 申请单号 设置为来源单号 发货单号 TODO
        if (StringUtils.isNotBlank(notice.getDeliveryId())) {
            tMiStock.setLotId(notice.getDeliveryId());
        } else if (StringUtils.isNotBlank(notice.getPurchaseId())) {
            tMiStock.setLotId(notice.getPurchaseId());
        } else if (StringUtils.isNotBlank(noticeTab.getSourceNum())) {
            tMiStock.setLotId(noticeTab.getSourceNum());
        } else {
            tMiStock.setLotId(noticeTab.getPurchaseId());
        }
        // 申请人
        tMiStock.setApplicant(notice.getApplicant());
        // 计划日期
        tMiStock.setPlanDate(noticeTab.getPlanDate());
        // 计划期间
        tMiStock.setPlanTime(noticeTab.getPlanTime());
        // 需求周期
        tMiStock.setNeedCycle(noticeTab.getNeedCycle());
        // 需求类型
        tMiStock.setNeedType(noticeTab.getNeedType());
        // 物料编码
        tMiStock.setGoodsId(noticeTab.getGoodsId());
        // 物料分类
        tMiStock.setGoodsTypeId(noticeTab.getGoodsTypeId());
        // 品牌
        tMiStock.setBrand(noticeTab.getBrand());
        // 计划单价（含税）
        tMiStock.setPrice(noticeTab.getPrice() != null ? noticeTab.getPrice().toString() : null);
        // 计划金额
        tMiStock.setTotalMoney(noticeTab.getTotalMoney());
        // 需求时间
        tMiStock.setExpiryDate(noticeTab.getExpiryDate());
        // 建议供应商名称 TODO
        tMiStock.setProviderName(notice.getProviderName());
        // 收货人
        tMiStock.setReceiver(notice.getReceiver());
        // 需求部门
        tMiStock.setNeedDept(noticeTab.getNeedDept());
        // 采购组织
        tMiStock.setPurchaseDept(notice.getPurchaseDept());
        // 收货组织
        tMiStock.setProduclotId(notice.getProduclotId());
        // 收货人部门
        tMiStock.setReceiverDept(notice.getReceiverDept());
        // 送货区域
        tMiStock.setReceivingArea(notice.getReceivingArea());
        // 技术需求附件
        tMiStock.setPackageId(noticeTab.getPackageId());
        // 物资计划明细备注
        tMiStock.setRemark(noticeTab.getRemark());
        // 用途
        tMiStock.setUseType(noticeTab.getUseType());
        // 中标供应商联系方式
        tMiStock.setTelephone(notice.getTelephone());
        // wms订单号 入库通知单号
        tMiStock.setNoticeId(notice.getId());
        // 生产日期
        tMiStock.setProductionDate(noticeTab.getProductionDate());
        // 入库类型
        tMiStock.setStorageMode(params.getStorageMode());
        // 仓库编号
        tMiStock.setStorageId(noticeTab.getStorageId());
        // 库位
        tMiStock.setLocationId(noticeTab.getStorageLocation());
        // 增加外部批次号
        tMiStock.setBatchNo(noticeTab.getBatchNo());
        // 条码
        tMiStock.setBarcode(noticeTab.getBarcode());
        // 入库级别
        tMiStock.setLevelType(noticeTab.getLevelType());
        // 标准超期呆滞
        tMiStock.setStandard(params.getExtras().get("extraTime"));
        // 托盘
        tMiStock.setCtl(params.getCtlNo());

        tMiStock.setCreateBy(notice.getOperatorId());

        tMiStock.setCreateTime(new Date());
        // 入库时间
        tMiStock.setWareDate(DateUtils.getTime());
        tMiStock.setDeptId(params.getDeptId());
        tMiStock.setNeedPerson(noticeTab.getNeedPerson());
        tMiStock.setNeedTel(noticeTab.getNeedTel());
        tMiStock.setExpiryDate(noticeTab.getExpiryDate());
        tMiStock.setShelvesNum(noticeTab.getAmount());

        tMiStock.setPurchaseId(noticeTab.getPurchaseId());
        tMiStock.setUpdateTime(new Date());
        tMiStock.setOperateDate(new Date());
        return tMiStock;
    }

    /**
     * 编辑库存信息
     *
     * @param notice
     * @param noticeTab
     * @return
     */
    private TMiStockF makeTMiStockF(TRkWareNotice notice, TRkWareNoticeTab noticeTab, TRkWareNoticeTabUpdate params) {
        TMiStockF tMiStock = new TMiStockF();

        // 需求数量 TODO
        // tMiStock.setStoNum();

        tMiStock.setId(OrderCodeFactory.getOrderCode("TMI", ""));

        // 上架数量
        tMiStock.setShelvesNum(noticeTab.getAmount());
        // 中标供应商
        tMiStock.setProviderId(notice.getProviderId());
        // 单位
        tMiStock.setUnit(noticeTab.getUnit());
        // 子需求编号
        tMiStock.setSalesOrderNumber(noticeTab.getSalesOrderNumber());
        // 物料名称
        tMiStock.setGoodsName(noticeTab.getGoodsName());
        // 规格型号
        tMiStock.setSpecification(noticeTab.getSpecification());
        // 物料描述
        tMiStock.setRecoil(noticeTab.getRecoil());
        // 招标员
        tMiStock.setCustomerId(notice.getTenderer());
        // 需求组织
        tMiStock.setOperatorId(notice.getOperatorId());
        // 申请部门
        tMiStock.setSupplier(noticeTab.getSupplier());
        // 创建时间
        tMiStock.setOperateDate(noticeTab.getOperateDate());
        // 上报时间
        tMiStock.setReportTime(noticeTab.getReportTime());
        // 申请单号 设置为来源单号 发货单号 TODO
        tMiStock.setLotId(notice.getPurchaseId());
        // 申请人
        tMiStock.setApplicant(notice.getApplicant());
        // 计划日期
        tMiStock.setPlanDate(noticeTab.getPlanDate());
        // 计划期间
        tMiStock.setPlanTime(noticeTab.getPlanTime());
        // 需求周期
        tMiStock.setNeedCycle(noticeTab.getNeedCycle());
        // 需求类型
        tMiStock.setNeedType(noticeTab.getNeedType());
        // 物料编码
        tMiStock.setGoodsId(noticeTab.getGoodsId());
        // 物料分类
        tMiStock.setGoodsTypeId(noticeTab.getGoodsTypeId());
        // 品牌
        tMiStock.setBrand(noticeTab.getBrand());
        // 计划单价（含税）
        tMiStock.setPrice(noticeTab.getPrice() != null ? noticeTab.getPrice().toString() : null);
        // 计划金额
        tMiStock.setTotalMoney(noticeTab.getTotalMoney());
        // 需求时间
        tMiStock.setExpiryDate(noticeTab.getExpiryDate());
        // 建议供应商名称 TODO
        tMiStock.setProviderName(notice.getProviderName());
        // 收货人
        tMiStock.setReceiver(notice.getReceiver());
        // 需求部门
        tMiStock.setNeedDept(noticeTab.getNeedDept());
        // 采购组织
        tMiStock.setPurchaseDept(notice.getPurchaseDept());
        // 收货组织
        tMiStock.setProduclotId(notice.getProduclotId());
        // 收货人部门
        tMiStock.setReceiverDept(notice.getReceiverDept());
        // 送货区域
        tMiStock.setReceivingArea(notice.getReceivingArea());
        // 技术需求附件
        tMiStock.setPackageId(noticeTab.getPackageId());
        // 物资计划明细备注
        tMiStock.setRemark(noticeTab.getRemark());
        // 用途
        tMiStock.setUseType(noticeTab.getUseType());
        // 中标供应商联系方式
        tMiStock.setTelephone(notice.getTelephone());
        // wms订单号 入库通知单号
        tMiStock.setNoticeId(notice.getNoticeId());
        // 生产日期
        tMiStock.setProductionDate(noticeTab.getProductionDate());
        // 入库类型
        tMiStock.setStorageMode(params.getStorageMode());
        // 仓库编号
        tMiStock.setStorageId(noticeTab.getStorageId());
        // 库位
        tMiStock.setLocationId(noticeTab.getStorageLocation());
        // 增加外部批次号
        tMiStock.setBatchNo(noticeTab.getBatchNo());
        // 条码
        tMiStock.setBarcode(noticeTab.getBarcode());
        // 入库级别
        tMiStock.setLevelType(noticeTab.getLevelType());

        // 标准超期呆滞
        tMiStock.setStandard(params.getExtras().get("extraTime"));

        // 托盘
        tMiStock.setCtl(params.getCtlNo());

        tMiStock.setCreateBy(notice.getOperatorId());
        tMiStock.setCreateTime(new Date());

        // 入库时间
        tMiStock.setWareDate(DateUtils.getTime());

        tMiStock.setDeptId(params.getDeptId());

        tMiStock.setNoticeTabId(noticeTab.getId());

        return tMiStock;
    }


    @Log(title = "出库过账", businessType = BusinessType.OTHER)
    @PostMapping(value = "/accountOutOrder")
    @Transactional
    public AjaxResult accountOutOrder(@RequestBody JSONObject jsonObject) {
        String orderNum = "";
        String orderItem = "";
        TCkOrders ckOrders = null;
        JSONArray dataArray = jsonObject.getJSONArray("data");
        for (int i = 0; i < dataArray.size(); i++) {
            JSONObject item = dataArray.getJSONObject(i);
            //仓位号
            String binCode = item.getStr("binCode");
            //物料编码
            String matCode = item.getStr("matCode");
            //数量
            double matQty = item.getDouble("matQty");
            //单位
            String matUnit = item.getStr("matUnit");
            //明细单号
            orderItem = item.getStr("orderItem");
            //明细子需求编号
            String orderKeyThird = item.getStr("orderKeyThird");
            //通知单号
            orderNum = item.getStr("orderNum");
            //入库类型
            String orderType = item.getStr("orderType");
            // 申请人
            String username = item.getStr("username");
            //仓库
            String whCode = item.getStr("whCode");
            if (whCode.equals("RZ01")) {
                whCode = "FJQR01";
            }
            //容器号
            String traceCode = item.getStr("traceCode");
            // 处理这些数据，例如保存到数据库或进行其他业务逻辑
            //通知单
            ckOrders = tCkOrdersMapper.selectOnes(orderNum);
            List<TCkOrderdetail> list = ckOrders.getTckOrderdetailList();
            //通知单明细
            String finalOrderItem = orderItem;
            TCkOrderdetail ck = list.stream()
                    .filter(c -> {
                        boolean isMatch = c.getId().equals(finalOrderItem);
                        return isMatch;
                    })
                    .findFirst()
                    .orElse(null);  // 如果没有找到，返回 null

            if (ck == null) {
                logger.error("出库明细条数必须大于0");
                return AjaxResult.error("出库明细条数必须大于0");
            }

            //全部出matCode
            TMiStock tMiStock = new TMiStock();
            tMiStock.setGoodsId(ck.getGoodsId());
            tMiStock.setGoodsName(ck.getGoodsName());
            tMiStock.setStorageId(whCode);
            tMiStock.setCtl(traceCode);
            tMiStock.setSalesOrderNumber(ck.getBusinessId());

            /**
             * 正序列出仓库下的该物料列表
             */
            List<TMiStock> tMiStocks = tMiStockMapper.selectTMiStockListByGoodsId(tMiStock);
            if (ck.getShelvesNum().compareTo(BigDecimal.valueOf(matQty)) == 0) {
                logger.info("出库请求解析开始：{}", ck);
                if (tMiStocks.size() == 0) {
                    logger.warn("未找到该物料库存或在冻结中：{}", ck.getGoodsId());
                    return AjaxResult.error("未找到该物料库存或在冻结中： + ck.getGoodsId()");
                }
                if (!"2".equals(ck.getConfirmStatus())) {

                    /*  lock.lock();  // 获取锁*/

                    for (TMiStock stock : tMiStocks) {
                        BigDecimal currentStockQty = stock.getShelvesNum(); // 假设这是库存数量字段
                        BigDecimal newStockQty = currentStockQty.subtract(BigDecimal.valueOf(matQty)); // 减去本次出库数量
                        stock.setShelvesNum(newStockQty); // 设置新的库存数量

                        String goodsId = stock.getGoodsId();


                        LambdaQueryWrapper<TBaseGoods> queryWrapper = new LambdaQueryWrapper<>();
                        queryWrapper.eq(TBaseGoods::getGoodsId, goodsId);
                        TBaseGoods tBaseGoods = goodsMapper.selectOne(queryWrapper);
                        //原来仓库
                        //总价
                        BigDecimal shelvesNum = stock.getShelvesNum();
                        BigDecimal price = tBaseGoods.getPrice();
                        if (price == null || price.compareTo(BigDecimal.ZERO) == 0) {
                            price = BigDecimal.ZERO; // 默认值为 1
                        }
                        BigDecimal totalPrice = price.multiply(shelvesNum);
                        stock.setPrice(String.valueOf(price));
                        stock.setTotalMoney(totalPrice);

                        // 更新库存记录
                        LambdaUpdateWrapper<TMiStock> updateWrapper = new LambdaUpdateWrapper<>();
                        updateWrapper.eq(TMiStock::getId, stock.getId()) // 假设有一个ID字段
                                .set(TMiStock::getShelvesNum, newStockQty)
                                .set(TMiStock::getPrice, price)
                                .set(TMiStock::getTotalMoney, totalPrice);
                        if (newStockQty.compareTo(BigDecimal.ZERO) == 0) {
                            tMiStockMapper.deleteById(stock.getId());
                        } else {
                            tMiStockMapper.update(null, updateWrapper); // 执行更新操作
                        }

                    }
                     /*finally {
                        lock.unlock();  // 释放锁
                    }*/
                    logger.error("出库过账成功");
                    tCkPickingwavegoodsService.sendDevice(ckOrders);
                } else {
                    ckOrders.setConfirmStatus("1");
                    tCkOrdersMapper.updateConfirmStatus(ckOrders);
                }
            } else {
                // 部分出库逻辑
                logger.info("部分出库逻辑解析：{}", ck);
                BigDecimal shelvesNum = ck.getShelvesNum(); // 总数量
                BigDecimal alreadyShippedQty = ck.getGoodsNum(); // 已出库数量
                BigDecimal remainingQty = shelvesNum.subtract(alreadyShippedQty); // 剩余数量

                BigDecimal partQty = BigDecimal.valueOf(matQty); // 本次请求的出库数量

                // 检查本次请求的出库数量是否可以满足
                if (partQty.compareTo(remainingQty) <= 0) {
                    // 可以满足本次出库请求
                    ck.setGoodsNum(alreadyShippedQty.add(partQty)); // 更新已出库数量
                    // 更新库存
                    for (TMiStock stock : tMiStocks) {
                        BigDecimal currentStockQty = stock.getShelvesNum();
                        BigDecimal newStockQty = currentStockQty.subtract(partQty);
                        stock.setShelvesNum(newStockQty);

                        LambdaUpdateWrapper<TMiStock> updateWrapper = new LambdaUpdateWrapper<>();
                        updateWrapper.eq(TMiStock::getId, stock.getId())
                                .set(TMiStock::getShelvesNum, newStockQty);
                        tMiStockMapper.update(null, updateWrapper);
                    }

                    // 更新订单详情
                    LambdaUpdateWrapper<TCkOrderdetail> updateOrderDetailWrapper = new LambdaUpdateWrapper<>();
                    updateOrderDetailWrapper.eq(TCkOrderdetail::getOrderId, ck.getOrderId())
                            .set(TCkOrderdetail::getGoodsNum, ck.getGoodsNum());
                    tCkOrderdetailMapper.update(null, updateOrderDetailWrapper);


                    // 重新获取最新的订单详情
                    TCkOrderdetail updatedCk = tCkOrderdetailMapper.selectById(ck.getId());

                    // 检查是否所有物品都已出库
                    if (updatedCk.getShelvesNum().compareTo(updatedCk.getGoodsNum()) == 0) {
                        // 所有物品都已出库，处理通知单的删除和备份
                        TckOrdersBak tckOrdersBak = new TckOrdersBak();
                        org.springframework.beans.BeanUtils.copyProperties(ckOrders, tckOrdersBak);
                        LambdaQueryWrapper<TCkOrderdetail> queryWrapper1 = new LambdaQueryWrapper<>();
                        queryWrapper1.eq(TCkOrderdetail::getOrderId, ck.getOrderId());
                        List<TCkOrderdetail> detailList = tCkOrderdetailMapper.selectList(queryWrapper1);
                        List<TckOrderdetailBak> bakList = new ArrayList<>();
                        for (TCkOrderdetail tCkOrderdetail1 : detailList) {
                            TckOrderdetailBak tckOrderdetailBak = new TckOrderdetailBak();
                            org.springframework.beans.BeanUtils.copyProperties(tCkOrderdetail1, tckOrderdetailBak);
                            //存储审核人和审核时间
                            tckOrderdetailBak.setAuditDate(ckOrders.getAuditDate());
                            tckOrderdetailBak.setAuditMan(ckOrders.getAuditMan());
                            tckOrderdetailBak.setApplicant(ckOrders.getApplicant());
                            tckOrderdetailBak.setRejectReason(ckOrders.getRejectReason());
                            bakList.add(tckOrderdetailBak);
                        }
                        tckOrdersBak.setTckOrderdetailBakList(bakList);
                        tckOrdersBakService.insertTckOrdersBak(tckOrdersBak);
                        tCkOrdersMapper.deleteTCkOrdersById(ck.getOrderId());
                        tCkOrdersMapper.deleteTCkOrderdetailByOrderId(ck.getOrderId());
                        logger.info("全部出库完成，通知单已删除并备份");
                        return new AjaxResult(0, "部分出库已完成最最大数量,通知单改为bak", null);
                    }
                    // 更新订单状态为部分出库
                    ckOrders.setConfirmStatus("1");
                    BigDecimal newShippedQty = alreadyShippedQty.add(partQty); // 更新已出库数量
                    ck.setGoodsNum(newShippedQty);
                    tCkOrdersMapper.updateConfirmStatus(ckOrders);
                    logger.info("部分出库更新完成");
                    return new AjaxResult(0, "部分出库成功", null);

                } else {
                    // 请求的出库数量大于剩余库存，不能出库
                    logger.warn("请求的出库数量大于剩余库存，无法出库");
                    return new AjaxResult(99, "请求的出库数量大于剩余库存", null);
                }
            }

            //删除通知单
            //根据库位查询是否有库存
            LambdaQueryWrapper<TMiStock> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(TMiStock::getLocationId,binCode);
//        queryWrapper.eq(TMiStock::getCtl,ctl);

            List<TMiStock> tMiStocks0 = tMiStockMapper.selectList(queryWrapper);
            if(tMiStocks0.size() == 0){
                //释放库位
                TBaseStorageAreaLocation baseStorageAreaLocation = new TBaseStorageAreaLocation();
                baseStorageAreaLocation.setLocationId(binCode);
                baseStorageAreaLocation.setStatus("0");
                tBaseStorageAreaLocationMapper.updateLocationSts(baseStorageAreaLocation);
            }
            //校验托盘容器是否正确
            LambdaQueryWrapper<TMiStock> queryWrapper2 = new LambdaQueryWrapper<>();
            queryWrapper2.eq(TMiStock::getCtl,traceCode);
            List<TMiStock> tMiStocks2 = tMiStockMapper.selectList(queryWrapper);
            if(tMiStocks2.size() == 0){
                LambdaQueryWrapper<TBasePallet> ctlWrapper = new LambdaQueryWrapper<>();
                ctlWrapper.eq(TBasePallet::getPalletId, traceCode);
                List<TBasePallet> plcs = basePalletMapper.selectList(ctlWrapper);
                if (!plcs.isEmpty()) {
                    TBasePallet palletChk = plcs.get(0);
                    if("1".equals(palletChk.getStatus())){
                        TBasePallet tBasePallet = new TBasePallet();
                        tBasePallet.setStatus("0");
                        tBasePallet.setId(palletChk.getId());
                        tBasePallet.setUpdateTime(new Date());
                        basePalletMapper.updateTBasePallet(tBasePallet);
                    }
                }
            }

        }


        //删除出库通知单 备份出库通知单
        TckOrdersBak tckOrdersBak = new TckOrdersBak();
        BeanUtils.copyProperties(ckOrders, tckOrdersBak);

        List<TCkOrderdetail> list = ckOrders.getTckOrderdetailList();
        for (TCkOrderdetail ckOrderdetail : list) {
            if (ckOrderdetail.getStorageId().startsWith("FJQR")) {
                ckOrderdetail.setConfirmStatus("2");
                orderdetailMapper.updateTCkOrderdetail(ckOrderdetail);
            }
        }

        //
        List<TckOrderdetailBak> bakList = new ArrayList<>();
        for (TCkOrderdetail ckOrderdetail : list) {
            if (ckOrderdetail.getConfirmStatus().equals("2")) {
                TckOrderdetailBak tckOrderdetailBak = new TckOrderdetailBak();
                org.springframework.beans.BeanUtils.copyProperties(ckOrderdetail, tckOrderdetailBak);
                //存储审核人和审核时间
                tckOrderdetailBak.setAuditDate(ckOrders.getAuditDate());
                tckOrderdetailBak.setAuditMan(ckOrders.getAuditMan());
                tckOrderdetailBak.setApplicant(ckOrders.getApplicant());
                tckOrderdetailBak.setRejectReason(ckOrders.getRejectReason());
                bakList.add(tckOrderdetailBak);
                tCkOrderdetailMapper.deleteById(orderItem);
            }
        }
        if (bakList.size() == list.size()) {
            tckOrdersBak.setTckOrderdetailBakList(bakList);
            tckOrdersBakService.insertTckOrdersBak(tckOrdersBak);
            tCkOrdersMapper.deleteTCkOrdersById(orderNum);
        }
        return new AjaxResult(0, "出库过账成功", null);
    }


    @Log(title = "库位查询", businessType = BusinessType.OTHER)
    @Transactional(rollbackFor = Exception.class)
    @GetMapping("/stocks")
    public AjaxResult getStocks(@RequestParam String whCode, @RequestParam(required = false) String ownerCode, @RequestParam(required = false) String matCode, @RequestParam(required = false) String batchNum, @RequestParam(required = false) String podCode, @RequestParam(required = false) String binCode, @RequestParam(required = false) Integer pageNum, @RequestParam(required = false) Integer pageSize, @RequestParam String type) {
        List<DataItem> dataItems = null;
        if (type.equals("0") || type.equals("1")) {

            String ip = "http://172.18.29.101/wms/api/RestJsonService/getStocks";
            ObjectMapper objectMapper = new ObjectMapper();

            // Build request body
            Map<String, Object> requestMap = new HashMap<>();
            requestMap.put("reqCode", "T" + System.currentTimeMillis());

            Map<String, Object> data = new HashMap<>();
            data.put("whCode", "RZ01");
            data.put("ownerCode", ownerCode != null ? ownerCode : "");
            data.put("matCode", matCode != null ? matCode : "");
            data.put("batchNum", batchNum != null ? batchNum : "");
            data.put("podCode", podCode != null ? podCode : "");
            data.put("binCode", binCode != null ? binCode : "");
            if(pageNum == null || pageSize == null) {
                pageNum = 1;
                pageSize = 1000;
            }
            data.put("pageNum", pageNum);
            data.put("pageSize", pageSize);

            requestMap.put("data", data);

            // Set request headers
            Map<String, String> headers = new HashMap<>();
            headers.put("Content-Type", "application/json;charset=UTF-8");

            // Create request entity
            String jsonString = null;
            try {
                objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
                jsonString = objectMapper.writeValueAsString(requestMap);
            } catch (JsonProcessingException e) {
                throw new RuntimeException(e);
            }

            JSONObject result = HttpUtils.post(ip, jsonString, headers);
            List<Object> data1 = (List<Object>) result.get("data");
             dataItems = new ArrayList<>();


            // Convert data1 to DataItem objects
            for (Object obj : data1) {
                if (obj instanceof Map) {
                    Map<String, Object> map = (Map<String, Object>) obj;
                    DataItem dataItem = objectMapper.convertValue(map, DataItem.class);
                    dataItems.add(dataItem);
                }
            }

            // If type is 0, also add data from TBaseGoods
            if (type.equals("0")) {
                List<TBaseGoods> list = tBaseGoodsMapper.selectTBaseGoodsList(new TBaseGoods());
                for (TBaseGoods tBaseGoods : list) {
                    for (DataItem dataItem : dataItems) {
                        if (tBaseGoods.getGoodsId().equals(dataItem.getMatCode())) {
                            dataItem.setContainerCode(tBaseGoods.getGoodsTid());
                        }
                    }
                }
            }
            //去重
            List<DataItem> distinctDataItems = dataItems.stream()
                    .filter(Objects::nonNull) // 过滤掉 null 值
                    .filter(item -> !item.getContainerCode().startsWith("A2F")) // 过滤掉以 A2FB 开头的项
                    .collect(Collectors.toMap(DataItem::getContainerCode, item -> item, (existing, replacement) -> existing))
                    .values()
                    .stream()
                    .collect(Collectors.toList());

            return AjaxResult.success(distinctDataItems);
        } else if (type.equals("2")) {
            List<TBaseGoods> list = tBaseGoodsMapper.selectTBaseGoodsList(new TBaseGoods());
            for (TBaseGoods tBaseGoods : list) {
                for (DataItem dataItem : dataItems) {
                    if (tBaseGoods.getGoodsId().equals(dataItem.getMatCode())) {
                        dataItem.setContainerCode(tBaseGoods.getGoodsEpc());
                    }
                }
            }
            //去重
            List<DataItem> distinctDataItems = dataItems.stream()
                    .filter(Objects::nonNull) // 过滤掉 null 值
                    .filter(item -> !item.getContainerCode().startsWith("A2F")) // 过滤掉以 A2FB 开头的项
                    .collect(Collectors.toMap(DataItem::getContainerCode, item -> item, (existing, replacement) -> existing))
                    .values()
                    .stream()
                    .collect(Collectors.toList());
            return AjaxResult.success(distinctDataItems);
        } else if (type.equals("3")) {
            //请求海康
            String ip = "http://172.18.29.101/wms/api/RestJsonService/getStocks";
            ObjectMapper objectMapper = new ObjectMapper();

            // Build request body
            Map<String, Object> requestMap = new HashMap<>();
            requestMap.put("reqCode", "T" + System.currentTimeMillis());

            Map<String, Object> data = new HashMap<>();
            data.put("whCode", "RZ01");
            data.put("ownerCode", ownerCode != null ? ownerCode : "");
            data.put("matCode", matCode != null ? matCode : "");
            data.put("batchNum", batchNum != null ? batchNum : "");
            data.put("podCode", podCode != null ? podCode : "");
            data.put("binCode", binCode != null ? binCode : "");
            data.put("pageNum", 1);
            data.put("pageSize", 1000);
            requestMap.put("data", data);
            Map<String, String> headers = new HashMap<>();
            headers.put("Content-Type", "application/json;charset=UTF-8");
            String jsonString = null;
            try {
                objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
                jsonString = objectMapper.writeValueAsString(requestMap);
            } catch (JsonProcessingException e) {
                throw new RuntimeException(e);
            }
            JSONObject result = HttpUtils.post(ip, jsonString, headers);
            List<Object> data1 = (List<Object>) result.get("data");
            List<DataItem> dataItem = new ArrayList<>();
            for (Object obj : data1) {
                if (obj instanceof Map) {
                    Map<String, Object> map = (Map<String, Object>) obj;
                    DataItem item = objectMapper.convertValue(map, DataItem.class);
                    dataItem.add(item);
                }
            }
            //推送盘点
            String url = "http://172.22.28.156:8090/api/v2/inventory/container";
            List<TBaseGoods> list = tBaseGoodsMapper.selectTBaseGoodsList(new TBaseGoods());
            for (TBaseGoods tBaseGoods : list) {
                for (DataItem item : dataItem) {
                    if (tBaseGoods.getGoodsId().equals(item.getMatCode())) {
                        item.setContainerCode(tBaseGoods.getGoodsEpc());
                    }
                }

            }
            Map<String, Object> requestBody = new HashMap<>();
            requestBody.put("data", dataItem);
            requestMap.put("code", 200);
            requestMap.put("msg", "操作成功");
            try {
                String jsonBody = objectMapper.writeValueAsString(requestBody);
                logger.info("盘点推送数据:{}",jsonBody);
                JSONObject results = HttpUtils.post(url, jsonBody, headers);

                // 检查返回的 JSON 对象
                if (results != null && "succ".equals(results.getStr("msg")) && results.getInt("result") == 0) {
                    return AjaxResult.success("数据推送成功", results);
                } else {
                    return AjaxResult.error("推送失败，未收到有效响应或返回值不正确");
                }
            } catch (Exception e) {
                return AjaxResult.error("推送过程中发生错误: " + e.getMessage());
            }
        }

        return AjaxResult.error("有问题");
    }


    @PostMapping("/sendMqtt")
    public Boolean sendGoMessage(@RequestBody Types types) {
        String method = "go";
        Object[] params = new Object[]{types.getCheckType()};
        String id = "sdrz.go";
        return mqttMessageSender.sendMessage(method, params, id);
    }


}





