| package com.dy.pmsProduct.taskPlan; | 
|   | 
| import cn.hutool.core.date.DateUtil; | 
| import com.alibaba.excel.util.StringUtils; | 
| import com.dy.common.webFilter.UserTokenContext; | 
| import com.dy.common.webUtil.QueryResultVo; | 
| import com.dy.pmsGlobal.daoPlt.PltProductMapper; | 
| import com.dy.pmsGlobal.daoPr.PrAssemblyPlanMapper; | 
| import com.dy.pmsGlobal.daoPr.PrBatchNumberMapper; | 
| import com.dy.pmsGlobal.daoPr.PrEquipMapper; | 
| import com.dy.pmsGlobal.daoPr.PrProductionProcessMapper; | 
| import com.dy.pmsGlobal.pojoBa.BaUser; | 
| import com.dy.pmsGlobal.pojoPlt.PltProduct; | 
| import com.dy.pmsGlobal.pojoPr.PrAssemblyPlan; | 
| import com.dy.pmsGlobal.pojoPr.PrBatchNumber; | 
| import com.dy.pmsGlobal.pojoPr.PrEquip; | 
| import com.dy.pmsGlobal.pojoPr.PrProductionProcess; | 
| import com.dy.pmsGlobal.util.QrCodeUtil; | 
| import com.dy.pmsGlobal.util.UserUtil; | 
| import lombok.extern.slf4j.Slf4j; | 
| import org.apache.dubbo.common.utils.PojoUtils; | 
| import org.apache.ibatis.session.SqlSessionFactory; | 
| import org.springframework.beans.factory.annotation.Autowired; | 
| import org.springframework.stereotype.Service; | 
| import org.springframework.transaction.annotation.Transactional; | 
|   | 
| import java.util.Date; | 
| import java.util.List; | 
| import java.util.Map; | 
|   | 
| @Slf4j | 
| @Service | 
| public class AssemblySv { | 
|     private static final int BATCH_SIZE = 100; // 批量处理大小 | 
|     private static final String CODE_FORMAT = "%03d"; | 
|     private static final String CODE_FORMAT_7 = "%07d"; | 
|     private static final String TYPE_CODE_EQUIP = "110"; | 
|     private PrAssemblyPlanMapper assemblyDao; | 
|     private UserUtil userUtil; | 
|     private PrBatchNumberMapper batchDao; | 
|     private PrEquipMapper equipDao; | 
|     private PltProductMapper productDao; | 
|     private PrProductionProcessMapper processDao; | 
|     @Autowired | 
|     public void setAssemblyDao(PrAssemblyPlanMapper assemblyDao) { | 
|         this.assemblyDao = assemblyDao; | 
|     } | 
|     @Autowired | 
|     public void setBatchDao(PrBatchNumberMapper batchDao) { | 
|         this.batchDao = batchDao; | 
|     } | 
|     @Autowired | 
|     public void setUserUtil(UserUtil userUtil){ | 
|         this.userUtil = userUtil; | 
|     } | 
|     @Autowired | 
|     public void setEquipDao(PrEquipMapper equipDao) { | 
|         this.equipDao = equipDao; | 
|     } | 
|     @Autowired | 
|     public void setProductDao(PltProductMapper productDao) { | 
|         this.productDao = productDao; | 
|     } | 
|   | 
|     @Autowired | 
|     public void setProcessDao(PrProductionProcessMapper processDao) { | 
|         this.processDao = processDao; | 
|     } | 
|   | 
|     @Transactional | 
|     public int save(PrAssemblyPlan plan){ | 
|         //计划名称不能重复 | 
|         if(assemblyDao.exists(plan.name,plan.id)){ | 
|             throw new RuntimeException("计划名称不能重复"); | 
|         } | 
|         PrProductionProcess process = processDao.selectByPrimaryKey(plan.processId); | 
|         if(process == null || !process.proId.equals(plan.proId)){ | 
|             throw new RuntimeException("产品与生产流程不匹配"); | 
|         } | 
|         PrBatchNumber batch = new PrBatchNumber(); | 
|         batch.batchNumber = getNextCode(); | 
|         batch.proId = plan.proId; | 
|         batch.remark = plan.content; | 
|         BaUser loginUser = userUtil.getUser(UserTokenContext.get()); | 
|         if(loginUser!=null){ | 
|             batch.creator = loginUser.id; | 
|             plan.creator = loginUser.id; | 
|         } | 
|         batchDao.insertSelective(batch); | 
|         insertEquip(plan.proId,batch.id,batch.batchNumber,plan.number,1); | 
|   | 
|         plan.batchId = batch.id; | 
|         plan.status =PlanStatusEnum.NORMAL.getCode(); | 
|         plan.deleted = false; | 
|         return assemblyDao.insertSelective(plan); | 
|     } | 
|   | 
|     @Transactional | 
|     public int update(PrAssemblyPlan plan){ | 
|         //计划名称不能重复 | 
|         if(assemblyDao.exists(plan.name,plan.id)){ | 
|             throw new RuntimeException("计划名称不能重复"); | 
|         } | 
|         PrProductionProcess process = processDao.selectByPrimaryKey(plan.processId); | 
|         if(process == null || !process.proId.equals(plan.proId)){ | 
|             throw new RuntimeException("产品与生产流程不匹配"); | 
|         } | 
|         PrAssemblyPlan origPlan = assemblyDao.selectByPrimaryKey(plan.id); | 
|         PrBatchNumber batch = batchDao.selectByPrimaryKey(origPlan.batchId); | 
|         //产品改变则更新全部已生成设备号 | 
|         if(origPlan.proId != plan.proId){ | 
|             batch.proId = plan.proId; | 
|             batchDao.updateByPrimaryKeySelective(batch); | 
|   | 
|             equipDao.deleteByBatchId(origPlan.batchId); | 
|             insertEquip(plan.proId,origPlan.batchId,batch.batchNumber,plan.number,1); | 
|         }else if(origPlan.number < plan.number){ | 
|             //数量增加则新增设备号 | 
|             insertEquip(plan.proId,origPlan.batchId,batch.batchNumber,plan.number,origPlan.number+1); | 
|         } | 
|         return assemblyDao.updateByPrimaryKeySelective(plan); | 
|     } | 
|   | 
|   | 
|     @Transactional | 
|     public int addEquip(Long planId,int num){ | 
|         PrAssemblyPlan plan = assemblyDao.selectByPrimaryKey(planId); | 
|         PrBatchNumber batch = batchDao.selectByPrimaryKey(plan.batchId); | 
|         int count =insertEquip(plan.proId,plan.batchId,batch.batchNumber,num + plan.number,plan.number+1); | 
|         plan.number = plan.number + num; | 
|         assemblyDao.updateByPrimaryKeySelective (plan); | 
|         return count; | 
|     } | 
|   | 
|   | 
|     /** | 
|      * 批量插入  设备数据 | 
|      * @param proId 产品id | 
|      * @param batchId 批次id | 
|      * @param batchCode 批次号 | 
|      * @param number 数量 | 
|      * @return 插入数量 | 
|      */ | 
|     private int insertEquip(Long proId,Long batchId,String batchCode,Integer number,int startIndex){ | 
|         log.info("批量插入设备"); | 
|         PltProduct product = productDao.selectByPrimaryKey(proId); | 
|         List<PrEquip> list = new java.util.ArrayList<>(); | 
|         for(int i= startIndex ;i<= number;i++){ | 
|             PrEquip equip = new PrEquip(); | 
|             equip.proId = proId; | 
|             equip.batchId = batchId; | 
|             equip.equipNo = getEquipNo(product.code,batchCode,i); | 
|             equip.status = 0; | 
|             list.add(equip); | 
|         } | 
|         return insertBatchEquip(list); | 
|     } | 
|   | 
|     private int insertBatchEquip(List<PrEquip> list) { | 
|         int count = 0; | 
|         for (int i = 0; i < list.size(); i += BATCH_SIZE) { | 
|             List<PrEquip> subList = list.subList(i, Math.min(i + BATCH_SIZE, list.size())); | 
|             // 调用MyBatis插入这批数据 | 
|             count += equipDao.insertBatch(subList); | 
|         } | 
|         return count; | 
|     } | 
|   | 
|     public String getNextCode(){ | 
|         log.info("获取批次编号"); | 
|         String currentDay = getCurrentDay(); | 
|         String maxCode = batchDao.selectMaxCode(currentDay); | 
|         if (StringUtils.isBlank(maxCode)) { | 
|             return currentDay + String.format(CODE_FORMAT, 1); | 
|         } else { | 
|             int nextCode = Integer.parseInt(maxCode.replace(currentDay, "")) + 1; | 
|             // 检查溢出 | 
|             if (nextCode > 999) { | 
|                 throw new RuntimeException("批次编号溢出"); | 
|             } | 
|             return currentDay + String.format(CODE_FORMAT, nextCode); | 
|         } | 
|     } | 
|     private static String getEquipNo(String proCode,String batchCode,int index){ | 
|         String equipNo = TYPE_CODE_EQUIP + proCode + batchCode + | 
|                 String.format(CODE_FORMAT_7, index); | 
|         return equipNo; | 
|     } | 
|   | 
|     public static void main(String[] args) { | 
|         List<PrEquip> list = new java.util.ArrayList<>(); | 
|         for(int i= 1 ;i<= 10000;i++){ | 
|   | 
|             PrEquip equip = new PrEquip(); | 
|             equip.proId = 2024052310512000003l; | 
|             equip.batchId = 2024053017154400004l; | 
|             equip.equipNo = getEquipNo("002","2024001",i); | 
|             equip.status = 0; | 
|   | 
|             list.add(equip); | 
|         } | 
|         list.forEach(equip->{ | 
|             System.out.println(equip.equipNo); | 
|         }); | 
|     } | 
|   | 
|     /** | 
|      * 获取当前日期 | 
|      * @return yyMMdd | 
|      */ | 
|     private String getCurrentDay(){ | 
|         return DateUtil.format(new Date(), "yyMMdd"); | 
|     } | 
|   | 
|     public PrAssemblyPlan selectById(Long id){ | 
|         return assemblyDao.selectByPrimaryKey(id); | 
|     } | 
|   | 
|     public QueryResultVo<List<PrAssemblyPlan>> selectSome(QueryVo queryVo){ | 
|         Map<String, Object> params = (Map<String, Object>) PojoUtils.generalize(queryVo); | 
|         //查询符合条件的记录总数 | 
|         Long itemTotal = assemblyDao.selectSomeCount(params); | 
|         QueryResultVo<List<PrAssemblyPlan>> rsVo = new QueryResultVo<>(queryVo.pageSize, queryVo.pageCurr) ; | 
|         //计算分页等信息 | 
|         rsVo.calculateAndSet(itemTotal, params); | 
|         //查询符合条件的记录 | 
|         rsVo.obj = assemblyDao.selectSome(params); | 
|         return rsVo ; | 
|     } | 
|   | 
|     public QueryResultVo<List<PrEquip>> selectSomeEquip(QueryVo queryVo) { | 
|         Map<String, Object> params = (Map<String, Object>) PojoUtils.generalize(queryVo); | 
|         //查询符合条件的记录总数 | 
|         Long itemTotal = equipDao.selectSomeCount(params); | 
|         QueryResultVo<List<PrEquip>> rsVo = new QueryResultVo<>(queryVo.pageSize, queryVo.pageCurr) ; | 
|         //计算分页等信息 | 
|         rsVo.calculateAndSet(itemTotal, params); | 
|         //查询符合条件的记录 | 
|         rsVo.obj = equipDao.selectSome(params); | 
|         rsVo.obj.forEach(equip->{ | 
|             equip.qrCode = QrCodeUtil.genQrCodeString(equip.equipNo); | 
|         }); | 
|         return rsVo ; | 
|     } | 
|   | 
|     public List<PrEquip> selectEquipByBatchId(Long batchId) { | 
|         return equipDao.selectByBatchId(batchId); | 
|     } | 
|   | 
|     /** | 
|      * 只更新状态,不更新其他字段 | 
|      * @param plan | 
|      * @return | 
|      */ | 
|     @Transactional | 
|     public int updateStatus(PrAssemblyPlan plan) { | 
|         PrAssemblyPlan param = new PrAssemblyPlan(); | 
|         param.id =plan.id; | 
|         param.status = plan.status; | 
|         return assemblyDao.updateByPrimaryKeySelective(param); | 
|     } | 
| } |