Przeglądaj źródła

fix(system): 修复预约页面时间显示问题

- 更新 AppSitePriceRulesMapper.xml 中的 SQL 查询逻辑
- 修复由于时区差异导致的时间显示错误
- 优化日期计算方法,确保正确处理不同时间规则
- 调整时间格式化方式,提高可读性
SheepHy 1 tydzień temu
rodzic
commit
1e63ba5934

+ 1 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/app/service/impl/DetailServiceImpl.java

@@ -42,6 +42,7 @@ import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.LocalTime;
 import java.time.ZoneId;
+import java.time.format.DateTimeFormatter;
 import java.util.*;
 import java.util.stream.Collectors;
 

+ 117 - 49
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/system/app/mapper/xml/AppSitePriceRulesMapper.xml

@@ -2,14 +2,24 @@
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="org.jeecg.modules.system.app.mapper.AppSitePriceRulesMapper">
     <select id="theGymnasiumIsCharteredInfo" resultType="org.jeecg.modules.app.vo.PlaceInfoVO$theGymnasiumIsCharteredInfoVO">
-        <![CDATA[
-WITH RECURSIVE dates AS (
-    SELECT 1 AS offset_day, CURDATE() AS date_val, WEEKDAY(CURDATE()) + 1 AS dow
-    UNION ALL
-    SELECT offset_day + 1, date_val + INTERVAL 1 DAY, WEEKDAY(date_val + INTERVAL 1 DAY) + 1
-    FROM dates WHERE offset_day < 7
-),
-available_slots AS (
+        <![CDATA[WITH RECURSIVE dates AS (
+        SELECT
+            1 AS offset_day,
+            CONVERT_TZ(NOW(), '+00:00', '+08:00') AS current_datetime,
+                     DATE(CONVERT_TZ(NOW(), '+00:00', '+08:00')) AS date_val,
+                     WEEKDAY(DATE(CONVERT_TZ(NOW(), '+00:00', '+08:00'))) + 1 AS dow
+                 UNION ALL
+    SELECT
+        offset_day + 1,
+        current_datetime + INTERVAL 1 DAY,
+        date_val + INTERVAL 1 DAY,
+        WEEKDAY(date_val + INTERVAL 1 DAY) + 1
+    FROM
+        dates
+    WHERE
+        offset_day < 7
+        ),
+        available_slots AS (
     SELECT
         r.id,
         r.start_time,
@@ -17,54 +27,112 @@ available_slots AS (
         r.selling_price,
         r.day_of_week,
         r.date_of_sale,
+        CASE
+        WHEN r.date_of_sale IS NOT NULL THEN r.date_of_sale
+        ELSE
+        -- 计算下一个指定星期几的日期 (使用本地时区)
+        DATE(CONVERT_TZ(NOW(), '+00:00', '+08:00')) + INTERVAL (
+        (7 + (r.day_of_week - 1) - WEEKDAY(DATE(CONVERT_TZ(NOW(), '+00:00', '+08:00')))) % 7
+        ) DAY
+        END AS effective_date,
         ROW_NUMBER() OVER (
-            PARTITION BY COALESCE(r.date_of_sale, ADDDATE(CURDATE(), INTERVAL ((7 - WEEKDAY(CURDATE()) + (r.day_of_week - 1)) % 7) DAY))
-            ORDER BY r.start_time ASC
+        PARTITION BY CASE
+        WHEN r.date_of_sale IS NOT NULL THEN r.date_of_sale
+        ELSE
+        DATE(CONVERT_TZ(NOW(), '+00:00', '+08:00')) + INTERVAL (
+        (7 + (r.day_of_week - 1) - WEEKDAY(DATE(CONVERT_TZ(NOW(), '+00:00', '+08:00')))) % 7
+        ) DAY
+        END
+        ORDER BY
+        r.start_time ASC
         ) AS rn
-    FROM nm_site_price_rules r
-    LEFT JOIN nm_order_pro_info opi ON r.id = opi.product_id
+    FROM
+        nm_site_price_rules r
+        LEFT JOIN nm_order_pro_info opi ON r.id = opi.product_id
         AND opi.order_status IN (1, 2)
-        AND opi.use_date_str = COALESCE(
-            DATE_FORMAT(r.date_of_sale, '%Y-%m-%d'),
-            DATE_FORMAT(ADDDATE(CURDATE(), INTERVAL ((7 - WEEKDAY(CURDATE()) + (r.day_of_week - 1)) % 7) DAY), '%Y-%m-%d')
+        AND opi.use_date_str = CASE
+        WHEN r.date_of_sale IS NOT NULL THEN DATE_FORMAT(r.date_of_sale, '%Y-%m-%d')
+        ELSE DATE_FORMAT(
+        DATE(CONVERT_TZ(NOW(), '+00:00', '+08:00')) + INTERVAL (
+        (7 + (r.day_of_week - 1) - WEEKDAY(DATE(CONVERT_TZ(NOW(), '+00:00', '+08:00')))) % 7
+        ) DAY,
+        '%Y-%m-%d'
+        )
+        END
+    WHERE
+        r.org_code = #{orgCode}
+      AND r.category_id = #{categoryId}
+      AND r.del_flag = 0
+      AND opi.product_id IS NULL
+      AND (
+    -- 对于特定日期的规则
+        (
+        r.date_of_sale IS NOT NULL
+      AND (
+        r.date_of_sale > DATE(CONVERT_TZ(NOW(), '+00:00', '+08:00'))
+       OR (
+        r.date_of_sale = DATE(CONVERT_TZ(NOW(), '+00:00', '+08:00'))
+      AND r.start_time > TIME(CONVERT_TZ(NOW(), '+00:00', '+08:00'))
         )
-    WHERE r.org_code = #{orgCode}
-        AND r.category_id = #{categoryId}
-        AND r.del_flag = 0
-        AND opi.product_id IS NULL
-        AND (
-        (r.date_of_sale IS NOT NULL AND (r.date_of_sale > CURDATE() OR (r.date_of_sale = CURDATE() AND r.start_time > CURRENT_TIME())))
-        OR
-        (r.date_of_sale IS NULL AND r.day_of_week IS NOT NULL AND (
-        ADDDATE(CURDATE(), INTERVAL ((7 - WEEKDAY(CURDATE()) + (r.day_of_week - 1)) % 7) DAY) > CURDATE()
-        OR (ADDDATE(CURDATE(), INTERVAL ((7 - WEEKDAY(CURDATE()) + (r.day_of_week - 1)) % 7) DAY) = CURDATE() AND r.start_time > CURRENT_TIME())
-        ))
         )
-        -- 添加时间段有效性检查
-        AND (
-        (r.date_of_sale IS NOT NULL AND (r.date_of_sale > CURDATE() OR (r.date_of_sale = CURDATE() AND r.end_time > CURRENT_TIME())))
-        OR
-        (r.date_of_sale IS NULL AND ADDDATE(CURDATE(), INTERVAL ((7 - WEEKDAY(CURDATE()) + (r.day_of_week - 1)) % 7) DAY) > CURDATE())
-        OR
-        (r.date_of_sale IS NULL AND ADDDATE(CURDATE(), INTERVAL ((7 - WEEKDAY(CURDATE()) + (r.day_of_week - 1)) % 7) DAY) = CURDATE() AND r.end_time > CURRENT_TIME())
         )
+       OR
+    -- 对于按周重复的规则
+        (
+        r.date_of_sale IS NULL
+      AND r.day_of_week IS NOT NULL
+      AND (
+        DATE(CONVERT_TZ(NOW(), '+00:00', '+08:00')) + INTERVAL (
+        (7 + (r.day_of_week - 1) - WEEKDAY(DATE(CONVERT_TZ(NOW(), '+00:00', '+08:00')))) % 7
+        ) DAY > DATE(CONVERT_TZ(NOW(), '+00:00', '+08:00'))
+       OR (
+        DATE(CONVERT_TZ(NOW(), '+00:00', '+08:00')) + INTERVAL (
+        (7 + (r.day_of_week - 1) - WEEKDAY(DATE(CONVERT_TZ(NOW(), '+00:00', '+08:00')))) % 7
+        ) DAY = DATE(CONVERT_TZ(NOW(), '+00:00', '+08:00'))
+      AND r.start_time > TIME(CONVERT_TZ(NOW(), '+00:00', '+08:00'))
         )
-        SELECT
-            asl.id,
-            asl.day_of_week,
-            asl.start_time AS startTime,
-            CONCAT(asl.start_time, '-', asl.end_time) AS time_range,
-            asl.selling_price AS sellingPrice,
-            CASE
-                WHEN dm.offset_day = 1 THEN CONCAT('今天(', DATE_FORMAT(dm.date_val, '%m-%d'), ')')
-                WHEN dm.offset_day = 2 THEN CONCAT('明天(', DATE_FORMAT(dm.date_val, '%m-%d'), ')')
-                WHEN dm.offset_day = 3 THEN CONCAT('后天(', DATE_FORMAT(dm.date_val, '%m-%d'), ')')
-                ELSE CONCAT(ELT(dm.dow, '星期一', '星期二', '星期三', '星期四', '星期五', '星期六', '星期日'), '(', DATE_FORMAT(dm.date_val, '%m-%d'), ')')
-                END AS date_label
-        FROM available_slots asl
-                 JOIN dates dm ON COALESCE(asl.date_of_sale, ADDDATE(CURDATE(), INTERVAL ((7 - WEEKDAY(CURDATE()) + (asl.day_of_week - 1)) % 7) DAY)) = dm.date_val
-        WHERE asl.rn = 1
-        ORDER BY dm.offset_day;
+        )
+        )
+        )
+        )
+    SELECT
+        asl.id,
+        asl.day_of_week,
+        asl.start_time AS startTime,
+        CONCAT(asl.start_time, '-', asl.end_time) AS time_range,
+        asl.selling_price AS sellingPrice,
+        CASE
+            WHEN dm.offset_day = 1 THEN
+                CONCAT('今天(', DATE_FORMAT(dm.date_val, '%m-%d'), ')')
+            WHEN dm.offset_day = 2 THEN
+                CONCAT('明天(', DATE_FORMAT(dm.date_val, '%m-%d'), ')')
+            WHEN dm.offset_day = 3 THEN
+                CONCAT('后天(', DATE_FORMAT(dm.date_val, '%m-%d'), ')')
+            ELSE
+                CONCAT(
+                        CASE
+                            dm.dow
+                            WHEN 1 THEN '星期一'
+                            WHEN 2 THEN '星期二'
+                            WHEN 3 THEN '星期三'
+                            WHEN 4 THEN '星期四'
+                            WHEN 5 THEN '星期五'
+                            WHEN 6 THEN '星期六'
+                            WHEN 7 THEN '星期日'
+                            END,
+                        '(',
+                        DATE_FORMAT(dm.date_val, '%m-%d'),
+                        ')'
+                )
+            END AS date_label
+    FROM
+        available_slots asl
+            JOIN dates dm ON asl.effective_date = dm.date_val
+    WHERE
+        asl.rn = 1
+      AND NOT (dm.offset_day = 1 AND asl.start_time <= TIME(CONVERT_TZ(NOW(), '+00:00', '+08:00')))
+    ORDER BY
+        dm.offset_day;
         ]]>
     </select>
     <select id="timeSlot" resultType="org.jeecg.modules.app.vo.OrderVO$PreviewOrderPlaceSchoolChild">