e179ca5166d6296c9bbc79067669919212e72123..d0eaee38a59ec4f2600bfec41b3db5f80500af32
2025-12-12 maven
yys
d0eaee 对比 | 目录
2025-12-12 maven
yys BI大屏接口修改
b6ec30 对比 | 目录
已修改8个文件
242 ■■■■ 文件已修改
src/main/java/com/ruoyi/account/service/impl/AccountExpenseServiceImpl.java 103 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java 106 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/service/impl/ProcurementRecordServiceImpl.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/procurementrecord/ProcurementRecordMapper.xml 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/procurementrecord/ProcurementRecordOutMapper.xml 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/production/SalesLedgerProductionAccountingMapper.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/production/SalesLedgerSchedulingMapper.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/production/SalesLedgerWorkMapper.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/account/service/impl/AccountExpenseServiceImpl.java
@@ -24,8 +24,10 @@
import java.math.BigDecimal;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
@AllArgsConstructor
@Service
@@ -115,38 +117,87 @@
    @Override
    public Map<String, List<String>> analysis() {
        // 获取本周的时间范围
        LocalDate startOfWeek = LocalDate.now().with(DayOfWeek.MONDAY);
        LocalDate endOfWeek = LocalDate.now().with(DayOfWeek.SUNDAY);
        // 获取最近四个月(当前月 + 前3个月)的时间范围
        LocalDate today = LocalDate.now();
        DateTimeFormatter monthFormatter = DateTimeFormatter.ofPattern("yyyy-MM"); // 年月格式化器
        Map<String, List<String>> result = new HashMap<>();
        List<String> days = new ArrayList<>();
        List<String> totalIncomeList = new ArrayList<>();
        List<String> totalExpenseList = new ArrayList<>();
        List<String> netIncomeList = new ArrayList<>();
        // 根据时间范围循环查询每一天的总收入,总支出,净收入(总收入-总支出)
        for (LocalDate date = startOfWeek; date.isBefore(endOfWeek) || date.isEqual(endOfWeek); date = date.plusDays(1)) {
            BigDecimal totalIncome = accountIncomeMapper.selectList(Wrappers.<AccountIncome>lambdaQuery()
                    .eq(AccountIncome::getInputTime, date.toString()))
                    .stream()
                    .map(AccountIncome::getIncomeMoney)
                    .filter(Objects::nonNull)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            BigDecimal totalExpense = accountExpenseMapper.selectList(Wrappers.<AccountExpense>lambdaQuery()
                    .eq(AccountExpense::getInputTime, date.toString()))
                    .stream()
                    .map(AccountExpense::getExpenseMoney)
                    .filter(Objects::nonNull)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
        List<String> months = new ArrayList<>(); // 存储年月(如 2025-12、2025-11)
        List<String> totalIncomeList = new ArrayList<>(); // 每月总收入
        List<String> totalExpenseList = new ArrayList<>(); // 每月总支出
        List<String> netIncomeList = new ArrayList<>(); // 每月净收入(收入-支出)
        // 步骤1:计算近4个月的年月列表(当前月、前1月、前2月、前3月)
        List<String> targetMonths = new ArrayList<>();
        for (int i = 0; i < 4; i++) {
            LocalDate currentMonth = today.minusMonths(i);
            String monthStr = currentMonth.format(monthFormatter);
            targetMonths.add(monthStr);
        }
        // 反转列表,确保顺序为「前3月 → 当前月」(可选,按需求调整顺序)
        Collections.reverse(targetMonths);
        // 步骤2:一次性查询近4个月所有收入数据,按“年月”分组汇总
        LocalDate fourMonthsAgo = today.minusMonths(3).withDayOfMonth(1); // 近4个月起始日(前3月1号)
        LocalDate currentMonthEnd = today.withDayOfMonth(today.lengthOfMonth()); // 当前月结束日
        ZoneId zoneId = ZoneId.of("Asia/Shanghai");
        // 查询近4个月所有收入
        List<AccountIncome> allIncomes = accountIncomeMapper.selectList(
                Wrappers.<AccountIncome>lambdaQuery()
                        .ge(AccountIncome::getIncomeDate, fourMonthsAgo.toString()) // 大于等于起始日
                        .le(AccountIncome::getIncomeDate, currentMonthEnd.toString()) // 小于等于结束日
        );
        // 收入按“年月”分组汇总(key:年月字符串,value:当月总收入)
        Map<String, BigDecimal> monthlyIncomeMap = allIncomes.stream()
                .filter(income -> income.getIncomeMoney() != null) // 过滤空金额
                .collect(Collectors.groupingBy(
                        income -> {
                            // 将输入时间(字符串)转换为LocalDate,再格式化为年月
                            LocalDate inputDate = income.getIncomeDate().toInstant().atZone(zoneId).toLocalDate();
                            return inputDate.format(monthFormatter);
                        },
                        Collectors.reducing(BigDecimal.ZERO, AccountIncome::getIncomeMoney, BigDecimal::add)
                ));
        // 步骤3:一次性查询近4个月所有支出数据,按“年月”分组汇总
        List<AccountExpense> allExpenses = accountExpenseMapper.selectList(
                Wrappers.<AccountExpense>lambdaQuery()
                        .ge(AccountExpense::getExpenseDate, fourMonthsAgo.toString())
                        .le(AccountExpense::getExpenseDate, currentMonthEnd.toString())
        );
        // 支出按“年月”分组汇总
        Map<String, BigDecimal> monthlyExpenseMap = allExpenses.stream()
                .filter(expense -> expense.getExpenseMoney() != null) // 过滤空金额
                .collect(Collectors.groupingBy(
                        expense -> {
                            LocalDate inputDate = expense.getExpenseDate().toInstant().atZone(zoneId).toLocalDate();
                            return inputDate.format(monthFormatter);
                        },
                        Collectors.reducing(BigDecimal.ZERO, AccountExpense::getExpenseMoney, BigDecimal::add)
                ));
        // 步骤4:循环4个目标月份,填充统计数据(无数据时默认为0)
        for (String month : targetMonths) {
            // 当月总收入(无数据则为0)
            BigDecimal totalIncome = monthlyIncomeMap.getOrDefault(month, BigDecimal.ZERO);
            // 当月总支出(无数据则为0)
            BigDecimal totalExpense = monthlyExpenseMap.getOrDefault(month, BigDecimal.ZERO);
            // 当月净收入(收入 - 支出)
            BigDecimal netIncome = totalIncome.subtract(totalExpense);
            days.add(date.toString());
            // 填充列表
            months.add(month);
            totalIncomeList.add(totalIncome.toString());
            totalExpenseList.add(totalExpense.toString());
            netIncomeList.add(netIncome.toString());
        }
        result.put("days", days);  //  天
        result.put("totalIncome", totalIncomeList); // 收入
        result.put("totalExpense", totalExpenseList); // 支出
        result.put("netIncome", netIncomeList); // 净收入
        // 组装结果
        result.put("days", months); // 年月(如 ["2025-09", "2025-10", "2025-11", "2025-12"])
        result.put("totalIncome", totalIncomeList); // 对应月份总收入
        result.put("totalExpense", totalExpenseList); // 对应月份总支出
        result.put("netIncome", netIncomeList); // 对应月份净收入
        return result;
    }
src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java
@@ -44,6 +44,7 @@
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
@@ -270,50 +271,83 @@
    @Override
    public QualityStatisticsDto qualityStatistics() {
        // 获取一周数据
        // 获取当前时间
        // 获取近四个月数据(往前推三个月,共4个完整月份)
        LocalDate today = LocalDate.now();
        // 获取本周周一
        LocalDate startOfWeek = today.with(DayOfWeek.MONDAY);
        // 获取本周周日
        LocalDate endOfWeek = today.with(DayOfWeek.SUNDAY);
        LambdaQueryWrapper<QualityInspect> qualityInspectLambdaQueryWrapper = new LambdaQueryWrapper<>();
        qualityInspectLambdaQueryWrapper.ge(QualityInspect::getCheckTime, startOfWeek)
                .gt(QualityInspect::getCheckTime, endOfWeek);
        List<QualityInspect> qualityInspects = qualityStatisticsMapper.selectList(qualityInspectLambdaQueryWrapper);
        // 定义日期格式化器(用于显示“年月”格式)
        DateTimeFormatter monthFormatter = DateTimeFormatter.ofPattern("yyyy-MM");
        QualityStatisticsDto qualityStatisticsDto = new QualityStatisticsDto();
        qualityStatisticsDto.setSupplierNum(qualityInspects.stream().filter(item -> item.getInspectType().equals(0)).map(QualityInspect::getQuantity).reduce(BigDecimal.ZERO, BigDecimal::add));
        qualityStatisticsDto.setProcessNum(qualityInspects.stream().filter(item -> item.getInspectType().equals(1)).map(QualityInspect::getQuantity).reduce(BigDecimal.ZERO, BigDecimal::add));
        qualityStatisticsDto.setFactoryNum(qualityInspects.stream().filter(item -> item.getInspectType().equals(2)).map(QualityInspect::getQuantity).reduce(BigDecimal.ZERO, BigDecimal::add));
        List<QualityStatisticsItem> qualityStatisticsItems = new ArrayList<>();
        for (int j = 1; j < 8; j++) {
            LocalDate endTime = startOfWeek.plusDays(j);
            LocalDate startTime = endTime.minusDays(1);
            QualityStatisticsItem qualityStatisticsItem = new QualityStatisticsItem();
            qualityStatisticsItem.setDate(startTime.toString());
            qualityStatisticsItem.setSupplierNum(qualityInspects.stream()
                    .filter(item -> item.getInspectType().equals(0) && "不合格".equals(item.getCheckResult())
                            && (startTime.isEqual(item.getCheckTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate()) || startTime.isAfter(item.getCheckTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate()))
                            && endTime.isBefore(item.getCheckTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate()))
        BigDecimal supplierNum = new BigDecimal(0);
        BigDecimal factoryNum = new BigDecimal(0);
        BigDecimal processNum = new BigDecimal(0);
        // 循环4次,分别统计近4个月的数据(当前月、前1个月、前2个月、前3个月)
        for (int i = 3; i >= 0; i--) {
            // 计算当前循环对应的月份(i=0:当前月,i=1:前1个月,以此类推)
            LocalDate currentMonth = today.minusMonths(i);
            // 当月的开始日期(每月1号)
            LocalDate monthStart = currentMonth.withDayOfMonth(1);
            // 当月的结束日期(每月最后一天)
            LocalDate monthEnd = currentMonth.withDayOfMonth(currentMonth.lengthOfMonth());
            // 构建当月的查询条件(如果想一次性查全4个月数据再内存筛选,可优化为先查全再循环筛选)
            LambdaQueryWrapper<QualityInspect> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.ge(QualityInspect::getCheckTime, monthStart)
                    .le(QualityInspect::getCheckTime, monthEnd); // 筛选当月数据
            List<QualityInspect> monthInspects = qualityStatisticsMapper.selectList(queryWrapper);
            BigDecimal reduce = monthInspects.stream()
                    .filter(inspect -> inspect.getInspectType().equals(0))
                    .map(QualityInspect::getQuantity)
                    .reduce(BigDecimal.ZERO, BigDecimal::add)
            );
            qualityStatisticsItem.setFactoryNum(qualityInspects.stream()
                    .filter(item -> item.getInspectType().equals(1) && "不合格".equals(item.getCheckResult())
                            && (startTime.isEqual(item.getCheckTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate()) || startTime.isAfter(item.getCheckTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate()))
                            && endTime.isBefore(item.getCheckTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate()))
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            supplierNum = supplierNum.add(reduce);
            BigDecimal reduce1 = monthInspects.stream()
                    .filter(inspect -> inspect.getInspectType().equals(1))
                    .map(QualityInspect::getQuantity)
                    .reduce(BigDecimal.ZERO, BigDecimal::add)
            );
            qualityStatisticsItem.setProcessNum(qualityInspects.stream()
                    .filter(item -> item.getInspectType().equals(2) && "不合格".equals(item.getCheckResult())
                            && (startTime.isEqual(item.getCheckTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate()) || startTime.isAfter(item.getCheckTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate()))
                            && endTime.isBefore(item.getCheckTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate()))
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            processNum= processNum.add(reduce1);
            BigDecimal reduce2 = monthInspects.stream()
                    .filter(inspect -> inspect.getInspectType().equals(2))
                    .map(QualityInspect::getQuantity)
                    .reduce(BigDecimal.ZERO, BigDecimal::add));
            qualityStatisticsItems.add(qualityStatisticsItem);
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            factoryNum = factoryNum.add(reduce2);
            // 构建当月统计项
            QualityStatisticsItem item = new QualityStatisticsItem();
            item.setDate(monthStart.format(monthFormatter)); // 日期显示为“年月”(如 2025-10)
            // 1. 供应商检验(类型0)- 合格数量
            BigDecimal supplierQualified = monthInspects.stream()
                    .filter(inspect -> inspect.getInspectType().equals(0)
                            && "合格".equals(inspect.getCheckResult()))
                    .map(QualityInspect::getQuantity)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            item.setSupplierNum(supplierQualified);
            // 2. 工序检验(类型1)- 合格数量
            BigDecimal processQualified = monthInspects.stream()
                    .filter(inspect -> inspect.getInspectType().equals(1)
                            && "合格".equals(inspect.getCheckResult()))
                    .map(QualityInspect::getQuantity)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            item.setProcessNum(processQualified);
            // 3. 工厂检验(类型2)- 合格数量
            BigDecimal factoryQualified = monthInspects.stream()
                    .filter(inspect -> inspect.getInspectType().equals(2)
                            && "合格".equals(inspect.getCheckResult()))
                    .map(QualityInspect::getQuantity)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            item.setFactoryNum(factoryQualified);
            qualityStatisticsItems.add(item);
        }
        // 统计近4个月总数据(所有月份汇总)
        qualityStatisticsDto.setProcessNum(processNum);
        qualityStatisticsDto.setSupplierNum(supplierNum);
        qualityStatisticsDto.setFactoryNum(factoryNum);
        qualityStatisticsDto.setItem(qualityStatisticsItems);
        return qualityStatisticsDto;
    }
src/main/java/com/ruoyi/procurementrecord/service/impl/ProcurementRecordServiceImpl.java
@@ -467,6 +467,9 @@
            if(customStorage.getTimeStr() != null){
                customStorageLambdaQueryWrapper.eq(CustomStorage::getInboundDate, customStorage.getTimeStr());
            }
            if(!StringUtils.isEmpty(customStorage.getProductCategory())){
                customStorageLambdaQueryWrapper.like(CustomStorage::getProductCategory, customStorage.getProductCategory());
            }
        }
        customStorageLambdaQueryWrapper.orderByDesc(CustomStorage::getInboundDate);
        IPage<CustomStorage> procurementPageDtoIPage = customStorageMapper.selectPage(page, customStorageLambdaQueryWrapper);
@@ -561,6 +564,9 @@
            if(customStorage.getInboundDate() != null){
                customStorageLambdaQueryWrapper.eq(CustomStorage::getInboundDate, customStorage.getInboundDate());
            }
            if(!StringUtils.isEmpty(customStorage.getProductCategory())){
                customStorageLambdaQueryWrapper.like(CustomStorage::getProductCategory, customStorage.getProductCategory());
            }
        }
        customStorageLambdaQueryWrapper.orderByDesc(CustomStorage::getInboundDate);
        IPage<CustomStorage> pageList = customStorageMapper.selectPage(page, customStorageLambdaQueryWrapper);
