feat(material-coil): 添加退火操作的二维码步骤类型支持

- 修改IWmsMaterialCoilService接口中的updateByBo方法,增加qrcodeStepType参数
- 在WmsFurnacePlanServiceImpl中实现退火操作的库位分配功能
- 添加updateQrcodeContentForCustomStep方法支持自定义二维码步骤类型
- 更新controller调用传入null作为默认值
- 完善退火操作的二维码内容更新逻辑
This commit is contained in:
2026-04-16 15:56:26 +08:00
parent c2da7640c3
commit 50670b64d8
4 changed files with 113 additions and 9 deletions

View File

@@ -234,7 +234,7 @@ public class WmsMaterialCoilController extends BaseController {
@RepeatSubmit()
@PutMapping()
public R<String> edit(@Validated(EditGroup.class) @RequestBody WmsMaterialCoilBo bo) {
return R.ok(iWmsMaterialCoilService.updateByBo(bo));
return R.ok(iWmsMaterialCoilService.updateByBo(bo, null));
}
/**

View File

@@ -59,7 +59,7 @@ public interface IWmsMaterialCoilService {
* 如果newCoils为空则进行单个更新
* @return 单个更新或合卷时返回新钢卷ID分卷时返回逗号分隔的新钢卷ID字符串
*/
String updateByBo(WmsMaterialCoilBo bo);
String updateByBo(WmsMaterialCoilBo bo, String qrcodeStepType);
/**
* 合卷操作

View File

@@ -11,11 +11,14 @@ import com.klp.common.utils.StringUtils;
import com.klp.domain.*;
import com.klp.domain.bo.WmsFurnacePlanBo;
import com.klp.domain.bo.WmsFurnacePlanCoilBo;
import com.klp.domain.bo.WmsMaterialCoilBo;
import com.klp.domain.vo.WmsFurnacePlanCoilVo;
import com.klp.domain.vo.WmsFurnacePlanVo;
import com.klp.mapper.*;
import com.klp.service.IWmsFurnacePlanService;
import com.klp.service.IWmsMaterialCoilService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -41,6 +44,7 @@ public class WmsFurnacePlanServiceImpl implements IWmsFurnacePlanService {
private final WmsMaterialCoilMapper materialCoilMapper;
private final WmsActualWarehouseMapper actualWarehouseMapper;
private final WmsWarehouseMapper warehouseMapper;
private final IWmsMaterialCoilService materialCoilService;
@Override
public WmsFurnacePlanVo queryById(Long planId) {
@@ -321,15 +325,42 @@ public class WmsFurnacePlanServiceImpl implements IWmsFurnacePlanService {
throw new ServiceException("请先分配逻辑库位");
}
java.util.Map<Long, Long> locationMap = locations.stream()
.collect(Collectors.toMap(com.klp.domain.bo.WmsFurnacePlanLocationItemBo::getCoilId,
.collect(java.util.stream.Collectors.toMap(com.klp.domain.bo.WmsFurnacePlanLocationItemBo::getCoilId,
com.klp.domain.bo.WmsFurnacePlanLocationItemBo::getWarehouseId, (a, b) -> a));
for (WmsFurnacePlanCoilVo coil : coils) {
Long targetLocation = locationMap.get(coil.getCoilId());
if (targetLocation == null) {
throw new ServiceException("钢卷" + coil.getEnterCoilNo() + "未分配库位");
}
occupyWarehouse(planId, coil.getCoilId(), targetLocation);
WmsMaterialCoil oldCoil = materialCoilMapper.selectById(coil.getCoilId());
if (oldCoil == null) {
throw new ServiceException("钢卷不存在: " + coil.getCoilId());
}
WmsMaterialCoilBo updateBo = new WmsMaterialCoilBo();
// 复制老钢卷的所有信息
BeanUtils.copyProperties(oldCoil, updateBo);
// 只覆盖需要修改的字段
updateBo.setCoilId(coil.getCoilId());
updateBo.setWarehouseId(targetLocation);
updateBo.setActualWarehouseId(-1L);
materialCoilService.updateByBo(updateBo, "annealing");
WmsFurnacePlanCoil wmsFurnacePlanCoil = planCoilMapper.selectOne(Wrappers.<WmsFurnacePlanCoil>lambdaQuery()
.eq(WmsFurnacePlanCoil::getPlanId, planId)
.eq(WmsFurnacePlanCoil::getCoilId, coil.getCoilId())
.eq(WmsFurnacePlanCoil::getDelFlag, 0));
if (wmsFurnacePlanCoil != null && wmsFurnacePlanCoil.getPlanCoilId() != null) {
planCoilMapper.update(null, Wrappers.<WmsFurnacePlanCoil>lambdaUpdate()
.eq(WmsFurnacePlanCoil::getPlanCoilId, wmsFurnacePlanCoil.getPlanCoilId())
.set(WmsFurnacePlanCoil::getLogicWarehouseId, targetLocation));
}
}
Date now = new Date();
WmsFurnacePlan update = new WmsFurnacePlan();
update.setPlanId(planId);

View File

@@ -1193,7 +1193,7 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
*/
@Override
@Transactional(rollbackFor = Exception.class)
public String updateByBo(WmsMaterialCoilBo bo) {
public String updateByBo(WmsMaterialCoilBo bo, String qrcodeStepType) {
// 判断是否批量更新
if (bo.getNewCoils() != null && !bo.getNewCoils().isEmpty()) {
// 批量更新逻辑(分卷/合卷)
@@ -1203,7 +1203,7 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
if (bo.getCoilId() == null) {
throw new RuntimeException("钢卷ID不能为空");
}
return updateBySingle(bo); // 返回新钢卷ID字符串
return updateBySingle(bo, qrcodeStepType); // 返回新钢卷ID字符串
}
}
@@ -1320,9 +1320,11 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
/**
* 单个更新
* @param bo 更新数据
* @param qrcodeStepType 二维码步骤类型null/空-默认"更新", "annealing"-退火
* @return 新钢卷ID字符串
*/
private String updateBySingle(WmsMaterialCoilBo bo) {
private String updateBySingle(WmsMaterialCoilBo bo, String qrcodeStepType) {
// 检查独占状态
validateCoilOperationPermission(bo.getCoilId(), "单个更新");
@@ -1386,7 +1388,11 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
// 3. 更新二维码内容添加更新步骤并更新current_coil_id
if (oldCoil.getQrcodeRecordId() != null) {
updateQrcodeContentForNormalUpdate(oldCoil, bo, newCoil.getCoilId());
if ("annealing".equals(qrcodeStepType)) {
updateQrcodeContentForCustomStep(oldCoil, bo, newCoil.getCoilId(), "退火", "退火操作");
} else {
updateQrcodeContentForNormalUpdate(oldCoil, bo, newCoil.getCoilId());
}
}
// 只有当新的库区ID不为空时更新库区状态
@@ -2155,6 +2161,73 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
}
}
/**
* 更新二维码内容(自定义步骤类型)
* 用于退火完成等场景action和operation可以自定义
* @param oldCoil 旧钢卷记录
* @param bo 更新数据
* @param newCoilId 新钢卷ID
* @param action 自定义action如"更新"、"退火"
* @param operation 自定义operation如"信息更新"、"退火操作"
*/
private void updateQrcodeContentForCustomStep(WmsMaterialCoil oldCoil, WmsMaterialCoilBo bo, Long newCoilId, String action, String operation) {
try {
WmsGenerateRecordVo oldRecord = generateRecordService.queryById(oldCoil.getQrcodeRecordId());
if (oldRecord == null) {
throw new RuntimeException("二维码记录不存在");
}
ObjectMapper objectMapper = new ObjectMapper();
@SuppressWarnings("unchecked")
Map<String, Object> contentMap = objectMapper.readValue(oldRecord.getContent(), Map.class);
@SuppressWarnings("unchecked")
List<Map<String, Object>> steps = (List<Map<String, Object>>) contentMap.get("steps");
if (steps == null) {
steps = new ArrayList<>();
}
Map<String, Object> newStep = new HashMap<>();
newStep.put("step", steps.size() + 1);
newStep.put("action", action);
newStep.put("operation", operation);
newStep.put("old_current_coil_no", oldCoil.getCurrentCoilNo());
newStep.put("new_current_coil_no", bo.getCurrentCoilNo() != null ? bo.getCurrentCoilNo() : oldCoil.getCurrentCoilNo());
newStep.put("old_coil_id", String.valueOf(oldCoil.getCoilId()));
newStep.put("new_coil_id", String.valueOf(newCoilId));
newStep.put("operator", LoginHelper.getUsername());
List<String> changedFields = new ArrayList<>();
if (bo.getWarehouseId() != null && !bo.getWarehouseId().equals(oldCoil.getWarehouseId())) {
changedFields.add("逻辑库区ID: " + oldCoil.getWarehouseId() + "" + bo.getWarehouseId());
}
if (bo.getActualWarehouseId() != null && !bo.getActualWarehouseId().equals(oldCoil.getActualWarehouseId())) {
changedFields.add("真实库区ID: " + oldCoil.getActualWarehouseId() + "" + bo.getActualWarehouseId());
}
newStep.put("changed_fields", String.join("; ", changedFields));
newStep.put("update_time", new java.util.Date());
steps.add(newStep);
contentMap.put("steps", steps);
if (bo.getCurrentCoilNo() != null) {
contentMap.put("current_coil_no", bo.getCurrentCoilNo());
}
if (newCoilId != null) {
contentMap.put("current_coil_id", String.valueOf(newCoilId));
}
String newContentJson = objectMapper.writeValueAsString(contentMap);
WmsGenerateRecordBo updateBo = new WmsGenerateRecordBo();
updateBo.setRecordId(oldCoil.getQrcodeRecordId());
updateBo.setContent(newContentJson);
generateRecordService.updateByBo(updateBo);
} catch (Exception e) {
throw new RuntimeException("更新二维码失败: " + e.getMessage());
}
}
/**
* 保存前的数据校验
@@ -3472,7 +3545,7 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
result.put("operationType", "SPLIT");
return result;
}
// 这里不写新是因为还有退货操作,但是也和新一样可以回滚所以直接找new_coil_id即可
// 这里不写新是因为还有退货操作和退火操作,但是也和新一样可以回滚所以直接找new_coil_id即可
// 如果找到普通更新操作
Object newCoilIdObj = step.get("new_coil_id");
if (newCoilIdObj != null && newCoilIdObj.toString().equals(currentCoilId.toString())) {