活动运营自动化平台实践

人人贷活动运营平台,是一个由人人贷大前端团队进行开发和维护,并用于自动化、可视化构建人人贷常规活动的系统。本文将会分享"人人贷活动运营平台"的设计思想和部分技术实现,但愿对你们有所帮助。javascript

1、背景

人人贷前端团队在过去的几年里,接到了不少来自市场部门的活动开发需求,这些活动主要分为4大类:css

  • LP活动(Landing Page,引导页),用于新人注册的活动页面,基本都是一个注册框 + 若干产品卡
  • MGM活动(Members get member),用于好友间邀请拉新的活动页面,通常包括邀请记录,邀请排行,分享等功能
  • 常规活动,通常包括抽奖、产品卡、排行榜、分享等功能,用于促进销量
  • 特殊活动,通常是游戏页面,相同的形式基本只会使用一次

1.1 活动开发人力瓶颈和上线周期长

一个普通的活动(包括上述的LP活动、MGM活动、常规活动)开发时间得多久?html

正常状况下,一个涉及到H5和PC两端的简单活动,从产品提出需求开始,设计师须要2人*2天来完成设计工做,开发须要3人*2天(包括H五、PC端页面、后端接口开发、接口联调),测试须要2人*2天投入。前端

就这样,从需求提出到页面上线,须要一共投入14人*天的人力资源,得 7个工做日 才能完成。java

而遇到比较紧急的活动开发需求,上线周期须要压缩,你们都得加班来完成。node

另外,因为公司财务结算的特殊性,不少活动的开始时间通常都是凌晨,开发、测试人员须要确认活动在线上运行正常,才能下班。git

1.2 活动功能重复和反复修改

随着公司业务的发展,活动的开发需求愈来愈多。前端团队有三分之一的人力,长期投入在活动页面的开发中。github

事实上,我们大部分的普通活动,功能并不复杂,并且大部分的功能比较重复。web

这种功能重复性的页面开发,对于我的和团队的成长来讲,并无太多的价值。并且活动上线后,常常由于样式和文案的关系,须要修改代码,从新上线,致使团队成员广泛比较反感这种普通活动的开发。npm

期间,团队也提出过组件化开发的方式,试图将不一样的功能模块抽取出来,在不一样的活动页面上进行引用,以便节省开发时间。但因为设计方案的不肯定性,以及不一样开发人员参与,这种抽取的功能模块复用性不过高,效果不是特别理想。而且不能解决样式和文案修改,须要从新上线的问题。

总之,普通活动的特色是:页面功能大同小异、开发时间紧、下线快、技术成长低。

随着团队的技术体系日益成熟,咱们终于腾出精力,试图解决普通活动开发中各项痛点。

2、人人贷活动运营平台

早在十几年前,使用Dreamweaver就能可视化地搭建出前端静态页面。虽然Dreamweaver已经成为过去式,可是可视化搭建的思想,却被普遍使用。

咱们在调研业界经常使用解决方案中发现,不少公司都有本身的活动运营系统,可用来高效、可视化地配置活动,以及监控活动运营数据。咱们但愿采用这种活动页面可视化搭建的思想,由运营人员根据实际的运营需求,自行添加活动,并配置对应的活动页面。

运营平台

2.1 总体框架

首先,简单介绍下人人贷前端的开发模式。

随着 Node.js 的兴起,咱们从2016年开始,将原有基于 JSP 的前端开发模式,改形成使用 Node.js 作中间层,进行先后端分离的模式。

先后端分离

人人贷前端使用的就是图中所示的先后端分离的开发模式(图片来自Web 研发模式演变),这种开发模式下,先后端的职责清晰。对于前端来讲,两个UI层各司其职:Front-end UI layer 处理浏览器层的展示逻辑,Back-end UI layer 能够用来处理路由、模板、数据获取、cookie、服务器端渲染等。

在这种先后端开发模式下,整我的人贷活动运营平台的架构图以下:

总体架构图

整个运营平台系统分为四大块。

一、组件库。运营平台采用了业界通用的 组件化 方案,而且选用 React.js 做为组件的开发库。下面会详细介绍组件库的拆分和开发模式。

二、前端系统。整个运营平台包括 积木系统rrd-h5rrd-pc 三个前端系统。其中 积木系统 是运营建立、编辑、发布活动页面的系统,属于内部系统。而rrd-h5rrd-pc 属于面向用户的Back-end UI layer,它们是基于生成的活动配置数据,对活动页面进行渲染及提供异步接口,以供用户访问。

三、后端接口。在后台服务上,因为活动并非特别复杂,咱们有较大一部分接口,好比抽奖、记录收获地址,只是作一些简单的存储或者计算,就直接使用了Node.js实现,也就是上图中的node-market-service服务。而部分与公司主营业务相关的接口,好比投资返现这类,仍是直接使用后端提供的Java接口。

四、数据层。用于存储活动配置相关的数据以及部分运营数据。

