You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

415 lines
16 KiB

package com.dreamworks.boditech.service;
import com.dreamworks.boditech.driver.task.Task;
import com.dreamworks.boditech.driver.task.TaskTestEmergency;
import com.dreamworks.boditech.driver.task.TaskTestRegular;
import com.dreamworks.boditech.driver.task.TaskTestTubeRackPrepare;
import com.dreamworks.boditech.entity.*;
import com.dreamworks.boditech.entity.parameter.*;
import com.dreamworks.boditech.mapper.*;
import com.dreamworks.boditech.utils.AppError;
import com.dreamworks.boditech.utils.AppRuntimeException;
import com.dreamworks.boditech.utils.MyCommon;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Objects;
@Service
public class TestService {
@Resource
private TestMapper testMapper;
@Resource
private TestStepMapper testStepMapper;
@Resource
private TestTubeRackTestTaskMapper testTubeRackTestTaskMapper;
@Resource
private TestTubeRackTestTaskTubeMapper testTubeRackTestTaskTubeMapper;
@Resource
private EmergencyTestTaskMapper emergencyTestTaskMapper;
@Resource
@Lazy
private AccountService accountService;
@Resource
private ActionLogService actionLog;
@Resource
@Lazy
private DeviceService deviceService;
// batch id
private Long batchId = null;
@PostConstruct
public void init() {
this.batchId = System.currentTimeMillis();
}
// fetch task from database
public List<Task> fetchTask() {
// find emergency task first
MdbEmergencyTestTask test = this.emergencyTestTaskMapper.findExecutableTask();
if ( null != test ) {
List<Integer> projectIds = (List<Integer>)MyCommon.jsonToObject(test.projectIds, List.class);
if (Objects.equals(test.projectDetectType, MdbEmergencyTestTask.PROJECT_DETECT_TYPE_AUTO)) {
// @TODO : 这里需要从 LIS 获取项目信息之类的数据了, 这里先模拟个hsCRP
projectIds = List.of(1);
test.sampleType = "WB";
}
if ( projectIds.isEmpty() ) {
throw new AppRuntimeException(AppError.TEST_NO_PROJECT_ASSIGNED);
}
List<Task> tasks = new ArrayList<>();
for (Integer projectId : projectIds) {
TaskTestEmergency task = new TaskTestEmergency();
task.setMdbEmergencyTestTask(test);
task.setProjectId(projectId);
tasks.add(task);
}
return tasks;
}
// find test tube rack task
MdbTestTubeRackTestTask rack = this.testTubeRackTestTaskMapper.findExecutableTask();
if ( null != rack ) {
List<Task> tasks = new ArrayList<>();
TaskTestTubeRackPrepare prepare = new TaskTestTubeRackPrepare();
prepare.setTestService(this);
prepare.setMdbTestTubeRackTestTask(rack);
tasks.add(prepare);
return tasks;
}
return new ArrayList<>();
}
// test tube rack task save
public MdbTestTubeRackTestTask testTubeRackTaskSave(ParamTestTubeRackTaskSave param) {
if ( null == param.id ) {
return this.testTubeRackTaskSaveInsert(param);
} else {
return this.testTubeRackTaskSaveUpdate(param);
}
}
// test tube rack task save insert
private MdbTestTubeRackTestTask testTubeRackTaskSaveInsert (ParamTestTubeRackTaskSave param) {
this.actionLog.log("test-tube-rack-task.insert", param.tubeType);
MdbTestTubeRackTestTask task = new MdbTestTubeRackTestTask();
task.status = "CONFIGURING";
task.editable = true;
task.createdAt = System.currentTimeMillis();
task.createdBy = this.accountService.getCurrentAccountId();
task.tubeTypeDetectType = param.tubeTypeDetectType;
task.tubeType = param.tubeType;
this.testTubeRackTestTaskMapper.insert(task);
this.testTubeRackTaskSaveUpdateTubes(task, param);
return task;
}
// test tube rack task save update
private MdbTestTubeRackTestTask testTubeRackTaskSaveUpdate (ParamTestTubeRackTaskSave param) {
this.actionLog.log("test-tube-rack-task.update", param.tubeType);
MdbTestTubeRackTestTask task = this.testTubeRackTestTaskMapper.findById(param.id);
if ( null == task ) {
throw new RuntimeException("TEST_TUBE_RACK_TASK_NOT_FOUND");
}
if ( !task.editable ) {
throw new RuntimeException("TEST_TUBE_RACK_TASK_NOT_EDITABLE");
}
task.tubeTypeDetectType = param.tubeTypeDetectType;
task.tubeType = param.tubeType;
task.updatedAt = System.currentTimeMillis();
task.updatedBy = this.accountService.getCurrentAccountId();
this.testTubeRackTestTaskMapper.update(task);
this.testTubeRackTaskSaveUpdateTubes(task, param);
return task;
}
// test tube rack task save update tubes
private void testTubeRackTaskSaveUpdateTubes(MdbTestTubeRackTestTask task, ParamTestTubeRackTaskSave param) {
this.testTubeRackTestTaskTubeMapper.deleteAllByRackId(task.id);
for (ParamTestTubeRackTaskSaveTube tube : param.tubes) {
MdbTestTubeRackTestTaskTube item = new MdbTestTubeRackTestTaskTube();
item.rackId = task.id;
item.index = tube.index;
item.projectDetectType = tube.projectDetectType;
item.sampleTypeDetectType = tube.sampleTypeDetectType;
item.sampleType = tube.sampleType;
item.sampleUid = tube.sampleUid;
item.barCode = tube.barCode;
item.attenuation = tube.attenuation;
item.projectIds = MyCommon.objectToJson(tube.projectIds);
item.status = MdbTestTubeRackTestTaskTube.STATUS_NEW;
this.testTubeRackTestTaskTubeMapper.insert(item);
}
}
// test tube rack task tube list
public List<MdbTestTubeRackTestTaskTube> testTubeRackTaskTubeListByRackId(Integer rackId) {
return this.testTubeRackTestTaskTubeMapper.findAllByRackId(rackId);
}
// test tube rack task delete
public void testTubeRackTaskDeleteById(Integer id) {
this.actionLog.log("test-tube-rack-task.delete", id);
this.testTubeRackTestTaskMapper.deleteById(id);
this.testTubeRackTestTaskTubeMapper.deleteAllByRackId(id);
}
// test tube rack task lock
public void testTubeRackTestLock(Integer id) {
if ( !this.deviceService.isExecutorRunning() ) {
throw new AppRuntimeException(AppError.DEVICE_EXECUTING_REQUIRED);
}
this.actionLog.log("test-tube-rack-task.lock", id);
MdbTestTubeRackTestTask task = this.testTubeRackTestTaskMapper.findById(id);
if ( null == task ) {
throw new RuntimeException("TEST_TUBE_RACK_TASK_NOT_FOUND");
}
if ( !task.editable ) {
throw new RuntimeException("TEST_TUBE_RACK_TASK_NOT_EDITABLE");
}
task.editable = false;
task.status = "WAITING";
task.updatedAt = System.currentTimeMillis();
task.updatedBy = this.accountService.getCurrentAccountId();
this.testTubeRackTestTaskMapper.updateLock(task);
this.deviceService.getTaskExecutor().newTaskNotify();
}
// test tube rack task unlock
public void testTubeRackTestUnlock(Integer id) {
this.actionLog.log("test-tube-rack-task.unlock", id);
MdbTestTubeRackTestTask task = this.testTubeRackTestTaskMapper.findById(id);
if ( null == task ) {
throw new RuntimeException("TEST_TUBE_RACK_TASK_NOT_FOUND");
}
if ( task.editable ) {
throw new RuntimeException("TEST_TUBE_RACK_TASK_NOT_LOCKED");
}
task.editable = true;
task.status = "CONFIGURING";
task.updatedAt = System.currentTimeMillis();
task.updatedBy = this.accountService.getCurrentAccountId();
this.testTubeRackTestTaskMapper.updateLock(task);
}
// emergency task save
public void emergencyTaskSave(ParamEmergencyTaskSave param) {
MdbEmergencyTestTask task = new MdbEmergencyTestTask();
task.index = param.index;
task.enable = param.enable;
task.isSlotLocked = true;
task.projectDetectType = param.projectDetectType;
task.sampleTypeDetectType = param.sampleTypeDetectType;
task.sampleType = param.sampleType;
task.sampleUid = param.sampleUid;
task.barCode = param.barCode;
task.attenuation = param.attenuation;
task.updatedAt = System.currentTimeMillis();
task.updatedBy = this.accountService.getCurrentAccountId();
task.projectIds = MyCommon.objectToJson(param.projectIds);
task.status = "WAITING";
task.createdAt = System.currentTimeMillis();
task.createdBy = this.accountService.getCurrentAccountId();
this.emergencyTestTaskMapper.insert(task);
this.deviceService.getTaskExecutor().newTaskNotify();
}
// emergency task status get
public MdbEmergencyTestTask activeEmergencyTaskGetBySlot(Integer slotIndex) {
return this.emergencyTestTaskMapper.activeEmergencyTaskGetBySlot(slotIndex);
}
// emergency task start
public void emergencyTaskStart( MdbEmergencyTestTask task ) {
task.status = MdbEmergencyTestTask.STATUS_EXECUTING;
task.execStartedAt = System.currentTimeMillis();
this.emergencyTestTaskMapper.executeStart(task);
}
// emergency task end
public void emergencyTaskEnd( MdbEmergencyTestTask task ) {
Integer finishCount = this.testMapper.countFinishedTestsByTaskId(task.id, "emergency");
if ( finishCount < task.getProjectIdList().size() ) {
return ;
}
task.status = MdbEmergencyTestTask.STATUS_FINISHED;
task.execFinishedAt = System.currentTimeMillis();
this.emergencyTestTaskMapper.executeEnd(task);
}
// emergency task cancel
public void emergencyTaskCancel( MdbEmergencyTestTask task ) {
task.status = MdbEmergencyTestTask.STATUS_CANCELED;
task.execFinishedAt = System.currentTimeMillis();
this.emergencyTestTaskMapper.executeCancel(task);
}
// test tube rack task current get
public MdbTestTubeRackTestTask testTubeRackTaskCurrentGet() {
return this.testTubeRackTestTaskMapper.findCurrentTask();
}
// update test tube rack task
public void regularTaskUpdate( MdbTestTubeRackTestTask task ) {
this.testTubeRackTestTaskMapper.update(task);
}
// test tube rack task list
public List<MdbTestTubeRackTestTask> regularTaskEditableList() {
return this.testTubeRackTestTaskMapper.findAllEditableTasks();
}
// regular task start
public void regularTaskStart( MdbTestTubeRackTestTask task ) {
task.status = MdbTestTubeRackTestTask.STATUS_EXECUTING;
task.execStartedAt = System.currentTimeMillis();
this.testTubeRackTestTaskMapper.testStart(task);
}
// regular task tube update
public void regularTaskTubeUpdate( MdbTestTubeRackTestTaskTube tube ) {
this.testTubeRackTestTaskTubeMapper.update(tube);
}
// test tube rack task tube status update
public void regularTaskTubeStatusUpdate( MdbTestTubeRackTestTaskTube tube ) {
this.testTubeRackTestTaskTubeMapper.statusUpdate(tube);
}
// regular task tube start
public void regularTaskTubeStart( MdbTestTubeRackTestTask task, MdbTestTubeRackTestTaskTube tube ) {
tube.status = MdbTestTubeRackTestTaskTube.STATUS_EXECUTING;
tube.execStartedAt = System.currentTimeMillis();
this.testTubeRackTestTaskTubeMapper.testStart(tube);
}
// emergency task end
public void regularTaskTubeEnd( MdbTestTubeRackTestTask task, MdbTestTubeRackTestTaskTube tube ) {
tube.status = MdbTestTubeRackTestTaskTube.STATUS_FINISHED;
tube.execFinishedAt = System.currentTimeMillis();
this.testTubeRackTestTaskTubeMapper.testEnd(tube);
Integer finishedCount = this.testTubeRackTestTaskTubeMapper.countByRackIdAndStatus(task.id, MdbTestTubeRackTestTaskTube.STATUS_FINISHED);
Integer ignoredCount = this.testTubeRackTestTaskTubeMapper.countByRackIdAndStatus(task.id, MdbTestTubeRackTestTaskTube.STATUS_IGNORED);
Integer totalCount = this.testTubeRackTestTaskTubeMapper.countByRackId(task.id);
if ( finishedCount + ignoredCount >= totalCount ) {
task.status = MdbTestTubeRackTestTask.STATUS_FINISHED;
task.execFinishedAt = System.currentTimeMillis();
this.testTubeRackTestTaskMapper.testFinish(task);
}
}
// emergency task cancel
public void regularTaskCancel( MdbTestTubeRackTestTask task ) {
task.status = MdbTestTubeRackTestTask.STATUS_CANCELED;
task.execFinishedAt = System.currentTimeMillis();
this.testTubeRackTestTaskMapper.testCancel(task);
}
// test update
public void testUpdate( MdbTest test ) {
this.testMapper.update(test);
}
// test end
public void testEnd(MdbTest test) {
test.status = "FINISHED";
this.testMapper.statusUpdate(test);
}
// test cancel
public void testCancel(MdbTest test) {
test.status = "CANCELED";
this.testMapper.statusUpdate(test);
}
// test search
public List<MdbTest> testSearch (ParamTestSearch param) {
return this.testMapper.search(param);
}
// test count
public Integer testCount( ParamTestSearch param ) {
return this.testMapper.count(param);
}
// test list
public List<MdbTest> testActiveBatchList() {
return this.testMapper.activeBatchList(this.batchId);
}
public void testBatchDeleteById(ParamBatchDeleteById param) {
this.actionLog.log("test.batch-delete");
this.testMapper.batchDeleteById(param.idList);
}
// create test
public void insert(MdbTest test) {
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
Long startTime = calendar.getTimeInMillis();
int count = this.testMapper.countByTimeRange(startTime, System.currentTimeMillis());
test.serialCode = String.format("%s_%03d", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyMMdd")), count + 1);
test.batchId = this.batchId;
test.startedBy = this.accountService.getCurrentAccountId();
test.startedAt = System.currentTimeMillis();
this.testMapper.insert(test);
}
// update test
public void statusUpdate(MdbTest test) {
this.testMapper.statusUpdate(test);
}
// update test
public void resultUpdate(MdbTest test) {
this.testMapper.resultUpdate(test);
}
// log step start
public void logStepStart(MdbTest test, TestStepLogEntry entry ) {
entry.testId = test.id;
entry.startedAt = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
this.testStepMapper.insert(entry);
}
// log step end
public void logStepEnd(TestStepLogEntry entry) {
entry.finishedAt = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
this.testStepMapper.update(entry);
}
// cancel all tasks
public void cancelAllTasks() {
this.testTubeRackTestTaskMapper.cancelAllTasks();
this.testTubeRackTestTaskTubeMapper.cancelAllTasks();
this.emergencyTestTaskMapper.cancelAllTasks();
this.testMapper.cancelAllTasks();
}
}