657 Commits

Author SHA1 Message Date
kuaifan
6f22fd2706 fix(ai-assistant): respect model visibility settings 2026-07-20 10:48:33 +00:00
kuaifan
df6c1fc04d refactor(i18n): 完成前端国际化改造 2026-07-20 02:35:07 +00:00
kuaifan
966c7b4ef0 feat(microapp): iframe 同源 HTTP 5xx 检测与内联错误层,错误态强制显示胶囊
- iframe.vue 读 responseStatus 检测同源 5xx(宁可漏判不误判),与原生 error 统一走 load-error
- index.vue 新增可读的内联错误层(重试/关闭),覆盖深色下被反色成一条线的错误页
- 检测到错误时强制显示胶囊,保证关闭/更多入口
2026-07-16 06:26:39 +00:00
kuaifan
f45f86601e fix(ai-assistant): Modal 模式移动端恢复居中弹框,不再沉浸全屏
移动端仅聊天(chat)浮窗保留全屏沉浸,Modal 模式两端统一为居中模态,
回退 f6067d1bd 对 Modal 的移动端全屏处理;删除随之失效的
.ai-assistant-modal .is-mobile-fullscreen 样式块。
2026-07-01 07:39:50 +00:00
kuaifan
184fb27680 feat(upload): 分片上传统一链路,5 场景突破单文件 1G 限制
- 新增 api/upload/{init,chunk,merge} 入口与 ChunkUpload 模块(5MB 分片、3 并发、Redis 状态机)
- 5 场景接入:文件柜 / 聊天 / 任务附件 / 头像&系统图片 / 编辑器粘贴
- 秒传:同用户同 hash 复用 FileContent 物理文件,零传输
- 续传:Redis + localStorage 双索引,24h TTL
- 与老接口对齐:pid 锁、≤300 上限、webkit_relative_path 目录递归、overwrite 替换语义
- init 阶段读 file_upload_limit 拦截超限,避免传完分片才报错
- DeleteTmpTask 加 tmp_chunks case 兜底清理 24h 未合并目录
- files 表新增 hash 列(migration)
- 前端 chunkedUpload wrapper:主线程 spark-md5 流式 + 指数退避重试
- ai-kb 同步:upload / file-upload-limit / upload-size-limit 三个 chunk
2026-06-30 04:30:09 +00:00
kuaifan
420d46d5cc feat(apps): 新增应用菜单角标(数字/红点,per-user 实时推送)
插件/微应用可在自己的菜单入口显示数字或红点角标,插件未打开也生效。

- 后端:新增 app_badges 表 + AppBadge 模型 + Module/Badge 业务编排 +
  AppsController(badge__set 应用密钥鉴权 / badge__clear 用户鉴权)
- 每应用独立密钥 APP_SECRET:按 appid 持久化于 appstore config.yml,鉴权校验
- 推送:复用 PushTask 下发 appBadge WS 消息;microapp_menu 附带初始角标
- 前端:appBadges Vuex module + WS 处理 + 三处菜单渲染(应用卡片/主菜单入口/
  父『应用』入口聚合)+ 移动端 Tabbar + 打开即清(badge_clear_on_open)
- 用户离职级联清理;同步 ai-kb 角标知识
2026-06-29 02:32:19 +00:00
kuaifan
6a4f815d5a style(ai-assistant): 调整输出占位符的行高和内边距 2026-06-21 23:34:02 +00:00
kuaifan
aa872773f5 feat(ai-assistant): 添加用户消息展开功能,支持点击显示全部内容 2026-06-18 13:20:43 +00:00
kuaifan
8e591503dd feat(ai-assistant): 统一 AI 回复内链接导航时的浮窗策略
- 移动端:点任意 in-app 链接(task/project/file/contact/message/深链)一律关闭浮窗,避免全屏遮挡目标
- 桌面端:一律保留浮窗以便继续对话;若处于全屏则退出全屏让目标露出
- modal 模式:点链接一律关闭(居中弹窗会挡住目标)
- 策略集中到 AssistantModal.prepareForNavigate,DialogMarkdown 各链接类型统一调用 beforeNavigate

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 11:10:13 +00:00
kuaifan
7453b79c8d feat(ai-assistant): chat 浮窗接入全局模态栈支持 ESC/滑动返回关闭
- modal.vue: chat 模式新增空助理 Modal(mask=false 不挡背后操作),
  进入 ViewUI 模态栈,由 removeLast() 统一管理 ESC/滑动返回/返回键/Electron 关窗
