Browse Source

refactor: 重构倒计时

master
姜鑫 3 years ago
parent
commit
0d24526a7d
  1. 4
      public/static/offline/JSON/getBackTime.json
  2. 5
      src/assets/scss/mixin.scss
  3. 5
      src/base/Logout/Logout.vue
  4. 24
      src/base/Message/Message.vue
  5. 37
      src/components/PublicComponent/PublicComponent.vue
  6. 170
      src/composables/useHandleScreen.ts
  7. 2
      src/plugins/switchLanguage.ts
  8. 5
      src/router/routes.ts

4
public/static/offline/JSON/getBackTime.json

@ -2,7 +2,7 @@
"code": 200,
"msg": "操作成功",
"data": [
100000000000000,
100000000000000
15,
20
]
}

5
src/assets/scss/mixin.scss

@ -27,3 +27,8 @@
}
}
}
@mixin font-bold() {
font-family: 'font_bold';
font-weight: 700;
}

5
src/base/Logout/Logout.vue

@ -1,6 +1,6 @@
<template>
<div v-if="modelValue" class="logout-container">
<div class="dialog-wrapper">
<div class="dialog-wrapper animate__animated animate__zoomIn">
<p class="out-icon" @click="close">
<img src="./chahao.svg" class="close-icon" />
</p>
@ -74,7 +74,7 @@ watch(
<style lang="scss" scoped>
.logout-container {
position: fixed;
position: absolute;
top: 0;
right: 0;
bottom: 0;
@ -82,6 +82,7 @@ watch(
z-index: 9999;
background-color: rgb(0 0 0 / 30%);
backdrop-filter: blur(20px);
animation-duration: 0.3s;
.dialog-wrapper {
position: fixed;

24
src/base/Message/Message.vue

@ -1,5 +1,5 @@
<template>
<Transition name="down">
<Transition enter-active-class="animate__animated animate__fadeInDown" leave-active-class="animate__animated animate__fadeOutUp">
<div v-if="isShowRef" class="message-container">
<div class="message-content" :style="style[type]">
<p class="text-tips">{{ text }}</p>
@ -46,21 +46,6 @@ onMounted(() => {
</script>
<style lang="scss" scoped>
.down {
&-enter {
&-from {
transform: translate3d(0, -75px, 0);
opacity: 0;
}
&-active {
transition: all 0.5s;
}
&-to {
transform: none;
opacity: 1;
}
}
}
.message-container {
position: fixed;
top: 0;
@ -68,10 +53,11 @@ onMounted(() => {
bottom: 0;
left: 0;
z-index: 9999;
animation-duration: 0.3s;
}
.message-content {
position: fixed;
top: 25px;
position: absolute;
top: 200px;
left: 50%;
z-index: 9999;
min-width: 300px;
@ -85,7 +71,7 @@ onMounted(() => {
line-height: 50px;
.text-tips {
font-size: 16px;
font-size: 24px;
text-align: center;
vertical-align: middle;
}

37
src/components/PublicComponent/PublicComponent.vue

@ -1,12 +1,15 @@
<template>
<div></div>
<!-- 地图容器 -->
<Map @handle-go="handleGO" @handle-detail="handleDetail" />
<!-- <Map @handle-go="handleGO" @handle-detail="handleDetail" /> -->
<!-- 退出弹框 -->
<Logout v-model="logoutRef" />
<!-- 倒计时返回首页提示 -->
<AutoBackNotification v-if="countDownGif" :title="title" :delay="isWallpaper ? countDownToWallpaperTimes : countDownToIndexTimes" />
<Transition enter-active-class="animate__animated animate__zoomIn" leave-active-class="animate__animated animate__zoomOut">
<AutoBackNotification v-if="showCountDownDialog" :title="title" :delay="isWallpaper ? toWallpaperTime : toIndexTime" />
</Transition>
</template>
<script setup lang="ts">
@ -15,8 +18,8 @@ import { storeToRefs } from 'pinia'
import { useStore } from '@/store/root'
import { useRouter, useRoute } from 'vue-router'
import { useHandleScreen } from '@/composables/useHandleScreen'
import { useInitMap } from '@/composables/useInitMap'
import Map from '@/components/Map/Map.vue'
// import { useInitMap } from '@/composables/useInitMap'
// import Map from '@/components/Map/Map.vue'
const Logout = defineAsyncComponent(() => import('@/base/Logout/Logout.vue'))
const AutoBackNotification = defineAsyncComponent(() => import('@/base/AutoBackNotification/AutoBackNotification.vue'))
@ -25,15 +28,15 @@ const route = useRoute()
const store = useStore()
const { language } = storeToRefs(store)
const {
checkHandleScreen,
showCountDownDialog,
title,
countDownGif,
toIndexTime,
toWallpaperTime,
isWallpaper,
countDownToWallpaperTimes,
countDownToIndexTimes,
logoutRef,
checkHandleScreen,
setLogoutRef,
resetClickNumber
resetClickNumber,
logoutRef
} = useHandleScreen(handleScreen)
//
@ -43,14 +46,14 @@ function handleScreen() {
language.value !== 'zh' && store.SET_LANGUAGE('zh')
router.push('/transfer')
}
function handleGO() {
router.push('/nav')
}
function handleDetail() {
store.SET_SHOW_DETAIL(true)
}
// function handleGO() {
// router.push('/nav')
// }
// function handleDetail() {
// store.SET_SHOW_DETAIL(true)
// }
onMounted(() => {
!window.Map_QM && useInitMap()
// !window.Map_QM && useInitMap()
window.addEventListener('touchend', checkHandleScreen)
})
onBeforeUnmount(() => {

170
src/composables/useHandleScreen.ts

@ -1,115 +1,105 @@
import { toRefs, computed, reactive, onMounted, ref } from 'vue'
import { ref, computed, onMounted, watch } from 'vue'
import { useRouter } from 'vue-router'
import { useLogout } from '@/composables/useLogout'
import { getBackTime } from '@/http/api/base'
import { useLogout } from '@/composables/useLogout'
import { isAndroid } from '@/utils/utils'
type Reactive = {
totalTime: [number, number] //总时间
countDownToIndexTimer: any //返回首页的定时器
countDownToWallpaperTimer: any //返回屏保的定时器
countDownToIndexTimes: number //返回首页倒计时时间
countDownToWallpaperTimes: number //返回首页倒计时时间
isWallpaper: boolean //当前是回到首页还是回到屏保
countDownGif: boolean //是否显示倒计时gif动图
}
export const useHandleScreen = (callback: () => void) => {
const MIN_TIME = 0
const MAX_TIME = 5
const CHECK_TIME = 1000
const DELAY_CHECK_TIME = 400
const _isAndroid = isAndroid()
const router = useRouter()
const { logoutRef, resetClickNumber, setLogoutRef, addTotalClick } = useLogout()
const state = reactive<Reactive>({
totalTime: [60, 0], //总时间
countDownToIndexTimer: 0, //返回首页的定时器
countDownToWallpaperTimer: 0, //返回屏保的定时器
countDownToIndexTimes: 0, //返回首页倒计时时间
countDownToWallpaperTimes: 0, //返回首页倒计时时间
isWallpaper: false, //当前是回到首页还是回到屏保
countDownGif: false //是否显示倒计时gif动图
})
const title = computed(() => (state.isWallpaper ? '即将进入屏幕保护' : '即将进入首页'))
const totalTime = ref<number[]>([60, 60]) //总时间
const toIndexTime = ref(60) //回首页的时间
const toWallpaperTime = ref(60) //回屏保的时间
const isWallpaper = ref(false) //回首页是否已经跑完
const showCountDownDialog = ref(false)
const title = computed(() => (isWallpaper.value ? '即将进入屏幕保护' : '即将进入首页'))
//超过一分钟未操作回到首页
const delayCheckRouterPathTimer = ref<any>()
const checkHandleScreen = (e: TouchEvent) => {
!_isAndroid && addTotalClick(e)
clearTimeout(delayCheckRouterPathTimer.value)
clearInterval(state.countDownToIndexTimer)
clearInterval(state.countDownToWallpaperTimer)
state.countDownToIndexTimes = state.totalTime[0]
state.countDownToWallpaperTimes = state.totalTime[1]
state.isWallpaper = false
state.countDownGif = false
//延迟判断当前路由处于哪个当中
delayCheckRouterPathTimer.value = setTimeout(async () => {
//如果当前路由不是根路由且倒计时满足条件时优先弹出返回首页
if (router.currentRoute.value.fullPath !== '/') {
await countDownToIndex()
callback && callback()
}
const toIndexInterval = ref()
const toWallpaperInterval = ref()
const delayCheckRoutePathTimer = ref()
//返回屏保时长不为0时跳出返回屏保弹框
if (state.countDownToWallpaperTimes !== 0) {
await countDownToWallpaper()
callback && callback()
}
}, 400)
}
//检测倒计时返回首页弹框是否满足要求
function countDownToIndex() {
clearInterval(state.countDownToIndexTimer)
function sleepToIndex() {
isWallpaper.value = false
return new Promise<void>(resolve => {
state.countDownToIndexTimer = setInterval(() => {
state.countDownToIndexTimes--
if (state.countDownToIndexTimes > 0 && state.countDownToIndexTimes <= 5) {
state.countDownGif = true
}
if (state.countDownToIndexTimes <= 0) {
clearInterval(state.countDownToIndexTimer)
state.countDownGif = false
state.countDownToIndexTimes = state.totalTime[0]
toIndexInterval.value = setInterval(() => {
toIndexTime.value--
if (toIndexTime.value <= MIN_TIME) {
clearInterval(toIndexInterval.value)
toIndexTime.value = totalTime.value[0]
isWallpaper.value = false
resolve()
}
}, 1000)
}, CHECK_TIME)
})
}
//检测倒计时返回屏保弹框是否满足要求
function countDownToWallpaper() {
clearInterval(state.countDownToWallpaperTimer)
state.countDownToWallpaperTimes = state.totalTime[1]
function sleepToWallpaper() {
isWallpaper.value = true
return new Promise<void>(resolve => {
state.countDownToWallpaperTimer = setInterval(() => {
state.countDownToWallpaperTimes--
if (state.countDownToWallpaperTimes > 0 && state.countDownToWallpaperTimes <= 5) {
state.isWallpaper = true
state.countDownGif = true
}
if (state.countDownToWallpaperTimes <= 0) {
clearInterval(state.countDownToWallpaperTimer)
state.countDownGif = false
state.isWallpaper = false
state.countDownToWallpaperTimes = state.totalTime[1]
toWallpaperInterval.value = setInterval(() => {
toWallpaperTime.value--
if (toWallpaperTime.value <= MIN_TIME) {
clearInterval(toWallpaperInterval.value)
toWallpaperTime.value = totalTime.value[1]
isWallpaper.value = false
resolve()
}
}, 1000)
}, CHECK_TIME)
})
}
onMounted(_getBackTime)
//获取返回时长
async function _getBackTime() {
try {
const { data } = await getBackTime()
state.totalTime = data
state.countDownToIndexTimes = data[0]
state.countDownToWallpaperTimes = data[1]
} catch (error) {
console.log('error: ', error)
}
async function checkHandleScreen(e: TouchEvent) {
!_isAndroid && addTotalClick(e)
toIndexTime.value = totalTime.value[0]
toWallpaperTime.value = totalTime.value[1]
clearInterval(toIndexInterval.value)
clearInterval(toWallpaperInterval.value)
clearTimeout(delayCheckRoutePathTimer.value)
delayCheckRoutePathTimer.value = setTimeout(async () => {
if (router.currentRoute.value.fullPath !== '/') {
await sleepToIndex()
callback()
}
await sleepToWallpaper()
callback()
}, DELAY_CHECK_TIME)
}
return { ...toRefs(state), title, logoutRef, checkHandleScreen, resetClickNumber, setLogoutRef }
//监听时间 大于等于0且小于等于5时显示弹框
watch([toIndexTime, toWallpaperTime], ([indexTime, wallpaperTime]) => {
if ((indexTime >= MIN_TIME && indexTime <= MAX_TIME) || (wallpaperTime >= MIN_TIME && wallpaperTime <= MAX_TIME)) {
showCountDownDialog.value = true
} else {
showCountDownDialog.value = false
}
})
onMounted(() => {
//获取返回首页和进入屏保的具体时间
getBackTime().then(({ data }) => {
totalTime.value = data
toIndexTime.value = data[0]
toWallpaperTime.value = data[1]
})
})
return {
isWallpaper,
showCountDownDialog,
title,
checkHandleScreen,
totalTime,
toIndexTime,
toWallpaperTime,
logoutRef,
resetClickNumber,
setLogoutRef
}
}

2
src/plugins/switchLanguage.ts

@ -6,7 +6,7 @@ export const switchLanguage = {
install: (app: App<Element>) => {
const store = useStore()
app.config.globalProperties.switchLanguage = <V extends object, K extends keyof V>(value: V, key: K): V[K] => {
app.config.globalProperties.switchLanguage = (value, key) => {
const language = store.language
let content: any
if (language === 'zh') {

5
src/router/routes.ts

@ -14,5 +14,10 @@ export const routes: RouteRecordRaw[] = [
path: '/parking',
name: 'Parking',
component: () => import(/* webpackChunkName: "parking" */ '@/views/Parking/Parking.vue')
},
{
path: '/transfer',
name: 'Transfer',
component: () => import(/* webpackChunkName: "transfer" */ '@/views/Transfer/Transfer.vue')
}
]

Loading…
Cancel
Save