gongchunyi
昨天 b504b19b0881a7c1bd9e280ba41e993956b7f94e
feat: 进销存生产分析大屏
已添加2个文件
已修改13个文件
718 ■■■■■ 文件已修改
src/main/java/com/ruoyi/home/controller/HomeController.java 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/home/dto/InputOutputAnalysisDto.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/home/dto/WorkOrderEfficiencyDto.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/home/service/HomeService.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java 533 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/mapper/ProductOrderMapper.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/mapper/ProductWorkOrderMapper.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/mapper/ProductionProductInputMapper.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/mapper/ProductionProductOutputMapper.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/mapper/SalesLedgerProductionAccountingMapper.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/production/ProductOrderMapper.xml 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/production/ProductWorkOrderMapper.xml 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/production/ProductionProductInputMapper.xml 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/production/ProductionProductOutputMapper.xml 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/production/SalesLedgerProductionAccountingMapper.xml 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/home/controller/HomeController.java
@@ -166,6 +166,41 @@
        MonthlyExpenditureDto dto = homeService.monthlyExpenditure();
        return AjaxResult.success(dto);
   }
    @GetMapping("/inputOutputAnalysis")
    @ApiOperation("投入产出分析")
    public AjaxResult inputOutputAnalysis(@RequestParam(value = "type", defaultValue = "1") Integer type){
      List<InputOutputAnalysisDto> list = homeService.inputOutputAnalysis(type);
        return AjaxResult.success(list);
    }
    @GetMapping("/processOutputAnalysis")
    @ApiOperation("工序产出分析")
    public AjaxResult processOutputAnalysis(@RequestParam(value = "type", defaultValue = "1") Integer type){
        List<MapDto> list = homeService.processOutputAnalysis(type);
        return AjaxResult.success(list);
    }
    @GetMapping("/workOrderEfficiencyAnalysis")
    @ApiOperation("工单执行效率分析")
    public AjaxResult workOrderEfficiencyAnalysis(@RequestParam(value = "type", defaultValue = "1") Integer type){
        List<WorkOrderEfficiencyDto> list = homeService.workOrderEfficiencyAnalysis(type);
        return AjaxResult.success(list);
    }
    @GetMapping("/productionAccountingAnalysis")
    @ApiOperation("生产核算分析")
    public AjaxResult productionAccountingAnalysis(@RequestParam(value = "type", defaultValue = "1") Integer type){
        List<MapDto> list = homeService.productionAccountingAnalysis(type);
        return AjaxResult.success(list);
    }
    @GetMapping("/orderCount")
    @ApiOperation("订单数")
    public AjaxResult orderCount(){
        return AjaxResult.success(homeService.orderCount());
    }
    /********************************************************营销采购类**************************************************/
    @GetMapping("/business")
