wanghanlin
|
2001dc3a0f
|
fix(doc): 修复重新处理文档会按 2000 字截断预览重建导致内容丢失
问题
- knowledge_document.content 上传时被截断到 2000 字符(有意的预览设计),
但 reprocessDocument 把它当原文重建分块,而 DocumentProcessingService 以
cleanBeforeFirstAttempt=true 运行(先删光旧向量)——对超过 2000 字符的文档
执行 POST /document/batch/reprocess 会永久丢失其余内容
修复
- content 改存原文全文(列已是 TEXT,无需 DDL),并写 extra_config.contentComplete
作为完整性标记
- 实体 content 加 @JsonIgnore:全文任何接口都不返回(否则 GET /document/list
无字段投影,每行都会带上整篇正文);文档详情接口单独组装响应,返回 2000 字预览
(键名仍是 content)与 contentTruncated 标志,前端据此提示截断
- reprocessDocument 的数据源按优先级解析:
1) 有 contentComplete 标记 → 用库内全文(语义最忠实,JSON 的 fields/pointer
模式不受影响,也不依赖文件是否还在)
2) 历史遗留文档(无标记,content 是截断预览)→ 按 fileType 从原始文件重解析
(md → MarkdownDocumentLoader,json → JsonDocumentLoader,其余 → Tika),
成功后回填全文并打标记,此后不再依赖原始文件
3) 两者都不可用 → 明确报错拒绝,绝不静默按截断预览重建
无法完整还原时在标记 PROCESSING 之前抛错,事务回滚,文档状态与已有向量都不受影响
- contentTruncated 判据覆盖历史数据:长度恰好等于上限且无 contentComplete 标记时
同样判定为已截断,避免把截断预览误报成完整内容
- 同步 content 列注释(DatabaseInitConfig / init-database.sql / knowledge-base.sql),
该注释会在下次启动幂等刷新到库
验证(真实库 + 557 篇存量文档环境)
- 上传 4891 字符正文:库内存全文,详情接口返回 2000 字预览 + contentTruncated=true
- 重新处理:chunk_count 与首次完全一致(修复前会降为个位数),内容无丢失
- 模拟历史数据(截断 + 无标记):有文件时从文件重解析成功并回填全文;
文件也丢失时明确拒绝,且文档状态与 chunk_count 保持不变(向量未被破坏)
- 回填后再删文件重跑仍成功(已自愈);GET /document/list 不再含 content
- RAG 对话回归正常
已知降级
- JSON 的 basic/fields/pointer 解析模式上传时未持久化,历史 JSON 文档从文件重解析
只能按 basic 还原(不丢数据,仅抽取口径可能变化,日志有 WARN)
- 存量中疑似被截断的文档需重跑一次才能回填全文(均已保留原始文件,均可恢复)
|
2 days ago |
wanghanlin
|
f71e83bf7c
|
refactor(frontend): 消息提示统一改用 TDesign 标准组件
- 删除 McpServerManager/ModelConfigManager 手写 fixed 浮层,连接测试结果改用 toast()(MessagePlugin)
- 按钮加载态统一使用 :loading 替代 emoji/纯文字切换(刷新连接、测试连接、获取模型)
- 登录错误、文档详情错误提示改 t-alert;目录树 / AI 执行链加载态改 t-loading
- 导出图片等提示统一走 utils/toast,移除 PipelineFlow 对 MessagePlugin 的直接 import
- 同步清理死代码与孤立样式(components.d.ts 补登记 TAlert)
|
4 days ago |
wanghanlin
|
a7d0ad87c9
|
feat(doc): 文档列表目录树默认收起并移除标签筛选
- 目录树去除 expand-all,初始仅显示分类、子目录折叠,点击展开
- 移除工具栏「全部标签」下拉及其数据源链路:filterTag/tagOptions、
api 的 listDocuments tag 参数与 getTagList、store 的 tags/loadTags、
路由守卫预加载
- 后端删除 /document/list 的 tag 参数过滤与 /tag/list 聚合接口
(getTagList 实现一并移除)
- 文档自带 tags 属性、行内/详情展示、向量 metadata 均保留不变
|
1 week ago |
wanghanlin
|
6c35aa0ff6
|
style(frontend): 上传页让「选择文件夹上传」与「选择文件」按钮同行显示
将独立成行的文件夹上传按钮并入 t-upload file-flow 的 trigger 插槽,
与「选择文件」按钮并排一行,消除上传区顶部孤零按钮的松散观感。
- 文件夹上传:@click.stop.prevent 触发独立 webkitdirectory input
- 选择文件:调用官方实例方法 uploadRef.triggerUpload() 打开多文件选择器
- 两个入口各自触发、互不误触;拖拽卡与底部上传按钮逻辑保持不变
|
1 week ago |
wanghanlin
|
06edac2738
|
feat(frontend): 文档列表位置列显示目录路径并修复一屏滚动布局
- 文档列表分类列改为「位置」列:沿 folderMap 回溯 parentId 拼出目录路径(不含分类名),直接挂分类根显示 —,长路径省略号截断+悬停 title 看全
- 修复文档卡片一屏高度布局:补 .t-loading__parent 参与 flex 高度链,目录树/表格在面板内滚动不再撑高整页
|
1 week ago |
wanghanlin
|
459cabb1bc
|
fix(mcp-server): 修复启用开关触发 toggle/refresh 请求死循环
- 前端 toggleMcpServer 补发 { active } 请求体,与后端 @RequestBody 契约一致(此前 active 拼在 query、无 body,每次点开关必 400)
- 后端 toggleActive 兼容 query 兜底,避免旧调用方仍 400
- axios 拦截器加重试上限(_retry),刷新改用裸 axios 发起,切断 401→refresh→重试 自激递归
- MCP 开关失败回滚 _active 状态并加 _toggling 防连点
|
1 week ago |
wanghanlin
|
9896dec82a
|
feat(frontend): DocList 目录树支持拖拽宽度与更多操作菜单,接入 BaseTable
目录树宽度可拖拽调节(分隔条)并将节点操作收敛为 t-dropdown 更多菜单(新建子目录/重命名/删除);文档表格接入 BaseTable,改为固定表头 + 内容超高内部滚动(基于视口 calc 高度)。因与目录树样式在同一段 CSS 中交织,同文件一并提交
|
1 week ago |
wanghanlin
|
97f9befc6d
|
refactor(frontend): 统一列表表格为 BaseTable 组件
新增 BaseTable 封装 t-table,统一下发小尺寸/悬浮/占满宽度/固定表头,操作列自动右固定,替换 13 个列表页 t-table,补齐缺失 loading;同步 UI 开发准则与组件声明
|
1 week ago |
wanghanlin
|
1ea991e5b8
|
fix(frontend): 全局重置 body margin 消除页面多余滚动
浏览器默认 body margin:8px 未清零,导致 .layout-container(100vh) 与登录页 min-height:100vh 超出视口出现滚动条及四周白边。在 shared.css 顶部新增全局基础重置(margin/padding 清零 + box-sizing:border-box)。
|
2 weeks ago |
wanghanlin
|
2668b8e73b
|
feat(document): 文档列表支持移动到目录(统一分类根/目录)
- 后端 moveDocuments 统一移动:目标为目录时校验存在并强制采用目录所属分类,分类变更时同步 vector_store 的 categoryId metadata
- DocumentController 批量移动接口新增 folderId 参数(extractLong 兼容雪花 ID 字符串)
- 前端 DocList 新增单行/批量「移动」弹窗,复用目录树 t-tree 选目标,替换原「移动分类」
|
2 weeks ago |
wanghanlin
|
f06422d5e9
|
docs: 补充开发规范与踩坑记录
- 列表排序字段白名单、vector_store 物理删除、数据库初始化幂等自愈、Java 文本块拼 SQL 等规则
|
2 weeks ago |
wanghanlin
|
1ffd960377
|
feat(document): 目录树独立滚动与文件夹上传完善
- 文档列表目录树独立滚动
- 上传页目录选择器改为先选分类再选目录
- 文件夹上传标题剥离目录前缀(原样文件名)
- 部分文件失败时弹窗按原因分组展示失败明细
|
2 weeks ago |
wanghanlin
|
dc8aa7a9d1
|
refactor(backend): 列表排序字段白名单统一走 SortUtils 防 SQL 注入
- 新增 SortUtils.resolveColumn 统一排序字段白名单映射,未知字段回退默认列
- 各 Controller/Service 列表接口新增 sortField/sortOrder 参数并接入白名单
- 前端列表页列加 sorter 并透传服务端排序参数
|
2 weeks ago |
wanghanlin
|
367ec79401
|
fix(document): 修复文件夹上传连接池耗尽与目录树独立滚动
- 移除 DocumentProcessingService 异步方法上的跨方法事务,AI 关键词提取/向量化期间不再占用数据库连接,避免文件夹批量上传时连接池被占满超时
- 新增有界 documentExecutor 线程池,替代默认无界 SimpleAsyncTaskExecutor,防线程爆炸与大模型限流
- 文档列表页目录树与列表改为左右独立滚动
|
2 weeks ago |
wanghanlin
|
780917561b
|
feat(document): 新增知识库文档目录(文件夹)功能
- 新增 KnowledgeFolder 实体/Mapper、FolderService、FolderController,支持目录树增删改查
- 文档新增 folderId 字段,列表支持按目录筛选与服务端排序
- 新增文件夹批量上传(按相对路径自动创建子目录)
- 文档列表页新增左侧目录树面板,上传页新增目录选择与文件夹上传
|
2 weeks ago |
wanghanlin
|
9d5fe80fb3
|
fix(upload): 修复文档上传多文件失效与 401 跳登录
- 上传改走 axios 复用 401 自动刷新,显式 multipart/form-data 修复 MultipartException
- DocUpload 文件 Tab 加 multiple,上传 handler 按 TDesign requestMethod 契约重写
- AuthController 的 refresh cookie Secure 属性按请求 scheme 动态判断,HTTP 自动降级
- application.yml / application-dev.yml 统一 refresh-cookie-secure 配置
|
2 weeks ago |
wanghanlin
|
1986500321
|
style(frontend): API Key 角色绑定弹窗简化角色名展示
角色绑定弹窗 checkbox 仅展示角色 name,移除冗余的 roleKey 显示
|
2 weeks ago |
wanghanlin
|
a2dff86923
|
feat(rag): FAQ 匹配支持分类隔离并在闲聊意图前精准匹配
FaqMatchEngine 三级匹配(精确/关键词/语义)新增 categoryIds 分类过滤,授权分类与未分类 FAQ 可见;ChatPipeline 闲聊(CHITCHAT)意图前先尝试 FAQ 精准匹配,命中则短路返回标准答案;同步更新 PipelineFlow 架构图
|
2 weeks ago |
wanghanlin
|
5856237746
|
fix(frontend): 移除分类管理列表中的文档数量显示
|
3 weeks ago |
wanghanlin
|
9338fcbd5f
|
feat(security): JWT token_version 服务端撤销与登录安全加固
- 新增 token_version 服务端撤销机制:改密/禁用/角色变更/登出时自增,使已签发 token 立即失效
- refresh token 从 localStorage 迁移到 httpOnly Cookie,access token 有效期缩短至 15 分钟
- 新增登录失败锁定(LoginAttemptService)与密码强度校验(PasswordValidator)
- SDK JWT 密钥支持环境变量注入,使用默认密钥时告警
修复:
- assignRoles 角色未变化仍自增 token_version,导致用户新建用户时 token 被误失效而跳转登录
- 角色 ID 解析兼容前端字符串传输,避免雪花 ID 精度丢失导致 ClassCastException
- updateFill 改用 setFieldValByName,修复 update_time 未自动填充的问题
|
3 weeks ago |
wanghanlin
|
f0325d8f2d
|
feat(frontend): AI 执行链页面新增导出图片功能
- PipelineFlow.vue 增加导出 PNG/SVG 按钮,支持将当前渲染的流程图导出为高清图片
- 同步更新 static/sdk/test.html 构建产物资源引用
|
3 weeks ago |
wanghanlin
|
d6a20f228a
|
feat: 支持图片/附件 SFTP 上传、多模态对话与 FAQ Markdown 编辑器
后端:
- 新增 SFTP 附件上传服务与 /attachment/upload 接口
- 新增 StorageProperties 集中化存储配置(支持 DataSize 50MB)
- ChatContext 新增 imageUrls,AI 调用链路透传多模态图片
- AssistantApp 构造 UserMessage(text, Media) 实现视觉输入
- ContentSafetyAdvisor MASK 脱敏时保留原消息图片 Media
- 配置拆分到 application-dev.yml / application-prod.yml(对齐参考项目)
前端:
- 对话面板支持图片/附件上传与缩略图/下载链接展示
- chat.ts 透传 imageUrls,chatAdapter 增加 Attachment 模型
- FAQ 编辑器替换为 md-editor-v3,支持粘贴图片自动上传
- FAQ 表格答案摘要去除 markdown 语法
- UI-DEV-GUIDE 补充 FormDrawer 使用规范
|
3 weeks ago |
wanghanlin
|
a1328994a5
|
feat(mcp): MCP 服务配置支持自定义请求头鉴权
- mcp_server_config 新增 headers JSONB 字段,SSE 模式通过 customizeRequest 注入请求头
- 敏感头(Authorization 等)返回前脱敏,更新时未改动保留原值
- DatabaseInitConfig 与 init-database.sql 同步新增 headers 列迁移
- McpClientManager 增加 @DependsOn(databaseInitConfig) 保证列迁移先于客户端加载
- 前端 MCP 配置弹窗新增请求头输入框
|
4 weeks ago |
wanghanlin
|
e23b70ffca
|
feat(client): SDK 界面重构改用 TDesign Web Components 组件
- 聊天核心:消息气泡/输入框/操作栏/加载态改用 t-chat-message/t-chat-sender/t-chat-action/t-chat-loading
- 外围 UI:知识库下拉/推荐问题/离线横幅改用 t-select/t-tag/t-alert
- Markdown 渲染由 t-chat-item 内置 cherry-markdown 承担,移除自研 marked 渲染器与 marked.min.js
- 构建管线:引入 tdesign-web-components@1.2.10 按需打包,mermaid 用本地 stub 替换省约 1.2MB
- 清理重构后死代码与死样式(escapeHtml/getLocale/appendStreamingCaret/offlineBannerEl 等)
- 同步更新测试面板断言(T3/T6/T10 适配 t-chat-sender)与 README/CLAUDE.md
|
4 weeks ago |
wanghanlin
|
b9f91d0903
|
fix(sse): 修复 SSE 鉴权头覆盖问题并同步测试用例文档
- sse.ts authHeaders 仅当调用方未显式提供 Authorization 时才注入管理后台 token,避免覆盖测试面板传入的 SDK Token
- client/README.md、client/CLAUDE.md 同步测试用例数量 22 → 10
|
4 weeks ago |
wanghanlin
|
8132f26891
|
feat(sdk-test): 测试面板重构为 Vue 3 + TDesign Chat 应用
- 新增 Vite 多页入口 sdk-test.html 与 SdkTestPanel.vue,用 TDesign Chat(ChatList/ChatSender/ChatActionbar)渲染对话演示
- 对话演示直调 GET /ai/chat/stream(OpenAI 格式),复用 readSSEStream 解析 delta.content,支持同步/流式、RAG 开关与来源展示
- SDK 集成验证区精简为 10 个核心用例,接口统一迁到新路径 /ai/chat*
- cp-to-static.mjs 构建后将 sdk-test.html 移动到 static/sdk/test.html
|
4 weeks ago |
wanghanlin
|
60d336d384
|
fix(前端): 反馈看板时间列统一 formatDate 格式化
- 反馈看板「时间」列改用 formatDate 输出 YYYY-MM-DD HH:mm:ss,空值显示 -
- 提示词追踪移除重复的 fmtDateTime 内联实现,复用统一 formatDate
- 反馈看板新增「补充说明」列及消息详情补充说明展示
|
4 weeks ago |
wanghanlin
|
b0319392a2
|
feat(client): 前端与 SDK 迁移新对话接口并支持 OpenAI SSE 解析
- 前端 chat.ts 合并为 chatSync/chatSSEUrl/ragSources 三个函数,统一走 /ai/chat、/ai/chat/stream、/ai/chat/sources,用 ChatOptions + enableRag 布尔参数统一普通/RAG 路径
- 前端 sse.ts 新增 extractOpenAIDelta 解析 choices[0].delta.content,识别 error chunk,JSON 解析失败回退纯文本,旧纯文本流向后兼容
- ChatPanel.vue 将 RAG sync/SSE/普通 sync/SSE 四分支合并为 sync/SSE 两分支
- SDK api.ts 迁移 URL 至 /ai/chat 系列,chatSSERequest 抽取 emitRawChunk 解析 OpenAI delta 与 error,正确处理 data: [DONE]
|
4 weeks ago |
wanghanlin
|
953a3c96ab
|
fix(chat): 修复 ChatList 消息显示为骨架屏的问题
ChatList 内部会把任何 truthy 的 status 强制重写为 "pending",
导致所有历史消息都显示为骨架屏。移除 chatAdapter 中的 status 字段,
由 ChatPanel.vue 的 #content slot 自行控制流式/错误态渲染。
|
4 weeks ago |
wanghanlin
|
7f6b696885
|
refactor(chat): 使用 TDesign Chat 组件重构聊天面板
安装 @tdesign-vue-next/chat@0.6.0 并新增 chatAdapter.ts 统一消息格式适配;
将 ChatPanel.vue 的手写消息列表、输入框与操作栏替换为 ChatList/ChatSender/ChatActionbar,保留 SSE、RAG、MCP、反馈、推荐问题、编辑及重新生成等业务逻辑;
同步优化 vite.config.ts 的 manualChunks,将 tdesign-chat、tdesign-web-components 与 tdesign 拆分为独立 chunk。
|
4 weeks ago |
wanghanlin
|
23f195326d
|
feat(llm-trace): 提示词追踪增强与缺陷修复
新增追踪字段与落库链路:
- FAQ 命中详情(faqId/faqQuestion/faqMatchType/faqScore)
- 错误分类(errorType/errorMessage)与 Token 用量三档
- MCP 工具调用事件(toolCallsJson)、多轮历史(historyMessagesJson/historyTurns)
- RAG 命中片段(ragHitsJson)、检索模式(searchMode)、账户/API Key
- 数据库迁移新增 13 列 + 3 索引,同步 init-database.sql
前端增强:
- 筛选新增 API Key / 错误类型下拉,列表新增 RAG 列与刷新按钮
- 详情 Tab 扩展 FAQ / 工具调用 / 对话上下文,Prompt 关键词搜索高亮
- 新增会话时间线抽屉、调用趋势图(Chart.js 双轴折线)
缺陷修复:
- MCP 工具事件采集改用 ToolContext 显式收集器,修复 Reactor 流式跨线程丢 ThreadLocal 导致 toolCallsJson 为空
- 趋势统计 GROUP BY 别名改为 date_trunc 表达式,修复 PostgreSQL 语法错误
- 详情表格移除重复 row-key,新增 /error-types 与 /trend 接口
|
4 weeks ago |
wanghanlin
|
2fe322aa7d
|
完成「LLM 调用追踪面板」开发
|
4 weeks ago |
wanghanlin
|
4438545693
|
TDesign 术语对齐
|
4 weeks ago |
wanghanlin
|
61fc637992
|
TDesign 术语对齐
|
4 weeks ago |
wanghanlin
|
add8b3fd05
|
chore(deps): 升级 TDesign UI 组件库至最新版
- tdesign-vue-next: ^1.10.6 → ^1.20.6
- tdesign-icons-vue-next: ^0.3.6 → ^0.4.9
|
4 weeks ago |
wanghanlin
|
45d34e76d1
|
优化前端配色
|
4 weeks ago |
wanghanlin
|
d6be720965
|
按 ui-ux.md 规范重设计「系统配置」页
|
4 weeks ago |
wanghanlin
|
61b0ae5639
|
feat(sensitive-word): 敏感词管理页布局与交互优化
- 工具栏新增级别筛选、统计提示,表格新增备注/更新时间列
- 状态列改为 t-switch 一键启用/禁用(失败自动回滚)
- 编辑弹窗加宽并新增启用开关、保存 loading、必填校验
- 批量导入提示成功/跳过重复数,删除确认带词内容
- 后端 list 接口新增 level 级别过滤参数
|
1 month ago |
wanghanlin
|
7222893120
|
feat(role): 客服角色管理页布局优化并支持 MCP 工具全选
|
1 month ago |
wanghanlin
|
6590ac762d
|
feat(role): 客服角色 MCP 工具授权
- 修正 allowedMcpTools 空列表语义:仅无角色(null)回退为全部,空列表=严格禁止
- 三个对话入口区分「无角色」与「角色无授权」,无角色向后兼容允许全部
- 工具注册名引入 configId 命名空间(mcp_<configId>_<name>),避免跨 Server 同名工具冲突
- 新增 GET /mcp-server/tools 接口,返回按 Server 分组的可用工具清单
- 更新角色 MCP 授权后清理 AssistantApp ChatClient 缓存,改动即时生效
- listRoles 解析 allowed_mcp_tools JSONB 为 string[],避免 PGobject 原样返回
- 前端 RoleManager 新增「MCP 工具授权」区块,接入保存/脏检测/全部授权
|
1 month ago |
wanghanlin
|
7ce8028d73
|
重构客服角色管理页面排版
|
1 month ago |
wanghanlin
|
1dc9cc9fe6
|
修复保存faq报错问题
|
1 month ago |
wanghanlin
|
d5585206cf
|
新增反馈运营看板删除功能
|
1 month ago |
wanghanlin
|
1ed6c8fb43
|
新增反馈运营看板
|
1 month ago |
wanghanlin
|
b5abf32530
|
迁移到 TDesign 架构时漏掉了文档上传路由和菜单入口
|
1 month ago |
wanghanlin
|
1fe6a19366
|
修复:TDesign <t-space> 内部 v-if 导致按钮动作错位
|
1 month ago |
wanghanlin
|
fc1193c4f3
|
完成了 AI 执行链流程图的 5 项差异修正,并建立了三层持续同步机制(CLAUDE.md 规则 + Stop Hook + JavaDoc 标记)
|
1 month ago |
wanghanlin
|
bfb5a66393
|
AI回复增加推荐问题功能
|
1 month ago |
wanghanlin
|
ba933825d4
|
优化打包、编译速度
|
1 month ago |
wanghanlin
|
149dc3270c
|
新增日志查看功能
|
1 month ago |