diff --git a/backend/src/main/java/io/dataease/commons/constants/SysMsgConstants.java b/backend/src/main/java/io/dataease/commons/constants/SysMsgConstants.java index 206bfbc264..6c2689404a 100644 --- a/backend/src/main/java/io/dataease/commons/constants/SysMsgConstants.java +++ b/backend/src/main/java/io/dataease/commons/constants/SysMsgConstants.java @@ -4,4 +4,5 @@ public class SysMsgConstants { public final static String SYS_MSG_CHANNEL = "sys_msg_channel"; public final static String SYS_MSG_TYPE = "sys_msg_type"; + public final static String SYS_MSG_USER_SUBSCRIBE = "sys_msg_user_subscribe"; } diff --git a/backend/src/main/java/io/dataease/controller/message/MsgController.java b/backend/src/main/java/io/dataease/controller/message/MsgController.java index 51415ea0ff..6f84a2e4df 100644 --- a/backend/src/main/java/io/dataease/controller/message/MsgController.java +++ b/backend/src/main/java/io/dataease/controller/message/MsgController.java @@ -8,7 +8,6 @@ import io.dataease.base.domain.SysMsgType; import io.dataease.commons.utils.AuthUtils; import io.dataease.commons.utils.PageUtils; import io.dataease.commons.utils.Pager; -import io.dataease.controller.handler.annotation.I18n; import io.dataease.controller.message.dto.MsgGridDto; import io.dataease.controller.message.dto.MsgRequest; import io.dataease.controller.message.dto.MsgSettingRequest; @@ -53,14 +52,12 @@ public class MsgController { sysMsgService.batchDelete(msgIds); } - @I18n @PostMapping("/treeNodes") public List treeNodes() { return sysMsgService.treeNodes(); } - @I18n @PostMapping("/channelList") public List channelList() { return sysMsgService.channelList(); @@ -73,10 +70,10 @@ public class MsgController { @PostMapping("/updateSetting") public void updateSetting(@RequestBody MsgSettingRequest request) { - sysMsgService.updateSetting(request); + Long userId = AuthUtils.getUser().getUserId(); + sysMsgService.updateSetting(request, userId); } - @I18n @PostMapping("/types") public List allTypes() { List sysMsgTypes = sysMsgService.queryMsgTypes(); diff --git a/backend/src/main/java/io/dataease/controller/message/dto/SubscribeNode.java b/backend/src/main/java/io/dataease/controller/message/dto/SubscribeNode.java new file mode 100644 index 0000000000..40773bd735 --- /dev/null +++ b/backend/src/main/java/io/dataease/controller/message/dto/SubscribeNode.java @@ -0,0 +1,20 @@ +package io.dataease.controller.message.dto; + + +import lombok.Data; + +import java.io.Serializable; + +@Data +public class SubscribeNode implements Serializable { + + private static final long serialVersionUID = -1680823237289721438L; + + private Long typeId; + + private Long channelId; + + public Boolean match(Long type, Long channel) { + return type == typeId && channel == channelId; + } +} diff --git a/backend/src/main/java/io/dataease/service/message/DeMsgutil.java b/backend/src/main/java/io/dataease/service/message/DeMsgutil.java index 765d9e27e8..8d3e62c527 100644 --- a/backend/src/main/java/io/dataease/service/message/DeMsgutil.java +++ b/backend/src/main/java/io/dataease/service/message/DeMsgutil.java @@ -1,6 +1,5 @@ package io.dataease.service.message; -import io.dataease.base.domain.SysMsg; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -20,14 +19,14 @@ public class DeMsgutil { public static void sendMsg(Long userId, Long typeId, Long channelId, String content, String param) { - SysMsg sysMsg = new SysMsg(); - sysMsg.setUserId(userId); - sysMsg.setTypeId(typeId); - sysMsg.setContent(content); - sysMsg.setStatus(false); - sysMsg.setCreateTime(System.currentTimeMillis()); - sysMsg.setParam(param); - sysMsgService.save(sysMsg); +// SysMsg sysMsg = new SysMsg(); +// sysMsg.setUserId(userId); +// sysMsg.setTypeId(typeId); +// sysMsg.setContent(content); +// sysMsg.setStatus(false); +// sysMsg.setCreateTime(System.currentTimeMillis()); +// sysMsg.setParam(param); + sysMsgService.sendMsg(userId, typeId, channelId, content, param); } diff --git a/backend/src/main/java/io/dataease/service/message/MsgAop.java b/backend/src/main/java/io/dataease/service/message/MsgAop.java index 1dc102206a..cf4cb8790e 100644 --- a/backend/src/main/java/io/dataease/service/message/MsgAop.java +++ b/backend/src/main/java/io/dataease/service/message/MsgAop.java @@ -1,20 +1,25 @@ package io.dataease.service.message; -import io.dataease.base.domain.SysMsgSettingExample; -import io.dataease.base.mapper.SysMsgSettingMapper; + +import io.dataease.controller.message.dto.SubscribeNode; +import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.ObjectUtils; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.springframework.stereotype.Component; import javax.annotation.Resource; +import java.util.List; @Aspect @Component public class MsgAop { + + + @Resource - private SysMsgSettingMapper sysMsgSettingMapper; + private SysMsgService sysMsgService; @@ -24,7 +29,7 @@ public class MsgAop { * 对sendMsg 切面拦截 * @param point */ - @Around("(execution(* io.dataease.service.message.DeMsgutil.sendMsg(..)))") + @Around("(execution(* io.dataease.service.message.SysMsgService.sendMsg(..)))") public Object cutPoint(ProceedingJoinPoint point) { Object[] args = point.getArgs(); @@ -39,11 +44,11 @@ public class MsgAop { Long typeId = (Long) arg1; Long channelId = (Long) arg2; - SysMsgSettingExample example = new SysMsgSettingExample(); - example.createCriteria().andChannelIdEqualTo(channelId).andUserIdEqualTo(userId).andTypeIdEqualTo(typeId).andEnableEqualTo(true); + List subscribes = sysMsgService.subscribes(userId); try { - if (sysMsgSettingMapper.countByExample(example) > 0) + // 如果已经订阅了这种类型的消息 直接发送 否则直接返回 + if (CollectionUtils.isNotEmpty(subscribes) && subscribes.stream().anyMatch(item -> item.match(typeId, channelId))) return point.proceed(args); return null; } catch (Throwable throwable) { diff --git a/backend/src/main/java/io/dataease/service/message/SysMsgService.java b/backend/src/main/java/io/dataease/service/message/SysMsgService.java index 9f8255bc4d..0bc5cdb8c8 100644 --- a/backend/src/main/java/io/dataease/service/message/SysMsgService.java +++ b/backend/src/main/java/io/dataease/service/message/SysMsgService.java @@ -7,16 +7,13 @@ import io.dataease.base.mapper.SysMsgMapper; import io.dataease.base.mapper.SysMsgSettingMapper; import io.dataease.base.mapper.SysMsgTypeMapper; import io.dataease.base.mapper.ext.ExtSysMsgMapper; -import io.dataease.commons.constants.AuthConstants; import io.dataease.commons.constants.SysMsgConstants; import io.dataease.commons.utils.AuthUtils; import io.dataease.commons.utils.CommonBeanFactory; -import io.dataease.controller.message.dto.MsgGridDto; -import io.dataease.controller.message.dto.MsgRequest; -import io.dataease.controller.message.dto.MsgSettingRequest; -import io.dataease.controller.message.dto.SettingTreeNode; +import io.dataease.controller.message.dto.*; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.ObjectUtils; +import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -179,11 +176,17 @@ public class SysMsgService { return sysMsgSettings; } + /** + * 修改了订阅信息 需要清除缓存 + * @param request + * @param userId + */ @Transactional - public void updateSetting(MsgSettingRequest request) { + @CacheEvict(value = SysMsgConstants.SYS_MSG_USER_SUBSCRIBE, key = "#userId") + public void updateSetting(MsgSettingRequest request, Long userId) { Long typeId = request.getTypeId(); Long channelId = request.getChannelId(); - Long userId = AuthUtils.getUser().getUserId(); + // Long userId = AuthUtils.getUser().getUserId(); SysMsgSettingExample example = new SysMsgSettingExample(); example.createCriteria().andUserIdEqualTo(userId).andTypeIdEqualTo(typeId).andChannelIdEqualTo(channelId); List sysMsgSettings = sysMsgSettingMapper.selectByExample(example); @@ -202,5 +205,34 @@ public class SysMsgService { sysMsgSettingMapper.insert(sysMsgSetting); } + public void sendMsg(Long userId, Long typeId, Long channelId, String content, String param) { + SysMsg sysMsg = new SysMsg(); + sysMsg.setUserId(userId); + sysMsg.setTypeId(typeId); + sysMsg.setContent(content); + sysMsg.setStatus(false); + sysMsg.setCreateTime(System.currentTimeMillis()); + sysMsg.setParam(param); + save(sysMsg); + } + + /** + * 查询用户订阅的消息 并缓存 + * @param userId + * @return + */ + @Cacheable(value = SysMsgConstants.SYS_MSG_USER_SUBSCRIBE, key = "#userId") + public List subscribes(Long userId) { + SysMsgSettingExample example = new SysMsgSettingExample(); + example.createCriteria().andUserIdEqualTo(userId).andEnableEqualTo(true); + List sysMsgSettings = sysMsgSettingMapper.selectByExample(example); + List resultLists = sysMsgSettings.stream().map(item -> { + SubscribeNode subscribeNode = new SubscribeNode(); + subscribeNode.setTypeId(item.getTypeId()); + subscribeNode.setChannelId(item.getChannelId()); + return subscribeNode; + }).collect(Collectors.toList()); + return resultLists; + } } diff --git a/backend/src/main/resources/db/migration/V10__web_msg.sql b/backend/src/main/resources/db/migration/V10__web_msg.sql index 5702ecc48d..139c31b8e8 100644 --- a/backend/src/main/resources/db/migration/V10__web_msg.sql +++ b/backend/src/main/resources/db/migration/V10__web_msg.sql @@ -5,24 +5,81 @@ DROP TABLE IF EXISTS `sys_msg`; CREATE TABLE `sys_msg` ( `msg_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '消息主键', `user_id` bigint(20) NOT NULL COMMENT '用户ID', - `type` int(4) NOT NULL COMMENT '类型', + `type_id` bigint(20) NOT NULL COMMENT '类型', `status` tinyint(1) NOT NULL COMMENT '状态', - `router` varchar(255) DEFAULT NULL COMMENT '跳转路由', `param` varchar(255) DEFAULT NULL COMMENT '路由参数', `create_time` bigint(13) NOT NULL COMMENT '发送时间', `read_time` bigint(13) DEFAULT NULL COMMENT '读取时间', `content` varchar(255) DEFAULT NULL COMMENT '消息内容', PRIMARY KEY (`msg_id`) USING BTREE, KEY `inx_msg_userid` (`user_id`) USING BTREE, - KEY `inx_msg_type` (`type`) USING BTREE, + KEY `inx_msg_type` (`type_id`) USING BTREE, KEY `inx_msg_status` (`status`) USING BTREE -) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='消息通知表'; +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='消息通知表'; + +-- ---------------------------- +-- Table structure for sys_msg_channel +-- ---------------------------- +DROP TABLE IF EXISTS `sys_msg_channel`; +CREATE TABLE `sys_msg_channel` ( + `msg_channel_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键', + `channel_name` varchar(255) DEFAULT NULL COMMENT '渠道名称', + PRIMARY KEY (`msg_channel_id`) USING BTREE +) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COMMENT='消息渠道表'; + +-- ---------------------------- +-- Records of sys_msg_channel +-- ---------------------------- +BEGIN; +INSERT INTO `sys_msg_channel` VALUES (1, 'webmsg.channel_inner_msg'); +COMMIT; + + +-- ---------------------------- +-- Table structure for sys_msg_type +-- ---------------------------- +DROP TABLE IF EXISTS `sys_msg_type`; +CREATE TABLE `sys_msg_type` ( + `msg_type_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键', + `pid` bigint(20) NOT NULL COMMENT '父类ID', + `type_name` varchar(255) DEFAULT NULL COMMENT '类型名称', + `router` varchar(255) DEFAULT NULL COMMENT '跳转路由', + `callback` varchar(255) DEFAULT NULL COMMENT '回调方法', + PRIMARY KEY (`msg_type_id`) USING BTREE, + KEY `inx_msgtype_pid` (`pid`) USING BTREE +) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 COMMENT='消息类型表'; + +-- ---------------------------- +-- Records of sys_msg_type +-- ---------------------------- +BEGIN; +INSERT INTO `sys_msg_type` VALUES (1, 0, 'i18n_msg_type_panel_share', 'panel', 'to-msg-share'); +INSERT INTO `sys_msg_type` VALUES (2, 1, 'i18n_msg_type_panel_share', 'panel', 'to-msg-share'); +INSERT INTO `sys_msg_type` VALUES (3, 1, 'i18n_msg_type_panel_share_cacnel', 'panel', 'to-msg-share'); +INSERT INTO `sys_msg_type` VALUES (4, 0, 'i18n_msg_type_dataset_sync', 'dataset', 'to-msg-dataset'); +INSERT INTO `sys_msg_type` VALUES (5, 4, 'i18n_msg_type_dataset_sync_success', 'dataset', 'to-msg-dataset'); +INSERT INTO `sys_msg_type` VALUES (6, 4, 'i18n_msg_type_dataset_sync_faild', 'dataset', 'to-msg-dataset'); +COMMIT; + +-- ---------------------------- +-- Table structure for sys_msg_setting +-- ---------------------------- +DROP TABLE IF EXISTS `sys_msg_setting`; +CREATE TABLE `sys_msg_setting` ( + `msg_setting_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键', + `user_id` bigint(20) NOT NULL COMMENT '用户ID', + `type_id` bigint(20) NOT NULL COMMENT '类型ID', + `channel_id` bigint(20) NOT NULL COMMENT '渠道ID', + `enable` tinyint(1) DEFAULT NULL COMMENT '是否启用', + PRIMARY KEY (`msg_setting_id`) USING BTREE +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='消息设置表'; BEGIN; INSERT INTO `sys_menu` VALUES (53, 1, 3, 1, '站内消息', 'sys-msg-web', 'msg/index', 1000, 'all-msg', 'system-msg-web', b'0', b'0', b'0', NULL, NULL, NULL, NULL, NULL); INSERT INTO `sys_menu` VALUES (54, 53, 0, 1, '所有消息', 'sys-msg-web-all', 'msg/all', 1, 'web-msg', 'all', b'0', b'0', b'0', NULL, NULL, NULL, NULL, NULL); INSERT INTO `sys_menu` VALUES (55, 53, 0, 1, '未读消息', 'sys-msg-web-unread', 'msg/unread', 2, 'unread-msg', 'unread', b'0', b'0', b'0', NULL, NULL, NULL, NULL, NULL); INSERT INTO `sys_menu` VALUES (56, 53, 0, 1, '已读消息', 'sys-msg-web-readed', 'msg/readed', 3, 'readed-msg', 'readed', b'0', b'0', b'0', NULL, NULL, NULL, NULL, NULL); +INSERT INTO `sys_menu` VALUES (59, 53, 0, 1, '接收管理', 'sys-msg-setting', 'msg/setting', 4, 'msg-setting', 'setting', b'0', b'0', b'0', NULL, NULL, NULL, NULL, NULL); COMMIT; BEGIN; diff --git a/backend/src/main/resources/ehcache/ehcache.xml b/backend/src/main/resources/ehcache/ehcache.xml index 3407f77ff9..7043e2aa90 100644 --- a/backend/src/main/resources/ehcache/ehcache.xml +++ b/backend/src/main/resources/ehcache/ehcache.xml @@ -102,7 +102,7 @@ maxElementsInMemory="100" maxElementsOnDisk="1000" overflowToDisk="true" - diskPersistent="true" + diskPersistent="false" /> @@ -112,7 +112,20 @@ maxElementsInMemory="100" maxElementsOnDisk="1000" overflowToDisk="true" - diskPersistent="true" + diskPersistent="false" + /> + + + diff --git a/frontend/src/components/Notification/index.vue b/frontend/src/components/Notification/index.vue index 4ec8f8102d..c173641dfe 100644 --- a/frontend/src/components/Notification/index.vue +++ b/frontend/src/components/Notification/index.vue @@ -108,7 +108,7 @@ export default { // console.log(lang) // }, showDetail(row) { - const param = { ...{ msgNotification: true, msgType: row.type, sourceParam: row.param }} + const param = { ...{ msgNotification: true, msgType: row.typeId, sourceParam: row.param }} this.visible = false // if (this.$route && this.$route.name && this.$route.name.includes('panel') && row.type === 0) { // bus.$emit('to-msg-share', param) @@ -162,7 +162,7 @@ export default { }) }, getTypeName(value) { - return getTypeName(value) + return this.$t('webmsg.' + getTypeName(value)) }, open() { this.visible = true diff --git a/frontend/src/lang/en.js b/frontend/src/lang/en.js index 207e2187f3..1f54e9be60 100644 --- a/frontend/src/lang/en.js +++ b/frontend/src/lang/en.js @@ -1240,6 +1240,13 @@ export default { mark_readed: 'Mark As Read', please_select: 'Please select at least one message', mark_success: 'Mark read successfully', - receive_manage: 'Receive Manage' + receive_manage: 'Receive Manage', + i18n_msg_type_panel_share: 'Dashboard sharing', + i18n_msg_type_panel_share_cacnel: 'Dashboard unshared', + i18n_msg_type_dataset_sync: 'Data set synchronization', + i18n_msg_type_dataset_sync_success: 'Dataset synchronization successful', + i18n_msg_type_dataset_sync_faild: 'Dataset synchronization failed', + i18n_msg_type_all: 'All type', + channel_inner_msg: 'On site news' } } diff --git a/frontend/src/lang/tw.js b/frontend/src/lang/tw.js index 319a8a3c62..8b229008d4 100644 --- a/frontend/src/lang/tw.js +++ b/frontend/src/lang/tw.js @@ -1240,6 +1240,13 @@ export default { mark_readed: '標記已讀', please_select: '請至少選擇一條消息', mark_success: '標記已讀成功', - receive_manage: '接收管理' + receive_manage: '接收管理', + i18n_msg_type_panel_share: '儀表板分享', + i18n_msg_type_panel_share_cacnel: '儀表板取消分享', + i18n_msg_type_dataset_sync: '數據集同步', + i18n_msg_type_dataset_sync_success: '數據集同步成功', + i18n_msg_type_dataset_sync_faild: '數據集同步失敗', + i18n_msg_type_all: '全部類型', + channel_inner_msg: '站內消息' } } diff --git a/frontend/src/lang/zh.js b/frontend/src/lang/zh.js index 69f9751ada..91c05e0578 100644 --- a/frontend/src/lang/zh.js +++ b/frontend/src/lang/zh.js @@ -1242,6 +1242,13 @@ export default { mark_readed: '标记已读', please_select: '请至少选择一条消息', mark_success: '标记已读成功', - receive_manage: '接收管理' + receive_manage: '接收管理', + i18n_msg_type_panel_share: '仪表板分享', + i18n_msg_type_panel_share_cacnel: '仪表板取消分享', + i18n_msg_type_dataset_sync: '数据集同步', + i18n_msg_type_dataset_sync_success: '数据集同步成功', + i18n_msg_type_dataset_sync_faild: '数据集同步失败', + i18n_msg_type_all: '全部类型', + channel_inner_msg: '站内消息' } } diff --git a/frontend/src/utils/webMsg.js b/frontend/src/utils/webMsg.js index 46ba904728..7e697a59cc 100644 --- a/frontend/src/utils/webMsg.js +++ b/frontend/src/utils/webMsg.js @@ -6,7 +6,7 @@ export const loadMsgTypes = value => { if (!msgTypes || Object.keys(msgTypes).length === 0) { allTypes().then(res => { msgTypes = res.data - const defaultType = { msgTypeId: -1, pid: 0, typeName: '全部类型' } + const defaultType = { msgTypeId: -1, pid: 0, typeName: 'i18n_msg_type_all' } msgTypes.splice(0, 0, defaultType) store.dispatch('msg/setMsgTypes', msgTypes) }) diff --git a/frontend/src/views/dataset/index.vue b/frontend/src/views/dataset/index.vue index 860139cf0e..49415c7a7e 100644 --- a/frontend/src/views/dataset/index.vue +++ b/frontend/src/views/dataset/index.vue @@ -99,15 +99,16 @@ export default { toMsgShare(routerParam) { if (routerParam !== null && routerParam.msgNotification) { - // 说明是从消息通知跳转过来的 - if (routerParam.msgType === 1) { // 是数据集同步 + const panelShareTypeIds = [4, 5, 6] + // 说明是从消息通知跳转过来的 + if (panelShareTypeIds.includes(routerParam.msgType)) { // 是数据集同步 if (routerParam.sourceParam) { try { const msgParam = JSON.parse(routerParam.sourceParam) this.param = msgParam.tableId this.component = ViewTable this.$nextTick(() => { - this.$refs.dynamic_component.msg2Current(routerParam.sourceParam) + this.$refs.dynamic_component && this.$refs.dynamic_component.msg2Current && this.$refs.dynamic_component.msg2Current(routerParam.sourceParam) }) } catch (error) { console.error(error) diff --git a/frontend/src/views/msg/all.vue b/frontend/src/views/msg/all.vue index 6325a48b4c..803a24ba12 100644 --- a/frontend/src/views/msg/all.vue +++ b/frontend/src/views/msg/all.vue @@ -2,7 +2,7 @@ - {{ $t(item.typeName) }} + {{ $t('webmsg.' + item.typeName) }} - {{ $t(item.typeName) }} + {{ $t('webmsg.' + item.typeName) }} - + @@ -118,13 +118,13 @@ export default { }) }, getTypeName(value) { - return getTypeName(value) + return this.$t('webmsg.' + getTypeName(value)) }, typeChange(value) { this.search() }, toDetail(row) { - const param = { ...{ msgNotification: true, msgType: row.type, sourceParam: row.param }} + const param = { ...{ msgNotification: true, msgType: row.typeId, sourceParam: row.param }} this.$router.push({ name: row.router, params: param }) }, sortChange({ column, prop, order }) { diff --git a/frontend/src/views/msg/setting.vue b/frontend/src/views/msg/setting.vue index 124ee469fc..730cd3d858 100644 --- a/frontend/src/views/msg/setting.vue +++ b/frontend/src/views/msg/setting.vue @@ -4,7 +4,7 @@ {{ $t('webmsg.type') }} - {{ channel.channelName }} + {{ $t(channel.channelName) }} @@ -18,7 +18,7 @@ > - + {{ $t('webmsg.' + data.name) }}