feat :组件分类

This commit is contained in:
lizhengwei 2026-03-10 22:59:08 +08:00
parent 5b7a447fd6
commit d0e5c81582
13 changed files with 433 additions and 54 deletions

View File

@ -0,0 +1,80 @@
### H5 组件分类管理接口测试
### 1. 分页查询分类(查询一级分类)
GET {{baseUrl}}/h5/category/page?pageNum=1&pageSize=10
Content-Type: application/json
### 2. 分页查询分类(查询指定父分类的子分类)
GET {{baseUrl}}/h5/category/page?pageNum=1&pageSize=10&parentId=1
Content-Type: application/json
### 3. 分页查询分类(带类型过滤)
GET {{baseUrl}}/h5/category/page?pageNum=1&pageSize=10&type=text
Content-Type: application/json
### 4. 分页查询分类(带关键词搜索)
GET {{baseUrl}}/h5/category/page?pageNum=1&pageSize=10&keyword=文字
Content-Type: application/json
### 5. 根据类型查询分类
GET {{baseUrl}}/h5/category/by-type?type=text
Content-Type: application/json
### 6. 获取分类树形结构
GET {{baseUrl}}/h5/category/tree
Content-Type: application/json
### 7. 创建分类(一级分类)
POST {{baseUrl}}/h5/category
Content-Type: application/json
{
"parentId": 0,
"name": "测试分类",
"type": "text",
"sort": 100,
"icon": "https://example.com/icon.png",
"description": "这是一个测试分类",
"isSystem": 0
}
### 8. 创建分类(二级分类)
POST {{baseUrl}}/h5/category
Content-Type: application/json
{
"parentId": 1,
"name": "测试子分类",
"type": "text",
"sort": 1,
"description": "这是一个测试子分类",
"isSystem": 0
}
### 9. 更新分类
POST {{baseUrl}}/h5/category/update/1
Content-Type: application/json
{
"id": 1,
"parentId": 0,
"name": "更新后的分类名称",
"type": "text",
"sort": 100,
"icon": "https://example.com/new-icon.png",
"description": "更新后的分类描述",
"isSystem": 0
}
### 10. 删除分类
POST {{baseUrl}}/h5/category/delete/1
Content-Type: application/json
### 11. 查询所有一级分类(旧接口,保留兼容)
GET {{baseUrl}}/h5/category/top-level
Content-Type: application/json
### 12. 根据父分类 ID 查询子分类(旧接口,保留兼容)
GET {{baseUrl}}/h5/category/children?parentId=1
Content-Type: application/json

View File

@ -0,0 +1,89 @@
### H5 组件管理接口测试
### 1. 根据 ID 查询组件
GET {{baseUrl}}/h5/component/1
Content-Type: application/json
### 2. 分页查询组件列表(不带筛选条件)
GET {{baseUrl}}/h5/component/page?page=1&pageSize=10
Content-Type: application/json
### 3. 分页查询组件列表(按类型筛选)
GET {{baseUrl}}/h5/component/page?page=1&pageSize=10&type=text
Content-Type: application/json
### 4. 分页查询组件列表(关键词搜索)
GET {{baseUrl}}/h5/component/page?page=1&pageSize=10&keyword=标题
Content-Type: application/json
### 5. 分页查询组件列表(按分类筛选)
GET {{baseUrl}}/h5/component/page?page=1&pageSize=10&categoryId=1
Content-Type: application/json
### 6. 分页查询组件列表(按标签筛选)
GET {{baseUrl}}/h5/component/page?page=1&pageSize=10&tagId=1
Content-Type: application/json
### 7. 分页查询组件列表(组合筛选)
GET {{baseUrl}}/h5/component/page?page=1&pageSize=10&type=image&keyword=产品&categoryId=2
Content-Type: application/json
### 8. 创建组件
POST {{baseUrl}}/h5/component
Content-Type: application/json
{
"name": "测试组件",
"type": "text",
"thumbnailUrl": "https://example.com/thumb.jpg",
"previewUrl": "https://example.com/preview.jpg",
"content": "{\"version\":\"1.0\",\"data\":{\"text\":\"测试文本\"}}",
"remark": "这是一个测试组件",
"isPremium": 0,
"isSystem": 0,
"status": 1
}
### 9. 更新组件
POST {{baseUrl}}/h5/component/update/1
Content-Type: application/json
{
"id": 1,
"name": "更新后的组件名称",
"type": "text",
"thumbnailUrl": "https://example.com/new-thumb.jpg",
"previewUrl": "https://example.com/new-preview.jpg",
"content": "{\"version\":\"1.1\",\"data\":{\"text\":\"更新的文本\"}}",
"remark": "更新后的备注说明",
"isPremium": 0,
"isSystem": 0,
"status": 1
}
### 10. 删除组件
POST {{baseUrl}}/h5/component/delete/1
Content-Type: application/json
### 11. 批量删除组件
POST {{baseUrl}}/h5/component/batch
Content-Type: application/json
[1, 2, 3]
### 12. 增加使用次数
POST {{baseUrl}}/h5/component/1/usage
Content-Type: application/json
### 13. 增加点赞数
POST {{baseUrl}}/h5/component/1/like
Content-Type: application/json
### 14. 获取热门组件(默认类型)
GET {{baseUrl}}/h5/component/hot?limit=10
Content-Type: application/json
### 15. 获取热门组件(指定类型)
GET {{baseUrl}}/h5/component/hot?type=text&limit=5
Content-Type: application/json

