src/main/java/com/ruoyi/procurementrecord/controller/ProcurementRecordController.java
@@ -80,6 +80,11 @@ IPage<ProcurementPageDtoCopy> result =procurementRecordService.listPageCopy(page, procurementDto); return AjaxResult.success(result); } @GetMapping("/getReportList") @Log(title = "库存报表查询", businessType = BusinessType.OTHER) public AjaxResult getReportList(Page page, ProcurementPageDto procurementDto) { return AjaxResult.success(procurementRecordService.getReportList(page, procurementDto)); } /** * 导出 src/main/java/com/ruoyi/procurementrecord/dto/ProcurementDto.java
@@ -57,6 +57,11 @@ private BigDecimal quantity; /** * 最低库存数量 */ @Excel(name = "最低库存数量") private BigDecimal minStock; /** * 待入库数量 */ @Excel(name = "待入库数量") src/main/java/com/ruoyi/procurementrecord/dto/ProcurementPageDto.java
@@ -1,10 +1,13 @@ package com.ruoyi.procurementrecord.dto; import com.fasterxml.jackson.annotation.JsonFormat; import com.ruoyi.framework.aspectj.lang.annotation.Excel; import lombok.Data; import org.springframework.format.annotation.DateTimeFormat; import java.math.BigDecimal; import java.time.LocalDate; import java.time.LocalDateTime; /** @@ -112,5 +115,35 @@ */ @Excel(name = "不含税总价") private BigDecimal taxExclusiveTotalPrice; /** * 报表日报 */ @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") @DateTimeFormat(pattern = "yyyy-MM-dd") private LocalDate reportDate; /** * 报表月报 */ @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") @DateTimeFormat(pattern = "yyyy-MM-dd") private LocalDate startMonth; /** * 报表月报 */ @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") @DateTimeFormat(pattern = "yyyy-MM-dd") private LocalDate endMonth; /** * 报表月报 */ @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") @DateTimeFormat(pattern = "yyyy-MM-dd") private LocalDate startDate; /** * 报表月报 */ @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") @DateTimeFormat(pattern = "yyyy-MM-dd") private LocalDate endDate; } src/main/java/com/ruoyi/procurementrecord/dto/ProcurementPageDtoCopy.java
@@ -5,6 +5,7 @@ import lombok.Data; import java.math.BigDecimal; import java.time.LocalDate; import java.time.LocalDateTime; /** @@ -43,7 +44,11 @@ @Excel(name = "待出库数量") private BigDecimal inboundNum0; /** * 最低库存数量 */ @Excel(name = "最低库存数量") private BigDecimal minStock; /** * 出入库时间 */ @@ -124,5 +129,35 @@ */ @Excel(name = "不含税总价") private BigDecimal taxExclusiveTotalPrice; /** * 报表日报 */ @Excel(name = "报表日报") @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") private LocalDate reportDate; /** * 报表月报 */ @Excel(name = "报表月报开始时间") @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") private LocalDate startMonth; /** * 报表月报 */ @Excel(name = "报表月报结束时间") @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") private LocalDate endMonth; /** * 报表月报 */ @Excel(name = "报表作业开始时间") @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") private LocalDate startDate; /** * 报表月报 */ @Excel(name = "报表作业结束时间") @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") private LocalDate endDate; } src/main/java/com/ruoyi/procurementrecord/pojo/ProcurementRecordStorage.java
@@ -35,12 +35,17 @@ * 入库数量 */ private BigDecimal inboundNum; // /** // * 最低库存数量 // */ // private BigDecimal minStock; /** * 入库用户 */ private String createBy; /** * 入库用户id */ src/main/java/com/ruoyi/procurementrecord/service/ProcurementRecordService.java
@@ -8,6 +8,7 @@ import javax.servlet.http.HttpServletResponse; import java.util.List; import java.util.Map; /** * @author :yys @@ -31,4 +32,6 @@ int updateManagement(ProcurementManagementUpdateDto procurementDto); void exportCopy(HttpServletResponse response); Map<String, Object> getReportList(Page page, ProcurementPageDto procurementDto); } src/main/java/com/ruoyi/procurementrecord/service/impl/ProcurementRecordServiceImpl.java
@@ -4,7 +4,6 @@ import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.common.utils.DateUtils; import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.framework.security.LoginUser; @@ -17,7 +16,6 @@ import com.ruoyi.project.system.domain.SysUser; import com.ruoyi.project.system.mapper.SysUserMapper; import com.ruoyi.sales.mapper.SalesLedgerProductMapper; import com.ruoyi.sales.pojo.SalesLedgerProduct; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -25,9 +23,10 @@ import javax.servlet.http.HttpServletResponse; import java.math.BigDecimal; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.List; import java.util.*; import java.util.stream.Collectors; /** @@ -231,6 +230,104 @@ } @Override public Map<String, Object> getReportList(Page page, ProcurementPageDto procurementDto) { // 构建报表数据结构 Map<String, Object> reportData = new HashMap<>(); // 2. 构建图表数据 Map<String, Object> chartData = new HashMap<>(); IPage<ProcurementPageDtoCopy> procurementPageDtoCopyIPage = procurementRecordMapper.listPageCopy(page, procurementDto); List<ProcurementPageDtoCopy> procurementPageDtoCopyList = procurementPageDtoCopyIPage.getRecords(); // 计算待入库数量 reportData.put("tableData", procurementPageDtoCopyList); // 查询采购记录已入库数量 List<Integer> collect = procurementPageDtoCopyList.stream().map(ProcurementPageDtoCopy::getId).collect(Collectors.toList()); if(CollectionUtils.isEmpty(collect)){ return reportData; } LambdaQueryWrapper<ProcurementRecordOut> procurementRecordLambdaQueryWrapper = new LambdaQueryWrapper<>(); procurementRecordLambdaQueryWrapper.in(ProcurementRecordOut::getProcurementRecordStorageId, collect); List<ProcurementRecordOut> procurementRecords = procurementRecordOutMapper.selectList(procurementRecordLambdaQueryWrapper); if(CollectionUtils.isEmpty( procurementRecords)){ return reportData; } int totalIn =0; int totalOut =0; int currentStock =0; int turnoverRate =0; List<String> dates = new ArrayList<>(); List<Integer> values = new ArrayList<>(); List<String> comparisonDates = new ArrayList<>(); List<Integer> inValues = new ArrayList<>(); List<Integer> outValues = new ArrayList<>(); // 定义日期格式化器,指定为yyyy-MM-dd格式 DateTimeFormatter dateFormatter = DateTimeFormatter.ISO_LOCAL_DATE; for (ProcurementPageDtoCopy dto : procurementPageDtoCopyList) { dates.add(dto.getCreateTime().format(dateFormatter)); comparisonDates.add(dto.getCreateTime().format(dateFormatter)); // 根据采购台账ID筛选对应的出库记录 List<ProcurementRecordOut> collect1 = procurementRecords.stream() .filter(ProcurementRecordOut -> ProcurementRecordOut.getProcurementRecordStorageId().equals(dto.getId())) .collect(Collectors.toList()); // 如果没有相关的出库记录,跳过该条数据 if(CollectionUtils.isEmpty(collect1)){ dto.setInboundNum0(dto.getInboundNum()); continue; } // 计算已出库数量总和,并设置待出库数量 BigDecimal totalInboundNum = collect1.stream() .map(ProcurementRecordOut::getInboundNum) .reduce(BigDecimal.ZERO, BigDecimal::add); // 待出库数量 = 总数量 - 已出库数量 dto.setInboundNum0(dto.getInboundNum().subtract(totalInboundNum)); // 计算总入库数量 totalIn += dto.getInboundNum().intValue(); inValues.add(totalIn); // 计算总出库数量 totalOut += totalInboundNum.intValue(); outValues.add(totalOut); // 计算当前库存 currentStock += dto.getInboundNum().intValue() - totalInboundNum.intValue(); values.add(currentStock); // 计算周转率 if(totalIn > 0){ turnoverRate = totalOut * 100 / totalIn; } } // 1. 构建汇总数据 Map<String, Object> summary = new HashMap<>(); summary.put("totalIn", totalIn); // 总入库量,实际应从数据计算 summary.put("totalOut", totalOut); // 总出库量,实际应从数据计算 summary.put("currentStock", currentStock); // 当前库存量,实际应从数据计算 summary.put("turnoverRate", turnoverRate); // 周转率,实际应从数据计算 reportData.put("summary", summary); // 2. 构建图表数据 // Map<String, Object> chartData = new HashMap<>(); // List<String> dates = Arrays.asList("2025-09-15", "2025-09-16", "2025-09-17", "2025-09-18", "2025-09-19"); // List<Integer> values = Arrays.asList(300, 350, 400, 380, 420); chartData.put("dates", dates); chartData.put("values", values); chartData.put("comparisonDates", comparisonDates); // 实际应从数据计算 chartData.put("inValues", inValues); // 实际应从数据计算 chartData.put("outValues", outValues); // 实际应从数据计算 reportData.put("chartData", chartData); // 3. 设置表格数据 reportData.put("tableData", procurementPageDtoCopyList); return reportData; } @Override public int add(ProcurementAddDto procurementDto) { LoginUser loginUser = SecurityUtils.getLoginUser(); // 批量新增 src/main/resources/mapper/procurementrecord/ProcurementRecordMapper.xml
@@ -11,6 +11,7 @@ t2.specification_model, t2.unit, t2.quantity, t2.min_stock, t2.quantity as quantity0, t2.tax_rate, t2.tax_inclusive_unit_price, @@ -89,6 +90,7 @@ t1.create_user, t2.specification_model, t2.unit, t2.min_stock, t2.tax_rate, t2.tax_inclusive_unit_price, t2.tax_inclusive_total_price, @@ -107,6 +109,21 @@ <if test="req.supplierName != null and req.supplierName != ''"> and t3.supplier_name like concat('%',#{req.supplierName},'%') </if> <if test="req.reportDate != null"> and t1.create_time >= #{req.reportDate} and t1.create_time < DATE_ADD(#{req.reportDate}, INTERVAL 1 DAY) </if> <if test="req.startMonth != null"> and t1.create_time >= #{req.startMonth} </if> <if test="req.endMonth != null"> and t1.create_time <= #{req.endMonth} </if> <if test="req.startDate != null"> and t1.create_time >= #{req.startDate} </if> <if test="req.endDate != null"> and t1.create_time <= #{req.endDate} </if> </where> </select> <select id="listCopy" resultType="com.ruoyi.procurementrecord.dto.ProcurementPageDtoCopy">