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.PrDeviceMapper;
|
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.PrDevice;
|
import com.dy.pmsGlobal.pojoPr.PrProductionProcess;
|
import com.dy.pmsGlobal.util.QrCodeConstant;
|
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.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
|
import java.time.LocalDate;
|
import java.time.format.DateTimeFormatter;
|
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 PrAssemblyPlanMapper assemblyDao;
|
private UserUtil userUtil;
|
private PrBatchNumberMapper batchDao;
|
private PrDeviceMapper deviceDao;
|
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 setDeviceDao(PrDeviceMapper deviceDao) {
|
this.deviceDao = deviceDao;
|
}
|
@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);
|
insertDevice(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("计划名称不能重复");
|
}
|
PrAssemblyPlan origPlan = assemblyDao.selectByPrimaryKey(plan.id);
|
PrBatchNumber batch = batchDao.selectByPrimaryKey(origPlan.batchId);
|
//如果有投入,产品和流程不能变更
|
if(origPlan.getInputNumber() > 0){
|
if(!origPlan.proId.equals(plan.proId) || !origPlan.processId.equals(plan.processId)){
|
throw new RuntimeException("计划已投入,产品与生产流程不能变更");
|
}
|
}
|
extractedCheck(plan);
|
//产品改变则更新全部已生成设备号
|
if(origPlan.proId != plan.proId){
|
batch.proId = plan.proId;
|
batchDao.updateByPrimaryKeySelective(batch);
|
|
deviceDao.deleteByBatchId(origPlan.batchId);
|
insertDevice(plan.proId,origPlan.batchId,batch.batchNumber,plan.number,1);
|
}else if(origPlan.number < plan.number){
|
//数量增加则新增设备号
|
insertDevice(plan.proId,origPlan.batchId,batch.batchNumber,plan.number,origPlan.number+1);
|
}
|
return assemblyDao.updateByPrimaryKeySelective(plan);
|
}
|
|
private void extractedCheck(PrAssemblyPlan plan) {
|
PrProductionProcess process = processDao.selectByPrimaryKey(plan.processId);
|
if(process == null || !process.proId.equals(plan.proId)){
|
throw new RuntimeException("产品与生产流程不匹配");
|
}
|
//Fancy add 2024/07/09 如果状态为执行 ,则结束日期必须大于等于当前日期
|
if(plan.status == PlanStatusEnum.NORMAL.getCode()){
|
String endDateStr = plan.getEndDate();
|
LocalDate endDate = LocalDate.parse(endDateStr, DateTimeFormatter.ISO_LOCAL_DATE);
|
LocalDate nextDay = endDate.plusDays(1);
|
LocalDate today = LocalDate.now(); // 获取当前日期
|
if (nextDay.isBefore(today)) {
|
throw new RuntimeException("执行状态结束日期必须大于等于当前日期,请修改结束日期");
|
}
|
}
|
}
|
|
|
@Transactional
|
public int addDevice(Long planId,int num){
|
PrAssemblyPlan plan = assemblyDao.selectByPrimaryKey(planId);
|
PrBatchNumber batch = batchDao.selectByPrimaryKey(plan.batchId);
|
int count =insertDevice(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 insertDevice(Long proId,Long batchId,String batchCode,Integer number,int startIndex){
|
log.info("批量插入设备");
|
PltProduct product = productDao.selectByPrimaryKey(proId);
|
List<PrDevice> list = new java.util.ArrayList<>();
|
for(int i= startIndex ;i<= number;i++){
|
PrDevice device = new PrDevice();
|
device.proId = proId;
|
device.batchId = batchId;
|
device.deviceNo = getDeviceNo(product.code,batchCode,i);
|
device.status = 0;
|
list.add(device);
|
}
|
return insertBatchDevice(list);
|
}
|
|
private int insertBatchDevice(List<PrDevice> list) {
|
int count = 0;
|
for (int i = 0; i < list.size(); i += BATCH_SIZE) {
|
List<PrDevice> subList = list.subList(i, Math.min(i + BATCH_SIZE, list.size()));
|
// 调用MyBatis插入这批数据
|
count += deviceDao.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 getDeviceNo(String proCode,String batchCode,int index){
|
String deviceNo = QrCodeConstant.TypeProduct + proCode + batchCode +
|
String.format(CODE_FORMAT_7, index);
|
return deviceNo;
|
}
|
|
public static void main(String[] args) {
|
List<PrDevice> list = new java.util.ArrayList<>();
|
for(int i= 1 ;i<= 10000;i++){
|
|
PrDevice device = new PrDevice();
|
device.proId = 2024052310512000003l;
|
device.batchId = 2024053017154400004l;
|
device.deviceNo = getDeviceNo("002","2024001",i);
|
device.status = 0;
|
|
list.add(device);
|
}
|
list.forEach(device->{
|
System.out.println(device.deviceNo);
|
});
|
}
|
|
/**
|
* 获取当前日期
|
* @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<PrDevice>> selectSomeDevice(QueryVo queryVo) {
|
Map<String, Object> params = (Map<String, Object>) PojoUtils.generalize(queryVo);
|
//查询符合条件的记录总数
|
Long itemTotal = deviceDao.selectSomeCount(params);
|
QueryResultVo<List<PrDevice>> rsVo = new QueryResultVo<>(queryVo.pageSize, queryVo.pageCurr) ;
|
//计算分页等信息
|
rsVo.calculateAndSet(itemTotal, params);
|
//查询符合条件的记录
|
rsVo.obj = deviceDao.selectSome(params);
|
rsVo.obj.forEach(device->{
|
device.qrCode = QrCodeUtil.genQrCodeString(device.deviceNo);
|
});
|
return rsVo ;
|
}
|
|
public List<PrDevice> selectDeviceByBatchId(Long batchId) {
|
return deviceDao.selectByBatchId(batchId);
|
}
|
|
/**
|
* 只更新状态,不更新其他字段
|
* @param plan
|
* @return
|
*/
|
@Transactional
|
public int updateStatus(PrAssemblyPlan plan) {
|
if(plan.status == PlanStatusEnum.NORMAL.getCode()){
|
PrAssemblyPlan assemblyPlan = assemblyDao.selectByPrimaryKey(plan.id);
|
assemblyPlan.status = plan.status;
|
extractedCheck(assemblyPlan);
|
}
|
PrAssemblyPlan param = new PrAssemblyPlan();
|
param.id =plan.id;
|
param.status = plan.status;
|
return assemblyDao.updateByPrimaryKeySelective(param);
|
}
|
}
|