liyong
5 小时以前 1cf91e355038837f30f2d727507b2229263d7de7
src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java
@@ -16,6 +16,7 @@
import com.ruoyi.basic.pojo.SupplierManage;
import com.ruoyi.collaborativeApproval.mapper.NoticeMapper;
import com.ruoyi.collaborativeApproval.pojo.Notice;
import com.ruoyi.common.enums.ApproveTypeEnum;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.device.mapper.DeviceRepairMapper;
import com.ruoyi.device.pojo.DeviceRepair;
@@ -32,9 +33,11 @@
import com.ruoyi.production.mapper.ProductWorkOrderMapper;
import com.ruoyi.production.pojo.ProductWorkOrder;
import com.ruoyi.project.system.domain.SysDept;
import com.ruoyi.project.system.domain.SysUser;
import com.ruoyi.project.system.domain.SysUserDept;
import com.ruoyi.project.system.mapper.SysDeptMapper;
import com.ruoyi.project.system.mapper.SysUserDeptMapper;
import com.ruoyi.project.system.mapper.SysUserMapper;
import com.ruoyi.purchase.mapper.PaymentRegistrationMapper;
import com.ruoyi.purchase.mapper.PurchaseLedgerMapper;
import com.ruoyi.purchase.pojo.PaymentRegistration;
@@ -44,8 +47,6 @@
import com.ruoyi.sales.mapper.ReceiptPaymentMapper;
import com.ruoyi.sales.mapper.SalesLedgerMapper;
import com.ruoyi.sales.mapper.SalesLedgerProductMapper;
import com.ruoyi.project.system.domain.SysUser;
import com.ruoyi.project.system.mapper.SysUserMapper;
import com.ruoyi.sales.pojo.ReceiptPayment;
import com.ruoyi.sales.pojo.SalesLedger;
import com.ruoyi.sales.pojo.SalesLedgerProduct;
@@ -399,6 +400,12 @@
        if (CollectionUtils.isEmpty(approveProcesses)) {
            approveProcesses = new ArrayList<>();
        }
        approveProcesses.forEach(a -> {
            if (a.getApproveType() != null) {
                a.setApproveTypeName(ApproveTypeEnum.getNameByCode(a.getApproveType()));
            }
        });
//        // 查询未领用劳保记录
//        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
//
@@ -416,6 +423,8 @@
//                approveProcesses.add(approveProcess);
//            }
//        }
        return approveProcesses;
    }
