소스 검색

Merge remote-tracking branch 'origin/dev/20211117_2.1.4' into develop

chengyao 3 년 전
부모
커밋
1c3728752c
50개의 변경된 파일3389개의 추가작업 그리고 128개의 파일을 삭제
  1. 174 0
      doc/037.20211117_2.1.4/qc_initv2.1.4.sql
  2. 37 0
      src/main/java/com/diagbot/config/AccessDeniedExceptionPoint.java
  3. 2 37
      src/main/java/com/diagbot/config/AuthExceptionEntryPoint.java
  4. 90 0
      src/main/java/com/diagbot/config/AuthenticationExceptionHandler.java
  5. 223 0
      src/main/java/com/diagbot/config/MyJwtTokenStore.java
  6. 23 2
      src/main/java/com/diagbot/config/ResourceServerConfigurer.java
  7. 22 2
      src/main/java/com/diagbot/config/security/UrlAccessDecisionManager.java
  8. 94 0
      src/main/java/com/diagbot/dto/BehospitalAnalysisDTO.java
  9. 72 0
      src/main/java/com/diagbot/dto/BehospitalCodeDetail.java
  10. 20 0
      src/main/java/com/diagbot/dto/BehospitalCodeInfo.java
  11. 58 37
      src/main/java/com/diagbot/dto/BehospitalInfoDTO.java
  12. 26 0
      src/main/java/com/diagbot/dto/EntryDefectImprove.java
  13. 24 0
      src/main/java/com/diagbot/dto/EntryDefectImproveInner.java
  14. 25 0
      src/main/java/com/diagbot/dto/EntryDefectImproveInnerDoctor.java
  15. 27 0
      src/main/java/com/diagbot/dto/EntryDefectImproveInnerExport.java
  16. 77 0
      src/main/java/com/diagbot/dto/GetEntryDefectImproveDTO.java
  17. 85 0
      src/main/java/com/diagbot/dto/GetEntryDefectImproveDeptDTO.java
  18. 35 0
      src/main/java/com/diagbot/dto/GetEntryInfoDTO.java
  19. 40 0
      src/main/java/com/diagbot/dto/GetQcClickDTO.java
  20. 52 0
      src/main/java/com/diagbot/dto/GetQcClickInnerPageDTO.java
  21. 20 0
      src/main/java/com/diagbot/dto/QcResultDetailInfo.java
  22. 7 2
      src/main/java/com/diagbot/entity/MedClickInfo.java
  23. 61 0
      src/main/java/com/diagbot/entity/MedQcresultClick.java
  24. 2 0
      src/main/java/com/diagbot/exception/ServiceErrorCode.java
  25. 15 1
      src/main/java/com/diagbot/facade/BasDeptInfoFacade.java
  26. 1 16
      src/main/java/com/diagbot/facade/BehospitalInfoFacade.java
  27. 215 0
      src/main/java/com/diagbot/facade/DataAnalysisDeptFacade.java
  28. 758 0
      src/main/java/com/diagbot/facade/DataAnalysisFacade.java
  29. 9 0
      src/main/java/com/diagbot/facade/SysDictionaryFacade.java
  30. 6 0
      src/main/java/com/diagbot/facade/SysUserFacade.java
  31. 1 0
      src/main/java/com/diagbot/mapper/BehospitalInfoMapper.java
  32. 22 1
      src/main/java/com/diagbot/mapper/MedClickInfoMapper.java
  33. 16 0
      src/main/java/com/diagbot/mapper/MedQcresultClickMapper.java
  34. 16 0
      src/main/java/com/diagbot/service/MedQcresultClickService.java
  35. 20 0
      src/main/java/com/diagbot/service/impl/MedQcresultClickServiceImpl.java
  36. 1 1
      src/main/java/com/diagbot/service/impl/SysTokenServiceImpl.java
  37. 14 2
      src/main/java/com/diagbot/util/SysUserUtils.java
  38. 74 0
      src/main/java/com/diagbot/vo/GetEntryDefectImproveDeptVO.java
  39. 115 0
      src/main/java/com/diagbot/vo/GetEntryDefectImproveInnerVO.java
  40. 65 0
      src/main/java/com/diagbot/vo/GetEntryDefectImproveVO.java
  41. 51 0
      src/main/java/com/diagbot/vo/GetQcClickInnerPageVO.java
  42. 54 0
      src/main/java/com/diagbot/vo/GetQcClickVO.java
  43. 15 5
      src/main/java/com/diagbot/vo/MedClickInfoVO.java
  44. 1 7
      src/main/java/com/diagbot/web/BehospitalInfoController.java
  45. 169 0
      src/main/java/com/diagbot/web/DataAnalysisController.java
  46. 94 0
      src/main/java/com/diagbot/web/DataAnalysisDeptController.java
  47. 2 2
      src/main/resources/application-test.yml
  48. 20 0
      src/main/resources/mapper/BehospitalInfoMapper.xml
  49. 322 13
      src/main/resources/mapper/MedClickInfoMapper.xml
  50. 17 0
      src/main/resources/mapper/MedQcresultClickMapper.xml

+ 174 - 0
doc/037.20211117_2.1.4/qc_initv2.1.4.sql