2.2 组件库

咱们按照功能模块,将往期的活动页面拆分红了不一样的组件。

移动端的邀请好友页面 为例,这个页面就包括:图片组件(banner图)、活动规则组件、邀请记录组件、战队排行榜组件、平台增信组件和邀请好友按钮组件等。

组件拆分完成后,咱们就获得了一个组件库。

为了便于对组件库进行管理,咱们按照所属的平台,将组件库拆分为 jm-commonjm-mobilejm-pc 三类,分别对应两端公用组件、H5组件、PC端组件。

如上文所述,咱们的积木系统定位为 可视化编辑平台,在对组件进行配置后,须要在编辑页面实时展现。rrd-h5rrd-pc服务也须要根据页面的配置数据,对组件进行渲染。

这三个系统中都须要使用组件库,为了方便组件的开发以及预览,咱们将组件库的源码集成到了积木系统的代码仓库中。

积木系统经过项目代码中的组件库源码来加载组件库,当组件的代码有修改,积木系统能经过从新编译,刷新页面并预览到新的组件样式。

组件库还会经过开发环境判断,会自动在编辑系统中使用模拟数据,方便了组件开发时的测试。

为了方便进行版本管理和组件库接入,当组件开发完成后,咱们会将组件库发布在私有的npm仓库中,同时在rrd-h5rrd-pc中,更新对应的组件库版本号,就能加载到新的组件。

2.3 活动配置与页面配置

在积木系统中,须要先建立活动,而后才能建立该活动对应的移动端、PC端页面,而不是直接建立活动页面。

这是由于根据以往的运营经验,一个活动,是能够对应多个推广页面(至少是H5和PC端两个页面),而这些推广页面须要共享一些活动配置。

数据存储上看,咱们新建了 activitypagepage_record 三张表用于存储活动配置、页面配置和组件配置相关的数据。

  • activity 是活动配置表,负责记录活动名,活动的上下线时间,业务相关的活动配置以及公用活动配置等。其中公用组件配置,是指该活动下的页面,须要公用的组件配置项。好比领取优惠券组件,会将优惠券的金额、类型、批次等,放到公用组件配置中,这样能有效避免在多个页面的组件中分开进行配置时,配置出错或者不统一的状况。

  • page 是页面表。新建页面时,就会往该表中插入数据。信息会记录页面名,页面所属的活动id,页面所属的平台(移动端 or PC端),发布时间等。须要注意的是,该表不会记录具体的组件配置数据。这是为了将页面数据与组件配置数据分离。可是页面表会记录线上页面使用的 online_record_id ,用来关联查询线上页面使用的组件数据。每次发布页面后,咱们会将最新的 online_record_id 更新到对应页面数据中。

  • page_record 是组件配置记录表,主要负责记录所属的页面id,具体的组件数据,编辑人,发布时间等。在积木系统的活动页面编辑中,每一次保存页面,都会在这个表中插入一条数据,这样方便查找编辑记录,同时也方便回滚。

2.4 组件的配置与配置数据解析

按照咱们规划的操做流程,运营同窗在 积木系统 中新增活动,建立页面后,须要给页面添加组件,修改组件配置,配置完成后,保存页面中的组件配置,最后发布页面。

不一样的组件,须要用到不一样的配置项。那么咱们该怎么在积木系统中,给不一样的组件提供不一样的配置项呢?

首先得介绍一下组件的开发模式。

在开发组件前,咱们会提早和产品同事确认该组件所须要的配置,包括组件样式配置、组件文案配置以及组件业务属性配置等。

开发组件时,咱们通常会添加三个文件。以图片组件为例,咱们添加image.jsximage.scssspec.js,分别是组件的具体实现代码、组件样式文件、组件的配置文件数据。

在配置某个组件时,积木系统经过读取该组件下的spec.js文件,提供不一样的配置弹窗。

如下是图片组件的spec.js文件内容:

import Image from './image.js';

export default {
    Component: Image,
    type: Image.type,
    _name: '图片',	//组件列表使用的名称
    _platform: 'common', //该组件属于公共组件
    _acceptChild: false, //是否容许嵌套其余组件
    _dataSchema: {  //组件配置项须要的JSON Schema
        type: "object",
        required: ["src"],
        properties: {
            src: {
                type: "string",
                title: "请填写图片地址",
            },
            alt: {
                type: "string",
                title: "图片没法加载时的文案",
            },
            title: {
                type: "string",
                title: "鼠标移到图片上的提示文案",
            }
        }
    },
    data: {  //默认数据
        src: 'https://www.we.com/cms/5864b0d6a24d131067ef7956/jimu/default-img.jpg',
        alt: '',
        title: ''
    },
    style: {  //样式配置项
        width: '',
        height: '',
        position: 'static',
        display: 'block',
        margin: '',
        padding: ''
    },
    _defaultStyle: {  //默认样式
        mobile: {
            width: '100%'
        },
        pc: {
            maxWidth: '1080px',
            height: 'auto'
        }
    }
}
复制代码

