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; |
|||
|
|||
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