xucaiqin 19 時間 前
コミット
4c21260e68
17 ファイル変更1136 行追加1 行削除
  1. 1 1
      sckw-common/sckw-common-remote/src/main/java/com/sckw/remote/annotation/SckwRemoteApplication.java
  2. 138 0
      sckw-modules/sckw-report/src/main/java/com/sckw/report/controller/KwrReportController.java
  3. 61 0
      sckw-modules/sckw-report/src/main/java/com/sckw/report/model/export/KwrCustomLedgerExport.java
  4. 52 0
      sckw-modules/sckw-report/src/main/java/com/sckw/report/model/export/KwrDailySummaryExport.java
  5. 46 0
      sckw-modules/sckw-report/src/main/java/com/sckw/report/model/export/KwrMonthLedgerExport.java
  6. 64 0
      sckw-modules/sckw-report/src/main/java/com/sckw/report/model/export/KwrTaskListExport.java
  7. 14 0
      sckw-modules/sckw-report/src/main/java/com/sckw/report/model/query/KwrDailySummaryQuery.java
  8. 51 0
      sckw-modules/sckw-report/src/main/java/com/sckw/report/model/query/KwrRecordOrderBaseQuery.java
  9. 14 0
      sckw-modules/sckw-report/src/main/java/com/sckw/report/model/query/KwrTaskListQuery.java
  10. 50 0
      sckw-modules/sckw-report/src/main/java/com/sckw/report/model/vo/KwrDailySummaryRowVo.java
  11. 26 0
      sckw-modules/sckw-report/src/main/java/com/sckw/report/model/vo/KwrFilterOptionsVo.java
  12. 17 0
      sckw-modules/sckw-report/src/main/java/com/sckw/report/model/vo/KwrLedgerSummaryVo.java
  13. 44 0
      sckw-modules/sckw-report/src/main/java/com/sckw/report/model/vo/KwrMonthLedgerRowVo.java
  14. 19 0
      sckw-modules/sckw-report/src/main/java/com/sckw/report/model/vo/KwrSelectOptionVo.java
  15. 47 0
      sckw-modules/sckw-report/src/main/java/com/sckw/report/service/KwrReportService.java
  16. 489 0
      sckw-modules/sckw-report/src/main/java/com/sckw/report/service/impl/KwrReportServiceImpl.java
  17. 3 0
      sckw-modules/sckw-report/src/main/java/com/sckw/report/task/OrderTask.java

+ 1 - 1
sckw-common/sckw-common-remote/src/main/java/com/sckw/remote/annotation/SckwRemoteApplication.java

@@ -12,6 +12,6 @@ import java.lang.annotation.*;
 @Inherited
 @EnableDubbo
 @EnableFeignClients({"com.sckw.*.api.feign"})
-@ComponentScan(basePackages = {"com.sckw.message.consumer","com.sckw.order","com.sckw.file.config", "com.sckw.payment.config", "com.sckw.fleet.config", "com.sckw.remote.filter", "com.sckw.*.dao","com.sckw.*.controller", "com.sckw.*.service", "com.sckw.*.repository", "com.sckw.*.dubbo", "com.sckw.*.model", "com.sckw.transport.*", "com.sckw.*.serivce","com.sckw.transport.config","com.sckw.contract.config"})
+@ComponentScan(basePackages = {"com.sckw.message.consumer","com.sckw.report","com.sckw.order","com.sckw.file.config", "com.sckw.payment.config", "com.sckw.fleet.config", "com.sckw.remote.filter", "com.sckw.*.dao","com.sckw.*.controller", "com.sckw.*.service", "com.sckw.*.repository", "com.sckw.*.dubbo", "com.sckw.*.model", "com.sckw.transport.*", "com.sckw.*.serivce","com.sckw.transport.config","com.sckw.contract.config"})
 public @interface SckwRemoteApplication {
 }

+ 138 - 0
sckw-modules/sckw-report/src/main/java/com/sckw/report/controller/KwrReportController.java

