Эх сурвалжийг харах

Merge branch 'master' of http://git.fmode.cn:3000/nkkj/yss-project

Future 23 цаг өмнө
parent
commit
a4f49bba4f

+ 2 - 2
deploy.ps1

@@ -6,13 +6,13 @@
 # yss-project 子项目名称
 # /dev/ 项目测试版上传路径
 # /dev/crm yss-project项目预留路径
-ng build yss-project --base-href=/dev/yss/
+NODE_OPTIONS="--max-old-space-size=24192" ng build yss-project --base-href=/dev/yss/
 
 # 清空旧文件目录
 obsutil rm obs://nova-cloud/dev/yss -r -f -i=XSUWJSVMZNHLWFAINRZ1 -k=P4TyfwfDovVNqz08tI1IXoLWXyEOSTKJRVlsGcV6 -e="obs.cn-south-1.myhuaweicloud.com"
 
 # 同步文件目录
-obsutil sync ./dist/yss-project/browser obs://nova-cloud/dev/yss  -i=XSUWJSVMZNHLWFAINRZ1 -k=P4TyfwfDovVNqz08tI1IXoLWXyEOSTKJRVlsGcV6 -e="obs.cn-south-1.myhuaweicloud.com" -acl=public-read
+obsutil sync ./dist/yss-project/ obs://nova-cloud/dev/yss  -i=XSUWJSVMZNHLWFAINRZ1 -k=P4TyfwfDovVNqz08tI1IXoLWXyEOSTKJRVlsGcV6 -e="obs.cn-south-1.myhuaweicloud.com" -acl=public-read
 
 # 授权公开可读
 obsutil chattri obs://nova-cloud/dev/yss -r -f -i=XSUWJSVMZNHLWFAINRZ1 -k=P4TyfwfDovVNqz08tI1IXoLWXyEOSTKJRVlsGcV6 -e="obs.cn-south-1.myhuaweicloud.com" -acl=public-read

+ 1136 - 2916
docs/prd/项目-售后归档.md

