import { reactive, ref } from 'vue' /** 后端 errcode → 前端友好文案 */ const ERR_TEXT: Record = { TOO_FREQUENT: '操作过于频繁,请稍后再试', DUPLICATE_PENDING: '您已有一条待处理的留言,请耐心等待我们与您联系', CAPTCHA_INVALID: '滑块验证已失效,请重新验证', CAPTCHA_EXPIRED: '滑块验证已过期,请重新验证', CAPTCHA_FAILED: '滑块验证未通过,请重试', INVALID_NAME: '请输入有效的姓名(1-20 字)', INVALID_PHONE: '联系电话格式不正确(支持港澳台及海外号码)', INVALID_CONTENT: '留言内容需 5-500 字', UPSTREAM_ERROR: '提交失败,请稍后重试' } /** * 留言表单提交逻辑(前端)。 * 负责:蜜罐静默、调 /api/form/submit、错误码映射到友好提示。 * 真正的校验/限流/去重在服务端完成。 */ export function useContactForm(type = 'contact') { const form = reactive({ name: '', phone: '', content: '' }) const honeypot = ref('') // 蜜罐字段:机器人易填,正常人不可见 const submitting = ref(false) const success = ref(false) const message = ref('') const messageType = ref<'success' | 'error'>('success') async function submit(captcha: { token: string; x: number }) { // 蜜罐命中:假装成功,不真正提交(迷惑机器人) if (honeypot.value.trim()) { success.value = true messageType.value = 'success' message.value = '提交成功,我们会尽快与您联系!' form.name = form.phone = form.content = '' honeypot.value = '' return } submitting.value = true message.value = '' success.value = false try { await $fetch('/api/form/submit', { method: 'POST', body: { type, name: form.name, phone: form.phone, content: form.content, captchaToken: captcha.token, captchaX: captcha.x } }) success.value = true messageType.value = 'success' message.value = '提交成功,我们会尽快与您联系!' form.name = '' form.phone = '' form.content = '' } catch (e: any) { const code = e?.data?.errcode || e?.statusMessage || 'UPSTREAM_ERROR' messageType.value = 'error' message.value = ERR_TEXT[code] || ERR_TEXT.UPSTREAM_ERROR } finally { submitting.value = false } } return { form, honeypot, submitting, success, message, messageType, submit } }