فهرست منبع

【亿道外协厂EIS增加接口:接收SN序列号扫码绑定物料结果】

xiaost 4 ماه پیش
والد
کامیت
580509a50a

+ 29 - 0
src/main/java/com/uas/eis/controller/MESDataController.java

@@ -3,6 +3,7 @@ package com.uas.eis.controller;
 import com.uas.eis.entity.ErrorMessage;
 import com.uas.eis.entity.ProdBindSetRequest;
 import com.uas.eis.entity.SNBindInfoRequest;
+import com.uas.eis.entity.SNBindMaterialRequest;
 import com.uas.eis.sdk.entity.ApiResult;
 import com.uas.eis.sdk.resp.ApiResponse;
 import com.uas.eis.service.MESDataService;
@@ -241,4 +242,32 @@ public class MESDataController {
         }
         return mesDataService.SNBindInfo(accessKey,requestId,reqData,rawJson);
     }
+
+    /**
+     * @add xiaost 2026-06-03
+     * 接收SN序列号扫码绑定物料结果
+     * @param rawJson
+     * @return
+     */
+    @RequestMapping(value = "/api/mes/SNBindMaterial" , method = RequestMethod.POST)
+    public ApiResult<Map<Object,Object>> SNBindMaterial(HttpServletRequest request,@RequestBody String rawJson){
+        String accessKey = request.getHeader("AccessKey");
+        String requestId = request.getHeader("RequestId");
+        SNBindMaterialRequest reqData;
+        try {
+            reqData = FlexJsonUtil.fromJson(rawJson, SNBindMaterialRequest.class);
+        } catch (Exception e) {
+            return ApiResponse.failRsp(ErrorMessage.BUSINESS_ILLEGAL.getCode(),requestId,"传参数据格式错误");
+        }
+        // 手动校验
+        Set<ConstraintViolation<SNBindMaterialRequest>> violations = validator.validate(reqData);
+        if (!violations.isEmpty()) {
+            String msg = violations.stream()
+                    .map(ConstraintViolation::getMessage)
+                    .distinct()  // 按消息内容去重
+                    .collect(Collectors.joining(";"));
+            return ApiResponse.failRsp(ErrorMessage.BUSINESS_ILLEGAL.getCode(), requestId, msg);
+        }
+        return mesDataService.SNBindMaterial(accessKey,requestId,reqData,rawJson);
+    }
 }

+ 1 - 0
src/main/java/com/uas/eis/dao/BaseDao.java

@@ -127,6 +127,7 @@ public class BaseDao  {
 			jdbcTemplate.update(sql, objs);
 			return true;
 		} catch (Exception e) {
+			BaseUtil.showError(e.getMessage());
 			return false;
 		}
 	}

+ 2 - 3
src/main/java/com/uas/eis/entity/ProdBindSetRequest.java