@@ -0,0 +1,138 @@
+package com.sckw.report.controller;
+
+import com.sckw.core.exception.CustomPromptException;
+import com.sckw.core.web.constant.HttpStatus;
+import com.sckw.core.web.response.BaseResult;
+import com.sckw.core.web.response.result.PageDataResult;
+import com.sckw.excel.utils.ExcelUtil;
+import com.sckw.report.entity.KwrRecordOrder;
+import com.sckw.report.model.export.KwrCustomLedgerExport;
+import com.sckw.report.model.export.KwrDailySummaryExport;
+import com.sckw.report.model.export.KwrMonthLedgerExport;
+import com.sckw.report.model.export.KwrTaskListExport;
+import com.sckw.report.model.query.KwrDailySummaryQuery;
+import com.sckw.report.model.query.KwrRecordOrderBaseQuery;
+import com.sckw.report.model.query.KwrTaskListQuery;
+import com.sckw.report.model.vo.KwrDailySummaryRowVo;
+import com.sckw.report.model.vo.KwrFilterOptionsVo;
+import com.sckw.report.model.vo.KwrLedgerSummaryVo;
+import com.sckw.report.model.vo.KwrMonthLedgerRowVo;
+import com.sckw.report.service.KwrReportService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.validation.Valid;
+import lombok.AllArgsConstructor;
+import org.springframework.http.MediaType;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+@AllArgsConstructor
+@RestController
+@RequestMapping("/kwrReport")
+@Tag(name = "统计报表", description = "过磅台账/每日汇总/任务清单")
+public class KwrReportController {
+
+    private final KwrReportService kwrReportService;
+
+    @GetMapping("/options")
+    @Operation(summary = "筛选项下拉数据")
+    public BaseResult<KwrFilterOptionsVo> options() {
+        return BaseResult.success(kwrReportService.filterOptions());
+    }
+
+    @PostMapping("/custom/page")
+    @Operation(summary = "自定义台账-分页")
+    public BaseResult<PageDataResult<KwrRecordOrder>> customPage(@RequestBody @Valid KwrRecordOrderBaseQuery query) {
+        return BaseResult.success(kwrReportService.customLedgerPage(query));
+    }
+
+    @PostMapping("/custom/summary")
+    @Operation(summary = "自定义台账-汇总")
+    public BaseResult<KwrLedgerSummaryVo> customSummary(@RequestBody @Valid KwrRecordOrderBaseQuery query) {
+        return BaseResult.success(kwrReportService.customLedgerSummary(query));
+    }
+
+    @PostMapping(value = "/custom/export", produces = MediaType.APPLICATION_JSON_VALUE)
+    @Operation(summary = "自定义台账-导出")
+    public void customExport(@RequestBody @Validated KwrRecordOrderBaseQuery query, HttpServletResponse response) {
+        List<KwrCustomLedgerExport> list = kwrReportService.customLedgerExport(query);
+        if (list == null || list.isEmpty()) {
+            throw new CustomPromptException(HttpStatus.SUCCESS_CODE, "暂无数据,请确认");
+        }
+        ExcelUtil.downData(response, KwrCustomLedgerExport.class, list);
+    }
+
+    @PostMapping("/month/page")
+    @Operation(summary = "月台账-分页")
+    public BaseResult<PageDataResult<KwrMonthLedgerRowVo>> monthPage(@RequestBody @Valid KwrRecordOrderBaseQuery query) {
+        return BaseResult.success(kwrReportService.monthLedgerPage(query));
+    }
+
+    @PostMapping("/month/summary")
+    @Operation(summary = "月台账-汇总")
+    public BaseResult<KwrMonthLedgerRowVo> monthSummary(@RequestBody @Valid KwrRecordOrderBaseQuery query) {
+        return BaseResult.success(kwrReportService.monthLedgerTotal(query));
+    }
+
+    @PostMapping(value = "/month/export", produces = MediaType.APPLICATION_JSON_VALUE)
+    @Operation(summary = "月台账-导出")
+    public void monthExport(@RequestBody @Validated KwrRecordOrderBaseQuery query, HttpServletResponse response) {
+        List<KwrMonthLedgerExport> list = kwrReportService.monthLedgerExport(query);
+        if (list == null || list.isEmpty()) {
+            throw new CustomPromptException(HttpStatus.SUCCESS_CODE, "暂无数据,请确认");
+        }
+        ExcelUtil.downData(response, KwrMonthLedgerExport.class, list);
+    }
+
+    @PostMapping("/daily/page")
+    @Operation(summary = "每日汇总-分页")
+    public BaseResult<PageDataResult<KwrDailySummaryRowVo>> dailyPage(@RequestBody @Valid KwrDailySummaryQuery query) {
+        return BaseResult.success(kwrReportService.dailySummaryPage(query));
+    }
+
+    @PostMapping("/daily/summary")
+    @Operation(summary = "每日汇总-汇总")
+    public BaseResult<KwrLedgerSummaryVo> dailySummary(@RequestBody @Valid KwrDailySummaryQuery query) {
+        return BaseResult.success(kwrReportService.dailySummaryTotal(query));
+    }
+
+    @PostMapping(value = "/daily/export", produces = MediaType.APPLICATION_JSON_VALUE)
+    @Operation(summary = "每日汇总-导出")
+    public void dailyExport(@RequestBody @Validated KwrDailySummaryQuery query, HttpServletResponse response) {
+        List<KwrDailySummaryExport> list = kwrReportService.dailySummaryExport(query);
+        if (list == null || list.isEmpty()) {
+            throw new CustomPromptException(HttpStatus.SUCCESS_CODE, "暂无数据,请确认");
+        }
+        ExcelUtil.downData(response, KwrDailySummaryExport.class, list);
+    }
+
+    @PostMapping("/task/page")
+    @Operation(summary = "任务清单-分页")
+    public BaseResult<PageDataResult<KwrRecordOrder>> taskPage(@RequestBody @Valid KwrTaskListQuery query) {
+        return BaseResult.success(kwrReportService.taskListPage(query));
+    }
+
+    @PostMapping("/task/summary")
+    @Operation(summary = "任务清单-汇总")
+    public BaseResult<KwrLedgerSummaryVo> taskSummary(@RequestBody @Valid KwrTaskListQuery query) {
+        return BaseResult.success(kwrReportService.taskListTotal(query));
+    }
+
+    @PostMapping(value = "/task/export", produces = MediaType.APPLICATION_JSON_VALUE)
+    @Operation(summary = "任务清单-导出")
+    public void taskExport(@RequestBody @Validated KwrTaskListQuery query, HttpServletResponse response) {
+        List<KwrTaskListExport> list = kwrReportService.taskListExport(query);
+        if (list == null || list.isEmpty()) {
+            throw new CustomPromptException(HttpStatus.SUCCESS_CODE, "暂无数据,请确认");
+        }
+        ExcelUtil.downData(response, KwrTaskListExport.class, list);
+    }
+}
+

+ 61 - 0
sckw-modules/sckw-report/src/main/java/com/sckw/report/model/export/KwrCustomLedgerExport.java

