From 0c1f8c479065739f3c7a5126de8e667035d00b58 Mon Sep 17 00:00:00 2001
From: liusheng <337615773@qq.com>
Date: 星期一, 12 十月 2026 14:21:52 +0800
Subject: [PATCH] 【丽水】满意度模块化:新增 ruoyi-satisfaction 独立模块
---
smartor/src/main/java/com/smartor/service/impl/ServiceSLTDHealthcareRecordServiceImpl.java | 243 ++++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 224 insertions(+), 19 deletions(-)
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 00b3a3f..2fc97a6 100644
--- a/smartor/src/main/java/com/smartor/service/impl/ServiceSLTDHealthcareRecordServiceImpl.java
+++ b/smartor/src/main/java/com/smartor/service/impl/ServiceSLTDHealthcareRecordServiceImpl.java
@@ -90,6 +90,11 @@
private ServiceSubtaskServiceImpl serviceSubtaskServiceImpl;
@Autowired
private ServiceSubtaskMapper serviceSubtaskMapper;
+ @Autowired
+ private PatMedInhospMapper patMedInhospMapper;
+
+ @Autowired
+ private PatMedOuthospErrorMapper patMedOuthospErrorMapper;
@Override
public List<ServiceSLTDInhospResDTO> queryHealthcareRecordList(ServiceSLTDInhospReqVO reqVO) {
@@ -501,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());
@@ -611,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) {
@@ -679,11 +839,35 @@
}
}
+ /**
+ * 鍙栧氨璇婃棩鏈熺殑 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) {
+ int failCount = 0;
for (ServiceSLTDInhospResDTO dto : resultList) {
if (Objects.isNull(dto)) continue;
- PatArchive patArchive = processPatientArchive(dto);
- processPatientInhospInfo(dto, patArchive, cry);
+ try {
+ PatArchive patArchive = processPatientArchive(dto);
+ processPatientInhospInfo(dto, patArchive, cry);
+ } catch (Exception e) {
+ failCount++;
+ log.error("銆恑nHospitalDate銆戝崟鏉¤褰曞鐞嗗け璐ワ紝宸茶烦杩囩户缁噰闆嗐�俿tate={}, serialnum={}, patname={}, patno={}, orgid={}, campusId={}",
+ cry, dto.getHealthcareRecordNo(), dto.getPatientName(), dto.getMedicalRecordNo(),
+ dto.getOrgId(), dto.getCampusId(), e);
+ }
+ }
+ if (failCount > 0) {
+ log.warn("銆恑nHospitalDate銆戞湰椤靛叡{}鏉★紝澶辫触{}鏉″凡璺宠繃锛屽叾浣檣}鏉″鐞嗗畬鎴愶紝state={}",
+ resultList.size(), failCount, resultList.size() - failCount, cry);
}
return true;
}
@@ -716,7 +900,8 @@
if (CollectionUtils.isNotEmpty(patMedInhospList)) {
//濡傛灉涓嶄负绌猴紝鍒欏皢鍏ラ櫌鏃堕棿杩涜鏇存柊
PatMedInhosp pmOut = patMedInhospList.get(0);
- PatMedInhosp pmIn = existingInhosps.get(0);
+ //鏈鍏ラ櫌鏁版嵁锛堣繖閲� existingInhosps 蹇呬负绌猴紝鍙� existingInhosps.get(0) 浼氫笅鏍囪秺鐣岋級
+ PatMedInhosp pmIn = patMedInhosp;
pmOut.setStarttime(pmIn.getStarttime());
pmOut.setUpdateTime(new Date());
patMedInhospService.updatePatMedInhosp(pmOut);
@@ -728,6 +913,26 @@
serviceSubtask.setSendstate(4L);
serviceSubtaskMapper.updateServiceSubtaskByCondition(serviceSubtask);
}
+ //閫氳繃鍏ラ櫌鏃堕棿锛屽拰鎮h�呯殑缂栧彿鍘绘煡涓�涓嬪嚭闄㈡椂闂达紝鏄惁瀛樺湪锛屽鏋滃瓨鍦紝鍒欒鎮h�呮槸鍐嶅叆闄㈢殑锛岄渶瑕佹敼鎴愪笉鎵ц
+ //鍑洪櫌鏃堕棿鍙瘮杈冨埌澶╋紝涓嶆瘮杈冩椂鍒嗙
+ if (pmIn.getStarttime() != null) {
+ Date dayStart = DateUtils.truncate(pmIn.getStarttime(), Calendar.DAY_OF_MONTH);
+ Date dayEnd = DateUtils.addDays(dayStart, 1);
+ List<PatMedInhosp> outInhosps = patMedInhospMapper.selectOutInhospByPatnoAndOutDate(
+ StringUtils.trim(pmIn.getPatno()), dayStart, dayEnd);
+ if (CollectionUtils.isNotEmpty(outInhosps)) {
+ //瀛樺湪鍑洪櫌璁板綍锛岃鏄庤鎮h�呮槸鍐嶅叆闄紝鎶婁笂涓�娆″嚭闄骇鐢熺殑瀛愪换鍔℃敼鎴愪笉鎵ц
+ ServiceSubtask outSubtask = new ServiceSubtask();
+ outSubtask.setInhospid(outInhosps.get(0).getInhospid());
+ outSubtask.setSendstate(4L);
+ outSubtask.setRemark("鎮h�呭啀鍏ラ櫌");
+ outSubtask.setUpdateTime(new Date());
+ serviceSubtaskMapper.updateServiceSubtaskByCondition(outSubtask);
+ log.info("鎮h�呭啀鍏ラ櫌锛屽皢涓婃鍑洪櫌璁板綍鐨勫瓙浠诲姟鏀逛负涓嶆墽琛岋細patno={}, 鍑洪櫌inhospid={}, 鍑洪櫌鏃堕棿={}, 鏈鍏ラ櫌鏃堕棿={}",
+ pmIn.getPatno(), outInhosps.get(0).getInhospid(), outInhosps.get(0).getEndtime(), pmIn.getStarttime());
+ }
+ }
+
} catch (Exception e) {
log.error("灏嗗嚭闄㈡椂闂寸瓑浜庡叆闄㈡椂闂寸殑inhospid鐨勪换鍔℃洿鏂板け璐ヤ簡, inhospid={}", pmOut.getInhospid(), e);
}
--
Gitblit v1.9.3