- index.vue: 移除 onInputKeydown 内重复的 chat ESC 处理,改由全局栈统一处理
- modal.vue: 捕获阶段抢先拦截 ESC,chat 全屏时退全屏而非关闭栈顶 Modal
  (AI 浮窗 z-index 恒最高但未必是栈顶,故不能依赖 ViewUI 冒泡 ESC)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 10:50:18 +00:00
kuaifan
135b419572 fix(micro-apps): 修复深色主题下微应用自定义背景色显示错误
深色主题通过 html 整体 invert+hue-rotate 反色,导致配置的背景色被反成错误颜色。
改为在 iframe 铺底伪元素上承载真实背景色,并在深色下对该伪元素施加同款反向 filter
抵消整体反转,使背景与内容区反色行为一致,不再用 JS 近似反相。

- modal.vue:bodyStyle 通过 CSS 变量 --micro-body-background-color 传递真实色
- iframe.vue:.micro-app-iframe::before 铺底背景层 + 深色反向 filter,并加 isolation 隔离 z-index
- 移除不再需要的 utils/color.js 颜色反相工具

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 22:21:19 +08:00
kuaifan
a19822a617 feat(ai-assistant): 新增 close_app 动作支持关闭当前应用窗口
打开微应用后 AI 页面操作默认锁定在该应用 iframe 内部,无法关闭应用本身
(关闭控件在主程序外壳层)。新增外壳层 close_app 动作绕过 iframe 作用域:

- action-executor 注册 close_app,先用 store 状态判断有无打开应用(无则报错
  不假报成功),再经事件总线 observeMicroApp:close 投递给 MicroApps 组件。
- MicroApps 复用现成 onAssistClose(findLast(isOpen)+closeByName)作为该事件
  处理器,关闭最前打开的应用,零重复逻辑。
- page-context-collector 在有微应用打开时向模型注入 close_app 可用动作。
- 同步 ai-kb page-action chunk 与 events-map。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 03:09:38 +00:00
kuaifan
a3d5bdf93c feat(ai-assistant): 重构页面操作为统一执行器(Web DOM floor + Electron CDP 双后端)
页面操作(doo page → /ws → 浮窗 operation-module → action-executor)原用手写
iView-only 选择器 + 朴素 value= 赋值,在 React+Radix 同源 iframe 业务表单上几乎
填不进。重构为「复用 Playwright 注入脚本的描述层 + 按环境选后端的执行层」:

描述层(共用):
- 新增 aria/aria-bundle.js,vendoring Playwright ariaSnapshot/roleUtils/domUtils
  子集预构建为 ESM(Apache-2.0 NOTICE + 固定上游 commit),产出 YAML 快照与活的
  ref→Element Map。
- page-context-collector 改用 buildSnapshot 采集,operation-module 经 setRefMap
  以 Map 直接持有元素取代 selector 反查。

执行层(按环境选后端,失败回退):
- web-backend:原生 prototype value setter + beforeinput/input/change/blur 序列
  + 回读校验(不符报 value_not_applied,绝不假报成功);自定义下拉/日期 open→click。
- electron-backend + electron/lib/page-input.js:经 webContents.debugger 走 CDP
  Input 域产生 isTrusted=true 可信输入(insertText/dispatchMouseEvent/KeyEvent),
  任一步失败回退 Web 后端。
- 复杂控件(动态明细表/成员选择器/文件上传)如实返回 unsupported_widget。

