Browse Source

feet:customer12

徐福静0235668 3 days ago
parent
commit
353c852025
22 changed files with 2519 additions and 813 deletions
  1. 35 0
      src/app/pages/designer/project-detail/debug-styles.scss
  2. 12 1
      src/app/pages/designer/project-detail/project-detail.html
  3. 9 0
      src/app/pages/designer/project-detail/project-detail.scss
  4. 150 3
      src/app/pages/designer/project-detail/project-detail.ts
  5. 245 245
      src/app/pages/team-leader/dashboard/dashboard.scss
  6. 1 0
      src/app/pages/team-leader/ios-theme.scss
  7. 3 3
      src/app/services/project.service.ts
  8. 281 238
      src/app/shared/components/complaint-card/complaint-card.scss
  9. 45 2
      src/app/shared/components/consultation-order-panel/consultation-order-panel.component.html
  10. 40 5
      src/app/shared/components/consultation-order-panel/consultation-order-panel.component.scss
  11. 49 12
      src/app/shared/components/consultation-order-panel/consultation-order-panel.component.ts
  12. 120 287
      src/app/shared/components/customer-review-card/customer-review-card.scss
  13. 12 11
      src/app/shared/components/proposal-confirm-card/proposal-confirm-card.scss
  14. 4 5
      src/app/shared/components/requirements-confirm-card/requirements-confirm-card.scss
  15. 152 0
      src/app/shared/components/team-assignment-dialog/team-assignment-dialog.component.html
  16. 340 0
      src/app/shared/components/team-assignment-dialog/team-assignment-dialog.component.scss
  17. 216 0
      src/app/shared/components/team-assignment-dialog/team-assignment-dialog.component.ts
  18. 103 0
      src/app/shared/components/team-assignment-modal/team-assignment-modal.component.html
  19. 463 0
      src/app/shared/components/team-assignment-modal/team-assignment-modal.component.scss
  20. 233 0
      src/app/shared/components/team-assignment-modal/team-assignment-modal.component.ts
  21. 5 0
      src/assets/images/default-avatar.svg
  22. 1 1
      src/styles.scss

+ 35 - 0
src/app/pages/designer/project-detail/debug-styles.scss

@@ -428,4 +428,39 @@
 
 .vertical-stage-block.active .dot {
   background: #fa8c16 !important;
+}
+
+/* 订单创建阶段完成后的绿色高亮 */
+.vertical-stage-block.completed {
+  background: #f6ffed !important;
+  border-color: #b7eb8f !important;
+  box-shadow: 0 2px 8px rgba(183, 235, 143, 0.3) !important;
+}
+
+.vertical-stage-block.completed .vertical-stage-header h3 {
+  color: #389e0d !important;
+  font-weight: 600 !important;
+}
+
+.vertical-stage-block.completed .dot {
+  background: #52c41a !important;
+}
+
+/* 需求沟通阶段激活时的高亮 */
+.vertical-stage-block[id="stage-requirements-talk"].active {
+  background: linear-gradient(135deg, #e6f7ff 0%, #f0f9ff 100%) !important;
+  border-color: #40a9ff !important;
+  box-shadow: 0 4px 16px rgba(64, 169, 255, 0.2) !important;
+  transform: translateY(-2px) !important;
+  transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1) !important;
+}
+
+.vertical-stage-block[id="stage-requirements-talk"].active .vertical-stage-header h3 {
+  color: #1890ff !important;
+  font-weight: 700 !important;
+}
+
+.vertical-stage-block[id="stage-requirements-talk"].active .dot {
+  background: #1890ff !important;
+  box-shadow: 0 0 0 4px rgba(24, 144, 255, 0.2) !important;
 }

+ 12 - 1
src/app/pages/designer/project-detail/project-detail.html

@@ -85,6 +85,15 @@
         </button>
       </div>
     </div>
+
+  <!-- 团队分配弹窗 -->
+  @if (showTeamAssignmentModal) {
+    <app-team-assignment-modal
+      [isVisible]="showTeamAssignmentModal"
+      (closeModal)="closeTeamAssignmentModal()"
+      (confirmAssignment)="confirmTeamAssignment($event)">
+    </app-team-assignment-modal>
+  }
 </div>
 
 <!-- 四大板块按钮组 - 位于项目详情标题区域正下方 -->
@@ -94,6 +103,7 @@
             [class.completed]="getSectionStatus(sec.key) === 'completed'"
             [class.active]="getSectionStatus(sec.key) === 'active'"
             [class.pending]="getSectionStatus(sec.key) === 'pending'"
+            [class.current-order]="sec.key === 'order' && isCurrentOrderCreation()"
             (click)="toggleSection(sec.key)">
       <span class="section-label">{{ sec.label }}</span>
     </button>
@@ -263,7 +273,8 @@
                     <div class="vertical-stage-body">
                       @if (stage === '订单创建') {
                         <app-consultation-order-panel
-                          (formSubmit)="onConsultationOrderSubmit($event)"
+                          (orderCreated)="onConsultationOrderSubmit($event)"
+                          (projectCreated)="onProjectCreated($event)"
                         ></app-consultation-order-panel>
                       } @else if (stage === '需求沟通') {
                         <app-requirements-confirm-card 

+ 9 - 0
src/app/pages/designer/project-detail/project-detail.scss

@@ -67,6 +67,15 @@
       color: $ios-text-secondary;
       border-color: rgba(0, 0, 0, 0.1);
     }
+    
+    // 订单创建按钮的红色高亮状态
+    &.current-order {
+      background: linear-gradient(135deg, #ffe6e6 0%, #ffcccc 100%);
+      color: #d32f2f;
+      border-color: #d32f2f;
+      box-shadow: 0 0.15rem 0.6rem rgba(211, 47, 47, 0.2);
+      font-weight: 600;
+    }
   }
 }
 

+ 150 - 3
src/app/pages/designer/project-detail/project-detail.ts

@@ -1,4 +1,4 @@
-import { Component, OnInit, OnDestroy } from '@angular/core';
+import { Component, OnInit, OnDestroy, ChangeDetectorRef } from '@angular/core';
 import { CommonModule } from '@angular/common';
 import { ActivatedRoute, Router } from '@angular/router';
 import { FormsModule, ReactiveFormsModule, FormBuilder, FormGroup, Validators } from '@angular/forms';
@@ -17,6 +17,7 @@ import { RequirementsConfirmCardComponent } from '../../../shared/components/req
 import { SettlementCardComponent } from '../../../shared/components/settlement-card/settlement-card';
 import { CustomerReviewCardComponent } from '../../../shared/components/customer-review-card/customer-review-card';
 import { ComplaintCardComponent } from '../../../shared/components/complaint-card/complaint-card';