@@ -1,3110 +1,1330 @@
-# 项目管理 - 售后归档阶段 PRD (Product表版本)
-
-## 1. 功能概述
-
-### 1.1 阶段定位
-售后归档阶段是项目管理流程的收尾环节,包含尾款结算、全景图合成、客户评价、投诉处理、项目复盘五大核心模块。该阶段负责完成项目交付、收集反馈、总结经验,为后续项目优化提供数据支撑。
-
-### 1.2 核心目标
-- **多产品设计售后管理**:基于Product表实现单产品到多产品项目的差异化管理
-- **实现自动化尾款结算流程**
-- **按产品生成全景图分享链接**
-- **收集客户多维度评价(按产品维度)**
-- **处理客户投诉反馈(产品定位)**
-- **生成多产品项目复盘报告**
-
-### 1.3 涉及角色
-- **客服人员**:跟进尾款支付、发送评价链接、处理投诉
-- **技术人员**:验收交付物、启动自动结算、合成全景图
-- **组长**:审核复盘报告、处理投诉、优化流程
-- **财务人员**:确认款项到账、核对支付凭证
-
-### 1.4 多产品设计售后特性
-
-#### 1.4.1 产品差异化售后策略
-- **单产品设计项目**:标准售后流程,统一结算和评价
-- **双产品设计项目**:按产品独立生成全景图,支持分别评价
-- **多产品设计项目**:
-  - 分产品尾款结算(支持按产品或整体结算)
-  - 产品全景图合集(支持单产品查看和全屋漫游)
-  - 分产品客户评价(支持整体和细分产品评价)
-  - 产品定位的投诉处理
-  - 多维度项目复盘(产品间对比分析)
-
-#### 1.4.2 产品间协同售后
-```mermaid
-graph TD
-    A[所有产品设计完成] --> B{是否多产品设计项目?}
-    B -->|否| C[单产品设计售后流程]
-    B -->|是| D[多产品协同售后]
-
-    D --> E[产品设计质量检查]
-    D --> F[跨产品一致性验证]
-    D --> G[整体结算策略选择]
-    D --> H[全景图合成方案确定]
-
-    E --> I[产品间对比分析]
-    F --> I
-    G --> J[分产品/整体结算]
-    H --> K[产品全景图合集]
-    I --> L[多产品复盘报告]
-    J --> M[客户多维度评价]
-    K --> N[产品漫游体验]
-    L --> O[项目归档完成]
-    M --> O
-    N --> O
-
-    style C fill:#e8f5e9
-    style D fill:#fff3e0
-    style O fill:#e3f2fd
-```
-
-## 2. 多产品尾款结算模块
-
-### 2.1 基于Product表的多产品结算策略
-
-#### 2.1.1 结算模式选择
-```typescript
-interface MultiProductSettlementStrategy {
-  mode: 'unified' | 'separated' | 'hybrid';     // 统一结算/分产品结算/混合模式
-  products: string[];                            // 参与结算的产品ID列表
-  settlementBreakdown: ProductSettlementBreakdown[]; // 产品结算明细
-  discounts: SettlementDiscount[];               // 多产品优惠
-  paymentSchedule: PaymentSchedule[];            // 付款计划
-}
-
-interface ProductSettlementBreakdown {
-  productId: string;
-  productName: string;
-  productType: string;                           // "bedroom", "living_room" 等
-  totalAmount: number;
-  paidAmount: number;
-  remainingAmount: number;
-  completionPercentage: number;                  // 该产品完成度
-  isFullyDelivered: boolean;                    // 是否完全交付
-  specialNotes?: string;                        // 特殊说明
-}
-
-class MultiProductSettlementManager {
-  // 智能推荐结算模式
-  recommendSettlementMode(products: Product[]): SettlementModeRecommendation {
-    const totalProducts = products.length;
-    const completedProducts = products.filter(p => p.status === 'completed').length;
-    const highPriorityProducts = products.filter(p => p.space?.priority >= 8).length;
-
-    // 策略1:所有产品都完成且优先级相似,推荐统一结算
-    if (completedProducts === totalProducts && this.hasSimilarPriority(products)) {
-      return {
-        recommendedMode: 'unified',
-        confidence: 0.9,
-        reason: '所有产品已完成且优先级相近,统一结算更便捷'
-      };
-    }
-
-    // 策略2:高优先级产品已完成,推荐混合模式
-    if (highPriorityProducts > 0 && highPriorityProducts === completedProducts) {
-      return {
-        recommendedMode: 'hybrid',
-        confidence: 0.8,
-        reason: '高优先级产品已完成,可以优先结算'
-      };
-    }
-
-    // 策略3:产品完成情况差异大,推荐分产品结算
-    if (this.hasVariableCompletion(products)) {
-      return {
-        recommendedMode: 'separated',
-        confidence: 0.85,
-        reason: '各产品完成情况差异较大,分产品结算更清晰'
-      };
-    }
-
-    // 默认推荐统一结算
-    return {
-      recommendedMode: 'unified',
-      confidence: 0.6,
-      reason: '标准项目,统一结算'
-    };
-  }
-
-  // 计算多产品优惠
-  calculateMultiProductDiscount(
-    products: Product[],
-    baseTotal: number
-  ): SettlementDiscount[] {
-    const discounts: SettlementDiscount[] = [];
-
-    // 1. 产品数量折扣
-    if (products.length >= 5) {
-      discounts.push({
-        type: 'product_count',
-        description: '5产品及以上项目享受10%折扣',
-        value: baseTotal * 0.1,
-        applicable: true
-      });
-    } else if (products.length >= 3) {
-      discounts.push({
-        type: 'product_count',
-        description: '3-4产品项目享受5%折扣',
-        value: baseTotal * 0.05,
-        applicable: true
-      });
-    }
-
-    // 2. 优先级折扣
-    const highPriorityCount = products.filter(p => p.space?.priority >= 8).length;
-    if (highPriorityCount === products.length) {
-      discounts.push({
-        type: 'high_priority',
-        description: '全高优先级产品项目额外5%折扣',
-        value: baseTotal * 0.05,
-        applicable: true
-      });
-    }
-
-    // 3. 同时完成折扣
-    const completedWithinTimeframe = this.getProductsCompletedWithinTimeframe(products, 7); // 7天内
-    if (completedWithinTimeframe.length === products.length) {
-      discounts.push({
-        type: 'simultaneous_completion',
-        description: '所有产品同时完成享受3%折扣',
-        value: baseTotal * 0.03,
-        applicable: true
-      });
-    }
-
-    return discounts;
-  }
-
-  // 生成结算报告
-  generateSettlementReport(
-    strategy: MultiProductSettlementStrategy,
-    products: Product[]
-  ): SettlementReport {
-    const report: SettlementReport = {
-      projectId: this.getProjectId(),
-      settlementDate: new Date(),
-      strategy: strategy.mode,
-      totalProducts: products.length,
-      completedProducts: products.filter(p => p.status === 'completed').length,
-
-      // 财务明细
-      financials: {
-        totalBaseAmount: this.calculateBaseAmount(products),
-        discounts: strategy.discounts,
-        finalAmount: this.calculateFinalAmount(products, strategy.discounts),
-        paidAmount: this.calculatePaidAmount(products),
-        remainingAmount: 0
-      },
-
-      // 产品详情
-      productDetails: strategy.settlementBreakdown.map(breakdown => ({
-        productId: breakdown.productId,
-        productName: breakdown.productName,
-        productType: breakdown.productType,
-        totalAmount: breakdown.totalAmount,
-        discountApplied: this.getProductDiscount(breakdown.productId, strategy.discounts),
-        finalAmount: breakdown.remainingAmount,
-        completionStatus: breakdown.isFullyDelivered ? 'completed' : 'partial',
-        deliveryQuality: this.assessDeliveryQuality(breakdown.productId)
-      })),
-
-      // 风险评估
-      riskAssessment: this.assessSettlementRisks(products, strategy),
-
-      // 建议
-      recommendations: this.generateSettlementRecommendations(products, strategy)
-    };
-
-    return report;
-  }
-}
-
-interface SettlementModeRecommendation {
-  recommendedMode: 'unified' | 'separated' | 'hybrid';
-  confidence: number;    // 推荐置信度 0-1
-  reason: string;        // 推荐理由
-}
-
-interface SettlementDiscount {
-  type: 'space_count' | 'high_priority' | 'simultaneous_completion' | 'early_payment';
-  description: string;
-  value: number;
-  applicable: boolean;
-}
-
-interface SettlementReport {
-  projectId: string;
-  settlementDate: Date;
-  strategy: string;
-  totalSpaces: number;
-  completedSpaces: number;
-  financials: {
-    totalBaseAmount: number;
-    discounts: SettlementDiscount[];
-    finalAmount: number;
-    paidAmount: number;
-    remainingAmount: number;
-  };
-  spaceDetails: any[];
-  riskAssessment: any;
-  recommendations: string[];
-}
-```
-
-## 3. 多产品全景图合成模块
-
-### 3.1 基于Product表的产品全景图管理
-
-#### 3.1.1 全景图合成策略
-```typescript
-class MultiProductPanoramaManager {
-  // 生成产品全景图合集
-  async generateProductPanoramaCollection(
-    products: Product[],
-    synthesisOptions: PanoramaSynthesisOptions
-  ): Promise<PanoramaCollection> {
-
-    const collection: PanoramaCollection = {
-      id: `collection_${Date.now()}`,
-      projectId: this.getProjectId(),
-      totalProducts: products.length,
-      synthesisStrategy: synthesisOptions.strategy,
-
-      // 单产品全景图
-      productPanoramas: [],
-
-      // 跨产品连接
-      productConnections: [],
-
-      // 全屋漫游
-      fullHouseTour: null,
-
-      // 分享链接
-      shareLinks: {
-        collection: '',
-        individualProducts: {} as Record<string, string>
-      },
-
-      createdAt: new Date(),
-      status: 'processing'
-    };
-
-    // 1. 生成各产品独立全景图
-    for (const product of products) {
-      const productPanorama = await this.generateProductPanorama(product, synthesisOptions);
-      collection.productPanoramas.push(productPanorama);
-    }
-
-    // 2. 分析产品间连接关系
-    collection.productConnections = await this.analyzeProductConnections(products);
-
-    // 3. 生成全屋漫游(如果是多产品项目)
-    if (products.length > 1) {
-      collection.fullHouseTour = await this.generateFullHouseTour(
-        collection.productPanoramas,
-        collection.productConnections
-      );
-    }
-
-    // 4. 生成分享链接
-    collection.shareLinks = await this.generatePanoramaShareLinks(collection);
-
-    // 5. 保存并返回结果
-    await this.savePanoramaCollection(collection);
-
-    return collection;
-  }
-
-  // 生成单产品全景图
-  private async generateProductPanorama(
-    product: Product,
-    options: PanoramaSynthesisOptions
-  ): Promise<ProductPanorama> {
-
-    // 获取产品的最终交付图片
-    const finalImages = await this.getProductFinalImages(product.id);
-
-    // KR Panel 集成
-    const krPanelConfig = {
-      spaceType: product.productType,
-      spaceName: product.productName,
-      images: finalImages,
-      synthesisQuality: options.quality,
-      outputFormat: options.format,
-      includeHotspots: options.includeHotspots,
-      backgroundMusic: options.backgroundMusic
-    };
-
-    // 调用 KR Panel 合成
-    const panoramaData = await this.krPanelService.synthesizePanorama(krPanelConfig);
-
-    return {
-      id: `panorama_${product.id}_${Date.now()}`,
-      productId: product.id,
-      productName: product.productName,
-      productType: product.productType,
-
-      // 全景图资源
-      panoramaUrl: panoramaData.panoramaUrl,
-      thumbnailUrl: panoramaData.thumbnailUrl,
-      previewImages: panoramaData.previewImages,
-
-      // 热点信息
-      hotspots: panoramaData.hotspots || [],
-
-      // 技术参数
-      resolution: panoramaData.resolution,
-      fileSize: panoramaData.fileSize,
-      renderTime: panoramaData.renderTime,
-
-      // 元数据
-      metadata: {
-        createdAt: new Date(),
-        synthesisEngine: 'KR Panel',
-        quality: options.quality,
-        imageCount: finalImages.length
-      }
-    };
-  }
-
-  // 分析产品连接关系
-  private async analyzeProductConnections(products: Product[]): Promise<ProductConnection[]> {
-    const connections: ProductConnection[] = [];
-
-    // 基于产品类型和位置推断连接关系
-    for (let i = 0; i < products.length; i++) {
-      for (let j = i + 1; j < products.length; j++) {
-        const product1 = products[i];
-        const product2 = products[j];
-
-        const connection = await this.determineProductConnection(product1, product2);
-        if (connection) {
-          connections.push(connection);
-        }
-      }
-    }
-
-    return connections;
-  }
-
-  private async determineProductConnection(
-    product1: Product,
-    product2: Product
-  ): Promise<ProductConnection | null> {
-    // 定义常见的产品连接关系
-    const connectionRules = [
-      {
-        from: 'living_room',
-        to: 'dining_room',
-        type: 'direct',
-        transitionStyle: 'open_passage',
-        likelihood: 0.9
-      },
-      {
-        from: 'living_room',
-        to: 'corridor',
-        type: 'direct',
-        transitionStyle: 'doorway',
-        likelihood: 0.8
-      },
-      {
-        from: 'bedroom',
-        to: 'corridor',
-        type: 'direct',
-        transitionStyle: 'doorway',
-        likelihood: 0.9
-      },
-      {
-        from: 'kitchen',
-        to: 'dining_room',
-        type: 'direct',
-        transitionStyle: 'open_passage',
-        likelihood: 0.7
-      }
-    ];
-
-    // 查找匹配的连接规则
-    const rule = connectionRules.find(r =>
-      (r.from === product1.productType && r.to === product2.productType) ||
-      (r.from === product2.productType && r.to === product1.productType)
-    );
-
-    if (rule && rule.likelihood > 0.6) {
-      return {
-        fromProductId: product1.id,
-        toProductId: product2.id,
-        connectionType: rule.type,
-        transitionStyle: rule.transitionStyle,
-        confidence: rule.likelihood,
-        navigationLabel: `${product1.productName} → ${product2.productName}`,
-        estimatedDistance: this.estimateProductDistance(product1, product2)
-      };
-    }
-
-    return null;
-  }
-
-  // 生成全屋漫游
-  private async generateFullHouseTour(
-    panoramas: ProductPanorama[],
-    connections: ProductConnection[]
-  ): Promise<FullHouseTour> {
-
-    // 构建漫游路径
-    const tourPath = this.optimizeTourPath(panoramas, connections);
-
-    // 生成导航数据
-    const navigationData = {
-      panoramas: panoramas.map(p => ({
-        id: p.id,
-        name: p.productName,
-        type: p.productType,
-        url: p.panoramaUrl,
-        hotspots: p.hotspots
-      })),
-      connections: connections.map(c => ({
-        from: c.fromProductId,
-        to: c.toProductId,
-        type: c.connectionType,
-        style: c.transitionStyle,
-        label: c.navigationLabel
-      })),
-      path: tourPath
-    };
-
-    // 生成漫游配置
-    const tourConfig = {
-      autoPlay: true,
-      transitionDuration: 2000,
-      pauseDuration: 5000,
-      showNavigation: true,
-      backgroundMusic: 'soft_ambient',
-      quality: 'high'
-    };
-
-    return {
-      id: `tour_${Date.now()}`,
-      navigationData,
-      tourConfig,
-      totalDuration: this.calculateTourDuration(tourPath, tourConfig),
-      estimatedSize: this.estimateTourSize(panoramas),
-      generatedAt: new Date()
-    };
-  }
-}
-
-interface PanoramaSynthesisOptions {
-  strategy: 'individual' | 'connected' | 'full_house';
-  quality: 'standard' | 'high' | 'ultra';
-  format: 'jpg' | 'png' | 'webp';
-  includeHotspots: boolean;
-  backgroundMusic?: string;
-  maxFileSize?: number;
-}
-
-interface PanoramaCollection {
-  id: string;
-  projectId: string;
-  totalProducts: number;
-  synthesisStrategy: string;
-  productPanoramas: ProductPanorama[];
-  productConnections: ProductConnection[];
-  fullHouseTour?: FullHouseTour;
-  shareLinks: {
-    collection: string;
-    individualProducts: Record<string, string>;
-  };
-  createdAt: Date;
-  status: 'processing' | 'completed' | 'failed';
-}
-
-interface ProductPanorama {
-  id: string;
-  productId: string;
-  productName: string;
-  productType: string;
-  panoramaUrl: string;
-  thumbnailUrl: string;
-  previewImages: string[];
-  hotspots: PanoramaHotspot[];
-  resolution: { width: number; height: number };
-  fileSize: number;
-  renderTime: number;
-  metadata: any;
-}
-
-interface ProductConnection {
-  fromProductId: string;
-  toProductId: string;
-  connectionType: 'direct' | 'indirect' | 'external';
-  transitionStyle: 'doorway' | 'open_passage' | 'stair' | 'corridor';
-  confidence: number;
-  navigationLabel: string;
-  estimatedDistance: number;
-}
-
-interface FullHouseTour {
-  id: string;
-  navigationData: any;
-  tourConfig: any;
-  totalDuration: number;
-  estimatedSize: number;
-  generatedAt: Date;
-}
-```
-
-## 4. 多产品客户评价模块
-
-### 4.1 基于Product表的分产品评价系统
-
-#### 4.1.1 多维度评价结构
-```typescript
-interface MultiProductCustomerReview {
-  id: string;
-  projectId: string;
-  submittedAt: Date;
-
-  // 整体评价
-  overallReview: OverallReview;
-
-  // 产品评价
-  productReviews: ProductReview[];
-
-  // 跨产品评价
-  crossProductReview: CrossProductReview;
-
-  // 推荐意愿
-  recommendations: RecommendationData;
-}
-
-interface OverallReview {
-  // 整体满意度评分 (1-5星)
-  overallSatisfaction: number;
-
-  // 多维度评分
-  dimensionRatings: {
-    designQuality: number;         // 设计质量
-    productPlanning: number;       // 产品规划
-    colorCoordination: number;     // 色彩协调
-    functionality: number;         // 功能性
-    timeliness: number;            // 及时性
-    communication: number;         // 沟通效率
-    professionalism: number;       // 专业程度
-    valueForMoney: number;         // 性价比
-  };
-
-  // 文字评价
-  comments: {
-    strengths: string;            // 优点
-    improvements: string;         // 改进建议
-    overallImpression: string;    // 整体印象
-    additionalComments: string;   // 其他意见
-  };
-
-  // 最满意和最不满意的产品
-  mostSatisfiedProduct?: string;
-  leastSatisfiedProduct?: string;
-}
-
-interface ProductReview {
-  productId: string;
-  productName: string;
-  productType: string;             // "bedroom", "living_room" 等
-
-  // 产品满意度评分
-  satisfactionScore: number;
-
-  // 产品特定评分
-  productSpecificRatings: {
-    layoutDesign: number;         // 布局设计
-    functionality: number;         // 功能实现
-    aestheticAppeal: number;       // 美观度
-    practicality: number;         // 实用性
-    storageSolutions: number;      // 收纳方案
-    lighting: number;             // 灯光效果
-  };
-
-  // 产品使用反馈
-  usageFeedback: {
-    actualUsage: string;           // 实际使用情况
-    favoriteFeatures: string[];    // 最喜欢的特点
-    issuesEncountered: string[];   // 遇到的问题
-    modifications: string[];       // 后续改动
-    unexpectedBenefits: string[];  // 意外收获
-  };
-
-  // 产品文字评价
-  comments: {
-    whatWorkedWell: string;       // 做得好的地方
-    whatCouldBeBetter: string;     // 可以改进的地方
-    personalNotes: string;         // 个人备注
-  };
-
-  // 照片上传(实际使用后的照片)
-  afterPhotos?: string[];
-}
-
-interface CrossProductReview {
-  // 产品间一致性
-  consistencyRatings: {
-    styleConsistency: number;      // 风格一致性
-    colorFlow: number;             // 色彩流线
-    materialHarmony: number;       // 材质和谐
-    scaleProportion: number;       // 比例协调
-  };
-
-  // 动线体验
-  circulationExperience: {
-    flowLogic: number;             // 流线逻辑性
-    transitionSmoothness: number;  // 过渡流畅度
-    accessibility: number;         // 便利性
-  };
-
-  // 跨产品评价
-  crossProductComments: {
-    productRelationships: string;  // 产品关系
-    overallCohesion: string;       // 整体协调性
-    suggestedImprovements: string; // 改进建议
-  };
-}
-
-interface RecommendationData {
-  wouldRecommend: boolean;         // 是否推荐
-  likelihoodScore: number;         // 推荐意愿 0-10
-
-  // 推荐理由
-  recommendationReasons: string[];
-
-  // 不推荐原因(如果不推荐)
-  nonRecommendationReasons?: string[];
-
-  // 推荐给的人群
-  recommendedFor: string[];
-
-  // 联系信息(允许联系)
-  contactPermission: boolean;
-  contactInfo?: {
-    wechat?: string;
-    phone?: string;
-    email?: string;
-  };
-}
-
-class MultiProductReviewManager {
-  // 生成分产品评价链接
-  async generateMultiProductReviewLinks(
-    projectId: string,
-    products: Product[]
-  ): Promise<MultiProductReviewLinks> {
-
-    const links: MultiProductReviewLinks = {
-      projectId,
-      collectionLink: '',
-      productLinks: {} as Record<string, string>,
-      expiresAt: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000), // 30天后过期
-      createdAt: new Date()
-    };
-
-    // 1. 生成合集评价链接
-    links.collectionLink = await this.generateCollectionReviewLink(projectId, products);
-
-    // 2. 生成各产品独立评价链接
-    for (const product of products) {
-      const productLink = await this.generateProductReviewLink(projectId, product);
-      links.productLinks[product.id] = productLink;
-    }
-
-    // 3. 保存链接记录
-    await this.saveReviewLinks(links);
-
-    return links;
-  }
-
-  // 处理多产品评价提交
-  async processMultiProductReview(
-    reviewData: MultiProductCustomerReview
-  ): Promise<ReviewProcessingResult> {
-
-    const result: ReviewProcessingResult = {
-      success: false,
-      reviewId: '',
-      processingSteps: []
-    };
-
-    try {
-      // 1. 验证评价数据
-      await this.validateReviewData(reviewData);
-      result.processingSteps.push({ step: 'validation', status: 'completed' });
-
-      // 2. 保存评价数据
-      const savedReview = await this.saveMultiProductReview(reviewData);
-      result.reviewId = savedReview.id;
-      result.processingSteps.push({ step: 'saving', status: 'completed' });
-
-      // 3. 计算评价统计
-      const statistics = await this.calculateReviewStatistics(reviewData);
-      result.processingSteps.push({ step: 'statistics', status: 'completed' });
-
-      // 4. 更新项目评分
-      await this.updateProjectRating(reviewData.projectId, statistics);
-      result.processingSteps.push({ step: 'rating_update', status: 'completed' });
-
-      // 5. 发送通知
-      await this.sendReviewNotifications(reviewData);
-      result.processingSteps.push({ step: 'notifications', status: 'completed' });
-
-      result.success = true;
-
-    } catch (error) {
-      console.error('处理多产品评价失败:', error);
-      result.error = error.message;
-    }
-
-    return result;
-  }
-
-  // 分析评价数据
-  async analyzeMultiProductReviews(
-    projectId: string
-  ): Promise<MultiProductReviewAnalysis> {
-
-    // 获取项目的所有评价
-    const reviews = await this.getProjectReviews(projectId);
-
-    const analysis: MultiProductReviewAnalysis = {
-      projectId,
-      totalReviews: reviews.length,
-
-      // 整体分析
-      overallAnalysis: this.analyzeOverallReviews(reviews),
-
-      // 产品分析
-      productAnalysis: this.analyzeProductReviews(reviews),
-
-      // 跨产品分析
-      crossProductAnalysis: this.analyzeCrossProductReviews(reviews),
-
-      // 趋势分析
-      trendAnalysis: this.analyzeReviewTrends(reviews),
-
-      // 改进建议
-      improvementSuggestions: this.generateImprovementSuggestions(reviews),
-
-      // 对比分析
-      benchmarkComparison: await this.benchmarkAgainstIndustry(reviews)
-    };
-
-    return analysis;
-  }
-
-  private analyzeProductReviews(reviews: MultiProductCustomerReview[]): Record<string, ProductAnalysis> {
-    const productAnalysis: Record<string, ProductAnalysis> = {};
-
-    // 按产品分组统计
-    const reviewsByProduct: Record<string, ProductReview[]> = {};
-
-    for (const review of reviews) {
-      for (const productReview of review.productReviews) {
-        if (!reviewsByProduct[productReview.productId]) {
-          reviewsByProduct[productReview.productId] = [];
-        }
-        reviewsByProduct[productReview.productId].push(productReview);
-      }
-    }
-
-    // 分析每个产品
-    for (const [productId, productReviews] of Object.entries(reviewsByProduct)) {
-      const satisfactionScores = productReviews.map(r => r.satisfactionScore);
-      const averageSatisfaction = satisfactionScores.reduce((a, b) => a + b, 0) / satisfactionScores.length;
-
-      productAnalysis[productId] = {
-        productId,
-        productName: productReviews[0].productName,
-        productType: productReviews[0].productType,
-        totalReviews: productReviews.length,
-        averageSatisfaction,
-        satisfactionDistribution: this.calculateSatisfactionDistribution(satisfactionScores),
-
-        // 详细评分分析
-        dimensionAverages: this.calculateDimensionAverages(productReviews),
-
-        // 常见反馈
-        commonStrengths: this.extractCommonStrengths(productReviews),
-        commonIssues: this.extractCommonIssues(productReviews),
-
-        // 改进建议
-        improvementSuggestions: this.generateProductImprovementSuggestions(productReviews)
-      };
-    }
-
-    return productAnalysis;
-  }
-}
-
-interface MultiProductReviewLinks {
-  projectId: string;
-  collectionLink: string;
-  productLinks: Record<string, string>;
-  expiresAt: Date;
-  createdAt: Date;
-}
-
-interface ReviewProcessingResult {
-  success: boolean;
-  reviewId: string;
-  processingSteps: Array<{
-    step: string;
-    status: 'completed' | 'failed' | 'skipped';
-    error?: string;
-  }>;
-  error?: string;
-}
-
-interface MultiProductReviewAnalysis {
-  projectId: string;
-  totalReviews: number;
-  overallAnalysis: any;
-  productAnalysis: Record<string, ProductAnalysis>;
-  crossProductAnalysis: any;
-  trendAnalysis: any;
-  improvementSuggestions: string[];
-  benchmarkComparison: any;
-}
-
-interface ProductAnalysis {
-  productId: string;
-  productName: string;
-  productType: string;
-  totalReviews: number;
-  averageSatisfaction: number;
-  satisfactionDistribution: Record<string, number>;
-  dimensionAverages: Record<string, number>;
-  commonStrengths: string[];
-  commonIssues: string[];
-  improvementSuggestions: string[];
-}
-```
-
-## 5. 多产品投诉处理模块
-
-### 5.1 基于Product表的产品定位投诉系统
-
-#### 5.1.1 产品投诉分类
-```typescript
-class MultiProductComplaintManager {
-  // 创建产品相关投诉
-  async createProductComplaint(
-    complaintData: ProductComplaintData
-  ): Promise<ProductComplaint> {
-
-    const complaint: ProductComplaint = {
-      id: `complaint_${Date.now()}`,
-      projectId: complaintData.projectId,
-
-      // 投诉分类
-      category: complaintData.category,
-      subcategory: complaintData.subcategory,
-
-      // 产品信息
-      productId: complaintData.productId,
-      productName: complaintData.productName,
-      productType: complaintData.productType,
-      affectedProducts: complaintData.affectedProducts || [],
-
-      // 投诉内容
-      title: complaintData.title,
-      description: complaintData.description,
-      severity: complaintData.severity,
-
-      // 客户信息
-      customerInfo: complaintData.customerInfo,
-
-      // 处理信息
-      status: 'pending',
-      priority: this.calculateComplaintPriority(complaintData),
-      assignedTo: null,
-      assignedAt: null,
-
-      // 时间信息
-      createdAt: new Date(),
-      expectedResolutionTime: this.calculateExpectedResolutionTime(complaintData),
-
-      // 附件
-      attachments: complaintData.attachments || []
-    };
-
-    // 保存投诉
-    const savedComplaint = await this.saveProductComplaint(complaint);
-
-    // 自动分析并分配
-    await this.autoAnalyzeAndAssign(complaint);
-
-    // 发送通知
-    await this.sendComplaintNotifications(complaint);
-
-    return savedComplaint;
-  }
-
-  // 产品投诉智能分类
-  private classifyProductComplaint(description: string, productType: string): ComplaintClassification {
-    const classification: ComplaintClassification = {
-      category: 'other',
-      subcategory: 'general',
-      confidence: 0,
-      keywords: []
-    };
-
-    // 产品特定关键词库
-    const productSpecificKeywords = {
-      'living_room': {
-        'sofa': { category: 'furniture', subcategory: 'seating' },
-        'tv': { category: 'electronics', subcategory: 'entertainment' },
-        'lighting': { category: 'lighting', subcategory: 'ambient' },
-        'storage': { category: 'storage', subcategory: 'display' }
-      },
-      'bedroom': {
-        'bed': { category: 'furniture', subcategory: 'sleeping' },
-        'wardrobe': { category: 'storage', subcategory: 'clothing' },
-        'lighting': { category: 'lighting', subcategory: 'task' },
-        'noise': { category: 'environmental', subcategory: 'acoustic' }
-      },
-      'kitchen': {
-        'cabinet': { category: 'furniture', subcategory: 'storage' },
-        'countertop': { category: 'materials', subcategory: 'surface' },
-        'appliances': { category: 'equipment', subcategory: 'kitchen' },
-        'plumbing': { category: 'systems', subcategory: 'water' }
-      }
-    };
-
-    // 通用关键词
-    const generalKeywords = {
-      'color': { category: 'aesthetics', subcategory: 'color' },
-      'size': { category: 'layout', subcategory: 'dimensions' },
-      'quality': { category: 'quality', subcategory: 'materials' },
-      'function': { category: 'functionality', subcategory: 'usage' },
-      'delivery': { category: 'service', subcategory: 'timeline' }
-    };
-
-    // 分析描述中的关键词
-    const allKeywords = {
-      ...generalKeywords,
-      ...(productSpecificKeywords[productType] || {})
-    };
-
-    const foundKeywords: Array<{ keyword: string; classification: any; confidence: number }> = [];
-
-    for (const [keyword, classification] of Object.entries(allKeywords)) {
-      if (description.toLowerCase().includes(keyword.toLowerCase())) {
-        foundKeywords.push({
-          keyword,
-          classification,
-          confidence: 0.8
-        });
-      }
-    }
-
-    if (foundKeywords.length > 0) {
-      // 选择置信度最高的分类
-      const bestMatch = foundKeywords.reduce((best, current) =>
-        current.confidence > best.confidence ? current : best
-      );
-
-      classification.category = bestMatch.classification.category;
-      classification.subcategory = bestMatch.classification.subcategory;
-      classification.confidence = bestMatch.confidence;
-      classification.keywords = foundKeywords.map(f => f.keyword);
-    }
-
-    return classification;
-  }
-
-  // 跨产品投诉处理
-  async handleCrossProductComplaint(
-    complaintData: CrossProductComplaintData
-  ): Promise<CrossProductComplaint> {
-
-    const complaint: CrossProductComplaint = {
-      id: `cross_product_complaint_${Date.now()}`,
-      projectId: complaintData.projectId,
-
-      // 跨产品特有字段
-      primaryProductId: complaintData.primaryProductId,
-      affectedProducts: complaintData.affectedProducts,
-      relationshipType: complaintData.relationshipType, // 'style_inconsistency', 'functional_conflict', 'transition_issue'
-
-      // 投诉内容
-      title: complaintData.title,
-      description: complaintData.description,
-      category: 'cross_product',
-      severity: complaintData.severity,
-
-      // 处理信息
-      status: 'pending',
-      requiresMultiProductCoordination: true,
-      assignedTeam: this.assignCrossProductTeam(complaintData),
-
-      // 时间信息
-      createdAt: new Date(),
-      expectedResolutionTime: this.calculateCrossProductResolutionTime(complaintData)
-    };
-
-    // 分析产品间关系
-    complaint.productRelationshipAnalysis = await this.analyzeProductRelationship(
-      complaint.primaryProductId,
-      complaint.affectedProducts
-    );
-
-    // 保存并处理
-    const savedComplaint = await this.saveCrossProductComplaint(complaint);
-    await this.initiateCrossProductResolution(complaint);
-
-    return savedComplaint;
-  }
-
-  // 生成投诉处理报告
-  async generateProductComplaintReport(
-    projectId: string,
-    timeRange?: { start: Date; end: Date }
-  ): Promise<ProductComplaintReport> {
-
-    const complaints = await this.getProjectProductComplaints(projectId, timeRange);
-
-    const report: ProductComplaintReport = {
-      projectId,
-      reportPeriod: timeRange || { start: new Date(0), end: new Date() },
-
-      // 统计概览
-      overview: {
-        totalComplaints: complaints.length,
-        resolvedComplaints: complaints.filter(c => c.status === 'resolved').length,
-        pendingComplaints: complaints.filter(c => c.status === 'pending').length,
-        averageResolutionTime: this.calculateAverageResolutionTime(complaints),
-        complaintRate: this.calculateComplaintRate(complaints)
-      },
-
-      // 产品分布
-      productDistribution: this.analyzeComplaintProductDistribution(complaints),
-
-      // 分类统计
-      categoryBreakdown: this.analyzeComplaintCategories(complaints),
-
-      // 严重程度分析
-      severityAnalysis: this.analyzeComplaintSeverity(complaints),
-
-      // 处理效率
-      resolutionEfficiency: this.analyzeResolutionEfficiency(complaints),
-
-      // 改进建议
-      recommendations: this.generateComplaintResolutionRecommendations(complaints),
-
-      // 趋势分析
-      trends: this.analyzeComplaintTrends(complaints)
-    };
-
-    return report;
-  }
-}
-
-interface ProductComplaintData {
-  projectId: string;
-  productId: string;
-  productName: string;
-  productType: string;
-  affectedProducts?: string[];
-  category: string;
-  subcategory: string;
-  title: string;
-  description: string;
-  severity: 'low' | 'medium' | 'high' | 'critical';
-  customerInfo: any;
-  attachments?: any[];
-}
-
-interface CrossProductComplaintData {
-  projectId: string;
-  primaryProductId: string;
-  affectedProducts: string[];
-  relationshipType: 'style_inconsistency' | 'functional_conflict' | 'transition_issue';
-  title: string;
-  description: string;
-  severity: 'low' | 'medium' | 'high' | 'critical';
-}
-
-interface ProductComplaint {
-  id: string;
-  projectId: string;
-  category: string;
-  subcategory: string;
-  productId: string;
-  productName: string;
-  productType: string;
-  affectedProducts: string[];
-  title: string;
-  description: string;
-  severity: string;
-  customerInfo: any;
-  status: string;
-  priority: number;
-  assignedTo: string;
-  assignedAt: Date;
-  createdAt: Date;
-  expectedResolutionTime: Date;
-  attachments: any[];
-}
-
-interface CrossProductComplaint {
-  id: string;
-  projectId: string;
-  primaryProductId: string;
-  affectedProducts: string[];
-  relationshipType: string;
-  title: string;
-  description: string;
-  category: string;
-  severity: string;
-  status: string;
-  requiresMultiProductCoordination: boolean;
-  assignedTeam: string[];
-  productRelationshipAnalysis: any;
-  createdAt: Date;
-  expectedResolutionTime: Date;
-}
-
-interface ProductComplaintReport {
-  projectId: string;
-  reportPeriod: { start: Date; end: Date };
-  overview: any;
-  productDistribution: any;
-  categoryBreakdown: any;
-  severityAnalysis: any;
-  resolutionEfficiency: any;
-  recommendations: string[];
-  trends: any;
-}
-```
-
-## 6. 多产品项目复盘模块
-
-### 6.1 基于Product表的产品对比分析
-
-#### 6.1.1 产品绩效对比
-```typescript
-class MultiProductReviewManager {
-  // 生成多产品项目复盘报告
-  async generateMultiProductReviewReport(
-    projectId: string,
-    options?: ReviewReportOptions
-  ): Promise<MultiProductReviewReport> {
-
-    const report: MultiProductReviewReport = {
-      id: `review_report_${Date.now()}`,
-      projectId,
-      reportType: 'multi_product',
-      generatedAt: new Date(),
-
-      // 项目概览
-      projectOverview: await this.generateProjectOverview(projectId),
-
-      // 产品对比分析
-      productComparison: await this.generateProductComparison(projectId),
-
-      // 跨产品分析
-      crossProductAnalysis: await this.generateCrossProductAnalysis(projectId),
-
-      // 效率分析
-      efficiencyAnalysis: await this.generateEfficiencyAnalysis(projectId),
-
-      // 客户满意度分析
-      satisfactionAnalysis: await this.generateSatisfactionAnalysis(projectId),
-
-      // 改进建议
-      improvementRecommendations: await this.generateImprovementRecommendations(projectId),
-
-      // 经验总结
-      lessonsLearned: await this.extractLessonsLearned(projectId)
-    };
-
-    return report;
-  }
-
-  // 生成产品对比分析
-  private async generateProductComparison(projectId: string): Promise<ProductComparisonAnalysis> {
-    const products = await this.getProjectProducts(projectId);
-
-    const comparison: ProductComparisonAnalysis = {
-      products: products.map(product => ({
-        productId: product.id,
-        productName: product.productName,
-        productType: product.productType,
-        metrics: {} as ProductMetrics
-      })),
-
-      // 对比维度
-      comparisonMetrics: [
-        'deliveryTime',
-        'qualityScore',
-        'customerSatisfaction',
-        'budgetPerformance',
-        'revisionCount',
-        'teamEfficiency'
-      ],
-
-      // 产品排名
-      productRankings: {} as Record<string, Record<string, number>>,
-
-      // 最佳实践
-      bestPractices: {},
-
-      // 改进产品
-      improvementAreas: {}
-    };
-
-    // 计算各产品指标
-    for (const product of products) {
-      comparison.products.find(p => p.productId === product.id)!.metrics =
-        await this.calculateProductMetrics(product.id);
-    }
-
-    // 生成产品排名
-    for (const metric of comparison.comparisonMetrics) {
-      const ranked = comparison.products
-        .sort((a, b) => (b.metrics as any)[metric] - (a.metrics as any)[metric])
-        .map((product, index) => ({
-          productId: product.productId,
-          rank: index + 1,
-          value: (product.metrics as any)[metric]
-        }));
-
-      comparison.productRankings[metric] = ranked;
-    }
-
-    // 识别最佳实践
-    comparison.bestPractices = this.identifyBestPractices(comparison.products);
-
-    // 识别改进区域
-    comparison.improvementAreas = this.identifyImprovementAreas(comparison.products);
-
-    return comparison;
-  }
-
-  // 计算产品指标
-  private async calculateProductMetrics(productId: string): Promise<ProductMetrics> {
-    const metrics: ProductMetrics = {
-      // 时间指标
-      deliveryTime: await this.calculateProductDeliveryTime(productId),
-      onTimeDelivery: await this.calculateOnTimeDeliveryRate(productId),
-
-      // 质量指标
-      qualityScore: await this.calculateProductQualityScore(productId),
-      revisionCount: await this.countProductRevisions(productId),
-      reworkRate: await this.calculateProductReworkRate(productId),
-
-      // 客户满意度
-      customerSatisfaction: await this.calculateProductCustomerSatisfaction(productId),
-      customerComplaints: await this.countProductComplaints(productId),
-
-      // 财务指标
-      budgetPerformance: await this.calculateProductBudgetPerformance(productId),
-      profitability: await this.calculateProductProfitability(productId),
-
-      // 团队效率
-      teamEfficiency: await this.calculateProductTeamEfficiency(productId),
-      resourceUtilization: await this.calculateProductResourceUtilization(productId)
-    };
-
-    return metrics;
-  }
-
-  // 识别最佳实践
-  private identifyBestPractices(products: any[]): Record<string, BestPractice[]> {
-    const bestPractices: Record<string, BestPractice[]> = {};
-
-    // 找出各维度表现最好的产品
-    const topPerformers = {
-      deliveryTime: this.getTopPerformer(products, 'deliveryTime', 'asc'),      // 时间越短越好
-      qualityScore: this.getTopPerformer(products, 'qualityScore', 'desc'),    // 质量越高越好
-      customerSatisfaction: this.getTopPerformer(products, 'customerSatisfaction', 'desc'),
-      budgetPerformance: this.getTopPerformer(products, 'budgetPerformance', 'desc'),
-      teamEfficiency: this.getTopPerformer(products, 'teamEfficiency', 'desc')
-    };
-
-    // 提取最佳实践
-    for (const [metric, performer] of Object.entries(topPerformers)) {
-      const practices = await this.extractBestPractices(performer.productId, metric);
-      bestPractices[metric] = practices;
-    }
-
-    return bestPractices;
-  }
-
-  // 生成跨产品分析
-  private async generateCrossProductAnalysis(projectId: string): Promise<CrossProductAnalysis> {
-    const analysis: CrossProductAnalysis = {
-      // 风格一致性分析
-      styleConsistency: await this.analyzeStyleConsistency(projectId),
-
-      // 功能协调性分析
-      functionalCoordination: await this.analyzeFunctionalCoordination(projectId),
-
-      // 产品流线分析
-      circulationFlow: await this.analyzeCirculationFlow(projectId),
-
-      // 资源配置分析
-      resourceAllocation: await this.analyzeResourceAllocation(projectId),
-
-      // 时间协调分析
-      timeCoordination: await this.analyzeTimeCoordination(projectId)
-    };
-
-    return analysis;
-  }
-
-  // 风格一致性分析
-  private async analyzeStyleConsistency(projectId: string): Promise<StyleConsistencyAnalysis> {
-    const products = await this.getProjectProducts(projectId);
-
-    // 提取各产品的设计元素
-    const designElements = await Promise.all(
-      products.map(product => this.extractProductDesignElements(product.id))
-    );
-
-    // 分析一致性
-    const consistencyAnalysis: StyleConsistencyAnalysis = {
-      overallConsistencyScore: this.calculateOverallConsistency(designElements),
-
-      // 具体维度分析
-      colorConsistency: this.analyzeColorConsistency(designElements),
-      materialConsistency: this.analyzeMaterialConsistency(designElements),
-      styleConsistency: this.analyzeStyleConsistency(designElements),
-      scaleConsistency: this.analyzeScaleConsistency(designElements),
-
-      // 不一致点识别
-      inconsistencies: this.identifyStyleInconsistencies(designElements),
-
-      // 改进建议
-      recommendations: this.generateStyleConsistencyRecommendations(designElements)
-    };
-
-    return consistencyAnalysis;
-  }
-
-  // 生成效率分析
-  private async generateEfficiencyAnalysis(projectId: string): Promise<EfficiencyAnalysis> {
-    const analysis: EfficiencyAnalysis = {
-      // 时间效率
-      timeEfficiency: await this.analyzeTimeEfficiency(projectId),
-
-      // 资源效率
-      resourceEfficiency: await this.analyzeResourceEfficiency(projectId),
-
-      // 流程效率
-      processEfficiency: await this.analyzeProcessEfficiency(projectId),
-
-      // 协作效率
-      collaborationEfficiency: await this.analyzeCollaborationEfficiency(projectId),
-
-      // 效率瓶颈
-      bottlenecks: await this.identifyEfficiencyBottlenecks(projectId),
-
-      // 优化建议
-      optimizationSuggestions: await this.generateEfficiencyOptimizationSuggestions(projectId)
-    };
-
-    return analysis;
-  }
-}
-
-interface MultiProductReviewReport {
-  id: string;
-  projectId: string;
-  reportType: string;
-  generatedAt: Date;
-  projectOverview: any;
-  productComparison: ProductComparisonAnalysis;
-  crossProductAnalysis: CrossProductAnalysis;
-  efficiencyAnalysis: EfficiencyAnalysis;
-  satisfactionAnalysis: any;
-  improvementRecommendations: any[];
-  lessonsLearned: string[];
-}
-
-interface ProductComparisonAnalysis {
-  products: Array<{
-    productId: string;
-    productName: string;
-    productType: string;
-    metrics: ProductMetrics;
-  }>;
-  comparisonMetrics: string[];
-  productRankings: Record<string, Array<{
-    productId: string;
-    rank: number;
-    value: number;
-  }>>;
-  bestPractices: Record<string, BestPractice[]>;
-  improvementAreas: Record<string, ImprovementArea[]>;
-}
-
-interface ProductMetrics {
-  deliveryTime: number;
-  onTimeDelivery: number;
-  qualityScore: number;
-  revisionCount: number;
-  reworkRate: number;
-  customerSatisfaction: number;
-  customerComplaints: number;
-  budgetPerformance: number;
-  profitability: number;
-  teamEfficiency: number;
-  resourceUtilization: number;
-}
-
-interface BestPractice {
-  title: string;
-  description: string;
-  applicableTo: SpaceType[];
-  impactLevel: 'high' | 'medium' | 'low';
-  implementationComplexity: 'simple' | 'moderate' | 'complex';
-}
-
-interface CrossSpaceAnalysis {
-  styleConsistency: StyleConsistencyAnalysis;
-  functionalCoordination: any;
-  circulationFlow: any;
-  resourceAllocation: any;
-  timeCoordination: any;
-}
-
-interface StyleConsistencyAnalysis {
-  overallConsistencyScore: number;
-  colorConsistency: any;
-  materialConsistency: any;
-  styleConsistency: any;
-  scaleConsistency: any;
-  inconsistencies: any[];
-  recommendations: string[];
-}
-
-interface EfficiencyAnalysis {
-  timeEfficiency: any;
-  resourceEfficiency: any;
-  processEfficiency: any;
-  collaborationEfficiency: any;
-  bottlenecks: any[];
-  optimizationSuggestions: string[];
-}
-```
-
----
-
-**文档版本**:v3.0 (Product表统一空间管理)
-**更新日期**:2025-10-20
-**维护者**:YSS Development Team
-
-### 2.1 功能特点
-- 技术验收触发自动化结算
-- 小程序支付自动监听
-- 支付凭证智能识别
-- 渲染大图自动解锁
-- 客服一键发图
-
-### 2.2 自动化结算流程
-
-#### 2.2.1 启动自动化结算
-```typescript
-// project-detail.ts lines 3892-3938
-initiateAutoSettlement(): void {
-  console.log('🚀 启动自动化尾款结算流程');
-
-  // 1. 权限验证
-  if (!this.isTechnicalView()) {
-    alert('⚠️ 仅技术人员可以启动自动化结算流程');
-    return;
-  }
-
-  // 2. 验收状态检查
-  if (!this.isAllDeliveryCompleted()) {
-    alert('⚠️ 请先完成所有交付阶段验收');
-    return;
-  }
-
-  console.log('✅ 验收状态检查通过');
-
-  // 3. 激活小程序支付监听
-  this.miniprogramPaymentStatus = 'active';
-  console.log('📱 小程序支付监听已激活');
-
-  // 4. 创建尾款结算记录
-  this.createFinalPaymentRecord();
-
-  // 5. 通知客服跟进尾款
-  this.notifyCustomerServiceForFinalPayment();
-
-  // 6. 启动支付自动化
-  this.setupPaymentAutomation();
-
-  alert('✅ 自动化结算流程已启动!\n\n- 小程序支付监听已激活\n- 客服已收到尾款跟进通知\n- 支付到账后将自动解锁大图');
-}
-```
-
-**权限验证**:
-- 仅技术人员可以启动
-- 确保所有交付阶段已完成
-- 验证交付物质量合格
-
-#### 2.2.2 创建结算记录
-```typescript
-// project-detail.ts lines 3940-3962
-private createFinalPaymentRecord(): void {
-  const totalAmount = this.orderAmount || 150000;
-  const downPayment = totalAmount * 0.5; // 假设定金50%
-  const remainingAmount = totalAmount - downPayment;
-
-  this.settlementRecord = {
-    id: `settlement-${Date.now()}`,
-    projectId: this.projectId,
-    totalAmount: totalAmount,
-    downPayment: downPayment,
-    remainingAmount: remainingAmount,
-    paidAmount: 0,
-    status: 'pending',
-    createdAt: new Date(),
-    dueDate: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000), // 7天后到期
-    paymentMethod: undefined,
-    paidAt: undefined,
-    notes: '技术验收完成,等待客户支付尾款'
-  };
-
-  console.log('📝 尾款结算记录已创建:', this.settlementRecord);
-}
-```
-
-**结算记录结构**:
-```typescript
-interface SettlementRecord {
-  id: string;
-  projectId: string;
-  totalAmount: number;          // 订单总金额
-  downPayment: number;          // 定金金额
-  remainingAmount: number;      // 尾款金额
-  paidAmount: number;           // 已支付金额
-  status: 'pending' | 'partial' | 'completed' | 'overdue';
-  createdAt: Date;
-  dueDate: Date;                // 到期日期
-  paymentMethod?: 'wechat' | 'alipay' | 'bank';
-  paidAt?: Date;
-  voucherUrl?: string;          // 支付凭证URL
-  notes?: string;
-}
-```
-
-#### 2.2.3 通知客服跟进
-```typescript
-// project-detail.ts lines 3964-3978
-private notifyCustomerServiceForFinalPayment(): void {
-  const notification = {
-    type: 'final-payment-reminder',
-    projectId: this.projectId,
-    projectName: this.project?.name || '未命名项目',
-    amount: this.settlementRecord?.remainingAmount || 0,
-    dueDate: this.settlementRecord?.dueDate,
-    message: `项目"${this.project?.name}"已完成技术验收,请跟进客户支付尾款 ¥${this.settlementRecord?.remainingAmount.toLocaleString()}`
-  };
-
-  // 实际应用中调用通知服务
-  console.log('📧 已发送客服通知:', notification);
-
-  // 模拟通知发送
-  alert(`✉️ 已通知客服跟进尾款\n\n项目: ${notification.projectName}\n尾款金额: ¥${notification.amount.toLocaleString()}`);
-}
-```
-
-### 2.3 支付监听系统
-
-#### 2.3.1 小程序支付监听
-```typescript
-// project-detail.ts lines 3980-4012
-private setupPaymentAutomation(): void {
-  console.log('🔧 设置支付自动化监听');
-
-  // 监听小程序支付状态变化
-  // 实际应用中应使用WebSocket或轮询API
-  this.miniprogramPaymentStatus = 'active';
-
-  // 模拟支付监听(实际项目中应替换为真实的WebSocket连接)
-  this.simulatePaymentMonitoring();
-}
-
-private simulatePaymentMonitoring(): void {
-  console.log('🔄 开始模拟支付监听...');
-
-  // 实际项目中应该是:
-  // 1. 建立WebSocket连接到支付服务器
-  // 2. 监听支付成功事件
-  // 3. 接收支付信息(金额、方式、时间等)
-  // 4. 自动触发解锁流程
-
-  // 这里仅作演示,实际不会自动触发
-  console.log('💡 提示: 客户通过小程序支付后,系统将自动接收通知');
-  console.log('💡 提示: 支付凭证识别功能可手动上传截图触发');
-}
-```
-
-**监听流程**:
-```mermaid
-sequenceDiagram
-    participant Customer as 客户
-    participant MiniApp as 小程序
-    participant PaymentGateway as 支付网关
-    participant System as 系统
-    participant Designer as 设计师
-
-    Customer->>MiniApp: 发起尾款支付
-    MiniApp->>PaymentGateway: 调用支付接口
-    PaymentGateway-->>MiniApp: 支付成功回调
-    MiniApp->>System: 推送支付通知
-    System->>System: 更新结算状态
-    System->>System: 解锁渲染大图
-    System->>Designer: 通知客服发图
-```
-
-#### 2.3.2 支付到账处理
-```typescript
-// project-detail.ts lines 4014-4048
-onPaymentReceived(paymentInfo?: any): void {
-  console.log('💰 收到支付通知:', paymentInfo);
-
-  if (!this.settlementRecord) {
-    console.error('❌ 结算记录不存在');
-    return;
-  }
-
-  // 更新结算状态
-  this.settlementRecord.status = 'completed';
-  this.settlementRecord.paidAmount = paymentInfo?.amount || this.settlementRecord.remainingAmount;
-  this.settlementRecord.paymentMethod = paymentInfo?.method || 'wechat';
-  this.settlementRecord.paidAt = new Date();
-
-  console.log('✅ 结算状态已更新:', this.settlementRecord);
-
-  // 自动解锁渲染大图
-  this.autoUnlockAndSendImages();
-
-  // 发送支付确认通知
-  this.sendPaymentConfirmationNotifications();
-
-  // 停止支付监听
-  this.miniprogramPaymentStatus = 'completed';
-
-  console.log('🎉 尾款结算流程完成');
-}
-```
-
-#### 2.3.3 自动解锁大图
-```typescript
-// project-detail.ts lines 4050-4068
-private autoUnlockAndSendImages(): void {
-  console.log('🔓 开始自动解锁渲染大图');
-
-  // 解锁所有渲染大图
-  let unlockedCount = 0;
-  this.renderLargeImages.forEach(img => {
-    if (img.locked) {
-      img.locked = false;
-      unlockedCount++;
-    }
-  });
-
-  console.log(`✅ 已解锁${unlockedCount}张渲染大图`);
-
-  // 通知客服可以发送大图
-  alert(`✅ 尾款已到账,${unlockedCount}张渲染大图已解锁!\n\n客服可一键发送给客户。`);
-
-  // 触发界面更新
-  this.cdr.detectChanges();
-}
-```
-
-### 2.4 支付凭证识别
-
-#### 2.4.1 凭证上传
-```typescript
-// 上传支付凭证
-uploadPaymentVoucher(event: Event): void {
-  const input = event.target as HTMLInputElement;
-  if (!input.files || input.files.length === 0) return;
-
-  const file = input.files[0];
-
-  // 验证文件类型
-  if (!file.type.startsWith('image/')) {
-    alert('请上传图片格式的支付凭证');
-    return;
-  }
-
-  this.isUploadingVoucher = true;
-
-  // 上传文件到服务器
-  this.uploadFile(file).then(url => {
-    // 触发智能识别
-    this.recognizePaymentVoucher(url);
-  }).catch(error => {
-    console.error('支付凭证上传失败:', error);
-    alert('上传失败,请重试');
-    this.isUploadingVoucher = false;
-  });
-}
-```
-
-#### 2.4.2 智能识别
-```typescript
-// 调用支付凭证识别服务
-private recognizePaymentVoucher(imageUrl: string): void {
-  this.paymentVoucherService.recognize(imageUrl).subscribe({
-    next: (result) => {
-      console.log('识别结果:', result);
-
-      // 显示识别结果
-      this.voucherRecognitionResult = {
-        amount: result.amount,
-        paymentMethod: result.method,
-        transactionId: result.transactionId,
-        transactionTime: result.time,
-        confidence: result.confidence
-      };
-
-      // 如果识别置信度高,自动填充
-      if (result.confidence > 0.8) {
-        this.autoFillPaymentInfo(result);
-      }
-
-      this.isUploadingVoucher = false;
-    },
-    error: (error) => {
-      console.error('支付凭证识别失败:', error);
-      alert('识别失败,请手动填写支付信息');
-      this.isUploadingVoucher = false;
-    }
-  });
-}
-```
-
-**识别结果结构**:
-```typescript
-interface VoucherRecognitionResult {
-  amount: number;                           // 支付金额
-  paymentMethod: 'wechat' | 'alipay';      // 支付方式
-  transactionId: string;                    // 交易单号
-  transactionTime: Date;                    // 交易时间
-  confidence: number;                       // 识别置信度 0-1
-  merchantName?: string;                    // 商户名称
-  remarks?: string;                         // 备注信息
-}
-```
-
-### 2.5 一键发图功能
-
-```typescript
-// 客服一键发送渲染大图
-sendImagesToCustomer(): void {
-  const unlockedImages = this.renderLargeImages.filter(img => !img.locked);
-
-  if (unlockedImages.length === 0) {
-    alert('没有可发送的图片(渲染大图未解锁)');
-    return;
-  }
-
-  // 生成图片下载链接
-  const imageLinks = unlockedImages.map(img => ({
-    name: img.name,
-    url: img.url,
-    size: img.size
-  }));
-
-  // 调用发送服务
-  this.projectService.sendImagesToCustomer(
-    this.projectId,
-    imageLinks
-  ).subscribe({
-    next: (result) => {
-      if (result.success) {
-        alert(`✅ 已成功发送${unlockedImages.length}张图片给客户!`);
-
-        // 标记为已发送
-        unlockedImages.forEach(img => {
-          img.synced = true;
-        });
-      }
-    },
-    error: (error) => {
-      console.error('发送图片失败:', error);
-      alert('发送失败,请重试');
-    }
-  });
-}
-```
-
-## 3. 全景图合成模块
-
-### 3.1 功能特点
-- KR Panel集成
-- 智能空间标注
-- 自动生成分享链接
-- 漫游式预览体验
-
-### 3.2 全景图合成流程
-
-#### 3.2.1 启动合成
-```typescript
-// 开始全景图合成
-startPanoramicSynthesis(): void {
-  console.log('🖼️ 启动全景图合成');
-
-  // 打开文件选择对话框
-  const input = document.createElement('input');
-  input.type = 'file';
-  input.multiple = true;
-  input.accept = 'image/*';
-
-  input.onchange = (event: any) => {
-    const files = Array.from(event.target.files) as File[];
-    if (files.length === 0) return;
-
-    this.uploadAndSynthesizePanoramic(files);
-  };
-
-  input.click();
-}
-```
-
-#### 3.2.2 文件上传与合成
-```typescript
-// project-detail.ts lines 4217-4288
-private uploadAndSynthesizePanoramic(files: File[]): void {
-  console.log(`📤 开始上传${files.length}个文件...`);
-
-  this.isUploadingPanoramicFiles = true;
-  this.panoramicUploadProgress = 0;
-
-  // 模拟文件上传进度
-  const uploadInterval = setInterval(() => {
-    this.panoramicUploadProgress += 10;
-    if (this.panoramicUploadProgress >= 100) {
-      this.panoramicUploadProgress = 100;
-      clearInterval(uploadInterval);
-
-      // 上传完成,开始合成
-      this.synthesizePanoramicView(files);
-    }
-  }, 300);
-}
-
-private synthesizePanoramicView(files: File[]): void {
-  console.log('🔧 开始合成全景图...');
-
-  this.isUploadingPanoramicFiles = false;
-  this.isSynthesizingPanoramic = true;
-  this.panoramicSynthesisProgress = 0;
-
-  // 模拟合成进度
-  const synthesisInterval = setInterval(() => {
-    this.panoramicSynthesisProgress += 5;
-    if (this.panoramicSynthesisProgress >= 100) {
-      this.panoramicSynthesisProgress = 100;
-      clearInterval(synthesisInterval);
-
-      // 合成完成
-      this.completePanoramicSynthesis(files);
-    }
-  }, 500);
-}
-```
-
-**KR Panel集成**:
-- 支持多角度图片合成
-- 自动识别空间名称
-- 生成3D漫游场景
-- 支持VR模式预览
-
-#### 3.2.3 完成合成
-```typescript
-// project-detail.ts lines 4290-4328
-private completePanoramicSynthesis(files: File[]): void {
-  this.isSynthesizingPanoramic = false;
-
-  // 创建全景图合成记录
-  const synthesis: PanoramicSynthesis = {
-    id: `panoramic-${Date.now()}`,
-    name: `全景图_${new Date().toLocaleDateString()}`,
-    createdAt: new Date(),
-    spaces: files.map((file, index) => ({
-      id: `space-${index}`,
-      name: this.extractSpaceName(file.name),
-      imageUrl: URL.createObjectURL(file),
-      angle: index * 60 // 假设每60度一个角度
-    })),
-    previewUrl: 'https://example.com/panoramic/preview',
-    downloadUrl: 'https://example.com/panoramic/download',
-    shareLink: '',
-    fileSize: files.reduce((sum, f) => sum + f.size, 0),
-    status: 'completed'
-  };
-
-  // 添加到历史记录
-  this.panoramicSynthesisHistory.push(synthesis);
-
-  // 生成分享链接
-  this.generatePanoramicShareLink(synthesis);
+# 项目售后归档模块设计方案
 
-  console.log('✅ 全景图合成完成:', synthesis);
+## 概述
 
-  alert(`✅ 全景图合成完成!\n\n已生成${synthesis.spaces.length}个空间的全景图\n文件大小: ${this.formatFileSize(synthesis.fileSize)}`);
-}
-```
-
-**全景图数据结构**:
-```typescript
-interface PanoramicSynthesis {
-  id: string;
-  name: string;
-  createdAt: Date;
-  spaces: Array<{
-    id: string;
-    name: string;              // 空间名称:客厅-角度1
-    imageUrl: string;
-    angle: number;             // 拍摄角度
-  }>;
-  previewUrl: string;          // 预览链接
-  downloadUrl: string;         // 下载链接
-  shareLink: string;           // 分享链接
-  fileSize: number;
-  status: 'processing' | 'completed' | 'failed';
-}
-```
+基于ProjectPayment、ProjectFeedback、Product等表结构和现有的stage-aftercare组件,设计完整的项目售后归档模块,包含**验收尾款**、**客户评价**、**项目复盘**三大核心功能,通过数据分析实现项目执行效率和团队绩效的科学评估。
 
