前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >用户成长体系之任务系统架构设计

用户成长体系之任务系统架构设计

作者头像
西柚dzh
发布2022-06-09 15:33:37
2.8K1
发布2022-06-09 15:33:37
举报
文章被收录于专栏:dcmickey小站dcmickey小站

1、引言

搭建用户成长体系的核心目的在于用户的「 留存」和「 促活」,对平台来说,合理的用户成长体系可以提升用户粘性,反之则会让用户觉得繁琐累赘,日渐失去活跃度。本文讲述的是用户成长体系中的核心模块《任务系统》。

2、 系统概述

任务中心分为五大类:每日任务、成长任务、基础任务、试用延期任务、试用达标任务(转正),支持横向扩展 每月任务、新手任务等等。其实每日任务应该叫周期任务,然后再细分成每日、每月等,但是考虑到以后统计查询的方便,故没有设计成二级划分。

2.1、主要功能描述

任务配置设计、用户任务领取、 任务记录进度推送(发送方)、任务记录进度订阅(接收方)、任务记录进度更新和奖励发放、试用期任务清算job。

3、系统结构设计

3.1、用户领取常规任务(非试用期任务)

流程图,本文是登录后任务自动领取,因此放在登录入口里

用户领取任务分为三种情况:

1.领取每日任务:每日任务需要有每日快照,这样配置修改不会影响当天做任务的用户,配置通过redis缓存到当天24点前过期控制。快照的触发由当天第一个领取用户的幸运儿完成。也就是说当天没人领取任务, 系统修改任务配置也是会实时生效的。

2.领取成长任务:成长任务是实时响应的,修改配置会即可生效。领取过一次就一直在了,不会重复领取。不过成长任务的记录是以子任务形式触发的。当第一次领取成长任务,是记录的第一个里程碑指标的任务记录,系统触发任务完成后,会判断该里程碑后面是否有下一个节点了,有的话就新增一条新的子任务记录给用户去完成。当所有节点都完成后,任务停留在最后一个节点上。

每天用户登录的时候判断成长任务是否领取的条件是:有没有领取过这个任务,只要领取过不管是第几个节点的子任务,都算领取了。

考虑到成长任务可能会存在用户全部完成所有里程碑,然后某天产品配置了一个新的里程碑,这时候就需要在登陆上做判断:逻辑是找到当前成长任务记录的最后一个指标值A,如果A已完成并领取了奖励,就判断是否小于该任务配置的最后一个里程碑的指标值B,如果小于 就创建一个新的子任务记录(指标值为配置中大于A的最近一个指标值C,C不一定是B)

3.领取基础任务: 这个就比较简单了,只要领取过该任务,就不能领取了。记录里没有的任务才会领取。

3.2、用户领取试用期任务

用户开通账户时,调用接口CreateTrialRecords来创建试用期任务记录,分为试用达标任务和试用延期任务。(试用期任务领取时会记下试用期截止日期(注意非任务截止日期,任务截止时间可能在试用期结束之前),清算试用任务job会每天0点1分跑试用期任务记录数据,更新试用期试用结果)。

3.3、任务进度更新

流程图(已订单数量达标任务为例):

1.用户下单,订单推送一个mq给任务中心,任务中心处理,根据任务指标类型,找到符合条件的每日任务/成长任务/基础任务,判断完成情况,更新任务进度并发放奖励,如果是成长任务,会在这里创建下一个里程碑的任务记录。

2.推送mq的结构如下:

代码语言:javascript
复制
    /// <summary>
    /// MQ更新任务消息体
    /// </summary>
    public class UpsetMissionRecordRequest : BaseRequestSafety
    {
        /// <summary>
        /// 会员id
        /// </summary>
        public long MemberId { get; set; }
        /// <summary>
        /// 业务端唯一请求标识(标识一次请求)
        /// </summary>
        public string TransGuid { get; set; }
        /// <summary>
        /// 是否是成长任务轮询
        /// </summary>
        public bool IsLoop { get; set; } = false;
        /// <summary>
        /// 信号量集合
        /// </summary>
        public List<SignalInfo> SignalDataList { get; set; }

    }

SignalInfo实体

代码语言:javascript
复制
    /// <summary>
    /// 信号量信息
    /// </summary>
    public class SignalInfo
    {
        /// <summary>
        /// 指标类型
        /// </summary>
        public MissionTarget TargetId { get; set; }

        /// <summary>
        /// 当前指标本次增益的数值 比如下了一单付款16.88元, 就传16.88
        /// 当bool类型的返回值时,返回1为成功, 其他为失败。比如绑定手机号 1代表绑定成功
        /// 比如访客数 就传访客id
        /// </summary>
        public decimal IncrementValue { get; set; }
    }

