feat(puzzle): 添加模板分页查询功能并优化DTO序列化

- 在PuzzleTemplateController中新增pageTemplates接口支持分页查询
- 为ElementCreateRequest和PuzzleElementDTO添加@JsonProperty注解优化JSON序列化
- 实现PuzzleTemplateServiceImpl中的pageTemplates分页逻辑
- 使用PageHelper实现分页查询并限制最大页面大小为100
- 在IPuzzleTemplateService接口中定义pageTemplates方法签名及文档说明
- 添加参数校验确保page和pageSize的有效性
- 返回PageResponse对象封装分页结果供前端使用
This commit is contained in:
2025-11-18 12:05:21 +08:00
parent bb2367c5a6
commit af60e95529
5 changed files with 99 additions and 0 deletions

View File

@@ -1,5 +1,6 @@
package com.ycwl.basic.puzzle.controller; package com.ycwl.basic.puzzle.controller;
import com.ycwl.basic.integration.common.response.PageResponse;
import com.ycwl.basic.puzzle.dto.ElementCreateRequest; import com.ycwl.basic.puzzle.dto.ElementCreateRequest;
import com.ycwl.basic.puzzle.dto.PuzzleElementDTO; import com.ycwl.basic.puzzle.dto.PuzzleElementDTO;
import com.ycwl.basic.puzzle.dto.PuzzleTemplateDTO; import com.ycwl.basic.puzzle.dto.PuzzleTemplateDTO;
@@ -80,6 +81,22 @@ public class PuzzleTemplateController {
return ApiResponse.success(templates); return ApiResponse.success(templates);
} }
/**
* 分页获取模板列表
*/
@GetMapping("/templates/page")
public ApiResponse<PageResponse<PuzzleTemplateDTO>> pageTemplates(
@RequestParam(defaultValue = "1") Integer page,
@RequestParam(defaultValue = "10") Integer pageSize,
@RequestParam(required = false) Long scenicId,
@RequestParam(required = false) String category,
@RequestParam(required = false) Integer status) {
log.debug("分页查询模板列表: page={}, pageSize={}, scenicId={}, category={}, status={}",
page, pageSize, scenicId, category, status);
PageResponse<PuzzleTemplateDTO> templates = templateService.pageTemplates(page, pageSize, scenicId, category, status);
return ApiResponse.success(templates);
}
/** /**
* 为模板添加单个元素 * 为模板添加单个元素
*/ */

View File

