Files
klp-oa/klp-wms/src/main/java/com/klp/controller/WmsMaterialCoilController.java
Joshi ec5da2a7ca fix(WmsMaterialCoilController): 修改编辑接口返回类型
- 将返回类型从 R<Void> 更改为 R<String>
- 修改返回方式从 toAjax() 改为 R.ok()
- 确保接口返回操作结果字符串而非空值
2026-04-15 14:33:09 +08:00

592 lines
23 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.klp.controller;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Arrays;
import java.util.stream.Collectors;
import java.util.HashMap;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.klp.domain.vo.*;
import com.klp.domain.WmsCoilPendingAction;
import com.klp.mapper.WmsCoilPendingActionMapper;
import com.klp.service.IWmsCoilPendingActionService;
import lombok.RequiredArgsConstructor;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.*;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import com.klp.common.annotation.RepeatSubmit;
import com.klp.common.annotation.Log;
import com.klp.common.core.controller.BaseController;
import com.klp.common.core.domain.PageQuery;
import com.klp.common.core.domain.R;
import com.klp.common.core.validate.AddGroup;
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;
import com.klp.common.core.page.TableDataInfo;
/**
* 钢卷物料表
*
* @author Joshi
* @date 2025-07-18
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/wms/materialCoil")
public class WmsMaterialCoilController extends BaseController {
private final IWmsMaterialCoilService iWmsMaterialCoilService;
private final IWmsCoilPendingActionService coilPendingActionService;
private final WmsCoilPendingActionMapper coilPendingActionMapper;
/**
* 查询钢卷物料表列表
*/
@GetMapping("/list")
public TableDataInfo<WmsMaterialCoilVo> list(WmsMaterialCoilBo bo, PageQuery pageQuery) {
return iWmsMaterialCoilService.queryPageList(bo, pageQuery);
}
/**
* 查询钢卷物料表列表(包含发货绑定增强字段)
*/
@GetMapping("/listWithBindInfo")
public TableDataInfo<WmsMaterialCoilBindVo> listWithBindInfo(WmsMaterialCoilBo bo, PageQuery pageQuery) {
return iWmsMaterialCoilService.queryPageListWithBindInfo(bo, pageQuery);
}
/**
* 原料钢卷库位分布查询(先库位,再钢卷映射)
*/
@GetMapping("/locationGrid")
public R<WmsMaterialCoilLocationGridVo> locationGrid(
@RequestParam @NotNull(message = "库区ID不能为空") Long actualWarehouseId,
@RequestParam(required = false, defaultValue = "raw_material") String itemType,
@RequestParam(required = false) String enterCoilNo,
@RequestParam(required = false) String currentCoilNo,
@RequestParam(required = false) String manufacturer
) {
return R.ok(iWmsMaterialCoilService.queryLocationGrid(actualWarehouseId, itemType, enterCoilNo, currentCoilNo, manufacturer));
}
/**
* 导出钢卷物料表列表(精简字段版本)
*/
@Log(title = "钢卷物料表", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(WmsMaterialCoilBo bo, HttpServletResponse response) {
List<WmsMaterialCoilExportVo> list = iWmsMaterialCoilService.queryExportList(bo);
ExcelUtil.exportExcel(list, "钢卷物料表", WmsMaterialCoilExportVo.class, response);
}
/**
* 导出钢卷物料表列表(完整字段版本)
* 导出全部字段
*/
@Log(title = "钢卷物料表", businessType = BusinessType.EXPORT)
@PostMapping("/exportAll")
public void exportSimple(WmsMaterialCoilBo bo, HttpServletResponse response) {
List<WmsMaterialCoilAllExportVo> list = iWmsMaterialCoilService.queryExportListAll(bo);
ExcelUtil.exportExcel(list, "钢卷物料表", WmsMaterialCoilAllExportVo.class, response);
}
/**
* 导出发货报表(按 coilIds联查发货单明细/主表/发货计划)
* 前端仍使用 POST 传参(建议在 body 中传 coilIds避免 URL 限制)
*/
@Log(title = "钢卷物料表-发货报表", businessType = BusinessType.EXPORT)
@PostMapping("/exportDelivery")
public void exportDelivery(WmsMaterialCoilBo bo, HttpServletResponse response) {
List<WmsMaterialCoilDeliveryExportVo> list = iWmsMaterialCoilService.queryDeliveryExportList(bo);
ExcelUtil.exportExcel(list, "发货报表", WmsMaterialCoilDeliveryExportVo.class, response);
}
/**
* 查询钢卷物料表列表POST请求支持大量coilIds查询
* 功能与GET /list相同但使用POST请求体传递参数避免URL长度限制
* 特别适合需要查询大量coilIds的场景
* 如果coilIds为空且actionIds不为空则根据actionIds查询wms_coil_pending_action表获取coilIds和完成时间
*/
@PostMapping("/listByPost")
public TableDataInfo<WmsMaterialCoilVo> listByPost(@RequestBody WmsMaterialCoilBo bo, PageQuery pageQuery) {
if ((bo.getCoilIds() == null || bo.getCoilIds().isEmpty())
&& bo.getActionIds() != null && !bo.getActionIds().isEmpty()) {
String[] actionIdArr = bo.getActionIds().split(",");
java.util.List<Long> actionIdList = Arrays.stream(actionIdArr)
.map(String::trim)
.filter(s -> !s.isEmpty())
.map(Long::parseLong)
.collect(Collectors.toList());
LambdaQueryWrapper<WmsCoilPendingAction> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.in(WmsCoilPendingAction::getActionId, actionIdList);
java.util.List<com.klp.domain.WmsCoilPendingAction> actions =
coilPendingActionMapper.selectList(queryWrapper);
if (actions != null && !actions.isEmpty()) {
Map<Long, java.util.Date> coilIdCompleteTimeMap = new HashMap<>();
List<Long> coilIdsList = actions.stream()
.map(com.klp.domain.WmsCoilPendingAction::getCoilId)
.collect(Collectors.toList());
for (com.klp.domain.WmsCoilPendingAction action : actions) {
coilIdCompleteTimeMap.put(action.getCoilId(), action.getCompleteTime());
}
bo.setCoilIds(coilIdsList.stream()
.map(String::valueOf)
.collect(Collectors.joining(",")));
TableDataInfo<WmsMaterialCoilVo> result = iWmsMaterialCoilService.queryPageList(bo, pageQuery);
for (WmsMaterialCoilVo vo : result.getRows()) {
if (coilIdCompleteTimeMap.containsKey(vo.getCoilId())) {
vo.setActionCompleteTime(coilIdCompleteTimeMap.get(vo.getCoilId()));
}
}
return result;
}
}
return iWmsMaterialCoilService.queryPageList(bo, pageQuery);
}
/**
* 报表汇总(待操作筛选 + 钢卷筛选)
* 仅返回统计结果,不返回钢卷明细
*/
@PostMapping("/reportSummary")
public R<WmsMaterialCoilReportSummaryVo> reportSummary(@RequestBody WmsMaterialCoilReportSummaryBo bo) {
return R.ok(iWmsMaterialCoilService.reportSummary(bo));
}
/**
* 钢卷发货,将钢卷状态更新为已发货,且更新发货时间
*
* @param coilId 主键
*/
@Log(title = "钢卷物料表", businessType = BusinessType.DELETE)
@GetMapping("/exportCoil/{coilId}")
public R<Void> remove(@NotNull(message = "主键不能为空")
@PathVariable("coilId") Long coilId) {
return toAjax(iWmsMaterialCoilService.exportCoil(coilId));
}
/**
* 钢卷发货撤回,将钢卷状态更新为未发货,且清空发货时间
*
* @param coilId 主键
*/
@Log(title = "钢卷物料表", businessType = BusinessType.UPDATE)
@GetMapping("/withdrawExportCoil/{coilId}")
public R<Void> withdrawExport(@NotNull(message = "主键不能为空")
@PathVariable("coilId") Long coilId) {
return toAjax(iWmsMaterialCoilService.withdrawExportCoil(coilId));
}
/**
* 获取钢卷物料表详细信息
*
* @param coilId 主键
*/
@GetMapping("/{coilId}")
public R<WmsMaterialCoilVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable("coilId") Long coilId) {
return R.ok(iWmsMaterialCoilService.queryById(coilId));
}
/**
* 新增钢卷物料表
*/
@Log(title = "钢卷物料表", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<WmsMaterialCoilVo> add(@Validated(AddGroup.class) @RequestBody WmsMaterialCoilBo bo) {
return R.ok(iWmsMaterialCoilService.insertByBo(bo));
}
/**
* 修改钢卷物料表
*/
@Log(title = "钢卷物料表", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<String> edit(@Validated(EditGroup.class) @RequestBody WmsMaterialCoilBo bo) {
return R.ok(iWmsMaterialCoilService.updateByBo(bo));
}
/**
* 合卷操作
* 在批量更新逻辑的基础上为newCoils中的每个被合的卷加入actionId和actionType
* 如果传递了actionId则更新操作记录状态为已完成并设置完成时间和合卷后的钢卷ID到processedCoilIds
* 如果未传actionId则创建新的操作记录
*/
@Log(title = "钢卷物料表-合卷", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PostMapping("/merge")
public R<Void> mergeCoils(@Validated(EditGroup.class) @RequestBody WmsMaterialCoilBo bo) {
return toAjax(iWmsMaterialCoilService.mergeCoils(bo));
}
/**
* 简单更新钢卷物料表
* 直接更新属性内容,不进行历史记录处理
*/
@Log(title = "钢卷物料表", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping("/update")
public R<Void> update(@Validated(EditGroup.class) @RequestBody WmsMaterialCoilBo bo) {
return toAjax(iWmsMaterialCoilService.updateSimple(bo));
}
/**
* 删除钢卷物料表
*
* @param coilIds 主键串
*/
@Log(title = "钢卷物料表", businessType = BusinessType.DELETE)
@DeleteMapping("/{coilIds}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable("coilIds") Long[] coilIds) {
return toAjax(iWmsMaterialCoilService.deleteWithValidByIds(Arrays.asList(coilIds), true));
}
/**
* 钢卷溯源查询
* 根据钢卷ID查询二维码解析content中的steps然后根据steps中的钢卷号反向查询数据库
*
* @param coilId 钢卷ID
* @param currentCoilNo 当前钢卷号(可选参数,用于查询特定子钢卷)
*/
@GetMapping("/trace")
public R<Map<String, Object>> trace(@RequestParam @NotNull(message = "钢卷ID不能为空") Long coilId,
@RequestParam(required = false) String currentCoilNo) {
Map<String, Object> traceResult = iWmsMaterialCoilService.queryTrace(coilId, currentCoilNo);
return R.ok(traceResult);
}
/**
* 查询各个库区中不同类型的钢卷分布情况
* 按库区分组统计每种物品类型和物品ID的钢卷数量和重量
*/
@GetMapping("/distributionByWarehouse")
public R<List<WmsMaterialCoilVo>> getDistributionByWarehouse(
@RequestParam(required = false) String itemType,
@RequestParam(required = false) Long itemId) {
List<WmsMaterialCoilVo> distribution = iWmsMaterialCoilService.getDistributionByWarehouse(itemType, itemId);
return R.ok(distribution);
}
/**
* 查询各个库区中不同类型的钢卷分布情况
* 按库区分组统计每种物品类型和物品ID的钢卷数量和重量
*/
@GetMapping("/distributionByActualWarehouse")
public R<List<WmsMaterialCoilVo>> getDistributionByActualWarehouse(
@RequestParam(required = false) String itemType,
@RequestParam(required = false) Long itemId) {
List<WmsMaterialCoilVo> distribution = iWmsMaterialCoilService.getDistributionByActualWarehouse(itemType, itemId);
return R.ok(distribution);
}
/**
* 查询不同类型的钢卷在不同库区的分布情况
* 按物品类型和物品ID分组统计每个库区的钢卷数量和重量
*/
@GetMapping("/distributionByItemType")
public R<List<WmsMaterialCoilVo>> getDistributionByItemType(
@RequestParam(required = false) String itemType,
@RequestParam(required = false) Long itemId) {
List<WmsMaterialCoilVo> distribution = iWmsMaterialCoilService.getDistributionByItemType(itemType, itemId);
return R.ok(distribution);
}
/**
* 查询不同类型的钢卷在不同库区的分布情况
* 按物品类型和物品ID分组统计每个库区的钢卷数量和重量
*/
@GetMapping("/distributionByActualItemType")
public R<List<WmsMaterialCoilVo>> getDistributionByActualItemType(
@RequestParam(required = false) String itemType,
@RequestParam(required = false) Long itemId) {
List<WmsMaterialCoilVo> distribution = iWmsMaterialCoilService.getDistributionByActualItemType(itemType, itemId);
return R.ok(distribution);
}
/**
* 批量更新钢卷发货状态
*
* @param coilIds 钢卷ID多个ID用逗号分隔
* @param status 目标状态 (0=在库, 1=在途, 2=已出库)
* @return 操作结果
*/
@Log(title = "钢卷物料表", businessType = BusinessType.UPDATE)
@PutMapping("/batchUpdateDeliveryStatus")
public R<Void> batchUpdateDeliveryStatus(
@RequestParam String coilIds,
@RequestParam Integer status) {
// 解析钢卷ID列表
List<Long> coilIdList = Arrays.stream(coilIds.split(","))
.map(String::trim)
.filter(s -> !s.isEmpty())
.map(Long::valueOf)
.collect(Collectors.toList());
Boolean result = iWmsMaterialCoilService.batchUpdateDeliveryStatus(coilIdList, status);
return result ? R.ok() : R.fail("批量更新失败");
}
/**
* 根据更新前的钢卷ID列表获取更新后的钢卷ID映射关系
*/
@GetMapping("/nextCoilIds")
public R<Map<Long, String>> getUpdatedCoilIdsByOldCoilIds(@RequestParam List<Long> oldCoilIds)
{
if (oldCoilIds == null || oldCoilIds.isEmpty()) {
return R.fail("钢卷ID列表不能为空");
}
try {
Map<Long, String> result = iWmsMaterialCoilService.getUpdatedCoilIdsByOldCoilIds(oldCoilIds);
return R.ok(result);
} catch (Exception e) {
return R.fail("获取更新后的钢卷ID失败: " + e.getMessage());
}
}
/**
* 检查钢卷号是否重复
* 前端传入入场钢卷号和当前钢卷号,返回哪个钢卷号重复
*
* @param coilId 钢卷ID修改时传入用于排除自身
* @param enterCoilNo 入场钢卷号
* @param currentCoilNo 当前钢卷号
* @param supplierCoilNo 厂家原料卷号
* @return 返回结果,包含:
* - duplicateType: "enter" (入场钢卷号重复), "current" (当前钢卷号重复), "supplier" (厂家原料卷号重复), "both" (都重复), "none" (都不重复)
* - enterCoilNoDuplicate: 入场钢卷号是否重复
* - currentCoilNoDuplicate: 当前钢卷号是否重复
* - supplierCoilNoDuplicate: 厂家原料卷号是否重复
*/
@GetMapping("/checkCoilNoDuplicate")
public R<Map<String, Object>> checkCoilNoDuplicate(
@RequestParam(required = false) Long coilId,
@RequestParam(required = false) String enterCoilNo,
@RequestParam(required = false) String currentCoilNo,
@RequestParam(required = false) String supplierCoilNo) {
Map<String, Object> result = iWmsMaterialCoilService.checkCoilNoDuplicate(coilId, enterCoilNo, currentCoilNo, supplierCoilNo);
return R.ok(result);
}
/**
* 根据入场钢卷号前缀查询最大的入场钢卷号
* 前端传入入场钢卷号的前四位,查询所有符合的入场钢卷号,返回最大值
*
* @param enterCoilNoPrefix 入场钢卷号前缀(前四位)
* @return 返回结果,包含:
* - maxEnterCoilNo: 最大的入场钢卷号
* - prefix: 前缀值
*/
@GetMapping("/getMaxEnterCoilNo")
public R<Map<String, Object>> getMaxEnterCoilNoByPrefix(
@RequestParam @NotBlank(message = "入场钢卷号前缀不能为空") String enterCoilNoPrefix) {
Map<String, Object> result = iWmsMaterialCoilService.getMaxEnterCoilNoByPrefix(enterCoilNoPrefix);
return R.ok(result);
}
/**
* 查询data_type=1的重复钢卷分组
* - 入场钢卷号重复分组
* - 当前钢卷号重复分组
*/
@GetMapping("/duplicateGroups")
public R<Map<String, Object>> getDuplicateCoilGroups() {
Map<String, Object> result = iWmsMaterialCoilService.getDuplicateCoilGroups();
return R.ok(result);
}
/**
* 回滚钢卷操作
* 根据当前钢卷ID找到历史钢卷并恢复删除当前钢卷
* 用于撤销单个更新、合卷或分卷操作
*
* @param currentCoilId 当前钢卷ID需要回滚的钢卷
* @return 操作结果,包含恢复的历史钢卷信息
*/
@Log(title = "钢卷物料表", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PostMapping("/rollback/{currentCoilId}")
public R<Map<String, Object>> rollbackCoil(
@NotNull(message = "当前钢卷ID不能为空")
@PathVariable("currentCoilId") Long currentCoilId) {
try {
Map<String, Object> rollbackResult = iWmsMaterialCoilService.rollbackCoil(currentCoilId);
return R.ok(rollbackResult);
} catch (RuntimeException e) {
return R.fail("回滚失败:" + e.getMessage());
}
}
/**
* 特殊分卷 - 第一步:锁定钢卷
* 设置钢卷独占状态
*/
@Log(title = "钢卷物料表", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PostMapping("/specialSplit/start")
public R<Long> startSpecialSplit(
@NotNull(message = "钢卷ID不能为空")
@RequestParam Long coilId,
@NotNull(message = "操作类型不能为空")
@RequestParam Integer actionType
) {
try {
Boolean result = iWmsMaterialCoilService.startSpecialSplit(coilId, actionType);
if (Boolean.TRUE.equals(result)) {
return R.ok();
}
return R.fail("钢卷锁定失败");
} catch (RuntimeException e) {
return R.fail(e.getMessage());
}
}
/**
* 特殊分卷 - 第二步:逐个创建子钢卷
* 生成单个子钢卷并更新二维码信息
*/
@Log(title = "钢卷物料表", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping("/specialSplit/createChild")
public R<WmsMaterialCoilVo> createChildCoilInSpecialSplit(
@NotNull(message = "母卷ID不能为空")
@RequestParam Long parentCoilId,
@NotNull(message = "待操作记录ID不能为空")
@RequestParam Long pendingActionId,
@RequestBody @NotNull(message = "子钢卷数据不能为空")
WmsMaterialCoilBo childCoilBo) {
try {
WmsMaterialCoilVo result =
iWmsMaterialCoilService.createChildCoilInSpecialSplit(
parentCoilId, childCoilBo, pendingActionId
);
return R.ok(result);
} catch (RuntimeException e) {
return R.fail("创建子钢卷失败:" + e.getMessage());
}
}
/**
* 特殊分卷 - 第三步:完成分卷操作
* 批量更新二维码追溯信息,设置母卷为历史数据,解除独占状态
*/
@Log(title = "钢卷物料表", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PostMapping("/specialSplit/complete")
public R<Map<String, Object>> completeSpecialSplit(
@NotNull(message = "待操作记录ID不能为空")
@RequestParam Long pendingActionId) {
try {
Map<String, Object> result =
iWmsMaterialCoilService.completeSpecialSplit(pendingActionId);
return R.ok(result);
} catch (RuntimeException e) {
return R.fail("完成分卷失败:" + e.getMessage());
}
}
// 取消单步分卷操作
@Log(title = "钢卷物料表", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PostMapping("/specialSplit/cancel")
public R<Map<String, Object>> cancelSpecialSplit(
@NotNull(message = "待操作记录ID不能为空")
@RequestParam Long pendingActionId) {
try {
Map<String, Object> result = iWmsMaterialCoilService.cancelSpecialSplit(pendingActionId);
return R.ok(result);
} catch (RuntimeException e) {
return R.fail("取消分卷失败:" + e.getMessage());
}
}
/**
* 钢卷退货操作
* 将钢卷退货到退货仓,创建新钢卷记录,将原钢卷设置为历史钢卷
*/
@Log(title = "钢卷物料表-退货", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PostMapping("/return")
public R<WmsMaterialCoilVo> returnCoil(
@NotNull(message = "钢卷ID不能为空")
@RequestParam Long coilId) {
try {
WmsMaterialCoilVo result = iWmsMaterialCoilService.returnCoil(coilId);
return R.ok(result);
} catch (RuntimeException e) {
return R.fail("退货失败:" + e.getMessage());
}
}
/**
* 冷硬卷切边统计
* 按厚度、宽度、切边要求(净边/毛边)统计钢卷数量和重量
*/
@GetMapping("/statistics/trimStatistics")
public R<List<CoilTrimStatisticsVo>> trimStatistics() {
return R.ok(iWmsMaterialCoilService.getCoilTrimStatistics());
}
/**
* 类别宽度统计
* 纵坐标:热轧卷板、冷硬卷、冷轧卷、镀锌钢卷(毛化)、镀锌管料、镀锌钢卷(未光整)
* 横坐标净边1000、1200、1220、1250 + 其他宽度及毛边 + 合计
*/
@GetMapping("/statistics/categoryWidthStatistics")
public R<List<CategoryWidthStatisticsVo>> categoryWidthStatistics() {
return R.ok(iWmsMaterialCoilService.getCategoryWidthStatistics());
}
/**
* 查询itemId和itemType不匹配的钢卷
* 检查所有钢卷的itemId是否存在于对应的表中根据itemType
* 返回所有不匹配的钢卷记录,用于数据清理和修复
*
* @return 不匹配的钢卷列表
*/
@GetMapping("/queryMismatchedItemCoils")
public R<List<WmsMaterialCoilVo>> queryMismatchedItemCoils() {
List<WmsMaterialCoilVo> mismatchedCoils = iWmsMaterialCoilService.queryMismatchedItemCoils();
return R.ok(mismatchedCoils);
}
}