@@ -695,15 +704,15 @@
        LocalDate startDate;
        LocalDate endDate;
        switch (type) {
            case 0: // 周
            case 1: // 周
                startDate = today.with(DayOfWeek.MONDAY);
                endDate = today.with(DayOfWeek.SUNDAY);
                break;
            case 1: // 月
            case 2: // 月
                startDate = today.with(TemporalAdjusters.firstDayOfMonth());
                endDate = today.with(TemporalAdjusters.lastDayOfMonth());
                break;
            case 2: // 季度
            case 3: // 季度
                Month currentMonth = today.getMonth();
                Month firstMonthOfQuarter = currentMonth.firstMonthOfQuarter();
                Month lastMonthOfQuarter = Month.of(firstMonthOfQuarter.getValue() + 2);
@@ -745,15 +754,15 @@
        boolean groupByMonth = false;
        switch (type) {
            case 0: // 周
            case 1: // 周
                start = today.with(DayOfWeek.MONDAY);
                end = today.with(DayOfWeek.SUNDAY);
                break;
            case 1: // 月
            case 2: // 月
                start = today.with(TemporalAdjusters.firstDayOfMonth());
                end = today.with(TemporalAdjusters.lastDayOfMonth());
                break;
            case 2: // 季度
            case 3: // 季度
                Month firstMonthOfQuarter = today.getMonth().firstMonthOfQuarter();
                start = today.withMonth(firstMonthOfQuarter.getValue()).with(TemporalAdjusters.firstDayOfMonth());
                end = today.withMonth(firstMonthOfQuarter.plus(2).getValue()).with(TemporalAdjusters.lastDayOfMonth());
@@ -814,109 +823,54 @@
        ProductCategoryDistributionDto dto = new ProductCategoryDistributionDto();
        List<ProductCategoryDistributionDto.MajorCategoryDto> majorItems = new ArrayList<>();
        //  所有的产品大类和小类
        List<Product> allProducts = productMapper.selectList(new LambdaQueryWrapper<Product>());
        // 查询所有的产品类别
        List<Product> allProducts = productMapper.selectList(new LambdaQueryWrapper<>());
        if (CollectionUtils.isEmpty(allProducts)) {
            dto.setItems(majorItems);
            return dto;
        }
        List<Product> majorCategories = allProducts.stream().filter(p -> p.getParentId() == null).collect(Collectors.toList());
        List<Product> minorCategories = allProducts.stream().filter(p -> p.getParentId() != null).collect(Collectors.toList());
        // 分离大类和小类
        List<Product> majorCategories = allProducts.stream()
                .filter(p -> p.getParentId() == null)
                .collect(Collectors.toList());
        List<Product> minorCategories = allProducts.stream()
                .filter(p -> p.getParentId() != null)
                .collect(Collectors.toList());
        //  从 sales_ledger_product 拿到每个产品的型号库存
        // 需包含规格型号以支持三级分布
        List<Map<String, Object>> quantityMaps = salesLedgerProductMapper.selectMaps(new QueryWrapper<SalesLedgerProduct>()
                .select("product_id", "specification_model", "type", "SUM(quantity) as sum_qty")
                .isNotNull("product_id")
                .groupBy("product_id", "specification_model", "type"));
        // 按父类ID对小类进行分组
        Map<Long, List<Product>> minorGroupMap = minorCategories.stream()
                .collect(Collectors.groupingBy(Product::getParentId));
        Map<Long, Map<String, Map<Integer, BigDecimal>>> modelStockGroups = new HashMap<>();
        for (Map<String, Object> map : quantityMaps) {
            Long productId = Long.parseLong(map.get("product_id").toString());
            String model = map.get("specification_model") != null ? map.get("specification_model").toString() : "未知型号";
            Integer type = Integer.parseInt(map.get("type").toString());
            BigDecimal sum = map.get("sum_qty") != null ? new BigDecimal(map.get("sum_qty").toString()) : BigDecimal.ZERO;
        int totalMinorCount = minorCategories.size();
            modelStockGroups.computeIfAbsent(productId, k -> new HashMap<>())
                    .computeIfAbsent(model, k -> new HashMap<>())
                    .put(type, sum);
        }
        //  库存并汇总
        Map<Long, List<MapDto>> productModelsMap = new HashMap<>();
        Map<Long, BigDecimal> productTotalStockMap = new HashMap<>();
        for (Long pid : modelStockGroups.keySet()) {
            Map<String, Map<Integer, BigDecimal>> models = modelStockGroups.get(pid);
            BigDecimal productStock = BigDecimal.ZERO;
            List<MapDto> modelDtos = new ArrayList<>();
            for (String modelName : models.keySet()) {
                Map<Integer, BigDecimal> types = models.get(modelName);
                BigDecimal procurement = types.getOrDefault(2, BigDecimal.ZERO);
                BigDecimal sales = types.getOrDefault(1, BigDecimal.ZERO);
                BigDecimal stock = procurement.subtract(sales);
                if (stock.compareTo(BigDecimal.ZERO) < 0) stock = BigDecimal.ZERO;
                MapDto modelDto = new MapDto();
                modelDto.setName(modelName);
                modelDto.setValue(stock.stripTrailingZeros().toPlainString());
                modelDtos.add(modelDto);
                productStock = productStock.add(stock);
            }
            productModelsMap.put(pid, modelDtos);
            productTotalStockMap.put(pid, productStock);
        }
        BigDecimal totalInventory = productTotalStockMap.values().stream().reduce(BigDecimal.ZERO, BigDecimal::add);
        //  型号占比
        if (totalInventory.compareTo(BigDecimal.ZERO) > 0) {
            for (List<MapDto> dtos : productModelsMap.values()) {
                for (MapDto m : dtos) {
                    BigDecimal val = new BigDecimal(m.getValue());
                    m.setRate(val.multiply(new BigDecimal("100"))
                            .divide(totalInventory, 2, RoundingMode.HALF_UP).toString());
                }
            }
        }
        //  分层数据
        for (Product major : majorCategories) {
            ProductCategoryDistributionDto.MajorCategoryDto majorDto = new ProductCategoryDistributionDto.MajorCategoryDto();
            majorDto.setName(major.getProductName());
            List<ProductCategoryDistributionDto.MinorCategoryDto> minorDtos = new ArrayList<>();
            BigDecimal majorStock = BigDecimal.ZERO;
            List<Product> children = minorGroupMap.getOrDefault(major.getId(), new ArrayList<>());
            int childrenSize = children.size();
            // 设置小类的总数
            majorDto.setValue(String.valueOf(childrenSize));
            for (Product minor : minorCategories) {
                if (major.getId().equals(minor.getParentId())) {
                    BigDecimal stock = productTotalStockMap.getOrDefault(minor.getId(), BigDecimal.ZERO);
                    ProductCategoryDistributionDto.MinorCategoryDto minorDto = new ProductCategoryDistributionDto.MinorCategoryDto();
                    minorDto.setName(minor.getProductName());
                    minorDto.setValue(stock.stripTrailingZeros().toPlainString());
                    if (totalInventory.compareTo(BigDecimal.ZERO) > 0) {
                        minorDto.setRate(stock.multiply(new BigDecimal("100"))
                                .divide(totalInventory, 2, RoundingMode.HALF_UP).toString());
                    } else {
                        minorDto.setRate("0.00");
                    }
                    minorDto.setChildren(productModelsMap.getOrDefault(minor.getId(), new ArrayList<>()));
                    minorDtos.add(minorDto);
                    majorStock = majorStock.add(stock);
                }
            }
            majorDto.setValue(majorStock.stripTrailingZeros().toPlainString());
            if (totalInventory.compareTo(BigDecimal.ZERO) > 0) {
                majorDto.setRate(majorStock.multiply(new BigDecimal("100"))
                        .divide(totalInventory, 2, RoundingMode.HALF_UP).toString());
            // 计算占比
            if (totalMinorCount > 0) {
                BigDecimal rate = BigDecimal.valueOf(childrenSize)
                        .multiply(new BigDecimal("100"))
                        .divide(BigDecimal.valueOf(totalMinorCount), 2, RoundingMode.HALF_UP);
                majorDto.setRate(rate.toString());
            } else {
                majorDto.setRate("0.00");
            }
            List<ProductCategoryDistributionDto.MinorCategoryDto> minorDtos = new ArrayList<>();
            for (Product minor : children) {
                ProductCategoryDistributionDto.MinorCategoryDto minorDto = new ProductCategoryDistributionDto.MinorCategoryDto();
                minorDto.setName(minor.getProductName());
                minorDto.setValue("0");
                minorDto.setRate("0.00");
                minorDto.setChildren(new ArrayList<>());
                minorDtos.add(minorDto);
            }
            majorDto.setChildren(minorDtos);
            majorItems.add(majorDto);
@@ -932,15 +886,15 @@
        LocalDate startDate = null;
        LocalDate endDate = null;
        switch (type) {
            case 0:
            case 1:
                startDate = today.with(DayOfWeek.MONDAY);
                endDate = today.with(DayOfWeek.SUNDAY);
                break;
            case 1:
            case 2:
                startDate = today.with(TemporalAdjusters.firstDayOfMonth());
                endDate = today.with(TemporalAdjusters.lastDayOfMonth());
                break;
            case 2:
            case 3:
                Month currentMonth = today.getMonth();
                Month firstMonthOfQuarter = currentMonth.firstMonthOfQuarter();
                Month lastMonthOfQuarter = Month.of(firstMonthOfQuarter.getValue() + 2);