src/main/java/com/ruoyi/home/dto/InputOutputAnalysisDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,16 @@
package com.ruoyi.home.dto;
import lombok.Data;
import java.math.BigDecimal;
@Data
public class InputOutputAnalysisDto {
    private String date;
    private BigDecimal inputSum;
    private BigDecimal outputSum;
}
src/main/java/com/ruoyi/home/dto/WorkOrderEfficiencyDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,24 @@
package com.ruoyi.home.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
@Data
@ApiModel("工单执行效率分析Dto")
public class WorkOrderEfficiencyDto {
    @ApiModelProperty(value = "日期")
    private String date;
    @ApiModelProperty(value = "开工数量")
    private BigDecimal startQuantity;
    @ApiModelProperty(value = "完工数量")
    private BigDecimal finishQuantity;
    @ApiModelProperty(value = "良品率")
    private String yieldRate;
}
src/main/java/com/ruoyi/home/service/HomeService.java
@@ -64,4 +64,14 @@
    MonthlyIncomeDto monthlyIncome();
    MonthlyExpenditureDto monthlyExpenditure();
    List<InputOutputAnalysisDto> inputOutputAnalysis(Integer type);
    List<MapDto> processOutputAnalysis(Integer type);
    List<WorkOrderEfficiencyDto> workOrderEfficiencyAnalysis(Integer type);
    List<MapDto> productionAccountingAnalysis(Integer type);
    List<MapDto> orderCount();
}
src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java
@@ -33,6 +33,8 @@
import com.ruoyi.production.dto.ProductWorkOrderDto;
import com.ruoyi.production.mapper.ProductOrderMapper;
import com.ruoyi.production.mapper.ProductWorkOrderMapper;
import com.ruoyi.production.mapper.ProductionProductInputMapper;
import com.ruoyi.production.mapper.ProductionProductOutputMapper;
import com.ruoyi.production.pojo.ProductWorkOrder;
import com.ruoyi.project.system.domain.SysDept;
import com.ruoyi.project.system.domain.SysUser;
@@ -134,6 +136,9 @@
    @Autowired
    private HomeMapper homeMapper;
    @Autowired
    private ProductionProductOutputMapper productionProductOutputMapper;
    @Override
    public HomeBusinessDto business() {
        // æž„建结果
@@ -152,8 +157,10 @@
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            LambdaQueryWrapper<SalesLedgerProduct> salesLedgerProductMapperLambdaQueryWrapper = new LambdaQueryWrapper<SalesLedgerProduct>();
            salesLedgerProductMapperLambdaQueryWrapper.eq(SalesLedgerProduct::getType, 1)
                    .in(SalesLedgerProduct::getSalesLedgerId, salesLedgers.stream().map(SalesLedger::getId).collect(Collectors.toList()));
            List<SalesLedgerProduct> salesLedgerProducts = salesLedgerProductMapper.selectList(salesLedgerProductMapperLambdaQueryWrapper);
                    .in(SalesLedgerProduct::getSalesLedgerId,
                            salesLedgers.stream().map(SalesLedger::getId).collect(Collectors.toList()));
            List<SalesLedgerProduct> salesLedgerProducts = salesLedgerProductMapper
                    .selectList(salesLedgerProductMapperLambdaQueryWrapper);
            // æœªå¼€ç¥¨é‡‘额
            BigDecimal noInvoiceAmountTotal = salesLedgerProducts.stream().map(SalesLedgerProduct::getNoInvoiceAmount)
                    .filter(Objects::nonNull)
@@ -170,8 +177,10 @@
        if (!CollectionUtils.isEmpty(purchaseLedgers)) {
            LambdaQueryWrapper<SalesLedgerProduct> salesLedgerProductMapperLambdaQueryWrapperCopy = new LambdaQueryWrapper<SalesLedgerProduct>();
            salesLedgerProductMapperLambdaQueryWrapperCopy.eq(SalesLedgerProduct::getType, 2)
                    .in(SalesLedgerProduct::getSalesLedgerId, purchaseLedgers.stream().map(PurchaseLedger::getId).collect(Collectors.toList()));
            List<SalesLedgerProduct> salesLedgerProductsCopy = salesLedgerProductMapper.selectList(salesLedgerProductMapperLambdaQueryWrapperCopy);
                    .in(SalesLedgerProduct::getSalesLedgerId,
                            purchaseLedgers.stream().map(PurchaseLedger::getId).collect(Collectors.toList()));
            List<SalesLedgerProduct> salesLedgerProductsCopy = salesLedgerProductMapper
                    .selectList(salesLedgerProductMapperLambdaQueryWrapperCopy);
            // åˆè®¡åˆåŒé‡‘额
            BigDecimal receiveAmount = purchaseLedgers.stream()
                    .map(PurchaseLedger::getContractAmount)
@@ -183,12 +192,12 @@
                    .filter(Objects::nonNull)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            homeBusinessDto.setMonthPurchaseMoney(receiveAmount.setScale(2, RoundingMode.HALF_UP).toString());
            homeBusinessDto.setMonthPurchaseHaveMoney(unReceiptPaymentAmount.setScale(2, RoundingMode.HALF_UP).toString());
            homeBusinessDto
                    .setMonthPurchaseHaveMoney(unReceiptPaymentAmount.setScale(2, RoundingMode.HALF_UP).toString());
        }
        // ç»Ÿè®¡åº“å­˜
        BigDecimal stockQuantityTotal = stockInventoryMapper.selectTotal();
        homeBusinessDto.setInventoryNum(stockQuantityTotal.setScale(2, RoundingMode.HALF_UP).toString());
        // èŽ·å–å½“å¤©å…¥åº“æ•°é‡
        BigDecimal bigDecimal = stockInventoryMapper.selectTotalByDate(LocalDate.now());
@@ -233,7 +242,8 @@
        if (subtract.compareTo(BigDecimal.ZERO) == 0 || lastYearWeekContractAmount.compareTo(BigDecimal.ZERO) == 0) {
            weekYny = "0.00";
        } else {
            weekYny = String.format("%.2f", subtract.divide(lastYearWeekContractAmount, 2, RoundingMode.HALF_UP).multiply(new BigDecimal("100")));
            weekYny = String.format("%.2f", subtract.divide(lastYearWeekContractAmount, 2, RoundingMode.HALF_UP)
                    .multiply(new BigDecimal("100")));
        }
@@ -252,15 +262,18 @@
        BigDecimal lastYearYesterdayContractAmount = salesLedgers4.stream().map(SalesLedger::getContractAmount)
                .filter(Objects::nonNull)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        BigDecimal subtract1 = todayContractAmount.subtract(lastYearYesterdayContractAmount); // ä¿®æ”¹ï¼šä½¿ç”¨ todayContractAmount è€Œä¸æ˜¯ yesterdayContractAmount
        BigDecimal subtract1 = todayContractAmount.subtract(lastYearYesterdayContractAmount); // ä¿®æ”¹ï¼šä½¿ç”¨
                                                                                              // todayContractAmount è€Œä¸æ˜¯
                                                                                              // yesterdayContractAmount
        // æ—¥çŽ¯æ¯”
        String chain = "";
        if (subtract1.compareTo(BigDecimal.ZERO) == 0 || lastYearYesterdayContractAmount.compareTo(BigDecimal.ZERO) == 0) {
        if (subtract1.compareTo(BigDecimal.ZERO) == 0
                || lastYearYesterdayContractAmount.compareTo(BigDecimal.ZERO) == 0) {
            chain = "0.00";
        } else {
            chain = String.format("%.2f", subtract1.divide(lastYearYesterdayContractAmount, 2, RoundingMode.HALF_UP).multiply(new BigDecimal("100")));
            chain = String.format("%.2f", subtract1.divide(lastYearYesterdayContractAmount, 2, RoundingMode.HALF_UP)
                    .multiply(new BigDecimal("100")));
        }
        AnalysisCustomerContractAmountsDto analysisCustomerContractAmountsDto = new AnalysisCustomerContractAmountsDto();
        // ä¿®æ”¹ï¼šå°†åˆåŒé‡‘额保留两位小数
@@ -268,7 +281,8 @@
        analysisCustomerContractAmountsDto.setYny(weekYny);
        analysisCustomerContractAmountsDto.setChain(chain);
        Map<String, BigDecimal> collect = salesLedgers.stream().collect(Collectors.groupingBy(SalesLedger::getCustomerName, Collectors.reducing(BigDecimal.ZERO,
        Map<String, BigDecimal> collect = salesLedgers.stream()
                .collect(Collectors.groupingBy(SalesLedger::getCustomerName, Collectors.reducing(BigDecimal.ZERO,
                SalesLedger::getContractAmount, BigDecimal::add)));
        List<MapDto> mapDtos = new ArrayList<>();
        collect.forEach((k, v) -> {
@@ -279,14 +293,14 @@
            if (contractAmount.compareTo(new BigDecimal(0)) == 0) {
                mapDto.setRate("0");
            } else {
                mapDto.setRate(String.format("%.2f", v.divide(contractAmount, 2, RoundingMode.HALF_UP).multiply(new BigDecimal("100"))));
                mapDto.setRate(String.format("%.2f",
                        v.divide(contractAmount, 2, RoundingMode.HALF_UP).multiply(new BigDecimal("100"))));
            }
            mapDtos.add(mapDto);
        });
        analysisCustomerContractAmountsDto.setItem(mapDtos);
        return analysisCustomerContractAmountsDto;
    }
    @Override
    public QualityStatisticsDto qualityStatistics() {
@@ -394,18 +408,19 @@
//        LaborIssue laborIssue1 = new LaborIssue();
//        laborIssue1.setAdoptedDate(new Date());
//        laborIssue1.setIssueDate(sdf.parse(sdf.format(new Date())));
//        List<LaborIssue> laborIssues = lavorIssueMapper.list(laborIssue1);  //staff_join_leave_record表被删除
        // List<LaborIssue> laborIssues = lavorIssueMapper.list(laborIssue1);
        // //staff_join_leave_record表被删除
//        if(!CollectionUtils.isEmpty(laborIssues)){
//            for (LaborIssue laborIssue : laborIssues) {
//                ApproveProcess approveProcess = new ApproveProcess();
//                approveProcess.setApproveId(laborIssue.getOrderNo());
//                approveProcess.setApproveDeptName(sysDeptMapper.selectDeptById(loginUser.getTenantId()).getDeptName());
//                approveProcess.setApproveTime(laborIssue.getIssueDate());
//                approveProcess.setApproveReason(laborIssue.getDictTypeName() + "-" + laborIssue.getDictName() + "超时未领取");
        // approveProcess.setApproveReason(laborIssue.getDictTypeName() + "-" +
        // laborIssue.getDictName() + "超时未领取");
//                approveProcesses.add(approveProcess);
//            }
//        }
        return approveProcesses;
    }
@@ -446,28 +461,38 @@
//                .ge(SalesLedger::getEntryDate, startDate)
//                .lt(SalesLedger::getEntryDate, endDate)
        );
//        BigDecimal receivableMoney = salesLedgers.stream().map(SalesLedger::getContractAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
        // BigDecimal receivableMoney =
        // salesLedgers.stream().map(SalesLedger::getContractAmount).reduce(BigDecimal.ZERO,
        // BigDecimal::add);
        BigDecimal receivableMoney = sumAmount(salesLedgers, SalesLedger::getContractAmount);
        // åº”付
        List<PurchaseLedger> procurementRecords = purchaseLedgerMapper.selectList(new LambdaQueryWrapper<PurchaseLedger>()
        List<PurchaseLedger> procurementRecords = purchaseLedgerMapper
                .selectList(new LambdaQueryWrapper<PurchaseLedger>()
//                .ge(PurchaseLedger::getEntryDate, startDate)
//                .lt(PurchaseLedger::getEntryDate, endDate)
        );
//        BigDecimal payableMoney = procurementRecords.stream().map(PurchaseLedger::getContractAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
        // BigDecimal payableMoney =
        // procurementRecords.stream().map(PurchaseLedger::getContractAmount).reduce(BigDecimal.ZERO,
        // BigDecimal::add);
        BigDecimal payableMoney = sumAmount(procurementRecords, PurchaseLedger::getContractAmount);
        // é¢„æ”¶
        List<ReceiptPayment> receiptPayments = receiptPaymentMapper.selectList(new LambdaQueryWrapper<ReceiptPayment>()
//                .ge(ReceiptPayment::getReceiptPaymentDate, startDate)
//                .lt(ReceiptPayment::getReceiptPaymentDate, endDate)
        );
//        BigDecimal advanceMoney = receiptPayments.stream().map(ReceiptPayment::getReceiptPaymentAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
        // BigDecimal advanceMoney =
        // receiptPayments.stream().map(ReceiptPayment::getReceiptPaymentAmount).reduce(BigDecimal.ZERO,
        // BigDecimal::add);
        BigDecimal advanceMoney = sumAmount(receiptPayments, ReceiptPayment::getReceiptPaymentAmount);
        // é¢„付
        List<PaymentRegistration> paymentRegistrations = paymentRegistrationMapper.selectList(new LambdaQueryWrapper<PaymentRegistration>()
        List<PaymentRegistration> paymentRegistrations = paymentRegistrationMapper
                .selectList(new LambdaQueryWrapper<PaymentRegistration>()
//                .ge(PaymentRegistration::getPaymentDate, startDate)
//                .lt(PaymentRegistration::getPaymentDate, endDate)
        );
//        BigDecimal prepayMoney = paymentRegistrations.stream().map(PaymentRegistration::getCurrentPaymentAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
        // BigDecimal prepayMoney =
        // paymentRegistrations.stream().map(PaymentRegistration::getCurrentPaymentAmount).reduce(BigDecimal.ZERO,
        // BigDecimal::add);
        BigDecimal prepayMoney = sumAmount(paymentRegistrations, PaymentRegistration::getCurrentPaymentAmount);
        StatisticsReceivablePayableDto statisticsReceivablePayableDto = new StatisticsReceivablePayableDto();
        statisticsReceivablePayableDto.setPayableMoney(payableMoney.subtract(prepayMoney));
@@ -500,10 +525,12 @@
        Long aLong1 = deviceRepairMapper.selectCount(new LambdaQueryWrapper<DeviceRepair>()
                .eq(DeviceRepair::getStatus, 0)
                .eq(DeviceRepair::getRepairName, SecurityUtils.getLoginUser().getNickName()));
        return new HashMap<String, Object>() {{
        return new HashMap<String, Object>() {
            {
            put("approveTodo", aLong);
            put("deviceRepairTodo", aLong1);
        }};
            }
        };
    }
    @Override
@@ -520,11 +547,16 @@
        ProductOrderDto orderDto = new ProductOrderDto();
        orderDto.setStartTime(LocalDateTime.now().minusMonths(1));
        orderDto.setEndTime(LocalDateTime.now());
        List<ProductOrderDto> productOrderDtos = productOrderMapper.pageProductOrder(new Page<>(1, -1), orderDto).getRecords();
        List<ProductOrderDto> productOrderDtos = productOrderMapper.pageProductOrder(new Page<>(1, -1), orderDto)
                .getRecords();
        productionProgressDto.setCompletedOrderDetails(productOrderDtos);
        long totalCount = productOrderDtos.size();
        long count = productOrderDtos.stream().filter(productOrderDto -> productOrderDto.getCompleteQuantity().compareTo(productOrderDto.getQuantity()) >= 0).count();
        long count2 = productOrderDtos.stream().filter(productOrderDto -> productOrderDto.getCompleteQuantity().compareTo(BigDecimal.ZERO) == 0).count();
        long count = productOrderDtos.stream().filter(
                productOrderDto -> productOrderDto.getCompleteQuantity().compareTo(productOrderDto.getQuantity()) >= 0)
                .count();
        long count2 = productOrderDtos.stream()
                .filter(productOrderDto -> productOrderDto.getCompleteQuantity().compareTo(BigDecimal.ZERO) == 0)
                .count();
        productionProgressDto.setTotalOrderCount(totalCount);
        productionProgressDto.setCompletedOrderCount(count);
        productionProgressDto.setUncompletedOrderCount(count2);
@@ -538,29 +570,38 @@
        ProductWorkOrderDto workOrder = new ProductWorkOrderDto();
        workOrder.setPlanStartTime(LocalDate.now().minusMonths(1));
        workOrder.setPlanEndTime(LocalDate.now());
        List<ProductWorkOrderDto> productWorkOrders = productWorkOrderMapper.pageProductWorkOrder(new Page<>(1, -1), workOrder).getRecords();
        List<ProductWorkOrderDto> productWorkOrders = productWorkOrderMapper
                .pageProductWorkOrder(new Page<>(1, -1), workOrder).getRecords();
        long sum = productWorkOrders.stream()
                .filter(productWorkOrder -> productWorkOrder.getPlanQuantity().compareTo(productWorkOrder.getCompleteQuantity()) > 0)
                .filter(productWorkOrder -> productWorkOrder.getPlanQuantity()
                        .compareTo(productWorkOrder.getCompleteQuantity()) > 0)
                .map(ProductWorkOrder::getPlanQuantity)
                .mapToLong(BigDecimal::longValue)
                .sum();
        if (sum == 0) return null;
        if (sum == 0)
            return null;
        productionTurnoverDto.setTotalOrderCount(sum);//总在制品数量
        productionTurnoverDto.setAverageTurnoverDays(BigDecimal.valueOf(sum).divide(BigDecimal.valueOf(ChronoUnit.DAYS.between(LocalDateTime.now().minusMonths(1), LocalDateTime.now())), 2, RoundingMode.HALF_UP));
        productionTurnoverDto.setAverageTurnoverDays(BigDecimal.valueOf(sum).divide(
                BigDecimal.valueOf(ChronoUnit.DAYS.between(LocalDateTime.now().minusMonths(1), LocalDateTime.now())), 2,
                RoundingMode.HALF_UP));
        long completeQuantity = productWorkOrders.stream()
                .filter(productWorkOrder -> productWorkOrder.getCompleteQuantity().compareTo(productWorkOrder.getPlanQuantity()) >= 0)
                .filter(productWorkOrder -> productWorkOrder.getCompleteQuantity()
                        .compareTo(productWorkOrder.getPlanQuantity()) >= 0)
                .map(ProductWorkOrder::getCompleteQuantity)
                .mapToLong(BigDecimal::longValue)
                .sum();
        productionTurnoverDto.setTurnoverEfficiency(BigDecimal.valueOf(completeQuantity).divide(BigDecimal.valueOf(sum), 2, RoundingMode.HALF_UP));
        productionTurnoverDto.setTurnoverEfficiency(
                BigDecimal.valueOf(completeQuantity).divide(BigDecimal.valueOf(sum), 2, RoundingMode.HALF_UP));
        Map<String, List<ProductWorkOrderDto>> map = productWorkOrders.stream()
                .filter(productWorkOrder -> productWorkOrder.getPlanQuantity().compareTo(productWorkOrder.getCompleteQuantity()) > 0)
                .filter(productWorkOrder -> productWorkOrder.getPlanQuantity()
                        .compareTo(productWorkOrder.getCompleteQuantity()) > 0)
                .collect(Collectors.groupingBy(ProductWorkOrderDto::getProcessName));
        List<String> strings = new ArrayList<>();
        List<Long> processQuantityDetails = new ArrayList<>();
        map.entrySet().stream().forEach(entry -> {
            String key = entry.getKey();
            long completeSum = entry.getValue().stream().map(ProductWorkOrderDto::getCompleteQuantity).mapToLong(BigDecimal::longValue).sum();
            long completeSum = entry.getValue().stream().map(ProductWorkOrderDto::getCompleteQuantity)
                    .mapToLong(BigDecimal::longValue).sum();
            strings.add(key);
            processQuantityDetails.add(completeSum);
        });
@@ -655,7 +696,6 @@
                .le(StaffOnJob::getCreateTime, dateTime));
        return sysUserCount + staffCountItem;
    }
    private Long countCustomers(LocalDateTime dateTime) {
        return customerMapper.selectCount(new LambdaQueryWrapper<Customer>()
@@ -785,7 +825,8 @@
                String dayName = d.getMonthValue() + "/" + d.getDayOfMonth();
                BigDecimal sum = list.stream()
                        .filter(l -> l.getEntryDate() != null)
                        .filter(l -> l.getEntryDate().toInstant().atZone(ZoneId.systemDefault()).toLocalDate().equals(d))
                        .filter(l -> l.getEntryDate().toInstant().atZone(ZoneId.systemDefault()).toLocalDate()
                                .equals(d))
                        .map(SalesLedger::getContractAmount)
                        .filter(Objects::nonNull)
                        .reduce(BigDecimal.ZERO, BigDecimal::add);
@@ -901,7 +942,9 @@
        for (Map<String, Object> map : maps) {
            CustomerContributionRankingDto rankingDto = new CustomerContributionRankingDto();
            rankingDto.setCustomerName(map.get("customer_name").toString());
            rankingDto.setTotalAmount(map.get("total_amount") != null ? new BigDecimal(map.get("total_amount").toString()) : BigDecimal.ZERO);
            rankingDto
                    .setTotalAmount(map.get("total_amount") != null ? new BigDecimal(map.get("total_amount").toString())
                            : BigDecimal.ZERO);
            result.add(rankingDto);
        }
        return result;
@@ -994,11 +1037,13 @@
        String lastMonthEnd = lastMonth.with(TemporalAdjusters.lastDayOfMonth()).format(dtf);
        // é”€å”®
        int currentSales = salesLedgerProductMapper.selectProductCountByTypeAndDate(1, currentMonthStart, currentMonthNow);
        int currentSales = salesLedgerProductMapper.selectProductCountByTypeAndDate(1, currentMonthStart,
                currentMonthNow);
        int lastSales = salesLedgerProductMapper.selectProductCountByTypeAndDate(1, lastMonthStart, lastMonthEnd);
        // é‡‡è´­
        int currentPurchase = salesLedgerProductMapper.selectProductCountByTypeAndDate(2, currentMonthStart, currentMonthNow);
        int currentPurchase = salesLedgerProductMapper.selectProductCountByTypeAndDate(2, currentMonthStart,
                currentMonthNow);
        int lastPurchase = salesLedgerProductMapper.selectProductCountByTypeAndDate(2, lastMonthStart, lastMonthEnd);
        // å‚¨å­˜
@@ -1063,23 +1108,23 @@
        String startDate = now.minusDays(6).toString();
        String endDate = now.toString();
        List<Map<String, Object>> inCounts = stockInventoryMapper.selectDailyStockInCounts(rootCategoryId, startDate, endDate + " 23:59:59");
        List<Map<String, Object>> inCounts = stockInventoryMapper.selectDailyStockInCounts(rootCategoryId, startDate,
                endDate + " 23:59:59");
        List<Map<String, Object>> outCounts = stockInventoryMapper.selectDailyStockOutCounts(rootCategoryId, startDate, endDate + " 23:59:59");
        List<Map<String, Object>> outCounts = stockInventoryMapper.selectDailyStockOutCounts(rootCategoryId, startDate,
                endDate + " 23:59:59");
        Map<LocalDate, BigDecimal> inMap = inCounts.stream()
                .collect(Collectors.toMap(
                        m -> ((java.sql.Date) m.get("date")).toLocalDate(),
                        m -> (BigDecimal) m.get("count"),
                        BigDecimal::add
                ));
                        BigDecimal::add));
        Map<LocalDate, BigDecimal> outMap = outCounts.stream()
                .collect(Collectors.toMap(
                        m -> ((java.sql.Date) m.get("date")).toLocalDate(),
                        m -> (BigDecimal) m.get("count"),
                        BigDecimal::add
                ));
                        BigDecimal::add));
        List<Map<String, Object>> result = new ArrayList<>();
