优化: 所有剩余UI/UX待办一批完成(持久化+AuditLog+解耦+total+原12大改+P2)

持久化(P1-c):新建 usePersistedRef composable,Tasks/AuditLog/ProjectDetail 等接入 localStorage

AuditLog(P1-d):后端 list_tool_executions 加 WHERE 筛选+返 {items,total,has_more},前端对接+长列折叠+筛选持久化

数据源解耦(P1-g):ProjectDetail projectTasks 按 project_id 独立加载 + ChatInput @项目联想独立加载(不读 store.tasks 当前页)

GitChanges(12a):后端 get_module_commits 加 git rev-list --count 返 total,前端显真实总数

原12大改:Dashboard 统计卡压底行(1)/Projects 列表卡片视图(2)/project_event 埋点排序(3)/TaskDetail 重设计(4)/IdeaDetail 重设计(5)/KnowledgeDetail 重设计(6)/界面持久化+侧栏Ctrl+B+审批数字键(7)/ProjectDetail 三栏改两栏(10)

P2打磨:文件浏览器(FileTree去重/FilePreview行号.md Diff/selectedFilePath归位)/settings反馈(假保存/端口校验)/AI会话(try-catch/scrollIntoView)/后端计数(move_queue事件/timeline total/workflow分页/import_batch分块)/杂项(TopBar/ConfirmDialog键盘/CIStatus i18n/ToolResultBody/ModuleNode/ApprovalDialog全选)
This commit is contained in:
lxy
2026-08-02 13:11:06 +08:00
parent caaabf0c15
commit f736f435bc
70 changed files with 2645 additions and 576 deletions
+14 -2
View File
@@ -5,7 +5,7 @@
点停止 ai_stop_loop(后端走 AiCompleted 收尾) 卡片隐藏
store 单例共享(state/aiApi),pendingMaxRounds 模块级 ref(useAiEvents)直接导入
toast emit 转父(保持单一 toast ) -->
<div v-if="showMaxRoundsCard" class="ai-max-rounds">
<div v-if="showMaxRoundsCard" ref="maxRoundsRef" class="ai-max-rounds">
<span class="ai-max-rounds-text">{{ $t('aiChat.maxRoundsReached') }}</span>
<span class="ai-max-rounds-hint">{{ $t('aiChat.maxRoundsHint') }}</span>
<div class="ai-max-rounds-actions">
@@ -24,7 +24,7 @@
</template>
<script setup lang="ts">
import { ref, computed, watch } from 'vue'
import { ref, computed, watch, nextTick } from 'vue'
import { useI18n } from 'vue-i18n'
import { useAiStore } from '../../stores/ai'
import { pendingMaxRounds, getConvState } from '../../composables/ai/useAiEvents'
@@ -73,6 +73,10 @@ const showMaxRoundsCard = computed(() =>
&& isViewingGeneratingState.value,
)
// M8:卡片根 ref。达 max 挂起卡位于输入区上方,多轮迭代后消息流已很长,卡片常被挤出视口 → 用户看不到
// "继续/停止" → generating 永真卡死。卡片显示时 scrollIntoView 让操作入口立即可见。
const maxRoundsRef = ref<HTMLElement | null>(null)
/** 点继续:调 ai_continue_loop。后端续 max_iterations 轮(iteration 从 0 重计)。
* 不主动清 pendingMaxRounds——由后端新一轮事件(AiAgentRound)与最终 AiCompleted/AiError
* 在 useAiEvents 内清。IPC 失败回滚 acting 让用户可重试。 */
@@ -108,6 +112,14 @@ async function handleStopLoop(): Promise<void> {
watch(() => pendingMaxRounds.value, (v) => {
if (!v) maxRoundsActing.value = false
})
/** M8:卡片显示(从无→有)时 scrollIntoView 让"继续/停止"按钮组立即进入视口。
* 仅监 showMaxRoundsCard 真值翻转,不监 acting 等内部态避免已可见时反复跳。 */
watch(showMaxRoundsCard, async (show) => {
if (!show) return
await nextTick()
maxRoundsRef.value?.scrollIntoView({ block: 'center', behavior: 'smooth' })
})
</script>
<style scoped>