大话业务场景与解决方案-做任务

大话业务场景与解决方案-做任务

背景

多数的移动端APP都会有做任务领取奖励的功能模块,这类需求的目的是培养用户使用习惯,提升用户活跃性,用户完成任务获得积分奖励,通过积分兑换商品或者充值话费,微信体现等。

拟定需求场景(如图↓),概要:APP底部导航中新增小任务Tab,点击Tab可查看任务完成进度和领取情况,点击去完成跳转到做任务的业务界面,当用户完成任务并且满足领取条件的时候,任务Tab需要红点提醒用户当前有奖励可领取,用户领取后并且当前没有待领取奖励小红点消失,任务完成进度和领取状态仅保持当天,隔天刷新。

任务需求

业务分析

在开发前需要对需求进行整理,对细节进行确认,然后设计解决方案,预估开发时间,这里将对于业务中核心的内容进行梳理:

  1. 用户想要完成任务,需要去操作其他业务功能,如:评论成功后需要完成每日评论任务,关注主题后完成关注新手任务,这里就涉及核心问题,任务需要依赖于其他业务

  2. 为了保障后续拓展性,任务需要支持后台管理,配置任务名,描述,任务类型(每日,新手,活动),完成次数,奖励积分数量,去完成跳转uri 等

  3. 用户完成任务后不用自动领取奖励,需要进入到任务列表点击领取操作,可领取时导航Tab需要小红点提醒,和产品确认任务的完成和提醒的用户体验 可以接受短时间延迟

  4. 用户多次操作业务,或者出现重复操作(恶意并发请求刷积分),保证任务只能完成一次并且只能领取一次奖励,需要保证幂等性


方案设计

核心目标:
  1. 任务依赖其他业务,需要进行解耦,不影响其他业务的功能和性能
  2. 设计后台可管理,便于后续拓展
  3. 抽象任务模块,代码抽象开发
  4. 完成任务和领取需要保证幂等性
  5. 高可用
名词定义:

事件

  • 任务中涉及依赖其他业务,这里需要抽象出一个概念,用户通过操作业务,完成任务的这个操作,我们把这个过程定义为用户完成任务事件触发完成,如:评论事件,点赞事件,关注事件,等
解决方案:

在实现方案上,采用异步消耗队列的方式,依赖业务接口埋入事件上报,将用户成功操作业务的任务事件上报到队里中,然后开发消息消耗的脚本程序,对消息中用户触发的任务事件进行业务逻辑处理和DB操作,更新用户任务进度和可领取状态,响应给用户(完成任务红点提醒),设计图:


任务功能设计图
  • 依赖业务解耦
    • 依赖业务将操作成功用户的任务事件上报到消息队列,然后程序进行异步消耗
    • 方案解决了依赖业务之间的强耦合,并且基本不影响现有依赖业务的接口性能
  • 高可用:
    • 通过调度系统启动多进程对队列进行消耗
      • 进程守护系统,守护进程保活,奔溃重启,可对执行日志进行记录与查看
      • 如: gocron
    • 消息队列监控,无法及时消耗进行预警,保障即时性,避免长时间的延迟
      • rabbitmq
      • redis list
      • ... ...
    • 容错与补偿
      • 队列消耗失败需要进行记录,并可根据业务场景,通过另外程序进行补充处理
      • 用户操作业务上报任务事件不限制次数,以免用户没完成任务,允许用户重新尝试去做任务,程序消耗需要控制任务只能完成一次

表结构:

