Browse Source

feat: add project fields analysis documentation and enhance delivery execution stage

- Introduced a comprehensive analysis document for project fields, detailing the structure and requirements for various stages including confirmation and delivery execution.
- Enhanced the delivery execution stage component by adding fields for space ID and delivery type, and implemented logic to update space deliverable summaries based on approval status.
- Updated the requirements stage component to include additional fields for uploaded files, ensuring better tracking of space-related data and analysis results.
- Implemented initialization of phase deadlines and space deliverable summaries to improve project management and tracking capabilities.
徐福静0235668 1 day ago
parent
commit
56ce1468fe

+ 349 - 0
project_fields_analysis.md

@@ -0,0 +1,349 @@
+# 项目字段结构分析文档
+
+## 1. 确认需求阶段字段
+
+### 1.1 确认需求按钮时间字段
+**位置**: `Project.data.requirementsConfirmed*` 字段组
+```typescript
+// 确认需求阶段完成时保存的字段
+data.requirementsConfirmed = true;                          // 是否已确认需求
+data.requirementsConfirmedBy = this.currentUser.id;        // 确认人ID
+data.requirementsConfirmedByName = this.currentUser.get('name'); // 确认人姓名
+data.requirementsConfirmedAt = new Date().toISOString();   // 确认时间 (ISO字符串)
+```
+
+**文件位置**: `src/modules/project/pages/project-detail/stages/stage-requirements.component.ts:1363-1366`
+
+## 2. 交付执行阶段字段
+
+### 2.1 交付执行四个子阶段
+**阶段标识符**:
+- `white_model` - 白模阶段
+- `soft_decor` - 软装阶段  
+- `rendering` - 渲染阶段
+- `post_process` - 后期阶段
+
+### 2.2 阶段状态字段
+**位置**: `Project.data.deliveryStageStatus` 对象
+```typescript
+// 每个子阶段的状态结构
+deliveryStageStatus: {
+  [stageId: string]: {
+    status: 'not_started' | 'in_progress' | 'completed' | 'approved' | 'rejected';
+    startedAt?: string;      // 开始时间
+    completedAt?: string;    // 完成时间
+    approvedAt?: string;     // 审批通过时间
+    rejectedAt?: string;     // 审批驳回时间
+    approvedBy?: string;     // 审批人ID
+    rejectionReason?: string; // 驳回原因
+  }
+}
+```
+
+**示例**:
+```typescript
+data.deliveryStageStatus = {
+  white_model: {
+    status: 'approved',
+    startedAt: '2024-01-01T09:00:00.000Z',
+    completedAt: '2024-01-05T17:00:00.000Z',
+    approvedAt: '2024-01-06T10:00:00.000Z',
+    approvedBy: 'userId123'
+  },
+  soft_decor: {
+    status: 'in_progress',
+    startedAt: '2024-01-06T09:00:00.000Z'
+  },
+  rendering: {
+    status: 'not_started'
+  },
+  post_process: {
+    status: 'not_started'
+  }
+}
+```
+
+**文件位置**: `src/modules/project/pages/project-detail/stages/stage-delivery.component.ts:391-400`
+
+## 3. 产品空间场景字段分析
+
+### 3.1 Product表结构 (产品空间)
+**主要字段**:
+```typescript
+interface Product {
+  id: string;
+  project: Pointer<Project>;           // 关联项目
+  productName: string;                 // 产品/空间名称
+  productType: string;                 // 产品类型
+  status: string;                      // 状态 ('not_started' | 'in_progress' | 'completed')
+  
+  // 空间信息
+  space: {
+    spaceName: string;                 // 空间名称
+    area: number;                      // 面积
+    dimensions: {                      // 尺寸
+      length: number;
+      width: number; 
+      height: number;
+    };
+    features: string[];                // 空间特征
+    constraints: string[];             // 限制条件
+    priority: number;                  // 优先级 (1-10)
+    complexity: string;                // 复杂度 ('simple' | 'medium' | 'complex')
+  };
+  
+  // 报价信息
+  quotation: {
+    price: number;                     // 价格
+    currency: string;                  // 货币
+    breakdown: object;                 // 价格明细
+    status: string;                    // 报价状态
+    validUntil: Date;                  // 有效期
+  };
+  
+  // 需求信息
+  requirements: {
+    colorRequirement: object;          // 色彩需求
+    spaceStructureRequirement: object; // 空间结构需求
+    materialRequirement: object;       // 材质需求
+    lightingRequirement: object;       // 照明需求
+    specificRequirements: object;      // 特殊需求
+  };
+  
+  profile: Pointer<Profile>;           // 设计师
+  images: string[];                    // 空间图片URLs
+}
+```
+
+### 3.2 Project表中的空间场景字段
+**位置**: `Project.data.quotation.spaces` 数组
+```typescript
+// 报价明细中的空间信息
+data.quotation = {
+  spaces: [
+    {
+      name: string;          // 空间名称 (如: "客厅", "主卧", "厨房")
+      type: string;          // 空间类型 (如: "living", "bedroom", "kitchen") 
+      area: number;          // 面积 (平方米)
+      price: number;         // 单价
+      totalPrice: number;    // 总价
+      description?: string;  // 描述
+      productId?: string;    // 关联的Product ID (如果已创建)
+    }
+  ],
+  totalPrice: number;        // 总价
+  currency: string;          // 货币
+  validUntil: Date;         // 有效期
+}
+```
+
+### 3.3 空间场景提取逻辑
+**从Product表提取**:
+```typescript
+// 获取项目所有产品空间
+const products = await productSpaceService.getProjectProductSpaces(projectId);
+
+products.forEach(product => {
+  const spaceName = product.name || product.space?.spaceName;
+  const spaceType = product.type || product.space?.spaceType;
+  const area = product.space?.area;
+  const complexity = product.space?.complexity;
+  const priority = product.space?.priority;
+  const status = product.status;
+});
+```
+
+**从Project.data提取**:
+```typescript
+// 从报价明细提取空间信息
+const data = project.get('data') || {};
+const quotationSpaces = data.quotation?.spaces || [];
+
+quotationSpaces.forEach(space => {
+  const spaceName = space.name;
+  const spaceType = space.type;
+  const area = space.area;
+  const price = space.price;
+  const productId = space.productId; // 关联的Product记录
+});
+```
+
+## 4. 已补充的字段结构
+
+### 4.1 Project.data 中已添加的字段
+
+```typescript
+// ✅ 已在确认需求阶段添加:阶段时间轴字段
+data.phaseDeadlines = {
+  modeling: {
+    startDate: Date;
+    deadline: Date;
+    estimatedDays: number;
+    status: 'not_started' | 'in_progress' | 'completed';
+    priority: 'high' | 'medium' | 'low';
+  };
+  softDecor: { /* 同上结构 */ };
+  rendering: { /* 同上结构 */ };
+  postProcessing: { /* 同上结构 */ };
+};
+
+// ✅ 已在确认需求阶段初始化,交付执行阶段动态更新:空间交付物汇总
+data.spaceDeliverableSummary = {
+  [productId: string]: {
+    spaceName: string;
+    totalDeliverables: number;
+    completedDeliverables: number;
+    completionRate: number;
+    lastUpdateTime: string;
+    phaseProgress: {
+      white_model: number;    // 0-100 (审批通过=100, 待审批=80, 驳回=50)
+      soft_decor: number;
+      rendering: number; 
+      post_process: number;
+    };
+  };
+  overallCompletionRate: number; // 整体完成率
+};
+
+// ✅ 已在确认需求阶段添加:需求确认详细信息
+data.requirementsDetail = {
+  globalRequirements: object;     // 全局需求
+  spaceRequirements: object[];    // 空间需求
+  crossSpaceRequirements: object[]; // 跨空间需求
+  referenceImages: object[];      // 参考图片信息
+  cadFiles: object[];            // CAD文件信息
+  aiAnalysisResults: object;     // AI分析结果
+  confirmedAt: string;           // 确认时间
+};
+```
+
+### 4.2 ProjectFile.data 中已添加的字段
+
+```typescript
+// ✅ 已在需求阶段和交付阶段文件上传时添加:文件关联信息
+data.spaceId = string;           // 关联的空间/产品ID
+data.deliveryType = string;      // 交付类型标识
+data.uploadedFor = string;       // 上传用途
+data.uploadStage = string;       // 上传阶段 ('requirements' | 'delivery')
+
+// ✅ 已添加:AI分析结果结构
+data.analysis = {
+  ai: {
+    // 图片分析结果
+    styleElements?: string[];
+    colorPalette?: string[];
+    materialAnalysis?: string[];
+    layoutFeatures?: string[];
+    mood?: string;
+    confidence?: number;
+    // CAD分析结果  
+    spaceStructure?: object;
+    dimensions?: object;
+    constraints?: string[];
+    opportunities?: string[];
+    // 通用字段
+    analyzedAt: string;
+    version: string;
+    source: string;
+  };
+  manual: object | null;         // 手动分析结果
+  lastAnalyzedAt: string | null; // 最后分析时间
+  // 交付文件专用字段
+  qualityScore?: number | null;   // 质量评分
+  designCompliance?: object | null; // 设计合规性
+};
+
+// ✅ 需求阶段CAD文件额外字段
+data.cadFormat = string;         // CAD格式 (dwg/dxf/pdf)
+
+// ✅ 交付阶段文件额外字段  
+data.approvalStatus = string;    // 审批状态 ('unverified' | 'pending' | 'approved' | 'rejected')
+```
+
+### 4.3 字段补充实现位置
+
+**确认需求阶段** (`stage-requirements.component.ts`):
+- ✅ `requirementsDetail` - 需求确认详细信息 (行1368-1390)
+- ✅ `phaseDeadlines` - 阶段截止时间初始化 (行1392-1436) 
+- ✅ `spaceDeliverableSummary` - 空间交付物汇总初始化 (行1438-1467)
+- ✅ 参考图片 `ProjectFile.data` 补充 (行445-459)
+- ✅ CAD文件 `ProjectFile.data` 补充 (行607-626)
+- ✅ AI分析结果保存到 `ProjectFile.data.analysis.ai` (行802-833)
+
+**交付执行阶段** (`stage-delivery.component.ts`):
+- ✅ 交付文件 `ProjectFile.data` 补充 (行685-703)
+- ✅ `spaceDeliverableSummary` 动态更新 (行1569, 1863-1929)
+- ✅ 审批状态变更时更新交付物进度
+
+## 5. 字段使用示例
+
+### 5.1 获取确认需求时间
+```typescript
+const project = await projectQuery.get(projectId);
+const data = project.get('data') || {};
+const requirementsConfirmedAt = data.requirementsConfirmedAt; // ISO字符串
+const confirmedTime = new Date(requirementsConfirmedAt);
+```
+
+### 5.2 获取交付阶段状态
+```typescript
+const data = project.get('data') || {};
+const deliveryStatus = data.deliveryStageStatus || {};
+
+// 获取白模阶段状态
+const whiteModelStatus = deliveryStatus.white_model?.status || 'not_started';
+const whiteModelApprovedAt = deliveryStatus.white_model?.approvedAt;
+
+// 检查所有阶段完成情况
+const allStages = ['white_model', 'soft_decor', 'rendering', 'post_process'];
+const completedStages = allStages.filter(stage => 
+  deliveryStatus[stage]?.status === 'approved'
+);
+```
+
+### 5.3 获取空间场景信息
+```typescript
+// 方法1: 从Product表获取
+const products = await productSpaceService.getProjectProductSpaces(projectId);
+const spaceScenes = products.map(p => ({
+  id: p.id,
+  name: p.name,
+  type: p.type,
+  area: p.space?.area,
+  status: p.status,
+  complexity: p.space?.complexity
+}));
+
+// 方法2: 从Project.data获取
+const data = project.get('data') || {};
+const quotationSpaces = data.quotation?.spaces || [];
+const spaceScenes = quotationSpaces.map(s => ({
+  name: s.name,
+  type: s.type, 
+  area: s.area,
+  price: s.price,
+  productId: s.productId
+}));
+```
+
+## 6. 数据同步建议
+
+### 6.1 确保数据一致性
+- Product表中的空间信息应与Project.data.quotation.spaces保持同步
+- 交付阶段状态变更时,同时更新Project.currentStage字段
+- 空间名称修改时,同步更新所有关联的ProjectFile记录
+
+### 6.2 性能优化
+- 使用include查询减少网络请求: `query.include('contact', 'assignee', 'department')`
+- 批量操作时使用Parse.Object.saveAll()
+- 大数据量时使用分页查询: `query.limit(100).skip(offset)`
+
+---
+
+**文档生成时间**: 2025-11-13  
+**基于代码版本**: yss-project latest  
+**分析覆盖文件**: 
+- stage-requirements.component.ts
+- stage-delivery.component.ts  
+- product-space.service.ts
+- 相关数据模型定义

