活動運營自動化平臺實踐

人人貸大前端技術中心發表於2019-06-05

人人貸活動運營平臺,是一個由人人貸大前端團隊進行開發和維護,並用於自動化、視覺化構建人人貸常規活動的系統。本文將會分享"人人貸活動運營平臺"的設計思想和部分技術實現,希望對大家有所幫助。

一、背景

人人貸前端團隊在過去的幾年裡,接到了很多來自市場部門的活動開發需求,這些活動主要分為4大類:

  • LP活動(Landing Page,引導頁),用於新人註冊的活動頁面,基本都是一個註冊框 + 若干產品卡
  • MGM活動(Members get member),用於好友間邀請拉新的活動頁面,一般包括邀請記錄,邀請排行,分享等功能
  • 常規活動,一般包括抽獎、產品卡、排行榜、分享等功能,用於促進銷量
  • 特殊活動,一般是遊戲頁面,相同的形式基本只會使用一次

1.1 活動開發人力瓶頸和上線週期長

一個普通的活動(包括上述的LP活動、MGM活動、常規活動)開發時間得多久?

正常情況下,一個涉及到H5和PC兩端的簡單活動,從產品提出需求開始,設計師需要2人*2天來完成設計工作,開發需要3人*2天(包括H5、PC端頁面、後端介面開發、介面聯調),測試需要2人*2天投入。

就這樣,從需求提出到頁面上線,需要一共投入14人*天的人力資源,得 7個工作日 才能完成。

而遇到比較緊急的活動開發需求,上線週期需要壓縮,大家都得加班來完成。

另外,由於公司財務結算的特殊性,很多活動的開始時間一般都是凌晨,開發、測試人員需要確認活動線上上執行正常,才能下班。

1.2 活動功能重複和反覆修改

隨著公司業務的發展,活動的開發需求越來越多。前端團隊有三分之一的人力,長期投入在活動頁面的開發中。

事實上,我們們大部分的普通活動,功能並不複雜,而且大部分的功能比較重複。

這種功能重複性的頁面開發,對於個人和團隊的成長來說,並沒有太多的價值。而且活動上線後,經常因為樣式和文案的關係,需要修改程式碼,重新上線,導致團隊成員普遍比較反感這種普通活動的開發。

期間,團隊也提出過元件化開發的方式,試圖將不同的功能模組抽取出來,在不同的活動頁面上進行引用,以便節省開發時間。但由於設計方案的不確定性,以及不同開發人員參與,這種抽取的功能模組複用性不太高,效果不是特別理想。並且不能解決樣式和文案修改,需要重新上線的問題。

總之,普通活動的特點是:頁面功能大同小異、開發時間緊、下線快、技術成長低。

隨著團隊的技術體系日益成熟,我們終於騰出精力,試圖解決普通活動開發中各項痛點。

二、人人貸活動運營平臺

早在十幾年前,使用Dreamweaver就能視覺化地搭建出前端靜態頁面。雖然Dreamweaver已經成為過去式,但是視覺化搭建的思想,卻被廣泛使用。

我們在調研業界常用解決方案中發現,很多公司都有自己的活動運營系統,可用來高效、視覺化地配置活動,以及監控活動運營資料。我們希望採用這種活動頁面視覺化搭建的思想,由運營人員根據實際的運營需求,自行新增活動,並配置對應的活動頁面。

運營平臺

2.1 整體框架

首先,簡單介紹下人人貸前端的開發模式。

隨著 Node.js 的興起,我們從2016年開始,將原有基於 JSP 的前端開發模式,改造成使用 Node.js 做中間層,進行前後端分離的模式。

前後端分離

人人貸前端使用的就是圖中所示的前後端分離的開發模式(圖片來自Web 研發模式演變),這種開發模式下,前後端的職責清晰。對於前端來說,兩個UI層各司其職:Front-end UI layer 處理瀏覽器層的展現邏輯,Back-end UI layer 可以用來處理路由、模板、資料獲取、cookie、伺服器端渲染等。

在這種前後端開發模式下,整個人人貸活動運營平臺的架構圖如下:

整體架構圖

整個運營平臺系統分為四大塊。

1、元件庫。運營平臺採用了業界通用的 元件化 方案,並且選用 React.js 作為元件的開發庫。下面會詳細介紹元件庫的拆分和開發模式。

2、前端系統。整個運營平臺包括 積木系統rrd-h5rrd-pc 三個前端系統。其中 積木系統 是運營建立、編輯、釋出活動頁面的系統,屬於內部系統。而rrd-h5rrd-pc 屬於面向使用者的Back-end UI layer,它們是基於生成的活動配置資料,對活動頁面進行渲染及提供非同步介面,以供使用者訪問。

3、後端介面。在後臺服務上,由於活動並不是特別複雜,我們有較大一部分介面,比如抽獎、記錄收穫地址,只是做一些簡單的儲存或者計算,就直接使用了Node.js實現,也就是上圖中的node-market-service服務。而部分與公司主營業務相關的介面,比如投資返現這類,還是直接使用後端提供的Java介面。

4、資料層。用於儲存活動配置相關的資料以及部分運營資料。

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 元件的配置與配置資料解析 中介紹的元件配置資料解析方式,渲染出整個活動頁面。

就這樣,使用者就能看到配置的活動頁面。

三、TODO

目前的運營平臺,其實主要以編輯系統為主,並提供了少量的查詢功能。

我們未來會繼續迭代,將繼續整合運營監控報警自動生成活動資料包表等功能。

同時,為了提高頁面載入速度,考慮到活動頁面上圖片較多、且切圖普遍較大的問題,我們即將在rrd-h5rrd-pc中引入 webphttp2service-worker等。

四、總結

人人貸活動運營平臺在2018年9月上線後,效果極其明顯:

  • 活動運營平臺,能夠自動化、視覺化地建立活動及活動頁面。
  • 活動運營平臺,讓活動的上線週期,從以往的6天,降低到了2天。設計師切完圖,運營人員就能配置上線。
  • 活動可配置上線和下線時間,開發人員基本不會因為活動的開發而加班。
  • 運營平臺規範了活動功能的形式,同時,設計師也會在元件的可編輯範圍內進行設計,元件可配置項豐富。
  • 活動頁面的樣式和文案的修改,不再需要重新上線。
  • 釋放出的前、後端開發人員,能將更多的精力投入到對新技術的研究。

由於篇幅有限,活動運營平臺的很多具體實現細節並沒有過多描述。如果大家有感興趣的問題,可以留言進行交流。

最後,歡迎大家star我們的人人貸大前端團隊部落格,所有的文章還會同步更新到知乎專欄掘金賬號,我們每週都會分享幾篇高質量的大前端技術文章。

參考文章

相關文章