以上的配置文件中,有部分属性是如下划线_开头,这部分属性属于积木系统专用的属性,会在给前端页面传递组件配置数据时,过滤掉这些专属属性,避免配置数据过多,也避免部份内部数据泄露。

一个活动页面,通常会添加多个组件,并且组件间还可能存在嵌套关系,页面上的组件配置数据如何组织、解析,也是必需要解决的问题。

咱们这样定义页面上的组件数据:

{
    "dataMap":{
        "id1":{
            "cid":"id1", // 组件id
            "type":"pc_component_1", //组件类型
            "name":"组件一", //组件名
            "platform":"pc", //组件所属的平台
            "acceptChild":true, //是否能添加子组件
            "data":{},//组件数据
            "style":{},//组件样式
            "childs":['id3'] //子组件id
        },
        "id2":{
            "cid":"id2", // 组件id
            "type":"pc_component_2", //组件类型
            "name":"组件二", //组件名
            "platform":"pc", //组件所属的平台
            "acceptChild":false, //是否能添加子组件
            "data":{},//组件数据
            "style":{},//组件样式
            "childs":[] //子组件id
        },
        "id3":{
            "cid":"id3", // 组件id
            "type":"pc_component_3", //组件类型
            "name":"组件三", //组件名
            "platform":"pc", //组件所属的平台
            "acceptChild":false, //是否能添加子组件
            "data":{},//组件数据
            "style":{},//组件样式
            "childs":[] //子组件id
        },
        ...
    },
    "childs": ["id1","id2"] //第一层级的组件id
}
复制代码

页面的组件配置数据中有dataMapchilds两个字段。

在须要经过这些配置的组件数据来渲染页面时,首先使用配置项中的 main 字段获取全部第一层级子组件的id,而后在dataMap中,根据组件id来查找对应的具体配置,进行渲染。

若是某个组件配置数据中的 childs 字段不为空数组,就意味该组件中嵌套了其余组件,就继续经过 childs 中的id值,在dataMap中查找对应组件的配置数据,并渲染子组件。

还有,咱们以前提到过的公共组件配置数据,在渲染组件前,也会和dataMap中的对应组件配置进行数据合并。

2.5 rrd-h5 & rrd-pc 中如何渲染?

那么积木系统中生成的页面组件配置数据,是如何在 rrd-h5 和 rrd-pc 中,进行渲染的呢?

其实,目前主流的组件渲染方式有三种:

  • 加载全部的组件定义,而后经过活动id和页面id获取页面的配置数据,进而动态渲染出页面
  • 先经过活动id和页面id获取页面的配置数据,而后按需加载组件,渲染出页面
  • 服务器经过页面配置和组件定义,直接在发布时生成静态页面

不一样的方案各有优劣。rrd-h5 和 rrd-pc 系统中,咱们使用了第一种方案来进行渲染:咱们的线上页面模板,会默认加载全部的组件。

rrd-h5为例,咱们会在活动页面模板中引用全部的 jm-common(公共组件) 和jm-mobile组件库代码。而后使用活动页面URL中携带的活动id和页面id,经过 node-market-service 服务获取活动数据和页面组件配置数据。以后就按上述 2.4 组件的配置与配置数据解析 中介绍的组件配置数据解析方式,渲染出整个活动页面。

就这样,用户就能看到配置的活动页面。

3、TODO

目前的运营平台,其实主要以编辑系统为主,并提供了少许的查询功能。

咱们将来会继续迭代,将继续集成运营监控报警自动生成活动数据报表等功能。

同时,为了提升页面加载速度,考虑到活动页面上图片较多、且切图广泛较大的问题,咱们即将在rrd-h5rrd-pc中引入 webphttp2service-worker等。

4、总结

人人贷活动运营平台在2018年9月上线后,效果极其明显:

  • 活动运营平台,可以自动化、可视化地建立活动及活动页面。
  • 活动运营平台,让活动的上线周期,从以往的6天,下降到了2天。设计师切完图,运营人员就能配置上线。
  • 活动可配置上线和下线时间,开发人员基本不会由于活动的开发而加班。
  • 运营平台规范了活动功能的形式,同时,设计师也会在组件的可编辑范围内进行设计,组件可配置项丰富。
  • 活动页面的样式和文案的修改,再也不须要从新上线。
  • 释放出的前、后端开发人员,能将更多的精力投入到对新技术的研究。

因为篇幅有限,活动运营平台的不少具体实现细节并无过多描述。若是你们有感兴趣的问题,能够留言进行交流。

最后,欢迎你们star咱们的人人贷大前端团队博客,全部的文章还会同步更新到知乎专栏掘金帐号,咱们每周都会分享几篇高质量的大前端技术文章。

参考文章

相关文章
相关标签/搜索