+ 98 - 1
src/modules/project/pages/project-detail/stages/stage-delivery.component.ts

@@ -669,7 +669,10 @@ export class StageDeliveryComponent implements OnInit, OnDestroy {
             // ✨ 新增:设置初始审批状态为"未验证"
             approvalStatus: 'unverified',
             uploadedByName: this.currentUser?.get('name') || '',
-            uploadedById: this.currentUser?.id || ''
+            uploadedById: this.currentUser?.id || '',
+            // 补充:添加关联空间ID和交付类型标识
+            spaceId: productId,
+            uploadStage: 'delivery'
           },
           (progress) => {
             // 计算总体进度
@@ -678,6 +681,26 @@ export class StageDeliveryComponent implements OnInit, OnDestroy {
             this.cdr.markForCheck();
           }
         );
+
+        // 补充:为交付文件ProjectFile添加扩展数据字段
+        const existingData = projectFile.get('data') || {};
+        projectFile.set('data', {
+          ...existingData,
+          spaceId: productId,
+          deliveryType: deliveryType,
+          uploadedFor: 'delivery_execution',
+          approvalStatus: 'unverified',
+          uploadStage: 'delivery',
+          analysis: {
+            // 预留分析结果字段
+            ai: null,
+            manual: null,
+            lastAnalyzedAt: null,
+            qualityScore: null,
+            designCompliance: null
+          }
+        });
+        await projectFile.save();
         
         console.log('✅ ProjectFile 创建成功:', projectFile.id);
 
