Quellcode durchsuchen

涂胶优化,安装水冷板优化

sunxianglong vor 2 Monaten
Ursprung
Commit
e171707002

+ 6 - 84
src/main/java/com/jeesite/modules/mes/web/MesSnColdController.java

@@ -1,6 +1,5 @@
 package com.jeesite.modules.mes.web;
 
-import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
 import javax.servlet.http.HttpServletRequest;
@@ -8,24 +7,12 @@ import javax.servlet.http.HttpServletResponse;
 
 import com.jeesite.common.lang.ObjectUtils;
 import com.jeesite.common.lang.StringUtils;
-import com.jeesite.modules.mes.entity.MesLine;
 import com.jeesite.modules.mes.entity.MesProduct;
-import com.jeesite.modules.mes.resp.BindMaterialResp;
 import com.jeesite.modules.mes.resp.CommonResp;
-import com.jeesite.modules.mes.resp.ParamsResp;
-import com.jeesite.modules.mes.service.MesLineProcessMaterialService;
-import com.jeesite.modules.mes.service.MesLineService;
-import com.jeesite.modules.mes.service.MesProductRecordService;
 import com.jeesite.modules.mes.service.MesProductService;
-import com.jeesite.modules.sys.entity.User;
-import com.jeesite.modules.sys.utils.UserUtils;
-import com.jeesite.modules.utils.ErrorMsg;
 import org.apache.shiro.authz.annotation.RequiresPermissions;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Controller;
-import org.springframework.transaction.annotation.Transactional;
-import org.springframework.transaction.interceptor.TransactionAspectSupport;
 import org.springframework.ui.Model;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.ModelAttribute;
