feat:报告数据算法调整

This commit is contained in:
FCL
2025-11-05 15:29:18 +08:00
parent 09ca90355d
commit a4105aef49
5 changed files with 169 additions and 14 deletions

View File

@@ -148,4 +148,10 @@ public interface QmsCommonConstant {
/** 品质控制 **/ /** 品质控制 **/
String ASSAY_PROJECT_USAGE_QUALITY_CONTROL = "quality_control"; String ASSAY_PROJECT_USAGE_QUALITY_CONTROL = "quality_control";
/** 检验完成状态-完成 **/
String CHECKED = "checked";
/** 检验完成状态-未完成 **/
String UNCHECKED = "unchecked";
} }

View File

@@ -7,6 +7,7 @@ import com.zt.plat.module.qms.business.bus.controller.vo.BusinessSampleEntrustRe
import com.zt.plat.module.qms.business.bus.controller.vo.BusinessSampleEntrustRegistrationPageReqVO; import com.zt.plat.module.qms.business.bus.controller.vo.BusinessSampleEntrustRegistrationPageReqVO;
import com.zt.plat.module.qms.business.bus.controller.vo.BusinessSampleEntrustRegistrationRespVO; import com.zt.plat.module.qms.business.bus.controller.vo.BusinessSampleEntrustRegistrationRespVO;
import com.zt.plat.module.qms.business.bus.controller.vo.BusinessSampleEntrustRegistrationSaveReqVO; import com.zt.plat.module.qms.business.bus.controller.vo.BusinessSampleEntrustRegistrationSaveReqVO;
import com.zt.plat.module.qms.enums.QmsCommonConstant;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
@@ -97,6 +98,7 @@ public class BusinessSampleEntrustRegistrationServiceImpl implements BusinessSam
@Override @Override
public PageResult<BusinessSampleEntrustRegistrationExtendRespVO> queryWaitingDataForReport(BusinessSampleEntrustRegistrationPageReqVO pageReqVO) { public PageResult<BusinessSampleEntrustRegistrationExtendRespVO> queryWaitingDataForReport(BusinessSampleEntrustRegistrationPageReqVO pageReqVO) {
IPage<BusinessSampleEntrustRegistrationDO> page = new Page<>(pageReqVO.getPageNo(), pageReqVO.getPageSize()); IPage<BusinessSampleEntrustRegistrationDO> page = new Page<>(pageReqVO.getPageNo(), pageReqVO.getPageSize());
pageReqVO.setAssayStatus(QmsCommonConstant.CHECKED);
Page<BusinessSampleEntrustRegistrationDO> pageList = businessSampleEntrustRegistrationMapper.queryWaitingDataForReport(page, pageReqVO); Page<BusinessSampleEntrustRegistrationDO> pageList = businessSampleEntrustRegistrationMapper.queryWaitingDataForReport(page, pageReqVO);
PageResult<BusinessSampleEntrustRegistrationDO> pageResult = new PageResult<>(pageList.getRecords(), pageList.getTotal()); PageResult<BusinessSampleEntrustRegistrationDO> pageResult = new PageResult<>(pageList.getRecords(), pageList.getTotal());
return BeanUtils.toBean(pageResult, BusinessSampleEntrustRegistrationExtendRespVO.class); return BeanUtils.toBean(pageResult, BusinessSampleEntrustRegistrationExtendRespVO.class);

View File

@@ -58,7 +58,7 @@ public class ReportDocumentDataController extends AbstractFileUploadController i
@Resource private ReportDocumentTypeService reportDocumentTypeService; @Resource private ReportDocumentTypeService reportDocumentTypeService;
/* /*
* 查询报告明细数据,返回结果包含报表字段配置、组装后的报告明细数据*/ * 查询报告明细数据,返回结果包含表头、数据、检出限等。会按报告配置进行“换行”处理。*/
@GetMapping("/queryReportDetail") @GetMapping("/queryReportDetail")
@Operation(summary = "查询报告明细数据") @Operation(summary = "查询报告明细数据")
@Parameter(name = "mainId", description = "报告id", required = true, example = "1024") @Parameter(name = "mainId", description = "报告id", required = true, example = "1024")

View File

@@ -49,6 +49,7 @@ public class ReportDocumentDataServiceImpl implements ReportDocumentDataService
private final String name_code_name = "name"; private final String name_code_name = "name";
private final String name_code_code = "code"; private final String name_code_code = "code";
private final String name_code_split = "split"; private final String name_code_split = "split";
private final String rangeKey = "minLimitValue";
@@ -58,7 +59,7 @@ public class ReportDocumentDataServiceImpl implements ReportDocumentDataService
@Override @Override
public CommonResult<List<JSONObject>> assembleDynamicData(ReportDocumentMainDO mainData, ReportDocumentTypeDO typeDO) { public CommonResult<List<JSONObject>> assembleDynamicData(ReportDocumentMainDO mainData, ReportDocumentTypeDO typeDO) {
if(typeDO == null || typeDO.getConfigReportTypeId() == null) if(typeDO == null || typeDO.getConfigReportTypeId() == null)
return CommonResult.error(REPORT_DOCUMENT_TYPE_NOT_EXISTS, "报告配置为空,或未配置报表类型,请联系管理员处理!"); return CommonResult.error(REPORT_DOCUMENT_TYPE_NOT_EXISTS.getCode(), "报告配置为空,或未配置报表类型,请联系管理员处理!");
String customConfig = typeDO.getCustomConfig(); String customConfig = typeDO.getCustomConfig();
//查询报表字段配置 //查询报表字段配置
ConfigReportFieldPageReqVO fieldParam = new ConfigReportFieldPageReqVO(); ConfigReportFieldPageReqVO fieldParam = new ConfigReportFieldPageReqVO();
@@ -66,7 +67,7 @@ public class ReportDocumentDataServiceImpl implements ReportDocumentDataService
fieldParam.setPageSize(9999); fieldParam.setPageSize(9999);
List<ConfigReportFieldDO> fieldListAll = configReportFieldService.getConfigReportFieldPage(fieldParam).getList(); List<ConfigReportFieldDO> fieldListAll = configReportFieldService.getConfigReportFieldPage(fieldParam).getList();
if(fieldListAll.isEmpty()) if(fieldListAll.isEmpty())
return CommonResult.error(REPORT_DOCUMENT_TYPE_NOT_EXISTS, "未配置报表字段,请联系管理员处理!"); return CommonResult.error(REPORT_DOCUMENT_TYPE_NOT_EXISTS.getCode(), "未配置报表字段,请联系管理员处理!");
List<ReportDocumentDataDO> dataList = listByMainDataId(mainData.getId()).getData(); List<ReportDocumentDataDO> dataList = listByMainDataId(mainData.getId()).getData();
//处理字段,提取有数据的字段 //处理字段,提取有数据的字段
List<ConfigReportFieldDO> fieldList = new ArrayList<>(); List<ConfigReportFieldDO> fieldList = new ArrayList<>();
@@ -97,14 +98,12 @@ public class ReportDocumentDataServiceImpl implements ReportDocumentDataService
//组装数据 //组装数据
List<JSONObject> step1Arr = assembleStep1(fieldList, dataList, customConfig); //处理后的组数对象 List<JSONObject> step1Arr = assembleStep1(fieldList, dataList, customConfig); //处理后的组数对象
//移除第一个元素
step1Arr.remove(0);
return CommonResult.success(step1Arr); return CommonResult.success(step1Arr);
} }
/** /**
* 将数据按colCount分组。返回2维数组 * 将数据按colCount分组。返回2维数组
* @param fieldList 处理过的字段列表。固定字段在最前 * @param fieldList 要显示的字段列表。固定字段在最前
* @param customConfig 报告配置项 * @param customConfig 报告配置项
* */ * */
private List<JSONObject> assembleStep1(List<ConfigReportFieldDO> fieldList, List<ReportDocumentDataDO> dataList, String customConfig){ private List<JSONObject> assembleStep1(List<ConfigReportFieldDO> fieldList, List<ReportDocumentDataDO> dataList, String customConfig){
@@ -112,11 +111,17 @@ public class ReportDocumentDataServiceImpl implements ReportDocumentDataService
Integer dynamicColCount = 3; Integer dynamicColCount = 3;
Integer fixedColCount = 3; Integer fixedColCount = 3;
Integer maxRowCount = 3; Integer maxRowCount = 3;
String dynamicColCountStr = jsonObject.getString("dynamicColCount"); String dynamicColCountStr = jsonObject.getString("dynamicColCount"); //动态列(检测项)数量
String fixedColCountStr = jsonObject.getString("fixedColCount"); String fixedColCountStr = jsonObject.getString("fixedColCount"); //固定列(样品名称、样品编号等)数量
String maxRowCountStr = jsonObject.getString("maxRowCount"); String maxRowCountStr = jsonObject.getString("maxRowCount"); //最大行数
String nameCodeType = jsonObject.getString("nameCodeType"); String nameCodeType = jsonObject.getString("nameCodeType"); //名称、编号处理方式merge-合并, name-只显示名称, code-只显示编号, split-2列分开显示
String hasRemark = jsonObject.getString("hasRemark"); String hasRemark = jsonObject.getString("hasRemark"); //是否有备注
String hasRange = jsonObject.getString("hasRange"); //是否有检出限
String align = jsonObject.getString("align"); //vertical-纵表, 否则为横表
if("vertical".equals(align)){
return assembleVerticalData(fieldList, dataList, customConfig);
}
if(!ObjectUtils.isEmpty(dynamicColCountStr)) dynamicColCount = Integer.parseInt(dynamicColCountStr); if(!ObjectUtils.isEmpty(dynamicColCountStr)) dynamicColCount = Integer.parseInt(dynamicColCountStr);
if(!ObjectUtils.isEmpty(fixedColCountStr)) fixedColCount = Integer.parseInt(fixedColCountStr); if(!ObjectUtils.isEmpty(fixedColCountStr)) fixedColCount = Integer.parseInt(fixedColCountStr);
@@ -133,32 +138,54 @@ public class ReportDocumentDataServiceImpl implements ReportDocumentDataService
Integer dataLength = dataList.size(); Integer dataLength = dataList.size();
Integer emptyRowCount = dataLength < maxRowCount ? 1 : 0; //空行数 Integer emptyRowCount = dataLength < maxRowCount ? 1 : 0; //空行数
Integer allRowCount = 1 + dataLength + emptyRowCount + 1; //标题 + 样品数 + 空行 Integer allRowCount = 1 + dataLength + emptyRowCount + 1; //标题 + 样品数 + 空行
if("1".equals(hasRange))
emptyRowCount ++;
if(rowCountOneSample > 1){ if(rowCountOneSample > 1){
allRowCount = (1 + dataLength + emptyRowCount + 9) * rowCountOneSample + emptyRowCount; //(标题 + 样品数 + 空行) * 但样品行数 + 末尾行 allRowCount = (1 + dataLength + emptyRowCount + 9) * rowCountOneSample + emptyRowCount; //(标题 + 样品数 + 空行) * 但样品行数 + 末尾行
} }
List<JSONObject> rowList = new ArrayList<>(Arrays.asList(new JSONObject[allRowCount + 1])); List<JSONObject> rowList = new ArrayList<>(Arrays.asList(new JSONObject[allRowCount + 1]));
//处理表头 //=============处理表头============
JSONObject t = new JSONObject(); JSONObject t = new JSONObject();
JSONObject r = new JSONObject(); //检出限
int rowAssist = 1; int rowAssist = 1;
int colIndex = fixedColCount + 1; int colIndex = fixedColCount + 1;
boolean lastObjFlag = true; boolean lastObjFlag = true;
//取第一行数据,用来处理检出限
JSONObject firstData = new JSONObject(); //取第一行数据,用于处理检出限
if(dataLength > 0)
firstData = JSONObject.parseObject(dataList.get(0).getDocumentContent());
if("1".equals(hasRemark)){ if("1".equals(hasRemark)){
//在最后一列增加备注 //在最后一列增加备注
t.put(colPrefix + parseNumToString(colCountOneSample + 1, 2), "备注"); t.put(colPrefix + parseNumToString(colCountOneSample + 1, 2), "备注");
} }
for(ConfigReportFieldDO fieldDO : fieldList){ for(ConfigReportFieldDO fieldDO : fieldList){
String fieldType = fieldDO.getFieldType(); String fieldType = fieldDO.getFieldType();
String field = fieldDO.getField();
if(FIELD_FIXED.equals(fieldType)){ //这里只处理动态列。固定列在 addTitleToRowList 处理 if(FIELD_FIXED.equals(fieldType)){ //这里只处理动态列。固定列在 addTitleToRowList 处理
continue; continue;
} }
String fieldName = fieldDO.getFieldName(); String fieldName = fieldDO.getFieldName();
String colKey = parseNumToString(colIndex, 2); String colKey = parseNumToString(colIndex, 2);
t.put(colPrefix + colKey, fieldName); t.put(colPrefix + colKey, fieldName);
//查询当前字段的检出限
JSONObject fieldObj = firstData.getJSONObject( field);
String rangeVal = "";
if(fieldObj != null){
rangeVal = fieldObj.getString(rangeKey);
}
r.put(colPrefix + colKey, rangeVal);
r.put(colPrefix + "01", "方法检出限");
lastObjFlag = true; lastObjFlag = true;
if(colIndex % colCountOneSample == 0){ if(colIndex % colCountOneSample == 0){
addTitleToRowList(nameCodeType, rowAssist, t, dataLength, emptyRowCount, rowList, fieldList); addTitleToRowList(nameCodeType, rowAssist, t, dataLength, emptyRowCount, rowList, fieldList);
if("1".equals(hasRange))
addRangeToRowList(rowAssist, r, dataLength, emptyRowCount, rowList);
t = new JSONObject(); t = new JSONObject();
r = new JSONObject();
if("1".equals(hasRemark)){ if("1".equals(hasRemark)){
//在最后一列增加备注 //在最后一列增加备注
t.put(colPrefix + parseNumToString(colCountOneSample + 1, 2), "备注"); t.put(colPrefix + parseNumToString(colCountOneSample + 1, 2), "备注");
@@ -166,13 +193,17 @@ public class ReportDocumentDataServiceImpl implements ReportDocumentDataService
rowAssist++; rowAssist++;
colIndex = fixedColCount + 1; //第二组以后,从固定列数开始 colIndex = fixedColCount + 1; //第二组以后,从固定列数开始
lastObjFlag = false; lastObjFlag = false;
continue;
} }
colIndex++; colIndex++;
} }
if(lastObjFlag){ if(lastObjFlag){
addTitleToRowList(nameCodeType, rowAssist, t, dataLength, emptyRowCount, rowList, fieldList); addTitleToRowList(nameCodeType, rowAssist, t, dataLength, emptyRowCount, rowList, fieldList);
if("1".equals(hasRange))
addRangeToRowList(rowAssist, r, dataLength, emptyRowCount, rowList);
} }
//处理数据
//=============处理数据============
int dataIndex = 1; int dataIndex = 1;
for(ReportDocumentDataDO dataDO : dataList){ for(ReportDocumentDataDO dataDO : dataList){
String documentContent = dataDO.getDocumentContent(); String documentContent = dataDO.getDocumentContent();
@@ -198,8 +229,13 @@ public class ReportDocumentDataServiceImpl implements ReportDocumentDataService
String colKey = parseNumToString(colIndex, 2); String colKey = parseNumToString(colIndex, 2);
JSONObject fieldObj = s.getJSONObject( field); JSONObject fieldObj = s.getJSONObject( field);
String fieldValue = ""; String fieldValue = "";
if(fieldObj != null) String mathSymbol = "";
if(fieldObj != null){
fieldValue = fieldObj.getString("fieldValue"); fieldValue = fieldObj.getString("fieldValue");
mathSymbol = fieldObj.getString("mathSymbol");
}
if(!ObjectUtils.isEmpty(mathSymbol) && !"=".equals(mathSymbol))
fieldValue = mathSymbol + fieldValue;
t.put(colPrefix + colKey, fieldValue); t.put(colPrefix + colKey, fieldValue);
lastObjFlag = true; lastObjFlag = true;
if(colIndex % colCountOneSample == 0){ if(colIndex % colCountOneSample == 0){
@@ -211,6 +247,7 @@ public class ReportDocumentDataServiceImpl implements ReportDocumentDataService
rowAssist++; rowAssist++;
colIndex = fixedColCount + 1; //第二组以后,从固定列数开始 colIndex = fixedColCount + 1; //第二组以后,从固定列数开始
lastObjFlag = false; lastObjFlag = false;
continue;
} }
colIndex++; colIndex++;
} }
@@ -219,6 +256,19 @@ public class ReportDocumentDataServiceImpl implements ReportDocumentDataService
} }
dataIndex ++; dataIndex ++;
} }
//==============以下为空白=================
//实际使用行数小于总行数,显示“”以下为空白“
if(dataIndex < maxRowCount){
String colKey = colPrefix + "01";
t = new JSONObject();
t.put(colKey, "以下为空白");
int rowIndex = (dataLength + emptyRowCount) * (rowAssist) + 1;
rowList.set(rowIndex + 1, t.clone());
}
//前面的计数是从1开始移除第一个元素
if(!rowList.isEmpty())
rowList.remove(0);
return rowList; return rowList;
} }
@@ -258,6 +308,17 @@ public class ReportDocumentDataServiceImpl implements ReportDocumentDataService
} }
rowList.set(rowIndex, t.clone()); rowList.set(rowIndex, t.clone());
} }
/**
* 处理检出限
* 如果是
* */
private void addRangeToRowList(Integer rowAssist, JSONObject r, Integer dataLength, Integer emptyRowCount, List<JSONObject> rowList){
int rowIndex = (dataLength + emptyRowCount + 1 ) * (rowAssist);
rowList.set(rowIndex, r.clone());
}
private void addDataToRowList(String nameCodeType, ReportDocumentDataDO dataDO, Integer rowAssist, JSONObject t, Integer dataLength, Integer emptyRowCount, Integer dataIndex, List<JSONObject> rowList, List<ConfigReportFieldDO> fieldList){ private void addDataToRowList(String nameCodeType, ReportDocumentDataDO dataDO, Integer rowAssist, JSONObject t, Integer dataLength, Integer emptyRowCount, Integer dataIndex, List<JSONObject> rowList, List<ConfigReportFieldDO> fieldList){
int rowIndex = (1 + dataLength + emptyRowCount) * (rowAssist - 1) + dataIndex + 1; //(标题 + 数据行 + 空行) int rowIndex = (1 + dataLength + emptyRowCount) * (rowAssist - 1) + dataIndex + 1; //(标题 + 数据行 + 空行)
t.put("id", dataDO.getId()); t.put("id", dataDO.getId());
@@ -306,6 +367,89 @@ public class ReportDocumentDataServiceImpl implements ReportDocumentDataService
return sb.append(num).toString(); return sb.append(num).toString();
} }
/**
* 组装纵表数据
* 第1列固定为元素 第2列方法检出限%);第三列开始为各个样品
* */
private List<JSONObject> assembleVerticalData(List<ConfigReportFieldDO> fieldList, List<ReportDocumentDataDO> dataList, String customConfig){
JSONObject jsonObject = JSONObject.parseObject(customConfig);
Integer dynamicColCount = 3;
Integer fixedColCount = 2;
Integer maxRowCount = 3;
String dynamicColCountStr = jsonObject.getString("dynamicColCount"); //动态列(检测项)数量
String fixedColCountStr = jsonObject.getString("fixedColCount"); //固定列(样品名称、样品编号等)数量
String maxRowCountStr = jsonObject.getString("maxRowCount"); //最大行数
String nameCodeType = jsonObject.getString("nameCodeType"); //名称、编号处理方式merge-合并, name-只显示名称, code-只显示编号, split-2列分开显示
String hasRemark = jsonObject.getString("hasRemark"); //是否有备注
String hasRange = jsonObject.getString("hasRange"); //是否有检出限
//取数据第一行,用于处理方法检出限
String content = "";
if(!ObjectUtils.isEmpty(dataList))
content = dataList.get(0).getDocumentContent();
JSONObject firstData = new JSONObject();
if(!ObjectUtils.isEmpty(content)){
firstData = JSONObject.parseObject(content);
}
List<JSONObject> rowList = new ArrayList<>();
//处理第一行-样品编号
int colIndex = fixedColCount + 1;
int rowIndex = 1;
JSONObject t = new JSONObject();
for(ReportDocumentDataDO dataDO : dataList){
String colKey = parseNumToString(colIndex, 2);
t.put(colPrefix + colKey, dataDO.getSampleCode());
colIndex++;
}
rowList.add(t);
//处理其他行
rowIndex = 1;
for(ConfigReportFieldDO fieldDO : fieldList) {
t = new JSONObject();
String fieldType = fieldDO.getFieldType();
String field = fieldDO.getField();
if (FIELD_FIXED.equals(fieldType)) { //这里只处理动态列。固定列在 addTitleToRowList 处理
continue;
}
String fieldName = fieldDO.getFieldName();
String colKey = "";
t.put(colPrefix + "01", fieldName); //第1列元素
if("1".equals(hasRange)){
//方法检出限
JSONObject fieldObj = firstData.getJSONObject( field);
String rangeVal = "";
if(fieldObj != null){
rangeVal = fieldObj.getString(rangeKey);
}
t.put(colPrefix + "02", rangeVal); //第2列检出限
}
colIndex = fixedColCount + 1;
for(ReportDocumentDataDO dataDO : dataList){
colKey = parseNumToString(colIndex, 2);
content = dataDO.getDocumentContent();
JSONObject dataJson = new JSONObject();
if(!ObjectUtils.isEmpty(content)){
dataJson = JSONObject.parseObject(content);
}
JSONObject fieldObj = firstData.getJSONObject( field);
String fieldValue = "";
String mathSymbol = "";
if(fieldObj != null){
fieldValue = fieldObj.getString("fieldValue");
mathSymbol = fieldObj.getString("mathSymbol");
}
if(!ObjectUtils.isEmpty(mathSymbol) && !"=".equals(mathSymbol))
fieldValue = mathSymbol + fieldValue;
t.put(colPrefix + colKey, fieldValue);
colIndex++;
}
rowList.add(t);
rowIndex ++;
}
return rowList;
}
@Override @Override
public CommonResult<List<ReportDocumentDataDO>> listByMainDataId(Long mainDataId) { public CommonResult<List<ReportDocumentDataDO>> listByMainDataId(Long mainDataId) {
QueryWrapper<ReportDocumentDataDO> queryWrapper = new QueryWrapper<>(); QueryWrapper<ReportDocumentDataDO> queryWrapper = new QueryWrapper<>();

View File

@@ -65,6 +65,9 @@
select 1 from T_RPT_DOC_MAIN dm left join T_RPT_DOC_MAIN_CORR dc on dm.id = dc.MAIN_ID select 1 from T_RPT_DOC_MAIN dm left join T_RPT_DOC_MAIN_CORR dc on dm.id = dc.MAIN_ID
where dc.CORR_ID = m.id and dm.FLW_STS in ('not_start','in_progress','completed','rejected') and dm.deleted = 0 where dc.CORR_ID = m.id and dm.FLW_STS in ('not_start','in_progress','completed','rejected') and dm.deleted = 0
) )
<if test="param.assayStatus != null and param.assayStatus != ''">
and m.ASY_STS = #{param.assayStatus}
</if>
<if test="param.entrustType != null and param.entrustType != ''"> <if test="param.entrustType != null and param.entrustType != ''">
and m.ENTT_TP = #{param.entrustType} and m.ENTT_TP = #{param.entrustType}
</if> </if>