diff --git a/gym-manage-api/gym-groupCourse/pom.xml b/gym-manage-api/gym-groupCourse/pom.xml
index 3fc53bb..a7bfc02 100644
--- a/gym-manage-api/gym-groupCourse/pom.xml
+++ b/gym-manage-api/gym-groupCourse/pom.xml
@@ -67,6 +67,13 @@
2.2.43
compile
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-redis
+
diff --git a/gym-manage-api/gym-groupCourse/src/main/java/cn/novalon/gym/manage/groupcourse/handler/GroupCourseHandler.java b/gym-manage-api/gym-groupCourse/src/main/java/cn/novalon/gym/manage/groupcourse/handler/GroupCourseHandler.java
index 920786f..db6c601 100644
--- a/gym-manage-api/gym-groupCourse/src/main/java/cn/novalon/gym/manage/groupcourse/handler/GroupCourseHandler.java
+++ b/gym-manage-api/gym-groupCourse/src/main/java/cn/novalon/gym/manage/groupcourse/handler/GroupCourseHandler.java
@@ -1,8 +1,11 @@
package cn.novalon.gym.manage.groupcourse.handler;
+import cn.novalon.gym.manage.common.dto.PageRequest;
import cn.novalon.gym.manage.groupcourse.domain.GroupCourse;
import cn.novalon.gym.manage.groupcourse.service.IGroupCourseService;
+import cn.novalon.gym.manage.groupcourse.service.RedisService;
+import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Validator;
@@ -11,15 +14,25 @@ import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Mono;
+import java.util.HashMap;
+import java.util.Map;
+
@Component
@Tag(name="团课管理",description = "团课相关操作")
public class GroupCourseHandler {
private final IGroupCourseService groupCourseService;
private final Validator validator;
+ private final RedisService redisService;
+ private final ObjectMapper objectMapper;
- public GroupCourseHandler(IGroupCourseService groupCourseService, Validator validator){
+ public GroupCourseHandler(IGroupCourseService groupCourseService,
+ Validator validator,
+ RedisService redisService,
+ ObjectMapper objectMapper){
this.groupCourseService = groupCourseService;
this.validator = validator;
+ this.redisService = redisService;
+ this.objectMapper = objectMapper;
}
@Operation(summary = "获取所有团课", description = "获取系统中所有团课列表")
@@ -29,10 +42,87 @@ public class GroupCourseHandler {
.body(groupCourseService.findAll(includeDeleted), GroupCourse.class);
}
+ @Operation(summary = "分页获取团课", description = "根据分页参数获取团课列表")
+ public Mono getGroupCoursesByPage(ServerRequest request) {
+ return request.bodyToMono(PageRequest.class)
+ .flatMap(pageRequest -> {
+ boolean includeDeleted = request.queryParam("includeDeleted")
+ .map(Boolean::parseBoolean)
+ .orElse(false);
+
+ if (pageRequest.getPage() < 0) {
+ pageRequest.setPage(0);
+ }
+ if (pageRequest.getSize() <= 0 || pageRequest.getSize() > 100) {
+ pageRequest.setSize(10);
+ }
+ if (pageRequest.getSort() == null || pageRequest.getSort().isEmpty()) {
+ pageRequest.setSort("id");
+ }
+ if (pageRequest.getOrder() == null || pageRequest.getOrder().isEmpty()) {
+ pageRequest.setOrder("asc");
+ }
+
+ return groupCourseService.findByPage(pageRequest, includeDeleted)
+ .flatMap(response -> ServerResponse.ok().bodyValue(response));
+ });
+ }
+
@Operation(summary = "根据ID获取团课", description = "根据ID获取团课详情")
public Mono getGroupCourseById(ServerRequest request){
Long id = Long.valueOf(request.pathVariable("id"));
return ServerResponse.ok()
.body(groupCourseService.findById(id), GroupCourse.class);
}
+
+ @Operation(summary = "测试-根据Key获取Redis缓存", description = "测试接口:根据传入的key值获取Redis中缓存的数据")
+ public Mono getCacheByKey(ServerRequest request) {
+ return request.bodyToMono(Map.class)
+ .flatMap(body -> {
+ String key = (String) body.get("key");
+
+ if (key == null || key.isEmpty()) {
+ Map error = new HashMap<>();
+ error.put("success", false);
+ error.put("message", "key参数不能为空");
+ return ServerResponse.badRequest().bodyValue(error);
+ }
+
+ Object cachedValue = redisService.get(key);
+
+ Map result = new HashMap<>();
+ if (cachedValue != null) {
+ result.put("success", true);
+ result.put("key", key);
+ result.put("value", cachedValue);
+ result.put("message", "缓存命中");
+
+ try {
+ if (cachedValue instanceof String) {
+ Object jsonObject = objectMapper.readValue((String) cachedValue, Object.class);
+ result.put("parsedValue", jsonObject);
+ result.put("valueType", "JSON字符串");
+ } else {
+ result.put("valueType", cachedValue.getClass().getSimpleName());
+ }
+ } catch (Exception e) {
+ result.put("parsedValue", null);
+ result.put("valueType", "无法解析");
+ }
+ } else {
+ result.put("success", false);
+ result.put("key", key);
+ result.put("value", null);
+ result.put("message", "缓存未命中");
+ }
+
+ return ServerResponse.ok().bodyValue(result);
+ })
+ .onErrorResume(error -> {
+ Map errorResponse = new HashMap<>();
+ errorResponse.put("success", false);
+ errorResponse.put("message", "请求处理失败: " + error.getMessage());
+ return ServerResponse.status(500).bodyValue(errorResponse);
+ });
+ }
}
diff --git a/gym-manage-api/gym-groupCourse/src/main/java/cn/novalon/gym/manage/groupcourse/repository/IGroupCourseRepository.java b/gym-manage-api/gym-groupCourse/src/main/java/cn/novalon/gym/manage/groupcourse/repository/IGroupCourseRepository.java
index 4ade673..1a2d402 100644
--- a/gym-manage-api/gym-groupCourse/src/main/java/cn/novalon/gym/manage/groupcourse/repository/IGroupCourseRepository.java
+++ b/gym-manage-api/gym-groupCourse/src/main/java/cn/novalon/gym/manage/groupcourse/repository/IGroupCourseRepository.java
@@ -1,6 +1,8 @@
package cn.novalon.gym.manage.groupcourse.repository;
+import cn.novalon.gym.manage.common.dto.PageRequest;
+import cn.novalon.gym.manage.common.dto.PageResponse;
import cn.novalon.gym.manage.groupcourse.domain.GroupCourse;
import org.springframework.data.domain.Sort;
import reactor.core.publisher.Flux;
@@ -12,4 +14,7 @@ public interface IGroupCourseRepository {
Flux findAll(Sort sort);
Flux findByDeletedAtIsNull();
Flux findByDeletedAtIsNull(Sort sort);
+
+ Mono> findByPage(PageRequest pageRequest);
+ Mono> findByPageAndNotDeleted(PageRequest pageRequest);
}
diff --git a/gym-manage-api/gym-groupCourse/src/main/java/cn/novalon/gym/manage/groupcourse/repository/impl/GroupCourseRepository.java b/gym-manage-api/gym-groupCourse/src/main/java/cn/novalon/gym/manage/groupcourse/repository/impl/GroupCourseRepository.java
index 5c11325..aa249d1 100644
--- a/gym-manage-api/gym-groupCourse/src/main/java/cn/novalon/gym/manage/groupcourse/repository/impl/GroupCourseRepository.java
+++ b/gym-manage-api/gym-groupCourse/src/main/java/cn/novalon/gym/manage/groupcourse/repository/impl/GroupCourseRepository.java
@@ -1,16 +1,22 @@
package cn.novalon.gym.manage.groupcourse.repository.impl;
+import cn.novalon.gym.manage.common.dto.PageRequest;
+import cn.novalon.gym.manage.common.dto.PageResponse;
import cn.novalon.gym.manage.groupcourse.converter.GroupCourseConverter;
import cn.novalon.gym.manage.groupcourse.dao.GroupCourseDao;
import cn.novalon.gym.manage.groupcourse.domain.GroupCourse;
+import cn.novalon.gym.manage.groupcourse.entity.GroupCourseEntity;
import cn.novalon.gym.manage.groupcourse.repository.IGroupCourseRepository;
import org.springframework.data.domain.Sort;
import org.springframework.data.r2dbc.core.R2dbcEntityTemplate;
+import org.springframework.data.relational.core.query.Query;
import org.springframework.stereotype.Repository;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
+import java.util.List;
+
@Repository
public class GroupCourseRepository implements IGroupCourseRepository {
private final GroupCourseDao groupCourseDao;
@@ -53,4 +59,73 @@ public class GroupCourseRepository implements IGroupCourseRepository {
return groupCourseDao.findAllByDeletedAtIsNull(sort)
.map(groupCourseConverter::toDomain);
}
+
+ @Override
+ public Mono> findByPage(PageRequest pageRequest) {
+ int page = pageRequest.getPage();
+ int size = pageRequest.getSize();
+ String sort = pageRequest.getSort();
+ String order = pageRequest.getOrder();
+
+ Sort sortObj = Sort.unsorted();
+ if (sort != null && !sort.isEmpty()) {
+ sortObj = Sort.by(Sort.Direction.fromString(order), sort);
+ }
+
+ org.springframework.data.domain.PageRequest pageable = org.springframework.data.domain.PageRequest.of(page, size, sortObj);
+
+ Query query = Query.empty();
+
+ return r2dbcEntityTemplate.select(GroupCourseEntity.class)
+ .matching(query.with(pageable))
+ .all()
+ .collectList()
+ .zipWith(r2dbcEntityTemplate.count(query, GroupCourseEntity.class))
+ .map(tuple -> {
+ long total = tuple.getT2();
+ int totalPages = (int) Math.ceil((double) total / size);
+ List courseList = tuple.getT1().stream()
+ .map(groupCourseConverter::toDomain)
+ .toList();
+ return new PageResponse<>(courseList, totalPages, total, page, size);
+ });
+ }
+
+ @Override
+ public Mono> findByPageAndNotDeleted(PageRequest pageRequest) {
+ int page = pageRequest.getPage();
+ int size = pageRequest.getSize();
+ String sort = pageRequest.getSort();
+ String order = pageRequest.getOrder();
+
+ Sort sortObj = Sort.unsorted();
+ if (sort != null && !sort.isEmpty()) {
+ sortObj = Sort.by(Sort.Direction.fromString(order), sort);
+ }
+
+ org.springframework.data.domain.PageRequest pageable = org.springframework.data.domain.PageRequest.of(page, size, sortObj);
+
+ return groupCourseDao.findAllByDeletedAtIsNull(sortObj)
+ .collectList()
+ .zipWith(groupCourseDao.findAllByDeletedAtIsNull().count())
+ .map(tuple -> {
+ List allEntities = tuple.getT1();
+ long total = tuple.getT2();
+
+ int fromIndex = page * size;
+ int toIndex = Math.min(fromIndex + size, allEntities.size());
+
+ List courseList;
+ if (fromIndex < allEntities.size()) {
+ courseList = allEntities.subList(fromIndex, toIndex).stream()
+ .map(groupCourseConverter::toDomain)
+ .toList();
+ } else {
+ courseList = List.of();
+ }
+
+ int totalPages = (int) Math.ceil((double) total / size);
+ return new PageResponse<>(courseList, totalPages, total, page, size);
+ });
+ }
}
diff --git a/gym-manage-api/gym-groupCourse/src/main/java/cn/novalon/gym/manage/groupcourse/service/IGroupCourseService.java b/gym-manage-api/gym-groupCourse/src/main/java/cn/novalon/gym/manage/groupcourse/service/IGroupCourseService.java
index d43b396..7fa0b70 100644
--- a/gym-manage-api/gym-groupCourse/src/main/java/cn/novalon/gym/manage/groupcourse/service/IGroupCourseService.java
+++ b/gym-manage-api/gym-groupCourse/src/main/java/cn/novalon/gym/manage/groupcourse/service/IGroupCourseService.java
@@ -1,6 +1,8 @@
package cn.novalon.gym.manage.groupcourse.service;
+import cn.novalon.gym.manage.common.dto.PageRequest;
+import cn.novalon.gym.manage.common.dto.PageResponse;
import cn.novalon.gym.manage.groupcourse.domain.GroupCourse;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
@@ -9,4 +11,6 @@ public interface IGroupCourseService {
Mono findById(Long id);
Flux findAll();
Flux findAll(boolean includeDeleted);
+
+ Mono> findByPage(PageRequest pageRequest, boolean includeDeleted);
}
diff --git a/gym-manage-api/gym-groupCourse/src/main/java/cn/novalon/gym/manage/groupcourse/service/RedisService.java b/gym-manage-api/gym-groupCourse/src/main/java/cn/novalon/gym/manage/groupcourse/service/RedisService.java
new file mode 100644
index 0000000..aa92e38
--- /dev/null
+++ b/gym-manage-api/gym-groupCourse/src/main/java/cn/novalon/gym/manage/groupcourse/service/RedisService.java
@@ -0,0 +1,76 @@
+package cn.novalon.gym.manage.groupcourse.service;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.stereotype.Service;
+
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * @author:liwentao
+ * @date:2026/5/15-05-15-16:05
+ */
+@Service
+public class RedisService {
+
+ @Autowired
+ private RedisTemplate redisTemplate;
+
+ // 设置值
+ public void set(String key, Object value) {
+ redisTemplate.opsForValue().set(key, value);
+ }
+
+ // 设置值并指定过期时间(秒)
+ public void setWithExpire(String key, Object value, long timeout) {
+ redisTemplate.opsForValue().set(key, value, timeout, TimeUnit.SECONDS);
+ }
+
+ // 获取值
+ public Object get(String key) {
+ return redisTemplate.opsForValue().get(key);
+ }
+
+ // 删除key
+ public Boolean delete(String key) {
+ return redisTemplate.delete(key);
+ }
+
+ // 判断key是否存在
+ public Boolean hasKey(String key) {
+ return redisTemplate.hasKey(key);
+ }
+
+ // 设置过期时间
+ public Boolean expire(String key, long timeout) {
+ return redisTemplate.expire(key, timeout, TimeUnit.SECONDS);
+ }
+
+ // Hash操作
+ public void putHash(String key, String hashKey, Object value) {
+ redisTemplate.opsForHash().put(key, hashKey, value);
+ }
+
+ public Object getHash(String key, String hashKey) {
+ return redisTemplate.opsForHash().get(key, hashKey);
+ }
+
+ // List操作
+ public void leftPush(String key, Object value) {
+ redisTemplate.opsForList().leftPush(key, value);
+ }
+
+ public Object rightPop(String key) {
+ return redisTemplate.opsForList().rightPop(key);
+ }
+
+ // Set操作
+ public void addToSet(String key, Object... values) {
+ redisTemplate.opsForSet().add(key, values);
+ }
+
+ public Set