From 68ff33beff11310e830b0615b5a81f83fad0f683 Mon Sep 17 00:00:00 2001
From: yxh <172933527@qq.com>
Date: 星期日, 08 十一月 2026 23:33:14 +0800
Subject: [PATCH] ai优化
---
jh-module-ecg/jh-module-ecg-biz/src/main/java/cn/lihu/jh/module/ecg/service/appointment/AppointmentServiceImpl.java | 674 +++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 639 insertions(+), 35 deletions(-)
diff --git a/jh-module-ecg/jh-module-ecg-biz/src/main/java/cn/lihu/jh/module/ecg/service/appointment/AppointmentServiceImpl.java b/jh-module-ecg/jh-module-ecg-biz/src/main/java/cn/lihu/jh/module/ecg/service/appointment/AppointmentServiceImpl.java
index fe54ef3..6df4631 100644
--- a/jh-module-ecg/jh-module-ecg-biz/src/main/java/cn/lihu/jh/module/ecg/service/appointment/AppointmentServiceImpl.java
+++ b/jh-module-ecg/jh-module-ecg-biz/src/main/java/cn/lihu/jh/module/ecg/service/appointment/AppointmentServiceImpl.java
@@ -37,6 +37,7 @@
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
+import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
@@ -104,6 +105,79 @@
// 杩斿洖
return appointment.getId();
+ }
+
+ /** 骞跺彂鍐茬獊鍚庣殑閲嶈瘯娆℃暟涓庣瓑寰呴棿闅旓紙浠呯敤浜�"鎻掑叆鎾炲敮涓�绱㈠紩"杩欎竴绉嶆儏鍐碉級 */
+ private static final int APPLY_NO_CONFLICT_RETRY = 3;
+ private static final long APPLY_NO_CONFLICT_WAIT_MS = 150L;
+
+ /**
+ * 鎸� {@code apply_no} 鍘熷瓙钀藉簱锛氬凡瀛樺湪鍒欐洿鏂帮紝涓嶅瓨鍦ㄥ垯鎻掑叆锛涘苟鍙戦噸澶嶆彃鍏ユ椂涓嶄細鐣欓噸澶嶈銆�
+ *
+ * <h3>涓轰粈涔堥渶瑕佸畠</h3>
+ * 鍘熷疄鐜版槸銆寋@code getByApplyNo} 鏌ヤ竴涓� 鈫� 娌℃湁灏� insert銆嶏紝鏌ヤ笌鎻掍箣闂存病鏈夊師瀛愭�с��
+ * 瀹炴祴 2026-10-04 12:16锛欻IS 鍦� 423ms 鍐呮妸鍚屼竴寮犵敵璇峰崟鎺ㄤ簡涓ら亶锛屼袱涓嚎绋嬮兘璇诲埌 0 琛屻��
+ * 閮芥墽琛屼簡 insert锛屼簬鏄悓涓� {@code apply_no} 钀戒笅涓ゆ潯锛坕d 211740 / 211741锛夈��
+ * 琛ㄤ笂鍘熸湁鐨勫敮涓�绱㈠紩 {@code uniq-pat-book(pat_id, book_date, book_check_type)}
+ * 鍦� book_date / book_check_type 涓� NULL 鏃朵笉鐢熸晥锛屾嫤涓嶄綇銆�
+ *
+ * <h3>鐜板湪鐨勫仛娉�</h3>
+ * 鏁版嵁搴撲晶宸插姞鍞竴绱㈠紩 {@code uk_appointment_apply_no_active}锛堝彧绾︽潫鏈垹闄よ锛夈��
+ * 杩欓噷鏀规垚銆屽厛灏濊瘯鎻掑叆锛屾挒鍞竴閿氨鍥炶骞舵敼涓烘洿鏂般�嶏細
+ * <ul>
+ * <li>涓茶鍦烘櫙锛氭彃鍏ユ垚鍔燂紝琛屼负涓庡師鏉ヤ竴鑷达紱</li>
+ * <li>骞跺彂鍦烘櫙锛氬叾涓竴涓彃鍏ュ繀鐒跺け璐ワ紙DuplicateKeyException锛夛紝澶辫触鏂硅蛋鏇存柊锛屼笉鍐嶄骇鐢熼噸澶嶈锛�</li>
+ * <li>瀵规柟浜嬪姟灏氭湭鎻愪氦瀵艰嚧鍥炶涓嶅埌鏃讹紝鐭殏绛夊緟鍚庨噸璇曪紙鏈�澶� {@value #APPLY_NO_CONFLICT_RETRY} 娆★級銆�</li>
+ * </ul>
+ *
+ * @return 钀藉簱璁板綍鐨� id
+ */
+ private Long atomicSaveByApplyNo(AppointmentSaveReqVO saveReqVO) {
+ String applyNo = saveReqVO.getApplyNo();
+ // 鈶� 鍏堟寜鐢宠鍗曞彿璧�"鏇存柊"鍒嗘敮锛堜笌鏀归�犲墠鐨勮涔変竴鑷达細鍛戒腑宸插瓨鍦ㄥ垯浠ユ湰娆℃姤鏂囧唴瀹规洿鏂帮級
+ AppointmentDO exists = (applyNo == null) ? null : appointmentMapper.getByApplyNo(applyNo);
+ if (exists != null) {
+ saveReqVO.setId(exists.getId());
+ updateAppointment(saveReqVO);
+ return exists.getId();
+ }
+
+ // 鈶� 涓嶅瓨鍦� 鈫� 灏濊瘯鎻掑叆锛涙挒鍞竴绱㈠紩璇存槑鏈夊苟鍙戞彃鍏ワ紝杞洿鏂伴噸璇�
+ for (int attempt = 0; attempt <= APPLY_NO_CONFLICT_RETRY; attempt++) {
+ try {
+ AppointmentDO toInsert = BeanUtils.toBean(saveReqVO, AppointmentDO.class);
+ toInsert.setId(null);
+ appointmentMapper.insert(toInsert);
+ return toInsert.getId();
+ } catch (DuplicateKeyException e) {
+ AppointmentDO concurrent = (applyNo == null) ? null : appointmentMapper.getByApplyNo(applyNo);
+ if (concurrent != null) {
+ log.warn("[atomicSaveByApplyNo][骞跺彂閲嶅鎻掑叆宸叉嫤鎴紝鏀逛负鏇存柊宸叉湁璁板綍] applyNo={} existingId={}",
+ applyNo, concurrent.getId());
+ saveReqVO.setId(concurrent.getId());
+ updateAppointment(saveReqVO);
+ return concurrent.getId();
+ }
+ // 瀵规柟鍙兘杩樻病鎻愪氦锛氱瓑涓�涓嬪啀璇曪紙鏈�鍚庝粛鎷夸笉鍒板氨涓婃姏锛岀敱澶栧眰璁板綍閿欒鏃ュ織锛�
+ if (attempt < APPLY_NO_CONFLICT_RETRY) {
+ try {
+ Thread.sleep(APPLY_NO_CONFLICT_WAIT_MS);
+ } catch (InterruptedException ie) {
+ Thread.currentThread().interrupt();
+ throw e;
+ }
+ AppointmentDO retry = appointmentMapper.getByApplyNo(applyNo);
+ if (retry != null) {
+ saveReqVO.setId(retry.getId());
+ updateAppointment(saveReqVO);
+ return retry.getId();
+ }
+ } else {
+ throw e;
+ }
+ }
+ }
+ throw exception(APPOINTMENT_CREATE_FAIL);
}
@Override
@@ -183,6 +257,12 @@
@Override
public List<AppointmentDO> queryAndCreateAppointmentByPatId(String patCode) {
// 浠庡尰闄㈠钩鍙版煡璇�
+ //
+ // 銆愭湰闇�姹傘�戝尮閰嶅彛寰勪粠銆岀敵璇峰崟鍙� / 灏辫瘖娴佹按鍙� / 浣忛櫌鍙� / 韬唤璇佸彿銆嶆墿灞曚负**鍐嶅姞涓� pat_id**
+ // 锛堣 AppointmentMapper.getCurrentCode 鐨� SQL锛夈�傚師鍥狅細
+ // 鎵嬪姩鏂板缓鐨勯绾︼紙/ecg/appointment/create锛夊彧鏈� pat_id锛�
+ // apply_no / episode_id / hospital_no / pat_identity_id 鍏ㄤ负绌猴紝
+ // 绛惧埌椤垫寜鎮h�呯紪鍙锋煡璇㈡椂**姘歌繙鏌ヤ笉鍒�** 鈫� 椤甸潰鎻愮ず銆岃鍏堥绾︺�嶁啋 鏃犳硶绛惧埌銆�
List<AppointmentDO> appointmentExtermalList = appointmentMapper.getCurrentCode(patCode);
for (int appointmentIndex = 0; appointmentIndex < appointmentExtermalList.size(); appointmentIndex++) {
@@ -190,26 +270,47 @@
if (null == appointmentExtermal) continue;
// 浠嶥B鏌ヨ棰勭害锛屾槸鍚﹀凡缁忓瓨鍦�
- AppointmentDO appointmentDO = appointmentMapper.getByEpisodeIdAndApplyNo(appointmentExtermal.getEpisodeId(), appointmentExtermal.getApplyNo());
+ //
+ // 銆愭湰闇�姹傘�戜紭鍏堟寜**涓婚敭 id** 鍒ゆ柇銆屾槸鍚﹀凡瀛樺湪銆嶏細
+ // getCurrentCode 鏄湰鍦板簱鏌ヨ锛坰elect * 浼氭妸 id 甯﹀洖鏉ワ級锛�
+ // 鑰屽師閫昏緫鐢� getByEpisodeIdAndApplyNo(episodeId, applyNo) 鍒ゆ柇锛�
+ // 鎵嬪姩鏂板缓鐨勮杩欎袱涓瓧娈垫槸 NULL/绌� 鈬� `= NULL` 姘歌繙涓嶅尮閰� 鈬� 姣忔墦寮�涓�娆$鍒伴〉灏�**閲嶅鎻掑叆**涓�鏉°��
+ AppointmentDO appointmentDO = null;
+ if (null != appointmentExtermal.getId()) {
+ appointmentDO = appointmentMapper.selectById(appointmentExtermal.getId());
+ }
+ if (null == appointmentDO) {
+ appointmentDO = appointmentMapper.getByEpisodeIdAndApplyNo(
+ appointmentExtermal.getEpisodeId(), appointmentExtermal.getApplyNo());
+ }
if (null == appointmentDO) {
appointmentMapper.insert(appointmentExtermal);
} else {
appointmentExtermal.setId(appointmentDO.getId()); // 纭繚 杩斿洖鍊煎寘鍚� appointment id
// 澶勭悊绗竴娆$‘璁ゆ椂杩樻病鏈夐绾︽椂闂达紝鍐嶆潵纭鏃跺凡鏈夐绾︽椂闂寸殑鎯呭喌
- if (appointmentDO.getBookDate() != appointmentExtermal.getBookDate()) {
+ // 銆愭湰娆′慨澶嶃�戝師鍐欐硶 `appointmentDO.getBookDate() != appointmentExtermal.getBookDate()`
+ // 鏄�**寮曠敤姣旇緝**锛圠ocalDate 涓や釜涓嶅悓瀹炰緥鍗充娇鍊肩浉鍚屼篃浼氬垽涓轰笉绛夛級锛�
+ // 浼氬鑷存瘡娆¢兘鐧借窇涓�娆� updateById锛堟棤璋撴敼鍐� update_time锛夈�傛敼涓哄�兼瘮杈冦��
+ if (!java.util.Objects.equals(appointmentDO.getBookDate(), appointmentExtermal.getBookDate())) {
appointmentMapper.updateById(appointmentExtermal);
}
}
}
- // 鏌ヨ[queue琛╙琛ュ厖 book_seq_num 鍒拌繑鍥炲�间腑
+ // 鏌ヨ[queue琛╙琛ュ厖銆屾帓闃熷彿銆嶅埌杩斿洖鍊间腑
+ //
+ // 銆愬彿缁熶竴锛堟湰闇�姹傦級銆戞帓闃熷彿鏀逛负鍦ㄧ鍒版椂涓�娆℃�у啓杩� queue.seq_num锛屼笉鍐嶅啓 book_seq_num銆�
+ // 鍥犳杩欓噷鍙� seq_num锛涘澶栧瓧娈靛悕浠嶅彨 bookSeqNum锛堥渶姹傝姹傛帴鍙e瓧娈典繚鐣欎笉鍔級銆�
+ // 杩囨护 null锛氬瓨閲忚锛堟敼閫犲墠绛惧埌鐨勶級seq_num 鍙兘涓虹┖锛岃�� toMap 鐨� value 涓� null 浼氭姏 NPE銆�
if (!appointmentExtermalList.isEmpty()) {
List<Long> appointIdlist = appointmentExtermalList.stream().map(appointmentDO -> appointmentDO.getId()).toList();
- List<QueueDO> simpleQueueDOList = queueService.selectBookSeqNumByAppointIdList(appointIdlist);
+ List<QueueDO> simpleQueueDOList = queueService.selectQueueByAppointIdList(appointIdlist);
if (!simpleQueueDOList.isEmpty()) {
- Map<Long, Integer> mapAppointIdVsBookSeqNo = simpleQueueDOList.stream().collect(Collectors.toMap(QueueDO::getAppointId, QueueDO::getBookSeqNum));
- appointmentExtermalList.forEach(appointmentExterma -> appointmentExterma.setBookSeqNum(mapAppointIdVsBookSeqNo.get(appointmentExterma.getId())));
+ Map<Long, Integer> mapAppointIdVsSeqNo = simpleQueueDOList.stream()
+ .filter(queueDO -> null != queueDO.getAppointId() && null != queueDO.getSeqNum())
+ .collect(Collectors.toMap(QueueDO::getAppointId, QueueDO::getSeqNum, (a, b) -> a));
+ appointmentExtermalList.forEach(appointmentExterma -> appointmentExterma.setBookSeqNum(mapAppointIdVsSeqNo.get(appointmentExterma.getId())));
}
}
@@ -315,27 +416,52 @@
AppointmentDO appointment = getAppointment(confirmReqVO.getId());
if (null == appointment) throw exception(PATIENT_NOT_EXISTS);
- // 鎵嬪姩棰勭害锛岀洿鎺ヨ缃绾︽棩鏈熶负褰撳ぉ
- if (confirmReqVO.getIsVip() == 1) {
+ boolean isVipFlag = (null != confirmReqVO.getIsVip() && 1 == confirmReqVO.getIsVip());
+ boolean forceCheckIn = Boolean.TRUE.equals(confirmReqVO.getForceCheckIn());
+ // 娉ㄦ剰锛氳繖閲岀殑"鏄惁褰撳ぉ"蹇呴』鍦ㄦ敼鍐� bookDate 涔嬪墠鍒ゆ柇锛堜笅闈細鎶婇潪褰撳ぉ鏀逛负褰撳ぉ锛�
+ boolean bookDateIsToday = DateUtils.isToday(appointment.getBookDate());
+
+ // 鎵嬪姩棰勭害 / VIP 鍔犲彿锛氶绾︽棩鏈熺洿鎺ユ寜褰撳ぉ绛惧埌
+ if (isVipFlag) {
appointment.setBookDate(LocalDate.now());
+ bookDateIsToday = true;
}
- if (!DateUtils.isToday(appointment.getBookDate())) throw exception(APPOINTMENT_NOT_TODAY);
-
+ // 銆愭湰闇�姹傘�戦潪褰撳ぉ棰勭害鐨勭鍒帮細鍏堟彁閱掋�佺‘璁ゅ悗鍏佽绛惧叆锛堝墠绔脊绐楃‘璁ゅ悗甯� forceCheckIn=true锛�
+ // 鈶� 鏈‘璁わ紙鍓嶇杩樻病璁╃敤鎴风‘璁わ級鈫� 浠嶈繑鍥� APPOINTMENT_NOT_TODAY锛屽墠绔嵁姝ゅ脊銆岄潪褰撳ぉ锛屾槸鍚︾鍒般�嶏紱
+ // 鈶� 宸茬‘璁� 鈫� 鍏佽绛惧叆锛屽苟涓�**寮哄埗璧伴鐣欏彿閫氶亾**锛岄伩鍏嶅崰鐢ㄥ綋澶╁悓鏃舵鐨勬甯搁绾﹀彿锛�
+ // 鈶� 棰勭害鏃ユ湡鏀瑰啓涓哄綋澶╋細闃熷垪/澶у睆/宸ヤ綔鍙伴兘鎸� book_date = 浠婂ぉ 杩囨护锛�
+ // 鑻ヤ繚鐣欏師鏃ユ湡锛屾偅鑰呯鍏ュ悗涓嶄細鍑虹幇鍦ㄤ换浣曞垪琛ㄩ噷銆�
+ if (!bookDateIsToday) {
+ if (!forceCheckIn) {
+ throw exception(APPOINTMENT_NOT_TODAY);
+ }
+ log.info("[appoitmentConfirm] 闈炲綋澶╅绾︾鍏ワ紙鏀圭敤棰勭暀鍙凤紝棰勭害鏃ユ湡鏀逛粖澶╋級. appointmentId={} 鍘熼绾︽棩鏈�={} checkType={} timeslot={}",
+ appointment.getId(), appointment.getBookDate(), confirmReqVO.getBookCheckType(),
+ confirmReqVO.getBookTimeslot());
+ appointment.setBookDate(LocalDate.now());
+ }
// 銆愰渶姹傦細鎺掗槦搴忓彿瑙勫垯銆戞寜 check_type.seq_rule 鍐冲畾鍙栧彿鏂瑰紡锛�
// 0=棰勭害鍙凤紙鐢ㄩ绾︾郴缁熷凡涓嬪彂鐨勫彿锛涘綋鍓� HIS 鏈笅鍙戯紝浼氳嚜鍔ㄥ洖閫�鍒扮鍒板簭鍙凤級
// 1=绛惧埌搴忓彿锛堝綋澶╁悓妫�鏌ョ被鍨嬭繛缁�掑锛屾瘡 9 涓鐣� 1 涓粰鍔犳�ワ級
// 2=鏃舵鍙凤紙鎸� bookTimeslot 浠庡彿姹犲彇鍙� 鈥斺�� 鏀归�犲墠鐨勫師鏈夎涓猴紝涔熸槸鏈厤缃椂鐨勯粯璁わ級
+ //
+ // 銆愭湰闇�姹傦細鎸夋椂娈甸绾︺�戝鍔� VIP/鍔犲彿鏍囪锛�
+ // 路 VIP/鍔犲彿/闈炲綋澶╃鍏� 鈫� 鏈棰勭暀鍙� 鈫� 鎬婚鐣欐睜锛坱ime_slot=0锛�
+ // 路 鏅�� 鈫� 鏈鏅�氬彿 鈫� 鏈棰勭暀鍙� 鈫� 鎬婚鐣欐睜
+ // 娌℃湁棰勭害鏃舵锛坆ookTimeslot 涓虹┖/0/瀛楀吀澶栵級鏃朵篃鑳界鍒帮細鐩存帴钀藉埌鎬婚鐣欐睜銆�
boolean urgent = isHisUrgent(appointment);
+ boolean vip = isVipFlag || urgent || !bookDateIsToday;
Integer newSeqNo = queueSequenceService.distributeSeqNoByRule(
confirmReqVO.getBookCheckType(),
confirmReqVO.getBookTimeslot(),
appointment.getBookSeqNum(),
- urgent);
- log.info("[appoitmentConfirm][鍒嗛厤鎺掗槦搴忓彿] appointmentId={} checkType={} timeslot={} 瑙勫垯鍙栧彿={} 鍔犳��={}",
+ urgent,
+ vip);
+ log.info("[appoitmentConfirm][鍒嗛厤鎺掗槦搴忓彿] appointmentId={} checkType={} timeslot={} 瑙勫垯鍙栧彿={} 鍔犳��={} VIP/鍔犲彿={}",
appointment.getId(), confirmReqVO.getBookCheckType(), confirmReqVO.getBookTimeslot(),
- newSeqNo, urgent);
+ newSeqNo, urgent, vip);
try {
QueueSaveReqVO queueSaveReqVO = new QueueSaveReqVO();
@@ -348,14 +474,19 @@
queueSaveReqVO.setBookDate(appointment.getBookDate());
queueSaveReqVO.setBookTimeslot(confirmReqVO.getBookTimeslot()); /*appointment.getBookTimeslot()*/
queueSaveReqVO.setBookCheckType(appointment.getBookCheckType());
- queueSaveReqVO.setBookSeqNum(newSeqNo);
+ // 銆愬彿缁熶竴锛堟湰闇�姹傦級銆戠鍒版椂鍙栫殑鍙�**鐩存帴鍐欏叆 seq_num**锛堜笉鍐嶅啓 book_seq_num锛夈��
+ // 涔嬪悗浠讳綍鐜妭閮戒笉鍐嶆敼杩欎釜鍙凤細鍒嗘祦銆佽繃鍙枫�佸彫鍥炪�佸姞鎬ャ�佽鏈哄潎鍙敼鐘舵��/宸ヤ綅銆�
+ // 鍙栧彿瑙勫垯浠嶇敱 check_type.seq_rule 鍐冲畾锛堥绾﹀彿 / 绛惧埌搴忓彿 / 鏃舵鍙凤級锛岃 distributeSeqNoByRule銆�
+ queueSaveReqVO.setSeqNum(newSeqNo);
queueSaveReqVO.setIsVip(confirmReqVO.getIsVip());
queueSaveReqVO.setPassed((byte) 0);
queueSaveReqVO.setExpired((byte) 0);
// 闇�姹�2锛欼SCB銆屾槸鍚﹀簥杈广�嶉殢闃熷垪涓�璧疯惤搴擄紝渚涘睆骞�/椤甸潰灞曠ず
queueSaveReqVO.setIsBedside(appointment.getIsBedside());
// HIS 鍔犳�ユ爣璁帮紙jjbz=J锛夆啋 鎺掗槦鍔犳�ワ紝涓庝汉宸ユ彃闃熷叡鐢� jump_flag銆�
- // queue 琛ㄦ寜 "order by jump_flag desc, book_timeslot, create_time" 鍙栧彿锛岀疆 1 鍗充紭鍏堛��
+ // 銆愬彿缁熶竴鍚庛�戝姞鎬�**涓嶆敼鎺掗槦鍙�**锛堝彿鍦ㄤ笅闈� setSeqNum 鏃跺凡缁忓畾姝伙級锛�
+ // 鑰屾槸闈犳帓搴忎綋鐜帮細鍒嗘祦鍙栦汉銆佸彨鍙峰彇浜恒�佸伐浣滃彴/璇婇棿灞�/澶у睆鍒楄〃閮芥槸
+ // "jump_flag desc 浼樺厛 鈫� seq_num 鍗囧簭"锛岀疆 1 鍗虫帓鍒版渶鍓嶃��
if (urgent) {
queueSaveReqVO.setJumpFlag((byte) 1);
log.info("[appoitmentConfirm][HIS 鍔犳�ユ偅鑰咃紝鎺掗槦鏍囪涓哄姞鎬 applyNo={} patId={}",
@@ -471,6 +602,40 @@
appointment.setTargetSiteCode(targetSite);
}
+ // 棰勭害鏃堕棿/鏃堕棿娈�/璇婂锛圫0201ECG 鎶ユ枃鐨� component2.observationRequest.ZDY锛屽疄娴嬪舰濡傦細
+ // ZDY={time=2026-10-06 08:00-08:30, area=..., roomname=6鍙疯瘖瀹�(鍘呭彸渚�), roomcode=, jcxmcode=201652, jcxmname=骞虫澘杩愬姩璇曢獙}
+ // 鍘熷疄鐜板彧鎶婂畠褰�"妫�鏌ョ被鍨�"鐢紝娌¤В鏋愰绾︿俊鎭紝瀵艰嚧杩欐潯娴佸缓鍑烘潵鐨勮褰�
+ // book_date / book_timeslot / book_time / room_name 鍏ㄤ负绌猴紙瀹炴祴 211741銆�211962 灏辨槸杩欑鍗婃潯鏁版嵁锛夈��
+ Object zdyRaw = c2.get("ZDY");
+ if (zdyRaw == null) {
+ zdyRaw = c2.get("zdy");
+ }
+ if (zdyRaw instanceof Map) {
+ Map<String, Object> zdyMap = (Map<String, Object>) zdyRaw;
+ Object timeObj = zdyMap.get("time");
+ String timeRange = timeObj == null ? null : timeObj.toString();
+ Integer timeslot = parseBookTimeslot(timeRange);
+ if (timeslot != null) {
+ appointment.setBookTimeslot(timeslot);
+ // 鐢辨椂闂存璧峰鎺ㄧ畻棰勭害鏃跺埢锛堝 8000830 鈫� 08:00锛夛紱book_date 瑙佷笅鏂� 鈶� 鐨勭粺涓�鎺ㄥ
+ LocalTime startTime = timeOfTimeslot(timeslot);
+ if (startTime != null) {
+ appointment.setBookTime(LocalDateTime.of(LocalDate.now(), startTime));
+ }
+ } else {
+ // 鏃堕棿娈佃В鏋愪笉鍑烘潵鏃讹紝閫�鍥炵敤 effectiveTime锛堟姤鏂囬噷鍙︿竴涓绾︽椂鍒诲瓧娈碉級
+ LocalDateTime bookTime = parseDateTime(digText(c2, "effectiveTime", "any", "value"));
+ if (bookTime != null) {
+ appointment.setBookTime(bookTime);
+ appointment.setBookDate(bookTime.toLocalDate());
+ }
+ }
+ Object roomName = zdyMap.get("roomname");
+ if (roomName != null && StringUtils.isNotEmpty(roomName.toString())) {
+ appointment.setRoomName(truncate(roomName.toString(), ROOM_NAME_MAX_LEN));
+ }
+ }
+
// 鍖诲槺鍙凤細component2.observationRequest.id.item[root=2.16.156.10011.1.28].extension
//
// 渚濇嵁锛圚IS銆婁氦浜掓湇鍔¢�氱敤鎺ュ彛鏂囨。銆嬶級锛�
@@ -491,15 +656,29 @@
}
}
- // 鍖荤敓寮�鍗曟椂闂�
- Optional.ofNullable(dataMap.get("controlActProcess")).map(controlActProcess -> (Map<String, Object>) controlActProcess).map(controlActProcess -> (Map<String, Object>) controlActProcess.get("subject")).map(subject -> (Map<String, Object>) subject.get("observationRequest")).map(observationRequest -> (Map<String, Object>) observationRequest.get("author")).map(author -> (Map<String, Object>) author.get("time")).map(time -> (String) time.get("value")).map(str -> {
- try {
- return new SimpleDateFormat("yyyyMMddHHmmss").parse(str);
- } catch (Exception e) {
- e.printStackTrace();
- return null;
+ // 鍖荤敓寮�鍗曟椂闂达紙鎶ユ枃璺緞锛歝ontrolActProcess.subject.observationRequest.author.time.value锛�
+ //
+ // 銆愪负浠�涔堜笉鐢ㄤ竴琛� Optional 閾剧洿鎺� parse銆�
+ // 鍘熷疄鐜板啓姝� `SimpleDateFormat("yyyyMMddHHmmss")`锛屾牸寮忎笉绗﹀彧浼� **闈欓粯涓㈠純**
+ // 锛坈atch 閲屼粎 printStackTrace锛屼笉钀芥棩蹇楀瓧娈碉級鈥斺�旂嚎涓婂嚭鐜伴棶棰樻椂鏃犱粠瀹氫綅銆�
+ // 鐜版敼涓烘樉寮忓垎鏀� + 缁撴瀯鍖� WARN 鏃ュ織锛岃嚦灏戞妸銆屾姤鏂囧師鍊� / 鐢宠鍗曞彿銆嶈涓嬫潵銆�
+ String doctorTimeRaw = digText(dataMap, "controlActProcess", "subject",
+ "observationRequest", "author", "time", "value");
+ // 璇ュ灏氭湭鎵ц鍒颁笅鏂圭殑 setApplyNo锛堝師 L575锛夛紝鏁呭崟鐙彇涓�娆$敵璇峰崟鍙凤紝浠呯敤浜庢棩蹇楀畾浣�
+ String applyNoForLog = digText(dataMap, "controlActProcess", "subject",
+ "observationRequest", "id", "item", "extension");
+ if (StringUtils.isNotEmpty(doctorTimeRaw)) {
+ // 鍘熸牱閲囩撼 HIS 鎵�鍙戠殑鍊硷紙涓嶅仛鍙栬垗锛岄伩鍏嶈鍒ゅ弽鑰屽啓鍧忔暟鎹級銆�
+ // 鑻ヤ负銆屾棩鏈熷�笺�嶏紙鏃跺垎绉�=000000锛屽疄娴嬬害 61%锛夛紝parseHisDoctorTime 浼氭墦 WARN
+ // 璁板綍鍘熷鎶ユ枃鍊� + 鐢宠鍗曞彿锛屼究浜庡悜 HIS 渚у弽棣堬紱鍐欏叆琛屼负涓庢敼鍔ㄥ墠涓�鑷淬��
+ java.util.Date parsedDoctorTime = parseHisDoctorTime(doctorTimeRaw, applyNoForLog);
+ if (parsedDoctorTime != null) {
+ appointment.setDoctorTime(parsedDoctorTime);
}
- }).filter(Objects::nonNull).ifPresent(appointment::setDoctorTime);
+ } else {
+ log.warn("[handleAppointmentCreate][鎶ユ枃缂哄皯寮�鍗曟椂闂� author/time/value锛宒octor_time 灏嗕负绌篯 applyNo={}",
+ applyNoForLog);
+ }
//璁剧疆寮�鍗曞尰鐢熷鍚�
Optional.ofNullable(dataMap.get("controlActProcess")).map(controlActProcess -> (Map<String, Object>) controlActProcess).map(controlActProcess -> (Map<String, Object>) controlActProcess.get("subject")).map(subject -> (Map<String, Object>) subject.get("observationRequest")).map(observationRequest -> (Map<String, Object>) observationRequest.get("author")).map(author -> (Map<String, Object>) author.get("assignedEntity")).map(assignedEntity -> (Map<String, Object>) assignedEntity.get("assignedPerson")).map(assignedPerson -> (Map<String, Object>) assignedPerson.get("name")).map(name -> (Map<String, Object>) name.get("item")).map(item -> (Map<String, Object>) item.get("part")).map(part -> (String) part.get("value")).ifPresent(appointment::setDoctor);
@@ -563,6 +742,33 @@
// 璁剧疆鐢宠鍗曞彿
Optional.ofNullable(dataMap.get("controlActProcess")).map(controlActProcess -> (Map<String, Object>) controlActProcess).map(controlActProcess -> (Map<String, Object>) controlActProcess.get("subject")).map(subject -> (Map<String, Object>) subject.get("observationRequest")).map(observationRequest -> (Map<String, Object>) observationRequest.get("id")).map(id -> (Map<String, Object>) id.get("item")).map(item -> (String) item.get("extension")).ifPresent(appointment::setApplyNo);
+ // 棰勭害鏃ユ湡锛氭姤鏂囬噷鐨勯绾︽椂闂存 ZDY.time 褰㈠ "2026-10-06 08:00-08:30"銆�
+ // 涓婇潰瑙f瀽鏃堕棿娈垫椂鍙嬁鍒颁簡鏃跺垎锛堢敤浜� book_timeslot/book_time锛夛紝杩欓噷琛ユ棩鏈燂細
+ // 鑻ュ彧鎷垮埌鏃堕棿娈佃�屾棩鏈熶负绌猴紝灏变粠 ZDY.time 鐨勬棩鏈熼儴鍒嗚ˉ涓婏紝骞舵嵁姝や慨姝� book_time 鐨勬棩鏈熴��
+ String zdyTimeRange = digText(dataMap, "controlActProcess", "subject", "observationRequest",
+ "component2", "observationRequest", "ZDY", "time");
+ if (StringUtils.isEmpty(zdyTimeRange)) {
+ zdyTimeRange = digText(dataMap, "controlActProcess", "subject", "observationRequest",
+ "component2", "observationRequest", "zdy", "time");
+ }
+ if (StringUtils.isNotEmpty(zdyTimeRange)) {
+ String[] parts = zdyTimeRange.trim().split("\\s+");
+ if (parts.length >= 1) {
+ LocalDateTime parsedDate = parseDateTime(parts[0] + " 00:00");
+ if (parsedDate != null) {
+ LocalDate zdyBookDate = parsedDate.toLocalDate();
+ if (appointment.getBookDate() == null) {
+ appointment.setBookDate(zdyBookDate);
+ }
+ // book_time 涔嬪墠鍙槸鐢�"浠婂ぉ"鍗犱綅锛岃繖閲屾崲鎴愮湡瀹為绾︽棩鏈�
+ if (appointment.getBookTime() != null) {
+ appointment.setBookTime(appointment.getBookTime().withYear(zdyBookDate.getYear())
+ .withMonth(zdyBookDate.getMonthValue()).withDayOfMonth(zdyBookDate.getDayOfMonth()));
+ }
+ }
+ }
+ }
+
//璁剧疆妫�鏌ョ被鍨�
// String checkType = Optional.ofNullable(dataMap.get("controlActProcess")).map(controlActProcess -> (Map<String, Object>) controlActProcess).map(controlActProcess -> (Map<String, Object>) controlActProcess.get("component2")).map(component2 -> (Map<String, Object>) component2.get("observationRequest")).map(observationRequest -> (Map<String, Object>) observationRequest.get("code")).map(code -> (String) code.get("code")).orElseThrow(() -> exception(APPOINTMENT_CREATE_FAIL));
String checkType = Optional.ofNullable(dataMap.get("controlActProcess")).map(controlActProcess -> (Map<String, Object>) controlActProcess).map(controlActProcess -> (Map<String, Object>) controlActProcess.get("subject")).map(subject -> (Map<String, Object>) subject.get("observationRequest")).map(observationRequest -> (Map<String, Object>) observationRequest.get("component2")).map(component2 -> (Map<String, Object>) component2.get("observationRequest")).map(observationRequest -> (Map<String, Object>) observationRequest.get("code")).map(code -> (String) code.get("code")).orElseThrow(() -> exception(APPOINTMENT_CREATE_FAIL));
@@ -582,7 +788,17 @@
if (value != null) {
appointment.setBookCheckType(value);
} else {
- log.warn("[handleAppointmentCreate][浣撴鎮h�呮鏌ラ」鐩悕绉版棤娉曟槧灏刔 checkName={}", checkName);
+ // 鍚嶇О鏄犲皠涓嶅埌灏遍��鍥炪�屾寜 HIS 妫�鏌ヤ唬鐮佹槧灏勩�嶏細
+ // 瀹炴祴杩愬姩璇曢獙鍦� HIS 渚ф敼杩囧悕锛堝钩鏉胯繍鍔ㄥ績鐢� 鈫� 骞虫澘杩愬姩璇曢獙锛夛紝
+ // 鍙鍚嶇О浼氳 book_check_type 钀界┖锛涜�屾姤鏂囬噷鐨� code锛堝 201652锛夋槸绋冲畾鐨勩��
+ Integer fallback = resolveBookCheckTypeFromComponent2(dataMap);
+ if (fallback != null) {
+ appointment.setBookCheckType(fallback);
+ log.info("[handleAppointmentCreate][浣撴鎮h�呭悕绉版湭鏄犲皠锛屽凡鎸夋鏌ヤ唬鐮佸厹搴昡 checkName={} bookCheckType={}",
+ checkName, fallback);
+ } else {
+ log.warn("[handleAppointmentCreate][浣撴鎮h�呮鏌ラ」鐩悕绉颁笌浠g爜鍧囨棤娉曟槧灏刔 checkName={}", checkName);
+ }
}
} else {
Integer value = resolveBookCheckTypeFromComponent2(dataMap);
@@ -627,13 +843,12 @@
if (appointmentDO != null) {
// 淇濈暀鍘熻褰曚腑鏈鎶ユ枃鏈彁渚涚殑瀛楁锛岄伩鍏嶈绌哄�艰鐩�
mergeUnsetFields(appointment, appointmentDO);
+ // 鍚堝苟缁撴灉瑕佸洖鍒� saveReqVO 涓婏紝鍚﹀垯鏇存柊/鎻掑叆鐢ㄧ殑杩樻槸"鏈悎骞�"鐨勬姤鏂囧��
saveReqVO = BeanUtils.toBean(appointment, AppointmentSaveReqVO.class);
- saveReqVO.setId(appointmentDO.getId());
- updateAppointment(saveReqVO);
- return appointmentDO.getId();
}
-
- return createAppointment(saveReqVO);
+ // 浜ょ粰鍘熷瓙钀藉簱锛氫笉瀛樺湪鍒欐彃鍏ワ紝宸插瓨鍦ㄥ垯鏇存柊锛涘苟鍙戦噸澶嶆彃鍏ヤ細琚敮涓�绱㈠紩鎷︿笅骞惰浆涓烘洿鏂帮紝
+ // 涓嶄細鍐嶅嚭鐜�"鍚屼竴 apply_no 涓ゆ潯璁板綍"锛堝師瀹炵幇鍦ㄨ繖閲�"鏌ヤ竴娆″啀鎻�"锛屽苟鍙戜笅蹇呯劧婕忥級銆�
+ return atomicSaveByApplyNo(saveReqVO);
} catch (Exception e) {
log.error("[handleAppointmentCreate][澶勭悊棰勭害鍒涘缓澶辫触 dataMap({})]", dataMap, e);
throw exception(APPOINTMENT_CREATE_FAIL);
@@ -904,12 +1119,18 @@
// 3. 鏈湴璁板綍鍖归厤
AppointmentDO existingAppointment = appointmentMapper.getByApplyNo(applyNo);
if (existingAppointment != null) {
- existingAppointment.setStatus(status);
- if (HisCheckStatusEnum.REGISTERED.getCode().toString().equals(status)) {
- existingAppointment.setRegisterDate(new Date());
- }
- AppointmentSaveReqVO updateReqVO = BeanUtils.toBean(existingAppointment, AppointmentSaveReqVO.class);
- updateAppointment(updateReqVO);
+ // 鐘舵�佹祦鍙厑璁告敼 status / register_date锛�
+ // 鍘熷疄鐜版妸鏌ュ嚭鏉ョ殑鏁磋瀵硅薄鍐� updateById 鍐欏洖锛堣-鏀�-鍐欙級锛屼細鎶� book_date / book_check_type
+ // 绛夊瓧娈垫寜鏃у揩鐓ц鐩栥�傚疄娴� 2026-10-05 07:58锛屼竴绗旈绾﹀垰琚� S050401 鍐欏ソ棰勭害鏃堕棿涓庢鏌ョ被鍨嬶紝
+ // 3.6 绉掑悗 S0405 鐘舵�佹祦鍙堟妸鏁磋鍐欏洖涓�娆★紝check_type 琚啓鎴愪簡绌恒��
+ // 杩欓噷鏀规垚鍙洿鏂扮姸鎬侊紙register_date 浠呭湪鐘舵��=鐧昏鏃跺啓鍏ワ紝鐢� updateStatusByApplyNo 澶勭悊锛夈��
+ Date registerDate = HisCheckStatusEnum.REGISTERED.getCode().toString().equals(status)
+ ? new Date() : null;
+ Integer updated = registerDate != null
+ ? appointmentMapper.updateStatusByApplyNo(applyNo, status, registerDate)
+ : appointmentMapper.updateStatusOnlyByApplyNo(applyNo, status);
+ log.info("[handleAppointmentStateUpdate][浠呮洿鏂扮姸鎬乚 applyNo={} status={} 褰卞搷琛屾暟={}",
+ applyNo, status, updated);
return;
}
@@ -1062,6 +1283,121 @@
return o == null ? null : o.toString();
}
+ /**
+ * 浠� S050401/S050501锛堟鏌ラ绾︼級鎶ユ枃鐨� {@code ZDY} 鑺傜偣瑙f瀽鏈湴 {@code book_check_type}銆�
+ *
+ * <h3>涓轰粈涔堥渶瑕佽繖涓柟娉�</h3>
+ * {@code S050401/S050501} 鎶ユ枃鐨勬鏌ラ」鐩斁鍦� {@code ZDY.jcxmcode / ZDY.jcxmname}
+ * 锛堝舰濡� {@code jcxmcode=201652, jcxmname=骞虫澘杩愬姩璇曢獙}锛夛紝
+ * 涓� {@code S0201ECG} 鐨� {@code component2.observationRequest.code.code} **涓嶆槸鍚屼竴璺緞**銆�
+ * 鍘熷厛鍙湁 S0201ECG 閭f潯璺緞瑙f瀽妫�鏌ョ被鍨嬶紝浜庢槸銆孲050401 鍏堝埌銆丼0201ECG 鏈埌銆嶆椂璧�
+ * {@link #insertAppointmentFromCheckAppointment} 瀹归敊鏂板锛�
+ * {@code book_check_type} 浼�**姘歌繙涓虹┖** 鈥斺�� 瀹炴祴 2026-09-29~10-09 鍏� 279 鏉�
+ * 锛堝 {@code apply_no=8826092420371106}锛屾姤鏂囬噷 {@code jcxmcode=201652} 鏄庢槑瀛樺湪锛夈��
+ *
+ * <h3>瑙f瀽椤哄簭</h3>
+ * <ol>
+ * <li><b>鍚嶇О浼樺厛</b>锛歿@code jcxmname} 鈫� {@link HisCheckNameEnum#getByName}銆�
+ * 璇ユ灇涓惧凡鍚�屽钩鏉胯繍鍔ㄨ瘯楠屻�嶇瓑 HIS 鏀瑰悕鍒悕锛屼笖鍐呯疆瑙勮寖鍖栧尮閰嶏紱</li>
+ * <li><b>浠g爜鍏滃簳</b>锛歿@code jcxmcode} 鈫� {@link HisCheckCodeEnum}锛�
+ * 鍏煎甯�/涓嶅甫 {@code Y} 鍓嶇紑銆�</li>
+ * </ol>
+ *
+ * <h3>澶氬�煎鐞�</h3>
+ * 瀹炴祴璇ュ瓧娈靛彲鑳戒负閫楀彿鍒嗛殧澶氬�硷紙濡� S0405 鐨� {@code jcxmcode=1080,3016,3014}锛夈��
+ * 绛栫暐锛�**鎸夐『搴忓彇绗竴涓兘鏄犲皠鎴愬姛鐨勫��**锛涘厛鏁翠綋璇曟帰锛堝崟鍊煎満鏅級锛屽啀閫愭璇曟帰銆�
+ *
+ * @param zdy 鎶ユ枃涓殑 {@code ZDY} 鑺傜偣锛屽彲涓� null
+ * @return 鏈湴妫�鏌ョ被鍨嬪�硷紙濡� 400锛夛紱鏃犳硶瑙f瀽鏃惰繑鍥� null锛堣皟鐢ㄦ柟淇濇寔鍘熷�间笉鍐欙級
+ */
+ private Integer resolveBookCheckTypeFromZdy(Map<String, Object> zdy, String applyNo) {
+ if (zdy == null) {
+ log.warn("[resolveBookCheckTypeFromZdy][鎶ユ枃鏃� ZDY 鑺傜偣锛屾棤娉曡В鏋愭鏌ョ被鍨媇 applyNo={}", applyNo);
+ return null;
+ }
+ String jcxmName = extractZdyValueFromMap(zdy, "jcxmname");
+ String jcxmCode = extractZdyValueFromMap(zdy, "jcxmcode");
+
+ // 鈶� 鍚嶇О鏄犲皠锛堜紭鍏堬細鍙锛屼笖鏋氫妇宸茶鐩� HIS 鏀瑰悕涓庤鑼冨寲宸紓锛�
+ Integer byName = mapCheckNameToType(jcxmName);
+ if (byName != null) {
+ return byName;
+ }
+ // 鈶� 浠g爜鏄犲皠锛堝厹搴曪細瀹炴祴 HIS 渚ф敼杩囧悕锛屼唬鐮佹洿绋冲畾锛�
+ Integer byCode = mapCheckCodeToType(jcxmCode);
+ if (byCode != null) {
+ log.info("[resolveBookCheckTypeFromZdy][鍚嶇О鏈槧灏勶紝宸叉寜妫�鏌ヤ唬鐮佸厹搴昡 "
+ + "applyNo={} jcxmname={} jcxmcode={} bookCheckType={}",
+ applyNo, jcxmName, jcxmCode, byCode);
+ return byCode;
+ }
+
+ log.warn("[resolveBookCheckTypeFromZdy][妫�鏌ラ」鐩悕绉颁笌浠g爜鍧囨棤娉曟槧灏勶紝book_check_type 淇濇寔鍘熷�糫 "
+ + "applyNo={} jcxmname={} jcxmcode={}", applyNo, jcxmName, jcxmCode);
+ return null;
+ }
+
+ /** 妫�鏌ラ」鐩悕绉� 鈫� 鏈湴妫�鏌ョ被鍨嬶紙鏀寔閫楀彿鍒嗛殧澶氬�硷紝鍙栫涓�涓彲鏄犲皠鐨勶級 */
+ private Integer mapCheckNameToType(String rawName) {
+ if (StringUtils.isEmpty(rawName)) {
+ return null;
+ }
+ for (String candidate : splitMultiValue(rawName)) {
+ // 鍘荤┖鐧斤細HIS 鎶ユ枃閲屽伓瑙併�屽钩鏉胯繍鍔ㄨ瘯楠� 銆嶈繖绫诲熬闅忕┖鏍�
+ String mapped = HisCheckNameEnum.getByName(candidate.replaceAll("\\s+", ""));
+ Integer value = parseIntegerQuietly(mapped);
+ if (value != null) {
+ return value;
+ }
+ }
+ return null;
+ }
+
+ /** HIS 妫�鏌ヤ唬鐮� 鈫� 鏈湴妫�鏌ョ被鍨嬶紙鏀寔閫楀彿鍒嗛殧澶氬�硷紱鍏煎甯�/涓嶅甫 Y 鍓嶇紑锛� */
+ private Integer mapCheckCodeToType(String rawCode) {
+ if (StringUtils.isEmpty(rawCode)) {
+ return null;
+ }
+ for (String candidate : splitMultiValue(rawCode)) {
+ String code = candidate.replaceAll("\\s+", "");
+ if (code.isEmpty()) {
+ continue;
+ }
+ // 鍏煎涓ょ鎶ユ枃褰㈡�侊細甯﹀墠缂�锛圷1202065锛変笌涓嶅甫鍓嶇紑锛�201652锛�
+ String[] tries = code.length() > 1
+ ? new String[]{code, code.substring(1)}
+ : new String[]{code};
+ for (String t : tries) {
+ Integer value = parseIntegerQuietly(HisCheckCodeEnum.getByCode(t));
+ if (value != null) {
+ return value;
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * 鎷嗗垎銆屽彲鑳界殑澶氬�笺�嶅瓧娈点��
+ * <p>
+ * 鍏堣繑鍥�**鏁翠綋**锛堣鐩栧崟鍊煎満鏅紝涔熼伩鍏嶆妸鍚嶇О閲屾湰灏卞惈閫楀彿鐨勯」鎷嗗潖锛夛紝
+ * 鍐嶈繑鍥炴寜 {@code ,} / {@code 锛寎 鎷嗗嚭鐨勫悇娈点��
+ */
+ private List<String> splitMultiValue(String raw) {
+ List<String> result = new ArrayList<>();
+ if (StringUtils.isEmpty(raw)) {
+ return result;
+ }
+ result.add(raw);
+ for (String part : raw.split("[,锛宂")) {
+ String p = part == null ? "" : part.trim();
+ if (!p.isEmpty() && !p.equals(raw)) {
+ result.add(p);
+ }
+ }
+ return result;
+ }
+
/** {@code appointment.remark} 鍒楀涓婇檺锛堣 08_fix_remark_length.sql锛屽綋鍓� varchar(2000)锛� */
private static final int REMARK_MAX_LEN = 2000;
/** {@code appointment.room_name} 鍒楀涓婇檺 */
@@ -1139,6 +1475,27 @@
/** HIS 鎶ユ枃涓�屽尰鍢卞彿/鍖诲槺ID銆嶇殑 id root锛堣銆婁氦浜掓湇鍔¢�氱敤鎺ュ彛鏂囨。銆�6.1 / 6.4 / 6.5锛� */
private static final String ORDER_NO_ROOT = "2.16.156.10011.1.28";
+
+ /**
+ * HIS銆屽紑鍗曟椂闂淬��({@code author/time/value}) 鐨勬椂闂存牸寮忋��
+ * 娉ㄦ剰锛歿@link SimpleDateFormat} **涓嶆槸绾跨▼瀹夊叏**鐨勶紝鏁呰繖閲屽彧淇濆瓨 pattern 瀛楃涓诧紝
+ * 姣忔閮芥柊寤哄疄渚嬶紙瑙� {@link #parseHisDoctorTime}锛夈��
+ */
+ private static final String HIS_DOCTOR_TIME_PATTERN = "yyyyMMddHHmmss";
+
+ /**
+ * 鍒ゆ柇 HIS 寮�鍗曟椂闂存槸鍚︿负銆屾棩鏈熷�笺�嶏紙褰㈠ {@code 20261001000000}锛屾椂鍒嗙鍏� 0锛夈��
+ *
+ * <p>鐢� {@code endsWith} 鑰屼笉鏄鍒欙細璇箟鐩寸櫧涓旀棤杞箟鍧�
+ * 锛堟浘鍐欒繃 {@code value.matches("\\d{6}000000")}锛屽洜杞箟灞傜骇鍑洪敊瀵艰嚧姘镐笉鍖归厤锛夈��
+ */
+ private boolean isHisTimeOnlyDate(String value) {
+ if (value == null || value.length() != 14) {
+ return false;
+ }
+ // 鍚� 6 浣嶏紙HHmmss锛夊叏涓� '0' 鍗充负銆屾棩鏈熷�笺�嶅舰鎬�
+ return value.endsWith("000000");
+ }
/**
* 鍦� HL7 鐨� {@code id} 鑺傜偣涓紝鎸� {@code root} 鍖归厤骞跺彇鍑� {@code extension}銆�
@@ -1442,6 +1799,15 @@
if (roomName != null && StringUtils.isNotEmpty(roomName.toString())) {
appointment.setRoomName(truncate(roomName.toString(), ROOM_NAME_MAX_LEN));
}
+ // 妫�鏌ョ被鍨嬶細**浠呭湪涓虹┖鏃惰ˉ**
+ // 绛栫暐 (a)锛氫笉瑕嗙洊宸叉湁鍊硷紝閬垮厤鏀瑰潖鏁版嵁锛堜緥濡傝鍗曟浘鐢� S0201ECG 姝g‘鍐欏叆杩囩被鍨嬶級銆�
+ // 涓庡閿欐柊澧炲垎鏀繚鎸佸悓涓�閫昏緫銆�
+ if (appointment.getBookCheckType() == null) {
+ Integer checkTypeValue = resolveBookCheckTypeFromZdy(zdy, applyNo);
+ if (checkTypeValue != null) {
+ appointment.setBookCheckType(checkTypeValue);
+ }
+ }
}
// 棰勭害鎺掑簭鍙凤紙patient.id.item[4]锛�
Integer seqNum = extractBookSeqNum(actAppointment);
@@ -1548,6 +1914,23 @@
appointment.setBookSrc(bookSrcValue);
appointment.setStatus(status);
+ // 鎮h�呮潵婧愶紙pat_src锛夛細涓� S0201ECG 淇濇寔鍚屼竴鍋氭硶 鈥斺�� 鐩存帴鍙栨姤鏂囦腑鐨勬偅鑰呯被鍨嬩唬鐮併��
+ //
+ // 鈿狅笍 宸茬煡椋庨櫓锛堜繚鐣欑幇鐘讹紝涓嶅湪鏈鏀瑰姩鑼冨洿鍐咃級锛�
+ // 瀹炴祴 S050401 鎶ユ枃瀵规湰鏉′綋妫�鍗曠粰鍑虹殑鏄� code=3 / displayName=浣撴锛�
+ // 鑰屾湰鍦板瓧鍏革紙ecg_patient_source锛変笌鏁版嵁鍒嗗竷閮借〃鏄庛�屼綋妫� = 4銆佷綇闄� = 3銆嶏細
+ // 鍏ㄥ簱 pat_src=4 鐨� 55,729 鏉$瀹ゅ潎涓恒�屽仴搴风鐞嗕腑蹇冦�嶏紝88 鍓嶇紑锛堜綋妫�锛夊崟 55,874 鏉′负 pat_src=4銆�
+ // 鍗虫姤鏂� code 涓庢湰鍦板瓧鍏哥紪鐮佸苟涓嶄竴鑷淬�傛澶�**鍒绘剰娌跨敤鎶ユ枃鍘熷��**浠ヤ笌 S0201ECG 琛屼负涓�鑷达紝
+ // 濡傞渶鎸夊悕绉扮籂姝o紙浣撴鈫�4锛夛紝搴旂粺涓�鍦ㄤ袱澶勪竴璧锋敼锛岄伩鍏嶄袱鏉℃祦鍐欏嚭涓嶅悓鍊笺��
+ Map<String, Object> codeNode = (Map<String, Object>) actAppointment.get("code");
+ Integer patSrcValue = codeNode == null ? null : parseIntegerQuietly(str(codeNode.get("code")));
+ if (patSrcValue != null) {
+ appointment.setPatSrc(patSrcValue);
+ } else {
+ log.warn("[insertAppointmentFromCheckAppointment][鎶ユ枃缂烘偅鑰呯被鍨�(actAppointment.code.code)锛�"
+ + "pat_src 灏嗕负绌篯 applyNo={} code={}", applyNo, codeNode);
+ }
+
Map<String, Object> zdy = (Map<String, Object>) actAppointment.get("ZDY");
// ZDY 涓殑 remark锛堟敞鎰忎簨椤癸級涓� roomname锛堟埧闂村悕绉帮級宸查殢琛ㄦ柊澧炲垪钀藉簱锛�
// area锛堜綅缃級涓� roomcode锛堟埧闂寸紪鐮侊級鐩墠浠嶆棤瀵瑰簲鍒楋紝鏆備笉淇濆瓨銆�
@@ -1559,6 +1942,18 @@
Object roomName = zdy.get("roomname");
if (roomName != null && StringUtils.isNotEmpty(roomName.toString())) {
appointment.setRoomName(truncate(roomName.toString(), ROOM_NAME_MAX_LEN));
+ }
+ // 妫�鏌ョ被鍨嬶細鎶ユ枃閲岀殑 ZDY.jcxmcode / ZDY.jcxmname
+ //
+ // 銆愪慨澶嶃�戝師鍏堟澶�**瀹屽叏娌℃湁**瑙f瀽妫�鏌ョ被鍨嬶紝瀵艰嚧銆孲050401 鍏堝埌銆佷笖灏氭棤 S0201ECG 璁板綍銆�
+ // 鏃跺閿欐柊澧炲嚭鏉ョ殑 appointment.book_check_type 姘歌繙涓虹┖銆�
+ // 瀹炴祴 2026-09-29~10-09 鍏� 279 鏉★紙濡� apply_no=8826092420371106锛�
+ // 鎶ユ枃 ZDY 閲� jcxmcode=201652 / jcxmname=骞虫澘杩愬姩璇曢獙 鏄庢槑瀛樺湪锛夈��
+ if (appointment.getBookCheckType() == null) {
+ Integer checkTypeValue = resolveBookCheckTypeFromZdy(zdy, applyNo);
+ if (checkTypeValue != null) {
+ appointment.setBookCheckType(checkTypeValue);
+ }
}
}
// 棰勭害鎺掑簭鍙凤紙patient.id.item[4]锛�
@@ -1584,6 +1979,17 @@
}
if (patIdItems.size() > 3) {
appointment.setHospitalNo((String) ((Map<String, Object>) patIdItems.get(3)).get("extension"));
+ }
+ // 灏辫瘖娴佹按鍙凤紙episode_id锛夛細patient.id.item[5]
+ //
+ // 涓� S0201ECG 鍚屾簮锛堥偅杈瑰彇鑷� placerGroup.componentOf1.encounter.id.item[1]锛�
+ // 瀹炴祴涓ゅ鍊肩浉鍚岋細鏈潯鍧囦负 882609242037锛夈��
+ // 銆愪慨澶嶃�戝師鍏堝閿欐柊澧�**瀹屽叏娌℃湁**鍐欏叆灏辫瘖娴佹按鍙凤紝瀵艰嚧璇ュ瓧娈典负绌恒��
+ if (patIdItems.size() > 5) {
+ String episodeId = (String) ((Map<String, Object>) patIdItems.get(5)).get("extension");
+ if (StringUtils.isNotEmpty(episodeId)) {
+ appointment.setEpisodeId(episodeId);
+ }
}
// 棰勭害鎺掑簭鍙峰凡鍦ㄤ笂鏂归�氳繃 extractBookSeqNum 缁熶竴璧嬪�硷紝姝ゅ涓嶅啀閲嶅澶勭悊
// 鎮h�呭鍚�
@@ -1628,8 +2034,84 @@
log.warn("[insertAppointmentFromCheckAppointment][鎶ユ枃鏈彁渚涙偅鑰呮�у埆锛屾寜鏈煡(0)鍐欏叆] applyNo={}", applyNo);
appointment.setPatGender(UNKNOWN_GENDER);
}
+ // 鎮h�呭浐鏈夊睘鎬у洖濉紙鐢熸棩 / 鐢佃瘽 / 韬唤璇� / 鍦板潃锛�
+ //
+ // 銆愪负浠�涔堥渶瑕併�慡050401 鎶ユ枃鐨� patient.patientPerson **鍙甫濮撳悕**锛�
+ // 涓嶅惈鐢熸棩/鐢佃瘽/韬唤璇侊紙S0201ECG 鏈夈�丼0405 涔熸湁锛屼絾杩欎袱鏉℃姤鏂囧湪鏈満鏅病鏈夊厛鍒帮級锛�
+ // 浜庢槸瀹归敊鏂板鍑烘潵鐨勮褰曡繖浜涘瓧娈靛叏涓虹┖锛屼笌 S0201ECG 寤虹殑鍗曠浉姣�"缂哄瓧娈�"銆�
+ //
+ // 銆愪负浠�涔堣繖鏍疯ˉ鏄噯纭殑銆戣繖浜涙槸**鎮h�呭浐鏈夊睘鎬�**锛堜笉鏄祦姘村睘鎬э級锛�
+ // 鍚屼竴 pat_id 鐨勫巻鍙茶褰曢噷蹇呯劧涓�鑷达紙鍏ㄥ簱濉厖鐜� 99%锛夈��
+ // 娉ㄦ剰锛氬紑鍗曞尰鐢�/寮�鍗曟椂闂村睘娴佹按灞炴�э紝**鍒绘剰涓嶇户鎵�**锛堥偅灞炰簬鎺ㄦ柇锛屽彲鑳藉紶鍐犳潕鎴达級銆�
+ inheritPatientDemographics(appointment, applyNo);
+
AppointmentSaveReqVO saveReqVO = BeanUtils.toBean(appointment, AppointmentSaveReqVO.class);
createAppointment(saveReqVO);
+ }
+
+ /**
+ * 瀹归敊鏂板鏃讹紝浠庤鎮h�呮渶杩戜竴鏉¤褰曠户鎵�**鎮h�呭浐鏈夊睘鎬�**銆�
+ *
+ * <p>鍙ˉ銆屾湰娆′负绌恒�嶇殑瀛楁锛岀粷涓嶈鐩栨姤鏂囧凡鎻愪緵鐨勫�笺��
+ * 缁ф壙澶辫触锛堟棤鍘嗗彶璁板綍 / 鏌ヨ寮傚父锛変笉褰卞搷钀藉簱锛屼粎璁版棩蹇椼��</p>
+ *
+ * <p><b>鍒绘剰涓嶇户鎵�</b>鐨勫瓧娈碉細{@code doctor}/{@code doctor_code}/{@code doctor_time}
+ * 锛堝紑鍗曞尰鐢熶笌寮�鍗曟椂闂村睘娴佹按灞炴�э紝鎶ユ枃鏈彁渚涙椂鍙兘鎺ㄦ柇锛屽疄娴嬪悓鎮h�呭悓鏃ヤ竴鑷寸巼 90%锛�
+ * 瀛樺湪寮犲啝鏉庢埓椋庨櫓锛屾晠鎸変笟鍔$‘璁や繚鎸佷负绌猴級銆亄@code register_date}
+ * 锛堝彧搴斿湪 HIS 鎶ャ�屾鏌ョ櫥璁般�嶇姸鎬佹椂鍐欏叆锛夈��</p>
+ *
+ * @param target 鏈瀹归敊鏂板鐨勫璞★紙灏卞湴琛ュ叏锛�
+ * @param applyNo 鐢宠鍗曞彿锛屼粎鐢ㄤ簬鏃ュ織
+ */
+ private void inheritPatientDemographics(AppointmentDO target, String applyNo) {
+ if (StringUtils.isEmpty(target.getPatId())) {
+ return;
+ }
+ // 涓夐」鍏抽敭浜哄彛瀛︿俊鎭姤鏂囬兘缁欎簡灏辨棤闇�缁ф壙锛堟姤鏂囧�间紭鍏堬級
+ if (target.getPatBirthday() != null
+ && StringUtils.isNotEmpty(target.getPatIdentityId())
+ && StringUtils.isNotEmpty(target.getPatMobile())) {
+ return;
+ }
+ AppointmentDO sibling;
+ try {
+ sibling = appointmentMapper.getLatestByPatId(target.getPatId());
+ } catch (Exception e) {
+ log.warn("[inheritPatientDemographics][鏌ヨ鍚屾偅鑰呭巻鍙茶褰曞け璐ワ紝璺宠繃缁ф壙] applyNo={} patId={} err={}",
+ applyNo, target.getPatId(), e.getMessage());
+ return;
+ }
+ if (sibling == null) {
+ log.warn("[inheritPatientDemographics][璇ユ偅鑰呮棤鍘嗗彶璁板綍鍙户鎵匡紝鎮h�呬俊鎭皢涓嶅畬鏁碷 "
+ + "applyNo={} patId={}", applyNo, target.getPatId());
+ return;
+ }
+ StringBuilder inherited = new StringBuilder();
+ if (target.getPatBirthday() == null && sibling.getPatBirthday() != null) {
+ target.setPatBirthday(sibling.getPatBirthday());
+ inherited.append("pat_birthday ");
+ }
+ if (StringUtils.isEmpty(target.getPatIdentityId()) && StringUtils.isNotEmpty(sibling.getPatIdentityId())) {
+ target.setPatIdentityId(sibling.getPatIdentityId());
+ inherited.append("pat_identity_id ");
+ }
+ if (StringUtils.isEmpty(target.getPatMobile()) && StringUtils.isNotEmpty(sibling.getPatMobile())) {
+ target.setPatMobile(sibling.getPatMobile());
+ inherited.append("pat_mobile ");
+ }
+ if (StringUtils.isEmpty(target.getPatPhone()) && StringUtils.isNotEmpty(sibling.getPatPhone())) {
+ target.setPatPhone(sibling.getPatPhone());
+ inherited.append("pat_phone ");
+ }
+ if (StringUtils.isEmpty(target.getPatAddr()) && StringUtils.isNotEmpty(sibling.getPatAddr())) {
+ target.setPatAddr(sibling.getPatAddr());
+ inherited.append("pat_addr ");
+ }
+ if (inherited.length() > 0) {
+ log.info("[inheritPatientDemographics][S050401 鎶ユ枃涓嶅惈鎮h�呬汉鍙e淇℃伅锛�"
+ + "宸蹭粠鍚屾偅鑰呮渶杩戣褰曠户鎵縘 applyNo={} patId={} fromApplyNo={} fields=[{}]",
+ applyNo, target.getPatId(), sibling.getApplyNo(), inherited.toString().trim());
+ }
}
/** 瑙f瀽 {@code yyyyMMddHHmmss} 鏃堕棿锛屽け璐ユ垨涓虹┖杩斿洖 null锛堜笉鎶涘紓甯革級 */
@@ -1641,6 +2123,96 @@
return LocalDateTime.parse(value.trim(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
} catch (Exception e) {
log.warn("[parseDateTime][鏃堕棿鏍煎紡闈炴硶锛屽拷鐣 value={}", value);
+ return null;
+ }
+ }
+
+ /**
+ * 瑙f瀽 HIS 鎶ユ枃涓殑銆屽紑鍗曟椂闂淬��({@code author/time/value})銆�
+ *
+ * <h3>鑳屾櫙锛堝疄娴嬬粨璁猴紝2026-10 鎺掓煡锛�</h3>
+ * 搴撲腑绾� <b>61%</b> 鐨� {@code appointment.doctor_time} 涓� {@code yyyy-MM-dd 00:00:00}銆�
+ * 缁忔牳鏌�**涓嶆槸**鏈」鐩殑鏍煎紡鍖栫己闄凤細
+ * <ul>
+ * <li>鍒楃被鍨嬫槸 {@code datetime}锛屽啓鍏ョ殑鏄� {@code java.util.Date}锛屼繚鐣欐椂鍒嗙锛�</li>
+ * <li>鐪熷疄鎶ユ枃鏍蜂緥涓瀛楁褰㈠ {@code 20260917005255}锛堝甫鏃跺垎绉掞級锛�</li>
+ * <li>鏈夌湡瀹炴椂鍒荤殑璁板綍鍛堟甯稿伐浣滄椂娈靛垎甯冿紙06:00鈫�08:00 涓洪珮宄帮級锛�
+ * 鑰岃惤鍦ㄥ紑璇婂墠鐨� 00:00-05:59 鐨勪粎 15 鏉� 鈥斺�� 璇存槑璇ユ椂娈垫湰灏卞嚑涔庝笉寮�鍗曪紱</li>
+ * <li>鎸夊氨璇婄被鍒湅锛氶棬璇�({@code book_src=1}) 99.6%銆佷綇闄�({@code book_src=2}) 90.5%
+ * 涓� 0 鐐癸紝涓旇鐜拌薄璐┛ 2026 鍏ㄥ勾锛堜笌 2026-09-27 鐨� {@code register_date}
+ * 鎴柇缂洪櫡鏃犲叧锛夈��</li>
+ * </ul>
+ * 鈬� 缁撹锛�**鏄� HIS 渚ф妸璇ュ瓧娈电殑鏃跺垎绉掑彂鎴愪簡 {@code 000000}**锛堝緢鍙兘鏄�屽彧绮剧‘鍒版棩銆�
+ * 鎴栬ˉ褰�/鎵归噺鍥炰紶鐨勫尰鍢憋級銆�
+ *
+ * <h3>鏈柟娉曞仛浠�涔�</h3>
+ * <ul>
+ * <li>鎸� {@code yyyyMMddHHmmss} 瑙f瀽锛�</li>
+ * <li>璇嗗埆銆屾椂鍒嗙 = 000000銆嶇殑**鏃ユ湡鍊�**锛屾墦鍑哄甫**鍘熷鎶ユ枃鍊� + 鐢宠鍗曞彿**鐨� WARN
+ * 鈥斺�� 鍘熷疄鐜板彧 {@code printStackTrace()}锛屽嚭闂鏃舵棤浠庡畾浣嶏紱</li>
+ * <li><b>浠嶇劧鍐欏叆</b>锛堜繚鐣欐棩鏈熼儴鍒嗭級锛氬洜涓恒�岃窛浠婂ぉ鏁般�嶃�屾寜鏃ユ湡鎺掑簭/绛涢�夈�嶉兘鐢ㄦ棩鏈燂紝
+ * 鍐欏叆 NULL 浼氳杩欎簺鍔熻兘閫�鍖栵紝涓旇鍊肩‘涓� HIS 鎵�鍙戙�佸師鏍蜂繚瀛樻洿鍙拷婧��</li>
+ * </ul>
+ *
+ * @param rawValue HIS 鎶ユ枃鍘熷�硷紙褰㈠ {@code 20260917005255}锛�
+ * @param applyNo 鐢宠鍗曞彿锛屼粎鐢ㄤ簬鏃ュ織瀹氫綅
+ * @return 瑙f瀽鍚庣殑鏃堕棿锛涙牸寮忛潪娉曟椂杩斿洖 {@code null}锛堜笉鍐欏簱锛�
+ */
+ private java.util.Date parseHisDoctorTime(String rawValue, String applyNo) {
+ String v = rawValue == null ? null : rawValue.trim();
+ if (StringUtils.isEmpty(v)) {
+ return null;
+ }
+ if (!v.matches("\\d{14}")) {
+ // 瀹炴祴 HIS 鏂囨。鏍蜂緥涓瓨鍦� 12 浣嶏紙yyyyMMddHHmm锛夌敋鑷崇┖鍊硷紝缁熶竴璁� WARN 渚夸簬鍚� HIS 鍙嶉
+ log.warn("[parseHisDoctorTime][寮�鍗曟椂闂存牸寮忛潪 14 浣嶏紝鏃犳硶瑙f瀽锛宒octor_time 灏嗕负绌篯 "
+ + "applyNo={} raw={} length={}", applyNo, v, v.length());
+ return null;
+ }
+ try {
+ // 鈿狅笍 蹇呴』 setLenient(false)锛歋impleDateFormat 榛樿瀹芥澗锛�
+ // 浼氭妸闈炴硶鏃ユ湡闈欓粯婊氭垚鍚堟硶鍊硷紙濡� 13 鏈� 鈫� 娆″勾 1 鏈堬級锛屽鑷磋剰鏁版嵁鍏ュ簱銆�
+ // 瀹炴祴锛歭enient 涓� "20261301000000" 琚В鏋愭垚 2027-01-01 涓斾笉鎶ラ敊銆�
+ SimpleDateFormat sdf = new SimpleDateFormat(HIS_DOCTOR_TIME_PATTERN);
+ sdf.setLenient(false);
+ java.util.Date parsed = sdf.parse(v);
+ if (isHisTimeOnlyDate(v)) {
+ log.warn("[parseHisDoctorTime][HIS 寮�鍗曟椂闂存椂鍒嗙涓� 000000锛堟棩鏈熷�硷級锛�"
+ + "doctor_time 灏嗕繚瀛樹负褰撴棩 00:00:00 鈥斺�� 璇ュ�肩敱 HIS 鎶ユ枃鍘熸牱鑰屾潵] "
+ + "applyNo={} raw={}", applyNo, v);
+ }
+ return parsed;
+ } catch (Exception e) {
+ log.warn("[parseHisDoctorTime][寮�鍗曟椂闂磋В鏋愬け璐ワ紝doctor_time 灏嗕负绌篯 applyNo={} raw={} err={}",
+ applyNo, v, e.getMessage());
+ return null;
+ }
+ }
+
+ /**
+ * 鐢� {@code book_timeslot}锛坔hmmhhmm锛屽 8000830=08:00-08:30銆�13301400=13:30-14:00锛夊彇棰勭害鏃跺埢锛堝彧鍚椂鍒嗭級銆�
+ * <p>鐢ㄦ潵缁� S0201ECG 杩欐潯娴佽ˉ {@code book_time}锛氬師瀹炵幇鏁存潯娴佷笉鍐欓绾︽椂闂达紝
+ * 寤哄嚭鏉ョ殑璁板綍 book_date/book_timeslot/book_time 鍏ㄧ┖锛堝疄娴� 211741銆�211962锛夈��</p>
+ */
+ private LocalTime timeOfTimeslot(Integer timeslot) {
+ if (timeslot == null) {
+ return null;
+ }
+ try {
+ String s = String.valueOf(timeslot);
+ if (s.length() < 5) {
+ return null;
+ }
+ String start = s.substring(0, s.length() - 4); // 鍓嶄竴娈� = 寮�濮嬫椂闂� hhmm
+ int hhmm = Integer.parseInt(start);
+ int hour = hhmm / 100;
+ int minute = hhmm % 100;
+ if (hour > 23 || minute > 59) {
+ return null;
+ }
+ return LocalTime.of(hour, minute);
+ } catch (Exception e) {
+ log.warn("[timeOfTimeslot][鏃堕棿娈佃В鏋愬け璐ワ紝蹇界暐] timeslot={}", timeslot);
return null;
}
}
@@ -1680,6 +2252,38 @@
}
}
+ /**
+ * 銆愭湰闇�姹傦細绱ф�ユ偅鑰呬笉鎺掗槦鐩存帴妫�鏌ャ�戞寜銆岀敵璇峰崟鍙� / 灏辫瘖鍙� / 鎮h�呯紪鍙枫�嶆煡杩戜竴涓湀鐨勯绾﹁褰曘��
+ * <p>
+ * 绐楀彛 [浠婂ぉ-30 澶�, 浠婂ぉ+30 澶锛屾寜鏈獥鍙e紑灞曠殑妫�鏌ラ」鐩繃婊わ紝缁撴灉鎸�**棰勭害鏃堕棿鍊掑簭**銆�
+ */
+ @Override
+ public List<AppointmentDO> getEmergencyCandidates(String code, String checkTypes) {
+ if (StringUtils.isEmpty(code)) {
+ return new ArrayList<>();
+ }
+ List<Integer> checkTypeList = splitToIntList(checkTypes);
+ List<AppointmentDO> list = appointmentMapper.getEmergencyCandidates(code.trim(), checkTypeList);
+ log.info("[getEmergencyCandidates] 绱ф�ュ姞鍋氬�欓�夋煡璇�. code={} checkTypes={} 鍛戒腑={}",
+ code, checkTypes, null == list ? 0 : list.size());
+ return null == list ? new ArrayList<>() : list;
+ }
+
+ /** 鎶� `100,200` 杩欑被閫楀彿鍒嗛殧涓茶В鏋愭垚 List<Integer>锛涢潪娉曢」蹇界暐 */
+ private List<Integer> splitToIntList(String raw) {
+ List<Integer> result = new ArrayList<>();
+ if (StringUtils.isEmpty(raw)) {
+ return result;
+ }
+ for (String part : raw.split("[,锛宂")) {
+ Integer v = parseIntegerQuietly(part);
+ if (null != v && !result.contains(v)) {
+ result.add(v);
+ }
+ }
+ return result;
+ }
+
/** 瀹芥澗 Byte 瑙f瀽锛氶潪鏁板瓧鎴栫┖杩斿洖 null锛堢敤浜庢偅鑰呮�у埆绛� tinyint 瀛楁锛� */
private Byte parseByteQuietly(String value) {
if (StringUtils.isEmpty(value) || !value.trim().matches("-?\\d+")) {
--
Gitblit v1.9.3