3.任务进度推送(发送)和订阅(接收)方法

继承接口IMissionEventRegister

实现IMissionEventRegister.SignalSubscribe方法:订阅任务进度并处理

实现IMissionEventRegister.GetMissionResult方法:返回这个任务指标对应的最新进度值(即SignalSubscribe方法产生的结论)

代码语言:javascript
复制
     /// <summary>
    /// Todo  确保子类单例
    /// </summary>
    public interface IMissionEventRegister
    {
        /// <summary>
        /// 返回任务最新进度值decimal的方法。
        /// 当bool类型的返回值时,返回1为成功, 其他为失败。
        /// 比如绑定手机号 1代表绑定成功
        /// 比如当前下单量为10,则返回10,后面增加到20了,则返回20,而不是增加的区间值
        /// </summary>
        /// <param name="request">请求调解</param>
        /// <returns></returns>
        ResultMessage<decimal> GetMissionResult(MissionCurrentDataRequest request);

        /// <summary>
        /// 信号量订阅服务
        /// 处理业务发送过来的信号转换成任务中心的数据
        /// </summary>
        /// <param name="memberId"></param>
        /// <param name="incrementValue">增量值</param>
        void SignalSubscribe(long memberId, decimal incrementValue);

    }
代码语言:javascript
复制
     /// <summary>
    /// 
    /// </summary>
    public class MissionCurrentDataRequest
    {
        /// <summary>
        /// 会员id
        /// </summary>
        public long MemberId { get; set; }
        /// <summary>
        /// 任务分类
        /// </summary>
        public MissionClassify MissionClassifyId { get; set; }

        /// <summary>
        /// 任务指标
        /// </summary>
        public MissionTarget MissionTargetId { get; set; }
        /// <summary>
        /// 任务结算周期
        /// </summary>
        public SettleCycle SettleCycle { get; set; }
    }

事件注册入口,采用简单工厂模式(MissionEventRegisterFactory的GetInstance):

代码语言:javascript
复制
    /// <summary>
    /// 任务事件注册服务入口
    /// </summary>
    public class MissionEventRegisterFactory
    {

        #region 任务事件注册
        /// <summary>
        /// 
        /// </summary>
        /// <param name="missionTarget"></param>
        /// <returns></returns>
        public static IMissionEventRegister GetInstance(MissionTarget missionTarget)
        {
            IMissionEventRegister _instance = null;
            switch (missionTarget)
            {
                case MissionTarget.BindPhone: _instance = null; break;
                case MissionTarget.Visitors: _instance = new VisitiorCountRegister(); break;
                case MissionTarget.EnteredCommission: _instance = new EnterCommisitionRegister(); break;
                case MissionTarget.NetBills: _instance = new NetBillRegister(); break;
                case MissionTarget.PayedOrders: _instance = new PayOrdersRegister(); break;
                case MissionTarget.PayMBills: _instance = new PayBillRegister(); break;
                case MissionTarget.ShareCount: _instance = new ShareCountRegister(); break;
                case MissionTarget.TaobaoAuthorize: _instance = new TaobaoAuthRegister(); break;
                case MissionTarget.OrderPeoples: _instance = new OrderPeopleRegister(); break;
                case MissionTarget.PredictCommission: _instance = new PredictCommissionRegister(); break;
                default:
                    _instance = null; break;
            }
            return _instance;
        }
        #endregion
    }

由于任务功能上线前,有的指标其实用户已经完成,这时候就需要在领取任务的逻辑后调用发送更新任务信号量的接口。

3.4、试用期任务清算job

每天0点1分跑试用期任务记录数据,将到期的任务依次判断是否达标,则转正;其次判断是否延期,则试用期延期一个月,并领取下一轮的试用期任务;否则试用期结束不通过。更新试用期任务记录为已清算。

4、程序调用说明:

4.1、领取常规任务接口(会员登录时领取任务):

方法名:MemberLoginFilterAttribute类的OnActionExecutedAsync方法 (核心方法是CreateMissionRecords接口创建任务)

public override Task OnActionExecutedAsync(HttpActionExecutedContext actionExecutedContext, CancellationToken cancellationToken)

4.2、试用期任务领取接口:

方法名:CreateTrialRecords

4.3、业务发送信号量更新任务记录进度接口