协议与链路(doo page、active-context 失效守卫、导航类 action)保持不变。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 02:03:59 +00:00
kuaifan
b0a4fe6646 feat(ai-assistant): AI 回复增加复制/时间/反馈取消,历史删除二次确认
- 反馈行新增复制按钮(去推理段落)与回复时间(规则参考 formatMessageTime)
- 点赞/点踩支持再点取消;修复 feedbackLoading 持久化导致重载后无法再点
- 历史删除改为二次确认(垃圾桶→红勾),离开/3秒/下拉关闭自动复位,触摸端常显
- 回复完成后贴底用户自动滚动到底部,露出反馈按钮
- 后端 feedback__save 支持空 feedback 取消(删除记录),同步 ai-kb

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 22:58:50 +00:00
kuaifan
97bd58312e refactor(approve): 移除主仓库内置审批功能,收敛到插件/微应用
删除 ApproveController、ApproveProcInstHistory/ApproveProcMsg 模型、approve
前端页面与导出组件,移除 approve 路由与 flow_url 配置;审批消息模板改为对接
插件侧能力。版本号 1.7.90 → 1.7.91。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 11:35:49 +00:00
kuaifan
27c65cc582 fix(frontend): TagInput 体质优化与多分隔符支持 + 后端 saveOrIgnore 加固
TagInput:
- cut prop 支持字符串或字符串数组,多分隔符任一匹配即切;
  v-model 写回用第一个分隔符 (joinChar) 拼接保持向后兼容
- 修复 max 仅在 cut 分隔符路径生效,回车/blur/paste 路径未查 max 的 bug
- 修复 data() 初始化与 watch(value) 用硬编码 ',' 切分,
  统一走 joinChar (单一输出分隔符) 还原 v-model,避免含空格的列名
  (如项目模板 'Sprint 1') 被切碎
- 修复 watch(value) 空值/null 时不清空 disSource 的潜在残留数据
- v-for 加 :key='text',配合初始化去重避免拖拽错位
- 重复 tag 由静默忽略改为提示「该标签已存在」
- 编辑 tag 加 dedup 检查,重命名成已有 tag 文本时阻止关闭
- 粘贴改为按 cut 切分逐个 addTag;addTag 返回 boolean,
  pasteText 在 max 满时 break 短路
- splitByCuts/parseValue 拆分:回切用 joinChar,paste/输入用 cutPattern
- 拼接翻译 '最多只能添加X个' 改为 $L('最多只能添加(*)个', max);
  新增「最多只能添加(*)个」「该标签已存在」到 language/original-web.txt

manage.vue:
- 创建项目任务列表启用 :cut=\"[',', ',', ' ']\",支持半角/全角逗号/空格

IME (compositionstart/end 时序不可靠,统一走 @on-keydown + W3C 标准 229 守卫):
- login/ProjectPanel/TaskAdd/UserTagsModal 的 onXxxKeydown 加
  isComposing || key=='Process' || keyCode==229 三重守卫,
  与 TagInput.downEnter 风格统一
- file.vue 块模式重命名 onKeydown 用 \$nextTick 包 onEnter,
  避免 keydown 早于 input 事件 commit v-model 导致少一个字符

AbstractModel.performInsertOrIgnore:
- \$uniqueBy 不为 null 时抛 InvalidArgumentException;
  MySQL INSERT IGNORE 无法按指定列 scope 冲突,与框架 ON CONFLICT 语义不一致
- lastInsertId 仅在 > 0 时回填主键;
  避免在无 auto_increment 列的表上把业务设置的 PK 覆盖为 0

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-15 01:26:55 +00:00
kuaifan
3f5078ec9b fix(frontend): 修复多处输入框 IME 合成期回车/Backspace 误触发提交
- file.vue 块模式文件重命名输入框 @on-keyup → @on-keydown,
  避免拼音选词回车的 keyup 阶段误触发提交
- TagInput 回车添加 tag、Backspace 删除 tag 增加 IME 守卫
  (isComposing / key=Process / keyCode=229),避免拼音选词回车
  误加 tag、合成期 Backspace 误删上一个 tag
