红点功能设计与实现

1,说明

互联网产品,最常见的一个功能就是红点。下面举一个简单需求场景:

  • 某个产品很多订阅者(即用户),后台维护有很多内容。
  • 后台新增或编辑某个内容,所有订阅者打开这个页面都会看到红点。
  • 某个订阅者点击红点后红点消失,其他订阅者没有点击过还会有红点。
  • 后台再次新增内容,所有订阅者都会再次看到红点。

现在我们做一个简单的红点微服务。

2,这个需求怎么实现

2.1 数据库设计

2.1.1 外部表引用说明:用户表和内容表

这俩表不属于红点微服务,简单起见就给出最小可行性定义:

create table user (
    id int unsigned not null AUTO_INCREMENT default 0 comment '主键id';
    status tinyint unsigned not null default 1 comment '数据状态:1正常/0软删除标示';
    update_time datetime not null default CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP comment '更新时间',
    create_time datetime not null default CURRENT_TIMESTAMP comment '创建时间',
    PRIMARY KEY (`id`),
)ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';

create table content (
    id int unsigned not null AUTO_INCREMENT default 0 comment '主键id';
    status tinyint unsigned not null default 1 comment '数据状态:1正常/0软删除标示';
    update_time datetime not null default CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP comment '更新时间',
    create_time datetime not null default CURRENT_TIMESTAMP comment '创建时间',
    PRIMARY KEY (`id`),
)ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='内容表';

2.1.2 微服务表设计

只需要定义一个用户阅读记录表,记录下阅读某个内容的时间。

