暂停二次确认是否 等待小项检测完成功能补充

This commit is contained in:
caozehui
2026-07-20 08:48:41 +08:00
parent 36f621b17d
commit a8976a80cf
10 changed files with 230 additions and 22 deletions

View File

@@ -11,6 +11,7 @@ import com.njcn.gather.detection.lock.DetectionLock;
import com.njcn.gather.detection.lock.DetectionLockManager;
import com.njcn.gather.detection.lock.DetectionLockManager.AcquireResult;
import com.njcn.gather.detection.pojo.enums.DetectionResponseEnum;
import com.njcn.gather.detection.pojo.param.ClosePreTestParam;
import com.njcn.gather.detection.pojo.param.ContrastDetectionParam;
import com.njcn.gather.detection.pojo.param.FormalProgressParam;
import com.njcn.gather.detection.pojo.param.PreDetectionParam;
@@ -66,8 +67,7 @@ public class PreDetectionController extends BaseController {
boolean keepLock = false;
try {
// 重置 FormalTestManager 暂停计数残留,避免上次暂停残留计数误触发 R4
FormalTestManager.stopTime = 0;
FormalTestManager.hasStopFlag = false;
FormalTestManager.clearPauseState();
preDetectionService.sourceCommunicationCheck(param);
keepLock = true;
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, null, methodDescribe);
@@ -116,8 +116,7 @@ public class PreDetectionController extends BaseController {
// 同步阶段抛异常时回滚锁,理由同 startPreTest
boolean keepLock = false;
try {
FormalTestManager.stopTime = 0;
FormalTestManager.hasStopFlag = false;
FormalTestManager.clearPauseState();
preDetectionService.sendScript(param);
keepLock = true;
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, null, methodDescribe);
@@ -170,20 +169,30 @@ public class PreDetectionController extends BaseController {
/**
* 暂停检测
* 暂停检测,兼容旧前端:默认等待当前小项完成后暂停。
*/
@GetMapping("/closePreTest")
@OperateInfo
@ApiOperation("暂停检测")
@ApiImplicitParam(name = "param", value = "参数", required = true)
public HttpResult<?> temStopTest() {
return closePreTest(new ClosePreTestParam());
}
/**
* 暂停检测
*/
@PostMapping("/closePreTest")
@OperateInfo
@ApiOperation("暂停检测")
public HttpResult<?> closePreTest(@RequestBody(required = false) ClosePreTestParam param) {
String methodDescribe = getMethodDescribe("temStopTest");
HttpResult<DetectionLockHolderVO> busy = requireHolderSelf();
if (busy != null) {
return busy;
}
// 暂停保持锁spec §2.3),不释放
preDetectionService.temStopTest();
ClosePreTestParam request = param == null ? new ClosePreTestParam() : param;
preDetectionService.temStopTest(RequestUtil.getLoginNameByToken(), request.isWaitCurrentItem());
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, null, methodDescribe);
}
@@ -252,8 +261,7 @@ public class PreDetectionController extends BaseController {
// 同步阶段抛异常时回滚锁,理由同 startPreTest
boolean keepLock = false;
try {
FormalTestManager.stopTime = 0;
FormalTestManager.hasStopFlag = false;
FormalTestManager.clearPauseState();
preDetectionService.startContrastTest(param);
keepLock = true;
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, null, methodDescribe);

View File

@@ -1233,6 +1233,7 @@ public class SocketDevResponseService {
}
FormalTestManager.currentIssue = firstIssue;
FormalTestManager.resumeFormalStartTime = LocalDateTime.now();
sendFormalCurrentItem(param, firstIssue, type);
SocketMsg<String> socketMsg = new SocketMsg<>();
socketMsg.setOperateCode(SourceOperateCodeEnum.OPER_GATHER.getValue());
@@ -1244,6 +1245,23 @@ public class SocketDevResponseService {
WebServiceManager.sendMsg(param.getUserPageId(), JSON.toJSONString(webSocketVO));
}
private void sendFormalCurrentItem(PreDetectionParam param, SourceIssue issue, String displayType) {
if (issue == null) {
return;
}
FormalTestManager.currentIssue = issue;
String type = StrUtil.isNotBlank(displayType) ? displayType : issue.getType();
PowerIndexEnum powerIndexEnum = PowerIndexEnum.getByKey(type);
String typeName = powerIndexEnum == null ? type : powerIndexEnum.getDesc();
FormalCurrentItemVO currentItem = new FormalCurrentItemVO(
type,
typeName,
issue.getIndex(),
StrUtil.blankToDefault(issue.getDesc(), "当前检测小项")
);
WebServiceManager.sendDetectionMessage(param.getUserPageId(), "formal_current_item", "current", currentItem, null);
}
/**
* 添加并且按照slowValueTimeList中的时间去重
*
@@ -1292,6 +1310,11 @@ public class SocketDevResponseService {
DevData devData = JSON.parseObject(data, DevData.class); //DevData的id值为 设备id_通道号 这种形式
SourceResponseCodeEnum dictDataEnumByCode = SourceResponseCodeEnum.getDictDataEnumByCode(socketDataMsg.getCode());
SourceIssue sourceIssue = SocketManager.getSourceList().get(0);
if (FormalTestManager.isImmediatePause()) {
successComm.clear();
FormalTestManager.realDataXiList.clear();
return;
}
switch (Objects.requireNonNull(dictDataEnumByCode)) {
case SUCCESS:
@@ -1377,9 +1400,10 @@ public class SocketDevResponseService {
WebServiceManager.sendDetectionMessage(param.getUserPageId(), socketDataMsg.getRequestId().split(CnSocketUtil.STEP_TAG)[1] + CnSocketUtil.END_TAG, null, resultList, null);
}
//在这一步判断是否已经触发暂停按钮
if (FormalTestManager.stopFlag && CollUtil.isNotEmpty(SocketManager.getSourceList())) {
FormalTestManager.stopTime = 0;
FormalTestManager.hasStopFlag = true;
if (FormalTestManager.stopFlag
&& FormalTestManager.isWaitCurrentItemPause()
&& CollUtil.isNotEmpty(SocketManager.getSourceList())) {
FormalTestManager.markPausedAfterCurrentItem();
successComm.clear();
FormalTestManager.realDataXiList.clear();
sendWebSocket(param.getUserPageId(), "preStopTest", "stop", null);
@@ -1406,6 +1430,8 @@ public class SocketDevResponseService {
xuMsg.setOperateCode(SourceOperateCodeEnum.OPER_GATHER.getValue());
xuMsg.setData(JSON.toJSONString(sourceIssues));
xuMsg.setRequestId(SourceOperateCodeEnum.FORMAL_REAL.getValue() + CnSocketUtil.STEP_TAG + type);
FormalTestManager.currentIssue = sourceIssues;
sendFormalCurrentItem(param, sourceIssues, type);
SocketManager.sendMsg(param.getUserPageId() + CnSocketUtil.SOURCE_TAG, JSON.toJSONString(xuMsg));
} else {
//TODO 是否最终检测完成需要推送给用户
@@ -1799,9 +1825,7 @@ public class SocketDevResponseService {
SocketManager.clockMap.clear();
successComm.clear();
FormalTestManager.stopFlag = false;
FormalTestManager.hasStopFlag = false;
FormalTestManager.stopTime = 0;
FormalTestManager.clearPauseState();
//初始化相序集合
this.devInfo.clear();

View File

@@ -0,0 +1,13 @@
package com.njcn.gather.detection.pojo.param;
import lombok.Data;
@Data
public class ClosePreTestParam {
private Boolean waitCurrentItem;
public boolean isWaitCurrentItem() {
return !Boolean.FALSE.equals(waitCurrentItem);
}
}

View File

@@ -0,0 +1,20 @@
package com.njcn.gather.detection.pojo.vo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class FormalCurrentItemVO {
private String type;
private String typeName;
private Integer index;
private String desc;
}

View File

@@ -30,7 +30,7 @@ public interface PreDetectionService {
void coefficientCheck(PreDetectionParam param);
boolean temStopTest();
boolean temStopTest(String userPageId, boolean waitCurrentItem);
boolean restartTemTest(PreDetectionParam param);

View File

@@ -277,8 +277,20 @@ public class PreDetectionServiceImpl implements PreDetectionService {
}
@Override
public boolean temStopTest() {
FormalTestManager.stopFlag = true;
public boolean temStopTest(String userPageId, boolean waitCurrentItem) {
if (waitCurrentItem) {
FormalTestManager.requestWaitPause();
return true;
}
FormalTestManager.requestImmediatePause();
SocketManager.ensureFirst(FormalTestManager.currentIssue);
socketDevResponseService.initRestart();
PreDetectionParam runtimeParam = WebServiceManager.getPreDetectionParam(userPageId);
String pushUserPageId = runtimeParam != null && StrUtil.isNotBlank(runtimeParam.getUserPageId())
? runtimeParam.getUserPageId()
: userPageId;
WebServiceManager.sendDetectionMessage(pushUserPageId, "preStopTest", "stop", null, null);
return true;
}
@@ -291,7 +303,7 @@ public class PreDetectionServiceImpl implements PreDetectionService {
}
runtimeParam = param;
}
FormalTestManager.stopFlag = false;
FormalTestManager.clearPauseState();
socketDevResponseService.initRestart();
List<SourceIssue> sourceIssueList = SocketManager.getSourceList();
if (StrUtil.isBlank(runtimeParam.getSourceName()) && StrUtil.isNotBlank(runtimeParam.getSourceId())) {

View File

@@ -84,6 +84,14 @@ public class FormalTestManager {
*/
public static Integer stopTime = 0;
public enum PauseMode {
NONE,
WAIT_CURRENT_ITEM,
IMMEDIATE
}
public static PauseMode pauseMode = PauseMode.NONE;
/**
* 当前正在检测的计划
*/
@@ -233,11 +241,45 @@ public class FormalTestManager {
public static Integer longFlickerDataCount;
public static void requestWaitPause() {
stopFlag = true;
hasStopFlag = false;
stopTime = 0;
pauseMode = PauseMode.WAIT_CURRENT_ITEM;
}
public static void clearFormalRuntime() {
public static void requestImmediatePause() {
stopFlag = true;
hasStopFlag = true;
stopTime = 0;
pauseMode = PauseMode.IMMEDIATE;
}
public static void markPausedAfterCurrentItem() {
stopFlag = true;
hasStopFlag = true;
stopTime = 0;
pauseMode = PauseMode.WAIT_CURRENT_ITEM;
}
public static boolean isWaitCurrentItemPause() {
return pauseMode == PauseMode.WAIT_CURRENT_ITEM;
}
public static boolean isImmediatePause() {
return pauseMode == PauseMode.IMMEDIATE;
}
public static void clearPauseState() {
stopFlag = false;
hasStopFlag = false;
stopTime = 0;
pauseMode = PauseMode.NONE;
}
public static void clearFormalRuntime() {
clearPauseState();
resumeFormalPending = false;
resumeNextSort = null;
resumeBaseFormalCheckTime = null;

View File

@@ -326,6 +326,22 @@ public class SocketManager {
sourceIssueList.removeIf(s -> index.equals(s.getIndex()));
}
public static void ensureFirst(SourceIssue issue) {
if (issue == null || issue.getIndex() == null) {
return;
}
if (sourceIssueList.isEmpty()) {
sourceIssueList.add(0, issue);
return;
}
SourceIssue first = sourceIssueList.get(0);
if (issue.getIndex().equals(first.getIndex())) {
return;
}
sourceIssueList.removeIf(s -> issue.getIndex().equals(s.getIndex()));
sourceIssueList.add(0, issue);
}
public static void delSourceTarget(String sourceTag) {
targetMap.remove(sourceTag);
}

View File

@@ -273,8 +273,7 @@ public class NettyDevClientHandler extends SimpleChannelInboundHandler<String> {
DetectionLockManager.getInstance().releaseIfHeldBy(cur.getUserId(), "PAUSE_TIMEOUT");
}
// 重置 FormalTestManager 状态,避免下次进入误判
FormalTestManager.stopTime = 0;
FormalTestManager.hasStopFlag = false;
FormalTestManager.clearPauseState();
}
}

View File

@@ -0,0 +1,74 @@
package com.njcn.gather.detection.util.socket;
import com.njcn.gather.script.pojo.po.SourceIssue;
import org.junit.After;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
public class FormalTestManagerPauseTest {
@After
public void tearDown() {
FormalTestManager.clearFormalRuntime();
SocketManager.clearFormalRuntime();
}
@Test
public void requestWaitPause_keepsPauseDeferredUntilCurrentItemFinishes() {
FormalTestManager.requestWaitPause();
assertTrue(FormalTestManager.stopFlag);
assertFalse(FormalTestManager.hasStopFlag);
assertTrue(FormalTestManager.isWaitCurrentItemPause());
assertFalse(FormalTestManager.isImmediatePause());
}
@Test
public void requestImmediatePause_entersPausedStateImmediately() {
FormalTestManager.requestImmediatePause();
assertTrue(FormalTestManager.stopFlag);
assertTrue(FormalTestManager.hasStopFlag);
assertFalse(FormalTestManager.isWaitCurrentItemPause());
assertTrue(FormalTestManager.isImmediatePause());
assertEquals(Integer.valueOf(0), FormalTestManager.stopTime);
}
@Test
public void ensureFirst_keepsCurrentIssueAtQueueHead() {
SourceIssue first = issue(1, "V");
SourceIssue second = issue(2, "I");
SocketManager.addSourceList(new ArrayList<>(Arrays.asList(second)));
SocketManager.ensureFirst(first);
assertSame(first, SocketManager.getSourceList().get(0));
assertSame(second, SocketManager.getSourceList().get(1));
}
@Test
public void ensureFirst_doesNotDuplicateExistingHead() {
SourceIssue first = issue(1, "V");
SocketManager.addSourceList(new ArrayList<>(Arrays.asList(first)));
SocketManager.ensureFirst(first);
assertEquals(1, SocketManager.getSourceList().size());
assertSame(first, SocketManager.getSourceList().get(0));
}
private SourceIssue issue(Integer index, String type) {
SourceIssue issue = new SourceIssue();
issue.setIndex(index);
issue.setType(type);
issue.setDesc(type + " item");
return issue;
}
}