diff --git a/src/main/java/com/zg/project/wisdom/controller/RkStatisticsController.java b/src/main/java/com/zg/project/wisdom/controller/RkStatisticsController.java index 6cd3e16..9ae0e26 100644 --- a/src/main/java/com/zg/project/wisdom/controller/RkStatisticsController.java +++ b/src/main/java/com/zg/project/wisdom/controller/RkStatisticsController.java @@ -1,188 +1,29 @@ package com.zg.project.wisdom.controller; import com.zg.framework.web.domain.AjaxResult; -import com.zg.project.wisdom.domain.dto.RkInfoQueryDTO; -import com.zg.project.wisdom.domain.vo.*; +import com.zg.project.wisdom.domain.dto.HomeStatQueryDTO; import com.zg.project.wisdom.service.RkStatisticsService; -import com.zg.project.wisdom.service.WarehouseStatService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; -import javax.annotation.Resource; -import javax.servlet.http.HttpServletResponse; -import java.util.List; -import java.util.Map; - @Api(tags = "库存统计") @RestController @RequestMapping("/stat") public class RkStatisticsController { - @Resource + @Autowired private RkStatisticsService rkStatisticsService; - @Resource - private WarehouseStatService warehouseStatService; - - - /** 库龄统计(未出库:>10 / >20 / >30 天),value 为项目数(按 xm_no 去重) */ - @ApiOperation("库龄统计(未出库:>10 / >20 / >30 天)") - @GetMapping("/age") - public AjaxResult ageStats() { - List> stats = rkStatisticsService.getAgeStatsAsList(); - return AjaxResult.success(stats); - } /** - * 仓库-场景库位使用统计(总仓库数、每仓库场景数、每场景库位/使用率/空闲率) - * @return + * 首页统计(一次返回所有模块) */ - @GetMapping("/warehouseScene") - public AjaxResult warehouseScene() { - WarehouseSceneStatsResp resp = warehouseStatService.getWarehouseSceneStats(); - return AjaxResult.success(resp); + @ApiOperation("首页统计") + @PostMapping("/home") + public AjaxResult home(@RequestBody(required = false) HomeStatQueryDTO query) { + return AjaxResult.success(rkStatisticsService.getHomeStatistics(query)); } - /** - * 按仓库查询:场景列表 + 每个场景的可用库位明细 - * 示例:GET /warehouse/positions/available?warehouseCode=CK001 - */ - @ApiOperation("按仓库查询各场景的可用库位(排除未出库占用)") - @GetMapping("/warehouse/available") - public AjaxResult listAvailableByWarehouse(@RequestParam String warehouseCode) { - List data = rkStatisticsService.listAvailableByWarehouse(warehouseCode); - return AjaxResult.success(data); - } - - /** - * 当前库存根据入库类型统计项目数,每个项目的条目数,实际入库总数,金额总和(仅未出库) - */ - @GetMapping("/type/summary") - public AjaxResult typeSummary() { - List list = rkStatisticsService.getTypeSummary(); - return AjaxResult.success(list); - } - - - /** - * 县局汇总(仅未出库,county 非空) - */ - @GetMapping("/county/summary") - public AjaxResult countySummary() { - List list = rkStatisticsService.getCountySummary(); - return AjaxResult.success(list); - } - - /** - * 一个接口:一周天级统计(返回入库+出库)根据供电中心统计 - * - 如果 start/end 都传了,就用传入值; - * - 否则:end=今天,start=本周周一; - */ - @ApiOperation("一周天级统计(入库+出库合并返回)") - @GetMapping("/week/daily") - public AjaxResult weekDaily(@RequestParam(required = false) String start, - @RequestParam(required = false) String end) { - Map data = rkStatisticsService.weekDaily(start, end); - return AjaxResult.success(data); - } - - /** - * 库龄统计(>30天 & >60天):项目数、条目数、总金额 + 明细列表 - */ - @ApiOperation("库龄统计:>30天 & >60天(含汇总与明细)") - @GetMapping("/age/count") - public AjaxResult age3060() { - List> data = rkStatisticsService.getAge3060(); - return AjaxResult.success(data); - } - - @ApiOperation("导出库龄明细(>30天与>60天,合并导出)") - @PostMapping("/age/export") - public void exportAge3060(HttpServletResponse response) { - rkStatisticsService.exportAge3060(response); - } - - /** - * 入库类型饼图数据接口 - * 返回每个入库类型的项目数、条目数、总数量、总金额 - */ - @ApiOperation("入库类型饼图数据") - @GetMapping("/type/pie") - public AjaxResult typePie() { - List list = rkStatisticsService.getTypePie(); - return AjaxResult.success(list); - } - - /** - * 按入库类型统计(带时间范围) - * 统计维度:项目数、条目数、总数量、总金额 - * 时间字段:rk_time(自然日闭区间 [start, end]) - * 参数格式:推荐 yyyy-MM-dd(如 2025-01-01) - */ - @ApiOperation("按入库类型统计(带时间范围:项目数/条目数/总数量/总金额)") - @GetMapping("/type/range") - public AjaxResult typeSummaryRange(@RequestParam(required = false) String start, - @RequestParam(required = false) String end) { - List list = rkStatisticsService.getTypeSummaryByRange(start, end); - return AjaxResult.success(list); - } - - @ApiOperation("按出库类型统计(带时间范围:项目数/条目数/总数量/总金额)") - @GetMapping("/type/out/range") - public AjaxResult outTypeSummaryRange(@RequestParam(required = false) String start, - @RequestParam(required = false) String end) { - List list = rkStatisticsService.getOutTypeSummaryByRange(start, end); - return AjaxResult.success(list); - } - - - @ApiOperation("本月出入库汇总(项目数/条目数/总数量/总金额)") - @GetMapping("/month/summary") - public AjaxResult monthSummary() { - RkMonthInOutSummaryVO vo = rkStatisticsService.getThisMonthInOutSummary(); - return AjaxResult.success(vo); - } - - @ApiOperation("应到未到统计(未到/部分未到)") - @GetMapping("/undelivered") - public AjaxResult undelivered() { - GysJhUndeliveredVO vo = rkStatisticsService.getUndeliveredSummary(); - return AjaxResult.success(vo); - } - - @ApiOperation("当前库存按物资类型统计(项目数/条目数/总数量/总金额)") - @GetMapping("/stock/wlType") - public AjaxResult stockByWlType() { - List list = rkStatisticsService.getCurrentStockByWlType(); - return AjaxResult.success(list); - } - - /** - * 当前库存:入库时间 >30天(项目数 / 条目数 / 总数量 / 总金额) - * 口径:仅统计未删除、未出库(is_chuku=0 或 NULL)、rk_time 非空且 DATEDIFF(CURDATE(), DATE(rk_time)) > 30 的记录 - */ - @ApiOperation("当前库存:入库时间>30天(项目数/条目数/总数量/总金额)") - @GetMapping("/age/gt30") - public AjaxResult ageGt30() { - RkTypePieVO vo = rkStatisticsService.getAgeGt30Summary(); - return AjaxResult.success(vo); - } - - /** - * range: 0=最近一周(7天, 按日);2=最近半年(6个月, 按月) - * 返回:每个时间桶一行(bucket, 入/出库项目数&条目数) - */ - @ApiOperation("出/入库项目数与条目数(按时间桶返回)") - @GetMapping("/io/buckets") - public AjaxResult ioBuckets(@RequestParam Integer range) { - List rows = rkStatisticsService.getIOBuckets(range); - return AjaxResult.success(rows); - } - -// @PostMapping("/statistics") -// public Map statistics(@RequestBody RkInfoQueryDTO dto) { -// // 调用新的合并查询方法 -// return rkStatisticsService.selectStockStatistics(dto); -// } } \ No newline at end of file diff --git a/src/main/java/com/zg/project/wisdom/domain/dto/HomeStatQueryDTO.java b/src/main/java/com/zg/project/wisdom/domain/dto/HomeStatQueryDTO.java new file mode 100644 index 0000000..74f14b3 --- /dev/null +++ b/src/main/java/com/zg/project/wisdom/domain/dto/HomeStatQueryDTO.java @@ -0,0 +1,15 @@ +package com.zg.project.wisdom.domain.dto; + +import lombok.Data; + +import java.util.Date; + +@Data +public class HomeStatQueryDTO { + + /** 开始时间(可空) */ + private Date startDate; + + /** 结束时间(可空) */ + private Date endDate; +} diff --git a/src/main/java/com/zg/project/wisdom/domain/vo/Age3060ResultVO.java b/src/main/java/com/zg/project/wisdom/domain/vo/Age3060ResultVO.java deleted file mode 100644 index 299ca29..0000000 --- a/src/main/java/com/zg/project/wisdom/domain/vo/Age3060ResultVO.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.zg.project.wisdom.domain.vo; - -import lombok.Data; -import java.util.List; - -/** 最终返回结构(汇总 + 明细) */ -@Data -public class Age3060ResultVO { - /** >30 天的汇总 */ - private AgeSummaryVO.Slot gt30; - /** >60 天的汇总 */ - private AgeSummaryVO.Slot gt60; - /** >30 天明细 */ - private List gt30List; - /** >60 天明细 */ - private List gt60List; -} diff --git a/src/main/java/com/zg/project/wisdom/domain/vo/AgeSummaryVO.java b/src/main/java/com/zg/project/wisdom/domain/vo/AgeSummaryVO.java deleted file mode 100644 index fdd8d81..0000000 --- a/src/main/java/com/zg/project/wisdom/domain/vo/AgeSummaryVO.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.zg.project.wisdom.domain.vo; - -import lombok.Data; -import java.math.BigDecimal; - -/** 汇总 VO(包含两个 Slot:gt30 / gt60) */ -@Data -public class AgeSummaryVO { - - @Data - public static class Slot { - /** 仅用于 resultMap 绑定(无业务含义) */ - private Integer dummyId; - /** 项目数(DISTINCT xm_no) */ - private Integer projectCount; - /** 条目数(COUNT(*)) */ - private Integer goodsCount; - /** 总金额(SUM(ht_dj * real_qty)) */ - private BigDecimal sumAmount; - } - - private Slot gt30; - private Slot gt60; -} diff --git a/src/main/java/com/zg/project/wisdom/domain/vo/AuditSignatureReviewVO.java b/src/main/java/com/zg/project/wisdom/domain/vo/AuditSignatureReviewVO.java deleted file mode 100644 index 1716a38..0000000 --- a/src/main/java/com/zg/project/wisdom/domain/vo/AuditSignatureReviewVO.java +++ /dev/null @@ -1,87 +0,0 @@ -package com.zg.project.wisdom.domain.vo; - -import com.zg.framework.aspectj.lang.annotation.Excel; -import com.zg.project.wisdom.domain.AuditSignature; -import lombok.Data; - -import java.util.Date; -import java.util.List; - -/** - * 审核记录封装VO(包含一条审核记录 + 多张现场照片) - */ -@Data -public class AuditSignatureReviewVO { - - /** 主键ID(审核记录的ID) */ - private Long id; - - /** 单据编号 */ - private String billNo; - - /** 入库记录ID(对应rk_info.id) */ - private Long rkId; - - /** 单据类型(0入库,1出库) */ - private String billType; - - /** 审核人ID */ - private String approverId; - - /** 审核人签字图片URL(签字图) */ - private String approverSignUrl; - - /** 审核结果(0通过,1驳回) */ - private String auditResult; - - /** 是否当前记录(1是,0否) */ - private String isCurrent; - - private String ckType; - - private String ckTypeName; - - private String teamCode; - - private String teamName; - - /** 审核时间 */ - private Date signTime; - - /** 审核备注 */ - private String remark; - - /** 创建人 */ - private String createBy; - - /** 创建时间 */ - private Date createTime; - - /** 更新人 */ - private String updateBy; - - /** 更新时间 */ - private Date updateTime; - - /** 逻辑删除标记(0正常,1删除) */ - private String isDelete; - - /** 携带入库信息的现场图片列表 */ - private List scenePhotos; - - /** 入库类型名称(中文) */ - private String rkTypeName; - - /** 所属仓库名称(中文) */ - private String cangkuName; - - /** 物资类型名称(中文) */ - private String wlTypeName; - - /** 理货员名称(原本就是中文) */ - private String lihuoY; - - /** 理货员名称(联查显示用,导出专用) */ - private String lihuoYName; - -} diff --git a/src/main/java/com/zg/project/wisdom/domain/vo/DayCountyStatVO.java b/src/main/java/com/zg/project/wisdom/domain/vo/DayCountyStatVO.java deleted file mode 100644 index 010eb08..0000000 --- a/src/main/java/com/zg/project/wisdom/domain/vo/DayCountyStatVO.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.zg.project.wisdom.domain.vo; - -import lombok.Data; -import java.math.BigDecimal; - -/** 周天级统计(按县局) */ -@Data -public class DayCountyStatVO { - /** - * 日期(如果 SQL 未分日统计,该字段可能为 null) - * 示例:2025-08-19 - */ - private String day; - - /** 县局(若为空或空串会被归类为“未知县局”) */ - private String xj; - - /** 项目数(去重 xm_no 计数) */ - private Integer projectCount; - - /** 条目数(明细记录总数,COUNT(*)) */ - private Integer itemCount; - - /** 数量总和(SUM(real_qty)) */ - private Long totalQty; - - /** 合同金额总和(SUM(ht_dj * real_qty)) */ - private BigDecimal amountHt; - - /** 计划金额总和(仅入库时有值,出库恒为 0) */ - private BigDecimal amountPlan; -} \ No newline at end of file diff --git a/src/main/java/com/zg/project/wisdom/domain/vo/DeliveryBillVO.java b/src/main/java/com/zg/project/wisdom/domain/vo/DeliveryBillVO.java deleted file mode 100644 index 6c95701..0000000 --- a/src/main/java/com/zg/project/wisdom/domain/vo/DeliveryBillVO.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.zg.project.wisdom.domain.vo; - -import com.fasterxml.jackson.annotation.JsonFormat; -import com.zg.project.wisdom.domain.RkInfo; -import lombok.Data; - -import java.io.Serializable; -import java.util.Date; -import java.util.List; - -/** - * 待配送出库单据 VO(1 对多:一个出库单据 + 多条货物明细) - */ -@Data -public class DeliveryBillVO implements Serializable { - - /** 出库单据号(rk_info.bill_no_ck) */ - private String billNoCk; - - /** 领货人(出库理货员) */ - private String ckLihuoY; - - /** 施工队/出库班组 */ - private String teamCode; - - /** 领用时间(出库时间) */ - @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") - private Date lyTime; - - /** 该出库单据下的所有货物明细 */ - private List detailList; -} diff --git a/src/main/java/com/zg/project/wisdom/domain/vo/GysJhUndeliveredVO.java b/src/main/java/com/zg/project/wisdom/domain/vo/GysJhUndeliveredVO.java deleted file mode 100644 index 8bfc16c..0000000 --- a/src/main/java/com/zg/project/wisdom/domain/vo/GysJhUndeliveredVO.java +++ /dev/null @@ -1,13 +0,0 @@ -// com.zg.project.wisdom.domain.vo.GysJhUndeliveredVO -package com.zg.project.wisdom.domain.vo; - -import lombok.Data; - -/** 返回体:未到 + 部分未到 + 合计 */ -@Data -public class GysJhUndeliveredVO { - /** 未到货(status='0') */ - private GysJhUndeliveredSummaryVO undelivered; - /** 部分未到货(status='2') */ - private GysJhUndeliveredSummaryVO partialUndelivered; -} diff --git a/src/main/java/com/zg/project/wisdom/domain/vo/HomeKpiVO.java b/src/main/java/com/zg/project/wisdom/domain/vo/HomeKpiVO.java new file mode 100644 index 0000000..2000cdf --- /dev/null +++ b/src/main/java/com/zg/project/wisdom/domain/vo/HomeKpiVO.java @@ -0,0 +1,30 @@ +package com.zg.project.wisdom.domain.vo; + +import lombok.Data; + +import java.math.BigDecimal; + +/** + * 首页顶部 KPI 统计 + */ +@Data +public class HomeKpiVO { + + /** 月入库条数 */ + private Integer monthInCount; + + /** 月入库项目数 */ + private Integer monthInProjectCount; + + /** 月入库金额 */ + private BigDecimal monthInAmount; + + /** 月出库条数 */ + private Integer monthOutCount; + + /** 月出库项目数 */ + private Integer monthOutProjectCount; + + /** 月出库金额 */ + private BigDecimal monthOutAmount; +} diff --git a/src/main/java/com/zg/project/wisdom/domain/vo/HomeStatVO.java b/src/main/java/com/zg/project/wisdom/domain/vo/HomeStatVO.java new file mode 100644 index 0000000..952ffcd --- /dev/null +++ b/src/main/java/com/zg/project/wisdom/domain/vo/HomeStatVO.java @@ -0,0 +1,27 @@ +package com.zg.project.wisdom.domain.vo; + +import lombok.Data; + +import java.util.List; + +/** + * 首页统计返回 VO(最终版) + */ +@Data +public class HomeStatVO { + + /** 顶部 KPI */ + private HomeKpiVO kpi; + + /** 当前入库类型统计 */ + private List currentInType; + + /** 物资类型统计 */ + private List materialType; + + /** 入库类型统计(时间) */ + private List inTypeByTime; + + /** 出库类型统计(时间) */ + private List outTypeByTime; +} diff --git a/src/main/java/com/zg/project/wisdom/domain/vo/IOBucketVO.java b/src/main/java/com/zg/project/wisdom/domain/vo/IOBucketVO.java deleted file mode 100644 index 319f341..0000000 --- a/src/main/java/com/zg/project/wisdom/domain/vo/IOBucketVO.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.zg.project.wisdom.domain.vo; - -import lombok.Data; - -/** - * 出/入库统计结果 VO - * 每个时间桶(按日/按月)一行 - */ -@Data -public class IOBucketVO { - - /** 时间桶: - * range=0(最近一周):返回 MM-dd; - * range=2(最近半年):返回 yyyy-MM - */ - private String bucket; - - /** 入库项目数 */ - private Integer inProjectCount; - /** 入库条目数 */ - private Integer inItemCount; - /** 出库项目数 */ - private Integer outProjectCount; - /** 出库条目数 */ - private Integer outItemCount; -} \ No newline at end of file diff --git a/src/main/java/com/zg/project/wisdom/domain/vo/PcodeQtyVO.java b/src/main/java/com/zg/project/wisdom/domain/vo/PcodeQtyVO.java deleted file mode 100644 index 5ef7d0f..0000000 --- a/src/main/java/com/zg/project/wisdom/domain/vo/PcodeQtyVO.java +++ /dev/null @@ -1,14 +0,0 @@ -// vo/PcodeQtyVO.java -package com.zg.project.wisdom.domain.vo; - -import java.math.BigDecimal; -import lombok.Data; - -@Data -public class PcodeQtyVO { - /** 库位码 */ - private String pcode; - - /** 在库总数量(real_qty 之和) */ - private BigDecimal totalQty; -} diff --git a/src/main/java/com/zg/project/wisdom/domain/vo/RkAgeDetailVO.java b/src/main/java/com/zg/project/wisdom/domain/vo/RkAgeDetailVO.java deleted file mode 100644 index 5dc5db4..0000000 --- a/src/main/java/com/zg/project/wisdom/domain/vo/RkAgeDetailVO.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.zg.project.wisdom.domain.vo; - -import com.zg.framework.aspectj.lang.annotation.Excel; -import com.fasterxml.jackson.annotation.JsonFormat; -import lombok.Data; - -import java.math.BigDecimal; -import java.util.Date; - -@Data -public class RkAgeDetailVO { - /* ---------- 仅用于导出分组显示,不落库 ---------- */ - @Excel(name = "库龄分组") // “>30天”/“>60天” - private String ageBucket; - - @Excel(name = "ID") - private Long id; - - /** 项目号 / 项目描述 */ - @Excel(name = "项目号") - private String xmNo; - - @Excel(name = "项目描述") - private String xmMs; - - /** 入库时间 & 库龄天数 */ - @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") - @Excel(name = "入库时间", dateFormat = "yyyy-MM-dd HH:mm:ss") - private Date rkTime; - - @Excel(name = "库龄(天)") - private Integer kuLingDays; - - /** 单价、数量、行金额 */ - @Excel(name = "单价") - private BigDecimal htDj; - - @Excel(name = "数量") - private BigDecimal realQty; - - @Excel(name = "行金额") - private BigDecimal amount; - - /** 库位 / 托盘 / 单据号(便于追踪) */ - @Excel(name = "库位") - private String pcode; - - @Excel(name = "托盘") - private String trayCode; - - @Excel(name = "单据号") - private String billNo; -} diff --git a/src/main/java/com/zg/project/wisdom/domain/vo/RkAgeStatVO.java b/src/main/java/com/zg/project/wisdom/domain/vo/RkAgeStatVO.java deleted file mode 100644 index 31a7884..0000000 --- a/src/main/java/com/zg/project/wisdom/domain/vo/RkAgeStatVO.java +++ /dev/null @@ -1,21 +0,0 @@ -// com/zg/project/wisdom/vo/stat/RkAgeStatVO.java -package com.zg.project.wisdom.domain.vo; - -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; - -@Data -@ApiModel(value = "RkAgeStatVO", description = "库龄统计结果(仅未出库)") -public class RkAgeStatVO { - - @ApiModelProperty("大于10天的数量") - private Integer gt10; - - @ApiModelProperty("大于20天的数量") - private Integer gt20; - - @ApiModelProperty("大于30天的数量") - private Integer gt30; - -} diff --git a/src/main/java/com/zg/project/wisdom/domain/vo/RkCkStatisticVO.java b/src/main/java/com/zg/project/wisdom/domain/vo/RkCkStatisticVO.java deleted file mode 100644 index 744321f..0000000 --- a/src/main/java/com/zg/project/wisdom/domain/vo/RkCkStatisticVO.java +++ /dev/null @@ -1,79 +0,0 @@ -package com.zg.project.wisdom.domain.vo; - -import com.zg.framework.aspectj.lang.annotation.Excel; -import lombok.Data; - -import java.io.Serializable; -import java.math.BigDecimal; -import java.util.Date; - -/** - * 出入库统计明细 VO - * 仅用于查询与展示,不参与落库 - */ -@Data -public class RkCkStatisticVO implements Serializable { - - private static final long serialVersionUID = 1L; - - /** 操作类型:入库 / 出库 */ - @Excel(name = "操作类型") - private String operationType; - - /** 详细类型:入库类型名 / 出库类型名 */ - @Excel(name = "详细类型") - private String detailType; - - /** 库存状态(在库 / 已出库 / 借料等) */ - @Excel(name = "库存状态") - private String stockStatus; - - /** 单据号(入库单号或出库单号) */ - @Excel(name = "单据号") - private String billNo; - - /** 物料号 */ - @Excel(name = "物料号") - private String materialCode; - - /** 物料描述 */ - @Excel(name = "物料描述") - private String materialName; - - /** 单位 */ - @Excel(name = "单位") - private String unit; - - /** 数量(实际数量) */ - @Excel(name = "数量") - private BigDecimal quantity; - - /** 项目号 */ - @Excel(name = "项目号") - private String projectCode; - - /** 项目描述 */ - @Excel(name = "项目描述") - private String projectName; - - /** 库位码 */ - @Excel(name = "库位码") - private String locationCode; - - /** 订单编号(SAP 订单号) */ - @Excel(name = "订单编号") - private String orderNo; - - /** 供应商名称 */ - @Excel(name = "供应商名称") - private String supplierName; - - /** 备注 */ - @Excel(name = "备注") - private String remark; - - /** 入库时间(用户操作入库的日期) */ - @Excel(name = "操作时间", dateFormat = "yyyy-MM-dd HH:mm:ss") - private Date operationTime; - -} diff --git a/src/main/java/com/zg/project/wisdom/domain/vo/RkInVO.java b/src/main/java/com/zg/project/wisdom/domain/vo/RkInVO.java deleted file mode 100644 index 8d4e21e..0000000 --- a/src/main/java/com/zg/project/wisdom/domain/vo/RkInVO.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.zg.project.wisdom.domain.vo; - -import lombok.Data; -import java.time.LocalDateTime; - -/** 入库原始数据(用于代码侧分桶) */ -@Data -public class RkInVO { - private String xmNo; - private LocalDateTime rkTime; -} diff --git a/src/main/java/com/zg/project/wisdom/domain/vo/RkMonthInOutSummaryVO.java b/src/main/java/com/zg/project/wisdom/domain/vo/RkMonthInOutSummaryVO.java deleted file mode 100644 index 5163668..0000000 --- a/src/main/java/com/zg/project/wisdom/domain/vo/RkMonthInOutSummaryVO.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.zg.project.wisdom.domain.vo; - -import lombok.Data; - -/** 月度入/出库两段结果 */ -@Data -public class RkMonthInOutSummaryVO { - /** 入库汇总(rk_time) */ - private RkMonthSummaryVO inSummary; - /** 出库汇总(ly_time, is_chuku=1) */ - private RkMonthSummaryVO outSummary; -} \ No newline at end of file diff --git a/src/main/java/com/zg/project/wisdom/domain/vo/RkMonthSummaryVO.java b/src/main/java/com/zg/project/wisdom/domain/vo/RkMonthSummaryVO.java deleted file mode 100644 index c37abef..0000000 --- a/src/main/java/com/zg/project/wisdom/domain/vo/RkMonthSummaryVO.java +++ /dev/null @@ -1,18 +0,0 @@ -// com.zg.project.wisdom.domain.vo.RkMonthSummaryVO -package com.zg.project.wisdom.domain.vo; - -import lombok.Data; -import java.math.BigDecimal; - -/** 月度汇总(项目数/条目数/总数量/总金额) */ -@Data -public class RkMonthSummaryVO { - /** 去重项目数(按 xm_no 去重) */ - private Integer projectCount; - /** 条目数(明细行数) */ - private Integer itemCount; - /** 总数量(real_qty 合计) */ - private Long totalQty; - /** 总金额(ht_dj * real_qty 合计) */ - private BigDecimal amountHt; -} \ No newline at end of file diff --git a/src/main/java/com/zg/project/wisdom/domain/vo/RkOutVO.java b/src/main/java/com/zg/project/wisdom/domain/vo/RkOutVO.java deleted file mode 100644 index cc2a01a..0000000 --- a/src/main/java/com/zg/project/wisdom/domain/vo/RkOutVO.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.zg.project.wisdom.domain.vo; - -import lombok.Data; -import java.time.LocalDateTime; - -/** 出库原始数据(用于代码侧分桶) */ -@Data -public class RkOutVO { - private String xmNoCk; - private String xmNo; - private LocalDateTime lyTime; - private LocalDateTime updateTime; -} diff --git a/src/main/java/com/zg/project/wisdom/domain/vo/RkSubmitResultVO.java b/src/main/java/com/zg/project/wisdom/domain/vo/RkSubmitResultVO.java deleted file mode 100644 index e9dfa29..0000000 --- a/src/main/java/com/zg/project/wisdom/domain/vo/RkSubmitResultVO.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.zg.project.wisdom.domain.vo; - -import lombok.Data; - -import java.util.List; - -/** - * 入库提交返回 VO - * 返回入库单据号、是否需要审核、及托盘信息 - */ -@Data -public class RkSubmitResultVO { - - /** 单据号 */ - private String billNo; - - /** 是否需要审核流程 */ - private boolean needAudit; - - /** 所有库位码 */ - private List pcodeList; - - /** 所有托盘码 */ - private List trayCodeList; -} diff --git a/src/main/java/com/zg/project/wisdom/domain/vo/RkSummaryVO.java b/src/main/java/com/zg/project/wisdom/domain/vo/RkSummaryVO.java deleted file mode 100644 index 5658f42..0000000 --- a/src/main/java/com/zg/project/wisdom/domain/vo/RkSummaryVO.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.zg.project.wisdom.domain.vo; - -import lombok.Data; -import java.math.BigDecimal; - -/** 县局维度汇总结果 */ -@Data -public class RkSummaryVO { - - /** 分组名称(如县局名、入库类型等) */ - private String groupName; - - /** 项目数(去重 xm_no) */ - private Integer projectCount; - - /** 条目总数(COUNT(*)) */ - private Integer goodsCountTotal; - - /** 总金额 = SUM(ht_dj * real_qty) */ - private BigDecimal sumAmount; - - /** 总数量 = SUM(real_qty) */ - private BigDecimal sumQty; -} diff --git a/src/main/java/com/zg/project/wisdom/domain/vo/RkTypePieVO.java b/src/main/java/com/zg/project/wisdom/domain/vo/RkTypePieVO.java deleted file mode 100644 index f112f9f..0000000 --- a/src/main/java/com/zg/project/wisdom/domain/vo/RkTypePieVO.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.zg.project.wisdom.domain.vo; - -import lombok.Data; -import java.math.BigDecimal; - -/** - * 入库类型饼状图统计 VO - * 每个入库类型对应一条记录,用于前端饼状图展示 - */ -@Data -public class RkTypePieVO { - - /** 入库类型编码(stock_in_type.type_code) */ - private String rkTypeCode; - - /** 入库类型名称(stock_in_type.type_name) */ - private String rkTypeName; - - /** 项目数量(去重 xm_no) */ - private Integer projectCount; - - /** 条目总数(COUNT(*)) */ - private Integer goodsCountTotal; - - /** 总数量(SUM real_qty) */ - private BigDecimal sumQty; - - /** 总金额(SUM ht_dj * real_qty) */ - private BigDecimal sumAmount; -} diff --git a/src/main/java/com/zg/project/wisdom/domain/vo/RkTypeProjectDetailVO.java b/src/main/java/com/zg/project/wisdom/domain/vo/RkTypeProjectDetailVO.java deleted file mode 100644 index e9580cc..0000000 --- a/src/main/java/com/zg/project/wisdom/domain/vo/RkTypeProjectDetailVO.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.zg.project.wisdom.domain.vo; - -import lombok.Data; -import java.math.BigDecimal; - -/** - * 入库类型 + 项目 明细VO - * 用于统计每种入库类型下的每个项目: - * - 项目信息 - * - 货物数量 - * - 合同单价合计 - * - 实际入库数量合计 - * - 金额合计 - */ -@Data -public class RkTypeProjectDetailVO { - /** 入库类型(rk_type) */ - private Integer rkType; - /** 项目号(xm_no) */ - private String projectNo; - /** 项目名称/描述(xm_ms) */ - private String projectName; - /** 该项目下的货物条数 */ - private Integer goodsCount; - /** 合同单价合计 */ - private BigDecimal sumHtDj; - /** 实际入库数量合计 */ - private BigDecimal sumRealQty; - /** 金额合计 = ht_dj * real_qty */ - private BigDecimal sumAmount; -} diff --git a/src/main/java/com/zg/project/wisdom/domain/vo/RkTypeProjectGoodsCountVO.java b/src/main/java/com/zg/project/wisdom/domain/vo/RkTypeProjectGoodsCountVO.java deleted file mode 100644 index 0ec6b56..0000000 --- a/src/main/java/com/zg/project/wisdom/domain/vo/RkTypeProjectGoodsCountVO.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.zg.project.wisdom.domain.vo; - -import lombok.Data; - -/** - * 某入库类型下,单个项目的货物条目数 - */ -@Data -public class RkTypeProjectGoodsCountVO { - /** 入库类型(冗余用于归并) */ - private Integer rkType; - - /** 县局,类型统计时可为null */ - private String county; - - /** 项目号(xm_no) */ - private String projectNo; - - /** 项目名称/描述(xm_ms),取一个示例值 */ - private String projectName; - - /** 该项目的货物条目数(COUNT(*)) */ - private Integer goodsCount; -} diff --git a/src/main/java/com/zg/project/wisdom/domain/vo/RkTypeSummaryVO.java b/src/main/java/com/zg/project/wisdom/domain/vo/RkTypeSummaryVO.java deleted file mode 100644 index 76e6701..0000000 --- a/src/main/java/com/zg/project/wisdom/domain/vo/RkTypeSummaryVO.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.zg.project.wisdom.domain.vo; - -import lombok.Data; -import java.math.BigDecimal; -import java.util.List; - - -/** - * 入库类型汇总VO(仅统计未出库 is_chuku = 0) - * 每种入库类型下聚合: - * - projectCount:项目数量(去重xm_no) - * - goodsCountTotal:货物条目总数(记录条数) - * - sumHtDj:合同单价合计 - * - sumRealQty:实际入库数量合计 - * - sumAmount:金额合计 = ht_dj * real_qty - * - avgGoodsPerProject:每项目平均条目数 = goodsCountTotal / projectCount(保留2位小数) - * - projectGoodsCounts:每个项目的“条目数清单”(你要的关键补充) - */ -@Data -public class RkTypeSummaryVO { - /** 入库类型(rk_type) */ - private String rkType; - - /** 县局,类型统计时可为null */ - private String county; - - /** 项目数量(去重xm_no) */ - private Integer projectCount; - - /** 货物条目总数(该类型下的记录条数) */ - private Integer goodsCountTotal; - - /** 合同单价合计 */ - private BigDecimal sumHtDj; - - /** 实际入库数量合计 */ - private BigDecimal sumRealQty; - - /** 金额合计 = ht_dj * real_qty */ - private BigDecimal sumAmount; - - /** 每个项目的条目数清单(仅含条目数;如需金额/数量可再扩展) */ - private List projectGoodsCounts; -} \ No newline at end of file diff --git a/src/main/java/com/zg/project/wisdom/domain/vo/SceneAvailableVO.java b/src/main/java/com/zg/project/wisdom/domain/vo/SceneAvailableVO.java deleted file mode 100644 index f0e34f2..0000000 --- a/src/main/java/com/zg/project/wisdom/domain/vo/SceneAvailableVO.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.zg.project.wisdom.domain.vo; - -import lombok.Data; -import java.util.List; - -/** - * 场景下的可用库位 - */ -@Data -public class SceneAvailableVO { - /** 场景编码(pcde_detail.scene,对应 scene_mapping.scene_code) */ - private String sceneCode; - /** 场景名称(scene_mapping.scene_name) */ - private String sceneName; - /** 可用库位数量 */ - private Integer availableCount; - /** 可用库位明细 */ - private List positions; -} diff --git a/src/main/java/com/zg/project/wisdom/domain/vo/StockStatisticGroupVO.java b/src/main/java/com/zg/project/wisdom/domain/vo/StockStatisticGroupVO.java new file mode 100644 index 0000000..7641543 --- /dev/null +++ b/src/main/java/com/zg/project/wisdom/domain/vo/StockStatisticGroupVO.java @@ -0,0 +1,27 @@ +package com.zg.project.wisdom.domain.vo; + +import lombok.Data; + +import java.math.BigDecimal; + +/** + * 首页分组统计 VO(通用) + */ +@Data +public class StockStatisticGroupVO { + + /** 分组值(类型编码,如 operation_type / wl_type) */ + private String groupValue; + + /** 总金额 */ + private BigDecimal totalAmount; + + /** 使用库位数 */ + private Integer locationCount; + + /** 总数量 */ + private BigDecimal totalQuantity; + + /** 项目数(去重 xm_no) */ + private Integer projectCount; +} diff --git a/src/main/java/com/zg/project/wisdom/domain/vo/StockStatisticVO.java b/src/main/java/com/zg/project/wisdom/domain/vo/StockStatisticVO.java index 1400be4..0e040e5 100644 --- a/src/main/java/com/zg/project/wisdom/domain/vo/StockStatisticVO.java +++ b/src/main/java/com/zg/project/wisdom/domain/vo/StockStatisticVO.java @@ -13,6 +13,9 @@ public class StockStatisticVO { /** 使用库位数量 */ private Integer locationCount; - /** 货物总数量 */ + /** 库存总数量 */ private BigDecimal totalQuantity; + + /** 项目总数(去重 xm_no) */ + private Integer projectCount; } diff --git a/src/main/java/com/zg/project/wisdom/domain/vo/WlTypeStockStatVO.java b/src/main/java/com/zg/project/wisdom/domain/vo/WlTypeStockStatVO.java deleted file mode 100644 index e7b955d..0000000 --- a/src/main/java/com/zg/project/wisdom/domain/vo/WlTypeStockStatVO.java +++ /dev/null @@ -1,20 +0,0 @@ -// com.zg.project.wisdom.domain.vo.WlTypeStockStatVO -package com.zg.project.wisdom.domain.vo; - -import lombok.Data; -import java.math.BigDecimal; - -/** 当前库存-按物资类型统计 */ -@Data -public class WlTypeStockStatVO { - /** 物资类型(wl_type) */ - private String typeName; - /** 去重项目数(按 xm_no) */ - private Integer projectCount; - /** 条目数(明细行数) */ - private Integer itemCount; - /** 总数量(real_qty 合计) */ - private Long totalQty; - /** 总金额(ht_dj * real_qty 合计) */ - private BigDecimal amountHt; -} diff --git a/src/main/java/com/zg/project/wisdom/mapper/RkStatisticsMapper.java b/src/main/java/com/zg/project/wisdom/mapper/RkStatisticsMapper.java index 22329ec..9b03ebf 100644 --- a/src/main/java/com/zg/project/wisdom/mapper/RkStatisticsMapper.java +++ b/src/main/java/com/zg/project/wisdom/mapper/RkStatisticsMapper.java @@ -1,114 +1,35 @@ package com.zg.project.wisdom.mapper; -import com.zg.project.wisdom.domain.vo.*; +import com.zg.project.wisdom.domain.vo.HomeKpiVO; +import com.zg.project.wisdom.domain.vo.StockStatisticGroupVO; +import io.lettuce.core.dynamic.annotation.Param; import org.apache.ibatis.annotations.Mapper; -import org.apache.ibatis.annotations.Param; +import java.util.Date; import java.util.List; -import java.util.Map; @Mapper public interface RkStatisticsMapper { - /** 库龄统计(未出库):按项目数计数(去重 xm_no) */ - RkAgeStatVO selectAgeStats(); + /** 当前入库类型统计 */ + List statCurrentInByOperationType(); - /** - * 入库类型汇总(仅未出库) - * @return 汇总结果列表 - */ - List selectRkTypeSummary(); + /** 当前物资类型统计 */ + List statCurrentByMaterialType(); + /** 入库类型统计(时间) */ + List statInByOperationType( + @Param("startDate") Date startDate, + @Param("endDate") Date endDate + ); - /** - * 按入库类型 + 项目 统计【每项目的条目数】 - * (用于回填到类型汇总的 projectGoodsCounts 中) - */ - List selectProjectGoodsCountByType(); + /** 出库类型统计(时间) */ + List statOutByOperationType( + @Param("startDate") Date startDate, + @Param("endDate") Date endDate + ); - - /** 入库类型汇总(未出库,rk_type 非空) */ - List selectTypeSummary(); - - /** - * 县局汇总(未出库,县局非空) - */ - List selectCountySummary(); - - /** 入库(每天+县局):按 rk_time */ - List selectWeekDailyIn(@Param("startDate") String startDate, - @Param("endDate") String endDate); - - /** 出库(每天+县局):按 ly_time */ - List selectWeekDailyOut(@Param("startDate") String startDate, - @Param("endDate") String endDate); - - /** 汇总(>30 & >60):项目数、条目数、总金额 */ - AgeSummaryVO selectAge3060Summary(); - - /** 明细列表:返回超过 minDays 天的明细(minDays 取 30 或 60) */ - List selectAgeDetails(@Param("minDays") int minDays); - - /** - * 按入库类型统计饼状图数据 - * @return 每个入库类型的项目数、条目数、总数量、总金额 - */ - List selectTypePie(); - - /** - * 按入库类型统计(联查 stock_in_type,时间范围过滤) - * 仅统计未删除、未出库 - */ - List selectTypeSummaryByRange(@Param("start") String start, - @Param("end") String end); - - /** - * 按出库类型统计(时间范围;仅 is_chuku=1) - * 维度:项目数、条目数、总数量、总金额 - */ - List selectOutTypeSummaryByRange(@Param("start") String start, - @Param("end") String end); - - - /** 本月入库汇总(按 rk_time 过滤) */ - RkMonthSummaryVO selectMonthlyInSummary(@Param("start") String start, - @Param("end") String end); - - /** 本月出库汇总(is_chuku=1 且按 ly_time 过滤) */ - RkMonthSummaryVO selectMonthlyOutSummary(@Param("start") String start, - @Param("end") String end); - - - /** 应到未到(status='0') */ - GysJhUndeliveredSummaryVO selectUndelivered(); - - /** 部分未到(status='2') */ - GysJhUndeliveredSummaryVO selectPartialUndelivered(); - - /** 当前库存:按物资类型统计(过滤 wl_type 空/无) */ - List selectCurrentStockByWlType(); - - /** 当前库存:入库时间 >30 天的四项汇总(SQL 聚合计算) */ - RkTypePieVO selectAgeGt30Summary(); - - /** 入库:在 [startTs, endTs) 时间范围内的原始行(仅最小过滤) */ - List selectInRange(@Param("startTs") String startTs, - @Param("endTs") String endTs); - - /** 出库:在 [startTs, endTs) 时间范围内、is_chuku=1 的原始行(仅最小过滤) */ - List selectOutRange(@Param("startTs") String startTs, - @Param("endTs") String endTs); - - /** - * 外层:按场景汇总可用数量,并级联查询可用库位明细(返回 SceneAvailableVO 列表) - */ - List selectAvailableByWarehouse(@Param("warehouseCode") String warehouseCode); - - /** - * 内层:指定仓库 + 场景,查询该场景下的可用库位明细 - */ - List selectAvailablePositionsByWarehouseAndScene( - @Param("warehouseCode") String warehouseCode, - @Param("sceneCode") String sceneCode); + /** 首页 KPI */ + HomeKpiVO statHomeKpi(); } diff --git a/src/main/java/com/zg/project/wisdom/service/RkStatisticsService.java b/src/main/java/com/zg/project/wisdom/service/RkStatisticsService.java index 1435d62..43b9ff8 100644 --- a/src/main/java/com/zg/project/wisdom/service/RkStatisticsService.java +++ b/src/main/java/com/zg/project/wisdom/service/RkStatisticsService.java @@ -1,98 +1,15 @@ package com.zg.project.wisdom.service; -import com.zg.project.wisdom.domain.dto.RkInfoQueryDTO; -import com.zg.project.wisdom.domain.vo.*; - -import javax.servlet.http.HttpServletResponse; -import java.util.List; -import java.util.Map; +import com.zg.project.wisdom.domain.dto.HomeStatQueryDTO; +import com.zg.project.wisdom.domain.vo.HomeStatVO; /** 首页统计服务 */ public interface RkStatisticsService { - /** 库龄统计(仅未出库) */ -// RkAgeStatVO getAgeStats(); - - /** 新增:返回 Map */ - List> getAgeStatsAsList(); - - /** 入库类型汇总(未出库) */ - List getTypeSummary(); /** - * 县局汇总(未出库) + * 首页统计 */ - List getCountySummary(); + HomeStatVO getHomeStatistics(HomeStatQueryDTO query); - - /** - * 一周天级统计(一个接口返回入库+出库) - * @param start 可空(yyyy-MM-dd) - * @param end 可空(yyyy-MM-dd) - * @return { "in": List, "out": List } - */ - Map weekDaily(String start, String end); - - /** - * 库龄统计(>30天 & >60天):项目数、条目数、总金额 + 两个明细列表 - */ - Age3060ResultVO getAge3060Detail(); - - List> getAge3060(); - - /** 导出库龄明细(>30 与 >60 合并导出) */ - void exportAge3060(HttpServletResponse response); - - /** - * 获取入库类型饼状图数据 - * @return 入库类型饼图统计列表 - */ - List getTypePie(); - - /** - * 按入库类型统计(时间范围) - * @param start 开始日期(建议 yyyy-MM-dd) - * @param end 结束日期(建议 yyyy-MM-dd) - * @return 每个入库类型的项目数、条目数、总数量、总金额 - */ - List getTypeSummaryByRange(String start, String end); - - /** - * 按出库类型统计(时间范围) - * 口径:仅统计已出库(is_chuku = 1),排除删除;出库类型非空 - * 时间字段:ly_time(自然日闭区间 [start, end],参数建议 yyyy-MM-dd) - */ - List getOutTypeSummaryByRange(String start, String end); - - /** 本月入/出库汇总(项目数/条目数/总数量/总金额) */ - RkMonthInOutSummaryVO getThisMonthInOutSummary(); - - /** 供应计划:应到未到统计(未到、部分未到、合计) */ - GysJhUndeliveredVO getUndeliveredSummary(); - - /** 当前库存:按物资类型统计 */ - List getCurrentStockByWlType(); - - /** 当前库存 “入库时间 >30 天”的四项汇总 */ - RkTypePieVO getAgeGt30Summary(); - - /** - * range: 0=最近一周(日);2=最近半年(月) - * 返回每个时间桶的一行数据(固定 7 行或 6 行) - */ - List getIOBuckets(Integer range); - - - /** - * 根据仓库编码,返回各场景的可用库位(含数量与明细) - * 规则:排除 rk_info 中未出库(is_chuku=0 或 NULL)的占用库位 - */ - List listAvailableByWarehouse(String warehouseCode); - - /** - * 库存统计 - * @param dto 查询参数 - * @return { "total": 0, "rows": List } - */ -// Map selectStockStatistics(RkInfoQueryDTO dto); } diff --git a/src/main/java/com/zg/project/wisdom/service/impl/RkBillServiceImpl.java b/src/main/java/com/zg/project/wisdom/service/impl/RkBillServiceImpl.java index 1d4b1a1..cc84721 100644 --- a/src/main/java/com/zg/project/wisdom/service/impl/RkBillServiceImpl.java +++ b/src/main/java/com/zg/project/wisdom/service/impl/RkBillServiceImpl.java @@ -498,7 +498,7 @@ public class RkBillServiceImpl implements IRkBillService Date now = DateUtils.getNowDate(); String userId = String.valueOf(SecurityUtils.getUserId()); - // ================== 1. 主单 rk_bill ================== + /* ================== 1. 主单 rk_bill ================== */ RkBill bill = new RkBill(); if (dto.getRkBill() != null) { BeanUtils.copyProperties(dto.getRkBill(), bill); @@ -525,16 +525,14 @@ public class RkBillServiceImpl implements IRkBillService boolean isPreOut = "0".equals(bill.getExecStatus()); - // ===== 借料出库字段 ===== + // 借料出库字段 if ("2".equals(bill.getBizType())) { bill.setBorrowTime(bill.getBorrowTime() != null ? bill.getBorrowTime() : now); - bill.setXmNoCk(bill.getXmNoCk()); - bill.setXmMsCk(bill.getXmMsCk()); } rkBillMapper.insertRkBill(bill); - // ================== 2. 出库处理 ================== + /* ================== 2. 出库处理 ================== */ for (RkInfo outInfo : dto.getRkInfoList()) { if (outInfo.getId() == null) { @@ -556,18 +554,17 @@ public class RkBillServiceImpl implements IRkBillService throw new RuntimeException("出库数量不能大于库存数量,库存ID:" + dbInfo.getId()); } - // ===== ① 非预出库才扣库存 ===== + // ① 非预出库才扣库存 if (!isPreOut) { BigDecimal newQty = remainQty.subtract(outQty); rkInfoMapper.updateRealQtyById(dbInfo.getId(), newQty); - rkInfoMapper.updateIsChukuById( dbInfo.getId(), newQty.compareTo(BigDecimal.ZERO) == 0 ? "1" : "0" ); } - // ===== ② 出库记录(重点:传 outInfo)===== + // ② 写出库记录(已修复 cangku) RkRecord record = buildOutRkRecord(bill, dbInfo, outInfo, outQty, now); record.setExecStatus(isPreOut ? "0" : "1"); @@ -577,6 +574,7 @@ public class RkBillServiceImpl implements IRkBillService return 1; } + private RkRecord buildOutRkRecord( RkBill bill, RkInfo dbInfo, @@ -586,26 +584,29 @@ public class RkBillServiceImpl implements IRkBillService RkRecord record = new RkRecord(); - // ① 库存快照 + /* ① 库存快照 */ BeanUtils.copyProperties(dbInfo, record); record.setId(null); - // ② 本次出库数量 + /* ② 本次出库数量 */ record.setRealQty(outQty); - // ③ 主单上下文 + /* ③ 主单上下文 */ record.setBillNo(bill.getBillNo()); record.setBizType(bill.getBizType()); record.setOperationType(bill.getOperationType()); record.setOperationTime(bill.getOperationTime()); record.setOperator(bill.getOperator()); - record.setCangku(bill.getCangku()); record.setTeamCode(bill.getTeamCode()); - // ===== ★ 关键:备注来自【出库明细 outInfo】===== + /* ================== ✅ 关键修复 ================== */ + // 仓库必须来源于【库存快照】,而不是 bill + record.setCangku(dbInfo.getCangku()); + + /* ④ 备注来自出库明细 */ record.setRemark(outInfo.getRemark()); - // ④ 借料专属字段 + /* ⑤ 借料字段 */ if ("2".equals(bill.getBizType())) { record.setIsBorrowed("1"); record.setBorrowTime(bill.getBorrowTime()); @@ -616,17 +617,17 @@ public class RkBillServiceImpl implements IRkBillService record.setIsBorrowed("0"); } - // ⑤ 状态字段 + /* ⑥ 状态字段 */ record.setIsChuku("1"); record.setHasMoved("0"); record.setIsDelete("0"); record.setExecStatus(bill.getExecStatus()); - // ⑥ 审计字段 + /* ⑦ 审计字段 */ record.setCreateTime(now); record.setCreateBy(bill.getCreateBy()); - // ⑦ 关联库存 + /* ⑧ 关联库存 */ record.setRkInfoId(dbInfo.getId()); record.setRdid(dbInfo.getId()); diff --git a/src/main/java/com/zg/project/wisdom/service/impl/RkStatisticsServiceImpl.java b/src/main/java/com/zg/project/wisdom/service/impl/RkStatisticsServiceImpl.java index 18697a3..7577ffb 100644 --- a/src/main/java/com/zg/project/wisdom/service/impl/RkStatisticsServiceImpl.java +++ b/src/main/java/com/zg/project/wisdom/service/impl/RkStatisticsServiceImpl.java @@ -1,23 +1,13 @@ package com.zg.project.wisdom.service.impl; -import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; -import com.zg.common.exception.ServiceException; -import com.zg.common.utils.DateUtils; -import com.zg.common.utils.StringUtils; -import com.zg.common.utils.poi.ExcelUtil; -import com.zg.project.wisdom.domain.dto.RkInfoQueryDTO; -import com.zg.project.wisdom.domain.vo.*; -import com.zg.project.wisdom.mapper.RkInfoMapper; +import com.zg.project.wisdom.domain.dto.HomeStatQueryDTO; +import com.zg.project.wisdom.domain.vo.HomeStatVO; import com.zg.project.wisdom.mapper.RkStatisticsMapper; import com.zg.project.wisdom.service.RkStatisticsService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import javax.servlet.http.HttpServletResponse; -import java.math.BigDecimal; -import java.time.*; -import java.time.format.DateTimeFormatter; -import java.util.*; +import java.util.Date; @Service public class RkStatisticsServiceImpl implements RkStatisticsService { @@ -25,427 +15,26 @@ public class RkStatisticsServiceImpl implements RkStatisticsService { @Autowired private RkStatisticsMapper rkStatisticsMapper; - @Autowired - private RkInfoMapper rkInfoMapper; - - @Override - public List> getAgeStatsAsList() { - // 这里的 gt10/gt20/gt30 均为“项目数”(COUNT DISTINCT xm_no) - RkAgeStatVO vo = rkStatisticsMapper.selectAgeStats(); + public HomeStatVO getHomeStatistics(HomeStatQueryDTO query) { - List> list = new ArrayList<>(3); - Map m1 = new HashMap<>(); - m1.put("name", ">10天"); - m1.put("value", vo.getGt10()); - list.add(m1); + HomeStatVO vo = new HomeStatVO(); - Map m2 = new HashMap<>(); - m2.put("name", ">20天"); - m2.put("value", vo.getGt20()); - list.add(m2); + // ========== 1. 顶部 KPI ========== + vo.setKpi(rkStatisticsMapper.statHomeKpi()); - Map m3 = new HashMap<>(); - m3.put("name", ">30天"); - m3.put("value", vo.getGt30()); - list.add(m3); + // ========== 2. 当前库存统计 ========== + vo.setCurrentInType(rkStatisticsMapper.statCurrentInByOperationType()); + vo.setMaterialType(rkStatisticsMapper.statCurrentByMaterialType()); - return list; - } - /** - * 库存类型统计(仅未出库) - */ - @Override - public List getTypeSummary() { - List list = rkStatisticsMapper.selectTypeSummary(); - return CollectionUtils.isEmpty(list) ? Collections.emptyList() : list; - } + // ========== 3. 时间维度统计 ========== + Date start = query == null ? null : query.getStartDate(); + Date end = query == null ? null : query.getEndDate(); - /** - * 县局统计(仅未出库) - */ - @Override - public List getCountySummary() { - List list = rkStatisticsMapper.selectCountySummary(); - return CollectionUtils.isEmpty(list) ? Collections.emptyList() : list; - } + vo.setInTypeByTime(rkStatisticsMapper.statInByOperationType(start, end)); + vo.setOutTypeByTime(rkStatisticsMapper.statOutByOperationType(start, end)); - private static final DateTimeFormatter F = DateTimeFormatter.ofPattern("yyyy-MM-dd"); - - @Override - public Map weekDaily(String start, String end) { - // 如果携带了 start 和 end,就直接用;否则:end=今天,start=本周周一 - if (StringUtils.isBlank(start) || StringUtils.isBlank(end)) { - LocalDate today = LocalDate.now(); - LocalDate monday = today.with(DayOfWeek.MONDAY); - start = monday.format(F); - end = today.format(F); - } - - Map ret = new HashMap<>(2); - ret.put("in", rkStatisticsMapper.selectWeekDailyIn(start, end)); - ret.put("out", rkStatisticsMapper.selectWeekDailyOut(start, end)); - return ret; - } - - - @Override - public Age3060ResultVO getAge3060Detail() { - // 1) 汇总(同时返回 >30 / >60 的项目数、条目数、总金额) - AgeSummaryVO summary = rkStatisticsMapper.selectAge3060Summary(); - - // 2) 明细(>30) - List gt30List = rkStatisticsMapper.selectAgeDetails(30); - - // 3) 明细(>60) - List gt60List = rkStatisticsMapper.selectAgeDetails(60); - - // 4) 组装返回 - Age3060ResultVO vo = new Age3060ResultVO(); - vo.setGt30(summary.getGt30()); - vo.setGt60(summary.getGt60()); - vo.setGt30List(gt30List); - vo.setGt60List(gt60List); return vo; } - @Override - public List> getAge3060() { - // 1) 汇总(同时返回 >30 / >60 的项目数、条目数、总金额) - AgeSummaryVO summary = rkStatisticsMapper.selectAge3060Summary(); - - // 2) 用 List 封装成数组结构 - List> list = new ArrayList<>(); - - Map gt30 = new HashMap<>(); - gt30.put("name", ">30天"); - gt30.put("value", summary.getGt30().getGoodsCount()); // 这里取“货物数量”作 value - list.add(gt30); - - Map gt60 = new HashMap<>(); - gt60.put("name", ">60天"); - gt60.put("value", summary.getGt60().getGoodsCount()); - list.add(gt60); - - return list; - } - - - /** - * 导出库龄明细(>30天 与 >60天 合并导出为一张表) - * - 所有业务逻辑均在 Service 层完成 - * - 使用若依 ExcelUtil + @Excel 注解导出 - */ - @Override - public void exportAge3060(HttpServletResponse response) { - // 1) 调用已有统计逻辑 - Age3060ResultVO res = this.getAge3060Detail(); - - // 2) 合并两组明细,加上导出用的分组字段 - List out = new ArrayList<>(); - if (res.getGt30List() != null) { - for (RkAgeDetailVO row : res.getGt30List()) { - normalizeRowForExport(row, ">30天"); - out.add(row); - } - } - if (res.getGt60List() != null) { - for (RkAgeDetailVO row : res.getGt60List()) { - normalizeRowForExport(row, ">60天"); - out.add(row); - } - } - - // 3) 导出 Excel - ExcelUtil util = new ExcelUtil<>(RkAgeDetailVO.class); - util.exportExcel(response, out, "库龄明细"); - } - - private void normalizeRowForExport(RkAgeDetailVO row, String bucket) { - row.setAgeBucket(bucket); - if (row.getAmount() == null) { - BigDecimal dj = row.getHtDj() == null ? BigDecimal.ZERO : row.getHtDj(); - BigDecimal qty = row.getRealQty() == null ? BigDecimal.ZERO : row.getRealQty(); - row.setAmount(dj.multiply(qty)); - } - } - - /** - * 获取入库类型饼状图数据 - */ - @Override - public List getTypePie() { - return rkStatisticsMapper.selectTypePie(); - } - - @Override - public List getTypeSummaryByRange(String start, String end) { - // 基础入参校验(避免全表扫描/人为误操作) - if (StringUtils.isBlank(start) || StringUtils.isBlank(end)) { - throw new ServiceException("start/end 不能为空,建议格式:yyyy-MM-dd"); - } - return rkStatisticsMapper.selectTypeSummaryByRange(start, end); - } - - @Override - public List getOutTypeSummaryByRange(String start, String end) { - if (StringUtils.isBlank(start) || StringUtils.isBlank(end)) { - throw new ServiceException("start/end 不能为空,建议格式:yyyy-MM-dd"); - } - return rkStatisticsMapper.selectOutTypeSummaryByRange(start, end); - } - - private static final DateTimeFormatter DF = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); - @Override - public RkMonthInOutSummaryVO getThisMonthInOutSummary() { - // 本月起止: [YYYY-MM-01 00:00:00, 下月01 00:00:00) - LocalDate firstDay = LocalDate.now().withDayOfMonth(1); - LocalDate nextMonthFirst = firstDay.plusMonths(1); - - String start = firstDay.atStartOfDay().format(DF); - String end = nextMonthFirst.atStartOfDay().format(DF); - - RkMonthSummaryVO inSummary = rkStatisticsMapper.selectMonthlyInSummary(start, end); - RkMonthSummaryVO outSummary = rkStatisticsMapper.selectMonthlyOutSummary(start, end); - - // null 兜底 - if (inSummary == null) { - inSummary = new RkMonthSummaryVO(); - } - if (outSummary == null) { - outSummary = new RkMonthSummaryVO(); - } - - RkMonthInOutSummaryVO vo = new RkMonthInOutSummaryVO(); - vo.setInSummary(inSummary); - vo.setOutSummary(outSummary); - return vo; - } - - - @Override - public GysJhUndeliveredVO getUndeliveredSummary() { - // 分别查询:未到(status=0)、部分未到(status=2) - GysJhUndeliveredSummaryVO undelivered = rkStatisticsMapper.selectUndelivered(); - GysJhUndeliveredSummaryVO partial = rkStatisticsMapper.selectPartialUndelivered(); - - // 对象兜底 - if (undelivered == null) undelivered = new GysJhUndeliveredSummaryVO(); - if (partial == null) partial = new GysJhUndeliveredSummaryVO(); - - // 字段兜底(防止仍有 null 透出) - if (undelivered.getProjectCount() == null) undelivered.setProjectCount(0); - if (undelivered.getItemCount() == null) undelivered.setItemCount(0); - if (undelivered.getTotalQty() == null) undelivered.setTotalQty(0L); - if (undelivered.getAmountPlan() == null) undelivered.setAmountPlan(BigDecimal.ZERO); - - if (partial.getProjectCount() == null) partial.setProjectCount(0); - if (partial.getItemCount() == null) partial.setItemCount(0); - if (partial.getTotalQty() == null) partial.setTotalQty(0L); - if (partial.getAmountPlan() == null) partial.setAmountPlan(BigDecimal.ZERO); - - // 返回 - GysJhUndeliveredVO vo = new GysJhUndeliveredVO(); - vo.setUndelivered(undelivered); - vo.setPartialUndelivered(partial); - return vo; - } - - @Override - public List getCurrentStockByWlType() { - List list = rkStatisticsMapper.selectCurrentStockByWlType(); - return list == null ? Collections.emptyList() : list; - } - - @Override - public RkTypePieVO getAgeGt30Summary() { - RkTypePieVO vo = rkStatisticsMapper.selectAgeGt30Summary(); - if (vo == null) vo = new RkTypePieVO(); - - // 兜底,避免前端拿到 null - if (vo.getProjectCount() == null) vo.setProjectCount(0); - if (vo.getGoodsCountTotal() == null) vo.setGoodsCountTotal(0); - if (vo.getSumQty() == null) vo.setSumQty(BigDecimal.ZERO); - if (vo.getSumAmount() == null) vo.setSumAmount(BigDecimal.ZERO); - - // 本接口不设置 rkTypeCode / rkTypeName - vo.setRkTypeCode(null); - vo.setRkTypeName(null); - return vo; - } - - - private static final DateTimeFormatter TS_FMT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); - private static final DateTimeFormatter DAY_FMT = DateTimeFormatter.ofPattern("MM-dd"); - private static final DateTimeFormatter MON_FMT = DateTimeFormatter.ofPattern("yyyy-MM"); - - @Override - public List getIOBuckets(Integer range) { - if (range == null || (range != 0 && range != 2)) { - throw new IllegalArgumentException("range 仅支持 0(最近一周) 或 2(最近半年)"); - } - - Date now = DateUtils.getNowDate(); - LocalDateTime nowLdt = LocalDateTime.ofInstant(now.toInstant(), ZoneId.systemDefault()); - - if (range == 0) { - // ===== 最近一周(按日),输出 MM-dd ===== - LocalDate endDay = nowLdt.toLocalDate(); - LocalDate startDay = endDay.minusDays(6); - LocalDateTime startTs = startDay.atStartOfDay(); - LocalDateTime endTs = endDay.plusDays(1).atStartOfDay(); - - List inRows = rkStatisticsMapper.selectInRange(startTs.format(TS_FMT), endTs.format(TS_FMT)); - List outRows = rkStatisticsMapper.selectOutRange(startTs.format(TS_FMT), endTs.format(TS_FMT)); - - // 改为以 LocalDate 作为桶键,防止键格式与输出格式不一致导致匹配失败 - LinkedHashMap acc = new LinkedHashMap<>(); - for (int i = 0; i < 7; i++) { - LocalDate d = startDay.plusDays(i); - acc.put(d, new BucketAcc()); - } - - // 入库聚合(按 LocalDate) - for (RkInVO r : inRows) { - if (r.getRkTime() == null) continue; - LocalDate d = r.getRkTime().toLocalDate(); - BucketAcc b = acc.get(d); - if (b == null) continue; - b.inItemCount++; - if (StringUtils.isNotBlank(r.getXmNo())) { - b.inProjects.add(r.getXmNo().trim()); - } - } - - // 出库聚合(按 LocalDate;ly_time 优先,否则 update_time) - for (RkOutVO r : outRows) { - LocalDateTime t = (r.getLyTime() != null) ? r.getLyTime() : r.getUpdateTime(); - if (t == null) continue; - LocalDate d = t.toLocalDate(); - BucketAcc b = acc.get(d); - if (b == null) continue; - b.outItemCount++; - String proj = StringUtils.isNotBlank(r.getXmNoCk()) ? r.getXmNoCk().trim() : r.getXmNo(); - if (StringUtils.isNotBlank(proj)) b.outProjects.add(proj); - } - - ArrayList out = new ArrayList<>(7); - for (Map.Entry e : acc.entrySet()) { - IOBucketVO row = new IOBucketVO(); - row.setBucket(e.getKey().format(DAY_FMT)); // 仅返回 MM-dd - row.setInProjectCount(e.getValue().inProjects.size()); - row.setInItemCount(e.getValue().inItemCount); - row.setOutProjectCount(e.getValue().outProjects.size()); - row.setOutItemCount(e.getValue().outItemCount); - out.add(row); - } - return out; - - } else { - // ===== 最近半年(按月),输出 yyyy-MM ===== - YearMonth endYm = YearMonth.from(nowLdt.toLocalDate()); - YearMonth startYm = endYm.minusMonths(5); - LocalDateTime startTs = startYm.atDay(1).atStartOfDay(); - LocalDateTime endTs = endYm.plusMonths(1).atDay(1).atStartOfDay(); - - List inRows = rkStatisticsMapper.selectInRange(startTs.format(TS_FMT), endTs.format(TS_FMT)); - List outRows = rkStatisticsMapper.selectOutRange(startTs.format(TS_FMT), endTs.format(TS_FMT)); - - LinkedHashMap acc = new LinkedHashMap<>(); - for (int i = 0; i < 6; i++) { - YearMonth ym = startYm.plusMonths(i); - acc.put(ym, new BucketAcc()); - } - - // 入库按月 - for (RkInVO r : inRows) { - if (r.getRkTime() == null) continue; - YearMonth ym = YearMonth.from(r.getRkTime().toLocalDate()); - BucketAcc b = acc.get(ym); - if (b == null) continue; - b.inItemCount++; - if (StringUtils.isNotBlank(r.getXmNo())) { - b.inProjects.add(r.getXmNo().trim()); - } - } - - // 出库按月 - for (RkOutVO r : outRows) { - LocalDateTime t = (r.getLyTime() != null) ? r.getLyTime() : r.getUpdateTime(); - if (t == null) continue; - YearMonth ym = YearMonth.from(t.toLocalDate()); - BucketAcc b = acc.get(ym); - if (b == null) continue; - b.outItemCount++; - String proj = StringUtils.isNotBlank(r.getXmNoCk()) ? r.getXmNoCk().trim() : r.getXmNo(); - if (StringUtils.isNotBlank(proj)) b.outProjects.add(proj); - } - - ArrayList out = new ArrayList<>(6); - for (Map.Entry e : acc.entrySet()) { - IOBucketVO row = new IOBucketVO(); - row.setBucket(e.getKey().format(MON_FMT)); // yyyy-MM - row.setInProjectCount(e.getValue().inProjects.size()); - row.setInItemCount(e.getValue().inItemCount); - row.setOutProjectCount(e.getValue().outProjects.size()); - row.setOutItemCount(e.getValue().outItemCount); - out.add(row); - } - return out; - } - } - - /** 桶内累加器 */ - private static class BucketAcc { - int inItemCount = 0; - int outItemCount = 0; - Set inProjects = new HashSet<>(); - Set outProjects = new HashSet<>(); - } - - - @Override - public List listAvailableByWarehouse(String warehouseCode) { - List list = rkStatisticsMapper.selectAvailableByWarehouse(warehouseCode); - - if (list == null || list.isEmpty()) { - // 没有查到任何数据时,返回一个默认对象 - SceneAvailableVO vo = new SceneAvailableVO(); -// vo.setSceneCode("N/A"); // 默认场景编码 -// vo.setSceneName("无可用场景"); // 默认场景名称 - vo.setAvailableCount(0); // 可用数量为0 - vo.setPositions(new ArrayList<>()); // 空数组 - - list = new ArrayList<>(); - list.add(vo); - } else { - // 保证 positions 不为 null - for (SceneAvailableVO vo : list) { - if (vo.getPositions() == null) { - vo.setPositions(new ArrayList<>()); - } - } - } - return list; - } - -// @Override -// public Map selectStockStatistics(RkInfoQueryDTO query) { -// -// if (query.getIsChuku() == null) { -// query.setIsChuku("0"); // 默认只查在库 -// } -// -// Map result = rkInfoMapper.selectStockStatistics(query); -// -// // 处理空值情况,防止前端拿到 null 报错 -// if (result == null) { -// result = new HashMap<>(); -// } -// result.putIfAbsent("sumMoney", 0); -// result.putIfAbsent("sumQty", 0); -// result.putIfAbsent("pcdeCount", 0); -// -// return result; -// } } diff --git a/src/main/resources/mybatis/wisdom/RkStatisticsMapper.xml b/src/main/resources/mybatis/wisdom/RkStatisticsMapper.xml index 2d00299..3823b33 100644 --- a/src/main/resources/mybatis/wisdom/RkStatisticsMapper.xml +++ b/src/main/resources/mybatis/wisdom/RkStatisticsMapper.xml @@ -2,541 +2,115 @@ - - - SELECT - /* >10 天的项目数(至少一条记录满足 >10 天的 xm_no 个数) */ - COUNT(DISTINCT CASE - WHEN ri.rk_time IS NOT NULL - AND DATEDIFF(CURDATE(), DATE(ri.rk_time)) > 10 - THEN ri.xm_no END) AS gt10, - - /* >20 天的项目数 */ - COUNT(DISTINCT CASE - WHEN ri.rk_time IS NOT NULL - AND DATEDIFF(CURDATE(), DATE(ri.rk_time)) > 20 - THEN ri.xm_no END) AS gt20, - - /* >30 天的项目数 */ - COUNT(DISTINCT CASE - WHEN ri.rk_time IS NOT NULL - AND DATEDIFF(CURDATE(), DATE(ri.rk_time)) > 30 - THEN ri.xm_no END) AS gt30 + ri.operation_type AS groupValue, + IFNULL(SUM(ri.real_qty * ri.ht_dj), 0) AS totalAmount, + COUNT(DISTINCT ri.pcode) AS locationCount, + IFNULL(SUM(ri.real_qty), 0) AS totalQuantity, + COUNT(DISTINCT ri.xm_no) AS projectCount FROM rk_info ri - WHERE ri.is_delete = 0 - AND (ri.is_chuku = 0 OR ri.is_chuku IS NULL) - - - - - - SELECT - ri.rk_type AS rkType, - ri.xm_no AS projectNo, - MAX(ri.xm_ms) AS projectName, - COUNT(*) AS goodsCount + ri.wl_type AS groupValue, + IFNULL(SUM(ri.real_qty * ri.ht_dj), 0) AS totalAmount, + COUNT(DISTINCT ri.pcode) AS locationCount, + IFNULL(SUM(ri.real_qty), 0) AS totalQuantity, + COUNT(DISTINCT ri.xm_no) AS projectCount FROM rk_info ri - WHERE ri.is_delete = 0 + WHERE ri.exec_status = 1 AND ri.is_chuku = 0 - GROUP BY ri.rk_type, ri.xm_no - ORDER BY rkType, projectNo + AND ri.is_delete = 0 + GROUP BY ri.wl_type - - SELECT - sit.type_name AS groupName, - COUNT(DISTINCT ri.xm_no) AS projectCount, - COUNT(*) AS goodsCountTotal, - COALESCE(SUM(COALESCE(ri.real_qty, 0)), 0) AS sumQty, - COALESCE(SUM(COALESCE(ri.ht_dj, 0) * COALESCE(ri.real_qty, 0)), 0) AS sumAmount + ri.operation_type AS groupValue, + IFNULL(SUM(ri.real_qty * ri.ht_dj), 0) AS totalAmount, + COUNT(DISTINCT ri.pcode) AS locationCount, + IFNULL(SUM(ri.real_qty), 0) AS totalQuantity, + COUNT(DISTINCT ri.xm_no) AS projectCount FROM rk_info ri - LEFT JOIN stock_in_type sit - ON ri.rk_type = sit.type_code - WHERE ri.is_delete = 0 - AND ri.is_chuku = 0 - -- 入库类型过滤:剔除 NULL / 空串 / '无' - AND ri.rk_type IS NOT NULL - AND TRIM(ri.rk_type) <> '' - AND ri.rk_type <> '无' - -- 名称做一层过滤,避免出现“无”或空的分组 - AND sit.type_name IS NOT NULL - AND TRIM(sit.type_name) <> '' - AND sit.type_name <> '无' - GROUP BY sit.type_name - ORDER BY groupName - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - SELECT - COALESCE(sit.type_code, ri.rk_type) AS rkTypeCode, - COALESCE(sit.type_name, ri.rk_type) AS rkTypeName, - COUNT(DISTINCT ri.xm_no) AS projectCount, - COUNT(*) AS goodsCountTotal, - COALESCE(SUM(COALESCE(ri.real_qty, 0)), 0) AS sumQty, - COALESCE(SUM(COALESCE(ri.ht_dj, 0) * COALESCE(ri.real_qty, 0)), 0) AS sumAmount + ri.operation_type AS groupValue, + IFNULL(SUM(ri.real_qty * ri.ht_dj), 0) AS totalAmount, + COUNT(DISTINCT ri.pcode) AS locationCount, + IFNULL(SUM(ri.real_qty), 0) AS totalQuantity, + COUNT(DISTINCT ri.xm_no) AS projectCount FROM rk_info ri - LEFT JOIN stock_in_type sit - ON ri.rk_type = sit.type_code - WHERE ri.is_delete = 0 - AND (ri.is_chuku = 0 OR ri.is_chuku IS NULL) -- 当前库存口径(保持你原条件) - -- 入库类型过滤:剔除 NULL / 空串 / '无' - AND ri.rk_type IS NOT NULL - AND TRIM(ri.rk_type) <> '' - AND ri.rk_type <> '无' - -- 若字典表匹配到了名称且名称为“无”,也剔除;未匹配(NULL)则保留 - AND (sit.type_name IS NULL OR (TRIM(sit.type_name) <> '' AND sit.type_name <> '无')) - -- 时间范围:闭区间 [start, end] - AND ri.rk_time >= #{start} - AND ri.rk_time < DATE_ADD(#{end}, INTERVAL 1 DAY) - GROUP BY COALESCE(sit.type_code, ri.rk_type), COALESCE(sit.type_name, ri.rk_type) - ORDER BY sumAmount DESC - ]]> - + WHERE ri.exec_status = 1 + AND ri.is_chuku = 1 + AND ri.is_delete = 0 + + AND ri.operation_time =]]> #{startDate} + + + AND ri.operation_time #{endDate} + + GROUP BY ri.operation_type + + + - '' - AND ri.ck_type <> '无' - AND (sot.type_name IS NULL OR TRIM(sot.type_name) <> '无') - -- 时间范围:闭区间 [start, end] - AND ri.ly_time >= #{start} - AND ri.ly_time < DATE_ADD(#{end}, INTERVAL 1 DAY) - GROUP BY COALESCE(sot.type_code, ri.ck_type), COALESCE(sot.type_name, ri.ck_type) - ORDER BY sumAmount DESC - ]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -