踩坑记录:消息推送已读未读

一、需求

最近工作中遇到了一个坑,在次记录一下。

社区管理员在后台发布一条社区公告,手机端该社区下的所有居民都可以收到这条公告,并且消息有已读未读状态。

二、分析

这个需求看起来很简单,无非就是后台发布完公告之后,同时在消息表里添加一条记录,移动端通过社区去查询到此条公告,给用户展示即可。

最初的设计是这样的,发送消息使用MQ异步发送,消息表中新增一个消息类型字段和接收的ID字段,消息类型分为角色、用户、小区、社区四种类型。如果消息发送的用户数不庞大,则类型使用用户发送,查询出要发送的所有用户ID,向消息表中添加多条记录即可;如果发送的用户数过于庞大(比如社区下的所有居民),显然这种方式就不合理了,这个时候就需要通过社区发送,将社区ID作为接收的ID,在消息表中最终只需要添加一条记录即可。

具体的表字段如下:

CREATE TABLE `basic_remind` (
  `ID` bigint(20) NOT NULL COMMENT '主键ID',
  `COMMUNITY_ID` bigint(20) DEFAULT NULL COMMENT '社区ID',
  `RESOURCES_ID` bigint(20) DEFAULT NULL COMMENT '资源ID',
  `TITLE_` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '消息标题',
  `CONTENT_` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '消息内容',
  `ACCOUNT_TYPE` varchar(5) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '消息接收类型(角色、用户、小区、社区)',
  `ACCOUNT_ID` bigint(20) DEFAULT NULL COMMENT '接收id',
  `TRIGGER_TIME` datetime DEFAULT NULL COMMENT '提醒时间',
  `STATUS_` varchar(2) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '状态(0-未读 1-已读)',
  `MSG_SCENE_TYPE` char(8) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '应用场景',
  `MSG_CHANNEL_TYPE` char(8) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '消息渠道(web端、C端)',
  `TEMPLATE_CODE` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '模板编码-由MSG_SCENE_TYPE、MSG_BUS_TYPE、MSG_TYPE、CHANNEL_TYPE组合而成',
  `READ_PERSON_IDS` json DEFAULT NULL COMMENT '已读人id(类型为社区或小区时使用)',
  `IS_DELETE` tinyint(1) DEFAULT '0' COMMENT '状态:0-正常,1-删除',
  `SEQ_NO` int(11) NOT NULL DEFAULT '0' COMMENT '排序号',
  `CREATE_DATE` datetime DEFAULT NULL COMMENT '创建时间',
  `CREATE_USER_ID` bigint(20) NOT NULL COMMENT '创建者',
  KEY `remind_account_id_index` (`ACCOUNT_ID`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='消息提醒表';

三、发现问题

到目前为止,已经实现了消息发送和展示的功能。但具体的业务中每条消息是有已读和未读的状态的,也就是说,用户点进消息详情,这条消息是要变为已读的。

回想上面的方案,虽然表中设计了阅读状态字段,但当消息不是按用户ID发送的时候,比如按社区发送,在消息表中是只有一条消息的,也就是说,一旦这个社区下任何一个居民阅读了这条消息,状态字段就会修改为已读,这就导致社区下其他居民看到这条消息的状态也是已读。

四、解决问题

最终的解决方案是:当消息类型不是用户时,使用MySQLJSON字段,去存储已阅读此消息的用户ID。当用户阅读此消息时,将用户ID作为数组,存入此字段,查询时使用JSON_CONTAINS()看当前用户ID是否在此数组中,在的话表示已读,否则未读。

mybatis代码片段如下:

在这里插入图片描述
问题解决!!

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一支帆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值