From e815bc6e05ca7cdaabd51068d7f9defbdad05269 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E4=BD=B3=E8=B1=AA?= Date: Thu, 19 Jun 2025 09:30:09 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B6=88=E6=81=AF=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mybatis/core/domain/BaseEntity.java | 10 +- .../handler/InjectionMetaObjectHandler.java | 2 +- ruoyi-modules/ruoyi-system/pom.xml | 18 ++ .../controller/SysMessageController.java | 178 +++++++++++++++++ .../SysMessageTemplateController.java | 90 +++++++++ .../system/converter/SysMessageConvert.java | 39 ++++ .../org/dromara/system/domain/SysMessage.java | 49 +++++ .../system/domain/SysMessageTemplate.java | 62 ++++++ .../dromara/system/domain/SysMessageUser.java | 49 +++++ .../system/domain/bo/SysMessageBo.java | 104 ++++++++++ .../domain/bo/SysMessageTemplateBo.java | 90 +++++++++ .../system/domain/event/MessageEvent.java | 23 +++ .../domain/vo/SysMessageTemplateVo.java | 59 ++++++ .../system/domain/vo/SysMessageUserVo.java | 45 +++++ .../system/domain/vo/SysMessageVo.java | 65 +++++++ .../system/event/MessageEventListener.java | 35 ++++ .../system/mapper/SysMessageMapper.java | 23 +++ .../mapper/SysMessageTemplateMapper.java | 14 ++ .../system/mapper/SysMessageUserMapper.java | 32 +++ .../dromara/system/mapper/SysUserMapper.java | 15 ++ .../service/IMessageWebSocketService.java | 26 +++ .../system/service/ISysMessageService.java | 136 +++++++++++++ .../service/ISysMessageTemplateService.java | 75 ++++++++ .../impl/MessageWebSocketServiceImpl.java | 31 +++ .../service/impl/SysMessageServiceImpl.java | 182 ++++++++++++++++++ .../impl/SysMessageTemplateServiceImpl.java | 83 ++++++++ .../service/impl/SysTenantServiceImpl.java | 10 +- .../system/task/MessageScheduledTask.java | 78 ++++++++ .../websocket/MessageWebSocketServer.java | 116 +++++++++++ .../src/main/resources/mapper/package-info.md | 3 - .../mapper/system/SysMessageMapper.xml | 32 +++ .../mapper/system/SysMessageUserMapper.xml | 33 ++++ .../resources/mapper/system/SysUserMapper.xml | 14 ++ .../impl/FlwDefinitionServiceImpl.java | 2 +- 34 files changed, 1808 insertions(+), 15 deletions(-) create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/SysMessageController.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/SysMessageTemplateController.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/converter/SysMessageConvert.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysMessage.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysMessageTemplate.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysMessageUser.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysMessageBo.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysMessageTemplateBo.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/event/MessageEvent.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysMessageTemplateVo.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysMessageUserVo.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysMessageVo.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/event/MessageEventListener.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysMessageMapper.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysMessageTemplateMapper.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysMessageUserMapper.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/IMessageWebSocketService.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysMessageService.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysMessageTemplateService.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/MessageWebSocketServiceImpl.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysMessageServiceImpl.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysMessageTemplateServiceImpl.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/task/MessageScheduledTask.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/websocket/MessageWebSocketServer.java delete mode 100644 ruoyi-modules/ruoyi-system/src/main/resources/mapper/package-info.md create mode 100644 ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysMessageMapper.xml create mode 100644 ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysMessageUserMapper.xml diff --git a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/core/domain/BaseEntity.java b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/core/domain/BaseEntity.java index 969ae6b5e..749fde7fe 100644 --- a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/core/domain/BaseEntity.java +++ b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/core/domain/BaseEntity.java @@ -31,11 +31,11 @@ public class BaseEntity implements Serializable { @TableField(exist = false) private String searchValue; - /** - * 创建部门 - */ - @TableField(fill = FieldFill.INSERT) - private Long createDept; +// /** +// * 创建部门 +// */ +// @TableField(fill = FieldFill.INSERT) +// private Long createDept; /** * 创建者 diff --git a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/InjectionMetaObjectHandler.java b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/InjectionMetaObjectHandler.java index 713d4ce0c..5413f6178 100644 --- a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/InjectionMetaObjectHandler.java +++ b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/InjectionMetaObjectHandler.java @@ -45,7 +45,7 @@ public class InjectionMetaObjectHandler implements MetaObjectHandler { // 填充创建人、更新人和创建部门信息 baseEntity.setCreateBy(userId); baseEntity.setUpdateBy(userId); - baseEntity.setCreateDept(ObjectUtils.notNull(baseEntity.getCreateDept(), loginUser.getDeptId())); +// baseEntity.setCreateDept(ObjectUtils.notNull(baseEntity.getCreateDept(), loginUser.getDeptId())); } } } else { diff --git a/ruoyi-modules/ruoyi-system/pom.xml b/ruoyi-modules/ruoyi-system/pom.xml index 7fdea9248..dd960febd 100644 --- a/ruoyi-modules/ruoyi-system/pom.xml +++ b/ruoyi-modules/ruoyi-system/pom.xml @@ -20,6 +20,7 @@ org.dromara ruoyi-common-core + ${revision} @@ -112,6 +113,23 @@ fastjson + + + org.springframework.boot + spring-boot-starter-websocket + + + + + jakarta.websocket + jakarta.websocket-api + + + + + org.apache.tomcat.embed + tomcat-embed-websocket + diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/SysMessageController.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/SysMessageController.java new file mode 100644 index 000000000..2e99b35e2 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/SysMessageController.java @@ -0,0 +1,178 @@ +package org.dromara.system.controller; + +import cn.dev33.satoken.annotation.SaCheckPermission; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import lombok.RequiredArgsConstructor; +import org.dromara.common.core.domain.R; +import org.dromara.common.core.service.UserService; +import org.dromara.common.core.utils.MapstructUtils; +import org.dromara.common.core.validate.AddGroup; +import org.dromara.common.core.validate.EditGroup; +import org.dromara.common.core.validate.QueryGroup; +import org.dromara.common.idempotent.annotation.RepeatSubmit; +import org.dromara.common.log.annotation.Log; +import org.dromara.common.log.enums.BusinessType; +import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.common.web.core.BaseController; +import org.dromara.common.satoken.utils.LoginHelper; +import org.dromara.system.domain.SysMessage; +import org.dromara.system.domain.SysUser; +import org.dromara.system.domain.bo.SysMessageBo; +import org.dromara.system.domain.bo.SysUserBo; +import org.dromara.system.domain.vo.SysMessageVo; +import org.dromara.system.domain.vo.SysUserVo; +import org.dromara.system.service.ISysMessageService; +import org.dromara.system.service.ISysUserService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.util.StringUtils; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * 消息管理 + * + * @author ruoyi + */ +@Validated +@RestController +@RequiredArgsConstructor +@RequestMapping("/system/message") +public class SysMessageController extends BaseController { + + private final ISysMessageService messageService; + private final ISysUserService userService; + + /** + * 获取当前用户ID + */ + private Long getUserId() { + return LoginHelper.getUserId(); + } + + /** + * 查询消息列表 + */ + @SaCheckPermission("system:message:list") + @PostMapping("/list") + public R> list(@RequestBody SysMessageBo bo, @RequestBody Page page) { + Page messagePage = messageService.page(page, bo.toWrapper()); + Page voPage = new Page<>(messagePage.getCurrent(), messagePage.getSize(), messagePage.getTotal()); + voPage.setRecords(MapstructUtils.convert(messagePage.getRecords(), SysMessageVo.class)); + return R.ok(voPage); + } + + /** + * 获取消息详细信息 + * + * @param id 消息ID + */ + @SaCheckPermission("system:message:query") + @GetMapping("/{id}") + public R getInfo(@NotNull(message = "消息ID不能为空") @PathVariable Long id) { + return R.ok(messageService.selectMessageById(id)); + } + + /** + * 发送消息 + */ + @SaCheckPermission("system:message:send") + @Log(title = "消息管理", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping("/send") + public R send(@Validated(AddGroup.class) @RequestBody SysMessageBo bo) { + List users = userService.selectUserListByDept(null); + List userIds; + + switch (bo.getSendScope()) { + case "all": + // 全部用户 + userIds = users.stream().map(SysUserVo::getUserId).toList(); + break; + case "expert": + // 达人 + userIds = users.stream() + .filter(user -> "expert".equals(user.getUserType())) + .map(SysUserVo::getUserId) + .toList(); + break; + case "merchant": + // 商户 + userIds = users.stream() + .filter(user -> "merchant".equals(user.getUserType())) + .map(SysUserVo::getUserId) + .toList(); + break; + case "user": + // 普通用户 + userIds = users.stream() + .filter(user -> "user".equals(user.getUserType())) + .map(SysUserVo::getUserId) + .toList(); + break; + default: + // 其他情况(如指定userIds) + userIds = bo.getUserIds(); + } + + return toAjax(messageService.sendMessageToUsers(bo, userIds)); + } + + /** + * 标记消息为已读 + */ + @SaCheckPermission("system:message:mark") + @Log(title = "消息管理", businessType = BusinessType.UPDATE) + @PutMapping("/mark/{id}") + public R markAsRead(@NotNull(message = "消息ID不能为空") @PathVariable Long id) { + return toAjax(messageService.markAsRead(id, getUserId())); + } + + /** + * 删除消息 + * + * @param ids 消息ID串 + */ + @SaCheckPermission("system:message:remove") + @Log(title = "消息管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public R remove(@NotEmpty(message = "消息ID不能为空") @PathVariable Long[] ids) { + return toAjax(messageService.deleteMessageByIds(ids)); + } + + /** + * 获取未读消息列表 + */ + @SaCheckPermission("system:message:list") + @GetMapping("/unread") + public TableDataInfo unreadList(PageQuery pageQuery) { + return messageService.selectPageUnreadMessages(getUserId(), pageQuery); + } + + /** + * 获取已读消息列表 + */ + @SaCheckPermission("system:message:list") + @GetMapping("/read") + public TableDataInfo readList(PageQuery pageQuery) { + return messageService.selectPageReadMessages(getUserId(), pageQuery); + } + + /** + * 获取用户列表 + */ +// @SaCheckPermission("system:message:list") +// @GetMapping("/user/list") +// public R> getUserList() { +// PageQuery pageQuery = new PageQuery(); +// pageQuery.setPageNum(1); +// pageQuery.setPageSize(Integer.MAX_VALUE); +// TableDataInfo users = userService.selectPageUserList(new SysUserBo(), pageQuery); +// return R.ok(users); +// } +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/SysMessageTemplateController.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/SysMessageTemplateController.java new file mode 100644 index 000000000..7ab52929a --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/SysMessageTemplateController.java @@ -0,0 +1,90 @@ +package org.dromara.system.controller; + +import cn.dev33.satoken.annotation.SaCheckPermission; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import lombok.RequiredArgsConstructor; +import org.dromara.common.core.domain.R; +import org.dromara.common.core.validate.AddGroup; +import org.dromara.common.core.validate.EditGroup; +import org.dromara.common.idempotent.annotation.RepeatSubmit; +import org.dromara.common.log.annotation.Log; +import org.dromara.common.log.enums.BusinessType; +import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.common.web.core.BaseController; +import org.dromara.system.domain.bo.SysMessageTemplateBo; +import org.dromara.system.domain.vo.SysMessageTemplateVo; +import org.dromara.system.service.ISysMessageTemplateService; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * 消息模板管理 + * + * @author ruoyi + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/system/message/template") +public class SysMessageTemplateController extends BaseController { + + private final ISysMessageTemplateService templateService; + + /** + * 查询消息模板列表 + */ + @SaCheckPermission("system:message:template:list") + @GetMapping("/list") + public TableDataInfo list(SysMessageTemplateBo bo, PageQuery pageQuery) { + return templateService.selectTemplatePage(bo, pageQuery); + } + + /** + * 获取消息模板详细信息 + * + * @param id 消息模板ID + */ + @SaCheckPermission("system:message:template:query") + @GetMapping("/{id}") + public R getInfo(@NotNull(message = "消息模板ID不能为空") @PathVariable Long id) { + return R.ok(templateService.selectTemplateById(id)); + } + + /** + * 新增消息模板 + */ + @SaCheckPermission("system:message:template:add") + @Log(title = "消息模板管理", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping() + public R add(@Validated(AddGroup.class) @RequestBody SysMessageTemplateBo bo) { + return toAjax(templateService.insertTemplate(bo)); + } + + /** + * 修改消息模板 + */ + @SaCheckPermission("system:message:template:edit") + @Log(title = "消息模板管理", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping() + public R edit(@Validated(EditGroup.class) @RequestBody SysMessageTemplateBo bo) { + return toAjax(templateService.updateTemplate(bo)); + } + + /** + * 删除消息模板 + * + * @param ids 消息模板ID串 + */ + @SaCheckPermission("system:message:template:remove") + @Log(title = "消息模板管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public R remove(@NotEmpty(message = "消息模板ID不能为空") @PathVariable Long[] ids) { + return toAjax(templateService.deleteTemplateByIds(ids)); + } +} \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/converter/SysMessageConvert.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/converter/SysMessageConvert.java new file mode 100644 index 000000000..11fe544f8 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/converter/SysMessageConvert.java @@ -0,0 +1,39 @@ +package org.dromara.system.converter; + +import org.dromara.system.domain.SysMessage; +import org.dromara.system.domain.vo.SysMessageVo; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +import java.util.List; + +/** + * 消息对象转换器 + * + * @author ruoyi + */ +@Mapper(componentModel = "spring") +public interface SysMessageConvert { + + SysMessageConvert INSTANCE = Mappers.getMapper(SysMessageConvert.class); + + /** + * SysMessage转SysMessageVo + */ + SysMessageVo convert(SysMessage sysMessage); + + /** + * SysMessage列表转SysMessageVo列表 + */ + List convertList(List sysMessageList); + + /** + * SysMessageVo转SysMessage + */ + SysMessage convert(SysMessageVo sysMessageVo); + + /** + * SysMessageVo列表转SysMessage列表 + */ + List convertListVoToEntity(List sysMessageVoList); +} \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysMessage.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysMessage.java new file mode 100644 index 000000000..88de0ca71 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysMessage.java @@ -0,0 +1,49 @@ +package org.dromara.system.domain; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.dromara.common.mybatis.core.domain.BaseEntity; +import org.dromara.common.tenant.core.TenantEntity; + +import java.io.Serializable; +import java.util.Date; + +/** + * 消息对象 sys_message + * + * @author ruoyi + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("sys_message") +public class SysMessage extends BaseEntity { + + private static final long serialVersionUID = 1L; + + /** 主键ID */ + @TableId(value = "id") + private Long id; + + /** 消息标题 */ + private String title; + + /** 消息内容 */ + private String content; + + /** 消息类型(AUTO自动/MANUAL手动) */ + private String msgType; + + /** 触发条件 */ + private String subType; + + /** 发送者ID */ + private Long senderId; + + /** 定时发送时间 */ + private Date scheduledTime; + +// /** 状态(0正常 1停用) */ +// private String status; +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysMessageTemplate.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysMessageTemplate.java new file mode 100644 index 000000000..26c6bc738 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysMessageTemplate.java @@ -0,0 +1,62 @@ +package org.dromara.system.domain; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.dromara.common.mybatis.core.domain.BaseEntity; +import org.dromara.common.tenant.core.TenantEntity; + +/** + * 消息模板对象 sys_message_template + * + * @author ruoyi + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("sys_message_template") +public class SysMessageTemplate extends BaseEntity { + + private static final long serialVersionUID = 1L; + + /** + * 模板ID + */ + @TableId(value = "id") + private Long id; + + /** + * 模板类型(1通知 2公告 3消息) + */ + private String templateType; + + /** + * 模板编码 + */ + private String templateCode; + + /** + * 模板名称 + */ + private String templateName; + + /** + * 模板内容 + */ + private String templateContent; + + /** + * 模板参数 + */ + private String templateParams; + + /** + * 状态(0正常 1停用) + */ + private String status; + + /** + * 备注 + */ + private String remark; +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysMessageUser.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysMessageUser.java new file mode 100644 index 000000000..8994159c1 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysMessageUser.java @@ -0,0 +1,49 @@ +package org.dromara.system.domain; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.dromara.common.mybatis.core.domain.BaseEntity; +import org.dromara.common.tenant.core.TenantEntity; + +import java.util.Date; + +/** + * 消息用户关联对象 sys_message_user + * + * @author ruoyi + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("sys_message_user") +public class SysMessageUser extends BaseEntity { + + private static final long serialVersionUID = 1L; + + /** + * 主键ID + */ + @TableId(value = "id") + private Long id; + + /** + * 消息ID + */ + private Long messageId; + + /** + * 用户ID + */ + private Long userId; + + /** + * 是否已读(0未读 1已读) + */ + private Boolean isRead; + + /** + * 阅读时间 + */ + private Date readTime; +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysMessageBo.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysMessageBo.java new file mode 100644 index 000000000..5082bc6da --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysMessageBo.java @@ -0,0 +1,104 @@ +package org.dromara.system.domain.bo; + +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; +import com.alibaba.excel.annotation.ExcelProperty; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Size; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.dromara.common.core.validate.AddGroup; +import org.dromara.common.core.validate.EditGroup; +import org.dromara.common.mybatis.core.domain.BaseEntity; +import org.dromara.system.domain.SysMessage; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.StringUtils; + +import java.util.Date; +import java.util.List; + +/** + * 消息业务对象 + * + * @author ruoyi + */ +@Data +@EqualsAndHashCode(callSuper = true) +@ExcelIgnoreUnannotated +public class SysMessageBo extends BaseEntity { + + /** 主键ID */ + @ExcelProperty(value = "消息ID") + private Long id; + + /** 消息标题 */ + @NotBlank(message = "消息标题不能为空", groups = { AddGroup.class, EditGroup.class }) + @Size(min = 0, max = 100, message = "消息标题长度不能超过100个字符") + @ExcelProperty(value = "消息标题") + private String title; + + /** 消息内容 */ + @NotBlank(message = "消息内容不能为空", groups = { AddGroup.class, EditGroup.class }) + @ExcelProperty(value = "消息内容") + private String content; + + /** 消息类型(AUTO自动/MANUAL手动) */ + @NotBlank(message = "消息类型不能为空", groups = { AddGroup.class, EditGroup.class }) + @ExcelProperty(value = "消息类型") + private String msgType; + + /** 触发条件 */ + @ExcelProperty(value = "触发条件") + private String subType; + + /** 发送者ID */ + @ExcelProperty(value = "发送者ID") + private Long senderId; + + /** 定时发送时间 */ + @ExcelProperty(value = "定时发送时间") + private Date scheduledTime; + +// /** 状态(0正常 1停用) */ +// @ExcelProperty(value = "状态") +// private String status; + + /** 发送范围(all:全部用户, userType:按用户类型, userIds:指定用户) */ + private String sendScope; + + /** 接收用户ID列表 */ + private List userIds; + +// /** 用户类型(1普通用户 2商家 3达人 4代理) */ +// private String userType; + + /** 是否发送给所有用户 */ + private Boolean sendToAll; + + public SysMessage toEntity() { + SysMessage entity = new SysMessage(); + entity.setId(this.getId()); + entity.setTitle(this.getTitle()); + entity.setContent(this.getContent()); + entity.setMsgType(this.getMsgType()); + entity.setSubType(this.getSubType()); + entity.setSenderId(this.getSenderId()); + entity.setScheduledTime(this.getScheduledTime()); +// entity.setStatus(this.getStatus()); + entity.setCreateBy(this.getCreateBy()); + entity.setCreateTime(this.getCreateTime()); + entity.setUpdateBy(this.getUpdateBy()); + entity.setUpdateTime(this.getUpdateTime()); + return entity; + } + + /** + * 转换为查询条件 + */ + public LambdaQueryWrapper toWrapper() { + LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); + lqw.like(StringUtils.isNotBlank(this.getTitle()), SysMessage::getTitle, this.getTitle()) + .eq(StringUtils.isNotBlank(this.getMsgType()), SysMessage::getMsgType, this.getMsgType()) + .orderByDesc(SysMessage::getCreateTime); + return lqw; + } +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysMessageTemplateBo.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysMessageTemplateBo.java new file mode 100644 index 000000000..fc6cca4ec --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysMessageTemplateBo.java @@ -0,0 +1,90 @@ +package org.dromara.system.domain.bo; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.dromara.common.core.validate.AddGroup; +import org.dromara.common.core.validate.EditGroup; +import org.dromara.common.mybatis.core.domain.BaseEntity; +import org.dromara.system.domain.SysMessageTemplate; + +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; + +/** + * 消息模板业务对象 sys_message_template + * + * @author ruoyi + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class SysMessageTemplateBo extends BaseEntity { + + /** + * 模板ID + */ + @NotNull(message = "模板ID不能为空", groups = { EditGroup.class }) + private Long id; + + /** + * 模板类型(1通知 2公告 3消息) + */ + @NotBlank(message = "模板类型不能为空", groups = { AddGroup.class, EditGroup.class }) + private String templateType; + + /** + * 模板编码 + */ + @NotBlank(message = "模板编码不能为空", groups = { AddGroup.class, EditGroup.class }) + @Size(min = 0, max = 64, message = "模板编码长度不能超过64个字符") + private String templateCode; + + /** + * 模板名称 + */ + @NotBlank(message = "模板名称不能为空", groups = { AddGroup.class, EditGroup.class }) + @Size(min = 0, max = 100, message = "模板名称长度不能超过100个字符") + private String templateName; + + /** + * 模板内容 + */ + @NotBlank(message = "模板内容不能为空", groups = { AddGroup.class, EditGroup.class }) + private String templateContent; + + /** + * 模板参数 + */ + private String templateParams; + +// /** +// * 状态(0正常 1停用) +// */ +// @NotBlank(message = "状态不能为空", groups = { AddGroup.class, EditGroup.class }) +// private String status; + + /** + * 备注 + */ + private String remark; + + /** + * 转换为实体对象 + */ + public SysMessageTemplate toEntity() { + SysMessageTemplate entity = new SysMessageTemplate(); + entity.setId(this.getId()); + entity.setTemplateType(this.getTemplateType()); + entity.setTemplateCode(this.getTemplateCode()); + entity.setTemplateName(this.getTemplateName()); + entity.setTemplateContent(this.getTemplateContent()); + entity.setTemplateParams(this.getTemplateParams()); +// entity.setStatus(this.getStatus()); + entity.setRemark(this.getRemark()); + entity.setCreateBy(this.getCreateBy()); + entity.setCreateTime(this.getCreateTime()); + entity.setUpdateBy(this.getUpdateBy()); + entity.setUpdateTime(this.getUpdateTime()); + return entity; + } +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/event/MessageEvent.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/event/MessageEvent.java new file mode 100644 index 000000000..9cea99281 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/event/MessageEvent.java @@ -0,0 +1,23 @@ +package org.dromara.system.domain.event; + +import lombok.Getter; +import org.dromara.system.domain.vo.SysMessageVo; +import org.springframework.context.ApplicationEvent; + +/** + * 消息事件 + * + * @author ruoyi + */ +@Getter +public class MessageEvent extends ApplicationEvent { + + private final SysMessageVo message; + private final Long userId; + + public MessageEvent(Object source, SysMessageVo message, Long userId) { + super(source); + this.message = message; + this.userId = userId; + } +} \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysMessageTemplateVo.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysMessageTemplateVo.java new file mode 100644 index 000000000..958fe5b61 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysMessageTemplateVo.java @@ -0,0 +1,59 @@ +package org.dromara.system.domain.vo; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.dromara.common.tenant.core.TenantEntity; + +import java.io.Serializable; + +/** + * 消息模板视图对象 sys_message_template + * + * @author ruoyi + */ +@Data +//@EqualsAndHashCode(callSuper = true) +public class SysMessageTemplateVo implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 模板ID + */ + private Long id; + + /** + * 模板类型(1通知 2公告 3消息) + */ + private String templateType; + + /** + * 模板编码 + */ + private String templateCode; + + /** + * 模板名称 + */ + private String templateName; + + /** + * 模板内容 + */ + private String templateContent; + + /** + * 模板参数 + */ + private String templateParams; + +// /** +// * 状态(0正常 1停用) +// */ +// private String status; + + /** + * 备注 + */ + private String remark; +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysMessageUserVo.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysMessageUserVo.java new file mode 100644 index 000000000..635c1beb1 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysMessageUserVo.java @@ -0,0 +1,45 @@ +package org.dromara.system.domain.vo; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.dromara.common.tenant.core.TenantEntity; + +import java.io.Serializable; +import java.util.Date; + +/** + * 消息用户关联视图对象 sys_message_user + * + * @author ruoyi + */ +@Data +//@EqualsAndHashCode(callSuper = true) +public class SysMessageUserVo implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 主键ID + */ + private Long id; + + /** + * 消息ID + */ + private Long messageId; + + /** + * 用户ID + */ + private Long userId; + + /** + * 是否已读(0未读 1已读) + */ + private Boolean isRead; + + /** + * 阅读时间 + */ + private Date readTime; +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysMessageVo.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysMessageVo.java new file mode 100644 index 000000000..455a29e47 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysMessageVo.java @@ -0,0 +1,65 @@ +package org.dromara.system.domain.vo; + +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; +import com.alibaba.excel.annotation.ExcelProperty; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; +import org.dromara.system.domain.SysMessage; +import org.dromara.system.domain.SysNotice; + +import java.io.Serial; +import java.io.Serializable; +import java.util.Date; + +/** + * 消息视图对象 + * + * @author ruoyi + */ +@Data +@AutoMapper(target = SysMessage.class) +public class SysMessageVo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** 主键ID */ + @ExcelProperty(value = "消息ID") + private Long id; + + /** 消息标题 */ + @ExcelProperty(value = "消息标题") + private String title; + + /** 消息内容 */ + @ExcelProperty(value = "消息内容") + private String content; + + /** 消息类型(AUTO自动/MANUAL手动) */ + @ExcelProperty(value = "消息类型") + private String msgType; + + /** 触发条件 */ + @ExcelProperty(value = "触发条件") + private String subType; + + /** 发送者ID */ + @ExcelProperty(value = "发送者ID") + private Long senderId; + + /** 发送者名称 */ + @ExcelProperty(value = "发送者") + private String senderName; + + /** 定时发送时间 */ + @ExcelProperty(value = "定时发送时间") + private Date scheduledTime; + +// /** 状态(0正常 1停用) */ +// @ExcelProperty(value = "状态") +// private String status; + + /** 创建时间 */ + @ExcelProperty(value = "创建时间") + private Date createTime; +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/event/MessageEventListener.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/event/MessageEventListener.java new file mode 100644 index 000000000..0c38d1c0e --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/event/MessageEventListener.java @@ -0,0 +1,35 @@ +package org.dromara.system.event; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.dromara.system.domain.event.MessageEvent; +import org.dromara.system.websocket.MessageWebSocketServer; +import org.springframework.context.event.EventListener; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Component; + +/** + * 消息事件监听器 + * + * @author ruoyi + */ +@Slf4j +@Component +@RequiredArgsConstructor +public class MessageEventListener { + + private final MessageWebSocketServer messageWebSocketServer; + + /** + * 处理消息事件 + */ + @Async + @EventListener + public void handleMessageEvent(MessageEvent event) { + try { + messageWebSocketServer.sendMessage(event.getUserId(), String.valueOf(event.getMessage())); + } catch (Exception e) { + log.error("处理消息事件失败", e); + } + } +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysMessageMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysMessageMapper.java new file mode 100644 index 000000000..03bcd9c77 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysMessageMapper.java @@ -0,0 +1,23 @@ +package org.dromara.system.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.dromara.system.domain.SysMessage; +import org.dromara.system.domain.vo.SysMessageVo; + +/** + * 消息Mapper接口 + * + * @author ruoyi + */ +public interface SysMessageMapper extends BaseMapper { + + /** + * 查询用户未读消息分页列表 + * + * @param page 分页参数 + * @param userId 用户ID + * @return 消息分页列表 + */ + Page selectPageUnreadMessages(Page page, Long userId); +} \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysMessageTemplateMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysMessageTemplateMapper.java new file mode 100644 index 000000000..7220814e7 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysMessageTemplateMapper.java @@ -0,0 +1,14 @@ +package org.dromara.system.mapper; + +import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; +import org.dromara.system.domain.SysMessageTemplate; +import org.dromara.system.domain.vo.SysMessageTemplateVo; + +/** + * 消息模板Mapper接口 + * + * @author ruoyi + */ +public interface SysMessageTemplateMapper extends BaseMapperPlus { + +} \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysMessageUserMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysMessageUserMapper.java new file mode 100644 index 000000000..13730aa4b --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysMessageUserMapper.java @@ -0,0 +1,32 @@ +package org.dromara.system.mapper; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; +import org.dromara.system.domain.SysMessageUser; +import org.dromara.system.domain.vo.SysMessageUserVo; + +/** + * 消息用户关联Mapper接口 + * + * @author ruoyi + */ +public interface SysMessageUserMapper extends BaseMapperPlus { + + /** + * 更新消息读取状态 + * + * @param messageId 消息ID + * @param userId 用户ID + * @param isRead 是否已读 + * @return 结果 + */ + default int updateReadStatus(Long messageId, Long userId, boolean isRead) { + LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + lqw.eq(SysMessageUser::getMessageId, messageId) + .eq(SysMessageUser::getUserId, userId); + SysMessageUser messageUser = new SysMessageUser(); + messageUser.setIsRead(isRead); + return update(messageUser, lqw); + } +} \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysUserMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysUserMapper.java index 46695aa4c..99a25cb33 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysUserMapper.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysUserMapper.java @@ -120,4 +120,19 @@ public interface SysUserMapper extends BaseMapperPlus { }) int updateById(@Param(Constants.ENTITY) SysUser user); + /** + * 根据用户类型查询用户ID列表 + * + * @param userType 用户类型 + * @return 用户ID列表 + */ + List selectUserIdsByType(@Param("userType") String userType); + + /** + * 查询所有用户ID + * + * @return 用户ID列表 + */ + List selectAllUserIds(); + } diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/IMessageWebSocketService.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/IMessageWebSocketService.java new file mode 100644 index 000000000..ce321e34d --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/IMessageWebSocketService.java @@ -0,0 +1,26 @@ +package org.dromara.system.service; + +import org.dromara.system.domain.vo.SysMessageVo; + +/** + * WebSocket消息服务接口 + * + * @author ruoyi + */ +public interface IMessageWebSocketService { + + /** + * 发送消息给指定用户 + * + * @param userId 用户ID + * @param message 消息内容 + */ + void sendMessage(Long userId, SysMessageVo message); + + /** + * 广播消息给所有在线用户 + * + * @param message 消息内容 + */ + void broadcastMessage(SysMessageVo message); +} \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysMessageService.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysMessageService.java new file mode 100644 index 000000000..158346f4b --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysMessageService.java @@ -0,0 +1,136 @@ +package org.dromara.system.service; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.service.IService; +import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.system.domain.SysMessage; +import org.dromara.system.domain.bo.SysMessageBo; +import org.dromara.system.domain.vo.SysMessageVo; + +import java.util.List; + +/** + * 消息Service接口 + * + * @author ruoyi + */ +public interface ISysMessageService extends IService { + + /** + * 分页查询消息列表 + */ + TableDataInfo selectPageMessageList(SysMessageBo bo, PageQuery pageQuery); + + /** + * 发送消息给指定用户 + * + * @param message 消息内容 + * @param userId 用户ID + * @return 结果 + */ + int sendMessageToUser(SysMessageBo message, Long userId); + + /** + * 发送消息给多个用户 + * + * @param message 消息内容 + * @param userIds 用户ID列表 + * @return 结果 + */ + int sendMessageToUsers(SysMessageBo message, List userIds); + + /** + * 发送自动消息 + * + * @param message 消息信息 + * @param userIds 用户ID列表 + * @return 结果 + */ + int sendAutoMessage(SysMessageBo message, List userIds); + + /** + * 标记消息为已读 + * + * @param messageId 消息ID + * @param userId 用户ID + * @return 结果 + */ + int markAsRead(Long messageId, Long userId); + + /** + * 查询用户未读消息分页列表 + * + * @param userId 用户ID + * @param pageQuery 分页参数 + * @return 消息分页列表 + */ + TableDataInfo selectPageUnreadMessages(Long userId, PageQuery pageQuery); + + /** + * 查询用户已读消息分页列表 + * + * @param userId 用户ID + * @param pageQuery 分页参数 + * @return 消息分页列表 + */ + TableDataInfo selectPageReadMessages(Long userId, PageQuery pageQuery); + + /** + * 查询消息列表 + * + * @param message 消息信息 + * @return 消息列表 + */ + List selectMessageList(SysMessageBo message); + + /** + * 查询消息详细信息 + * + * @param id 消息ID + * @return 消息信息 + */ + SysMessageVo selectMessageById(Long id); + + /** + * 新增消息 + * + * @param message 消息信息 + * @return 结果 + */ + int insertMessage(SysMessageBo message); + + /** + * 修改消息 + * + * @param message 消息信息 + * @return 结果 + */ + int updateMessage(SysMessageBo message); + + /** + * 批量删除消息 + * + * @param ids 需要删除的消息ID数组 + * @return 结果 + */ + int deleteMessageByIds(Long[] ids); + + /** + * 删除消息信息 + * + * @param id 消息ID + * @return 结果 + */ + int deleteMessageById(Long id); + + /** + * 将BO对象转换为查询条件 + * + * @param bo 业务对象 + * @return 查询条件 + */ + LambdaQueryWrapper toWrapper(SysMessageBo bo); + + +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysMessageTemplateService.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysMessageTemplateService.java new file mode 100644 index 000000000..c53b0ec44 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysMessageTemplateService.java @@ -0,0 +1,75 @@ +package org.dromara.system.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.system.domain.SysMessageTemplate; +import org.dromara.system.domain.bo.SysMessageTemplateBo; +import org.dromara.system.domain.vo.SysMessageTemplateVo; + +import java.util.List; + +/** + * 消息模板Service接口 + * + * @author ruoyi + */ +public interface ISysMessageTemplateService extends IService { + + /** + * 查询消息模板列表 + * + * @param template 消息模板信息 + * @return 消息模板列表 + */ + List selectTemplateList(SysMessageTemplateBo template); + + /** + * 查询消息模板分页列表 + * + * @param template 消息模板信息 + * @param pageQuery 分页参数 + * @return 消息模板分页列表 + */ + TableDataInfo selectTemplatePage(SysMessageTemplateBo template, PageQuery pageQuery); + + /** + * 查询消息模板详细信息 + * + * @param id 消息模板ID + * @return 消息模板信息 + */ + SysMessageTemplateVo selectTemplateById(Long id); + + /** + * 新增消息模板 + * + * @param template 消息模板信息 + * @return 结果 + */ + int insertTemplate(SysMessageTemplateBo template); + + /** + * 修改消息模板 + * + * @param template 消息模板信息 + * @return 结果 + */ + int updateTemplate(SysMessageTemplateBo template); + + /** + * 批量删除消息模板 + * + * @param ids 需要删除的消息模板ID数组 + * @return 结果 + */ + int deleteTemplateByIds(Long[] ids); + + /** + * 删除消息模板信息 + * + * @param id 消息模板ID + * @return 结果 + */ + int deleteTemplateById(Long id); +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/MessageWebSocketServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/MessageWebSocketServiceImpl.java new file mode 100644 index 000000000..9af04a16c --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/MessageWebSocketServiceImpl.java @@ -0,0 +1,31 @@ +package org.dromara.system.service.impl; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.dromara.system.domain.vo.SysMessageVo; +import org.dromara.system.service.IMessageWebSocketService; +import org.dromara.system.websocket.MessageWebSocketServer; +import org.springframework.stereotype.Service; + +/** + * WebSocket消息服务实现类 + * + * @author ruoyi + */ +@Slf4j +@Service +@RequiredArgsConstructor +public class MessageWebSocketServiceImpl implements IMessageWebSocketService { + + private final MessageWebSocketServer messageWebSocketServer; + + @Override + public void sendMessage(Long userId, SysMessageVo message) { + messageWebSocketServer.sendMessage(userId, String.valueOf(message)); + } + + @Override + public void broadcastMessage(SysMessageVo message) { + messageWebSocketServer.broadcastMessage(String.valueOf(message)); + } +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysMessageServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysMessageServiceImpl.java new file mode 100644 index 000000000..896b8b9c2 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysMessageServiceImpl.java @@ -0,0 +1,182 @@ +package org.dromara.system.service.impl; + +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 lombok.RequiredArgsConstructor; +import org.dromara.common.core.utils.MapstructUtils; +import org.dromara.common.core.utils.StringUtils; +import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.system.domain.SysMessage; +import org.dromara.system.domain.SysMessageUser; +import org.dromara.system.domain.bo.SysMessageBo; +import org.dromara.system.domain.event.MessageEvent; +import org.dromara.system.domain.vo.SysMessageVo; +import org.dromara.system.mapper.SysMessageMapper; +import org.dromara.system.mapper.SysMessageUserMapper; +import org.dromara.system.service.ISysMessageService; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +/** + * 消息Service业务层处理 + * + * @author ruoyi + */ +@Service +@RequiredArgsConstructor +public class SysMessageServiceImpl extends ServiceImpl implements ISysMessageService { + + private final SysMessageMapper messageMapper; + private final SysMessageUserMapper messageUserMapper; + private final ApplicationEventPublisher eventPublisher; + + @Override + public TableDataInfo selectPageMessageList(SysMessageBo bo, PageQuery pageQuery) { + LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); + lqw.like(StringUtils.isNotBlank(bo.getTitle()), SysMessage::getTitle, bo.getTitle()) + .eq(StringUtils.isNotBlank(bo.getMsgType()), SysMessage::getMsgType, bo.getMsgType()) +// .eq(StringUtils.isNotBlank(bo.getStatus()), SysMessage::getStatus, bo.getStatus()) + .orderByDesc(SysMessage::getCreateTime); + Page page = messageMapper.selectPage(pageQuery.build(), lqw); + List records = MapstructUtils.convert(page.getRecords(), SysMessageVo.class); + Page voPage = new Page<>(page.getCurrent(), page.getSize(), page.getTotal()); + voPage.setRecords(records); + return TableDataInfo.build(voPage); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public int sendMessageToUser(SysMessageBo message, Long userId) { + // 保存消息 + SysMessage entity = message.toEntity(); + messageMapper.insert(entity); + // 创建消息用户关联 + SysMessageUser messageUser = new SysMessageUser(); + messageUser.setMessageId(entity.getId()); + messageUser.setUserId(userId); + messageUser.setIsRead(false); + int rows = messageUserMapper.insert(messageUser); + // 发送WebSocket消息 + if (rows > 0) { + SysMessageVo messageVo = MapstructUtils.convert(entity, SysMessageVo.class); + eventPublisher.publishEvent(new MessageEvent(this, messageVo, userId)); + } + return rows; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public int sendMessageToUsers(SysMessageBo message, List userIds) { + // 保存消息 + SysMessage entity = message.toEntity(); + messageMapper.insert(entity); + // 批量创建消息用户关联 + int count = 0; + for (Long userId : userIds) { + SysMessageUser messageUser = new SysMessageUser(); + messageUser.setMessageId(entity.getId()); + messageUser.setUserId(userId); + messageUser.setIsRead(false); + int rows = messageUserMapper.insert(messageUser); + if (rows > 0) { + count++; + // 发送WebSocket消息 + SysMessageVo messageVo = MapstructUtils.convert(entity, SysMessageVo.class); + eventPublisher.publishEvent(new MessageEvent(this, messageVo, userId)); + } + } + return count; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public int sendAutoMessage(SysMessageBo message, List userIds) { + message.setMsgType("AUTO"); + return sendMessageToUsers(message, userIds); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public int markAsRead(Long messageId, Long userId) { + LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); + lqw.eq(SysMessageUser::getMessageId, messageId) + .eq(SysMessageUser::getUserId, userId); + SysMessageUser messageUser = new SysMessageUser(); + messageUser.setIsRead(true); + return messageUserMapper.update(messageUser, lqw); + } + + @Override + public TableDataInfo selectPageUnreadMessages(Long userId, PageQuery pageQuery) { + Page page = messageMapper.selectPageUnreadMessages(pageQuery.build(), userId); + return TableDataInfo.build(page); + } + + @Override + public TableDataInfo selectPageReadMessages(Long userId, PageQuery pageQuery) { + LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); +// lqw.eq(SysMessage::getStatus, "0") +// .inSql(SysMessage::getId, +// "SELECT message_id FROM sys_message_user WHERE user_id = " + userId + " AND is_read = 1") +// .orderByDesc(SysMessage::getCreateTime); +// + Page page = new Page<>(pageQuery.getPageNum(), pageQuery.getPageSize()); + Page resultPage = messageMapper.selectPage(page, lqw); + List records = MapstructUtils.convert(resultPage.getRecords(), SysMessageVo.class); + Page voPage = new Page<>(resultPage.getCurrent(), resultPage.getSize(), resultPage.getTotal()); + voPage.setRecords(records); + return TableDataInfo.build(voPage); + } + + @Override + public List selectMessageList(SysMessageBo message) { + LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); + lqw.eq(StringUtils.isNotBlank(message.getMsgType()), SysMessage::getMsgType, message.getMsgType()) + .eq(StringUtils.isNotBlank(message.getSubType()), SysMessage::getSubType, message.getSubType()) + .eq(message.getSenderId() != null, SysMessage::getSenderId, message.getSenderId()) +// .eq(StringUtils.isNotBlank(message.getStatus()), SysMessage::getStatus, message.getStatus()) + .orderByDesc(SysMessage::getCreateTime); + return MapstructUtils.convert(messageMapper.selectList(lqw), SysMessageVo.class); + } + + @Override + public SysMessageVo selectMessageById(Long id) { + return MapstructUtils.convert(messageMapper.selectById(id), SysMessageVo.class); + } + + @Override + public int insertMessage(SysMessageBo message) { + return messageMapper.insert(message.toEntity()); + } + + @Override + public int updateMessage(SysMessageBo message) { + return messageMapper.updateById(message.toEntity()); + } + + @Override + public int deleteMessageByIds(Long[] ids) { + return messageMapper.deleteBatchIds(List.of(ids)); + } + + @Override + public int deleteMessageById(Long id) { + return messageMapper.deleteById(id); + } + + @Override + public LambdaQueryWrapper toWrapper(SysMessageBo bo) { + LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); + lqw.like(StringUtils.isNotBlank(bo.getTitle()), SysMessage::getTitle, bo.getTitle()) + .eq(StringUtils.isNotBlank(bo.getMsgType()), SysMessage::getMsgType, bo.getMsgType()) + .orderByDesc(SysMessage::getCreateTime); + return lqw; + } + + +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysMessageTemplateServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysMessageTemplateServiceImpl.java new file mode 100644 index 000000000..c859018d4 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysMessageTemplateServiceImpl.java @@ -0,0 +1,83 @@ +package org.dromara.system.service.impl; + +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 lombok.RequiredArgsConstructor; +import org.dromara.common.core.utils.MapstructUtils; +import org.dromara.common.core.utils.StringUtils; +import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.system.domain.SysMessageTemplate; +import org.dromara.system.domain.bo.SysMessageTemplateBo; +import org.dromara.system.domain.vo.SysMessageTemplateVo; +import org.dromara.system.mapper.SysMessageTemplateMapper; +import org.dromara.system.service.ISysMessageTemplateService; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 消息模板Service业务层处理 + * + * @author ruoyi + */ +@RequiredArgsConstructor +@Service +public class SysMessageTemplateServiceImpl extends ServiceImpl implements ISysMessageTemplateService { + + private final SysMessageTemplateMapper templateMapper; + + @Override + public TableDataInfo selectTemplatePage(SysMessageTemplateBo bo, PageQuery pageQuery) { + LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); + lqw.eq(StringUtils.isNotBlank(bo.getTemplateType()), SysMessageTemplate::getTemplateType, bo.getTemplateType()) + .eq(StringUtils.isNotBlank(bo.getStatus()), SysMessageTemplate::getStatus, bo.getStatus()) + .like(StringUtils.isNotBlank(bo.getTemplateName()), SysMessageTemplate::getTemplateName, bo.getTemplateName()) + .like(StringUtils.isNotBlank(bo.getTemplateCode()), SysMessageTemplate::getTemplateCode, bo.getTemplateCode()) + .orderByDesc(SysMessageTemplate::getCreateTime); + + Page page = new Page<>(pageQuery.getPageNum(), pageQuery.getPageSize()); + Page resultPage = templateMapper.selectPage(page, lqw); + List records = MapstructUtils.convert(resultPage.getRecords(), SysMessageTemplateVo.class); + Page voPage = new Page<>(resultPage.getCurrent(), resultPage.getSize(), resultPage.getTotal()); + voPage.setRecords(records); + return TableDataInfo.build(voPage); + } + + @Override + public List selectTemplateList(SysMessageTemplateBo bo) { + LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); + lqw.eq(StringUtils.isNotBlank(bo.getTemplateType()), SysMessageTemplate::getTemplateType, bo.getTemplateType()) + .eq(StringUtils.isNotBlank(bo.getStatus()), SysMessageTemplate::getStatus, bo.getStatus()) + .like(StringUtils.isNotBlank(bo.getTemplateName()), SysMessageTemplate::getTemplateName, bo.getTemplateName()) + .like(StringUtils.isNotBlank(bo.getTemplateCode()), SysMessageTemplate::getTemplateCode, bo.getTemplateCode()) + .orderByDesc(SysMessageTemplate::getCreateTime); + return MapstructUtils.convert(templateMapper.selectList(lqw), SysMessageTemplateVo.class); + } + + @Override + public SysMessageTemplateVo selectTemplateById(Long id) { + return MapstructUtils.convert(templateMapper.selectById(id), SysMessageTemplateVo.class); + } + + @Override + public int insertTemplate(SysMessageTemplateBo bo) { + return templateMapper.insert(bo.toEntity()); + } + + @Override + public int updateTemplate(SysMessageTemplateBo bo) { + return templateMapper.updateById(bo.toEntity()); + } + + @Override + public int deleteTemplateByIds(Long[] ids) { + return templateMapper.deleteBatchIds(List.of(ids)); + } + + @Override + public int deleteTemplateById(Long id) { + return templateMapper.deleteById(id); + } +} \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysTenantServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysTenantServiceImpl.java index a73415c64..ac115f736 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysTenantServiceImpl.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysTenantServiceImpl.java @@ -179,7 +179,7 @@ public class SysTenantServiceImpl implements ISysTenantService { for (SysDictType dictType : dictTypeList) { dictType.setDictId(null); dictType.setTenantId(tenantId); - dictType.setCreateDept(null); +// dictType.setCreateDept(null); dictType.setCreateBy(null); dictType.setCreateTime(null); dictType.setUpdateBy(null); @@ -188,7 +188,7 @@ public class SysTenantServiceImpl implements ISysTenantService { for (SysDictData dictData : dictDataList) { dictData.setDictCode(null); dictData.setTenantId(tenantId); - dictData.setCreateDept(null); +// dictData.setCreateDept(null); dictData.setCreateBy(null); dictData.setCreateTime(null); dictData.setUpdateBy(null); @@ -202,7 +202,7 @@ public class SysTenantServiceImpl implements ISysTenantService { for (SysConfig config : sysConfigList) { config.setConfigId(null); config.setTenantId(tenantId); - config.setCreateDept(null); +// config.setCreateDept(null); config.setCreateBy(null); config.setCreateTime(null); config.setUpdateBy(null); @@ -448,7 +448,7 @@ public class SysTenantServiceImpl implements ISysTenantService { data.setTenantId(tenantId); data.setCreateTime(null); data.setUpdateTime(null); - data.setCreateDept(null); +// data.setCreateDept(null); data.setCreateBy(null); data.setUpdateBy(null); set.add(tenantId); @@ -472,7 +472,7 @@ public class SysTenantServiceImpl implements ISysTenantService { data.setTenantId(tenantId); data.setCreateTime(null); data.setUpdateTime(null); - data.setCreateDept(null); +// data.setCreateDept(null); data.setCreateBy(null); data.setUpdateBy(null); set.add(tenantId); diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/task/MessageScheduledTask.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/task/MessageScheduledTask.java new file mode 100644 index 000000000..9c4778efe --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/task/MessageScheduledTask.java @@ -0,0 +1,78 @@ +package org.dromara.system.task; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.dromara.common.core.utils.MapstructUtils; +import org.dromara.system.domain.SysMessage; +//import org.dromara.system.domain.SysMessageUser; +import org.dromara.system.domain.SysMessageUser; +import org.dromara.system.domain.vo.SysMessageVo; +import org.dromara.system.mapper.SysMessageMapper; +//import org.dromara.system.mapper.SysMessageUserMapper +import org.dromara.system.mapper.SysMessageUserMapper; +import org.dromara.system.websocket.MessageWebSocketServer; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; + +import java.time.LocalDateTime; +import java.util.List; + +/** + * 消息定时任务 + * + * @author ruoyi + */ +@Slf4j +@Component +@RequiredArgsConstructor +public class MessageScheduledTask { + + private final SysMessageMapper messageMapper; + private final SysMessageUserMapper messageUserMapper; + private final MessageWebSocketServer messageWebSocketServer; + + /** + * 每分钟执行一次,处理待发送的消息 + */ + @Scheduled(cron = "0 */1 * * * ?") + @Transactional(rollbackFor = Exception.class) + public void processScheduledMessages() { + log.info("开始处理定时消息..."); + try { + // 查询待发送的消息 + LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); +// lqw.eq(SysMessage::getStatus, "0") +// .le(SysMessage::getScheduledTime, LocalDateTime.now()) +// .isNotNull(SysMessage::getScheduledTime); + + List messages = messageMapper.selectList(lqw); + + for (SysMessage message : messages) { + // 查询消息接收者 + LambdaQueryWrapper userLqw = new LambdaQueryWrapper<>(); + userLqw.eq(SysMessageUser::getMessageId, message.getId()); + List messageUsers = messageUserMapper.selectList(userLqw); + + // 发送消息 + SysMessageVo messageVo = MapstructUtils.convert(message, SysMessageVo.class); + for (SysMessageUser messageUser : messageUsers) { + try { + messageWebSocketServer.sendMessage(messageUser.getUserId(), String.valueOf(messageVo)); + } catch (Exception e) { + log.error("发送消息失败,消息ID:{},用户ID:{}", message.getId(), messageUser.getUserId(), e); + } + } + + // 更新消息状态为已发送 +// message.setStatus("1"); + messageMapper.updateById(message); + } + + log.info("定时消息处理完成,共处理{}条消息", messages.size()); + } catch (Exception e) { + log.error("处理定时消息时发生错误", e); + } + } +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/websocket/MessageWebSocketServer.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/websocket/MessageWebSocketServer.java new file mode 100644 index 000000000..03ce98449 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/websocket/MessageWebSocketServer.java @@ -0,0 +1,116 @@ +package org.dromara.system.websocket; + +import jakarta.websocket.*; +import jakarta.websocket.server.ServerEndpoint; +import lombok.extern.slf4j.Slf4j; +import org.dromara.common.core.domain.model.LoginUser; +import org.dromara.common.websocket.holder.WebSocketSessionHolder; +import org.dromara.common.websocket.utils.WebSocketUtils; +import org.springframework.stereotype.Component; + +import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * 站内信 WebSocket 服务 + */ +@Slf4j +@Component +@ServerEndpoint("/websocket/message") +public class MessageWebSocketServer { + + /** + * 用户ID和会话的映射关系 + */ + private static final Map SESSION_MAP = new ConcurrentHashMap<>(); + + /** + * 连接建立成功调用的方法 + */ + @OnOpen + public void onOpen(Session session) { + log.info("[WebSocket] 新的连接建立,sessionId: {}", session.getId()); + try { + // 获取当前登录用户 + LoginUser loginUser = (LoginUser) session.getUserProperties().get("loginUser"); + if (loginUser != null) { + SESSION_MAP.put(loginUser.getUserId(), session); + log.info("[WebSocket] 用户 {} 连接成功", loginUser.getUserId()); + } else { + log.warn("[WebSocket] 未获取到用户信息,关闭连接"); + session.close(); + } + } catch (Exception e) { + log.error("[WebSocket] 连接建立失败", e); + } + } + + /** + * 连接关闭调用的方法 + */ + @OnClose + public void onClose(Session session) { + log.info("[WebSocket] 连接关闭,sessionId: {}", session.getId()); + // 从映射中移除会话 + SESSION_MAP.values().removeIf(s -> s.getId().equals(session.getId())); + } + + /** + * 收到客户端消息后调用的方法 + */ + @OnMessage + public void onMessage(String message, Session session) { + log.info("[WebSocket] 收到消息: {}", message); + // 这里可以处理客户端发送的消息 + } + + /** + * 发生错误时调用 + */ + @OnError + public void onError(Session session, Throwable error) { + log.error("[WebSocket] 发生错误", error); + // 从映射中移除会话 + SESSION_MAP.values().removeIf(s -> s.getId().equals(session.getId())); + } + + /** + * 发送消息给指定用户 + * + * @param userId 用户ID + * @param message 消息内容 + */ + public void sendMessage(Long userId, String message) { + Session session = SESSION_MAP.get(userId); + if (session != null && session.isOpen()) { + try { + session.getBasicRemote().sendText(message); + log.info("[WebSocket] 消息发送成功,接收者: {}", userId); + } catch (IOException e) { + log.error("[WebSocket] 消息发送失败", e); + } + } else { + log.warn("[WebSocket] 用户 {} 不在线或会话已关闭", userId); + } + } + + /** + * 广播消息给所有在线用户 + * + * @param message 消息内容 + */ + public void broadcastMessage(String message) { + SESSION_MAP.forEach((userId, session) -> { + if (session.isOpen()) { + try { + session.getBasicRemote().sendText(message); + log.info("[WebSocket] 广播消息发送成功,接收者: {}", userId); + } catch (IOException e) { + log.error("[WebSocket] 广播消息发送失败,接收者: {}", userId, e); + } + } + }); + } +} diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/package-info.md b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/package-info.md deleted file mode 100644 index c938b1e50..000000000 --- a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/package-info.md +++ /dev/null @@ -1,3 +0,0 @@ -java包使用 `.` 分割 resource 目录使用 `/` 分割 -
-此文件目的 防止文件夹粘连找不到 `xml` 文件 \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysMessageMapper.xml b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysMessageMapper.xml new file mode 100644 index 000000000..bc5135bf9 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysMessageMapper.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysMessageUserMapper.xml b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysMessageUserMapper.xml new file mode 100644 index 000000000..c89c93e52 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysMessageUserMapper.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + select id, message_id, user_id, is_read, read_time, create_time, update_time + from sys_message_user + + + + update sys_message_user + set is_read = #{isRead}, + read_time = sysdate() + where message_id = #{messageId} + and user_id = #{userId} + + + diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml index ded6fa858..fdd5e84a4 100644 --- a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml +++ b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml @@ -69,5 +69,19 @@ select count(*) from sys_user where del_flag = '0' and user_id = #{userId} + + + diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwDefinitionServiceImpl.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwDefinitionServiceImpl.java index 7f0f67ec6..b725b783d 100644 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwDefinitionServiceImpl.java +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwDefinitionServiceImpl.java @@ -220,7 +220,7 @@ public class FlwDefinitionServiceImpl implements IFlwDefinitionService { .eq(FlowCategory::getTenantId, DEFAULT_TENANT_ID).eq(FlowCategory::getCategoryId, FlowConstant.FLOW_CATEGORY_ID)); flowCategory.setCategoryId(null); flowCategory.setTenantId(tenantId); - flowCategory.setCreateDept(null); +// flowCategory.setCreateDept(null); flowCategory.setCreateBy(null); flowCategory.setCreateTime(null); flowCategory.setUpdateBy(null);