多数的移动端APP都会有做任务领取奖励的功能模块,这类需求的目的是培养用户使用习惯,提升用户活跃性,用户完成任务获得积分奖励,通过积分兑换商品或者充值话费,微信体现等。
拟定需求场景(如图↓),概要:APP底部导航中新增小任务Tab,点击Tab可查看任务完成进度和领取情况,点击去完成跳转到做任务的业务界面,当用户完成任务并且满足领取条件的时候,任务Tab需要红点提醒用户当前有奖励可领取,用户领取后并且当前没有待领取奖励小红点消失,任务完成进度和领取状态仅保持当天,隔天刷新。
在开发前需要对需求进行整理,对细节进行确认,然后设计解决方案,预估开发时间,这里将对于业务中核心的内容进行梳理:
用户想要完成任务,需要去操作其他业务功能,如:评论成功后需要完成每日评论任务,关注主题后完成关注新手任务,这里就涉及核心问题,任务需要依赖于其他业务
为了保障后续拓展性,任务需要支持后台管理,配置任务名,描述,任务类型(每日,新手,活动),完成次数,奖励积分数量,去完成跳转uri 等
用户完成任务后不用自动领取奖励,需要进入到任务列表点击领取操作,可领取时导航Tab需要小红点提醒,和产品确认任务的完成和提醒的用户体验 可以接受短时间延迟
用户多次操作业务,或者出现重复操作(恶意并发请求刷积分),保证任务只能完成一次并且只能领取一次奖励,需要保证幂等性
事件
在实现方案上,采用异步消耗队列的方式,依赖业务接口埋入事件上报,将用户成功操作业务的任务事件上报到队里中,然后开发消息消耗的脚本程序,对消息中用户触发的任务事件进行业务逻辑处理和DB操作,更新用户任务进度和可领取状态,响应给用户(完成任务红点提醒),设计图:
表结构:
-- 任务表 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 组合唯一约束索引
幂等性
管理后台:
产品在规划需求的时候会设计出相关后台,但是不一定设计的合理,所以这里需要根据确认的解决方案协助产品对于管理后台进行调整,保障后续的拓展性
代码层面:
谈近一年的感悟,近一年参与了新APP项目的开发,从0开始搭建项目,看着DAU一点点儿的涨起来,还是挺有成就感的。
角色上产生了变化,现在感觉自己更像是一个项目的参与者,而不是任务的执行人,完成业务开发的同时也会对产品上有根深了解。
空闲时间也会对竞品调研以及用户使用意见或者问题进行跟进,站在用户角度提供产品上的一些建议。
后续会把新项目开发过程中遇到问题或者常见的业务场景下的解决方案进行梳理出来进行博文分享。
首发于Github : 🌱《大话WEB开发》,WEB开发相关经验总结分享,欢迎大家Star一波,后续想看不迷路 🌈
发布时间:2020-04-06