- login / ProjectPanel / UserTagsModal / TaskAdd 的 @on-enter
  改用 @on-keydown 包装 (keyCode===13),绕开 iview Input
  handleEnter 走 keyup.enter 在 IME 选词回车会误触发提交的问题

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-14 23:03:01 +00:00
kuaifan
cf6f6041b6 fix(micro-app): 浏览器独立窗口(popout)关闭应用时关闭窗口
assistShow watch 此前只为 Electron 子窗口发送 windowDestroy 销毁窗口,
浏览器以 window.open 打开的 popout 独立窗口(single/apps.vue)关闭应用后
只隐藏内容、窗口空挂不关。补全浏览器分支:windowType 为 popout 时调用
window.close()。主程序内嵌的 embed 窗口(默认值)不进入此分支,不受影响。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-14 05:30:31 +00:00
kuaifan
e17a520599 fix(micro-app): 修复 resolveType 调用不存在的 $A.platformType 报错
$A 上从未定义 platformType 方法,resolveType 解析微应用类型时
必抛 "$A.platformType is not a function"。改用既有 $A.Platform
属性判断桌面端(web/mac/win),保持 desktop/mobile 语义不变。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-14 04:26:33 +00:00
kuaifan
bfa0920579 feat(ai-assistant): 采集器补 tabindex/ARIA 角色覆盖 + label 去重
借鉴 browser-use clickable_elements 规则补齐页面元素采集边界:
- 用已定义但闲置的 INTERACTIVE_ROLES 补全所有 ARIA 可交互角色选择器(原仅扫部分 role)
- 选择器加 [tabindex]:not([tabindex="-1"]),捕捉自定义可聚焦/可交互元素
- 第二遍扫描跳过 label[for]/包裹控件的 label,避免与其表单控件重复采集

纯 DOM 增量、零风险(只多采不误删);真机验证无报错、label 去重生效。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-12 08:18:24 +00:00
kuaifan
88fed0744c feat(ai-assistant): 页面操作穿透到当前微应用 iframe 内部
- 新增 active-context.js:按 microApps 解析最前的同源微应用 iframe(src 匹配 + contentDocument 同源探测),给出 doc/frameKey
- 采集器/执行器从只认主 document 泛化为按 el.ownerDocument 自适应,覆盖主文档与 iframe;视口与事件构造器取元素所在 window
- operation-module 加 scope(auto/main/app)、跨源/未就绪降级、frame 标注,并存活动上下文供失效守卫
- ai-kb 同步 page-action / page-context-tool / element-action 三 chunk

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-12 07:02:35 +00:00
kuaifan
da095a1a80 feat(ai-assistant): 页面操作搬到主程序 /ws + doo task notify + 删 OCR
页面操作传输层从 MCP 独立 WebSocket 迁到主程序常驻 /ws:
- 后端 AssistantController 加 operation__dispatch/result(fd 归属校验 +
  PushTask 精推 + Cache 轮询取结果),WebSocketService onMessage 加
  operationResult 回包分支
- 前端 actions.js 加 case "operation" 经 emitter 桥接到浮窗执行后回包;
  float-button.vue 接 aiOperationRequest;operation-module.js 解耦、
  executor 惰性化;删除 operation-client.js(不再单连 MCP WS)

ai-kb 同步:tool-binding.yaml 去掉 4 个工具(3 页面 + OCR),相关 chunk
reconcile(措辞去 MCP 化、OCR 改多模态识图),工具数 33→29

i18n:后端新增文案登记 original-api.txt

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-12 01:31:21 +00:00
kuaifan
39b9a72b16 refactor(ai-assistant): 用内联深链替代 driver.js 页面引导
「带我去」分步引导(driver.js + 四级元素定位 + show_guide)定位不稳、
二级菜单不可达、点高亮按钮触发跳转即被杀,体验差。改为 AI 回复正文里把
可定位的页面/面板渲染成可点深链 chip,点击直达那一屏。

- 新增深链目录:_meta/page-links.yaml(语义,供 AI 选择)+ deep-links.js
  (可执行映射,21 个无需运行时 id 的导航目的地),两端 id 一致性由
  tests/deep-links-parity.mjs 校验
