智能H5打通了前端的可视化编辑器和后端的运营活动中台,方便用户在挑选组合业务组件,并填写必要的活动逻辑参数后,在生成页面数据的同时联动中台生成对应的活动服务。本文将聊一聊我们是如何将一个玩法复杂、交互多样的活动的核心业务逻辑拆解、抽象成一份有序清晰的数据结构,以及实现过程的细节。
一、 活动结构拆分
在此要介绍几个概念用以理解我们这套活动模型:
1. canvas: 活动整体的代名词,标识一个包含全局配置的step集合配置的整体。
1. step: 一个独立的事件流转配置,包含一套完整TCA事件处理的配置。
1. TCA事件流:基于Trigger+Condition=>Action的抽象模型,所有活动step的入口是特定的trigger,基于当前trigger判定可以使用的condition全集,通过condition判定配置,最后针对流量运营目的,配置相应触达手段Action,实时感知被运营对象。
1. Trigger:触发事件,例如用户登录、抽奖、做任务等
1. Condition:过滤条件,对某些既定事件的特性、条件判定,例如频率、用户画像等
1. Action:触达,能够实际对用户带来的价值体现,例如礼包码、研发礼包、实物奖励等
以一个常见的活动为例,其直接的逻辑关系图如下所示:
可以看出活动中尽管有多个交互事件,但事件之间均为并列关系,因此其整体结构可以抽象为一个活动是多个step事件的集合,如下图所示:
上图结构所对应的数据结构即为:
二、TCA数据结构定义
1. Trigger定义
```
{
"trigger_id": 1,
"name": "test",
"sign": "test",
"type": 1
}
```
| **参数** | **类型** | **必填** | **说明** |
| ---------- | ------ | ------ | -------------------- |
| trigger_id | int | 是 | |
| name | string | 是 | trigger名称 |
| sign | string | 是 | trigger唯一标识 |
| type | int | 是 | 类型,1实时事件,2异步事件,3定时事件 |
2. Condition定义
```
{
"condition_id": 1,
"name": "test",
"sign": "test",
"config_sign": "test",
"operator": [
"in",
"elt",
"eqt"
],
"value_list": [
{
"operator": "in",
"value": "1,2,3"
}
]
}
```
| **参数** | **类型** | **必填** | **说明** |
| ------------- | ------ | ------ | --------------------- |
| condition_id | int | 是 | |
| name | string | 是 | condition名称 |
| sign | string | 是 | condition唯一标识 |
| config_sign | string | 是 | 配置标识,配置下发时的获取链接或参数 |
| operator | string | 是 | condition可以操作的操作符标识列表 |
| value_list | array | 是 | condition的操作符和赋值列表 |
| | – operator | string | 是 | 操作符标识 |
| | – value | string | 是 | condition值 |
其中操作符operator的取值参考列表如下:
| **标识** | **名称** | **说明** |
| ------- | ------ | --------------- |
| in | 包含 | 类似于sql中的in |
| not_in | 不包含 | 类似于sql中的not in |
| eq | 等于 | 类似于sql中的= |
| neq | 不等于 | 类似于sql中的<> |
| gt | 大于 | 类似于sql中的> |
| egt | 大于等于 | 类似于sql中的>= |
| lt | 小于 | 类似于sql中的< |
| elt | 小于等于 | 类似于sql中的<= |
| between | 区间 | 类似于sql中的between |
3. Action定义
```
{
"action_id": 1,
"name": "发礼包",
"sign": "send_prize",
"type": 1,
"config_info": {
"prizeid": "",
"prizecont": ""
}
}
```
| **参数** | **类型** | **必填** | **说明** |
| ----------- | ------ | ------ | ----------------------------------------------- |
| action_id | int | 是 | |
| name | string | 是 | action名称 |
| sign | string | 是 | action唯一标识 |
| type | int | 是 | 类型,1普通action,2分层action |
| config_info | object | 是 | action所需配置参数 ,type=1时为对象,type=2时为数组(level为层级标准) |
三、 数据结构解析
最终,一个完整的活动逻辑可以映射成如下所示的一份JSON数据:
{
'id': '',
'name': '测试的H5项目',
'description': '测试',
'begin_time': '',
'end_time': '',
'tgid': [],
'pgid': [],
'gid': [],
'dgid': [],
'pid': [],
'uname': '',
'notify_to': '22',
'crowd': {},
'account_type': 'uid',
'weixin': {},
'join_dimension': {},
'assets_share_dimension': 'uid',
'init_task': [],
'frontend': {},
'lottery': {},
'task_list': [],
'status': 1
}
这份数据可以分为两大类:
-
活动全局配置:基于TCA事件流上层,全局的配置项,对整个活动负责,既可以描述活动的基础要素,包括名称、描述、时间、状态等,又可以限定活动的游戏范围、权益维度、人群限制等。
-
Step事件集合配置
-
lottery——抽奖事件流配置,用以确定活动中抽奖模块的抽奖策略、奖品列表、中奖策略、兜底设置等逻辑,从而在后台生成相应的奖池服务和配置文件。
'lottery': { 'lottery_type': 'no', 'strategy_type': 'simple', 'strategy': { // 抽奖策略限制 'win_strategy': {}, 'lottery_strategy': {} }, 'prize_list': [], // 奖品列表 'frontend': {}, 'condition_list': [ // 频次控制 { 'sign': 'total_times', 'value_list': [{ 'operator': 'eq', 'value': [1, 0] }], 'mismatch_tip': '今日抽奖次数已达上限' } ] } -
task_list——任务事件流配置集合,遵循TCA事件流模型,明确规定各任务事件的触发、条件和触达三个要素,用以在后台生成对应的任务服务。
'task_list': [{ 'name': 'XXX任务', 'description': '', 'trigger': '', 'type': '', 'index': '', 'is_show_status': 'Y', 'frontend': {}, 'condition_list': [ { 'sign': 'total_times', 'value_list': [{ 'operator': 'eq', 'value': [] }], 'mismatch_tip': '' } ], 'action_list': [] }]
四、前端实现
-
前端数据管理
本项目使用vue-x实现数据管理,初始值定义如上一节所示。
-
数据配置填充
由于设计初衷是让用户在拉取、配置组件的过程中完成活动逻辑的组合,故而该步骤与智能H5组件的选取和编辑深度绑定:
- 考虑到登录组件的全局性和必备性,在引入登录组件时即初始化活动逻辑数据,并在登录组件的编辑面板中完成全局配置参数的填充;
- 在引入抽奖类型组件时初始化抽奖逻辑数据,并在抽奖组件的编辑面板中完成抽奖逻辑参数的填充;
- 在引入任务类型组件时初始化抽奖逻辑数据,并在任务组件的编辑面板中完成抽奖逻辑参数的填充。
-
数据校验和保存
活动逻辑数据配置完成后,在提交数据生成活动前,需进行前端校验并给出不符合要求的指引提示。包括但不限于:
- 存在字段缺失
- 奖品列表中存在重复奖品
- 奖品列表中各奖品中奖概率总和不等于100%
通过校验后的数据可以通过接口提交到后端数据库存档。
-
远程数据拉取
在H5编辑页面的created生命周期内,根据活动唯一标识canvas_id通过后端接口获取到最新的活动逻辑数据,并更新页面活动数据和各相关组件中的配置参数。