Commit d89a19a92ba588724ae7858fc8488b1a6fdfac31

Authored by YunaiV
1 parent 2347bffe

【代码评审】商城:客服功能

Showing 16 changed files with 57 additions and 31 deletions
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/kehu/KeFuMessageContentTypeEnum.java
@@ -7,7 +7,7 @@ import lombok.Getter; @@ -7,7 +7,7 @@ import lombok.Getter;
7 import java.util.Arrays; 7 import java.util.Arrays;
8 8
9 /** 9 /**
10 - * 消息类型枚举 10 + * 客服消息的类型枚举
11 * 11 *
12 * @author HUIHUI 12 * @author HUIHUI
13 */ 13 */
@@ -19,7 +19,7 @@ public enum KeFuMessageContentTypeEnum implements IntArrayValuable { @@ -19,7 +19,7 @@ public enum KeFuMessageContentTypeEnum implements IntArrayValuable {
19 IMAGE(2, "图片消息"), 19 IMAGE(2, "图片消息"),
20 VOICE(3, "语音消息"), 20 VOICE(3, "语音消息"),
21 VIDEO(4, "视频消息"), 21 VIDEO(4, "视频消息"),
22 - // 和正常消息隔离下 22 + // ========== 商城特殊消息 ==========
23 PRODUCT(10, "商品消息"), 23 PRODUCT(10, "商品消息"),
24 ORDER(11, "订单消息"); 24 ORDER(11, "订单消息");
25 25
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/kefu/KeFuConversationController.java
@@ -27,6 +27,7 @@ public class KeFuConversationController { @@ -27,6 +27,7 @@ public class KeFuConversationController {
27 @Resource 27 @Resource
28 private KeFuConversationService conversationService; 28 private KeFuConversationService conversationService;
29 29
  30 + // TODO @puhui999:updateConversationPinned
30 @PostMapping("/update-pinned") 31 @PostMapping("/update-pinned")
31 @Operation(summary = "置顶客服会话") 32 @Operation(summary = "置顶客服会话")
32 @PreAuthorize("@ss.hasPermission('promotion:kefu-conversation:update')") 33 @PreAuthorize("@ss.hasPermission('promotion:kefu-conversation:update')")
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/kefu/KeFuMessageController.java
1 package cn.iocoder.yudao.module.promotion.controller.admin.kefu; 1 package cn.iocoder.yudao.module.promotion.controller.admin.kefu;
2 2
  3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  4 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  5 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
3 import cn.iocoder.yudao.module.promotion.controller.admin.kefu.vo.message.KeFuMessagePageReqVO; 6 import cn.iocoder.yudao.module.promotion.controller.admin.kefu.vo.message.KeFuMessagePageReqVO;
4 import cn.iocoder.yudao.module.promotion.controller.admin.kefu.vo.message.KeFuMessageRespVO; 7 import cn.iocoder.yudao.module.promotion.controller.admin.kefu.vo.message.KeFuMessageRespVO;
5 import cn.iocoder.yudao.module.promotion.controller.admin.kefu.vo.message.KeFuMessageSendReqVO; 8 import cn.iocoder.yudao.module.promotion.controller.admin.kefu.vo.message.KeFuMessageSendReqVO;
6 -import org.springframework.web.bind.annotation.*; 9 +import cn.iocoder.yudao.module.promotion.dal.dataobject.kefu.KeFuMessageDO;
  10 +import cn.iocoder.yudao.module.promotion.service.kefu.KeFuMessageService;
  11 +import io.swagger.v3.oas.annotations.Operation;
  12 +import io.swagger.v3.oas.annotations.Parameter;
  13 +import io.swagger.v3.oas.annotations.tags.Tag;
7 import jakarta.annotation.Resource; 14 import jakarta.annotation.Resource;
8 -import org.springframework.validation.annotation.Validated; 15 +import jakarta.validation.Valid;
9 import org.springframework.security.access.prepost.PreAuthorize; 16 import org.springframework.security.access.prepost.PreAuthorize;
10 -import io.swagger.v3.oas.annotations.tags.Tag;  
11 -import io.swagger.v3.oas.annotations.Parameter;  
12 -import io.swagger.v3.oas.annotations.Operation;  
13 -  
14 -import jakarta.validation.*; 17 +import org.springframework.validation.annotation.Validated;
  18 +import org.springframework.web.bind.annotation.*;
15 19
16 -import cn.iocoder.yudao.framework.common.pojo.PageResult;  
17 -import cn.iocoder.yudao.framework.common.pojo.CommonResult;  
18 -import cn.iocoder.yudao.framework.common.util.object.BeanUtils;  
19 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; 20 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
20 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; 21 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
21 22
22 -import cn.iocoder.yudao.module.promotion.dal.dataobject.kefu.KeFuMessageDO;  
23 -import cn.iocoder.yudao.module.promotion.service.kefu.KeFuMessageService;  
24 -  
25 @Tag(name = "管理后台 - 客服消息") 23 @Tag(name = "管理后台 - 客服消息")
26 @RestController 24 @RestController
27 @RequestMapping("/promotion/kefu-message") 25 @RequestMapping("/promotion/kefu-message")
@@ -47,6 +45,7 @@ public class KeFuMessageController { @@ -47,6 +45,7 @@ public class KeFuMessageController {
47 return success(true); 45 return success(true);
48 } 46 }
49 47
  48 + // TODO @puhui999:这个应该是某个会话,上翻、下翻;不是传统的分页哈;
50 @GetMapping("/page") 49 @GetMapping("/page")
51 @Operation(summary = "获得客服消息分页") 50 @Operation(summary = "获得客服消息分页")
52 @PreAuthorize("@ss.hasPermission('promotion:kefu-message:query')") 51 @PreAuthorize("@ss.hasPermission('promotion:kefu-message:query')")
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/kefu/vo/conversation/KeFuConversationRespVO.java
@@ -15,9 +15,11 @@ public class KeFuConversationRespVO { @@ -15,9 +15,11 @@ public class KeFuConversationRespVO {
15 @Schema(description = "会话所属用户", requiredMode = Schema.RequiredMode.REQUIRED, example = "8300") 15 @Schema(description = "会话所属用户", requiredMode = Schema.RequiredMode.REQUIRED, example = "8300")
16 private Long userId; 16 private Long userId;
17 17
18 - @Schema(description = "最后聊天时间", requiredMode = Schema.RequiredMode.REQUIRED,example = "2024-01-01 00:00:00") 18 + @Schema(description = "最后聊天时间", requiredMode = Schema.RequiredMode.REQUIRED)
19 private LocalDateTime lastMessageTime; 19 private LocalDateTime lastMessageTime;
20 20
  21 + // TODO @puhui999:, 缺了空格哈
  22 +
21 @Schema(description = "最后聊天内容", requiredMode = Schema.RequiredMode.REQUIRED,example = "嗨,您好啊") 23 @Schema(description = "最后聊天内容", requiredMode = Schema.RequiredMode.REQUIRED,example = "嗨,您好啊")
22 private String lastMessageContent; 24 private String lastMessageContent;
23 25
@@ -36,7 +38,7 @@ public class KeFuConversationRespVO { @@ -36,7 +38,7 @@ public class KeFuConversationRespVO {
36 @Schema(description = "管理员未读消息数", requiredMode = Schema.RequiredMode.REQUIRED,example = "6") 38 @Schema(description = "管理员未读消息数", requiredMode = Schema.RequiredMode.REQUIRED,example = "6")
37 private Integer adminUnreadMessageCount; 39 private Integer adminUnreadMessageCount;
38 40
39 - @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED,example = "2024-01-01 00:00:00") 41 + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
40 private LocalDateTime createTime; 42 private LocalDateTime createTime;
41 43
42 } 44 }
43 \ No newline at end of file 45 \ No newline at end of file
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/kefu/vo/conversation/KeFuConversationUpdatePinnedReqVO.java
@@ -9,11 +9,11 @@ import lombok.Data; @@ -9,11 +9,11 @@ import lombok.Data;
9 public class KeFuConversationUpdatePinnedReqVO { 9 public class KeFuConversationUpdatePinnedReqVO {
10 10
11 @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "23202") 11 @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "23202")
12 - @NotNull(message = "会话编号,不能为空") 12 + @NotNull(message = "会话编号不能为空")
13 private Long id; 13 private Long id;
14 14
15 @Schema(description = "管理端置顶", requiredMode = Schema.RequiredMode.REQUIRED, example = "false") 15 @Schema(description = "管理端置顶", requiredMode = Schema.RequiredMode.REQUIRED, example = "false")
16 - @NotNull(message = "管理端置顶,不能为空") 16 + @NotNull(message = "管理端置顶不能为空")
17 private Boolean adminPinned; 17 private Boolean adminPinned;
18 18
19 } 19 }
20 \ No newline at end of file 20 \ No newline at end of file
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/kefu/vo/message/KeFuMessagePageReqVO.java
@@ -6,6 +6,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageParam; @@ -6,6 +6,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageParam;
6 6
7 @Schema(description = "管理后台 - 客服消息分页 Request VO") 7 @Schema(description = "管理后台 - 客服消息分页 Request VO")
8 @Data 8 @Data
  9 +// TODO @puhui999:不用 @EqualsAndHashCode 哈
9 @EqualsAndHashCode(callSuper = true) 10 @EqualsAndHashCode(callSuper = true)
10 @ToString(callSuper = true) 11 @ToString(callSuper = true)
11 public class KeFuMessagePageReqVO extends PageParam { 12 public class KeFuMessagePageReqVO extends PageParam {
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/kefu/vo/message/KeFuMessageSendReqVO.java
@@ -9,6 +9,8 @@ import lombok.Data; @@ -9,6 +9,8 @@ import lombok.Data;
9 @Data 9 @Data
10 public class KeFuMessageSendReqVO { 10 public class KeFuMessageSendReqVO {
11 11
  12 + // TODO @puhui999:貌似字段多了;1)id 不用;2)senderId、senderType 不用;3)receiverId、receiverType 也不用;原因可以想下哈
  13 +
12 @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "23202") 14 @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "23202")
13 private Long id; 15 private Long id;
14 16
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/kefu/AppKeFuConversationController.java
@@ -25,10 +25,12 @@ public class AppKeFuConversationController { @@ -25,10 +25,12 @@ public class AppKeFuConversationController {
25 @Resource 25 @Resource
26 private KeFuConversationService conversationService; 26 private KeFuConversationService conversationService;
27 27
  28 + // TODO @puhui999:接口名不对噢;
28 @GetMapping("/get") 29 @GetMapping("/get")
29 @Operation(summary = "获得客服会话") 30 @Operation(summary = "获得客服会话")
30 @PreAuthenticated 31 @PreAuthenticated
31 public CommonResult<AppKeFuConversationRespVO> getDiyPage() { 32 public CommonResult<AppKeFuConversationRespVO> getDiyPage() {
  33 + // TODO @puhui999:建议获取;和转换,分成 2 个哈;干净一些;
32 return success(BeanUtils.toBean(conversationService.getOrCreateConversation(getLoginUserId()), AppKeFuConversationRespVO.class)); 34 return success(BeanUtils.toBean(conversationService.getOrCreateConversation(getLoginUserId()), AppKeFuConversationRespVO.class));
33 } 35 }
34 36
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/kefu/vo/message/AppKeFuMessagePageReqVO.java
@@ -8,6 +8,7 @@ import lombok.ToString; @@ -8,6 +8,7 @@ import lombok.ToString;
8 8
9 @Schema(description = "用户 App - 客服消息分页 Request VO") 9 @Schema(description = "用户 App - 客服消息分页 Request VO")
10 @Data 10 @Data
  11 +// TODO @puhui999:不用 @EqualsAndHashCode 哈
11 @EqualsAndHashCode(callSuper = true) 12 @EqualsAndHashCode(callSuper = true)
12 @ToString(callSuper = true) 13 @ToString(callSuper = true)
13 public class AppKeFuMessagePageReqVO extends PageParam { 14 public class AppKeFuMessagePageReqVO extends PageParam {
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/kefu/KeFuConversationMapper.java
@@ -16,6 +16,7 @@ import java.util.List; @@ -16,6 +16,7 @@ import java.util.List;
16 @Mapper 16 @Mapper
17 public interface KeFuConversationMapper extends BaseMapperX<KeFuConversationDO> { 17 public interface KeFuConversationMapper extends BaseMapperX<KeFuConversationDO> {
18 18
  19 + // TODO @puhui999:排序可以交给前端,或者 controller;数据库的计算尽量少哈;
19 default List<KeFuConversationDO> selectListWithSort() { 20 default List<KeFuConversationDO> selectListWithSort() {
20 return selectList(new LambdaQueryWrapperX<KeFuConversationDO>() 21 return selectList(new LambdaQueryWrapperX<KeFuConversationDO>()
21 .eq(KeFuConversationDO::getAdminDeleted, Boolean.FALSE) 22 .eq(KeFuConversationDO::getAdminDeleted, Boolean.FALSE)
@@ -23,6 +24,7 @@ public interface KeFuConversationMapper extends BaseMapperX&lt;KeFuConversationDO&gt; @@ -23,6 +24,7 @@ public interface KeFuConversationMapper extends BaseMapperX&lt;KeFuConversationDO&gt;
23 .orderByDesc(KeFuConversationDO::getCreateTime)); 24 .orderByDesc(KeFuConversationDO::getCreateTime));
24 } 25 }
25 26
  27 + // TODO @puhui999:是不是置零,用 update 就 ok 拉;然后单独搞个 +1 的方法;
26 default void updateAdminUnreadMessageCountByConversationId(Long id, Integer count) { 28 default void updateAdminUnreadMessageCountByConversationId(Long id, Integer count) {
27 LambdaUpdateWrapper<KeFuConversationDO> updateWrapper = new LambdaUpdateWrapper<>(); 29 LambdaUpdateWrapper<KeFuConversationDO> updateWrapper = new LambdaUpdateWrapper<>();
28 updateWrapper.eq(KeFuConversationDO::getId, id); 30 updateWrapper.eq(KeFuConversationDO::getId, id);
@@ -31,7 +33,6 @@ public interface KeFuConversationMapper extends BaseMapperX&lt;KeFuConversationDO&gt; @@ -31,7 +33,6 @@ public interface KeFuConversationMapper extends BaseMapperX&lt;KeFuConversationDO&gt;
31 } else { // 情况二:管理员已读后重置 33 } else { // 情况二:管理员已读后重置
32 updateWrapper.set(KeFuConversationDO::getAdminUnreadMessageCount, 0); 34 updateWrapper.set(KeFuConversationDO::getAdminUnreadMessageCount, 0);
33 } 35 }
34 -  
35 update(updateWrapper); 36 update(updateWrapper);
36 } 37 }
37 38
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/kefu/KeFuMessageMapper.java
@@ -26,13 +26,16 @@ public interface KeFuMessageMapper extends BaseMapperX&lt;KeFuMessageDO&gt; { @@ -26,13 +26,16 @@ public interface KeFuMessageMapper extends BaseMapperX&lt;KeFuMessageDO&gt; {
26 .orderByDesc(KeFuMessageDO::getId)); 26 .orderByDesc(KeFuMessageDO::getId));
27 } 27 }
28 28
29 - default List<KeFuMessageDO> selectListByConversationIdAndReceiverIdAndReadStatus(Long conversationId, Long receiverId, Boolean readStatus) { 29 + default List<KeFuMessageDO> selectListByConversationIdAndReceiverIdAndReadStatus(Long conversationId,
  30 + Long receiverId,
  31 + Boolean readStatus) {
30 return selectList(new LambdaQueryWrapper<KeFuMessageDO>() 32 return selectList(new LambdaQueryWrapper<KeFuMessageDO>()
31 .eq(KeFuMessageDO::getConversationId, conversationId) 33 .eq(KeFuMessageDO::getConversationId, conversationId)
32 .eq(KeFuMessageDO::getReceiverId, receiverId) 34 .eq(KeFuMessageDO::getReceiverId, receiverId)
33 .eq(KeFuMessageDO::getReadStatus, readStatus)); 35 .eq(KeFuMessageDO::getReadStatus, readStatus));
34 } 36 }
35 37
  38 + // TODO @puhui999:status 拼写不对哈;ps:是不是搞个 ids + entity 的更新,更通用点
36 default void updateReadStstusBatchByIds(Collection<Long> ids, Boolean readStatus) { 39 default void updateReadStstusBatchByIds(Collection<Long> ids, Boolean readStatus) {
37 update(new LambdaUpdateWrapper<KeFuMessageDO>() 40 update(new LambdaUpdateWrapper<KeFuMessageDO>()
38 .in(KeFuMessageDO::getId, ids) 41 .in(KeFuMessageDO::getId, ids)
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/kefu/KeFuConversationService.java
@@ -6,6 +6,7 @@ import cn.iocoder.yudao.module.promotion.dal.dataobject.kefu.KeFuConversationDO; @@ -6,6 +6,7 @@ import cn.iocoder.yudao.module.promotion.dal.dataobject.kefu.KeFuConversationDO;
6 import java.time.LocalDateTime; 6 import java.time.LocalDateTime;
7 import java.util.List; 7 import java.util.List;
8 8
  9 +// TODO @puhui999:可以在每个方法前面,加个【会员】【管理员】区分下
9 /** 10 /**
10 * 客服会话 Service 接口 11 * 客服会话 Service 接口
11 * 12 *
@@ -20,6 +21,7 @@ public interface KeFuConversationService { @@ -20,6 +21,7 @@ public interface KeFuConversationService {
20 */ 21 */
21 void deleteKefuConversation(Long id); 22 void deleteKefuConversation(Long id);
22 23
  24 + // TODO @puhui999:是不是方法名,体现出更新的是管理员的置顶哈
23 /** 25 /**
24 * 客服会话置顶 26 * 客服会话置顶
25 * 27 *
@@ -27,6 +29,7 @@ public interface KeFuConversationService { @@ -27,6 +29,7 @@ public interface KeFuConversationService {
27 */ 29 */
28 void updatePinned(KeFuConversationUpdatePinnedReqVO updateReqVO); 30 void updatePinned(KeFuConversationUpdatePinnedReqVO updateReqVO);
29 31
  32 + // TODO @puhui999:updateConversationLastMessage 会好点哈
30 /** 33 /**
31 * 更新会话客服消息冗余信息 34 * 更新会话客服消息冗余信息
32 * 35 *
@@ -60,7 +63,9 @@ public interface KeFuConversationService { @@ -60,7 +63,9 @@ public interface KeFuConversationService {
60 List<KeFuConversationDO> getKefuConversationList(); 63 List<KeFuConversationDO> getKefuConversationList();
61 64
62 /** 65 /**
63 - * 获得或创建会话 66 + * 【会员】获得或创建会话
  67 + *
  68 + * 对于【会员】来说,有且仅有一个对话
64 * 69 *
65 * @param userId 用户编号 70 * @param userId 用户编号
66 * @return 客服会话 71 * @return 客服会话
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/kefu/KeFuConversationServiceImpl.java
@@ -37,7 +37,6 @@ public class KeFuConversationServiceImpl implements KeFuConversationService { @@ -37,7 +37,6 @@ public class KeFuConversationServiceImpl implements KeFuConversationService {
37 37
38 @Override 38 @Override
39 public void updatePinned(KeFuConversationUpdatePinnedReqVO updateReqVO) { 39 public void updatePinned(KeFuConversationUpdatePinnedReqVO updateReqVO) {
40 - // 只有管理员端可以置顶会话  
41 conversationMapper.updateById(new KeFuConversationDO().setId(updateReqVO.getId()).setAdminPinned(updateReqVO.getAdminPinned())); 40 conversationMapper.updateById(new KeFuConversationDO().setId(updateReqVO.getId()).setAdminPinned(updateReqVO.getAdminPinned()));
42 } 41 }
43 42
@@ -62,10 +61,12 @@ public class KeFuConversationServiceImpl implements KeFuConversationService { @@ -62,10 +61,12 @@ public class KeFuConversationServiceImpl implements KeFuConversationService {
62 return conversationMapper.selectListWithSort(); 61 return conversationMapper.selectListWithSort();
63 } 62 }
64 63
  64 + // TODO @puhui999:貌似这个对话,得用户主动创建。不然管理员会看到一个空的对话?
65 @Override 65 @Override
66 public KeFuConversationDO getOrCreateConversation(Long userId) { 66 public KeFuConversationDO getOrCreateConversation(Long userId) {
67 KeFuConversationDO conversation = conversationMapper.selectOne(KeFuConversationDO::getUserId, userId); 67 KeFuConversationDO conversation = conversationMapper.selectOne(KeFuConversationDO::getUserId, userId);
68 - if (conversation == null) { // 没有历史会话则初始化一个新会话 68 + // 没有历史会话,则初始化一个新会话
  69 + if (conversation == null) {
69 conversation = new KeFuConversationDO().setUserId(userId).setLastMessageTime(LocalDateTime.now()) 70 conversation = new KeFuConversationDO().setUserId(userId).setLastMessageTime(LocalDateTime.now())
70 .setLastMessageContent("").setLastMessageContentType(KeFuMessageContentTypeEnum.TEXT.getType()) 71 .setLastMessageContent("").setLastMessageContentType(KeFuMessageContentTypeEnum.TEXT.getType())
71 .setAdminPinned(Boolean.FALSE).setUserDeleted(Boolean.FALSE).setAdminDeleted(Boolean.FALSE) 72 .setAdminPinned(Boolean.FALSE).setUserDeleted(Boolean.FALSE).setAdminDeleted(Boolean.FALSE)
@@ -77,12 +78,11 @@ public class KeFuConversationServiceImpl implements KeFuConversationService { @@ -77,12 +78,11 @@ public class KeFuConversationServiceImpl implements KeFuConversationService {
77 78
78 @Override 79 @Override
79 public KeFuConversationDO validateKefuConversationExists(Long id) { 80 public KeFuConversationDO validateKefuConversationExists(Long id) {
80 - KeFuConversationDO conversationDO = conversationMapper.selectById(id);  
81 - if (conversationDO == null) { 81 + KeFuConversationDO conversation = conversationMapper.selectById(id);
  82 + if (conversation == null) {
82 throw exception(KEFU_CONVERSATION_NOT_EXISTS); 83 throw exception(KEFU_CONVERSATION_NOT_EXISTS);
83 } 84 }
84 -  
85 - return conversationDO; 85 + return conversation;
86 } 86 }
87 87
88 } 88 }
89 \ No newline at end of file 89 \ No newline at end of file
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/kefu/KeFuMessageService.java
@@ -6,6 +6,7 @@ import cn.iocoder.yudao.module.promotion.controller.admin.kefu.vo.message.KeFuMe @@ -6,6 +6,7 @@ import cn.iocoder.yudao.module.promotion.controller.admin.kefu.vo.message.KeFuMe
6 import cn.iocoder.yudao.module.promotion.dal.dataobject.kefu.KeFuMessageDO; 6 import cn.iocoder.yudao.module.promotion.dal.dataobject.kefu.KeFuMessageDO;
7 import jakarta.validation.Valid; 7 import jakarta.validation.Valid;
8 8
  9 +// TODO @puhui999:可以在每个方法前面,加个【会员】【管理员】区分下
9 /** 10 /**
10 * 客服消息 Service 接口 11 * 客服消息 Service 接口
11 * 12 *
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/kefu/KeFuMessageServiceImpl.java
@@ -34,12 +34,16 @@ import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils. @@ -34,12 +34,16 @@ import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.
34 @Validated 34 @Validated
35 public class KeFuMessageServiceImpl implements KeFuMessageService { 35 public class KeFuMessageServiceImpl implements KeFuMessageService {
36 36
  37 + // TODO @puhui999:@芋艿:捉摸要不要拿到一个地方枚举;
37 private static final String KEFU_MESSAGE_TYPE = "kefu_message_type"; // 客服消息类型 38 private static final String KEFU_MESSAGE_TYPE = "kefu_message_type"; // 客服消息类型
38 39
  40 + // TODO @puhui999:kefuMessageMapper;因为 messageMapper 可能会重叠
39 @Resource 41 @Resource
40 private KeFuMessageMapper messageMapper; 42 private KeFuMessageMapper messageMapper;
  43 +
41 @Resource 44 @Resource
42 private KeFuConversationService conversationService; 45 private KeFuConversationService conversationService;
  46 +
43 @Resource 47 @Resource
44 private AdminUserApi adminUserApi; 48 private AdminUserApi adminUserApi;
45 @Resource 49 @Resource
@@ -58,6 +62,7 @@ public class KeFuMessageServiceImpl implements KeFuMessageService { @@ -58,6 +62,7 @@ public class KeFuMessageServiceImpl implements KeFuMessageService {
58 // 2.1 保存消息 62 // 2.1 保存消息
59 KeFuMessageDO kefuMessage = BeanUtils.toBean(sendReqVO, KeFuMessageDO.class); 63 KeFuMessageDO kefuMessage = BeanUtils.toBean(sendReqVO, KeFuMessageDO.class);
60 messageMapper.insert(kefuMessage); 64 messageMapper.insert(kefuMessage);
  65 + // TODO @puhui999:是不是 updateConversationMessage,里面统一处理未读、恢复;直接设置 KeFuMessageDO 作为参数好了。。。
61 // 2.2 更新会话消息冗余 66 // 2.2 更新会话消息冗余
62 conversationService.updateConversationMessage(kefuMessage.getConversationId(), LocalDateTime.now(), 67 conversationService.updateConversationMessage(kefuMessage.getConversationId(), LocalDateTime.now(),
63 kefuMessage.getContent(), kefuMessage.getContentType()); 68 kefuMessage.getContent(), kefuMessage.getContentType());
@@ -66,14 +71,13 @@ public class KeFuMessageServiceImpl implements KeFuMessageService { @@ -66,14 +71,13 @@ public class KeFuMessageServiceImpl implements KeFuMessageService {
66 conversationService.updateAdminUnreadMessageCountByConversationId(kefuMessage.getConversationId(), 1); 71 conversationService.updateAdminUnreadMessageCountByConversationId(kefuMessage.getConversationId(), 1);
67 } 72 }
68 // 2.4 会员用户发送消息时,如果管理员删除过会话则进行恢复 73 // 2.4 会员用户发送消息时,如果管理员删除过会话则进行恢复
  74 + // TODO @puhui999:建议 && 换一行
69 if (UserTypeEnum.MEMBER.getValue().equals(kefuMessage.getSenderType()) && Boolean.TRUE.equals(conversation.getAdminDeleted())) { 75 if (UserTypeEnum.MEMBER.getValue().equals(kefuMessage.getSenderType()) && Boolean.TRUE.equals(conversation.getAdminDeleted())) {
70 conversationService.updateConversationAdminDeleted(kefuMessage.getConversationId(), Boolean.FALSE); 76 conversationService.updateConversationAdminDeleted(kefuMessage.getConversationId(), Boolean.FALSE);
71 } 77 }
72 78
73 // 3. 发送消息 79 // 3. 发送消息
74 getSelf().sendAsyncMessage(sendReqVO.getReceiverType(), sendReqVO.getReceiverId(), kefuMessage); 80 getSelf().sendAsyncMessage(sendReqVO.getReceiverType(), sendReqVO.getReceiverId(), kefuMessage);
75 -  
76 - // 返回  
77 return kefuMessage.getId(); 81 return kefuMessage.getId();
78 } 82 }
79 83
@@ -83,6 +87,7 @@ public class KeFuMessageServiceImpl implements KeFuMessageService { @@ -83,6 +87,7 @@ public class KeFuMessageServiceImpl implements KeFuMessageService {
83 // 1.1 校验会话是否存在 87 // 1.1 校验会话是否存在
84 conversationService.validateKefuConversationExists(conversationId); 88 conversationService.validateKefuConversationExists(conversationId);
85 // 1.2 查询接收人所有的未读消息 89 // 1.2 查询接收人所有的未读消息
  90 + // TODO @puhui999:应该不能 receiverId 过滤哈。因为多个客服,一个人点了,就都点了。
86 List<KeFuMessageDO> messageList = messageMapper.selectListByConversationIdAndReceiverIdAndReadStatus( 91 List<KeFuMessageDO> messageList = messageMapper.selectListByConversationIdAndReceiverIdAndReadStatus(
87 conversationId, receiverId, Boolean.FALSE); 92 conversationId, receiverId, Boolean.FALSE);
88 // 1.3 情况一:没有未读消息 93 // 1.3 情况一:没有未读消息
@@ -98,7 +103,9 @@ public class KeFuMessageServiceImpl implements KeFuMessageService { @@ -98,7 +103,9 @@ public class KeFuMessageServiceImpl implements KeFuMessageService {
98 if (UserTypeEnum.ADMIN.getValue().equals(message.getReceiverType())) { 103 if (UserTypeEnum.ADMIN.getValue().equals(message.getReceiverType())) {
99 conversationService.updateAdminUnreadMessageCountByConversationId(conversationId, 0); 104 conversationService.updateAdminUnreadMessageCountByConversationId(conversationId, 0);
100 } 105 }
  106 +
101 // 2.3 发送消息通知发送者,接收者已读 -> 发送者更新发送的消息状态 107 // 2.3 发送消息通知发送者,接收者已读 -> 发送者更新发送的消息状态
  108 + // TODO @puhui999:待定~
102 getSelf().sendAsyncMessage(message.getSenderType(), message.getSenderId(), "keFuMessageReadStatusChange"); 109 getSelf().sendAsyncMessage(message.getSenderType(), message.getSenderId(), "keFuMessageReadStatusChange");
103 } 110 }
104 111
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageUserServiceImpl.java
@@ -131,8 +131,9 @@ public class BrokerageUserServiceImpl implements BrokerageUserService { @@ -131,8 +131,9 @@ public class BrokerageUserServiceImpl implements BrokerageUserService {
131 @Override 131 @Override
132 public BrokerageUserDO getOrCreateBrokerageUser(Long id) { 132 public BrokerageUserDO getOrCreateBrokerageUser(Long id) {
133 BrokerageUserDO brokerageUser = brokerageUserMapper.selectById(id); 133 BrokerageUserDO brokerageUser = brokerageUserMapper.selectById(id);
  134 + // 特殊:人人分销的情况下,如果分销人为空则创建分销人
134 if (brokerageUser == null && ObjUtil.equal(BrokerageEnabledConditionEnum.ALL.getCondition(), 135 if (brokerageUser == null && ObjUtil.equal(BrokerageEnabledConditionEnum.ALL.getCondition(),
135 - tradeConfigService.getTradeConfig().getBrokerageEnabledCondition())) { // 人人分销的情况下,如果分销人为空则创建分销人 136 + tradeConfigService.getTradeConfig().getBrokerageEnabledCondition())) {
136 brokerageUser = new BrokerageUserDO().setId(id).setBrokerageEnabled(true).setBrokeragePrice(0) 137 brokerageUser = new BrokerageUserDO().setId(id).setBrokerageEnabled(true).setBrokeragePrice(0)
137 .setBrokerageTime(LocalDateTime.now()).setFrozenPrice(0); 138 .setBrokerageTime(LocalDateTime.now()).setFrozenPrice(0);
138 brokerageUserMapper.insert(brokerageUser); 139 brokerageUserMapper.insert(brokerageUser);