package cn.iocoder.yudao.module.mes.service.pro.maintenanceplan;
|
|
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.date.DateUtil;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
import cn.iocoder.yudao.module.erp.api.purchase.ErpPurchasePlanApi;
|
import cn.iocoder.yudao.module.erp.api.purchase.dto.ErpPurchasePlanCreateReqDTO;
|
import cn.iocoder.yudao.module.mes.controller.admin.pro.maintenanceplan.vo.MesProMaintenancePlanPageReqVO;
|
import cn.iocoder.yudao.module.mes.controller.admin.pro.maintenanceplan.vo.MesProMaintenancePlanSaveReqVO;
|
import cn.iocoder.yudao.module.mes.controller.admin.pro.workorder.vo.MesProWorkOrderSaveReqVO;
|
import cn.iocoder.yudao.module.mes.dal.dataobject.cal.team.MesCalTeamDO;
|
import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
|
import cn.iocoder.yudao.module.mes.dal.dataobject.pro.maintenanceplan.MesProMaintenancePlanDO;
|
import cn.iocoder.yudao.module.mes.dal.dataobject.pro.maintenanceplan.MesProMaintenancePlanItemDO;
|
import cn.iocoder.yudao.module.mes.dal.mysql.pro.maintenanceplan.MesProMaintenancePlanItemMapper;
|
import cn.iocoder.yudao.module.mes.dal.mysql.pro.maintenanceplan.MesProMaintenancePlanMapper;
|
import cn.iocoder.yudao.module.mes.enums.pro.MesProWorkOrderSourceTypeEnum;
|
import cn.iocoder.yudao.module.mes.enums.pro.MesProWorkOrderTypeEnum;
|
import cn.iocoder.yudao.module.mes.service.cal.team.MesCalTeamService;
|
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
|
import cn.iocoder.yudao.module.mes.service.pro.workorder.MesProWorkOrderService;
|
import jakarta.annotation.Resource;
|
import lombok.extern.slf4j.Slf4j;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.validation.annotation.Validated;
|
|
import java.math.BigDecimal;
|
import java.util.Collection;
|
import java.util.List;
|
import java.util.Map;
|
import java.util.Objects;
|
import java.util.stream.Collectors;
|
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
|
|
/**
|
* MES 电力作业计划 Service 实现类
|
*
|
* @author xiaoyi
|
*/
|
@Service
|
@Validated
|
@Slf4j
|
public class MesProMaintenancePlanServiceImpl implements MesProMaintenancePlanService {
|
|
/**
|
* 状态:草稿
|
*/
|
private static final Integer STATUS_DRAFT = 0;
|
/**
|
* 状态:已下发
|
*/
|
private static final Integer STATUS_ISSUED = 10;
|
/**
|
* 状态:已完成
|
*/
|
private static final Integer STATUS_FINISHED = 20;
|
/**
|
* 状态:已取消
|
*/
|
private static final Integer STATUS_CANCELLED = 30;
|
|
@Resource
|
private MesProMaintenancePlanMapper planMapper;
|
@Resource
|
private MesProMaintenancePlanItemMapper planItemMapper;
|
|
@Resource
|
private MesCalTeamService teamService;
|
@Resource
|
private MesMdItemService itemService;
|
|
@Resource
|
private ErpPurchasePlanApi erpPurchasePlanApi;
|
@Resource
|
private MesProWorkOrderService workOrderService;
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public Long createPlan(MesProMaintenancePlanSaveReqVO createReqVO) {
|
// 1. 生成计划编码
|
String code = generatePlanCode();
|
if (planMapper.selectByCode(code) != null) {
|
throw exception(MD_ITEM_CODE_DUPLICATE);
|
}
|
// 2. 校验班组并回填
|
fillTeamInfo(createReqVO);
|
// 3. 插入计划
|
MesProMaintenancePlanDO plan = BeanUtils.toBean(createReqVO, MesProMaintenancePlanDO.class, req -> req
|
.setCode(code)
|
.setStatus(STATUS_DRAFT));
|
planMapper.insert(plan);
|
// 4. 插入明细
|
insertPlanItems(plan.getId(), createReqVO.getItems());
|
return plan.getId();
|
}
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public void updatePlan(MesProMaintenancePlanSaveReqVO updateReqVO) {
|
// 1. 校验存在 + 草稿状态
|
MesProMaintenancePlanDO oldPlan = validatePlanCanModify(updateReqVO.getId());
|
fillTeamInfo(updateReqVO);
|
// 2. 更新主表
|
MesProMaintenancePlanDO updateObj = BeanUtils.toBean(updateReqVO, MesProMaintenancePlanDO.class, req -> req
|
.setCode(oldPlan.getCode())
|
.setStatus(oldPlan.getStatus()));
|
planMapper.updateById(updateObj);
|
// 3. 更新明细:先删后插
|
planItemMapper.deleteByPlanId(updateReqVO.getId());
|
insertPlanItems(updateReqVO.getId(), updateReqVO.getItems());
|
}
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public void deletePlan(Collection<Long> ids) {
|
if (CollUtil.isEmpty(ids)) {
|
return;
|
}
|
for (Long id : ids) {
|
validatePlanCanModify(id);
|
planItemMapper.deleteByPlanId(id);
|
planMapper.deleteById(id);
|
}
|
}
|
|
@Override
|
public MesProMaintenancePlanDO getPlan(Long id) {
|
return planMapper.selectById(id);
|
}
|
|
@Override
|
public List<MesProMaintenancePlanItemDO> getPlanItemListByPlanId(Long planId) {
|
return planItemMapper.selectListByPlanId(planId);
|
}
|
|
@Override
|
public List<MesProMaintenancePlanItemDO> getPlanItemListByPlanIds(Collection<Long> planIds) {
|
return planItemMapper.selectListByPlanIds(planIds);
|
}
|
|
@Override
|
public PageResult<MesProMaintenancePlanDO> getPlanPage(MesProMaintenancePlanPageReqVO pageReqVO) {
|
return planMapper.selectPage(pageReqVO);
|
}
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public void issuePlan(Long id) {
|
MesProMaintenancePlanDO plan = validatePlanExists(id);
|
if (!Objects.equals(plan.getStatus(), STATUS_DRAFT)) {
|
throw exception(PRO_WORK_ORDER_NOT_PREPARE);
|
}
|
planMapper.updateById(new MesProMaintenancePlanDO().setId(id).setStatus(STATUS_ISSUED));
|
}
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public void finishPlan(Long id) {
|
MesProMaintenancePlanDO plan = validatePlanExists(id);
|
if (!Objects.equals(plan.getStatus(), STATUS_ISSUED)) {
|
throw exception(PRO_WORK_ORDER_NOT_CONFIRMED);
|
}
|
planMapper.updateById(new MesProMaintenancePlanDO().setId(id).setStatus(STATUS_FINISHED));
|
}
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public Long generatePurchasePlan(Long id) {
|
// 1. 校验计划存在且已下发
|
MesProMaintenancePlanDO plan = validatePlanExists(id);
|
if (!Objects.equals(plan.getStatus(), STATUS_ISSUED)) {
|
throw exception(PRO_WORK_ORDER_NOT_CONFIRMED);
|
}
|
// 2. 获取明细
|
List<MesProMaintenancePlanItemDO> planItems = planItemMapper.selectListByPlanId(id);
|
if (CollUtil.isEmpty(planItems)) {
|
throw exception(PRO_WORK_ORDER_NOT_EXISTS);
|
}
|
// 3. 组装采购计划 DTO(MES 物料 -> MDM 物料)
|
Map<Long, MesMdItemDO> itemMap = itemService.getItemMap(
|
planItems.stream().map(MesProMaintenancePlanItemDO::getItemId).collect(Collectors.toSet()));
|
List<ErpPurchasePlanCreateReqDTO.Item> items = planItems.stream().map(item -> {
|
ErpPurchasePlanCreateReqDTO.Item dtoItem = new ErpPurchasePlanCreateReqDTO.Item();
|
MesMdItemDO mesItem = itemMap.get(item.getItemId());
|
dtoItem.setProductId(mesItem != null ? mesItem.getMdmItemId() : item.getItemId());
|
dtoItem.setProductUnitId(mesItem != null ? mesItem.getUnitMeasureId() : null);
|
dtoItem.setCount(item.getQuantity());
|
dtoItem.setRemark(item.getRemark());
|
return dtoItem;
|
}).collect(Collectors.toList());
|
// 4. 调用 ERP 生成采购计划
|
ErpPurchasePlanCreateReqDTO createReqDTO = new ErpPurchasePlanCreateReqDTO();
|
createReqDTO.setName("作业计划采购-" + plan.getName());
|
createReqDTO.setDemandSource(2); // 运维/生产计划
|
createReqDTO.setPlanDate(plan.getPlanDate());
|
createReqDTO.setRemark("来源计划: " + plan.getCode());
|
createReqDTO.setItems(items);
|
return erpPurchasePlanApi.createPurchasePlan(createReqDTO);
|
}
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public Long generateWorkOrder(Long id) {
|
// 1. 校验计划存在且已下发
|
MesProMaintenancePlanDO plan = validatePlanExists(id);
|
if (!Objects.equals(plan.getStatus(), STATUS_ISSUED)) {
|
throw exception(PRO_WORK_ORDER_NOT_CONFIRMED);
|
}
|
// 2. 已生成过工单则直接返回
|
if (plan.getWorkOrderId() != null) {
|
return plan.getWorkOrderId();
|
}
|
// 3. 组装工单
|
MesProWorkOrderSaveReqVO workOrderReq = new MesProWorkOrderSaveReqVO();
|
workOrderReq.setName(plan.getName());
|
workOrderReq.setType(convertPlanTypeToWorkOrderType(plan.getPlanType()));
|
workOrderReq.setOrderSourceType(MesProWorkOrderSourceTypeEnum.MAINTENANCE_PLAN.getType());
|
workOrderReq.setOrderSourceCode(plan.getCode());
|
workOrderReq.setQuantity(BigDecimal.ONE);
|
workOrderReq.setRequestDate(plan.getPlanDate() != null ? plan.getPlanDate() : java.time.LocalDateTime.now());
|
workOrderReq.setRemark("来自电力作业计划: " + plan.getCode());
|
Long workOrderId = workOrderService.createWorkOrder(workOrderReq);
|
// 4. 回写计划
|
MesProMaintenancePlanDO updateObj = new MesProMaintenancePlanDO();
|
updateObj.setId(id);
|
updateObj.setWorkOrderId(workOrderId);
|
planMapper.updateById(updateObj);
|
return workOrderId;
|
}
|
|
/**
|
* 计划类型 -> 工单类型映射
|
*/
|
private Integer convertPlanTypeToWorkOrderType(Integer planType) {
|
return switch (planType) {
|
case 1 -> MesProWorkOrderTypeEnum.POWER_OPERATION.getType(); // 电网运行 -> 电力运维
|
case 2 -> MesProWorkOrderTypeEnum.POWER_GENERATION.getType(); // 发电
|
case 3 -> MesProWorkOrderTypeEnum.POWER_OPERATION.getType(); // 变电运维 -> 电力运维
|
case 4 -> MesProWorkOrderTypeEnum.POWER_MAINTENANCE.getType(); // 线路检修 -> 检修
|
default -> MesProWorkOrderTypeEnum.POWER_OPERATION.getType();
|
};
|
}
|
|
private void insertPlanItems(Long planId, List<MesProMaintenancePlanSaveReqVO.Item> items) {
|
if (CollUtil.isEmpty(items)) {
|
return;
|
}
|
planItemMapper.insertBatch(items.stream().map(item ->
|
BeanUtils.toBean(item, MesProMaintenancePlanItemDO.class).setPlanId(planId))
|
.collect(Collectors.toList()));
|
}
|
|
private void fillTeamInfo(MesProMaintenancePlanSaveReqVO reqVO) {
|
if (reqVO.getTeamId() == null) {
|
return;
|
}
|
MesCalTeamDO team = teamService.validateTeamExists(reqVO.getTeamId());
|
if (team != null) {
|
reqVO.setTeamName(team.getName());
|
}
|
}
|
|
private String generatePlanCode() {
|
return "MP" + DateUtil.format(java.time.LocalDateTime.now(), "yyyyMMddHHmmss")
|
+ String.format("%03d", (int) (Math.random() * 1000));
|
}
|
|
private MesProMaintenancePlanDO validatePlanExists(Long id) {
|
MesProMaintenancePlanDO plan = planMapper.selectById(id);
|
if (plan == null) {
|
throw exception(PRO_WORK_ORDER_NOT_EXISTS);
|
}
|
return plan;
|
}
|
|
private MesProMaintenancePlanDO validatePlanCanModify(Long id) {
|
MesProMaintenancePlanDO plan = validatePlanExists(id);
|
if (!Objects.equals(plan.getStatus(), STATUS_DRAFT)) {
|
throw exception(PRO_WORK_ORDER_NOT_PREPARE);
|
}
|
return plan;
|
}
|
|
}
|