import { getLocal, changSaveLocal } from "@/util/localUtil"; import { reactive, watchEffect } from "vue"; // 发送手机验证码 export enum CountdownStuts { never, sendIng, effective, } export type CountdownStore = { status: CountdownStuts; miss: number; create: number; }; export const countdownFactory = (miss: number = 60, key: string = "") => { const store: { [key in string]: CountdownStore } = reactive( getLocal("codeStore" + key, {}) ); console.log(store); changSaveLocal("codeStore" + key, () => store); const get = (key: string) => { if (!store[key]) { store[key] = { status: CountdownStuts.never, miss: 0, create: 0, }; } return store[key]; }; const set = async (key: string, use: (key: string) => void) => { const storeItem = get(key); console.log(storeItem); if (storeItem.status !== CountdownStuts.never) { return; } try { storeItem.status = CountdownStuts.sendIng; await use(key); storeItem.status = CountdownStuts.effective; storeItem.miss = miss; storeItem.create = new Date().getTime(); } catch (e) { console.error(e); storeItem.status = CountdownStuts.never; } }; const setItemStore = (item: CountdownStore) => { if (item.status === CountdownStuts.effective) { const diffMis = (new Date().getTime() - item.create) / 1000; if (diffMis > miss) { item.status = CountdownStuts.never; } else { item.miss = Math.ceil(miss - diffMis); } } else { item.create = 0; item.miss = 0; } }; watchEffect((onCleanup) => { const intervals: number[] = []; for (const key in store) { const item = get(key); setItemStore(item); if (item.status === CountdownStuts.effective) { intervals.push( setInterval(() => { setItemStore(item); }, 1000) ); } } onCleanup(() => { intervals.forEach(clearInterval); }); }); return { get, set(key: string, send: (key: string) => void) { set(key, send || (() => null)); }, }; };