37 changed files with 888 additions and 116 deletions
-
17src/main/java/a8k/appbase/A8kTubeType.java
-
21src/main/java/a8k/appbase/ProjectInfoSimple.java
-
38src/main/java/a8k/db/DBTableVersion.java
-
19src/main/java/a8k/db/ProjectColor.java
-
209src/main/java/a8k/db/ProjectInfo.java
-
4src/main/java/a8k/service/AddSampleService.java
-
92src/main/java/a8k/service/ProjectColorAllocer.java
-
4src/main/java/a8k/service/UIEventProcesser.java
-
1src/main/java/a8k/service/appeventbus/appevent/A8kCanBusOnConnectEvent.java
-
8src/main/java/a8k/service/appeventbus/appevent/A8kHardwareReport.java
-
8src/main/java/a8k/service/appeventbus/appevent/A8kStateChangeEvent.java
-
6src/main/java/a8k/service/appeventbus/appevent/AppEvent.java
-
2src/main/java/a8k/service/appeventbus/appevent/AppStepNotifyEvent.java
-
1src/main/java/a8k/service/appeventbus/appevent/AppWarningNotifyEvent.java
-
34src/main/java/a8k/service/base/A8kDeviceState.java
-
6src/main/java/a8k/service/base/BloodType.java
-
10src/main/java/a8k/service/base/consumable/ConsumableItemGroup.java
-
16src/main/java/a8k/service/base/consumable/ReactantItem.java
-
5src/main/java/a8k/service/base/consumable/TipGroupInfo.java
-
12src/main/java/a8k/service/base/plate/PlateState.java
-
23src/main/java/a8k/service/base/plate/ReactingPlateState.java
-
13src/main/java/a8k/service/base/reaction_result/ReactionResult.java
-
7src/main/java/a8k/service/base/sample/EmergencyPosState.java
-
6src/main/java/a8k/service/base/sample/EmergencySampleInfo.java
-
18src/main/java/a8k/service/base/sample/SampleInfo.java
-
8src/main/java/a8k/service/base/sample/Tube.java
-
12src/main/java/a8k/service/base/sample/TubeHolder.java
-
7src/main/java/a8k/service/base/sample/TubeHolderState.java
-
18src/main/java/a8k/service/base/sample/TubeState.java
-
8src/main/java/a8k/service/base/samplecfg/SampleTubeCfg.java
-
9src/main/java/a8k/service/base/samplecfg/SampleTubeHolderCfg.java
-
78src/main/java/a8k/service/ctrl_service/AppCtrlService.java
-
11src/main/java/a8k/service/hardware/SamplesPreProcessModuleCtrlService.java
-
76src/main/java/a8k/service/project_mgr/ProjectItemMgrService.java
-
182src/main/java/a8k/service/state_service/A8kStateMgrService.java
-
7src/main/resources/db/migration/V100_5__create_table_DBVersion.sql
-
8src/main/resources/db/migration/V100_6__create_table_ProjectColorTable.sql
@ -0,0 +1,21 @@ |
|||||
|
package a8k.appbase; |
||||
|
|
||||
|
import a8k.db.ProjectInfo; |
||||
|
|
||||
|
public class ProjectInfoSimple { |
||||
|
String projectName; //项目名称 |
||||
|
String lotName; //批次名称 |
||||
|
String expiryDate; //有效日期 |
||||
|
|
||||
|
public ProjectInfoSimple(String projectName, String lotName, String expiryDate) { |
||||
|
this.projectName = projectName; |
||||
|
this.lotName = lotName; |
||||
|
this.expiryDate = expiryDate; |
||||
|
} |
||||
|
|
||||
|
public ProjectInfoSimple(ProjectInfo pinfo) { |
||||
|
this.projectName = pinfo.projectName; |
||||
|
this.lotName = pinfo.lotName; |
||||
|
this.expiryDate = pinfo.expiryDate; |
||||
|
} |
||||
|
} |
@ -0,0 +1,38 @@ |
|||||
|
package a8k.db; |
||||
|
|
||||
|
import com.iflytop.uf.UfActiveRecord; |
||||
|
import com.iflytop.uf.UfActiveRecordField; |
||||
|
|
||||
|
import java.util.Map; |
||||
|
|
||||
|
public class DBTableVersion extends UfActiveRecord { |
||||
|
@UfActiveRecordField |
||||
|
public String tableName; |
||||
|
@UfActiveRecordField |
||||
|
public Integer version; |
||||
|
|
||||
|
public static String getTableName() { |
||||
|
return DBTableVersion.class.getSimpleName() + "Table"; |
||||
|
} |
||||
|
|
||||
|
public static void setTableVersion(String tableName, Integer version) { |
||||
|
var dbDataVersion = UfActiveRecord.findOne(DBTableVersion.class, Map.of("tableName", tableName)); |
||||
|
if (null == dbDataVersion) { |
||||
|
dbDataVersion = new DBTableVersion(); |
||||
|
dbDataVersion.tableName = tableName; |
||||
|
dbDataVersion.version = version; |
||||
|
dbDataVersion.save(); |
||||
|
} else { |
||||
|
dbDataVersion.version = version; |
||||
|
dbDataVersion.save(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public static Integer getTableVersion(String tableName) { |
||||
|
var dbDataVersion = UfActiveRecord.findOne(DBTableVersion.class, Map.of("tableName", tableName)); |
||||
|
if (null == dbDataVersion) { |
||||
|
return 0; |
||||
|
} |
||||
|
return dbDataVersion.version; |
||||
|
} |
||||
|
} |
@ -0,0 +1,19 @@ |
|||||
|
package a8k.db; |
||||
|
|
||||
|
import com.iflytop.uf.UfActiveRecord; |
||||
|
import com.iflytop.uf.UfActiveRecordField; |
||||
|
|
||||
|
public class ProjectColor extends UfActiveRecord { |
||||
|
|
||||
|
@UfActiveRecordField |
||||
|
public String color; |
||||
|
@UfActiveRecordField |
||||
|
public String projectId; |
||||
|
@UfActiveRecordField |
||||
|
public Integer index; |
||||
|
|
||||
|
public static String getTableName() { |
||||
|
return "ProjectColorTable"; |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,209 @@ |
|||||
|
package a8k.db; |
||||
|
|
||||
|
import com.iflytop.uf.UfActiveRecord; |
||||
|
import com.iflytop.uf.UfActiveRecordField; |
||||
|
|
||||
|
//ref:https://iflytop1.feishu.cn/wiki/HvDlwbEWDi4fgkkL6qSc2iLGnte |
||||
|
public class ProjectInfo extends UfActiveRecord { |
||||
|
|
||||
|
public static String getTableName() { |
||||
|
return "ProjectInfoTable"; |
||||
|
} |
||||
|
|
||||
|
@UfActiveRecordField |
||||
|
public Integer buildIn;//是否是内置,如果是内置则不显示,作为项目的默认值使用 |
||||
|
|
||||
|
@UfActiveRecordField |
||||
|
public String insertTime; //插入时间 |
||||
|
|
||||
|
@UfActiveRecordField |
||||
|
public String projectName; //项目名称 |
||||
|
@UfActiveRecordField |
||||
|
public String lotName; //批次名称 |
||||
|
@UfActiveRecordField |
||||
|
public String expiryDate; //有效日期 |
||||
|
@UfActiveRecordField |
||||
|
public String projectCode; //项目名称代码 |
||||
|
@UfActiveRecordField |
||||
|
public Integer palteCode; // 板条条码代码 |
||||
|
@UfActiveRecordField |
||||
|
public Integer updateChipVersion; // 更新芯片版本号 |
||||
|
@UfActiveRecordField |
||||
|
public Double QCPeakMinVal; // 质控峰最小值 |
||||
|
@UfActiveRecordField |
||||
|
public Double QCPeakMaxVal; // 质控峰最大值 设置值x10最大不超过250000 |
||||
|
@UfActiveRecordField |
||||
|
public Integer optType; //光学类型 光学类型(0=自动;1=F光学;2=T光学;3=F/T光学;其他=无效;) |
||||
|
@UfActiveRecordField |
||||
|
public Integer optFixedGainSetting; //光学固定增益设置 |
||||
|
@UfActiveRecordField |
||||
|
public Integer optAreaPeakCount; //光学面积峰个数 |
||||
|
@UfActiveRecordField |
||||
|
public Integer calculationDirection; //计算方向 |
||||
|
@UfActiveRecordField |
||||
|
public Integer sampleType; //样本类型 |
||||
|
@UfActiveRecordField |
||||
|
public Integer equipmentManufacturer; //设备厂商 |
||||
|
@UfActiveRecordField |
||||
|
public Integer tOptIlluminationTime; //T光学持续光照时间 |
||||
|
@UfActiveRecordField |
||||
|
public Integer incMultiInstruDataMerge; //是否包含多款仪器数据合并 |
||||
|
@UfActiveRecordField |
||||
|
public Integer multiInstruDataMerge; //多款仪器数据合并 |
||||
|
@UfActiveRecordField |
||||
|
public Integer wBloodSampleVol; //全血样本量 |
||||
|
@UfActiveRecordField |
||||
|
public Integer serumSampleVol; //血清/血浆样本量 |
||||
|
@UfActiveRecordField |
||||
|
public Integer tubeMixingCount; //试管混匀次数 |
||||
|
@UfActiveRecordField |
||||
|
public Integer bufferBottleSize; //缓冲液瓶大小 |
||||
|
@UfActiveRecordField |
||||
|
public Integer bufferBottleCapacity; //缓冲液瓶容量 |
||||
|
@UfActiveRecordField |
||||
|
public Integer buffLiquidAspirMixingCnt; //缓冲液吸吐混匀次数 |
||||
|
@UfActiveRecordField |
||||
|
public Integer buffLiquidAspirMixingVol; //缓冲液吐混混匀量 |
||||
|
@UfActiveRecordField |
||||
|
public Integer buffLiquidReactionTime; //缓冲液反应时间 |
||||
|
@UfActiveRecordField |
||||
|
public Integer reactionPlateReactionTime; //反应板反应时间 |
||||
|
@UfActiveRecordField |
||||
|
public Integer reactionPlateDropletVol; //反应板滴样量 |
||||
|
@UfActiveRecordField |
||||
|
public Integer resultDecimalPlaces; //结果小数点位数 |
||||
|
@UfActiveRecordField |
||||
|
public Integer scanningRange; //扫描范围 |
||||
|
|
||||
|
//当前项目是几联卡项目 |
||||
|
//项目1 结果曲线是否为分段函数 |
||||
|
//项目2 结果曲线是否为分段函数 |
||||
|
//项目3 结果曲线是否为分段函数 |
||||
|
|
||||
|
@UfActiveRecordField |
||||
|
public Integer projectNum; //当前项目是几联卡项目 |
||||
|
@UfActiveRecordField |
||||
|
public Integer project1CurveType; //项目1 结果曲线是否为分段函数 |
||||
|
@UfActiveRecordField |
||||
|
public Integer project2CurveType; //项目2 结果曲线是否为分段函数 |
||||
|
@UfActiveRecordField |
||||
|
public Integer project3CurveType; //项目3 结果曲线是否为分段函数 |
||||
|
|
||||
|
//非分段函数 |
||||
|
@UfActiveRecordField |
||||
|
public Integer p0FnX; //函数未知数是 |
||||
|
@UfActiveRecordField |
||||
|
public Double p0FnXMin; //函数未知数下限闻值 |
||||
|
@UfActiveRecordField |
||||
|
public Double p0FnXMax; //函数未知数上限闻值 |
||||
|
@UfActiveRecordField |
||||
|
public Double p0FnSerumA; //A |
||||
|
@UfActiveRecordField |
||||
|
public Double p0FnSerumB; //B |
||||
|
@UfActiveRecordField |
||||
|
public Double p0FnSerumC; //C |
||||
|
@UfActiveRecordField |
||||
|
public Double p0FnSerumD; //D |
||||
|
@UfActiveRecordField |
||||
|
public Double p0FnRtSerumUpLimit; //结果上限 |
||||
|
@UfActiveRecordField |
||||
|
public Double p0FnRtSerumLowLimit; //结果下限 |
||||
|
|
||||
|
@UfActiveRecordField |
||||
|
public Double p0FnBloodA; //A |
||||
|
@UfActiveRecordField |
||||
|
public Double p0FnBloodB; //B |
||||
|
@UfActiveRecordField |
||||
|
public Double p0FnBloodC; //C |
||||
|
@UfActiveRecordField |
||||
|
public Double p0FnBloodD; //D |
||||
|
@UfActiveRecordField |
||||
|
public Double p0FnRtBloodUpLimit; //结果上限 |
||||
|
@UfActiveRecordField |
||||
|
public Double p0FnRtBloodLowLimit; //结果下限 |
||||
|
|
||||
|
//分段函数 |
||||
|
@UfActiveRecordField |
||||
|
public Integer p0PwFnJudeX; //分界判断数据来源 |
||||
|
@UfActiveRecordField |
||||
|
public Double p0PwFnJudeThres; //分界判断数据值 |
||||
|
@UfActiveRecordField |
||||
|
public Double p0PwFnLCX; //低浓度未知数 |
||||
|
@UfActiveRecordField |
||||
|
public Double p0PwFnHCX; //高浓度未知数 |
||||
|
@UfActiveRecordField |
||||
|
public Double p0PwFnXMin; //函数未知数下限闻值 |
||||
|
@UfActiveRecordField |
||||
|
public Double p0PwFnXMax; //函数未知数上限闻值 |
||||
|
|
||||
|
@UfActiveRecordField |
||||
|
public Double p0PwFnLCSerumA; //A |
||||
|
@UfActiveRecordField |
||||
|
public Double p0PwFnLCSerumB; //B |
||||
|
@UfActiveRecordField |
||||
|
public Double p0PwFnLCSerumC; //C |
||||
|
@UfActiveRecordField |
||||
|
public Double p0PwFnLCSerumD; //D |
||||
|
@UfActiveRecordField |
||||
|
public Double p0PwFnLCRtSerumUpLimit; //结果上限 |
||||
|
@UfActiveRecordField |
||||
|
public Double p0PwFnLCRtSerumLowLimit; //结果下限 |
||||
|
|
||||
|
@UfActiveRecordField |
||||
|
public Double p0PwFnHCSerumA; //A |
||||
|
@UfActiveRecordField |
||||
|
public Double p0PwFnHCSerumB; //B |
||||
|
@UfActiveRecordField |
||||
|
public Double p0PwFnHCSerumC; //C |
||||
|
@UfActiveRecordField |
||||
|
public Double p0PwFnHCSerumD; //D |
||||
|
@UfActiveRecordField |
||||
|
public Double p0PwFnHCRtSerumUpLimit; //结果上限 |
||||
|
@UfActiveRecordField |
||||
|
public Double p0PwFnHCRtSerumLowLimit; //结果下限 |
||||
|
|
||||
|
@UfActiveRecordField |
||||
|
public Double p0PwFnLCBloodA; //A |
||||
|
@UfActiveRecordField |
||||
|
public Double p0PwFnLCBloodB; //B |
||||
|
@UfActiveRecordField |
||||
|
public Double p0PwFnLCBloodC; //C |
||||
|
@UfActiveRecordField |
||||
|
public Double p0PwFnLCBloodD; //D |
||||
|
@UfActiveRecordField |
||||
|
public Double p0PwFnLCRtBloodUpLimit; //结果上限 |
||||
|
@UfActiveRecordField |
||||
|
public Double p0PwFnLCRtBloodLowLimit; //结果下限 |
||||
|
|
||||
|
@UfActiveRecordField |
||||
|
public Double p0PwFnHCBloodA; //A |
||||
|
@UfActiveRecordField |
||||
|
public Double p0PwFnHCBloodB; //B |
||||
|
@UfActiveRecordField |
||||
|
public Double p0PwFnHCBloodC; //C |
||||
|
@UfActiveRecordField |
||||
|
public Double p0PwFnHCBloodD; //D |
||||
|
@UfActiveRecordField |
||||
|
public Double p0PwFnHCRtBloodUpLimit; //结果上限 |
||||
|
@UfActiveRecordField |
||||
|
public Double p0PwFnHCRtBloodLowLimit; //结果下限 |
||||
|
|
||||
|
//结果 |
||||
|
@UfActiveRecordField |
||||
|
public Integer ret1Unit; //单位 |
||||
|
@UfActiveRecordField |
||||
|
public Integer ret2Unit; //单位 |
||||
|
@UfActiveRecordField |
||||
|
public Integer ret3Unit; //单位 |
||||
|
|
||||
|
@UfActiveRecordField |
||||
|
public Double ret2UnitFnA; // |
||||
|
@UfActiveRecordField |
||||
|
public Double ret2UnitFnB; // |
||||
|
|
||||
|
@UfActiveRecordField |
||||
|
public Double ret3UnitFnA; // |
||||
|
@UfActiveRecordField |
||||
|
public Double ret3UnitFnB; // |
||||
|
|
||||
|
} |
@ -0,0 +1,4 @@ |
|||||
|
package a8k.service; |
||||
|
|
||||
|
public class AddSampleService { |
||||
|
} |
@ -0,0 +1,92 @@ |
|||||
|
package a8k.service; |
||||
|
|
||||
|
import a8k.db.DBTableVersion; |
||||
|
import a8k.db.ProjectColor; |
||||
|
import com.iflytop.uf.UfActiveRecord; |
||||
|
import jakarta.annotation.PostConstruct; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
|
||||
|
import java.util.List; |
||||
|
import java.util.Map; |
||||
|
|
||||
|
@Component |
||||
|
public class ProjectColorAllocer { |
||||
|
final String[] colors = { |
||||
|
"#ff8283", |
||||
|
"#ffff81", |
||||
|
"#86ff86", |
||||
|
"#ffc491", |
||||
|
"#87f4ff", |
||||
|
"#9191ff", |
||||
|
}; |
||||
|
static final Integer dbVersion = 1; |
||||
|
Integer colorIndexMax = 0; |
||||
|
|
||||
|
ProjectColor dbGetProjectColor(String projId) { |
||||
|
return UfActiveRecord.findOne(ProjectColor.class, Map.of("projectId", projId)); |
||||
|
} |
||||
|
|
||||
|
List<ProjectColor> dbGetProjectColors() { |
||||
|
return UfActiveRecord.find(ProjectColor.class); |
||||
|
} |
||||
|
|
||||
|
void dbEmptyProjectColors() { |
||||
|
var list = dbGetProjectColors(); |
||||
|
for (var projColor : list) { |
||||
|
projColor.delete(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@PostConstruct |
||||
|
void init() { |
||||
|
//初始化项目颜色 |
||||
|
Integer var = DBTableVersion.getTableVersion(ProjectColor.getTableName()); |
||||
|
if (!dbVersion.equals(var)) { |
||||
|
initdbdata(); |
||||
|
} |
||||
|
|
||||
|
var allColors = dbGetProjectColors(); |
||||
|
for (var projColor : allColors) { |
||||
|
if (projColor.index > colorIndexMax) { |
||||
|
colorIndexMax = projColor.index; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private void initdbdata() { |
||||
|
dbEmptyProjectColors(); |
||||
|
for (String color : colors) { |
||||
|
var projColor = new ProjectColor(); |
||||
|
projColor.projectId = ""; |
||||
|
projColor.color = color; |
||||
|
projColor.index = 0; |
||||
|
projColor.save(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
//项目颜色 |
||||
|
public String getProjectColor(String projId) { |
||||
|
var projColor = dbGetProjectColor(projId); |
||||
|
if (projColor != null) { |
||||
|
colorIndexMax++; |
||||
|
projColor.index = colorIndexMax; |
||||
|
projColor.save(); |
||||
|
return projColor.color; |
||||
|
} |
||||
|
|
||||
|
var colors = dbGetProjectColors(); |
||||
|
//找到index最小的颜色 |
||||
|
ProjectColor minColor = null; |
||||
|
for (var color : colors) { |
||||
|
if (minColor == null || color.index < minColor.index) { |
||||
|
minColor = color; |
||||
|
} |
||||
|
} |
||||
|
assert minColor != null; |
||||
|
colorIndexMax++; |
||||
|
minColor.projectId = projId; |
||||
|
minColor.index = colorIndexMax; |
||||
|
minColor.save(); |
||||
|
return minColor.color; |
||||
|
} |
||||
|
} |
@ -0,0 +1,4 @@ |
|||||
|
package a8k.service; |
||||
|
|
||||
|
public class UIEventProcesser { |
||||
|
} |
@ -0,0 +1,8 @@ |
|||||
|
package a8k.service.appeventbus.appevent; |
||||
|
|
||||
|
public class A8kStateChangeEvent extends AppEvent { |
||||
|
|
||||
|
A8kStateChangeEvent(String displayInfo) { |
||||
|
super(A8kStateChangeEvent.class.getSimpleName()); |
||||
|
} |
||||
|
} |
@ -1,6 +1,8 @@ |
|||||
package a8k.service.appeventbus.appevent; |
package a8k.service.appeventbus.appevent; |
||||
|
|
||||
public class AppEvent { |
public class AppEvent { |
||||
|
|
||||
|
|
||||
|
public String name; |
||||
|
public AppEvent(String name) { |
||||
|
this.name = name; |
||||
|
} |
||||
} |
} |
@ -0,0 +1,34 @@ |
|||||
|
package a8k.service.base; |
||||
|
|
||||
|
import a8k.service.base.consumable.ConsumableItemGroup; |
||||
|
import a8k.service.base.plate.ReactingPlateState; |
||||
|
import a8k.service.base.reaction_result.ReactionResult; |
||||
|
import a8k.service.base.sample.EmergencyPosState; |
||||
|
import a8k.service.base.sample.SampleInfo; |
||||
|
import a8k.service.base.sample.TubeHolder; |
||||
|
import a8k.service.base.samplecfg.SampleTubeHolderCfg; |
||||
|
|
||||
|
import java.util.ArrayList; |
||||
|
import java.util.List; |
||||
|
|
||||
|
public class A8kDeviceState { |
||||
|
//耗材 |
||||
|
public ConsumableItemGroup consumableItemGroup = null; |
||||
|
//急诊位状态 |
||||
|
public EmergencyPosState emergencyPosState = EmergencyPosState.IDLE; |
||||
|
//急诊位样本信息 |
||||
|
public SampleInfo emergencySampleInfo = null; |
||||
|
//急诊位反应结果 |
||||
|
public ReactionResult emergencyResult = null; |
||||
|
//正在孵育的任务状态 |
||||
|
public List<ReactingPlateState> incubatingPlateStates = null; |
||||
|
//当前正在被处理的试管架状态 |
||||
|
public TubeHolder processingTubeHolder = null; |
||||
|
//温度 |
||||
|
public Integer temperature; |
||||
|
//配置 |
||||
|
public List<SampleTubeHolderCfg> cfgs = new ArrayList<>(); |
||||
|
|
||||
|
Boolean deviceInited = false; //设备是否初始化过 |
||||
|
Boolean devicePoweredOffNormally = false; //设备是否正常关机 |
||||
|
} |
@ -0,0 +1,6 @@ |
|||||
|
package a8k.service.base; |
||||
|
|
||||
|
public enum BloodType { |
||||
|
WHOLE_BLOOD, |
||||
|
SERUM; |
||||
|
} |
@ -0,0 +1,10 @@ |
|||||
|
package a8k.service.base.consumable; |
||||
|
|
||||
|
import java.util.Date; |
||||
|
|
||||
|
public class ConsumableItemGroup { |
||||
|
|
||||
|
public Date scanDate = new Date(); |
||||
|
public ReactantItem[] reactantItems = new ReactantItem[6]; |
||||
|
public TipGroupInfo[] tip = new TipGroupInfo[3]; |
||||
|
} |
@ -0,0 +1,16 @@ |
|||||
|
package a8k.service.base.consumable; |
||||
|
|
||||
|
//反应物,诸如反应板夹,小瓶缓冲液,大瓶缓冲液... |
||||
|
public class ReactantItem { |
||||
|
|
||||
|
public String projId; //项目ID |
||||
|
public String lotVal; //批次号 |
||||
|
public String color; //颜色 |
||||
|
|
||||
|
public Integer num = 0; //数量 |
||||
|
public Boolean hasPlateClip = false; //是否有反应板夹 always true |
||||
|
public Boolean hasLargeBufferBottle = false; //是否有大瓶缓冲液 |
||||
|
public Boolean hasSmallBufferBottle = false; //是否有小瓶缓冲液 |
||||
|
public Boolean hasDetectionMaterial = false; //是否有探测物质 |
||||
|
|
||||
|
} |
@ -0,0 +1,5 @@ |
|||||
|
package a8k.service.base.consumable; |
||||
|
|
||||
|
public class TipGroupInfo { |
||||
|
public Integer tipNum = 0;//剩余可用数量 |
||||
|
} |
@ -0,0 +1,12 @@ |
|||||
|
package a8k.service.base.plate; |
||||
|
|
||||
|
public enum PlateState { |
||||
|
//赋予中 |
||||
|
Incubating, |
||||
|
//孵育完成 |
||||
|
Incubated, |
||||
|
//孵育异常 |
||||
|
IncubateError, |
||||
|
//板条码异常 |
||||
|
PlateCodeError, |
||||
|
} |
@ -0,0 +1,23 @@ |
|||||
|
package a8k.service.base.plate; |
||||
|
|
||||
|
import a8k.service.base.reaction_result.ReactionResult; |
||||
|
import a8k.service.base.sample.SampleInfo; |
||||
|
import a8k.service.base.sample.Tube; |
||||
|
|
||||
|
import java.util.Date; |
||||
|
|
||||
|
public class ReactingPlateState { |
||||
|
|
||||
|
String sampleUUID; //样本UUID 系统自动生成 |
||||
|
String projectId;//项目id |
||||
|
|
||||
|
SampleInfo bindSample; //绑定的样本运行状态 |
||||
|
|
||||
|
Integer incubationPos; //孵育盘中的位置 0->19 |
||||
|
Date startIncubatedTime; //开始孵育时间 |
||||
|
Integer targetIncubatedTimeS; //目标孵育时间 |
||||
|
|
||||
|
PlateState plateState; //孵育盘状态 |
||||
|
|
||||
|
ReactionResult reactionResult; //反应结果 |
||||
|
} |
@ -0,0 +1,13 @@ |
|||||
|
package a8k.service.base.reaction_result; |
||||
|
|
||||
|
public class ReactionResult { |
||||
|
|
||||
|
Boolean result0Error; |
||||
|
Boolean result1Error; |
||||
|
Boolean result2Error; |
||||
|
|
||||
|
String result0; |
||||
|
String result1; |
||||
|
String result2; |
||||
|
|
||||
|
} |
@ -0,0 +1,7 @@ |
|||||
|
package a8k.service.base.sample; |
||||
|
|
||||
|
public enum EmergencyPosState { |
||||
|
IDLE,// |
||||
|
PROCESSING,// |
||||
|
PROCESS_COMPLETE,// |
||||
|
} |
@ -0,0 +1,6 @@ |
|||||
|
package a8k.service.base.sample; |
||||
|
|
||||
|
public class EmergencySampleInfo { |
||||
|
|
||||
|
|
||||
|
} |
@ -0,0 +1,18 @@ |
|||||
|
package a8k.service.base.sample; |
||||
|
|
||||
|
import a8k.appbase.A8kTubeType; |
||||
|
|
||||
|
import java.util.List; |
||||
|
|
||||
|
public class SampleInfo { |
||||
|
A8kTubeType tubeType; //管子类型 |
||||
|
|
||||
|
String sampleUUID; //样本UUID 系统自动生成 |
||||
|
String projectId; //项目id,用于查找项目相关信息 |
||||
|
String sampleUDPID; //用户输入的样本ID,不做逻辑,只做展示 |
||||
|
String sampleBarcodeID; //用于请求用户信息的条码ID |
||||
|
|
||||
|
List<String> projectIds; //项目id,用于查找项目相关信息 |
||||
|
|
||||
|
|
||||
|
} |
@ -0,0 +1,8 @@ |
|||||
|
package a8k.service.base.sample; |
||||
|
|
||||
|
import a8k.appbase.A8kTubeType; |
||||
|
|
||||
|
public class Tube { |
||||
|
TubeState tubeState = TubeState.EMPTY; //样本运行状态 |
||||
|
SampleInfo sampleInfo; //样本信息 |
||||
|
} |
@ -0,0 +1,12 @@ |
|||||
|
package a8k.service.base.sample; |
||||
|
|
||||
|
import a8k.appbase.A8kTubeType; |
||||
|
import a8k.service.base.BloodType; |
||||
|
|
||||
|
public class TubeHolder { |
||||
|
public BloodType bloodType = BloodType.WHOLE_BLOOD; //血型 |
||||
|
public A8kTubeType tubeHolderType = A8kTubeType.BloodTube; //管子类型 |
||||
|
public TubeHolderState tubeHolderState = TubeHolderState.TubeHolderStateIdle; //管子状态 |
||||
|
public Tube[] tubes = new Tube[10]; //管子 |
||||
|
public Integer processingTubeIndex = -1; //当前管子索引 |
||||
|
} |
@ -0,0 +1,7 @@ |
|||||
|
package a8k.service.base.sample; |
||||
|
|
||||
|
public enum TubeHolderState { |
||||
|
TubeHolderStateIdle, //空闲 |
||||
|
TubeHolderStateProcessing, //处理中 |
||||
|
TubeHolderStateProcessed, //处理完成 |
||||
|
} |
@ -0,0 +1,18 @@ |
|||||
|
package a8k.service.base.sample; |
||||
|
|
||||
|
public enum TubeState { |
||||
|
//空 |
||||
|
EMPTY, |
||||
|
//待处理 |
||||
|
READY, |
||||
|
//预处理中 |
||||
|
PRE_PROCESSING, |
||||
|
//待采样 |
||||
|
TO_BE_SAMPLED, |
||||
|
//采样中 |
||||
|
SAMPLING, |
||||
|
//采样完成 |
||||
|
SAMPLED, |
||||
|
//处理完成 |
||||
|
PROCESS_COMPLETE, |
||||
|
} |
@ -0,0 +1,8 @@ |
|||||
|
package a8k.service.base.samplecfg; |
||||
|
|
||||
|
import a8k.service.base.sample.SampleInfo; |
||||
|
|
||||
|
import java.util.List; |
||||
|
|
||||
|
public class SampleTubeCfg extends SampleInfo { |
||||
|
} |
@ -0,0 +1,9 @@ |
|||||
|
package a8k.service.base.samplecfg; |
||||
|
|
||||
|
import a8k.appbase.A8kTubeType; |
||||
|
|
||||
|
public class SampleTubeHolderCfg { |
||||
|
Boolean active;//是否激活 |
||||
|
A8kTubeType tubeHolderType = A8kTubeType.BloodTube; //试管架类型 |
||||
|
SampleTubeCfg[] sampleTubeCfgs = new SampleTubeCfg[10]; //试管配置 |
||||
|
} |
@ -0,0 +1,78 @@ |
|||||
|
package a8k.service.ctrl_service; |
||||
|
|
||||
|
import a8k.appbase.appret.AppRet; |
||||
|
import a8k.controler.engineer.utils.EngineerPageTab; |
||||
|
import a8k.controler.engineer.utils.EnginnerPageAction; |
||||
|
import a8k.service.ProjectColorAllocer; |
||||
|
import a8k.service.base.consumable.ConsumableItemGroup; |
||||
|
import a8k.service.base.consumable.ReactantItem; |
||||
|
import a8k.service.base.consumable.TipGroupInfo; |
||||
|
import jakarta.annotation.Resource; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
|
||||
|
@EngineerPageTab(name = "AppCtrlService") |
||||
|
@Component |
||||
|
public class AppCtrlService { |
||||
|
|
||||
|
|
||||
|
@Resource |
||||
|
ProjectColorAllocer projectColorAllocer; |
||||
|
|
||||
|
|
||||
|
@EnginnerPageAction(name = "初始化设备") |
||||
|
public AppRet<Object> initDevice() { |
||||
|
return AppRet.success(); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
//启动 |
||||
|
@EnginnerPageAction(name = "启动") |
||||
|
public AppRet<Object> startProcess() { |
||||
|
return AppRet.success(); |
||||
|
} |
||||
|
|
||||
|
//暂停 |
||||
|
@EnginnerPageAction(name = "暂停") |
||||
|
public AppRet<Object> pauseProcess() { |
||||
|
return AppRet.success(); |
||||
|
} |
||||
|
|
||||
|
//急停 |
||||
|
@EnginnerPageAction(name = "急停") |
||||
|
public AppRet<Object> forceStopProcess() { |
||||
|
return AppRet.success(); |
||||
|
} |
||||
|
|
||||
|
//停止 |
||||
|
@EnginnerPageAction(name = "停止") |
||||
|
public AppRet<Object> stopProcess() { |
||||
|
return AppRet.success(); |
||||
|
} |
||||
|
|
||||
|
//关机 |
||||
|
@EnginnerPageAction(name = "关机") |
||||
|
public AppRet<Object> shutdown() { |
||||
|
return AppRet.success(); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
//扫描耗材 |
||||
|
@EnginnerPageAction(name = "扫描耗材") |
||||
|
public AppRet<ConsumableItemGroup> scanningConsumables() { |
||||
|
ConsumableItemGroup var = new ConsumableItemGroup(); |
||||
|
for (int i = 0; i < 6; i++) { |
||||
|
var.reactantItems[i] = new ReactantItem(); |
||||
|
var.reactantItems[i].projId = "PROJECT_" + i; |
||||
|
var.reactantItems[i].lotVal = "LOT_" + i; |
||||
|
var.reactantItems[i].color = projectColorAllocer.getProjectColor(var.reactantItems[i].projId); |
||||
|
var.reactantItems[i].hasDetectionMaterial = i % 2 == 0; |
||||
|
var.reactantItems[i].hasSmallBufferBottle = i % 2 == 1; |
||||
|
var.reactantItems[i].hasLargeBufferBottle = i % 2 == 0; |
||||
|
|
||||
|
} |
||||
|
var.tip[0] = new TipGroupInfo(); |
||||
|
var.tip[1] = new TipGroupInfo(); |
||||
|
var.tip[2] = new TipGroupInfo(); |
||||
|
return AppRet.success(var); |
||||
|
} |
||||
|
} |
@ -0,0 +1,76 @@ |
|||||
|
package a8k.service.project_mgr; |
||||
|
|
||||
|
|
||||
|
import a8k.appbase.AppEventListener; |
||||
|
import a8k.appbase.ProjectInfoSimple; |
||||
|
import a8k.appbase.appret.AppRet; |
||||
|
import a8k.controler.engineer.utils.EngineerPageTab; |
||||
|
import a8k.controler.engineer.utils.EnginnerPageAction; |
||||
|
import a8k.db.ProjectInfo; |
||||
|
import a8k.service.appeventbus.AppEventBusService; |
||||
|
import a8k.service.appeventbus.appevent.A8kHardwareReport; |
||||
|
import a8k.service.appeventbus.appevent.AppEvent; |
||||
|
import a8k.service.hardware.canbus.A8kCanBusService; |
||||
|
import a8k.service.hardware.canbus.protocol.A8kPacket; |
||||
|
import a8k.service.hardware.canbus.protocol.CmdId; |
||||
|
import jakarta.annotation.PostConstruct; |
||||
|
import jakarta.annotation.Resource; |
||||
|
import org.slf4j.Logger; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
|
||||
|
import java.util.ArrayList; |
||||
|
import java.util.List; |
||||
|
import java.util.Map; |
||||
|
|
||||
|
@Component |
||||
|
@EngineerPageTab(name = "ProjectItemMgr") |
||||
|
public class ProjectItemMgrService implements AppEventListener { |
||||
|
static Logger logger = org.slf4j.LoggerFactory.getLogger(ProjectItemMgrService.class); |
||||
|
|
||||
|
@Resource |
||||
|
A8kCanBusService canBus; |
||||
|
|
||||
|
@Resource |
||||
|
AppEventBusService eventBus; |
||||
|
|
||||
|
@PostConstruct |
||||
|
public void init() { |
||||
|
|
||||
|
} |
||||
|
|
||||
|
@Override public void onAppEvent(AppEvent event) { |
||||
|
if (event instanceof A8kHardwareReport canPacket) { |
||||
|
A8kPacket packet = canPacket.getReportPacket(); |
||||
|
CmdId cmdId = CmdId.valueOf(packet.getCmdId()); |
||||
|
if (CmdId.event_a8000_idcard_online.equals(cmdId)) { |
||||
|
logger.info("插入ID卡"); |
||||
|
} else if (CmdId.event_a8000_idcard_offline.equals(cmdId)) { |
||||
|
logger.info("拔出ID卡"); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
|
||||
|
ProjectInfo dbGetProjectInfo(String lotName) { |
||||
|
return ProjectInfo.findOne(ProjectInfo.class, Map.of("lotName", lotName)); |
||||
|
} |
||||
|
|
||||
|
List<ProjectInfoSimple> dbGetProjectInfos() { |
||||
|
var pinfos = ProjectInfo.find(ProjectInfo.class); |
||||
|
List<ProjectInfoSimple> result = new ArrayList<>(); |
||||
|
for (var pinfo : pinfos) { |
||||
|
result.add(new ProjectInfoSimple(pinfo)); |
||||
|
} |
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
@EnginnerPageAction(name = "获取项目信息(简单)") |
||||
|
public AppRet<List<ProjectInfoSimple>> getProjectInfoSimple() { |
||||
|
return AppRet.success(dbGetProjectInfos()); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
} |
@ -0,0 +1,7 @@ |
|||||
|
CREATE TABLE "DBTableVersionTable" |
||||
|
( |
||||
|
"id" text NOT NULL, |
||||
|
"tableName" text, |
||||
|
"version" integer, |
||||
|
PRIMARY KEY ("id") |
||||
|
); |
@ -0,0 +1,8 @@ |
|||||
|
CREATE TABLE "ProjectColorTable" |
||||
|
( |
||||
|
"id" text NOT NULL, |
||||
|
"color" text, |
||||
|
"projectId" text, |
||||
|
"index" integer, |
||||
|
PRIMARY KEY ("id") |
||||
|
); |
Write
Preview
Loading…
Cancel
Save
Reference in new issue