-### 3.3 自动生成分享链接
+## 数据表结构分析
 
-```typescript
-// project-detail.ts lines 4330-4360
-private generatePanoramicShareLink(synthesis: PanoramicSynthesis): void {
-  // 生成唯一分享链接
-  const linkId = btoa(`panoramic-${synthesis.id}-${Date.now()}`);
-  const shareLink = `https://vr.example.com/view/${linkId}`;
-
-  synthesis.shareLink = shareLink;
-
-  console.log('🔗 已生成分享链接:', shareLink);
-
-  // 自动复制到剪贴板
-  this.copyToClipboard(shareLink);
+### 1. ProjectPayment(项目付款表)
 
-  // 通知客服发送给客户
-  this.notifyCustomerServiceForPanoramicShare(synthesis);
+现有结构已支持尾款管理:
+- **type**: "final" - 尾款类型
+- **stage**: "aftercare" - 售后归档阶段
+- **status**: "pending" | "partial" | "completed" - 支付状态
+- **voucherFile**: 指向ProjectFile的付款凭证
+- **product**: 支持按Product分摊尾款
 
-  alert(`✅ 分享链接已生成并复制到剪贴板!\n\n${shareLink}\n\n客服已收到通知,可发送给客户。`);
-}
+### 2. ProjectFeedback(客户反馈表)
 
