chen пре 1 година
родитељ
комит
317eea257c
16 измењених фајлова са 759 додато и 76 уклоњено
  1. 1 1
      src/main/java/org/springblade/api/CameraApiController.java
  2. 178 1
      src/main/java/org/springblade/applet/ProductApiController.java
  3. 21 1
      src/main/java/org/springblade/applet/ProductReworkApiController.java
  4. 21 0
      src/main/java/org/springblade/modules/pl/process/entity/ProcessItemEntity.java
  5. 1 1
      src/main/java/org/springblade/modules/pl/processConfig/controller/ProcessConfigController.java
  6. 5 0
      src/main/java/org/springblade/modules/pl/product/entity/ProductEntity.java
  7. 183 69
      src/main/java/org/springblade/modules/pl/product/service/impl/ProductImageRecordServiceImpl.java
  8. 8 0
      src/main/java/org/springblade/modules/pl/product/vo/ProductVO.java
  9. 2 0
      src/main/java/org/springblade/modules/pl/productBatch/service/impl/ProductBatchServiceImpl.java
  10. 49 0
      src/main/java/org/springblade/modules/pl/productProcess/entity/ProductProcessEntity.java
  11. 23 0
      src/main/java/org/springblade/modules/pl/productProcess/entity/ProductProcessItemEntity.java
  12. 3 0
      src/main/java/org/springblade/modules/pl/productProcess/service/IProductProcessService.java
  13. 215 0
      src/main/java/org/springblade/modules/pl/productProcess/service/impl/ProductProcessServiceImpl.java
  14. 41 0
      src/main/java/org/springblade/modules/pl/productProcess/vo/ProductProcessSubmitVO.java
  15. 6 0
      src/main/java/org/springblade/modules/pl/productProcess/vo/ProductProcessVO.java
  16. 2 3
      src/main/java/org/springblade/modules/pl/productRework/service/impl/ProductReworkServiceImpl.java

+ 1 - 1
src/main/java/org/springblade/api/CameraApiController.java

