处理倒计时

This commit is contained in:
杨 2026-05-22 14:29:32 +08:00
parent f8062eae7b
commit 8ef911603e
10 changed files with 36 additions and 27 deletions

View File

@ -23,18 +23,26 @@ export interface CaptchaCountdownState {
* 初始化验证码倒计时状态(支持刷新恢复) * 初始化验证码倒计时状态(支持刷新恢复)
* @param key 唯一标识(必填,如:register_phone/register_email/forgotPassword_phone) * @param key 唯一标识(必填,如:register_phone/register_email/forgotPassword_phone)
* @param totalSeconds 总倒计时时长(默认60秒) * @param totalSeconds 总倒计时时长(默认60秒)
* @param pagePrefix 页面级唯一前缀(可选,用于隔离不同页面的倒计时状态)
* @returns 倒计时状态对象 * @returns 倒计时状态对象
*/ */
export const initCaptchaState = (key: string, totalSeconds: number = 60): CaptchaCountdownState => { export const initCaptchaState = (
key: string,
totalSeconds: number = 60,
pagePrefix?: string
): CaptchaCountdownState => {
// 生成完整的 key,包含页面级前缀以避免跨页面状态污染
const fullKey = pagePrefix ? `${pagePrefix}_${key}` : key;
const state: CaptchaCountdownState = { const state: CaptchaCountdownState = {
countdown: ref(0), countdown: ref(0),
isCounting: ref(false), isCounting: ref(false),
timer: null, timer: null,
key key: fullKey
}; };
// 页面刷新后,从sessionStorage恢复状态 // 页面刷新后,从sessionStorage恢复状态
const stored = getStorage<StoredCaptchaState>(`captcha_${key}`, 'session'); const stored = getStorage<StoredCaptchaState>(`captcha_${fullKey}`, 'session');
if (stored) { if (stored) {
try { try {
const now = Date.now(); const now = Date.now();
@ -58,11 +66,11 @@ export const initCaptchaState = (key: string, totalSeconds: number = 60): Captch
}, 1000); }, 1000);
} else { } else {
// 剩余时间<=0,清空本地存储 // 剩余时间<=0,清空本地存储
removeStorage(`captcha_${key}`, 'session'); removeStorage(`captcha_${fullKey}`, 'session');
} }
} catch (e) { } catch (e) {
console.error('恢复验证码倒计时状态失败:', e); console.error('恢复验证码倒计时状态失败:', e);
removeStorage(`captcha_${key}`, 'session'); removeStorage(`captcha_${fullKey}`, 'session');
} }
} }

View File

@ -1,7 +1,7 @@
<template> <template>
<div class="table_form-container"> <div class="table_form-container">
<!-- 搜索 --> <!-- 搜索 -->
<FundDetailSearch :search-form="searchForm" :search-options="searchOptions" @search="handleSearch" <FundDetailSearch :search-form="searchForm" :search-options="searchOptions" :buttonLoading="loading" @search="handleSearch"
@reset="handleReset"> @reset="handleReset">
<template #button="{ form }"> <template #button="{ form }">
<el-button type="primary" @click="handleExport()"> 导出 </el-button> <el-button type="primary" @click="handleExport()"> 导出 </el-button>

View File

@ -2,6 +2,7 @@
<div class="rechange-check table_form-container"> <div class="rechange-check table_form-container">
<!-- 搜索区域:默认把当天 0 点到当前时间写入时间输入框 --> <!-- 搜索区域:默认把当天 0 点到当前时间写入时间输入框 -->
<RechangeSearch <RechangeSearch
:buttonLoading="loading"
:search-form="searchForm" :search-form="searchForm"
:search-options="searchOptions" :search-options="searchOptions"
@search="handleSearch" @search="handleSearch"

View File

@ -227,9 +227,9 @@ const sendState = ref({
countdown: 0, countdown: 0,
}) })
//初始化验证码倒计时状态 //初始化验证码倒计时状态(添加页面前缀隔离不同页面的倒计时状态)
const emailCaptchaState = initCaptchaState('email') // 邮箱专属 const emailCaptchaState = initCaptchaState('email', 60, 'transfer_email') // 邮箱专属
const phoneCaptchaState = initCaptchaState('phone') // 手机专属 const phoneCaptchaState = initCaptchaState('phone', 60, 'transfer_phone') // 手机专属
// 邮箱验证码状态 // 邮箱验证码状态
const { isCounting: emailIsCounting, countdown: emailCountdown } = emailCaptchaState const { isCounting: emailIsCounting, countdown: emailCountdown } = emailCaptchaState

View File

