1.问题来源
最近要做一个学校的班牌项目,选择了uniapp开发(用来用去感觉真的不好用),安卓端,时间也就花在这上面了,然后需要在学生未操作系统一分钟则自动退出,但是uniapp又没有对应可以用的组件,所以只能自己来封装了。
2.解决过程
因为目前是应届毕业生,经验来说不是那么充足,所以解决一些问题还是很吃力的,前期只能在网上找类似的案例来提取自己需要的东西,不过所幸,还是找到了一个有用的案例。最后再根据自己的需求改进了一下。
2.1 getCurrentPages
uniqpp在getCurrentPages内置了一个方法$getAppWebview(),可以得到当前webview的对象实例,从而实现对 webview 更强大的控制。(此方法好像只有在app端才有用)此方法仅 App-Vue 支持
2.2 pinia
uniapp项目目前用的是vue3开发的,所以用的也是和vue3配套的pinia,再加上uview目前也出了个plus版可以很好的支持vue3项目
3.代码实现
stores.js
export const useUserStore = defineStore('user', {
state: () => {
return {
token:"",
userData:{},
};
},
actions: {
setUserName(data) {
//自己的方法
},
getUserName(){
//自己的方法
},
deleteUserName(){
this.token = "",
this.userData={}
}
},
});
export const useTimeStore = defineStore('time', {
state: () => {
//最后一次点击事件的元素
return {lastTime:new Date().getTime()};
},
actions: {
lastTimeUpdata(lastTime) {
this.lastTime = lastTime
},
},
});
time.js
import {useTimeStore,useUserStore} from "@/stores/index.js"
export const timeOut = () => {
const store = useTimeStore()
const userStore = useUserStore()
let WebviewList = [];
// 上一次点击时间
let lastTime = null
// 当前时间
let currentTime = null
// 超时时间【可以自己设置】
let sys_timeout = 60 * 1000
// 每隔多长时间检查是否超时【可以自己设置】
let check_time = 1000
// 计时器【此为功能实现的方法,现在为空】
let goOut = null
const isTimeOut = () => {
// 页面上一次的点击时间
lastTime = store.lastTime
currentTime = new Date().getTime()
// 超时了
if ((currentTime - lastTime) > sys_timeout) {
return true;
} else {
if( (currentTime - lastTime) < 30000 && (currentTime - lastTime)>29000){
uni.showToast({
title:"30秒内未操作将自动退出",
duration:5000,
position:'center'
})
}
return false;
}
}
//我这里写的是判断是否登录,如果登录则监听全局事件
const isLogin = () => {
if (userStore.token != '') {
clearTimeout(isLogin)
isLoginOut();
} else {
setTimeout(isLogin, 1000)
// console.log("等待登录");
}
}
const isLoginOut = () => {
var pages = getCurrentPages();
var page = pages[pages.length - 1];
var currentWebview = page?.$getAppWebview();
//如果超时 则关闭定时器,退出登录,继续监听是否登录
if (isTimeOut()) {
// 已经超时跳转到相应界面,不需要计时了
clearTimeout(goOut)
userStore.deleteUserName();
if (currentWebview.__uniapp_route != 'pages/index/index') {
// 需要转到的页面【这里用你自己的跳转方法和地址】
uni.switchTab({
url: `/pages/index/index`,
});
}
isLogin()
} else {
if(userStore.token == ''){
isLogin()
clearTimeout(goOut)
}else{
goOut = setTimeout(isLoginOut, check_time)
}
}
let flag = false;
for (let webview of WebviewList) {
if (webview?.__uniapp_route == currentWebview?.__uniapp_route) {
flag = true;
}
}
if (!flag) {
store.lastTimeUpdata(new Date().getTime());
WebviewList.push(currentWebview)
currentWebview?.addEventListener('touchstart', function() {
// console.log('点击了');
store.lastTimeUpdata(new Date().getTime());
}, false);
currentWebview?.addEventListener('close', function() {
// console.log('关闭了');
for (var i = 0; i < WebviewList.length; i++) {
if (WebviewList[i].__uniapp_route == currentWebview
.__uniapp_route) {
WebviewList.splice(i, 1);
}
}
}, false);
}
}
isLogin()
}
4.总结
写出来上面的代码后,我看还有很多可以优化的点,包括有几行代码写的比较多余了,但目前业务很多,我一个人是很难忙的过来的,所以代码也就没有优化,能跑起来就很不错了。主要是自己来记录一下思路,保证以后遇到类似的问题可以参考。