package com.dy.pmsStation.assemblyStep;
|
|
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
|
import com.dy.pmsGlobal.daoOth.OthFileMapper;
|
import com.dy.pmsGlobal.daoPlt.*;
|
import com.dy.pmsGlobal.daoPr.PrAssemblyPlanMapper;
|
import com.dy.pmsGlobal.daoPr.PrProductionNodeMapper;
|
import com.dy.pmsGlobal.daoSta.*;
|
import com.dy.pmsGlobal.dyFile.FileOperate;
|
import com.dy.pmsGlobal.dyFile.FileRestVo;
|
import com.dy.pmsGlobal.pojoOth.OthFile;
|
import com.dy.pmsGlobal.pojoPlt.*;
|
import com.dy.pmsGlobal.pojoPr.PrAssemblyPlan;
|
import com.dy.pmsGlobal.pojoPr.PrProductionNode;
|
import com.dy.pmsGlobal.pojoPr.PrWorkingInstruction;
|
import com.dy.pmsGlobal.pojoSta.*;
|
import com.dy.pmsGlobal.util.DeviceStatus;
|
import com.dy.pmsGlobal.util.QrCodeConstant;
|
import lombok.extern.slf4j.Slf4j;
|
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
|
import java.util.*;
|
|
@Slf4j
|
@Service
|
public class AssemblyStepSv {
|
private static final String WORK_TYPE_ASSEMBLY = "1";
|
private static final String WORK_TYPE_TEST = "2";
|
private static final String WORK_TYPE_INSPECTION = "3";
|
private static final String WORK_TYPE_REPAIR = "4";
|
|
private StaDeviceLastMapper deviceLastDao;
|
private StaDeviceLifeMapper deviceLifeDao;
|
private StaDeviceLifeLastMapper deviceLifeLastDao;
|
private StaWipSnExMapper wipSnExDao;
|
private StaDeviceProductionLogMapper deviceProductionLogDao;
|
private StaAssemblyWorkLastMapper assemblyWorkLastDao;
|
private PrAssemblyPlanMapper assemblyPlanDao;
|
// private PrProductionProcessMapper processDao;
|
private PrProductionNodeMapper nodeDao;
|
private StaRepairInfoMapper repairInfoDao;
|
private PltProductQualityInspectionItemsMapper qualityItemsDao;
|
private PltProductTestInspectionItemsMapper testItemsDao;
|
private PltProductMapper productDao;
|
private PltProParamsMapper paramsDao;
|
private PltProductFileMapper productFileDao;
|
private FileOperate fileOperate;
|
private OthFileMapper othFileMapper;
|
@Value("${dy.webFile.fmUrl}")
|
private String fmUrl;
|
@Autowired
|
public void setDeviceLastDao(StaDeviceLastMapper deviceLastDao) {
|
this.deviceLastDao = deviceLastDao;
|
}
|
@Autowired
|
public void setDeviceLifeDao(StaDeviceLifeMapper deviceLifeDao) {
|
this.deviceLifeDao = deviceLifeDao;
|
}
|
@Autowired
|
public void setWipSnExDao(StaWipSnExMapper wipSnExDao) {
|
this.wipSnExDao = wipSnExDao;
|
}
|
@Autowired
|
public void setDeviceProductionLogDao(StaDeviceProductionLogMapper deviceProductionLogDao) {
|
this.deviceProductionLogDao = deviceProductionLogDao;
|
}
|
@Autowired
|
public void setAssemblyWorkLastDao(StaAssemblyWorkLastMapper assemblyWorkLastDao) {
|
this.assemblyWorkLastDao = assemblyWorkLastDao;
|
}
|
@Autowired
|
public void setAssemblyPlanDao(PrAssemblyPlanMapper assemblyPlanDao) {
|
this.assemblyPlanDao = assemblyPlanDao;
|
}
|
@Autowired
|
public void setNodeDao(PrProductionNodeMapper nodeDao) {
|
this.nodeDao = nodeDao;
|
}
|
@Autowired
|
public void setRepairInfoDao(StaRepairInfoMapper repairInfoDao) {
|
this.repairInfoDao = repairInfoDao;
|
}
|
@Autowired
|
public void setQualityItemsDao(PltProductQualityInspectionItemsMapper qualityItemsDao) {
|
this.qualityItemsDao = qualityItemsDao;
|
}
|
@Autowired
|
public void setTestItemsDao(PltProductTestInspectionItemsMapper testItemsDao) {
|
this.testItemsDao = testItemsDao;
|
}
|
@Autowired
|
public void setProductDao(PltProductMapper productDao) {
|
this.productDao = productDao;
|
}
|
|
@Autowired
|
public void setParamsDao(PltProParamsMapper paramsDao) {
|
this.paramsDao = paramsDao;
|
}
|
|
@Autowired
|
public void setProductFileDao(PltProductFileMapper productFileDao) {
|
this.productFileDao = productFileDao;
|
}
|
|
@Autowired
|
public void setFileOperate(FileOperate fileOperate) {
|
this.fileOperate = fileOperate;
|
}
|
|
@Autowired
|
public void setOthFileMapper(OthFileMapper othFileMapper) {
|
this.othFileMapper = othFileMapper;
|
}
|
@Autowired
|
public void setDeviceLifeLastDao(StaDeviceLifeLastMapper deviceLifeLastDao) {
|
this.deviceLifeLastDao = deviceLifeLastDao;
|
}
|
|
@Transactional
|
public int save(QueryVo params) {
|
long workId = Long.parseLong(params.workId);
|
StaAssemblyWorkLast workLast = assemblyWorkLastDao.selectByPrimaryKey(workId);
|
if (workLast == null) {
|
throw new RuntimeException("系统中没有该条登录信息");//工单不存在
|
}
|
PrAssemblyPlan plan = assemblyPlanDao.selectByPrimaryKey(workLast.getPlanId());
|
// 验证并处理设备号和物料号
|
Set<String> deviceSet = new HashSet<>(Arrays.asList(params.deviceNo));
|
// 分类设备号和物料号
|
List<String> deviceList = new ArrayList<>();
|
List<String> materialList = new ArrayList<>();
|
List<PltProduct> productList = productDao.selectAll(null);
|
deviceSet.forEach(device -> {
|
if (device.contains(plan.batchNo)) {
|
deviceList.add(device);
|
} else if(isOurProduct(device,productList)){
|
materialList.add(device);
|
}
|
});
|
|
if (deviceList.isEmpty()) {
|
throw new RuntimeException("设备号(" + Arrays.toString(params.deviceNo) + ")均不属于当前任务计划");
|
}
|
if (deviceList.size() > 1) {
|
throw new RuntimeException("设备号有且只能有一个属于当前任务计划");
|
}
|
|
StaDeviceLast deviceLast = buildDeviceLast(params, workLast, deviceList.get(0));
|
int count = deviceLast.id == null ? deviceLastDao.insertSelective(deviceLast) :
|
deviceLastDao.updateByPrimaryKeySelective(deviceLast);
|
|
saveDeviceProductionLog(deviceLast);
|
|
PrProductionNode node = nodeDao.selectByPrimaryKey(workLast.nodeId);
|
if (node.isRecord) {
|
saveDeviceLife(deviceLast);
|
}
|
if (CollectionUtils.isNotEmpty(materialList)) {
|
saveSnEx(workLast, deviceList, materialList, plan);
|
}
|
return count;
|
}
|
|
private void saveDeviceProductionLog(StaDeviceLast deviceLast) {
|
StaDeviceProductionLog log = new StaDeviceProductionLog();
|
BeanUtils.copyProperties(deviceLast, log);
|
log.setId(null); // 设备生产日志ID设为null,表示新增
|
deviceProductionLogDao.insertSelective(log);
|
}
|
|
private void saveDeviceLife(StaDeviceLast deviceLast) {
|
StaDeviceLife life = new StaDeviceLife();
|
BeanUtils.copyProperties(deviceLast, life);
|
life.setId(null);
|
deviceLifeDao.insertSelective(life);
|
|
StaDeviceLifeLast lastLife = new StaDeviceLifeLast();
|
BeanUtils.copyProperties(deviceLast, lastLife);
|
lastLife.setId(null);
|
int count = deviceLifeLastDao.updateByDeviceNo(lastLife);
|
if (count == 0){
|
deviceLifeLastDao.insertSelective(lastLife);
|
}
|
}
|
|
private StaDeviceLast buildDeviceLast(QueryVo params, StaAssemblyWorkLast workLast,String deviceNo) {
|
//组装数据
|
StaDeviceLast record = new StaDeviceLast();
|
//pr_assembly_plan input_number +1 投入数加1
|
PrAssemblyPlan assemblyPlan = assemblyPlanDao.selectByPrimaryKey(workLast.planId);
|
StaDeviceLast preRecord = deviceLastDao.selectByDeviceNo(deviceNo);
|
if (preRecord != null) {
|
record.id = preRecord.id;
|
record.inTime = preRecord.outTime;
|
record.outLineTime = preRecord.outLineTime;
|
}else{
|
record.inTime = new Date();
|
record.inLineTime = new Date();
|
assemblyPlan.setInputNumber(assemblyPlan.getInputNumber() + 1);
|
}
|
record.outTime = new Date();
|
|
record.planId = workLast.planId;
|
record.workId = Long.parseLong(params.workId);
|
record.stationId = workLast.stationId;
|
record.deviceNo = deviceNo;
|
record.currNode = workLast.nodeId;
|
|
record.updatedBy = workLast.userId;
|
record.assistants = workLast.assistants;
|
record.errorMsg = params.errorMsg;
|
|
PrProductionNode node = nodeDao.selectByPrimaryKey(workLast.nodeId);
|
record.nodeContent = node.content;
|
if (node.isRecord) {
|
record.deviceCycleContent = node.deviceCycleContent;
|
}
|
if(node.getIsEnd() && record.outLineTime == null){
|
record.outLineTime = new Date();
|
assemblyPlan.setOutputNumber(assemblyPlan.getOutputNumber() + 1);
|
}
|
assemblyPlanDao.updateByPrimaryKeySelective(assemblyPlan);
|
record.status = getStatus(params.status, node.isEnd,workLast.workType.toString());
|
return record;
|
}
|
|
private void saveSnEx(StaAssemblyWorkLast workLast, List<String> deviceList, List<String> materialList, PrAssemblyPlan plan) {
|
for (String material : materialList) {
|
StaWipSnEx snEx = new StaWipSnEx();
|
snEx.deviceNo = deviceList.get(0);
|
snEx.productId = plan.process.proId;
|
snEx.productNo = material;
|
snEx.createTime = workLast.startTime;
|
snEx.createBy = workLast.userId;
|
snEx.productName = plan.proName;
|
wipSnExDao.insertSelective(snEx);
|
}
|
}
|
|
/**
|
* 状态: 1:组装中,2:完成,3:维修,4:报废
|
*
|
* @param status 状态
|
* @param isEndNode 是否结束节点
|
* @return 状态
|
*/
|
private int getStatus(String status, boolean isEndNode,String workType) {
|
//组装,维修
|
if (WORK_TYPE_ASSEMBLY.equals(workType)||WORK_TYPE_REPAIR.equals(workType)) {
|
return switch (status) {
|
case QrCodeConstant.MarkOk -> isEndNode? DeviceStatus.COMPLETED.getCode(): DeviceStatus.ASSEMBLING.getCode();
|
case QrCodeConstant.MarkUnqualified, QrCodeConstant.MarkPreUnqualified -> DeviceStatus.REPAIR.getCode();
|
case QrCodeConstant.MarkWaste -> DeviceStatus.WASTE.getCode();
|
default -> throw new RuntimeException("状态错误");
|
};
|
//品检,测试
|
}else if(WORK_TYPE_INSPECTION.equals(workType)||WORK_TYPE_TEST.equals(workType)){
|
return switch (status) {
|
case QrCodeConstant.MarkOk -> DeviceStatus.COMPLETED.getCode();
|
case QrCodeConstant.MarkUnqualified -> DeviceStatus.TEST_FAILED.getCode();
|
case QrCodeConstant.MarkWaste -> DeviceStatus.WASTE.getCode();
|
default -> throw new RuntimeException("状态错误");
|
};
|
}
|
throw new RuntimeException("状态错误,无效的节点类型: " + workType);
|
}
|
|
public int repair(QueryVo vo) {
|
long workId = Long.parseLong(vo.workId);
|
StaAssemblyWorkLast workLast = assemblyWorkLastDao.selectByPrimaryKey(workId);
|
if (workLast == null) {
|
throw new RuntimeException("系统中没有该条登录信息");
|
}
|
StaDeviceLast preDeviceRecord = deviceLastDao.selectByDeviceNo(vo.deviceNo[0]);
|
StaRepairInfo repairInfo = new StaRepairInfo();
|
repairInfo.workId = workId;
|
repairInfo.deviceNo = vo.deviceNo[0];
|
repairInfo.repairTime = new Date();
|
repairInfo.repairBy = workLast.userId;
|
repairInfo.repairReason = vo.errorMsg;
|
repairInfo.fromNode = preDeviceRecord.currNode;
|
repairInfoDao.insertSelective(repairInfo);
|
|
StaDeviceLast deviceLast = buildDeviceLast(vo, workLast, vo.deviceNo[0]);
|
|
int count = deviceLast.id == null ? deviceLastDao.insertSelective(deviceLast) :
|
deviceLastDao.updateByPrimaryKeySelective(deviceLast);
|
saveDeviceProductionLog(deviceLast);
|
boolean isEndNode = nodeDao.isEndNode(preDeviceRecord.currNode);
|
if (isEndNode) {
|
saveDeviceLife(deviceLast);
|
}
|
return count;
|
}
|
|
public int testing(QueryVo vo) {
|
long workId = Long.parseLong(vo.workId);
|
StaAssemblyWorkLast workLast = assemblyWorkLastDao.selectByPrimaryKey(workId);
|
if (workLast == null) {
|
throw new RuntimeException("系统中没有该条登录信息");
|
}
|
|
StaDeviceLast deviceLast = buildDeviceLast(vo, workLast, vo.deviceNo[0]);
|
int count = deviceLast.id == null ? deviceLastDao.insertSelective(deviceLast) :
|
deviceLastDao.updateByPrimaryKeySelective(deviceLast);
|
saveDeviceProductionLog(deviceLast);
|
return count;
|
}
|
//根据节点查出节点作业指导书
|
public PrProductionNode getSopByNodeId(String nodeId) {
|
if(com.alibaba.excel.util.StringUtils.isBlank(nodeId)){
|
throw new RuntimeException("节点ID不能为空");
|
}
|
PrProductionNode node = nodeDao.selectByPrimaryKey(Long.parseLong(nodeId));
|
if(node == null){
|
throw new RuntimeException("节点ID不存在,请检查");
|
}
|
if(node.instruction != null){
|
addUrl(node.instruction);
|
}
|
return node;
|
}
|
//主要技术参数 俩个方法同 platform-->product-->productSv
|
public List<PltProductParams> getParamsByProId(String proId) {
|
if(StringUtils.isBlank(proId)){
|
throw new RuntimeException("产品ID不能为空");
|
}
|
List<PltProductParams> proParams = paramsDao.selectParams(Long.parseLong(proId));
|
return proParams;
|
}
|
// 根据产品查出产品文件
|
public List<PltProductFile> getFileByProId(String proId) {
|
if(StringUtils.isBlank(proId)){
|
throw new RuntimeException("产品ID不能为空");
|
}
|
List<PltProductFile> proFiles = productFileDao.selectDocuments(Long.parseLong(proId));
|
proFiles.stream().forEach(doc -> {
|
OthFile file = othFileMapper.selectByPrimaryKey(doc.fileId);
|
if (file == null) {
|
return;
|
}
|
FileRestVo fileRestVo = fileOperate.parseHashcode(fmUrl, file.hash);
|
doc.webUrl = fileRestVo.fileSysRestUrl + fileRestVo.fileWebDownloadPath + doc.fileId;
|
doc.orgName = file.orgName;
|
doc.extName = file.extName;
|
});
|
return proFiles;
|
}
|
|
public List<PltProductQualityInspectionItems> getQualityItems(String proId) {
|
Map<String, Object> params = new HashMap<>();
|
params.put("proId", proId);//item start count
|
//查询符合条件的记录
|
return qualityItemsDao.selectSome(params);
|
}
|
|
public List<PltProductTestInspectionItems> getTestItems(String proId) {
|
Map<String, Object> params = new HashMap<>();
|
params.put("proId", proId);
|
return testItemsDao.selectSome(params);
|
}
|
|
private boolean isOurProduct(String deviceNo, List<PltProduct> products){
|
if(StringUtils.isNotEmpty(deviceNo) && deviceNo.length() ==22 ){
|
for(PltProduct product:products){
|
if(deviceNo.startsWith(QrCodeConstant.TypeProduct + product.getCode())){
|
return true;
|
}
|
}
|
}
|
return false;
|
}
|
private void addUrl(PrWorkingInstruction ins) {
|
if (ins == null || ins.fileId == null) {
|
return;
|
}
|
OthFile file = othFileMapper.selectByPrimaryKey(ins.fileId);
|
if (file == null) {
|
return;
|
}
|
FileRestVo fileRestVo = fileOperate.parseHashcode(fmUrl, file.hash);
|
ins.webUrl = fileRestVo.fileSysRestUrl + fileRestVo.fileWebDownloadPath + ins.fileId;
|
ins.orgName = file.orgName;
|
ins.extName = file.extName;
|
}
|
private PltProduct addWebUrl(PltProduct pro) {
|
if (pro != null) {
|
if (pro.image != null) {
|
String filePathWithWebUrl = getFilePathWithWebUrl(pro.image);
|
pro.imageWebPath = filePathWithWebUrl;
|
pro.imageWebPathZip = fileOperate.getImgFileZipPath(filePathWithWebUrl);
|
}
|
|
pro.proFiles.stream().forEach(doc -> {
|
OthFile file = othFileMapper.selectByPrimaryKey(doc.fileId);
|
if (file == null) {
|
return;
|
}
|
FileRestVo fileRestVo = fileOperate.parseHashcode(fmUrl, file.hash);
|
doc.webUrl = fileRestVo.fileSysRestUrl + fileRestVo.fileWebDownloadPath + doc.fileId;
|
doc.orgName = file.orgName;
|
doc.extName = file.extName;
|
});
|
}
|
return pro;
|
}
|
private String getFilePathWithWebUrl(Long fileId) {
|
OthFile file = othFileMapper.selectByPrimaryKey(fileId);
|
FileRestVo fileRestVo = fileOperate.parseHashcode(fmUrl, file.hash);
|
return fileRestVo.fileWebUrl + file.filePath;
|
}
|
|
public Map<String,String> queryByDeviceNo(String deviceNo) {
|
Map<String,String> map = new HashMap<>();
|
map.put("deviceNo", deviceNo);
|
map.put("proName", "");
|
map.put("proType", "");
|
|
PltProduct product = productDao.selectByCode(deviceNo.substring(3,6));
|
if(product != null){
|
map.put("proName", product.getName());
|
map.put("proType", product.getType());
|
}
|
/*else{
|
throw new RuntimeException("该编码("+deviceNo +")不是主要物料(系统中管控的其他设备)");
|
}*/
|
return map;
|
}
|
|
public List<StaDeviceLife> queryLifeByDeviceNo(String deviceNo) {
|
return deviceLifeDao.selectByDeviceNo(deviceNo);
|
}
|
|
public List<StaDeviceProductionLog> queryLogByDeviceNo(String devoiceNo) {
|
return deviceProductionLogDao.selectByDeviceNo(devoiceNo);
|
}
|
}
|