From 60ade5154522a042c816abaa1840751011ae0371 Mon Sep 17 00:00:00 2001
From: liusheng <337615773@qq.com>
Date: 星期二, 29 九月 2026 19:15:03 +0800
Subject: [PATCH] 1.省立同德满度问题处理 2.门急诊数据采集优化
---
smartor/src/main/java/com/smartor/service/impl/PatSatisfactionServiceImpl.java | 152 +++--
smartor/src/main/java/com/smartor/service/impl/ServiceSLTDHealthcareRecordServiceImpl.java | 202 ++++++
smartor/src/main/java/com/smartor/domain/DTO/DetailTraceDealDTO.java | 7
smartor/src/main/java/com/smartor/mapper/PatMedOuthospMapper.java | 10
smartor/src/main/resources/mapper/smartor/PatMedOuthospMapper.xml | 10
smartor/src/main/java/com/smartor/domain/SvyLibTemplateCategory.java | 6
ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/ServiceSubtaskDetailTraceController.java | 18
smartor/src/main/java/com/smartor/service/impl/ServiceSubtaskDetailTraceServiceImpl.java | 186 ++++--
ruoyi-quartz/src/main/java/com/ruoyi/quartz/enums/MzGatherSlotEnum.java | 37 +
smartor/src/main/java/com/smartor/service/IPatMedOuthospService.java | 14
ruoyi-quartz/src/main/java/com/ruoyi/quartz/enums/MzGatherStatusEnum.java | 36 +
smartor/src/main/resources/mapper/smartor/SvyLibTemplageCategoryMapper.xml | 6
smartor/src/main/java/com/smartor/mapper/ServiceSubtaskDetailMapper.java | 23
ruoyi-quartz/src/main/java/com/ruoyi/quartz/enums/MzGatherParamEnum.java | 56 ++
smartor/src/main/java/com/smartor/service/impl/PatMedOuthospServiceImpl.java | 43 +
smartor/src/main/resources/mapper/smartor/ServiceSubtaskDetailTraceMapper.xml | 222 +++++--
ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java | 467 ++++++++++++++---
smartor/src/main/java/com/smartor/domain/ServiceSLTDInhospReqVO.java | 4
smartor/src/main/java/com/smartor/mapper/ServiceSubtaskDetailTraceMapper.java | 36 +
smartor/src/main/resources/mapper/smartor/ServiceSubtaskDetailMapper.xml | 69 ++
20 files changed, 1,304 insertions(+), 300 deletions(-)
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/ServiceSubtaskDetailTraceController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/ServiceSubtaskDetailTraceController.java
index eda9ed5..3df473e 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/ServiceSubtaskDetailTraceController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/ServiceSubtaskDetailTraceController.java
@@ -62,22 +62,16 @@
@AddOrgId(field = "orgid", paramIndex = 0, campusField = "campusid")
@PostMapping("/tracedeallist")
public Map<String, Object> tracedeallist(@RequestBody DetailTraceDealVO detailTraceDealVO) {
+ // PageUtils.getOffset 杩斿洖鐨勬槸 offset锛孲QL 閲屾寜 limit/offset 浣跨敤
Integer offset = PageUtils.getOffset(detailTraceDealVO.getPageNum(), detailTraceDealVO.getPageSize());
detailTraceDealVO.setPageNum(offset);
+ // 涓�娆℃煡璇㈠悓鏃惰繑鍥炲垎椤垫暟鎹�侀棶棰樻�绘暟鍜屽叏閲忔眹鎬�
+ // 锛堝師鏉ヤ负浜嗘嬁鎬绘暟鎶� method 鍙堝叏閲忚窇浜嗕竴閬嶏紝N+1 涔熻窡鐫�璺戠浜岄亶锛�
Map<String, Object> result = serviceSubtaskDetailTraceService.tracedeallist(detailTraceDealVO);
- // 鏌ヨ鎬绘暟锛堜笉鍒嗛〉锛�
- detailTraceDealVO.setPageNum(null);
- detailTraceDealVO.setPageSize(null);
- Map<String, Object> totalResult = serviceSubtaskDetailTraceService.tracedeallist(detailTraceDealVO);
- List<?> totalRows = (List<?>) totalResult.get("detailTraceDealDTOList");
-
- //灏嗘�绘暟淇℃伅娣诲姞鍒扮粨鏋滀腑
- result.put("totalException", totalResult.get("totalException"));
- result.put("noDealException", totalResult.get("noDealException"));
- result.put("yesDealException", totalResult.get("yesDealException"));
-
- return getDataTable3(CollectionUtils.isNotEmpty(totalRows) ? totalRows.size() : 0, result);
+ Object questionTotal = result.get("questionTotal");
+ long total = questionTotal == null ? 0L : Long.parseLong(String.valueOf(questionTotal));
+ return getDataTable3(total, result);
}
/**
diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/enums/MzGatherParamEnum.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/enums/MzGatherParamEnum.java
new file mode 100644
index 0000000..0993330
--- /dev/null
+++ b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/enums/MzGatherParamEnum.java
@@ -0,0 +1,56 @@
+package com.ruoyi.quartz.enums;
+
+/**
+ * 鐪佺珛鍚屽痉闂ㄦ�ヨ瘖閲囬泦鍙傛暟锛坰ys_config锛屾満鏋� orgid=20001001锛�
+ * <p>
+ * 鎶婇厤缃� key銆侀粯璁ゅ�笺�佸彇鍊艰寖鍥寸粦鍦ㄤ竴璧凤紝璇诲彇鏃跺彧瑕佷紶鏋氫妇鏈韩锛�
+ * 閬垮厤 key 鍜岄粯璁ゅ�煎啓鏁e湪浠诲姟閲屻�佹敼涓�涓紡涓�涓�
+ *
+ * @author smartor
+ */
+public enum MzGatherParamEnum {
+
+ /**
+ * 鍗曡疆閲囬泦鏃堕棿棰勭畻锛堝垎閽燂級
+ * 蹇呴』灏忎簬璋冨害闂撮殧锛屼繚璇� 30 鍒嗛挓涓�璋冩椂鏈疆鑳借刀鍦ㄤ笅涓�杞箣鍓嶇粨鏉�
+ */
+ BUDGET_MINUTES("sltd.gather.mz.budget.minutes", 20L, 1L, 24L * 60L),
+
+ /** 鍒嗛〉姣忛〉鏉℃暟 */
+ PAGE_SIZE("sltd.gather.mz.page.size", 500L, 1L, 5000L),
+
+ /** 鍗曟棩鏈�澶氱炕椤垫暟锛岄槻姝㈡帴鍙e紓甯镐竴鐩磋繑鍥炴弧椤靛鑷存寰幆 */
+ MAX_PAGE("sltd.gather.mz.max.page", 2000L, 1L, 100000L);
+
+ /** sys_config.config_key */
+ private final String key;
+ /** 閰嶇疆缂哄け鎴栬秴鑼冨洿鏃朵娇鐢ㄧ殑榛樿鍊� */
+ private final long defaultValue;
+ /** 鍏佽鐨勬渶灏忓�硷紙鍚級 */
+ private final long min;
+ /** 鍏佽鐨勬渶澶у�硷紙鍚級 */
+ private final long max;
+
+ MzGatherParamEnum(String key, long defaultValue, long min, long max) {
+ this.key = key;
+ this.defaultValue = defaultValue;
+ this.min = min;
+ this.max = max;
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public long getDefaultValue() {
+ return defaultValue;
+ }
+
+ public long getMin() {
+ return min;
+ }
+
+ public long getMax() {
+ return max;
+ }
+}
diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/enums/MzGatherSlotEnum.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/enums/MzGatherSlotEnum.java
new file mode 100644
index 0000000..c54c833
--- /dev/null
+++ b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/enums/MzGatherSlotEnum.java
@@ -0,0 +1,37 @@
+package com.ruoyi.quartz.enums;
+
+/**
+ * 鐪佺珛鍚屽痉闂ㄦ�ヨ瘖閲囬泦锛氭柇鐐规Ы浣�
+ * <p>
+ * 姣忓ぉ涓�杞叏閲忓埛鏂帮紝鍚屾椂杩樻湁"鏄ㄥぉ鏀跺熬"鍜�"鎵嬪伐鍥炴函"涓や釜杞锛�
+ * 姣忚疆鍚勮嚜鍙兘琚绠楁垨鎺ュ彛澶辫触鎵撴柇锛屾墍浠ユ柇鐐瑰垎妲戒綅淇濆瓨锛屼簰涓嶈鐩�
+ *
+ * @author smartor
+ */
+public enum MzGatherSlotEnum {
+
+ /** 浠婂ぉ鐨勬暣杞埛鏂� */
+ TODAY("1", "浠婂ぉ鏁磋疆鍒锋柊"),
+
+ /** 鏄ㄥぉ鐨勬敹灏鹃噰闆嗭紝姣忓ぉ鍙仛涓�娆★紝鍏滀綇 23:xx 鍚庡啓鍏� HIS 鐨勮褰曞拰璺ㄩ浂鐐规暟鎹� */
+ FINAL("2", "鏄ㄦ棩鏀跺熬閲囬泦"),
+
+ /** 浠诲姟鍏ュ弬鎸囧畾鏃ユ湡鐨勪竴娆℃�у洖婧� */
+ BACKFILL("3", "鎵嬪伐鍥炴函");
+
+ private final String code;
+ private final String desc;
+
+ MzGatherSlotEnum(String code, String desc) {
+ this.code = code;
+ this.desc = desc;
+ }
+
+ public String getCode() {
+ return code;
+ }
+
+ public String getDesc() {
+ return desc;
+ }
+}
diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/enums/MzGatherStatusEnum.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/enums/MzGatherStatusEnum.java
new file mode 100644
index 0000000..2737a50
--- /dev/null
+++ b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/enums/MzGatherStatusEnum.java
@@ -0,0 +1,36 @@
+package com.ruoyi.quartz.enums;
+
+/**
+ * 鐪佺珛鍚屽痉闂ㄦ�ヨ瘖閲囬泦锛氬崟鏃ラ噰闆嗙粨鏋�
+ * <p>
+ * 鐢ㄤ簬 {@code RyTask#runDayPass} 鐨勮繑鍥炲�硷紝鍛婅瘔璋冪敤鏂硅繖涓�澶╂槸閲囧畬浜嗐�侀绠楃敤灏戒簡锛岃繕鏄帴鍙f寕浜�
+ *
+ * @author smartor
+ */
+public enum MzGatherStatusEnum {
+
+ /** 璇ユ棩鏈熷凡浠庣涓�椤甸噰鍒版渶鍚庝竴椤碉紝鏁磋疆瀹屾垚 */
+ DONE("0", "閲囬泦瀹屾垚"),
+
+ /** 鏈疆鏃堕棿棰勭畻鐢ㄥ敖锛岄〉鐮佹柇鐐瑰凡淇濆瓨锛屼笅涓�杞粠璇ラ〉缁х画 */
+ BUDGET_UP("1", "鏈疆棰勭畻鐢ㄥ敖"),
+
+ /** 鎺ュ彛灞傝繛缁け璐ワ紝鏈疆鎻愬墠缁撴潫锛岄〉鐮佹柇鐐逛繚鐣欏湪绗竴涓け璐ラ〉 */
+ FAILED("2", "鎺ュ彛杩炵画澶辫触");
+
+ private final String code;
+ private final String desc;
+
+ MzGatherStatusEnum(String code, String desc) {
+ this.code = code;
+ this.desc = desc;
+ }
+
+ public String getCode() {
+ return code;
+ }
+
+ public String getDesc() {
+ return desc;
+ }
+}
diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java
index 7fca0e5..c076b5f 100644
--- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java
+++ b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java
@@ -18,6 +18,10 @@
import com.ruoyi.common.utils.*;
import com.ruoyi.common.utils.http.HttpUtils;
import com.ruoyi.common.utils.sms.smsUtils;
+import com.ruoyi.quartz.constant.MzGatherConstant;
+import com.ruoyi.quartz.enums.MzGatherParamEnum;
+import com.ruoyi.quartz.enums.MzGatherSlotEnum;
+import com.ruoyi.quartz.enums.MzGatherStatusEnum;
import com.ruoyi.quartz.service.ICollectHISService;
import com.ruoyi.quartz.util.CreateDataTable;
import com.ruoyi.system.domain.SysConfig;
@@ -630,96 +634,395 @@
}
/**
- * HIS鐪佺珛鍚屽痉闂ㄦ�ヨ瘖鏁版嵁閲囬泦锛堣繖涓彧鑳戒竴澶╂墽琛屼竴娆★紝涓嶈兘鍗婁釜灏忔椂鎵ц涓�涓紝鏁版嵁閲忓お澶э紝褰卞搷鎬ц兘锛�
- * 瀹氭椂浠诲姟锛氶棬璇婃暟鎹�
- * todayZeroStr 褰撳墠鐨勬椂闂� 渚嬪锛�2026-05-06 00:00:00
+ * HIS鐪佺珛鍚屽痉闂ㄦ�ヨ瘖鏁版嵁閲囬泦锛堟瘡鍗婂皬鏃朵竴杞紝鎸夊ぉ鍏ㄩ噺鍒锋柊 + 鍒嗛〉鏂偣缁噰锛�
+ * <p>
+ * HIS 渚ч棬鎬ヨ瘖鏁版嵁鍙兘鎸夊ぉ鏌ワ紝姣忚疆鎷夊埌鐨勯兘鏄綋澶╁叏閲忥紙鍒版櫄涓婁竴涓囧鏉★級锛岃繖涓彇鏁版垚鏈敼涓嶄簡锛�
+ * 鑳芥敼鐨勬槸澶勭悊鎴愭湰锛氬綋澶╂暟鎹噷缁濆ぇ澶氭暟涓婁竴杞凡缁忓叆搴擄紝闈�"鏁撮〉鎵归噺鏌ラ噸 + 宸插叆搴撶洿鎺ヨ烦杩�"锛�
+ * 姣忚疆鐪熸闇�瑕佸仛妗f澶勭悊鍜屽叆搴撶殑鍙湁鏂板嚭鐜扮殑閭e嚑鐧炬潯锛屼竴涓囧鏉′篃鑳藉湪寰堢煭鏃堕棿鍐呰窇瀹屻��
+ * <p>
+ * 姣忎竴杞仛涓変欢浜嬶細
+ * <ol>
+ * <li>浠婂ぉ鐨勬暣杞埛鏂帮細绗� 1 椤电炕鍒版渶鍚庝竴椤碉紝鍙鐞嗘柊璁板綍锛�</li>
+ * <li>鏄ㄥぉ鐨勬敹灏鹃噰闆嗭細姣忓ぉ鍙仛涓�娆★紝鍏滀綇 23:xx 涔嬪悗鎵嶅啓鍏� HIS 鐨勮褰曞拰璺ㄩ浂鐐圭殑鏁版嵁锛�</li>
+ * <li>鎵嬪伐鍥炴函锛氫换鍔″叆鍙傜粰浜嗘棩鏈熸椂锛屾妸閭eぉ琛ラ噰涓�娆★紙鍚屼竴澶╁彧琛ヤ竴娆★紝涓嶄細姣忚疆閲嶅琛ワ級銆�</li>
+ * </ol>
+ * 姣忚疆鏈�澶氳窇 {@link MzGatherParamEnum#BUDGET_MINUTES}锛堥粯璁� 20 鍒嗛挓锛夛紝鍒扮偣淇濆瓨椤电爜鏂偣姝e父閫�鍑猴紝涓嬩竴杞粠璇ラ〉缁х画锛�
+ * 姣忛噰瀹屼竴椤甸兘浼氳惤涓�娆℃柇鐐癸紝杩涚▼琚潃涔熶笉浼氫粠澶撮噸鎵��
+ * <p>
+ * 澶辫触涓�寰嬩笉闃绘柇閲囬泦杩涘害锛�
+ * <ul>
+ * <li>鏁版嵁灞傚け璐ワ紙杞崲/妗f/鍏ュ簱锛夎惤 pat_med_outhosp_error 琛ㄤ氦浜哄伐澶勭悊锛�</li>
+ * <li>鎺ュ彛灞傚け璐ワ紙缃戠粶瓒呮椂銆佹潵鏈潵杩斿洖闈� 200锛夋病鏈夋暟鎹彲钀借〃锛屽彧鍐� error 鏃ュ織锛堝惈闄㈠尯銆佹棩鏈熴�侀〉鐮併�佹帴鍙e叆鍙傦級锛�
+ * 璺宠繃璇ラ〉缁х画寰�鍚庨噰锛屾湰杞粨鏉熸椂鎶婃柇鐐圭暀鍦ㄧ涓�涓け璐ラ〉锛涘洜涓烘瘡杞兘鏄暣澶╀粠澶村叏閲忓埛鏂帮紝
+ * 琚烦杩囩殑椤典笅涓�杞繀鐒堕噸鏂伴噰鍒帮紝涓嶄細婕忥紱</li>
+ * <li>杩炵画 {@link MzGatherConstant#MAX_CONSECUTIVE_PAGE_FAIL} 椤垫帴鍙eけ璐ュ垽瀹氫负鎺ュ彛鏁翠綋涓嶅彲鐢紝鏈疆鎻愬墠缁撴潫锛堥伩鍏嶇┖杞嚑鍗侀〉锛夛紝
+ * 鏂偣鐣欏湪绗竴涓け璐ラ〉锛屼笅涓�杞啀璇曘��</li>
+ * </ul>
+ *
+ * @param todayZeroStr 鍙�夛紝鎵嬪伐鎸囧畾瑕佷竴娆℃�у洖婧殑鏃ユ湡锛屾敮鎸� yyyy-MM-dd HH:mm:ss 鎴� yyyy-MM-dd锛涗负绌烘椂鍙埛鏂颁粖澶�+鏀跺熬鏄ㄥぉ
*/
public void dealHisDataMZ(String todayZeroStr) {
- log.info("銆恉ealHisData銆戦棬鎬ヨ瘖鏁版嵁寮�濮嬫墽琛孒IS鏁版嵁閲囬泦浠诲姟");
- // 鑾峰彇鏄ㄥぉ0鐐瑰埌浠婂ぉ0鐐圭殑鏃堕棿鑼冨洿
- LocalDateTime todayZero = LocalDateTime.now().with(LocalTime.MIN);
- if (StringUtils.isNotBlank(todayZeroStr)) {
- DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
- todayZero = LocalDateTime.parse(todayZeroStr, formatter);
+ log.info("銆恉ealHisDataMZ銆戦棬鎬ヨ瘖鏁版嵁閲囬泦寮�濮嬶紝鍏ュ弬锛歿}", todayZeroStr);
+ // 鍗楀崕闄勪竴鐨勫厛涓嶉噰闂ㄦ�ヨ瘖鏁版嵁
+ if (!"sltd".equals(active.trim())) {
+ log.info("銆恉ealHisDataMZ銆戝綋鍓嶇幆澧� {} 涓嶉噰闆嗛棬鎬ヨ瘖鏁版嵁锛岃烦杩�", active.trim());
+ return;
}
- LocalDateTime tomorrowdayZero = todayZero.plusDays(1);
- if (active.trim().equals("sltd") || active.trim().equals("nhfy")) {
- //鐪佺珛鍚屽痉涓庡崕鍗楅檮涓�鐢ㄥ悓涓�濂楅噰闆嗘柟娉曪紙閮芥槸鏉ユ湭鏉ユ彁渚涳級
+ long budgetMinutes = getMzConfigLong(MzGatherParamEnum.BUDGET_MINUTES);
+ long pageSize = getMzConfigLong(MzGatherParamEnum.PAGE_SIZE);
+ long maxPage = getMzConfigLong(MzGatherParamEnum.MAX_PAGE);
+
+ LocalDateTime now = LocalDateTime.now().withNano(0);
+ LocalDateTime deadline = now.plusMinutes(budgetMinutes);
+
+ // 鑾峰彇鐪佺珛鍚屽痉瑕侀噰闆嗙殑闄㈠尯
+ SysConfig cf = new SysConfig();
+ cf.setConfigKey("sltd.gather.campusid");
+ cf.setOrgid(MzGatherConstant.ORG_ID);
+ List<SysConfig> sysConfigcampusids = configService.selectConfigList(cf);
+ if (CollectionUtils.isEmpty(sysConfigcampusids) || StringUtils.isBlank(sysConfigcampusids.get(0).getConfigValue())) {
+ log.error("銆恉ealHisDataMZ銆慡ysConfig涓殑闄㈠尯ID涓虹┖锛�");
+ return;
+ }
+ List<Long> campusidList = Arrays.stream(sysConfigcampusids.get(0).getConfigValue().split(","))
+ .map(String::trim).filter(StringUtils::isNotBlank).map(Long::valueOf).collect(Collectors.toList());
+ log.info("銆恉ealHisDataMZ銆戦櫌鍖猴細{}锛屽崟杞绠楋細{}鍒嗛挓锛屾瘡椤碉細{}鏉�", campusidList, budgetMinutes, pageSize);
+
+ for (Long cid : campusidList) {
+ if (LocalDateTime.now().isAfter(deadline)) {
+ log.warn("銆恉ealHisDataMZ銆戞湰杞椂闂撮绠楀凡鐢ㄥ敖锛屽墿浣欓櫌鍖虹暀鍒颁笅涓�杞户缁紝闄㈠尯锛歿}", cid);
+ break;
+ }
+ // 闃叉涓婁竴杞繕娌¤窇瀹屽氨琚笅涓�杞彔鐫�璺戯紙棰勭畻閰嶇疆杩囧ぇ銆佹垨鎵嬪伐瑙﹀彂鏃跺厹搴曪級
+ String lockKey = "mzRunning:" + cid;
+ if (Boolean.TRUE.equals(redisCache.hasKey(lockKey))) {
+ log.warn("銆恉ealHisDataMZ銆戣闄㈠尯涓婁竴杞噰闆嗗皻鏈粨鏉燂紝鏈疆璺宠繃锛岄櫌鍖猴細{}锛堟柇鐐瑰凡淇濈暀锛屼笅涓�杞户缁級", cid);
+ continue;
+ }
+ redisCache.setCacheObject(lockKey, MzGatherConstant.MINUTE_FMT.format(now), budgetMinutes * 2, TimeUnit.MINUTES);
try {
- //鑾峰彇鐪佺珛鍚屽痉瑕侀噰闆嗙殑闄㈠尯
- SysConfig cf = new SysConfig();
- cf.setConfigKey("sltd.gather.campusid");
- cf.setOrgid("20001001");
- List<SysConfig> sysConfigcampusids = configService.selectConfigList(cf);
-
- List<Long> campusidList = new ArrayList<>();
- if (CollectionUtils.isNotEmpty(sysConfigcampusids)) {
- String[] split = sysConfigcampusids.get(0).getConfigValue().split(",");
- campusidList = Arrays.stream(split).map(Long::valueOf).collect(Collectors.toList());
- } else {
- log.error("SysConfig涓殑闄㈠尯ID涓虹┖锛�");
- return;
- }
-
- // 鐪佺珛鍚屽痉鏁版嵁閲囬泦
- log.info("--campusidList鐨勫�间负锛歿}", campusidList);
- for (Long cid : campusidList) {
- String nowTime = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
- ServiceSLTDInhospReqVO serviceSLTDInhospReqVO = new ServiceSLTDInhospReqVO();
- serviceSLTDInhospReqVO.setOrgId("20001001");
- serviceSLTDInhospReqVO.setCampusId(cid);
- serviceSLTDInhospReqVO.setEncounterTimeStart(nowTime);
- serviceSLTDInhospReqVO.setEncounterTimeEnd(nowTime);
-
- // 闂ㄦ�ヨ瘖鍒嗛〉閲囬泦锛氭瘡椤�40鏉★紝鐩村埌鏃犳暟鎹负姝�(鍗楀崕闄勪竴鐨勫厛涓嶉噰闂ㄦ�ヨ瘖鏁版嵁)
- if (active.trim().equals("sltd")) {
- log.info("銆恉ealHisData銆戠渷绔嬪悓寰封�滈棬鎬ヨ瘖鈥濆紑濮嬪垎椤甸噰闆嗘暟鎹紝闄㈠尯锛歿}", cid);
- serviceSLTDInhospReqVO.setStartHeadTime(null);
- serviceSLTDInhospReqVO.setStartTailTime(null);
- //鏌ヨ褰撳ぉ鐨勬暟鎹�
- serviceSLTDInhospReqVO.setEncounterTimeEnd(tomorrowdayZero.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
- serviceSLTDInhospReqVO.setEncounterTimeStart(todayZero.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
- serviceSLTDInhospReqVO.setStatusList(null);
- List<String> list1 = new ArrayList<>();
- list1.add("FH0108.01");
- list1.add("FH0108.03");
- serviceSLTDInhospReqVO.setHealthcareRecordTypeList(list1);
- //浠庣紦瀛橀噷鑾峰彇璧峰椤碉紙闆剁偣鍓�10鍒嗛挓鍐呯敤鏄ㄥぉ鐨勬棩鏈燂紝閬垮厤璺ㄥぉ婕忛噰锛�
- LocalDateTime now = LocalDateTime.now();
- String mzCacheDate = (now.getHour() == 0 && now.getMinute() < 10) ? now.minusDays(1).format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) : now.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
- Long outpPage = redisCache.getCacheObject("mzCurrent" + cid + mzCacheDate);
- if (outpPage == null) outpPage = 1L;
- //閭h竟鏆傛椂鍙兘璁剧疆40
- final long OUTP_PAGE_SIZE = 500L;
- while (true) {
- serviceSLTDInhospReqVO.setCurrent(outpPage);
- serviceSLTDInhospReqVO.setSize(OUTP_PAGE_SIZE);
- log.info("銆恉ealHisData銆戠渷绔嬪悓寰封�滈棬鎬ヨ瘖鈥濋噰闆嗙{}椤垫暟鎹紝闄㈠尯锛歿}", outpPage, cid);
- List<ServiceSLTDInhospResDTO> outpResult = serviceSLTDHealthcareRecordService.queryHealthcareRecordList(serviceSLTDInhospReqVO);
- if (CollectionUtils.isEmpty(outpResult)) {
- log.info("銆恉ealHisData銆戠渷绔嬪悓寰封�滈棬鎬ヨ瘖鈥濈{}椤垫棤鏁版嵁锛岄噰闆嗙粨鏉燂紝闄㈠尯锛歿}", outpPage, cid);
- break;
- }
- log.info("銆恉ealHisData銆戠渷绔嬪悓寰封�滈棬鎬ヨ瘖鈥濈{}椤甸噰闆唟}鏉★紝闄㈠尯锛歿}", outpPage, outpResult.size(), cid);
- if (outpResult.size() < OUTP_PAGE_SIZE) {
- //璁剧疆涓�涓紦瀛橈紝鐢ㄦ潵瀛樺湪涓嬫鐨勮捣濮嬮〉
- redisCache.setCacheObject("mzCurrent" + cid + mzCacheDate, outpPage, 24, TimeUnit.HOURS);
- log.info("銆恉ealHisData銆戠渷绔嬪悓寰封�滈棬鎬ヨ瘖鈥濈殑缂撳瓨key:{}涓嬫鐨勮捣濮嬮〉{}锛岄櫌鍖猴細{}", "mzCurrent" + cid + mzCacheDate, outpPage, cid);
- break;
- }
- outpPage++;
- }
- // 娓呴櫎鍒嗛〉鍙傛暟锛岄伩鍏嶅奖鍝嶅悗缁嚭鍏ラ櫌鏌ヨ
- serviceSLTDInhospReqVO.setCurrent(null);
- serviceSLTDInhospReqVO.setSize(null);
- log.info("銆恉ealHisData銆戠渷绔嬪悓寰封�滈棬鎬ヨ瘖鈥濆垎椤甸噰闆嗗畬鎴愶紝闄㈠尯锛歿}", cid);
- }
- }
+ collectOutpatientDaily(cid, todayZeroStr, pageSize, maxPage, deadline);
} catch (Exception e) {
- log.error("銆恉ealHisData銆戠渷绔嬪悓寰锋暟鎹棬鎬ヨ瘖閲囬泦寮傚父", e);
+ log.error("銆恉ealHisDataMZ銆戦棬鎬ヨ瘖閲囬泦寮傚父锛岄櫌鍖猴細{}锛屾柇鐐瑰凡淇濈暀锛屼笅涓�杞粠鏂偣缁х画", cid, e);
+ } finally {
+ redisCache.deleteObject(lockKey);
}
}
+ log.info("銆恉ealHisDataMZ銆戦棬鎬ヨ瘖閲囬泦鏈疆缁撴潫锛岃�楁椂锛歿}绉�",
+ java.time.Duration.between(now, LocalDateTime.now()).getSeconds());
+ }
+
+ /**
+ * 閲囬泦鏌愪釜闄㈠尯锛氬厛琛ヤ竴娆℃�у洖婧棩鏈燂紝鍐嶅仛鏄ㄥぉ鐨勬敹灏鹃噰闆嗭紝鏈�鍚庢暣杞埛鏂颁粖澶�
+ */
+ private void collectOutpatientDaily(Long cid, String backfillParam, long pageSize, long maxPage,
+ LocalDateTime deadline) {
+ String cursorKey = "mzDayCursor:" + cid;
+ MzDayCursor cursor = loadMzDayCursor(cursorKey);
+ LocalDate today = LocalDate.now();
+ LocalDate yesterday = today.minusDays(1);
+
+ // 鎵嬪伐鍏ュ弬鎸囧畾鐨勪竴娆℃�у洖婧細鍚屼竴涓棩鏈熷彧琛ヤ竴娆★紝閬垮厤瀹氭椂浠诲姟姣忚疆閲嶅琛�
+ LocalDateTime backfillTime = parseMzStartTime(backfillParam);
+ if (backfillTime != null) {
+ LocalDate backfillDay = backfillTime.toLocalDate();
+ if (backfillDay.toString().equals(cursor.backfillDone)) {
+ log.info("銆恉ealHisDataMZ銆戝叆鍙傛棩鏈� {} 宸插畬鎴愬洖婧紝璺宠繃锛岄櫌鍖猴細{}", backfillDay, cid);
+ } else if (backfillDay.equals(today)) {
+ // 鍏ュ弬灏辨槸浠婂ぉ锛屼氦缁欎笅闈㈢殑鏁磋疆鍒锋柊澶勭悊鍗冲彲
+ cursor.backfillDone = backfillDay.toString();
+ saveMzDayCursor(cursorKey, cursor);
+ } else {
+ cursor.backfillDay = backfillDay.toString();
+ cursor.backfillPage = 1L;
+ saveMzDayCursor(cursorKey, cursor);
+ log.info("銆恉ealHisDataMZ銆戝緟鍥炴函鏃ユ湡锛歿}锛岄櫌鍖猴細{}", backfillDay, cid);
+ }
+ }
+
+ // 1) 涓�娆℃�у洖婧�
+ if (cursor.backfillDay != null) {
+ LocalDate day = LocalDate.parse(cursor.backfillDay);
+ MzGatherStatusEnum status = runDayPass(cid, cursorKey, cursor, MzGatherSlotEnum.BACKFILL, day,
+ cursor.backfillPage, pageSize, maxPage, deadline);
+ if (status != MzGatherStatusEnum.DONE) {
+ log.warn("銆恉ealHisDataMZ銆戝洖婧棩鏈� {} 鏈疆鏈畬鎴愶紙{}锛夛紝鏂偣宸蹭繚鐣欙紝闄㈠尯锛歿}", day, status.getDesc(), cid);
+ return;
+ }
+ cursor.backfillDone = cursor.backfillDay;
+ cursor.backfillDay = null;
+ cursor.backfillPage = 1L;
+ saveMzDayCursor(cursorKey, cursor);
+ }
+
+ // 2) 鏄ㄥぉ鏀跺熬閲囬泦锛氭瘡澶╀竴娆★紝鍏滀綇 23:xx 涔嬪悗鎵嶅啓杩� HIS 鐨勮褰曞拰璺ㄩ浂鐐圭殑鏁版嵁
+ if (!yesterday.toString().equals(cursor.finalDay)) {
+ MzGatherStatusEnum status = runDayPass(cid, cursorKey, cursor, MzGatherSlotEnum.FINAL, yesterday,
+ cursor.finalPage, pageSize, maxPage, deadline);
+ if (status != MzGatherStatusEnum.DONE) {
+ log.warn("銆恉ealHisDataMZ銆戞槰鏃ユ敹灏鹃噰闆� {} 鏈疆鏈畬鎴愶紙{}锛夛紝鏂偣宸蹭繚鐣欙紝闄㈠尯锛歿}", yesterday, status.getDesc(), cid);
+ return;
+ }
+ cursor.finalDay = yesterday.toString();
+ cursor.finalPage = 1L;
+ saveMzDayCursor(cursorKey, cursor);
+ }
+
+ // 3) 浠婂ぉ鐨勬暣杞埛鏂�
+ if (!today.toString().equals(cursor.day)) {
+ cursor.day = today.toString();
+ cursor.page = 1L;
+ saveMzDayCursor(cursorKey, cursor);
+ }
+ MzGatherStatusEnum status = runDayPass(cid, cursorKey, cursor, MzGatherSlotEnum.TODAY, today,
+ cursor.page, pageSize, maxPage, deadline);
+ if (status == MzGatherStatusEnum.DONE) {
+ // 鏁磋疆鍒锋柊瀹屾垚锛岄〉鐮佸綊浣嶏紝涓嬩竴杞噸鏂颁粠绗竴椤垫暣杞埛鏂�
+ cursor.page = 1L;
+ saveMzDayCursor(cursorKey, cursor);
+ log.info("銆恉ealHisDataMZ銆憑} 闂ㄦ�ヨ瘖鏁磋疆鍒锋柊瀹屾垚锛岄櫌鍖猴細{}", today, cid);
+ }
+ }
+
+ /**
+ * 鍏ㄩ噺閲囬泦鏌愪竴澶╋紙鍒嗛〉鐩村埌閲囧畬锛夛紝姣忛噰瀹屼竴椤电珛鍗宠惤涓�娆℃柇鐐�
+ *
+ * @param slot 鏂偣妲戒綅锛堜粖澶╂暣杞埛鏂� / 鏄ㄦ棩鏀跺熬 / 鎵嬪伐鍥炴函锛夛紝鍐冲畾涓柇椤电爜璁板埌鍝釜瀛楁
+ * @return {@link MzGatherStatusEnum} 閲囬泦瀹屾垚 / 棰勭畻鐢ㄥ敖 / 鎺ュ彛杩炵画澶辫触鎻愬墠缁撴潫
+ */
+ private MzGatherStatusEnum runDayPass(Long cid, String cursorKey, MzDayCursor cursor, MzGatherSlotEnum slot,
+ LocalDate day, long startPage, long pageSize, long maxPage,
+ LocalDateTime deadline) {
+ String startStr = day.format(MzGatherConstant.DAY_FMT);
+ String endStr = day.plusDays(1).format(MzGatherConstant.DAY_FMT);
+
+ ServiceSLTDInhospReqVO reqVO = new ServiceSLTDInhospReqVO();
+ reqVO.setOrgId(MzGatherConstant.ORG_ID);
+ reqVO.setCampusId(cid);
+ reqVO.setStartHeadTime(null);
+ reqVO.setStartTailTime(null);
+ reqVO.setStatusList(null);
+ // 鎺ュ彛鍙敮鎸佹寜澶╂煡锛岃捣姝㈤兘浼犳棩鏈�
+ reqVO.setEncounterTimeStart(startStr);
+ reqVO.setEncounterTimeEnd(endStr);
+ List<String> typeList = new ArrayList<>();
+ typeList.add("FH0108.01"); // 闂ㄨ瘖
+ typeList.add("FH0108.03"); // 鎬ヨ瘖
+ reqVO.setHealthcareRecordTypeList(typeList);
+ reqVO.setSize(pageSize);
+
+ long page = startPage < 1L ? 1L : startPage;
+ long total = 0L;
+ long pageCount = 0L;
+ // 鎺ュ彛灞傚け璐ヨ烦杩囩殑椤垫暟銆佺涓�涓け璐ラ〉銆佽繛缁け璐ラ〉鏁�
+ long skippedPages = 0L;
+ long firstFailPage = -1L;
+ int consecutiveFail = 0;
+ while (true) {
+ if (LocalDateTime.now().isAfter(deadline)) {
+ // 鏈疆鏈夎烦杩囩殑椤垫椂锛屾柇鐐瑰洖鍒扮涓�涓け璐ラ〉锛屼繚璇佷笅涓�杞厛鎶婅繖浜涢〉琛ュ洖鏉�
+ long resumePage = (skippedPages > 0 && firstFailPage > 0) ? firstFailPage : page;
+ saveMzDayPage(cursorKey, cursor, slot, resumePage);
+ log.warn("銆恉ealHisDataMZ銆戞湰杞椂闂撮绠楃敤灏斤紝{} 鏈疆宸查噰{}椤祘}鏉}锛屼笅娆′粠绗瑊}椤电户缁紝闄㈠尯锛歿}",
+ day, pageCount, total, skippedLog(skippedPages), resumePage, cid);
+ return MzGatherStatusEnum.BUDGET_UP;
+ }
+ reqVO.setCurrent(page);
+ log.info("銆恉ealHisDataMZ銆戦噰闆嗛棬鎬ヨ瘖鏁版嵁锛岄櫌鍖猴細{}锛屾棩鏈燂細{}锛岀{}椤�", cid, day, page);
+
+ List<ServiceSLTDInhospResDTO> pageData = null;
+ Exception lastError = null;
+ for (int attempt = 1; attempt <= MzGatherConstant.PAGE_RETRY_TIMES; attempt++) {
+ try {
+ pageData = serviceSLTDHealthcareRecordService.queryHealthcareRecordList(reqVO);
+ lastError = null;
+ break;
+ } catch (Exception e) {
+ lastError = e;
+ log.error("銆恉ealHisDataMZ銆戦棬鎬ヨ瘖绗瑊}椤电{}娆¢噰闆嗗け璐ワ紝闄㈠尯锛歿}锛屾棩鏈燂細{}", page, attempt, cid, day, e);
+ if (attempt < MzGatherConstant.PAGE_RETRY_TIMES) {
+ try {
+ Thread.sleep(MzGatherConstant.PAGE_RETRY_SLEEP_MS);
+ } catch (InterruptedException ie) {
+ Thread.currentThread().interrupt();
+ break;
+ }
+ }
+ }
+ }
+ if (lastError != null) {
+ // 鎺ュ彛灞傚け璐ワ紙缃戠粶瓒呮椂 / 鏉ユ湭鏉ヨ繑鍥為潪200锛夋病鏈夋暟鎹彲浠ヨ惤琛紝鍙啓 error 鏃ュ織锛岀劧鍚庤烦杩囪椤电户缁線鍚庨噰锛屼笉闃绘柇杩涘害銆�
+ // 姣忚疆閮芥槸鏁村ぉ浠庡ご鍏ㄩ噺鍒锋柊锛岃璺宠繃鐨勯〉涓嬩竴杞繀鐒堕噸鏂伴噰鍒帮紝鎵�浠ヤ笉浼氭紡鏁版嵁銆�
+ skippedPages++;
+ if (firstFailPage < 0) {
+ firstFailPage = page;
+ }
+ consecutiveFail++;
+ log.error("銆恉ealHisDataMZ銆戞帴鍙e眰閲囬泦澶辫触锛屽凡璁� error 鏃ュ織骞惰烦杩囪椤碉紝鏈疆缁х画寰�鍚庨噰锛�"
+ + "闄㈠尯锛歿}锛屾棩鏈燂細{}锛岀{}椤碉紝鎺ュ彛鍏ュ弬锛歿}锛屽紓甯革細{}",
+ cid, day, page, new Gson().toJson(reqVO), lastError.getMessage(), lastError);
+ if (consecutiveFail >= MzGatherConstant.MAX_CONSECUTIVE_PAGE_FAIL) {
+ // 杩炵画澶氶〉鎺ュ彛澶辫触锛屽垽瀹氭潵鏈潵鎺ュ彛鏁翠綋涓嶅彲鐢紝鏈疆鎻愬墠缁撴潫锛堜笉鍐嶇┖杞悗闈㈠嚑鍗侀〉锛夛紝鏂偣鐣欏湪绗竴涓け璐ラ〉
+ log.error("銆恉ealHisDataMZ銆戣繛缁瓄}椤垫帴鍙eけ璐ワ紝鍒ゅ畾鏉ユ湭鏉ユ帴鍙d笉鍙敤锛屾湰杞彁鍓嶇粨鏉燂紱闄㈠尯锛歿}锛屾棩鏈燂細{}锛屾柇鐐逛繚鐣欏湪绗瑊}椤�",
+ consecutiveFail, cid, day, firstFailPage);
+ saveMzDayPage(cursorKey, cursor, slot, firstFailPage);
+ return MzGatherStatusEnum.FAILED;
+ }
+ page++;
+ continue;
+ }
+ consecutiveFail = 0;
+
+ if (CollectionUtils.isEmpty(pageData)) {
+ log.info("銆恉ealHisDataMZ銆憑} 绗瑊}椤垫棤鏁版嵁锛岄噰闆嗙粨鏉燂紝闄㈠尯锛歿}锛屾湰杞畕}椤靛叡{}鏉}",
+ day, page, cid, pageCount, total, skippedLog(skippedPages));
+ return MzGatherStatusEnum.DONE;
+ }
+ pageCount++;
+ total += pageData.size();
+ log.info("銆恉ealHisDataMZ銆憑} 绗瑊}椤甸噰闆唟}鏉★紝闄㈠尯锛歿}", day, page, pageData.size(), cid);
+ if (pageData.size() < pageSize) {
+ log.info("銆恉ealHisDataMZ銆憑} 閲囬泦缁撴潫锛岄櫌鍖猴細{}锛屾湰杞畕}椤靛叡{}鏉}", day, cid, pageCount, total, skippedLog(skippedPages));
+ return MzGatherStatusEnum.DONE;
+ }
+ page++;
+ if (page > maxPage) {
+ log.error("銆恉ealHisDataMZ銆憑} 宸茬炕鍒扮{}椤碉紝瓒呰繃鍗曟棩涓婇檺{}椤碉紝鎸夐噰瀹屽鐞嗭紝闄㈠尯锛歿}", day, page, maxPage, cid);
+ return MzGatherStatusEnum.DONE;
+ }
+ // 姣忛噰瀹屼竴椤电珛鍗宠惤鏂偣锛氳繘绋嬭閲嶅惎/寮烘潃涔熻兘浠庤繖涓�椤电户缁紝涓嶄粠澶撮噸鎵紝涔熶笉浼氭紡
+ saveMzDayPage(cursorKey, cursor, slot, page);
+ }
+ }
+
+ /** 鎸夋Ы浣嶄繚瀛樹腑鏂〉鐮� */
+ private void saveMzDayPage(String cursorKey, MzDayCursor cursor, MzGatherSlotEnum slot, long page) {
+ if (slot == MzGatherSlotEnum.FINAL) {
+ cursor.finalPage = page;
+ } else if (slot == MzGatherSlotEnum.BACKFILL) {
+ cursor.backfillPage = page;
+ } else {
+ cursor.page = page;
+ }
+ saveMzDayCursor(cursorKey, cursor);
+ }
+
+ /** 鏃ュ織閲屾彁绀烘帴鍙e眰澶辫触璺宠繃浜嗗嚑椤碉紙涓嬩竴杞暣杞埛鏂颁細閲嶆柊閲囧埌锛� */
+ private String skippedLog(long skippedPages) {
+ return skippedPages > 0L ? "锛屾帴鍙eけ璐ヨ烦杩�" + skippedPages + "椤碉紙涓嬩竴杞暣杞埛鏂颁細閲嶆柊閲囧埌锛�" : "";
+ }
+
+ /** 璇诲彇 sys_config 閲岀殑闂ㄦ�ヨ瘖閲囬泦鍙傛暟锛堟満鏋� orgid=20001001锛夛紝鍙栦笉鍒版垨瓒呰寖鍥存椂鐢ㄦ灇涓鹃噷鐨勯粯璁ゅ�� */
+ private long getMzConfigLong(MzGatherParamEnum param) {
+ try {
+ SysConfig config = new SysConfig();
+ config.setConfigKey(param.getKey());
+ config.setOrgid(MzGatherConstant.ORG_ID);
+ List<SysConfig> configs = configService.selectConfigList(config);
+ if (CollectionUtils.isNotEmpty(configs) && StringUtils.isNotBlank(configs.get(0).getConfigValue())) {
+ long value = Long.parseLong(configs.get(0).getConfigValue().trim());
+ if (value >= param.getMin() && value <= param.getMax()) {
+ return value;
+ }
+ log.warn("銆恉ealHisDataMZ銆戦厤缃畕}鐨勫�納}瓒呭嚭鑼冨洿[{},{}]锛屼娇鐢ㄩ粯璁ゅ�納}",
+ param.getKey(), value, param.getMin(), param.getMax(), param.getDefaultValue());
+ }
+ } catch (Exception e) {
+ log.warn("銆恉ealHisDataMZ銆戣鍙栭厤缃畕}澶辫触锛屼娇鐢ㄩ粯璁ゅ�納}", param.getKey(), param.getDefaultValue(), e);
+ }
+ return param.getDefaultValue();
+ }
+
+ /** 瑙f瀽浠诲姟鍏ュ弬锛堣涓�娆℃�у洖婧殑鏃ユ湡锛夛紝鏀寔 yyyy-MM-dd HH:mm:ss 涓� yyyy-MM-dd */
+ private LocalDateTime parseMzStartTime(String text) {
+ LocalDateTime time = parseMzTimeQuiet(text);
+ if (time == null && StringUtils.isNotBlank(text)) {
+ log.warn("銆恉ealHisDataMZ銆戝叆鍙� {} 鏃犳硶瑙f瀽涓烘棩鏈燂紝鎸夋湭鎸囧畾澶勭悊", text);
+ }
+ return time;
+ }
+
+ /** 闈欓粯瑙f瀽鏃ユ湡锛屾敮鎸� yyyy-MM-dd HH:mm:ss 涓� yyyy-MM-dd锛屾牸寮忎笉绗﹁繑鍥� null锛堜笉鍒锋棩蹇楋級 */
+ private LocalDateTime parseMzTimeQuiet(String text) {
+ if (StringUtils.isBlank(text)) {
+ return null;
+ }
+ String value = text.trim();
+ try {
+ return LocalDateTime.parse(value, MzGatherConstant.MINUTE_FMT);
+ } catch (Exception ignore) {
+ // 鍏煎鍙紶鏃ユ湡鐨勬儏鍐碉紝钀藉埌涓嬮潰鎸夋棩鏈熻В鏋�
+ }
+ try {
+ return LocalDate.parse(value).atStartOfDay();
+ } catch (Exception ignore) {
+ return null;
+ }
+ }
+
+ /** 淇濆瓨闂ㄦ�ヨ瘖閲囬泦鏂偣锛堝悇杞涓柇鐨勯〉鐮侊級 */
+ private void saveMzDayCursor(String cursorKey, MzDayCursor cursor) {
+ JSONObject json = new JSONObject();
+ json.put("day", cursor.day);
+ json.put("page", cursor.page);
+ json.put("finalDay", cursor.finalDay);
+ json.put("finalPage", cursor.finalPage);
+ json.put("backfillDay", cursor.backfillDay);
+ json.put("backfillPage", cursor.backfillPage);
+ json.put("backfillDone", cursor.backfillDone);
+ json.put("updateTime", MzGatherConstant.MINUTE_FMT.format(LocalDateTime.now().withNano(0)));
+ redisCache.setCacheObject(cursorKey, json.toJSONString(), MzGatherConstant.CACHE_TTL_HOURS, TimeUnit.HOURS);
+ }
+
+ /** 璇诲彇闂ㄦ�ヨ瘖閲囬泦鏂偣锛岃涓嶅埌鎴栬В鏋愬け璐ユ椂杩斿洖绌烘柇鐐癸紙绛変环浜庝粠绗竴椤靛紑濮嬫暣杞埛鏂帮級 */
+ private MzDayCursor loadMzDayCursor(String cursorKey) {
+ MzDayCursor cursor = new MzDayCursor();
+ try {
+ String json = redisCache.getCacheObject(cursorKey);
+ if (StringUtils.isBlank(json)) {
+ return cursor;
+ }
+ JSONObject obj = JSONObject.parseObject(json);
+ cursor.day = obj.getString("day");
+ cursor.page = obj.getLongValue("page");
+ cursor.finalDay = obj.getString("finalDay");
+ cursor.finalPage = obj.getLongValue("finalPage");
+ cursor.backfillDay = obj.getString("backfillDay");
+ cursor.backfillPage = obj.getLongValue("backfillPage");
+ cursor.backfillDone = obj.getString("backfillDone");
+ if (cursor.page < 1L) {
+ cursor.page = 1L;
+ }
+ if (cursor.finalPage < 1L) {
+ cursor.finalPage = 1L;
+ }
+ if (cursor.backfillPage < 1L) {
+ cursor.backfillPage = 1L;
+ }
+ return cursor;
+ } catch (Exception e) {
+ log.warn("銆恉ealHisDataMZ銆戣鍙栨柇鐐箋}澶辫触锛屾寜绌烘柇鐐瑰鐞�", cursorKey, e);
+ return new MzDayCursor();
+ }
+ }
+
+ /**
+ * 闂ㄦ�ヨ瘖閲囬泦鏂偣锛氭瘡澶╀竴杞叏閲忓埛鏂帮紝杩欓噷鍒嗗埆璁板綍涓変釜杞涓柇鍦ㄧ鍑犻〉
+ * 锛堥〉鐮佷负 1 琛ㄧず璇ヨ疆娆′笅涓�杞粠绗竴椤垫暣杞紑濮嬶級
+ */
+ private static class MzDayCursor {
+ /** 浠婂ぉ鐨勬暣杞埛鏂� */
+ private String day;
+ private long page = 1L;
+ /** 鏄ㄥぉ鐨勬敹灏鹃噰闆� */
+ private String finalDay;
+ private long finalPage = 1L;
+ /** 寰呭仛鐨勪竴娆℃�у洖婧� */
+ private String backfillDay;
+ private long backfillPage = 1L;
+ /** 宸茬粡琛ヨ繃鐨勫洖婧棩鏈燂紝閬垮厤瀹氭椂浠诲姟姣忚疆閲嶅琛ュ悓涓�澶� */
+ private String backfillDone;
}
/**
diff --git a/smartor/src/main/java/com/smartor/domain/DTO/DetailTraceDealDTO.java b/smartor/src/main/java/com/smartor/domain/DTO/DetailTraceDealDTO.java
index 29a12de..b0ac693 100644
--- a/smartor/src/main/java/com/smartor/domain/DTO/DetailTraceDealDTO.java
+++ b/smartor/src/main/java/com/smartor/domain/DTO/DetailTraceDealDTO.java
@@ -37,7 +37,12 @@
@Excel(name = "闂ID")
private Long scriptid;
-
+ /**
+ * 闂ID
+ */
+ @ApiModelProperty("闂ID闆嗗悎")
+ @Excel(name = "闂ID闆嗗悎")
+ private List<Long> scriptids;
/**
* 妯℃澘绫诲瀷锛�1.璇煶 2.闂嵎
diff --git a/smartor/src/main/java/com/smartor/domain/ServiceSLTDInhospReqVO.java b/smartor/src/main/java/com/smartor/domain/ServiceSLTDInhospReqVO.java
index aa0724d..2e82db5 100644
--- a/smartor/src/main/java/com/smartor/domain/ServiceSLTDInhospReqVO.java
+++ b/smartor/src/main/java/com/smartor/domain/ServiceSLTDInhospReqVO.java
@@ -68,10 +68,10 @@
@ApiModelProperty(value = "鍑洪櫌鏃堕棿-缁撴潫鏃堕棿 yyyy-MM-dd")
private String preOutHospitalTailDate;
- @ApiModelProperty(value = "灏辫瘖鏃堕棿-寮�濮嬫椂闂� : 闂ㄨ瘖璇婄枟璁板綍涓哄彿婧愭椂闂� 浣忛櫌璇婄枟璁板綍涓哄叆闄㈢櫥璁版椂闂� yyyy-MM-dd")
+ @ApiModelProperty(value = "灏辫瘖鏃堕棿-寮�濮嬫椂闂� : 闂ㄨ瘖璇婄枟璁板綍涓哄彿婧愭椂闂� 浣忛櫌璇婄枟璁板綍涓哄叆闄㈢櫥璁版椂闂� yyyy-MM-dd 鎴� yyyy-MM-dd HH:mm:ss锛堥棬鎬ヨ瘖澧為噺閲囬泦绮剧‘鍒扮锛�")
private String encounterTimeStart;
- @ApiModelProperty(value = "灏辫瘖鏃堕棿-缁撴潫鏃堕棿 yyyy-MM-dd")
+ @ApiModelProperty(value = "灏辫瘖鏃堕棿-缁撴潫鏃堕棿 yyyy-MM-dd 鎴� yyyy-MM-dd HH:mm:ss锛堥棬鎬ヨ瘖澧為噺閲囬泦绮剧‘鍒扮锛�")
private String encounterTimeEnd;
@ApiModelProperty(value = "鍑洪櫌缁撶畻鏃堕棿-寮�濮嬫椂闂� yyyy-MM-dd")
diff --git a/smartor/src/main/java/com/smartor/domain/SvyLibTemplateCategory.java b/smartor/src/main/java/com/smartor/domain/SvyLibTemplateCategory.java
index 0047b17..fc770a5 100644
--- a/smartor/src/main/java/com/smartor/domain/SvyLibTemplateCategory.java
+++ b/smartor/src/main/java/com/smartor/domain/SvyLibTemplateCategory.java
@@ -66,5 +66,11 @@
@ApiModelProperty(value = "鍖婚櫌鏈烘瀯id")
private Integer seqno;
+ /**
+ * 闂绫诲瀷锛堜緥濡�,闂ㄨ瘖婊℃剰搴︼細mzmyd 浣忛櫌婊℃剰搴︼細zymyd ...锛�
+ */
+ @Excel(name = "闂绫诲瀷锛堜緥濡�,闂ㄨ瘖婊℃剰搴︼細mzmyd 浣忛櫌婊℃剰搴︼細zymyd ...锛�")
+ @ApiModelProperty("闂绫诲瀷锛堜緥濡�,闂ㄨ瘖婊℃剰搴︼細mzmyd 浣忛櫌婊℃剰搴︼細zymyd ...锛�")
+ private String type;
}
diff --git a/smartor/src/main/java/com/smartor/mapper/PatMedOuthospMapper.java b/smartor/src/main/java/com/smartor/mapper/PatMedOuthospMapper.java
index c0fb31b..90bb456 100644
--- a/smartor/src/main/java/com/smartor/mapper/PatMedOuthospMapper.java
+++ b/smartor/src/main/java/com/smartor/mapper/PatMedOuthospMapper.java
@@ -1,5 +1,6 @@
package com.smartor.mapper;
+import java.util.Collection;
import java.util.List;
import java.util.Map;
@@ -90,6 +91,15 @@
// 鏌ヨ鎵�鏈� pat_med_outhosp 寮�澶寸殑琛ㄥ悕
List<String> getAllOuthospTableNames();
+ /**
+ * 鎵归噺鏌ヨ鎸囧畾鍒嗚〃涓凡瀛樺湪鐨� serialnum锛堜竴娆� SQL 浠f浛閫愭潯 countBySerialnum锛�
+ *
+ * @param tableName 鍒嗚〃鍚�
+ * @param serialnums 寰呮煡璇㈢殑璇婄枟璁板綍鍙�
+ * @return 宸插瓨鍦ㄧ殑 serialnum 闆嗗悎
+ */
+ List<String> selectExistingSerialnums(@Param("tableName") String tableName, @Param("serialnums") Collection<String> serialnums);
+
// 鏌ヨ鎸囧畾琛ㄧ殑瀛楁鍒楄〃锛堟寜 ordinal_position 鎺掑簭锛�
List<String> getTableColumns(@Param("tableName") String tableName);
diff --git a/smartor/src/main/java/com/smartor/mapper/ServiceSubtaskDetailMapper.java b/smartor/src/main/java/com/smartor/mapper/ServiceSubtaskDetailMapper.java
index 5ceb6b8..7161470 100644
--- a/smartor/src/main/java/com/smartor/mapper/ServiceSubtaskDetailMapper.java
+++ b/smartor/src/main/java/com/smartor/mapper/ServiceSubtaskDetailMapper.java
@@ -51,6 +51,29 @@
*/
public List<Map<String, Object>> selectSatisfactionFillStatByMatchedtext(SatisfactionStatQuery query);
+ /**
+ * 婊℃剰搴︽煴鐘跺浘锛氫竴娆℃�х粺璁℃湰娆¤姹傚叏閮ㄦā鏉跨殑銆屽洖鏀朵汉鏁般��
+ * 锛堟寜 libtemplateid 鍒嗙粍锛宑ount(distinct sub_id)锛氬悓涓�涓汉绛斾簡澶氶亾棰樺彧绠椾竴浜猴級
+ * <p>
+ * satisfactionGraph / satisfactionGraphDimension 鐨勫洖鏀朵汉鏁板繀椤绘槸浜烘暟鍙e緞锛�
+ * 涓嶈兘鍍� selectSatisfactionFillStat 閭f牱鎸夐鐩眹鎬荤瓟妗堣鏁帮紙閭f槸棰橀噺鍙e緞锛�
+ *
+ * @param query 鑱氬悎鏌ヨ鏉′欢
+ * @return 姣忚鍚� libtemplateid銆乧nt锛堣妯℃澘宸插洖鏀剁殑浠芥暟/浜烘暟锛�
+ */
+ public List<Map<String, Object>> selectSatisfactionFillPersonCount(SatisfactionStatQuery query);
+
+ /**
+ * 鎸� scriptid 鎵归噺缁熻濉啓璁板綍鏁帮紙涓�娆� SQL 鏇夸唬閫愪釜 scriptid 鏌ユ槑缁嗭級
+ * <p>
+ * 鍙e緞涓庡師鏉ャ�宷uery.setScriptid(scriptId) 鍚� selectServiceSubtaskDetailList(...).size()銆嶄竴鑷达細
+ * 鍙寜 scriptid 杩囨护锛屼笉甯� del_flag锛堝師 SQL 閲屽苟娌℃湁 del_flag 鏉′欢锛夈��
+ *
+ * @param scriptIds 闂ID闆嗗悎
+ * @return 姣忚鍚� scriptid銆乧nt
+ */
+ public List<Map<String, Object>> countDetailByScriptIds(@Param("scriptIds") List<Long> scriptIds);
+
public ServiceSubtaskDetailDTO isExistServiceSubtaskDetail(@Param("subid") Long subid, @Param("scriptid") Long scriptid);
/**
diff --git a/smartor/src/main/java/com/smartor/mapper/ServiceSubtaskDetailTraceMapper.java b/smartor/src/main/java/com/smartor/mapper/ServiceSubtaskDetailTraceMapper.java
index cb7a2fa..a13006a 100644
--- a/smartor/src/main/java/com/smartor/mapper/ServiceSubtaskDetailTraceMapper.java
+++ b/smartor/src/main/java/com/smartor/mapper/ServiceSubtaskDetailTraceMapper.java
@@ -1,10 +1,12 @@
package com.smartor.mapper;
import java.util.List;
+import java.util.Map;
import com.smartor.domain.VO.DetailTraceDealVO;
import com.smartor.domain.VO.ServiceSubtaskDetailTraceVO;
import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
import com.smartor.domain.ServiceSubtaskDetailTrace;
/**
@@ -32,7 +34,39 @@
public List<ServiceSubtaskDetailTrace> selectServiceSubtaskDetailTtraceList(ServiceSubtaskDetailTraceVO ServiceSubtaskDetailTtrace);
- public List<ServiceSubtaskDetailTrace> tracedeallist(DetailTraceDealVO detailTraceDealVO);
+ /**
+ * 寮傚父闂澶勭悊鎯呭喌鏌ヨ锛氬綋鍓嶉〉鐨勯棶棰樺垎缁勮仛鍚堬紙涓�涓� SQL 鎷垮埌鏈〉姣忎釜闂鐨勫紓甯告暟銆佸凡澶勭悊/鏈鐞嗘暟锛�
+ * <p>
+ * 鍒嗛〉鎸夈�岄棶棰樸�嶇淮搴︿笅鎺紝涓嶅啀鎶婃暣琛� trace 鏄庣粏鎷夊洖 Java 鍐嶅垎缁�
+ *
+ * @param vo 鏌ヨ鏉′欢锛坧ageNum 涓� offset锛屼笌 PageUtils.getOffset 涓�鑷达級
+ * @return 姣忚鍚� questiontext銆乻criptid銆乼emplateType銆乪xceptionFillNum銆亂esDeal銆乶oDeal
+ */
+ public List<Map<String, Object>> selectTraceDealGroups(@Param("vo") DetailTraceDealVO vo);
+
+ /**
+ * 寮傚父闂澶勭悊鎯呭喌鏌ヨ锛氶棶棰樻�绘暟锛堝垎椤� total锛屾寜 questiontext 鍘婚噸锛�
+ */
+ public long countTraceDealQuestions(@Param("vo") DetailTraceDealVO vo);
+
+ /**
+ * 寮傚父闂澶勭悊鎯呭喌鏌ヨ锛氬叏閲忔眹鎬伙紙涓嶅彈鍒嗛〉褰卞搷锛�
+ *
+ * @return totalException 寮傚父鎬绘暟銆亂esDeal 宸插鐞嗘暟
+ */
+ public Map<String, Object> sumTraceDeal(@Param("vo") DetailTraceDealVO vo);
+
+ /**
+ * 寮傚父闂澶勭悊鎯呭喌鏌ヨ锛氬綋鍓嶉〉闂鐨勮礋璐g瀹わ紙鎸� todeptcode 鍘婚噸锛�
+ */
+ public List<Map<String, Object>> selectTraceDealDepts(@Param("vo") DetailTraceDealVO vo,
+ @Param("questiontexts") List<String> questiontexts);
+
+ /**
+ * 寮傚父闂澶勭悊鎯呭喌鏌ヨ锛氬綋鍓嶉〉闂鐨勬渶鏂板鐞嗕汉鍜屽鐞嗘椂闂达紙handle_time 鏈�澶х殑涓�鏉★級
+ */
+ public List<Map<String, Object>> selectTraceDealLatestHandle(@Param("vo") DetailTraceDealVO vo,
+ @Param("questiontexts") List<String> questiontexts);
/**
* 鏂板闅忚浠诲姟寮傚父璁板綍璺熻釜
diff --git a/smartor/src/main/java/com/smartor/service/IPatMedOuthospService.java b/smartor/src/main/java/com/smartor/service/IPatMedOuthospService.java
index 6b66717..889501e 100644
--- a/smartor/src/main/java/com/smartor/service/IPatMedOuthospService.java
+++ b/smartor/src/main/java/com/smartor/service/IPatMedOuthospService.java
@@ -1,7 +1,9 @@
package com.smartor.service;
+import java.util.Collection;
import java.util.Date;
import java.util.List;
+import java.util.Set;
import com.ruoyi.common.core.page.TableDataInfo;
import com.smartor.domain.*;
@@ -39,6 +41,18 @@
public int insertPatMedOuthosp(PatMedOuthosp patMedOuthosp);
/**
+ * 鎵归噺鏌ヨ宸插叆搴撶殑 serialnum锛堝唴閮ㄦ寜灏辫瘖鏃ユ湡瀹氫綅鍒嗚〃锛屼竴娆� SQL 瀹屾垚锛�
+ * <p>
+ * 闂ㄦ�ヨ瘖鎸夊ぉ鍏ㄩ噺閲囬泦鏃讹紝姣忓崐灏忔椂浼氭妸褰撳ぉ涓婁竾涓瘖鐤楄褰曢噸鏂版媺涓�閬嶏紝
+ * 鐢ㄨ繖涓柟娉曚竴娆℃煡鍑哄凡缁忓叆搴撶殑锛岀洿鎺ヨ烦杩囷紝閬垮厤瀵归噸澶嶆暟鎹啀鍋氫竴閬嶆。妗堝鐞嗗拰鍏ュ簱
+ *
+ * @param admitDateStr 灏辫瘖鏃ユ湡 yyyy-MM-dd锛屼负绌烘垨瑙f瀽澶辫触鏃舵寜涓昏〃鏌ヨ
+ * @param serialnums 寰呮煡璇㈢殑璇婄枟璁板綍鍙烽泦鍚�
+ * @return 宸插瓨鍦ㄧ殑 serialnum 闆嗗悎
+ */
+ public Set<String> selectExistingSerialnums(String admitDateStr, Collection<String> serialnums);
+
+ /**
* 淇敼鎮h�呴棬璇婅褰�
*
* @param patMedOuthosp 鎮h�呴棬璇婅褰�
diff --git a/smartor/src/main/java/com/smartor/service/impl/PatMedOuthospServiceImpl.java b/smartor/src/main/java/com/smartor/service/impl/PatMedOuthospServiceImpl.java
index b73e932..9b0fcea 100644
--- a/smartor/src/main/java/com/smartor/service/impl/PatMedOuthospServiceImpl.java
+++ b/smartor/src/main/java/com/smartor/service/impl/PatMedOuthospServiceImpl.java
@@ -197,7 +197,48 @@
patMedOuthosp.setUpdateTime(DateUtils.getNowDate());
patMedOuthosp.setGuid(UUID.randomUUID().toString());
log.info("[insert] 璺敱鍒板垎琛�: {}", targetTable);
- return patMedOuthospMapper.insertIntoTable(targetTable, patMedOuthosp);
+ try {
+ return patMedOuthospMapper.insertIntoTable(targetTable, patMedOuthosp);
+ } catch (org.springframework.dao.DuplicateKeyException e) {
+ // 鍔犱簡 serialnum 鍞竴绱㈠紩鍚庯紝鏋佺骞跺彂鎴栭噸澶嶉噰闆嗕細琚暟鎹簱鐩存帴鎷︿笅锛�
+ // 杩欏睘浜�"璁板綍宸插瓨鍦�"锛屾寜姝e父璺宠繃澶勭悊锛堣繑鍥�0锛夛紝涓嶈褰撴垚鍏ュ簱澶辫触鍐欒繘閿欒琛�
+ log.info("[insert] serialnum={} 宸插瓨鍦ㄤ簬琛� {}锛堝敮涓�绱㈠紩鎷︽埅锛夛紝璺宠繃鎻掑叆", patMedOuthosp.getSerialnum(), targetTable);
+ return 0;
+ }
+ }
+
+ /**
+ * 鎵归噺鏌ヨ宸插叆搴撶殑 serialnum锛氭寜灏辫瘖鏃ユ湡瀹氫綅鍒嗚〃锛屼竴娆� IN 鏌ヨ鏌ュ嚭鏁撮〉宸插瓨鍦ㄧ殑璁板綍
+ * <p>
+ * 鍘熸潵姣忔潯璁板綍閮借 countBySerialnum 涓�娆★紝涓�椤� 500 鏉″氨鏄� 500 娆� SQL锛�
+ * 闂ㄦ�ヨ瘖鎸夊ぉ鍏ㄩ噺閲囬泦鏃舵瘡澶╄杩欎箞璺� 48 杞紝杩欓噷鍚堝苟鎴� 1 娆℃煡璇�
+ */
+ @Override
+ public Set<String> selectExistingSerialnums(String admitDateStr, Collection<String> serialnums) {
+ Set<String> existing = new HashSet<>();
+ if (CollectionUtils.isEmpty(serialnums)) {
+ return existing;
+ }
+ Date admitDate = null;
+ if (StringUtils.isNotBlank(admitDateStr)) {
+ try {
+ admitDate = new java.text.SimpleDateFormat("yyyy-MM-dd").parse(admitDateStr);
+ } catch (java.text.ParseException e) {
+ log.warn("[selectExistingSerialnums] 灏辫瘖鏃ユ湡瑙f瀽澶辫触锛歿}锛屾寜涓昏〃鏌ヨ", admitDateStr);
+ }
+ }
+ // 涓庢彃鍏ユ椂鐨勮矾鐢辫鍒欎繚鎸佷竴鑷达紝淇濊瘉鏌ラ噸鏌ョ殑灏辨槸瑕佸啓鍏ョ殑閭e紶琛�
+ String targetTable = admitDate == null ? null : resolveTargetTable(admitDate);
+ if (targetTable == null) {
+ targetTable = "pat_med_outhosp";
+ }
+ List<String> existed = patMedOuthospMapper.selectExistingSerialnums(targetTable, serialnums);
+ if (!CollectionUtils.isEmpty(existed)) {
+ existing.addAll(existed);
+ }
+ log.info("[selectExistingSerialnums] 鏃ユ湡={}锛屽垎琛�={}锛屽緟鏌}鏉★紝宸插瓨鍦▄}鏉�",
+ admitDateStr, targetTable, serialnums.size(), existing.size());
+ return existing;
}
/**
diff --git a/smartor/src/main/java/com/smartor/service/impl/PatSatisfactionServiceImpl.java b/smartor/src/main/java/com/smartor/service/impl/PatSatisfactionServiceImpl.java
index d952ca2..9e07d77 100644
--- a/smartor/src/main/java/com/smartor/service/impl/PatSatisfactionServiceImpl.java
+++ b/smartor/src/main/java/com/smartor/service/impl/PatSatisfactionServiceImpl.java
@@ -326,31 +326,40 @@
//2 鍐嶈幏鍙栬闂婊℃剰搴﹀垎绫讳笅鐨処vrLibaTemplateScript鐨勯泦鍚�
List<IvrLibaTemplateScript> ivrLibaTemplateScripts = ivrLibaTemplateScriptMapper.queryLibTemplateIds(mydIdList);
- //2.1 涓�娆℃�ф妸鏈璇锋眰鍏ㄩ儴妯℃澘鐨勫彂閫侀噺銆佸~鎶ラ噺鏌ュ洖鏉ワ紙鍘熸潵鏄瘡涓ā鏉块棶棰樺悇鏌ヤ袱娆★級
+ //2.1 涓�娆℃�ф妸鏈璇锋眰鍏ㄩ儴妯℃澘鐨勫彂閫侀噺銆佸洖鏀朵汉鏁版煡鍥炴潵锛堝師鏉ユ槸姣忎釜妯℃澘闂鍚勬煡涓ゆ锛�
SatisfactionStatQuery statQuery = buildSatisfactionStatQuery(patSatisfactionReqVO, "1",
ivrLibaTemplateScripts.stream().map(IvrLibaTemplateScript::getTemplateid).collect(Collectors.toList()));
Map<Long, Long> sendCountMap = mapSatisfactionSendCount(statQuery);
SatisfactionFillStat fillStat = querySatisfactionFillStat(statQuery);
+ Map<Long, Long> fillPersonCountMap = mapSatisfactionFillPersonCount(statQuery);
//3 鎸塻criptAssortname鍒嗙粍,骞惰幏鍙栨瘡涓泦鍚堣繘琛岄亶鍘嗭紝璁$畻姣忎釜鍒嗙被鐨勬�讳汉鏁板拰濉姤浜烘暟
Map<String, List<IvrLibaTemplateScript>> scriptGroupByAssortName = ivrLibaTemplateScripts.stream().filter(item -> item.getScriptAssortname() != null).collect(Collectors.groupingBy(IvrLibaTemplateScript::getScriptAssortname));
if (scriptGroupByAssortName != null && !scriptGroupByAssortName.isEmpty()) {
for (String assortNameKey : scriptGroupByAssortName.keySet()) {
- //璁板綍鎬讳汉鏁�
- Double subidAll = 0.0;
- //璁板綍鎬荤殑濉姤浜烘暟
- Double fillCountAll = 0.0;
- //鑾峰彇璇ュ垎绫荤殑濉姤鎬绘暟閲�
+ // 璇ュ垎绫绘秹鍙婄殑鍘婚噸妯℃澘锛氬彂閫佷汉鏁�/鍥炴敹浜烘暟閮芥寜妯℃澘缁熻锛�
+ // 鎸夐鐩惊鐜疮鍔犱細鎶婂悓涓�涓ā鏉跨殑閲忛噸澶嶈鎴愩�岄閲忋��
+ Set<Long> categoryTemplateIds = new LinkedHashSet<>();
+ //鑾峰彇璇ュ垎绫荤殑濉姤鎬绘暟閲忥紙鍙敤浜庣畻骞冲潎鍒嗭紝鎸夐鐩仛鍚堢殑琛屾暟锛�
List<ScoreCount> allFillCountList = new ArrayList<>();
List<IvrLibaTemplateScript> ivrLibaTemplateScriptList = scriptGroupByAssortName.get(assortNameKey);
for (IvrLibaTemplateScript ivrLibaTemplateScript : ivrLibaTemplateScriptList) {
- //閫氳繃妯℃澘id鍙栭棶棰樺彂閫佹�婚噺锛堝師鏉ユ槸鎶婂叏閮� sub_id 鏌ュ洖 Java 鍐嶅彇 size锛�
- subidAll += sendCountMap.getOrDefault(ivrLibaTemplateScript.getTemplateid(), 0L);
- //鑾峰彇濉姤鏁伴噺锛堝師鏉ユ槸鎶婃槑缁嗚鍏ㄩ儴鏌ュ洖 Java 鍐嶅彇 size锛�
- List<ScoreCount> fillCount = fillStat.get(ivrLibaTemplateScript.getTemplateid(), ivrLibaTemplateScript.getScriptContent());
+ Long templateId = ivrLibaTemplateScript.getTemplateid();
+ if (templateId != null) {
+ categoryTemplateIds.add(templateId);
+ }
+ //鑾峰彇濉姤鍒嗗�煎垎甯冿紙鍙敤浜庡钩鍧囧垎锛�
+ List<ScoreCount> fillCount = fillStat.get(templateId, ivrLibaTemplateScript.getScriptContent());
if (CollectionUtils.isNotEmpty(fillCount)) allFillCountList.addAll(fillCount);
- fillCountAll += countFillRows(fillCount);
+ }
+
+ //璁板綍鍙戦�佹�讳汉鏁般�佸洖鏀舵�讳汉鏁�
+ Double subidAll = 0.0;
+ Double fillCountAll = 0.0;
+ for (Long templateId : categoryTemplateIds) {
+ subidAll += sendCountMap.getOrDefault(templateId, 0L);
+ fillCountAll += fillPersonCountMap.getOrDefault(templateId, 0L);
}
// 杩欓噷鍏堣褰曚竴涓嬫瘡涓垎绫荤殑鎬讳汉鏁板拰濉姤浜烘暟
@@ -375,31 +384,40 @@
//2 鍐嶈幏鍙栬闂婊℃剰搴﹀垎绫讳笅鐨処vrLibaTemplateScript鐨勯泦鍚�
List<SvyLibTemplateScript> svyLibTemplateScripts = svyLibTemplateScriptMapper.querySvyLibTemplateIds(mydIdList);
- //2.1 涓�娆℃�ф妸鏈璇锋眰鍏ㄩ儴妯℃澘鐨勫彂閫侀噺銆佸~鎶ラ噺鏌ュ洖鏉ワ紙鍘熸潵鏄瘡涓ā鏉块棶棰樺悇鏌ヤ袱娆★級
+ //2.1 涓�娆℃�ф妸鏈璇锋眰鍏ㄩ儴妯℃澘鐨勫彂閫侀噺銆佸洖鏀朵汉鏁版煡鍥炴潵锛堝師鏉ユ槸姣忎釜妯℃澘闂鍚勬煡涓ゆ锛�
SatisfactionStatQuery statQuery = buildSatisfactionStatQuery(patSatisfactionReqVO, "2",
svyLibTemplateScripts.stream().map(SvyLibTemplateScript::getSvyid).collect(Collectors.toList()));
Map<Long, Long> sendCountMap = mapSatisfactionSendCount(statQuery);
SatisfactionFillStat fillStat = querySatisfactionFillStat(statQuery);
+ Map<Long, Long> fillPersonCountMap = mapSatisfactionFillPersonCount(statQuery);
//3 鎸塻criptAssortname鍒嗙粍,骞惰幏鍙栨瘡涓泦鍚堣繘琛岄亶鍘嗭紝璁$畻姣忎釜鍒嗙被鐨勬�讳汉鏁板拰濉姤浜烘暟
Map<String, List<SvyLibTemplateScript>> scriptGroupByatCegoryName = svyLibTemplateScripts.stream().filter(item -> item.getCategoryName() != null).collect(Collectors.groupingBy(SvyLibTemplateScript::getCategoryName));
if (scriptGroupByatCegoryName != null && !scriptGroupByatCegoryName.isEmpty()) {
for (String categoryNameKey : scriptGroupByatCegoryName.keySet()) {
- //璁板綍鎬讳汉鏁�
- Double subidAll = 0.0;
- //璁板綍鎬荤殑濉姤浜烘暟
- Double fillCountAll = 0.0;
- //鑾峰彇璇ュ垎绫荤殑濉姤鎬绘暟閲�
+ // 璇ュ垎绫绘秹鍙婄殑鍘婚噸妯℃澘锛氬彂閫佷汉鏁�/鍥炴敹浜烘暟閮芥寜妯℃澘缁熻锛�
+ // 鎸夐鐩惊鐜疮鍔犱細鎶婂悓涓�涓ā鏉跨殑閲忛噸澶嶈鎴愩�岄閲忋��
+ Set<Long> categoryTemplateIds = new LinkedHashSet<>();
+ //鑾峰彇璇ュ垎绫荤殑濉姤鎬绘暟閲忥紙鍙敤浜庣畻骞冲潎鍒嗭紝鎸夐鐩仛鍚堢殑琛屾暟锛�
List<ScoreCount> allFillCountList = new ArrayList<>();
List<SvyLibTemplateScript> svyLibTemplateScriptList = scriptGroupByatCegoryName.get(categoryNameKey);
for (SvyLibTemplateScript svyLibTemplateScript : svyLibTemplateScriptList) {
- //閫氳繃妯℃澘id鍙栭棶棰樺彂閫佹�婚噺锛堝師鏉ユ槸鎶婂叏閮� sub_id 鏌ュ洖 Java 鍐嶅彇 size锛�
- subidAll += sendCountMap.getOrDefault(svyLibTemplateScript.getSvyid(), 0L);
- //鑾峰彇濉姤鏁伴噺锛堝師鏉ユ槸鎶婃槑缁嗚鍏ㄩ儴鏌ュ洖 Java 鍐嶅彇 size锛�
- List<ScoreCount> fillCount = fillStat.get(svyLibTemplateScript.getSvyid(), svyLibTemplateScript.getScriptContent());
+ Long templateId = svyLibTemplateScript.getSvyid();
+ if (templateId != null) {
+ categoryTemplateIds.add(templateId);
+ }
+ //鑾峰彇濉姤鍒嗗�煎垎甯冿紙鍙敤浜庡钩鍧囧垎锛�
+ List<ScoreCount> fillCount = fillStat.get(templateId, svyLibTemplateScript.getScriptContent());
if (CollectionUtils.isNotEmpty(fillCount)) allFillCountList.addAll(fillCount);
- fillCountAll += countFillRows(fillCount);
+ }
+
+ //璁板綍鍙戦�佹�讳汉鏁般�佸洖鏀舵�讳汉鏁�
+ Double subidAll = 0.0;
+ Double fillCountAll = 0.0;
+ for (Long templateId : categoryTemplateIds) {
+ subidAll += sendCountMap.getOrDefault(templateId, 0L);
+ fillCountAll += fillPersonCountMap.getOrDefault(templateId, 0L);
}
@@ -453,28 +471,36 @@
Map<String, List<IvrLibaTemplateScript>> groupByDimension = dimensionScripts.stream().collect(Collectors.groupingBy(IvrLibaTemplateScript::getDimension));
if (groupByDimension != null && !groupByDimension.isEmpty()) {
- //3.1 涓�娆℃�ф妸鏈璇锋眰鍏ㄩ儴妯℃澘鐨勫彂閫侀噺銆佸~鎶ラ噺鏌ュ洖鏉ワ紙鍘熸潵鏄瘡涓ā鏉块棶棰樺悇鏌ヤ袱娆★級
+ //3.1 涓�娆℃�ф妸鏈璇锋眰鍏ㄩ儴妯℃澘鐨勫彂閫侀噺銆佸洖鏀朵汉鏁版煡鍥炴潵锛堝師鏉ユ槸姣忎釜妯℃澘闂鍚勬煡涓ゆ锛�
SatisfactionStatQuery statQuery = buildSatisfactionStatQuery(patSatisfactionReqVO, "1",
dimensionScripts.stream().map(IvrLibaTemplateScript::getTemplateid).collect(Collectors.toList()));
Map<Long, Long> sendCountMap = mapSatisfactionSendCount(statQuery);
SatisfactionFillStat fillStat = querySatisfactionFillStat(statQuery);
+ Map<Long, Long> fillPersonCountMap = mapSatisfactionFillPersonCount(statQuery);
for (String dimension : groupByDimension.keySet()) {
- //璁板綍鎬讳汉鏁�
- Double subidAll = 0.0;
- //璁板綍鎬荤殑濉姤浜烘暟
- Double fillCountAll = 0.0;
- //鑾峰彇璇ョ淮搴︾殑濉姤鎬绘暟閲�
+ // 璇ョ淮搴︽秹鍙婄殑鍘婚噸妯℃澘锛氬彂閫佷汉鏁�/鍥炴敹浜烘暟閮芥寜妯℃澘缁熻锛屾寜棰樼洰绱姞浼氬彉鎴愰閲�
+ Set<Long> dimensionTemplateIds = new LinkedHashSet<>();
+ //鑾峰彇璇ョ淮搴︾殑濉姤鍒嗗�煎垎甯冿紙鍙敤浜庣畻骞冲潎鍒嗭級
List<ScoreCount> allFillCountList = new ArrayList<>();
List<IvrLibaTemplateScript> ivrLibaTemplateScriptList = groupByDimension.get(dimension);
for (IvrLibaTemplateScript ivrLibaTemplateScript : ivrLibaTemplateScriptList) {
- //閫氳繃妯℃澘id鍙栭棶棰樺彂閫佹�婚噺锛堝師鏉ユ槸鎶婂叏閮� sub_id 鏌ュ洖 Java 鍐嶅彇 size锛�
- subidAll += sendCountMap.getOrDefault(ivrLibaTemplateScript.getTemplateid(), 0L);
- //鑾峰彇濉姤鏁伴噺锛堝師鏉ユ槸鎶婃槑缁嗚鍏ㄩ儴鏌ュ洖 Java 鍐嶅彇 size锛�
- List<ScoreCount> fillCount = fillStat.get(ivrLibaTemplateScript.getTemplateid(), ivrLibaTemplateScript.getScriptContent());
+ Long templateId = ivrLibaTemplateScript.getTemplateid();
+ if (templateId != null) {
+ dimensionTemplateIds.add(templateId);
+ }
+ //鑾峰彇濉姤鍒嗗�煎垎甯冿紙鍙敤浜庡钩鍧囧垎锛�
+ List<ScoreCount> fillCount = fillStat.get(templateId, ivrLibaTemplateScript.getScriptContent());
if (CollectionUtils.isNotEmpty(fillCount)) allFillCountList.addAll(fillCount);
- fillCountAll += countFillRows(fillCount);
+ }
+
+ //璁板綍鍙戦�佹�讳汉鏁般�佸洖鏀舵�讳汉鏁�
+ Double subidAll = 0.0;
+ Double fillCountAll = 0.0;
+ for (Long templateId : dimensionTemplateIds) {
+ subidAll += sendCountMap.getOrDefault(templateId, 0L);
+ fillCountAll += fillPersonCountMap.getOrDefault(templateId, 0L);
}
// 杩欓噷鍏堣褰曚竴涓嬫瘡涓垎绫荤殑鎬讳汉鏁板拰濉姤浜烘暟
@@ -502,28 +528,36 @@
List<SvyLibTemplateScript> dimensionScripts = svyLibTemplateScripts.stream().filter(item -> item.getDimension() != null).collect(Collectors.toList());
Map<String, List<SvyLibTemplateScript>> groupByDimension = dimensionScripts.stream().collect(Collectors.groupingBy(SvyLibTemplateScript::getDimension));
if (groupByDimension != null && !groupByDimension.isEmpty()) {
- //3.1 涓�娆℃�ф妸鏈璇锋眰鍏ㄩ儴妯℃澘鐨勫彂閫侀噺銆佸~鎶ラ噺鏌ュ洖鏉ワ紙鍘熸潵鏄瘡涓ā鏉块棶棰樺悇鏌ヤ袱娆★級
+ //3.1 涓�娆℃�ф妸鏈璇锋眰鍏ㄩ儴妯℃澘鐨勫彂閫侀噺銆佸洖鏀朵汉鏁版煡鍥炴潵锛堝師鏉ユ槸姣忎釜妯℃澘闂鍚勬煡涓ゆ锛�
SatisfactionStatQuery statQuery = buildSatisfactionStatQuery(patSatisfactionReqVO, "2",
dimensionScripts.stream().map(SvyLibTemplateScript::getSvyid).collect(Collectors.toList()));
Map<Long, Long> sendCountMap = mapSatisfactionSendCount(statQuery);
SatisfactionFillStat fillStat = querySatisfactionFillStat(statQuery);
+ Map<Long, Long> fillPersonCountMap = mapSatisfactionFillPersonCount(statQuery);
for (String dimension : groupByDimension.keySet()) {
- //璁板綍鎬讳汉鏁�
- Double subidAll = 0.0;
- //璁板綍鎬荤殑濉姤浜烘暟
- Double fillCountAll = 0.0;
- //鑾峰彇璇ュ垎绫荤殑濉姤鎬绘暟閲�
+ // 璇ョ淮搴︽秹鍙婄殑鍘婚噸妯℃澘锛氬彂閫佷汉鏁�/鍥炴敹浜烘暟閮芥寜妯℃澘缁熻锛屾寜棰樼洰绱姞浼氬彉鎴愰閲�
+ Set<Long> dimensionTemplateIds = new LinkedHashSet<>();
+ //鑾峰彇璇ュ垎绫荤殑濉姤鍒嗗�煎垎甯冿紙鍙敤浜庣畻骞冲潎鍒嗭級
List<ScoreCount> allFillCountList = new ArrayList<>();
List<SvyLibTemplateScript> svyLibTemplateScriptList = groupByDimension.get(dimension);
for (SvyLibTemplateScript svyLibTemplateScript : svyLibTemplateScriptList) {
- //閫氳繃妯℃澘id鍙栭棶棰樺彂閫佹�婚噺锛堝師鏉ユ槸鎶婂叏閮� sub_id 鏌ュ洖 Java 鍐嶅彇 size锛�
- subidAll += sendCountMap.getOrDefault(svyLibTemplateScript.getSvyid(), 0L);
- //鑾峰彇濉姤鏁伴噺锛堝師鏉ユ槸鎶婃槑缁嗚鍏ㄩ儴鏌ュ洖 Java 鍐嶅彇 size锛�
- List<ScoreCount> fillCount = fillStat.get(svyLibTemplateScript.getSvyid(), svyLibTemplateScript.getScriptContent());
+ Long templateId = svyLibTemplateScript.getSvyid();
+ if (templateId != null) {
+ dimensionTemplateIds.add(templateId);
+ }
+ //鑾峰彇濉姤鍒嗗�煎垎甯冿紙鍙敤浜庡钩鍧囧垎锛�
+ List<ScoreCount> fillCount = fillStat.get(templateId, svyLibTemplateScript.getScriptContent());
if (CollectionUtils.isNotEmpty(fillCount)) allFillCountList.addAll(fillCount);
- fillCountAll += countFillRows(fillCount);
+ }
+
+ //璁板綍鍙戦�佹�讳汉鏁般�佸洖鏀舵�讳汉鏁�
+ Double subidAll = 0.0;
+ Double fillCountAll = 0.0;
+ for (Long templateId : dimensionTemplateIds) {
+ subidAll += sendCountMap.getOrDefault(templateId, 0L);
+ fillCountAll += fillPersonCountMap.getOrDefault(templateId, 0L);
}
@@ -644,6 +678,24 @@
}
/**
+ * 涓�娆℃煡鍑哄叏閮ㄦā鏉跨殑銆屽洖鏀朵汉鏁般�嶏紙鎸夋ā鏉垮幓閲嶏紝鍚屼竴涓汉绛斿閬撻鍙畻涓�浜猴級
+ *
+ * @return key=妯℃澘id锛寁alue=鍥炴敹浜烘暟
+ */
+ private Map<Long, Long> mapSatisfactionFillPersonCount(SatisfactionStatQuery statQuery) {
+ Map<Long, Long> fillPersonCountMap = new HashMap<>();
+ if (statQuery == null || CollectionUtils.isEmpty(statQuery.getLibTemplateIds())) return fillPersonCountMap;
+ List<Map<String, Object>> rows = serviceSubtaskDetailMapper.selectSatisfactionFillPersonCount(statQuery);
+ if (CollectionUtils.isEmpty(rows)) return fillPersonCountMap;
+ for (Map<String, Object> row : rows) {
+ Long templateId = toLong(row.get("libtemplateid"));
+ if (templateId == null) continue;
+ fillPersonCountMap.put(templateId, toLong(row.get("cnt"), 0L));
+ }
+ return fillPersonCountMap;
+ }
+
+ /**
* 涓�娆℃煡鍑哄叏閮ㄦā鏉跨殑濉姤閲忥紙鎸� 妯℃澘+闂+鍒嗗�� 鍒嗙粍锛�
*/
private SatisfactionFillStat querySatisfactionFillStat(SatisfactionStatQuery statQuery) {
@@ -662,18 +714,6 @@
fillStat.add(templateId, questiontextValue == null ? null : String.valueOf(questiontextValue), scoreCount);
}
return fillStat;
- }
-
- /**
- * 鍙栧~鎶ユ槑缁嗚鏁帮紙鍘� fillCount.size()锛�
- */
- private long countFillRows(List<ScoreCount> fillCount) {
- if (CollectionUtils.isEmpty(fillCount)) return 0L;
- long rows = 0L;
- for (ScoreCount scoreCount : fillCount) {
- rows += scoreCount.getCount();
- }
- return rows;
}
/**
diff --git a/smartor/src/main/java/com/smartor/service/impl/ServiceSLTDHealthcareRecordServiceImpl.java b/smartor/src/main/java/com/smartor/service/impl/ServiceSLTDHealthcareRecordServiceImpl.java
index d2d357c..258cbe8 100644
--- a/smartor/src/main/java/com/smartor/service/impl/ServiceSLTDHealthcareRecordServiceImpl.java
+++ b/smartor/src/main/java/com/smartor/service/impl/ServiceSLTDHealthcareRecordServiceImpl.java
@@ -93,6 +93,9 @@
@Autowired
private PatMedInhospMapper patMedInhospMapper;
+ @Autowired
+ private PatMedOuthospErrorMapper patMedOuthospErrorMapper;
+
@Override
public List<ServiceSLTDInhospResDTO> queryHealthcareRecordList(ServiceSLTDInhospReqVO reqVO) {
try {
@@ -503,7 +506,12 @@
log.info("銆恜arseResponseData銆戞垚鍔熻В鏋恉ataList:{}鏉″仴搴疯褰曟暟鎹�", dataList.size());
List<ServiceSLTDInhospResDTO> resultList = new ArrayList<>();
for (Map<String, Object> dataItem : dataList) {
- resultList.add(convertToDTO(dataItem));
+ try {
+ resultList.add(convertToDTO(dataItem));
+ } catch (Exception e) {
+ // 鍗曟潯鏁版嵁杞崲澶辫触涓嶅啀璁╂暣椤靛け璐ワ細鍐欓敊璇〃浜ょ粰浜哄伐澶勭悊锛屽叾浣欒褰曠収甯稿叆搴�
+ saveOuthospError(dataItem, "CONVERT", e.getMessage(), new Gson().toJson(dataItem), e);
+ }
}
log.info("銆恜arseResponseData銆戞垚鍔熻В鏋恟esultList:{}鏉″仴搴疯褰曟暟鎹�", resultList.size());
@@ -613,34 +621,184 @@
}
private Boolean outHospitalDate(List<ServiceSLTDInhospResDTO> resultList) {
- List<PatMedOuthosp> batchList = new ArrayList<>();
-
+ // 闂ㄦ�ヨ瘖鍦� HIS 渚у彧鑳芥寜澶╂煡锛岄噰闆嗕换鍔℃瘡鍗婂皬鏃堕兘浼氭妸褰撳ぉ涓婁竾涓瘖鐤楄褰曢噸鏂版媺涓�閬嶏紝
+ // 鍏朵腑缁濆ぇ澶氭暟涓婁竴杞凡缁忓叆搴撱�傝繖閲屽厛鏁撮〉鎵归噺鏌ラ噸锛屾妸宸插叆搴撶殑鐩存帴璺宠繃锛�
+ // 鍙鏂板璁板綍鍋�"妗f澶勭悊 + 鍏ュ簱"锛屽惁鍒欐瘡鏉¢噸澶嶆暟鎹兘瑕佽蛋涓�閬�
+ // Redis鍔犻攣 + 妗f鏌ラ噸 + 妗f鏇存柊 + countBySerialnum + insert锛屼竴涓囨潯灏辨槸鍑犱竾娆� SQL锛屽崐灏忔椂璺戜笉瀹屻��
+ Set<String> pageSerialnums = new HashSet<>();
+ List<ServiceSLTDInhospResDTO> uniqueList = new ArrayList<>();
+ List<ServiceSLTDInhospResDTO> noSerialnumList = new ArrayList<>();
+ Map<String, List<String>> serialnumsByDate = new LinkedHashMap<>();
for (ServiceSLTDInhospResDTO dto : resultList) {
if (Objects.isNull(dto)) {
continue;
}
- PatArchive patArchive = processPatientArchive(dto);
- PatMedOuthosp patMedOuthosp = buildPatMedOuthosp(dto, patArchive);
- batchList.add(patMedOuthosp);
+ String serialnum = dto.getHealthcareRecordNo();
+ if (StringUtils.isEmpty(serialnum)) {
+ // 娌℃湁璇婄枟璁板綍鍙峰氨娌℃硶鏌ラ噸锛屼繚鎸佸師鏈夎涓虹収甯稿鐞嗭紙鍏ュ簱鐜妭杩樹細鍐嶅厹涓�娆★級
+ log.warn("銆恛utHospitalDate銆戣瘖鐤楄褰曞彿涓虹┖锛屾棤娉曟煡閲嶏紝鎸夋柊澧炲鐞嗭細patientName={}", dto.getPatientName());
+ noSerialnumList.add(dto);
+ continue;
+ }
+ if (!pageSerialnums.add(serialnum)) {
+ // 鍚屼竴椤靛唴閲嶅鐨勮褰曪紝鍙鐞嗕竴鏉�
+ continue;
+ }
+ uniqueList.add(dto);
+ // 鎸夊氨璇婃棩鏈熷垎缁勶紙璺ㄩ浂鐐规椂鏈�澶氫袱涓棩鏈燂級锛屼繚璇佹煡閲嶇殑鍒嗚〃鍜屽叆搴撴椂鍒嗚〃璺敱涓�鑷�
+ String admitDateStr = formatAdmitDate(dto.getLastEncounterTime());
+ serialnumsByDate.computeIfAbsent(admitDateStr == null ? "" : admitDateStr, k -> new ArrayList<>()).add(serialnum);
}
+
+ // 涓�娆� SQL 鏌ュ嚭杩欎竴椤甸噷宸茬粡鍏ュ簱鐨� serialnum锛堝彇浠i�愭潯 countBySerialnum锛�
+ Set<String> existingSerialnums = new HashSet<>();
+ for (Map.Entry<String, List<String>> entry : serialnumsByDate.entrySet()) {
+ try {
+ existingSerialnums.addAll(patMedOuthospService.selectExistingSerialnums(entry.getKey(), entry.getValue()));
+ } catch (Exception e) {
+ // 鎵归噺鏌ラ噸澶辫触涓嶅奖鍝嶆纭�э細涓嬮潰鍏ュ簱鏃舵瘡鏉¤繕浼氬啀鏌ヤ竴娆¢噸锛屽彧鏄參涓�浜�
+ log.error("銆恛utHospitalDate銆戞壒閲忔煡閲嶅け璐ワ紝閫�鍖栦负閫愭潯鏌ラ噸锛屽氨璇婃棩鏈燂細{}", entry.getKey(), e);
+ }
+ }
+
+ List<PatMedOuthosp> batchList = new ArrayList<>();
+ int existSkipCount = 0;
+ for (ServiceSLTDInhospResDTO dto : uniqueList) {
+ if (existingSerialnums.contains(dto.getHealthcareRecordNo())) {
+ existSkipCount++;
+ continue;
+ }
+ PatMedOuthosp patMedOuthosp = buildNewOuthosp(dto);
+ if (patMedOuthosp != null) {
+ batchList.add(patMedOuthosp);
+ }
+ }
+ for (ServiceSLTDInhospResDTO dto : noSerialnumList) {
+ PatMedOuthosp patMedOuthosp = buildNewOuthosp(dto);
+ if (patMedOuthosp != null) {
+ batchList.add(patMedOuthosp);
+ }
+ }
+ log.info("銆恛utHospitalDate銆戞湰椤祘}鏉★紝鍘婚噸鍚巤}鏉★紝宸插叆搴撹烦杩噞}鏉★紝寰呭叆搴搟}鏉�",
+ resultList.size(), uniqueList.size(), existSkipCount, batchList.size());
// 鎵归噺鎻掑叆锛岃嚜鍔ㄥ拷鐣ラ噸澶�
if (CollectionUtils.isNotEmpty(batchList)) {
- try {
- //杩欓噷鐢ㄨ嚜鍔ㄥ拷鐣ラ噸澶嶄細鏈夐棶棰橈紝濡傛灉琛ㄩ噸鏂板缓锛宻erialnum绱㈠紩浼氫涪澶便�傚氨鏃犳硶鍘婚噸锛屾墍浠ヨ繕鏄渶瑕佸唴瀛橀噷鍘婚噸
- batchList = DistinctByProperty.distinctByProperty(batchList, PatMedOuthosp::getSerialnum);
- Integer insertCount = 0;
- for (PatMedOuthosp patMedOuthosp : batchList) {
- insertCount += patMedOuthospService.insertPatMedOuthosp(patMedOuthosp);
+ //杩欓噷鐢ㄨ嚜鍔ㄥ拷鐣ラ噸澶嶄細鏈夐棶棰橈紝濡傛灉琛ㄩ噸鏂板缓锛宻erialnum绱㈠紩浼氫涪澶便�傚氨鏃犳硶鍘婚噸锛屾墍浠ヨ繕鏄渶瑕佸唴瀛橀噷鍘婚噸
+ batchList = DistinctByProperty.distinctByProperty(batchList, PatMedOuthosp::getSerialnum);
+ int insertCount = 0;
+ int skipCount = 0;
+ List<String> failSerialnums = new ArrayList<>();
+ for (PatMedOuthosp patMedOuthosp : batchList) {
+ try {
+ int inserted = patMedOuthospService.insertPatMedOuthosp(patMedOuthosp);
+ if (inserted > 0) {
+ insertCount += inserted;
+ } else {
+ // 杩斿洖0琛ㄧず宸插瓨鍦紙閲嶅閲囬泦锛夋垨灏辫瘖鏃堕棿涓虹┖锛屽睘浜庢甯歌烦杩囷紝涓嶇畻澶辫触
+ skipCount++;
+ }
+ } catch (Exception e) {
+ // 鍗曟潯鍏ュ簱澶辫触涓嶅啀涓柇閲囬泦锛氳惤閿欒琛ㄤ氦缁欎汉宸ュ鐞嗭紝閲囬泦鏂偣鐓у父鎺ㄨ繘
+ failSerialnums.add(patMedOuthosp.getSerialnum());
+ saveOuthospError(null, patMedOuthosp, "INSERT", e.getMessage(), new Gson().toJson(patMedOuthosp), e);
}
+ }
+ log.info("鎵归噺鎻掑叆闂ㄦ�ヨ瘖璁板綍锛屾�绘暟锛歿}, 瀹為檯鎻掑叆锛歿}, 璺宠繃锛堝凡瀛樺湪/鏃犲氨璇婃椂闂达級锛歿}, 钀介敊璇〃锛歿}",
+ batchList.size(), insertCount, skipCount, failSerialnums.size());
- log.info("鎵归噺鎻掑叆闂ㄦ�ヨ瘖璁板綍锛屾�绘暟锛歿}, 瀹為檯鎻掑叆锛歿}", batchList.size(), insertCount);
-
- } catch (Exception e) {
- log.error("鎵归噺鎻掑叆闂ㄦ�ヨ瘖璁板綍澶辫触", e);
+ if (!failSerialnums.isEmpty()) {
+ // 澶辫触鏄庣粏宸查�愭潯鍐欒繘 pat_med_outhosp_error锛岃繖閲屽彧鎻愮ず锛屼笉鍐嶆姏寮傚父闃绘柇閲囬泦
+ log.error("闂ㄦ�ヨ瘖璁板綍鍏ュ簱澶辫触 {} 鏉★紝宸插啓鍏� pat_med_outhosp_error 绛変汉宸ュ鐞嗭紝serialnum锛歿}",
+ failSerialnums.size(), failSerialnums);
}
}
return true;
+ }
+
+ /**
+ * 澶勭悊鍗曟潯鏂板璁板綍鐨勬偅鑰呮。妗堝苟鏋勫缓闂ㄦ�ヨ瘖璁板綍锛�
+ * 澶辫触鏃跺啓閿欒琛ㄤ氦缁欎汉宸ュ鐞嗗苟杩斿洖 null锛屼笉褰卞搷鍚屼竴椤甸噷鍏朵粬璁板綍
+ */
+ private PatMedOuthosp buildNewOuthosp(ServiceSLTDInhospResDTO dto) {
+ try {
+ PatArchive patArchive = processPatientArchive(dto);
+ return buildPatMedOuthosp(dto, patArchive);
+ } catch (Exception e) {
+ saveOuthospError(dto, null, "ARCHIVE", e.getMessage(), new Gson().toJson(dto), e);
+ return null;
+ }
+ }
+
+ /** 閲囬泦澶辫触鐨勫師濮嬭褰曟潵鑷帴鍙h繑鍥炵殑 Map锛堟暟鎹浆鎹㈠け璐ユ椂杩樻病鏈� DTO锛� */
+ private void saveOuthospError(Map<String, Object> dataItem, String errorType, String errorMsg,
+ String rawData, Throwable cause) {
+ PatMedOuthospError error = new PatMedOuthospError();
+ error.setSerialnum(getStringValue(dataItem, "healthcareRecordNo"));
+ error.setOuthospno(getStringValue(dataItem, "healthcareRecordNo"));
+ error.setPatname(getStringValue(dataItem, "patientName"));
+ error.setPatno(getStringValue(dataItem, "medicalRecordNo"));
+ error.setCampusid(getStringValue(dataItem, "campusId"));
+ error.setOrgid(getStringValue(dataItem, "orgId"));
+ doSaveOuthospError(error, errorType, errorMsg, rawData, cause);
+ }
+
+ /** 閲囬泦澶辫触鐨勫師濮嬭褰曟潵鑷� DTO / 寰呭叆搴撶殑 PatMedOuthosp */
+ private void saveOuthospError(ServiceSLTDInhospResDTO dto, PatMedOuthosp patMedOuthosp, String errorType,
+ String errorMsg, String rawData, Throwable cause) {
+ PatMedOuthospError error = new PatMedOuthospError();
+ if (dto != null) {
+ error.setSerialnum(dto.getHealthcareRecordNo());
+ error.setOuthospno(dto.getHealthcareRecordNo());
+ error.setPatname(dto.getPatientName());
+ error.setPatno(dto.getMedicalRecordNo());
+ error.setCampusid(dto.getCampusId());
+ error.setOrgid(dto.getOrgId());
+ error.setAdmitdate(parseDate(dto.getLastEncounterTime()));
+ }
+ if (patMedOuthosp != null) {
+ if (StringUtils.isEmpty(error.getSerialnum())) {
+ error.setSerialnum(patMedOuthosp.getSerialnum());
+ }
+ error.setOuthospno(patMedOuthosp.getOuthospno());
+ error.setPatname(patMedOuthosp.getPatname());
+ error.setPatno(patMedOuthosp.getPatno());
+ error.setCampusid(patMedOuthosp.getCampusid());
+ error.setOrgid(patMedOuthosp.getOrgid());
+ error.setAdmitdate(patMedOuthosp.getAdmitdate());
+ }
+ doSaveOuthospError(error, errorType, errorMsg, rawData, cause);
+ }
+
+ /**
+ * 鍐欓棬鎬ヨ瘖閲囬泦澶辫触璁板綍琛紝浜ょ粰浜哄伐澶勭悊銆�
+ * 杩欓噷鍏滀綇涓�鍒囧紓甯革細杩為敊璇〃閮藉啓涓嶈繘鍘绘椂鍙墦鏃ュ織锛堝甫鍘熷鏁版嵁锛夛紝缁濅笉鍥犱负鍐欓敊璇〃澶辫触鑰屼腑鏂噰闆�
+ */
+ private void doSaveOuthospError(PatMedOuthospError error, String errorType, String errorMsg,
+ String rawData, Throwable cause) {
+ error.setErrorType(errorType);
+ error.setErrorMsg(truncate(errorMsg == null || errorMsg.isEmpty() ? String.valueOf(cause) : errorMsg, 1000));
+ error.setRawData(rawData);
+ error.setFailCount(1);
+ error.setHandleStatus("0");
+ error.setGatherDate(new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
+ error.setCreateTime(DateUtils.getNowDate());
+ try {
+ patMedOuthospErrorMapper.insertPatMedOuthospError(error);
+ log.error("銆愰棬鎬ヨ瘖閲囬泦銆憑} 澶辫触锛屽凡鍐欏叆 pat_med_outhosp_error 绛変汉宸ュ鐞嗭紝serialnum={}锛屾偅鑰�={}锛屽師鍥�={}",
+ errorType, error.getSerialnum(), error.getPatname(), error.getErrorMsg(), cause);
+ } catch (Exception ex) {
+ log.error("銆愰棬鎬ヨ瘖閲囬泦銆憑} 澶辫触锛屼笖鍐欏叆閿欒琛ㄤ篃澶辫触锛宻erialnum={}锛屽師濮嬫暟鎹細{}",
+ errorType, error.getSerialnum(), rawData, ex);
+ }
+ }
+
+ /** 鎴柇瓒呴暱鏂囨湰锛岄伩鍏嶈秴鍑洪敊璇〃瀛楁闀垮害瀵艰嚧钀借〃澶辫触 */
+ private String truncate(String text, int maxLength) {
+ if (text == null) {
+ return null;
+ }
+ return text.length() <= maxLength ? text : text.substring(0, maxLength);
}
private PatMedOuthosp buildPatMedOuthosp(ServiceSLTDInhospResDTO dto, PatArchive patArchive) {
@@ -681,6 +839,18 @@
}
}
+ /**
+ * 鍙栧氨璇婃棩鏈熺殑 yyyy-MM-dd 閮ㄥ垎锛屼笌 buildPatMedOuthosp 閲岀殑 admitdate 淇濇寔瀹屽叏涓�鑷寸殑瑙f瀽瑙勫垯锛�
+ * 淇濊瘉鎵归噺鏌ラ噸鐢ㄧ殑鍒嗚〃鍜屽叆搴撴椂璺敱鍒扮殑鍒嗚〃鏄悓涓�寮�
+ */
+ private String formatAdmitDate(String lastEncounterTime) {
+ Date admitDate = parseDate(lastEncounterTime);
+ if (admitDate == null) {
+ return null;
+ }
+ return new SimpleDateFormat("yyyy-MM-dd").format(admitDate);
+ }
+
private Boolean inHospitalDate(List<ServiceSLTDInhospResDTO> resultList, String cry) {
for (ServiceSLTDInhospResDTO dto : resultList) {
if (Objects.isNull(dto)) continue;
diff --git a/smartor/src/main/java/com/smartor/service/impl/ServiceSubtaskDetailTraceServiceImpl.java b/smartor/src/main/java/com/smartor/service/impl/ServiceSubtaskDetailTraceServiceImpl.java
index b19a590..985cbbb 100644
--- a/smartor/src/main/java/com/smartor/service/impl/ServiceSubtaskDetailTraceServiceImpl.java
+++ b/smartor/src/main/java/com/smartor/service/impl/ServiceSubtaskDetailTraceServiceImpl.java
@@ -80,78 +80,115 @@
@Override
public Map<String, Object> tracedeallist(DetailTraceDealVO detailTraceDealVO) {
- // 鍒嗛〉鏌ヨ
- List<ServiceSubtaskDetailTrace> tracedeallist = serviceSubtaskDetailTraceMapper.tracedeallist(detailTraceDealVO);
-
- // 鎸� questiontext 鍒嗙粍
- Map<String, List<ServiceSubtaskDetailTrace>> groupByQuestion = tracedeallist.stream().filter(t -> t.getQuestiontext() != null).collect(Collectors.groupingBy(ServiceSubtaskDetailTrace::getQuestiontext));
+ // 浼樺寲鍓嶏細鈶� 杩欐潯 SQL 娌℃湁 limit锛屾瘡娆¢兘鎶婃暣琛� trace锛堝惈 patdesc/recordurl 澶у瓧娈碉級鎷夊洖 Java 鍐嶅垎缁勶紱
+ // 鈶� 姣忎釜闂閮芥嬁 scriptid 鍘� service_subtask_detail 鏌ヤ竴娆″叏琛ㄥ彧涓哄彇 size锛圢+1锛夛紱
+ // 鈶� controller 鎶婅繖涓柟娉曡皟浜嗕袱閬嶏紙绗簩閬嶄负浜嗘�绘暟锛夛紝绛変簬涓婇潰涓ゆ鍚勮窇涓ゆ銆�
+ // 浼樺寲鍚庯細鍥哄畾鐨� 5 鏉¤仛鍚� SQL锛孌B 鍙鐞嗗綋鍓嶉〉鐨勯鐩��
+ // 1) 褰撳墠椤电殑闂鍒嗙粍鑱氬悎锛堝垎椤典笅鎺ㄥ埌 SQL锛�
+ List<Map<String, Object>> groupRows = serviceSubtaskDetailTraceMapper.selectTraceDealGroups(detailTraceDealVO);
+ // 2) 闂鎬绘暟锛堝垎椤� total锛屽叏閲忓彛寰勶級
+ long questionTotal = serviceSubtaskDetailTraceMapper.countTraceDealQuestions(detailTraceDealVO);
+ // 3) 姹囨�荤粺璁★紙鍏ㄩ噺鍙e緞锛屼笉鍙楀垎椤靛奖鍝嶏級
+ Map<String, Object> sumRow = serviceSubtaskDetailTraceMapper.sumTraceDeal(detailTraceDealVO);
+ long totalException = toLong(sumRow == null ? null : sumRow.get("totalException"), 0L);
+ long yesDealException = toLong(sumRow == null ? null : sumRow.get("yesDeal"), 0L);
+ long noDealException = totalException - yesDealException;
List<DetailTraceDealDTO> detailTraceDealDTOList = new ArrayList<>();
- long totalException = 0L;
- long noDealException = 0L;
- long yesDealException = 0L;
+ if (CollectionUtils.isNotEmpty(groupRows)) {
+ // 鏈〉娑夊強鐨勯棶棰樻枃鏈紝鍚庨潰 3 鏉℃煡璇㈤兘鎸夊畠杩囨护
+ List<String> questiontexts = groupRows.stream()
+ .map(row -> row.get("questiontext"))
+ .filter(Objects::nonNull)
+ .map(String::valueOf)
+ .distinct()
+ .collect(Collectors.toList());
- for (Map.Entry<String, List<ServiceSubtaskDetailTrace>> entry : groupByQuestion.entrySet()) {
- List<ServiceSubtaskDetailTrace> group = entry.getValue();
- DetailTraceDealDTO dto = new DetailTraceDealDTO();
+ // 4) 鏈〉闂鐨勮礋璐g瀹わ紙鎸夌瀹ょ紪鍙峰幓閲嶏級
+ Map<String, List<Map<String, Object>>> deptMap = new HashMap<>();
+ // 5) 鏈〉闂鐨勬渶鏂板鐞嗕汉/澶勭悊鏃堕棿
+ Map<String, Map<String, Object>> latestHandleMap = new HashMap<>();
+ if (CollectionUtils.isNotEmpty(questiontexts)) {
+ for (Map<String, Object> row : serviceSubtaskDetailTraceMapper.selectTraceDealDepts(detailTraceDealVO, questiontexts)) {
+ String questiontext = row.get("questiontext") == null ? null : String.valueOf(row.get("questiontext"));
+ if (questiontext == null) continue;
+ Map<String, Object> deptMapItem = new HashMap<>();
+ deptMapItem.put("deptName", row.get("deptName"));
+ deptMapItem.put("deptCode", row.get("deptCode"));
+ deptMap.computeIfAbsent(questiontext, key -> new ArrayList<>()).add(deptMapItem);
+ }
- // 闂鍐呭
- dto.setQuestiontext(entry.getKey());
- if (CollectionUtils.isNotEmpty(group)) {
- dto.setScriptid(group.get(0).getScriptid());
- dto.setTemplateType(group.get(0).getTemplateType());
- }
- // 璐熻矗绉戝锛堝幓閲嶏級
- List<Map<String, Object>> responsibleDept = group.stream().filter(t -> t.getTodeptcode() != null).collect(Collectors.collectingAndThen(Collectors.toMap(ServiceSubtaskDetailTrace::getTodeptcode, t -> {
- Map<String, Object> deptMap = new HashMap<>();
- deptMap.put("deptName", t.getTodeptname());
- deptMap.put("deptCode", t.getTodeptcode());
- return deptMap;
- }, (existing, replacement) -> existing), map -> new ArrayList<>(map.values())));
- dto.setResponsibleDept(responsibleDept);
-
- // 鏈夋晥濉啓鏁帮細閫氳繃缁勫唴鐨� scriptid 鍘� service_subtask_detail 琛ㄦ煡璇�
- List<Long> scriptIds = group.stream().map(ServiceSubtaskDetailTrace::getScriptid).filter(Objects::nonNull).distinct().collect(Collectors.toList());
- long effectiveFillNum = 0L;
- if (CollectionUtils.isNotEmpty(scriptIds)) {
- ServiceSubtaskDetail query = new ServiceSubtaskDetail();
- query.setDelFlag("0");
- for (Long scriptId : scriptIds) {
- query.setScriptid(scriptId);
- List<ServiceSubtaskDetail> details = serviceSubtaskDetailMapper.selectServiceSubtaskDetailList(query);
- effectiveFillNum += CollectionUtils.isEmpty(details) ? 0 : details.size();
+ for (Map<String, Object> row : serviceSubtaskDetailTraceMapper.selectTraceDealLatestHandle(detailTraceDealVO, questiontexts)) {
+ String questiontext = row.get("questiontext") == null ? null : String.valueOf(row.get("questiontext"));
+ if (questiontext == null) continue;
+ // 鍚屼竴涓渶澶у鐞嗘椂闂村彲鑳芥湁澶氭潯锛屼繚鐣欑涓�鏉″嵆鍙紙鍘熷疄鐜板彇缁勫唴 handle_time 鏈�澶х殑閭f潯锛�
+ latestHandleMap.putIfAbsent(questiontext, row);
}
}
- // 寮傚父濉啓鏁� = 褰撳墠鍒嗙粍鐨� List 鏁伴噺
- long exceptionFillNum = group.size();
+ // 6) 鏈〉闂鐨勬湁鏁堝~鍐欐暟锛氫竴娆� group by 鏌ュ洖锛屾浛浠i�愪釜 scriptid 鏌ヨ
+ // 涓�涓棶棰樺彲鑳藉搴斿涓� scriptid锛屾墍浠ュ厛鎶� questiontext -> scriptid 鍒楄〃瑙e紑锛�
+ // 鍐嶆妸璇ラ棶棰樻墍鏈� scriptid 鐨勫~鍐欐暟鐩稿姞锛堜笌鍘熷疄鐜� for 寰幆绱姞鐨勫彛寰勪竴鑷达級
+ Map<String, List<Long>> questionScriptIds = new LinkedHashMap<>();
+ Set<Long> scriptIdSet = new LinkedHashSet<>();
+ for (Map<String, Object> row : groupRows) {
+ String questiontext = row.get("questiontext") == null ? null : String.valueOf(row.get("questiontext"));
+ if (questiontext == null) continue;
+ List<Long> ids = parseScriptIds(row.get("scriptids"));
+ questionScriptIds.put(questiontext, ids);
+ scriptIdSet.addAll(ids);
+ }
+ Map<Long, Long> effectiveFillMap = new HashMap<>();
+ if (CollectionUtils.isNotEmpty(scriptIdSet)) {
+ for (Map<String, Object> row : serviceSubtaskDetailMapper.countDetailByScriptIds(new ArrayList<>(scriptIdSet))) {
+ Long scriptId = toLongObj(row.get("scriptid"));
+ if (scriptId == null) continue;
+ effectiveFillMap.put(scriptId, toLong(row.get("cnt"), 0L));
+ }
+ }
- Map<String, Object> fillSituation = new HashMap<>();
- fillSituation.put("effectiveFillNum", effectiveFillNum);
- fillSituation.put("exceptionFillNum", exceptionFillNum);
- dto.setFillSituation(fillSituation);
+ // 7) 缁勮杩斿洖缁撴瀯锛堥『搴� = SQL 鐨� order by questiontext锛屼繚璇佸垎椤电ǔ瀹氾級
+ for (Map<String, Object> row : groupRows) {
+ String questiontext = row.get("questiontext") == null ? null : String.valueOf(row.get("questiontext"));
+ if (questiontext == null) continue;
- // 寮傚父闂澶勭悊鏁伴噺锛氫粠 handleFlag 缁熻
- long yesDeal = group.stream().filter(t -> "1".equals(t.getHandleFlag())).count();
- long noDeal = group.stream().filter(t -> !"1".equals(t.getHandleFlag())).count();
- Map<String, Object> exceptionQuesNum = new HashMap<>();
- exceptionQuesNum.put("yesDeal", yesDeal);
- exceptionQuesNum.put("noDeal", noDeal);
- exceptionQuesNum.put("all", exceptionFillNum);
- dto.setExceptionQuesNum(exceptionQuesNum);
+ DetailTraceDealDTO dto = new DetailTraceDealDTO();
+ dto.setQuestiontext(questiontext);
+ Long scriptId = toLongObj(row.get("scriptid"));
+ dto.setScriptid(scriptId);
+ dto.setScriptids(parseScriptIds(row.get("scriptids")));
+ Object templateType = row.get("templateType");
+ dto.setTemplateType(templateType == null ? null : Integer.valueOf(String.valueOf(templateType)));
+ dto.setResponsibleDept(deptMap.getOrDefault(questiontext, new ArrayList<>()));
- // 姹囨�荤粺璁$疮鍔�
- totalException += exceptionFillNum;
- noDealException += noDeal;
- yesDealException += yesDeal;
+ long exceptionFillNum = toLong(row.get("exceptionFillNum"), 0L);
+ // 璇ラ棶棰樹笅鎵�鏈� scriptid 鐨勬湁鏁堝~鍐欐暟涔嬪拰锛堜竴涓� questiontext 鍙兘瀵瑰簲澶氫釜 scriptid锛�
+ long effectiveFillNum = 0L;
+ for (Long sid : questionScriptIds.getOrDefault(questiontext, new ArrayList<>())) {
+ effectiveFillNum += effectiveFillMap.getOrDefault(sid, 0L);
+ }
+ Map<String, Object> fillSituation = new HashMap<>();
+ fillSituation.put("effectiveFillNum", effectiveFillNum);
+ fillSituation.put("exceptionFillNum", exceptionFillNum);
+ dto.setFillSituation(fillSituation);
- // 鏈�鏂板鐞嗕汉鍜屽鐞嗘椂闂达紙鍙� handleTime 鏈�鏂扮殑涓�鏉★級
- group.stream().filter(t -> t.getHandleTime() != null).max(Comparator.comparing(ServiceSubtaskDetailTrace::getHandleTime)).ifPresent(latest -> {
- dto.setHandleBy(latest.getHandleBy());
- dto.setHandleTime(latest.getHandleTime());
- });
+ long yesDeal = toLong(row.get("yesDeal"), 0L);
+ long noDeal = toLong(row.get("noDeal"), 0L);
+ Map<String, Object> exceptionQuesNum = new HashMap<>();
+ exceptionQuesNum.put("yesDeal", yesDeal);
+ exceptionQuesNum.put("noDeal", noDeal);
+ exceptionQuesNum.put("all", exceptionFillNum);
+ dto.setExceptionQuesNum(exceptionQuesNum);
- detailTraceDealDTOList.add(dto);
+ Map<String, Object> latestHandle = latestHandleMap.get(questiontext);
+ if (latestHandle != null) {
+ dto.setHandleBy(latestHandle.get("handleBy") == null ? null : String.valueOf(latestHandle.get("handleBy")));
+ Object handleTime = latestHandle.get("handleTime");
+ dto.setHandleTime(handleTime instanceof Date ? (Date) handleTime : null);
+ }
+
+ detailTraceDealDTOList.add(dto);
+ }
}
Map<String, Object> result = new HashMap<>();
@@ -159,9 +196,38 @@
result.put("totalException", totalException);
result.put("noDealException", noDealException);
result.put("yesDealException", yesDealException);
+ // 鍒嗛〉鎬绘暟锛堟寜闂缁村害锛夛紝controller 鐩存帴鐢ㄥ畠锛屼笉鐢ㄥ啀鍏ㄩ噺鏌ヤ竴閬�
+ result.put("questionTotal", questionTotal);
return result;
}
+ private static Long toLongObj(Object value) {
+ if (value == null) return null;
+ if (value instanceof Number) return ((Number) value).longValue();
+ String text = String.valueOf(value).trim();
+ return text.isEmpty() ? null : Long.valueOf(text);
+ }
+
+ private static long toLong(Object value, long defaultValue) {
+ Long result = toLongObj(value);
+ return result == null ? defaultValue : result;
+ }
+
+ /**
+ * 瑙f瀽 group_concat(distinct scriptid) 鐨勭粨鏋滐紙濡� "101,102"锛変负 scriptid 鍒楄〃
+ */
+ private static List<Long> parseScriptIds(Object value) {
+ List<Long> scriptIds = new ArrayList<>();
+ if (value == null) return scriptIds;
+ for (String item : String.valueOf(value).split(",")) {
+ Long scriptId = toLongObj(item);
+ if (scriptId != null && !scriptIds.contains(scriptId)) {
+ scriptIds.add(scriptId);
+ }
+ }
+ return scriptIds;
+ }
+
/**
* 鏂板闅忚浠诲姟寮傚父璁板綍璺熻釜
*
diff --git a/smartor/src/main/resources/mapper/smartor/PatMedOuthospMapper.xml b/smartor/src/main/resources/mapper/smartor/PatMedOuthospMapper.xml
index b53811c..ef8ecf9 100644
--- a/smartor/src/main/resources/mapper/smartor/PatMedOuthospMapper.xml
+++ b/smartor/src/main/resources/mapper/smartor/PatMedOuthospMapper.xml
@@ -454,6 +454,16 @@
WHERE serialnum = #{serialnum}
</select>
+ <!-- 鎵归噺鏌ヨ鎸囧畾鍒嗚〃涓凡瀛樺湪鐨� serialnum锛屼竴娆� SQL 瀹屾垚鏁撮〉鍘婚噸锛岄伩鍏嶉�愭潯 countBySerialnum -->
+ <select id="selectExistingSerialnums" resultType="java.lang.String">
+ SELECT serialnum
+ FROM ${tableName}
+ WHERE serialnum IN
+ <foreach collection="serialnums" item="serialnum" open="(" separator="," close=")">
+ #{serialnum}
+ </foreach>
+ </select>
+
<update id="updateInTable" parameterType="map">
update ${tableName}
<trim prefix="SET" suffixOverrides=",">
diff --git a/smartor/src/main/resources/mapper/smartor/ServiceSubtaskDetailMapper.xml b/smartor/src/main/resources/mapper/smartor/ServiceSubtaskDetailMapper.xml
index fe90a21..945af85 100644
--- a/smartor/src/main/resources/mapper/smartor/ServiceSubtaskDetailMapper.xml
+++ b/smartor/src/main/resources/mapper/smartor/ServiceSubtaskDetailMapper.xml
@@ -185,6 +185,24 @@
</select>
+ <!--
+ 寮傚父闂澶勭悊鎯呭喌鏌ヨ锛坱racedeallist锛夌殑銆屾湁鏁堝~鍐欐暟銆嶏細
+ 鍘熸潵瀵规瘡涓� scriptid 閮芥墽琛屼竴娆� selectServiceSubtaskDetailList锛堟煡鍥炲叏閮ㄥ垪鍐嶅幓 size锛夛紝
+ 涓�涓棶棰樹竴娆°�佽�屼笖鏁翠釜鎺ュ彛浼氳璋冪敤涓ら亶锛屽嚑鍗佷笂鐧句釜闂灏辨槸涓婄櫨娆″ぇ琛ㄦ壂鎻忥紱
+ 杩欓噷鍚堝苟鎴愪竴鏉� group by銆�
+ 娉ㄦ剰锛氫负涓庡師鍙e緞瀹屽叏涓�鑷达紝杩欓噷涓嶅姞 del_flag 鏉′欢锛堝師 selectServiceSubtaskDetailList
+ 铏界劧 Java 閲� setDelFlag("0")锛屼絾 SQL 閲屽苟娌℃湁 del_flag 杩囨护锛夈��
+ -->
+ <select id="countDetailByScriptIds" resultType="java.util.Map">
+ select scriptid as scriptid, count(*) as cnt
+ from service_subtask_detail
+ where scriptid in
+ <foreach collection="scriptIds" item="scriptId" open="(" separator="," close=")">
+ #{scriptId}
+ </foreach>
+ group by scriptid
+ </select>
+
<select id="getServiceSubtaskDetails" parameterType="com.smartor.domain.ServiceSubtaskDetailVO"
resultType="java.util.HashMap">
select
@@ -327,6 +345,57 @@
group by ss.libtemplateid, ssd.questiontext, ssd.score
</select>
+ <select id="selectSatisfactionFillPersonCount" parameterType="com.smartor.domain.entity.SatisfactionStatQuery"
+ resultType="java.util.Map">
+ select ss.libtemplateid as libtemplateid,
+ count(distinct ssd.sub_id) as cnt
+ from service_subtask_detail ssd
+ join service_subtask ss on ss.id = ssd.sub_id
+ where ssd.del_flag = 0
+ and ss.del_flag = 0
+ <if test="orgid != null and orgid != ''">
+ and ss.orgid = #{orgid}
+ </if>
+ <if test="campusid != null and campusid != ''">
+ and ss.campusid = #{campusid}
+ </if>
+ <if test="type != null and type != ''">and ss.type = #{type}</if>
+ <if test="startTime != null">
+ and ss.visit_time >= #{startTime}
+ </if>
+ <if test="endTime != null">
+ and ss.visit_time < date_add(#{endTime}, interval 1 day)
+ </if>
+ <if test="libTemplateIds != null and libTemplateIds.size() > 0">
+ and ss.libtemplateid IN
+ <foreach collection="libTemplateIds" item="libTemplateId" open="(" separator="," close=")">
+ #{libTemplateId}
+ </foreach>
+ </if>
+ <if test="(hospitaldistrictcodes != null and hospitaldistrictcodes.size() > 0) or (deptcodes != null and deptcodes.size() > 0)">
+ AND (
+ <if test="hospitaldistrictcodes != null and hospitaldistrictcodes.size() > 0">
+ ss.leavehospitaldistrictcode IN
+ <foreach collection="hospitaldistrictcodes" item="hospitaldistrictcode" open="("
+ separator=","
+ close=")">
+ #{hospitaldistrictcode}
+ </foreach>
+ </if>
+ <if test="hospitaldistrictcodes != null and hospitaldistrictcodes.size() > 0 and deptcodes != null and deptcodes.size() > 0">
+ OR
+ </if>
+ <if test="deptcodes != null and deptcodes.size() > 0">
+ ss.deptcode IN
+ <foreach collection="deptcodes" item="deptcode" open="(" separator="," close=")">
+ #{deptcode}
+ </foreach>
+ </if>
+ )
+ </if>
+ group by ss.libtemplateid
+ </select>
+
<!--
婊℃剰搴︾粺璁★紙statistics / statisticsByDimension锛夛細涓�娆℃�х粺璁℃湰娆¤姹傚叏閮ㄩ棶棰樼殑濉姤閲忋��
绛変环浜庡姣忎釜闂鎵ц queryFillCount(subids, questiontext)锛屽尯鍒槸锛�
diff --git a/smartor/src/main/resources/mapper/smartor/ServiceSubtaskDetailTraceMapper.xml b/smartor/src/main/resources/mapper/smartor/ServiceSubtaskDetailTraceMapper.xml
index 79943e7..1bc14e8 100644
--- a/smartor/src/main/resources/mapper/smartor/ServiceSubtaskDetailTraceMapper.xml
+++ b/smartor/src/main/resources/mapper/smartor/ServiceSubtaskDetailTraceMapper.xml
@@ -326,79 +326,163 @@
<if test="pageSize != null and pageNum != null">limit ${pageSize} OFFSET ${pageNum}</if>
</select>
- <select id="tracedeallist" parameterType="com.smartor.domain.VO.DetailTraceDealVO"
- resultMap="ServiceSubtaskDetailTtraceResult">
- <include refid="selectServiceSubtaskDetailTtraceVo"/>
- where del_flag=0
+ <!--
+ 寮傚父闂澶勭悊鎯呭喌鏌ヨ锛坱racedeallist锛夌殑鍏叡杩囨护鏉′欢銆�
+ 涓嬮潰 5 鏉� SQL 鍏辩敤鏈墖娈碉紝淇濊瘉銆屽垎椤垫暟鎹�侀棶棰樻�绘暟銆佸叏閲忔眹鎬汇�嶇殑鍙e緞瀹屽叏涓�鑷淬��
+ 娉ㄦ剰锛歲uestiontext 涓虹┖鐨勮鍘熷疄鐜伴噷琚� stream().filter(questiontext != null) 涓㈡帀浜嗭紝
+ 鎵�浠ヨ繖閲岀粺涓�鎺掗櫎锛屾眹鎬绘暟鎵嶅拰鍘熸潵涓�鑷淬��
+ -->
+ <sql id="traceDealWhere">
+ and del_flag = 0
+ and questiontext is not null
+ <if test="vo.templateid != null and vo.templateid != ''">
+ and templateid = #{vo.templateid}
+ </if>
+ <if test="vo.todeptcode != null and vo.todeptcode != ''">
+ and FIND_IN_SET(#{vo.todeptcode}, todeptcode)
+ </if>
+ <if test="vo.todeptname != null and vo.todeptname != ''">
+ and todeptname like concat('%', #{vo.todeptname}, '%')
+ </if>
+ <if test="vo.handleStartTime != null and vo.handleEndTime != null">
+ and handle_time between #{vo.handleStartTime} and #{vo.handleEndTime}
+ </if>
+ <if test="vo.orgid != null and vo.orgid != ''">
+ and orgid = #{vo.orgid}
+ </if>
+ <if test="vo.type != null and vo.type != ''">
+ and type = #{vo.type}
+ </if>
+ <if test="vo.templateType != null">
+ and template_type = #{vo.templateType}
+ </if>
+ <if test="vo.isMydException != null ">
+ and is_myd_exception = #{vo.isMydException}
+ </if>
+ <if test="vo.dimension != null and vo.dimension != ''">
+ and dimension = #{vo.dimension}
+ </if>
+ <if test="vo.dutyDeptPersonName != null and vo.dutyDeptPersonName != ''">
+ and duty_dept_person_name like concat('%', #{vo.dutyDeptPersonName}, '%')
+ </if>
+ <if test="vo.dutyDeptPersonCode != null and vo.dutyDeptPersonCode != ''">
+ and duty_dept_person_code like concat('%', #{vo.dutyDeptPersonCode}, '%')
+ </if>
+ <if test="vo.reportDeptPersonName != null and vo.reportDeptPersonName != ''">
+ and report_dept_person_name like concat('%', #{vo.reportDeptPersonName}, '%')
+ </if>
+ <if test="vo.reportDeptPersonCode != null and vo.reportDeptPersonCode != ''">
+ and report_dept_person_code like concat('%', #{vo.reportDeptPersonCode}, '%')
+ </if>
+ <if test="vo.circulationDeptPersonCode != null and vo.circulationDeptPersonCode != ''">
+ and circulation_dept_person_code like concat('%', #{vo.circulationDeptPersonCode}, '%')
+ </if>
+ <if test="vo.circulationDeptPersonName != null and vo.circulationDeptPersonName != ''">
+ and circulation_dept_person_name like concat('%', #{vo.circulationDeptPersonName}, '%')
+ </if>
+ <if test="vo.circulationDeptCode != null and vo.circulationDeptCode != ''">
+ and circulation_dept_code like concat('%', #{vo.circulationDeptCode}, '%')
+ </if>
+ <if test="vo.circulationDeptName != null and vo.circulationDeptName != ''">
+ and circulation_dept_name like concat('%', #{vo.circulationDeptName}, '%')
+ </if>
+ <if test="vo.circulationExplain != null and vo.circulationExplain != ''">
+ and circulation_explain like concat('%', #{vo.circulationExplain}, '%')
+ </if>
+ <if test="vo.circulationTime != null ">
+ and circulation_time = #{vo.circulationTime}
+ </if>
+ <if test="vo.circulationStatus != null ">
+ and circulation_status = #{vo.circulationStatus}
+ </if>
+ <if test="vo.circulationPersonName != null and vo.circulationPersonName != ''">
+ and circulation_person_name like concat('%', #{vo.circulationPersonName}, '%')
+ </if>
+ <if test="vo.circulationPersonCode != null and vo.circulationPersonCode != ''">
+ and circulation_person_code = #{vo.circulationPersonCode}
+ </if>
+ </sql>
- <if test="templateid != null and templateid != ''">
- and templateid = #{templateid}
- </if>
- <if test="todeptcode != null and todeptcode != ''">
- and FIND_IN_SET(#{todeptcode}, todeptcode)
- </if>
- <if test="todeptname != null and todeptname != ''">
- and todeptname like concat('%', #{todeptname}, '%')
- </if>
- <if test="handleStartTime != null and handleEndTime != null">
- and handle_time between #{handleStartTime} and #{handleEndTime}
- </if>
+ <!--
+ 褰撳墠椤电殑闂鍒嗙粍鑱氬悎锛氬垎椤垫寜闂缁村害涓嬫帹鍒� SQL銆�
+ 鍘熸潵鏄妸 service_subtask_detail_trace 鍏ㄨ〃锛堝惈 patdesc/recordurl 绛夊ぇ瀛楁锛夋媺鍥� Java 鍐嶅垎缁勶紝
+ pageSize 瀹屽叏娌$敓鏁堬紱鐜板湪 DB 鍙鐞嗗綋鍓嶉〉鐨勯鐩��
- <if test="orgid != null and orgid != ''">
- and orgid = #{orgid}
+ 娉ㄦ剰鍒嗙粍缁村害蹇呴』鏄� questiontext锛堟帴鍙f枃妗g害瀹氥�屾瘡涓棶棰樺搴斾竴鏉¤褰曘�嶏級锛�
+ 涓�涓� questiontext 鍙兘瀵瑰簲澶氫釜 scriptid锛岃繖鏃惰鎶婅闂鎵�鏈� scriptid 鐨勬湁鏁堝~鍐欐暟鍔犺捣鏉ワ紝
+ 鎵�浠ヨ繖閲岀敤 group_concat(distinct scriptid) 鎶� scriptid 鍒楄〃甯﹀洖 Java锛坰criptid 鍙栨渶灏忓�肩敤浜庡睍绀猴級銆�
+ 濡傛灉鏀规垚 group by questiontext, scriptid锛屽悓涓�涓棶棰樹細鎷嗘垚澶氳锛�
+ 涓� countTraceDealQuestions锛堟寜 questiontext 鍘婚噸锛夈�乼otal銆佽礋璐g瀹ゃ�佹渶鏂板鐞嗕汉鐨勫彛寰勯兘浼氫笉涓�鑷淬��
+ -->
+ <select id="selectTraceDealGroups" resultType="java.util.Map">
+ select questiontext as questiontext,
+ min(scriptid) as scriptid,
+ group_concat(distinct scriptid) as scriptids,
+ min(template_type) as templateType,
+ count(*) as exceptionFillNum,
+ sum(case when handle_flag = '1' then 1 else 0 end) as yesDeal,
+ sum(case when handle_flag = '1' then 0 else 1 end) as noDeal
+ from service_subtask_detail_trace
+ where 1 = 1
+ <include refid="traceDealWhere"/>
+ group by questiontext
+ order by questiontext
+ <if test="vo.pageSize != null and vo.pageNum != null">
+ limit ${vo.pageSize} offset ${vo.pageNum}
</if>
+ </select>
- <if test="type != null and type != ''">
- and type = #{type}
- </if>
- <if test="templateType != null">
- and template_type = #{templateType}
- </if>
- <if test="isMydException != null ">
- and is_myd_exception = #{isMydException}
- </if>
- <if test="dimension != null and dimension != ''">
- and dimension = #{dimension}
- </if>
- <if test="dutyDeptPersonName != null and dutyDeptPersonName != ''">
- and duty_dept_person_name like concat('%', #{dutyDeptPersonName}, '%')
- </if>
- <if test="dutyDeptPersonCode != null and dutyDeptPersonCode != ''">
- and duty_dept_person_code like concat('%', #{dutyDeptPersonCode}, '%')
- </if>
- <if test="reportDeptPersonName != null and reportDeptPersonName != ''">
- and report_dept_person_name like concat('%', #{reportDeptPersonName}, '%')
- </if>
- <if test="reportDeptPersonCode != null and reportDeptPersonCode != ''">
- and report_dept_person_code like concat('%', #{reportDeptPersonCode}, '%')
- </if>
- <if test="circulationDeptPersonCode != null and circulationDeptPersonCode != ''">
- and circulation_dept_person_code like concat('%', #{circulationDeptPersonCode}, '%')
- </if>
- <if test="circulationDeptPersonName != null and circulationDeptPersonName != ''">
- and circulation_dept_person_name like concat('%', #{circulationDeptPersonName}, '%')
- </if>
- <if test="circulationDeptCode != null and circulationDeptCode != ''">
- and circulation_dept_code like concat('%', #{circulationDeptCode}, '%')
- </if>
- <if test="circulationDeptName != null and circulationDeptName != ''">
- and circulation_dept_name like concat('%', #{circulationDeptName}, '%')
- </if>
- <if test="circulationExplain != null and circulationExplain != ''">
- and circulation_explain like concat('%', #{circulationExplain}, '%')
- </if>
- <if test="circulationTime != null ">
- and circulation_time = #{circulationTime}
- </if>
- <if test="circulationStatus != null ">
- and circulation_status = #{circulationStatus}
- </if>
- <if test="circulationPersonName != null and circulationPersonName != ''">
- and circulation_person_name like concat('%', #{circulationPersonName}, '%')
- </if>
- <if test="circulationPersonCode != null and circulationPersonCode != ''">
- and circulation_person_code =#{circulationPersonCode}
- </if>
+ <!-- 闂鎬绘暟锛堝垎椤� total锛屾寜闂缁村害锛� -->
+ <select id="countTraceDealQuestions" resultType="long">
+ select count(distinct questiontext)
+ from service_subtask_detail_trace
+ where 1 = 1
+ <include refid="traceDealWhere"/>
+ </select>
+
+ <!-- 鍏ㄩ噺姹囨�伙紙涓嶅彈鍒嗛〉褰卞搷锛夛細鎬绘暟 + 宸插鐞嗘暟锛屾湭澶勭悊鏁板湪 Java 閲岀浉鍑� -->
+ <select id="sumTraceDeal" resultType="java.util.Map">
+ select count(*) as totalException,
+ sum(case when handle_flag = '1' then 1 else 0 end) as yesDeal
+ from service_subtask_detail_trace
+ where 1 = 1
+ <include refid="traceDealWhere"/>
+ </select>
+
+ <!-- 褰撳墠椤甸棶棰樼殑璐熻矗绉戝锛堟寜绉戝缂栧彿鍘婚噸锛屽悕绉板彇缁勫唴闈炵┖鐨勪竴涓級 -->
+ <select id="selectTraceDealDepts" resultType="java.util.Map">
+ select questiontext as questiontext,
+ todeptcode as deptCode,
+ min(todeptname) as deptName
+ from service_subtask_detail_trace
+ where 1 = 1
+ <include refid="traceDealWhere"/>
+ and todeptcode is not null and todeptcode != ''
+ and questiontext in
+ <foreach collection="questiontexts" item="qt" open="(" separator="," close=")">
+ #{qt}
+ </foreach>
+ group by questiontext, todeptcode
+ </select>
+
+ <!-- 褰撳墠椤甸棶棰樼殑鏈�鏂板鐞嗕汉鍜屽鐞嗘椂闂达紙handle_time 鏈�澶х殑涓�鏉★級 -->
+ <select id="selectTraceDealLatestHandle" resultType="java.util.Map">
+ select t.questiontext as questiontext,
+ t.handle_by as handleBy,
+ t.handle_time as handleTime
+ from service_subtask_detail_trace t
+ inner join (select questiontext, max(handle_time) as maxHandleTime
+ from service_subtask_detail_trace
+ where 1 = 1
+ <include refid="traceDealWhere"/>
+ and handle_time is not null
+ and questiontext in
+ <foreach collection="questiontexts" item="qt" open="(" separator="," close=")">
+ #{qt}
+ </foreach>
+ group by questiontext) m
+ on m.questiontext = t.questiontext and m.maxHandleTime = t.handle_time
+ where t.del_flag = 0
</select>
diff --git a/smartor/src/main/resources/mapper/smartor/SvyLibTemplageCategoryMapper.xml b/smartor/src/main/resources/mapper/smartor/SvyLibTemplageCategoryMapper.xml
index 0e7b2c9..e83b92f 100644
--- a/smartor/src/main/resources/mapper/smartor/SvyLibTemplageCategoryMapper.xml
+++ b/smartor/src/main/resources/mapper/smartor/SvyLibTemplageCategoryMapper.xml
@@ -15,6 +15,7 @@
<result property="updateBy" column="update_by"/>
<result property="updateTime" column="update_time"/>
<result property="orgid" column="orgid"/>
+ <result property="type" column="type"/>
<result property="seqno" column="seqno"/>
</resultMap>
@@ -29,6 +30,7 @@
update_by,
update_time,
orgid,
+ type,
seqno
from svy_lib_template_category
</sql>
@@ -43,6 +45,7 @@
<if test="guid != null and guid != ''">and guid = #{guid}</if>
<if test="orgid != null ">and orgid = #{orgid}</if>
<if test="seqno != null ">and seqno = #{seqno}</if>
+ <if test="type != null ">and type = #{type}</if>
</select>
@@ -65,6 +68,7 @@
<if test="updateTime != null">update_time,</if>
<if test="orgid != null">orgid,</if>
<if test="seqno != null">seqno,</if>
+ <if test="type != null">type,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="name != null">#{name},</if>
@@ -77,6 +81,7 @@
<if test="updateTime != null">#{updateTime},</if>
<if test="orgid != null">#{orgid},</if>
<if test="seqno != null">#{seqno},</if>
+ <if test="type != null">#{type},</if>
</trim>
</insert>
@@ -93,6 +98,7 @@
<if test="updateTime != null">update_time = #{updateTime},</if>
<if test="orgid != null">orgid = #{orgid},</if>
<if test="seqno != null">seqno = #{seqno},</if>
+ <if test="type != null">type = #{type},</if>
</trim>
where id = #{id}
</update>
--
Gitblit v1.9.3