feat(app): 添加多模板关于我们页面及相关路由和404页面

- 新增404页面,优化未找到页面体验,避免被搜索引擎索引
- 增加文件代理接口,隐藏真实文件服务器地址,支持文件请求代理
- 实现/article、/case、/product及/page动态路由兼容列表与详情展示
- 添加动态CMS页面兼容入口处理旧式路径,统一路由与SEO设置
- 新增模板1、模板7、模板2、模板3关于我们页面,实现多模板支持
- 模板增强支持CMS单页内容加载及SEO信息动态设置
- 配置环境变量及Git忽略文件规则辅助开发和构建环境管理
This commit is contained in:
2026-09-08 12:13:44 +08:00
commit 2b69686795
381 changed files with 59891 additions and 0 deletions
+20
View File
@@ -0,0 +1,20 @@
import { defineEventHandler, readBody } from 'h3'
import { saveCaptcha } from '../../utils/guard'
const SLIDER_SIZE = 42
const MIN_W = 240
const MAX_W = 480
/**
* 生成滑块拼图验证码 challenge。
* 前端量取自身宽度后传入,后端在该宽度内随机生成缺口 X 坐标作为答案。
* 返回 token + puzzleX(缺口位置,前端用于渲染) + width + size。
*/
export default defineEventHandler(async (event) => {
const body = (await readBody(event).catch(() => ({}))) as Record<string, any>
const width = Math.min(Math.max(Number(body?.width) || 320, MIN_W), MAX_W)
const token = globalThis.crypto.randomUUID()
const answer = Math.floor(Math.random() * (width - SLIDER_SIZE * 2)) + SLIDER_SIZE
await saveCaptcha(token, answer)
return { token, puzzleX: answer, width, size: SLIDER_SIZE }
})
+22
View File
@@ -0,0 +1,22 @@
import { defineEventHandler, readBody, createError } from 'h3'
import { verifyCaptcha } from '../../utils/guard'
/**
* 校验滑块拼图位置。
* body: { token, x } x 为用户拖动后拼图块中心 X 坐标。
* 成功返回 { pass: true, ticket }ticket 为一次性提交票据);失败返回 { pass: false }。
*/
export default defineEventHandler(async (event) => {
const body = (await readBody(event).catch(() => ({}))) as Record<string, any>
const token = body?.token
const x = Number(body?.x)
if (!token || !Number.isFinite(x)) {
throw createError({ statusCode: 400, statusMessage: '参数缺失' })
}
const ticket = await verifyCaptcha(token, x)
if (!ticket) return { pass: false }
return { pass: true, ticket }
})