@@ -1542,6 +1565,9 @@ export class StageDeliveryComponent implements OnInit, OnDestroy {
       data.deliveryStageStatus[stageKey].approvedBy = this.currentUser.id;
       data.deliveryStageStatus[stageKey].approvedByName = this.currentUser.get('name');
       data.deliveryStageStatus[stageKey].approvedAt = now;
+
+      // 补充:更新空间交付物汇总
+      this.updateSpaceDeliverableSummary(data, currentType, 'approved');
       
       // 兼容旧字段:设置总体审批状态
       data.deliveryApprovalStatus = 'approved';
@@ -1830,4 +1856,75 @@ export class StageDeliveryComponent implements OnInit, OnDestroy {
       this.cdr.markForCheck();
     }
   }
+
+  /**
+   * 补充:更新空间交付物汇总
+   */
+  private updateSpaceDeliverableSummary(data: any, deliveryType: string, status: 'approved' | 'rejected' | 'pending'): void {
+    try {
+      if (!data.spaceDeliverableSummary) {
+        data.spaceDeliverableSummary = {};
+      }
+
+      // 为每个产品空间更新交付物汇总
+      this.projectProducts.forEach(product => {
+        if (!data.spaceDeliverableSummary[product.id]) {
+          data.spaceDeliverableSummary[product.id] = {
+            spaceName: product.name,
+            totalDeliverables: 4, // 白模、软装、渲染、后期各1个
+            completedDeliverables: 0,
+            completionRate: 0,
+            lastUpdateTime: new Date().toISOString(),
+            phaseProgress: {
+              white_model: 0,
+              soft_decor: 0,
+              rendering: 0,
+              post_process: 0
+            }
+          };
+        }
+
+        const summary = data.spaceDeliverableSummary[product.id];
+        
+        // 更新阶段进度
+        if (status === 'approved') {
+          summary.phaseProgress[deliveryType] = 100;
+        } else if (status === 'pending') {
+          summary.phaseProgress[deliveryType] = 80; // 已提交待审批
+        } else if (status === 'rejected') {
+          summary.phaseProgress[deliveryType] = 50; // 被驳回需重新提交
+        }
+
+        // 重新计算完成的交付物数量
+        const completedPhases = Object.values(summary.phaseProgress).filter(progress => progress === 100).length;
+        summary.completedDeliverables = completedPhases;
+        summary.completionRate = Math.round((completedPhases / summary.totalDeliverables) * 100);
+        summary.lastUpdateTime = new Date().toISOString();
+      });
+
+      // 计算整体完成率
+      let totalDeliverables = 0;
+      let totalCompleted = 0;
+      
+      Object.values(data.spaceDeliverableSummary).forEach((summary: any) => {
+        if (summary.totalDeliverables !== undefined) {
+          totalDeliverables += summary.totalDeliverables;
+          totalCompleted += summary.completedDeliverables || 0;
+        }
+      });
+
+      data.spaceDeliverableSummary.overallCompletionRate = totalDeliverables > 0 
+        ? Math.round((totalCompleted / totalDeliverables) * 100) 
+        : 0;
+
+      console.log('✅ 空间交付物汇总已更新:', {
+        deliveryType,
+        status,
+        overallCompletionRate: data.spaceDeliverableSummary.overallCompletionRate
+      });
+
+    } catch (error) {
+      console.error('❌ 更新空间交付物汇总失败:', error);
+    }
+  }
 }

