This commit is contained in:
zjf committed 2026-05-25 18:07:09 +08:00
1 parent 45b8e69402
commit 4e5e9cee2e
1 file changed
+145
@@ -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<OrderingFoodMealSegmentVO> parseMealSegments(String jobTime) {
List<OrderingFoodMealSegmentVO> out = new ArrayList<>();
List<TimeRange> 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<OrderingFoodMealSegmentVO> 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<TimeRange> mergeJobTimeIntervals(String jobTime) {
List<TimeRange> 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<TimeRange> 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;
}
}
}