docs/archives/132-architecture-migration-and-session-persistence-plans/architecture-migration-analysis.md
文档名称: architecture-migration-guide.md
性质: 长期规划文档(未执行)
目标: 将三种模式统一到 Store + Operations 架构
logic.testResults?.originalResult 遗漏 .value,导致 UI 显示问题Component (直接消费 store)
↓
Operations composable (副作用/流程逻辑)
↓
Pinia Session Store (单一真源)
BasicSystemWorkspace.vue / BasicUserWorkspace.vue
↓
useBasicWorkspaceLogic (状态代理 + 业务逻辑) ← 仍在使用
↓
useBasicSystemSession / useBasicUserSession (Pinia Store)
Logic 层仍在使用 (packages/ui/src/composables/workspaces/useBasicWorkspaceLogic.ts):
// ✅ P0 Bug 已修复:testResults getter 不再返回临时对象
const testResults = computed<BasicSessionStore['testResults']>({
get: () => {
// 关键修复:始终返回 sessionStore.testResults(即使是 null)
return sessionStore.testResults
},
set: (value) => {
sessionStore.updateTestResults(value)
}
})
// ❌ 但 Logic 层仍然返回大量 computed 包装
export function useBasicWorkspaceLogic(options) {
return {
// 状态代理(所有都是 ComputedRef)
prompt, // ComputedRef<string>
optimizedPrompt, // ComputedRef<string>
testResults, // ComputedRef<TestResults | null>
testContent, // ComputedRef<string>
// 过程态
isOptimizing, // Ref<boolean>
isTestingOriginal, // Ref<boolean>
// 业务方法
handleOptimize,
handleTest,
handleIterate,
// ...
}
}
组件消费方式 (BasicSystemWorkspace.vue:323-365):
const logic = useBasicWorkspaceLogic({
services,
sessionStore: session,
optimizationMode: 'system',
promptRecordType: 'optimize'
})
// ✅ P0 Bug 已修复:组件中正确使用 .value
const hasOriginalResult = computed(() => !!logic.testResults.value?.originalResult)
const hasOptimizedResult = computed(() => !!logic.testResults.value?.optimizedResult)
已完成的工作:
.value)testResults getter 不再返回临时对象state.xxx)未完成的迁移:
logic.xxx 访问状态,而非直接访问 session.xxx为什么没有迁移?
ContextSystemWorkspace.vue
↓
useConversationTester (reactive 状态树 + 业务逻辑)
↓
部分数据写入 Session Store
Tester composable (ContextSystemWorkspace.vue:461):
const conversationTester = useConversationTester(
services,
optimizationContext,
// ... 其他参数
)
Tester 内部使用 reactive 状态树:
// useConversationTester 内部(推测)
const state = reactive({
testResults: null,
isTestingOriginal: false,
isTestingOptimized: false,
// ... 大量临时状态
})
问题:
迁移指南建议:
// 目标架构
useContextWorkspaceOperations (对外接口)
↓
useConversationTester (内部实现,只管理临时态)
↓
Session Store (持久化状态的唯一真源)
ImageText2ImageWorkspace.vue
↓
直接消费 useImageText2ImageSession (Pinia Store)
↓
ImageStorageService (图像数据存储)
Session Store (useImageText2ImageSession.ts:41-56):
export const useImageText2ImageSession = defineStore('imageText2ImageSession', () => {
// ✅ 使用独立 ref,符合 Pinia 最佳实践
const originalPrompt = ref('')
const optimizedPrompt = ref('')
const reasoning = ref('')
const originalImageResult = ref<ImageResult | null>(null)
const optimizedImageResult = ref<ImageResult | null>(null)
// ✅ 提供简洁的 action 方法
const updatePrompt = (prompt: string) => {
if (originalPrompt.value === prompt) return
originalPrompt.value = prompt
lastActiveAt.value = Date.now()
}
return {
// state
originalPrompt,
optimizedPrompt,
// ...
// actions
updatePrompt,
updateOptimizedResult,
// ...
}
})
图像存储分离 (ImageStorageService):
// ✅ base64 数据存储在独立的 IndexedDB
// ✅ Session Store 只存储 ImageRef
{
id: 'img_123',
_type: 'image-ref'
}
优点:
缺点:
目标: 建立护栏和规范
具体任务:
为什么没做?
目标: Logic → Operations
迁移步骤(指南描述):
// Step 1: 创建新的 Operations composable
export function useBasicWorkspaceOperations(options) {
// 只返回过程态和方法,不包装状态
const isOptimizing = ref(false)
const handleOptimize = async () => { /* ... */ }
return {
isOptimizing,
handleOptimize,
handleTest,
handleIterate
}
}
// Step 2: 组件直接消费 store
const session = useBasicSystemSession()
const ops = useBasicWorkspaceOperations({ services, sessionStore: session })
// 直接访问 store(不通过 Logic 层)
const hasOriginalResult = computed(() => !!session.testResults?.originalResult)
// 触发操作
<button @click="ops.handleOptimize()">优化</button>
当前 vs 目标对比:
| 维度 | 当前(Logic 层) | 目标(Operations) |
|---|---|---|
| 状态访问 | logic.testResults.value | session.testResults |
| 状态类型 | ComputedRef | 原生 Ref |
| 业务逻辑 | Logic 层内部 | Operations 独立 |
| 组件绑定 | logic.handleOptimize | ops.handleOptimize |
| 响应式陷阱 | 易漏 .value | 直接访问 store,无陷阱 |
为什么没迁移?
迁移指南描述: 需要迁移到 Store + Operations 实际修复: 局部修复组件消费方式
修复前 (BasicSystemWorkspace.vue):
// ❌ 错误:logic.testResults 是 ComputedRef,漏了 .value
const hasOriginalResult = computed(() => !!logic.testResults?.originalResult)
修复后 (BasicSystemWorkspace.vue:365):
// ✅ 正确:显式使用 .value
const hasOriginalResult = computed(() => !!logic.testResults.value?.originalResult)
结论: P0 Bug 通过最小化修改已解决,不需要完整迁移架构。
迁移指南认为: Logic 层是"技术债",应该删除 实际情况: Logic 层提供了价值
Logic 层的优点:
Logic 层的缺点:
.value迁移指南假设: 团队愿意投入资源完成迁移 实际情况: 存在多重阻力
阻力来源:
保持现状,不强制迁移
理由:
可选优化:
.value)逐步迁移,按优先级排序
优先级:
Context 模式 (优先级最高)
Image 模式 (优先级中)
Basic 模式 (优先级低)
建立规范,新代码遵循 Store + Operations
策略:
文档性质: 长期愿景,非强制执行计划 实际价值:
但实际上:
答案: 不强制,按需渐进
理由:
现状维持(短期)
↓
Context 模式优先迁移(中期)
↓
新功能强制使用 Store + Operations(长期)
↓
旧代码按需重构(逐步收敛)
| 模式 | 架构 | 是否需要迁移 | 优先级 |
|---|---|---|---|
| Basic | Store → Logic → Component | 可选 | 低 |
| Context | Tester → Component | 建议迁移 | 高 |
| Image | Store → Component | 补充优化 | 中 |
packages/ui/src/composables/workspaces/useBasicWorkspaceLogic.ts (597 行)packages/ui/src/composables/prompt/useConversationTester.tspackages/ui/src/stores/session/useImageText2ImageSession.tsdocs/archives/132-architecture-migration-and-session-persistence-plans/architecture-migration-guide.md (20 KB)