-private notifyCustomerServiceForPanoramicShare(synthesis: PanoramicSynthesis): void {
-  const notification = {
-    type: 'panoramic-ready',
-    projectId: this.projectId,
-    projectName: this.project?.name || '未命名项目',
-    shareLink: synthesis.shareLink,
-    spaceCount: synthesis.spaces.length,
-    message: `项目"${this.project?.name}"的全景图已合成完成,请发送给客户查看`
-  };
+现有结构支持多维度评价:
+- **project**: 关联项目
+- **product**: 关联具体空间产品
+- **rating**: 1-5分评分
+- **feedbackType**: "suggestion" | "complaint" | "praise"
+- **content**: 评价内容
+- **stage**: 评价阶段
 
-  console.log('📧 已通知客服发送全景图:', notification);
-}
-```
+### 3. Product(空间设计产品表)
 
-**分享链接特点**:
-- 唯一性标识
-- 有效期控制(可选)
-- 访问统计
-- VR模式支持
+现有结构支持复盘分析:
+- **profile**: 负责设计师
+- **stage**: 当前阶段状态
+- **status**: 产品状态
+- **estimatedDuration**: 预估工期
+- **order**: 排序顺序
+- **reviews**: 产品评价数组
 
-## 4. 客户评价模块
+## 三大功能模块设计
 
-### 4.1 功能特点
-- 多维度评分系统
-- 评价链接自动生成
-- 30天有效期
-- 数据统计分析
+### 1. 验收尾款模块
 
-### 4.2 评价链接生成
+#### 1.1 功能结构
 
-#### 4.2.1 生成评价令牌
 ```typescript