@@ -93,7 +93,7 @@ public class CameraApiController {
 		// 参数1:获取锁的最大等待时间(期间会多次重试获取锁)
 		// 参数2:锁自动释放时间
 		// 参数3:时间单位
-		boolean isGetLock = lock.tryLock(30, 60, TimeUnit.SECONDS);
+		boolean isGetLock = lock.tryLock(50, 60, TimeUnit.SECONDS);
 		String fileUrl = "";
 		if (isGetLock) {
 			try {

+ 178 - 1
src/main/java/org/springblade/applet/ProductApiController.java

@@ -6,17 +6,31 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
+import liquibase.pro.packaged.I;
 import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.flowable.engine.impl.persistence.entity.ProcessDefinitionEntityImpl;
+import org.redisson.api.RLock;
+import org.redisson.api.RedissonClient;
 import org.springblade.core.log.annotation.ApiLog;
 import org.springblade.core.mp.support.Condition;
 import org.springblade.core.mp.support.Query;
 import org.springblade.core.secure.BladeUser;
 import org.springblade.core.secure.utils.AuthUtil;
 import org.springblade.core.tool.api.R;
+import org.springblade.core.tool.utils.BeanUtil;
 import org.springblade.core.tool.utils.Func;
+import org.springblade.core.tool.utils.StringUtil;
 import org.springblade.modules.pl.client.entity.ClientEntity;
 import org.springblade.modules.pl.client.service.IClientService;
+import org.springblade.modules.pl.process.entity.ProcessEntity;
+import org.springblade.modules.pl.process.entity.ProcessItemEntity;
+import org.springblade.modules.pl.process.service.IProcessItemService;
+import org.springblade.modules.pl.process.service.IProcessService;
+import org.springblade.modules.pl.process.vo.ProcessVO;
+import org.springblade.modules.pl.process.wrapper.ProcessWrapper;
+import org.springblade.modules.pl.processConfig.entity.ProcessConfigEntity;
+import org.springblade.modules.pl.processConfig.service.IProcessConfigService;
 import org.springblade.modules.pl.product.entity.ProductEntity;
 import org.springblade.modules.pl.product.service.IProductService;
 import org.springblade.modules.pl.product.vo.ProductVO;
@@ -25,15 +39,28 @@ import org.springblade.modules.pl.productBatch.service.IProductBatchService;
 import org.springblade.modules.pl.productBatch.vo.ProductBatchVO;
 import org.springblade.modules.pl.productModel.entity.ProductModelEntity;
 import org.springblade.modules.pl.productModel.service.IProductModelService;
+import org.springblade.modules.pl.productProcess.entity.ProductProcessEntity;
+import org.springblade.modules.pl.productProcess.entity.ProductProcessItemEntity;
+import org.springblade.modules.pl.productProcess.service.IProductProcessItemService;
+import org.springblade.modules.pl.productProcess.service.IProductProcessService;
+import org.springblade.modules.pl.productProcess.vo.ProductProcessItemVO;
+import org.springblade.modules.pl.productProcess.vo.ProductProcessSubmitVO;
+import org.springblade.modules.pl.productProcess.vo.ProductProcessVO;
+import org.springblade.modules.pl.productProcess.wrapper.ProductProcessWrapper;
 import org.springblade.modules.pl.productRework.entity.ProductReworkEntity;
 import org.springblade.modules.pl.productRework.service.IProductReworkService;
+import org.springblade.modules.system.wrapper.UserWrapper;
 import org.springframework.web.bind.annotation.*;
 import springfox.documentation.annotations.ApiIgnore;
 
+import javax.annotation.Resource;
 import javax.validation.Valid;
+import java.io.IOException;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.TimeUnit;
 
 @RestController
 @AllArgsConstructor
@@ -41,6 +68,8 @@ import java.util.Map;
 @Api(value = "产品", tags = "产品相关外放接口")
 @Slf4j
 public class ProductApiController {
+	@Resource
+	private final RedissonClient redissonLock;
 
 	private final IProductBatchService productBatchService;
 
@@ -52,6 +81,16 @@ public class ProductApiController {
 
 	private final IProductReworkService productReworkService;
 
+	private final IProcessConfigService processConfigService;
+
+	private final IProcessService processService;
+
+	private final IProductProcessService productProcessService;
+
+	private final IProcessItemService processItemService;
+
+	private final IProductProcessItemService productProcessItemService;
+
 	/**
 	 * 产品表 分页
 	 */
@@ -103,7 +142,27 @@ public class ProductApiController {
 		if(detail==null){
 			return R.fail("未查询到产品信息");
 		}
-		return R.data(ProductWrapper.build().entityVO(detail));
+		ProductVO productVO = ProductWrapper.build().entityVO(detail);
+		ProductModelEntity productModel = productModelService.getById(detail.getProductModelId());
+		if(productModel!=null && productModel.getIsEnableProcess()==1){
+			productVO.setIsEnableProcess(productModel.getIsEnableProcess());
+			List<ProductProcessEntity> productProcesss = productProcessService.list(Wrappers.<ProductProcessEntity>lambdaQuery()
+				.eq(ProductProcessEntity::getProductId,detail.getId())
+				.orderByAsc(ProductProcessEntity::getSort));
+			List<ProductProcessVO> productProcessList = new ArrayList<>();
+			for(ProductProcessEntity processEntity : productProcesss){
+				ProductProcessVO processVO = ProductProcessWrapper.build().entityVO(processEntity);
+				if(processVO.getStatus() == 1 && processVO.getIsRetrospect()==1){
+					processVO.setDetails(productProcessItemService.list(Wrappers.<ProductProcessItemEntity>lambdaQuery()
+						.eq(ProductProcessItemEntity::getProductProcessId,processVO.getId())));
+				}
+				productProcessList.add(processVO);
+			}
+			productVO.setProductProcessList(productProcessList);
+		}else{
+			productVO.setIsEnableProcess(0);
+		}
+		return R.data(productVO);
 	}
 
 
@@ -191,4 +250,122 @@ public class ProductApiController {
 		}
 		return R.success("操作成功");
 	}
+
+
+	/**
+	 * 获取产品及工序休息
+	 */
+	@GetMapping("/getProductProcess")
+	@ApiOperationSupport(order = 6)
+	@ApiOperation(value = "获取产品及工序休息", notes = "传入productBatch")
+	public R getProductProcess(@Valid @RequestParam String qrCode) throws InterruptedException {
+		if(StringUtil.isBlank(qrCode)) {
+			return R.fail("请传入产品信息");
+		}
+		BladeUser user = AuthUtil.getUser();
+		ProductEntity productEntity = productService.getOne(Wrappers.<ProductEntity>lambdaQuery().eq(ProductEntity::getQrCode,qrCode).eq(ProductEntity::getFactoryId,user.getFactoryId()),false);
+		if(productEntity==null){
+			//产品不存在,新产品未启动工序
+			if(qrCode.length()<18){
+				return R.fail("产品二维码不能小于18位数");
+			}
+			String code = qrCode.substring(8,12);
+			ProductModelEntity productModel = productModelService.getOne(Wrappers.<ProductModelEntity>lambdaQuery().eq(ProductModelEntity::getProductSpec,code).eq(ProductModelEntity::getFactoryId,user.getFactoryId()),false);
+			if(productModel==null){
+				return R.fail("未找到型号码为'"+code+"'的数据");
+			}
+			if(productModel.getIsEnableProcess()==0){
+				return R.fail("当前产品型号未启用工序");
+			}
+			ProcessConfigEntity processConfigEntity = processConfigService.getById(productModel.getProcessConfigId());
+			if(processConfigEntity==null){
+				return R.fail("获取产品型号的工序配置异常");
+			}
+			String[] processIds = processConfigEntity.getProcessIds().split(",");
+			ProcessEntity processEntity = processService.getById(processIds[0]);
+
+			ProductProcessVO productProcessVO = BeanUtil.copy(processEntity, ProductProcessVO.class);
+			productProcessVO.setProcessId(processEntity.getId());
+			productProcessVO.setProcessName(processEntity.getName());
+			productProcessVO.setProcessCode(processEntity.getCode());
+			productProcessVO.setProcessType(processEntity.getType());
+			if(productProcessVO.getIsRetrospect()==1){
+				List<ProcessItemEntity>detailList = processItemService.list(Wrappers.<ProcessItemEntity>lambdaUpdate().eq(ProcessItemEntity::getProcessId,processEntity.getId()));
+				List<ProductProcessItemEntity>details = new ArrayList<>();
+				for(ProcessItemEntity processItem : detailList){
+					ProductProcessItemEntity productProcessItem = new ProductProcessItemVO();
+					productProcessItem.setProcessItemId(processItem.getId());
+					productProcessItem.setProcessItemName(processItem.getName());
+					productProcessItem.setProcessItemValue(processItem.getValue());
+					productProcessItem.setValueType(processItem.getValueType());
+					productProcessItem.setMaxValue(processItem.getMaxValue());
+					productProcessItem.setMinValue(processItem.getMinValue());
+					productProcessItem.setUnit(processItem.getUnit());
+					details.add(productProcessItem);
+				}
+				productProcessVO.setDetails(details);
+			}
+			Map<String,Object> result = new HashMap<>();
+			result.put("productModel",productModel);
+			result.put("process",productProcessVO);
+			return R.data(result);
+		}else{
+			if(productEntity.getStatus()==0){
+				return R.fail("产品已作废");
+			}
+			if(productEntity.getStatus()==1){
+				return R.fail("产品维修中");
+			}
+			if(productEntity.getStatus()==3){
+				return R.fail("产品已入库");
+			}
+			//产品存在,查询工序数据
+			long count = productProcessService.count(Wrappers.<ProductProcessEntity>lambdaQuery().eq(ProductProcessEntity::getProductId,productEntity.getId()));
+			if(count==0){
+				return R.fail("产品工序数据异常");
+			}
+			ProductProcessEntity processEntity = productProcessService.getOne(Wrappers.<ProductProcessEntity>lambdaQuery()
+				.eq(ProductProcessEntity::getProductId,productEntity.getId())
+				.eq(ProductProcessEntity::getStatus,0)
+				.orderByAsc(ProductProcessEntity::getSort),false);
+			if(processEntity==null){
+				return R.fail("已完成全部工序");
+			}
+			ProductProcessVO productProcessVO = ProductProcessWrapper.build().entityVO(processEntity);
+			if(processEntity.getIsRetrospect()==1){
+				List<ProductProcessItemEntity>details = productProcessItemService.list(Wrappers.<ProductProcessItemEntity>lambdaUpdate().eq(ProductProcessItemEntity::getProductProcessId,processEntity.getId()));
+				productProcessVO.setDetails(details);
+			}
+			Map<String,Object> result = new HashMap<>();
+			result.put("product",productEntity);
+			result.put("process",productProcessVO);
+			return R.data(result);
+		}
+	}
+
+
+	/**
+	 * 工序提交
+	 */
+	@PostMapping("/processSubmit")
+	@ApiOperationSupport(order = 6)
+	@ApiOperation(value = "工序提交", notes = "传入productBatch")
+	@ApiLog("工序提交")
+	public R submit(@Valid @RequestBody ProductProcessSubmitVO productProcess) throws InterruptedException {
+		// 获取可重入锁, 指定锁的名称
+		RLock lock = redissonLock.getLock("lock:cameraUploadImg:"+productProcess.getQrCode());
+		// 尝试获取锁
+		// 参数1:获取锁的最大等待时间(期间会多次重试获取锁)
+		// 参数2:锁自动释放时间
+		// 参数3:时间单位
+		boolean isGetLock = lock.tryLock(50, 60, TimeUnit.SECONDS);
+		if (isGetLock) {
+			try {
+				return productProcessService.processSubmit(productProcess);
+			} finally {
+				lock.unlock();
+			}
+		}
+		return R.success("操作失败");
+	}
 }

+ 21 - 1
src/main/java/org/springblade/applet/ProductReworkApiController.java

@@ -19,6 +19,8 @@ import org.springblade.core.tool.utils.Func;
 import org.springblade.core.tool.utils.StringUtil;
 import org.springblade.modules.pl.product.entity.ProductEntity;
 import org.springblade.modules.pl.product.service.IProductService;
+import org.springblade.modules.pl.productProcess.entity.ProductProcessEntity;
+import org.springblade.modules.pl.productProcess.service.IProductProcessService;
 import org.springblade.modules.pl.productRework.entity.ProductReworkEntity;
 import org.springblade.modules.pl.productRework.service.IProductReworkService;
 import org.springblade.modules.pl.productRework.vo.ProductReworkVO;
@@ -42,6 +44,8 @@ public class ProductReworkApiController {
 
 	private final IProductReworkService productReworkService;
 
+	private final IProductProcessService productProcessService;
+
 
 
 	/**
@@ -202,7 +206,23 @@ public class ProductReworkApiController {
 			ProductEntity product = productService.getById(detail.getProductId());
 			ProductEntity productEntity = new ProductEntity();
 			productEntity.setId(product.getId());
-			productEntity.setStatus(2);
+			long count = productProcessService.count(Wrappers.<ProductProcessEntity>lambdaQuery().eq(ProductProcessEntity::getProductId,productEntity.getId()));
+			if(count==0){
+				//无工序数据
+				productEntity.setStatus(2);
+			}else{
+				count = productProcessService.count(Wrappers.<ProductProcessEntity>lambdaQuery()
+					.eq(ProductProcessEntity::getProductId,productEntity.getId())
+					.eq(ProductProcessEntity::getIsDownline,1)
+					.eq(ProductProcessEntity::getStatus,1));
+				if(count>1){
+					//已执行下线工序状态改为已下线
+					productEntity.setStatus(2);
+				}else{
+					//未执行下线工序状态改为生产中
+					productEntity.setStatus(-1);
+				}
+			}
 			if(product.getAiStatus()==1){
 				productEntity.setAiStatus(3);
 			}

+ 21 - 0
src/main/java/org/springblade/modules/pl/process/entity/ProcessItemEntity.java

@@ -52,4 +52,25 @@ public class ProcessItemEntity extends TenantEntity {
 	@ApiModelProperty(value = "预设达标值")
 	private String value;
 
+
+	/**
+	 * 值类型 1匹配 2范围
+	 */
+	@ApiModelProperty(value = "值类型 1匹配 2范围")
+	private String valueType;
+	/**
+	 * 最大值
+	 */
+	@ApiModelProperty(value = "最大值")
+	private String maxValue;
+	/**
+	 * 最小值
+	 */
+	@ApiModelProperty(value = "最小值")
+	private String minValue;
+	/**
+	 * 单位
+	 */
+	@ApiModelProperty(value = "单位")
+	private String unit;
 }

+ 1 - 1
src/main/java/org/springblade/modules/pl/processConfig/controller/ProcessConfigController.java

@@ -146,7 +146,7 @@ public class ProcessConfigController extends BladeController {
 			}
 		}
 		if(count!=1){
-			return R.fail("当前选择了"+count+"个下线工序,仅选择1个下线工序");
+			return R.fail("当前选择了"+count+"个下线工序,仅必须只选择1个下线工序");
 		}
 		processConfig.setProcessNames(String.join(">",processNames));
 		return R.status(processConfigService.saveOrUpdate(processConfig));

+ 5 - 0
src/main/java/org/springblade/modules/pl/product/entity/ProductEntity.java

@@ -155,5 +155,10 @@ public class ProductEntity extends TenantEntity {
 	 */
 	@ApiModelProperty(value = "ai识别状态 -1无需识别 0未识别 1ng 2ok 3人工ok")
 	private Integer aiStatus;
+	/**
+	 * 产品来源 1相机拍照 2产品入库 3维修 4工序追溯
+	 */
+	@ApiModelProperty(value = "产品来源 1相机拍照 2产品入库 3维修 4工序追溯")
+	private Integer source;
 
 }

+ 183 - 69
src/main/java/org/springblade/modules/pl/product/service/impl/ProductImageRecordServiceImpl.java

@@ -23,6 +23,7 @@ import org.apache.http.client.utils.HttpClientUtils;
 import org.springblade.common.utils.PostGet;
 import org.springblade.core.http.util.HttpUtil;
 import org.springblade.core.oss.model.BladeFile;
+import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.utils.DateUtil;
 import org.springblade.core.tool.utils.FileUtil;
 import org.springblade.core.tool.utils.StringUtil;
@@ -38,6 +39,8 @@ import org.springblade.modules.pl.product.service.IProductImageRecordService;
 import org.springblade.modules.pl.product.wrapper.ProductImageRecordWrapper;
 import org.springblade.modules.pl.productModel.entity.ProductModelEntity;
 import org.springblade.modules.pl.productModel.service.IProductModelService;
+import org.springblade.modules.pl.productProcess.entity.ProductProcessEntity;
+import org.springblade.modules.pl.productProcess.service.IProductProcessService;
 import org.springblade.modules.resource.builder.OssBuilder;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
@@ -68,6 +71,8 @@ public class ProductImageRecordServiceImpl extends BaseServiceImpl<ProductImageR
 	private IProductService productService;
 	@Resource
 	private IProductModelService productModelService;
+	@Resource
+	private IProductProcessService productProcessService;
 
 	@Resource
 	private OssBuilder ossBuilder;
@@ -108,94 +113,203 @@ public class ProductImageRecordServiceImpl extends BaseServiceImpl<ProductImageR
 				productImageRecord.setMessage("未找到型号码为'"+code+"'的数据");
 			}else{
 				productEntity = productService.getOne(Wrappers.<ProductEntity>lambdaQuery().eq(ProductEntity::getQrCode,productCode).eq(ProductEntity::getFactoryId,equipmentEntity.getFactoryId()),false);
-				if(productEntity!=null && productEntity.getStatus()!=2){
-					productImageRecord.setStatus(2);
-					productImageRecord.setMessage("产品"+(productEntity.getStatus()==1?"正在维修中,":(productEntity.getStatus()==0?"已作废,":"已入库,"))+"无法下线");
-				}else if(productEntity!=null && productEntity.getAiStatus()!=null && (productEntity.getAiStatus()==0 || productEntity.getAiStatus()==1) ){
-					productImageRecord.setStatus(2);
-					productImageRecord.setMessage("产品"+(productEntity.getAiStatus()==0 ?"AI未识别-待处理,":(productEntity.getAiStatus()==1?"NG待处理,":""))+"无法下线");
+				if(productModel.getIsEnableProcess()==1){
+					if(productEntity ==null){
+						productImageRecord.setStatus(2);
+						productImageRecord.setMessage("产品不存在,请通过工序进行建档");
+					}else if(productEntity.getStatus()!=2 && productEntity.getStatus()!=-1 ){
+						productImageRecord.setStatus(2);
+						productImageRecord.setMessage("产品"+(productEntity.getStatus()==1?"正在维修中,":(productEntity.getStatus()==0?"已作废,":"已入库,"))+"无法下线");
+					}else if( productEntity.getAiStatus()!=null && (productEntity.getAiStatus()==0 || productEntity.getAiStatus()==1) ){
+						productImageRecord.setStatus(2);
+						productImageRecord.setMessage("产品"+(productEntity.getAiStatus()==0 ?"AI未识别-待处理,":(productEntity.getAiStatus()==1?"NG待处理,":""))+"无法下线");
+					}else{
+						long count = productProcessService.count(Wrappers.<ProductProcessEntity>lambdaQuery().eq(ProductProcessEntity::getProductId,productEntity.getId()));
+						if(count>0){
+							ProductProcessEntity processEntity = productProcessService.getOne(Wrappers.<ProductProcessEntity>lambdaQuery()
+								.eq(ProductProcessEntity::getProductId,productEntity.getId())
+								.eq(ProductProcessEntity::getStatus,0)
+								.orderByAsc(ProductProcessEntity::getSort),false);
+							if(processEntity!=null){
+								if(processEntity.getIsPhotograph()==1){
+									if(processEntity.getIsDownline()==1){
+										//下线拍照
+										if(productModel.getIsAi()==1){
+											aiStatus = 0;
+											try {
+												JSONObject param = new JSONObject();
+												param.put("action","detect");
+												param.put("type",productModel.getProductModel()+(productEntity==null?"-1":"-0"));
+												param.put("path",bladeFile.getLink());
+												String result = PostGet.getResult(aiUrl+"/ws_init",param.toJSONString(),true);
+												JSONObject jsonObject = JSONObject.parseObject(result);
+												if(jsonObject.get("status")!=null && jsonObject.getInteger("status")==200){
+													String filePath = jsonObject.getString("path");
+													File file = new File(filePath);
+													if(file.exists()){
+														aiStatus = "OK".equals(jsonObject.get("result"))?2:1;
+														String fileName= "upload/"+(factory==null?"000000":factory.getCode())+"/" + DateUtil.today() + "/"+productCode+"/" + StringUtil.randomUUID() + "." + FileUtil.getFileExtension(file.getName());
+														BladeFile aiFile = ossBuilder.template(equipmentEntity.getTenantId(),"minio").putFile(fileName, Files.newInputStream(Paths.get(filePath)));
+														productImageRecord.setProductAiImage(aiFile.getLink());
+														file.delete();
+													}
+													else{
+														productImageRecord.setStatus(2);
+														productImageRecord.setMessage("拍照成功,AI识别接口调用异常-文件不存在");
+													}
+												}else{
+													productImageRecord.setStatus(2);
+													productImageRecord.setMessage("拍照成功,AI识别接口调用失败"+jsonObject.get("result"));
+												}
+											}catch (Exception e){
+												e.printStackTrace();
+												log.error("AI识别接口调用异常",e);
+												productImageRecord.setStatus(2);
+												productImageRecord.setMessage("拍照成功,AI识别接口调用异常");
+											}
+										}
+										if(StringUtil.isBlank(productEntity.getBackImg())){
+											productEntity.setBackImg(productImageRecord.getProductImage());
+											productEntity.setBackAiImg(productImageRecord.getProductAiImage());
+											productEntity.setStatus(2);
+											productEntity.setAiStatus(aiStatus);
+
+											processEntity.setImages((StringUtil.isBlank(processEntity.getImages())?"":processEntity.getImages()+",")+productImageRecord.getProductImage());
+										}else{
+											productEntity.setFrontImg(productImageRecord.getProductImage());
+											productEntity.setFrontAiImg(productImageRecord.getProductAiImage());
+											productEntity.setStatus(2);
+											productEntity.setAiStatus(aiStatus);
+
+											processEntity.setImages((StringUtil.isBlank(processEntity.getImages())?"":processEntity.getImages()+",")+productImageRecord.getProductImage());
+											processEntity.setStatus(1);
+										}
+
+									}else{
+										//工序拍照
+										processEntity.setImages((StringUtil.isBlank(processEntity.getImages())?"":processEntity.getImages()+",")+productImageRecord.getProductImage());
+										processEntity.setStatus(1);
+									}
+
+									productService.updateById(productEntity);
+									productProcessService.updateById(processEntity);
+									if(aiStatus==0 ||  aiStatus==1){
+										productImageRecord.setStatus(2);
+									}
+
+									productImageRecord.setProductId(productEntity.getId());
+									if(aiStatus==-1){
+										productImageRecord.setMessage("工序拍照成功");
+									}else if(aiStatus==1 || aiStatus==2){
+										productImageRecord.setMessage("工序拍照成功,产品识别"+(aiStatus==2?"OK":"NG"));
+									}
+								}else{
+									productImageRecord.setStatus(2);
+									productImageRecord.setMessage("该产品当前执行工序非拍照工序,请前往小程序进行操作");
+								}
+							}else{
+								productImageRecord.setStatus(2);
+								productImageRecord.setMessage("已完成全部工序");
+							}
+						}else{
+							productImageRecord.setStatus(2);
+							productImageRecord.setMessage("产品工序数据异常");
+						}
+
+
+					}
+
+
 				}else{
-					if(productModel.getIsAi()==1){
-						aiStatus = 0;
-						try {
+					if(productEntity!=null && productEntity.getStatus()!=2){
+						productImageRecord.setStatus(2);
+						productImageRecord.setMessage("产品"+(productEntity.getStatus()==1?"正在维修中,":(productEntity.getStatus()==0?"已作废,":"已入库,"))+"无法下线");
+					}else if(productEntity!=null && productEntity.getAiStatus()!=null && (productEntity.getAiStatus()==0 || productEntity.getAiStatus()==1) ){
+						productImageRecord.setStatus(2);
+						productImageRecord.setMessage("产品"+(productEntity.getAiStatus()==0 ?"AI未识别-待处理,":(productEntity.getAiStatus()==1?"NG待处理,":""))+"无法下线");
+					}else{
+						if(productModel.getIsAi()==1){
+							aiStatus = 0;
+							try {
 //						Map<String,Object> param = new HashMap<>();
 //						param.put("action","detect");
 //						param.put("type",productEntity==null?"origin-background":"origin-front");
 //						param.put("path",bladeFile.getLink());
-							JSONObject param = new JSONObject();
-							param.put("action","detect");
-							param.put("type",productModel.getProductModel()+(productEntity==null?"-1":"-0"));
-							param.put("path",bladeFile.getLink());
+								JSONObject param = new JSONObject();
+								param.put("action","detect");
+								param.put("type",productModel.getProductModel()+(productEntity==null?"-1":"-0"));
+								param.put("path",bladeFile.getLink());
 
 //							String result = HttpUtil.postJson("http://127.0.0.1:3300/ws_init",param.toJSONString());
-							String result = PostGet.getResult(aiUrl+"/ws_init",param.toJSONString(),true);
-							JSONObject jsonObject = JSONObject.parseObject(result);
-							if(jsonObject.get("status")!=null && jsonObject.getInteger("status")==200){
-								String filePath = jsonObject.getString("path");
-								File file = new File(filePath);
-								if(file.exists()){
-									aiStatus = "OK".equals(jsonObject.get("result"))?2:1;
-									String fileName= "upload/"+(factory==null?"000000":factory.getCode())+"/" + DateUtil.today() + "/"+productCode+"/" + StringUtil.randomUUID() + "." + FileUtil.getFileExtension(file.getName());
-									BladeFile aiFile = ossBuilder.template(equipmentEntity.getTenantId(),"minio").putFile(fileName, Files.newInputStream(Paths.get(filePath)));
-									productImageRecord.setProductAiImage(aiFile.getLink());
-									file.delete();
-								}
-								else{
+								String result = PostGet.getResult(aiUrl+"/ws_init",param.toJSONString(),true);
+								JSONObject jsonObject = JSONObject.parseObject(result);
+								if(jsonObject.get("status")!=null && jsonObject.getInteger("status")==200){
+									String filePath = jsonObject.getString("path");
+									File file = new File(filePath);
+									if(file.exists()){
+										aiStatus = "OK".equals(jsonObject.get("result"))?2:1;
+										String fileName= "upload/"+(factory==null?"000000":factory.getCode())+"/" + DateUtil.today() + "/"+productCode+"/" + StringUtil.randomUUID() + "." + FileUtil.getFileExtension(file.getName());
+										BladeFile aiFile = ossBuilder.template(equipmentEntity.getTenantId(),"minio").putFile(fileName, Files.newInputStream(Paths.get(filePath)));
+										productImageRecord.setProductAiImage(aiFile.getLink());
+										file.delete();
+									}
+									else{
+										productImageRecord.setStatus(2);
+										productImageRecord.setMessage("拍照成功,AI识别接口调用异常-文件不存在");
+									}
+								}else{
 									productImageRecord.setStatus(2);
-									productImageRecord.setMessage("拍照成功,AI识别接口调用异常-文件不存在");
+									productImageRecord.setMessage("拍照成功,AI识别接口调用失败"+jsonObject.get("result"));
 								}
-							}else{
+							}catch (Exception e){
+								e.printStackTrace();
+								log.error("AI识别接口调用异常",e);
 								productImageRecord.setStatus(2);
-								productImageRecord.setMessage("拍照成功,AI识别接口调用失败"+jsonObject.get("result"));
+								productImageRecord.setMessage("拍照成功,AI识别接口调用异常");
 							}
-						}catch (Exception e){
-							e.printStackTrace();
-							log.error("AI识别接口调用异常",e);
-							productImageRecord.setStatus(2);
-							productImageRecord.setMessage("拍照成功,AI识别接口调用异常");
 						}
 					}
-				}
-
-				if(productImageRecord.getStatus()==2 && aiStatus==-1){
-					this.save(productImageRecord);
-					ProductImageRecordVO productImageRecordVO = ProductImageRecordWrapper.build().entityVO(productImageRecord);
-					productImageRecordVO.setAiStatus(aiStatus);
+					if(productImageRecord.getStatus()==2 && aiStatus==-1){
+						this.save(productImageRecord);
+						ProductImageRecordVO productImageRecordVO = ProductImageRecordWrapper.build().entityVO(productImageRecord);
+						productImageRecordVO.setAiStatus(aiStatus);
 //					productImageRecordVO.setProductEntity(productEntity);
-					return productImageRecordVO;
-				}
-				if(aiStatus==0 ||  aiStatus==1){
-					productImageRecord.setStatus(2);
-				}
+						return productImageRecordVO;
+					}
+					if(aiStatus==0 ||  aiStatus==1){
+						productImageRecord.setStatus(2);
+					}
 
-				if(productEntity==null){
-					productEntity = new ProductEntity();
-					productEntity.setTenantId(productModel.getTenantId());
-					productEntity.setFactoryId(productModel.getFactoryId());
+					if(productEntity==null){
+						productEntity = new ProductEntity();
+						productEntity.setTenantId(productModel.getTenantId());
+						productEntity.setFactoryId(productModel.getFactoryId());
 //								productEntity.setClientId(productModel.getClientId());
-					productEntity.setProductModelId(productModel.getId());
-					productEntity.setProductName(productModel.getProductName());
-					productEntity.setProductModel(productModel.getProductModel());
-					productEntity.setBackImg(productImageRecord.getProductImage());
-					productEntity.setBackAiImg(productImageRecord.getProductAiImage());
-					productEntity.setQrCode(productCode);
-					productEntity.setStatus(2);
-					productEntity.setAiStatus(aiStatus);
-					productService.save(productEntity);
-				}else{
-					if(productEntity.getStatus()==2){
-						productEntity.setFrontImg(productImageRecord.getProductImage());
-						productEntity.setFrontAiImg(productImageRecord.getProductAiImage());
+						productEntity.setProductModelId(productModel.getId());
+						productEntity.setProductName(productModel.getProductName());
+						productEntity.setProductModel(productModel.getProductModel());
+						productEntity.setBackImg(productImageRecord.getProductImage());
+						productEntity.setBackAiImg(productImageRecord.getProductAiImage());
+						productEntity.setQrCode(productCode);
 						productEntity.setStatus(2);
 						productEntity.setAiStatus(aiStatus);
-						productService.updateById(productEntity);
+						productEntity.setSource(1);
+						productService.save(productEntity);
+					}else{
+						if(productEntity.getStatus()==2){
+							productEntity.setFrontImg(productImageRecord.getProductImage());
+							productEntity.setFrontAiImg(productImageRecord.getProductAiImage());
+							productEntity.setStatus(2);
+							productEntity.setAiStatus(aiStatus);
+							productService.updateById(productEntity);
+						}
+					}
+					productImageRecord.setProductId(productEntity.getId());
+					if(aiStatus==-1){
+						productImageRecord.setMessage("拍照成功");
+					}else if(aiStatus==1 || aiStatus==2){
+						productImageRecord.setMessage("拍照成功,产品识别"+(aiStatus==2?"OK":"NG"));
 					}
-				}
-				productImageRecord.setProductId(productEntity.getId());
-				if(aiStatus==-1){
-					productImageRecord.setMessage("拍照成功");
-				}else if(aiStatus==1 || aiStatus==2){
-					productImageRecord.setMessage("拍照成功,产品识别"+(aiStatus==2?"OK":"NG"));
 				}
 			}
 		}

+ 8 - 0
src/main/java/org/springblade/modules/pl/product/vo/ProductVO.java

@@ -16,10 +16,15 @@
  */
 package org.springblade.modules.pl.product.vo;
 
+import io.swagger.models.auth.In;
 import org.springblade.modules.pl.product.entity.ProductEntity;
 import org.springblade.core.tool.node.INode;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
+import org.springblade.modules.pl.productProcess.entity.ProductProcessEntity;
+import org.springblade.modules.pl.productProcess.vo.ProductProcessVO;
+
+import java.util.List;
 
 /**
  * 产品表 视图实体类
@@ -35,4 +40,7 @@ public class ProductVO extends ProductEntity {
 	private String createTimeArr;
 	private String scanDateArr;
 
+	private Integer isEnableProcess;
+	private List<ProductProcessVO> productProcessList;
+
 }

+ 2 - 0
src/main/java/org/springblade/modules/pl/productBatch/service/impl/ProductBatchServiceImpl.java

@@ -121,6 +121,8 @@ public class ProductBatchServiceImpl extends BaseServiceImpl<ProductBatchMapper,
 							return R.fail("产品二维码:"+productEntity.getQrCode()+"与当前批次的型号不符,请更换产品");
 						}
 						productEntity.setId(product.getId());
+					}else{
+						productEntity.setSource(2);
 					}
 					productEntity.setFactoryId(productModel.getFactoryId());
 					productEntity.setProductModelId(productModel.getId());

+ 49 - 0
src/main/java/org/springblade/modules/pl/productProcess/entity/ProductProcessEntity.java

@@ -17,6 +17,8 @@
 package org.springblade.modules.pl.productProcess.entity;
 
 import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.NullSerializer;
 import lombok.Data;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
@@ -56,15 +58,62 @@ public class ProductProcessEntity extends TenantEntity {
 	 */
 	@ApiModelProperty(value = "工序编码")
 	private String processCode;
+	/**
+	 * 过程类型
+	 */
+	@ApiModelProperty(value = "过程类型")
+	private String processType;
 	/**
 	 * 是否追溯 0否1是
 	 */
 	@ApiModelProperty(value = "是否追溯 0否1是")
 	private Integer isRetrospect;
+	/**
+	 * 关键过程 0否1是
+	 */
+	@ApiModelProperty(value = "关键过程 0否1是")
+	private Integer isCrux;
+	/**
+	 * 设备/冶具
+	 */
+	@ApiModelProperty(value = "设备/冶具")
+	private String equipment;
+	/**
+	 * 使用寿命-数字
+	 */
+	@ApiModelProperty(value = "使用寿命-数字")
+	private Integer lifeSpan;
+	/**
+	 * 是否拍照 0否1是
+	 */
+	@ApiModelProperty(value = "是否拍照 0否1是")
+	private Integer isPhotograph;
+	/**
+	 * 是否下线 0否1是
+	 */
+	@ApiModelProperty(value = "是否下线 0否1是")
+	private Integer isDownline;
+
 	/**
 	 * 是否达标 -1无需追溯 0未达标 1达标
 	 */
+	@JsonSerialize(nullsUsing = NullSerializer.class)
 	@ApiModelProperty(value = "是否达标 -1无需追溯 0未达标 1达标")
 	private Integer isStandards;
 
+	/**
+	 * 排序
+	 */
+	@ApiModelProperty(value = "排序")
+	private Integer sort;
+	/**
+	 * 操作人
+	 */
+	@ApiModelProperty(value = "操作人")
+	private String operatorName;
+	/**
+	 * 拍照图片
+	 */
+	@ApiModelProperty(value = "拍照图片")
+	private String images;
 }

+ 23 - 0
src/main/java/org/springblade/modules/pl/productProcess/entity/ProductProcessItemEntity.java

@@ -56,6 +56,29 @@ public class ProductProcessItemEntity extends TenantEntity {
 	 */
 	@ApiModelProperty(value = "工序项值")
 	private String processItemValue;
+
+	/**
+	 * 值类型 1匹配 2范围
+	 */
+	@ApiModelProperty(value = "值类型 1匹配 2范围")
+	private String valueType;
+	/**
+	 * 最大值
+	 */
+	@ApiModelProperty(value = "最大值")
+	private String maxValue;
+	/**
+	 * 最小值
+	 */
+	@ApiModelProperty(value = "最小值")
+	private String minValue;
+	/**
+	 * 单位
+	 */
+	@ApiModelProperty(value = "单位")
+	private String unit;
+
+
 	/**
 	 * 实际值
 	 */

+ 3 - 0
src/main/java/org/springblade/modules/pl/productProcess/service/IProductProcessService.java

@@ -17,7 +17,9 @@
 package org.springblade.modules.pl.productProcess.service;
 
 import com.baomidou.mybatisplus.core.conditions.Wrapper;
+import org.springblade.core.tool.api.R;
 import org.springblade.modules.pl.productProcess.entity.ProductProcessEntity;
+import org.springblade.modules.pl.productProcess.vo.ProductProcessSubmitVO;
 import org.springblade.modules.pl.productProcess.vo.ProductProcessVO;
 import org.springblade.modules.pl.productProcess.excel.ProductProcessExcel;
 import com.baomidou.mybatisplus.core.metadata.IPage;
@@ -49,4 +51,5 @@ public interface IProductProcessService extends BaseService<ProductProcessEntity
 	 */
 	List<ProductProcessExcel> exportProductProcess(Wrapper<ProductProcessEntity> queryWrapper);
 
+    R processSubmit(ProductProcessSubmitVO productProcess);
 }

+ 215 - 0
src/main/java/org/springblade/modules/pl/productProcess/service/impl/ProductProcessServiceImpl.java

@@ -16,16 +16,49 @@
  */
 package org.springblade.modules.pl.productProcess.service.impl;
 
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import org.redisson.api.RedissonClient;
+import org.springblade.core.secure.BladeUser;
+import org.springblade.core.secure.utils.AuthUtil;
+import org.springblade.core.tool.api.R;
+import org.springblade.core.tool.utils.BeanUtil;
+import org.springblade.core.tool.utils.StringUtil;
+import org.springblade.modules.pl.client.service.IClientService;
+import org.springblade.modules.pl.process.entity.ProcessEntity;
+import org.springblade.modules.pl.process.entity.ProcessItemEntity;
+import org.springblade.modules.pl.process.service.IProcessItemService;
+import org.springblade.modules.pl.process.service.IProcessService;
+import org.springblade.modules.pl.processConfig.entity.ProcessConfigEntity;
+import org.springblade.modules.pl.processConfig.service.IProcessConfigService;
+import org.springblade.modules.pl.product.entity.ProductEntity;
+import org.springblade.modules.pl.product.service.IProductService;
+import org.springblade.modules.pl.productBatch.service.IProductBatchService;
+import org.springblade.modules.pl.productModel.entity.ProductModelEntity;
+import org.springblade.modules.pl.productModel.service.IProductModelService;
 import org.springblade.modules.pl.productProcess.entity.ProductProcessEntity;
+import org.springblade.modules.pl.productProcess.entity.ProductProcessItemEntity;
+import org.springblade.modules.pl.productProcess.service.IProductProcessItemService;
+import org.springblade.modules.pl.productProcess.vo.ProductProcessItemVO;
+import org.springblade.modules.pl.productProcess.vo.ProductProcessSubmitVO;
 import org.springblade.modules.pl.productProcess.vo.ProductProcessVO;
 import org.springblade.modules.pl.productProcess.excel.ProductProcessExcel;
 import org.springblade.modules.pl.productProcess.mapper.ProductProcessMapper;
 import org.springblade.modules.pl.productProcess.service.IProductProcessService;
+import org.springblade.modules.pl.productProcess.wrapper.ProductProcessWrapper;
+import org.springblade.modules.pl.productRework.entity.ProductReworkEntity;
+import org.springblade.modules.pl.productRework.service.IProductReworkService;
+import org.springblade.modules.pl.productRework.vo.ProductReworkVO;
 import org.springframework.stereotype.Service;
 import com.baomidou.mybatisplus.core.conditions.Wrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import org.springblade.core.mp.base.BaseServiceImpl;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 /**
  * 商品工序记录表 服务实现类
@@ -35,6 +68,20 @@ import java.util.List;
  */
 @Service
 public class ProductProcessServiceImpl extends BaseServiceImpl<ProductProcessMapper, ProductProcessEntity> implements IProductProcessService {
+	@Resource
+	private IProductService productService;
+	@Resource
+	private IProductModelService productModelService;
+	@Resource
+	private IProductReworkService productReworkService;
+	@Resource
+	private IProcessConfigService processConfigService;
+	@Resource
+	private IProcessService processService;
+	@Resource
+	private IProcessItemService processItemService;
+	@Resource
+	private IProductProcessItemService productProcessItemService;
 
 	@Override
 	public IPage<ProductProcessVO> selectProductProcessPage(IPage<ProductProcessVO> page, ProductProcessVO productProcess) {
@@ -51,4 +98,172 @@ public class ProductProcessServiceImpl extends BaseServiceImpl<ProductProcessMap
 		return productProcessList;
 	}
 
+	@Override
+	@Transactional(rollbackFor = Exception.class)
+	public R processSubmit(ProductProcessSubmitVO productProcess) {
+		String qrCode = productProcess.getQrCode();
+		BladeUser user = AuthUtil.getUser();
+
+		ProductEntity productEntity = productService.getOne(Wrappers.<ProductEntity>lambdaQuery().eq(ProductEntity::getQrCode,qrCode).eq(ProductEntity::getFactoryId,user.getFactoryId()),false);
+		if(productEntity==null){
+			//产品不存在,新产品未启动工序
+			if(qrCode.length()<18){
+				return R.fail("产品二维码不能小于18位数");
+			}
+			String code = qrCode.substring(8,12);
+			ProductModelEntity productModel = productModelService.getOne(Wrappers.<ProductModelEntity>lambdaQuery().eq(ProductModelEntity::getProductSpec,code).eq(ProductModelEntity::getFactoryId,user.getFactoryId()),false);
+			if(productModel==null){
+				return R.fail("未找到型号码为'"+code+"'的数据");
+			}
+			if(productModel.getIsEnableProcess()==0){
+				return R.fail("当前产品型号未启用工序");
+			}
+			ProcessConfigEntity processConfigEntity = processConfigService.getById(productModel.getProcessConfigId());
+			if(processConfigEntity==null){
+				return R.fail("获取产品型号的工序配置异常");
+			}
+			String[] processIds = processConfigEntity.getProcessIds().split(",");
+			for(int i=0;i<processIds.length;i++){
+				String processId = processIds[i];
+				ProcessEntity processEntity = processService.getById(processId);
+				if(i==0){
+					if(!processEntity.getId().equals(productProcess.getProductProcess().getProcessId())){
+						return R.fail("型号工序已变动,请重新追溯");
+					}
+				}
+			}
+			ProductProcessVO productProcessVO = productProcess.getProductProcess();
+			if(productProcessVO.getIsStandards()==0){
+				if(StringUtil.isBlank(productProcess.getImages())){
+					return R.fail("追溯不达标,请重新提交并上传图片");
+				}
+				if(StringUtil.isBlank(productProcess.getProblemDesc())){
+					return R.fail("追溯不达标,请填写错误原因");
+				}
+			}
+			productEntity = new ProductEntity();
+			productEntity.setTenantId(productModel.getTenantId());
+			productEntity.setFactoryId(productModel.getFactoryId());
+			productEntity.setProductModelId(productModel.getId());
+			productEntity.setProductName(productModel.getProductName());
+			productEntity.setProductModel(productModel.getProductModel());
+			productEntity.setQrCode(productProcess.getQrCode());
+			productEntity.setStatus(-1);
+			productEntity.setSource(4);
+			productService.save(productEntity);
+			if(productProcessVO.getIsStandards()==0){
+				productEntity.setStatus(1);
+				productService.updateById(productEntity);
+				//未达标发起维修
+				ProductReworkEntity productReworkEntity = new ProductReworkEntity();
+				productReworkEntity.setFactoryId(productEntity.getFactoryId());
+				productReworkEntity.setProductId(productEntity.getId());
+				productReworkEntity.setQrCode(productEntity.getQrCode());
+				productReworkEntity.setProductModelId(productEntity.getProductModelId());
+				productReworkEntity.setProductName(productEntity.getProductName());
+				productReworkEntity.setProductModel(productEntity.getProductModel());
+				productReworkEntity.setRepairsImgs(productProcess.getImages());
+				productReworkEntity.setProblemDesc(productProcess.getProblemDesc());
+				productReworkEntity.setStatus(1);
+				productReworkEntity.setCreatePersonName(user.getNickName());
+				productReworkService.save(productReworkEntity);
+			}
+			for(int i=0;i<processIds.length;i++){
+				if(i==0){
+					productProcessVO = productProcess.getProductProcess();
+					productProcessVO.setId(null);
+					productProcessVO.setProductId(productEntity.getId());
+					productProcessVO.setSort(i);
+					productProcessVO.setStatus(1);
+					productProcessVO.setOperatorName(user.getNickName());
+					this.save(productProcessVO);
+					if(productProcessVO.getIsRetrospect()==1){
+						List<ProductProcessItemEntity>details = productProcess.getProductProcess().getDetails();
+						for(ProductProcessItemEntity productProcessItem : details){
+							productProcessItem.setId(null);
+							productProcessItem.setProductProcessId(productProcessVO.getId());
+							productProcessItem.setStatus(1);
+						}
+						productProcessItemService.saveBatch(details);
+					}
+				}else{
+					String processId = processIds[i];
+					ProcessEntity processEntity = processService.getById(processId);
+					productProcessVO = BeanUtil.copy(processEntity, ProductProcessVO.class);
+					productProcessVO.setId(null);
+					productProcessVO.setProcessId(processEntity.getId());
+					productProcessVO.setProcessName(processEntity.getName());
+					productProcessVO.setProcessCode(processEntity.getCode());
+					productProcessVO.setProcessType(processEntity.getType());
+					productProcessVO.setProductId(productEntity.getId());
+					productProcessVO.setSort(i);
+					productProcessVO.setStatus(0);
+					this.save(productProcessVO);
+					if(productProcessVO.getIsRetrospect()==1){
+						List<ProcessItemEntity>detailList = processItemService.list(Wrappers.<ProcessItemEntity>lambdaUpdate().eq(ProcessItemEntity::getProcessId,processEntity.getId()));
+						List<ProductProcessItemEntity>details = new ArrayList<>();
+						for(ProcessItemEntity processItem : detailList){
+							ProductProcessItemEntity productProcessItem = new ProductProcessItemVO();
+							productProcessItem.setId(null);
+							productProcessItem.setProductProcessId(productProcessVO.getId());
+							productProcessItem.setProcessItemId(processItem.getId());
+							productProcessItem.setProcessItemName(processItem.getName());
+							productProcessItem.setProcessItemValue(processItem.getValue());
+							productProcessItem.setValueType(processItem.getValueType());
+							productProcessItem.setMaxValue(processItem.getMaxValue());
+							productProcessItem.setMinValue(processItem.getMinValue());
+							productProcessItem.setUnit(processItem.getUnit());
+							productProcessItem.setStatus(1);
+							details.add(productProcessItem);
+						}
+						productProcessItemService.saveBatch(details);
+					}
+				}
+			}
+
+			return R.success("操作成功");
+		}else{
+			//产品存在,查询工序数据
+			long count = this.count(Wrappers.<ProductProcessEntity>lambdaQuery().eq(ProductProcessEntity::getProductId,productEntity.getId()));
+			if(count==0){
+				return R.fail("产品工序数据异常");
+			}
+			ProductProcessEntity processEntity = this.getOne(Wrappers.<ProductProcessEntity>lambdaQuery()
+				.eq(ProductProcessEntity::getProductId,productEntity.getId())
+				.eq(ProductProcessEntity::getStatus,0)
+				.orderByAsc(ProductProcessEntity::getSort),false);
+			if(processEntity==null){
+				return R.fail("已完成全部工序");
+			}
+			ProductProcessVO productProcessVO = productProcess.getProductProcess();
+			if(productProcessVO.getId()==null){
+				return R.fail("数据异常");
+			}
+			productProcessVO.setStatus(1);
+			productProcessVO.setOperatorName(user.getNickName());
+			this.updateById(productProcessVO);
+			if(processEntity.getIsRetrospect()==1){
+				productProcessItemService.updateBatchById(productProcess.getProductProcess().getDetails());
+			}
+			if(productProcessVO.getIsStandards()==0){
+				productEntity.setStatus(1);
+				productService.updateById(productEntity);
+				//未达标发起维修
+				ProductReworkEntity productReworkEntity = new ProductReworkEntity();
+				productReworkEntity.setFactoryId(productEntity.getFactoryId());
+				productReworkEntity.setProductId(productEntity.getId());
+				productReworkEntity.setQrCode(productEntity.getQrCode());
+				productReworkEntity.setProductModelId(productEntity.getProductModelId());
+				productReworkEntity.setProductName(productEntity.getProductName());
+				productReworkEntity.setProductModel(productEntity.getProductModel());
+				productReworkEntity.setRepairsImgs(productProcess.getImages());
+				productReworkEntity.setProblemDesc(productProcess.getProblemDesc());
+				productReworkEntity.setStatus(1);
+				productReworkEntity.setCreatePersonName(user.getNickName());
+				productReworkService.save(productReworkEntity);
+			}
+			return R.success("操作成功");
+		}
+	}
+
 }

+ 41 - 0
src/main/java/org/springblade/modules/pl/productProcess/vo/ProductProcessSubmitVO.java

@@ -0,0 +1,41 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.modules.pl.productProcess.vo;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springblade.modules.pl.productProcess.entity.ProductProcessEntity;
+import org.springblade.modules.pl.productProcess.entity.ProductProcessItemEntity;
+
+import java.util.List;
+
+/**
+ * 工序提交 视图实体类
+ *
+ * @author BladeX
+ * @since 2024-04-21
+ */
+@Data
+public class ProductProcessSubmitVO {
+	private static final long serialVersionUID = 1L;
+
+	private ProductProcessVO productProcess;
+	private String qrCode;
+	private String images;
+	private String problemDesc;
+
+}

+ 6 - 0
src/main/java/org/springblade/modules/pl/productProcess/vo/ProductProcessVO.java

@@ -16,10 +16,14 @@
  */
 package org.springblade.modules.pl.productProcess.vo;
 
+import org.springblade.modules.pl.process.entity.ProcessItemEntity;
 import org.springblade.modules.pl.productProcess.entity.ProductProcessEntity;
 import org.springblade.core.tool.node.INode;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
+import org.springblade.modules.pl.productProcess.entity.ProductProcessItemEntity;
+
+import java.util.List;
 
 /**
  * 商品工序记录表 视图实体类
@@ -32,4 +36,6 @@ import lombok.EqualsAndHashCode;
 public class ProductProcessVO extends ProductProcessEntity {
 	private static final long serialVersionUID = 1L;
 
+	private List<ProductProcessItemEntity> details;
+
 }

+ 2 - 3
src/main/java/org/springblade/modules/pl/productRework/service/impl/ProductReworkServiceImpl.java

@@ -63,8 +63,6 @@ public class ProductReworkServiceImpl extends BaseServiceImpl<ProductReworkMappe
 	@Resource
 	private RedissonClient redissonLock;
 	@Resource
-	private IProductImageRecordService productImageRecordService;
-	@Resource
 	private IProductModelService productModelService;
 
 	@Override
@@ -92,7 +90,7 @@ public class ProductReworkServiceImpl extends BaseServiceImpl<ProductReworkMappe
 		// 参数1:获取锁的最大等待时间(期间会多次重试获取锁)
 		// 参数2:锁自动释放时间
 		// 参数3:时间单位
-		boolean isGetLock = lock.tryLock(30, 60, TimeUnit.SECONDS);
+		boolean isGetLock = lock.tryLock(50, 60, TimeUnit.SECONDS);
 		if (isGetLock) {
 			try {
 				if(productCode.length()<25){
@@ -110,6 +108,7 @@ public class ProductReworkServiceImpl extends BaseServiceImpl<ProductReworkMappe
 				}else{
 					if(productEntity==null){
 						productEntity = new ProductEntity();
+						productEntity.setSource(3);
 					}
 					productEntity.setTenantId(productModel.getTenantId());
 					productEntity.setFactoryId(productModel.getFactoryId());