Commit 865a58a646afb285fdd71ff75922fa406832c7c3

Authored by YunaiV
1 parent d6015601

✨ feat(im): 继续优化频道的各种代码,

Showing 25 changed files with 149 additions and 101 deletions
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/manager/channel/ImChannelManagerController.java
1 package cn.iocoder.yudao.module.im.controller.admin.manager.channel; 1 package cn.iocoder.yudao.module.im.controller.admin.manager.channel;
2 2
  3 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
3 import cn.iocoder.yudao.framework.common.pojo.CommonResult; 4 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
4 import cn.iocoder.yudao.framework.common.pojo.PageResult; 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
5 import cn.iocoder.yudao.framework.common.util.object.BeanUtils; 6 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
@@ -73,9 +74,9 @@ public class ImChannelManagerController { @@ -73,9 +74,9 @@ public class ImChannelManagerController {
73 74
74 @GetMapping("/simple-list") 75 @GetMapping("/simple-list")
75 @Operation(summary = "获得启用的频道精简列表;前端表单选择频道时调用") 76 @Operation(summary = "获得启用的频道精简列表;前端表单选择频道时调用")
76 - public CommonResult<List<ImChannelRespVO>> getEnabledChannelList() {  
77 - // TODO @AI:getChannelListByXXX;更通用点;  
78 - List<ImChannelDO> list = channelService.getEnabledChannelList(); 77 + public CommonResult<List<ImChannelRespVO>> getSimpleChannelList() {
  78 + // TODO DONE @AI:getChannelListByStatus 统一命名
  79 + List<ImChannelDO> list = channelService.getChannelListByStatus(CommonStatusEnum.ENABLE.getStatus());
79 return success(BeanUtils.toBean(list, ImChannelRespVO.class)); 80 return success(BeanUtils.toBean(list, ImChannelRespVO.class));
80 } 81 }
81 82
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/manager/channel/vo/material/ImChannelMaterialPageReqVO.java
@@ -18,8 +18,8 @@ public class ImChannelMaterialPageReqVO extends PageParam { @@ -18,8 +18,8 @@ public class ImChannelMaterialPageReqVO extends PageParam {
18 @Schema(description = "频道编号", example = "1") 18 @Schema(description = "频道编号", example = "1")
19 private Long channelId; 19 private Long channelId;
20 20
21 - @Schema(description = "素材类型", example = "125")  
22 - private Integer type; 21 + @Schema(description = "内容类型", example = "1")
  22 + private Integer type; // 参见 ImChannelMaterialContentTypeEnum 枚举类
23 23
24 @Schema(description = "标题", example = "活动") 24 @Schema(description = "标题", example = "活动")
25 private String title; 25 private String title;
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/manager/channel/vo/material/ImChannelMaterialRespVO.java
@@ -18,8 +18,8 @@ public class ImChannelMaterialRespVO { @@ -18,8 +18,8 @@ public class ImChannelMaterialRespVO {
18 @Schema(description = "频道名称(关联查询填充)") 18 @Schema(description = "频道名称(关联查询填充)")
19 private String channelName; 19 private String channelName;
20 20
21 - @Schema(description = "素材类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "125")  
22 - private Integer type; // 参见 ImMessageTypeEnum 枚举类 21 + @Schema(description = "内容类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  22 + private Integer type; // 参见 ImChannelMaterialContentTypeEnum 枚举类
23 23
24 @Schema(description = "标题", requiredMode = Schema.RequiredMode.REQUIRED) 24 @Schema(description = "标题", requiredMode = Schema.RequiredMode.REQUIRED)
25 private String title; 25 private String title;
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/manager/channel/vo/material/ImChannelMaterialSaveReqVO.java
@@ -17,9 +17,9 @@ public class ImChannelMaterialSaveReqVO { @@ -17,9 +17,9 @@ public class ImChannelMaterialSaveReqVO {
17 @NotNull(message = "频道编号不能为空") 17 @NotNull(message = "频道编号不能为空")
18 private Long channelId; 18 private Long channelId;
19 19
20 - @Schema(description = "素材类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "125")  
21 - @NotNull(message = "素材类型不能为空")  
22 - private Integer type; // 参见 ImMessageTypeEnum 枚举类 20 + @Schema(description = "内容类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  21 + @NotNull(message = "内容类型不能为空")
  22 + private Integer type; // 参见 ImChannelMaterialContentTypeEnum 枚举类
23 23
24 @Schema(description = "标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "双十一活动来啦") 24 @Schema(description = "标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "双十一活动来啦")
25 @NotBlank(message = "标题不能为空") 25 @NotBlank(message = "标题不能为空")
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/manager/channel/ImChannelMessageManagerController.java renamed to yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/manager/message/ImChannelMessageManagerController.java
1 -package cn.iocoder.yudao.module.im.controller.admin.manager.channel; 1 +package cn.iocoder.yudao.module.im.controller.admin.manager.message;
2 2
3 import cn.hutool.core.collection.CollUtil; 3 import cn.hutool.core.collection.CollUtil;
4 import cn.iocoder.yudao.framework.common.pojo.CommonResult; 4 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
5 import cn.iocoder.yudao.framework.common.pojo.PageResult; 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
6 import cn.iocoder.yudao.framework.common.util.collection.MapUtils; 6 import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
7 import cn.iocoder.yudao.framework.common.util.object.BeanUtils; 7 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
8 -import cn.iocoder.yudao.module.im.controller.admin.manager.channel.vo.message.ImChannelMessagePageReqVO;  
9 -import cn.iocoder.yudao.module.im.controller.admin.manager.channel.vo.message.ImChannelMessageRespVO;  
10 -import cn.iocoder.yudao.module.im.controller.admin.manager.channel.vo.message.ImChannelMessageSendReqVO; 8 +import cn.iocoder.yudao.module.im.controller.admin.manager.message.vo.channel.ImChannelMessagePageReqVO;
  9 +import cn.iocoder.yudao.module.im.controller.admin.manager.message.vo.channel.ImChannelMessageRespVO;
  10 +import cn.iocoder.yudao.module.im.controller.admin.manager.message.vo.channel.ImChannelMessageSendReqVO;
11 import cn.iocoder.yudao.module.im.dal.dataobject.channel.ImChannelDO; 11 import cn.iocoder.yudao.module.im.dal.dataobject.channel.ImChannelDO;
12 import cn.iocoder.yudao.module.im.dal.dataobject.channel.ImChannelMaterialDO; 12 import cn.iocoder.yudao.module.im.dal.dataobject.channel.ImChannelMaterialDO;
13 -import cn.iocoder.yudao.module.im.dal.dataobject.channel.ImChannelMessageDO; 13 +import cn.iocoder.yudao.module.im.dal.dataobject.message.ImChannelMessageDO;
14 import cn.iocoder.yudao.module.im.service.channel.ImChannelMaterialService; 14 import cn.iocoder.yudao.module.im.service.channel.ImChannelMaterialService;
15 -import cn.iocoder.yudao.module.im.service.channel.ImChannelMessageService; 15 +import cn.iocoder.yudao.module.im.service.message.ImChannelMessageService;
16 import cn.iocoder.yudao.module.im.service.channel.ImChannelService; 16 import cn.iocoder.yudao.module.im.service.channel.ImChannelService;
17 import io.swagger.v3.oas.annotations.Operation; 17 import io.swagger.v3.oas.annotations.Operation;
18 import io.swagger.v3.oas.annotations.Parameter; 18 import io.swagger.v3.oas.annotations.Parameter;
@@ -26,7 +26,6 @@ import org.springframework.web.bind.annotation.*; @@ -26,7 +26,6 @@ import org.springframework.web.bind.annotation.*;
26 import java.util.Map; 26 import java.util.Map;
27 27
28 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; 28 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
29 -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;  
30 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; 29 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
31 30
32 @Tag(name = "管理后台 - IM 频道消息") 31 @Tag(name = "管理后台 - IM 频道消息")
@@ -66,14 +65,11 @@ public class ImChannelMessageManagerController { @@ -66,14 +65,11 @@ public class ImChannelMessageManagerController {
66 if (CollUtil.isEmpty(pageResult.getList())) { 65 if (CollUtil.isEmpty(pageResult.getList())) {
67 return success(PageResult.empty(pageResult.getTotal())); 66 return success(PageResult.empty(pageResult.getTotal()));
68 } 67 }
69 - // TODO @AI:最好是 channelService 也包出一个 getChannelMap;类似别的模块  
70 - Map<Long, ImChannelDO> channelMap = convertMap(  
71 - channelService.getChannelList(convertSet(pageResult.getList(), ImChannelMessageDO::getChannelId)),  
72 - ImChannelDO::getId);  
73 - // TODO @AI:最好是 channelService 也包出一个 getChannelMap;类似别的模块  
74 - Map<Long, ImChannelMaterialDO> materialMap = convertMap(  
75 - channelMaterialService.getMaterialList(convertSet(pageResult.getList(), ImChannelMessageDO::getMaterialId)),  
76 - ImChannelMaterialDO::getId); 68 + // 批量查询频道和素材,并回填频道名 / 素材标题
  69 + Map<Long, ImChannelDO> channelMap = channelService.getChannelMap(
  70 + convertSet(pageResult.getList(), ImChannelMessageDO::getChannelId));
  71 + Map<Long, ImChannelMaterialDO> materialMap = channelMaterialService.getMaterialMap(
  72 + convertSet(pageResult.getList(), ImChannelMessageDO::getMaterialId));
77 return success(BeanUtils.toBean(pageResult, ImChannelMessageRespVO.class, vo -> { 73 return success(BeanUtils.toBean(pageResult, ImChannelMessageRespVO.class, vo -> {
78 MapUtils.findAndThen(channelMap, vo.getChannelId(), c -> vo.setChannelName(c.getName())); 74 MapUtils.findAndThen(channelMap, vo.getChannelId(), c -> vo.setChannelName(c.getName()));
79 MapUtils.findAndThen(materialMap, vo.getMaterialId(), m -> vo.setMaterialTitle(m.getTitle())); 75 MapUtils.findAndThen(materialMap, vo.getMaterialId(), m -> vo.setMaterialTitle(m.getTitle()));
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/manager/channel/vo/message/ImChannelMessagePageReqVO.java renamed to yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/manager/message/vo/channel/ImChannelMessagePageReqVO.java
1 -package cn.iocoder.yudao.module.im.controller.admin.manager.channel.vo.message; 1 +package cn.iocoder.yudao.module.im.controller.admin.manager.message.vo.channel;
2 2
3 import cn.iocoder.yudao.framework.common.pojo.PageParam; 3 import cn.iocoder.yudao.framework.common.pojo.PageParam;
4 import io.swagger.v3.oas.annotations.media.Schema; 4 import io.swagger.v3.oas.annotations.media.Schema;
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/manager/channel/vo/message/ImChannelMessageRespVO.java renamed to yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/manager/message/vo/channel/ImChannelMessageRespVO.java
1 -package cn.iocoder.yudao.module.im.controller.admin.manager.channel.vo.message; 1 +package cn.iocoder.yudao.module.im.controller.admin.manager.message.vo.channel;
2 2
3 import io.swagger.v3.oas.annotations.media.Schema; 3 import io.swagger.v3.oas.annotations.media.Schema;
4 import lombok.Data; 4 import lombok.Data;
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/manager/channel/vo/message/ImChannelMessageSendReqVO.java renamed to yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/manager/message/vo/channel/ImChannelMessageSendReqVO.java
1 -package cn.iocoder.yudao.module.im.controller.admin.manager.channel.vo.message; 1 +package cn.iocoder.yudao.module.im.controller.admin.manager.message.vo.channel;
2 2
3 import io.swagger.v3.oas.annotations.media.Schema; 3 import io.swagger.v3.oas.annotations.media.Schema;
4 import jakarta.validation.constraints.NotNull; 4 import jakarta.validation.constraints.NotNull;
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/channel/ImChannelMessageController.java renamed to yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/ImChannelMessageController.java
1 -package cn.iocoder.yudao.module.im.controller.admin.channel; 1 +package cn.iocoder.yudao.module.im.controller.admin.message;
2 2
3 import cn.iocoder.yudao.framework.common.pojo.CommonResult; 3 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
4 import cn.iocoder.yudao.framework.common.util.object.BeanUtils; 4 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
5 -import cn.iocoder.yudao.module.im.controller.admin.channel.vo.ImChannelMessagePullRespVO;  
6 -import cn.iocoder.yudao.module.im.dal.dataobject.channel.ImChannelMessageDO;  
7 -import cn.iocoder.yudao.module.im.service.channel.ImChannelMessageService; 5 +import cn.iocoder.yudao.module.im.controller.admin.message.vo.channel.ImChannelMessagePullRespVO;
  6 +import cn.iocoder.yudao.module.im.dal.dataobject.message.ImChannelMessageDO;
  7 +import cn.iocoder.yudao.module.im.service.message.ImChannelMessageService;
8 import io.swagger.v3.oas.annotations.Operation; 8 import io.swagger.v3.oas.annotations.Operation;
9 import io.swagger.v3.oas.annotations.tags.Tag; 9 import io.swagger.v3.oas.annotations.tags.Tag;
10 import jakarta.annotation.Resource; 10 import jakarta.annotation.Resource;
  11 +import jakarta.validation.constraints.Max;
  12 +import jakarta.validation.constraints.Min;
  13 +import jakarta.validation.constraints.PositiveOrZero;
11 import org.springframework.validation.annotation.Validated; 14 import org.springframework.validation.annotation.Validated;
12 import org.springframework.web.bind.annotation.GetMapping; 15 import org.springframework.web.bind.annotation.GetMapping;
13 import org.springframework.web.bind.annotation.RequestMapping; 16 import org.springframework.web.bind.annotation.RequestMapping;
@@ -31,8 +34,10 @@ public class ImChannelMessageController { @@ -31,8 +34,10 @@ public class ImChannelMessageController {
31 @GetMapping("/pull") 34 @GetMapping("/pull")
32 @Operation(summary = "拉取频道消息(离线增量);按 minId 游标分页") 35 @Operation(summary = "拉取频道消息(离线增量);按 minId 游标分页")
33 public CommonResult<List<ImChannelMessagePullRespVO>> pull( 36 public CommonResult<List<ImChannelMessagePullRespVO>> pull(
34 - @RequestParam(value = "minId", defaultValue = "0") Long minId,  
35 - @RequestParam(value = "size", defaultValue = "100") Integer size) { 37 + @RequestParam(value = "minId", defaultValue = "0") @PositiveOrZero(message = "minId 不能小于 0") Long minId,
  38 + @RequestParam(value = "size", defaultValue = "100")
  39 + @Min(value = 1, message = "size 必须大于 0")
  40 + @Max(value = 200, message = "size 一次最多 200 条") Integer size) {
36 List<ImChannelMessageDO> list = channelMessageService.getMessageListForPull(getLoginUserId(), minId, size); 41 List<ImChannelMessageDO> list = channelMessageService.getMessageListForPull(getLoginUserId(), minId, size);
37 return success(BeanUtils.toBean(list, ImChannelMessagePullRespVO.class)); 42 return success(BeanUtils.toBean(list, ImChannelMessagePullRespVO.class));
38 } 43 }
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/channel/vo/ImChannelMessagePullRespVO.java renamed to yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/vo/channel/ImChannelMessagePullRespVO.java
1 -package cn.iocoder.yudao.module.im.controller.admin.channel.vo; 1 +package cn.iocoder.yudao.module.im.controller.admin.message.vo.channel;
2 2
3 import io.swagger.v3.oas.annotations.media.Schema; 3 import io.swagger.v3.oas.annotations.media.Schema;
4 import lombok.Data; 4 import lombok.Data;
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/channel/ImChannelMaterialDO.java
1 package cn.iocoder.yudao.module.im.dal.dataobject.channel; 1 package cn.iocoder.yudao.module.im.dal.dataobject.channel;
2 2
3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; 3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
4 -import cn.iocoder.yudao.module.im.enums.message.ImMessageTypeEnum; 4 +import cn.iocoder.yudao.module.im.enums.channel.ImChannelMaterialContentTypeEnum;
5 import com.baomidou.mybatisplus.annotation.KeySequence; 5 import com.baomidou.mybatisplus.annotation.KeySequence;
6 import com.baomidou.mybatisplus.annotation.TableId; 6 import com.baomidou.mybatisplus.annotation.TableId;
7 import com.baomidou.mybatisplus.annotation.TableName; 7 import com.baomidou.mybatisplus.annotation.TableName;
@@ -39,9 +39,9 @@ public class ImChannelMaterialDO extends BaseDO { @@ -39,9 +39,9 @@ public class ImChannelMaterialDO extends BaseDO {
39 */ 39 */
40 private Long channelId; 40 private Long channelId;
41 /** 41 /**
42 - * 素材类型 42 + * 素材内容类型
43 * <p> 43 * <p>
44 - * 枚举 {@link ImMessageTypeEnum};当前仅 MATERIAL(125) 44 + * 枚举 {@link ImChannelMaterialContentTypeEnum}
45 */ 45 */
46 private Integer type; 46 private Integer type;
47 /** 47 /**
@@ -56,15 +56,12 @@ public class ImChannelMaterialDO extends BaseDO { @@ -56,15 +56,12 @@ public class ImChannelMaterialDO extends BaseDO {
56 * 摘要 56 * 摘要
57 */ 57 */
58 private String summary; 58 private String summary;
59 - // TODO @AI:素材类型,是不是有个 type;这样一个 content、url 更好区分;然后这个 type ,是不是在 MATERIAL Message 类上,也带上;  
60 /** 59 /**
61 - * 正文;富文本 HTML 60 + * 富文本 HTML;在 {@link ImChannelMaterialContentTypeEnum#CONTENT} 使用
62 */ 61 */
63 private String content; 62 private String content;
64 /** 63 /**
65 - * 跳转链接  
66 - * <p>  
67 - * 为空时点击在客户端内置详情页拉 {@link #content} 渲染;非空则跳 url 64 + * 跳转链接;在 {@link ImChannelMaterialContentTypeEnum#LINK} 使用
68 */ 65 */
69 private String url; 66 private String url;
70 67
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/channel/ImChannelMessageDO.java renamed to yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/message/ImChannelMessageDO.java
1 -package cn.iocoder.yudao.module.im.dal.dataobject.channel; 1 +package cn.iocoder.yudao.module.im.dal.dataobject.message;
2 2
3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; 3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
4 import cn.iocoder.yudao.framework.mybatis.core.type.LongListTypeHandler; 4 import cn.iocoder.yudao.framework.mybatis.core.type.LongListTypeHandler;
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/channel/ImChannelMaterialMapper.java
@@ -20,21 +20,12 @@ public interface ImChannelMaterialMapper extends BaseMapperX&lt;ImChannelMaterialDO @@ -20,21 +20,12 @@ public interface ImChannelMaterialMapper extends BaseMapperX&lt;ImChannelMaterialDO
20 } 20 }
21 21
22 default PageResult<ImChannelMaterialDO> selectPage(ImChannelMaterialPageReqVO reqVO) { 22 default PageResult<ImChannelMaterialDO> selectPage(ImChannelMaterialPageReqVO reqVO) {
23 - LambdaQueryWrapperX<ImChannelMaterialDO> wrapper = new LambdaQueryWrapperX<ImChannelMaterialDO>() 23 + return selectPage(reqVO, new LambdaQueryWrapperX<ImChannelMaterialDO>()
24 .eqIfPresent(ImChannelMaterialDO::getChannelId, reqVO.getChannelId()) 24 .eqIfPresent(ImChannelMaterialDO::getChannelId, reqVO.getChannelId())
25 .eqIfPresent(ImChannelMaterialDO::getType, reqVO.getType()) 25 .eqIfPresent(ImChannelMaterialDO::getType, reqVO.getType())
26 .likeIfPresent(ImChannelMaterialDO::getTitle, reqVO.getTitle()) 26 .likeIfPresent(ImChannelMaterialDO::getTitle, reqVO.getTitle())
27 .betweenIfPresent(ImChannelMaterialDO::getCreateTime, reqVO.getCreateTime()) 27 .betweenIfPresent(ImChannelMaterialDO::getCreateTime, reqVO.getCreateTime())
28 - .orderByDesc(ImChannelMaterialDO::getId);  
29 - // TODO @AI:不用排除;列表问题不大的;  
30 - // 列表查询排除富文本 content 字段,避免 mediumtext 拖垮分页响应  
31 - wrapper.select(ImChannelMaterialDO::getId, ImChannelMaterialDO::getChannelId,  
32 - ImChannelMaterialDO::getType, ImChannelMaterialDO::getTitle,  
33 - ImChannelMaterialDO::getCoverUrl, ImChannelMaterialDO::getSummary,  
34 - ImChannelMaterialDO::getUrl, ImChannelMaterialDO::getCreator,  
35 - ImChannelMaterialDO::getCreateTime, ImChannelMaterialDO::getUpdater,  
36 - ImChannelMaterialDO::getUpdateTime, ImChannelMaterialDO::getDeleted);  
37 - return selectPage(reqVO, wrapper); 28 + .orderByDesc(ImChannelMaterialDO::getId));
38 } 29 }
39 30
40 } 31 }
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/channel/ImChannelMessageMapper.java renamed to yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/message/ImChannelMessageMapper.java
1 -package cn.iocoder.yudao.module.im.dal.mysql.channel; 1 +package cn.iocoder.yudao.module.im.dal.mysql.message;
2 2
3 import cn.iocoder.yudao.framework.common.pojo.PageResult; 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; 4 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
5 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; 5 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
6 -import cn.iocoder.yudao.module.im.controller.admin.manager.channel.vo.message.ImChannelMessagePageReqVO;  
7 -import cn.iocoder.yudao.module.im.dal.dataobject.channel.ImChannelMessageDO; 6 +import cn.iocoder.yudao.module.im.controller.admin.manager.message.vo.channel.ImChannelMessagePageReqVO;
  7 +import cn.iocoder.yudao.module.im.dal.dataobject.message.ImChannelMessageDO;
8 import org.apache.ibatis.annotations.Mapper; 8 import org.apache.ibatis.annotations.Mapper;
9 9
10 import java.util.List; 10 import java.util.List;
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/enums/channel/ImChannelMaterialContentTypeEnum.java 0 → 100644
  1 +package cn.iocoder.yudao.module.im.enums.channel;
  2 +
  3 +import cn.iocoder.yudao.framework.common.core.ArrayValuable;
  4 +import lombok.AllArgsConstructor;
  5 +import lombok.Getter;
  6 +
  7 +import java.util.Arrays;
  8 +
  9 +/**
  10 + * IM 频道素材内容类型枚举
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +@Getter
  15 +@AllArgsConstructor
  16 +public enum ImChannelMaterialContentTypeEnum implements ArrayValuable<Integer> {
  17 +
  18 + /**
  19 + * 站内富文本;点击素材在客户端内置详情页拉 content 渲染
  20 + */
  21 + CONTENT(1, "站内富文本"),
  22 + /**
  23 + * 外链;点击素材跳 url 打开浏览器
  24 + */
  25 + LINK(2, "外链");
  26 +
  27 + public static final Integer[] ARRAYS = Arrays.stream(values()).map(ImChannelMaterialContentTypeEnum::getType).toArray(Integer[]::new);
  28 +
  29 + private final Integer type;
  30 + private final String name;
  31 +
  32 + @Override
  33 + public Integer[] array() {
  34 + return ARRAYS;
  35 + }
  36 +
  37 +}
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/channel/ImChannelMaterialService.java
@@ -8,6 +8,9 @@ import jakarta.validation.Valid; @@ -8,6 +8,9 @@ import jakarta.validation.Valid;
8 8
9 import java.util.Collection; 9 import java.util.Collection;
10 import java.util.List; 10 import java.util.List;
  11 +import java.util.Map;
  12 +
  13 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
11 14
12 /** 15 /**
13 * IM 频道素材 Service 接口 16 * IM 频道素材 Service 接口
@@ -19,14 +22,6 @@ public interface ImChannelMaterialService { @@ -19,14 +22,6 @@ public interface ImChannelMaterialService {
19 // ==================== 用户端 ==================== 22 // ==================== 用户端 ====================
20 23
21 /** 24 /**
22 - * 获取素材正文;用于客户端点击图文卡片时拉富文本  
23 - *  
24 - * @param id 素材编号  
25 - * @return 富文本 HTML  
26 - */  
27 - String getMaterialContent(Long id);  
28 -  
29 - /**  
30 * 校验素材存在 25 * 校验素材存在
31 * 26 *
32 * @param id 素材编号 27 * @param id 素材编号
@@ -43,6 +38,16 @@ public interface ImChannelMaterialService { @@ -43,6 +38,16 @@ public interface ImChannelMaterialService {
43 List<ImChannelMaterialDO> getMaterialList(Collection<Long> ids); 38 List<ImChannelMaterialDO> getMaterialList(Collection<Long> ids);
44 39
45 /** 40 /**
  41 + * 按编号批量查询素材 Map
  42 + *
  43 + * @param ids 素材编号列表
  44 + * @return id -> 素材 Map
  45 + */
  46 + default Map<Long, ImChannelMaterialDO> getMaterialMap(Collection<Long> ids) {
  47 + return convertMap(getMaterialList(ids), ImChannelMaterialDO::getId);
  48 + }
  49 +
  50 + /**
46 * 统计指定频道下的素材数量 51 * 统计指定频道下的素材数量
47 * 52 *
48 * @param channelId 频道编号 53 * @param channelId 频道编号
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/channel/ImChannelMaterialServiceImpl.java
@@ -7,7 +7,7 @@ import cn.iocoder.yudao.module.im.controller.admin.manager.channel.vo.material.I @@ -7,7 +7,7 @@ import cn.iocoder.yudao.module.im.controller.admin.manager.channel.vo.material.I
7 import cn.iocoder.yudao.module.im.controller.admin.manager.channel.vo.material.ImChannelMaterialSaveReqVO; 7 import cn.iocoder.yudao.module.im.controller.admin.manager.channel.vo.material.ImChannelMaterialSaveReqVO;
8 import cn.iocoder.yudao.module.im.dal.dataobject.channel.ImChannelMaterialDO; 8 import cn.iocoder.yudao.module.im.dal.dataobject.channel.ImChannelMaterialDO;
9 import cn.iocoder.yudao.module.im.dal.mysql.channel.ImChannelMaterialMapper; 9 import cn.iocoder.yudao.module.im.dal.mysql.channel.ImChannelMaterialMapper;
10 -import cn.iocoder.yudao.module.im.dal.mysql.channel.ImChannelMessageMapper; 10 +import cn.iocoder.yudao.module.im.dal.mysql.message.ImChannelMessageMapper;
11 import jakarta.annotation.Resource; 11 import jakarta.annotation.Resource;
12 import org.springframework.stereotype.Service; 12 import org.springframework.stereotype.Service;
13 import org.springframework.validation.annotation.Validated; 13 import org.springframework.validation.annotation.Validated;
@@ -39,12 +39,6 @@ public class ImChannelMaterialServiceImpl implements ImChannelMaterialService { @@ -39,12 +39,6 @@ public class ImChannelMaterialServiceImpl implements ImChannelMaterialService {
39 // ==================== 用户端 ==================== 39 // ==================== 用户端 ====================
40 40
41 @Override 41 @Override
42 - public String getMaterialContent(Long id) {  
43 - ImChannelMaterialDO material = validateMaterialExists(id);  
44 - return material.getContent();  
45 - }  
46 -  
47 - @Override  
48 public ImChannelMaterialDO validateMaterialExists(Long id) { 42 public ImChannelMaterialDO validateMaterialExists(Long id) {
49 ImChannelMaterialDO material = channelMaterialMapper.selectById(id); 43 ImChannelMaterialDO material = channelMaterialMapper.selectById(id);
50 if (material == null) { 44 if (material == null) {
@@ -78,20 +72,25 @@ public class ImChannelMaterialServiceImpl implements ImChannelMaterialService { @@ -78,20 +72,25 @@ public class ImChannelMaterialServiceImpl implements ImChannelMaterialService {
78 return channelMaterialMapper.selectById(id); 72 return channelMaterialMapper.selectById(id);
79 } 73 }
80 74
81 - // TODO @AI:类似别的模块,写全注释  
82 @Override 75 @Override
83 public Long createMaterial(ImChannelMaterialSaveReqVO reqVO) { 76 public Long createMaterial(ImChannelMaterialSaveReqVO reqVO) {
  77 + // 1. 校验所属频道存在
84 channelService.validateChannelExists(reqVO.getChannelId()); 78 channelService.validateChannelExists(reqVO.getChannelId());
  79 +
  80 + // 2. 插入素材
85 ImChannelMaterialDO material = BeanUtils.toBean(reqVO, ImChannelMaterialDO.class); 81 ImChannelMaterialDO material = BeanUtils.toBean(reqVO, ImChannelMaterialDO.class);
86 channelMaterialMapper.insert(material); 82 channelMaterialMapper.insert(material);
87 return material.getId(); 83 return material.getId();
88 } 84 }
89 85
90 - // TODO @AI:类似别的模块,写全注释  
91 @Override 86 @Override
92 public void updateMaterial(ImChannelMaterialSaveReqVO reqVO) { 87 public void updateMaterial(ImChannelMaterialSaveReqVO reqVO) {
  88 + // 1.1 校验存在
93 validateMaterialExists(reqVO.getId()); 89 validateMaterialExists(reqVO.getId());
  90 + // 1.2 校验所属频道存在
94 channelService.validateChannelExists(reqVO.getChannelId()); 91 channelService.validateChannelExists(reqVO.getChannelId());
  92 +
  93 + // 2. 更新素材
95 ImChannelMaterialDO updateObj = BeanUtils.toBean(reqVO, ImChannelMaterialDO.class); 94 ImChannelMaterialDO updateObj = BeanUtils.toBean(reqVO, ImChannelMaterialDO.class);
96 channelMaterialMapper.updateById(updateObj); 95 channelMaterialMapper.updateById(updateObj);
97 } 96 }
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/channel/ImChannelService.java
@@ -8,6 +8,9 @@ import jakarta.validation.Valid; @@ -8,6 +8,9 @@ import jakarta.validation.Valid;
8 8
9 import java.util.Collection; 9 import java.util.Collection;
10 import java.util.List; 10 import java.util.List;
  11 +import java.util.Map;
  12 +
  13 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
11 14
12 /** 15 /**
13 * IM 频道 Service 接口 16 * IM 频道 Service 接口
@@ -18,13 +21,13 @@ public interface ImChannelService { @@ -18,13 +21,13 @@ public interface ImChannelService {
18 21
19 // ==================== 用户端 ==================== 22 // ==================== 用户端 ====================
20 23
21 - // TODO @AI:getChannelListByStatus 这种形式;  
22 /** 24 /**
23 - * 获取所有启用的频道,按 sort 升序 25 + * 按状态查询频道列表,按 sort 升序
24 * 26 *
25 - * @return 启用的频道列表 27 + * @param status 状态;对应 CommonStatusEnum
  28 + * @return 频道列表
26 */ 29 */
27 - List<ImChannelDO> getEnabledChannelList(); 30 + List<ImChannelDO> getChannelListByStatus(Integer status);
28 31
29 /** 32 /**
30 * 按编号批量查询频道 33 * 按编号批量查询频道
@@ -35,6 +38,16 @@ public interface ImChannelService { @@ -35,6 +38,16 @@ public interface ImChannelService {
35 List<ImChannelDO> getChannelList(Collection<Long> ids); 38 List<ImChannelDO> getChannelList(Collection<Long> ids);
36 39
37 /** 40 /**
  41 + * 按编号批量查询频道 Map
  42 + *
  43 + * @param ids 频道编号列表
  44 + * @return id -> 频道 Map
  45 + */
  46 + default Map<Long, ImChannelDO> getChannelMap(Collection<Long> ids) {
  47 + return convertMap(getChannelList(ids), ImChannelDO::getId);
  48 + }
  49 +
  50 + /**
38 * 校验频道存在 51 * 校验频道存在
39 * 52 *
40 * @param id 频道编号 53 * @param id 频道编号
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/channel/ImChannelServiceImpl.java
@@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.im.service.channel; @@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.im.service.channel;
2 2
3 import cn.hutool.core.collection.CollUtil; 3 import cn.hutool.core.collection.CollUtil;
4 import cn.hutool.core.util.ObjUtil; 4 import cn.hutool.core.util.ObjUtil;
5 -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;  
6 import cn.iocoder.yudao.framework.common.pojo.PageResult; 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
7 import cn.iocoder.yudao.framework.common.util.object.BeanUtils; 6 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
8 import cn.iocoder.yudao.module.im.controller.admin.manager.channel.vo.channel.ImChannelPageReqVO; 7 import cn.iocoder.yudao.module.im.controller.admin.manager.channel.vo.channel.ImChannelPageReqVO;
@@ -18,9 +17,7 @@ import java.util.Collections; @@ -18,9 +17,7 @@ import java.util.Collections;
18 import java.util.List; 17 import java.util.List;
19 18
20 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 19 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
21 -import static cn.iocoder.yudao.module.im.enums.ErrorCodeConstants.IM_CHANNEL_CODE_DUPLICATED;  
22 -import static cn.iocoder.yudao.module.im.enums.ErrorCodeConstants.IM_CHANNEL_HAS_MATERIAL;  
23 -import static cn.iocoder.yudao.module.im.enums.ErrorCodeConstants.IM_CHANNEL_NOT_EXISTS; 20 +import static cn.iocoder.yudao.module.im.enums.ErrorCodeConstants.*;
24 21
25 /** 22 /**
26 * IM 频道 Service 实现类 23 * IM 频道 Service 实现类
@@ -39,8 +36,8 @@ public class ImChannelServiceImpl implements ImChannelService { @@ -39,8 +36,8 @@ public class ImChannelServiceImpl implements ImChannelService {
39 // ==================== 用户端 ==================== 36 // ==================== 用户端 ====================
40 37
41 @Override 38 @Override
42 - public List<ImChannelDO> getEnabledChannelList() {  
43 - return channelMapper.selectListByStatusOrderBySort(CommonStatusEnum.ENABLE.getStatus()); 39 + public List<ImChannelDO> getChannelListByStatus(Integer status) {
  40 + return channelMapper.selectListByStatusOrderBySort(status);
44 } 41 }
45 42
46 @Override 43 @Override
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/channel/ImChannelMessageService.java renamed to yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/message/ImChannelMessageService.java
1 -package cn.iocoder.yudao.module.im.service.channel; 1 +package cn.iocoder.yudao.module.im.service.message;
2 2
3 import cn.iocoder.yudao.framework.common.pojo.PageResult; 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 -import cn.iocoder.yudao.module.im.controller.admin.manager.channel.vo.message.ImChannelMessagePageReqVO;  
5 -import cn.iocoder.yudao.module.im.controller.admin.manager.channel.vo.message.ImChannelMessageSendReqVO;  
6 -import cn.iocoder.yudao.module.im.dal.dataobject.channel.ImChannelMessageDO; 4 +import cn.iocoder.yudao.module.im.controller.admin.manager.message.vo.channel.ImChannelMessagePageReqVO;
  5 +import cn.iocoder.yudao.module.im.controller.admin.manager.message.vo.channel.ImChannelMessageSendReqVO;
  6 +import cn.iocoder.yudao.module.im.dal.dataobject.message.ImChannelMessageDO;
7 import jakarta.validation.Valid; 7 import jakarta.validation.Valid;
8 8
9 import java.util.List; 9 import java.util.List;
10 10
11 -// TODO @AI:这块消息,我想挪到 message 里;后续,可能整合成一个表存储的;  
12 /** 11 /**
13 * IM 频道消息 Service 接口 12 * IM 频道消息 Service 接口
14 * 13 *
@@ -33,8 +32,6 @@ public interface ImChannelMessageService { @@ -33,8 +32,6 @@ public interface ImChannelMessageService {
33 32
34 /** 33 /**
35 * 立即推送频道消息 34 * 立即推送频道消息
36 - * <p>  
37 - * 流程:读 material → 组装 payload → INSERT 1 行 im_channel_message → WebSocket 扇出  
38 * 35 *
39 * @param reqVO 推送请求 36 * @param reqVO 推送请求
40 * @return 消息编号 37 * @return 消息编号
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/channel/ImChannelMessageServiceImpl.java renamed to yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/message/ImChannelMessageServiceImpl.java
1 -package cn.iocoder.yudao.module.im.service.channel; 1 +package cn.iocoder.yudao.module.im.service.message;
2 2
3 import cn.hutool.core.collection.CollUtil; 3 import cn.hutool.core.collection.CollUtil;
4 import cn.iocoder.yudao.framework.common.pojo.PageResult; 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
5 import cn.iocoder.yudao.framework.common.util.json.JsonUtils; 5 import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
6 import cn.iocoder.yudao.framework.common.util.object.BeanUtils; 6 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
7 -import cn.iocoder.yudao.module.im.controller.admin.manager.channel.vo.message.ImChannelMessagePageReqVO;  
8 -import cn.iocoder.yudao.module.im.controller.admin.manager.channel.vo.message.ImChannelMessageSendReqVO; 7 +import cn.iocoder.yudao.module.im.controller.admin.manager.message.vo.channel.ImChannelMessagePageReqVO;
  8 +import cn.iocoder.yudao.module.im.controller.admin.manager.message.vo.channel.ImChannelMessageSendReqVO;
9 import cn.iocoder.yudao.module.im.dal.dataobject.channel.ImChannelMaterialDO; 9 import cn.iocoder.yudao.module.im.dal.dataobject.channel.ImChannelMaterialDO;
10 -import cn.iocoder.yudao.module.im.dal.dataobject.channel.ImChannelMessageDO;  
11 -import cn.iocoder.yudao.module.im.dal.mysql.channel.ImChannelMessageMapper; 10 +import cn.iocoder.yudao.module.im.dal.dataobject.message.ImChannelMessageDO;
  11 +import cn.iocoder.yudao.module.im.dal.mysql.message.ImChannelMessageMapper;
12 import cn.iocoder.yudao.module.im.enums.message.ImMessageTypeEnum; 12 import cn.iocoder.yudao.module.im.enums.message.ImMessageTypeEnum;
  13 +import cn.iocoder.yudao.module.im.service.channel.ImChannelMaterialService;
13 import cn.iocoder.yudao.module.im.service.websocket.ImWebSocketService; 14 import cn.iocoder.yudao.module.im.service.websocket.ImWebSocketService;
14 import cn.iocoder.yudao.module.im.service.websocket.dto.ImChannelMessageDTO; 15 import cn.iocoder.yudao.module.im.service.websocket.dto.ImChannelMessageDTO;
15 import cn.iocoder.yudao.module.im.service.websocket.dto.message.MaterialMessage; 16 import cn.iocoder.yudao.module.im.service.websocket.dto.message.MaterialMessage;
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/ImChannelMessageDTO.java
1 package cn.iocoder.yudao.module.im.service.websocket.dto; 1 package cn.iocoder.yudao.module.im.service.websocket.dto;
2 2
3 import cn.iocoder.yudao.framework.common.util.object.BeanUtils; 3 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
4 -import cn.iocoder.yudao.module.im.dal.dataobject.channel.ImChannelMessageDO; 4 +import cn.iocoder.yudao.module.im.dal.dataobject.message.ImChannelMessageDO;
5 import lombok.Data; 5 import lombok.Data;
6 import lombok.experimental.Accessors; 6 import lombok.experimental.Accessors;
7 7
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/message/MaterialMessage.java
@@ -15,6 +15,14 @@ import lombok.experimental.Accessors; @@ -15,6 +15,14 @@ import lombok.experimental.Accessors;
15 public class MaterialMessage { 15 public class MaterialMessage {
16 16
17 /** 17 /**
  18 + * 素材内容类型
  19 + * <p>
  20 + * 枚举 {@link cn.iocoder.yudao.module.im.enums.channel.ImChannelMaterialContentTypeEnum}
  21 + * 客户端按本字段判定点击行为:CONTENT 走站内详情页拉富文本;LINK 跳 url
  22 + */
  23 + private Integer type;
  24 +
  25 + /**
18 * 标题 26 * 标题
19 */ 27 */
20 private String title; 28 private String title;
@@ -27,7 +35,7 @@ public class MaterialMessage { @@ -27,7 +35,7 @@ public class MaterialMessage {
27 */ 35 */
28 private String summary; 36 private String summary;
29 /** 37 /**
30 - * 跳转链接;为空时点击在客户端内置详情页按 materialId 拉 content 渲染;非空则跳 url 38 + * 跳转链接
31 */ 39 */
32 private String url; 40 private String url;
33 41
yudao-module-im/src/test/resources/sql/create_tables.sql
@@ -255,7 +255,7 @@ CREATE TABLE IF NOT EXISTS &quot;im_channel&quot; ( @@ -255,7 +255,7 @@ CREATE TABLE IF NOT EXISTS &quot;im_channel&quot; (
255 CREATE TABLE IF NOT EXISTS "im_channel_material" ( 255 CREATE TABLE IF NOT EXISTS "im_channel_material" (
256 "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY COMMENT '编号', 256 "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY COMMENT '编号',
257 "channel_id" bigint NOT NULL COMMENT '频道编号', 257 "channel_id" bigint NOT NULL COMMENT '频道编号',
258 - "type" smallint NOT NULL COMMENT '素材类型;对应 ImMessageTypeEnum', 258 + "type" tinyint NOT NULL COMMENT '内容类型;1 站内富文本 2 外链',
259 "title" varchar(128) NOT NULL COMMENT '标题', 259 "title" varchar(128) NOT NULL COMMENT '标题',
260 "cover_url" varchar(512) DEFAULT NULL COMMENT '封面图', 260 "cover_url" varchar(512) DEFAULT NULL COMMENT '封面图',
261 "summary" varchar(255) DEFAULT NULL COMMENT '摘要', 261 "summary" varchar(255) DEFAULT NULL COMMENT '摘要',
yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserController.java
@@ -116,7 +116,8 @@ public class UserController { @@ -116,7 +116,8 @@ public class UserController {
116 116
117 @GetMapping({"/list-all-simple", "/simple-list"}) 117 @GetMapping({"/list-all-simple", "/simple-list"})
118 @Operation(summary = "获取用户精简信息列表", description = "只包含被开启的用户,主要用于前端的下拉选项") 118 @Operation(summary = "获取用户精简信息列表", description = "只包含被开启的用户,主要用于前端的下拉选项")
119 - public CommonResult<List<UserSimpleRespVO>> getSimpleUserList(@RequestParam("id") Long deptId) { 119 + public CommonResult<List<UserSimpleRespVO>> getSimpleUserList(
  120 + @RequestParam(value = "deptId", required = false) Long deptId) {
120 List<AdminUserDO> list; 121 List<AdminUserDO> list;
121 if (deptId != null) { 122 if (deptId != null) {
122 List<Long> deptIds = Collections.singletonList(deptId); 123 List<Long> deptIds = Collections.singletonList(deptId);