|
|
69b9694cfe
|
fix: 修复“设置”侧栏双重展开的问题
|
2026-06-22 13:02:05 +08:00 |
|
|
|
03a19befe1
|
fix: 修复前端侧边栏无法平滑弹出的问题
|
2026-06-22 12:53:09 +08:00 |
|
|
|
4cc0713459
|
fix: 修复空会话返回 null 导致前端崩溃的问题
## 问题描述
当用户创建新会话但未发送任何消息就切换到其他会话时,前端控制台报错:
"TypeError: Cannot read properties of null (reading 'map')"
根本原因:Go 后端未初始化的切片序列化为 JSON 时会变成 `null` 而非 `[]`,
前端尝试对 `null` 调用 `.map()` 导致崩溃。
## 修复方案
采用多层防御策略,同时修复后端和前端:
### 后端修复(确保 API 契约正确)
1. message_pg.go:93 - 将 `var messages []StoredMessage` 改为
`messages := make([]StoredMessage, 0)`,确保空结果序列化为 `[]`
2. conversation.go - 在两个响应路径(PG 查询 + 内存回退)添加防御性 nil 检查
### 前端防御(多层保护)
1. useSessionList.ts - 在 loadMessages 和 loadSessions 中添加 null 合并操作
`(res.data.messages || [])` 确保即使后端退化也不会崩溃
## 影响范围
- 所有空会话(新建后未发送消息的对话)现在可以正常切换
- API 响应符合 JSON 最佳实践(数组字段永远是 `[]` 而非 `null`)
|
2026-06-22 12:39:37 +08:00 |
|
|
|
2180751a9b
|
fix: 修复前端侧边栏双重展开动画问题
移除条件渲染和 CSS animation 的冲突,改用纯 CSS transition 控制显示/隐藏。
**问题根源:**
- 组件使用 `if (!open) return null;` 条件渲染,导致挂载时立即出现
- CSS 同时使用 `animation: slideInLeft`,触发从 -100% 的二次滑入
- 两个独立显示机制叠加,造成双重动画闪烁
**修复方案:**
- SessionSidebar: 移除条件渲染,始终保持 DOM 存在,通过动态 className 控制状态
- App.css: 移除 `animation` 和 `@keyframes`,改用 `transition: transform`
- 新增 `.sidebar--collapsed` / `.sidebar--open` 类控制 `translateX`
- 新增 `.sidebar-backdrop--visible` 类控制背景遮罩淡入淡出
- 添加 `pointer-events: none` 确保隐藏状态不响应交互
影响范围:
- frontend/src/components/SessionSidebar/index.tsx
- frontend/src/App.css
|
2026-06-22 12:05:54 +08:00 |
|
|
|
6bca4e0d47
|
fix: 修复前端侧边栏弹出异常问题
|
2026-06-22 11:15:41 +08:00 |
|
|
|
1b99d24fc1
|
fix: 修复前端 TypeScript 编译错误
- 移除 App.tsx 中未使用的 activeScenario 变量
- 修复 ChatPanel 中 ReactNode 的 type-only import
- 移除 ChatPanel 中未使用的 onSelectScenario 参数
修复 CI 构建失败问题
|
2026-06-22 00:28:59 +08:00 |
|
|
|
e24fb2cc19
|
refactor: 将情景图标和设备选择器的 emoji 统一替换为 SVG 图标
- 新增 scenarioIcons.tsx 提取情景图标渲染逻辑
- 情景芯片、设备选择器、警告提示等 emoji 全部改为 Feather-style SVG
- 调整 CSS 确保 SVG 图标居中对齐
|
2026-06-21 23:50:27 +08:00 |
|
|
|
6cbabb63bb
|
refactor: 情景选择从卡片网格改为横向滚动芯片条
- 将 scenario-picker 网格布局改为 scenario-strip 横向滚动芯片条
- 新增「新建情景」快捷入口芯片(+按钮)
- 新增 scenario.createChip 三语言翻译键
|
2026-06-21 23:23:22 +08:00 |
|
|
|
949a707e0f
|
refactor: 重构视频面板 UI,情景选择改为卡片网格,控制按钮改为 SVG 图标
- 情景选择从 ChatPanel header 下拉菜单迁移至视频面板下方卡片网格
- 摄像头/麦克风按钮改为圆形 SVG 图标按钮
- 识别/中断/停止按钮改为药丸形状 SVG 图标按钮
- 设备选择器改为水平布局,优化空间利用
- 移除 ChatPanel 空状态中重复的情景卡片
- .gitignore 忽略 .claudian/ 和笔记目录
|
2026-06-21 22:58:02 +08:00 |
|
|
|
6967dd7b2e
|
feat: 实现摄像头和麦克风设备选择功能
- 新增 useDeviceList hook,枚举音视频输入设备并监听热插拔
- CameraManager/MicManager 的 startCamera/startMic 支持可选 deviceId 参数
- useVisionSession 集成设备选择:授权后自动枚举、切换设备时热重启
- 连接后显示设备下拉选择器,未连接时隐藏(避免未授权时空列表)
- SessionConfig 新增 cameraDeviceId/micDeviceId 持久化到 localStorage
|
2026-06-21 16:49:48 +08:00 |
|
|
|
eea5c07eaa
|
refactor: 删除实时分析/按需识别/纯聊天三种模式切换
三种模式仅为前端 UI 区分,后端无感知,实际使用中价值不大:
- 纯聊天模式名不副实(VAD 仍附带摄像头帧)
- 实时分析增加 API 成本且体验不佳
- 按需识别已是默认且最自然的交互方式
删除后保留按需识别行为:语音带图 + 手动识别按钮,UI 更简洁。
|
2026-06-21 16:24:09 +08:00 |
|
|
|
1079e22699
|
feat: 实现自建情景功能
## 功能概述
- 用户可创建、编辑、删除自定义情景
- 支持自定义情景名称、图标、描述、Prompt、首句引导
- 完整的权限隔离,用户只能管理自己的情景
- 深度集成 Eino 框架,动态加载自建情景 Prompt
## 后端实现
### 数据库
- 新增 user_scenarios 表
- 支持用户配额(最多 20 个)
- 字段验证:description 可选,prompt 最小 10 字符
### API
- GET /api/scenarios - 获取用户情景列表
- POST /api/scenarios - 创建情景
- GET /api/scenarios/:id - 获取详情
- PATCH /api/scenarios/:id - 更新情景
- DELETE /api/scenarios/:id - 删除情景
### Eino 集成
- PipelineState 添加 UserID 字段
- nodes_history 动态加载用户自建情景
- GetScenarioPrompt 支持自建情景优先级
## 前端实现
### 组件
- CreateScenarioModal - 创建情景对话框
- EditScenarioModal - 编辑情景对话框
- ConfigPanel 改造 - 分组显示系统预置和自建情景
### Hook
- useScenarios - 合并系统和自建情景,提供 CRUD 接口
### 国际化
- 中文、英文、日文翻译支持
## 问题修复
- 修复 CORS 问题:使用 Vite 代理
- 统一验证规则:description 可选,prompt 最小 10 字符
- 修复数据库约束:使用 NULLIF 处理空字符串
## 文件变更
新增文件: 13 个
修改文件: 14 个
详见文档: docs/自建情景功能完整文档.md
|
2026-06-21 15:38:28 +08:00 |
|
|
|
9ad486d117
|
feat:部署修改
|
2026-06-20 23:35:13 +08:00 |
|
|
|
2fb23852ef
|
feat: 优化情景切换功能
|
2026-06-20 23:24:32 +08:00 |
|
|
|
ed95ce56a8
|
fix: 关闭摄像头后文本输入不再发送图像数据
修复了用户关闭摄像头后,使用文本输入时 AI 仍会分析黑色画面的问题。
变更:
- sendTextMessage: 只在摄像头开启时捕获画面
- 待发消息队列: 根据摄像头状态决定是否携带画面
效果:
- 摄像头关闭时纯文本对话,不提及画面
- 节省 token 消耗和网络带宽
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-06-20 22:21:03 +08:00 |
|
|
|
e37dc7074d
|
chore: 首页代码仓库链接改为 Gitea 地址
|
2026-06-20 21:12:06 +08:00 |
|
|
|
9ba4eb4825
|
Merge pull request 'feat: 优化对话历史功能、增加首页登录页面' (#155) from feat/historychat into develop
Reviewed-on: http://8.161.227.145:3000/XEngineers/CamTalk/pulls/155
|
2026-06-20 20:06:39 +08:00 |
|
|
|
ab07e01adf
|
feat: 优化对话历史功能
|
2026-06-20 19:57:36 +08:00 |
|
|
|
12e2d24f37
|
fix: checkout 后显式 git fetch 切换触发分支,避免始终部署 main 代码;Dockerfile 添加 BuildKit cache mount 加速构建
|
2026-06-20 17:43:32 +08:00 |
|
|
|
2a7d4c74d4
|
feat:增加首页登录页面
|
2026-06-20 17:35:14 +08:00 |
|
|
|
3572b867c0
|
Merge pull request 'feat: 完善鉴权模块' (#142) from fix/auth into develop
Reviewed-on: http://8.161.227.145:3000/XEngineers/CamTalk/pulls/142
|
2026-06-20 16:34:47 +08:00 |
|
|
|
970f10a274
|
fix: 修复前端 lint 错误 — 移除 ref 模式,用 useEffect 依赖注入回调
- api.ts: 移除 catch 中未使用的 err 变量
- auth.tsx: 去掉 useRef 模式,直接在 useEffect 中注册回调并声明依赖
|
2026-06-20 15:07:09 +08:00 |
|
|
|
d78cdb509d
|
feat: 前端 401 拦截器 — access token 过期时自动刷新并重试原请求
api.ts:
- 增加 setAuthCallbacks 回调注入机制(避免 api/auth 循环依赖)
- request() 对非公开路径自动附加 Authorization header
- 收到 401 时自动触发 refresh token 刷新,成功后重试原请求
- 并发保护:多个 401 只触发一次 refresh,其余等待同一 Promise
- refreshTokenDirect 内部方法绕过 401 拦截避免递归
auth.tsx:
- 用 ref 保存 persistAuth/scheduleRefresh 最新引用(避免闭包陈旧)
- 初始化时调用 setAuthCallbacks 注入认证回调
|
2026-06-20 14:57:27 +08:00 |
|
|
|
50c84fce88
|
fix: 修复新对话首次打字出现两个输入框
根因:sendTextMessage 断开状态时立即 setMessages 添加用户消息到 UI,
同时 connect() 触发连接成功后 flush useEffect 再次 setMessages 添加同一条消息,
导致消息重复、ChatPanel 渲染出两个输入区域。
修复:断开状态时只入队不立即显示,由 flush 统一处理。
|
2026-06-20 14:32:40 +08:00 |
|
|
|
ae09fba400
|
fix: 修复聊天输入框 flex 布局导致重复渲染
- chat-input__field 增加 min-width: 0 防止 flex 项溢出
- chat-input__send 增加 flex-shrink: 0 防止按钮被挤压换行
|
2026-06-20 14:24:52 +08:00 |
|
|
|
f8a79a3b0b
|
fix: 修复文字对话态误显「正在初始化语音检测」
ChatPanel VAD 初始化提示条件增加 isCameraOn 判断,
视频结束后不再显示语音检测初始化提示。
|
2026-06-20 14:04:20 +08:00 |
|
|
|
ae9a27c300
|
feat: 结束视频后保留对话,支持继续文字聊天
- useVisionSession 新增 stopVideo 回调(停媒体流,保持连接和消息)
- App.tsx 控制区从二态改为三态(initial/video/textOnly)
- 文字对话态显示「重新开始视频」和「结束会话」按钮
- 新增 CSS 样式(video-ended-hint、btn--outline)
- 新增 i18n key(stopVideo/endSession/resumeVideo/video.ended)
- 新增设计方案文档
|
2026-06-20 13:48:26 +08:00 |
|
|
|
c2bae4e3b7
|
feat:部署优化
|
2026-06-14 21:28:18 +08:00 |
|
|
|
083ede8b6d
|
feat: 部署优化
|
2026-06-14 21:24:11 +08:00 |
|
|
|
057a226610
|
Merge remote-tracking branch 'origin/develop' into feat/optimize
# Conflicts:
# frontend/src/lib/errors.ts
|
2026-06-14 20:40:05 +08:00 |
|
|
|
b60e513317
|
feat:添加对话情景功能
|
2026-06-14 20:32:30 +08:00 |
|
|
|
92e47718bc
|
fix: 修复 ChatPanel vadError 属性类型不匹配导致构建失败
|
2026-06-14 20:10:31 +08:00 |
|
|
|
44f4f3ce1a
|
Merge pull request 'feat:语音对话优化' (#106) from feat/onload into develop
Reviewed-on: http://8.161.227.145:3000/XEngineers/CamTalk/pulls/106
|
2026-06-14 19:55:02 +08:00 |
|
|
|
c3118dd72a
|
feat:语音对话优化
|
2026-06-14 19:54:22 +08:00 |
|
|
|
e11934cf70
|
fix: 移除未使用的变量和导入,修复 tsc 编译错误
|
2026-06-14 19:37:16 +08:00 |
|
|
|
1109ab41f7
|
refactor: 将退出登录功能从顶部导航栏移至设置面板
|
2026-06-14 18:42:47 +08:00 |
|
|
|
8de956719c
|
feat: 实现前端认证系统,WebSocket 连接携带 JWT token
- 新增 AuthContext/AuthProvider:登录/注册状态管理,JWT 自动刷新
- 新增 AuthPage 组件:登录/注册表单,支持模式切换和前端校验
- 新增 api.ts:封装 auth REST API 客户端(register/login/refresh/logout)
- WebSocket 连接时拼接 ?token=<jwt>,重连自动携带
- useVisionSession 接受 accessToken 参数并透传
- App.tsx 包裹 AuthProvider,未登录时显示登录页
- storage.ts 新增 token/user 的 localStorage 存储
- i18n 新增中/英/日三语 auth 翻译
- App.css 新增 auth 页面和用户 badge 样式
|
2026-06-14 18:38:45 +08:00 |
|
|
|
7a0443ebcc
|
style: 样式优化
|
2026-06-14 16:31:23 +08:00 |
|
|
|
fe053f94dc
|
fix: 隐藏观察模式按钮,清理未使用的 toggleMode 引用
|
2026-06-14 15:56:59 +08:00 |
|
|
|
9433612c4b
|
Merge pull request '聊天框与会话历史栏优化' (#91) from fix/language into develop
Reviewed-on: http://8.161.227.145:3000/XEngineers/CamTalk/pulls/91
|
2026-06-14 15:46:40 +08:00 |
|
|
|
92f3f45c41
|
feat: 新增会话历史侧边栏,支持新建/切换/删除/重命名会话
类似 ChatGPT 的侧边栏布局,消息历史持久化到 localStorage。
- 新增 SessionSummary 类型和 localStorage 读写函数
- 新增 useSessionList Hook 管理会话列表 CRUD
- 新增 SessionSidebar 组件(展开/折叠、行内重命名)
- App.tsx 协调 useSessionList 和 useVisionSession
- 消息变化时自动持久化,切换/新建会话时保存并加载
- 新增 i18n 翻译 key(中/英/日)
|
2026-06-14 15:44:25 +08:00 |
|
|
|
cb0c747133
|
ci: 添加国内镜像代理和 BuildKit 缓存优化构建速度
|
2026-06-14 15:14:28 +08:00 |
|
|
|
da8818c3be
|
fix: 隐藏顶部状态栏的 token 数显示
|
2026-06-14 15:10:43 +08:00 |
|
|
|
15b1dd56fa
|
feat: 聊天框与视频功能解耦,输入文字即可开始对话
之前必须点击「开始对话」连接 WebSocket 后才能使用聊天框。
现在聊天输入框始终可用,输入文字自动连接 WebSocket 并发送消息;
左侧按钮改为「开始视频通话」,单独控制摄像头/麦克风。
- ChatPanel 移除 !isConnected early return,始终显示输入框
- useVisionSession 新增待发消息队列,sendTextMessage 支持自动连接
- startSession 改为仅负责视频(摄像头 + 麦克风 + VAD)
- 修复 statusRef 在 useWebSocketManager 之前声明导致的 TDZ 错误
- 更新 i18n 翻译(新增 controls.startVideo、video.placeholder)
|
2026-06-14 15:07:39 +08:00 |
|
|
|
d32112e074
|
chore: 添加 .dockerignore 优化 Docker 构建上下文
|
2026-06-14 14:54:52 +08:00 |
|
|
|
e95b1603c1
|
feat: 前端 UI 国际化,支持中/英/日三语切换
之前语言设置只影响后端 AI 行为,前端 UI 文字始终为中文。
新增轻量 i18n 模块(React Context + 翻译字典),切换语言后所有 UI 文字即时刷新。
- 新增 i18n 核心模块和 zh-CN/en-US/ja-JP 翻译文件(约 72 个 key)
- App.tsx 拆分为 App(Provider)+ AppContent(业务),确保 Hook 可访问 Context
- 所有组件通过 useI18n().t() 获取翻译文本
- errors.ts 改为接受翻译函数参数
- storage.ts saveConfig 时派发事件通知 locale 变化
|
2026-06-14 14:34:30 +08:00 |
|
|
|
d8bbdb1744
|
Merge pull request 'fix: 修复语音与文字不同步的问题,改为句子级流式播放' (#67) from frontend-12 into develop
Backend CI / ci (pull_request) Failing after 2m14s
Deploy / verify (pull_request) Failing after 1s
Deploy / deploy (pull_request) Has been skipped
Frontend CI / ci (pull_request) Successful in 56s
Reviewed-on: http://8.161.227.145:3000/XEngineers/CamTalk/pulls/67
|
2026-06-14 13:55:47 +08:00 |
|
|
|
da5c727d8c
|
fix: 修复语音与文字不同步的问题,改为句子级流式播放
之前前端 TTSPlayer 攒齐所有音频片段后才播放,导致文字全部显示后才开始语音。
改为后端每句 TTS 发送 is_last: true,前端收到每句即加入播放队列,第一句到达即开始播放。
- 后端 Chunk 结构体新增 Final 字段,区分句子结束和整轮结束
- 前端 TTSPlayer 重写为队列式播放,onended 回调自动衔接下一句
- 同步更新接口文档和测试用例
|
2026-06-14 13:54:49 +08:00 |
|
|
|
7108d2a58b
|
feat: 添加前端 Dockerfile 和 Nginx 配置
- 多阶段构建:node:22-alpine 构建,nginx:stable-alpine 运行
- Nginx 配置:静态文件服务 + /api /ws 反代到后端
|
2026-06-14 13:38:22 +08:00 |
|
|
|
81c2b64e5f
|
fix: 修复无摄像头/麦克风时聊天框不显示的问题
- 重构 ChatPanel 逻辑,连接后始终显示输入框
- 将欢迎消息移入消息容器内
- 确保输入框在任何状态下都可见
|
2026-06-14 13:17:14 +08:00 |
|