chore: initial import

This commit is contained in:
liangjian
2026-06-29 09:42:53 +08:00
commit 9fea127de1
241 changed files with 82767 additions and 0 deletions

View File

@@ -0,0 +1,165 @@
<template>
<view class="tn-code-class tn-code">
</view>
</template>
<script>
import { getCurrentLanguage } from '../../../utils/i18n'
function getLocalizedText(vm, zh, en) {
const language = vm && vm.$getLanguage ? vm.$getLanguage() : getCurrentLanguage()
return language === 'en' ? en : zh
}
export default {
name: 'tn-verification-code',
props: {
// 倒计时总秒数
seconds: {
type: Number,
default: 60
},
// 开始时提示文字
startText: {
type: String,
default: null
},
// 倒计时提示文字
countDownText: {
type: String,
default: null
},
// 结束时提示文字
endText: {
type: String,
default: null
},
// 是否在H5刷新或各端返回再进入时继续倒计时
keepRunning: {
type: Boolean,
default: false
},
// 为了区分多个页面,或者一个页面多个倒计时组件本地存储的继续倒计时变了
uniqueKey: {
type: String,
default: ''
}
},
data() {
return {
timer: null,
secNum: this.seconds,
// 是否可以执行验证码操作
canGetCode: true
}
},
watch: {
seconds: {
handler(n) {
this.secNum = n
},
immediate: true
}
},
mounted() {
this.checkKeepRunning()
},
beforeDestroy() {
this.setTimeToStorage()
if (this.timer) {
clearInterval(this.timer)
this.timer = null
}
},
methods: {
resolvedStartText() {
return this.startText === null ? getLocalizedText(this, '获取验证码', 'Get Code') : this.startText
},
resolvedCountDownText() {
return this.countDownText === null ? getLocalizedText(this, 's秒后重新获取', 'Resend in s') : this.countDownText
},
resolvedEndText() {
return this.endText === null ? getLocalizedText(this, '重新获取', 'Resend') : this.endText
},
// 检查是否继续运行
checkKeepRunning() {
// 获取上一次退出页面时的时间戳,如果没有上次保存,该值为空
let lastTimestamp = Number(uni.getStorageSync(this.uniqueKey + '_$tCountDownTimestamp'))
if (!lastTimestamp) return this.changeEvent(this.resolvedStartText())
// 当前秒的时间戳
// + new Date() 相当于 new Date().getTime()
let nowTimestamp = Math.floor((+ new Date()) / 1000)
// 判断当前的时间戳,是否小于上一次的设定结束的时间,提前于结束的时间戳
if (this.keepRunning && lastTimestamp && lastTimestamp > nowTimestamp) {
// 剩余尚未执行完倒计时秒数
this.secNum = lastTimestamp - nowTimestamp
// 清除本地保存的变量
uni.removeStorageSync(this.uniqueKey + '_$tCountDownTimestamp')
// 开始倒计时
this.start()
} else {
// 如果不存在需要继续上一次的倒计时,执行正常的逻辑
this.changeEvent(this.resolvedStartText());
}
},
// 开始倒计时
start() {
// 防止快速点击获取验证码按钮导致产生多个定时器导致混乱
if (this.timer) {
clearInterval(this.timer)
this.timer = null
}
this.$emit('start')
this.canGetCode = false
this.changeEvent(this.resolvedCountDownText().replace(/s|S/, this.secNum))
this.setTimeToStorage()
this.timer = setInterval(() => {
if (--this.secNum) {
this.changeEvent(this.resolvedCountDownText().replace(/s|S/, this.secNum))
} else {
// 倒计时结束,清空定时器、重置提示信息
this.reset()
this.$emit('end')
}
}, 1000)
},
// 重置倒计时
reset() {
this.canGetCode = true
if (this.timer) {
clearInterval(this.timer)
this.timer = null
}
this.secNum = this.seconds
this.changeEvent(this.resolvedEndText())
},
// 倒计时改变事件
changeEvent(text) {
this.$emit('change', text)
},
// 保存当前时间戳
// 防止倒计时尚未结束,H5刷新或者各端的右上角返回上一页再进来
setTimeToStorage() {
if (!this.keepRunning ||!this.timer) return
// 记录当前的时间戳,为了下次进入页面,如果还在倒计时内的话,继续倒计时
// 倒计时尚未结束,结果大于0;倒计时已经开始,就会小于初始值,如果等于初始值,说明没有开始倒计时,无需处理
if (this.secNum > 0 && this.secNum <= this.seconds) {
let nowTimestamp = Math.floor((+ new Date()) / 1000)
// 保存本次倒计时结束时候的时间戳
uni.setStorageSync(this.uniqueKey + '_$tCountDownTimestamp', nowTimestamp + this.secNum)
}
}
}
}
</script>
<style lang="scss" scoped>
.tn-code {
width: 0;
height: 0;
position: fixed;
z-index: -1;
}
</style>