ReportUtil.java 14 KB

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