+import { TeamAssignmentModalComponent } from '../../../shared/components/team-assignment-modal/team-assignment-modal.component';
 import { VerticalNavComponent } from './components/vertical-nav/vertical-nav.component';
 
 interface ExceptionHistory {
@@ -61,7 +62,7 @@ type SectionKey = 'order' | 'requirements' | 'delivery' | 'aftercare';
 @Component({
   selector: 'app-project-detail',
   standalone: true,
-  imports: [CommonModule, FormsModule, ReactiveFormsModule, ConsultationOrderPanelComponent, RequirementsConfirmCardComponent, SettlementCardComponent, CustomerReviewCardComponent, ComplaintCardComponent, VerticalNavComponent],
+  imports: [CommonModule, FormsModule, ReactiveFormsModule, ConsultationOrderPanelComponent, RequirementsConfirmCardComponent, SettlementCardComponent, CustomerReviewCardComponent, ComplaintCardComponent, TeamAssignmentModalComponent, VerticalNavComponent],
   templateUrl: './project-detail.html',
   styleUrls: ['./project-detail.scss', './debug-styles.scss']
 })
@@ -139,6 +140,11 @@ export class ProjectDetail implements OnInit, OnDestroy {
   // 团队协作时间轴
   timelineEvents: TimelineEvent[] = [];
 
+  // 团队分配弹窗相关
+  showTeamAssignmentModal = false;
+  selectedDesigner: any = null;
+  projectData: any = null;
+
   // ============ 阶段图片上传状态(新增) ============
   allowedImageTypes: string = '.jpg,.jpeg,.png';
   // 增加审核状态reviewStatus与是否已同步synced标记(仅由组长操作)
@@ -157,6 +163,7 @@ export class ProjectDetail implements OnInit, OnDestroy {
     private projectService: ProjectService,
     private router: Router,
     private fb: FormBuilder,
+    private cdr: ChangeDetectorRef,
   ) {}
 
   // 切换标签页
@@ -197,6 +204,11 @@ export class ProjectDetail implements OnInit, OnDestroy {
     this.router.navigate([], { relativeTo: this.route, queryParamsHandling: 'merge', queryParams: { id: projectId } });
   }
 
+  // 检查是否处于订单创建阶段,用于红色高亮显示
+  isCurrentOrderCreation(): boolean {
+    return this.project?.currentStage === '订单创建';
+  }
+
   // 返回工作台
   backToWorkbench(): void {
     this.router.navigate(['/designer/dashboard']);
@@ -1391,6 +1403,7 @@ export class ProjectDetail implements OnInit, OnDestroy {
       case '建模':
       case '软装':
       case '渲染':
+      case '后期':
         return 'delivery';
       case '尾款结算':
       case '客户评价':
@@ -1440,7 +1453,7 @@ export class ProjectDetail implements OnInit, OnDestroy {
       '建模': 'modeling',
       '软装': 'softdecor',
       '渲染': 'render',
-      '后期': 'aftercare',
+      '后期': 'post',
       '尾款结算': 'settlement',
       '客户评价': 'customer-review',
       '投诉处理': 'complaint'
@@ -1731,5 +1744,139 @@ export class ProjectDetail implements OnInit, OnDestroy {
     console.log('咨询订单表单提交:', formData);
     // 这里可以添加处理表单提交的逻辑
     // 例如:保存订单信息、更新项目状态等
+    
+    // 保存项目数据
+    this.projectData = formData;
+    
+    // 显示团队分配弹窗
+    this.showTeamAssignmentModal = true;
+  }
+
+  // 处理项目创建成功
+  onProjectCreated(projectData: any): void {
+    console.log('项目创建成功:', projectData);
+    
+    // 保存项目数据
+    this.projectData = projectData;
+    
+    // 显示团队分配弹窗
+    this.showTeamAssignmentModal = true;
+  }
+
+  // 确认团队分配
+  confirmTeamAssignment(designer: any): void {
+    console.log('确认团队分配:', designer);
+    
+    // 保存选中的设计师
+    this.selectedDesigner = designer;
+    
+    // 关闭团队分配弹窗
+    this.showTeamAssignmentModal = false;
+    
+    // 更新项目状态到下一阶段
+    if (this.project) {
+      this.project.currentStage = '需求沟通';
+      
+      // 显示成功提示
+      this.showSuccessMessage('项目创建成功!已分配给设计师:' + designer.name);
+      
+      // 自动切换到需求沟通阶段
+      this.scrollToStage('需求沟通');
+      
+      // 更新阶段展开状态
+      this.expandedSection = 'requirements';
+      
+      // 更新顶部导航栏状态(订单创建标绿,确认需求高亮)
+      this.updateNavigationStatus();
+    }
+  }
+
+  // 关闭团队分配弹窗
+  closeTeamAssignmentModal(): void {
+    this.showTeamAssignmentModal = false;
+  }
+
+  // 更新导航栏状态
+  private updateNavigationStatus(): void {
+    // 更新项目当前阶段为需求沟通
+    if (this.project) {
+      this.project.currentStage = '需求沟通';
+    }
+    
+    // 触发变更检测,确保UI更新
+    this.cdr.detectChanges();
+    
+    console.log('更新导航栏状态:订单创建已完成,需求沟通为当前阶段');
+  }
+
+  // 显示成功提示消息
+  private showSuccessMessage(message: string): void {
+    // 创建成功提示元素
+    const successToast = document.createElement('div');
+    successToast.className = 'success-toast';
+    successToast.innerHTML = `
+      <div class="toast-content">
+        <div class="toast-icon">✓</div>
+        <div class="toast-message">${message}</div>
+      </div>
+    `;
+    
+    // 添加样式
+    successToast.style.cssText = `
+      position: fixed;
+      top: 20px;
+      right: 20px;
+      background: linear-gradient(135deg, #34C759 0%, #28A745 100%);
+      color: white;
+      padding: 16px 24px;
+      border-radius: 12px;
+      box-shadow: 0 4px 20px rgba(52, 199, 89, 0.3);
+      z-index: 10000;
+      font-family: -apple-system, BlinkMacSystemFont, 'PingFang SC', sans-serif;
+      font-size: 14px;
+      font-weight: 500;
+      transform: translateX(100%);
+      transition: transform 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
+    `;
+    
+    const toastContent = successToast.querySelector('.toast-content') as HTMLElement;
+    if (toastContent) {
+      toastContent.style.cssText = `
+        display: flex;
+        align-items: center;
+        gap: 12px;
+      `;
+    }
+    
+    const toastIcon = successToast.querySelector('.toast-icon') as HTMLElement;
+    if (toastIcon) {
+      toastIcon.style.cssText = `
+        width: 24px;
+        height: 24px;
+        background: rgba(255, 255, 255, 0.2);
+        border-radius: 50%;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        font-size: 16px;
+        font-weight: bold;
+      `;
+    }
+    
+    // 添加到页面
+    document.body.appendChild(successToast);
+    
+    // 显示动画
+    setTimeout(() => {
+      successToast.style.transform = 'translateX(0)';
+    }, 100);
+    
+    // 自动隐藏
+    setTimeout(() => {
+      successToast.style.transform = 'translateX(100%)';
+      setTimeout(() => {
+        document.body.removeChild(successToast);
+      }, 300);
+    }, 3000);
   }
 }

+ 245 - 245
src/app/pages/team-leader/dashboard/dashboard.scss

@@ -1,44 +1,44 @@
-@import '../../../shared/styles/ios-theme';
-@import '../ios-theme.scss';
+@use '../../../shared/styles/ios-theme' as ios;
+@use '../ios-theme.scss' as local;
 
 :host {
   display: block;
-  background-color: $ios-background-secondary;
+  background-color: ios.$ios-background-secondary;
   min-height: 100vh;
-  padding: $ios-spacing-lg;
+  padding: ios.$ios-spacing-lg;
 }
 
 .dashboard-header {
-  margin-bottom: $ios-spacing-xxl;
+  margin-bottom: local.$ios-spacing-xxl;
   h1 {
-    font-size: $ios-font-size-xl;
-    font-weight: $ios-font-weight-bold;
-    color: $ios-text-primary;
-    margin: 0 0 $ios-spacing-lg 0;
+    font-size: local.$ios-font-size-xl;
+    font-weight: local.$ios-font-weight-bold;
+    color: local.$ios-text-primary;
+    margin: 0 0 local.$ios-spacing-lg 0;
   }
   
   // �詨��唳旿����∠��瑕�
   .dashboard-metrics {
     display: grid;
     grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
-    gap: $ios-spacing-lg;
-    margin-top: $ios-spacing-lg;
+    gap: local.$ios-spacing-lg;
+    margin-top: local.$ios-spacing-lg;
     
     .metric-card {
       display: flex;
       align-items: center;
-      gap: $ios-spacing-md;
-      background: linear-gradient(135deg, $ios-card-background, #f8f9fa);
-      border-radius: $ios-radius-lg;
-      padding: $ios-spacing-lg;
-      border: 1px solid $ios-border;
-      box-shadow: $ios-shadow-sm;
+      gap: local.$ios-spacing-md;
+      background: linear-gradient(135deg, local.$ios-card-background, #f8f9fa);
+      border-radius: local.$ios-radius-lg;
+      padding: local.$ios-spacing-lg;
+      border: 1px solid local.$ios-border;
+      box-shadow: local.$ios-shadow-sm;
       cursor: pointer;
       transition: all 0.3s ease;
       
       &:hover {
         transform: translateY(-2px);
-        box-shadow: $ios-shadow-card;
+        box-shadow: local.$ios-shadow-card;
       }
       
       .metric-icon {
@@ -48,8 +48,8 @@
         display: flex;
         align-items: center;
         justify-content: center;
-        border-radius: $ios-radius-full;
-        background-color: $ios-background;
+        border-radius: local.$ios-radius-full;
+        background-color: local.$ios-background;
       }
       
       .metric-icon.warning { background-color: rgba(255, 149, 0, 0.1); }
@@ -60,14 +60,14 @@
       
       .metric-count {
         font-size: 2rem;
-        font-weight: $ios-font-weight-bold;
-        color: $ios-text-primary;
+        font-weight: local.$ios-font-weight-bold;
+        color: local.$ios-text-primary;
         line-height: 1.2;
       }
       
       .metric-label {
-        font-size: $ios-font-size-sm;
-        color: $ios-text-secondary;
+        font-size: local.$ios-font-size-sm;
+        color: local.$ios-text-secondary;
         text-transform: uppercase;
         letter-spacing: 0.5px;
       }
@@ -75,12 +75,12 @@
   }
 }
 
-/* ���撅𤩺甅撘譍��吔��誩��烾𡢿頝苷��堒捐嚗䔶�霂�虾閫��摨� */
+/* ���撅𤩺甅撘譍��吔��誩��烾𡢿頝苷��堒捐嚗䔶�霂�虾閫��嚙?*/
 @media (max-width: 640px) {
   .project-kanban {
-    .kanban-header { gap: $ios-spacing-sm; }
+    .kanban-header { gap: local.$ios-spacing-sm; }
     .kanban-body {
-      gap: $ios-spacing-sm;
+      gap: local.$ios-spacing-sm;
       .kanban-column {
         min-width: 160px;
         max-width: 160px;
@@ -109,11 +109,11 @@
   display: flex;
   justify-content: space-between;
   align-items: center;
-  margin-bottom: $ios-spacing-lg;
+  margin-bottom: local.$ios-spacing-lg;
   h2 {
-    font-size: $ios-font-size-lg;
-    font-weight: $ios-font-weight-semibold;
-    color: $ios-text-primary;
+    font-size: local.$ios-font-size-lg;
+    font-weight: local.$ios-font-weight-semibold;
+    color: local.$ios-text-primary;
     margin: 0;
   }
   .section-actions {
@@ -132,51 +132,51 @@
 }
 
 .btn-toggle-view {
-  padding: $ios-spacing-sm $ios-spacing-md;
-  border-radius: $ios-radius-md;
-  border: 1px solid $ios-border;
+  padding: local.$ios-spacing-sm local.$ios-spacing-md;
+  border-radius: local.$ios-radius-md;
+  border: 1px solid local.$ios-border;
   background: linear-gradient(180deg, #fff, #f8fafc);
-  color: $ios-text-primary;
-  font-size: $ios-font-size-sm;
+  color: local.$ios-text-primary;
+  font-size: local.$ios-font-size-sm;
   cursor: pointer;
-  box-shadow: $ios-shadow-sm;
+  box-shadow: local.$ios-shadow-sm;
   transition: all .2s ease;
   &:hover {
     transform: translateY(-1px);
-    box-shadow: $ios-shadow-card;
+    box-shadow: local.$ios-shadow-card;
   }
 }
 
 .gantt-card {
-  background: $ios-card-background;
-  border: 1px solid $ios-border;
-  border-radius: $ios-radius-lg;
-  box-shadow: $ios-shadow-card;
-  padding: $ios-spacing-lg;
-  margin-bottom: $ios-spacing-xl;
-  position: relative; // 蝖桐����蝏嘥笆摰帋�銝𧢲��箔�霂亙捆��
+  background: local.$ios-card-background;
+  border: 1px solid local.$ios-border;
+  border-radius: local.$ios-radius-lg;
+  box-shadow: local.$ios-shadow-card;
+  padding: local.$ios-spacing-lg;
+  margin-bottom: local.$ios-spacing-xl;
+  position: relative; // 蝖桐����蝏嘥笆摰帋�銝𧢲��箔�霂亙捆嚙?
   
   .gantt-header {
     display: flex;
     justify-content: space-between;
     align-items: center;
-    margin-bottom: $ios-spacing-md;
+    margin-bottom: local.$ios-spacing-md;
     overflow: visible; // �踹�憭湧��箏�鋆��銝𧢲�
     
     .title {
-      font-size: $ios-font-size-md;
-      font-weight: $ios-font-weight-semibold;
-      color: $ios-text-primary;
+      font-size: local.$ios-font-size-md;
+      font-weight: local.$ios-font-weight-semibold;
+      color: local.$ios-text-primary;
     }
     .hint {
-      font-size: $ios-font-size-xs;
-      color: $ios-text-secondary;
+      font-size: local.$ios-font-size-xs;
+      color: local.$ios-text-secondary;
     }
-    // 撣��靚�㟲嚗𡁏�蝝X��曉銁���蝥扳��唾器嚗峕芋撘誩��W銁�嗅椰靘�
+    // 撣��靚�㟲嚗𡁏�蝝X��曉銁���蝥扳��唾器嚗峕芋撘誩��W銁�嗅椰嚙?
     .scale-switch { margin-left: 0; }
     .mode-switch { order: 3; margin-left: 8px; }
     .search-box { order: 4; margin-left: auto; position: relative; }
-    // �条鸌憭湧�銝剔��𦦵揣撱箄悅銝𧢲�銝箸�瘚桀�嚗䔶��䭾旿��﹝瘚�
+    // �条鸌憭湧�銝剔��𦦵揣撱箄悅銝𧢲�銝箸�瘚桀�嚗䔶��䭾旿��﹝嚙?
     .search-box {
       .suggestion-panel {
         position: absolute;
@@ -221,18 +221,18 @@
 
 .section-filters {
   display: flex;
-  gap: $ios-spacing-md;
+  gap: local.$ios-spacing-md;
   flex-wrap: wrap;
   align-items: center;
-  overflow: visible; // �踹��𧢲踎蝑偦�匧躹�𦦵揣撱箄悅鋡怨���
+  overflow: visible; // �踹��𧢲踎蝑偦�匧躹�𦦵揣撱箄悅鋡怨�嚙?
   
   .custom-select {
-    padding: $ios-spacing-sm $ios-spacing-md;
-    border: 1px solid $ios-border;
-    border-radius: $ios-radius-md;
-    background-color: $ios-background;
-    font-size: $ios-font-size-sm;
-    color: $ios-text-primary;
+    padding: local.$ios-spacing-sm local.$ios-spacing-md;
+    border: 1px solid local.$ios-border;
+    border-radius: local.$ios-radius-md;
+    background-color: local.$ios-background;
+    font-size: local.$ios-font-size-sm;
+    color: local.$ios-text-primary;
     cursor: pointer;
     transition: all 0.2s ease;
     min-width: 140px;
@@ -240,7 +240,7 @@
 
   .search-box {
     margin-right: 8px;
-    position: relative; // 雿靝蛹銝𧢲�摰帋�����
+    position: relative; // 雿靝蛹銝𧢲�摰帋���蕭?
     .input-search {
       width: 260px;
       padding: 8px 12px;
@@ -290,7 +290,7 @@
   }
 }
 
-// 憿寧𤌍�∠�銝𡒊��踵甅撘�
+// 憿寧𤌍�∠�銝𡒊��踵甅嚙?
 .project-kanban {
   position: relative;
   z-index: 1;
@@ -298,33 +298,33 @@
   // �砍�璅芸�皛𡁜𢆡摰孵膥
   .kanban-scroll {
     overflow-x: auto;
-    padding-bottom: $ios-spacing-md;
+    padding-bottom: local.$ios-spacing-md;
     -webkit-overflow-scrolling: touch;
 
     &::-webkit-scrollbar { height: 6px; }
     &::-webkit-scrollbar-track {
-      background: $ios-background;
-      border-radius: $ios-radius-full;
+      background: local.$ios-background;
+      border-radius: local.$ios-radius-full;
     }
     &::-webkit-scrollbar-thumb {
-      background: $ios-border;
-      border-radius: $ios-radius-full;
+      background: local.$ios-border;
+      border-radius: local.$ios-radius-full;
     }
-    &::-webkit-scrollbar-thumb:hover { background: $ios-text-tertiary; }
+    &::-webkit-scrollbar-thumb:hover { background: local.$ios-text-tertiary; }
 
     .kanban-header, .kanban-body { width: max-content; }
   }
   
-  // �𧢲踎���銵�
+  // �𧢲踎���嚙?
   .kanban-header {
     position: sticky;
     top: 0;
     z-index: 2;
-    background: $ios-card-background;
-    border-bottom: 1px solid $ios-border;
+    background: local.$ios-card-background;
+    border-bottom: 1px solid local.$ios-border;
     display: flex;
-    gap: $ios-spacing-md;
-    margin-bottom: $ios-spacing-md;
+    gap: local.$ios-spacing-md;
+    margin-bottom: local.$ios-spacing-md;
     
     .kanban-column-header {
       flex: 0 0 180px;
@@ -333,25 +333,25 @@
       display: flex;
       justify-content: space-between;
       align-items: center;
-      padding: $ios-spacing-sm $ios-spacing-md;
-      background-color: $ios-background;
-      border-radius: $ios-radius-md;
-      border: 1px solid $ios-border;
+      padding: local.$ios-spacing-sm local.$ios-spacing-md;
+      background-color: local.$ios-background;
+      border-radius: local.$ios-radius-md;
+      border: 1px solid local.$ios-border;
       
       h3 {
-        font-size: $ios-font-size-sm;
-        font-weight: $ios-font-weight-medium;
-        color: $ios-text-primary;
+        font-size: local.$ios-font-size-sm;
+        font-weight: local.$ios-font-weight-medium;
+        color: local.$ios-text-primary;
         margin: 0;
       }
       
       .stage-count {
-        font-size: $ios-font-size-xs;
-        background-color: $ios-primary;
-        color: $ios-background;
+        font-size: local.$ios-font-size-xs;
+        background-color: local.$ios-primary;
+        color: local.$ios-background;
         padding: 2px 8px;
-        border-radius: $ios-radius-full;
-        font-weight: $ios-font-weight-medium;
+        border-radius: local.$ios-radius-full;
+        font-weight: local.$ios-font-weight-medium;
       }
     }
   }
@@ -359,34 +359,34 @@
   // �𧢲踎銝颱���捆
   .kanban-body {
     display: flex;
-    gap: $ios-spacing-md;
+    gap: local.$ios-spacing-md;
     
     .kanban-column {
       flex: 1;
       min-width: 180px;
       max-width: 180px;
       height: 400px;
-      background-color: $ios-background;
-      border-radius: $ios-radius-md;
-      border: 1px solid $ios-border;
-      padding: $ios-spacing-sm;
+      background-color: local.$ios-background;
+      border-radius: local.$ios-radius-md;
+      border: 1px solid local.$ios-border;
+      padding: local.$ios-spacing-sm;
       overflow-y: auto;
       -webkit-overflow-scrolling: touch;
       
       &::-webkit-scrollbar { width: 4px; }
       &::-webkit-scrollbar-track { background: transparent; }
       &::-webkit-scrollbar-thumb {
-        background: $ios-border;
-        border-radius: $ios-radius-full;
+        background: local.$ios-border;
+        border-radius: local.$ios-radius-full;
       }
       
       .project-card {
-        background-color: $ios-card-background;
-        border-radius: $ios-radius-md;
-        padding: $ios-spacing-md;
-        margin-bottom: $ios-spacing-sm;
-        border: 1px solid $ios-border;
-        box-shadow: $ios-shadow-sm;
+        background-color: local.$ios-card-background;
+        border-radius: local.$ios-radius-md;
+        padding: local.$ios-spacing-md;
+        margin-bottom: local.$ios-spacing-sm;
+        border: 1px solid local.$ios-border;
+        box-shadow: local.$ios-shadow-sm;
         transition: all 0.2s ease;
         cursor: pointer;
         user-select: none;
@@ -397,20 +397,20 @@
         }
         
         &:active { transform: translateY(-1px); opacity: 0.98; }
-        &.overdue { border-left: 4px solid $ios-danger; }
-        &.high-urgency { border-left: 4px solid $ios-warning; }
-        &.due-soon { border-left: 4px solid $ios-warning; }
+        &.overdue { border-left: 4px solid local.$ios-danger; }
+        &.high-urgency { border-left: 4px solid local.$ios-warning; }
+        &.due-soon { border-left: 4px solid local.$ios-warning; }
         
         .project-card-header {
           display: flex;
           justify-content: space-between;
           align-items: flex-start;
-          margin-bottom: $ios-spacing-sm;
+          margin-bottom: local.$ios-spacing-sm;
           
           h4 {
-            font-size: $ios-font-size-sm;
-            font-weight: $ios-font-weight-medium;
-            color: $ios-primary;
+            font-size: local.$ios-font-size-sm;
+            font-weight: local.$ios-font-weight-medium;
+            color: local.$ios-primary;
             margin: 0;
             cursor: pointer;
             &:hover { text-decoration: underline; }
@@ -419,25 +419,25 @@
           .project-urgency {
             font-size: 10px;
             padding: 2px 6px;
-            border-radius: $ios-radius-full;
-            font-weight: $ios-font-weight-medium;
+            border-radius: local.$ios-radius-full;
+            font-weight: local.$ios-font-weight-medium;
           }
           
-          .urgency-high { background-color: rgba(239, 68, 68, 0.1); color: $ios-danger; }
-          .urgency-medium { background-color: rgba(255, 149, 0, 0.1); color: $ios-warning; }
-          .urgency-low { background-color: rgba(59, 130, 246, 0.1); color: $ios-info; }
+          .urgency-high { background-color: rgba(239, 68, 68, 0.1); color: local.$ios-danger; }
+          .urgency-medium { background-color: rgba(255, 149, 0, 0.1); color: local.$ios-warning; }
+          .urgency-low { background-color: rgba(59, 130, 246, 0.1); color: local.$ios-info; }
         }
         
         .project-card-content {
-          margin-bottom: $ios-spacing-sm;
+          margin-bottom: local.$ios-spacing-sm;
           
           p {
             font-size: 11px;
-            color: $ios-text-secondary;
+            color: local.$ios-text-secondary;
             margin: 0 0 4px 0;
           }
           
-          .deadline { font-size: 10px; color: $ios-text-tertiary; }
+          .deadline { font-size: 10px; color: local.$ios-text-tertiary; }
         }
         
         .project-card-footer {
@@ -449,13 +449,13 @@
             font-size: 10px;
             padding: 4px 6px;
             border: none;
-            border-radius: $ios-radius-sm;
+            border-radius: local.$ios-radius-sm;
             cursor: pointer;
             transition: all 0.2s ease;
           }
           
-          .btn-view { background-color: $ios-primary; color: $ios-background; }
-          .btn-assign { background-color: $ios-success; color: $ios-background; }
+          .btn-view { background-color: local.$ios-primary; color: local.$ios-background; }
+          .btn-assign { background-color: local.$ios-success; color: local.$ios-background; }
           button:hover { opacity: 0.9; }
         }
         
@@ -467,13 +467,13 @@
         .member-badge {
           font-size: 10px;
           padding: 2px 6px;
-          border-radius: $ios-radius-full;
+          border-radius: local.$ios-radius-full;
           background-color: rgba(59, 130, 246, 0.08);
-          color: $ios-info;
+          color: local.$ios-info;
           &.vip {
             background-color: rgba(124, 58, 237, 0.12);
-            color: $ios-primary;
-            font-weight: $ios-font-weight-semibold;
+            color: local.$ios-primary;
+            font-weight: local.$ios-font-weight-semibold;
           }
         }
       }
@@ -487,13 +487,13 @@
         
         .empty-icon {
           font-size: 2rem;
-          margin-bottom: $ios-spacing-sm;
+          margin-bottom: local.$ios-spacing-sm;
           opacity: 0.3;
         }
         
         p {
-          font-size: $ios-font-size-sm;
-          color: $ios-text-tertiary;
+          font-size: local.$ios-font-size-sm;
+          color: local.$ios-text-tertiary;
           margin: 0;
         }
       }
@@ -503,11 +503,11 @@
 
 /* 憿寧𤌍�烐綉憭抒��瑕� */
 .monitoring-section {
-  background-color: $ios-card-background;
-  border-radius: $ios-radius-lg;
-  padding: $ios-spacing-xl;
-  margin-bottom: $ios-spacing-xl;
-  box-shadow: $ios-shadow-card;
+  background-color: local.$ios-card-background;
+  border-radius: local.$ios-radius-lg;
+  padding: local.$ios-spacing-xl;
+  margin-bottom: local.$ios-spacing-xl;
+  box-shadow: local.$ios-shadow-card;
   position: relative;
   overflow: visible; // ��捂�𦦵揣撱箄悅銝𧢲��X踎銝滩◤鋆��
   
@@ -528,24 +528,24 @@
   .gantt-card { position: relative; z-index: 1; }
 }
 
-/* 敹恍���雿𣈯𢒰�踵甅撘� */
+/* 敹恍���雿𣈯𢒰�踵甅嚙?*/
 .quick-actions-section {
-  background-color: $ios-card-background;
-  border-radius: $ios-radius-lg;
-  padding: $ios-spacing-xl;
-  margin-bottom: $ios-spacing-xl;
-  box-shadow: $ios-shadow-card;
+  background-color: local.$ios-card-background;
+  border-radius: local.$ios-radius-lg;
+  padding: local.$ios-spacing-xl;
+  margin-bottom: local.$ios-spacing-xl;
+  box-shadow: local.$ios-shadow-card;
   
   .quick-actions-grid {
     display: grid;
     grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
-    gap: $ios-spacing-lg;
+    gap: local.$ios-spacing-lg;
     
     .action-card {
-      background: linear-gradient(135deg, $ios-background, #f8f9fa);
-      border-radius: $ios-radius-lg;
-      padding: $ios-spacing-xl;
-      border: 1px solid $ios-border;
+      background: linear-gradient(135deg, local.$ios-background, #f8f9fa);
+      border-radius: local.$ios-radius-lg;
+      padding: local.$ios-spacing-xl;
+      border: 1px solid local.$ios-border;
       text-align: center;
       cursor: pointer;
       transition: all 0.3s ease;
@@ -553,25 +553,25 @@
       &:hover {
         transform: translateY(-3px);
         box-shadow: 0 8px 24px rgba(0, 0, 0, 0.08);
-        border-color: $ios-primary-light;
+        border-color: local.$ios-primary-light;
       }
       
       .action-icon {
         font-size: 2.5rem;
-        margin-bottom: $ios-spacing-md;
+        margin-bottom: local.$ios-spacing-md;
         opacity: 0.8;
       }
       
       h3 {
-        font-size: $ios-font-size-base;
-        font-weight: $ios-font-weight-medium;
-        color: $ios-text-primary;
-        margin: 0 0 $ios-spacing-xs 0;
+        font-size: local.$ios-font-size-base;
+        font-weight: local.$ios-font-weight-medium;
+        color: local.$ios-text-primary;
+        margin: 0 0 local.$ios-spacing-xs 0;
       }
       
       p {
-        font-size: $ios-font-size-sm;
-        color: $ios-text-secondary;
+        font-size: local.$ios-font-size-sm;
+        color: local.$ios-text-secondary;
         margin: 0;
       }
     }
@@ -580,76 +580,76 @@
 
 /* 敺��隞餃𦛚�瑕� */
 .todo-section {
-  background-color: $ios-card-background;
-  border-radius: $ios-radius-lg;
-  padding: $ios-spacing-xl;
-  margin-bottom: $ios-spacing-xl;
-  box-shadow: $ios-shadow-card;
+  background-color: local.$ios-card-background;
+  border-radius: local.$ios-radius-lg;
+  padding: local.$ios-spacing-xl;
+  margin-bottom: local.$ios-spacing-xl;
+  box-shadow: local.$ios-shadow-card;
 }
 
 .todo-list {
   .todo-item {
-    padding: $ios-spacing-lg;
-    border-radius: $ios-radius-md;
-    margin-bottom: $ios-spacing-md;
-    background-color: $ios-background;
-    border: 1px solid $ios-border;
-    transition: $ios-feedback-hover;
+    padding: local.$ios-spacing-lg;
+    border-radius: local.$ios-radius-md;
+    margin-bottom: local.$ios-spacing-md;
+    background-color: local.$ios-background;
+    border: 1px solid local.$ios-border;
+    transition: local.$ios-feedback-hover;
     
     &:last-child { margin-bottom: 0; }
     
-    &.priority-high { border-left: 4px solid $ios-danger; }
-    &.priority-medium { border-left: 4px solid $ios-warning; }
-    &.priority-low { border-left: 4px solid $ios-info; }
+    &.priority-high { border-left: 4px solid local.$ios-danger; }
+    &.priority-medium { border-left: 4px solid local.$ios-warning; }
+    &.priority-low { border-left: 4px solid local.$ios-info; }
     
-    &:hover { transform: translateY(-1px); box-shadow: $ios-shadow-sm; }
+    &:hover { transform: translateY(-1px); box-shadow: local.$ios-shadow-sm; }
     
     .todo-header {
       display: flex;
       justify-content: space-between;
       align-items: center;
-      margin-bottom: $ios-spacing-md;
+      margin-bottom: local.$ios-spacing-md;
       
       h3 {
-        font-size: $ios-font-size-base;
-        font-weight: $ios-font-weight-medium;
-        color: $ios-text-primary;
+        font-size: local.$ios-font-size-base;
+        font-weight: local.$ios-font-weight-medium;
+        color: local.$ios-text-primary;
         margin: 0;
       }
       
       .task-priority {
-        font-size: $ios-font-size-xs;
-        padding: $ios-spacing-xs $ios-spacing-sm;
-        border-radius: $ios-radius-full;
-        font-weight: $ios-font-weight-medium;
+        font-size: local.$ios-font-size-xs;
+        padding: local.$ios-spacing-xs local.$ios-spacing-sm;
+        border-radius: local.$ios-radius-full;
+        font-weight: local.$ios-font-weight-medium;
       }
     }
     
     .todo-info {
-      margin-bottom: $ios-spacing-md;
+      margin-bottom: local.$ios-spacing-md;
       
       p {
-        margin: 0 0 $ios-spacing-xs 0;
-        font-size: $ios-font-size-sm;
-        color: $ios-text-secondary;
+        margin: 0 0 local.$ios-spacing-xs 0;
+        font-size: local.$ios-font-size-sm;
+        color: local.$ios-text-secondary;
       }
       
-      .task-deadline { font-size: $ios-font-size-xs; color: $ios-text-tertiary; }
+      .task-deadline { font-size: local.$ios-font-size-xs; color: local.$ios-text-tertiary; }
     }
     
     .todo-actions {
       .btn-handle {
-        background-color: $ios-primary;
-        color: $ios-background;
+        background-color: local.$ios-primary;
+        color: local.$ios-background;
         border: none;
-        border-radius: $ios-radius-md;
-        padding: $ios-spacing-sm $ios-spacing-lg;
-        font-size: $ios-font-size-sm;
-        font-weight: $ios-font-weight-medium;
+        border-radius: local.$ios-radius-md;
+        padding: local.$ios-spacing-sm local.$ios-spacing-lg;
+        font-size: local.$ios-font-size-sm;
+        font-weight: local.$ios-font-weight-medium;
         cursor: pointer;
-        transition: $ios-feedback-tap;
+        transition: local.$ios-feedback-tap;
         
-        &:hover { background-color: $ios-primary-light; }
+        &:hover { background-color: local.$ios-primary-light; }
       }
     }
   }
@@ -661,9 +661,9 @@
   top: 50%;
   left: 50%;
   transform: translate(-50%, -50%);
-  background-color: $ios-card-background;
-  border-radius: $ios-radius-lg;
-  padding: $ios-spacing-xl;
+  background-color: local.$ios-card-background;
+  border-radius: local.$ios-radius-lg;
+  padding: local.$ios-spacing-xl;
   box-shadow: 0 10px 40px rgba(0, 0, 0, 0.15);
   z-index: 1000;
   min-width: 400px;
@@ -676,23 +676,23 @@
   
   .alert-content {
     h3 {
-      font-size: $ios-font-size-lg;
-      font-weight: $ios-font-weight-semibold;
-      color: $ios-danger;
-      margin: 0 0 $ios-spacing-lg 0;
+      font-size: local.$ios-font-size-lg;
+      font-weight: local.$ios-font-weight-semibold;
+      color: local.$ios-danger;
+      margin: 0 0 local.$ios-spacing-lg 0;
       display: flex;
       align-items: center;
-      gap: $ios-spacing-sm;
+      gap: local.$ios-spacing-sm;
     }
     
     ul {
-      margin: 0 0 $ios-spacing-lg 0;
-      padding-left: $ios-spacing-xl;
+      margin: 0 0 local.$ios-spacing-lg 0;
+      padding-left: local.$ios-spacing-xl;
       
       li {
-        font-size: $ios-font-size-base;
-        color: $ios-text-primary;
-        margin-bottom: $ios-spacing-sm;
+        font-size: local.$ios-font-size-base;
+        color: local.$ios-text-primary;
+        margin-bottom: local.$ios-spacing-sm;
         
         &:last-child { margin-bottom: 0; }
       }
@@ -700,35 +700,35 @@
     
     .alert-actions {
       display: flex;
-      gap: $ios-spacing-md;
+      gap: local.$ios-spacing-md;
       justify-content: flex-end;
       
       .btn-view-all {
-        background-color: $ios-primary;
-        color: $ios-background;
+        background-color: local.$ios-primary;
+        color: local.$ios-background;
         border: none;
-        border-radius: $ios-radius-md;
-        padding: $ios-spacing-sm $ios-spacing-lg;
-        font-size: $ios-font-size-sm;
-        font-weight: $ios-font-weight-medium;
+        border-radius: local.$ios-radius-md;
+        padding: local.$ios-spacing-sm local.$ios-spacing-lg;
+        font-size: local.$ios-font-size-sm;
+        font-weight: local.$ios-font-weight-medium;
         cursor: pointer;
-        transition: $ios-feedback-tap;
+        transition: local.$ios-feedback-tap;
         
-        &:hover { background-color: $ios-primary-light; }
+        &:hover { background-color: local.$ios-primary-light; }
       }
       
       .btn-close {
-        background-color: $ios-text-tertiary;
-        color: $ios-text-primary;
+        background-color: local.$ios-text-tertiary;
+        color: local.$ios-text-primary;
         border: none;
-        border-radius: $ios-radius-md;
-        padding: $ios-spacing-sm $ios-spacing-lg;
-        font-size: $ios-font-size-sm;
-        font-weight: $ios-font-weight-medium;
+        border-radius: local.$ios-radius-md;
+        padding: local.$ios-spacing-sm local.$ios-spacing-lg;
+        font-size: local.$ios-font-size-sm;
+        font-weight: local.$ios-font-weight-medium;
         cursor: pointer;
-        transition: $ios-feedback-tap;
+        transition: local.$ios-feedback-tap;
         
-        &:hover { background-color: $ios-text-secondary; color: $ios-background; }
+        &:hover { background-color: local.$ios-text-secondary; color: local.$ios-background; }
       }
     }
   }
@@ -811,7 +811,7 @@
   }
 }
 
-/* �典��条鸌憭湧�撌亙��∴�蝵烐聢撣��嚗�鉄蝻拇𦆮/�𦦵揣/璅∪���揢嚗� */
+/* �典��条鸌憭湧�撌亙��∴�蝵烐聢撣��嚗�鉄蝻拇𦆮/�𦦵揣/璅∪���揢嚙?*/
 .gantt-header {
   position: relative;
   z-index: 2;
@@ -839,23 +839,23 @@
   .scale-switch {
     margin-left: auto;
     display: inline-flex;
-    border: 1px solid $ios-border;
+    border: 1px solid local.$ios-border;
     border-radius: 8px;
     overflow: hidden;
     button {
       background: #fff;
-      color: $ios-text-secondary;
+      color: local.$ios-text-secondary;
       padding: 6px 10px;
       border: none;
       outline: none;
       cursor: pointer;
-      font-size: $ios-font-size-sm;
-      &:hover { background: $ios-background-secondary; }
+      font-size: local.$ios-font-size-sm;
+      &:hover { background: local.$ios-background-secondary; }
       &.active {
-        background: $ios-primary-light;
+        background: local.$ios-primary-light;
         color: #fff;
       }
-      & + button { border-left: 1px solid $ios-border; }
+      & + button { border-left: 1px solid local.$ios-border; }
     }
   }
 
@@ -863,14 +863,14 @@
     position: relative;
     display: inline-flex;
     align-items: center;
-    background: $ios-background;
-    border: 1px solid $ios-border;
+    background: local.$ios-background;
+    border: 1px solid local.$ios-border;
     border-radius: 999px;
     padding: 2px;
     overflow: hidden;
     box-shadow: 0 1px 2px rgba(0,0,0,.04);
 
-    // 皛穃�撘誯�鈭株���
+    // 皛穃�撘誯�鈭株�嚙?
     &::before {
       content: '';
       position: absolute;
@@ -878,7 +878,7 @@
       left: 2px;
       bottom: 2px;
       width: calc(50% - 2px);
-      background: linear-gradient(180deg, $ios-primary-light 0%, darken($ios-primary-light, 4%) 100%);
+      background: linear-gradient(180deg, local.$ios-primary-light 0%, darken(local.$ios-primary-light, 4%) 100%);
       border-radius: 999px;
       box-shadow: 0 6px 14px rgba(99,102,241,.22);
       transform: translateX(0%);
@@ -893,10 +893,10 @@
       background: transparent;
       border: none;
       outline: none;
-      color: $ios-text-secondary;
+      color: local.$ios-text-secondary;
       padding: 10px 16px 10px 14px;
-      font-size: $ios-font-size-sm;
-      font-weight: $ios-font-weight-semibold;
+      font-size: local.$ios-font-size-sm;
+      font-weight: local.$ios-font-weight-semibold;
       letter-spacing: .2px;
       border-radius: 999px;
       cursor: pointer;
@@ -904,7 +904,7 @@
       display: inline-flex;
       align-items: center;
       gap: 6px;
-      &:hover { color: $ios-text-primary; }
+      &:hover { color: local.$ios-text-primary; }
       &:active { transform: translateY(0.5px); }
       &:focus-visible { box-shadow: 0 0 0 3px rgba(99,102,241,.25); }
       &.active {
@@ -959,9 +959,9 @@
 .workload-summary {
   margin: 12px 0 16px;
   padding: 12px 14px;
-  background: $ios-background;
-  border: 1px solid $ios-border;
-  border-radius: $ios-radius-lg;
+  background: local.$ios-background;
+  border: 1px solid local.$ios-border;
+  border-radius: local.$ios-radius-lg;
   box-shadow: 0 1px 2px rgba(0,0,0,.04);
 
   .summary-header {
@@ -969,26 +969,26 @@
     align-items: center;
     justify-content: space-between;
     margin-bottom: 8px;
-    h3 { font-size: $ios-font-size-md; margin: 0; color: $ios-text-primary; }
+    h3 { font-size: local.$ios-font-size-md; margin: 0; color: local.$ios-text-primary; }
     .summary-actions {
       display: flex;
       align-items: center;
       gap: 8px;
       .dimension-switch {
         display: inline-flex;
-        border: 1px solid $ios-border;
+        border: 1px solid local.$ios-border;
         border-radius: 999px;
         overflow: hidden;
         button {
           background: #fff;
-          color: $ios-text-secondary;
+          color: local.$ios-text-secondary;
           padding: 6px 10px;
           border: none;
           cursor: pointer;
-          font-size: $ios-font-size-sm;
-          &:hover { background: $ios-background-secondary; }
-          &.active { background: $ios-primary-light; color: #fff; }
-          & + button { border-left: 1px solid $ios-border; }
+          font-size: local.$ios-font-size-sm;
+          &:hover { background: local.$ios-background-secondary; }
+          &.active { background: local.$ios-primary-light; color: #fff; }
+          & + button { border-left: 1px solid local.$ios-border; }
         }
       }
     }
@@ -1000,9 +1000,9 @@
   }
 }
 
-// �冽�隞嗆錰撠曇蕭�㰘��𡝗甅撘𧶏�霈拚★�桃��批之�睃��㛖����皛∪㨃���摰�
+// �冽�隞嗆錰撠曇蕭�㰘��𡝗甅撘𧶏�霈拚★�桃��批之�睃��㛖����皛∪㨃���嚙?
 .project-kanban {
-  // 霈拙仍�其�銝颱�摰孵膥雿輻鍂�舐鍂摰賢漲�屸�max-content嚗屸��滢�敹����赤�烐���
+  // 霈拙仍�其�銝颱�摰孵膥雿輻鍂�舐鍂摰賢漲�屸�max-content嚗屸��滢�敹����赤�烐�嚙?
   .kanban-scroll {
     .kanban-header, .kanban-body { width: 100%; }
   }
@@ -1011,7 +1011,7 @@
   .kanban-header {
     display: grid;
     grid-template-columns: repeat(4, minmax(0, 1fr));
-    gap: $ios-spacing-md;
+    gap: local.$ios-spacing-md;
 
     .kanban-column-header {
       // �𡝗��箏�180px嚗��霈貉䌊���
@@ -1024,7 +1024,7 @@
   .kanban-body {
     display: grid;
     grid-template-columns: repeat(4, minmax(0, 1fr));
-    gap: $ios-spacing-md;
+    gap: local.$ios-spacing-md;
 
     .kanban-column {
       // �𡝗��箏�180px嚗��霈貉䌊���
@@ -1364,7 +1364,7 @@
   }
 }
 
-// �滚�撘讛挽霈�
+// �滚�撘讛挽嚙?
 @media (max-width: 768px) {
   .employee-detail-overlay {
     padding: 10px;
@@ -1402,4 +1402,4 @@
       }
     }
   }
-}
+}

+ 1 - 0
src/app/pages/team-leader/ios-theme.scss

@@ -18,6 +18,7 @@ $ios-info: #5AC8FA; // 信息色
 $ios-font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
 $ios-font-size-xs: 12px;
 $ios-font-size-sm: 14px;
+$ios-font-size-md: 16px;  // 添加缺失的md尺寸
 $ios-font-size-base: 16px;
 $ios-font-size-lg: 18px;
 $ios-font-size-xl: 22px;

+ 3 - 3
src/app/services/project.service.ts

@@ -59,7 +59,7 @@ export class ProjectService {
   // 模拟数据 - 实际应用中应从API获取
   private projects: Project[] = [
     {
-      id: '1',
+      id: 'proj-001',
       name: '现代风格客厅设计',
       customerName: '张三',
       customerTags: [
@@ -67,8 +67,8 @@ export class ProjectService {
       ],
       highPriorityNeeds: ['需家具购买建议'],
       status: '进行中',
-      currentStage: '建',
-      stage: '建',
+      currentStage: '订单创建',
+      stage: '订单创建',
       createdAt: new Date('2025-09-01'),
       deadline: new Date('2025-09-15'),
       assigneeId: 'designer1',

+ 281 - 238
src/app/shared/components/complaint-card/complaint-card.scss

@@ -1,103 +1,102 @@
-@use '../../styles/_ios-theme.scss' as *;
-@import '../../../../styles/variables';
+@use '../../styles/_ios-theme.scss' as ios;
 
 :host { display: block; height: 100%; }
 
 .complaint-card {
-  padding: $ios-spacing-md;
-  background: $ios-background;
+  padding: ios.$ios-spacing-md;
+  background: ios.$ios-background;
   border-radius: 12px;
-  border: 1px solid $ios-border;
+  border: 1px solid ios.$ios-border;
 
   // 统计数据概览
   .stats-overview {
-    margin-bottom: $ios-spacing-lg;
+    margin-bottom: ios.$ios-spacing-lg;
     
     h4 {
-      margin: 0 0 $ios-spacing-md 0;
-      font-size: $ios-font-size-lg;
-      font-weight: $ios-font-weight-semibold;
-      color: $ios-text-primary;
+      margin: 0 0 ios.$ios-spacing-md 0;
+      font-size: ios.$ios-font-size-lg;
+      font-weight: ios.$ios-font-weight-semibold;
+      color: ios.$ios-text-primary;
     }
 
     .stats-grid {
       display: grid;
       grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
-      gap: $ios-spacing-md;
+      gap: ios.$ios-spacing-md;
 
       .stat-item {
         text-align: center;
-        padding: $ios-spacing-md;
-        background: $ios-background-secondary;
-        border-radius: $ios-border-radius-md;
-        border: 1px solid $ios-border;
+        padding: ios.$ios-spacing-md;
+        background: ios.$ios-background-secondary;
+        border-radius: ios.$ios-radius-md;
+        border: 1px solid ios.$ios-border;
 
         .stat-value {
-          font-size: $ios-font-size-xl;
-          font-weight: $ios-font-weight-bold;
-          color: $ios-text-primary;
-          margin-bottom: $ios-spacing-xs;
+          font-size: ios.$ios-font-size-xl;
+          font-weight: ios.$ios-font-weight-bold;
+          color: ios.$ios-text-primary;
+          margin-bottom: ios.$ios-spacing-xs;
 
           .time-suffix {
-            font-size: $ios-font-size-sm;
-            color: $ios-text-secondary;
+            font-size: ios.$ios-font-size-sm;
+            color: ios.$ios-text-secondary;
           }
         }
 
         .stat-label {
-          font-size: $ios-font-size-xs;
-          color: $ios-text-secondary;
+          font-size: ios.$ios-font-size-xs;
+          color: ios.$ios-text-secondary;
         }
 
-        &.total .stat-value { color: $ios-primary; }
-        &.pending .stat-value { color: $ios-warning; }
+        &.total .stat-value { color: ios.$ios-primary; }
+        &.pending .stat-value { color: ios.$ios-warning; }
         &.processing .stat-value { color: #1890ff; }
-        &.resolved .stat-value { color: $ios-success; }
-        &.high-priority .stat-value { color: $ios-danger; }
+        &.resolved .stat-value { color: ios.$ios-success; }
+        &.high-priority .stat-value { color: ios.$ios-danger; }
         &.resolution-time .stat-value { color: #722ed1; }
       }
     }
   }
 
   // 优先级统计
-  .priority-stats {
-    margin-bottom: $ios-spacing-lg;
-    padding: $ios-spacing-md;
-    background: $ios-background-secondary;
-    border-radius: $ios-border-radius-md;
-    border: 1px solid $ios-border;
+  .priority-stats.complaint-trends {
+    margin-bottom: ios.$ios-spacing-lg;
+    padding: ios.$ios-spacing-md;
+    background: ios.$ios-background-secondary;
+    border-radius: ios.$ios-radius-md;
+    border: 1px solid ios.$ios-border;
 
     h5 {
-      margin: 0 0 $ios-spacing-md 0;
-      font-size: $ios-font-size-md;
-      font-weight: $ios-font-weight-semibold;
-      color: $ios-text-primary;
+      margin: 0 0 ios.$ios-spacing-md 0;
+      font-size: ios.$ios-font-size-md;
+      font-weight: ios.$ios-font-weight-semibold;
+      color: ios.$ios-text-primary;
     }
 
     .priority-grid {
       display: grid;
       grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
-      gap: $ios-spacing-sm;
+      gap: ios.$ios-spacing-sm;
 
       .priority-item {
         display: flex;
         justify-content: space-between;
         align-items: center;
-        padding: $ios-spacing-sm;
-        background: $ios-background;
-        border-radius: $ios-border-radius-sm;
-        border: 1px solid $ios-border;
+        padding: ios.$ios-spacing-sm;
+        background: ios.$ios-background;
+        border-radius: ios.$ios-radius-sm;
+        border: 1px solid ios.$ios-border;
         border-left-width: 4px;
 
         .priority-label {
-          font-size: $ios-font-size-sm;
-          color: $ios-text-secondary;
+          font-size: ios.$ios-font-size-sm;
+          color: ios.$ios-text-secondary;
         }
 
         .priority-count {
-          font-size: $ios-font-size-md;
-          font-weight: $ios-font-weight-semibold;
-          color: $ios-text-primary;
+          font-size: ios.$ios-font-size-md;
+          font-weight: ios.$ios-font-weight-semibold;
+          color: ios.$ios-text-primary;
         }
       }
     }
@@ -105,42 +104,42 @@
 
   // 类型统计
   .type-stats {
-    margin-bottom: $ios-spacing-lg;
-    padding: $ios-spacing-md;
-    background: $ios-background-secondary;
-    border-radius: $ios-border-radius-md;
-    border: 1px solid $ios-border;
+    margin-bottom: ios.$ios-spacing-lg;
+    padding: ios.$ios-spacing-md;
+    background: ios.$ios-background-secondary;
+    border-radius: ios.$ios-radius-md;
+    border: 1px solid ios.$ios-border;
 
     h5 {
-      margin: 0 0 $ios-spacing-md 0;
-      font-size: $ios-font-size-md;
-      font-weight: $ios-font-weight-semibold;
-      color: $ios-text-primary;
+      margin: 0 0 ios.$ios-spacing-md 0;
+      font-size: ios.$ios-font-size-md;
+      font-weight: ios.$ios-font-weight-semibold;
+      color: ios.$ios-text-primary;
     }
 
     .type-grid {
       display: grid;
       grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
-      gap: $ios-spacing-sm;
+      gap: ios.$ios-spacing-sm;
 
       .type-item {
         display: flex;
         justify-content: space-between;
         align-items: center;
-        padding: $ios-spacing-sm;
-        background: $ios-background;
-        border-radius: $ios-border-radius-sm;
-        border: 1px solid $ios-border;
+        padding: ios.$ios-spacing-sm;
+        background: ios.$ios-background;
+        border-radius: ios.$ios-radius-sm;
+        border: 1px solid ios.$ios-border;
 
         .type-label {
-          font-size: $ios-font-size-xs;
-          color: $ios-text-secondary;
+          font-size: ios.$ios-font-size-xs;
+          color: ios.$ios-text-secondary;
         }
 
         .type-count {
-          font-size: $ios-font-size-sm;
-          font-weight: $ios-font-weight-semibold;
-          color: $ios-primary;
+          font-size: ios.$ios-font-size-sm;
+          font-weight: ios.$ios-font-weight-semibold;
+          color: ios.$ios-primary;
         }
       }
     }
@@ -148,42 +147,42 @@
 
   // 筛选区域
   .filter-section {
-    margin-bottom: $ios-spacing-lg;
-    padding: $ios-spacing-md;
-    background: $ios-background-secondary;
-    border-radius: $ios-border-radius-md;
-    border: 1px solid $ios-border;
+    margin-bottom: ios.$ios-spacing-lg;
+    padding: ios.$ios-spacing-md;
+    background: ios.$ios-background-secondary;
+    border-radius: ios.$ios-radius-md;
+    border: 1px solid ios.$ios-border;
 
     .search-row {
-      margin-bottom: $ios-spacing-md;
+      margin-bottom: ios.$ios-spacing-md;
 
       .search-group {
         display: flex;
         align-items: center;
-        gap: $ios-spacing-sm;
+        gap: ios.$ios-spacing-sm;
 
         label {
-          font-size: $ios-font-size-sm;
-          color: $ios-text-secondary;
+          font-size: ios.$ios-font-size-sm;
+          color: ios.$ios-text-secondary;
           white-space: nowrap;
         }
 
         .search-input {
           flex: 1;
-          padding: $ios-spacing-sm;
-          border: 1px solid $ios-border;
-          border-radius: $ios-border-radius-sm;
-          background: $ios-background;
-          color: $ios-text-primary;
-          font-size: $ios-font-size-sm;
+          padding: ios.$ios-spacing-sm;
+          border: 1px solid ios.$ios-border;
+          border-radius: ios.$ios-radius-sm;
+          background: ios.$ios-background;
+          color: ios.$ios-text-primary;
+          font-size: ios.$ios-font-size-sm;
 
           &:focus {
             outline: none;
-            border-color: $ios-primary;
+            border-color: ios.$ios-primary;
           }
 
           &::placeholder {
-            color: $ios-text-secondary;
+            color: ios.$ios-text-secondary;
           }
         }
       }
@@ -192,8 +191,8 @@
     .filter-row {
       display: flex;
       flex-wrap: wrap;
-      gap: $ios-spacing-md;
-      margin-bottom: $ios-spacing-md;
+      gap: ios.$ios-spacing-md;
+      margin-bottom: ios.$ios-spacing-md;
 
       &:last-child {
         margin-bottom: 0;
@@ -202,41 +201,41 @@
       .filter-group {
         display: flex;
         align-items: center;
-        gap: $ios-spacing-sm;
+        gap: ios.$ios-spacing-sm;
 
         label {
-          font-size: $ios-font-size-sm;
-          color: $ios-text-secondary;
+          font-size: ios.$ios-font-size-sm;
+          color: ios.$ios-text-secondary;
           white-space: nowrap;
         }
 
         .filter-buttons {
           display: flex;
-          gap: $ios-spacing-xs;
+          gap: ios.$ios-spacing-xs;
 
           .filter-btn {
-            padding: $ios-spacing-xs $ios-spacing-sm;
-            border: 1px solid $ios-border;
-            background: $ios-background;
-            color: $ios-text-secondary;
-            border-radius: $ios-border-radius-sm;
-            font-size: $ios-font-size-xs;
+            padding: ios.$ios-spacing-xs ios.$ios-spacing-sm;
+            border: 1px solid ios.$ios-border;
+            background: ios.$ios-background;
+            color: ios.$ios-text-secondary;
+            border-radius: ios.$ios-radius-sm;
+            font-size: ios.$ios-font-size-xs;
             cursor: pointer;
             transition: all 0.2s ease;
 
             &:hover {
-              background: $ios-background-secondary;
+              background: ios.$ios-background-secondary;
             }
 
             &.active {
-              background: $ios-primary;
+              background: ios.$ios-primary;
               color: white;
-              border-color: $ios-primary;
+              border-color: ios.$ios-primary;
             }
 
             &.pending.active {
-              background: $ios-warning;
-              border-color: $ios-warning;
+              background: ios.$ios-warning;
+              border-color: ios.$ios-warning;
             }
 
             &.processing.active {
@@ -245,24 +244,24 @@
             }
 
             &.resolved.active {
-              background: $ios-success;
-              border-color: $ios-success;
+              background: ios.$ios-success;
+              border-color: ios.$ios-success;
             }
           }
         }
 
         .filter-select {
-          padding: $ios-spacing-xs $ios-spacing-sm;
-          border: 1px solid $ios-border;
-          border-radius: $ios-border-radius-sm;
-          background: $ios-background;
-          color: $ios-text-primary;
-          font-size: $ios-font-size-xs;
+          padding: ios.$ios-spacing-xs ios.$ios-spacing-sm;
+          border: 1px solid ios.$ios-border;
+          border-radius: ios.$ios-radius-sm;
+          background: ios.$ios-background;
+          color: ios.$ios-text-primary;
+          font-size: ios.$ios-font-size-xs;
           min-width: 120px;
 
           &:focus {
             outline: none;
-            border-color: $ios-primary;
+            border-color: ios.$ios-primary;
           }
         }
       }
@@ -273,11 +272,13 @@
   .complaints-list {
     .list-body {
       .complaint-item {
-        padding: $ios-spacing-md;
-        margin-bottom: $ios-spacing-md;
-        background: $ios-background;
-        border: 1px solid $ios-border;
-        border-radius: $ios-border-radius-md;
+        display: flex;
+        align-items: center;
+        gap: ios.$ios-spacing-md;
+        padding: ios.$ios-spacing-md;
+        background: ios.$ios-background;
+        border: 1px solid ios.$ios-border;
+        border-radius: ios.$ios-radius-md;
         transition: all 0.2s ease;
 
         &:hover {
@@ -289,15 +290,15 @@
         }
 
         &.overdue {
-          border-left: 4px solid $ios-danger;
-          background: rgba($ios-danger, 0.02);
+          border-left: 4px solid ios.$ios-danger;
+          background: rgba(ios.$ios-danger, 0.02);
         }
 
         .complaint-header {
           display: flex;
           justify-content: space-between;
           align-items: flex-start;
-          margin-bottom: $ios-spacing-md;
+          margin-bottom: ios.$ios-spacing-md;
 
           .complaint-info {
             flex: 1;
@@ -305,161 +306,202 @@
             .complaint-title {
               display: flex;
               align-items: center;
-              gap: $ios-spacing-sm;
-              margin-bottom: $ios-spacing-xs;
+              gap: ios.$ios-spacing-sm;
+              margin-bottom: ios.$ios-spacing-xs;
 
               .type-tag {
-                padding: $ios-spacing-xs $ios-spacing-sm;
-                background: $ios-primary;
+                padding: ios.$ios-spacing-xs ios.$ios-spacing-sm;
+                background: ios.$ios-primary;
                 color: white;
-                border-radius: $ios-border-radius-sm;
-                font-size: $ios-font-size-xs;
+                border-radius: ios.$ios-radius-sm;
+                font-size: ios.$ios-font-size-xs;
               }
 
               .customer-name {
-                font-size: $ios-font-size-md;
-                font-weight: $ios-font-weight-semibold;
-                color: $ios-text-primary;
+                font-size: ios.$ios-font-size-md;
+                font-weight: ios.$ios-font-weight-semibold;
+                color: ios.$ios-text-primary;
               }
             }
 
             .priority-badge {
               display: inline-block;
-              padding: $ios-spacing-xs $ios-spacing-sm;
+              padding: ios.$ios-spacing-xs ios.$ios-spacing-sm;
               color: white;
-              border-radius: $ios-border-radius-sm;
-              font-size: $ios-font-size-xs;
-              font-weight: $ios-font-weight-semibold;
+              border-radius: ios.$ios-radius-sm;
+              font-size: ios.$ios-font-size-xs;
+              font-weight: ios.$ios-font-weight-semibold;
             }
           }
 
           .complaint-meta {
             display: flex;
             align-items: center;
-            gap: $ios-spacing-sm;
-
-            .status-badge {
-              padding: $ios-spacing-xs $ios-spacing-sm;
-              border-radius: $ios-border-radius-sm;
-              font-size: $ios-font-size-xs;
-              font-weight: $ios-font-weight-semibold;
-
-              &.pending {
-                background: rgba($ios-warning, 0.1);
-                color: $ios-warning;
-              }
-
-              &.processing {
-                background: rgba(#1890ff, 0.1);
-                color: #1890ff;
-              }
+            gap: ios.$ios-spacing-sm;
+            margin-bottom: ios.$ios-spacing-xs;
 
-              &.resolved {
-                background: rgba($ios-success, 0.1);
-                color: $ios-success;
-              }
+            .complaint-id {
+              padding: ios.$ios-spacing-xs ios.$ios-spacing-sm;
+              background: ios.$ios-primary;
+              color: white;
+              border-radius: ios.$ios-radius-sm;
+              font-size: ios.$ios-font-size-xs;
             }
 
-            .overdue-badge {
-              padding: $ios-spacing-xs $ios-spacing-sm;
-              background: rgba($ios-danger, 0.1);
-              color: $ios-danger;
-              border-radius: $ios-border-radius-sm;
-              font-size: $ios-font-size-xs;
-              font-weight: $ios-font-weight-semibold;
+            .complaint-title {
+              font-size: ios.$ios-font-size-md;
+              font-weight: ios.$ios-font-weight-semibold;
+              color: ios.$ios-text-primary;
             }
           }
-        }
-
-        .complaint-content {
-          margin-bottom: $ios-spacing-md;
 
-          .description {
-            margin: 0 0 $ios-spacing-sm 0;
-            color: $ios-text-primary;
-            line-height: 1.5;
-          }
+          .complaint-status {
+            padding: ios.$ios-spacing-xs ios.$ios-spacing-sm;
+            color: white;
+            border-radius: ios.$ios-radius-sm;
+            font-size: ios.$ios-font-size-xs;
+            font-weight: ios.$ios-font-weight-semibold;
 
-          .complaint-images {
-            display: flex;
-            gap: $ios-spacing-sm;
-            flex-wrap: wrap;
-
-            .complaint-image {
-              width: 80px;
-              height: 80px;
-              object-fit: cover;
-              border-radius: $ios-border-radius-sm;
-              border: 1px solid $ios-border;
+            &.pending {
+              background: rgba(ios.$ios-warning, 0.1);
+              color: ios.$ios-warning;
             }
-          }
-        }
 
-        .complaint-footer {
-          .time-info {
-            display: flex;
-            flex-wrap: wrap;
-            gap: $ios-spacing-md;
-            margin-bottom: $ios-spacing-sm;
-
-            .submitted-time,
-            .days-progress,
-            .resolved-time {
-              font-size: $ios-font-size-xs;
-              color: $ios-text-secondary;
+            &.processing {
+              background: rgba(ios.$ios-info, 0.1);
+              color: ios.$ios-info;
             }
 
-            .days-progress {
-              color: $ios-primary;
-              font-weight: $ios-font-weight-semibold;
+            &.resolved {
+              background: rgba(ios.$ios-success, 0.1);
+              color: ios.$ios-success;
             }
 
-            .resolved-time {
-              color: $ios-success;
+            &.urgent {
+              padding: ios.$ios-spacing-xs ios.$ios-spacing-sm;
+              background: rgba(ios.$ios-danger, 0.1);
+              color: ios.$ios-danger;
+              border-radius: ios.$ios-radius-sm;
+              font-size: ios.$ios-font-size-xs;
+              font-weight: ios.$ios-font-weight-semibold;
             }
           }
 
-          .handler-response {
-            padding: $ios-spacing-sm;
-            background: rgba($ios-primary, 0.05);
-            border-radius: $ios-border-radius-sm;
-            border-left: 3px solid $ios-primary;
-            margin-bottom: $ios-spacing-sm;
+          .complaint-content {
+            margin-bottom: ios.$ios-spacing-md;
 
-            strong {
-              color: $ios-primary;
-              font-size: $ios-font-size-sm;
+            .complaint-description {
+              margin: 0 0 ios.$ios-spacing-sm 0;
+              color: ios.$ios-text-primary;
             }
 
-            .response-text {
-              margin: $ios-spacing-xs 0;
-              color: $ios-text-secondary;
-              font-size: $ios-font-size-sm;
-              line-height: 1.4;
+            .complaint-details {
+              display: flex;
+              flex-direction: column;
+              gap: ios.$ios-spacing-sm;
             }
 
-            .handler-name {
-              font-size: $ios-font-size-xs;
-              color: $ios-text-secondary;
+            .detail-item {
+              display: flex;
+              justify-content: space-between;
+              padding: ios.$ios-spacing-xs;
+              border-radius: ios.$ios-radius-sm;
+              border: 1px solid ios.$ios-border;
+
+              .detail-label {
+                font-weight: 500;
+              }
+
+              .detail-value {
+                display: flex;
+                align-items: center;
+                gap: ios.$ios-spacing-md;
+                margin-bottom: ios.$ios-spacing-sm;
+
+                .customer-info {
+                  display: flex;
+                  align-items: center;
+                  gap: ios.$ios-spacing-xs;
+
+                  .customer-name {
+                    font-size: ios.$ios-font-size-xs;
+                    color: ios.$ios-text-secondary;
+                  }
+
+                  .customer-id {
+                    color: ios.$ios-primary;
+                    font-weight: ios.$ios-font-weight-semibold;
+                  }
+
+                  .customer-level {
+                    color: ios.$ios-success;
+                  }
+                }
+
+                .complaint-actions {
+                  padding: ios.$ios-spacing-sm;
+                  background: rgba(ios.$ios-primary, 0.05);
+                  border-radius: ios.$ios-radius-sm;
+                  border-left: 3px solid ios.$ios-primary;
+                  margin-bottom: ios.$ios-spacing-sm;
+
+                  .action-title {
+                    color: ios.$ios-primary;
+                    font-size: ios.$ios-font-size-sm;
+                  }
+
+                  .action-description {
+                    margin: ios.$ios-spacing-xs 0;
+                    color: ios.$ios-text-secondary;
+                    font-size: ios.$ios-font-size-sm;
+                  }
+
+                  .action-timestamp {
+                    font-size: ios.$ios-font-size-xs;
+                    color: ios.$ios-text-secondary;
+                  }
+                }
+
+                .resolution-note {
+                  padding: ios.$ios-spacing-sm;
+                  background: rgba(ios.$ios-success, 0.05);
+                  border-radius: ios.$ios-radius-sm;
+                  border-left: 3px solid ios.$ios-success;
+
+                  .resolution-title {
+                    color: ios.$ios-success;
+                    font-size: ios.$ios-font-size-sm;
+                  }
+
+                  .resolution-content {
+                    margin: ios.$ios-spacing-xs 0 0 0;
+                    color: ios.$ios-text-secondary;
+                    font-size: ios.$ios-font-size-sm;
+                  }
+                }
+              }
             }
           }
 
-          .solution-section {
-            padding: $ios-spacing-sm;
-            background: rgba($ios-success, 0.05);
-            border-radius: $ios-border-radius-sm;
-            border-left: 3px solid $ios-success;
+          .complaint-footer {
+            text-align: center;
+            padding: ios.$ios-spacing-xl;
+            color: ios.$ios-text-secondary;
 
-            strong {
-              color: $ios-success;
-              font-size: $ios-font-size-sm;
+            .no-complaints-message {
+              margin-bottom: ios.$ios-spacing-md;
             }
 
-            .solution-text {
-              margin: $ios-spacing-xs 0 0 0;
-              color: $ios-text-secondary;
-              font-size: $ios-font-size-sm;
-              line-height: 1.4;
+            .no-complaints-title {
+              font-size: ios.$ios-font-size-lg;
+              font-weight: ios.$ios-font-weight-semibold;
+              color: ios.$ios-text-primary;
+              margin-bottom: ios.$ios-spacing-sm;
+            }
+
+            .no-complaints-description {
+              font-size: ios.$ios-font-size-sm;
+              color: ios.$ios-text-secondary;
             }
           }
         }
@@ -468,32 +510,33 @@
 
     .empty-state {
       text-align: center;
-      padding: $ios-spacing-xl;
-      color: $ios-text-secondary;
+      padding: ios.$ios-spacing-xl;
+      color: ios.$ios-text-secondary;
 
       .empty-icon {
         font-size: 48px;
-        margin-bottom: $ios-spacing-md;
+        margin-bottom: ios.$ios-spacing-md;
       }
 
       .empty-title {
-        font-size: $ios-font-size-lg;
-        font-weight: $ios-font-weight-semibold;
-        color: $ios-text-primary;
-        margin-bottom: $ios-spacing-sm;
+        font-size: ios.$ios-font-size-lg;
+        font-weight: ios.$ios-font-weight-semibold;
+        color: ios.$ios-text-primary;
+        margin-bottom: ios.$ios-spacing-sm;
       }
 
       .empty-desc {
-        font-size: $ios-font-size-sm;
-        color: $ios-text-secondary;
+        font-size: ios.$ios-font-size-sm;
+        color: ios.$ios-text-secondary;
       }
     }
   }
 
   // 响应式设计
   @media (max-width: 768px) {
-    .stats-overview .stats-grid {
+    .stats-grid {
       grid-template-columns: repeat(2, 1fr);
+      gap: ios.$ios-spacing-sm;
     }
 
     .priority-stats .priority-grid,
@@ -524,7 +567,7 @@
 
     .complaints-list .complaint-item .complaint-header {
       flex-direction: column;
-      gap: $ios-spacing-sm;
+      gap: ios.$ios-spacing-sm;
     }
   }
 }

+ 45 - 2
src/app/shared/components/consultation-order-panel/consultation-order-panel.component.html

@@ -124,6 +124,28 @@
               </div>
             </div>
 
+            <div class="form-row">
+              <div class="form-group">
+                <label for="budget">预算 *</label>
+                <input type="number" id="budget" formControlName="budget" placeholder="请输入预算金额">
+              </div>
+              <div class="form-group">
+                <label for="area">面积 *</label>
+                <input type="number" id="area" formControlName="area" placeholder="请输入面积(平方米)">
+              </div>
+            </div>
+
+            <div class="form-row">
+              <div class="form-group">
+                <label for="smallImageTime">小图时间</label>
+                <input type="date" id="smallImageTime" formControlName="smallImageTime">
+              </div>
+              <div class="form-group">
+                <label for="largeImageTime">大图时间</label>
+                <input type="date" id="largeImageTime" formControlName="largeImageTime">
+              </div>
+            </div>
+
             <!-- 详细需求 -->
             <div class="form-row">
               <div class="form-group">
@@ -218,7 +240,8 @@
     <button 
       class="submit-btn" 
       (click)="submitForm()"
-      [disabled]="isSubmitting || !customerForm.valid || !requirementForm.valid"
+      [disabled]="isSubmitting || !isFormValid()"
+      [class.disabled]="isSubmitting || !isFormValid()"
     >
       @if (isSubmitting) {
         提交中...
@@ -226,5 +249,25 @@
         创建项目
       }
     </button>
+    
+    <!-- 表单验证提示 -->
+    @if (!isFormValid()) {
+      <div class="validation-hint">
+        <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
+          <circle cx="12" cy="12" r="10"></circle>
+          <line x1="12" y1="8" x2="12" y2="12"></line>
+          <line x1="12" y1="16" x2="12.01" y2="16"></line>
+        </svg>
+        请填写完整的项目信息
+      </div>
+    }
   </div>
-</div>
+</div>
+
+<!-- 团队分配弹窗 -->
+<app-team-assignment-modal
+  [isVisible]="showTeamAssignmentModal"
+  (closeModal)="closeTeamAssignmentModal()"
+  (confirmAssignment)="confirmTeamAssignment($event)">
+</app-team-assignment-modal>
+

+ 40 - 5
src/app/shared/components/consultation-order-panel/consultation-order-panel.component.scss

@@ -1,3 +1,5 @@
+@use 'sass:color';
+
 // iOS风格变量定义
 $ios-primary: #007AFF;
 $ios-primary-dark: #0062CC;
@@ -218,7 +220,7 @@ $ios-spacing-xl: 32px;
         transition: $ios-transition;
 
         &:hover {
-          background: darken($ios-danger, 10%);
+          background: color.adjust($ios-danger, $lightness: -10%);
           transform: translateY(-1px);
         }
       }
@@ -497,7 +499,7 @@ $ios-spacing-xl: 32px;
             transition: $ios-transition;
 
             &:hover {
-              background: darken($ios-secondary, 10%);
+              background: color.adjust($ios-secondary, $lightness: -10%);
               transform: translateY(-1px);
             }
 
@@ -530,22 +532,55 @@ $ios-spacing-xl: 32px;
       transition: $ios-transition;
       box-shadow: $ios-shadow-sm;
 
-      &:hover {
+      &:hover:not(:disabled) {
         transform: translateY(-2px);
         box-shadow: $ios-shadow-md;
+        background: linear-gradient(135deg, #0056CC 0%, #004499 100%);
       }
 
-      &:active {
+      &:active:not(:disabled) {
         transform: translateY(0);
         box-shadow: $ios-shadow-sm;
       }
 
       &:disabled {
-        background: $ios-text-tertiary;
+        background: linear-gradient(135deg, $ios-text-tertiary 0%, #B0B0B0 100%);
+        color: #FFFFFF;
         cursor: not-allowed;
         transform: none;
         box-shadow: none;
+        opacity: 0.6;
       }
+      
+      // 表单有效时的强调样式
+      &:not(:disabled) {
+        background: linear-gradient(135deg, $ios-success 0%, #28A745 100%);
+        box-shadow: 0 4px 15px rgba(52, 199, 89, 0.3);
+        
+        &:hover {
+          background: linear-gradient(135deg, #28A745 0%, #1E7E34 100%);
+          box-shadow: 0 6px 20px rgba(52, 199, 89, 0.4);
+        }
+      }
+    }
+  }
+
+  // 表单验证提示
+  .validation-hint {
+    display: flex;
+    align-items: center;
+    gap: $ios-spacing-sm;
+    margin-top: $ios-spacing-sm;
+    padding: $ios-spacing-sm $ios-spacing-md;
+    background: rgba($ios-warning, 0.1);
+    border: 1px solid rgba($ios-warning, 0.3);
+    border-radius: $ios-radius;
+    color: $ios-warning;
+    font-size: 14px;
+    font-weight: 500;
+    
+    svg {
+      flex-shrink: 0;
     }
   }
 

+ 49 - 12
src/app/shared/components/consultation-order-panel/consultation-order-panel.component.ts

@@ -1,6 +1,8 @@
-import { Component, EventEmitter, Output } from '@angular/core';
+import { Component, EventEmitter, OnInit, Output } from '@angular/core';
+import { FormBuilder, FormGroup, Validators, ReactiveFormsModule } from '@angular/forms';
 import { CommonModule } from '@angular/common';
-import { FormsModule, ReactiveFormsModule, FormBuilder, FormGroup, Validators } from '@angular/forms';
+import { TeamAssignmentModalComponent, Designer } from '../team-assignment-modal/team-assignment-modal.component';
+import { FormsModule } from '@angular/forms';
 import { MatChipsModule } from '@angular/material/chips';
 import { MatIconModule } from '@angular/material/icon';
 
@@ -24,16 +26,18 @@ interface Customer {
   standalone: true,
   imports: [
     CommonModule,
-    FormsModule,
     ReactiveFormsModule,
+    FormsModule,
     MatChipsModule,
-    MatIconModule
+    MatIconModule,
+    TeamAssignmentModalComponent
   ],
   templateUrl: './consultation-order-panel.component.html',
   styleUrls: ['./consultation-order-panel.component.scss']
 })
 export class ConsultationOrderPanelComponent {
   @Output() orderCreated = new EventEmitter<any>();
+  @Output() projectCreated = new EventEmitter<any>(); // 新增项目创建成功事件
 
   // 搜索客户关键词
   searchKeyword = '';
@@ -50,6 +54,10 @@ export class ConsultationOrderPanelComponent {
   requirementForm: FormGroup;
   // 客户表单
   customerForm: FormGroup;
+  
+  // 团队分配弹窗相关
+  showTeamAssignmentModal = false;
+  selectedDesigner: Designer | null = null;
 
   // 样式选项
   styleOptions = [
@@ -83,6 +91,8 @@ export class ConsultationOrderPanelComponent {
       projectGroup: [''],
       budget: ['', Validators.required],
       area: ['', [Validators.required, Validators.min(1)]],
+      smallImageTime: [''],
+      largeImageTime: [''],
       houseType: [''],
       floor: ['', Validators.min(1)],
       preferredDesigner: [''],
@@ -177,6 +187,11 @@ export class ConsultationOrderPanelComponent {
     }
   }
 
+  // 检查表单是否有效
+  isFormValid(): boolean {
+    return this.customerForm.valid && this.requirementForm.valid;
+  }
+
   // 提交表单
   submitForm() {
     if (this.customerForm.valid && this.requirementForm.valid) {
@@ -193,15 +208,37 @@ export class ConsultationOrderPanelComponent {
       setTimeout(() => {
         this.isSubmitting = false;
         this.orderCreated.emit(formData);
-        
-        // 重置表单
-        this.customerForm.reset({
-          customerType: '新客户'
-        });
-        this.requirementForm.reset();
-        this.preferenceTags = [];
-        this.selectedCustomer = null;
       }, 1000);
     }
   }
+
+  // 关闭团队分配弹窗
+  closeTeamAssignmentModal() {
+    this.showTeamAssignmentModal = false;
+  }
+
+  // 确认团队分配
+  confirmTeamAssignment(designer: Designer) {
+    this.selectedDesigner = designer;
+    this.showTeamAssignmentModal = false;
+    
+    // 发出项目创建成功事件
+    const projectData = {
+      customerInfo: this.customerForm.value,
+      requirementInfo: this.requirementForm.value,
+      preferenceTags: this.preferenceTags,
+      assignedDesigner: designer,
+      createdAt: new Date()
+    };
+    
+    this.projectCreated.emit(projectData);
+    
+    // 重置表单
+    this.customerForm.reset({
+      customerType: '新客户'
+    });
+    this.requirementForm.reset();
+    this.preferenceTags = [];
+    this.selectedCustomer = null;
+  }
 }

+ 120 - 287
src/app/shared/components/customer-review-card/customer-review-card.scss

@@ -1,109 +1,108 @@
-@use '../../styles/_ios-theme.scss' as *;
+@use '../../styles/_ios-theme.scss' as ios;
+@use '../../../../styles/variables' as vars;
 
 :host { display: block; height: 100%; }
 
-@import '../../../../styles/variables';
-
 .customer-review-card {
-  padding: $ios-spacing-md;
-  background: $ios-background;
+  padding: ios.$ios-spacing-md;
+  background: ios.$ios-background;
   border-radius: 12px;
-  border: 1px solid $ios-border;
+  border: 1px solid ios.$ios-border;
 
   // 统计数据概览
   .stats-overview {
-    margin-bottom: $ios-spacing-lg;
+    margin-bottom: ios.$ios-spacing-lg;
     
     h4 {
-      margin: 0 0 $ios-spacing-md 0;
-      font-size: $ios-font-size-lg;
-      font-weight: $ios-font-weight-semibold;
-      color: $ios-text-primary;
+      margin: 0 0 ios.$ios-spacing-md 0;
+      font-size: ios.$ios-font-size-lg;
+      font-weight: ios.$ios-font-weight-semibold;
+      color: ios.$ios-text-primary;
     }
 
     .stats-grid {
       display: grid;
       grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
-      gap: $ios-spacing-md;
+      gap: ios.$ios-spacing-md;
 
       .stat-item {
         text-align: center;
-        padding: $ios-spacing-md;
-        background: $ios-background-secondary;
-        border-radius: $ios-border-radius-md;
-        border: 1px solid $ios-border;
+        padding: ios.$ios-spacing-md;
+        background: ios.$ios-background-secondary;
+        border-radius: vars.$ios-border-radius-md;
+        border: 1px solid ios.$ios-border;
 
         .stat-value {
-          font-size: $ios-font-size-xl;
-          font-weight: $ios-font-weight-bold;
-          color: $ios-text-primary;
-          margin-bottom: $ios-spacing-xs;
+          font-size: ios.$ios-font-size-xl;
+          font-weight: ios.$ios-font-weight-bold;
+          color: ios.$ios-text-primary;
+          margin-bottom: ios.$ios-spacing-xs;
 
           .score-suffix {
-            font-size: $ios-font-size-sm;
-            color: $ios-text-secondary;
+            font-size: ios.$ios-font-size-sm;
+            color: ios.$ios-text-secondary;
           }
         }
 
         .stat-label {
-          font-size: $ios-font-size-xs;
-          color: $ios-text-secondary;
-          margin-bottom: $ios-spacing-xs;
+          font-size: ios.$ios-font-size-xs;
+          color: ios.$ios-text-secondary;
+          margin-bottom: ios.$ios-spacing-xs;
         }
 
         .star-display {
           .star {
             color: #FFD700;
-            font-size: $ios-font-size-sm;
+            font-size: ios.$ios-font-size-sm;
           }
         }
 
-        &.total .stat-value { color: $ios-primary; }
+        &.total .stat-value { color: ios.$ios-primary; }
         &.score .stat-value { color: #FF6B35; }
-        &.satisfied .stat-value { color: $ios-success; }
-        &.pending .stat-value { color: $ios-warning; }
+        &.satisfied .stat-value { color: ios.$ios-success; }
+        &.pending .stat-value { color: ios.$ios-warning; }
       }
     }
   }
 
   // 分类统计
   .category-stats {
-    margin-bottom: $ios-spacing-lg;
-    padding: $ios-spacing-md;
-    background: $ios-background-secondary;
-    border-radius: $ios-border-radius-md;
-    border: 1px solid $ios-border;
+    margin-bottom: ios.$ios-spacing-lg;
+    padding: ios.$ios-spacing-md;
+    background: ios.$ios-background-secondary;
+    border-radius: vars.$ios-border-radius-md;
+    border: 1px solid ios.$ios-border;
 
     h5 {
-      margin: 0 0 $ios-spacing-md 0;
-      font-size: $ios-font-size-md;
-      font-weight: $ios-font-weight-semibold;
-      color: $ios-text-primary;
+      margin: 0 0 ios.$ios-spacing-md 0;
+      font-size: ios.$ios-font-size-md;
+      font-weight: ios.$ios-font-weight-semibold;
+      color: ios.$ios-text-primary;
     }
 
     .category-grid {
       display: grid;
       grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
-      gap: $ios-spacing-sm;
+      gap: ios.$ios-spacing-sm;
 
       .category-item {
         display: flex;
         justify-content: space-between;
         align-items: center;
-        padding: $ios-spacing-sm;
-        background: $ios-background;
-        border-radius: $ios-border-radius-sm;
-        border: 1px solid $ios-border;
+        padding: ios.$ios-spacing-sm;
+        background: ios.$ios-background;
+        border-radius: vars.$ios-border-radius-sm;
+        border: 1px solid ios.$ios-border;
 
         .category-label {
-          font-size: $ios-font-size-xs;
-          color: $ios-text-secondary;
+          font-size: ios.$ios-font-size-xs;
+          color: ios.$ios-text-secondary;
         }
 
         .category-count {
-          font-size: $ios-font-size-sm;
-          font-weight: $ios-font-weight-semibold;
-          color: $ios-primary;
+          font-size: ios.$ios-font-size-sm;
+          font-weight: ios.$ios-font-weight-semibold;
+          color: ios.$ios-primary;
         }
       }
     }
@@ -111,17 +110,17 @@
 
   // 筛选区域
   .filter-section {
-    margin-bottom: $ios-spacing-lg;
-    padding: $ios-spacing-md;
-    background: $ios-background-secondary;
-    border-radius: $ios-border-radius-md;
-    border: 1px solid $ios-border;
+    margin-bottom: ios.$ios-spacing-lg;
+    padding: ios.$ios-spacing-md;
+    background: ios.$ios-background-secondary;
+    border-radius: vars.$ios-border-radius-md;
+    border: 1px solid ios.$ios-border;
 
     .filter-row {
       display: flex;
       flex-wrap: wrap;
-      gap: $ios-spacing-md;
-      margin-bottom: $ios-spacing-md;
+      gap: ios.$ios-spacing-md;
+      margin-bottom: ios.$ios-spacing-md;
 
       &:last-child {
         margin-bottom: 0;
@@ -130,67 +129,67 @@
       .filter-group {
         display: flex;
         align-items: center;
-        gap: $ios-spacing-sm;
+        gap: ios.$ios-spacing-sm;
 
         label {
-          font-size: $ios-font-size-sm;
-          color: $ios-text-secondary;
+          font-size: ios.$ios-font-size-sm;
+          color: ios.$ios-text-secondary;
           white-space: nowrap;
         }
 
         .filter-buttons {
           display: flex;
-          gap: $ios-spacing-xs;
+          gap: ios.$ios-spacing-xs;
 
           .filter-btn {
-            padding: $ios-spacing-xs $ios-spacing-sm;
-            border: 1px solid $ios-border;
-            background: $ios-background;
-            color: $ios-text-secondary;
-            border-radius: $ios-border-radius-sm;
-            font-size: $ios-font-size-xs;
+            padding: ios.$ios-spacing-xs ios.$ios-spacing-sm;
+            border: 1px solid ios.$ios-border;
+            background: ios.$ios-background;
+            color: ios.$ios-text-secondary;
+            border-radius: vars.$ios-border-radius-sm;
+            font-size: ios.$ios-font-size-xs;
             cursor: pointer;
             transition: all 0.2s ease;
 
             &:hover {
-              background: $ios-background-secondary;
+              background: ios.$ios-background-secondary;
             }
 
             &.active {
-              background: $ios-primary;
+              background: ios.$ios-primary;
               color: white;
-              border-color: $ios-primary;
+              border-color: ios.$ios-primary;
             }
 
             &.pending.active {
-              background: $ios-warning;
-              border-color: $ios-warning;
+              background: ios.$ios-warning;
+              border-color: ios.$ios-warning;
             }
 
             &.satisfied.active {
-              background: $ios-success;
-              border-color: $ios-success;
+              background: ios.$ios-success;
+              border-color: ios.$ios-success;
             }
 
             &.unsatisfied.active {
-              background: $ios-danger;
-              border-color: $ios-danger;
+              background: ios.$ios-danger;
+              border-color: ios.$ios-danger;
             }
           }
         }
 
         .filter-select {
-          padding: $ios-spacing-xs $ios-spacing-sm;
-          border: 1px solid $ios-border;
-          border-radius: $ios-border-radius-sm;
-          background: $ios-background;
-          color: $ios-text-primary;
-          font-size: $ios-font-size-xs;
+          padding: ios.$ios-spacing-xs ios.$ios-spacing-sm;
+          border: 1px solid ios.$ios-border;
+          border-radius: vars.$ios-border-radius-sm;
+          background: ios.$ios-background;
+          color: ios.$ios-text-primary;
+          font-size: ios.$ios-font-size-xs;
           min-width: 120px;
 
           &:focus {
             outline: none;
-            border-color: $ios-primary;
+            border-color: ios.$ios-primary;
           }
         }
       }
@@ -198,228 +197,62 @@
   }
 
   // 评价列表
-  .reviews-list {
-    .list-body {
-      .review-item {
-        padding: $ios-spacing-md;
-        margin-bottom: $ios-spacing-md;
-        background: $ios-background;
-        border: 1px solid $ios-border;
-        border-radius: $ios-border-radius-md;
-        transition: all 0.2s ease;
-
-        &:hover {
-          box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
-        }
-
-        &:last-child {
-          margin-bottom: 0;
-        }
+  .review-list {
+    .review-item {
+      padding: ios.$ios-spacing-md;
+      margin-bottom: ios.$ios-spacing-md;
+      background: ios.$ios-background;
+      border: 1px solid ios.$ios-border;
+      border-radius: vars.$ios-border-radius-md;
+
+      .review-header {
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        margin-bottom: ios.$ios-spacing-md;
 
-        .review-header {
+        .reviewer-info {
           display: flex;
-          justify-content: space-between;
-          align-items: flex-start;
-          margin-bottom: $ios-spacing-md;
-
-          .customer-info {
-            display: flex;
-            align-items: center;
-            gap: $ios-spacing-sm;
-
-            .customer-name {
-              font-size: $ios-font-size-md;
-              font-weight: $ios-font-weight-semibold;
-              color: $ios-text-primary;
-            }
-
-            .category-tag {
-              padding: $ios-spacing-xs $ios-spacing-sm;
-              background: $ios-primary;
-              color: white;
-              border-radius: $ios-border-radius-sm;
-              font-size: $ios-font-size-xs;
-            }
-          }
-
-          .review-meta {
-            display: flex;
-            align-items: center;
-            gap: $ios-spacing-sm;
-
-            .score-display {
-              display: flex;
-              align-items: center;
-              gap: $ios-spacing-xs;
-
-              .score-stars {
-                .star {
-                  color: #FFD700;
-                  font-size: $ios-font-size-sm;
-                }
-              }
-
-              .score-number {
-                font-size: $ios-font-size-xs;
-                color: $ios-text-secondary;
-              }
-
-              &.high .score-number { color: $ios-success; }
-              &.medium .score-number { color: $ios-warning; }
-              &.low .score-number { color: $ios-danger; }
-            }
-
-            .status-badge {
-              padding: $ios-spacing-xs $ios-spacing-sm;
-              border-radius: $ios-border-radius-sm;
-              font-size: $ios-font-size-xs;
-              font-weight: $ios-font-weight-semibold;
-
-              &.satisfied {
-                background: rgba($ios-success, 0.1);
-                color: $ios-success;
-              }
-
-              &.unsatisfied {
-                background: rgba($ios-danger, 0.1);
-                color: $ios-danger;
-              }
-
-              &.pending {
-                background: rgba($ios-warning, 0.1);
-                color: $ios-warning;
-              }
-            }
-          }
-        }
-
-        .review-content {
-          margin-bottom: $ios-spacing-md;
-
-          .feedback-text {
-            margin: 0 0 $ios-spacing-sm 0;
-            color: $ios-text-primary;
-            line-height: 1.5;
-          }
-
-          .problem-location {
-            margin-bottom: $ios-spacing-sm;
-            padding: $ios-spacing-sm;
-            background: rgba($ios-warning, 0.1);
-            border-radius: $ios-border-radius-sm;
-            font-size: $ios-font-size-sm;
-            color: $ios-text-secondary;
-
-            strong {
-              color: $ios-warning;
-            }
-          }
-
-          .feedback-images {
-            display: flex;
-            gap: $ios-spacing-sm;
-            flex-wrap: wrap;
-
-            .feedback-image {
-              width: 80px;
-              height: 80px;
-              object-fit: cover;
-              border-radius: $ios-border-radius-sm;
-              border: 1px solid $ios-border;
-            }
-          }
-        }
-
-        .review-footer {
-          .time-info {
-            display: flex;
-            gap: $ios-spacing-md;
-            margin-bottom: $ios-spacing-sm;
+          align-items: center;
+          gap: ios.$ios-spacing-sm;
 
-            .created-time,
-            .updated-time {
-              font-size: $ios-font-size-xs;
-              color: $ios-text-secondary;
-            }
-
-            .updated-time {
-              color: $ios-primary;
-            }
+          .reviewer-name {
+            font-size: ios.$ios-font-size-md;
+            font-weight: ios.$ios-font-weight-semibold;
+            color: ios.$ios-text-primary;
           }
 
-          .response-section {
-            padding: $ios-spacing-sm;
-            background: rgba($ios-primary, 0.05);
-            border-radius: $ios-border-radius-sm;
-            border-left: 3px solid $ios-primary;
-
-            strong {
-              color: $ios-primary;
-              font-size: $ios-font-size-sm;
-            }
-
-            .response-text {
-              margin: $ios-spacing-xs 0 0 0;
-              color: $ios-text-secondary;
-              font-size: $ios-font-size-sm;
-              line-height: 1.4;
-            }
+          .review-date {
+            font-size: ios.$ios-font-size-xs;
+            color: ios.$ios-text-secondary;
           }
         }
       }
     }
-
-    .empty-state {
-      text-align: center;
-      padding: $ios-spacing-xl;
-      color: $ios-text-secondary;
-
-      .empty-icon {
-        font-size: 48px;
-        margin-bottom: $ios-spacing-md;
-      }
-
-      .empty-title {
-        font-size: $ios-font-size-lg;
-        font-weight: $ios-font-weight-semibold;
-        color: $ios-text-primary;
-        margin-bottom: $ios-spacing-sm;
-      }
-
-      .empty-desc {
-        font-size: $ios-font-size-sm;
-        color: $ios-text-secondary;
-      }
-    }
   }
 
-  // 响应式设计
-  @media (max-width: 768px) {
-    .stats-overview .stats-grid {
-      grid-template-columns: repeat(2, 1fr);
-    }
+  // 空状态
+  .empty-state {
+    padding: ios.$ios-spacing-xl;
+    text-align: center;
+    color: ios.$ios-text-secondary;
 
-    .category-stats .category-grid {
-      grid-template-columns: 1fr;
+    .empty-icon {
+      font-size: 3rem;
+      margin-bottom: ios.$ios-spacing-md;
+      opacity: 0.5;
     }
 
-    .filter-section .filter-row {
-      flex-direction: column;
-      align-items: stretch;
-
-      .filter-group {
-        flex-direction: column;
-        align-items: stretch;
-
-        .filter-buttons {
-          justify-content: center;
-        }
-      }
+    .empty-title {
+      font-size: ios.$ios-font-size-lg;
+      font-weight: ios.$ios-font-weight-semibold;
+      color: ios.$ios-text-primary;
+      margin-bottom: ios.$ios-spacing-sm;
     }
 
-    .reviews-list .review-item .review-header {
-      flex-direction: column;
-      gap: $ios-spacing-sm;
+    .empty-description {
+      font-size: ios.$ios-font-size-sm;
+      color: ios.$ios-text-secondary;
     }
   }
 }

+ 12 - 11
src/app/shared/components/proposal-confirm-card/proposal-confirm-card.scss

@@ -1,4 +1,5 @@
 @use '../../styles/_ios-theme.scss' as *;
+@use 'sass:color';
 
 :host {
   display: block;
@@ -508,7 +509,7 @@
                   color: white;
                   
                   &:hover {
-                    background: darken($ios-primary, 10%);
+                    background: color.adjust($ios-primary, $lightness: -10%);
                   }
                 }
                 
@@ -517,7 +518,7 @@
                   color: $ios-text-primary;
                   
                   &:hover {
-                    background: darken($ios-background-secondary, 5%);
+                    background: color.adjust($ios-background-secondary, $lightness: -5%);
                   }
                 }
               }
@@ -993,7 +994,7 @@
                 color: white;
                 
                 &:hover {
-                  background: darken(#34C759, 10%);
+                  background: color.adjust(#34C759, $lightness: -10%);
                 }
               }
               
@@ -1002,7 +1003,7 @@
                 color: white;
                 
                 &:hover {
-                  background: darken(#FF3B30, 10%);
+                  background: color.adjust(#FF3B30, $lightness: -10%);
                 }
               }
               
@@ -1011,7 +1012,7 @@
                 color: $ios-text-primary;
                 
                 &:hover {
-                  background: darken($ios-background-secondary, 5%);
+                  background: color.adjust($ios-background-secondary, $lightness: -5%);
                 }
               }
             }
@@ -1277,7 +1278,7 @@
                 text-decoration: none;
                 
                 &:hover {
-                  background: darken($ios-background-secondary, 5%);
+                  background: color.adjust($ios-background-secondary, $lightness: -5%);
                 }
               }
             }
@@ -1449,7 +1450,7 @@
     color: white;
     
     &:hover:not(:disabled) {
-      background: darken($ios-primary, 10%);
+      background: color.adjust($ios-primary, $lightness: -10%);
     }
   }
   
@@ -1458,7 +1459,7 @@
     color: white;
     
     &:hover:not(:disabled) {
-      background: darken(#34C759, 10%);
+      background: color.adjust(#34C759, $lightness: -10%);
     }
   }
   
@@ -1513,7 +1514,7 @@
       cursor: pointer;
       
       &:hover {
-        background: darken($ios-background-secondary, 5%);
+        background: color.adjust($ios-background-secondary, $lightness: -5%);
       }
     }
   }
@@ -1598,7 +1599,7 @@
         color: $ios-text-primary;
         
         &:hover {
-          background: darken($ios-background-secondary, 5%);
+          background: color.adjust($ios-background-secondary, $lightness: -5%);
         }
       }
       
@@ -1607,7 +1608,7 @@
         color: white;
         
         &:hover {
-          background: darken($ios-primary, 10%);
+          background: color.adjust($ios-primary, $lightness: -10%);
         }
       }
     }

+ 4 - 5
src/app/shared/components/requirements-confirm-card/requirements-confirm-card.scss

@@ -1,4 +1,6 @@
 @use '../../styles/_ios-theme.scss' as *;
+@use 'sass:color';
+@use './requirements-confirm-card-alternative.scss' as *;
 
 :host { 
   display: block; 
@@ -66,9 +68,6 @@
   }
 }
 
-// 导入备选方案样式
-@import './requirements-confirm-card-alternative.scss';
-
 .requirements-confirm-card {
   .card-header {
     display: flex;
@@ -1347,7 +1346,7 @@
     color: white;
     
     &:hover:not(:disabled) {
-      background: darken($ios-primary, 10%);
+      background: color.adjust($ios-primary, $lightness: -10%);
     }
   }
   
@@ -1356,7 +1355,7 @@
     color: white;
     
     &:hover:not(:disabled) {
-      background: darken(#34C759, 10%);
+      background: color.adjust(#34C759, $lightness: -10%);
     }
   }
   

+ 152 - 0
src/app/shared/components/team-assignment-dialog/team-assignment-dialog.component.html

@@ -0,0 +1,152 @@
+<div class="team-assignment-modal">
+  <div class="modal-backdrop" (click)="closeDialog()"></div>
+  
+  <div class="modal-content">
+    <!-- 模态框头部 -->
+    <div class="modal-header">
+      <h2 class="modal-title">分配项目组员</h2>
+      <button class="close-btn" (click)="closeDialog()">
+        <svg width="24" height="24" viewBox="0 0 24 24" fill="none">
+          <path d="M18 6L6 18M6 6l12 12" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
+        </svg>
+      </button>
+    </div>
+
+    <!-- 模态框内容 -->
+    <div class="modal-body">
+      <div class="assignment-form">
+        <!-- 项目信息概览 -->
+        <div class="project-overview">
+          <h3>项目信息</h3>
+          <div class="project-info">
+            <div class="info-item">
+              <span class="label">客户姓名:</span>
+              <span class="value">{{ projectData?.customerName || '未设置' }}</span>
+            </div>
+            <div class="info-item">
+              <span class="label">装修类型:</span>
+              <span class="value">{{ projectData?.decorationType || '未设置' }}</span>
+            </div>
+            <div class="info-item">
+              <span class="label">项目面积:</span>
+              <span class="value">{{ projectData?.area || '未设置' }}㎡</span>
+            </div>
+            <div class="info-item">
+              <span class="label">首稿时间:</span>
+              <span class="value">{{ projectData?.firstDraftDate || '未设置' }}</span>
+            </div>
+          </div>
+        </div>
+
+        <!-- 组员选择 -->
+        <div class="team-selection">
+          <h3>选择项目组员</h3>
+          
+          <!-- 设计师选择 -->
+          <div class="role-section">
+            <h4>主设计师</h4>
+            <div class="member-grid">
+              @for (designer of designers; track designer.id) {
+                <div class="member-card" 
+                     [class.selected]="selectedDesigner?.id === designer.id"
+                     (click)="selectDesigner(designer)">
+                  <div class="member-avatar">
+                    <img [src]="designer.avatar || '/assets/default-avatar.png'" [alt]="designer.name">
+                  </div>
+                  <div class="member-info">
+                    <div class="member-name">{{ designer.name }}</div>
+                    <div class="member-role">{{ designer.role }}</div>
+                    <div class="task-status" [class]="getTaskStatusClass(designer.taskCount)">
+                      当前任务:{{ designer.taskCount }}个
+                    </div>
+                  </div>
+                  @if (selectedDesigner?.id === designer.id) {
+                    <div class="selected-indicator">
+                      <svg width="20" height="20" viewBox="0 0 24 24" fill="none">
+                        <path d="M20 6L9 17l-5-5" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
+                      </svg>
+                    </div>
+                  }
+                </div>
+              }
+            </div>
+          </div>
+
+          <!-- 助理设计师选择 -->
+          <div class="role-section">
+            <h4>助理设计师</h4>
+            <div class="member-grid">
+              @for (assistant of assistants; track assistant.id) {
+                <div class="member-card" 
+                     [class.selected]="selectedAssistant?.id === assistant.id"
+                     (click)="selectAssistant(assistant)">
+                  <div class="member-avatar">
+                    <img [src]="assistant.avatar || '/assets/default-avatar.png'" [alt]="assistant.name">
+                  </div>
+                  <div class="member-info">
+                    <div class="member-name">{{ assistant.name }}</div>
+                    <div class="member-role">{{ assistant.role }}</div>
+                    <div class="task-status" [class]="getTaskStatusClass(assistant.taskCount)">
+                      当前任务:{{ assistant.taskCount }}个
+                    </div>
+                  </div>
+                  @if (selectedAssistant?.id === assistant.id) {
+                    <div class="selected-indicator">
+                      <svg width="20" height="20" viewBox="0 0 24 24" fill="none">
+                        <path d="M20 6L9 17l-5-5" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
+                      </svg>
+                    </div>
+                  }
+                </div>
+              }
+            </div>
+          </div>
+
+          <!-- 项目经理选择 -->
+          <div class="role-section">
+            <h4>项目经理</h4>
+            <div class="member-grid">
+              @for (manager of managers; track manager.id) {
+                <div class="member-card" 
+                     [class.selected]="selectedManager?.id === manager.id"
+                     (click)="selectManager(manager)">
+                  <div class="member-avatar">
+                    <img [src]="manager.avatar || '/assets/default-avatar.png'" [alt]="manager.name">
+                  </div>
+                  <div class="member-info">
+                    <div class="member-name">{{ manager.name }}</div>
+                    <div class="member-role">{{ manager.role }}</div>
+                    <div class="task-status" [class]="getTaskStatusClass(manager.taskCount)">
+                      当前任务:{{ manager.taskCount }}个
+                    </div>
+                  </div>
+                  @if (selectedManager?.id === manager.id) {
+                    <div class="selected-indicator">
+                      <svg width="20" height="20" viewBox="0 0 24 24" fill="none">
+                        <path d="M20 6L9 17l-5-5" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
+                      </svg>
+                    </div>
+                  }
+                </div>
+              }
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+
+    <!-- 模态框底部 -->
+    <div class="modal-footer">
+      <button class="cancel-btn" (click)="closeDialog()">取消</button>
+      <button class="confirm-btn" 
+              [disabled]="!isAssignmentValid()" 
+              (click)="confirmAssignment()">
+        @if (isSubmitting) {
+          分配中...
+        } @else {
+          确认分配
+        }
+      </button>
+    </div>
+  </div>
+</div>

+ 340 - 0
src/app/shared/components/team-assignment-dialog/team-assignment-dialog.component.scss

@@ -0,0 +1,340 @@
+@use '../../../shared/styles/_ios-theme.scss' as *;
+@use 'sass:color';
+
+.team-assignment-modal {
+  position: fixed;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  z-index: 1000;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  padding: 20px;
+
+  .modal-backdrop {
+    position: absolute;
+    top: 0;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    background: rgba(0, 0, 0, 0.5);
+    backdrop-filter: blur(8px);
+  }
+
+  .modal-content {
+    position: relative;
+    background: white;
+    border-radius: 16px;
+    width: 100%;
+    max-width: 800px;
+    max-height: 90vh;
+    overflow: hidden;
+    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
+    animation: modalSlideIn 0.3s ease-out;
+  }
+
+  .modal-header {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    padding: 20px 24px;
+    border-bottom: 1px solid $ios-border;
+    background: linear-gradient(135deg, #f8f9fa 0%, #ffffff 100%);
+
+    .modal-title {
+      font-size: 20px;
+      font-weight: 600;
+      color: $ios-text-primary;
+      margin: 0;
+    }
+
+    .close-btn {
+      appearance: none;
+      border: none;
+      background: none;
+      color: $ios-text-secondary;
+      cursor: pointer;
+      padding: 8px;
+      border-radius: 8px;
+      transition: all 0.2s ease;
+
+      &:hover {
+        background: rgba(0, 0, 0, 0.05);
+        color: $ios-text-primary;
+      }
+    }
+  }
+
+  .modal-body {
+    padding: 24px;
+    max-height: calc(90vh - 140px);
+    overflow-y: auto;
+
+    .assignment-form {
+      .project-overview {
+        margin-bottom: 32px;
+        padding: 20px;
+        background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
+        border-radius: 12px;
+        border: 1px solid $ios-border;
+
+        h3 {
+          font-size: 16px;
+          font-weight: 600;
+          color: $ios-text-primary;
+          margin: 0 0 16px 0;
+        }
+
+        .project-info {
+          display: grid;
+          grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
+          gap: 12px;
+
+          .info-item {
+            display: flex;
+            align-items: center;
+
+            .label {
+              font-size: 14px;
+              color: $ios-text-secondary;
+              font-weight: 500;
+              min-width: 80px;
+            }
+
+            .value {
+              font-size: 14px;
+              color: $ios-text-primary;
+              font-weight: 500;
+            }
+          }
+        }
+      }
+
+      .team-selection {
+        h3 {
+          font-size: 18px;
+          font-weight: 600;
+          color: $ios-text-primary;
+          margin: 0 0 24px 0;
+        }
+
+        .role-section {
+          margin-bottom: 32px;
+
+          h4 {
+            font-size: 16px;
+            font-weight: 600;
+            color: $ios-text-primary;
+            margin: 0 0 16px 0;
+            padding-left: 12px;
+            border-left: 4px solid $ios-primary;
+          }
+
+          .member-grid {
+            display: grid;
+            grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
+            gap: 16px;
+
+            .member-card {
+              position: relative;
+              display: flex;
+              align-items: center;
+              padding: 16px;
+              background: white;
+              border: 2px solid $ios-border;
+              border-radius: 12px;
+              cursor: pointer;
+              transition: all 0.3s ease;
+
+              &:hover {
+                transform: translateY(-2px);
+                box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1);
+                border-color: rgba($ios-primary, 0.3);
+              }
+
+              &.selected {
+                border-color: $ios-primary;
+                background: linear-gradient(135deg, rgba($ios-primary, 0.05) 0%, rgba($ios-primary, 0.02) 100%);
+                box-shadow: 0 4px 20px rgba($ios-primary, 0.2);
+              }
+
+              .member-avatar {
+                width: 48px;
+                height: 48px;
+                border-radius: 50%;
+                overflow: hidden;
+                margin-right: 16px;
+                border: 2px solid $ios-border;
+
+                img {
+                  width: 100%;
+                  height: 100%;
+                  object-fit: cover;
+                }
+              }
+
+              .member-info {
+                flex: 1;
+
+                .member-name {
+                  font-size: 16px;
+                  font-weight: 600;
+                  color: $ios-text-primary;
+                  margin-bottom: 4px;
+                }
+
+                .member-role {
+                  font-size: 14px;
+                  color: $ios-text-secondary;
+                  margin-bottom: 6px;
+                }
+
+                .task-status {
+                  font-size: 12px;
+                  font-weight: 500;
+                  padding: 4px 8px;
+                  border-radius: 6px;
+                  display: inline-block;
+
+                  &.status-light {
+                    background: rgba(52, 199, 89, 0.1);
+                    color: #34c759;
+                  }
+
+                  &.status-medium {
+                    background: rgba(255, 149, 0, 0.1);
+                    color: #ff9500;
+                  }
+
+                  &.status-heavy {
+                    background: rgba(255, 59, 48, 0.1);
+                    color: #ff3b30;
+                  }
+                }
+              }
+
+              .selected-indicator {
+                position: absolute;
+                top: 12px;
+                right: 12px;
+                width: 24px;
+                height: 24px;
+                background: $ios-primary;
+                border-radius: 50%;
+                display: flex;
+                align-items: center;
+                justify-content: center;
+                color: white;
+                font-size: 14px;
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+
+  .modal-footer {
+    display: flex;
+    align-items: center;
+    justify-content: flex-end;
+    gap: 12px;
+    padding: 20px 24px;
+    border-top: 1px solid $ios-border;
+    background: linear-gradient(135deg, #ffffff 0%, #f8f9fa 100%);
+
+    .cancel-btn {
+      appearance: none;
+      border: 1px solid $ios-border;
+      background: white;
+      color: $ios-text-secondary;
+      padding: 12px 24px;
+      border-radius: 8px;
+      font-size: 14px;
+      font-weight: 500;
+      cursor: pointer;
+      transition: all 0.2s ease;
+
+      &:hover {
+        background: rgba(0, 0, 0, 0.05);
+        color: $ios-text-primary;
+      }
+    }
+
+    .confirm-btn {
+      appearance: none;
+      border: none;
+      background: linear-gradient(135deg, $ios-primary 0%, color.adjust($ios-primary, $lightness: -10%) 100%);
+      color: white;
+      padding: 12px 24px;
+      border-radius: 8px;
+      font-size: 14px;
+      font-weight: 600;
+      cursor: pointer;
+      transition: all 0.2s ease;
+      min-width: 100px;
+
+      &:hover:not(:disabled) {
+        transform: translateY(-1px);
+        box-shadow: 0 4px 15px rgba($ios-primary, 0.3);
+      }
+
+      &:disabled {
+        opacity: 0.5;
+        cursor: not-allowed;
+        transform: none;
+        box-shadow: none;
+      }
+    }
+  }
+}
+
+@keyframes modalSlideIn {
+  from {
+    opacity: 0;
+    transform: scale(0.9) translateY(20px);
+  }
+  to {
+    opacity: 1;
+    transform: scale(1) translateY(0);
+  }
+}
+
+// 响应式设计
+@media (max-width: 768px) {
+  .team-assignment-modal {
+    padding: 10px;
+
+    .modal-content {
+      max-width: 100%;
+      max-height: 95vh;
+    }
+
+    .modal-body {
+      padding: 16px;
+
+      .assignment-form {
+        .team-selection {
+          .role-section {
+            .member-grid {
+              grid-template-columns: 1fr;
+            }
+          }
+        }
+      }
+    }
+
+    .modal-footer {
+      padding: 16px;
+      flex-direction: column;
+      gap: 8px;
+
+      .cancel-btn,
+      .confirm-btn {
+        width: 100%;
+      }
+    }
+  }
+}

+ 216 - 0
src/app/shared/components/team-assignment-dialog/team-assignment-dialog.component.ts

@@ -0,0 +1,216 @@
+import { Component, EventEmitter, Input, Output } from '@angular/core';
+import { CommonModule } from '@angular/common';
+
+// 定义团队成员接口
+interface TeamMember {
+  id: string;
+  name: string;
+  role: string;
+  avatar?: string;
+  taskCount: number;
+  department: string;
+  skills?: string[];
+  experience?: number;
+}
+
+// 定义项目数据接口
+interface ProjectData {
+  customerName: string;
+  decorationType: string;
+  area: number;
+  firstDraftDate: string;
+  budget?: number;
+  style?: string;
+}
+
+@Component({
+  selector: 'app-team-assignment-dialog',
+  standalone: true,
+  imports: [CommonModule],
+  templateUrl: './team-assignment-dialog.component.html',
+  styleUrls: ['./team-assignment-dialog.component.scss']
+})
+export class TeamAssignmentDialogComponent {
+  @Input() projectData: ProjectData | null = null;
+  @Output() assignmentConfirmed = new EventEmitter<{
+    designer: TeamMember;
+    assistant: TeamMember | null;
+    manager: TeamMember;
+  }>();
+  @Output() dialogClosed = new EventEmitter<void>();
+
+  // 选中的团队成员
+  selectedDesigner: TeamMember | null = null;
+  selectedAssistant: TeamMember | null = null;
+  selectedManager: TeamMember | null = null;
+
+  // 提交状态
+  isSubmitting = false;
+
+  // 模拟团队成员数据
+  designers: TeamMember[] = [
+    {
+      id: 'designer-1',
+      name: '张设计',
+      role: '高级设计师',
+      avatar: '/assets/avatars/designer1.jpg',
+      taskCount: 3,
+      department: '设计部',
+      skills: ['现代简约', '北欧风', '工业风'],
+      experience: 5
+    },
+    {
+      id: 'designer-2',
+      name: '李美美',
+      role: '资深设计师',
+      avatar: '/assets/avatars/designer2.jpg',
+      taskCount: 2,
+      department: '设计部',
+      skills: ['新中式', '法式轻奢', '美式'],
+      experience: 8
+    },
+    {
+      id: 'designer-3',
+      name: '王创意',
+      role: '首席设计师',
+      avatar: '/assets/avatars/designer3.jpg',
+      taskCount: 1,
+      department: '设计部',
+      skills: ['高端定制', '别墅设计', '商业空间'],
+      experience: 12
+    },
+    {
+      id: 'designer-4',
+      name: '陈艺术',
+      role: '设计师',
+      avatar: '/assets/avatars/designer4.jpg',
+      taskCount: 4,
+      department: '设计部',
+      skills: ['日式', '混搭', '小户型'],
+      experience: 3
+    }
+  ];
+
+  assistants: TeamMember[] = [
+    {
+      id: 'assistant-1',
+      name: '小刘',
+      role: '助理设计师',
+      avatar: '/assets/avatars/assistant1.jpg',
+      taskCount: 2,
+      department: '设计部',
+      skills: ['效果图制作', '方案整理'],
+      experience: 2
+    },
+    {
+      id: 'assistant-2',
+      name: '小周',
+      role: '助理设计师',
+      avatar: '/assets/avatars/assistant2.jpg',
+      taskCount: 3,
+      department: '设计部',
+      skills: ['CAD绘图', '材料整理'],
+      experience: 1
+    },
+    {
+      id: 'assistant-3',
+      name: '小王',
+      role: '助理设计师',
+      avatar: '/assets/avatars/assistant3.jpg',
+      taskCount: 1,
+      department: '设计部',
+      skills: ['3D建模', '渲染'],
+      experience: 3
+    }
+  ];
+
+  managers: TeamMember[] = [
+    {
+      id: 'manager-1',
+      name: '赵经理',
+      role: '项目经理',
+      avatar: '/assets/avatars/manager1.jpg',
+      taskCount: 5,
+      department: '项目部',
+      skills: ['项目管理', '客户沟通'],
+      experience: 7
+    },
+    {
+      id: 'manager-2',
+      name: '孙总监',
+      role: '高级项目经理',
+      avatar: '/assets/avatars/manager2.jpg',
+      taskCount: 3,
+      department: '项目部',
+      skills: ['团队协调', '质量控制'],
+      experience: 10
+    },
+    {
+      id: 'manager-3',
+      name: '钱主管',
+      role: '项目经理',
+      avatar: '/assets/avatars/manager3.jpg',
+      taskCount: 4,
+      department: '项目部',
+      skills: ['进度管控', '成本控制'],
+      experience: 6
+    }
+  ];
+
+  constructor() {}
+
+  // 选择设计师
+  selectDesigner(designer: TeamMember): void {
+    this.selectedDesigner = designer;
+  }
+
+  // 选择助理设计师
+  selectAssistant(assistant: TeamMember): void {
+    this.selectedAssistant = assistant;
+  }
+
+  // 选择项目经理
+  selectManager(manager: TeamMember): void {
+    this.selectedManager = manager;
+  }
+
+  // 获取任务状态样式类
+  getTaskStatusClass(taskCount: number): string {
+    if (taskCount <= 2) {
+      return 'status-light';
+    } else if (taskCount <= 4) {
+      return 'status-medium';
+    } else {
+      return 'status-heavy';
+    }
+  }
+
+  // 检查分配是否有效
+  isAssignmentValid(): boolean {
+    return !!(this.selectedDesigner && this.selectedManager);
+  }
+
+  // 确认分配
+  confirmAssignment(): void {
+    if (!this.isAssignmentValid()) {
+      return;
+    }
+
+    this.isSubmitting = true;
+
+    // 模拟API调用
+    setTimeout(() => {
+      this.assignmentConfirmed.emit({
+        designer: this.selectedDesigner!,
+        assistant: this.selectedAssistant,
+        manager: this.selectedManager!
+      });
+      this.isSubmitting = false;
+    }, 1500);
+  }
+
+  // 关闭弹窗
+  closeDialog(): void {
+    this.dialogClosed.emit();
+  }
+}

+ 103 - 0
src/app/shared/components/team-assignment-modal/team-assignment-modal.component.html

@@ -0,0 +1,103 @@
+@if (isVisible) {
+<div class="team-assignment-modal">
+  <!-- 模态框背景 -->
+  <div class="modal-backdrop" (click)="closeModalAction()"></div>
+  
+  <!-- 弹窗内容 -->
+  <div class="modal-content">
+    <!-- 头部 -->
+    <div class="modal-header">
+      <h2>分配设计师</h2>
+      <button class="close-btn" (click)="closeModalAction()">
+        <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
+          <line x1="18" y1="6" x2="6" y2="18"></line>
+          <line x1="6" y1="6" x2="18" y2="18"></line>
+        </svg>
+      </button>
+    </div>
+    
+    <!-- 内容区域 -->
+    <div class="modal-body">
+      <div class="assignment-section">
+        <h3 class="section-title">选择设计师</h3>
+        <p class="section-subtitle">为项目分配合适的设计师,查看他们的当前任务状态</p>
+        
+        <!-- 设计师列表 -->
+        <div class="designer-list">
+          @for (designer of designers; track designer.id) {
+            <div class="designer-card" 
+                 [class.selected]="selectedDesigner?.id === designer.id"
+                 (click)="selectDesigner(designer)">
+              <!-- 设计师头像和基本信息 -->
+              <div class="designer-info">
+                <div class="designer-avatar">
+                  <img [src]="designer.avatar" 
+                       [alt]="designer.name" 
+                       (error)="onImageError($event, designer)"
+                       onerror="this.src='/assets/images/default-avatar.svg'" />
+                </div>
+                <div class="designer-details">
+                  <h4 class="designer-name">{{ designer.name }}</h4>
+                  <p class="designer-role">{{ designer.role }}</p>
+                  <div class="designer-skills">
+                    @for (skill of designer.skills; track skill) {
+                      <span class="skill-tag">{{ skill }}</span>
+                    }
+                  </div>
+                </div>
+              </div>
+              
+              <!-- 工作负载状态 -->
+              <div class="workload-status">
+                <div class="workload-indicator" [class]="getWorkloadClass(designer.workload)">
+                  <span class="workload-text">{{ getWorkloadText(designer.workload) }}</span>
+                  <div class="workload-bar">
+                    <div class="workload-fill" [style.width.%]="designer.workload.percentage"></div>
+                  </div>
+                </div>
+              </div>
+              
+              <!-- 最近任务状态 -->
+              <div class="recent-tasks">
+                <h5 class="tasks-title">最近任务</h5>
+                @if (designer.recentTasks.length > 0) {
+                  <div class="task-list">
+                    @for (task of designer.recentTasks.slice(0, 2); track task.id) {
+                      <div class="task-item">
+                        <span class="task-name">{{ task.projectName }}</span>
+                        <span class="task-stage" [class]="getTaskStageClass(task.stage)">{{ getStageText(task.stage) }}</span>
+                        <span class="task-deadline">{{ formatDeadline(task.deadline) }}</span>
+                      </div>
+                    }
+                  </div>
+                } @else {
+                  <p class="no-tasks">暂无进行中的任务</p>
+                }
+              </div>
+              
+              <!-- 选择指示器 -->
+              @if (selectedDesigner?.id === designer.id) {
+                <div class="selection-indicator">
+                  <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
+                    <polyline points="20 6 9 17 4 12"></polyline>
+                  </svg>
+                </div>
+              }
+            </div>
+          }
+        </div>
+      </div>
+    </div>
+    
+    <!-- 底部操作区域 -->
+    <div class="modal-footer">
+      <button class="btn-cancel" (click)="closeModalAction()">取消</button>
+      <button class="btn-confirm" 
+              [disabled]="!selectedDesigner" 
+              (click)="confirmAssignmentAction()">
+        确认分配
+      </button>
+    </div>
+  </div>
+</div>
+}

+ 463 - 0
src/app/shared/components/team-assignment-modal/team-assignment-modal.component.scss

@@ -0,0 +1,463 @@
+// iOS风格变量定义
+$ios-primary: #007AFF;
+$ios-primary-dark: #0062CC;
+$ios-secondary: #34C759;
+$ios-success: #34C759;
+$ios-warning: #FF9500;
+$ios-danger: #FF3B30;
+$ios-text-primary: #000000;
+$ios-text-secondary: #3C3C43;
+$ios-text-tertiary: #8E8E93;
+$ios-border: #D1D1D6;
+$ios-background: #FFFFFF;
+$ios-background-secondary: #F2F2F7;
+$ios-background-tertiary: #E5E5EA;
+$ios-shadow-sm: 0 1px 3px rgba(0,0,0,0.1);
+$ios-shadow-md: 0 4px 10px rgba(0,0,0,0.1);
+$ios-shadow-lg: 0 10px 30px rgba(0,0,0,0.1);
+$ios-radius: 10px;
+$ios-radius-lg: 16px;
+$ios-radius-sm: 6px;
+$ios-radius-full: 50px;
+$ios-transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
+$ios-font-family: -apple-system, BlinkMacSystemFont, 'PingFang SC', sans-serif;
+$ios-spacing-xs: 4px;
+$ios-spacing-sm: 8px;
+$ios-spacing-md: 16px;
+$ios-spacing-lg: 24px;
+$ios-spacing-xl: 32px;
+
+.team-assignment-modal {
+  position: fixed;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  z-index: 1000;
+  font-family: $ios-font-family;
+
+  .modal-backdrop {
+    position: absolute;
+    top: 0;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    background: rgba(0, 0, 0, 0.4);
+    backdrop-filter: blur(4px);
+  }
+
+  .modal-content {
+    position: absolute;
+    top: 50%;
+    left: 50%;
+    transform: translate(-50%, -50%);
+    width: 90%;
+    max-width: 800px;
+    max-height: 90vh;
+    background: $ios-background;
+    border-radius: $ios-radius-lg;
+    box-shadow: $ios-shadow-lg;
+    overflow: hidden;
+    display: flex;
+    flex-direction: column;
+  }
+
+  .modal-header {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    padding: $ios-spacing-lg;
+    background: linear-gradient(135deg, $ios-background 0%, $ios-background-secondary 100%);
+    border-bottom: 1px solid $ios-border;
+    flex-shrink: 0;
+
+    .modal-title {
+      font-size: 20px;
+      font-weight: 600;
+      color: $ios-text-primary;
+      margin: 0;
+    }
+
+    .close-btn {
+      background: none;
+      border: none;
+      color: $ios-text-secondary;
+      cursor: pointer;
+      padding: $ios-spacing-sm;
+      border-radius: $ios-radius-sm;
+      transition: $ios-transition;
+
+      &:hover {
+        background: $ios-background-tertiary;
+        color: $ios-text-primary;
+      }
+    }
+  }
+
+  .modal-body {
+    flex: 1;
+    overflow-y: auto;
+    padding: $ios-spacing-lg;
+
+    .assignment-section {
+      .section-title {
+        font-size: 18px;
+        font-weight: 600;
+        color: $ios-text-primary;
+        margin: 0 0 $ios-spacing-sm 0;
+      }
+
+      .section-subtitle {
+        font-size: 14px;
+        color: $ios-text-secondary;
+        margin: 0 0 $ios-spacing-lg 0;
+      }
+    }
+
+    .designer-list {
+      display: flex;
+      flex-direction: column;
+      gap: $ios-spacing-md;
+
+      .designer-card {
+        background: $ios-background;
+        border: 2px solid $ios-border;
+        border-radius: $ios-radius-lg;
+        padding: $ios-spacing-lg;
+        cursor: pointer;
+        transition: $ios-transition;
+        position: relative;
+        overflow: hidden;
+
+        &:hover {
+          border-color: color-mix(in srgb, $ios-primary 50%, $ios-border);
+          box-shadow: $ios-shadow-md;
+        }
+
+        &.selected {
+          border-color: $ios-primary;
+          background: linear-gradient(135deg, rgba(0, 122, 255, 0.05) 0%, rgba(0, 122, 255, 0.02) 100%);
+          box-shadow: 0 4px 20px rgba(0, 122, 255, 0.15);
+        }
+
+        .designer-info {
+          display: flex;
+          align-items: flex-start;
+          gap: $ios-spacing-md;
+          margin-bottom: $ios-spacing-md;
+
+          .designer-avatar {
+            width: 60px;
+            height: 60px;
+            border-radius: $ios-radius-full;
+            overflow: hidden;
+            flex-shrink: 0;
+            border: 2px solid $ios-border;
+            background: linear-gradient(135deg, $ios-background-secondary 0%, $ios-background-tertiary 100%);
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            position: relative;
+
+            img {
+              width: 100%;
+              height: 100%;
+              object-fit: cover;
+              transition: $ios-transition;
+            }
+
+            &:hover img {
+              transform: scale(1.05);
+            }
+          }
+
+          .designer-details {
+            flex: 1;
+
+            .designer-name {
+              font-size: 16px;
+              font-weight: 600;
+              color: $ios-text-primary;
+              margin: 0 0 $ios-spacing-xs 0;
+            }
+
+            .designer-role {
+              font-size: 14px;
+              color: $ios-text-secondary;
+              margin: 0 0 $ios-spacing-sm 0;
+            }
+
+            .designer-skills {
+              display: flex;
+              flex-wrap: wrap;
+              gap: $ios-spacing-xs;
+
+              .skill-tag {
+                background: linear-gradient(135deg, $ios-background-secondary 0%, rgba(0, 122, 255, 0.1) 100%);
+                color: $ios-primary;
+                padding: 4px 12px;
+                border-radius: $ios-radius;
+                font-size: 12px;
+                font-weight: 600;
+                border: 1px solid rgba(0, 122, 255, 0.2);
+                transition: $ios-transition;
+
+                &:hover {
+                  background: linear-gradient(135deg, rgba(0, 122, 255, 0.1) 0%, rgba(0, 122, 255, 0.2) 100%);
+                  transform: translateY(-1px);
+                  box-shadow: 0 2px 4px rgba(0, 122, 255, 0.2);
+                }
+              }
+            }
+          }
+        }
+
+        .workload-status {
+          margin-bottom: $ios-spacing-md;
+
+          .workload-indicator {
+            display: flex;
+            align-items: center;
+            gap: $ios-spacing-sm;
+
+            .workload-text {
+              font-size: 14px;
+              font-weight: 500;
+              min-width: 60px;
+            }
+
+            .workload-bar {
+              flex: 1;
+              height: 8px;
+              background: $ios-background-tertiary;
+              border-radius: 4px;
+              overflow: hidden;
+              box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
+
+              .workload-fill {
+                height: 100%;
+                border-radius: 4px;
+                transition: $ios-transition;
+                position: relative;
+                overflow: hidden;
+
+                &::after {
+                  content: '';
+                  position: absolute;
+                  top: 0;
+                  left: -100%;
+                  width: 100%;
+                  height: 100%;
+                  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.3), transparent);
+                  animation: shimmer 2s infinite;
+                }
+              }
+            }
+
+            @keyframes shimmer {
+              0% { left: -100%; }
+              100% { left: 100%; }
+            }
+
+            &.low {
+              .workload-text { color: $ios-success; }
+              .workload-fill { background: $ios-success; }
+            }
+
+            &.medium {
+              .workload-text { color: $ios-warning; }
+              .workload-fill { background: $ios-warning; }
+            }
+
+            &.high {
+              .workload-text { color: $ios-danger; }
+              .workload-fill { background: $ios-danger; }
+            }
+          }
+        }
+
+        .recent-tasks {
+          .tasks-title {
+            font-size: 14px;
+            font-weight: 600;
+            color: $ios-text-primary;
+            margin: 0 0 $ios-spacing-sm 0;
+          }
+
+          .task-list {
+            display: flex;
+            flex-direction: column;
+            gap: $ios-spacing-xs;
+
+            .task-item {
+              display: flex;
+              align-items: center;
+              gap: $ios-spacing-sm;
+              padding: $ios-spacing-xs $ios-spacing-sm;
+              background: $ios-background-secondary;
+              border-radius: $ios-radius-sm;
+              font-size: 12px;
+
+              .task-name {
+                flex: 1;
+                color: $ios-text-primary;
+                font-weight: 500;
+              }
+
+              .task-stage {
+                padding: 2px 6px;
+                border-radius: $ios-radius-sm;
+                font-weight: 500;
+                font-size: 11px;
+
+                &.modeling { background: #E3F2FD; color: #1976D2; }
+                &.rendering { background: #F3E5F5; color: #7B1FA2; }
+                &.soft-decoration { background: #E8F5E8; color: #388E3C; }
+                &.post-production { background: #FFF3E0; color: #F57C00; }
+              }
+
+              .task-deadline {
+                color: $ios-text-tertiary;
+                font-size: 11px;
+              }
+            }
+          }
+
+          .no-tasks {
+            color: $ios-text-tertiary;
+            font-size: 12px;
+            text-align: center;
+            padding: $ios-spacing-sm;
+            background: $ios-background-secondary;
+            border-radius: $ios-radius-sm;
+            margin: 0;
+          }
+        }
+
+        .selection-indicator {
+          position: absolute;
+          top: $ios-spacing-md;
+          right: $ios-spacing-md;
+          width: 32px;
+          height: 32px;
+          background: $ios-primary;
+          border-radius: $ios-radius-full;
+          display: flex;
+          align-items: center;
+          justify-content: center;
+          color: white;
+          box-shadow: $ios-shadow-sm;
+        }
+      }
+    }
+  }
+
+  .modal-footer {
+    display: flex;
+    justify-content: flex-end;
+    gap: $ios-spacing-md;
+    padding: $ios-spacing-lg;
+    background: $ios-background-secondary;
+    border-top: 1px solid $ios-border;
+    flex-shrink: 0;
+
+    .btn-cancel {
+      padding: $ios-spacing-sm $ios-spacing-lg;
+      background: none;
+      border: 1px solid $ios-border;
+      color: $ios-text-secondary;
+      border-radius: $ios-radius;
+      font-size: 14px;
+      font-weight: 500;
+      cursor: pointer;
+      transition: $ios-transition;
+
+      &:hover {
+        background: $ios-background-tertiary;
+        color: $ios-text-primary;
+      }
+    }
+
+    .btn-confirm {
+      padding: $ios-spacing-md $ios-spacing-xl;
+      background: linear-gradient(135deg, $ios-primary 0%, $ios-primary-dark 100%);
+      border: none;
+      color: white;
+      border-radius: $ios-radius;
+      font-size: 16px;
+      font-weight: 600;
+      cursor: pointer;
+      transition: $ios-transition;
+      box-shadow: 0 2px 8px rgba(0, 122, 255, 0.3);
+      position: relative;
+      overflow: hidden;
+
+      &::before {
+        content: '';
+        position: absolute;
+        top: 0;
+        left: -100%;
+        width: 100%;
+        height: 100%;
+        background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
+        transition: left 0.5s;
+      }
+
+      &:hover:not(:disabled) {
+        background: linear-gradient(135deg, $ios-primary-dark 0%, #004499 100%);
+        box-shadow: 0 4px 16px rgba(0, 122, 255, 0.4);
+        transform: translateY(-1px);
+
+        &::before {
+          left: 100%;
+        }
+      }
+
+      &:active:not(:disabled) {
+        transform: translateY(0);
+        box-shadow: 0 2px 8px rgba(0, 122, 255, 0.3);
+      }
+
+      &:disabled {
+        background: $ios-text-tertiary;
+        cursor: not-allowed;
+        box-shadow: none;
+        transform: none;
+
+        &::before {
+          display: none;
+        }
+      }
+    }
+  }
+
+  // 响应式设计
+  @media (max-width: 768px) {
+    .modal-content {
+      width: 95%;
+      max-height: 95vh;
+    }
+
+    .modal-header,
+    .modal-body,
+    .modal-footer {
+      padding: $ios-spacing-md;
+    }
+
+    .designer-list .designer-card {
+      padding: $ios-spacing-md;
+
+      .designer-info {
+        flex-direction: column;
+        align-items: center;
+        text-align: center;
+        gap: $ios-spacing-sm;
+
+        .designer-avatar {
+          width: 50px;
+          height: 50px;
+        }
+      }
+    }
+  }
+}

+ 233 - 0
src/app/shared/components/team-assignment-modal/team-assignment-modal.component.ts

@@ -0,0 +1,233 @@
+import { Component, EventEmitter, Input, Output } from '@angular/core';
+import { CommonModule } from '@angular/common';
+
+export interface Designer {
+  id: string;
+  name: string;
+  role: string;
+  avatar: string;
+  skills: string[];
+  workload: {
+    level: 'low' | 'medium' | 'high';
+    percentage: number;
+    text: string;
+  };
+  recentTasks: {
+    id: string;
+    name: string;
+    projectName: string;
+    stage: 'modeling' | 'rendering' | 'soft-decoration' | 'post-production';
+    deadline: string;
+  }[];
+}
+
+@Component({
+  selector: 'app-team-assignment-modal',
+  standalone: true,
+  imports: [CommonModule],
+  templateUrl: './team-assignment-modal.component.html',
+  styleUrls: ['./team-assignment-modal.component.scss']
+})
+export class TeamAssignmentModalComponent {
+  @Input() isVisible = false;
+  @Output() closeModal = new EventEmitter<void>();
+  @Output() confirmAssignment = new EventEmitter<Designer>();
+
+  selectedDesigner: Designer | null = null;
+
+  // 模拟设计师数据
+  designers: Designer[] = [
+    {
+      id: '1',
+      name: '张设计师',
+      role: '高级室内设计师',
+      avatar: '/assets/images/default-avatar.svg',
+      skills: ['现代简约', '北欧风格', '工业风'],
+      workload: {
+        level: 'low',
+        percentage: 30,
+        text: '轻度'
+      },
+      recentTasks: [
+        {
+          id: '1',
+          name: '海景别墅设计',
+          projectName: '海景别墅设计',
+          stage: 'modeling',
+          deadline: '2024-01-15'
+        },
+        {
+          id: '2',
+          name: '现代公寓改造',
+          projectName: '现代公寓改造',
+          stage: 'rendering',
+          deadline: '2024-01-20'
+        }
+      ]
+    },
+    {
+      id: '2',
+      name: '李设计师',
+      role: '资深设计总监',
+      avatar: '/assets/images/default-avatar.svg',
+      skills: ['欧式古典', '美式乡村', '中式传统'],
+      workload: {
+        level: 'medium',
+        percentage: 65,
+        text: '中度'
+      },
+      recentTasks: [
+        {
+          id: '3',
+          name: '豪华会所设计',
+          projectName: '豪华会所设计',
+          stage: 'soft-decoration',
+          deadline: '2024-01-18'
+        },
+        {
+          id: '4',
+          name: '商业空间规划',
+          projectName: '商业空间规划',
+          stage: 'post-production',
+          deadline: '2024-01-25'
+        },
+        {
+          id: '5',
+          name: '私人定制住宅',
+          projectName: '私人定制住宅',
+          stage: 'modeling',
+          deadline: '2024-02-01'
+        }
+      ]
+    },
+    {
+      id: '3',
+      name: '王设计师',
+      role: '创意设计师',
+      avatar: '/assets/images/default-avatar.svg',
+      skills: ['极简主义', '日式禅风', '斯堪的纳维亚'],
+      workload: {
+        level: 'high',
+        percentage: 85,
+        text: '重度'
+      },
+      recentTasks: [
+        {
+          id: '6',
+          name: '艺术画廊设计',
+          projectName: '艺术画廊设计',
+          stage: 'rendering',
+          deadline: '2024-01-12'
+        },
+        {
+          id: '7',
+          name: '精品酒店套房',
+          projectName: '精品酒店套房',
+          stage: 'soft-decoration',
+          deadline: '2024-01-16'
+        },
+        {
+          id: '8',
+          name: '创意办公空间',
+          projectName: '创意办公空间',
+          stage: 'post-production',
+          deadline: '2024-01-22'
+        },
+        {
+          id: '9',
+          name: '高端住宅项目',
+          projectName: '高端住宅项目',
+          stage: 'modeling',
+          deadline: '2024-01-28'
+        }
+      ]
+    },
+    {
+      id: '4',
+      name: '陈设计师',
+      role: '室内设计师',
+      avatar: '/assets/images/default-avatar.svg',
+      skills: ['新中式', '轻奢风格', '混搭风格'],
+      workload: {
+        level: 'low',
+        percentage: 20,
+        text: '轻度'
+      },
+      recentTasks: [
+        {
+          id: '10',
+          name: '温馨家庭住宅',
+          projectName: '温馨家庭住宅',
+          stage: 'modeling',
+          deadline: '2024-01-30'
+        }
+      ]
+    }
+  ];
+
+  selectDesigner(designer: Designer): void {
+    this.selectedDesigner = designer;
+  }
+
+  closeModalAction(): void {
+    this.selectedDesigner = null;
+    this.closeModal.emit();
+  }
+
+  confirmAssignmentAction(): void {
+    if (this.selectedDesigner) {
+      this.confirmAssignment.emit(this.selectedDesigner);
+      this.closeModalAction();
+    }
+  }
+
+  getStageText(stage: string): string {
+    const stageMap: { [key: string]: string } = {
+      'modeling': '建模',
+      'rendering': '渲染',
+      'soft-decoration': '软装',
+      'post-production': '后期'
+    };
+    return stageMap[stage] || stage;
+  }
+
+  // 图片加载错误处理
+  onImageError(event: any, designer: Designer): void {
+    event.target.src = '/assets/images/default-avatar.svg';
+  }
+
+  getWorkloadClass(workload: { level: 'low' | 'medium' | 'high'; percentage: number; text: string }): string {
+    return `workload-${workload.level}`;
+  }
+
+  getWorkloadText(workload: { level: 'low' | 'medium' | 'high'; percentage: number; text: string }): string {
+    return workload.text;
+  }
+
+  getTaskStageClass(stage: 'modeling' | 'rendering' | 'soft-decoration' | 'post-production'): string {
+    const stageClassMap: { [key: string]: string } = {
+      'modeling': 'stage-modeling',
+      'rendering': 'stage-rendering',
+      'soft-decoration': 'stage-soft-decoration',
+      'post-production': 'stage-post-production'
+    };
+    return stageClassMap[stage] || '';
+  }
+
+  formatDeadline(deadline: string): string {
+    const date = new Date(deadline);
+    const now = new Date();
+    const diffTime = date.getTime() - now.getTime();
+    const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
+    
+    if (diffDays < 0) {
+      return '已逾期';
+    } else if (diffDays === 0) {
+      return '今天';
+    } else if (diffDays === 1) {
+      return '明天';
+    } else {
+      return `${diffDays}天后`;
+    }
+  }
+}

+ 5 - 0
src/assets/images/default-avatar.svg

@@ -0,0 +1,5 @@
+<svg width="64" height="64" viewBox="0 0 64 64" fill="none" xmlns="http://www.w3.org/2000/svg">
+  <circle cx="32" cy="32" r="32" fill="#E5E7EB"/>
+  <circle cx="32" cy="24" r="10" fill="#9CA3AF"/>
+  <path d="M12 52C12 44.268 18.268 38 26 38H38C45.732 38 52 44.268 52 52V56C52 58.209 50.209 60 48 60H16C13.791 60 12 58.209 12 56V52Z" fill="#9CA3AF"/>
+</svg>

+ 1 - 1
src/styles.scss

@@ -7,7 +7,7 @@
 @use '@angular/material' as mat;
 
 // 导入变量
-@import './styles/variables';
+@use './styles/variables' as *;
 
 // 自定义字体配置
 @include mat.core();