@@ -11,11 +11,10 @@ import java.util.List;
 @Data
 public class ProdBindSetRequest {
 
-    @NotNull(message = "code不能为空")
+    @NotBlank(message = "code不能为空")
     private String code;
 
     @NotNull(message = "data不能为空")
-
     @Valid
     private DataDTO data;
 
@@ -27,7 +26,7 @@ public class ProdBindSetRequest {
         @Pattern(regexp = "ADD|DEL", message = "type必须是ADD或DEL")
         private String type;
 
-        @NotNull(message = "ss_mothercode不能为空")
+        @NotBlank(message = "ss_mothercode不能为空")
         private String ss_mothercode;
 
         // 注意:detail 在 ADD 时必填且元素必填,但注解无法表达“条件必填”,

+ 67 - 0
src/main/java/com/uas/eis/entity/SNBindMaterialRequest.java

@@ -0,0 +1,67 @@
+package com.uas.eis.entity;
+import lombok.Data;
+import org.hibernate.validator.constraints.NotBlank;
+
+import javax.validation.Valid;
+import javax.validation.constraints.DecimalMin;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Pattern;
+import javax.validation.constraints.Size;
+import java.util.List;
+
+@Data
+public class SNBindMaterialRequest {
+
+    @NotBlank(message = "code不能为空")
+    private String code;
+
+    @NotNull(message = "data不能为空")
+    @Valid
+    private DataDTO data;
+
+    @Data
+    public static class DataDTO {
+        @NotBlank(message = "type不能为空")
+        @Pattern(regexp = "ADD|DEL", message = "type必须是ADD或者DEL")
+        private String type;   //目前是ADD,后续再考虑其它的
+
+        @NotBlank(message = "sm_macode不能为空")
+        private String sm_macode;
+
+        @NotBlank(message = "sm_maprodcode不能为空")
+        private String sm_maprodcode;
+
+        @NotBlank(message = "sm_sncode不能为空")
+        private String sm_sncode;
+
+        // (若为空数组则通过 @Size(min=1) 限制)
+        @NotNull(message = "detail不能为空或者null")
+        @Size(min = 1, max = 1000, message = "detail至少包含1条记录,最多不超过1000条")
+        @Valid
+        private List<DetailDTO> detail;
+
+    }
+
+    @Data
+    public static class DetailDTO {
+
+        private Integer sm_binddetno;
+
+        private String sm_stepcode;
+
+        private String sm_stepname;
+
+        @NotBlank(message = "sm_fprodcode不能为空")
+        private String sm_fprodcode;
+
+        @NotBlank(message = "sm_aprodcode不能为空")
+        private String sm_aprodcode;
+
+        @NotBlank(message = "sm_barcode不能为空")
+        private String sm_barcode;
+
+        @NotNull(message = "sm_qty不能为空")
+        @DecimalMin(value = "0.0", inclusive = false, message = "sm_qty必须大于0")
+        private double sm_qty;
+    }
+}

+ 3 - 0
src/main/java/com/uas/eis/service/MESDataService.java

@@ -2,6 +2,7 @@ package com.uas.eis.service;
 
 import com.uas.eis.entity.ProdBindSetRequest;
 import com.uas.eis.entity.SNBindInfoRequest;
+import com.uas.eis.entity.SNBindMaterialRequest;
 import com.uas.eis.sdk.entity.ApiResult;
 
 import java.util.List;
@@ -40,4 +41,6 @@ public interface MESDataService {
 	ApiResult<Map<Object, Object>> prodBindSet(String accessKey, String requestId, ProdBindSetRequest reqData,String jsonData);
 
 	ApiResult<Map<Object, Object>> SNBindInfo(String accessKey, String requestId, SNBindInfoRequest reqData, String rawJson);
+
+	ApiResult<Map<Object, Object>> SNBindMaterial(String accessKey, String requestId, SNBindMaterialRequest reqData, String rawJson);
 }

+ 144 - 0
src/main/java/com/uas/eis/serviceImpl/MESDataServiceImpl.java

@@ -6,6 +6,7 @@ import com.uas.eis.dao.SqlRowList;
 import com.uas.eis.entity.ErrorMessage;
 import com.uas.eis.entity.ProdBindSetRequest;
 import com.uas.eis.entity.SNBindInfoRequest;
+import com.uas.eis.entity.SNBindMaterialRequest;
 import com.uas.eis.exception.ApiSystemException;
 import com.uas.eis.sdk.entity.ApiResult;
 import com.uas.eis.sdk.resp.ApiResponse;
@@ -608,6 +609,149 @@ public class MESDataServiceImpl implements MESDataService {
 		return executeSNBindInfo(accessKey,requestId,reqData);
 	}
 
+
+	/**
+	 * @add xiaost 2026-06-03
+	 * 接收SN序列号扫码绑定物料结果
+	 * @param rawJson
+	 * {
+	 * "code": "SNBINDMATERIAL",
+	 * "data":{
+	 *    "type":"ADD",
+	 *    "sm_mothercode":"MA123003",
+	 *    "sm_maprodcode":"01EL0PR68M06030A",
+	 *    "sm_sncode":"W20211230029A1",
+	 *    "detail":[{
+	 *       "sm_stepcode":"B_AOIB",
+	 *       "sm_stepname":"B_AOIB",
+	 *       "sm_binddetno":2,
+	 *       "sm_fprodcode":"ER35564666",
+	 *       "sm_aprodcode":"ER35564666",
+	 *       "sm_barcode":"B34677733",
+	 *       "sm_qty":1
+	 *    }]
+	 *  }
+	 * }
+	 * @return
+	 */
+	@Override
+	public ApiResult<Map<Object, Object>> SNBindMaterial(String accessKey, String requestId, SNBindMaterialRequest reqData, String rawJson) {
+		String AE_MASTER = checkAccessKey(accessKey, requestId);
+		SpObserver.putSp(AE_MASTER);  //切换数据源
+		//保存传参数据原始JSON串,记录日志
+		savelog("接收SN序列号扫码绑定物料结果",rawJson,accessKey,requestId);
+		//执行业务操作
+		return executeSNBindMaterial(accessKey,requestId,reqData);
+	}
+
+
+	@Transactional
+	public ApiResult<Map<Object, Object>> executeSNBindMaterial(String accessKey, String requestId, SNBindMaterialRequest reqData) {
+		SNBindMaterialRequest.DataDTO dataDTO = reqData.getData();
+		String mothercode = dataDTO.getSm_maprodcode();
+		String sncode = dataDTO.getSm_sncode();
+		String macode = dataDTO.getSm_macode();
+		String type = dataDTO.getType();
+		List<SNBindMaterialRequest.DetailDTO> detailList = dataDTO.getDetail();
+
+		//绑定项编号不能重复
+		Set<String> set = new HashSet<>();
+		List<String> duplicates = detailList.stream()
+				.map(SNBindMaterialRequest.DetailDTO::getSm_fprodcode)
+				.filter(s -> !set.add(s))
+				.distinct()
+				.collect(Collectors.toList());
+		if (!duplicates.isEmpty()) {
+			return ApiResponse.failRsp(ErrorMessage.BUSINESS_ILLEGAL.getCode(), requestId,
+					 "本次传参存在重复的sm_fprodcode: " + String.join(", ", duplicates));
+		}
+		//绑定值条码号等必须唯一不能重复 ,也不能与历史数据重复
+		Set<String> set1 = new HashSet<>();
+		duplicates = detailList.stream()
+				.map(SNBindMaterialRequest.DetailDTO::getSm_barcode)
+				.filter(s -> !set1.add(s))
+				.distinct()
+				.collect(Collectors.toList());
+		if (!duplicates.isEmpty()) {
+			return ApiResponse.failRsp(ErrorMessage.BUSINESS_ILLEGAL.getCode(), requestId,
+					"本次传参存在重复的sm_barcode: " + String.join(", ", duplicates));
+		}
+
+		//校验是否存在绑定项
+		String insertSql = "INSERT INTO SNBINDMATERIAL (SM_ID,SM_SNCODE,SM_MAPRODCODE,SM_MACODE,SM_STEPCODE,SM_STEPNAME," +
+				"  SM_BINDDETNO,SM_FPRODCODE,SM_APRODCODE,SM_QTY,SM_BARCODE,SM_INDATE) " +
+				" VALUES (SNBINDMATERIAL_seq.nextval,?, ?, ?, ?, ?, ?, ?,?,?,?,sysdate)";
+		String insertHisSql = "INSERT INTO SNBINDMATERIAL_HIS (SM_ID,SM_SNCODE,SM_MAPRODCODE,SM_MACODE,SM_STEPCODE,SM_STEPNAME," +
+				"  SM_BINDDETNO,SM_FPRODCODE,SM_APRODCODE,SM_QTY,SM_BARCODE,SM_INDATE,SH_INDATE,SH_TYPE) " +
+				" select SM_ID,SM_SNCODE,SM_MAPRODCODE,SM_MACODE,SM_STEPCODE,SM_STEPNAME," +
+				"  SM_BINDDETNO,SM_FPRODCODE,SM_APRODCODE,SM_QTY,SM_BARCODE,SM_INDATE,SYSDATE,? from SNBINDMATERIAL " +
+				"  where SM_SNCODE=? and SM_MACODE=? and sm_fprodcode=? ";
+		List<Object[]> batchArgs = new ArrayList<>();
+		for (SNBindMaterialRequest.DetailDTO detail : detailList) {
+			String fprodcode = detail.getSm_fprodcode();
+			if("ADD".equals(type)) {
+				int cn = baseDao.getJdbcTemplate().queryForObject("select count(1) from SNBINDSET where ss_mothercode=? and ss_prodcode =?",Integer.class,
+						mothercode,detail.getSm_fprodcode());
+				if(cn == 0){
+					return ApiResponse.failRsp(ErrorMessage.BUSINESS_ILLEGAL.getCode(), requestId,
+							"绑定项编号(sm_fprodcode):" +detail.getSm_fprodcode()+",不在产品强制绑定项设置里面!");
+				}
+				cn = baseDao.getJdbcTemplate().queryForObject("select count(1) from SNBINDSET where ss_mothercode=? and ss_prodcode =?",Integer.class,
+						mothercode,detail.getSm_aprodcode());
+				if(cn == 0){
+					return ApiResponse.failRsp(ErrorMessage.BUSINESS_ILLEGAL.getCode(), requestId,
+							"实际绑定编号(sm_aprodcode):" +detail.getSm_aprodcode()+",与绑定项设置"+detail.getSm_fprodcode()+"不一致");
+				}
+				batchArgs.add(new Object[]{
+						sncode,
+						mothercode,
+						macode,
+						detail.getSm_stepcode(),
+						detail.getSm_stepname(),
+						detail.getSm_binddetno(),
+						fprodcode,
+						detail.getSm_aprodcode(),
+						detail.getSm_qty(),
+						detail.getSm_barcode()
+				});
+				//是否原有绑定项,有则删除写历史表
+				cn = baseDao.getJdbcTemplate().queryForObject("select count(1)  from SNBINDMATERIAL WHERE SM_SNCODE=? and SM_MACODE=? and sm_fprodcode=?",Integer.class,sncode,macode,fprodcode);
+			    if(cn>0){
+					baseDao.execute(insertHisSql,"修改",sncode,macode,fprodcode);
+					baseDao.execute("delete from SNBINDMATERIAL WHERE SM_SNCODE=? and SM_MACODE=? and sm_fprodcode=?",sncode,macode,fprodcode);
+				}
+			}else if("DEL".equals(type)){
+				int cn = baseDao.getJdbcTemplate().queryForObject("select count(1) from SNBINDMATERIAL where SM_SNCODE=? and SM_MACODE=? and sm_fprodcode=? and sm_barcode=?",
+						Integer.class,sncode,macode,fprodcode,detail.getSm_barcode());
+                if(cn == 0){
+					return ApiResponse.failRsp(ErrorMessage.BUSINESS_ILLEGAL.getCode(), requestId,
+							"绑定项编号(sm_fprodcode):" +detail.getSm_fprodcode()+",不在产品强制绑定项设置里面!");
+				}else{
+                    baseDao.execute(insertHisSql+" and sm_barcode=?","解绑",sncode,macode,fprodcode,detail.getSm_barcode());
+					baseDao.execute("delete from SNBINDMATERIAL WHERE SM_SNCODE=? and SM_MACODE=? and sm_fprodcode=? and sm_barcode=?",sncode,macode,fprodcode,detail.getSm_barcode());
+				}
+			}
+		}
+		if("ADD".equals(type)) {
+			//校验是否重复barcode 不重复则插入
+			List<String> barList = detailList.stream()
+					.map(SNBindMaterialRequest.DetailDTO::getSm_barcode)
+					.distinct()
+					.collect(Collectors.toList());
+			String checksql = "select wm_concat(sm_barcode) from SNBINDMATERIAL where sm_barcode IN (%s) and rownum<20";
+			String inClause = String.join(",", Collections.nCopies(barList.size(), "?"));
+			checksql = String.format(checksql, inClause);
+			String barr = baseDao.getJdbcTemplate().queryForObject(checksql,String.class,barList.toArray());
+            if(null != barr){
+				return ApiResponse.failRsp(ErrorMessage.BUSINESS_ILLEGAL.getCode(), requestId,
+						"sm_barcode与历史已有数据表重复: " + barr);
+			}
+			baseDao.getJdbcTemplate().batchUpdate(insertSql, batchArgs);
+		}
+		return ApiResponse.successRsp("0",requestId,"操作成功");
+	}
+
+
 	@Transactional
 	public ApiResult<Map<Object, Object>> executeSNBindInfo(String accessKey, String requestId, SNBindInfoRequest reqData) {
 		List<SNBindInfoRequest.DetailDTO> detailList =  reqData.getData().getDetail();