create table user_read_record (
    id int unsigned not null AUTO_INCREMENT default 0 comment '主键id';
    user_id int unsigned not null default 0 comment '用户uid';
    content_id int unsigned not null default 0 comment '内容id';
    last_read_time datetime not null default CURRENT_TIMESTAMP comment '最后阅读时间',
    status tinyint unsigned not null default 1 comment '数据状态:1正常/0软删除标示';
    update_time datetime not null default CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP comment '更新时间',
    create_time datetime not null default CURRENT_TIMESTAMP comment '创建时间',
    PRIMARY KEY (`id`),
    index idx_uid (`user_id`),
    index idx_cid (`content_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户阅读内容记录表';

2.2 接口设计

红点微服务应当提供这几个能力:查询某个用户对某个内容是否应该看到红点,用户点击红点使其消失,编辑或新增内容用户重新看到红点。

2.2.1 查询红点

message GetRedDotRequest {
    int user_id=1;// 用户uid
    int content_id=2;// 内容id
};

message GetRedDotResponse {
    int need_show=1;  // 是否应该展示红点:1是/0不是
}

service RedDot {
  rpc GetRedDot(GetRedDotRequest) returns(GetRedDotResponse);  // 查询用户最后阅读时间,以及内容最新更新时间,对比后返回是和否应该展示红点
}

2.2.2 消除红点

message ClickRedDotRequest {
    int user_id=1;// 用户uid
    int content_id=2;// 内容id
};

message ClickRedDotResponse {
}

service RedDot {
  rpc ClickRedDot(ClickRedDotRequest) returns(ClickRedDotResponse);  // 插入或更新一下用户阅读内容记录表
}

2.2.3 重置红点

message ResetRedDotRequest {
    int content_id=1;// 内容id
};

message ResetRedDotResponse {
}

service RedDot {
  rpc ResetRedDot(ResetRedDotRequest) returns(ResetRedDotResponse);  // 调用内容微服务更新内容的updatetime
}

3,这样做有什么问题

按照上面的实现,一个简单的内容更新提醒微服务就完成了。

but,红点服务和内容服务,紧密耦合,有两个问题:

  • 红点微服务需要调用内容服务(比如查询/更新内容的更新时间)。
  • 通用性不强,如果想对别的什么非内容实体也添加红点逻辑或着弹框逻辑,就不适用了。

3.1 纠正

红点服务应当属于非业务相关的基础功能服务,应当与业务服务解藕,并进一步抽象提升通用能力。

3.2 数据库设计

红点微服务需要建立两个表:触发器事件用来记录某个抽象实体(内容/通知/弹框/浮层)最新的抽象事件触发记录,用户行为事件用来记录用户对某个触发器的最后一次行为记录(比如点击/阅读/展示)。

create table trigger_event (
    id int unsigned not null AUTO_INCREMENT default 0 comment '主键id';
    obj_type tinyint unsigned not null default 0 comment '实体对象类型:1内容,2通知,3,弹框,...';
    obj_id int unsigned not null default 0 comment '实体对象id';
    event_time datetime not null default CURRENT_TIMESTAMP comment '触发器事件发生时间',
    status tinyint unsigned not null default 1 comment '数据状态:1正常/0软删除标示';
    update_time datetime not null default CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP comment '更新时间',
    create_time datetime not null default CURRENT_TIMESTAMP comment '创建时间',
    PRIMARY KEY (`id`),
    index idx_objtype_objid (`obj_type`, `obj_id`)
)ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='触发器事件记录表';


create table user_event (
    id int unsigned not null AUTO_INCREMENT default 0 comment '主键id';
    user_id int unsigned not null default 0 comment '用户uid';
    trigger_id int unsigned not null default 0 comment '触发器事件id';
    event_time datetime not null default CURRENT_TIMESTAMP comment '用户行为事件发生时间',
    status tinyint unsigned not null default 1 comment '数据状态:1正常/0软删除标示';
    update_time datetime not null default CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP comment '更新时间',
    create_time datetime not null default CURRENT_TIMESTAMP comment '创建时间',
    PRIMARY KEY (`id`),
    index idx_uid (`user_id`),
    index idx_trigger_id (`trigger_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户行为事件记录表';


3.3 接口设计 

3.3.1 事件查询

message GetEventStatusRequest {
    int user_id=1;// 用户uid
    int obj_type=2;// 实体对象类型
    int obj_id=3;  // 实体对象id
};

message GetEventStatusResponse {
    int has_happened=1;  // 用户行为是否已经发生过

service Event {
  rpc GetEventStatus(GetEventStatusRequest) returns(GetEventStatusResponse);   // 查询触发器,根据触发器id查询用户行为,对比两者的事件发生时间
}

3.3.2 事件发生

message EventHappendRequest {
    int user_id=1;
    int obj_type=2;
    int obj_id=3;
};

message EventHappendResponse {
}

service Event {
  rpc EventHappend(EventHappendRequest) returns(EventHappendResponse);  // 查询触发器,根据uid和触发器id,更新或插入用户行为事件记录
}

3.3.3 触发器重置

message ResetTriggerRequest {
    int obj_type=1;
    int obj_id=2;
};

message ResetTriggerResponse {
}

service Event {
  rpc ResetTrigger(ResetTriggerRequest) returns(ResetTriggerResponse);  // 插入或更新触发器事件记录表
}

4. 结语

本质上,这是一个yes/no业务需求,常规有两种思路:有/没有分别对应yes/no,大于/小于分别对应yes/no。这两种思路属于经验之谈,难道一切内卷的尽头都是经验吗?

微服务应当尽可能抽象,且在实际项目中,应当划分业务层和基础层微服务。基础层就如本次提到的用户行为/触发器功能,可以用于红点,弹框,浮层,push等各种应用场景的实现。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Unity红点系统是一种常用的游戏UI设计,主要用于提醒玩家当前有新的任务、奖励或其他未读信息需要处理。下面是一个简单的Unity红点系统设计: 1. 定义红点控件:在UI界面中添加一个红点控件,通常是一个小圆点或小数字。该控件需要有一个唯一的名称,用于后续的操作。 2. 定义红点数据结构:为每个需要红点提醒的功能定义一个红点数据结构,包含以下信息: - 功能名称:用于标识该功能。 - 红点控件名称:与UI界面中的红点控件名称对应。 - 是否需要红点提醒:标识该功能是否需要红点提醒。 - 红点数量:如果需要显示数字红点,则需要记录具体的数量。 3. 定义红点管理类:创建一个红点管理类,用于管理所有的红点数据和UI界面上的红点控件。该类需要提供以下功能: - 添加红点数据:向红点管理类中添加新的红点数据。 - 更新红点状态:根据红点数据中的信息,更新UI界面上对应的红点控件状态。 - 监听红点变化:提供回调函数,当某个红点数据的状态发生变化时,通知相应的UI界面进行更新。 4. 使用红点系统:在需要使用红点系统的地方,调用红点管理类的方法添加红点数据和监听红点变化。当红点数据的状态发生变化时,红点管理类会自动更新UI界面上的红点控件状态。 通过以上步骤,就可以实现一个简单的Unity红点系统。当玩家有新的任务或奖励时,红点控件会自动提醒玩家,增强了游戏的交互性和用户体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值