2b69686795
- 新增404页面,优化未找到页面体验,避免被搜索引擎索引 - 增加文件代理接口,隐藏真实文件服务器地址,支持文件请求代理 - 实现/article、/case、/product及/page动态路由兼容列表与详情展示 - 添加动态CMS页面兼容入口处理旧式路径,统一路由与SEO设置 - 新增模板1、模板7、模板2、模板3关于我们页面,实现多模板支持 - 模板增强支持CMS单页内容加载及SEO信息动态设置 - 配置环境变量及Git忽略文件规则辅助开发和构建环境管理
72 lines
2.5 KiB
TypeScript
72 lines
2.5 KiB
TypeScript
import { reactive, ref } from 'vue'
|
|
|
|
/** 后端 errcode → 前端友好文案 */
|
|
const ERR_TEXT: Record<string, string> = {
|
|
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 }
|
|
}
|