更新记录
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