ReportUtil.java 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. package thyyxxk.webserver.utils;
  2. import org.jetbrains.annotations.NotNull;
  3. import thyyxxk.webserver.entity.highreport.HighReportDto;
  4. import thyyxxk.webserver.entity.highreport.ReportBaseInfo;
  5. import thyyxxk.webserver.entity.highreport.TableGroupInfo;
  6. import thyyxxk.webserver.entity.targetmanagement.TargetManagement;
  7. import java.util.Date;
  8. import java.util.HashMap;
  9. import java.util.Map;
  10. /**
  11. * @Description: 报表相关的工具类
  12. * @Author: hsh
  13. * @CreateTime: 2022-11-04 08:34
  14. * @Version: 1.0
  15. */
  16. public class ReportUtil {
  17. private static final String START_TIME = ":startTime";
  18. private static final String END_TIME = ":endTime";
  19. /**
  20. * 险种(下拉选查询使用)
  21. **/
  22. private static final String INSUR_NAME = "insurName";
  23. /**
  24. * 科室(下拉选查询使用)
  25. **/
  26. private static final String DEPT = "dept";
  27. /**
  28. * 医生(下拉选查询使用)
  29. **/
  30. private static final String DOCTOR = "doctor";
  31. /**
  32. * 诊断(模糊查询使用)
  33. **/
  34. private static final String DIAGN = "diagn";
  35. /**
  36. * 住院号
  37. **/
  38. private static final String ZYH = "zyh";
  39. /**
  40. * 姓名(模糊查询使用)
  41. **/
  42. private static final String XM = "xm";
  43. /**
  44. * 号别(下拉选查询使用)
  45. **/
  46. private static final String REG_LEVEL = "regLevel";
  47. private static final String OTHER_PARAM = "其他";
  48. /**
  49. * 手工指标值(固定填写的值)
  50. **/
  51. public static final String SG = "sg";
  52. /**
  53. * @description: 拼接查询数据的sql(备注:采用了script标签包裹方式拼接sql)
  54. * @author: hsh
  55. * @date: 2022/11/7 16:21
  56. * @param: [dto 查询条件, baseSql 基础sql, gatherSql 聚合sql, groupColumn 分组sql字段, dropSql 钻取条件sql, sortSql 排序sql]
  57. * @return: String
  58. **/
  59. public static @NotNull String callSqlFormat(HighReportDto dto, @NotNull String baseSql, String gatherSql, String groupColumn, String dropSql, String sortSql){
  60. // 查询必填字段(包括开始时间,结束时间,钻取科室,医生等sql用:拼接的字符)替换
  61. baseSql = getTimeString(dto, baseSql);
  62. // 查询非必填字段(一般是下拉选险种,模糊查询科室、诊断等sql用_拼接的字符)
  63. StringBuilder sql = new StringBuilder();
  64. sql.append(" select ").append(gatherSql).append(" from (").append(baseSql).append(") t where 1 = 1 ");
  65. if(baseSql.contains(DEPT) && StringUtil.notBlank(dto.getDept())){
  66. sql.append(" and t.dept = '").append(dto.getDept()).append("' ");
  67. }
  68. if(baseSql.contains(DOCTOR) && StringUtil.notBlank(dto.getDoctor())){
  69. sql.append(" and t.doctor = '").append(dto.getDoctor()).append("' ");
  70. }
  71. if(baseSql.contains(INSUR_NAME) && StringUtil.notBlank(dto.getInsurName())){
  72. sql.append(" and t.insurName = '").append(dto.getInsurName()).append("' ");
  73. }
  74. if(baseSql.contains(REG_LEVEL) && StringUtil.notBlank(dto.getRegLevel())){
  75. sql.append(" and t.regLevel = '").append(dto.getRegLevel()).append("' ");
  76. }
  77. if(baseSql.contains(DIAGN) && StringUtil.notBlank(dto.getDiagn())){
  78. sql.append(" and t.diagn like '%").append(dto.getDiagn()).append("%' ");
  79. }
  80. if(baseSql.contains(ZYH) && StringUtil.notBlank(dto.getZyh())){
  81. sql.append(" and t.zyh = '").append(dto.getZyh()).append("' ");
  82. }
  83. if(baseSql.contains(XM) && StringUtil.notBlank(dto.getXm())){
  84. sql.append(" and t.xm like '%").append(dto.getXm()).append("%' ");
  85. }
  86. // 存在钻取,需要添加钻取条件
  87. if(StringUtil.notBlank(dropSql)){
  88. sql.append(dropSql);
  89. }
  90. // 如果存在分组情况,需要添加分组sql字段
  91. if(StringUtil.notBlank(groupColumn)){
  92. sql.append(" group by t.").append(groupColumn);
  93. }
  94. // 如果存在默认排序,需要添加排序sql
  95. if(StringUtil.notBlank(sortSql)){
  96. sql.append(" order by t.").append(sortSql);
  97. }
  98. return sql.toString();
  99. }
  100. /**
  101. * @description: 钻取分组查询数据
  102. * @author: hsh
  103. * @date: 2022/11/16 14:20
  104. * @param: [dto, report, info, isPatient] isPatient: 是否是病人这一层查询
  105. * @return: String
  106. **/
  107. public static String callSqlFormatByGroup(HighReportDto dto, ReportBaseInfo report, TableGroupInfo info, boolean isPatient) {
  108. // 获取分组查询条件
  109. String groupColumn = info.getFstGroup();
  110. String gatherMainSql = report.getGatherSql();
  111. StringBuilder dropSql = new StringBuilder();
  112. StringBuilder gatherSql = new StringBuilder();
  113. if (StringUtil.notBlank(info.getFthGroup()) && StringUtil.notBlank(dto.getTrdName())) {
  114. groupColumn = info.getFthGroup();
  115. if(OTHER_PARAM.equals(dto.getFstName())){
  116. callIsNotMatchData(dropSql, info.getFstGroup(), null, true);
  117. } else {
  118. callIsNotMatchData(dropSql, info.getFstGroup(), dto.getFstName(), false);
  119. }
  120. if(OTHER_PARAM.equals(dto.getSndName())){
  121. callIsNotMatchData(dropSql, info.getSndGroup(), null, true);
  122. } else {
  123. callIsNotMatchData(dropSql, info.getSndGroup(), dto.getSndName(), false);
  124. }
  125. if(OTHER_PARAM.equals(dto.getTrdName())){
  126. callIsNotMatchData(dropSql, info.getTrdGroup(), null, true);
  127. } else {
  128. callIsNotMatchData(dropSql, info.getTrdGroup(), dto.getTrdName(), false);
  129. }
  130. } else if (StringUtil.notBlank(info.getTrdGroup()) && StringUtil.notBlank(dto.getSndName())) {
  131. groupColumn = info.getTrdGroup();
  132. if(OTHER_PARAM.equals(dto.getFstName())){
  133. callIsNotMatchData(dropSql, info.getFstGroup(), null, true);
  134. } else {
  135. callIsNotMatchData(dropSql, info.getFstGroup(), dto.getFstName(), false);
  136. }
  137. if(OTHER_PARAM.equals(dto.getSndName())){
  138. callIsNotMatchData(dropSql, info.getSndGroup(), null, true);
  139. } else {
  140. callIsNotMatchData(dropSql, info.getSndGroup(), dto.getSndName(), false);
  141. }
  142. } else if (StringUtil.notBlank(info.getSndGroup()) && StringUtil.notBlank(dto.getFstName())) {
  143. groupColumn = info.getSndGroup();
  144. if(OTHER_PARAM.equals(dto.getFstName())){
  145. callIsNotMatchData(dropSql, info.getFstGroup(), null, true);
  146. } else {
  147. callIsNotMatchData(dropSql, info.getFstGroup(), dto.getFstName(), false);
  148. }
  149. } else {
  150. dropSql.setLength(0);
  151. }
  152. if(isPatient){
  153. // 查询病人不需要分组sql,也不需要聚合函数,需要查询显示所有列并带上钻取条件即可
  154. gatherSql.append(" t.* ");
  155. return callSqlFormat(dto, report.getBaseSql(), gatherSql.toString(), null, dropSql.toString(), report.getReportSort());
  156. } else {
  157. gatherSql.append("isnull(rtrim(").append(groupColumn).append("), '").append(OTHER_PARAM).append("') as x, ").append(gatherMainSql).append(" as y ");
  158. return callSqlFormat(dto, report.getBaseSql(), gatherSql.toString(), groupColumn, dropSql.toString(), report.getReportSort());
  159. }
  160. }
  161. /**
  162. * @description: 查询条件中出现参数是空或者是null的情况(前端传来的参数是其他)sql拼接处理
  163. * @author: hsh
  164. * @date: 2022/11/17 9:44
  165. * @param: [sql, column, param, isNotMatchParam]
  166. * sql: 拼接sql;column: 查询条件字段;param: 查询条件值;isNotMatchParam: true表示前端传来的参数是其他即实际是没有值
  167. * @return: void
  168. **/
  169. private static void callIsNotMatchData(StringBuilder sql, String column, String param, boolean isNotMatchParam) {
  170. if(isNotMatchParam){
  171. sql.append(" and (t.").append(column).append(" is null or ").append(" t.").append(column).append(" = '') ");
  172. } else {
  173. sql.append(" and t.").append(column).append(" = '").append(param).append("' ");
  174. }
  175. }
  176. /**
  177. * @description: 指标字典定义的sql条件转换
  178. * @author: hsh
  179. * @date: 2023/6/13 10:47
  180. * @param: [dto]
  181. * @return: void
  182. **/
  183. public static void callSqlFormatTarget(TargetManagement dto){
  184. String sqlChild = dto.getCalcChild();
  185. String sqlMom = dto.getCalcMom();
  186. if(sqlChild.contains(START_TIME)){
  187. if(StringUtil.notBlank(dto.getStartTime())){
  188. sqlChild = sqlChild.replaceAll(START_TIME, "'" + dto.getStartTime() + "'");
  189. } else {
  190. sqlChild = sqlChild.replaceAll(START_TIME, "'" + DateUtil.getDayStartTime(new Date()) + "'");
  191. }
  192. }
  193. if(sqlChild.contains(END_TIME)){
  194. if(StringUtil.notBlank(dto.getEndTime())){
  195. sqlChild = sqlChild.replaceAll(END_TIME, "'" + dto.getEndTime() + "'");
  196. } else {
  197. sqlChild = sqlChild.replaceAll(END_TIME, DateUtil.getDayEndTime(new Date()));
  198. }
  199. }
  200. if (StringUtil.notBlank(sqlMom)) {
  201. if(sqlMom.contains(START_TIME)){
  202. if(StringUtil.notBlank(dto.getStartTime())){
  203. sqlMom = sqlMom.replaceAll(START_TIME, "'" + dto.getStartTime() + "'");
  204. } else {
  205. sqlMom = sqlMom.replaceAll(START_TIME, "'" + DateUtil.getDayStartTime(new Date()) + "'");
  206. }
  207. }
  208. if(sqlMom.contains(END_TIME)){
  209. if(StringUtil.notBlank(dto.getEndTime())){
  210. sqlMom = sqlMom.replaceAll(END_TIME, "'" + dto.getEndTime() + "'");
  211. } else {
  212. sqlMom = sqlMom.replaceAll(END_TIME, DateUtil.getDayEndTime(new Date()));
  213. }
  214. }
  215. }
  216. dto.setCalcChild(sqlChild);
  217. dto.setCalcMom(sqlMom);
  218. }
  219. /**
  220. * @description: 根据指标字典sql信息组装指标报表信息
  221. * @author: hsh
  222. * @date: 2023/7/3 14:44
  223. * @param: [dto]
  224. * @return: Map<String,List<ReportBaseInfo>>
  225. **/
  226. public static Map<String, ReportBaseInfo> assertReportForTarget(TargetManagement dto){
  227. Map<String, ReportBaseInfo> map = new HashMap<>();
  228. ReportBaseInfo report = new ReportBaseInfo();
  229. if(StringUtil.notBlank(dto.getCalcChild()) && !dto.getCalcChild().contains("/")){
  230. report.setReportId(dto.getChildId());
  231. report.setReportName(dto.getChildName());
  232. report.setBaseSql(dto.getCalcChild());
  233. report.setGatherSql(dto.getChildGather());
  234. report.setLevel("group_zb");
  235. report.setMenuId("777");
  236. report.setReportType("zb");
  237. report.setFlag("Y");
  238. report.setDisplayType("mx");
  239. map.put("calcChild", report);
  240. }
  241. if(StringUtil.notBlank(dto.getCalcMom()) && !dto.getCalcMom().contains("/")){
  242. report = new ReportBaseInfo();
  243. report.setReportId(dto.getMomId());
  244. report.setReportName(dto.getMomName());
  245. report.setBaseSql(dto.getCalcMom());
  246. report.setGatherSql(dto.getMomGather());
  247. report.setLevel("group_zb");
  248. report.setMenuId("777");
  249. report.setReportType("zb");
  250. report.setFlag("Y");
  251. report.setDisplayType("mx");
  252. map.put("calcMom", report);
  253. }
  254. return map;
  255. }
  256. /**
  257. * @description: 实体查询条件转换(历史条件原因)
  258. * @author: hsh
  259. * @date: 2023/7/17 16:43
  260. * @param: [dto]
  261. * @return: HighReportDto
  262. **/
  263. public static HighReportDto TargetManagementConvertHighReportDto(TargetManagement dto){
  264. HighReportDto d = new HighReportDto();
  265. d.setStartTime(dto.getStartTime());
  266. d.setEndTime(dto.getEndTime());
  267. return d;
  268. }
  269. /**
  270. * @description: 验证sql是否正确
  271. * @author: hsh
  272. * @date: 2023/7/12 10:32
  273. * @param: [sql, isValid]
  274. * @return: String
  275. **/
  276. public static String sqlCheckAndVerifyByKeyword(String sql){
  277. if(sql.contains("drop") || sql.contains("truncate") || sql.contains("delete") || sql.contains("update")
  278. || sql.contains("DROP") || sql.contains("TRUNCATE") || sql.contains("DELETE") || sql.contains("UPDATE")){
  279. return "sql语句存在非查询语句关键字,请检查!";
  280. }
  281. return "";
  282. }
  283. /**
  284. * @Description 报表sql中关键字替换
  285. * @Author hsh
  286. * @param dto 查询条件
  287. * @param sql 统计sql
  288. * @return sql 统计sql
  289. * @Date 2024/8/19 14:46
  290. */
  291. public static String sqlFormat(HighReportDto dto, String sql){
  292. // 查询必填字段(包括开始时间,结束时间)替换
  293. sql = getTimeString(dto, sql);
  294. // 存在dept的查询条件
  295. if(StringUtil.notBlank(dto.getDept())){
  296. sql = sql.replaceAll("::ward_code", "and t.ward_code = '" + dto.getDept() + "' ");
  297. sql = sql.replaceAll("::exec_unit", "and t.exec_unit = '" + dto.getDept() + "' ");
  298. sql = sql.replaceAll("::dept", "and t.dept = '" + dto.getDept() + "' ");
  299. } else {
  300. sql = sql.replaceAll("::ward_code", "");
  301. sql = sql.replaceAll("::exec_unit", "");
  302. sql = sql.replaceAll("::dept", "");
  303. }
  304. return sql;
  305. }
  306. @NotNull
  307. private static String getTimeString(HighReportDto dto, String sql) {
  308. if(sql.contains(START_TIME)){
  309. if(StringUtil.notBlank(dto.getStartTime())){
  310. sql = sql.replaceAll(START_TIME, "'" + dto.getStartTime() + "'");
  311. } else {
  312. sql = sql.replaceAll(START_TIME,"'2012-01-01 00:00:00'");
  313. }
  314. }
  315. if(sql.contains(END_TIME)){
  316. if(StringUtil.notBlank(dto.getEndTime())){
  317. sql = sql.replaceAll(END_TIME, "'" + dto.getEndTime() + "'");
  318. } else {
  319. sql = sql.replaceAll(END_TIME, DateUtil.getDayEndTime(new Date()));
  320. }
  321. }
  322. return sql;
  323. }
  324. }