uni-app:APP/IOS/小程序對接數商雲

背景

我們的公司需要給APP、IOS、小程序對接數商雲,而我們的這個幾個產品都是通過uni-app去開發的,比較特殊的一點是,我們公司沒有專門的原生工程師,因此對接這3個產品的責任就交給了我這個前端去負責。

對接方案

接到這個任務的時候,我首先做的是閱讀數商雲的文檔,數商雲提供了以下幾種接入方式:小程序SDK、JS SDK、IOS_SDK以及Android_SDK。小程序使用小程序SDK接入就好了,沒有問題。問題在於app和ios要如何接入,採用原生的方案對接我一個前端難度很大啊?我想到以前好像看到過說APP/ios是可以通過小程序SDK進行對接的,因此我決定APP和ios也採用小程序SDK去進行對接。
最終我們的項目也是按照此方案進行對接的,也許可以給有類似需求的人們一點啓發。

多端產品均採用小程序SDK對接的好處是:

  • 對接的方式對前端更爲友好
  • 小程序、app、ios可以採用同一套方案進行對接

但與此同時也存在一些問題:

  • 都採用了小程序SDK導致,無法直接通過數商雲判斷平臺來源(當然也有相應的解決方案,後面會提及)

說幹就幹,我按照文檔安裝插件npm install --save shushangyun-masdk,這時我發現小程序原生和UNI-APP項目還是有區別啊,接入方案生搬硬套文檔是行不通的。
大致存在這幾個問題:

  • uni-app不支持小程序的npm構建
  • uni-app的語法和小程序不盡相同

通過觀察,比較,我發現它npm構建的內容其實就是node_modules\shushangyun-masdk\miniprogram_dist

現在,我要做的就是要在uni-app引入這個SDK裏面的原生自定義組件。通過查閱文檔,確定了 [^1]

uni-app 支持在 App 和 小程序 中使用小程序自定義組件。

參考了以下文檔:uni-app使用小程序原生自定義組件

在根目錄新建wxcomponents文件夾(注意必須要叫這個名字),將npm install --save shushangyun-masdk下載下來的node_modules\shushangyun-masdk\miniprogram_dist這個文件夾裏的文件複製到新建的文件夾中,結構類似以下這樣:

├─pages
│  └─index
├─static
└─wxcomponents
    └─components

接着全局註冊組件:

// pages.json
{
  "pages": [
    //pages數組中第一項表示應用啓動頁,參考:https://uniapp.dcloud.io/collocation/pages
    {
      "path": "pages/index/index",
      "style": {
        "navigationBarTitleText": "uni-app"
      }
    }
  ],
  "globalStyle": {
    "navigationBarTextStyle": "black",
    "navigationBarTitleText": "uni-app",
    "navigationBarBackgroundColor": "#F8F8F8",
    "backgroundColor": "#F8F8F8",
    // 註冊全局組件
    "usingComponents": {
      "banner": "/wxcomponents/components/banner",
      "trigger": "/wxcomponents/components/trigger"
    }
  }
}

這時已經引入了原生組件了,但是我們還需要引入數商雲的頁面,這時,就不能直接引入了,還好在看過代碼後,我發現這個page頁面比較簡單,因此我決定將它轉換爲普通的.vue頁面,新建/pages/webview/index.vue。

// /pages/webview/index.vue
<template>
  <web-view :src="path"></web-view>
</template>

<script>
export default {
  data () {
    return {
      path: ''
    }
  },
  onLoad (options) {
    let webview = options.webview;
    console.log(webview);
    let url = decodeURIComponent(unescape(webview));
    this.path = url
  }
}
</script>

<style lang="scss" scoped>
</style>

修改pages.json文件

{
  "pages": [
    //pages數組中第一項表示應用啓動頁,參考:https://uniapp.dcloud.io/collocation/pages
    {
      "path": "pages/index/index",
      "style": {
        "navigationBarTitleText": "uni-app"
      }
    },
    {
      "path": "pages/webview/index"
    }
  ],
  "globalStyle": {
    "navigationBarTextStyle": "black",
    "navigationBarTitleText": "uni-app",
    "navigationBarBackgroundColor": "#F8F8F8",
    "backgroundColor": "#F8F8F8",
    "usingComponents": {
      "banner": "/wxcomponents/components/banner",
      "trigger": "/wxcomponents/components/trigger"
    }
  }
}

現在,可以試着去初始化一下SDK了。
配置App.vue,這裏和文檔一樣,爲了方便,直接在啓動時就進行上傳用戶信息,正式使用時應該在登錄用戶(獲取到用戶信息)時使用

<script>
const masdk = require('./wxcomponents/index');
export default {
  onLaunch: function () {
    this.masdkInit()
  },
  methods: {
    // 初始化數商雲sdk
    masdkInit () {
      //初始化sdk,應該在小程序打開的時候就初始化。
      masdk.init({
        appKey: "應用key",//應用key,必填
        appSecret: "應用secret",//應用secret,必填
        debug: fasle,//是否開啓debug模式,選填,默認爲fasle
        domain: '服務器地址',//服務器地址,一般不用配置此項,此項只針對私有化部署客戶 
        webviewUrl: '/pages/webview/index',//用來打開活動的頁面,選填,默認值是組件提供的webview頁面:miniprogram_npm/shushangyun-masdk/pages/webview,如果有需要,此項指針對需要使用自己定義的頁面去打開活動的開發者
      })
	  //登錄一個測試用戶
      //上傳用戶信息,這個方法應該在用戶登錄之後調用,此例子直接在onLaunch方法裏調用了。正式使用時應該在登錄用戶(獲取到用戶信息)時使用
      masdk.infosUser({
        userid: "user12345",
        sex: "男",
        province: "廣東省",
        //具體字段以商家自定義的用戶表決定。
      });
    },
  },
}
</script>

