diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/controller/MsgNotificationController.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/controller/MsgNotificationController.java new file mode 100644 index 00000000..317cd76c --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/controller/MsgNotificationController.java @@ -0,0 +1,95 @@ +package org.dromara.message.controller; + +import cn.dev33.satoken.annotation.SaCheckPermission; +import jakarta.annotation.Resource; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import org.dromara.common.core.domain.R; +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.satoken.utils.LoginHelper; +import org.dromara.common.web.core.BaseController; +import org.dromara.message.domain.dto.notification.MsgNotificationQueryReq; +import org.dromara.message.domain.dto.notification.MsgNotificationSendMessageReq; +import org.dromara.message.domain.vo.notification.MsgNotificationVo; +import org.dromara.message.service.IMsgNotificationService; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * 消息通知 + * + * @author lilemy + * @date 2025-08-05 + */ +@Validated +@RestController +@RequestMapping("/message/notification") +public class MsgNotificationController extends BaseController { + + @Resource + private IMsgNotificationService msgNotificationService; + + /** + * 查询当前登录用户发送的消息通知列表 + */ + @SaCheckPermission("message:notification:listLoginSend") + @GetMapping("/list/send/login") + public TableDataInfo listByLoginSend(MsgNotificationQueryReq req, PageQuery pageQuery) { + Long userId = LoginHelper.getUserId(); + req.setSenderId(userId); + return msgNotificationService.queryPageList(req, pageQuery); + } + + /** + * 查询当前登录用户接收的消息通知列表 + */ + @SaCheckPermission("message:notification:listLoginRecipient") + @GetMapping("/list/recipient/login") + public TableDataInfo listByLoginRecipient(MsgNotificationQueryReq req, PageQuery pageQuery) { + Long userId = LoginHelper.getUserId(); + req.setRecipientId(userId); + return msgNotificationService.queryPageList(req, pageQuery); + } + + /** + * 获取消息通知详细信息 + * + * @param id 主键 + */ + @SaCheckPermission("message:notification:query") + @GetMapping("/{id}") + public R getInfo(@NotNull(message = "主键不能为空") + @PathVariable Long id) { + return R.ok(msgNotificationService.queryById(id)); + } + + /** + * 新增消息通知 + */ + @SaCheckPermission("message:notification:send") + @Log(title = "消息通知", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping("/send") + public R sendMessage(@Validated @RequestBody MsgNotificationSendMessageReq req) { + return toAjax(msgNotificationService.sendMessage(req)); + } + + /** + * 删除消息通知 + * + * @param ids 主键串 + */ + @SaCheckPermission("message:notification:remove") + @Log(title = "消息通知", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public R remove(@NotEmpty(message = "主键不能为空") + @PathVariable Long[] ids) { + return toAjax(msgNotificationService.deleteByIds(List.of(ids))); + } +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/controller/MsgNotifyTargetController.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/controller/MsgNotifyTargetController.java new file mode 100644 index 00000000..876673cb --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/controller/MsgNotifyTargetController.java @@ -0,0 +1,106 @@ +package org.dromara.message.controller; + +import cn.dev33.satoken.annotation.SaCheckPermission; +import jakarta.annotation.Resource; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import org.dromara.common.core.domain.R; +import org.dromara.common.excel.utils.ExcelUtil; +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.message.domain.dto.notifytarget.MsgNotifyTargetCreateReq; +import org.dromara.message.domain.dto.notifytarget.MsgNotifyTargetQueryReq; +import org.dromara.message.domain.dto.notifytarget.MsgNotifyTargetUpdateReq; +import org.dromara.message.domain.vo.notifytarget.MsgNotifyTargetVo; +import org.dromara.message.service.IMsgNotifyTargetService; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * 通知人员配置 + * + * @author lilemy + * @date 2025-08-05 + */ +@Validated +@RestController +@RequestMapping("/message/notifyTarget") +public class MsgNotifyTargetController extends BaseController { + + @Resource + private IMsgNotifyTargetService msgNotifyTargetService; + + /** + * 查询通知人员配置列表 + */ + @SaCheckPermission("message:notifyTarget:list") + @GetMapping("/list") + public TableDataInfo list(MsgNotifyTargetQueryReq req, PageQuery pageQuery) { + return msgNotifyTargetService.queryPageList(req, pageQuery); + } + + /** + * 导出通知人员配置列表 + */ + @SaCheckPermission("message:notifyTarget:export") + @Log(title = "通知人员配置", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(MsgNotifyTargetQueryReq req, HttpServletResponse response) { + List list = msgNotifyTargetService.queryList(req); + ExcelUtil.exportExcel(list, "通知人员配置", MsgNotifyTargetVo.class, response); + } + + /** + * 获取通知人员配置详细信息 + * + * @param id 主键 + */ + @SaCheckPermission("message:notifyTarget:query") + @GetMapping("/{id}") + public R getInfo(@NotNull(message = "主键不能为空") + @PathVariable Long id) { + return R.ok(msgNotifyTargetService.queryById(id)); + } + + /** + * 新增通知人员配置 + */ + @SaCheckPermission("message:notifyTarget:add") + @Log(title = "通知人员配置", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping() + public R add(@Validated @RequestBody MsgNotifyTargetCreateReq req) { + return toAjax(msgNotifyTargetService.insertByBo(req)); + } + + /** + * 修改通知人员配置 + */ + @SaCheckPermission("message:notifyTarget:edit") + @Log(title = "通知人员配置", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping() + public R edit(@Validated @RequestBody MsgNotifyTargetUpdateReq req) { + return toAjax(msgNotifyTargetService.updateByBo(req)); + } + + /** + * 删除通知人员配置 + * + * @param ids 主键串 + */ + @SaCheckPermission("message:notifyTarget:remove") + @Log(title = "通知人员配置", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public R remove(@NotEmpty(message = "主键不能为空") + @PathVariable Long[] ids) { + return toAjax(msgNotifyTargetService.deleteByIds(List.of(ids))); + } +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/controller/MsgTypeConfigController.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/controller/MsgTypeConfigController.java new file mode 100644 index 00000000..ee0c0784 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/controller/MsgTypeConfigController.java @@ -0,0 +1,105 @@ +package org.dromara.message.controller; + +import cn.dev33.satoken.annotation.SaCheckPermission; +import jakarta.annotation.Resource; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import org.dromara.common.core.domain.R; +import org.dromara.common.excel.utils.ExcelUtil; +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.web.core.BaseController; +import org.dromara.message.domain.dto.typeconfig.MsgTypeConfigCreateReq; +import org.dromara.message.domain.dto.typeconfig.MsgTypeConfigQueryReq; +import org.dromara.message.domain.dto.typeconfig.MsgTypeConfigUpdateReq; +import org.dromara.message.domain.vo.typeconfig.MsgTypeConfigVo; +import org.dromara.message.service.IMsgTypeConfigService; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * 消息类型配置 + * + * @author lilemy + * @date 2025-08-05 + */ +@Validated +@RestController +@RequestMapping("/message/typeConfig") +public class MsgTypeConfigController extends BaseController { + + @Resource + private IMsgTypeConfigService msgTypeConfigService; + + /** + * 查询消息类型配置列表 + */ + @SaCheckPermission("message:typeConfig:list") + @GetMapping("/list") + public R> list(MsgTypeConfigQueryReq req) { + List list = msgTypeConfigService.queryList(req); + return R.ok(list); + } + + /** + * 导出消息类型配置列表 + */ + @SaCheckPermission("message:typeConfig:export") + @Log(title = "消息类型配置", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(MsgTypeConfigQueryReq req, HttpServletResponse response) { + List list = msgTypeConfigService.queryList(req); + ExcelUtil.exportExcel(list, "消息类型配置", MsgTypeConfigVo.class, response); + } + + /** + * 获取消息类型配置详细信息 + * + * @param id 主键 + */ + @SaCheckPermission("message:typeConfig:query") + @GetMapping("/{id}") + public R getInfo(@NotNull(message = "主键不能为空") + @PathVariable Long id) { + return R.ok(msgTypeConfigService.queryById(id)); + } + + /** + * 新增消息类型配置 + */ + @SaCheckPermission("message:typeConfig:add") + @Log(title = "消息类型配置", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping() + public R add(@Validated @RequestBody MsgTypeConfigCreateReq req) { + return R.ok(msgTypeConfigService.insertByBo(req)); + } + + /** + * 修改消息类型配置 + */ + @SaCheckPermission("message:typeConfig:edit") + @Log(title = "消息类型配置", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping() + public R edit(@Validated @RequestBody MsgTypeConfigUpdateReq req) { + return toAjax(msgTypeConfigService.updateByBo(req)); + } + + /** + * 删除消息类型配置 + * + * @param ids 主键串 + */ + @SaCheckPermission("message:typeConfig:remove") + @Log(title = "消息类型配置", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public R remove(@NotEmpty(message = "主键不能为空") + @PathVariable Long[] ids) { + return toAjax(msgTypeConfigService.deleteByIds(List.of(ids))); + } +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/domain/MsgNotification.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/domain/MsgNotification.java new file mode 100644 index 00000000..06e292cf --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/domain/MsgNotification.java @@ -0,0 +1,95 @@ +package org.dromara.message.domain; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; +import java.util.Date; + +/** + * 消息通知对象 msg_notification + * + * @author lilemy + * @date 2025-08-05 + */ +@Data +@TableName("msg_notification") +public class MsgNotification implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键ID + */ + @TableId(value = "id") + private Long id; + + /** + * 项目ID + */ + private Long projectId; + + /** + * 接收通知的用户ID + */ + private Long recipientId; + + /** + * 发送通知的用户ID(系统通知 0) + */ + private Long senderId; + + /** + * 通知类型ID + */ + private Long typeId; + + /** + * 通知标题 + */ + private String title; + + /** + * 通知的主要内容 + */ + private String content; + + /** + * 查看状态(0未读 1已读) + */ + private String viewStatus; + + /** + * 查看时间 + */ + private Date viewTime; + + /** + * 点击通知后跳转的目标URL + */ + private String actionUrl; + + /** + * 通知附件 + */ + private String file; + + /** + * 备注 + */ + private String remark; + + /** + * 创建时间 + */ + private Date createTime; + + /** + * 更新时间 + */ + private Date updateTime; + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/domain/MsgNotifyTarget.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/domain/MsgNotifyTarget.java new file mode 100644 index 00000000..832f84c9 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/domain/MsgNotifyTarget.java @@ -0,0 +1,51 @@ +package org.dromara.message.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 java.io.Serial; + +/** + * 通知人员配置对象 msg_notify_target + * + * @author lilemy + * @date 2025-08-05 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("msg_notify_target") +public class MsgNotifyTarget extends BaseEntity { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键ID + */ + @TableId(value = "id") + private Long id; + + /** + * 项目ID + */ + private Long projectId; + + /** + * 消息类型ID + */ + private Long typeId; + + /** + * 是否启用(0正常 1禁用) + */ + private String status; + + /** + * 备注 + */ + private String remark; + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/domain/MsgNotifyTargetDetail.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/domain/MsgNotifyTargetDetail.java new file mode 100644 index 00000000..8a9f662b --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/domain/MsgNotifyTargetDetail.java @@ -0,0 +1,44 @@ +package org.dromara.message.domain; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; + +/** + * 通知人员配置详情对象 msg_notify_target_detail + * + * @author lilemy + * @date 2025-08-05 + */ +@Data +@TableName("msg_notify_target_detail") +public class MsgNotifyTargetDetail implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键ID + */ + @TableId(value = "id") + private Long id; + + /** + * 消息类型配置ID + */ + private Long configId; + + /** + * 接收类型 + */ + private String targetType; + + /** + * 接收ID + */ + private Long targetId; + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/domain/MsgTypeConfig.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/domain/MsgTypeConfig.java new file mode 100644 index 00000000..c4295ac0 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/domain/MsgTypeConfig.java @@ -0,0 +1,66 @@ +package org.dromara.message.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 java.io.Serial; + +/** + * 消息类型配置对象 msg_type_config + * + * @author lilemy + * @date 2025-08-05 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("msg_type_config") +public class MsgTypeConfig extends BaseEntity { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键ID + */ + @TableId(value = "id") + private Long id; + + /** + * 项目ID + */ + private Long projectId; + + /** + * 父ID + */ + private Long parentId; + + /** + * 消息类型编码 + */ + private String typeCode; + + /** + * 消息类型名称 + */ + private String typeName; + + /** + * 消息类型描述 + */ + private String typeDesc; + + /** + * 是否启用(0正常 1禁用) + */ + private String status; + + /** + * 备注 + */ + private String remark; + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/domain/dto/notification/MsgNotificationQueryReq.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/domain/dto/notification/MsgNotificationQueryReq.java new file mode 100644 index 00000000..9c90a02e --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/domain/dto/notification/MsgNotificationQueryReq.java @@ -0,0 +1,47 @@ +package org.dromara.message.domain.dto.notification; + +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; + +/** + * @author lilemy + * @date 2025-08-05 14:58 + */ +@Data +public class MsgNotificationQueryReq implements Serializable { + + @Serial + private static final long serialVersionUID = 6297082509342761841L; + + /** + * 项目ID + */ + private Long projectId; + + /** + * 接收通知的用户ID + */ + private Long recipientId; + + /** + * 发送通知的用户ID(系统通知 0) + */ + private Long senderId; + + /** + * 通知类型ID + */ + private Long typeId; + + /** + * 通知标题 + */ + private String title; + + /** + * 查看状态(0未读 1已读) + */ + private String viewStatus; +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/domain/dto/notification/MsgNotificationSendMessageReq.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/domain/dto/notification/MsgNotificationSendMessageReq.java new file mode 100644 index 00000000..f9761a9e --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/domain/dto/notification/MsgNotificationSendMessageReq.java @@ -0,0 +1,64 @@ +package org.dromara.message.domain.dto.notification; + +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; + +/** + * @author lilemy + * @date 2025-08-05 15:04 + */ +@Data +public class MsgNotificationSendMessageReq implements Serializable { + + @Serial + private static final long serialVersionUID = -3818662203023362981L; + + /** + * 项目ID + */ + private Long projectId; + + /** + * 接收通知的用户ID + */ + @NotNull(message = "接收通知的用户ID不能为空") + private Long recipientId; + + /** + * 通知类型ID + */ + @NotNull(message = "通知类型ID不能为空") + private Long typeId; + + /** + * 通知标题 + */ + @NotBlank(message = "通知标题不能为空") + private String title; + + /** + * 通知的主要内容 + */ + @NotBlank(message = "通知主要内容不能为空") + private String content; + + /** + * 点击通知后跳转的目标URL + */ + private String actionUrl; + + /** + * 通知附件 + */ + private String file; + + /** + * 备注 + */ + private String remark; + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/domain/dto/notifytarget/MsgNotifyTargetCreateReq.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/domain/dto/notifytarget/MsgNotifyTargetCreateReq.java new file mode 100644 index 00000000..6d67ffb1 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/domain/dto/notifytarget/MsgNotifyTargetCreateReq.java @@ -0,0 +1,50 @@ +package org.dromara.message.domain.dto.notifytarget; + +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import lombok.Data; +import org.dromara.message.domain.dto.notifytargetdetail.MsgNotifyTargetDetailCreateDto; + +import java.io.Serial; +import java.io.Serializable; +import java.util.List; + +/** + * @author lilemy + * @date 2025-08-05 16:14 + */ +@Data +public class MsgNotifyTargetCreateReq implements Serializable { + + @Serial + private static final long serialVersionUID = 6726656627774354043L; + + /** + * 项目ID + */ + @NotNull(message = "项目ID不能为空") + private Long projectId; + + /** + * 消息类型ID + */ + @NotNull(message = "消息类型ID不能为空") + private Long typeId; + + /** + * 通知人员配置详情列表 + */ + @NotEmpty(message = "通知人员配置详情列表不能为空") + private List detailList; + + /** + * 是否启用(0正常 1禁用) + */ + private String status; + + /** + * 备注 + */ + private String remark; + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/domain/dto/notifytarget/MsgNotifyTargetQueryReq.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/domain/dto/notifytarget/MsgNotifyTargetQueryReq.java new file mode 100644 index 00000000..24dd7c19 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/domain/dto/notifytarget/MsgNotifyTargetQueryReq.java @@ -0,0 +1,33 @@ +package org.dromara.message.domain.dto.notifytarget; + +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; + +/** + * @author lilemy + * @date 2025-08-05 16:14 + */ +@Data +public class MsgNotifyTargetQueryReq implements Serializable { + + @Serial + private static final long serialVersionUID = -1555802564920782912L; + + /** + * 项目ID + */ + private Long projectId; + + /** + * 消息类型ID + */ + private Long typeId; + + /** + * 是否启用(0正常 1禁用) + */ + private String status; + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/domain/dto/notifytarget/MsgNotifyTargetUpdateReq.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/domain/dto/notifytarget/MsgNotifyTargetUpdateReq.java new file mode 100644 index 00000000..78ef8117 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/domain/dto/notifytarget/MsgNotifyTargetUpdateReq.java @@ -0,0 +1,54 @@ +package org.dromara.message.domain.dto.notifytarget; + +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import lombok.Data; +import org.dromara.message.domain.dto.notifytargetdetail.MsgNotifyTargetDetailUpdateDto; + +import java.io.Serial; +import java.io.Serializable; +import java.util.List; + +/** + * @author lilemy + * @date 2025-08-05 16:15 + */ +@Data +public class MsgNotifyTargetUpdateReq implements Serializable { + + @Serial + private static final long serialVersionUID = -8315266866313669088L; + + /** + * 主键ID + */ + @NotNull(message = "主键ID不能为空") + private Long id; + + /** + * 项目ID + */ + private Long projectId; + + /** + * 消息类型ID + */ + private Long typeId; + + /** + * 通知人员配置详情列表 + */ + @NotEmpty(message = "通知人员配置详情列表不能为空") + private List detailList; + + /** + * 是否启用(0正常 1禁用) + */ + private String status; + + /** + * 备注 + */ + private String remark; + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/domain/dto/notifytargetdetail/MsgNotifyTargetDetailCreateDto.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/domain/dto/notifytargetdetail/MsgNotifyTargetDetailCreateDto.java new file mode 100644 index 00000000..d1042f92 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/domain/dto/notifytargetdetail/MsgNotifyTargetDetailCreateDto.java @@ -0,0 +1,26 @@ +package org.dromara.message.domain.dto.notifytargetdetail; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author lilemy + * @date 2025-08-05 17:34 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class MsgNotifyTargetDetailCreateDto { + + /** + * 接收类型 + */ + private String targetType; + + /** + * 接收ID + */ + private Long targetId; + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/domain/dto/notifytargetdetail/MsgNotifyTargetDetailUpdateDto.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/domain/dto/notifytargetdetail/MsgNotifyTargetDetailUpdateDto.java new file mode 100644 index 00000000..948b3489 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/domain/dto/notifytargetdetail/MsgNotifyTargetDetailUpdateDto.java @@ -0,0 +1,32 @@ +package org.dromara.message.domain.dto.notifytargetdetail; + +import lombok.Data; + +/** + * @author lilemy + * @date 2025-08-05 18:54 + */ +@Data +public class MsgNotifyTargetDetailUpdateDto { + + /** + * 主键ID + */ + private Long id; + + /** + * 消息类型配置ID + */ + private Long configId; + + /** + * 接收类型 + */ + private String targetType; + + /** + * 接收ID + */ + private Long targetId; + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/domain/dto/typeconfig/MsgTypeConfigCreateReq.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/domain/dto/typeconfig/MsgTypeConfigCreateReq.java new file mode 100644 index 00000000..6ddbeb64 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/domain/dto/typeconfig/MsgTypeConfigCreateReq.java @@ -0,0 +1,59 @@ +package org.dromara.message.domain.dto.typeconfig; + +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotEmpty; +import lombok.Data; +import org.dromara.message.domain.dto.notifytargetdetail.MsgNotifyTargetDetailCreateDto; + +import java.io.Serial; +import java.io.Serializable; +import java.util.List; + +/** + * @author lilemy + * @date 2025-08-05 11:55 + */ +@Data +public class MsgTypeConfigCreateReq implements Serializable { + + @Serial + private static final long serialVersionUID = 7200792696273923100L; + + /** + * 项目ID + */ + private Long projectId; + + /** + * 父ID + */ + private Long parentId; + + /** + * 消息类型编码 + */ + @NotBlank(message = "消息类型编码不能为空") + private String typeCode; + + /** + * 消息类型名称 + */ + @NotBlank(message = "消息类型名称不能为空") + private String typeName; + + /** + * 消息类型描述 + */ + private String typeDesc; + + /** + * 是否启用(0正常 1禁用) + */ + private String status; + + /** + * 备注 + */ + private String remark; + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/domain/dto/typeconfig/MsgTypeConfigQueryReq.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/domain/dto/typeconfig/MsgTypeConfigQueryReq.java new file mode 100644 index 00000000..a7865a48 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/domain/dto/typeconfig/MsgTypeConfigQueryReq.java @@ -0,0 +1,42 @@ +package org.dromara.message.domain.dto.typeconfig; + +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; + +/** + * @author lilemy + * @date 2025-08-05 11:56 + */ +@Data +public class MsgTypeConfigQueryReq implements Serializable { + + @Serial + private static final long serialVersionUID = 4107391817233057971L; + + /** + * 项目ID + */ + private Long projectId; + + /** + * 父ID + */ + private Long parentId; + + /** + * 消息类型编码 + */ + private String typeCode; + + /** + * 消息类型名称 + */ + private String typeName; + + /** + * 是否启用(0正常 1禁用) + */ + private String status; +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/domain/dto/typeconfig/MsgTypeConfigUpdateReq.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/domain/dto/typeconfig/MsgTypeConfigUpdateReq.java new file mode 100644 index 00000000..637211d1 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/domain/dto/typeconfig/MsgTypeConfigUpdateReq.java @@ -0,0 +1,55 @@ +package org.dromara.message.domain.dto.typeconfig; + +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; + +/** + * @author lilemy + * @date 2025-08-05 11:55 + */ +@Data +public class MsgTypeConfigUpdateReq implements Serializable { + + @Serial + private static final long serialVersionUID = -9036270979980317352L; + + /** + * 主键ID + */ + @NotNull(message = "主键ID不能为空") + private Long id; + + /** + * 父ID + */ + private Long parentId; + + /** + * 消息类型编码 + */ + private String typeCode; + + /** + * 消息类型名称 + */ + private String typeName; + + /** + * 消息类型描述 + */ + private String typeDesc; + + /** + * 是否启用(0正常 1禁用) + */ + private String status; + + /** + * 备注 + */ + private String remark; + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/domain/enums/MsgMessageTargetType.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/domain/enums/MsgMessageTargetType.java new file mode 100644 index 00000000..4786c37a --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/domain/enums/MsgMessageTargetType.java @@ -0,0 +1,25 @@ +package org.dromara.message.domain.enums; + +import lombok.Getter; + +/** + * @author lilemy + * @date 2025-08-05 16:47 + */ +@Getter +public enum MsgMessageTargetType { + + USER("用户", "1"), + ROLE("角色", "2"), + DEPT("部门", "3"); + + private final String text; + + private final String value; + + MsgMessageTargetType(String text, String value) { + this.text = text; + this.value = value; + } + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/domain/enums/MsgMessageViewStatus.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/domain/enums/MsgMessageViewStatus.java new file mode 100644 index 00000000..c2c0103d --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/domain/enums/MsgMessageViewStatus.java @@ -0,0 +1,24 @@ +package org.dromara.message.domain.enums; + +import lombok.Getter; + +/** + * @author lilemy + * @date 2025-08-05 15:39 + */ +@Getter +public enum MsgMessageViewStatus { + + NO("未读", "0"), + YSE("已读", "1"); + + private final String text; + + private final String value; + + MsgMessageViewStatus(String text, String value) { + this.text = text; + this.value = value; + } + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/domain/vo/notification/MsgNotificationVo.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/domain/vo/notification/MsgNotificationVo.java new file mode 100644 index 00000000..3997a1ac --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/domain/vo/notification/MsgNotificationVo.java @@ -0,0 +1,108 @@ +package org.dromara.message.domain.vo.notification; + +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; +import com.alibaba.excel.annotation.ExcelProperty; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; +import org.dromara.common.excel.annotation.ExcelDictFormat; +import org.dromara.common.excel.convert.ExcelDictConvert; +import org.dromara.message.domain.MsgNotification; + +import java.io.Serial; +import java.io.Serializable; +import java.util.Date; + + +/** + * 消息通知视图对象 msg_notification + * + * @author lilemy + * @date 2025-08-05 + */ +@Data +@ExcelIgnoreUnannotated +@AutoMapper(target = MsgNotification.class) +public class MsgNotificationVo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键ID + */ + @ExcelProperty(value = "主键ID") + private Long id; + + /** + * 项目ID + */ + @ExcelProperty(value = "项目ID") + private Long projectId; + + /** + * 接收通知的用户ID + */ + @ExcelProperty(value = "接收通知的用户ID") + private Long recipientId; + + /** + * 发送通知的用户ID(系统通知 0) + */ + @ExcelProperty(value = "发送通知的用户ID") + private Long senderId; + + /** + * 发送通知的用户名称 + */ + private String senderName; + + /** + * 通知类型ID + */ + @ExcelProperty(value = "通知类型ID") + private Long typeId; + + /** + * 通知标题 + */ + @ExcelProperty(value = "通知标题") + private String title; + + /** + * 通知的主要内容 + */ + @ExcelProperty(value = "通知的主要内容") + private String content; + + /** + * 查看状态(0未读 1已读) + */ + @ExcelProperty(value = "查看状态(0未读 1已读)", converter = ExcelDictConvert.class) + @ExcelDictFormat(dictType = "view_status") + private String viewStatus; + + /** + * 查看时间 + */ + @ExcelProperty(value = "查看时间") + private Date viewTime; + + /** + * 点击通知后跳转的目标URL + */ + @ExcelProperty(value = "点击通知后跳转的目标URL") + private String actionUrl; + + /** + * 通知附件 + */ + @ExcelProperty(value = "通知附件") + private String file; + + /** + * 备注 + */ + @ExcelProperty(value = "备注") + private String remark; + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/domain/vo/notifytarget/MsgNotifyTargetVo.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/domain/vo/notifytarget/MsgNotifyTargetVo.java new file mode 100644 index 00000000..a5f95a42 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/domain/vo/notifytarget/MsgNotifyTargetVo.java @@ -0,0 +1,67 @@ +package org.dromara.message.domain.vo.notifytarget; + +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; +import com.alibaba.excel.annotation.ExcelProperty; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; +import org.dromara.common.excel.annotation.ExcelDictFormat; +import org.dromara.common.excel.convert.ExcelDictConvert; +import org.dromara.message.domain.MsgNotifyTarget; +import org.dromara.message.domain.vo.notifytargetdetail.MsgNotifyTargetDetailVo; + +import java.io.Serial; +import java.io.Serializable; +import java.util.List; + + +/** + * 通知人员配置视图对象 msg_notify_target + * + * @author lilemy + * @date 2025-08-05 + */ +@Data +@ExcelIgnoreUnannotated +@AutoMapper(target = MsgNotifyTarget.class) +public class MsgNotifyTargetVo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键ID + */ + @ExcelProperty(value = "主键ID") + private Long id; + + /** + * 项目ID + */ + @ExcelProperty(value = "项目ID") + private Long projectId; + + /** + * 消息类型ID + */ + @ExcelProperty(value = "消息类型ID") + private Long typeId; + + /** + * 通知人员配置详情列表 + */ + private List detailList; + + /** + * 是否启用(0正常 1禁用) + */ + @ExcelProperty(value = "是否启用(0正常 1禁用)", converter = ExcelDictConvert.class) + @ExcelDictFormat(dictType = "sys_notice_status") + private String status; + + /** + * 备注 + */ + @ExcelProperty(value = "备注") + private String remark; + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/domain/vo/notifytargetdetail/MsgNotifyTargetDetailVo.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/domain/vo/notifytargetdetail/MsgNotifyTargetDetailVo.java new file mode 100644 index 00000000..dcddf6dc --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/domain/vo/notifytargetdetail/MsgNotifyTargetDetailVo.java @@ -0,0 +1,49 @@ +package org.dromara.message.domain.vo.notifytargetdetail; + +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; +import org.dromara.message.domain.MsgNotifyTargetDetail; + +import java.io.Serial; +import java.io.Serializable; + + +/** + * 通知人员配置详情视图对象 msg_notify_target_detail + * + * @author lilemy + * @date 2025-08-05 + */ +@Data +@AutoMapper(target = MsgNotifyTargetDetail.class) +public class MsgNotifyTargetDetailVo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键ID + */ + private Long id; + + /** + * 消息类型配置ID + */ + private Long configId; + + /** + * 接收类型 + */ + private String targetType; + + /** + * 接收ID + */ + private Long targetId; + + /** + * 接收名称 + */ + private String targetName; + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/domain/vo/typeconfig/MsgTypeConfigVo.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/domain/vo/typeconfig/MsgTypeConfigVo.java new file mode 100644 index 00000000..56ba028d --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/domain/vo/typeconfig/MsgTypeConfigVo.java @@ -0,0 +1,78 @@ +package org.dromara.message.domain.vo.typeconfig; + +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; +import com.alibaba.excel.annotation.ExcelProperty; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; +import org.dromara.common.excel.annotation.ExcelDictFormat; +import org.dromara.common.excel.convert.ExcelDictConvert; +import org.dromara.message.domain.MsgTypeConfig; + +import java.io.Serial; +import java.io.Serializable; + + +/** + * 消息类型配置视图对象 msg_type_config + * + * @author lilemy + * @date 2025-08-05 + */ +@Data +@ExcelIgnoreUnannotated +@AutoMapper(target = MsgTypeConfig.class) +public class MsgTypeConfigVo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键ID + */ + @ExcelProperty(value = "主键ID") + private Long id; + + /** + * 项目ID + */ + @ExcelProperty(value = "项目ID") + private Long projectId; + + /** + * 父ID + */ + @ExcelProperty(value = "父ID") + private Long parentId; + + /** + * 消息类型编码 + */ + @ExcelProperty(value = "消息类型编码") + private String typeCode; + + /** + * 消息类型名称 + */ + @ExcelProperty(value = "消息类型名称") + private String typeName; + + /** + * 消息类型描述 + */ + @ExcelProperty(value = "消息类型描述") + private String typeDesc; + + /** + * 是否启用(0正常 1禁用) + */ + @ExcelProperty(value = "是否启用(0正常 1禁用)", converter = ExcelDictConvert.class) + @ExcelDictFormat(dictType = "sys_notice_status") + private String status; + + /** + * 备注 + */ + @ExcelProperty(value = "备注") + private String remark; + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/mapper/MsgNotificationMapper.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/mapper/MsgNotificationMapper.java new file mode 100644 index 00000000..3fd7efcc --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/mapper/MsgNotificationMapper.java @@ -0,0 +1,15 @@ +package org.dromara.message.mapper; + +import org.dromara.message.domain.MsgNotification; +import org.dromara.message.domain.vo.notification.MsgNotificationVo; +import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; + +/** + * 消息通知Mapper接口 + * + * @author lilemy + * @date 2025-08-05 + */ +public interface MsgNotificationMapper extends BaseMapperPlus { + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/mapper/MsgNotifyTargetDetailMapper.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/mapper/MsgNotifyTargetDetailMapper.java new file mode 100644 index 00000000..14edb925 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/mapper/MsgNotifyTargetDetailMapper.java @@ -0,0 +1,15 @@ +package org.dromara.message.mapper; + +import org.dromara.message.domain.MsgNotifyTargetDetail; +import org.dromara.message.domain.vo.notifytargetdetail.MsgNotifyTargetDetailVo; +import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; + +/** + * 通知人员配置详情Mapper接口 + * + * @author lilemy + * @date 2025-08-05 + */ +public interface MsgNotifyTargetDetailMapper extends BaseMapperPlus { + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/mapper/MsgNotifyTargetMapper.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/mapper/MsgNotifyTargetMapper.java new file mode 100644 index 00000000..9c514b39 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/mapper/MsgNotifyTargetMapper.java @@ -0,0 +1,15 @@ +package org.dromara.message.mapper; + +import org.dromara.message.domain.MsgNotifyTarget; +import org.dromara.message.domain.vo.notifytarget.MsgNotifyTargetVo; +import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; + +/** + * 通知人员配置Mapper接口 + * + * @author lilemy + * @date 2025-08-05 + */ +public interface MsgNotifyTargetMapper extends BaseMapperPlus { + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/mapper/MsgTypeConfigMapper.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/mapper/MsgTypeConfigMapper.java new file mode 100644 index 00000000..d7612c51 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/mapper/MsgTypeConfigMapper.java @@ -0,0 +1,15 @@ +package org.dromara.message.mapper; + +import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; +import org.dromara.message.domain.MsgTypeConfig; +import org.dromara.message.domain.vo.typeconfig.MsgTypeConfigVo; + +/** + * 消息类型配置Mapper接口 + * + * @author lilemy + * @date 2025-08-05 + */ +public interface MsgTypeConfigMapper extends BaseMapperPlus { + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/service/IMsgNotificationService.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/service/IMsgNotificationService.java new file mode 100644 index 00000000..cc99e409 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/service/IMsgNotificationService.java @@ -0,0 +1,96 @@ +package org.dromara.message.service; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +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.message.domain.MsgNotification; +import org.dromara.message.domain.dto.notification.MsgNotificationQueryReq; +import org.dromara.message.domain.dto.notification.MsgNotificationSendMessageReq; +import org.dromara.message.domain.vo.notification.MsgNotificationVo; + +import java.util.Collection; +import java.util.List; + +/** + * 消息通知Service接口 + * + * @author lilemy + * @date 2025-08-05 + */ +public interface IMsgNotificationService extends IService { + + /** + * 校验消息通知权限 + * + * @param userId 用户ID + * @param notification 消息通知 + */ + void validHasPermission(Long userId, MsgNotification notification); + + /** + * 查询消息通知 + * + * @param id 主键 + * @return 消息通知 + */ + MsgNotificationVo queryById(Long id); + + /** + * 分页查询消息通知列表 + * + * @param req 查询条件 + * @param pageQuery 分页参数 + * @return 消息通知分页列表 + */ + TableDataInfo queryPageList(MsgNotificationQueryReq req, PageQuery pageQuery); + + /** + * 查询符合条件的消息通知列表 + * + * @param req 查询条件 + * @return 消息通知列表 + */ + List queryList(MsgNotificationQueryReq req); + + /** + * 发送消息通知 + * + * @param req 消息通知 + * @return 是否发送成功 + */ + Boolean sendMessage(MsgNotificationSendMessageReq req); + + /** + * 批量删除消息通知信息 + * + * @param ids 待删除的主键集合 + * @return 是否删除成功 + */ + Boolean deleteByIds(Collection ids); + + /** + * 获取消息通知视图对象 + * + * @param notification 消息通知对象 + * @return 消息通知视图对象 + */ + MsgNotificationVo getVo(MsgNotification notification); + + /** + * 获取消息通知查询条件封装 + * + * @param req 查询条件 + * @return 查询条件封装 + */ + LambdaQueryWrapper buildQueryWrapper(MsgNotificationQueryReq req); + + /** + * 获取消息通知分页对象视图 + * + * @param notificationPage 消息通知分页对象 + * @return 消息通知分页详情对象视图 + */ + Page getVoPage(Page notificationPage); +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/service/IMsgNotifyTargetDetailService.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/service/IMsgNotifyTargetDetailService.java new file mode 100644 index 00000000..607f9f88 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/service/IMsgNotifyTargetDetailService.java @@ -0,0 +1,49 @@ +package org.dromara.message.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import org.dromara.message.domain.MsgNotifyTargetDetail; +import org.dromara.message.domain.vo.notifytargetdetail.MsgNotifyTargetDetailVo; + +import java.util.List; + +/** + * 通知人员配置详情Service接口 + * + * @author lilemy + * @date 2025-08-05 + */ +public interface IMsgNotifyTargetDetailService extends IService { + + /** + * 根据通知目标ID查询用户ID列表 + * + * @param targetId 通知目标ID + * @return 用户ID列表 + */ + List queryUserIdsByTargetId(Long targetId); + + /** + * 根据通知目标ID查询通知目标详情列表 + * + * @param targetId 通知目标ID + * @return 通知目标详情列表 + */ + List queryVoListByTargetId(Long targetId); + + /** + * 获取通知人员配置详情封装 + * + * @param detail 通知人员配置详情 + * @return 通知人员配置详情封装 + */ + MsgNotifyTargetDetailVo getVo(MsgNotifyTargetDetail detail); + + /** + * 批量获取通知人员配置详情封装 + * + * @param detailList 通知人员配置详情列表 + * @return 通知人员配置详情封装列表 + */ + List getVoList(List detailList); + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/service/IMsgNotifyTargetService.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/service/IMsgNotifyTargetService.java new file mode 100644 index 00000000..a1984c48 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/service/IMsgNotifyTargetService.java @@ -0,0 +1,97 @@ +package org.dromara.message.service; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +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.message.domain.MsgNotifyTarget; +import org.dromara.message.domain.dto.notifytarget.MsgNotifyTargetCreateReq; +import org.dromara.message.domain.dto.notifytarget.MsgNotifyTargetQueryReq; +import org.dromara.message.domain.dto.notifytarget.MsgNotifyTargetUpdateReq; +import org.dromara.message.domain.vo.notifytarget.MsgNotifyTargetVo; + +import java.util.Collection; +import java.util.List; + +/** + * 通知人员配置Service接口 + * + * @author lilemy + * @date 2025-08-05 + */ +public interface IMsgNotifyTargetService extends IService { + + /** + * 查询通知人员配置 + * + * @param id 主键 + * @return 通知人员配置 + */ + MsgNotifyTargetVo queryById(Long id); + + /** + * 分页查询通知人员配置列表 + * + * @param req 查询条件 + * @param pageQuery 分页参数 + * @return 通知人员配置分页列表 + */ + TableDataInfo queryPageList(MsgNotifyTargetQueryReq req, PageQuery pageQuery); + + /** + * 查询符合条件的通知人员配置列表 + * + * @param req 查询条件 + * @return 通知人员配置列表 + */ + List queryList(MsgNotifyTargetQueryReq req); + + /** + * 新增通知人员配置 + * + * @param req 通知人员配置 + * @return 是否新增成功 + */ + Boolean insertByBo(MsgNotifyTargetCreateReq req); + + /** + * 修改通知人员配置 + * + * @param req 通知人员配置 + * @return 是否修改成功 + */ + Boolean updateByBo(MsgNotifyTargetUpdateReq req); + + /** + * 批量删除通知人员配置信息 + * + * @param ids 待删除的主键集合 + * @return 是否删除成功 + */ + Boolean deleteByIds(Collection ids); + + /** + * 获取通知人员配置视图对象 + * + * @param notifyTarget 通知人员配置对象 + * @return 通知人员配置视图对象 + */ + MsgNotifyTargetVo getVo(MsgNotifyTarget notifyTarget); + + /** + * 获取通知人员配置查询条件封装 + * + * @param req 查询条件 + * @return 查询条件封装 + */ + LambdaQueryWrapper buildQueryWrapper(MsgNotifyTargetQueryReq req); + + /** + * 获取通知人员配置分页对象视图 + * + * @param notifyTargetPage 通知人员配置分页对象 + * @return 通知人员配置分页详情对象视图 + */ + Page getVoPage(Page notifyTargetPage); +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/service/IMsgTypeConfigService.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/service/IMsgTypeConfigService.java new file mode 100644 index 00000000..11722d79 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/service/IMsgTypeConfigService.java @@ -0,0 +1,86 @@ +package org.dromara.message.service; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.service.IService; +import org.dromara.message.domain.MsgTypeConfig; +import org.dromara.message.domain.dto.typeconfig.MsgTypeConfigCreateReq; +import org.dromara.message.domain.dto.typeconfig.MsgTypeConfigQueryReq; +import org.dromara.message.domain.dto.typeconfig.MsgTypeConfigUpdateReq; +import org.dromara.message.domain.vo.typeconfig.MsgTypeConfigVo; + +import java.util.Collection; +import java.util.List; + +/** + * 消息类型配置Service接口 + * + * @author lilemy + * @date 2025-08-05 + */ +public interface IMsgTypeConfigService extends IService { + + /** + * 查询消息类型配置 + * + * @param id 主键 + * @return 消息类型配置 + */ + MsgTypeConfigVo queryById(Long id); + + + /** + * 查询符合条件的消息类型配置列表 + * + * @param req 查询条件 + * @return 消息类型配置列表 + */ + List queryList(MsgTypeConfigQueryReq req); + + /** + * 新增消息类型配置 + * + * @param req 消息类型配置 + * @return 新增成功消息类型配置id + */ + Long insertByBo(MsgTypeConfigCreateReq req); + + /** + * 修改消息类型配置 + * + * @param req 消息类型配置 + * @return 是否修改成功 + */ + Boolean updateByBo(MsgTypeConfigUpdateReq req); + + /** + * 批量删除消息类型配置信息 + * + * @param ids 待删除的主键集合 + * @return 是否删除成功 + */ + Boolean deleteByIds(Collection ids); + + /** + * 获取消息类型配置视图对象 + * + * @param typeConfig 消息类型配置对象 + * @return 消息类型配置视图对象 + */ + MsgTypeConfigVo getVo(MsgTypeConfig typeConfig); + + /** + * 获取消息类型配置查询条件封装 + * + * @param req 查询条件 + * @return 查询条件封装 + */ + LambdaQueryWrapper buildQueryWrapper(MsgTypeConfigQueryReq req); + + /** + * 获取消息类型配置分页对象视图 + * + * @param typeConfigList 消息类型配置分页对象 + * @return 消息类型配置分页对象视图 + */ + List getVoList(List typeConfigList); +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/service/impl/MsgNotificationServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/service/impl/MsgNotificationServiceImpl.java new file mode 100644 index 00000000..19de83f6 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/service/impl/MsgNotificationServiceImpl.java @@ -0,0 +1,280 @@ +package org.dromara.message.service.impl; + +import cn.hutool.core.collection.CollUtil; +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 jakarta.annotation.Resource; +import org.dromara.common.core.constant.HttpStatus; +import org.dromara.common.core.exception.ServiceException; +import org.dromara.common.core.utils.ObjectUtils; +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.common.satoken.utils.LoginHelper; +import org.dromara.common.sse.dto.SseMessageDto; +import org.dromara.common.sse.utils.SseMessageUtils; +import org.dromara.message.domain.MsgNotification; +import org.dromara.message.domain.MsgTypeConfig; +import org.dromara.message.domain.dto.notification.MsgNotificationQueryReq; +import org.dromara.message.domain.dto.notification.MsgNotificationSendMessageReq; +import org.dromara.message.domain.enums.MsgMessageViewStatus; +import org.dromara.message.domain.vo.notification.MsgNotificationVo; +import org.dromara.message.mapper.MsgNotificationMapper; +import org.dromara.message.service.IMsgNotificationService; +import org.dromara.message.service.IMsgTypeConfigService; +import org.dromara.system.domain.vo.SysUserVo; +import org.dromara.system.service.ISysUserService; +import org.springframework.beans.BeanUtils; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Collection; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * 消息通知Service业务层处理 + * + * @author lilemy + * @date 2025-08-05 + */ +@Service +public class MsgNotificationServiceImpl extends ServiceImpl + implements IMsgNotificationService { + + @Resource + private ISysUserService userService; + + @Resource + private IMsgTypeConfigService typeConfigService; + + /** + * 校验消息通知权限 + * + * @param userId 用户ID + * @param notification 消息通知 + */ + @Override + public void validHasPermission(Long userId, MsgNotification notification) { + Long senderId = notification.getSenderId(); + Long recipientId = notification.getRecipientId(); + if ((senderId == 0 && !userId.equals(recipientId)) + || (senderId != 0 && !userId.equals(senderId) && !userId.equals(recipientId))) { + throw new ServiceException("无权限处理此消息通知", HttpStatus.FORBIDDEN); + } + } + + /** + * 查询消息通知 + * + * @param id 主键 + * @return 消息通知 + */ + @Override + public MsgNotificationVo queryById(Long id) { + MsgNotification notification = this.getById(id); + if (notification == null) { + throw new ServiceException("消息通知信息不存在", HttpStatus.NOT_FOUND); + } + Long userId = LoginHelper.getUserId(); + if (userId == null) { + throw new ServiceException("未获取到用户信息", HttpStatus.UNAUTHORIZED); + } + // 校验权限 + validHasPermission(userId, notification); + // 如果为消息接收方,则修改状态为已阅读 + if (userId.equals(notification.getRecipientId()) && notification.getViewStatus().equals(MsgMessageViewStatus.NO.getValue())) { + notification.setViewStatus(MsgMessageViewStatus.YSE.getValue()); + notification.setViewTime(new Date()); + this.updateById(notification); + } + return this.getVo(notification); + } + + /** + * 分页查询消息通知列表 + * + * @param req 查询条件 + * @param pageQuery 分页参数 + * @return 消息通知分页列表 + */ + @Override + public TableDataInfo queryPageList(MsgNotificationQueryReq req, PageQuery pageQuery) { + Page result = this.page(pageQuery.build(), this.buildQueryWrapper(req)); + return TableDataInfo.build(this.getVoPage(result)); + } + + /** + * 查询符合条件的消息通知列表 + * + * @param req 查询条件 + * @return 消息通知列表 + */ + @Override + public List queryList(MsgNotificationQueryReq req) { + List list = this.list(this.buildQueryWrapper(req)); + // 获取发送用户信息 + List senderUserIds = list.stream() + .map(MsgNotification::getSenderId).distinct().filter(id -> id != null && id != 0).toList(); + List senderUserVoList = userService.selectUserByIds(senderUserIds, null); + Map senderUserMap = senderUserVoList.stream() + .collect(Collectors.toMap(SysUserVo::getUserId, SysUserVo::getNickName)); + return list.stream().map(notification -> { + MsgNotificationVo notificationVo = new MsgNotificationVo(); + BeanUtils.copyProperties(notification, notificationVo); + // 关联发送用户信息 + Long senderId = notification.getSenderId(); + if (senderId != null && senderId != 0 && senderUserMap.containsKey(senderId)) { + notificationVo.setSenderName(senderUserMap.get(senderId)); + } + return notificationVo; + } + ).toList(); + } + + /** + * 发送消息通知 + * + * @param req 消息通知 + * @return 是否发送成功 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean sendMessage(MsgNotificationSendMessageReq req) { + // 记录发送消息 + MsgNotification notification = new MsgNotification(); + BeanUtils.copyProperties(req, notification); + Long recipientId = req.getRecipientId(); + if (userService.selectUserById(recipientId) == null) { + throw new ServiceException("接收用户不存在", HttpStatus.NOT_FOUND); + } + Long typeId = notification.getTypeId(); + MsgTypeConfig typeConfig = typeConfigService.getById(typeId); + if (typeConfig == null) { + throw new ServiceException("消息类型不存在", HttpStatus.NOT_FOUND); + } + // 填充默认值 + Long userId = LoginHelper.getUserId(); + if (userId == null) { + throw new ServiceException("未获取到用户信息", HttpStatus.UNAUTHORIZED); + } + notification.setSenderId(userId); + boolean save = this.save(notification); + if (!save) { + throw new ServiceException("发送消息失败", HttpStatus.ERROR); + } + // 使用 sse 发送消息 + SseMessageDto sseMessageDto = new SseMessageDto(); + sseMessageDto.setUserIds(List.of(recipientId)); + String message = StringUtils.format("您有一条{}消息,请及时查看", typeConfig.getTypeName()); + sseMessageDto.setMessage(message); + SseMessageUtils.publishMessage(sseMessageDto); + return true; + } + + /** + * 批量删除消息通知信息 + * + * @param ids 待删除的主键集合 + * @return 是否删除成功 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean deleteByIds(Collection ids) { + List notifications = this.listByIds(ids); + if (CollUtil.isEmpty(notifications)) { + return false; + } + Long userId = LoginHelper.getUserId(); + notifications.forEach(notification -> validHasPermission(userId, notification)); + return removeBatchByIds(ids); + } + + /** + * 获取消息通知视图对象 + * + * @param notification 消息通知对象 + * @return 消息通知视图对象 + */ + @Override + public MsgNotificationVo getVo(MsgNotification notification) { + MsgNotificationVo vo = new MsgNotificationVo(); + if (notification == null) { + return vo; + } + BeanUtils.copyProperties(notification, vo); + // 获取发送用户信息 + Long senderId = notification.getSenderId(); + if (senderId != null && senderId != 0) { + SysUserVo userVo = userService.selectUserById(senderId); + vo.setSenderName(userVo.getNickName()); + } + return vo; + } + + /** + * 获取消息通知查询条件封装 + * + * @param req 查询条件 + * @return 查询条件封装 + */ + @Override + public LambdaQueryWrapper buildQueryWrapper(MsgNotificationQueryReq req) { + LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); + if (req == null) { + return lqw; + } + Long projectId = req.getProjectId(); + Long recipientId = req.getRecipientId(); + Long senderId = req.getSenderId(); + Long typeId = req.getTypeId(); + String title = req.getTitle(); + String viewStatus = req.getViewStatus(); + lqw.eq(ObjectUtils.isNotEmpty(projectId), MsgNotification::getProjectId, projectId); + lqw.eq(ObjectUtils.isNotEmpty(recipientId), MsgNotification::getRecipientId, recipientId); + lqw.eq(ObjectUtils.isNotEmpty(senderId), MsgNotification::getSenderId, senderId); + lqw.eq(ObjectUtils.isNotEmpty(typeId), MsgNotification::getTypeId, typeId); + lqw.like(StringUtils.isNotBlank(title), MsgNotification::getTitle, title); + lqw.eq(StringUtils.isNotBlank(viewStatus), MsgNotification::getViewStatus, viewStatus); + return lqw; + } + + /** + * 获取消息通知分页对象视图 + * + * @param notificationPage 消息通知分页对象 + * @return 消息通知分页详情对象视图 + */ + @Override + public Page getVoPage(Page notificationPage) { + List notificationList = notificationPage.getRecords(); + Page notificationVoPage = new Page<>( + notificationPage.getCurrent(), + notificationPage.getSize(), + notificationPage.getTotal()); + if (CollUtil.isEmpty(notificationList)) { + return notificationVoPage; + } + // 获取发送用户信息 + List senderUserIds = notificationList.stream() + .map(MsgNotification::getSenderId).distinct().filter(id -> id != null && id != 0).toList(); + List senderUserVoList = userService.selectUserByIds(senderUserIds, null); + Map senderUserMap = senderUserVoList.stream() + .collect(Collectors.toMap(SysUserVo::getUserId, SysUserVo::getNickName)); + List notificationVoList = notificationList.stream().map(notification -> { + MsgNotificationVo notificationVo = new MsgNotificationVo(); + BeanUtils.copyProperties(notification, notificationVo); + // 关联发送用户信息 + Long senderId = notification.getSenderId(); + if (senderId != null && senderId != 0 && senderUserMap.containsKey(senderId)) { + notificationVo.setSenderName(senderUserMap.get(senderId)); + } + return notificationVo; + }).toList(); + notificationVoPage.setRecords(notificationVoList); + return notificationVoPage; + } +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/service/impl/MsgNotifyTargetDetailServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/service/impl/MsgNotifyTargetDetailServiceImpl.java new file mode 100644 index 00000000..3689ba32 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/service/impl/MsgNotifyTargetDetailServiceImpl.java @@ -0,0 +1,166 @@ +package org.dromara.message.service.impl; + +import cn.hutool.core.collection.CollUtil; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import jakarta.annotation.Resource; +import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.message.domain.MsgNotifyTargetDetail; +import org.dromara.message.domain.enums.MsgMessageTargetType; +import org.dromara.message.domain.vo.notifytargetdetail.MsgNotifyTargetDetailVo; +import org.dromara.message.mapper.MsgNotifyTargetDetailMapper; +import org.dromara.message.service.IMsgNotifyTargetDetailService; +import org.dromara.system.domain.bo.SysUserBo; +import org.dromara.system.domain.vo.SysDeptVo; +import org.dromara.system.domain.vo.SysRoleVo; +import org.dromara.system.domain.vo.SysUserVo; +import org.dromara.system.service.ISysDeptService; +import org.dromara.system.service.ISysRoleService; +import org.dromara.system.service.ISysUserService; +import org.springframework.beans.BeanUtils; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Collectors; + +/** + * 通知人员配置详情Service业务层处理 + * + * @author lilemy + * @date 2025-08-05 + */ +@Service +public class MsgNotifyTargetDetailServiceImpl extends ServiceImpl + implements IMsgNotifyTargetDetailService { + + @Resource + private ISysUserService userService; + + @Resource + private ISysRoleService roleService; + + @Resource + private ISysDeptService deptService; + + /** + * 根据通知目标ID查询用户ID列表 + * + * @param targetId 通知目标ID + * @return 用户ID列表 + */ + @Override + public List queryUserIdsByTargetId(Long targetId) { + List details = this.lambdaQuery() + .eq(MsgNotifyTargetDetail::getTargetId, targetId) + .list(); + List userIds = new ArrayList<>(); + details.forEach(detail -> { + String targetType = detail.getTargetType(); + if (targetType.equals(MsgMessageTargetType.USER.getValue())) { + userIds.add(detail.getTargetId()); + } else if (targetType.equals(MsgMessageTargetType.ROLE.getValue())) { + SysUserBo userBo = new SysUserBo(); + userBo.setRoleId(detail.getTargetId()); + TableDataInfo dataInfo = userService.selectAllocatedList(userBo, new PageQuery(PageQuery.DEFAULT_PAGE_NUM, PageQuery.DEFAULT_PAGE_SIZE)); + List rows = dataInfo.getRows(); + List userIdList = rows.stream().map(SysUserVo::getUserId).distinct().filter(Objects::nonNull).toList(); + userIds.addAll(userIdList); + } else if (targetType.equals(MsgMessageTargetType.DEPT.getValue())) { + List userVos = userService.selectUserListByDept(detail.getTargetId()); + List userIdList = userVos.stream().map(SysUserVo::getUserId).distinct().filter(Objects::nonNull).toList(); + userIds.addAll(userIdList); + } + }); + return userIds; + } + + /** + * 根据通知目标ID查询通知目标详情列表 + * + * @param targetId 通知目标ID + * @return 通知目标详情列表 + */ + @Override + public List queryVoListByTargetId(Long targetId) { + List details = this.lambdaQuery() + .eq(MsgNotifyTargetDetail::getTargetId, targetId) + .list(); + return this.getVoList(details); + } + + /** + * 获取通知人员配置详情封装 + * + * @param detail 通知人员配置详情 + * @return 通知人员配置详情封装 + */ + @Override + public MsgNotifyTargetDetailVo getVo(MsgNotifyTargetDetail detail) { + MsgNotifyTargetDetailVo vo = new MsgNotifyTargetDetailVo(); + if (detail == null) { + return vo; + } + BeanUtils.copyProperties(detail, vo); + Long targetId = detail.getTargetId(); + if (detail.getTargetType().equals(MsgMessageTargetType.USER.getValue())) { + vo.setTargetName(userService.selectUserById(targetId).getUserName()); + } else if (detail.getTargetType().equals(MsgMessageTargetType.ROLE.getValue())) { + vo.setTargetName(roleService.selectRoleById(targetId).getRoleName()); + } else if (detail.getTargetType().equals(MsgMessageTargetType.DEPT.getValue())) { + vo.setTargetName(deptService.selectDeptById(targetId).getDeptName()); + } + return vo; + } + + /** + * 批量获取通知人员配置详情封装 + * + * @param detailList 通知人员配置详情列表 + * @return 通知人员配置详情封装列表 + */ + @Override + public List getVoList(List detailList) { + if (CollUtil.isEmpty(detailList)) { + return List.of(); + } + // 获取用户列表 + List userIds = new ArrayList<>(); + List roleIds = new ArrayList<>(); + List deptIds = new ArrayList<>(); + detailList.forEach(detail -> { + String targetType = detail.getTargetType(); + Long targetId = detail.getTargetId(); + if (targetType.equals(MsgMessageTargetType.USER.getValue())) { + userIds.add(targetId); + } else if (targetType.equals(MsgMessageTargetType.ROLE.getValue())) { + roleIds.add(targetId); + } else if (targetType.equals(MsgMessageTargetType.DEPT.getValue())) { + deptIds.add(targetId); + } + }); + List newUserIds = userIds.stream().distinct().filter(Objects::nonNull).toList(); + List newRoleIds = roleIds.stream().distinct().filter(Objects::nonNull).toList(); + List newDeptIds = deptIds.stream().distinct().filter(Objects::nonNull).toList(); + List userVos = userService.selectUserByIds(newUserIds, null); + List roleVos = roleService.selectRoleByIds(newRoleIds); + List deptVos = deptService.selectDeptByIds(newDeptIds); + Map userMap = userVos.stream().collect(Collectors.toMap(SysUserVo::getUserId, SysUserVo::getNickName)); + Map roleMap = roleVos.stream().collect(Collectors.toMap(SysRoleVo::getRoleId, SysRoleVo::getRoleName)); + Map deptMap = deptVos.stream().collect(Collectors.toMap(SysDeptVo::getDeptId, SysDeptVo::getDeptName)); + return detailList.stream().map(detail -> { + MsgNotifyTargetDetailVo vo = new MsgNotifyTargetDetailVo(); + BeanUtils.copyProperties(detail, vo); + if (detail.getTargetType().equals(MsgMessageTargetType.USER.getValue())) { + vo.setTargetName(userMap.get(detail.getTargetId())); + } else if (detail.getTargetType().equals(MsgMessageTargetType.ROLE.getValue())) { + vo.setTargetName(roleMap.get(detail.getTargetId())); + } else if (detail.getTargetType().equals(MsgMessageTargetType.DEPT.getValue())) { + vo.setTargetName(deptMap.get(detail.getTargetId())); + } + return vo; + }).toList(); + } +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/service/impl/MsgNotifyTargetServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/service/impl/MsgNotifyTargetServiceImpl.java new file mode 100644 index 00000000..7e5e0a62 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/service/impl/MsgNotifyTargetServiceImpl.java @@ -0,0 +1,268 @@ +package org.dromara.message.service.impl; + +import cn.hutool.core.collection.CollUtil; +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 jakarta.annotation.Resource; +import org.dromara.common.core.constant.HttpStatus; +import org.dromara.common.core.exception.ServiceException; +import org.dromara.common.core.utils.ObjectUtils; +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.message.domain.MsgNotifyTarget; +import org.dromara.message.domain.MsgNotifyTargetDetail; +import org.dromara.message.domain.dto.notifytarget.MsgNotifyTargetCreateReq; +import org.dromara.message.domain.dto.notifytarget.MsgNotifyTargetQueryReq; +import org.dromara.message.domain.dto.notifytarget.MsgNotifyTargetUpdateReq; +import org.dromara.message.domain.dto.notifytargetdetail.MsgNotifyTargetDetailCreateDto; +import org.dromara.message.domain.dto.notifytargetdetail.MsgNotifyTargetDetailUpdateDto; +import org.dromara.message.domain.vo.notifytarget.MsgNotifyTargetVo; +import org.dromara.message.domain.vo.notifytargetdetail.MsgNotifyTargetDetailVo; +import org.dromara.message.mapper.MsgNotifyTargetMapper; +import org.dromara.message.service.IMsgNotifyTargetDetailService; +import org.dromara.message.service.IMsgNotifyTargetService; +import org.springframework.beans.BeanUtils; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Collection; +import java.util.List; +import java.util.Objects; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * 通知人员配置Service业务层处理 + * + * @author lilemy + * @date 2025-08-05 + */ +@Service +public class MsgNotifyTargetServiceImpl extends ServiceImpl + implements IMsgNotifyTargetService { + + @Resource + private IMsgNotifyTargetDetailService notifyTargetDetailService; + + /** + * 查询通知人员配置 + * + * @param id 主键 + * @return 通知人员配置 + */ + @Override + public MsgNotifyTargetVo queryById(Long id) { + MsgNotifyTarget notifyTarget = this.getById(id); + if (notifyTarget == null) { + throw new ServiceException("通知人员配置信息不存在", HttpStatus.NOT_FOUND); + } + return this.getVo(notifyTarget); + } + + /** + * 分页查询通知人员配置列表 + * + * @param req 查询条件 + * @param pageQuery 分页参数 + * @return 通知人员配置分页列表 + */ + @Override + public TableDataInfo queryPageList(MsgNotifyTargetQueryReq req, PageQuery pageQuery) { + Page result = this.page(pageQuery.build(), this.buildQueryWrapper(req)); + return TableDataInfo.build(this.getVoPage(result)); + } + + /** + * 查询符合条件的通知人员配置列表 + * + * @param req 查询条件 + * @return 通知人员配置列表 + */ + @Override + public List queryList(MsgNotifyTargetQueryReq req) { + return this.list(this.buildQueryWrapper(req)).stream().map(this::getVo).toList(); + } + + /** + * 新增通知人员配置 + * + * @param req 通知人员配置 + * @return 是否新增成功 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean insertByBo(MsgNotifyTargetCreateReq req) { + MsgNotifyTarget target = new MsgNotifyTarget(); + BeanUtils.copyProperties(req, target); + boolean save = this.save(target); + if (!save) { + throw new ServiceException("新增通知人员配置信息异常", HttpStatus.ERROR); + } + List detailList = req.getDetailList(); + List saveDetail = detailList.stream().map(detail -> { + MsgNotifyTargetDetail entity = new MsgNotifyTargetDetail(); + entity.setConfigId(target.getId()); + entity.setTargetId(detail.getTargetId()); + entity.setTargetType(detail.getTargetType()); + return entity; + }).toList(); + boolean b = notifyTargetDetailService.saveBatch(saveDetail); + if (!b) { + throw new ServiceException("新增通知人员配置信息异常", HttpStatus.ERROR); + } + return true; + } + + /** + * 修改通知人员配置 + * + * @param req 通知人员配置 + * @return 是否修改成功 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean updateByBo(MsgNotifyTargetUpdateReq req) { + Long id = req.getId(); + MsgNotifyTarget notifyTarget = this.getById(id); + if (notifyTarget == null) { + throw new ServiceException("修改通知人员配置信息不存在", HttpStatus.ERROR); + } + MsgNotifyTarget target = new MsgNotifyTarget(); + BeanUtils.copyProperties(req, target); + List detailList = req.getDetailList(); + // 判断是否需要新增或删除配置详情 + if (CollUtil.isNotEmpty(detailList)) { + // 1. 从数据库中获取当前配置下的所有旧详情 + List oldDetails = notifyTargetDetailService.lambdaQuery() + .eq(MsgNotifyTargetDetail::getTargetId, id) + .list(); + // 2. 计算需要删除的详情ID + // 提取前端提交的详情中,所有已存在的记录ID (ID不为null) + Set incomingIds = detailList.stream() + .map(MsgNotifyTargetDetailUpdateDto::getId) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + + // 筛选出 oldDetails 中 ID 不在 incomingIds 里的记录,这些就是要删除的 + List idsToDelete = oldDetails.stream() + .map(MsgNotifyTargetDetail::getId) + .filter(detailId -> !incomingIds.contains(detailId)) + .toList(); + + // 3. 执行删除操作 + if (CollUtil.isNotEmpty(idsToDelete)) { + notifyTargetDetailService.removeBatchByIds(idsToDelete); + } + + // 4. 准备新增和修改的数据,并执行批量保存或更新 + if (CollUtil.isNotEmpty(detailList)) { + // 将 DTO 列表转换为实体列表 + List entitiesToSaveOrUpdate = detailList.stream().map(dto -> { + MsgNotifyTargetDetail entity = new MsgNotifyTargetDetail(); + entity.setId(dto.getId()); // ID为null是新增,不为null是更新 + entity.setConfigId(id); // 设置关联的父ID + entity.setTargetType(dto.getTargetType()); + entity.setTargetId(dto.getTargetId()); + return entity; + }).collect(Collectors.toList()); + + // 5. 执行批量新增或更新 + notifyTargetDetailService.saveOrUpdateBatch(entitiesToSaveOrUpdate); + } + } + boolean b = this.updateById(target); + if (!b) { + throw new ServiceException("修改通知人员配置失败", HttpStatus.ERROR); + } + return true; + } + + /** + * 批量删除通知人员配置信息 + * + * @param ids 待删除的主键集合 + * @return 是否删除成功 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean deleteByIds(Collection ids) { + List details = notifyTargetDetailService.lambdaQuery() + .in(MsgNotifyTargetDetail::getTargetId, ids) + .list(); + boolean result = notifyTargetDetailService.removeBatchByIds(details); + if (!result) { + throw new ServiceException("删除通知人员配置详情信息失败"); + } + result = this.removeBatchByIds(ids); + if (!result) { + throw new ServiceException("删除通知人员配置信息失败"); + } + return true; + } + + /** + * 获取通知人员配置视图对象 + * + * @param notifyTarget 通知人员配置对象 + * @return 通知人员配置视图对象 + */ + @Override + public MsgNotifyTargetVo getVo(MsgNotifyTarget notifyTarget) { + MsgNotifyTargetVo vo = new MsgNotifyTargetVo(); + if (notifyTarget == null) { + return vo; + } + BeanUtils.copyProperties(notifyTarget, vo); + Long id = notifyTarget.getId(); + List detailVos = notifyTargetDetailService.queryVoListByTargetId(id); + vo.setDetailList(detailVos); + return vo; + } + + /** + * 获取通知人员配置查询条件封装 + * + * @param req 查询条件 + * @return 查询条件封装 + */ + @Override + public LambdaQueryWrapper buildQueryWrapper(MsgNotifyTargetQueryReq req) { + LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); + if (req == null) { + return lqw; + } + Long projectId = req.getProjectId(); + Long typeId = req.getTypeId(); + String status = req.getStatus(); + lqw.eq(ObjectUtils.isNotEmpty(projectId), MsgNotifyTarget::getProjectId, projectId); + lqw.eq(ObjectUtils.isNotEmpty(typeId), MsgNotifyTarget::getTypeId, typeId); + lqw.eq(StringUtils.isNotBlank(status), MsgNotifyTarget::getStatus, status); + return lqw; + } + + /** + * 获取通知人员配置分页对象视图 + * + * @param notifyTargetPage 通知人员配置分页对象 + * @return 通知人员配置分页详情对象视图 + */ + @Override + public Page getVoPage(Page notifyTargetPage) { + List notifyTargetList = notifyTargetPage.getRecords(); + Page voPage = new Page<>( + notifyTargetPage.getCurrent(), + notifyTargetPage.getSize(), + notifyTargetPage.getTotal() + ); + List targetVoList = notifyTargetList.stream().map(notifyTarget -> { + MsgNotifyTargetVo vo = new MsgNotifyTargetVo(); + BeanUtils.copyProperties(notifyTarget, vo); + vo.setDetailList(notifyTargetDetailService.queryVoListByTargetId(notifyTarget.getId())); + return vo; + }).toList(); + voPage.setRecords(targetVoList); + return voPage; + } +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/service/impl/MsgTypeConfigServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/service/impl/MsgTypeConfigServiceImpl.java new file mode 100644 index 00000000..0f3665f2 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/message/service/impl/MsgTypeConfigServiceImpl.java @@ -0,0 +1,180 @@ +package org.dromara.message.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.dromara.common.core.constant.HttpStatus; +import org.dromara.common.core.exception.ServiceException; +import org.dromara.common.core.utils.ObjectUtils; +import org.dromara.common.core.utils.StringUtils; +import org.dromara.message.domain.MsgTypeConfig; +import org.dromara.message.domain.dto.typeconfig.MsgTypeConfigCreateReq; +import org.dromara.message.domain.dto.typeconfig.MsgTypeConfigQueryReq; +import org.dromara.message.domain.dto.typeconfig.MsgTypeConfigUpdateReq; +import org.dromara.message.domain.vo.typeconfig.MsgTypeConfigVo; +import org.dromara.message.mapper.MsgTypeConfigMapper; +import org.dromara.message.service.IMsgTypeConfigService; +import org.springframework.beans.BeanUtils; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Collection; +import java.util.List; + +/** + * 消息类型配置Service业务层处理 + * + * @author lilemy + * @date 2025-08-05 + */ +@Service +public class MsgTypeConfigServiceImpl extends ServiceImpl + implements IMsgTypeConfigService { + + /** + * 查询消息类型配置 + * + * @param id 主键 + * @return 消息类型配置 + */ + @Override + public MsgTypeConfigVo queryById(Long id) { + MsgTypeConfig typeConfig = this.getById(id); + if (typeConfig == null) { + throw new ServiceException("消息类型配置信息不存在", HttpStatus.NOT_FOUND); + } + return this.getVo(typeConfig); + } + + /** + * 查询符合条件的消息类型配置列表 + * + * @param req 查询条件 + * @return 消息类型配置列表 + */ + @Override + public List queryList(MsgTypeConfigQueryReq req) { + List result = this.list(this.buildQueryWrapper(req)); + return this.getVoList(result); + } + + /** + * 新增消息类型配置 + * + * @param req 消息类型配置 + * @return 新增成功消息类型配置id + */ + @Override + public Long insertByBo(MsgTypeConfigCreateReq req) { + MsgTypeConfig typeConfig = new MsgTypeConfig(); + BeanUtils.copyProperties(req, typeConfig); + // 校验编号是否重复 + boolean b = this.lambdaQuery() + .eq(MsgTypeConfig::getTypeCode, typeConfig.getTypeCode()) + .in(MsgTypeConfig::getProjectId, typeConfig.getProjectId(), 0L) + .count() > 0; + if (b) { + throw new ServiceException("当前消息编号已存在", HttpStatus.CONFLICT); + } + boolean save = this.save(typeConfig); + if (!save) { + throw new ServiceException("新增消息类型配置信息异常", HttpStatus.ERROR); + } + return typeConfig.getId(); + } + + /** + * 修改消息类型配置 + * + * @param req 消息类型配置 + * @return 是否修改成功 + */ + @Override + public Boolean updateByBo(MsgTypeConfigUpdateReq req) { + Long id = req.getId(); + MsgTypeConfig oldTypeConfig = this.getById(id); + if (oldTypeConfig == null) { + throw new ServiceException("消息类型配置信息不存在", HttpStatus.NOT_FOUND); + } + MsgTypeConfig typeConfig = new MsgTypeConfig(); + BeanUtils.copyProperties(req, typeConfig); + // 校验编号是否重复 + if (!typeConfig.getTypeCode().equals(oldTypeConfig.getTypeCode())){ + boolean b = this.lambdaQuery() + .eq(MsgTypeConfig::getTypeCode, typeConfig.getTypeCode()) + .in(MsgTypeConfig::getProjectId, typeConfig.getProjectId(), 0L) + .count() > 0; + if (b) { + throw new ServiceException("当前消息编号已存在", HttpStatus.CONFLICT); + } + } + boolean result = this.updateById(typeConfig); + if (!result) { + throw new ServiceException("修改消息类型配置信息异常", HttpStatus.ERROR); + } + return true; + } + + /** + * 批量删除消息类型配置信息 + * + * @param ids 待删除的主键集合 + * @return 是否删除成功 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean deleteByIds(Collection ids) { + return this.removeBatchByIds(ids); + } + + /** + * 获取消息类型配置视图对象 + * + * @param typeConfig 消息类型配置对象 + * @return 消息类型配置视图对象 + */ + @Override + public MsgTypeConfigVo getVo(MsgTypeConfig typeConfig) { + MsgTypeConfigVo vo = new MsgTypeConfigVo(); + if (typeConfig == null) { + return vo; + } + BeanUtils.copyProperties(typeConfig, vo); + return vo; + } + + /** + * 获取消息类型配置查询条件封装 + * + * @param req 查询条件 + * @return 查询条件封装 + */ + @Override + public LambdaQueryWrapper buildQueryWrapper(MsgTypeConfigQueryReq req) { + LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); + if (req == null) { + return lqw; + } + Long projectId = req.getProjectId(); + Long parentId = req.getParentId(); + String typeCode = req.getTypeCode(); + String typeName = req.getTypeName(); + String status = req.getStatus(); + lqw.eq(ObjectUtils.isNotEmpty(projectId), MsgTypeConfig::getProjectId, projectId); + lqw.eq(ObjectUtils.isNotEmpty(parentId), MsgTypeConfig::getParentId, parentId); + lqw.eq(StringUtils.isNotBlank(typeCode), MsgTypeConfig::getTypeCode, typeCode); + lqw.like(StringUtils.isNotBlank(typeName), MsgTypeConfig::getTypeName, typeName); + lqw.eq(StringUtils.isNotBlank(status), MsgTypeConfig::getStatus, status); + return lqw; + } + + /** + * 获取消息类型配置分页对象视图 + * + * @param typeConfigList 消息类型配置分页对象 + * @return 消息类型配置分页对象视图 + */ + @Override + public List getVoList(List typeConfigList) { + return typeConfigList.stream().map(this::getVo).toList(); + } +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/message/MsgNotificationMapper.xml b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/message/MsgNotificationMapper.xml new file mode 100644 index 00000000..2352fc25 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/message/MsgNotificationMapper.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/message/MsgNotifyTargetDetailMapper.xml b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/message/MsgNotifyTargetDetailMapper.xml new file mode 100644 index 00000000..f9fe17b6 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/message/MsgNotifyTargetDetailMapper.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/message/MsgNotifyTargetMapper.xml b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/message/MsgNotifyTargetMapper.xml new file mode 100644 index 00000000..d81143cf --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/message/MsgNotifyTargetMapper.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/message/MsgTypeConfigMapper.xml b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/message/MsgTypeConfigMapper.xml new file mode 100644 index 00000000..2693ee91 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/message/MsgTypeConfigMapper.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/xinnengyuan/script/sql/menuInitValue.sql b/xinnengyuan/script/sql/menuInitValue.sql index 497751de..e8797e26 100644 --- a/xinnengyuan/script/sql/menuInitValue.sql +++ b/xinnengyuan/script/sql/menuInitValue.sql @@ -1914,3 +1914,83 @@ values(1951230902137835526, '物资-材料设备删除', 1951230902137835522, '4 insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) values(1951230902137835527, '物资-材料设备导出', 1951230902137835522, '5', '#', '', 1, 0, 'F', '0', '0', 'cailiaoshebei:cailiaoshebei:export', '#', 103, 1, sysdate(), null, null, ''); + +-- 菜单 SQL +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1952577325643083777, '消息通知', '1952576561528975362', '1', 'notification', 'message/notification/index', 1, 0, 'C', '0', '0', 'message:notification:list', '#', 103, 1, sysdate(), null, null, '消息通知菜单'); + +-- 按钮 SQL +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1952577325643083778, '消息通知查询', 1952577325643083777, '1', '#', '', 1, 0, 'F', '0', '0', 'message:notification:query', '#', 103, 1, sysdate(), null, null, ''); + +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1952577325643083779, '消息通知新增', 1952577325643083777, '2', '#', '', 1, 0, 'F', '0', '0', 'message:notification:add', '#', 103, 1, sysdate(), null, null, ''); + +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1952577325643083780, '消息通知修改', 1952577325643083777, '3', '#', '', 1, 0, 'F', '0', '0', 'message:notification:edit', '#', 103, 1, sysdate(), null, null, ''); + +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1952577325643083781, '消息通知删除', 1952577325643083777, '4', '#', '', 1, 0, 'F', '0', '0', 'message:notification:remove', '#', 103, 1, sysdate(), null, null, ''); + +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1952577325643083782, '消息通知导出', 1952577325643083777, '5', '#', '', 1, 0, 'F', '0', '0', 'message:notification:export', '#', 103, 1, sysdate(), null, null, ''); + +-- 菜单 SQL +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1952577327337582594, '通知人员配置', '1952576561528975362', '1', 'notifyTarget', 'message/notifyTarget/index', 1, 0, 'C', '0', '0', 'message:notifyTarget:list', '#', 103, 1, sysdate(), null, null, '通知人员配置菜单'); + +-- 按钮 SQL +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1952577327337582595, '通知人员配置查询', 1952577327337582594, '1', '#', '', 1, 0, 'F', '0', '0', 'message:notifyTarget:query', '#', 103, 1, sysdate(), null, null, ''); + +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1952577327337582596, '通知人员配置新增', 1952577327337582594, '2', '#', '', 1, 0, 'F', '0', '0', 'message:notifyTarget:add', '#', 103, 1, sysdate(), null, null, ''); + +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1952577327337582597, '通知人员配置修改', 1952577327337582594, '3', '#', '', 1, 0, 'F', '0', '0', 'message:notifyTarget:edit', '#', 103, 1, sysdate(), null, null, ''); + +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1952577327337582598, '通知人员配置删除', 1952577327337582594, '4', '#', '', 1, 0, 'F', '0', '0', 'message:notifyTarget:remove', '#', 103, 1, sysdate(), null, null, ''); + +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1952577327337582599, '通知人员配置导出', 1952577327337582594, '5', '#', '', 1, 0, 'F', '0', '0', 'message:notifyTarget:export', '#', 103, 1, sysdate(), null, null, ''); + +-- 菜单 SQL +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1952577327597629441, '消息类型配置', '1952576561528975362', '1', 'typeConfig', 'message/typeConfig/index', 1, 0, 'C', '0', '0', 'message:typeConfig:list', '#', 103, 1, sysdate(), null, null, '消息类型配置菜单'); + +-- 按钮 SQL +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1952577327597629442, '消息类型配置查询', 1952577327597629441, '1', '#', '', 1, 0, 'F', '0', '0', 'message:typeConfig:query', '#', 103, 1, sysdate(), null, null, ''); + +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1952577327597629443, '消息类型配置新增', 1952577327597629441, '2', '#', '', 1, 0, 'F', '0', '0', 'message:typeConfig:add', '#', 103, 1, sysdate(), null, null, ''); + +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1952577327597629444, '消息类型配置修改', 1952577327597629441, '3', '#', '', 1, 0, 'F', '0', '0', 'message:typeConfig:edit', '#', 103, 1, sysdate(), null, null, ''); + +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1952577327597629445, '消息类型配置删除', 1952577327597629441, '4', '#', '', 1, 0, 'F', '0', '0', 'message:typeConfig:remove', '#', 103, 1, sysdate(), null, null, ''); + +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1952577327597629446, '消息类型配置导出', 1952577327597629441, '5', '#', '', 1, 0, 'F', '0', '0', 'message:typeConfig:export', '#', 103, 1, sysdate(), null, null, ''); + +-- 菜单 SQL +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1952650149079576578, '通知人员配置详情', '1952577327337582594', '1', 'notifyTargetDetail', 'message/notifyTargetDetail/index', 1, 0, 'C', '0', '0', 'message:notifyTargetDetail:list', '#', 103, 1, sysdate(), null, null, '通知人员配置详情菜单'); + +-- 按钮 SQL +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1952650149079576579, '通知人员配置详情查询', 1952650149079576578, '1', '#', '', 1, 0, 'F', '0', '0', 'message:notifyTargetDetail:query', '#', 103, 1, sysdate(), null, null, ''); + +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1952650149079576580, '通知人员配置详情新增', 1952650149079576578, '2', '#', '', 1, 0, 'F', '0', '0', 'message:notifyTargetDetail:add', '#', 103, 1, sysdate(), null, null, ''); + +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1952650149079576581, '通知人员配置详情修改', 1952650149079576578, '3', '#', '', 1, 0, 'F', '0', '0', 'message:notifyTargetDetail:edit', '#', 103, 1, sysdate(), null, null, ''); + +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1952650149079576582, '通知人员配置详情删除', 1952650149079576578, '4', '#', '', 1, 0, 'F', '0', '0', 'message:notifyTargetDetail:remove', '#', 103, 1, sysdate(), null, null, ''); + +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1952650149079576583, '通知人员配置详情导出', 1952650149079576578, '5', '#', '', 1, 0, 'F', '0', '0', 'message:notifyTargetDetail:export', '#', 103, 1, sysdate(), null, null, ''); diff --git a/xinnengyuan/script/sql/xinnengyuan.sql b/xinnengyuan/script/sql/xinnengyuan.sql index 7babcec4..c78f3876 100644 --- a/xinnengyuan/script/sql/xinnengyuan.sql +++ b/xinnengyuan/script/sql/xinnengyuan.sql @@ -1718,3 +1718,76 @@ create table pgs_construction_schedule_plan primary key (`id`) using btree, index `idx_project_id` (`project_id` asc) using btree comment '项目ID' ) comment '施工进度计划' collate = utf8mb4_unicode_ci; + +drop table if exists msg_type_config; +create table msg_type_config +( + `id` bigint not null auto_increment comment '主键ID', + `project_id` bigint default 0 not null comment '项目ID', + `parent_id` bigint default 0 not null comment '父ID', + `type_code` varchar(64) not null comment '消息类型编码', + `type_name` varchar(128) not null comment '消息类型名称', + `type_desc` varchar(512) null comment '消息类型描述', + `status` char(1) default '0' null comment '是否启用(0正常 1禁用)', + `remark` varchar(255) null comment '备注', + `create_by` bigint null comment '创建者', + `update_by` bigint null comment '更新者', + `create_dept` bigint null comment '创建部门', + `create_time` datetime default CURRENT_TIMESTAMP null comment '创建时间', + `update_time` datetime default CURRENT_TIMESTAMP null on update CURRENT_TIMESTAMP comment '更新时间', + primary key (`id`) using btree, + index `idx_project_id` (`project_id` asc) using btree comment '项目ID' +) comment '消息类型配置' collate = utf8mb4_unicode_ci; + +drop table if exists msg_notify_target; +create table msg_notify_target +( + `id` bigint not null auto_increment comment '主键ID', + `project_id` bigint default 0 not null comment '项目ID', + `type_id` bigint not null comment '消息类型ID', + `status` char(1) default '0' null comment '是否启用(0正常 1禁用)', + `remark` varchar(255) null comment '备注', + `create_by` bigint null comment '创建者', + `update_by` bigint null comment '更新者', + `create_dept` bigint null comment '创建部门', + `create_time` datetime default CURRENT_TIMESTAMP null comment '创建时间', + `update_time` datetime default CURRENT_TIMESTAMP null on update CURRENT_TIMESTAMP comment '更新时间', + primary key (`id`) using btree, + index `idx_project_id` (`project_id` asc) using btree comment '项目ID', + index `idx_type_id` (`type_id` asc) using btree comment '消息类型ID' +) comment '通知人员配置' collate = utf8mb4_unicode_ci; + +drop table if exists msg_notification; +create table msg_notification +( + `id` bigint not null auto_increment comment '主键ID', + `project_id` bigint default 0 not null comment '项目ID', + `recipient_id` bigint not null comment '接收通知的用户ID', + `sender_id` bigint default 0 not null comment '发送通知的用户ID(系统通知 0)', + `type_id` bigint not null comment '通知类型ID', + `title` varchar(255) default '' not null comment '通知标题', + `content` text not null comment '通知的主要内容', + `view_status` char(1) default '0' not null comment '查看状态(0未读 1已读)', + `view_time` datetime null comment '查看时间', + `action_url` varchar(1024) default '' not null comment '点击通知后跳转的目标URL', + `file` varchar(1024) null comment '通知附件', + `remark` varchar(255) null comment '备注', + `create_time` datetime default CURRENT_TIMESTAMP null comment '创建时间', + `update_time` datetime default CURRENT_TIMESTAMP null on update CURRENT_TIMESTAMP comment '更新时间', + primary key (`id`) using btree, + index `idx_project_id` (`project_id` asc) using btree comment '项目ID', + index `idx_type_id` (`type_id` asc) using btree comment '消息类型ID', + index `idx_sender_id` (`sender_id` asc) using btree comment '发送通知的用户ID', + index `idx_recipient_view` (`recipient_id` asc, `view_status` asc) comment '接收通知的用户ID,查看状态' +) comment '消息通知' collate = utf8mb4_unicode_ci; + +drop table if exists msg_notify_target_detail; +create table msg_notify_target_detail +( + `id` bigint not null auto_increment comment '主键ID', + `config_id` bigint not null comment '消息类型配置ID', + `target_type` char(1) not null comment '接收类型', + `target_id` bigint not null comment '接收ID', + primary key (`id`) using btree, + unique index `un_idx_config_target` (`config_id`, `target_type`, `target_id`) +) comment '通知人员配置详情' collate = utf8mb4_unicode_ci;