feat: add api recommond game list
This commit is contained in:
@@ -0,0 +1,22 @@
|
|||||||
|
package icu.sunway.ai_spring_example.Config;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.models.OpenAPI;
|
||||||
|
import io.swagger.v3.oas.models.info.Info;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OpenAPI配置类
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
public class OpenApiConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public OpenAPI customOpenAPI() {
|
||||||
|
return new OpenAPI()
|
||||||
|
.info(new Info()
|
||||||
|
.title("Steam-like Game Platform API")
|
||||||
|
.version("1.0.0")
|
||||||
|
.description("类似Steam的游戏平台API文档,提供游戏推荐等功能"));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
package icu.sunway.ai_spring_example.Controllers.GameController;
|
||||||
|
|
||||||
|
import icu.sunway.ai_spring_example.Controllers.GameController.VO.GameVO;
|
||||||
|
import icu.sunway.ai_spring_example.Service.IGameService;
|
||||||
|
import icu.sunway.ai_spring_example.Utils.PageUtils;
|
||||||
|
import icu.sunway.ai_spring_example.Utils.ResponseUtils;
|
||||||
|
import icu.sunway.ai_spring_example.Utils.ResponseUtils.Response;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/games")
|
||||||
|
public class GameController {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private IGameService gameService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取游戏推荐列表
|
||||||
|
*
|
||||||
|
* @param page 当前页码
|
||||||
|
* @param limit 每页游戏数量
|
||||||
|
* @return 游戏推荐列表
|
||||||
|
*/
|
||||||
|
@GetMapping("/recommendations")
|
||||||
|
public Response<PageUtils.PaginationResult<GameVO>> getRecommendedGames(
|
||||||
|
@RequestParam(required = false) Integer page,
|
||||||
|
@RequestParam(required = false) Integer limit) {
|
||||||
|
try {
|
||||||
|
PageUtils.PaginationResult<GameVO> result = gameService.getRecommendedGames(page, limit);
|
||||||
|
return ResponseUtils.success("获取游戏推荐列表成功", result);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return ResponseUtils.fail(ResponseUtils.INTERNAL_SERVER_ERROR, "获取游戏推荐列表失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package icu.sunway.ai_spring_example.Controllers.GameController.VO;
|
||||||
|
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 游戏推荐列表VO,只返回指定的信息
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
public class GameVO {
|
||||||
|
private String name;
|
||||||
|
private String mainImage;
|
||||||
|
private String supportedPlatforms;
|
||||||
|
private List<String> genres;
|
||||||
|
private BigDecimal price;
|
||||||
|
private Integer discountPercentage;
|
||||||
|
private LocalDateTime releaseDate;
|
||||||
|
private List<ScreenshotVO> screenshots;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 游戏截图VO
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
public static class ScreenshotVO {
|
||||||
|
private String mediaUrl;
|
||||||
|
private String thumbnailUrl;
|
||||||
|
}
|
||||||
|
}
|
||||||
64
src/main/java/icu/sunway/ai_spring_example/Entity/Game.java
Normal file
64
src/main/java/icu/sunway/ai_spring_example/Entity/Game.java
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
package icu.sunway.ai_spring_example.Entity;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@TableName("games")
|
||||||
|
public class Game {
|
||||||
|
private Integer id;
|
||||||
|
private Integer steamAppid;
|
||||||
|
private String name;
|
||||||
|
private String slug;
|
||||||
|
private String shortDescription;
|
||||||
|
private String detailedDescription;
|
||||||
|
private String aboutTheGame;
|
||||||
|
private LocalDateTime releaseDate;
|
||||||
|
private Boolean comingSoon;
|
||||||
|
private BigDecimal price;
|
||||||
|
private Integer discountPercentage;
|
||||||
|
private BigDecimal finalPrice;
|
||||||
|
private String currency;
|
||||||
|
private String paymentType;
|
||||||
|
private Integer metacriticScore;
|
||||||
|
private BigDecimal userRating;
|
||||||
|
private Integer ratingCount;
|
||||||
|
private Integer reviewScore;
|
||||||
|
private Integer positiveReviews;
|
||||||
|
private Integer negativeReviews;
|
||||||
|
private String supportedPlatforms;
|
||||||
|
private String gameEngine;
|
||||||
|
private String developerIds;
|
||||||
|
private String publisherIds;
|
||||||
|
private String genreIds;
|
||||||
|
private String tagIds;
|
||||||
|
private String headerImage;
|
||||||
|
private String capsuleImage;
|
||||||
|
private String website;
|
||||||
|
private Integer achievementsCount;
|
||||||
|
private Boolean controllerSupport;
|
||||||
|
private Boolean multiplayer;
|
||||||
|
private Boolean coOp;
|
||||||
|
private Boolean lobbies;
|
||||||
|
private String status;
|
||||||
|
private LocalDateTime createdAt;
|
||||||
|
private LocalDateTime updatedAt;
|
||||||
|
|
||||||
|
// 非数据库字段,用于返回API结果
|
||||||
|
@TableField(exist = false)
|
||||||
|
private String mainImage;
|
||||||
|
@TableField(exist = false)
|
||||||
|
private List<String> genres;
|
||||||
|
@TableField(exist = false)
|
||||||
|
private List<Screenshot> screenshots;
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package icu.sunway.ai_spring_example.Entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@TableName("game_genres")
|
||||||
|
public class GameGenre {
|
||||||
|
private Integer gameId;
|
||||||
|
private Integer genreId;
|
||||||
|
private LocalDateTime createdAt;
|
||||||
|
}
|
||||||
21
src/main/java/icu/sunway/ai_spring_example/Entity/Genre.java
Normal file
21
src/main/java/icu/sunway/ai_spring_example/Entity/Genre.java
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
package icu.sunway.ai_spring_example.Entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@TableName("genres")
|
||||||
|
public class Genre {
|
||||||
|
private Integer id;
|
||||||
|
private String name;
|
||||||
|
private String slug;
|
||||||
|
private String description;
|
||||||
|
private LocalDateTime createdAt;
|
||||||
|
private LocalDateTime updatedAt;
|
||||||
|
}
|
||||||
25
src/main/java/icu/sunway/ai_spring_example/Entity/Media.java
Normal file
25
src/main/java/icu/sunway/ai_spring_example/Entity/Media.java
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
package icu.sunway.ai_spring_example.Entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@TableName("media")
|
||||||
|
public class Media {
|
||||||
|
private Integer id;
|
||||||
|
private Integer gameId;
|
||||||
|
private String mediaType;
|
||||||
|
private String mediaUrl;
|
||||||
|
private String thumbnailUrl;
|
||||||
|
private String description;
|
||||||
|
private Integer orderIndex;
|
||||||
|
private Boolean isPrimary;
|
||||||
|
private LocalDateTime createdAt;
|
||||||
|
private LocalDateTime updatedAt;
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package icu.sunway.ai_spring_example.Entity;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class Screenshot {
|
||||||
|
private Integer id;
|
||||||
|
private String mediaUrl;
|
||||||
|
private String thumbnailUrl;
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package icu.sunway.ai_spring_example.Mapper;
|
||||||
|
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import icu.sunway.ai_spring_example.Entity.GameGenre;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface GameGenreMapper extends BaseMapper<GameGenre> {
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package icu.sunway.ai_spring_example.Mapper;
|
||||||
|
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
|
||||||
|
import icu.sunway.ai_spring_example.Entity.Game;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface GameMapper extends BaseMapper<Game> {
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package icu.sunway.ai_spring_example.Mapper;
|
||||||
|
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import icu.sunway.ai_spring_example.Entity.Genre;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface GenreMapper extends BaseMapper<Genre> {
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package icu.sunway.ai_spring_example.Mapper;
|
||||||
|
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import icu.sunway.ai_spring_example.Entity.Media;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface MediaMapper extends BaseMapper<Media> {
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package icu.sunway.ai_spring_example.Service;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
|
||||||
|
import icu.sunway.ai_spring_example.Controllers.GameController.VO.GameVO;
|
||||||
|
import icu.sunway.ai_spring_example.Entity.Game;
|
||||||
|
import icu.sunway.ai_spring_example.Utils.PageUtils;
|
||||||
|
|
||||||
|
public interface IGameService extends IService<Game> {
|
||||||
|
|
||||||
|
// 获取游戏推荐列表
|
||||||
|
PageUtils.PaginationResult<GameVO> getRecommendedGames(Integer page, Integer limit);
|
||||||
|
}
|
||||||
@@ -0,0 +1,153 @@
|
|||||||
|
package icu.sunway.ai_spring_example.Service.Implements;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
|
||||||
|
import icu.sunway.ai_spring_example.Controllers.GameController.VO.GameVO;
|
||||||
|
import icu.sunway.ai_spring_example.Entity.Game;
|
||||||
|
import icu.sunway.ai_spring_example.Entity.GameGenre;
|
||||||
|
import icu.sunway.ai_spring_example.Entity.Genre;
|
||||||
|
import icu.sunway.ai_spring_example.Entity.Media;
|
||||||
|
import icu.sunway.ai_spring_example.Mapper.GameGenreMapper;
|
||||||
|
import icu.sunway.ai_spring_example.Mapper.GameMapper;
|
||||||
|
import icu.sunway.ai_spring_example.Mapper.GenreMapper;
|
||||||
|
import icu.sunway.ai_spring_example.Mapper.MediaMapper;
|
||||||
|
import icu.sunway.ai_spring_example.Service.IGameService;
|
||||||
|
import icu.sunway.ai_spring_example.Utils.PageUtils;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class GameServiceImpl extends ServiceImpl<GameMapper, Game>
|
||||||
|
implements IGameService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private GameMapper gameMapper;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private GameGenreMapper gameGenreMapper;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private GenreMapper genreMapper;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private MediaMapper mediaMapper;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PageUtils.PaginationResult<GameVO> getRecommendedGames(Integer page, Integer limit) {
|
||||||
|
// 使用分页工具类创建Page对象
|
||||||
|
Page<Game> gamePage = PageUtils.createPage(page, limit);
|
||||||
|
QueryWrapper<Game> queryWrapper = new QueryWrapper<>();
|
||||||
|
queryWrapper.orderByDesc("release_date");
|
||||||
|
|
||||||
|
// 获取游戏列表
|
||||||
|
Page<Game> pageResult = this.page(gamePage, queryWrapper);
|
||||||
|
List<Game> games = pageResult.getRecords();
|
||||||
|
|
||||||
|
if (games.isEmpty()) {
|
||||||
|
// 组装空结果返回
|
||||||
|
return PageUtils.createEmptyPaginationResult(page, limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取游戏ID列表
|
||||||
|
List<Integer> gameIds = games.stream()
|
||||||
|
.map(Game::getId)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
// 使用MyBatis Plus查询游戏类型
|
||||||
|
// 1. 查询游戏与类型的关联关系
|
||||||
|
QueryWrapper<GameGenre> gameGenreWrapper = new QueryWrapper<>();
|
||||||
|
gameGenreWrapper.in("game_id", gameIds);
|
||||||
|
List<GameGenre> gameGenres = gameGenreMapper.selectList(gameGenreWrapper);
|
||||||
|
|
||||||
|
// 2. 获取所有类型ID
|
||||||
|
List<Integer> genreIds = gameGenres.stream()
|
||||||
|
.map(GameGenre::getGenreId)
|
||||||
|
.distinct()
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
// 3. 查询类型信息
|
||||||
|
Map<Integer, String> genreMap = new HashMap<>();
|
||||||
|
if (!genreIds.isEmpty()) {
|
||||||
|
QueryWrapper<Genre> genreWrapper = new QueryWrapper<>();
|
||||||
|
genreWrapper.in("id", genreIds);
|
||||||
|
List<Genre> genres = genreMapper.selectList(genreWrapper);
|
||||||
|
genreMap = genres.stream()
|
||||||
|
.collect(Collectors.toMap(Genre::getId, Genre::getName));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 组装游戏类型映射
|
||||||
|
Map<Integer, List<String>> genresMap = new HashMap<>();
|
||||||
|
for (GameGenre gameGenre : gameGenres) {
|
||||||
|
Integer gameId = gameGenre.getGameId();
|
||||||
|
String genreName = genreMap.get(gameGenre.getGenreId());
|
||||||
|
if (genreName != null) {
|
||||||
|
genresMap.computeIfAbsent(gameId, k -> new ArrayList<>())
|
||||||
|
.add(genreName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用MyBatis Plus查询游戏主图
|
||||||
|
QueryWrapper<Media> mainImageWrapper = new QueryWrapper<>();
|
||||||
|
mainImageWrapper.in("game_id", gameIds)
|
||||||
|
.eq("is_primary", true)
|
||||||
|
.select("game_id", "media_url");
|
||||||
|
List<Media> mainImages = mediaMapper.selectList(mainImageWrapper);
|
||||||
|
Map<Integer, String> mainImagesMap = mainImages.stream()
|
||||||
|
.collect(Collectors.toMap(Media::getGameId, Media::getMediaUrl));
|
||||||
|
|
||||||
|
// 使用MyBatis Plus查询游戏截图列表
|
||||||
|
QueryWrapper<Media> screenshotWrapper = new QueryWrapper<>();
|
||||||
|
screenshotWrapper.in("game_id", gameIds)
|
||||||
|
.in("media_type", "screenshot", "image")
|
||||||
|
.orderByAsc("order_index")
|
||||||
|
.select("id", "game_id", "media_url", "thumbnail_url");
|
||||||
|
List<Media> screenshots = mediaMapper.selectList(screenshotWrapper);
|
||||||
|
|
||||||
|
// 组装游戏截图映射
|
||||||
|
Map<Integer, List<GameVO.ScreenshotVO>> screenshotsMap = new HashMap<>();
|
||||||
|
for (Media media : screenshots) {
|
||||||
|
Integer gameId = media.getGameId();
|
||||||
|
GameVO.ScreenshotVO screenshot = GameVO.ScreenshotVO.builder()
|
||||||
|
.mediaUrl(media.getMediaUrl())
|
||||||
|
.thumbnailUrl(media.getThumbnailUrl())
|
||||||
|
.build();
|
||||||
|
screenshotsMap.computeIfAbsent(gameId, k -> new ArrayList<>())
|
||||||
|
.add(screenshot);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将Game转换为GameVO
|
||||||
|
List<GameVO> gameVOs = games.stream()
|
||||||
|
.map(game -> {
|
||||||
|
Integer gameId = game.getId();
|
||||||
|
return GameVO.builder()
|
||||||
|
.name(game.getName())
|
||||||
|
.mainImage(mainImagesMap.getOrDefault(gameId, ""))
|
||||||
|
.supportedPlatforms(game.getSupportedPlatforms())
|
||||||
|
.genres(genresMap.getOrDefault(gameId, new ArrayList<String>()))
|
||||||
|
.price(game.getPrice())
|
||||||
|
.discountPercentage(game.getDiscountPercentage())
|
||||||
|
.releaseDate(game.getReleaseDate())
|
||||||
|
.screenshots(screenshotsMap.getOrDefault(gameId, new ArrayList<GameVO.ScreenshotVO>()))
|
||||||
|
.build();
|
||||||
|
})
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
// 创建新的Page结果
|
||||||
|
Page<GameVO> voPageResult = new Page<>();
|
||||||
|
voPageResult.setRecords(gameVOs);
|
||||||
|
voPageResult.setTotal(pageResult.getTotal());
|
||||||
|
voPageResult.setCurrent(pageResult.getCurrent());
|
||||||
|
voPageResult.setSize(pageResult.getSize());
|
||||||
|
voPageResult.setPages(pageResult.getPages());
|
||||||
|
|
||||||
|
// 组装分页结果并返回
|
||||||
|
return PageUtils.createPaginationResult(voPageResult);
|
||||||
|
}
|
||||||
|
}
|
||||||
111
src/main/java/icu/sunway/ai_spring_example/Utils/PageUtils.java
Normal file
111
src/main/java/icu/sunway/ai_spring_example/Utils/PageUtils.java
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
package icu.sunway.ai_spring_example.Utils;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页工具类
|
||||||
|
*/
|
||||||
|
public class PageUtils {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 默认页码
|
||||||
|
*/
|
||||||
|
public static final Integer DEFAULT_PAGE = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 默认每页数量
|
||||||
|
*/
|
||||||
|
public static final Integer DEFAULT_LIMIT = 10;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 最大每页数量
|
||||||
|
*/
|
||||||
|
public static final Integer MAX_LIMIT = 100;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页结果类
|
||||||
|
*
|
||||||
|
* @param <T> 数据类型
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
public static class PaginationResult<T> {
|
||||||
|
private Integer currentPage;
|
||||||
|
private Integer pageSize;
|
||||||
|
private Long totalItems;
|
||||||
|
private Integer totalPages;
|
||||||
|
private List<T> list;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证和调整分页参数
|
||||||
|
*
|
||||||
|
* @param page 页码
|
||||||
|
* @param limit 每页数量
|
||||||
|
* @return 调整后的分页参数数组 [page, limit]
|
||||||
|
*/
|
||||||
|
public static Integer[] validatePageParams(Integer page, Integer limit) {
|
||||||
|
// 验证页码
|
||||||
|
if (page == null || page < 1) {
|
||||||
|
page = DEFAULT_PAGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证每页数量
|
||||||
|
if (limit == null || limit < 1 || limit > MAX_LIMIT) {
|
||||||
|
limit = DEFAULT_LIMIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Integer[] { page, limit };
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建Page对象
|
||||||
|
*
|
||||||
|
* @param page 页码
|
||||||
|
* @param limit 每页数量
|
||||||
|
* @return Page对象
|
||||||
|
*/
|
||||||
|
public static <T> Page<T> createPage(Integer page, Integer limit) {
|
||||||
|
Integer[] params = validatePageParams(page, limit);
|
||||||
|
return new Page<>(params[0], params[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将MyBatis Plus的Page结果转换为分页结果
|
||||||
|
*
|
||||||
|
* @param pageResult MyBatis Plus的Page结果
|
||||||
|
* @return 分页结果
|
||||||
|
*/
|
||||||
|
public static <T> PaginationResult<T> createPaginationResult(IPage<T> pageResult) {
|
||||||
|
return new PaginationResult<>(
|
||||||
|
(int) pageResult.getCurrent(),
|
||||||
|
(int) pageResult.getSize(),
|
||||||
|
pageResult.getTotal(),
|
||||||
|
(int) pageResult.getPages(),
|
||||||
|
pageResult.getRecords());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建空的分页结果
|
||||||
|
*
|
||||||
|
* @param page 页码
|
||||||
|
* @param limit 每页数量
|
||||||
|
* @return 空的分页结果
|
||||||
|
*/
|
||||||
|
public static <T> PaginationResult<T> createEmptyPaginationResult(Integer page, Integer limit) {
|
||||||
|
Integer[] params = validatePageParams(page, limit);
|
||||||
|
return new PaginationResult<>(
|
||||||
|
params[0],
|
||||||
|
params[1],
|
||||||
|
0L,
|
||||||
|
0,
|
||||||
|
List.of());
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user