From aa67b3cb0fe26fab576f7710c978ff3594426cca Mon Sep 17 00:00:00 2001
From: longz <longzhaoz@qq.com>
Date: 星期四, 28 五月 2026 15:23:30 +0800
Subject: [PATCH] 添加微信公众号登录功能并优化系统配置

---
 backend/src/main/java/com/sinata/appointment/service/ConfigApplicationService.java |   65 ++++++++++++++++++++++++++++++++
 1 files changed, 65 insertions(+), 0 deletions(-)

diff --git a/backend/src/main/java/com/sinata/appointment/service/ConfigApplicationService.java b/backend/src/main/java/com/sinata/appointment/service/ConfigApplicationService.java
index 839bcf0..562683d 100644
--- a/backend/src/main/java/com/sinata/appointment/service/ConfigApplicationService.java
+++ b/backend/src/main/java/com/sinata/appointment/service/ConfigApplicationService.java
@@ -33,6 +33,7 @@
 import com.sinata.appointment.mapper.SysDeptMapper;
 import com.sinata.appointment.util.UuidAssert;
 import java.time.LocalDate;
+import java.time.YearMonth;
 import java.time.format.DateTimeParseException;
 import java.util.Comparator;
 import java.util.LinkedHashSet;
@@ -233,6 +234,62 @@
     }
 
     @Transactional(rollbackFor = Exception.class)
+    public void toggleHolidayDate(String date, boolean holiday) {
+        LocalDate target = parseDate(date);
+        if (holiday) {
+            Long exists =
+                    bizHolidayDateMapper.selectCount(
+                            new LambdaQueryWrapper<BizHolidayDate>()
+                                    .eq(BizHolidayDate::getDelFlag, 0)
+                                    .eq(BizHolidayDate::getHolidayDate, target));
+            if (exists == null || exists == 0L) {
+                BizHolidayDate row = new BizHolidayDate();
+                row.setHolidayDate(target);
+                bizHolidayDateMapper.insert(row);
+            }
+        } else {
+            bizHolidayDateMapper.deleteByHolidayDates(List.of(target));
+        }
+        bizHolidayDateCacheService.evictAllHolidayDates();
+        upsertSetting(SystemSettingKeys.BOOKING_HOLIDAY_DATES, "[]");
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    public void addMonthWeekends(String month) {
+        YearMonth yearMonth;
+        try {
+            yearMonth = YearMonth.parse(month.trim());
+        } catch (Exception ex) {
+            throw new BizException(BizErrorCode.AUTH_INVALID_CREDENTIALS, "非法月份: " + month);
+        }
+        Set<LocalDate> existsSet =
+                bizHolidayDateMapper.selectList(
+                                new LambdaQueryWrapper<BizHolidayDate>()
+                                        .eq(BizHolidayDate::getDelFlag, 0)
+                                        .ge(BizHolidayDate::getHolidayDate, yearMonth.atDay(1))
+                                        .le(BizHolidayDate::getHolidayDate, yearMonth.atEndOfMonth()))
+                        .stream()
+                        .map(BizHolidayDate::getHolidayDate)
+                        .collect(Collectors.toSet());
+
+        for (int d = 1; d <= yearMonth.lengthOfMonth(); d++) {
+            LocalDate current = yearMonth.atDay(d);
+            int dayOfWeek = current.getDayOfWeek().getValue(); // 1..7 (Mon..Sun)
+            if (dayOfWeek != 6 && dayOfWeek != 7) {
+                continue;
+            }
+            if (existsSet.contains(current)) {
+                continue;
+            }
+            BizHolidayDate row = new BizHolidayDate();
+            row.setHolidayDate(current);
+            bizHolidayDateMapper.insert(row);
+        }
+        bizHolidayDateCacheService.evictAllHolidayDates();
+        upsertSetting(SystemSettingKeys.BOOKING_HOLIDAY_DATES, "[]");
+    }
+
+    @Transactional(rollbackFor = Exception.class)
     public void saveContentSettings(ContentSettingsSaveRequest req) {
         upsertSetting(SystemSettingKeys.CONTENT_ABOUT_US_HTML, normalizeHtml(req.getAboutUsHtml()));
         upsertSetting(SystemSettingKeys.CONTENT_PARK_NOTICE_HTML, normalizeHtml(req.getParkNoticeHtml()));
@@ -397,6 +454,14 @@
         return set.stream().sorted(Comparator.naturalOrder()).collect(Collectors.toList());
     }
 
+    private LocalDate parseDate(String date) {
+        try {
+            return LocalDate.parse(date.trim());
+        } catch (Exception ex) {
+            throw new BizException(BizErrorCode.AUTH_INVALID_CREDENTIALS, "非法日期: " + date);
+        }
+    }
+
     private BizVisitReason loadActiveVisitReason(Long id, String uuid) {
         BizVisitReason row = bizVisitReasonMapper.selectById(id);
         if (row == null || (row.getDelFlag() != null && row.getDelFlag() == 1)) {

--
Gitblit v1.7.1