@ -205,16 +205,16 @@ const passwordForm = reactive<PasswordForm>({
login_password2: '' login_password2: ''
}); });
// 验证码状态 // 验证码状态(添加页面前缀隔离不同页面的倒计时状态)
const showSendButton = ref(true); const showSendButton = ref(true);
const sendState = ref({ isCounting: false, countdown: 0 }); const sendState = ref({ isCounting: false, countdown: 0 });
const phoneCaptchaState = initCaptchaState('phone'); const phoneCaptchaState = initCaptchaState('phone', 60, 'center_phone');
const emailCaptchaState = initCaptchaState('email'); const emailCaptchaState = initCaptchaState('email', 60, 'center_email');
const showPwdSendButton = ref(true); const showPwdSendButton = ref(true);
const pwdSendState = reactive({ isCounting: false, countdown: 0 }); const pwdSendState = reactive({ isCounting: false, countdown: 0 });
const pwdMobileCaptchaState = initCaptchaState('phone'); const pwdMobileCaptchaState = initCaptchaState('phone', 60, 'center_pwd_phone');
const pwdEmailCaptchaState = initCaptchaState('email'); const pwdEmailCaptchaState = initCaptchaState('email', 60, 'center_pwd_email');
const userStore = useUserStore(); const userStore = useUserStore();
const languageStore = useLanguageStore(); const languageStore = useLanguageStore();

View File

@ -86,9 +86,9 @@ const sendState = ref<object>({
isCounting: false, isCounting: false,
countdown: 0, countdown: 0,
}) })
//初始化验证码倒计时状态 //初始化验证码倒计时状态(添加页面前缀隔离不同页面的倒计时状态)
const emailCaptchaState = initCaptchaState('email'); // 邮箱专属 const emailCaptchaState = initCaptchaState('email', 60, 'changepwd_email'); // 邮箱专属
const phoneCaptchaState = initCaptchaState('phone'); // 手机专属 const phoneCaptchaState = initCaptchaState('phone', 60, 'changepwd_phone'); // 手机专属
// 邮箱验证码状态 // 邮箱验证码状态
const { isCounting: emailIsCounting, countdown: emailCountdown } = emailCaptchaState const { isCounting: emailIsCounting, countdown: emailCountdown } = emailCaptchaState
// 手机验证码状态 // 手机验证码状态

View File

@ -116,9 +116,9 @@ const sendState = ref<object>({
isCounting: false, isCounting: false,
countdown: 0, countdown: 0,
}) })
//初始化验证码倒计时状态 //初始化验证码倒计时状态(添加页面前缀隔离不同页面的倒计时状态)
const emailCaptchaState = initCaptchaState('email'); // 邮箱专属 const emailCaptchaState = initCaptchaState('email', 60, 'forgot_email'); // 邮箱专属
const phoneCaptchaState = initCaptchaState('phone'); // 手机专属 const phoneCaptchaState = initCaptchaState('phone', 60, 'forgot_phone'); // 手机专属
// 邮箱验证码状态 // 邮箱验证码状态
const { isCounting: emailIsCounting, countdown: emailCountdown } = emailCaptchaState const { isCounting: emailIsCounting, countdown: emailCountdown } = emailCaptchaState
// 手机验证码状态 // 手机验证码状态

View File

@ -163,9 +163,9 @@ const registerRules = ref<FormRules>({
code: codeRules().code, code: codeRules().code,
}) })
//初始化验证码倒计时状态 //初始化验证码倒计时状态(添加页面前缀隔离不同页面的倒计时状态)
const emailCaptchaState = initCaptchaState('email') // 邮箱专属 const emailCaptchaState = initCaptchaState('email', 60, 'register_email') // 邮箱专属
const phoneCaptchaState = initCaptchaState('phone') // 手机专属 const phoneCaptchaState = initCaptchaState('phone', 60, 'register_phone') // 手机专属
// 邮箱验证码状态 // 邮箱验证码状态
const { isCounting: emailIsCounting, countdown: emailCountdown } = emailCaptchaState const { isCounting: emailIsCounting, countdown: emailCountdown } = emailCaptchaState
// 手机验证码状态 // 手机验证码状态

View File

@ -60,8 +60,8 @@ const sendState = ref<object>({
isCounting: false, isCounting: false,
countdown: 0, countdown: 0,
}) })
//初始化验证码倒计时状态 //初始化验证码倒计时状态(添加页面前缀隔离不同页面的倒计时状态)
const emailCaptchaState = initCaptchaState('email'); const emailCaptchaState = initCaptchaState('email', 60, 'bindemail_email');
// 邮箱验证码状态 // 邮箱验证码状态
const { isCounting: emailIsCounting, countdown: emailCountdown } = emailCaptchaState const { isCounting: emailIsCounting, countdown: emailCountdown } = emailCaptchaState

View File

@ -70,8 +70,8 @@ const sendState = ref<object>({
isCounting: false, isCounting: false,
countdown: 0, countdown: 0,
}) })
//初始化验证码倒计时状态 //初始化验证码倒计时状态(添加页面前缀隔离不同页面的倒计时状态)
const phoneCaptchaState = initCaptchaState('phone'); const phoneCaptchaState = initCaptchaState('phone', 60, 'bindphone_phone');
// 邮箱验证码状态 // 邮箱验证码状态
const { isCounting: phoneIsCounting, countdown: phoneCountdown } = phoneCaptchaState const { isCounting: phoneIsCounting, countdown: phoneCountdown } = phoneCaptchaState