@@ -0,0 +1,174 @@
+
+use `qc`;
+-- 执行前请看注意事项!
+-- 此脚本为通版脚本,均执行病历doctorId、doctorName回查 @hospitalId =**:需要更新的医院hospitalId在下面调整即可SET @hospitalId =**
+
+-- 如果其它医院不使用此次版本的数据分析报表,则需要手动到关闭数据分析报表
+SET @hospitalId =35;
+ UPDATE med_behospital_info a,
+ (
+	SELECT
+		doctor_id,
+		name
+		NAME
+	FROM
+		bas_doctor_info b
+	WHERE
+		b.hospital_id = @hospitalId
+	AND b.is_deleted = 'N'
+) c
+SET a.doctor_name = c. NAME
+WHERE
+	a.doctor_id = c.doctor_id
+AND a.hospital_id = @hospitalId
+AND (a.doctor_name is null or a.doctor_name = '' or a.doctor_name ='-' or a.doctor_name ='—' or LENGTH(a.doctor_name)>64);
+
+-- med_behospital_info病历doctorId回查
+UPDATE med_behospital_info a,
+ (
+	SELECT
+		doctor_id,
+		NAME
+	FROM
+		bas_doctor_info b
+	WHERE
+		b.hospital_id = @hospitalId
+	AND b.is_deleted = 'N'
+	GROUP BY
+		b. NAME
+	HAVING
+		count(b.doctor_id) = 1
+) c
+SET a.doctor_id = c.doctor_id
+WHERE
+	a.doctor_name = c.NAME
+AND a.hospital_id = @hospitalId
+AND (a.doctor_id is null or a.doctor_id = '' or a.doctor_id ='-' or a.doctor_id ='—' or LENGTH(a.doctor_id)>64);
+
+
+-- 对空数据初始化
+UPDATE med_behospital_info a set a.doctor_name = '-' where a.doctor_name is null || a.doctor_name = '' AND a.hospital_id = @hospitalId;
+UPDATE med_behospital_info a set a.doctor_id = '-' where a.doctor_id is null || a.doctor_id = '' AND a.hospital_id = @hospitalId;
+
+
+DROP TABLE IF EXISTS `med_click_info`;
+CREATE TABLE `med_click_info` (
+  `id` int(20) NOT NULL AUTO_INCREMENT,
+  `hospital_id` tinyint(5) DEFAULT '0' COMMENT '医院ID',
+  `dept_id` varchar(16) DEFAULT NULL COMMENT '科室ID',
+  `dept_name` varchar(64) DEFAULT NULL COMMENT '科室名称',
+  `doctor_id` varchar(16) DEFAULT NULL COMMENT '医生ID',
+  `doctor_name` varchar(64) DEFAULT NULL COMMENT '医生姓名',
+  `opt_type` tinyint(1) DEFAULT '1' COMMENT '0-单模块质控 1-全病历质控',
+  `qcresult_info_id` int(16) DEFAULT NULL COMMENT '评分结果id',
+  `behospital_code` varchar(16) DEFAULT NULL COMMENT '病人住院ID',
+  `is_deleted` char(3) DEFAULT 'N' COMMENT '是否删除,N:未删除,Y:删除',
+  `gmt_create` datetime DEFAULT '1970-01-01 12:00:00' COMMENT ' 记录创建时间',
+  `gmt_modified` datetime DEFAULT '1970-01-01 12:00:00' COMMENT ' 记录修改时间,如果时间是1970年则表示纪录未修改',
+  `creator` varchar(20) DEFAULT '0' COMMENT '创建人,0表示无创建人值',
+  `modifier` varchar(20) DEFAULT '0' COMMENT '修改人,如果为0则表示纪录未修改',
+  PRIMARY KEY (`id`),
+  KEY `idx_all` (`hospital_id`,`behospital_code`) USING BTREE,
+) ENGINE=InnoDB AUTO_INCREMENT=62313 DEFAULT CHARSET=utf8 COMMENT='临床医生点击质控病历次数基本表';
+
+DROP TABLE IF EXISTS `med_qcresult_click`;
+CREATE TABLE `med_qcresult_click` (
+  `id` bigint(20) NOT NULL AUTO_INCREMENT,
+  `hospital_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '医院ID',
+  `behospital_code` varchar(16) NOT NULL COMMENT '病人住院ID',
+  `dept_id` varchar(16) DEFAULT NULL COMMENT '住院科室ID',
+  `dept_name` varchar(64) DEFAULT NULL COMMENT '住院科室名称',
+  `qcresult_info_id` bigint(20) NOT NULL COMMENT '评分结果id',
+  `cases_entry_ids` varchar(1024) DEFAULT '0' COMMENT '触发埋点病历质控缺陷id集',
+  `is_deleted` char(3) DEFAULT 'N' COMMENT '是否删除,N:未删除,Y:删除',
+  `gmt_create` datetime DEFAULT '1970-01-01 12:00:00' COMMENT ' 记录创建时间',
+  PRIMARY KEY (`id`),
+  KEY `idx_all` (`hospital_id`,`behospital_code`)
+) ENGINE=InnoDB AUTO_INCREMENT=8587 DEFAULT CHARSET=utf8 COMMENT='全病历质控、单模块质控(触发埋点)缺陷详情';
+
+
+
+/**
+med_qcresult_detail表新增评分结果主表id字段
+ */
+ALTER TABLE `med_qcresult_detail` ADD COLUMN qcresult_info_id BIGINT (20) DEFAULT NULL COMMENT '评分结果id' AFTER `behospital_code`;
+
+/**
+med_qcresult_cases表新增评分结果主表id字段
+ */
+ALTER TABLE `med_qcresult_cases` ADD COLUMN qcresult_info_id BIGINT (20) DEFAULT NULL COMMENT '评分结果id' AFTER `behospital_code`;
+
+-- 全院
+SET @id =69;
+INSERT INTO `sys_menu` ( `id`,`is_deleted`, `gmt_create`, `gmt_modified`, `creator`, `modifier`, `name`, `parent_id`, `code`, `show_status`, `maintain_status`, `order_no`, `remark`) VALUES (@id,'N', '1970-01-01 12:00:00', '1970-01-01 12:00:00', '0', '0', '数据分析', '-1', 'YH-SJFX', '1', '1', '12', '用户-数据分析');
+
+
+INSERT INTO `sys_menu` ( `is_deleted`, `gmt_create`, `gmt_modified`, `creator`, `modifier`, `name`, `parent_id`, `code`, `show_status`, `maintain_status`, `order_no`, `remark`) VALUES ( 'N', '1970-01-01 12:00:00', '1970-01-01 12:00:00', '0', '0', '临床质控使用统计', @id , 'YH-ZKK-LCZKSYTJ', '1', '1', '1', '用户-质控科-临床质控使用统计');
+SET @idSec =@@identity;
+INSERT INTO `sys_menu` ( `is_deleted`, `gmt_create`, `gmt_modified`, `creator`, `modifier`, `name`, `parent_id`, `code`, `show_status`, `maintain_status`, `order_no`, `remark`) VALUES ( 'N', '1970-01-01 12:00:00', '1970-01-01 12:00:00', '0', '0', '条目缺陷改善统计', @id , 'YH-ZKK-TMQXGSTJ', '1', '1', '2', '用户-质控科-条目缺陷改善统计');
+SET @idThr =@@identity;
+
+INSERT INTO `sys_role_menu` ( `is_deleted`, `gmt_create`, `gmt_modified`, `creator`, `modifier`, `role_id`, `menu_id`, `remark`) VALUES ( 'N', '1970-01-01 12:00:00', '1970-01-01 12:00:00', '0', '0', '-1', @id, NULL);
+INSERT INTO `sys_role_menu` ( `is_deleted`, `gmt_create`, `gmt_modified`, `creator`, `modifier`, `role_id`, `menu_id`, `remark`) VALUES ( 'N', '1970-01-01 12:00:00', '1970-01-01 12:00:00', '0', '0', '1', @id, NULL);
+
+
+INSERT INTO `sys_role_menu` ( `is_deleted`, `gmt_create`, `gmt_modified`, `creator`, `modifier`, `role_id`, `menu_id`, `remark`) VALUES ( 'N', '1970-01-01 12:00:00', '1970-01-01 12:00:00', '0', '0', '-1', @idSec, NULL);
+INSERT INTO `sys_role_menu` ( `is_deleted`, `gmt_create`, `gmt_modified`, `creator`, `modifier`, `role_id`, `menu_id`, `remark`) VALUES ( 'N', '1970-01-01 12:00:00', '1970-01-01 12:00:00', '0', '0', '1', @idSec, NULL);
+INSERT INTO `sys_role_menu` ( `is_deleted`, `gmt_create`, `gmt_modified`, `creator`, `modifier`, `role_id`, `menu_id`, `remark`) VALUES ( 'N', '1970-01-01 12:00:00', '1970-01-01 12:00:00', '0', '0', '-1', @idThr, NULL);
+INSERT INTO `sys_role_menu` ( `is_deleted`, `gmt_create`, `gmt_modified`, `creator`, `modifier`, `role_id`, `menu_id`, `remark`) VALUES ( 'N', '1970-01-01 12:00:00', '1970-01-01 12:00:00', '0', '0', '1', @idThr, NULL);
+
+
+
+INSERT INTO `sys_permission` ( `is_deleted`, `gmt_create`, `gmt_modified`, `creator`, `modifier`, `name`, `code`, `permissionUrl`, `method`, `descritpion`, `remark`) VALUES ( 'N', '1970-01-01 12:00:00', '1970-01-01 12:00:00', '0', '0', '临床质控使用统计', '', '/qc/analysis/getQcClick', 'ALL', '临床质控使用统计', NULL);
+SET @idperFir =@@identity;
+INSERT INTO `sys_permission` ( `is_deleted`, `gmt_create`, `gmt_modified`, `creator`, `modifier`, `name`, `code`, `permissionUrl`, `method`, `descritpion`, `remark`) VALUES ( 'N', '1970-01-01 12:00:00', '1970-01-01 12:00:00', '0', '0', '临床质控使用统计(内页)', '', '/qc/analysis/getQcClickInnerPage', 'ALL', '临床质控使用统计(内页)', NULL);
+SET @idperSec =@@identity;
+INSERT INTO `sys_permission` ( `is_deleted`, `gmt_create`, `gmt_modified`, `creator`, `modifier`, `name`, `code`, `permissionUrl`, `method`, `descritpion`, `remark`) VALUES ( 'N', '1970-01-01 12:00:00', '1970-01-01 12:00:00', '0', '0', '条目缺陷改善统计', '', '/qc/analysis/getEntryDefectImprove', 'ALL', '条目缺陷改善统计', NULL);
+SET @idperThr =@@identity;
+INSERT INTO `sys_permission` ( `is_deleted`, `gmt_create`, `gmt_modified`, `creator`, `modifier`, `name`, `code`, `permissionUrl`, `method`, `descritpion`, `remark`) VALUES ( 'N', '1970-01-01 12:00:00', '1970-01-01 12:00:00', '0', '0', '条目缺陷改善统计(内页)', '', '/qc/analysis/getEntryDefectImproveInner', 'ALL', '条目缺陷改善统计(内页)-病历列表', NULL);
+SET @idperFou =@@identity;
+
+
+INSERT INTO `sys_role_permission` ( `is_deleted`, `gmt_create`, `gmt_modified`, `creator`, `modifier`, `role_id`, `permission_id`, `remark`) VALUES ( 'N', '1970-01-01 12:00:00', '1970-01-01 12:00:00', '0', '0', '-1', @idperFir, NULL);
+INSERT INTO `sys_role_permission` ( `is_deleted`, `gmt_create`, `gmt_modified`, `creator`, `modifier`, `role_id`, `permission_id`, `remark`) VALUES ( 'N', '1970-01-01 12:00:00', '1970-01-01 12:00:00', '0', '0', '-1', @idperSec, NULL);
+INSERT INTO `sys_role_permission` ( `is_deleted`, `gmt_create`, `gmt_modified`, `creator`, `modifier`, `role_id`, `permission_id`, `remark`) VALUES ( 'N', '1970-01-01 12:00:00', '1970-01-01 12:00:00', '0', '0', '-1', @idperThr, NULL);
+INSERT INTO `sys_role_permission` ( `is_deleted`, `gmt_create`, `gmt_modified`, `creator`, `modifier`, `role_id`, `permission_id`, `remark`) VALUES ( 'N', '1970-01-01 12:00:00', '1970-01-01 12:00:00', '0', '0', '-1', @idperFou, NULL);
+INSERT INTO `sys_role_permission` ( `is_deleted`, `gmt_create`, `gmt_modified`, `creator`, `modifier`, `role_id`, `permission_id`, `remark`) VALUES ( 'N', '1970-01-01 12:00:00', '1970-01-01 12:00:00', '0', '0', '1', @idperFir, NULL);
+INSERT INTO `sys_role_permission` ( `is_deleted`, `gmt_create`, `gmt_modified`, `creator`, `modifier`, `role_id`, `permission_id`, `remark`) VALUES ( 'N', '1970-01-01 12:00:00', '1970-01-01 12:00:00', '0', '0', '1', @idperSec, NULL);
+INSERT INTO `sys_role_permission` ( `is_deleted`, `gmt_create`, `gmt_modified`, `creator`, `modifier`, `role_id`, `permission_id`, `remark`) VALUES ( 'N', '1970-01-01 12:00:00', '1970-01-01 12:00:00', '0', '0', '1', @idperThr, NULL);
+INSERT INTO `sys_role_permission` ( `is_deleted`, `gmt_create`, `gmt_modified`, `creator`, `modifier`, `role_id`, `permission_id`, `remark`) VALUES ( 'N', '1970-01-01 12:00:00', '1970-01-01 12:00:00', '0', '0', '1', @idperFou, NULL);
+
+-- INSERT INTO `sys_menu_permission` ( `is_deleted`, `gmt_create`, `gmt_modified`, `creator`, `modifier`, `menu_id`, `permission_id`, `order_nu`, `remark`) VALUES ( 'N', '1970-01-01 12:00:00', '1970-01-01 12:00:00', '0', '0', @idSec, @idperFir, NULL, '临床质控使用统计');
+-- INSERT INTO `sys_menu_permission` ( `is_deleted`, `gmt_create`, `gmt_modified`, `creator`, `modifier`, `menu_id`, `permission_id`, `order_nu`, `remark`) VALUES ( 'N', '1970-01-01 12:00:00', '1970-01-01 12:00:00', '0', '0', @idSec, @idperSec, NULL, '临床质控使用统计(内页)');
+-- INSERT INTO `sys_menu_permission` ( `is_deleted`, `gmt_create`, `gmt_modified`, `creator`, `modifier`, `menu_id`, `permission_id`, `order_nu`, `remark`) VALUES ( 'N', '1970-01-01 12:00:00', '1970-01-01 12:00:00', '0', '0', @idThr, @idperThr, NULL, '条目缺陷改善统计');
+-- INSERT INTO `sys_menu_permission` ( `is_deleted`, `gmt_create`, `gmt_modified`, `creator`, `modifier`, `menu_id`, `permission_id`, `order_nu`, `remark`) VALUES ( 'N', '1970-01-01 12:00:00', '1970-01-01 12:00:00', '0', '0', @idThr, @idperFou, NULL, '条目缺陷改善统计(内页)');
+
+
+-- 科室
+INSERT INTO `sys_menu` ( `is_deleted`, `gmt_create`, `gmt_modified`, `creator`, `modifier`, `name`, `parent_id`, `code`, `show_status`, `maintain_status`, `order_no`, `remark`) VALUES ( 'N', '1970-01-01 12:00:00', '1970-01-01 12:00:00', '0', '0', '数据分析(科室)', '-1', 'YH-SJFXKS', '1', '1', '13', '用户-数据分析(科室)');
+SET @idks =@@identity;
+
+INSERT INTO `sys_menu` ( `is_deleted`, `gmt_create`, `gmt_modified`, `creator`, `modifier`, `name`, `parent_id`, `code`, `show_status`, `maintain_status`, `order_no`, `remark`) VALUES ( 'N', '1970-01-01 12:00:00', '1970-01-01 12:00:00', '0', '0', '条目缺陷改善统计', @idks , 'YH-KSZR-TMQXGSTJ', '1', '1', '2', '用户-质控科-条目缺陷改善统计(科室)');
+SET @idksThr =@@identity;
+
+INSERT INTO `sys_role_menu` ( `is_deleted`, `gmt_create`, `gmt_modified`, `creator`, `modifier`, `role_id`, `menu_id`, `remark`) VALUES ( 'N', '1970-01-01 12:00:00', '1970-01-01 12:00:00', '0', '0', '-1', @idks, NULL);
+INSERT INTO `sys_role_menu` ( `is_deleted`, `gmt_create`, `gmt_modified`, `creator`, `modifier`, `role_id`, `menu_id`, `remark`) VALUES ( 'N', '1970-01-01 12:00:00', '1970-01-01 12:00:00', '0', '0', '2', @idks, NULL);
+
+INSERT INTO `sys_role_menu` ( `is_deleted`, `gmt_create`, `gmt_modified`, `creator`, `modifier`, `role_id`, `menu_id`, `remark`) VALUES ( 'N', '1970-01-01 12:00:00', '1970-01-01 12:00:00', '0', '0', '-1', @idksThr, NULL);
+INSERT INTO `sys_role_menu` ( `is_deleted`, `gmt_create`, `gmt_modified`, `creator`, `modifier`, `role_id`, `menu_id`, `remark`) VALUES ( 'N', '1970-01-01 12:00:00', '1970-01-01 12:00:00', '0', '0', '2', @idksThr, NULL);
+
+
+
+INSERT INTO `sys_permission` ( `is_deleted`, `gmt_create`, `gmt_modified`, `creator`, `modifier`, `name`, `code`, `permissionUrl`, `method`, `descritpion`, `remark`) VALUES ( 'N', '1970-01-01 12:00:00', '1970-01-01 12:00:00', '0', '0', '条目缺陷改善统计', '', '/qc/analysisDept/getEntryDefectImproveDept', 'ALL', '条目缺陷改善统计-科室', NULL);
+SET @idperFiv =@@identity;
+INSERT INTO `sys_permission` ( `is_deleted`, `gmt_create`, `gmt_modified`, `creator`, `modifier`, `name`, `code`, `permissionUrl`, `method`, `descritpion`, `remark`) VALUES ('N', '1970-01-01 12:00:00', '1970-01-01 12:00:00', '0', '0', '条目缺陷改善统计(内页)', '', '/qc/analysisDept/getEntryDefectImproveInnerDept', 'ALL', '条目缺陷改善统计(内页)-科室', NULL);
+SET @idperSix =@@identity;
+
+INSERT INTO `sys_role_permission` ( `is_deleted`, `gmt_create`, `gmt_modified`, `creator`, `modifier`, `role_id`, `permission_id`, `remark`) VALUES ( 'N', '1970-01-01 12:00:00', '1970-01-01 12:00:00', '0', '0', '-1', @idperFiv, NULL);
+INSERT INTO `sys_role_permission` ( `is_deleted`, `gmt_create`, `gmt_modified`, `creator`, `modifier`, `role_id`, `permission_id`, `remark`) VALUES ( 'N', '1970-01-01 12:00:00', '1970-01-01 12:00:00', '0', '0', '-1', @idperSix, NULL);
+INSERT INTO `sys_role_permission` ( `is_deleted`, `gmt_create`, `gmt_modified`, `creator`, `modifier`, `role_id`, `permission_id`, `remark`) VALUES ( 'N', '1970-01-01 12:00:00', '1970-01-01 12:00:00', '0', '0', '2', @idperFiv, NULL);
+INSERT INTO `sys_role_permission` ( `is_deleted`, `gmt_create`, `gmt_modified`, `creator`, `modifier`, `role_id`, `permission_id`, `remark`) VALUES ( 'N', '1970-01-01 12:00:00', '1970-01-01 12:00:00', '0', '0', '2', @idperSix, NULL);
+
+
+-- INSERT INTO `sys_menu_permission` ( `is_deleted`, `gmt_create`, `gmt_modified`, `creator`, `modifier`, `menu_id`, `permission_id`, `order_nu`, `remark`) VALUES ( 'N', '1970-01-01 12:00:00', '1970-01-01 12:00:00', '0', '0', @idksThr, @idperFiv, NULL, '条目缺陷改善统计');
+-- INSERT INTO `sys_menu_permission` ( `is_deleted`, `gmt_create`, `gmt_modified`, `creator`, `modifier`, `menu_id`, `permission_id`, `order_nu`, `remark`) VALUES ( 'N', '1970-01-01 12:00:00', '1970-01-01 12:00:00', '0', '0', @idksThr, @idperSix, NULL, '条目缺陷改善统计(内页)');

+ 37 - 0
src/main/java/com/diagbot/config/AccessDeniedExceptionPoint.java

@@ -0,0 +1,37 @@
+package com.diagbot.config;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.springframework.security.access.AccessDeniedException;
+import org.springframework.security.web.access.AccessDeniedHandler;
+import org.springframework.stereotype.Component;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @Description:
+ * @Author songxl
+ * @Date 2021/11/30
+ */
+@Component
+public class AccessDeniedExceptionPoint implements AccessDeniedHandler {
+    @Override
+    public void handle(HttpServletRequest httpServletRequest, HttpServletResponse response, AccessDeniedException e) throws IOException, ServletException {
+        Map map = new HashMap();
+        //响应状态码统一为200
+        response.setStatus(HttpServletResponse.SC_OK);
+        map.put("code", "00000001");
+        map.put("msg","没有该权限");
+        response.setContentType("application/json");
+        try {
+            ObjectMapper mapper = new ObjectMapper();
+            mapper.writeValue(response.getOutputStream(), map);
+        } catch (Exception e1) {
+            throw new ServletException();
+        }
+    }
+}

+ 2 - 37
src/main/java/com/diagbot/config/AuthExceptionEntryPoint.java

@@ -1,19 +1,13 @@
 package com.diagbot.config;
 
-import com.diagbot.facade.SysUserFacade;
-import com.diagbot.util.StringUtil;
-import com.fasterxml.jackson.databind.ObjectMapper;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.core.AuthenticationException;
 import org.springframework.security.web.AuthenticationEntryPoint;
-import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
 import org.springframework.stereotype.Component;
 
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
-import java.util.HashMap;
-import java.util.Map;
 
 /**
  * @Description:
@@ -23,45 +17,16 @@ import java.util.Map;
 @Component
 public class AuthExceptionEntryPoint implements AuthenticationEntryPoint {
     @Autowired
-    private SysUserFacade userFacade;
+    AuthenticationExceptionHandler authenticationExceptionHandler;
 
     @Override
     public void commence(HttpServletRequest request, HttpServletResponse response,
                          AuthenticationException authException)
             throws ServletException {
-        Map map = new HashMap();
-        if (StringUtil.isNotEmpty(authException.getMessage()) && authException.getMessage().contains("Access token expired")) {
-            map.put("code", "10020011");
-            map.put("msg", "登录超时。为确保您的账户安全,系统已自动退出,请重新登录。");
-            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
-        } else {
-            //登录前的获取登录页面的请求接口不知道什么原因会抛出未认证(Full authentication is required to access this resource)
-            //如果抛出未认证在这个调用这个服务接口返回消息
-            response.setStatus(HttpServletResponse.SC_OK);
-            if (matchers("/sys/user/getHospitalMark", request)) {
-                map.put("code", "0");
-                map.put("msg", "");
-                map.put("data", userFacade.getHospitalMark());
-            } else {
-                map.put("code", "00000001");
-                map.put("msg", authException.getMessage());
-            }
-        }
-        response.setContentType("application/json");
         try {
-            ObjectMapper mapper = new ObjectMapper();
-            mapper.writeValue(response.getOutputStream(), map);
+            authenticationExceptionHandler.handleException(request,response,authException);
         } catch (Exception e) {
             throw new ServletException();
         }
     }
-
-
-    private boolean matchers(String url, HttpServletRequest request) {
-        AntPathRequestMatcher matcher = new AntPathRequestMatcher(url);
-        if (matcher.matches(request)) {
-            return true;
-        }
-        return false;
-    }
 }

+ 90 - 0
src/main/java/com/diagbot/config/AuthenticationExceptionHandler.java

@@ -0,0 +1,90 @@
+package com.diagbot.config;
+
+
+import com.diagbot.facade.SysUserFacade;
+import com.diagbot.util.StringUtil;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.authentication.AccountExpiredException;
+import org.springframework.security.authentication.AccountStatusException;
+import org.springframework.security.authentication.BadCredentialsException;
+import org.springframework.security.authentication.CredentialsExpiredException;
+import org.springframework.security.authentication.DisabledException;
+import org.springframework.security.authentication.InsufficientAuthenticationException;
+import org.springframework.security.authentication.LockedException;
+import org.springframework.security.core.AuthenticationException;
+import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
+import org.springframework.stereotype.Component;
+import org.springframework.validation.BindException;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @Description:权限认证异常处理
+ * @Author songxl
+ * @Date 2021/12/13
+ */
+@Component
+public class AuthenticationExceptionHandler {
+    @Autowired
+    private SysUserFacade userFacade;
+
+    public void handleException(HttpServletRequest request, HttpServletResponse response,
+                                AuthenticationException authException) throws ServletException {
+        Map map = new HashMap();
+        //登录前的获取登录页面的请求接口不知道什么原因会抛出未认证(Full authentication is required to access this resource)
+        //如果抛出未认证在这个调用这个服务接口返回消息
+        //响应状态码统一为200
+        response.setStatus(HttpServletResponse.SC_OK);
+        if (matchers("/sys/user/getHospitalMark", request)) {
+            map.put("code", "0");
+            map.put("msg", "");
+            map.put("data", userFacade.getHospitalMark());
+        } else if (authException instanceof BadCredentialsException) {
+            map.put("code", "00000001");
+            map.put("msg", "用户或密码不正确");
+        } else if (authException instanceof AccountStatusException) {
+            if (authException instanceof LockedException) {
+                map.put("code", "00000001");
+                map.put("msg", "账户锁定");
+            } else if (authException instanceof AccountExpiredException) {//账户过期
+                map.put("code", "10020011");
+                map.put("msg", "登录超时。为确保您的账户安全,系统已自动退出,请重新登录。");
+            } else if (authException instanceof CredentialsExpiredException) {//证书过期
+                map.put("code", "10020011");
+                map.put("msg", "登录超时。为确保您的账户安全,系统已自动退出,请重新登录。");
+            } else if (authException instanceof DisabledException) {
+                map.put("code", "00000001");
+                map.put("msg", "账户不可用");
+            } else {
+                map.put("code", "00000001");
+                map.put("msg", "用户状态异常");
+            }
+        } else if (authException instanceof InsufficientAuthenticationException) {
+            map.put("code", "10020011");
+            map.put("msg", "登录超时。为确保您的账户安全,系统已自动退出,请重新登录。");
+        } else {
+            map.put("code", "00000001");
+            map.put("msg", authException.getMessage());
+        }
+        response.setContentType("application/json");
+        try {
+            ObjectMapper mapper = new ObjectMapper();
+            mapper.writeValue(response.getOutputStream(), map);
+        } catch (Exception e) {
+            throw new ServletException();
+        }
+    }
+
+    private boolean matchers(String url, HttpServletRequest request) {
+        AntPathRequestMatcher matcher = new AntPathRequestMatcher(url);
+        if (matcher.matches(request)) {
+            return true;
+        }
+        return false;
+    }
+}

+ 223 - 0
src/main/java/com/diagbot/config/MyJwtTokenStore.java

@@ -0,0 +1,223 @@
+package com.diagbot.config;
+
+import com.diagbot.util.DateUtil;
+import com.diagbot.util.RedisUtils;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.core.io.Resource;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.jwt.Jwt;
+import org.springframework.security.jwt.JwtHelper;
+import org.springframework.security.jwt.crypto.sign.RsaVerifier;
+import org.springframework.security.jwt.crypto.sign.SignatureVerifier;
+import org.springframework.security.oauth2.common.DefaultExpiringOAuth2RefreshToken;
+import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
+import org.springframework.security.oauth2.common.DefaultOAuth2RefreshToken;
+import org.springframework.security.oauth2.common.OAuth2AccessToken;
+import org.springframework.security.oauth2.common.OAuth2RefreshToken;
+import org.springframework.security.oauth2.common.exceptions.InvalidTokenException;
+import org.springframework.security.oauth2.common.util.JsonParser;
+import org.springframework.security.oauth2.common.util.JsonParserFactory;
+import org.springframework.security.oauth2.provider.OAuth2Authentication;
+import org.springframework.security.oauth2.provider.approval.Approval;
+import org.springframework.security.oauth2.provider.approval.ApprovalStore;
+import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
+import org.springframework.security.oauth2.provider.token.store.JwtClaimsSetVerifier;
+import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
+import org.springframework.security.oauth2.provider.approval.Approval.ApprovalStatus;
+import org.springframework.util.FileCopyUtils;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * @Description:token续签
+ * @Author songxl
+ * @Date 2021/12/17
+ */
+public class MyJwtTokenStore extends JwtTokenStore {
+    private JwtAccessTokenConverter jwtTokenEnhancer;
+    private ApprovalStore approvalStore;
+    private JsonParser objectMapper = JsonParserFactory.create();
+    private JwtClaimsSetVerifier jwtClaimsSetVerifier = new NoOpJwtClaimsSetVerifier();
+    private SignatureVerifier verifier;
+    private RedisUtils redisUtils;
+    public MyJwtTokenStore(JwtAccessTokenConverter jwtTokenEnhancer,RedisUtils redisUtils) {
+        super(jwtTokenEnhancer);
+        verifier = createVerifier();
+        this.jwtTokenEnhancer = jwtTokenEnhancer;
+        this.redisUtils = redisUtils;
+    }
+
+    private SignatureVerifier createVerifier() {
+        Resource resource = new ClassPathResource("public.cert");
+        String publicKey;
+        try {
+            publicKey = new String(FileCopyUtils.copyToByteArray(resource.getInputStream()));
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+        return new RsaVerifier(publicKey);
+    }
+
+    public void setApprovalStore(ApprovalStore approvalStore) {
+        this.approvalStore = approvalStore;
+    }
+
+    public OAuth2Authentication readAuthentication(OAuth2AccessToken token) {
+        return this.readAuthentication(token.getValue());
+    }
+
+
+    public void storeAccessToken(OAuth2AccessToken token, OAuth2Authentication authentication) {
+    }
+
+    public OAuth2AccessToken readAccessToken(String tokenValue) {
+        DefaultOAuth2AccessToken accessToken = (DefaultOAuth2AccessToken) this.convertAccessToken(tokenValue);
+        OAuth2AccessToken newAccessToken = updateTokenOutTime(accessToken);
+        if (this.jwtTokenEnhancer.isRefreshToken(accessToken)) {
+            throw new InvalidTokenException("Encoded token is a refresh token");
+        } else {
+            return newAccessToken;
+        }
+    }
+
+    private OAuth2AccessToken updateTokenOutTime(DefaultOAuth2AccessToken accessToken) {
+        if(accessToken.getAdditionalInformation()!=null&&accessToken.getAdditionalInformation().containsKey("user_id")){
+            //通过用户id获取redis存储的token过期时间
+            Object userIdObj = accessToken.getAdditionalInformation().get("user_id");
+            Integer value =(Integer) redisUtils.get("user:refreshToken:outTime_" + userIdObj);
+            if (value!=null){
+                //更新token过期时间为明天
+                accessToken.setExpiration(DateUtil.addDay(new Date(),1));
+                //将这个时间重新存到redis
+                redisUtils.set("user:refreshToken:outTime_" + userIdObj, value, value);
+            }
+        }
+        return accessToken;
+    }
+
+    private OAuth2AccessToken convertAccessToken(String tokenValue) {
+        return this.jwtTokenEnhancer.extractAccessToken(tokenValue, decode(tokenValue));
+    }
+
+    public void removeAccessToken(OAuth2AccessToken token) {
+    }
+
+    public void storeRefreshToken(OAuth2RefreshToken refreshToken, OAuth2Authentication authentication) {
+    }
+
+    public OAuth2RefreshToken readRefreshToken(String tokenValue) {
+        OAuth2AccessToken encodedRefreshToken = this.convertAccessToken(tokenValue);
+        OAuth2RefreshToken refreshToken = this.createRefreshToken(encodedRefreshToken);
+        if (this.approvalStore != null) {
+            OAuth2Authentication authentication = this.readAuthentication(tokenValue);
+            if (authentication.getUserAuthentication() != null) {
+                String userId = authentication.getUserAuthentication().getName();
+                String clientId = authentication.getOAuth2Request().getClientId();
+                Collection<Approval> approvals = this.approvalStore.getApprovals(userId, clientId);
+                Collection<String> approvedScopes = new HashSet();
+                Iterator var9 = approvals.iterator();
+
+                while(var9.hasNext()) {
+                    Approval approval = (Approval)var9.next();
+                    if (approval.isApproved()) {
+                        approvedScopes.add(approval.getScope());
+                    }
+                }
+
+                if (!approvedScopes.containsAll(authentication.getOAuth2Request().getScope())) {
+                    return null;
+                }
+            }
+        }
+
+        return refreshToken;
+    }
+
+    private OAuth2RefreshToken createRefreshToken(OAuth2AccessToken encodedRefreshToken) {
+        if (!this.jwtTokenEnhancer.isRefreshToken(encodedRefreshToken)) {
+            throw new InvalidTokenException("Encoded token is not a refresh token");
+        } else {
+            return (OAuth2RefreshToken)(encodedRefreshToken.getExpiration() != null ? new DefaultExpiringOAuth2RefreshToken(encodedRefreshToken.getValue(), encodedRefreshToken.getExpiration()) : new DefaultOAuth2RefreshToken(encodedRefreshToken.getValue()));
+        }
+    }
+
+    public OAuth2Authentication readAuthenticationForRefreshToken(OAuth2RefreshToken token) {
+        return this.readAuthentication(token.getValue());
+    }
+
+    public void removeRefreshToken(OAuth2RefreshToken token) {
+        this.remove(token.getValue());
+    }
+
+    public void removeAccessTokenUsingRefreshToken(OAuth2RefreshToken refreshToken) {
+    }
+
+    public OAuth2AccessToken getAccessToken(OAuth2Authentication authentication) {
+        return null;
+    }
+
+    public Collection<OAuth2AccessToken> findTokensByClientIdAndUserName(String clientId, String userName) {
+        return Collections.emptySet();
+    }
+
+    public Collection<OAuth2AccessToken> findTokensByClientId(String clientId) {
+        return Collections.emptySet();
+    }
+
+    public void setTokenEnhancer(JwtAccessTokenConverter tokenEnhancer) {
+        this.jwtTokenEnhancer = tokenEnhancer;
+    }
+
+    private void remove(String token) {
+        if (this.approvalStore != null) {
+            OAuth2Authentication auth = this.readAuthentication(token);
+            String clientId = auth.getOAuth2Request().getClientId();
+            Authentication user = auth.getUserAuthentication();
+            if (user != null) {
+                Collection<Approval> approvals = new ArrayList();
+                Iterator var6 = auth.getOAuth2Request().getScope().iterator();
+
+                while(var6.hasNext()) {
+                    String scope = (String)var6.next();
+                    approvals.add(new Approval(user.getName(), clientId, scope, new Date(), ApprovalStatus.APPROVED));
+                }
+
+                this.approvalStore.revokeApprovals(approvals);
+            }
+        }
+
+    }
+
+    protected Map<String, Object> decode(String token) {
+        try {
+            Jwt jwt = JwtHelper.decodeAndVerify(token,verifier);
+            String claimsStr = jwt.getClaims();
+            Map<String, Object> claims = this.objectMapper.parseMap(claimsStr);
+            if (claims.containsKey("exp") && claims.get("exp") instanceof Integer) {
+                Integer intValue = (Integer)claims.get("exp");
+                claims.put("exp", new Long((long)intValue));
+            }
+
+            jwtClaimsSetVerifier.verify(claims);
+            return claims;
+        } catch (Exception var6) {
+            throw new InvalidTokenException("Cannot convert access token to JSON", var6);
+        }
+    }
+
+
+    private class NoOpJwtClaimsSetVerifier implements JwtClaimsSetVerifier {
+        private NoOpJwtClaimsSetVerifier() {
+        }
+
+        public void verify(Map<String, Object> claims) throws InvalidTokenException {
+        }
+    }
+}

+ 23 - 2
src/main/java/com/diagbot/config/ResourceServerConfigurer.java

@@ -1,5 +1,6 @@
 package com.diagbot.config;
 
+import com.diagbot.util.RedisUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -32,6 +33,10 @@ public class ResourceServerConfigurer extends ResourceServerConfigurerAdapter {
     Logger log = LoggerFactory.getLogger(ResourceServerConfigurer.class);
     @Autowired
     private AuthExceptionEntryPoint authExceptionEntryPoint;
+    @Autowired
+    private AccessDeniedExceptionPoint accessDeniedExceptionPoint;
+    @Autowired
+    private RedisUtils redisUtils;
 
     @Override
     public void configure(HttpSecurity http) throws Exception {
@@ -39,6 +44,8 @@ public class ResourceServerConfigurer extends ResourceServerConfigurerAdapter {
                 .and()
                 .exceptionHandling().authenticationEntryPoint(authExceptionEntryPoint)
                 .and()
+                .exceptionHandling().accessDeniedHandler(accessDeniedExceptionPoint)
+                .and()
                 .csrf().disable()
                 .authorizeRequests()
                 .regexMatchers(".*swagger.*", ".*v2.*", ".*webjars.*", "/druid.*", "/actuator.*", "/hystrix.*").permitAll()
@@ -219,7 +226,6 @@ public class ResourceServerConfigurer extends ResourceServerConfigurerAdapter {
                 .antMatchers("/qc/medLisInfo/getExamineSonPage").permitAll()
                 .antMatchers("/console/medicalCheckForm").permitAll()
                 .antMatchers("/qc/behospitalInfo/analyzeCds").permitAll()
-                .antMatchers("/qc/behospitalInfo/addMedClickInfo").permitAll()
                 .antMatchers("/console/medicalCheckTitle").permitAll()
                 .antMatchers("/console/export/medicalCheckExport").permitAll()
                 .antMatchers("/console/export/medicalCheckInnerExport").permitAll()
@@ -269,6 +275,20 @@ public class ResourceServerConfigurer extends ResourceServerConfigurerAdapter {
                 .antMatchers("/qc/medCheckInfo/addMedCheckInfo").permitAll()
                 .antMatchers("/qc/medCheckInfo/getDataEdit").permitAll()
                 .antMatchers("/qc/medCheckInfo/saveDataEdit").permitAll()
+                .antMatchers("/qc/analysis/addMedClickInfo").permitAll()
+                .antMatchers("/qc/analysis/getQcClickDeptList").permitAll()
+                .antMatchers("/qc/analysis/getQcClick").permitAll()
+                .antMatchers("/qc/analysis/getQcClickByExport").permitAll()
+                .antMatchers("/qc/analysis/getQcClickInnerPage").permitAll()
+                .antMatchers("/qc/analysis/getQcClickInnerPageByExport").permitAll()
+                .antMatchers("/qc/analysis/getEntryDefectImprove").permitAll()
+                .antMatchers("/qc/analysis/getEntryDefectImproveByExport").permitAll()
+                .antMatchers("/qc/analysis/getEntryDefectImproveInner").permitAll()
+                .antMatchers("/qc/analysis/getDefectImproveInnerByExport").permitAll()
+                .antMatchers("/qc/analysisDept/getEntryDefectImproveDept").permitAll()
+                .antMatchers("/qc/analysisDept/getEntryDefectImproveByDeptExport").permitAll()
+                .antMatchers("/qc/analysisDept/getEntryDefectImproveInnerDept").permitAll()
+                .antMatchers("/qc/analysisDept/getDefectImproveInnerByDeptExport").permitAll()
                 .antMatchers("/**").authenticated();
         //                .antMatchers("/**").permitAll();
     }
@@ -276,8 +296,9 @@ public class ResourceServerConfigurer extends ResourceServerConfigurerAdapter {
     @Override
     public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
         log.info("Configuring ResourceServerSecurityConfigurer");
-        resources.resourceId("user-service").tokenStore(new JwtTokenStore(jwtTokenEnhancerClient()));
+        resources.resourceId("user-service").tokenStore(new MyJwtTokenStore(jwtTokenEnhancerClient(),redisUtils));
         resources.authenticationEntryPoint(authExceptionEntryPoint);
+        resources.accessDeniedHandler(accessDeniedExceptionPoint);
     }
 
     @Autowired

+ 22 - 2
src/main/java/com/diagbot/config/security/UrlAccessDecisionManager.java

@@ -36,14 +36,20 @@ public class UrlAccessDecisionManager implements AccessDecisionManager {
         HttpServletRequest request = ((FilterInvocation) object).getHttpRequest();
         String url, method;
         String tokenStr = HttpUtils.getHeaders(request).get("Authorization");
+        if (!request.getMethod().equals("OPTIONS") && StringUtil.isEmpty(tokenStr)) {
+            tokenStr = HttpUtils.getHeaders(request).get("authorization");
+        }
         //用户是否被顶掉校验
         if (StringUtil.isNotEmpty(tokenStr) && !matchNotCheckUrl(request)) {
             tokenStr = tokenStr.replaceFirst("Bearer ", "");
             int res = tokenFacade.newVerifyToken(tokenStr, 1);
             if (-1 == res) {
                 throw new CommonException(ServiceErrorCode.LONGIN_ERROE);
+            } else if (-2 == res) {
+                throw new CommonException(ServiceErrorCode.USER_POWER_UP);
             }
         }
+
         if (matchPermitAllUrl(request)) {
             return;
         }
@@ -55,7 +61,7 @@ public class UrlAccessDecisionManager implements AccessDecisionManager {
 //                Boolean res = tokenFacade.verifyToken(tokenStr, 1);
                 int res = tokenFacade.newVerifyToken(tokenStr, 1);
                 if (-1 == res) {
-                    throw new CommonException(CommonErrorCode.SERVER_IS_ERROR, "该账号在其他地方登录。");
+                    throw new CommonException(ServiceErrorCode.LONGIN_ERROE);
                 } else if (1 != res) {
                     throw new AccountExpiredException("token expire");
                 }
@@ -270,7 +276,6 @@ public class UrlAccessDecisionManager implements AccessDecisionManager {
                 || matchers("/qc/medPacsInfo/getCheckPage", request)
                 || matchers("/qc/medLisInfo/getExaminePage", request)
                 || matchers("/qc/behospitalInfo/analyzeCds", request)
-                || matchers("/qc/behospitalInfo/addMedClickInfo", request)
                 || matchers("/qc/medLisInfo/getExamineSonPage", request)
                 || matchers("/console/medicalCheckForm", request)
                 || matchers("/console/medicalCheckTitle", request)
@@ -322,6 +327,20 @@ public class UrlAccessDecisionManager implements AccessDecisionManager {
                 || matchers("/qc/medCheckInfo/addMedCheckInfo", request)
                 || matchers("/qc/dataEdit/getDataEdit", request)
                 || matchers("/qc/dataEdit/saveDataEdit", request)
+                || matchers("/qc/analysis/addMedClickInfo", request)
+                || matchers("/qc/analysis/getQcClickDeptList", request)
+                || matchers("/qc/analysis/getQcClick", request)
+                || matchers("/qc/analysis/getQcClickByExport", request)
+                || matchers("/qc/analysis/getQcClickInnerPage", request)
+                || matchers("/qc/analysis/getQcClickInnerPageByExport", request)
+                || matchers("/qc/analysis/getEntryDefectImprove", request)
+                || matchers("/qc/analysis/getEntryDefectImproveByExport", request)
+                || matchers("/qc/analysis/getEntryDefectImproveInner", request)
+                || matchers("/qc/analysis/getDefectImproveInnerByExport", request)
+                || matchers("/qc/analysisDept/getEntryDefectImproveDept", request)
+                || matchers("/qc/analysisDept/getEntryDefectImproveByDeptExport", request)
+                || matchers("/qc/analysisDept/getEntryDefectImproveInnerDept", request)
+                || matchers("/qc/analysisDept/getDefectImproveInnerByDeptExport", request)
                 || matchers("/", request)) {
             return true;
         }
@@ -335,6 +354,7 @@ public class UrlAccessDecisionManager implements AccessDecisionManager {
         }
         return false;
     }
+
     private boolean matchNotCheckUrl(HttpServletRequest request) {
         if (matchers("/swagger/**", request)
                 || matchers("/v2/**", request)

+ 94 - 0
src/main/java/com/diagbot/dto/BehospitalAnalysisDTO.java

@@ -0,0 +1,94 @@
+package com.diagbot.dto;
+
+import cn.afterturn.easypoi.excel.annotation.Excel;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * <p>
+ * 住院病历信息
+ * </p>
+ *
+ * @author zhoutg
+ * @since 2020-04-13
+ */
+@Data
+public class BehospitalAnalysisDTO implements Serializable {
+
+    /**
+     * 病历等级
+     */
+    @Excel(name = "病历等级")
+    private String level;
+
+    /**
+     * 最后得分
+     */
+    @Excel(name = "病历得分")
+    private Double scoreRes;
+
+    /**
+     * 病人住院ID
+     */
+    @Excel(name = "病人住院序号",width = 12d)
+    private String behospitalCode;
+
+    /**
+     * 档案号
+     */
+    @Excel(name = "病案号")
+    private String fileCode;
+
+    /**
+     * 姓名
+     */
+    @Excel(name = "病人姓名")
+    private String name;
+
+
+    /**
+     * 年龄
+     */
+    @Excel(name = "年龄")
+    private String age = "";
+
+
+    /**
+     * 入院时间
+     */
+    @Excel(name = "入院日期", exportFormat = "yyyy/MM/dd")
+    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
+    private Date behospitalDate;
+
+    /**
+     * 出院时间
+     */
+    @Excel(name = "出院日期", exportFormat = "yyyy/MM/dd")
+    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
+    private Date leaveHospitalDate;
+
+    /**
+     * 医生姓名
+     */
+    @Excel(name = "主管医生",width = 12d)
+    private String doctorName;
+
+    /**
+     * 住院科室名称
+     */
+    @Excel(name = "科室")
+    private String behDeptName;
+
+    private String behDoctorName;
+
+
+    /**
+     * 评分时间
+     */
+    @Excel(name = "评分时间", exportFormat = "yyyy/MM/dd")
+    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
+    private Date gradeTime;
+}

+ 72 - 0
src/main/java/com/diagbot/dto/BehospitalCodeDetail.java

@@ -0,0 +1,72 @@
+package com.diagbot.dto;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * @Description:
+ * @Author: cy
+ * @time: 2021/12/2 11:04
+ */
+@Data
+public class BehospitalCodeDetail {
+
+    /**
+     * 病人住院ID
+     */
+    private String behospitalCode;
+
+    /**
+     * 姓名
+     */
+    private String name;
+
+    /**
+     * 档案号
+     */
+    private String fileCode;
+
+    /**
+     * 入院时间
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
+    private Date behospitalDate;
+
+    /**
+     * 出院时间
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
+    private Date leaveHospitalDate;
+
+
+    /**
+     * 医生姓名
+     */
+    private String doctorName;
+
+    /**
+     * 年龄
+     */
+    private String age;
+
+    /**
+     * 病历等级
+     */
+    private String level;
+
+    /**
+     * 最后得分
+     */
+    private Double scoreRes;
+
+    /**
+     * 评分时间
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
+    private Date gradeTime;
+
+    List<QcResultDetailInfo> qcResultDetailInfos;
+}

+ 20 - 0
src/main/java/com/diagbot/dto/BehospitalCodeInfo.java

@@ -0,0 +1,20 @@
+package com.diagbot.dto;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @Description:
+ * @Author: cy
+ * @time: 2021/12/2 11:04
+ */
+@Data
+public class BehospitalCodeInfo {
+    /**
+     * 住院号
+     */
+    private String behospitalCode;
+
+    List<QcResultDetailInfo> qcResultDetailInfos;
+}

+ 58 - 37
src/main/java/com/diagbot/dto/BehospitalInfoDTO.java

@@ -1,5 +1,6 @@
 package com.diagbot.dto;
 
+import cn.afterturn.easypoi.excel.annotation.Excel;
 import com.fasterxml.jackson.annotation.JsonFormat;
 import lombok.Data;
 
@@ -20,82 +21,107 @@ public class BehospitalInfoDTO implements Serializable {
     private static final long serialVersionUID = 1L;
 
     /**
-     * 病人住院ID
+     * 住院科室名称
      */
-    private String behospitalCode;
+    @Excel(name = "科室", mergeVertical = true, width = 25d, orderNum = "1")
+    private String behDeptName;
+
+
+    /**
+     * 医生姓名
+     */
+    @Excel(name = "主管医生", orderNum = "2")
+    private String doctorName;
 
+
+    private String behDoctorName;
     /**
      * 姓名
      */
+    @Excel(name = "患者姓名", orderNum = "3")
     private String name;
 
     /**
-     * 性别
+     * 档案号
      */
-    private String sex;
+    @Excel(name = "病案号", orderNum = "4")
+    private String fileCode;
 
     /**
-     * 出生日期
+     * 年龄
      */
-    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
-    private Date birthday;
+    @Excel(name = "年龄", orderNum = "5")
+    private String age = "";
+
 
     /**
-     * 档案号
+     * 入院时间
      */
-    private String fileCode;
+    @Excel(name = "入院时间", orderNum = "6", exportFormat = "yyyy/MM/dd")
+    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
+    private Date behospitalDate;
 
     /**
-     * 病区名称
+     * 出院时间
      */
-    private String wardName;
+    @Excel(name = "出院时间", orderNum = "7", exportFormat = "yyyy/MM/dd")
+    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
+    private Date leaveHospitalDate;
+
 
     /**
-     * 住院科室名称
+     * 最后得分
      */
-    private String behDeptName;
+    @Excel(name = "病历得分", orderNum = "8")
+    private Double scoreRes;
 
     /**
-     * 床位号
+     * 病历等级
      */
-    private String bedCode;
+    @Excel(name = "病历等级", orderNum = "9")
+    private String level;
 
     /**
-     * 入院时间
+     * 评分时间
      */
+    @Excel(name = "评分时间", orderNum = "10", exportFormat = "yyyy/MM/dd")
     @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
-    private Date behospitalDate;
+    private Date gradeTime;
+
 
     /**
-     * 出院时间
+     * 病人住院ID
      */
-    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
-    private Date leaveHospitalDate;
+    private String behospitalCode;
+
 
     /**
-     * 疾病名称
+     * 性别
      */
-    private String diagnose;
+    private String sex;
 
     /**
-     * 医生姓名
+     * 出生日期
      */
-    private String doctorName;
+    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
+    private Date birthday;
 
     /**
-     * 年龄
+     * 病区名称
      */
-    private String age;
+    private String wardName;
 
     /**
-     * 病历等级
+     * 床位号
      */
-    private String level;
+    private String bedCode;
+
 
     /**
-     * 最后得分
+     * 疾病名称
      */
-    private Double scoreRes;
+    private String diagnose;
+
 
     /**
      * 病案首页得分
@@ -107,15 +133,10 @@ public class BehospitalInfoDTO implements Serializable {
      */
     private String gradeType;
 
-    /**
-     * 评分时间
-     */
-    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
-    private Date gradeTime;
 
-    private String directorDoctorName ;
+    private String directorDoctorName;
+
 
-    private String behDoctorName;
 
     /**
      * 归档时间

+ 26 - 0
src/main/java/com/diagbot/dto/EntryDefectImprove.java

@@ -0,0 +1,26 @@
+package com.diagbot.dto;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @Description:
+ * @Author: cy
+ * @time: 2021/12/2 11:04
+ */
+@Data
+public class EntryDefectImprove {
+    /**
+     * 科室id
+     */
+    private String deptId;
+
+    /**
+     * 科室name
+     */
+    private String deptName;
+
+    List<BehospitalCodeInfo> behospitalCodeInfos;
+
+}

+ 24 - 0
src/main/java/com/diagbot/dto/EntryDefectImproveInner.java

@@ -0,0 +1,24 @@
+package com.diagbot.dto;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * @Description:
+ * @Author: cy
+ * @time: 2021/12/2 11:04
+ */
+@Data
+public class EntryDefectImproveInner {
+
+    /**
+     * 住院科室名称
+     */
+    private String behDeptName;
+
+
+    List<BehospitalCodeDetail> behospitalCodeInfos;
+}

+ 25 - 0
src/main/java/com/diagbot/dto/EntryDefectImproveInnerDoctor.java

@@ -0,0 +1,25 @@
+package com.diagbot.dto;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @Description:
+ * @Author: cy
+ * @time: 2021/12/2 11:04
+ */
+@Data
+public class EntryDefectImproveInnerDoctor {
+    /**
+     * 医生id
+     */
+    private String doctorId;
+    /**
+     * 医生姓名
+     */
+    private String doctorName;
+
+
+    List<BehospitalCodeInfo> behospitalCodeInfos;
+}

+ 27 - 0
src/main/java/com/diagbot/dto/EntryDefectImproveInnerExport.java

@@ -0,0 +1,27 @@
+package com.diagbot.dto;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @Description:
+ * @Author: cy
+ * @time: 2021/12/2 11:04
+ */
+@Data
+public class EntryDefectImproveInnerExport {
+
+    /**
+     * 科室id
+     */
+    private String deptId;
+
+    /**
+     * 科室name
+     */
+    private String deptName;
+
+
+    List<EntryDefectImproveInnerDoctor> entryDefectImproveInnerDoctors;
+}

+ 77 - 0
src/main/java/com/diagbot/dto/GetEntryDefectImproveDTO.java

@@ -0,0 +1,77 @@
+package com.diagbot.dto;
+
+import cn.afterturn.easypoi.excel.annotation.Excel;
+import lombok.Data;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.io.Serializable;
+import java.text.DecimalFormat;
+
+/**
+ * @Description:
+ * @author: cy
+ * @time: 2020/9/4 14:59
+ */
+@Data
+public class GetEntryDefectImproveDTO {
+    /**
+     * 科室id
+     */
+    private String deptId;
+
+
+    /**
+     * 科室名称
+     */
+    @Excel(name = "科室", width = 25d, orderNum = "1")
+    private String deptName;
+
+    /**
+     * 模块id
+     */
+    private String casesId;
+
+    /**
+     * 模块名称
+     */
+    @Excel(name = "模块名称", width = 15d, orderNum = "2")
+    private String casesName;
+
+    /**
+     * 缺陷id
+     */
+    private String entryId;
+
+    /**
+     * 缺陷名称
+     */
+    @Excel(name = "缺陷名称", width = 30d, orderNum = "3")
+    private String entryName;
+
+
+    /**
+     * 缺陷总数
+     */
+    @Excel(name = "总数量", width = 10d, orderNum = "4")
+    private Long totalNum = 0L;
+
+    /**
+     * 已改善数
+     */
+    @Excel(name = "已改善数量", width = 13d, orderNum = "5")
+    private Long handleNum = 0L;
+
+    /**
+     * 待改善数
+     */
+    @Excel(name = "待改善数量", width = 13d, orderNum = "6")
+    private Long improveleNum = 0L;
+
+    /**
+     * 改善率
+     */
+    @Excel(name = "改善率", width = 10d, orderNum = "7")
+    private String handleStr = "0.00%";
+
+}

+ 85 - 0
src/main/java/com/diagbot/dto/GetEntryDefectImproveDeptDTO.java

@@ -0,0 +1,85 @@
+package com.diagbot.dto;
+
+import cn.afterturn.easypoi.excel.annotation.Excel;
+import lombok.Data;
+
+/**
+ * @Description:
+ * @author: cy
+ * @time: 2020/9/4 14:59
+ */
+@Data
+public class GetEntryDefectImproveDeptDTO {
+    /**
+     * 科室id
+     */
+    private String deptId;
+
+
+    /**
+     * 科室名称
+     */
+    @Excel(name = "科室", width = 25d, orderNum = "1")
+    private String deptName;
+
+    /**
+     * 模块id
+     */
+    private String casesId;
+
+    /**
+     * 模块名称
+     */
+    @Excel(name = "模块名称", width = 15d, orderNum = "2")
+    private String casesName;
+
+    /**
+     * 缺陷id
+     */
+    private String entryId;
+
+    /**
+     * 缺陷名称
+     */
+    @Excel(name = "缺陷名称", width = 30d, orderNum = "3")
+    private String entryName;
+
+    /**
+     * 主管医生
+     */
+    @Excel(name = "主管医生", width = 10d, orderNum = "4")
+    private String doctorName;
+
+    /**
+     * 医师工号
+     */
+    @Excel(name = "医师工号", width = 10d, orderNum = "5")
+    private String doctorId;
+
+
+
+    /**
+     * 缺陷总数
+     */
+    @Excel(name = "总数量", width = 10d, orderNum = "6")
+    private Long totalNum=0L;
+
+    /**
+     * 已改善数
+     */
+    @Excel(name = "已改善数量", width = 13d, orderNum = "7")
+    private Long handleNum=0L;
+
+    /**
+     * 待改善数
+     */
+    @Excel(name = "待改善数量", width = 13d, orderNum = "8")
+    private Long improveleNum=0L;
+
+    /**
+     * 改善率
+     */
+    @Excel(name = "改善率", width = 10d, orderNum = "9")
+    private String handleStr= "0.00%";
+
+}

+ 35 - 0
src/main/java/com/diagbot/dto/GetEntryInfoDTO.java

@@ -0,0 +1,35 @@
+package com.diagbot.dto;
+
+import cn.afterturn.easypoi.excel.annotation.Excel;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @Description:
+ * @Author: cy
+ * @time: 2021/12/2 11:04
+ */
+@Data
+public class GetEntryInfoDTO {
+    /**
+     * 模块id
+     */
+    private String casesId;
+
+    /**
+     * 模块名称
+     */
+    private String casesName;
+
+    /**
+     * 缺陷id
+     */
+    private String entryId;
+
+    /**
+     * 缺陷名称
+     */
+    private String entryName;
+
+}

+ 40 - 0
src/main/java/com/diagbot/dto/GetQcClickDTO.java

@@ -0,0 +1,40 @@
+package com.diagbot.dto;
+
+import cn.afterturn.easypoi.excel.annotation.Excel;
+import lombok.Getter;
+import lombok.Setter;
+import java.io.Serializable;
+
+/**
+ * @Description:
+ * @author: cy
+ * @time: 2020/9/4 14:59
+ */
+@Getter
+@Setter
+public class GetQcClickDTO implements Serializable {
+
+    /**
+     * 科室id
+     */
+    private String deptId;
+
+    /**
+     * 科室名称
+     */
+    @Excel(name = "科室", width = 30d, orderNum = "1")
+    private String deptName;
+
+    /**
+     * 模块质控按钮点击数
+     */
+    @Excel(name = "模块质控按钮点击数", width = 20d,orderNum = "2")
+    private Integer singleModeNum;
+
+    /**
+     * 全病历质控按钮点击数
+     */
+    @Excel(name = "全病历质控按钮点击数", width = 20d,orderNum = "3")
+    private Integer totalModeNum;
+
+}

+ 52 - 0
src/main/java/com/diagbot/dto/GetQcClickInnerPageDTO.java

@@ -0,0 +1,52 @@
+package com.diagbot.dto;
+
+import cn.afterturn.easypoi.excel.annotation.Excel;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.io.Serializable;
+
+/**
+ * @Description:
+ * @author: cy
+ * @time: 2020/9/4 14:59
+ */
+@Getter
+@Setter
+public class GetQcClickInnerPageDTO implements Serializable {
+    /**
+     * 科室id
+     */
+    private String deptId;
+
+
+    /**
+     * 科室名称
+     */
+    @Excel(name = "科室", width = 30d, orderNum = "1")
+    private String deptName;
+
+    /**
+     * 医师id
+     */
+    @Excel(name = "医师工号", width = 10d, orderNum = "2")
+    private String doctorId;
+
+    /**
+     * 医师姓名
+     */
+    @Excel(name = "医师姓名", width = 10d, orderNum = "3")
+    private String doctorName;
+
+    /**
+     * 模块质控按钮点击数
+     */
+    @Excel(name = "模块质控按钮点击数", width = 20d,orderNum = "4")
+    private Integer singleModeNum;
+
+    /**
+     * 全病历质控按钮点击数
+     */
+    @Excel(name = "全病历质控按钮点击数", width = 20d,orderNum = "5")
+    private Integer totalModeNum;
+}

+ 20 - 0
src/main/java/com/diagbot/dto/QcResultDetailInfo.java

@@ -0,0 +1,20 @@
+package com.diagbot.dto;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @Description:
+ * @Author: cy
+ * @time: 2021/12/2 11:04
+ */
+@Data
+public class QcResultDetailInfo {
+
+    /**
+     * 触发埋点病历质控缺陷id集
+     */
+    private String CasesEntryIds;
+
+}

+ 7 - 2
src/main/java/com/diagbot/entity/MedClickInfo.java

@@ -28,7 +28,7 @@ public class MedClickInfo implements Serializable {
     /**
      * 医院ID
      */
-    private Integer hospitalId;
+    private Long hospitalId;
 
     /**
      * 科室ID
@@ -50,10 +50,15 @@ public class MedClickInfo implements Serializable {
      */
     private String doctorName;
 
+    /**
+     * 0-单模块质控 1-全病历质控
+     */
+    private Long optType;
+
     /**
      * 质控结果基本信息ID
      */
-    private Integer qcresultInfoId;
+    private Long qcresultInfoId;
 
     /**
      * 病人住院ID

+ 61 - 0
src/main/java/com/diagbot/entity/MedQcresultClick.java

@@ -0,0 +1,61 @@
+package com.diagbot.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * <p>
+ * 
+ * </p>
+ *
+ * @author zhanghang
+ * @since 2021-12-02
+ */
+@Data
+public class MedQcresultClick implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    /**
+     * 医院ID
+     */
+    private Long hospitalId;
+
+    /**
+     * 住院号
+     */
+    private String behospitalCode;
+
+    /**
+     * 科室id
+     */
+    private String deptId;
+
+    /**
+     * 科室name
+     */
+    private String deptName;
+
+
+    /**
+     * 评分结果id
+     */
+    private Long qcresultInfoId;
+
+    /**
+     * 触发埋点病历质控缺陷id集
+     */
+    private String CasesEntryIds;
+
+    /**
+     *  记录创建时间
+     */
+    private Date gmtCreate;
+}

+ 2 - 0
src/main/java/com/diagbot/exception/ServiceErrorCode.java

@@ -13,6 +13,8 @@ public enum ServiceErrorCode implements ErrorCode {
     GET_TOKEN_FAIL("10020002", "获取token失败"),
     TOKEN_IS_NOT_MATCH_USER("10020003", "请使用自己的token进行接口请求"),
     LONGIN_ERROE("10020012", "您的账号在其它地方已登录,您已被迫下线,请重新登录。如非本人授权,登录后请及时修改密码。"),
+    USER_POWER_UP("10020012", "您的权限已被管理员修改,您已被迫下线,请重新登录。"),
+    LONGIN_TOKEN_ERROE("10020013", "登录异常"),
 
     SMS_SEND_ERROR("10020004", "短信发送错误"),
     USER_BIND_ERROR("10020005", "用户手机号已经绑定无需再次验证"),

+ 15 - 1
src/main/java/com/diagbot/facade/BasDeptInfoFacade.java

@@ -4,6 +4,7 @@ import com.diagbot.dto.BasDeptInfoDTO;
 import com.diagbot.service.impl.BasDeptInfoServiceImpl;
 import com.diagbot.util.SysUserUtils;
 import com.diagbot.vo.BasDeptInfoVO;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.stereotype.Component;
 
 import java.util.List;
@@ -24,10 +25,23 @@ public class BasDeptInfoFacade extends BasDeptInfoServiceImpl {
      */
     public List<BasDeptInfoDTO> listForUser(BasDeptInfoVO basDeptInfoVO) {
         basDeptInfoVO.setHospitalId(Long.valueOf(SysUserUtils.getCurrentHospitalID()));
+        listForUserSet(basDeptInfoVO);
         List<BasDeptInfoDTO> basDeptInfoDTOList = this.getList(basDeptInfoVO);
         return basDeptInfoDTOList;
     }
-
+    private void listForUserSet(BasDeptInfoVO basDeptInfoVO) {
+        if (StringUtils.isNotBlank(basDeptInfoVO.getInputStr())) {
+            String tranStr = basDeptInfoVO.getInputStr();
+            if( tranStr.contains("%")){
+                tranStr = tranStr.replace("%", "\\%");
+                basDeptInfoVO.setInputStr(tranStr);
+            }
+            if( tranStr.contains("_")){
+                tranStr = tranStr.replace("_","\\_");
+                basDeptInfoVO.setInputStr(tranStr);
+            }
+        }
+    }
 
     /**
      * 获取医院用户下拉列表信息

+ 1 - 16
src/main/java/com/diagbot/facade/BehospitalInfoFacade.java

@@ -1747,7 +1747,7 @@ public class BehospitalInfoFacade extends BehospitalInfoServiceImpl {
             algorithmDTO = (AlgorithmDTO) resMap.get("algorithmDTO");
         }
 
-        List<MsgDTO> msgDTOList = getMsg(analyzeVO);
+        List<MsgDTO> msgDTOList = this.getBaseMapper().getForeignMsg(analyzeVO);
         if (ListUtil.isNotEmpty(msgDTOList)) {
             msgDTOList.forEach(msgDTO -> {
                 if (StringUtils.isNotEmpty(msgDTO.getInfo()) && StringUtils.isNotEmpty(msgDTO.getInfo().trim()) &&
@@ -2508,21 +2508,6 @@ public class BehospitalInfoFacade extends BehospitalInfoServiceImpl {
         return baseMapper.malignancy(filterVO);
     }
 
-    /**
-     * @Description:医生质控信息次数
-     * @Param: [medClickInfoVO]
-     * @return: void
-     * @Author: cy
-     * @Date: 2021/11/10
-     */
-    public Boolean addMedClickInfo(MedClickInfoVO medClickInfoVO) {
-        MedClickInfo medClickInfo = new MedClickInfo();
-        medClickInfo.setHospitalId(Integer.valueOf(SysUserUtils.getCurrentHospitalID()));
-        medClickInfo.setCreator(SysUserUtils.getCurrentPrincipleID());
-        BeanUtil.copyProperties(medClickInfoVO, medClickInfo);
-        medClickInfo.setGmtCreate(new Date());
-        return medClickInfoService.save(medClickInfo);
-    }
 
     /**
      * 获取患者年龄信息(通过出生日期和入院日期重新计算)

+ 215 - 0
src/main/java/com/diagbot/facade/DataAnalysisDeptFacade.java

@@ -0,0 +1,215 @@
+package com.diagbot.facade;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.diagbot.dto.BehospitalCodeInfo;
+import com.diagbot.dto.EntryDefectImproveInnerDoctor;
+import com.diagbot.dto.EntryDefectImproveInnerExport;
+import com.diagbot.dto.GetEntryDefectImproveDeptDTO;
+import com.diagbot.dto.GetEntryInfoDTO;
+import com.diagbot.exception.CommonErrorCode;
+import com.diagbot.exception.CommonException;
+import com.diagbot.service.impl.MedClickInfoServiceImpl;
+import com.diagbot.util.DateUtil;
+import com.diagbot.util.ExcelUtils;
+import com.diagbot.util.ListUtil;
+import com.diagbot.util.SysUserUtils;
+import com.diagbot.vo.GetEntryDefectImproveDeptVO;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.stereotype.Component;
+import javax.servlet.http.HttpServletResponse;
+import java.text.DecimalFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+
+/**
+ * @Description:数据分析
+ * @Author: cy
+ * @time: 2021/11/16 18:28
+ */
+@Component
+public class DataAnalysisDeptFacade {
+    @Autowired
+    @Qualifier("medClickInfoServiceImpl")
+    private MedClickInfoServiceImpl medClickInfoService;
+
+    public IPage<GetEntryDefectImproveDeptDTO> getEntryDefectImproveDept(GetEntryDefectImproveDeptVO getEntryDefectImproveDeptVO) {
+        int current = (int) getEntryDefectImproveDeptVO.getCurrent();
+        int size = (int) getEntryDefectImproveDeptVO.getSize();
+        entryDefectDeptSet(getEntryDefectImproveDeptVO);
+        IPage<GetEntryDefectImproveDeptDTO> page = new Page<>();
+        List<GetEntryDefectImproveDeptDTO> getEntryDefectImproveDeptDTOList = new ArrayList<>();
+        DecimalFormat df = new DecimalFormat("#.00");
+        //获取标准缺陷信息
+        List<GetEntryInfoDTO> entryInfo = medClickInfoService.getBaseMapper().getEntryInfo();
+        //查询基础数据源
+        List<EntryDefectImproveInnerExport> records = medClickInfoService.getBaseMapper().getEntryDefectImproveDept(getEntryDefectImproveDeptVO);
+        //遍历科室
+        for (EntryDefectImproveInnerExport entryDefectImproveInnerExport : records) {
+            List<EntryDefectImproveInnerDoctor> entryDefectImproveInnerDoctors = entryDefectImproveInnerExport.getEntryDefectImproveInnerDoctors();
+            for (EntryDefectImproveInnerDoctor entryDefectImproveInnerDoctor : entryDefectImproveInnerDoctors) {
+                //对科室下医生质控的病历缺陷计数
+                Map<String, Long> totalMap = new HashMap<>();
+                Map<String, Long> improveleMap = new HashMap<>();
+                List<BehospitalCodeInfo> behospitalCodeInfoList = entryDefectImproveInnerDoctor.getBehospitalCodeInfos();
+                //多份病历多次质控评分得到质控缺陷总量、待改善总量
+                DataAnalysisFacade.unitProcessing(behospitalCodeInfoList, totalMap, improveleMap);
+                //按照全院维度进行数据封装
+                for (Map.Entry<String, Long> stringLongEntry : totalMap.entrySet()) {
+                    GetEntryDefectImproveDeptDTO getEntryDefectImproveDeptDTO = new GetEntryDefectImproveDeptDTO();
+                    getEntryDefectImproveDeptDTO.setDeptId(entryDefectImproveInnerExport.getDeptId());
+                    getEntryDefectImproveDeptDTO.setDeptName(entryDefectImproveInnerExport.getDeptName());
+                    getEntryDefectImproveDeptDTO.setDoctorId(entryDefectImproveInnerDoctor.getDoctorId());
+                    getEntryDefectImproveDeptDTO.setDoctorName(entryDefectImproveInnerDoctor.getDoctorName());
+                    getEntryDefectImproveDeptDTO.setEntryId(stringLongEntry.getKey());
+                    getEntryInfoByDept(entryInfo, stringLongEntry, getEntryDefectImproveDeptDTO);
+                    getEntryDefectImproveDeptDTO.setTotalNum(stringLongEntry.getValue());
+                    if (improveleMap.containsKey(stringLongEntry.getKey())) {
+                        getEntryDefectImproveDeptDTO.setImproveleNum(improveleMap.get(stringLongEntry.getKey()));
+                    }
+                    getEntryDefectImproveDeptDTO.setHandleNum(getEntryDefectImproveDeptDTO.getTotalNum() - getEntryDefectImproveDeptDTO.getImproveleNum());
+                    double handleRatio = 0d;
+                    if(getEntryDefectImproveDeptDTO.getTotalNum()!=0 && getEntryDefectImproveDeptDTO.getHandleNum()!=0){
+                        handleRatio = getEntryDefectImproveDeptDTO.getHandleNum().doubleValue()*100/getEntryDefectImproveDeptDTO.getTotalNum().doubleValue();
+                        String handleStr = df.format(handleRatio)+"%";
+                        getEntryDefectImproveDeptDTO.setHandleStr(handleStr);
+                    }
+                    getEntryDefectImproveDeptDTOList.add(getEntryDefectImproveDeptDTO);
+                }
+            }
+        }
+        //(部分模糊查询在此)
+        if (ListUtil.isNotEmpty(getEntryDefectImproveDeptDTOList)) {
+            if (StringUtils.isNotBlank(getEntryDefectImproveDeptVO.getCasesName()) || StringUtils.isNotBlank(getEntryDefectImproveDeptVO.getEntryName())) {
+                getEntryDefectImproveQueryDept(getEntryDefectImproveDeptVO, getEntryDefectImproveDeptDTOList);
+            }
+        }
+
+        //导出操作
+        if (getEntryDefectImproveDeptVO.getExportType() == 1L) {
+            size = getEntryDefectImproveDeptDTOList.size();
+        }
+        page.setSize(size);
+        page.setTotal(getEntryDefectImproveDeptDTOList.size());
+        page.setCurrent(current);
+        //排序操作
+        if (ListUtil.isNotEmpty(getEntryDefectImproveDeptDTOList)) {
+            getEntryDefectImproveDeptDTOList = sortEntryDefectListByDdept(getEntryDefectImproveDeptDTOList, getEntryDefectImproveDeptVO);
+        }
+        //分页操作
+        List<GetEntryDefectImproveDeptDTO> getEntryDefectImproveDeptDTOS = DataAnalysisFacade.page(getEntryDefectImproveDeptDTOList, size, current);
+        page.setRecords(getEntryDefectImproveDeptDTOS);
+        return page;
+    }
+
+    public void getEntryDefectImproveQueryDept(GetEntryDefectImproveDeptVO getEntryDefectImproveDeptVO, List<GetEntryDefectImproveDeptDTO> getEntryDefectImproveDeptDTOList) {
+
+        Iterator<GetEntryDefectImproveDeptDTO> iterator = getEntryDefectImproveDeptDTOList.iterator();
+        while (iterator.hasNext()) {
+            boolean mark = true;
+            GetEntryDefectImproveDeptDTO kfc = iterator.next();
+            if (StringUtils.isNotBlank(getEntryDefectImproveDeptVO.getCasesName()) &&
+                    !kfc.getCasesName().contains(getEntryDefectImproveDeptVO.getCasesName())) {
+                iterator.remove();
+                mark = false;
+            }
+            if (mark && StringUtils.isNotBlank(getEntryDefectImproveDeptVO.getEntryName()) &&
+                    !kfc.getEntryName().contains(getEntryDefectImproveDeptVO.getEntryName())) {
+                iterator.remove();
+            }
+        }
+    }
+
+    public void getEntryDefectImproveByDeptExport(HttpServletResponse response, GetEntryDefectImproveDeptVO getEntryDefectImproveDeptVO) {
+        getEntryDefectImproveDeptVO.setCurrent(1L);
+        getEntryDefectImproveDeptVO.setSize(Long.MAX_VALUE);
+        getEntryDefectImproveDeptVO.setSearchCount(false);
+        getEntryDefectImproveDeptVO.setExportType(1L);
+        IPage<GetEntryDefectImproveDeptDTO> page = getEntryDefectImproveDept(getEntryDefectImproveDeptVO);
+        String fileName = "条目缺陷改善统计(科室).xls";
+        ExcelUtils.exportExcel(page.getRecords(), null, "sheet1", GetEntryDefectImproveDeptDTO.class, fileName, response, 12.8f);
+    }
+
+    private void entryDefectDeptSet(GetEntryDefectImproveDeptVO getEntryDefectImproveDeptVO) {
+        if(StringUtils.isBlank(getEntryDefectImproveDeptVO.getDeptName())){
+            getEntryDefectImproveDeptVO.setDeptName("--");
+        }
+        getEntryDefectImproveDeptVO.setCurrent(1L);
+        getEntryDefectImproveDeptVO.setSize(Long.MAX_VALUE);
+        //入参验证
+        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
+        Date startDate = null;
+        Date endDate = null;
+        try {
+            startDate = simpleDateFormat.parse(getEntryDefectImproveDeptVO.getStartDate());
+            endDate = simpleDateFormat.parse(getEntryDefectImproveDeptVO.getEndDate());
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+        if (DateUtil.after(startDate, endDate)) {
+            throw new CommonException(CommonErrorCode.PARAM_IS_ERROR, "开始时间必须小于结束时间!");
+        }
+        getEntryDefectImproveDeptVO.setHospitalId(Long.parseLong(SysUserUtils.getCurrentHospitalID()));
+    }
+
+    public List<GetEntryDefectImproveDeptDTO> sortEntryDefectListByDdept(List<GetEntryDefectImproveDeptDTO> getEntryDefectImproveDeptDTOS, GetEntryDefectImproveDeptVO getEntryDefectImproveDeptVO) {
+        if (StringUtils.isNotBlank(getEntryDefectImproveDeptVO.getAsc())) {
+            if ("totalNum".equals(getEntryDefectImproveDeptVO.getAsc())) {
+                getEntryDefectImproveDeptDTOS = getEntryDefectImproveDeptDTOS.stream().sorted(Comparator.comparing(GetEntryDefectImproveDeptDTO::getTotalNum)).collect(Collectors.toList());
+
+            }
+            if ("handleNum".equals(getEntryDefectImproveDeptVO.getAsc())) {
+                getEntryDefectImproveDeptDTOS = getEntryDefectImproveDeptDTOS.stream().sorted(Comparator.comparing(GetEntryDefectImproveDeptDTO::getHandleNum)).collect(Collectors.toList());
+
+            }
+            if ("improveleNum".equals(getEntryDefectImproveDeptVO.getAsc())) {
+                getEntryDefectImproveDeptDTOS = getEntryDefectImproveDeptDTOS.stream().sorted(Comparator.comparing(GetEntryDefectImproveDeptDTO::getImproveleNum)).collect(Collectors.toList());
+            }
+        }
+
+        if (StringUtils.isNotBlank(getEntryDefectImproveDeptVO.getDesc())) {
+            if ("totalNum".equals(getEntryDefectImproveDeptVO.getDesc())) {
+                getEntryDefectImproveDeptDTOS = getEntryDefectImproveDeptDTOS.stream().sorted(Comparator.comparing(GetEntryDefectImproveDeptDTO::getTotalNum).reversed()).collect(Collectors.toList());
+
+            }
+            if ("handleNum".equals(getEntryDefectImproveDeptVO.getDesc())) {
+                getEntryDefectImproveDeptDTOS = getEntryDefectImproveDeptDTOS.stream().sorted(Comparator.comparing(GetEntryDefectImproveDeptDTO::getHandleNum).reversed()).collect(Collectors.toList());
+
+            }
+            if ("improveleNum".equals(getEntryDefectImproveDeptVO.getDesc())) {
+                getEntryDefectImproveDeptDTOS = getEntryDefectImproveDeptDTOS.stream().sorted(Comparator.comparing(GetEntryDefectImproveDeptDTO::getImproveleNum).reversed()).collect(Collectors.toList());
+            }
+        }
+        return getEntryDefectImproveDeptDTOS;
+    }
+
+    /**
+     * @Description: 缺陷信息封装
+     * @Param: [entryInfo, stringLongEntry, getEntryDefectImprove]
+     * @return: com.diagbot.dto.GetEntryDefectImproveDTO
+     * @Author: cy
+     * @Date: 2021/12/3
+     */
+    public GetEntryDefectImproveDeptDTO getEntryInfoByDept(List<GetEntryInfoDTO> entryInfo, Map.Entry<String, Long> stringLongEntry,
+                                                           GetEntryDefectImproveDeptDTO getEntryDefectImproveDeptDTO) {
+        entryInfo.parallelStream().filter(kfc -> kfc.getEntryId().equals(stringLongEntry.getKey())).forEach(
+                obj -> {
+                    getEntryDefectImproveDeptDTO.setCasesId(obj.getCasesId());
+                    getEntryDefectImproveDeptDTO.setCasesName(obj.getCasesName());
+                    getEntryDefectImproveDeptDTO.setEntryName(obj.getEntryName());
+                }
+        );
+        return getEntryDefectImproveDeptDTO;
+    }
+}

+ 758 - 0
src/main/java/com/diagbot/facade/DataAnalysisFacade.java

@@ -0,0 +1,758 @@
+package com.diagbot.facade;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.diagbot.dto.BehospitalAnalysisDTO;
+import com.diagbot.dto.BehospitalCodeDetail;
+import com.diagbot.dto.BehospitalCodeInfo;
+import com.diagbot.dto.DeptBaseDTO;
+import com.diagbot.dto.EntryDefectImprove;
+import com.diagbot.dto.EntryDefectImproveInner;
+import com.diagbot.dto.GetEntryDefectImproveDTO;
+import com.diagbot.dto.GetEntryInfoDTO;
+import com.diagbot.dto.GetQcClickDTO;
+import com.diagbot.dto.GetQcClickInnerPageDTO;
+import com.diagbot.dto.QcResultDetailInfo;
+import com.diagbot.entity.BehospitalInfo;
+import com.diagbot.entity.MedClickInfo;
+import com.diagbot.entity.MedQcresultClick;
+import com.diagbot.entity.QcresultDetail;
+import com.diagbot.entity.QcresultInfo;
+import com.diagbot.enums.IsDeleteEnum;
+import com.diagbot.exception.CommonErrorCode;
+import com.diagbot.exception.CommonException;
+import com.diagbot.service.MedQcresultClickService;
+import com.diagbot.service.impl.MedClickInfoServiceImpl;
+import com.diagbot.util.BeanUtil;
+import com.diagbot.util.DateUtil;
+import com.diagbot.util.ExcelUtils;
+import com.diagbot.util.ListUtil;
+import com.diagbot.util.StringUtil;
+import com.diagbot.util.SysUserUtils;
+import com.diagbot.vo.BasDeptInfoVO;
+import com.diagbot.vo.GetEntryDefectImproveInnerVO;
+import com.diagbot.vo.GetEntryDefectImproveVO;
+import com.diagbot.vo.GetQcClickInnerPageVO;
+import com.diagbot.vo.GetQcClickVO;
+import com.diagbot.vo.MedClickInfoVO;
+import org.apache.commons.collections4.MapUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.stereotype.Component;
+
+import javax.servlet.http.HttpServletResponse;
+import java.text.DecimalFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+
+/**
+ * @Description:数据分析
+ * @Author: cy
+ * @time: 2021/11/16 18:28
+ */
+@Component
+public class DataAnalysisFacade {
+    @Autowired
+    @Qualifier("medClickInfoServiceImpl")
+    private MedClickInfoServiceImpl medClickInfoService;
+
+    @Autowired
+    private QcresultInfoFacade qcresultInfoFacade;
+
+    @Autowired
+    private QcresultDetailFacade qcresultDetailFacade;
+
+    @Autowired
+    private MedQcresultClickService medQcresultClickService;
+
+    @Autowired
+    private BehospitalInfoFacade behospitalInfoFacade;
+
+    /**
+     * @Description:医生质控信息次数
+     * @Param: [medClickInfoVO]
+     * @return: void
+     * @Author: cy
+     * @Date: 2021/11/10
+     */
+    public Boolean addMedClickInfo(MedClickInfoVO medClickInfoVO) {
+        BehospitalInfo behospitalInfo = behospitalInfoFacade.lambdaQuery()
+                .eq(BehospitalInfo::getHospitalId, medClickInfoVO.getHospitalId())
+                .eq(BehospitalInfo::getBehospitalCode, medClickInfoVO.getBehospitalCode())
+                .ne(BehospitalInfo::getQcTypeId, "0")
+                .eq(BehospitalInfo::getIsDeleted, IsDeleteEnum.N.getKey())
+                .one();
+        if(null == behospitalInfo){
+            throw new CommonException(CommonErrorCode.FAIL, "该病历不符合要求");
+        }
+
+        MedClickInfo medClickInfo = new MedClickInfo();
+        BeanUtil.copyProperties(medClickInfoVO, medClickInfo);
+        QcresultInfo qcresultInfo = qcresultInfoFacade.lambdaQuery()
+                .eq(QcresultInfo::getHospitalId, medClickInfoVO.getHospitalId())
+                .eq(QcresultInfo::getBehospitalCode, medClickInfoVO.getBehospitalCode())
+                .eq(QcresultInfo::getIsDeleted, IsDeleteEnum.N.getKey())
+                .select(QcresultInfo::getId).one();
+        if (null == qcresultInfo || null == qcresultInfo.getId()
+        ) {
+            throw new CommonException(CommonErrorCode.PARAM_IS_ERROR, "内部参数异常");
+        }
+        medClickInfo.setQcresultInfoId(qcresultInfo.getId());
+        medClickInfo.setGmtCreate(new Date());
+        medClickInfoService.save(medClickInfo);
+
+        List<QcresultDetail> list = qcresultDetailFacade.lambdaQuery()
+                .eq(QcresultDetail::getHospitalId, medClickInfoVO.getHospitalId())
+                .eq(QcresultDetail::getBehospitalCode, medClickInfoVO.getBehospitalCode())
+                .eq(QcresultDetail::getQcresultInfoId, qcresultInfo.getId())
+                .eq(QcresultDetail::getIsDeleted, IsDeleteEnum.N.getKey()).list();
+        if (ListUtil.isNotEmpty(list)) {
+            StringBuilder sbFir = new StringBuilder();
+            for (QcresultDetail qcresultDetail : list) {
+                if (1 == qcresultDetail.getGradeType()) {
+                    if (null != qcresultDetail.getCasesEntryId() && 0L != qcresultDetail.getCasesEntryId()) {
+                        sbFir.append(qcresultDetail.getCasesEntryId() + "、");
+                    }
+                }
+            }
+            if (sbFir.length() > 0) {
+                sbFir = sbFir.deleteCharAt(sbFir.length() - 1);
+            }
+            MedQcresultClick medQcresultClick = new MedQcresultClick();
+            medQcresultClick.setHospitalId(medClickInfoVO.getHospitalId());
+            medQcresultClick.setBehospitalCode(medClickInfoVO.getBehospitalCode());
+            medQcresultClick.setDeptId(behospitalInfo.getBehDeptId());
+            medQcresultClick.setDeptName(behospitalInfo.getBehDeptName());
+            medQcresultClick.setQcresultInfoId(qcresultInfo.getId());
+            medQcresultClick.setCasesEntryIds(sbFir.toString());
+            medQcresultClick.setGmtCreate(new Date());
+            medQcresultClickService.save(medQcresultClick);
+        }
+        return true;
+    }
+
+    public List<DeptBaseDTO> getQcClickDeptList(BasDeptInfoVO basDeptInfoVO) {
+        long hospitalId = Long.parseLong(SysUserUtils.getCurrentHospitalID());
+        List<DeptBaseDTO> deptDTO = new ArrayList<>();
+        List<MedClickInfo> deptList = medClickInfoService.lambdaQuery()
+                .eq(MedClickInfo::getHospitalId, hospitalId)
+                .eq(MedClickInfo::getIsDeleted, IsDeleteEnum.N.getKey())
+                .like(MedClickInfo::getDeptName, basDeptInfoVO.getInputStr())
+                .select(MedClickInfo::getDeptId, MedClickInfo::getDeptName)
+                .groupBy(MedClickInfo::getDeptId)
+                .groupBy(MedClickInfo::getDeptName)
+                .list();
+        if (ListUtil.isNotEmpty(deptList)) {
+            for (MedClickInfo kfc : deptList) {
+                if (null == kfc) {
+                    return deptDTO;
+                }
+                DeptBaseDTO deptBaseDTO = new DeptBaseDTO();
+                deptBaseDTO.setDeptId(kfc.getDeptId());
+                deptBaseDTO.setDeptName(kfc.getDeptName());
+                deptDTO.add(deptBaseDTO);
+            }
+        }
+        return deptDTO;
+    }
+
+    public List<GetQcClickDTO> getQcClick(GetQcClickVO getQcClickVO) {
+        clickPageSet(getQcClickVO);
+        List<GetQcClickDTO> records = medClickInfoService.getBaseMapper().getQcClick(getQcClickVO);
+        //没有科室过滤时增加全院数据
+        if (StringUtil.isBlank(getQcClickVO.getDeptName()) || getQcClickVO.getDeptName().equals("全院")) {
+            GetQcClickDTO item = getGlobleTitle(records);
+            if (item != null) {
+                records.add(0, item);
+            }
+        }
+        return records;
+    }
+
+
+    public void getQcClickByExport(HttpServletResponse response, GetQcClickVO getQcClickVO) {
+        List<GetQcClickDTO> records = getQcClick(getQcClickVO);
+        String fileName = "临床质控使用统计.xls";
+        ExcelUtils.exportExcel(records, null, "sheet1", GetQcClickDTO.class, fileName, response, 12.8f);
+    }
+
+    public IPage<GetQcClickInnerPageDTO> getQcClickInnerPage(GetQcClickInnerPageVO getQcClickInnerPageVO) {
+        clickInnerPageSet(getQcClickInnerPageVO);
+        IPage<GetQcClickInnerPageDTO> records = medClickInfoService.getBaseMapper().getQcClickInnerPage(getQcClickInnerPageVO);
+        return records;
+    }
+
+    public void getQcClickInnerPageByExport(HttpServletResponse response, GetQcClickInnerPageVO getQcClickInnerPageVO) {
+        getQcClickInnerPageVO.setCurrent(1L);
+        getQcClickInnerPageVO.setSize(Long.MAX_VALUE);
+        getQcClickInnerPageVO.setSearchCount(false);
+        IPage<GetQcClickInnerPageDTO> page = getQcClickInnerPage(getQcClickInnerPageVO);
+        String fileName = "临床质控使用统计内页.xls";
+        ExcelUtils.exportExcel(page.getRecords(), null, "sheet1", GetQcClickInnerPageDTO.class, fileName, response, 12.8f);
+    }
+
+    public IPage<GetEntryDefectImproveDTO> getEntryDefectImprove(GetEntryDefectImproveVO getEntryDefectImproveVO) {
+        int current = (int) getEntryDefectImproveVO.getCurrent();
+        int size = (int) getEntryDefectImproveVO.getSize();
+        IPage<GetEntryDefectImproveDTO> page = new Page<>();
+        entryDefectSet(getEntryDefectImproveVO);
+        DecimalFormat df = new DecimalFormat("#.00");
+        List<GetEntryDefectImproveDTO> getEntryDefectImproveDTO = new ArrayList<>();
+        //获取标准缺陷信息
+        List<GetEntryInfoDTO> entryInfo = medClickInfoService.getBaseMapper().getEntryInfo();
+        //查询基础数据源
+        List<EntryDefectImprove> records = medClickInfoService.getBaseMapper().getEntryDefectImprove(getEntryDefectImproveVO);
+        //遍历科室
+        for (EntryDefectImprove entryDefectImprove : records) {
+            Map<String, Long> totalMap = new HashMap<>();
+            Map<String, Long> improveleMap = new HashMap<>();
+            List<BehospitalCodeInfo> behospitalCodeInfoList = entryDefectImprove.getBehospitalCodeInfos();
+            //多份病历多次质控评分得到质控缺陷总量、待改善总量
+            unitProcessing(behospitalCodeInfoList, totalMap, improveleMap);
+            //按照全院维度进行数据封装
+            for (Map.Entry<String, Long> stringLongEntry : totalMap.entrySet()) {
+                //封装DTO
+                GetEntryDefectImproveDTO getEntryDefectImprove = new GetEntryDefectImproveDTO();
+                getEntryDefectImprove.setDeptId(entryDefectImprove.getDeptId());
+                getEntryDefectImprove.setDeptName(entryDefectImprove.getDeptName());
+                getEntryDefectImprove.setEntryId(stringLongEntry.getKey());
+                getEntryInfo(entryInfo, stringLongEntry, getEntryDefectImprove);
+                getEntryDefectImprove.setTotalNum(stringLongEntry.getValue());
+                if (improveleMap.containsKey(stringLongEntry.getKey())) {
+                    getEntryDefectImprove.setImproveleNum(improveleMap.get(stringLongEntry.getKey()));
+                }
+                getEntryDefectImprove.setHandleNum(getEntryDefectImprove.getTotalNum() - getEntryDefectImprove.getImproveleNum());
+                double handleRatio = 0d;
+                if(getEntryDefectImprove.getTotalNum()!=0 && getEntryDefectImprove.getHandleNum()!=0){
+                    handleRatio = getEntryDefectImprove.getHandleNum().doubleValue()*100/getEntryDefectImprove.getTotalNum().doubleValue();
+                    String handleStr = df.format(handleRatio)+"%";
+                    getEntryDefectImprove.setHandleStr(handleStr);
+                }
+                getEntryDefectImproveDTO.add(getEntryDefectImprove);
+            }
+        }
+        //(部分模糊查询在此)
+            if (ListUtil.isNotEmpty(getEntryDefectImproveDTO)) {
+                if (StringUtils.isNotBlank(getEntryDefectImproveVO.getCasesName()) || StringUtils.isNotBlank(getEntryDefectImproveVO.getEntryName())) {
+                getEntryDefectImproveQuery(getEntryDefectImproveVO, getEntryDefectImproveDTO);
+            }
+        }
+
+
+        //导出操作
+        if (getEntryDefectImproveVO.getExportType() == 1L) {
+            size = getEntryDefectImproveDTO.size();
+        }
+        page.setSize(size);
+        page.setTotal(getEntryDefectImproveDTO.size());
+        page.setCurrent(current);
+        //排序操作
+        if (ListUtil.isNotEmpty(getEntryDefectImproveDTO)) {
+            getEntryDefectImproveDTO =  sortEntryDefectList( getEntryDefectImproveDTO ,getEntryDefectImproveVO);
+        }
+        //分页操作
+        List<GetEntryDefectImproveDTO> getEntryDefectImproveDTOS = page(getEntryDefectImproveDTO, size, current);
+        page.setRecords(getEntryDefectImproveDTOS);
+        return page;
+    }
+
+    /**
+     * @Description: 缺陷信息封装
+     * @Param: [entryInfo, stringLongEntry, getEntryDefectImprove]
+     * @return: com.diagbot.dto.GetEntryDefectImproveDTO
+     * @Author: cy
+     * @Date: 2021/12/3
+     */
+    public GetEntryDefectImproveDTO getEntryInfo(List<GetEntryInfoDTO> entryInfo, Map.Entry<String, Long> stringLongEntry,
+                                                 GetEntryDefectImproveDTO getEntryDefectImprove) {
+        entryInfo.parallelStream().filter(kfc -> kfc.getEntryId().equals(stringLongEntry.getKey())).forEach(
+                obj -> {
+                    getEntryDefectImprove.setCasesId(obj.getCasesId());
+                    getEntryDefectImprove.setCasesName(obj.getCasesName());
+                    getEntryDefectImprove.setEntryName(obj.getEntryName());
+                }
+        );
+        return getEntryDefectImprove;
+    }
+
+    /**
+     * @Description: 多份病历多次质控评分得到质控缺陷总量、待改善总量
+     * @Param: [behospitalCodeInfoList, totalMap, improveleMap]
+     * @return: void
+     * @Author: cy
+     * @Date: 2021/12/3
+     */
+    public static void unitProcessing(List<BehospitalCodeInfo> behospitalCodeInfoList, Map<String, Long> totalMap,
+                                      Map<String, Long> improveleMap) {
+        for (BehospitalCodeInfo behospitalCodeInfo : behospitalCodeInfoList) {
+            //病历下
+            List<QcResultDetailInfo> qcResultDetailInfos = behospitalCodeInfo.getQcResultDetailInfos();
+                //获取多病历多质控质控缺陷总量
+                totalMap = getEntryTotalMap(qcResultDetailInfos, totalMap);
+                if (MapUtils.isNotEmpty(totalMap)) {
+                    //获取多病历多质控质控缺陷待改善总量
+                    QcResultDetailInfo qcResultDetailInfo = qcResultDetailInfos.get(qcResultDetailInfos.size() - 1);
+                    improveleMap = getEntryImproveleMap(qcResultDetailInfo, improveleMap);
+                }
+        }
+    }
+
+
+    public void getEntryDefectImproveQuery(GetEntryDefectImproveVO getEntryDefectImproveVO, List<GetEntryDefectImproveDTO> getEntryDefectImproveDTO) {
+        Iterator<GetEntryDefectImproveDTO> iterator = getEntryDefectImproveDTO.iterator();
+        while (iterator.hasNext()) {
+            boolean mark = true;
+            GetEntryDefectImproveDTO kfc = iterator.next();
+            if (StringUtils.isNotBlank(getEntryDefectImproveVO.getCasesName()) &&
+                    !kfc.getCasesName().contains(getEntryDefectImproveVO.getCasesName())) {
+                iterator.remove();
+                mark = false;
+            }
+            if (mark && StringUtils.isNotBlank(getEntryDefectImproveVO.getEntryName()) &&
+                    !kfc.getEntryName().contains(getEntryDefectImproveVO.getEntryName())) {
+                iterator.remove();
+            }
+        }
+    }
+
+    /**
+     * @Description:分页数据
+     * @Param: [dataList, pageSize, currentPage]
+     * @return: java.util.List<java.lang.String>
+     * @Author: cy
+     * @Date: 2021/12/2
+     */
+    public static <T> List<T> page(List<T> retRecords, int pageSize, int currentPage) {
+        List<T> currentPageList = new ArrayList<>();
+        if (retRecords != null && retRecords.size() > 0) {
+            int currIdx = (currentPage > 1 ? (currentPage - 1) * pageSize : 0);
+            for (int i = 0; i < pageSize && i < retRecords.size() - currIdx; i++) {
+                T data = retRecords.get(currIdx + i);
+                currentPageList.add(data);
+            }
+        }
+        return currentPageList;
+    }
+
+    public  List<BehospitalAnalysisDTO>  getEntryDefectImproveInnerDTOS( List<BehospitalAnalysisDTO> behospitalInfoDTOList ,GetEntryDefectImproveInnerVO
+            getEntryDefectImproveInnerVO) {
+        if(StringUtils.isNotBlank(getEntryDefectImproveInnerVO.getAsc())){
+            if("behDeptName".equals(getEntryDefectImproveInnerVO.getAsc())){
+                behospitalInfoDTOList = behospitalInfoDTOList.stream().sorted(Comparator.comparing(BehospitalAnalysisDTO::getBehDeptName, Comparator.nullsLast(String::compareTo))).collect(Collectors.toList());
+            }
+            if("behDoctorName".equals(getEntryDefectImproveInnerVO.getAsc()) || "doctorName".equals(getEntryDefectImproveInnerVO.getAsc())){
+                behospitalInfoDTOList = behospitalInfoDTOList.stream().sorted(Comparator.comparing(BehospitalAnalysisDTO::getDoctorName, Comparator.nullsLast(String::compareTo))).collect(Collectors.toList());
+            }
+            if("name".equals(getEntryDefectImproveInnerVO.getAsc())){
+                behospitalInfoDTOList = behospitalInfoDTOList.stream().sorted(Comparator.comparing(BehospitalAnalysisDTO::getName, Comparator.nullsLast(String::compareTo))).collect(Collectors.toList());
+            }
+            if("fileCode".equals(getEntryDefectImproveInnerVO.getAsc())){
+                behospitalInfoDTOList = behospitalInfoDTOList.stream().sorted(Comparator.comparing(BehospitalAnalysisDTO::getFileCode, Comparator.nullsLast(String::compareTo))).collect(Collectors.toList());
+            }
+            if("behospitalCode".equals(getEntryDefectImproveInnerVO.getAsc())){
+                behospitalInfoDTOList = behospitalInfoDTOList.stream().sorted(Comparator.comparing(BehospitalAnalysisDTO::getBehospitalCode, Comparator.nullsLast(String::compareTo))).collect(Collectors.toList());
+            }
+            if("age".equals(getEntryDefectImproveInnerVO.getAsc())){
+                behospitalInfoDTOList = behospitalInfoDTOList.stream().sorted(Comparator.comparing(BehospitalAnalysisDTO::getAge, Comparator.nullsLast(String::compareTo))).collect(Collectors.toList());
+            }
+            if("behospitalDate".equals(getEntryDefectImproveInnerVO.getAsc())){
+                behospitalInfoDTOList = behospitalInfoDTOList.stream().sorted(Comparator.comparing(BehospitalAnalysisDTO::getBehospitalDate, Comparator.nullsLast(Date::compareTo))).collect(Collectors.toList());
+            }
+            if("leaveHospitalDate".equals(getEntryDefectImproveInnerVO.getAsc())){
+                behospitalInfoDTOList = behospitalInfoDTOList.stream().sorted(Comparator.comparing(BehospitalAnalysisDTO::getLeaveHospitalDate, Comparator.nullsLast(Date::compareTo))).collect(Collectors.toList());
+            }
+            if("scoreRes".equals(getEntryDefectImproveInnerVO.getAsc())){
+                behospitalInfoDTOList = behospitalInfoDTOList.stream().sorted(Comparator.comparing(BehospitalAnalysisDTO::getScoreRes, Comparator.nullsLast(Double::compareTo))).collect(Collectors.toList());
+            }
+            if("level".equals(getEntryDefectImproveInnerVO.getAsc())){
+                behospitalInfoDTOList = behospitalInfoDTOList.stream().sorted(Comparator.comparing(BehospitalAnalysisDTO::getLevel, Comparator.nullsLast(String::compareTo))).collect(Collectors.toList());
+            }
+            if("gradeTime".equals(getEntryDefectImproveInnerVO.getAsc())){
+                behospitalInfoDTOList = behospitalInfoDTOList.stream().sorted(Comparator.comparing(BehospitalAnalysisDTO::getGradeTime, Comparator.nullsLast(Date::compareTo))).collect(Collectors.toList());
+            }
+        }
+
+        if(StringUtils.isNotBlank(getEntryDefectImproveInnerVO.getDesc())){
+            if("behDeptName".equals(getEntryDefectImproveInnerVO.getDesc())){
+                behospitalInfoDTOList = behospitalInfoDTOList.stream().sorted(Comparator.comparing(BehospitalAnalysisDTO::getBehDeptName, Comparator.nullsLast(String::compareTo)).reversed()).collect(Collectors.toList());
+            }
+            if("behDoctorName".equals(getEntryDefectImproveInnerVO.getDesc()) || "doctorName".equals(getEntryDefectImproveInnerVO.getDesc())){
+                behospitalInfoDTOList = behospitalInfoDTOList.stream().sorted(Comparator.comparing(BehospitalAnalysisDTO::getDoctorName, Comparator.nullsLast(String::compareTo)).reversed()).collect(Collectors.toList());
+            }
+            if("name".equals(getEntryDefectImproveInnerVO.getDesc())){
+                behospitalInfoDTOList = behospitalInfoDTOList.stream().sorted(Comparator.comparing(BehospitalAnalysisDTO::getName, Comparator.nullsLast(String::compareTo)).reversed()).collect(Collectors.toList());
+            }
+            if("fileCode".equals(getEntryDefectImproveInnerVO.getDesc())){
+                behospitalInfoDTOList = behospitalInfoDTOList.stream().sorted(Comparator.comparing(BehospitalAnalysisDTO::getFileCode, Comparator.nullsLast(String::compareTo)).reversed()).collect(Collectors.toList());
+            }
+            if("behospitalCode".equals(getEntryDefectImproveInnerVO.getDesc())){
+                behospitalInfoDTOList = behospitalInfoDTOList.stream().sorted(Comparator.comparing(BehospitalAnalysisDTO::getBehospitalCode, Comparator.nullsLast(String::compareTo)).reversed()).collect(Collectors.toList());
+            }
+            if("age".equals(getEntryDefectImproveInnerVO.getDesc())){
+                behospitalInfoDTOList = behospitalInfoDTOList.stream().sorted(Comparator.comparing(BehospitalAnalysisDTO::getAge, Comparator.nullsLast(String::compareTo)).reversed()).collect(Collectors.toList());
+            }
+            if("behospitalDate".equals(getEntryDefectImproveInnerVO.getDesc())){
+                behospitalInfoDTOList = behospitalInfoDTOList.stream().sorted(Comparator.comparing(BehospitalAnalysisDTO::getBehospitalDate, Comparator.nullsLast(Date::compareTo)).reversed()).collect(Collectors.toList());
+            }
+            if("leaveHospitalDate".equals(getEntryDefectImproveInnerVO.getDesc())){
+                behospitalInfoDTOList = behospitalInfoDTOList.stream().sorted(Comparator.comparing(BehospitalAnalysisDTO::getLeaveHospitalDate, Comparator.nullsLast(Date::compareTo)).reversed()).collect(Collectors.toList());
+            }
+            if("scoreRes".equals(getEntryDefectImproveInnerVO.getDesc())){
+                behospitalInfoDTOList = behospitalInfoDTOList.stream().sorted(Comparator.comparing(BehospitalAnalysisDTO::getScoreRes, Comparator.nullsLast(Double::compareTo)).reversed()).collect(Collectors.toList());
+            }
+            if("level".equals(getEntryDefectImproveInnerVO.getDesc())){
+                behospitalInfoDTOList = behospitalInfoDTOList.stream().sorted(Comparator.comparing(BehospitalAnalysisDTO::getLevel, Comparator.nullsLast(String::compareTo)).reversed()).collect(Collectors.toList());
+            }
+            if("gradeTime".equals(getEntryDefectImproveInnerVO.getDesc())){
+                behospitalInfoDTOList = behospitalInfoDTOList.stream().sorted(Comparator.comparing(BehospitalAnalysisDTO::getGradeTime, Comparator.nullsLast(Date::compareTo)).reversed()).collect(Collectors.toList());
+            }
+        }
+        return behospitalInfoDTOList;
+    }
+    public  List<GetEntryDefectImproveDTO>  sortEntryDefectList( List<GetEntryDefectImproveDTO> getEntryDefectImproveDTOS ,GetEntryDefectImproveVO getEntryDefectImproveVO) {
+        if(StringUtils.isNotBlank(getEntryDefectImproveVO.getAsc())){
+            if("totalNum".equals(getEntryDefectImproveVO.getAsc())){
+                getEntryDefectImproveDTOS = getEntryDefectImproveDTOS.stream().sorted(Comparator.comparing(GetEntryDefectImproveDTO::getTotalNum)).collect(Collectors.toList());
+
+            }
+            if("handleNum".equals(getEntryDefectImproveVO.getAsc())){
+                getEntryDefectImproveDTOS = getEntryDefectImproveDTOS.stream().sorted(Comparator.comparing(GetEntryDefectImproveDTO::getHandleNum)).collect(Collectors.toList());
+
+            }
+            if("improveleNum".equals(getEntryDefectImproveVO.getAsc())){
+                getEntryDefectImproveDTOS = getEntryDefectImproveDTOS.stream().sorted(Comparator.comparing(GetEntryDefectImproveDTO::getImproveleNum)).collect(Collectors.toList());
+            }
+        }
+
+        if(StringUtils.isNotBlank(getEntryDefectImproveVO.getDesc())){
+            if("totalNum".equals(getEntryDefectImproveVO.getDesc())){
+                getEntryDefectImproveDTOS = getEntryDefectImproveDTOS.stream().sorted(Comparator.comparing(GetEntryDefectImproveDTO::getTotalNum).reversed()).collect(Collectors.toList());
+
+            }
+            if("handleNum".equals(getEntryDefectImproveVO.getDesc())){
+                getEntryDefectImproveDTOS = getEntryDefectImproveDTOS.stream().sorted(Comparator.comparing(GetEntryDefectImproveDTO::getHandleNum).reversed()).collect(Collectors.toList());
+
+            }
+            if("improveleNum".equals(getEntryDefectImproveVO.getDesc())){
+                getEntryDefectImproveDTOS = getEntryDefectImproveDTOS.stream().sorted(Comparator.comparing(GetEntryDefectImproveDTO::getImproveleNum).reversed()).collect(Collectors.toList());
+            }
+        }
+        return getEntryDefectImproveDTOS;
+    }
+
+    public static Map getEntryTotalMap(List<QcResultDetailInfo> qcResultDetailInfos, Map<String, Long> totalMap) {
+        Set<String> totalSet = new HashSet<String>();
+        for (QcResultDetailInfo qcResultDetailInfo : qcResultDetailInfos) {
+                //质控下获取科室下总缺陷
+                String casesEntryIds = qcResultDetailInfo.getCasesEntryIds();
+                totalSet = getSetEntry(casesEntryIds, totalSet);
+        }
+        if (null == totalSet && totalSet.size() == 0) {
+            return totalMap;
+        }
+        totalMap = getSetEntryCount(totalMap, totalSet);
+        return totalMap;
+    }
+
+    public static Map getEntryImproveleMap(QcResultDetailInfo qcResultDetailInfo, Map<String, Long> improveMap) {
+        Set<String> improveleSet = new HashSet<String>();
+        String casesEntryIds = qcResultDetailInfo.getCasesEntryIds();
+        improveleSet = getSetEntry(casesEntryIds, improveleSet);
+        improveMap = getSetEntryCount(improveMap, improveleSet);
+        return improveMap;
+    }
+
+    public static Set getSetEntry(String casesEntryIds, Set set) {
+        if (StringUtils.isNotBlank(casesEntryIds) && !"0".equals(casesEntryIds)) {
+            if (casesEntryIds.contains("、")) {
+                String[] split = casesEntryIds.split("、");
+                for (String id : split) {
+                    set.add(id);
+                }
+            } else {
+                set.add(casesEntryIds);
+            }
+        }
+        return set;
+    }
+
+    public static Map getSetEntryCount(Map<String, Long> map, Set<String> sets) {
+        if (null != sets && sets.size() > 0) {
+        for (String set : sets) {
+            if (map.containsKey(set)) {
+                long count = map.get(set) + 1l;
+                map.put(set, count);
+            } else {
+                map.put(set, 1L);
+                }
+            }
+        }
+        return map;
+    }
+
+    public void getEntryDefectImproveByExport(HttpServletResponse response, GetEntryDefectImproveVO
+            getEntryDefectImproveVO) {
+        getEntryDefectImproveVO.setExportType(1L);
+        getEntryDefectImproveVO.setCurrent(1L);
+        getEntryDefectImproveVO.setSize(Long.MAX_VALUE);
+        getEntryDefectImproveVO.setSearchCount(false);
+        IPage<GetEntryDefectImproveDTO> page = getEntryDefectImprove(getEntryDefectImproveVO);
+        String fileName = "条目缺陷改善统计.xls";
+        ExcelUtils.exportExcel(page.getRecords(), null, "sheet1", GetEntryDefectImproveDTO.class, fileName, response, 12.8f);
+    }
+
+
+    public IPage<BehospitalAnalysisDTO> getEntryDefectImproveInner(GetEntryDefectImproveInnerVO
+                                                                       getEntryDefectImproveInnerVO) {
+        int current = (int) getEntryDefectImproveInnerVO.getCurrent();
+        int size = (int) getEntryDefectImproveInnerVO.getSize();
+        IPage<BehospitalAnalysisDTO> page = new Page<>();
+        List<BehospitalAnalysisDTO> behospitalInfoDTOS = new ArrayList<>();
+        entryDefectInnerSet(getEntryDefectImproveInnerVO);
+        // List<GetEntryInfoDTO> entryInfo = medClickInfoService.getBaseMapper().getEntryInfo();
+        List<EntryDefectImproveInner> records = medClickInfoService.getBaseMapper().getEntryDefectImproveInner(getEntryDefectImproveInnerVO);
+        if (ListUtil.isNotEmpty(records) && records.size() == 1) {
+            EntryDefectImproveInner entryDefectImproveInner = records.get(0);
+            List<BehospitalCodeDetail> behospitalCodeDetails = entryDefectImproveInner.getBehospitalCodeInfos();
+            for (BehospitalCodeDetail behospitalCodeDetail : behospitalCodeDetails) {
+                List<QcResultDetailInfo> qcResultDetailInfos = behospitalCodeDetail.getQcResultDetailInfos();
+                Set<String> totalSet = new HashSet<String>();
+                Set<String> improveleSet = new HashSet<String>();
+                for (QcResultDetailInfo qcResultDetailInfo : qcResultDetailInfos) {
+                    String casesEntryIds = qcResultDetailInfo.getCasesEntryIds();
+                    totalSet = getSetEntry(casesEntryIds, totalSet);
+                }
+                QcResultDetailInfo qcResultDetailInfo = qcResultDetailInfos.get(qcResultDetailInfos.size() - 1);
+                if (null != qcResultDetailInfo && StringUtils.isNotBlank(qcResultDetailInfo.getCasesEntryIds())) {
+                    improveleSet = getSetEntry(qcResultDetailInfo.getCasesEntryIds(), improveleSet);
+                }
+                if ("0".equals(getEntryDefectImproveInnerVO.getTypeMark()) && totalSet.contains(getEntryDefectImproveInnerVO.getEntryId())) {
+                    behospitalInfoDTOS = getBehospitalInfoDTO(entryDefectImproveInner, behospitalCodeDetail, behospitalInfoDTOS);
+                }
+                if ("1".equals(getEntryDefectImproveInnerVO.getTypeMark()) && totalSet.contains(getEntryDefectImproveInnerVO.getEntryId())
+                        && !improveleSet.contains(getEntryDefectImproveInnerVO.getEntryId())) {
+                    behospitalInfoDTOS = getBehospitalInfoDTO(entryDefectImproveInner, behospitalCodeDetail, behospitalInfoDTOS);
+                }
+                if ("2".equals(getEntryDefectImproveInnerVO.getTypeMark()) && totalSet.contains(getEntryDefectImproveInnerVO.getEntryId())
+                        && improveleSet.contains(getEntryDefectImproveInnerVO.getEntryId())) {
+                    behospitalInfoDTOS = getBehospitalInfoDTO(entryDefectImproveInner, behospitalCodeDetail, behospitalInfoDTOS);
+                }
+            }
+        }
+        //导出操作
+        if (getEntryDefectImproveInnerVO.getExportType() == 1L) {
+            size = behospitalInfoDTOS.size();
+        }
+        page.setSize(size);
+        page.setTotal(behospitalInfoDTOS.size());
+        page.setCurrent(current);
+        //排序操作
+        if (ListUtil.isNotEmpty(behospitalInfoDTOS)) {
+            behospitalInfoDTOS =  getEntryDefectImproveInnerDTOS( behospitalInfoDTOS ,getEntryDefectImproveInnerVO);
+        }
+        //分页操作
+        List<BehospitalAnalysisDTO> behospitalInfoDTOList = page(behospitalInfoDTOS, size, current);
+        page.setRecords(behospitalInfoDTOList);
+        return page;
+    }
+
+    /**
+     * @Description: 数据封装
+     * @Param: [entryDefectImproveInner, behospitalCodeDetail, qcResultDetailInfo, behospitalInfoDTOS]
+     * @return: java.util.List<com.diagbot.dto.BehospitalInfoDTO>
+     * @Author: cy
+     * @Date: 2021/12/3
+     */
+    public List<BehospitalAnalysisDTO> getBehospitalInfoDTO(EntryDefectImproveInner entryDefectImproveInner, BehospitalCodeDetail behospitalCodeDetail,
+                                                        List<BehospitalAnalysisDTO> behospitalInfoDTOS) {
+        BehospitalAnalysisDTO behospitalInfoDTO = new BehospitalAnalysisDTO();
+        behospitalInfoDTO.setLevel(behospitalCodeDetail.getLevel());
+        behospitalInfoDTO.setScoreRes(behospitalCodeDetail.getScoreRes());
+        behospitalInfoDTO.setFileCode(behospitalCodeDetail.getFileCode());
+        behospitalInfoDTO.setBehospitalCode(behospitalCodeDetail.getBehospitalCode());
+        behospitalInfoDTO.setName(behospitalCodeDetail.getName());
+        behospitalInfoDTO.setAge(behospitalCodeDetail.getAge());
+        behospitalInfoDTO.setBehospitalDate(behospitalCodeDetail.getBehospitalDate());
+        behospitalInfoDTO.setLeaveHospitalDate(behospitalCodeDetail.getLeaveHospitalDate());
+        behospitalInfoDTO.setDoctorName(behospitalCodeDetail.getDoctorName());
+        behospitalInfoDTO.setBehDoctorName(behospitalCodeDetail.getDoctorName());
+        behospitalInfoDTO.setBehDeptName(entryDefectImproveInner.getBehDeptName());
+        behospitalInfoDTO.setGradeTime(behospitalCodeDetail.getGradeTime());
+        behospitalInfoDTOS.add(behospitalInfoDTO);
+        return behospitalInfoDTOS;
+    }
+
+    public void getDefectImproveInnerByExport(HttpServletResponse response, GetEntryDefectImproveInnerVO
+            getEntryDefectImproveInnerVO) {
+        getEntryDefectImproveInnerVO.setExportType(1L);
+        getEntryDefectImproveInnerVO.setCurrent(1L);
+        getEntryDefectImproveInnerVO.setSize(Long.MAX_VALUE);
+        getEntryDefectImproveInnerVO.setSearchCount(false);
+        String fileName = "条目缺陷改善统计病历列表.xls";
+        IPage<BehospitalAnalysisDTO> page = this.getEntryDefectImproveInner(getEntryDefectImproveInnerVO);
+        ExcelUtils.exportExcelUser(page.getRecords(), null, "sheet1", BehospitalAnalysisDTO.class, fileName, response);
+    }
+
+    /**
+     * 增加全院记录
+     *
+     * @param records
+     * @return
+     */
+    public GetQcClickDTO getGlobleTitle(List<GetQcClickDTO> records) {
+        GetQcClickDTO item = new GetQcClickDTO();
+        if (ListUtil.isEmpty(records)) {
+            return null;
+        }
+
+        //缺陷总数
+        Integer singleMode = records
+                .stream()
+                .map(GetQcClickDTO::getSingleModeNum)
+                .reduce(0, Integer::sum);
+        if (singleMode == null) {
+            singleMode = 0;
+        }
+        Integer totalMode = records
+                .stream()
+                .map(GetQcClickDTO::getTotalModeNum)
+                .reduce(0, Integer::sum);
+        if (totalMode == null) {
+            totalMode = 0;
+        }
+        item.setDeptName("全院");
+        item.setSingleModeNum(singleMode);
+        item.setTotalModeNum(totalMode);
+        return item;
+    }
+
+    private void clickPageSet(GetQcClickVO getQcClickVO) {
+        if(StringUtils.isNotBlank(getQcClickVO.getDeptName())){
+            getQcClickVO.setDeptName(transferredMeaning(getQcClickVO.getDeptName()));
+        }
+        //入参验证
+        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
+        Date startDate = null;
+        Date endDate = null;
+        try {
+            startDate = simpleDateFormat.parse(getQcClickVO.getStartDate());
+            endDate = simpleDateFormat.parse(getQcClickVO.getEndDate());
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+        if (DateUtil.after(startDate, endDate)) {
+            throw new CommonException(CommonErrorCode.PARAM_IS_ERROR, "开始时间必须小于结束时间!");
+        }
+        getQcClickVO.setHospitalId(Long.parseLong(SysUserUtils.getCurrentHospitalID()));
+    }
+
+    private void clickInnerPageSet(GetQcClickInnerPageVO getQcClickInnerPageVO) {
+        if(StringUtils.isNotBlank(getQcClickInnerPageVO.getDoctorId())){
+            getQcClickInnerPageVO.setDoctorId(transferredMeaning(getQcClickInnerPageVO.getDoctorId()));
+        }
+        if(StringUtils.isNotBlank(getQcClickInnerPageVO.getDoctorName())){
+            getQcClickInnerPageVO.setDoctorName(transferredMeaning(getQcClickInnerPageVO.getDoctorName()));
+        }
+        //入参验证
+        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
+        Date startDate = null;
+        Date endDate = null;
+        try {
+            startDate = simpleDateFormat.parse(getQcClickInnerPageVO.getStartDate());
+            endDate = simpleDateFormat.parse(getQcClickInnerPageVO.getEndDate());
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+        if (DateUtil.after(startDate, endDate)) {
+            throw new CommonException(CommonErrorCode.PARAM_IS_ERROR, "开始时间必须小于结束时间!");
+        }
+        getQcClickInnerPageVO.setHospitalId(Long.parseLong(SysUserUtils.getCurrentHospitalID()));
+    }
+
+   public String transferredMeaning(String tranStr){
+          if( tranStr.contains("%")){
+              tranStr = tranStr.replace("%", "\\%");
+          }
+           if( tranStr.contains("_")){
+              tranStr = tranStr.replace("_","\\_");
+           }
+       return tranStr;
+    };
+    private void entryDefectSet(GetEntryDefectImproveVO getEntryDefectImproveVO) {
+        if(StringUtils.isNotBlank(getEntryDefectImproveVO.getDeptName())){
+            getEntryDefectImproveVO.setDeptName(transferredMeaning(getEntryDefectImproveVO.getDeptName()));
+        }
+        getEntryDefectImproveVO.setCurrent(1L);
+        getEntryDefectImproveVO.setSize(Long.MAX_VALUE);
+        //入参验证
+        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
+        Date startDate = null;
+        Date endDate = null;
+        try {
+            startDate = simpleDateFormat.parse(getEntryDefectImproveVO.getStartDate());
+            endDate = simpleDateFormat.parse(getEntryDefectImproveVO.getEndDate());
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+        if (DateUtil.after(startDate, endDate)) {
+            throw new CommonException(CommonErrorCode.PARAM_IS_ERROR, "开始时间必须小于结束时间!");
+        }
+        getEntryDefectImproveVO.setHospitalId(Long.parseLong(SysUserUtils.getCurrentHospitalID()));
+    }
+
+    private void entryDefectInnerSet(GetEntryDefectImproveInnerVO getEntryDefectImproveInnerVO) {
+        if(StringUtils.isNotBlank(getEntryDefectImproveInnerVO.getPatName())){
+            getEntryDefectImproveInnerVO.setPatName(transferredMeaning(getEntryDefectImproveInnerVO.getPatName()));
+        }
+        if(StringUtils.isNotBlank(getEntryDefectImproveInnerVO.getDoctorId())){
+            getEntryDefectImproveInnerVO.setDoctorId(transferredMeaning(getEntryDefectImproveInnerVO.getDoctorId()));
+        }
+        if(StringUtils.isNotBlank(getEntryDefectImproveInnerVO.getDoctorName())){
+            getEntryDefectImproveInnerVO.setDoctorName(transferredMeaning(getEntryDefectImproveInnerVO.getDoctorName()));
+        }
+        getEntryDefectImproveInnerVO.setCurrent(1L);
+        getEntryDefectImproveInnerVO.setSize(Long.MAX_VALUE);
+        //入参验证
+        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
+        Date startDate = null;
+        Date endDate = null;
+        try {
+            startDate = simpleDateFormat.parse(getEntryDefectImproveInnerVO.getStartDate());
+            endDate = simpleDateFormat.parse(getEntryDefectImproveInnerVO.getEndDate());
+
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+        if (DateUtil.after(startDate, endDate)) {
+            throw new CommonException(CommonErrorCode.PARAM_IS_ERROR, "开始时间必须小于结束时间!");
+        }
+        if (StringUtils.isNotBlank(getEntryDefectImproveInnerVO.getChTimeStart())
+                && StringUtils.isNotBlank(getEntryDefectImproveInnerVO.getChTimeEnd())
+        ) {
+            Date chTimeStartDate = null;
+            Date chTimeEndDate = null;
+            try {
+                chTimeStartDate = simpleDateFormat.parse(getEntryDefectImproveInnerVO.getChTimeStart());
+                chTimeEndDate = simpleDateFormat.parse(getEntryDefectImproveInnerVO.getChTimeStart());
+            } catch (ParseException e) {
+                e.printStackTrace();
+            }
+            if (DateUtil.after(chTimeStartDate, chTimeEndDate)) {
+                throw new CommonException(CommonErrorCode.PARAM_IS_ERROR, "病历核查开始时间必须小于结束时间!");
+            }
+        }
+        getEntryDefectImproveInnerVO.setHospitalId(Long.parseLong(SysUserUtils.getCurrentHospitalID()));
+    }
+}

+ 9 - 0
src/main/java/com/diagbot/facade/SysDictionaryFacade.java

@@ -61,4 +61,13 @@ public class SysDictionaryFacade extends SysDictionaryInfoServiceImpl {
         return res;
     }
 
+    public long getAccessTokenOutTime() {
+        long accessToken = 24 * 3600*1l;
+        if (getDictionaryWithKey() != null
+                && getDictionaryWithKey().containsKey("31")
+                && getDictionaryWithKey().get("31").containsKey("accessToken")) {
+            accessToken = Long.parseLong(getDictionaryWithKey().get("31").get("accessToken"));
+        }
+        return accessToken;
+    }
 }

+ 6 - 0
src/main/java/com/diagbot/facade/SysUserFacade.java

@@ -215,6 +215,10 @@ public class SysUserFacade extends SysUserServiceImpl {
         jwtStore.setAccessToken(jwt.getAccess_token());
         jwtStore.setRefreshToken(jwt.getRefresh_token());
         tokenFacade.createToken(jwtStore);
+
+        //每次登录在redis缓存该用户登录成功的token;缓存时间为token有效时间
+        long accessTokenTime = sysDictionaryFacade.getAccessTokenOutTime();
+        redisUtils.set("user:refreshToken:outTime_" + user.getId(), accessTokenTime, accessTokenTime);
         /***
          * 未经过MD5加密密码复杂度判断
          */
@@ -703,6 +707,8 @@ public class SysUserFacade extends SysUserServiceImpl {
             }
             sysUserDeptService.saveBatch(sysUserDeptList);
         }
+        //删除Token
+        tokenFacade.deleteToken(sysUserDeptVO.getUserId().toString());
         //更新用户表
         return this.update(new UpdateWrapper<SysUser>()
                 .eq("is_deleted", IsDeleteEnum.N.getKey())

+ 1 - 0
src/main/java/com/diagbot/mapper/BehospitalInfoMapper.java

@@ -24,6 +24,7 @@ public interface BehospitalInfoMapper extends BaseMapper<BehospitalInfo> {
     public IPage<BehospitalInfoDTO> getPage(BehospitalPageVO behospitalPageVO);
 
     public List<MsgDTO> getMsg(AnalyzeVO analyzeVO);
+    public List<MsgDTO> getForeignMsg(AnalyzeVO analyzeVO);
 
     public List<MsgDTO> getMsgByEntryCode(AnalyzeCodeVO analyzeCodeVO);
 

+ 22 - 1
src/main/java/com/diagbot/mapper/MedClickInfoMapper.java

@@ -1,7 +1,22 @@
 package com.diagbot.mapper;
 
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.diagbot.dto.EntryDefectImprove;
+import com.diagbot.dto.EntryDefectImproveInner;
+import com.diagbot.dto.EntryDefectImproveInnerExport;
+import com.diagbot.dto.ExportExcelDTO;
+import com.diagbot.dto.GetEntryInfoDTO;
+import com.diagbot.dto.GetQcClickDTO;
+import com.diagbot.dto.GetQcClickInnerPageDTO;
 import com.diagbot.entity.MedClickInfo;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.diagbot.vo.GetEntryDefectImproveDeptVO;
+import com.diagbot.vo.GetEntryDefectImproveInnerVO;
+import com.diagbot.vo.GetEntryDefectImproveVO;
+import com.diagbot.vo.GetQcClickInnerPageVO;
+import com.diagbot.vo.GetQcClickVO;
+
+import java.util.List;
 
 /**
  * <p>
@@ -12,5 +27,11 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
  * @since 2021-11-10
  */
 public interface MedClickInfoMapper extends BaseMapper<MedClickInfo> {
-
+    public List<GetQcClickDTO> getQcClick(GetQcClickVO getQcClickVO);
+    public IPage<GetQcClickInnerPageDTO> getQcClickInnerPage(GetQcClickInnerPageVO getQcClickInnerPageVO);
+    public List<EntryDefectImprove> getEntryDefectImprove(GetEntryDefectImproveVO getEntryDefectImproveVO);
+    public List<GetEntryInfoDTO> getEntryInfo();
+    public List<EntryDefectImproveInnerExport> getEntryDefectImproveDept(GetEntryDefectImproveDeptVO getEntryDefectImproveDeptVO);
+    public List<EntryDefectImproveInner> getEntryDefectImproveInner(GetEntryDefectImproveInnerVO getEntryDefectImproveInnerVO);
+    public List<ExportExcelDTO> getDefectImproveInnerByExport(GetEntryDefectImproveInnerVO getEntryDefectImproveInnerVO);
 }

+ 16 - 0
src/main/java/com/diagbot/mapper/MedQcresultClickMapper.java

@@ -0,0 +1,16 @@
+package com.diagbot.mapper;
+
+import com.diagbot.entity.MedQcresultClick;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author zhanghang
+ * @since 2021-12-02
+ */
+public interface MedQcresultClickMapper extends BaseMapper<MedQcresultClick> {
+
+}

+ 16 - 0
src/main/java/com/diagbot/service/MedQcresultClickService.java

@@ -0,0 +1,16 @@
+package com.diagbot.service;
+
+import com.diagbot.entity.MedQcresultClick;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * <p>
+ *  服务类
+ * </p>
+ *
+ * @author zhanghang
+ * @since 2021-12-02
+ */
+public interface MedQcresultClickService extends IService<MedQcresultClick> {
+
+}

+ 20 - 0
src/main/java/com/diagbot/service/impl/MedQcresultClickServiceImpl.java

@@ -0,0 +1,20 @@
+package com.diagbot.service.impl;
+
+import com.diagbot.entity.MedQcresultClick;
+import com.diagbot.mapper.MedQcresultClickMapper;
+import com.diagbot.service.MedQcresultClickService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ *  服务实现类
+ * </p>
+ *
+ * @author zhanghang
+ * @since 2021-12-02
+ */
+@Service
+public class MedQcresultClickServiceImpl extends ServiceImpl<MedQcresultClickMapper, MedQcresultClick> implements MedQcresultClickService {
+
+}

+ 1 - 1
src/main/java/com/diagbot/service/impl/SysTokenServiceImpl.java

@@ -175,7 +175,7 @@ public class SysTokenServiceImpl implements SysTokenService {
                 }
             }
         } else {
-            res = -1;
+            res = -2;       //redis取不到token原因是因为用户权限修改被清空掉了,如果是到时钱被清空会先提示用户登录超时
         }
 
         return res;

+ 14 - 2
src/main/java/com/diagbot/util/SysUserUtils.java

@@ -1,5 +1,7 @@
 package com.diagbot.util;
 
+import com.diagbot.exception.CommonException;
+import com.diagbot.exception.ServiceErrorCode;
 import org.springframework.security.core.Authentication;
 import org.springframework.security.core.authority.SimpleGrantedAuthority;
 import org.springframework.security.core.context.SecurityContextHolder;
@@ -41,7 +43,12 @@ public class SysUserUtils {
      * @return
      */
     public static String getCurrentPrincipleID() {
-        OAuth2AuthenticationDetails oauthDetails = (OAuth2AuthenticationDetails) SecurityContextHolder.getContext().getAuthentication().getDetails();
+        OAuth2AuthenticationDetails oauthDetails = null;
+        try {
+            oauthDetails = (OAuth2AuthenticationDetails) SecurityContextHolder.getContext().getAuthentication().getDetails();
+        }catch (ClassCastException e){
+            throw new CommonException(ServiceErrorCode.LONGIN_TOKEN_ERROE);
+        }
         return SysJwtUtil.getUserId(oauthDetails.getTokenValue());
     }
 
@@ -51,7 +58,12 @@ public class SysUserUtils {
      * @return
      */
     public static String getCurrentHospitalID() {
-        OAuth2AuthenticationDetails oauthDetails = (OAuth2AuthenticationDetails) SecurityContextHolder.getContext().getAuthentication().getDetails();
+        OAuth2AuthenticationDetails oauthDetails = null;
+        try {
+            oauthDetails = (OAuth2AuthenticationDetails) SecurityContextHolder.getContext().getAuthentication().getDetails();
+        }catch (ClassCastException e){
+            throw new CommonException(ServiceErrorCode.LONGIN_TOKEN_ERROE);
+        }
         return SysJwtUtil.getHospId(oauthDetails.getTokenValue());
     }
 

+ 74 - 0
src/main/java/com/diagbot/vo/GetEntryDefectImproveDeptVO.java

@@ -0,0 +1,74 @@
+package com.diagbot.vo;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+
+import javax.validation.constraints.NotNull;
+
+/**
+ * @Description:
+ * @author: cy
+ * @time: 2020/9/4 14:59
+ */
+@Getter
+@Setter
+public class GetEntryDefectImproveDeptVO extends Page {
+    /**
+     * 医院id
+     */
+    @ApiModelProperty(hidden = true)
+    private Long hospitalId;
+
+    /**
+     * 科室id
+     */
+    private String deptId;
+
+    /**
+     * 科室名称
+     */
+    private String deptName;
+
+    /**
+     * 主管医生
+     */
+    private String doctorName;
+
+    /**
+     * 医师工号
+     */
+    private String doctorId;
+
+    /**
+     * 缺陷名称
+     */
+    private String entryName;
+
+    /**
+     * 模块名称
+     */
+    private String casesName;
+
+    @NotNull(message = "请输入起始时间")
+    private String startDate;
+
+    @NotNull(message = "请输入截止时间")
+    private String endDate;
+    /**
+     * 0-不导出 1-导出
+     */
+    private Long exportType = 0L;
+
+    /**
+     * 排序(升序)
+     */
+    private String asc;
+
+    /**
+     * 排序(降序)
+     */
+    private String desc;
+
+}

+ 115 - 0
src/main/java/com/diagbot/vo/GetEntryDefectImproveInnerVO.java

@@ -0,0 +1,115 @@
+package com.diagbot.vo;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+import javax.validation.constraints.NotNull;
+
+/**
+ * @Description:
+ * @Author:zhaops
+ * @time: 2020/6/16 17:00
+ */
+@Getter
+@Setter
+public class GetEntryDefectImproveInnerVO extends Page {
+    @ApiModelProperty(hidden = true)
+    private Long userId;
+    @ApiModelProperty(hidden = true)
+    private Long hospitalId;
+    /**
+     * 病历号
+     */
+    private String behospitalCode;
+    /**
+     * 病人姓名
+     */
+    private String patName;
+
+
+    /**
+     * 条目id
+     */
+    private String entryId;
+
+    /**
+     * 条目缺陷名称
+     */
+    private String entryName;
+
+    /**
+     * 主诊断
+     */
+    private String diagnose;
+
+    /**
+     * 科室id
+     */
+    private String deptId;
+
+    /**
+     * 科室名称
+     */
+    private String deptName;
+
+    /**
+     * 医生编号
+     */
+    private String doctorId;
+
+    /**
+     * 医生姓名
+     */
+    private String doctorName;
+
+    /**
+     * 病历等级
+     */
+    private String level;
+
+    @NotNull(message = "请输入起始时间")
+    private String startDate;
+
+    @NotNull(message = "请输入截止时间")
+    private String endDate;
+
+    /**
+     * 核查状态(1:已核查,0:未核查)
+     */
+    private Integer checkStatus;
+
+    /**
+     * 病历核查人员
+     */
+    private String chName;
+
+    /**
+     * 病历核查起始时间
+     */
+    private String chTimeStart;
+    /**
+     * 病历核查截止时间
+     */
+    private String chTimeEnd;
+
+    /**
+     * 总数量-0,已改善数量-1,待改善数量-2
+     */
+    private String typeMark;
+
+    /**
+     * 排序(升序)
+     */
+    private String asc;
+
+    /**
+     * 排序(降序)
+     */
+    private String desc;
+
+    /**
+     * 0-不导出 1-导出
+     */
+    private Long exportType = 0L;
+}

+ 65 - 0
src/main/java/com/diagbot/vo/GetEntryDefectImproveVO.java

@@ -0,0 +1,65 @@
+package com.diagbot.vo;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import javax.validation.constraints.NotNull;
+
+/**
+ * @Description:
+ * @author: cy
+ * @time: 2020/9/4 14:59
+ */
+@Getter
+@Setter
+public class GetEntryDefectImproveVO extends Page {
+    /**
+     * 医院id
+     */
+    @ApiModelProperty(hidden = true)
+    private Long hospitalId;
+
+    /**
+     * 科室id
+     */
+    private String deptId;
+
+    /**
+     * 科室名称
+     */
+    private String deptName;
+
+    /**
+     * 缺陷名称
+     */
+    private String entryName;
+
+    /**
+     * 模块名称
+     */
+    private String casesName;
+
+    @NotNull(message = "请输入起始时间")
+    private String startDate;
+
+    @NotNull(message = "请输入截止时间")
+    private String endDate;
+    /**
+     * 0-不导出 1-导出
+     */
+    private Long exportType = 0L;
+
+    /**
+     * 排序(升序)
+     */
+    private String asc;
+
+    /**
+     * 排序(降序)
+     */
+    private String desc;
+
+}

+ 51 - 0
src/main/java/com/diagbot/vo/GetQcClickInnerPageVO.java

@@ -0,0 +1,51 @@
+package com.diagbot.vo;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import javax.validation.constraints.NotNull;
+
+/**
+ * @Description:
+ * @author: cy
+ * @time: 2020/9/4 14:59
+ */
+@Getter
+@Setter
+public class GetQcClickInnerPageVO extends Page {
+    /**
+     * 医院id
+     */
+    @ApiModelProperty(hidden = true)
+    private Long hospitalId;
+
+    /**
+     * 科室id
+     */
+    private String deptId;
+
+    /**
+     * 科室名称
+     */
+    private String deptName;
+
+    /**
+     * 医师id
+     */
+    private String doctorId;
+
+    /**
+     * 医师名称
+     */
+    private String doctorName;
+
+    @NotNull(message = "请输入起始时间")
+    private String startDate;
+
+    @NotNull(message = "请输入截止时间")
+    private String endDate;
+
+}

+ 54 - 0
src/main/java/com/diagbot/vo/GetQcClickVO.java

@@ -0,0 +1,54 @@
+package com.diagbot.vo;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import java.util.Date;
+
+/**
+ * @Description:
+ * @author: cy
+ * @time: 2020/9/4 14:59
+ */
+@Getter
+@Setter
+public class GetQcClickVO{
+    /**
+     * 医院id
+     */
+    @ApiModelProperty(hidden = true)
+    private Long hospitalId;
+
+    /**
+     * 科室id
+     */
+    private String deptId;
+
+    /**
+     * 科室名称
+     */
+    private String deptName;
+
+    /**
+     * 排序(升序)
+     */
+    private String asc;
+
+    /**
+     * 排序(降序)
+     */
+    private String desc;
+
+
+    @NotNull(message = "请输入起始时间")
+    private String startDate;
+
+    @NotNull(message = "请输入截止时间")
+    private String endDate;
+}

+ 15 - 5
src/main/java/com/diagbot/vo/MedClickInfoVO.java

@@ -1,5 +1,8 @@
 package com.diagbot.vo;
 import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
 import java.io.Serializable;
 
 /**
@@ -16,35 +19,42 @@ public class MedClickInfoVO implements Serializable {
     /**
      * 医院ID
      */
-    private Integer hospitalId;
+    @NotNull(message = "请输入医院id")
+    private Long hospitalId;
 
     /**
      * 科室ID
      */
+    @NotBlank(message = "请输入科室id")
     private String deptId;
 
     /**
      * 科室名称
      */
+    @NotBlank(message = "请输入科室名称")
     private String deptName;
 
     /**
      * 医生ID
      */
+    @NotBlank(message = "请输入医生id")
     private String doctorId;
 
     /**
      * 医生姓名
      */
+    @NotBlank(message = "请输入医生姓名")
     private String doctorName;
 
     /**
-     * 质控结果基本信息ID
+     * 病人住院ID
      */
-    private Integer qcresultInfoId;
+    @NotBlank(message = "请输入病历住院id")
+    private String behospitalCode;
 
     /**
-     * 病人住院ID
+     * 0-单模块质控 1-全病历质控
      */
-    private String behospitalCode;
+    private Long optType;
+
 }

+ 1 - 7
src/main/java/com/diagbot/web/BehospitalInfoController.java

@@ -284,11 +284,5 @@ public class BehospitalInfoController {
         return RespDTO.onSuc(behospitalInfoFacade.analyzeCds(analyzeCdsVO));
     }
 
-    @ApiOperation(value = "记录医生点击质控病历信息[by:cy]",
-            notes = "")
-    @PostMapping("/addMedClickInfo")
-    @SysLogger("addMedClickInfo")
-    public RespDTO<Boolean> addMedClickInfo(@RequestBody MedClickInfoVO medClickInfoVO) {
-        return RespDTO.onSuc(behospitalInfoFacade.addMedClickInfo(medClickInfoVO));
-    }
+
 }

+ 169 - 0
src/main/java/com/diagbot/web/DataAnalysisController.java

@@ -0,0 +1,169 @@
+package com.diagbot.web;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.diagbot.annotation.SysLogger;
+import com.diagbot.dto.BehospitalInfoDTO;
+import com.diagbot.dto.DeptBaseDTO;
+import com.diagbot.dto.GetQcClickDTO;
+import com.diagbot.dto.GetQcClickInnerPageDTO;
+import com.diagbot.dto.RespDTO;
+import com.diagbot.dto.GetEntryDefectImproveDTO;
+import com.diagbot.facade.DataAnalysisFacade;
+import com.diagbot.vo.BasDeptInfoVO;
+import com.diagbot.vo.GetEntryDefectImproveInnerVO;
+import com.diagbot.vo.GetQcClickInnerPageVO;
+import com.diagbot.vo.GetQcClickVO;
+import com.diagbot.vo.GetEntryDefectImproveVO;
+import com.diagbot.vo.MedClickInfoVO;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletResponse;
+import javax.validation.Valid;
+import java.util.List;
+
+/**
+ * @Description:数据分析
+ * @Author: cy
+ * @time: 2021/11/16 18:28
+ */
+@RestController
+@Api(value = "数据分析相关API", tags = { "数据分析相关API" })
+@RequestMapping("/qc/analysis")
+public class DataAnalysisController {
+
+    @Autowired
+    DataAnalysisFacade dataAnalysisFacade;
+
+    @ApiOperation(value = "记录医生点击质控病历信息[by:cy]")
+    @PostMapping("/addMedClickInfo")
+    @SysLogger("addMedClickInfo")
+    @Transactional
+    public RespDTO<Boolean> addMedClickInfo(@RequestBody @Valid MedClickInfoVO medClickInfoVO) {
+        return RespDTO.onSuc(dataAnalysisFacade.addMedClickInfo(medClickInfoVO));
+    }
+
+    /**
+     * 临床质控使用统计科室列表返回
+     *
+     * @param
+     * @return
+     */
+    @ApiOperation(value = "临床质控使用统计科室列表[by:cy]")
+    @PostMapping("/getQcClickDeptList")
+    @SysLogger("getQcClickDeptList")
+    public RespDTO<List<DeptBaseDTO>> getQcClickDeptList(@RequestBody BasDeptInfoVO basDeptInfoVO) {
+        return RespDTO.onSuc(dataAnalysisFacade.getQcClickDeptList(basDeptInfoVO));
+    }
+    /**
+     * 临床质控使用统计
+     *
+     * @param getQcClickVO
+     * @return
+     */
+    @ApiOperation(value = "临床质控使用统计[by:cy]")
+    @PostMapping("/getQcClick")
+    @SysLogger("getQcClick")
+    public RespDTO<List<GetQcClickDTO>> getQcClick(@RequestBody @Valid GetQcClickVO getQcClickVO) {
+        return RespDTO.onSuc(dataAnalysisFacade.getQcClick(getQcClickVO));
+    }
+
+    /**
+     * 临床质控使用统计-导出
+     *
+     * @param getQcClickVO
+     * @return
+     */
+    @ApiOperation(value = "临床质控使用统计-导出[by:cy]")
+    @PostMapping("/getQcClickByExport")
+    @SysLogger("getQcClickByExport")
+    public void getQcClickByExport(HttpServletResponse response, @RequestBody @Valid GetQcClickVO getQcClickVO) {
+        dataAnalysisFacade.getQcClickByExport(response, getQcClickVO);
+    }
+
+
+    /**
+     * 临床质控使用统计-内页
+     *
+     * @param getQcClickInnerPageVO
+     * @return
+     */
+    @ApiOperation(value = "临床质控使用统计-内页[by:cy]")
+    @PostMapping("/getQcClickInnerPage")
+    @SysLogger("getQcClickInnerPage")
+    public RespDTO<IPage<GetQcClickInnerPageDTO>> getQcClickInnerPage(@RequestBody @Valid GetQcClickInnerPageVO getQcClickInnerPageVO) {
+        return RespDTO.onSuc(dataAnalysisFacade.getQcClickInnerPage(getQcClickInnerPageVO));
+    }
+
+    /**
+     * 临床质控使用统计-内页导出
+     *
+     * @param getQcClickInnerPageVO
+     * @return
+     */
+    @ApiOperation(value = "临床质控使用统计-内页导出[by:cy]")
+    @PostMapping("/getQcClickInnerPageByExport")
+    @SysLogger("getQcClickInnerPageByExport")
+    public void getQcClickInnerPageByExport(HttpServletResponse response, @RequestBody @Valid GetQcClickInnerPageVO getQcClickInnerPageVO) {
+        dataAnalysisFacade.getQcClickInnerPageByExport(response, getQcClickInnerPageVO);
+    }
+
+    /**
+     * 条目缺陷改善统计
+     *
+     * @param getEntryDefectImproveVO
+     * @return
+     */
+    @ApiOperation(value = "条目缺陷改善统计[by:cy]")
+    @PostMapping("/getEntryDefectImprove")
+    @SysLogger("getEntryDefectImprove")
+    public RespDTO<IPage<GetEntryDefectImproveDTO>> getEntryDefectImprove(@RequestBody @Valid GetEntryDefectImproveVO getEntryDefectImproveVO) {
+        return RespDTO.onSuc(dataAnalysisFacade.getEntryDefectImprove(getEntryDefectImproveVO));
+    }
+
+    /**
+     * 条目缺陷改善统计-导出
+     *
+     * @param getEntryDefectImproveVO
+     * @return
+     */
+    @ApiOperation(value = "条目缺陷改善统计-导出[by:cy]")
+    @PostMapping("/getEntryDefectImproveByExport")
+    @SysLogger("getEntryDefectImproveByExport")
+    public void getEntryDefectImproveByExport(HttpServletResponse response, @RequestBody @Valid GetEntryDefectImproveVO getEntryDefectImproveVO) {
+        dataAnalysisFacade.getEntryDefectImproveByExport(response, getEntryDefectImproveVO);
+    }
+
+
+    /**
+     * 条目缺陷改善统计-内页
+     *
+     * @param getEntryDefectImproveInnerVO
+     * @return
+     */
+    @ApiOperation(value = "条目缺陷改善统计-内页[by:cy]")
+    @PostMapping("/getEntryDefectImproveInner")
+    @SysLogger("getEntryDefectImproveInner")
+    public RespDTO<IPage<BehospitalInfoDTO>> getEntryDefectImproveInner(@RequestBody GetEntryDefectImproveInnerVO getEntryDefectImproveInnerVO) {
+        return RespDTO.onSuc(dataAnalysisFacade.getEntryDefectImproveInner(getEntryDefectImproveInnerVO));
+    }
+
+    /**
+     * 条目缺陷改善统计-内页导出
+     *
+     * @param getEntryDefectImproveInnerVO
+     * @return
+     */
+    @ApiOperation(value = "条目缺陷改善统计-内页导出[by:cy]")
+    @PostMapping("/getDefectImproveInnerByExport")
+    @SysLogger("getDefectImproveInnerByExport")
+    public void getDefectImproveInnerByExport(HttpServletResponse response, @RequestBody GetEntryDefectImproveInnerVO getEntryDefectImproveInnerVO) {
+        dataAnalysisFacade.getDefectImproveInnerByExport(response, getEntryDefectImproveInnerVO);
+    }
+}

+ 94 - 0
src/main/java/com/diagbot/web/DataAnalysisDeptController.java

@@ -0,0 +1,94 @@
+package com.diagbot.web;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.diagbot.annotation.SysLogger;
+import com.diagbot.dto.BehospitalInfoDTO;
+import com.diagbot.dto.GetEntryDefectImproveDeptDTO;
+import com.diagbot.dto.GetQcClickDTO;
+import com.diagbot.dto.RespDTO;
+import com.diagbot.facade.DataAnalysisDeptFacade;
+import com.diagbot.facade.DataAnalysisFacade;
+import com.diagbot.vo.GetEntryDefectImproveDeptVO;
+import com.diagbot.vo.GetEntryDefectImproveInnerVO;
+import com.diagbot.vo.GetQcClickInnerPageVO;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletResponse;
+import javax.validation.Valid;
+import java.util.List;
+
+/**
+ * @Description:数据分析(科室)
+ * @Author: cy
+ * @time: 2021/11/25 11:42
+ */
+@RestController
+@Api(value = "数据分析(科室)相关API", tags = { "数据分析(科室)相关API" })
+@RequestMapping("/qc/analysisDept")
+public class DataAnalysisDeptController {
+
+    @Autowired
+    DataAnalysisFacade dataAnalysisFacade;
+    @Autowired
+    DataAnalysisDeptFacade dataAnalysisDeptFacade;
+
+
+    /**
+     * 条目缺陷改善统计(科室)
+     *
+     * @param getEntryDefectImproveDeptVO
+     * @return
+     */
+    @ApiOperation(value = "条目缺陷改善统计(科室)[by:cy]")
+    @PostMapping("/getEntryDefectImproveDept")
+    @SysLogger("getEntryDefectImproveDept")
+    public RespDTO<IPage<GetEntryDefectImproveDeptDTO>> getEntryDefectImprove(@RequestBody @Valid GetEntryDefectImproveDeptVO getEntryDefectImproveDeptVO) {
+        return RespDTO.onSuc(dataAnalysisDeptFacade.getEntryDefectImproveDept(getEntryDefectImproveDeptVO));
+    }
+
+    /**
+     * 条目缺陷改善统计(科室)-导出
+     *
+     * @param getEntryDefectImproveDeptVO
+     * @return
+     */
+    @ApiOperation(value = "条目缺陷改善统计(科室)-导出[by:cy]")
+    @PostMapping("/getEntryDefectImproveByDeptExport")
+    @SysLogger("getEntryDefectImproveByDeptExport")
+    public void getEntryDefectImproveByDeptExport(HttpServletResponse response,@RequestBody @Valid GetEntryDefectImproveDeptVO getEntryDefectImproveDeptVO) {
+        dataAnalysisDeptFacade.getEntryDefectImproveByDeptExport(response,getEntryDefectImproveDeptVO);
+    }
+
+    /**
+     * 条目缺陷改善统计(科室)-内页
+     *
+     * @param getEntryDefectImproveInnerVO
+     * @return
+     */
+    @ApiOperation(value = "条目缺陷改善统计(科室)-内页[by:cy]")
+    @PostMapping("/getEntryDefectImproveInnerDept")
+    @SysLogger("getEntryDefectImproveInnerDept")
+    public RespDTO<IPage<BehospitalInfoDTO>> getEntryDefectImproveInnerDept(@RequestBody GetEntryDefectImproveInnerVO getEntryDefectImproveInnerVO) {
+        return RespDTO.onSuc(dataAnalysisFacade.getEntryDefectImproveInner(getEntryDefectImproveInnerVO));
+    }
+
+    /**
+     * 条目缺陷改善统计(科室)-内页导出
+     *
+     * @param getEntryDefectImproveInnerVO
+     * @return
+     */
+    @ApiOperation(value = "条目缺陷改善统计(科室)-内页导出[by:cy]")
+    @PostMapping("/getDefectImproveInnerByDeptExport")
+    @SysLogger("getDefectImproveInnerByDeptExport")
+    public void getDefectImproveInnerByDeptExport(HttpServletResponse response, @RequestBody GetEntryDefectImproveInnerVO getEntryDefectImproveInnerVO) {
+        dataAnalysisFacade.getDefectImproveInnerByExport(response, getEntryDefectImproveInnerVO);
+    }
+
+}

+ 2 - 2
src/main/resources/application-test.yml

@@ -59,7 +59,7 @@ spring:
     druid:
       driver-class-name: com.mysql.cj.jdbc.Driver
       platform: mysql
-      url: jdbc:mysql://192.168.2.126:3307/qc?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&characterSetResults=utf8&useSSL=false&allowMultiQueries=true
+      url: jdbc:mysql://192.168.2.126:3307/qc_xy?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&characterSetResults=utf8&useSSL=false&allowMultiQueries=true
       username: root
       password: Lat0ne@tesT
       # 连接池的配置信息
@@ -164,7 +164,7 @@ oath.self.address: http://${myhost}:${server.port}
 
 # 加解密开关
 encrypt:
-  enable: true
+  enable: false
 
 swagger:
   enable: true

+ 20 - 0
src/main/resources/mapper/BehospitalInfoMapper.xml

@@ -701,6 +701,26 @@
         LEFT JOIN sys_user u  on u.id = a.modifier  and u.is_deleted = 'N'
     </select>
 
+    <select id="getForeignMsg" resultType="com.diagbot.dto.MsgDTO">
+        SELECT a.*, u.linkman
+        FROM
+        (
+        SELECT DISTINCT b.`name` model_name,c.score,c.msg,c.cases_entry_id,c.is_reject,c.id id,c.info, a.cases_id cases_id, d.score cases_score,
+        b.id model_id, a.name standard_msg, c.opt_type, c.grade_type,
+         c.gmt_create, c.gmt_modified, c.modifier,c.is_deleted,c.explain_info as explainInfo,
+        a.type, a.drgs
+        FROM
+        `qc_cases_entry` a, qc_mode b, med_qcresult_detail c, qc_cases_hospital d
+        where a.is_deleted = 'N' and b.is_deleted = 'N' and c.is_deleted = 'N' and d.is_deleted = 'N'
+        and a.id = c.cases_entry_id and a.mode_id = b.id
+        AND c.cases_id = d.cases_id and c.hospital_id = d.hospital_id
+        and c.hospital_id = #{hospitalId}
+        and c.behospital_code = #{behospitalCode}
+        order by b.order_no, c.grade_type desc, a.order_no) a
+        LEFT JOIN sys_user u  on u.id = a.modifier  and u.is_deleted = 'N'
+    </select>
+
+
 
 
 

+ 322 - 13
src/main/resources/mapper/MedClickInfoMapper.xml

@@ -4,19 +4,328 @@
 
     <!-- 通用查询映射结果 -->
     <resultMap id="BaseResultMap" type="com.diagbot.entity.MedClickInfo">
-        <id column="id" property="id" />
-        <result column="hospital_id" property="hospitalId" />
-        <result column="dept_id" property="deptId" />
-        <result column="dept_name" property="deptName" />
-        <result column="doctor_id" property="doctorId" />
-        <result column="doctor_name" property="doctorName" />
-        <result column="qcresult_info_id" property="qcresultInfoId" />
-        <result column="behospital_code" property="behospitalCode" />
-        <result column="is_deleted" property="isDeleted" />
-        <result column="gmt_create" property="gmtCreate" />
-        <result column="gmt_modified" property="gmtModified" />
-        <result column="creator" property="creator" />
-        <result column="modifier" property="modifier" />
+        <id column="id" property="id"/>
+        <result column="hospital_id" property="hospitalId"/>
+        <result column="dept_id" property="deptId"/>
+        <result column="dept_name" property="deptName"/>
+        <result column="doctor_id" property="doctorId"/>
+        <result column="doctor_name" property="doctorName"/>
+        <result column="opt_type" property="optType"/>
+        <result column="qcresult_info_id" property="qcresultInfoId"/>
+        <result column="behospital_code" property="behospitalCode"/>
+        <result column="is_deleted" property="isDeleted"/>
+        <result column="gmt_create" property="gmtCreate"/>
+        <result column="gmt_modified" property="gmtModified"/>
+        <result column="creator" property="creator"/>
+        <result column="modifier" property="modifier"/>
     </resultMap>
 
+
+    <resultMap id="entryDefectImproveMap" type="com.diagbot.dto.EntryDefectImprove">
+        <result column="deptId" property="deptId"/>
+        <result column="deptName" property="deptName"/>
+        <collection property="behospitalCodeInfos"
+                    ofType="com.diagbot.dto.BehospitalCodeInfo">
+            <result column="behospitalCode" property="behospitalCode"/>
+            <collection property="qcResultDetailInfos" ofType="com.diagbot.dto.QcResultDetailInfo">
+                <result column="CasesEntryIds" property="CasesEntryIds"/>
+            </collection>
+        </collection>
+    </resultMap>
+
+
+    <resultMap id="ExportExcelMap" type="com.diagbot.dto.ExportExcelDTO">
+        <result column="deptName" property="behDeptName"/>
+        <result column="avgScore" property="avgScore"/>
+        <collection property="excelBehospitalDTOS"
+                    ofType="com.diagbot.dto.ExportExcelBehospitalDTO">
+            <result column="doctorName" property="doctorName"/>
+            <result column="NAME" property="patName"/>
+            <result column="behospitalCode" property="behospitalCode"/>
+            <result column="behospitalDate" property="behospitalDate"/>
+            <result column="leaveHospitalDate" property="leaveHospitalDate"/>
+            <result column="scoreRes" property="score"/>
+            <result column="scoreBn" property="scoreBn"/>
+            <collection property="exportExcelCaseDTOS" ofType="com.diagbot.dto.ExportExcelCaseDTO">
+                <result column="casesName" property="caseName"/>
+                <collection property="exportExcelMsgDTOS"
+                            ofType="com.diagbot.dto.ExportExcelMsgDTO">
+                    <result column="entryName" property="msg"/>
+                </collection>
+            </collection>
+        </collection>
+    </resultMap>
+
+
+    <resultMap id="entryDefectImproveInnerMap" type="com.diagbot.dto.EntryDefectImproveInner">
+        <result column="behDeptName" property="behDeptName"/>
+        <collection property="behospitalCodeInfos" ofType="com.diagbot.dto.BehospitalCodeDetail">
+            <result column="behospitalCode" property="behospitalCode"/>
+            <result column="name" property="name"/>
+            <result column="fileCode" property="fileCode"/>
+            <result column="behospitalDate" property="behospitalDate"/>
+            <result column="leaveHospitalDate" property="leaveHospitalDate"/>
+            <result column="doctorName" property="doctorName"/>
+            <result column="age" property="age"/>
+            <result column="level" property="level"/>
+            <result column="scoreRes" property="scoreRes"/>
+            <result column="gradeTime" property="gradeTime"/>
+            <collection property="qcResultDetailInfos" ofType="com.diagbot.dto.QcResultDetailInfo">
+                <result column="CasesEntryIds" property="CasesEntryIds"/>
+            </collection>
+        </collection>
+    </resultMap>
+
+
+    <resultMap id="entryDefectImproveInnerExportMap" type="com.diagbot.dto.EntryDefectImproveInnerExport">
+        <result column="deptId" property="deptId"/>
+        <result column="deptName" property="deptName"/>
+        <collection property="entryDefectImproveInnerDoctors" ofType="com.diagbot.dto.EntryDefectImproveInnerDoctor">
+            <result column="doctorId" property="doctorId"/>
+            <result column="doctorName" property="doctorName"/>
+            <collection property="behospitalCodeInfos" ofType="com.diagbot.dto.BehospitalCodeInfo">
+                <result column="behospitalCode" property="behospitalCode"/>
+                    <collection property="qcResultDetailInfos" ofType="com.diagbot.dto.QcResultDetailInfo">
+                        <result column="CasesEntryIds" property="CasesEntryIds"/>
+                </collection>
+            </collection>
+        </collection>
+    </resultMap>
+
+
+    <select id="getQcClick" resultType="com.diagbot.dto.GetQcClickDTO">
+        SELECT
+        a.dept_id AS deptId,
+        a.dept_name AS deptName,
+        sum(a.opt_type = 0) AS singleModeNum,
+        sum(a.opt_type = 1) AS totalModeNum
+        FROM
+        med_click_info a
+        where
+        a.is_deleted = 'N'
+        <if test="hospitalId != null">
+            and a.hospital_id = #{hospitalId}
+        </if>
+        <if test="deptName != null and deptName != ''">
+            and a.dept_name like CONCAT('%',#{deptName},'%')
+        </if>
+        <if test="startDate != null">
+            <![CDATA[ and a.gmt_create >= #{startDate}]]>
+        </if>
+        <if test="endDate != null">
+            <![CDATA[ and a.gmt_create < #{endDate}]]>
+        </if>
+        group by
+        a.dept_id,
+        a.dept_name
+        <if test="asc != null and asc !=''">
+            order by
+            <choose>
+                <when test='asc=="singleModeNum"'>singleModeNum asc</when>
+                <when test='asc=="totalModeNum"'>totalModeNum asc</when>
+            </choose>
+        </if>
+        <if test="desc != null and desc !=''">
+            order by
+            <choose>
+                <when test='desc=="singleModeNum"'>singleModeNum desc</when>
+                <when test='desc=="totalModeNum"'>totalModeNum desc</when>
+            </choose>
+        </if>
+    </select>
+
+    <select id="getQcClickInnerPage" resultType="com.diagbot.dto.GetQcClickInnerPageDTO">
+        SELECT
+        a.dept_id as deptId,
+        a.dept_name as deptName,
+        a.doctor_id AS doctorId,
+        a.doctor_name AS doctorName,
+        count(case when a.opt_type = 0 then 1 end) AS singleModeNum,
+        count(case when a.opt_type = 1 then 1 end) AS totalModeNum
+        FROM
+        med_click_info a
+        where
+        a.is_deleted = 'N'
+        <if test="hospitalId != null">
+            and a.hospital_id = #{hospitalId}
+        </if>
+        <if test="deptName != null and deptName != ''">
+            and a.dept_name =#{deptName}
+        </if>
+        <if test="deptId != null and deptId != ''">
+            and a.dept_id= #{deptId}
+        </if>
+        <if test="doctorId != null and doctorId != ''">
+            and a.doctor_id like CONCAT('%',#{doctorId},'%')
+        </if>
+        <if test="doctorName != null and doctorName != ''">
+            and a.doctor_name like CONCAT('%',#{doctorName},'%')
+        </if>
+        <if test="startDate != null">
+            <![CDATA[ and a.gmt_create >= #{startDate}]]>
+        </if>
+        <if test="endDate != null">
+            <![CDATA[ and a.gmt_create < #{endDate}]]>
+        </if>
+        group by
+        a.dept_id,
+        a.dept_name,
+        a.doctor_id,
+        a.doctor_name
+    </select>
+
+    <select id="getEntryInfo" resultType="com.diagbot.dto.GetEntryInfoDTO">
+        SELECT
+            a.id AS casesId,
+            a. NAME AS casesName,
+            b.id AS entryId,
+            b. NAME AS entryName
+        FROM
+            qc_cases a,
+            qc_cases_entry b
+        WHERE
+            a.is_deleted = 'N'
+        AND b.is_deleted = 'N'
+        AND a.id = b.cases_id
+    </select>
+
+    <select id="getEntryDefectImprove" resultMap="entryDefectImproveMap">
+        SELECT
+        b.hospital_id as hospitalId,
+        b.beh_dept_id as deptId,
+        b.beh_dept_name as deptName,
+        b.behospital_code as behospitalCode,
+        ifnull(a.cases_entry_ids,0) as casesEntryIds
+        FROM
+        med_qcresult_click a,
+        med_behospital_info b
+        WHERE
+        a.is_deleted = 'N'
+        AND b.is_deleted = 'N'
+        AND a.hospital_id =b.hospital_id
+        AND a.behospital_code =b.behospital_code
+        <if test="hospitalId != null and hospitalId != ''">
+            AND b.hospital_id = #{hospitalId}
+        </if>
+        <if test="deptName != null and deptName != ''">
+            and b.beh_dept_name like CONCAT('%',#{deptName},'%')
+        </if>
+        <if test="startDate != null and startDate != ''">
+            <![CDATA[ AND a.gmt_create >= #{startDate}]]>
+        </if>
+        <if test="endDate != null and endDate != ''">
+            <![CDATA[ AND a.gmt_create <= #{endDate}]]>
+        </if>
+        order by a.gmt_create
+    </select>
+
+    <select id="getEntryDefectImproveInner" resultMap="entryDefectImproveInnerMap">
+        SELECT
+        t.*,
+        IF( n.age IS NULL,NULL,CONCAT(ifnull(n.age, ''),ifnull(n.age_unit, ''))) AS age
+        from (
+        SELECT
+        b.hospital_id as hospitalId,
+        b.beh_dept_id as deptId,
+        b.beh_dept_name as behDeptName,
+        b.file_code AS fileCode,
+        b.behospital_code as behospitalCode,
+        b.name,
+        b.behospital_date AS behospitalDate,
+        b.leave_hospital_date AS leaveHospitalDate,
+        b.doctor_id AS doctorId,
+        b.doctor_name AS doctorName,
+        ifnull(c. level, '未评分') AS `level`,
+        c.score_res AS scoreRes,
+        c.gmt_create AS gradeTime,
+        ifnull(a.cases_entry_ids,0) as casesEntryIds
+        FROM
+        med_qcresult_click a,
+        med_behospital_info b,
+        med_qcresult_info c
+        WHERE
+        a.is_deleted = 'N'
+        AND b.is_deleted = 'N'
+        AND c.is_deleted = 'N'
+        AND a.hospital_id =b.hospital_id
+        AND a.hospital_id =c.hospital_id
+        AND a.behospital_code =b.behospital_code
+        AND a.behospital_code =c.behospital_code
+        <if test="hospitalId != null and hospitalId != ''">
+            AND b.hospital_id = #{hospitalId}
+        </if>
+        <if test="deptId != null and deptId != ''">
+            and b.beh_dept_id = #{deptId}
+        </if>
+        <if test="deptName != null and deptName != ''">
+            and b.beh_dept_name = #{deptName}
+        </if>
+        <if test="patName != null and patName != ''">
+            and b.name like CONCAT('%',#{patName},'%')
+        </if>
+        <if test="behospitalCode != null and behospitalCode != ''">
+            and b.behospital_code like CONCAT('%',#{behospitalCode},'%')
+        </if>
+        <if test="doctorId != null and doctorId != ''">
+            and b.doctor_id like CONCAT('%',#{doctorId},'%')
+        </if>
+        <if test="doctorName != null and doctorName != ''">
+            and b.doctor_name like CONCAT('%',#{doctorName},'%')
+        </if>
+        <if test="level != null and level != ''">
+            and c.level = #{level}
+        </if>
+        <if test="startDate != null and startDate != ''">
+            <![CDATA[ AND a.gmt_create >= #{startDate}]]>
+        </if>
+        <if test="endDate != null and endDate != ''">
+            <![CDATA[ AND a.gmt_create <= #{endDate}]]>
+        </if>
+        order by a.gmt_create
+        )t LEFT JOIN med_home_page n
+        ON t.hospitalId = n.hospital_id
+        AND t.behospitalCode = n.behospital_code
+        AND n.is_deleted = 'N'
+    </select>
+
+    <select id="getEntryDefectImproveDept" resultMap="entryDefectImproveInnerExportMap">
+        SELECT
+        b.hospital_id as hospitalId,
+        b.beh_dept_id as deptId,
+        b.beh_dept_name as deptName,
+        b.behospital_code as behospitalCode,
+        b.doctor_id AS doctorId,
+        b.doctor_name AS doctorName,
+        ifnull(a.cases_entry_ids,0) as casesEntryIds
+        FROM
+        med_qcresult_click a,
+        med_behospital_info b
+        WHERE
+        a.is_deleted = 'N'
+        AND b.is_deleted = 'N'
+        AND a.hospital_id =b.hospital_id
+        AND a.behospital_code =b.behospital_code
+        <if test="hospitalId != null and hospitalId != ''">
+            AND b.hospital_id = #{hospitalId}
+        </if>
+        <if test="deptId != null and deptId != ''">
+            and b.beh_dept_id = #{deptId}
+        </if>
+        <if test="deptName != null and deptName != ''">
+            and b.beh_dept_name = #{deptName}
+        </if>
+        <if test="doctorId != null and doctorId != ''">
+            and b.doctor_id like CONCAT('%',#{doctorId},'%')
+        </if>
+        <if test="doctorName != null and doctorName != ''">
+            and b.doctor_name like CONCAT('%',#{doctorName},'%')
+        </if>
+        <if test="startDate != null and startDate != ''">
+            <![CDATA[ AND a.gmt_create >= #{startDate}]]>
+        </if>
+        <if test="endDate != null and endDate != ''">
+            <![CDATA[ AND a.gmt_create <= #{endDate}]]>
+        </if>
+        order by a.gmt_create
+    </select>
 </mapper>

+ 17 - 0
src/main/resources/mapper/MedQcresultClickMapper.xml

@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.diagbot.mapper.MedQcresultClickMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.diagbot.entity.MedQcresultClick">
+        <result column="id" property="id" />
+        <result column="hospital_id" property="hospitalId" />
+        <result column="behospital_code" property="behospitalCode" />
+        <result column="dept_id" property="deptId" />
+        <result column="dept_name" property="deptName" />
+        <result column="qcresult_info_id" property="qcresultInfoId" />
+        <result column="cases_entry_ids" property="CasesEntryIds" />
+        <result column="gmt_create" property="gmtCreate" />
+    </resultMap>
+
+</mapper>