mirror of
https://gitee.com/dromara/RuoYi-Vue-Plus.git
synced 2026-03-28 08:13:23 +08:00
update 完成消息盒子功能前后端联动(已读未读在前端浏览器存储)
This commit is contained in:
@@ -12,12 +12,13 @@ import me.zhyd.oauth.request.AuthRequest;
|
||||
import me.zhyd.oauth.utils.AuthStateUtils;
|
||||
import org.dromara.common.core.constant.SystemConstants;
|
||||
import org.dromara.common.core.domain.R;
|
||||
import org.dromara.common.core.domain.dto.PushPayload;
|
||||
import org.dromara.common.core.domain.dto.PushPayloadDTO;
|
||||
import org.dromara.common.core.domain.model.LoginBody;
|
||||
import org.dromara.common.core.domain.model.RegisterBody;
|
||||
import org.dromara.common.core.domain.model.SocialLoginBody;
|
||||
import org.dromara.common.core.enums.PushSourceEnum;
|
||||
import org.dromara.common.core.enums.PushTypeEnum;
|
||||
import org.dromara.common.core.service.MessageService;
|
||||
import org.dromara.common.core.utils.DateUtils;
|
||||
import org.dromara.common.core.utils.MessageUtils;
|
||||
import org.dromara.common.core.utils.StringUtils;
|
||||
@@ -26,7 +27,6 @@ import org.dromara.common.encrypt.annotation.ApiEncrypt;
|
||||
import org.dromara.common.json.utils.JsonUtils;
|
||||
import org.dromara.common.redis.annotation.RateLimiter;
|
||||
import org.dromara.common.redis.enums.LimitType;
|
||||
import org.dromara.common.push.helper.PushHelper;
|
||||
import org.dromara.common.satoken.utils.LoginHelper;
|
||||
import org.dromara.common.social.config.properties.SocialLoginConfigProperties;
|
||||
import org.dromara.common.social.config.properties.SocialProperties;
|
||||
@@ -66,6 +66,7 @@ public class AuthController {
|
||||
private final ISysSocialService socialUserService;
|
||||
private final ISysClientService clientService;
|
||||
private final ScheduledExecutorService scheduledExecutorService;
|
||||
private final MessageService messageService;
|
||||
|
||||
|
||||
/**
|
||||
@@ -95,9 +96,9 @@ public class AuthController {
|
||||
|
||||
Long userId = LoginHelper.getUserId();
|
||||
scheduledExecutorService.schedule(() -> {
|
||||
PushHelper.publishMessage(
|
||||
messageService.publishMessage(
|
||||
List.of(userId),
|
||||
PushPayload.of(
|
||||
PushPayloadDTO.of(
|
||||
PushTypeEnum.MESSAGE,
|
||||
PushSourceEnum.BACKEND,
|
||||
DateUtils.getTodayHour(new Date()) + "好,欢迎登录 RuoYi-Vue-Plus 后台管理系统",
|
||||
|
||||
@@ -14,11 +14,16 @@ import java.io.Serializable;
|
||||
* @author Lion Li
|
||||
*/
|
||||
@Data
|
||||
public class PushPayload implements Serializable {
|
||||
public class PushPayloadDTO implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 消息记录ID
|
||||
*/
|
||||
private Long messageId;
|
||||
|
||||
/**
|
||||
* 消息类型
|
||||
*/
|
||||
@@ -49,8 +54,8 @@ public class PushPayload implements Serializable {
|
||||
*/
|
||||
private Long timestamp;
|
||||
|
||||
public static PushPayload of(String type, String source, String message, Object data) {
|
||||
PushPayload payload = new PushPayload();
|
||||
public static PushPayloadDTO of(String type, String source, String message, Object data) {
|
||||
PushPayloadDTO payload = new PushPayloadDTO();
|
||||
payload.setType(StringUtils.defaultIfBlank(type, PushTypeEnum.MESSAGE.getType()));
|
||||
payload.setSource(StringUtils.defaultIfBlank(source, PushSourceEnum.BACKEND.getSource()));
|
||||
payload.setMessage(message);
|
||||
@@ -59,7 +64,7 @@ public class PushPayload implements Serializable {
|
||||
return payload;
|
||||
}
|
||||
|
||||
public static PushPayload of(PushTypeEnum type, PushSourceEnum source, String message, Object data) {
|
||||
public static PushPayloadDTO of(PushTypeEnum type, PushSourceEnum source, String message, Object data) {
|
||||
return of(
|
||||
type == null ? null : type.getType(),
|
||||
source == null ? null : source.getSource(),
|
||||
@@ -68,8 +73,8 @@ public class PushPayload implements Serializable {
|
||||
);
|
||||
}
|
||||
|
||||
public static PushPayload of(PushTypeEnum type, PushSourceEnum source, String message, Object data, String path) {
|
||||
PushPayload payload = of(type, source, message, data);
|
||||
public static PushPayloadDTO of(PushTypeEnum type, PushSourceEnum source, String message, Object data, String path) {
|
||||
PushPayloadDTO payload = of(type, source, message, data);
|
||||
payload.setPath(path);
|
||||
return payload;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package org.dromara.common.core.service;
|
||||
|
||||
import org.dromara.common.core.domain.dto.PushPayloadDTO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 通用 消息服务
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
public interface MessageService {
|
||||
|
||||
void sendMessage(Long userId, String message);
|
||||
|
||||
void sendMessage(String message);
|
||||
|
||||
void sendMessage(Long userId, PushPayloadDTO payload);
|
||||
|
||||
void sendMessage(PushPayloadDTO payload);
|
||||
|
||||
void publishMessage(List<Long> userIds, PushPayloadDTO payload);
|
||||
|
||||
void publishAll(String message);
|
||||
|
||||
void publishAll(PushPayloadDTO payload);
|
||||
}
|
||||
@@ -63,7 +63,7 @@ public class SseController implements DisposableBean {
|
||||
// public R<Void> send(Long userId, String msg) {
|
||||
// PushDTO dto = new PushDTO();
|
||||
// dto.setUserIds(List.of(userId));
|
||||
// dto.setPayload(PushPayload.of("message", "backend", msg, null));
|
||||
// dto.setPayload(PushPayloadDTO.of("message", "backend", msg, null));
|
||||
// sessionManager.publishMessage(dto);
|
||||
// return R.ok();
|
||||
// }
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package org.dromara.common.push.core;
|
||||
|
||||
import org.dromara.common.core.domain.dto.PushPayload;
|
||||
import org.dromara.common.core.domain.dto.PushPayloadDTO;
|
||||
import org.dromara.common.push.dto.PushDTO;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
@@ -14,11 +14,11 @@ public interface PushSessionManager {
|
||||
|
||||
void subscribeMessage(Consumer<PushDTO> consumer);
|
||||
|
||||
void sendMessage(Long userId, PushPayload payload);
|
||||
void sendMessage(Long userId, PushPayloadDTO payload);
|
||||
|
||||
void sendMessage(PushPayload payload);
|
||||
void sendMessage(PushPayloadDTO payload);
|
||||
|
||||
void publishMessage(PushDTO pushDTO);
|
||||
|
||||
void publishAll(PushPayload payload);
|
||||
void publishAll(PushPayloadDTO payload);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ package org.dromara.common.push.core;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.common.core.domain.dto.PushPayload;
|
||||
import org.dromara.common.core.domain.dto.PushPayloadDTO;
|
||||
import org.dromara.common.push.constant.MessageConstants;
|
||||
import org.dromara.common.push.dto.PushDTO;
|
||||
import org.dromara.common.core.utils.SpringUtils;
|
||||
@@ -194,7 +194,7 @@ public class SseEmitterSessionManager implements PushSessionManager {
|
||||
* @param payload 要发送的消息体
|
||||
*/
|
||||
@Override
|
||||
public void sendMessage(Long userId, PushPayload payload) {
|
||||
public void sendMessage(Long userId, PushPayloadDTO payload) {
|
||||
sendMessage(userId, JsonUtils.toJsonString(payload));
|
||||
}
|
||||
|
||||
@@ -228,7 +228,7 @@ public class SseEmitterSessionManager implements PushSessionManager {
|
||||
* @param payload 要发送的消息体
|
||||
*/
|
||||
@Override
|
||||
public void sendMessage(PushPayload payload) {
|
||||
public void sendMessage(PushPayloadDTO payload) {
|
||||
sendMessage(JsonUtils.toJsonString(payload));
|
||||
}
|
||||
|
||||
@@ -253,7 +253,7 @@ public class SseEmitterSessionManager implements PushSessionManager {
|
||||
* @param message 要发布的消息内容
|
||||
*/
|
||||
public void publishAll(String message) {
|
||||
publishAll(PushPayload.of("message", "backend", message, null));
|
||||
publishAll(PushPayloadDTO.of("message", "backend", message, null));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -262,7 +262,7 @@ public class SseEmitterSessionManager implements PushSessionManager {
|
||||
* @param payload 要发布的消息体
|
||||
*/
|
||||
@Override
|
||||
public void publishAll(PushPayload payload) {
|
||||
public void publishAll(PushPayloadDTO payload) {
|
||||
PushDTO dto = new PushDTO();
|
||||
dto.setPayload(payload);
|
||||
RedisUtils.publish(MessageConstants.MESSAGE_TOPIC, dto, consumer -> {
|
||||
|
||||
@@ -3,7 +3,7 @@ package org.dromara.common.push.core;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.common.core.domain.dto.PushPayload;
|
||||
import org.dromara.common.core.domain.dto.PushPayloadDTO;
|
||||
import org.dromara.common.core.utils.SpringUtils;
|
||||
import org.dromara.common.json.utils.JsonUtils;
|
||||
import org.dromara.common.push.dto.PushDTO;
|
||||
@@ -90,7 +90,7 @@ public class WebSocketSessionManager implements PushSessionManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessage(Long userId, PushPayload payload) {
|
||||
public void sendMessage(Long userId, PushPayloadDTO payload) {
|
||||
if (payload == null) {
|
||||
return;
|
||||
}
|
||||
@@ -113,7 +113,7 @@ public class WebSocketSessionManager implements PushSessionManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessage(PushPayload payload) {
|
||||
public void sendMessage(PushPayloadDTO payload) {
|
||||
USER_TOKEN_SESSIONS.keySet().forEach(userId -> sendMessage(userId, payload));
|
||||
}
|
||||
|
||||
@@ -128,7 +128,7 @@ public class WebSocketSessionManager implements PushSessionManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void publishAll(PushPayload payload) {
|
||||
public void publishAll(PushPayloadDTO payload) {
|
||||
PushDTO dto = new PushDTO();
|
||||
dto.setPayload(payload);
|
||||
publishMessage(dto);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package org.dromara.common.push.dto;
|
||||
|
||||
import lombok.Data;
|
||||
import org.dromara.common.core.domain.dto.PushPayload;
|
||||
import org.dromara.common.core.domain.dto.PushPayloadDTO;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
@@ -26,5 +26,5 @@ public class PushDTO implements Serializable {
|
||||
/**
|
||||
* 推送消息体。
|
||||
*/
|
||||
private PushPayload payload;
|
||||
private PushPayloadDTO payload;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ package org.dromara.common.push.handler;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.common.core.domain.dto.PushPayload;
|
||||
import org.dromara.common.core.domain.dto.PushPayloadDTO;
|
||||
import org.dromara.common.core.domain.model.LoginUser;
|
||||
import org.dromara.common.core.enums.PushSourceEnum;
|
||||
import org.dromara.common.core.enums.PushTypeEnum;
|
||||
@@ -61,7 +61,7 @@ public class PlusWebSocketHandler extends AbstractWebSocketHandler {
|
||||
}
|
||||
PushDTO dto = new PushDTO();
|
||||
dto.setUserIds(List.of(loginUser.getUserId()));
|
||||
dto.setPayload(PushPayload.of(
|
||||
dto.setPayload(PushPayloadDTO.of(
|
||||
PushTypeEnum.CUSTOM,
|
||||
PushSourceEnum.CLIENT,
|
||||
message.getPayload(),
|
||||
|
||||
@@ -2,7 +2,7 @@ package org.dromara.common.push.helper;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.dromara.common.core.domain.dto.PushPayload;
|
||||
import org.dromara.common.core.domain.dto.PushPayloadDTO;
|
||||
import org.dromara.common.core.enums.PushSourceEnum;
|
||||
import org.dromara.common.core.enums.PushTypeEnum;
|
||||
import org.dromara.common.core.utils.SpringUtils;
|
||||
@@ -27,21 +27,21 @@ public class PushHelper {
|
||||
sendMessage(buildMessage(message));
|
||||
}
|
||||
|
||||
public static void sendMessage(Long userId, PushPayload payload) {
|
||||
public static void sendMessage(Long userId, PushPayloadDTO payload) {
|
||||
if (!isEnabled()) {
|
||||
return;
|
||||
}
|
||||
getSessionManager().sendMessage(userId, payload);
|
||||
}
|
||||
|
||||
public static void sendMessage(PushPayload payload) {
|
||||
public static void sendMessage(PushPayloadDTO payload) {
|
||||
if (!isEnabled()) {
|
||||
return;
|
||||
}
|
||||
getSessionManager().sendMessage(payload);
|
||||
}
|
||||
|
||||
public static void publishMessage(List<Long> userIds, PushPayload payload) {
|
||||
public static void publishMessage(List<Long> userIds, PushPayloadDTO payload) {
|
||||
PushDTO dto = new PushDTO();
|
||||
dto.setUserIds(userIds);
|
||||
dto.setPayload(payload);
|
||||
@@ -59,7 +59,7 @@ public class PushHelper {
|
||||
publishAll(buildMessage(message));
|
||||
}
|
||||
|
||||
public static void publishAll(PushPayload payload) {
|
||||
public static void publishAll(PushPayloadDTO payload) {
|
||||
if (!isEnabled()) {
|
||||
return;
|
||||
}
|
||||
@@ -74,7 +74,7 @@ public class PushHelper {
|
||||
return SpringUtils.getBean(PushSessionManager.class);
|
||||
}
|
||||
|
||||
private static PushPayload buildMessage(String message) {
|
||||
return PushPayload.of(PushTypeEnum.MESSAGE, PushSourceEnum.BACKEND, message, null);
|
||||
private static PushPayloadDTO buildMessage(String message) {
|
||||
return PushPayloadDTO.of(PushTypeEnum.MESSAGE, PushSourceEnum.BACKEND, message, null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package org.dromara.demo.controller;
|
||||
|
||||
import org.dromara.common.core.domain.R;
|
||||
import org.dromara.common.core.domain.dto.PushPayload;
|
||||
import org.dromara.common.core.domain.dto.PushPayloadDTO;
|
||||
import org.dromara.common.core.enums.PushSourceEnum;
|
||||
import org.dromara.common.core.enums.PushTypeEnum;
|
||||
import org.dromara.common.push.helper.PushHelper;
|
||||
import org.dromara.common.core.service.MessageService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
@@ -24,6 +24,8 @@ import java.util.List;
|
||||
@Slf4j
|
||||
public class WebSocketController {
|
||||
|
||||
private final MessageService messageService;
|
||||
|
||||
/**
|
||||
* 发布消息
|
||||
*
|
||||
@@ -32,16 +34,16 @@ public class WebSocketController {
|
||||
*/
|
||||
@GetMapping("/send")
|
||||
public R<Void> send(Long userId, String message) {
|
||||
PushPayload payload = PushPayload.of(
|
||||
PushPayloadDTO payload = PushPayloadDTO.of(
|
||||
PushTypeEnum.MESSAGE,
|
||||
PushSourceEnum.BACKEND,
|
||||
message,
|
||||
null
|
||||
);
|
||||
if (userId == null) {
|
||||
PushHelper.publishAll(payload);
|
||||
messageService.publishAll(payload);
|
||||
} else {
|
||||
PushHelper.publishMessage(List.of(userId), payload);
|
||||
messageService.publishMessage(List.of(userId), payload);
|
||||
}
|
||||
return R.ok("操作成功");
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
package org.dromara.system.controller.system;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.dromara.common.core.domain.R;
|
||||
import org.dromara.common.satoken.utils.LoginHelper;
|
||||
import org.dromara.common.web.core.BaseController;
|
||||
import org.dromara.system.domain.vo.SysMessageBoxVo;
|
||||
import org.dromara.system.service.ISysMessageService;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* 消息记录控制器
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/system/message")
|
||||
public class SysMessageController extends BaseController {
|
||||
|
||||
private final ISysMessageService messageService;
|
||||
|
||||
/**
|
||||
* 查询当前用户消息盒子数据
|
||||
*
|
||||
* @return 消息盒子数据
|
||||
*/
|
||||
@GetMapping("/box")
|
||||
public R<SysMessageBoxVo> getBox() {
|
||||
return R.ok(messageService.queryMessageBox(LoginHelper.getUserId()));
|
||||
}
|
||||
}
|
||||
@@ -4,14 +4,14 @@ import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.dromara.common.core.domain.PageResult;
|
||||
import org.dromara.common.core.domain.R;
|
||||
import org.dromara.common.core.domain.dto.PushPayload;
|
||||
import org.dromara.common.core.domain.dto.PushPayloadDTO;
|
||||
import org.dromara.common.core.enums.PushSourceEnum;
|
||||
import org.dromara.common.core.enums.PushTypeEnum;
|
||||
import org.dromara.common.core.service.DictService;
|
||||
import org.dromara.common.core.service.MessageService;
|
||||
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.push.helper.PushHelper;
|
||||
import org.dromara.common.redis.annotation.RepeatSubmit;
|
||||
import org.dromara.common.web.core.BaseController;
|
||||
import org.dromara.system.domain.bo.SysNoticeBo;
|
||||
@@ -36,6 +36,7 @@ public class SysNoticeController extends BaseController {
|
||||
|
||||
private final ISysNoticeService noticeService;
|
||||
private final DictService dictService;
|
||||
private final MessageService messageService;
|
||||
|
||||
/**
|
||||
* 分页查询通知公告列表。
|
||||
@@ -83,7 +84,9 @@ public class SysNoticeController extends BaseController {
|
||||
data.put("noticeTypeLabel", type);
|
||||
data.put("noticeTitle", notice.getNoticeTitle());
|
||||
data.put("noticeId", notice.getNoticeId());
|
||||
PushHelper.publishAll(PushPayload.of(
|
||||
data.put("noticeContent", notice.getNoticeContent());
|
||||
data.put("status", notice.getStatus());
|
||||
messageService.publishAll(PushPayloadDTO.of(
|
||||
PushTypeEnum.NOTICE,
|
||||
PushSourceEnum.NOTICE,
|
||||
"[" + type + "] " + notice.getNoticeTitle(),
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
package org.dromara.system.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||
|
||||
/**
|
||||
* 消息记录表 sys_message
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("sys_message")
|
||||
public class SysMessage extends BaseEntity {
|
||||
|
||||
/**
|
||||
* 消息ID
|
||||
*/
|
||||
@TableId(value = "message_id")
|
||||
private Long messageId;
|
||||
|
||||
/**
|
||||
* 消息分组
|
||||
*/
|
||||
private String category;
|
||||
|
||||
/**
|
||||
* 消息类型
|
||||
*/
|
||||
private String type;
|
||||
|
||||
/**
|
||||
* 消息来源
|
||||
*/
|
||||
private String source;
|
||||
|
||||
/**
|
||||
* 标题
|
||||
*/
|
||||
private String title;
|
||||
|
||||
/**
|
||||
* 摘要消息
|
||||
*/
|
||||
private String message;
|
||||
|
||||
/**
|
||||
* 详细内容
|
||||
*/
|
||||
private String content;
|
||||
|
||||
/**
|
||||
* 扩展数据 JSON
|
||||
*/
|
||||
private String dataJson;
|
||||
|
||||
/**
|
||||
* 前端跳转路径
|
||||
*/
|
||||
private String path;
|
||||
|
||||
/**
|
||||
* 目标用户ID串,0 表示全局
|
||||
*/
|
||||
private String sendUserIds;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package org.dromara.system.domain.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 消息盒子视图对象
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@Data
|
||||
public class SysMessageBoxVo implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 系统消息
|
||||
*/
|
||||
private List<SysMessageVo> systemList = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* 通知公告消息
|
||||
*/
|
||||
private List<SysMessageVo> noticeList = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* 工作流消息
|
||||
*/
|
||||
private List<SysMessageVo> workflowList = new ArrayList<>();
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package org.dromara.system.domain.vo;
|
||||
|
||||
import io.github.linpeilie.annotations.AutoMapper;
|
||||
import lombok.Data;
|
||||
import org.dromara.system.domain.SysMessage;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 消息记录视图对象 sys_message
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@Data
|
||||
@AutoMapper(target = SysMessage.class)
|
||||
public class SysMessageVo implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 消息ID
|
||||
*/
|
||||
private Long messageId;
|
||||
|
||||
/**
|
||||
* 消息分组
|
||||
*/
|
||||
private String category;
|
||||
|
||||
/**
|
||||
* 消息类型
|
||||
*/
|
||||
private String type;
|
||||
|
||||
/**
|
||||
* 消息来源
|
||||
*/
|
||||
private String source;
|
||||
|
||||
/**
|
||||
* 标题
|
||||
*/
|
||||
private String title;
|
||||
|
||||
/**
|
||||
* 摘要消息
|
||||
*/
|
||||
private String message;
|
||||
|
||||
/**
|
||||
* 详细内容
|
||||
*/
|
||||
private String content;
|
||||
|
||||
/**
|
||||
* 扩展数据
|
||||
*/
|
||||
private Object data;
|
||||
|
||||
/**
|
||||
* 前端跳转路径
|
||||
*/
|
||||
private String path;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private Date createTime;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package org.dromara.system.mapper;
|
||||
|
||||
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
|
||||
import org.dromara.system.domain.SysMessage;
|
||||
import org.dromara.system.domain.vo.SysMessageVo;
|
||||
|
||||
/**
|
||||
* 消息记录Mapper接口
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
public interface SysMessageMapper extends BaseMapperPlus<SysMessage, SysMessageVo> {
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
package org.dromara.system.service;
|
||||
|
||||
import org.dromara.common.core.domain.dto.PushPayloadDTO;
|
||||
import org.dromara.system.domain.vo.SysMessageBoxVo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 消息记录服务接口
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
public interface ISysMessageService {
|
||||
|
||||
/**
|
||||
* 查询当前用户消息盒子数据
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @return 消息盒子数据
|
||||
*/
|
||||
SysMessageBoxVo queryMessageBox(Long userId);
|
||||
|
||||
/**
|
||||
* 发送指定用户文本消息
|
||||
*
|
||||
* @param userId 目标用户
|
||||
* @param message 文本消息
|
||||
*/
|
||||
void sendMessage(Long userId, String message);
|
||||
|
||||
/**
|
||||
* 广播文本消息
|
||||
*
|
||||
* @param message 文本消息
|
||||
*/
|
||||
void sendMessage(String message);
|
||||
|
||||
/**
|
||||
* 发送指定用户消息
|
||||
*
|
||||
* @param userId 目标用户
|
||||
* @param payload 推送消息体
|
||||
*/
|
||||
void sendMessage(Long userId, PushPayloadDTO payload);
|
||||
|
||||
/**
|
||||
* 广播消息
|
||||
*
|
||||
* @param payload 推送消息体
|
||||
*/
|
||||
void sendMessage(PushPayloadDTO payload);
|
||||
|
||||
/**
|
||||
* 发布指定用户消息
|
||||
*
|
||||
* @param userIds 用户ID列表
|
||||
* @param payload 推送消息体
|
||||
*/
|
||||
void publishMessage(List<Long> userIds, PushPayloadDTO payload);
|
||||
|
||||
/**
|
||||
* 发布广播文本消息
|
||||
*
|
||||
* @param message 文本消息
|
||||
*/
|
||||
void publishAll(String message);
|
||||
|
||||
/**
|
||||
* 发布广播消息
|
||||
*
|
||||
* @param payload 推送消息体
|
||||
*/
|
||||
void publishAll(PushPayloadDTO payload);
|
||||
|
||||
/**
|
||||
* 记录全局消息
|
||||
*
|
||||
* @param payload 推送消息体
|
||||
* @return 回填消息ID后的推送消息体
|
||||
*/
|
||||
PushPayloadDTO storeAll(PushPayloadDTO payload);
|
||||
|
||||
/**
|
||||
* 记录指定用户消息
|
||||
*
|
||||
* @param userIds 用户ID列表
|
||||
* @param payload 推送消息体
|
||||
* @return 回填消息ID后的推送消息体
|
||||
*/
|
||||
PushPayloadDTO storeUsers(List<Long> userIds, PushPayloadDTO payload);
|
||||
}
|
||||
@@ -0,0 +1,194 @@
|
||||
package org.dromara.system.service.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.dromara.common.core.domain.dto.PushPayloadDTO;
|
||||
import org.dromara.common.core.enums.PushSourceEnum;
|
||||
import org.dromara.common.core.enums.PushTypeEnum;
|
||||
import org.dromara.common.core.service.MessageService;
|
||||
import org.dromara.common.core.utils.MapstructUtils;
|
||||
import org.dromara.common.core.utils.StringUtils;
|
||||
import org.dromara.common.json.utils.JsonUtils;
|
||||
import org.dromara.common.mybatis.helper.DataBaseHelper;
|
||||
import org.dromara.common.mybatis.utils.IdGeneratorUtil;
|
||||
import org.dromara.common.push.helper.PushHelper;
|
||||
import org.dromara.system.domain.SysMessage;
|
||||
import org.dromara.system.domain.vo.SysMessageBoxVo;
|
||||
import org.dromara.system.domain.vo.SysMessageVo;
|
||||
import org.dromara.system.mapper.SysMessageMapper;
|
||||
import org.dromara.system.service.ISysMessageService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* 消息记录服务实现
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
public class SysMessageServiceImpl implements ISysMessageService, MessageService {
|
||||
|
||||
private static final String GLOBAL_USER_IDS = "0";
|
||||
private static final String CATEGORY_SYSTEM = "system";
|
||||
private static final String CATEGORY_NOTICE = "notice";
|
||||
private static final String CATEGORY_WORKFLOW = "workflow";
|
||||
private static final int BOX_LIMIT = 100;
|
||||
private static final long BOX_DAYS = 30L;
|
||||
|
||||
private final SysMessageMapper baseMapper;
|
||||
|
||||
@Override
|
||||
public SysMessageBoxVo queryMessageBox(Long userId) {
|
||||
SysMessageBoxVo box = new SysMessageBoxVo();
|
||||
box.setSystemList(selectMessageList(CATEGORY_SYSTEM, userId));
|
||||
box.setNoticeList(selectMessageList(CATEGORY_NOTICE, userId));
|
||||
box.setWorkflowList(selectMessageList(CATEGORY_WORKFLOW, userId));
|
||||
return box;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessage(Long userId, String message) {
|
||||
PushHelper.sendMessage(userId, buildDefaultMessage(message));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessage(String message) {
|
||||
PushHelper.sendMessage(buildDefaultMessage(message));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessage(Long userId, PushPayloadDTO payload) {
|
||||
PushHelper.sendMessage(userId, payload);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessage(PushPayloadDTO payload) {
|
||||
PushHelper.sendMessage(payload);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void publishMessage(List<Long> userIds, PushPayloadDTO payload) {
|
||||
PushHelper.publishMessage(userIds, storeUsers(userIds, payload));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void publishAll(String message) {
|
||||
publishAll(buildDefaultMessage(message));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void publishAll(PushPayloadDTO payload) {
|
||||
PushHelper.publishAll(storeAll(payload));
|
||||
}
|
||||
|
||||
@Override
|
||||
public PushPayloadDTO storeAll(PushPayloadDTO payload) {
|
||||
return storeMessage(null, payload);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PushPayloadDTO storeUsers(List<Long> userIds, PushPayloadDTO payload) {
|
||||
return storeMessage(userIds, payload);
|
||||
}
|
||||
|
||||
private PushPayloadDTO storeMessage(List<Long> userIds, PushPayloadDTO payload) {
|
||||
if (!supportsMessageBox(payload)) {
|
||||
return payload;
|
||||
}
|
||||
SysMessage message = buildMessage(userIds, payload);
|
||||
baseMapper.insert(message);
|
||||
payload.setMessageId(message.getMessageId());
|
||||
return payload;
|
||||
}
|
||||
|
||||
private List<SysMessageVo> selectMessageList(String category, Long userId) {
|
||||
LambdaQueryWrapper<SysMessage> lqw = Wrappers.lambdaQuery();
|
||||
lqw.eq(SysMessage::getCategory, category);
|
||||
lqw.ge(SysMessage::getCreateTime, new Date(System.currentTimeMillis() - TimeUnit.DAYS.toMillis(BOX_DAYS)));
|
||||
lqw.and(wrapper -> wrapper.eq(SysMessage::getSendUserIds, GLOBAL_USER_IDS)
|
||||
.or()
|
||||
.apply(DataBaseHelper.findInSet(userId, "send_user_ids")));
|
||||
lqw.orderByDesc(SysMessage::getCreateTime, SysMessage::getMessageId);
|
||||
List<SysMessage> list = baseMapper.selectList(new Page<>(1, BOX_LIMIT, false), lqw);
|
||||
return list.stream().map(this::buildVo).toList();
|
||||
}
|
||||
|
||||
private SysMessage buildMessage(List<Long> userIds, PushPayloadDTO payload) {
|
||||
SysMessage message = new SysMessage();
|
||||
message.setMessageId(payload.getMessageId() == null ? IdGeneratorUtil.nextLongId() : payload.getMessageId());
|
||||
message.setCategory(resolveCategory(payload));
|
||||
message.setType(payload.getType());
|
||||
message.setSource(payload.getSource());
|
||||
message.setTitle(resolveTitle(payload));
|
||||
message.setMessage(payload.getMessage());
|
||||
message.setContent(resolveContent(payload));
|
||||
message.setDataJson(JsonUtils.toJsonString(payload.getData()));
|
||||
message.setPath(payload.getPath());
|
||||
message.setSendUserIds(CollUtil.isEmpty(userIds) ? GLOBAL_USER_IDS : StringUtils.joinComma(userIds));
|
||||
return message;
|
||||
}
|
||||
|
||||
private SysMessageVo buildVo(SysMessage entity) {
|
||||
SysMessageVo vo = MapstructUtils.convert(entity, SysMessageVo.class);
|
||||
vo.setData(parseData(entity.getDataJson()));
|
||||
return vo;
|
||||
}
|
||||
|
||||
private boolean supportsMessageBox(PushPayloadDTO payload) {
|
||||
if (payload == null) {
|
||||
return false;
|
||||
}
|
||||
if (StringUtils.equalsAny(payload.getType(), PushTypeEnum.MESSAGE.getType(), PushTypeEnum.NOTICE.getType())) {
|
||||
return !StringUtils.equalsAny(payload.getType(), PushTypeEnum.LLM.getType())
|
||||
&& !StringUtils.equalsAny(payload.getSource(), PushSourceEnum.LLM.getSource());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private String resolveCategory(PushPayloadDTO payload) {
|
||||
if (StringUtils.equalsAny(payload.getType(), PushTypeEnum.NOTICE.getType())
|
||||
|| StringUtils.equalsAny(payload.getSource(), PushSourceEnum.NOTICE.getSource())) {
|
||||
return CATEGORY_NOTICE;
|
||||
}
|
||||
if (StringUtils.equalsAny(payload.getSource(), PushSourceEnum.WORKFLOW.getSource())) {
|
||||
return CATEGORY_WORKFLOW;
|
||||
}
|
||||
return CATEGORY_SYSTEM;
|
||||
}
|
||||
|
||||
private String resolveTitle(PushPayloadDTO payload) {
|
||||
return switch (resolveCategory(payload)) {
|
||||
case CATEGORY_NOTICE -> "通知公告消息";
|
||||
case CATEGORY_WORKFLOW -> "工作流消息";
|
||||
default -> "系统消息";
|
||||
};
|
||||
}
|
||||
|
||||
private String resolveContent(PushPayloadDTO payload) {
|
||||
Object data = payload.getData();
|
||||
if (data instanceof Map<?, ?> map) {
|
||||
return Convert.toStr(map.get("noticeContent"));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Object parseData(String dataJson) {
|
||||
if (StringUtils.isBlank(dataJson)) {
|
||||
return null;
|
||||
}
|
||||
return JsonUtils.parseObject(dataJson, Object.class);
|
||||
}
|
||||
|
||||
private PushPayloadDTO buildDefaultMessage(String message) {
|
||||
return PushPayloadDTO.of(PushTypeEnum.MESSAGE, PushSourceEnum.BACKEND, message, null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="org.dromara.system.mapper.SysMessageMapper">
|
||||
|
||||
</mapper>
|
||||
@@ -4,16 +4,16 @@ import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.common.core.domain.dto.PushPayload;
|
||||
import org.dromara.common.core.domain.dto.PushPayloadDTO;
|
||||
import org.dromara.common.core.domain.dto.UserDTO;
|
||||
import org.dromara.common.core.enums.PushSourceEnum;
|
||||
import org.dromara.common.core.enums.PushTypeEnum;
|
||||
import org.dromara.common.core.exception.ServiceException;
|
||||
import org.dromara.common.core.service.MessageService;
|
||||
import org.dromara.common.core.utils.SpringUtils;
|
||||
import org.dromara.common.core.utils.StreamUtils;
|
||||
import org.dromara.common.core.utils.StringUtils;
|
||||
import org.dromara.common.mail.utils.MailUtils;
|
||||
import org.dromara.common.push.helper.PushHelper;
|
||||
import org.dromara.warm.flow.core.FlowEngine;
|
||||
import org.dromara.warm.flow.core.entity.Node;
|
||||
import org.dromara.warm.flow.orm.entity.FlowTask;
|
||||
@@ -41,6 +41,7 @@ import java.util.Set;
|
||||
public class FlwCommonServiceImpl implements IFlwCommonService {
|
||||
|
||||
private static final String DEFAULT_SUBJECT = "单据审批提醒";
|
||||
private final MessageService messageService;
|
||||
|
||||
/**
|
||||
* 根据流程实例发送消息给当前处理人
|
||||
@@ -94,7 +95,7 @@ public class FlwCommonServiceImpl implements IFlwCommonService {
|
||||
try {
|
||||
switch (messageTypeEnum) {
|
||||
case SYSTEM_MESSAGE -> {
|
||||
PushHelper.publishMessage(userIds, PushPayload.of(
|
||||
messageService.publishMessage(userIds, PushPayloadDTO.of(
|
||||
PushTypeEnum.MESSAGE,
|
||||
PushSourceEnum.WORKFLOW,
|
||||
message,
|
||||
|
||||
@@ -925,7 +925,50 @@ insert into sys_notice values('2', '维护通知:2018-07-01 系统凌晨维护
|
||||
|
||||
|
||||
-- ----------------------------
|
||||
-- 18、代码生成业务表
|
||||
-- 18、消息记录表
|
||||
-- ----------------------------
|
||||
create table sys_message (
|
||||
message_id number(20) not null,
|
||||
category varchar2(20) not null,
|
||||
type varchar2(20) not null,
|
||||
source varchar2(20) not null,
|
||||
title varchar2(100) default '',
|
||||
message varchar2(500) default '',
|
||||
content clob default null,
|
||||
data_json clob default null,
|
||||
path varchar2(500) default null,
|
||||
send_user_ids varchar2(2000) default '0' not null,
|
||||
create_dept number(20) default null,
|
||||
create_by number(20) default null,
|
||||
create_time date,
|
||||
update_by number(20) default null,
|
||||
update_time date
|
||||
);
|
||||
|
||||
alter table sys_message add constraint pk_sys_message primary key (message_id);
|
||||
|
||||
create index idx_sys_message_category_time on sys_message(category, create_time);
|
||||
|
||||
comment on table sys_message is '消息记录表';
|
||||
comment on column sys_message.message_id is '消息ID';
|
||||
comment on column sys_message.category is '消息分组(system/notice/workflow)';
|
||||
comment on column sys_message.type is '消息类型';
|
||||
comment on column sys_message.source is '消息来源';
|
||||
comment on column sys_message.title is '标题';
|
||||
comment on column sys_message.message is '摘要消息';
|
||||
comment on column sys_message.content is '详细内容';
|
||||
comment on column sys_message.data_json is '扩展数据JSON';
|
||||
comment on column sys_message.path is '前端跳转路径';
|
||||
comment on column sys_message.send_user_ids is '目标用户ID串,0表示全局';
|
||||
comment on column sys_message.create_dept is '创建部门';
|
||||
comment on column sys_message.create_by is '创建者';
|
||||
comment on column sys_message.create_time is '创建时间';
|
||||
comment on column sys_message.update_by is '更新者';
|
||||
comment on column sys_message.update_time is '更新时间';
|
||||
|
||||
|
||||
-- ----------------------------
|
||||
-- 19、代码生成业务表
|
||||
-- ----------------------------
|
||||
create table gen_table (
|
||||
table_id number(20) not null,
|
||||
@@ -980,7 +1023,7 @@ comment on column gen_table.remark is '备注';
|
||||
|
||||
|
||||
-- ----------------------------
|
||||
-- 19、代码生成业务表字段
|
||||
-- 20、代码生成业务表字段
|
||||
-- ----------------------------
|
||||
create table gen_table_column (
|
||||
column_id number(20) not null,
|
||||
|
||||
@@ -923,7 +923,50 @@ insert into sys_notice values('2', '维护通知:2018-07-01 系统凌晨维护
|
||||
|
||||
|
||||
-- ----------------------------
|
||||
-- 18、代码生成业务表
|
||||
-- 18、消息记录表
|
||||
-- ----------------------------
|
||||
create table if not exists sys_message
|
||||
(
|
||||
message_id int8,
|
||||
category varchar(20) not null,
|
||||
type varchar(20) not null,
|
||||
source varchar(20) not null,
|
||||
title varchar(100) default ''::varchar,
|
||||
message varchar(500) default ''::varchar,
|
||||
content text,
|
||||
data_json text,
|
||||
path varchar(500) default null::varchar,
|
||||
send_user_ids varchar(2000) not null default '0'::varchar,
|
||||
create_dept int8,
|
||||
create_by int8,
|
||||
create_time timestamp,
|
||||
update_by int8,
|
||||
update_time timestamp,
|
||||
constraint sys_message_pk primary key (message_id)
|
||||
);
|
||||
|
||||
create index if not exists idx_sys_message_category_time on sys_message (category, create_time);
|
||||
|
||||
comment on table sys_message is '消息记录表';
|
||||
comment on column sys_message.message_id is '消息ID';
|
||||
comment on column sys_message.category is '消息分组(system/notice/workflow)';
|
||||
comment on column sys_message.type is '消息类型';
|
||||
comment on column sys_message.source is '消息来源';
|
||||
comment on column sys_message.title is '标题';
|
||||
comment on column sys_message.message is '摘要消息';
|
||||
comment on column sys_message.content is '详细内容';
|
||||
comment on column sys_message.data_json is '扩展数据JSON';
|
||||
comment on column sys_message.path is '前端跳转路径';
|
||||
comment on column sys_message.send_user_ids is '目标用户ID串,0表示全局';
|
||||
comment on column sys_message.create_dept is '创建部门';
|
||||
comment on column sys_message.create_by is '创建者';
|
||||
comment on column sys_message.create_time is '创建时间';
|
||||
comment on column sys_message.update_by is '更新者';
|
||||
comment on column sys_message.update_time is '更新时间';
|
||||
|
||||
|
||||
-- ----------------------------
|
||||
-- 19、代码生成业务表
|
||||
-- ----------------------------
|
||||
create table if not exists gen_table
|
||||
(
|
||||
@@ -977,7 +1020,7 @@ comment on column gen_table.update_time is '更新时间';
|
||||
comment on column gen_table.remark is '备注';
|
||||
|
||||
-- ----------------------------
|
||||
-- 19、代码生成业务表字段
|
||||
-- 20、代码生成业务表字段
|
||||
-- ----------------------------
|
||||
create table if not exists gen_table_column
|
||||
(
|
||||
|
||||
@@ -689,7 +689,31 @@ insert into sys_notice values('2', '维护通知:2018-07-01 系统凌晨维护
|
||||
|
||||
|
||||
-- ----------------------------
|
||||
-- 18、代码生成业务表
|
||||
-- 18、消息记录表
|
||||
-- ----------------------------
|
||||
create table sys_message (
|
||||
message_id bigint(20) not null comment '消息ID',
|
||||
category varchar(20) not null comment '消息分组(system/notice/workflow)',
|
||||
type varchar(20) not null comment '消息类型',
|
||||
source varchar(20) not null comment '消息来源',
|
||||
title varchar(100) default '' comment '标题',
|
||||
message varchar(500) default '' comment '摘要消息',
|
||||
content longtext comment '详细内容',
|
||||
data_json longtext comment '扩展数据JSON',
|
||||
path varchar(500) default null comment '前端跳转路径',
|
||||
send_user_ids varchar(2000) not null default '0' comment '目标用户ID串,0表示全局',
|
||||
create_dept bigint(20) default null comment '创建部门',
|
||||
create_by bigint(20) default null comment '创建者',
|
||||
create_time datetime comment '创建时间',
|
||||
update_by bigint(20) default null comment '更新者',
|
||||
update_time datetime comment '更新时间',
|
||||
primary key (message_id),
|
||||
key idx_sys_message_category_time (category, create_time)
|
||||
) engine=innodb comment = '消息记录表';
|
||||
|
||||
|
||||
-- ----------------------------
|
||||
-- 19、代码生成业务表
|
||||
-- ----------------------------
|
||||
create table gen_table (
|
||||
table_id bigint(20) not null comment '编号',
|
||||
|
||||
@@ -1674,6 +1674,130 @@ GO
|
||||
INSERT sys_notice VALUES (2, N'维护通知:2018-07-01 若依系统凌晨维护', N'1', N'维护内容', N'0', 103, 1, getdate(), NULL, NULL, N'管理员')
|
||||
GO
|
||||
|
||||
CREATE TABLE sys_message
|
||||
(
|
||||
message_id bigint NOT NULL,
|
||||
category nvarchar(20) NOT NULL,
|
||||
type nvarchar(20) NOT NULL,
|
||||
source nvarchar(20) NOT NULL,
|
||||
title nvarchar(100) DEFAULT ('') NULL,
|
||||
message nvarchar(500) DEFAULT ('') NULL,
|
||||
content nvarchar(max) NULL,
|
||||
data_json nvarchar(max) NULL,
|
||||
path nvarchar(500) NULL,
|
||||
send_user_ids nvarchar(2000) DEFAULT ('0') NOT NULL,
|
||||
create_dept bigint NULL,
|
||||
create_by bigint NULL,
|
||||
create_time datetime2(7) NULL,
|
||||
update_by bigint NULL,
|
||||
update_time datetime2(7) NULL,
|
||||
CONSTRAINT PK__sys_mess__0BBF6EE69F35486A PRIMARY KEY CLUSTERED (message_id)
|
||||
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
|
||||
ON [PRIMARY]
|
||||
)
|
||||
ON [PRIMARY]
|
||||
TEXTIMAGE_ON [PRIMARY]
|
||||
GO
|
||||
|
||||
CREATE NONCLUSTERED INDEX idx_sys_message_category_time ON sys_message(category, create_time)
|
||||
GO
|
||||
|
||||
EXEC sys.sp_addextendedproperty
|
||||
'MS_Description', N'消息ID' ,
|
||||
'SCHEMA', N'dbo',
|
||||
'TABLE', N'sys_message',
|
||||
'COLUMN', N'message_id'
|
||||
GO
|
||||
EXEC sys.sp_addextendedproperty
|
||||
'MS_Description', N'消息分组(system/notice/workflow)' ,
|
||||
'SCHEMA', N'dbo',
|
||||
'TABLE', N'sys_message',
|
||||
'COLUMN', N'category'
|
||||
GO
|
||||
EXEC sys.sp_addextendedproperty
|
||||
'MS_Description', N'消息类型' ,
|
||||
'SCHEMA', N'dbo',
|
||||
'TABLE', N'sys_message',
|
||||
'COLUMN', N'type'
|
||||
GO
|
||||
EXEC sys.sp_addextendedproperty
|
||||
'MS_Description', N'消息来源' ,
|
||||
'SCHEMA', N'dbo',
|
||||
'TABLE', N'sys_message',
|
||||
'COLUMN', N'source'
|
||||
GO
|
||||
EXEC sys.sp_addextendedproperty
|
||||
'MS_Description', N'标题' ,
|
||||
'SCHEMA', N'dbo',
|
||||
'TABLE', N'sys_message',
|
||||
'COLUMN', N'title'
|
||||
GO
|
||||
EXEC sys.sp_addextendedproperty
|
||||
'MS_Description', N'摘要消息' ,
|
||||
'SCHEMA', N'dbo',
|
||||
'TABLE', N'sys_message',
|
||||
'COLUMN', N'message'
|
||||
GO
|
||||
EXEC sys.sp_addextendedproperty
|
||||
'MS_Description', N'详细内容' ,
|
||||
'SCHEMA', N'dbo',
|
||||
'TABLE', N'sys_message',
|
||||
'COLUMN', N'content'
|
||||
GO
|
||||
EXEC sys.sp_addextendedproperty
|
||||
'MS_Description', N'扩展数据JSON' ,
|
||||
'SCHEMA', N'dbo',
|
||||
'TABLE', N'sys_message',
|
||||
'COLUMN', N'data_json'
|
||||
GO
|
||||
EXEC sys.sp_addextendedproperty
|
||||
'MS_Description', N'前端跳转路径' ,
|
||||
'SCHEMA', N'dbo',
|
||||
'TABLE', N'sys_message',
|
||||
'COLUMN', N'path'
|
||||
GO
|
||||
EXEC sys.sp_addextendedproperty
|
||||
'MS_Description', N'目标用户ID串,0表示全局' ,
|
||||
'SCHEMA', N'dbo',
|
||||
'TABLE', N'sys_message',
|
||||
'COLUMN', N'send_user_ids'
|
||||
GO
|
||||
EXEC sys.sp_addextendedproperty
|
||||
'MS_Description', N'创建部门' ,
|
||||
'SCHEMA', N'dbo',
|
||||
'TABLE', N'sys_message',
|
||||
'COLUMN', N'create_dept'
|
||||
GO
|
||||
EXEC sys.sp_addextendedproperty
|
||||
'MS_Description', N'创建者' ,
|
||||
'SCHEMA', N'dbo',
|
||||
'TABLE', N'sys_message',
|
||||
'COLUMN', N'create_by'
|
||||
GO
|
||||
EXEC sys.sp_addextendedproperty
|
||||
'MS_Description', N'创建时间' ,
|
||||
'SCHEMA', N'dbo',
|
||||
'TABLE', N'sys_message',
|
||||
'COLUMN', N'create_time'
|
||||
GO
|
||||
EXEC sys.sp_addextendedproperty
|
||||
'MS_Description', N'更新者' ,
|
||||
'SCHEMA', N'dbo',
|
||||
'TABLE', N'sys_message',
|
||||
'COLUMN', N'update_by'
|
||||
GO
|
||||
EXEC sys.sp_addextendedproperty
|
||||
'MS_Description', N'更新时间' ,
|
||||
'SCHEMA', N'dbo',
|
||||
'TABLE', N'sys_message',
|
||||
'COLUMN', N'update_time'
|
||||
GO
|
||||
EXEC sys.sp_addextendedproperty
|
||||
'MS_Description', N'消息记录表' ,
|
||||
'SCHEMA', N'dbo',
|
||||
'TABLE', N'sys_message'
|
||||
GO
|
||||
|
||||
CREATE TABLE sys_oper_log
|
||||
(
|
||||
oper_id bigint NOT NULL,
|
||||
|
||||
Reference in New Issue
Block a user