榆钱落尽槿花稀 448712ece5 feat: 添加积分申请系统基础功能与UI组件
本次提交主要包含以下内容:

1. 新增积分申请系统核心功能:
   - 添加登录页面及API接口
   - 实现积分申请记录查看功能
   - 集成微信小程序分享功能
   - 添加请求管理工具类

2. 引入Tuniao UI组件库:
   - 添加时间线、折叠面板、表格等UI组件
   - 集成头像组、单选框组等交互组件
   - 配置全局样式和主题颜色

3. 基础架构搭建:
   - 配置项目manifest和pages.json路由
   - 添加状态管理store
   - 实现自定义导航栏适配
   - 添加工具函数(加解密、数字处理等)

4. 静态资源:
   - 添加项目logo和背景图片
   - 配置uni.scss全局样式变量

本次提交为系统基础功能搭建,后续将进一步完善积分申请流程和审批功能。
2025-05-27 16:40:02 +08:00

150 lines
4.5 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="tn-code-class tn-code">
</view>
</template>
<script>
export default {
name: 'tn-verification-code',
props: {
// 倒计时总秒数
seconds: {
type: Number,
default: 60
},
// 开始时提示文字
startText: {
type: String,
default: '获取验证码'
},
// 倒计时提示文字
countDownText: {
type: String,
default: 's秒后重新获取'
},
// 结束时提示文字
endText: {
type: String,
default: '重新获取'
},
// 是否在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: {
// 检查是否继续运行
checkKeepRunning() {
// 获取上一次退出页面时的时间戳,如果没有上次保存,该值为空
let lastTimestamp = Number(uni.getStorageSync(this.uniqueKey + '_$tCountDownTimestamp'))
if (!lastTimestamp) return this.changeEvent(this.startText)
// 当前秒的时间戳
// + 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.startText);
}
},
// 开始倒计时
start() {
// 防止快速点击获取验证码按钮导致产生多个定时器导致混乱
if (this.timer) {
clearInterval(this.timer)
this.timer = null
}
this.$emit('start')
this.canGetCode = false
this.changeEvent(this.countDownText.replace(/s|S/, this.secNum))
this.setTimeToStorage()
this.timer = setInterval(() => {
if (--this.secNum) {
this.changeEvent(this.countDownText.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.endText)
},
// 倒计时改变事件
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>