新增: AI Chat多项增强(审批去重/编辑重发/导出/实体引用/会话置顶搜索)+任务推进链df-nodes落地

This commit is contained in:
2026-06-16 12:41:13 +08:00
parent 212a927eee
commit 7d5cd4c89a
62 changed files with 4576 additions and 248 deletions

View File

@@ -19,7 +19,7 @@
//! 故 useAiStore() 之外无需手动 init;以下 import 即触发恢复逻辑
//! - state 为模块级单例,全应用共享同一引用
import { reactive, watch } from 'vue'
import { computed, reactive, watch } from 'vue'
import type { AiChatEvent, AiConversationSummary, AiMessage, AiProviderConfig, AiToolCallInfo, SkillInfo } from '@/api/types'
/**
@@ -73,6 +73,9 @@ export const state = reactive({
agentRound: 0,
// 归档分组折叠态(默认折叠)
archivedCollapsed: true,
// 对话搜索关键字(UX-06 §3.1):非空时侧栏取消时间分组,平铺展示标题匹配的会话(updated_at DESC)。
// 清空恢复原分组。消费方:Sidebar 渲染(读 searchQuery 决定走 filteredConversations 还是 groupedActive)。
searchQuery: '',
// token 用量展示(受 df-show-token-usage 开关控制;lastTokenUsage=最近一条回复,convTokenTotal=当前对话累计)
lastTokenUsage: null as { prompt: number; completion: number; total: number } | null,
convTokenTotal: null as { prompt: number; completion: number; total: number } | null,
@@ -101,6 +104,25 @@ watch(
},
)
/**
* 对话搜索过滤结果(UX-06 §3.1)。
*
* 行为:
* - searchQuery 为空 → 返回 null(信号:消费方走原时间分组 groupedActive / 归档分组)。
* - 非空 → 在全部对话(活跃+归档)中按标题做 case-insensitive 子串匹配,平铺返回
* (取消分组),按 updated_at DESC 排序,最近改过的在最前。
*
* 设计:过滤逻辑放 store 而非组件,供主窗口/分离窗口两处侧栏复用同一结果;
* 消费方仅需 `store.filteredConversations` 即得数组或 null,UI 连接在侧栏视图内完成。
*/
const filteredConversations = computed<AiConversationSummary[] | null>(() => {
const q = state.searchQuery.trim().toLowerCase()
if (!q) return null
return state.conversations
.filter(c => (c.title ?? '').toLowerCase().includes(q))
.sort((a, b) => (b.updated_at > a.updated_at ? 1 : b.updated_at < a.updated_at ? -1 : 0))
})
/**
* AI Store 统一入口 — 返回单例 state + 全部方法。
*
@@ -110,6 +132,7 @@ watch(
export function useAiStore() {
return {
state,
filteredConversations,
...useAiEvents(),
...useAiStream(),
...useAiSend(),

View File

@@ -55,7 +55,9 @@ export function parseTags(tags: string | null): string[] {
}
export function useKnowledgeStore() {
// ── 加载列表(默认排除 archived) ──
// ── 加载列表(library:默认仅 published,F-260616-02 决策 a) ──
// 后端 knowledge_list 默认收窄为 published,无需前端传 status。
// 显式 status 仍透传(如 status='archived' 查归档)。
async function loadList(status?: string) {
const seq = ++_itemsReqSeq
state.loading = true
@@ -72,7 +74,8 @@ export function useKnowledgeStore() {
}
}
// ── 加载审核收件箱(候选列表) ──
// ── 加载待处理收件箱(candidate + pending_review,F-260616-02 决策 a) ──
// 后端 knowledge_list_candidates 已收两种待处理状态,前端调用不变。
async function loadCandidates() {
const seq = ++_itemsReqSeq
try {

View File

@@ -12,8 +12,18 @@ const t = ((i18n as any).global.t as (k: string) => string).bind((i18n as any).g
* src/api/workflow.ts,本子 store 不再直接 invoke IPC。
*/
export function createWorkflowStore() {
async function runWorkflow(name: string, dag: unknown, config?: Record<string, unknown>) {
return await workflowApi.run(name, dag, config)
/**
* 触发工作流执行。
* F-260616-06 阶段2(②-2): taskId/targetStatus 可选,同时传时工作流完成/失败联动推进任务。
*/
async function runWorkflow(
name: string,
dag: unknown,
config?: Record<string, unknown>,
taskId?: string,
targetStatus?: string,
) {
return await workflowApi.run(name, dag, config, taskId, targetStatus)
}
async function loadWorkflowExecutions() {