反馈系统
概述
MysticX 包含一个双通道反馈系统,用户可以分享体验、报告问题和提出改进建议。反馈通过所有主页面上的浮动小组件和专用的完整反馈页面收集,然后由管理员在后台面板中管理。
反馈通道
浮动小组件
一个轻量级反馈小组件,在所有 (main) 布局页面上延迟 5 秒后显示。
流程:
- 用户点击右下角的"反馈"浮动按钮
- 弹出面板滑出,显示"您的体验如何?"
- 用户选择一个心情表情(很差 → 不好 → 一般 → 还不错 → 太棒了)
- 文本框展开,可输入可选文字(最多 500 字符)
- 用户点击"发送反馈"提交
行为:
- 在
/feedback和/auth/*路径下隐藏,避免重复 - 提交成功后按钮隐藏 7 天(存储在
localStorage的feedback_widget_submitted_at中) - 移动端:仅显示图标;桌面端:图标 + 本地化"反馈"文字
- 点击外部区域或按 Escape 键关闭面板
- 未登录用户使用占位邮箱提交;已登录用户自动填充会话邮箱
- 自动捕获
window.location.pathname作为 pageUrl
文件:
components/FeedbackWidget/FeedbackWidget.tsx— 主组件components/FeedbackWidget/MoodPicker.tsx— 5 级心情选择器(支持size="sm"用于小组件,size="lg"用于页面)components/FeedbackWidget/FeedbackWidget.css— 动画样式stores/feedbackWidgetStore.ts— Zustand 状态管理(isOpen、open、close)
反馈页面
位于 /feedback 的完整反馈表单页面,提供更丰富的输入选项。
功能:
- 邮箱字段(从会话自动填充)
- 心情选择器(可选,大尺寸变体)— 复用
MoodPicker,传入size="lg" - 内容文本框(必填,最多 2,000 字符)
- 截图上传(最多 5 张,JPEG/PNG/WebP,每张最大 5MB)
- 常见问题 FAQ 部分
- 带有动画标题和金色光泽效果的头部区域
文件:
app/[locale]/(main)/feedback/page.tsx— 带 i18n 元数据的服务端组件app/[locale]/(main)/feedback/_components/FeedbackPageContent.tsx— 头部 + 布局app/[locale]/(main)/feedback/_components/FeedbackForm.tsx— 表单组件app/[locale]/(main)/feedback/_components/FeedbackFAQ.tsx— FAQ 手风琴组件
数据模型
prisma
enum FeedbackStatus {
PENDING
REVIEWED
RESOLVED
}
enum FeedbackMood {
AMAZING
GOOD
OKAY
BAD
TERRIBLE
}
model UserFeedback {
id String @id @default(uuid())
userId String?
user User? @relation(...)
email String
content String? @db.Text
screenshotUrls Json @default("[]") // string[],最多 5 个
status FeedbackStatus @default(PENDING)
adminNote String? @db.Text
mood FeedbackMood?
source String @default("page") // "widget" | "page"
pageUrl String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}关键字段:
mood— 可为空。小组件提交时必填;页面提交时可选。source—"widget"或"page"。标识提交渠道。pageUrl— 用户提交时所在的页面路径,自动捕获。content— 小组件提交时可选(仅选择心情即可);页面提交时必填。
API 端点
POST /api/v1/feedback
提交反馈条目。无需登录(访客可提交)。
请求体:
json
{
"email": "user@example.com",
"content": "很棒的应用!",
"screenshotUrls": [],
"mood": "AMAZING",
"source": "widget",
"pageUrl": "/zh-CN/love-tarot"
}验证规则:
| 字段 | 小组件 | 页面 |
|---|---|---|
email | 必填(合法格式) | 必填(合法格式) |
mood | 必填 | 可选 |
content | 可选 | 必填 |
screenshotUrls | 不支持 | 可选(最多 5 张) |
pageUrl | 自动捕获 | 自动捕获 |
POST /api/v1/feedback/upload
上传截图到 Cloudflare R2,供页面表单使用。
- 接收:包含
file字段的FormData - 验证:JPEG/PNG/WebP,最大 5MB,通过
sharp验证格式 - 返回:
{ data: { url } },包含公开的 R2 URL
管理后台
位于 /admin/app/feedback。
反馈列表
- 按状态筛选:全部、待处理、已查看、已解决
- 按邮箱或内容搜索
- 分页显示(每页 20 条)
- 列:邮箱、心情(表情)、内容、来源(标签)、截图、状态、提交时间、操作
反馈详情弹窗
- 完整内容查看及元数据(邮箱、用户、时间戳)
- 来源标签和心情显示
- 提交反馈时的页面 URL
- 截图画廊,支持外部链接打开
- 状态下拉菜单(待处理 → 已查看 → 已解决)
- 管理员备注文本框
管理操作
updateFeedback(id, { status, adminNote })— 更新状态和备注deleteFeedback(id)— 删除反馈并清理 R2 截图
国际化
所有面向用户的文本均使用 useTrans/getTrans 内联字典翻译为 12 种语言: en、zh_CN、ja、ko、pt、es、fr、de、ar、zh_TW、id、nl。
管理后台按项目规范仅使用英文。
页脚链接
页脚的"探索"栏目下包含一个"意见反馈"链接,指向 /feedback。