yxh
7 天以前 68ff33beff11310e830b0615b5a81f83fad0f683
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
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;
 
public class Utils {
    public static LocalTime parseTime(String strTime) {
        String regex = "(\\d+)[::](\\d+)";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(strTime);
 
        if (!matcher.find())
            return null;
 
        // 获取整个匹配的字符串
        String fullMatch = matcher.group();
 
        // 获取第一个捕获组(小时)
        String strOpenHour = matcher.group(1);
 
        // 获取第二个捕获组(分钟)
        String strOpenMinute = matcher.group(2);
 
        LocalTime localTime = LocalTime.of(Integer.valueOf(strOpenHour), Integer.valueOf(strOpenMinute));
        return localTime;
    }
 
    public static List<LocalTime> parseOpeningTime(String strOpeningTime) {
        String regex = "(\\d+)[::](\\d+)~(\\d+)[::](\\d+)";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(strOpeningTime);
 
        if (!matcher.find())
            return null;
 
        // 获取整个匹配的字符串
        String fullMatch = matcher.group();
 
        // 获取第一个捕获组(小时)
        String strOpenHour = matcher.group(1);
 
        // 获取第二个捕获组(分钟)
        String strOpenMinute = matcher.group(2);
 
        // 获取第一个捕获组(小时)
        String strCloseHour = matcher.group(3);
 
        // 获取第二个捕获组(分钟)
        String strCloseMinute = matcher.group(4);
 
        LocalTime localOpenTime = LocalTime.of(Integer.valueOf(strOpenHour), Integer.valueOf(strOpenMinute));
        LocalTime localCloseTime = LocalTime.of(Integer.valueOf(strCloseHour), Integer.valueOf(strCloseMinute));
        List openCloseTime = new ArrayList<LocalTime>();
        openCloseTime.add(localOpenTime);
        openCloseTime.add(localCloseTime);
        return openCloseTime;
    }
 
    public static String  formatRoomBed(Long roomId, String bedNo) {
        return String.format("%09d%s", roomId, bedNo);
    }
 
    public static List<LocalTime> parseTimeSlotList(String strTimeSlotList, Integer timeslotLength) {
        List<LocalTime> localTimeList = new ArrayList<>();
 
        // 7:30,8:30,9:30,10:30,11:30,12:30,13:30,14:30,15:30
        String[] arrTimeSlotItemStr = strTimeSlotList.split(",|,");
        Arrays.stream(arrTimeSlotItemStr).forEach( strTimeSlot -> {
            String regex = "(\\d+)[::](\\d+)";
            Pattern pattern = Pattern.compile(regex);
            Matcher matcher = pattern.matcher(strTimeSlot);
            if (!matcher.find())
                return;
 
            // 获取整个匹配的字符串
            String fullMatch = matcher.group();
 
            // 获取第一个捕获组(小时)
            String strHour = matcher.group(1);
 
            // 获取第二个捕获组(分钟)
            String strMinute = matcher.group(2);
 
            LocalTime localTimeSlot = LocalTime.of(Integer.valueOf(strHour), Integer.valueOf(strMinute));
            localTimeList.add( localTimeSlot );
        } );
 
        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();
    }
}