更新记录

1.0.5(2022-10-12)

Docs

  • readme增加接入指引

1.0.4(2022-10-11)

Docs

  • readme增加安装依赖的说明

1.0.3(2022-10-11)

Bug Fixes

  • 引入类文件路径改为相对路径
查看更多

平台兼容性

hd-uni

1. 插件介绍

HD-UNI小程序接入插件

2. 安装依赖

yarn add jwt-decode -D

3. 插件引入

在main.ts中加入以下代码

import Vue from 'vue'
import App from './App.vue'

// #ifdef APP-PLUS
import hdUni from './uni_modules/hd-uni'
Vue.use(hdUni)
// #endif

Vue.config.productionTip = false

new App({}).$mount()

4. 小程序初始化

定义vuex key存储初始化信息


import Vue from 'vue'
import Vuex from 'vuex'
import { Commit } from 'vuex'
import StoragePlugin from './StoragePlugin'
import { State } from 'vuex-class'
import MpInfo from '@/model/microApp/MpInfo'
Vue.use(Vuex)

export interface State {
  microInfo: Nullable<MpInfo> // 在uni-portal环境中的登录信息
}

const store = new Vuex.Store({
  plugins: [StoragePlugin],
  state: {
    microInfo: null // 在uni-portal环境中的登录信息
  },
  mutations: {
    microInfo(state: State, microInfo: MpInfo) {
      state.microInfo = microInfo
    }
  },
  getters: {
    /**
     * 是否在UNI-PORTAL中
     */
    isMicro: (state: State) => {
      if (state.microInfo) {
        return true
      } else {
        return false
      }
    }
  },
  actions: {
    microInfo(context: { commit: Commit }, microInfo: MpInfo) {
      context.commit('microInfo', microInfo)
    }
  }
})

export default store

在APP.vue中接收主应用传入的初始化参数

<script lang="ts">
import Vue from 'vue'
import store from '@/store'
...

export default Vue.extend({
  mpType: 'app',
  // 我们从onLaunch生命周期中取到初始化信息
  onLaunch(info) {

    ...

    // #ifdef APP-PLUS
    // 初始化信息的模型为MpInfo,这个模型由插件提供
    if (info && info.referrerInfo && info.referrerInfo.extraData) {
      const { data: mpInfo }: BaseMp<MpInfo> = info.referrerInfo.extraData
      if (mpInfo && mpInfo.serverUrl) {
        // 接收到初始化信息之后,我们推荐采用独立的vuex key来存储,这里我们定义为microInfo
        store.commit('microInfo', mpInfo)
      }
    }
    // 由于hd-uni小程序基于APP-PLUS平台,所以需要通过判断是否获取到了初始化信息来区分表现
    // 如果单独的APP则采用原APP的逻辑(检查更新等)
    if (!store.getters.isMicro) {
      if (uni.getSystemInfoSync().platform == 'android') {
        const hdconfig: any = uni.requireNativePlugin('HDConfig')
        hdconfig.checkUpdate()
      }
    } else { // hd-uni小程序则开始与主应用通信的逻辑
      // 通知主应用 小程序已启动
      uni.$hdmp.sendMessage({
        event: 'mpInited',
        data: {
          traceId: DateUtil.format(new Date().getTime(), 'yyyyMMddHHmmssSSS'),
          msg: '小程序启动了'
        }
      })
      // 监听主应用消息
      uni.$hdmp.reciveMessage({
        success: (event, result) => {
          switch (event) {
            // 更新token的通知,则将token信息更新 模型为TokenInfo
            case 'updateToken':
              store.commit('microInfo', { ...store.state.microInfo, ...result.data })
              break
            // 主应用询问信息
            case 'askMpRuntimeInfo':
              const data: MpRuntimeInfo = {
                appId: plus.runtime.appid || '',
                currentPath: getCurrentPages()[getCurrentPages().length - 1].route || '',
                enableHot: true
              }
              uni.$hdmp.sendMessage({
                event: 'mpRuntimeInfo',
                data: {
                  traceId: result.traceId,
                  data: data,
                  msg: '可以启动'
                }
              })
              break
            default:
              break
          }
        }
      })
    }
    // #endif
  }
  ...
})
</script>

修改请求&响应拦截器 fly.ts

import Config from '@/config'
import store from '@/store'
import DateUtil from '@/utils/DateUtil'
import ResponseCode from '@/network/ResponseCode'
import LogApi from './LogApi/LogApi'
import LogModel from '@/model/common/LogModel'
let Fly = require('flyio/dist/npm/wx')
// #ifdef MP-ALIPAY
Fly = require('flyio/dist/npm/ap')
// #endif
const fly = new Fly()

// 在uni中则取服务返回的接口地址
// 否则取配置的
if (store && store.getters && store.getters.isMicro) {
  fly.config.baseURL = store.state.microInfo!.serverUrl
} else {
  fly.config.baseURL = Config.baseUrl
}
...

// 请求拦截
fly.interceptors.request.use((request: any) => {
  ...

  // 添加默认签名
  if (store && store.getters && store.getters.isMicro) {
    if (store.state.microInfo) {
      request = uni.$hdmp.setToken(request, store.state.microInfo)
    }
  } else {
      request.headers.Authorization = 单独运行时的token
  }
  return request
})
// 返回拦截
fly.interceptors.response.use(
  function(response) {
    if (store && store.getters && store.getters.isMicro) {
      if (store.state.microInfo) {
        const microInfo = uni.$hdmp.refreshToken(response.headers, store.state.microInfo)
        if (microInfo) {
          store.dispatch('microInfo', microInfo)
          uni.$hdmp.sendMessage({
            event: 'updateToken',
            data: {
              traceId: DateUtil.format(new Date().getTime(), 'yyyyMMddHHmmssSSS'),
              data: microInfo,
              msg: 'token发生更新'
            }
          })
        }
      }
    }
  },
  function(error) {
    ... 原逻辑

    switch (error.status) {
      // 此处重点在于401状态的处理
      case 401:
        if (!store || !store.getters || !store.getters.isMicro) {
          ... 原逻辑
        } else {
          // 如果是HD-UNI则关闭当前应用
          if (store.getters.isMicro) {
            uni.$hdmp.sendMessage({
              event: 'tokenExpire',
              data: {
                traceId: DateUtil.format(new Date().getTime(), 'yyyyMMddHHmmssSSS'),
                msg: '401了'
              },
              complete: () => {
                uni.showToast({ title: '小程序鉴权信息已过期', icon: 'none' })
                plus.runtime.quit()
              }
            })
          }
        }
        break

      case 403:
        error.msg = `${error.status} 禁止访问!`
        break
      case 500:
        error.msg = `${error.status} 服务内部异常!`
        break
      case 502:
        error.msg = `${error.status} 服务器暂不可用!`
        break
      case 503:
        error.msg = `${error.status} 服务器升级中!`
        break
      case 404:
        error.msg = `${error.status} 接口不存在!`
        break
      default:
        error.msg = `${error.status} 未知错误!`

        ... 原逻辑
    }
    return Promise.reject(error)
  }
)

export default fly

隐私、权限声明

1. 本插件需要申请的系统权限列表:

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

许可协议

MIT协议

暂无用户评论。

使用中有什么不明白的地方,就向插件作者提问吧~ 我要提问