From 30a1d1f557f1c0b3527b086926e1e2ba7de39b1e Mon Sep 17 00:00:00 2001
From: Alan <3052806735@qq.com>
Date: Sat, 10 Aug 2024 17:14:55 +0800
Subject: [PATCH] =?UTF-8?q?=E8=AF=BE=E7=A8=8B=E8=A1=A8=E9=83=A8=E5=88=86?=
=?UTF-8?q?=E5=AD=97=E6=AE=B5=E7=B1=BB=E5=9E=8B=E4=BF=AE=E6=94=B9=20?=
=?UTF-8?q?=E6=B6=88=E6=81=AF=E6=A8=A1=E5=9D=97=E5=8A=9F=E8=83=BD=EF=BC=88?=
=?UTF-8?q?=E7=94=A8=E6=88=B7=E6=94=B6=E4=BB=B6=E7=AE=B1=EF=BC=8C=E5=8F=91?=
=?UTF-8?q?=E4=BB=B6=E7=AE=B1=EF=BC=8C=E5=B7=B2=E8=AF=BB/=E6=9C=AA?=
=?UTF-8?q?=E8=AF=BB=E6=95=B0=E6=8D=AE=E6=98=BE=E7=A4=BA=EF=BC=8C=E6=B6=88?=
=?UTF-8?q?=E6=81=AF=E9=80=BB=E8=BE=91=E5=88=A0=E9=99=A4=EF=BC=8C=E6=B6=88?=
=?UTF-8?q?=E6=81=AF=E6=89=B9=E9=87=8F=E5=B7=B2=E8=AF=BB=EF=BC=89?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../teaching/backend/common/ErrorCode.java | 3 +-
.../message/MessagesController.java | 79 ++++
.../message/UserInboxController.java | 83 ++++
.../mapper/message/MessagesMapper.java | 16 +
.../mapper/message/UserInboxMapper.java | 19 +
.../model/dto/message/SysMessageDTO.java | 14 +
.../model/entity/message/SysMessages.java | 56 +++
.../model/entity/message/UserInbox.java | 50 ++
.../backend/model/query/CourseQuery.java | 6 +-
.../backend/model/query/MessagesQuery.java | 24 +
.../backend/model/query/PageQuery.java | 1 +
.../model/vo/message/SysMessageVO.java | 53 +++
.../model/vo/message/UserCheckMessageVO.java | 36 ++
.../vo/message/UserReadMessageTimeVO.java | 21 +
.../impl/courses/CoursesServiceImpl.java | 14 +-
.../impl/message/MessagesServiceImpl.java | 134 ++++++
.../impl/message/UserInboxServiceImpl.java | 445 ++++++++++++++++++
.../service/message/IMessagesService.java | 27 ++
.../service/message/IUserInboxService.java | 32 ++
src/main/resources/mapper/UserInboxMapper.xml | 12 +
20 files changed, 1114 insertions(+), 11 deletions(-)
create mode 100644 src/main/java/com/teaching/backend/controller/message/MessagesController.java
create mode 100644 src/main/java/com/teaching/backend/controller/message/UserInboxController.java
create mode 100644 src/main/java/com/teaching/backend/mapper/message/MessagesMapper.java
create mode 100644 src/main/java/com/teaching/backend/mapper/message/UserInboxMapper.java
create mode 100644 src/main/java/com/teaching/backend/model/dto/message/SysMessageDTO.java
create mode 100644 src/main/java/com/teaching/backend/model/entity/message/SysMessages.java
create mode 100644 src/main/java/com/teaching/backend/model/entity/message/UserInbox.java
create mode 100644 src/main/java/com/teaching/backend/model/query/MessagesQuery.java
create mode 100644 src/main/java/com/teaching/backend/model/vo/message/SysMessageVO.java
create mode 100644 src/main/java/com/teaching/backend/model/vo/message/UserCheckMessageVO.java
create mode 100644 src/main/java/com/teaching/backend/model/vo/message/UserReadMessageTimeVO.java
create mode 100644 src/main/java/com/teaching/backend/service/impl/message/MessagesServiceImpl.java
create mode 100644 src/main/java/com/teaching/backend/service/impl/message/UserInboxServiceImpl.java
create mode 100644 src/main/java/com/teaching/backend/service/message/IMessagesService.java
create mode 100644 src/main/java/com/teaching/backend/service/message/IUserInboxService.java
create mode 100644 src/main/resources/mapper/UserInboxMapper.xml
diff --git a/src/main/java/com/teaching/backend/common/ErrorCode.java b/src/main/java/com/teaching/backend/common/ErrorCode.java
index 95830fb..4883d57 100644
--- a/src/main/java/com/teaching/backend/common/ErrorCode.java
+++ b/src/main/java/com/teaching/backend/common/ErrorCode.java
@@ -20,7 +20,8 @@ public enum ErrorCode {
CONTENT_NOT_EXIT(40008, "内容id不存在"),
KNOWS_EXIT(40009, "该项下面存在关联的知识点,请在删除关联的知识点后再来操作!"),
INVALID_ROLE(400010, "角色不存在"),
-
+ MESSAGE_NO_READ(400011, "消息未读,禁止删除!"),
+ MESSAGE_NO_EXIT(400012, "消息不存在!"),
NOT_LOGIN_ERROR(40100, "未登录"),
NO_AUTH_ERROR(40101, "无权限"),
NOT_FOUND_ERROR(40400, "请求数据不存在"),
diff --git a/src/main/java/com/teaching/backend/controller/message/MessagesController.java b/src/main/java/com/teaching/backend/controller/message/MessagesController.java
new file mode 100644
index 0000000..be95f7f
--- /dev/null
+++ b/src/main/java/com/teaching/backend/controller/message/MessagesController.java
@@ -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;
+
+/**
+ *
+ * 前端控制器
+ *
+ *
+ * @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 sendMessage(@RequestBody SysMessageDTO sysMessageDTO){
+ String data = messagesService.sendMessageToUserInbox(sysMessageDTO);
+ return ResultUtils.success(data);
+ }
+
+ //TODO 功能待完善
+ @ApiOperation("删除发件箱的消息--批删--逻辑删除")
+ @ValidateParams({"messageIds"}) // 需要校验的参数
+ @DeleteMapping ("/deletesendmessage")
+ public BaseResponse deleteMessages(@RequestParam List messageIds){
+ String data = messagesService.deleteSendMessagesByLogical(messageIds);
+ return ResultUtils.success(data);
+ }
+
+
+
+ @ApiOperation("根据id查询消息")
+ @ValidateParams({"id"}) // 需要校验的参数
+ @GetMapping ("/getmessage/{id}")
+ public BaseResponse getMessageById(@PathVariable("id") Long id){
+ SysMessages data = messagesService.getById(id);
+ return ResultUtils.success(data);
+ }
+
+ /**
+ * 修改消息
+ * @param sysMessageDTO
+ * @return
+ */
+ @ApiOperation("修改消息--仅限于未发送成功的消息(草稿功能)")
+ @PutMapping ("/modifymessage")
+ public BaseResponse modifyMessage(@RequestBody SysMessageDTO sysMessageDTO){
+ boolean b = messagesService.updateById(sysMessageDTO);
+ return ResultUtils.success(b ? "修改成功" : "修改失败");
+ }
+
+
+}
diff --git a/src/main/java/com/teaching/backend/controller/message/UserInboxController.java b/src/main/java/com/teaching/backend/controller/message/UserInboxController.java
new file mode 100644
index 0000000..0fb7469
--- /dev/null
+++ b/src/main/java/com/teaching/backend/controller/message/UserInboxController.java
@@ -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;
+
+/**
+ *
+ * 前端控制器
+ *
+ *
+ * @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> getMessages(MessagesQuery messagesQuery){
+ PageDTO messageList = userInboxService.queryReceiveMessages(messagesQuery);
+ return ResultUtils.success(messageList);
+ }
+
+ @ApiOperation("用户分页查看个人消息(发件箱)")
+ @ValidateParams({"userId","isDelete","isSend"})
+ @GetMapping("/page/sendmessages")
+ public BaseResponse> getSendMessages(MessagesQuery messagesQuery){
+ PageDTO messageList = userInboxService.querySendMessages(messagesQuery);
+ return ResultUtils.success(messageList);
+ }
+
+ //用户查看消息详情,如果是第一次查看,则会更新“已读状态”和“阅读时间”
+ @ApiOperation("查看消息详情")
+ @ValidateParams({"userId","messageId"}) // 需要校验的参数
+ @GetMapping("/getmessagedetails")
+ public BaseResponse getMessageDetail(MessagesQuery messagesQuery){
+ SysMessageVO userCheckMessageVO = userInboxService.getMessageDetail(messagesQuery);
+ return ResultUtils.success(userCheckMessageVO);
+ }
+
+ @ApiOperation("获取已读/未读用户集合")
+ @ValidateParams({"userId", "messageId"})
+ @GetMapping("/message/readstatus")
+ public BaseResponse getMessageReadStatus(@RequestParam Long userId, @RequestParam Long messageId) {
+ SysMessageVO messageVO = userInboxService.getReadStatus(userId, messageId);
+ return ResultUtils.success(messageVO);
+ }
+
+
+ @ApiOperation("一键已读")
+ @PutMapping ("/readmessagesbatch")
+ public BaseResponse readMessagesBatch(@RequestParam List messageIds, @RequestParam Long userId){
+ String data = userInboxService.readMessagesBatch(messageIds,userId);
+ return ResultUtils.success(data);
+ }
+
+ @ApiOperation("删除收件箱的消息--批删--逻辑删除")
+ @ValidateParams({"messageIds","userId"}) // 需要校验的参数
+ @DeleteMapping ("/deletereceivemessage")
+ public BaseResponse deleteReceiveMessages(@RequestParam List messageIds,@RequestParam Long userId){
+ String data = userInboxService.deleteReceiveMessagesByLogical(messageIds,userId);
+ return ResultUtils.success(data);
+ }
+
+}
diff --git a/src/main/java/com/teaching/backend/mapper/message/MessagesMapper.java b/src/main/java/com/teaching/backend/mapper/message/MessagesMapper.java
new file mode 100644
index 0000000..7c267c4
--- /dev/null
+++ b/src/main/java/com/teaching/backend/mapper/message/MessagesMapper.java
@@ -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;
+
+/**
+ *
+ * Mapper 接口
+ *
+ *
+ * @author zjh
+ * @since 2024-08-06
+ */
+public interface MessagesMapper extends BaseMapper {
+
+}
diff --git a/src/main/java/com/teaching/backend/mapper/message/UserInboxMapper.java b/src/main/java/com/teaching/backend/mapper/message/UserInboxMapper.java
new file mode 100644
index 0000000..bf18b1f
--- /dev/null
+++ b/src/main/java/com/teaching/backend/mapper/message/UserInboxMapper.java
@@ -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;
+
+/**
+ *
+ * Mapper 接口
+ *
+ *
+ * @author zjh
+ * @since 2024-08-06
+ */
+public interface UserInboxMapper extends BaseMapper {
+
+ boolean insertBatchInBox(List userInboxes);
+}
diff --git a/src/main/java/com/teaching/backend/model/dto/message/SysMessageDTO.java b/src/main/java/com/teaching/backend/model/dto/message/SysMessageDTO.java
new file mode 100644
index 0000000..87a82c5
--- /dev/null
+++ b/src/main/java/com/teaching/backend/model/dto/message/SysMessageDTO.java
@@ -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;
+}
diff --git a/src/main/java/com/teaching/backend/model/entity/message/SysMessages.java b/src/main/java/com/teaching/backend/model/entity/message/SysMessages.java
new file mode 100644
index 0000000..1677b01
--- /dev/null
+++ b/src/main/java/com/teaching/backend/model/entity/message/SysMessages.java
@@ -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;
+
+/**
+ *
+ *
+ *
+ *
+ * @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;
+
+
+}
diff --git a/src/main/java/com/teaching/backend/model/entity/message/UserInbox.java b/src/main/java/com/teaching/backend/model/entity/message/UserInbox.java
new file mode 100644
index 0000000..aca75c1
--- /dev/null
+++ b/src/main/java/com/teaching/backend/model/entity/message/UserInbox.java
@@ -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;
+
+/**
+ *
+ *
+ *
+ *
+ * @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;
+
+
+}
diff --git a/src/main/java/com/teaching/backend/model/query/CourseQuery.java b/src/main/java/com/teaching/backend/model/query/CourseQuery.java
index b8d1e73..0e523dc 100644
--- a/src/main/java/com/teaching/backend/model/query/CourseQuery.java
+++ b/src/main/java/com/teaching/backend/model/query/CourseQuery.java
@@ -25,11 +25,11 @@ public class CourseQuery extends PageQuery {
private String teacher;
@ApiModelProperty("课程类别")
- private String category;
+ private Integer category;
@ApiModelProperty("课程性质")
- private String nature;
+ private Integer nature;
@ApiModelProperty("课程考核类型")
- private String assessmenttype;
+ private Integer assessmenttype;
}
diff --git a/src/main/java/com/teaching/backend/model/query/MessagesQuery.java b/src/main/java/com/teaching/backend/model/query/MessagesQuery.java
new file mode 100644
index 0000000..33172d4
--- /dev/null
+++ b/src/main/java/com/teaching/backend/model/query/MessagesQuery.java
@@ -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;
+
+
+}
diff --git a/src/main/java/com/teaching/backend/model/query/PageQuery.java b/src/main/java/com/teaching/backend/model/query/PageQuery.java
index 7b8e7da..7896a66 100644
--- a/src/main/java/com/teaching/backend/model/query/PageQuery.java
+++ b/src/main/java/com/teaching/backend/model/query/PageQuery.java
@@ -41,4 +41,5 @@ public class PageQuery {
public Page toMpPageDefaultSortByUpdateTime(){
return toMpPage(new OrderItem("update_time", false));
}
+
}
diff --git a/src/main/java/com/teaching/backend/model/vo/message/SysMessageVO.java b/src/main/java/com/teaching/backend/model/vo/message/SysMessageVO.java
new file mode 100644
index 0000000..f4ddd9c
--- /dev/null
+++ b/src/main/java/com/teaching/backend/model/vo/message/SysMessageVO.java
@@ -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 receiveUsers;
+
+ @ApiModelProperty(value = "是否已读(0没有,1有)")
+ private Boolean isRead;
+
+ @ApiModelProperty(value = "已读用户集合")
+ private List readUsers;
+
+ @ApiModelProperty(value = "未读用户集合")
+ private List noReadUsers;
+
+}
diff --git a/src/main/java/com/teaching/backend/model/vo/message/UserCheckMessageVO.java b/src/main/java/com/teaching/backend/model/vo/message/UserCheckMessageVO.java
new file mode 100644
index 0000000..373ade4
--- /dev/null
+++ b/src/main/java/com/teaching/backend/model/vo/message/UserCheckMessageVO.java
@@ -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;
+
+}
diff --git a/src/main/java/com/teaching/backend/model/vo/message/UserReadMessageTimeVO.java b/src/main/java/com/teaching/backend/model/vo/message/UserReadMessageTimeVO.java
new file mode 100644
index 0000000..413ce06
--- /dev/null
+++ b/src/main/java/com/teaching/backend/model/vo/message/UserReadMessageTimeVO.java
@@ -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;
+
+}
diff --git a/src/main/java/com/teaching/backend/service/impl/courses/CoursesServiceImpl.java b/src/main/java/com/teaching/backend/service/impl/courses/CoursesServiceImpl.java
index 313528a..ebfe8ae 100644
--- a/src/main/java/com/teaching/backend/service/impl/courses/CoursesServiceImpl.java
+++ b/src/main/java/com/teaching/backend/service/impl/courses/CoursesServiceImpl.java
@@ -195,10 +195,10 @@ public class CoursesServiceImpl extends ServiceImpl impl
Page p = lambdaQuery()
.like(courseQuery.getName() != null, Courses::getName, courseQuery.getName())
.apply("FIND_IN_SET({0}, teacher)", courseQuery.getUserId())
- .eq(StringUtils.hasText(courseQuery.getCategory()), Courses::getCategory, courseQuery.getCategory())
-// .eq(courseQuery.getCategory() != null && !courseQuery.getCategory().isEmpty(), Courses::getCategory, courseQuery.getCategory())
- .eq(courseQuery.getNature() != null && !courseQuery.getNature().isEmpty(), Courses::getNature, courseQuery.getNature())
- .eq(courseQuery.getAssessmenttype() != null &&!courseQuery.getAssessmenttype().isEmpty(), Courses::getAssessmenttype, courseQuery.getAssessmenttype())
+// .eq(StringUtils.hasText(courseQuery.getCategory()), Courses::getCategory, courseQuery.getCategory())
+ .eq(courseQuery.getCategory() != null, Courses::getCategory, courseQuery.getCategory())
+ .eq(courseQuery.getNature() != null, Courses::getNature, courseQuery.getNature())
+ .eq(courseQuery.getAssessmenttype() != null, Courses::getAssessmenttype, courseQuery.getAssessmenttype())
.select(Courses::getId,Courses::getTeacher,Courses::getImg,Courses::getName,Courses::getCredit,Courses::getClasshours)
.page(page);
return PageDTO.of(p,CoursesVO.class);
@@ -222,9 +222,9 @@ public class CoursesServiceImpl extends ServiceImpl impl
Page page = courseQuery.toMpPageDefaultSortByCreateTime();
Page p = lambdaQuery()
.like(courseQuery.getName() != null && !courseQuery.getName().isEmpty(), Courses::getName, courseQuery.getName())
- .eq(courseQuery.getCategory() != null && !courseQuery.getCategory().isEmpty(), Courses::getCategory, courseQuery.getCategory())
- .eq(courseQuery.getNature() != null && !courseQuery.getNature().isEmpty(), Courses::getNature, courseQuery.getNature())
- .eq(courseQuery.getAssessmenttype() != null &&!courseQuery.getAssessmenttype().isEmpty(), Courses::getAssessmenttype, courseQuery.getAssessmenttype())
+ .eq(courseQuery.getCategory() != null, Courses::getCategory, courseQuery.getCategory())
+ .eq(courseQuery.getNature() != null, Courses::getNature, courseQuery.getNature())
+ .eq(courseQuery.getAssessmenttype() != null, Courses::getAssessmenttype, courseQuery.getAssessmenttype())
.apply(courseQuery.getTeacher() != null && !courseQuery.getTeacher().isEmpty(), "FIND_IN_SET({0}, teacher)", courseQuery.getTeacher())
.select(Courses::getId,Courses::getTeacher,Courses::getImg,Courses::getName,Courses::getCredit,Courses::getClasshours)
.page(page);
diff --git a/src/main/java/com/teaching/backend/service/impl/message/MessagesServiceImpl.java b/src/main/java/com/teaching/backend/service/impl/message/MessagesServiceImpl.java
new file mode 100644
index 0000000..b20226c
--- /dev/null
+++ b/src/main/java/com/teaching/backend/service/impl/message/MessagesServiceImpl.java
@@ -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;
+
+/**
+ *
+ * 服务实现类
+ *
+ *
+ * @author zjh
+ * @since 2024-08-06
+ */
+@Service
+@Slf4j
+public class MessagesServiceImpl extends ServiceImpl 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 receiverIds = Arrays.stream(sysMessageDTO.getReceiverId().split(","))
+ .map(Long::valueOf)
+ .collect(Collectors.toList());
+
+ // 4.数据写入收件箱
+ List 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 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());
+ }
+ }
+
+}
diff --git a/src/main/java/com/teaching/backend/service/impl/message/UserInboxServiceImpl.java b/src/main/java/com/teaching/backend/service/impl/message/UserInboxServiceImpl.java
new file mode 100644
index 0000000..a3de4f1
--- /dev/null
+++ b/src/main/java/com/teaching/backend/service/impl/message/UserInboxServiceImpl.java
@@ -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;
+
+/**
+ *
+ * 服务实现类
+ *
+ *
+ * @author zjh
+ * @since 2024-08-06
+ */
+@Service
+@Slf4j
+public class UserInboxServiceImpl extends ServiceImpl 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 queryReceiveMessages(MessagesQuery messagesQuery) {
+ // 先按用户的id找到其的消息列表 默认看未删除的,(是否读 作为筛选条件后传进去)
+ LambdaQueryWrapper userInboxQueryWrapper = new LambdaQueryWrapper<>();
+ userInboxQueryWrapper
+ .eq(UserInbox::getReceiverId, messagesQuery.getUserId())
+ .eq(messagesQuery.getIsRead() != null,UserInbox::getIsRead,messagesQuery.getIsRead())
+ .eq(UserInbox::getIsDelete, messagesQuery.getIsDelete());
+ List userInboxes = userInboxMapper.selectList(userInboxQueryWrapper);
+ if (userInboxes.isEmpty()){
+ throw new BusinessException(ErrorCode.MESSAGE_NO_EXIT);
+ }
+ Map messageReadStatusMap = userInboxes.stream()
+ .collect(Collectors.toMap(UserInbox::getMessageId, UserInbox::getIsRead));
+
+ List messageIds = new ArrayList<>(messageReadStatusMap.keySet());
+
+ Page page = messagesQuery.toMpPage("send_time", false);
+
+ // 根据条件查询SysMessages表
+ Page p = messagesService.page(page,
+ new LambdaQueryWrapper()
+ .in(SysMessages::getId,messageIds)
+ .select(SysMessages::getId,SysMessages::getCourseId,SysMessages::getTitle,SysMessages::getSenderId,SysMessages::getSendTime)
+ );
+
+ // 将Page转换为PageDTO
+
+ PageDTO messages = PageDTO.of(p, SysMessageVO.class);
+// PageDTO messages = PageDTO.of(p, message -> {
+// SysMessageVO vo = new SysMessageVO();
+// BeanUtil.copyProperties(message, vo, CopyOptions.create().setIgnoreProperties(SysMessageVO::getContent));
+// return vo;
+// });
+ // 获取PageDTO中的SysMessageVO列表
+ List messagesList = messages.getList();
+ // 填充附加数据
+ for (SysMessageVO messageVO : messagesList) {
+ //获取发件人信息
+ UmsTeacher umsTeacher = umsTeacherMapper.selectOne(
+ new LambdaQueryWrapper()
+ .eq(UmsTeacher::getUserId, messageVO.getSenderId()));
+ //没有这个教师那说明就是学生
+ if (umsTeacher == null) {
+ messageVO.setSenderName(umsStudentMapper.selectOne(
+ new LambdaQueryWrapper()
+ .eq(UmsStudent::getUserId, messageVO.getSenderId())
+ ).getName());
+ } else {
+ messageVO.setSenderName(umsTeacher.getName());
+ }
+
+ Courses course = coursesMapper.selectOne(new LambdaQueryWrapper()
+ .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 querySendMessages(MessagesQuery messagesQuery) {
+ // 初始化一个按发送时间降序排序的Page对象
+ Page page = messagesQuery.toMpPage("send_time", false);
+
+ // 根据条件查询SysMessages表
+ Page p = messagesService.page(page,
+ new LambdaQueryWrapper()
+ .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转换为PageDTO
+// PageDTO messages = PageDTO.of(p, sysMessages -> {
+// SysMessageVO vo = new SysMessageVO();
+// BeanUtil.copyProperties(sysMessages, vo, CopyOptions.create().setIgnoreProperties(SysMessageVO::getSenderId));
+// return vo;
+// });
+ PageDTO messages = PageDTO.of(p, SysMessageVO.class);
+ // 获取PageDTO中的SysMessageVO列表
+ List 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()
+ .eq(UserInbox::getMessageId, sysMessageVO.getId())
+ );
+
+ sysMessageVO.setUserNum(totalReceiverCount); // 设置收信总人数
+
+ // 查询前5个UserInbox以获取当前消息的收件人列表
+ List userInboxes = userInboxMapper.selectList(
+ new LambdaQueryWrapper()
+ .eq(UserInbox::getMessageId, sysMessageVO.getId())
+ .select(UserInbox::getReceiverId, UserInbox::getIsRead)
+ .last("LIMIT 5")
+ );
+
+ // 设置收件用户集合
+ List receiveUsers = userInboxes.stream().map(userInbox -> {
+ UserReadMessageTimeVO vo = new UserReadMessageTimeVO();
+ vo.setId(userInbox.getReceiverId());
+
+ UmsStudent umsStudent = umsStudentMapper.selectOne(
+ new LambdaQueryWrapper()
+ .eq(UmsStudent::getUserId, userInbox.getReceiverId()));
+ if (umsStudent == null) {
+ vo.setReceiverName(umsTeacherMapper.selectOne(
+ new LambdaQueryWrapper()
+ .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()
+ .eq(UmsTeacher::getUserId, sysMessage.getSenderId()));
+ if (umsTeacher == null) {
+ sysMessageVO.setSenderName(umsStudentMapper.selectOne(
+ new LambdaQueryWrapper()
+ .eq(UmsStudent::getUserId, sysMessage.getSenderId())
+ ).getName());
+ } else {
+ sysMessageVO.setSenderName(umsTeacher.getName());
+ }
+
+ // 根据当前用户是发件人还是收件人决定查询的内容
+ if (sysMessage.getSenderId().equals(messagesQuery.getUserId())) {
+ // 发件人查看详情,查询所有收件人信息
+ List userInboxes = userInboxMapper.selectList(
+ new LambdaQueryWrapper()
+ .eq(UserInbox::getMessageId, messagesQuery.getMessageId())
+ );
+
+ List receiveUsers = userInboxes.stream().map(userInbox -> {
+ UserReadMessageTimeVO vo = new UserReadMessageTimeVO();
+ vo.setId(userInbox.getReceiverId());
+ UmsStudent umsStudent = umsStudentMapper.selectOne(
+ new LambdaQueryWrapper()
+ .eq(UmsStudent::getUserId, userInbox.getReceiverId()));
+ if (umsStudent == null) {
+ vo.setReceiverName(umsTeacherMapper.selectOne(
+ new LambdaQueryWrapper()
+ .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()
+ .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 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 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()
+ .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 userInboxes = userInboxMapper.selectList(
+ new LambdaQueryWrapper()
+ .eq(UserInbox::getMessageId, messageId)
+ .select(UserInbox::getReceiverId, UserInbox::getIsRead, UserInbox::getReadTime)
+ );
+
+ List receiverIds = userInboxes.stream().map(UserInbox::getReceiverId).collect(Collectors.toList());
+ sysMessageVO.setUserNum((long) receiverIds.size()); // 设置收信总人数
+
+ // 提取已读消息的 UserInbox 并按阅读时间降序排序
+ List 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 readStudents = readUserInboxes.stream()
+ .map(userInbox -> {
+ UserReadMessageTimeVO vo = new UserReadMessageTimeVO();
+ vo.setId(userInbox.getReceiverId());
+ UmsStudent umsStudent = umsStudentMapper.selectOne(
+ new LambdaQueryWrapper()
+ .eq(UmsStudent::getUserId, userInbox.getReceiverId()));
+ if (umsStudent == null) {
+ vo.setReceiverName(umsTeacherMapper.selectOne(
+ new LambdaQueryWrapper()
+ .eq(UmsTeacher::getUserId, userInbox.getReceiverId())
+ ).getName());
+ } else {
+ vo.setReceiverName(umsStudent.getName());
+ }
+ vo.setReadTime(userInbox.getReadTime());
+ return vo;
+ })
+ .collect(Collectors.toList());
+
+ // 创建未读用户的 UserReadMessageTimeVO 列表
+ List 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()
+ .eq(UmsStudent::getUserId, id));
+ if (umsStudent == null) {
+ vo.setReceiverName(umsTeacherMapper.selectOne(
+ new LambdaQueryWrapper()
+ .eq(UmsTeacher::getUserId, id)
+ ).getName());
+ } else {
+ vo.setReceiverName(umsStudent.getName());
+ }
+ return vo;
+ })
+ .collect(Collectors.toList());
+
+ // 设置已读和未读学生集合
+ sysMessageVO.setReadUsers(readStudents);
+ sysMessageVO.setNoReadUsers(noReadStudents);
+
+ return sysMessageVO;
+ }
+
+}
diff --git a/src/main/java/com/teaching/backend/service/message/IMessagesService.java b/src/main/java/com/teaching/backend/service/message/IMessagesService.java
new file mode 100644
index 0000000..687d204
--- /dev/null
+++ b/src/main/java/com/teaching/backend/service/message/IMessagesService.java
@@ -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;
+
+/**
+ *
+ * 服务类
+ *
+ *
+ * @author zjh
+ * @since 2024-08-06
+ */
+public interface IMessagesService extends IService {
+
+ String sendMessageToUserInbox(SysMessageDTO sysMessageDTO);
+
+ String deleteSendMessagesByLogical(List messageIds);
+
+}
diff --git a/src/main/java/com/teaching/backend/service/message/IUserInboxService.java b/src/main/java/com/teaching/backend/service/message/IUserInboxService.java
new file mode 100644
index 0000000..9bc13ba
--- /dev/null
+++ b/src/main/java/com/teaching/backend/service/message/IUserInboxService.java
@@ -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;
+
+/**
+ *
+ * 服务类
+ *
+ *
+ * @author zjh
+ * @since 2024-08-06
+ */
+public interface IUserInboxService extends IService {
+
+ PageDTO queryReceiveMessages(MessagesQuery messagesQuery);
+
+ SysMessageVO getMessageDetail(MessagesQuery messagesQuery);
+
+ PageDTO querySendMessages(MessagesQuery messagesQuery);
+
+ String readMessagesBatch(List messageIds, Long userId);
+
+ String deleteReceiveMessagesByLogical(List messageIds, Long userId);
+
+ SysMessageVO getReadStatus(Long userId, Long messageId);
+}
diff --git a/src/main/resources/mapper/UserInboxMapper.xml b/src/main/resources/mapper/UserInboxMapper.xml
new file mode 100644
index 0000000..99c8bec
--- /dev/null
+++ b/src/main/resources/mapper/UserInboxMapper.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+ INSERT INTO user_inbox (message_id, receiver_id)
+ VALUES
+
+ (#{item.messageId}, #{item.receiverId})
+
+
+