H5页面接入浙里办之后,需要使用到浙里办的登录,其中登录分为法人登录及个人登录,我们这里采取的是个人登录也就是单点登录。
在接入单点登录后,H5界面需要返回两次才能返回到浙里办APP,这样的体验对用户来说不友好。借鉴了网上了的两种方法:一种是监听popstate,一种是监听pageshow。都没有达到想要的效果使用popstate在次级页面返回的时候就会直接退到浙里办APP;使用pageshow,其中使用的判断window.performance.navigation.type 一直都是0,无法作为依据来判断
解决办法:
设置中转页。经测试,这样的写法在iPhone上,在切换账号、切换设备的时候获取不到loginResult页存储的token
一、使用空白页
设置应用的启动第一页为firstScreen
//pages.json
"pages": [
{
"path": "pages/firstScreen/firstScreen",
"style": {
"navigationBarTitleText": ""
}
},
{
"path": "pages/home/home",
"style": {
"navigationBarTitleText": ""
}
},
{
"path": "pages/loginResult/loginResult",
"style": {
"navigationBarTitleText": "登录结果"
}
},
......
]
//firstScreen.vue
<template>
<view class="firstScreen">
{{ ticket ? "前往登录。。。。" : "首屏 应用启动页" }}
</view>
</template>
<script>
export default {
name: "firstScreen",
components: {},
props: {},
data() {
return { ticket: "" };
},
watch: {},
computed: {},
onLoad() {
this.ticket = this.getTicketByUrl();
if (!this.ticket) {
if (!uni.getStorageSync("token")) {
console.log("无ticket,没有token,重定向到首页 再重定向浙里办登录");
this.goHome(true);
} else {
console.log("无ticket,有token,重定向到首页");
this.goHome(false);
}
} else {
console.log("有ticket,重定向到登录结果页");
this.goLoginResult();
}
},
created() {},
mounted() {},
methods: {
// 截取url获取ticket
getTicketByUrl() {
let ticket = null;
let reg = new RegExp("(^|&)" + "ticket" + "=([^&]*)(&|$)");
let r = location.href.substr(1).match(reg);
if (r != null) ticket = unescape(r[2]).replace("#/", "");
console.log("截取url获取ticket--->", ticket);
return ticket;
},
goHome(redrectTo) {
uni.reLaunch({
url: "/pages/home/home?redrectTo=" + redrectTo,
});
},
goLoginResult() {
uni.reLaunch({
url: "/pages/loginResult/loginResult?ticket=" + this.ticket,
});
},
},
};
</script>
<style scoped lang="scss">
.firstScreen {
}
</style>
2、新建一个loginResult页面,在该页面根据ticket去获取token
<template>
<view class="loginResult">
<view> {{ loginResult ? "浙里办登录成功" : "登录中。。。" }}</view>
<view @click="goBack" class="goBack" v-if="loginResult">
返回首页
<text v-if="loginResult">({{ backCount }}s)</text>
</view>
</view>
</template>
<script>
import { zwGoBack } from "@/util/zwUtil";
//根据浙里办RCP接口要求自定义封装的的接口请求方法
import { mgopRequest } from "@/request/mgop";
export default {
name: "loginResult",
components: {},
props: {},
data() {
return {
loginResult: false,
backCount: 3,
cleanIntervalFn: null,
};
},
watch: {},
computed: {},
created() {},
mounted() {},
onLoad(option) {
let ticket = option.ticket;
this.getToken(ticket);
},
destroyed() {
if (this.cleanIntervalFn) clearInterval(this.cleanIntervalFn);
},
methods: {
goBack() {
if (this.cleanIntervalFn) clearInterval(this.cleanIntervalFn);
ZWJSBridge.onReady(() => {
zwGoBack();
});
},
getToken(ticket) {
const data = {
url: "mgop.ztzk.jtyszlb.token", //接口名称
data: {
//参数
loginType: "zlb",
ticket: ticket,
},
};
mgopRequest(data).then((res) => {
console.log(res, "zheliban浙里办");
const resultCode = res.code; // 获取返回的请求状态码
if (resultCode == 200) {
uni.setStorageSync("token", res.data);
this.loginResult = true;
this.cleanIntervalFn = setInterval(() => {
if (this.backCount > 0) this.backCount--;
if (this.backCount === 0) {
if (this.cleanIntervalFn) clearInterval(this.cleanIntervalFn);
this.goBack();
}
}, 1000);
} else {
uni.showToast({ title: res.message, icon: "none" });
}
});
console.log("浙里办ticket 2=====>", ticket);
},
// 截取url获取ticket
getTicketByUrl() {
let ticket = null;
let reg = new RegExp("(^|&)" + "ticket" + "=([^&]*)(&|$)");
let r = location.href.substr(1).match(reg);
if (r != null) ticket = unescape(r[2]).replace("#/", "");
console.log("截取url获取ticket--->", ticket);
return ticket;
},
},
};
</script>
<style scoped lang="scss">
.loginResult {
height: 100vh;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
view {
width: 100%;
text-align: center;
}
.goBack {
margin-top: 32rpx;
}
}
</style>
3、应用首页home.vue,在该页面判断是否要重定向到浙里办登录页
import { zwRedirectTo } from "@/util/zwUtil";
onLoad(option) {
let redrectTo = option.redrectTo;
ZWJSBridge.onReady(() => {
console.log("初始化完成后,执行bridge方法", ZWJSBridge);
if (redrectTo === "true")
setTimeout(() => {
zwRedirectTo();
}, 1000);
});
},
4、浙政钉 H5 埋点代码
// 浙里办登录重定向
export function zwRedirectTo() {
let urlMobile ="https://puser.zjzwfw.gov.cn/sso/mobile.do?xxxxxx";
let urlAlipay ="https://puser.zjzwfw.gov.cn/sso/alipay.do?xxxxxx";
let url = "";
let zwPlatform = checkZwPlatform();
if (zwPlatform === "app") url = urlMobile;
if (zwPlatform === "mini") url = urlAlipay;
console.log("完整的重定向地址 = ", url);
ZWJSBridge.openLink({ url: url });
}
// 检查平台 是浙里办APP 还是支付宝
export function checkZwPlatform() {
const sUserAgent = window.navigator.userAgent.toLowerCase();
// 浙里办APP
const bIsDtDreamApp = sUserAgent.indexOf("dtdreamweb") > -1;
// 支付宝小程序
const bIsAlipayMini =
sUserAgent.indexOf("miniprogram") > -1 && sUserAgent.indexOf("alipay") > -1;
let result = "";
if (bIsDtDreamApp === true) {
result = "app";
} else if (bIsAlipayMini === true) {
result = "mini";
}
console.log("checkZwPlatform=", result);
return result;
}
//判断是否是 android终端
export function isAndroid() {
const sUserAgent = window.navigator.userAgent.toLowerCase();
const isAndroid = sUserAgent.indexOf("android") > -1;
return isAndroid;
}
// 浙里办的二次回退 实测 目前版本不需要区分浙里办APP、支付宝
export function zwGoBack() {
ZWJSBridge.close()
.then((result) => {
console.log(result);
})
.catch((error) => {
console.log(error);
});
}
二、使用路由监听方式
可使用插件:https://github.com/devilwjp/uni-crazy-router/
// 安装 uni-crazy-router
npm i uni-crazy-router -S
// 创建router/index.js
import Vue from 'vue'
import uniCrazyRouter from "uni-crazy-router";
Vue.use(uniCrazyRouter)
uniCrazyRouter.beforeEach(async (to, from ,next)=>{
// 逻辑代码
next()
})
uniCrazyRouter.afterEach((to, from)=>{
// 逻辑代码
const toUrl= to && to.url
const fromUrl= from && from.url
//首页回退到返回界面 :pages/authsso/backpage/backpage:中间件界面
if( toUrl ==='pages/authsso/backpage/backpage' && fromUrl==='pages/index/index'){
console.log(" >>> afterEach >>> ZWJSBridge.close ")
ZWJSBridge.close({}).then(res => {
console.log(res)
}).catch(err => {
console.log(err)
})
}
})
uniCrazyRouter.onError((to, from)=>{
// 逻辑代码
})