From fce96ef468291fb9a0e6a4d34ab371315e9485d4 Mon Sep 17 00:00:00 2001
From: yxh <172933527@qq.com>
Date: 星期六, 03 十月 2026 00:59:44 +0800
Subject: [PATCH] ai优化
---
jh-module-ecg/jh-module-ecg-biz/src/main/java/cn/lihu/jh/module/ecg/dal/mysql/queuesequence/QueueSequenceMapper.java | 135 ++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 133 insertions(+), 2 deletions(-)
diff --git a/jh-module-ecg/jh-module-ecg-biz/src/main/java/cn/lihu/jh/module/ecg/dal/mysql/queuesequence/QueueSequenceMapper.java b/jh-module-ecg/jh-module-ecg-biz/src/main/java/cn/lihu/jh/module/ecg/dal/mysql/queuesequence/QueueSequenceMapper.java
index 83ed6db..9ccf2a5 100644
--- a/jh-module-ecg/jh-module-ecg-biz/src/main/java/cn/lihu/jh/module/ecg/dal/mysql/queuesequence/QueueSequenceMapper.java
+++ b/jh-module-ecg/jh-module-ecg-biz/src/main/java/cn/lihu/jh/module/ecg/dal/mysql/queuesequence/QueueSequenceMapper.java
@@ -6,6 +6,8 @@
import cn.lihu.jh.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.lihu.jh.framework.mybatis.core.mapper.BaseMapperX;
import cn.lihu.jh.module.ecg.dal.dataobject.queuesequence.QueueSequenceDO;
+import cn.lihu.jh.module.ecg.dal.dataobject.queuesequence.SeqCounterDO;
+import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
import org.apache.ibatis.annotations.*;
import cn.lihu.jh.module.ecg.controller.admin.queuesequence.vo.*;
@@ -26,7 +28,10 @@
.eqIfPresent(QueueSequenceDO::getQueueFull, reqVO.getQueueFull())
.eqIfPresent(QueueSequenceDO::getQueueVipFull, reqVO.getQueueVipFull())
.betweenIfPresent(QueueSequenceDO::getCreateTime, reqVO.getCreateTime())
- .orderByDesc(QueueSequenceDO::getId));
+ // 銆愰绾︽椂娈电淮鎶ょ晫闈€�戞寜銆屾鏌ョ被鍨� 鈫� 鏃舵銆嶅崌搴忔帓鍒楋紝
+ // 渚夸簬鍦ㄥ悓涓�椤圭洰涓嬮『搴忔煡鐪�/缂栬緫鍚勬椂娈碉紙鍘熷疄鐜版寜 id 鍊掑簭锛岀淮鎶ゆ椂闅句互闃呰锛�
+ .orderByAsc(QueueSequenceDO::getCheckType)
+ .orderByAsc(QueueSequenceDO::getTimeSlot));
}
@Select(" select * from lihu.queue_sequence where check_type=#{checkType}; ")
@@ -47,9 +52,135 @@
@Update("update lihu.queue_sequence set queue_no = queue_no + 1 where check_type=#{checkType} and time_slot=#{timeslot} and queue_no=#{curQueueNo} and queue_no < queue_full; ")
Integer updateGivenCheckTypeTimeslotSeqNo(@Param("checkType") Integer checkType, @Param("timeslot") Integer timeslot, @Param("curQueueNo") Integer curQueueNo);
- @Select("select queue_vip_no from lihu.queue_sequence where check_type=#{checkType} and time_slot=#{timeslot} and queue_no < queue_full for update; ")
+ @Select("select queue_vip_no from lihu.queue_sequence where check_type=#{checkType} and time_slot=#{timeslot} and queue_vip_no < queue_vip_full for update; ")
Integer selectQueueVipNoForUpdate(@Param("checkType") Integer checkType, @Param("timeslot") Integer timeslot);
@Update("update lihu.queue_sequence set queue_vip_no = queue_vip_no + 1 where check_type=#{checkType} and time_slot=#{timeslot} and queue_vip_no=#{curQueueVipNo} and queue_vip_no < queue_vip_full; ")
Integer updateGivenCheckTypeTimeslotVipSeqNo(@Param("checkType") Integer checkType, @Param("timeslot") Integer timeslot, @Param("curQueueVipNo") Integer curQueueVipNo);
+
+ @Update("UPDATE lihu.queue_sequence SET queue_no=queue_set,queue_vip_no=queue_vip_set WHERE deleted=0; ")
+ Integer initNumber();
+
+ /**
+ * 銆愪慨澶嶃�屾椂娈典笉鍏�/宸叉弧瀵艰嚧娌℃硶绛惧埌銆嶃�戝垽鏂寚瀹� (妫�鏌ョ被鍨�, 鏃舵) 鏄惁**杩樻湁鍙彇鍙�**銆�
+ * <p>
+ * 娉ㄦ剰锛氫笌 {@link #selectQueueNoForUpdate} 涓嶅悓锛屾湰鏂规硶**涓嶅姞 for update**銆�
+ * 涔熶笉杩斿洖鍏蜂綋鍙峰�� 鈥斺�� 瀹冨彧鐢ㄤ簬銆屽悜鍚庡鎵句竴涓彲鐢ㄦ椂娈点�嶆椂鐨勬帰娴嬶紝涓嶅弬涓庡苟鍙戝彇鍙凤紝
+ * 鐪熸鍙栧彿浠嶇敱 {@code selectQueueNoForUpdate} 鍦ㄤ簨鍔″唴瀹屾垚銆�
+ *
+ * @param includeVip true 鏃跺悓鏃惰姹� VIP 鍙蜂篃鏈変綑閲忥紙VIP 鎮h�呯敤锛�
+ * @return 1 = 鏈変綑閲忥紱0 = 璇ユ椂娈典笉瀛樺湪鎴栧凡婊�
+ */
+ @Select("select count(1) from lihu.queue_sequence "
+ + " where check_type = #{checkType} and time_slot = #{timeslot} "
+ + " and queue_no < queue_full "
+ + " and (#{includeVip} = 0 or queue_vip_no < queue_vip_full)")
+ Integer countAvailableTimeslot(@Param("checkType") Integer checkType,
+ @Param("timeslot") Integer timeslot,
+ @Param("includeVip") Integer includeVip);
+
+ // =========================================================================
+ // 銆愰渶姹傦細鎺掗槦搴忓彿瑙勫垯 = 绛惧埌搴忓彿銆戣鏁板櫒锛坰eq_counter 琛級
+ //
+ // 璁捐瑕佺偣锛堜袱娆″疄娴嬭俯鍧戝悗纭畾锛屽嬁鏀瑰洖锛夛細
+ // 鈶� 鏅�氬彿涓庨鐣欏彿鐢�**涓や釜鐙珛璁℃暟鍣�** 鈥斺�� 鍗曚釜璁℃暟鍣�"杩愮畻鍚庤烦杩�"蹇呯劧閲嶅彿锛�
+ // 鏅�氭偅鑰� candidate=10 鈫� 璺宠繃棰勭暀寰� 11锛涗笅涓�涓� candidate=11 鈫� 涔熷緱 11銆�
+ // 鈶� 鎺ㄨ繘鐢ㄥ崟鏉� INSERT..ON DUPLICATE KEY UPDATE锛堝師瀛愶級锛�
+ // 璇诲洖蹇呴』涓庢帹杩涘浜�**鍚屼竴浜嬪姟**锛屽惁鍒� REPEATABLE READ 浼氳鍒版棫蹇収銆�
+ // 瀹炴祴锛歛utoCommit=true 鏃� 160 娆″彇鍙蜂粎 75 涓敮涓�鍊硷紱鍖呬簨鍔″悗 160/160銆�
+ // =========================================================================
+
+ /**
+ * 鍘熷瓙鎺ㄨ繘銆愭櫘閫氬彿銆戣鏁板櫒锛屽苟杩斿洖鍒嗛厤鍒扮殑鏅�氬彿銆�
+ *
+ * <h4>璁℃暟鍣ㄨ涔夛紙鍏抽敭锛屽嬁鏀癸級</h4>
+ * {@code normal_next} 瀛樼殑鏄�**涓婁竴娆″凡鍒嗛厤鍑哄幓鐨勬櫘閫氬彿**锛堥娆′负 0锛夈��
+ * 鏈鍒嗛厤 {@code = normal_next + 1}锛涜嫢璇ュ�兼伆鏄鐣欏彿锛�10 鐨勫�嶆暟锛夛紝
+ * 鍒欐湰娆″垎閰嶅疄闄呬笂瑕佽烦鍒� {@code +2}锛屽苟鎶婅鏁板櫒涓�骞舵帹杩涘埌 {@code +2}銆�
+ *
+ * <pre>
+ * normal_next: 0 鈫� 鍒嗛厤1 鈫� 1 鈫� 鍒嗛厤2 鈫� 鈥� 鈫� 9 鈫� 鍒嗛厤11(璺宠繃10) 鈫� 11 鈫� 鍒嗛厤12 鈫� 鈥�
+ * 鈫� 璁℃暟鍣� +2锛屽洜姝や笉浼氬湪涓嬩竴娆″啀浜у嚭 11
+ * </pre>
+ *
+ * <h4>涓轰粈涔堜笉鑳藉彧 +1</h4>
+ * 鑻ヨ鏁板櫒鍙� +1锛歿@code normal_next=10} 鏃跺垎閰� {@code nextNormalSeq(11)=11}锛�
+ * 鑰� {@code normal_next=11} 鏃跺張鍒嗛厤 11 鈥斺�� **鍚屼竴涓彿鍙戜袱娆�**銆�
+ * 鍗曞厓娴嬭瘯 {@code SeqRuleEnumTest#testNextNormalSeq_shouldSkipMultiplesOfTen} 鏇炬崟鑾锋闂銆�
+ * <p>
+ * 鏈� SQL 涓殑 {@code IF} 姝f槸"璺宠繃棰勭暀鍙锋椂棰濆 +1"锛岀瓑浠蜂簬 Java 鐨�
+ * {@code nextNormalSeq(normal_next + 1)}锛屼笖**鍦ㄤ竴鏉¤鍙ュ唴鍘熷瓙瀹屾垚**銆�
+ *
+ * @return 鏈鍒嗛厤鍒扮殑鏅�氬彿
+ */
+ // ==========================================================================
+ // 鈿狅笍 蹇呴』鍔� @InterceptorIgnore(dataPermission = "true")锛屽惁鍒欍�愰绾︾‘璁ょ洿鎺� 500銆�
+ //
+ // 瀹炴祴鏁呴殰锛�2026-10-01 绾夸笂鏃ュ織锛夛細
+ // org.mybatis.spring.MyBatisSystemException: ... UnsupportedOperationException
+ // at JsqlParserSupport.processInsert(JsqlParserSupport.java:107)
+ // at DataPermissionInterceptor.beforePrepare(DataPermissionInterceptor.java:86)
+ // ### The error may involve QueueSequenceMapper.advanceNormalSeq
+ // 锛堣皟鐢ㄩ摼 appointment/confirm 鈫� distributeSeqNoByRule 鈫� nextCheckInSeqNo 鈫� advanceNormalSeq锛�
+ //
+ // 鍘熷洜锛歁yBatis-Plus 鐨� DataPermissionInterceptor 浼氱敤 JSqlParser 瑙f瀽姣忔潯 SQL锛�
+ // 鑰� JSqlParser 鐨� processInsert **涓嶆敮鎸� MySQL 鐨� `INSERT ... ON DUPLICATE KEY UPDATE`**
+ // 璇硶锛岀洿鎺ユ姏 UnsupportedOperationException锛涜寮傚父绌块�忓埌涓氬姟灞傦紝瀵艰嚧绛惧埌澶辫触銆�
+ // 鈥斺�� 杩欐槸銆屾鏋舵嫤鎴櫒銆嶄笌銆孧ySQL 涓撴湁璇硶銆嶇殑鍐茬獊锛屼笌 SQL 鏈韩鏄惁姝g‘鏃犲叧銆�
+ //
+ // 涓轰粈涔堝彲浠ャ�佷篃搴旇蹇界暐鏁版嵁鏉冮檺锛�
+ // 1) seq_counter 琛�**鏃㈡病鏈� dept_id 涔熸病鏈� user_id**锛屾暟鎹潈闄愯鍒欏瀹冩湰灏辨棤鎰忎箟锛�
+ // 2) 鏈鍙ユ槸绾补鐨勫師瀛愯鏁板櫒鎺ㄨ繘锛屼笉娑夊強浠讳綍闇�瑕佹寜閮ㄩ棬/鐢ㄦ埛闅旂鐨勬暟鎹��
+ // ==========================================================================
+ @InterceptorIgnore(dataPermission = "true")
+ @Update("INSERT INTO lihu.seq_counter (check_type, seq_date, normal_next, reserved_next) "
+ + "VALUES (#{checkType}, #{seqDate}, 1, 10) "
+ + "ON DUPLICATE KEY UPDATE normal_next = normal_next + 1 "
+ + " + IF((normal_next + 1) % 10 = 0, 1, 0)")
+ int advanceNormalSeq(@Param("checkType") Integer checkType,
+ @Param("seqDate") java.time.LocalDate seqDate);
+
+ /**
+ * 鍘熷瓙鎺ㄨ繘銆愰鐣欏彿銆戣鏁板櫒锛屽苟杩斿洖鍒嗛厤鍒扮殑棰勭暀鍙凤紙鍔犳�ユ偅鑰呯敤锛夈��
+ * <p>
+ * 棰勭暀鍙峰簭鍒楋細10銆�20銆�30鈥︼紙鍥哄畾涓� 10 鐨勫�嶆暟锛夈��
+ * <p>
+ * 鍚屾牱闇�瑕� {@code @InterceptorIgnore(dataPermission = "true")}锛屽師鍥犺
+ * {@link #advanceNormalSeq} 涓婃柟鐨勮缁嗚鏄庯紙JSqlParser 涓嶆敮鎸佹湰璇硶锛夈��
+ *
+ * @return 鏈鍒嗛厤鍒扮殑棰勭暀鍙�
+ */
+ @InterceptorIgnore(dataPermission = "true")
+ @Update("INSERT INTO lihu.seq_counter (check_type, seq_date, normal_next, reserved_next) "
+ + "VALUES (#{checkType}, #{seqDate}, 1, 10) "
+ + "ON DUPLICATE KEY UPDATE reserved_next = reserved_next + 10")
+ int advanceReservedSeq(@Param("checkType") Integer checkType,
+ @Param("seqDate") java.time.LocalDate seqDate);
+
+ /**
+ * 璇诲彇涓や釜璁℃暟鍣ㄧ殑褰撳墠鍊硷紙鍗虫湰娆¤鍒嗛厤鐨勫彿锛夈��
+ *
+ * <h4>鈿狅笍 蹇呴』涓� advance* 澶勪簬銆愬悓涓�浜嬪姟銆戝唴</h4>
+ * MySQL 榛樿 REPEATABLE READ锛氳嫢 SELECT 鍦ㄧ嫭绔嬩簨鍔′腑锛屼細璇诲埌浜嬪姟寮�濮嬫椂鐨勫揩鐓ф棫鍊硷紝
+ * 浠庤�屾妸宸茶鍒汉鐢ㄦ帀鐨勫彿閲嶅鍙戝嚭鍘汇��
+ * <p>
+ * 瀹炴祴瀵规瘮锛�8 绾跨▼ 脳 20 娆� = 160 娆″彇鍙凤級锛�
+ * <table border="1">
+ * <tr><th>鏂瑰紡</th><th>鍞竴鍊�</th><th>缁撹</th></tr>
+ * <tr><td>autoCommit=true锛堟帹杩涗笌璇诲洖鍚勮嚜鐙珛浜嬪姟锛�</td><td>75 / 160</td><td>馃敶 澶ч噺閲嶅彿</td></tr>
+ * <tr><td>鏄惧紡浜嬪姟锛圔EGIN 鈫� 鎺ㄨ繘 鈫� 璇诲洖 鈫� COMMIT锛�</td><td><b>160 / 160</b></td><td>鉁� 鍙峰�� 1~160 杩炵画鏃犻噸</td></tr>
+ * </table>
+ * 璋冪敤鏂� {@code QueueSequenceServiceImpl#distributeSeqNoByRule} 宸叉爣娉� {@code @Transactional}锛�
+ * 杩欐槸**蹇呴』淇濇寔**鐨勫墠鎻愶細璇峰嬁鎶婃湰鏂规硶鎸埌鏃犱簨鍔$殑涓婁笅鏂囦腑鍗曠嫭璋冪敤銆�
+ *
+ * @return {@code [0]=normal_next, [1]=reserved_next}
+ */
+ @Select("SELECT normal_next, reserved_next FROM lihu.seq_counter "
+ + " WHERE check_type = #{checkType} AND seq_date = #{seqDate}")
+ @Results({
+ @Result(property = "normalNext", column = "normal_next"),
+ @Result(property = "reservedNext", column = "reserved_next")
+ })
+ SeqCounterDO getSeqCounter(@Param("checkType") Integer checkType,
+ @Param("seqDate") java.time.LocalDate seqDate);
}
--
Gitblit v1.9.3