-- 任务表
CREATE TABLE `task` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增',
  `icon` varchar(300) NOT NULL DEFAULT '' COMMENT '图标',
  `title` varchar(30) NOT NULL DEFAULT '' COMMENT '任务标题',
  `type` tinyint(4) NOT NULL DEFAULT '0' COMMENT '任务类型,新手任务=1,每日任务=2',
  `event` int(11) NOT NULL DEFAULT '0' COMMENT '事件',
  `des` varchar(30) NOT NULL DEFAULT '' COMMENT '任务描述',
  `target_num` int(11) NOT NULL DEFAULT '0' COMMENT '目标数量',
  `points` int(11) NOT NULL DEFAULT '0' COMMENT '金币',
  `sort` int(11) NOT NULL DEFAULT '0' COMMENT '排序',
  `status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '状态 0=下线,1=上线,-1=删除',
  `app_version` varchar(15) NOT NULL DEFAULT '' COMMENT 'app版本号',
  `app_version_compare` varchar(10) NOT NULL DEFAULT '' COMMENT 'app版本号比较运算符',
  `operator` varchar(10) NOT NULL DEFAULT '' COMMENT '操作人',
  `jump_uri` varchar(300) NOT NULL DEFAULT '' COMMENT '跳转协议',
  `create_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '更新时间',
  `event_begin` timestamp NOT NULL DEFAULT '1970-01-02 00:00:00' COMMENT '事件开始时间',
  `event_end` timestamp NOT NULL DEFAULT '1970-01-02 00:00:00' COMMENT '事件结束时间',
  `task_begin` timestamp NOT NULL DEFAULT '1970-01-02 00:00:00' COMMENT '任务开始时间',
  `task_end` timestamp NOT NULL DEFAULT '1970-01-02 00:00:00' COMMENT '任务结束时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- 用户任务情况表
CREATE TABLE `user_task_case` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户任务情况',
  `user_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '用户ID',
  `task_id` int(11) NOT NULL DEFAULT '0' COMMENT '任务id',
  `task_type` int(11) NOT NULL DEFAULT '0' COMMENT '任务类型',
  `event` int(11) NOT NULL DEFAULT '0' COMMENT '事件',
  `task_uni` varchar(30) NOT NULL DEFAULT '' COMMENT '任务唯一标识(唯一约束) ',
  `target_num` int(11) NOT NULL DEFAULT '0' COMMENT '目标数量',
  `finish_num` int(11) NOT NULL DEFAULT '0' COMMENT '完成数量',
  `points` int(11) NOT NULL DEFAULT '0' COMMENT '可领取金币数量',
  `status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '状态 0=待完成,1=待领取,2=已经领取',
  `finish_at` timestamp NOT NULL DEFAULT '1970-01-02 00:00:00' COMMENT '完成任务时间',
  `get_at` timestamp NOT NULL DEFAULT '1970-01-02 00:00:00' COMMENT '领取时间',
  `create_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uni_user_id_task_uni` (`user_id`,`task_uni`) USING BTREE,
) ENGINE=InnoDB  DEFAULT CHARSET=utf8mb4 COMMENT='用户任务情况表';

更新语句:

-- 更新领取状态,注意:WHERE条件,强校验
UPDATE user_task_case 
SET  `status`=2,finish_at=CURRENT_TIMESTAMP
WHERE id=:id AND user_id=:user_id AND `status`=1 AND finish_num>=target_num

表重点字段说明:

  • task_uni
    • 任务唯一标识
  • user_id和task_uni 组合唯一约束索引
    • 每日任务:
      • 任务id_任务类型_日期(task_id_type_date)
    • 默认都是只做一次(新手任务/活动任务):
      • 任务id(task_id)
  • 幂等性
    • user_task_case 表中 user_id和task_uni 组合唯一约束索引,通过mysql的唯一约束,保证了多进程并行消耗事件队列的情况下,每日任务和一次性任务不能重复INSERT
    • 通过UPDATE的WHERE条件校验保障领取的幂等性

管理后台:

产品在规划需求的时候会设计出相关后台,但是不一定设计的合理,所以这里需要根据确认的解决方案协助产品对于管理后台进行调整,保障后续的拓展性

任务管理

任务添加

代码层面:

  • 面向抽象开发,合理使用设计模式,便于后续的拓展

话外篇:

谈近一年的感悟,近一年参与了新APP项目的开发,从0开始搭建项目,看着DAU一点点儿的涨起来,还是挺有成就感的。

角色上产生了变化,现在感觉自己更像是一个项目的参与者,而不是任务的执行人,完成业务开发的同时也会对产品上有根深了解。

空闲时间也会对竞品调研以及用户使用意见或者问题进行跟进,站在用户角度提供产品上的一些建议。

后续会把新项目开发过程中遇到问题或者常见的业务场景下的解决方案进行梳理出来进行博文分享。


首发于Github : 🌱《大话WEB开发》,WEB开发相关经验总结分享,欢迎大家Star一波,后续想看不迷路 🌈

发布时间:2020-04-06

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345

推荐阅读更多精彩内容