import { useSettingStore } from '@af-mobile-client-vue3/stores/modules/setting' import { defineStore } from 'pinia' import { ref } from 'vue' // 验证码字符集 const CHARS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' // 生成随机验证码 function generateCode(length = 4): string { let code = '' for (let i = 0; i < length; i++) { code += CHARS.charAt(Math.floor(Math.random() * CHARS.length)) } return code } // 用 canvas 生成验证码图片的 base64 function generateCaptchaImage(code: string): string { try { const canvas = document.createElement('canvas') canvas.width = 80 canvas.height = 32 const ctx = canvas.getContext('2d') if (!ctx) return '' // 随机浅色背景 const bgColors = ['#e8f4ff', '#f0f7ff', '#fff8e1', '#f3e5f5', '#e8f5e9'] ctx.fillStyle = bgColors[Math.floor(Math.random() * bgColors.length)] ctx.fillRect(0, 0, canvas.width, canvas.height) // 随机文字颜色 const textColors = ['#1a73e8', '#e91e63', '#2e7d32', '#6a1b9a', '#1565c0', '#ad1457'] const textColor = textColors[Math.floor(Math.random() * textColors.length)] // 文字 ctx.font = 'bold 22px Arial' ctx.fillStyle = textColor ctx.textAlign = 'center' ctx.textBaseline = 'middle' ctx.fillText(code, canvas.width / 2, canvas.height / 2) return canvas.toDataURL('image/png') } catch { return '' } } export const useCaptchaStore = defineStore('captcha', () => { const show = ref(false) const isLoading = ref(false) const captchaImgBase64 = ref('') const captchaUUID = ref('') const captchaCode = ref('') async function fetchCaptcha() { if (isLoading.value) return isLoading.value = true try { // 未配置 captchaEnable 或显式为 true 时才显示验证码 const setting = useSettingStore().getSetting() if (!setting?.captchaEnable) { show.value = false return } // 本地生成验证码 const code = generateCode() captchaCode.value = code captchaUUID.value = `local_${Date.now()}` captchaImgBase64.value = generateCaptchaImage(code) show.value = true } catch (e) { console.error('生成验证码失败', e) show.value = false } finally { isLoading.value = false } } // 验证验证码 function verifyCaptcha(inputCode: string): boolean { return captchaCode.value.toLowerCase() === inputCode.toLowerCase() } function resetCaptcha() { captchaUUID.value = '' captchaImgBase64.value = '' captchaCode.value = '' show.value = false } return { show, isLoading, captchaImgBase64, captchaUUID, fetchCaptcha, verifyCaptcha, resetCaptcha, } }) export default useCaptchaStore