<style>
/*每個頁面公共css */
</style>

同時在需要的地方引入組件

// 根據業務需要使用組件的地方
<template>
  <view>
    <button size="mini"
            type="primary"
            plain="true"
            @click="triggerDemo">觸發Demo</button>
    <!--引入這個trigger組件顯示觸發圖標-->
    <trigger :param="param" />
    <!-- 數商雲後臺設置的key -->
    <banner position-key="後臺設置的key"
            :swiper-options="swiperOptoins"
            default-image="/static/img/image/bg.png" />
  </view>
</template>

<script>
const masdk = require('../../wxcomponents/index');
export default {
  data () {
    return {
      param: {}, //數商雲觸發返回的數據
      swiperOptoins: { //投放組件輪播圖的配置,配置項請參考小程序的swiper組件
        indicatorDots: true,
        displayMultipleItems: 1
      }
    }
  },
  methods: {
    triggerDemo () {
      //調用sdk的trigger方法
      let infosUser = uni.getStorageSync('infosUser')
      try {
        infosUser = JSON.parse(infosUser)
        if (infosUser && infosUser.userid) {
          masdk.trigger({
            userid: infosUser.userid, //觸發用戶id
            eventKey: '事件key', // 事件key
            conditions: {
              loginFrequency: 20,
              loginTime: '2019-10-28 08:00:00',
              registrationTime: '2019-10-01 08:00:00',
              storeConsumption: 10000
            }
          }).then((res) => {
            this.param = res.data
          })
            .catch((err) => {
              console.log(err);

            })
        }
      } catch (error) {

      }
    }
  }
}
</script>

<style lang="scss" scoped>
</style>

這時運行uni-app項目是會報錯的,因爲數商雲的組件引入SDK的路徑是錯誤的。例如:

// /wxcomponents/components/banner.js
// 原始代碼是這樣的,現在沒有用到npm安裝依賴,自然不應該這樣引入,事實上,好像安裝了依賴好像也是引入不了的,我記得當時我是npm安裝了的,但是一樣會報錯
const masdk = require('shushangyun-masdk');

需要改成這樣:

// /wxcomponents/components/banner.js 以及 /wxcomponents/components/trigger.js
const masdk = require('../index');

當時的我是這樣做的,但是發現還是有報錯,Cannot read property 'appKey' of undefined。這個問題我排查了很久,對比了原生小程序接入SDK,以及debugger,發現正常情況下,小程序組件引入的masdk對象裏是會帶有初始化時傳入的配置信息的,但是uni-app這個項目裏的原生組件裏的masdk (如: /wxcomponents/components/banner.js 以及 /wxcomponents/components/trigger.js裏引入了masdk),裏面masdk對象沒有初始化到。原因我也不確定,可能是跨模塊通信有問題?畢竟本來uni-app是用vue的,引入原生組件,相互通信間可能有一些兼容問題吧。

現在,我遇到的問題是,數商雲的對象masdk無法在小程序自定義組件和普通的uni-app頁面公用,因此我決定將這個對象存入全局對象globalData中,以解決通信的問題。

 // App.vue
 globalData: {
   // 一般的全局變量使用vuex實現,現在我遇到一個問題,數商雲對象masdk無法在小程序自定義組件和普通頁面公用,因此採用此種方式實現
   masdk
 },

同時,自定義的小程序組件也使用globalData的masdk。

// /wxcomponents/components/banner.js 以及 /wxcomponents/components/trigger.js
const masdk = getApp().globalData.masdk;

這時應該就可以調通數商雲了,接下來就是根據業務需要進行埋點了。

關於埋點

由於本人即將離職,因此後續的埋點工作我是轉交給了同事去進行的。雖然沒有直接參與,有些東西還是可以聊聊的。
由於我這個方案,只用了小程序SDK去進行對接,數商雲無法直接判斷平臺來源。
爲此我需要傳一個條件去標明用戶觸發的平臺是小程序、app、ios。
另外,由於運營那邊希望用戶不登錄也可以觸發數商雲,因此userid定義了一個特殊的遊客id,這個時候,爲了讓數商雲可以方便判斷用戶是否遊客,需要傳一個條件去標明用戶是否已登錄。
大致就是這樣,後面如果有需要補充的,我也會繼續更新文章。

本文目的

寫這篇博客是因爲替公司面試前端時,發現一個前端簡歷上的博客竟然有好幾頁那麼多,想到自己博客裏的寥寥幾篇文章,心裏難免有點波動。又發現自己的github上竟然在別人提了issues兩個多月後纔看到,心裏還是很驚訝的。
工作越來越忙,半年007,擠佔了我大部分的時間,連生活的節奏都被打亂,很多希望自己養成的習慣都被放下了。那個面試的前端,她的博客我看了一下,每篇都不是很長,但一直都在堅持,我也想試着實踐一下,記錄一下自己的一些小小的收穫,小小的心得。

參考:
[1]: https://uniapp.dcloud.io/frame?id=%E5%B0%8F%E7%A8%8B%E5%BA%8F%E7%BB%84%E4%BB%B6%E6%94%AF%E6%8C%81

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章