@@ -0,0 +1,61 @@
+package com.sckw.report.model.export;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.sckw.excel.annotation.ExcelContext;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+@Data
+@ExcelContext(fileName = "过磅台账-自定义台账", sheetName = "自定义台账")
+public class KwrCustomLedgerExport {
+
+    @ExcelProperty("商品")
+    private String goodsName;
+
+    @ExcelProperty("类别")
+    private String goodsTypeName;
+
+    @ExcelProperty("规格")
+    private String goodsSpecName;
+
+    @ExcelProperty("客户")
+    private String proEntName;
+
+    @ExcelProperty("订单号")
+    private String tOrderNo;
+
+    @ExcelProperty("运单号")
+    private String wOrderNo;
+
+    @ExcelProperty("供应单位")
+    private String supEntName;
+
+    @ExcelProperty("代理单位")
+    private String agentEntName;
+
+    @ExcelProperty("装货地址")
+    private String loadAddress;
+
+    @ExcelProperty("卸货地址")
+    private String unloadAddress;
+
+    @ExcelProperty("完成时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private LocalDateTime successTime;
+
+    @ExcelProperty("车牌号")
+    private String truckNo;
+
+    @ExcelProperty("毛重(吨)")
+    private BigDecimal grossAmount;
+
+    @ExcelProperty("皮重(吨)")
+    private BigDecimal tareAmount;
+
+    @ExcelProperty("净重(吨)")
+    private BigDecimal netAmount;
+}
+

+ 52 - 0
sckw-modules/sckw-report/src/main/java/com/sckw/report/model/export/KwrDailySummaryExport.java

@@ -0,0 +1,52 @@
+package com.sckw.report.model.export;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.sckw.excel.annotation.ExcelContext;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+@Data
+@ExcelContext(fileName = "过磅台账-每日汇总", sheetName = "每日汇总")
+public class KwrDailySummaryExport {
+
+    @ExcelProperty("日期")
+    private String day;
+
+    @ExcelProperty("客户/代理单位")
+    private String targetEntName;
+
+    @ExcelProperty("商品名称")
+    private String goodsName;
+
+    @ExcelProperty("类别")
+    private String goodsTypeName;
+
+    @ExcelProperty("规格")
+    private String goodsSpecName;
+
+    @ExcelProperty("车次")
+    private Long truckCount;
+
+    @ExcelProperty("异常车次")
+    private Long abnormalTruckCount;
+
+    @ExcelProperty("异常占比(%)")
+    private BigDecimal abnormalRate;
+
+    @ExcelProperty("皮重(吨)")
+    private BigDecimal tareAmountTotal;
+
+    @ExcelProperty("毛重(吨)")
+    private BigDecimal grossAmountTotal;
+
+    @ExcelProperty("净重(吨)")
+    private BigDecimal netAmountTotal;
+
+    @ExcelProperty("供应单位")
+    private String supEntName;
+
+    @ExcelProperty("代理单位")
+    private String agentEntName;
+}
+

+ 46 - 0
sckw-modules/sckw-report/src/main/java/com/sckw/report/model/export/KwrMonthLedgerExport.java

@@ -0,0 +1,46 @@
+package com.sckw.report.model.export;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.sckw.excel.annotation.ExcelContext;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+@Data
+@ExcelContext(fileName = "过磅台账-月台账", sheetName = "月台账")
+public class KwrMonthLedgerExport {
+
+    @ExcelProperty("商品")
+    private String goodsName;
+
+    @ExcelProperty("类别")
+    private String goodsTypeName;
+
+    @ExcelProperty("规格")
+    private String goodsSpecName;
+
+    @ExcelProperty("供应单位")
+    private String supEntName;
+
+    @ExcelProperty("代理单位")
+    private String agentEntName;
+
+    @ExcelProperty("订单号")
+    private String tOrderNos;
+
+    @ExcelProperty("客户")
+    private String proEntNames;
+
+    @ExcelProperty("毛重(吨)")
+    private BigDecimal grossAmountTotal;
+
+    @ExcelProperty("皮重(吨)")
+    private BigDecimal tareAmountTotal;
+
+    @ExcelProperty("净重(吨)")
+    private BigDecimal netAmountTotal;
+
+    @ExcelProperty("车次")
+    private Long truckCount;
+}
+

+ 64 - 0
sckw-modules/sckw-report/src/main/java/com/sckw/report/model/export/KwrTaskListExport.java

@@ -0,0 +1,64 @@
+package com.sckw.report.model.export;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.sckw.excel.annotation.ExcelContext;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+@Data
+@ExcelContext(fileName = "统计报表-任务清单", sheetName = "任务清单")
+public class KwrTaskListExport {
+
+    @ExcelProperty("运单号")
+    private String wOrderNo;
+
+    @ExcelProperty("供应单位")
+    private String supEntName;
+
+    @ExcelProperty("客户")
+    private String proEntName;
+
+    @ExcelProperty("代理商")
+    private String agentEntName;
+
+    @ExcelProperty("装货地址")
+    private String loadAddress;
+
+    @ExcelProperty("卸货地址")
+    private String unloadAddress;
+
+    @ExcelProperty("订单号")
+    private String tOrderNo;
+
+    @ExcelProperty("商品")
+    private String goodsName;
+
+    @ExcelProperty("规格")
+    private String goodsSpecName;
+
+    @ExcelProperty("车牌号")
+    private String truckNo;
+
+    @ExcelProperty("车轴")
+    private String axes;
+
+    @ExcelProperty("任务量")
+    private BigDecimal taskNum;
+
+    @ExcelProperty("皮重(吨)")
+    private BigDecimal tareAmount;
+
+    @ExcelProperty("毛重(吨)")
+    private BigDecimal grossAmount;
+
+    @ExcelProperty("净重(吨)")
+    private BigDecimal netAmount;
+
+    @ExcelProperty("完成时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private LocalDateTime successTime;
+}
+

+ 14 - 0
sckw-modules/sckw-report/src/main/java/com/sckw/report/model/query/KwrDailySummaryQuery.java

@@ -0,0 +1,14 @@
+package com.sckw.report.model.query;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class KwrDailySummaryQuery extends KwrRecordOrderBaseQuery {
+
+    @Schema(description = "汇总维度 1-按客户 2-按代理")
+    private Integer groupType = 1;
+}
+

+ 51 - 0
sckw-modules/sckw-report/src/main/java/com/sckw/report/model/query/KwrRecordOrderBaseQuery.java

@@ -0,0 +1,51 @@
+package com.sckw.report.model.query;
+
+import com.sckw.core.web.page.BaseQuery;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class KwrRecordOrderBaseQuery extends BaseQuery {
+
+    @Schema(description = "贸易订单号")
+    private String tOrderNo;
+
+    @Schema(description = "物流订单号")
+    private String lOrderNo;
+
+    @Schema(description = "物流运单号")
+    private String wOrderNo;
+
+    @Schema(description = "客户(采购企业)ID")
+    private Long proEntId;
+
+    @Schema(description = "供应企业ID")
+    private Long supEntId;
+
+    @Schema(description = "代理企业ID")
+    private Long agentEntId;
+
+    @Schema(description = "商品ID")
+    private Long goodsId;
+
+    @Schema(description = "商品类别")
+    private String goodsType;
+
+    @Schema(description = "商品规格")
+    private String goodsSpec;
+
+    @Schema(description = "车牌号")
+    private String truckNo;
+
+    @Schema(description = "完成时间-开始(yyyy-MM-dd HH:mm:ss 或 yyyy/MM/dd HH:mm)")
+    private String successTimeStart;
+
+    @Schema(description = "完成时间-结束(yyyy-MM-dd HH:mm:ss 或 yyyy/MM/dd HH:mm)")
+    private String successTimeEnd;
+
+    @Schema(description = "数据类型 1-自销 2-代理")
+    private Integer dataType;
+}
+

+ 14 - 0
sckw-modules/sckw-report/src/main/java/com/sckw/report/model/query/KwrTaskListQuery.java

@@ -0,0 +1,14 @@
+package com.sckw.report.model.query;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class KwrTaskListQuery extends KwrRecordOrderBaseQuery {
+
+    @Schema(description = "车轴数")
+    private String axes;
+}
+

+ 50 - 0
sckw-modules/sckw-report/src/main/java/com/sckw/report/model/vo/KwrDailySummaryRowVo.java

@@ -0,0 +1,50 @@
+package com.sckw.report.model.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+@Data
+public class KwrDailySummaryRowVo {
+
+    @Schema(description = "日期(yyyy-MM-dd)")
+    private String day;
+
+    @Schema(description = "客户/代理单位名称")
+    private String targetEntName;
+
+    @Schema(description = "商品名称")
+    private String goodsName;
+
+    @Schema(description = "类别")
+    private String goodsTypeName;
+
+    @Schema(description = "规格")
+    private String goodsSpecName;
+
+    @Schema(description = "车次")
+    private Long truckCount;
+
+    @Schema(description = "异常车次")
+    private Long abnormalTruckCount;
+
+    @Schema(description = "异常占比(%)")
+    private BigDecimal abnormalRate;
+
+    @Schema(description = "皮重(吨)")
+    private BigDecimal tareAmountTotal;
+
+    @Schema(description = "毛重(吨)")
+    private BigDecimal grossAmountTotal;
+
+    @Schema(description = "净重(吨)")
+    private BigDecimal netAmountTotal;
+
+    @Schema(description = "供应单位")
+    private String supEntName;
+
+    @Schema(description = "代理单位")
+    private String agentEntName;
+}
+

+ 26 - 0
sckw-modules/sckw-report/src/main/java/com/sckw/report/model/vo/KwrFilterOptionsVo.java

@@ -0,0 +1,26 @@
+package com.sckw.report.model.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class KwrFilterOptionsVo {
+
+    @Schema(description = "客户")
+    private List<KwrSelectOptionVo> customers;
+
+    @Schema(description = "供应企业")
+    private List<KwrSelectOptionVo> suppliers;
+
+    @Schema(description = "代理单位")
+    private List<KwrSelectOptionVo> agents;
+
+    @Schema(description = "商品类别")
+    private List<KwrSelectOptionVo> goodsTypes;
+
+    @Schema(description = "规格")
+    private List<KwrSelectOptionVo> goodsSpecs;
+}
+

+ 17 - 0
sckw-modules/sckw-report/src/main/java/com/sckw/report/model/vo/KwrLedgerSummaryVo.java

@@ -0,0 +1,17 @@
+package com.sckw.report.model.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+@Data
+public class KwrLedgerSummaryVo {
+
+    @Schema(description = "净重合计(吨)")
+    private BigDecimal netAmountTotal;
+
+    @Schema(description = "车次")
+    private Long truckCount;
+}
+

+ 44 - 0
sckw-modules/sckw-report/src/main/java/com/sckw/report/model/vo/KwrMonthLedgerRowVo.java

@@ -0,0 +1,44 @@
+package com.sckw.report.model.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+@Data
+public class KwrMonthLedgerRowVo {
+
+    @Schema(description = "商品")
+    private String goodsName;
+
+    @Schema(description = "类别")
+    private String goodsTypeName;
+
+    @Schema(description = "规格")
+    private String goodsSpecName;
+
+    @Schema(description = "供应单位")
+    private String supEntName;
+
+    @Schema(description = "代理单位")
+    private String agentEntName;
+
+    @Schema(description = "订单号(去重拼接)")
+    private String tOrderNos;
+
+    @Schema(description = "客户(去重拼接)")
+    private String proEntNames;
+
+    @Schema(description = "毛重(吨)")
+    private BigDecimal grossAmountTotal;
+
+    @Schema(description = "皮重(吨)")
+    private BigDecimal tareAmountTotal;
+
+    @Schema(description = "净重(吨)")
+    private BigDecimal netAmountTotal;
+
+    @Schema(description = "车次")
+    private Long truckCount;
+}
+

+ 19 - 0
sckw-modules/sckw-report/src/main/java/com/sckw/report/model/vo/KwrSelectOptionVo.java

@@ -0,0 +1,19 @@
+package com.sckw.report.model.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class KwrSelectOptionVo {
+
+    @Schema(description = "值")
+    private String value;
+
+    @Schema(description = "名称")
+    private String label;
+}
+

+ 47 - 0
sckw-modules/sckw-report/src/main/java/com/sckw/report/service/KwrReportService.java

@@ -0,0 +1,47 @@
+package com.sckw.report.service;
+
+import com.sckw.core.web.response.result.PageDataResult;
+import com.sckw.report.entity.KwrRecordOrder;
+import com.sckw.report.model.export.KwrCustomLedgerExport;
+import com.sckw.report.model.export.KwrDailySummaryExport;
+import com.sckw.report.model.export.KwrMonthLedgerExport;
+import com.sckw.report.model.export.KwrTaskListExport;
+import com.sckw.report.model.query.KwrDailySummaryQuery;
+import com.sckw.report.model.query.KwrRecordOrderBaseQuery;
+import com.sckw.report.model.query.KwrTaskListQuery;
+import com.sckw.report.model.vo.KwrDailySummaryRowVo;
+import com.sckw.report.model.vo.KwrFilterOptionsVo;
+import com.sckw.report.model.vo.KwrLedgerSummaryVo;
+import com.sckw.report.model.vo.KwrMonthLedgerRowVo;
+
+import java.util.List;
+
+public interface KwrReportService {
+
+    PageDataResult<KwrRecordOrder> customLedgerPage(KwrRecordOrderBaseQuery query);
+
+    KwrLedgerSummaryVo customLedgerSummary(KwrRecordOrderBaseQuery query);
+
+    List<KwrCustomLedgerExport> customLedgerExport(KwrRecordOrderBaseQuery query);
+
+    PageDataResult<KwrMonthLedgerRowVo> monthLedgerPage(KwrRecordOrderBaseQuery query);
+
+    KwrMonthLedgerRowVo monthLedgerTotal(KwrRecordOrderBaseQuery query);
+
+    List<KwrMonthLedgerExport> monthLedgerExport(KwrRecordOrderBaseQuery query);
+
+    PageDataResult<KwrDailySummaryRowVo> dailySummaryPage(KwrDailySummaryQuery query);
+
+    KwrLedgerSummaryVo dailySummaryTotal(KwrDailySummaryQuery query);
+
+    List<KwrDailySummaryExport> dailySummaryExport(KwrDailySummaryQuery query);
+
+    PageDataResult<KwrRecordOrder> taskListPage(KwrTaskListQuery query);
+
+    KwrLedgerSummaryVo taskListTotal(KwrTaskListQuery query);
+
+    List<KwrTaskListExport> taskListExport(KwrTaskListQuery query);
+
+    KwrFilterOptionsVo filterOptions();
+}
+

+ 489 - 0
sckw-modules/sckw-report/src/main/java/com/sckw/report/service/impl/KwrReportServiceImpl.java

@@ -0,0 +1,489 @@
+package com.sckw.report.service.impl;
+
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.sckw.core.model.enums.EntTypeEnum;
+import com.sckw.core.web.context.LoginEntHolder;
+import com.sckw.core.web.response.result.PageDataResult;
+import com.sckw.excel.utils.ExcelUtil;
+import com.sckw.report.entity.KwrRecordOrder;
+import com.sckw.report.model.export.KwrCustomLedgerExport;
+import com.sckw.report.model.export.KwrDailySummaryExport;
+import com.sckw.report.model.export.KwrMonthLedgerExport;
+import com.sckw.report.model.export.KwrTaskListExport;
+import com.sckw.report.model.query.KwrDailySummaryQuery;
+import com.sckw.report.model.query.KwrRecordOrderBaseQuery;
+import com.sckw.report.model.query.KwrTaskListQuery;
+import com.sckw.report.model.vo.KwrDailySummaryRowVo;
+import com.sckw.report.model.vo.KwrFilterOptionsVo;
+import com.sckw.report.model.vo.KwrLedgerSummaryVo;
+import com.sckw.report.model.vo.KwrMonthLedgerRowVo;
+import com.sckw.report.model.vo.KwrSelectOptionVo;
+import com.sckw.report.service.KwrReportService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.BeanUtils;
+import org.springframework.stereotype.Service;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.time.format.DateTimeFormatter;
+import java.util.*;
+import java.util.stream.Collectors;
+
+@Service
+@RequiredArgsConstructor
+public class KwrReportServiceImpl implements KwrReportService {
+
+    private static final DateTimeFormatter DAY_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd");
+
+    private final KwrRecordOrderService kwrRecordOrderService;
+
+    @Override
+    public PageDataResult<KwrRecordOrder> customLedgerPage(KwrRecordOrderBaseQuery query) {
+        Page<KwrRecordOrder> page = new Page<>(query.getPageNum(), query.getPageSize());
+        QueryWrapper<KwrRecordOrder> wrapper = buildListWrapper(query);
+        Page<KwrRecordOrder> result = kwrRecordOrderService.page(page, wrapper);
+        return PageDataResult.of(result, result.getRecords());
+    }
+
+    @Override
+    public KwrLedgerSummaryVo customLedgerSummary(KwrRecordOrderBaseQuery query) {
+        QueryWrapper<KwrRecordOrder> wrapper = buildListWrapper(query);
+        wrapper.select("COALESCE(SUM(net_amount),0) AS netAmountTotal", "COUNT(1) AS truckCount");
+        Map<String, Object> map = firstMap(kwrRecordOrderService.listMaps(wrapper));
+        KwrLedgerSummaryVo vo = new KwrLedgerSummaryVo();
+        vo.setNetAmountTotal(toBigDecimal(map.get("netAmountTotal")));
+        vo.setTruckCount(toLong(map.get("truckCount")));
+        return vo;
+    }
+
+    @Override
+    public List<KwrCustomLedgerExport> customLedgerExport(KwrRecordOrderBaseQuery query) {
+        QueryWrapper<KwrRecordOrder> wrapper = buildListWrapper(query);
+        wrapper.orderByDesc("success_time", "id");
+        List<KwrRecordOrder> list = kwrRecordOrderService.list(wrapper);
+        if (list.isEmpty()) {
+            return Collections.emptyList();
+        }
+        return list.stream().map(e -> {
+            KwrCustomLedgerExport export = new KwrCustomLedgerExport();
+            BeanUtils.copyProperties(e, export);
+            return export;
+        }).toList();
+    }
+
+    @Override
+    public PageDataResult<KwrMonthLedgerRowVo> monthLedgerPage(KwrRecordOrderBaseQuery query) {
+        Page<Map<String, Object>> page = new Page<>(query.getPageNum(), query.getPageSize());
+        QueryWrapper<KwrRecordOrder> wrapper = buildListWrapper(query);
+        wrapper.select(
+                "goods_name AS goodsName",
+                "goods_type_name AS goodsTypeName",
+                "goods_spec_name AS goodsSpecName",
+                "sup_ent_name AS supEntName",
+                "agent_ent_name AS agentEntName",
+                "GROUP_CONCAT(DISTINCT t_order_no) AS tOrderNos",
+                "GROUP_CONCAT(DISTINCT pro_ent_name) AS proEntNames",
+                "COALESCE(SUM(gross_amount),0) AS grossAmountTotal",
+                "COALESCE(SUM(tare_amount),0) AS tareAmountTotal",
+                "COALESCE(SUM(net_amount),0) AS netAmountTotal",
+                "COUNT(1) AS truckCount"
+        );
+        wrapper.groupBy("goods_name", "goods_type_name", "goods_spec_name", "sup_ent_name", "agent_ent_name");
+        wrapper.orderByDesc("netAmountTotal");
+        Page<Map<String, Object>> result = kwrRecordOrderService.pageMaps(page, wrapper);
+        List<KwrMonthLedgerRowVo> rows = result.getRecords().stream().map(this::mapToMonthRow).toList();
+        return PageDataResult.of(result, rows);
+    }
+
+    @Override
+    public KwrMonthLedgerRowVo monthLedgerTotal(KwrRecordOrderBaseQuery query) {
+        QueryWrapper<KwrRecordOrder> wrapper = buildListWrapper(query);
+        wrapper.select(
+                "COALESCE(SUM(gross_amount),0) AS grossAmountTotal",
+                "COALESCE(SUM(tare_amount),0) AS tareAmountTotal",
+                "COALESCE(SUM(net_amount),0) AS netAmountTotal",
+                "COUNT(1) AS truckCount"
+        );
+        Map<String, Object> map = firstMap(kwrRecordOrderService.listMaps(wrapper));
+        KwrMonthLedgerRowVo vo = new KwrMonthLedgerRowVo();
+        vo.setGrossAmountTotal(toBigDecimal(map.get("grossAmountTotal")));
+        vo.setTareAmountTotal(toBigDecimal(map.get("tareAmountTotal")));
+        vo.setNetAmountTotal(toBigDecimal(map.get("netAmountTotal")));
+        vo.setTruckCount(toLong(map.get("truckCount")));
+        return vo;
+    }
+
+    @Override
+    public List<KwrMonthLedgerExport> monthLedgerExport(KwrRecordOrderBaseQuery query) {
+        QueryWrapper<KwrRecordOrder> wrapper = buildListWrapper(query);
+        wrapper.select(
+                "goods_name AS goodsName",
+                "goods_type_name AS goodsTypeName",
+                "goods_spec_name AS goodsSpecName",
+                "sup_ent_name AS supEntName",
+                "agent_ent_name AS agentEntName",
+                "GROUP_CONCAT(DISTINCT t_order_no) AS tOrderNos",
+                "GROUP_CONCAT(DISTINCT pro_ent_name) AS proEntNames",
+                "COALESCE(SUM(gross_amount),0) AS grossAmountTotal",
+                "COALESCE(SUM(tare_amount),0) AS tareAmountTotal",
+                "COALESCE(SUM(net_amount),0) AS netAmountTotal",
+                "COUNT(1) AS truckCount"
+        );
+        wrapper.groupBy("goods_name", "goods_type_name", "goods_spec_name", "sup_ent_name", "agent_ent_name");
+        wrapper.orderByDesc("netAmountTotal");
+        List<Map<String, Object>> records = kwrRecordOrderService.listMaps(wrapper);
+        if (records.isEmpty()) {
+            return Collections.emptyList();
+        }
+        return records.stream().map(m -> {
+            KwrMonthLedgerRowVo row = mapToMonthRow(m);
+            KwrMonthLedgerExport export = new KwrMonthLedgerExport();
+            BeanUtils.copyProperties(row, export);
+            return export;
+        }).toList();
+    }
+
+    @Override
+    public PageDataResult<KwrDailySummaryRowVo> dailySummaryPage(KwrDailySummaryQuery query) {
+        Page<Map<String, Object>> page = new Page<>(query.getPageNum(), query.getPageSize());
+        QueryWrapper<KwrRecordOrder> wrapper = buildListWrapper(query);
+
+        String entNameCol = Objects.equals(query.getGroupType(), 2) ? "agent_ent_name" : "pro_ent_name";
+        String entIdCol = Objects.equals(query.getGroupType(), 2) ? "agent_ent_id" : "pro_ent_id";
+
+        wrapper.select(
+                "DATE_FORMAT(success_time,'%Y-%m-%d') AS day",
+                entNameCol + " AS targetEntName",
+                "goods_name AS goodsName",
+                "goods_type_name AS goodsTypeName",
+                "goods_spec_name AS goodsSpecName",
+                "sup_ent_name AS supEntName",
+                "agent_ent_name AS agentEntName",
+                "COUNT(1) AS truckCount",
+                "COALESCE(SUM(CASE WHEN weigh_count <> 2 OR net_amount <= 0 THEN 1 ELSE 0 END),0) AS abnormalTruckCount",
+                "COALESCE(SUM(gross_amount),0) AS grossAmountTotal",
+                "COALESCE(SUM(tare_amount),0) AS tareAmountTotal",
+                "COALESCE(SUM(net_amount),0) AS netAmountTotal"
+        );
+        wrapper.groupBy("DATE_FORMAT(success_time,'%Y-%m-%d')", entIdCol, "goods_name", "goods_type_name", "goods_spec_name", "sup_ent_name", "agent_ent_name");
+        wrapper.orderByDesc("day");
+
+        Page<Map<String, Object>> result = kwrRecordOrderService.pageMaps(page, wrapper);
+        List<KwrDailySummaryRowVo> rows = result.getRecords().stream().map(this::mapToDailyRow).toList();
+        return PageDataResult.of(result, rows);
+    }
+
+    @Override
+    public KwrLedgerSummaryVo dailySummaryTotal(KwrDailySummaryQuery query) {
+        QueryWrapper<KwrRecordOrder> wrapper = buildListWrapper(query);
+        wrapper.select("COALESCE(SUM(net_amount),0) AS netAmountTotal", "COUNT(1) AS truckCount");
+        Map<String, Object> map = firstMap(kwrRecordOrderService.listMaps(wrapper));
+        KwrLedgerSummaryVo vo = new KwrLedgerSummaryVo();
+        vo.setNetAmountTotal(toBigDecimal(map.get("netAmountTotal")));
+        vo.setTruckCount(toLong(map.get("truckCount")));
+        return vo;
+    }
+
+    @Override
+    public List<KwrDailySummaryExport> dailySummaryExport(KwrDailySummaryQuery query) {
+        QueryWrapper<KwrRecordOrder> wrapper = buildListWrapper(query);
+
+        String entNameCol = Objects.equals(query.getGroupType(), 2) ? "agent_ent_name" : "pro_ent_name";
+        String entIdCol = Objects.equals(query.getGroupType(), 2) ? "agent_ent_id" : "pro_ent_id";
+
+        wrapper.select(
+                "DATE_FORMAT(success_time,'%Y-%m-%d') AS day",
+                entNameCol + " AS targetEntName",
+                "goods_name AS goodsName",
+                "goods_type_name AS goodsTypeName",
+                "goods_spec_name AS goodsSpecName",
+                "sup_ent_name AS supEntName",
+                "agent_ent_name AS agentEntName",
+                "COUNT(1) AS truckCount",
+                "COALESCE(SUM(CASE WHEN weigh_count <> 2 OR net_amount <= 0 THEN 1 ELSE 0 END),0) AS abnormalTruckCount",
+                "COALESCE(SUM(gross_amount),0) AS grossAmountTotal",
+                "COALESCE(SUM(tare_amount),0) AS tareAmountTotal",
+                "COALESCE(SUM(net_amount),0) AS netAmountTotal"
+        );
+        wrapper.groupBy("DATE_FORMAT(success_time,'%Y-%m-%d')", entIdCol, "goods_name", "goods_type_name", "goods_spec_name", "sup_ent_name", "agent_ent_name");
+        wrapper.orderByDesc("day");
+
+        List<Map<String, Object>> records = kwrRecordOrderService.listMaps(wrapper);
+        if (records.isEmpty()) {
+            return Collections.emptyList();
+        }
+        return records.stream().map(m -> {
+            KwrDailySummaryRowVo row = mapToDailyRow(m);
+            KwrDailySummaryExport export = new KwrDailySummaryExport();
+            BeanUtils.copyProperties(row, export);
+            return export;
+        }).toList();
+    }
+
+    @Override
+    public PageDataResult<KwrRecordOrder> taskListPage(KwrTaskListQuery query) {
+        Page<KwrRecordOrder> page = new Page<>(query.getPageNum(), query.getPageSize());
+        QueryWrapper<KwrRecordOrder> wrapper = buildListWrapper(query);
+        if (StrUtil.isNotBlank(query.getAxes())) {
+            wrapper.eq("axes", query.getAxes());
+        }
+        Page<KwrRecordOrder> result = kwrRecordOrderService.page(page, wrapper);
+        return PageDataResult.of(result, result.getRecords());
+    }
+
+    @Override
+    public KwrLedgerSummaryVo taskListTotal(KwrTaskListQuery query) {
+        QueryWrapper<KwrRecordOrder> wrapper = buildListWrapper(query);
+        if (StrUtil.isNotBlank(query.getAxes())) {
+            wrapper.eq("axes", query.getAxes());
+        }
+        wrapper.select("COALESCE(SUM(net_amount),0) AS netAmountTotal", "COUNT(1) AS truckCount");
+        Map<String, Object> map = firstMap(kwrRecordOrderService.listMaps(wrapper));
+        KwrLedgerSummaryVo vo = new KwrLedgerSummaryVo();
+        vo.setNetAmountTotal(toBigDecimal(map.get("netAmountTotal")));
+        vo.setTruckCount(toLong(map.get("truckCount")));
+        return vo;
+    }
+
+    @Override
+    public List<KwrTaskListExport> taskListExport(KwrTaskListQuery query) {
+        QueryWrapper<KwrRecordOrder> wrapper = buildListWrapper(query);
+        if (StrUtil.isNotBlank(query.getAxes())) {
+            wrapper.eq("axes", query.getAxes());
+        }
+        wrapper.orderByDesc("success_time", "id");
+        List<KwrRecordOrder> list = kwrRecordOrderService.list(wrapper);
+        if (list.isEmpty()) {
+            return Collections.emptyList();
+        }
+        return list.stream().map(e -> {
+            KwrTaskListExport export = new KwrTaskListExport();
+            BeanUtils.copyProperties(e, export);
+            return export;
+        }).toList();
+    }
+
+    @Override
+    public KwrFilterOptionsVo filterOptions() {
+        QueryWrapper<KwrRecordOrder> base = new QueryWrapper<>();
+        applyEntScope(base);
+        base.isNotNull("success_time");
+
+        KwrFilterOptionsVo vo = new KwrFilterOptionsVo();
+        vo.setCustomers(distinctEntOptions(base, "pro_ent_id", "pro_ent_name"));
+        vo.setSuppliers(distinctEntOptions(base, "sup_ent_id", "sup_ent_name"));
+        vo.setAgents(distinctEntOptions(base, "agent_ent_id", "agent_ent_name"));
+        vo.setGoodsTypes(distinctStringOptions(base, "goods_type", "goods_type_name"));
+        vo.setGoodsSpecs(distinctStringOptions(base, "goods_spec", "goods_spec_name"));
+        return vo;
+    }
+
+    private QueryWrapper<KwrRecordOrder> buildListWrapper(KwrRecordOrderBaseQuery query) {
+        QueryWrapper<KwrRecordOrder> wrapper = new QueryWrapper<>();
+        applyEntScope(wrapper);
+
+        if (StrUtil.isNotBlank(query.getTOrderNo())) {
+            wrapper.like("t_order_no", query.getTOrderNo());
+        }
+        if (StrUtil.isNotBlank(query.getLOrderNo())) {
+            wrapper.like("l_order_no", query.getLOrderNo());
+        }
+        if (StrUtil.isNotBlank(query.getWOrderNo())) {
+            wrapper.like("w_order_no", query.getWOrderNo());
+        }
+        if (query.getProEntId() != null) {
+            wrapper.eq("pro_ent_id", query.getProEntId());
+        }
+        if (query.getSupEntId() != null) {
+            wrapper.eq("sup_ent_id", query.getSupEntId());
+        }
+        if (query.getAgentEntId() != null) {
+            wrapper.eq("agent_ent_id", query.getAgentEntId());
+        }
+        if (query.getGoodsId() != null) {
+            wrapper.eq("goods_id", query.getGoodsId());
+        }
+        if (StrUtil.isNotBlank(query.getGoodsType())) {
+            wrapper.eq("goods_type", query.getGoodsType());
+        }
+        if (StrUtil.isNotBlank(query.getGoodsSpec())) {
+            wrapper.eq("goods_spec", query.getGoodsSpec());
+        }
+        if (StrUtil.isNotBlank(query.getTruckNo())) {
+            wrapper.like("truck_no", query.getTruckNo());
+        }
+        if (query.getDataType() != null) {
+            wrapper.eq("data_type", query.getDataType());
+        }
+
+        LocalDateTime start = parseTime(query.getSuccessTimeStart());
+        if (start != null) {
+            wrapper.ge("success_time", start);
+        }
+        LocalDateTime end = parseTime(query.getSuccessTimeEnd());
+        if (end != null) {
+            wrapper.le("success_time", end);
+        }
+
+        wrapper.orderByDesc("success_time", "id");
+        return wrapper;
+    }
+
+    private void applyEntScope(QueryWrapper<KwrRecordOrder> wrapper) {
+        String entTypes = LoginEntHolder.getEntTypes();
+        Long entId = LoginEntHolder.getEntId();
+        if (entId == null || StrUtil.isBlank(entTypes)) {
+            return;
+        }
+        if (entTypes.contains(String.valueOf(EntTypeEnum.SUPPLIER.getCode()))) {
+            wrapper.eq("sup_ent_id", entId);
+            return;
+        }
+        if (entTypes.contains(String.valueOf(EntTypeEnum.PURCHASER.getCode()))) {
+            wrapper.eq("pro_ent_id", entId);
+            return;
+        }
+        if (entTypes.contains(String.valueOf(EntTypeEnum.PROXY.getCode()))) {
+            wrapper.eq("agent_ent_id", entId);
+        }
+    }
+
+    private LocalDateTime parseTime(String text) {
+        if (StrUtil.isBlank(text)) {
+            return null;
+        }
+        try {
+            return DateUtil.parse(text).toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
+        } catch (Exception ignore) {
+            return null;
+        }
+    }
+
+    private Map<String, Object> firstMap(List<Map<String, Object>> list) {
+        if (list == null || list.isEmpty()) {
+            return Collections.emptyMap();
+        }
+        Map<String, Object> map = list.get(0);
+        return map == null ? Collections.emptyMap() : map;
+    }
+
+    private KwrMonthLedgerRowVo mapToMonthRow(Map<String, Object> map) {
+        KwrMonthLedgerRowVo vo = new KwrMonthLedgerRowVo();
+        vo.setGoodsName(toString(map.get("goodsName")));
+        vo.setGoodsTypeName(toString(map.get("goodsTypeName")));
+        vo.setGoodsSpecName(toString(map.get("goodsSpecName")));
+        vo.setSupEntName(toString(map.get("supEntName")));
+        vo.setAgentEntName(toString(map.get("agentEntName")));
+        vo.setTOrderNos(toString(map.get("tOrderNos")));
+        vo.setProEntNames(toString(map.get("proEntNames")));
+        vo.setGrossAmountTotal(toBigDecimal(map.get("grossAmountTotal")));
+        vo.setTareAmountTotal(toBigDecimal(map.get("tareAmountTotal")));
+        vo.setNetAmountTotal(toBigDecimal(map.get("netAmountTotal")));
+        vo.setTruckCount(toLong(map.get("truckCount")));
+        return vo;
+    }
+
+    private KwrDailySummaryRowVo mapToDailyRow(Map<String, Object> map) {
+        KwrDailySummaryRowVo vo = new KwrDailySummaryRowVo();
+        vo.setDay(toString(map.get("day")));
+        vo.setTargetEntName(toString(map.get("targetEntName")));
+        vo.setGoodsName(toString(map.get("goodsName")));
+        vo.setGoodsTypeName(toString(map.get("goodsTypeName")));
+        vo.setGoodsSpecName(toString(map.get("goodsSpecName")));
+        vo.setSupEntName(toString(map.get("supEntName")));
+        vo.setAgentEntName(toString(map.get("agentEntName")));
+        Long truckCount = toLong(map.get("truckCount"));
+        Long abnormalTruckCount = toLong(map.get("abnormalTruckCount"));
+        vo.setTruckCount(truckCount);
+        vo.setAbnormalTruckCount(abnormalTruckCount);
+        vo.setAbnormalRate(calcRate(abnormalTruckCount, truckCount));
+        vo.setGrossAmountTotal(toBigDecimal(map.get("grossAmountTotal")));
+        vo.setTareAmountTotal(toBigDecimal(map.get("tareAmountTotal")));
+        vo.setNetAmountTotal(toBigDecimal(map.get("netAmountTotal")));
+        return vo;
+    }
+
+    private BigDecimal calcRate(Long abnormal, Long total) {
+        if (abnormal == null || total == null || total == 0L) {
+            return BigDecimal.ZERO;
+        }
+        return BigDecimal.valueOf(abnormal)
+                .multiply(BigDecimal.valueOf(100))
+                .divide(BigDecimal.valueOf(total), 2, RoundingMode.HALF_UP);
+    }
+
+    private List<KwrSelectOptionVo> distinctEntOptions(QueryWrapper<KwrRecordOrder> base, String idCol, String nameCol) {
+        QueryWrapper<KwrRecordOrder> wrapper = base.clone();
+        wrapper.select(idCol + " AS id", nameCol + " AS name");
+        wrapper.isNotNull(idCol);
+        wrapper.isNotNull(nameCol);
+        wrapper.groupBy(idCol, nameCol);
+        wrapper.orderByAsc(nameCol);
+        List<Map<String, Object>> maps = kwrRecordOrderService.listMaps(wrapper);
+        if (maps == null || maps.isEmpty()) {
+            return Collections.emptyList();
+        }
+        return maps.stream()
+                .map(m -> new KwrSelectOptionVo(toString(m.get("id")), toString(m.get("name"))))
+                .filter(o -> StrUtil.isNotBlank(o.getValue()) && StrUtil.isNotBlank(o.getLabel()))
+                .toList();
+    }
+
+    private List<KwrSelectOptionVo> distinctStringOptions(QueryWrapper<KwrRecordOrder> base, String valueCol, String labelCol) {
+        QueryWrapper<KwrRecordOrder> wrapper = base.clone();
+        wrapper.select(valueCol + " AS value", labelCol + " AS label");
+        wrapper.isNotNull(valueCol);
+        wrapper.isNotNull(labelCol);
+        wrapper.groupBy(valueCol, labelCol);
+        wrapper.orderByAsc(labelCol);
+        List<Map<String, Object>> maps = kwrRecordOrderService.listMaps(wrapper);
+        if (maps == null || maps.isEmpty()) {
+            return Collections.emptyList();
+        }
+        return maps.stream()
+                .map(m -> new KwrSelectOptionVo(toString(m.get("value")), toString(m.get("label"))))
+                .filter(o -> StrUtil.isNotBlank(o.getValue()) && StrUtil.isNotBlank(o.getLabel()))
+                .toList();
+    }
+
+    private String toString(Object obj) {
+        return obj == null ? "" : String.valueOf(obj);
+    }
+
+    private Long toLong(Object obj) {
+        if (obj == null) {
+            return 0L;
+        }
+        if (obj instanceof Number n) {
+            return n.longValue();
+        }
+        try {
+            return Long.parseLong(String.valueOf(obj));
+        } catch (Exception e) {
+            return 0L;
+        }
+    }
+
+    private BigDecimal toBigDecimal(Object obj) {
+        if (obj == null) {
+            return BigDecimal.ZERO;
+        }
+        if (obj instanceof BigDecimal b) {
+            return b;
+        }
+        if (obj instanceof Number n) {
+            return BigDecimal.valueOf(n.doubleValue());
+        }
+        try {
+            return new BigDecimal(String.valueOf(obj));
+        } catch (Exception e) {
+            return BigDecimal.ZERO;
+        }
+    }
+}
+

+ 3 - 0
sckw-modules/sckw-report/src/main/java/com/sckw/report/task/OrderTask.java

@@ -16,6 +16,7 @@ import com.sckw.transport.api.model.dto.EntDto;
 import com.sckw.transport.api.model.dto.OrderTicketDto;
 import com.sckw.transport.api.model.dto.WeighDto;
 import jakarta.annotation.Resource;
+import lombok.extern.slf4j.Slf4j;
 import org.apache.dubbo.config.annotation.DubboReference;
 import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Component;
@@ -32,6 +33,7 @@ import java.util.Optional;
  * @date 2026-06-26 19:42:30
  */
 @Component
+@Slf4j
 public class OrderTask {
     @DubboReference(version = "1.0.0", group = "design", check = false)
     private TransportRemoteService transportRemoteService;
@@ -43,6 +45,7 @@ public class OrderTask {
     @Scheduled(cron = "0 0/15 * * * ?")
     public void task() {
         List<ArchiveOrderDto> archiveOrderDtos = transportRemoteService.queryArchiveOrder(15);
+        log.info("运单数据 {}",archiveOrderDtos.size());
         if (CollUtil.isNotEmpty(archiveOrderDtos)) {
             for (ArchiveOrderDto archiveOrderDto : archiveOrderDtos) {
                 KwrRecordOrder build = this.build(archiveOrderDto);