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
转载时须注明出处及本声明