From 83438b76dd57972e357a763fa9c533624c3b0389 Mon Sep 17 00:00:00 2001 From: lizhengwei <171332584@qq.com> Date: Thu, 12 Mar 2026 23:17:54 +0800 Subject: [PATCH] =?UTF-8?q?feat=20:=E7=BB=84=E4=BB=B6=E5=88=86=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ruoyi-site/ruoyi-h5/README_COMPONENT.md | 194 ++++++++++++++++++ .../api/controller/H5ComponentController.java | 27 ++- .../luban/api/convert/H5ComponentConvert.java | 9 + .../com/luban/api/dao/H5ComponentDao.java | 10 + .../com/luban/api/dto/H5ComponentDTO.java | 107 ++++++++++ .../luban/api/dto/H5ComponentTopQueryDTO.java | 25 +++ .../com/luban/api/entity/H5Component.java | 4 +- .../luban/api/service/H5ComponentService.java | 23 ++- .../service/impl/H5ComponentServiceImpl.java | 89 +++++--- .../mapper/ruoyi-h5/H5ComponentDao.xml | 18 ++ 10 files changed, 459 insertions(+), 47 deletions(-) create mode 100644 ruoyi-site/ruoyi-h5/README_COMPONENT.md create mode 100644 ruoyi-site/ruoyi-h5/src/main/java/com/luban/api/dto/H5ComponentDTO.java create mode 100644 ruoyi-site/ruoyi-h5/src/main/java/com/luban/api/dto/H5ComponentTopQueryDTO.java create mode 100644 ruoyi-site/ruoyi-h5/src/main/resources/mapper/ruoyi-h5/H5ComponentDao.xml diff --git a/ruoyi-site/ruoyi-h5/README_COMPONENT.md b/ruoyi-site/ruoyi-h5/README_COMPONENT.md new file mode 100644 index 000000000..68d51478c --- /dev/null +++ b/ruoyi-site/ruoyi-h5/README_COMPONENT.md @@ -0,0 +1,194 @@ +# H5 组件库系统开发完成 + +## 开发时间 +2026-03-06 + +## 功能概述 +实现了一个完整的 H5 组件库系统,支持组件分类管理、标签检索、快速应用等功能。 + +## 已完成的功能 + +### 1. 数据库设计 (5 张表) +- **h5_component**: 组件表 - 存储组件基本信息和配置数据 +- **h5_component_category**: 分类表 - 存储两级分类结构 +- **h5_component_category_rel**: 组件分类关联表 - 组件与分类的多对多关系 +- **h5_tag**: 标签表 - 存储标签信息 +- **h5_component_tag_rel**: 组件标签关联表 - 组件与标签的多对多关系 + +### 2. 核心功能 + +#### 组件管理 +- ✅ 组件 CRUD 操作 +- ✅ 分页查询 (支持按类型、关键词、分类、标签筛选) +- ✅ 使用次数统计 +- ✅ 点赞数统计 +- ✅ 热门组件查询 +- ✅ 批量删除 + +#### 分类管理 +- ✅ 两级分类结构 (一级固定 5 大类:文字、图片、扩展、背景、音乐) +- ✅ 一级分类查询 +- ✅ 二级分类查询 (按父 ID) +- ✅ 按类型查询分类 +- ✅ 分类树形结构 +- ✅ 分类 CRUD 操作 + +#### 标签管理 +- ✅ 所有标签查询 +- ✅ 热门标签查询 +- ✅ 按类型查询标签 +- ✅ 标签 CRUD 操作 +- ✅ 标签使用次数统计 + +### 3. 技术实现 + +#### 分层架构 +``` +com.luban.api +├── controller # 控制器层 +│ ├── H5ComponentController +│ ├── H5ComponentCategoryController +│ └── H5TagController +├── service # 服务层接口 +│ ├── H5ComponentService +│ ├── H5ComponentCategoryService +│ └── H5TagService +├── service.impl # 服务层实现 +│ ├── H5ComponentServiceImpl +│ ├── H5ComponentCategoryServiceImpl +│ └── H5TagServiceImpl +├── dao # 数据访问层 +│ ├── H5ComponentDao +│ ├── H5ComponentCategoryDao +│ ├── H5TagDao +│ ├── H5ComponentCategoryRelDao +│ └── H5ComponentTagRelDao +├── entity # 实体类 +│ ├── H5Component +│ ├── H5ComponentCategory +│ ├── H5Tag +│ ├── H5ComponentCategoryRel +│ └── H5ComponentTagRel +├── vo # 视图对象 +│ ├── H5ComponentVO +│ └── Result +└── convert # 转换类 + └── H5ComponentConvert +``` + +#### 技术栈 +- Spring Boot 3 +- MyBatis-Plus (ORM 框架) +- Lombok (简化代码) +- MapStruct (对象转换) +- Swagger (API 文档) + +#### 代码规范 +- ✅ 使用 `@Data`、`@EqualsAndHashCode`、`@NoArgsConstructor`、`@AllArgsConstructor`进行 POJO 类定义 +- ✅ MyBatis-Plus映射添加`@TableName`和`@TableId`注解 +- ✅ 事务一致性保障 (`@Transactional` 注解) +- ✅ Controller 不直接调用 Repository +- ✅ Controller 返回值不使用 Map 类型 +- ✅ ID 字段统一命名为 id +- ✅ 所有类和方法有适当的 Swagger 注解 +- ✅ 时间字段使用 Unix 时间戳 (秒级) + +### 4. API 接口列表 + +#### 组件接口 +``` +GET /h5/component/{id} # 根据 ID 查询组件 +GET /h5/component/page # 分页查询组件列表 +POST /h5/component # 创建组件 +PUT /h5/component/{id} # 更新组件 +DELETE /h5/component/{id} # 删除组件 +DELETE /h5/component/batch # 批量删除组件 +POST /h5/component/{id}/usage # 增加使用次数 +POST /h5/component/{id}/like # 增加点赞数 +GET /h5/component/hot # 获取热门组件 +``` + +#### 分类接口 +``` +GET /h5/category/top-level # 查询所有一级分类 +GET /h5/category/children # 根据父分类 ID 查询子分类 +GET /h5/category/by-type # 根据类型查询分类 +GET /h5/category/tree # 获取分类树形结构 +POST /h5/category # 创建分类 +PUT /h5/category/{id} # 更新分类 +DELETE /h5/category/{id} # 删除分类 +``` + +#### 标签接口 +``` +GET /h5/tag # 查询所有标签 +GET /h5/tag/hot # 查询热门标签 +GET /h5/tag/by-type # 根据类型查询标签 +POST /h5/tag # 创建标签 +PUT /h5/tag/{id} # 更新标签 +DELETE /h5/tag/{id} # 删除标签 +``` + +### 5. 数据库初始化脚本 +位置:`ruoyi-site/ruoyi-h5/doc/dml/h5_component.sql` + +包含: +- 5 张表的建表语句 +- 一级分类初始化数据 (固定 5 大类) +- 二级分类示例数据 +- 标签示例数据 + +### 6. 组件类型说明 + +根据需求定义的组件类型: +- **text**: 文字类组件 (标题、正文、艺术字等) +- **image**: 图片类组件 (产品图、装饰图等) +- **form**: 表单组件 +- **map**: 地图定位组件 +- **background**: 背景类组件 +- **music**: 音乐音频组件 +- **extension**: 扩展组件 (包含 form、map 等) + +### 7. JSON 数据结构 + +组件内容使用 JSON 格式存储,支持以下类型: +- image: 包含 url、width、height、transform 等属性 +- text: 包含 content、fontFamily、fontSize、color 等属性 +- svg: 包含 url、content、colors 等属性 +- group: 包含 elements 数组 (可嵌套子元素) +- form: 包含 formData、formSchema、formItems 等属性 +- map: 包含 longitude、latitude、address 等属性 + +## 下一步工作 + +### 阶段 2: 核心业务逻辑 +- [ ] 组件推荐算法 +- [ ] 标签智能匹配 +- [ ] 组件收藏功能 +- [ ] 用户上传自定义组件 + +### 阶段 3: 性能优化 +- [ ] Redis 缓存热门数据 +- [ ] 搜索引擎集成 (Elasticsearch) +- [ ] 图片 CDN 加速 +- [ ] 批量操作优化 + +### 阶段 4: 扩展功能 +- [ ] 组件版本管理 +- [ ] 组件评价系统 +- [ ] 组件下载统计 +- [ ] 组件分享功能 + +## 编译验证 +✅ 所有代码编译通过,无错误 + +## 使用说明 +1. 执行数据库脚本:`doc/dml/h5_component.sql` +2. 启动项目后访问 Swagger 文档查看 API +3. 使用 Postman 或前端项目进行接口测试 + +## 注意事项 +- 所有时间字段使用 Unix 时间戳 (秒级) +- 组件内容以 JSON 字符串形式存储 +- 分类只支持两层结构,不支持多级嵌套 +- 删除分类前会检查是否有子分类 diff --git a/ruoyi-site/ruoyi-h5/src/main/java/com/luban/api/controller/H5ComponentController.java b/ruoyi-site/ruoyi-h5/src/main/java/com/luban/api/controller/H5ComponentController.java index 0318806f8..002826372 100644 --- a/ruoyi-site/ruoyi-h5/src/main/java/com/luban/api/controller/H5ComponentController.java +++ b/ruoyi-site/ruoyi-h5/src/main/java/com/luban/api/controller/H5ComponentController.java @@ -2,6 +2,7 @@ package com.luban.api.controller; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.luban.api.dto.H5ComponentDTO; import com.luban.api.entity.H5Component; import com.luban.api.service.H5ComponentService; import com.luban.api.vo.H5ComponentVO; @@ -12,7 +13,10 @@ import lombok.RequiredArgsConstructor; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; +import jakarta.validation.Valid; + import java.util.List; +import java.util.Map; /** * H5 组件控制器 @@ -48,26 +52,31 @@ public class H5ComponentController { return h5ComponentService.getPage(page, pageSize, type, keyword, categoryId, tagId); } + @Operation(summary = "查询指定分类下排行前 6 的组件") + @GetMapping("/top") + public Map> getPage2( + @Parameter(description = "每页大小", required = true) @RequestParam Integer pageSize, + @Parameter(description = "分类 IDS", required = true) @RequestParam List categoryIds) { + + return h5ComponentService.getPageByTopComponents(pageSize, categoryIds); + } + @Operation(summary = "创建组件") @PostMapping public Long create( - @Parameter(description = "组件信息", required = true) @RequestBody @Validated H5Component component, - @Parameter(description = "分类 ID 列表") @RequestBody(required = false) List categoryIds, - @Parameter(description = "标签 ID 列表") @RequestBody(required = false) List tagIds) { + @Parameter(description = "组件信息", required = true) @RequestBody @Valid H5ComponentDTO dto) { - return h5ComponentService.create(component, categoryIds, tagIds); + return h5ComponentService.create(dto); } @Operation(summary = "更新组件") @PostMapping("/update/{id}") public void update( @Parameter(description = "组件 ID", required = true) @PathVariable Long id, - @Parameter(description = "组件信息", required = true) @RequestBody @Validated H5Component component, - @Parameter(description = "分类 ID 列表") @RequestBody(required = false) List categoryIds, - @Parameter(description = "标签 ID 列表") @RequestBody(required = false) List tagIds) { + @Parameter(description = "组件信息", required = true) @RequestBody @Valid H5ComponentDTO dto) { - component.setId(id); - h5ComponentService.update(component, categoryIds, tagIds); + dto.setId(id); + h5ComponentService.update(dto); } @Operation(summary = "删除组件") diff --git a/ruoyi-site/ruoyi-h5/src/main/java/com/luban/api/convert/H5ComponentConvert.java b/ruoyi-site/ruoyi-h5/src/main/java/com/luban/api/convert/H5ComponentConvert.java index f5110c183..f3eb90c76 100644 --- a/ruoyi-site/ruoyi-h5/src/main/java/com/luban/api/convert/H5ComponentConvert.java +++ b/ruoyi-site/ruoyi-h5/src/main/java/com/luban/api/convert/H5ComponentConvert.java @@ -1,5 +1,6 @@ package com.luban.api.convert; +import com.luban.api.dto.H5ComponentDTO; import com.luban.api.entity.H5Component; import com.luban.api.vo.H5ComponentVO; import org.mapstruct.Mapper; @@ -22,4 +23,12 @@ public interface H5ComponentConvert { * @return VO */ H5ComponentVO toVO(H5Component entity); + + /** + * DTO 转 Entity + * + * @param dto 数据传输对象 + * @return 实体 + */ + H5Component toEntity(H5ComponentDTO dto); } diff --git a/ruoyi-site/ruoyi-h5/src/main/java/com/luban/api/dao/H5ComponentDao.java b/ruoyi-site/ruoyi-h5/src/main/java/com/luban/api/dao/H5ComponentDao.java index 9647c0262..8f1c8b1a3 100644 --- a/ruoyi-site/ruoyi-h5/src/main/java/com/luban/api/dao/H5ComponentDao.java +++ b/ruoyi-site/ruoyi-h5/src/main/java/com/luban/api/dao/H5ComponentDao.java @@ -3,6 +3,9 @@ package com.luban.api.dao; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.luban.api.entity.H5Component; import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; /** * H5 组件 Mapper 接口 @@ -13,4 +16,11 @@ import org.apache.ibatis.annotations.Mapper; @Mapper public interface H5ComponentDao extends BaseMapper { + /** + * 查询指定分类下的热门组件 + * @param categoryId 分类 ID + * @param pageSize 每页大小 + * @return 组件列表 + */ + List selectTopComponentsByCategory(@Param("categoryId") Long categoryId, @Param("pageSize") Integer pageSize); } diff --git a/ruoyi-site/ruoyi-h5/src/main/java/com/luban/api/dto/H5ComponentDTO.java b/ruoyi-site/ruoyi-h5/src/main/java/com/luban/api/dto/H5ComponentDTO.java new file mode 100644 index 000000000..3b611998d --- /dev/null +++ b/ruoyi-site/ruoyi-h5/src/main/java/com/luban/api/dto/H5ComponentDTO.java @@ -0,0 +1,107 @@ + +package com.luban.api.dto; + +import io.swagger.v3.oas.annotations.Parameter; +import jakarta.validation.constraints.NotBlank; +import lombok.Data; +import org.springframework.validation.annotation.Validated; + +import java.util.List; +import java.util.Map; + +/** + * H5 组件创建/更新 DTO + * + * @author system + * @since 2026-03-12 + */ +@Data +@Validated +public class H5ComponentDTO { + + /** + * 组件 ID(更新时使用) + */ + @Parameter(description = "组件 ID(更新时使用)") + private Long id; + + /** + * 组件名称 + */ + @Parameter(description = "组件名称", required = true) + @NotBlank(message = "组件名称不能为空") + private String name; + + /** + * 组件类型 (text/image/form/map/background/music) + */ + @Parameter(description = "组件类型 (text/image/form/map/background/music)", required = true) + @NotBlank(message = "组件类型不能为空") + private String type; + + /** + * 缩略图 URL + */ + @Parameter(description = "缩略图 URL") + private String thumbnailUrl; + + /** + * 预览图 URL + */ + @Parameter(description = "预览图 URL") + private String previewUrl; + + /** + * 组件完整配置数据 (Map 格式) + */ + @Parameter(description = "组件完整配置数据 (Map 格式)") + private Map content; + + /** + * 使用次数统计 + */ + @Parameter(description = "使用次数统计") + private Long usageCount; + + /** + * 点赞数量 + */ + @Parameter(description = "点赞数量") + private Long likeCount; + + /** + * 是否付费组件 (1:是 0:否) + */ + @Parameter(description = "是否付费组件 (1:是 0:否)") + private Integer isPremium; + + /** + * 是否系统预设 (1:是 0:否) + */ + @Parameter(description = "是否系统预设 (1:是 0:否)") + private Integer isSystem; + + /** + * 状态 (1:启用 0:禁用) + */ + @Parameter(description = "状态 (1:启用 0:禁用)") + private Integer status; + + /** + * 备注说明 + */ + @Parameter(description = "备注说明") + private String remark; + + /** + * 分类 ID 列表 + */ + @Parameter(description = "分类 ID 列表") + private List categoryIds; + + /** + * 标签 ID 列表 + */ + @Parameter(description = "标签 ID 列表") + private List tagIds; +} diff --git a/ruoyi-site/ruoyi-h5/src/main/java/com/luban/api/dto/H5ComponentTopQueryDTO.java b/ruoyi-site/ruoyi-h5/src/main/java/com/luban/api/dto/H5ComponentTopQueryDTO.java new file mode 100644 index 000000000..97ef7d98e --- /dev/null +++ b/ruoyi-site/ruoyi-h5/src/main/java/com/luban/api/dto/H5ComponentTopQueryDTO.java @@ -0,0 +1,25 @@ +package com.luban.api.dto; + +import io.swagger.v3.oas.annotations.Parameter; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +import java.util.List; + +/** + * 查询分类下热门组件请求 DTO + * + * @author system + * @since 2026-03-12 + */ +@Data +public class H5ComponentTopQueryDTO { + + @NotNull(message = "每页大小不能为空") + @Parameter(description = "每页大小", required = true) + private Integer pageSize; + + @NotNull(message = "分类 IDS 不能为空") + @Parameter(description = "分类 IDS", required = true) + private List categoryIds; +} diff --git a/ruoyi-site/ruoyi-h5/src/main/java/com/luban/api/entity/H5Component.java b/ruoyi-site/ruoyi-h5/src/main/java/com/luban/api/entity/H5Component.java index 7c51da21e..dc8855526 100644 --- a/ruoyi-site/ruoyi-h5/src/main/java/com/luban/api/entity/H5Component.java +++ b/ruoyi-site/ruoyi-h5/src/main/java/com/luban/api/entity/H5Component.java @@ -8,6 +8,8 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; +import java.util.Map; + /** * H5 组件实体 * @@ -50,7 +52,7 @@ public class H5Component { /** * 组件完整配置数据 (JSON 格式) */ - private String content; + private Map content; /** * 使用次数统计 diff --git a/ruoyi-site/ruoyi-h5/src/main/java/com/luban/api/service/H5ComponentService.java b/ruoyi-site/ruoyi-h5/src/main/java/com/luban/api/service/H5ComponentService.java index 83a7c675f..5da4bb1ec 100644 --- a/ruoyi-site/ruoyi-h5/src/main/java/com/luban/api/service/H5ComponentService.java +++ b/ruoyi-site/ruoyi-h5/src/main/java/com/luban/api/service/H5ComponentService.java @@ -1,10 +1,12 @@ package com.luban.api.service; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.luban.api.dto.H5ComponentDTO; import com.luban.api.entity.H5Component; import com.luban.api.vo.H5ComponentVO; import java.util.List; +import java.util.Map; /** * H5 组件服务接口 @@ -38,21 +40,17 @@ public interface H5ComponentService { /** * 创建组件 * - * @param component 组件信息 - * @param categoryIds 分类 ID 列表 - * @param tagIds 标签 ID 列表 + * @param dto 组件信息 DTO * @return 组件 ID */ - Long create(H5Component component, List categoryIds, List tagIds); + Long create(H5ComponentDTO dto); /** * 更新组件 * - * @param component 组件信息 - * @param categoryIds 分类 ID 列表 - * @param tagIds 标签 ID 列表 + * @param dto 组件信息 DTO */ - void update(H5Component component, List categoryIds, List tagIds); + void update(H5ComponentDTO dto); /** * 删除组件 @@ -90,4 +88,13 @@ public interface H5ComponentService { * @return 组件列表 */ List getHotComponents(String type, Integer limit); + + /** + * 查询指定分类下排行前 6 的组件 + * + * @param pageSize 每页大小 + * @param categoryIds 分类 IDS + * @return Map<分类 ID, 组件列表> + */ + Map> getPageByTopComponents(Integer pageSize, List categoryIds); } diff --git a/ruoyi-site/ruoyi-h5/src/main/java/com/luban/api/service/impl/H5ComponentServiceImpl.java b/ruoyi-site/ruoyi-h5/src/main/java/com/luban/api/service/impl/H5ComponentServiceImpl.java index cb76b4261..02c476889 100644 --- a/ruoyi-site/ruoyi-h5/src/main/java/com/luban/api/service/impl/H5ComponentServiceImpl.java +++ b/ruoyi-site/ruoyi-h5/src/main/java/com/luban/api/service/impl/H5ComponentServiceImpl.java @@ -7,7 +7,9 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.luban.api.dao.H5ComponentCategoryRelDao; import com.luban.api.dao.H5ComponentDao; import com.luban.api.dao.H5ComponentTagRelDao; +import com.luban.api.dto.H5ComponentDTO; import com.luban.api.entity.H5Component; +import com.luban.api.entity.H5ComponentCategory; import com.luban.api.entity.H5ComponentCategoryRel; import com.luban.api.entity.H5ComponentTagRel; import com.luban.api.service.H5ComponentService; @@ -19,7 +21,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.time.Instant; -import java.util.List; +import java.util.*; import java.util.stream.Collectors; /** @@ -33,6 +35,7 @@ import java.util.stream.Collectors; @RequiredArgsConstructor public class H5ComponentServiceImpl extends ServiceImpl implements H5ComponentService { + private final H5ComponentDao h5ComponentDao; private final H5ComponentCategoryRelDao h5ComponentCategoryRelDao; private final H5ComponentTagRelDao h5ComponentTagRelDao; @@ -45,17 +48,17 @@ public class H5ComponentServiceImpl extends ServiceImpl getPage(Integer page, Integer pageSize, String type, String keyword, Long categoryId, Long tagId) { Page mpPage = new Page<>(page, pageSize); - + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); wrapper.eq(H5Component::getStatus, 1); // 只查询启用的组件 - + wrapper.eq(StrUtil.isNotBlank(type), H5Component::getType, type); - + if (StrUtil.isNotBlank(keyword)) { wrapper.and(w -> w.like(H5Component::getName, keyword) .or().like(H5Component::getRemark, keyword)); } - + // 按分类筛选 if (categoryId != null) { List componentIds = getComponentIdsByCategory(categoryId); @@ -64,7 +67,7 @@ public class H5ComponentServiceImpl extends ServiceImpl componentIds = getComponentIdsByTag(tagId); @@ -73,65 +76,75 @@ public class H5ComponentServiceImpl extends ServiceImpl resultPage = baseMapper.selectPage(mpPage, wrapper); - + Page voPage = new Page<>(resultPage.getCurrent(), resultPage.getSize(), resultPage.getTotal()); List voList = resultPage.getRecords().stream() .map(H5ComponentConvert.INSTANCE::toVO) .collect(Collectors.toList()); voPage.setRecords(voList); - + return voPage; } @Override @Transactional(rollbackFor = Exception.class) - public Long create(H5Component component, List categoryIds, List tagIds) { + public Long create(H5ComponentDTO dto) { long now = Instant.now().getEpochSecond(); - + + // 转换为实体对象 + H5Component component = H5ComponentConvert.INSTANCE.toEntity(dto); + // 初始化数据 component.setCreateTime(now); component.setUpdateTime(now); component.setUsageCount(0L); component.setLikeCount(0L); component.setStatus(1); - + baseMapper.insert(component); - + // 保存分类关联 + List categoryIds = dto.getCategoryIds(); if (categoryIds != null && !categoryIds.isEmpty()) { saveCategoryRels(component.getId(), categoryIds, now); } - + // 保存标签关联 + List tagIds = dto.getTagIds(); if (tagIds != null && !tagIds.isEmpty()) { saveTagRels(component.getId(), tagIds, now); } - + return component.getId(); } @Override @Transactional(rollbackFor = Exception.class) - public void update(H5Component component, List categoryIds, List tagIds) { + public void update(H5ComponentDTO dto) { long now = Instant.now().getEpochSecond(); - + + // 转换为实体对象 + H5Component component = H5ComponentConvert.INSTANCE.toEntity(dto); component.setUpdateTime(now); - baseMapper.updateById(component); + baseMapper.updateById(component); + // 更新分类关联 + List categoryIds = dto.getCategoryIds(); if (categoryIds != null) { deleteCategoryRels(component.getId()); if (!categoryIds.isEmpty()) { saveCategoryRels(component.getId(), categoryIds, now); } } - + // 更新标签关联 + List tagIds = dto.getTagIds(); if (tagIds != null) { deleteTagRels(component.getId()); if (!tagIds.isEmpty()) { @@ -145,10 +158,10 @@ public class H5ComponentServiceImpl extends ServiceImpl getHotComponents(String type, Integer limit) { LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); wrapper.eq(H5Component::getStatus, 1); - + if (StrUtil.isNotBlank(type)) { wrapper.eq(H5Component::getType, type); } - + wrapper.orderByDesc(H5Component::getUsageCount) .last("LIMIT " + limit); - + List components = baseMapper.selectList(wrapper); return components.stream() .map(H5ComponentConvert.INSTANCE::toVO) .collect(Collectors.toList()); } + @Override + public Map> getPageByTopComponents(Integer pageSize, List categoryIds) { + if (categoryIds == null || categoryIds.isEmpty()) { + return new HashMap<>(); + } + + Map> resultMap = new HashMap<>(); + for (Long categoryId : categoryIds) { + List components = h5ComponentDao.selectTopComponentsByCategory(categoryId, pageSize); + List vos = components.stream() + .map(H5ComponentConvert.INSTANCE::toVO) + .toList(); + resultMap.put(categoryId, vos); + } + + return resultMap; + } + private List getComponentIdsByCategory(Long categoryId) { LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); wrapper.eq(H5ComponentCategoryRel::getCategoryId, categoryId); wrapper.select(H5ComponentCategoryRel::getComponentId); - + return h5ComponentCategoryRelDao.selectList(wrapper).stream() .map(H5ComponentCategoryRel::getComponentId) .collect(Collectors.toList()); @@ -213,7 +244,7 @@ public class H5ComponentServiceImpl extends ServiceImpl wrapper = new LambdaQueryWrapper<>(); wrapper.eq(H5ComponentTagRel::getTagId, tagId); wrapper.select(H5ComponentTagRel::getComponentId); - + return h5ComponentTagRelDao.selectList(wrapper).stream() .map(H5ComponentTagRel::getComponentId) .collect(Collectors.toList()); @@ -223,7 +254,7 @@ public class H5ComponentServiceImpl extends ServiceImpl rels = categoryIds.stream() .map(categoryId -> new H5ComponentCategoryRel(null, componentId, categoryId, createTime)) .collect(Collectors.toList()); - + rels.forEach(h5ComponentCategoryRelDao::insert); } @@ -231,7 +262,7 @@ public class H5ComponentServiceImpl extends ServiceImpl rels = tagIds.stream() .map(tagId -> new H5ComponentTagRel(null, componentId, tagId, createTime)) .collect(Collectors.toList()); - + rels.forEach(h5ComponentTagRelDao::insert); } diff --git a/ruoyi-site/ruoyi-h5/src/main/resources/mapper/ruoyi-h5/H5ComponentDao.xml b/ruoyi-site/ruoyi-h5/src/main/resources/mapper/ruoyi-h5/H5ComponentDao.xml new file mode 100644 index 000000000..866e51799 --- /dev/null +++ b/ruoyi-site/ruoyi-h5/src/main/resources/mapper/ruoyi-h5/H5ComponentDao.xml @@ -0,0 +1,18 @@ + + + + + + + +