From 8da58a8f5187c7e12be1c5eadc5298e907379a71 Mon Sep 17 00:00:00 2001 From: liwentao Date: Thu, 18 Jun 2026 10:48:23 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=8A=9F=E8=83=BD=EF=BC=9A?= =?UTF-8?q?=E5=9B=A2=E8=AF=BE=E7=AD=BE=E5=88=B0=E5=89=8D=E9=AA=8C=E8=AF=81?= =?UTF-8?q?=E6=98=AF=E5=90=A6=E5=88=B0=E5=BA=97=E7=AD=BE=E5=88=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gym-manage-api/docs/groupcourse-api.md | 5 ++- .../service/impl/GroupCourseService.java | 39 +++++++++++++------ 2 files changed, 32 insertions(+), 12 deletions(-) diff --git a/gym-manage-api/docs/groupcourse-api.md b/gym-manage-api/docs/groupcourse-api.md index 4880759..481fb06 100644 --- a/gym-manage-api/docs/groupcourse-api.md +++ b/gym-manage-api/docs/groupcourse-api.md @@ -648,7 +648,9 @@ | 4 | 当前时间早于开课前2小时 | `未到签到时间,请在开课前2小时内签到` | | 5 | 当前时间晚于团课结束时间 | `团课已结束,无法签到` | | 6 | 课程当前人数已达上限 | `课程已满员,无法签到` | -| 7 | 用户未预约此课程 | `您未预约此课程,无法签到` | +| 7 | 用户今日无到店签到记录 | `请先完成到店签到` | +| 8 | 到店签到状态非SUCCESS | `到店签到未成功,请重新签到` | +| 9 | 用户未预约此课程 | `您未预约此课程,无法签到` | | - | 请求体为空 | `请求体不能为空` | | - | 请求体缺少courseId | `courseId不能为空` | @@ -1664,6 +1666,7 @@ - 团课状态不为"已结束"(含已过结束时间) - 当前时间在开课前2小时内(签到时间窗口) - 课程当前人数未达到最大人数上限 + - 用户今日已成功到店签到(查询 sign_in_record 表当日 SUCCESS 记录) - 用户已预约该课程(有效预约) 4. **删除团课**:采用软删除机制,数据保留可恢复 diff --git a/gym-manage-api/gym-groupCourse/src/main/java/cn/novalon/gym/manage/groupcourse/service/impl/GroupCourseService.java b/gym-manage-api/gym-groupCourse/src/main/java/cn/novalon/gym/manage/groupcourse/service/impl/GroupCourseService.java index 023c8ee..91b871d 100644 --- a/gym-manage-api/gym-groupCourse/src/main/java/cn/novalon/gym/manage/groupcourse/service/impl/GroupCourseService.java +++ b/gym-manage-api/gym-groupCourse/src/main/java/cn/novalon/gym/manage/groupcourse/service/impl/GroupCourseService.java @@ -28,6 +28,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.r2dbc.core.DatabaseClient; import org.springframework.stereotype.Service; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @@ -49,6 +50,7 @@ public class GroupCourseService implements IGroupCourseService { private final RedisUtil redisUtil; private final ObjectMapper objectMapper; private final GroupCourseStateMachine stateMachine; + private final DatabaseClient databaseClient; private static final String CACHE_KEY_PREFIX = "group_course:page:"; private static final String CACHE_KEY_ID_PREFIX = "group_course:id:"; @@ -65,7 +67,8 @@ public class GroupCourseService implements IGroupCourseService { MemberCardRepository memberCardRepository, RedisUtil redisUtil, ObjectMapper objectMapper, - GroupCourseStateMachine stateMachine){ + GroupCourseStateMachine stateMachine, + DatabaseClient databaseClient){ this.groupCourseRepository = groupCourseRepository; this.bookingRepository = bookingRepository; this.groupCourseTypeRepository = groupCourseTypeRepository; @@ -75,6 +78,7 @@ public class GroupCourseService implements IGroupCourseService { this.redisUtil = redisUtil; this.objectMapper = objectMapper; this.stateMachine = stateMachine; + this.databaseClient = databaseClient; } @Override @@ -506,16 +510,29 @@ public class GroupCourseService implements IGroupCourseService { return Mono.error(new RuntimeException("课程已满员,无法签到")); } - // 校验5:用户已预约此课程(有效预约,状态为0-已预约) - return bookingRepository.findValidBooking(courseId, memberId) - .switchIfEmpty(Mono.error(new RuntimeException("您未预约此课程,无法签到"))) - .flatMap(booking -> { - // 更新课程当前人数 - return groupCourseRepository.updateCurrentMembers(courseId, 1) - .flatMap(updatedCourse -> { - // 更新预约状态为已出席 - return bookingRepository.updateStatus(booking.getId(), "2") - .thenReturn(updatedCourse); + // 校验5:用户今日是否已到店签到(直接查询sign_in_record表) + LocalDateTime todayStart = LocalDateTime.now().toLocalDate().atStartOfDay(); + LocalDateTime todayEnd = todayStart.plusDays(1); + return databaseClient.sql("SELECT sign_in_status FROM sign_in_record WHERE member_id = :memberId AND sign_in_time >= :startTime AND sign_in_time < :endTime AND is_delete = false ORDER BY sign_in_time DESC LIMIT 1") + .bind("memberId", memberId) + .bind("startTime", todayStart) + .bind("endTime", todayEnd) + .map(row -> row.get("sign_in_status", String.class)) + .one() + .switchIfEmpty(Mono.error(new RuntimeException("请先完成到店签到"))) + .flatMap(status -> { + if (!"SUCCESS".equals(status)) { + return Mono.error(new RuntimeException("到店签到未成功,请重新签到")); + } + // 校验6:用户已预约此课程(有效预约,状态为0-已预约) + return bookingRepository.findValidBooking(courseId, memberId) + .switchIfEmpty(Mono.error(new RuntimeException("您未预约此课程,无法签到"))) + .flatMap(booking -> { + return groupCourseRepository.updateCurrentMembers(courseId, 1) + .flatMap(updatedCourse -> { + return bookingRepository.updateStatus(booking.getId(), "2") + .thenReturn(updatedCourse); + }); }); }); }) -- 2.52.0