@@ -1,5 +1,6 @@
package com.ycwl.basic.puzzle.dto; package com.ycwl.basic.puzzle.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data; import lombok.Data;
import java.util.Map; import java.util.Map;
@@ -22,21 +23,25 @@ public class ElementCreateRequest {
/** /**
* 模板ID * 模板ID
*/ */
@JsonProperty("templateId")
private Long templateId; private Long templateId;
/** /**
* 元素类型(TEXT-文字 IMAGE-图片 QRCODE-二维码等) * 元素类型(TEXT-文字 IMAGE-图片 QRCODE-二维码等)
*/ */
@JsonProperty("elementType")
private String elementType; private String elementType;
/** /**
* 元素标识(用于动态数据映射) * 元素标识(用于动态数据映射)
*/ */
@JsonProperty("elementKey")
private String elementKey; private String elementKey;
/** /**
* 元素名称(便于管理识别) * 元素名称(便于管理识别)
*/ */
@JsonProperty("elementName")
private String elementName; private String elementName;
// ===== 位置和布局属性(所有元素通用) ===== // ===== 位置和布局属性(所有元素通用) =====
@@ -44,36 +49,43 @@ public class ElementCreateRequest {
/** /**
* X坐标(相对于画布左上角,像素) * X坐标(相对于画布左上角,像素)
*/ */
@JsonProperty("xPosition")
private Integer xPosition; private Integer xPosition;
/** /**
* Y坐标(相对于画布左上角,像素) * Y坐标(相对于画布左上角,像素)
*/ */
@JsonProperty("yPosition")
private Integer yPosition; private Integer yPosition;
/** /**
* 宽度(像素) * 宽度(像素)
*/ */
@JsonProperty("width")
private Integer width; private Integer width;
/** /**
* 高度(像素) * 高度(像素)
*/ */
@JsonProperty("height")
private Integer height; private Integer height;
/** /**
* 层级(数值越大越靠上) * 层级(数值越大越靠上)
*/ */
@JsonProperty("zIndex")
private Integer zIndex; private Integer zIndex;
/** /**
* 旋转角度(0-360度,顺时针) * 旋转角度(0-360度,顺时针)
*/ */
@JsonProperty("rotation")
private Integer rotation; private Integer rotation;
/** /**
* 不透明度(0-100,100为完全不透明) * 不透明度(0-100,100为完全不透明)
*/ */
@JsonProperty("opacity")
private Integer opacity; private Integer opacity;
// ===== JSON配置(二选一) ===== // ===== JSON配置(二选一) =====
@@ -85,6 +97,7 @@ public class ElementCreateRequest {
* - 文字元素:"{\"defaultText\":\"用户名\", \"fontFamily\":\"微软雅黑\", \"fontSize\":14}" * - 文字元素:"{\"defaultText\":\"用户名\", \"fontFamily\":\"微软雅黑\", \"fontSize\":14}"
* - 图片元素:"{\"defaultImageUrl\":\"https://...\", \"imageFitMode\":\"COVER\", \"borderRadius\":10}" * - 图片元素:"{\"defaultImageUrl\":\"https://...\", \"imageFitMode\":\"COVER\", \"borderRadius\":10}"
*/ */
@JsonProperty("config")
private String config; private String config;
/** /**
@@ -96,5 +109,6 @@ public class ElementCreateRequest {
* configMap.put("fontSize", 14); * configMap.put("fontSize", 14);
* request.setConfigMap(configMap); * request.setConfigMap(configMap);
*/ */
@JsonProperty("configMap")
private Map<String, Object> configMap; private Map<String, Object> configMap;
} }

View File

@@ -1,5 +1,6 @@
package com.ycwl.basic.puzzle.dto; package com.ycwl.basic.puzzle.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data; import lombok.Data;
import java.util.Map; import java.util.Map;
@@ -21,26 +22,31 @@ public class PuzzleElementDTO {
/** /**
* 元素ID * 元素ID
*/ */
@JsonProperty("id")
private Long id; private Long id;
/** /**
* 模板ID * 模板ID
*/ */
@JsonProperty("templateId")
private Long templateId; private Long templateId;
/** /**
* 元素类型(TEXT-文字 IMAGE-图片 QRCODE-二维码等) * 元素类型(TEXT-文字 IMAGE-图片 QRCODE-二维码等)
*/ */
@JsonProperty("elementType")
private String elementType; private String elementType;
/** /**
* 元素标识(用于动态数据映射) * 元素标识(用于动态数据映射)
*/ */
@JsonProperty("elementKey")
private String elementKey; private String elementKey;
/** /**
* 元素名称(便于管理识别) * 元素名称(便于管理识别)
*/ */
@JsonProperty("elementName")
private String elementName; private String elementName;
// ===== 位置和布局属性(所有元素通用) ===== // ===== 位置和布局属性(所有元素通用) =====
@@ -48,36 +54,43 @@ public class PuzzleElementDTO {
/** /**
* X坐标(相对于画布左上角,像素) * X坐标(相对于画布左上角,像素)
*/ */
@JsonProperty("xPosition")
private Integer xPosition; private Integer xPosition;
/** /**
* Y坐标(相对于画布左上角,像素) * Y坐标(相对于画布左上角,像素)
*/ */
@JsonProperty("yPosition")
private Integer yPosition; private Integer yPosition;
/** /**
* 宽度(像素) * 宽度(像素)
*/ */
@JsonProperty("width")
private Integer width; private Integer width;
/** /**
* 高度(像素) * 高度(像素)
*/ */
@JsonProperty("height")
private Integer height; private Integer height;
/** /**
* 层级(数值越大越靠上) * 层级(数值越大越靠上)
*/ */
@JsonProperty("zIndex")
private Integer zIndex; private Integer zIndex;
/** /**
* 旋转角度(0-360度,顺时针) * 旋转角度(0-360度,顺时针)
*/ */
@JsonProperty("rotation")
private Integer rotation; private Integer rotation;
/** /**
* 不透明度(0-100,100为完全不透明) * 不透明度(0-100,100为完全不透明)
*/ */
@JsonProperty("opacity")
private Integer opacity; private Integer opacity;
// ===== JSON配置 ===== // ===== JSON配置 =====
@@ -85,10 +98,12 @@ public class PuzzleElementDTO {
/** /**
* JSON配置字符串 * JSON配置字符串
*/ */
@JsonProperty("config")
private String config; private String config;
/** /**
* JSON配置Map(方便前端使用) * JSON配置Map(方便前端使用)
*/ */
@JsonProperty("configMap")
private Map<String, Object> configMap; private Map<String, Object> configMap;
} }

View File

@@ -1,5 +1,6 @@
package com.ycwl.basic.puzzle.service; package com.ycwl.basic.puzzle.service;
import com.ycwl.basic.integration.common.response.PageResponse;
import com.ycwl.basic.puzzle.dto.ElementCreateRequest; import com.ycwl.basic.puzzle.dto.ElementCreateRequest;
import com.ycwl.basic.puzzle.dto.PuzzleElementDTO; import com.ycwl.basic.puzzle.dto.PuzzleElementDTO;
import com.ycwl.basic.puzzle.dto.PuzzleTemplateDTO; import com.ycwl.basic.puzzle.dto.PuzzleTemplateDTO;
@@ -45,6 +46,19 @@ public interface IPuzzleTemplateService {
*/ */
List<PuzzleTemplateDTO> listTemplates(Long scenicId, String category, Integer status); List<PuzzleTemplateDTO> listTemplates(Long scenicId, String category, Integer status);
/**
* 分页获取模板列表
*
* @param page 页码(从1开始)
* @param pageSize 每页大小
* @param scenicId 景区ID(可选)
* @param category 模板分类(可选)
* @param status 状态(可选): 0-禁用 1-启用
* @return 分页结果
*/
PageResponse<PuzzleTemplateDTO> pageTemplates(Integer page, Integer pageSize,
Long scenicId, String category, Integer status);
/** /**
* 为模板添加元素 * 为模板添加元素
*/ */

View File

@@ -3,6 +3,7 @@ import cn.hutool.core.util.StrUtil;
import com.ycwl.basic.puzzle.util.ElementConfigHelper; import com.ycwl.basic.puzzle.util.ElementConfigHelper;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.BeanUtil;
import com.ycwl.basic.integration.common.response.PageResponse;
import com.ycwl.basic.puzzle.dto.ElementCreateRequest; import com.ycwl.basic.puzzle.dto.ElementCreateRequest;
import com.ycwl.basic.puzzle.dto.PuzzleElementDTO; import com.ycwl.basic.puzzle.dto.PuzzleElementDTO;
import com.ycwl.basic.puzzle.dto.PuzzleTemplateDTO; import com.ycwl.basic.puzzle.dto.PuzzleTemplateDTO;
@@ -134,6 +135,44 @@ public class PuzzleTemplateServiceImpl implements IPuzzleTemplateService {
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
@Override
public PageResponse<PuzzleTemplateDTO> pageTemplates(Integer page, Integer pageSize,
Long scenicId, String category, Integer status) {
log.debug("分页查询拼图模板: page={}, pageSize={}, scenicId={}, category={}, status={}",
page, pageSize, scenicId, category, status);
// 参数校验
if (page == null || page < 1) {
page = 1;
}
if (pageSize == null || pageSize < 1) {
pageSize = 10;
}
if (pageSize > 100) {
pageSize = 100; // 限制最大页面大小
}
// 使用PageHelper进行分页
com.github.pagehelper.Page<PuzzleTemplateEntity> pageResult =
com.github.pagehelper.PageHelper.startPage(page, pageSize)
.doSelectPage(() -> templateMapper.list(scenicId, category, status));
// 转换为DTO
List<PuzzleTemplateDTO> dtoList = pageResult.getResult().stream()
.map(this::convertToDTO)
.collect(Collectors.toList());
// 构建分页响应
PageResponse<PuzzleTemplateDTO> response = new PageResponse<>();
response.setList(dtoList);
response.setTotal((int) pageResult.getTotal());
response.setPage(page);
response.setPageSize(pageSize);
log.debug("分页查询完成: total={}, currentSize={}", pageResult.getTotal(), dtoList.size());
return response;
}
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public Long addElement(ElementCreateRequest request) { public Long addElement(ElementCreateRequest request) {