View File

@ -0,0 +1,39 @@
### H5 分组管理接口测试
### 1. 根据 ID 查询分组
GET {{baseUrl}}/h5/group/1
Content-Type: application/json
### 2. 分页查询分组列表(按用户 ID 筛选)
GET {{baseUrl}}/h5/group/page?page=1&pageSize=10&userId=1
Content-Type: application/json
### 3. 分页查询分组列表(带关键词搜索)
GET {{baseUrl}}/h5/group/page?page=1&pageSize=10&keyword=我的分组
Content-Type: application/json
### 4. 创建分组
POST {{baseUrl}}/h5/group
Content-Type: application/json
{
"name": "默认分组",
"userId": 1,
"sort": 1
}
### 5. 更新分组
POST {{baseUrl}}/h5/group/update/1
Content-Type: application/json
{
"id": 1,
"name": "更新后的分组名称",
"userId": 1,
"sort": 2
}
### 6. 删除分组
POST {{baseUrl}}/h5/group/delete/1
Content-Type: application/json

View File

@ -1,5 +1,8 @@
{
"dev": {
"host": "http://localhost:19200"
"baseUrl": "http://localhost:19200"
},
"prod": {
"baseUrl": "https://api.example.com"
}
}

View File

@ -0,0 +1,49 @@
### H5 项目管理接口测试
### 1. 根据 ID 查询项目
GET {{baseUrl}}/h5/project/1
Content-Type: application/json
### 2. 分页查询项目列表(按用户 ID 筛选)
GET {{baseUrl}}/h5/project/page?page=1&pageSize=10&userId=1
Content-Type: application/json
### 3. 分页查询项目列表(带关键词搜索)
GET {{baseUrl}}/h5/project/page?page=1&pageSize=10&keyword=我的作品
Content-Type: application/json
### 4. 创建项目
POST {{baseUrl}}/h5/project
Content-Type: application/json
{
"name": "我的 H5 作品",
"description": "这是一个 H5 作品描述",
"coverUrl": "https://example.com/cover.jpg",
"remark": "备注信息"
}
### 5. 更新项目
POST {{baseUrl}}/h5/project/update/1
Content-Type: application/json
{
"id": 1,
"name": "更新后的作品名称",
"description": "更新后的作品描述",
"coverUrl": "https://example.com/new-cover.jpg",
"remark": "更新后的备注信息"
}
### 6. 更新项目状态
POST {{baseUrl}}/h5/project/updateStatus?id=1
Content-Type: application/json
{
"status": 2
}
### 7. 删除项目
POST {{baseUrl}}/h5/project/delete/1
Content-Type: application/json

View File

