parent
2a42c9de00
commit
30a1d1f557
20 changed files with 1114 additions and 11 deletions
@ -0,0 +1,79 @@ |
|||||||
|
package com.teaching.backend.controller.message; |
||||||
|
|
||||||
|
|
||||||
|
import com.teaching.backend.common.BaseResponse; |
||||||
|
import com.teaching.backend.common.ResultUtils; |
||||||
|
import com.teaching.backend.filter.ValidateParams; |
||||||
|
import com.teaching.backend.model.dto.courses.PageDTO; |
||||||
|
import com.teaching.backend.model.dto.message.SysMessageDTO; |
||||||
|
import com.teaching.backend.model.entity.message.SysMessages; |
||||||
|
import com.teaching.backend.model.query.CourseQuery; |
||||||
|
import com.teaching.backend.model.query.MessagesQuery; |
||||||
|
import com.teaching.backend.model.vo.courses.CoursesVO; |
||||||
|
import com.teaching.backend.model.vo.message.SysMessageVO; |
||||||
|
import com.teaching.backend.service.message.IMessagesService; |
||||||
|
import io.swagger.annotations.Api; |
||||||
|
import io.swagger.annotations.ApiOperation; |
||||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||||
|
import org.springframework.web.bind.annotation.*; |
||||||
|
|
||||||
|
import java.time.LocalDateTime; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* <p> |
||||||
|
* 前端控制器 |
||||||
|
* </p> |
||||||
|
* |
||||||
|
* @author zjh |
||||||
|
* @since 2024-08-06 |
||||||
|
*/ |
||||||
|
@Api(tags = "系统消息管理接口") |
||||||
|
@RestController |
||||||
|
@RequestMapping("/messages") |
||||||
|
public class MessagesController { |
||||||
|
|
||||||
|
@Autowired |
||||||
|
private IMessagesService messagesService; |
||||||
|
|
||||||
|
@ApiOperation("发送消息") |
||||||
|
@ValidateParams({"senderId","title","content","receiverId"}) // 需要校验的参数
|
||||||
|
@PostMapping("/addmessage") |
||||||
|
public BaseResponse<String> sendMessage(@RequestBody SysMessageDTO sysMessageDTO){ |
||||||
|
String data = messagesService.sendMessageToUserInbox(sysMessageDTO); |
||||||
|
return ResultUtils.success(data); |
||||||
|
} |
||||||
|
|
||||||
|
//TODO 功能待完善
|
||||||
|
@ApiOperation("删除发件箱的消息--批删--逻辑删除") |
||||||
|
@ValidateParams({"messageIds"}) // 需要校验的参数
|
||||||
|
@DeleteMapping ("/deletesendmessage") |
||||||
|
public BaseResponse<String> deleteMessages(@RequestParam List<Long> messageIds){ |
||||||
|
String data = messagesService.deleteSendMessagesByLogical(messageIds); |
||||||
|
return ResultUtils.success(data); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ApiOperation("根据id查询消息") |
||||||
|
@ValidateParams({"id"}) // 需要校验的参数
|
||||||
|
@GetMapping ("/getmessage/{id}") |
||||||
|
public BaseResponse<SysMessages> getMessageById(@PathVariable("id") Long id){ |
||||||
|
SysMessages data = messagesService.getById(id); |
||||||
|
return ResultUtils.success(data); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 修改消息 |
||||||
|
* @param sysMessageDTO |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
@ApiOperation("修改消息--仅限于未发送成功的消息(草稿功能)") |
||||||
|
@PutMapping ("/modifymessage") |
||||||
|
public BaseResponse<String> modifyMessage(@RequestBody SysMessageDTO sysMessageDTO){ |
||||||
|
boolean b = messagesService.updateById(sysMessageDTO); |
||||||
|
return ResultUtils.success(b ? "修改成功" : "修改失败"); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
} |
@ -0,0 +1,83 @@ |
|||||||
|
package com.teaching.backend.controller.message; |
||||||
|
|
||||||
|
|
||||||
|
import com.teaching.backend.common.BaseResponse; |
||||||
|
import com.teaching.backend.common.ResultUtils; |
||||||
|
import com.teaching.backend.filter.ValidateParams; |
||||||
|
import com.teaching.backend.model.dto.courses.PageDTO; |
||||||
|
import com.teaching.backend.model.query.MessagesQuery; |
||||||
|
import com.teaching.backend.model.vo.message.SysMessageVO; |
||||||
|
import com.teaching.backend.service.message.IUserInboxService; |
||||||
|
import io.swagger.annotations.Api; |
||||||
|
import io.swagger.annotations.ApiOperation; |
||||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||||
|
import org.springframework.web.bind.annotation.*; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* <p> |
||||||
|
* 前端控制器 |
||||||
|
* </p> |
||||||
|
* |
||||||
|
* @author zjh |
||||||
|
* @since 2024-08-06 |
||||||
|
*/ |
||||||
|
@Api(tags = "用户信箱管理接口") |
||||||
|
@RestController |
||||||
|
@RequestMapping("/user-inbox") |
||||||
|
public class UserInboxController { |
||||||
|
|
||||||
|
|
||||||
|
@Autowired |
||||||
|
private IUserInboxService userInboxService; |
||||||
|
@ApiOperation("用户分页查看个人消息(收件箱)") |
||||||
|
@ValidateParams({"userId","isDelete"}) // 需要校验的参数
|
||||||
|
@GetMapping("/page/receivemessages") |
||||||
|
public BaseResponse<PageDTO<SysMessageVO>> getMessages(MessagesQuery messagesQuery){ |
||||||
|
PageDTO<SysMessageVO> messageList = userInboxService.queryReceiveMessages(messagesQuery); |
||||||
|
return ResultUtils.success(messageList); |
||||||
|
} |
||||||
|
|
||||||
|
@ApiOperation("用户分页查看个人消息(发件箱)") |
||||||
|
@ValidateParams({"userId","isDelete","isSend"}) |
||||||
|
@GetMapping("/page/sendmessages") |
||||||
|
public BaseResponse<PageDTO<SysMessageVO>> getSendMessages(MessagesQuery messagesQuery){ |
||||||
|
PageDTO<SysMessageVO> messageList = userInboxService.querySendMessages(messagesQuery); |
||||||
|
return ResultUtils.success(messageList); |
||||||
|
} |
||||||
|
|
||||||
|
//用户查看消息详情,如果是第一次查看,则会更新“已读状态”和“阅读时间”
|
||||||
|
@ApiOperation("查看消息详情") |
||||||
|
@ValidateParams({"userId","messageId"}) // 需要校验的参数
|
||||||
|
@GetMapping("/getmessagedetails") |
||||||
|
public BaseResponse<SysMessageVO> getMessageDetail(MessagesQuery messagesQuery){ |
||||||
|
SysMessageVO userCheckMessageVO = userInboxService.getMessageDetail(messagesQuery); |
||||||
|
return ResultUtils.success(userCheckMessageVO); |
||||||
|
} |
||||||
|
|
||||||
|
@ApiOperation("获取已读/未读用户集合") |
||||||
|
@ValidateParams({"userId", "messageId"}) |
||||||
|
@GetMapping("/message/readstatus") |
||||||
|
public BaseResponse<SysMessageVO> getMessageReadStatus(@RequestParam Long userId, @RequestParam Long messageId) { |
||||||
|
SysMessageVO messageVO = userInboxService.getReadStatus(userId, messageId); |
||||||
|
return ResultUtils.success(messageVO); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@ApiOperation("一键已读") |
||||||
|
@PutMapping ("/readmessagesbatch") |
||||||
|
public BaseResponse<String> readMessagesBatch(@RequestParam List<Long> messageIds, @RequestParam Long userId){ |
||||||
|
String data = userInboxService.readMessagesBatch(messageIds,userId); |
||||||
|
return ResultUtils.success(data); |
||||||
|
} |
||||||
|
|
||||||
|
@ApiOperation("删除收件箱的消息--批删--逻辑删除") |
||||||
|
@ValidateParams({"messageIds","userId"}) // 需要校验的参数
|
||||||
|
@DeleteMapping ("/deletereceivemessage") |
||||||
|
public BaseResponse<String> deleteReceiveMessages(@RequestParam List<Long> messageIds,@RequestParam Long userId){ |
||||||
|
String data = userInboxService.deleteReceiveMessagesByLogical(messageIds,userId); |
||||||
|
return ResultUtils.success(data); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,16 @@ |
|||||||
|
package com.teaching.backend.mapper.message; |
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
||||||
|
import com.teaching.backend.model.entity.message.SysMessages; |
||||||
|
|
||||||
|
/** |
||||||
|
* <p> |
||||||
|
* Mapper 接口 |
||||||
|
* </p> |
||||||
|
* |
||||||
|
* @author zjh |
||||||
|
* @since 2024-08-06 |
||||||
|
*/ |
||||||
|
public interface MessagesMapper extends BaseMapper<SysMessages> { |
||||||
|
|
||||||
|
} |
@ -0,0 +1,19 @@ |
|||||||
|
package com.teaching.backend.mapper.message; |
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
||||||
|
import com.teaching.backend.model.entity.message.UserInbox; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* <p> |
||||||
|
* Mapper 接口 |
||||||
|
* </p> |
||||||
|
* |
||||||
|
* @author zjh |
||||||
|
* @since 2024-08-06 |
||||||
|
*/ |
||||||
|
public interface UserInboxMapper extends BaseMapper<UserInbox> { |
||||||
|
|
||||||
|
boolean insertBatchInBox(List<UserInbox> userInboxes); |
||||||
|
} |
@ -0,0 +1,14 @@ |
|||||||
|
package com.teaching.backend.model.dto.message; |
||||||
|
|
||||||
|
import com.teaching.backend.model.entity.message.SysMessages; |
||||||
|
import io.swagger.annotations.ApiModel; |
||||||
|
import lombok.Data; |
||||||
|
|
||||||
|
@Data |
||||||
|
@ApiModel(description = "教师创建课程参数实体") |
||||||
|
public class SysMessageDTO extends SysMessages { |
||||||
|
/** |
||||||
|
* 收件人id集合 |
||||||
|
*/ |
||||||
|
private String receiverId; |
||||||
|
} |
@ -0,0 +1,56 @@ |
|||||||
|
package com.teaching.backend.model.entity.message; |
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName; |
||||||
|
import com.baomidou.mybatisplus.annotation.IdType; |
||||||
|
import com.baomidou.mybatisplus.annotation.TableId; |
||||||
|
import java.time.LocalDateTime; |
||||||
|
import java.io.Serializable; |
||||||
|
import io.swagger.annotations.ApiModel; |
||||||
|
import io.swagger.annotations.ApiModelProperty; |
||||||
|
import lombok.Data; |
||||||
|
import lombok.EqualsAndHashCode; |
||||||
|
import lombok.experimental.Accessors; |
||||||
|
|
||||||
|
/** |
||||||
|
* <p> |
||||||
|
* |
||||||
|
* </p> |
||||||
|
* |
||||||
|
* @author zjh |
||||||
|
* @since 2024-08-06 |
||||||
|
*/ |
||||||
|
@Data |
||||||
|
@EqualsAndHashCode(callSuper = false) |
||||||
|
@Accessors(chain = true) |
||||||
|
@TableName("sys_messages") |
||||||
|
@ApiModel(value="SysMessages对象", description="") |
||||||
|
public class SysMessages implements Serializable { |
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L; |
||||||
|
|
||||||
|
@TableId(value = "id", type = IdType.AUTO) |
||||||
|
private Long id; |
||||||
|
|
||||||
|
@ApiModelProperty(value = "发件人id") |
||||||
|
private Long senderId; |
||||||
|
|
||||||
|
@ApiModelProperty(value = "课程id") |
||||||
|
private String courseId; |
||||||
|
|
||||||
|
@ApiModelProperty(value = "消息标题") |
||||||
|
private String title; |
||||||
|
|
||||||
|
@ApiModelProperty(value = "消息内容") |
||||||
|
private String content; |
||||||
|
|
||||||
|
@ApiModelProperty(value = "发送时间") |
||||||
|
private LocalDateTime sendTime; |
||||||
|
|
||||||
|
@ApiModelProperty(value = "是否删除(逻辑删除)") |
||||||
|
private Integer isDelete; |
||||||
|
|
||||||
|
@ApiModelProperty(value = "是否发送(未发送的存草稿)") |
||||||
|
private Boolean isSend; |
||||||
|
|
||||||
|
|
||||||
|
} |
@ -0,0 +1,50 @@ |
|||||||
|
package com.teaching.backend.model.entity.message; |
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName; |
||||||
|
import com.baomidou.mybatisplus.annotation.IdType; |
||||||
|
import com.baomidou.mybatisplus.annotation.TableId; |
||||||
|
import java.time.LocalDateTime; |
||||||
|
import java.io.Serializable; |
||||||
|
import io.swagger.annotations.ApiModel; |
||||||
|
import io.swagger.annotations.ApiModelProperty; |
||||||
|
import lombok.Data; |
||||||
|
import lombok.EqualsAndHashCode; |
||||||
|
import lombok.experimental.Accessors; |
||||||
|
|
||||||
|
/** |
||||||
|
* <p> |
||||||
|
* |
||||||
|
* </p> |
||||||
|
* |
||||||
|
* @author zjh |
||||||
|
* @since 2024-08-06 |
||||||
|
*/ |
||||||
|
@Data |
||||||
|
@EqualsAndHashCode(callSuper = false) |
||||||
|
@Accessors(chain = true) |
||||||
|
@TableName("user_inbox") |
||||||
|
@ApiModel(value="UserInbox对象", description="") |
||||||
|
public class UserInbox implements Serializable { |
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L; |
||||||
|
|
||||||
|
@TableId(value = "id", type = IdType.AUTO) |
||||||
|
private Long id; |
||||||
|
|
||||||
|
@ApiModelProperty(value = "消息id") |
||||||
|
private Long messageId; |
||||||
|
|
||||||
|
@ApiModelProperty(value = "接收人id") |
||||||
|
private Long receiverId; |
||||||
|
|
||||||
|
@ApiModelProperty(value = "消息查看时间") |
||||||
|
private LocalDateTime readTime; |
||||||
|
|
||||||
|
@ApiModelProperty(value = "是否已读(0没有,1有)") |
||||||
|
private Boolean isRead; |
||||||
|
|
||||||
|
@ApiModelProperty(value = "是否删除(0没有,1有)") |
||||||
|
private Boolean isDelete; |
||||||
|
|
||||||
|
|
||||||
|
} |
@ -0,0 +1,24 @@ |
|||||||
|
package com.teaching.backend.model.query; |
||||||
|
|
||||||
|
import io.swagger.annotations.ApiModel; |
||||||
|
import io.swagger.annotations.ApiModelProperty; |
||||||
|
import lombok.Data; |
||||||
|
import lombok.EqualsAndHashCode; |
||||||
|
|
||||||
|
@EqualsAndHashCode(callSuper = true) |
||||||
|
@Data |
||||||
|
@ApiModel(description = "系统消息查询条件实体") |
||||||
|
public class MessagesQuery extends PageQuery { |
||||||
|
@ApiModelProperty(value = "用户的userId",required = true) |
||||||
|
private Long userId; |
||||||
|
@ApiModelProperty(value = "消息id") |
||||||
|
private Long messageId; |
||||||
|
@ApiModelProperty(value = "是否发送 false没有 true已发送") |
||||||
|
private Boolean isSend; |
||||||
|
@ApiModelProperty(value = "是否已读 false没有 true已读 可以作为消息筛选条件 用户不选这个就不用传") |
||||||
|
private Boolean isRead; |
||||||
|
@ApiModelProperty(value = "是否删除 0没有 1回收站 2回收站已删除(发件人不可见,收件人可见)") |
||||||
|
private Integer isDelete; |
||||||
|
|
||||||
|
|
||||||
|
} |
@ -0,0 +1,53 @@ |
|||||||
|
package com.teaching.backend.model.vo.message; |
||||||
|
|
||||||
|
import io.swagger.annotations.ApiModelProperty; |
||||||
|
import lombok.Data; |
||||||
|
|
||||||
|
import java.math.BigDecimal; |
||||||
|
import java.time.LocalDateTime; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
@Data |
||||||
|
public class SysMessageVO { |
||||||
|
@ApiModelProperty("id") |
||||||
|
private Long id; |
||||||
|
|
||||||
|
@ApiModelProperty("课程id") |
||||||
|
private String courseId; |
||||||
|
|
||||||
|
@ApiModelProperty("课程名称") |
||||||
|
private String courseName; |
||||||
|
|
||||||
|
@ApiModelProperty(value = "发件人id") |
||||||
|
private Long senderId; |
||||||
|
@ApiModelProperty(value = "发件人name") |
||||||
|
private String senderName; |
||||||
|
|
||||||
|
@ApiModelProperty(value = "消息标题") |
||||||
|
private String title; |
||||||
|
|
||||||
|
@ApiModelProperty(value = "消息内容") |
||||||
|
private String content; |
||||||
|
|
||||||
|
@ApiModelProperty(value = "发送时间") |
||||||
|
private LocalDateTime sendTime; |
||||||
|
|
||||||
|
@ApiModelProperty(value = "收信总人数") |
||||||
|
private Long userNum; |
||||||
|
|
||||||
|
@ApiModelProperty(value = "已读用户人数") |
||||||
|
private Long readUserNum; |
||||||
|
|
||||||
|
@ApiModelProperty(value = "收件用户信息集合") |
||||||
|
private List<UserReadMessageTimeVO> receiveUsers; |
||||||
|
|
||||||
|
@ApiModelProperty(value = "是否已读(0没有,1有)") |
||||||
|
private Boolean isRead; |
||||||
|
|
||||||
|
@ApiModelProperty(value = "已读用户集合") |
||||||
|
private List<UserReadMessageTimeVO> readUsers; |
||||||
|
|
||||||
|
@ApiModelProperty(value = "未读用户集合") |
||||||
|
private List<UserReadMessageTimeVO> noReadUsers; |
||||||
|
|
||||||
|
} |
@ -0,0 +1,36 @@ |
|||||||
|
package com.teaching.backend.model.vo.message; |
||||||
|
|
||||||
|
import io.swagger.annotations.ApiModelProperty; |
||||||
|
import lombok.Data; |
||||||
|
|
||||||
|
import java.time.LocalDateTime; |
||||||
|
|
||||||
|
@Data |
||||||
|
public class UserCheckMessageVO { |
||||||
|
@ApiModelProperty("id") |
||||||
|
private Long id; |
||||||
|
|
||||||
|
@ApiModelProperty("课程id") |
||||||
|
private String courseId; |
||||||
|
|
||||||
|
@ApiModelProperty("课程名称") |
||||||
|
private String courseName; |
||||||
|
|
||||||
|
@ApiModelProperty(value = "发件人id") |
||||||
|
private Long senderId; |
||||||
|
@ApiModelProperty(value = "发件人name") |
||||||
|
private String senderName; |
||||||
|
|
||||||
|
@ApiModelProperty(value = "消息标题") |
||||||
|
private String title; |
||||||
|
|
||||||
|
@ApiModelProperty(value = "消息内容") |
||||||
|
private String content; |
||||||
|
|
||||||
|
@ApiModelProperty(value = "发送时间") |
||||||
|
private LocalDateTime sendTime; |
||||||
|
|
||||||
|
@ApiModelProperty(value = "是否已读(0没有,1有)") |
||||||
|
private Boolean isRead; |
||||||
|
|
||||||
|
} |
@ -0,0 +1,21 @@ |
|||||||
|
package com.teaching.backend.model.vo.message; |
||||||
|
|
||||||
|
import io.swagger.annotations.ApiModelProperty; |
||||||
|
import lombok.Data; |
||||||
|
|
||||||
|
import java.time.LocalDateTime; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
@Data |
||||||
|
public class UserReadMessageTimeVO { |
||||||
|
|
||||||
|
@ApiModelProperty(value = "接收人id") |
||||||
|
private Long id; |
||||||
|
|
||||||
|
@ApiModelProperty(value = "接收人name") |
||||||
|
private String receiverName; |
||||||
|
|
||||||
|
@ApiModelProperty(value = "消息查看时间") |
||||||
|
private LocalDateTime readTime; |
||||||
|
|
||||||
|
} |
@ -0,0 +1,134 @@ |
|||||||
|
package com.teaching.backend.service.impl.message; |
||||||
|
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
||||||
|
import com.teaching.backend.common.ErrorCode; |
||||||
|
import com.teaching.backend.exception.BusinessException; |
||||||
|
import com.teaching.backend.mapper.message.MessagesMapper; |
||||||
|
import com.teaching.backend.mapper.message.UserInboxMapper; |
||||||
|
import com.teaching.backend.model.dto.message.SysMessageDTO; |
||||||
|
import com.teaching.backend.model.entity.message.SysMessages; |
||||||
|
import com.teaching.backend.model.entity.message.UserInbox; |
||||||
|
import com.teaching.backend.service.message.IMessagesService; |
||||||
|
import lombok.extern.slf4j.Slf4j; |
||||||
|
import org.springframework.beans.BeanUtils; |
||||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||||
|
import org.springframework.stereotype.Service; |
||||||
|
import org.springframework.transaction.annotation.Transactional; |
||||||
|
|
||||||
|
import java.time.LocalDateTime; |
||||||
|
import java.util.Arrays; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Optional; |
||||||
|
import java.util.concurrent.ThreadLocalRandom; |
||||||
|
import java.util.stream.Collectors; |
||||||
|
|
||||||
|
/** |
||||||
|
* <p> |
||||||
|
* 服务实现类 |
||||||
|
* </p> |
||||||
|
* |
||||||
|
* @author zjh |
||||||
|
* @since 2024-08-06 |
||||||
|
*/ |
||||||
|
@Service |
||||||
|
@Slf4j |
||||||
|
public class MessagesServiceImpl extends ServiceImpl<MessagesMapper, SysMessages> implements IMessagesService { |
||||||
|
|
||||||
|
@Autowired |
||||||
|
private UserInboxMapper userInboxMapper; |
||||||
|
@Override |
||||||
|
@Transactional |
||||||
|
public String sendMessageToUserInbox(SysMessageDTO sysMessageDTO) { |
||||||
|
// 1.数据非空校验(已完成)
|
||||||
|
|
||||||
|
// 2.消息ID检查,如果存在,说明是草稿箱编辑过的消息,否则生成新的ID
|
||||||
|
Long messageId = Optional.ofNullable(sysMessageDTO.getId()) |
||||||
|
.orElseGet(() -> System.currentTimeMillis() + ThreadLocalRandom.current().nextLong(1000)); |
||||||
|
|
||||||
|
// 3.解析传过来的receiverId
|
||||||
|
List<Long> receiverIds = Arrays.stream(sysMessageDTO.getReceiverId().split(",")) |
||||||
|
.map(Long::valueOf) |
||||||
|
.collect(Collectors.toList()); |
||||||
|
|
||||||
|
// 4.数据写入收件箱
|
||||||
|
List<UserInbox> userInboxes = receiverIds.stream() |
||||||
|
.map(receiverId -> { |
||||||
|
UserInbox userInbox = new UserInbox(); |
||||||
|
userInbox.setMessageId(messageId); |
||||||
|
userInbox.setReceiverId(receiverId); |
||||||
|
return userInbox; |
||||||
|
}) |
||||||
|
.collect(Collectors.toList()); |
||||||
|
|
||||||
|
// 执行批量插入操作,并判断是否成功
|
||||||
|
boolean inboxInsertSuccess = userInboxMapper.insertBatchInBox(userInboxes); |
||||||
|
if (!inboxInsertSuccess) { |
||||||
|
throw new BusinessException(ErrorCode.OPERATION_ERROR,"收件箱数据插入失败!"); |
||||||
|
} |
||||||
|
|
||||||
|
// 5.更新或保存消息数据
|
||||||
|
SysMessages sysMessages = new SysMessages(); |
||||||
|
BeanUtils.copyProperties(sysMessageDTO, sysMessages); |
||||||
|
sysMessages.setId(messageId); |
||||||
|
sysMessages.setSendTime(LocalDateTime.now()); |
||||||
|
sysMessages.setIsSend(true); |
||||||
|
|
||||||
|
boolean messageSaveSuccess = updateById(sysMessages); |
||||||
|
if (!messageSaveSuccess) { |
||||||
|
throw new BusinessException(ErrorCode.OPERATION_ERROR,"消息保存失败!"); |
||||||
|
} |
||||||
|
return "消息发送成功!"; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* 发件箱的删除 |
||||||
|
* |
||||||
|
* @param messageIds 消息ID列表 |
||||||
|
* @return 删除结果 |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
@Transactional |
||||||
|
public String deleteSendMessagesByLogical(List<Long> messageIds) { |
||||||
|
for (Long messageId : messageIds) { |
||||||
|
// 1.查询消息体
|
||||||
|
SysMessages message = query().getBaseMapper().selectById(messageId); |
||||||
|
if (message == null) { |
||||||
|
log.error("消息未找到,消息id:{}", messageId); |
||||||
|
continue; |
||||||
|
} |
||||||
|
// 2.根据消息状态处理删除逻辑
|
||||||
|
switch (message.getIsDelete()) { |
||||||
|
case 0: // 未删除状态
|
||||||
|
if (Boolean.FALSE.equals(message.getIsSend())) { |
||||||
|
// 未发送,物理删除
|
||||||
|
if (query().getBaseMapper().deleteById(messageId) < 1) { |
||||||
|
log.error("删除失败,消息id:{}", messageId); |
||||||
|
} |
||||||
|
} else { |
||||||
|
// 已发送,标记为回收站
|
||||||
|
updateMessageDeleteStatus(message, 1); |
||||||
|
} |
||||||
|
break; |
||||||
|
case 1: // 回收站状态
|
||||||
|
// 标记为彻底删除
|
||||||
|
updateMessageDeleteStatus(message, 2); |
||||||
|
break; |
||||||
|
default: |
||||||
|
log.warn("未知删除状态,消息id:{}", messageId); |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
return "删除成功"; |
||||||
|
} |
||||||
|
|
||||||
|
private void updateMessageDeleteStatus(SysMessages message, int deleteStatus) { |
||||||
|
message.setIsDelete(deleteStatus); |
||||||
|
if (query().getBaseMapper().updateById(message) < 1) { |
||||||
|
log.error("删除失败,消息id:{}", message.getId()); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,445 @@ |
|||||||
|
package com.teaching.backend.service.impl.message; |
||||||
|
|
||||||
|
import cn.hutool.core.bean.BeanUtil; |
||||||
|
import cn.hutool.core.bean.copier.CopyOptions; |
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
||||||
|
import com.teaching.backend.common.ErrorCode; |
||||||
|
import com.teaching.backend.exception.BusinessException; |
||||||
|
import com.teaching.backend.mapper.courses.CoursesMapper; |
||||||
|
import com.teaching.backend.mapper.message.UserInboxMapper; |
||||||
|
import com.teaching.backend.mapper.umsAdmin.UmsStudentMapper; |
||||||
|
import com.teaching.backend.mapper.umsAdmin.UmsTeacherMapper; |
||||||
|
import com.teaching.backend.model.dto.courses.PageDTO; |
||||||
|
import com.teaching.backend.model.entity.courses.Courses; |
||||||
|
import com.teaching.backend.model.entity.message.SysMessages; |
||||||
|
import com.teaching.backend.model.entity.message.UserInbox; |
||||||
|
import com.teaching.backend.model.entity.umsAdmin.UmsStudent; |
||||||
|
import com.teaching.backend.model.entity.umsAdmin.UmsTeacher; |
||||||
|
import com.teaching.backend.model.query.MessagesQuery; |
||||||
|
import com.teaching.backend.model.vo.message.SysMessageVO; |
||||||
|
import com.teaching.backend.model.vo.message.UserReadMessageTimeVO; |
||||||
|
import com.teaching.backend.service.message.IMessagesService; |
||||||
|
import com.teaching.backend.service.message.IUserInboxService; |
||||||
|
import lombok.extern.slf4j.Slf4j; |
||||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||||
|
import org.springframework.stereotype.Service; |
||||||
|
import org.springframework.transaction.annotation.Transactional; |
||||||
|
import org.springframework.util.StringUtils; |
||||||
|
|
||||||
|
import java.time.LocalDateTime; |
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.Comparator; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Map; |
||||||
|
import java.util.stream.Collectors; |
||||||
|
|
||||||
|
/** |
||||||
|
* <p> |
||||||
|
* 服务实现类 |
||||||
|
* </p> |
||||||
|
* |
||||||
|
* @author zjh |
||||||
|
* @since 2024-08-06 |
||||||
|
*/ |
||||||
|
@Service |
||||||
|
@Slf4j |
||||||
|
public class UserInboxServiceImpl extends ServiceImpl<UserInboxMapper, UserInbox> implements IUserInboxService { |
||||||
|
|
||||||
|
@Autowired |
||||||
|
private UmsTeacherMapper umsTeacherMapper; |
||||||
|
|
||||||
|
@Autowired |
||||||
|
private UmsStudentMapper umsStudentMapper; |
||||||
|
@Autowired |
||||||
|
private CoursesMapper coursesMapper; |
||||||
|
@Autowired |
||||||
|
private IMessagesService messagesService; |
||||||
|
@Autowired |
||||||
|
private UserInboxMapper userInboxMapper; |
||||||
|
|
||||||
|
//TODO 不需要特别指定“已读”或者是“未读”
|
||||||
|
@Override |
||||||
|
public PageDTO<SysMessageVO> queryReceiveMessages(MessagesQuery messagesQuery) { |
||||||
|
// 先按用户的id找到其的消息列表 默认看未删除的,(是否读 作为筛选条件后传进去)
|
||||||
|
LambdaQueryWrapper<UserInbox> userInboxQueryWrapper = new LambdaQueryWrapper<>(); |
||||||
|
userInboxQueryWrapper |
||||||
|
.eq(UserInbox::getReceiverId, messagesQuery.getUserId()) |
||||||
|
.eq(messagesQuery.getIsRead() != null,UserInbox::getIsRead,messagesQuery.getIsRead()) |
||||||
|
.eq(UserInbox::getIsDelete, messagesQuery.getIsDelete()); |
||||||
|
List<UserInbox> userInboxes = userInboxMapper.selectList(userInboxQueryWrapper); |
||||||
|
if (userInboxes.isEmpty()){ |
||||||
|
throw new BusinessException(ErrorCode.MESSAGE_NO_EXIT); |
||||||
|
} |
||||||
|
Map<Long, Boolean> messageReadStatusMap = userInboxes.stream() |
||||||
|
.collect(Collectors.toMap(UserInbox::getMessageId, UserInbox::getIsRead)); |
||||||
|
|
||||||
|
List<Long> messageIds = new ArrayList<>(messageReadStatusMap.keySet()); |
||||||
|
|
||||||
|
Page<SysMessages> page = messagesQuery.toMpPage("send_time", false); |
||||||
|
|
||||||
|
// 根据条件查询SysMessages表
|
||||||
|
Page<SysMessages> p = messagesService.page(page, |
||||||
|
new LambdaQueryWrapper<SysMessages>() |
||||||
|
.in(SysMessages::getId,messageIds) |
||||||
|
.select(SysMessages::getId,SysMessages::getCourseId,SysMessages::getTitle,SysMessages::getSenderId,SysMessages::getSendTime) |
||||||
|
); |
||||||
|
|
||||||
|
// 将Page<SysMessages>转换为PageDTO<SysMessageVO>
|
||||||
|
|
||||||
|
PageDTO<SysMessageVO> messages = PageDTO.of(p, SysMessageVO.class); |
||||||
|
// PageDTO<SysMessageVO> messages = PageDTO.of(p, message -> {
|
||||||
|
// SysMessageVO vo = new SysMessageVO();
|
||||||
|
// BeanUtil.copyProperties(message, vo, CopyOptions.create().setIgnoreProperties(SysMessageVO::getContent));
|
||||||
|
// return vo;
|
||||||
|
// });
|
||||||
|
// 获取PageDTO中的SysMessageVO列表
|
||||||
|
List<SysMessageVO> messagesList = messages.getList(); |
||||||
|
// 填充附加数据
|
||||||
|
for (SysMessageVO messageVO : messagesList) { |
||||||
|
//获取发件人信息
|
||||||
|
UmsTeacher umsTeacher = umsTeacherMapper.selectOne( |
||||||
|
new LambdaQueryWrapper<UmsTeacher>() |
||||||
|
.eq(UmsTeacher::getUserId, messageVO.getSenderId())); |
||||||
|
//没有这个教师那说明就是学生
|
||||||
|
if (umsTeacher == null) { |
||||||
|
messageVO.setSenderName(umsStudentMapper.selectOne( |
||||||
|
new LambdaQueryWrapper<UmsStudent>() |
||||||
|
.eq(UmsStudent::getUserId, messageVO.getSenderId()) |
||||||
|
).getName()); |
||||||
|
} else { |
||||||
|
messageVO.setSenderName(umsTeacher.getName()); |
||||||
|
} |
||||||
|
|
||||||
|
Courses course = coursesMapper.selectOne(new LambdaQueryWrapper<Courses>() |
||||||
|
.eq(Courses::getId, messageVO.getCourseId())); |
||||||
|
if (course != null) { |
||||||
|
messageVO.setCourseName(course.getName()); |
||||||
|
} |
||||||
|
|
||||||
|
// 设置isRead字段
|
||||||
|
Boolean isRead = messageReadStatusMap.get(messageVO.getId()); |
||||||
|
messageVO.setIsRead(isRead != null ? isRead : false); |
||||||
|
} |
||||||
|
// 设置消息列表并返回
|
||||||
|
messages.setList(messagesList); |
||||||
|
return messages; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public PageDTO<SysMessageVO> querySendMessages(MessagesQuery messagesQuery) { |
||||||
|
// 初始化一个按发送时间降序排序的Page对象
|
||||||
|
Page<SysMessages> page = messagesQuery.toMpPage("send_time", false); |
||||||
|
|
||||||
|
// 根据条件查询SysMessages表
|
||||||
|
Page<SysMessages> p = messagesService.page(page, |
||||||
|
new LambdaQueryWrapper<SysMessages>() |
||||||
|
.eq(SysMessages::getSenderId, messagesQuery.getUserId()) |
||||||
|
.eq(SysMessages::getIsSend, messagesQuery.getIsSend()) |
||||||
|
.eq(SysMessages::getIsDelete, messagesQuery.getIsDelete()) |
||||||
|
.select(SysMessages::getId,SysMessages::getCourseId,SysMessages::getTitle,SysMessages::getSendTime)); |
||||||
|
|
||||||
|
// 将Page<SysMessages>转换为PageDTO<SysMessageVO>
|
||||||
|
// PageDTO<SysMessageVO> messages = PageDTO.of(p, sysMessages -> {
|
||||||
|
// SysMessageVO vo = new SysMessageVO();
|
||||||
|
// BeanUtil.copyProperties(sysMessages, vo, CopyOptions.create().setIgnoreProperties(SysMessageVO::getSenderId));
|
||||||
|
// return vo;
|
||||||
|
// });
|
||||||
|
PageDTO<SysMessageVO> messages = PageDTO.of(p, SysMessageVO.class); |
||||||
|
// 获取PageDTO中的SysMessageVO列表
|
||||||
|
List<SysMessageVO> messagesList = messages.getList(); |
||||||
|
|
||||||
|
if (messagesList.isEmpty()) { |
||||||
|
throw new BusinessException(ErrorCode.MESSAGE_NO_EXIT); |
||||||
|
} |
||||||
|
|
||||||
|
// 遍历每个消息以填充附加数据
|
||||||
|
for (SysMessageVO sysMessageVO : messagesList) { |
||||||
|
// 设置课程名称
|
||||||
|
if (!StringUtils.isEmpty(sysMessageVO.getCourseId())) { |
||||||
|
Courses courses = coursesMapper.selectById(sysMessageVO.getCourseId()); |
||||||
|
if (courses != null) { |
||||||
|
sysMessageVO.setCourseName(courses.getName()); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// 查询UserInbox以获取当前消息的所有收件人数量
|
||||||
|
Long totalReceiverCount = userInboxMapper.selectCount( |
||||||
|
new LambdaQueryWrapper<UserInbox>() |
||||||
|
.eq(UserInbox::getMessageId, sysMessageVO.getId()) |
||||||
|
); |
||||||
|
|
||||||
|
sysMessageVO.setUserNum(totalReceiverCount); // 设置收信总人数
|
||||||
|
|
||||||
|
// 查询前5个UserInbox以获取当前消息的收件人列表
|
||||||
|
List<UserInbox> userInboxes = userInboxMapper.selectList( |
||||||
|
new LambdaQueryWrapper<UserInbox>() |
||||||
|
.eq(UserInbox::getMessageId, sysMessageVO.getId()) |
||||||
|
.select(UserInbox::getReceiverId, UserInbox::getIsRead) |
||||||
|
.last("LIMIT 5") |
||||||
|
); |
||||||
|
|
||||||
|
// 设置收件用户集合
|
||||||
|
List<UserReadMessageTimeVO> receiveUsers = userInboxes.stream().map(userInbox -> { |
||||||
|
UserReadMessageTimeVO vo = new UserReadMessageTimeVO(); |
||||||
|
vo.setId(userInbox.getReceiverId()); |
||||||
|
|
||||||
|
UmsStudent umsStudent = umsStudentMapper.selectOne( |
||||||
|
new LambdaQueryWrapper<UmsStudent>() |
||||||
|
.eq(UmsStudent::getUserId, userInbox.getReceiverId())); |
||||||
|
if (umsStudent == null) { |
||||||
|
vo.setReceiverName(umsTeacherMapper.selectOne( |
||||||
|
new LambdaQueryWrapper<UmsTeacher>() |
||||||
|
.eq(UmsTeacher::getUserId, userInbox.getReceiverId()) |
||||||
|
).getName()); |
||||||
|
} else { |
||||||
|
vo.setReceiverName(umsStudent.getName()); |
||||||
|
} |
||||||
|
return vo; |
||||||
|
}).collect(Collectors.toList()); |
||||||
|
sysMessageVO.setReceiveUsers(receiveUsers); // 设置收件人信息
|
||||||
|
|
||||||
|
// 计算已读用户人数
|
||||||
|
long readUserCount = userInboxes.stream() |
||||||
|
.filter(UserInbox::getIsRead) |
||||||
|
.count(); |
||||||
|
sysMessageVO.setReadUserNum(readUserCount); |
||||||
|
} |
||||||
|
|
||||||
|
// 更新PageDTO中的消息列表并返回
|
||||||
|
messages.setList(messagesList); |
||||||
|
return messages; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
public SysMessageVO getMessageDetail(MessagesQuery messagesQuery) { |
||||||
|
SysMessages sysMessage = messagesService.getById(messagesQuery.getMessageId()); |
||||||
|
SysMessageVO sysMessageVO = new SysMessageVO(); |
||||||
|
// BeanUtil.copyProperties(sysMessage, sysMessageVO);
|
||||||
|
sysMessageVO.setId(messagesQuery.getMessageId()); |
||||||
|
sysMessageVO.setContent(sysMessage.getContent()); |
||||||
|
|
||||||
|
|
||||||
|
// 设置课程名称 列表已查 前端自己去拿
|
||||||
|
// if (!StringUtils.isEmpty(sysMessage.getCourseId())) {
|
||||||
|
// Courses courses = coursesMapper.selectById(sysMessage.getCourseId());
|
||||||
|
// if (courses != null) {
|
||||||
|
// sysMessageVO.setCourseName(courses.getName());
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
sysMessageVO.setSenderId(messagesQuery.getUserId()); |
||||||
|
// 获取发件人信息
|
||||||
|
UmsTeacher umsTeacher = umsTeacherMapper.selectOne( |
||||||
|
new LambdaQueryWrapper<UmsTeacher>() |
||||||
|
.eq(UmsTeacher::getUserId, sysMessage.getSenderId())); |
||||||
|
if (umsTeacher == null) { |
||||||
|
sysMessageVO.setSenderName(umsStudentMapper.selectOne( |
||||||
|
new LambdaQueryWrapper<UmsStudent>() |
||||||
|
.eq(UmsStudent::getUserId, sysMessage.getSenderId()) |
||||||
|
).getName()); |
||||||
|
} else { |
||||||
|
sysMessageVO.setSenderName(umsTeacher.getName()); |
||||||
|
} |
||||||
|
|
||||||
|
// 根据当前用户是发件人还是收件人决定查询的内容
|
||||||
|
if (sysMessage.getSenderId().equals(messagesQuery.getUserId())) { |
||||||
|
// 发件人查看详情,查询所有收件人信息
|
||||||
|
List<UserInbox> userInboxes = userInboxMapper.selectList( |
||||||
|
new LambdaQueryWrapper<UserInbox>() |
||||||
|
.eq(UserInbox::getMessageId, messagesQuery.getMessageId()) |
||||||
|
); |
||||||
|
|
||||||
|
List<UserReadMessageTimeVO> receiveUsers = userInboxes.stream().map(userInbox -> { |
||||||
|
UserReadMessageTimeVO vo = new UserReadMessageTimeVO(); |
||||||
|
vo.setId(userInbox.getReceiverId()); |
||||||
|
UmsStudent umsStudent = umsStudentMapper.selectOne( |
||||||
|
new LambdaQueryWrapper<UmsStudent>() |
||||||
|
.eq(UmsStudent::getUserId, userInbox.getReceiverId())); |
||||||
|
if (umsStudent == null) { |
||||||
|
vo.setReceiverName(umsTeacherMapper.selectOne( |
||||||
|
new LambdaQueryWrapper<UmsTeacher>() |
||||||
|
.eq(UmsTeacher::getUserId, userInbox.getReceiverId()) |
||||||
|
).getName()); |
||||||
|
} else { |
||||||
|
vo.setReceiverName(umsStudent.getName()); |
||||||
|
} |
||||||
|
vo.setReadTime(userInbox.getReadTime()); |
||||||
|
return vo; |
||||||
|
}).collect(Collectors.toList()); |
||||||
|
sysMessageVO.setReceiveUsers(receiveUsers); |
||||||
|
} else { |
||||||
|
// 收件人查看详情,无需再次查询收件人信息,前端可复用列表中已查询到的部分数据
|
||||||
|
UserInbox userInbox = userInboxMapper.selectOne( |
||||||
|
new LambdaQueryWrapper<UserInbox>() |
||||||
|
.eq(UserInbox::getMessageId, messagesQuery.getMessageId()) |
||||||
|
.eq(UserInbox::getReceiverId, messagesQuery.getUserId()) |
||||||
|
); |
||||||
|
if (userInbox != null) { |
||||||
|
if (userInbox.getReadTime() == null) { |
||||||
|
userInbox.setReadTime(LocalDateTime.now()); |
||||||
|
} |
||||||
|
if (!userInbox.getIsRead()) { |
||||||
|
userInbox.setIsRead(true); |
||||||
|
} |
||||||
|
sysMessageVO.setIsRead(userInbox.getIsRead()); |
||||||
|
userInboxMapper.updateById(userInbox); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return sysMessageVO; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* 收件箱消息删除(逻辑删除) |
||||||
|
* |
||||||
|
* @param messageIds 消息ID列表 |
||||||
|
* @param userId 用户ID |
||||||
|
* @return 删除结果 |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
@Transactional |
||||||
|
public String deleteReceiveMessagesByLogical(List<Long> messageIds, Long userId) { |
||||||
|
for (Long messageId : messageIds) { |
||||||
|
UserInbox userInbox = getUserInboxByMessageIdAndUserId(messageId, userId); |
||||||
|
if (userInbox == null) { |
||||||
|
log.error("未找到收件箱消息,消息id:{},用户id:{}", messageId, userId); |
||||||
|
continue; |
||||||
|
} |
||||||
|
|
||||||
|
if (!userInbox.getIsRead()) { |
||||||
|
log.error("此消息未读:{}", messageId); |
||||||
|
throw new BusinessException(ErrorCode.MESSAGE_NO_READ); |
||||||
|
} |
||||||
|
|
||||||
|
if (!userInbox.getIsDelete()) { |
||||||
|
userInbox.setIsDelete(true); |
||||||
|
userInboxMapper.updateById(userInbox); |
||||||
|
} else { |
||||||
|
userInboxMapper.deleteById(userInbox); |
||||||
|
} |
||||||
|
} |
||||||
|
return "删除成功!"; |
||||||
|
} |
||||||
|
/** |
||||||
|
* 一键已读 |
||||||
|
* |
||||||
|
* @param messageIds 消息ID列表 |
||||||
|
* @param userId 用户ID |
||||||
|
* @return 操作结果 |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
@Transactional |
||||||
|
public String readMessagesBatch(List<Long> messageIds, Long userId) { |
||||||
|
for (Long messageId : messageIds) { |
||||||
|
UserInbox userInbox = getUserInboxByMessageIdAndUserId(messageId, userId); |
||||||
|
if (userInbox == null) { |
||||||
|
log.error("未找到收件箱消息,消息id:{},用户id:{}", messageId, userId); |
||||||
|
continue; |
||||||
|
} |
||||||
|
|
||||||
|
if (!userInbox.getIsRead()) { |
||||||
|
userInbox.setIsRead(true); |
||||||
|
userInbox.setReadTime(LocalDateTime.now()); |
||||||
|
userInboxMapper.updateById(userInbox); |
||||||
|
} |
||||||
|
} |
||||||
|
return "操作成功!"; |
||||||
|
} |
||||||
|
private UserInbox getUserInboxByMessageIdAndUserId(Long messageId, Long userId) { |
||||||
|
return userInboxMapper.selectOne(new LambdaQueryWrapper<UserInbox>() |
||||||
|
.eq(UserInbox::getMessageId, messageId) |
||||||
|
.eq(UserInbox::getReceiverId, userId)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* |
||||||
|
* @param userId |
||||||
|
* @param messageId |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public SysMessageVO getReadStatus(Long userId, Long messageId) { |
||||||
|
// 验证当前用户是否是消息的发件人
|
||||||
|
SysMessages sysMessages = messagesService.getById(messageId); |
||||||
|
if (sysMessages == null || !sysMessages.getSenderId().equals(userId)) { |
||||||
|
throw new BusinessException(ErrorCode.NO_AUTH_ERROR, "您没有权限查看此消息的已读/未读用户信息。"); |
||||||
|
} |
||||||
|
|
||||||
|
SysMessageVO sysMessageVO = new SysMessageVO(); |
||||||
|
sysMessageVO.setId(messageId); |
||||||
|
|
||||||
|
// 查询 UserInbox 以获取当前消息的收件人列表
|
||||||
|
List<UserInbox> userInboxes = userInboxMapper.selectList( |
||||||
|
new LambdaQueryWrapper<UserInbox>() |
||||||
|
.eq(UserInbox::getMessageId, messageId) |
||||||
|
.select(UserInbox::getReceiverId, UserInbox::getIsRead, UserInbox::getReadTime) |
||||||
|
); |
||||||
|
|
||||||
|
List<Long> receiverIds = userInboxes.stream().map(UserInbox::getReceiverId).collect(Collectors.toList()); |
||||||
|
sysMessageVO.setUserNum((long) receiverIds.size()); // 设置收信总人数
|
||||||
|
|
||||||
|
// 提取已读消息的 UserInbox 并按阅读时间降序排序
|
||||||
|
List<UserInbox> readUserInboxes = userInboxes.stream() |
||||||
|
.filter(UserInbox::getIsRead) |
||||||
|
.sorted(Comparator.comparing(UserInbox::getReadTime, Comparator.nullsLast(Comparator.reverseOrder()))) |
||||||
|
.collect(Collectors.toList()); |
||||||
|
|
||||||
|
// 设置已读学生人数
|
||||||
|
sysMessageVO.setReadUserNum((long) readUserInboxes.size()); |
||||||
|
|
||||||
|
// 创建已读用户的 UserReadMessageTimeVO 列表
|
||||||
|
List<UserReadMessageTimeVO> readStudents = readUserInboxes.stream() |
||||||
|
.map(userInbox -> { |
||||||
|
UserReadMessageTimeVO vo = new UserReadMessageTimeVO(); |
||||||
|
vo.setId(userInbox.getReceiverId()); |
||||||
|
UmsStudent umsStudent = umsStudentMapper.selectOne( |
||||||
|
new LambdaQueryWrapper<UmsStudent>() |
||||||
|
.eq(UmsStudent::getUserId, userInbox.getReceiverId())); |
||||||
|
if (umsStudent == null) { |
||||||
|
vo.setReceiverName(umsTeacherMapper.selectOne( |
||||||
|
new LambdaQueryWrapper<UmsTeacher>() |
||||||
|
.eq(UmsTeacher::getUserId, userInbox.getReceiverId()) |
||||||
|
).getName()); |
||||||
|
} else { |
||||||
|
vo.setReceiverName(umsStudent.getName()); |
||||||
|
} |
||||||
|
vo.setReadTime(userInbox.getReadTime()); |
||||||
|
return vo; |
||||||
|
}) |
||||||
|
.collect(Collectors.toList()); |
||||||
|
|
||||||
|
// 创建未读用户的 UserReadMessageTimeVO 列表
|
||||||
|
List<UserReadMessageTimeVO> noReadStudents = receiverIds.stream() |
||||||
|
.filter(id -> readUserInboxes.stream().noneMatch(ri -> ri.getReceiverId().equals(id))) |
||||||
|
.map(id -> { |
||||||
|
UserReadMessageTimeVO vo = new UserReadMessageTimeVO(); |
||||||
|
vo.setId(id); |
||||||
|
UmsStudent umsStudent = umsStudentMapper.selectOne( |
||||||
|
new LambdaQueryWrapper<UmsStudent>() |
||||||
|
.eq(UmsStudent::getUserId, id)); |
||||||
|
if (umsStudent == null) { |
||||||
|
vo.setReceiverName(umsTeacherMapper.selectOne( |
||||||
|
new LambdaQueryWrapper<UmsTeacher>() |
||||||
|
.eq(UmsTeacher::getUserId, id) |
||||||
|
).getName()); |
||||||
|
} else { |
||||||
|
vo.setReceiverName(umsStudent.getName()); |
||||||
|
} |
||||||
|
return vo; |
||||||
|
}) |
||||||
|
.collect(Collectors.toList()); |
||||||
|
|
||||||
|
// 设置已读和未读学生集合
|
||||||
|
sysMessageVO.setReadUsers(readStudents); |
||||||
|
sysMessageVO.setNoReadUsers(noReadStudents); |
||||||
|
|
||||||
|
return sysMessageVO; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,27 @@ |
|||||||
|
package com.teaching.backend.service.message; |
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService; |
||||||
|
import com.teaching.backend.model.dto.courses.PageDTO; |
||||||
|
import com.teaching.backend.model.dto.message.SysMessageDTO; |
||||||
|
import com.teaching.backend.model.entity.message.SysMessages; |
||||||
|
import com.teaching.backend.model.entity.message.UserInbox; |
||||||
|
import com.teaching.backend.model.query.MessagesQuery; |
||||||
|
import com.teaching.backend.model.vo.message.SysMessageVO; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* <p> |
||||||
|
* 服务类 |
||||||
|
* </p> |
||||||
|
* |
||||||
|
* @author zjh |
||||||
|
* @since 2024-08-06 |
||||||
|
*/ |
||||||
|
public interface IMessagesService extends IService<SysMessages> { |
||||||
|
|
||||||
|
String sendMessageToUserInbox(SysMessageDTO sysMessageDTO); |
||||||
|
|
||||||
|
String deleteSendMessagesByLogical(List<Long> messageIds); |
||||||
|
|
||||||
|
} |
@ -0,0 +1,32 @@ |
|||||||
|
package com.teaching.backend.service.message; |
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService; |
||||||
|
import com.teaching.backend.model.dto.courses.PageDTO; |
||||||
|
import com.teaching.backend.model.entity.message.UserInbox; |
||||||
|
import com.teaching.backend.model.query.MessagesQuery; |
||||||
|
import com.teaching.backend.model.vo.message.SysMessageVO; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* <p> |
||||||
|
* 服务类 |
||||||
|
* </p> |
||||||
|
* |
||||||
|
* @author zjh |
||||||
|
* @since 2024-08-06 |
||||||
|
*/ |
||||||
|
public interface IUserInboxService extends IService<UserInbox> { |
||||||
|
|
||||||
|
PageDTO<SysMessageVO> queryReceiveMessages(MessagesQuery messagesQuery); |
||||||
|
|
||||||
|
SysMessageVO getMessageDetail(MessagesQuery messagesQuery); |
||||||
|
|
||||||
|
PageDTO<SysMessageVO> querySendMessages(MessagesQuery messagesQuery); |
||||||
|
|
||||||
|
String readMessagesBatch(List<Long> messageIds, Long userId); |
||||||
|
|
||||||
|
String deleteReceiveMessagesByLogical(List<Long> messageIds, Long userId); |
||||||
|
|
||||||
|
SysMessageVO getReadStatus(Long userId, Long messageId); |
||||||
|
} |
@ -0,0 +1,12 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
||||||
|
<mapper namespace="com.teaching.backend.mapper.message.UserInboxMapper"> |
||||||
|
|
||||||
|
<insert id="insertBatchInBox" parameterType="java.util.List"> |
||||||
|
INSERT INTO user_inbox (message_id, receiver_id) |
||||||
|
VALUES |
||||||
|
<foreach collection="list" item="item" index="index" separator=","> |
||||||
|
(#{item.messageId}, #{item.receiverId}) |
||||||
|
</foreach> |
||||||
|
</insert> |
||||||
|
</mapper> |
Loading…
Reference in new issue