src/main/resources/mapper/procurementrecord/ProcurementRecordMapper.xml
@@ -57,6 +57,9 @@
            <if test="req.supplierName != null and req.supplierName != ''">
                and t3.supplier_name like  concat('%',#{req.supplierName},'%')
            </if>
            <if test="req.productCategory != null and req.productCategory != ''">
                and t2.product_category like  concat('%',#{req.productCategory},'%')
            </if>
            <if test="req.timeStr != null and req.timeStr != ''">
                and t1.create_time like  concat('%',#{req.timeStr},'%')
            </if>
@@ -142,6 +145,9 @@
            t1.type = 1
            <if test="req.supplierName != null and req.supplierName != ''">
                and t3.supplier_name like  concat('%',#{req.supplierName},'%')
            </if>
            <if test="req.productCategory != null and req.productCategory != ''">
                and t2.product_category like  concat('%',#{req.productCategory},'%')
            </if>
            <if test="req.timeStr != null and req.timeStr != ''">
                and t1.create_time like  concat('%',#{req.timeStr},'%')
@@ -252,6 +258,9 @@
            <if test="req.customerName != null and req.customerName != ''">
                and t3.customer_name like  concat('%',#{req.customerName},'%')
            </if>
            <if test="req.productCategory != null and req.productCategory != ''">
                and t2.product_category like  concat('%',#{req.productCategory},'%')
            </if>
            <if test="req.timeStr != null and req.timeStr != ''">
                and t1.create_time like  concat('%',#{req.timeStr},'%')
            </if>
@@ -290,6 +299,9 @@
            <if test="req.customerName != null and req.customerName != ''">
                and t3.customer_name like  concat('%',#{req.customerName},'%')
            </if>
            <if test="req.productCategory != null and req.productCategory != ''">
                and t2.product_category like  concat('%',#{req.productCategory},'%')
            </if>
            <if test="req.timeStr != null and req.timeStr != ''">
                and t1.create_time like  concat('%',#{req.timeStr},'%')
            </if>
src/main/resources/mapper/procurementrecord/ProcurementRecordOutMapper.xml
@@ -26,6 +26,9 @@
            <if test="req.supplierName != null and req.supplierName != ''">
                and t3.supplier_name like  concat('%',#{req.supplierName},'%')
            </if>
            <if test="req.productCategory != null and req.productCategory != ''">
                and t2.product_category like  concat('%',#{req.productCategory},'%')
            </if>
            <if test="req.timeStr != null and req.timeStr != ''">
                and t1.create_time like  concat('%',#{req.timeStr},'%')
            </if>
@@ -119,6 +122,9 @@
            <if test="req.customerName != null and req.customerName != ''">
                and t3.customer_name like  concat('%',#{req.customerName},'%')
            </if>
            <if test="req.productCategory != null and req.productCategory != ''">
                and t2.product_category like  concat('%',#{req.productCategory},'%')
            </if>
            <if test="req.timeStr != null and req.timeStr != ''">
                and t1.create_time like  concat('%',#{req.timeStr},'%')
            </if>
@@ -147,6 +153,9 @@
            <if test="req.supplierName != null and req.supplierName != ''">
                and t2.supplier_name like  concat('%',#{req.supplierName},'%')
            </if>
            <if test="req.productCategory != null and req.productCategory != ''">
                and t2.product_category like  concat('%',#{req.productCategory},'%')
            </if>
            <if test="req.timeStr != null and req.timeStr != ''">
                and t1.create_time like  concat('%',#{req.timeStr},'%')
            </if>
src/main/resources/mapper/production/SalesLedgerProductionAccountingMapper.xml
@@ -48,6 +48,6 @@
            </if>
        </where>
        group by t4.id
        order by t4.update_time desc
        order by t4.scheduling_date desc
    </select>
</mapper>
src/main/resources/mapper/production/SalesLedgerSchedulingMapper.xml
@@ -115,6 +115,6 @@
                AND  T2.scheduling_date &lt;= DATE_FORMAT(#{salesLedgerDto.entryDateEnd},'%Y-%m-%d')
            </if>
        </where>
        order by T2.status asc
        order by T2.scheduling_date desc
    </select>
</mapper>
src/main/resources/mapper/production/SalesLedgerWorkMapper.xml
@@ -54,6 +54,6 @@
                AND  t4.scheduling_date &lt;= DATE_FORMAT(#{salesLedgerDto.entryDateEnd},'%Y-%m-%d')
            </if>
        </where>
        order by t4.update_time desc
        order by t4.scheduling_date desc
    </select>
</mapper>