+ 169 - 8
src/modules/project/pages/project-detail/stages/stage-requirements.component.ts

@@ -431,13 +431,33 @@ export class StageRequirementsComponent implements OnInit {
           'requirements', // stage参数
           {
             imageType: 'style',
-            uploadedFor: 'requirements_analysis'
+            uploadedFor: 'requirements_analysis',
+            // 补充:添加关联空间ID和交付类型标识
+            spaceId: targetProductId,
+            deliveryType: 'requirements_reference', // 需求阶段参考图片
+            uploadStage: 'requirements'
           },
           (progress) => {
             console.log(`上传进度: ${progress}%`);
           }
         );
 
+        // 补充:为ProjectFile添加扩展数据字段
+        const existingData = projectFile.get('data') || {};
+        projectFile.set('data', {
+          ...existingData,
+          spaceId: targetProductId,
+          deliveryType: 'requirements_reference',
+          uploadedFor: 'requirements_analysis',
+          analysis: {
+            // 预留AI分析结果字段
+            ai: null,
+            manual: null,
+            lastAnalyzedAt: null
+          }
+        });
+        await projectFile.save();
+
         // 创建参考图片记录
         const uploadedFile = {
           id: projectFile.id || '',
@@ -573,13 +593,38 @@ export class StageRequirementsComponent implements OnInit {
           'requirements', // stage参数
           {
             cadFormat: fileExtension.replace('.', ''),
-            uploadedFor: 'requirements_analysis'
+            uploadedFor: 'requirements_analysis',
+            // 补充:添加关联空间ID和交付类型标识
+            spaceId: targetProductId,
+            deliveryType: 'requirements_cad',
+            uploadStage: 'requirements'
           },
           (progress) => {
             console.log(`上传进度: ${progress}%`);
           }
         );
 
+        // 补充:为CAD文件ProjectFile添加扩展数据字段
+        const existingData = projectFile.get('data') || {};
+        projectFile.set('data', {
+          ...existingData,
+          spaceId: targetProductId,
+          deliveryType: 'requirements_cad',
+          uploadedFor: 'requirements_analysis',
+          cadFormat: fileExtension.replace('.', ''),
+          analysis: {
+            // 预留CAD分析结果字段
+            ai: null,
+            manual: null,
+            lastAnalyzedAt: null,
+            spaceStructure: null,
+            dimensions: null,
+            constraints: [],
+            opportunities: []
+          }
+        });
+        await projectFile.save();
+
         // 创建CAD文件记录
         const uploadedFile = {
           id: projectFile.id || '',
@@ -754,25 +799,40 @@ export class StageRequirementsComponent implements OnInit {
    */
   private async saveImageAnalysisToProjectFile(projectFile: any, analysisResult: any): Promise<void> {
     try {
-      // 获取现有的analysis对象
-      const currentAnalysis = projectFile.get('analysis') || {};
+      // 补充:更新ProjectFile.data.analysis.ai字段(与现有analysis字段并存)
+      const existingData = projectFile.get('data') || {};
+      const existingAnalysis = existingData.analysis || {};
+      
+      // 保存AI分析结果到data.analysis.ai字段
+      existingAnalysis.ai = {
+        ...analysisResult,
+        analyzedAt: new Date().toISOString(),
+        version: '1.0',
+        source: 'image_analysis'
+      };
+      existingAnalysis.lastAnalyzedAt = new Date().toISOString();
+
+      existingData.analysis = existingAnalysis;
+      projectFile.set('data', existingData);
 
-      // 保存AI分析结果到analysis.ai字段
+      // 兼容:同时保存到原有的analysis字段
+      const currentAnalysis = projectFile.get('analysis') || {};
       currentAnalysis.ai = {
         ...analysisResult,
         analyzedAt: new Date().toISOString(),
         version: '1.0',
         source: 'image_analysis'
       };
-
-      // 更新ProjectFile
       projectFile.set('analysis', currentAnalysis);
+
+      // 确保关联Product
       if(!projectFile?.get("product")?.id && projectFile?.get("data")?.spaceId){
         projectFile.set("product",{__type:"Pointer",className:"Product",objectId:projectFile?.get("data")?.spaceId})
       }
+      
       await projectFile.save();
 
-      console.log('图片分析结果已保存到ProjectFile.analysis.ai');
+      console.log('图片分析结果已保存到ProjectFile.data.analysis.ai和ProjectFile.analysis.ai');
     } catch (error) {
       console.error('保存分析结果失败:', error);
     }
@@ -1365,6 +1425,107 @@ ${context}
       data.requirementsConfirmedByName = this.currentUser.get('name');
       data.requirementsConfirmedAt = new Date().toISOString();
 
+      // 补充:需求确认详细信息
+      data.requirementsDetail = {
+        globalRequirements: this.globalRequirements,
+        spaceRequirements: this.spaceRequirements,
+        crossSpaceRequirements: this.crossSpaceRequirements,
+        referenceImages: this.referenceImages.map(img => ({
+          id: img.id,
+          url: img.url,
+          name: img.name,
+          type: img.type,
+          spaceId: img.spaceId,
+          tags: img.tags
+        })),
+        cadFiles: this.cadFiles.map(file => ({
+          id: file.id,
+          url: file.url,
+          name: file.name,
+          size: file.size,
+          spaceId: file.spaceId
+        })),
+        aiAnalysisResults: this.aiAnalysisResults,
+        confirmedAt: new Date().toISOString()
+      };
+
+      // 补充:初始化阶段截止时间 (基于项目交付日期推算)
+      if (!data.phaseDeadlines && this.project.get('deadline')) {
+        const deliveryDate = new Date(this.project.get('deadline'));
+        const startDate = new Date();
+        const totalDays = Math.ceil((deliveryDate.getTime() - startDate.getTime()) / (24 * 60 * 60 * 1000));
+        
+        // 按比例分配各阶段时间:建模30%,软装25%,渲染30%,后期15%
+        const modelingDays = Math.ceil(totalDays * 0.3);
+        const softDecorDays = Math.ceil(totalDays * 0.25);
+        const renderingDays = Math.ceil(totalDays * 0.3);
+        const postProcessDays = totalDays - modelingDays - softDecorDays - renderingDays;
+
+        let currentDate = new Date(startDate);
+        
+        data.phaseDeadlines = {
+          modeling: {
+            startDate: new Date(currentDate),
+            deadline: new Date(currentDate.setDate(currentDate.getDate() + modelingDays)),
+            estimatedDays: modelingDays,
+            status: 'not_started',
+            priority: 'high'
+          },
+          softDecor: {
+            startDate: new Date(currentDate),
+            deadline: new Date(currentDate.setDate(currentDate.getDate() + softDecorDays)),
+            estimatedDays: softDecorDays,
+            status: 'not_started',
+            priority: 'medium'
+          },
+          rendering: {
+            startDate: new Date(currentDate),
+            deadline: new Date(currentDate.setDate(currentDate.getDate() + renderingDays)),
+            estimatedDays: renderingDays,
+            status: 'not_started',
+            priority: 'high'
+          },
+          postProcessing: {
+            startDate: new Date(currentDate),
+            deadline: new Date(currentDate.setDate(currentDate.getDate() + postProcessDays)),
+            estimatedDays: postProcessDays,
+            status: 'not_started',
+            priority: 'medium'
+          }
+        };
+      }
+
+      // 补充:初始化空间交付物汇总
+      if (!data.spaceDeliverableSummary && this.projectProducts.length > 0) {
+        data.spaceDeliverableSummary = {};
+        let totalDeliverables = 0;
+        let completedDeliverables = 0;
+
+        this.projectProducts.forEach(product => {
+          const productSummary = {
+            spaceName: product.name,
+            totalDeliverables: 4, // 白模、软装、渲染、后期各1个
+            completedDeliverables: 0,
+            completionRate: 0,
+            lastUpdateTime: new Date().toISOString(),
+            phaseProgress: {
+              white_model: 0,
+              soft_decor: 0,
+              rendering: 0,
+              post_process: 0
+            }
+          };
+          
+          data.spaceDeliverableSummary[product.id] = productSummary;
+          totalDeliverables += productSummary.totalDeliverables;
+          completedDeliverables += productSummary.completedDeliverables;
+        });
+
+        data.spaceDeliverableSummary.overallCompletionRate = totalDeliverables > 0 
+          ? Math.round((completedDeliverables / totalDeliverables) * 100) 
+          : 0;
+      }
+
       // 派发阶段完成事件,通知父组件前进
       console.log('📡 [确认需求] 派发 stage:completed 事件');
         try {