diff --git a/pjcloud-canteen/pjcloud-canteen-biz/src/main/java/com/bsd/pjcloud/canteen/util/MchJobTimeMealSegmentUtils.java b/pjcloud-canteen/pjcloud-canteen-biz/src/main/java/com/bsd/pjcloud/canteen/util/MchJobTimeMealSegmentUtils.java new file mode 100644 index 00000000..4538c729 --- /dev/null +++ b/pjcloud-canteen/pjcloud-canteen-biz/src/main/java/com/bsd/pjcloud/canteen/util/MchJobTimeMealSegmentUtils.java @@ -0,0 +1,145 @@ +package com.bsd.pjcloud.canteen.util; + +import cn.hutool.core.util.StrUtil; +import com.bsd.pjcloud.canteen.vo.app.OrderingFoodMealSegmentVO; + +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeFormatterBuilder; +import java.time.format.DateTimeParseException; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; + +/** + * 将商户 {@code jobTime}(营业时间)解析为报餐餐段列表。 + */ +public final class MchJobTimeMealSegmentUtils { + + private static final DateTimeFormatter HM = DateTimeFormatter.ofPattern("HH:mm"); + + private static final DateTimeFormatter HM_OPTIONAL_SEC = new DateTimeFormatterBuilder() + .appendPattern("HH:mm") + .optionalStart() + .appendPattern(":ss") + .optionalEnd() + .toFormatter(); + + private static final String[] DEFAULT_SEGMENT_NAMES = {"早餐", "午餐", "晚餐"}; + + private MchJobTimeMealSegmentUtils() { + } + + public static boolean isBlankJobTime(String jobTime) { + return StrUtil.isBlank(StrUtil.trim(jobTime)); + } + + public static List parseMealSegments(String jobTime) { + List out = new ArrayList<>(); + List merged = mergeJobTimeIntervals(jobTime); + for (int i = 0; i < merged.size(); i++) { + TimeRange r = merged.get(i); + OrderingFoodMealSegmentVO vo = new OrderingFoodMealSegmentVO(); + vo.setSegmentIndex(i); + vo.setMealSegmentType(resolveMealType(i)); + vo.setMealSegmentName(resolveMealName(i)); + vo.setStartTime(r.start.format(HM)); + vo.setEndTime(r.end.format(HM)); + out.add(vo); + } + return out; + } + + public static OrderingFoodMealSegmentVO findSegment(String jobTime, int segmentIndex) { + List list = parseMealSegments(jobTime); + if (segmentIndex < 0 || segmentIndex >= list.size()) { + return null; + } + return list.get(segmentIndex); + } + + public static boolean isValidSegmentIndex(String jobTime, Integer segmentIndex) { + if (segmentIndex == null || segmentIndex < 0) { + return false; + } + return findSegment(jobTime, segmentIndex) != null; + } + + private static int resolveMealType(int index) { + if (index >= 0 && index < DEFAULT_SEGMENT_NAMES.length) { + return index + 1; + } + return 99; + } + + private static String resolveMealName(int index) { + if (index >= 0 && index < DEFAULT_SEGMENT_NAMES.length) { + return DEFAULT_SEGMENT_NAMES[index]; + } + return "时段" + (index + 1); + } + + private static List mergeJobTimeIntervals(String jobTime) { + List raw = new ArrayList<>(); + if (isBlankJobTime(jobTime)) { + return raw; + } + for (String part : jobTime.split(",")) { + part = StrUtil.trim(part); + if (StrUtil.isBlank(part)) { + continue; + } + String[] se = part.split("-"); + if (se.length != 2) { + continue; + } + LocalTime a = parseHm(StrUtil.trim(se[0])); + LocalTime b = parseHm(StrUtil.trim(se[1])); + if (a == null || b == null || !b.isAfter(a)) { + continue; + } + raw.add(new TimeRange(a, b)); + } + if (raw.isEmpty()) { + return raw; + } + raw.sort(Comparator.comparing(r -> r.start)); + List merged = new ArrayList<>(); + TimeRange cur = raw.get(0); + for (int i = 1; i < raw.size(); i++) { + TimeRange next = raw.get(i); + if (!next.start.isAfter(cur.end)) { + if (next.end.isAfter(cur.end)) { + cur = new TimeRange(cur.start, next.end); + } + } else { + merged.add(cur); + cur = next; + } + } + merged.add(cur); + return merged; + } + + private static LocalTime parseHm(String s) { + try { + return LocalTime.parse(s, HM_OPTIONAL_SEC); + } catch (DateTimeParseException e) { + try { + return LocalTime.parse(s, HM); + } catch (DateTimeParseException e2) { + return null; + } + } + } + + private static final class TimeRange { + private final LocalTime start; + private final LocalTime end; + + private TimeRange(LocalTime start, LocalTime end) { + this.start = start; + this.end = end; + } + } +}