diff --git a/web/src/views/projects/RequirementDetailView.vue b/web/src/views/projects/RequirementDetailView.vue
index 6e1a518..2805659 100644
--- a/web/src/views/projects/RequirementDetailView.vue
+++ b/web/src/views/projects/RequirementDetailView.vue
@@ -88,7 +88,7 @@
-
+
+
+
+
(null)
const artifactPanelRef = ref | null>(null)
+const historyPanelRef = ref | null>(null)
const prevArtifact = ref(null)
const workspaceOptions = computed(() =>
wsStore.list.map((w) => ({ label: `${w.name} (${w.slug})`, value: w.id })),
)
+const workspaceSlug = computed(() => {
+ if (!data.value?.requirement.workspace_id) return null
+ return wsStore.list.find((w) => w.id === data.value!.requirement.workspace_id)?.slug ?? null
+})
+
// 当前阶段属于 AI 对话三阶段时返回该阶段,否则 null。
const chatPhase = computed(() => {
const p = data.value?.requirement.phase
@@ -271,6 +289,7 @@ watch(chatPhase, loadPrevArtifact)
function onArtifactSaved() {
artifactPanelRef.value?.refresh()
+ historyPanelRef.value?.refresh()
}
async function onWorkspaceChange(v: string | null) {
diff --git a/web/src/views/projects/components/RequirementHistoryPanel.vue b/web/src/views/projects/components/RequirementHistoryPanel.vue
new file mode 100644
index 0000000..5cfcef0
--- /dev/null
+++ b/web/src/views/projects/components/RequirementHistoryPanel.vue
@@ -0,0 +1,330 @@
+
+
+
+
+
+
+
+
+ {{ PHASE_TITLE[phase] }}产物
+
+ {{ artifactsByPhase[phase].length }}
+
+ 当前
+
+
+
+
+
+
+
+ v{{ a.version }}
+
+ AI
+
+
+
+
+ {{ formatDate(a.created_at) }}
+
+
+ {{ a.note }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ AI 对话
+ {{ conversations.length }}
+
+
+
+
+
+
+
+
+ {{ c.title || '(未命名)' }}
+
+
+
+
+ {{ formatDateTime(c.updated_at) }}
+
+
+
+
+
+
+
+
+
+
+
+
+ ACP 会话
+ {{ acpSessions.length }}
+
+
+
+
+
+
+
+ {{ s.branch }}
+
+
+
+
+
+ {{ formatDateTime(s.started_at) }}
+ · {{ s.last_error }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+