| | |
| | | String label = readCellData.getStringValue(); |
| | | String value = DictFrameworkUtils.parseDictDataValue(type, label); |
| | | if (value == null) { |
| | | log.error("[convertToJavaData][type({}) è§£æä¸æ label({})]", type, label); |
| | | // ãæ¬éæ±ãä¸å¯¼åºæ¹åä¸è´ï¼åå
¸ç¼ºé¡¹å±æ°æ®é®é¢ï¼ç¨ WARN è䏿¯ ERRORï¼é¿å
导å
¥æ¶å·çº¢æ¥å¿ï¼ |
| | | log.warn("[convertToJavaData][type({}) æªæ¾å°åå
¸é¡¹ label({})ï¼æ null å¤ç]", type, label); |
| | | return null; |
| | | } |
| | | // å° String ç value è½¬æ¢æå¯¹åºç屿§ |
| | |
| | | String value = String.valueOf(object); |
| | | String label = DictFrameworkUtils.getDictDataLabel(type, value); |
| | | if (label == null) { |
| | | log.error("[convertToExcelData][type({}) 转æ¢ä¸äº label({})]", type, value); |
| | | // ãæ¬éæ±ãåå
¸é没æè¿ä¸ªå¼æ¶ï¼å±äº"æ°æ®æ²¡é
åå
¸"ï¼ä¸æ¯ç³»ç»éè¯¯ï¼ |
| | | // åæ¥ç¨ log.errorï¼å¯¼åº N è¡å°±ä¼å· N æ¡ ERRORï¼ä¾å¦"æ£è
æ§å«=0"å¨åå
¸é没æ 0ï¼ï¼ |
| | | // ç°åºççåç³»ç»åºæ
éãè¿éé为 WARNï¼ä»ä¿çå¯è¿½æº¯ä¿¡æ¯ã |
| | | // è¿åå¼ä¿æç©ºåå
æ ¼ï¼æ¯ç´æ¥è¾åºåå§å¼ "0" æ´åçï¼ã |
| | | log.warn("[convertToExcelData][type({}) æªæ¾å°åå
¸é¡¹ value({})ï¼å¯¼åºä¸ºç©º]", type, value); |
| | | return new WriteCellData<>(""); |
| | | } |
| | | // çæ Excel å°è¡¨æ ¼ |
| | |
| | | import cn.hutool.core.map.MapUtil; |
| | | import cn.hutool.core.util.ObjUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import com.fasterxml.jackson.core.JsonParseException; |
| | | import com.fasterxml.jackson.databind.exc.InvalidFormatException; |
| | | import cn.lihu.jh.framework.apilog.core.service.ApiErrorLogFrameworkService; |
| | | import cn.lihu.jh.framework.common.exception.ServiceException; |
| | | import cn.lihu.jh.framework.common.exception.util.ServiceExceptionUtil; |
| | |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.apache.commons.lang3.exception.ExceptionUtils; |
| | | import org.springframework.http.converter.HttpMessageNotReadableException; |
| | | import org.springframework.security.access.AccessDeniedException; |
| | | import org.springframework.util.Assert; |
| | | import org.springframework.validation.BindException; |
| | |
| | | } |
| | | |
| | | /** |
| | | * å¤ç请æ±ä½ï¼@RequestBodyï¼ååºåå失败ã |
| | | * |
| | | * <h3>为ä»ä¹éè¦åç¬å¤ç</h3> |
| | | * ä¹å没æè¿ä¸ªå¤çå¨ï¼JSON éçåæ®µç±»åä¸å¯¹ï¼ä¾å¦ {@code "bookCheckType": "常è§å¿çµå¾"}ï¼ |
| | | * èå®ä½åæ®µæ¯ {@code Integer}ï¼æ¶ä¼æ {@link HttpMessageNotReadableException}ï¼ |
| | | * ä¸è·¯è½å° {@link #defaultExceptionHandler} å
åº ââ å端åªçå° <b>500ãç³»ç»å¼å¸¸ã</b>ï¼ |
| | | * å®å
¨çä¸åºæ¯åæ°æ ¼å¼é®é¢ï¼å®æµ 2026-10-28 ææ¥ {@code /ecg/appointment/create} å³ä¸ºæ¤ï¼ã |
| | | * |
| | | * <p>ç°å¨æ¹ä¸ºè¿å <b>400</b> å¹¶æç¡®æåºãåªä¸ªåæ®µãæ¶å°ä»ä¹å¼ãææä»ä¹ç±»åãã |
| | | */ |
| | | @ExceptionHandler(HttpMessageNotReadableException.class) |
| | | public CommonResult<?> httpMessageNotReadableExceptionHandler(HttpMessageNotReadableException ex) { |
| | | log.warn("[httpMessageNotReadableExceptionHandler]", ex); |
| | | return CommonResult.error(BAD_REQUEST.getCode(), "请æ±åæ°æ ¼å¼é误:" + buildMessageNotReadableDetail(ex)); |
| | | } |
| | | |
| | | /** |
| | | * æååºååå¼å¸¸ç¿»è¯æäººè½çæç说æï¼å段å + æ¶å°çå¼ + ææçç±»åã |
| | | */ |
| | | private String buildMessageNotReadableDetail(HttpMessageNotReadableException ex) { |
| | | Throwable cause = ex.getMostSpecificCause(); |
| | | // â åæ®µç±»åä¸å¹é
ï¼æå¸¸è§ï¼ï¼æ¿å°äºå段å / å®é
å¼ / ææç±»å |
| | | if (cause instanceof InvalidFormatException) { |
| | | InvalidFormatException ife = (InvalidFormatException) cause; |
| | | String field = ife.getPath().isEmpty() |
| | | ? "" : ife.getPath().get(ife.getPath().size() - 1).getFieldName(); |
| | | Object value = ife.getValue(); |
| | | Class<?> target = ife.getTargetType(); |
| | | return String.format("åæ®µã%sãç±»å䏿£ç¡®ï¼æ¶å°å¼:%sï¼ææç±»å:%sï¼", |
| | | StrUtil.blankToDefault(field, "æªç¥å段"), value, null == target ? "æªç¥" : target.getSimpleName()); |
| | | } |
| | | // ⡠请æ±ä½ç¼ºå¤± / JSON è¯æ³é误çï¼ç¨æå
·ä½çåå |
| | | if (cause instanceof JsonParseException) { |
| | | return "JSON æ ¼å¼ä¸æ£ç¡®:" + ((JsonParseException) cause).getOriginalMessage(); |
| | | } |
| | | String message = null == cause ? ex.getMessage() : cause.getMessage(); |
| | | return StrUtil.blankToDefault(message, "请æ±ä½æ æ³è§£æ"); |
| | | } |
| | | |
| | | /** |
| | | * å¤ç SpringMVC åæ°æ ¡éªä¸æ£ç¡® |
| | | */ |
| | | @ExceptionHandler(MethodArgumentNotValidException.class) |
| | |
| | | ErrorCode ROOM_NOT_EXISTS = new ErrorCode(1_010_002_000, "è¯å®¤åè¯çåºä¸åå¨"); |
| | | ErrorCode ROOM_NOT_SIT = new ErrorCode(1_010_002_001, "è¯·éæ°å°±åº§"); |
| | | ErrorCode ROOM_INVALID_STATUS = new ErrorCode(1_010_002_001, "è¯å®¤åè¯çåºç¶æå¼å¸¸"); |
| | | /** |
| | | * å
¥åº§è¢«æï¼è¯¥å·¥ä½å·²è¢«**å
¶ä»å»ç**å ç¨ï¼æ¬æ¬¡æ°å¢ï¼ã |
| | | * |
| | | * <p>èæ¯ï¼åæ¥è¿ç§æ
åµä¹è¿å {@link #ROOM_INVALID_STATUS}ï¼"è¯å®¤åè¯çåºç¶æå¼å¸¸"ï¼ï¼ |
| | | * ç°åºçå°è¿å¥è¯æ æ³å¤ææ¯"å·¥ä½è¢«äººå äº"è¿æ¯"ç¶æä¸å¯¹"ï¼æéææ¬é«ã |
| | | * ç¬ç«æç åï¼å端å¯ç´æ¥æç¤º"该工ä½å·²ç±å
¶ä»å»çæä½ä¸"ï¼å¹¶å·æ°å表ã |
| | | */ |
| | | ErrorCode ROOM_OCCUPIED_BY_OTHER = new ErrorCode(1_010_002_002, |
| | | "该工ä½å·²ç±å
¶ä»å»çæä½ä¸ï¼ä¸è½å
¥åº§ï¼è¯·å·æ°åéæ©ç©ºé²å·¥ä½"); |
| | | /** |
| | | * å´è§æ¨¡å¼ï¼å½åç»å½äººä¸æ¯è¯¥å·¥ä½ç主人ï¼ä¸è½æ§è¡**å**æä½ï¼æ¬æ¬¡æ°å¢ï¼ã |
| | | * |
| | | * <p>èæ¯ï¼å¼å
¥"å´è§"åä»»ä½ç»å½ç¨æ·é½è½æ¥çä»»æå·²å¼æ¾å·¥ä½çæ°æ®ï¼åªè¯»ï¼ï¼ |
| | | * ä½å«å·ãè¿å·ãå®ææ£æ¥ã确费ãé¢ç¨ãè£
æºçåæä½åªè½ç±è¯¥å·¥ä½ä¸»äººæ§è¡ã |
| | | * å端ç¦ç¨æé®åªæ¯çé¢çº¦å®ï¼æå¡ç«¯ç± {@code @RequireBedOwner} åé¢ç»ä¸æ¦æªã |
| | | */ |
| | | ErrorCode ROOM_NOT_OWNER = new ErrorCode(1_010_002_003, |
| | | "å½åå·¥ä½ç±å
¶ä»å»çæä½ä¸ï¼æ¨å¤äºå´è§æ¨¡å¼ï¼ä¸è½æ§è¡è¯¥æä½"); |
| | | |
| | | ErrorCode QUEUE_NOT_EXISTS = new ErrorCode(1_010_003_000, "æéä¸åå¨"); |
| | | ErrorCode QUEUE_BED_NOT_EXIST = new ErrorCode(1_010_003_001, "å·¥ä½éåä¸åå¨"); |
| | |
| | | */ |
| | | ErrorCode QUEUE_STOP_READY_NOT_CONFIGURED = new ErrorCode(1_010_003_006, |
| | | "忢åè¯åè½æªé
ç½®ï¼è¯·å
æ§è¡æ°æ®åºåçº§èæ¬ï¼clinic_room.stop_readyï¼"); |
| | | /** æå·¥"æå
¥æéæ£è
"æ¶ï¼è¯¥æ£è
å·²ä¸å¨ãæéä¸ãï¼è¢«å«çå·¥ä½æèµ°/å·²å«å·ï¼ */ |
| | | ErrorCode QUEUE_NOT_WAITING = new ErrorCode(1_010_003_007, |
| | | "该æ£è
å·²ä¸å¨æéä¸ï¼å¯è½å·²è¢«å
¶ä»å·¥ä½æå
¥ï¼ï¼è¯·å·æ°åéè¯"); |
| | | /** æå·¥"æå
¥æéæ£è
"æ¶ï¼æ£æ¥é¡¹ç®ä¸å¨æ¬å·¥ä½å¼å±èå´å
*/ |
| | | ErrorCode QUEUE_CHECK_TYPE_NOT_MATCH = new ErrorCode(1_010_003_008, |
| | | "该æ£è
çæ£æ¥é¡¹ç®ä¸å¨æ¬å·¥ä½å¼å±èå´å
ï¼ä¸è½æå
¥"); |
| | | |
| | | ErrorCode PATIENT_NOT_EXISTS = new ErrorCode(1_010_004_000, "æ£è
ä¸åå¨"); |
| | | |
| | |
| | | AFFINITY(12, "亲å"), |
| | | AFFINITY_INSTALL(13, "亲å-å®è£
"), |
| | | RECALLED(15, "å·²å¬å"), |
| | | READY(20, "åè¯ä¸"), // åè¯ä¸ 已念å°å·¥ä½ |
| | | READY(20, "åå¤ä¸"), // åå¤ä¸ï¼å·²åæµå°å·¥ä½ï¼åç§°"åè¯ä¸"ï¼2026-10-16 ç»ä¸æ¹å为"åå¤ä¸"ï¼ |
| | | ONSTAGE(30, "å°±è¯ä¸"), // æ é¢ç¨ä¸ |
| | | RECEIVED(33, "å·²é¢ç¨"), |
| | | RECALLED_INSTALL(34, "å·²å¬å-å®è£
"), |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.lihu.jh.module.ecg.enums; |
| | | |
| | | import cn.lihu.jh.framework.common.core.IntArrayValuable; |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Getter; |
| | | |
| | | import java.util.Arrays; |
| | | |
| | | /** |
| | | * æéåºå·è§åæä¸¾ ââ å¨ãæ£æ¥ç±»å管çã(system/check-type) ç {@code check_type.seq_rule} ä¸é
ç½®ã |
| | | * |
| | | * <h3>èæ¯</h3> |
| | | * ç¾å°æ¶éè¦ç»æ£è
ä¸ä¸ªãæéåºå·ãï¼ä¸åæ£æ¥é¡¹ç®ç¨ä¸åè§åãåå®ç°**åªæ¯æä¸ç§** |
| | | * ï¼ææ¶æ®µåå·ï¼è§ {@link #TIMESLOT}ï¼ï¼æ¬æä¸¾æä¸ç§è§åæ¾å¼åï¼ä¾¿äºæé¡¹ç®é
ç½®ã |
| | | * |
| | | * <h3>ä¸ç§è§å</h3> |
| | | * <ul> |
| | | * <li>{@link #APPOINT} ââ **ç´æ¥ç¨é¢çº¦ç³»ç»ä¸åçé¢çº¦å·**ï¼ç¾å°æ¶ä¸ååé
æ°åºå·ï¼</li> |
| | | * <li>{@link #CHECKIN} ââ **ç¾å°æ¶ç»ç¾å°åºå·**ï¼åä¸å¤©ãå䏿£æ¥ç±»åå
ï¼ç¬¬ 1 个ç¾å°æ¯ 1 å·ï¼ |
| | | * 第 2 ä¸ªæ¯ 2 å·â¦â¦ï¼å¹¶æãæ¯ 9 个å·é¢ç 1 个ãè·³è¿é¢çå·ï¼çç»å æ¥æ£è
ï¼</li> |
| | | * <li>{@link #TIMESLOT} ââ **æé¢çº¦æ¶é´æ®µç»å·**ï¼ç°ç¶è§åï¼ï¼å·æ± æ |
| | | * {@code (check_type, time_slot)} ç»´æ¤ï¼å®¹éåæ¶æ®µé
ç½®éå¶ã</li> |
| | | * </ul> |
| | | * |
| | | * <h3>容éè¯ä¹å·®å¼ï¼éè¦ï¼</h3> |
| | | * {@link #APPOINT} ä¸ {@link #CHECKIN} **ä¸è®¾å½æ¥ä¸é**ï¼å·è¿ç»éå¢ï¼åå®å³æ¢ä¸åå¨ï¼ï¼ |
| | | * åªæ {@link #TIMESLOT} ä¿çåæçæ¶æ®µå®¹éæ§å¶ãè§ {@link #isCapacityLimited()}ã |
| | | * |
| | | * <h3>ä¸ç°æ {@code timeslot_book_num} / {@code timeslot_reserved_num} çå
³ç³»</h3> |
| | | * é£ä¸¤ä¸ªå段æ¯**æ¶æ®µå·æ± **çåæ°ï¼ä»
å¨ {@link #TIMESLOT} ä¸çæï¼ |
| | | * {@link #CHECKIN} çé¢çè§ååºå®ä¸ºãæ¯ 9 个跳 1 个ãï¼9 个æ®éå· + 1 个é¢çå· = ä¸è½® 10 个ï¼ã |
| | | * |
| | | * @author å¿çµæéè£
æºç³»ç» |
| | | */ |
| | | @Getter |
| | | @AllArgsConstructor |
| | | public enum SeqRuleEnum implements IntArrayValuable { |
| | | |
| | | /** â ç¨é¢çº¦ç³»ç»çé¢çº¦å·ï¼ä¸ååé
æ°å·ï¼ */ |
| | | APPOINT(0, "é¢çº¦å·"), |
| | | /** â¡ ç¾å°æ¶ç»ç¾å°åºå·ï¼å½å¤©åæ£æ¥ç±»åå
è¿ç»éå¢ï¼æ¯ 9 个é¢ç 1 ä¸ªï¼ */ |
| | | CHECKIN(1, "ç¾å°åºå·"), |
| | | /** ⢠æé¢çº¦æ¶é´æ®µç»å·ï¼ç°ç¶è§åï¼å·æ± ææ¶æ®µç»´æ¤ï¼ */ |
| | | TIMESLOT(2, "æ¶æ®µå·"); |
| | | |
| | | public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(SeqRuleEnum::getRule).toArray(); |
| | | |
| | | /** é»è®¤è§åï¼ä¿æä¸æ¹é åä¸è´çè¡ä¸ºï¼é¿å
åéæ°æ®æªé
ç½®æ¶è¡ä¸ºåå */ |
| | | public static final SeqRuleEnum DEFAULT = TIMESLOT; |
| | | |
| | | /** |
| | | * ä¸è½®å·çæ°éï¼9 个æ®éå· + 1 个é¢çå·ã |
| | | * é¢çå·ç¨äºå æ¥æ£è
ï¼{@code jjbz=J}ï¼ã |
| | | */ |
| | | public static final int ROUND_SIZE = 10; |
| | | |
| | | /** ä¸è½®ä¸è¢«é¢ççå·ä¸ªæ°ï¼æ¯ {@link #ROUND_SIZE} 个ç 1 ä¸ªï¼ */ |
| | | public static final int RESERVED_PER_ROUND = 1; |
| | | |
| | | /** è§åå¼ */ |
| | | private final Integer rule; |
| | | /** è§åå */ |
| | | private final String name; |
| | | |
| | | @Override |
| | | public int[] array() { |
| | | return ARRAYS; |
| | | } |
| | | |
| | | /** |
| | | * 该è§å䏿¯å¦éè¦æ£æ¥ãæ¶æ®µå·æ± 容éãã |
| | | * <p> |
| | | * ä»
{@link #TIMESLOT} éè¦ ââ å®å {@code queue_sequence.queue_full} éå¶ï¼ |
| | | * å¦ä¸¤ç§è§åå·å¼æ¯è¿ç»éå¢çï¼ä¸è®¾ä¸éã |
| | | */ |
| | | public boolean isCapacityLimited() { |
| | | return this == TIMESLOT; |
| | | } |
| | | |
| | | /** |
| | | * æè§åå¼è§£ææä¸¾ï¼æ æ³è¯å«æä¸º null æ¶è¿å {@link #DEFAULT}ã |
| | | * <p> |
| | | * 乿以䏿å¼å¸¸ï¼è¯¥å¼æ¥èªæ°æ®åºé
ç½®ï¼åéè¡å¯è½ä¸º nullï¼ |
| | | * åé»è®¤å¼å¯ä¿è¯å级å**è¡ä¸ºä¸æ¹é åä¸è´**ï¼ä¸å æªé
ç½®è黿ç¾å°ã |
| | | */ |
| | | public static SeqRuleEnum parse(Integer rule) { |
| | | if (rule == null) { |
| | | return DEFAULT; |
| | | } |
| | | for (SeqRuleEnum item : values()) { |
| | | if (item.rule.equals(rule)) { |
| | | return item; |
| | | } |
| | | } |
| | | return DEFAULT; |
| | | } |
| | | |
| | | /** |
| | | * 夿ç»å®å·æ¯å¦ä¸ºãé¢çå·ãï¼çç»å æ¥æ£è
ï¼ã |
| | | * <p> |
| | | * è§åï¼æ¯ {@link #ROUND_SIZE} 个å·ç {@link #RESERVED_PER_ROUND} 个ã |
| | | * 以 1 ä¸ºèµ·ç¹æ¶ï¼æ¯è½®ç第 10 个ï¼10ã20ã30â¦ï¼ä¸ºé¢çå·ã |
| | | * |
| | | * @param seq åéå·ï¼ä» 1 å¼å§ï¼ |
| | | * @return true 表示该å·éè·³è¿ï¼é¤éæ¯å æ¥æ£è
ï¼ |
| | | */ |
| | | public static boolean isReservedSeq(int seq) { |
| | | return seq > 0 && seq % ROUND_SIZE == 0; |
| | | } |
| | | |
| | | /** |
| | | * å {@code from} åä¹å第ä¸ä¸ªãéé¢çå·ãã |
| | | * |
| | | * <p>ç¨äºæ®éæ£è
ï¼è¥è®¡æ°å¨ç®åºçå·æ°å¥½æ¯é¢çå·ï¼10 çåæ°ï¼ï¼ |
| | | * åæ¹ç¨ä¸ä¸ä¸ªå·ï¼æé¢çå·çç»å æ¥æ£è
ã |
| | | * |
| | | * <p>注æä¸è°ç¨æ¹ {@code advanceNormalSeq} çé
åï¼è®¡æ°å¨å¨åä¸äºå¡å
|
| | | * <b>ä¹è¦</b>è·³è¿è¯¥é¢çå·ï¼å¤ +1ï¼ï¼å¦åä¸ä¸æ¬¡ä¼æåä¸ä¸ªå·åå䏿¬¡ã |
| | | * è¯¦è§ {@code QueueSequenceMapper#advanceNormalSeq} ç说æã |
| | | * |
| | | * @param from èµ·å§å·ï¼å«ï¼ |
| | | * @return 第ä¸ä¸ªéé¢çå· |
| | | */ |
| | | public static int nextNormalSeq(int from) { |
| | | int seq = Math.max(1, from); |
| | | while (isReservedSeq(seq)) { |
| | | seq++; |
| | | } |
| | | return seq; |
| | | } |
| | | |
| | | /** |
| | | * åä¸ä¸ä¸ªé¢çå·ï¼ç»å æ¥æ£è
ï¼ã |
| | | * <p> |
| | | * è¥ {@code from} æ¬èº«å·²æ¯é¢çå·åç´æ¥è¿åï¼å¦åè·³å°æ¬è½®çé¢çå·ã |
| | | * ä¾ï¼from=1 â 10ï¼from=10 â 10ï¼from=11 â 20ã |
| | | * |
| | | * @param from èµ·å§å·ï¼å«ï¼ |
| | | * @return ä¸å°äº {@code from} ç第ä¸ä¸ªé¢çå· |
| | | */ |
| | | public static int nextReservedSeq(int from) { |
| | | int seq = Math.max(1, from); |
| | | int rem = seq % ROUND_SIZE; |
| | | if (rem == 0) { |
| | | return seq; |
| | | } |
| | | return seq + (ROUND_SIZE - rem); |
| | | } |
| | | |
| | | } |
| | |
| | | static final String ECG_SCREEN_PANE_PASSED_KEY = "ecg.screen.pane.passed"; |
| | | static final String DEV_CODE_CHOICE = "dev.code.choice"; |
| | | |
| | | /** |
| | | * 鿩工使¨¡å¼ï¼éæ±ï¼å·¥ä½éæ©æ¨¡å¼ï¼ã |
| | | * <p>åå¼ï¼ |
| | | * <ul> |
| | | * <li>{@code 0} æéè¦å¼ºå¶éæ©å·¥ä½ï¼=忥è¡ä¸ºï¼ç»å½åæªå
¥åº§å°±å¼ºå¶å»éå·¥ä½ï¼</li> |
| | | * <li>{@code 1} ç»å½IPå¹é
å·¥ä½ï¼ææ¥è®¿IPèªå¨å¹é
å·¥ä½å¹¶èªå¨å
¥åº§ï¼å¹é
ä¸å°åæ 0 æ§è¡ï¼</li> |
| | | * <li>{@code 2} ç»å½æ¶æå¨éæ©å·¥ä½ï¼å¼ºå¶éæ©ï¼å¹¶ææ¬æºIPåå
¥æéå·¥ä½ç clinic_room.ipï¼</li> |
| | | * <li>{@code 3} æç³»ç»é»è®¤å¤çï¼è¯¥IPæªç»å®è¿å·¥ä½âæ 2 é䏿¬¡å¹¶è®°ä½IPï¼å·²ç»å®âæ 1 èªå¨å¹é
ï¼å¹é
ä¸å°âæ 0ï¼</li> |
| | | * </ul> |
| | | * åæ°ç¼ºå¤±æéæ³æ¶ï¼ä¸å¾æ {@code 0} å¤çï¼ä¿è¯ä¸å½±ååéé¨ç½²ã</p> |
| | | */ |
| | | static final String ECG_ROOM_SELECT_MODE_KEY = "ecg.room.select.mode"; |
| | | |
| | | /** 鿩工使¨¡å¼ï¼æéè¦å¼ºå¶éæ©å·¥ä½ï¼é»è®¤ï¼çä»·äºåè¡ä¸ºï¼ */ |
| | | static final int ROOM_SELECT_MODE_FORCE = 0; |
| | | /** 鿩工使¨¡å¼ï¼ç»å½IPå¹é
å·¥ä½ */ |
| | | static final int ROOM_SELECT_MODE_BY_IP = 1; |
| | | /** 鿩工使¨¡å¼ï¼ç»å½æ¶æå¨éæ©å·¥ä½ï¼å¹¶åå
¥æ¬æºIP */ |
| | | static final int ROOM_SELECT_MODE_MANUAL_BIND_IP = 2; |
| | | /** 鿩工使¨¡å¼ï¼æç³»ç»é»è®¤å¤çï¼é¦æ¬¡=æå¨éå¹¶è®°IPï¼ä¹å=IPå¹é
ï¼ */ |
| | | static final int ROOM_SELECT_MODE_SYSTEM_DEFAULT = 3; |
| | | |
| | | // æ¶é´æ®µ.é´éæ¶é¿ |
| | | static final String BOOK_TIMESLOT_LENGTH = "book.timeslot.length"; |
| | | //static final String BOOK_TIMESLOT_LIST = "book.timeslot.list"; |
| | |
| | | package cn.lihu.jh.module.ecg; |
| | | |
| | | import cn.lihu.jh.module.ecg.dal.dataobject.queue.QueueDO; |
| | | |
| | | import java.time.LocalTime; |
| | | import java.util.ArrayList; |
| | | import java.util.Arrays; |
| | | import java.util.List; |
| | | import java.util.Objects; |
| | | import java.util.regex.Matcher; |
| | | import java.util.regex.Pattern; |
| | | |
| | |
| | | |
| | | return localTimeList; |
| | | } |
| | | |
| | | /** |
| | | * æã亲å项ãæåå°å®çã主项ãåé¢ï¼ä½¿ä¸¤è
å¨çé¢ä¸ç´§æ¨çæ¾ç¤ºã |
| | | * |
| | | * <p>亲å项 = å䏿£è
çå¦ä¸ä¸ªæ£æ¥é¡¹ç®ï¼ä¸»é¡¹è¿åè¯æ¶å®ä¸èµ·è¿ï¼ä¸»é¡¹å宿¶å®ä¸èµ·åå® |
| | | * ï¼è§ {@code QueueServiceTxFunctions#procAffinityWhenPreempt}ï¼ã |
| | | * |
| | | * <p>ä¹æä»¥æ½æä¸ä¸ªæ¹æ³ï¼è¿æ®µé»è¾å¨å·¥ä½å°å表ãè¯é´å±ã大å±å
± <b>5 å¤</b>éå¤ï¼ |
| | | * èåå®ç°æä¸¤ä¸ªåï¼éãæéå·ç»ä¸ãæ¹é ä¸å¹¶ä¿®æ£ï¼ï¼ |
| | | * <ol> |
| | | * <li>åªç¨ {@code seqNum} ç¸çæ¥å®ä½ä¸»é¡¹ãæéå·æ¹ä¸ºãææ£æ¥ç±»ååèªç¼å·ãåå·ä¼è·¨æ£æ¥ç±»åéå¤ï¼ |
| | | * å¯è½æäº²å项æå°<b>å«çæ£æ¥ç±»å</b>çæ£è
åé¢ï¼æ
åæ¶è¦æ± {@code patId} ç¸åã</li> |
| | | * <li>ç¨ {@code ==} æ¯è¾ {@code Integer}ï¼å·å¤§äº 127 æ¶æ¯å¼ç¨æ¯è¾ãæ°¸è¿ä¸ç¸çï¼ |
| | | * 亲å项被 {@code remove} ä¹åæä¸åå» ââ 表ç°ä¸º<b>亲å项å¨åè¡¨éæ¶å¤±</b> |
| | | * ï¼æ¶æ®µå·è§åä¸å·å¾å®¹æè¶
è¿ 127ï¼ãæ¹ä¸ºæå¼æ¯è¾ï¼å¹¶å "æ¾ä¸å°ä¸»é¡¹å°±è¿½å å°æ«å°¾"çå
åºã</li> |
| | | * </ol> |
| | | * |
| | | * @param list å·²æå¥½åºçå表ï¼è°ç¨æ¹éå
æäº²å项ä»ä¸ç§»é¤ï¼ |
| | | * @param affinityItems 被移é¤åºæ¥ç亲å项 |
| | | */ |
| | | public static void insertAffinityItemsAfterMain(List<QueueDO> list, List<QueueDO> affinityItems) { |
| | | if (list == null || affinityItems == null || affinityItems.isEmpty()) { |
| | | return; |
| | | } |
| | | for (QueueDO affinityItem : affinityItems) { |
| | | boolean inserted = false; |
| | | for (int i = list.size() - 1; i >= 0; i--) { |
| | | QueueDO mainItem = list.get(i); |
| | | if (isSameSeqNum(affinityItem.getSeqNum(), mainItem.getSeqNum()) |
| | | && Objects.equals(affinityItem.getPatId(), mainItem.getPatId())) { |
| | | list.add(i + 1, affinityItem); |
| | | inserted = true; |
| | | break; |
| | | } |
| | | } |
| | | if (!inserted) { |
| | | // 主项ä¸å¨æ¬å表ï¼ä¾å¦å·²å°±è¯å®æè¢«ç¶æè¿æ»¤æï¼ï¼å
åºè¿½å å°æ«å°¾ï¼ |
| | | // å®å¯ä½ç½®ä¸å®ç¾ï¼ä¹ä¸è½è®©åè¯ä¸çæ£è
ä»å表é"æ¶å¤±"ã |
| | | list.add(affinityItem); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** æé巿弿¯è¾ï¼{@code Integer} ç¨ {@code ==} å¨å¤§äº 127 æ¶æ¯å¼ç¨æ¯è¾ï¼ä¼è¯¯å¤ä¸ºä¸çï¼ */ |
| | | private static boolean isSameSeqNum(Integer a, Integer b) { |
| | | return a != null && b != null && a.intValue() == b.intValue(); |
| | | } |
| | | } |
| | | |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.lihu.jh.module.ecg.annotation; |
| | | |
| | | import java.lang.annotation.*; |
| | | |
| | | /** |
| | | * æ è®°ãå¿
é¡»æ¯è¯¥å·¥ä½ç主人æè½è°ç¨ãç忥å£ï¼ä¸»/å´è§æ¨¡åçæ ¸å¿é´æï¼ã |
| | | * |
| | | * <h3>为ä»ä¹éè¦å®</h3> |
| | | * å¼å
¥"å´è§"åï¼ä»»ä½ç»å½ç¨æ·é½è½**æ¥ç**ä»»æå·²å¼æ¾å·¥ä½çæ°æ®ï¼åªè¯»ï¼ï¼ |
| | | * ä½**å**æä½ï¼å«å·ãè¿å·ãå®ææ£æ¥ã确费ãé¢ç¨ãè£
æºâ¦ï¼åªè½ç±è¯¥å·¥ä½ç主人æ§è¡ã |
| | | * |
| | | * <p>å端è½ç¶ä¼å¨å´è§æ¨¡å¼ä¸ç¦ç¨æé®ï¼ä½é£åªæ¯çé¢çº¦å® ââ ä»»ä½äººç»è¿çé¢ç´æ¥è°æ¥å£ç
§æ ·è½æ¹æ°æ®ã |
| | | * å æ¤æå¡ç«¯å¿
é¡»ç»ä¸æ ¡éªï¼<b>å½åç»å½äºº == clinic_room 该 roomId+bedNo ç doc_id</b>ã |
| | | * |
| | | * <h3>ç¨æ³</h3> |
| | | * å å¨ Controller çåæ¹æ³ä¸å³å¯ï¼åé¢ä¼èªå¨ä»åæ°éè§£æ roomId / bedNoï¼ |
| | | * <ul> |
| | | * <li>{@code @RequestParam("roomId") Long roomId} / {@code @RequestParam("bedNo") String bedNo}ï¼</li> |
| | | * <li>æ {@code @RequestBody XxxVO vo}ï¼VO éæ {@code getRoomId()} / {@code getBedNo()}ã</li> |
| | | * </ul> |
| | | * è§£æä¸å° roomId/bedNo æ¶**æ¾è¡å¹¶è®°è¦å**ï¼é¿å
误伤ï¼ï¼æ¤ç±»æ¥å£éå¨ä¸å¡éèªè¡æ ¡éª |
| | | * ï¼ä¾å¦åªå¸¦ rentId ç {@code fee-confirm}ï¼ã |
| | | * |
| | | * @author å¿çµæéè£
æºç³»ç» |
| | | */ |
| | | @Target({ElementType.METHOD}) |
| | | @Retention(RetentionPolicy.RUNTIME) |
| | | @Documented |
| | | public @interface RequireBedOwner { |
| | | |
| | | /** ä¾¿äºæ¥å¿ææ¥ï¼åæ¸
è¿ä¸ªæ¥å£æ¯åä»ä¹çï¼å¯éï¼ */ |
| | | String value() default ""; |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.lihu.jh.module.ecg.aspect; |
| | | |
| | | import cn.lihu.jh.module.ecg.annotation.RequireBedOwner; |
| | | import cn.lihu.jh.module.ecg.service.room.RoomService; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.aspectj.lang.JoinPoint; |
| | | import org.aspectj.lang.annotation.Aspect; |
| | | import org.aspectj.lang.annotation.Before; |
| | | import org.aspectj.lang.reflect.MethodSignature; |
| | | import org.springframework.stereotype.Component; |
| | | import org.springframework.web.bind.annotation.RequestParam; |
| | | |
| | | import javax.annotation.Resource; |
| | | import java.lang.annotation.Annotation; |
| | | import java.lang.reflect.Method; |
| | | |
| | | /** |
| | | * ãå¿
é¡»æ¯å·¥ä½ä¸»äººãçåæä½é´æåé¢ï¼ä¸»/å´è§æ¨¡åçæ ¸å¿ï¼ã |
| | | * |
| | | * <p>å¤ç被 {@link RequireBedOwner} æ æ³¨ç Controller æ¹æ³ï¼è§£æåº roomId / bedNoï¼ |
| | | * äº¤ç» {@link RoomService#assertBedOwner(Long, String)} æ ¡éªï¼ |
| | | * å´è§äººææ 座è
è°ç¨åæ¥å£æ¶ç´æ¥æ {@code ROOM_NOT_OWNER}ï¼"æ¨å¤äºå´è§æ¨¡å¼ï¼ä¸è½æ§è¡è¯¥æä½"ï¼ã |
| | | * |
| | | * <p><b>为ä»ä¹è§£æä¸å°å°±æ¾è¡</b>ï¼åªå¸¦ rentId ä¹ç±»çæ¥å£æ¿ä¸å° roomId/bedNoï¼ |
| | | * è¥ä¸å¾æç»ä¼ææ£å¸¸ä¸å¡ä¹æ¡æï¼ä¾å¦ç¡®è´¹ï¼ãè¿ç±»æ¥å£è®°è¦åæ¥å¿ï¼å¹¶ç±ä¸å¡èªè¡æ ¡éªã |
| | | */ |
| | | @Aspect |
| | | @Component |
| | | @Slf4j |
| | | public class BedOwnerAspect { |
| | | |
| | | @Resource |
| | | private RoomService roomService; |
| | | |
| | | @Before("@annotation(requireBedOwner)") |
| | | public void checkBedOwner(JoinPoint joinPoint, RequireBedOwner requireBedOwner) { |
| | | Long roomId = null; |
| | | String bedNo = null; |
| | | |
| | | Object[] args = joinPoint.getArgs(); |
| | | MethodSignature signature = (MethodSignature) joinPoint.getSignature(); |
| | | Method method = signature.getMethod(); |
| | | Annotation[][] paramAnnotations = method.getParameterAnnotations(); |
| | | |
| | | for (int i = 0; i < args.length; i++) { |
| | | Object arg = args[i]; |
| | | if (null == arg) { |
| | | continue; |
| | | } |
| | | // â @RequestParam("roomId"/"bedNo") ç´æ¥åæ° |
| | | Annotation[] annotations = (i < paramAnnotations.length) ? paramAnnotations[i] : null; |
| | | if (null != annotations) { |
| | | for (Annotation annotation : annotations) { |
| | | if (!(annotation instanceof RequestParam)) { |
| | | continue; |
| | | } |
| | | String name = ((RequestParam) annotation).value(); |
| | | if (name.isEmpty()) { |
| | | name = ((RequestParam) annotation).name(); |
| | | } |
| | | if ("roomId".equals(name) && arg instanceof Number) { |
| | | roomId = ((Number) arg).longValue(); |
| | | } else if ("bedNo".equals(name)) { |
| | | bedNo = String.valueOf(arg); |
| | | } |
| | | } |
| | | } |
| | | // ⡠请æ±ä½ VOï¼åå°è¯» getRoomId() / getBedNo() |
| | | if (isSimpleValue(arg)) { |
| | | continue; |
| | | } |
| | | if (null == roomId) { |
| | | Object v = readGetter(arg, "getRoomId"); |
| | | if (v instanceof Number) { |
| | | roomId = ((Number) v).longValue(); |
| | | } |
| | | } |
| | | if (null == bedNo) { |
| | | Object v = readGetter(arg, "getBedNo"); |
| | | if (null != v) { |
| | | bedNo = String.valueOf(v); |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (null == roomId || null == bedNo || bedNo.isEmpty() || "null".equals(bedNo)) { |
| | | log.warn("[RequireBedOwner] æªè½ä»åæ°è§£æ roomId/bedNoï¼è·³è¿ä¸»äººæ ¡éªï¼è¯¥æ¥å£éèªè¡æ ¡éªï¼. æ¥å£={} æ è®°={}", |
| | | signature.getName(), requireBedOwner.value()); |
| | | return; |
| | | } |
| | | roomService.assertBedOwner(roomId, bedNo); |
| | | } |
| | | |
| | | /** ç®åç±»åï¼æ°å/å符串/éåçï¼ä¸éè¦å getter åå° */ |
| | | private boolean isSimpleValue(Object arg) { |
| | | return arg instanceof Number || arg instanceof CharSequence || arg instanceof Boolean |
| | | || arg instanceof java.util.Collection || arg instanceof java.util.Map; |
| | | } |
| | | |
| | | private Object readGetter(Object target, String getterName) { |
| | | try { |
| | | Method getter = target.getClass().getMethod(getterName); |
| | | return getter.invoke(target); |
| | | } catch (Exception e) { |
| | | return null; |
| | | } |
| | | } |
| | | } |
| | |
| | | return success(BeanUtils.toBean(appointmentList.get(0), AppointmentRespVO.class)); |
| | | } |
| | | |
| | | /** |
| | | * ãæ¬éæ±ï¼ç´§æ¥æ£è
䏿éç´æ¥æ£æ¥ãæãç³è¯·åå· / å°±è¯å· / æ£è
ç¼å·ãæ¥è¿ä¸ä¸ªæçé¢çº¦è®°å½ã |
| | | * |
| | | * <p>å·¥ä½å°å¨ä¸ä¸ªè¾å
¥æ¡éæå车æ¶è°ç¨ï¼ç»ææ**é¢çº¦æ¶é´ååº**ï¼æè¿çå¨åï¼ï¼ |
| | | * 夿¡æ¶ç±åç«¯å¼¹éæ©æ¡ãçªå£ä¸º [ä»å¤©-30 天, ä»å¤©+30 天]ï¼å¹¶ææ¬çªå£å¼å±çæ£æ¥é¡¹ç®è¿æ»¤ã |
| | | * |
| | | * @param code ç³è¯·åå· / å°±è¯æµæ°´å· / æ£è
ç¼å·ï¼ä¸è
ä¹ä¸ï¼ |
| | | * @param checkTypes æ¬çªå£ï¼è¯å®¤ï¼å¼å±çæ£æ¥é¡¹ç®ï¼éå·åéï¼ä¸ºç©ºè¡¨ç¤ºä¸éå¶ |
| | | */ |
| | | @GetMapping("/emergency-candidates") |
| | | @Operation(summary = "ç´§æ¥å åï¼æç³è¯·åå·/å°±è¯å·/æ£è
ç¼å·æ¥è¿ä¸ä¸ªæçé¢çº¦è®°å½") |
| | | @Parameter(name = "code", description = "ç³è¯·åå· / å°±è¯æµæ°´å· / æ£è
ç¼å·", required = true) |
| | | @Parameter(name = "checkTypes", description = "æ¬çªå£å¼å±çæ£æ¥é¡¹ç®ï¼éå·åéï¼ä¸ºç©ºä¸éå¶") |
| | | @PreAuthorize("@ss.hasPermission('ecg:appointment:query')") |
| | | public CommonResult<List<AppointmentRespVO>> getEmergencyCandidates(@RequestParam("code") String code, |
| | | @RequestParam(value = "checkTypes", required = false) String checkTypes) { |
| | | List<AppointmentDO> appointmentList = appointmentService.getEmergencyCandidates(code, checkTypes); |
| | | return success(BeanUtils.toBean(appointmentList, AppointmentRespVO.class)); |
| | | } |
| | | |
| | | @GetMapping("/page") |
| | | @Operation(summary = "è·å¾é¢çº¦å页") |
| | | @PreAuthorize("@ss.hasPermission('ecg:appointment:query')") |
| | | public CommonResult<PageResult<AppointmentRespVO>> getAppointmentPage(AppointmentPageReqVO pageReqVO) { |
| | | @PreAuthorize("@ss.hasPermission('ecg:appointment:query')") public CommonResult<PageResult<AppointmentRespVO>> getAppointmentPage(AppointmentPageReqVO pageReqVO) { |
| | | pageReqVO.setOrderCreateTime("1"); |
| | | PageResult<AppointmentDO> pageResult = appointmentService.getAppointmentPage(pageReqVO); |
| | | return success(BeanUtils.toBean(pageResult, AppointmentRespVO.class)); |
| | |
| | | |
| | | private Integer isVip; |
| | | |
| | | /** |
| | | * ãæ¬éæ±ãæ¯å¦"已确认ç¾å
¥"éå½å¤©é¢çº¦ã |
| | | * |
| | | * <p>é¢çº¦æ¥æä¸æ¯å½å¤©æ¶ï¼ |
| | | * <ul> |
| | | * <li>{@code forceCheckIn != true} ââ ç´æ¥è¿å {@code APPOINTMENT_NOT_TODAY}ï¼ |
| | | * åç«¯æ®æ¤å¼¹ãéå½å¤©é¢çº¦ï¼æ¯å¦ç»§ç»ç¾å°ãï¼</li> |
| | | * <li>{@code forceCheckIn == true} ââ å
许ç¾å
¥ï¼å¹¶æ**é¢çå·**åå· |
| | | * ï¼ä¸å ç¨å½å¤©åæ¶æ®µçæ£å¸¸é¢çº¦å·ï¼ã</li> |
| | | * </ul> |
| | | */ |
| | | private Boolean forceCheckIn; |
| | | |
| | | } |
| | |
| | | @Schema(description = "é¢çº¦æ¥æ") |
| | | private LocalDate bookDate; |
| | | |
| | | /** |
| | | * ãæ¬éæ±ãé¢çº¦æ¥æ**æ¶é´æ®µ**æ¥è¯¢ï¼èµ·å§ï¼å«å½å¤© 00:00:00ï¼ã |
| | | * <p>å端ãé¢çº¦æ¥æãç¨æ¥æèå´éæ©å¨ï¼æ¥è¯¢æ¶ææ start(00:00:00) / end(23:59:59) ä¸¤ä¸ªåæ°ï¼ |
| | | * 䏿¢æç {@code registerDateStart/End}ã{@code createTimeStart/End} åæ³ä¿æä¸è´ã |
| | | */ |
| | | @Schema(description = "é¢çº¦æ¥æ-å¼å§ï¼å«ï¼", example = "2026-11-01 00:00:00") |
| | | @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
| | | private LocalDateTime bookDateStart; |
| | | |
| | | @Schema(description = "é¢çº¦æ¥æ-ç»æï¼å«ï¼", example = "2026-11-30 23:59:59") |
| | | @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
| | | private LocalDateTime bookDateEnd; |
| | | |
| | | @Schema(description = "é¢çº¦æ¶é´æ®µ") |
| | | private Integer bookTimeslot; |
| | | |
| | |
| | | import java.time.LocalDate; |
| | | import java.util.*; |
| | | |
| | | import org.springframework.format.annotation.DateTimeFormat; |
| | | |
| | | import java.time.LocalDateTime; |
| | | |
| | | import com.alibaba.excel.annotation.*; |
| | | import com.alibaba.excel.annotation.format.DateTimeFormat; |
| | | import com.alibaba.excel.annotation.write.style.ColumnWidth; |
| | | import cn.lihu.jh.framework.excel.core.annotations.DictFormat; |
| | | import cn.lihu.jh.framework.excel.core.convert.DictConvert; |
| | | |
| | |
| | | |
| | | @Schema(description = "æ£è
çæ¥") |
| | | @ExcelProperty("æ£è
çæ¥") |
| | | // ãæ¬éæ±ã导åºåªæ¾ç¤ºæ¥æï¼åæ¥ LocalDateTime é»è®¤å¸¦æ¶åç§ â "1990-01-01 00:00:00"ï¼ |
| | | @DateTimeFormat("yyyy-MM-dd") |
| | | private LocalDateTime patBirthday; |
| | | |
| | | @Schema(description = "æ£è
ææº") |
| | |
| | | |
| | | @Schema(description = "é¢çº¦åçæ¶é´", requiredMode = Schema.RequiredMode.REQUIRED) |
| | | @ExcelProperty("é¢çº¦åçæ¶é´") |
| | | // ãæ¬éæ±ãå宽åºå® 20ï¼åå
é LongestMatchColumnWidth èªå¨ç®ï¼çº¦ 18ï¼ï¼ |
| | | // ä¸ç»è®°æ¶é´/å¼åæ¶é´ï¼Date ååå
æ ¼åªç®å° 12ï¼ä¸ä¸è´ï¼è¿éä¸åç»ä¸ã |
| | | @ColumnWidth(20) |
| | | private LocalDateTime bookTime; |
| | | |
| | | @Schema(description = "é¢çº¦æ£æ¥ç±»å", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") |
| | |
| | | @ExcelProperty(value = "é¢çº¦æ£æ¥ç±»å", converter = DictConvert.class) |
| | | private Integer bookCheckType; |
| | | |
| | | @Schema(description = "å
é¨é¢çº¦ç¼å·", requiredMode = Schema.RequiredMode.REQUIRED) |
| | | @ExcelProperty("å
é¨é¢çº¦ç¼å·") |
| | | /** |
| | | * æéå·ï¼å¯¹å¤å段åä¿æ bookSeqNum ä¸åï¼ã |
| | | * |
| | | * <p>ãå·ç»ä¸ï¼æ¬éæ±ï¼ã弿¥æºå·²æ¹ä¸º {@code queue.seq_num} ââ |
| | | * å·å¨ç¾å°æ¶ä¸æ¬¡æ§åé
ãä¹åä¸åï¼æ¬å段åªå¨"该é¢çº¦å·²æé"æ¶ç¨äºåæ¾ã |
| | | * æ¾ç¤ºæ¶è¯·æ¼ä¸ {@code check_type.seq_prefix}ï¼å·ææ£æ¥é¡¹ç®åèªç¼å·ï¼ä¼è·¨é¡¹ç®éå¤ï¼ã |
| | | */ |
| | | @Schema(description = "æéå·ï¼æ¥æº queue.seq_numï¼å·²æ book å·ï¼", requiredMode = Schema.RequiredMode.REQUIRED) |
| | | @ExcelProperty("æéå·") |
| | | private Integer bookSeqNum; |
| | | |
| | | @Schema(description = "é¢çº¦æ¥æºï¼Xç³»ç»ãæ¤å£«æå¨é¢çº¦", requiredMode = Schema.RequiredMode.REQUIRED) |
| | |
| | | */ |
| | | @Schema(description = "ç»è®°æ¶é´", requiredMode = Schema.RequiredMode.REQUIRED) |
| | | @ExcelProperty("ç»è®°æ¶é´") |
| | | // ãæ¬éæ±ãå宽åºå® 20ï¼ä¸ãé¢çº¦åçæ¶é´ãä¸è´ï¼ï¼ |
| | | // Date ååå
æ ¼å¨ LongestMatchColumnWidth ä¸åªä¼ç®å° 12ï¼æ¶é´è¢«æªæã |
| | | @ColumnWidth(20) |
| | | private Date registerDate; |
| | | |
| | | /** |
| | |
| | | * å¼åæ¶é´ |
| | | */ |
| | | @ExcelProperty("å¼åæ¶é´") |
| | | // ãæ¬éæ±ãå宽åºå® 20ï¼ä¸ãé¢çº¦åçæ¶é´ãä¸è´ï¼ |
| | | @ColumnWidth(20) |
| | | private Date doctorTime; |
| | | |
| | | // ==================== HIS æ¥å
¥è¡¥å
åæ®µï¼2026-09-27 é表æ°å¢åä¸èµ·å å
¥ï¼ ==================== |
| | |
| | | import cn.hutool.extra.servlet.ServletUtil; |
| | | import cn.lihu.jh.framework.common.pojo.CommonResult; |
| | | import cn.lihu.jh.framework.common.util.object.BeanUtils; |
| | | import cn.lihu.jh.module.ecg.dal.dataobject.checktype.CheckTypeDO; |
| | | import cn.lihu.jh.module.ecg.dal.dataobject.queue.QueueDO; |
| | | import cn.lihu.jh.module.ecg.dal.mysql.checktype.CheckTypeMapper; |
| | | import cn.lihu.jh.module.ecg.service.callingscreen.CallingScreenService; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.stream.Collectors; |
| | | |
| | | import static cn.lihu.jh.framework.common.pojo.CommonResult.error; |
| | | import static cn.lihu.jh.framework.common.pojo.CommonResult.success; |
| | |
| | | |
| | | @Resource |
| | | private CallingScreenService callingScreenService; |
| | | |
| | | /** ç¨äºç»å±å¹æ°æ®è¡¥ãæéå·åç¼ãï¼check_type.seq_prefixï¼ */ |
| | | @Resource |
| | | private CheckTypeMapper checkTypeMapper; |
| | | |
| | | /** ãéå«ãç¨äºç»å±å¹æ°æ®è¡¥"æè¿ä¸æ¬¡å«å·è®°å½id"ï¼call_patientï¼ */ |
| | | @Resource |
| | | private cn.lihu.jh.module.ecg.dal.mysql.call.CallMapper callMapper; |
| | | |
| | | @GetMapping("/display-col-info") |
| | | @Operation(summary = "å䏿¾ç¤ºçæ£æ¥ç±»ååç§°") |
| | |
| | | Map<Integer, List<QueueDO>> map = callingScreenService.getBigScreenPatient(); |
| | | |
| | | Map<Integer, List<ScreenQueueRespVO>> mapVO = new HashMap<>(); |
| | | // å±å¹è¦æ¾ç¤ºãåç¼ + æéå·ãï¼è®¾å¤æªç»å½æ¿ä¸å°æ£æ¥é¡¹ç®åå
¸ï¼æ
ç±å端ä¸å¹¶ä¸åï¼æ¯æ¬¡è¯·æ±è¯»ä¸æ¬¡ï¼ |
| | | Map<Integer, String> seqPrefixMap = getSeqPrefixMap(); |
| | | // ãéå«ãä¸å¹¶ä¸å"æè¿ä¸æ¬¡å«å·è®°å½id"ï¼å±å¹æ®æ¤éæ°ææ¥ |
| | | Map<String, Long> callIdMap = getLatestCallIdMap(); |
| | | map.keySet().forEach( displayCol -> { |
| | | //log.info("dispayCol: " + displayCol); |
| | | List<QueueDO> columnQueueDOList = map.get(displayCol); |
| | | List<ScreenQueueRespVO> screenQueueRespVOList = BeanUtils.toBean(columnQueueDOList, ScreenQueueRespVO.class); |
| | | fillSeqPrefix(screenQueueRespVOList, seqPrefixMap); |
| | | fillCallId(screenQueueRespVOList, callIdMap); |
| | | mapVO.put(displayCol, screenQueueRespVOList); |
| | | }); |
| | | |
| | |
| | | List<QueueDO> queueDOList2 = callingScreenService.getRoomInstallRelatedPatient(reqIp, roomId); |
| | | |
| | | Map<Integer, List<ScreenQueueRespVO>> mapVO = new HashMap<>(); |
| | | mapVO.put(1, BeanUtils.toBean(queueDOList1, ScreenQueueRespVO.class)); |
| | | mapVO.put(2, BeanUtils.toBean(queueDOList2, ScreenQueueRespVO.class)); |
| | | List<ScreenQueueRespVO> waitingVOList = BeanUtils.toBean(queueDOList1, ScreenQueueRespVO.class); |
| | | List<ScreenQueueRespVO> installVOList = BeanUtils.toBean(queueDOList2, ScreenQueueRespVO.class); |
| | | // å±å¹è¦æ¾ç¤ºãåç¼ + æéå·ãï¼è®¾å¤æªç»å½æ¿ä¸å°æ£æ¥é¡¹ç®åå
¸ï¼æ
ç±å端ä¸å¹¶ä¸åï¼æ¯æ¬¡è¯·æ±è¯»ä¸æ¬¡ï¼ |
| | | Map<Integer, String> seqPrefixMap = getSeqPrefixMap(); |
| | | Map<String, Long> callIdMap = getLatestCallIdMap(); |
| | | fillSeqPrefix(waitingVOList, seqPrefixMap); |
| | | fillSeqPrefix(installVOList, seqPrefixMap); |
| | | fillCallId(waitingVOList, callIdMap); |
| | | fillCallId(installVOList, callIdMap); |
| | | mapVO.put(1, waitingVOList); |
| | | mapVO.put(2, installVOList); |
| | | return success( mapVO ); |
| | | } |
| | | |
| | | /** |
| | | * ç»å±å¹æ°æ®è¡¥ä¸ãæéå·æ¾ç¤ºåç¼ã= {@code check_type.seq_prefix}ã |
| | | * |
| | | * <p>ãå·ç»ä¸ï¼æ¬éæ±ï¼ãæéå·ææ£æ¥é¡¹ç®åèªç¼å·ï¼ä¸åæ£æ¥é¡¹ç®ä¼åºç°ç¸åæ°åï¼ |
| | | * å±å¹ä¸å¿
须带åç¼æå徿¸
ï¼ä¾ï¼A5 / B5ï¼ãå±å¹è®¾å¤ä¸ç»å½ãæ æ³è°ç¨æ£æ¥é¡¹ç®æ¥å£ï¼ |
| | | * å æ¤å¨è¿éè¡¥é½ã |
| | | * |
| | | * <p>æ¯æ¬¡è¯·æ±æ¥ä¸æ¬¡å
¨è¡¨å»ºæ å°ï¼æ£æ¥é¡¹ç®åªæåå 个ï¼é级å¾å°ï¼ï¼ |
| | | * ä¸åé¿æç¼åï¼é¿å
管çåæ¹äºåç¼åå±å¹ä¸ç´æ¾ç¤ºæ§å¼ã |
| | | * æ¥ä¸å°é
ç½®æ¶ç空串ââå®å¯åªæ¾ç¤ºæ°åï¼ä¹ä¸è¦è®©å±å¹æ¥éæç©ºç½ã |
| | | */ |
| | | private void fillSeqPrefix(List<ScreenQueueRespVO> voList, Map<Integer, String> seqPrefixMap) { |
| | | if (voList == null || voList.isEmpty() || seqPrefixMap == null) { |
| | | return; |
| | | } |
| | | voList.forEach(vo -> vo.setSeqPrefix(seqPrefixMap.getOrDefault(vo.getBookCheckType(), ""))); |
| | | } |
| | | |
| | | /* ==================== éå«ï¼ä¸å"æè¿ä¸æ¬¡å«å·è®°å½id" ==================== */ |
| | | |
| | | /** |
| | | * ç»å±å¹æ°æ®è¡¥ä¸ {@code callId}ï¼è¯¥æ£è
æè¿ä¸æ¬¡å«å·è®°å½ç idï¼ã |
| | | * |
| | | * <p>为ä»ä¹éè¦ï¼å±å¹ææ¥é "æ°æ®åå"触å ââ 大å±å¤æ"ææ£è
æ°åºç°å¨å«å·å"ã |
| | | * è¯é´å±å¤æ"è¯ä¸ç¬¬ä¸äººåå"ãèå»çç¹ãéå«ãæ¶**æ£è
è¿æ¯é£ä¸ªäººãè¯å®¤è¿æ¯é£ä¸ªè¯å®¤**ï¼ |
| | | * éåæ°æ®ä¸ç¹æ²¡åï¼ä¸¤åå±èªç¶ä¸ä¼åæãéå«ä¼æ°å¢ä¸æ¡å«å·è®°å½ï¼call_patientï¼ï¼ |
| | | * æå®ç id ä¸ååï¼å±å¹åªè¦åç° callId åäºå°±éæ°ææ¥ã |
| | | */ |
| | | private void fillCallId(List<ScreenQueueRespVO> voList, Map<String, Long> callIdMap) { |
| | | if (voList == null || voList.isEmpty() || callIdMap == null || callIdMap.isEmpty()) { |
| | | return; |
| | | } |
| | | voList.forEach(vo -> { |
| | | if (null != vo.getPatId()) { |
| | | vo.setCallId(callIdMap.get(vo.getPatId())); |
| | | } |
| | | }); |
| | | } |
| | | |
| | | /** 䏿¬¡æ¥è¯¢åå°ãæ£è
ç¼å· â æè¿ä¸æ¬¡å«å·è®°å½ idãï¼å¤±è´¥æ¶è¿å空æ å°ï¼å±å¹æèé»è¾ææ¥ï¼ */ |
| | | private Map<String, Long> getLatestCallIdMap() { |
| | | try { |
| | | Map<String, Long> map = new HashMap<>(); |
| | | for (Map<String, Object> row : callMapper.selectLatestCallIds()) { |
| | | Object patId = row.get("patId"); |
| | | Object callId = row.get("callId"); |
| | | if (null != patId && callId instanceof Number) { |
| | | map.put(String.valueOf(patId), ((Number) callId).longValue()); |
| | | } |
| | | } |
| | | return map; |
| | | } catch (Exception e) { |
| | | log.error("[getLatestCallIdMap] 读åæè¿å«å·è®°å½å¤±è´¥ï¼éå«å°ä¸ä¼è§¦åå±å¹éæ", e); |
| | | return new HashMap<>(); |
| | | } |
| | | } |
| | | |
| | | /** è¯»ä¸æ¬¡æ£æ¥é¡¹ç®é
ç½®ï¼å¾å°ãæ£æ¥é¡¹ç®å¼ â æéå·åç¼ãæ å°ï¼å¤±è´¥æ¶è¿å空æ å°ï¼å±å¹åªæ¾ç¤ºå·ï¼ */ |
| | | private Map<Integer, String> getSeqPrefixMap() { try { |
| | | return checkTypeMapper.simpleCheckTypeList().stream() |
| | | .filter(checkType -> null != checkType.getValue()) |
| | | .collect(Collectors.toMap(CheckTypeDO::getValue, |
| | | checkType -> null == checkType.getSeqPrefix() ? "" : checkType.getSeqPrefix(), |
| | | (a, b) -> a)); |
| | | } catch (Exception e) { |
| | | log.error("[getSeqPrefixMap] è¯»åæ£æ¥é¡¹ç®åç¼å¤±è´¥ï¼å±å¹å°åªæ¾ç¤ºå·", e); |
| | | return new HashMap<>(); |
| | | } |
| | | } |
| | | |
| | | } |
| | |
| | | @ExcelProperty("æéåºå·") |
| | | private Integer seqNum; |
| | | |
| | | @Schema(description = "é¢çº¦åºå·", requiredMode = Schema.RequiredMode.REQUIRED) |
| | | /** |
| | | * æéå·æ¾ç¤ºåç¼ï¼{@code check_type.seq_prefix}ï¼ã |
| | | * |
| | | * <p>ãå·ç»ä¸ï¼æ¬éæ±ï¼ãæéå·æ¹ä¸º**ææ£æ¥é¡¹ç®åèªç¼å·**ï¼ä¸åæ£æ¥é¡¹ç®ä¹é´ä¼åºç°ç¸åæ°å |
| | | * ï¼ä¾ï¼å¨æå¿çµ 5 å·ã卿è¡å 5 å·ï¼ï¼å±å¹å¿
é¡»é åç¼åºåï¼æ
ç±å端ééåæ°æ®ä¸å¹¶ä¸åã |
| | | * <p>å±å¹è®¾å¤æªç»å½ãæ¿ä¸å°æ£æ¥é¡¹ç®åå
¸æ¥å£ï¼å æ¤ä¸è½ç±å端èªè¡æ¥è¡¨ã |
| | | */ |
| | | @Schema(description = "æéå·æ¾ç¤ºåç¼ï¼æ£æ¥é¡¹ç®é
ç½®ç seq_prefixï¼", example = "A") |
| | | @ExcelProperty("æéå·åç¼") |
| | | private String seqPrefix; |
| | | |
| | | /** ãå·²åç¨ãå±å¹è¯·æ¾ç¤º seqPrefix + seqNumï¼æ¬å段ä»
ä¿çå
¼å®¹èå±å¹é¡µé¢ï¼å端已ä¸ååå
¥ */ |
| | | @Schema(description = "é¢çº¦åºå·ï¼å·²åç¨ï¼è¯·ç¨ seqPrefix + seqNumï¼", requiredMode = Schema.RequiredMode.REQUIRED) |
| | | @ExcelProperty("é¢çº¦åºå·") |
| | | private Integer bookSeqNum; |
| | | |
| | | /** |
| | | * ãéå«ï¼æ¬éæ±ï¼ã该æ£è
**æè¿ä¸æ¬¡å«å·è®°å½**ç idã |
| | | * |
| | | * <p>å±å¹é "æ°æ®åå"è§¦åææ¥ï¼å»çç¹ãéå«ãåªä¼æ°å¢ä¸æ¡å«å·è®°å½ã䏿¹åéåæ°æ®ï¼ |
| | | * å æ¤æ callId ä¸å¹¶ä¸å ââ å®ä¸åï¼å±å¹å°±éæ°ææ¥ï¼å¤§å±ç»è¿"å䏿£è
åªæä¸æ¬¡"çéï¼ |
| | | * è¯é´å±å¯¹æ¯ä¸æ¬¡ç callIdï¼ã为空表示ä»å¤©è¿æ²¡æå«å·è®°å½ï¼å±å¹æèé»è¾å¤çã |
| | | */ |
| | | @Schema(description = "æè¿ä¸æ¬¡å«å·è®°å½idï¼ç¨äºé嫿¶éæ°ææ¥ï¼", example = "1234") |
| | | private Long callId; |
| | | |
| | | /** |
| | | * 5:è¿å· 10:æéä¸ 15:å·²å¬å 20:åè¯åå¤ 30:å°±è¯ä¸ 40:å°±è¯å®æ |
| | | */ |
| | | @Schema(description = "æéç¶æ", example = "1") |
| | |
| | | @Resource |
| | | private CheckTypeService checkTypeService; |
| | | |
| | | /** ãæ¬æ¬¡å åºãæ£æ¥é¡¹ç®æ¹å¨åå·æ°æé模åçæ£æ¥é¡¹ç®ç¼åï¼äº²å项ãåè¯ä¸éçï¼ï¼æ¹å®ä¸ç¨éå¯æå¡ */ |
| | | @Resource |
| | | private cn.lihu.jh.module.ecg.service.queue.QueueService queueService; |
| | | |
| | | @PostMapping("/create") |
| | | @Operation(summary = "åå»ºæ£æ¥ç±»å") |
| | | @PreAuthorize("@ss.hasPermission('ecg:check-type:create')") |
| | | public CommonResult<Integer> createCheckType(@Valid @RequestBody CheckTypeSaveReqVO createReqVO) { |
| | | return success(checkTypeService.createCheckType(createReqVO)); |
| | | Integer id = checkTypeService.createCheckType(createReqVO); |
| | | queueService.initCheckType(); |
| | | return success(id); |
| | | } |
| | | |
| | | @PutMapping("/update") |
| | |
| | | @PreAuthorize("@ss.hasPermission('ecg:check-type:update')") |
| | | public CommonResult<Boolean> updateCheckType(@Valid @RequestBody CheckTypeSaveReqVO updateReqVO) { |
| | | checkTypeService.updateCheckType(updateReqVO); |
| | | queueService.initCheckType(); |
| | | return success(true); |
| | | } |
| | | |
| | |
| | | @PreAuthorize("@ss.hasPermission('ecg:check-type:delete')") |
| | | public CommonResult<Boolean> deleteCheckType(@RequestParam("id") Integer id) { |
| | | checkTypeService.deleteCheckType(id); |
| | | queueService.initCheckType(); |
| | | return success(true); |
| | | } |
| | | |
| | |
| | | package cn.lihu.jh.module.ecg.controller.admin.devrent; |
| | | |
| | | |
| | | |
| | | import cn.lihu.jh.framework.security.core.util.SecurityFrameworkUtils; |
| | | |
| | | import cn.lihu.jh.module.ecg.dal.dataobject.appointment.AppointmentDO; |
| | | |
| | | import cn.lihu.jh.module.ecg.dal.dataobject.devmanage.DeviceDO; |
| | | |
| | | import cn.lihu.jh.module.ecg.enums.DevStateEnum; |
| | | |
| | | import cn.lihu.jh.module.ecg.annotation.RequireBedOwner; |
| | | |
| | | import cn.lihu.jh.module.ecg.service.appointment.AppointmentService; |
| | | |
| | | |
| | | import cn.lihu.jh.module.ecg.service.devmanage.DeviceService; |
| | | |
| | | |
| | | import cn.lihu.jh.module.ecg.service.queue.QueueService; |
| | | |
| | | import lombok.extern.slf4j.Slf4j; |
| | | |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import org.springframework.validation.annotation.Validated; |
| | | |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | | |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | |
| | | |
| | | |
| | | import java.util.*; |
| | | |
| | | import java.io.IOException; |
| | | |
| | | |
| | | |
| | | import cn.lihu.jh.framework.common.pojo.PageParam; |
| | | |
| | | import cn.lihu.jh.framework.common.pojo.PageResult; |
| | | |
| | | import cn.lihu.jh.framework.common.pojo.CommonResult; |
| | | |
| | | import cn.lihu.jh.framework.common.util.object.BeanUtils; |
| | | |
| | | |
| | | |
| | | import cn.lihu.jh.framework.excel.core.util.ExcelUtils; |
| | | |
| | | |
| | | |
| | | import cn.lihu.jh.framework.apilog.core.annotation.ApiAccessLog; |
| | | |
| | | |
| | | |
| | | import static cn.lihu.jh.framework.apilog.core.enums.OperateTypeEnum.*; |
| | | |
| | | |
| | | |
| | | import cn.lihu.jh.module.ecg.controller.admin.devrent.vo.*; |
| | | |
| | | import cn.lihu.jh.module.ecg.dal.dataobject.devrent.DevRentDO; |
| | | |
| | | |
| | | import cn.lihu.jh.module.ecg.service.devrent.DevRentService; |
| | | |
| | | |
| | | |
| | | import javax.annotation.Resource; |
| | | |
| | | import javax.servlet.http.HttpServletResponse; |
| | | |
| | | import javax.validation.Valid; |
| | | |
| | | |
| | | |
| | | @Tag(name = "è£
æºææº") |
| | | |
| | | @RestController |
| | | |
| | | @RequestMapping("/ecg/dev-rent") |
| | | |
| | | @Validated |
| | | |
| | | @Slf4j |
| | | |
| | | public class DevRentController { |
| | | |
| | | |
| | | |
| | | @Resource |
| | | |
| | | private DevRentService devRentService; |
| | | |
| | | |
| | | |
| | | @Resource |
| | | |
| | | private DeviceService deviceService; |
| | | |
| | | |
| | | |
| | | @Resource |
| | | |
| | | private QueueService queueService; |
| | | |
| | | |
| | | |
| | | @Resource |
| | | |
| | | private AppointmentService appointmentService; |
| | | |
| | | /** ã主/å´è§ãåæä½çå·¥ä½ä¸»äººæ ¡éªï¼åªå¸¦æ£è
ä¿¡æ¯çæ¥å£å¨æ¹æ³éæ¾å¼è°ç¨ï¼ */ |
| | | @Resource |
| | | |
| | | private cn.lihu.jh.module.ecg.service.room.RoomService roomService; |
| | | |
| | | |
| | | |
| | | // å¸¸è§æ£æ¥ 宿 |
| | | |
| | | @RequireBedOwner("æ£æ¥å®æ") |
| | | |
| | | @PostMapping("/routine-finish") |
| | | |
| | | @Operation(summary = "å¸¸è§æ£æ¥å®æ") |
| | | |
| | | @PreAuthorize("@ss.hasPermission('ecg:doctor:task')") |
| | | |
| | | public CommonResult<Long> routineFinish(@Valid @RequestBody RoutineFinishReqVO routineFinishReqVO) { |
| | | |
| | | CommonResult<Long> result = devRentService.routineFinishOperation(routineFinishReqVO); |
| | | |
| | | |
| | | |
| | | try { |
| | | |
| | | String userNickname = SecurityFrameworkUtils.getLoginUserNickname(); |
| | | |
| | | String userHisId = SecurityFrameworkUtils.getLoginUserHisId(); |
| | | Long rentId = routineFinishReqVO.getId(); |
| | | |
| | | // ã缺é·ä¿®å¤ãä¼å
ç¨**æå¡è¿åç rentId**ï¼= æ¬æ¬¡å®æå®é
åå
¥çæ£æ¥å idï¼ï¼ |
| | | // · æ®éæ£è
ï¼è¯·æ±éå¸¦äº idï¼ä¸¤è
ç¸åï¼ |
| | | // · ç´§æ¥å 忣è
ï¼è¯·æ±é没æ idï¼æ²¡ç¾å°è¿ï¼ï¼æå¡ä¼æ°å»ºæ£æ¥å ââ |
| | | // åå®ç°ç¨ routineFinishReqVO.getId()ï¼nullï¼å»ç¡®è´¹ï¼å¿
ç¶å¤±è´¥ï¼ä¸è¢« catch åæï¼ï¼ |
| | | // ç°åºè¡¨ç°ä¸º"å æ¥æ£è
æ£æ¥å®æå没æç¡®è´¹"ã |
| | | Long rentId = null != result && null != result.getData() |
| | | ? result.getData() : routineFinishReqVO.getId(); |
| | | |
| | | devRentService.feeConfirm(rentId, userHisId, userNickname, true); // æ
æ 䏿£æ¥è¿åå¼ |
| | | |
| | | } catch (Exception e) { |
| | | |
| | | log.error("å¸¸è§æ£æ¥å®æ, èªå¨ç¡®è´¹å¤±è´¥", e); |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | return result; |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | @RequireBedOwner("设å¤é¢ç¨å®æ") |
| | | |
| | | @PostMapping("/dev-ready") |
| | | |
| | | @Operation(summary = "设å¤é¢ç¨å®æ") |
| | | |
| | | @PreAuthorize("@ss.hasPermission('ecg:doctor:task')") |
| | | |
| | | public CommonResult<Long> devReady(@Valid @RequestBody DevRentSaveReqVO createReqVO) { |
| | | |
| | | String userHisId = SecurityFrameworkUtils.getLoginUserHisId(); |
| | | |
| | | String userNickname = SecurityFrameworkUtils.getLoginUserNickname(); |
| | | |
| | | createReqVO.setOperater(userNickname); |
| | | |
| | | CommonResult<Long> result = devRentService.readyOperation(createReqVO); |
| | | |
| | | |
| | | |
| | | try { |
| | | |
| | | Long rentId = createReqVO.getId(); |
| | | |
| | | devRentService.feeConfirm(rentId, userHisId, userNickname, true); // æ
æ 䏿£æ¥è¿åå¼ |
| | | |
| | | } catch (Exception e) { |
| | | |
| | | log.error("设å¤é¢ç¨å®æ, èªå¨ç¡®è´¹å¤±è´¥", e); |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | return result; |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | @RequireBedOwner("è£
æºå®æ") |
| | | |
| | | @PostMapping("/dev-install") |
| | | |
| | | @Operation(summary = "è£
æº") |
| | | |
| | | @PreAuthorize("@ss.hasPermission('ecg:doctor:task')") |
| | | |
| | | public CommonResult<Long> devInstall(@Valid @RequestBody DevRentSaveReqVO createReqVO) { |
| | | |
| | | return devRentService.installOperation(createReqVO); |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | @RequireBedOwner("ææº") |
| | | |
| | | @PostMapping("/dev-dismantle") |
| | | |
| | | @Operation(summary = "ææº") |
| | | |
| | | @PreAuthorize("@ss.hasPermission('ecg:doctor:task')") |
| | | |
| | | public CommonResult<Long> devDismantle(@Valid @RequestBody DevRentSaveReqVO createReqVO) { |
| | | |
| | | devRentService.dismantleOperation(createReqVO); |
| | | |
| | | return CommonResult.success(0L); |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | @RequireBedOwner("æ°æ®å½å
¥") |
| | | |
| | | @PostMapping("/dev-data-entry") |
| | | |
| | | @Operation(summary = "æ°æ®å½å
¥") |
| | | |
| | | @PreAuthorize("@ss.hasPermission('ecg:doctor:task')") |
| | | |
| | | public CommonResult<Long> devDataEntry(@Valid @RequestBody DevRentSaveReqVO createReqVO) { |
| | | |
| | | devRentService.dataEntryOperation(createReqVO); |
| | | |
| | | return CommonResult.success(0L); |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | @PostMapping("/routine-check-cancel") |
| | | |
| | | @Operation(summary = "åæ¶å¸¸è§æ£æ¥") |
| | | |
| | | @PreAuthorize("@ss.hasPermission('ecg:doctor:task')") |
| | | |
| | | public CommonResult<Long> routineCheckCancel(@Valid @RequestBody DevCancelReqVO cancelReqVO) { |
| | | |
| | | // ã主/å´è§ã该æ¥å£æ²¡æ roomId/bedNoï¼æãæ£è
+ æ£æ¥é¡¹ç®ã忥å
¶æå¨å·¥ä½åæ ¡éªä¸»äººèº«ä»½ |
| | | roomService.assertBedOwnerByPatient(cancelReqVO.getPatId(), cancelReqVO.getCheckType()); |
| | | |
| | | return devRentService.cancelRoutineOperation(cancelReqVO); |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | @PostMapping("/dev-ready-cancel") |
| | | |
| | | @Operation(summary = "åæ¶é¢ç¨") |
| | | |
| | | @PreAuthorize("@ss.hasPermission('ecg:doctor:task')") |
| | | |
| | | public CommonResult<Long> devReadyCancel(@Valid @RequestBody DevCancelReqVO cancelReqVO) { |
| | | |
| | | // ã主/å´è§ãæãæ£è
+ æ£æ¥é¡¹ç®ã忥工ä½åæ ¡éªä¸»äººèº«ä»½ |
| | | roomService.assertBedOwnerByPatient(cancelReqVO.getPatId(), cancelReqVO.getCheckType()); |
| | | |
| | | return devRentService.cancelReadyOperation(cancelReqVO); |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | @PostMapping("/dev-install-cancel") |
| | | |
| | | @Operation(summary = "åæ¶è£
æº") |
| | | |
| | | @PreAuthorize("@ss.hasPermission('ecg:doctor:task')") |
| | | |
| | | public CommonResult<Long> devInstallCancel(@Valid @RequestBody DevCancelReqVO cancelReqVO) { |
| | | |
| | | // ã主/å´è§ãæãæ£è
+ æ£æ¥é¡¹ç®ã忥工ä½åæ ¡éªä¸»äººèº«ä»½ |
| | | roomService.assertBedOwnerByPatient(cancelReqVO.getPatId(), cancelReqVO.getCheckType()); |
| | | |
| | | return devRentService.cancelInstallOperation(cancelReqVO); |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | @RequireBedOwner("设å¤é失") |
| | | |
| | | @PostMapping("/dev-lose") |
| | | |
| | | @Operation(summary = "é失") |
| | | |
| | | @PreAuthorize("@ss.hasPermission('ecg:doctor:task')") |
| | | |
| | | public CommonResult<Long> devLose(@Valid @RequestBody DevRentSaveReqVO loseReqVO) { |
| | | |
| | | loseReqVO.setState(DevStateEnum.LOST.getState()); |
| | | |
| | | return devRentService.dismantleExceptionOperation(loseReqVO); |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | @RequireBedOwner("è®¾å¤æå") |
| | | |
| | | @PostMapping("/dev-damage") |
| | | |
| | | @Operation(summary = "æå") |
| | | |
| | | @PreAuthorize("@ss.hasPermission('ecg:doctor:task')") |
| | | |
| | | public CommonResult<Long> devDamage(@Valid @RequestBody DevRentSaveReqVO damageReqVO) { |
| | | |
| | | damageReqVO.setState(DevStateEnum.DAMAGED.getState()); |
| | | |
| | | return devRentService.dismantleExceptionOperation(damageReqVO); |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | @PostMapping("/create") |
| | | |
| | | @Operation(summary = "å建è£
æºææº") |
| | | |
| | | @PreAuthorize("@ss.hasPermission('ecg:doctor:task')") |
| | | |
| | | public CommonResult<Long> createDevRent(@Valid @RequestBody DevRentSaveReqVO createReqVO) { |
| | | |
| | | return CommonResult.success(devRentService.createDevRent(createReqVO)); |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | @PutMapping("/update") |
| | | |
| | | @Operation(summary = "æ´æ°è£
æºææº") |
| | | |
| | | @PreAuthorize("@ss.hasPermission('ecg:doctor:task')") |
| | | |
| | | public CommonResult<Boolean> updateDevRent(@Valid @RequestBody DevRentSaveReqVO updateReqVO) { |
| | | |
| | | devRentService.updateDevRent(updateReqVO); |
| | | |
| | | return CommonResult.success(true); |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | @DeleteMapping("/delete") |
| | | |
| | | @Operation(summary = "å é¤è£
æºææº") |
| | | |
| | | @Parameter(name = "id", description = "ç¼å·", required = true) |
| | | |
| | | @PreAuthorize("@ss.hasPermission('ecg:doctor:task')") |
| | | |
| | | public CommonResult<Boolean> deleteDevRent(@RequestParam("id") Long id) { |
| | | |
| | | devRentService.deleteDevRent(id); |
| | | |
| | | return CommonResult.success(true); |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | @GetMapping("/get") |
| | | |
| | | @Operation(summary = "è·å¾è£
æºææº") |
| | | |
| | | @Parameter(name = "id", description = "ç¼å·", required = true, example = "1024") |
| | | |
| | | @PreAuthorize("@ss.hasPermission('ecg:doctor:task')") |
| | | |
| | | public CommonResult<DevRentRespVO> getDevRent(@RequestParam("id") Long id) { |
| | | |
| | | DevRentDO devRent = devRentService.getDevRent(id); |
| | | |
| | | |
| | | |
| | | DevRentRespVO devRentRespVO = BeanUtils.toBean(devRent, DevRentRespVO.class); |
| | | |
| | | |
| | | |
| | | DeviceDO deviceDO = deviceService.getDevice(devRent.getDevId()); |
| | | |
| | | if (null != deviceDO) { |
| | | |
| | | devRentRespVO.setCategory(deviceDO.getCategory()); |
| | | |
| | | devRentRespVO.setBrand(deviceDO.getBrand()); |
| | | |
| | | devRentRespVO.setModel(deviceDO.getModel()); |
| | | |
| | | devRentRespVO.setDevState(deviceDO.getState()); |
| | | |
| | | } |
| | | |
| | | return CommonResult.success(devRentRespVO); |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | @GetMapping("/page") |
| | | |
| | | @Operation(summary = "è·å¾è£
æºææºå页") |
| | | |
| | | @PreAuthorize("@ss.hasPermission('ecg:doctor:task')") |
| | | |
| | | public CommonResult<PageResult<DevRentRespVO>> getDevRentPage(@Valid DevRentPageReqVO pageReqVO) { |
| | | |
| | | PageResult<DevRentDO> pageResult = devRentService.getDevRentPage(pageReqVO); |
| | | |
| | | return CommonResult.success(BeanUtils.toBean(pageResult, DevRentRespVO.class)); |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | @GetMapping("/export-excel") |
| | | |
| | | @Operation(summary = "导åºè£
æºææº Excel") |
| | | |
| | | @PreAuthorize("@ss.hasPermission('ecg:dev-rent:export')") |
| | | |
| | | @ApiAccessLog(operateType = EXPORT) |
| | | |
| | | public void exportDevRentExcel(@Valid DevRentPageReqVO pageReqVO, HttpServletResponse response) throws IOException { |
| | | |
| | | pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); |
| | | |
| | | List<DevRentDO> list = devRentService.getDevRentPage(pageReqVO).getList(); |
| | | |
| | | // å¯¼åº Excel |
| | | |
| | | ExcelUtils.write(response, "è£
æºææº.xls", "æ°æ®", DevRentRespVO.class, BeanUtils.toBean(list, DevRentRespVO.class)); |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | @GetMapping("/get-free-rent") |
| | | |
| | | @Operation(summary = "æ ¹æ®æ£è
æè®¾å¤, è·åå·²é¢åç§èµæ
åµ") |
| | | |
| | | @PreAuthorize("@ss.hasPermission('ecg:doctor:task')") |
| | | |
| | | public CommonResult<DevRentRespVO> getFreeRent(@Valid DevRentSearchReqVO searchReqVO) { |
| | | |
| | | DevRentDO devRent = devRentService.getFreeRent(searchReqVO); |
| | | |
| | | if (null == devRent) { |
| | | |
| | | return CommonResult.success(null); |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | DevRentRespVO devRentRespVO = BeanUtils.toBean(devRent, DevRentRespVO.class); |
| | | |
| | | return CommonResult.success(devRentRespVO); |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | @GetMapping("/get-ready-rent") |
| | | |
| | | @Operation(summary = "è·åå·²é¢åç§èµæ
åµ") |
| | | |
| | | @PreAuthorize("@ss.hasPermission('ecg:doctor:task')") |
| | | |
| | | public CommonResult<DevRentRespVO> getReadyRent(@Valid DevRentSearchReqVO searchReqVO) { |
| | | |
| | | DevRentDO devRent = devRentService.getReadyOrCancelledRent(searchReqVO); |
| | | |
| | | if (null == devRent) { |
| | | |
| | | return CommonResult.success(null); |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | DevRentRespVO devRentRespVO = BeanUtils.toBean(devRent, DevRentRespVO.class); |
| | | |
| | | |
| | | |
| | | DeviceDO deviceDO = deviceService.getDevice(devRent.getDevId()); |
| | | |
| | | if (null != deviceDO) { |
| | | |
| | | devRentRespVO.setCategory(deviceDO.getCategory()); |
| | | |
| | | devRentRespVO.setBrand(deviceDO.getBrand()); |
| | | |
| | | devRentRespVO.setModel(deviceDO.getModel()); |
| | | |
| | | devRentRespVO.setDevState(deviceDO.getState()); |
| | | |
| | | } |
| | | |
| | | return CommonResult.success(devRentRespVO); |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | @GetMapping("/get-existing-rent") |
| | | |
| | | @Operation(summary = "è·åå·²å®è£
ãå·²é¢ç¨çç§èµæ
åµ") |
| | | |
| | | @PreAuthorize("@ss.hasPermission('ecg:doctor:task')") |
| | | |
| | | public CommonResult<DevRentRespVO> getInstalledRent(@Valid DevRentSearchReqVO searchReqVO) { |
| | | |
| | | DevRentDO devRent = devRentService.getExistingRent(searchReqVO); |
| | | |
| | | if (null == devRent) { |
| | | |
| | | return CommonResult.success(null); |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | DeviceDO deviceDO = deviceService.getDevice(devRent.getDevId()); |
| | | |
| | | |
| | | |
| | | DevRentRespVO devRentRespVO = BeanUtils.toBean(devRent, DevRentRespVO.class); |
| | | |
| | | devRentRespVO.setCategory(deviceDO.getCategory()); |
| | | |
| | | devRentRespVO.setBrand(deviceDO.getBrand()); |
| | | |
| | | devRentRespVO.setModel(deviceDO.getModel()); |
| | | |
| | | devRentRespVO.setDevState(devRent.getState()); |
| | | |
| | | return CommonResult.success(devRentRespVO); |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | @GetMapping("/get-dismantled-rent") |
| | | |
| | | @Operation(summary = "è·åå·²æå¸ç§èµæ
åµ") |
| | | |
| | | @PreAuthorize("@ss.hasPermission('ecg:doctor:task')") |
| | | |
| | | public CommonResult<DevRentRespVO> getDismantledRent(@Valid DevRentSearchReqVO searchReqVO) { |
| | | |
| | | DevRentDO devRent = devRentService.getDismantledRent(searchReqVO); |
| | | |
| | | if (null == devRent) { |
| | | |
| | | return CommonResult.success(null); |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | DeviceDO deviceDO = deviceService.getDevice(devRent.getDevId()); |
| | | |
| | | |
| | | |
| | | DevRentRespVO devRentRespVO = BeanUtils.toBean(devRent, DevRentRespVO.class); |
| | | |
| | | devRentRespVO.setCategory(deviceDO.getCategory()); |
| | | |
| | | devRentRespVO.setBrand(deviceDO.getBrand()); |
| | | |
| | | devRentRespVO.setModel(deviceDO.getModel()); |
| | | |
| | | return CommonResult.success(devRentRespVO); |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | // 确费 |
| | | |
| | | @GetMapping("/fee-confirm") |
| | | |
| | | @Operation(summary = "确费") |
| | | |
| | | @PreAuthorize("@ss.hasPermission('ecg:doctor:task')") |
| | | |
| | | public CommonResult<Integer> feeConfirm(@Valid Long rentId) { |
| | | |
| | | Long userId = SecurityFrameworkUtils.getLoginUserId(); |
| | | |
| | | String userNickname = SecurityFrameworkUtils.getLoginUserNickname(); |
| | | |
| | | String userHisId = SecurityFrameworkUtils.getLoginUserHisId(); |
| | | |
| | | |
| | | |
| | | // ã主/å´è§ã确费ä¹è¦æ¦å´è§äººï¼æè¯¥ç§èµåçæ£è
忥å
¶å½åå·¥ä½å¹¶æ ¡éªä¸»äººèº«ä»½ã |
| | | // ç¨ Soft çæ¬ï¼ç¡®è´¹å¸¸å¨æµç¨æ«ç«¯è°ç¨ï¼æ£è
å¯è½å·²ä¸å¨éåä¸ï¼æ¥ä¸å°å·¥ä½æ¶åªè®°è¦åæ¾è¡ã |
| | | assertRentBedOwnerSoft(rentId); |
| | | |
| | | Integer result = devRentService.feeConfirm(rentId, userHisId, userNickname, true); |
| | | |
| | | if (1 == result) return CommonResult.error(result, "确费失败"); |
| | | |
| | | |
| | | |
| | | return CommonResult.success(result); |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | // åæ¶ç¡®è´¹ |
| | | |
| | | @GetMapping("/fee-cancel") |
| | | |
| | | @Operation(summary = "åæ¶ç¡®è´¹") |
| | | |
| | | @PreAuthorize("@ss.hasPermission('ecg:doctor:task')") |
| | | |
| | | public CommonResult<Integer> feeCancel(@Valid Long rentId) { |
| | | |
| | | Long userId = SecurityFrameworkUtils.getLoginUserId(); |
| | | |
| | | String userNickname = SecurityFrameworkUtils.getLoginUserNickname(); |
| | | |
| | | String userHisId = SecurityFrameworkUtils.getLoginUserHisId(); |
| | | |
| | | |
| | | |
| | | // ã主/å´è§ãåæ¶ç¡®è´¹åæ ·è¦æ¦å´è§äººï¼Softï¼æ¥ä¸å°å·¥ä½åªè®°è¦åï¼ |
| | | assertRentBedOwnerSoft(rentId); |
| | | |
| | | Integer result = devRentService.feeConfirm(rentId, userHisId, userNickname, false); |
| | | |
| | | if (1 == result) return CommonResult.error(result, "åæ¶ç¡®è´¹å¤±è´¥"); |
| | | |
| | | |
| | | |
| | | return CommonResult.success(result); |
| | | |
| | | } |
| | | |
| | | /** |
| | | * ã主/å´è§ã确费 / åæ¶ç¡®è´¹çä¸»äººæ ¡éªã |
| | | * |
| | | * <p>æ¥å£åªå¸¦ rentIdï¼æ¿ä¸å° roomId/bedNoï¼å æ¤å
æç§èµåæ¾å°æ£è
ï¼ |
| | | * åç± {@link cn.lihu.jh.module.ecg.service.room.RoomService#assertBedOwnerByPatientSoft} |
| | | * ææ£è
å½åæå¨å·¥ä½æ ¡éªä¸»äººèº«ä»½ï¼æ¥ä¸å°å·¥ä½æ¶åªè®°è¦åæ¾è¡ï¼é¿å
误伤æ«ç«¯æµç¨ï¼ã |
| | | * |
| | | * <p>注æï¼åªå
ä½"读ç§èµå"è¿ä¸æ¥ï¼**ä¸è½**æä¸»äººæ ¡éªçå¼å¸¸ä¹åæï¼å¦åçäºæ²¡ææ ¡éªã |
| | | */ |
| | | private void assertRentBedOwnerSoft(Long rentId) { |
| | | cn.lihu.jh.module.ecg.dal.dataobject.devrent.DevRentDO rent; |
| | | try { |
| | | rent = devRentService.getDevRent(rentId); |
| | | } catch (Exception e) { |
| | | log.error("[assertRentBedOwnerSoft] 读åç§èµå失败ï¼è·³è¿ä¸»äººæ ¡éª. rentId={}", rentId, e); |
| | | return; |
| | | } |
| | | roomService.assertBedOwnerByPatientSoft(null == rent ? null : rent.getPatId(), |
| | | null == rent ? null : rent.getCheckType()); |
| | | } |
| | | |
| | | } |
| | | |
| | |
| | | |
| | | @Schema(description = "è¯åºç¼å·") |
| | | String bedNo; |
| | | |
| | | /** |
| | | * ãæ¬éæ±ï¼ç´§æ¥æ£è
䏿éç´æ¥æ£æ¥ãæ¯å¦ãç´§æ¥å åãã |
| | | * |
| | | * <p>为 {@code true} æ¶ï¼å端å¨è¯¥æ£è
+ æ£æ¥é¡¹ç®**ä»å¤©æ²¡æãå¾
æ£æ¥(0)ãæ£æ¥å**çæ
åµä¸ï¼ |
| | | * 伿é¢çº¦åèªå¨è¡¥å»ºä¸æ¡ï¼å 为è¿äºæ£è
没走ç¾å°/æéï¼æ£å¸¸ç¾å°æä¼å»ºè¿æ¡ï¼ï¼ |
| | | * ä»èå¯ä»¥åæéæ£è
䏿 ·å®ææ£æ¥å¹¶åå
¥ã已宿å表ãã |
| | | * |
| | | * <p>为 {@code false}/{@code null} æ¶ï¼è¡ä¸ºä¸æ¹é å**å®å
¨ä¸è´**ã |
| | | */ |
| | | @Schema(description = "æ¯å¦ç´§æ¥å åï¼ä¸æéç´æ¥æ£æ¥ï¼", example = "false") |
| | | private Boolean emergency; |
| | | } |
| | |
| | | import cn.lihu.jh.module.ecg.dal.dataobject.queue.QueueDO; |
| | | import cn.lihu.jh.module.ecg.dal.dataobject.room.RoomDO; |
| | | import cn.lihu.jh.module.ecg.enums.QueueStatusEnum; |
| | | import cn.lihu.jh.module.ecg.annotation.RequireBedOwner; |
| | | import cn.lihu.jh.module.ecg.service.call.CallService; |
| | | import cn.lihu.jh.module.ecg.service.queue.QueueService; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | |
| | | import javax.annotation.Resource; |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.Objects; |
| | | |
| | | import static cn.lihu.jh.framework.common.exception.enums.GlobalErrorCodeConstants.SUCCESS; |
| | |
| | | @Resource |
| | | private QueueService queueService; |
| | | |
| | | /** ãæ¬æ¬¡ä¿®å¤ãæ¤é"æ£æ¥å®æ"æ¶åæ»æ£æ¥åç¶æå¹¶åæ¶ç¡®è´¹ */ |
| | | @Resource |
| | | private cn.lihu.jh.module.ecg.service.devrent.DevRentService devRentService; |
| | | |
| | | @Resource |
| | | private CallService callService; |
| | | |
| | | @RequireBedOwner("æåæ¥è¯") |
| | | @GetMapping("/bed-doctor-pause") |
| | | @Operation(summary = "å»çæå") |
| | | @PreAuthorize("@ss.hasPermission('ecg:doctor:state')") |
| | |
| | | return error(result); |
| | | } |
| | | |
| | | @RequireBedOwner("æ¢å¤æ¥è¯") |
| | | @GetMapping("/bed-doctor-resume") |
| | | @Operation(summary = "å»çæ¢å¤") |
| | | @PreAuthorize("@ss.hasPermission('ecg:doctor:state')") |
| | |
| | | @PreAuthorize("@ss.hasPermission('ecg:doctor:state')") |
| | | public CommonResult<Integer> bedDoctorOn( |
| | | @RequestParam("roomId") Long roomId, |
| | | @RequestParam("bedNo") String bedNo) |
| | | @RequestParam("bedNo") String bedNo, |
| | | // å·¥ä½ä¸»é®ï¼å端请æ±éæ¬æ¥å°±å¸¦ï¼ï¼ä¼ å
¥æ¶ä¼å
æå®å®ä½ï¼é¿å
bed_no ä¸è¯·æ±å¼ |
| | | // åå¨èç¼é¾è¾¨çå·®å¼ï¼ç»å°¾ç©ºæ ¼/大å°å/å
¨è§ï¼æ¶"ææç©ºé²å´æ´æ° 0 è¡" |
| | | @RequestParam(value = "id", required = false) Integer bedId) |
| | | { |
| | | Long userId = SecurityFrameworkUtils.getLoginUserId(); |
| | | String userNickname = SecurityFrameworkUtils.getLoginUserNickname(); |
| | | |
| | | ErrorCode result = queueService.startBedDoctorOn(roomId, bedNo, userId, userNickname); |
| | | ErrorCode result = queueService.startBedDoctorOn(roomId, bedNo, userId, userNickname, bedId); |
| | | if (result.equals(SUCCESS)) |
| | | return success(0); |
| | | |
| | |
| | | return result; |
| | | } |
| | | |
| | | @RequireBedOwner("å«å·ï¼åä¸ä¸ä½æ£è
") |
| | | @GetMapping("/finish-next-patient") |
| | | @Operation(summary = "常è§å«å·ãä¸ä¸ä½æ£è
") |
| | | @Parameter(name = "roomId", description = "è¯å®¤ç¼å·", required = true, example = "116") |
| | |
| | | return success(BeanUtils.toBean(queueDOList, QueueRespVO.class)); |
| | | } |
| | | |
| | | @RequireBedOwner("é¢ç¨ï¼åä¸ä¸ä½æ£è
") |
| | | @GetMapping("/finish-receive-next-patient") |
| | | @Operation(summary = "é¢ç¨å«å·ãä¸ä¸ä½æ£è
") |
| | | @Parameter(name = "roomId", description = "è¯å®¤ç¼å·", required = true, example = "116") |
| | |
| | | return success(BeanUtils.toBean(queueDOList, QueueRespVO.class)); |
| | | } |
| | | |
| | | @RequireBedOwner("è£
æºï¼åä¸ä¸ä½æ£è
") |
| | | @GetMapping("/finish-install-next-patient") |
| | | @Operation(summary = "è£
æºå«å·ãä¸ä¸ä½æ£è
") |
| | | @Parameter(name = "roomId", description = "è¯å®¤ç¼å·", required = true, example = "116") |
| | |
| | | } |
| | | |
| | | // å¸¸è§æ£æ¥è¿å·ãé¢ç¨è¿å· |
| | | @RequireBedOwner("è¿å·") |
| | | @GetMapping("/pass-next-patient") |
| | | @Operation(summary = "è¿å·ãä¸ä¸ä½æ£è
") |
| | | @Parameter(name = "roomId", description = "è¯å®¤ç¼å·", required = true, example = "116") |
| | |
| | | return success(BeanUtils.toBean(queueDOList, QueueRespVO.class)); |
| | | } |
| | | |
| | | @RequireBedOwner("è£
æºè¿å·") |
| | | @GetMapping("/pass-install-next-patient") |
| | | @Operation(summary = "å®è£
è¿å·ãä¸ä¸ä½æ£è
") |
| | | @Parameter(name = "roomId", description = "è¯å®¤ç¼å·", required = true, example = "116") |
| | |
| | | return success(BeanUtils.toBean(queueDOList, QueueRespVO.class)); |
| | | } |
| | | |
| | | @RequireBedOwner("éå«") |
| | | @GetMapping("/call-again") |
| | | @Operation(summary = "[å¸¸è§æ£æ¥]æ[é¢ç¨] éå«ãæ£è
") |
| | | @Parameter(name = "roomId", description = "è¯å®¤ç¼å·", required = true, example = "116") |
| | |
| | | } |
| | | |
| | | |
| | | @RequireBedOwner("éå«ï¼å®è£
ï¼") |
| | | @GetMapping("/call-install-again") |
| | | @Operation(summary = "éå«ãæ£è
") |
| | | @Parameter(name = "roomId", description = "è¯å®¤ç¼å·", required = true, example = "116") |
| | |
| | | @RequestParam("bedNo") String bedNo) |
| | | { |
| | | List<QueueDO> queueDOList = queueService.getCheckRelatedPatient(roomId, bedNo); |
| | | // ãèªå©è¯æãç°åºå¤æ¬¡åºç°"å表æ¯ç©ºç"å´çä¸åºåå ï¼è¿éæ**å端é®çå·¥ä½ + å端è¿åå æ¡** |
| | | // æåºæ¥ï¼é
忥å£ä¸èµ·çå°±è½ç«å»åºå"å端é®éå·¥ä½ / åç«¯ç¡®å®æ²¡æ°æ® / 页颿²¡å·æ°"ã |
| | | log.info("[getToBeCheckedPatientList] roomId={} bedNo=[{}] ç»å½äºº={} â è¿å {} æ¡", |
| | | roomId, bedNo, SecurityFrameworkUtils.getLoginUserId(), |
| | | null == queueDOList ? 0 : queueDOList.size()); |
| | | return success(BeanUtils.toBean(queueDOList, QueueRespVO.class)); |
| | | } |
| | | |
| | | @GetMapping("/get-room-waiting-list") |
| | | @Operation(summary = "忬è¯å®¤ãæéä¸ï¼æªåé
å·¥ä½ï¼ãæ£è
å表") |
| | | @Parameter(name = "roomId", description = "è¯å®¤ç¼å·", required = true, example = "121") |
| | | @Parameter(name = "bedNo", description = "å·¥ä½ç¼å·", required = true, example = "F1") |
| | | @PreAuthorize("@ss.hasPermission('ecg:doctor:task')") |
| | | public CommonResult<List<QueueRespVO>> getRoomWaitingList( |
| | | @RequestParam("roomId") Long roomId, |
| | | @RequestParam("bedNo") String bedNo) |
| | | { |
| | | // ãæ¬è¯å®¤æªåé
ãåè¯å表åªå«"已念尿¬å·¥ä½"çæ£è
ï¼è¿éæ"æ¬å·¥ä½æ£æ¥ç±»åã |
| | | // è¿æ²¡åé
å·¥ä½"çæéæ£è
ï¼å¤§å±è½çå°ãå·¥ä½å°åå
çä¸å°ï¼åç¬è¿åï¼ä¾å»çæå·¥æå
¥ã |
| | | List<QueueDO> queueDOList = queueService.getUnassignedWaitingPatient(roomId, bedNo); |
| | | log.info("[getRoomWaitingList] roomId={} bedNo=[{}] ç»å½äºº={} â æªåé
æéä¸ {} æ¡", |
| | | roomId, bedNo, SecurityFrameworkUtils.getLoginUserId(), |
| | | null == queueDOList ? 0 : queueDOList.size()); |
| | | return success(BeanUtils.toBean(queueDOList, QueueRespVO.class)); |
| | | } |
| | | |
| | | @RequireBedOwner("æå
¥æéæ£è
") |
| | | @GetMapping("/pull-waiting-patient") |
| | | @Operation(summary = "æãæéä¸ãçæ£è
æå·¥æå
¥æ¬å·¥ä½") |
| | | @Parameter(name = "roomId", description = "è¯å®¤ç¼å·", required = true, example = "121") |
| | | @Parameter(name = "bedNo", description = "å·¥ä½ç¼å·", required = true, example = "F1") |
| | | @Parameter(name = "id", description = "æéè¡id", required = true, example = "123") |
| | | @PreAuthorize("@ss.hasPermission('ecg:doctor:task')") |
| | | public CommonResult<String> pullWaitingPatient( |
| | | @RequestParam("roomId") Long roomId, |
| | | @RequestParam("bedNo") String bedNo, |
| | | @RequestParam("id") Integer id) |
| | | { |
| | | ErrorCode result = queueService.pullWaitingPatient(roomId, bedNo, id); |
| | | if (result.equals(SUCCESS)) |
| | | return success("æä½æå"); |
| | | |
| | | return error(result); |
| | | } |
| | | |
| | | @RequireBedOwner("ç«å³è¡¥äºº") |
| | | @GetMapping("/hurry-up-now") |
| | | @Operation(summary = "ç«å³è¡¥äººï¼æå¨è§¦åæ¬å·¥ä½èªå¨åæµï¼å¹¶è¿åè¯æä¿¡æ¯ï¼") |
| | | @Parameter(name = "roomId", description = "è¯å®¤ç¼å·", required = true, example = "121") |
| | | @Parameter(name = "bedNo", description = "å·¥ä½ç¼å·", required = true, example = "F1") |
| | | @PreAuthorize("@ss.hasPermission('ecg:doctor:task')") |
| | | public CommonResult<Map<String, Object>> hurryUpNow( |
| | | @RequestParam("roomId") Long roomId, |
| | | @RequestParam("bedNo") String bedNo) |
| | | { |
| | | // ç°åºèªæ + èªå©è¯æï¼åè¯åºä¸ºç©ºæ¶ç¹ä¸ä¸ï¼ç«å»å¾å° |
| | | // ãç³»ç»å¼è¯ç¶æ / æ¯å¦åæ¢åè¯ / åè¯ä¸é / 补人ååäººæ° / ç»è®ºãã |
| | | return success(queueService.hurryUpNow(roomId, bedNo)); |
| | | } |
| | | |
| | | @GetMapping("/get-to-be-installed-list") |
| | |
| | | return success(patientStatisticVO); |
| | | } |
| | | |
| | | // ãæ¬éæ±Â·æééå便å¡å°åè¯è°åº¦ä½¿ç¨ãä¸ååãå·¥ä½ä¸»äººãæ ¡éªï¼ |
| | | // åè¯å°ä¸å 座ï¼clinic_room.doc_id æ¯åè¯å»çï¼ï¼å¦åå¿
æ¥ 1010002003ãå´è§æ¨¡å¼ï¼ä¸è½æ§è¡è¯¥æä½ãã |
| | | // ä»ä¿ç @PreAuthorize('ecg:doctor:task') æéç¹ã |
| | | @GetMapping("/recall-pass-waiting-patient") |
| | | @Operation(summary = "è¿å·-æéä¸ æ£è
å¬å") |
| | | @Parameter(name = "patId", description = "æ£è
ç¼å·", required = true, example = "B2") |
| | |
| | | return success("æä½æå"); |
| | | } |
| | | |
| | | // ãæ¬éæ±Â·æééå便å¡å°åè¯è°åº¦ä½¿ç¨ãä¸ååãå·¥ä½ä¸»äººãæ ¡éªï¼åå åä¸ï¼ã |
| | | @GetMapping("/recall-patient") |
| | | @Operation(summary = "è¿å·ç
人å¬å") |
| | | @Parameter(name = "roomId", description = "è¯å®¤ç¼å·", required = true, example = "116") |
| | |
| | | return success("æä½æå"); |
| | | } |
| | | |
| | | // ãæ¬éæ±Â·æééå便å¡å°åè¯è°åº¦ä½¿ç¨ãä¸ååãå·¥ä½ä¸»äººãæ ¡éªï¼åå åä¸ï¼ã |
| | | @GetMapping("/recall-install-patient") |
| | | @Operation(summary = "è¿å·å®è£
ç
人å¬å") |
| | | @Parameter(name = "roomId", description = "è¯å®¤ç¼å·", required = true, example = "116") |
| | |
| | | @RequestParam("roomId_operator") Long roomId_operator, |
| | | @RequestParam("bedNo_operator") String bedNo_operator ) |
| | | { |
| | | if (roomId != roomId_operator) |
| | | return error(QUEUE_RECALL_INSTALL_NOT_CUR_ROOM); |
| | | // ãæ¬éæ±Â·æééå便å¡å°åè¯è°åº¦ä½¿ç¨ã廿ãæä½è
å·¥ä½å¿
é¡»çäºæ£è
å·¥ä½ãçæ ¡éªï¼ |
| | | // · åè¯å°ä¸å 座ï¼roomId_operator / bedNo_operator å¯è½æ¯ç©ºæä¸æå¡å°å½åå·¥ä½ä¸ä¸è´ï¼ |
| | | // · æééåé¡µä¼ çæ¯**éåè¡å
çå·¥ä½**ï¼æ¬æ¥ä¹åªç¨äºäº²å项鿰å®ä½ã |
| | | // åæ ¡éªï¼if (roomId != roomId_operator) return error(QUEUE_RECALL_INSTALL_NOT_CUR_ROOM); |
| | | // ç°å¨ï¼æä½è
å·¥ä½ç¼ºå¤±æ¶ï¼éåä¸ºç¨æ£è
éåè¡ä¸çå·¥ä½ï¼roomId/bedNoï¼ã |
| | | Long operatorRoomId = (null != roomId_operator) ? roomId_operator : roomId; |
| | | String operatorBedNo = (null != bedNo_operator && !bedNo_operator.isEmpty()) ? bedNo_operator : bedNo; |
| | | |
| | | Integer result = queueService.recallInstallPatient(roomId, bedNo, patId, checkType, roomId_operator, bedNo_operator); |
| | | Integer result = queueService.recallInstallPatient(roomId, bedNo, patId, checkType, operatorRoomId, operatorBedNo); |
| | | if (null == result || 0 == result) |
| | | return error(PATIENT_NOT_EXISTS); |
| | | |
| | |
| | | |
| | | // ==================== éæ±2ï¼æ¤éãå«å· / æ£æ¥å®æã ==================== |
| | | |
| | | @RequireBedOwner("æ¤éæ£æ¥å®æ") |
| | | @GetMapping("/undo-finish-patient") |
| | | @Operation(summary = "æ¤éæ£æ¥å®æï¼å·²å°±è¯(40) â åè¯ä¸(20)") |
| | | @Parameter(name = "roomId", description = "è¯å®¤ç¼å·", required = true, example = "116") |
| | |
| | | if (null == result || 0 == result) { |
| | | return error(APPOINTMENT_NOT_EXISTS); |
| | | } |
| | | // ãæ¬æ¬¡ä¿®å¤ãåªåæ»éåç¶ææ¯ä¸å¤çï¼æ£æ¥å(dev_rent)ä»åå¨ãå¸¸è§æ£æ¥å®æ(60)ãï¼ |
| | | // åç«¯åæ¬¡å®ææ¶åä¸å°ãå¾
æ£æ¥ãåï¼rentId 为空ï¼â å端æ¥ã请å
é¢çº¦ç¡®è®¤ãã |
| | | // è¿éææ£æ¥ååæ»æãå¾
æ£æ¥ãå¹¶åæ¶ç¡®è´¹ï¼å
é¨å·² try/catchï¼å¤±è´¥ä¸å½±åæ¤éç»æï¼ã |
| | | devRentService.rollbackRoutineFinish(patId, checkType); |
| | | return success("å·²æ¤éæ£æ¥å®æï¼æ£è
å·²è¿ååè¯åº"); |
| | | } |
| | | |
| | | @RequireBedOwner("æ¤éå«å·") |
| | | @GetMapping("/undo-call-patient") |
| | | @Operation(summary = "æ¤éå«å·ï¼å°±è¯ä¸(30) â åè¯ä¸(20)") |
| | | @Parameter(name = "roomId", description = "è¯å®¤ç¼å·", required = true, example = "116") |
| | |
| | | |
| | | // ==================== éæ±3ï¼åæ¢åè¯å¼å
³ ==================== |
| | | |
| | | @RequireBedOwner("忢åè¯") |
| | | @GetMapping("/stop-ready") |
| | | @Operation(summary = "忢åè¯ï¼ä¸åæ°å¢åè¯æ£è
ï¼å·²æåè¯ä»å¯å«å·ï¼") |
| | | @Parameter(name = "roomId", description = "è¯å®¤ç¼å·", required = true, example = "116") |
| | |
| | | return success(true); |
| | | } |
| | | |
| | | @RequireBedOwner("æ¢å¤åè¯") |
| | | @GetMapping("/resume-ready") |
| | | @Operation(summary = "æ¢å¤åè¯ï¼éæ°å¼å§æ¥æ¶åè¯æ£è
") |
| | | @Parameter(name = "roomId", description = "è¯å®¤ç¼å·", required = true, example = "116") |
| | |
| | | import cn.lihu.jh.module.ecg.controller.admin.jobrecord.vo.*; |
| | | import cn.lihu.jh.module.ecg.dal.dataobject.jobrecord.JobRecordDO; |
| | | import cn.lihu.jh.module.ecg.service.jobrecord.JobRecordService; |
| | | import cn.lihu.jh.module.ecg.service.room.RoomService; |
| | | |
| | | import javax.annotation.Resource; |
| | | import javax.servlet.http.HttpServletResponse; |
| | |
| | | |
| | | @Resource |
| | | private JobRecordService jobRecordService; |
| | | |
| | | /** ã主/å´è§ãå´è§äººæ¥"å·¥ä½ä¸»äººçè®°å½"æ¶éè¦æ ¡éªè¯¥å·¥ä½å½å主人 */ |
| | | @Resource |
| | | private RoomService roomService; |
| | | |
| | | @PostMapping("/create") |
| | | @Operation(summary = "å建工ä½è®°å½") |
| | |
| | | } |
| | | |
| | | @GetMapping("/doctor-page") |
| | | @Operation(summary = "è·å¾ç¨æ·èªå·±çå·¥ä½è®°å½å页") |
| | | @Operation(summary = "è·å¾å·¥ä½è®°å½å页ï¼é»è®¤æ¥èªå·±ï¼å´è§æ¶æå·¥ä½ä¸»äººæ¥ï¼") |
| | | @PreAuthorize("@ss.hasPermission('ecg:doctor:task')") |
| | | public CommonResult<PageResult<JobRecordRespVO>> getJobRecordDoctorPage(@Valid JobRecordPageReqVO pageReqVO) { |
| | | public CommonResult<PageResult<JobRecordRespVO>> getJobRecordDoctorPage( |
| | | @Valid JobRecordPageReqVO pageReqVO, |
| | | @RequestParam(value = "roomId", required = false) Long roomId, |
| | | @RequestParam(value = "bedNo", required = false) String bedNo) { |
| | | Long userId = SecurityFrameworkUtils.getLoginUserId(); |
| | | String userNickname = SecurityFrameworkUtils.getLoginUserNickname(); |
| | | |
| | | pageReqVO.setDocId( userId ); |
| | | // ã主/å´è§ãé»è®¤æ¥èªå·±çè®°å½ï¼ä¿æåè¡ä¸ºï¼ï¼ |
| | | // ä¼ äºå«äººç docIdï¼å´è§æ¶åç«¯ä¼ "该工ä½ä¸»äºº"ï¼â å¿
é¡»æ ¡éªè¯¥å·¥ä½å½åä¸»äººç¡®å®æ¯è¿ä¸ª docIdï¼ |
| | | // å¦åå´è§äººçå°ç"å·²å®ææ£æ¥è®°å½"æ°¸è¿æ¯ç©ºçï¼åå®ç°æ æ¡ä»¶è¦çæç»å½äººï¼ã |
| | | Long ownerDocId = pageReqVO.getDocId(); |
| | | if (null == ownerDocId || ownerDocId.equals(userId)) { |
| | | pageReqVO.setDocId(userId); |
| | | } else { |
| | | roomService.assertBedOwnerIs(roomId, bedNo, ownerDocId); |
| | | } |
| | | |
| | | PageResult<JobRecordDO> pageResult = jobRecordService.getJobRecordPage(pageReqVO); |
| | | return success(BeanUtils.toBean(pageResult, JobRecordRespVO.class)); |
| | | } |
| | |
| | | @Schema(description = "已缴费", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| | | @ExcelProperty("已缴费") |
| | | private Integer paid; |
| | | |
| | | /** |
| | | * ãæ¤éæ è¯ï½éåºå段ã该æ¡å®æè®°å½å¯¹åºçæ£è
"彿¥éåç¶æå·²ä¸æ¯å·²å°±è¯(40)"ï¼ |
| | | * å³**æ£æ¥å®æè¢«æ¤éè¿ãè¿æ²¡éæ°å®æ**ãæ¤éåèªå¨å trueï¼åæ¬¡å®æåèªå¨å falseã |
| | | */ |
| | | @Schema(description = "æ¯å¦å·²æ¤éï¼å®æè¢«æ¤éãå°æªéæ°å®æï¼", example = "false") |
| | | private Boolean undone; |
| | | } |
| | |
| | | @Schema(description = "é¢çº¦æ£æ¥ç±»å", example = "1") |
| | | private Integer bookCheckType; |
| | | |
| | | @Schema(description = "é¢çº¦åºå·") |
| | | /** ãå·²åç¨ãæéå·ç»ä¸ä¸º seqNumï¼æ¬å段ä»
ä¿çå
¼å®¹ï¼æ¥è¯¢è¯·ç¨ seqNum */ |
| | | @Schema(description = "é¢çº¦åºå·ï¼å·²åç¨ï¼è¯·ç¨ seqNumï¼") |
| | | private Integer bookSeqNum; |
| | | |
| | | @Schema(description = "æéåºå·") |
| | |
| | | @ExcelProperty("é¢çº¦æ£æ¥ç±»å") |
| | | private Integer bookCheckType; |
| | | |
| | | @Schema(description = "é¢çº¦åºå·") |
| | | /** ãå·²åç¨ãæéå·ç»ä¸ä¸º seqNumï¼è§ä¸ï¼ï¼æ¬å段ä»
ä¿ç以å
¼å®¹èå端/èæ°æ®ï¼ä¸ååå
¥ä¸æ¾ç¤º */ |
| | | @Schema(description = "é¢çº¦åºå·ï¼å·²åç¨ï¼è¯·ç¨ seqNumï¼") |
| | | @ExcelProperty("é¢çº¦åºå·") |
| | | private Integer bookSeqNum; |
| | | |
| | | @Schema(description = "æéåºå·", requiredMode = Schema.RequiredMode.REQUIRED) |
| | | @Schema(description = "æéåºå·ï¼= check_type.seq_prefix + æ¬å¼ï¼", requiredMode = Schema.RequiredMode.REQUIRED) |
| | | @ExcelProperty("æéåºå·") |
| | | private Integer seqNum; |
| | | |
| | |
| | | @Schema(description = "é¢çº¦æ£æ¥ç±»å", example = "1") |
| | | private Integer bookCheckType; |
| | | |
| | | @Schema(description = "é¢çº¦åºå·", requiredMode = Schema.RequiredMode.REQUIRED) |
| | | /** ãå·²åç¨ãæéå·ç»ä¸ä¸º seqNumï¼è§ä¸ï¼ï¼æ¬å段ä»
ä¿ç以å
¼å®¹èè°ç¨æ¹ï¼æ°ä»£ç 请å¿èµå¼ */ |
| | | @Schema(description = "é¢çº¦åºå·ï¼å·²åç¨ï¼è¯·ç¨ seqNumï¼", requiredMode = Schema.RequiredMode.REQUIRED) |
| | | //@NotNull(message = "é¢çº¦åºå·ä¸è½ä¸ºç©º") |
| | | private Integer bookSeqNum; |
| | | |
| | |
| | | //@NotNull(message = "æ¯å¦VIP") |
| | | private Integer isVip; |
| | | |
| | | /** æéå·ï¼ç¾å°æ¶æ check_type.seq_rule åé
䏿¬¡ï¼ä¹åä¸åæ¹å¨ */ |
| | | @Schema(description = "æéåºå·", requiredMode = Schema.RequiredMode.REQUIRED) |
| | | @NotNull(message = "æéåºå·ä¸è½ä¸ºç©º") |
| | | private Integer seqNum; |
| | |
| | | * <p> |
| | | * æ¥æºï¼HIS æ¥æ {@code observationRequest.zdy.jjbz}ï¼N=常è§ï¼J=å æ¥ï¼ |
| | | * â é¢çº¦è®°å½ {@code appointment.jjbz} â é¢çº¦ç¡®è®¤æ¶å¸¦å
¥æéã |
| | | * ä¸äººå·¥æéï¼{@code QueueServiceImpl#patientJump}ï¼å
±ç¨è¯¥åæ®µï¼ |
| | | * {@code queue} 表æ {@code order by jump_flag desc, book_timeslot, create_time} åå·ï¼ |
| | | * å æ¤ç½® 1 å³å®ç°"å æ¥ä¼å
"ã |
| | | * ä¸äººå·¥æéï¼{@code QueueServiceImpl#patientJump}ï¼å
±ç¨è¯¥å段ã |
| | | * <p> |
| | | * ãå·ç»ä¸åãæéå·å¨ç¾å°æ¶ä¸æ¬¡æ§å®æ»ãä¹åä¸åæ¹å¨ï¼å æ¥**ä¸åé æ¹å·/æééç¼å·**ï¼ |
| | | * èæ¯é æåºï¼åæµå人ãå«å·å人以åå·¥ä½å°/è¯é´å±/大å±å表å为 |
| | | * {@code jump_flag desc ä¼å
â seq_num ååº}ï¼å æ¤ç½® 1 å³å®ç°"å æ¥ä¼å
"ã |
| | | */ |
| | | @Schema(description = "å æ¥æ è®° 1=å æ¥") |
| | | private Byte jumpFlag; |
| | |
| | | import javax.validation.Valid; |
| | | |
| | | import cn.hutool.extra.servlet.ServletUtil; |
| | | import cn.lihu.jh.module.ecg.utils.IpUtils; |
| | | import cn.lihu.jh.module.ecg.controller.admin.room.vo.*; |
| | | import cn.lihu.jh.module.ecg.dal.dataobject.queue.QueueDO; |
| | | import cn.lihu.jh.module.ecg.dal.dataobject.room.RoomDO; |
| | |
| | | import cn.lihu.jh.framework.common.pojo.PageParam; |
| | | import cn.lihu.jh.framework.common.pojo.PageResult; |
| | | import cn.lihu.jh.framework.common.pojo.CommonResult; |
| | | import cn.lihu.jh.framework.common.exception.ErrorCode; |
| | | import cn.lihu.jh.framework.common.exception.enums.GlobalErrorCodeConstants; |
| | | import cn.lihu.jh.framework.common.util.object.BeanUtils; |
| | | import cn.lihu.jh.framework.excel.core.util.ExcelUtils; |
| | | import cn.lihu.jh.framework.apilog.core.annotation.ApiAccessLog; |
| | | import cn.lihu.jh.framework.security.core.util.SecurityFrameworkUtils; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | |
| | | import static cn.lihu.jh.framework.common.pojo.CommonResult.success; |
| | | import static cn.lihu.jh.framework.common.exception.util.ServiceExceptionUtil.exception; |
| | | import static cn.lihu.jh.framework.apilog.core.enums.OperateTypeEnum.*; |
| | | |
| | | |
| | |
| | | @RestController |
| | | @RequestMapping("/clinic/room") |
| | | @Validated |
| | | @Slf4j |
| | | public class RoomController { |
| | | |
| | | @Resource |
| | |
| | | String reqIp = ServletUtil.getClientIP(request); |
| | | RoomProfile roomProfile = roomService.getRoomByIP(reqIp, roomId); |
| | | return success(BeanUtils.toBean(roomProfile, RoomProfileRespVO.class)); |
| | | } |
| | | |
| | | /* ==================== 鿩工使¨¡å¼ï¼éæ±ï¼è¯å®¤å·¥ä½éæ©æ¨¡å¼ 0/1/2/3ï¼ ==================== */ |
| | | |
| | | /** |
| | | * ææ¬æºIPå¹é
å·¥ä½ï¼æ¨¡å¼ 1/3 ç¨ï¼ã |
| | | * |
| | | * <p>åªè¯»æ¥å£ï¼ |
| | | * <ul> |
| | | * <li>æå端å®é
è¯å«å°çæ¥è®¿IPä¸èµ·è¿åï¼ä¾¿äºææ¥"åç½®ä»£çæªéä¼ X-Forwarded-For"ï¼</li> |
| | | * <li>åéå·¥ä½å·²æãæ¬äººå·²å ç¨ â ç©ºé² â 被ä»äººå ç¨ãæå¥½åºï¼å端å第ä¸ä¸ªå¯ç¨çèªå¨å
¥åº§ï¼</li> |
| | | * <li>æ¬æ¥å£ä¸æ¹ä»»ä½ç¶æï¼å
¥åº§ä»èµ°åæç bedDoctorOn æµç¨ã</li> |
| | | * </ul> |
| | | * éè¦ç»å½ï¼æªç»å½æ¶è¿åç©ºç»æï¼ï¼ä½ä¸åèåæéæ ¡éªï¼è½ç»å½å°±è½æ¥èªå·±çå·¥ä½ã</p> |
| | | */ |
| | | @GetMapping("/get-ip-bed") |
| | | @Operation(summary = "ææ¬æºIPå¹é
å·¥ä½ï¼éæ©å·¥ä½æ¨¡å¼ 1/3ï¼") |
| | | public CommonResult<RoomSelectBedRespVO> getIpBed(HttpServletRequest request) { |
| | | // è§èåï¼å»æ¬å·/åºåå·ãç»ä¸å°åãIPv4-mapped IPv6 è¿åæ IPv4ï¼æ¯æ IPv4 ä¸ IPv6ï¼ |
| | | String clientIp = IpUtils.normalize(ServletUtil.getClientIP(request)); |
| | | Long docId = SecurityFrameworkUtils.getLoginUserId(); |
| | | RoomSelectBedRespVO resp = new RoomSelectBedRespVO(); |
| | | resp.setClientIp(clientIp); |
| | | resp.setIpValid(IpUtils.isBindableIp(clientIp)); |
| | | resp.setIpLoopback(IpUtils.isLoopback(clientIp)); |
| | | resp.setIpv6(IpUtils.isIpv6Address(clientIp)); |
| | | List<RoomSelectBedRespVO.RoomSelectBedItem> beds = roomService.matchBedsByIp(clientIp, docId); |
| | | resp.setBeds(beds); |
| | | resp.setIpBound(!beds.isEmpty()); |
| | | // æ"æ¬äººå·²å ç¨"æ"空é²"çå·¥ä½ï¼å°±è½èªå¨å
¥åº§ |
| | | resp.setMatched(beds.stream() |
| | | .anyMatch(b -> Boolean.TRUE.equals(b.getMine()) || !Boolean.TRUE.equals(b.getOccupied()))); |
| | | log.info("[getIpBed][æIPå¹é
å·¥ä½] clientIp={} docId={} ipValid={} loopback={} åéæ°={} å¯èªå¨å
¥åº§={}", |
| | | clientIp, docId, resp.getIpValid(), resp.getIpLoopback(), beds.size(), resp.getMatched()); |
| | | return success(resp); |
| | | } |
| | | |
| | | /** |
| | | * ææ¬æºIPåå
¥æå®å·¥ä½ï¼æ¨¡å¼ 2/3 ç¨ï¼ã |
| | | * |
| | | * <p>åªæ´æ° {@code clinic_room.ip} ä¸ä¸ªå段ï¼ä¸èµ° {@code clinic:room:update}ï¼å¦å为äºéå·¥ä½è¿å¾ç»å»çå¼è¯å®¤ç®¡çæéï¼ï¼ |
| | | * ä¹ä¸ä¼ç¢° status/doc_id/check_types çå
¶å®å段ã |
| | | * è¥è¯¥IPå·²ç»å¨å«çå·¥ä½ä¸ï¼é»è®¤è¿åå²çªå·¥ä½è®©å端确认ï¼ç¡®è®¤å带 {@code force=true} åè°ä¸æ¬¡å³è¦çã</p> |
| | | */ |
| | | @PostMapping("/bind-ip") |
| | | @Operation(summary = "ææ¬æºIPç»å®å°å·¥ä½ï¼éæ©å·¥ä½æ¨¡å¼ 2/3ï¼") |
| | | public CommonResult<Map<String, Object>> bindIp(HttpServletRequest request, |
| | | @RequestParam("id") Integer id, |
| | | @RequestParam(value = "force", required = false, defaultValue = "false") Boolean force) { |
| | | Map<String, Object> data = new HashMap<>(); |
| | | String rawIp = ServletUtil.getClientIP(request); |
| | | String clientIp = IpUtils.normalize(rawIp); |
| | | data.put("clientIp", clientIp); |
| | | if (!IpUtils.isBindableIp(clientIp)) { |
| | | data.put("code", 400); |
| | | if (IpUtils.isLoopback(clientIp)) { |
| | | // æµè§å¨åæå¡å¨åä¸å°æºå¨ä¸è®¿é®æ¶å¿
ç¶åºç°ï¼IPv4 æ¯ 127.0.0.1ï¼IPv6 æ¯ ::1 |
| | | data.put("msg", "æ æ³ç»å®å·¥ä½ï¼æ£æµå°å½åè®¿é®æ¥èªæ¬æºåç¯å°åï¼" + clientIp |
| | | + "ï¼å³æ¬æºè®¿é®ï¼ï¼è¯·å¨å»çå®é
使ç¨ççµèä¸è®¿é®ååç»å®"); |
| | | } else if (IpUtils.isUnspecified(clientIp)) { |
| | | data.put("msg", "æ æ³ç»å®å·¥ä½ï¼å½åè¯å«å°çå°åæ¯æªæå®å°åï¼" + clientIp + "ï¼"); |
| | | } else if (IpUtils.isLocalAddress(clientIp)) { |
| | | // æ¬æ¬¡æ°å¢ï¼ç°åºæå¸¸è§ç"IP ä¸å¯¹"å°±æ¯è¿ç§ ââ 卿å¡å¨ä¸ï¼æè¿ç¨æ¡é¢éï¼è®¿é®ç³»ç»ï¼ |
| | | // 客æ·ç«¯æ¬æ¥å°±æ¯æå¡å¨èªå·±ï¼è¥æå®åè¿å·¥ä½ï¼è¯¥å·¥ä½ä»¥åæ°¸è¿å¹é
ä¸å°å»ççµèã |
| | | data.put("msg", "æ æ³ç»å®å·¥ä½ï¼è¯å«å°çæ¯**æå¡å¨èªèº«å°å**ï¼" + clientIp |
| | | + "ï¼ââ 说æå½åæ¯å¨æå¡å¨ä¸è®¿é®ï¼æç»è¿ç¨æ¡é¢/æ¬æºä»£ç访é®ï¼è¿ä¸æ¯å»ççµèç IPã" |
| | | + "请å¨å»çå®é
使ç¨ççµèä¸ãç¨æå¡å¨ç IPv4 å°å访é®ååç»å®" |
| | | + "ï¼å¯ç¨ãIP è¯æãæ¥çå端å°åºæè°å½æäºå®¢æ·ç«¯ï¼"); |
| | | log.warn("[bindIp][è¯å«å°æå¡å¨èªèº«å°åï¼æç»ç»å®] clientIp={} bedId={} æå¡å¨ç½å¡IPv4={}", |
| | | clientIp, id, IpUtils.localIpv4Addresses()); |
| | | } else if (IpUtils.isIpv6Address(clientIp)) { |
| | | // æ¬ç³»ç»å·¥ä½ç»å®ç»ä¸éç¨ IPv4ï¼å®¢æ·ç«¯èµ° IPv6 æ¶æ æ³ä»ä»£ç "éåæ"IPv4 |
| | | data.put("msg", "æ æ³ç»å®å·¥ä½ï¼å½å访é®ä½¿ç¨çæ¯ IPv6 å°åï¼" + clientIp |
| | | + "ï¼ï¼æ¬ç³»ç»å·¥ä½ç»å®ä»
éç¨ IPv4ï¼è¯·æ¹ç¨æå¡å¨ç IPv4 å°å访é®" |
| | | + "ï¼æè®©æå¡åªçå¬ IPv4ï¼JVM åæ° -Djava.net.preferIPv4Stack=trueï¼"); |
| | | } else { |
| | | data.put("msg", "æ æ³ç»å®å·¥ä½ï¼æªè½è¯å«å°åæ³ç IPv4 æ¥è®¿å°åï¼" + clientIp |
| | | + "ï¼ï¼è¯·æ£æ¥æ¯å¦éè¿ä»£ç访é®ã以åä»£çæ¯å¦éä¼ å®¢æ·ç«¯å°åï¼X-Forwarded-Forï¼"); |
| | | } |
| | | log.warn("[bindIp][IPä¸å¯ç¨ï¼æç»ç»å®] raw={} normalized={} ipv6={} bedId={}", |
| | | rawIp, clientIp, IpUtils.isIpv6Address(clientIp), id); |
| | | return success(data); |
| | | } |
| | | // å²çªæ£æµï¼è¯¥IPå·²ç»å¨å«çå·¥ä½ â å
让å端确认 |
| | | List<RoomDO> conflicts = roomService.listIpBindings(clientIp, id); |
| | | if (!conflicts.isEmpty() && !Boolean.TRUE.equals(force)) { |
| | | RoomDO c = conflicts.get(0); |
| | | data.put("code", 409); |
| | | data.put("conflict", true); |
| | | data.put("conflictBedId", c.getId()); |
| | | data.put("conflictRoomName", c.getRoomName()); |
| | | data.put("conflictBedNo", c.getBedNo()); |
| | | data.put("msg", "该IPå·²ç»å®ã" + c.getRoomName() + " / " + c.getBedNo() + "ã"); |
| | | return success(data); |
| | | } |
| | | Integer rows = roomService.bindIpToBed(id, clientIp); |
| | | data.put("code", rows != null && rows > 0 ? 200 : 500); |
| | | data.put("msg", rows != null && rows > 0 ? "å·²ç»å®æ¬æºIPå°è¯¥å·¥ä½" : "ç»å®å¤±è´¥ï¼å·¥ä½ä¸åå¨ï¼ï¼"); |
| | | data.put("rows", rows); |
| | | log.info("[bindIp][ç»å®ç»æ] raw={} clientIp={} bedId={} force={} rows={}", rawIp, clientIp, id, force, rows); |
| | | return success(data); |
| | | } |
| | | |
| | | /* ==================== èªå¨å
¥åº§ / æçå·¥ä½ï¼æ¬æ¬¡éæ±ï¼ ==================== */ |
| | | |
| | | /** |
| | | * ä¸é®èªå¨å
¥åº§ï¼éæ©å·¥ä½æ¨¡å¼ 1/3 ç¨ï¼ã |
| | | * |
| | | * <p>为ä»ä¹åå¹¶æä¸ä¸ªæ¥å£ï¼åç«¯åæ¥æãå¹é
â ç» IP â å
¥åº§ãææä¸ä¸ªè¯·æ±èªå·±æ¼ï¼ |
| | | * 任䏿¥å¤±è´¥é½åªè½åè½"æéå·¥ä½"ï¼ç°åºè¡¨ç°å°±æ¯"ç»å½å没æèªå¨å
¥åº§"ä¸çä¸åºåå ã |
| | | * ç°å¨ä¸æ¬¡è°ç¨å®æï¼å¹¶è¿å**è¯å«å°ç IP** ä¸**æªå
¥åº§åå ** |
| | | * ï¼{@code ip_invalid / nomatch / multi / occupied / error}ï¼ï¼ææ¥ä¸ç¼å¯è¾¨ã |
| | | * |
| | | * <p>éè¦ç»å½ï¼ä½ä¸åèåæéæ ¡éªï¼è½ç»å½å°±è½åèªå·±çå·¥ä½ã |
| | | */ |
| | | @PostMapping("/auto-seat") |
| | | @Operation(summary = "ææ¬æºIPèªå¨å¹é
å·¥ä½å¹¶èªå¨å
¥åº§ï¼éæ©å·¥ä½æ¨¡å¼ 1/3ï¼") |
| | | public CommonResult<RoomSeatRespVO> autoSeat(HttpServletRequest request) { |
| | | String clientIp = IpUtils.normalize(ServletUtil.getClientIP(request)); |
| | | Long docId = SecurityFrameworkUtils.getLoginUserId(); |
| | | String docName = SecurityFrameworkUtils.getLoginUserNickname(); |
| | | RoomSeatRespVO resp = roomService.autoSeatByIp(clientIp, docId, docName); |
| | | log.info("[autoSeat][èªå¨å
¥åº§] clientIp={} docId={} seated={} reason={} å·¥ä½={}/{}", |
| | | clientIp, docId, resp.getSeated(), resp.getReason(), resp.getRoomName(), resp.getBedNo()); |
| | | return success(resp); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢å½åç»å½äºº**å·²å
¥åº§**çå·¥ä½ï¼ç³»ç»é¡¶æ "å½åå·¥ä½"æ ç¾ç¨ï¼ã |
| | | * |
| | | * <p>æªå
¥åº§æ¶è¿å {@code seated=false}ï¼åç«¯æ®æ¤æ¾ç¤ºç°è²ãæªå
¥åº§ãå¹¶å¯ç¹å»å»éå·¥ä½ã |
| | | */ |
| | | @GetMapping("/my-seat") |
| | | @Operation(summary = "æ¥è¯¢å½åç»å½äººå·²å
¥åº§çå·¥ä½ï¼ç³»ç»é¡¶æ å±ç¤ºï¼") |
| | | public CommonResult<RoomSeatRespVO> mySeat() { |
| | | Long docId = SecurityFrameworkUtils.getLoginUserId(); |
| | | RoomSeatRespVO resp = roomService.getMySeat(docId); |
| | | log.info("[mySeat][æ¥è¯¢æçå·¥ä½] docId={} seated={} å·¥ä½={}/{}", |
| | | docId, resp.getSeated(), resp.getRoomName(), resp.getBedNo()); |
| | | return success(resp); |
| | | } |
| | | |
| | | /** |
| | | * ãæ¬éæ±Â·ä¸äººå¤å·¥ä½ãæ¥è¯¢å½åç»å½äººå æ®ç**å
¨é¨**å·¥ä½ï¼è忥å¼çå¤å²ä½ï¼ã |
| | | * |
| | | * <p>è¿åãå»çå¨åº§ / å»çæåãçå·¥ä½åè¡¨ï¼æ roomId + bedNo ååºï¼æªå å·¥ä½è¿å空æ°ç»ã |
| | | * å端ç¨å®æ¸²æé¡¶æ ãæçå·¥ä½ï¼N 个ï¼ãå¹¶å¨å·¥ä½ä¹é´åæ¢ã |
| | | */ |
| | | @GetMapping("/my-seats") |
| | | @Operation(summary = "æ¥è¯¢å½åç»å½äººå·²å
¥åº§çå
¨é¨å·¥ä½ï¼ä¸äººå¤å²ä½ï¼") |
| | | public CommonResult<List<RoomSeatRespVO>> mySeats() { |
| | | Long docId = SecurityFrameworkUtils.getLoginUserId(); |
| | | List<RoomSeatRespVO> seats = roomService.getMySeats(docId); |
| | | log.info("[mySeats][æ¥è¯¢æçå
¨é¨å·¥ä½] docId={} æ°é={}", docId, null == seats ? 0 : seats.size()); |
| | | return success(seats); |
| | | } |
| | | |
| | | /** |
| | | * ãæ¬éæ±Â·æ¥çèªå©æ¥ç®¡ãæå·¥ä½ä»"å«äººå ç¨"æ¹ä¸º"å½åç»å½äººå ç¨"ã |
| | | * |
| | | * <p>åºæ¯ï¼ä¸ä¸çå»çä¸çæªç¹ã离座ãï¼ä¸ä¸çå»çå¨åä¸å°çµè/åä¸å·¥ä½æ¥çã |
| | | * åå ç¨äººä¼è¢«å¼ºå¶ç¦»åº§ï¼å
¶é¡µé¢ 5s è½®è¯¢ä¼æç¤ºãè¯·éæ°å°±åã并转åªè¯»ï¼ã |
| | | * æé沿ç¨å»çå·¥ä½å°å·²æç {@code ecg:doctor:task}ï¼æ 鿰墿éç¹ã |
| | | */ |
| | | @PostMapping("/take-over-bed") |
| | | @Operation(summary = "æ¥ç®¡å·¥ä½ï¼æ¥çï¼æä»äººå ç¨çå·¥ä½è½¬ç»æï¼") |
| | | @PreAuthorize("@ss.hasPermission('ecg:doctor:task')") |
| | | public CommonResult<Boolean> takeOverBed(@RequestParam("roomId") Long roomId, |
| | | @RequestParam("bedNo") String bedNo) { |
| | | roomService.takeOverBed(roomId, bedNo); |
| | | return success(true); |
| | | } |
| | | |
| | | /** |
| | | * 客æ·ç«¯ IP è¯å«è¯æï¼ç°åºææ¥"å·¥ä½ç»å®ç IP ä¸å¯¹"ç¨ï¼ã |
| | | * |
| | | * <p>䏿¬¡æææç¸å
³çº¿ç´¢æå¼ï¼å个代ç头ãTCP ç´è¿å°åãè§èåç»æãæ¯å¦åç¯/IPv6ã |
| | | * **æ¯å¦æ¯æå¡å¨èªèº«å°å**ã以åæå¡å¨ææ IPv4 ç½å¡å°åãçé¢ä¸çãIP è¯æãæé®å°±è°å®ã |
| | | * |
| | | * <p>å
¸åç»è®ºï¼ |
| | | * <ul> |
| | | * <li>åå°çæ¯æå¡å¨èªèº«å°å â å½åæ¯å¨æå¡å¨ä¸/è¿ç¨æ¡é¢é访é®ï¼æä»£çæå®¢æ·ç«¯å°åè¦çæäºæå¡å¨å°åï¼</li> |
| | | * <li>åå° 127.x / ::1 â æµè§å¨ä¸æå¡å¨åä¸å°æºå¨ï¼</li> |
| | | * <li>åå° IPv6 â 客æ·ç«¯èµ° IPv6ï¼æ¬ç³»ç»å·¥ä½ç»å®åªç¨ IPv4ï¼ï¼</li> |
| | | * <li>{@code X-Forwarded-For} 为空ä¸ç´è¿å°å=ç½å
³ â åé¢çä»£çæ²¡éä¼ å®¢æ·ç«¯å°åã</li> |
| | | * </ul> |
| | | */ |
| | | @GetMapping("/ip-debug") |
| | | @Operation(summary = "客æ·ç«¯IPè¯å«è¯æï¼ææ¥å·¥ä½ç»å®IPä¸å¯¹ï¼") |
| | | public CommonResult<Map<String, Object>> ipDebug(HttpServletRequest request) { |
| | | Map<String, Object> data = new LinkedHashMap<>(); |
| | | String xff = request.getHeader("X-Forwarded-For"); |
| | | String realIp = request.getHeader("X-Real-IP"); |
| | | String remoteAddr = request.getRemoteAddr(); |
| | | String raw = ServletUtil.getClientIP(request); |
| | | String clientIp = IpUtils.normalize(raw); |
| | | |
| | | data.put("访é®Host", request.getHeader("Host")); |
| | | data.put("X-Forwarded-For", xff); |
| | | data.put("X-Real-IP", realIp); |
| | | data.put("Proxy-Client-IP", request.getHeader("Proxy-Client-IP")); |
| | | data.put("WL-Proxy-Client-IP", request.getHeader("WL-Proxy-Client-IP")); |
| | | data.put("HTTP_CLIENT_IP", request.getHeader("HTTP_CLIENT_IP")); |
| | | data.put("ç´è¿å°å(remoteAddr)", remoteAddr); |
| | | data.put("åå°çåå§å¼", raw); |
| | | data.put("è§èåå(工使æ¤å¹é
)", clientIp); |
| | | data.put("å¯ç¨äºå·¥ä½ç»å®", IpUtils.isBindableIp(clientIp)); |
| | | data.put("æ¯åç¯(æµè§å¨ä¸æå¡åæº)", IpUtils.isLoopback(clientIp)); |
| | | data.put("æ¯IPv6", IpUtils.isIpv6Address(clientIp)); |
| | | data.put("æ¯æå¡å¨èªèº«å°å", IpUtils.isLocalAddress(clientIp)); |
| | | data.put("æå¡å¨ç½å¡IPv4", IpUtils.localIpv4Addresses()); |
| | | |
| | | String verdict; |
| | | if (IpUtils.isLoopback(clientIp)) { |
| | | verdict = "客æ·ç«¯å°±æ¯æå¡å¨æ¬æºï¼åç¯ " + clientIp + "ï¼ï¼å±ãæµè§å¨ä¸æå¡å¨åä¸å°æºå¨ãçæ£å¸¸ç°è±¡ï¼" |
| | | + "ä¸è½ä½ä¸ºå·¥ä½æ è¯ï¼è¯·å¨å»ççµèä¸è®¿é®ã"; |
| | | } else if (IpUtils.isLocalAddress(clientIp)) { |
| | | verdict = "â è¯å«å°çæ¯ãæå¡å¨èªèº«å°åãï¼" + clientIp + "ï¼ï¼å½åæ¯å¨æå¡å¨ä¸/è¿ç¨æ¡é¢é访é®ï¼" |
| | | + "æå置代çæå®¢æ·ç«¯å°åè¦çæäºæå¡å¨å°å â ä¸è½ä½ä¸ºå·¥ä½æ è¯ã" |
| | | + "请å¨å»ççµèä¸ãç¨æå¡å¨ç IPv4 å°å访é®ï¼è¥ç¡®è®¤æ¯å¨å»ççµèä¸è®¿é®ï¼è¯·æ£æ¥ä»£çæ¯å¦éä¼ " |
| | | + "X-Forwarded-Forï¼nginx: proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;ï¼ã"; |
| | | } else if (IpUtils.isIpv6Address(clientIp)) { |
| | | verdict = "客æ·ç«¯èµ°çæ¯ IPv6ï¼" + clientIp + "ï¼ï¼æ¬ç³»ç»å·¥ä½ç»å®åªéç¨ IPv4ï¼" |
| | | + "请让æå¡åªçå¬ IPv4ï¼JVM: -Djava.net.preferIPv4Stack=trueï¼ææ¹ç¨ IPv4 å°å访é®ã"; |
| | | } else if (IpUtils.isBindableIp(clientIp)) { |
| | | verdict = "è¯å«æ£å¸¸ï¼å¯ç¨äºå·¥ä½ç»å®ï¼" + clientIp; |
| | | } else { |
| | | verdict = "æªè½è¯å«å°å¯ç¨ç IPv4 客æ·ç«¯å°åï¼åå§å¼ï¼" + raw + "ï¼ç´è¿å°åï¼" + remoteAddr |
| | | + "ï¼ï¼è¯·æ£æ¥ä»£çæ¯å¦éä¼ å®¢æ·ç«¯å°åï¼X-Forwarded-Forï¼ã"; |
| | | } |
| | | data.put("è¯æç»è®º", verdict); |
| | | |
| | | log.info("[ipDebug][客æ·ç«¯IPè¯æ] Host={} XFF={} X-Real-IP={} remoteAddr={} â clientIp={} æå¡å¨å°å={}", |
| | | request.getHeader("Host"), xff, realIp, remoteAddr, clientIp, IpUtils.isLocalAddress(clientIp)); |
| | | return success(data); |
| | | } |
| | | |
| | | /** |
| | | * å·¥ä½ç¶æè¯æï¼ææ¥"å
¥åº§æ¥ç¶æå¼å¸¸ / ææç©ºé²å´åä¸ä¸"ï¼ã |
| | | * |
| | | * <p>æåºé**åå§è¡**æå¼ï¼`id / room_id / room_name / bed_no(å«é¿åº¦ä¸ HEXï¼ç¨äºåç°ç»å°¾ç©ºæ ¼ãå
¨è§) / |
| | | * ip / status / doc_id / doc_name / op_type / deleted / update_time`ï¼å¹¶ç»åºä¸å¥ç»è®ºã |
| | | * |
| | | * <p>ç¨æ³ï¼`GET /clinic/room/bed-state?id=3` æ `?roomId=118&bedNo=C1`ã |
| | | */ |
| | | @GetMapping("/bed-state") |
| | | @Operation(summary = "å·¥ä½ç¶æè¯æï¼ææ¥å
¥åº§æ¥ç¶æå¼å¸¸ï¼") |
| | | public CommonResult<Map<String, Object>> bedState( |
| | | @RequestParam(value = "id", required = false) Integer id, |
| | | @RequestParam(value = "roomId", required = false) Long roomId, |
| | | @RequestParam(value = "bedNo", required = false) String bedNo) { |
| | | return success(roomService.diagnoseBed(id, roomId, bedNo)); |
| | | } |
| | | |
| | | @GetMapping("/page") |
| | |
| | | List<RoomDO> list = roomService.simpleRoomList(); |
| | | List<RoomRespVO> list2 = BeanUtils.toBean(list, RoomRespVO.class); |
| | | |
| | | // æ¾å¼æ æ³¨ãæ¯å¦å·²è¢«å»çå ç¨ãï¼éå·¥ä½é¡µæ®æ¤æ¾ç¤ºãå·²å
¥åº§ï¼å¼ ä¸ãå¹¶**ç¦ç¨å
¥åº§æé®**ï¼ |
| | | // ä¸ä¾èµ BeanUtils æ¯å¦æ docId å¤å¶è¿æ¥ï¼åä¿é©ï¼æ¬æ¬¡ç°åºå°±æ"çä¸åºæ¥è°å äºå·¥ä½"çåé¦ï¼ã |
| | | list2.forEach(roomRespVO -> roomRespVO.setOccupied(null != roomRespVO.getDocId())); |
| | | |
| | | Map<Long, List<RoomRespVO>> map = list2.stream().collect(Collectors.groupingBy(RoomRespVO::getRoomId)); |
| | | return success(map); |
| | | } |
| | |
| | | return success(0); |
| | | } |
| | | |
| | | /** |
| | | * ãæ¬æ¬¡éæ±ã管çåå¼ºå¶æ¸
空æä¸ªå·¥ä½ï¼ä¸è¦æ±æ¯å ç¨è
æ¬äººï¼ã |
| | | * <p> |
| | | * 使ç¨åºæ¯ï¼å»çä¸çå¿è®°ã离座ãï¼ææ¢äººä½¿ç¨åä¸å·¥ä½ã |
| | | * <p> |
| | | * ä¸å»çèªå·±çãç¦»åº§ãæ¥å£ï¼{@code /ecg/doctor/bed-doctor-off}ï¼çåºå«ï¼ |
| | | * · 该æ¥å£åªè½æ¸
**èªå·±**å ç¨çå·¥ä½ï¼SQL 带 {@code doc_id = å½åç¨æ·}ï¼ï¼ |
| | | * · æ¬æ¥å£é¢å管ç端ï¼å¯ä»¥æ¸
**ä»»ä½äºº**å ç¨çå·¥ä½ï¼ä»
è¦æ±è¯¥å·¥ä½å½åæ¯ãå»çå¨å² / æåãï¼ã |
| | | * <p> |
| | | * å·¥ä½ç©ºé²æ¶ä¼è¿åãå½åå·¥ä½ç¶æä¸å
许该æä½ãââè¿æ¯é¢æè¡ä¸ºã |
| | | */ |
| | | @PostMapping("/force-clear-bed") |
| | | @Operation(summary = "管çåå¼ºå¶æ¸
空工ä½", description = "å»çä¸çå¿ç¦»åº§ / æ¢äººä½¿ç¨åä¸å·¥ä½æ¶ä½¿ç¨") |
| | | @PreAuthorize("@ss.hasPermission('clinic:room:update')") |
| | | public CommonResult<Boolean> forceClearBed(@RequestParam("roomId") Long roomId, |
| | | @RequestParam("bedNo") String bedNo) { |
| | | ErrorCode ec = queueService.startBedDoctorOffByAdmin(roomId, bedNo); |
| | | if (!GlobalErrorCodeConstants.SUCCESS.getCode().equals(ec.getCode())) { |
| | | log.warn("[forceClearBed] æ¸
空工ä½å¤±è´¥ roomId={} bedNo={} code={} msg={}", |
| | | roomId, bedNo, ec.getCode(), ec.getMsg()); |
| | | throw exception(ec); |
| | | } |
| | | return success(true); |
| | | } |
| | | |
| | | } |
| | |
| | | @Data |
| | | public class MonitorInfoVO { |
| | | private Integer openingBedNum; |
| | | /** å¨åº§**工使°**ï¼å»çå¨åº§ / å»çæå ç工使°éï¼ä¸äººå¤å·¥ä½æ¶å¯è½å¤§äºå»çæ°ï¼ */ |
| | | private Integer docBedNum; |
| | | /** |
| | | * ãæ¬éæ±Â·ç»è®¡æäººåå¹¶ãå¨åº§**å»çæ°**ï¼æ doc_id å»éï¼ã |
| | | * <p>ä¸äººå¤å·¥ä½å {@link #docBedNum} 伿工ä½ç´¯è®¡ï¼çæ§é¡µè¦è¡¨è¾¾"å°åºå 个å»çå¨å²"å°±ç¨æ¬å段ã |
| | | */ |
| | | private Integer docNum; |
| | | private Integer routingBedNum; |
| | | private Integer openingFlag; |
| | | private Map<Integer, String> checkTypeBedInfo; |
| | |
| | | @ExcelProperty("å»çå") |
| | | private String docName; |
| | | |
| | | /** |
| | | * è¯¥å·¥ä½æ¯å¦å·²è¢«å»çå ç¨ï¼docId é空å³ä¸ºå ç¨ï¼ã |
| | | * <p>ç¨äº"æIPèªå¨å¹é
å·¥ä½"æ¶å¤æåé工使¯å¦å¯ç¨ï¼ä»
æ¥è¯¢è¿åï¼ä¸è½åºã</p> |
| | | */ |
| | | @Schema(description = "æ¯å¦å·²è¢«å»çå ç¨") |
| | | private Boolean occupied; |
| | | |
| | | @Schema(description = "å建æ¶é´", requiredMode = Schema.RequiredMode.REQUIRED) |
| | | @ExcelProperty("å建æ¶é´") |
| | | private LocalDateTime createTime; |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.lihu.jh.module.ecg.controller.admin.room.vo; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * ãå·¥ä½å
¥åº§ãç»æ ââ èªå¨å
¥åº§ï¼{@code POST /clinic/room/auto-seat}ï¼ |
| | | * ä¸ãæ¥è¯¢æçå·¥ä½ãï¼{@code GET /clinic/room/my-seat}ï¼å
±ç¨ã |
| | | * |
| | | * <p>èæ¯ï¼åç«¯åæ¥æ"æ IP å¹é
â ç» IP â å
¥åº§"ææä¸ä¸ªè¯·æ±èªå·±æ¼ï¼ |
| | | * 任䏿¥å¤±è´¥å°±åªè½åè½å°"æéå·¥ä½"ï¼ç°åºè¡¨ç°ä¸º"ç»å½å没æèªå¨å
¥åº§"䏿 ä»å¤æåå ã |
| | | * ç°å¨æ¶ææä¸ä¸ªæ¥å£ï¼å¹¶æ**è¯å«å°ç IP** ä¸**æªå
¥åº§åå **ä¸èµ·è¿åï¼ä¾¿äºææ¥ã |
| | | * |
| | | * @author å¿çµæéè£
æºç³»ç» |
| | | */ |
| | | @Data |
| | | public class RoomSeatRespVO { |
| | | |
| | | @Schema(description = "æ¯å¦å·²å
¥åº§ï¼true æ¶ä¸é¢çå·¥ä½ä¿¡æ¯ææï¼", example = "true") |
| | | private Boolean seated = false; |
| | | |
| | | /** |
| | | * æªå
¥åº§åå ï¼seated=true æ¶ä¸ºç©ºï¼ï¼ |
| | | * <ul> |
| | | * <li>{@code ip_invalid} ââ æ¬æº IP ä¸å¯ç¨ï¼åç¯ / IPv6 / æªæå® / éæ³ï¼ï¼ä¸è½ä½ä¸ºå·¥ä½æ è¯ï¼</li> |
| | | * <li>{@code nomatch} ââ 该 IP 没æå¹é
å°ä»»ä½å·¥ä½ï¼å·¥ä½æ²¡å½ IPï¼æå·¥ä½å·²å
³éï¼ï¼</li> |
| | | * <li>{@code multi} ââ 该 IP 对åº**å¤ä¸ªç©ºé²å·¥ä½**ï¼æ æ³ç¡®å®ååªä¸ä¸ªï¼é人工ç¹éï¼</li> |
| | | * <li>{@code occupied} ââ å¹é
å°çå·¥ä½å·²è¢«**ä»äºº**å ç¨ï¼ä¸æ¤æä»ï¼è½¬æé/æè§ï¼ï¼</li> |
| | | * <li>{@code error} ââ å
¥åº§ååºæªçæï¼å¹¶å被å«äººæ¢å
ãç¶æä¸å
许çï¼ã</li> |
| | | * </ul> |
| | | */ |
| | | @Schema(description = "æªå
¥åº§åå ï¼ip_invalid/nomatch/multi/occupied/error", example = "nomatch") |
| | | private String reason; |
| | | |
| | | @Schema(description = "å端å®é
è¯å«å°ç客æ·ç«¯IPï¼ææ¥ä»£çæªéä¼ X-Forwarded-For ç¨ï¼", example = "32.88.65.208") |
| | | private String clientIp; |
| | | |
| | | @Schema(description = "被å ç¨æ¶çå ç¨äººå§å", example = "å¼ ä¸") |
| | | private String ownerName; |
| | | |
| | | /* ==================== å·¥ä½ä¿¡æ¯ï¼seated=true æ¶ææï¼ ==================== */ |
| | | |
| | | @Schema(description = "å·¥ä½ä¸»é®", example = "1") |
| | | private Integer id; |
| | | |
| | | @Schema(description = "è¯å®¤ç¼å·", example = "1") |
| | | private Long roomId; |
| | | |
| | | @Schema(description = "è¯å®¤åç§°", example = "1å·é¨è¯") |
| | | private String roomName; |
| | | |
| | | @Schema(description = "å·¥ä½å·", example = "A1") |
| | | private String bedNo; |
| | | |
| | | @Schema(description = "å·¥ä½ç»å®çIP", example = "32.88.65.208") |
| | | private String ip; |
| | | |
| | | @Schema(description = "å·¥ä½ç¶æï¼0å·²å
³é 10å·²å¼é 20æå»ç 30æå", example = "20") |
| | | private Integer status; |
| | | |
| | | @Schema(description = "å½å主人ï¼å»çï¼ç¼å·", example = "1") |
| | | private Long docId; |
| | | |
| | | @Schema(description = "å½å主人ï¼å»çï¼å§å", example = "å¼ ä¸") |
| | | private String docName; |
| | | |
| | | @Schema(description = "该工ä½å¼å±çæ£æ¥é¡¹ç®") |
| | | private Integer[] checkTypes; |
| | | |
| | | @Schema(description = "ä½ä¸ç±»åï¼0æ£æ¥ 1é¢ç¨ 2è£
æº", example = "0") |
| | | private Integer opType; |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.lihu.jh.module.ecg.controller.admin.room.vo; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * ã鿩工使¨¡å¼ã- ææ¬æºIPå¹é
å·¥ä½çè¿åç»æã |
| | | * |
| | | * <p>ç¨äºå»ç端ç»å½åèªå¨å¹é
å·¥ä½ï¼ |
| | | * <ul> |
| | | * <li>{@code clientIp}ï¼å端å®é
è¯å«å°çæ¥è®¿IPï¼ææ¥"ä»£çæªéä¼ X-Forwarded-For"æ¶çè¿ä¸ªï¼</li> |
| | | * <li>{@code ipValid}ï¼è¯¥IPæ¯å¦å¯ç¨äºç»å®ï¼æé¤ç©ºã0.0.0.0ã127.0.0.1ãéæ³æ ¼å¼ï¼</li> |
| | | * <li>{@code matched}ï¼æ¯å¦æå¯ç´æ¥èªå¨å
¥åº§çå·¥ä½</li> |
| | | * <li>{@code beds}ï¼è¯¥IPä¸å¹é
å°çåéå·¥ä½ï¼å·²æãæ¬äººå·²å ç¨ â ç©ºé² â 被ä»äººå ç¨ãæå¥½åº</li> |
| | | * </ul> |
| | | */ |
| | | @Data |
| | | @Schema(description = "管çåå° - æIPå¹é
å·¥ä½ Response VO") |
| | | public class RoomSelectBedRespVO { |
| | | |
| | | @Schema(description = "å端è¯å«å°çæ¥è®¿IP") |
| | | private String clientIp; |
| | | |
| | | @Schema(description = "该IPæ¯å¦å¯ç¨äºç»å®ï¼ç©º/0.0.0.0/127.0.0.1/::1/éæ³æ ¼å¼ä¸º falseï¼") |
| | | private Boolean ipValid; |
| | | |
| | | @Schema(description = "该IPæ¯å¦æ¯æ¬æºåç¯å°åï¼127.x / ::1ï¼ï¼ç¨äºç»åºãæ¬æºè®¿é®ãçåç¡®æç¤º") |
| | | private Boolean ipLoopback; |
| | | |
| | | @Schema(description = "该IPæ¯å¦æ¯ IPv6 å°åï¼æ¬ç³»ç»å·¥ä½ç»å®ä»
éç¨ IPv4ï¼IPv6 ä¸åä¸å¹é
ä¸ç»å®ï¼") |
| | | private Boolean ipv6; |
| | | |
| | | @Schema(description = "该IPæ¯å¦å·²ç»ç»å®äºå·¥ä½") |
| | | private Boolean ipBound; |
| | | |
| | | @Schema(description = "æ¯å¦æå¯ç´æ¥å
¥åº§çå·¥ä½ï¼æ¬äººå·²å ç¨ æ 空é²ï¼") |
| | | private Boolean matched; |
| | | |
| | | @Schema(description = "åéå·¥ä½åè¡¨ï¼æ æ¬äººå·²å ç¨ â ç©ºé² â 被ä»äººå ç¨ æåºï¼") |
| | | private List<RoomSelectBedItem> beds; |
| | | |
| | | @Data |
| | | @Schema(description = "åéå·¥ä½") |
| | | public static class RoomSelectBedItem { |
| | | |
| | | @Schema(description = "å·¥ä½ä¸»é® clinic_room.id") |
| | | private Integer id; |
| | | |
| | | @Schema(description = "è¯å®¤ç¼å·") |
| | | private Long roomId; |
| | | |
| | | @Schema(description = "è¯å®¤åç§°") |
| | | private String roomName; |
| | | |
| | | @Schema(description = "è¯çåº/å·¥ä½ç¼å·") |
| | | private String bedNo; |
| | | |
| | | @Schema(description = "该工ä½ç»å®çIP") |
| | | private String ip; |
| | | |
| | | @Schema(description = "å½åå ç¨çå»çIDï¼ç©ºè¡¨ç¤ºç©ºé²") |
| | | private Long docId; |
| | | |
| | | @Schema(description = "å½åå ç¨çå»çå§å") |
| | | private String docName; |
| | | |
| | | @Schema(description = "æä½ç±»å 0æ£æ¥ 1é¢ç¨ 2è£
æº") |
| | | private Integer opType; |
| | | |
| | | @Schema(description = "工使¥è¯çæ£æ¥ç±»å") |
| | | private Integer[] checkTypes; |
| | | |
| | | @Schema(description = "å¼è¯ç¶æ") |
| | | private Integer status; |
| | | |
| | | @Schema(description = "æ¯å¦å·²è¢«å ç¨ï¼docId é空ï¼") |
| | | private Boolean occupied; |
| | | |
| | | @Schema(description = "æ¯å¦è¢«ãå½åç»å½äººãå ç¨ï¼å·æ°/éè¿æ¶å¯ç´æ¥æ¢å¤ï¼") |
| | | private Boolean mine; |
| | | } |
| | | } |
| | |
| | | /** å¤èè¯ï¼0æ 1å¤è 2å¤éèè¯ */ |
| | | @TableField(exist = false) |
| | | private String tolerance; |
| | | |
| | | /** |
| | | * ãæ¤éæ è¯ï½éåºå段ã该æ¡å®æè®°å½å¯¹åºçæ£è
**彿¥éåç¶ææ¯å¦å·²ä¸æ¯"已就è¯(40)"**ï¼ |
| | | * å³"æ£æ¥å®æè¢«æ¤éè¿ãè¿æ²¡éæ°å®æ"ã |
| | | * |
| | | * <p>è®¡ç®æ¹å¼ï¼`JobRecordServiceImpl#getJobRecordPage` éæ (patId, checkType) å
³è彿¥ |
| | | * `queue.status`ï¼ç¶æ â 40 â trueãæ¤éåèªå¨å trueï¼æ£è
忬¡å®æï¼å 40ï¼èªå¨å falseï¼ |
| | | * ä¸éè¦ååºãä¹ä¸ä¼æ¼æ¸
æ è®°ã |
| | | * |
| | | * <p>å¿
é¡»æ {@code @TableField(exist = false)}ï¼æ¬ DO ä¼ç¨äº insert/updateByIdã |
| | | */ |
| | | @TableField(exist = false) |
| | | private Boolean undone; |
| | | } |
| | |
| | | */ |
| | | private Integer bookCheckType; |
| | | /** |
| | | * é¢çº¦åºå· |
| | | * é¢çº¦åºå·ã |
| | | * |
| | | * <p><b>ãå·²åç¨ã</b>æéå·ç»ä¸ä¸º {@link #seqNum}ï¼ç¾å°æ¶ä¸æ¬¡æ§åé
ãä¹åä¸åï¼ï¼ |
| | | * æ¬å段ä¸ååå
¥ãä¸åæ¾ç¤ºï¼ä»
为å
¼å®¹å岿°æ®ä¸ä¾¿äºåæ»èä¿çåã |
| | | * æ°ä»£ç 请å¿è¯»åæèµå¼ã |
| | | */ |
| | | private Integer bookSeqNum; |
| | | /** |
| | |
| | | */ |
| | | private Integer isVip; |
| | | /** |
| | | * æéåºå· |
| | | * æéåºå·ï¼æéå·ï¼ã |
| | | * |
| | | * <p>ãå·ç»ä¸ï¼æ¬éæ±ï¼ã<b>ç¾å°æ¶</b>æ {@code check_type.seq_rule} è§ååé
ï¼ |
| | | * ä¹åä»»ä½ç¯èé½ä¸åæ¹å¨ï¼åæµ/å«å·/è¿å·/å¬å/å æ¥/è£
æºåªæ¹ç¶æä¸è¯å®¤å·¥ä½ï¼ã |
| | | * <p>å·æ**æ£æ¥é¡¹ç®åèªç¼å·**ï¼è·¨æ£æ¥é¡¹ç®å
许éå¤ â æ¾ç¤ºä¸å¾ä¸º |
| | | * {@code check_type.seq_prefix + seqNum}ã |
| | | */ |
| | | private Integer seqNum; |
| | | /** |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.lihu.jh.module.ecg.dal.dataobject.queuesequence; |
| | | |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * ç¾å°åºå·è®¡æ°å¨ï¼å¯¹åº {@code seq_counter} 表ï¼ã |
| | | * |
| | | * <p>ä»
ç¨äºãæéåºå·è§å = ç¾å°åºå·ãæ¶è¯»å两个计æ°å¨ï¼ |
| | | * <ul> |
| | | * <li>{@code normalNext} ââ ä¸ä¸ä¸ª**æ®éå·**ï¼1..9ã11..19â¦ï¼è·³è¿ 10 çåæ°ï¼ï¼</li> |
| | | * <li>{@code reservedNext} ââ ä¸ä¸ä¸ª**é¢çå·**ï¼10ã20ã30â¦ï¼çç»å æ¥æ£è
ï¼ã</li> |
| | | * </ul> |
| | | * |
| | | * <p>乿以åæä¸¤ä¸ªè®¡æ°å¨ï¼å个计æ°å¨å¨"è·³è¿é¢çå·"æ¶å¿
ç¶ä¸åç»å·æè½¦ |
| | | * ï¼candidate=10 è·³è¿å¾ 11ï¼ä¸ä¸ä¸ª candidate=11 ä¹å¾ 11ï¼ãè¯¦è§ |
| | | * {@code QueueSequenceMapper} ä¸ç踩åè®°å½ã |
| | | * |
| | | * <p>该表æ {@code (check_type, seq_date)} å¯ä¸ï¼æ
**æ¯å¤©èªå¨éç½®** |
| | | * ï¼ç¬¬ä¸æ¬¡åå·æ¶ä»¥ {@code normal_next=1, reserved_next=10} æå
¥ï¼ã |
| | | * |
| | | * @author å¿çµæéè£
æºç³»ç» |
| | | */ |
| | | @Data |
| | | public class SeqCounterDO { |
| | | |
| | | private Integer id; |
| | | |
| | | /** æ£æ¥ç±»åå¼ï¼check_type.valueï¼ */ |
| | | private Integer checkType; |
| | | |
| | | /** æ¥æï¼æå¤©éç½®ï¼ */ |
| | | private java.time.LocalDate seqDate; |
| | | |
| | | /** ä¸ä¸ä¸ªæ®éå· */ |
| | | private Integer normalNext; |
| | | |
| | | /** ä¸ä¸ä¸ªé¢çå·ï¼å æ¥ç¨ï¼ */ |
| | | private Integer reservedNext; |
| | | |
| | | } |
| | |
| | | default PageResult<AppointmentDO> selectPage(AppointmentPageReqVO reqVO) { |
| | | LambdaQueryWrapperX<AppointmentDO> wrapper = (LambdaQueryWrapperX<AppointmentDO>) new LambdaQueryWrapperX<AppointmentDO>().eqIfPresent(AppointmentDO::getPatId, reqVO.getPatId()).likeIfPresent(AppointmentDO::getPatName, reqVO.getPatName()).eqIfPresent(AppointmentDO::getPatGender, reqVO.getPatGender()).eqIfPresent(AppointmentDO::getPatBirthday, reqVO.getPatBirthday()).eqIfPresent(AppointmentDO::getPatMobile, reqVO.getPatMobile()).eqIfPresent(AppointmentDO::getPatPhone, reqVO.getPatPhone()).eqIfPresent(AppointmentDO::getPatIdentityId, reqVO.getPatIdentityId()).eqIfPresent(AppointmentDO::getPatAddr, reqVO.getPatAddr()).eqIfPresent(AppointmentDO::getPatDeptCode, reqVO.getPatDeptCode()).eqIfPresent(AppointmentDO::getPatDeptDesc, reqVO.getPatDeptDesc()).eqIfPresent(AppointmentDO::getPatWardCode, reqVO.getPatWardCode()).eqIfPresent(AppointmentDO::getPatWardDesc, reqVO.getPatWardDesc()).eqIfPresent(AppointmentDO::getBookDate, reqVO.getBookDate()).eqIfPresent(AppointmentDO::getBookTimeslot, reqVO.getBookTimeslot()).eqIfPresent(AppointmentDO::getBookCheckType, reqVO.getBookCheckType()).eqIfPresent(AppointmentDO::getBookSrc, reqVO.getBookSrc()).eqIfPresent(AppointmentDO::getPaid, reqVO.getPaid()).eqIfPresent(AppointmentDO::getApplyNo, reqVO.getApplyNo()).eqIfPresent(AppointmentDO::getEpisodeId, reqVO.getEpisodeId()).inIfPresent(AppointmentDO::getStatus, reqVO.getStatus()) |
| | | // â
æ°å¢ï¼createTime åºé´æ¥è¯¢ |
| | | .betweenIfPresent(AppointmentDO::getCreateTime, reqVO.getCreateTimeStart(), reqVO.getCreateTimeEnd()).betweenIfPresent(AppointmentDO::getRegisterDate, reqVO.getRegisterDateStart(), reqVO.getRegisterDateEnd()); |
| | | .betweenIfPresent(AppointmentDO::getCreateTime, reqVO.getCreateTimeStart(), reqVO.getCreateTimeEnd()).betweenIfPresent(AppointmentDO::getRegisterDate, reqVO.getRegisterDateStart(), reqVO.getRegisterDateEnd()) |
| | | // ãæ¬éæ±ãé¢çº¦æ¥æ**æ¶é´æ®µ**æ¥è¯¢ï¼é¢çº¦è®°å½é¡µçãé¢çº¦æ¥æãæ¥æèå´ï¼ |
| | | .betweenIfPresent(AppointmentDO::getBookDate, reqVO.getBookDateStart(), reqVO.getBookDateEnd()); |
| | | // 卿æåº |
| | | if (reqVO.getOrderCreateTime() != null) { |
| | | wrapper.orderByDesc(AppointmentDO::getCreateTime); |
| | |
| | | } |
| | | |
| | | |
| | | @Select("select * from lihu.appointment where pat_id = #{patId} and to_days(book_date) = to_days(Now())") |
| | | @Select("select * from lihu.appointment where deleted = 0 and pat_id = #{patId} and to_days(book_date) = to_days(Now())") |
| | | List<AppointmentDO> getCurrentPatId(String patId); |
| | | |
| | | @Select("select * from lihu.appointment where (apply_no = #{code} or episode_id= #{code} or hospital_no =#{code} or pat_identity_id=#{code}) and book_date >= DATE_ADD(CURDATE(), INTERVAL -5 DAY) AND book_date <= DATE_ADD(CURDATE(), INTERVAL 15 DAY)") |
| | | /** |
| | | * ãæ¬éæ±ãæãæ£è
ç¼å· / ç³è¯·åå· / å°±è¯æµæ°´å· / ä½é¢å· / 身份è¯å·ãå¹é
é¢çº¦ï¼Â±5/+15 天çªå£ï¼ã |
| | | * |
| | | * <h3>为ä»ä¹å {@code pat_id} ä¸ {@code deleted = 0}</h3> |
| | | * <ul> |
| | | * <li><b>pat_id</b>ï¼æå¨æ°å»ºçé¢çº¦ï¼{@code /ecg/appointment/create}ï¼åªæ pat_idï¼ |
| | | * {@code apply_no} / {@code episode_id} / {@code hospital_no} / {@code pat_identity_id} å
¨ä¸ºç©ºï¼ |
| | | * ç¾å°é¡µææ£è
ç¼å·æ¥è¯¢æ¶æ°¸è¿æ¥ä¸å° â æç¤ºã请å
é¢çº¦ãâ æ æ³ç¾å°ï¼</li> |
| | | * <li><b>deleted = 0</b>ï¼å SQL æ¯è£¸æ¥è¯¢ï¼é»è¾å é¤çæ§è¡ä¹ä¼è¢«æåºæ¥ï¼ |
| | | * åç» {@code queryAndCreateAppointmentByPatId} ç"ä¸åå¨åæå
¥"é»è¾å¯è½æå·²å çååæåæ¥ã</li> |
| | | * </ul> |
| | | */ |
| | | @Select("select * from lihu.appointment where deleted = 0 " |
| | | + " and (apply_no = #{code} or episode_id = #{code} or hospital_no = #{code} " |
| | | + " or pat_identity_id = #{code} or pat_id = #{code}) " |
| | | + " and book_date >= DATE_ADD(CURDATE(), INTERVAL -5 DAY) " |
| | | + " and book_date <= DATE_ADD(CURDATE(), INTERVAL 15 DAY) " |
| | | + " order by book_date, id") |
| | | List<AppointmentDO> getCurrentCode(String code); |
| | | |
| | | @Select("select * from lihu.appointment where pat_id = #{patId} and book_check_type = #{checkType} and to_days(book_date) = to_days(Now()) limit 1") |
| | | AppointmentDO getByPatAndCheckTypeAndBookDate(@Param("patId") String patId, @Param("checkType") Integer checkType); |
| | | |
| | | /** |
| | | * ãæ¬éæ±ï¼ç´§æ¥æ£è
䏿éç´æ¥æ£æ¥ãæãç³è¯·åå· / å°±è¯å· / æ£è
ç¼å·ãæ¥è¿ä¸ä¸ªæçé¢çº¦è®°å½ã |
| | | * |
| | | * <p>çªå£ = [ä»å¤©-30 天, ä»å¤©+30 天]ï¼ç»æ**æé¢çº¦æ¶é´ååº**ï¼æè¿çæåé¢ï¼ï¼ä¾¿äºå»çéæ©ã |
| | | * æ£æ¥é¡¹ç®è¿æ»¤ï¼æ¬çªå£å¼å±çæ£æ¥é¡¹ç®ï¼ç± {@code checkTypeList} ä¼ å
¥ï¼ç©º/æªä¼ 表示ä¸éå¶ã |
| | | */ |
| | | @Select("<script>" + |
| | | "select * from lihu.appointment where deleted = 0 " + |
| | | " and (apply_no = #{code} or episode_id = #{code} or pat_id = #{code}) " + |
| | | " and book_date >= DATE_ADD(CURDATE(), INTERVAL -30 DAY) " + |
| | | " and book_date <= DATE_ADD(CURDATE(), INTERVAL 30 DAY) " + |
| | | " <if test='checkTypeList != null and checkTypeList.size() > 0'> " + |
| | | " and book_check_type in ( <foreach collection='checkTypeList' separator=',' item='ct'>#{ct}</foreach> ) " + |
| | | " </if> " + |
| | | " order by book_date desc, book_timeslot desc, id desc " + |
| | | "</script>") |
| | | List<AppointmentDO> getEmergencyCandidates(@Param("code") String code, |
| | | @Param("checkTypeList") List<Integer> checkTypeList); |
| | | |
| | | Integer updateStatusByApplyNo(@Param("applyNo") String applyNo, @Param("status") String status, @Param("registerDate") Date registerDate); |
| | | |
| | | @Select("select * from lihu.appointment where episode_id = #{episodeId} and apply_no = #{applyNo} limit 1") |
| | | /** |
| | | * åªæ´æ°ç¶æï¼ä¸å¨å
¶å®å段ï¼ã |
| | | * |
| | | * <p>èæ¯ï¼ç¶ææµåæ¥æ¯æ {@code getByApplyNo} æ¥åºæ¥çæ´è¡å¯¹è±¡å {@code updateById} ååï¼ |
| | | * å±äºã读-æ¹-åããå¹¶å/äº¤éæ¶ä¼æå«çåæ®µï¼å¦ book_date / book_check_typeï¼ææ§å¿«ç
§è¦çæï¼ |
| | | * 宿µ 2026-10-05 07:58 å°±åºç°è¿ä¸ç¬é¢çº¦ç check_type è¢«ç¶ææµè¦çã |
| | | * ç¶ææµåªè¯¥æ¹ç¶æï¼å æ¤åç¬æä¾è¿ä¸ªåªæ¹ status çè¯å¥ã</p> |
| | | */ |
| | | @Update("update lihu.appointment set status = #{status}, update_time = sysdate() where apply_no = #{applyNo} and deleted = 0") |
| | | Integer updateStatusOnlyByApplyNo(@Param("applyNo") String applyNo, @Param("status") String status); |
| | | /** ãæ¬æ¬¡ä¿®å¤ãè¡¥ {@code deleted = 0}ï¼é»è¾å é¤çè¡ä¸åºå被å½ä½"å·²åå¨"èè·³è¿æå
¥ã */ |
| | | @Select("select * from lihu.appointment where deleted = 0 and episode_id = #{episodeId} and apply_no = #{applyNo} limit 1") |
| | | AppointmentDO getByEpisodeIdAndApplyNo(@Param("episodeId") String episodeId, @Param("applyNo") String applyNo); |
| | | |
| | | @Select("select * from lihu.appointment where apply_no = #{applyNo} limit 1") |
| | | /** |
| | | * æç³è¯·åå·åæªå é¤çè®°å½ã |
| | | * |
| | | * <p>注æï¼è¿éå¿
须带 {@code deleted = 0}ãåå®ç°æ¯è£¸ selectï¼ä¼æ**é»è¾å é¤**çæ§è¡ä¹æåºæ¥ï¼ |
| | | * é
å {@code LIMIT 1} æ¶è¥æ§è¡ id æ´å°å°±ä¼åå°å·²å é¤ç飿¡ ââ è¿æ¯"å äºåè¢«æ´æ°åæ¥"ç鿣ã |
| | | * å¦å¤æ¬æ¹æ³é
åå¯ä¸ç´¢å¼ {@code uk_appointment_apply_no_active}ï¼åªçº¦ææªå é¤è¡ï¼ä½¿ç¨ã</p> |
| | | */ |
| | | @Select("select * from lihu.appointment where apply_no = #{applyNo} and deleted = 0 limit 1") |
| | | AppointmentDO getByApplyNo(@Param("applyNo") String applyNo); |
| | | |
| | | /** |
| | |
| | | " </foreach> )" + |
| | | "</script>") |
| | | List<AppointmentDO> getByApplyNoList(@Param("applyNoList") List<String> applyNoList); |
| | | |
| | | /** |
| | | * å该æ£è
**æè¿ä¸æ¡**æªå é¤è®°å½ï¼ç¨äºå®¹éæ°å¢æ¶ç»§æ¿æ£è
åºæå±æ§ |
| | | * ï¼çæ¥/çµè¯/身份è¯/å°åç ââ S050401 æ¥æåªå¸¦å§åï¼è¿äºåæ®µæ¥æéæ²¡æï¼ã |
| | | * |
| | | * <p>æ {@code create_time desc, id desc} æåºï¼ä¿è¯ç»æç¨³å®ï¼åä¸ç§å
æå
¥ç夿¡ä¹è½å®åºï¼ã |
| | | * åªç»§æ¿**æ£è
åºæå±æ§**ï¼ä¸ç»§æ¿å¼åå»ç/å¼åæ¶é´çæµæ°´å±æ§ï¼é£å±äºæ¨æï¼å¯è½å¼ å ææ´ï¼ã</p> |
| | | * |
| | | * @param patId æ£è
ç¼å·ï¼{@code appointment.pat_id}ï¼ |
| | | * @return æè¿ä¸æ¡è®°å½ï¼æ è®°å½æ¶è¿å {@code null} |
| | | */ |
| | | @Select("select * from lihu.appointment where pat_id = #{patId} and deleted = 0 " |
| | | + "order by create_time desc, id desc limit 1") |
| | | AppointmentDO getLatestByPatId(@Param("patId") String patId); |
| | | } |
| | | |
| | |
| | | @Select("select * from lihu.call_patient where pat_id = #{patId} order by id desc limit 1") |
| | | CallDO getLatestPatientCall(@Param("patId") String patId); |
| | | |
| | | /** |
| | | * 忣è
**æè¿ä¸æ¬¡å«å·è®°å½**ç idï¼key=pat_idï¼value=ææ° idï¼ã |
| | | * |
| | | * <p>ãéå«ï¼æ¬éæ±ï¼ã大å±/è¯é´å±é "æ°æ®åå"è§¦åææ¥ï¼é嫿¬èº«ä¸ä¼æ¹åéåæ°æ®ï¼ |
| | | * å æ¤ä¸åè¿ä¸ª callIdï¼å»çæ¯ç¹ä¸æ¬¡éå«é½ä¼**æ°å¢ä¸æ¡å«å·è®°å½**ï¼è§ {@code CallService#callAgain}ï¼ï¼ |
| | | * callId éä¹å大 â å±å¹æ®æ¤éæ°ææ¥ã |
| | | * |
| | | * <p>ç¨ create_time éå®è¿ 2 天ï¼call_patient ä¼è¢«æ¯æ¥æ¸
çï¼è§ clearCallï¼ï¼ |
| | | * é¿å
å
¨è¡¨ group byï¼ä¸ä¾èµ book_dateï¼å¯è½ä¸ºç©ºï¼ã |
| | | */ |
| | | @Select("select pat_id as patId, max(id) as callId from lihu.call_patient " + |
| | | "where create_time >= date_sub(now(), interval 2 day) group by pat_id") |
| | | List<Map<String, Object>> selectLatestCallIds(); |
| | | |
| | | // call_type 0 å¤§å± |
| | | @Select("select * from lihu.call_patient where called = 0 and call_type = 0 order by id limit 1") |
| | | CallDO getNextCall( ); |
| | |
| | | @Select("select * from lihu.dev_rent where state=#{state} and pat_id=#{patId} and check_type=#{checkType} and to_days(create_time)=to_days(now())") |
| | | List<DevRentDO> selectByPatAndChecktypeAndState(@Param("patId") String patId, @Param("checkType") Integer checkType, @Param("state") Integer state); |
| | | |
| | | /** |
| | | * 该æ£è
+ æ£æ¥é¡¹ç®ã**仿¥**ãç¶æå¨ç»å®éåéç**æè¿ä¸æ¡**æ£æ¥åã |
| | | * |
| | | * <p>两å¤ç¨éï¼ |
| | | * <ol> |
| | | * <li>ãæ¤éåæ»ãæ¤éãæ£æ¥å®æãæ¶ï¼æ 60(å¸¸è§æ£æ¥å®æ) çåæ¾åºæ¥åæ»æ 0(å¾
æ£æ¥)ï¼</li> |
| | | * <li>ã宿å
åºã忬¡å®ææ¶è¥æ¾ä¸å°ãå¾
æ£æ¥(0)ãçåï¼ç¨æè¿ä¸æ¡ 60/50 çåå
åºå¤ç¨ï¼ |
| | | * é¿å
ç´æ¥æ¥ã请å
é¢çº¦ç¡®è®¤ãã</li> |
| | | * </ol> |
| | | */ |
| | | @Select("<script>" + |
| | | "select * from lihu.dev_rent where pat_id=#{patId} and check_type=#{checkType} " + |
| | | " and to_days(create_time)=to_days(now()) and state in ( " + |
| | | " <foreach collection='stateList' separator=',' item='state'>#{state}</foreach> ) " + |
| | | " order by id desc limit 1" + |
| | | "</script>") |
| | | @Results({ |
| | | @Result(property = "patDetails", column = "pat_details", typeHandler=com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler.class) |
| | | }) |
| | | DevRentDO selectLatestByPatCheckTypeStates(@Param("patId") String patId, @Param("checkType") Integer checkType, |
| | | @Param("stateList") List<Integer> stateList); |
| | | |
| | | @Select("<script>" + |
| | | "SELECT paid FROM lihu.dev_rent " + |
| | | "where id in (" + |
| | |
| | | import cn.lihu.jh.module.ecg.controller.admin.queue.vo.*; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * æé Mapper |
| | |
| | | .orderByDesc(QueueDO::getId)); |
| | | } |
| | | |
| | | @Select("SELECT max(seq_num) FROM lihu.queue") |
| | | Integer getMaxSeqNum(); |
| | | |
| | | @Select("SELECT * FROM lihu.queue where seq_num = #{seqNum}") |
| | | @Results({ |
| | | @Result(property = "patDetails", column = "pat_details", typeHandler=com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler.class) |
| | | }) |
| | | QueueDO getQueueItemBySeqNum(@Param("seqNum")Integer seqNum); |
| | | |
| | | @Select("SELECT * FROM lihu.queue where pat_id = #{patId} and book_check_type = #{bookCheckType}") |
| | | @Results({ |
| | | @Result(property = "patDetails", column = "pat_details", typeHandler=com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler.class) |
| | | }) |
| | | QueueDO getQueueByPatId(@Param("patId")String patId, @Param("bookCheckType")Integer bookCheckType); |
| | | |
| | | /** |
| | | * è¯é´å±ï¼{@code ecg_call/small.html}ï¼åæ°ï¼æ¬è¯å®¤çæ£æ¥éåã |
| | | * |
| | | * <p>æåºè§åï¼å·ç»ä¸åçæç»è§åï¼ï¼<b>å°±è¯ä¸(30) 置顶 â å æ¥(jump_flag=1) â å
¶ä½ææéå· seq_num ååº</b>ï¼ |
| | | * å·ä¸ºç©ºï¼æ¹é å½å¤©å°æªè¿ç§»çåéè¡ï¼çæå¨æåã |
| | | * <p>è¿å·(3/5) <b>ä¸ååç¬æåä¸ç»</b>ï¼å®ä¸ãçåãæ··æãçå¨èªå·±çå·ä½ä¸ï¼ |
| | | * ç±å±ä¸ç¨çº¢è² +ã(è¿)ãå°ååºåï¼éæ±ï¼è¯é´å±ãçåãä¸ãè¿å·ãå并为ä¸ä¸ªãçåã颿¿ï¼ã |
| | | */ |
| | | @Select(""" |
| | | <script> |
| | | SELECT * FROM lihu.queue |
| | |
| | | </foreach> ) |
| | | order by case |
| | | when status = 30 then 0 |
| | | when status in (3, 5) then 1 |
| | | when jump_flag = 1 then 1 |
| | | when seq_num is null then 3 |
| | | else 2 |
| | | end, |
| | | seq_num, book_timeslot |
| | |
| | | |
| | | /** |
| | | * 大å±åæ°ã |
| | | * <p> |
| | | * æåºè§åï¼éæ±8ï¼ï¼**å°±è¯ä¸(30) 置顶 â è¿å·(3/5) ä¸çå(10/15/20/12) ææéåºå· seq_num ååºæ··æ**ã |
| | | * åå
ç¨ {@code order by status desc}ï¼ä¼æè¿å·(3/5)æå°æ¯ä¸åæåºé¨ï¼ |
| | | * å¨ {@code overflow-y:auto} çåéæ»ä¸å°ï¼çåäº"è¿å·ä¸æ¾ç¤º"ã |
| | | * <p> |
| | | * åæ¶è¡¥ä¸ {@code deleted = 0}ï¼æ¬æ¹æ³æ¯èªå®ä¹ {@code @Select}ï¼ |
| | | * ä¼ç»è¿ MyBatis-Plus ç {@code @TableLogic} é»è¾å é¤è¿æ»¤ã |
| | | * |
| | | * <p>æåºè§åï¼å·ç»ä¸åçæç»è§åï¼ï¼<b>å°±è¯ä¸(30) 置顶 â å æ¥(jump_flag=1) â å
¶ä½ææéå· seq_num ååº</b>ï¼ |
| | | * å·ä¸ºç©ºï¼æ¹é å½å¤©å°æªè¿ç§»çåéè¡ï¼çæå¨æåã |
| | | * <ul> |
| | | * <li>è¿å·(3/5) <b>ä¸ååç¬æåä¸ç»</b>ï¼å®çå¨èªå·±çå·ä½ä¸ï¼å±ä¸ç¨çº¢è² + è¿å·æ è®°åºåï¼ |
| | | * ä¸è¯é´å±ï¼{@code ecg_call/small.html}ï¼æ¹é åçå£å¾ä¸è´ã |
| | | * ï¼åå®ç°æ¯ {@code status desc}ï¼ä¼æè¿å·åå°æåºé¨ãçåäº"è¿å·ä¸æ¾ç¤º"ãï¼</li> |
| | | * <li>å æ¥å¿
é¡»å䏿åºï¼æéå·æ¹ä¸ºç¾å°æ¶ä¸æ¬¡æ§åé
ãä¹åä¸åæ¹å¨ï¼ |
| | | * å æ¥æ æ³åé "åæµæ¶æ¹å·/æééç¼å·"ä½ç°ã</li> |
| | | * <li>æ²¿ç¨ {@code deleted = 0}ï¼æ¬æ¹æ³æ¯èªå®ä¹ {@code @Select}ï¼ |
| | | * ä¼ç»è¿ MyBatis-Plus ç {@code @TableLogic} é»è¾å é¤è¿æ»¤ã</li> |
| | | * </ul> |
| | | */ |
| | | @Select(""" |
| | | <script> |
| | |
| | | </foreach> ) |
| | | order by case |
| | | when status = 30 then 0 |
| | | when status in (3, 5) then 1 |
| | | when jump_flag = 1 then 1 |
| | | when seq_num is null then 3 |
| | | else 2 |
| | | end, |
| | | seq_num, book_timeslot |
| | |
| | | <foreach collection='statusList' separator=',' item='status'> |
| | | #{status} |
| | | </foreach> ) |
| | | order by status desc, seq_num, book_timeslot |
| | | order by case when status = 30 then 0 else 1 end, |
| | | jump_flag desc, |
| | | case when seq_num is null then 1 else 0 end, |
| | | seq_num, book_timeslot |
| | | </script> |
| | | """) |
| | | @Results({ |
| | |
| | | }) |
| | | List<QueueDO> getBedQueueByStatus(@Param("roomId")Long roomId, @Param("bedNo")String bedNo, @Param("statusList")List<Integer> statusList); |
| | | |
| | | /** |
| | | * å«å·åäººï¼æ¬å·¥ä½ãåè¯ä¸(20)ãé**åºä¼å
å«**çé£ä¸ä½ã |
| | | * |
| | | * <p>æåºï¼å·ç»ä¸åçæç»è§åï¼ï¼<b>å æ¥(jump_flag=1) â æéå· seq_num ååº</b>ï¼å·ä¸ºç©ºï¼åéè¡ï¼ææåã |
| | | * <p>æéå·å¨ç¾å°æ¶ä¸æ¬¡æ§åé
ãä¹åä¸åæ¹å¨ï¼æä»¥"ä¸ä¸ä½å«è°"å®å
¨ç±æ¬æ¹æ³å³å®ï¼ |
| | | * å æ¥å¿
é¡»å¨è¿éå䏿åºï¼å¦åå æ¥æ£è
æ°¸è¿ä¸ä¼è¢«ä¼å
å«å°ã |
| | | */ |
| | | @Select(""" |
| | | SELECT * from lihu.queue where room_id = #{roomId} and bed_no = #{bedNo} |
| | | and status = #{curStatus} order by seq_num, book_timeslot limit 1 |
| | | and status = #{curStatus} and deleted = 0 |
| | | order by jump_flag desc, |
| | | case when seq_num is null then 1 else 0 end, |
| | | seq_num, book_timeslot |
| | | limit 1 |
| | | """) |
| | | QueueDO getBedFirstQueueItemByStatus(@Param("roomId")Long roomId, @Param("bedNo")String bedNo, @Param("curStatus")Integer curStatus); |
| | | |
| | |
| | | |
| | | // æä¸ªè¯å®¤èå´å
[å·²é¢ç¨] [å·²å¬å-å®è£
] äººå æ¢å , 伿´æ° [å·¥ä½å·] |
| | | // 没æé宿£æ¥ç±»åï¼ä¸è¦ä½¿ç¨æ¶é´æ§½ |
| | | // æåºï¼å æ¥ä¼å
â æéå·ååºï¼å·ä¸ºç©ºææåï¼ãè£
æºå«å·å人ä¹èµ°è¿éã |
| | | @Select("<script> " + |
| | | "select * from lihu.queue where room_id = #{roomId} and status in ( " + |
| | | "select * from lihu.queue where deleted = 0 and room_id = #{roomId} and status in ( " + |
| | | " <foreach collection='curStatusList' separator=',' item='status'>" + |
| | | " #{status} " + |
| | | " </foreach> )" + |
| | | " order by seq_num, book_timeslot limit 1 " + |
| | | " order by jump_flag desc, case when seq_num is null then 1 else 0 end, seq_num, book_timeslot limit 1 " + |
| | | "</script>" ) |
| | | QueueDO getRoomFirstQueueItemByStatus(@Param("roomId")Long roomId, @Param("curStatusList")List<Integer> curStatusList); |
| | | |
| | | /** |
| | | * æé¢çº¦å id æ¹éå queue è¡ã |
| | | * |
| | | * <p>ç¨éï¼é¢çº¦ç¾å°åï¼æã该é¢çº¦æ¯å¦å·²æéãæ¿å°çæéå·æ¯å¤å°ãåå¡«ç»å端ã |
| | | * å·ç»ä¸ååçæ¯ {@code seq_num}ï¼è§ AppointmentServiceImpl#queryAndCreateAppointmentByPatIdï¼ã |
| | | * <p>åæ¹æ³å为 {@code selectBookSeqNumByAppointIdList}ï¼å å·å·²ç»ä¸ä¸º seq_num èæ¹åã |
| | | */ |
| | | @Select("<script> " + |
| | | "select * from lihu.queue where appoint_id in ( " + |
| | | "select * from lihu.queue where deleted = 0 and appoint_id in ( " + |
| | | " <foreach collection='appointIdList' separator=',' item='appointId'>" + |
| | | " #{appointId} " + |
| | | " </foreach> )" + |
| | | "</script>" ) |
| | | List<QueueDO> selectBookSeqNumByAppointIdList(@Param("appointIdList") List<Long> appointIdList); |
| | | List<QueueDO> selectQueueByAppointIdList(@Param("appointIdList") List<Long> appointIdList); |
| | | |
| | | /* |
| | | @Select("select * from lihu.queue where room_id = #{roomId} and bed_no = #{bedNo} " + |
| | |
| | | @Update("update lihu.queue set status = #{newStatus} where pat_id = #{patId} and book_check_type = #{checkType} and status = #{curStatus}; " ) |
| | | Integer updatePatientQueueStatus(@Param("patId")String patId, @Param("checkType")Integer checkType, @Param("curStatus")Integer curStatus, @Param("newStatus")Integer newStatus); |
| | | |
| | | @Update("update lihu.queue set status = #{newStatus} where status = #{curStatus} and seq_num = \n" + |
| | | "(select a.min_seq_num from \n" + |
| | | " (select min(seq_num) as min_seq_num from lihu.queue where room_id = #{roomId} and bed_no = #{bedNo} and status = #{curStatus}) a )") |
| | | /** |
| | | * ææ¬å·¥ä½ãæå®ç¶æä¸ãæéå·æå°ãçä¸ä½æ¹ææ°ç¶æï¼è¿å·ç¨ï¼ã |
| | | * |
| | | * <p><b>ãå·ç»ä¸æ¹é å¿
ä¿®ãå¿
é¡»æè¡ id æ´æ°ã</b> |
| | | * æ§å®ç°å¤å±æ¡ä»¶æ¯ {@code where status = ? and seq_num = (select min(seq_num) ...)}ââ |
| | | * å¤å±<b>没æ room_id / bed_no æ¡ä»¶</b>ï¼å®å
¨ä¾èµ"seq_num å
¨è¡¨å¯ä¸"æä¸ä¼è¯¯ä¼¤ã |
| | | * æ¬éæ±ææéå·æ¹ä¸ºãææ£æ¥ç±»ååèªç¼å·ãï¼å·ä¼è·¨æ£æ¥ç±»åéå¤ï¼ |
| | | * æ§åæ³ä¼ä¸æ¬¡æ§æ<b>å
¨é¢ææåå·åç¶æçæ£è
</b>ä¸èµ·æ¹æ |
| | | * ï¼ä¾ï¼å¸¸è§å¿çµ 5 å·è¿å·ï¼å¨æå¿çµç 5 å·ä¹è¢«è¿å·ï¼ãæ
æ¹ä¸ºå
å idãåæ id æ´æ°ã |
| | | */ |
| | | @Update("update lihu.queue set status = #{newStatus} where id = " + |
| | | " (select a.id from " + |
| | | " (select id from lihu.queue where room_id = #{roomId} and bed_no = #{bedNo} " + |
| | | " and status = #{curStatus} and deleted = 0 " + |
| | | " order by case when seq_num is null then 1 else 0 end, seq_num, book_timeslot limit 1) a)") |
| | | Integer updateBedQueueStatus(@Param("roomId")Long roomId, @Param("bedNo")String bedNo, @Param("curStatus")Integer curStatus, @Param("newStatus")Integer newStatus); |
| | | |
| | | // å¼ç¨åå ï¼éè¦å
è·åï¼å¤æé»è¾å¤çåï¼åæ´æ° |
| | |
| | | ) |
| | | Integer preemptToBeInstalledPatient(@Param("roomId")Long roomId, @Param("bedNo")String bedNo, @Param("curStatusList")List<Integer> curStatusList, @Param("newStatus")Integer newStatus); |
| | | |
| | | // æ´ä¸ªç³»ç»èå´å
[æéä¸]人å [被工ä½å»ç]æ¢å |
| | | @Update("update lihu.queue set status = #{newStatus}, room_id = #{roomId}, room_name = #{roomName}, \n" + |
| | | " bed_no = #{bedNo}, seq_num = #{seqNum} where id = \n" + |
| | | " (select a.id from \n" + |
| | | " (select id from lihu.queue where status = #{curStatus} and book_check_type= #{checkType} order by jump_flag desc, book_timeslot, create_time limit 1) a)") |
| | | Integer preemptWaitingPatient(@Param("roomId")Long roomId, @Param("roomName")String roomName, @Param("bedNo")String bedNo, |
| | | @Param("seqNum")Integer seqNum, @Param("curStatus")Integer curStatus, @Param("newStatus")Integer newStatus, |
| | | @Param("checkType")Integer checkType); |
| | | |
| | | // æ´ä¸ªç³»ç»èå´å
[æéä¸]人å [被工ä½å»ç]æ¢å æ ¹æ® å¤ä¸ªæ£æ¥é¡¹ç® |
| | | @Update("<script>" + |
| | | "update lihu.queue set status = #{newStatus}, room_id = #{roomId}, room_name = #{roomName}, \n" + |
| | | " bed_no = #{bedNo}, seq_num = #{seqNum} where id = \n" + |
| | | " (select a.id from \n" + |
| | | " (select id from lihu.queue where status = #{curStatus} " + |
| | | " and book_check_type in ( " + |
| | | " <foreach collection='checkTypeArray' separator=',' item='_checkType'>" + |
| | | " #{_checkType} " + |
| | | " </foreach> )" + |
| | | " order by jump_flag desc, book_timeslot, create_time limit 1) a) " + |
| | | /** |
| | | * åãæ¬å·¥ä½å¼å±çæ£æ¥é¡¹ç®ãä¸ä¸ä¸ä½åºåæµçãæéä¸(10)ãæ£è
ã |
| | | * |
| | | * <p>æåºï¼<b>å æ¥(jump_flag=1) â é¢çº¦æ¶æ®µ â å»ºåæ¶é´</b>ï¼å·ä¸ºç©ºï¼åéè¡ï¼ææåã |
| | | * <p><b>è¿éä¸ååé
æéå·</b>ï¼å·å·²å¨ç¾å°æ¶ä¸æ¬¡æ§åå
¥ {@code seq_num}ï¼ |
| | | * åæµåªè´è´£ææ£è
ä»ãæéä¸ãæ¬å°æä¸ªå·¥ä½çãåè¯ä¸ãã |
| | | * <p>ååºååç¨ {@link #preemptWaitingPatientById} åæ¡ä»¶æ´æ°ï¼ |
| | | * é {@code and status = 10} ä¿è¯å¹¶åä¸åªæä¸æ¹è½æ¢å°è¯¥è¡ã |
| | | */ |
| | | @Select("<script>" + |
| | | "select * from lihu.queue where deleted = 0 and status = #{curStatus} " + |
| | | " and book_check_type in ( " + |
| | | " <foreach collection='checkTypeArray' separator=',' item='_checkType'>" + |
| | | " #{_checkType} " + |
| | | " </foreach> )" + |
| | | " order by jump_flag desc, case when seq_num is null then 1 else 0 end, book_timeslot, create_time limit 1" + |
| | | "</script>") |
| | | Integer preemptWaitingPatientWithBedCheckTypes(@Param("roomId")Long roomId, @Param("roomName")String roomName, @Param("bedNo")String bedNo, |
| | | @Param("seqNum")Integer seqNum, @Param("curStatus")Integer curStatus, @Param("newStatus")Integer newStatus, |
| | | @Param("checkTypeArray")Integer[] checkTypeArray); |
| | | @Results({ |
| | | @Result(property = "patDetails", column = "pat_details", typeHandler=com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler.class) |
| | | }) |
| | | QueueDO getFirstWaitingByCheckTypes(@Param("curStatus")Integer curStatus, @Param("checkTypeArray")Integer[] checkTypeArray); |
| | | |
| | | @Update("update lihu.queue set status = #{newStatus}, seq_num = #{seqNum} " + |
| | | " where id = " + |
| | | " (select a.id from \n" + |
| | | " (select id from lihu.queue where room_id = #{roomId} and bed_no = #{bedNo} and status = #{curStatus} " + |
| | | " order by seq_num, book_timeslot limit 1" + |
| | | " ) a" + |
| | | " )" ) |
| | | Integer queueRecalledPatient(@Param("roomId")Long roomId, @Param("roomName")String roomName, @Param("bedNo")String bedNo, |
| | | @Param("seqNum")Integer seqNum, @Param("curStatus")Integer curStatus, @Param("newStatus")Integer newStatus); |
| | | /** |
| | | * ãæ¬è¯å®¤/æ¬å·¥ä½**æéä¸ãè¿æ²¡åé
å·¥ä½**ãçæ£è
ï¼å·¥ä½å°"æ¬è¯å®¤æéä¸ï¼æªåé
ï¼"ååºç¨ï¼ã |
| | | * |
| | | * <p>èæ¯ï¼å·¥ä½å°çåè¯å表æ {@code room_id + bed_no} æ¥ï¼åªå
å«**å·²ç»åæµå°è¯¥å·¥ä½**çæ£è
ï¼ |
| | | * è"æéä¸(10)"çæ£è
{@code bed_no} æ¯ç©ºçï¼è§ QueueServiceImpl éç½®é»è¾ï¼room_id=0 / bed_no=' 'ï¼ï¼ |
| | | * 大å±ä¼æ¾ç¤ºä»ä»¬ï¼å¤§å±ä¸æè¯å®¤/å·¥ä½è¿æ»¤ï¼ï¼äºæ¯åºç°"大屿ãå·¥ä½å°å表没æ"çå°æã |
| | | * è¿éæ"æ¬å·¥ä½æ£æ¥ç±»åãå°æªåé
å·¥ä½"çæéæ£è
åç¬æ¥åºæ¥ï¼ç±å»ç**æå·¥æå
¥**ã |
| | | * |
| | | * <p>å¤å®"æªåé
"ç¨ {@code bed_no} 为空ï¼å
¼å®¹ null / 空串 / åä¸ªç©ºæ ¼ï¼ï¼ |
| | | * ä¸ä¾èµ {@code room_id = 0} è¿ä¸çº¦å®ï¼å®¹éæ´å¥½ã |
| | | */ |
| | | @Select(""" |
| | | <script> |
| | | SELECT * FROM lihu.queue |
| | | where deleted = 0 and status = #{curStatus} |
| | | and (bed_no is null or trim(bed_no) = '') |
| | | and book_check_type in ( |
| | | <foreach collection='checkTypeArray' separator=',' item='_checkType'> |
| | | #{_checkType} |
| | | </foreach> ) |
| | | order by jump_flag desc, |
| | | case when seq_num is null then 1 else 0 end, |
| | | book_timeslot, create_time |
| | | </script> |
| | | """) |
| | | @Results({ |
| | | @Result(property = "patDetails", column = "pat_details", typeHandler=com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler.class) |
| | | }) |
| | | List<QueueDO> selectUnassignedWaitingByCheckTypes(@Param("curStatus")Integer curStatus, |
| | | @Param("checkTypeArray")Integer[] checkTypeArray); |
| | | |
| | | /** |
| | | * æãæéä¸ãçæä¸è¡æ¢å å°æå®å·¥ä½ã |
| | | * |
| | | * <p><b>䏿¹æéå·</b>ï¼å·æ¯ç¾å°æ¶å®çï¼ï¼åªæ¹ç¶æãè¯å®¤ãå·¥ä½ã |
| | | * <p>{@code and status = #{curStatus}} æ¯å¹¶åä¿æ¤ ââ 两个工ä½åæ¶æ¢åä¸ä½æ£è
æ¶ï¼ |
| | | * åªæç¬¬ä¸ä¸ª UPDATE ä¼å½ä¸ï¼è¿å 1ï¼ï¼å¦ä¸æ¹è¿å 0ï¼ééæ°å人ã |
| | | */ |
| | | @Update("update lihu.queue set status = #{newStatus}, room_id = #{roomId}, room_name = #{roomName}, bed_no = #{bedNo} " + |
| | | " where id = #{id} and status = #{curStatus} and deleted = 0") |
| | | Integer preemptWaitingPatientById(@Param("id")Integer id, @Param("roomId")Long roomId, @Param("roomName")String roomName, |
| | | @Param("bedNo")String bedNo, @Param("curStatus")Integer curStatus, @Param("newStatus")Integer newStatus); |
| | | |
| | | /** |
| | | * ãæ¬éæ±Â·å¹¶åå åºãæä¸»é® + **å½åç¶æ**æ¡ä»¶æ¨è¿ç¶æï¼å«å·ï¼åè¯ä¸(20) â å°±è¯ä¸(30)ï¼ã |
| | | * |
| | | * <p>为ä»ä¹éè¦å®ï¼{@code nextPatient} 忥æ¯"å
æ¥æå°å·çåè¯è¡ â updateById"ï¼ |
| | | * 两个并å请æ±ï¼åå» / å¤ç«¯ï¼å¯è½åæ¨è¿ä¸æ¡ READYï¼å¯¼è´åä¸å·¥ä½åºç° **2 个ãå°±è¯ä¸ã**ã |
| | | * æäº {@code and status = #{curStatus}}ï¼åªæç¬¬ä¸ä¸ª UPDATE å½ä¸ï¼è¿å 1ï¼ï¼ |
| | | * å¦ä¸æ¹è¿å 0ï¼ç±è°ç¨æ¹æ¾å¼æ¬æ¬¡å«å·ï¼çä¸ä¸æ¬¡ååã |
| | | */ |
| | | @Update("update lihu.queue set status = #{newStatus}, update_time = NOW() " |
| | | + " where id = #{id} and status = #{curStatus} and deleted = 0") |
| | | Integer updateStatusByIdIfCurrent(@Param("id") Integer id, |
| | | @Param("curStatus") Integer curStatus, |
| | | @Param("newStatus") Integer newStatus); |
| | | |
| | | // å¸¸è§æ£æ¥ æ é¢ç¨ çæ£è
å¬å, åå·¥ä½å¤ç |
| | | @Update("update lihu.queue set status = #{newStatus}, passed = 1 " + |
| | |
| | | // ==================== éæ±2ï¼è¯¯ç¹ãå«å· / æ£æ¥å®æãçæ¤é ==================== |
| | | |
| | | /** |
| | | * æ¹éåãè¿äºæ£è
仿¥çéåç¶æãï¼ç¨äºå¤æ"å·²å®æè®°å½"æ¯å¦è¢«æ¤éè¿ï¼ã |
| | | * |
| | | * <p>ãéæ±ï¼æ¤éæ è¯ãæ¤éãæ£æ¥å®æãåªæ¯æéåè¡ 40(已就è¯) æ¹å 20(åå¤ä¸)ï¼ |
| | | * ä¸ç¢° job_recordãå æ¤"è¿æ¡å®æè®°å½æ¯å¦å·²æ¤é"ç¨**彿¥éåè¡çå½åç¶æ**夿å³å¯ï¼ |
| | | * ç¶æ â 40 â 已被æ¤éï¼åæ¬¡å®ææ¶ä¼åå 40 â èªå¨æ¢å¤æ"已宿"ï¼æ éé¢å¤æ¸
æ è®°ï¼ã |
| | | * |
| | | * <p>åªå彿¥ï¼æ¤éæ¬èº«å°±åªæ¯æå½æ¥ï¼ï¼ä¸æ¬¡æ¥è¯¢è§£å³æ´é¡µè®°å½ã |
| | | */ |
| | | @Select("<script>" + |
| | | "select pat_id as patId, book_check_type as checkType, status " + |
| | | " from lihu.queue " + |
| | | " where deleted = 0 and TO_DAYS(book_date) = TO_DAYS(NOW()) " + |
| | | " and pat_id in ( " + |
| | | " <foreach collection='patIdList' separator=',' item='_patId'>#{_patId}</foreach> ) " + |
| | | "</script>") |
| | | List<Map<String, Object>> selectTodayStatusByPatIds(@Param("patIdList")List<String> patIdList); |
| | | |
| | | /** |
| | | * æ¤éãæ£æ¥å®æãï¼ææ¬å·¥ä½ä»æ¥ç**æå®æ£è
**ä» å·²å°±è¯(40) éå åè¯ä¸(20)ã |
| | | * <p> |
| | | * å¿
é¡»æ {@code pat_id + book_check_type + 仿¥} 精确å®ä½ï¼**ä¸è½**åªæ |
| | |
| | | @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; ") |
| | | @Update("UPDATE lihu.queue_sequence SET queue_no=COALESCE(queue_set, 0), queue_vip_no=COALESCE(queue_vip_set, 0) WHERE deleted=0; ") |
| | | Integer initNumber(); |
| | | |
| | | // ========================================================================= |
| | | // ãæ¬éæ±ãææ¶æ®µé¢çº¦ä¸çº§åå·ï¼æ¬æ®µæ®éå· â æ¬æ®µé¢çå· â æ»é¢çæ± (time_slot=0) |
| | | // |
| | | // å·æ®µçº¦å®ï¼æ®éå¨åãé¢çç´§è·å
¶åãä¸ä¸æ®µèµ·ç¹ = ä¸ä¸æ®µ queue_vip_fullï¼ï¼ |
| | | // æ®éå·: queue_set+1 ⦠queue_full |
| | | // é¢çå·: queue_full+1 ⦠queue_vip_full |
| | | // æ»é¢çæ± : å·æ®µæ¾å¨å½å¤©æææ¶æ®µä¹åï¼ä¸**ä¸è®¾ä¸é** |
| | | // ========================================================================= |
| | | |
| | | /** åææ¶æ®µæ´è¡ï¼æ¿å° queue_set/queue_full/queue_vip_set/queue_vip_full è¾¹çï¼ */ |
| | | @Select("select * from lihu.queue_sequence where check_type=#{checkType} and time_slot=#{timeslot} and deleted=0 limit 1") |
| | | QueueSequenceDO selectSegByCheckTypeAndTimeSlot(@Param("checkType") Integer checkType, |
| | | @Param("timeslot") Integer timeslot); |
| | | |
| | | /** åè¯¥æ£æ¥ç±»åçãæ»é¢çæ± ãè¡ï¼time_slot = 0ï¼ */ |
| | | @Select("select * from lihu.queue_sequence where check_type=#{checkType} and time_slot=0 and deleted=0 limit 1") |
| | | QueueSequenceDO selectTotalPool(@Param("checkType") Integer checkType); |
| | | |
| | | /** è¯¥æ£æ¥ç±»åå½å¤©æææ¶æ®µç**æå¤§é¢çå·ä¸é**ï¼ç¨äºç»æ»é¢çæ± å®ä½å·æ®µèµ·ç¹ï¼ */ |
| | | @Select("select COALESCE(MAX(queue_vip_full), 0) from lihu.queue_sequence " |
| | | + " where check_type=#{checkType} and time_slot<>0 and deleted=0") |
| | | Integer selectMaxVipFullOfCheckType(@Param("checkType") Integer checkType); |
| | | |
| | | /** |
| | | * æ»é¢çæ± åå·ï¼**ä¸è®¾ä¸é**ã |
| | | * <p> |
| | | * è¯ä¹ä¸å
¶å®å·æ± ä¿æä¸è´ï¼{@code queue_vip_full} = å½åæå¤§å¯åå·ï¼ï¼ |
| | | * å· +1 çåæ¶æ {@code queue_vip_full} 顶䏿¥ï¼å æ¤æ°¸è¿ä¸ä¼åºç°"æ»æ± 已满ãç¾ä¸ä¸"ã |
| | | */ |
| | | @Update("update lihu.queue_sequence " |
| | | + " set queue_vip_no = queue_vip_no + 1, " |
| | | + " queue_vip_full = GREATEST(queue_vip_full, queue_vip_no + 1) " |
| | | + " where check_type=#{checkType} and time_slot=0 and deleted=0") |
| | | Integer advanceTotalPoolVipNo(@Param("checkType") Integer checkType); |
| | | |
| | | /** è¯»åæ»é¢çæ± å½åå·²åå·ï¼å¿
须䏿¨è¿å¨åä¸äºå¡å
ï¼ */ |
| | | @Select("select queue_vip_no from lihu.queue_sequence where check_type=#{checkType} and time_slot=0 and deleted=0") |
| | | Integer selectTotalPoolVipNo(@Param("checkType") Integer checkType); |
| | | |
| | | /** |
| | | * ãä¿®å¤ãæ¶æ®µä¸å
¨/å·²æ»¡å¯¼è´æ²¡æ³ç¾å°ãã夿æå® (æ£æ¥ç±»å, æ¶æ®µ) æ¯å¦**è¿æå¯åå·**ã |
| | | * <p> |
| | |
| | | @Mapper |
| | | public interface RoomMapper extends BaseMapperX<RoomDO> { |
| | | |
| | | /** |
| | | * è¯å®¤å·¥ä½å页ï¼è¯å®¤ç®¡çå表 / 导åºå
±ç¨ï¼ã |
| | | * |
| | | * <p>æåºï¼æ¬éæ±ï¼ï¼**è¯å®¤ç¼å·ååº â å·¥ä½å·ååº**ï¼åä¸è¯å®¤æå¤ä¸ªå·¥ä½æ¶é¡ºåºç¨³å®ã |
| | | * åå®ç°æ¯ {@code orderByDesc(id)}ï¼åå çææåï¼ï¼ä¸"æè¯å®¤ç¼å·ç"çç°åºä¹ æ¯ä¸ç¬¦ã |
| | | */ |
| | | default PageResult<RoomDO> selectPage(RoomPageReqVO reqVO) { |
| | | return selectPage(reqVO, new LambdaQueryWrapperX<RoomDO>() |
| | | .eqIfPresent(RoomDO::getRoomId, reqVO.getRoomId()) |
| | | .eqIfPresent(RoomDO::getBedNo, reqVO.getBedNo()) |
| | | .betweenIfPresent(RoomDO::getCreateTime, reqVO.getCreateTime()) |
| | | .orderByDesc(RoomDO::getId)); |
| | | .orderByAsc(RoomDO::getRoomId) |
| | | .orderByAsc(RoomDO::getBedNo)); |
| | | } |
| | | |
| | | @Select("select * from lihu.clinic_room where ip = #{ip}") |
| | | /** |
| | | * æ IP æ¥è¯¥ IP ä¸**å¯ç¨**çå·¥ä½ï¼ä¾"æIPèªå¨å¹é
å·¥ä½"使ç¨ï¼ã |
| | | * |
| | | * <p>䏿¡è¿æ»¤ç¼ºä¸ä¸å¯ï¼ |
| | | * <ul> |
| | | * <li>{@code deleted = 0}ï¼åå®ç°æ¯è£¸æ¥ï¼å·²å é¤çå·¥ä½ä¹ä¼è¢«å¹é
å°ââ |
| | | * 䏿¦æ IP è¢«åæ¶ååé
ç»æ°å·¥ä½ï¼å°±ä¼èªå¨å
¥åº§å°åå²èå·¥ä½ä¸ï¼</li> |
| | | * <li>{@code status != 0(å·²å
³é)}ï¼å·²å
³éçå·¥ä½ä¸è¯¥è¢«èªå¨å
¥åº§ï¼å¦å人åä¸å»å´æ²¡æåè¯éåï¼ççå"没ç
人"ï¼ï¼</li> |
| | | * <li>{@code ip <> ''}ï¼ç©º IP ä¸åå¹é
ï¼é¿å
åå²ç©ºå¼è¡è¢«æ«å°ï¼ã</li> |
| | | * </ul> |
| | | * ç¶æåå¼è§ {@link cn.lihu.jh.module.ecg.enums.BedStatusEnum}ï¼0å·²å
³é / 10å·²å¼é / 20æå»ç / 30æåã</p> |
| | | */ |
| | | @Select("select * from lihu.clinic_room " + |
| | | " where ip = #{ip} and deleted = 0 and coalesce(status, 0) <> 0") |
| | | @Results({ |
| | | @Result(property = "checkTypes", column = "check_types", typeHandler = com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler.class) |
| | | }) |
| | | List<RoomDO> queueByIp(@Param("ip") String ip); |
| | | |
| | | /** |
| | | * 该 IP æ¯å¦å·²ç»å®å¨**å«ç**å·¥ä½ä¸ï¼ç¨äº"鿩工使¨¡å¼"éå IP åçå²çªæ£æµï¼ã |
| | | * <p>ä¸ä¸ªå·¥ä½åªæä¸ä¸ª ip åæ®µï¼è¥ä¸¤å°çµèèµ°åä¸åºå£ IPï¼åç»å®ç伿åé¢çæ¢èµ°ï¼ |
| | | * æä»¥è¦çåè¦å
è®©ç¨æ·ç¡®è®¤ï¼å端æ¿å°å²çªå·¥ä½å弹确认ï¼å带 force éè°ï¼ã</p> |
| | | * |
| | | * @param ip å¾
ç»å®ç IP |
| | | * @param excludeId æé¤çå·¥ä½ä¸»é®ï¼éå¸¸æ¯æ¬æ¬¡è¦ç»å®çé£ä¸ªï¼ï¼å¯ä¸ºç©º |
| | | */ |
| | | @Select("<script> " + |
| | | "SELECT * FROM lihu.clinic_room " + |
| | | " WHERE deleted = 0 AND ip = #{ip} " + |
| | | " <if test='excludeId != null'> AND id != #{excludeId} </if> " + |
| | | " ORDER BY id" + |
| | | "</script>") |
| | | @Results({ |
| | | @Result(property = "checkTypes", column = "check_types", typeHandler = com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler.class) |
| | | }) |
| | | List<RoomDO> listByIpExcludeId(@Param("ip") String ip, @Param("excludeId") Integer excludeId); |
| | | |
| | | /** |
| | | * ææ¬æº IP åå°æå®å·¥ä½ï¼åªæ¹ ip ä¸ä¸ªå段ï¼ä¾"鿩工使¨¡å¼ 2/3"使ç¨ï¼ã |
| | | */ |
| | | @Update("update lihu.clinic_room set ip = #{ip} where id = #{id} and deleted = 0") |
| | | Integer updateIpById(@Param("id") Integer id, @Param("ip") String ip); |
| | | |
| | | @Update("<script> " + |
| | | "update lihu.clinic_room set status=#{newStatus}, doc_id=null, doc_name=null " + |
| | |
| | | |
| | | @Select("SELECT * FROM lihu.clinic_room where doc_id=#{docId}") |
| | | List<RoomDO> getRoomByDocId(@Param("docId")Long docId); |
| | | |
| | | /** |
| | | * ãæ¬éæ±Â·ä¸äººå¤å·¥ä½ã该å»ç**å½åææ**å ç¨çå
¨é¨å·¥ä½ã |
| | | * |
| | | * <p>æ¯ {@link #getRoomByDocId} å¤äºä¸¤ä¸ªè¿æ»¤ï¼ |
| | | * <ul> |
| | | * <li>{@code deleted = 0}ï¼æé¤åå²é»è¾å é¤è¡ï¼å SQL 没æï¼å¯è½è¿åèè¡ï¼ï¼</li> |
| | | * <li>{@code status in (20,30)}ï¼åªåãå»çå¨åº§(DOCTOR_ON) / å»çæå(DOCTOR_PAUSE)ãï¼ |
| | | * æé¤æ°æ®ä¸ä¸è´æ®çç"doc_id è¿å¨ä½ç¶æå·²å空é²"ã两个å¼ä»¥å¸¸éä¼ å
¥ï¼é¿å
硬ç¼ç ã</li> |
| | | * </ul> |
| | | */ |
| | | @Select("<script> " + |
| | | "SELECT * FROM lihu.clinic_room where doc_id = #{docId} and deleted = 0 " + |
| | | " and status in ( " + |
| | | " <foreach collection='statusList' separator=',' item='st'>#{st}</foreach> " + |
| | | " ) order by room_id, bed_no " + |
| | | "</script>") |
| | | List<RoomDO> getMyActiveBeds(@Param("docId") Long docId, @Param("statusList") List<Integer> statusList); |
| | | |
| | | /** |
| | | * ãæ¬éæ±Â·ç»è®¡æäººåå¹¶ãå½å**å¨åº§å»çæ°**ï¼æ doc_id å»éï¼ã |
| | | * |
| | | * <p>ä¸äººå¤å·¥ä½åï¼"å¨åº§å·¥ä½æ°"伿工ä½ç´¯è®¡ï¼æ°å¼æ¬èº«æ£ç¡®ï¼ï¼ |
| | | * ä½çæ§é¡µè¿éè¦"å°åºå 个å»çå¨å²"ï¼ç¨å®è¡¥ä¸ä¸ªææ ã |
| | | */ |
| | | @Select("<script> " + |
| | | "select count(distinct doc_id) from lihu.clinic_room " + |
| | | " where doc_id is not null and deleted = 0 and status in ( " + |
| | | " <foreach collection='statusList' separator=',' item='st'>#{st}</foreach> " + |
| | | " ) " + |
| | | "</script>") |
| | | Integer countSeatedDoctors(@Param("statusList") List<Integer> statusList); |
| | | |
| | | @Update("<script> " + |
| | | "update lihu.clinic_room set status=#{newStatus.status} " + |
| | |
| | | Integer setBedStopReady(@Param("roomId")Long roomId, @Param("bedNo")String bedNo, |
| | | @Param("stopReady")Integer stopReady); |
| | | |
| | | /** |
| | | * å
¥åº§ï¼æè¯¥å·¥ä½ç**主人**设为æï¼æ room_id + bed_no å®ä½ï¼ã |
| | | * |
| | | * <p>ãæ¬æ¬¡æ¾å®½ + ä¿®å¤ã |
| | | * <ul> |
| | | * <li>å¯å
¥åº§æ¡ä»¶ç»ä¸ä¸ºï¼<b>ï¼æ 主人 æ ä¸»äººæ¯æï¼ä¸ ç¶æ â claimableStatusList</b>ã |
| | | * ç¶æéåç±è°ç¨æ¹ä¼ {å·²å¼é, æå»ç, æå}ï¼**æé¤"å·²å
³é"**ï¼ã<br> |
| | | * 忥"æ 主人"æ¶åªè®¤"å·²å¼é"ï¼ä¸æ¦æ°æ®éåºç°"doc_id 为空ä½ç¶æä»æ¯æå»ç/æå" |
| | | * è¿ç§ä¸ä¸è´ï¼å»çç«å¨å·¥ä½åå´å§ç»åä¸ä¸ï¼åªæ¥"ç¶æå¼å¸¸"ï¼ç°åºæ ä»å¤çã</li> |
| | | * <li>ä¸»äººæ¯ææ¶åæ ·æ¾è¡ â 䏿¬¡æ²¡æ£å¸¸ç¦»åº§ï¼å
³æµè§å¨/è¶
æ¶ï¼ä¹è½ååèªå·±çå·¥ä½ã</li> |
| | | * <li>主人æ¯**å«äºº**æ¶æ´æ° 0 è¡ï¼è°ç¨æ¹æ®æ¤æç»ï¼ä¸æ¤ææ£å¨æä½ç人ï¼ã</li> |
| | | * </ul> |
| | | */ |
| | | @Update("<script> " + |
| | | "update lihu.clinic_room set status=#{newStatus.status}, doc_id=#{docId}, doc_name=#{docName} " + |
| | | "where room_id=#{roomId} and bed_no=#{bedNo} and isNull(doc_id)" + |
| | | "and status in ( " + |
| | | " <foreach collection='curStatusList' separator=',' item='curStatus'>" + |
| | | " #{curStatus.status} " + |
| | | " </foreach> );" + |
| | | "update lihu.clinic_room set status=#{newStatus.status}, doc_id=#{docId}, doc_name=#{docName}, update_time=NOW() " + |
| | | "where room_id=#{roomId} and bed_no=#{bedNo} and deleted = 0 " + |
| | | " and ( isNull(doc_id) or doc_id = #{docId} ) " + |
| | | " and status in ( " + |
| | | " <foreach collection='claimableStatusList' separator=',' item='curStatus'>#{curStatus.status}</foreach> );" + |
| | | "</script>") |
| | | Integer setBedDoctorOn(@Param("roomId")Long roomId, @Param("bedNo")String bedNo, @Param("docId")Long docId, @Param("docName")String docName, @Param("newStatus") BedStatusEnum newStatus, @Param("curStatusList") List<BedStatusEnum> curStatusList); |
| | | Integer setBedDoctorOn(@Param("roomId")Long roomId, @Param("bedNo")String bedNo, @Param("docId")Long docId, @Param("docName")String docName, |
| | | @Param("newStatus") BedStatusEnum newStatus, |
| | | @Param("claimableStatusList") List<BedStatusEnum> claimableStatusList); |
| | | |
| | | /** |
| | | * å
¥åº§ï¼åä¸ï¼ä½æ**ä¸»é® id** å®ä½ã |
| | | * |
| | | * <p>ãæ¬æ¬¡ä¿®å¤ãç°åºåºç°è¿"å·¥ä½å¨åºéæææ¯ç©ºé²çï¼å
¥åº§å´æ´æ° 0 è¡ â æ¥ç¶æå¼å¸¸"ã |
| | | * å·²ç¡®è®¤ä¸æ¯è¢«å ç¨ï¼å©ä¸çå¯è½æ¯ {@code bed_no} ä¸è¯·æ±å¼åå¨èç¼é¾è¾¨çå·®å¼ |
| | | * ï¼ç»å°¾ç©ºæ ¼ã大å°åãå
¨è§ç ââ JSON ä¸å¤å¶ç²è´´é½çä¸åºæ¥ï¼ã |
| | | * å端请æ±éæ¬æ¥å°±å¸¦ {@code id}ï¼å æ¤ä¼å
æä¸»é®æ´æ°ï¼å½»åºç»å¼è¿ç±»é®é¢ã |
| | | */ |
| | | @Update("<script> " + |
| | | "update lihu.clinic_room set status=#{newStatus.status}, doc_id=#{docId}, doc_name=#{docName}, update_time=NOW() " + |
| | | "where id=#{id} and deleted = 0 " + |
| | | " and ( isNull(doc_id) or doc_id = #{docId} ) " + |
| | | " and status in ( " + |
| | | " <foreach collection='claimableStatusList' separator=',' item='curStatus'>#{curStatus.status}</foreach> );" + |
| | | "</script>") |
| | | Integer setBedDoctorOnById(@Param("id")Integer id, @Param("docId")Long docId, @Param("docName")String docName, |
| | | @Param("newStatus") BedStatusEnum newStatus, |
| | | @Param("claimableStatusList") List<BedStatusEnum> claimableStatusList); |
| | | |
| | | /** |
| | | * è¯æç¨ï¼åå·¥ä½**åå§è¡**ï¼å« {@code bed_no} çé¿åº¦ä¸åå
è¿å¶ï¼ç¨äºåç°ç»å°¾ç©ºæ ¼/å
¨è§å·®å¼ï¼ã |
| | | * |
| | | * <p>ä¼ å
¥ id æ¶æ id æ¥ï¼å«å·²å é¤è¡ï¼ï¼å¦åæ room_id + {@code TRIM(bed_no)} å®½æ¾æ¥ã |
| | | * è¿å Map è䏿¯ DOï¼è¿éè¦æ {@code deleted}ãé¿åº¦ãHEX è¿äº"éå®ä½å段"ä¸èµ·å¸¦åºæ¥ã |
| | | */ |
| | | @Select("<script>" + |
| | | "select id, room_id, room_name, bed_no," + |
| | | " CHAR_LENGTH(bed_no) as bed_no_len, HEX(bed_no) as bed_no_hex," + |
| | | " ip, status, doc_id, doc_name, op_type, deleted, update_time" + |
| | | " from lihu.clinic_room" + |
| | | " where 1 = 1" + |
| | | " <if test='id != null'> and id = #{id} </if>" + |
| | | " <if test='id == null'> and room_id = #{roomId} and TRIM(bed_no) = TRIM(#{bedNo}) </if>" + |
| | | " order by deleted, id" + |
| | | "</script>") |
| | | List<Map<String, Object>> selectBedRawState(@Param("id") Integer id, @Param("roomId") Long roomId, @Param("bedNo") String bedNo); |
| | | |
| | | /** |
| | | * ãæ¬éæ±ãä¸ä¸ªç¨æ·åªå
许å ä¸ä¸ªå·¥ä½ï¼å
¥åº§æååï¼æ**æçå
¶å®å·¥ä½**éæ¾æã |
| | | * |
| | | * <p>åªæ¸
{@code doc_id/doc_name} å¹¶æç¶æç½®å"å·²å¼é"ï¼ä¸å¨ check_types / ip / stop_readyï¼ |
| | | * ç¨ {@code not (room_id = ? and bed_no = ?)} æé¤æ¬æ¬¡å
¥åº§çå·¥ä½ï¼é¿å
æèªå·±ååä¸ç乿¸
æã |
| | | * |
| | | * @param keepRoomId æ¬æ¬¡å
¥åº§çè¯å®¤ç¼å·ï¼ä¿çä¸å¨ï¼ |
| | | * @param keepBedNo æ¬æ¬¡å
¥åº§çå·¥ä½å·ï¼ä¿çä¸å¨ï¼ |
| | | */ |
| | | @Update("<script> " + |
| | | "update lihu.clinic_room set status=#{newStatus.status}, doc_id=null, doc_name=null, update_time=NOW() " + |
| | | "where doc_id=#{docId} and deleted = 0 " + |
| | | "<if test='keepRoomId != null and keepBedNo != null'>" + |
| | | " and not (room_id = #{keepRoomId} and bed_no = #{keepBedNo}) " + |
| | | "</if>" + |
| | | "</script>") |
| | | Integer releaseOtherBedsOfDoc(@Param("docId")Long docId, @Param("keepRoomId")Long keepRoomId, |
| | | @Param("keepBedNo")String keepBedNo, @Param("newStatus") BedStatusEnum newStatus); |
| | | |
| | | @Update("<script> " + |
| | | "update lihu.clinic_room set status=#{newStatus.status}, doc_id=null, doc_name=null " + |
| | | "where room_id=#{roomId} and bed_no=#{bedNo} " + |
| | | "where room_id=#{roomId} and bed_no=#{bedNo} and doc_id=#{docId} " + |
| | | "and status in ( " + |
| | | " <foreach collection='curStatusList' separator=',' item='curStatus'>" + |
| | | " #{curStatus.status} " + |
| | | " </foreach> );" + |
| | | "</script>") |
| | | Integer setBedDoctorOff(@Param("roomId")Long roomId, @Param("bedNo")String bedNo, @Param("docId")Long docId, @Param("newStatus") BedStatusEnum newStatus, @Param("curStatusList") List<BedStatusEnum> curStatusList); |
| | | |
| | | /** |
| | | * ãæ¬æ¬¡éæ±ãéè¯æ¶æ¸
空**ææè¢«å»çå ç¨**çå·¥ä½ï¼doc_id é空ï¼ä¸ç¶æä¸ºãå»çå¨å² / æåãï¼ã |
| | | * <p> |
| | | * èæ¯ï¼å·¥ä½ä¸åå ã空é²è¶
æ¶ / 令ç失æ / å·æ°é¡µé¢ãè¢«éæ¾ï¼é¿å
å»ç离å¼ä¸ä¼å¿å°±ä¸¢å·¥ä½ï¼ï¼ |
| | | * å æ¤éè¦ä¸ä¸ªå
åºï¼é²æ¢å»çä¸çå¿ç¦»åº§å¯¼è´å·¥ä½é¿æè¢«å ç¨ ââ éè¯æ¶ç»ä¸æ¸
空å½çå·¥ä½ã |
| | | * |
| | | * @param newStatus æ¸
空å置为çç¶æï¼ç©ºé² / å·²å¼éï¼ |
| | | * @param curStatusList å
许被æ¸
空çå½åç¶æéå |
| | | */ |
| | | @Update("<script> " + |
| | | "update lihu.clinic_room set status=#{newStatus.status}, doc_id=null, doc_name=null, update_time=NOW() " + |
| | | "where deleted = 0 and doc_id is not null " + |
| | | "and status in ( " + |
| | | " <foreach collection='curStatusList' separator=',' item='curStatus'>" + |
| | | " #{curStatus.status} " + |
| | | " </foreach> )" + |
| | | "</script>") |
| | | Integer clearAllBedDoctors(@Param("newStatus") BedStatusEnum newStatus, @Param("curStatusList") List<BedStatusEnum> curStatusList); |
| | | |
| | | /** |
| | | * ãæ¬æ¬¡éæ±ã管çåå¼ºå¶æ¸
空æä¸ªå·¥ä½ã |
| | | * <p> |
| | | * ä¸ {@link #setBedDoctorOff} çå¯ä¸åºå«ï¼**ä¸å¸¦ `doc_id = ?` æ¡ä»¶**ï¼ |
| | | * å æ¤å¯ä»¥æ"å«äººå ç¨ä¸"ç工使¸
æï¼å»çä¸çå¿ç¦»åº§ãæ¢äººä½¿ç¨åä¸å·¥ä½æ¶ç¨ï¼ã |
| | | * ä»ç¶è¦æ±å½åç¶ææ¯ãå»çå¨å² / æåãä¸ doc_id é空ï¼é¿å
误æ¸
空é²å·¥ä½ã |
| | | */ |
| | | @Update("<script> " + |
| | | "update lihu.clinic_room set status=#{newStatus.status}, doc_id=null, doc_name=null, update_time=NOW() " + |
| | | "where room_id=#{roomId} and bed_no=#{bedNo} and doc_id is not null " + |
| | | "and status in ( " + |
| | | " <foreach collection='curStatusList' separator=',' item='curStatus'>" + |
| | | " #{curStatus.status} " + |
| | | " </foreach> )" + |
| | | "</script>") |
| | | Integer setBedDoctorOffAdmin(@Param("roomId")Long roomId, @Param("bedNo")String bedNo, |
| | | @Param("newStatus") BedStatusEnum newStatus, @Param("curStatusList") List<BedStatusEnum> curStatusList); |
| | | } |
| | |
| | | import lombok.Getter; |
| | | |
| | | /** |
| | | * HisçCheck_typeç±»åæä¸¾ |
| | | * HisçCheck_typeç±»åæä¸¾ï¼æ HIS ä¼ æ¥ç**æ£æ¥é¡¹ç®åç§°**æ å°æ¬å° check_typeï¼ |
| | | * |
| | | * <p>注æï¼åä¸ä¸ªæ£æ¥å¨ HIS ä¾§å¯è½æå¤ä¸ªå«æ³ï¼æ¬æä¸¾ç¨ãä¸ä¸ªå¼æå¤ä¸ªåç§°ãçæ¹å¼å
¼å®¹ã |
| | | * 宿µ 2026-10-04/05ï¼è¿å¨è¯éªè¿ä¸é¡¹ HIS ä¾§æ¹åè¿ââ |
| | | * ãå¹³æ¿è¿å¨å¿çµãï¼æ§ï¼âãå¹³æ¿è¿å¨è¯éªãï¼ç°ï¼ï¼èæ¬å° check_type ä¸ç´æ¯ 400ã |
| | | * åç§°æ å°ä¸å°æ¶ï¼{@code handleAppointmentCreate} ä¼éåæ HIS æ£æ¥ä»£ç æ å° |
| | | * ï¼{@link HisCheckCodeEnum}ï¼ï¼ä¸¤æ¡è·¯ä»»ä¸æ¡éå³å¯ï¼é¿å
ååºç° book_check_type 为空ã</p> |
| | | * |
| | | * <p>宿µ 2026-10-07 ååç°è¡åç±»åæ ·çé®é¢ï¼HIS åçæ¯ã24å°æ¶å¨æè¡åçæµãï¼ |
| | | * èæä¸¾é彿¶åªæã卿è¡åãï¼ç²¾ç¡®å¹é
å¤±è´¥ï¼æ¥å¿ï¼ |
| | | * {@code [handleAppointmentCreate][使£æ£è
æ£æ¥é¡¹ç®åç§°æ æ³æ å°] checkName=24å°æ¶å¨æè¡åçæµ}ï¼ã |
| | | * ç°å·²è¡¥é½å«åï¼åæ¶ {@link #getByName(String)} å¢å ä¸å±**è§èåå
åºå¹é
**ï¼ |
| | | * ç¨äºå¸æ¶ HIS ä¾§ãææ ã24å°æ¶ãåç¼ããå
¨/åè§æ¬å·ããå¤ä½ç©ºæ ¼ãè¿ç±»æ æä¹å·®å¼ï¼ |
| | | * é¿å
æ¯æ¢ä¸ç§å«æ³å°±è¦æ¹ä¸æ¬¡ä»£ç ã</p> |
| | | */ |
| | | @Getter |
| | | @AllArgsConstructor |
| | |
| | | Y691133607("常è§å¿çµå¾", "100"), |
| | | Y201605("24å°æ¶å¨æå¿çµå¾", "200"), |
| | | Y201606("24å°æ¶å¨æå¿çµçæµ", "200"), |
| | | // å䏿£æ¥ï¼æ¬å° check_type=200 卿å¿çµï¼çå
¶å®å«æ³ã |
| | | // 宿µæ¥æé该项ç code åå¨ä¸¤ç§å½¢æï¼Y201605ï¼å¸¦Yåç¼ï¼ä¸ 201605ï¼ä¸å¸¦ï¼ï¼ |
| | | // è HisCheckCodeEnum åªç»è®°äº 201605ï¼æ
带 Y çé£ç§å¿
é¡»é åç§°æ å°å
ä½ã |
| | | Y201605_ALIAS1("卿å¿çµå¾", "200"), |
| | | Y201605_ALIAS2("24å°æ¶å¨æå¿çµ", "200"), |
| | | Y201605_ALIAS3("卿å¿çµçæµ", "200"), |
| | | Y200327("卿è¡å", "300"), |
| | | // å䏿£æ¥ï¼æ¬å° check_type=300 卿è¡åï¼çå
¶å®å«æ³ã |
| | | // 宿µ 2026-10-07ï¼HIS å®é
ä¸åçæ¯ã24å°æ¶å¨æè¡åçæµãï¼jcxmcode=Y200327ï¼ï¼ |
| | | // 彿¶æä¸¾åªæã卿è¡åãâ åç§°å¹é
失败ï¼ä¸ä»£ç å
åºä¹å¯¹ä¸ä¸ï¼ä»£ç æ¯ Y200327ï¼è¡¨éè®°çæ¯ 200327ï¼ã |
| | | Y200327_ALIAS1("24å°æ¶å¨æè¡åçæµ", "300"), |
| | | Y200327_ALIAS2("24å°æ¶å¨æè¡å", "300"), |
| | | Y200327_ALIAS3("卿è¡åçæµ", "300"), |
| | | Y201652("å¹³æ¿è¿å¨å¿çµ", "400"), |
| | | // å䏿£æ¥ï¼æ¬å° check_type=400ï¼çå
¶å®å«æ³ï¼æä¸¾å¸¸éåä¸è½éå¤ï¼æ
å åç¼ |
| | | Y201652_ALIAS1("å¹³æ¿è¿å¨è¯éª", "400"), |
| | | Y201652_ALIAS2("å¿çµå¾è¿å¨è¯éª", "400"), |
| | | Y502490914("å¨èç¡¬åæ£æµ", "500"), |
| | | Y419562119("é£éçµçç", "600"), |
| | | Y201604("å¿çµå¾è¯ç©è´è·è¯éª", "700"), |
| | |
| | | private final String value; |
| | | |
| | | /** |
| | | * æ ¹æ®ç±»åè·åæä¸¾ |
| | | * æ ¹æ®åç§°è·åæ¬å°æ£æ¥ç±»åï¼å
精确å¹é
ï¼åè§èåå
åºå¹é
ã |
| | | * |
| | | * @param type ç±»å |
| | | * @return æä¸¾ |
| | | * @param name HIS ä¼ æ¥çæ£æ¥é¡¹ç®åç§° |
| | | * @return æ¬å° check_type å符串ï¼é½å¹é
ä¸å°è¿å null |
| | | */ |
| | | public static String getByName(String name) { |
| | | if (name == null) { |
| | | return null; |
| | | } |
| | | // â 精确å¹é
ï¼ä¿æåæè¡ä¸ºï¼ |
| | | for (HisCheckNameEnum value : values()) { |
| | | if (value.getName().equals(name)) { |
| | | return value.getValue(); |
| | | } |
| | | } |
| | | // â¡ è§èåååå¹é
ï¼å¸æ¶ã24å°æ¶ãåç¼ãå
¨/åè§æ¬å·ãç©ºæ ¼ã大å°åçæ æä¹å·®å¼ï¼ |
| | | // é¿å
HIS æ¯æ¢ä¸ç§å«æ³å°±æ¼æ å°ï¼ä¾å¦ã24å°æ¶å¨æè¡åçæµãvsã卿è¡åçæµãï¼ |
| | | String normalized = normalizeName(name); |
| | | if (normalized.isEmpty()) { |
| | | return null; |
| | | } |
| | | for (HisCheckNameEnum value : values()) { |
| | | String enumNormalized = normalizeName(value.getName()); |
| | | if (enumNormalized.equals(normalized)) { |
| | | return value.getValue(); |
| | | } |
| | | // â¢ å»æã24å°æ¶ãå忝䏿¬¡ï¼HIS ä¾§ææ è¯¥åç¼é½å¯è½åºç° |
| | | if (strip24Hour(enumNormalized).equals(strip24Hour(normalized)) && !strip24Hour(normalized).isEmpty()) { |
| | | return value.getValue(); |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | /** è§èå项ç®åç§°ï¼å»ç©ºç½ãç»ä¸å¤§å°åãå
¨è§æ¬å·âåè§ã廿ã24å°æ¶ãåç¼ */ |
| | | private static String normalizeName(String name) { |
| | | if (name == null) { |
| | | return ""; |
| | | } |
| | | return name.trim() |
| | | .replace(" ", "") |
| | | .replace("\u3000", "") |
| | | .replace("ï¼", "(") |
| | | .replace("ï¼", ")") |
| | | .replace("ï¼ï¼", "24") |
| | | .toLowerCase(); |
| | | } |
| | | |
| | | /** 廿ã24å°æ¶ã/ã24hãåç¼ï¼ç¨äºæ¯è¾åä¹åç§° */ |
| | | private static String strip24Hour(String normalizedName) { |
| | | String v = normalizedName; |
| | | if (v.startsWith("24å°æ¶")) { |
| | | v = v.substring("24å°æ¶".length()); |
| | | } |
| | | if (v.startsWith("24h")) { |
| | | v = v.substring("24h".length()); |
| | | } |
| | | return v; |
| | | } |
| | | |
| | | /** |
| | | * æ ¹æ®ç±»åè·åæä¸¾ |
| | | * |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.lihu.jh.module.ecg.enums; |
| | | |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Getter; |
| | | |
| | | import java.util.Objects; |
| | | |
| | | /** |
| | | * HIS æ£æ¥ç¶æç¼ç ã |
| | | * |
| | | * <h3>æ¥æº</h3> |
| | | * 颿¹ãæ£æ¥ç¶æç¼ç 表ãï¼ |
| | | * <pre> |
| | | * 1 ç³è¯·åå¼ç« 2 ç³è¯·åæ¤é 3 æ£æ¥ç»è®° |
| | | * 4 åæ¶æ£æ¥ 5 æ£æ¥å¼å§ 6 ç»é å½±å |
| | | * 7 æ£æ¥ç»æ 8 æ¥åçæ 9 æ¥åæ¤é |
| | | * 10 æ¥åå®¡æ ¸ |
| | | * 21 æ æ¬éæ£ï¼ç
çç¨ï¼ 22 åæ¶æ æ¬éæ£ï¼ç
çç¨ï¼ 23 已缴费ï¼ç
çç¨ï¼ |
| | | * </pre> |
| | | * å
¶ä¸ 21/22/23 为**ç
çä¸ç¨ï¼å¿çµç³»ç»ä¸æ¶å**ï¼æ¬æä¸¾ä¸å
å«ã |
| | | * |
| | | * <h3>为ä»ä¹éè¦å½ä¸å</h3> |
| | | * HIS æ¥æä¸åä¸ä¸ªç¶æä¼ä»¥ä¸ååé¢å½¢å¼åºç°ï¼å®æµæ¥å¿ä¸åå¨ï¼ |
| | | * <pre> |
| | | * processStep.code = "3" / "03" / "7" / "08" / "10" |
| | | * </pre> |
| | | * å³**å坼鶿¯å¦åå¨å¹¶ä¸ç¨³å®**ï¼æ¥å£ææ¡£ç¤ºä¾ç»çæ¯ {@code code="01"}ï¼ã |
| | | * è¥ç´æ¥åå
¥æ°æ®åºï¼ä¼äº§ç "3" ä¸ "03" 两ç§å¼ï¼å¯¼è´ç¶æå¤æéä¹±ã |
| | | * å æ¤ç»ä¸ç» {@link #normalize(String)} å½ä¸å为æ å导é¶çæ åç¼ç ååå
¥åºã |
| | | * |
| | | * @author å¿çµæéè£
æºç³»ç» |
| | | */ |
| | | @Getter |
| | | @AllArgsConstructor |
| | | public enum HisCheckStatusEnum { |
| | | |
| | | APPLY_CREATED(1, "ç³è¯·åå¼ç«"), |
| | | APPLY_CANCELLED(2, "ç³è¯·åæ¤é"), |
| | | REGISTERED(3, "æ£æ¥ç»è®°"), |
| | | CHECK_CANCELLED(4, "åæ¶æ£æ¥"), |
| | | CHECK_STARTED(5, "æ£æ¥å¼å§"), |
| | | CONTRAST_GIVEN(6, "ç»é å½±å"), |
| | | CHECK_FINISHED(7, "æ£æ¥ç»æ"), |
| | | REPORT_GENERATED(8, "æ¥åçæ"), |
| | | REPORT_CANCELLED(9, "æ¥åæ¤é"), |
| | | REPORT_REVIEWED(10, "æ¥åå®¡æ ¸"); |
| | | |
| | | /** æ åç¼ç ï¼æ å导é¶ï¼ */ |
| | | private final Integer code; |
| | | /** ç¶æåç§° */ |
| | | private final String name; |
| | | |
| | | /** |
| | | * å½ä¸å HIS æ¥æä¸çç¶æç¼ç å符串ã |
| | | * <p> |
| | | * å¤çå
容ï¼å»ç©ºç½ãå»å导é¶ãæ ¡éªæ¯å¦å¨ç¼ç 表å
ã |
| | | * |
| | | * @param raw æ¥æåå§å¼ï¼å¦ "3"ã"03"ã" 10 " |
| | | * @return å½ä¸ååçæ åç¼ç å符串ï¼å¦ "3"ã"10"ï¼ï¼æ æ³è¯å«æ¶è¿å null |
| | | */ |
| | | public static String normalize(String raw) { |
| | | if (raw == null) { |
| | | return null; |
| | | } |
| | | String trimmed = raw.trim(); |
| | | if (trimmed.isEmpty()) { |
| | | return null; |
| | | } |
| | | // ä»
æ¥åæ°åï¼é¿å
æéæ°åå
容åå
¥ status |
| | | if (!trimmed.matches("\\d+")) { |
| | | return null; |
| | | } |
| | | // å»å导é¶ï¼"03" -> "3"ï¼"0" -> "0" |
| | | String stripped = trimmed.replaceFirst("^0+(?=\\d)", ""); |
| | | int code; |
| | | try { |
| | | code = Integer.parseInt(stripped); |
| | | } catch (NumberFormatException e) { |
| | | return null; |
| | | } |
| | | // åªæ¥åç¼ç 表å
çå¼ |
| | | return contains(code) ? String.valueOf(code) : null; |
| | | } |
| | | |
| | | /** 夿ç¼ç æ¯å¦å±äºæ¬ç¼ç 表ï¼ä¸å«ç
çä¸ç¨ç¶æï¼ */ |
| | | public static boolean contains(Integer code) { |
| | | if (code == null) { |
| | | return false; |
| | | } |
| | | for (HisCheckStatusEnum item : values()) { |
| | | if (Objects.equals(item.code, code)) { |
| | | return true; |
| | | } |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | /** æç¼ç åç¶æåç§°ï¼æªå¹é
è¿å null */ |
| | | public static String getNameByCode(Integer code) { |
| | | if (code == null) { |
| | | return null; |
| | | } |
| | | for (HisCheckStatusEnum item : values()) { |
| | | if (Objects.equals(item.code, code)) { |
| | | return item.name; |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | } |
| | |
| | | */ |
| | | List<AppointmentDO> queryAndCreateAppointmentByPatId(String patCode); |
| | | |
| | | /** |
| | | * ãæ¬éæ±ï¼ç´§æ¥æ£è
䏿éç´æ¥æ£æ¥ãæãç³è¯·åå· / å°±è¯å· / æ£è
ç¼å·ãæ¥è¿ä¸ä¸ªæçé¢çº¦è®°å½ã |
| | | * |
| | | * @param code ç³è¯·åå· / å°±è¯æµæ°´å· / æ£è
ç¼å·ï¼ä¸è
ä¹ä¸ï¼ |
| | | * @param checkTypes æ¬çªå£å¼å±çæ£æ¥é¡¹ç®ï¼éå·åéï¼ä¸ºç©ºè¡¨ç¤ºä¸éå¶ |
| | | * @return é¢çº¦è®°å½ï¼**æé¢çº¦æ¶é´ååº**ï¼æè¿çå¨åï¼ |
| | | */ |
| | | List<AppointmentDO> getEmergencyCandidates(String code, String checkTypes); |
| | | |
| | | List<AppointmentDO> getAppointmentExtermal(String patId); |
| | | |
| | | Integer appoitmentConfirm(AppointmentConfirmReqVO appointmentConfirmReqVO); |
| | |
| | | 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; |
| | |
| | | |
| | | // è¿å |
| | | 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ï¼HIS å¨ 423ms å
æåä¸å¼ ç³è¯·åæ¨äºä¸¤éï¼ä¸¤ä¸ªçº¿ç¨é½è¯»å° 0 è¡ã |
| | | * 齿§è¡äº insertï¼äºæ¯åä¸ {@code apply_no} è½ä¸ä¸¤æ¡ï¼id 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 |
| | |
| | | @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 å
¨ä¸ºç©ºï¼ |
| | | // ç¾å°é¡µææ£è
ç¼å·æ¥è¯¢æ¶**æ°¸è¿æ¥ä¸å°** â é¡µé¢æç¤ºã请å
é¢çº¦ãâ æ æ³ç¾å°ã |
| | | List<AppointmentDO> appointmentExtermalList = appointmentMapper.getCurrentCode(patCode); |
| | | |
| | | for (int appointmentIndex = 0; appointmentIndex < appointmentExtermalList.size(); appointmentIndex++) { |
| | |
| | | if (null == appointmentExtermal) continue; |
| | | |
| | | // ä»DBæ¥è¯¢é¢çº¦ï¼æ¯å¦å·²ç»åå¨ |
| | | AppointmentDO appointmentDO = appointmentMapper.getByEpisodeIdAndApplyNo(appointmentExtermal.getEpisodeId(), appointmentExtermal.getApplyNo()); |
| | | // |
| | | // ãæ¬éæ±ãä¼å
æ**ä¸»é® id** å¤æãæ¯å¦å·²åå¨ãï¼ |
| | | // getCurrentCode æ¯æ¬å°åºæ¥è¯¢ï¼select * 伿 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()` |
| | | // æ¯**å¼ç¨æ¯è¾**ï¼LocalDate 两个ä¸åå®ä¾å³ä½¿å¼ç¸åä¹ä¼å¤ä¸ºä¸çï¼ï¼ |
| | | // ä¼å¯¼è´æ¯æ¬¡é½ç½è·ä¸æ¬¡ 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ï¼éæ±è¦æ±æ¥å£å段ä¿çä¸å¨ï¼ã |
| | | // è¿æ»¤ 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()))); |
| | | } |
| | | } |
| | | |
| | |
| | | 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/å å·/éå½å¤©ç¾å
¥ â æ¬æ®µé¢çå· â æ»é¢çæ± ï¼time_slot=0ï¼ |
| | | // · æ®é â æ¬æ®µæ®éå· â æ¬æ®µé¢çå· â æ»é¢çæ± |
| | | // 没æé¢çº¦æ¶æ®µï¼bookTimeslot 为空/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(); |
| | |
| | | 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ï¼ISCBãæ¯å¦åºè¾¹ãééåä¸èµ·è½åºï¼ä¾å±å¹/页é¢å±ç¤º |
| | | 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={}", |
| | |
| | | appointment.setTargetSiteCode(targetSite); |
| | | } |
| | | |
| | | // é¢çº¦æ¶é´/æ¶é´æ®µ/è¯å®¤ï¼S0201ECG æ¥æç 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 |
| | | // |
| | | // 便®ï¼HISãäº¤äºæå¡éç¨æ¥å£ææ¡£ãï¼ï¼ |
| | |
| | | } |
| | | } |
| | | |
| | | // å»çå¼åæ¶é´ |
| | | 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; |
| | | // å»çå¼åæ¶é´ï¼æ¥æè·¯å¾ï¼controlActProcess.subject.observationRequest.author.time.valueï¼ |
| | | // |
| | | // ã为ä»ä¹ä¸ç¨ä¸è¡ Optional é¾ç´æ¥ parseã |
| | | // åå®ç°åæ» `SimpleDateFormat("yyyyMMddHHmmss")`ï¼æ ¼å¼ä¸ç¬¦åªä¼ **éé»ä¸¢å¼** |
| | | // ï¼catch éä»
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ï¼doctor_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); |
| | |
| | | // 设置ç³è¯·åå· |
| | | 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"ã |
| | | // ä¸é¢è§£ææ¶é´æ®µæ¶åªæ¿å°äºæ¶åï¼ç¨äº 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)); |
| | |
| | | if (value != null) { |
| | | appointment.setBookCheckType(value); |
| | | } else { |
| | | log.warn("[handleAppointmentCreate][使£æ£è
æ£æ¥é¡¹ç®åç§°æ æ³æ å°] checkName={}", checkName); |
| | | // åç§°æ å°ä¸å°å°±éåãæ HIS æ£æ¥ä»£ç æ å°ãï¼ |
| | | // 宿µè¿å¨è¯éªå¨ HIS ä¾§æ¹è¿åï¼å¹³æ¿è¿å¨å¿çµ â å¹³æ¿è¿å¨è¯éªï¼ï¼ |
| | | // åªè®¤åç§°ä¼è®© book_check_type è½ç©ºï¼èæ¥æéç codeï¼å¦ 201652ï¼æ¯ç¨³å®çã |
| | | Integer fallback = resolveBookCheckTypeFromComponent2(dataMap); |
| | | if (fallback != null) { |
| | | appointment.setBookCheckType(fallback); |
| | | log.info("[handleAppointmentCreate][使£æ£è
åç§°æªæ å°ï¼å·²ææ£æ¥ä»£ç å
åº] checkName={} bookCheckType={}", |
| | | checkName, fallback); |
| | | } else { |
| | | log.warn("[handleAppointmentCreate][使£æ£è
æ£æ¥é¡¹ç®åç§°ä¸ä»£ç åæ æ³æ å°] checkName={}", checkName); |
| | | } |
| | | } |
| | | } else { |
| | | Integer value = resolveBookCheckTypeFromComponent2(dataMap); |
| | |
| | | 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); |
| | |
| | | // 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; |
| | | } |
| | | |
| | |
| | | return o == null ? null : o.toString(); |
| | | } |
| | | |
| | | /** |
| | | * ä» S050401/S050501ï¼æ£æ¥é¢çº¦ï¼æ¥æç {@code ZDY} èç¹è§£ææ¬å° {@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 飿¡è·¯å¾è§£ææ£æ¥ç±»åï¼äºæ¯ãS050401 å
å°ãS0201ECG æªå°ãæ¶èµ° |
| | | * {@link #insertAppointmentFromCheckAppointment} 容鿰å¢ï¼ |
| | | * {@code book_check_type} ä¼**æ°¸è¿ä¸ºç©º** ââ 宿µ 2026-09-29~10-09 å
± 279 æ¡ |
| | | * ï¼å¦ {@code apply_no=8826092420371106}ï¼æ¥æé {@code jcxmcode=201652} ææåå¨ï¼ã |
| | | * |
| | | * <h3>è§£æé¡ºåº</h3> |
| | | * <ol> |
| | | * <li><b>åç§°ä¼å
</b>ï¼{@code jcxmname} â {@link HisCheckNameEnum#getByName}ã |
| | | * 该æä¸¾å·²å«ãå¹³æ¿è¿å¨è¯éªãç HIS æ¹åå«åï¼ä¸å
ç½®è§èåå¹é
ï¼</li> |
| | | * <li><b>代ç å
åº</b>ï¼{@code jcxmcode} â {@link HisCheckCodeEnum}ï¼ |
| | | * å
¼å®¹å¸¦/ä¸å¸¦ {@code Y} åç¼ã</li> |
| | | * </ol> |
| | | * |
| | | * <h3>å¤å¼å¤ç</h3> |
| | | * 宿µè¯¥å段å¯è½ä¸ºéå·åéå¤å¼ï¼å¦ S0405 ç {@code jcxmcode=1080,3016,3014}ï¼ã |
| | | * çç¥ï¼**æé¡ºåºå第ä¸ä¸ªè½æ å°æåçå¼**ï¼å
æ´ä½è¯æ¢ï¼åå¼åºæ¯ï¼ï¼åéæ®µè¯æ¢ã |
| | | * |
| | | * @param zdy æ¥æä¸ç {@code ZDY} èç¹ï¼å¯ä¸º null |
| | | * @return æ¬å°æ£æ¥ç±»åå¼ï¼å¦ 400ï¼ï¼æ æ³è§£ææ¶è¿å 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; |
| | | } |
| | | // â¡ ä»£ç æ å°ï¼å
åºï¼å®æµ HIS ä¾§æ¹è¿åï¼ä»£ç æ´ç¨³å®ï¼ |
| | | Integer byCode = mapCheckCodeToType(jcxmCode); |
| | | if (byCode != null) { |
| | | log.info("[resolveBookCheckTypeFromZdy][åç§°æªæ å°ï¼å·²ææ£æ¥ä»£ç å
åº] " |
| | | + "applyNo={} jcxmname={} jcxmcode={} bookCheckType={}", |
| | | applyNo, jcxmName, jcxmCode, byCode); |
| | | return byCode; |
| | | } |
| | | |
| | | log.warn("[resolveBookCheckTypeFromZdy][æ£æ¥é¡¹ç®åç§°ä¸ä»£ç åæ æ³æ å°ï¼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; |
| | | } |
| | | // å
¼å®¹ä¸¤ç§æ¥æå½¢æï¼å¸¦åç¼ï¼Y1202065ï¼ä¸ä¸å¸¦åç¼ï¼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} å宽ä¸é */ |
| | |
| | | |
| | | /** 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}ã |
| | |
| | | if (roomName != null && StringUtils.isNotEmpty(roomName.toString())) { |
| | | appointment.setRoomName(truncate(roomName.toString(), ROOM_NAME_MAX_LEN)); |
| | | } |
| | | // æ£æ¥ç±»åï¼**ä»
å¨ä¸ºç©ºæ¶è¡¥** |
| | | // çç¥ (a)ï¼ä¸è¦çå·²æå¼ï¼é¿å
æ¹åæ°æ®ï¼ä¾å¦è¯¥åæ¾ç± S0201ECG æ£ç¡®åå
¥è¿ç±»åï¼ã |
| | | // ä¸å®¹éæ°å¢åæ¯ä¿æåä¸é»è¾ã |
| | | if (appointment.getBookCheckType() == null) { |
| | | Integer checkTypeValue = resolveBookCheckTypeFromZdy(zdy, applyNo); |
| | | if (checkTypeValue != null) { |
| | | appointment.setBookCheckType(checkTypeValue); |
| | | } |
| | | } |
| | | } |
| | | // é¢çº¦æåºå·ï¼patient.id.item[4]ï¼ |
| | | Integer seqNum = extractBookSeqNum(actAppointment); |
| | |
| | | appointment.setBookSrc(bookSrcValue); |
| | | appointment.setStatus(status); |
| | | |
| | | // æ£è
æ¥æºï¼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 è¡ä¸ºä¸è´ï¼ |
| | | // å¦éæåç§°çº æ£ï¼ä½æ£â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ï¼æ¿é´ç¼ç ï¼ç®å仿 对åºåï¼æä¸ä¿åã |
| | |
| | | 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 |
| | | // |
| | | // ãä¿®å¤ãåå
æ¤å¤**å®å
¨æ²¡æ**è§£ææ£æ¥ç±»åï¼å¯¼è´ãS050401 å
å°ãä¸å°æ 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]ï¼ |
| | |
| | | } |
| | | 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 ç»ä¸èµå¼ï¼æ¤å¤ä¸åéå¤å¤ç |
| | | // æ£è
å§å |
| | |
| | | log.warn("[insertAppointmentFromCheckAppointment][æ¥ææªæä¾æ£è
æ§å«ï¼ææªç¥(0)åå
¥] applyNo={}", applyNo); |
| | | appointment.setPatGender(UNKNOWN_GENDER); |
| | | } |
| | | // æ£è
åºæå±æ§åå¡«ï¼çæ¥ / çµè¯ / èº«ä»½è¯ / å°åï¼ |
| | | // |
| | | // ã为ä»ä¹éè¦ãS050401 æ¥æç patient.patientPerson **åªå¸¦å§å**ï¼ |
| | | // ä¸å«çæ¥/çµè¯/身份è¯ï¼S0201ECG æãS0405 乿ï¼ä½è¿ä¸¤æ¡æ¥æå¨æ¬åºæ¯æ²¡æå
å°ï¼ï¼ |
| | | // äºæ¯å®¹éæ°å¢åºæ¥çè®°å½è¿äºå段å
¨ä¸ºç©ºï¼ä¸ S0201ECG 建çåç¸æ¯"ç¼ºåæ®µ"ã |
| | | // |
| | | // ã为ä»ä¹è¿æ ·è¡¥æ¯åç¡®çãè¿äºæ¯**æ£è
åºæå±æ§**ï¼ä¸æ¯æµæ°´å±æ§ï¼ï¼ |
| | | // åä¸ pat_id çåå²è®°å½éå¿
ç¶ä¸è´ï¼å
¨åºå¡«å
ç 99%ï¼ã |
| | | // 注æï¼å¼åå»ç/å¼åæ¶é´å±æµæ°´å±æ§ï¼**廿ä¸ç»§æ¿**ï¼é£å±äºæ¨æï¼å¯è½å¼ å ææ´ï¼ã |
| | | inheritPatientDemographics(appointment, applyNo); |
| | | |
| | | AppointmentSaveReqVO saveReqVO = BeanUtils.toBean(appointment, AppointmentSaveReqVO.class); |
| | | createAppointment(saveReqVO); |
| | | } |
| | | |
| | | /** |
| | | * 容鿰墿¶ï¼ä»è¯¥æ£è
æè¿ä¸æ¡è®°å½ç»§æ¿**æ£è
åºæå±æ§**ã |
| | | * |
| | | * <p>åªè¡¥ãæ¬æ¬¡ä¸ºç©ºãçåæ®µï¼ç»ä¸è¦çæ¥æå·²æä¾çå¼ã |
| | | * ç»§æ¿å¤±è´¥ï¼æ åå²è®°å½ / æ¥è¯¢å¼å¸¸ï¼ä¸å½±åè½åºï¼ä»
è®°æ¥å¿ã</p> |
| | | * |
| | | * <p><b>廿ä¸ç»§æ¿</b>çåæ®µï¼{@code doctor}/{@code doctor_code}/{@code doctor_time} |
| | | * ï¼å¼åå»çä¸å¼åæ¶é´å±æµæ°´å±æ§ï¼æ¥ææªæä¾æ¶åªè½æ¨æï¼å®æµåæ£è
忥ä¸è´ç 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][该æ£è
æ åå²è®°å½å¯ç»§æ¿ï¼æ£è
ä¿¡æ¯å°ä¸å®æ´] " |
| | | + "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 æ¥æä¸å«æ£è
人å£å¦ä¿¡æ¯ï¼" |
| | | + "å·²ä»åæ£è
æè¿è®°å½ç»§æ¿] applyNo={} patId={} fromApplyNo={} fields=[{}]", |
| | | applyNo, target.getPatId(), sibling.getApplyNo(), inherited.toString().trim()); |
| | | } |
| | | } |
| | | |
| | | /** è§£æ {@code yyyyMMddHHmmss} æ¶é´ï¼å¤±è´¥æä¸ºç©ºè¿å nullï¼ä¸æå¼å¸¸ï¼ */ |
| | |
| | | return LocalDateTime.parse(value.trim(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss")); |
| | | } catch (Exception e) { |
| | | log.warn("[parseDateTime][æ¶é´æ ¼å¼éæ³ï¼å¿½ç¥] value={}", value); |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * è§£æ 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} è§£æï¼</li> |
| | | * <li>è¯å«ãæ¶åç§ = 000000ãç**æ¥æå¼**ï¼æåºå¸¦**åå§æ¥æå¼ + ç³è¯·åå·**ç WARN |
| | | * ââ åå®ç°åª {@code printStackTrace()}ï¼åºé®é¢æ¶æ ä»å®ä½ï¼</li> |
| | | * <li><b>ä»ç¶åå
¥</b>ï¼ä¿çæ¥æé¨åï¼ï¼å 为ãè·ä»å¤©æ°ããææ¥ææåº/çéãé½ç¨æ¥æï¼ |
| | | * åå
¥ NULL ä¼è®©è¿äºåè½éåï¼ä¸è¯¥å¼ç¡®ä¸º HIS æåãåæ ·ä¿åæ´å¯è¿½æº¯ã</li> |
| | | * </ul> |
| | | * |
| | | * @param rawValue HIS æ¥æåå¼ï¼å½¢å¦ {@code 20260917005255}ï¼ |
| | | * @param applyNo ç³è¯·åå·ï¼ä»
ç¨äºæ¥å¿å®ä½ |
| | | * @return è§£æåçæ¶é´ï¼æ ¼å¼éæ³æ¶è¿å {@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 ä½ï¼æ æ³è§£æï¼doctor_time å°ä¸ºç©º] " |
| | | + "applyNo={} raw={} length={}", applyNo, v, v.length()); |
| | | return null; |
| | | } |
| | | try { |
| | | // â ï¸ å¿
é¡» setLenient(false)ï¼SimpleDateFormat é»è®¤å®½æ¾ï¼ |
| | | // ä¼æéæ³æ¥æé黿»æåæ³å¼ï¼å¦ 13 æ â æ¬¡å¹´ 1 æï¼ï¼å¯¼è´èæ°æ®å
¥åºã |
| | | // 宿µï¼lenient ä¸ "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}ï¼hhmmhhmmï¼å¦ 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; |
| | | } |
| | | } |
| | |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * ãæ¬éæ±ï¼ç´§æ¥æ£è
䏿éç´æ¥æ£æ¥ãæãç³è¯·åå· / å°±è¯å· / æ£è
ç¼å·ãæ¥è¿ä¸ä¸ªæçé¢çº¦è®°å½ã |
| | | * <p> |
| | | * çªå£ [ä»å¤©-30 天, ä»å¤©+30 天]ï¼ææ¬çªå£å¼å±çæ£æ¥é¡¹ç®è¿æ»¤ï¼ç»ææ**é¢çº¦æ¶é´ååº**ã |
| | | */ |
| | | @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 è§£æï¼éæ°åæç©ºè¿å nullï¼ç¨äºæ£è
æ§å«ç tinyint åæ®µï¼ */ |
| | | private Byte parseByteQuietly(String value) { |
| | | if (StringUtils.isEmpty(value) || !value.trim().matches("-?\\d+")) { |
| | |
| | | |
| | | import javax.annotation.Resource; |
| | | |
| | | import java.time.Duration; |
| | | import java.time.LocalDateTime; |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | import java.util.Optional; |
| | |
| | | */ |
| | | @Service |
| | | @Validated |
| | | @lombok.extern.slf4j.Slf4j |
| | | public class CallServiceImpl implements CallService { |
| | | |
| | | @Resource |
| | |
| | | return callMapper.selectPage(pageReqVO); |
| | | } |
| | | |
| | | /** |
| | | * éå«ï¼åçæä¸æ¡å«å·è®°å½ï¼è®©å¤§å± / è¯é´å±éæ°ææ¥ã |
| | | * |
| | | * <p>ãæ¬æ¬¡ä¿®å¤ãåå®ç°ï¼ |
| | | * <pre> |
| | | * CallDO callDO = callMapper.getLatestPatientCall(patId); |
| | | * if (null != callDO && callDO.getCalled() == 0) return 0; // â æ°¸è¿æç« |
| | | * return createCall(createReqVO); |
| | | * </pre> |
| | | * è**å
¨é¡¹ç®æ²¡æä»»ä½å°æ¹æ {@code called} 置为 1**ï¼{@code getNextCall} / |
| | | * {@code getNextInstallCall} åªæ¥ {@code called = 0}ï¼â 该å®å«æ¯æ¬¡é½å½ä¸ â |
| | | * <b>éå«ä»ä¸åå
¥æ°è®°å½</b>ï¼ä¸¤åå±ä¹å°±å®å
¨æ²¡æååºï¼ç°åºåé¦å³æ¤ï¼ã |
| | | * |
| | | * <p>ç°å¨åªå"é²è¿ç¹"ï¼å䏿£è
**3 ç§å
**çéå¤éå«å¿½ç¥ï¼å
¶ä½æ
åµä¸å¾æ£å¸¸æ°å»ºã |
| | | */ |
| | | @Override |
| | | public Integer callAgain(CallSaveReqVO createReqVO) { |
| | | CallDO callDO = callMapper.getLatestPatientCall(createReqVO.getPatId()); |
| | | if (null != callDO && callDO.getCalled() == 0) |
| | | return 0; |
| | | |
| | | CallDO latest = callMapper.getLatestPatientCall(createReqVO.getPatId()); |
| | | if (null != latest && null != latest.getCreateTime()) { |
| | | long seconds = Duration.between(latest.getCreateTime(), LocalDateTime.now()).getSeconds(); |
| | | if (seconds >= 0 && seconds < 3) { |
| | | log.info("[callAgain] 3 ç§å
éå¤éå«ï¼å¿½ç¥. patId={} 䏿¬¡={}", createReqVO.getPatId(), latest.getCreateTime()); |
| | | return 0; |
| | | } |
| | | } |
| | | return createCall(createReqVO); |
| | | } |
| | | } |
| | |
| | | package cn.lihu.jh.module.ecg.service.callingscreen; |
| | | |
| | | import cn.lihu.jh.framework.common.pojo.PageResult; |
| | | import cn.lihu.jh.module.ecg.Utils; |
| | | import cn.lihu.jh.module.ecg.controller.admin.checktype.vo.CheckTypePageReqVO; |
| | | import cn.lihu.jh.module.ecg.dal.dataobject.checktype.CheckTypeDO; |
| | | import cn.lihu.jh.module.ecg.dal.dataobject.queue.QueueDO; |
| | |
| | | }); |
| | | |
| | | mapDisplayColQueue.values().forEach( _queueDOList -> { |
| | | //æ [亲åç] æªå°ä¸»é¡¹åé¢ |
| | | //æ [亲åç] æªå°ä¸»é¡¹åé¢ï¼åæéå· + 忣è
æç®ä¸ç»ï¼è§ Utils#insertAffinityItemsAfterMainï¼ |
| | | List<QueueDO> affinityWaitingList = new ArrayList<>(); |
| | | ListIterator<QueueDO> iterator = _queueDOList.listIterator(); |
| | | while (iterator.hasNext()) { |
| | |
| | | affinityWaitingList.add(item); |
| | | } |
| | | } |
| | | affinityWaitingList.forEach( affinityWaitingItem -> { |
| | | for (int i = _queueDOList.size()-1; i >= 0; i--) { |
| | | if ( affinityWaitingItem.getSeqNum() == _queueDOList.get(i).getSeqNum() ) { |
| | | _queueDOList.add(i + 1, affinityWaitingItem); |
| | | break; |
| | | } |
| | | } |
| | | }); |
| | | Utils.insertAffinityItemsAfterMain(_queueDOList, affinityWaitingList); |
| | | }); |
| | | |
| | | return mapDisplayColQueue; |
| | |
| | | // éæ±1ï¼åå¡«æ£è
ä¿¡æ¯ï¼è¯é´å±-æ£æ¥éåï¼ |
| | | queueService.fillAppointmentInfo(queueDOList); |
| | | |
| | | //æ [亲åç] æªå°ä¸»é¡¹åé¢ |
| | | //æ [亲åç] æªå°ä¸»é¡¹åé¢ï¼åæéå· + 忣è
æç®ä¸ç»ï¼è§ Utils#insertAffinityItemsAfterMainï¼ |
| | | List<QueueDO> affinityWaitingList = new ArrayList<>(); |
| | | ListIterator<QueueDO> iterator = queueDOList.listIterator(); |
| | | while (iterator.hasNext()) { |
| | |
| | | affinityWaitingList.add(item); |
| | | } |
| | | } |
| | | affinityWaitingList.forEach( affinityWaitingItem -> { |
| | | for (int i = queueDOList.size()-1; i >= 0; i--) { |
| | | if ( affinityWaitingItem.getSeqNum() == queueDOList.get(i).getSeqNum() ) { |
| | | queueDOList.add(i + 1, affinityWaitingItem); |
| | | break; |
| | | } |
| | | } |
| | | }); |
| | | Utils.insertAffinityItemsAfterMain(queueDOList, affinityWaitingList); |
| | | |
| | | return queueDOList; |
| | | } |
| | |
| | | // éæ±1ï¼åå¡«æ£è
ä¿¡æ¯ï¼è¯é´å±-è£
æºéåï¼ |
| | | queueService.fillAppointmentInfo(queueDOList); |
| | | |
| | | //æ [亲åç] æªå°ä¸»é¡¹åé¢ |
| | | //æ [亲åç] æªå°ä¸»é¡¹åé¢ï¼åæéå· + 忣è
æç®ä¸ç»ï¼è§ Utils#insertAffinityItemsAfterMainï¼ |
| | | List<QueueDO> affinityReceivedList = new ArrayList<>(); |
| | | ListIterator<QueueDO> iterator = queueDOList.listIterator(); |
| | | while (iterator.hasNext()) { |
| | |
| | | affinityReceivedList.add(item); |
| | | } |
| | | } |
| | | affinityReceivedList.forEach( affinityReceivedItem -> { |
| | | for (int i = queueDOList.size()-1; i >= 0; i--) { |
| | | if ( affinityReceivedItem.getSeqNum() == queueDOList.get(i).getSeqNum() ) { |
| | | queueDOList.add(i + 1, affinityReceivedItem); |
| | | break; |
| | | } |
| | | } |
| | | }); |
| | | Utils.insertAffinityItemsAfterMain(queueDOList, affinityReceivedList); |
| | | |
| | | return queueDOList; |
| | | } |
| | |
| | | |
| | | String strRoomResetTime = configApi.getConfigValueByKey(ECG_ROOM_RESET_TIME_KEY); |
| | | LocalTime roomResetTime = Utils.parseTime(strRoomResetTime); |
| | | // ãæ¬éæ±Â·å
åºå åºãé
置项 ecg.room.reset.time 缺失/æ ¼å¼éæ³æ¶ parseTime è¿å nullï¼ |
| | | // åå®ç°ç´æ¥ roomResetTime.getMinute() 伿 NPEï¼è resetScheduler() å¨å¯å¨çå¬é |
| | | // **没æ try/catch** â å¼è¯/éè¯/éç½®ä¸ä¸ªå®æ¶ä»»å¡å
¨é¨æ³¨å失败ï¼çäº"æ¯æ¥éç½®"仿ªçæï¼ã |
| | | // è¿éç»é»è®¤ 23:00ï¼å¹¶ä¿è¯æ¯ä¸ªä»»å¡æ³¨å失败åªè®° ERRORãä¸å½±åå¯å¨ã |
| | | if (null == roomResetTime) { |
| | | roomResetTime = LocalTime.of(23, 0); |
| | | log.warn("[resetScheduler] é
置项 {} ç¼ºå¤±ææ ¼å¼éæ³ï¼åå¼=[{}]ï¼ï¼æ¯æ¥å·¥ä½éç½®æ¶é´åé为é»è®¤ 23:00", |
| | | ECG_ROOM_RESET_TIME_KEY, strRoomResetTime); |
| | | } |
| | | String roomResetCronExpression = String.format("0 %d %d * * ?", roomResetTime.getMinute(), roomResetTime.getHour()); |
| | | |
| | | startBizTask = taskRegistrar.scheduleCronTask(new CronTask(() -> { |
| | | System.out.println("Opening Task executed at: " + System.currentTimeMillis()); |
| | | queueService.startBiz(); |
| | | }, openCronExpression)); |
| | | try { |
| | | startBizTask = taskRegistrar.scheduleCronTask(new CronTask(() -> { |
| | | System.out.println("Opening Task executed at: " + System.currentTimeMillis()); |
| | | queueService.startBiz(); |
| | | }, openCronExpression)); |
| | | } catch (Exception e) { |
| | | log.error("[resetScheduler] 注åãå¼è¯ã宿¶ä»»å¡å¤±è´¥ï¼ä¸å½±åå
¶å®ä»»å¡ï¼. cron={}", openCronExpression, e); |
| | | } |
| | | |
| | | closeBizTask = taskRegistrar.scheduleCronTask(new CronTask(() -> { |
| | | System.out.println("Close Task executed at: " + System.currentTimeMillis()); |
| | | queueService.closeBiz(); |
| | | }, closeCronExpression)); |
| | | try { |
| | | closeBizTask = taskRegistrar.scheduleCronTask(new CronTask(() -> { |
| | | System.out.println("Close Task executed at: " + System.currentTimeMillis()); |
| | | queueService.closeBiz(); |
| | | }, closeCronExpression)); |
| | | } catch (Exception e) { |
| | | log.error("[resetScheduler] 注åãéè¯ã宿¶ä»»å¡å¤±è´¥ï¼ä¸å½±åå
¶å®ä»»å¡ï¼. cron={}", closeCronExpression, e); |
| | | } |
| | | |
| | | resetRoomTask = taskRegistrar.scheduleCronTask(new CronTask(() -> { |
| | | System.out.println("Room Reset Task executed at: " + System.currentTimeMillis()); |
| | | roomService.resetRoom(false); |
| | | //queueSequenceService.resetQueueSequence(); |
| | | queueSequenceService.initNumber(); |
| | | }, roomResetCronExpression)); |
| | | try { |
| | | resetRoomTask = taskRegistrar.scheduleCronTask(new CronTask(() -> { |
| | | System.out.println("Room Reset Task executed at: " + System.currentTimeMillis()); |
| | | roomService.resetRoom(false); |
| | | //queueSequenceService.resetQueueSequence(); |
| | | queueSequenceService.initNumber(); |
| | | }, roomResetCronExpression)); |
| | | } catch (Exception e) { |
| | | log.error("[resetScheduler] 注åãæ¯æ¥å·¥ä½éç½®ã宿¶ä»»å¡å¤±è´¥. cron={}", roomResetCronExpression, e); |
| | | } |
| | | |
| | | taskRegistrar.afterPropertiesSet(); |
| | | } |
| | |
| | | DevRentDO getDismantledRent(DevRentSearchReqVO searchReqVO); |
| | | |
| | | Integer feeConfirm(Long rentId, String hisId, String userNickname, Boolean isFeeConfirmOrCancel); |
| | | |
| | | /** |
| | | * æ¤éãæ£æ¥å®æãåçåæ»ï¼æ¬æ¬¡æ°å¢ï¼ï¼ |
| | | * æè¯¥æ£è
仿¥ãè¯¥æ£æ¥é¡¹ç®ç **60(å¸¸è§æ£æ¥å®æ) â 0(å¾
æ£æ¥)**ï¼å¹¶**åæ¶ç¡®è´¹**ã |
| | | * |
| | | * <p>为ä»ä¹å¿
é¡»åæ»ï¼æ¤éåå
åªæéåè¡ 40â20ï¼æ£æ¥å仿¯ 60ï¼ |
| | | * åç«¯åæ¬¡å®ææ¶ `getFreeRent` åä¸å°ãå¾
æ£æ¥ãåï¼rentId 为空ï¼ï¼å端便æ¥ã请å
é¢çº¦ç¡®è®¤ãã |
| | | * |
| | | * <p>å
é¨å·² try/catchï¼åæ»å¤±è´¥ä¸åºå½±å"æ¤é"æ¬èº«çç»æã |
| | | */ |
| | | void rollbackRoutineFinish(String patId, Integer checkType); |
| | | } |
| | |
| | | @Autowired |
| | | private WebServiceClient webServiceClient; |
| | | |
| | | /** ãæ¬éæ±ãç´§æ¥å åç夿³¨æ è®°ï¼ä¾¿äºå¨å®æå表/æ¥è¡¨éåºåè¿ç±»"䏿éç´æ¥æ£æ¥"çè®°å½ */ |
| | | private static final String EMERGENCY_REMARK = "ç´§æ¥å å"; |
| | | |
| | | |
| | | @Override |
| | | public CommonResult<Long> registerOperation(DevRentSaveReqVO createReqVO) { |
| | |
| | | String userNickname = SecurityFrameworkUtils.getLoginUserNickname(); |
| | | String userHisId = SecurityFrameworkUtils.getLoginUserHisId(); |
| | | |
| | | // ãæ¬éæ±ï¼ç´§æ¥æ£è
䏿éç´æ¥æ£æ¥ã |
| | | // æ£å¸¸æ£è
çãå¾
æ£æ¥(0)ãæ£æ¥åæ¯ç¾å°å»ºéåæ¶ä¸èµ·æçï¼ç´§æ¥å åçæ£è
没走ç¾å°ï¼ |
| | | // å æ¤è¿éå
æè¿æ¡åè¡¥åºæ¥ï¼åç»é»è¾ï¼åä½ä¸è®°å½ãæ´æ°éåãååéæå¹³å°ï¼å®å
¨å¤ç¨ã |
| | | if (Boolean.TRUE.equals(routineFinishReqVO.getEmergency())) { |
| | | prepareEmergencyDevRent(routineFinishReqVO, createReqVO); |
| | | } |
| | | |
| | | // å¨é¢çº¦ç¡®è®¤æ¶ å°±è¿å
¥ [dev_rent] è¡¨äº |
| | | Long rent_id = createReqVO.getId(); |
| | | |
| | |
| | | JobRecordDO jobRecordDO = jobRecordMapper.selectByRentIdDocId(rent_id, userId, jobTypeList); |
| | | if (null == jobRecordDO) { |
| | | List<DevRentDO> devRentDOList = devRentMapper.selectByPatAndChecktypeAndState(createReqVO.getPatId(), createReqVO.getCheckType(), DevRentStateEnum.FREE.getState()); |
| | | if (devRentDOList.size() == 0) throw exception(DEV_INSTALL_NOT_APPOINTMENT); |
| | | else if (devRentDOList.size() != 1) { |
| | | throw exception(DEV_INSTALL_EXCEPTION); |
| | | |
| | | // ãæ¬æ¬¡ä¿®å¤ãæ¤éå忬¡å®ææ¶çå
åºï¼ |
| | | // è¥ãå¾
æ£æ¥(0)ãçååä¸åå¨ï¼æ¤éæ¶æ²¡è½åæ»å° 0ãæå岿°æ®ï¼ï¼ |
| | | // ä¸è½åç´æ¥æ¥ã请å
é¢çº¦ç¡®è®¤ãï¼å¦åå»çæ æ³æè¯¯å®æçæ£è
鿰宿ã |
| | | // è¿éå¤ç¨**仿¥æè¿ä¸æ¡**ãå¸¸è§æ£æ¥å®æ(60)/å¸¸è§æ£æ¥æ¾å¼(50)ãçåï¼ |
| | | // ä¸å¦æè¯¥åå·²ç»æå®æè®°å½ï¼å°±èµ°ä¸é¢ç"æ´æ°"忝ï¼é¿å
é夿å
¥ job_recordã |
| | | if (devRentDOList.isEmpty()) { |
| | | List<Integer> fallbackStateList = new ArrayList<>(); |
| | | fallbackStateList.add(DevRentStateEnum.ROUTINE_FINISH.getState()); |
| | | fallbackStateList.add(DevRentStateEnum.ROUTINE_CANCELLED.getState()); |
| | | DevRentDO fallbackRent = devRentMapper.selectLatestByPatCheckTypeStates( |
| | | createReqVO.getPatId(), createReqVO.getCheckType(), fallbackStateList); |
| | | if (null == fallbackRent) { |
| | | throw exception(DEV_INSTALL_NOT_APPOINTMENT); |
| | | } |
| | | log.warn("[routineFinishOperation] ãå¾
æ£æ¥ãåä¸åå¨ï¼å
åºå¤ç¨æè¿ä¸æ¡å·²å®æ/å·²æ¾å¼å. " |
| | | + "rentId={} patId={} checkType={}", |
| | | fallbackRent.getId(), createReqVO.getPatId(), createReqVO.getCheckType()); |
| | | devRentDOList = new ArrayList<>(List.of(fallbackRent)); |
| | | jobRecordDO = jobRecordMapper.selectByRentIdDocId(fallbackRent.getId(), userId, jobTypeList); |
| | | if (null != jobRecordDO) { |
| | | rent_id = fallbackRent.getId(); |
| | | createReqVO.setId(rent_id); |
| | | } |
| | | } |
| | | |
| | | rent_id = devRentDOList.get(0).getId(); |
| | | createReqVO.setId(rent_id); |
| | | createReqVO.setState(DevRentStateEnum.ROUTINE_FINISH.getState()); |
| | | updateDevRent(createReqVO); |
| | | if (null != jobRecordDO) { |
| | | // å
åºå½ä¸å·²æå®æè®°å½ â è½å°ä¸æ¹"æ´æ°"忝ï¼ä¸ else åæ¯åæ ·çå¤çï¼ |
| | | } else { |
| | | if (devRentDOList.size() != 1) { |
| | | throw exception(DEV_INSTALL_EXCEPTION); |
| | | } |
| | | |
| | | JobRecordSaveReqVO jobRecordSaveReqVO = new JobRecordSaveReqVO(); |
| | | jobRecordSaveReqVO.setRentId(rent_id); |
| | | jobRecordSaveReqVO.setDevId(createReqVO.getDevId()); |
| | | jobRecordSaveReqVO.setDocId(userId); |
| | | jobRecordSaveReqVO.setDocName(userNickname); |
| | | jobRecordSaveReqVO.setPatId(createReqVO.getPatId()); |
| | | jobRecordSaveReqVO.setPatName(createReqVO.getPatName()); |
| | | jobRecordSaveReqVO.setJobTime(createReqVO.getRentTime()); |
| | | jobRecordSaveReqVO.setJobType(DevRentStateEnum.ROUTINE_FINISH.getState()); |
| | | jobRecordSaveReqVO.setRemark(createReqVO.getRemark()); |
| | | jobRecordSaveReqVO.setSummary(""); |
| | | jobRecordSaveReqVO.setCheckType(createReqVO.getCheckType()); |
| | | rent_id = devRentDOList.get(0).getId(); |
| | | createReqVO.setId(rent_id); |
| | | createReqVO.setState(DevRentStateEnum.ROUTINE_FINISH.getState()); |
| | | updateDevRent(createReqVO); |
| | | |
| | | JobRecordDO jobRecord = BeanUtils.toBean(jobRecordSaveReqVO, JobRecordDO.class); |
| | | jobRecordMapper.insert(jobRecord); |
| | | } else { |
| | | JobRecordSaveReqVO jobRecordSaveReqVO = new JobRecordSaveReqVO(); |
| | | jobRecordSaveReqVO.setRentId(rent_id); |
| | | jobRecordSaveReqVO.setDevId(createReqVO.getDevId()); |
| | | jobRecordSaveReqVO.setDocId(userId); |
| | | jobRecordSaveReqVO.setDocName(userNickname); |
| | | jobRecordSaveReqVO.setPatId(createReqVO.getPatId()); |
| | | jobRecordSaveReqVO.setPatName(createReqVO.getPatName()); |
| | | jobRecordSaveReqVO.setJobTime(createReqVO.getRentTime()); |
| | | jobRecordSaveReqVO.setJobType(DevRentStateEnum.ROUTINE_FINISH.getState()); |
| | | jobRecordSaveReqVO.setRemark(createReqVO.getRemark()); |
| | | jobRecordSaveReqVO.setSummary(""); |
| | | jobRecordSaveReqVO.setCheckType(createReqVO.getCheckType()); |
| | | |
| | | JobRecordDO jobRecord = BeanUtils.toBean(jobRecordSaveReqVO, JobRecordDO.class); |
| | | jobRecordMapper.insert(jobRecord); |
| | | } |
| | | } |
| | | if (null != jobRecordDO) { |
| | | // æ¤é æ¾å¼æä½ |
| | | createReqVO.setId(rent_id); |
| | | createReqVO.setState(DevRentStateEnum.ROUTINE_FINISH.getState()); |
| | | |
| | | updateDevRent(createReqVO); |
| | |
| | | } |
| | | |
| | | return CommonResult.success(rent_id); |
| | | } |
| | | |
| | | /** |
| | | * ãæ¬éæ±ï¼ç´§æ¥æ£è
䏿éç´æ¥æ£æ¥ã为ãç´§æ¥å åãçæ£è
åå¤ãå¾
æ£æ¥(0)ãæ£æ¥åã |
| | | * |
| | | * <h3>为ä»ä¹éè¦å®</h3> |
| | | * æ£å¸¸æ£è
ç {@code dev_rent(state=0)} è¡æ¯**ç¾å°å»ºéå**æ¶ä¸èµ·æå
¥çï¼è§ |
| | | * {@code QueueServiceImpl#queue}ï¼ãç´§æ¥å åçæ£è
ä¸èµ°ç¾å°/æéï¼æä»¥å®ææ¶æ¾ä¸å°è¿è¡ï¼ |
| | | * åé»è¾ä¼ç´æ¥æ {@code DEV_INSTALL_NOT_APPOINTMENT}ï¼"请å
é¢çº¦ç¡®è®¤"ï¼ã |
| | | * |
| | | * <h3>åæ³</h3> |
| | | * <ol> |
| | | * <li>ä»å¤©å·²æè¯¥æ£è
+ æ£æ¥é¡¹ç®çãå¾
æ£æ¥ãè¡ â ä»ä¹é½ä¸åï¼èµ°æ£å¸¸æµç¨ï¼ï¼</li> |
| | | * <li>å¦åæ**é¢çº¦å**ï¼ç³è¯·åå·ä¼å
ï¼å
¶æ¬¡æ£è
ç¼å· + æ£æ¥é¡¹ç®ï¼è¿ ±30 天ï¼è¡¥å»ºä¸è¡ï¼</li> |
| | | * <li>åæ¶æå¤æ³¨è¡¥ä¸ãç´§æ¥å åãï¼ä¾¿äºå¨å®æå表/æ¥è¡¨éåºåã</li> |
| | | * </ol> |
| | | * é¢çº¦åä¸åå¨ææ£æ¥é¡¹ç®ä¸å¹é
æ¶**ä¸è¡¥å»º**ï¼è®©åé»è¾ç
§å¸¸æ¥éï¼é¿å
产çèæ°æ®ã |
| | | */ |
| | | private void prepareEmergencyDevRent(RoutineFinishReqVO req, DevRentSaveReqVO createReqVO) { |
| | | // 夿³¨ç»ä¸ææ ï¼å夿³¨ä¿çï¼ |
| | | String remark = createReqVO.getRemark(); |
| | | if (org.springframework.util.StringUtils.hasText(remark)) { |
| | | if (!remark.contains(EMERGENCY_REMARK)) { |
| | | createReqVO.setRemark(EMERGENCY_REMARK + "ï¼" + remark); |
| | | } |
| | | } else { |
| | | createReqVO.setRemark(EMERGENCY_REMARK); |
| | | } |
| | | |
| | | if (org.springframework.util.StringUtils.hasText(req.getPatId()) && null != req.getCheckType()) { |
| | | List<DevRentDO> existList = devRentMapper.selectByPatAndChecktypeAndState( |
| | | req.getPatId(), req.getCheckType(), DevRentStateEnum.FREE.getState()); |
| | | if (!existList.isEmpty()) { |
| | | log.info("[prepareEmergencyDevRent] 仿¥å·²æå¾
æ£æ¥åï¼ææ£å¸¸æµç¨å®æ. patId={} checkType={} æ¡æ°={}", |
| | | req.getPatId(), req.getCheckType(), existList.size()); |
| | | return; |
| | | } |
| | | } |
| | | |
| | | AppointmentDO appointment = findEmergencyAppointment(req); |
| | | if (null == appointment) { |
| | | log.warn("[prepareEmergencyDevRent] æªæ¾å°å¯ç¨çé¢çº¦åï¼è·³è¿è¡¥å»ºï¼åé»è¾å°æ¥ã请å
é¢çº¦ç¡®è®¤ãï¼. " |
| | | + "applyNo={} patId={} checkType={}", req.getApplyNo(), req.getPatId(), req.getCheckType()); |
| | | return; |
| | | } |
| | | |
| | | DevRentDO devRent = new DevRentDO(); |
| | | devRent.setApplyNo(nonBlank(appointment.getApplyNo(), req.getApplyNo())); |
| | | devRent.setEpisodeId(nonBlank(appointment.getEpisodeId(), req.getEpisodeId())); |
| | | devRent.setPatId(nonBlank(appointment.getPatId(), req.getPatId())); |
| | | devRent.setPatName(nonBlank(appointment.getPatName(), req.getPatName())); |
| | | devRent.setCheckType(appointment.getBookCheckType()); |
| | | devRent.setPaid(appointment.getPaid()); |
| | | devRent.setState(DevRentStateEnum.FREE.getState()); |
| | | devRent.setRemark(createReqVO.getRemark()); |
| | | devRentMapper.insert(devRent); |
| | | |
| | | // 让åç»ãææ£è
+ æ£æ¥é¡¹ç® + 仿¥ + å¾
æ£æ¥ãè½æ£å¸¸å®ä½å° |
| | | createReqVO.setId(devRent.getId()); |
| | | createReqVO.setApplyNo(devRent.getApplyNo()); |
| | | createReqVO.setEpisodeId(devRent.getEpisodeId()); |
| | | // æ£æ¥é¡¹ç®ä»¥é¢çº¦å为åï¼é¢çº¦åæ²¡åæ¶ææ²¿ç¨è¯·æ±éçå¼ï¼é¿å
æ checkType 置空导è´åç»æ¥éï¼ |
| | | if (null != devRent.getCheckType()) { |
| | | createReqVO.setCheckType(devRent.getCheckType()); |
| | | } |
| | | if (null == createReqVO.getPaid()) { |
| | | createReqVO.setPaid(devRent.getPaid()); |
| | | } |
| | | log.info("[prepareEmergencyDevRent] ç´§æ¥å åï¼å·²è¡¥å»ºãå¾
æ£æ¥ãæ£æ¥å. rentId={} patId={} checkType={} applyNo={}", |
| | | devRent.getId(), devRent.getPatId(), devRent.getCheckType(), devRent.getApplyNo()); |
| | | } |
| | | |
| | | /** ç´§æ¥å åï¼å®ä½è¦ç¨åªå¼ é¢çº¦åï¼ç³è¯·åå·ä¼å
ï¼å
¶æ¬¡æ£è
ç¼å· + æ£æ¥é¡¹ç®ï¼è¿ ±30 天ï¼åæè¿çï¼ */ |
| | | private AppointmentDO findEmergencyAppointment(RoutineFinishReqVO req) { |
| | | // â ç³è¯·åå·è½ç´æ¥å½ä¸ |
| | | if (org.springframework.util.StringUtils.hasText(req.getApplyNo())) { |
| | | AppointmentDO byApplyNo = appointmentMapper.getByApplyNo(req.getApplyNo()); |
| | | if (null != byApplyNo && matchesCheckType(byApplyNo, req.getCheckType())) { |
| | | return byApplyNo; |
| | | } |
| | | } |
| | | // â¡ ææ£è
ç¼å· + æ£æ¥é¡¹ç®ï¼åæè¿ä¸å¼ |
| | | if (org.springframework.util.StringUtils.hasText(req.getPatId()) && null != req.getCheckType()) { |
| | | List<Integer> one = new ArrayList<>(); |
| | | one.add(req.getCheckType()); |
| | | List<AppointmentDO> candidates = appointmentMapper.getEmergencyCandidates(req.getPatId(), one); |
| | | if (!candidates.isEmpty()) { |
| | | return candidates.get(0); |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | private boolean matchesCheckType(AppointmentDO appointment, Integer checkType) { |
| | | return null == checkType || null == appointment.getBookCheckType() |
| | | || checkType.equals(appointment.getBookCheckType()); |
| | | } |
| | | |
| | | private String nonBlank(String first, String second) { |
| | | return org.springframework.util.StringUtils.hasText(first) ? first : second; |
| | | } |
| | | |
| | | /** |
| | |
| | | return devRentDO; |
| | | } |
| | | |
| | | /** |
| | | * æ¤éãæ£æ¥å®æãåçåæ»ï¼æ£æ¥å 60(å¸¸è§æ£æ¥å®æ) â 0(å¾
æ£æ¥)ï¼å¹¶åæ¶ç¡®è´¹ã |
| | | * |
| | | * <p>ãæ¬æ¬¡ä¿®å¤çæ ¹å ãæ¤éåå
åªæéåè¡ 40â20ï¼`dev_rent` 仿¯ 60ï¼ |
| | | * åç«¯åæ¬¡å®ææ¶ `getFreeRent`ï¼åªæ¥ state=0ï¼åä¸å°å â `formData.id` 为空 |
| | | * â å端 `routineFinishOperation` æ (patId, checkType, state=0) 乿¾ä¸å° â æ¥ã请å
é¢çº¦ç¡®è®¤ãã |
| | | * æç¶æåæ»å° 0 åï¼æ´æ¡é¾è·¯æ¢å¤æ£å¸¸ã |
| | | * |
| | | * <p>失败çç¥ï¼å
¨ç¨ try/catchï¼åæ»/åæ¶è´¹å¤±è´¥é½åªè®°æ¥å¿ï¼**ä¸å½±å"æ¤é"æ¬èº«çç»æ**ã |
| | | */ |
| | | @Override |
| | | public DevRentDO getFreeRent(DevRentSearchReqVO searchReqVO) { |
| | | List<Integer> stateList = new ArrayList<>(); |
| | | public void rollbackRoutineFinish(String patId, Integer checkType) { |
| | | try { |
| | | List<Integer> finishedStateList = new ArrayList<>(); |
| | | finishedStateList.add(DevRentStateEnum.ROUTINE_FINISH.getState()); |
| | | DevRentDO rent = devRentMapper.selectLatestByPatCheckTypeStates(patId, checkType, finishedStateList); |
| | | if (null == rent) { |
| | | log.warn("[rollbackRoutineFinish] æªæ¾å°ä»æ¥è¯¥æ£è
çãå¸¸è§æ£æ¥å®æãæ£æ¥åï¼è·³è¿åæ». patId={} checkType={}", |
| | | patId, checkType); |
| | | return; |
| | | } |
| | | |
| | | // â ç¶æåæ»ï¼åªæ¹ stateï¼rent_time/return_time ä¿çï¼ä½ä¸º"åè¿ä¸æ¬¡"ççè¿¹ï¼ |
| | | DevRentDO updateObj = new DevRentDO(); |
| | | updateObj.setId(rent.getId()); |
| | | updateObj.setState(DevRentStateEnum.FREE.getState()); |
| | | devRentMapper.updateById(updateObj); |
| | | log.info("[rollbackRoutineFinish] æ£æ¥åå·²åæ»ä¸º[å¾
æ£æ¥]. rentId={} patId={} checkType={}", |
| | | rent.getId(), patId, checkType); |
| | | |
| | | // â¡ åæ¶ç¡®è´¹ï¼ç¬¬ä¸æ¬¡å®ææ¶æ§å¶å¨ä¼èªå¨ç¡®è´¹ï¼æ¤éååºåéï¼åæ¬¡å®ææ¶éæ°ç¡®è´¹ï¼ |
| | | Integer paid = rent.getPaid(); |
| | | if (null != paid && 1 == paid) { |
| | | try { |
| | | String hisId = SecurityFrameworkUtils.getLoginUserHisId(); |
| | | String nickname = SecurityFrameworkUtils.getLoginUserNickname(); |
| | | Integer ret = feeConfirm(rent.getId(), hisId, nickname, false); |
| | | log.info("[rollbackRoutineFinish] å·²åæ¶ç¡®è´¹. rentId={} è¿å={}", rent.getId(), ret); |
| | | } catch (Exception e) { |
| | | log.error("[rollbackRoutineFinish] åæ¶ç¡®è´¹å¤±è´¥ï¼ä¸å½±åæ¤éï¼. rentId={}", rent.getId(), e); |
| | | } |
| | | } |
| | | } catch (Exception e) { |
| | | log.error("[rollbackRoutineFinish] åæ»æ£æ¥å失败ï¼ä¸å½±åæ¤éï¼. patId={} checkType={}", patId, checkType, e); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public DevRentDO getFreeRent(DevRentSearchReqVO searchReqVO) { List<Integer> stateList = new ArrayList<>(); |
| | | stateList.add(DevRentStateEnum.FREE.getState()); |
| | | searchReqVO.setStateList(stateList); |
| | | DevRentDO devRentDO = devRentMapper.getRentByState(searchReqVO); |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.lihu.jh.module.ecg.service.his; |
| | | |
| | | import cn.lihu.jh.module.ecg.enums.HisCheckCodeEnum; |
| | | import cn.lihu.jh.module.ecg.enums.HisCheckNameEnum; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.stereotype.Component; |
| | | import org.springframework.util.StringUtils; |
| | | |
| | | import java.util.Arrays; |
| | | import java.util.List; |
| | | import java.util.Optional; |
| | | |
| | | /** |
| | | * å¤å®ä¸æ¡ HIS æ¥ææ¯å¦ä¸ºãå¿çµä¸å¡åãã |
| | | * |
| | | * <h3>为ä»ä¹éè¦å®</h3> |
| | | * {@code S0405}ï¼ç³è¯·åç¶ææ´æ°ï¼æ¯**å
¨é¢éç¨**æå¡ï¼æ¥å£ææ¡£å®ä¹ä¸º |
| | | * {@code S0405|S0405HIS|S040501HIS}ï¼ä¸åºåç§å®¤ãå»é¢ä¼æ**æææ£æ¥ç§å®¤** |
| | | * ï¼CTãMRIãDRãè¶
声ã骨å¯åº¦â¦ï¼çæ£æ¥ç¶æä¸å¹¶æ¨éç»å¿çµç³»ç»ã |
| | | * |
| | | * <p>宿µ 2026-09-17 æ¥å¿ï¼S0405 å
± 1225 次ï¼å
¶ä¸ä»
3.5% çç³è¯·åå·è½å¨ |
| | | * å¿çµåºä¸æ¾å°ãå
¶ä½ä¸ºæ¾å°/è¶
声çç§å®¤çåï¼ä¾å¦ï¼ |
| | | * <pre> |
| | | * æ£æ¥é¡¹ç®ï¼è¸é¨CTå¹³æ«ãå èCTAãé¢
èMRIå¹³æ«ã彩è¶
èèè°è¾ã骨å¯åº¦â¦ |
| | | * è¯å®¤ ï¼10å·æºæ¿(CT)ãæ¥è¯CT室ã15å·æºæ¿(MRI)ã产ç§è¶
声1ãæ¥è¯Bè¶
⦠|
| | | * </pre> |
| | | * è¥ä¸è¿æ»¤ï¼ä¼å¯¹è¿äºåæ§è¡"æ¥ä¸å° â æå
¥æ°è®°å½"ï¼å appointment 表çå
¥ |
| | | * å¤§éæ å
³æ°æ®ï¼å®æµåæ¥é¾åæ¡ï¼ã |
| | | * |
| | | * <h3>å¤å®æ¹å¼ï¼ä¸éï¼ä»»ä¸å½ä¸å³ä¸ºå¿çµåï¼</h3> |
| | | * <ol> |
| | | * <li><b>A. ç³è¯·åå·åç¼</b>ï¼å¿çµåç± {@code S0201ECG} å建ï¼ç¼å·å¸¦åºå®åç¼ |
| | | * {@value #ECG_APPLY_NO_SUFFIX_1101} / {@value #ECG_APPLY_NO_SUFFIX_6401} |
| | | * ï¼å®æµæ ·ä¾ {@code 8826091720001101}ã{@code 8826081120716401}ï¼ã |
| | | * 䏿¾å°ç§ç纯æ°åæµæ°´å·ï¼å¦ {@code 2126091700001}ï¼å½¢æææ¾ä¸åã</li> |
| | | * <li><b>B. æ£æ¥ç±»å</b>ï¼HIS æ£æ¥ä»£ç ï¼{@code jcxmcode} / æ¥æç |
| | | * {@code component2...code.code}ï¼è½å¹é
{@link HisCheckCodeEnum}ï¼ |
| | | * ææ£æ¥åç§°è½å¹é
{@link HisCheckNameEnum}ï¼ä½æ£æ£è
æåç§°å¹é
ï¼ã</li> |
| | | * <li><b>C. æ§è¡ç§å®¤</b>ï¼HIS æ§è¡ç§å®¤ä»£ç å¨é
ç½®ç½ååå
ã |
| | | * 该ç½å忥èªé
置项 {@code ecg.his.ecg-dept-codes}ï¼éå·åéï¼ã |
| | | * <b>æªé
ç½®æ¶æ¬é¡¹ä¸åä¸å¤å®</b>ï¼é¿å
误å¤ã</li> |
| | | * </ol> |
| | | * |
| | | * <h3>ä¿å®çç¥</h3> |
| | | * å½ä¸é¡¹åæ æ³å¤å®æ¶ï¼è¿å {@code false}ï¼è§ä¸ºéå¿çµåï¼å¹¶è®°å½ä¸æ¡ DEBUG æ¥å¿ã |
| | | * è¿æ¯å»æçä¿å®éæ©ï¼å®å¯æ¼æ¶ï¼ææ¥å¿å¯æ¥ãå¯è¡¥ï¼ï¼ä¹ä¸åä¸å¡è¡¨çå
¥æ å
³æ°æ®ã |
| | | * |
| | | * @author å¿çµæéè£
æºç³»ç» |
| | | */ |
| | | @Slf4j |
| | | @Component |
| | | public class HisEcgFilter { |
| | | |
| | | /** å¿çµç³è¯·åå·åç¼ä¹ä¸ï¼å¯¹åº check_type=1100 常è§å¿çµå¾-å¿çµåéå¾ ç³»åï¼ */ |
| | | public static final String ECG_APPLY_NO_SUFFIX_1101 = "1101"; |
| | | /** å¿çµç³è¯·åå·åç¼ä¹äºï¼å¯¹åº check_type=500 å¨èç¡¬åæ£æµ ç³»åï¼ */ |
| | | public static final String ECG_APPLY_NO_SUFFIX_6401 = "6401"; |
| | | |
| | | /** å¿çµç³è¯·åå·åç¼ç½åå */ |
| | | private static final List<String> ECG_APPLY_NO_SUFFIXES = Arrays.asList( |
| | | ECG_APPLY_NO_SUFFIX_1101, ECG_APPLY_NO_SUFFIX_6401); |
| | | |
| | | /** |
| | | * å¿çµæ£æ¥é¡¹ç®åç§°å
³é®åï¼**è¾
å©ä¿¡å·ï¼ä¸æ¯å¯ä¸ä¾æ®**ï¼ã |
| | | * <p> |
| | | * <b>â ï¸ éè¦æ´æ£</b>ï¼æ©æçæ¬æ³¨éæ¾å£°ç§°"æ¬é¢å
¨é¨ 15 个å¿çµé¡¹ç®åç§°åå«ãå¿çµã"ï¼ |
| | | * è¿æ¯**é误ç**ãæ ¸å¯¹ {@code check_type} è¡¨åæ **4 个å¿çµç±»åä¸å«"å¿çµ"**ï¼ |
| | | * <pre> |
| | | * 300 卿è¡å åºä¸ 9083 æ¡ |
| | | * 500 å¨èç¡¬åæ£æµ åºä¸ 11205 æ¡ |
| | | * 600 é£éçµçç åºä¸ 60 æ¡ |
| | | * 900 å¿å®¤æçµä½ åºä¸ 0 æ¡ |
| | | * </pre> |
| | | * å æ¤**ç»ä¸è½**ç¨"å«å¿çµ"ä½ä¸ºå¯ä¸å¤å®ä¾æ®ï¼å¦åè¿ 2 ä¸å¤æ¡çå®å¿çµè®°å½ä¼è¢«ä¸¢å¼ã |
| | | * <p> |
| | | * æ¬å
³é®åä»
ä½ä¸º**ç½ååä¹å¤çè¡¥å
**ï¼{@link #ECG_NAME_WHITELIST} æªæ¶å½ç |
| | | * é¿å°¾åç§°åä½ï¼å¦"åäºå¯¼èå¿çµæ£æ¥"ï¼ãçæ£çæå¨ä¾æ®æ¯ï¼ |
| | | * â æ£æ¥ä»£ç ï¼{@link HisCheckCodeEnum}ï¼ãâ¡ åç§°ç½ååã⢠éå¿çµæé¤è¯ã |
| | | */ |
| | | private static final String ECG_NAME_KEYWORD = "å¿çµ"; |
| | | |
| | | /** |
| | | * å¿çµæ£æ¥é¡¹ç®åç§°ç½ååã |
| | | * <p> |
| | | * ä¸¤ä¸ªæ¥æºåå¹¶ï¼ |
| | | * <ol> |
| | | * <li>{@code check_type} 表ç 15 个æå¨åç§°ï¼</li> |
| | | * <li>{@code HisCheckNameEnum} ä¸ HIS å®é
使ç¨çåç§°åä½ï¼å¦"24å°æ¶å¨æå¿çµå¾"ã |
| | | * "24å°æ¶å¨æå¿çµçæµ"ã"24å°æ¶å¨æè¡åçæµ"ï¼ã</li> |
| | | * </ol> |
| | | * ç¨**å»ç©ºç½åç宿´å称精确å¹é
**ï¼é¿å
"å«å¿çµ"è¿ç±»ä¸ä¸¥è°¨ç模ç³å¤æã |
| | | * <p> |
| | | * 注æï¼300/500/600/900 è¿åç±»åç§°æ¬èº«ä¸å«"å¿çµ"ï¼é æ¬ç½åå䏿£æ¥ä»£ç å
±åå
ä½ã |
| | | */ |
| | | private static final List<String> ECG_NAME_WHITELIST = Arrays.asList( |
| | | // ââ check_type 表 15 个æå¨åç§°ï¼åç¼å¹é
ï¼å¯è¦ç带ååç¼çåä½ï¼ââ |
| | | "常è§å¿çµå¾", |
| | | "卿å¿çµ", |
| | | "卿è¡å", |
| | | "å¹³æ¿è¿å¨å¿çµ", |
| | | "å¨èç¡¬åæ£æµ", |
| | | "é£éçµçç", |
| | | "å¿çµå¾è¯ç©è´è·è¯éª", |
| | | "é¢è°±å¿çµå¾", |
| | | "å¿å®¤æçµä½", |
| | | "åºè¾¹å¿çµå¾(常è§+é¢è°±)", |
| | | "常è§å¿çµå¾-å¿çµåéå¾", |
| | | "卿å¿çµå¾+è¡å", |
| | | "(GCP)å¿çµå¾", |
| | | "常è§å¿çµå¾18导-å¿çµåéå¾", |
| | | "åºè¾¹å¿çµå¾18导ï¼å¸¸è§+é¢è°±ï¼", |
| | | // ââ HIS å®é
使ç¨çåç§°åä½ï¼æ¥èª HisCheckNameEnum ä¸ç产æ¥å¿ï¼ââ |
| | | "24å°æ¶å¨æå¿çµå¾", |
| | | "24å°æ¶å¨æå¿çµçæµ", |
| | | "24å°æ¶å¨æè¡åçæµ", |
| | | "å¿çµå¾è¿å¨è¯éª", // 宿µ S050401 åºç°ï¼å¯¹åº check_type=400 |
| | | "è¿å¨å¿çµå¾", |
| | | "è¿å¨è¯éª", // å¿çµå¾è¿å¨è¯éªççåï¼ç¨æ·æåºï¼ |
| | | "å¹³æ¿è¿å¨", // è¦ç"å¹³æ¿è¿å¨è¯éª"/"å¹³æ¿è¿å¨å¿çµå¾"çåä½ |
| | | "æ´»å¨å¹³æ¿è¯éª", |
| | | "å¿çµåéå¾", |
| | | "åºè¾¹å¿çµå¾", |
| | | "é¢è°±å¿çµ", |
| | | "é£éè°æ", |
| | | "ç»é£éå¿æ¿è°æ", |
| | | "å¨è硬å", // check_type=500 ççåï¼è¡¨å
为"å¨èç¡¬åæ£æµ"ï¼ |
| | | "è¸èææ°", |
| | | "ABI" |
| | | ); |
| | | |
| | | /** |
| | | * æç¡®ç**éå¿çµ**æé¤è¯ã |
| | | * <p> |
| | | * ç¨äºå¨"åç§°æ¢ä¸å¨ç½ååãä¹ä¸å«å¿çµå
³é®å"æ¶ï¼å¿«éå¤å®ä¸ºå
¶ä»ç§å®¤æ£æ¥ã |
| | | * è¿äºè¯æ¥èªå®æµç产æ¥å¿ä¸å¤§éåºç°çå½±å/è¶
声/å
é/åè½æ£æ¥é¡¹ç® |
| | | * ï¼å¦"彩è¶
èèè°è¾"ã"è¸é¨CTå¹³æ«"ã"æ çèé"ã"骨å¯åº¦"ï¼ã |
| | | * <p> |
| | | * <b>廿ä¿å®</b>ï¼åªæ¶å½ä¸å¿çµç»æ 交éç强ç¹å¾è¯ï¼é¿å
误伤ãä¾å¦ |
| | | * "彩è¶
èå¿å¿è"å«"å¿è"ä½å±è¶
声ç§ï¼ç¨"彩è¶
"æé¤ï¼è䏿¶å½å¤ç«ç"å¿è"ï¼ |
| | | * 以å
误伤å¯è½çå¿çµé¡¹ç®ã |
| | | */ |
| | | private static final List<String> NON_ECG_EXCLUDE_KEYWORDS = Arrays.asList( |
| | | // è¶
声类 |
| | | "彩è¶
", "Bè¶
", "è¶
声", "夿®åè¶
声", |
| | | // æ¾å°å½±åç±» |
| | | "CT", "MRI", "MRå¹³æ«", "DR", "CR", "X线", "æç", "æ£ä¾§ä½", "æ£æä½", "æ£ä½", "ä¾§ä½", |
| | | "å¹³æ«", "å¢å¼º", "CTA", "MRA", "DWI", "ä¸ç»´é建", "é建", "é å½±", "é¼é¶", |
| | | "æºæ¿", "æ¾å°", "æ ¸ç£", "ç£å
±æ¯", |
| | | // å
éç±» |
| | | "èé", "è é", "æ¯æ°ç®¡é", "åé", "é¼»å½é", "å
é", "å
窥é", |
| | | // å
¶ä»åè½æ£æ¥ï¼éå¿çµï¼ |
| | | "èºåè½", "èºéæ°", "èºå¼¥æ£", "骨å¯åº¦", "èçµå¾", "èçµå¾", "èè¡æµ", |
| | | "弿°", "æ¿åè¯éª", "èå¼ è¯éª", "å¼¹æ§æµå®", "å¼¹æ§æå", "é表", |
| | | "骨é¾", "KUB", "æç²ªé å½±", |
| | | // ç
ç/æ£éªç±» |
| | | "æ´»æ£", "ç©¿åº", "ç
ç", "æ æ¬" |
| | | ); |
| | | |
| | | /** |
| | | * HIS æ§è¡ç§å®¤ä»£ç ç½ååï¼é
置项 {@code ecg.his.ecg-dept-codes}ï¼éå·åéï¼ã |
| | | * <p> |
| | | * 说æï¼å®æµåºä¸æ¥ä¸å° HIS æ§è¡ç§å®¤ä»£ç ï¼å¦ {@code YJ001}ï¼ä¸æ¬å°ç§å®¤çæ å°è¡¨ï¼ |
| | | * å æ¤è¿éåæå¯é
ç½®é¡¹ãæªé
ç½®æ¶ã便® Cãä¸åä¸å¤å®ï¼ä¸å½±å A/B çè¿æ»¤ææã |
| | | * å¾
颿¹æä¾å¿çµæ§è¡ç§å®¤ä»£ç åï¼å¨ infra_config å¢å 该é
ç½®å³å¯çæã |
| | | */ |
| | | private volatile List<String> ecgDeptCodes = java.util.Collections.emptyList(); |
| | | |
| | | /** ä¾å¤é¨ï¼é
ç½®å·æ°ï¼æ³¨å
¥ç§å®¤ç½åå */ |
| | | public void setEcgDeptCodes(List<String> codes) { |
| | | this.ecgDeptCodes = codes == null ? java.util.Collections.emptyList() : codes; |
| | | } |
| | | |
| | | /** |
| | | * å¤å®ç»æï¼æ¯å¦ä¸ºå¿çµä¸å¡åï¼ä»¥åå½ä¸ç便®ï¼ä¾¿äºææ¥ï¼ã |
| | | */ |
| | | public static class Result { |
| | | private final boolean ecg; |
| | | private final String reason; |
| | | |
| | | Result(boolean ecg, String reason) { |
| | | this.ecg = ecg; |
| | | this.reason = reason; |
| | | } |
| | | |
| | | public boolean isEcg() { |
| | | return ecg; |
| | | } |
| | | |
| | | public String getReason() { |
| | | return reason; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 综åå¤å®ï¼ä¸éï¼ã |
| | | * |
| | | * @param applyNo ç³è¯·åå·ï¼å¯ä¸ºç©º |
| | | * @param hisCheckCode HIS æ£æ¥é¡¹ç®ä»£ç ï¼å¦ {@code Y1202065}ï¼ï¼å¯ä¸ºç©º |
| | | * @param hisCheckName HIS æ£æ¥é¡¹ç®åç§°ï¼å¦ {@code åºè¾¹å¿çµå¾(常è§+é¢è°±)}ï¼ï¼å¯ä¸ºç©º |
| | | * @param hisDeptCode HIS æ§è¡ç§å®¤ä»£ç ï¼å¯ä¸ºç©º |
| | | * @return å¤å®ç»æ |
| | | */ |
| | | public Result judge(String applyNo, String hisCheckCode, String hisCheckName, String hisDeptCode) { |
| | | // 便® Aï¼ç³è¯·åå·åç¼ |
| | | if (matchApplyNoSuffix(applyNo)) { |
| | | return new Result(true, "A:ç³è¯·åå·åç¼"); |
| | | } |
| | | // 便® Bï¼æ£æ¥ç±»åï¼ä»£ç ä¼å
ï¼å
¶æ¬¡åç§°ï¼ |
| | | if (matchCheckCode(hisCheckCode)) { |
| | | return new Result(true, "B:æ£æ¥é¡¹ç®ä»£ç =" + hisCheckCode); |
| | | } |
| | | if (matchCheckName(hisCheckName)) { |
| | | return new Result(true, "B:æ£æ¥é¡¹ç®åç§°=" + hisCheckName); |
| | | } |
| | | // 便® Cï¼æ§è¡ç§å®¤ï¼éé
ç½®ç½ååï¼æªé
ç½®æ¶ä¸åä¸ï¼ |
| | | if (matchDeptCode(hisDeptCode)) { |
| | | return new Result(true, "C:æ§è¡ç§å®¤=" + hisDeptCode); |
| | | } |
| | | return new Result(false, "æªå½ä¸ä»»ä½å¿çµå¤å®ä¾æ®"); |
| | | } |
| | | |
| | | /** |
| | | * 综åå¤å®ï¼å« ZDY æ£æ¥é¡¹ç®ï¼ç¨äº {@code S050401}/{@code S050501}ï¼ã |
| | | * <p> |
| | | * è¿ä¸¤ä¸ªæå¡çæ£æ¥é¡¹ç®ä¸å¨ {@code component2.observationRequest.code}ï¼ |
| | | * èå¨ {@code actAppointment.ZDY.jcxmcode} / {@code ZDY.jcxmname}ï¼éå·åéå¤å¼ï¼ã |
| | | * |
| | | * @param zdy æ¥æä¸ç {@code ZDY} èç¹ï¼å¯ä¸ºç©º |
| | | */ |
| | | public Result judgeWithZdy(String applyNo, String hisDeptCode, Object zdy) { |
| | | // 便® Aï¼ç³è¯·åå·åç¼ |
| | | if (matchApplyNoSuffix(applyNo)) { |
| | | return new Result(true, "A:ç³è¯·åå·åç¼"); |
| | | } |
| | | // 便® Bï¼ZDY ä¸çæ£æ¥é¡¹ç®ï¼ä»£ç + åç§°ï¼æ¯æéå·åéå¤å¼ï¼ |
| | | String jcxmCode = extractZdyValue(zdy, "jcxmcode"); |
| | | String jcxmName = extractZdyValue(zdy, "jcxmname"); |
| | | if (matchCheckItems(jcxmCode, jcxmName)) { |
| | | return new Result(true, "B:ZDYæ£æ¥é¡¹ç® code=" + jcxmCode + " name=" + jcxmName); |
| | | } |
| | | // 便® Cï¼æ§è¡ç§å®¤ |
| | | if (matchDeptCode(hisDeptCode)) { |
| | | return new Result(true, "C:æ§è¡ç§å®¤=" + hisDeptCode); |
| | | } |
| | | return new Result(false, "æªå½ä¸ä»»ä½å¿çµå¤å®ä¾æ®"); |
| | | } |
| | | |
| | | /** å ZDY ä¸çæä¸ªææ¬å段 */ |
| | | private String extractZdyValue(Object zdy, String key) { |
| | | if (!(zdy instanceof java.util.Map)) { |
| | | return null; |
| | | } |
| | | Object v = ((java.util.Map<?, ?>) zdy).get(key); |
| | | return v == null ? null : v.toString(); |
| | | } |
| | | |
| | | /** 便® Aï¼ç³è¯·åå·æ¯å¦ä»¥å¿çµåç¼ç»å°¾ */ |
| | | public boolean matchApplyNoSuffix(String applyNo) { |
| | | if (!StringUtils.hasText(applyNo)) { |
| | | return false; |
| | | } |
| | | String trimmed = applyNo.trim(); |
| | | for (String suffix : ECG_APPLY_NO_SUFFIXES) { |
| | | if (trimmed.endsWith(suffix)) { |
| | | return true; |
| | | } |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | /** |
| | | * 便® B-1ï¼HIS æ£æ¥é¡¹ç®ä»£ç æ¯å¦å±å¿çµã |
| | | * <p> |
| | | * HIS æ¥æä¸è¯¥å¼å½¢å¦ {@code Y1202065}ï¼è {@link HisCheckCodeEnum} ç code 为 |
| | | * 廿åç¼ {@code Y} åçæ°åï¼{@code 1202065}ï¼ãå代ç ä½¿ç¨ |
| | | * {@code checkType.substring(1)} åæªæï¼è¿éååæ ·å
¼å®¹å¹¶è¡¥é¿åº¦æ ¡éªï¼ |
| | | * åæ¶å®¹å¿æ¥ææ¬èº«å°±å¸¦æä¸å¸¦ {@code Y} åç¼ã |
| | | */ |
| | | public boolean matchCheckCode(String hisCheckCode) { |
| | | if (!StringUtils.hasText(hisCheckCode)) { |
| | | return false; |
| | | } |
| | | String raw = hisCheckCode.trim().replaceAll("\\s+", ""); |
| | | // åé»è¾ï¼substring(1) 廿é¦åç¬¦ãæ¤å¤åæ¶å°è¯åå¼ä¸å»é¦å符ï¼å
¼å®¹ä¸¤ç§æ¥æ |
| | | String[] candidates = raw.length() > 1 |
| | | ? new String[]{raw, raw.substring(1)} |
| | | : new String[]{raw}; |
| | | for (String candidate : candidates) { |
| | | if (HisCheckCodeEnum.getByCode(candidate) != null) { |
| | | return true; |
| | | } |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | /** |
| | | * 便® B-2ï¼HIS æ£æ¥é¡¹ç®åç§°æ¯å¦å±å¿çµã |
| | | * |
| | | * <p>å¤å®é¡ºåºï¼**å
ç½ååãåå
³é®åãåç¨æé¤è¯æ¡ä½**ï¼ï¼ |
| | | * <ol> |
| | | * <li><b>åç§°ç½åå精确å¹é
</b>ï¼{@link ECG_NAME_WHITELIST} æ |
| | | * {@link HisCheckNameEnum}ï¼ââ è¦ç"卿è¡å""å¨èç¡¬åæ£æµ" |
| | | * "é£éçµçç""å¿å®¤æçµä½"ç**ä¸å«"å¿çµ"**çå¿çµé¡¹ç®ï¼</li> |
| | | * <li><b>å«"å¿çµ"å
³é®å</b> ââ è¦çç½ååæªæ¶å½çåç§°åä½ |
| | | * ï¼å¦"åäºå¯¼èå¿çµæ£æ¥"ï¼ï¼</li> |
| | | * <li><b>å½ä¸éå¿çµæé¤è¯</b>ï¼{@link NON_ECG_EXCLUDE_KEYWORDS}ï¼ââ |
| | | * æç¡®å¤ä¸ºå
¶ä»ç§å®¤æ£æ¥ï¼ç´æ¥è¿å falseã |
| | | * è¿ä¸æ¥å¾å
³é®ï¼è¥æåç§°åæ¶å½ä¸"å¿çµ"䏿é¤è¯ï¼å¼å¸¸æ
åµï¼ï¼ |
| | | * è¯´ææ¥æææ§ä¹ï¼å®å¯äº¤ç»æé¤è¯å¤å¦ï¼ä¹ä¸è¯¯æ¶ã</li> |
| | | * </ol> |
| | | * |
| | | * <p><b>为ä»ä¹ä¸åªç¨"å«å¿çµ"</b>ï¼æ¬é¢ {@code check_type} 表ç 15 个å¿çµç±»åä¸ï¼ |
| | | * æ 4 个ä¸å«"å¿çµ"ï¼300 卿è¡åã500 å¨èç¡¬åæ£æµã600 é£éçµççã |
| | | * 900 å¿å®¤æçµä½ï¼ï¼åºä¸å计 2 ä¸ä½æ¡çå®è®°å½ãä»
é å
³é®åä¼**丢å¼è¿äºçå®å¿çµå**ã |
| | | */ |
| | | public boolean matchCheckName(String hisCheckName) { |
| | | if (!StringUtils.hasText(hisCheckName)) { |
| | | return false; |
| | | } |
| | | String normalized = hisCheckName.trim().replaceAll("\\s+", ""); |
| | | |
| | | // 1) éå¿çµæé¤è¯ä¼å
å¤å¦ï¼é²æ¢æ§ä¹å称被åé¢çå
³é®å误æ¶ï¼ |
| | | for (String kw : NON_ECG_EXCLUDE_KEYWORDS) { |
| | | if (normalized.contains(kw)) { |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | // 2) åç§°ç½ååå¹é
|
| | | // éç¨**åç¼å¹é
**èéå
¨çï¼HIS çå称常带ååç¼åä½ |
| | | // ï¼å¦"24å°æ¶å¨æè¡åçæµ"= åç¼"卿è¡å" + "çæµ"ï¼ |
| | | // "卿å¿çµå¾+è¡å"以"卿å¿çµ"å¼å¤´ï¼ï¼åç¼å¹é
å¯è¦çé¿å°¾åä½ã |
| | | // å®å
¨åæï¼æé¤è¯å·²å¨ç¬¬ 1 æ¥å
è¡æ¦æªï¼ä¸ä¼åºç°"彩è¶
â¦"被åç¼è¯¯æ¶ã |
| | | if (HisCheckNameEnum.getByName(normalized) != null) { |
| | | return true; |
| | | } |
| | | for (String name : ECG_NAME_WHITELIST) { |
| | | if (normalized.startsWith(name)) { |
| | | return true; |
| | | } |
| | | } |
| | | |
| | | // 3) å
³é®åå
åºï¼ç½ååä¹å¤çé¿å°¾åç§°åä½ï¼ |
| | | return normalized.contains(ECG_NAME_KEYWORD); |
| | | } |
| | | |
| | | /** |
| | | * 便® Bï¼å¤å¼çï¼ï¼æ¥æä¸çæ£æ¥é¡¹ç®ä»£ç /åç§°å¯è½æ¯**éå·åéçå¤ä¸ªé¡¹ç®**ã |
| | | * <p> |
| | | * 宿µ {@code S050401}/{@code S050501} ç {@code ZDY.jcxmcode}/{@code ZDY.jcxmname} |
| | | * å½¢å¦ï¼ |
| | | * <pre> |
| | | * jcxmcode=1393,1506 jcxmname=å³èæ£ä¾§ä½,å·¦è©å
³èæ£ä¾§ä½ |
| | | * jcxmcode=35672306,35672504,... jcxmname=彩è¶
å³ä¸è¢å¨è,彩è¶
å³ä¸è¢éè,... |
| | | * </pre> |
| | | * åªè¦**ä»»ä¸**项ç®å±å¿çµå³å¤å®ä¸ºå¿çµåã |
| | | * |
| | | * @param hisCheckCodes éå·åéçæ£æ¥é¡¹ç®ä»£ç ï¼å¯ä¸ºç©º |
| | | * @param hisCheckNames éå·åéçæ£æ¥é¡¹ç®åç§°ï¼å¯ä¸ºç©º |
| | | * @return æ¯å¦å½ä¸å¿çµæ£æ¥é¡¹ç® |
| | | */ |
| | | public boolean matchCheckItems(String hisCheckCodes, String hisCheckNames) { |
| | | return matchAny(hisCheckCodes, this::matchCheckCode) |
| | | || matchAny(hisCheckNames, this::matchCheckName); |
| | | } |
| | | |
| | | /** å°åé符æå¼çå¼é个交ç»å¤å®å½æ°ï¼ä»»ä¸å½ä¸å³è¿å true */ |
| | | private boolean matchAny(String joined, java.util.function.Predicate<String> matcher) { |
| | | if (!StringUtils.hasText(joined)) { |
| | | return false; |
| | | } |
| | | for (String part : joined.split("[,ï¼;ï¼]")) { |
| | | if (matcher.test(part.trim())) { |
| | | return true; |
| | | } |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | /** |
| | | * 便® Bï¼S050401/S050501 ä¸ç¨ï¼ï¼ä» {@code ZDY.jcxmcode} / {@code ZDY.jcxmname} |
| | | * 综åå¤å®æ¯å¦å±å¿çµæ£æ¥ã |
| | | */ |
| | | public boolean matchZdyCheckItems(Object zdy) { |
| | | if (!(zdy instanceof java.util.Map)) { |
| | | return false; |
| | | } |
| | | java.util.Map<?, ?> m = (java.util.Map<?, ?>) zdy; |
| | | Object code = m.get("jcxmcode"); |
| | | Object name = m.get("jcxmname"); |
| | | return matchCheckItems(code == null ? null : code.toString(), |
| | | name == null ? null : name.toString()); |
| | | } |
| | | |
| | | /** 便® Cï¼æ§è¡ç§å®¤ä»£ç æ¯å¦å¨ç½ååå
ï¼ç½åå为空æ¶è§ä¸ºä¸åä¸å¤å®ï¼ */ |
| | | public boolean matchDeptCode(String hisDeptCode) { |
| | | if (ecgDeptCodes.isEmpty() || !StringUtils.hasText(hisDeptCode)) { |
| | | return false; |
| | | } |
| | | String trimmed = hisDeptCode.trim(); |
| | | return ecgDeptCodes.stream().anyMatch(c -> c.equalsIgnoreCase(trimmed)); |
| | | } |
| | | |
| | | /** |
| | | * ä¾¿æ·æ¹æ³ï¼ä»
å¤å®ï¼å¹¶å¨éå¿çµåæ¶è¾åºå¯ææ¥ç DEBUG æ¥å¿ã |
| | | * |
| | | * @param source è°ç¨æ¥æºæ è¯ï¼ç¨äºæ¥å¿å®ä½ï¼å¦ {@code S0405}ï¼ |
| | | */ |
| | | public boolean isEcgOrder(String source, String applyNo, String hisCheckCode, |
| | | String hisCheckName, String hisDeptCode) { |
| | | Result r = judge(applyNo, hisCheckCode, hisCheckName, hisDeptCode); |
| | | if (!r.isEcg()) { |
| | | // ç¨ INFO 级ï¼ç产æ¥å¿çº§å«ä¸º INFOï¼è¥ç¨ DEBUG åè·³è¿è®°å½å®å
¨ä¸å¯è§ï¼ |
| | | // æ¾å æ¤æ¼æäº S050401/S050501 æ··å
¥éå¿çµåçé®é¢ï¼æ æ³ä»æ¥å¿åç°ï¼ã |
| | | log.info("[{}][éå¿çµä¸å¡åï¼è·³è¿å¤ç] applyNo={} æ£æ¥ä»£ç ={} 项ç®åç§°={} æ§è¡ç§å®¤={} åå ={}", |
| | | source, applyNo, hisCheckCode, hisCheckName, hisDeptCode, r.getReason()); |
| | | } |
| | | return r.isEcg(); |
| | | } |
| | | |
| | | /** |
| | | * ä¾¿æ·æ¹æ³ï¼å« ZDY æ£æ¥é¡¹ç®ï¼ï¼ç¨äº {@code S050401}/{@code S050501}ã |
| | | * <p> |
| | | * éå¿çµåæ¶è¾åº INFO 级æ¥å¿ï¼è¿ä¸¤ä¸ªæå¡æ¤å**æªåä»»ä½è¿æ»¤**ï¼å¯¼è´æ¾å°/è¶
声å |
| | | * 被å½ä½å¿çµç³è¯·åééï¼å®æµ S050401 æ 109/256ãS050501 æ 4/19 å±éå¿çµï¼ã |
| | | * |
| | | * @param zdy æ¥æä¸ç {@code ZDY} èç¹ |
| | | */ |
| | | public boolean isEcgOrderWithZdy(String source, String applyNo, String hisDeptCode, Object zdy) { |
| | | Result r = judgeWithZdy(applyNo, hisDeptCode, zdy); |
| | | if (!r.isEcg()) { |
| | | Object name = zdy instanceof java.util.Map ? ((java.util.Map<?, ?>) zdy).get("jcxmname") : null; |
| | | Object room = zdy instanceof java.util.Map ? ((java.util.Map<?, ?>) zdy).get("roomname") : null; |
| | | log.info("[{}][éå¿çµä¸å¡åï¼è·³è¿å¤ç] applyNo={} æ£æ¥é¡¹ç®={} æ¿é´={} æ§è¡ç§å®¤={} åå ={}", |
| | | source, applyNo, name, room, hisDeptCode, r.getReason()); |
| | | } |
| | | return r.isEcg(); |
| | | } |
| | | |
| | | /** ä»å½¢å¦ {@code component2={observationRequest={...code={code=Y1202065,...}}}} çç»æä¸åæ£æ¥é¡¹ç®ä»£ç */ |
| | | @SuppressWarnings("unchecked") |
| | | public static String extractCheckCode(Object component2) { |
| | | return Optional.ofNullable(component2) |
| | | .filter(v -> v instanceof java.util.Map) |
| | | .map(v -> (java.util.Map<String, Object>) v) |
| | | .map(m -> (java.util.Map<String, Object>) m.get("observationRequest")) |
| | | .map(or -> (java.util.Map<String, Object>) or.get("code")) |
| | | .map(code -> { |
| | | Object c = code.get("code"); |
| | | return c == null ? null : c.toString(); |
| | | }) |
| | | .orElse(null); |
| | | } |
| | | } |
| | |
| | | import cn.lihu.jh.framework.common.util.object.BeanUtils; |
| | | |
| | | import cn.lihu.jh.module.ecg.dal.mysql.jobrecord.JobRecordMapper; |
| | | import cn.lihu.jh.module.ecg.dal.mysql.queue.QueueMapper; |
| | | import cn.lihu.jh.module.ecg.enums.QueueStatusEnum; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | |
| | | import javax.annotation.Resource; |
| | | |
| | |
| | | */ |
| | | @Service |
| | | @Validated |
| | | @Slf4j |
| | | public class JobRecordServiceImpl implements JobRecordService { |
| | | |
| | | @Resource |
| | | private JobRecordMapper jobRecordMapper; |
| | | |
| | | /** ãæ¤éæ è¯ãè¯»å½æ¥éåç¶æï¼å¤æ"宿æ¯å¦è¢«æ¤éè¿" */ |
| | | @Resource |
| | | private QueueMapper queueMapper; |
| | | |
| | | @Resource |
| | | private DevRentMapper devRentMapper; |
| | |
| | | } |
| | | // éæ±1ï¼åå¡«æ£è
ä¿¡æ¯ï¼æ¹éï¼é¿å
N+1ï¼ |
| | | fillPatientInfo(jobRecordDOList); |
| | | // ãæ¤éæ è¯ãæ è®°"å®æè¢«æ¤éè¿ãè¿æ²¡éæ°å®æ"çè®°å½ |
| | | fillUndoneFlag(jobRecordDOList); |
| | | } |
| | | |
| | | return pageResult; |
| | | } |
| | | |
| | | /** |
| | | * ãæ¤éæ è¯ãç»"å·²å®æè®°å½"è¡¥ä¸ {@code undone}ã |
| | | * |
| | | * <p>æ¤éãæ£æ¥å®æãåªæ¯æéåè¡ 40(已就è¯) æ¹å 20(åå¤ä¸)ï¼**ä¸ç¢° job_record**ï¼ |
| | | * å æ¤å¤æè§åæ¯ï¼è¯¥æ£è
**仿¥**å¯¹åºæ£æ¥é¡¹ç®çéåè¡åå¨ãä¸ç¶æ â 40 â 已被æ¤éã |
| | | * æ£è
忬¡å®æåéåè¡ä¼åå° 40 â èªå¨æ¢å¤æ"已宿"ï¼æ éååºãä¹ä¸ä¼æ¼æ¸
æ è®°ã |
| | | * |
| | | * <p>䏿¬¡æ¹éæ¥è¯¢è§£å³æ´é¡µï¼æ patId å彿¥éåç¶æï¼åå¨å
åéæ patId+checkType å¹é
ï¼ã |
| | | */ |
| | | private void fillUndoneFlag(List<JobRecordDO> jobRecordDOList) { |
| | | List<String> patIdList = jobRecordDOList.stream() |
| | | .map(JobRecordDO::getPatId) |
| | | .filter(Objects::nonNull) |
| | | .distinct() |
| | | .toList(); |
| | | if (patIdList.isEmpty()) { |
| | | return; |
| | | } |
| | | Map<String, Integer> statusMap = new HashMap<>(); |
| | | try { |
| | | for (Map<String, Object> row : queueMapper.selectTodayStatusByPatIds(patIdList)) { |
| | | Object patId = row.get("patId"); |
| | | Object checkType = row.get("checkType"); |
| | | Object status = row.get("status"); |
| | | if (null != patId && null != checkType && status instanceof Number) { |
| | | statusMap.put(patId + "#" + checkType, ((Number) status).intValue()); |
| | | } |
| | | } |
| | | } catch (Exception e) { |
| | | log.warn("[fillUndoneFlag] 读å彿¥éåç¶æå¤±è´¥ï¼æ¤éæ è¯æãæªæ¤éãå¤ç", e); |
| | | return; |
| | | } |
| | | for (JobRecordDO row : jobRecordDOList) { |
| | | if (null == row.getPatId() || null == row.getCheckType()) { |
| | | row.setUndone(false); |
| | | continue; |
| | | } |
| | | Integer status = statusMap.get(row.getPatId() + "#" + row.getCheckType()); |
| | | // éåè¡ä¸åå¨ï¼åå²è®°å½/å·²æ¸
çï¼â è§ä¸ºæªæ¤éï¼åå¨ä¸ä¸æ¯ 40 â å·²æ¤é |
| | | row.setUndone(null != status && QueueStatusEnum.FINISH.getStatus() != status); |
| | | } |
| | | } |
| | | |
| | | // ==================== éæ±1ï¼åå¡«æ£è
ä¿¡æ¯ 18 项 ==================== |
| | | // åå¡«é¾è·¯ï¼ä¸çº§ï¼ï¼ |
| | | // job_record.rentId â dev_rent.applyNo â appointment |
| | |
| | | private String bedNo; |
| | | private Long docId; |
| | | private String docName; |
| | | /** å·¥ä½ä¸»é®ï¼å¯éï¼ï¼ä¼å
æå®å®ä½ï¼é¿å
bed_no ä¸è¯·æ±å¼æèç¼é¾è¾¨å·®å¼æ¶æ´æ° 0 è¡ */ |
| | | private Integer bedId; |
| | | |
| | | public BedDoctorOnCallable(QueueServiceTxFunctions queueService, Long roomId, String bedNo, Long docId, String docName) |
| | | public BedDoctorOnCallable(QueueServiceTxFunctions queueService, Long roomId, String bedNo, Long docId, String docName, Integer bedId) |
| | | { |
| | | super(); |
| | | this.queueService = queueService; |
| | |
| | | this.bedNo = bedNo; |
| | | this.docId = docId; |
| | | this.docName = docName; |
| | | this.bedId = bedId; |
| | | } |
| | | |
| | | public ErrorCode call() throws Exception { |
| | | ErrorCode ec = queueService.bedDoctorOn(roomId, bedNo, docId, docName); |
| | | ErrorCode ec = queueService.bedDoctorOn(roomId, bedNo, docId, docName, bedId); |
| | | if (GlobalErrorCodeConstants.SUCCESS.equals(ec)) { |
| | | queueService.hurryupOneBed(roomId, bedNo); |
| | | } |
| | |
| | | * ä¸ä¸ªå·¥ä½ å¯è½æ¯æå¤ä¸ªæ£æ¥ç±»åï¼ |
| | | */ |
| | | void startHurryUpOneBed(Long roomId, String bedNo); |
| | | |
| | | /** |
| | | * ç«å³è¡¥äººï¼ç°åºèªæ + èªå©è¯æï¼ï¼æå¨è§¦å䏿¬¡è¯¥å·¥ä½çèªå¨åæµï¼ |
| | | * å¹¶è¿åãç³»ç»å¼è¯ç¶æ / æ¯å¦åæ¢åè¯ / åè¯ä¸é / 补人ååäººæ° / ç»è®ºãã |
| | | * |
| | | * <p>è°ç¨æ¹å¿
é¡»ä¿è¯"å½åç»å½äººæ¯è¯¥å·¥ä½ä¸»äºº"ï¼Controller ä¸ç¨ {@code @RequireBedOwner}ï¼ã |
| | | */ |
| | | java.util.Map<String, Object> hurryUpNow(Long roomId, String bedNo); |
| | | void startHurryUpOneCheckType(Integer checkType); |
| | | |
| | | void startBedReload(); |
| | |
| | | ErrorCode startBedClose(Long roomId, String bedNo); |
| | | ErrorCode startBedDoctorPause(Long roomId, String bedNo, Long docId, String docName); |
| | | ErrorCode startBedDoctorResume(Long roomId, String bedNo, Long docId, String docName); |
| | | ErrorCode startBedDoctorOn(Long roomId, String bedNo, Long docId, String docName); |
| | | /** |
| | | * å»çå
¥åº§ï¼æå·¥ä½ä¸»äººè®¾ä¸ºè¯¥å»çï¼ã |
| | | * |
| | | * @param bedId å·¥ä½ä¸»é®ï¼å¯éï¼ï¼ä¼ å
¥æ¶**ä¼å
æå®å®ä½**ï¼é¿å
bed_no ä¸è¯·æ±å¼åå¨ |
| | | * èç¼é¾è¾¨å·®å¼ï¼ç»å°¾ç©ºæ ¼/大å°å/å
¨è§ï¼å¯¼è´"ææç©ºé²å´å
¥åº§å¤±è´¥" |
| | | */ |
| | | ErrorCode startBedDoctorOn(Long roomId, String bedNo, Long docId, String docName, Integer bedId); |
| | | |
| | | /** |
| | | * ãæ¬è¯å®¤æéä¸ï¼æªåé
å·¥ä½ï¼ãçæ£è
å表ï¼å·¥ä½å°"æ¬è¯å®¤æéä¸ï¼æªåé
ï¼"ååºç¨ï¼ã |
| | | * |
| | | * <p>åè¯å表æ {@code room_id + bed_no} æ¥ï¼åªå«**已念尿¬å·¥ä½**çæ£è
ï¼ |
| | | * æéä¸(10) çæ£è
{@code bed_no} 为空ï¼å¤§å±ä¼æ¾ç¤ºãå·¥ä½å°çä¸å°ï¼ï¼è¿éææ¬å·¥ä½ |
| | | * å¼å±çæ£æ¥é¡¹ç®åç¬æ¥åºæ¥ï¼ä¾å»çæå·¥æå
¥ã |
| | | */ |
| | | List<cn.lihu.jh.module.ecg.dal.dataobject.queue.QueueDO> getUnassignedWaitingPatient(Long roomId, String bedNo); |
| | | |
| | | /** |
| | | * æå·¥ææä½ãæéä¸ãæ£è
æå
¥æ¬å·¥ä½ï¼â åå¤ä¸ï¼ã |
| | | * |
| | | * <p>è°ç¨æ¹å¿
é¡»ä¿è¯"å½åç»å½äººæ¯è¯¥å·¥ä½ä¸»äºº"ï¼Controller ä¸ç¨ {@code @RequireBedOwner}ï¼ã |
| | | */ |
| | | ErrorCode pullWaitingPatient(Long roomId, String bedNo, Integer queueId); |
| | | ErrorCode startBedDoctorOff(Long roomId, String bedNo, Long docId, String docName); |
| | | |
| | | /** |
| | | * ãæ¬æ¬¡éæ±ã管çåå¼ºå¶æ¸
空工ä½ï¼ä¸è¦æ±æ¯æ¬äººï¼ââ å»çä¸çå¿ç¦»åº§ / æ¢äººä½¿ç¨åä¸å·¥ä½æ¶ç¨ã |
| | | */ |
| | | ErrorCode startBedDoctorOffByAdmin(Long roomId, String bedNo); |
| | | ErrorCode startNextPatient(Long roomId, String bedNo); |
| | | ErrorCode startNextInstallPatient(Long roomId, String bedNo); |
| | | |
| | |
| | | */ |
| | | void queue(QueueSaveReqVO queueSaveReqVO); |
| | | |
| | | List<QueueDO> selectBookSeqNumByAppointIdList(List<Long> appointIdList); |
| | | /** |
| | | * æé¢çº¦å id æ¹éå queue è¡ï¼é¢çº¦ç¾å°ååå¡«ãå·²æé + æéå· seq_numãç¨ï¼ã |
| | | * <p>åæ¹æ³å为 {@code selectBookSeqNumByAppointIdList}ï¼å·ç»ä¸å° seq_num åæ¹åã |
| | | */ |
| | | List<QueueDO> selectQueueByAppointIdList(List<Long> appointIdList); |
| | | |
| | | /** |
| | | * å¸¸è§æ£æ¥ å»çå«ä¸ä¸ä½æ£è
|
| | |
| | | |
| | | import java.util.*; |
| | | import java.util.concurrent.*; |
| | | import java.util.stream.Collectors; |
| | | import javax.annotation.Resource; |
| | | |
| | | import cn.lihu.jh.module.ecg.Utils; |
| | |
| | | return ECG_INNER_ERROR; |
| | | } |
| | | |
| | | /** |
| | | * ãæ¬è¯å®¤æéä¸ï¼æªåé
å·¥ä½ï¼ãçæ£è
å表ã |
| | | * |
| | | * <p>å·¥ä½å°åè¯å表æ {@code room_id + bed_no} æ¥ï¼åªçå¾å°**已念尿¬å·¥ä½**çæ£è
ï¼ |
| | | * è"æéä¸(10)"çæ£è
{@code bed_no} 为空ï¼å¤§å±ä¼æ¾ç¤ºãå·¥ä½å°çä¸å°ï¼ï¼ |
| | | * è¿éæ**æ¬å·¥ä½å¼å±çæ£æ¥é¡¹ç®**æä»ä»¬åç¬æ¥åºæ¥ï¼ä¾å»çæå·¥æå
¥ã |
| | | * |
| | | * <p>å·¥ä½ä¸åå¨ææ²¡é
æ£æ¥é¡¹ç®æ¶è¿å空å表ï¼è®°è¦åï¼ï¼ä¸æå¼å¸¸ ââ å表为空ä¸å½±å主æµç¨ã |
| | | */ |
| | | @Override |
| | | public ErrorCode startBedDoctorOn(Long roomId, String bedNo, Long docId, String docName) { |
| | | Future<ErrorCode> future = singleThreadExecutor.submit(new BedDoctorOnCallable(queueServiceTxFunctions, roomId, bedNo, docId, docName)); |
| | | public List<QueueDO> getUnassignedWaitingPatient(Long roomId, String bedNo) { |
| | | RoomDO bed = (null == roomId || null == bedNo) ? null : roomMapper.getRoom(roomId, bedNo); |
| | | if (null == bed || null == bed.getCheckTypes() || 0 == bed.getCheckTypes().length) { |
| | | log.warn("[getUnassignedWaitingPatient] å·¥ä½ä¸å卿æªé
ç½®æ£æ¥é¡¹ç®ï¼è¿å空. roomId={} bedNo={}", |
| | | roomId, bedNo); |
| | | return new ArrayList<>(); |
| | | } |
| | | return queueMapper.selectUnassignedWaitingByCheckTypes( |
| | | QueueStatusEnum.WAITING.getStatus(), bed.getCheckTypes()); |
| | | } |
| | | |
| | | /** |
| | | * æå·¥ææä½ãæéä¸ãæ£è
æå
¥æ¬å·¥ä½ï¼â åå¤ä¸ï¼ã |
| | | * |
| | | * <p>æéç± Controller ä¸ç {@code @RequireBedOwner} ä¿è¯ï¼åªææ¬å·¥ä½ä¸»äººè½æã |
| | | * è¿éåªåä¸å¡æ ¡éªä¸æ¡ä»¶æ´æ°ï¼å¹¶åå®å
¨ï¼{@code and status = 10}ï¼ï¼å¹¶å¤ç¨èªå¨åæµç亲å项é»è¾ã |
| | | */ |
| | | @Override |
| | | public ErrorCode pullWaitingPatient(Long roomId, String bedNo, Integer queueId) { |
| | | return queueServiceTxFunctions.pullWaitingPatient(roomId, bedNo, queueId); |
| | | } |
| | | |
| | | @Override |
| | | public ErrorCode startBedDoctorOn(Long roomId, String bedNo, Long docId, String docName, Integer bedId) { |
| | | Future<ErrorCode> future = singleThreadExecutor.submit(new BedDoctorOnCallable(queueServiceTxFunctions, roomId, bedNo, docId, docName, bedId)); |
| | | |
| | | try { |
| | | ErrorCode ret = future.get(); |
| | |
| | | } |
| | | |
| | | //System.out.println("startBedDoctorOff ========"); |
| | | return ECG_INNER_ERROR; |
| | | } |
| | | |
| | | /** |
| | | * ãæ¬æ¬¡éæ±ã管çåå¼ºå¶æ¸
空工ä½ï¼ä¸è¦æ±æ¯æ¬äººï¼ã |
| | | * <p> |
| | | * ä¸ {@link #startBedDoctorOff} å
±ç¨åä¸ä¸ªåçº¿ç¨æ§è¡å¨ï¼ä¿è¯å䏿¶å»åªå¤çä¸ä¸ªå·¥ä½æä½ï¼ |
| | | * é¿å
ä¸ãå«å· / å
¥åº§ / 离座ãå¹¶åæ¹åä¸è¡ã |
| | | */ |
| | | @Override |
| | | public ErrorCode startBedDoctorOffByAdmin(Long roomId, String bedNo) { |
| | | Future<ErrorCode> future = singleThreadExecutor.submit( |
| | | () -> queueServiceTxFunctions.bedDoctorOffByAdmin(roomId, bedNo)); |
| | | try { |
| | | return future.get(); |
| | | } catch (InterruptedException e) { |
| | | Thread.currentThread().interrupt(); |
| | | log.error("[管ç忏
空工ä½] è¢«ä¸æ", e); |
| | | } catch (ExecutionException e) { |
| | | log.error("[管ç忏
空工ä½] æ§è¡å¤±è´¥", e.getCause() != null ? e.getCause() : e); |
| | | } |
| | | return ECG_INNER_ERROR; |
| | | } |
| | | |
| | |
| | | singleThreadExecutor.execute(() -> { |
| | | queueServiceTxFunctions.hurryupOneBed(roomId, bedNo); |
| | | }); |
| | | } |
| | | |
| | | @Override |
| | | public Map<String, Object> hurryUpNow(Long roomId, String bedNo) { |
| | | // 忥æ§è¡ï¼è¦ç«å»è¿å"补人ååäººæ° + ç»è®º"ï¼å¼æ¥å°±çä¸å°ç»æäº |
| | | return queueServiceTxFunctions.hurryUpNow(roomId, bedNo); |
| | | } |
| | | |
| | | @Override |
| | |
| | | } |
| | | |
| | | @Override |
| | | public List<QueueDO> selectBookSeqNumByAppointIdList(List<Long> appointIdList) { |
| | | return queueMapper.selectBookSeqNumByAppointIdList(appointIdList); |
| | | public List<QueueDO> selectQueueByAppointIdList(List<Long> appointIdList) { |
| | | return queueMapper.selectQueueByAppointIdList(appointIdList); |
| | | } |
| | | |
| | | // å¸¸è§æ£æ¥ å«å· |
| | |
| | | // ä» DB æ [å®è£
ä¸]ç人 设置为 [è¿å·-å®è£
] |
| | | Integer ret = queueMapper.updateBedQueueStatus(roomId, bedNo, QueueStatusEnum.INSTALLING.getStatus(), QueueStatusEnum.PASSED_INSTALL.getStatus()); |
| | | |
| | | startNextPatient(roomId, bedNo); |
| | | // ãæ¢æç¬è¯¯ä¿®å¤ãè¿é忬è°çæ¯ startNextPatientï¼å¸¸è§æ£æ¥å人ï¼åè¯ä¸ â å°±è¯ä¸ï¼ï¼ |
| | | // èè£
æºè¿å·ååºå½ç»§ç»å**å®è£
éå**éçä¸ä¸ä½ï¼å·²é¢ç¨/å·²å¬å-å®è£
â å®è£
ä¸ï¼ã |
| | | // ç±äºè£
æºå·¥ä½ä¸åä¸åæµã没æ"åè¯ä¸"æ£è
ï¼åè°ç¨å®é
ä¸ä»ä¹ä¹ä¸ä¼åçï¼ |
| | | // 表ç°ä¸º"è£
æºè¿å·åä¸ä¼èªå¨å«ä¸ä¸ä½"ã |
| | | startNextInstallPatient(roomId, bedNo); |
| | | } |
| | | |
| | | public List<QueueDO> getBedQueueByStatus(Long roomId, String bedNo, List<Integer> statusList) { |
| | |
| | | /** |
| | | * ä»é¢çº¦åè¡¥é½ queue è¡¨ä¸æ²¡æçæ£è
ä¿¡æ¯ã |
| | | * |
| | | * queue 表ä¸åè¿äºå段ï¼ä½å»ç端å表æ¥å£éè¦å±ç¤ºï¼æä»¥æ¥è¯¢åæ applyNo 忥é¢çº¦åå¡«å
ï¼ |
| | | * å¤èè¯ãæ§å«ãåºçæ¥æãç»è®°æ¶é´ãå¼åå»å¸ãå¼åæ¥æã |
| | | * <p>queue 表ä¸åè¿äºå段ï¼ä½å»ç端å表æ¥å£éè¦å±ç¤ºï¼æä»¥æ¥è¯¢åæ applyNo 忥é¢çº¦åå¡«å
ï¼ |
| | | * å¤èè¯ãæ§å«ãåºçæ¥æãç»è®°æ¶é´ãå¼åå»å¸ãå¼åæ¥æã</p> |
| | | * |
| | | * <h3>â ï¸ æ§è½ä¿®å¤ï¼ç± N+1 æ¹ä¸ºä¸æ¬¡æ¹éæ¥è¯¢</h3> |
| | | * <p><b>åå®ç°</b>å¨ {@code forEach} é对æ¯ä¸è¡è°ç¨ |
| | | * {@code appointmentMapper.getByApplyNo(applyNo)}ï¼å³**æ¯è¡ä¸æ¬¡ SQL**ã |
| | | * å表æ¯é¡µ 10 æ¡ â 10 次æ¥è¯¢ï¼è该 SQL |
| | | * ï¼{@code WHERE apply_no = ? AND deleted = 0}ï¼å¨ä¿®å¤å**ç¨ä¸ä¸ç´¢å¼**ï¼ |
| | | * æ¯æ¬¡é½æ¯å
¨è¡¨æ«æ appointmentï¼å®æµ 16.6 ä¸è¡ï¼çº¦ 549 ms/次ï¼ï¼ |
| | | * ä¸é¡µå°±è¦ 4.5~5.5 ç§ ââ è¿æ¯ãéåå表æå¼å¾æ
¢ãçç´æ¥åå ã</p> |
| | | * |
| | | * <p><b>ç°å®ç°</b>æ¹ä¸ºï¼å
æ¶éæ¬é¡µææ applyNoï¼å»éï¼â **䏿¬¡** |
| | | * {@code getByApplyNoList} æ¹éåå â å
åéæ applyNo 建æ å°ååå¡«ã |
| | | * ä¸é¡µ SQL ä» 10 次éå° 1 次ã</p> |
| | | * |
| | | * <p>注ï¼é
å¥å·²äº {@code 26_add_index_appointment_apply_no.sql} |
| | | * ç» {@code appointment.apply_no} å ä¸ç´¢å¼ï¼ |
| | | * ä½å³ä¾¿æç´¢å¼ï¼N+1 仿¯ 10 次å¾è¿ï¼æ
两å¤ä¸èµ·æ¹ææ¯æä¼ã</p> |
| | | */ |
| | | @Override |
| | | public void fillAppointmentInfo(List<QueueDO> queueDOList) { |
| | | if (CollectionUtils.isEmpty(queueDOList)) { |
| | | return; |
| | | } |
| | | // 1. æ¶éæ¬æ¬¡éè¦åæ¥çç³è¯·åå·ï¼è·³è¿ç©ºå¼ï¼ã |
| | | // ç¨ LinkedHashSet å»éï¼åä¸é¡µéçè®ºä¸ apply_no å¯ä¸ï¼ä½å»éå IN å表æ´çãæ´å®å
¨ã |
| | | Set<String> applyNoSet = new LinkedHashSet<>(); |
| | | for (QueueDO queueDO : queueDOList) { |
| | | if (queueDO != null && queueDO.getApplyNo() != null && !queueDO.getApplyNo().isEmpty()) { |
| | | applyNoSet.add(queueDO.getApplyNo()); |
| | | } |
| | | } |
| | | if (applyNoSet.isEmpty()) { |
| | | return; |
| | | } |
| | | |
| | | // 2. 䏿¬¡æ¹éååï¼SQL å
é¨å·²å¸¦ deleted = 0ï¼ã |
| | | // 注æï¼MySQL ç IN () ä¼è¯æ³éè¯¯ï¼æ
å¿
é¡»ä¿è¯å表é空 ââ ä¸é¢å·²å¤ç©ºã |
| | | List<AppointmentDO> appointmentList = appointmentMapper.getByApplyNoList(new ArrayList<>(applyNoSet)); |
| | | |
| | | // 3. æ applyNo 建æ å°ï¼ä¸ªå« applyNo æ¥ä¸å°é¢çº¦åæ¯æ£å¸¸æ
åµï¼åå²èæ°æ®ï¼ï¼è·³è¿å³å¯ã |
| | | Map<String, AppointmentDO> appointmentMap = appointmentList.stream() |
| | | .filter(item -> item != null && item.getApplyNo() != null) |
| | | .collect(Collectors.toMap(AppointmentDO::getApplyNo, item -> item, (a, b) -> a)); |
| | | |
| | | // 4. å
ååå¡«ï¼ä¸åéæ¡æ¥åº |
| | | queueDOList.forEach(queueDO -> { |
| | | if (null == queueDO.getApplyNo() || queueDO.getApplyNo().isEmpty()) { |
| | | if (queueDO == null || queueDO.getApplyNo() == null || queueDO.getApplyNo().isEmpty()) { |
| | | return; |
| | | } |
| | | AppointmentDO appointment = appointmentMapper.getByApplyNo(queueDO.getApplyNo()); |
| | | AppointmentDO appointment = appointmentMap.get(queueDO.getApplyNo()); |
| | | if (null == appointment) { |
| | | return; |
| | | } |
| | |
| | | |
| | | public void closeBiz() { |
| | | queueServiceTxFunctions.setOpeningFlag(0); |
| | | |
| | | // ãæ¬æ¬¡éæ±ãéè¯æ¶æ¸
空å½çå·¥ä½ï¼doc_id / doc_name 置空ï¼ç¶ææ¹å空é²ï¼ã |
| | | // |
| | | // èæ¯ï¼å·¥ä½ä¸åå ã空é²è¶
æ¶ / 令ç失æ / å·æ°é¡µé¢ãè¢«éæ¾ï¼é¿å
å»ç离å¼ä¸ä¼å¿å°±ä¸¢å·¥ä½ï¼ï¼ |
| | | // å æ¤éè¦ä¸ä¸ªå
åº ââ æ¯å¤©éè¯æ¶ç»ä¸æ¸
空ï¼é²æ¢å»çä¸çå¿ç¦»åº§å¯¼è´å·¥ä½é¿æè¢«å ç¨ã |
| | | // å
æ¸
åºï¼åç±ä¸é¢ç startBedReload() æåºéæ°è£
è½½å
åï¼ä¿è¯äºè
ä¸è´ã |
| | | try { |
| | | queueServiceTxFunctions.closeBizClearBeds(); |
| | | } catch (Exception e) { |
| | | // æ¸
空失败ä¸è½é»æéè¯æµç¨æ¬èº« |
| | | log.error("[éè¯] æ¸
空å½çå·¥ä½å¤±è´¥ï¼ä¸å½±åéè¯ï¼", e); |
| | | } |
| | | |
| | | startBedReload(); |
| | | } |
| | | |
| | |
| | | // ä¼å¨ HurryUpOnBed éé¢å¤ç æ£æ¥é¡¹ç®.äº²åæ§ |
| | | |
| | | startHurryUpOneBed(roomId, bedNo); |
| | | |
| | | // ãè¯æãè¡¥äººå¾ªç¯æä¸éé¨é¸ï¼æªå¼è¯ / 已忢åè¯ / åè¯åºå·²æ»¡ï¼ï¼ |
| | | // 任䏿¡æç«æ¶æ£è
ä¼**åå¨ãå·²å¬å(15)ãä¸è¿åè¯åº**ã |
| | | // ç°å¨ nextPatient æ¯æç´æ¥ä»ãå·²å¬åãå«å·ï¼2026-10-29 ä¿®å¤ï¼ï¼è¿éåªè¡¥ä¸æ¡æ¥å¿æ¹ä¾¿ç°åºææ¥ã |
| | | if (null != updateNum && updateNum > 0) { |
| | | try { |
| | | QueueDO stillRecalled = queueMapper.getBedQueueItemByPatAndStatus( |
| | | roomId, bedNo, patId, checkType, QueueStatusEnum.RECALLED.getStatus()); |
| | | if (null != stillRecalled) { |
| | | log.warn("[recallPatient] 已置为ãå·²å¬åãï¼ä½æªè¿å
¥åè¯åº" |
| | | + "ï¼å¯è½åå ï¼æªå¼è¯ / 已忢åè¯ / åè¯åºå·²æ»¡ï¼ï¼å«å·æ¶å°ç´æ¥ä»ãå·²å¬åãå人. " |
| | | + "å·¥ä½={}/{} patId={} seqNum={}", |
| | | roomId, bedNo, patId, stillRecalled.getSeqNum()); |
| | | } |
| | | } catch (Exception e) { |
| | | log.warn("[recallPatient] æ£æ¥ãå·²å¬åãæ¯å¦è¿å
¥åè¯åºæ¶å¼å¸¸ï¼ä¸å½±åå¬åç»æï¼. å·¥ä½={}/{} patId={}", |
| | | roomId, bedNo, patId, e); |
| | | } |
| | | } |
| | | return updateNum; |
| | | } |
| | | |
| | |
| | | queueStatusList.add(QueueStatusEnum.AFFINITY.getStatus()); |
| | | List<QueueDO> queueDOList = getBedQueueByStatus(roomId, bedNo, queueStatusList); |
| | | |
| | | //æ [亲åç] æªå°ä¸»é¡¹åé¢ |
| | | //æ [亲åç] æªå°ä¸»é¡¹åé¢ï¼åæéå· + 忣è
æç®ä¸ç»ï¼è§ Utils#insertAffinityItemsAfterMainï¼ |
| | | List<QueueDO> affinityWaitingList = new ArrayList<>(); |
| | | ListIterator<QueueDO> iterator = queueDOList.listIterator(); |
| | | while (iterator.hasNext()) { |
| | |
| | | affinityWaitingList.add(item); |
| | | } |
| | | } |
| | | affinityWaitingList.forEach(affinityWaitingItem -> { |
| | | for (int i = queueDOList.size() - 1; i >= 0; i--) { |
| | | if (affinityWaitingItem.getSeqNum() == queueDOList.get(i).getSeqNum()) { |
| | | queueDOList.add(i + 1, affinityWaitingItem); |
| | | break; |
| | | } |
| | | } |
| | | }); |
| | | Utils.insertAffinityItemsAfterMain(queueDOList, affinityWaitingList); |
| | | |
| | | return queueDOList; |
| | | } |
| | |
| | | // |
| | | // èæ¯ï¼ä¸é¢ä¸¤å¤æ¥è¯¢çæ¡ä»¶æ¯ `room_id = ? AND status IN (...)` |
| | | // ï¼getRoomQueueByStatus çè³**ä¸å« bed_no**ï¼ï¼**å®å
¨ä¸ç book_check_type**ã |
| | | // èèªå¨åæµï¼preemptWaitingPatientWithBedCheckTypesï¼æ¯**æå·¥ä½ checkTypes è¿æ»¤**çï¼ |
| | | // èèªå¨åæµï¼QueueMapper#getFirstWaitingByCheckTypes + preemptWaitingPatientByIdï¼æ¯**æå·¥ä½ checkTypes è¿æ»¤**çï¼ |
| | | // æä»¥åªæ"äººå·¥ææ£è
æè¿æ¥"è¿æ¡è·¯å¾ä¼æ¼ ââ 表ç°ä¸º |
| | | // ã设å¤é¢ç¨ã页é误åºç°å¸¸è§å¿çµå¾(100)ãå¹³æ¿è¿å¨å¿çµ(400)ç**ä¸éé¢ç¨è®¾å¤**çæ£è
ã |
| | | // |
| | |
| | | // æ
è¿éå¦èµ·ä¸ä¸ª final åéï¼è䏿¯å¤ç¨ä¸é¢ç queueDOListï¼å®å·²è¢«éæ°èµå¼ï¼ã |
| | | final List<QueueDO> installQueueList = queueDOList; |
| | | |
| | | //æ [亲åç] æªå°ä¸»é¡¹åé¢ |
| | | //æ [亲åç] æªå°ä¸»é¡¹åé¢ï¼åæéå· + 忣è
æç®ä¸ç»ï¼è§ Utils#insertAffinityItemsAfterMainï¼ |
| | | List<QueueDO> affinityReceivedList = new ArrayList<>(); |
| | | ListIterator<QueueDO> iterator = installQueueList.listIterator(); |
| | | while (iterator.hasNext()) { |
| | |
| | | affinityReceivedList.add(item); |
| | | } |
| | | } |
| | | affinityReceivedList.forEach(affinityReceivedItem -> { |
| | | for (int i = installQueueList.size() - 1; i >= 0; i--) { |
| | | if (affinityReceivedItem.getSeqNum() == installQueueList.get(i).getSeqNum()) { |
| | | installQueueList.add(i + 1, affinityReceivedItem); |
| | | break; |
| | | } |
| | | } |
| | | }); |
| | | Utils.insertAffinityItemsAfterMain(installQueueList, affinityReceivedList); |
| | | |
| | | return installQueueList; |
| | | } |
| | |
| | | |
| | | |
| | | AtomicInteger openingFlag = new AtomicInteger(0); |
| | | AtomicInteger curSeqNum = new AtomicInteger(0); |
| | | |
| | | // ãå·ç»ä¸ï¼æ¬éæ±ï¼ãå curSeqNumï¼åæµæ¶ç»æ£è
ç¼"å
é¨åºå·"çå
å计æ°å¨ï¼å·²å é¤ã |
| | | // æéå·æ¹ä¸ºç¾å°æ¶ä¸æ¬¡æ§åå
¥ queue.seq_numï¼ä¹åä»»ä½ç¯èé½ä¸åèµå·ï¼ |
| | | // åæµãå«å·åè¡¥é½åè¯ãè¿å·ãå¬åãå æ¥ãè£
æºé½åªæ¹ç¶æ/è¯å®¤/å·¥ä½ã |
| | | |
| | | // ç»´æ¤ å¼æ¾çå·¥ä½ |
| | | ConcurrentHashMap<String, BedBO> mapOpeningBed = new ConcurrentHashMap<>(); |
| | |
| | | return null == bedBO ? null : Boolean.TRUE.equals(bedBO.getStopReady()); |
| | | } |
| | | |
| | | public ErrorCode bedDoctorOn(Long roomId, String bedNo, Long docId, String docName) { |
| | | /** |
| | | * å
¥åº§ï¼æå·¥ä½ä¸»äººè®¾ä¸ºæï¼ã |
| | | * |
| | | * @param bedId å·¥ä½ä¸»é®ï¼å端请æ±é带ï¼**ä¼å
æå®å®ä½**ï¼è§ä¸ï¼ââå¯ä¸ºç©ºï¼ä¸ºç©ºæ¶æ roomId+bedNo å®ä½ |
| | | */ |
| | | public ErrorCode bedDoctorOn(Long roomId, String bedNo, Long docId, String docName, Integer bedId) { |
| | | BedBO bedBO = mapOpeningBed.get( Utils.formatRoomBed(roomId, bedNo) ); |
| | | if (null == bedBO) { |
| | | log.error("bedDoctorOn mapBedVsQueue DONOT existed. " + roomId + " " + bedNo); |
| | | return QUEUE_BED_NOT_EXIST; |
| | | } |
| | | |
| | | // DB update |
| | | List statusList = new ArrayList<BedStatusEnum>(); |
| | | statusList.add(BedStatusEnum.OPENING); |
| | | Integer updateNum = roomMapper.setBedDoctorOn(roomId, bedNo, docId, docName, BedStatusEnum.DOCTOR_ON, statusList); |
| | | // å¯ä»¥"æä¸ºä¸»äºº"çç¶æï¼å·²å¼é / æå»ç / æåï¼**æé¤"å·²å
³é"**ï¼ã |
| | | // ãæ¬æ¬¡æ¾å®½ã忥"æ 主人"æ¶åªè®¤"å·²å¼é"ï¼ä¸æ¦æ°æ®åºç°"doc_id 为空ä½ç¶æä»æ¯æå»ç/æå" |
| | | // è¿ç§ä¸ä¸è´ï¼å»çç«å¨å·¥ä½åå´å§ç»åä¸ä¸ï¼åªæ¥"ç¶æå¼å¸¸"ï¼ç°åºæ ä»å¤çã |
| | | List<BedStatusEnum> claimableStatusList = new ArrayList<>(); |
| | | claimableStatusList.add(BedStatusEnum.OPENING); |
| | | claimableStatusList.add(BedStatusEnum.DOCTOR_ON); |
| | | claimableStatusList.add(BedStatusEnum.DOCTOR_PAUSE); |
| | | |
| | | // ãæ¬æ¬¡ä¿®å¤ãä¼å
æ**主é®**æ´æ°ï¼ç°åºåºç°è¿"å·¥ä½å¨åºéææç©ºé²ãå
¥åº§å´æ´æ° 0 è¡"ï¼ |
| | | // å·²æé¤"被å ç¨"ï¼å©ä¸çå¯è½æ¯ bed_no ä¸è¯·æ±å¼æèç¼é¾è¾¨çå·®å¼ |
| | | // ï¼ç»å°¾ç©ºæ ¼ / 大å°å / å
¨è§ï¼JSON ä¸å¤å¶ç²è´´é½çä¸åºæ¥ï¼ãåç«¯æ¬æ¥å°±å¸¦ idï¼ç¨å®æç¨³ã |
| | | Integer updateNum = null; |
| | | if (null != bedId) { |
| | | updateNum = roomMapper.setBedDoctorOnById(bedId, docId, docName, |
| | | BedStatusEnum.DOCTOR_ON, claimableStatusList); |
| | | if (null != updateNum && updateNum > 0) { |
| | | // æ ¡éªä¸ä¸ id æåçè¡ç¡®å®å°±æ¯è¯·æ±çå·¥ä½ï¼ä¸ä¸è´è¯´æå端ç¼åä¸åºä¸åæ¥ï¼è®°æ¥å¿ä¾¿äºææ¥ï¼ |
| | | RoomDO seatRow = roomMapper.getRoom(roomId, bedNo); |
| | | RoomDO idRow = roomMapper.selectById(bedId); |
| | | if (null != idRow && null != seatRow && !idRow.getId().equals(seatRow.getId())) { |
| | | log.warn("[bedDoctorOn] æ id å
¥åº§æåï¼ä½ id æåçå·¥ä½ä¸è¯·æ±ç roomId/bedNo 䏿¯åä¸è¡ï¼" |
| | | + " id={} â {}/{}, è¯·æ± â {}/{}", |
| | | bedId, idRow.getRoomId(), idRow.getBedNo(), roomId, bedNo); |
| | | } |
| | | } |
| | | } |
| | | if (null == updateNum || 0 == updateNum) { |
| | | // åéï¼æ roomId + bedNo å®ä½ï¼å
¼å®¹ä¸å¸¦ id çè°ç¨æ¹ï¼å¦èªå¨å
¥åº§çèè·¯å¾ï¼ |
| | | updateNum = roomMapper.setBedDoctorOn(roomId, bedNo, docId, docName, |
| | | BedStatusEnum.DOCTOR_ON, claimableStatusList); |
| | | } |
| | | |
| | | if ( null==updateNum || 0 == updateNum ) { |
| | | log.error("bedDoctorOn DB invalid status. " + roomId + " " + bedNo); |
| | | // ä»å¤±è´¥ â æåºé**çå®ç¶æ**æå¼ï¼å¹¶åºååå ï¼åæ¥ä¸å¾"ç¶æå¼å¸¸"ï¼ç°åºçä¸åºæä»¥ç¶ï¼ |
| | | RoomDO rowById = (null == bedId) ? null : roomMapper.selectById(bedId); |
| | | RoomDO rowByRoomBed = roomMapper.getRoom(roomId, bedNo); |
| | | log.warn("[bedDoctorOn] å
¥åº§æ´æ° 0 è¡. è¯·æ± roomId={} bedNo=[{}] bedId={} docId={}ï¼" |
| | | + "æidæ¥å°={} æroomId+bedNoæ¥å°={}", |
| | | roomId, bedNo, bedId, docId, |
| | | null == rowById ? "æ " : describeBedRow(rowById), |
| | | null == rowByRoomBed ? "æ " : describeBedRow(rowByRoomBed)); |
| | | |
| | | RoomDO occupant = (null != rowById) ? rowById : rowByRoomBed; |
| | | if (null != occupant && null != occupant.getDocId() && !occupant.getDocId().equals(docId)) { |
| | | log.warn("[bedDoctorOn] å·¥ä½å·²è¢«ä»äººå ç¨ï¼æç»å
¥åº§ï¼ä¸æ¤æï¼. å ç¨äºº={}({})", |
| | | occupant.getDocName(), occupant.getDocId()); |
| | | return ROOM_OCCUPIED_BY_OTHER; |
| | | } |
| | | return ROOM_INVALID_STATUS; |
| | | } |
| | | |
| | | // ãæ¬éæ±Â·ä¸äººå¤å·¥ä½ãå
¥åº§æåå**ä¸åéæ¾**该å»ççå
¶å®å·¥ä½ï¼ |
| | | // è忥å¼çæ¶ä¸ä½å»çå¯è½åæ¶å ãæ£æ¥å·¥ä½ + é¢ç¨å·¥ä½ + è£
æºå·¥ä½ãï¼ |
| | | // ç±å端ãæçå·¥ä½ã䏿å¨åå·¥ä½é´åæ¢ï¼åæä½ä»ç± @RequireBedOwner æå·¥ä½ doc_id æ ¡éªï¼ã |
| | | // åå®ç°ï¼roomMapper.releaseOtherBedsOfDoc(docId, roomId, bedNo, BedStatusEnum.OPENING); |
| | | // å·¥ä½éæ¾æ¹ä¸ºä¸ç§æç¡®éå¾ï¼â å»çç¹ã离座ãï¼â¡ éè¯ç»ä¸æ¸
空ï¼â¢ 管çåãæ¸
空工ä½ã/æ¥çå»çãæ¥ç®¡ãã |
| | | |
| | | bedBO.setStatus(BedStatusEnum.DOCTOR_ON.getStatus()); |
| | | addBedToRoutingQueue(bedBO); |
| | | return GlobalErrorCodeConstants.SUCCESS; |
| | | } |
| | | |
| | | /** |
| | | * æå·¥ææä½ãæéä¸ãæ£è
æå
¥æå®å·¥ä½ï¼å·¥ä½å°"æ¬è¯å®¤æéä¸ï¼æªåé
ï¼"ååºçãæå
¥ãæé®ï¼ã |
| | | * |
| | | * <p>ä¸èªå¨åæµï¼{@code hurryupOneCheckType}ï¼èµ°**åä¸å¥**å¨ä½ï¼ |
| | | * æ¡ä»¶æ´æ°ãæéä¸(10) â åå¤ä¸(20)ãå¹¶æ room/bed åææ¬å·¥ä½ï¼ç¶åå¤ç亲å项ã |
| | | * å·ä¸åï¼å·å¨ç¾å°æ¶å·²å®ï¼ã |
| | | * |
| | | * <p>ä¸éæ ¡éªï¼å·¥ä½åå¨ â 该è¡ä»æ¯ãæéä¸ãâ æ£æ¥é¡¹ç®å¨æ¬å·¥ä½å¼å±èå´å
ã |
| | | * æ¡ä»¶æ´æ°èªå¸¦å¹¶åä¿æ¤ï¼ä¸¤ä¸ªå·¥ä½åæ¶ç¹ãæå
¥ãï¼åªæä¸ä¸ªè½æåã |
| | | */ |
| | | public ErrorCode pullWaitingPatient(Long roomId, String bedNo, Integer queueId) { |
| | | RoomDO bed = (null == roomId || null == bedNo) ? null : roomMapper.getRoom(roomId, bedNo); |
| | | if (null == bed) { |
| | | log.warn("[pullWaitingPatient] å·¥ä½ä¸åå¨. roomId={} bedNo={}", roomId, bedNo); |
| | | return QUEUE_BED_NOT_EXIST; |
| | | } |
| | | |
| | | QueueDO item = (null == queueId) ? null : queueMapper.selectById(queueId); |
| | | if (null == item) { |
| | | log.warn("[pullWaitingPatient] æéè¡ä¸åå¨. queueId={}", queueId); |
| | | return QUEUE_NOT_EXISTS; |
| | | } |
| | | if (!QueueStatusEnum.WAITING.getStatus().equals(item.getStatus())) { |
| | | log.warn("[pullWaitingPatient] 该æ£è
å·²ä¸å¨æéä¸. queueId={} patId={} status={}", |
| | | queueId, item.getPatId(), item.getStatus()); |
| | | return QUEUE_NOT_WAITING; |
| | | } |
| | | Integer[] bedCheckTypes = bed.getCheckTypes(); |
| | | if (null == bedCheckTypes || 0 == bedCheckTypes.length |
| | | || null == item.getBookCheckType() |
| | | || !java.util.Arrays.asList(bedCheckTypes).contains(item.getBookCheckType())) { |
| | | log.warn("[pullWaitingPatient] æ£æ¥é¡¹ç®ä¸å¨æ¬å·¥ä½èå´. queueId={} checkType={} æ¬å·¥ä½={}", |
| | | queueId, null == item ? null : item.getBookCheckType(), java.util.Arrays.toString(bedCheckTypes)); |
| | | return QUEUE_CHECK_TYPE_NOT_MATCH; |
| | | } |
| | | |
| | | Integer updateNum = queueMapper.preemptWaitingPatientById(queueId, roomId, bed.getRoomName(), bedNo, |
| | | QueueStatusEnum.WAITING.getStatus(), QueueStatusEnum.READY.getStatus()); |
| | | if (null == updateNum || 0 == updateNum) { |
| | | log.warn("[pullWaitingPatient] æå
¥æªçæï¼å·²è¢«å
¶ä»å·¥ä½æèµ°ï¼. queueId={}", queueId); |
| | | return QUEUE_NOT_WAITING; |
| | | } |
| | | |
| | | // å
å对象ä¸åºå
ä¿æä¸è´ï¼äº²å项è¦è·é主项çè¯å®¤/å·¥ä½ï¼ |
| | | item.setStatus(QueueStatusEnum.READY.getStatus()); |
| | | item.setRoomId(roomId); |
| | | item.setRoomName(bed.getRoomName()); |
| | | item.setBedNo(bedNo); |
| | | |
| | | try { |
| | | CheckTypeDO checkTypeDO = getCheckTypeItem(item.getBookCheckType()); |
| | | if (null != checkTypeDO && null != checkTypeDO.getAffinityCheckTypes() |
| | | && checkTypeDO.getAffinityCheckTypes().length > 0) { |
| | | procAffinityWhenPreempt(item, checkTypeDO.getAffinityCheckTypes()); |
| | | } |
| | | } catch (Exception e) { |
| | | // 亲å项å¤ç失败ä¸å½±å主项已æåæå
¥ |
| | | log.error("[pullWaitingPatient] 亲å项å¤ç失败ï¼ä¸»é¡¹å·²æå
¥ï¼. queueId={}", queueId, e); |
| | | } |
| | | |
| | | log.info("[pullWaitingPatient] å·²æå·¥æå
¥. roomId={} bedNo={} queueId={} patId={} seqNum={}", |
| | | roomId, bedNo, queueId, item.getPatId(), item.getSeqNum()); |
| | | return GlobalErrorCodeConstants.SUCCESS; |
| | | } |
| | | |
| | | /** æ¼ä¸è¡å·¥ä½å
³é®å段ï¼ä¾æ¥å¿/ææ¥å¿«é对æ¯ï¼å°¤å
¶ç bed_no æ¯å¦ä¸è¯·æ±ä¸è´ï¼ */ |
| | | private String describeBedRow(RoomDO row) { |
| | | return String.format("id=%s,room_id=%s,bed_no=[%s](len=%d),status=%s,doc_id=%s,doc_name=%s", |
| | | row.getId(), row.getRoomId(), row.getBedNo(), |
| | | null == row.getBedNo() ? -1 : row.getBedNo().length(), |
| | | row.getStatus(), row.getDocId(), row.getDocName()); |
| | | } |
| | | |
| | | public ErrorCode bedDoctorOff(Long roomId, String bedNo, Long docId, String docName) { |
| | |
| | | return GlobalErrorCodeConstants.SUCCESS; |
| | | } |
| | | |
| | | /** |
| | | * ãæ¬æ¬¡éæ±ã管çåå¼ºå¶æ¸
空工ä½ï¼ä¸è¦æ±æ¯æ¬äººï¼ã |
| | | * <p> |
| | | * ä¸ {@link #bedDoctorOff} çåºå«ï¼ä¸æ¸
{@code doc_id=?} æ¡ä»¶ï¼ |
| | | * å æ¤å¯æãå«äººå ç¨ä¸ãç工使¸
æ ââ ç¨äºå»çä¸çå¿ç¦»åº§ãæ¢äººä½¿ç¨åä¸å·¥ä½çåºæ¯ã |
| | | * ä»ç¶åªæ¸
ãå»çå¨å² / æåãä¸ doc_id é空çå·¥ä½ï¼ç©ºé²å·¥ä½ä¸ä¼è¢«è¯¯å¨ã |
| | | */ |
| | | public ErrorCode bedDoctorOffByAdmin(Long roomId, String bedNo) { |
| | | BedBO bedBO = mapOpeningBed.get( Utils.formatRoomBed( roomId, bedNo ) ); |
| | | if (null == bedBO) { |
| | | log.error("bedDoctorOffByAdmin mapBedVsQueue DONOT existed. " + roomId + " " + bedNo); |
| | | return QUEUE_BED_NOT_EXIST; |
| | | } |
| | | |
| | | List statusList = new ArrayList<BedStatusEnum>(); |
| | | statusList.add(BedStatusEnum.DOCTOR_ON); |
| | | statusList.add(BedStatusEnum.DOCTOR_PAUSE); |
| | | Integer updateNum = roomMapper.setBedDoctorOffAdmin(roomId, bedNo, BedStatusEnum.OPENING, statusList); |
| | | if ( null==updateNum || 0 == updateNum ) { |
| | | log.error("bedDoctorOffByAdmin DB invalid status. " + roomId + " " + bedNo); |
| | | return ROOM_INVALID_STATUS; |
| | | } |
| | | |
| | | removeBedFromRoutingQueue(bedBO); |
| | | |
| | | bedBO.setStatus(BedStatusEnum.OPENING.getStatus()); |
| | | log.info("[管ç忏
空工ä½] roomId={} bedNo={} 已置为空é²", roomId, bedNo); |
| | | return GlobalErrorCodeConstants.SUCCESS; |
| | | } |
| | | |
| | | /** |
| | | * ãæ¬æ¬¡éæ±ãéè¯æ¸
ç©ºï¼æææãå»çå¨å² / æåãçå·¥ä½ç½®ä¸ºç©ºé²ï¼doc_id / doc_name æ¸
空ï¼ã |
| | | * <p> |
| | | * ä¸ {@link #closeBiz()} é
åï¼å
æ¸
åºï¼éå {@code startBedReload()} 伿åºéæ°è£
è½½å
åï¼ |
| | | * ä¿è¯å
åï¼mapOpeningBed / åæµéåï¼ä¸åºä¸è´ã |
| | | * |
| | | * @return æ¸
空ç工使° |
| | | */ |
| | | public int closeBizClearBeds() { |
| | | List statusList = new ArrayList<BedStatusEnum>(); |
| | | statusList.add(BedStatusEnum.DOCTOR_ON); |
| | | statusList.add(BedStatusEnum.DOCTOR_PAUSE); |
| | | Integer updateNum = roomMapper.clearAllBedDoctors(BedStatusEnum.OPENING, statusList); |
| | | |
| | | // å
ååæ¥ï¼æå·¥ä½ç¶ææ¹å空é²ï¼å¹¶ä»åæµéåæé¤ï¼é¿å
éè¯å仿工ä½è¢«æ´¾æ£è
ï¼ |
| | | // 注æï¼status æ¯ Integer å
è£
ç±»åï¼å¿
é¡»ç¨ equals æ¯è¾ï¼== åªå¨ -128~127 ç¼ååºé´å
å¶ç¶æç«ï¼ |
| | | for (BedBO bedBO : mapOpeningBed.values()) { |
| | | if (Objects.equals(BedStatusEnum.DOCTOR_ON.getStatus(), bedBO.getStatus()) |
| | | || Objects.equals(BedStatusEnum.DOCTOR_PAUSE.getStatus(), bedBO.getStatus())) { |
| | | removeBedFromRoutingQueue(bedBO); |
| | | bedBO.setStatus(BedStatusEnum.OPENING.getStatus()); |
| | | } |
| | | } |
| | | log.info("[éè¯] å·²æ¸
空å½çå·¥ä½ {} 个ï¼doc_id / doc_name 置空ï¼ç¶ææ¹ä¸ºç©ºé²ï¼", |
| | | updateNum == null ? 0 : updateNum); |
| | | return updateNum == null ? 0 : updateNum; |
| | | } |
| | | |
| | | /* 2024.11.11 |
| | | // å¸¸è§ æè
é¢ç¨ æ¶ å»ç åä¸ä¸ä½æ£è
|
| | | public ErrorCode nextPatient(Long roomId, String bedNo) { |
| | |
| | | |
| | | // å¸¸è§ æè
é¢ç¨ æ¶ å»ç åä¸ä¸ä½æ£è
|
| | | public ErrorCode nextPatient(Long roomId, String bedNo) { |
| | | QueueDO firstReadyQueueItem = queueMapper.getBedFirstQueueItemByStatus(roomId, bedNo, QueueStatusEnum.READY.getStatus()); |
| | | // è¯¥å·¥ä½ æ²¡æ [åè¯ä¸ä¸] 人å |
| | | if (null == firstReadyQueueItem) { |
| | | // ⪠ãå¹¶åå åºÂ·æ¬éæ±ãæ¬å·¥ä½**å·²æãå°±è¯ä¸(30)ãæ£è
æ¶ä¸åå«ä¸ä¸ä½**ã |
| | | // |
| | | // åå
è¿ä¸ªå¤æåªå¨ `QueueServiceImpl#finishNextPatient` éåè¿ï¼èå®ä½äº |
| | | // singleThreadExecutor 串è¡åº**ä¹å¤**ï¼ä¸¤ä¸ªå¹¶å请æ±ï¼åå» / å¤ç«¯ï¼é½å¯è½è¯»å° 0ï¼ |
| | | // éååèªæäº¤ä¸æ¬¡ nextPatientï¼ä¸²è¡æ§è¡æ¶ä¼åæ¨è¿ä¸æ¡ READY â |
| | | // åä¸å·¥ä½åºç° 2 个ãå°±è¯ä¸ãï¼æ£è
被"å¡"å¨å°±è¯ä¸ãå·¥ä½ä¹ä¸å补人ã |
| | | // è¿éå¨ä¸²è¡åºå
åå¤ä¸æ¬¡ï¼æ¬æ¹æ³åªç±è¯¥ä¸²è¡çº¿ç¨æ± è°ç¨ï¼ã |
| | | List<Integer> onstageStatusList = new ArrayList<>(); |
| | | onstageStatusList.add(QueueStatusEnum.ONSTAGE.getStatus()); |
| | | Integer onstageNum = queueMapper.bedQueueStatisticByStatus(roomId, bedNo, onstageStatusList); |
| | | if (null != onstageNum && onstageNum > 0) { |
| | | log.warn("[nextPatient] æ¬å·¥ä½å·²æ {} 个ãå°±è¯ä¸ãæ£è
ï¼è·³è¿æ¬æ¬¡å«å·ï¼é²å¹¶ååå°±è¯ä¸ï¼. å·¥ä½={}/{}", |
| | | onstageNum, roomId, bedNo); |
| | | return GlobalErrorCodeConstants.SUCCESS; |
| | | } |
| | | |
| | | // â åè¯ä¸(20) ä¼å
|
| | | QueueDO firstQueueItem = queueMapper.getBedFirstQueueItemByStatus( |
| | | roomId, bedNo, QueueStatusEnum.READY.getStatus()); |
| | | boolean fromRecalled = false; |
| | | |
| | | // â¡ åè¯åºæ²¡äººæ¶ï¼åéåãå·²å¬å(15)ãéå·æå°çä¸ä½ |
| | | // |
| | | // ã缺é·ä¿®å¤ãè¿å·æ£è
"å¬å"åä¼å
置为 RECALLED(15)ï¼åé hurryupOneBed çè¡¥äººå¾ªç¯ |
| | | // æåæ READY(20)ãä½è¡¥äººå¾ªç¯æä¸éé¨é¸ï¼openingFlag=0 / stopReady=true / åè¯åºå·²æ»¡ï¼ï¼ |
| | | // 任䏿¡æç«æ£è
å°±**ä¸ç´åå¨ 15**ï¼èå«å·æ¤ååªè®¤ READY â åºç°æ»ç»ï¼ |
| | | // ç°åºè¡¨ç°ä¸º"æéå· A2/A3 ç¶ææ¯å·²å¬åï¼ç¹å«å·å è½½ä¸åºæ£è
ä¿¡æ¯ï¼æ æ³æ£æ¥"ï¼2026-10-29 åé¦ï¼ã |
| | | // è¿éæä¸ nextInstallPatientï¼å·²å« RECALLED_INSTALLï¼ä¸è´çæè·¯ç´æ¥å«å°ï¼ |
| | | // ä¸åä¾èµè¡¥äººæ¯å¦æåã |
| | | if (null == firstQueueItem) { |
| | | firstQueueItem = queueMapper.getBedFirstQueueItemByStatus( |
| | | roomId, bedNo, QueueStatusEnum.RECALLED.getStatus()); |
| | | fromRecalled = null != firstQueueItem; |
| | | if (fromRecalled) { |
| | | log.info("[nextPatient] åè¯åºæ äººï¼æ¹å«ãå·²å¬åãæ£è
. å·¥ä½={}/{} patId={} seqNum={}", |
| | | roomId, bedNo, firstQueueItem.getPatId(), firstQueueItem.getSeqNum()); |
| | | } |
| | | } |
| | | |
| | | // è¯¥å·¥ä½æ¢æ²¡æ [åè¯ä¸] 乿²¡æ [å·²å¬å] 人å |
| | | if (null == firstQueueItem) { |
| | | return QUEUE_NOT_READY_PATIENT; |
| | | } |
| | | |
| | | // QueueStatusEnum.READY => QueueStatusEnum.ONSTAGE |
| | | firstReadyQueueItem.setStatus(QueueStatusEnum.ONSTAGE.getStatus()); |
| | | queueMapper.updateById( firstReadyQueueItem ); |
| | | // ⢠READY / RECALLED => ONSTAGEï¼ç¨ãä¸»é® + å½åç¶æãæ¡ä»¶æ´æ°ï¼å¹¶åå åºï¼ï¼ |
| | | // 0 è¡è¯´æè¯¥è¡å·²è¢«å¦ä¸è¯·æ±æ¨è¿ï¼æ¬æ¬¡æ¾å¼ï¼ä¸æ¬¡ååï¼ã |
| | | int curStatus = fromRecalled |
| | | ? QueueStatusEnum.RECALLED.getStatus() : QueueStatusEnum.READY.getStatus(); |
| | | Integer updated = queueMapper.updateStatusByIdIfCurrent( |
| | | firstQueueItem.getId(), curStatus, QueueStatusEnum.ONSTAGE.getStatus()); |
| | | if (null == updated || 0 == updated) { |
| | | log.warn("[nextPatient] åè¯è¡å·²è¢«å¹¶åæ¨è¿ï¼æ¾å¼æ¬æ¬¡å«å·. å·¥ä½={}/{} queueId={} ææç¶æ={}", |
| | | roomId, bedNo, firstQueueItem.getId(), curStatus); |
| | | return QUEUE_NOT_READY_PATIENT; |
| | | } |
| | | firstQueueItem.setStatus(QueueStatusEnum.ONSTAGE.getStatus()); |
| | | |
| | | // åæµéåä¸ è¯¥å·¥ä½ ãåè¯ä¸ãæ£è
æ°é åä¸ |
| | | BedBO bo = mapOpeningBed.get( Utils.formatRoomBed( roomId, bedNo ) ); |
| | | bo.readyPatNum--; // å¯è½å·²ç»å¨ hurry-up 䏿¹åäºå¼ |
| | | |
| | | refreshBedPriorityLevelInRoutingQueue(bo); |
| | | // 注æï¼å¬åçè¿ä½æ¬æ¥å°±ä¸å¨åè¯è®¡æ°éï¼ä¸è½åï¼å¦å¤ bo å¯è½ä¸º nullï¼å·¥ä½ä¸å¨å¼è¯å表ï¼ï¼ |
| | | // åå®ç°ç´æ¥ bo.readyPatNum-- ä¼ NPEã |
| | | BedBO bo = mapOpeningBed.get(Utils.formatRoomBed(roomId, bedNo)); |
| | | if (null != bo) { |
| | | if (!fromRecalled) { |
| | | bo.readyPatNum--; // å¯è½å·²ç»å¨ hurry-up 䏿¹åäºå¼ |
| | | } |
| | | refreshBedPriorityLevelInRoutingQueue(bo); |
| | | } else { |
| | | log.warn("[nextPatient] å·¥ä½ä¸å¨å¼è¯å表ï¼è·³è¿å
å计æ°ä¸åæµå·æ°. å·¥ä½={}/{}", roomId, bedNo); |
| | | } |
| | | return GlobalErrorCodeConstants.SUCCESS; |
| | | } |
| | | |
| | |
| | | } |
| | | }); |
| | | |
| | | Integer num = queueMapper.getMaxSeqNum(); |
| | | curSeqNum = new AtomicInteger(null == num ? 0 : num); |
| | | |
| | | // ãå·ç»ä¸ï¼æ¬éæ±ï¼ãä¸ååå§åå
å计æ°å¨ curSeqNumï¼ |
| | | // æéå·æ¥èªç¾å°æ¶ç queue.seq_numï¼åæµä¸ååé
å·ã |
| | | return GlobalErrorCodeConstants.SUCCESS; |
| | | } |
| | | |
| | |
| | | * æå»çåè¯çéå塿»¡ |
| | | */ |
| | | public void hurryupOneBed(Long roomId, String bedNo) { |
| | | if (0 == openingFlag.get()) |
| | | if (0 == openingFlag.get()) { |
| | | // ãç°åºææ¥ãæªå¼è¯æ¶**æ´ä¸ªèªå¨è¡¥äººé½æ¯å
³éç**ï¼æéä¸çç
人ä¸ä¼è¢«æ¬è¿åè¯åºï¼ã |
| | | // åå®ç°æ¯éé» returnï¼ç°åºåªè½çå°"人é½å¨ï¼å°±æ¯ä¸è¿æ¥"ï¼æ
è¿éæç¡®è®°ä¸æ¡ã |
| | | log.warn("[补人] ç³»ç»æªå¤äºãå¼è¯ãç¶æï¼openingFlag=0ï¼ï¼è·³è¿èªå¨è¡¥äºº. å·¥ä½={}/{}ï¼å¯å¨çæ§é¡µç¹ãå¼è¯ãï¼", |
| | | roomId, bedNo); |
| | | return; |
| | | } |
| | | |
| | | BedBO bedBO = getBedQueueBO(roomId, bedNo); |
| | | if (null == bedBO) { |
| | | log.warn("[补人] å·¥ä½ä¸å¨ãå·²å¼è¯å·¥ä½ãå表ä¸ï¼è·³è¿. å·¥ä½={}/{}", roomId, bedNo); |
| | | return; |
| | | } |
| | | |
| | | // ãæ¬æ¬¡å åºãç¨åºéççå®åè¯äººæ°æ ¡æ£å
å计æ°ï¼ |
| | | // readyPatNum æ¯å
åå¼ï¼è¥ææ¡è·¯å¾ï¼æ¤é/æ¾å¼/è¿å·çï¼æ²¡åæ¥ï¼å®ä¼èé«ï¼ |
| | | // äºæ¯ "åè¯åºå·²æ»¡" ç夿ä¸ç´æç«ãæ°¸è¿ä¸è¡¥äººï¼èçé¢ä¸åè¯åºå
¶å®æ¯ç©ºçï¼ã |
| | | int realReadyNum = countReadyInDb(roomId, bedNo); |
| | | if (realReadyNum != bedBO.getReadyPatNum()) { |
| | | log.warn("[补人] å
ååè¯äººæ°({}) ä¸åºå
({}) ä¸ä¸è´ï¼å·²æåºå
æ ¡æ£. å·¥ä½={}/{}", |
| | | bedBO.getReadyPatNum(), realReadyNum, roomId, bedNo); |
| | | bedBO.setReadyPatNum(realReadyNum); |
| | | } |
| | | |
| | | // ãéæ±3ãã忢åè¯ãæ¶ä¸åæãå·²å¬åãæ£è
æ¾å
¥åè¯åºã |
| | | // 注æï¼è¿**ä¸å½±å**å·²æåè¯æ£è
被æ£å¸¸å«å·ï¼nextPatient 䏿£æ¥æ¬å¼å
³ï¼ï¼ |
| | |
| | | |
| | | // å¤ç è¿å·-忥 ç人 |
| | | while (!stopReady && bedBO.getReadyPatNum() < bedBO.getMaxReadyPatNum()) { |
| | | // æ¥ç å½åå·¥ä½ æ¯å¦æè¿å·-åæ¥çæ£è
|
| | | Integer updateNum = queueMapper.queueRecalledPatient( |
| | | bedBO.getRoomId(), |
| | | bedBO.getRoomName(), |
| | | bedBO.getBedNo(), |
| | | curSeqNum.get() + 1, // è¿å·åæ¥ï¼æå°å½åçä¸ä¸ä½ |
| | | QueueStatusEnum.RECALLED.getStatus(), // ä¸éè¦å¤ç [å®è£
å¬å], åå : å®è£
å·¥ä½ ä¸è¿å
¥åæµéå |
| | | QueueStatusEnum.READY.getStatus()); |
| | | if (null == updateNum || 0 == updateNum) |
| | | // æ¥ç å½åå·¥ä½ æ¯å¦æãå·²å¬å(15)ãçæ£è
ï¼æéå·æå°çé£ä¸ä½ï¼ |
| | | QueueDO recalledQueueItem = queueMapper.getBedFirstQueueItemByStatus( |
| | | bedBO.getRoomId(), bedBO.getBedNo(), QueueStatusEnum.RECALLED.getStatus()); |
| | | if (null == recalledQueueItem) |
| | | break; |
| | | |
| | | // [è¿å·] æ£è
=> [åè¯ä¸] ï¼å¤ç æ£æ¥é¡¹ç®.äº²åæ§ é»è¾ |
| | | QueueDO recalledQueueItem = queueMapper.getQueueItemBySeqNum(curSeqNum.get() + 1); |
| | | // ãå·ç»ä¸ï¼æ¬éæ±ï¼ãè¿å·å¬å**ä¸åéæéå·**ï¼å·æ¯ç¾å°æ¶å®çï¼ |
| | | // æ£è
æåå·åå°åè¯åºåï¼éæ±ï¼ãç
人è¿å·äºï¼ä¹æçãï¼ã |
| | | // æ§å®ç°ï¼seq_num = å½åå·+1ï¼æå°éå°¾ï¼ä¼è®©ä»ä¸å±å¹ä¸/æ£è
æéçå·å¯¹ä¸ä¸ã |
| | | // ä¸éè¦å¤ç [å®è£
å¬å], åå : å®è£
å·¥ä½ ä¸è¿å
¥åæµéå |
| | | recalledQueueItem.setStatus(QueueStatusEnum.READY.getStatus()); |
| | | queueMapper.updateById(recalledQueueItem); |
| | | |
| | | // [è¿å·] æ£è
=> [åè¯ä¸] ï¼å¤ç æ£æ¥é¡¹ç®.äº²åæ§ é»è¾ |
| | | CheckTypeDO checkTypeDO = getCheckTypeItem( recalledQueueItem.getBookCheckType() ); |
| | | if ( checkTypeDO.getAffinityCheckTypes().length > 0) { |
| | | procAffinityWhenRecalled(recalledQueueItem, checkTypeDO.getAffinityCheckTypes()); |
| | | } |
| | | |
| | | curSeqNum.getAndIncrement(); |
| | | |
| | | // å¯è½å·²ç»å¨ nextPatient 䏿¹åäºå¼ |
| | | bedBO.readyPatNum++; |
| | |
| | | return; |
| | | |
| | | // æ¥ç æ¯å¦ææéä¸çæ£è
|
| | | Integer updateNum = queueMapper.preemptWaitingPatientWithBedCheckTypes( |
| | | bedBO.getRoomId(), |
| | | bedBO.getRoomName(), |
| | | bedBO.getBedNo(), |
| | | curSeqNum.get() + 1, |
| | | // |
| | | // ãå·ç»ä¸ï¼æ¬éæ±ï¼ãåæµåªåãæéä¸(10) â åè¯ä¸(20)ãçæ¬è¿ï¼**ä¸ååé
æéå·**ï¼ |
| | | // å·å¨ç¾å°æ¶å·²åå
¥ seq_numï¼å æ¥åªå½±åè¿éçå人顺åºï¼SQL å
jump_flag ä¼å
ï¼ã |
| | | // æ§å®ç°æ¯ãUPDATE ... 顺带 seq_num=å½åå·+1ï¼åæå·æ¥å该è¡ãââ |
| | | // å·ä¸åå¯ä¸å"æå·æ¥å"ä¼åéäººï¼æ
æ¹ä¸ºï¼å
åè¡ â æ id æ¡ä»¶æ´æ°ã |
| | | QueueDO preemptQueueItem = queueMapper.getFirstWaitingByCheckTypes( |
| | | QueueStatusEnum.WAITING.getStatus(), |
| | | QueueStatusEnum.READY.getStatus(), |
| | | bedBO.checkTypes); //å
³é®ç¹ å
³é®ç¹ å
³é®ç¹ checkType |
| | | |
| | | // æ²¡ææ¢å°æéæ£è
|
| | | if (null == updateNum || 0 == updateNum) { |
| | | // 没ææéä¸çæ£è
|
| | | if (null == preemptQueueItem) { |
| | | return; |
| | | } |
| | | |
| | | QueueDO preemptQueueItem = queueMapper.getQueueItemBySeqNum(curSeqNum.get() + 1); |
| | | // æ¡ä»¶æ´æ°ï¼status å¿
须仿¯ãæéä¸ãï¼ä¿è¯å¹¶åä¸åªæä¸æ¹æ¢å°è¯¥è¡ |
| | | Integer updateNum = queueMapper.preemptWaitingPatientById( |
| | | preemptQueueItem.getId(), |
| | | bedBO.getRoomId(), |
| | | bedBO.getRoomName(), |
| | | bedBO.getBedNo(), |
| | | QueueStatusEnum.WAITING.getStatus(), |
| | | QueueStatusEnum.READY.getStatus()); |
| | | if (null == updateNum || 0 == updateNum) { |
| | | // 被å
¶å®å·¥ä½æ¢å
ï¼æ¬è½®æ¾å¼ï¼çä¸ä¸æ¬¡è¡¥é½è§¦å |
| | | return; |
| | | } |
| | | |
| | | // å
å对象ä¸åºå
ä¿æä¸è´ ââ 亲å项è¦è·é主项çè¯å®¤/å·¥ä½ |
| | | preemptQueueItem.setStatus(QueueStatusEnum.READY.getStatus()); |
| | | preemptQueueItem.setRoomId(bedBO.getRoomId()); |
| | | preemptQueueItem.setRoomName(bedBO.getRoomName()); |
| | | preemptQueueItem.setBedNo(bedBO.getBedNo()); |
| | | |
| | | CheckTypeDO checkTypeDO = getCheckTypeItem( preemptQueueItem.getBookCheckType() ); |
| | | |
| | | // æ¢å°æéæ£è
åï¼å¤ç æ£æ¥é¡¹ç®.äº²åæ§ é»è¾ |
| | | if ( checkTypeDO.getAffinityCheckTypes().length > 0) { |
| | | procAffinityWhenPreempt(preemptQueueItem, checkTypeDO.getAffinityCheckTypes()); |
| | | } |
| | | |
| | | curSeqNum.getAndIncrement(); |
| | | |
| | | // å¯è½å·²ç»å¨ nextPatient 䏿¹åäºå¼ |
| | | bedBO.readyPatNum++; |
| | |
| | | // ãéæ±3ãã忢åè¯ãçå·¥ä½ä¸åæ°å¢åè¯æ£è
ã |
| | | // å·²æåè¯æ£è
ä»å¯æ£å¸¸å«å·ï¼æ¬æ¹æ³åªè´è´£"è¡¥é½åè¯"ï¼ä¸åä¸å«å·ï¼ã |
| | | if (Boolean.TRUE.equals(bedBO.getStopReady())) { |
| | | // ãç°åºææ¥ãæç¡®è®°ä¸æ¡ï¼å·¥ä½å¼äºã忢åè¯ãæ¶ä¸ä¼èªå¨è¡¥äºº |
| | | log.warn("[补人] å·¥ä½å¤äºã忢åè¯ãï¼è·³è¿èªå¨è¡¥äºº. å·¥ä½={}/{}ï¼å¦éæ¥æ¶è¯·å
³é该å¼å
³ï¼", |
| | | bedBO.getRoomId(), bedBO.getBedNo()); |
| | | return; |
| | | } |
| | | if (bedBO.getReadyPatNum() >= bedBO.getMaxReadyPatNum()) { |
| | | // ãç°åºææ¥ãåè¯åºå·²è¾¾ä¸éï¼ä¸é=忣æ¥é¡¹ç® check_type.ready_num çæå¤§å¼ï¼ |
| | | log.info("[补人] åè¯åºå·²è¾¾ä¸éï¼è·³è¿. å·¥ä½={}/{} å½ååè¯={} ä¸é={}", |
| | | bedBO.getRoomId(), bedBO.getBedNo(), bedBO.getReadyPatNum(), bedBO.getMaxReadyPatNum()); |
| | | refreshBedPriorityLevelInRoutingQueue(bedBO); |
| | | return; |
| | | } |
| | | int pulledNum = 0; |
| | | while (bedBO.getReadyPatNum() < bedBO.getMaxReadyPatNum()) { |
| | | // æ¢å æ¯å¦ææéä¸çæ£è
|
| | | Integer updateNum = queueMapper.preemptWaitingPatientWithBedCheckTypes( |
| | | bedBO.getRoomId(), |
| | | bedBO.getRoomName(), |
| | | bedBO.getBedNo(), |
| | | curSeqNum.get() + 1, |
| | | // |
| | | // ãå·ç»ä¸ï¼æ¬éæ±ï¼ãä¸ hurryupOneCheckType ç¸åï¼åªæ¬è¿ç¶æï¼**ä¸ååé
æéå·**ã |
| | | QueueDO preemptQueueItem = queueMapper.getFirstWaitingByCheckTypes( |
| | | QueueStatusEnum.WAITING.getStatus(), |
| | | QueueStatusEnum.READY.getStatus(), |
| | | bedBO.checkTypes); |
| | | |
| | | // æ²¡ææ¢å°æéæ£è
|
| | | if (null == updateNum || 0 == updateNum) { |
| | | // 没ææéä¸çæ£è
|
| | | if (null == preemptQueueItem) { |
| | | return; |
| | | } |
| | | |
| | | QueueDO preemptQueueItem = queueMapper.getQueueItemBySeqNum(curSeqNum.get() + 1); |
| | | // æ¡ä»¶æ´æ°ï¼status å¿
须仿¯ãæéä¸ãï¼ä¿è¯å¹¶åä¸åªæä¸æ¹æ¢å°è¯¥è¡ |
| | | Integer updateNum = queueMapper.preemptWaitingPatientById( |
| | | preemptQueueItem.getId(), |
| | | bedBO.getRoomId(), |
| | | bedBO.getRoomName(), |
| | | bedBO.getBedNo(), |
| | | QueueStatusEnum.WAITING.getStatus(), |
| | | QueueStatusEnum.READY.getStatus()); |
| | | if (null == updateNum || 0 == updateNum) { |
| | | // 被å
¶å®å·¥ä½æ¢å
ï¼æ¬è½®æ¾å¼ï¼çä¸ä¸æ¬¡è¡¥é½è§¦å |
| | | return; |
| | | } |
| | | |
| | | // å
å对象ä¸åºå
ä¿æä¸è´ ââ 亲å项è¦è·é主项çè¯å®¤/å·¥ä½ |
| | | preemptQueueItem.setStatus(QueueStatusEnum.READY.getStatus()); |
| | | preemptQueueItem.setRoomId(bedBO.getRoomId()); |
| | | preemptQueueItem.setRoomName(bedBO.getRoomName()); |
| | | preemptQueueItem.setBedNo(bedBO.getBedNo()); |
| | | |
| | | CheckTypeDO checkTypeDO = getCheckTypeItem( preemptQueueItem.getBookCheckType() ); |
| | | |
| | | // æ¢å°æéæ£è
åï¼å¤ç æ£æ¥é¡¹ç®.äº²åæ§ é»è¾ |
| | |
| | | procAffinityWhenPreempt(preemptQueueItem, checkTypeDO.getAffinityCheckTypes()); |
| | | } |
| | | |
| | | curSeqNum.getAndIncrement(); |
| | | |
| | | bedBO.readyPatNum++; |
| | | pulledNum++; |
| | | } |
| | | |
| | | if (pulledNum > 0) { |
| | | log.info("[补人] 已补å
¥ {} 人. å·¥ä½={}/{} å½ååè¯={} ä¸é={}", |
| | | pulledNum, bedBO.getRoomId(), bedBO.getBedNo(), |
| | | bedBO.getReadyPatNum(), bedBO.getMaxReadyPatNum()); |
| | | } |
| | | |
| | | // æ¹åäºåæµéåé¡ºåº |
| | | refreshBedPriorityLevelInRoutingQueue(bedBO); |
| | | } |
| | | |
| | | /** åºé该工ä½å½åãåå¤ä¸(20)ãççå®äººæ°ï¼ç¨äºæ ¡æ£å
å计æ°ä¸ç°åºè¯æï¼ */ |
| | | private int countReadyInDb(Long roomId, String bedNo) { |
| | | List<Integer> readyStatus = new ArrayList<>(); |
| | | readyStatus.add(QueueStatusEnum.READY.getStatus()); |
| | | List<QueueDO> readyList = queueMapper.getBedQueueByStatus(roomId, bedNo, readyStatus); |
| | | return null == readyList ? 0 : readyList.size(); |
| | | } |
| | | |
| | | /** |
| | | * ææ£æ¥é¡¹åæµå°è¯å®¤åï¼ä¹å°±æ¯è¿å
¥[åè¯ä¸]åï¼æ [æéä¸] + å
·æäº²åæ§ç æ£æ¥é¡¹ æ¥ä¾éè¯¥æ£æ¥é¡¹ |
| | | * ç«å³è¡¥äººï¼ç°åºèªæ + èªå©è¯æï¼ï¼æå¨è§¦å䏿¬¡è¯¥å·¥ä½çèªå¨åæµï¼å¹¶æ"为ä»ä¹æ²¡è¡¥/è¡¥äºå 人"ä¸èµ·è¿åã |
| | | * |
| | | * <p>ç¨äºå·¥ä½å°åè¯åºä¸ºç©ºæ¶çãç«å³è¡¥äººãæé®ï¼ä¸å¿
ç宿¶ä»»å¡ãä¹ä¸ç¨éå¯å»çæ¯åªéé¨é¸æ¡ä½çã |
| | | */ |
| | | public Map<String, Object> hurryUpNow(Long roomId, String bedNo) { |
| | | Map<String, Object> data = new LinkedHashMap<>(); |
| | | int flag = openingFlag.get(); |
| | | data.put("ç³»ç»å¼è¯ç¶æ", 0 == flag ? "å·²éè¯ï¼æ¤æ¶ä¸ä¼èªå¨è¡¥äººï¼è¯·å
å¨çæ§é¡µç¹ãå¼è¯ãï¼" : "å¼è¯ä¸"); |
| | | |
| | | BedBO bedBO = getBedQueueBO(roomId, bedNo); |
| | | if (null == bedBO) { |
| | | data.put("ç»è®º", "该工ä½ä¸å¨ãå·²å¼è¯å·¥ä½ãå表éï¼å¯è½å·²å
³é/æ¬æ¬¡æªå¼è¯ï¼ï¼æ æ³è¡¥äººï¼è¯·å
å°éå·¥ä½é¡µå
¥åº§æè®©ç®¡çåå¼è¯"); |
| | | log.warn("[补人] hurryUpNow å·¥ä½ä¸åå¨. å·¥ä½={}/{}", roomId, bedNo); |
| | | return data; |
| | | } |
| | | |
| | | boolean stopReady = Boolean.TRUE.equals(bedBO.getStopReady()); |
| | | int before = countReadyInDb(roomId, bedNo); |
| | | int memoryBefore = bedBO.getReadyPatNum(); |
| | | // å
æåºå
çå®å¼æ ¡æ£å
åï¼å
åèé«ä¼å¯¼è´æ°¸ä¹
"已满"ï¼ |
| | | bedBO.setReadyPatNum(before); |
| | | |
| | | data.put("å·¥ä½", bedBO.getRoomName() + " " + bedNo); |
| | | data.put("æ£æ¥é¡¹ç®", null == bedBO.getCheckTypes() ? "[]" : java.util.Arrays.toString(bedBO.getCheckTypes())); |
| | | data.put("忢åè¯", stopReady); |
| | | data.put("åè¯ä¸é", bedBO.getMaxReadyPatNum()); |
| | | data.put("补人ååè¯äººæ°", before + (memoryBefore == before ? "" : "ï¼å
åæ¾ä¸º " + memoryBefore + "ï¼å·²æ ¡æ£ï¼")); |
| | | |
| | | if (0 == flag) { |
| | | data.put("ç»è®º", "ç³»ç»å·²éè¯ï¼æ¬æ¬¡æªè¡¥äººï¼è¯·å
å¨çæ§é¡µç¹ãå¼è¯ã"); |
| | | return data; |
| | | } |
| | | if (stopReady) { |
| | | data.put("ç»è®º", "æ¬å·¥ä½å¼äºã忢åè¯ãï¼æ¬æ¬¡æªè¡¥äººï¼å¦éæ¥æ¶æ£è
请å
³é该å¼å
³"); |
| | | return data; |
| | | } |
| | | |
| | | hurryupOneBed(roomId, bedNo); |
| | | |
| | | int after = countReadyInDb(roomId, bedNo); |
| | | int pulled = Math.max(0, after - before); |
| | | data.put("补人ååè¯äººæ°", after); |
| | | data.put("æ¬æ¬¡è¡¥å
¥", pulled); |
| | | if (pulled > 0) { |
| | | data.put("ç»è®º", "已补å
¥ " + pulled + " 人"); |
| | | } else if (after >= bedBO.getMaxReadyPatNum()) { |
| | | data.put("ç»è®º", "åè¯åºå·²è¾¾ä¸éï¼" + after + "/" + bedBO.getMaxReadyPatNum() + "ï¼ï¼ä¸å补人"); |
| | | } else { |
| | | data.put("ç»è®º", "没æå¹é
æ¬å·¥ä½æ£æ¥é¡¹ç®çãæéä¸ãæ£è
ï¼å¯å°å·¥ä½å°æ¥çãæ¬è¯å®¤æéä¸ï¼æªåé
ï¼ãååºï¼"); |
| | | } |
| | | log.info("[补人] hurryUpNow å·¥ä½={}/{} å={} å={} ç»è®º={}", roomId, bedNo, before, after, data.get("ç»è®º")); |
| | | return data; |
| | | } |
| | | |
| | | /** |
| | | * ææ£æ¥é¡¹åæµå°è¯å®¤åï¼ä¹å°±æ¯è¿å
¥[åè¯ä¸]åï¼æ [æéä¸] + å
·æäº²åæ§ç æ£æ¥é¡¹ æ¥ä¾éè¯¥æ£æ¥é¡¹ã |
| | | * |
| | | * <p>ã亲å项䏿éå·ã亲å项ç®ï¼å䏿£è
ãå¯å¨ä¸ä¸ªå·¥ä½ä¸èµ·åçå¤ä¸ªæ£æ¥é¡¹ï¼å¨åè¯åº |
| | | * <b>è·é主项æ¾ç¤º</b>ï¼è¿éæäº²å项çæéå·æ¹æ**主项çå·**ãå¹¶æ¬å°ä¸»é¡¹æå¨è¯å®¤/å·¥ä½ï¼ |
| | | * çé¢ï¼å·¥ä½å°/è¯é´å±/大å±ï¼æè½æä¸¤è
æå¨ä¸èµ·ã |
| | | * <p>注æè¿**䏿¯**"éæ°èµå·"ï¼å·ä»æ¯ç¾å°æ¶å®çé£ä¸ªï¼åªæ¯äº²å项沿ç¨ä¸»é¡¹çå·ï¼ |
| | | * ä¸"åæµ/å«å·/å¬åä¸åæ¹å·"å¹¶ä¸å²çªã |
| | | */ |
| | | private void procAffinityWhenPreempt(QueueDO preemptQueueItem, Integer[] affinityCheckTypes) { |
| | | List<QueueDO> affinityItems = queueMapper.getCurPatGivenCheckTypesAndStatus( |
| | |
| | | queueItem.setRoomId(preemptQueueItem.getRoomId()); |
| | | queueItem.setRoomName(preemptQueueItem.getRoomName()); |
| | | queueItem.setBedNo(preemptQueueItem.getBedNo()); |
| | | queueItem.setSeqNum( preemptQueueItem.getSeqNum()); // 使ç¨åä¸ä¸ª å
é¨åºå· |
| | | queueItem.setSeqNum( preemptQueueItem.getSeqNum()); // 亲å项沿ç¨ä¸»é¡¹çæéå·ï¼è·éæ¾ç¤ºï¼ |
| | | queueMapper.updateById(queueItem); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * [è¿å·] æ£è
=> [åè¯ä¸] ï¼å¤ç æ£æ¥é¡¹ç®.äº²åæ§ é»è¾ |
| | | * [è¿å·] æ£è
=> [åè¯ä¸] ï¼å¤ç æ£æ¥é¡¹ç®.äº²åæ§ é»è¾ã |
| | | * |
| | | * <p>å¬åæ¶ä¸»é¡¹çå·ä¸åï¼å æ¤åªé让已ç»è·éç亲åé¡¹ä¿æä¸è´ï¼ä¿æåå· â çé¢ä»æå¨ä¸èµ·ï¼ã |
| | | */ |
| | | private void procAffinityWhenRecalled(QueueDO recalledQueueItem, Integer[] affinityCheckTypes) { |
| | | List<QueueDO> affinityItems = queueMapper.getCurPatGivenCheckTypesAndStatus( |
| | | recalledQueueItem.getPatId(), affinityCheckTypes, QueueStatusEnum.AFFINITY.getStatus()); |
| | | for (int i = 0; i < affinityItems.size(); i++) { |
| | | QueueDO queueItem = affinityItems.get(i); |
| | | queueItem.setSeqNum( recalledQueueItem.getSeqNum() ); // [è¿å·] æ£è
=> [åè¯ä¸]ï¼åå
é¨åºå·æ´æ° |
| | | queueItem.setSeqNum( recalledQueueItem.getSeqNum() ); // 亲å项ä¸ä¸»é¡¹ä¿æåä¸ä¸ªå· |
| | | queueMapper.updateById(queueItem); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * å·¥ä½ãåè¯åºå®¹éä¸éã= 该工ä½å¼å±ç**忣æ¥é¡¹ç®** {@code check_type.ready_num} |
| | | * ï¼é¡µé¢å段ï¼ãæ£æ¥ç±»å管çãâãåè¯åå¤äººæ°ãï¼ç**æå¤§å¼**ã |
| | | * |
| | | * <p><b>è¿å 0 表示"ä¸èªå¨åæµ"</b>ï¼æ¤æ¶æéä¸(10) çæ£è
**ä¸ä¼**è¢«ä¸»å¨æ¬è¿åè¯åº(20)ï¼ |
| | | * éè¦å»çå¨åè¯åºç¨ãæå
¥ãæå¨è¡¥äººï¼ç°åºç¡®è®¤çå£å¾ï¼ã |
| | | * |
| | | * <p>ãæ¬æ¬¡å åºã |
| | | * <ul> |
| | | * <li><b>宿¶è¯»åº</b>ï¼åæ¥è¿ä»½é
ç½®åªå¨æå¡å¯å¨æ¶å è½½ä¸æ¬¡ |
| | | * ï¼{@code MySpringEventListener} â {@code initCheckType()}ï¼ï¼ |
| | | * å¨é¡µé¢ä¸æ¹äºãåè¯åå¤äººæ°ãå¿
é¡»**é坿å¡**æçæï¼</li> |
| | | * <li><b>容é</b>ï¼æ£æ¥é¡¹ç®å¨é
ç½®éæ¥ä¸å°ãæ {@code ready_num} 为空 â **è·³è¿å¹¶è®°è¦å**ï¼ |
| | | * ä¸åæ NPEãåå
è¿ä¸ª NPE åçå¨ {@code addBedToRoutingQueue}ï¼å
¥åº§/å¼è¯/éè½½é½ä¼èµ°ï¼ï¼ |
| | | * ä¼è¿å¸¦æå
¥åº§å¼å¤±è´¥ã</li> |
| | | * </ul> |
| | | */ |
| | | private Integer getBedReadyMax(BedBO bedBO) { |
| | | Integer[] checkTypes = bedBO.getCheckTypes(); |
| | | if (null == checkTypes || 0 == checkTypes.length) { |
| | | return 0; |
| | | } |
| | | Map<Integer, CheckTypeDO> fresh = readCheckTypeMapFresh(); |
| | | int ret = 0; |
| | | for (Integer checkType : checkTypes) { |
| | | CheckTypeDO checkTypeDO = mapCheckTypeVsReadyMax.get(checkType); |
| | | CheckTypeDO checkTypeDO = fresh.get(checkType); |
| | | if (null == checkTypeDO) { |
| | | // å
¼å®¹ï¼å®æ¶è¯»å¤±è´¥æ¶åè½å°å¯å¨ç¼åï¼ä¸¤è¾¹é½æ²¡æå°±è·³è¿ï¼ä¸å NPEï¼ |
| | | checkTypeDO = getCheckTypeItem(checkType); |
| | | } |
| | | if (null == checkTypeDO) { |
| | | log.warn("[getBedReadyMax] æ£æ¥é¡¹ç®å¨ check_type éä¸åå¨ï¼è·³è¿ï¼æ 0 计ï¼. checkType={} å·¥ä½={}/{}", |
| | | checkType, bedBO.getRoomId(), bedBO.getBedNo()); |
| | | continue; |
| | | } |
| | | Integer tmp = checkTypeDO.getReadyNum(); |
| | | ret = ret < tmp ? tmp : ret; //ãåè¯ä¸ãæ°é åå¤§å¼ |
| | | if (null == tmp) { |
| | | log.warn("[getBedReadyMax] æ£æ¥é¡¹ç®[åè¯åå¤äººæ°]为空ï¼è·³è¿. checkType={} name={}", |
| | | checkType, checkTypeDO.getName()); |
| | | continue; |
| | | } |
| | | ret = Math.max(ret, tmp); //ãåè¯ä¸ãæ°é åå¤§å¼ |
| | | } |
| | | return ret; |
| | | } |
| | | |
| | | /** |
| | | * 宿¶è¯»åãæ£æ¥é¡¹ç®å¼ â æ£æ¥é¡¹ç®é
ç½®ãæ å°ï¼æ¯æ¬¡è£
é
工使¶è¯»ä¸æ¬¡å
¨è¡¨ï¼æ£æ¥é¡¹ç®åªæåå 个ï¼é级å¾å°ï¼ã |
| | | * è¿æ ·ç®¡çåå¨ãæ£æ¥ç±»å管çãéæ¹äºãåè¯åå¤äººæ°ã**ç«å»çæï¼ä¸ç¨é坿å¡**ã |
| | | * 读åºå¤±è´¥æ¶åè½å°å¯å¨æ¶å è½½çç¼åï¼{@link #initCheckType()}ï¼ã |
| | | */ |
| | | private Map<Integer, CheckTypeDO> readCheckTypeMapFresh() { |
| | | try { |
| | | List<CheckTypeDO> list = checkTypeMapper.simpleCheckTypeList(); |
| | | Map<Integer, CheckTypeDO> map = new HashMap<>(); |
| | | for (CheckTypeDO item : list) { |
| | | if (null != item && null != item.getValue()) { |
| | | map.put(item.getValue(), item); |
| | | } |
| | | } |
| | | return map; |
| | | } catch (Exception e) { |
| | | log.warn("[readCheckTypeMapFresh] 宿¶è¯»æ£æ¥é¡¹ç®å¤±è´¥ï¼æ¹ç¨å¯å¨æ¶ç¼å", e); |
| | | return null == mapCheckTypeVsReadyMax ? new HashMap<>() : mapCheckTypeVsReadyMax; |
| | | } |
| | | } |
| | | |
| | | private void addBedToRoutingQueue(BedBO bedBO) { |
| | |
| | | List<QueueDO> queueDOList = queueMapper.getBedQueueByStatus(bedBO.getRoomId(), bedBO.getBedNo(), queueStatusList); |
| | | bedBO.setMaxReadyPatNum( getBedReadyMax(bedBO) ); |
| | | bedBO.setReadyPatNum( queueDOList.size() ); |
| | | |
| | | // ãç°åºææ¥ãæ"åè¯åºä¸é / å½åäººæ° / æ¥æº"æåºæ¥ï¼ |
| | | // ä¸é=0 表示**ä¸èªå¨åæµ**ï¼æéä¸çæ£è
ä¸ä¼è¢«ä¸»å¨æ¬è¿åè¯åºï¼éå¨åè¯åºæå¨ãæå
¥ãï¼ã |
| | | // ç°åºåé¦è¿"æè¿ä¹å¤æéç
人ï¼ä¸ºä»ä¹æ²¡ä¸»å¨å è½½å°åè¯åº"ï¼ä¸æ¡æ¥å¿å³å¯èªè¯ã |
| | | log.info("[addBedToRoutingQueue] å·¥ä½ {}/{} åè¯ä¸é={} å½ååè¯={} æ£æ¥é¡¹ç®={}" |
| | | + "ï¼ä¸é=忣æ¥é¡¹ç® check_type.ready_num çæå¤§å¼ï¼0=ä¸èªå¨åæµï¼é 工使å¨ãæå
¥ãï¼", |
| | | bedBO.getRoomId(), bedBO.getBedNo(), bedBO.getMaxReadyPatNum(), bedBO.getReadyPatNum(), |
| | | null == bedBO.getCheckTypes() ? "[]" : java.util.Arrays.toString(bedBO.getCheckTypes())); |
| | | |
| | | Integer[] checkTypes = bedBO.getCheckTypes(); |
| | | Arrays.stream(checkTypes).forEach(checkType -> { |
| | |
| | | item.getStatus() == BedStatusEnum.DOCTOR_ON.getStatus() || |
| | | item.getStatus() == BedStatusEnum.DOCTOR_PAUSE.getStatus()) |
| | | .count()); |
| | | // ãæ¬éæ±Â·ç»è®¡æäººåå¹¶ãå¨åº§**å»çæ°**ï¼ä¸äººå¤å·¥ä½æ¶ä¸é¢ç docBedNum 伿工ä½ç´¯è®¡ï¼ |
| | | // è¿éæ doc_id å»éï¼ç»çæ§é¡µä¸ä¸ª"å°åºå 个å»çå¨å²"çææ ã |
| | | List<Integer> seatedStatusList = new ArrayList<>(); |
| | | seatedStatusList.add(BedStatusEnum.DOCTOR_ON.getStatus()); |
| | | seatedStatusList.add(BedStatusEnum.DOCTOR_PAUSE.getStatus()); |
| | | try { |
| | | Integer docNum = roomMapper.countSeatedDoctors(seatedStatusList); |
| | | monitorInfoVO.setDocNum(null == docNum ? 0 : docNum); |
| | | } catch (Exception e) { |
| | | // ç»è®¡å¤±è´¥ä¸å½±åçæ§é¡µå
¶å®æ°æ® |
| | | log.warn("[roomBedStatistic] ç»è®¡å¨åº§å»çæ°å¤±è´¥ï¼ä¸å½±åå
¶å®ææ ï¼", e); |
| | | monitorInfoVO.setDocNum(0); |
| | | } |
| | | monitorInfoVO.setRoutingBedNum( hashSetOperatingBedQueue.size() ); |
| | | monitorInfoVO.setMapBedVsQueue(mapOpeningBed); |
| | | } |
| | |
| | | Integer distributeSeqNoByRule(Integer checkType, Integer timeslot, |
| | | Integer existingSeqNo, boolean urgent); |
| | | |
| | | /** |
| | | * ãæ¬éæ±ãåä¸ï¼ä½å¢å ãæ¯å¦ VIP / 临æ¶å å·ãæ è®°ã |
| | | * |
| | | * <p>ææ¶æ®µé¢çº¦ï¼è§å 2ï¼ä¸ç两æ¡ééï¼ |
| | | * <ul> |
| | | * <li>VIP / å å·æ£è
ï¼**ç´æ¥åæ¬æ®µé¢çå·**ï¼æ¬æ®µé¢ç乿»¡ â æ»é¢çæ± ï¼{@code time_slot=0}ï¼ï¼</li> |
| | | * <li>æ®éæ£è
ï¼æ¬æ®µæ®éå· â æ¬æ®µé¢çå· â æ»é¢çæ± ã</li> |
| | | * </ul> |
| | | * 两æ¡ééæç»é½è½è½å°ãæ»é¢çæ± ãï¼èæ»é¢çæ± **ä¸è®¾ä¸é** â ä¸ä¼åºç°ç¾å°å¤±è´¥ã |
| | | * |
| | | * @param vip æ¯å¦ VIP / 临æ¶å å·ï¼{@code appointment.is_vip=1} æ HIS å æ¥ {@code jjbz=J}ï¼ |
| | | */ |
| | | Integer distributeSeqNoByRule(Integer checkType, Integer timeslot, |
| | | Integer existingSeqNo, boolean urgent, boolean vip); |
| | | |
| | | void initNumber(); |
| | | } |
| | |
| | | validateTimeslotNotDuplicated(createReqVO.getCheckType(), createReqVO.getTimeSlot(), null); |
| | | // æå
¥ |
| | | QueueSequenceDO queueSequence = BeanUtils.toBean(createReqVO, QueueSequenceDO.class); |
| | | if (null == queueSequence.getTimeSlot() || 0 != queueSequence.getTimeSlot()) { |
| | | // ãæ¬éæ±ãå·æ®µèµ·ç¹ / é¢çèµ·ç¹ç±ç³»ç»è®¡ç®ï¼ä¸æ¥åå端éæä¼ å¼ï¼å¦åå·æ®µä¼éå ï¼ |
| | | queueSequence.setQueueSet(null); |
| | | queueSequence.setQueueVipSet(null); |
| | | } |
| | | queueSequenceMapper.insert(queueSequence); |
| | | // ãæ¬éæ±ãæ°å¢/ç¼è¾åç»ä¸éæè¯¥æ£æ¥ç±»åçå·æ®µï¼ä¿è¯"æ®µä¸æ®µé¦å°¾ç¸æ¥"ï¼ |
| | | if (null != createReqVO.getCheckType()) { |
| | | recalcSegmentBounds(createReqVO.getCheckType()); |
| | | } |
| | | // è¿å |
| | | return queueSequence.getId(); |
| | | } |
| | |
| | | updateReqVO.getId()); |
| | | // æ´æ° |
| | | QueueSequenceDO updateObj = BeanUtils.toBean(updateReqVO, QueueSequenceDO.class); |
| | | // ãæ¬éæ±ãèµ·å§åºå·ç±ç³»ç»éæï¼å¿½ç¥åç«¯ä¼ å¼ï¼å端已置为åªè¯»ï¼ |
| | | updateObj.setQueueSet(null); |
| | | updateObj.setQueueVipSet(null); |
| | | queueSequenceMapper.updateById(updateObj); |
| | | if (null != updateReqVO.getCheckType()) { |
| | | recalcSegmentBounds(updateReqVO.getCheckType()); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * ãæ¬éæ±ãæãæ¶æ®µååºãéæææ£æ¥ç±»åçå·æ®µï¼ |
| | | * <pre> |
| | | * 段 iï¼queue_set = ä¸ä¸æ®µç queue_vip_fullï¼é¦æ®µ 0ï¼ |
| | | * queue_full = queue_set + P |
| | | * queue_vip_set = queue_full |
| | | * queue_vip_full = queue_vip_set + V |
| | | * å
¶ä¸ P / V = 该è¡å½åçï¼queue_full - queue_setï¼ãï¼queue_vip_full - queue_fullï¼ï¼ |
| | | * å³å段ç"é¢åº¦"ä¿æä¸åï¼åªæèµ·ç¹ä¸²èµ·æ¥ã |
| | | * </pre> |
| | | * è¿æ ·æ 论æ°å¢/å é¤/ç¼è¾æ¶æ®µï¼é½ä¸ä¼åºç°å·æ®µéå æç©ºæ´éä½ã |
| | | * <p>æ»é¢çæ± ï¼time_slot = 0ï¼ä¸åä¸éæï¼åªæèµ·ç¹å¯¹é½å°æå䏿®µä¹åã |
| | | */ |
| | | private void recalcSegmentBounds(Integer checkType) { |
| | | if (null == checkType) { |
| | | return; |
| | | } |
| | | List<QueueSequenceDO> all = queueSequenceMapper.selectTimeslotByCheckType(checkType); |
| | | if (null == all || all.isEmpty()) { |
| | | return; |
| | | } |
| | | all.sort(Comparator.comparingInt(r -> null == r.getTimeSlot() ? 0 : r.getTimeSlot())); |
| | | |
| | | CheckTypeDO ct = checkTypeMapper.getCheckTypeByValue(checkType); |
| | | |
| | | int cursor = 0; |
| | | int slotCount = 0; |
| | | for (QueueSequenceDO row : all) { |
| | | int slot = null == row.getTimeSlot() ? 0 : row.getTimeSlot(); |
| | | if (0 == slot) { |
| | | continue; // æ»é¢çæ± æååç¬å¤ç |
| | | } |
| | | slotCount++; |
| | | |
| | | // é¢åº¦ï¼å®½ï¼ï¼ä¼å
沿ç¨è¯¥è¡ç°æå·æ®µå®½åº¦ï¼æªç¥/鿣æ¶åéå°æ£æ¥ç±»åé
ç½® |
| | | int p = width(row.getQueueSet(), row.getQueueFull()); |
| | | if (p <= 0) { |
| | | p = (null == ct || null == ct.getTimeslotBookNum()) ? 0 : ct.getTimeslotBookNum(); |
| | | } |
| | | int v = width(row.getQueueFull(), row.getQueueVipFull()); |
| | | if (v < 0) { |
| | | v = (null == ct || null == ct.getTimeslotReservedNum()) ? 0 : ct.getTimeslotReservedNum(); |
| | | } |
| | | |
| | | QueueSequenceDO update = new QueueSequenceDO(); |
| | | update.setId(row.getId()); |
| | | update.setQueueSet(cursor); |
| | | update.setQueueFull(cursor + p); |
| | | update.setQueueVipSet(cursor + p); |
| | | update.setQueueVipFull(cursor + p + v); |
| | | // 游æ åª**䏿¬**å°å·æ®µèµ·ç¹ï¼ç»ä¸**ä¸è°**ï¼ |
| | | // ä¸è°ä¼è®©å·²ååºçå·è¢«å次ååºï¼éå·ï¼ãè¥æ¸¸æ å·²è¶
è¿ä¸éï¼è¯´æè¯¥æ®µå·²è¶
åï¼ |
| | | // åå·æ¶èªç¶ä¼è½å°ãé¢çå· â æ»é¢çæ± ãã |
| | | update.setQueueNo(raiseAtLeast(row.getQueueNo(), cursor)); |
| | | update.setQueueVipNo(raiseAtLeast(row.getQueueVipNo(), cursor + p)); |
| | | queueSequenceMapper.updateById(update); |
| | | |
| | | cursor = cursor + p + v; |
| | | } |
| | | |
| | | // æ»é¢çæ± ï¼èµ·ç¹å¯¹é½å°æå䏿®µä¹å |
| | | QueueSequenceDO pool = queueSequenceMapper.selectTotalPool(checkType); |
| | | if (null != pool) { |
| | | int poolFull = Math.max(null == pool.getQueueVipFull() ? 0 : pool.getQueueVipFull(), cursor); |
| | | QueueSequenceDO update = new QueueSequenceDO(); |
| | | update.setId(pool.getId()); |
| | | update.setQueueVipSet(cursor); |
| | | update.setQueueVipFull(poolFull); |
| | | update.setQueueVipNo(raiseAtLeast(pool.getQueueVipNo(), cursor)); |
| | | queueSequenceMapper.updateById(update); |
| | | } |
| | | log.info("[recalcSegmentBounds] å·²éæå·æ®µ. checkType={} 段æ°={} æ«å°¾æå¤§å·={}", |
| | | checkType, slotCount, cursor); |
| | | } |
| | | |
| | | /** å·æ®µå®½åº¦ï¼ç»æ¢ - èµ·å§ï¼ï¼ä»»ä¸ä¸º null è¿å -1 表示"æªç¥" */ |
| | | private int width(Integer from, Integer to) { |
| | | if (null == from || null == to) { |
| | | return -1; |
| | | } |
| | | return to - from; |
| | | } |
| | | |
| | | /** |
| | | * 游æ åªä¸æ¬ãä¸ä¸è°ï¼ä¸è°ä¼å¯¼è´å·²ååºçå·è¢«å次ååº â éå·ï¼ã |
| | | */ |
| | | private Integer raiseAtLeast(Integer value, int min) { |
| | | int v = null == value ? min : value; |
| | | return Math.max(v, min); |
| | | } |
| | | |
| | | /** |
| | |
| | | @Override |
| | | public void deleteQueueSequence(Integer id) { |
| | | // æ ¡éªåå¨ |
| | | validateQueueSequenceExists(id); |
| | | QueueSequenceDO exist = queueSequenceMapper.selectById(id); |
| | | if (null == exist) { |
| | | throw exception(QUEUE_SEQUENCE_NOT_EXISTS); |
| | | } |
| | | // å é¤ |
| | | queueSequenceMapper.deleteById(id); |
| | | // ãæ¬éæ±ãå é¤åéæå·æ®µï¼å¦ååç»æ¶æ®µçèµ·ç¹ä¼ç空æ´ï¼ |
| | | recalcSegmentBounds(exist.getCheckType()); |
| | | } |
| | | |
| | | private void validateQueueSequenceExists(Integer id) { |
| | |
| | | @Override |
| | | @Transactional |
| | | public Integer distributeSeqNo(Integer checkType, Integer timeslot) { |
| | | // ãæ¬éæ±ï¼ææ¶æ®µé¢çº¦ãæ®éæ£è
ä¸çº§åå·ï¼**ä¸å跨段åå·**ï¼ |
| | | // â æ¬æ¶æ®µæ®éå·ï¼queue_no < queue_fullï¼ |
| | | // â¡ æ¬æ¶æ®µé¢çå·ï¼queue_vip_no < queue_vip_fullï¼ |
| | | // ⢠æ»é¢çæ± ï¼time_slot=0ï¼**ä¸è®¾ä¸é**ï¼ |
| | | // ä»»ä½ä¸çº§æåå³è¿åï¼â¢ æ°¸ä¸å¤±è´¥ â ä¸åå¨"ç¾ä¸ä¸"ã |
| | | // æ é¢çº¦æ¶æ®µï¼timeslot 为 null/0/åå
¸å¤çå¼ï¼æ¶ â â¡ èªç¶æ¥ä¸å°è¡ï¼ç´æ¥è½å° â¢ã |
| | | |
| | | // â æ¬æ®µæ®éå· |
| | | Integer curSeqNo = queueSequenceMapper.selectQueueNoForUpdate(checkType, timeslot); |
| | | if (null == curSeqNo) { |
| | | // ãä¿®å¤ãæ¶æ®µä¸å
¨/å·²æ»¡å¯¼è´æ²¡æ³ç¾å°ãã |
| | | // åé»è¾ï¼åªå"åå
¸éçç´§é»ä¸ä¸ä¸ªæ¶æ®µ"ï¼ä¸è¦æ±è¯¥æ¶æ®µå¨ queue_sequence ä¸åå¨ã |
| | | // ç°å®é®é¢ï¼å®æµï¼ï¼ |
| | | // · åå
¸ ecg_book_timeslot æ 21 ä¸ªæ¶æ®µï¼ä½ queue_sequence ä¸ checkType=400 |
| | | // åªæ 13 个ãcheckType=100 åªæ 17 个 ââ é¨åæ¶æ®µæ ¹æ¬æ²¡æå·æ± è¡ï¼ |
| | | // · HIS ä¼ä¸å 60 åéç²åº¦ç bookTimeslotï¼å¦ 10001100ï¼ï¼åå
¸é没æè¯¥å¼ï¼ |
| | | // getNextTimeSlot ç´æ¥ return nullï¼ |
| | | // · ä¸ªå«æ¶æ®µå®¹éå¾å°ï¼å¹³æ¿è¿å¨ timeslot_book_num=3ï¼ï¼å¾å¿«éå®ã |
| | | // ä¸è
ä»»ä¸å½ä¸ â æ QUEUE_SEQUENCE_TIMESLOT_FULL â **æ£è
没æ³ç¾å°**ã |
| | | // |
| | | // ç°å¨æ¹ä¸ºï¼**ååæå¤æ¾ N ä¸ªæ¶æ®µï¼å第ä¸ä¸ªä»æä½éç**ï¼ä¸é¢ findAvailableTimeslot å
å®ç°ï¼ï¼ |
| | | // 大å¹
éä½"å ä¸ªå«æ¶æ®µç¼ºå¤±/已满就ç¾å°å¤±è´¥"çæ¦çï¼ç¡®å®é½æ»¡äºææéã |
| | | Integer nextTimeslot = findAvailableTimeslot(checkType, timeslot, false); |
| | | if (null == nextTimeslot) { |
| | | log.error("[distributeSeqNo] è¯¥æ£æ¥ç±»ååå {} ä¸ªæ¶æ®µå
åæ å¯åå·æ¶æ®µ. checkType={} timeslot={}", |
| | | MAX_TIMESLOT_LOOKAHEAD, checkType, timeslot); |
| | | throw exception(QUEUE_SEQUENCE_TIMESLOT_FULL); |
| | | if (null != curSeqNo) { |
| | | Integer updateNum = queueSequenceMapper.updateGivenCheckTypeTimeslotSeqNo(checkType, timeslot, curSeqNo); |
| | | if (null != updateNum && updateNum > 0) { |
| | | return curSeqNo + 1; |
| | | } |
| | | |
| | | curSeqNo = queueSequenceMapper.selectQueueNoForUpdate(checkType, nextTimeslot); |
| | | if (null == curSeqNo) { |
| | | // æ¢æµä¸åå·ä¹é´è¢«å¹¶åæ¢ç©ºï¼ä¿å®æ¥éï¼ç±å端æç¤ºéæ°ç¾å°ï¼ |
| | | log.warn("[distributeSeqNo] æ¢æµå°çæ¶æ®µéå³è¢«å 满. checkType={} timeslot={}", |
| | | checkType, nextTimeslot); |
| | | throw exception(QUEUE_SEQUENCE_TIMESLOT_FULL); |
| | | } |
| | | |
| | | Integer updateRowNum = queueSequenceMapper.updateGivenCheckTypeTimeslotSeqNo(checkType, nextTimeslot, curSeqNo); |
| | | if (null == updateRowNum || updateRowNum == 0) { |
| | | throw exception(QUEUE_SEQUENCE_TIMESLOT_EXCEPTION); |
| | | } |
| | | |
| | | } else { |
| | | Integer updateRowNum = queueSequenceMapper.updateGivenCheckTypeTimeslotSeqNo(checkType, timeslot, curSeqNo); |
| | | if (null == updateRowNum || updateRowNum == 0) { |
| | | throw exception(QUEUE_SEQUENCE_TIMESLOT_EXCEPTION); |
| | | } |
| | | // å¹¶å被æ¢ç©º â è½å° â¡ |
| | | log.info("[distributeSeqNo] æ¬æ®µæ®éå·å¹¶å被æ¢ç©ºï¼é级å°é¢çå·. checkType={} timeslot={}", checkType, timeslot); |
| | | } |
| | | |
| | | return curSeqNo + 1; |
| | | } |
| | | // â¡ æ¬æ®µé¢çå· |
| | | Integer curVipNo = queueSequenceMapper.selectQueueVipNoForUpdate(checkType, timeslot); |
| | | if (null != curVipNo) { |
| | | Integer updateNum = queueSequenceMapper.updateGivenCheckTypeTimeslotVipSeqNo(checkType, timeslot, curVipNo); |
| | | if (null != updateNum && updateNum > 0) { |
| | | log.info("[distributeSeqNo] æ®éå·å·²æ»¡ï¼æ¹åæ¬æ®µé¢çå·. checkType={} timeslot={} seqNo={}", |
| | | checkType, timeslot, curVipNo + 1); |
| | | return curVipNo + 1; |
| | | } |
| | | log.info("[distributeSeqNo] æ¬æ®µé¢çå·å¹¶å被æ¢ç©ºï¼éçº§å°æ»é¢çæ± . checkType={} timeslot={}", checkType, timeslot); |
| | | } |
| | | |
| | | // ⢠æ»é¢çæ± ï¼ä¸è®¾ä¸éï¼ä¿è¯ä¸å®è½ç¾å°ï¼ |
| | | return nextTotalPoolSeqNo(checkType, timeslot); |
| | | } |
| | | /** |
| | | * ãæ¬éæ±ãVIP / 临æ¶å å·æ£è
åå·ï¼**ç´æ¥åæ¬æ®µé¢çå·**ï¼æ¬æ®µé¢ç乿»¡ â æ»é¢çæ± ã |
| | | * <p> |
| | | * 䏿®éééçå·®å«åªå¨äº"è·³è¿æ¬æ®µæ®éå·"ï¼å
¶ä½ï¼é¢çå·ãæ»æ± å
åºï¼å®å
¨ä¸è´ã |
| | | */ |
| | | @Override |
| | | @Transactional |
| | | public Integer distributeVipSeqNo(Integer checkType, Integer timeslot) { |
| | | Integer curVipSeqNo = queueSequenceMapper.selectQueueVipNoForUpdate(checkType, timeslot); |
| | | if (null == curVipSeqNo) { |
| | | throw exception(QUEUE_SEQUENCE_TIMESLOT_FULL); |
| | | if (null != curVipSeqNo) { |
| | | Integer updateRowNum = queueSequenceMapper.updateGivenCheckTypeTimeslotVipSeqNo(checkType, timeslot, curVipSeqNo); |
| | | if (null != updateRowNum && updateRowNum > 0) { |
| | | return curVipSeqNo + 1; |
| | | } |
| | | log.info("[distributeVipSeqNo] æ¬æ®µé¢çå·å¹¶å被æ¢ç©ºï¼éçº§å°æ»é¢çæ± . checkType={} timeslot={}", checkType, timeslot); |
| | | } |
| | | return nextTotalPoolSeqNo(checkType, timeslot); |
| | | } |
| | | |
| | | /** |
| | | * ãæ¬éæ±ãæ»é¢çæ± åå·ï¼{@code time_slot = 0} é£ä¸è¡ï¼ââ **æ°¸ä¸å¤±è´¥**ã |
| | | * |
| | | * <h3>为ä»ä¹ä¸ä¼æ»¡</h3> |
| | | * æ»æ± ç {@code queue_vip_full} å¨åå·æ¶åæ¥"é¡¶é«"ï¼è§ Mapper ç |
| | | * {@code advanceTotalPoolVipNo}ï¼ï¼å æ¤ {@code queue_vip_no} æ°¸è¿å¯ä»¥ç»§ç» +1ã |
| | | * è¿æ¯"ç»ä¸åºç°ç¾ä¸ä¸"çæåä¸éå
åºã |
| | | * |
| | | * <h3>æ»æ± è¡ç¼ºå¤±æ¶èªå¨è¡¥</h3> |
| | | * å·æ®µæ¾å¨å½å¤©æææ¶æ®µçæå¤§å·ä¹åï¼{@code max(queue_vip_full)}ï¼ï¼ |
| | | * ä¿è¯æ»æ± å· **å¤§äºæææ¶æ®µå·** â æåºå¤©ç¶æå¨å
¨å¤©æåã |
| | | */ |
| | | private Integer nextTotalPoolSeqNo(Integer checkType, Integer timeslot) { |
| | | Integer curVipNo = null; |
| | | try { |
| | | curVipNo = queueSequenceMapper.selectTotalPoolVipNo(checkType); |
| | | } catch (Exception e) { |
| | | log.warn("[nextTotalPoolSeqNo] è¯»åæ»é¢çæ± å¼å¸¸ï¼æç¼ºå¤±å¤ç. checkType={}", checkType, e); |
| | | } |
| | | |
| | | Integer updateRowNum = queueSequenceMapper.updateGivenCheckTypeTimeslotVipSeqNo(checkType, timeslot, curVipSeqNo); |
| | | if (null == updateRowNum || updateRowNum == 0) { |
| | | if (null == curVipNo) { |
| | | // ç°åºå
åºï¼èªå¨è¡¥ä¸è¡æ»é¢çæ± ï¼å¹çï¼ä»¥ æ£æ¥ç±»å + time_slot=0 å¯ä¸ï¼ |
| | | Integer base = queueSequenceMapper.selectMaxVipFullOfCheckType(checkType); |
| | | if (null == base) { |
| | | base = 0; |
| | | } |
| | | QueueSequenceDO pool = new QueueSequenceDO(); |
| | | pool.setCheckType(checkType); |
| | | pool.setTimeSlot(0); |
| | | pool.setQueueSet(0); |
| | | pool.setQueueNo(0); |
| | | pool.setQueueFull(0); |
| | | pool.setQueueVipSet(base); |
| | | pool.setQueueVipNo(base); |
| | | pool.setQueueVipFull(base); |
| | | try { |
| | | queueSequenceMapper.insert(pool); |
| | | } catch (Exception e) { |
| | | // å¹¶åä¸å¯è½å·²è¢«å«ççº¿ç¨æå
¥ï¼å¿½ç¥åç»§ç»è¯» |
| | | log.warn("[nextTotalPoolSeqNo] è¡¥æ»é¢çæ± è¡å¤±è´¥ï¼å¯è½å¹¶åå·²æå
¥ï¼ï¼ç»§ç»åå·. checkType={}", checkType, e); |
| | | } |
| | | if (null == queueSequenceMapper.selectTotalPoolVipNo(checkType)) { |
| | | // æå
¥åä»è¯»ä¸å°ï¼æç«¯æ
åµï¼â ç¨å½å¤©æå¤§å·å
åºï¼ä¿è¯è½ç¾å° |
| | | Integer maxFull = queueSequenceMapper.selectMaxVipFullOfCheckType(checkType); |
| | | log.error("[nextTotalPoolSeqNo] æ»é¢çæ± ä¸å¯ç¨ï¼ä½¿ç¨æå¤§å·å
åº. checkType={} maxFull={}", checkType, maxFull); |
| | | return (null == maxFull ? 0 : maxFull) + 1; |
| | | } |
| | | } |
| | | |
| | | Integer updateNum = queueSequenceMapper.advanceTotalPoolVipNo(checkType); |
| | | if (null == updateNum || updateNum == 0) { |
| | | throw exception(QUEUE_SEQUENCE_TIMESLOT_EXCEPTION); |
| | | } |
| | | |
| | | return curVipSeqNo + 1; |
| | | Integer after = queueSequenceMapper.selectTotalPoolVipNo(checkType); |
| | | if (null == after) { |
| | | throw exception(QUEUE_SEQUENCE_TIMESLOT_EXCEPTION); |
| | | } |
| | | log.info("[nextTotalPoolSeqNo] 已仿»é¢çæ± åå·ï¼æ¬æ®µå·²æ»¡ææ²¡ææ¶æ®µï¼. checkType={} timeslot={} seqNo={}", |
| | | checkType, timeslot, after); |
| | | return after; |
| | | } |
| | | |
| | | /** |
| | |
| | | @Transactional |
| | | public Integer distributeSeqNoByRule(Integer checkType, Integer timeslot, |
| | | Integer existingSeqNo, boolean urgent) { |
| | | // å
¼å®¹æ§è°ç¨æ¹ï¼æªä¼ VIP æ è®°æ¶æ"é VIP"å¤ç |
| | | return distributeSeqNoByRule(checkType, timeslot, existingSeqNo, urgent, false); |
| | | } |
| | | |
| | | /** |
| | | * ãæ¬éæ±ã带 VIP/å å·æ è®°çåå·å
¥å£ã |
| | | * <p> |
| | | * ä¸ååçæ¬çå¯ä¸å·®å«ï¼ææ¶æ®µé¢çº¦ï¼TIMESLOTï¼ä¸ï¼VIP/å å·æ£è
**ç´æ¥åæ¬æ®µé¢çå·** |
| | | * ï¼è§ {@link #distributeVipSeqNo}ï¼ï¼è䏿¯å
åæ®éå·ï¼ç¾å°åºå·ï¼CHECKINï¼ä¸ |
| | | * VIP/å å·åæ ·å¯å ç¨é¢çå·ï¼æ¯ 9 ç 1 çé¢çä½ï¼ã |
| | | */ |
| | | @Override |
| | | @Transactional |
| | | public Integer distributeSeqNoByRule(Integer checkType, Integer timeslot, |
| | | Integer existingSeqNo, boolean urgent, boolean vip) { |
| | | SeqRuleEnum rule = resolveRule(checkType); |
| | | |
| | | switch (rule) { |
| | |
| | | } |
| | | log.warn("[distributeSeqNoByRule] è§å=é¢çº¦å·ï¼ä½é¢çº¦ç³»ç»æªä¸åå·ï¼åéå°ç¾å°åºå·. checkType={}", |
| | | checkType); |
| | | return nextCheckInSeqNo(checkType, urgent); |
| | | return nextCheckInSeqNo(checkType, urgent || vip); |
| | | |
| | | case CHECKIN: |
| | | // â¡ ç¾å°åºå·ï¼å½å¤©åæ£æ¥ç±»åè¿ç»éå¢ï¼æ¯ 9 个é¢ç 1 个 |
| | | return nextCheckInSeqNo(checkType, urgent); |
| | | return nextCheckInSeqNo(checkType, urgent || vip); |
| | | |
| | | case TIMESLOT: |
| | | default: |
| | | // â¢ æ¶æ®µå·ï¼ä¿ææ¹é åçè¡ä¸ºï¼å«æ¶æ®µå®¹éæ§å¶ï¼ |
| | | // â¢ æ¶æ®µå·ï¼VIP/å å·èµ°ãæ¬æ®µé¢çå· â æ»é¢çæ± ãï¼æ®éèµ°ãæ®é â é¢ç â æ»æ± ã |
| | | if (vip) { |
| | | return distributeVipSeqNo(checkType, timeslot); |
| | | } |
| | | return distributeSeqNo(checkType, timeslot); |
| | | } |
| | | } |
| | |
| | | import cn.lihu.jh.module.ecg.controller.admin.room.vo.MonitorInfoVO; |
| | | import cn.lihu.jh.module.ecg.controller.admin.room.vo.RoomPageReqVO; |
| | | import cn.lihu.jh.module.ecg.controller.admin.room.vo.RoomSaveReqVO; |
| | | import cn.lihu.jh.module.ecg.controller.admin.room.vo.RoomSeatRespVO; |
| | | import cn.lihu.jh.module.ecg.controller.admin.room.vo.RoomSelectBedRespVO; |
| | | import cn.lihu.jh.module.ecg.dal.dataobject.room.RoomDO; |
| | | import cn.lihu.jh.module.ecg.dal.dataobject.room.RoomProfile; |
| | | |
| | |
| | | RoomProfile getRoomByIP(String ip, Long roomId); |
| | | |
| | | /** |
| | | * ã鿩工使¨¡å¼ã- ææ¬æºIPå¹é
å·¥ä½ï¼è¿å该IPä¸çåéå·¥ä½ï¼æ¬äººå·²å ç¨ â ç©ºé² â 被ä»äººå ç¨ï¼ã |
| | | * <p>ä»
æ¥è¯¢ã䏿¹åä»»ä½ç¶æï¼èªå¨å
¥åº§ç±å端æ¿å°ç»æå沿ç¨åæç bedDoctorOn æµç¨å®æã</p> |
| | | * |
| | | * @param ip æ¥è®¿IP |
| | | * @param docId å½åç»å½äººIDï¼å¯è½ä¸ºç©ºï¼ |
| | | */ |
| | | List<RoomSelectBedRespVO.RoomSelectBedItem> matchBedsByIp(String ip, Long docId); |
| | | |
| | | /** |
| | | * ã鿩工使¨¡å¼ã- ææ¬æºIPåå°æå®å·¥ä½ï¼åªæ¹ clinic_room.ip ä¸ä¸ªå段ï¼ã |
| | | * |
| | | * @param id å·¥ä½ä¸»é® |
| | | * @param ip æ¥è®¿IP |
| | | * @return åå½±åè¡æ° |
| | | */ |
| | | Integer bindIpToBed(Integer id, String ip); |
| | | |
| | | /** |
| | | * 该IPæ¯å¦å·²ç»ç»å¨å«çå·¥ä½ä¸ï¼å²çªæ£æµï¼ä¾å端弹确认ååè¦çï¼ã |
| | | * |
| | | * @param ip å¾
ç»å®IP |
| | | * @param excludeId æé¤çå·¥ä½ä¸»é®ï¼å¯ä¸ºç©º |
| | | */ |
| | | List<RoomDO> listIpBindings(String ip, Integer excludeId); |
| | | |
| | | /** |
| | | * ã鿩工使¨¡å¼ã- ä¸é®èªå¨å
¥åº§ï¼ææ¥è®¿ IP å¹é
å·¥ä½å¹¶**ç´æ¥è½åº§**ï¼æ¨¡å¼ 1/3 ç¨ï¼ã |
| | | * |
| | | * <p>为ä»ä¹è¦æè¿ä¸ªæ¥å£ï¼åç«¯åæ¥æã{@code get-ip-bed} å¹é
â {@code bind-ip} å IP â |
| | | * {@code bed-doctor-on} å
¥åº§ãææä¸ä¸ªè¯·æ±èªå·±æ¼ï¼ä»»ä¸æ¥å¤±è´¥é½åªè½åè½å°"æéå·¥ä½"ï¼ |
| | | * ç°åºè¡¨ç°å°±æ¯"ç»å½å没æèªå¨å
¥åº§"ä¸çä¸åºåå ãè¿éæ¶ææä¸æ¬¡è°ç¨ï¼å¹¶è¿å**è¯å«å°ç IP** |
| | | * ä¸**æªå
¥åº§åå **ï¼ip_invalid / nomatch / multi / occupied / errorï¼ã |
| | | * |
| | | * <p>çç¥ä¸åæå端é»è¾ä¿æä¸è´ï¼ |
| | | * â å·²æ¯æçå·¥ä½ â å¹çæ¢å¤ï¼â¡ **æ°å¥½ä¸ä¸ª**空é²å·¥ä½ â å ç¨ï¼â¢ å¤ä¸ªç©ºé² â 䏿
èªå
¥åº§ï¼multiï¼ï¼ |
| | | * ⣠å
¨è¢«ä»äººå ç¨ â 䏿¤æï¼occupied + å ç¨äººå§åï¼ã |
| | | * |
| | | * @param ip æ¥è®¿ IPï¼è°ç¨æ¹å·²ç¨ {@code IpUtils.normalize} è§èåï¼ |
| | | * @param docId å½åç»å½äºº |
| | | * @param docName å½åç»å½äººå§å |
| | | */ |
| | | RoomSeatRespVO autoSeatByIp(String ip, Long docId, String docName); |
| | | |
| | | /** |
| | | * æ¥è¯¢å½åç»å½äºº**å·²å
¥åº§**çå·¥ä½ï¼ç»ç³»ç»é¡¶æ æ¾ç¤º"å½åå·¥ä½"ç¨ï¼ã |
| | | * |
| | | * @param docId å½åç»å½äºº |
| | | * @return æªå
¥åº§æ¶è¿å {@code seated=false} çç©ºç»æ |
| | | */ |
| | | RoomSeatRespVO getMySeat(Long docId); |
| | | |
| | | /** |
| | | * ãæ¬éæ±Â·ä¸äººå¤å·¥ä½ãæ¥è¯¢å½åç»å½äºº**å æ®çå
¨é¨å·¥ä½**ï¼è忥å¼çå¤å²ä½ï¼ã |
| | | * |
| | | * <p>è¿åãå»çå¨åº§ / å»çæåãç¶æçå·¥ä½ï¼æ roomId + bedNo ååºï¼ |
| | | * æªå ä»»ä½å·¥ä½æ¶è¿å空å表ï¼åç«¯æ®æ¤æ¾ç¤º"æªå
¥åº§"ï¼ã |
| | | * |
| | | * @param docId å½åç»å½äºº |
| | | */ |
| | | List<RoomSeatRespVO> getMySeats(Long docId); |
| | | |
| | | /** |
| | | * ãæ¬éæ±Â·æ¥çèªå©æ¥ç®¡ãææå®å·¥ä½ä»"å«äººå ç¨"æ¹ä¸º"å½åç»å½äººå ç¨"ã |
| | | * |
| | | * <p>使ç¨åºæ¯ï¼ä¸ä¸çå»çä¸çæªç¹ã离座ãï¼ä¸ä¸çå»çå¨åä¸å°çµè/åä¸å·¥ä½æ¥çã |
| | | * è¡ä¸ºï¼ |
| | | * <ol> |
| | | * <li>å·¥ä½ä¸åå¨ â æ¥éï¼</li> |
| | | * <li>å·¥ä½ç©ºé²ï¼ææ¬æ¥å°±å±äºå½åç»å½äºº â **å¹çæå**ï¼ä¸æ¥éï¼ï¼</li> |
| | | * <li>被ä»äººå ç¨ â è®°å½å®¡è®¡æ¥å¿ï¼å·¥ä½ãåå ç¨äººãæä½äººï¼â å¼ºå¶æ¸
空åå ç¨äºº â **ç«å³è®©å½åç»å½äººå
¥åº§**ã</li> |
| | | * </ol> |
| | | * |
| | | * @param roomId è¯å®¤ç¼å· |
| | | * @param bedNo å·¥ä½ç¼å· |
| | | */ |
| | | void takeOverBed(Long roomId, String bedNo); |
| | | |
| | | /** |
| | | * æ ¡éªãå½åç»å½äººå¿
é¡»æ¯è¯¥å·¥ä½ç主人ãï¼å¦åæ |
| | | * {@link cn.lihu.jh.module.ecg.enums.ErrorCodeConstants#ROOM_NOT_OWNER}ã |
| | | * |
| | | * <p>ç¨äº"主/å´è§"模åçåæä½é´æï¼å´è§äººåªè½çï¼ä¸è½æ¹æ°æ®ã |
| | | * {@code @RequireBedOwner} åé¢ä¼è°ç¨å®ï¼åªå¸¦ rentId ä¹ç±»çæ¥å£éè¦èªè¡è°ç¨ã |
| | | * |
| | | * @param roomId è¯å®¤ç¼å· |
| | | * @param bedNo å·¥ä½å· |
| | | */ |
| | | void assertBedOwner(Long roomId, String bedNo); |
| | | |
| | | /** |
| | | * åä¸ï¼ä½**ææ£è
忥工ä½**ï¼ç¨äºåªå¸¦æ£è
ä¿¡æ¯ã没æ roomId/bedNo çåæ¥å£ |
| | | * ï¼æ¾å¼æ£æ¥ / æ¾å¼é¢ç¨ / æ¾å¼è£
æºï¼ã |
| | | * |
| | | * <p>忥便®ï¼{@code queue} 表å½å该æ£è
+ æ£æ¥é¡¹ç®çé£ä¸è¡ä¸ç room_id / bed_noã |
| | | * æ¥ä¸å°å·¥ä½æ¶**æç»**ï¼å®å¯æç»ä¹ä¸æ¾è¡ï¼ã |
| | | */ |
| | | void assertBedOwnerByPatient(String patId, Integer checkType); |
| | | |
| | | /** |
| | | * åä¸ï¼ä½æ¥ä¸å°å·¥ä½æ¶**è®°è¦åæ¾è¡**ã |
| | | * |
| | | * <p>ç¨äºç¡®è´¹/åæ¶ç¡®è´¹ï¼è¿ä¸¤æ¥å¸¸å¨æµç¨æ«ç«¯è°ç¨ï¼æ£è
å¯è½å·²ç»ä¸å¨å·¥ä½éåä¸ï¼ |
| | | * ä¸å¾æç»ä¼ææ£å¸¸ä¸å¡æ¡æï¼æ
è¿éåªè®°è¦åï¼å端å¨å´è§æ¨¡å¼ä¸å·²ç¦ç¨æé®ï¼ã |
| | | */ |
| | | void assertBedOwnerByPatientSoft(String patId, Integer checkType); |
| | | |
| | | /** |
| | | * æ ¡éªã该工ä½å½åçä¸»äººå°±æ¯ ownerDocIdãã |
| | | * |
| | | * <p>ç¨äºå´è§äººæ¥ç**å·¥ä½ä¸»äººçå·²å®ææ£æ¥è®°å½**ï¼ä¸è¦æ±è°ç¨è
å
¥åº§ï¼å´è§æ¬æ¥å°±æ¯ä¸å
¥åº§ä¹è½çï¼ï¼ |
| | | * ä½å¿
须确认è¿ä¸ª docId ç¡®å®æ¯è¯¥å·¥ä½ç°å¨ç主人ï¼é¿å
è¢«å½æ"ä»»ææ¥å«äººè®°å½"çå
¥å£ã |
| | | * |
| | | * @param roomId è¯å®¤ç¼å· |
| | | * @param bedNo å·¥ä½å· |
| | | * @param ownerDocId ææçå·¥ä½ä¸»äºº |
| | | */ |
| | | void assertBedOwnerIs(Long roomId, String bedNo, Long ownerDocId); |
| | | |
| | | /** |
| | | * å·¥ä½ç¶æè¯æï¼ææ¥"å
¥åº§æ¥ç¶æå¼å¸¸/æ¾ä¸å°å·¥ä½"ï¼ã |
| | | * |
| | | * <p>æåºéç**åå§è¡**æå¼ï¼`id / room_id / bed_no(å«é¿åº¦ä¸ HEXï¼ç¨äºåç°ç»å°¾ç©ºæ ¼/å
¨è§) / |
| | | * status / doc_id / doc_name / deleted / update_time`ï¼å¹¶ç»åºä¸å¥ç»è®ºã |
| | | * |
| | | * @param id å·¥ä½ä¸»é®ï¼ä¼å
ï¼å«å·²å é¤è¡ï¼ |
| | | * @param roomId è¯å®¤ç¼å·ï¼id 为空æ¶ç¨ï¼ |
| | | * @param bedNo å·¥ä½å·ï¼id 为空æ¶ç¨ï¼æ TRIM 宽æ¾å¹é
ï¼ |
| | | */ |
| | | Map<String, Object> diagnoseBed(Integer id, Long roomId, String bedNo); |
| | | |
| | | /** |
| | | * è·å¾è¯å®¤åè¯çåºå页 |
| | | * |
| | | * @param pageReqVO å页æ¥è¯¢ |
| | |
| | | import java.util.*; |
| | | import javax.annotation.Resource; |
| | | |
| | | import cn.lihu.jh.framework.common.exception.ErrorCode; |
| | | import cn.lihu.jh.framework.common.exception.enums.GlobalErrorCodeConstants; |
| | | import cn.lihu.jh.framework.common.pojo.PageResult; |
| | | import cn.lihu.jh.module.ecg.utils.IpUtils; |
| | | import cn.lihu.jh.module.ecg.controller.admin.room.vo.MonitorInfoVO; |
| | | import cn.lihu.jh.module.ecg.controller.admin.room.vo.RoomSeatRespVO; |
| | | import cn.lihu.jh.module.ecg.dal.dataobject.room.RoomDO; |
| | | import cn.lihu.jh.module.ecg.dal.dataobject.queue.QueueDO; |
| | | import cn.lihu.jh.module.ecg.dal.dataobject.room.RoomProfile; |
| | | import cn.lihu.jh.module.ecg.enums.RoomCallingScreenEnum; |
| | | import cn.lihu.jh.module.ecg.service.queue.QueueService; |
| | |
| | | |
| | | import cn.lihu.jh.module.ecg.controller.admin.room.vo.RoomPageReqVO; |
| | | import cn.lihu.jh.module.ecg.controller.admin.room.vo.RoomSaveReqVO; |
| | | import cn.lihu.jh.module.ecg.controller.admin.room.vo.RoomSelectBedRespVO; |
| | | import cn.lihu.jh.module.ecg.dal.mysql.room.RoomMapper; |
| | | import cn.lihu.jh.module.ecg.enums.BedStatusEnum; |
| | | import cn.lihu.jh.framework.common.util.object.BeanUtils; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | |
| | | import static cn.lihu.jh.framework.common.exception.util.ServiceExceptionUtil.exception; |
| | | import static cn.lihu.jh.module.ecg.enums.ErrorCodeConstants.ROOM_INVALID_STATUS; |
| | | import static cn.lihu.jh.module.ecg.enums.ErrorCodeConstants.ROOM_NOT_EXISTS; |
| | | import static cn.lihu.jh.module.ecg.enums.ErrorCodeConstants.ROOM_NOT_OWNER; |
| | | |
| | | /** |
| | | * è¯å®¤åè¯çåº Service å®ç°ç±» |
| | |
| | | */ |
| | | @Service |
| | | @Validated |
| | | @Slf4j |
| | | public class RoomServiceImpl implements RoomService { |
| | | |
| | | @Resource |
| | |
| | | |
| | | @Resource |
| | | QueueService queueService; |
| | | |
| | | /** ã主/å´è§ãææ£è
忥工ä½åä¸»äººæ ¡éªæ¶éè¦è¯» queue è¡ */ |
| | | @Resource |
| | | private cn.lihu.jh.module.ecg.dal.mysql.queue.QueueMapper queueMapper; |
| | | |
| | | @Override |
| | | public Integer createRoom(RoomSaveReqVO createReqVO) { |
| | |
| | | return roomMapper.selectPage(pageReqVO); |
| | | } |
| | | |
| | | /** |
| | | * ã鿩工使¨¡å¼ã- ææ¬æºIPå¹é
å·¥ä½ã |
| | | * <p>æåºï¼å³å®èªå¨å
¥åº§éåªä¸ä¸ªï¼ï¼â æ¬äººå·²å ç¨ï¼å·æ°/éè¿ç´æ¥æ¢å¤ï¼â ⡠空é²ä¸å·¥ä½å·æå° |
| | | * â ⢠被ä»äººå ç¨ï¼åç«¯ä¼æç¤º"该IP对åºå·¥ä½å·²è¢«XXå ç¨"ï¼è®©äººå·¥å¤çï¼ã</p> |
| | | */ |
| | | @Override |
| | | public List<RoomSelectBedRespVO.RoomSelectBedItem> matchBedsByIp(String ip, Long docId) { |
| | | String normalized = IpUtils.normalize(ip); |
| | | if (!IpUtils.isBindableIp(normalized)) { |
| | | return Collections.emptyList(); |
| | | } |
| | | List<RoomDO> list = roomMapper.queueByIp(normalized); |
| | | if (list == null || list.isEmpty()) { |
| | | return Collections.emptyList(); |
| | | } |
| | | List<RoomSelectBedRespVO.RoomSelectBedItem> items = new ArrayList<>(list.size()); |
| | | for (RoomDO roomDO : list) { |
| | | RoomSelectBedRespVO.RoomSelectBedItem item = new RoomSelectBedRespVO.RoomSelectBedItem(); |
| | | item.setId(roomDO.getId()); |
| | | item.setRoomId(roomDO.getRoomId()); |
| | | item.setRoomName(roomDO.getRoomName()); |
| | | item.setBedNo(roomDO.getBedNo()); |
| | | item.setIp(roomDO.getIp()); |
| | | item.setDocId(roomDO.getDocId()); |
| | | item.setDocName(roomDO.getDocName()); |
| | | item.setOpType(roomDO.getOpType()); |
| | | item.setCheckTypes(roomDO.getCheckTypes()); |
| | | item.setStatus(roomDO.getStatus()); |
| | | item.setOccupied(roomDO.getDocId() != null); |
| | | item.setMine(docId != null && docId.equals(roomDO.getDocId())); |
| | | items.add(item); |
| | | } |
| | | // æåºï¼æ¬äººå·²å ç¨(0) â 空é²(1) â 被ä»äººå ç¨(2)ï¼åæ¡£æå·¥ä½å· |
| | | items.sort(Comparator |
| | | .comparingInt((RoomSelectBedRespVO.RoomSelectBedItem i) -> { |
| | | if (Boolean.TRUE.equals(i.getMine())) return 0; |
| | | if (!Boolean.TRUE.equals(i.getOccupied())) return 1; |
| | | return 2; |
| | | }) |
| | | .thenComparing(RoomSelectBedRespVO.RoomSelectBedItem::getBedNo, |
| | | Comparator.nullsLast(Comparator.naturalOrder()))); |
| | | return items; |
| | | } |
| | | |
| | | @Override |
| | | public Integer bindIpToBed(Integer id, String ip) { |
| | | // åç¯/æªæå®/éæ³å°åç»ä¸å»æ²¡ææä¹ï¼127.xã::1ã0.0.0.0ï¼ï¼è¿ä¼è®©åç»å¹é
失æ |
| | | if (!IpUtils.isBindableIp(ip)) { |
| | | return 0; |
| | | } |
| | | Integer rows = roomMapper.updateIpById(id, IpUtils.normalize(ip)); |
| | | log.info("[bindIpToBed][ææ¬æºIPç»å®å°å·¥ä½] id={} ip={} å½±åè¡æ°={}", id, ip, rows); |
| | | return rows; |
| | | } |
| | | |
| | | @Override |
| | | public List<RoomDO> listIpBindings(String ip, Integer excludeId) { |
| | | if (!IpUtils.isBindableIp(ip)) { |
| | | return Collections.emptyList(); |
| | | } |
| | | List<RoomDO> list = roomMapper.listByIpExcludeId(IpUtils.normalize(ip), excludeId); |
| | | return list == null ? Collections.emptyList() : list; |
| | | } |
| | | |
| | | @Override |
| | | public RoomSeatRespVO autoSeatByIp(String ip, Long docId, String docName) { |
| | | RoomSeatRespVO resp = new RoomSeatRespVO(); |
| | | String clientIp = IpUtils.normalize(ip); |
| | | resp.setClientIp(clientIp); |
| | | |
| | | // â æ¬æºIPä¸å¯ç¨ï¼åç¯ / IPv6 / æªæå® / éæ³ / **æå¡å¨èªèº«å°å**ï¼â ä¸è½ä½ä¸ºå·¥ä½æ è¯ |
| | | if (!IpUtils.isBindableIp(clientIp)) { |
| | | // åºå"è¯å«å°çæ¯æå¡å¨èªèº«å°å"ä¸å
¶å®ä¸å¯ç¨æ
åµï¼åè
ç°åºæå¸¸è§ï¼å¨æå¡å¨ä¸/è¿ç¨æ¡é¢é访é®ï¼ï¼ |
| | | // æç¤ºè¯è¦è½ç´æ¥æåè§£å³åæ³ï¼è䏿¯è®©ææ¥ç人以为æ¯ä»£ç åäºã |
| | | resp.setReason(IpUtils.isLocalAddress(clientIp) ? "ip_is_server" : "ip_invalid"); |
| | | log.info("[autoSeatByIp] æ¬æºIPä¸å¯ç¨ï¼ä¸èªå¨å
¥åº§. clientIp={} docId={} æ¯æå¡å¨èªèº«å°å={}", |
| | | clientIp, docId, IpUtils.isLocalAddress(clientIp)); |
| | | return resp; |
| | | } |
| | | |
| | | // å·²æãæ¬äººå·²å ç¨ â ç©ºé² â 被ä»äººå ç¨ãæåº |
| | | List<RoomSelectBedRespVO.RoomSelectBedItem> beds = matchBedsByIp(clientIp, docId); |
| | | if (beds.isEmpty()) { |
| | | // 该 IP 没æå¯¹åºä»»ä½å·¥ä½ï¼å·¥ä½æ²¡å½ IPï¼ç°åºå¤ä¸º 0.0.0.0ï¼ï¼æå·¥ä½å·²å
³é |
| | | resp.setReason("nomatch"); |
| | | log.info("[autoSeatByIp] 该IP没æå¹é
å°å·¥ä½ï¼å·¥ä½æªå½IP / å·²å
³éï¼. clientIp={} docId={}", clientIp, docId); |
| | | return resp; |
| | | } |
| | | |
| | | // â¡ å·²ç»æ¯æçå·¥ä½ â å¹çæ¢å¤ï¼å·æ°/éè¿/䏿¬¡æ²¡æ£å¸¸ç¦»åº§é½èµ°è¿æ¡ï¼ |
| | | RoomSelectBedRespVO.RoomSelectBedItem mine = beds.stream() |
| | | .filter(b -> Boolean.TRUE.equals(b.getMine())).findFirst().orElse(null); |
| | | if (null != mine) { |
| | | return doSeat(mine.getId(), mine.getRoomId(), mine.getBedNo(), docId, docName, resp, "mine"); |
| | | } |
| | | |
| | | // ⢠空é²å·¥ä½ï¼**æ°å¥½ä¸ä¸ª**æèªå¨å
¥åº§ |
| | | List<RoomSelectBedRespVO.RoomSelectBedItem> free = beds.stream() |
| | | .filter(b -> !Boolean.TRUE.equals(b.getOccupied())).toList(); |
| | | if (free.size() == 1) { |
| | | return doSeat(free.get(0).getId(), free.get(0).getRoomId(), free.get(0).getBedNo(), |
| | | docId, docName, resp, "free"); |
| | | } |
| | | if (free.size() > 1) { |
| | | // è¿å°æºå¨å¯¹åºå¤ä¸ªç©ºé²å·¥ä½ â åéçé£é©å¤§äºä¾¿å©ï¼äº¤äººå·¥ç¹é |
| | | resp.setReason("multi"); |
| | | log.info("[autoSeatByIp] 该IPå¯¹åº {} 个空é²å·¥ä½ï¼æ æ³ç¡®å®æ¯åªä¸ä¸ªï¼äº¤äººå·¥éæ©. clientIp={}", free.size(), clientIp); |
| | | return resp; |
| | | } |
| | | |
| | | // ⣠å
¨è¢«ä»äººå ç¨ â **ä¸èªå¨æ¤æ**ï¼ä½æåéå·¥ä½ä¸å ç¨äººå¸¦åå»ï¼ |
| | | // ä¾å端弹ã该工ä½ç± xxx å ç¨ï¼æ¯å¦æ¥ç®¡ï¼ãï¼æ¬éæ±ï¼æ¥çå»çèªå©æ¥ç®¡ï¼ã |
| | | RoomSelectBedRespVO.RoomSelectBedItem occupied = beds.get(0); |
| | | resp.setReason("occupied"); |
| | | resp.setOwnerName(occupied.getDocName()); |
| | | // ãæ¬éæ±ãè¡¥é½åéå·¥ä½ä¿¡æ¯ï¼å端åè¿äºåæ®µè° /clinic/room/take-over-bed |
| | | resp.setId(occupied.getId()); |
| | | resp.setRoomId(occupied.getRoomId()); |
| | | resp.setRoomName(occupied.getRoomName()); |
| | | resp.setBedNo(occupied.getBedNo()); |
| | | resp.setIp(occupied.getIp()); |
| | | resp.setDocId(occupied.getDocId()); |
| | | resp.setDocName(occupied.getDocName()); |
| | | resp.setCheckTypes(occupied.getCheckTypes()); |
| | | resp.setOpType(occupied.getOpType()); |
| | | log.info("[autoSeatByIp] 该IP对åºçå·¥ä½å·²è¢«ä»äººå ç¨ï¼çå¾
å端确认æ¯å¦æ¥ç®¡. clientIp={} å·¥ä½={}/{} å ç¨äºº={}({})", |
| | | clientIp, occupied.getRoomId(), occupied.getBedNo(), occupied.getDocName(), occupied.getDocId()); |
| | | return resp; |
| | | } |
| | | |
| | | /** æ§è¡å
¥åº§å¹¶åå¡«ç»æï¼å
鍿¹æ³ï¼ä¾ autoSeatByIp å忝å¤ç¨ï¼ */ |
| | | private RoomSeatRespVO doSeat(Integer bedId, Long roomId, String bedNo, Long docId, String docName, |
| | | RoomSeatRespVO resp, String branch) { |
| | | // ä¼ bedIdï¼å
¥åº§ä¼å
æä¸»é®å®ä½ï¼é¿å
bed_no ä¸åºå
弿èç¼é¾è¾¨å·®å¼æ¶æ´æ° 0 è¡ |
| | | ErrorCode ec = queueService.startBedDoctorOn(roomId, bedNo, docId, docName, bedId); |
| | | if (!GlobalErrorCodeConstants.SUCCESS.equals(ec)) { |
| | | resp.setReason("error"); |
| | | log.warn("[autoSeatByIp] å
¥åº§æªçæï¼{}ï¼. roomId={} bedNo={} docId={}", branch, roomId, bedNo, docId); |
| | | return resp; |
| | | } |
| | | fillSeatInfo(resp, roomMapper.getRoom(roomId, bedNo)); |
| | | resp.setSeated(true); |
| | | log.info("[autoSeatByIp] èªå¨å
¥åº§æåï¼{}ï¼. docId={} roomId={} bedNo={}", branch, docId, roomId, bedNo); |
| | | return resp; |
| | | } |
| | | |
| | | @Override |
| | | public RoomSeatRespVO getMySeat(Long docId) { |
| | | RoomSeatRespVO resp = new RoomSeatRespVO(); |
| | | if (null == docId) { |
| | | return resp; |
| | | } |
| | | List<RoomDO> beds = roomMapper.getRoomByDocId(docId); |
| | | if (null == beds || beds.isEmpty()) { |
| | | return resp; |
| | | } |
| | | if (beds.size() > 1) { |
| | | // ãæ¬éæ±Â·ä¸äººå¤å·¥ä½ãå¼çå»çå¯åæ¶å å¤ä¸ªå·¥ä½ï¼è¿éä¸åæ¯å¼å¸¸åºæ¯ï¼ |
| | | // æ¬æ¥å£åªä¸ºå
¼å®¹æ§å端/å
¶å®è°ç¨ï¼è¿å第ä¸ä¸ªï¼ï¼å®æ´åè¡¨ç¨ getMySeats()ã |
| | | log.info("[getMySeat] 该å»çå ç¨äº {} 个工ä½ï¼æ¬æ¥å£è¿å第ä¸ä¸ªï¼å®æ´åè¡¨è§ /my-seatsï¼. docId={}", |
| | | beds.size(), docId); |
| | | } |
| | | fillSeatInfo(resp, beds.get(0)); |
| | | resp.setSeated(true); |
| | | return resp; |
| | | } |
| | | |
| | | @Override |
| | | public List<RoomSeatRespVO> getMySeats(Long docId) { |
| | | List<RoomSeatRespVO> result = new ArrayList<>(); |
| | | if (null == docId) { |
| | | return result; |
| | | } |
| | | // åªåãå»çå¨åº§ / å»çæåã䏿ªå é¤çå·¥ä½ï¼æé¤å岿®çï¼ |
| | | List<Integer> statusList = new ArrayList<>(); |
| | | statusList.add(BedStatusEnum.DOCTOR_ON.getStatus()); |
| | | statusList.add(BedStatusEnum.DOCTOR_PAUSE.getStatus()); |
| | | List<RoomDO> beds = roomMapper.getMyActiveBeds(docId, statusList); |
| | | if (null == beds || beds.isEmpty()) { |
| | | return result; |
| | | } |
| | | for (RoomDO bed : beds) { |
| | | RoomSeatRespVO resp = new RoomSeatRespVO(); |
| | | fillSeatInfo(resp, bed); |
| | | resp.setSeated(true); |
| | | result.add(resp); |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | /** |
| | | * ãæ¬éæ±Â·æ¥çèªå©æ¥ç®¡ãæå·¥ä½ä»"å«äººå ç¨"æ¹ä¸º"å½åç»å½äººå ç¨"ã |
| | | * |
| | | * <p>è¿æ¯"ç»åºä¸éæ¾å·¥ä½"åºæ¯ä¸ï¼æ¥çå»çç«å³ç¨ä¸å·¥ä½çå¯ä¸å
¥å£ï¼ä¸éè¦ç®¡çåï¼ã |
| | | * åå ç¨äººé£å°çµèä¼å¨ä¸ä¸æ¬¡ 5s 轮询æ¶å°ãè¯·éæ°å°±åã并转åªè¯»ï¼ç°æé»è¾ï¼ã |
| | | * |
| | | * <p>ãå¼ºå¶æ¸
空 â æå
¥åº§ãå¨åä¸äºå¡å
宿ï¼é¿å
ä¸é´æè¢«ç¬¬ä¸æ¹æ¢å°ã |
| | | */ |
| | | @Override |
| | | @org.springframework.transaction.annotation.Transactional(rollbackFor = Exception.class) |
| | | public void takeOverBed(Long roomId, String bedNo) { |
| | | Long userId = cn.lihu.jh.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId(); |
| | | String userNickname = cn.lihu.jh.framework.security.core.util.SecurityFrameworkUtils.getLoginUserNickname(); |
| | | if (null == userId) { |
| | | throw exception(ROOM_NOT_OWNER); |
| | | } |
| | | if (null == roomId || null == bedNo || bedNo.isEmpty()) { |
| | | throw exception(ROOM_NOT_EXISTS); |
| | | } |
| | | RoomDO bed = roomMapper.getRoom(roomId, bedNo); |
| | | if (null == bed) { |
| | | throw exception(ROOM_NOT_EXISTS); |
| | | } |
| | | |
| | | // â æ¬æ¥å°±å±äºæ â å¹çæå |
| | | if (null != bed.getDocId() && bed.getDocId().equals(userId)) { |
| | | log.info("[takeOverBed] 工使¬å°±å±äºå½åç»å½äººï¼æ éæ¥ç®¡. å·¥ä½={}/{} docId={}", roomId, bedNo, userId); |
| | | return; |
| | | } |
| | | |
| | | // â¡ ç©ºé² â ç´æ¥å
¥åº§ï¼"æ¥ç®¡"çä»·äº"åä¸å»"ï¼çæå端åç¹ä¸æ¬¡å
¥åº§ï¼ |
| | | if (null == bed.getDocId()) { |
| | | ErrorCode onRet = queueService.startBedDoctorOn(roomId, bedNo, userId, userNickname, bed.getId()); |
| | | if (!GlobalErrorCodeConstants.SUCCESS.equals(onRet)) { |
| | | log.warn("[takeOverBed] 空é²å·¥ä½å
¥åº§å¤±è´¥. å·¥ä½={}/{} ret={}", roomId, bedNo, onRet); |
| | | throw exception(ROOM_INVALID_STATUS); |
| | | } |
| | | return; |
| | | } |
| | | |
| | | // ⢠被ä»äººå ç¨ â 审计æ¥å¿ + å¼ºå¶æ¸
空 + ç«å³å
¥åº§ |
| | | log.warn("[takeOverBed][æ¥çæ¥ç®¡] å·¥ä½={}/{} åå ç¨äºº={}({}) â æ¥ç®¡äºº={}({})", |
| | | roomId, bedNo, bed.getDocName(), bed.getDocId(), userNickname, userId); |
| | | ErrorCode offRet = queueService.startBedDoctorOffByAdmin(roomId, bedNo); |
| | | if (!GlobalErrorCodeConstants.SUCCESS.equals(offRet)) { |
| | | log.warn("[takeOverBed] æ¥ç®¡æ¶æ¸
空åå ç¨äººå¤±è´¥. å·¥ä½={}/{} ret={}", roomId, bedNo, offRet); |
| | | throw exception(ROOM_INVALID_STATUS); |
| | | } |
| | | ErrorCode onRet = queueService.startBedDoctorOn(roomId, bedNo, userId, userNickname, bed.getId()); |
| | | if (!GlobalErrorCodeConstants.SUCCESS.equals(onRet)) { |
| | | log.warn("[takeOverBed] æ¥ç®¡åå
¥åº§å¤±è´¥. å·¥ä½={}/{} ret={}", roomId, bedNo, onRet); |
| | | throw exception(ROOM_INVALID_STATUS); |
| | | } |
| | | log.info("[takeOverBed][æ¥çæ¥ç®¡] 宿. å·¥ä½={}/{} æ°å ç¨äºº={}({})", roomId, bedNo, userNickname, userId); |
| | | } |
| | | |
| | | @Override |
| | | public void assertBedOwner(Long roomId, String bedNo) { |
| | | Long userId = cn.lihu.jh.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId(); |
| | | RoomDO bed = (null == roomId || null == bedNo || bedNo.isEmpty()) |
| | | ? null : roomMapper.getRoom(roomId, bedNo); |
| | | if (null == bed) { |
| | | log.warn("[assertBedOwner] å·¥ä½ä¸åå¨ï¼æç»åæä½. roomId={} bedNo={} docId={}", roomId, bedNo, userId); |
| | | throw exception(ROOM_NOT_OWNER); |
| | | } |
| | | if (null == bed.getDocId() || !bed.getDocId().equals(userId)) { |
| | | log.warn("[assertBedOwner] éå·¥ä½ä¸»äººï¼æç»åæä½ï¼å´è§æ¨¡å¼ï¼. roomId={} bedNo={} æ={} 主人={}({})", |
| | | roomId, bedNo, userId, bed.getDocName(), bed.getDocId()); |
| | | throw exception(ROOM_NOT_OWNER); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public void assertBedOwnerByPatient(String patId, Integer checkType) { |
| | | QueueDO queue = resolvePatientBedQueue(patId, checkType); |
| | | if (null == queue) { |
| | | log.warn("[assertBedOwnerByPatient] æ¾ä¸å°è¯¥æ£è
å½åæå¨å·¥ä½ï¼æç»åæä½. patId={} checkType={}", |
| | | patId, checkType); |
| | | throw exception(ROOM_NOT_OWNER); |
| | | } |
| | | assertBedOwner(queue.getRoomId(), queue.getBedNo()); |
| | | } |
| | | |
| | | @Override |
| | | public void assertBedOwnerByPatientSoft(String patId, Integer checkType) { |
| | | QueueDO queue = resolvePatientBedQueue(patId, checkType); |
| | | if (null == queue) { |
| | | // 确费/åæ¶ç¡®è´¹å¸¸å¨æµç¨æ«ç«¯è°ç¨ï¼æ£è
å¯è½å·²ä¸å¨å·¥ä½éåä¸ï¼ |
| | | // ä¸å¾æç»ä¼è¯¯ä¼¤æ£å¸¸ä¸å¡ï¼è¿éåªè®°è¦åæ¾è¡ï¼å端å´è§æ¨¡å¼ä¸æé®å·²ç¦ç¨ï¼ã |
| | | log.warn("[assertBedOwnerByPatientSoft] æ¾ä¸å°è¯¥æ£è
å½åæå¨å·¥ä½ï¼æ¾è¡ï¼ä»
è®°è¦åï¼. patId={} checkType={}", |
| | | patId, checkType); |
| | | return; |
| | | } |
| | | assertBedOwner(queue.getRoomId(), queue.getBedNo()); |
| | | } |
| | | |
| | | @Override |
| | | public void assertBedOwnerIs(Long roomId, String bedNo, Long ownerDocId) { |
| | | RoomDO bed = (null == roomId || null == bedNo || bedNo.isEmpty()) |
| | | ? null : roomMapper.getRoom(roomId, bedNo); |
| | | if (null == bed || null == bed.getDocId() || !bed.getDocId().equals(ownerDocId)) { |
| | | log.warn("[assertBedOwnerIs] å·¥ä½å½å主人ä¸è¯·æ±ç ownerDocId ä¸ä¸è´ï¼æç». roomId={} bedNo={} 请æ±={} å®é
={}", |
| | | roomId, bedNo, ownerDocId, null == bed ? null : bed.getDocId()); |
| | | throw exception(ROOM_NOT_OWNER); |
| | | } |
| | | } |
| | | |
| | | /** æãæ£è
+ æ£æ¥é¡¹ç®ãæ¾å½åæå¨å·¥ä½ç飿¡éåè¡ï¼æ¾ä¸å°å·¥ä½è¿å null */ |
| | | private QueueDO resolvePatientBedQueue(String patId, Integer checkType) { |
| | | if (null == patId) { |
| | | return null; |
| | | } |
| | | QueueDO queue = queueMapper.getQueueByPatId(patId, checkType); |
| | | if (null == queue || null == queue.getRoomId() || null == queue.getBedNo() |
| | | || queue.getBedNo().trim().isEmpty()) { |
| | | return null; |
| | | } |
| | | return queue; |
| | | } |
| | | |
| | | @Override |
| | | public Map<String, Object> diagnoseBed(Integer id, Long roomId, String bedNo) { |
| | | Map<String, Object> data = new LinkedHashMap<>(); |
| | | String condition = String.format("id=%s, roomId=%s, bedNo=[%s](len=%s)", |
| | | id, roomId, bedNo, null == bedNo ? null : bedNo.length()); |
| | | data.put("æ¥è¯¢æ¡ä»¶", condition); |
| | | |
| | | List<Map<String, Object>> rows = roomMapper.selectBedRawState(id, roomId, bedNo); |
| | | data.put("å¹é
å°çè¡æ°", rows.size()); |
| | | data.put("è¡æç»", rows); |
| | | |
| | | String verdict; |
| | | if (rows.isEmpty()) { |
| | | verdict = "åºéãæ¥ä¸å°ãè¿ä¸ªå·¥ä½ï¼æ id ä¸ room_id+TRIM(bed_no) 齿²¡å¹é
å°ï¼â " |
| | | + "æ roomId+bedNo å
¥åº§å¿
ç¶æ´æ° 0 è¡ãæ¥âè¯å®¤åè¯çåºç¶æå¼å¸¸âã" |
| | | + "æ°çå·²æ¯ææ id å
¥åº§ï¼è¥ä»å¤±è´¥ï¼è¯·ææ¬ç»æååã"; |
| | | } else { |
| | | Map<String, Object> row = rows.get(0); |
| | | Integer rowStatus = toInt(row.get("status")); |
| | | Integer rowDeleted = toInt(row.get("deleted")); |
| | | Integer bedNoLen = toInt(row.get("bed_no_len")); |
| | | Object rowDocId = row.get("doc_id"); |
| | | if (null != rowDeleted && 0 != rowDeleted) { |
| | | verdict = "该工ä½å¨åºéæ¯ãå·²å é¤ã(deleted=1) â å
¥åº§ä¸ä¼å½ä¸ï¼è¯·æ¢å¤æ°æ®æé建工ä½ã"; |
| | | } else if (null != bedNoLen && null != bedNo && bedNoLen != bedNo.length()) { |
| | | verdict = String.format("åºé bed_no çé¿åº¦(%d)ä¸è¯·æ±å¼(%d)ä¸ä¸è´ â 请æ±éçå·¥ä½ç¼å·ä¸åºå
ä¸å" |
| | | + "ï¼å¸¸è§æ¯ç»å°¾ç©ºæ ¼/å
¨è§ï¼ï¼HEX=%sãæ°çå·²æ¹ä¸ºæ id å
¥åº§ï¼å¯ç»å¼è¯¥é®é¢ã", |
| | | bedNoLen, bedNo.length(), row.get("bed_no_hex")); |
| | | } else if (null == rowStatus || (10 != rowStatus && 20 != rowStatus && 30 != rowStatus)) { |
| | | verdict = "该工ä½ç¶æ=" + rowStatus + "ï¼0=å·²å
³éï¼ï¼ä¸å¨å¯å
¥åº§ç¶æï¼å¯å
¥åº§ç为 10/20/30ï¼ï¼" |
| | | + "请å
å¨å¼è¯è®¾ç½®/çæ§é¡µæå®å¼éã"; |
| | | } else if (null != rowDocId) { |
| | | verdict = "该工ä½å½åç主人æ¯ã" + row.get("doc_name") + "ã(doc_id=" + rowDocId + ")ï¼" |
| | | + "è¥è¿å°±æ¯ä½ æ¬äººï¼è¯´æä¸æ¬¡æ²¡æ£å¸¸ç¦»åº§ ââ æ°çå·²æ¯æå¹çæ¢å¤å
¥åº§ï¼" |
| | | + "è¥æ¯å«äººï¼åä¸è½å
¥åº§ï¼ä¸æ¤ææ£å¨æä½ç人ï¼ã"; |
| | | } else { |
| | | verdict = "该工ä½å½åãå¯å
¥åº§ããè¥ä¹å仿¥âç¶æå¼å¸¸âï¼è¯·ææ¬ç»æè¿å飿¬¡è¯·æ±åæ°ä¸èµ·ååã"; |
| | | } |
| | | } |
| | | data.put("è¯æç»è®º", verdict); |
| | | log.info("[diagnoseBed][å·¥ä½ç¶æè¯æ] {} â {}", condition, verdict); |
| | | return data; |
| | | } |
| | | |
| | | /** å
¼å®¹ bit(1)/Boolean/Number çåå¼ï¼è¯ææ¥å£ç¨ï¼ */ |
| | | private Integer toInt(Object v) { |
| | | if (null == v) { |
| | | return null; |
| | | } |
| | | if (v instanceof Boolean) { |
| | | return ((Boolean) v) ? 1 : 0; |
| | | } |
| | | if (v instanceof Number) { |
| | | return ((Number) v).intValue(); |
| | | } |
| | | try { |
| | | return Integer.valueOf(String.valueOf(v).trim()); |
| | | } catch (Exception e) { |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | /** æå·¥ä½å段æ·è¿ååºä½ */ |
| | | private void fillSeatInfo(RoomSeatRespVO resp, RoomDO bed) { |
| | | if (null == bed) { |
| | | return; |
| | | } |
| | | resp.setId(bed.getId()); |
| | | resp.setRoomId(bed.getRoomId()); |
| | | resp.setRoomName(bed.getRoomName()); |
| | | resp.setBedNo(bed.getBedNo()); |
| | | resp.setIp(bed.getIp()); |
| | | resp.setStatus(bed.getStatus()); |
| | | resp.setDocId(bed.getDocId()); |
| | | resp.setDocName(bed.getDocName()); |
| | | resp.setCheckTypes(bed.getCheckTypes()); |
| | | resp.setOpType(bed.getOpType()); |
| | | } |
| | | |
| | | @Override |
| | | public List<RoomDO> simpleRoomList() { |
| | | List<BedStatusEnum> bedStatusEnumList = new ArrayList<BedStatusEnum>(); |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.lihu.jh.module.ecg.utils; |
| | | |
| | | import java.net.Inet4Address; |
| | | import java.net.InetAddress; |
| | | import java.net.NetworkInterface; |
| | | import java.util.Enumeration; |
| | | import java.util.LinkedHashSet; |
| | | import java.util.Set; |
| | | |
| | | /** |
| | | * è®¿é®æ¹ IP çè§èå䏿 ¡éªï¼ä¾ã鿩工使¨¡å¼ã使ç¨ï¼ã |
| | | * |
| | | * <h3>å°åæçç¥ï¼åªéç¨ IPv4</h3> |
| | | * æ¬ç³»ç»ç°åºå·¥ä½ç»å®ç»ä¸ä½¿ç¨ IPv4ï¼`clinic_room.ip` éåçå°±æ¯ `32.88.65.x` è¿ç±»å°åï¼ã |
| | | * å æ¤ï¼ |
| | | * <ul> |
| | | * <li>{@link #isBindableIp(String)} **åªæ¥å IPv4**ï¼IPv6ï¼å«åç¯ {@code ::1}ï¼ä¸å¾ä¸åä¸å¹é
ä¸ç»å®ï¼ |
| | | * åªç¨äºè¯ææç¤ºï¼</li> |
| | | * <li>为å
¼å®¹"æµè§å¨ â æå¡å¨åæºè®¿é®"ä¸"容å¨/ç½å
³æ IPv4 表示æ IPv4-mapped IPv6"è¿ä¸¤ç§æ
åµï¼ |
| | | * è§èåæ¶ä¼å两件äºï¼æ {@code ::ffff:32.88.65.208} **è¿åæ {@code 32.88.65.208}**ï¼è¿ååå¯ç¨ï¼ï¼ |
| | | * æ {@code ::1} / {@code 0:0:0:0:0:0:0:1} è¯å«ä¸º<b>åç¯</b>ï¼ä¸å¯ç¨ï¼ä½æç¤ºè¯è¦è¯´æ¸
"æ¬æºè®¿é®"ï¼ï¼ |
| | | * <li>廿 IPv6 çæ¹æ¬å·ä¸åºåå·ï¼{@code %eth0}ï¼ãç»ä¸å°åã代ç转åé¾å第ä¸ä¸ªã</li> |
| | | * </ul> |
| | | * |
| | | * <h3>ãæå¡å¨èªèº«å°åãä¸ä½ä¸ºå·¥ä½æ è¯ï¼æ¬æ¬¡æ°å¢ï¼</h3> |
| | | * ç°åºåé¦è¿"æç»å½ç³»ç»çç½åä¸ç IP å½æäºæ¬æº IP"ãæ ¹å é常æ¯ï¼**卿å¡å¨ä¸ / éè¿è¿ç¨æ¡é¢è®¿é®ç³»ç»**ï¼ |
| | | * æåç½®ä»£çæ²¡éä¼ å®¢æ·ç«¯å°å ââ æ¤æ¶å端çå°ç"客æ·ç«¯"å
¶å®å°±æ¯æå¡å¨èªå·±ã |
| | | * è¿ç§å°åå¿
é¡»æç»ï¼å¦å伿æå¡å¨ IP åè¿ `clinic_room.ip`ï¼é£ä¸ªå·¥ä½ä»¥åæ°¸è¿å¹é
ä¸å°å»ççµèï¼ï¼ |
| | | * å¹¶ç± {@link #isLocalAddress(String)} è¯å«ãç»åºå¯æä½æç¤ºã |
| | | * |
| | | * <h3>è¿ç»´é¡»ç¥ï¼å¦ä½é¿å
客æ·ç«¯èµ° IPv6</h3> |
| | | * è¥æå¡å¨æå¨æºå¨åæ¶çå¬ IPv6ï¼å®¢æ·ç«¯å¯è½ä¼å
ç¨ IPv6 访é®ï¼æ¤æ¶å端çå°çå°±æ¯ IPv6 å°åï¼ |
| | | * æ æ³éè¿ä»£ç "éåæ"IPv4ï¼å ä¸ºè¿æ¥æ¬èº«å°±æ¯ IPv6 建ç«çï¼ãè§£å³åæ³æ¯è®©æå¡åªçå¬ IPv4ï¼ |
| | | * <pre> |
| | | * # æ¹å¼ä¸ï¼JVM åæ°ï¼æ¨èï¼jarboot/å¯å¨èæ¬éå ï¼ |
| | | * -Djava.net.preferIPv4Stack=true |
| | | * # æ¹å¼äºï¼Tomcat åªç» IPv4 å°å |
| | | * server.address=0.0.0.0 + ç³»ç»å
³é IPv6ï¼æç´æ¥ç»æ¬æº IPv4 å°å |
| | | * </pre> |
| | | * è¥ä¸è¿°é½ä¸ä¾¿è°æ´ï¼è¯·ç¡®ä¿å»çç«¯ç¨æå¡å¨ç **IPv4 å°å** 访é®ï¼ä¸è¦ç¨ IPv6 å°åæååè§£æå° IPv6ï¼ã |
| | | * |
| | | * <p>注æï¼å
åç¨ {@code utils}ï¼å°åï¼ââ æ¨¡åéå·²æ {@code cn.lihu.jh.module.ecg.Utils} è¿ä¸ªç±»ï¼ |
| | | * è¥å»ºååç {@code Utils} å
ä¼ä¸ç±»åå²çªï¼å®æµç¼è¯æ¥"ç±»ä¸ç¨åºå
å²çª"ï¼ã |
| | | * 妿³¨æ Windows è·¯å¾å¤§å°å䏿æï¼å é¤ {@code Utils} ç®å½ä¼è¿å¸¦å æ {@code utils}ã</p> |
| | | */ |
| | | public final class IpUtils { |
| | | |
| | | /** æ¯å¦åªéç¨ IPv4ï¼ç°åºçº¦å®ï¼ãæ¹ä¸º false å³å¯æ¾å¼ IPv6ï¼æ éæ¹å¨è°ç¨æ¹ã */ |
| | | public static final boolean IPV4_ONLY = true; |
| | | |
| | | /** æå¡å¨æ¬æº IPv4 ç½å¡å°åçç¼åï¼è§ {@link #localIpv4Addresses()}ï¼ */ |
| | | private static volatile Set<String> localIpv4Cache = null; |
| | | |
| | | private IpUtils() { |
| | | } |
| | | |
| | | /** |
| | | * è§èåæ¥è®¿ IPã |
| | | * |
| | | * @return è§èååçå符串ï¼å
¥å为空æ¶è¿å null |
| | | */ |
| | | public static String normalize(String ip) { |
| | | if (ip == null) { |
| | | return null; |
| | | } |
| | | String v = ip.trim(); |
| | | if (v.isEmpty()) { |
| | | return null; |
| | | } |
| | | // ServletUtil å¯è½è¿åéå·åéç转åé¾ï¼å第ä¸ä¸ªï¼æé è¿å®¢æ·ç«¯çå°åï¼ |
| | | if (v.contains(",")) { |
| | | v = v.split(",")[0].trim(); |
| | | } |
| | | // 廿 IPv6 çæ¹æ¬å·ä¸åºåå·ï¼ä¾å¦ [fe80::1%eth0] â fe80::1 |
| | | if (v.startsWith("[")) { |
| | | v = v.substring(1); |
| | | } |
| | | if (v.endsWith("]")) { |
| | | v = v.substring(0, v.length() - 1); |
| | | } |
| | | int zoneIdx = v.indexOf('%'); |
| | | if (zoneIdx > 0) { |
| | | v = v.substring(0, zoneIdx); |
| | | } |
| | | v = v.toLowerCase(); |
| | | // IPv4-mapped IPv6ï¼::ffff:32.88.65.208 â 32.88.65.208 |
| | | if (v.startsWith("::ffff:") && isIpv4(v.substring(7))) { |
| | | return v.substring(7); |
| | | } |
| | | return v; |
| | | } |
| | | |
| | | /** |
| | | * æ¯å¦æ¯å¯ç¨äºç»å®å·¥ä½ç IPï¼**åªéç¨ IPv4**ï¼ï¼ |
| | | * å¿
é¡»æ¯åæ³ IPv4ï¼ä¸ä¸æ¯åç¯ï¼127.xï¼ææªæå®ï¼0.0.0.0ï¼ã |
| | | * |
| | | * <p>IPv6 ä¸å¾è¿å false ââ å
æ¬åç¯ {@code ::1} ä¸çå® IPv6 å°åã |
| | | * 注æï¼{@code ::ffff:32.88.65.208} è¿ç±» IPv4-mapped å°åä¼å
被è§èåè¿åæ |
| | | * {@code 32.88.65.208}ï¼å æ¤**ä»ç¶å¯ç¨**ï¼è¿æ¯ IPv4 客æ·ç«¯å¨åæ ç¯å¢ä¸æå®¹æè¢«è¯¯å¤çæ
åµï¼ã</p> |
| | | */ |
| | | public static boolean isBindableIp(String ip) { |
| | | String v = normalize(ip); |
| | | if (v == null || v.isEmpty()) { |
| | | return false; |
| | | } |
| | | if (isLoopback(v) || isUnspecified(v)) { |
| | | return false; |
| | | } |
| | | // ãæ¬æ¬¡æ°å¢ãæå¡å¨èªèº«å°åä¸ä½ä¸ºå·¥ä½æ è¯ï¼ç°åºè¥å¨æå¡å¨ä¸ï¼æè¿ç¨æ¡é¢éï¼è®¿é®ç³»ç»ï¼ |
| | | // å端çå°ç"客æ·ç«¯"å°±æ¯æå¡å¨èªå·±ï¼åè¿ clinic_room.ip åè¯¥å·¥ä½æ°¸è¿å¹é
ä¸å°å»ççµèã |
| | | if (isLocalAddress(v)) { |
| | | return false; |
| | | } |
| | | boolean usable = isIpv4(v); |
| | | if (IPV4_ONLY && isIpv6(v)) { |
| | | usable = false; // åªéç¨ IPv4ï¼IPv6 ä¸åä¸ç»å®ä¸å¹é
|
| | | } |
| | | return usable; |
| | | } |
| | | |
| | | /** |
| | | * æå¡å¨æ¬æºææ IPv4 ç½å¡å°åï¼é¦æ¬¡è°ç¨åç¼åï¼ã |
| | | * |
| | | * <p>åä¸å°ç½å¡ä¿¡æ¯æ¶è¿å**空éå**ï¼æ¤æ¶ {@link #isLocalAddress} æä¸º false ââ |
| | | * å®å¯å°æ¦ï¼ä¹ä¸è¦å 为ç¯å¢åä¸å°ç½å¡å°±è¯¯å¤ææå°å齿¯æå¡å¨çã |
| | | */ |
| | | public static Set<String> localIpv4Addresses() { |
| | | Set<String> cached = localIpv4Cache; |
| | | if (null != cached) { |
| | | return cached; |
| | | } |
| | | Set<String> result = new LinkedHashSet<>(); |
| | | try { |
| | | Enumeration<NetworkInterface> nis = NetworkInterface.getNetworkInterfaces(); |
| | | while (null != nis && nis.hasMoreElements()) { |
| | | NetworkInterface ni = nis.nextElement(); |
| | | Enumeration<InetAddress> addrs = ni.getInetAddresses(); |
| | | while (addrs.hasMoreElements()) { |
| | | InetAddress addr = addrs.nextElement(); |
| | | if (addr instanceof Inet4Address) { |
| | | String ip = normalize(addr.getHostAddress()); |
| | | if (null != ip && !ip.isEmpty()) { |
| | | result.add(ip); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } catch (Exception e) { |
| | | // 忽ç¥ï¼æ¿ä¸å°ç½å¡ä¿¡æ¯æ¶ä¸å"æå¡å¨å°å"å¤å®ï¼è¿å空éåï¼ |
| | | } |
| | | localIpv4Cache = result; |
| | | return result; |
| | | } |
| | | |
| | | /** |
| | | * 该å°åæ¯å¦æ¯**æå¡å¨èªèº«**ç IPv4 å°åã |
| | | * |
| | | * <p>ç¨éï¼è¯å«"卿å¡å¨ä¸/è¿ç¨æ¡é¢é访é®ç³»ç»"è¿ç§è®¿é®æ¹å¼ï¼æ¤æ¶å端çå°ç客æ·ç«¯å°±æ¯æå¡å¨èªå·±ï¼ï¼ |
| | | * å¹¶ç»åºå¯æä½æç¤ºï¼è䏿¯æå®å½æå»ççæ¬æº IPã |
| | | * <p>注æï¼åç¯ {@code 127.0.0.1} é常ä¹å¨ç½å¡å表éï¼ä½è°ç¨æ¹ä¸è¬å
ç¨ {@link #isLoopback} å¤å®ï¼ |
| | | * æç¤ºè¯ä¼æ´è´´åï¼"æ¬æºè®¿é®"ï¼ã |
| | | */ |
| | | public static boolean isLocalAddress(String ip) { |
| | | String v = normalize(ip); |
| | | return null != v && !v.isEmpty() && localIpv4Addresses().contains(v); |
| | | } |
| | | |
| | | /** 该å°åæ¯å¦ä¸º IPv6ï¼è§èåä¹å夿ï¼IPv4-mapped å·²è¿åæ IPv4ï¼ä¸ä¼å½ä¸è¿éï¼ */ |
| | | public static boolean isIpv6Address(String ip) { |
| | | return isIpv6(normalize(ip)); |
| | | } |
| | | |
| | | /** åç¯å°åï¼127.0.0.0/8ã::1 */ |
| | | public static boolean isLoopback(String ip) { |
| | | String v = normalize(ip); |
| | | if (v == null) { |
| | | return false; |
| | | } |
| | | if (v.startsWith("127.")) { |
| | | return true; |
| | | } |
| | | return "::1".equals(v) || "0:0:0:0:0:0:0:1".equals(v); |
| | | } |
| | | |
| | | /** æªæå®å°åï¼0.0.0.0ã::ï¼å«å
¨é¶åæ³ï¼ */ |
| | | public static boolean isUnspecified(String ip) { |
| | | String v = normalize(ip); |
| | | if (v == null) { |
| | | return false; |
| | | } |
| | | if ("0.0.0.0".equals(v) || "::".equals(v)) { |
| | | return true; |
| | | } |
| | | // 0:0:0:0:0:0:0:0 |
| | | return v.matches("^0(:0){2,7}$"); |
| | | } |
| | | |
| | | /** IPv4 ç¹ååè¿å¶ */ |
| | | public static boolean isIpv4(String ip) { |
| | | String v = normalize(ip); |
| | | if (v == null || !v.matches("^(\\d{1,3}\\.){3}\\d{1,3}$")) { |
| | | return false; |
| | | } |
| | | for (String seg : v.split("\\.")) { |
| | | int n; |
| | | try { |
| | | n = Integer.parseInt(seg); |
| | | } catch (NumberFormatException e) { |
| | | return false; |
| | | } |
| | | if (n > 255) { |
| | | return false; |
| | | } |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | /** |
| | | * IPv6ï¼å«åç¼©åæ³ï¼ãè¿éå"ç»æçº§"æ ¡éªï¼å¿
é¡»æ¯åå
è¿å¶å段 + åå·ï¼ |
| | | * å
许å缩 {@code ::}ï¼å
许ç»å°¾ IPv4-mappedï¼{@code ::ffff:1.2.3.4}ï¼ã |
| | | * ä¸åä¸¥æ ¼çå
¨å±å¼æ ¡éªï¼å·¥ä¸ç°åºå°åå½¢æå¤ï¼å®½æ¾æ ¡éªæ´å®ç¨ï¼ã |
| | | */ |
| | | public static boolean isIpv6(String ip) { |
| | | String v = normalize(ip); |
| | | if (v == null || v.isEmpty() || !v.contains(":")) { |
| | | return false; |
| | | } |
| | | if (v.contains(":::")) { |
| | | return false; |
| | | } |
| | | int doubleColon = v.indexOf("::"); |
| | | if (doubleColon >= 0 && v.indexOf("::", doubleColon + 1) >= 0) { |
| | | return false; // åªè½åºç°ä¸æ¬¡ "::" |
| | | } |
| | | String body = v.endsWith("::") ? v.substring(0, v.length() - 2) : v; |
| | | if (body.isEmpty()) { |
| | | return true; // å°±æ¯ "::" |
| | | } |
| | | for (String seg : body.split("::", -1)) { |
| | | if (seg.isEmpty()) { |
| | | continue; |
| | | } |
| | | for (String part : seg.split(":", -1)) { |
| | | if (part.isEmpty()) { |
| | | return false; |
| | | } |
| | | if (part.contains(".")) { |
| | | if (!isIpv4(part)) { |
| | | return false; |
| | | } |
| | | } else if (!part.matches("[0-9a-f]{1,4}")) { |
| | | return false; |
| | | } |
| | | } |
| | | } |
| | | return true; |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.lihu.jh.module.ecg.dal.mysql.queuesequence; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.InterceptorIgnore; |
| | | import org.apache.ibatis.annotations.Update; |
| | | import org.junit.Test; |
| | | |
| | | import java.lang.reflect.Method; |
| | | import java.time.LocalDate; |
| | | |
| | | import static org.junit.Assert.assertEquals; |
| | | import static org.junit.Assert.assertNotNull; |
| | | import static org.junit.Assert.assertTrue; |
| | | |
| | | /** |
| | | * ãå彿µè¯ã鲿¢ {@code seq_counter} çå忍è¿è¯å¥å次触åçº¿ä¸æ
éã |
| | | * |
| | | * <h4>èæ¯ï¼ç宿
éï¼2026-10-01ï¼</h4> |
| | | * é¢çº¦ç¡®è®¤æ¥å£ 500ï¼æ¥å¿ï¼ |
| | | * <pre> |
| | | * org.mybatis.spring.MyBatisSystemException: ... UnsupportedOperationException |
| | | * at JsqlParserSupport.processInsert(JsqlParserSupport.java:107) |
| | | * at DataPermissionInterceptor.beforePrepare(DataPermissionInterceptor.java:86) |
| | | * ### The error may involve QueueSequenceMapper.advanceNormalSeq |
| | | * </pre> |
| | | * <b>æ ¹å </b>ï¼MyBatis-Plus ç {@code DataPermissionInterceptor} ä¼ç¨ JSqlParser è§£ææ¯ä¸æ¡ SQLï¼ |
| | | * è JSqlParser ç {@code processInsert} <b>䏿¯æ MySQL ç |
| | | * {@code INSERT ... ON DUPLICATE KEY UPDATE}</b> è¯æ³ï¼ç´æ¥æ {@code UnsupportedOperationException}ã |
| | | * |
| | | * <b>ä¿®å¤</b>ï¼å¨è¿ä¸¤ä¸ªæ¹æ³ä¸æ 注 {@code @InterceptorIgnore(dataPermission = "true")} |
| | | * ï¼{@code seq_counter} 表没æ dept_id/user_idï¼æ°æ®æé坹宿¬æ æä¹ï¼ã |
| | | * |
| | | * <h4>æ¬æµè¯é²çæ¯ä»ä¹</h4> |
| | | * è¥æäººåç»"æ¸
çæ³¨è§£"ææ¹å SQL æ¶æè¿ä¸ªæ³¨è§£å æï¼ |
| | | * <b>ç¼è¯ä¸å¸¸è§åæµé½ä¸ä¼æ¥é</b>ï¼åªæçå®èµ° MyBatis æ¦æªå¨é¾æä¼è§¦åï¼ï¼ |
| | | * ç´å°çº¿ä¸ç¾å°æ¶æç¸ãæ
卿¤<b>æ¾å¼æè¨æ³¨è§£åå¨</b>ã |
| | | */ |
| | | public class SeqCounterInterceptorIgnoreTest { |
| | | |
| | | private static final String IGNORE_MSG = |
| | | "seq_counter çå忍è¿è¯å¥ä½¿ç¨ MySQL 䏿ç INSERT ... ON DUPLICATE KEY UPDATE è¯æ³ï¼" |
| | | + "JSqlParser æ æ³è§£æãå¿
é¡»ä¿ç @InterceptorIgnore(dataPermission=\"true\")ï¼" |
| | | + "å¦å DataPermissionInterceptor 伿 UnsupportedOperationExceptionï¼" |
| | | + "导è´é¢çº¦ç¡®è®¤(ç¾å°)ç´æ¥ 500ã详è§è¯¥æ³¨è§£ä¸æ¹çæ
éè®°å½ã"; |
| | | |
| | | @Test |
| | | public void advanceNormalSeq_mustIgnoreDataPermission() throws Exception { |
| | | assertIgnorePresent("advanceNormalSeq"); |
| | | } |
| | | |
| | | @Test |
| | | public void advanceReservedSeq_mustIgnoreDataPermission() throws Exception { |
| | | assertIgnorePresent("advanceReservedSeq"); |
| | | } |
| | | |
| | | @Test |
| | | public void advanceSql_shouldStillUseOnDuplicateKeyUpdate() throws Exception { |
| | | for (String name : new String[]{"advanceNormalSeq", "advanceReservedSeq"}) { |
| | | Method m = QueueSequenceMapper.class.getMethod(name, Integer.class, LocalDate.class); |
| | | Update up = m.getAnnotation(Update.class); |
| | | assertNotNull(name + " åºä¿ç @Update 注解", up); |
| | | String sql = String.join(" ", up.value()).toUpperCase(); |
| | | assertTrue(name + " åºä½¿ç¨ ON DUPLICATE KEY UPDATE å®ç°å忍è¿ï¼å½å SQL=" + sql + "ï¼", |
| | | sql.contains("ON DUPLICATE KEY UPDATE")); |
| | | assertTrue(name + " åºä½ç¨äº seq_counter 表ï¼å½å SQL=" + sql + "ï¼", |
| | | sql.contains("SEQ_COUNTER")); |
| | | } |
| | | } |
| | | |
| | | private void assertIgnorePresent(String name) throws Exception { |
| | | Method m = QueueSequenceMapper.class.getMethod(name, Integer.class, LocalDate.class); |
| | | InterceptorIgnore ignore = m.getAnnotation(InterceptorIgnore.class); |
| | | assertNotNull(name + " ç¼ºå° @InterceptorIgnoreã\n" + IGNORE_MSG, ignore); |
| | | assertEquals(name + " ç @InterceptorIgnore.dataPermission å¿
须为 \"true\"ã\n" + IGNORE_MSG, |
| | | "true", ignore.dataPermission()); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.lihu.jh.module.ecg.enums; |
| | | |
| | | import org.junit.Test; |
| | | |
| | | import static org.junit.Assert.*; |
| | | |
| | | /** |
| | | * æ£æ¥ç¶æç¼ç å½ä¸åä¸å¿çµä¸å¡åå¤å®çå彿µè¯ã |
| | | * |
| | | * <p>æµè¯æ°æ®åèª 2026-09-17 ç产æ¥å¿ä¸çç宿¥æå¼ï¼ç¨äºé宿¬æ¬¡ä¿®å¤çè¡ä¸ºï¼ |
| | | * <ul> |
| | | * <li>{@code S0405} ç {@code processStep.code} 卿¥æä¸åå¨ {@code "3"}/{@code "03"}/ |
| | | * {@code "7"}/{@code "08"}/{@code "10"} çä¸ååæ³ï¼å¿
é¡»å½ä¸å°åä¸ç¼ç ï¼</li> |
| | | * <li>ç
çä¸ç¨ç¶æ {@code 21}/{@code 22}/{@code 23} ä¸å±äºå¿çµç¼ç 表ï¼åºè¢«æç»ï¼</li> |
| | | * <li>{@code AppointmentTypeEnum} å type å¼å«ç©ºæ ¼/å¶è¡¨ç¬¦ï¼{@code " 1"}ã{@code " 3\t"}ï¼ï¼ |
| | | * å¯¼è´ {@code getByType("3")} å¹é
å¤±è´¥ï¼æ¤å¤åºåä¿®å¤ç»æï¼</li> |
| | | * <li>å¿çµä¸å¡åå¤å®éæ£ç¡®è¯å«å¿çµå䏿¾å°/è¶
声åã</li> |
| | | * </ul> |
| | | * |
| | | * @author å¿çµæéè£
æºç³»ç» |
| | | */ |
| | | public class HisCheckStatusEnumTest { |
| | | |
| | | // ==================== HisCheckStatusEnum.normalize ==================== |
| | | |
| | | @Test |
| | | public void testNormalize_shouldStripLeadingZero() { |
| | | // æ¥å¿å®æµï¼"03" ä¸ "3" é½åºç°è¿ï¼å¿
é¡»å½ä¸ä¸ºåä¸ä¸ªå¼ |
| | | assertEquals("3", HisCheckStatusEnum.normalize("3")); |
| | | assertEquals("3", HisCheckStatusEnum.normalize("03")); |
| | | assertEquals("8", HisCheckStatusEnum.normalize("08")); |
| | | assertEquals("1", HisCheckStatusEnum.normalize("01")); |
| | | } |
| | | |
| | | @Test |
| | | public void testNormalize_shouldTrimWhitespace() { |
| | | assertEquals("7", HisCheckStatusEnum.normalize(" 7 ")); |
| | | assertEquals("10", HisCheckStatusEnum.normalize("\t10")); |
| | | } |
| | | |
| | | @Test |
| | | public void testNormalize_shouldKeepTwoDigitCodes() { |
| | | // char(2) åå¯å®¹çº³ "10" |
| | | assertEquals("10", HisCheckStatusEnum.normalize("10")); |
| | | assertEquals("9", HisCheckStatusEnum.normalize("9")); |
| | | } |
| | | |
| | | @Test |
| | | public void testNormalize_shouldRejectPathologyCodes() { |
| | | // 21 æ æ¬éæ£ / 22 åæ¶æ æ¬éæ£ / 23 已缴费 å±ç
çä¸ç¨ï¼å¿çµä¸æ¶å |
| | | assertNull(HisCheckStatusEnum.normalize("21")); |
| | | assertNull(HisCheckStatusEnum.normalize("22")); |
| | | assertNull(HisCheckStatusEnum.normalize("23")); |
| | | } |
| | | |
| | | @Test |
| | | public void testNormalize_shouldRejectInvalidInput() { |
| | | assertNull(HisCheckStatusEnum.normalize(null)); |
| | | assertNull(HisCheckStatusEnum.normalize("")); |
| | | assertNull(HisCheckStatusEnum.normalize(" ")); |
| | | assertNull(HisCheckStatusEnum.normalize("abc")); |
| | | assertNull(HisCheckStatusEnum.normalize("0")); // ä¸å¨ç¼ç 表å
|
| | | assertNull(HisCheckStatusEnum.normalize("99")); |
| | | } |
| | | |
| | | @Test |
| | | public void testContains() { |
| | | assertTrue(HisCheckStatusEnum.contains(1)); |
| | | assertTrue(HisCheckStatusEnum.contains(10)); |
| | | assertFalse(HisCheckStatusEnum.contains(0)); |
| | | assertFalse(HisCheckStatusEnum.contains(21)); |
| | | assertFalse(HisCheckStatusEnum.contains(null)); |
| | | } |
| | | |
| | | @Test |
| | | public void testGetNameByCode() { |
| | | assertEquals("ç³è¯·åå¼ç«", HisCheckStatusEnum.getNameByCode(1)); |
| | | assertEquals("æ£æ¥ç»è®°", HisCheckStatusEnum.getNameByCode(3)); |
| | | assertEquals("æ¥åå®¡æ ¸", HisCheckStatusEnum.getNameByCode(10)); |
| | | assertNull(HisCheckStatusEnum.getNameByCode(21)); |
| | | } |
| | | |
| | | // ==================== AppointmentTypeEnumï¼ä¿®å¤ç©ºæ ¼æ±¡æåï¼ ==================== |
| | | |
| | | @Test |
| | | public void testAppointmentTypeEnum_shouldMatchWithoutWhitespaceIssue() { |
| | | // åå®ç° type å¼ä¸º " 1" / " 3\t"ï¼getByType("1") ä¼è¿å nullãä¿®å¤åå¿
é¡»è½å¹é
ã |
| | | assertEquals("ç³è¯·åå¼ç«", AppointmentTypeEnum.getByType("1")); |
| | | assertEquals("æ£æ¥ç»è®°", AppointmentTypeEnum.getByType("3")); |
| | | assertEquals("æ£æ¥ç»æ", AppointmentTypeEnum.getByType("7")); |
| | | assertEquals("æ¥åå®¡æ ¸", AppointmentTypeEnum.getByType("10")); |
| | | } |
| | | |
| | | @Test |
| | | public void testAppointmentTypeEnum_shouldTolerateLeadingZeroAndSpace() { |
| | | assertEquals("æ£æ¥ç»è®°", AppointmentTypeEnum.getByType("03")); |
| | | assertEquals("æ£æ¥ç»è®°", AppointmentTypeEnum.getByType(" 3 ")); |
| | | assertEquals("æ¥åå®¡æ ¸", AppointmentTypeEnum.getByType("010")); |
| | | } |
| | | |
| | | @Test |
| | | public void testAppointmentTypeEnum_shouldRejectPathologyAndInvalid() { |
| | | assertNull(AppointmentTypeEnum.getByType("21")); |
| | | assertNull(AppointmentTypeEnum.getByType("23")); |
| | | assertNull(AppointmentTypeEnum.getByType(null)); |
| | | assertNull(AppointmentTypeEnum.getByType("abc")); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.lihu.jh.module.ecg.enums; |
| | | |
| | | import org.junit.Test; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.HashSet; |
| | | import java.util.List; |
| | | import java.util.Set; |
| | | |
| | | import static org.junit.Assert.*; |
| | | |
| | | /** |
| | | * å彿µè¯ï¼æéåºå·è§åæä¸¾ {@link SeqRuleEnum}ã |
| | | * |
| | | * <h3>èæ¯</h3> |
| | | * ãç¾å°æ¶å¦ä½ç»æ£è
æéåºå·ãææ£æ¥é¡¹ç®é
ç½®ï¼ä¸ç§è§åï¼ |
| | | * <ol> |
| | | * <li>é¢çº¦å· ââ ç¨é¢çº¦ç³»ç»ä¸åçå·</li> |
| | | * <li>ç¾å°åºå· ââ å½å¤©åæ£æ¥ç±»åå
è¿ç»éå¢ï¼<b>æ¯ 9 个å·é¢ç 1 个ç»å æ¥</b></li> |
| | | * <li>æ¶æ®µå· ââ æé¢çº¦æ¶é´æ®µç»å·ï¼æ¹é åçåæè¡ä¸ºï¼ä¹æ¯æªé
ç½®æ¶çé»è®¤ï¼</li> |
| | | * </ol> |
| | | * |
| | | * <h3>æ¬æµè¯éå®çå
³é®è¡ä¸º</h3> |
| | | * <ul> |
| | | * <li>{@code parse(null)} åéå° {@code TIMESLOT} ââ åéæ°æ® {@code seq_rule} 为 NULL æ¶ |
| | | * å级å**è¡ä¸ºä¸æ¹é åä¸è´**ï¼</li> |
| | | * <li>æ®éå·åºåè·³è¿ 10 çåæ°ï¼é¢çå·ï¼ï¼ä¸**ä¸è·³å·ãä¸éå·**ï¼</li> |
| | | * <li>é¢çå·åºå = 10 çåæ°ï¼</li> |
| | | * <li>两类å·éå**ä¸ç¸äº¤**ï¼è¿æ¯"两个ç¬ç«è®¡æ°å¨"设计çç®çï¼ã</li> |
| | | * </ul> |
| | | * |
| | | * <h3>æ¾æè·ççå®ç¼ºé·ï¼ä¿çè®°å½ï¼</h3> |
| | | * åçæãåé
å·ãåæ {@code nextNormalSeq(++counter)} å¹¶ææå®å¨ 10 æ¶è·³å° 11ï¼ |
| | | * <pre> |
| | | * counter: 9 â åé
9 |
| | | * counter: 10 â nextNormalSeq(10) ææ 11ï¼ï¼éï¼ |
| | | * counter: 11 â åé
11 â ä¸ä¸ä¸è¡æè½¦ |
| | | * </pre> |
| | | * æ£ç¡®è¯ä¹æ¯ï¼**åé
å· = {@code nextNormalSeq(counter)}ï¼ä¸è®¡æ°å¨å¨"ä¸ä¸ä¸ªå·æ¯é¢çå·"æ¶é¢å¤ +1**ï¼ |
| | | * å³ {@code normal_next = normal_next + 1 + (normal_next + 1 æ¯ 10 çåæ° ? 1 : 0)}ã |
| | | */ |
| | | public class SeqRuleEnumTest { |
| | | |
| | | // ---------------------------------------------------------------- è§£æ |
| | | |
| | | @Test |
| | | public void testParse_null_shouldFallbackToTimeslot() { |
| | | assertEquals(SeqRuleEnum.TIMESLOT, SeqRuleEnum.parse(null)); |
| | | } |
| | | |
| | | @Test |
| | | public void testParse_unknownValue_shouldFallbackToTimeslot() { |
| | | assertEquals(SeqRuleEnum.TIMESLOT, SeqRuleEnum.parse(99)); |
| | | assertEquals(SeqRuleEnum.TIMESLOT, SeqRuleEnum.parse(-1)); |
| | | } |
| | | |
| | | @Test |
| | | public void testParse_knownValues() { |
| | | assertEquals(SeqRuleEnum.APPOINT, SeqRuleEnum.parse(0)); |
| | | assertEquals(SeqRuleEnum.CHECKIN, SeqRuleEnum.parse(1)); |
| | | assertEquals(SeqRuleEnum.TIMESLOT, SeqRuleEnum.parse(2)); |
| | | } |
| | | |
| | | // ------------------------------------------------------- 容éè¯ä¹å·®å¼ |
| | | |
| | | @Test |
| | | public void testIsCapacityLimited_onlyTimeslot() { |
| | | assertFalse(SeqRuleEnum.APPOINT.isCapacityLimited()); |
| | | assertFalse(SeqRuleEnum.CHECKIN.isCapacityLimited()); |
| | | assertTrue(SeqRuleEnum.TIMESLOT.isCapacityLimited()); |
| | | } |
| | | |
| | | // ---------------------------------------------------------- é¢çå·å¤å® |
| | | |
| | | @Test |
| | | public void testIsReservedSeq() { |
| | | assertTrue(SeqRuleEnum.isReservedSeq(10)); |
| | | assertTrue(SeqRuleEnum.isReservedSeq(20)); |
| | | assertTrue(SeqRuleEnum.isReservedSeq(100)); |
| | | assertFalse(SeqRuleEnum.isReservedSeq(1)); |
| | | assertFalse(SeqRuleEnum.isReservedSeq(9)); |
| | | assertFalse(SeqRuleEnum.isReservedSeq(11)); |
| | | assertFalse(SeqRuleEnum.isReservedSeq(0)); |
| | | assertFalse(SeqRuleEnum.isReservedSeq(-10)); |
| | | } |
| | | |
| | | @Test |
| | | public void testRoundSize_matchesReservedRule() { |
| | | assertEquals(10, SeqRuleEnum.ROUND_SIZE); |
| | | assertEquals(1, SeqRuleEnum.RESERVED_PER_ROUND); |
| | | // ãæ¯ 9 个å·é¢ç 1 个ã= 9 æ®é + 1 é¢ç = ä¸è½® 10 个 |
| | | assertEquals(SeqRuleEnum.ROUND_SIZE, 9 + SeqRuleEnum.RESERVED_PER_ROUND); |
| | | } |
| | | |
| | | // -------------------------------------------------------- æ®éå·åºå |
| | | |
| | | @Test |
| | | public void testNextNormalSeq_shouldReturnNonReservedValue() { |
| | | // ç´æ¥è¯ä¹ï¼è¿å from 起第ä¸ä¸ªéé¢çå·ï¼10 æ¬èº«æ¯é¢çå· â è¿å 11ï¼ |
| | | assertEquals(1, SeqRuleEnum.nextNormalSeq(1)); |
| | | assertEquals(9, SeqRuleEnum.nextNormalSeq(9)); |
| | | assertEquals("10 æ¯é¢çå·ï¼åºè·³å° 11", 11, SeqRuleEnum.nextNormalSeq(10)); |
| | | assertEquals(11, SeqRuleEnum.nextNormalSeq(11)); |
| | | assertEquals(19, SeqRuleEnum.nextNormalSeq(19)); |
| | | assertEquals(21, SeqRuleEnum.nextNormalSeq(20)); |
| | | assertEquals("99 æ¬èº«ä¸æ¯é¢çå·ï¼åæ ·è¿å", 99, SeqRuleEnum.nextNormalSeq(99)); |
| | | assertEquals("100 æ¯é¢çå·ï¼è·³å° 101", 101, SeqRuleEnum.nextNormalSeq(100)); |
| | | } |
| | | |
| | | /** |
| | | * 端å°ç«¯æ¨¡æ Mapper çæ¨è¿å
¬å¼ï¼éªè¯**è¿ç» 30 次æ®éåå·ä¸éå·ãä¸è·³å·**ã |
| | | * |
| | | * <p>å
¬å¼ä¸ {@code QueueSequenceMapper#advanceNormalSeq} å®å
¨ä¸è´ï¼ |
| | | * <pre> |
| | | * INSERT æ¶ normal_next = 1 |
| | | * UPDATE æ¶ normal_next = normal_next + 1 + IF((normal_next + 1) % 10 = 0, 1, 0) |
| | | * åé
å· = nextNormalSeq(normal_next - 䏿¬¡æ¨è¿é)ï¼ ââ ä¸å¯¹ï¼ |
| | | * å®é
æ¯ï¼åé
å·ç±ã读ååç normal_nextãç» nextNormalSeq å¾å° |
| | | * </pre> |
| | | * è¿éç¨æç´ç½çæ¹å¼è¿åï¼ç»´æ¤ {@code lastAssigned}ï¼æ¯æ¬¡ |
| | | * {@code next = lastAssigned + 1}ï¼è¥æ¯é¢çå·å {@code next++}ï¼è·³è¿ï¼ï¼ |
| | | * ç¶å {@code lastAssigned = next}ã |
| | | */ |
| | | @Test |
| | | public void testNormalSequence_isContiguousAndSkipsReserved() { |
| | | List<Integer> assigned = new ArrayList<>(); |
| | | int lastAssigned = 0; |
| | | for (int i = 0; i < 30; i++) { |
| | | int next = lastAssigned + 1; |
| | | next = SeqRuleEnum.nextNormalSeq(next); // è·³è¿é¢çå· |
| | | assigned.add(next); |
| | | lastAssigned = next; |
| | | } |
| | | |
| | | // ææï¼1..9, 11..19, 21..29, 31..39 çå 30 个 |
| | | int[] expected = { |
| | | 1, 2, 3, 4, 5, 6, 7, 8, 9, |
| | | 11, 12, 13, 14, 15, 16, 17, 18, 19, |
| | | 21, 22, 23, 24, 25, 26, 27, 28, 29, |
| | | 31, 32, 33 |
| | | }; |
| | | for (int i = 0; i < expected.length; i++) { |
| | | assertEquals("第 " + (i + 1) + " 个æ®éå·", expected[i], (int) assigned.get(i)); |
| | | } |
| | | |
| | | // æ éå· |
| | | Set<Integer> uniq = new HashSet<>(assigned); |
| | | assertEquals("æ®éå·ä¸å¾éå¤", assigned.size(), uniq.size()); |
| | | |
| | | // æ 10 çåæ° |
| | | for (Integer v : assigned) { |
| | | assertFalse("æ®éå·ä¸åºè½å¨é¢çå·ä¸: " + v, SeqRuleEnum.isReservedSeq(v)); |
| | | } |
| | | } |
| | | |
| | | @Test |
| | | public void testNextNormalSeq_withZeroOrNegative_shouldStartFromOne() { |
| | | assertEquals(1, SeqRuleEnum.nextNormalSeq(0)); |
| | | assertEquals(1, SeqRuleEnum.nextNormalSeq(-5)); |
| | | } |
| | | |
| | | // -------------------------------------------------------- é¢çå·åºå |
| | | |
| | | @Test |
| | | public void testNextReservedSeq_shouldLandOnMultiplesOfTen() { |
| | | assertEquals(10, SeqRuleEnum.nextReservedSeq(1)); |
| | | assertEquals(10, SeqRuleEnum.nextReservedSeq(9)); |
| | | assertEquals("å·²æ¯é¢çå·ååæ ·è¿å", 10, SeqRuleEnum.nextReservedSeq(10)); |
| | | assertEquals(20, SeqRuleEnum.nextReservedSeq(11)); |
| | | assertEquals(20, SeqRuleEnum.nextReservedSeq(19)); |
| | | assertEquals(20, SeqRuleEnum.nextReservedSeq(20)); |
| | | assertEquals(30, SeqRuleEnum.nextReservedSeq(21)); |
| | | } |
| | | |
| | | @Test |
| | | public void testNextReservedSeq_withZeroOrNegative() { |
| | | assertEquals(10, SeqRuleEnum.nextReservedSeq(0)); |
| | | assertEquals(10, SeqRuleEnum.nextReservedSeq(-3)); |
| | | } |
| | | |
| | | // ------------------------------------------------- 两类å·ä¸ç¸äº¤ï¼æ ¸å¿ï¼ |
| | | |
| | | @Test |
| | | public void testNormalAndReservedSequences_shouldNotIntersect() { |
| | | // 模æï¼100 次æ®é + 10 æ¬¡å æ¥ |
| | | Set<Integer> normalSet = new HashSet<>(); |
| | | int last = 0; |
| | | for (int i = 0; i < 100; i++) { |
| | | last = SeqRuleEnum.nextNormalSeq(last + 1); |
| | | normalSet.add(last); |
| | | } |
| | | |
| | | Set<Integer> reservedSet = new HashSet<>(); |
| | | int reservedNext = 10; |
| | | for (int i = 0; i < 10; i++) { |
| | | reservedSet.add(SeqRuleEnum.nextReservedSeq(reservedNext)); |
| | | reservedNext += SeqRuleEnum.ROUND_SIZE; |
| | | } |
| | | |
| | | assertEquals("æ®éå·ä¸å¾éå¤", 100, normalSet.size()); |
| | | assertEquals("é¢çå·ä¸å¾éå¤", 10, reservedSet.size()); |
| | | |
| | | Set<Integer> intersection = new HashSet<>(normalSet); |
| | | intersection.retainAll(reservedSet); |
| | | assertTrue("æ®éå·ä¸é¢çå·éåä¸å¾æäº¤éï¼å®é
交é=" + intersection, intersection.isEmpty()); |
| | | } |
| | | |
| | | /** |
| | | * åè¯ï¼ä¸ºä»ä¹å¿
é¡»"两个ç¬ç«è®¡æ°å¨"ã |
| | | * |
| | | * <p>è¥åªç¨ä¸ä¸ªéå¢è®¡æ°å¨ãå¹¶æ"è·³è¿é¢çå·"åçå¼ç´æ¥å½å·ç ç¨ï¼ |
| | | * ä¼å¨ counter=10 ä¸ counter=11 两次åé
ä¸å¾å°åä¸ä¸ªå· 11ã |
| | | */ |
| | | @Test |
| | | public void testSingleCounterNaiveApproach_wouldCollide_documentingWhyTwoCounters() { |
| | | assertEquals("counter=10 æ¶è·³è¿é¢çå·å¾å° 11", 11, SeqRuleEnum.nextNormalSeq(10)); |
| | | assertEquals("counter=11 æ¶ç´æ¥å¾å° 11", 11, SeqRuleEnum.nextNormalSeq(11)); |
| | | assertEquals("两è
ç¸å â æ´ç´ åæ³å¿
ç¶éå·", |
| | | SeqRuleEnum.nextNormalSeq(10), SeqRuleEnum.nextNormalSeq(11)); |
| | | } |
| | | |
| | | // ------------------------------------------------------------- æ°ç» |
| | | |
| | | @Test |
| | | public void testArrays_containsAllRules() { |
| | | int[] arrays = SeqRuleEnum.ARRAYS; |
| | | assertEquals(3, arrays.length); |
| | | assertEquals(0, arrays[0]); |
| | | assertEquals(1, arrays[1]); |
| | | assertEquals(2, arrays[2]); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.lihu.jh.module.ecg.service.appointment; |
| | | |
| | | import org.junit.Test; |
| | | |
| | | import java.lang.reflect.Method; |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | |
| | | import static org.junit.Assert.*; |
| | | |
| | | /** |
| | | * éå® S050401/S050501ï¼æ£æ¥é¢çº¦ï¼æ¥æä¸æ£æ¥ç±»åçè§£æè¡ä¸ºã |
| | | * |
| | | * <h3>èæ¯ï¼2026-10 ææ¥ç»è®ºï¼</h3> |
| | | * 使£/é¨è¯ç S050401 åè¥**å
äº** S0201ECG å°è¾¾ï¼ä¼èµ° |
| | | * {@code insertAppointmentFromCheckAppointment} 容鿰å¢ï¼ |
| | | * è该路å¾åå
**å®å
¨ä¸è§£ææ£æ¥ç±»å**ï¼å¯¼è´ {@code appointment.book_check_type} æ°¸è¿ä¸ºç©ºã |
| | | * <p>宿µï¼{@code id=213466 / apply_no=8826092420371106}ï¼2026-10-08 07:15 容鿰å¢ï¼ï¼ |
| | | * æ¥æ {@code ZDY} éæææ {@code jcxmcode=201652, jcxmname=å¹³æ¿è¿å¨è¯éª}ï¼ |
| | | * åºæ å°ä¸ºæ¬å° {@code book_check_type=400}ï¼å¹³æ¿è¿å¨å¿çµï¼ã |
| | | * å
¨åºåç±»è®°å½ 279 æ¡ï¼2026-09-29 ~ 10-09ï¼ã |
| | | * |
| | | * <p>æ¬æ¬¡ä¿®å¤æ°å¢ {@code resolveBookCheckTypeFromZdy(ZDY, applyNo)}ï¼å¹¶æ¥å
¥ä¸¤æ¡è·¯å¾ï¼ |
| | | * <ol> |
| | | * <li>容鿰å¢ï¼{@code insertAppointmentFromCheckAppointment}ï¼ï¼</li> |
| | | * <li>æ´æ°å·²æè®°å½ï¼{@code handleCheckAppointmentUpdate}ï¼ã</li> |
| | | * </ol> |
| | | * 两æ¡è·¯å¾åéµå¾ª**ä»
å¨ä¸ºç©ºæ¶è¡¥**ï¼ä¸è¦çå·²æå¼ï¼ã |
| | | */ |
| | | public class HisCheckAppointmentCheckTypeTest { |
| | | |
| | | private Integer invokeResolve(Map<String, Object> zdy) throws Exception { |
| | | AppointmentServiceImpl svc = new AppointmentServiceImpl(); |
| | | Method m = AppointmentServiceImpl.class.getDeclaredMethod( |
| | | "resolveBookCheckTypeFromZdy", Map.class, String.class); |
| | | m.setAccessible(true); |
| | | return (Integer) m.invoke(svc, zdy, "TEST-APPLY-NO"); |
| | | } |
| | | |
| | | private Map<String, Object> zdy(String name, String code) { |
| | | Map<String, Object> m = new HashMap<>(); |
| | | if (name != null) { |
| | | m.put("jcxmname", name); |
| | | } |
| | | if (code != null) { |
| | | m.put("jcxmcode", code); |
| | | } |
| | | return m; |
| | | } |
| | | |
| | | /** ç宿
éæ ·æ¬ï¼å¹³æ¿è¿å¨è¯éª â 400ï¼èµ°åç§°æ å°ï¼ */ |
| | | @Test |
| | | public void testRealCase_pingBanYunDong_shouldMapTo400() throws Exception { |
| | | Integer v = invokeResolve(zdy("å¹³æ¿è¿å¨è¯éª", "201652")); |
| | | assertNotNull("ç宿
éåçæ£æ¥ç±»åå¿
é¡»è½è§£æåºæ¥", v); |
| | | assertEquals("å¹³æ¿è¿å¨è¯éª åºæ å°ä¸º 400ï¼å¹³æ¿è¿å¨å¿çµï¼", Integer.valueOf(400), v); |
| | | System.out.println("[ç宿 ·æ¬] jcxmname=å¹³æ¿è¿å¨è¯éª jcxmcode=201652 -> " + v); |
| | | } |
| | | |
| | | /** HIS æ¹ååºæ¯ï¼ä»
ç»ä»£ç 201652 ä¹è¦è½æ å°ï¼åç§°æ å°ä¸å°æ¶æä»£ç å
åºï¼ */ |
| | | @Test |
| | | public void testNameUnmappable_shouldFallbackToCode() throws Exception { |
| | | Integer v = invokeResolve(zdy("æä¸ªHISæ°å«æ³æªæ¶å½", "201652")); |
| | | assertEquals("åç§°æ å°ä¸å°æ¶åºæä»£ç å
åºä¸º 400", Integer.valueOf(400), v); |
| | | System.out.println("[代ç å
åº] jcxmname=æªæ¶å½ jcxmcode=201652 -> " + v); |
| | | } |
| | | |
| | | /** 代ç 带 Y åç¼ï¼S0201ECG å½¢æï¼ä¹è¦å
¼å®¹ */ |
| | | @Test |
| | | public void testCodeWithYPrefix_shouldBeCompatible() throws Exception { |
| | | assertEquals(Integer.valueOf(400), invokeResolve(zdy(null, "Y201652"))); |
| | | System.out.println("[åç¼å
¼å®¹] jcxmcode=Y201652 -> 400"); |
| | | } |
| | | |
| | | /** å¤å¼ï¼å第ä¸ä¸ªè½æ å°æåçï¼å®æµ S0405 åå¨ jcxmcode=1080,3016,3014 å½¢æï¼ */ |
| | | @Test |
| | | public void testMultiValue_shouldPickFirstMappable() throws Exception { |
| | | // 第ä¸ä¸ªæ¯æ å
³ä»£ç ï¼ç¬¬äºä¸ªææ¯å¿çµé¡¹ç® |
| | | Integer v = invokeResolve(zdy(null, "999999,201652")); |
| | | assertEquals("å¤å¼åºå第ä¸ä¸ªè½æ å°ç", Integer.valueOf(400), v); |
| | | System.out.println("[å¤å¼] jcxmcode=999999,201652 -> " + v); |
| | | } |
| | | |
| | | /** åç§°å¤å¼ï¼ä¸æéå·ï¼ä¹è¦æ¯æ */ |
| | | @Test |
| | | public void testMultiValueName_shouldPickFirstMappable() throws Exception { |
| | | Integer v = invokeResolve(zdy("è¸é¨CTå¹³æ«ï¼å¹³æ¿è¿å¨è¯éª", null)); |
| | | assertEquals("åç§°å¤å¼åºå第ä¸ä¸ªè½æ å°ç", Integer.valueOf(400), v); |
| | | System.out.println("[å¤å¼åç§°] jcxmname=è¸é¨CTå¹³æ«ï¼å¹³æ¿è¿å¨è¯éª -> " + v); |
| | | } |
| | | |
| | | /** å
¶å®å¿çµé¡¹ç®ä¹åºæ£ç¡®æ å°ï¼é²åªçä¸ä¸ªæ ·æ¬ï¼ */ |
| | | @Test |
| | | public void testOtherCheckTypes_shouldMapCorrectly() throws Exception { |
| | | assertEquals(Integer.valueOf(100), invokeResolve(zdy("常è§å¿çµå¾", "691133607"))); |
| | | assertEquals(Integer.valueOf(200), invokeResolve(zdy("24å°æ¶å¨æå¿çµå¾", "201605"))); |
| | | assertEquals(Integer.valueOf(300), invokeResolve(zdy("卿è¡å", "200327"))); |
| | | assertEquals(Integer.valueOf(1100), invokeResolve(zdy("常è§å¿çµå¾-å¿çµåéå¾", "559542128"))); |
| | | System.out.println("[å¤é¡¹ç®] 100/200/300/1100 åæ å°æ£ç¡®"); |
| | | } |
| | | |
| | | /** æ æ³æ å°æ¶è¿å nullï¼è°ç¨æ¹ä¿æåå¼ï¼ä¸ååæ°æ®ï¼ä¸ä¸æå¼å¸¸ */ |
| | | @Test |
| | | public void testUnmappable_shouldReturnNullQuietly() throws Exception { |
| | | assertNull("éå¿çµé¡¹ç®åºè¿å null", invokeResolve(zdy("è¸é¨CTå¹³æ«", "1080"))); |
| | | assertNull("空 ZDY åºè¿å null", invokeResolve(new HashMap<>())); |
| | | assertNull("null ZDY åºè¿å null ä¸ä¸æå¼å¸¸", invokeResolve(null)); |
| | | System.out.println("[å¥å£®æ§] æ æ³æ å°/空/null åè¿å null ä¸ä¸æå¼å¸¸"); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.lihu.jh.module.ecg.service.appointment; |
| | | |
| | | import org.junit.Test; |
| | | |
| | | import java.lang.reflect.Method; |
| | | import java.text.SimpleDateFormat; |
| | | |
| | | import static org.junit.Assert.*; |
| | | |
| | | /** |
| | | * éå® HISãå¼åæ¶é´ã({@code author/time/value}) çè§£æè¡ä¸ºã |
| | | * |
| | | * <h3>èæ¯ï¼2026-10 ææ¥ç»è®ºï¼</h3> |
| | | * åºä¸çº¦ 61% ç {@code appointment.doctor_time} 为 {@code yyyy-MM-dd 00:00:00}ã |
| | | * ç»æ ¸æ¥**䏿¯**æ¬é¡¹ç®çæ ¼å¼å缺é·ï¼åæ¯ datetimeãåå
¥ java.util.Dateã |
| | | * ç宿¥ææ ·ä¾å¸¦æ¶åç§ï¼ï¼èæ¯ **HIS ä¾§æè¯¥åæ®µçæ¶åç§åæäº {@code 000000}**ã |
| | | * è¯æ®ï¼æç宿¶å»çè®°å½åæ£å¸¸å·¥ä½æ¶æ®µåå¸ï¼06:00â08:00 é«å³°ï¼ï¼ |
| | | * è½å¨å¼è¯å 00:00-05:59 çä»
15 æ¡ï¼é¨è¯(book_src=1) 99.6%ãä½é¢(book_src=2) 90.5% 为 0 ç¹ã |
| | | * |
| | | * <p>å æ¤æ¬æ¬¡ä¿®å¤**䏿¹ååå
¥å¼**ï¼ä¿ç HIS åå¼ï¼æ¥æä»ææä¹ï¼ï¼åªå两件äºï¼ |
| | | * <ol> |
| | | * <li>æåå
ãéé»ä¸¢å¼ãçè§£æå¤±è´¥æ¹ä¸ºå¸¦<b>æ¥æåå¼ + ç³è¯·åå·</b>ç WARN æ¥å¿ï¼</li> |
| | | * <li>è¯å«ãæ¥æå¼ãå½¢æå¹¶æ WARNï¼ä¾¿äºå HIS ä¾§åé¦ã</li> |
| | | * </ol> |
| | | * |
| | | * <p>æ¬æµè¯éè¿åå°ç´æ¥éªè¯ç§æè§£ææ¹æ³ï¼ä¿è¯ä¸è¿°è¡ä¸ºä¸è¢«åéã |
| | | */ |
| | | public class HisDoctorTimeParseTest { |
| | | |
| | | /** åå°è°ç¨ç§ææ¹æ³ parseHisDoctorTime(String, String) */ |
| | | private Object invokeParse(String raw) throws Exception { |
| | | AppointmentServiceImpl svc = new AppointmentServiceImpl(); |
| | | Method m = AppointmentServiceImpl.class.getDeclaredMethod( |
| | | "parseHisDoctorTime", String.class, String.class); |
| | | m.setAccessible(true); |
| | | return m.invoke(svc, raw, "TEST-APPLY-NO"); |
| | | } |
| | | |
| | | /** åå°è°ç¨ç§ææ¹æ³ isHisTimeOnlyDate(String) */ |
| | | private boolean invokeIsDateOnly(String raw) throws Exception { |
| | | AppointmentServiceImpl svc = new AppointmentServiceImpl(); |
| | | Method m = AppointmentServiceImpl.class.getDeclaredMethod("isHisTimeOnlyDate", String.class); |
| | | m.setAccessible(true); |
| | | return (Boolean) m.invoke(svc, raw); |
| | | } |
| | | |
| | | /** æ£å¸¸å½¢æï¼14 ä½ä¸å¸¦æ¶åç§ ââ å¿
é¡»åæ ·è§£æåºç宿¶å» */ |
| | | @Test |
| | | public void testNormalTime_shouldParseExactMoment() throws Exception { |
| | | Object parsed = invokeParse("20260917005255"); |
| | | assertNotNull("14 ä½å¸¦æ¶åç§çå¼å¿
须解ææå", parsed); |
| | | String s = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(parsed); |
| | | assertEquals("2026-09-17 00:52:55", s); |
| | | System.out.println("[æ£å¸¸å½¢æ] 20260917005255 -> " + s); |
| | | } |
| | | |
| | | /** ãæ¥æå¼ãå½¢æï¼æ¶åç§=000000 ââ ä»è¦åå
¥ï¼ä¿çæ¥æï¼ï¼åªæ¯ä¼æ WARN */ |
| | | @Test |
| | | public void testDateOnlyValue_shouldStillParseAndKeepDate() throws Exception { |
| | | Object parsed = invokeParse("20261001000000"); |
| | | assertNotNull("æ¥æå¼å½¢æä»åºè§£ææåï¼æ¥æææä¹ï¼ä¸è½ä¸¢ï¼", parsed); |
| | | String s = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(parsed); |
| | | assertEquals("2026-10-01 00:00:00", s); |
| | | assertTrue("åºè¢«è¯å«ä¸ºæ¥æå¼", invokeIsDateOnly("20261001000000")); |
| | | System.out.println("[æ¥æå¼å½¢æ] 20261001000000 -> " + s + "ï¼æ¥æä¿çï¼æ¶å»ä¸º HIS æååå¼ï¼"); |
| | | } |
| | | |
| | | /** ç宿¶å»ä¸åºè¢«è¯¯å¤ä¸ºæ¥æå¼ */ |
| | | @Test |
| | | public void testRealTime_shouldNotBeTreatedAsDateOnly() throws Exception { |
| | | assertFalse(invokeIsDateOnly("20260917005255")); |
| | | assertFalse(invokeIsDateOnly("20261001120000")); |
| | | assertFalse(invokeIsDateOnly("20261001000001")); |
| | | System.out.println("[误å¤é²æ¤] 带ç宿¶åç§çå¼åæªè¢«å¤å®ä¸ºæ¥æå¼"); |
| | | } |
| | | |
| | | /** é 14 ä½ï¼HIS ææ¡£æ ·ä¾ä¸åºç°è¿ 12 ä½ yyyyMMddHHmmï¼ââ è¿å nullï¼ä¸ååº */ |
| | | @Test |
| | | public void testNonFourteenDigit_shouldReturnNull() throws Exception { |
| | | assertNull("12 ä½ä¸åºè¢«è§£æï¼åå®ç°ä¼éé»ä¸¢å¼ï¼ç°æ¹ä¸º WARNï¼", invokeParse("201205061000")); |
| | | assertNull("空串ä¸åºè¢«è§£æ", invokeParse("")); |
| | | assertNull("null ä¸åºè¢«è§£æ", invokeParse(null)); |
| | | System.out.println("[é14ä½] 12 ä½/空/null åè¿å nullï¼å¹¶æ WARNï¼ï¼ä¸ä¼ååæ°æ®"); |
| | | } |
| | | |
| | | /** éæ³æ ¼å¼ä¸åºæå¼å¸¸ï¼é¿å
å½±åæ´æ¡æ¥æè½åºï¼ */ |
| | | @Test |
| | | public void testInvalidFormat_shouldNotThrow() throws Exception { |
| | | assertNull(invokeParse("abc")); |
| | | assertNull(invokeParse("20261301000000")); // 13 æ |
| | | System.out.println("[å¥å£®æ§] éæ³æ ¼å¼è¿å null ä¸ä¸æå¼å¸¸"); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.lihu.jh.module.ecg.service.appointment; |
| | | |
| | | import org.junit.Test; |
| | | |
| | | import java.lang.reflect.Method; |
| | | import java.util.*; |
| | | |
| | | import static org.junit.Assert.*; |
| | | |
| | | /** |
| | | * å彿µè¯ï¼HIS æ¥æè§£æç**ç±»åå®å
¨å¯¼èª**ã |
| | | * |
| | | * <h3>èæ¯</h3> |
| | | * 2026-09-28 ç产æ¥å¿åºç° **287 次** {@code ClassCastException: |
| | | * class java.lang.String cannot be cast to class java.util.Map}ï¼ |
| | | * éä¸å¨ {@code extractCheckCodeFromComponent2} çæ¹æ³çé¾å¼å¼ºå¶è½¬æ¢ä¸ã |
| | | * |
| | | * <p>åå æ¯ HIS æ¥æç» Jackson ååºååå**åä¸å段类åå¹¶ä¸ç¨³å®**ï¼ |
| | | * {@code observationRequest.code} å¨é¨åæ¥æä¸æ¯ {@code Map} |
| | | * ï¼{@code code={code=7,...}}ï¼ï¼å¨å¦ä¸äºæ¥æä¸æ¯**空å符串**ï¼{@code code=}ï¼ã |
| | | * é¾å¼ {@code .map(m -> (Map<String,Object>) m.get("code"))} éå°åç¬¦ä¸²å³æå¼å¸¸ï¼ |
| | | * **å¯¼è´æ´æ¡æ¶æ¯å¤ç䏿**ï¼é¢çº¦æ¶é´ãæ¿é´çåæ®µåä¸è¿åºï¼ã |
| | | * |
| | | * <p>æ¬æµè¯éå®ä¿®å¤åçè¡ä¸ºï¼éå°ä»»æç±»åæ··åé½è¿å null è**䏿å¼å¸¸**ã |
| | | */ |
| | | public class HisParseSafetyTest { |
| | | |
| | | /** æé å
¸åæ¥æçæ®µï¼{@code code=} 为空å符串 */ |
| | | private static Map<String, Object> payloadWithEmptyStringCode() { |
| | | Map<String, Object> codeLeaf = new LinkedHashMap<>(); |
| | | codeLeaf.put("code", ""); // â å
³é®ï¼ç©ºå符串èé Map |
| | | codeLeaf.put("displayName", mapOf("value", "æ£æ¥ç»æ")); |
| | | |
| | | Map<String, Object> obs = new LinkedHashMap<>(); |
| | | obs.put("id", mapOf("item", mapOf("extension", "2126092800574"))); |
| | | obs.put("code", ""); // â å
³é®ï¼observationRequest.code æ¯ç©ºå符串 |
| | | obs.put("component1", mapOf("processStep", mapOf("code", codeLeaf))); |
| | | obs.put("component2", mapOf("observationRequest", mapOf("code", ""))); |
| | | |
| | | return mapOf("controlActProcess", |
| | | mapOf("subject", mapOf("placerGroup", mapOf("component2", obs)))); |
| | | } |
| | | |
| | | /** æ£å¸¸å½¢æï¼{@code code} æ¯ Mapï¼æ S0201ECG çå®ç»ææé ï¼ */ |
| | | private static Map<String, Object> payloadWithMapCode() { |
| | | // æ£æ¥ç¶æï¼component2.observationRequest.component1.processStep.code.code |
| | | Map<String, Object> statusCode = mapOf( |
| | | "code", "7", |
| | | "codeSystem", "2.16.156.10011.2.5.1.12", |
| | | "displayName", mapOf("value", "æ£æ¥ç»æ")); |
| | | Map<String, Object> processStep = mapOf("code", statusCode); |
| | | Map<String, Object> component1 = mapOf("processStep", processStep); |
| | | |
| | | // æ£æ¥é¡¹ç®ï¼component2.observationRequest.code.code |
| | | Map<String, Object> checkCode = mapOf( |
| | | "code", "Y1202065", |
| | | "displayName", mapOf("value", "åºè¾¹å¿çµå¾(常è§+é¢è°±)")); |
| | | |
| | | Map<String, Object> innerObs = mapOf( |
| | | "id", mapOf("item", mapOf("root", "2.16.156.10011.1.28", "extension", "113034157")), |
| | | "code", checkCode, |
| | | "component1", component1); |
| | | |
| | | Map<String, Object> component2 = mapOf("observationRequest", innerObs); |
| | | |
| | | Map<String, Object> outerObs = mapOf("component2", component2); |
| | | |
| | | return mapOf("controlActProcess", |
| | | mapOf("subject", |
| | | mapOf("observationRequest", outerObs))); |
| | | } |
| | | |
| | | private static Map<String, Object> mapOf(Object... kv) { |
| | | Map<String, Object> m = new LinkedHashMap<>(); |
| | | for (int i = 0; i + 1 < kv.length; i += 2) { |
| | | m.put((String) kv[i], kv[i + 1]); |
| | | } |
| | | return m; |
| | | } |
| | | |
| | | /** åå°è°ç¨ç§æç dig æ¹æ³ */ |
| | | private static Map<String, Object> invokeDig(Map<String, Object> root, String... path) throws Exception { |
| | | Method m = AppointmentServiceImpl.class.getDeclaredMethod("dig", Map.class, String[].class); |
| | | m.setAccessible(true); |
| | | @SuppressWarnings("unchecked") |
| | | Map<String, Object> r = (Map<String, Object>) m.invoke(null, root, path); |
| | | return r; |
| | | } |
| | | |
| | | /** åå°è°ç¨ç§æç digText æ¹æ³ */ |
| | | private static String invokeDigText(Map<String, Object> root, String... path) throws Exception { |
| | | Method m = AppointmentServiceImpl.class.getDeclaredMethod("digText", Map.class, String[].class); |
| | | m.setAccessible(true); |
| | | return (String) m.invoke(null, root, path); |
| | | } |
| | | |
| | | // ==================== æ ¸å¿ï¼ä¸å¾æ ClassCastException ==================== |
| | | |
| | | @Test |
| | | public void testDigText_emptyStringInPath_shouldReturnNullNotThrow() throws Exception { |
| | | Map<String, Object> payload = payloadWithEmptyStringCode(); |
| | | // code æ¯ç©ºå符串 â åºå®å
¨è¿å nullï¼è䏿¯æ ClassCastException |
| | | String v = invokeDigText(payload, "controlActProcess", "subject", "placerGroup", |
| | | "component2", "observationRequest", "code", "code"); |
| | | assertNull(v); |
| | | } |
| | | |
| | | @Test |
| | | public void testDigText_stringWhereMapExpected_shouldNotThrow() throws Exception { |
| | | // æ´æ¡è·¯å¾ä¸æ¾åç¬¦ä¸²ï¼æ¨¡æææ¶å£çå½¢æ |
| | | Map<String, Object> payload = mapOf("controlActProcess", "I-AM-A-STRING"); |
| | | assertNull(invokeDigText(payload, "controlActProcess", "subject", "placerGroup")); |
| | | } |
| | | |
| | | @Test |
| | | public void testDig_emptyStringInPath_shouldReturnNullNotThrow() throws Exception { |
| | | Map<String, Object> payload = payloadWithEmptyStringCode(); |
| | | assertNull(invokeDig(payload, "controlActProcess", "subject", "placerGroup", |
| | | "component2", "observationRequest", "component1", "processStep", "code", "ZDY")); |
| | | } |
| | | |
| | | @Test |
| | | public void testDig_nullInPath_shouldReturnNull() throws Exception { |
| | | assertNull(invokeDig(mapOf("a", null), "a", "b")); |
| | | assertNull(invokeDig(new LinkedHashMap<>(), "notExist")); |
| | | } |
| | | |
| | | @Test |
| | | public void testDigText_listInPath_shouldTakeFirstElement() throws Exception { |
| | | // item=[{code=X}] å½¢æï¼digText åºèªå¨åé¦å
ç´ ç»§ç»ä¸é» |
| | | Map<String, Object> payload = mapOf("methodCode", |
| | | mapOf("item", Collections.singletonList(mapOf("code", "M001")))); |
| | | assertEquals("M001", invokeDigText(payload, "methodCode", "item", "code")); |
| | | } |
| | | |
| | | @Test |
| | | public void testDigText_emptyListInPath_shouldReturnNull() throws Exception { |
| | | Map<String, Object> payload = mapOf("methodCode", mapOf("item", Collections.emptyList())); |
| | | assertNull(invokeDigText(payload, "methodCode", "item", "code")); |
| | | } |
| | | |
| | | @Test |
| | | public void testDigText_shouldStillReadNormalValues() throws Exception { |
| | | Map<String, Object> payload = payloadWithMapCode(); |
| | | // æ£å¸¸å½¢æå¿
é¡»ç
§å¸¸è¯»åºï¼ä¸è½å å äºé²å¾¡è失æ |
| | | // ä¸ç产代ç extractCheckCodeFromComponent2 使ç¨çæ¯**åæ ·çè·¯å¾åæ³** |
| | | assertEquals("Y1202065", invokeDigText(payload, "controlActProcess", "subject", |
| | | "observationRequest", "component2", "observationRequest", "code", "code")); |
| | | } |
| | | |
| | | @Test |
| | | public void testDigText_shouldReadProcessStepStatus() throws Exception { |
| | | // æ£æ¥ç¶æç ï¼controlActProcess.subject.observationRequest.component2 |
| | | // .observationRequest.component1.processStep.code.code |
| | | Map<String, Object> payload = payloadWithMapCode(); |
| | | assertEquals("7", invokeDigText(payload, "controlActProcess", "subject", |
| | | "observationRequest", "component2", "observationRequest", |
| | | "component1", "processStep", "code", "code")); |
| | | } |
| | | |
| | | @Test |
| | | public void testDigText_basicTraversal() throws Exception { |
| | | // æåºç¡ï¼ä¸å± Map åå¼ |
| | | Map<String, Object> payload = mapOf("a", mapOf("b", mapOf("c", "VALUE"))); |
| | | assertEquals("VALUE", invokeDigText(payload, "a", "b", "c")); |
| | | // ä¸¤å± |
| | | assertEquals("X", invokeDigText(mapOf("a", mapOf("b", "X")), "a", "b")); |
| | | // ä¸å± |
| | | assertEquals("Y", invokeDigText(mapOf("a", "Y"), "a")); |
| | | // Map æ«ç«¯å value |
| | | assertEquals("Z", invokeDigText(mapOf("a", mapOf("b", mapOf("value", "Z"))), "a", "b")); |
| | | } |
| | | |
| | | @Test |
| | | public void testDigText_blankString_shouldReturnNull() throws Exception { |
| | | // 空/纯空ç½å符串åºè§ä¸º"æ å¼"ï¼ä¾¿äºä¸å±ç¨ isEmpty 夿 |
| | | Map<String, Object> payload = mapOf("k", " "); |
| | | assertNull(invokeDigText(payload, "k")); |
| | | assertNull(invokeDigText(mapOf("k", ""), "k")); |
| | | } |
| | | |
| | | // ==================== å»å±å·æåï¼findExtensionByRootï¼ ==================== |
| | | // |
| | | // 便® HISãäº¤äºæå¡éç¨æ¥å£ææ¡£ãï¼ |
| | | // 6.1 ç³è¯·åæ°å¢æå¡ â observationRequest.id.item[root=2.16.156.10011.1.28] 注é为ãå»å±IDã |
| | | // 6.4 æ£æ¥é¢çº¦ç¶ææå¡ â åä¸ root 注é为ãå»å±å·ã |
| | | // 宿µ S0201ECG 220 æ¡ãS0202ECG 29 æ¡åæºå¸¦è¯¥å¼ï¼å½¢å¦ 112663505ï¼ã |
| | | // |
| | | // å
³é®é£é©ï¼id.item å¨é¨åæå¡ä¸æ¯**æ°ç»**ï¼åæ¶å« |
| | | // 1.24 ç³è¯·åå· ä¸ 1.28 å»å±å· |
| | | // è¥ç¨ digTextï¼é List åªåé¦å
ç´ ï¼ä¼æ**ç³è¯·åå·å½æå»å±å·**ã |
| | | // ä¸åç¨ä¾éå®ãæ root å¹é
ãçæ£ç¡®è¡ä¸ºã |
| | | |
| | | private static final String ROOT_ORDER_NO = "2.16.156.10011.1.28"; |
| | | private static final String ROOT_APPLY_NO = "2.16.156.10011.1.24"; |
| | | |
| | | /** åå°è°ç¨ç§æç findExtensionByRoot æ¹æ³ */ |
| | | private static String invokeFindExtensionByRoot(Object idNode, String root) throws Exception { |
| | | Method m = AppointmentServiceImpl.class.getDeclaredMethod("findExtensionByRoot", Object.class, String.class); |
| | | m.setAccessible(true); |
| | | return (String) m.invoke(null, idNode, root); |
| | | } |
| | | |
| | | @Test |
| | | public void testFindExtensionByRoot_singleMap_shouldReturnExtension() throws Exception { |
| | | // 宿µ S0201ECG ççå®å½¢æï¼id={item={root=1.28, extension=112663505}} |
| | | Object idNode = mapOf("item", mapOf("root", ROOT_ORDER_NO, "extension", "112663505")); |
| | | assertEquals("112663505", invokeFindExtensionByRoot(idNode, ROOT_ORDER_NO)); |
| | | } |
| | | |
| | | @Test |
| | | public void testFindExtensionByRoot_listWithBothRoots_shouldPickOrderNo() throws Exception { |
| | | // å
³é®ç¨ä¾ï¼æ°ç»åæ¶å« 1.24(ç³è¯·åå·) ä¸ 1.28(å»å±å·) |
| | | // digText ä¼åé¦å
ç´ ï¼ç³è¯·åå·ï¼â éï¼findExtensionByRoot å¿
é¡»æ root å½ä¸ 1.28 |
| | | List<Object> items = Arrays.asList( |
| | | mapOf("root", ROOT_APPLY_NO, "extension", "2126091700011"), |
| | | mapOf("root", ROOT_ORDER_NO, "extension", "112663505")); |
| | | Object idNode = mapOf("item", items); |
| | | assertEquals("112663505", invokeFindExtensionByRoot(idNode, ROOT_ORDER_NO)); |
| | | } |
| | | |
| | | @Test |
| | | public void testFindExtensionByRoot_listWithBothRoots_reverseOrder_shouldStillPickOrderNo() throws Exception { |
| | | // 顺åºé¢ åä¹å¿
é¡»å½ä¸ï¼ä¸è½ä¾èµ"æ°å¥½ç¬¬ä¸ä¸ªæ¯å»å±å·"ï¼ |
| | | List<Object> items = Arrays.asList( |
| | | mapOf("root", ROOT_ORDER_NO, "extension", "112663700"), |
| | | mapOf("root", ROOT_APPLY_NO, "extension", "2126091700012")); |
| | | assertEquals("112663700", invokeFindExtensionByRoot(mapOf("item", items), ROOT_ORDER_NO)); |
| | | } |
| | | |
| | | @Test |
| | | public void testFindExtensionByRoot_listWithoutOrderNo_shouldReturnNull() throws Exception { |
| | | // åªæç³è¯·åå·æ¶ï¼ç»ä¸è½æç³è¯·åå·å½å»å±å·è¿å |
| | | List<Object> items = Collections.singletonList( |
| | | mapOf("root", ROOT_APPLY_NO, "extension", "2126091700011")); |
| | | assertNull(invokeFindExtensionByRoot(mapOf("item", items), ROOT_ORDER_NO)); |
| | | } |
| | | |
| | | @Test |
| | | public void testFindExtensionByRoot_emptyOrBlankExtension_shouldReturnNull() throws Exception { |
| | | // è§èä¸è¯¥èç¹ extension å¯ä¸ºç©ºï¼6.1 示ä¾å³ extension=""ï¼â åºè¿å null èé空串 |
| | | assertNull(invokeFindExtensionByRoot( |
| | | mapOf("item", mapOf("root", ROOT_ORDER_NO, "extension", "")), ROOT_ORDER_NO)); |
| | | assertNull(invokeFindExtensionByRoot( |
| | | mapOf("item", mapOf("root", ROOT_ORDER_NO, "extension", " ")), ROOT_ORDER_NO)); |
| | | assertNull(invokeFindExtensionByRoot( |
| | | mapOf("item", mapOf("root", ROOT_ORDER_NO)), ROOT_ORDER_NO)); |
| | | } |
| | | |
| | | @Test |
| | | public void testFindExtensionByRoot_nullAndMalformed_shouldReturnNullNotThrow() throws Exception { |
| | | assertNull(invokeFindExtensionByRoot(null, ROOT_ORDER_NO)); |
| | | assertNull(invokeFindExtensionByRoot(new LinkedHashMap<>(), ROOT_ORDER_NO)); |
| | | assertNull(invokeFindExtensionByRoot(mapOf("item", null), ROOT_ORDER_NO)); |
| | | assertNull(invokeFindExtensionByRoot(mapOf("item", Collections.emptyList()), ROOT_ORDER_NO)); |
| | | // item æ¯å符串ï¼ç±»åä¸ç¨³å®ï¼â ä¸å¾æå¼å¸¸ |
| | | assertNull(invokeFindExtensionByRoot(mapOf("item", "I-AM-A-STRING"), ROOT_ORDER_NO)); |
| | | // root 缺失 |
| | | assertNull(invokeFindExtensionByRoot(mapOf("item", mapOf("extension", "X")), ROOT_ORDER_NO)); |
| | | // root 为 null |
| | | assertNull(invokeFindExtensionByRoot(mapOf("item", mapOf("root", null, "extension", "X")), ROOT_ORDER_NO)); |
| | | } |
| | | |
| | | @Test |
| | | public void testFindExtensionByRoot_listContainingNonMap_shouldSkipGracefully() throws Exception { |
| | | List<Object> items = Arrays.asList( |
| | | "NOT-A-MAP", |
| | | mapOf("root", ROOT_ORDER_NO, "extension", "112663932")); |
| | | assertEquals("112663932", invokeFindExtensionByRoot(mapOf("item", items), ROOT_ORDER_NO)); |
| | | } |
| | | |
| | | @Test |
| | | public void testFindExtensionByRoot_rootWithWhitespace_shouldStillMatch() throws Exception { |
| | | // æ¥æé root å¯è½å¸¦ç©ºç½ï¼é trim åæ¯è¾ |
| | | Object idNode = mapOf("item", mapOf("root", " " + ROOT_ORDER_NO + " ", "extension", "112664036")); |
| | | assertEquals("112664036", invokeFindExtensionByRoot(idNode, ROOT_ORDER_NO)); |
| | | } |
| | | |
| | | // ====================================================================== |
| | | // éæ±2ï¼ISCBãæ¯å¦åºè¾¹ãè§£æï¼zdy èªå®ä¹å段åºï¼ |
| | | // ====================================================================== |
| | | |
| | | /** åå°è°ç¨ç§æç findBedsideFlag(dataMap) */ |
| | | private static String invokeFindBedsideFlag(Map<String, Object> dataMap) throws Exception { |
| | | Method m = AppointmentServiceImpl.class.getDeclaredMethod("findBedsideFlag", Map.class); |
| | | m.setAccessible(true); |
| | | return (String) m.invoke(null, dataMap); |
| | | } |
| | | |
| | | /** æçå® S0201ECG ç»ææé å« zdy çæ¥æ */ |
| | | private static Map<String, Object> payloadWithZdy(Map<String, Object> zdyContent) { |
| | | Map<String, Object> obs = new LinkedHashMap<>(); |
| | | obs.put("zdy", zdyContent); |
| | | return mapOf("controlActProcess", mapOf("subject", mapOf("observationRequest", obs))); |
| | | } |
| | | |
| | | @Test |
| | | public void testFindBedsideFlag_presentZero_shouldReturnZero() throws Exception { |
| | | // 宿µç宿¥æä¸ ISCB æä¸º "0" |
| | | Map<String, Object> zdy = new LinkedHashMap<>(); |
| | | zdy.put("ISCB", "0"); |
| | | zdy.put("ISDN", "0"); |
| | | assertEquals("0", invokeFindBedsideFlag(payloadWithZdy(zdy))); |
| | | } |
| | | |
| | | @Test |
| | | public void testFindBedsideFlag_presentOne_shouldReturnOne() throws Exception { |
| | | Map<String, Object> zdy = new LinkedHashMap<>(); |
| | | zdy.put("ISCB", "1"); |
| | | assertEquals("1", invokeFindBedsideFlag(payloadWithZdy(zdy))); |
| | | } |
| | | |
| | | @Test |
| | | public void testFindBedsideFlag_absent_shouldReturnNull() throws Exception { |
| | | // 宿¹ææ¡£å®ä¹ç 19 ä¸ªåæ®µé没æ ISCB ââ è¿ç±»æ¥æåºè¿å nullï¼ä¸ååºï¼ |
| | | Map<String, Object> zdy = new LinkedHashMap<>(); |
| | | zdy.put("jjbz", "N"); |
| | | zdy.put("babyFlag", "0"); |
| | | assertNull(invokeFindBedsideFlag(payloadWithZdy(zdy))); |
| | | } |
| | | |
| | | @Test |
| | | public void testFindBedsideFlag_emptyString_shouldReturnNull() throws Exception { |
| | | Map<String, Object> zdy = new LinkedHashMap<>(); |
| | | zdy.put("ISCB", ""); |
| | | assertNull("空å符串åºè§ä½æªæä¾", invokeFindBedsideFlag(payloadWithZdy(zdy))); |
| | | |
| | | Map<String, Object> zdy2 = new LinkedHashMap<>(); |
| | | zdy2.put("ISCB", " "); |
| | | assertNull("纯空ç½åºè§ä½æªæä¾", invokeFindBedsideFlag(payloadWithZdy(zdy2))); |
| | | } |
| | | |
| | | @Test |
| | | public void testFindBedsideFlag_nonStringValue_shouldToString() throws Exception { |
| | | // Jackson ååºåååæ éç±»åå¯è½æ¯ Integer/Booleanï¼é稳妥 toString |
| | | Map<String, Object> zdy = new LinkedHashMap<>(); |
| | | zdy.put("ISCB", 1); |
| | | assertEquals("1", invokeFindBedsideFlag(payloadWithZdy(zdy))); |
| | | |
| | | Map<String, Object> zdy2 = new LinkedHashMap<>(); |
| | | zdy2.put("ISCB", 0); |
| | | assertEquals("0", invokeFindBedsideFlag(payloadWithZdy(zdy2))); |
| | | } |
| | | |
| | | @Test |
| | | public void testFindBedsideFlag_whitespaceAroundValue_shouldTrim() throws Exception { |
| | | Map<String, Object> zdy = new LinkedHashMap<>(); |
| | | zdy.put("ISCB", " 1 "); |
| | | assertEquals("1", invokeFindBedsideFlag(payloadWithZdy(zdy))); |
| | | } |
| | | |
| | | @Test |
| | | public void testFindBedsideFlag_nullOrMalformedPayload_shouldReturnNullWithoutThrow() throws Exception { |
| | | // ç±»åä¸ç¨³å®æ¯ HIS æ¥æç常æï¼åå²ä¸æ¾å æ¤æ ClassCastException ä¸ææ´æ¡æ¶æ¯ï¼ï¼ |
| | | // è¿éå¿
é¡»**䏿å¼å¸¸** |
| | | assertNull(invokeFindBedsideFlag(null)); |
| | | assertNull(invokeFindBedsideFlag(mapOf())); |
| | | assertNull("controlActProcess æ¯å符串", invokeFindBedsideFlag(mapOf("controlActProcess", "x"))); |
| | | assertNull("subject æ¯ç©ºå符串", invokeFindBedsideFlag( |
| | | mapOf("controlActProcess", mapOf("subject", "")))); |
| | | assertNull("observationRequest 缺失", invokeFindBedsideFlag( |
| | | mapOf("controlActProcess", mapOf("subject", mapOf())))); |
| | | assertNull("zdy æ¯å符串èé Map", invokeFindBedsideFlag( |
| | | mapOf("controlActProcess", mapOf("subject", |
| | | mapOf("observationRequest", mapOf("zdy", "not-a-map")))))); |
| | | } |
| | | |
| | | @Test |
| | | public void testFindBedsideFlag_realisticFullZdy_shouldReturnValue() throws Exception { |
| | | // ç宿¥æç zdy æ 26 ä¸ªåæ®µï¼ææ¡£åªå®ä¹ 19 个ï¼ï¼ææ¥å¿åæ ·æé å
³é®é¨å |
| | | Map<String, Object> zdy = new LinkedHashMap<>(); |
| | | zdy.put("ApplyTotalFee", "19"); |
| | | zdy.put("Urgency", ""); |
| | | zdy.put("PayStatus", "1"); |
| | | zdy.put("HospitalCode", "01"); |
| | | zdy.put("HospitalName", "éåå¸äººæ°å»é¢"); |
| | | zdy.put("jjbz", "N"); |
| | | zdy.put("babyFlag", "0"); |
| | | zdy.put("ISCB", "1"); // â éæ±2 å
³æ³¨çåæ®µ |
| | | zdy.put("ISDN", "0"); |
| | | zdy.put("BLLSH", "3054365"); |
| | | zdy.put("SWCJBS", "0"); |
| | | zdy.put("KDYSSJH", "15158660102"); |
| | | zdy.put("KLX", ""); |
| | | zdy.put("VTEGWBZ", "0"); |
| | | assertEquals("1", invokeFindBedsideFlag(payloadWithZdy(zdy))); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.lihu.jh.module.ecg.service.appointment; |
| | | |
| | | import cn.lihu.jh.framework.common.util.object.BeanUtils; |
| | | import cn.lihu.jh.module.ecg.controller.admin.appointment.vo.AppointmentSaveReqVO; |
| | | import cn.lihu.jh.module.ecg.dal.dataobject.appointment.AppointmentDO; |
| | | import org.junit.Test; |
| | | |
| | | import java.sql.Connection; |
| | | import java.sql.DriverManager; |
| | | import java.sql.PreparedStatement; |
| | | import java.sql.ResultSet; |
| | | import java.sql.Statement; |
| | | import java.text.SimpleDateFormat; |
| | | |
| | | import static org.junit.Assert.*; |
| | | |
| | | /** |
| | | * éå® {@code register_date}ãæ¶é´è¢«æªæä¸º 00:00:00ãçæå ä¸ä¿®å¤ã |
| | | * |
| | | * <h3>ç°è±¡</h3> |
| | | * 2026-09-27 èµ· {@code appointment.register_date} 大éåæ {@code yyyy-MM-dd 00:00:00}ï¼ |
| | | * è 09-26 ä¹åæ¯ {@code 2026-09-26 16:58:53} è¿æ ·ç宿´æ¶é´ã |
| | | * |
| | | * <h3>æå ï¼ç»å®éªç¡®å®ï¼</h3> |
| | | * {@code java.sql.Date} æ¯**åªè¡¨ç¤ºæ¥æ**ç JDBC ç±»åï¼æå®åå
¥ {@code DATETIME} åæ¶ï¼ |
| | | * æ¶é´é¨åå¿
ç¶åæ {@code 00:00:00}ã宿µï¼åè¿æ¥ä¸²ãååï¼ï¼ |
| | | * <pre> |
| | | * setObject(java.util.Date) â 2026-09-26 16:58:53 ä¿ç |
| | | * setObject(java.sql.Date) â 2026-09-26 00:00:00 ä¸¢å¼ |
| | | * </pre> |
| | | * è {@code AppointmentSaveReqVO}/{@code AppointmentRespVO}/{@code AppointmentPageReqVO} |
| | | * åå
齿 {@code registerDate}/{@code doctorTime} 声æä¸º {@code java.sql.Date} |
| | | * ï¼ç» {@code import java.sql.Date;}ï¼ï¼å¯¹åºç {@code AppointmentDO} å´æ¯ |
| | | * {@code java.util.Date} ââ ç±»åä¸ä¸è´å¯¼è´å¾è¿è¿ç¨ä¸æ¶é´ä¸¢å¤±ã |
| | | * |
| | | * <h3>ä¿®å¤</h3> |
| | | * ä¸ä¸ª VO ç»ä¸æ¹ä¸º {@code java.util.Date}ãæ¬æµè¯éå®ãç±»åä¸è´ãè¿ä¸çº¦æã |
| | | */ |
| | | public class RegisterDateTruncationTest { |
| | | |
| | | private static final String SAMPLE = "2026-09-26 16:58:53"; |
| | | |
| | | /** ç产/æµè¯åºè¿æ¥ä¸²ï¼ä¸ application-local.yaml ä¸è´ï¼ */ |
| | | private static final String JDBC_URL = |
| | | "jdbc:mysql://47.93.127.38:3308/lihu?useSSL=false&serverTimezone=Asia/Shanghai" |
| | | + "&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true"; |
| | | |
| | | /** |
| | | * æ ¸å¿çº¦æï¼VO ä¸ DO ç registerDate/doctorTime å¿
é¡»æ¯**åä¸ç§** Date ç±»åï¼ |
| | | * ä¸é½ä¸æ¯ {@code java.sql.Date}ï¼å¦åæ¶é´ä¼è¢«ä¸¢å¼ï¼ã |
| | | */ |
| | | @Test |
| | | public void testRegisterDateTypes_shouldBeConsistentAndNotSqlDate() throws Exception { |
| | | Class<?> voReg = AppointmentSaveReqVO.class.getDeclaredField("registerDate").getType(); |
| | | Class<?> voDoc = AppointmentSaveReqVO.class.getDeclaredField("doctorTime").getType(); |
| | | Class<?> doReg = AppointmentDO.class.getDeclaredField("registerDate").getType(); |
| | | Class<?> doDoc = AppointmentDO.class.getDeclaredField("doctorTime").getType(); |
| | | |
| | | System.out.println("[ç±»å] VO.registerDate = " + voReg.getName()); |
| | | System.out.println("[ç±»å] VO.doctorTime = " + voDoc.getName()); |
| | | System.out.println("[ç±»å] DO.registerDate = " + doReg.getName()); |
| | | System.out.println("[ç±»å] DO.doctorTime = " + doDoc.getName()); |
| | | |
| | | assertNotEquals("VO.registerDate ä¸å¾ä¸º java.sql.Dateï¼ä¼ä¸¢å¼æ¶åç§ï¼", |
| | | "java.sql.Date", voReg.getName()); |
| | | assertNotEquals("VO.doctorTime ä¸å¾ä¸º java.sql.Date", |
| | | "java.sql.Date", voDoc.getName()); |
| | | assertEquals("VO ä¸ DO ç registerDate ç±»åå¿
é¡»ä¸è´", |
| | | doReg.getName(), voReg.getName()); |
| | | assertEquals("VO ä¸ DO ç doctorTime ç±»åå¿
é¡»ä¸è´", |
| | | doDoc.getName(), voDoc.getName()); |
| | | } |
| | | |
| | | /** å¾è¿è½¬æ¢ä¸å¾ä¸¢å¤±æ¶é´ */ |
| | | @Test |
| | | public void testDoToVoToDo_keepsTime() throws Exception { |
| | | AppointmentDO source = new AppointmentDO(); |
| | | source.setApplyNo("TEST_TRUNC_1"); |
| | | source.setRegisterDate(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(SAMPLE)); |
| | | source.setDoctorTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(SAMPLE)); |
| | | |
| | | AppointmentSaveReqVO vo = BeanUtils.toBean(source, AppointmentSaveReqVO.class); |
| | | AppointmentDO back = BeanUtils.toBean(vo, AppointmentDO.class); |
| | | |
| | | String reg = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(back.getRegisterDate()); |
| | | String doc = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(back.getDoctorTime()); |
| | | System.out.println("[å¾è¿] registerDate = " + reg + " doctorTime = " + doc); |
| | | |
| | | assertEquals("registerDate ç» VO å¾è¿åä¸åºä¸¢å¤±æ¶é´", SAMPLE, reg); |
| | | assertEquals("doctorTime ç» VO å¾è¿åä¸åºä¸¢å¤±æ¶é´", SAMPLE, doc); |
| | | } |
| | | |
| | | /** |
| | | * å¤ç°å®éªï¼éè¦æµè¯åºå¯è®¿é®ï¼ï¼è¯æãjava.sql.Date â DATETIME åãå¿
ç¶æªæã |
| | | * <p>è¥æ°æ®åºä¸å¯è¾¾åè·³è¿ï¼ä¸å½±åå
¶å®æè¨çä»·å¼ï¼ã |
| | | */ |
| | | @Test |
| | | public void testJdbcWrite_sqlDateTruncates_utilDateKeeps() throws Exception { |
| | | Connection c = null; |
| | | try { |
| | | c = DriverManager.getConnection(JDBC_URL, "smartor", "Smartor.2016"); |
| | | } catch (Exception e) { |
| | | System.out.println("[è·³è¿] æ°æ®åºä¸å¯è¾¾: " + e.getMessage()); |
| | | return; |
| | | } |
| | | try { |
| | | c.setAutoCommit(false); |
| | | try (Statement s = c.createStatement()) { |
| | | s.execute("DROP TABLE IF EXISTS _probe_regdate_test"); |
| | | s.execute("CREATE TABLE _probe_regdate_test (id INT PRIMARY KEY AUTO_INCREMENT, " |
| | | + "d_util DATETIME NULL, d_sql DATETIME NULL)"); |
| | | } |
| | | java.util.Date utilDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(SAMPLE); |
| | | java.sql.Date sqlDate = new java.sql.Date(utilDate.getTime()); |
| | | try (PreparedStatement ps = c.prepareStatement( |
| | | "INSERT INTO _probe_regdate_test (d_util, d_sql) VALUES (?,?)")) { |
| | | ps.setObject(1, utilDate); |
| | | ps.setObject(2, sqlDate); |
| | | ps.executeUpdate(); |
| | | } |
| | | try (Statement s = c.createStatement(); |
| | | ResultSet r = s.executeQuery("SELECT d_util, d_sql FROM _probe_regdate_test")) { |
| | | assertTrue(r.next()); |
| | | String util = r.getString(1); |
| | | String sql = r.getString(2); |
| | | System.out.println("[å®éª] java.util.Date â " + util); |
| | | System.out.println("[å®éª] java.sql.Date â " + sql); |
| | | |
| | | assertEquals("java.util.Date åºä¿çæ¶åç§", SAMPLE, util); |
| | | assertEquals("java.sql.Date å¿
ç¶ä¸¢æ 00:00:00", |
| | | "2026-09-26 00:00:00", sql); |
| | | } |
| | | try (Statement s = c.createStatement()) { s.execute("DROP TABLE _probe_regdate_test"); } |
| | | c.rollback(); |
| | | } finally { |
| | | if (c != null) { try { c.close(); } catch (Exception ignore) { } } |
| | | } |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.lihu.jh.module.ecg.service.his; |
| | | |
| | | import org.junit.Test; |
| | | |
| | | import java.util.Arrays; |
| | | import java.util.Collections; |
| | | |
| | | import static org.junit.Assert.*; |
| | | |
| | | /** |
| | | * å¿çµä¸å¡åå¤å®ï¼{@link HisEcgFilter}ï¼å彿µè¯ã |
| | | * |
| | | * <p>å
¨é¨æµè¯æ°æ®åèª 2026-09-17 ç产æ¥å¿ä¸çç宿¥æå¼ï¼ |
| | | * <ul> |
| | | * <li><b>å¿çµå</b>ï¼{@code S0201ECG} / {@code S0405} ä¸å±å¿çµçå·ä¸æ£æ¥é¡¹ç®ï¼</li> |
| | | * <li><b>éå¿çµå</b>ï¼å䏿¶é´çªå
{@code S0405} æ¨éçæ¾å°/è¶
声å |
| | | * ï¼å®æµå 96.5%ï¼æ¯æ¬æ¬¡è¿æ»¤è¦æ¦æç主ä½ï¼ã</li> |
| | | * </ul> |
| | | * |
| | | * @author å¿çµæéè£
æºç³»ç» |
| | | */ |
| | | public class HisEcgFilterTest { |
| | | |
| | | private HisEcgFilter filter = new HisEcgFilter(); |
| | | |
| | | // ==================== 便® Aï¼ç³è¯·åå·åç¼ ==================== |
| | | |
| | | @Test |
| | | public void testSuffix_shouldMatchEcgApplyNo() { |
| | | // æ¥å¿å®æµçå¿çµç³è¯·åå·ï¼S0201ECG åå»ºï¼ |
| | | assertTrue(filter.matchApplyNoSuffix("8826091720001101")); |
| | | assertTrue(filter.matchApplyNoSuffix("8826081120716401")); |
| | | assertTrue(filter.matchApplyNoSuffix("8826091520521101")); |
| | | assertTrue(filter.matchApplyNoSuffix("8826091420571101")); |
| | | } |
| | | |
| | | @Test |
| | | public void testSuffix_shouldNotMatchRadiologyApplyNo() { |
| | | // æ¥å¿å®æµçæ¾å°/è¶
声ç³è¯·åå·ï¼S0405 æ¨éï¼çº¯æ°åæµæ°´å·ï¼æ å¿çµåç¼ï¼ |
| | | assertFalse(filter.matchApplyNoSuffix("2126091602867")); |
| | | assertFalse(filter.matchApplyNoSuffix("2126091700001")); |
| | | assertFalse(filter.matchApplyNoSuffix("2126091700038")); |
| | | assertFalse(filter.matchApplyNoSuffix("2126091700190")); |
| | | } |
| | | |
| | | @Test |
| | | public void testSuffix_shouldHandleBlank() { |
| | | assertFalse(filter.matchApplyNoSuffix(null)); |
| | | assertFalse(filter.matchApplyNoSuffix("")); |
| | | assertFalse(filter.matchApplyNoSuffix(" ")); |
| | | } |
| | | |
| | | // ==================== 便® Bï¼æ£æ¥é¡¹ç®ä»£ç / åç§° ==================== |
| | | |
| | | @Test |
| | | public void testCheckCode_shouldMatchWithAndWithoutPrefix() { |
| | | // æ¥å¿å®æµï¼S0201ECG æ¥æç component2...code.code = "Y1202065"ï¼åºè¾¹å¿çµå¾ï¼ |
| | | // HisCheckCodeEnum ç code 为å»åç¼åç "1202065" |
| | | assertTrue(filter.matchCheckCode("Y1202065")); |
| | | assertTrue(filter.matchCheckCode("1202065")); |
| | | // å
¶ä»å®å¿çµé¡¹ç® |
| | | assertTrue(filter.matchCheckCode("Y691133607")); |
| | | assertTrue(filter.matchCheckCode("Y559542128")); |
| | | } |
| | | |
| | | @Test |
| | | public void testCheckCode_shouldNotMatchRadiologyCode() { |
| | | // æ¥å¿å®æµï¼æ¾å°/è¶
声项ç®ç jcxmcodeï¼ä¸å¨å¿çµæä¸¾å
ï¼ |
| | | assertFalse(filter.matchCheckCode("1080")); // è¸é¨CTå¹³æ« |
| | | assertFalse(filter.matchCheckCode("1393")); // å³èæ£ä¾§ä½ |
| | | assertFalse(filter.matchCheckCode("1006")); // ä¸ä¸é¢éª¨ |
| | | assertFalse(filter.matchCheckCode("35689493")); // 彩è¶
å宫éä»¶ |
| | | } |
| | | |
| | | @Test |
| | | public void testCheckName_shouldMatchEcgNames() { |
| | | // S0201ECG æ¥æä¸åºç°çå¿çµæ£æ¥é¡¹ç®åç§° |
| | | assertTrue(filter.matchCheckName("常è§å¿çµå¾")); |
| | | assertTrue(filter.matchCheckName("24å°æ¶å¨æå¿çµå¾")); |
| | | assertTrue(filter.matchCheckName("åºè¾¹å¿çµå¾(常è§+é¢è°±)")); |
| | | assertTrue(filter.matchCheckName("常è§å¿çµå¾-å¿çµåéå¾")); |
| | | } |
| | | |
| | | @Test |
| | | public void testCheckName_shouldNotMatchRadiologyNames() { |
| | | // S0405 ä¸åºç°çå
¶ä»ç§å®¤é¡¹ç®åç§° |
| | | assertFalse(filter.matchCheckName("è¸é¨CTå¹³æ«")); |
| | | assertFalse(filter.matchCheckName("é¢
èMRIå¹³æ«ï¼å«DWIï¼")); |
| | | assertFalse(filter.matchCheckName("彩è¶
èèè°è¾")); |
| | | assertFalse(filter.matchCheckName("骨å¯åº¦")); |
| | | assertFalse(filter.matchCheckName("å³è
å
³èæ£ä¾§ä½")); |
| | | } |
| | | |
| | | // ==================== 便® Cï¼æ§è¡ç§å®¤ï¼å¯é
ç½®ç½ååï¼ ==================== |
| | | |
| | | @Test |
| | | public void testDeptCode_notConfigured_shouldNotFilter() { |
| | | // æªé
ç½®ç½ååæ¶ï¼ä¾æ® C ä¸åä¸å¤å®ï¼é¿å
è¯¯å¤ |
| | | assertFalse(filter.matchDeptCode("YJ001")); |
| | | assertFalse(filter.matchDeptCode("YJ002")); |
| | | } |
| | | |
| | | @Test |
| | | public void testDeptCode_configured_shouldMatch() { |
| | | filter.setEcgDeptCodes(Arrays.asList("YJECG01", "YJECG02")); |
| | | assertTrue(filter.matchDeptCode("YJECG01")); |
| | | assertTrue(filter.matchDeptCode("yjecg02")); // 忽ç¥å¤§å°å |
| | | assertFalse(filter.matchDeptCode("YJ001")); // æ¾å°ç§å®¤ä¸å¨ç½åå |
| | | } |
| | | |
| | | @Test |
| | | public void testDeptCode_shouldHandleEmptyWhitelistAndBlank() { |
| | | filter.setEcgDeptCodes(Collections.emptyList()); |
| | | assertFalse(filter.matchDeptCode("YJ001")); |
| | | filter.setEcgDeptCodes(Arrays.asList("YJECG01")); |
| | | assertFalse(filter.matchDeptCode(null)); |
| | | assertFalse(filter.matchDeptCode("")); |
| | | } |
| | | |
| | | // ==================== 综åå¤å® ==================== |
| | | |
| | | @Test |
| | | public void testJudge_ecgOrderBySuffix() { |
| | | HisEcgFilter.Result r = filter.judge("8826091720001101", null, null, null); |
| | | assertTrue(r.isEcg()); |
| | | assertTrue("åºå½ä¸ä¾æ® Aï¼å®é
=" + r.getReason(), r.getReason().startsWith("A:")); |
| | | } |
| | | |
| | | @Test |
| | | public void testJudge_ecgOrderByCheckCode() { |
| | | // ç³è¯·åå·ä¸æ¯å¿çµåç¼ï¼ä½æ£æ¥é¡¹ç®æ¯å¿çµ â ä»åºå¤å®ä¸ºå¿çµå |
| | | HisEcgFilter.Result r = filter.judge("2126091700001", "Y1202065", null, null); |
| | | assertTrue(r.isEcg()); |
| | | assertTrue("åºå½ä¸ä¾æ® Bï¼å®é
=" + r.getReason(), r.getReason().startsWith("B:")); |
| | | } |
| | | |
| | | @Test |
| | | public void testJudge_nonEcgRadiologyOrder() { |
| | | // å
¸åæ¾å°åï¼CT å¹³æ« + æ¥è¯CT室 â ä¸é¡¹é½ä¸å½ä¸ |
| | | HisEcgFilter.Result r = filter.judge("2126091602867", "1080", "è¸é¨CTå¹³æ«", "YJ002"); |
| | | assertFalse("æ¾å°åä¸åºè¢«å¤ä¸ºå¿çµå", r.isEcg()); |
| | | } |
| | | |
| | | @Test |
| | | public void testJudge_nonEcgUltrasoundOrder() { |
| | | // å
¸åè¶
声å |
| | | HisEcgFilter.Result r = filter.judge("2126091700038", "35711720", "彩è¶
宫é¢ç®¡é¿åº¦", "YJ001"); |
| | | assertFalse(r.isEcg()); |
| | | } |
| | | |
| | | @Test |
| | | public void testIsEcgOrder_convenience() { |
| | | assertTrue(filter.isEcgOrder("S0405", "8826091720001101", null, null, null)); |
| | | assertFalse(filter.isEcgOrder("S0405", "2126091602867", "1080", "è¸é¨CTå¹³æ«", "YJ002")); |
| | | } |
| | | |
| | | // ==================== å¤å¼æ£æ¥é¡¹ç®ï¼S050401/S050501 ç ZDY.jcxmcode / jcxmnameï¼ ==================== |
| | | |
| | | @Test |
| | | public void testMatchCheckItems_shouldSplitCommaSeparated() { |
| | | // 宿µ S050401ï¼éå¿çµï¼DR æ£ä¾§ä½ï¼ |
| | | assertFalse(filter.matchCheckItems("1393,1506", "å³èæ£ä¾§ä½,å·¦è©å
³èæ£ä¾§ä½")); |
| | | // 宿µ S050501ï¼éå¿çµï¼å½©è¶
ï¼ |
| | | assertFalse(filter.matchCheckItems("35672306,35672504,35672544,35672596", |
| | | "彩è¶
å³ä¸è¢å¨è,彩è¶
å³ä¸è¢éè,彩è¶
å·¦ä¸è¢å¨è,彩è¶
å·¦ä¸è¢éè")); |
| | | } |
| | | |
| | | @Test |
| | | public void testMatchCheckItems_shouldMatchWhenAnyIsEcg() { |
| | | // æ··ååºæ¯ï¼åªè¦æä¸ä¸ªæ¯å¿çµå°±ç®å¿çµå |
| | | assertTrue(filter.matchCheckItems("1393", "å³èæ£ä¾§ä½,常è§å¿çµå¾")); |
| | | assertTrue(filter.matchCheckItems("Y1202065", "彩è¶
èèè°è¾")); |
| | | } |
| | | |
| | | // ==================== å
³é®åå
åºï¼å¿çµé¡¹ç®ååå«ãå¿çµãï¼ ==================== |
| | | |
| | | @Test |
| | | public void testCheckName_keywordFallback() { |
| | | // æªæ¶å½è¿æä¸¾çåå²/æ°å¢é¿å°¾åç§°ï¼åªè¦å«ãå¿çµãå³è®¤å¯ |
| | | assertTrue(filter.matchCheckName("åäºå¯¼èå¿çµæ£æ¥")); |
| | | assertTrue(filter.matchCheckName("å¿çµçæ¤")); |
| | | assertTrue(filter.matchCheckName("è¿å¨å¿çµ")); |
| | | // æä¸¾å·²æ¶å½ç仿£å¸¸ |
| | | assertTrue(filter.matchCheckName("常è§å¿çµå¾")); |
| | | } |
| | | |
| | | /** |
| | | * â ï¸ å
³é®åå½ï¼**ä¸å«ãå¿çµãäºåçå¿çµæ£æ¥å¿
é¡»ä»è¢«å¤ä¸ºå¿çµ**ã |
| | | * |
| | | * <p>ç¨æ·æåºçåä¾ãæ ¸å¯¹ {@code check_type} è¡¨ç¡®è®¤ï¼æ¬é¢ 15 个å¿çµç±»åä¸ |
| | | * æ 4 个åç§°ä¸å«ãå¿çµãï¼åºä¸å计 2 ä¸ä½æ¡çå®è®°å½ï¼ |
| | | * <pre> |
| | | * 300 卿è¡åï¼9083 æ¡ï¼ 500 å¨èç¡¬åæ£æµï¼11205 æ¡ï¼ |
| | | * 600 é£éçµççï¼60 æ¡ï¼ 900 å¿å®¤æçµä½ï¼0 æ¡ï¼ |
| | | * </pre> |
| | | * è¥ä»
ç¨"å«å¿çµ"å¤å®ï¼è¿äºåä¼è¢«**误å¤ä¸ºéå¿çµè丢å¼**ã |
| | | */ |
| | | @Test |
| | | public void testCheckName_ecgWithoutKeyword_shouldStillBeAccepted() { |
| | | // ââ ç¨æ·ä¸¾çåä¾ ââ |
| | | assertTrue("卿è¡åï¼check_type=300ï¼åºä¸ 9083 æ¡ï¼ä¸åºè¢«ä¸¢å¼", |
| | | filter.matchCheckName("卿è¡å")); |
| | | assertTrue("å¨è硬åï¼check_type=500ï¼åºä¸ 11205 æ¡ï¼ä¸åºè¢«ä¸¢å¼", |
| | | filter.matchCheckName("å¨è硬å")); |
| | | assertTrue("è¿å¨è¯éªï¼check_type=400ï¼ä¸åºè¢«ä¸¢å¼", |
| | | filter.matchCheckName("è¿å¨è¯éª")); |
| | | assertTrue("é£éçµççï¼check_type=600ï¼ä¸åºè¢«ä¸¢å¼", |
| | | filter.matchCheckName("é£éçµçç")); |
| | | // ââ check_type 表ä¸çåç¡®åç§° ââ |
| | | assertTrue(filter.matchCheckName("å¨èç¡¬åæ£æµ")); |
| | | assertTrue(filter.matchCheckName("å¿å®¤æçµä½")); |
| | | assertTrue(filter.matchCheckName("å¹³æ¿è¿å¨å¿çµ")); |
| | | assertTrue(filter.matchCheckName("å¿çµå¾è¯ç©è´è·è¯éª")); |
| | | assertTrue(filter.matchCheckName("卿å¿çµå¾+è¡å")); |
| | | // ââ ç产æ¥å¿ä¸çå®é
åç§°åä½ï¼S050401 宿µï¼ââ |
| | | assertTrue("宿µ S050401 ä¸ '24å°æ¶å¨æè¡åçæµ' ä¸å«ãå¿çµãï¼é ç½ååéè¿", |
| | | filter.matchCheckName("24å°æ¶å¨æè¡åçæµ")); |
| | | assertTrue(filter.matchCheckName("24å°æ¶å¨æå¿çµå¾")); |
| | | assertTrue(filter.matchCheckName("24å°æ¶å¨æå¿çµçæµ")); |
| | | assertTrue("宿µ S050401 ä¸ 'å¿çµå¾è¿å¨è¯éª' åºå¯¹åº check_type=400", |
| | | filter.matchCheckName("å¿çµå¾è¿å¨è¯éª")); |
| | | // å¹³æ¿è¿å¨çåç§åæ³ |
| | | assertTrue(filter.matchCheckName("å¹³æ¿è¿å¨è¯éª")); |
| | | assertTrue(filter.matchCheckName("å¹³æ¿è¿å¨å¿çµå¾")); |
| | | assertTrue(filter.matchCheckName("æ´»å¨å¹³æ¿è¯éª")); |
| | | } |
| | | |
| | | /** |
| | | * éå¿çµæé¤è¯ï¼åç§°å«ãå¿èãä½å±å
¶ä»ç§å®¤è
ï¼å¿
é¡»å¤å¦ã |
| | | * ï¼"彩è¶
èå¿å¿è""è¶
声é å½±ç«ä½æåï¼å³å¿ï¼"忥èªå®æµæ¥å¿ï¼ |
| | | */ |
| | | @Test |
| | | public void testCheckName_nonEcgExcludeKeywords() { |
| | | assertFalse("彩è¶
èå¿å¿èå±è¶
声ç§ï¼ä¸åºè¢«å½ä½å¿çµ", |
| | | filter.matchCheckName("彩è¶
èå¿å¿è")); |
| | | assertFalse(filter.matchCheckName("è¶
声é å½±ç«ä½æåï¼å³å¿ï¼")); |
| | | assertFalse(filter.matchCheckName("彩è¶
å¿èï¼å¸¸è§ï¼")); |
| | | assertFalse(filter.matchCheckName("彩è¶
å¿èï¼14å²ä»¥ä¸ï¼")); |
| | | assertFalse(filter.matchCheckName("彩è¶
åºæå¿å
è
")); |
| | | } |
| | | |
| | | /** |
| | | * ç¨å®æµæ¥å¿ä¸åºç°ç 111 个éå¿çµé¡¹ç®åç§°ååå½ï¼ |
| | | * è¿äºæ¯ S0405 / S050401 / S050501 鿍éçæ¾å°ãè¶
声ãå
éç项ç®ï¼ |
| | | * å¿
é¡»**å
¨é¨**å¤ä¸ºéå¿çµï¼å¦åä¼è¢«è¯¯å½ä½å¿çµç³è¯·åééã |
| | | */ |
| | | @Test |
| | | public void testRealNonEcgNames_shouldAllBeRejected() { |
| | | String[] nonEcgNames = { |
| | | "彩è¶
èèè°è¾", "彩è¶
产æ£ï¼åèï¼", "彩è¶
å¿èï¼å¸¸è§ï¼", "彩è¶
é¢å¨è", |
| | | "彩è¶
ç²ç¶è
ºåé¢é¨æ·å·´ç»", "彩è¶
æ©åï¼ç»é´5-11wï¼", "彩è¶
产æ£1", |
| | | "彩è²å¤æ®åè¶
å£°æ£æ¥ï¼å¼¹æ§æåï¼", "彩è¶
æ©åï¼ç»è
¹5-11wï¼", "彩è¶
å宫éä»¶ï¼ç»è
¹ï¼", |
| | | "彩è¶
å宫éä»¶ï¼ç»é´éï¼", "彩è¶
åè¾è¾å°¿ç®¡èè±", "彩è¶
æ¤å¨è", "彩è¶
è¾ä¸è
º", |
| | | "彩è¶
è¾å¨è", "彩è¶
产æ£ï¼åèï¼", "彩è¶
åä¹³åè
çªæ·å·´ç»", "彩è¶
éå°¾", |
| | | "彩è¶
宫é¢ç®¡é¿åº¦", "è¶
声é å½±ç«ä½æåï¼å³å¿ï¼", "彩è¶
å³ä¸è¢å¨è", "彩è¶
ç¾ä¸¸", |
| | | "彩è¶
嵿³¡çæµï¼ç»é´éï¼", "彩è¶
åºæè¸è
", "彩è¶
åºæå·¦ä¸è¢éè", |
| | | "彩è¶
åºæå¿å
è
", "彩è¶
åºæåè¾è¾å°¿ç®¡èè±", "彩è¶
è
¹èåæ·å·´ç»", |
| | | "彩è¶
åºæèèè°è¾", "彩è¶
è¸è
", "彩è¶
èå¿ç³»ç»æ§çæ¥", "彩è¶
çè
è¶
声ï¼ç»é´éï¼", |
| | | "彩è¶
æ¶è
ºï¼é¢ä¸è
ºãè
®è
ºï¼", "彩è¶
å¿èï¼ç»é£ç®¡-åµååï¼", "彩è¶
å宫å¨èï¼ç»é´éï¼", |
| | | "彩è¶
ç²ç¶è
º", "彩è¶
è
¹è¡æ²æ·å·´ç»ï¼åä¾§ï¼", "彩è¶
å¿èï¼14å²ä»¥ä¸ï¼", |
| | | "彩è¶
ä½è¡¨å
å1ï¼è¯·æ 注1åå
åå
·ä½ä½ç½®ï¼", |
| | | "è¸é¨å¹³æ«", "è¸é¨CTå¹³æ«", "é¢
èCTå¹³æ«", "ä¸è
¹é¨CTå¹³æ«", "å£è
CT", |
| | | "ä¸è
¹é¨CTå¹³æ«", "çè
CTå¹³æ«", "è¸é¨é«å辨ï¼HRCT)", "è¸é¨CTå¢å¼º", |
| | | "é¢
èMRIå¹³æ«ï¼å«DWIï¼", "é¢
èMRIå¹³æ«", "é¢
èå¹³æ«", "é¢
èå¹³æ«+DWI", |
| | | "è
°æ¤å¹³æ«", "颿¤å¹³æ«", "è
°æ¤+äºãä¸ç»´", "å³è©å
³èå¹³æ«", "å·¦èå
³èå¹³æ«", |
| | | "å³èå
³èå¹³æ«", "å³è¶³å¹³æ«", "å
¨è
¹é¨å¹³æ«+å¢å¼º", "å
¨è
¹é¨å¹³æ«(å¹³æ«ä¸ä¸ªé¨ä½ï¼", |
| | | "ä¸è
¹é¨å¢å¼º", "ååè
ºå¢å¼º", "èèå¢å¼º", "ä¹³è
ºå¢å¼º", "çè
å¢å¼º", |
| | | "å èCTA", "èCTA", "é¢CTA", "é¢
èTOF MRA", |
| | | "è¸é¨æ£ä½", "è¸é¨æ£ä¾§ä½", "è¸é¨æ£æä½ï¼èµ·æå¨ï¼", "å°å¿è¸ç", |
| | | "å³èå
³è", "å·¦èå
³èæ£ä¾§ä½", "å³èå
³èæ£ä¾§ä½", "å³è¡éª¨å
¨é¿æ£ä¾§ä½", |
| | | "å·¦è«è
骨å
¨é¿æ£ä¾§ä½", "éª¨çæ£ä½", "è
°æ¤æ£ä¾§ä½", "è
°æ¤è¿å±è¿ä¼¸", |
| | | "å³èæ£ä¾§ä½", "å³æææ£ä¾§ä½", "å³è
å
³èæ£ä¾§ä½", "å³è
å
³è", |
| | | "å³è¸å
³èæ£ä¾§ä½", "å·¦è©å
³èæ£æä½", "å³å°ºæ¡¡éª¨æ£ä¾§ä½", "å³è±éª¨æ£ä¾§ä½", |
| | | "å
¨ä¸è¢æ£ä½", "å·¦è«è
骨", "ä¸ä¸é¢éª¨", "ä¹³çªæ°´å¹³", "颿¤", "è
°æ¤", |
| | | "è
¹é¨å¹³ç(å§ä½)KUB", "åè¾è¾å°¿ç®¡å
¨é¿", "骨å¯åº¦", |
| | | "èºéæ°åè½æ£æ¥", "èºå¼¥æ£åè½æ£æ¥", "æ¯æ°ç®¡æ¿åè¯éªæ£æ¥", "æ¯æ°ç®¡èå¼ è¯éª", |
| | | "䏿°§åæ°®å¼æ°æµå®", "æ çèé", "çµåè鿣æ¥", "æ çè é", |
| | | "æ åèå¼¹æ§æµå®", "å¿èåè½" |
| | | }; |
| | | java.util.List<String> wrong = new java.util.ArrayList<>(); |
| | | for (String name : nonEcgNames) { |
| | | if (filter.matchCheckName(name)) { |
| | | wrong.add(name); |
| | | } |
| | | } |
| | | assertTrue("以ä¸éå¿çµé¡¹ç®è¢«è¯¯å¤ä¸ºå¿çµ: " + wrong, wrong.isEmpty()); |
| | | } |
| | | |
| | | // ==================== judgeWithZdyï¼S050401/S050501 ä¸ç¨å
¥å£ï¼ ==================== |
| | | |
| | | @Test |
| | | public void testJudgeWithZdy_shouldRejectRadiology() { |
| | | java.util.Map<String, Object> zdy = new java.util.HashMap<>(); |
| | | zdy.put("jcxmcode", "1393,1506"); |
| | | zdy.put("jcxmname", "å³èæ£ä¾§ä½,å·¦è©å
³èæ£ä¾§ä½"); |
| | | zdy.put("roomname", "2å·æºæ¿(DR)"); |
| | | HisEcgFilter.Result r = filter.judgeWithZdy("2126091700001", "ZY012", zdy); |
| | | assertFalse("DR æ£ä¾§ä½ä¸åºå¤ä¸ºå¿çµå: " + r.getReason(), r.isEcg()); |
| | | } |
| | | |
| | | @Test |
| | | public void testJudgeWithZdy_shouldRejectUltrasound() { |
| | | java.util.Map<String, Object> zdy = new java.util.HashMap<>(); |
| | | zdy.put("jcxmcode", "35672306,35672504"); |
| | | zdy.put("jcxmname", "彩è¶
å³ä¸è¢å¨è,彩è¶
å³ä¸è¢éè"); |
| | | zdy.put("roomname", "5å·è¯å®¤"); |
| | | assertFalse(filter.judgeWithZdy("2126091700038", "ZY012", zdy).isEcg()); |
| | | } |
| | | |
| | | @Test |
| | | public void testJudgeWithZdy_shouldAcceptEcgOrder() { |
| | | // å¿çµåï¼åç§°å«ãå¿çµã |
| | | java.util.Map<String, Object> zdy = new java.util.HashMap<>(); |
| | | zdy.put("jcxmcode", "1202065"); |
| | | zdy.put("jcxmname", "åºè¾¹å¿çµå¾(常è§+é¢è°±)"); |
| | | zdy.put("roomname", "å¿çµæ£æ¥å®¤"); |
| | | HisEcgFilter.Result r = filter.judgeWithZdy("2126091700001", "ZY012", zdy); |
| | | assertTrue("å¿çµé¡¹ç®åºå¤ä¸ºå¿çµå: " + r.getReason(), r.isEcg()); |
| | | } |
| | | |
| | | @Test |
| | | public void testJudgeWithZdy_shouldAcceptByApplyNoSuffix() { |
| | | // å³ä¾¿æ£æ¥é¡¹ç®åä¸å°ï¼åªè¦ç³è¯·åå·å¸¦å¿çµåç¼ä¹è®¤å¯ |
| | | java.util.Map<String, Object> zdy = new java.util.HashMap<>(); |
| | | assertTrue(filter.judgeWithZdy("8826091720001101", null, zdy).isEcg()); |
| | | assertTrue(filter.judgeWithZdy("8826081120716401", null, null).isEcg()); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.lihu.jh.server.ecg; |
| | | |
| | | import cn.lihu.jh.framework.security.config.AuthorizeRequestsCustomizer; |
| | | import org.springframework.security.config.annotation.web.builders.HttpSecurity; |
| | | import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer; |
| | | |
| | | /** |
| | | * å端éæèµæºä¸ SPA 页é¢å¤å£³çå
ç»å½è§åã |
| | | * |
| | | * <h3>为ä»ä¹éè¦è¿ä¸ªç±»</h3> |
| | | * æå端æè¿äº jar ä¹åï¼å端å¼å§æ¿æ
"æä¾é¡µé¢ä¸éæèµæº"çèè´£ï¼ |
| | | * ä½èéæ¡æ¶é»è®¤çéæèµæºç½åååªè¦çèæ¬ä¸æ ·å¼ï¼ |
| | | * |
| | | * <pre> |
| | | * JhWebSecurityConfigurerAdapter#filterChain: |
| | | * .antMatchers(GET, "/*.html", "/**/*.html", "/**/*.css", "/**/*.js").permitAll() |
| | | * </pre> |
| | | * |
| | | * å æ¤ä¸å请æ±ä¼å½ä¸å
åºè§å {@code anyRequest().authenticated()} å¹¶è¿å |
| | | * {@code 401 è´¦å·æªç»å½}ï¼è¡¨ç°ä¸º**æµè§å¨ç½å±ææçº¿**ï¼ |
| | | * <ul> |
| | | * <li>{@code /logo.gif}ã{@code /favicon.ico} ââ ç»å½é¡µä¸å è½½å¨ç»ä¾èµçå¾ç</li> |
| | | * <li>{@code /assets/*.svg|png|woff} ââ 徿 ä¸åä½ï¼js/css æ°å¥½è¢«ä¸é¢è§åæ¾è¡ï¼ |
| | | * æä»¥æåçç¶æ¯"æ¥å£é½éã页é¢ç½å±"ï¼æå
·è¿·ææ§ï¼</li> |
| | | * <li>页é¢è·¯å¾ ââ ç¨æ·å·æ°æç´æ¥è®¿é®æ¶æµè§å¨å°æªæºå¸¦ tokenï¼ |
| | | * è¥è¦æ±è®¤è¯ä¼ç´æ¥ 401ï¼å¯¼è´"ä¸å·æ°å°±æçº¿"</li> |
| | | * </ul> |
| | | * |
| | | * <h3>页é¢è·¯å¾æ¸
åçæ¥æº</h3> |
| | | * åèª {@code ecg_web/src/router/modules/remaining.ts} çé¡¶å±éæè·¯ç± |
| | | * ï¼path ä¸å«å¨æåæ°è
ï¼ï¼ä»¥å卿èåï¼{@code system_menu} 表ï¼å¯è½åºç°ç |
| | | * ä¸å¡åç¼ï¼ |
| | | * <pre> |
| | | * / /user /dict /codegen /job /login /roomselect |
| | | * /redirect /sso /social-login /403 /404 /500 |
| | | * /calling-screen-big /calling-screen-room |
| | | * /ecg/** /clinic/** /system/** /infra/** |
| | | * </pre> |
| | | * |
| | | * <h3>å®å
¨æ§</h3> |
| | | * æ¾è¡ç**åªæ¯å端页é¢å¤å£³ä¸éæèµæº**ï¼ä¸æ¶å任使°æ®ï¼ |
| | | * <ul> |
| | | * <li>{@code /admin-api/**} å
¨é¨ä¸å¡æ¥å£ä»èµ° token é´æï¼æªæææ¿ä¸å°æ°æ®</li> |
| | | * <li>页é¢å¤å£³æ¬èº«ä¸å«ä»»ä½æ£è
ä¿¡æ¯ï¼å
容ç±å端æ¿å° token åå¦è¡è¯·æ±</li> |
| | | * <li>{@code /system/**}ã{@code /infra/**} çæ¾è¡çæ¯**页é¢**ï¼ |
| | | * å
¶æ°æ®æ¥å£ä½äº {@code /admin-api/system/**}ã{@code /admin-api/infra/**}ï¼ |
| | | * ä»å¨é´æä¿æ¤ä¹ä¸</li> |
| | | * <li>è¿ä¸åå¹¶å nginx æéæé¡µé¢å
¬å¼æç®¡çè¡ä¸ºä¸è´ï¼æªéä½å®å
¨ç级</li> |
| | | * </ul> |
| | | * 注æ {@code /admin-api/**} ç¹æä¸å¨æ¾è¡ä¹åï¼é¿å
误伤æ¥å£é´æã |
| | | * |
| | | * @author å¿çµæéè£
æºç³»ç» |
| | | */ |
| | | public class FrontendAuthorizeRequestsCustomizer extends AuthorizeRequestsCustomizer { |
| | | |
| | | /** éæèµæºãä¸å« html/css/js ââ æ¡æ¶å·²æ¾è¡ï¼æ¤å¤è¡¥é½å
¶ä½ç±»å */ |
| | | private static final String[] STATIC_RESOURCE_PATTERNS = { |
| | | "/favicon.ico", "/logo.gif", "/logo.png", "/logo0.png", |
| | | "/assets/**", "/static/**", |
| | | }; |
| | | |
| | | /** |
| | | * SPA 页é¢å¤å£³ã |
| | | * å¿
é¡»ä¸ {@link SpaForwardController} çæ å°ä¿æåæ¥ï¼ |
| | | * å¦åä¼åºç°"转åè½å°ãä½è¢«å®å
¨å±æ¦ä¸ 401"çä¸ä¸è´ç°è±¡ã |
| | | * |
| | | * <h4>â ï¸ ä¸ºä»ä¹ ECG å¿
é¡»éæ¡ç²¾ç¡®æä¸¾ï¼ä¸è½ç¨ /ecg/**</h4> |
| | | * ECG çå端æ¥å£ä¸å端页é¢å
±ç¨ {@code /ecg/} å½å空é´ï¼ä¾å¦ï¼ |
| | | * <pre> |
| | | * æ¥å£: /ecg/screen/big-screen-dataã/ecg/queue/pageã/ecg/call/next |
| | | * 页é¢: /ecg/queueã/ecg/roomã/ecg/check-type |
| | | * </pre> |
| | | * è¥æ¤å¤æ¾è¡ {@code /ecg/**}ï¼å**ææ ECG æ¥å£é½ä¼åæå
é´æ**ï¼ |
| | | * å±äºä¸¥éçå®å
¨æ¼æ´ï¼æªç»å½å³å¯è¯»åæéæ°æ®ï¼ã |
| | | * 精确路å¾å¨ Spring ä¸ä¸ä¼å¹é
带åè·¯å¾çæ¥å£ï¼å æ¤æ¯å®å
¨çã |
| | | */ |
| | | private static final String[] SPA_PAGE_PATTERNS = { |
| | | "/", "/index.html", |
| | | // æ¥èª remaining.ts çé¡¶å±éæè·¯ç± |
| | | "/user/**", "/dict/**", "/codegen/**", "/job/**", |
| | | "/login", "/roomselect", |
| | | "/redirect/**", "/sso", "/social-login", |
| | | "/403", "/404", "/500", |
| | | "/calling-screen-big", "/calling-screen-room", |
| | | // ââ ECG ä¸å¡é¡µï¼å¿
须精确ï¼ç¦æ¢ /ecg/** ââ |
| | | "/ecg/appointment", "/ecg/appointment-confirm", "/ecg/alter", |
| | | "/ecg/queue", "/ecg/roomselect", |
| | | "/ecg/doc/routine", "/ecg/doc/dev-ready", "/ecg/doc/dev-install", |
| | | "/ecg/dev-dismantle", "/ecg/dev-rent", |
| | | "/ecg/doctor/dev-data-entry", |
| | | "/ecg/job-statistic", "/ecg/dev-statistic", |
| | | "/ecg/room", "/ecg/roomstatus", "/ecg/dev-model", |
| | | "/ecg/device", "/ecg/check-type", |
| | | // ââ è¯å®¤é¡µï¼æ¥å£ /clinic/room/* 带åè·¯å¾ï¼ä¸å²çªï¼ââ |
| | | "/clinic/room", |
| | | // ââ ç³»ç»ç®¡çä¸åºç¡è®¾æ½é¡µï¼å
¶æ¥å£åä½äº /admin-api ä¸ï¼ä¸å²çªï¼ââ |
| | | "/system/**", "/infra/**", |
| | | }; |
| | | |
| | | @Override |
| | | public void customize(ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry) { |
| | | registry.antMatchers(STATIC_RESOURCE_PATTERNS).permitAll(); |
| | | registry.antMatchers(SPA_PAGE_PATTERNS).permitAll(); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.lihu.jh.server.ecg; |
| | | |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Configuration; |
| | | import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; |
| | | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; |
| | | |
| | | /** |
| | | * å端éæèµæºæ å°ï¼é
å"å端æè¿ jar"çåå¹¶é¨ç½²æ¹æ¡ï¼ã |
| | | * |
| | | * <h3>ä½ç¨</h3> |
| | | * æ jar å
{@code META-INF/resources/frontend/} ä¸çå端æå»ºäº§ç©æ å°å°ç«ç¹æ ¹è·¯å¾ã |
| | | * |
| | | * <pre> |
| | | * URL æ¥æº |
| | | * /assets/index-xxx.js -> classpath:/META-INF/resources/frontend/assets/index-xxx.js |
| | | * /logo.gif -> classpath:/META-INF/resources/frontend/logo.gif |
| | | * /favicon.ico -> classpath:/META-INF/resources/frontend/favicon.ico |
| | | * /static/jquery.min.js -> classpath:/META-INF/resources/frontend/static/jquery.min.js |
| | | * </pre> |
| | | * |
| | | * <h3>â 为ä»ä¹ãä¸è½ãç¨ {@code /**} éé
ï¼éè¦ï¼</h3> |
| | | * åçæ¾åæ {@code registry.addResourceHandler("/**")}ï¼è¿æ¯**é误**çï¼ |
| | | * 䏿¦æ {@code /**} æåå端ç®å½ï¼ä»¥ä¸å端èªå¸¦çè·¯å¾ä¼è¢«éæèµæºå¤çå¨ |
| | | * æ¢å
å¹é
ï¼å¯¼è´éææä»¶æ¾ä¸å°è**ç´æ¥ 404**ï¼æ§å¶å¨ä¸åææºä¼å¤çï¼ |
| | | * <ul> |
| | | * <li>{@code /doc.html}ã{@code /swagger-ui/**}ã{@code /v3/api-docs/**} |
| | | * ââ Knife4j / springdoc æ¥å£ææ¡£</li> |
| | | * <li>{@code /druid/**} ââ Druid çæ§å°ï¼å
¶ Servlet å·²å¯ç¨ï¼</li> |
| | | * <li>{@code /actuator/**} ââ Spring Boot çæ§ç«¯ç¹</li> |
| | | * <li>{@code /jmreport/**} ââ ç§¯æ¨æ¥è¡¨ï¼è¥å°æ¥å¯ç¨ï¼</li> |
| | | * <li>{@code /admin-api/**} ââ å
¨é¨ä¸å¡æ¥å£</li> |
| | | * <li>{@code /profile/**} ââ å¿çµæ¨¡å |
| | | * {@code WebConfig} æ å°å°æä»¶ç³»ç»ä¸ä¼ ç®å½</li> |
| | | * </ul> |
| | | * å æ¤è¿éæ¹ä¸º**æ¾å¼æä¸¾å端çå®åå¨çèµæºåç¼**ï¼ææ ¹è·¯å¾çç»å端èªå·±ã |
| | | * |
| | | * <h3>å端产ç©å®é
å
å«åªäºé¡¶å±æ¡ç®</h3> |
| | | * 便® {@code dist-prod} çå®é
æå»ºç»æï¼ |
| | | * <pre> |
| | | * index.html, favicon.ico, logo.gif â æä»¶ |
| | | * bigCall.html, smallCall.html â kiosk 页ï¼å»ºè®®å é¤ï¼è§é¨ç½²æåï¼ |
| | | * assets/ â 带å
容åå¸ç js/css/åä½/å¾ç |
| | | * static/ â jqueryãaxiosãvue çç¬¬ä¸æ¹éæåº |
| | | * </pre> |
| | | * |
| | | * <h3>SPA æ·±å±è·¯ç±çå
åº</h3> |
| | | * æ¬ç±»**ä¸è´è´£** SPA å
åºï¼åç«¯ç¨ {@code createWebHistory()}ï¼å·æ°æ·±å±è·¯ç± |
| | | * ä¼ 404ï¼ãå
åºç± {@link SpaForwardController} æ¾å¼æä¸¾ 5 类页é¢è·¯å¾å®æï¼ |
| | | * è¿æ ·æ¢ä¿®å¤å·æ° 404ï¼åä¸ä¼æå端çå®ç 404 åæ index.htmlã |
| | | * |
| | | * @author å¿çµæéè£
æºç³»ç» |
| | | */ |
| | | @Configuration |
| | | public class FrontendResourceConfig implements WebMvcConfigurer { |
| | | |
| | | /** å端产ç©å¨ jar å
çä½ç½®ï¼éä¸ jh-server/pom.xml ä¸ targetPath ä¿æä¸è´ */ |
| | | private static final String FRONTEND_LOCATION = "classpath:/META-INF/resources/frontend/"; |
| | | |
| | | /** 带å
容åå¸çèµæºå¯é¿ç¼åï¼30 å¤©ï¼ */ |
| | | private static final long CACHE_HASHED = 3600L * 24 * 30; |
| | | |
| | | /** æ åå¸çæ ¹çº§æä»¶ï¼logo.gif çï¼çç¼åï¼é¿å
æ´æ°åæµè§å¨ä¸å·æ°ï¼1 å°æ¶ï¼ */ |
| | | private static final long CACHE_UNHASHED = 3600L; |
| | | |
| | | @Override |
| | | public void addResourceHandlers(ResourceHandlerRegistry registry) { |
| | | // Vite 产åºç带åå¸èµæºç®å½ |
| | | registry.addResourceHandler("/assets/**") |
| | | .addResourceLocations(FRONTEND_LOCATION + "assets/") |
| | | .setCachePeriod((int) CACHE_HASHED); |
| | | |
| | | // public/ ä¸åæ ·æ·è´çç¬¬ä¸æ¹éæåºï¼jqueryãaxiosãvueãelement-ui çï¼ |
| | | // è¿äºæä»¶åä¸å«åå¸ï¼ç¨çç¼å |
| | | registry.addResourceHandler("/static/**") |
| | | .addResourceLocations(FRONTEND_LOCATION + "static/") |
| | | .setCachePeriod((int) CACHE_UNHASHED); |
| | | |
| | | // æ ¹çº§éææä»¶ãé个ååºï¼é¿å
/doc.htmlã/druid/** çè¢«è¯¯æ¦æª |
| | | // æä»¶åä¸å«åå¸ï¼ç¨çç¼å |
| | | registry.addResourceHandler( |
| | | "/favicon.ico", |
| | | "/logo.gif", |
| | | "/logo.png", |
| | | "/logo0.png") |
| | | .addResourceLocations(FRONTEND_LOCATION) |
| | | .setCachePeriod((int) CACHE_UNHASHED); |
| | | |
| | | // 注æï¼index.html ä¸å¨æ¤å¤æ å°ã |
| | | // å®åªåºéè¿ SpaForwardController ç forward:/frontend/index.html 访é®ï¼ |
| | | // é¿å
åºç°"两个å
¥å£é½è½æ¿å°é¦é¡µ"çæ§ä¹ã |
| | | } |
| | | |
| | | /** |
| | | * 注åå端å
ç»å½è§åã |
| | | * <p> |
| | | * å¿
é¡»æ¾å¼å£°æä¸º Beanï¼æ¡æ¶æä¼éè¿ |
| | | * {@code JhWebSecurityConfigurerAdapter} æ¶éå¹¶çæã |
| | | * ç¼ºå°æ¤ Bean çå
¸åçç¶ï¼æ¥å£é½æ£å¸¸ï¼ä½æµè§å¨æå¼æ¯ç½å± |
| | | * ï¼{@code /logo.gif}ã{@code /favicon.ico}ã页é¢è·¯å¾åè¿å |
| | | * {@code 401 è´¦å·æªç»å½}ï¼ã |
| | | * |
| | | * @see FrontendAuthorizeRequestsCustomizer |
| | | */ |
| | | @Bean |
| | | public FrontendAuthorizeRequestsCustomizer frontendAuthorizeRequestsCustomizer() { |
| | | return new FrontendAuthorizeRequestsCustomizer(); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.lihu.jh.server.ecg; |
| | | |
| | | import io.swagger.v3.oas.annotations.Hidden; |
| | | import org.springframework.stereotype.Controller; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | |
| | | import javax.annotation.security.PermitAll; |
| | | |
| | | /** |
| | | * å端 SPA è½¬åæ§å¶å¨ï¼é
å"å端æè¿ jar"çåå¹¶é¨ç½²æ¹æ¡ï¼ |
| | | * |
| | | * <h3>ä½ç¨</h3> |
| | | * åç«¯æ¯ Vue Router å页åºç¨ãç¨æ·ç´æ¥è®¿é®ææ F5 å·æ°ä¸ä¸ªæ·±å±è·¯ç± |
| | | * ï¼ä¾å¦ {@code /ecg/queue}ï¼æ¶ï¼jar éå¹¶ä¸åå¨å¯¹åºçç©çæä»¶ï¼éè¦æè¯·æ± |
| | | * 转åå {@code index.html}ï¼ç±åç«¯è·¯ç±æ¥ç®¡ï¼å¦åä¼ 404ã |
| | | * <p> |
| | | * åå
è¿æ®µé»è¾ç± nginx ç {@code try_files $uri $uri/ /index.html} æ¿æ
ï¼ |
| | | * å端并å
¥ jar ä¹åæ¹ç±å端è´è´£ï¼nginx åªéä¿ç {@code /admin-api/} åå代çã |
| | | * |
| | | * <h3>为ä»ä¹æ¾å¼æä¸¾è·¯å¾ï¼è䏿¯ç¨éé
å
åº</h3> |
| | | * åªæ å°å端å®é
åå¨ç 5 类页é¢è·¯å¾ï¼è§ {@code src/router/modules/remaining.ts} |
| | | * ä¸å¨æèå表 {@code system_menu}ï¼ï¼ |
| | | * <ul> |
| | | * <li>{@code /} é¦é¡µ</li> |
| | | * <li>{@code /ecg/**} å¿çµä¸å¡ï¼é¢çº¦ãæéãå»çå·¥ä½å°ãè¯å®¤ã设å¤ãè®°å½â¦ï¼</li> |
| | | * <li>{@code /clinic/**} è¯å®¤ç¸å
³</li> |
| | | * <li>{@code /system/**} ç³»ç»ç®¡çï¼ç¨æ·ãè§è²ãèåãåå
¸ãæ¥å¿â¦ï¼</li> |
| | | * <li>{@code /infra/**} åºç¡è®¾æ½ï¼æä»¶ã宿¶ä»»å¡ã代ç çæãçæ§â¦ï¼</li> |
| | | * </ul> |
| | | * è¿æ ·å¯é¿å
"æææ 404 é½åæ index.html"ï¼ä¿çå端çå®ç 404 è¯ä¹ |
| | | * ï¼ä¾å¦ {@code /admin-api/typo} ä»ä¼æ£ç¡®è¿å 404ï¼ã |
| | | * |
| | | * <h3>å®å
¨æ§è¯´æ</h3> |
| | | * {@code @PermitAll} æ¯å¿
é¡»çï¼å·æ°é¡µé¢æ¶æµè§å¨å°æªæºå¸¦ tokenï¼è¥è¦æ±è®¤è¯ |
| | | * ä¼ç´æ¥è¿å 401ï¼å¯¼è´ç¨æ·"ä¸å·æ°å°±æçº¿"ãæ¤å¤æ¾è¡çä»
æ¯**å端页é¢å¤å£³**ï¼ |
| | | * ç宿°æ®ä»ç± {@code /admin-api/**} èµ° token é´æï¼æªæææ¿ä¸å°ä»»ä½æ°æ®ï¼ |
| | | * ä¸åå
nginx å
¬å¼éæé¡µé¢çè¡ä¸ºä¸è´ï¼æªéä½å®å
¨ç级ã |
| | | * |
| | | * <h3>ä¸éæèµæºçä¼å
级</h3> |
| | | * éæèµæºç± {@link FrontendResourceConfig#addResourceHandlers} 注åï¼ |
| | | * å
¶ä¼å
级é«äº Controller æ å°ï¼å æ¤ {@code /assets/*.js}ã{@code /logo.gif} |
| | | * ççå®åå¨çæä»¶ä¸ä¼è¢«æ¬æ§å¶å¨æ¦æªã |
| | | * |
| | | * @author å¿çµæéè£
æºç³»ç» |
| | | */ |
| | | @Hidden // ä¸å¨ Swagger ææ¡£ä¸å±ç¤º |
| | | @Controller |
| | | @PermitAll |
| | | public class SpaForwardController { |
| | | |
| | | /** å端页é¢å¤å£³ãä½äº jar å
META-INF/resources/frontend/ ä¸ */ |
| | | private static final String SPA_INDEX = "forward:/frontend/index.html"; |
| | | |
| | | @GetMapping("/") |
| | | public String index() { |
| | | return SPA_INDEX; |
| | | } |
| | | |
| | | /** |
| | | * remaining.ts ä¸çé¡¶å±å页路ç±ï¼ |
| | | * /loginã/roomselectã/ssoã/social-loginã/403ã/404ã/500ã |
| | | * /calling-screen-bigã/calling-screen-roomã |
| | | * <p> |
| | | * å¿
é¡»ä¸ {@link FrontendAuthorizeRequestsCustomizer#SPA_PAGE_PATTERNS} |
| | | * ä¿æåæ¥ï¼å¦åä¼åºç°"æ§å¶å¨ææ å°ãå´è¢«å®å
¨å±æ¦æ 401"çä¸ä¸è´ |
| | | * ï¼æ¾å®æµæ¼æ /roomselect æ¶å³ä¸ºè¯¥çç¶ï¼ã |
| | | */ |
| | | @GetMapping({"/index.html", "/login", "/roomselect", |
| | | "/sso", "/social-login", "/403", "/404", "/500", |
| | | "/calling-screen-big", "/calling-screen-room"}) |
| | | public String simplePages() { |
| | | return SPA_INDEX; |
| | | } |
| | | |
| | | /** æ¡æ¶èªå¸¦çåè½é¡µï¼ä¸ªäººä¸å¿ãåå
¸ã代ç çæã宿¶ä»»å¡ãéå®åä¸è½¬ï¼ */ |
| | | @GetMapping({"/user/**", "/dict/**", "/codegen/**", "/job/**", "/redirect/**"}) |
| | | public String modulePages() { |
| | | return SPA_INDEX; |
| | | } |
| | | |
| | | /** |
| | | * â ï¸ ECG ä¸å¡é¡µé¢ï¼å¿
é¡»ãéæ¡ç²¾ç¡®æä¸¾ãï¼ç»ä¸è½ç¨ {@code /ecg/**} éé
ï¼ |
| | | * |
| | | * <h4>为ä»ä¹ä¸è½éé
ï¼è¿æ¯ä¸ä¸ªå·²å®æµå¤ç°çç宿
éï¼</h4> |
| | | * ECG çå端æ¥å£ä¸å端页é¢**å
±ç¨ /ecg/ å½å空é´**ï¼ |
| | | * <pre> |
| | | * æ¥å£ï¼javax @RestControllerï¼ å端页é¢ï¼èå pathï¼ |
| | | * /ecg/screen/big-screen-data /ecg/queue |
| | | * /ecg/queue/page /ecg/room |
| | | * /ecg/call/next /ecg/check-type |
| | | * /ecg/doctor/finish-next-patient /ecg/device |
| | | * /ecg/appointment/page /ecg/appointment |
| | | * </pre> |
| | | * è¥ç¨ {@code /ecg/**} 转åå° index.htmlï¼å大å±/è¯é´å±è¯·æ± |
| | | * {@code /ecg/screen/big-screen-data} 伿¿å°**HTML è䏿¯ JSON**ï¼ |
| | | * å«å·å±ç´æ¥å¤±æï¼HTTP 仿¯ 200ï¼æå
·è¿·ææ§ï¼ã |
| | | * |
| | | * <h4>精确路å¾ä¸ºä½å®å
¨</h4> |
| | | * å¨ Spring ä¸ {@code /ecg/queue} ä¸ {@code /ecg/queue/page} æ¯ä¸¤ä¸ªä¸åæ å°ï¼ |
| | | * 精确路å¾ä¸ä¼å¹é
带åè·¯å¾çæ¥å£ï¼å æ¤äºè
天ç¶åºåã |
| | | * |
| | | * <h4>è·¯å¾æ¥æº</h4> |
| | | * åèª {@code system_menu} è¡¨ä¸ parent_id 为 ECG æ ¹(1254)æç³»ç»ç®¡ç(1) |
| | | * çé¡µé¢ pathï¼ä»¥å {@code ecg_web/src/router} ä¸çéæè·¯ç±ã |
| | | */ |
| | | @GetMapping({ |
| | | // ââ ECG æ ¹(1254) ä¸çä¸å¡é¡µ ââ |
| | | "/ecg/appointment", "/ecg/appointment-confirm", "/ecg/alter", |
| | | "/ecg/queue", "/ecg/roomselect", |
| | | "/ecg/doc/routine", "/ecg/doc/dev-ready", "/ecg/doc/dev-install", |
| | | "/ecg/dev-dismantle", "/ecg/dev-rent", |
| | | "/ecg/doctor/dev-data-entry", |
| | | "/ecg/job-statistic", "/ecg/dev-statistic", |
| | | // ââ æç³»ç»ç®¡ç(1) ä¸ä½è·¯å¾å¨ /ecg çé¡µé¢ ââ |
| | | "/ecg/room", "/ecg/roomstatus", "/ecg/dev-model", |
| | | "/ecg/device", "/ecg/check-type", |
| | | }) |
| | | public String ecgPages() { |
| | | return SPA_INDEX; |
| | | } |
| | | |
| | | /** |
| | | * è¯å®¤ç¸å
³é¡µé¢ã注æï¼æ¥å£ {@code /clinic/room/page} ç带åè·¯å¾ï¼ |
| | | * ä¸ç²¾ç¡®è·¯å¾ {@code /clinic/room} ä¸å²çªã |
| | | */ |
| | | @GetMapping({"/clinic/room"}) |
| | | public String clinicPages() { |
| | | return SPA_INDEX; |
| | | } |
| | | |
| | | /** |
| | | * ç³»ç»ç®¡çä¸åºç¡è®¾æ½é¡µé¢ã |
| | | * <p> |
| | | * è¿ä¸¤ä¸ªåç¼**å¯ä»¥**ç¨éé
ï¼å 为 {@code /admin-api/**} ææ¯æ¥å£å½å空é´ï¼ |
| | | * {@code /system/**}ã{@code /infra/**} ä»
ç¨äºé¡µé¢ï¼ä¸åå¨å忥å£ã |
| | | * ï¼æ¾æ ¸æ¥ï¼system/infra æ¨¡åææ Controller å为 {@code @RequestMapping("/system/...")} å½¢å¼ï¼ |
| | | * ä½å®é
请æ±è·¯å¾é½å¸¦ {@code /admin-api} åç¼ï¼æ
ä¸å²çªãï¼ |
| | | */ |
| | | @GetMapping({"/system/**", "/infra/**"}) |
| | | public String adminPages() { |
| | | return SPA_INDEX; |
| | | } |
| | | } |