经过51的三天努力,完成基于JRT的质控核心部分。框架部分已经达到了第一个可生产版本。
可生产包括以下部分:
1.Web开发基础和发布运维基础
2.Linux和WIndows客户端浏览器
3.Linux和WIndows客户端打印导出程序
4.Linux和WIndows初始化程序
5.Linux和WIndows仪器接口程序
6.打印模板设计器
7.菜单权限基础
8.文件服务
9.核心质控验证程序
能够实现的效果有:
模板设计
质控图在线打印预览
质控图打印预览
质控图打印
质控月报的横纵向预览和打印
质控月报复杂的Excel模板导出
环境下载
码表
开发和运维调试端
jrt运维命令
代码生成器和SQL执行器
以前业务脚本基本上是孤岛,提供新api加强业务脚本之间的联系
基本涵盖开发业务系统需要的方方面面,始终坚持业务脚本化、环境简单化、开发高效化的理念。开发基于IRIS数据库,开发完成后然后用M一键生成PostGreSql和人大金仓构造库的SQL脚本用网站执行来在PostGreSql和人大金仓上构建数据库。业务因为不写SQL语句,所有迁移数据库不需要改动任何一行业务代码,为了实现真正的多数据库支持(而不是口号),ORM只支持基础数据类型、不允许使用Datetime类似、比特类型,就没有数据库差异性问题,所以理论是支持所有JDBC的数据库而不需要改业务代码的。
选择质控来验证架构,一是因为质控独立性好,二是质控无论是表关系还是业务复杂性都够了,三是质控的打印足够复杂,既有JS绘图部分,也有表格部分,多方糅合,比较考验基础层。四是质控规则判断和月报数据计算足够复杂来验证框架的可靠性。五是质控我熟,可以很快实现。整体开发下来开发效率比M高很多、执行效率和M不差什么、可以媲美一下Cache的效率了。有了DolerGet之后,关系库在多维业务处理上也不在是那么弱鸡的存在了,最难突破的是思想,有一年多的时间我也觉得关系库永远实现不到我用Cache也业务的效果。
质控图查询与规则判断的核心代码:
import JRT.Core.Dto.HashParam;
import JRT.Core.Dto.OutValue;
import JRT.Core.Util.Convert;
import JRT.Core.Util.TimeParser;
import JRT.Model.Bussiness.Parameters;
import JRT.Model.Entity.*;
import JRTBLLBase.BaseHttpHandler;
import JRTBLLBase.Helper;
import java.util.*;
/**
* 画质控图公共查询逻辑,所有的质控图都通过虚拟M调过来,该类实现规则判断、对接月报累计值计算等等
*/
public class QCDrawCommon extends BaseHttpHandler {
/**
* 质控绘图公共查数据
* @param Param
* @param Session
* @param Output
* @return
* @throws Exception
*/
public String QueryQcDrawData(Parameters Param, OutValue Session, OutValue Output) throws Exception {
int StartDate= Helper.ValidParam(Param.P0,0);
int EndDate=Helper.ValidParam(Param.P1,0);
int MachineParameterDR= Convert.ToInt32(Param.P2);
int TestCodeDR=Convert.ToInt32(Param.P3);
String Level=Param.P4;
String QcRule=Param.P5;
String PointRange=Param.P6;
String MaterialDR=Param.P7;
String UseFL=Param.P8;
String LotNo=Param.P9;
HashParam hs=new HashParam();
hs.Add("MachineParameterDR",MachineParameterDR);
hs.Add("TestCodeDR",TestCodeDR);
List<String> operater=new ArrayList<>();
operater.add("=");
operater.add("=");
hs.Add("TestDate",StartDate);
hs.Add("TestDate",EndDate);
operater.add(">=");
operater.add("<=");
//质控物浓度映射
HashMap<Integer,BTQCMaterialLevel> matLevMap=new HashMap<>();
//存计算的月报数据
HashMap<String,HashMap> calMonthData=new HashMap<>();
//筛选质控物
if(!MaterialDR.isEmpty())
{
int MaterialDRInt=Convert.ToInt32(MaterialDR);
hs.Add("MaterialDR",MaterialDRInt);
//质控浓度
List<BTQCMaterialLevel> levList=EntityManager().FindByColVal(BTQCMaterialLevel.class,"MaterialDR",Convert.ToInt32(MaterialDR));
if(levList!=null&&levList.size()>0)
{
for(BTQCMaterialLevel lev:levList)
{
matLevMap.put(lev.LevelNo,lev);
//计算质控规则
CalQCRule(StartDate,EndDate,MaterialDRInt,TestCodeDR,lev.LevelNo,PointRange,"");
//得到月报的计算数据
List<HashMap> monthData=(List<HashMap>)Helper.GetBllMethodData("qc.ashx.ashQCDataCalMonth","CalOneMonthData",StartDate,EndDate,MaterialDRInt,TestCodeDR,lev.LevelNo,PointRange,true);
if(monthData!=null&&monthData.size()>0)
{
//按计算键把月报数据存起来
for(HashMap one:monthData)
{
String calKey=one.get("CalKey").toString();
calMonthData.put(calKey,one);
}
}
}
}
}
//浓度筛选图
HashMap levMap=Helper.GetSplitMap(Level,",");
//查询仪器、项目、日期范围的所有质控数据
List<QCTestResultDto> allData=EntityManager().FindAllSimple(QCTestResultDto.class,hs,"LevelNo asc,TestDate asc,TestTime asc",-1,null,operater);
//存处理后的数据
List<QCTestResultDto> dealedData=new ArrayList<>();
//1:所有质控点 2:去除排除点 6:所有在控点 11:去除平行点 12:仅平行点 4:去除复查点 10:只查最后一点
//7:最好点连线 8:最后一点连线 9:只查最好点
//辅助判断复查点
HashMap redoMap=new HashMap();
//最好点的图
HashMap<String,QCTestResultDto> bestMap=new HashMap();
HashMap<Integer, Boolean> bestRowIDMap=new HashMap();
//最后点的图
HashMap<String,QCTestResultDto> lastMap=new HashMap();
HashMap<Integer, Boolean> lastRowIDMap=new HashMap();
//按点类型筛选数据
dealedData=FilterDataByPointType(allData,levMap,matLevMap,PointRange);
//补全计算值和累计值
if(dealedData!=null&&dealedData.size()>0)
{
for(QCTestResultDto one:dealedData)
{
//排除颜色
if(one.ExcludeType.equals("2"))
{
one.CurRuleColour="#549cc7";
}
//平行质控颜色
if(one.IsParallel!=null&&one.IsParallel==true)
{
one.CurRuleColour="#8A2BE2";
}
//计算的键,相同的键算一批
String calKey=one.LotNo;
//没维护批号的按靶值和SD相同的算
if(calKey.isEmpty())
{
calKey=one.TCX+"-"+one.TCSD;
}
calKey=one.MaterialDR+"-"+one.TestCodeDR+"-"+one.LevelNo+"-"+calKey;
//放入月报计算数据
if(calMonthData.containsKey(calKey))
{
HashMap oneMonthData=calMonthData.get(calKey);
one.CalX=oneMonthData.get("CalMean").toString();
one.CalSD=oneMonthData.get("CalSD").toString();
one.CalCV=oneMonthData.get("CalCV").toString();
one.AccMean=oneMonthData.get("AccMean").toString();
one.AccSD=oneMonthData.get("AccSD").toString();
one.AccCV=oneMonthData.get("AccCV").toString();
}
}
}
return Helper.Object2Json(dealedData);
}
/**
* 计算质控规则
* @param startDate 开始日期
* @param endDate 结束日期
* @param materialDR 质控物
* @param testCodeDR 项目浓度
* @param levelNo 浓度
* @param fPointType 点类型
* @param useFL 是否使用浮动
* @throws Exception
*/
public void CalQCRule(int startDate,int endDate,int materialDR, int testCodeDR, int levelNo, String fPointType,String useFL) throws Exception
{
//从前12天数据开始查询,最大到12x规则
int qryStartDate=Helper.AddDays(startDate,-12);
HashParam hs=new HashParam();
hs.Add("MaterialDR",materialDR);
hs.Add("TestCodeDR",testCodeDR);
hs.Add("LevelNo",levelNo);
hs.Add("TestDate",qryStartDate);
hs.Add("TestDate",endDate);
List<String> operater=new ArrayList<>();
operater.add("=");
operater.add("=");
operater.add("=");
operater.add(">");
operater.add("<=");
//查询结果
List<QCTestResultDto> resList=EntityManager().FindAllSimple(QCTestResultDto.class,hs,"TestDate asc,TestTime asc",-1,null,operater);
//质控使用的规则
List<BTQCRules> useRules=new ArrayList<>();
//项目单独维护的规则
List<BTQCMaterialTCRules> tcRules=EntityManager().FindByColVal(BTQCMaterialTCRules.class,"MaterialDR",materialDR);
//有项目规则就用项目的规则
if(tcRules!=null&&tcRules.size()>0)
{
for(BTQCMaterialTCRules one:tcRules)
{
BTQCRules rule=EntityManager().DolerGet(BTQCRules.class,one.QCRulesDR);
useRules.add(rule);
}
}
//否则用质控物上的规则
else
{
List<BTQCMaterialRules> rules=EntityManager().FindByColVal(BTQCMaterialRules.class,"MaterialDR",materialDR);
if(rules!=null&&rules.size()>0)
{
for(BTQCMaterialRules one:rules)
{
BTQCRules rule=EntityManager().DolerGet(BTQCRules.class,one.QCRulesDR);
useRules.add(rule);
}
}
}
//按序号排序规则
useRules.sort(new Comparator<BTQCRules>() {
@Override
public int compare(BTQCRules p1, BTQCRules p2) {
return p1.Sequence - p2.Sequence;
}
});
//判断规则
if(resList!=null&&resList.size()>0&&useRules!=null&&useRules.size()>0)
{
List<String> upCol=new ArrayList<>();
upCol.add("QCRulesDR");
upCol.add("DQIV_Status");
upCol.add("ResColor");
//计算方差SD,每个点偏离靶值的SD倍数先计算好
CalDeviationSD(resList);
//延迟更新
HashMap<Integer,QCTestResultDto> lazyUpdataMap=new HashMap<>();
//遍历检查每个结果
for(int i=0;i<resList.size();i++)
{
QCTestResultDto res=resList.get(i);
//是否更新了质控规则,没更新的最后如果有规则就清空
boolean hasUpdateRule=false;
//遍历判断每个规则
for(BTQCRules rule:useRules)
{
//判断1-1S########################################一个质控测定值超过X±1S质控限。
if(rule.Code.equals("Y"))
{
int numPos=CheckSameSide(resList,i,1,1.0,true);
int numNeg=CheckSameSide(resList,i,1,-1.0,false);
if(numPos+numNeg>0)
{
hasUpdateRule=true;
//更新质控规则
UpdateRule(res,rule,lazyUpdataMap);
//终止判断
if(rule.IsEnd==true)
{
break;
}
}
}
//判断1-2S########################################一个质控测定值超过X±2S质控限。
else if(rule.Code.equals("A"))
{
int numPos=CheckSameSide(resList,i,1,2.0,true);
int numNeg=CheckSameSide(resList,i,1,-2.0,false);
if(numPos+numNeg>0)
{
hasUpdateRule=true;
//更新质控规则
UpdateRule(res,rule,lazyUpdataMap);
//终止判断
if(rule.IsEnd==true)
{
break;
}
}
}
//判断1-3S########################################一个质控测定值超过X±3S质控限。
else if(rule.Code.equals("B"))
{
int numPos=CheckSameSide(resList,i,1,3.0,true);
int numNeg=CheckSameSide(resList,i,1,-3.0,false);
if(numPos+numNeg>0)
{
hasUpdateRule=true;
//更新质控规则
UpdateRule(res,rule,lazyUpdataMap);
//终止判断
if(rule.IsEnd==true)
{
break;
}
}
}
//判断2-2S########################################两个连续的质控测定值同时超过X-2S或同时超过X+2S质控限,或同一天不同水平超过±2S,都要求同侧.
else if(rule.Code.equals("C"))
{
int numPos=CheckSameSide(resList,i,2,2.0,true);
int numNeg=CheckSameSide(resList,i,2,-2.0,false);
//两个连续的质控测定值同时超过X-2S或X+2S质控限
if(numPos==2||numNeg==2)
{
hasUpdateRule=true;
//更新质控规则
UpdateRule(res,rule,lazyUpdataMap);
//终止判断
if(rule.IsEnd==true)
{
break;
}
}
else if(numPos==1||numNeg==1)
{
List<QCTestResultDto> otherRes=GetOtherLevRes(res);
if(otherRes!=null&&otherRes.size()>0) {
//正向检查其他浓度
if(numPos==1)
{
int otNum=otherRes.size();
int numPosOT=CheckSameSide(otherRes,otNum-1,otNum,2.0,true);
if(numPosOT>=1)
{
hasUpdateRule=true;
//更新质控规则
UpdateRule(res,rule,lazyUpdataMap);
//终止判断
if(rule.IsEnd==true)
{
break;
}
}
}
//反向检查其他浓度
else if(numNeg==1)
{
int otNum=otherRes.size();
int numNegOT=CheckSameSide(otherRes,otNum-1,otNum,-2.0,false);
if(numNegOT>=1)
{
hasUpdateRule=true;
//更新质控规则
UpdateRule(res,rule,lazyUpdataMap);
//终止判断
if(rule.IsEnd==true)
{
break;
}
}
}
}
}
}
//判断R-4S########################################同批连续质控点一个超过+2S,一个超过-2S,或者同一天不同浓度的超过±2S。要求不同侧
else if(rule.Code.equals("R"))
{
int numPos=CheckSameSide(resList,i,2,2.0,true);
int numNeg=CheckSameSide(resList,i,2,-2.0,false);
//同批连续质控点一个超过+2S,一个超过-2S
if(numPos==1&&numNeg==1)
{
hasUpdateRule=true;
//更新质控规则
UpdateRule(res,rule,lazyUpdataMap);
//终止判断
if(rule.IsEnd==true)
{
break;
}
}
//或者同一天不同浓度的超过±2S
else
{
List<QCTestResultDto> otherRes=GetOtherLevRes(res);
if(otherRes!=null&&otherRes.size()>0) {
//正向检查其他浓度
if(numPos==1)
{
int otNum=otherRes.size();
int numNegOT=CheckSameSide(otherRes,otNum-1,otNum,-2.0,false);
if(numNegOT>=1)
{
hasUpdateRule=true;
//更新质控规则
UpdateRule(res,rule,lazyUpdataMap);
//终止判断
if(rule.IsEnd==true)
{
break;
}
}
}
//反向检查其他浓度
else if(numNeg==1)
{
int otNum=otherRes.size();
int numPosOT=CheckSameSide(otherRes,otNum-1,otNum,2.0,true);
if(numPosOT>=1)
{
hasUpdateRule=true;
//更新质控规则
UpdateRule(res,rule,lazyUpdataMap);
//终止判断
if(rule.IsEnd==true)
{
break;
}
}
}
}
}
}
//判断R4S_########################################两个连续的测定值之差超过4S。
else if(rule.Code.equals("T"))
{
if(i>0)
{
Double preOffset=resList.get(i-1).Offset;
Double curOffset=resList.get(i).Offset;
Double calDV=Math.abs(preOffset-curOffset);
if(calDV>4)
{
hasUpdateRule=true;
//更新质控规则
UpdateRule(res,rule,lazyUpdataMap);
//终止判断
if(rule.IsEnd==true)
{
break;
}
}
}
}
//判断4-1S########################################四个连续的质控测定值同时超过X-1S或X+1S。(同侧)
else if(rule.Code.equals("E"))
{
int numPos=CheckSameSide(resList,i,4,1.0,true);
int numNeg=CheckSameSide(resList,i,4,-1.0,false);
//四个点大于1s或-1s
if(numPos==4||numNeg==4)
{
int numPos2S=CheckSameSide(resList,i,4,2.0,true);
int numNeg2S=CheckSameSide(resList,i,4,-2.0,false);
//有一个点大于1-2S
if(numPos2S>1||numNeg2S>1) {
hasUpdateRule = true;
//更新质控规则
UpdateRule(res, rule, lazyUpdataMap);
//终止判断
if (rule.IsEnd == true) {
break;
}
}
}
}
//判断3-1S########################################三个连续的质控测定值同时超过X-1S或X+1S。
else if(rule.Code.equals("D"))
{
int numPos=CheckSameSide(resList,i,3,1.0,true);
int numNeg=CheckSameSide(resList,i,3,-1.0,false);
//三个点大于1s或-1s
if(numPos==3||numNeg==3)
{
int numPos2S=CheckSameSide(resList,i,3,2.0,true);
int numNeg2S=CheckSameSide(resList,i,3,-2.0,false);
//有一个点大于1-2S
if(numPos2S>1||numNeg2S>1) {
hasUpdateRule = true;
//更新质控规则
UpdateRule(res, rule, lazyUpdataMap);
//终止判断
if (rule.IsEnd == true) {
break;
}
}
}
}
//判断10X########################################十个连续的质控测定值落在靶值(X)的同一侧。1-2S触发
else if(rule.Code.equals("G"))
{
int numPos=CheckSameSide(resList,i,10,0.0,true);
int numNeg=CheckSameSide(resList,i,10,0.0,false);
//十个连续的质控测定值落在靶值(X)的同一侧
if(numPos==10||numNeg==10)
{
int numPos2S=CheckSameSide(resList,i,10,2.0,true);
int numNeg2S=CheckSameSide(resList,i,10,-2.0,false);
//有一个点大于1-2S
if(numPos2S>1||numNeg2S>1) {
hasUpdateRule = true;
//更新质控规则
UpdateRule(res, rule, lazyUpdataMap);
//终止判断
if (rule.IsEnd == true) {
break;
}
}
}
}
//判断5X########################################五个连续的质控测定值落在靶值(X)的同一侧。1-2S触发
else if(rule.Code.equals("F"))
{
int numPos=CheckSameSide(resList,i,5,0.0,true);
int numNeg=CheckSameSide(resList,i,5,0.0,false);
//5个连续的质控测定值落在靶值(X)的同一侧
if(numPos==5||numNeg==5)
{
int numPos2S=CheckSameSide(resList,i,5,2.0,true);
int numNeg2S=CheckSameSide(resList,i,5,-2.0,false);
//有一个点大于1-2S
if(numPos2S>1||numNeg2S>1) {
hasUpdateRule = true;
//更新质控规则
UpdateRule(res, rule, lazyUpdataMap);
//终止判断
if (rule.IsEnd == true) {
break;
}
}
}
}
//判判断8X########################################八个连续的质控测定值落在靶值(X)的同一侧。1-2S触发
else if(rule.Code.equals("Q"))
{
int numPos=CheckSameSide(resList,i,8,0.0,true);
int numNeg=CheckSameSide(resList,i,8,0.0,false);
//8个连续的质控测定值落在靶值(X)的同一侧
if(numPos==8||numNeg==8)
{
int numPos2S=CheckSameSide(resList,i,8,2.0,true);
int numNeg2S=CheckSameSide(resList,i,8,-2.0,false);
//有一个点大于1-2S
if(numPos2S>1||numNeg2S>1) {
hasUpdateRule = true;
//更新质控规则
UpdateRule(res, rule, lazyUpdataMap);
//终止判断
if (rule.IsEnd == true) {
break;
}
}
}
}
//判断12X########################################十二个连续的质控测定值落在靶值(X)的同一侧。1-2S触发
else if(rule.Code.equals("S"))
{
int numPos=CheckSameSide(resList,i,12,0.0,true);
int numNeg=CheckSameSide(resList,i,12,0.0,false);
//十个连续的质控测定值落在靶值(X)的同一侧
if(numPos==12||numNeg==12)
{
int numPos2S=CheckSameSide(resList,i,12,2.0,true);
int numNeg2S=CheckSameSide(resList,i,12,-2.0,false);
//有一个点大于1-2S
if(numPos2S>1||numNeg2S>1) {
hasUpdateRule = true;
//更新质控规则
UpdateRule(res, rule, lazyUpdataMap);
//终止判断
if (rule.IsEnd == true) {
break;
}
}
}
}
//判断7T########################################七个连续的质控测定值呈现出向上或向下的趋势
else if(rule.Code.equals("P"))
{
int numPos=CheckTrend(resList,i,7,true);
int numNeg=CheckTrend(resList,i,7,false);
//十个连续的质控测定值落在靶值(X)的同一侧
if(numPos==7||numNeg==7)
{
hasUpdateRule = true;
//更新质控规则
UpdateRule(res, rule, lazyUpdataMap);
//终止判断
if (rule.IsEnd == true) {
break;
}
}
}
}
//没有更新规则的,如果数据里面有规则就清空
if(hasUpdateRule==false&&res.QCRulesDR!=null)
{
UpdateRule(res,null,lazyUpdataMap);
}
}
Iterator<HashMap.Entry<Integer, QCTestResultDto>> iterator = lazyUpdataMap.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<Integer, QCTestResultDto> entry = iterator.next();
QCTestResultDto cur=entry.getValue();
//变化了才更新
if(cur.NewRuleDR!=cur.QCRulesDR) {
cur.QCRulesDR=cur.NewRuleDR;
cur.DQIV_Status=cur.NewRuleStatus;
if(cur.NewRuleDR==null)
{
cur.ResColor="";
}
int ret = EntityManager().Update(cur, upCol);
}
}
}
}
/**
* 查找当天其他浓度的数据
* @param res 当前结果
* @return 当前结果时间之前的其他浓度结果
*/
private List<QCTestResultDto> GetOtherLevRes(QCTestResultDto res) throws Exception
{
HashParam hs=new HashParam();
hs.Add("MaterialDR",res.MaterialDR);
hs.Add("TestCodeDR",res.TestCodeDR);
hs.Add("TestDate",res.TestDate);
hs.Add("TestTime",res.TestTime);
List<String> operater=new ArrayList<>();
operater.add("=");
operater.add("=");
operater.add("=");
operater.add("<=");
List<QCTestResultDto> resList=EntityManager().FindAllSimple(QCTestResultDto.class,hs,"TestTime asc",-1,null,operater);
List<QCTestResultDto> retList=new ArrayList<>();
if(resList!=null&&resList.size()>0)
{
for(QCTestResultDto one:resList)
{
if(one.LevelNo==res.LevelNo)
{
continue;
}
QCResMaterialTestCode para=EntityManager().DolerGet(QCResMaterialTestCode.class,one.ResMaterialTestCodeDR);
one.RunPara=para;
if(para.SD!=0) {
one.Offset = (Convert.ToDouble(res.Result) - para.Mean) / para.SD;
}
else
{
one.Offset=0.0;
}
retList.add(one);
}
}
return retList;
}
/**
* 更新质控规则
* @param res 结果
* @param rule 规则
* @param lazyMap 延迟更新
* @throws Exception
*/
private void UpdateRule(QCTestResultDto res,BTQCRules rule,HashMap<Integer,QCTestResultDto> lazyMap) throws Exception
{
if(rule==null)
{
res.NewRuleDR=null;
res.NewRuleStatus="";
lazyMap.put(res.RowID,res);
}
else
{
res.NewRuleDR = rule.RowID;
res.NewRuleStatus = rule.Status;
lazyMap.put(res.RowID,res);
}
}
/**
* 检测向上和向下趋势
* @param resList
* @param start
* @param checkNum
* @param isPos
* @return
*/
public int CheckTrend(List<QCTestResultDto> resList,int start,int checkNum,boolean isPos)
{
int retNum=0;
Double preOffset=null;
//检测数据
for(int i=start;i>=0;i--)
{
QCTestResultDto res=resList.get(i);
checkNum--;
if(preOffset!=null)
{
//连续向下
if(isPos==true)
{
if(preOffset<res.Offset)
{
retNum++;
}
else
{
break;
}
}
//连续向下
else
{
if(preOffset>res.Offset)
{
retNum++;
}
else
{
break;
}
}
}
//检测数量
if(checkNum==0)
{
break;
}
}
return retNum;
}
/**
* 检测在一侧的点数
* @param resList 所有结果
* @param start 开始位置
* @param checkNum 往前找的数量
* @param sd sd值
* @param isPos 是否正向
* @return
*/
public int CheckSameSide(List<QCTestResultDto> resList,int start,int checkNum,Double sd,boolean isPos)
{
int retNum=0;
//检测数据
for(int i=start;i>=0;i--)
{
QCTestResultDto res=resList.get(i);
checkNum--;
if(isPos==true&&res.Offset>sd)
{
retNum++;
}
else if(isPos==false&&res.Offset<sd)
{
retNum++;
}
//检测数量
if(checkNum==0)
{
break;
}
}
return retNum;
}
/**
* 计算每个点的偏差SD
* @param resList 结果集合
*/
public void CalDeviationSD(List<QCTestResultDto> resList) throws Exception
{
for(QCTestResultDto res:resList)
{
//获得参数
QCResMaterialTestCode para=EntityManager().DolerGet(QCResMaterialTestCode.class,res.ResMaterialTestCodeDR);
res.RunPara=para;
if(para.SD!=0) {
res.Offset = (Convert.ToDouble(res.Result) - para.Mean) / para.SD;
}
else
{
res.Offset=0.0;
}
}
}
/**
* 按点类型筛选数据
* @param allData 所有数据
* @param levMap 浓度
* @param matLevMap 质控物浓度
* @param pointRange 点类型
* @return
* @throws Exception
*/
public List<QCTestResultDto> FilterDataByPointType(List<QCTestResultDto> allData,HashMap levMap,HashMap<Integer,BTQCMaterialLevel> matLevMap,String pointRange) throws Exception
{
//存处理后的数据
List<QCTestResultDto> dealedData=new ArrayList<>();
//1:所有质控点 2:去除排除点 6:所有在控点 11:去除平行点 12:仅平行点 4:去除复查点 10:只查最后一点
//7:最好点连线 8:最后一点连线 9:只查最好点
//辅助判断复查点
HashMap redoMap=new HashMap();
//最好点的图
HashMap<String,QCTestResultDto> bestMap=new HashMap();
HashMap<Integer, Boolean> bestRowIDMap=new HashMap();
//最后点的图
HashMap<String,QCTestResultDto> lastMap=new HashMap();
HashMap<Integer, Boolean> lastRowIDMap=new HashMap();
if(allData!=null&&allData.size()>0)
{
for(QCTestResultDto one:allData)
{
//不是数字的不参与
if(!Helper.IsNumeric(one.Result))
{
continue;
}
//筛选浓度
if(levMap.size()>0&&!levMap.containsKey(String.valueOf(one.LevelNo)))
{
continue;
}
//去除排除点
if(pointRange.equals("2")&&one.ExcludeType.equals("2"))
{
continue;
}
//所有在控点
if(pointRange.equals("6")&&one.CurRuleStatus.equals("R"))
{
continue;
}
//仅平行点
if(pointRange.equals("11")&&!one.IsParallel.equals("!"))
{
continue;
}
//去除平行点
if(pointRange.equals("12")&&one.IsParallel.equals("!"))
{
continue;
}
//去除复查点
if(pointRange.equals("4")&&redoMap.containsKey(one.LevelNo+"-"+one.TestDate))
{
continue;
}
//当天第一个数据
redoMap.put(one.LevelNo+"-"+one.TestDate,true);
one.CurLevelNo=one.LevelNo;
one.CurPointType="";
one.Num=1;
one.CurdateNum=Helper.DateIntToStr(one.TestDate);
one.TestRTime=Helper.TimeIntToStr(one.TestTime);
one.UserName="";
if(one.AddUserDR!=null)
{
SYSUser user=EntityManager().DolerGet(SYSUser.class,one.AddUserDR);
one.UserName=user.CName;
}
one.PicResult=one.Result;
one.PicX=one.PicResult;
one.CurRuleCode="";
one.CurRuleColour="";
one.CurRuleStatus="";
one.CurRuleName="";
if(one.QCRulesDR!=null)
{
BTQCRules rule=EntityManager().DolerGet(BTQCRules.class,one.QCRulesDR);
one.CurRuleCode=rule.Code;
one.CurRuleColour=rule.Color;
one.CurRuleStatus=rule.Status;
one.CurRuleName=rule.CName;
}
//参数
QCResMaterialTestCode para=EntityManager().DolerGet(QCResMaterialTestCode.class,one.ResMaterialTestCodeDR);
//结果和均值的差
one.Offset=Math.abs(Convert.ToInt32(one.Result)-para.Mean);
//找到最好结果
if(!bestMap.containsKey(one.LevelNo+"-"+one.TestDate))
{
bestMap.put(one.LevelNo+"-"+one.TestDate,one);
}
else
{
QCTestResultDto pre=bestMap.get(one.LevelNo+"-"+one.TestDate);
if(pre.Offset>one.Offset)
{
bestMap.put(one.LevelNo+"-"+one.TestDate,one);
}
}
//最后点
lastMap.put(one.LevelNo+"-"+one.TestDate,one);
one.TCX=String.valueOf(para.Mean);
one.TCSD=String.valueOf(para.SD);
BTTestCode testCode=EntityManager().DolerGet(BTTestCode.class,one.TestCodeDR);
one.TCName=testCode.CName;
one.CurTestCode=testCode.Code;
one.CurLevelName=matLevMap.get(one.LevelNo).CName;
one.TCCV=String.valueOf(para.SetCV);
one.CalX="";
one.CalSD="";
one.CalCV="";
one.CalcType="";
one.AccMean="";
one.AccSD="";
one.AccCV="";
one.SetCV=String.valueOf(para.SetCV);
one.TargetCV=para.TargetCV;
one.LotNo=para.LotNo;
one.Event="";
one.ReagentLot=para.RgLot;
one.ResRemark=one.Remark;
one.AutUserName="";
one.OriginalRes=one.TextRes;
one.TransactionRemark="";
one.TransactionMethod="";
one.TransactionRes="";
one.TransactionType="";
one.TransactionUser="";
one.LotNoAll=para.LotNo;
dealedData.add(one);
}
//转换成主键map
for (Map.Entry<String,QCTestResultDto> entry : bestMap.entrySet()) {
bestRowIDMap.put(entry.getValue().RowID,true);
}
//转换成主键map
for (Map.Entry<String,QCTestResultDto> entry : lastMap.entrySet()) {
lastRowIDMap.put(entry.getValue().RowID,true);
}
//第二次处理数据
for(int i=0;i<dealedData.size();i++)
{
//只查最好点
if(pointRange.equals("9"))
{
if(!bestRowIDMap.containsKey(dealedData.get(i).RowID))
{
dealedData.remove(i);
i--;
continue;
}
}
//只查最后点
if(pointRange.equals("10"))
{
if(!lastRowIDMap.containsKey(dealedData.get(i).RowID))
{
dealedData.remove(i);
i--;
continue;
}
}
//最好点连线
if(pointRange.equals("7"))
{
if(!bestRowIDMap.containsKey(dealedData.get(i).RowID))
{
dealedData.get(i).CurPointType="0";
}
}
//最后点连线
else
{
if(!lastRowIDMap.containsKey(dealedData.get(i).RowID))
{
dealedData.get(i).CurPointType="0";
}
}
}
}
return dealedData;
}
/**
* 查询日间质控图数据
* @param Param
* @param Session
* @param Output
* @return
* @throws Exception
*/
public String QueryQcDrawDataDay(Parameters Param, OutValue Session, OutValue Output) throws Exception {
int StartDate= Helper.ValidParam(Param.P0,0);
int EndDate=Helper.ValidParam(Param.P1,0);
int MachineParameterDR= Convert.ToInt32(Param.P2);
String TestCodeDRS=Param.P3;
String MaterialDRS=Param.P4;
String Level=Param.P5;
String LastPoint=Param.P6;
String LotNo=Param.P7;
HashParam hs=new HashParam();
hs.Add("MachineParameterDR",MachineParameterDR);
List<String> operater=new ArrayList<>();
operater.add("=");
hs.Add("TestDate",StartDate);
hs.Add("TestDate",EndDate);
operater.add(">=");
operater.add("<=");
//浓度筛选图
HashMap levMap=Helper.GetSplitMap(Level,",");
//项目筛选图
HashMap tsMap=Helper.GetSplitMap(TestCodeDRS,",");
//质控物筛选图
HashMap matMap=Helper.GetSplitMap(MaterialDRS,",");
String [] tsArr=TestCodeDRS.split(",");
String [] matArr=MaterialDRS.split(",");
String [] levArr=Level.split(",");
//计算质控规则
for(int i=0;i<tsArr.length;i++)
{
int TestCodeDR=Convert.ToInt32(tsArr[i]);
int MaterialDR=Convert.ToInt32(matArr[i]);
List<BTQCMaterialLevel> levList=EntityManager().FindByColVal(BTQCMaterialLevel.class,"MaterialDR",MaterialDR);
for(BTQCMaterialLevel lev:levList)
{
//筛选浓度
if(levMap.size()>0&&!levMap.containsKey(String.valueOf(lev.LevelNo)))
{
continue;
}
//计算质控规则
CalQCRule(StartDate,EndDate,MaterialDR,TestCodeDR,lev.LevelNo,"1","");
}
}
//查询仪器、项目、日期范围的所有质控数据
List<QCTestResultDto> allData=EntityManager().FindAllSimple(QCTestResultDto.class,hs,"LevelNo asc,TestDate asc,TestTime asc",-1,null,operater);
//存处理后的数据
List<QCTestResultDto> dealedData=new ArrayList<>();
HashMap lastMap=new HashMap();
if(allData!=null&&allData.size()>0)
{
for(QCTestResultDto one:allData)
{
//筛选浓度
if(levMap.size()>0&&!levMap.containsKey(String.valueOf(one.LevelNo)))
{
continue;
}
//筛选质控物
if(matMap.size()>0&&!matMap.containsKey(String.valueOf(one.MaterialDR)))
{
continue;
}
//筛选项目
if(tsMap.size()>0&&!tsMap.containsKey(String.valueOf(one.TestCodeDR)))
{
continue;
}
//最后点
if(LastPoint.equals("1")) {
String key = one.MaterialDR + "-" + one.TestCodeDR + "-" + one.LevelNo + "-" + one.TestDate;
lastMap.put(key, one);
}
else
{
dealedData.add(one);
}
}
//最后点
if(LastPoint.equals("1")) {
dealedData.addAll(lastMap.values());
}
//统计失控数量
int lossControlNum=0;
for(QCTestResultDto one:dealedData) {
if(one.DQIV_Status.equals("R"))
{
lossControlNum++;
}
}
//补全数据
for(QCTestResultDto one:dealedData)
{
BTQCMaterial matDto=EntityManager().DolerGet(BTQCMaterial.class,one.MaterialDR);
BTMIMachineParameter machDto=EntityManager().DolerGet(BTMIMachineParameter.class,matDto.MachineDR);
one.CurMachName=machDto.CName;
one.TestCodeNum=tsMap.size()+"";
one.LossControlNum=lossControlNum+"";
one.CurLevelNo=one.LevelNo;
one.CurPointType="";
one.Num=1;
one.CurdateNum=Helper.DateIntToStr(one.TestDate);
one.TestRTime=Helper.TimeIntToStr(one.TestTime);
one.UserName="";
if(one.AddUserDR!=null)
{
SYSUser user=EntityManager().DolerGet(SYSUser.class,one.AddUserDR);
one.UserName=user.CName;
}
one.PicResult=one.Result;
one.PicX=one.PicResult;
one.CurRuleCode="";
one.CurRuleColour="";
one.CurRuleStatus="";
one.CurRuleName="";
if(one.QCRulesDR!=null)
{
BTQCRules rule=EntityManager().DolerGet(BTQCRules.class,one.QCRulesDR);
one.CurRuleCode=rule.Code;
one.CurRuleColour=rule.Color;
one.CurRuleStatus=rule.Status;
one.CurRuleName=rule.CName;
}
//参数
QCResMaterialTestCode para=EntityManager().DolerGet(QCResMaterialTestCode.class,one.ResMaterialTestCodeDR);
//结果和均值的差
one.Offset=Math.abs(Convert.ToInt32(one.Result)-para.Mean);
//最后点
lastMap.put(one.LevelNo+"-"+one.TestDate,one);
one.TCX=String.valueOf(para.Mean);
one.TCSD=String.valueOf(para.SD);
BTTestCode testCode=EntityManager().DolerGet(BTTestCode.class,one.TestCodeDR);
one.TCName=testCode.CName;
one.CurTestCode=testCode.Code;
one.CurLevelName="";
one.TCCV=String.valueOf(para.SetCV);
one.CalX="";
one.CalSD="";
one.CalCV="";
one.CalcType="";
one.AccMean="";
one.AccSD="";
one.AccCV="";
one.SetCV=String.valueOf(para.SetCV);
one.TargetCV=para.TargetCV;
one.LotNo=para.LotNo;
one.Event="";
one.ReagentLot=para.RgLot;
one.ResRemark=one.Remark;
one.AutUserName="";
one.OriginalRes=one.TextRes;
one.TransactionRemark="";
one.TransactionMethod="";
one.TransactionRes="";
one.TransactionType="";
one.TransactionUser="";
one.LotNoAll=para.LotNo;
}
}
return Helper.Object2Json(dealedData);
}
/**
* 返回到前台的数据实体
*/
public static class QCTestResultDto extends QCTestResult
{
/**
* 当前浓度
*/
public int CurLevelNo;
/**
* 点类型
*/
public String CurPointType;
/**
* 数量
*/
public int Num;
/**
* 日期
*/
public String CurdateNum;
/**
* 测试时间
*/
public String TestRTime;
/**
* 用户名
*/
public String UserName;
/**
* 画图结果
*/
public String PicResult;
/**
* 结果
*/
public String PicX;
/**
* 规则代码
*/
public String CurRuleCode;
/**
* 规则颜色
*/
public String CurRuleColour;
/**
* 规则状态
*/
public String CurRuleStatus;
/**
* 规则名称
*/
public String CurRuleName;
/**
* 靶值
*/
public String TCX;
/**
* SD
*/
public String TCSD;
/**
* 项目名称
*/
public String TCName;
/**
* 项目代码
*/
public String CurTestCode;
/**
* 浓度名称
*/
public String CurLevelName;
/**
* CV
*/
public String TCCV;
/**
* 计算均值
*/
public String CalX;
/**
* 计算SD
*/
public String CalSD;
/**
* 计算CV
*/
public String CalCV;
/**
* 计算类型
*/
public String CalcType;
/**
* 计算均值
*/
public String AccMean;
/**
* 计算均值
*/
public String AccSD;
/**
* 计算均值
*/
public String AccCV;
/**
* 计算均值
*/
public String SetCV;
/**
* 计算均值
*/
public String TargetCV;
/**
* 计算均值
*/
public String LotNo;
/**
* 计算均值
*/
public String Event;
/**
* 计算均值
*/
public String ReagentLot;
/**
* 计算均值
*/
public String ResRemark;
/**
* 计算均值
*/
public String AutUserName;
/**
* 计算均值
*/
public String OriginalRes;
/**
* 失控处理说明
*/
public String TransactionRemark;
/**
* 失控类型
*/
public String TransactionType;
/**
* 处理方法
*/
public String TransactionMethod;
/**
* 失控处理结果
*/
public String TransactionRes;
/**
* 失控处理人
*/
public String TransactionUser;
/**
* 全部批号
*/
public String LotNoAll;
/**
* 结果和靶值的偏差
*/
public Double Offset;
/**
* 运行参数
*/
public QCResMaterialTestCode RunPara;
/**
* 仪器名称
*/
public String CurMachName="";
/**
* 测试项目数量
*/
public String TestCodeNum="";
/**
* 失控数量
*/
public String LossControlNum="";
/**
* 新判断的规则
*/
public Integer NewRuleDR;
/**
* 新规则状态
*/
public String NewRuleStatus;
}
}
质控月报的核心逻辑
import JRT.Core.Debug.DebugSession;
import JRT.Core.Dto.HashParam;
import JRT.Core.Dto.OutValue;
import JRT.Core.MultiPlatform.JRTContext;
import JRT.Core.Util.Convert;
import JRT.Core.Util.TimeParser;
import JRT.Model.Bussiness.Parameters;
import JRT.Model.Entity.*;
import JRTBLLBase.BaseHttpHandler;
import JRTBLLBase.Helper;
import java.util.*;
/**
* 质控月报后台
*/
public class ashQCDataCalMonth extends BaseHttpHandler {
/**
* 查询质控月报数据
* @return
* @throws Exception
*/
public String QueryTestResultMonthData() throws Exception
{
//开始日期
String StartDate = Helper.ValidParam(JRTContext.GetRequest(Request,"StartDate"),"");
//结束日期
String EndDate = Helper.ValidParam(JRTContext.GetRequest(Request,"EndDate"),"");
//仪器
String MachineParameterDR = Helper.ValidParam(JRTContext.GetRequest(Request,"MachineParameterDR"),"");
//浓度
String Leavel = Helper.ValidParam(JRTContext.GetRequest(Request,"Leavel"),"");
//项目
String TestCodeDRS = Helper.ValidParam(JRTContext.GetRequest(Request,"TestCodeDRS"),"");
//排除规则
String QcRule = Helper.ValidParam(JRTContext.GetRequest(Request,"QcRule"),"");
//质控物
String MaterialDRS = Helper.ValidParam(JRTContext.GetRequest(Request,"MaterialDRS"),"");
String PointType = Helper.ValidParam(JRTContext.GetRequest(Request,"PointType"), "");
String LotType = Helper.ValidParam(JRTContext.GetRequest(Request,"LotType"), "");
String FLots = Helper.ValidParam(JRTContext.GetRequest(Request,"FLots"), "");
Parameters param=new Parameters();
param.P0=StartDate;
param.P1=EndDate;
param.P2=MachineParameterDR;
param.P3=Leavel;
param.P4=TestCodeDRS;
param.P5=QcRule;
param.P6=MaterialDRS;
param.P7=PointType;
param.P8=LotType;
param.P9=FLots;
OutValue session=new OutValue();
session.Value=UserLogin().SessionStr;
OutValue output=new OutValue();
return QueryQCMonthData(param,session,output);
}
/**
* 查询质控月报数据的虚拟M方法
*
* @param Param
* @param Session
* @param Output
* @return
*/
public String QueryQCMonthData(Parameters Param, OutValue Session, OutValue Output) throws Exception {
String SessionStr=Session.GetString();
String [] sessArr=SessionStr.split("\\^");
BTHospital hosDto=EntityManager().DolerGet(BTHospital.class,Convert.ToInt32(sessArr[4]));
SYSUser userDto=EntityManager().DolerGet(SYSUser.class,Convert.ToInt32(sessArr[0]));
Session.Value=hosDto.CName+"检验科";
Session.Value+="^"+Helper.GetNowDateStr();
Session.Value+="^"+"";
Session.Value+="^"+"质控月报导出";
Session.Value+="^"+userDto.CName;
Session.Value+="^"+Helper.GetNowDateStr().substring(1,7);
//开始日期
String StartDate = Param.P0;
//结束日期
String EndDate = Param.P1;
//仪器
int MachineParameterDR = Helper.ValidParam(Param.P2,0);
BTMIMachineParameter machDto=EntityManager().DolerGet(BTMIMachineParameter.class,MachineParameterDR);
Session.Value+="^"+machDto.CName;
BTWorkGroupMachine wgmDto=EntityManager().DolerGet(BTWorkGroupMachine.class,machDto.WorkGroupMachineDR);
Session.Value+="^"+wgmDto.CName;
BTWorkGroup wgDto=EntityManager().DolerGet(BTWorkGroup.class,wgmDto.WorkGroupDR);
Session.Value+="^"+wgDto.CName;
//浓度
String Leavel = Param.P3;
//项目
String TestCodeDRS = Param.P4;
//排除规则
String QcRule = Param.P5;
//质控物
String MaterialDRS = Param.P6;
String PointType = Param.P7;
String LotType = Param.P8;
String FLots = Param.P9;
//计算项目
String [] tsArr=TestCodeDRS.split(",");
//计算质控物
String [] matArr=MaterialDRS.split(",");
//浓度图
HashMap levMap=Helper.GetSplitMap(Leavel,",");
List<QCMonthRetDto> retList=new ArrayList<>();
//存所有的质控规则
HashMap<Integer,Boolean> ruleMap=new HashMap();
//循环计算每个项目的月报数据
for(int i=0;i<tsArr.length;i++)
{
String MaterialDR=matArr[i];
//得到质控物的规则
List<BTQCMaterialRules> ruleList=EntityManager().FindByColVal(BTQCMaterialRules.class,"MaterialDR",Convert.ToInt32(MaterialDR));
if(ruleList!=null&&ruleList.size()>0)
{
for(BTQCMaterialRules rule:ruleList)
{
ruleMap.put(rule.QCRulesDR,true);
}
}
//得到质控物的浓度数据
List<BTQCMaterialLevel> levList=EntityManager().FindByColVal(BTQCMaterialLevel.class,"MaterialDR",Convert.ToInt32(MaterialDR));
for(BTQCMaterialLevel lev:levList) {
String levStr=String.valueOf(lev.LevelNo);
if(levMap.size()>0&&!levMap.containsKey(levStr))
{
continue;
}
//计算一个项目浓度的月报数据
List<HashMap> calResList=CalOneMonthData(Helper.ValidParam(StartDate,0),Helper.ValidParam(EndDate,0),Convert.ToInt32(MaterialDR),Convert.ToInt32(tsArr[i]),Convert.ToInt32(levStr),PointType,false);
for(HashMap one:calResList)
{
QCMonthRetDto oneMon=new QCMonthRetDto();
Helper.CopyProperties(one.get("LastPara"),oneMon);
BTQCMaterial matDto=EntityManager().DolerGet(BTQCMaterial.class,oneMon.MaterialDR);
oneMon.MatName=matDto.CName;
oneMon.YearMonth=Helper.DateIntToStr(oneMon.TestDate).substring(0,7);
oneMon.AccMean=String.valueOf(one.get("AccMean"));
oneMon.AccSD=String.valueOf(one.get("AccSD"));
oneMon.AccCV=String.valueOf(one.get("AccCV"));
oneMon.AccMax=String.valueOf(one.get("AccMax"));
oneMon.AccMin=String.valueOf(one.get("AccMin"));
oneMon.AccNum=String.valueOf(one.get("AccNum"));
oneMon.AccResStr=String.valueOf(one.get("AccResStr"));
oneMon.CalMean=String.valueOf(one.get("CalMean"));
oneMon.CalSD=String.valueOf(one.get("CalSD"));
oneMon.CalCV=String.valueOf(one.get("CalCV"));
oneMon.CalMax=String.valueOf(one.get("CalMax"));
oneMon.CalMin=String.valueOf(one.get("CalMin"));
oneMon.CalNum=String.valueOf(one.get("CalNum"));
oneMon.CalResStr=String.valueOf(one.get("CalResStr"));
oneMon.CalLossNum=String.valueOf(one.get("CalLossNum"));
oneMon.CalWaringNum=String.valueOf(one.get("CalWaringNum"));
oneMon.CalDealNum=String.valueOf(one.get("CalDealNum"));
oneMon.CalLossRate=String.valueOf(one.get("CalLossRate"));
oneMon.CalDealRate=String.valueOf(one.get("CalDealRate"));
oneMon.CalWaringRate=String.valueOf(one.get("CalWaringRate"));
oneMon.CalDealWRate=String.valueOf(one.get("CalDealWRate"));
oneMon.CalInMean=String.valueOf(one.get("CalInMean"));
oneMon.CalInSD=String.valueOf(one.get("CalInSD"));
oneMon.CalInCV=String.valueOf(one.get("CalInCV"));
oneMon.CalInMax=String.valueOf(one.get("CalInMax"));
oneMon.CalInMin=String.valueOf(one.get("CalInMin"));
oneMon.CalInNum=String.valueOf(one.get("CalInNum"));
oneMon.CalInResStr=String.valueOf(one.get("CalInResStr"));
if(!oneMon.CalCV.isEmpty()&&!oneMon.TargetCV.isEmpty())
{
if(Convert.ToDouble(oneMon.CalCV)<Convert.ToDouble(oneMon.TargetCV))
{
oneMon.IsQualified="通过";
}
}
BTTestCode tsDto=EntityManager().DolerGet(BTTestCode.class,oneMon.TestCodeDR);
oneMon.Synonym=tsDto.Synonym;
oneMon.TCName=tsDto.CName;
oneMon.LevelName=lev.CName;
retList.add(oneMon);
}
}
}
//所有的质控规则
String AllRuleName="";
Iterator<HashMap.Entry<Integer, Boolean>> iterator = ruleMap.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<Integer, Boolean> entry = iterator.next();
BTQCRules rule=EntityManager().DolerGet(BTQCRules.class,entry.getKey());
if(AllRuleName.isEmpty())
{
AllRuleName=rule.CName;
}
else
{
AllRuleName+=","+rule.CName;
}
}
Session.Value+="^"+AllRuleName;
return Helper.Object2Json(retList);
}
/**
* 计算一个项目浓度的月报数据
* @param StartDate 开始日期
* @param EndDate 结束日期
* @param MaterialDR 质控物
* @param TestCodeDR 项目
* @param LevelNo 浓度
* @param PointType 点类型
* @param isQCMap 是否是质控画图,画图不需要计算失控处理率相关东西
* @return 计算数据
* @throws Exception
*/
public List<HashMap> CalOneMonthData(int StartDate,int EndDate,int MaterialDR,int TestCodeDR,int LevelNo,String PointType,boolean isQCMap) throws Exception {
//返回的数据
List<HashMap> retList=new ArrayList<>();
//往前推一年取数据算累计数据
int accStartData=Helper.AddDays(StartDate,-365);
HashParam hs=new HashParam();
hs.Add("MaterialDR",MaterialDR);
hs.Add("TestCodeDR",TestCodeDR);
hs.Add("LevelNo",LevelNo);
hs.Add("TestDate",accStartData);
hs.Add("TestDate",EndDate);
List<String> operater=new ArrayList<>();
operater.add("=");
operater.add("=");
operater.add("=");
operater.add(">");
operater.add("<=");
//查询结果
List<QCTestResultDto> resList=EntityManager().FindAllSimple(QCTestResultDto.class,hs,"TestDate asc,TestTime asc",-1,null,operater);
//筛选点类型数据
resList=FilterDataByPointType(resList,PointType);
//按批号分别计算
HashMap<String,CalDto> calMap=new HashMap<>();
//前一个计算键
String preCalKey="";
if(resList!=null&&resList.size()>0)
{
for(int i=resList.size()-1;i>=0;i--)
{
QCTestResultDto one=resList.get(i);
//计算的键,相同的键算一批
String calKey=one.RunPara.LotNo;
//没维护批号的按靶值和SD相同的算
if(calKey.isEmpty())
{
calKey=one.RunPara.Mean+"-"+one.RunPara.SD;
}
calKey=one.MaterialDR+"-"+one.TestCodeDR+"-"+one.LevelNo+"-"+calKey;
//按计算键得到计算实体
CalDto curCalDto=null;
//创建新的计算实体
if(!calMap.containsKey(calKey))
{
CalDto newCal=new CalDto();
newCal.LastPara=one.RunPara;
calMap.put(calKey,newCal);
curCalDto=newCal;
}
else
{
curCalDto=calMap.get(calKey);
}
//查询是否有失控处理,质控图不统计失控处理率那些
if((isQCMap!=true)&&(one.DQIV_Status.equals("R")||one.DQIV_Status.equals("W")))
{
HashParam hsTran=new HashParam();
hsTran.Add("TestResultDR",one.RowID);
if(EntityManager().CheckHasData(QCTestResultTransaction.class,hsTran,null,null)==true)
{
one.HasDeal=true;
}
}
//算本次信息
if(one.TestDate>=StartDate)
{
//加入月数据
curCalDto.AddCalRes(one);
preCalKey=calKey;
}
//小于开始日期的就是累计数据,如果和前一个计算键不同就说明批号不是一个,就不往前找了
else if(one.TestDate<StartDate)
{
if(!calKey.equals(preCalKey))
{
break;
}
}
//加入累计数据
curCalDto.AddAccRes(one);
}
//使用迭代器遍历计算数据
Iterator<HashMap.Entry<String, CalDto>> iterator = calMap.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, CalDto> entry = iterator.next();
HashMap calRes=entry.getValue().GetCalRes();
//计算唯一键
calRes.put("CalKey",entry.getKey());
retList.add(calRes);
}
}
return retList;
}
/**
* 处理点范围
* @param allData 所有数据
* @param pointRange 点类型
* @return 处理后的数据
* @throws Exception
*/
public List<QCTestResultDto> FilterDataByPointType(List<QCTestResultDto> allData,String pointRange) throws Exception
{
//存处理后的数据
List<QCTestResultDto> dealedData=new ArrayList<>();
//1:所有质控点 2:去除排除点 6:所有在控点 11:去除平行点 12:仅平行点 4:去除复查点 10:只查最后一点
//7:最好点连线 8:最后一点连线 9:只查最好点
//辅助判断复查点
HashMap redoMap=new HashMap();
//最好点的图
HashMap<String,QCTestResultDto> bestMap=new HashMap();
HashMap<Integer, Boolean> bestRowIDMap=new HashMap();
//最后点的图
HashMap<String,QCTestResultDto> lastMap=new HashMap();
HashMap<Integer, Boolean> lastRowIDMap=new HashMap();
if(allData!=null&&allData.size()>0)
{
for(QCTestResultDto one:allData)
{
//不是数字的不参与
if(!Helper.IsNumeric(one.Result))
{
continue;
}
//去除排除点
if(pointRange.equals("2")&&one.ExcludeType.equals("2"))
{
continue;
}
//仅平行点
if(pointRange.equals("11")&&!one.IsParallel.equals("!"))
{
continue;
}
//去除平行点
if(pointRange.equals("12")&&one.IsParallel.equals("!"))
{
continue;
}
//去除复查点
if(pointRange.equals("4")&&redoMap.containsKey(one.LevelNo+"-"+one.TestDate))
{
continue;
}
//只查最后一点
if(pointRange.equals("10")&&redoMap.containsKey(one.LevelNo+"-"+one.TestDate))
{
continue;
}
//取规则状态
if(one.QCRulesDR!=null)
{
BTQCRules ruleDto=EntityManager().DolerGet(BTQCRules.class,one.QCRulesDR);
one.CurRuleStatus=ruleDto.Status;
}
//所有在控点
if(pointRange.equals("6")&&one.CurRuleStatus.equals("R"))
{
continue;
}
//当天第一个数据
redoMap.put(one.LevelNo+"-"+one.TestDate,true);
//参数
QCResMaterialTestCode para=EntityManager().DolerGet(QCResMaterialTestCode.class,one.ResMaterialTestCodeDR);
//结果和均值的差
one.Offset=Math.abs(Convert.ToInt32(one.Result)-para.Mean);
//找到最好结果
if(!bestMap.containsKey(one.LevelNo+"-"+one.TestDate))
{
bestMap.put(one.LevelNo+"-"+one.TestDate,one);
}
else
{
QCTestResultDto pre=bestMap.get(one.LevelNo+"-"+one.TestDate);
if(pre.Offset>one.Offset)
{
bestMap.put(one.LevelNo+"-"+one.TestDate,one);
}
}
//最后点
lastMap.put(one.LevelNo+"-"+one.TestDate,one);
one.RunPara=para;
dealedData.add(one);
}
//转换成主键map
for (Map.Entry<String,QCTestResultDto> entry : bestMap.entrySet()) {
bestRowIDMap.put(entry.getValue().RowID,true);
}
//转换成主键map
for (Map.Entry<String,QCTestResultDto> entry : lastMap.entrySet()) {
lastRowIDMap.put(entry.getValue().RowID,true);
}
//第二次处理数据
for(int i=0;i<dealedData.size();i++)
{
QCTestResultDto one=dealedData.get(i);
//只查最好点
if(pointRange.equals("9"))
{
if(!bestRowIDMap.containsKey(one.RowID))
{
dealedData.remove(i);
i--;
continue;
}
}
//只查最后点
if(pointRange.equals("10"))
{
if(!lastRowIDMap.containsKey(one.RowID))
{
dealedData.remove(i);
i--;
continue;
}
}
}
}
return dealedData;
}
/**
* 返回到前台的数据实体
*/
public static class QCTestResultDto extends QCTestResult {
/**
* 运行参数
*/
public QCResMaterialTestCode RunPara;
/**
* 规则状态
*/
public String CurRuleStatus;
/**
* 结果和靶值的偏差
*/
public Double Offset;
/**
* 是否进行失控处理
*/
public Boolean HasDeal;
}
/**
* 计算计算均值、SD、累计均值、SD用到的承载实体
*/
public static class CalDto
{
/**
* 最后的参数
*/
public QCResMaterialTestCode LastPara;
/**
* 失控数
*/
private int CalLossNum=0;
/**
* 警告数
*/
private int CalWaringNum=0;
/**
* 处理数
*/
private int CalDealNum=0;
/**
* 警告处理数
*/
private int CalDealWNum=0;
/**
* 失控数
*/
private int AccLossNum=0;
/**
* 警告数
*/
private int AccWaringNum=0;
/**
* 处理数
*/
private int AccDealNum=0;
/**
* 警告处理数
*/
private int AccDealWNum=0;
/**
* 总和
*/
private Double CalSumTotal=0.0;
/**
* 平方和
*/
private Double CalQuadraticSum=0.0;
/**
* 数据数量
*/
private int CalNum=0;
/**
* 存计算的结果
*/
private List<Double> CalResList=new ArrayList<>();
/**
* 在控数据总和
*/
private Double CalInSumTotal=0.0;
/**
* 在控数据平方和
*/
private Double CalInQuadraticSum=0.0;
/**
* 在控数据数据数量
*/
private int CalInNum=0;
/**
* 在控数据存计算的结果
*/
private List<Double> CalInResList=new ArrayList<>();
/**
* 总和
*/
private Double AccSumTotal=0.0;
/**
* 平方和
*/
private Double AccQuadraticSum=0.0;
/**
* 数据数量
*/
private int AccNum=0;
/**
* 存计算的结果
*/
private List<Double> AccResList=new ArrayList<>();
/**
* 添加累计结果
* @param one 质控结果
*/
public void AddAccRes(QCTestResultDto one)
{
Double res=Convert.ToDouble(one.Result,LastPara.Precision);
//累计只算非失控的
if(!one.DQIV_Status.equals("R"))
{
AccResList.add(res);
AccSumTotal+=res;
AccNum++;
}
}
/**
* 添加当前结果
* @param one 质控结果
*/
public void AddCalRes(QCTestResultDto one)
{
Double res=Convert.ToDouble(one.Result,LastPara.Precision);
//失控数
if(one.DQIV_Status.equals("R")) {
CalLossNum++;
if(one.HasDeal==true)
{
CalDealNum++;
}
}
//警告数
else if(one.DQIV_Status.equals("W")) {
CalWaringNum++;
if(one.HasDeal==true)
{
CalDealWNum++;
}
}
CalResList.add(res);
CalSumTotal+=res;
CalNum++;
//本月在控数据
if(!one.DQIV_Status.equals("R")) {
CalInResList.add(res);
CalInSumTotal+=res;
CalInNum++;
}
}
/**
* 计算月均值和累计均值等信息
* @return
*/
public HashMap GetCalRes()
{
//依次返回:计算值:均值、SD、CV、Min、Max、Num、ResStr 累计值:均值、SD、CV、Min、Max、Num、ResStr
HashMap hsRet=new HashMap();
hsRet.put("CalLossNum",CalLossNum);
hsRet.put("CalWaringNum",CalWaringNum);
hsRet.put("CalDealNum",CalDealNum);
if(CalNum>0) {
hsRet.put("CalLossRate", CalLossNum / CalNum);
}
else
{
hsRet.put("CalLossRate", "");
}
if(CalLossNum>0) {
hsRet.put("CalDealRate", CalDealNum / CalLossNum);
}
else
{
hsRet.put("CalDealRate", "");
}
if(CalLossNum>0) {
hsRet.put("CalWaringRate", CalWaringNum / CalNum);
}
else
{
hsRet.put("CalWaringRate", "");
}
if(CalWaringNum>0) {
hsRet.put("CalDealWRate", CalDealWNum / CalWaringNum);
}
else
{
hsRet.put("CalDealWRate", "");
}
hsRet.put("CalMean","");
hsRet.put("CalSD","");
hsRet.put("CalCV","");
hsRet.put("CalMin","");
hsRet.put("CalMax","");
hsRet.put("CalNum","");
hsRet.put("CalResStr","");
hsRet.put("CalInMean","");
hsRet.put("CalInSD","");
hsRet.put("CalInCV","");
hsRet.put("CalInMin","");
hsRet.put("CalInMax","");
hsRet.put("CalInNum","");
hsRet.put("CalInResStr","");
hsRet.put("AccMean","");
hsRet.put("AccSD","");
hsRet.put("AccCV","");
hsRet.put("AccMin","");
hsRet.put("AccMax","");
hsRet.put("AccNum","");
hsRet.put("AccResStr","");
hsRet.put("LastPara",LastPara);
if(CalNum>1) {
Double calAve = Convert.ToDouble(CalSumTotal / CalNum,LastPara.Precision);
if(calAve>0) {
Double maxVal=CalResList.get(0);
Double minVal=CalResList.get(0);
StringBuilder allResSB=new StringBuilder();
int index=-1;
for (Double res : CalResList) {
CalQuadraticSum += (res - calAve) * (res - calAve);
if(maxVal<res)
{
maxVal=res;
}
if(minVal>res)
{
minVal=res;
}
index++;
if(index==0)
{
allResSB.append(String.valueOf(res));
}
else
{
allResSB.append(","+String.valueOf(res));
}
}
Double SD = Convert.ToDouble(Math.sqrt(CalQuadraticSum / (CalNum - 1)),LastPara.Precision);
Double CV = Convert.ToDouble(SD / calAve * 100,LastPara.Precision);
hsRet.put("CalMean",Helper.FormatNumber(calAve,LastPara.Precision));
hsRet.put("CalSD",Helper.FormatNumber(SD,LastPara.Precision));
hsRet.put("CalCV",Helper.FormatNumber(CV,LastPara.Precision));
hsRet.put("CalMin",Helper.FormatNumber(minVal,LastPara.Precision));
hsRet.put("CalMax",Helper.FormatNumber(maxVal,LastPara.Precision));
hsRet.put("CalNum",String.valueOf(CalNum));
hsRet.put("CalResStr",allResSB.toString());
}
}
if(CalInNum>1) {
Double calAve = Convert.ToDouble(CalInSumTotal / CalInNum,LastPara.Precision);
if(calAve>0) {
Double maxVal=CalInResList.get(0);
Double minVal=CalInResList.get(0);
StringBuilder allResSB=new StringBuilder();
int index=-1;
for (Double res : CalInResList) {
CalInQuadraticSum += (res - calAve) * (res - calAve);
if(maxVal<res)
{
maxVal=res;
}
if(minVal>res)
{
minVal=res;
}
index++;
if(index==0)
{
allResSB.append(String.valueOf(res));
}
else
{
allResSB.append(","+String.valueOf(res));
}
}
Double SD = Convert.ToDouble(Math.sqrt(CalQuadraticSum / (CalNum - 1)),LastPara.Precision);
Double CV = Convert.ToDouble(SD / calAve * 100,LastPara.Precision);
hsRet.put("CalInMean",Helper.FormatNumber(calAve,LastPara.Precision));
hsRet.put("CalInSD",Helper.FormatNumber(SD,LastPara.Precision));
hsRet.put("CalInCV",Helper.FormatNumber(CV,LastPara.Precision));
hsRet.put("CalInMin",Helper.FormatNumber(minVal,LastPara.Precision));
hsRet.put("CalInMax",Helper.FormatNumber(maxVal,LastPara.Precision));
hsRet.put("CalInNum",String.valueOf(CalInNum));
hsRet.put("CalInResStr",allResSB.toString());
}
}
if(AccNum>1) {
Double accAve = Convert.ToDouble(AccSumTotal / AccNum,LastPara.Precision);
if(accAve>0) {
Double maxVal=AccResList.get(0);
Double minVal=AccResList.get(0);
StringBuilder allResSB=new StringBuilder();
int index=-1;
for (Double res : AccResList) {
AccQuadraticSum += (res - accAve) * (res - accAve);
if(maxVal<res)
{
maxVal=res;
}
if(minVal>res)
{
minVal=res;
}
index++;
if(index==0)
{
allResSB.append(String.valueOf(res));
}
else
{
allResSB.append(","+String.valueOf(res));
}
}
Double SD = Convert.ToDouble(Math.sqrt(AccQuadraticSum / (AccNum - 1)),LastPara.Precision);
Double CV = Convert.ToDouble(SD / accAve * 100,LastPara.Precision);
hsRet.put("AccMean",Helper.FormatNumber(accAve,LastPara.Precision));
hsRet.put("AccSD",Helper.FormatNumber(SD,LastPara.Precision));
hsRet.put("AccCV",Helper.FormatNumber(CV,LastPara.Precision));
hsRet.put("AccMin",Helper.FormatNumber(minVal,LastPara.Precision));
hsRet.put("AccMax",Helper.FormatNumber(maxVal,LastPara.Precision));
hsRet.put("AccNum",String.valueOf(CalNum));
hsRet.put("AccResStr",allResSB.toString());
}
}
return hsRet;
}
}
/**
* 查询质控浓度数据
*
* @return
*/
public String QueryQCLeaveData() throws Exception {
int MaterialDR = Helper.ValidParam(JRTContext.GetRequest(Request, "MaterialDR"), 0);
List<BTQCMaterialLevel> retList = EntityManager().FindByColVal(BTQCMaterialLevel.class, "MaterialDR", MaterialDR);
return Helper.Object2Json(retList);
}
/**
* 查询仪器的批号
* @return
* @throws Exception
*/
public String QryMachineLot() throws Exception
{
//返回的数据
List<String> retData = new ArrayList<>();
int MachineParameterDR = Helper.ValidParam(JRTContext.GetRequest(Request,"MachineParameterDR"), 0);
String MaterialDR = Helper.ValidParam(JRTContext.GetRequest(Request,"MaterialDR"), "");
int StartDate = Helper.ValidParam(JRTContext.GetRequest(Request,"StartDate"), 0);
int EndDate = Helper.ValidParam(JRTContext.GetRequest(Request,"EndDate"), 0);
//查询仪器的所有质控物
List<BTQCMaterial> matList=EntityManager().FindByColVal(BTQCMaterial.class,"MachineDR",MachineParameterDR);
//查询每个质控物下的项目
for(BTQCMaterial mat:matList) {
List<String> operators = new ArrayList<>();
HashParam hs = new HashParam();
hs.Add("MaterialDR", mat.RowID);
operators.add("=");
hs.Add("StartDate", StartDate);
operators.add("<=");
//先找小于开始日期的最近数据
List<BTQCMaterialTestCode> lastData = EntityManager().FindAllSimple(BTQCMaterialTestCode.class, hs, "StartDate desc", 1, null, operators);
//然后安装最近开始日期和结束日期找模板数据
List<String> operatorsFind = new ArrayList<>();
HashParam hsFind = new HashParam();
hsFind.Add("MaterialDR", mat.RowID);
operatorsFind.add("=");
//结束日期
hsFind.Add("StartDate", EndDate);
operatorsFind.add("<=");
List<String> joinerFind = new ArrayList<>();
if (lastData != null && lastData.size() > 0) {
joinerFind.add("and");
operatorsFind.add(">=");
//开始日期
hsFind.Add("StartDate", lastData.get(0).StartDate);
}
//目标数据
List<BTQCMaterialTestCodeDto> perData = EntityManager().FindAllSimple(BTQCMaterialTestCodeDto.class, hsFind, "StartDate asc", -1, joinerFind, operatorsFind);
HashMap map = new HashMap();
if (perData != null && perData.size() > 0) {
for (BTQCMaterialTestCodeDto one : perData) {
if (!map.containsKey(one.LotNo)) {
retData.add(one.LotNo);
map.put(one.LotNo, true);
}
}
}
}
return Helper.Object2Json(retData);
}
/**
* 查询工作组数据
*
* @return
*/
public String QueryWorkGroupData() throws Exception {
//得到用户的角色
List<SYSUserRoleDto> roleList = EntityManager().FindByColVal(SYSUserRoleDto.class, "UserDR", Convert.ToInt32(UserLogin().UserID));
if (roleList != null && roleList.size() > 0) {
for (SYSUserRoleDto one : roleList) {
BTWorkGroup wgDto = EntityManager().DolerGet(BTWorkGroup.class, one.WorkGroupDR);
one.WorkGroupName = wgDto.CName;
one.CurWorkGroupDR = UserLogin().GroupID;
}
}
return Helper.Object2Json(roleList);
}
/**
* 查询仪器
*
* @return
*/
public String QryMachineParameter() throws Exception {
int WorkGroupDR = Helper.ValidParam(JRTContext.GetRequest(Request, "WorkGroupDR"), 0);
List<BTWorkGroupMachine> wgmList = EntityManager().FindByColVal(BTWorkGroupMachine.class, "WorkGroupDR", WorkGroupDR);
List<BTMIMachineParameter> retList = new ArrayList<>();
if (wgmList != null && wgmList.size() > 0) {
for (BTWorkGroupMachine wgm : wgmList) {
//查询工作小组下的所有仪器
List<BTMIMachineParameter> machList = EntityManager().FindByColVal(BTMIMachineParameter.class, "WorkGroupMachineDR", wgm.RowID);
retList.addAll(machList);
}
}
return Helper.Object2Json(retList);
}
/**
* 查询仪器项目
*
* @return
*/
public String QryMachineTestCode() throws Exception {
int MachineParameterDR = Helper.ValidParam(JRTContext.GetRequest(Request, "MachineParameterDR"), 0);
int StartDate = Helper.ValidParam(JRTContext.GetRequest(Request, "StartDate"), 0);
int EndDate = Helper.ValidParam(JRTContext.GetRequest(Request, "EndDate"), 0);
//返回的数据
List<BTQCMaterialTestCodeDto> retData = new ArrayList<>();
//查询仪器的所有质控物
List<BTQCMaterial> matList=EntityManager().FindByColVal(BTQCMaterial.class,"MachineDR",MachineParameterDR);
//查询每个质控物下的项目
for(BTQCMaterial mat:matList) {
List<String> operators = new ArrayList<>();
HashParam hs = new HashParam();
hs.Add("MaterialDR", mat.RowID);
operators.add("=");
hs.Add("StartDate", StartDate);
operators.add("<=");
//先找小于开始日期的最近数据
List<BTQCMaterialTestCode> lastData = EntityManager().FindAllSimple(BTQCMaterialTestCode.class, hs, "StartDate desc", 1, null, operators);
List<String> operatorsFind = new ArrayList<>();
//然后安装最近开始日期和结束日期找模板数据
HashParam hsFind = new HashParam();
hsFind.Add("MaterialDR", mat.RowID);
operatorsFind.add("=");
//结束日期
hsFind.Add("StartDate", EndDate);
operatorsFind.add("<=");
List<String> joinerFind = new ArrayList<>();
if (lastData != null && lastData.size() > 0) {
joinerFind.add("and");
operatorsFind.add(">=");
//开始日期
hsFind.Add("StartDate", lastData.get(0).StartDate);
}
//目标数据
List<BTQCMaterialTestCodeDto> perData = EntityManager().FindAllSimple(BTQCMaterialTestCodeDto.class, hsFind, "StartDate asc", -1, joinerFind, operatorsFind);
HashMap map = new HashMap();
if (perData != null && perData.size() > 0) {
for (BTQCMaterialTestCodeDto one : perData) {
BTQCMaterial matDto = EntityManager().DolerGet(BTQCMaterial.class, one.MaterialDR);
one.MaterialName = matDto.CName;
BTTestCode tsDto = EntityManager().DolerGet(BTTestCode.class, one.TestCodeDR);
one.CName = tsDto.CName;
one.Code = tsDto.Code;
one.Synonym = tsDto.Synonym;
if (!map.containsKey(one.MaterialDR + "-" + one.TestCodeDR)) {
retData.add(one);
map.put(one.MaterialDR + "-" + one.TestCodeDR, true);
}
}
}
}
return Helper.Object2Json(retData);
}
/**
* 月报查询返回的实体
*/
public static class QCMonthRetDto extends QCResMaterialTestCode
{
/**
* 月报是否通过,月CV小于目标CV就是通过
*/
public String IsQualified="";
/**
* 质控物名称
*/
public String MatName="";
/**
* 年月
*/
public String YearMonth="";
/**
* 项目缩小
*/
public String Synonym="";
/**
* 项目名称
*/
public String TCName="";
/**
* 浓度名称
*/
public String LevelName="";
/**
* 计算均值
*/
public String CalMean="";
/**
* 计算SD
*/
public String CalSD="";
/**
* 计算CV
*/
public String CalCV="";
/**
* 计算最小值
*/
public String CalMin="";
/**
* 计算最大值
*/
public String CalMax="";
/**
* 计算数量
*/
public String CalNum="";
/**
* 计算结果串
*/
public String CalResStr="";
/**
* 在控数据计算均值
*/
public String CalInMean="";
/**
* 在控数据计算SD
*/
public String CalInSD="";
/**
* 在控数据计算CV
*/
public String CalInCV="";
/**
* 在控数据计算最小值
*/
public String CalInMin="";
/**
* 在控数据计算最大值
*/
public String CalInMax="";
/**
* 在控数据计算数量
*/
public String CalInNum="";
/**
* 在控数据计算结果串
*/
public String CalInResStr="";
/**
* 累计均值
*/
public String AccMean="";
/**
* 累计SD
*/
public String AccSD="";
/**
* 累计CV
*/
public String AccCV="";
/**
* 累计最小
*/
public String AccMin="";
/**
* 累计最大
*/
public String AccMax="";
/**
* 累计数量
*/
public String AccNum="";
/**
* 累计结果串
*/
public String AccResStr="";
/**
* 失控数量
*/
public String CalLossNum="";
/**
* 警告数量
*/
public String CalWaringNum="";
/**
* 处理数量
*/
public String CalDealNum="";
/**
* 失控率
*/
public String CalLossRate="";
/**
* 处理率
*/
public String CalDealRate="";
/**
* 警告率
*/
public String CalWaringRate="";
/**
* 警告处理率
*/
public String CalDealWRate="";
}
/**
* 查询批次项目实体
*/
public static class BTQCMaterialTestCodeDto extends BTQCMaterialTestCode {
/**
* 质控物名称
*/
public String MaterialName="";
/**
* 项目名称
*/
public String CName="";
/**
* 项目缩写
*/
public String Synonym="";
/**
* 项目代码
*/
public String Code="";
}
/**
* 角色查询实体
*/
public static class SYSUserRoleDto extends SYSUserRole {
//工作组名称
public String WorkGroupName="";
//当前工作组
public String CurWorkGroupDR="";
}
}