Files
klp-oa/klp-wms/src/main/java/com/klp/service/impl/WmsFurnacePlanServiceImpl.java

498 lines
19 KiB
Java
Raw Normal View History

package com.klp.service.impl;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.klp.common.core.domain.PageQuery;
import com.klp.common.core.page.TableDataInfo;
import com.klp.common.exception.ServiceException;
import com.klp.common.helper.LoginHelper;
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.domain.vo.WmsMaterialCoilVo;
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;
import java.util.*;
import java.util.stream.Collectors;
/**
* 退火计划Service业务层处理
*
* @author klp
* @date 2026-03-14
*/
@RequiredArgsConstructor
@Service
public class WmsFurnacePlanServiceImpl implements IWmsFurnacePlanService {
private final WmsFurnacePlanMapper baseMapper;
private final WmsFurnacePlanCoilMapper planCoilMapper;
private final WmsFurnaceMapper furnaceMapper;
private final WmsMaterialCoilMapper materialCoilMapper;
private final WmsActualWarehouseMapper actualWarehouseMapper;
private final WmsWarehouseMapper warehouseMapper;
private final IWmsMaterialCoilService materialCoilService;
@Override
public WmsFurnacePlanVo queryById(Long planId) {
WmsFurnacePlanVo plan = baseMapper.selectVoById(planId);
if (plan != null) {
plan.setCoilIds(queryPlanCoils(planId).stream()
.map(WmsFurnacePlanCoilVo::getCoilId)
.collect(Collectors.toList()));
fillFurnaceNames(java.util.Collections.singletonList(plan));
}
return plan;
}
@Override
public TableDataInfo<WmsFurnacePlanVo> queryPageList(WmsFurnacePlanBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<WmsFurnacePlan> lqw = buildQueryWrapper(bo);
Page<WmsFurnacePlanVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
fillFurnaceNames(result.getRecords());
return TableDataInfo.build(result);
}
@Override
public List<WmsFurnacePlanVo> queryList(WmsFurnacePlanBo bo) {
LambdaQueryWrapper<WmsFurnacePlan> lqw = buildQueryWrapper(bo);
List<WmsFurnacePlanVo> list = baseMapper.selectVoList(lqw);
fillFurnaceNames(list);
return list;
}
private LambdaQueryWrapper<WmsFurnacePlan> buildQueryWrapper(WmsFurnacePlanBo bo) {
LambdaQueryWrapper<WmsFurnacePlan> lqw = Wrappers.lambdaQuery();
lqw.like(StringUtils.isNotBlank(bo.getPlanNo()), WmsFurnacePlan::getPlanNo, bo.getPlanNo());
lqw.eq(bo.getTargetFurnaceId() != null, WmsFurnacePlan::getTargetFurnaceId, bo.getTargetFurnaceId());
lqw.eq(bo.getStatus() != null, WmsFurnacePlan::getStatus, bo.getStatus());
lqw.ge(bo.getPlanStartTime() != null, WmsFurnacePlan::getPlanStartTime, bo.getPlanStartTime());
lqw.orderByDesc(WmsFurnacePlan::getPlanStartTime);
return lqw;
}
private void fillFurnaceNames(List<WmsFurnacePlanVo> plans) {
if (plans == null || plans.isEmpty()) {
return;
}
List<Long> furnaceIds = plans.stream()
.map(WmsFurnacePlanVo::getTargetFurnaceId)
.filter(id -> id != null)
.distinct()
.collect(Collectors.toList());
if (furnaceIds.isEmpty()) {
return;
}
List<WmsFurnace> furnaces = furnaceMapper.selectBatchIds(furnaceIds);
java.util.Map<Long, String> nameMap = furnaces.stream()
.collect(Collectors.toMap(WmsFurnace::getFurnaceId, WmsFurnace::getFurnaceName, (a, b) -> a));
plans.forEach(plan -> {
if (plan.getTargetFurnaceId() != null) {
plan.setTargetFurnaceName(nameMap.get(plan.getTargetFurnaceId()));
}
});
}
@Override
public Boolean insertByBo(WmsFurnacePlanBo bo) {
WmsFurnacePlan add = BeanUtil.toBean(bo, WmsFurnacePlan.class);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setPlanId(add.getPlanId());
}
return flag;
}
@Override
public Boolean updateByBo(WmsFurnacePlanBo bo) {
WmsFurnacePlan update = BeanUtil.toBean(bo, WmsFurnacePlan.class);
validEntityBeforeSave(update, false);
return baseMapper.updateById(update) > 0;
}
private void validEntityBeforeSave(WmsFurnacePlan entity, boolean isNew) {
LambdaQueryWrapper<WmsFurnacePlan> planNoQuery = Wrappers.lambdaQuery();
planNoQuery.eq(WmsFurnacePlan::getPlanNo, entity.getPlanNo());
if (!isNew) {
planNoQuery.ne(WmsFurnacePlan::getPlanId, entity.getPlanId());
}
if (baseMapper.selectCount(planNoQuery) > 0) {
throw new ServiceException("计划号已存在");
}
WmsFurnace furnace = furnaceMapper.selectById(entity.getTargetFurnaceId());
if (furnace == null || furnace.getDelFlag() != null && furnace.getDelFlag() == 1) {
throw new ServiceException("目标炉子不存在");
}
}
@Override
public Boolean updateStatus(Long planId, Integer status) {
WmsFurnacePlan plan = baseMapper.selectById(planId);
if (plan == null) {
throw new ServiceException("计划不存在");
}
WmsFurnacePlan update = new WmsFurnacePlan();
update.setPlanId(planId);
update.setStatus(status);
boolean updated = baseMapper.updateById(update) > 0;
if (updated && plan.getTargetFurnaceId() != null) {
if (status != null && (status == 2)) {
updateFurnaceBusy(plan.getTargetFurnaceId(), 1);
}
if (status != null && (status == 3 || status == 4)) {
updateFurnaceBusy(plan.getTargetFurnaceId(), 0);
}
}
return updated;
}
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if (isValid && ids != null && !ids.isEmpty()) {
for (Long planId : ids) {
if (planCoilMapper.selectCount(Wrappers.<WmsFurnacePlanCoil>lambdaQuery()
.eq(WmsFurnacePlanCoil::getPlanId, planId)) > 0) {
throw new ServiceException("计划下存在钢卷,请先解绑");
}
}
}
return baseMapper.deleteBatchIds(ids) > 0;
}
@Override
public List<WmsFurnacePlanCoilVo> queryPlanCoils(Long planId) {
// 1. 查询计划钢卷关联记录
List<WmsFurnacePlanCoilVo> planCoils = planCoilMapper.selectVoList(
Wrappers.<WmsFurnacePlanCoil>lambdaQuery()
.eq(WmsFurnacePlanCoil::getPlanId, planId)
);
if (planCoils == null || planCoils.isEmpty()) {
return planCoils;
}
// 2. 收集钢卷ID并批量查询钢卷信息
List<Long> coilIds = planCoils.stream()
.map(WmsFurnacePlanCoilVo::getCoilId)
.filter(Objects::nonNull)
.distinct()
.collect(Collectors.toList());
if (coilIds.isEmpty()) {
return planCoils;
}
String coilIdsStr = coilIds.stream()
.map(String::valueOf)
.collect(Collectors.joining(","));
WmsMaterialCoilBo coilBo = new WmsMaterialCoilBo();
coilBo.setCoilIds(coilIdsStr);
List<WmsMaterialCoilVo> materialCoils = materialCoilService.queryList(coilBo);
Map<Long, WmsMaterialCoilVo> coilMap = materialCoils.stream()
.collect(Collectors.toMap(WmsMaterialCoilVo::getCoilId, item -> item, (a, b) -> a));
// 3. 批量查询逻辑库区名称
Map<Long, String> logicWarehouseMap = buildLogicWarehouseNameMap(
planCoils.stream()
.map(WmsFurnacePlanCoilVo::getLogicWarehouseId)
.filter(Objects::nonNull)
.distinct()
.collect(Collectors.toList())
);
// 4. 填充钢卷信息
planCoils.forEach(planCoil -> fillCoilInfo(planCoil, coilMap, logicWarehouseMap));
return planCoils;
}
/**
* 构建逻辑库区ID到名称的映射
*/
private Map<Long, String> buildLogicWarehouseNameMap(List<Long> warehouseIds) {
if (warehouseIds.isEmpty()) {
return Collections.emptyMap();
}
return warehouseMapper.selectBatchIds(warehouseIds).stream()
.collect(Collectors.toMap(WmsWarehouse::getWarehouseId,
WmsWarehouse::getWarehouseName, (a, b) -> a));
}
/**
* 填充钢卷信息
*/
private void fillCoilInfo(
WmsFurnacePlanCoilVo planCoil,
Map<Long, WmsMaterialCoilVo> coilMap,
Map<Long, String> logicWarehouseMap) {
// 填充钢卷基本信息(实际库区名称已在钢卷信息中)
WmsMaterialCoilVo coil = coilMap.get(planCoil.getCoilId());
if (coil != null) {
planCoil.setEnterCoilNo(coil.getEnterCoilNo());
planCoil.setCoil(coil);
}
// 填充逻辑库区名称
if (planCoil.getLogicWarehouseId() != null) {
planCoil.setLogicWarehouseName(logicWarehouseMap.get(planCoil.getLogicWarehouseId()));
}
}
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean bindPlanCoils(WmsFurnacePlanCoilBo bo) {
if (bo.getPlanId() == null) {
throw new ServiceException("计划ID不能为空");
}
List<Long> coilIds = parseCoilIds(bo);
if (coilIds.isEmpty()) {
throw new ServiceException("请至少选择一条钢卷");
}
WmsFurnacePlan plan = ensurePlanExist(bo.getPlanId());
if (plan.getStatus() != null && plan.getStatus() == 2) {
throw new ServiceException("计划进行中,无法再领料");
}
for (Long coilId : coilIds) {
if (planCoilMapper.selectCount(Wrappers.<WmsFurnacePlanCoil>lambdaQuery()
.eq(WmsFurnacePlanCoil::getPlanId, bo.getPlanId())
.eq(WmsFurnacePlanCoil::getCoilId, coilId)) > 0) {
continue;
}
WmsFurnacePlanCoil entity = new WmsFurnacePlanCoil();
entity.setPlanId(bo.getPlanId());
entity.setCoilId(coilId);
entity.setLogicWarehouseId(bo.getLogicWarehouseId());
entity.setFurnaceLevel(bo.getFurnaceLevel());
planCoilMapper.insert(entity);
}
return true;
}
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean unbindPlanCoil(WmsFurnacePlanCoilBo bo) {
if (bo.getPlanId() == null || bo.getCoilId() == null) {
throw new ServiceException("计划ID和钢卷ID不能为空");
}
return planCoilMapper.delete(Wrappers.<WmsFurnacePlanCoil>lambdaQuery()
.eq(WmsFurnacePlanCoil::getPlanId, bo.getPlanId())
.eq(WmsFurnacePlanCoil::getCoilId, bo.getCoilId())) > 0;
}
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean inFurnace(Long planId) {
WmsFurnacePlan plan = baseMapper.selectById(planId);
if (plan == null) {
throw new ServiceException("计划不存在");
}
if (plan.getActualStartTime() != null) {
throw new ServiceException("计划已入炉");
}
if (planCoilMapper.selectCount(Wrappers.<WmsFurnacePlanCoil>lambdaQuery()
.eq(WmsFurnacePlanCoil::getPlanId, planId)) <= 0) {
throw new ServiceException("计划未绑定钢卷");
}
Date now = new Date();
WmsFurnacePlan update = new WmsFurnacePlan();
update.setPlanId(planId);
update.setActualStartTime(now);
update.setStatus(2);
baseMapper.updateById(update);
updateFurnaceBusy(plan.getTargetFurnaceId(), 1);
List<WmsFurnacePlanCoilVo> coils = queryPlanCoils(planId);
for (WmsFurnacePlanCoilVo coil : coils) {
releaseActualWarehouse(coil.getCoilId());
}
return true;
}
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean completePlan(Long planId, List<com.klp.domain.bo.WmsFurnacePlanLocationItemBo> locations) {
WmsFurnacePlan plan = baseMapper.selectById(planId);
if (plan == null) {
throw new ServiceException("计划不存在");
}
if (plan.getStatus() == null || plan.getStatus() != 2) {
throw new ServiceException("计划未进行中,无法完成");
}
List<WmsFurnacePlanCoilVo> coils = queryPlanCoils(planId);
if (coils == null || coils.isEmpty()) {
throw new ServiceException("计划未绑定钢卷");
}
if (locations == null || locations.isEmpty()) {
throw new ServiceException("请先分配逻辑库位");
}
java.util.Map<Long, Long> locationMap = locations.stream()
.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() + "未分配库位");
}
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);
updateBo.setCreateTime(new Date());
updateBo.setUpdateTime(new Date());
updateBo.setExclusiveStatus(0);
updateBo.setCreateBy(LoginHelper.getUsername());
updateBo.setUpdateBy(LoginHelper.getUsername());
updateBo.setNextWarehouseId(null);
updateBo.setStatus(0);
updateBo.setExportBy(null);
updateBo.setExportTime(null);
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);
update.setStatus(3);
update.setEndTime(now);
baseMapper.updateById(update);
updateFurnaceBusy(plan.getTargetFurnaceId(), 0);
return true;
}
private void releaseActualWarehouse(Long coilId) {
WmsMaterialCoil coil = materialCoilMapper.selectById(coilId);
if (coil == null) {
return;
}
Long actualWarehouseId = coil.getActualWarehouseId();
if (actualWarehouseId != null) {
WmsActualWarehouse warehouse = new WmsActualWarehouse();
warehouse.setActualWarehouseId(actualWarehouseId);
warehouse.setIsEnabled(1);
actualWarehouseMapper.updateById(warehouse);
}
2026-03-15 15:10:17 +08:00
materialCoilMapper.update(null, Wrappers.<WmsMaterialCoil>lambdaUpdate()
.eq(WmsMaterialCoil::getCoilId, coilId)
.set(WmsMaterialCoil::getActualWarehouseId, null)
.set(WmsMaterialCoil::getExclusiveStatus, 2));
}
private List<Long> parseCoilIds(WmsFurnacePlanCoilBo bo) {
List<Long> coilIds = new ArrayList<>();
if (bo.getCoilId() != null) {
coilIds.add(bo.getCoilId());
}
if (StringUtils.isNotBlank(bo.getCoilIds())) {
String[] parts = bo.getCoilIds().split(",");
for (String part : parts) {
if (StringUtils.isNotBlank(part)) {
coilIds.add(Long.parseLong(part.trim()));
}
}
}
if (StringUtils.isNotBlank(bo.getEnterCoilNos())) {
coilIds.addAll(resolveCoilIdsByEnterNos(bo.getEnterCoilNos()));
}
if (StringUtils.isNotBlank(bo.getCurrentCoilNos())) {
coilIds.addAll(resolveCoilIdsByCurrentNos(bo.getCurrentCoilNos()));
}
return coilIds.stream().distinct().collect(Collectors.toList());
}
private List<Long> resolveCoilIdsByEnterNos(String enterCoilNos) {
List<String> nos = splitCommaValues(enterCoilNos);
if (nos.isEmpty()) {
return new ArrayList<>();
}
return materialCoilMapper.selectList(Wrappers.<WmsMaterialCoil>lambdaQuery()
.in(WmsMaterialCoil::getEnterCoilNo, nos)
.eq(WmsMaterialCoil::getDelFlag, 0))
.stream()
.map(WmsMaterialCoil::getCoilId)
.collect(Collectors.toList());
}
private List<Long> resolveCoilIdsByCurrentNos(String currentCoilNos) {
List<String> nos = splitCommaValues(currentCoilNos);
if (nos.isEmpty()) {
return new ArrayList<>();
}
return materialCoilMapper.selectList(Wrappers.<WmsMaterialCoil>lambdaQuery()
.in(WmsMaterialCoil::getCurrentCoilNo, nos)
.eq(WmsMaterialCoil::getDelFlag, 0))
.stream()
.map(WmsMaterialCoil::getCoilId)
.collect(Collectors.toList());
}
private List<String> splitCommaValues(String values) {
List<String> result = new ArrayList<>();
if (StringUtils.isBlank(values)) {
return result;
}
String[] parts = values.split(",");
for (String part : parts) {
if (StringUtils.isNotBlank(part)) {
result.add(part.trim());
}
}
return result;
}
private WmsFurnacePlan ensurePlanExist(Long planId) {
WmsFurnacePlan plan = baseMapper.selectById(planId);
if (plan == null) {
throw new ServiceException("计划不存在");
}
return plan;
}
private void updateFurnaceBusy(Long furnaceId, Integer busyFlag) {
if (furnaceId == null) {
return;
}
WmsFurnace update = new WmsFurnace();
update.setFurnaceId(furnaceId);
update.setBusyFlag(busyFlag);
furnaceMapper.updateById(update);
}
}