countdown.ts 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. import { getLocal, changSaveLocal } from "@/util/localUtil";
  2. import { reactive, watchEffect } from "vue";
  3. // 发送手机验证码
  4. export enum CountdownStuts {
  5. never,
  6. sendIng,
  7. effective,
  8. }
  9. export type CountdownStore = {
  10. status: CountdownStuts;
  11. miss: number;
  12. create: number;
  13. };
  14. export const countdownFactory = (miss: number = 60, key: string = "") => {
  15. const store: { [key in string]: CountdownStore } = reactive(
  16. getLocal("codeStore" + key, {})
  17. );
  18. console.log(store);
  19. changSaveLocal("codeStore" + key, () => store);
  20. const get = (key: string) => {
  21. if (!store[key]) {
  22. store[key] = {
  23. status: CountdownStuts.never,
  24. miss: 0,
  25. create: 0,
  26. };
  27. }
  28. return store[key];
  29. };
  30. const set = async (key: string, use: (key: string) => void) => {
  31. const storeItem = get(key);
  32. console.log(storeItem);
  33. if (storeItem.status !== CountdownStuts.never) {
  34. return;
  35. }
  36. try {
  37. storeItem.status = CountdownStuts.sendIng;
  38. await use(key);
  39. storeItem.status = CountdownStuts.effective;
  40. storeItem.miss = miss;
  41. storeItem.create = new Date().getTime();
  42. } catch (e) {
  43. console.error(e);
  44. storeItem.status = CountdownStuts.never;
  45. }
  46. };
  47. const setItemStore = (item: CountdownStore) => {
  48. if (item.status === CountdownStuts.effective) {
  49. const diffMis = (new Date().getTime() - item.create) / 1000;
  50. if (diffMis > miss) {
  51. item.status = CountdownStuts.never;
  52. } else {
  53. item.miss = Math.ceil(miss - diffMis);
  54. }
  55. } else {
  56. item.create = 0;
  57. item.miss = 0;
  58. }
  59. };
  60. watchEffect((onCleanup) => {
  61. const intervals: number[] = [];
  62. for (const key in store) {
  63. const item = get(key);
  64. setItemStore(item);
  65. if (item.status === CountdownStuts.effective) {
  66. intervals.push(
  67. setInterval(() => {
  68. setItemStore(item);
  69. }, 1000)
  70. );
  71. }
  72. }
  73. onCleanup(() => {
  74. intervals.forEach(clearInterval);
  75. });
  76. });
  77. return {
  78. get,
  79. set(key: string, send: (key: string) => void) {
  80. set(key, send || (() => null));
  81. },
  82. };
  83. };