-// 生成客户评价链接
-generateReviewLink(): void {
-  console.log('📋 生成客户评价链接');
-
-  // 生成唯一评价令牌
-  const token = this.generateUniqueToken();
-
-  // 创建评价链接记录
-  const reviewLink: CustomerReviewLink = {
-    id: `review-link-${Date.now()}`,
-    projectId: this.projectId,
-    token: token,
-    link: `https://review.example.com/${token}`,
-    createdAt: new Date(),
-    expiresAt: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000), // 30天后过期
-    status: 'active',
-    submittedAt: undefined
+interface FinalPaymentModule {
+  // 尾款总览
+  paymentOverview: {
+    totalAmount: number;          // 尾款总额
+    paidAmount: number;           // 已支付金额
+    remainingAmount: number;       // 待支付金额
+    dueDate: Date;              // 应付款日期
+    overdueDays: number;          // 逾期天数
+    status: PaymentStatus;       // 支付状态
   };
 
-  this.customerReviewLink = reviewLink;
-
-  // 复制到剪贴板
-  this.copyToClipboard(reviewLink.link);
-
-  // 通知客服
-  this.notifyCustomerServiceForReview(reviewLink);
+  // 按产品分摊
+  productBreakdown: Array<{
+    productId: string;
+    productName: string;
+    productType: string;
+    amount: number;
+    percentage: number;
+    paidAmount: number;
+    vouchers: PaymentVoucher[];
+  }>;
 
-  console.log('✅ 评价链接已生成:', reviewLink);
+  // 支付凭证管理
+  paymentVouchers: Array<{
+    id: string;
+    amount: number;
+    paymentMethod: string;
+    paymentTime: Date;
+    voucherFile: Parse.Object;
+    verifiedStatus: 'pending' | 'verified' | 'rejected';
+    ocrResult?: OCRResult;
+    notes?: string;
+  }>;
+}
 
-  alert(`✅ 评价链接已生成并复制到剪贴板!\n\n${reviewLink.link}\n\n有效期: 30天\n客服已收到通知,可发送给客户。`);
+enum PaymentStatus {
+  PENDING = 'pending',       // 待支付
+  OVERDUE = 'overdue',       // 逾期
+  PARTIAL = 'partial',       // 部分支付
+  PAID = 'paid',           // 已支付
+  DISPUTED = 'disputed'     // 争议中
 }
 ```
 
-**评价链接结构**:
+#### 1.2 OCR智能识别
+
+**支付凭证OCR识别结构**:
 ```typescript
-interface CustomerReviewLink {
-  id: string;
-  projectId: string;
-  token: string;                // 唯一令牌
-  link: string;                 // 完整链接
-  createdAt: Date;
-  expiresAt: Date;              // 过期时间
-  status: 'active' | 'submitted' | 'expired';
-  submittedAt?: Date;
+interface OCRResult {
+  confidence: number;           // 识别置信度
+  amount: number;              // 识别金额
+  paymentMethod: string;       // 支付方式
+  transactionId?: string;     // 交易号
+  payerName?: string;         // 付款人姓名
+  paymentTime?: Date;         // 付款时间
+  merchantName?: string;      // 收款商户
+  rawText: string;           // 原始识别文本
+  warnings?: string[];        // 识别警告
 }
 ```
 
-#### 4.2.2 生成唯一令牌
-```typescript
-private generateUniqueToken(): string {
-  const timestamp = Date.now().toString(36);
-  const randomStr = Math.random().toString(36).substring(2, 15);
-  const projectIdHash = btoa(this.projectId).substring(0, 8);
+#### 1.3 业务流程
 
-  return `${timestamp}-${randomStr}-${projectIdHash}`;
-}
+```mermaid
+graph TD
+    A[进入售后归档] --> B[加载尾款信息]
+    B --> C{是否已有尾款记录?}
+    C -->|否| D[从报价自动生成尾款]
+    C -->|是| E[显示现有尾款状态]
+    D --> F[按产品分摊尾款]
+    E --> G[尾款管理界面]
+    F --> G
+    G --> H{支付状态}
+    H -->|待支付| I[上传支付凭证]
+    H -->|已支付| J[显示凭证列表]
+    I --> K[OCR自动识别]
+    K --> L[人工确认信息]
+    L --> M[更新支付状态]
+    M --> N[尾款结清]
+    J --> N
+    N --> O[进入评价阶段]
 ```
 
-### 4.3 评价数据结构
+### 2. 客户评价模块
+
+#### 2.1 多维度评价体系
 
 ```typescript
-interface CustomerReview {
-  id: string;
+interface CustomerEvaluation {
+  // 基础信息
+  evaluationId: string;
   projectId: string;
-  submittedAt: Date;
-
-  // 多维度评分 (1-5星)
-  ratings: {
-    overall: number;            // 整体满意度
-    timeliness: number;         // 及时性
-    quality: number;            // 设计质量
-    communication: number;      // 沟通效率
-    professionalism: number;    // 专业程度
-  };
+  customerId: string;
+  evaluationTime: Date;
 
-  // 文字评价
-  comments: {
-    strengths: string;          // 优点
-    improvements: string;       // 改进建议
-    additional: string;         // 其他意见
+  // 整体评价
+  overallRating: {
+    score: number;              // 综合评分 1-5
+    comments: string;          // 整体评价
+    wouldRecommend: boolean;    // 是否愿意推荐
+    improvementSuggestions: string[];
   };
 
-  // 推荐意愿
-  wouldRecommend: boolean;
+  // 分维度评价
+  dimensionRatings: Array<{
+    dimension: 'design_quality' | 'service_attitude' | 'delivery_timeliness' | 'value_for_money';
+    score: number;            // 维度评分
+    weight: number;            // 权重
+    comments?: string;        // 维度评价
+  }>;
+
+  // 产品级评价
+  productRatings: Array<{
+    productId: string;
+    productName: string;
+    spaceSatisfaction: number;  // 空间满意度
+    designRating: number;       // 设计评分
+    functionalityRating: number; // 功能性评分
+    issues: string[];          // 存在问题
+    improvements: string[];      // 改进建议
+    photos?: string[];         // 实际效果照片
+  }>;
 
-  // 附加信息
-  contact?: string;
-  permitPublish: boolean;       // 是否允许公开
+  // 评价验证
+  verification: {
+    isVerified: boolean;
+    verificationMethod: 'customer_confirmation' | 'project_completion' | 'payment_confirmation';
+    verificationTime: Date;
+    verifiedBy: string;
+  };
 }
 ```
 
-### 4.4 评价提交处理
-
-```typescript
-// 处理客户提交的评价
-onReviewSubmitted(reviewData: CustomerReview): void {
-  console.log('📝 收到客户评价:', reviewData);
-
-  // 保存评价数据
-  this.customerReviews.push(reviewData);
-
-  // 更新评价链接状态
-  if (this.customerReviewLink) {
-    this.customerReviewLink.status = 'submitted';
-    this.customerReviewLink.submittedAt = new Date();
-  }
-
-  // 计算平均分
-  this.calculateAverageRatings();
+#### 2.2 智能评价引导
 
-  // 通知相关人员
-  this.notifyReviewReceived(reviewData);
+**评价引导策略**:
+- **实时反馈**: 客户可在项目过程中随时记录反馈
+- **分阶段提醒**: 在关键节点(设计确认、交付完成)提醒评价
+- **个性化问题**: 基于项目类型生成针对性评价问题
+- **可视化对比**: 对比预期效果与实际效果的差异
 
-  console.log('✅ 客户评价已保存');
+#### 2.3 评价数据结构
 
-  alert('✅ 感谢客户的宝贵评价!\n\n评价数据已保存并通知相关人员。');
-}
-```
+```typescript
+// 扩展ProjectFeedback表结构
+interface EnhancedProjectFeedback extends ProjectFeedback {
+  // 产品关联
+  product?: Parse.Object;
 
-### 4.5 评价数据分析
+  // 多维度评分
+  dimensionScores?: {
+    designQuality: number;     // 设计质量
+    serviceAttitude: number;   // 服务态度
+    deliveryTimeliness: number; // 交付及时性
+    valueForMoney: number;    // 性价比
+  };
 
-```typescript
-// 计算平均评分
-private calculateAverageRatings(): void {
-  if (this.customerReviews.length === 0) {
-    this.averageRatings = {
-      overall: 0,
-      timeliness: 0,
-      quality: 0,
-      communication: 0,
-      professionalism: 0
-    };
-    return;
-  }
+  // 评价上下文
+  context?: {
+    evaluationStage: string;    // 评价阶段
+    touchpoints: string[];     // 接触点
+    emotions: string[];        // 情感标签
+    expectations: string[];    // 期望值
+  };
 
-  const sum = this.customerReviews.reduce((acc, review) => ({
-    overall: acc.overall + review.ratings.overall,
-    timeliness: acc.timeliness + review.ratings.timeliness,
-    quality: acc.quality + review.ratings.quality,
-    communication: acc.communication + review.ratings.communication,
-    professionalism: acc.professionalism + review.ratings.professionalism
-  }), {
-    overall: 0,
-    timeliness: 0,
-    quality: 0,
-    communication: 0,
-    professionalism: 0
-  });
-
-  const count = this.customerReviews.length;
-
-  this.averageRatings = {
-    overall: Math.round((sum.overall / count) * 10) / 10,
-    timeliness: Math.round((sum.timeliness / count) * 10) / 10,
-    quality: Math.round((sum.quality / count) * 10) / 10,
-    communication: Math.round((sum.communication / count) * 10) / 10,
-    professionalism: Math.round((sum.professionalism / count) * 10) / 10
+  // 改进建议分类
+  improvementCategories?: {
+    design: string[];          // 设计改进
+    service: string[];         // 服务改进
+    process: string[];        // 流程改进
+    communication: string[];    // 沟通改进
   };
 
-  console.log('📊 平均评分已更新:', this.averageRatings);
+  // 推荐意愿
+  recommendationWillingness?: {
+    score: number;            // 推荐评分 1-10
+    reasons: string[];         // 推荐原因
+    barriers?: string[];       // 推荐障碍
+    networkScope: string[];   // 愿意推荐的圈层
+  };
 }
 ```
 
-## 5. 投诉处理模块
-
-### 5.1 功能特点
-- 人工创建投诉
-- 关键词自动抓取
-- 智能标注问题类型
-- 处理进度跟踪
+### 3. 项目复盘模块
 
-### 5.2 人工创建投诉
+#### 3.1 复盘数据收集
 
-#### 5.2.1 创建投诉记录
+**多维度数据采集**:
 ```typescript
-// 人工创建投诉记录
-createComplaintManually(): void {
-  console.log('📝 人工创建投诉记录');
-
-  // 验证权限
-  if (!this.isTeamLeaderView() && !this.isCustomerServiceView()) {
-    alert('⚠️ 仅组长和客服可以创建投诉记录');
-    return;
-  }
-
-  // 打开投诉创建表单
-  this.showComplaintForm = true;
-  this.complaintFormData = {
-    source: 'manual',
-    stage: '',
-    reason: '',
-    description: '',
-    severity: 'medium',
-    tags: []
+interface ProjectRetrospectiveData {
+  // 项目基础信息
+  projectBasic: {
+    title: string;
+    type: string;
+    duration: number;           // 实际工期(天)
+    budget: number;            // 项目预算
+    teamSize: number;          // 团队规模
+    productCount: number;      // 空间数量
   };
-}
-```
 
-#### 5.2.2 提交投诉
-```typescript
-// 提交投诉记录
-submitComplaint(): void {
-  if (!this.complaintFormData.reason || !this.complaintFormData.description) {
-    alert('请填写投诉原因和详细描述');
-    return;
-  }
-
-  const complaint: ComplaintRecord = {
-    id: `complaint-${Date.now()}`,
-    projectId: this.projectId,
-    source: this.complaintFormData.source,
-    stage: this.complaintFormData.stage || '未指定',
-    reason: this.complaintFormData.reason,
-    description: this.complaintFormData.description,
-    severity: this.complaintFormData.severity,
-    tags: this.complaintFormData.tags,
-    status: '待处理',
-    createdAt: new Date(),
-    createdBy: this.getCurrentUserName(),
-    assignedTo: undefined,
-    resolvedAt: undefined,
-    resolution: undefined
+  // 时间节点分析
+  timelineAnalysis: {
+    nodes: Array<{
+      stage: string;           // 阶段名称
+      plannedStart: Date;      // 计划开始时间
+      actualStart: Date;       // 实际开始时间
+      plannedEnd: Date;        // 计划结束时间
+      actualEnd: Date;         // 实际结束时间
+      duration: number;        // 阶段耗时
+      delayDays: number;       // 延期天数
+      efficiency: number;       // 效率评分
+    }>;
+    bottlenecks: string[];     // 瓶颈环节
+    criticalPath: string[];    // 关键路径
   };
 
-  // 添加到投诉列表
-  this.complaints.push(complaint);
-
-  // 通知相关处理人员
-  this.notifyComplaintHandler(complaint);
-
-  // 关闭表单
-  this.showComplaintForm = false;
+  // 团队效能分析
+  teamPerformance: Array<{
+    memberId: string;
+    memberName: string;
+    role: string;             // 角色类型
+    workload: number;          // 工作负载
+    efficiency: number;        // 执行效率
+    quality: number;          // 工作质量
+    collaboration: number;     // 协作表现
+    timeDistribution: {
+      design: number;          // 设计时间占比
+      communication: number;    // 沟通时间占比
+      revision: number;        // 修改时间占比
+      admin: number;          // 行政时间占比
+    };
+    contributions: Array<{
+      type: 'design' | 'review' | 'coordination' | 'problem_solving';
+      description: string;
+      impact: 'high' | 'medium' | 'low';
+    }>;
+  }>;
 
-  console.log('✅ 投诉记录已创建:', complaint);
+  // 质量分析
+  qualityAnalysis: {
+    revisionRate: number;       // 修改率
+    firstPassYield: number;    // 一次通过率
+    customerSatisfaction: number; // 客户满意度
+    issueResolutionTime: number; // 问题解决时间
+    qualityEscalations: number; // 质量升级次数
+    productScores: Array<{
+      productId: string;
+      productName: string;
+      finalScore: number;
+      issues: string[];
+      highlights: string[];
+    }>;
+  };
 
-  alert('✅ 投诉记录已创建!\n\n相关人员已收到通知。');
+  // 财务分析
+  financialAnalysis: {
+    budgetVariance: number;    // 预算偏差
+    profitMargin: number;       // 利润率
+    costBreakdown: {
+      labor: number;           // 人力成本
+      materials: number;        // 材料成本
+      overhead: number;         // 管理费用
+      revisions: number;        // 修改成本
+    };
+    cashFlow: Array<{
+      period: string;
+      inflow: number;
+      outflow: number;
+      netFlow: number;
+    }>;
+  };
 }
 ```
 
-**投诉数据结构**:
+#### 3.2 AI智能复盘生成
+
+**复盘生成算法**:
 ```typescript
-interface ComplaintRecord {
-  id: string;
-  projectId: string;
-  source: 'manual' | 'keyword-detection';    // 来源
-  stage: string;                              // 投诉环节
-  reason: string;                             // 投诉原因
-  description: string;                        // 详细描述
-  severity: 'low' | 'medium' | 'high';       // 严重程度
-  tags: string[];                             // 问题标签
-  status: '待处理' | '处理中' | '已解决' | '已关闭';
-  createdAt: Date;
-  createdBy: string;
-  assignedTo?: string;                        // 分配给
-  resolvedAt?: Date;
-  resolution?: string;                        // 解决方案
-  attachments?: Array<{
-    id: string;
-    name: string;
-    url: string;
-  }>;
-}
-```
+class RetrospectiveGenerator {
+  /**
+   * 生成项目复盘报告
+   */
+  async generateRetrospective(
+    projectData: ProjectData,
+    changeLogs: ProjectChange[],
+    teamMetrics: TeamMetrics
+  ): Promise<RetrospectiveReport> {
+
+    // 1. 数据预处理
+    const processedData = await this.preprocessData(projectData, changeLogs);
+
+    // 2. 效率分析
+    const efficiencyAnalysis = this.analyzeEfficiency(processedData);
+
+    // 3. 质量分析
+    const qualityAnalysis = this.analyzeQuality(processedData);
+
+    // 4. 团队协作分析
+    const collaborationAnalysis = this.analyzeCollaboration(changeLogs, teamMetrics);
+
+    // 5. 客户满意度分析
+    const satisfactionAnalysis = this.analyzeCustomerSatisfaction(processedData);
+
+    // 6. 生成洞察和建议
+    const insights = await this.generateInsights({
+      efficiency: efficiencyAnalysis,
+      quality: qualityAnalysis,
+      collaboration: collaborationAnalysis,
+      satisfaction: satisfactionAnalysis
+    });
 
-### 5.3 关键词自动监控
+    return {
+      summary: this.generateSummary(insights),
+      highlights: insights.highlights,
+      challenges: insights.challenges,
+      lessons: insights.lessons,
+      recommendations: insights.recommendations,
+      teamMetrics: this.formatTeamMetrics(teamMetrics),
+      detailedAnalysis: {
+        efficiency: efficiencyAnalysis,
+        quality: qualityAnalysis,
+        collaboration: collaborationAnalysis,
+        timeline: this.analyzeTimeline(processedData)
+      }
+    };
+  }
 
-#### 5.3.1 设置关键词监测
-```typescript
-// 启动关键词监测
-setupKeywordMonitoring(): void {
-  console.log('🔍 设置关键词监测');
-
-  // 打开监控设置面板
-  this.showKeywordMonitoringSettings = true;
-
-  // 初始化默认关键词
-  if (this.monitoringKeywords.length === 0) {
-    this.monitoringKeywords = [
-      '不满意',
-      '投诉',
-      '退款',
-      '差评',
-      '质量问题',
-      '延期',
-      '态度差'
-    ];
+  /**
+   * 分析项目效率
+   */
+  private analyzeEfficiency(data: ProcessedData): EfficiencyAnalysis {
+    return {
+      overallEfficiency: this.calculateOverallEfficiency(data),
+      stageEfficiency: this.calculateStageEfficiency(data),
+      resourceUtilization: this.calculateResourceUtilization(data),
+      bottlenecks: this.identifyBottlenecks(data),
+      timeDistribution: this.analyzeTimeDistribution(data)
+    };
   }
 
-  console.log('📋 当前监控关键词:', this.monitoringKeywords);
+  /**
+   * 识别项目瓶颈
+   */
+  private identifyBottlenecks(data: ProcessedData): Array<{
+    stage: string;
+    issue: string;
+    impact: string;
+    suggestion: string;
+    severity: 'high' | 'medium' | 'low';
+  }> {
+    const bottlenecks = [];
+
+    // 分析时间瓶颈
+    const timeBottlenecks = this.analyzeTimeBottlenecks(data.timeline);
+    bottlenecks.push(...timeBottlenecks);
+
+    // 分析协作瓶颈
+    const collaborationBottlenecks = this.analyzeCollaborationBottlenecks(data.teamWork);
+    bottlenecks.push(...collaborationBottlenecks);
+
+    // 分析质量瓶颈
+    const qualityBottlenecks = this.analyzeQualityBottlenecks(data.quality);
+    bottlenecks.push(...qualityBottlenecks);
+
+    return bottlenecks.sort((a, b) => {
+      const severityOrder = { 'high': 3, 'medium': 2, 'low': 1 };
+      return severityOrder[b.severity] - severityOrder[a.severity];
+    });
+  }
 }
 ```
 
-#### 5.3.2 关键词检测
-```typescript
-// 检测消息中的关键词
-private detectKeywords(message: string): string[] {
-  const detectedKeywords: string[] = [];
-
-  this.monitoringKeywords.forEach(keyword => {
-    if (message.includes(keyword)) {
-      detectedKeywords.push(keyword);
-    }
-  });
-
-  return detectedKeywords;
-}
-```
+#### 3.3 团队成员效率分析
 
-#### 5.3.3 自动创建投诉
+**个人效率指标**:
 ```typescript
-// 检测到关键词后自动创建投诉
-onKeywordDetected(message: string, keyword: string): void {
-  console.log(`🚨 检测到关键词: ${keyword}`);
-
-  // 智能分析投诉严重程度
-  const severity = this.assessComplaintSeverity(keyword);
-
-  // 智能识别投诉环节
-  const stage = this.identifyComplaintStage(message);
-
-  // 智能标注问题类型
-  const tags = this.generateComplaintTags(message, keyword);
-
-  // 自动创建投诉记录
-  const complaint: ComplaintRecord = {
-    id: `complaint-auto-${Date.now()}`,
-    projectId: this.projectId,
-    source: 'keyword-detection',
-    stage: stage,
-    reason: `检测到关键词: ${keyword}`,
-    description: message,
-    severity: severity,
-    tags: tags,
-    status: '待处理',
-    createdAt: new Date(),
-    createdBy: '系统自动',
-    assignedTo: undefined,
-    resolvedAt: undefined,
-    resolution: undefined
+interface TeamMemberEfficiency {
+  memberId: string;
+  memberName: string;
+
+  // 时间效率
+  timeEfficiency: {
+    plannedVsActual: number;      // 计划vs实际时间比
+    taskCompletionRate: number;    // 任务完成率
+    onTimeDeliveryRate: number;   // 按时交付率
+    avgTaskDuration: number;       // 平均任务耗时
   };
 
-  this.complaints.push(complaint);
-
-  // 立即通知处理人员
-  this.notifyUrgentComplaint(complaint);
-
-  console.log('✅ 已自动创建投诉记录:', complaint);
-
-  alert(`🚨 检测到客户投诉关键词: ${keyword}\n\n已自动创建投诉记录并通知相关人员。`);
-}
-```
-
-**智能分析方法**:
-```typescript
-// 评估投诉严重程度
-private assessComplaintSeverity(keyword: string): 'low' | 'medium' | 'high' {
-  const highSeverityKeywords = ['退款', '投诉', '差评'];
-  const mediumSeverityKeywords = ['不满意', '质量问题', '延期'];
-
-  if (highSeverityKeywords.includes(keyword)) return 'high';
-  if (mediumSeverityKeywords.includes(keyword)) return 'medium';
-  return 'low';
-}
-
-// 识别投诉环节
-private identifyComplaintStage(message: string): string {
-  if (message.includes('需求') || message.includes('沟通')) return '需求沟通';
-  if (message.includes('方案') || message.includes('设计')) return '方案确认';
-  if (message.includes('建模') || message.includes('模型')) return '建模';
-  if (message.includes('软装') || message.includes('家具')) return '软装';
-  if (message.includes('渲染') || message.includes('效果图')) return '渲染';
-  if (message.includes('交付') || message.includes('延期')) return '交付';
-  return '未识别';
-}
-
-// 生成问题标签
-private generateComplaintTags(message: string, keyword: string): string[] {
-  const tags: string[] = [];
-
-  // 根据消息内容添加标签
-  if (message.includes('需求') || message.includes('理解')) tags.push('需求理解');
-  if (message.includes('质量') || message.includes('效果')) tags.push('设计质量');
-  if (message.includes('延期') || message.includes('时间')) tags.push('交付延期');
-  if (message.includes('态度') || message.includes('服务')) tags.push('服务态度');
-  if (message.includes('价格') || message.includes('费用')) tags.push('价格问题');
+  // 质量效率
+  qualityEfficiency: {
+    firstPassYield: number;       // 一次通过率
+    revisionRate: number;         // 修改率
+    errorRate: number;            // 错误率
+    customerRating: number;       // 客户评分
+  };
 
-  // 添加关键词作为标签
-  tags.push(keyword);
+  // 协作效率
+  collaborationEfficiency: {
+    communicationFrequency: number; // 沟通频次
+    responseTime: number;         // 响应时间
+    coordinationScore: number;    // 协调评分
+    knowledgeSharing: number;    // 知识分享
+  };
 
-  return [...new Set(tags)]; // 去重
+  // 综合效率评分
+  overallEfficiency: {
+    score: number;               // 综合评分 0-100
+    ranking: number;             // 团队排名
+    strengths: string[];         // 优势领域
+    improvements: string[];      // 改进建议
+  };
 }
 ```
 
-### 5.4 投诉处理流程
+#### 3.4 项目场景分析
 
+**典型项目场景识别**:
 ```typescript
-// 处理投诉
-handleComplaint(complaintId: string, resolution: string): void {
-  const complaint = this.complaints.find(c => c.id === complaintId);
-  if (!complaint) return;
-
-  complaint.status = '已解决';
-  complaint.resolvedAt = new Date();
-  complaint.resolution = resolution;
+interface ProjectScenarioAnalysis {
+  // 项目复杂度评估
+  complexityAssessment: {
+    scopeComplexity: number;      // 范围复杂度
+    technicalComplexity: number;  // 技术复杂度
+    coordinationComplexity: number; // 协调复杂度
+    clientComplexity: number;     // 客户复杂度
+    overallComplexity: 'simple' | 'moderate' | 'complex' | 'highly_complex';
+  };
 
-  // 通知客户和相关人员
-  this.notifyComplaintResolved(complaint);
+  // 风险识别
+  riskIdentification: {
+    identifiedRisks: Array<{
+      riskType: 'timeline' | 'budget' | 'quality' | 'resource' | 'scope';
+      probability: number;       // 发生概率 0-1
+      impact: number;           // 影响程度 0-1
+      riskLevel: 'low' | 'medium' | 'high' | 'critical';
+      mitigation: string;        // 缓解措施
+      owner: string;            // 负责人
+    }>;
+    riskMitigationEffectiveness: number; // 风险缓解有效性
+  };
 
-  console.log('✅ 投诉已处理:', complaint);
+  // 成功因素分析
+  successFactors: {
+    keySuccessFactors: string[];     // 关键成功因素
+    clientAlignment: number;          // 客户对齐度
+    teamCapability: number;          // 团队能力
+    processMaturity: number;         // 流程成熟度
+    technologyFit: number;          // 技术适配性
+  };
 
-  alert('✅ 投诉处理完成!\n\n已通知客户和相关人员。');
+  // 改进机会
+  improvementOpportunities: Array<{
+    area: string;                   // 改进领域
+    currentPerformance: number;      // 当前绩效
+    targetPerformance: number;      // 目标绩效
+    improvementPotential: number;    // 改进潜力
+    requiredActions: string[];       // 必要行动
+    estimatedEffort: string;        // 预估工作量
+    expectedBenefit: string;       // 预期收益
+  }>;
 }
 ```
 
-## 6. 项目复盘模块
+## 页面重新设计
 
-### 6.1 功能特点
-- 三大核心板块(SOP执行数据、经验复盘、优化建议)
-- 数据可视化展示
-- 自动生成复盘报告
-- 导出为PDF/Excel
-
-### 6.2 SOP执行数据
-
-#### 6.2.1 数据收集
-```typescript
-// 收集SOP执行数据
-collectSOPExecutionData(): any {
-  return {
-    requirementCommunications: this.countRequirementCommunications(),
-    revisionCount: this.countRevisions(),
-    deliveryCycleCompliance: this.checkDeliveryCycleCompliance(),
-    customerSatisfaction: this.getCustomerSatisfactionScore(),
-    stageDetails: this.getStageExecutionDetails()
-  };
-}
-```
+### 1. 整体架构设计
 
-#### 6.2.2 阶段执行详情
 ```typescript
-// 获取各阶段执行详情
-private getStageExecutionDetails(): Array<{
-  stage: string;
-  plannedDuration: number;
-  actualDuration: number;
-  status: 'on-time' | 'delayed' | 'ahead';
-  score: number;
-}> {
-  return [
-    {
-      stage: '需求沟通',
-      plannedDuration: 2,
-      actualDuration: 2,
-      status: 'on-time',
-      score: 95
-    },
-    {
-      stage: '方案确认',
-      plannedDuration: 3,
-      actualDuration: 4,
-      status: 'delayed',
-      score: 85
-    },
-    {
-      stage: '建模',
-      plannedDuration: 5,
-      actualDuration: 4,
-      status: 'ahead',
-      score: 92
-    },
-    {
-      stage: '软装',
-      plannedDuration: 3,
-      actualDuration: 3,
-      status: 'on-time',
-      score: 90
-    },
-    {
-      stage: '渲染',
-      plannedDuration: 4,
-      actualDuration: 5,
-      status: 'delayed',
-      score: 88
-    }
-  ];
-}
-```
+interface AftercarePageArchitecture {
+  // 视图管理
+  currentView: 'overview' | 'payment' | 'evaluation' | 'retrospective' | 'archive';
 
-### 6.3 经验复盘
+  // 数据状态
+  dataStatus: {
+    loading: boolean;
+    error?: string;
+    lastSyncTime?: Date;
+  };
 
-#### 6.3.1 自动提取信息
-```typescript
-// 提取经验复盘数据
-extractExperienceSummary(): any {
-  return {
-    customerNeeds: this.extractCustomerNeeds(),
-    customerConcerns: this.extractCustomerConcerns(),
-    complaintPoints: this.extractComplaintPoints(),
-    projectHighlights: this.extractProjectHighlights(),
-    keyConversations: this.extractKeyConversations()
+  // 权限控制
+  permissions: {
+    canEditPayment: boolean;
+    canViewEvaluation: boolean;
+    canSubmitEvaluation: boolean;
+    canGenerateRetrospective: boolean;
+    canArchive: boolean;
   };
-}
-```
 
-#### 6.3.2 提取客户需求
-```typescript
-private extractCustomerNeeds(): string[] {
-  // 从需求沟通记录中提取
-  return [
-    '客户希望整体风格偏现代简约',
-    '客户重视收纳空间的设计',
-    '客户要求使用环保材料',
-    '客户希望采光效果良好'
-  ];
+  // 导航配置
+  navigation: {
+    steps: Array<{
+      id: string;
+      title: string;
+      icon: string;
+      status: 'pending' | 'in_progress' | 'completed';
+      enabled: boolean;
+    }>;
+    currentStep: number;
+  };
 }
 ```
 
-### 6.4 优化建议
-
-#### 6.4.1 生成优化建议
-```typescript
-// 生成优化建议
-generateOptimizationSuggestions(): any[] {
-  const suggestions = [];
-
-  // 基于数据分析生成建议
-  const sopData = this.collectSOPExecutionData();
-
-  // 建议1:需求沟通优化
-  if (sopData.requirementCommunications > 5) {
-    suggestions.push({
-      priority: 'high',
-      priorityText: '高',
-      category: '需求沟通',
-      problem: '需求沟通次数过多(6次),影响项目效率',
-      dataSupport: `需求沟通次数: ${sopData.requirementCommunications}次,标准为3-4次`,
-      solution: '建议在首次沟通时使用标准化需求采集表,确保需求收集的完整性',
-      actionPlan: [
-        '制定标准需求采集表模板',
-        '培训设计师使用标准表单',
-        '要求首次沟通必须完成80%需求确认'
-      ],
-      expectedImprovement: '减少30%的需求沟通次数',
-      referenceCase: '参考项目#1234在使用标准表后沟通次数从6次降至3次',
-      accepted: false
-    });
-  }
-
-  // 建议2:渲染阶段优化
-  const renderingStage = sopData.stageDetails.find((s: any) => s.stage === '渲染');
-  if (renderingStage && renderingStage.status === 'delayed') {
-    suggestions.push({
-      priority: 'medium',
-      priorityText: '中',
-      category: '渲染效率',
-      problem: '渲染阶段超期1天,影响整体交付时间',
-      dataSupport: `计划4天,实际5天,超期率25%`,
-      solution: '建议提前进行渲染设备性能检查,并预留缓冲时间',
-      actionPlan: [
-        '每月检查渲染设备性能',
-        '建模完成后立即启动预渲染',
-        '渲染阶段预留20%缓冲时间'
-      ],
-      expectedImprovement: '降低渲染超期率至10%以下',
-      referenceCase: '团队B采用预渲染机制后超期率从30%降至8%',
-      accepted: false
-    });
-  }
-
-  return suggestions;
-}
+### 2. 用户界面设计
+
+#### 2.1 概览视图
+
+**概览仪表板**:
+- **进度卡片**: 显示三大模块完成状态
+- **关键指标**: 尾款状态、客户满意度、项目效率
+- **快速操作**: 跳转到各功能模块
+- **时间线**: 项目关键节点时间轴
+
+```html
+<!-- 概览视图模板 -->
+<div class="aftercare-overview">
+  <!-- 进度卡片 -->
+  <div class="progress-cards">
+    <div class="progress-card" [class.completed]="paymentCompleted">
+      <div class="card-icon">💰</div>
+      <h3>验收尾款</h3>
+      <div class="progress-bar">
+        <div class="progress-fill" [style.width.%]="paymentProgress"></div>
+      </div>
+      <p class="status">{{ paymentStatusText }}</p>
+    </div>
+
+    <div class="progress-card" [class.completed]="evaluationCompleted">
+      <div class="card-icon">⭐</div>
+      <h3>客户评价</h3>
+      <div class="progress-bar">
+        <div class="progress-fill" [style.width.%]="evaluationProgress"></div>
+      </div>
+      <p class="status">{{ evaluationStatusText }}</p>
+    </div>
+
+    <div class="progress-card" [class.completed]="retrospectiveCompleted">
+      <div class="card-icon">📊</div>
+      <h3>项目复盘</h3>
+      <div class="progress-bar">
+        <div class="progress-fill" [style.width.%]="retrospectiveProgress"></div>
+      </div>
+      <p class="status">{{ retrospectiveStatusText }}</p>
+    </div>
+  </div>
+
+  <!-- 关键指标 -->
+  <div class="key-metrics">
+    <div class="metric-card">
+      <h4>尾款状态</h4>
+      <div class="metric-value">{{ finalPaymentAmount }}</div>
+      <div class="metric-change" [class.positive]="paymentTrend > 0">
+        {{ paymentTrend > 0 ? '↑' : '↓' }} {{ Math.abs(paymentTrend) }}%
+      </div>
+    </div>
+
+    <div class="metric-card">
+      <h4>客户满意度</h4>
+      <div class="metric-value">{{ customerSatisfaction }}/5.0</div>
+      <div class="metric-stars">
+        @for (star of [1,2,3,4,5]; track star) {
+          <span class="star" [class.filled]="star <= customerSatisfaction">★</span>
+        }
+      </div>
+    </div>
+
+    <div class="metric-card">
+      <h4>项目效率</h4>
+      <div class="metric-value">{{ projectEfficiency }}%</div>
+      <div class="metric-label">vs 行业平均</div>
+    </div>
+  </div>
+  </div>
+
+  <!-- 快速操作 -->
+  <div class="quick-actions">
+    <button class="action-btn" (click)="navigateToPayment()" [disabled]="!canEditPayment">
+      <span class="btn-icon">💰</span>
+      管理尾款
+    </button>
+
+    <button class="action-btn" (click)="navigateToEvaluation()" [disabled]="!canViewEvaluation">
+      <span class="btn-icon">⭐</span>
+      查看评价
+    </button>
+
+    <button class="action-btn" (click)="generateRetrospective()" [disabled]="!canGenerateRetrospective">
+      <span class="btn-icon">📊</span>
+      生成复盘
+    </button>
+
+    <button class="action-btn primary" (click)="archiveProject()" [disabled]="!canArchive">
+      <span class="btn-icon">📁</span>
+      归档项目
+    </button>
+  </div>
+</div>
 ```
 
-**优化建议结构**:
-```typescript
-interface OptimizationSuggestion {
-  priority: 'high' | 'medium' | 'low';
-  priorityText: string;
-  category: string;                     // 类别
-  problem: string;                      // 问题描述
-  dataSupport: string;                  // 数据支撑
-  solution: string;                     // 解决方案
-  actionPlan: string[];                 // 行动计划
-  expectedImprovement: string;          // 预期提升
-  referenceCase?: string;               // 参考案例
-  accepted: boolean;                    // 是否已采纳
-  acceptedAt?: Date;
-}
-```
+#### 2.2 尾款管理视图
 
-### 6.5 复盘报告生成
+**智能尾款管理**:
+- **分摊显示**: 按Product分摊显示尾款明细
+- **OCR识别**: 自动识别支付凭证信息
+- **状态追踪**: 实时显示支付进度
+- **提醒功能**: 逾期提醒和付款通知
 
-#### 6.5.1 生成报告
 ```typescript
-// 生成完整复盘报告
-generateReviewReport(): void {
-  console.log('📊 生成项目复盘报告');
-
-  this.isGeneratingReview = true;
-
-  // 模拟生成进度
-  let progress = 0;
-  const interval = setInterval(() => {
-    progress += 20;
-    if (progress >= 100) {
-      clearInterval(interval);
-      this.completeReviewReportGeneration();
-    }
-  }, 500);
-}
+interface PaymentManagementComponent {
+  // 尾款数据
+  finalPayment: FinalPaymentModule;
+
+  // 产品分摊
+  productAllocation: Array<{
+    product: Parse.Object;
+    allocation: PaymentAllocation;
+    status: 'pending' | 'partial' | 'completed';
+  }>;
 
-private completeReviewReportGeneration(): void {
-  // 收集所有数据
-  const reportData = {
-    projectInfo: {
-      name: this.project?.name || '未命名项目',
-      id: this.projectId,
-      startDate: this.project?.createdAt,
-      endDate: new Date()
-    },
-    sopData: this.collectSOPExecutionData(),
-    experience: this.extractExperienceSummary(),
-    suggestions: this.generateOptimizationSuggestions(),
-    statistics: {
-      overallScore: this.calculateOverallScore(),
-      strengths: this.getProjectStrengths(),
-      weaknesses: this.getProjectWeaknesses()
-    }
+  // OCR处理
+  ocrProcessing: {
+    isProcessing: boolean;
+    progress: number;
+    result?: OCRResult;
   };
 
-  // 保存报告
-  this.reviewReport = reportData;
-  this.isGeneratingReview = false;
-
-  console.log('✅ 复盘报告生成完成:', reportData);
-
-  alert('✅ 项目复盘报告已生成!\n\n您可以查看详情或导出报告。');
+  // 上传管理
+  uploadManagement: {
+    multipleUpload: boolean;
+    dragDropEnabled: boolean;
+    supportedFormats: string[];
+    maxFileSize: number;
+  };
 }
 ```
 
-#### 6.5.2 导出报告
-```typescript
-// 导出复盘报告
-exportReviewReport(format: 'pdf' | 'excel'): void {
-  if (!this.reviewReport) {
-    alert('请先生成复盘报告');
-    return;
-  }
-
-  console.log(`📤 导出复盘报告 (${format})`);
+#### 2.3 客户评价视图
+
+**交互式评价界面**:
+- **引导式评价**: 分步骤引导客户完成评价
+- **可视化反馈**: 支持图片、语音等多媒体评价
+- **实时预览**: 评价内容实时预览和确认
+- **奖励机制**: 评价完成后的客户激励
+
+```html
+<!-- 客户评价模板 -->
+<div class="customer-evaluation">
+  <!-- 评价引导 -->
+  <div class="evaluation-wizard">
+    <div class="wizard-steps">
+      <div class="step" [class.active]="currentStep === 1" [class.completed]="stepCompleted(1)">
+        <span class="step-number">1</span>
+        <span class="step-label">整体评价</span>
+      </div>
+      <div class="step" [class.active]="currentStep === 2" [class.completed]="stepCompleted(2)">
+        <span class="step-number">2</span>
+        <span class="step-label">分项评分</span>
+      </div>
+      <div class="step" [class.active]="currentStep === 3" [class.completed]="stepCompleted(3)">
+        <span class="step-number">3</span>
+        <span class="step-label">详细反馈</span>
+      </div>
+      <div class="step" [class.active]="currentStep === 4" [class.completed]="stepCompleted(4)">
+        <span class="step-number">4</span>
+        <span class="step-label">确认提交</span>
+      </div>
+    </div>
+  </div>
+
+  <!-- 评价内容 -->
+  <div class="evaluation-content">
+    <!-- 整体评价 -->
+    @if (currentStep === 1) {
+      <div class="overall-evaluation">
+        <h3>您对整体服务的评价如何?</h3>
+        <div class="rating-scale">
+          @for (rating of [1,2,3,4,5]; track rating) {
+            <button class="rating-btn" (click)="setOverallRating(rating)">
+              <span class="rating-number">{{ rating }}</span>
+              <span class="rating-label">{{ getRatingLabel(rating) }}</span>
+            </button>
+          }
+        </div>
+        <textarea
+          class="evaluation-textarea"
+          placeholder="请分享您的整体体验..."
+          [(ngModel)]="evaluation.overallComments">
+        </textarea>
+      </div>
+    }
 
-  if (format === 'excel') {
-    this.exportAsExcel(this.reviewReport);
-  } else {
-    this.exportAsPDF(this.reviewReport);
-  }
-}
+    <!-- 分项评分 -->
+    @if (currentStep === 2) {
+      <div class="dimension-evaluation">
+        @for (dimension of evaluationDimensions; track dimension) {
+          <div class="dimension-item">
+            <h4>{{ dimension.label }}</h4>
+            <p class="dimension-desc">{{ dimension.description }}</p>
+            <div class="star-rating">
+              @for (star of [1,2,3,4,5]; track star) {
+                <span
+                  class="star"
+                  [class.filled]="star <= dimension.rating"
+                  (click)="setDimensionRating(dimension.key, star)">
+                  ★
+                </span>
+              }
+            </div>
+          </div>
+        }
+      </div>
+    }
 
-private exportAsExcel(data: any): void {
-  // 转换为CSV格式
-  let csvContent = '\uFEFF'; // UTF-8 BOM
-
-  // 项目概况
-  csvContent += '=== 项目概况 ===\n';
-  csvContent += `项目名称,${data.projectInfo.name}\n`;
-  csvContent += `项目ID,${data.projectInfo.id}\n`;
-  csvContent += `总耗时,${this.calculateProjectDuration()}天\n\n`;
-
-  // SOP执行数据
-  csvContent += '=== SOP执行数据 ===\n';
-  csvContent += '阶段,计划时长,实际时长,状态,评分\n';
-  data.sopData.stageDetails.forEach((stage: any) => {
-    csvContent += `${stage.stage},${stage.plannedDuration},${stage.actualDuration},${stage.status},${stage.score}\n`;
-  });
-
-  // 优化建议
-  csvContent += '\n=== 优化建议 ===\n';
-  csvContent += '优先级,类别,问题,建议,预期提升\n';
-  data.suggestions.forEach((s: any) => {
-    csvContent += `${s.priorityText},${s.category},"${s.problem}","${s.solution}",${s.expectedImprovement}\n`;
-  });
-
-  // 创建下载
-  const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
-  const link = document.createElement('a');
-  const url = URL.createObjectURL(blob);
-
-  link.href = url;
-  link.download = `项目复盘报告_${data.projectInfo.name}_${this.formatDate(new Date())}.csv`;
-  link.click();
-
-  URL.revokeObjectURL(url);
-
-  console.log('✅ 报告已导出为Excel');
-  alert('✅ 报告已导出!\n\n文件已下载到您的下载文件夹。');
-}
+    <!-- 详细反馈 -->
+    @if (currentStep === 3) {
+      <div class="detailed-feedback">
+        <div class="feedback-section">
+          <h4>最喜欢的方面</h4>
+          <div class="feedback-tags">
+            @for (tag of positiveTags; track tag) {
+              <span class="feedback-tag" (click)="toggleTag(tag, 'positive')">
+                {{ tag }}
+              </span>
+            }
+          </div>
+        </div>
+
+        <div class="feedback-section">
+          <h4>希望改进的方面</h4>
+          <div class="feedback-tags">
+            @for (tag of improvementTags; track tag) {
+              <span class="feedback-tag" (click)="toggleTag(tag, 'improvement')">
+                {{ tag }}
+              </span>
+            }
+          </div>
+        </div>
+
+        <div class="feedback-section">
+          <h4>照片反馈</h4>
+          <div class="photo-upload">
+            <div class="upload-area" (drop)="onPhotoDrop($event)" (dragover)="onDragOver($event)">
+              <span class="upload-icon">📷</span>
+              <p>上传实际效果照片</p>
+              <input type="file" accept="image/*" multiple (change)="onPhotoSelect($event)">
+            </div>
+            <div class="uploaded-photos">
+              @for (photo of uploadedPhotos; track photo) {
+                <div class="photo-item">
+                  <img [src]="photo.url" [alt]="photo.description">
+                  <button class="remove-btn" (click)="removePhoto(photo.id)">×</button>
+                </div>
+              }
+            </div>
+          </div>
+        </div>
+      </div>
+    }
+  </div>
+</div>
 ```
 
-## 7. 权限控制
-
-### 7.1 角色权限矩阵
+#### 2.4 项目复盘视图
 
-| 操作 | 客服 | 设计师 | 组长 | 技术 | 财务 |
-|-----|------|--------|------|------|------|
-| 查看售后板块 | ✅ | ✅ | ✅ | ✅ | ✅ |
-| 启动自动结算 | ❌ | ❌ | ❌ | ✅ | ❌ |
-| 上传支付凭证 | ✅ | ❌ | ✅ | ❌ | ✅ |
-| 发送图片给客户 | ✅ | ❌ | ✅ | ❌ | ❌ |
-| 合成全景图 | ❌ | ❌ | ❌ | ✅ | ❌ |
-| 生成评价链接 | ✅ | ❌ | ✅ | ❌ | ❌ |
-| 创建投诉记录 | ✅ | ❌ | ✅ | ❌ | ❌ |
-| 处理投诉 | ✅ | ❌ | ✅ | ❌ | ❌ |
-| 生成复盘报告 | ❌ | ❌ | ✅ | ✅ | ❌ |
-| 导出复盘报告 | ❌ | ❌ | ✅ | ✅ | ✅ |
-
-### 7.2 权限检查实现
+**数据驱动复盘**:
+- **可视化图表**: 时间线、效率分析、质量统计
+- **团队绩效**: 个人和团队的多维度分析
+- **智能洞察**: AI生成的关键发现和建议
+- **对比分析**: 与历史项目和行业基准对比
 
 ```typescript
-// 检查尾款结算权限
-canInitiateSettlement(): boolean {
-  return this.isTechnicalView();
-}
+interface RetrospectiveVisualization {
+  // 时间线可视化
+  timelineChart: {
+    type: 'gantt' | 'timeline';
+    data: Array<{
+      phase: string;
+      planned: DateRange;
+      actual: DateRange;
+      participants: string[];
+      efficiency: number;
+    }>;
+  };
 
-// 检查全景图合成权限
-canSynthesizePanoramic(): boolean {
-  return this.isTechnicalView();
-}
+  // 效率分析图表
+  efficiencyCharts: {
+    radarChart: {
+      dimensions: string[];
+      teamData: number[][];
+      benchmarkData: number[];
+    };
+    barChart: {
+      categories: string[];
+      planned: number[];
+      actual: number[];
+    };
+  };
 
-// 检查投诉处理权限
-canHandleComplaints(): boolean {
-  return this.isTeamLeaderView() || this.isCustomerServiceView();
-}
+  // 团队绩效矩阵
+  teamMatrix: {
+    members: string[];
+    metrics: string[];
+    data: number[][];
+    heatmap: boolean;
+  };
 
-// 检查复盘报告权限
-canGenerateReviewReport(): boolean {
-  return this.isTeamLeaderView() || this.isTechnicalView();
+  // 趋势分析
+  trendAnalysis: {
+    timeSeries: Array<{
+      date: Date;
+      efficiency: number;
+      quality: number;
+      satisfaction: number;
+    }>;
+    projections: Array<{
+      futureDate: Date;
+      predictedEfficiency: number;
+      confidence: number;
+    }>;
+  };
 }
 ```
 
-## 8. 数据流转
+### 3. 交互体验优化
 
-### 8.1 售后流程总览
-
-```mermaid
-sequenceDiagram
-    participant Tech as 技术
-    participant System as 系统
-    participant Payment as 支付网关
-    participant CS as 客服
-    participant Customer as 客户
-
-    Tech->>System: 启动自动结算
-    System->>Payment: 激活支付监听
-    System->>CS: 通知跟进尾款
-    CS->>Customer: 发送支付请求
-    Customer->>Payment: 完成支付
-    Payment->>System: 支付通知
-    System->>System: 解锁渲染大图
-    System->>CS: 通知发送大图
-    CS->>Customer: 发送渲染大图
-    System->>CS: 生成评价链接
-    CS->>Customer: 发送评价链接
-    Customer->>System: 提交评价
-    System->>Tech: 生成复盘报告
-```
+#### 3.1 响应式设计
 
-### 8.2 数据同步机制
+**多设备适配**:
+- **桌面端**: 三栏布局,信息密度高
+- **平板端**: 两栏布局,适中的信息密度
+- **手机端**: 单栏布局,卡片式展示
 
-```typescript
-// 售后数据同步到项目
-private syncAfterCareDataToProject(): void {
-  if (!this.project) return;
-
-  this.project.afterCare = {
-    settlement: this.settlementRecord,
-    panoramic: this.panoramicSynthesisHistory,
-    reviews: this.customerReviews,
-    complaints: this.complaints,
-    reviewReport: this.reviewReport
-  };
+#### 3.2 实时协作
 
-  // 同步到服务器
-  this.projectService.updateProject(this.project).subscribe({
-    next: (result) => {
-      console.log('✅ 售后数据已同步到项目');
-    },
-    error: (error) => {
-      console.error('❌ 售后数据同步失败:', error);
-    }
-  });
-}
-```
+**多用户协同**:
+- **实时状态**: 显示其他用户当前操作
+- **冲突解决**: 多人编辑时的冲突处理
+- **消息通知**: 重要操作的实时通知
+- **版本控制**: 数据变更的版本管理
 
-## 9. 异常处理
+#### 3.3 智能化辅助
 
-### 9.1 支付监听失败
+**AI辅助功能**:
+- **智能提示**: 基于历史数据的操作建议
+- **自动填充**: 常用信息的自动填充
+- **异常检测**: 数据异常的自动识别和提醒
+- **预测分析**: 基于当前数据的结果预测
 
-```typescript
-// 支付监听连接失败处理
-private handlePaymentMonitoringError(error: any): void {
-  console.error('支付监听连接失败:', error);
+## 数据分析具体方法
 
-  // 降级为手动模式
-  this.miniprogramPaymentStatus = 'error';
+### 1. 项目效率分析算法
 
-  alert(`⚠️ 支付自动监听失败\n\n请使用"上传支付凭证"功能手动确认支付。`);
+#### 1.1 时间效率计算
 
-  // 显示手动上传入口
-  this.showManualPaymentVoucherUpload = true;
-}
-```
+```typescript
+class ProjectEfficiencyAnalyzer {
+  /**
+   * 计算整体项目效率
+   */
+  calculateOverallEfficiency(projectData: ProjectData): EfficiencyScore {
+    const { plannedDuration, actualDuration, milestones, teamWorkload } = projectData;
+
+    // 时间效率 = 计划时间 / 实际时间
+    const timeEfficiency = Math.min(1.0, plannedDuration / actualDuration) * 100;
+
+    // 里程碑完成率
+    const milestoneCompletionRate = this.calculateMilestoneCompletionRate(milestones);
+
+    // 资源利用效率
+    const resourceUtilization = this.calculateResourceUtilization(teamWorkload);
+
+    // 质量效率(基于修改率)
+    const qualityEfficiency = this.calculateQualityEfficiency(projectData.quality);
+
+    // 综合效率评分(加权平均)
+    const weights = {
+      time: 0.3,
+      milestones: 0.25,
+      resources: 0.25,
+      quality: 0.2
+    };
 
-### 9.2 全景图合成失败
+    const overallEfficiency =
+      timeEfficiency * weights.time +
+      milestoneCompletionRate * weights.milestones +
+      resourceUtilization * weights.resources +
+      qualityEfficiency * weights.quality;
 
-```typescript
-// 全景图合成失败处理
-private handlePanoramicSynthesisError(error: any): void {
-  console.error('全景图合成失败:', error);
+    return {
+      overallScore: Math.round(overallEfficiency),
+      timeEfficiency: Math.round(timeEfficiency),
+      milestoneCompletionRate: Math.round(milestoneCompletionRate),
+      resourceUtilization: Math.round(resourceUtilization),
+      qualityEfficiency: Math.round(qualityEfficiency),
+      grade: this.getEfficiencyGrade(overallEfficiency)
+    };
+  }
 
-  this.isSynthesizingPanoramic = false;
+  /**
+   * 识别效率瓶颈
+   */
+  identifyEfficiencyBottlenecks(projectData: ProjectData): Array<{
+    stage: string;
+    issue: string;
+    impact: number;
+    suggestion: string;
+    priority: 'high' | 'medium' | 'low';
+  }> {
+    const bottlenecks = [];
+
+    // 分析各阶段效率
+    for (const stage of projectData.stages) {
+      const stageEfficiency = this.calculateStageEfficiency(stage);
+
+      if (stageEfficiency < 0.7) { // 效率低于70%
+        bottlenecks.push({
+          stage: stage.name,
+          issue: `${stage.name}阶段效率偏低`,
+          impact: (0.7 - stageEfficiency) * 100,
+          suggestion: this.generateEfficiencySuggestion(stage),
+          priority: stageEfficiency < 0.5 ? 'high' : 'medium'
+        });
+      }
+    }
 
-  let errorMessage = '全景图合成失败';
+    // 分析团队协作问题
+    const collaborationIssues = this.analyzeCollaborationIssues(projectData);
+    bottlenecks.push(...collaborationIssues);
 
-  if (error.code === 'INSUFFICIENT_IMAGES') {
-    errorMessage = '图片数量不足,至少需要6张图片';
-  } else if (error.code === 'INVALID_FORMAT') {
-    errorMessage = '图片格式不支持,请使用JPG或PNG格式';
+    return bottlenecks.sort((a, b) => b.impact - a.impact);
+  }
   }
-
-  alert(`❌ ${errorMessage}\n\n请检查后重试。`);
 }
 ```
 
-### 9.3 评价链接过期
+### 2. 团队绩效分析模型
 
-```typescript
-// 检查评价链接是否过期
-checkReviewLinkExpiry(linkId: string): boolean {
-  const link = this.customerReviewLinks.find(l => l.id === linkId);
-
-  if (!link) return true;
+#### 2.1 个人绩效评估
 
-  if (link.status === 'expired') return true;
+```typescript
+class TeamPerformanceAnalyzer {
+  /**
+   * 评估团队成员绩效
+   */
+  evaluateMemberPerformance(
+    memberId: string,
+    projectData: ProjectData,
+    changeLogs: ProjectChange[]
+  ): TeamMemberPerformance {
+
+    // 获取成员相关的数据
+    const memberData = this.extractMemberData(memberId, projectData, changeLogs);
+
+    // 工作量评估
+    const workloadScore = this.evaluateWorkload(memberData);
+
+    // 效率评估
+    const efficiencyScore = this.evaluateEfficiency(memberData);
+
+    // 质量评估
+    const qualityScore = this.evaluateQuality(memberData);
+
+    // 协作评估
+    const collaborationScore = this.evaluateCollaboration(memberData, changeLogs);
+
+    // 创新评估
+    const innovationScore = this.evaluateInnovation(memberData);
+
+    // 综合绩效评分
+    const overallScore = this.calculateOverallScore({
+      workload: workloadScore,
+      efficiency: efficiencyScore,
+      quality: qualityScore,
+      collaboration: collaborationScore,
+      innovation: innovationScore
+    });
 
-  // 检查是否超过有效期
-  if (new Date() > link.expiresAt) {
-    link.status = 'expired';
-    return true;
+    return {
+      memberId,
+      overallScore,
+      workloadScore,
+      efficiencyScore,
+      qualityScore,
+      collaborationScore,
+      innovationScore,
+      strengths: this.identifyStrengths({
+        workload: workloadScore,
+        efficiency: efficiencyScore,
+        quality: qualityScore,
+        collaboration: collaborationScore,
+        innovation: innovationScore
+      }),
+      improvements: this.identifyImprovements({
+        workload: workloadScore,
+        efficiency: efficiencyScore,
+        quality: qualityScore,
+        collaboration: collaborationScore,
+        innovation: innovationScore
+      }),
+      recommendations: this.generateRecommendations(overallScore),
+      ranking: this.calculateRanking(memberId, overallScore, projectData)
+    };
   }
 
-  return false;
-}
-
-// 重新生成过期的评价链接
-regenerateReviewLink(oldLinkId: string): void {
-  const oldLink = this.customerReviewLinks.find(l => l.id === oldLinkId);
-
-  if (!oldLink) return;
-
-  // 将旧链接标记为过期
-  oldLink.status = 'expired';
+  /**
+   * 分析协作表现
+   */
+  private evaluateCollaboration(memberData: any, changeLogs: ProjectChange[]): number {
+    const collaborationMetrics = {
+      communicationFrequency: 0,
+      responseTime: 0,
+      coordinationScore: 0,
+      knowledgeSharing: 0,
+      conflictResolution: 0
+    };
 
-  // 生成新链接
-  this.generateReviewLink();
+    // 分析ProjectChange中的协作行为
+    const memberChanges = changeLogs.filter(log =>
+      log.profile.objectId === memberData.memberId
+    );
 
-  alert('✅ 已重新生成评价链接!\n\n旧链接已失效,请使用新链接。');
-}
-```
+    for (const change of memberChanges) {
+      switch (change.changeType) {
+        case 'communication':
+          collaborationMetrics.communicationFrequency += 1;
+          break;
+        case 'coordination':
+          collaborationMetrics.coordinationScore += 1;
+          break;
+        case 'knowledge_sharing':
+          collaborationMetrics.knowledgeSharing += 1;
+          break;
+        case 'conflict_resolution':
+          collaborationMetrics.conflictResolution += 1;
+          break;
+      }
 
-## 10. 性能优化
+      // 计算响应时间
+      if (change.duration && change.duration < 3600000) { // 1小时内响应
+        collaborationMetrics.responseTime += 1;
+      }
+    }
 
-### 10.1 报告生成优化
+    // 归一化评分
+    const maxChanges = Math.max(...Object.values(collaborationMetrics));
+    const normalizedMetrics = Object.fromEntries(
+      Object.entries(collaborationMetrics).map(([key, value]) => [
+        key,
+        maxChanges > 0 ? value / maxChanges : 0
+      ])
+    );
 
-```typescript
-// 使用Worker生成大型报告
-private generateReportWithWorker(data: any): void {
-  if (typeof Worker !== 'undefined') {
-    const worker = new Worker(new URL('./report-generator.worker', import.meta.url));
-
-    worker.onmessage = ({ data }) => {
-      console.log('报告生成完成:', data);
-      this.reviewReport = data.report;
-      this.isGeneratingReview = false;
+    // 加权平均
+    const weights = {
+      communicationFrequency: 0.25,
+      responseTime: 0.3,
+      coordinationScore: 0.2,
+      knowledgeSharing: 0.15,
+      conflictResolution: 0.1
     };
 
-    worker.postMessage({ type: 'generate', data });
-  } else {
-    // 降级为同步生成
-    this.generateReportSync(data);
+    return Object.entries(weights).reduce((score, [metric, weight]) => {
+      return score + normalizedMetrics[metric] * weight;
+    }, 0) * 100;
+  }
   }
 }
 ```
 
-### 10.2 图片压缩
+### 3. 客户满意度分析
+
+#### 3.1 满意度趋势分析
 
 ```typescript
-// 压缩全景图用于预览
-private compressImageForPreview(file: File): Promise<Blob> {
-  return new Promise((resolve, reject) => {
-    const reader = new FileReader();
-
-    reader.onload = (e) => {
-      const img = new Image();
-      img.onload = () => {
-        const canvas = document.createElement('canvas');
-        const ctx = canvas.getContext('2d');
-
-        // 压缩到最大1920px
-        const maxDimension = 1920;
-        const scale = Math.min(maxDimension / img.width, maxDimension / img.height, 1);
-
-        canvas.width = img.width * scale;
-        canvas.height = img.height * scale;
-
-        ctx?.drawImage(img, 0, 0, canvas.width, canvas.height);
-
-        canvas.toBlob((blob) => {
-          if (blob) {
-            resolve(blob);
-          } else {
-            reject(new Error('压缩失败'));
-          }
-        }, 'image/jpeg', 0.8);
-      };
+class SatisfactionAnalyzer {
+  /**
+   * 分析客户满意度趋势
+   */
+  analyzeSatisfactionTrends(
+    projectData: ProjectData,
+    feedbackHistory: ProjectFeedback[]
+  ): SatisfactionAnalysis {
 
-      img.src = e.target?.result as string;
-    };
+    // 计算当前满意度
+    const currentSatisfaction = this.calculateCurrentSatisfaction(feedbackHistory);
 
-    reader.readAsDataURL(file);
-  });
-}
-```
+    // 分析历史趋势
+    const trendAnalysis = this.analyzeHistoricalTrends(feedbackHistory);
 
-### 10.3 数据缓存
+    // 识别满意度驱动因素
+    const drivers = this.identifySatisfactionDrivers(feedbackHistory);
 
-```typescript
-// 缓存复盘报告数据
-private cacheReviewReport(report: any): void {
-  try {
-    localStorage.setItem(
-      `review-report-${this.projectId}`,
-      JSON.stringify(report)
-    );
-    console.log('✅ 复盘报告已缓存');
-  } catch (error) {
-    console.warn('缓存失败:', error);
+    // 预测满意度
+    const prediction = this.predictSatisfaction(projectData, drivers);
+
+    return {
+      currentScore: currentSatisfaction.overallScore,
+      dimensionScores: currentSatisfaction.dimensionScores,
+      trend: trendAnalysis,
+      keyDrivers: drivers,
+      prediction: prediction,
+      improvementAreas: this.identifyImprovementAreas(currentSatisfaction, drivers),
+      recommendations: this.generateSatisfactionRecommendations(currentSatisfaction, drivers)
+    };
   }
-}
 
-// 加载缓存的报告
-private loadCachedReviewReport(): any | null {
-  try {
-    const cached = localStorage.getItem(`review-report-${this.projectId}`);
-    if (cached) {
-      return JSON.parse(cached);
+  /**
+   * 识别满意度关键驱动因素
+   */
+  private identifySatisfactionDrivers(feedback: ProjectFeedback[]): Array<{
+    factor: string;
+    impact: number;
+    correlation: number;
+    description: string;
+  }> {
+    const drivers = [];
+
+    // 分析各维度与整体满意度的相关性
+    const dimensions = ['designQuality', 'serviceAttitude', 'deliveryTimeliness', 'valueForMoney'];
+
+    for (const dimension of dimensions) {
+      const correlation = this.calculateCorrelation(
+        feedback.map(f => this.getDimensionScore(f, dimension)),
+        feedback.map(f => f.rating || 0)
+      );
+
+      if (Math.abs(correlation) > 0.5) { // 相关性阈值
+        drivers.push({
+          factor: dimension,
+          impact: Math.abs(correlation) * 100,
+          correlation: correlation,
+          description: this.getDriverDescription(dimension, correlation)
+        });
+      }
     }
-  } catch (error) {
-    console.warn('加载缓存失败:', error);
+
+    return drivers.sort((a, b) => b.impact - a.impact);
+  }
   }
-  return null;
 }
 ```
 
-## 11. 测试用例
+### 4. 项目复盘洞察生成
 
-### 11.1 尾款结算测试
+#### 4.1 AI驱动的洞察生成
 
 ```typescript
-describe('Final Payment Settlement', () => {
-  it('should initiate auto settlement by technical user', () => {
-    component.roleContext = 'technical';
-    spyOn(component, 'isAllDeliveryCompleted').and.returnValue(true);
-
-    component.initiateAutoSettlement();
-
-    expect(component.miniprogramPaymentStatus).toBe('active');
-    expect(component.settlementRecord).toBeDefined();
-  });
-
-  it('should reject non-technical users', () => {
-    component.roleContext = 'designer';
-    spyOn(window, 'alert');
+class RetrospectiveInsightGenerator {
+  /**
+   * 生成项目复盘洞察
+   */
+  async generateInsights(projectData: ProjectData): Promise<RetrospectiveInsights> {
+    // 1. 数据预处理和特征提取
+    const features = await this.extractFeatures(projectData);
 
-    component.initiateAutoSettlement();
+    // 2. 模式识别
+    const patterns = this.identifyPatterns(features);
 
-    expect(window.alert).toHaveBeenCalledWith(jasmine.stringContaining('仅技术人员'));
-  });
+    // 3. 异常检测
+    const anomalies = this.detectAnomalies(features);
 
-  it('should unlock images after payment received', () => {
-    component.renderLargeImages = [
-      { id: '1', name: 'img1.jpg', url: 'blob:1', locked: true },
-      { id: '2', name: 'img2.jpg', url: 'blob:2', locked: true }
-    ];
+    // 4. 根因分析
+    const rootCauses = this.analyzeRootCauses(patterns, anomalies);
 
-    component.onPaymentReceived({ amount: 75000, method: 'wechat' });
+    // 5. 生成洞察
+    const insights = await this.generateInsightsFromData(patterns, anomalies, rootCauses);
 
-    expect(component.renderLargeImages.every(img => !img.locked)).toBe(true);
-  });
-});
-```
+    return {
+      summary: this.generateExecutiveSummary(insights),
+      highlights: insights.highlights,
+      challenges: insights.challenges,
+      rootCauses: insights.rootCauses,
+      lessons: insights.lessons,
+      recommendations: insights.recommendations,
+      actionItems: this.generateActionItems(insights),
+      riskFactors: this.identifyFutureRisks(insights),
+      successFactors: this.identifySuccessFactors(insights)
+    };
+  }
 
-### 11.2 投诉处理测试
+  /**
+   * 识别项目模式
+   */
+  private identifyPatterns(features: ProjectFeatures): Array<{
+    type: 'positive' | 'negative' | 'neutral';
+    pattern: string;
+    confidence: number;
+    evidence: string[];
+    impact: string;
+  }> {
+    const patterns = [];
+
+    // 识别高效模式
+    if (features.efficiencyPattern === 'consistent_high') {
+      patterns.push({
+        type: 'positive',
+        pattern: '持续高效执行',
+        confidence: 0.85,
+        evidence: [
+          '各阶段效率均高于80%',
+          '里程碑按时完成率100%',
+          '资源利用率稳定在75%-85%'
+        ],
+        impact: '项目执行效率优秀,团队协作顺畅'
+      });
+    }
 
-```typescript
-describe('Complaint Handling', () => {
-  it('should create complaint manually', () => {
-    component.roleContext = 'team-leader';
-    component.complaintFormData = {
-      source: 'manual',
-      stage: '渲染',
-      reason: '质量问题',
-      description: '渲染效果不符合预期',
-      severity: 'medium',
-      tags: ['设计质量']
-    };
+    // 识别协作问题模式
+    if (features.collaborationIssues.length > 2) {
+      patterns.push({
+        type: 'negative',
+        pattern: '跨团队协作障碍',
+        confidence: 0.75,
+        evidence: features.collaborationIssues,
+        impact: '影响项目进度,增加沟通成本'
+      });
+    }
 
-    component.submitComplaint();
+    // 识别客户需求变化模式
+    if (features.requirementChanges > 3) {
+      patterns.push({
+        type: 'neutral',
+        pattern: '需求频繁变更',
+        confidence: 0.8,
+        evidence: [
+          `需求变更次数: ${features.requirementChanges}`,
+          '平均变更间隔: 7天',
+          '变更影响范围: 中等'
+        ],
+        impact: '需要加强需求管理和变更控制'
+      });
+    }
 
-    expect(component.complaints.length).toBeGreaterThan(0);
-  });
+    return patterns;
+  }
+}
+```
 
-  it('should detect keywords and create complaint', () => {
-    const message = '我对渲染效果很不满意,要求退款';
+## 实施建议
 
-    component.monitoringKeywords = ['不满意', '退款'];
+### 1. 技术实施方案
 
-    component.onKeywordDetected(message, '不满意');
+#### 1.1 数据迁移策略
+- **渐进式迁移**: 保留现有功能,逐步添加新特性
+- **数据兼容**: 确保现有ProjectPayment和ProjectFeedback数据兼容
+- **向后兼容**: API设计保持向后兼容性
 
-    expect(component.complaints.length).toBeGreaterThan(0);
-    expect(component.complaints[0].severity).toBe('high');
-  });
-});
-```
+#### 1.2 性能优化
+- **数据缓存**: 复杂分析结果的缓存机制
+- **异步处理**: OCR识别和AI分析的异步处理
+- **分页加载**: 大数据集的分页加载
 
-### 11.3 复盘报告测试
+### 2. 用户体验优化
 
-```typescript
-describe('Review Report Generation', () => {
-  it('should generate complete review report', () => {
-    component.generateReviewReport();
+#### 2.1 引导和帮助
+- **新手引导**: 首次使用时的操作引导
+- **上下文帮助**: 各功能模块的即时帮助
+- **错误恢复**: 操作失败时的友好提示和恢复建议
 
-    // Wait for generation
-    setTimeout(() => {
-      expect(component.reviewReport).toBeDefined();
-      expect(component.reviewReport.sopData).toBeDefined();
-      expect(component.reviewReport.experience).toBeDefined();
-      expect(component.reviewReport.suggestions.length).toBeGreaterThan(0);
-    }, 3000);
-  });
+#### 2.2 移动端适配
+- **响应式设计**: 完整的移动端适配
+- **触摸优化**: 触摸操作的优化
+- **离线支持**: 关键功能的离线缓存
 
-  it('should export report as Excel', () => {
-    component.reviewReport = mockReviewReport;
+### 3. 数据分析应用
 
-    spyOn(document, 'createElement').and.callThrough();
+#### 3.1 实时监控
+- **效率仪表板**: 项目效率的实时监控
+- **质量追踪**: 项目质量的持续追踪
+- **团队状态**: 团队成员状态的实时更新
 
-    component.exportReviewReport('excel');
+#### 3.2 预测分析
+- **风险预警**: 项目风险的早期预警
+- **效率预测**: 基于历史数据的效率预测
+- **资源规划**: 基于分析结果的资源规划建议
 
-    expect(document.createElement).toHaveBeenCalledWith('a');
-  });
-});
-```
+## 总结
 
----
+通过重新设计项目售后归档模块,实现了:
 
-**文档版本**:v1.0.0
-**创建日期**:2025-10-16
-**最后更新**:2025-10-16
-**维护人**:产品团队
+✅ **完整功能覆盖** - 验收尾款、客户评价、项目复盘三大核心功能
+✅ **智能化升级** - OCR识别、AI复盘、智能评价引导
+✅ **数据驱动决策** - 多维度数据分析和洞察生成
+✅ **用户体验优化** - 响应式设计、实时协作、智能辅助
+✅ **科学绩效评估** - 团队成员效率的量化分析和评估
 
-**相关文档**:
-- [AFTERCARE-FEATURES-README.md](/home/ryan/workspace/nova/yss-project/src/app/pages/designer/project-detail/AFTERCARE-FEATURES-README.md) - 售后模块功能实现说明
+该方案将为项目管理提供强大的数据支持,帮助团队持续改进和优化项目执行效率。

+ 2 - 2
src/modules/project/components/project-members-modal/project-members-modal.component.html

@@ -166,7 +166,7 @@
 
               <!-- 操作按钮 -->
               <div class="member-actions">
-                @if (member.isInProjectTeam && !member.isInGroupChat && isWxworkEnvironment) {
+                @if (member.isInProjectTeam && !member.isInGroupChat ) {
                   <button
                     class="action-btn add-btn"
                     (click)="addMemberToGroupChat(member)"
@@ -176,7 +176,7 @@
                       <line x1="12" y1="8" x2="12" y2="16"></line>
                       <path d="M8 12h8"></path>
                     </svg>
-                    <span>添加</span>
+                    <span>邀请进群</span>
                   </button>
                 }
 

+ 34 - 40
src/modules/project/components/project-members-modal/project-members-modal.component.ts

@@ -2,14 +2,14 @@ import { Component, Input, Output, EventEmitter, OnInit } from '@angular/core';
 import { CommonModule } from '@angular/common';
 import { FormsModule } from '@angular/forms';
 import { FmodeObject, FmodeQuery, FmodeParse } from 'fmode-ng/parse';
-import { WxworkCorp } from 'fmode-ng/core';
+import { WxworkCorp, WxworkSDK } from 'fmode-ng/core';
 
 const Parse = FmodeParse.with('nova');
 
 export interface ProjectMember {
   id: string;
   name: string;
-  userId: string;
+  userid: string;
   avatar?: string;
   role: string;
   department?: string;
@@ -58,8 +58,12 @@ export class ProjectMembersModalComponent implements OnInit {
 
   // 企业微信API
   private wecorp: WxworkCorp | null = null;
+  private wwsdk: WxworkSDK | null = null;
 
+  isWechat:boolean = false;
   constructor() {
+    let ua = navigator.userAgent.toLowerCase();
+    this.isWechat = ua.indexOf('micromessenger') !== -1;
     this.checkWxworkEnvironment();
   }
 
@@ -77,20 +81,9 @@ export class ProjectMembersModalComponent implements OnInit {
 
   private checkWxworkEnvironment(): void {
     // 检查是否在企业微信环境中
-    this.isWxworkEnvironment = typeof window !== 'undefined' &&
-                              ((window as any).wx !== undefined ||
-                               (window as any).WWOpenData !== undefined ||
-                               location.hostname.includes('work.weixin.qq.com'));
-
-    if (this.isWxworkEnvironment && this.cid) {
-      try {
-        this.wecorp = new WxworkCorp(this.cid);
-        console.log('✅ 企业微信环境检测成功');
-      } catch (error) {
-        console.warn('⚠️ 企业微信SDK初始化失败:', error);
-        this.isWxworkEnvironment = false;
-      }
-    }
+    this.wecorp = new WxworkCorp(this.cid);
+    this.wwsdk = new WxworkSDK({cid:this.cid,appId:'crm'});
+    console.log('✅ 企业微信环境检测成功');
   }
 
   async loadMembers(): Promise<void> {
@@ -104,9 +97,15 @@ export class ProjectMembersModalComponent implements OnInit {
       const projectTeamMembers = await this.loadProjectTeamMembers();
 
       // 2. 加载群聊成员
+      if(!this.groupChat?.id){
+        const gcQuery2 = new Parse.Query('GroupChat');
+        gcQuery2.equalTo('project', this.project?.id);
+        this.groupChat = await gcQuery2.first();
+      }
       const groupChatMembers = await this.loadGroupChatMembers();
 
       // 3. 合并成员数据
+      console.log("999",projectTeamMembers, groupChatMembers)
       this.mergeMembersData(projectTeamMembers, groupChatMembers);
 
       this.calculateStats();
@@ -125,8 +124,7 @@ export class ProjectMembersModalComponent implements OnInit {
       if (this.project) {
         query.equalTo('project', this.project.toPointer());
       }
-      query.include('profile');
-      query.include('department');
+      query.include('profile','department','profile.department');
       query.notEqualTo('isDeleted', true);
 
       return await query.find();
@@ -141,12 +139,7 @@ export class ProjectMembersModalComponent implements OnInit {
 
     try {
       const memberList = this.groupChat.get('member_list') || [];
-      return memberList.map((member: any) => ({
-        userid: member.userid,
-        name: member.name,
-        type: member.type || 1,
-        avatar: member.avatar
-      }));
+      return memberList
     } catch (error) {
       console.error('加载群聊成员失败:', error);
       return [];
@@ -163,7 +156,7 @@ export class ProjectMembersModalComponent implements OnInit {
         const member: ProjectMember = {
           id: profile.id,
           name: profile.get('name') || '未知',
-          userId: profile.get('userid') || '',
+          userid: profile.get('userid') || '',
           avatar: profile.get('data')?.avatar,
           role: profile.get('roleName') || '未知',
           department: profile.get('department')?.get('name'),
@@ -180,7 +173,7 @@ export class ProjectMembersModalComponent implements OnInit {
     groupChatMembers.forEach(groupMember => {
       // 查找是否已在项目团队中
       const existingMember = Array.from(memberMap.values()).find(
-        m => m.userId === groupMember.userid || m.name === groupMember.name
+        m => m.userid === groupMember.userid || m.name === groupMember.name
       );
 
       if (existingMember) {
@@ -190,7 +183,7 @@ export class ProjectMembersModalComponent implements OnInit {
         const member: ProjectMember = {
           id: groupMember.userid,
           name: groupMember.name,
-          userId: groupMember.userid,
+          userid: groupMember.userid,
           avatar: groupMember.avatar,
           role: groupMember.type === 1 ? '外部联系人' : '内部成员',
           isInGroupChat: true,
@@ -259,34 +252,35 @@ export class ProjectMembersModalComponent implements OnInit {
   }
 
   async addMemberToGroupChat(member: ProjectMember): Promise<void> {
-    if (!this.isWxworkEnvironment || !this.wecorp || !this.groupChat) {
-      alert('当前环境不支持此操作');
-      return;
+   
+    if(!this.isWechat){
+      alert("请在企业微信客户端添加")
     }
-
-    if (!member.userId) {
+    if (!member.userid) {
       alert('该成员没有用户ID,无法添加到群聊');
       return;
     }
 
     try {
-      const chatId = this.groupChat.get('chat_id');
+      const chatId = this.groupChat?.get('chat_id');
       if (!chatId) {
         alert('群聊ID不存在');
         return;
       }
 
-      console.log(`🚀 开始添加成员 ${member.name} (${member.userId}) 到群聊 ${chatId}`);
+      console.log(`🚀 开始添加成员 ${member.name} (${member.userid}) 到群聊 ${chatId}`);
 
       // TODO: 实现正确的企业微信API调用
-      // await this.wecorp.appchat.updateEnterpriseChat({
-      //   chatId: chatId,
-      //   userIdsToAdd: [member.userId]
-      // });
+      let result = await this.wwsdk?.ww.updateEnterpriseChat({
+        chatId: chatId,
+        userIdsToAdd: [member.userid]
+      });
 
       // 临时:直接更新本地状态用于演示
-      member.isInGroupChat = true;
-      this.calculateStats();
+      if(result){
+        member.isInGroupChat = true;
+        this.calculateStats();
+      }
 
       alert(`✅ 已将 ${member.name} 添加到群聊`);
       console.log(`✅ 成功添加成员 ${member.name} 到群聊`);

+ 7 - 9
src/modules/project/components/team-assign/team-assign.component.html

@@ -2,10 +2,6 @@
 <div class="card designer-card">
   <div class="card-header">
     <h3 class="card-title">
-      <svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
-        <path fill="currentColor" d="M402 168c-2.93 40.67-33.1 72-66 72s-63.12-31.32-66-72c-3-42.31 26.37-72 66-72s69 30.46 66 72z"/>
-        <path fill="currentColor" d="M336 304c-65.17 0-127.84 32.37-143.54 95.41-2.08 8.34 3.15 16.59 11.72 16.59h263.65c8.57 0 13.77-8.25 11.72-16.59C463.85 335.36 401.18 304 336 304z"/>
-      </svg>
       设计师分配
     </h3>
     <p class="card-subtitle">先选择项目组,再选择组员</p>
@@ -91,13 +87,14 @@
         } @else {
           <div class="designer-grid">
             @for (designer of departmentMembers; track designer.id) {
+             @if(designer?.get){
               <div
                 class="designer-item"
-                [class.selected]="selectedDesigner?.id === designer.id"
+                [class.selected]="selectedDesigner?.id === designer?.id"
                 (click)="selectDesigner(designer)">
                 <div class="designer-avatar">
-                  @if (designer.get('data')?.avatar) {
-                    <img [src]="designer.get('data').avatar" alt="设计师头像" />
+                  @if (designer?.get('data')?.avatar) {
+                    <img [src]="designer?.get('data').avatar" alt="设计师头像" />
                   } @else {
                     <svg class="icon avatar-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
                       <path fill="currentColor" d="M256 48C141.31 48 48 141.31 48 256s93.31 208 208 208 208-93.31 208-208S370.69 48 256 48zm0 60a60 60 0 11-60 60 60 60 0 0160-60zm0 336c-63.6 0-119.92-36.47-146.39-89.68C109.74 329.09 176.24 296 256 296s146.26 33.09 146.39 58.32C376.92 407.53 319.6 444 256 444z"/>
@@ -105,15 +102,16 @@
                   }
                 </div>
                 <div class="designer-info">
-                  <h4>{{ designer.get('name') }}</h4>
+                  <h4>{{ designer?.get('name') }}</h4>
                   <p>{{ getDesignerWorkload(designer) }}</p>
                 </div>
-                @if (selectedDesigner?.id === designer.id) {
+                @if (selectedDesigner?.id === designer?.id) {
                   <svg class="icon selected-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
                     <path fill="currentColor" d="M256 48C141.31 48 48 141.31 48 256s93.31 208 208 208 208-93.31 208-208S370.69 48 256 48zm-38 312.38L137.4 280.8a24 24 0 0133.94-33.94l50.2 50.2 95.74-95.74a24 24 0 0133.94 33.94z"/>
                   </svg>
                 }
               </div>
+              }
             }
           </div>
         }

+ 8 - 0
src/modules/project/components/team-assign/team-assign.component.scss

@@ -1,5 +1,13 @@
 /* 设计师分配组件样式(复用 StageOrder 风格) */
 
+
+.card{
+  background: var(--white);
+  border-radius: 12px;
+  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
+  padding: 15px;
+}
+
 .designer-card {
   .section-title {
     font-size: 15px;

+ 5 - 3
src/modules/project/components/team-assign/team-assign.component.ts

@@ -78,7 +78,7 @@ export class TeamAssignComponent implements OnInit {
       deptQuery.notEqualTo('isDeleted', true);
       deptQuery.ascending('name');
       this.departments = await deptQuery.find();
-
+      console.log("this.departments",this.departments)
       // 加载项目团队
       await this.loadProjectTeams();
 
@@ -152,13 +152,14 @@ export class TeamAssignComponent implements OnInit {
       if (leader) {
         this.departmentMembers.unshift(leader);
       }
-      return this.departmentMembers;
+      this.loadingMembers = false;
     } catch (err) {
       console.error('加载项目组成员失败:', err);
     } finally {
       this.loadingMembers = false;
     }
-    return [];
+    this.cdr.detectChanges()
+    return this.departmentMembers;
   }
 
   selectDesigner(designer: FmodeObject) {
@@ -231,6 +232,7 @@ export class TeamAssignComponent implements OnInit {
         const team = new ProjectTeam();
         team.set('project', this.project.toPointer());
         team.set('profile', this.assigningDesigner.toPointer());
+        team.set('department', this.assigningDesigner.get("department"));
         team.set('role', '组员');
         team.set('data', {
           spaces: this.selectedSpaces,

+ 8 - 8
src/modules/project/pages/project-detail/project-detail.component.html

@@ -119,12 +119,12 @@
   </app-project-files-modal>
 
   <!-- 成员模态框 -->
-  <app-project-members-modal
-    [project]="project"
-    [groupChat]="groupChat"
-    [currentUser]="currentUser"
-    [cid]="cid"
-    [isVisible]="showMembersModal"
-    (close)="closeMembersModal()">
-  </app-project-members-modal>
+     <app-project-members-modal
+     [project]="project"
+     [groupChat]="groupChat"
+     [currentUser]="currentUser"
+     [cid]="cid"
+     [isVisible]="showMembersModal"
+     (close)="closeMembersModal()">
+    </app-project-members-modal>
 </div>

+ 10 - 3
src/modules/project/pages/project-detail/project-detail.component.ts

@@ -168,7 +168,7 @@ export class ProjectDetailComponent implements OnInit {
         if (this.projectId) {
           // 通过 projectId 加载(从后台进入)
           const query = new Parse.Query('Project');
-          query.include('customer', 'assignee');
+          query.include('customer', 'assignee','department','department.leader');
           this.project = await query.get(this.projectId);
         } else if (this.chatId) {
           // 通过 chat_id 查找项目(从企微群聊进入)
@@ -178,7 +178,14 @@ export class ProjectDetailComponent implements OnInit {
             const gcQuery = new Parse.Query('GroupChat');
             gcQuery.equalTo('chat_id', this.chatId);
             gcQuery.equalTo('company', companyId);
-            const groupChat = await gcQuery.first();
+            let groupChat = await gcQuery.first();
+
+            if(!groupChat?.id){
+              const gcQuery2 = new Parse.Query('GroupChat');
+              gcQuery2.equalTo('project', this.projectId);
+              gcQuery2.equalTo('company', companyId);
+              groupChat = await gcQuery2.first();
+            }
 
             if (groupChat) {
               this.groupChat = groupChat;
@@ -186,7 +193,7 @@ export class ProjectDetailComponent implements OnInit {
 
               if (projectPointer) {
                 const pQuery = new Parse.Query('Project');
-                pQuery.include('customer', 'assignee');
+                pQuery.include('customer', 'assignee','department','department.leader');
                 this.project = await pQuery.get(projectPointer.id);
               }
             }

+ 1 - 154
src/modules/project/pages/project-detail/stages/stage-order.component.html

@@ -168,160 +168,7 @@
       [currentUser]="currentUser">
     </app-team-assign>
 
-    <!-- 6. 项目文件管理 -->
-    <div class="card files-card">
-      <div class="card-header">
-        <h3 class="card-title">
-          <svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
-            <path fill="currentColor" d="M416 221.25V416a48 48 0 01-48 48H144a48 48 0 01-48-48V96a48 48 0 0148-48h98.75a32 32 0 0122.62 9.37l141.26 141.26a32 32 0 019.37 22.62z"/>
-            <path fill="currentColor" d="M256 56v120a32 32 0 0032 32h120"/>
-          </svg>
-          项目文件
-        </h3>
-        <p class="card-subtitle">
-          支持手动上传和企业微信拖拽上传,文件存储在项目目录中
-          @if (wxFileDropSupported) {
-            <span class="wx-support-indicator">📱 支持企业微信拖拽</span>
-          }
-        </p>
-      </div>
-      <div class="card-content">
-        <!-- 上传区域 -->
-        @if (canEdit) {
-          <div class="upload-section">
-            <div
-              #dropZone
-              class="drop-zone"
-              [class.drag-over]="dragOver"
-              [class.uploading]="isUploading"
-              (click)="triggerFileSelect()"
-              (dragover)="onDragOver($event)"
-              (dragleave)="onDragLeave($event)"
-              (drop)="onDrop($event)">
-
-              <!-- 上传图标和提示 -->
-              @if (!isUploading) {
-                <div class="upload-content">
-                  <div class="upload-icon">
-                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="none" stroke="currentColor" stroke-width="2">
-                      <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path>
-                      <polyline points="17,8 12,3 7,8"></polyline>
-                      <line x1="12" y1="3" x2="12" y2="15"></line>
-                    </svg>
-                  </div>
-                  <div class="upload-text">
-                    <p class="upload-title">
-                      拖拽文件到此处或 <span class="upload-link">点击选择文件</span>
-                    </p>
-                    <p class="upload-hint">
-                      @if (wxFileDropSupported) {
-                        支持从企业微信拖拽文件 •
-                      }
-                      支持多文件上传
-                    </p>
-                  </div>
-                </div>
-              }
-
-              <!-- 上传进度 -->
-              @if (isUploading) {
-                <div class="upload-progress">
-                  <div class="progress-circle">
-                    <svg class="progress-svg" viewBox="0 0 36 36">
-                      <path class="progress-bg"
-                        d="M18 2.0845 a 15.9155 15.9155 0 0 1 0 31.831 a 15.9155 15.9155 0 0 1 0 -31.831"
-                      />
-                      <path class="progress-bar"
-                        d="M18 2.0845 a 15.9155 15.9155 0 0 1 0 31.831 a 15.9155 15.9155 0 0 1 0 -31.831"
-                        [style.stroke-dasharray]="uploadProgress + ', 100'"
-                      />
-                    </svg>
-                    <div class="progress-text">{{ uploadProgress | number:'1.0-0' }}%</div>
-                  </div>
-                  <p class="progress-title">正在上传文件...</p>
-                </div>
-              }
-
-              <!-- 隐藏的文件输入 -->
-              <input #fileInput
-                     type="file"
-                     multiple
-                     [disabled]="isUploading"
-                     (change)="onFileSelect($event)"
-                     class="file-input">
-            </div>
-          </div>
-        }
-
-        <!-- 文件列表 -->
-        @if (projectFiles.length > 0) {
-          <div class="files-list">
-            <h4 class="section-title">
-              项目文件 ({{ projectFiles.length }})
-            </h4>
-            <div class="files-grid">
-              @for (file of projectFiles; track file.id) {
-                <div class="file-item">
-                  <div class="file-preview">
-                    @if (isImageFile(file.type)) {
-                      <img [src]="file.url" [alt]="file.name" class="file-image" />
-                    } @else {
-                      <div class="file-icon-large">
-                        {{ getFileIcon(file.type) }}
-                      </div>
-                    }
-                  </div>
-                  <div class="file-info">
-                    <h5 class="file-name" [title]="file.name">{{ file.name }}</h5>
-                    <div class="file-meta">
-                      <span class="file-size">{{ formatFileSize(file.size) }}</span>
-                      <span class="file-date">{{ file.uploadedAt | date:'MM-dd HH:mm' }}</span>
-                      <span class="file-uploader">{{ file.uploadedBy }}</span>
-                    </div>
-                  </div>
-                  <div class="file-actions">
-                    <button
-                      class="action-btn"
-                      (click)="downloadFile(file.url, file.name)"
-                      title="下载文件">
-                      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
-                        <path d="M376 232H216V72c0-13.3-10.7-24-24-24s-24 10.7-24 24v160H8c-13.3 0-24 10.7-24 24s10.7 24 24 24h160v160c0 13.3 10.7 24 24 24s24-10.7 24-24V280h160c13.3 0 24-10.7 24-24s-10.7-24-24-24z"/>
-                      </svg>
-                    </button>
-                    @if (canEdit) {
-                      <button
-                        class="action-btn delete-btn"
-                        (click)="deleteProjectFile(file.id)"
-                        title="删除文件">
-                        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
-                          <path d="M296 64h-80a7.91 7.91 0 00-8 8v56H136a56.16 56.16 0 00-56 56v208a56.16 56.16 0 0056 56h240a56.16 56.16 0 0056-56V184a56.16 56.16 0 00-56-56h-72V72a7.91 7.91 0 00-8-8zm-72 264h96a8 8 0 018 8v16a8 8 0 01-8 8h-96a8 8 0 01-8-8v-16a8 8 0 018-8z"/>
-                        </svg>
-                      </button>
-                    }
-                  </div>
-                </div>
-              }
-            </div>
-          </div>
-        } @else {
-          <div class="empty-files">
-            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor" class="empty-icon">
-              <path d="M64 464V48a48 48 0 0148-48h192a48 48 0 0133.94 13.94l83.05 83.05A48 48 0 01384 176v288a48 48 0 01-48 48H112a48 48 0 01-48-48zm176-304h144a16 16 0 0016-16v-16a16 16 0 00-16-16H240a16 16 0 00-16 16v16a16 16 0 0016 16zm48 0h96a16 16 0 0016-16v-16a16 16 0 00-16-16H288a16 16 0 00-16 16v16a16 16 0 0016 16zm-48 96h144a16 16 0 0016-16v-16a16 16 0 00-16-16H240a16 16 0 00-16 16v16a16 16 0 0016 16zm48 0h96a16 16 0 0016-16v-16a16 16 0 00-16-16H288a16 16 0 00-16 16v16a16 16 0 0016 16z"/>
-            </svg>
-            <p class="empty-text">暂无项目文件</p>
-            <p class="empty-hint">
-              @if (wxFileDropSupported) {
-                尝试从企业微信拖拽文件,或点击上方按钮上传
-              } @else {
-                点击上方按钮上传项目文件
-              }
-            </p>
-          </div>
-        }
-      </div>
-    </div>
-
-    <!-- 7. 操作按钮 -->
+    <!-- 6. 操作按钮 -->
     @if (canEdit) {
       <div class="action-buttons">
         <button