SimplePackageResolver.java 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. package com.yihu.ehr.resolve;
  2. import com.fasterxml.jackson.databind.JsonNode;
  3. import com.fasterxml.jackson.databind.node.ArrayNode;
  4. import com.fasterxml.jackson.databind.node.ObjectNode;
  5. import com.yihu.ehr.profile.exception.IllegalJsonDataException;
  6. import com.yihu.ehr.profile.exception.IllegalJsonFileException;
  7. import com.yihu.ehr.profile.exception.LegacyPackageException;
  8. import com.yihu.ehr.profile.model.MetaDataRecord;
  9. import com.yihu.ehr.profile.model.PackageDataSet;
  10. import com.yihu.ehr.resolve.config.EventIndexConfig;
  11. import com.yihu.ehr.resolve.dao.DataSetPackageDao;
  12. import com.yihu.ehr.resolve.log.PackResolveLogger;
  13. import com.yihu.ehr.resolve.model.stage1.OriginalPackage;
  14. import com.yihu.ehr.resolve.model.stage1.SimplePackage;
  15. import com.yihu.ehr.util.datetime.DateTimeUtil;
  16. import org.springframework.beans.factory.annotation.Autowired;
  17. import org.springframework.jdbc.core.JdbcTemplate;
  18. import org.springframework.stereotype.Component;
  19. import java.io.File;
  20. import java.io.IOException;
  21. import java.text.ParseException;
  22. import java.util.*;
  23. /**
  24. * 数据集(非档案类型)档案包解析器.
  25. *
  26. * @author 张进军
  27. * @created 2017.06.27 11:28
  28. */
  29. @Component
  30. public class SimplePackageResolver extends PackageResolver {
  31. @Autowired
  32. private JdbcTemplate jdbcTemplate;
  33. @Autowired
  34. private EventIndexConfig eventIndex;
  35. @Autowired
  36. private DataSetPackageDao dataSetPackageDao;
  37. @Override
  38. public void resolve(OriginalPackage originalPackage, File root) throws Exception {
  39. File originFolder = new File(root.getAbsolutePath());
  40. this.parseFiles((SimplePackage) originalPackage, originFolder.listFiles());
  41. }
  42. /**
  43. * 解析 .json 文件中的 JSON 数据,拼接成SQL语句
  44. * @param simplePackage
  45. * @param files
  46. * @throws IOException
  47. * @throws ParseException
  48. */
  49. private void parseFiles(SimplePackage simplePackage, File[] files) throws IOException, ParseException {
  50. List<String> sqlList = new ArrayList<>();
  51. for (File file : files) {
  52. // head 节点
  53. JsonNode headNode = objectMapper.readTree(file).get("head");
  54. String transactionId = headNode.get("id").asText();
  55. String orgCode = headNode.get("orgCode").asText();
  56. String version = headNode.get("version").asText();
  57. String sourceTable = headNode.get("source").asText();
  58. String targetTable = headNode.get("target").asText();
  59. String createTime = headNode.get("createTime").asText();
  60. // data 节点
  61. JsonNode dataNode = objectMapper.readTree(file).get("data");
  62. String tableName = dataNode.get("table").get("name").asText();
  63. String[] pkArr = dataNode.get("table").get("pk").asText().split(",");
  64. // columns 节点
  65. JsonNode columnsNode = dataNode.get("columns");
  66. // rows 节点
  67. JsonNode rowsNode = dataNode.get("rows");
  68. // 判断标准版本是否存在。
  69. String isExistVersionSql = "SELECT 1 FROM std_cda_versions WHERE version = '" + version + "'";
  70. if (jdbcTemplate.queryForList(isExistVersionSql).size() == 0) {
  71. throw new IllegalJsonDataException("标准版本号不存在,version: " + version);
  72. }
  73. // 判断表是否存在。
  74. String isExistTableSql = "SELECT 1 FROM std_data_set_" + version + " WHERE code = '" + tableName + "'";
  75. if (jdbcTemplate.queryForList(isExistTableSql).size() == 0) {
  76. throw new IllegalJsonDataException("标准中不存在该表,version: " + version + ", table: " + tableName);
  77. }
  78. // 拼接 insert/update 语句,后续批量执行保存数据。
  79. for (int i = 0, length = rowsNode.size(); i < length; i++) {
  80. JsonNode rowNode = rowsNode.get(i);
  81. // 用于记录日志:日志JSON结构中的data子节点。
  82. ObjectNode logDataNode = objectMapper.createObjectNode();
  83. ObjectNode logDataTargetIdNode = objectMapper.createObjectNode();
  84. logDataNode.put("transactionId", transactionId);
  85. logDataNode.put("target", targetTable);
  86. logDataNode.set("source_id", rowNode.get("_id"));
  87. // 判断是 insert,还是 update。
  88. StringBuffer hasRecordSql = new StringBuffer(" SELECT 1 FROM " + tableName + " WHERE ");
  89. for (String pk : pkArr) {
  90. String pkValue = rowNode.get(pk).asText();
  91. hasRecordSql.append(pk + " = '" + pkValue + "' AND ");
  92. logDataTargetIdNode.put(pk, pkValue);
  93. }
  94. logDataNode.set("target_id", logDataTargetIdNode);
  95. PackResolveLogger.info(logDataNode.toString());
  96. int hasRecordSqlLen = hasRecordSql.length();
  97. hasRecordSql.delete(hasRecordSqlLen - 4, hasRecordSqlLen);
  98. boolean isInsert = jdbcTemplate.queryForList(hasRecordSql.toString()).size() == 0 ? true : false;
  99. StringBuffer sql = new StringBuffer();
  100. if (isInsert) {
  101. sql.append(" INSERT INTO " + tableName + " SET ");
  102. } else {
  103. sql.append(" UPDATE " + tableName + " SET ");
  104. }
  105. for (JsonNode column : columnsNode) {
  106. if (rowNode == null){
  107. System.out.println("/////////");
  108. }
  109. String fieldName = column.get("column")== null ? "": column.get("column").asText();
  110. String fieldValue = rowNode.get(fieldName)== null ? "" : rowNode.get(fieldName).asText();
  111. // 判断表字段是否存在。
  112. String fieldSql = "SELECT f.column_type AS column_type FROM std_meta_data_" + version + " f " +
  113. "LEFT JOIN std_data_set_" + version + " t ON t.id = f.dataset_id " +
  114. "WHERE t.code = '" + tableName + "' AND f.column_name = '" + fieldName + "'";
  115. if (jdbcTemplate.queryForList(fieldSql).size() == 0) {
  116. throw new IllegalJsonDataException("标准中不存在该表字段的字段类型,version: " + version + ", table: " + tableName + ", field: " + fieldName);
  117. }
  118. // 判断字段类型
  119. String columnType = jdbcTemplate.queryForMap(fieldSql).get("column_type").toString().toUpperCase();
  120. if (columnType.contains("VARCHAR")) {
  121. sql.append(fieldName + " = '" + fieldValue + "', ");
  122. } else if (columnType.equals("TINYINT") || columnType.contains("NUMBER")) {
  123. sql.append(fieldName + " = " + fieldValue + ", ");
  124. } else if (columnType.equals("DATE")) {
  125. sql.append(fieldName + " = '" + DateTimeUtil.simpleDateFormat(DateTimeUtil.simpleDateParse(fieldValue)) + "', ");
  126. } else if (columnType.equals("DATETIME")) {
  127. sql.append(fieldName + " = '" + DateTimeUtil.simpleDateTimeFormat(DateTimeUtil.utcDateTimeParse(fieldValue)) + "', ");
  128. }
  129. }
  130. sql.deleteCharAt(sql.lastIndexOf(","));
  131. if (!isInsert) {
  132. sql.append(" WHERE ");
  133. for (String pk : pkArr) {
  134. sql.append(pk + " = '" + rowNode.get(pk).asText() + "' AND ");
  135. }
  136. int sqlLen = sql.length();
  137. sql.delete(sqlLen - 4, sqlLen);
  138. }
  139. sql.append(";");
  140. sqlList.add(sql.toString());
  141. }
  142. simplePackage.setOrgCode(orgCode);
  143. simplePackage.setCreateDate(DateTimeUtil.utcDateTimeParse(createTime));
  144. }
  145. simplePackage.setSqlList(sqlList);
  146. dataSetPackageDao.saveDataset(simplePackage);//执行sql操作
  147. }
  148. /**
  149. * 生产数据集
  150. *
  151. * @param jsonFile
  152. * @param isOrigin
  153. * @return
  154. * @throws IOException
  155. */
  156. private List<PackageDataSet> generateDataSet(File jsonFile, boolean isOrigin) throws IOException {
  157. JsonNode jsonNode = objectMapper.readTree(jsonFile);
  158. if (jsonNode.isNull()) {
  159. throw new IllegalJsonFileException("Invalid json file when generate data set");
  160. }
  161. List<PackageDataSet> dataSets = parseNonArchiveJsonDataSet(jsonNode);
  162. return dataSets;
  163. }
  164. /**
  165. * TODO 未完整逻辑,返回列表
  166. * add by HZY at 2017/07/03
  167. * (非档案类型)结构化档案包数据集处理
  168. *
  169. * @param root
  170. * @return
  171. */
  172. public List<PackageDataSet> parseNonArchiveJsonDataSet(JsonNode root) {
  173. List<PackageDataSet> packageDataSetList = new ArrayList<>();
  174. PackageDataSet dataSet;
  175. JsonNode head = root.get("head");//文件内容头信息
  176. JsonNode data = root.get("data");//文件内容主体信息
  177. String version = head.get("version").asText();
  178. if (version.equals("000000000000")) {
  179. throw new LegacyPackageException("Package is collected via cda version 00000000000, ignored.");
  180. }
  181. String dataSetCode = head.get("target").asText();
  182. String createTime = head.get("createTime").isNull() ? "" : head.get("createTime").asText();
  183. String orgCode = head.get("orgCode").asText();
  184. final String[] eventNo = {""};
  185. final String[] patientId = {""};
  186. final String[] eventTime = {""}; // 旧数据集结构可能不存在这个属性
  187. JsonNode table = data.get("table");//表
  188. List<String> pkList = Arrays.asList(table.path("pk").asText().split(","));//主键字段
  189. ArrayNode columns = (ArrayNode) data.get("columns");//列名
  190. ArrayNode rows = (ArrayNode) data.get("rows");//列值
  191. //获取索引字段
  192. columns.forEach(item -> {
  193. //事件号字段获取
  194. if (eventIndex.getEventNo().contains(item.get("column").asText())){
  195. eventNo[0] = item.get("column").asText();
  196. }
  197. //病人ID字段获取
  198. if (eventIndex.getPatientId().contains(item.get("column").asText())){
  199. patientId[0] = item.get("column").asText();
  200. }
  201. //时间时间获取
  202. if (eventIndex.getEventTime().contains(item.get("column").asText())){
  203. eventTime[0] = item.path("column").isNull() ? "" : item.path("column").asText(); // 旧数据集结构可能不存在这个属性
  204. }
  205. });
  206. StringBuffer pkBuffer = new StringBuffer();
  207. for (int i = 0; i < rows.size(); ++i) {
  208. JsonNode recordNode = rows.get(i);
  209. try {
  210. dataSet = new PackageDataSet();
  211. dataSet.setPatientId(recordNode.path(patientId[0]).asText());
  212. dataSet.setEventNo(recordNode.path(eventNo[0]).asText());
  213. dataSet.setCdaVersion(version);
  214. dataSet.setCode(dataSetCode);
  215. dataSet.setOrgCode(orgCode);
  216. dataSet.setEventTime(DateTimeUtil.simpleDateParse(recordNode.path(eventTime[0]).asText()));
  217. dataSet.setCreateTime(DateTimeUtil.simpleDateParse(createTime));
  218. MetaDataRecord record = new MetaDataRecord();
  219. Iterator<Map.Entry<String, JsonNode>> iterator = recordNode.fields();
  220. while (iterator.hasNext()) {
  221. Map.Entry<String, JsonNode> item = iterator.next();
  222. String metaData = item.getKey();
  223. if (metaData.equals("EVENT_NO")) continue; //metaData.equals("PATIENT_ID") ||
  224. if (metaData.equals("_id")) continue;//源表主键字段名
  225. String value = item.getValue().asText().equals("null") ? "" : item.getValue().asText();
  226. record.putMetaData(metaData, value);
  227. if (pkList != null && pkList.contains(metaData)){
  228. pkBuffer.append(value).append("_");
  229. }
  230. }
  231. dataSet.setPk(pkBuffer.toString());
  232. dataSet.addRecord(Integer.toString(i), record);
  233. packageDataSetList.add(dataSet);
  234. } catch (NullPointerException e) {
  235. throw new IllegalJsonDataException("Null pointer occurs while generate data set, package cda version: " + version);
  236. } catch (ParseException e) {
  237. throw new IllegalJsonDataException("Invalid date time format, do not deal with fail-tolerant.");
  238. }
  239. }
  240. return packageDataSetList;
  241. }
  242. }