方法名:UpsetMissionRecordMQProvider

public ResultMessage<bool> UpsetMissionRecordMQProvider(UpsetMissionRecordRequest request)

4.4、任务中心订阅信号量处理接口(需要实现接口)
方法名:IMissionEventRegister类的SignalSubscribe方法
处理信号为任务中心的需要的数据
4.5、任务中心实时获取任务进度情况接口(需要实现接口)
方法名:IMissionEventRegister类的GetMissionResult方法
4.6、注册任务模块接口
方法名:MissionEventRegisterFactory的GetInstance方法

注册任务模块实例

4.7、试用期任务清算job

方法名:SettleTrialMissionJob

配置页面设计

1.列表查询页面:

2.配置页面—基础任务

配置页面-每日任务

配置任务-成长任务:

配置页面-表单型任务(用户上传图片,后台审核图片的方式,或者其他表单型的)

配置页面:试用期延期任务、试用达标任务 (配置页面一致)

数据库设计

1.任务配置主表(每日任务、基础任务只用到这张表)

代码语言:javascript
复制
CREATE TABLE `TCDAILYSURPRISE`.`MissionConfig`  (
  `MCId` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `MCMissionClassifyId` int(11) NOT NULL DEFAULT 0 COMMENT '任务类别(每日、成长、基础)',
  `MCMissionName` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '任务名称',
  `MCDescription` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '任务简介',
  `MCIcon` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '任务图标',
  `MCTargetId` int(11) NOT NULL DEFAULT 0 COMMENT '任务指标Id(签到、订单数等)',
  `MCTargetName` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '任务指标名称(签到、订单数等)',
  `MCTargetValue` int(11) NOT NULL DEFAULT 0 COMMENT '指标值',
  `MCMoneyNumber` int(11) NOT NULL DEFAULT 0 COMMENT '奖励配置红包编号',
  `MCRewardValue` decimal(18, 2) NOT NULL DEFAULT 0.00 COMMENT '奖励值',
  `MCRuleExplain` varchar(300) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '任务规则说明(步骤描述)',
  `MCOfficialStory` varchar(300) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '任务推荐话术',
  `MCPhraseExplain` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '名词解释',
  `MCIsForm` int(11) NOT NULL DEFAULT 2 COMMENT '是否表单任务 1是 2不是 默认2',
  `MCIsAutoReceive` int(11) NOT NULL DEFAULT 0 COMMENT '任务是否自动领取 (1是 2否)',
  `MCIsManualAudit` int(11) NOT NULL DEFAULT 2 COMMENT '是否人工审核 1是 2否',
  `MCIsAutoReward` int(11) NOT NULL DEFAULT 0 COMMENT '是否自动发放奖励(1是 2否)',
  `MCSortBy` int(11) NOT NULL DEFAULT 0 COMMENT '排序字段(倒序模式)',
  `MCRowStatus` int(11) NOT NULL DEFAULT 1 COMMENT '有效性(1有效 2无效)',
  `MCCreateTime` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '创建时间',
  `MCCreateUser` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '创建人',
  `MCUpdateTime` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '修改时间',
  `MCUpdateUser` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '修改人',
  `MCProjectCode` int(11) NOT NULL DEFAULT 0 COMMENT '项目类型',
  `MCSettleCycle` int(11) NOT NULL DEFAULT 0 COMMENT '结算周期 1.当天 2.7天 3.31天 4.永久',
  PRIMARY KEY (`MCId`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 46 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '任务配置表' ROW_FORMAT = Compact;

2.任务配置明细表(成长任务用到)

代码语言:javascript
复制
CREATE TABLE `TCDAILYSURPRISE`.`MissionConfigDetail`  (
  `MCDId` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `MCDConfigId` bigint(20) NOT NULL DEFAULT 0 COMMENT '任务主键Id',
  `MCDTargetValue` int(11) NOT NULL DEFAULT 0 COMMENT '指标值',
  `MCDRewardValue` decimal(18, 2) NOT NULL DEFAULT 0.00 COMMENT '达标奖励值',
  `MCDRowStatus` int(11) NOT NULL DEFAULT 1 COMMENT '有效性 1有效 2无效',
  `MCDCreateTime` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '创建时间',
  `MCDCreateUser` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '创建人',
  `MCDUpdateTime` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '修改时间',
  `MCDUpdateUser` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '修改人',
  PRIMARY KEY (`MCDId`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 56 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '任务配置明细表' ROW_FORMAT = Compact;

3.用户记录表

代码语言:javascript
复制
CREATE TABLE `TCSURPRISEGAMELOG`.`MissionRecord`  (
  `MRId` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `MRConfigId` bigint(20) NOT NULL DEFAULT 0 COMMENT '任务配置表主键',
  `MRMIssionClassifyId` int(11) NOT NULL DEFAULT 0 COMMENT '任务类别(每日、成长、基础)',
  `MRMissionName` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '任务名称',
  `MRUserId` bigint(20) NOT NULL DEFAULT 0 COMMENT '用户Id',
  `MRNickName` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '用户昵称',
  `MRSOP` bigint(20) NOT NULL DEFAULT 0 COMMENT '归属SOP',
  `MRTargetId` int(11) NOT NULL DEFAULT 0 COMMENT '任务指标Id(字典值)',
  `MRTargetValue` int(11) NOT NULL DEFAULT 0 COMMENT '任务指标值',
  `MRCurrentValue` decimal(18, 2) NOT NULL DEFAULT 0.00 COMMENT '当前完成量',
  `MRRewardValue` decimal(18, 2) NOT NULL DEFAULT 0.00 COMMENT '奖励值',
  `MRFormValue1` varchar(300) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '用户录入信息1',
  `MRFormValue2` varchar(300) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '用户录入信息2',
  `MRFormValue3` varchar(300) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '用户录入信息3',
  `MRCreateTime` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '创建时间',
  `MRFinishTime` datetime(0) NOT NULL DEFAULT '1900-01-01 00:00:00' COMMENT '任务完成提交时间',
  `MRIsForm` int(11) NOT NULL DEFAULT 2 COMMENT '是否表单任务 1是 2否 默认2',
  `MRIsFinish` int(11) NOT NULL DEFAULT 0 COMMENT '任务完成情况 1已完成 2未完成 默认2',
  `MRIsManualAudit` int(11) NOT NULL DEFAULT 0 COMMENT '是否人工审核(1是 2否 默认0)',
  `MRAuditStatus` int(11) NOT NULL DEFAULT 0 COMMENT '审核状态(0默认 1待审核 2通过 3驳回)',
  `MRReceiveStatus` int(11) NOT NULL DEFAULT 0 COMMENT '奖励领取状态 1已领取 2未领取 默认',
  `MRReason` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '驳回原因',
  `MRRowStatus` int(11) NOT NULL DEFAULT 1 COMMENT '有效性 1有效 2无效',
  `MRUpdateTime` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '修改时间',
  `MRSettleCycle` int(11) NOT NULL DEFAULT 0 COMMENT '结算周期类型',
  `MRTrialTimes` int(11) NOT NULL DEFAULT 0 COMMENT '试用期第几次',
  `MRExpireTime` datetime(0) NOT NULL DEFAULT '1900-01-01 00:00:00' COMMENT '任务过期时间',
  `MRTrialDeadline` datetime(0) NOT NULL DEFAULT '1900-01-01 00:00:00' COMMENT '试用期到期时间(清算时间)',
  `MRIsSettleTrial` int(11) NOT NULL DEFAULT 2 COMMENT '试用期是否清算 1结算 2未结算',
  PRIMARY KEY (`MRId`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 823 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '用户任务记录表' ROW_FORMAT = Compact;

版权属于:dingzhenhua

本文链接:https://cloud.tencent.com/developer/article/2019121

转载时须注明出处及本声明

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-12-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、引言
  • 2、 系统概述
    • 2.1、主要功能描述
    • 3、系统结构设计
      • 3.1、用户领取常规任务(非试用期任务)
        • 3.2、用户领取试用期任务
          • 3.3、任务进度更新
            • 3.4、试用期任务清算job
            • 4、程序调用说明:
              • 4.1、领取常规任务接口(会员登录时领取任务):
                • 4.2、试用期任务领取接口:
                  • 4.3、业务发送信号量更新任务记录进度接口
                    • 4.4、任务中心订阅信号量处理接口(需要实现接口)
                      • 方法名:IMissionEventRegister类的SignalSubscribe方法
                        • 处理信号为任务中心的需要的数据
                          • 4.5、任务中心实时获取任务进度情况接口(需要实现接口)
                            • 方法名:IMissionEventRegister类的GetMissionResult方法
                              • 4.6、注册任务模块接口
                                • 方法名:MissionEventRegisterFactory的GetInstance方法
                                  • 4.7、试用期任务清算job
                                  • 配置页面设计
                                    • 1.列表查询页面:
                                    • 数据库设计
                                    领券
                                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档