@@ -1107,7 +1152,6 @@
    @Autowired
    private AccountIncomeMapper accountIncomeMapper;
    public List<Map<String, Object>> incomeExpenseAnalysis(Integer type) {
@@ -1166,7 +1210,8 @@
//        List<IncomeExpenseAnalysisDto> purchaseList =
//                purchaseLedgerMapper.selectPurchaseStats(startStr, endStr, dateFormat);
        List<IncomeExpenseAnalysisDto> expenseList = accountExpenseMapper.selectAccountExpenseStats(startStr, endStr, dateFormat);
        List<IncomeExpenseAnalysisDto> expenseList = accountExpenseMapper.selectAccountExpenseStats(startStr, endStr,
                dateFormat);
        // 3. è½¬ Map(自动合并)
        Map<String, BigDecimal> incomeMap = incomeList.stream()
@@ -1212,7 +1257,6 @@
        return result;
    }
    @Override
    public List<MapDto> profitTrendAnalysis() {
        LocalDate today = LocalDate.now();
@@ -1232,14 +1276,20 @@
        String startStr = startDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        String endStr = endDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
//        List<IncomeExpenseAnalysisDto> incomeList = salesLedgerMapper.selectIncomeStats(startStr, endStr, dateFormat);
        // List<IncomeExpenseAnalysisDto> incomeList =
        // salesLedgerMapper.selectIncomeStats(startStr, endStr, dateFormat);
        List<IncomeExpenseAnalysisDto> incomeList = new ArrayList<>();
        List<IncomeExpenseAnalysisDto> purchaseList = purchaseLedgerMapper.selectPurchaseStats(startStr, endStr, dateFormat);
        List<IncomeExpenseAnalysisDto> expenseList = accountExpenseMapper.selectAccountExpenseStats(startStr, endStr, dateFormat);
        List<IncomeExpenseAnalysisDto> purchaseList = purchaseLedgerMapper.selectPurchaseStats(startStr, endStr,
                dateFormat);
        List<IncomeExpenseAnalysisDto> expenseList = accountExpenseMapper.selectAccountExpenseStats(startStr, endStr,
                dateFormat);
        Map<String, BigDecimal> incomeMap = incomeList.stream().collect(Collectors.toMap(IncomeExpenseAnalysisDto::getDateStr, IncomeExpenseAnalysisDto::getAmount, BigDecimal::add));
        Map<String, BigDecimal> purchaseMap = purchaseList.stream().collect(Collectors.toMap(IncomeExpenseAnalysisDto::getDateStr, IncomeExpenseAnalysisDto::getAmount, BigDecimal::add));
        Map<String, BigDecimal> expenseMap = expenseList.stream().collect(Collectors.toMap(IncomeExpenseAnalysisDto::getDateStr, IncomeExpenseAnalysisDto::getAmount, BigDecimal::add));
        Map<String, BigDecimal> incomeMap = incomeList.stream().collect(Collectors
                .toMap(IncomeExpenseAnalysisDto::getDateStr, IncomeExpenseAnalysisDto::getAmount, BigDecimal::add));
        Map<String, BigDecimal> purchaseMap = purchaseList.stream().collect(Collectors
                .toMap(IncomeExpenseAnalysisDto::getDateStr, IncomeExpenseAnalysisDto::getAmount, BigDecimal::add));
        Map<String, BigDecimal> expenseMap = expenseList.stream().collect(Collectors
                .toMap(IncomeExpenseAnalysisDto::getDateStr, IncomeExpenseAnalysisDto::getAmount, BigDecimal::add));
        List<MapDto> result = new ArrayList<>();
@@ -1314,7 +1364,6 @@
        return result;
    }
    @Override
    public MonthlyIncomeDto monthlyIncome() {
        MonthlyIncomeDto dto = new MonthlyIncomeDto();
@@ -1381,8 +1430,7 @@
        purchaseWrapper.ge(SalesLedgerProduct::getRegisterDate, startOfMonth);
        purchaseWrapper.le(SalesLedgerProduct::getRegisterDate, endOfMonth);
        List<SalesLedgerProduct> purchaseProducts =
                salesLedgerProductMapper.selectList(purchaseWrapper);
        List<SalesLedgerProduct> purchaseProducts = salesLedgerProductMapper.selectList(purchaseWrapper);
        BigDecimal rawMaterialCost = BigDecimal.ZERO;   // åŽŸææ–™æˆæœ¬
        BigDecimal paidAmount = BigDecimal.ZERO;        // å·²ä»˜æ¬¾é‡‘额
@@ -1412,8 +1460,7 @@
        expenseWrapper.le(AccountExpense::getExpenseDate,
                java.sql.Date.valueOf(currentMonth.atEndOfMonth()));
        List<AccountExpense> expenses =
                accountExpenseMapper.selectList(expenseWrapper);
        List<AccountExpense> expenses = accountExpenseMapper.selectList(expenseWrapper);
        BigDecimal otherExpense = BigDecimal.ZERO;
        if (!CollectionUtils.isEmpty(expenses)) {
@@ -1446,8 +1493,7 @@
        salesWrapper.ge(SalesLedgerProduct::getRegisterDate, startOfMonth);
        salesWrapper.le(SalesLedgerProduct::getRegisterDate, endOfMonth);
        List<SalesLedgerProduct> salesProducts =
                salesLedgerProductMapper.selectList(salesWrapper);
        List<SalesLedgerProduct> salesProducts = salesLedgerProductMapper.selectList(salesWrapper);
        BigDecimal revenue = BigDecimal.ZERO;
        if (!CollectionUtils.isEmpty(salesProducts)) {
@@ -1479,4 +1525,365 @@
        return dto;
    }
    @Autowired
    private ProductionProductInputMapper productionProductInputMapper;
    @Override
    public List<InputOutputAnalysisDto> inputOutputAnalysis(Integer type) {
        LocalDate today = LocalDate.now();
        LocalDate startDate;
        switch (type) {
            case 1: // å‘¨
                startDate = today.with(DayOfWeek.MONDAY);
                break;
            case 2: // æœˆ
                startDate = today.withDayOfMonth(1);
                break;
            case 3: // å­£åº¦
                int currentMonth = today.getMonthValue();
                int startMonth = ((currentMonth - 1) / 3) * 3 + 1;
                startDate = LocalDate.of(today.getYear(), startMonth, 1);
                break;
            default:
                startDate = today.with(DayOfWeek.MONDAY);
                break;
        }
        LocalDate endDate = today.plusDays(1);
        String startStr = startDate.atStartOfDay()
                .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        String endStr = endDate.atStartOfDay()
                .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        List<Map<String, Object>> inputList = productionProductInputMapper.selectInputStats(startStr, endStr);
        List<Map<String, Object>> outputList = productionProductOutputMapper.selectDailyOutputStats(startStr, endStr);
        Map<String, InputOutputAnalysisDto> dateMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(inputList)) {
            for (Map<String, Object> map : inputList) {
                String date = (String) map.get("date");
                if (date == null)
                    continue;
                InputOutputAnalysisDto dto = dateMap.getOrDefault(date, new InputOutputAnalysisDto());
                dto.setDate(date);
                BigDecimal qty = (BigDecimal) map.get("quantity");
                dto.setInputSum(dto.getInputSum() != null ? dto.getInputSum().add(qty) : qty);
                dateMap.put(date, dto);
            }
        }
        if (!CollectionUtils.isEmpty(outputList)) {
            for (Map<String, Object> map : outputList) {
                String date = (String) map.get("date");
                if (date == null)
                    continue;
                InputOutputAnalysisDto dto = dateMap.getOrDefault(date, new InputOutputAnalysisDto());
                dto.setDate(date);
                BigDecimal qty = (BigDecimal) map.get("quantity");
                dto.setOutputSum(dto.getOutputSum() != null ? dto.getOutputSum().add(qty) : qty);
                dateMap.put(date, dto);
            }
        }
        dateMap.values().forEach(dto -> {
            if (dto.getInputSum() == null)
                dto.setInputSum(BigDecimal.ZERO);
            if (dto.getOutputSum() == null)
                dto.setOutputSum(BigDecimal.ZERO);
        });
        return dateMap.values().stream()
                .sorted(Comparator.comparing(InputOutputAnalysisDto::getDate))
                .collect(Collectors.toList());
    }
    @Override
    public List<MapDto> processOutputAnalysis(Integer type) {
        LocalDate today = LocalDate.now();
        LocalDate startDate;
        LocalDate endDate = today;
        switch (type) {
            case 1: // å‘¨
                startDate = today.with(DayOfWeek.MONDAY);
                break;
            case 2: // æœˆ
                startDate = today.withDayOfMonth(1);
                break;
            case 3: // å­£åº¦
                int currentMonth = today.getMonthValue();
                int startMonth = ((currentMonth - 1) / 3) * 3 + 1;
                startDate = LocalDate.of(today.getYear(), startMonth, 1);
                break;
            default:
                startDate = today.with(DayOfWeek.MONDAY);
                break;
        }
        ProductWorkOrderDto queryDto = new ProductWorkOrderDto();
        queryDto.setPlanStartTime(startDate);
        queryDto.setPlanEndTime(endDate);
        List<ProductWorkOrderDto> list = productWorkOrderMapper.pageProductWorkOrder(new Page<>(1, -1), queryDto)
                .getRecords();
        if (CollectionUtils.isEmpty(list)) {
            return new ArrayList<>();
        }
        Map<String, BigDecimal> processOutputMap = list.stream()
                .filter(item -> item.getProcessName() != null && item.getCompleteQuantity() != null)
                .collect(Collectors.groupingBy(
                        ProductWorkOrderDto::getProcessName,
                        Collectors.reducing(BigDecimal.ZERO,
                                ProductWorkOrderDto::getCompleteQuantity,
                                BigDecimal::add)));
        BigDecimal total = processOutputMap.values().stream()
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        if (BigDecimal.ZERO.compareTo(total) == 0) {
            return new ArrayList<>();
        }
        List<MapDto> result = new ArrayList<>();
        processOutputMap.forEach((name, value) -> {
            MapDto dto = new MapDto();
            dto.setName(name);
            dto.setValue(value.stripTrailingZeros().toPlainString());
            BigDecimal rate = value
                    .divide(total, 4, RoundingMode.HALF_UP)
                    .multiply(new BigDecimal("100"));
            dto.setRate(rate.setScale(2, RoundingMode.HALF_UP) + "%");
            result.add(dto);
        });
        return result;
    }
    @Override
    public List<WorkOrderEfficiencyDto> workOrderEfficiencyAnalysis(Integer type) {
        LocalDate today = LocalDate.now();
        LocalDate startDate;
        LocalDate endDate = today;
        switch (type) {
            case 1: // å‘¨
                startDate = today.with(DayOfWeek.MONDAY);
                break;
            case 2: // æœˆ
                startDate = today.withDayOfMonth(1);
                break;
            case 3: // å­£åº¦
                int currentMonth = today.getMonthValue();
                int startMonth = ((currentMonth - 1) / 3) * 3 + 1;
                startDate = LocalDate.of(today.getYear(), startMonth, 1);
                break;
            default:
                startDate = today.with(DayOfWeek.MONDAY);
                break;
        }
        String startStr = startDate.atStartOfDay().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        String endStr = endDate.atTime(LocalTime.MAX).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        List<ProductWorkOrderDto> startList = productWorkOrderMapper.selectWorkOrderStartStats(startStr, endStr);
        List<com.ruoyi.production.dto.ProductionProductOutputDto> outputList = productionProductOutputMapper
                .selectOutputStats(startStr, endStr);
        Map<String, WorkOrderEfficiencyDto> dateMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(startList)) {
            for (ProductWorkOrderDto item : startList) {
                if (item.getPlanStartTime() != null) {
                    String date = item.getPlanStartTime().toString();
                    WorkOrderEfficiencyDto dto = dateMap.getOrDefault(date, new WorkOrderEfficiencyDto());
                    dto.setDate(date);
                    BigDecimal qty = item.getPlanQuantity() != null ? item.getPlanQuantity() : BigDecimal.ZERO;
                    dto.setStartQuantity(dto.getStartQuantity() != null ? dto.getStartQuantity().add(qty) : qty);
                    dateMap.put(date, dto);
                }
            }
        }
        // å®Œå·¥æ•°é‡å’Œè‰¯å“çއ
        if (!CollectionUtils.isEmpty(outputList)) {
            for (com.ruoyi.production.dto.ProductionProductOutputDto item : outputList) {
                if (item.getCreateTime() != null) {
                    String date = item.getCreateTime().toLocalDate().toString();
                    WorkOrderEfficiencyDto dto = dateMap.getOrDefault(date, new WorkOrderEfficiencyDto());
                    dto.setDate(date);
                    BigDecimal finishQty = item.getQuantity() != null ? item.getQuantity() : BigDecimal.ZERO;
                    BigDecimal scrapQty = item.getScrapQty() != null ? item.getScrapQty() : BigDecimal.ZERO;
                    dto.setFinishQuantity(
                            dto.getFinishQuantity() != null ? dto.getFinishQuantity().add(finishQty) : finishQty);
                }
            }
            Map<String, BigDecimal> scrapMap = outputList.stream()
                    .filter(i -> i.getCreateTime() != null)
                    .collect(Collectors.groupingBy(
                            i -> i.getCreateTime().toLocalDate().toString(),
                            Collectors.reducing(BigDecimal.ZERO,
                                    i -> i.getScrapQty() != null ? i.getScrapQty() : BigDecimal.ZERO,
                                    BigDecimal::add)));
            Map<String, BigDecimal> finishMap = outputList.stream()
                    .filter(i -> i.getCreateTime() != null)
                    .collect(Collectors.groupingBy(
                            i -> i.getCreateTime().toLocalDate().toString(),
                            Collectors.reducing(BigDecimal.ZERO,
                                    i -> i.getQuantity() != null ? i.getQuantity() : BigDecimal.ZERO,
                                    BigDecimal::add)));
            finishMap.forEach((date, qty) -> {
                WorkOrderEfficiencyDto dto = dateMap.getOrDefault(date, new WorkOrderEfficiencyDto());
                dto.setDate(date);
                dto.setFinishQuantity(qty);
                dateMap.put(date, dto);
            });
            dateMap.forEach((date, dto) -> {
                BigDecimal finish = dto.getFinishQuantity() != null ? dto.getFinishQuantity() : BigDecimal.ZERO;
                BigDecimal scrap = scrapMap.getOrDefault(date, BigDecimal.ZERO);
                BigDecimal total = finish.add(scrap);
                if (total.compareTo(BigDecimal.ZERO) > 0) {
                    BigDecimal rate = finish.divide(total, 4, RoundingMode.HALF_UP).multiply(new BigDecimal("100"))
                            .setScale(2, RoundingMode.HALF_UP);
                    dto.setYieldRate(rate.toString());
                } else {
                    dto.setYieldRate("0.00");
                }
                if (dto.getStartQuantity() == null)
                    dto.setStartQuantity(BigDecimal.ZERO);
                if (dto.getFinishQuantity() == null)
                    dto.setFinishQuantity(BigDecimal.ZERO);
            });
        }
        dateMap.values().forEach(dto -> {
            if (dto.getStartQuantity() == null)
                dto.setStartQuantity(BigDecimal.ZERO);
            if (dto.getFinishQuantity() == null)
                dto.setFinishQuantity(BigDecimal.ZERO);
            if (dto.getYieldRate() == null)
                dto.setYieldRate("0.00");
        });
        return dateMap.values().stream()
                .sorted(Comparator.comparing(WorkOrderEfficiencyDto::getDate))
                .collect(Collectors.toList());
    }
    @Autowired
    private com.ruoyi.production.mapper.SalesLedgerProductionAccountingMapper salesLedgerProductionAccountingMapper;
    @Override
    public List<MapDto> productionAccountingAnalysis(Integer type) {
        LocalDate today = LocalDate.now();
        LocalDate startDate;
        LocalDate endDate = today;
        switch (type) {
            case 1: // å‘¨
                startDate = today.with(DayOfWeek.MONDAY);
                break;
            case 2: // æœˆ
                startDate = today.withDayOfMonth(1);
                break;
            case 3: // å­£åº¦
                int currentMonth = today.getMonthValue();
                int startMonth = ((currentMonth - 1) / 3) * 3 + 1;
                startDate = LocalDate.of(today.getYear(), startMonth, 1);
                break;
            default:
                startDate = today.with(DayOfWeek.MONDAY);
                break;
        }
        String startStr = startDate.atStartOfDay().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        String endStr = endDate.atTime(LocalTime.MAX).format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        List<Map<String, Object>> wagesList = salesLedgerProductionAccountingMapper.selectDailyWagesStats(startStr,
                endStr);
        if (CollectionUtils.isEmpty(wagesList)) {
            return new ArrayList<>();
        }
        List<MapDto> result = new ArrayList<>();
        for (Map<String, Object> map : wagesList) {
            MapDto dto = new MapDto();
            dto.setName((String) map.get("date"));
            BigDecimal wages = (BigDecimal) map.get("wages");
            dto.setValue(wages != null ? wages.toString() : "0");
            result.add(dto);
        }
        result.sort(Comparator.comparing(MapDto::getName));
        return result;
    }
    @Override
    public List<MapDto> orderCount() {
        LocalDate now = LocalDate.now();
        String currentStart = now.withDayOfMonth(1).atStartOfDay()
                .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        String currentEnd = now.atTime(LocalTime.MAX).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        LocalDate lastMonthDate = now.minusMonths(1);
        String lastStart = lastMonthDate.withDayOfMonth(1).atStartOfDay()
                .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        String lastEnd = lastMonthDate.withDayOfMonth(lastMonthDate.lengthOfMonth()).atTime(LocalTime.MAX)
                .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        int currentCreated = productOrderMapper.countCreated(currentStart, currentEnd);
        int lastCreated = productOrderMapper.countCreated(lastStart, lastEnd);
        MapDto createdDto = createOrderCountDto("生产订单数", currentCreated, lastCreated);
        int currentCompleted = productOrderMapper.countCompleted(currentStart, currentEnd);
        int lastCompleted = productOrderMapper.countCompleted(lastStart, lastEnd);
        MapDto completedDto = createOrderCountDto("已完成订单数", currentCompleted, lastCompleted);
        int currentPending = productOrderMapper.countPending(currentStart, currentEnd);
        int lastPending = productOrderMapper.countPending(lastStart, lastEnd);
        MapDto pendingDto = createOrderCountDto("待生产订单数", currentPending, lastPending);
        return Arrays.asList(createdDto, completedDto, pendingDto);
    }
    private MapDto createOrderCountDto(String name, int current, int last) {
        MapDto dto = new MapDto();
        dto.setName(name);
        dto.setValue(String.valueOf(current));
        BigDecimal currentVal = new BigDecimal(current);
        BigDecimal lastVal = new BigDecimal(last);
        if (lastVal.compareTo(BigDecimal.ZERO) == 0) {
            dto.setRate(currentVal.compareTo(BigDecimal.ZERO) > 0 ? "100" : "0");
        } else {
            // (Current - Last) / Last * 100
            BigDecimal diff = currentVal.subtract(lastVal);
            BigDecimal rate = diff.divide(lastVal, 2, RoundingMode.HALF_UP).multiply(new BigDecimal("100")).setScale(0,
                    RoundingMode.HALF_UP);
            dto.setRate(rate.toString());
        }
        return dto;
    }
}
src/main/java/com/ruoyi/production/mapper/ProductOrderMapper.java
@@ -25,4 +25,10 @@
    List<ProcessRoute> listProcessRoute(@Param("productModelId") Long productModelId);
    List<ProductStructureDto> listProcessBom(@Param("orderId") Long orderId);
    Integer countCreated(@Param("startDate") String startDate, @Param("endDate") String endDate);
    Integer countCompleted(@Param("startDate") String startDate, @Param("endDate") String endDate);
    Integer countPending(@Param("startDate") String startDate, @Param("endDate") String endDate);
}
src/main/java/com/ruoyi/production/mapper/ProductWorkOrderMapper.java
@@ -18,4 +18,6 @@
    IPage<ProductWorkOrderDto> pageProductWorkOrder(Page<ProductWorkOrderDto> page, @Param("c") ProductWorkOrderDto productWorkOrder);
    ProductWorkOrderDto getProductWorkOrderFlowCard(@Param("id") Long id);
    List<ProductWorkOrderDto> selectWorkOrderStartStats(@Param("startDate") String startDate, @Param("endDate") String endDate);
}
src/main/java/com/ruoyi/production/mapper/ProductionProductInputMapper.java
@@ -9,6 +9,7 @@
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
@Mapper
public interface ProductionProductInputMapper extends BaseMapper<ProductionProductInput> {
@@ -18,4 +19,6 @@
     * æ ¹æ®ç”Ÿäº§ä¸»è¡¨ID批量删除投入表数据
     */
    int deleteByProductMainIds(@Param("productMainIds") List<Long> productMainIds);
    List<Map<String, Object>> selectInputStats(@Param("startDate") String startDate, @Param("endDate") String endDate);
}
src/main/java/com/ruoyi/production/mapper/ProductionProductOutputMapper.java
@@ -9,6 +9,7 @@
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
@Mapper
public interface ProductionProductOutputMapper extends BaseMapper<ProductionProductOutput> {
@@ -18,4 +19,8 @@
     * æ ¹æ®ç”Ÿäº§ä¸»è¡¨ID批量删除产出表数据
     */
    int deleteByProductMainIds(@Param("productMainIds") List<Long> productMainIds);
    List<ProductionProductOutputDto> selectOutputStats(@Param("startDate") String startDate, @Param("endDate") String endDate);
    List<Map<String, Object>> selectDailyOutputStats(@Param("startDate") String startDate, @Param("endDate") String endDate);
}
src/main/java/com/ruoyi/production/mapper/SalesLedgerProductionAccountingMapper.java
@@ -7,6 +7,9 @@
import com.ruoyi.production.pojo.SalesLedgerProductionAccounting;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
/**
 * @author :yys
 * @date : 2025/7/21 14:38
@@ -18,4 +21,6 @@
    IPage<SalesLedgerProductionAccountingDto> pageProductionAccounting(Page page, @Param("ew") SalesLedgerProductionAccountingDto salesLedgerProductionAccountingDto);
    List<Map<String, Object>> selectDailyWagesStats(@Param("startDate") String startDate, @Param("endDate") String endDate);
}
src/main/resources/mapper/production/ProductOrderMapper.xml
@@ -90,4 +90,20 @@
    </select>
    <select id="countCreated" resultType="java.lang.Integer">
        SELECT count(1) FROM product_order
        WHERE create_time &gt;= #{startDate} AND create_time &lt;= #{endDate}
    </select>
    <select id="countCompleted" resultType="java.lang.Integer">
        SELECT count(1) FROM product_order
        WHERE end_time &gt;= #{startDate} AND end_time &lt;= #{endDate}
          AND complete_quantity &gt;= quantity
    </select>
    <select id="countPending" resultType="java.lang.Integer">
        SELECT count(1) FROM product_order
        WHERE create_time &gt;= #{startDate} AND create_time &lt;= #{endDate}
          AND complete_quantity &lt; quantity
    </select>
</mapper>
src/main/resources/mapper/production/ProductWorkOrderMapper.xml
@@ -72,4 +72,15 @@
                p.product_name,
                po.nps_no
    </select>
    <select id="selectWorkOrderStartStats" resultType="com.ruoyi.production.dto.ProductWorkOrderDto">
        SELECT
            id,
            actual_start_time AS planStartTime,
            plan_quantity
        FROM
            product_work_order
        WHERE
            actual_start_time &gt;= #{startDate}
            AND actual_start_time &lt;= #{endDate}
    </select>
</mapper>
src/main/resources/mapper/production/ProductionProductInputMapper.xml
@@ -35,5 +35,19 @@
        <foreach collection="productMainIds" item="id" open="(" separator="," close=")">
            #{id}
        </foreach>
    </delete>
    <select id="selectInputStats" resultType="java.util.Map">
        SELECT
            DATE_FORMAT(create_time, '%Y-%m-%d') as date,
            SUM(quantity) as quantity
        FROM
            production_product_input
        WHERE
            create_time &gt;= #{startDate}
            AND create_time &lt;= #{endDate}
        GROUP BY
            DATE_FORMAT(create_time, '%Y-%m-%d')
    </select>
</mapper>
src/main/resources/mapper/production/ProductionProductOutputMapper.xml
@@ -34,4 +34,28 @@
            #{id}
        </foreach>
    </delete>
    <select id="selectOutputStats" resultType="com.ruoyi.production.dto.ProductionProductOutputDto">
        SELECT
            create_time,
            quantity,
            scrap_qty
        FROM
            production_product_output
        WHERE
            create_time &gt;= #{startDate}
            AND create_time &lt;= #{endDate}
    </select>
    <select id="selectDailyOutputStats" resultType="java.util.Map">
        SELECT
            DATE_FORMAT(create_time, '%Y-%m-%d') as date,
            SUM(quantity) as quantity
        FROM
            production_product_output
        WHERE
            create_time &gt;= #{startDate}
            AND create_time &lt;= #{endDate}
        GROUP BY
            DATE_FORMAT(create_time, '%Y-%m-%d')
    </select>
</mapper>
src/main/resources/mapper/production/SalesLedgerProductionAccountingMapper.xml
@@ -70,4 +70,18 @@
    </select>
    <select id="selectDailyWagesStats" resultType="java.util.Map">
        SELECT
            DATE_FORMAT(scheduling_date, '%Y-%m-%d') as date,
            SUM(finished_num * work_hours) as wages
        FROM
            sales_ledger_production_accounting
        WHERE
            scheduling_date &gt;= #{startDate}
            AND scheduling_date &lt;= #{endDate}
        GROUP BY
            scheduling_date
    </select>
</mapper>