@ -0,0 +1,43 @@
### H5 标签管理接口测试
### 1. 分页查询标签列表(不带筛选条件)
GET {{baseUrl}}/h5/tag/page?page=1&pageSize=10
Content-Type: application/json
### 2. 分页查询标签列表(关键词搜索)
GET {{baseUrl}}/h5/tag/page?page=1&pageSize=10&keyword=热门
Content-Type: application/json
### 3. 根据 ID 查询标签
GET {{baseUrl}}/h5/tag/1
Content-Type: application/json
### 4. 创建标签
POST {{baseUrl}}/h5/tag
Content-Type: application/json
{
"name": "热门标签",
"color": "#FF5722"
}
### 5. 更新标签
POST {{baseUrl}}/h5/tag/update/1
Content-Type: application/json
{
"id": 1,
"name": "更新后的标签名称",
"color": "#4CAF50"
}
### 6. 删除标签
POST {{baseUrl}}/h5/tag/delete/1
Content-Type: application/json
### 7. 批量删除标签
POST {{baseUrl}}/h5/tag/batch
Content-Type: application/json
[1, 2, 3]

View File

@ -1,14 +1,13 @@
package com.luban.api.config;
import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor;
import org.dromara.common.mybatis.config.MybatisPlusConfig;
import org.dromara.common.tenant.properties.TenantProperties;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@ConditionalOnProperty(prefix = "tenant", value = "enabled", havingValue = "true")
public class MybatisPlusAutoConfigTenant {
@Bean

View File

@ -1,9 +1,9 @@
package com.luban.api.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.luban.api.dto.H5ComponentCategoryQueryDTO;
import com.luban.api.entity.H5ComponentCategory;
import com.luban.api.service.H5ComponentCategoryService;
import com.luban.api.vo.H5ComponentCategoryPageVO;
import com.luban.api.vo.H5ComponentCategoryTreeVO;
import com.luban.api.vo.Result;
import io.swagger.v3.oas.annotations.Operation;
@ -31,18 +31,17 @@ public class H5ComponentCategoryController {
@Operation(summary = "分页查询分类", description = "支持查询一级分类和子分类。不传 parentId 时查询一级分类,传入 parentId 时查询对应子分类")
@GetMapping("/page")
public Result<H5ComponentCategoryPageVO> pageCategories(
@Parameter(description = "查询参数") @ModelAttribute H5ComponentCategoryQueryDTO queryDTO) {
H5ComponentCategoryPageVO result = h5ComponentCategoryService.pageCategories(queryDTO);
public Result<Page<H5ComponentCategory>> pageCategories(
@Parameter(description = "查询参数") @ModelAttribute H5ComponentCategoryQueryDTO queryDTO) {
Page<H5ComponentCategory> result = h5ComponentCategoryService.pageCategories(queryDTO);
return new Result<>(result);
}
@Operation(summary = "根据类型查询分类")
@GetMapping("/by-type")
public Result<List<H5ComponentCategory>> getCategoriesByType(
@Parameter(description = "组件类型", required = true) @RequestParam String type) {
@Parameter(description = "组件类型", required = true) @RequestParam String type) {
List<H5ComponentCategory> result = h5ComponentCategoryService.getCategoriesByType(type);
return new Result<>(result);
}
@ -57,8 +56,8 @@ public class H5ComponentCategoryController {
@Operation(summary = "创建分类")
@PostMapping
public Result<Long> create(
@Parameter(description = "分类信息", required = true) @RequestBody @Validated H5ComponentCategory category) {
@Parameter(description = "分类信息", required = true) @RequestBody @Validated H5ComponentCategory category) {
Long id = h5ComponentCategoryService.create(category);
return new Result<>(id);
}
@ -66,9 +65,9 @@ public class H5ComponentCategoryController {
@Operation(summary = "更新分类")
@PostMapping("/update/{id}")
public Result<Void> update(
@Parameter(description = "分类 ID", required = true) @PathVariable Long id,
@Parameter(description = "分类信息", required = true) @RequestBody @Validated H5ComponentCategory category) {
@Parameter(description = "分类 ID", required = true) @PathVariable Long id,
@Parameter(description = "分类信息", required = true) @RequestBody @Validated H5ComponentCategory category) {
category.setId(id);
h5ComponentCategoryService.update(category);
return new Result<>();
@ -77,7 +76,7 @@ public class H5ComponentCategoryController {
@Operation(summary = "删除分类")
@PostMapping("/delete/{id}")
public Result<Void> deleteById(
@Parameter(description = "分类 ID", required = true) @PathVariable Long id) {
@Parameter(description = "分类 ID", required = true) @PathVariable Long id) {
h5ComponentCategoryService.deleteById(id);
return new Result<>();
}

View File

@ -0,0 +1,38 @@
package com.luban.api.dto;
import lombok.Data;
/**
* H5 组件分类查询 DTO
*
* @author system
* @since 2026-03-06
*/
@Data
public class H5ComponentCategoryQueryDTO {
/**
* 页码
*/
private Integer pageNum = 1;
/**
* 每页大小
*/
private Integer pageSize = 10;
/**
* 父分类 ID不传或为 0 时查询一级分类
*/
private Long parentId;
/**
* 分类类型
*/
private String type;
/**
* 搜索关键词
*/
private String keyword;
}

View File

@ -1,8 +1,8 @@
package com.luban.api.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.luban.api.dto.H5ComponentCategoryQueryDTO;
import com.luban.api.entity.H5ComponentCategory;
import com.luban.api.vo.H5ComponentCategoryPageVO;
import com.luban.api.vo.H5ComponentCategoryTreeVO;
import java.util.List;
@ -73,5 +73,5 @@ public interface H5ComponentCategoryService {
* @param queryDTO 查询参数
* @return 分页查询结果
*/
H5ComponentCategoryPageVO pageCategories(H5ComponentCategoryQueryDTO queryDTO);
Page<H5ComponentCategory> pageCategories(H5ComponentCategoryQueryDTO queryDTO);
}

View File

@ -7,7 +7,6 @@ import com.luban.api.dao.H5ComponentCategoryDao;
import com.luban.api.dto.H5ComponentCategoryQueryDTO;
import com.luban.api.entity.H5ComponentCategory;
import com.luban.api.service.H5ComponentCategoryService;
import com.luban.api.vo.H5ComponentCategoryPageVO;
import com.luban.api.vo.H5ComponentCategoryTreeVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@ -37,7 +36,7 @@ public class H5ComponentCategoryServiceImpl extends ServiceImpl<H5ComponentCateg
public List<H5ComponentCategory> getTopLevelCategories() {
LambdaQueryWrapper<H5ComponentCategory> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(H5ComponentCategory::getParentId, 0L)
.orderByAsc(H5ComponentCategory::getSort);
.orderByAsc(H5ComponentCategory::getSort);
return baseMapper.selectList(wrapper);
}
@ -46,7 +45,7 @@ public class H5ComponentCategoryServiceImpl extends ServiceImpl<H5ComponentCateg
public List<H5ComponentCategory> getChildCategories(Long parentId) {
LambdaQueryWrapper<H5ComponentCategory> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(H5ComponentCategory::getParentId, parentId)
.orderByAsc(H5ComponentCategory::getSort);
.orderByAsc(H5ComponentCategory::getSort);
return baseMapper.selectList(wrapper);
}
@ -55,8 +54,8 @@ public class H5ComponentCategoryServiceImpl extends ServiceImpl<H5ComponentCateg
public List<H5ComponentCategory> getCategoriesByType(String type) {
LambdaQueryWrapper<H5ComponentCategory> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(H5ComponentCategory::getType, type)
.orderByAsc(H5ComponentCategory::getParentId)
.orderByAsc(H5ComponentCategory::getSort);
.orderByAsc(H5ComponentCategory::getParentId)
.orderByAsc(H5ComponentCategory::getSort);
return baseMapper.selectList(wrapper);
}
@ -107,8 +106,8 @@ public class H5ComponentCategoryServiceImpl extends ServiceImpl<H5ComponentCateg
// 转换为 VO
List<H5ComponentCategoryTreeVO> allVOs = allCategories.stream()
.map(this::convertToTreeVO)
.toList();
.map(this::convertToTreeVO)
.toList();
// 构建树形结构
return buildTree(allVOs);
@ -125,10 +124,10 @@ public class H5ComponentCategoryServiceImpl extends ServiceImpl<H5ComponentCateg
// 使用 Map 提高查找效率
Map<Long, H5ComponentCategoryTreeVO> nodeMap = allNodes.stream()
.collect(Collectors.toMap(
H5ComponentCategoryTreeVO::getId,
vo -> vo
));
.collect(Collectors.toMap(
H5ComponentCategoryTreeVO::getId,
vo -> vo
));
// 遍历所有节点构建父子关系
for (H5ComponentCategoryTreeVO node : allNodes) {
@ -157,7 +156,7 @@ public class H5ComponentCategoryServiceImpl extends ServiceImpl<H5ComponentCateg
}
@Override
public H5ComponentCategoryPageVO pageCategories(H5ComponentCategoryQueryDTO queryDTO) {
public Page<H5ComponentCategory> pageCategories(H5ComponentCategoryQueryDTO queryDTO) {
// 构建查询条件
LambdaQueryWrapper<H5ComponentCategory> wrapper = new LambdaQueryWrapper<>();
@ -168,32 +167,18 @@ public class H5ComponentCategoryServiceImpl extends ServiceImpl<H5ComponentCateg
// 否则查询指定 parentId 的子分类
wrapper.eq(H5ComponentCategory::getParentId, queryDTO.getParentId());
}
// 类型过滤
wrapper.eq(queryDTO.getType() != null && !queryDTO.getType().isBlank(),H5ComponentCategory::getType, queryDTO.getType())
.like(queryDTO.getName() != null && !queryDTO.getName().isBlank(),H5ComponentCategory::getName, queryDTO.getName());
if (queryDTO.getType() != null && !queryDTO.getType().isBlank()) {
wrapper.eq(H5ComponentCategory::getType, queryDTO.getType());
}
// 关键词搜索
if (queryDTO.getKeyword() != null && !queryDTO.getKeyword().isBlank()) {
wrapper.like(H5ComponentCategory::getName, queryDTO.getKeyword());
}
// 排序
wrapper.orderByAsc(H5ComponentCategory::getSort);
// 分页参数
int pageNum = queryDTO.getPage() != null ? queryDTO.getPage() : 1;
int pageSize = queryDTO.getSize() != null ? queryDTO.getSize() : 10;
// 执行分页查询
Page<H5ComponentCategory> page = new Page<>(pageNum, pageSize);
Page<H5ComponentCategory> resultPage = baseMapper.selectPage(page, wrapper);
// 构建返回结果
H5ComponentCategoryPageVO pageVO = new H5ComponentCategoryPageVO();
pageVO.setList(resultPage.getRecords());
pageVO.setTotal(resultPage.getTotal());
pageVO.setPageNum((int) resultPage.getCurrent());
pageVO.setPageSize((int) resultPage.getSize());
pageVO.setHasPrevious(resultPage.getCurrent() > 1);
pageVO.setHasNext(resultPage.getCurrent() < resultPage.getPages());
return pageVO;
return baseMapper.selectPage(new Page<>(queryDTO.getPageNum(), queryDTO.getPageSize()), wrapper);
}
}

View File

@ -0,0 +1,54 @@
package com.luban.api.vo;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.Data;
import java.util.List;
/**
* H5 组件分类分页查询结果 VO
*
* @author system
* @since 2026-03-06
*/
@Data
public class H5ComponentCategoryPageVO {
/**
* 分类列表
*/
private List<H5ComponentCategoryTreeVO> list;
/**
* 总记录数
*/
private Long total;
/**
* 当前页码
*/
private Integer pageNum;
/**
* 每页大小
*/
private Integer pageSize;
/**
* 总页数
*/
private Integer pages;
/**
* MyBatis-Plus Page 构建分页 VO
*/
public static H5ComponentCategoryPageVO from(Page<H5ComponentCategoryTreeVO> page) {
H5ComponentCategoryPageVO vo = new H5ComponentCategoryPageVO();
vo.setList(page.getRecords());
vo.setTotal(page.getTotal());
vo.setPageNum((int) page.getCurrent());
vo.setPageSize((int) page.getSize());
vo.setPages((int) ((page.getTotal() + page.getSize() - 1) / page.getSize()));
return vo;
}
}

View File

@ -57,6 +57,7 @@ tenant:
enable: true
# 排除表
excludes:
- h5_font
- h5_group
- h5_project_group
- h5_component_category