Project lingjing
灵镜 v3.0 需求文档
灵镜 v3.0 需求文档
状态:开发中 | 基于 v2.0(commit: 0211f6a)
一、交互升级:混合题型
题型分类
| 类型 | 标识 | 说明 |
|---|---|---|
| 开放输入 | text | 用户手动输入,和v2.0相同 |
| 选择题 | choice | 气泡按钮,AI动态出选项(半固定模板) |
| 固定采集题 | fixed_gender / fixed_age / fixed_birth_month / fixed_birth_day | 固定选项,AI自然穿插问 |
API协议变更
后端/api/chat返回格式升级:
// 选择题
{ "done": false, "type": "choice", "question": "最近睡眠怎么样?", "options": ["很好", "还行", "很差", "完全不规律"], "index": 3, "sessionId": "..." }
// 开放题(兼容旧格式)
{ "done": false, "type": "text", "reply": "你现在最担心的事是什么?", "index": 4, "sessionId": "..." }
// 固定采集题
{ "done": false, "type": "fixed_gender", "question": "顺便问一下,你是", "index": 5, "sessionId": "..." }固定采集题选项
- 性别 (
fixed_gender):男生 / 女生 / 不想说 - 年龄 (
fixed_age):20以下 / 20-25 / 26-30 / 31-40 / 40以上 - 生日月份 (
fixed_birth_month):1月 ~ 12月(12个气泡) - 生日日期 (
fixed_birth_day):1日 ~ 31日(31个气泡,分行排列)
插入时机
- 固定采集题由AI自然穿插,不固定在第几题
- System Prompt中告知AI:在合适时机自然插入,不要集中在开头
- 避免连续两题都是固定采集题
AI选项生成规则
- 约10/30题为选择/判断题
- AI使用半固定模板出选项(情绪/状态类从预设词库选4个)
- 一次API调用同时返回题型+选项,不额外调用
- 选项数量:通常4个,判断题2个,月份12个,日期31个
二、气泡UI规范
气泡漂浮动画
- 各气泡相位错开,营造层次感(每个气泡的漂浮周期/幅度略有差异)
- 漂浮幅度:上下约6-10px,周期2-3秒,
ease-in-out缓动
点击交互
- 选中气泡:高亮放大(scale 1.1)→ 消散(opacity 0, scale 1.3),时长300ms
- 其他气泡:同时消散(opacity 0, scale 0.8),时长200ms
- 消散完成后进入下一题(同现有逻辑)
气泡样式
- 背景:
bg-white/10半透明,选中时bg-white/25 - 边框:
border border-white/30 - 文字:
text-white/90,选中时text-white - 圆角:
rounded-full,内边距px-5 py-2.5 - 布局:flex wrap居中,间距
gap-3
生日日期特殊处理
- 31个日期气泡分行排列,气泡稍小(
px-3 py-1.5 text-sm)
三、Session持久化
问题
现在session存内存(Map),PM2重启/部署新代码→数据全丢。
方案:文件持久化(JSON文件)
- 路径:
/root/Projects/lingjing/data/sessions/[sessionId].json - 写入时机:每次session更新后异步写文件
- 读取时机:
sessions.get(sid)miss时从文件读取并恢复到内存 - 清理:超过7天的session文件自动删除
数据结构(不变)
session对象原样JSON序列化存文件即可。
注意
- 写文件是异步的,不阻塞请求
data/sessions/目录需加入.gitignore
四、开发优先级
- Session持久化(影响可用性,先做)
- 后端API协议升级(返回type+options)
- System Prompt升级(教AI何时出选择题、固定采集题穿插时机)
- 前端气泡UI组件
- 前端chat页面接入新题型
五、文件改动范围
| 文件 | 改动 |
|---|---|
server.js | session持久化 + API返回格式升级 + System Prompt更新 |
app/chat/page.jsx | 新增题型渲染 + 气泡组件 + 点击动画 |
data/sessions/ | 新增目录(加入.gitignore) |
.gitignore | 新增 data/ |
v3.0 封版更新(2026-02-23)
已完成
- ✅ Session文件持久化:
data/sessions/<sid>.json,PM2重启不丢数据 - ✅ 混合题型API:返回
type: choice/text/fixed_gender/fixed_age/fixed_birth_month/fixed_birth_day - ✅ 气泡UI:错峰漂浮动画,点击高亮放大→消散,其他气泡同时消散
- ✅ fixed_birth_day允许紧跟fixed_birth_month(月日连续不拦截)
- ✅ 报告生成JSON结构修复(完整字段定义)
- ✅ /chat启动检测:已完成session直接跳报告页,不重复答题
Gitea
- 封版commit:3340b6a
v3.0 Bug修复记录(2026-02-23 下午)
Bug 1: 报告页JSON解析错误
- 现象:报告页显示
Unexpected token '<', "<!DOCTYPE"... is not valid JSON - 根因:旧sessionId在服务器上不存在,API返回404被前端当JSON解析
- 修复:报告页遇到
session_not_found显示友好提示"找不到你的报告记录"+重新开始按钮
Bug 2: 分享链接标题错误
- 现象:别人打开分享链接看到"你的灵镜报告"
- 修复:根据isOwner判断,本人看"你的灵镜报告",别人看"ta的灵镜报告"
Bug 3: 分享链接显示分享按钮
- 现象:B用户看A的分享报告,也能看到"分享给朋友"和"重新开始"按钮
- 修复:分享+重做按钮仅isOwner可见,非本人只显示底部"开始我的灵镜报告"引导
Bug 4: 图片识别不可用
- 根因:openclaw.json的模型定义缺少
"input": ["text", "image"] - 修复:给claude-opus-4-6和claude-sonnet-4-6加上image input声明
Bug 5: 小周SSH被ban
- 根因:fail2ban封了小周IP(34.84.9.167)
- 修复:解封+加入jail.local白名单
isOwner判断逻辑
localStorage.getItem('lingjing_sid') === URL中的sessionId→ 本人- 不相等或不存在 → 别人(分享链接访客)
Gitea
- bug修复commit:dfce4fc