diff --git a/klp-wms/src/main/java/com/klp/controller/WmsMaterialCoilController.java b/klp-wms/src/main/java/com/klp/controller/WmsMaterialCoilController.java index 9499f1fb..dad1f4ca 100644 --- a/klp-wms/src/main/java/com/klp/controller/WmsMaterialCoilController.java +++ b/klp-wms/src/main/java/com/klp/controller/WmsMaterialCoilController.java @@ -30,6 +30,7 @@ import com.klp.common.core.validate.EditGroup; import com.klp.common.enums.BusinessType; import com.klp.common.utils.poi.ExcelUtil; import com.klp.domain.bo.WmsMaterialCoilBo; +import com.klp.domain.bo.WmsMaterialCoilReportSummaryBo; import com.klp.domain.vo.dashboard.CoilTrimStatisticsVo; import com.klp.domain.vo.dashboard.CategoryWidthStatisticsVo; import com.klp.service.IWmsMaterialCoilService; @@ -162,6 +163,15 @@ public class WmsMaterialCoilController extends BaseController { return iWmsMaterialCoilService.queryPageList(bo, pageQuery); } + /** + * 报表汇总(待操作筛选 + 钢卷筛选) + * 仅返回统计结果,不返回钢卷明细 + */ + @PostMapping("/reportSummary") + public R reportSummary(@RequestBody WmsMaterialCoilReportSummaryBo bo) { + return R.ok(iWmsMaterialCoilService.reportSummary(bo)); + } + /** * 钢卷发货,将钢卷状态更新为已发货,且更新发货时间 * diff --git a/klp-wms/src/main/java/com/klp/domain/bo/WmsMaterialCoilReportSummaryBo.java b/klp-wms/src/main/java/com/klp/domain/bo/WmsMaterialCoilReportSummaryBo.java new file mode 100644 index 00000000..612ffc08 --- /dev/null +++ b/klp-wms/src/main/java/com/klp/domain/bo/WmsMaterialCoilReportSummaryBo.java @@ -0,0 +1,21 @@ +package com.klp.domain.bo; + +import lombok.Data; + +/** + * 报表汇总请求参数 + * 同时支持待操作条件 + 钢卷条件组合筛选 + */ +@Data +public class WmsMaterialCoilReportSummaryBo { + + /** + * 待操作筛选条件(可为空) + */ + private WmsCoilPendingActionBo pendingActionFilter; + + /** + * 钢卷筛选条件(可为空,内部会按空条件处理) + */ + private WmsMaterialCoilBo materialCoilFilter; +} diff --git a/klp-wms/src/main/java/com/klp/domain/vo/WmsMaterialCoilReportSummaryVo.java b/klp-wms/src/main/java/com/klp/domain/vo/WmsMaterialCoilReportSummaryVo.java new file mode 100644 index 00000000..071ab978 --- /dev/null +++ b/klp-wms/src/main/java/com/klp/domain/vo/WmsMaterialCoilReportSummaryVo.java @@ -0,0 +1,36 @@ +package com.klp.domain.vo; + +import lombok.Data; + +import java.util.List; +import java.util.Map; + +/** + * 报表汇总结果(不返回钢卷明细) + */ +@Data +public class WmsMaterialCoilReportSummaryVo { + + /** + * 简单汇总(总数量、总重、均重) + */ + private Integer totalCount; + private String totalWeight; + private String avgWeight; + + /** + * 异常库汇总明细(与前端 calcAbSummary 结构兼容) + */ + private List> abnormalSummary; + + /** + * 班组汇总(team -> count/weight) + */ + private Map teamSummary; + + @Data + public static class TeamSummaryItem { + private Integer count; + private String weight; + } +} diff --git a/klp-wms/src/main/java/com/klp/service/IWmsMaterialCoilService.java b/klp-wms/src/main/java/com/klp/service/IWmsMaterialCoilService.java index c7019af1..82c336ad 100644 --- a/klp-wms/src/main/java/com/klp/service/IWmsMaterialCoilService.java +++ b/klp-wms/src/main/java/com/klp/service/IWmsMaterialCoilService.java @@ -2,6 +2,7 @@ package com.klp.service; import com.klp.domain.vo.*; import com.klp.domain.bo.WmsMaterialCoilBo; +import com.klp.domain.bo.WmsMaterialCoilReportSummaryBo; import com.klp.common.core.page.TableDataInfo; import com.klp.common.core.domain.PageQuery; import com.klp.domain.vo.dashboard.CoilTrimStatisticsVo; @@ -247,5 +248,10 @@ public interface IWmsMaterialCoilService { String manufacturer); List queryExportListAll(WmsMaterialCoilBo bo); + + /** + * 报表汇总(待操作条件 + 钢卷条件) + */ + WmsMaterialCoilReportSummaryVo reportSummary(WmsMaterialCoilReportSummaryBo bo); } diff --git a/klp-wms/src/main/java/com/klp/service/impl/WmsMaterialCoilServiceImpl.java b/klp-wms/src/main/java/com/klp/service/impl/WmsMaterialCoilServiceImpl.java index 4a36e0ad..3c8b1144 100644 --- a/klp-wms/src/main/java/com/klp/service/impl/WmsMaterialCoilServiceImpl.java +++ b/klp-wms/src/main/java/com/klp/service/impl/WmsMaterialCoilServiceImpl.java @@ -4636,5 +4636,231 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService { return result; } + @Override + public WmsMaterialCoilReportSummaryVo reportSummary(WmsMaterialCoilReportSummaryBo req) { + WmsMaterialCoilBo coilFilter = req != null && req.getMaterialCoilFilter() != null + ? req.getMaterialCoilFilter() : new WmsMaterialCoilBo(); + WmsCoilPendingActionBo pendingFilter = req == null ? null : req.getPendingActionFilter(); + + if (hasAnyPendingFilter(pendingFilter)) { + List pendingCoilIds = queryCoilIdsByPendingFilter(pendingFilter); + if (CollectionUtils.isEmpty(pendingCoilIds)) { + return buildEmptySummary(); + } + coilFilter.setCoilIds(mergeCoilIds(coilFilter.getCoilIds(), pendingCoilIds)); + } + + List list = queryList(coilFilter); + return buildSummaryFromList(list); + } + + + + private boolean hasAnyPendingFilter(WmsCoilPendingActionBo bo) { + if (bo == null) { + return false; + } + return bo.getCoilId() != null + || StringUtils.isNotBlank(bo.getCurrentCoilNo()) + || bo.getActionType() != null + || CollectionUtils.isNotEmpty(bo.getActionTypes()) + || bo.getActionStatus() != null + || bo.getWarehouseId() != null + || bo.getPriority() != null + || StringUtils.isNotBlank(bo.getSourceType()) + || bo.getStartTime() != null + || bo.getEndTime() != null + || StringUtils.isNotBlank(bo.getCreateBy()) + || StringUtils.isNotBlank(bo.getUpdateBy()) + || StringUtils.isNotBlank(bo.getProcessedCoilIds()) + || bo.getIncludeDeleted() != null; + } + + private List queryCoilIdsByPendingFilter(WmsCoilPendingActionBo bo) { + LambdaQueryWrapper qw = Wrappers.lambdaQuery(); + qw.select(WmsCoilPendingAction::getCoilId); + qw.eq(bo.getCoilId() != null, WmsCoilPendingAction::getCoilId, bo.getCoilId()); + qw.like(StringUtils.isNotBlank(bo.getCurrentCoilNo()), WmsCoilPendingAction::getCurrentCoilNo, bo.getCurrentCoilNo()); + if (CollectionUtils.isNotEmpty(bo.getActionTypes())) { + qw.in(WmsCoilPendingAction::getActionType, bo.getActionTypes()); + } else { + qw.eq(bo.getActionType() != null, WmsCoilPendingAction::getActionType, bo.getActionType()); + } + if (bo.getActionStatus() != null) { + if (bo.getActionStatus() == -1) { + qw.ne(WmsCoilPendingAction::getActionStatus, 2); + } else { + qw.eq(WmsCoilPendingAction::getActionStatus, bo.getActionStatus()); + } + } + qw.eq(bo.getWarehouseId() != null, WmsCoilPendingAction::getWarehouseId, bo.getWarehouseId()); + qw.eq(bo.getPriority() != null, WmsCoilPendingAction::getPriority, bo.getPriority()); + qw.like(StringUtils.isNotBlank(bo.getSourceType()), WmsCoilPendingAction::getSourceType, bo.getSourceType()); + qw.ge(bo.getStartTime() != null, WmsCoilPendingAction::getCompleteTime, bo.getStartTime()); + qw.le(bo.getEndTime() != null, WmsCoilPendingAction::getCompleteTime, bo.getEndTime()); + qw.eq(StringUtils.isNotBlank(bo.getCreateBy()), WmsCoilPendingAction::getCreateBy, bo.getCreateBy()); + qw.eq(StringUtils.isNotBlank(bo.getUpdateBy()), WmsCoilPendingAction::getUpdateBy, bo.getUpdateBy()); + qw.like(StringUtils.isNotBlank(bo.getProcessedCoilIds()), WmsCoilPendingAction::getProcessedCoilIds, bo.getProcessedCoilIds()); + + if (bo.getIncludeDeleted() != null) { + if (bo.getIncludeDeleted() == 2) { + qw.eq(WmsCoilPendingAction::getDelFlag, 2); + } else if (bo.getIncludeDeleted() == 0) { + qw.eq(WmsCoilPendingAction::getDelFlag, 0); + } + } else { + qw.eq(WmsCoilPendingAction::getDelFlag, 0); + } + + List actions = coilPendingActionMapper.selectList(qw); + if (CollectionUtils.isEmpty(actions)) { + return Collections.emptyList(); + } + return actions.stream() + .map(WmsCoilPendingAction::getCoilId) + .filter(Objects::nonNull) + .distinct() + .collect(Collectors.toList()); + } + + private String mergeCoilIds(String coilIdsCsv, List pendingCoilIds) { + Set pendingSet = new LinkedHashSet<>(pendingCoilIds); + if (StringUtils.isBlank(coilIdsCsv)) { + return pendingSet.stream().map(String::valueOf).collect(Collectors.joining(",")); + } + + List existing = parseCsvLongs(coilIdsCsv); + if (CollectionUtils.isEmpty(existing)) { + return pendingSet.stream().map(String::valueOf).collect(Collectors.joining(",")); + } + + Set existingSet = new LinkedHashSet<>(existing); + existingSet.retainAll(pendingSet); + if (existingSet.isEmpty()) { + return "-1"; + } + return existingSet.stream().map(String::valueOf).collect(Collectors.joining(",")); + } + + private WmsMaterialCoilReportSummaryVo buildEmptySummary() { + WmsMaterialCoilReportSummaryVo vo = new WmsMaterialCoilReportSummaryVo(); + vo.setTotalCount(0); + vo.setTotalWeight("0.00"); + vo.setAvgWeight("0"); + vo.setAbnormalSummary(buildAbnormalSummary(Collections.emptyList())); + vo.setTeamSummary(Collections.emptyMap()); + return vo; + } + + private WmsMaterialCoilReportSummaryVo buildSummaryFromList(List list) { + List safeList = list == null ? Collections.emptyList() : list; + int totalCount = safeList.size(); + BigDecimal totalWeight = safeList.stream() + .map(WmsMaterialCoilVo::getNetWeight) + .filter(Objects::nonNull) + .reduce(BigDecimal.ZERO, BigDecimal::add); + String avgWeight = totalCount > 0 + ? totalWeight.divide(BigDecimal.valueOf(totalCount), 2, java.math.RoundingMode.HALF_UP).toPlainString() + : "0"; + + WmsMaterialCoilReportSummaryVo vo = new WmsMaterialCoilReportSummaryVo(); + vo.setTotalCount(totalCount); + vo.setTotalWeight(totalWeight.setScale(2, java.math.RoundingMode.HALF_UP).toPlainString()); + vo.setAvgWeight(avgWeight); + vo.setAbnormalSummary(buildAbnormalSummary(safeList)); + vo.setTeamSummary(buildTeamSummary(safeList)); + return vo; + } + + private List> buildAbnormalSummary(List list) { + int totalCount = list.size(); + int jishuCount = 0; + int miniCount = 0; + int rubbishCount = 0; + int returnCount = 0; + + BigDecimal jishuWeight = BigDecimal.ZERO; + BigDecimal miniWeight = BigDecimal.ZERO; + BigDecimal rubbishWeight = BigDecimal.ZERO; + BigDecimal returnWeight = BigDecimal.ZERO; + + for (WmsMaterialCoilVo coil : list) { + String warehouseId = coil.getWarehouseId() == null ? null : String.valueOf(coil.getWarehouseId()); + String qualityStatus = coil.getQualityStatus(); + BigDecimal netWeight = coil.getNetWeight() == null ? BigDecimal.ZERO : coil.getNetWeight(); + + if ("2019583656787259393".equals(warehouseId) || "O".equals(qualityStatus)) { + jishuCount++; + jishuWeight = jishuWeight.add(netWeight); + } else if ("2019583325311414274".equals(warehouseId)) { + miniCount++; + miniWeight = miniWeight.add(netWeight); + } else if ("2019583429955104769".equals(warehouseId) + || "D-".equals(qualityStatus) + || "D".equals(qualityStatus) + || "D+".equals(qualityStatus) + || "C-".equals(qualityStatus) + || "C".equals(qualityStatus) + || "C+".equals(qualityStatus)) { + rubbishCount++; + rubbishWeight = rubbishWeight.add(netWeight); + } else if ("2019583137616310273".equals(warehouseId)) { + returnCount++; + returnWeight = returnWeight.add(netWeight); + } + } + + List> result = new ArrayList<>(); + result.add(buildLabelValue("技术部钢卷数", String.valueOf(jishuCount))); + result.add(buildLabelValue("小钢卷库钢卷数", String.valueOf(miniCount))); + result.add(buildLabelValue("废品库钢卷数", String.valueOf(rubbishCount))); + result.add(buildLabelValue("退货库钢卷数", String.valueOf(returnCount))); + result.add(buildLabelValue("技术部钢卷重量", jishuWeight.setScale(2, java.math.RoundingMode.HALF_UP).toPlainString())); + result.add(buildLabelValue("小钢卷库钢卷重量", miniWeight.setScale(2, java.math.RoundingMode.HALF_UP).toPlainString())); + result.add(buildLabelValue("废品库钢卷重量", rubbishWeight.setScale(2, java.math.RoundingMode.HALF_UP).toPlainString())); + result.add(buildLabelValue("退货库钢卷重量", returnWeight.setScale(2, java.math.RoundingMode.HALF_UP).toPlainString())); + result.add(buildLabelValue("技术部占比", percent(jishuCount, totalCount))); + result.add(buildLabelValue("小钢卷库占比", percent(miniCount, totalCount))); + result.add(buildLabelValue("废品库占比", percent(rubbishCount, totalCount))); + result.add(buildLabelValue("退货库占比", percent(returnCount, totalCount))); + return result; + } + + private Map buildTeamSummary(List list) { + Map teamSummary = new LinkedHashMap<>(); + for (WmsMaterialCoilVo coil : list) { + String team = StringUtils.isNotBlank(coil.getTeam()) ? coil.getTeam() : "未分配"; + WmsMaterialCoilReportSummaryVo.TeamSummaryItem item = teamSummary.computeIfAbsent(team, k -> { + WmsMaterialCoilReportSummaryVo.TeamSummaryItem summaryItem = new WmsMaterialCoilReportSummaryVo.TeamSummaryItem(); + summaryItem.setCount(0); + summaryItem.setWeight("0.00"); + return summaryItem; + }); + int nextCount = item.getCount() == null ? 1 : item.getCount() + 1; + BigDecimal currWeight = StringUtils.isBlank(item.getWeight()) ? BigDecimal.ZERO : new BigDecimal(item.getWeight()); + BigDecimal netWeight = coil.getNetWeight() == null ? BigDecimal.ZERO : coil.getNetWeight(); + item.setCount(nextCount); + item.setWeight(currWeight.add(netWeight).setScale(2, java.math.RoundingMode.HALF_UP).toPlainString()); + } + return teamSummary; + } + + private Map buildLabelValue(String label, String value) { + Map map = new LinkedHashMap<>(2); + map.put("label", label); + map.put("value", value); + return map; + } + + private String percent(int part, int total) { + if (total <= 0) { + return "0.00%"; + } + return BigDecimal.valueOf(part) + .multiply(BigDecimal.valueOf(100)) + .divide(BigDecimal.valueOf(total), 2, java.math.RoundingMode.HALF_UP) + .toPlainString() + "%"; + } + }