- markdown.js 加 processDeepLinks:[文字](dootask://link/<id>) 合法 id →
  chip,非法 id → 纯文字(绝不渲染死链);复用现有 dootask:// 点击拦截链路
- DialogMarkdown 加 link 分支调 openDeepLink;system.vue 支持 query.tab
  初始化,系统设置二级 Tab 可深链直达
- 彻底移除 driver.js 引导:删 guide-renderer.js/guide.css、show_guide
  前端通道、aiGuideStarted 监听、driver.js 依赖
- 同步 ai-kb:改写 guide/start-guide 两 chunk、tool-binding 去 show_guide
- 插件侧 prompt 改动规格见 docs/ai-deeplink-plugin-spec.md(独立仓库实施)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 23:55:09 +00:00
kuaifan
4de6c69972 feat(ai-assistant): RAG 反馈闭环 + driver.js 页面操作引导
方向7 反馈闭环:
- 新增 ai_assistant_search_logs / ai_assistant_feedbacks 两表 + 模型
- AssistantController 加 log__search / feedback__save 端点,auth 透传 session_id→context_key
- 前端 AI 回复下方 👍/👎(可改票、随会话持久化回显),extractSourceIds 解析引用
- ai-kb:feedback chunk + README 运营 SQL 口径(低分 top query / 👎 source)

方向4 页面操作引导:
- 渲染层用 driver.js(高亮可点击挖洞 + 稳定定位),编排层自研
  (脚本 schema / 四级元素定位 / 跨页 pre_action 导航 / 找不到降级文字)
- leave-semantics:跳转动作在点「下一步」后才执行
- markdown.js 渲染 ```ai-guide 围栏为「带我去」按钮;DialogMarkdown 点击启动
- 近义词归一化(创建/新建/新增/添加互通)提升 target 命中
- ai-kb:guide/start-guide chunk + tool-binding 加 show_guide

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-10 16:07:08 +00:00
kuaifan
ec1ab31b0e refactor(ai-kb): 索引同步改为容器启动 reconcile
- 删除 CI reindex workflow(ai-kb-reindex.yml):内容入库不再依赖 CI
  远程触发,AI 插件容器每次启动按文件 hash 对账(reconcile)自动增量
  收敛,免重启即时生效时可手动调 POST /kb/reindex(默认 mode=reconcile)
- ai-kb README.md 同步更新贡献流程与内容同步机制说明
- CLAUDE.md 精简 ai-kb 同步规则:去除与 _schema/README 重复的写作规范
  与背景说明,保留同步时机、操作指引、改完无需触发索引三条
- 另:auth 接口 locale 检索语种缺省改为由请求语言推导(含 zh 视为 zh,
  否则 en),删除 config/ai.php 的 rag_supported_locales 与回退逻辑,
  前端改用 getLanguage() 统一映射,同步更新 ai-kb auth.md
- appstore 镜像升级 0.4.3 -> 0.5.0

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 09:46:58 +00:00
kuaifan
af206480fb feat(ai-kb): 落地 RAG 知识库与灰度链路(48 feature / 546 chunk) 2026-06-10 04:08:17 +00:00
kuaifan
f6067d1bd5 feat(ai-assistant): AI 浮窗/浮按钮移动端适配与流式不中断 2026-06-10 04:05:09 +00:00
kuaifan
8cd4669b90 refactor(manage): 部门负责人只读视角统一使用禁用态UserSelect组件
用 disabled 属性的 UserSelect 替代独立的 UserAvatar 只读展示,
消除双份渲染逻辑,负责人/协助人员/可见人员统一使用同一组件路径。

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 05:01:15 +00:00
kuaifan
0863e5529a feat(manage): 实现部门负责人视角,支持只读查看部门成员项目与任务
部门负责人/部门管理员可通过系统配置开启,选择管理部门后只读查看
本部门及下级部门成员的全部项目和任务。前端自动根据 department_readonly
标记禁用编辑操作,后端统一注入负责人视角上下文控制数据访问边界。

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 00:14:36 +00:00
kuaifan
24710289e1 feat(multi-owner): 群/项目/部门支持主+副双负责人体系
- 群组:新增 web_socket_dialog_users.role(1=主、2=副),主可任命/罢免副群主,副可邀请/移出普通成员
- 项目:project_users.owner 扩展为 0/1/2(成员/主/副),主独占转让和删除,副共享日常管理;任务可见性、通知、分配等下游逻辑统一用「主+副」
- 部门:新增 user_department_owners 表存储副负责人;部门群同步副群主,赋予群管理员权限
- 转移用户时副身份不替补、降级为普通成员
- 配套 migration/backfill、API、前端 UI、i18n 词条与三项 Feature 测试
- .gitignore 忽略 .playwright-mcp/
2026-05-03 00:05:31 +00:00
kuaifan
fbd1c829a1 fix(ai): AI助手图片压缩阈值从1024提升到1568,减少长图模糊
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-17 05:12:16 +00:00
kuaifan
82d2ca6360 feat(ai): AI助手聊天记录服务端持久化
- 图片缓存不再二次压缩,用户预览与AI收到的图片质量一致
- 新增 ai_assistant_sessions 表及 AiAssistantSession 模型
- 新增会话 API:session/list、session/save、session/delete
- 前端会话存储从 IndexedDB 切换为服务端 API,图片落盘到 uploads/assistant/{YYYYMM}/{user_id}/
- saveSessionStore 添加防抖,删除会话时同步清理内存缓存

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-17 04:22:35 +00:00
kuaifan
8def4addc4 fix(chat): 修复 AI 助手(userid=-1)在多处显示异常的问题
在 UserAvatar 组件中统一处理 AI 助手虚拟用户,避免各组件重复判断;
同时修复 @提及、回复引用、转发消息等场景下的 undefined 和空白显示问题,
并过滤批量用户请求中的无效 userid。

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 12:34:27 +00:00
kuaifan
9097369b0c fix(ai-assistant): 修复图片预览调用不存在方法的错误
将 $A.previewFile 替换为 this.$store.dispatch("previewImage"),
解决 TypeError: $A.previewFile is not a function 错误。

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 14:58:37 +00:00
kuaifan
95c6b53f10 fix(ai-assistant): 优化图片压缩逻辑避免重复质量压缩
- 新增 forceCompress 参数控制是否强制质量压缩
- compressImageForAI: 始终进行质量压缩(发送给 AI)
- saveImageToCache: 仅在需要缩小尺寸时才压缩(避免已压缩图片被重复压缩)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 14:52:57 +00:00
kuaifan
f7d5040b02 feat(ai-assistant): 支持拖放和粘贴上传图片
- 新增拖放上传:可将图片拖放到对话窗口任意位置
- 新增粘贴上传:在输入框中可直接粘贴剪贴板图片
- 提取 handleImageFiles 通用方法供多种上传方式复用
- 添加拖放时的视觉反馈(虚线边框 + 提示遮罩)
- 使用计数器方式正确处理嵌套元素和拖出窗口的情况

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 14:45:38 +00:00
kuaifan
07b99c6e75 fix(ai-assistant): 修复 SSE 连接失败时状态未正确更新的问题
当 SSE 连接一开始就失败时,响应状态保持 'waiting' 而非 'streaming',
导致 onFailed 回调不会更新状态,UI 一直显示 loading。

现在同时处理 'streaming' 和 'waiting' 状态,并标记为错误状态显示失败提示。

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 14:20:50 +00:00
kuaifan
cb5e7e2cc7 refactor(ai): 优化 AI 提示词构建逻辑
- withLanguagePreferencePrompt: 修复无语言标签时占位符未添加的问题
- handleBeforeSend: 简化操作会话提示词,移除冗余的工具名称说明

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 13:47:25 +00:00
kuaifan
2180998e81 feat(ai-assistant): 添加图片发送功能支持多模态对话
- 支持上传图片并压缩(当前消息 1024px,历史 512px)
- 图片独立缓存存储,使用占位符 [IMG:xxx] 替代 base64
- 新增 prompt-image.vue 组件展示历史图片缩略图
- 后端 AI.php 支持多模态消息格式处理
- 添加图片缓存清理机制(删除会话时同步清理)
- 优化 parsePromptContent 避免重复调用
- 会话标题自动过滤图片占位符

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 09:31:34 +00:00
kuaifan
f36317b081 fix(operation-client): 修正 WebSocket 路径格式并优化连接 URL 生成 2026-01-19 10:52:22 +08:00
kuaifan
066a5a619c build 2026-01-19 09:43:37 +08:00
kuaifan
654793156d feat(micro-app): 添加额外的事件发射器方法以支持动态事件处理 2026-01-19 09:19:27 +08:00
kuaifan
cb6c50b071 fix(ai-assistant): 修复弹窗和下拉菜单被其他弹窗遮挡的问题
- 使用 window.modalTransferIndex + 1000 作为动态 z-index
  - 添加定时刷新机制:弹窗可见时 5 秒刷新,不可见时 20 秒刷新
  - modal.vue 通过 zIndex prop 接收并应用 z-index
  - float-button.vue 通过 $parent.topZIndex 获取 z-index
  - Dropdown 和 Select 使用 ViewUI 新增的 z-index prop
2026-01-19 01:13:18 +00:00
kuaifan
2cb67fafe7 feat(ai-assistant): 支持任务弹窗和对话弹窗的场景检测
- 在 page-context.js 的 getPageContext 和 getSceneKey 函数中优先检测弹窗状态
  - 当 taskId > 0 时使用 single-task 上下文
  - 当 dialogModalShow && dialogId > 0 时使用 single-dialog 上下文
  - 在 welcome-prompts.js 中添加弹窗场景检测逻辑
  - 提取 formatPrompts 辅助函数减少代码重复
  - 在 index.vue 的 welcomePromptsKey 中监听 taskId 和 dialogModalShow 变化
2026-01-18 23:52:26 +00:00
kuaifan
8eaba6f364 fix(ai-assistant): 优化流式响应期间的 loading 状态显示
- 修改 loading 显示条件,streaming 状态时继续显示 loading icon
  - SSEClient 添加可选的 onFailed 回调,处理连接失败情况
  - 修复 done 事件处理,确保状态正确转为 completed
  - 解决工具调用期间 loading 动画过早消失的问题
2026-01-18 14:44:03 +00:00
kuaifan
59ad79fa58 feat(ai-assistant): 支持上下键切换历史输入
- 按 ↑ 键切换到上一条历史输入(光标在第一行时生效)
  - 按 ↓ 键切换到下一条历史输入(光标在最后一行时生效)
  - 历史记录使用 IndexedDB 持久化存储,最多保存 50 条
  - 重复输入会移动到末尾而非重复添加
  - 弹窗关闭时自动重置导航状态
2026-01-18 13:20:13 +00:00
kuaifan
c65f0276bd feat(ai-assistant): 支持编辑历史问题并重新发送
- 鼠标悬停历史问题时显示编辑图标
  - 点击编辑后在原位置显示内联编辑器
  - 支持 Enter 发送、Shift+Enter 换行、Esc 取消
  - 发送后删除该问题及之后的对话历史,重新发送编辑后的问题
  - 正确处理中文输入法组合状态,避免误触发提交
2026-01-18 12:56:16 +00:00
kuaifan
f8b335a003 feat(ai-assistant): 增加元素向量匹配与关键词搜索能力
- 新增后端 match_elements API,使用向量相似度匹配页面元素
  - 页面上下文采集支持关键词过滤,按 name/aria-label/placeholder/title 匹配
  - 关键词匹配失败时自动降级为向量搜索
  - 改进 findElementByRef 函数,使用 selector + name 双重匹配提高准确性
2026-01-18 11:50:27 +00:00
kuaifan
0ac4b546ba feat(ai-assistant): 实现 AI 前端操作能力
新增三个 MCP 工具的前端支持:
  - get_page_context: 基于 ARIA 角色收集页面元素,支持分页和区域筛选
  - execute_action: 执行导航操作(打开任务/对话、切换项目/页面)
  - execute_element_action: 元素级操作(click/type/select/focus/scroll/hover)

  新增文件:
  - operation-client.js: WebSocket 客户端,处理与 MCP Server 的通信
  - page-context-collector.js: 页面上下文收集器,ref 系统和 cursor:pointer 扫描
  - action-executor.js: 操作执行器,支持智能解析如 open_task_123
  - operation-module.js: 模块编排,整合上述模块

  修改文件:
  - float-button.vue: 集成 operation-module,AI 助手打开时启用
  - index.vue: 发射关闭事件供 float-button 监听
2026-01-18 01:35:13 +00:00
kuaifan
07a41ca0ac feat(ai-assistant): 扩充提示词库并优化随机选择策略
- 为提示词增加 type(query/action/sync/review)和 pin 属性
  - 新增 selectPrompts 函数:优先展示 pin 提示,按类型多样化抽样
  - 各场景提示词数量扩充 2-3 倍,覆盖更多常见操作
  - 部分场景使用动态数据(如 taskName、userName、groupName)个性化提示
2026-01-17 02:24:42 +00:00