@@ -54,19 +41,6 @@ public class MesSnColdController extends BaseController {
 	@Autowired
 	private MesProductService mesProductService;
 
-	@Autowired
-	private MesLineService mesLineService;
-
-	@Autowired
-	private MesProductRecordService mesProductRecordService;
-
-	@Autowired
-	private MesLineProcessMaterialService mesLineProcessMaterialService;
-
-	@Lazy
-	@Autowired
-	private MesProductRecordController mesProductRecordController;
-
 	/**
 	 * 获取数据
 	 */
@@ -147,13 +121,12 @@ public class MesSnColdController extends BaseController {
 
 	/**
 	 * 水冷板工件绑定提交
-	 * 传 sn、coldSn、oprno:校验工件存在 → 质量检验 → 可加工则写入绑定表,并提交该工位结果为 OK
+	 * 传 sn、coldSn、oprno:校验参数与工件后仅写入绑定表(质量校验、工位提交已隐藏)
 	 * @param mesSnCold
 	 * @return
 	 */
 	@RequestMapping(value = "coldSubmit")
 	@ResponseBody
-	@Transactional
 	public CommonResp coldSubmit(MesSnCold mesSnCold) {
 		CommonResp<String> resp = new CommonResp<>();
 		String sn = mesSnCold.getSn();
@@ -175,70 +148,19 @@ public class MesSnColdController extends BaseController {
 			return resp;
 		}
 
-		// 1. 判定工件码是否在数据库中
+		// 判定工件码是否在数据库中
 		MesProduct mesProduct1 = new MesProduct();
 		mesProduct1.setSn(mesSnCold.getSn());
 		List<MesProduct> list = mesProductService.findList(mesProduct1);
-		if (list.isEmpty()){
-			resp.setResult(Global.FALSE);
-			resp.setMessage("工件不存在");
-			return resp;
-		}
-		MesProduct mesProduct =list.get(0);
-		if (ObjectUtils.isEmpty(mesProduct)) {
+		if (list.isEmpty() || ObjectUtils.isEmpty(list.get(0))){
 			resp.setResult(Global.FALSE);
 			resp.setMessage("工件不存在");
 			return resp;
 		}
 
-		// 根据工件类型解析产线编号(质量检验需要 lineSn)
-		MesLine mesLine = new MesLine();
-		mesLine.setProductCate(mesProduct.getCate());
-		mesLine.setStatus("0");
-		MesLine lineInfo = mesLineService.findInfo(mesLine);
-		if (ObjectUtils.isEmpty(lineInfo) || StringUtils.isEmpty(lineInfo.getSn())) {
-			resp.setResult(Global.FALSE);
-			resp.setMessage("产线信息不存在");
-			return resp;
-		}
-		String lineSn = lineInfo.getSn();
-
-		// 2. 质量检验
-		String oldOprno = oprno;
-		if (oldOprno.length() == 5) {
-			oldOprno += "A";
-		}
-		String userCode = "";
-		User user = UserUtils.getUser();
-		if (user != null && StringUtils.isNotEmpty(user.getUserCode())) {
-			userCode = user.getUserCode();
-		}
-
-		String ret = mesProductRecordController.checkQualityCommon(oldOprno, sn, lineSn, userCode);
-		String checkret = ret.substring(3, 5);
-		if (!"UD".equals(checkret)) {
-			String lx = ret.substring(0, 3);
-			resp.setResult(Global.FALSE);
-			resp.setMessage(ErrorMsg.getErrorMsg(checkret, lx));
-			resp.setData(checkret);
-			return resp;
-		}
-
-		// 3. 可以加工:写入绑定表,并将该工位总结果提交为 OK
-		try {
-			mesSnCold.setUpdateTime(new Date());
-			mesSnColdService.save(mesSnCold);
-
-			List<ParamsResp> params = new ArrayList<>();
-			List<BindMaterialResp> bmlists = mesLineProcessMaterialService.getBindMaterial(oldOprno, lineSn);
-			mesProductRecordService.updateRecordResult(sn, oldOprno, "100000", coldSn, "OK",
-					userCode, params, lineSn, true, bmlists, null);
-		} catch (Exception e) {
-			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
-			resp.setResult(Global.FALSE);
-			resp.setMessage(StringUtils.isNotEmpty(e.getMessage()) ? e.getMessage() : "操作失败!");
-			return resp;
-		}
+		// 仅保存绑定数据(质量校验、工位提交已隐藏)
+		mesSnCold.setUpdateTime(new Date());
+		mesSnColdService.save(mesSnCold);
 
 		resp.setResult(Global.TRUE);
 		resp.setMessage("操作成功!");

+ 88 - 5
src/main/java/com/jeesite/modules/scheduling/ProductTjScheduling.java

@@ -7,10 +7,15 @@ import com.jeesite.common.lang.ObjectUtils;
 import com.jeesite.common.lang.StringUtils;
 import com.jeesite.modules.mes.entity.MesLine;
 import com.jeesite.modules.mes.entity.MesProduct;
+import com.jeesite.modules.mes.entity.MesProductRecord;
 import com.jeesite.modules.mes.entity.MesProductTj;
+import com.jeesite.modules.mes.resp.BindMaterialResp;
+import com.jeesite.modules.mes.resp.ParamsResp;
 import com.jeesite.modules.mes.service.MesLineService;
+import com.jeesite.modules.mes.service.MesProductRecordService;
 import com.jeesite.modules.mes.service.MesProductService;
 import com.jeesite.modules.mes.service.MesProductTjService;
+import com.jeesite.modules.mes.util.CommonUitl;
 import com.jeesite.modules.mes.web.MesProductRecordController;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -19,17 +24,19 @@ import org.springframework.context.annotation.Configuration;
 import org.springframework.scheduling.annotation.EnableScheduling;
 import org.springframework.scheduling.annotation.Scheduled;
 
+import java.util.ArrayList;
+import java.util.List;
 import java.util.concurrent.atomic.AtomicBoolean;
 
 /**
- * 涂胶 S7 采集与质量握手(OP220,固定工位号,不提交工位结果)。
+ * 涂胶 S7 采集与质量握手(OP220,固定工位号)。
  * <pre>
  * DB1300 点位:
  *   0.0    框架码 String[30]
  *   64.0   扫码反馈信号
  *   64.2   质量校验通过反馈(校验通过 MES 写 true,工位完成后 MES 写 false)
  *   64.4   涂胶数据采集触发
- *   64.5   整体完成信号(true 时 MES 将 64.2 置 false)
+ *   64.5   整体完成信号(true 时提交工位 OK 并回查确认落库,成功后将 64.2 置 false)
  *   66.0   涂胶序号 Word
  *   68.0   涂胶速度 Real
  *   72.0   涂胶长度 Word
@@ -68,6 +75,8 @@ public class ProductTjScheduling {
 	private MesLineService mesLineService;
 	@Autowired
 	private MesProductTjService mesProductTjService;
+	@Autowired
+	private MesProductRecordService mesProductRecordService;
 
 	private final AtomicBoolean running = new AtomicBoolean(false);
 	private volatile String lastKnownSn;
@@ -166,7 +175,7 @@ public class ProductTjScheduling {
 	}
 
 	/**
-	 * DB1300.64.5 整体完成信号为 true:将 DB1300.64.2 置 false(不提交工位结果)
+	 * DB1300.64.5 整体完成信号为 true:提交工位 OK → 成功后将 DB1300.64.2 置 false
 	 */
 	private void handleComplete(S7PLC s7PLC) {
 		if (!s7PLC.readBoolean(ADDR_COMPLETE)) {
@@ -178,16 +187,21 @@ public class ProductTjScheduling {
 			sn = lastKnownSn;
 		}
 		if (StringUtils.isBlank(sn)) {
-			logger.error("涂胶工位完成复位失败:无工件码,保持 {}=true 待重试", ADDR_COMPLETE);
+			logger.error("涂胶工位完成提交失败:无工件码,保持 {}=true 待重试", ADDR_COMPLETE);
 			return;
 		}
 		if (sn.equals(lastCompletedSn)) {
 			return;
 		}
 
+		if (!submitStationResult(sn, "OK")) {
+			logger.error("涂胶工位结果提交失败,保持信号待重试 sn={}", sn);
+			return;
+		}
+
 		s7PLC.writeBoolean(ADDR_QUALITY_PASS, false);
 		lastCompletedSn = sn;
-		logger.info("涂胶工位完成 sn={},已将 {} 置 false", sn, ADDR_QUALITY_PASS);
+		logger.info("涂胶工位完成 sn={},已提交 OK 并将 {} 置 false", sn, ADDR_QUALITY_PASS);
 	}
 
 	private boolean saveTjData(String sn, int glueSeq, float glueSpeed, int glueLength) {
@@ -206,6 +220,75 @@ public class ProductTjScheduling {
 		}
 	}
 
+	/**
+	 * 直接提交工位结果(供测试 / 手工触发),不读写 PLC 信号。
+	 * 逻辑与 64.5 完成时的 submitStationResult 相同(含回查与强制落库)。
+	 *
+	 * @param sn     工件码
+	 * @param result 结果,通常为 OK
+	 * @return true=craft=100000 已确认为目标结果
+	 */
+	public boolean submitStationResultNow(String sn, String result) {
+		if (StringUtils.isBlank(sn)) {
+			logger.error("涂胶工位结果提交跳过:工件码为空");
+			return false;
+		}
+		return submitStationResult(sn.trim(), StringUtils.isBlank(result) ? "OK" : result.trim());
+	}
+
+	/**
+	 * 提交工位结果为 OK,并回查 craft=100000 确认已落库。
+	 * updateRecordResult 在单部件工位或缺少总结果行时可能静默跳过,此时改走 updateRecord 强制更新。
+	 */
+	private boolean submitStationResult(String sn, String result) {
+		String oldOprno = OPRNO + "A";
+		String lineSn = getLineSn(sn);
+		if (StringUtils.isBlank(lineSn)) {
+			logger.warn("涂胶工位结果提交失败:无法解析产线编号 sn={}", sn);
+			return false;
+		}
+		try {
+			List<ParamsResp> params = new ArrayList<>();
+			List<BindMaterialResp> bmlists = new ArrayList<>();
+			mesProductRecordService.updateRecordResult(sn, oldOprno, "100000", "", result,
+					"", params, lineSn, true, bmlists, null);
+
+			if (isStationMainResult(sn, lineSn, result)) {
+				logger.info("涂胶工位结果已提交 sn={} oprno={} result={}", sn, oldOprno, result);
+				return true;
+			}
+
+			logger.warn("updateRecordResult 未真正更新 craft=100000,改为 updateRecord 强制提交 sn={} oprno={}",
+					sn, oldOprno);
+			mesProductRecordService.updateRecord(sn, oldOprno, "100000", "", result, "", lineSn);
+
+			if (!isStationMainResult(sn, lineSn, result)) {
+				logger.error("涂胶工位结果强制提交后仍未落库 sn={} oprno={} lineSn={}", sn, oldOprno, lineSn);
+				return false;
+			}
+			logger.info("涂胶工位结果已强制提交 sn={} oprno={} result={}", sn, oldOprno, result);
+			return true;
+		} catch (Exception e) {
+			logger.error("涂胶工位结果提交异常 sn={}:{}", sn, e.getMessage());
+			return false;
+		}
+	}
+
+	/** 回查工位总结果行 craft=100000 是否已为指定结果 */
+	private boolean isStationMainResult(String sn, String lineSn, String expectContent) {
+		String fOprno = CommonUitl.formatOprno(OPRNO + "A");
+		MesProductRecord query = new MesProductRecord();
+		query.setSn(sn);
+		query.setOprno(fOprno);
+		query.setCraft("100000");
+		query.setLineSn(lineSn);
+		List<MesProductRecord> list = mesProductRecordService.findList(query);
+		if (list == null || list.isEmpty()) {
+			return false;
+		}
+		return expectContent.equals(list.get(0).getContent());
+	}
+
 	private boolean doQualityCheck(String sn) {
 		String oldOprno = OPRNO + "A";
 		String lineSn = getLineSn(sn);

+ 82 - 249
src/test/java/com/jeesite/test/ProductTjQualityCheckTest.java

@@ -6,31 +6,27 @@ import com.jeesite.common.config.Global;
 import com.jeesite.common.lang.StringUtils;
 import com.jeesite.common.tests.BaseSpringContextTests;
 import com.jeesite.modules.Application;
+import com.jeesite.modules.mes.entity.MesProductRecord;
+import com.jeesite.modules.mes.service.MesProductRecordService;
+import com.jeesite.modules.mes.util.CommonUitl;
 import com.jeesite.modules.mes.web.MesProductRecordController;
+import com.jeesite.modules.scheduling.ProductTjScheduling;
 import org.junit.Assume;
 import org.junit.Test;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.test.annotation.Rollback;
 import org.springframework.test.context.ActiveProfiles;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
 
 /**
- * 涂胶 / FSW 定时任务质量校验联调测试。
- * <p>
- * 覆盖以下类的 {@code checkQualityCommon} 调用逻辑:
- * <ul>
- *   <li>{@link com.jeesite.modules.scheduling.ProductTjScheduling}(OP220)</li>
- *   <li>{@link com.jeesite.modules.scheduling.ProductTjBScheduling}(mes.tj.b.oprno)</li>
- *   <li>{@link com.jeesite.modules.scheduling.FswModbusScheduling}(mes.fsw.modbus.oprno)</li>
- * </ul>
- * 另含 ProductTjScheduling 写 DB1300.64.2 的 PLC 联调(需连涂胶 PLC)。
+ * 涂胶 / FSW 定时任务质量校验与提交联调测试。
  * <p>
- * 使用方式:
- * <ul>
- *   <li>JUnit:填写下方 TEST_SN 后运行 test 方法</li>
- *   <li>main:右键运行 main,需先启动数据库等服务</li>
- * </ul>
+ * 使用方式:填写下方 TEST_SN 后运行对应 @Test,或右键运行 main。
  */
 @ActiveProfiles("test")
 @SpringBootTest(classes = Application.class)
@@ -39,169 +35,134 @@ public class ProductTjQualityCheckTest extends BaseSpringContextTests {
 	// ===================== 自行填写 =====================
 
 	/** 待测工件码(必填) */
-	private static final String TEST_SN = "0050010200173E5240017067251A22";
+	private static final String TEST_SN = "0050010200173E5240017067171A02";
 
-	/** 产线编号,与 application.yml 中 mes.tj.lineSn / mes.tj.b.lineSn 一致 */
+	/** 产线编号(回查 craft=100000 时使用;提交时产线由 ProductTjScheduling 按配置解析) */
 	private static final String TEST_LINE_SN = "XT";
 
-	/**
-	 * B 侧工位号;留空则读取 mes.tj.b.oprno,仍为空时使用 OP240B(与 ProductTjBScheduling 默认一致)
-	 */
-	private static final String TJ_B_OPRNO = "";
-
-	/**
-	 * FSW 工位号;留空则读取 mes.fsw.modbus.oprno(与 FswModbusScheduling 一致,未配置则校验失败)
-	 */
-	private static final String FSW_OPRNO = "OP230";
-
-	/**
-	 * FSW 产线编号;留空则读取 mes.fsw.modbus.lineSn,仍为空则使用 TEST_LINE_SN
-	 */
-	private static final String FSW_LINE_SN = "XT";
-
-	/**
-	 * 涂胶 PLC IP;留空则读取 mes.tj.plc.ip,仍为空则使用 10.0.40.100
-	 */
+	/** 涂胶 PLC IP;留空则读取 mes.tj.plc.ip */
 	private static final String TJ_PLC_IP = "";
 
 	// ===================== 自行填写结束 =====================
 
-	/** ProductTjScheduling 固定工位号 */
 	private static final String TJ_A_OPRNO = "OP220";
-
-	private static final String DEFAULT_TJ_B_OPRNO = "OP240";
 	private static final String DEFAULT_TJ_PLC_IP = "10.0.40.100";
-	/** 与 ProductTjScheduling.ADDR_QUALITY_PASS 一致 */
 	private static final String ADDR_QUALITY_PASS = "DB1300.64.2";
 
 	@Autowired
 	private MesProductRecordController mesProductRecordController;
+	@Autowired
+	private MesProductRecordService mesProductRecordService;
+	@Autowired
+	private ProductTjScheduling productTjScheduling;
 
 	@Test
 	public void testProductTjSchedulingQualityCheck() {
-		Assume.assumeTrue("请先在类顶部填写 TEST_SN", StringUtils.isNotBlank(TEST_SN));
-
-		QualityCheckResult result = checkQualityLikeTjScheduling(TEST_SN.trim(), TEST_LINE_SN.trim());
-		printResult("ProductTjScheduling", TJ_A_OPRNO, result);
-
-		org.junit.Assert.assertNotNull(result.ret);
-		org.junit.Assert.assertTrue("返回码长度不足: " + result.ret, result.ret.length() >= 5);
+		Assume.assumeTrue("请先填写 TEST_SN", StringUtils.isNotBlank(TEST_SN));
+		String ret = mesProductRecordController.checkQualityCommon(
+				TJ_A_OPRNO + "A", TEST_SN.trim(), TEST_LINE_SN.trim(), "");
+		System.out.println("ProductTjScheduling 质量校验 ret=" + ret);
+		org.junit.Assert.assertNotNull(ret);
+		org.junit.Assert.assertTrue(ret.length() >= 5);
 	}
 
+	/**
+	 * 真实调用 ProductTjScheduling.submitStationResultNow,不读写 PLC(无 64.5/64.2 交互)。
+	 * 内部走与定时任务相同的提交 + 回查 + 强制落库逻辑。
+	 */
 	@Test
-	public void testProductTjBSchedulingQualityCheck() {
-		Assume.assumeTrue("请先在类顶部填写 TEST_SN", StringUtils.isNotBlank(TEST_SN));
-
-		String oprno = resolveTjBOprno();
-		QualityCheckResult result = checkQualityLikeTjBScheduling(TEST_SN.trim(), TEST_LINE_SN.trim(), oprno);
-		printResult("ProductTjBScheduling", oprno, result);
+	@Transactional
+	@Rollback(false)
+	public void testProductTjSchedulingSubmitStationResultNow() {
+		Assume.assumeTrue("请先填写 TEST_SN", StringUtils.isNotBlank(TEST_SN));
 
-		org.junit.Assert.assertNotNull(result.ret);
-		org.junit.Assert.assertTrue("返回码长度不足: " + result.ret, result.ret.length() >= 5);
-	}
-
-	@Test
-	public void testFswModbusSchedulingQualityCheck() {
-		Assume.assumeTrue("请先在类顶部填写 TEST_SN", StringUtils.isNotBlank(TEST_SN));
+		String sn = TEST_SN.trim();
+		String fOprno = CommonUitl.formatOprno(TJ_A_OPRNO + "A");
+		MesProductRecord before = findStationMainResult(sn, fOprno, TEST_LINE_SN.trim());
+		System.out.println("提交前 craft=100000 content="
+				+ (before == null ? "无记录" : before.getContent())
+				+ " oprno=" + (before == null ? "-" : before.getOprno()));
 
-		String oprno = resolveFswOprno();
-		Assume.assumeTrue("请配置 mes.fsw.modbus.oprno 或填写 FSW_OPRNO", StringUtils.isNotBlank(oprno));
+		boolean ok = productTjScheduling.submitStationResultNow(sn, "OK");
+		System.out.println("ProductTjScheduling.submitStationResultNow 返回=" + ok);
 
-		String lineSn = resolveFswLineSn();
-		QualityCheckResult result = checkQualityLikeFswModbusScheduling(TEST_SN.trim(), lineSn, oprno);
-		printResult("FswModbusScheduling", oprno, result, lineSn);
+		MesProductRecord after = findStationMainResult(sn, fOprno, TEST_LINE_SN.trim());
+		System.out.println("提交后 craft=100000 content="
+				+ (after == null ? "无记录" : after.getContent())
+				+ " oprno=" + (after == null ? "-" : after.getOprno()));
 
-		org.junit.Assert.assertNotNull(result.ret);
-		org.junit.Assert.assertTrue("返回码长度不足: " + result.ret, result.ret.length() >= 5);
+		org.junit.Assert.assertTrue("ProductTjScheduling 提交工位结果失败", ok);
+		org.junit.Assert.assertNotNull("提交后仍无 craft=100000 记录", after);
+		org.junit.Assert.assertEquals("OK", after.getContent());
 	}
 
-	/**
-	 * 模拟 ProductTjScheduling 写 DB1300.64.2=true(不做质量校验,直接写点位)。
-	 * 需涂胶 PLC 可达(mes.tj.plc.ip)。
-	 */
 	@Test
 	public void testProductTjSchedulingWriteQualityPass64_2() {
 		boolean written = writeQualityPassLikeTjScheduling(true);
-		org.junit.Assert.assertTrue("写 DB1300.64.2=true 失败(检查 PLC 连通性)", written);
+		org.junit.Assert.assertTrue("写 DB1300.64.2=true 失败", written);
 	}
 
-	/**
-	 * 手动联调:依次执行涂胶 A/B 与 FSW 质量校验,以及 A 侧写 64.2。
-	 */
 	public static void main(String[] args) {
 		if (StringUtils.isBlank(TEST_SN)) {
-			System.out.println("请先在 ProductTjQualityCheckTest 类顶部填写 TEST_SN 后再运行。");
+			System.out.println("请先填写 TEST_SN");
 			return;
 		}
-
-		System.out.println("========== 涂胶/FSW 质量校验联调 ==========");
+		System.out.println("========== ProductTjScheduling 提交工位结果联调(不连 PLC 信号)==========");
 		ConfigurableApplicationContext ctx = SpringApplication.run(Application.class, args);
 		try {
-			MesProductRecordController controller = ctx.getBean(MesProductRecordController.class);
-			ProductTjQualityCheckTest tester = new ProductTjQualityCheckTest();
-			tester.mesProductRecordController = controller;
+			ProductTjScheduling scheduling = ctx.getBean(ProductTjScheduling.class);
+			MesProductRecordService recordService = ctx.getBean(MesProductRecordService.class);
 
 			String sn = TEST_SN.trim();
-			String lineSn = TEST_LINE_SN.trim();
-
-			System.out.println("\n--- ProductTjScheduling (OP220) ---");
-			QualityCheckResult aResult = tester.checkQualityLikeTjScheduling(sn, lineSn);
-			printResult("ProductTjScheduling", TJ_A_OPRNO, aResult, lineSn);
+			String fOprno = CommonUitl.formatOprno(TJ_A_OPRNO + "A");
+			MesProductRecord before = findStationMainResultStatic(recordService, sn, fOprno, TEST_LINE_SN.trim());
+			System.out.println("提交前 content=" + (before == null ? "无记录" : before.getContent()));
 
-			System.out.println("\n--- ProductTjScheduling 写 DB1300.64.2=true(跳过质量校验)---");
-			boolean ok = writeQualityPassLikeTjScheduling(true);
-			System.out.println(ok ? "写 64.2=true 成功" : "写 64.2=true 失败");
+			boolean ok = scheduling.submitStationResultNow(sn, "OK");
+			System.out.println("submitStationResultNow=" + ok);
 
-			String bOprno = resolveTjBOprnoStatic();
-			System.out.println("\n--- ProductTjBScheduling (" + bOprno + ") ---");
-			QualityCheckResult bResult = tester.checkQualityLikeTjBScheduling(sn, lineSn, bOprno);
-			printResult("ProductTjBScheduling", bOprno, bResult, lineSn);
-
-			String fswOprno = resolveFswOprnoStatic();
-			if (StringUtils.isBlank(fswOprno)) {
-				System.out.println("\n--- FswModbusScheduling:未配置 mes.fsw.modbus.oprno,跳过 ---");
-			} else {
-				String fswLineSn = resolveFswLineSnStatic();
-				System.out.println("\n--- FswModbusScheduling (" + fswOprno + ") ---");
-				QualityCheckResult fswResult = tester.checkQualityLikeFswModbusScheduling(sn, fswLineSn, fswOprno);
-				printResult("FswModbusScheduling", fswOprno, fswResult, fswLineSn);
-			}
-
-			System.out.println("\n完成。");
+			MesProductRecord after = findStationMainResultStatic(recordService, sn, fOprno, TEST_LINE_SN.trim());
+			System.out.println("提交后 content=" + (after == null ? "无记录" : after.getContent()));
 		} finally {
 			ctx.close();
 		}
 	}
 
-	/**
-	 * 与 ProductTjScheduling.doQualityCheck 相同:固定 OP220,校验工位 OP220A。
-	 */
-	QualityCheckResult checkQualityLikeTjScheduling(String sn, String lineSn) {
-		String checkOprno = TJ_A_OPRNO + "A";
-		return invokeQualityCheck(checkOprno, sn, lineSn);
+	private MesProductRecord findStationMainResult(String sn, String oprnoLike, String lineSn) {
+		return findStationMainResultStatic(mesProductRecordService, sn, oprnoLike, lineSn);
+	}
+
+	private static MesProductRecord findStationMainResultStatic(MesProductRecordService service,
+			String sn, String oprnoLike, String lineSn) {
+		MesProductRecord query = new MesProductRecord();
+		query.setSn(sn);
+		query.setOprno(oprnoLike);
+		query.setCraft("100000");
+		query.setLineSn(lineSn);
+		List<MesProductRecord> list = service.findList(query);
+		if (list == null || list.isEmpty()) {
+			return null;
+		}
+		return list.get(0);
 	}
 
-	/**
-	 * 直接写 DB1300.64.2(不做质量校验),并回读确认。
-	 *
-	 * @param value true=质量通过反馈,false=复位
-	 * @return true=写入并回读一致
-	 */
 	static boolean writeQualityPassLikeTjScheduling(boolean value) {
-		String ip = resolveTjPlcIp();
+		String ip = StringUtils.isNotBlank(TJ_PLC_IP) ? TJ_PLC_IP.trim() : null;
+		if (StringUtils.isBlank(ip)) {
+			ip = Global.getConfig("mes.tj.plc.ip");
+		}
+		if (StringUtils.isBlank(ip)) {
+			ip = DEFAULT_TJ_PLC_IP;
+		}
 		S7PLC s7PLC = null;
 		try {
 			System.out.println("连接涂胶 PLC: " + ip);
 			s7PLC = new S7PLC(EPlcType.S1200, ip);
-			boolean before = s7PLC.readBoolean(ADDR_QUALITY_PASS);
-			System.out.println("写前 " + ADDR_QUALITY_PASS + "=" + before);
-
 			s7PLC.writeBoolean(ADDR_QUALITY_PASS, value);
 			boolean after = s7PLC.readBoolean(ADDR_QUALITY_PASS);
-			System.out.println("写后 " + ADDR_QUALITY_PASS + "=" + after + "(期望 " + value + ")");
+			System.out.println("写后 " + ADDR_QUALITY_PASS + "=" + after);
 			return after == value;
 		} catch (Exception e) {
-			System.out.println("写 " + ADDR_QUALITY_PASS + " 异常: " + e.getMessage());
 			e.printStackTrace();
 			return false;
 		} finally {
@@ -213,132 +174,4 @@ public class ProductTjQualityCheckTest extends BaseSpringContextTests {
 			}
 		}
 	}
-
-	private static String resolveTjPlcIp() {
-		if (StringUtils.isNotBlank(TJ_PLC_IP)) {
-			return TJ_PLC_IP.trim();
-		}
-		String ip = Global.getConfig("mes.tj.plc.ip");
-		return StringUtils.isBlank(ip) ? DEFAULT_TJ_PLC_IP : ip.trim();
-	}
-
-	/**
-	 * 与 ProductTjBScheduling.doQualityCheck 相同:5 位工位号补 A,6 位及以上原样传入。
-	 */
-	QualityCheckResult checkQualityLikeTjBScheduling(String sn, String lineSn, String oprno) {
-		String checkOprno = oprno.length() == 5 ? oprno + "A" : oprno;
-		return invokeQualityCheck(checkOprno, sn, lineSn);
-	}
-
-	/**
-	 * 与 FswModbusScheduling.doQualityCheck 相同:读 mes.fsw.modbus.oprno,5 位工位号补 A。
-	 */
-	QualityCheckResult checkQualityLikeFswModbusScheduling(String sn, String lineSn, String oprno) {
-		if (StringUtils.isBlank(oprno)) {
-			return QualityCheckResult.error(null, "未配置 mes.fsw.modbus.oprno");
-		}
-		String checkOprno = oprno;
-		if (checkOprno.length() == 5) {
-			checkOprno = checkOprno + "A";
-		}
-		return invokeQualityCheck(checkOprno, sn, lineSn);
-	}
-
-	private QualityCheckResult invokeQualityCheck(String checkOprno, String sn, String lineSn) {
-		if (StringUtils.isBlank(lineSn)) {
-			return QualityCheckResult.fail(checkOprno, "产线编号为空");
-		}
-		try {
-			String ret = mesProductRecordController.checkQualityCommon(checkOprno, sn, lineSn, "");
-			if (StringUtils.isBlank(ret) || ret.length() < 5) {
-				return QualityCheckResult.fail(checkOprno, ret);
-			}
-			boolean pass = "UD".equals(ret.substring(3, 5));
-			return new QualityCheckResult(checkOprno, ret, pass);
-		} catch (Exception e) {
-			return QualityCheckResult.error(checkOprno, e.getMessage());
-		}
-	}
-
-	private String resolveTjBOprno() {
-		return resolveTjBOprnoStatic();
-	}
-
-	private static String resolveTjBOprnoStatic() {
-		if (StringUtils.isNotBlank(TJ_B_OPRNO)) {
-			return TJ_B_OPRNO.trim();
-		}
-		String oprno = Global.getConfig("mes.tj.b.oprno");
-		return StringUtils.isBlank(oprno) ? DEFAULT_TJ_B_OPRNO : oprno.trim();
-	}
-
-	private String resolveFswOprno() {
-		return resolveFswOprnoStatic();
-	}
-
-	private static String resolveFswOprnoStatic() {
-		if (StringUtils.isNotBlank(FSW_OPRNO)) {
-			return FSW_OPRNO.trim();
-		}
-		String oprno = Global.getConfig("mes.fsw.modbus.oprno");
-		return StringUtils.isBlank(oprno) ? null : oprno.trim();
-	}
-
-	private String resolveFswLineSn() {
-		return resolveFswLineSnStatic();
-	}
-
-	private static String resolveFswLineSnStatic() {
-		if (StringUtils.isNotBlank(FSW_LINE_SN)) {
-			return FSW_LINE_SN.trim();
-		}
-		String lineSn = Global.getConfig("mes.fsw.modbus.lineSn");
-		if (StringUtils.isNotBlank(lineSn)) {
-			return lineSn.trim();
-		}
-		return StringUtils.isBlank(TEST_LINE_SN) ? null : TEST_LINE_SN.trim();
-	}
-
-	private static void printResult(String taskName, String configuredOprno, QualityCheckResult result) {
-		printResult(taskName, configuredOprno, result, TEST_LINE_SN);
-	}
-
-	private static void printResult(String taskName, String configuredOprno, QualityCheckResult result, String lineSn) {
-		System.out.println("任务类     : " + taskName);
-		System.out.println("配置工位号 : " + configuredOprno);
-		System.out.println("校验工位号 : " + result.checkOprno);
-		System.out.println("工件码     : " + TEST_SN);
-		System.out.println("产线       : " + lineSn);
-		System.out.println("返回码     : " + result.ret);
-		System.out.println("是否通过   : " + (result.pass ? "是 (UD)" : "否"));
-		if (result.error != null) {
-			System.out.println("异常信息   : " + result.error);
-		}
-	}
-
-	private static final class QualityCheckResult {
-		private final String checkOprno;
-		private final String ret;
-		private final boolean pass;
-		private final String error;
-
-		private QualityCheckResult(String checkOprno, String ret, boolean pass) {
-			this(checkOprno, ret, pass, null);
-		}
-
-		private QualityCheckResult(String checkOprno, String ret, boolean pass, String error) {
-			this.checkOprno = checkOprno;
-			this.ret = ret;
-			this.pass = pass;
-			this.error = error;
-		}
-
-		private static QualityCheckResult fail(String checkOprno, String ret) {
-			return new QualityCheckResult(checkOprno, ret, false);
-		}
-
-		private static QualityCheckResult error(String checkOprno, String error) {
-			return new QualityCheckResult(checkOprno, null, false, error);
-		}
-	}
 }