Browse Source

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

徐福静0235668 6 hours ago
parent
commit
629318bc66

+ 178 - 190
src/app/pages/team-leader/dashboard/components/todo-section/todo-section.component.html

@@ -135,66 +135,86 @@
           <svg viewBox="0 0 24 24" width="18" height="18" fill="currentColor">
             <path d="M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z"/>
           </svg>
-          紧急事件
+          紧急事件监控
           <span class="task-count urgent" *ngIf="urgentEvents.length > 0">({{ urgentEvents.length }})</span>
         </h3>
-        <span class="column-subtitle">自动计算的截止事件</span>
+        <span class="column-subtitle">自动计算截止/逾期</span>
       </div>
       
-      <div class="tag-filter-bar" *ngIf="!loadingUrgentEvents && urgentEvents.length > 0">
-        <button 
-          class="tag-button"
-          [class.active]="urgentEventTagFilter === 'all'"
-          (click)="filterUrgentEventsByTag('all')"
-          title="显示所有紧急事件"
-        >
-          <span class="tag-icon">📋</span>
-          <span class="tag-label">全部</span>
-          <span class="tag-count">{{ urgentEvents.length }}</span>
-        </button>
-        
-        <button 
-          class="tag-button"
-          [class.active]="urgentEventTagFilter === 'customer'"
-          (click)="filterUrgentEventsByTag('customer')"
-          title="客户服务"
-        >
-          <span class="tag-icon">👥</span>
-          <span class="tag-label">客户服务</span>
-          <span class="tag-count">{{ getTagCount('customer') }}</span>
+      <!-- 一级筛选 Tab -->
+      <div class="filter-tabs" *ngIf="!loadingUrgentEvents && urgentEvents.length > 0">
+        <div class="filter-tab" 
+             [class.active]="urgentEventCategoryFilter === 'all'"
+             (click)="filterUrgentEventsByTag('all')">
+          全部 <span class="count-badge">{{ urgentEvents.length }}</span>
+        </div>
+        <div class="filter-tab" 
+             [class.active-customer]="urgentEventCategoryFilter === 'customer'"
+             (click)="filterUrgentEventsByTag('customer')">
+          <svg viewBox="0 0 24 24" width="14" height="14" fill="currentColor"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 3c1.66 0 3 1.34 3 3s-1.34 3-3 3-3-1.34-3-3 1.34-3 3-3zm0 14.2c-2.5 0-4.71-1.28-6-3.22.03-1.99 4-3.08 6-3.08 1.99 0 5.97 1.09 6 3.08-1.29 1.94-3.5 3.22-6 3.22z"/></svg>
+          客户 <span class="count-badge">{{ getTagCount('customer') }}</span>
+        </div>
+        <div class="filter-tab" 
+             [class.active-phase]="urgentEventCategoryFilter === 'phase'"
+             (click)="filterUrgentEventsByTag('phase')">
+          <svg viewBox="0 0 24 24" width="14" height="14" fill="currentColor"><path d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8zm.5-13H11v6l5.25 3.15.75-1.23-4.5-2.67z"/></svg>
+          阶段逾期 <span class="count-badge">{{ getTagCount('phase') }}</span>
+        </div>
+        <div class="filter-tab" 
+             [class.active]="urgentEventCategoryFilter === 'review'"
+             (click)="filterUrgentEventsByTag('review')">
+          <svg viewBox="0 0 24 24" width="14" height="14" fill="currentColor"><path d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-4 6h-4v2h4v-2zm3 6H6v-2h12v2zm0-4H6V9h12v2z"/></svg>
+          小图/决策 <span class="count-badge">{{ getTagCount('review') }}</span>
+        </div>
+        <div class="filter-tab" 
+             [class.active-delivery]="urgentEventCategoryFilter === 'delivery'"
+             (click)="filterUrgentEventsByTag('delivery')">
+          <svg viewBox="0 0 24 24" width="14" height="14" fill="currentColor"><path d="M20 6h-4V4c0-1.11-.89-2-2-2h-4c-1.11 0-2 .89-2 2v2H4c-1.11 0-1.99.89-1.99 2L2 19c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V8c0-1.11-.89-2-2-2zm-6 0h-4V4h4v2z"/></svg>
+          交付延期 <span class="count-badge">{{ getTagCount('delivery') }}</span>
+        </div>
+      </div>
+      
+      <!-- 二级筛选 (阶段细分) -->
+      <div class="sub-filters" *ngIf="urgentEventCategoryFilter === 'phase'">
+        <span class="sub-label">阶段筛选:</span>
+        <span class="sub-chip" [class.active]="!activePhaseFilter" (click)="togglePhaseFilter('')">全部</span>
+        <span class="sub-chip" [class.active]="activePhaseFilter === 'modeling'" (click)="togglePhaseFilter('modeling')">建模</span>
+        <span class="sub-chip" [class.active]="activePhaseFilter === 'rendering'" (click)="togglePhaseFilter('rendering')">渲染</span>
+        <span class="sub-chip" [class.active]="activePhaseFilter === 'soft_fitting'" (click)="togglePhaseFilter('soft_fitting')">软装</span>
+        <span class="sub-chip" [class.active]="activePhaseFilter === 'post_processing'" (click)="togglePhaseFilter('post_processing')">后期</span>
+      </div>
+
+      <!-- 小图视图子标签,仅在“小图/决策”主标签下展示 -->
+      <div class="small-view-bar" *ngIf="urgentEventCategoryFilter === 'review'">
+        <span class="small-view-label">小图视图:</span>
+        <button
+          type="button"
+          class="small-view-chip"
+          [class.active]="smallViewFilter === 'all'"
+          (click)="setSmallViewFilter('all')">
+          全部小图
+          <span class="chip-count" *ngIf="getSmallViewCount() > 0">{{ getSmallViewCount() }}</span>
         </button>
-        
-        <button 
-          class="tag-button"
-          [class.active]="urgentEventTagFilter === 'phase'"
-          (click)="filterUrgentEventsByTag('phase')"
-          title="工作阶段"
-        >
-          <span class="tag-icon">🔧</span>
-          <span class="tag-label">工作阶段</span>
-          <span class="tag-count">{{ getTagCount('phase') }}</span>
+        <button
+          type="button"
+          class="small-view-chip"
+          [class.active]="smallViewFilter === 'nearDeadline'"
+          (click)="setSmallViewFilter('nearDeadline')">
+          临近截止
         </button>
-        
-        <button 
-          class="tag-button"
-          [class.active]="urgentEventTagFilter === 'review'"
-          (click)="filterUrgentEventsByTag('review')"
-          title="小图截止"
-        >
-          <span class="tag-icon">📐</span>
-          <span class="tag-label">小图截止</span>
-          <span class="tag-count">{{ getTagCount('review') }}</span>
+        <button
+          type="button"
+          class="small-view-chip"
+          [class.active]="smallViewFilter === 'overdue'"
+          (click)="setSmallViewFilter('overdue')">
+          对图期逾期
         </button>
-        
-        <button 
-          class="tag-button"
-          [class.active]="urgentEventTagFilter === 'delivery'"
-          (click)="filterUrgentEventsByTag('delivery')"
-          title="交付延期"
-        >
-          <span class="tag-icon">📦</span>
-          <span class="tag-label">交付延期</span>
-          <span class="tag-count">{{ getTagCount('delivery') }}</span>
+        <button
+          type="button"
+          class="small-view-chip"
+          [class.active]="smallViewFilter === 'stagnant'"
+          (click)="setSmallViewFilter('stagnant')">
+          停滞期项目
         </button>
       </div>
       
@@ -212,7 +232,6 @@
           <path d="M9 16.2L4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4L9 16.2z"/>
         </svg>
         <p>暂无紧急事件</p>
-        <p class="hint">所有项目时间节点正常 ✅</p>
       </div>
 
       <div class="empty-state filtered" *ngIf="!loadingUrgentEvents && urgentEvents.length > 0 && filteredUrgentEventsList.length === 0">
@@ -220,164 +239,133 @@
           <path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z"/>
         </svg>
         <p>该筛选条件下暂无事件</p>
-        <p class="hint">尝试切换其他标签</p>
       </div>
       
       <!-- 紧急事件列表 -->
       <div class="todo-list-compact urgent-list" *ngIf="!loadingUrgentEvents && filteredUrgentEventsList.length > 0">
-        <div class="todo-item-compact urgent-item" *ngFor="let event of filteredUrgentEventsList; trackBy: trackUrgentEventById" [attr.data-urgency]="event.urgencyLevel">
-          <!-- 左侧紧急程度色条 -->
-          <div class="urgency-indicator" [attr.data-urgency]="event.urgencyLevel"></div>
+        <div class="event-card" *ngFor="let event of filteredUrgentEventsList; trackBy: trackUrgentEventById" 
+             [attr.data-category]="getEventCategory(event)"
+             [class.small-view-card]="urgentEventCategoryFilter === 'review' && isSmallImageEvent(event)">
           
-          <!-- 事件内容 -->
-          <div class="task-content">
+          <!-- 左侧分类彩条 -->
+          <div class="card-line" [attr.data-category]="getEventCategory(event)"></div>
+          
+          <div class="event-main">
             <!-- 标题行 -->
-            <div class="task-header">
-              <span class="task-title">{{ event.title }}</span>
-              <div class="task-badges">
-                <span class="badge badge-urgency" [attr.data-urgency]="event.urgencyLevel">
-                  <ng-container *ngIf="event.urgencyLevel === 'critical'">🔴 紧急</ng-container>
-                  <ng-container *ngIf="event.urgencyLevel === 'high'">🟠 重要</ng-container>
-                  <ng-container *ngIf="event.urgencyLevel === 'medium'">🟡 注意</ng-container>
-                </span>
-                <span class="badge badge-event-type">
-                  <ng-container *ngIf="event.eventType === 'review'">对图</ng-container>
-                  <ng-container *ngIf="event.eventType === 'delivery'">交付</ng-container>
-                  <ng-container *ngIf="event.eventType === 'phase_deadline'">{{ event.phaseName }}</ng-container>
-                  <ng-container *ngIf="getEventCategory(event) === 'customer'">客户</ng-container>
-                </span>
-                <span class="badge-status overdue" *ngIf="event.statusType === 'overdue'">逾期</span>
-                <span class="badge-status upcoming" *ngIf="event.statusType === 'dueSoon'">临近</span>
-                <span class="badge-status stagnant" *ngIf="event.statusType === 'stagnant'">
-                  停滞{{ event.stagnationDays || 7 }}天
-                </span>
-                <span class="badge-status customer" *ngIf="getEventCategory(event) === 'customer'">客户预警</span>
-              </div>
+            <div class="event-header">
+              <span class="event-title" [class.text-red-700]="getEventCategory(event) === 'customer'">{{ event.title }}</span>
+              
+              <!-- 标签组 -->
+              <span class="event-tag" *ngIf="getEventCategory(event) === 'customer'">客户服务</span>
+              <span class="event-tag" *ngIf="getEventCategory(event) === 'phase'">{{ event.phaseName || '阶段' }}</span>
+              <span class="event-tag" *ngIf="getEventCategory(event) === 'review'">小图/决策</span>
+              <span class="event-tag" *ngIf="getEventCategory(event) === 'delivery'">交付</span>
+
+              <!-- 状态标签 -->
+              <span class="badge-status overdue" *ngIf="event.statusType === 'overdue'">逾期{{ event.overdueDays }}天</span>
+              <span class="badge-status upcoming" *ngIf="event.statusType === 'dueSoon'">临近</span>
             </div>
-            
-            <!-- 描述 -->
-            <div class="task-description">
+
+            <!-- 描述/内容 -->
+            <div class="event-desc">
               {{ event.description }}
             </div>
-            <div class="followup-tip" *ngIf="event.followUpNeeded">
-              客户反馈待跟进 · 请及时追踪
-            </div>
             
-            <!-- 停滞/改图原因标签 -->
-            <div class="reason-tags" *ngIf="event.isMarkedAsStagnant || event.isMarkedAsModification">
-              <div class="reason-tag stagnant" *ngIf="event.isMarkedAsStagnant">
-                <svg viewBox="0 0 24 24" width="12" height="12" fill="currentColor">
-                  <path d="M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z"/>
-                </svg>
-                <span class="reason-label">停滞原因:</span>
-                <span class="reason-text" *ngIf="event.stagnationReasonType === 'designer'">设计师原因停滞</span>
-                <span class="reason-text" *ngIf="event.stagnationReasonType === 'customer'">客户原因导致项目无法推进</span>
-                <span class="reason-text" *ngIf="event.stagnationReasonType === 'custom'">{{ event.stagnationCustomReason }}</span>
-                <span class="reason-date" *ngIf="event.estimatedResumeDate">
-                  (预计{{ event.estimatedResumeDate | date:'MM-dd' }}恢复)
-                </span>
-              </div>
-              <div class="reason-tag modification" *ngIf="event.isMarkedAsModification">
-                <svg viewBox="0 0 24 24" width="12" height="12" fill="currentColor">
-                  <path d="M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.39-.39-1.02-.39-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z"/>
-                </svg>
-                <span class="reason-label">改图原因:</span>
-                <span class="reason-text" *ngIf="event.modificationReasonType === 'customer'">客户要求改图</span>
-                <span class="reason-text" *ngIf="event.modificationReasonType === 'designer'">设计师主动优化</span>
-                <span class="reason-text" *ngIf="event.modificationReasonType === 'custom'">{{ event.modificationCustomReason }}</span>
-              </div>
-              <div class="reason-notes" *ngIf="event.reasonNotes">
-                <svg viewBox="0 0 24 24" width="12" height="12" fill="currentColor">
-                  <path d="M20 2H4c-1.1 0-1.99.9-1.99 2L2 22l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-7 9h-2V5h2v6zm0 4h-2v-2h2v2z"/>
-                </svg>
-                备注:{{ event.reasonNotes }}
+            <!-- 如果是决策卡片,显示决策提示(在“小图/决策”主视图下隐藏,由右侧按钮承载) -->
+            <div class="decision-prompt" *ngIf="(event.eventType === 'decision_needed' || event.statusType === 'stagnant') && urgentEventCategoryFilter !== 'review'">
+              <span class="text-xs text-slate-500 block mt-1">小图发送已久,请确认当前状态:</span>
+              <div class="decision-group">
+                <button class="decision-btn btn-yes" (click)="onMarkEventAsModification(event, $event)">
+                  <svg viewBox="0 0 24 24" width="12" height="12" fill="currentColor"><path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"/></svg>
+                  客户已反馈(转对图)
+                </button>
+                <button class="decision-btn btn-no" (click)="onMarkEventAsStagnant(event, $event)">
+                  <svg viewBox="0 0 24 24" width="12" height="12" fill="currentColor"><path d="M6 19h4V5H6v14zm8-14v14h4V5h-4z"/></svg>
+                  未回复(转停滞)
+                </button>
               </div>
             </div>
-            
-            <!-- 项目信息 -->
-            <div class="task-meta">
+
+            <!-- 项目信息 -->
+            <div class="event-meta">
               <span class="project-info">
-                <svg viewBox="0 0 24 24" width="12" height="12" fill="currentColor">
-                  <path d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z"/>
-                </svg>
-                项目: {{ event.projectName }}
+                <svg viewBox="0 0 24 24" width="12" height="12" fill="currentColor"><path d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z"/></svg>
+                {{ event.projectName }}
               </span>
               <span class="designer-info" *ngIf="event.designerName">
-                <svg viewBox="0 0 24 24" width="12" height="12" fill="currentColor">
-                  <path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"/>
-                </svg>
-                设计师: {{ event.designerName }}
+                <svg viewBox="0 0 24 24" width="12" height="12" fill="currentColor"><path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"/></svg>
+                {{ event.designerName }}
               </span>
-            </div>
-            
-            <!-- 底部信息行 -->
-            <div class="task-footer">
-              <span class="deadline-info" [class.overdue]="event.overdueDays && event.overdueDays > 0">
-                <svg viewBox="0 0 24 24" width="12" height="12" fill="currentColor">
-                  <path d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8zm.5-13H11v6l5.25 3.15.75-1.23-4.5-2.67z"/>
-                </svg>
-                截止: {{ event.deadline | date:'MM-dd HH:mm' }}
-                <span class="overdue-label" *ngIf="event.overdueDays && event.overdueDays > 0">(逾期{{ event.overdueDays }}天)</span>
-                <span class="upcoming-label" *ngIf="event.overdueDays && event.overdueDays < 0">(还剩{{ -event.overdueDays }}天)</span>
-                <span class="today-label" *ngIf="!event.overdueDays">(今天)</span>
-              </span>
-              
-              <span class="completion-info" *ngIf="event.completionRate !== undefined">
-                <svg viewBox="0 0 24 24" width="12" height="12" fill="currentColor">
-                  <path d="M9 16.2L4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4L9 16.2z"/>
-                </svg>
-                完成率: {{ event.completionRate }}%
+              <span class="deadline-info" *ngIf="event.statusType !== 'stagnant'">
+                 截止: {{ event.deadline | date:'MM-dd HH:mm' }}
               </span>
             </div>
           </div>
           
           <!-- 右侧操作按钮 -->
-          <div class="task-actions">
-            <button 
-              class="btn-action btn-muted" 
-              *ngIf="event.allowConfirmOnTime"
-              (click)="onConfirmEventOnTime(event)"
-            >
-              可按时交付
-            </button>
-            <button 
-              class="btn-action btn-stagnant" 
-              *ngIf="!event.isMarkedAsStagnant"
-              (click)="onMarkEventAsStagnant(event, $event)"
-            >
-              标记停滞
-            </button>
-            <button 
-              class="btn-action btn-modification" 
-              *ngIf="!event.isMarkedAsModification"
-              (click)="onMarkEventAsModification(event, $event)"
-            >
-              标记改图
-            </button>
-            <button 
-              class="btn-action btn-resolve" 
-              *ngIf="event.allowMarkHandled"
-              (click)="onResolveUrgentEvent(event)"
-            >
-              事件已处理
-            </button>
-            <button 
-              class="btn-action btn-todo" 
-              *ngIf="event.allowCreateTodo"
-              (click)="onCreateTodoFromEvent(event)"
-            >
-              创建代办
-            </button>
-            <button 
-              class="btn-action btn-view" 
-              (click)="onProjectClickHandler(event.projectId)"
-              title="查看项目">
-              <svg viewBox="0 0 24 24" width="14" height="14" fill="currentColor">
-                <path d="M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5zM12 17c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z"/>
-              </svg>
-              查看项目
-            </button>
+          <div class="event-actions" [class.small-view-actions]="urgentEventCategoryFilter === 'review' && isSmallImageEvent(event)">
+            <!-- 小图/决策视图下的专用按钮组 -->
+            <ng-container *ngIf="urgentEventCategoryFilter === 'review' && isSmallImageEvent(event); else defaultEventActions">
+              <!-- 临近截止 -->
+              <ng-container *ngIf="getSmallViewType(event) === 'nearDeadline'">
+                <button class="btn-action btn-success" (click)="onConfirmEventOnTime(event)">
+                  可以按时交付(隐藏本条)
+                </button>
+                <button class="btn-action btn-primary" (click)="onCreateTodoFromEvent(event)">
+                  有风险,需要重点关注
+                </button>
+              </ng-container>
+
+              <!-- 对图期逾期 -->
+              <ng-container *ngIf="getSmallViewType(event) === 'overdue'">
+                <button class="btn-action btn-success" (click)="onResolveUrgentEvent(event)">
+                  已完成/售后
+                </button>
+                <button class="btn-action btn-primary" (click)="onMarkEventAsModification(event, $event)">
+                  客户反馈·转改图
+                </button>
+                <button class="btn-action btn-default" (click)="onMarkEventAsStagnant(event, $event)">
+                  未回复·转停滞
+                </button>
+                <button class="btn-action btn-default" (click)="onCreateTodoFromEvent(event)">
+                  创建跟进代办
+                </button>
+              </ng-container>
+
+              <!-- 停滞期项目 -->
+              <ng-container *ngIf="getSmallViewType(event) === 'stagnant'">
+                <button class="btn-action btn-success" (click)="onMarkEventAsModification(event, $event)">
+                  客户已反馈 · 转入对图期
+                </button>
+                <button class="btn-action btn-primary" (click)="onMarkEventAsStagnant(event, $event)">
+                  仍未反馈 · 继续停滞
+                </button>
+                <button class="btn-action btn-default" (click)="onResolveUrgentEvent(event)">
+                  不再跟进 / 关闭事件
+                </button>
+              </ng-container>
+            </ng-container>
+
+            <!-- 默认事件操作按钮(非小图视图,保持原逻辑) -->
+            <ng-template #defaultEventActions>
+              <button class="btn-action btn-primary" *ngIf="event.statusType === 'overdue' && getEventCategory(event) !== 'decision'" 
+                      title="催办" (click)="onProjectClickHandler(event.projectId)">
+                <svg viewBox="0 0 24 24" width="14" height="14" fill="currentColor"><path d="M2.01 21L23 12 2.01 3 2 10l15 2-15 2z"/></svg>
+                催办
+              </button>
+              
+              <button class="btn-action btn-success" *ngIf="event.statusType === 'dueSoon'" 
+                      (click)="onConfirmEventOnTime(event)">
+                <svg viewBox="0 0 24 24" width="14" height="14" fill="currentColor"><path d="M9 16.2L4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4L9 16.2z"/></svg>
+                按时交付
+              </button>
+              
+              <button class="btn-action btn-default" (click)="onProjectClickHandler(event.projectId)">
+                查看项目
+              </button>
+            </ng-template>
           </div>
+
         </div>
       </div>
     </div>

+ 375 - 149
src/app/pages/team-leader/dashboard/components/todo-section/todo-section.component.scss

@@ -433,7 +433,7 @@
   // 双栏容器
   .todo-dual-columns {
     display: grid;
-    grid-template-columns: 1fr 1fr;
+    grid-template-columns: 2fr 3fr; // 左右宽度比例 2:3
     gap: 24px;
     margin-top: 20px;
   }
@@ -448,9 +448,8 @@
     overflow: hidden;
     
     .column-header {
-      padding: 16px;
-      background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
-      border-bottom: 1px solid #e5e7eb;
+      padding: 16px 20px;
+      border-bottom: none; // 移除底部边框,使用纯色块
       
       h3 {
         margin: 0 0 4px 0;
@@ -466,14 +465,15 @@
         }
         
         .task-count {
-          font-size: 13px;
-          font-weight: 500;
+          font-size: 12px;
+          font-weight: 600;
           padding: 2px 8px;
           background: rgba(255, 255, 255, 0.2);
           border-radius: 12px;
+          color: white;
           
           &.urgent {
-            background: rgba(239, 68, 68, 0.9);
+            background: rgba(255, 255, 255, 0.3);
             animation: pulse-glow 2s infinite;
           }
         }
@@ -481,216 +481,442 @@
       
       .column-subtitle {
         font-size: 12px;
-        color: rgba(255, 255, 255, 0.8);
+        color: rgba(255, 255, 255, 0.85);
         margin-left: 26px;
+        font-weight: 400;
       }
     }
     
     // 左栏特定样式(待办问题)
     &.todo-column-issues {
       .column-header {
-        background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+        background: #8b5cf6; // 紫色纯色背景
       }
     }
     
     // 右栏特定样式(紧急事件)
     &.todo-column-urgent {
+      border-top: none; // 移除之前的顶条
+      
       .column-header {
-        background: linear-gradient(135deg, #f97316 0%, #dc2626 100%);
+        background: #f97316; // 橙色纯色背景
       }
       
       // 标签过滤器样式
-      .tag-filter-bar {
+      .filter-tabs {
         display: flex;
         gap: 12px;
-        padding: 16px;
-        background: #fff7ed;
-        border-bottom: 1px solid #fed7aa;
+        padding: 12px 20px 16px; // 增加底部 padding,避免滚动条遮挡
+        background: white;
+        border-bottom: 1px solid #f3f4f6;
         overflow-x: auto;
+        align-items: center;
         
-        .tag-button {
+        // 隐藏滚动条但保持功能 (可选)
+        &::-webkit-scrollbar {
+          height: 4px;
+        }
+        &::-webkit-scrollbar-thumb {
+          background: rgba(0,0,0,0.1);
+          border-radius: 2px;
+        }
+        
+        .filter-tab {
+          padding: 6px 16px;
+          border-radius: 20px; // 胶囊形状
+          font-size: 13px;
+          font-weight: 500;
+          color: #64748b;
+          background: #f1f5f9;
+          border: 1px solid transparent;
+          cursor: pointer;
           display: flex;
           align-items: center;
-          gap: 8px;
-          padding: 8px 16px;
-          background: white;
-          border: 1px solid #fed7aa;
-          border-radius: 20px;
-          font-size: 14px;
-          color: #7c2d12;
-          cursor: pointer;
+          gap: 6px;
           transition: all 0.2s;
           white-space: nowrap;
-          font-weight: 500;
           
           &:hover {
-            background: #fff2cc;
-            transform: translateY(-1px);
-            box-shadow: 0 2px 4px rgba(249, 115, 22, 0.1);
+            background: #e2e8f0;
+            color: #475569;
           }
           
           &.active {
-            background: #f97316;
-            color: white;
-            border-color: #ea580c;
-            box-shadow: 0 2px 4px rgba(249, 115, 22, 0.3);
+            background: #fff7ed;
+            color: #ea580c;
+            border-color: #fdba74;
+            font-weight: 600;
             
-            .tag-count {
-              background: rgba(255,255,255,0.25);
-              color: white;
-            }
+            .count-badge { background: #fed7aa; color: #9a3412; }
           }
           
-          .tag-icon {
-            font-size: 16px;
+          // 客户类 - 红色
+          &.active-customer {
+            background: #fef2f2; 
+            color: #dc2626;
+            border-color: #fecaca;
+             .count-badge { background: #fecaca; color: #991b1b; }
           }
           
-          .tag-count {
-            background: #fed7aa;
-            color: #9a3412;
-            padding: 2px 8px;
-            border-radius: 12px;
-            font-size: 12px;
-            font-weight: 600;
-            min-width: 20px;
-            text-align: center;
+          // 阶段类 - 蓝色
+          &.active-phase {
+            background: #eff6ff; 
+            color: #2563eb;
+            border-color: #bfdbfe;
+             .count-badge { background: #dbeafe; color: #1e40af; }
+          }
+          
+          // 交付类 - 紫色
+          &.active-delivery {
+            background: #faf5ff; 
+            color: #9333ea;
+            border-color: #e9d5ff;
+             .count-badge { background: #f3e8ff; color: #6b21a8; }
+          }
+
+          .count-badge {
+            background: rgba(0,0,0,0.05);
+            padding: 1px 6px;
+            border-radius: 10px;
+            font-size: 11px;
+            transition: all 0.2s;
           }
         }
       }
-      
-      // 紧急事件特定样式
-      .urgent-item {
-        background: #fff8f8;
-        border-left-width: 4px;
-        
-        &[data-urgency="critical"] {
-          border-left-color: #dc2626;
-          background: #fef2f2;
-        }
+
+      // 二级筛选 (阶段)
+      .sub-filters {
+        padding: 8px 20px;
+        background: #fff7ed;
+        display: flex;
+        gap: 8px;
+        align-items: center;
+        border-bottom: 1px solid #fed7aa;
+        animation: slideDown 0.2s ease-out;
         
-        &[data-urgency="high"] {
-          border-left-color: #f97316;
-          background: #fff7ed;
+        .sub-label {
+          font-size: 12px;
+          font-weight: 600;
+          color: #ea580c;
+          margin-right: 8px;
         }
         
-        &[data-urgency="medium"] {
-          border-left-color: #f59e0b;
-          background: #fffbeb;
+        .sub-chip {
+          font-size: 12px;
+          padding: 2px 12px;
+          border-radius: 12px;
+          cursor: pointer;
+          color: #c2410c;
+          background: rgba(255, 255, 255, 0.5);
+          border: 1px solid transparent;
+          transition: all 0.2s;
+          
+          &:hover { background: white; }
+          
+          &.active {
+            background: #ea580c;
+            color: white;
+            font-weight: 600;
+            box-shadow: 0 2px 4px rgba(234, 88, 12, 0.2);
+          }
         }
       }
-      
-      .urgency-indicator {
-        width: 4px;
-        
-        &[data-urgency="critical"] {
-          background: linear-gradient(180deg, #dc2626 0%, #b91c1c 100%);
-          box-shadow: 0 0 10px rgba(220, 38, 38, 0.5);
-        }
-        
-        &[data-urgency="high"] {
-          background: linear-gradient(180deg, #f97316 0%, #ea580c 100%);
-        }
-        
-        &[data-urgency="medium"] {
-          background: linear-gradient(180deg, #f59e0b 0%, #d97706 100%);
+      .small-view-bar {
+        padding: 8px 20px;
+        background: #f9fafb;
+        display: flex;
+        align-items: center;
+        gap: 8px;
+        border-bottom: 1px solid #e5e7eb;
+        font-size: 12px;
+        color: #64748b;
+        overflow-x: auto;
+
+        .small-view-label {
+          font-weight: 600;
+          margin-right: 4px;
+          flex-shrink: 0;
         }
-      }
-      
-      .badge-urgency {
-        &[data-urgency="critical"] {
-          background: #fee2e2;
-          color: #dc2626;
-          font-weight: 700;
+
+        .small-view-chip {
+          display: inline-flex;
+          align-items: center;
+          gap: 4px;
+          padding: 4px 12px;
+          border-radius: 999px;
+          border: 1px solid #e2e8f0;
+          background: #ffffff;
+          color: #64748b;
+          font-size: 12px;
+          cursor: pointer;
+          flex-shrink: 0;
+          transition: all 0.2s;
+          white-space: nowrap;
         }
-        
-        &[data-urgency="high"] {
-          background: #ffedd5;
-          color: #f97316;
-          font-weight: 600;
+
+        .small-view-chip.active {
+          background: #0f172a;
+          color: #f9fafb;
+          border-color: #0f172a;
         }
-        
-        &[data-urgency="medium"] {
-          background: #fef3c7;
-          color: #f59e0b;
+
+        .chip-count {
+          padding: 0 6px;
+          border-radius: 999px;
+          background: rgba(15, 23, 42, 0.15);
+          font-size: 11px;
         }
       }
       
-      .badge-event-type {
-        background: #dbeafe;
-        color: #1e40af;
+      // 紧急事件列表容器
+      .urgent-list {
+        padding: 16px 20px;
       }
       
-      .badge-status {
-        padding: 2px 6px;
-        border-radius: 4px;
-        font-size: 11px;
+      // 事件卡片
+      .event-card {
+        background: white;
+        border-radius: 8px;
+        padding: 20px; 
+        margin-bottom: 16px;
+        border: 1px solid #e5e7eb;
+        display: flex;
+        align-items: stretch; 
+        gap: 16px; // 减小间距,避免水平溢出
+        position: relative;
+        height: auto; // 确保高度自动适应
+        flex-shrink: 0; // 关键:禁止卡片在滚动列表中被压缩高度
+        transition: all 0.2s;
+        min-height: 120px; 
+        box-shadow: 0 1px 2px rgba(0,0,0,0.05);
         
-        &.overdue {
-          background: #fee2e2;
-          color: #991b1b;
+        &:hover {
+          border-color: #cbd5e1;
+          box-shadow: 0 4px 12px rgba(0,0,0,0.08);
+          transform: translateY(-1px);
         }
         
-        &.upcoming {
-          background: #ffedd5;
-          color: #9a3412;
+        /* Color Lines */
+        .card-line {
+          position: absolute;
+          left: 0;
+          top: 0;
+          bottom: 0;
+          width: 4px;
+          border-top-left-radius: 8px;
+          border-bottom-left-radius: 8px;
+          
+          &[data-category="customer"] { background: #ef4444; }
+          &[data-category="review"] { background: #f97316; } 
+          &[data-category="phase"] { background: #3b82f6; }
+          &[data-category="delivery"] { background: #a855f7; }
         }
         
-        &.stagnant {
-          background: #f3f4f6;
-          color: #4b5563;
+        .event-main {
+          flex: 1;
+          display: flex;
+          flex-direction: column;
+          justify-content: flex-start;
+          min-width: 0;
+          padding-left: 8px;
+          padding-top: 4px;
+          padding-bottom: 2px;
         }
         
-        &.customer {
-          background: #e0e7ff;
-          color: #4338ca;
-        }
-      }
-      
-      .task-description {
-        font-size: 13px;
-        color: #6b7280;
-        margin: 8px 0;
-        line-height: 1.5;
-      }
-      
-      .followup-tip {
-        font-size: 12px;
-        color: #b91c1c;
-        background: #fef2f2;
-        padding: 4px 8px;
-        border-radius: 4px;
-        margin-bottom: 8px;
-        display: inline-block;
-      }
-      
-      .deadline-info {
-        &.overdue {
-          color: #dc2626;
-          font-weight: 600;
+        .event-header {
+          display: flex;
+          align-items: center;
+          gap: 10px; 
+          margin-bottom: 10px; 
+          flex-wrap: nowrap;
+          flex-shrink: 0; // 防止标题被压缩
+          
+          .event-title {
+            font-size: 16px; 
+            font-weight: 700;
+            color: #1e293b;
+            white-space: normal; 
+            line-height: 1.4;
+            display: -webkit-box;
+            -webkit-line-clamp: 2; 
+            -webkit-box-orient: vertical;
+            overflow: hidden;
+            text-overflow: ellipsis;
+            max-width: 480px; 
+            
+            &.text-red-700 { color: #b91c1c; }
+          }
+          
+          .event-tag {
+            flex-shrink: 0;
+            font-size: 11px;
+            padding: 2px 8px;
+            border-radius: 4px;
+            font-weight: 500;
+            background: #f1f5f9;
+            color: #475569;
+            white-space: nowrap;
+          }
+          
+          .badge-status {
+            flex-shrink: 0;
+            font-size: 11px; 
+            padding: 2px 8px;
+            border-radius: 4px;
+            font-weight: 600;
+            margin-left: auto;
+            white-space: nowrap;
+            
+            &.overdue { background: #fef2f2; color: #ef4444; }
+            &.upcoming { background: #fff7ed; color: #f97316; }
+          }
         }
         
-        .overdue-label {
-          color: #dc2626;
-          font-weight: 600;
+        .event-desc {
+          font-size: 13px;
+          color: #334155; 
+          margin-bottom: 12px; 
+          line-height: 1.6;
+          width: 100%; 
+          display: -webkit-box;
+          -webkit-line-clamp: 3; 
+          -webkit-box-orient: vertical;
+          overflow: hidden;
+          overflow-wrap: anywhere; 
+          flex-shrink: 0; // 防止描述被压缩
         }
-        
-        .upcoming-label {
-          color: #f97316;
+
+        .event-meta {
+           margin-top: 12px; // 使用固定间距代替 auto,防止布局计算异常
+           display: flex;
+           align-items: center;
+           gap: 12px;
+           font-size: 12px;
+           color: #64748b;
+           flex-shrink: 0; 
+           
+           .project-info, .designer-info, .deadline-info {
+             display: flex;
+             align-items: center;
+             gap: 4px;
+             white-space: nowrap;
+             overflow: hidden;
+             text-overflow: ellipsis;
+             max-width: 100%;
+           }
+           
+           svg { opacity: 0.7; }
+        }
+
+        // 决策卡片样式优化
+        .decision-prompt {
+          margin-top: 8px;
+          margin-bottom: 12px; // 增加底部间距
+          width: 100%;
+          flex-shrink: 0; // 防止决策按钮被压缩
+          
+          .text-xs {
+             display: none; 
+          }
+          
+          .decision-group {
+            display: flex;
+            gap: 12px;
+            margin-top: 4px;
+            
+            .decision-btn {
+              flex: 1;
+              padding: 8px 8px; // 减少水平内边距
+              border-radius: 6px;
+              font-size: 13px;
+              font-weight: 600;
+              cursor: pointer;
+              display: flex;
+              align-items: center;
+              justify-content: center;
+              gap: 6px;
+              border: 1px solid transparent;
+              transition: all 0.2s;
+              min-width: 0; // 允许缩小
+              overflow: hidden; // 隐藏溢出
+              white-space: nowrap; 
+              text-overflow: ellipsis; // 超出显示省略号
+              
+              &.btn-yes {
+                background: #f0fdf4;
+                color: #166534;
+                border-color: #bbf7d0;
+                &:hover { background: #dcfce7; }
+              }
+              
+              &.btn-no {
+                background: #fef2f2;
+                color: #991b1b;
+                border-color: #fecaca;
+                &:hover { background: #fee2e2; }
+              }
+            }
+          }
         }
         
-        .today-label {
-          color: #f59e0b;
-          font-weight: 600;
+        /* Action Buttons */
+        .event-actions {
+          display: flex;
+          flex-direction: column;
+          justify-content: center;
+          gap: 8px;
+          min-width: 110px; 
+          border-left: 1px dashed #e2e8f0;
+          padding-left: 16px;
+          flex-shrink: 0;
+          
+          .btn-action {
+            width: 100%;
+            padding: 7px 12px; 
+            border-radius: 6px;
+            font-size: 12px;
+            font-weight: 500;
+            cursor: pointer;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            gap: 4px;
+            border: 1px solid transparent;
+            transition: all 0.15s;
+            white-space: nowrap;
+            
+            &.btn-primary {
+              background: #fff7ed;
+              color: #c2410c;
+              border-color: #ffedd5;
+              &:hover { background: #ffedd5; }
+            }
+            
+            &.btn-success {
+              background: #f0fdf4;
+              color: #15803d;
+              border-color: #dcfce7;
+              &:hover { background: #dcfce7; }
+            }
+            
+            &.btn-default {
+              background: white;
+              color: #64748b;
+              border-color: #e2e8f0;
+              &:hover { background: #f8fafc; border-color: #cbd5e1; }
+            }
+          }
         }
       }
-      
-      .completion-info {
-        font-weight: 500;
-      }
     }
   }
 }
 
+@keyframes slideDown {
+  from { transform: translateY(-10px); opacity: 0; }
+  to { transform: translateY(0); opacity: 1; }
+}
+
 // 🆕 紧急事件脉冲动画
 @keyframes pulse-glow {
   0%, 100% {

+ 139 - 19
src/app/pages/team-leader/dashboard/components/todo-section/todo-section.component.ts

@@ -32,7 +32,9 @@ export class TodoSectionComponent implements OnInit, OnDestroy {
   @Output() createTodoFromEvent = new EventEmitter<UrgentEvent>();
 
   filteredUrgentEventsList: UrgentEvent[] = [];
-  urgentEventTagFilter: 'all' | 'customer' | 'phase' | 'review' | 'delivery' = 'all';
+  urgentEventCategoryFilter: 'all' | 'customer' | 'phase' | 'review' | 'delivery' = 'all';
+  smallViewFilter: 'all' | 'nearDeadline' | 'overdue' | 'stagnant' = 'all';
+  activePhaseFilter: string | null = null; // For phase sub-filters (modeling, rendering, etc.)
   
   private urgentEventsCache = new Map<string, UrgentEvent[]>();
   
@@ -63,40 +65,157 @@ export class TodoSectionComponent implements OnInit, OnDestroy {
 
   // 过滤紧急事件
   filterUrgentEventsByTag(tag: 'all' | 'customer' | 'phase' | 'review' | 'delivery'): void {
-    if (this.urgentEventTagFilter === tag) return;
-    this.urgentEventTagFilter = tag;
+    if (this.urgentEventCategoryFilter === tag) return;
+    this.urgentEventCategoryFilter = tag;
+    this.activePhaseFilter = null; // Reset sub-filter when changing main tab
     this.filterUrgentEvents();
   }
 
-  private filterUrgentEvents(): void {
-    if (this.urgentEventTagFilter === 'all') {
-      this.filteredUrgentEventsList = [...this.urgentEvents];
-      return;
+  togglePhaseFilter(phaseType: string): void {
+    if (this.activePhaseFilter === phaseType) {
+      this.activePhaseFilter = null;
+    } else {
+      this.activePhaseFilter = phaseType;
     }
+    this.filterUrgentEvents(); // Re-filter
+  }
 
-    // Check cache
-    if (this.urgentEventsCache.has(this.urgentEventTagFilter)) {
-      this.filteredUrgentEventsList = this.urgentEventsCache.get(this.urgentEventTagFilter)!;
+  setSmallViewFilter(view: 'all' | 'nearDeadline' | 'overdue' | 'stagnant'): void {
+    if (this.smallViewFilter === view) {
       return;
     }
+    this.smallViewFilter = view;
+    this.filterUrgentEvents();
+  }
 
+  private filterUrgentEvents(): void {
     let filtered: UrgentEvent[] = [];
     
-    if (this.urgentEventTagFilter === 'customer') {
+    // 1. Primary Category Filter
+    if (this.urgentEventCategoryFilter === 'all') {
+      filtered = [...this.urgentEvents];
+    } else if (this.urgentEventCategoryFilter === 'customer') {
       filtered = this.urgentEvents.filter(e => this.getEventCategory(e) === 'customer');
-    } else if (this.urgentEventTagFilter === 'phase') {
+    } else if (this.urgentEventCategoryFilter === 'phase') {
       filtered = this.urgentEvents.filter(e => e.eventType === 'phase_deadline');
-    } else if (this.urgentEventTagFilter === 'review') {
-      filtered = this.urgentEvents.filter(e => e.eventType === 'review');
-    } else if (this.urgentEventTagFilter === 'delivery') {
+    } else if (this.urgentEventCategoryFilter === 'review') {
+      filtered = this.urgentEvents.filter(e => this.isSmallImageEvent(e));
+    } else if (this.urgentEventCategoryFilter === 'delivery') {
       filtered = this.urgentEvents.filter(e => e.eventType === 'delivery');
     }
 
-    // Update cache
-    this.urgentEventsCache.set(this.urgentEventTagFilter, filtered);
+    // 2. Sub-filter for Phases
+    if (this.activePhaseFilter && this.urgentEventCategoryFilter === 'phase') {
+       filtered = filtered.filter(e => e.phaseType === this.activePhaseFilter);
+    }
+
+    if (this.urgentEventCategoryFilter === 'review') {
+      filtered = this.applySmallViewFilter(filtered);
+    }
+
+    // 3. Priority Sorting: Customer > Phase > Review > Delivery
+    // Within same category, sort by urgencyLevel (critical > high > medium) or deadline
+    filtered.sort((a, b) => {
+      const scoreA = this.calculatePriorityScore(a);
+      const scoreB = this.calculatePriorityScore(b);
+      return scoreB - scoreA; // Descending order
+    });
+
     this.filteredUrgentEventsList = filtered;
   }
 
+  private applySmallViewFilter(events: UrgentEvent[]): UrgentEvent[] {
+    if (this.smallViewFilter === 'all') {
+      return events;
+    }
+    return events.filter(event => {
+      const type = this.getSmallViewType(event);
+      if (this.smallViewFilter === 'nearDeadline') {
+        return type === 'nearDeadline';
+      }
+      if (this.smallViewFilter === 'overdue') {
+        return type === 'overdue';
+      }
+      if (this.smallViewFilter === 'stagnant') {
+        return type === 'stagnant';
+      }
+      return true;
+    });
+  }
+
+  getSmallViewCount(): number {
+    if (!this.urgentEvents || this.urgentEvents.length === 0) {
+      return 0;
+    }
+    return this.urgentEvents.filter(event => this.isSmallImageEvent(event)).length;
+  }
+
+  isSmallImageEvent(event: UrgentEvent): boolean {
+    const labels = event.labels || [];
+
+    if (event.eventType === 'review' || event.eventType === 'decision_needed') {
+      return true;
+    }
+
+    if (labels.includes('对图期') || labels.includes('停滞期')) {
+      return true;
+    }
+
+    if (event.customerIssueType === 'feedback_pending') {
+      return true;
+    }
+
+    return false;
+  }
+
+  getSmallViewType(event: UrgentEvent): 'nearDeadline' | 'overdue' | 'stagnant' | 'other' {
+    const labels = event.labels || [];
+    const isStagnant =
+      event.statusType === 'stagnant' ||
+      labels.includes('停滞期') ||
+      (typeof event.stagnationDays === 'number' && event.stagnationDays >= 7);
+
+    if (isStagnant) {
+      return 'stagnant';
+    }
+
+    const isReviewDeadline = event.eventType === 'review';
+    const isReviewFollowup =
+      event.eventType === 'decision_needed' ||
+      labels.includes('对图期') ||
+      event.customerIssueType === 'feedback_pending';
+
+    if ((isReviewDeadline || isReviewFollowup) && event.statusType === 'overdue') {
+      return 'overdue';
+    }
+    if ((isReviewDeadline || isReviewFollowup) && event.statusType === 'dueSoon') {
+      return 'nearDeadline';
+    }
+
+    return 'other';
+  }
+
+  private calculatePriorityScore(event: UrgentEvent): number {
+    let score = 0;
+    
+    // Base Category Score (Higher = More Important)
+    const category = this.getEventCategory(event);
+    if (category === 'customer') score += 1000;
+    else if (event.eventType === 'decision_needed') score += 900; // High priority for decision
+    else if (category === 'phase') score += 800;
+    else if (category === 'review') score += 600;
+    else if (category === 'delivery') score += 400;
+    
+    // Urgency Modifier
+    if (event.urgencyLevel === 'critical') score += 50;
+    if (event.urgencyLevel === 'high') score += 30;
+    
+    // Overdue Modifier
+    if (event.statusType === 'overdue') score += 20;
+    
+    return score;
+  }
+
   getTagCount(tag: string): number {
     if (tag === 'all') return this.urgentEvents.length;
     
@@ -105,7 +224,7 @@ export class TodoSectionComponent implements OnInit, OnDestroy {
     } else if (tag === 'phase') {
       return this.urgentEvents.filter(e => e.eventType === 'phase_deadline').length;
     } else if (tag === 'review') {
-      return this.urgentEvents.filter(e => e.eventType === 'review').length;
+      return this.urgentEvents.filter(e => this.isSmallImageEvent(e)).length;
     } else if (tag === 'delivery') {
       return this.urgentEvents.filter(e => e.eventType === 'delivery').length;
     }
@@ -115,10 +234,11 @@ export class TodoSectionComponent implements OnInit, OnDestroy {
   getEventCategory(event: UrgentEvent): string {
     if (event.category) return event.category;
     
-    // Fallback logic if category is missing
+    // Fallback logic
     if (event.eventType === 'customer_alert' || event.title.includes('客户') || event.description.includes('客户')) {
       return 'customer';
     }
+    if (event.eventType === 'decision_needed') return 'review'; // Group decision with review for now or separate
     if (event.eventType === 'review') return 'review';
     if (event.eventType === 'delivery') return 'delivery';
     if (event.eventType === 'phase_deadline') return 'phase';

+ 20 - 21
src/app/pages/team-leader/dashboard/dashboard.model.ts

@@ -86,39 +86,38 @@ export interface UrgentEvent {
   id: string;
   title: string;
   description: string;
-  eventType: 'review' | 'delivery' | 'phase_deadline' | 'customer_alert'; // 事件类型
-  phaseName?: string; // 阶段名称(如果是阶段截止)
-  deadline: Date; // 截止时间
+  eventType: 'review' | 'delivery' | 'phase_deadline' | 'customer_alert' | 'decision_needed'; // Added decision_needed
+  phaseName?: string;
+  phaseType?: 'modeling' | 'soft_fitting' | 'rendering' | 'post_processing' | 'sketch' | 'construction'; // New detailed phase types
+  deadline: Date;
   projectId: string;
   projectName: string;
   designerName?: string;
-  urgencyLevel: 'critical' | 'high' | 'medium'; // 紧急程度
-  overdueDays?: number; // 逾期天数(负数表示还有几天)
-  completionRate?: number; // 完成率(0-100)
-  category?: 'customer' | 'phase' | 'review' | 'delivery';
-  statusType?: 'dueSoon' | 'overdue' | 'stagnant' | 'modification';
+  urgencyLevel: 'critical' | 'high' | 'medium';
+  overdueDays?: number;
+  completionRate?: number;
+  category?: 'customer' | 'phase' | 'review' | 'delivery' | 'decision'; // Added decision
+  statusType?: 'dueSoon' | 'overdue' | 'stagnant' | 'modification' | 'completed';
   followUpNeeded?: boolean;
   allowConfirmOnTime?: boolean;
   allowMarkHandled?: boolean;
   allowCreateTodo?: boolean;
   stagnationDays?: number;
-  customerIssueType?: 'feedback_pending' | 'complaint' | 'idle';
+  customerIssueType?: 'feedback_pending' | 'complaint' | 'idle' | 'inappropriate_speech'; // Added inappropriate_speech
   labels?: string[];
   isMuted?: boolean;
   
   // 🆕 停滞/改图原因相关字段
-  isMarkedAsStagnant?: boolean; // 是否已标记为停滞
-  isMarkedAsModification?: boolean; // 是否已标记为改图
-  stagnationReasonType?: 'designer' | 'customer' | 'custom'; // 停滞原因类型
-  stagnationCustomReason?: string; // 自定义停滞原因
-  modificationReasonType?: 'designer' | 'customer' | 'custom'; // 改图原因类型
-  modificationCustomReason?: string; // 自定义改图原因
-  estimatedResumeDate?: Date; // 预计恢复时间
-  reasonNotes?: string; // 备注说明
-  markedAt?: Date; // 标记时间
-  markedBy?: string; // 标记人
-  
-  // 🆕 优先级排序权重(用于排序,数值越大优先级越高)
+  isMarkedAsStagnant?: boolean;
+  isMarkedAsModification?: boolean;
+  stagnationReasonType?: 'designer' | 'customer' | 'custom';
+  stagnationCustomReason?: string;
+  modificationReasonType?: 'designer' | 'customer' | 'custom';
+  modificationCustomReason?: string;
+  estimatedResumeDate?: Date;
+  reasonNotes?: string;
+  markedAt?: Date;
+  markedBy?: string;
   priorityWeight?: number;
 }
 

+ 5 - 4
src/app/pages/team-leader/dashboard/interfaces.ts

@@ -90,8 +90,9 @@ export interface UrgentEvent {
   id: string;
   title: string;
   description: string;
-  eventType: 'review' | 'delivery' | 'phase_deadline' | 'customer_alert';
+  eventType: 'review' | 'delivery' | 'phase_deadline' | 'customer_alert' | 'decision_needed'; // Added decision_needed
   phaseName?: string;
+  phaseType?: 'modeling' | 'soft_fitting' | 'rendering' | 'post_processing' | 'sketch' | 'construction'; // New detailed phase types
   deadline: Date;
   projectId: string;
   projectName: string;
@@ -99,14 +100,14 @@ export interface UrgentEvent {
   urgencyLevel: 'critical' | 'high' | 'medium';
   overdueDays?: number;
   completionRate?: number;
-  category?: 'customer' | 'phase' | 'review' | 'delivery';
-  statusType?: 'dueSoon' | 'overdue' | 'stagnant' | 'modification';
+  category?: 'customer' | 'phase' | 'review' | 'delivery' | 'decision'; // Added decision
+  statusType?: 'dueSoon' | 'overdue' | 'stagnant' | 'modification' | 'completed';
   followUpNeeded?: boolean;
   allowConfirmOnTime?: boolean;
   allowMarkHandled?: boolean;
   allowCreateTodo?: boolean;
   stagnationDays?: number;
-  customerIssueType?: 'feedback_pending' | 'complaint' | 'idle';
+  customerIssueType?: 'feedback_pending' | 'complaint' | 'idle' | 'inappropriate_speech'; // Added inappropriate_speech
   labels?: string[];
   isMuted?: boolean;
   

+ 13 - 4
src/app/pages/team-leader/services/urgent-event.service.ts

@@ -34,8 +34,8 @@ export class UrgentEventService {
     // 辅助函数:解析事件分类
     const resolveCategory = (
       eventType: UrgentEvent['eventType'],
-      category?: 'customer' | 'phase' | 'review' | 'delivery'
-    ): 'customer' | 'phase' | 'review' | 'delivery' => {
+      category?: 'customer' | 'phase' | 'review' | 'delivery' | 'decision'
+    ): 'customer' | 'phase' | 'review' | 'delivery' | 'decision' => {
       if (category) return category;
       switch (eventType) {
         case 'phase_deadline':
@@ -44,6 +44,8 @@ export class UrgentEventService {
           return 'delivery';
         case 'customer_alert':
           return 'customer';
+        case 'decision_needed':
+          return 'review'; // Group decision with review as per UI requirement
         default:
           return 'review';
       }
@@ -321,11 +323,18 @@ export class UrgentEventService {
     // 1. 基础权重:按事件类别
     const categoryWeight: Record<string, number> = {
       'customer': 1000,      // 客户服务事件优先级最高
-      'phase': 800,          // 工作阶段事件次之
+      'decision': 900,       // 决策事件(小图已出无反馈)次之
+      'phase': 800,          // 工作阶段事件
       'review': 600,         // 小图截止(对图事件)
       'delivery': 400        // 整体交付延期优先级最低
     };
-    weight += categoryWeight[event.category || 'delivery'] || 400;
+    
+    // Special check for decision_needed event type if category is mapped to review
+    let baseWeight = categoryWeight[event.category || 'delivery'] || 400;
+    if (event.eventType === 'decision_needed') {
+      baseWeight = Math.max(baseWeight, 900);
+    }
+    weight += baseWeight;
     
     // 2. 紧急程度加成
     const urgencyBonus: Record<string, number> = {

+ 304 - 0
src/test/todo-list-categorized.html

@@ -0,0 +1,304 @@
+<!DOCTYPE html>
+<html lang="zh-CN">
+<head>
+  <meta charset="UTF-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1.0">
+  <title>智能待办清单 - 分类优化版</title>
+  <script src="https://cdn.tailwindcss.com"></script>
+  <script src="https://unpkg.com/lucide@latest"></script>
+  <style>
+    body { background-color: #f1f5f9; padding: 20px; color: #1e293b; font-family: sans-serif; }
+    
+    /* 双栏布局容器 */
+    .dashboard-grid {
+      display: grid;
+      grid-template-columns: 380px 1fr;
+      gap: 20px;
+      max-width: 1000px;
+      margin: 0 auto;
+      align-items: start;
+    }
+
+    .panel {
+      background: white;
+      border-radius: 12px;
+      box-shadow: 0 1px 3px rgba(0,0,0,0.05);
+      border: 1px solid #e2e8f0;
+      overflow: hidden;
+    }
+
+    .panel-header {
+      padding: 16px;
+      border-bottom: 1px solid #f1f5f9;
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      background: #fff;
+    }
+    .panel-title { font-weight: 700; font-size: 15px; color: #0f172a; display: flex; align-items: center; gap: 8px; }
+    
+    /* 左栏:待处理 (决策类) */
+    .action-list { padding: 12px; background: #f8fafc; min-height: 400px; }
+    
+    .action-card {
+      background: white;
+      padding: 14px;
+      border-radius: 10px;
+      margin-bottom: 10px;
+      border: 1px solid #e2e8f0;
+      position: relative;
+      transition: transform 0.2s;
+    }
+    .action-card:hover { transform: translateY(-1px); box-shadow: 0 4px 6px -1px rgba(0,0,0,0.05); }
+    .action-card.critical { border-left: 3px solid #ef4444; }
+    .action-card.decision { border-left: 3px solid #f59e0b; }
+
+    /* 右栏:预警监控 (逾期类) */
+    .monitor-container { padding: 0; }
+    
+    /* 顶部统计条 */
+    .monitor-stats {
+      display: flex;
+      gap: 1px;
+      background: #e2e8f0;
+      padding-bottom: 1px;
+    }
+    .stat-box {
+      flex: 1;
+      background: white;
+      padding: 12px;
+      text-align: center;
+      cursor: pointer;
+    }
+    .stat-box.active { background: #f8fafc; border-bottom: 2px solid #3b82f6; }
+    .stat-num { font-size: 18px; font-weight: 700; display: block; }
+    .stat-label { font-size: 11px; color: #64748b; }
+    .text-red { color: #ef4444; }
+    .text-orange { color: #f97316; }
+
+    /* 分类筛选器 */
+    .filter-bar {
+      padding: 10px 16px;
+      display: flex;
+      gap: 8px;
+      overflow-x: auto;
+      border-bottom: 1px dashed #e2e8f0;
+    }
+    .chip {
+      padding: 4px 10px;
+      border-radius: 16px;
+      font-size: 11px;
+      background: #f1f5f9;
+      color: #64748b;
+      cursor: pointer;
+      white-space: nowrap;
+      transition: all 0.2s;
+    }
+    .chip:hover { background: #e2e8f0; }
+    .chip.active { background: #eff6ff; color: #3b82f6; font-weight: 600; }
+
+    /* 列表项 */
+    .monitor-list { padding: 0; }
+    .monitor-item {
+      display: flex;
+      align-items: center;
+      padding: 12px 16px;
+      border-bottom: 1px solid #f1f5f9;
+    }
+    .monitor-item:last-child { border-bottom: none; }
+    
+    .item-left { flex: 1; }
+    .item-title { font-size: 13px; font-weight: 600; color: #334155; display: flex; align-items: center; gap: 6px; }
+    .item-sub { font-size: 11px; color: #94a3b8; margin-top: 2px; }
+    
+    .phase-badge {
+      font-size: 10px;
+      padding: 2px 6px;
+      border-radius: 4px;
+      background: #f1f5f9;
+      color: #64748b;
+    }
+    .phase-mod { background: #e0f2fe; color: #0284c7; } /* 建模 */
+    .phase-soft { background: #f0fdf4; color: #16a34a; } /* 软装 */
+    .phase-ren { background: #fefce8; color: #ca8a04; } /* 渲染 */
+    .phase-post { background: #f3e8ff; color: #7e22ce; } /* 后期 */
+
+    .overdue-tag {
+      font-size: 11px;
+      color: #ef4444;
+      font-weight: 500;
+      background: #fef2f2;
+      padding: 2px 8px;
+      border-radius: 10px;
+    }
+    .actions { opacity: 0; transition: opacity 0.2s; }
+    .monitor-item:hover .actions { opacity: 1; }
+
+    .btn-icon { padding: 4px; color: #94a3b8; border-radius: 4px; }
+    .btn-icon:hover { background: #f1f5f9; color: #3b82f6; }
+
+  </style>
+</head>
+<body>
+
+<div class="dashboard-grid">
+
+  <!-- 左栏:管理决策 (需组长介入) -->
+  <div class="panel">
+    <div class="panel-header">
+      <div class="panel-title"><i data-lucide="check-square" width="18"></i> 待处理 (决策/派单)</div>
+      <span class="text-xs bg-red-100 text-red-600 px-2 py-1 rounded-full font-bold">3</span>
+    </div>
+    <div class="action-list">
+      
+      <!-- 客户投诉 -->
+      <div class="action-card critical">
+        <div class="flex justify-between mb-2">
+          <span class="text-xs font-bold text-red-500 flex items-center gap-1">
+            <i data-lucide="alert-circle" width="12"></i> 客户投诉
+          </span>
+          <span class="text-xs text-slate-400">1小时前</span>
+        </div>
+        <div class="text-sm font-bold text-slate-700 mb-1">锦江上院-13号</div>
+        <div class="text-xs text-slate-500 mb-3">反馈:"发消息没人回,进度太慢"</div>
+        <div class="flex gap-2">
+          <button class="flex-1 py-1.5 bg-red-50 text-red-600 text-xs rounded hover:bg-red-100">安抚</button>
+          <button class="flex-1 py-1.5 bg-slate-100 text-slate-600 text-xs rounded hover:bg-slate-200">转客服</button>
+        </div>
+      </div>
+
+      <!-- 状态决策 -->
+      <div class="action-card decision">
+        <div class="flex justify-between mb-2">
+          <span class="text-xs font-bold text-amber-500 flex items-center gap-1">
+            <i data-lucide="git-branch" width="12"></i> 状态判断
+          </span>
+          <span class="text-xs text-slate-400">已发图3天</span>
+        </div>
+        <div class="text-sm font-bold text-slate-700 mb-1">龙湖天街-B座</div>
+        <div class="text-xs text-slate-500 mb-3">小图已完成,后续无动作</div>
+        <div class="grid grid-cols-2 gap-2">
+          <button class="py-1.5 border border-green-200 text-green-600 text-xs rounded hover:bg-green-50">
+            客户已反馈<br><span class="scale-90 inline-block opacity-70">转对图</span>
+          </button>
+          <button class="py-1.5 border border-slate-200 text-slate-500 text-xs rounded hover:bg-slate-50">
+            客户未回复<br><span class="scale-90 inline-block opacity-70">转停滞</span>
+          </button>
+        </div>
+      </div>
+
+    </div>
+  </div>
+
+  <!-- 右栏:项目监控 (分类查看逾期) -->
+  <div class="panel">
+    <div class="panel-header" style="padding: 0;">
+      <!-- 顶部大类切换 -->
+      <div class="flex w-full">
+        <div class="flex-1 p-4 border-r border-f1f5f9 cursor-pointer bg-slate-50 hover:bg-white">
+          <div class="text-xs text-slate-500 mb-1">交付逾期 (最急)</div>
+          <div class="text-xl font-bold text-red-600">2 <span class="text-xs font-normal text-slate-400">项</span></div>
+        </div>
+        <div class="flex-1 p-4 cursor-pointer bg-white border-b-2 border-blue-500">
+          <div class="text-xs text-slate-500 mb-1">阶段逾期</div>
+          <div class="text-xl font-bold text-slate-700">5 <span class="text-xs font-normal text-slate-400">项</span></div>
+        </div>
+      </div>
+    </div>
+
+    <!-- 二级筛选:针对阶段逾期 -->
+    <div class="filter-bar">
+      <span class="chip active">全部 (5)</span>
+      <span class="chip">建模 (2)</span>
+      <span class="chip">渲染 (1)</span>
+      <span class="chip">软装 (1)</span>
+      <span class="chip">后期 (1)</span>
+    </div>
+
+    <div class="monitor-list">
+      
+      <!-- 列表项:建模逾期 -->
+      <div class="monitor-item">
+        <div class="item-left">
+          <div class="item-title">
+            万科城市花园
+            <span class="phase-badge phase-mod">建模</span>
+          </div>
+          <div class="item-sub">负责人: 李婷 · 截止: 11/25</div>
+        </div>
+        <div class="flex items-center gap-3">
+          <span class="overdue-tag">逾期2天</span>
+          <div class="actions flex">
+            <button class="btn-icon" title="催办"><i data-lucide="send" width="14"></i></button>
+            <button class="btn-icon" title="详情"><i data-lucide="more-horizontal" width="14"></i></button>
+          </div>
+        </div>
+      </div>
+
+      <!-- 列表项:渲染逾期 -->
+      <div class="monitor-item">
+        <div class="item-left">
+          <div class="item-title">
+            天鹅湖花园
+            <span class="phase-badge phase-ren">渲染</span>
+          </div>
+          <div class="item-sub">负责人: 张伟 · 截止: 昨天</div>
+        </div>
+        <div class="flex items-center gap-3">
+          <span class="overdue-tag">逾期1天</span>
+          <div class="actions flex">
+            <button class="btn-icon" title="催办"><i data-lucide="send" width="14"></i></button>
+          </div>
+        </div>
+      </div>
+      
+      <!-- 列表项:软装逾期 -->
+      <div class="monitor-item">
+        <div class="item-left">
+          <div class="item-title">
+            麓湖生态城
+            <span class="phase-badge phase-soft">软装</span>
+          </div>
+          <div class="item-sub">负责人: 王刚 · 截止: 11/24</div>
+        </div>
+        <div class="flex items-center gap-3">
+          <span class="overdue-tag">逾期3天</span>
+          <div class="actions flex">
+            <button class="btn-icon" title="催办"><i data-lucide="send" width="14"></i></button>
+          </div>
+        </div>
+      </div>
+
+    </div>
+  </div>
+
+</div>
+
+<div class="max-w-4xl mx-auto mt-8 text-slate-600 text-sm">
+  <h3 class="font-bold text-lg mb-2">方案二:双栏分类看板 (Dual-Column Categorized)</h3>
+  <p class="mb-2">满足您对"双栏式"和"多维度分类"的需求,同时保持界面清爽。</p>
+  <div class="grid grid-cols-2 gap-8">
+    <div>
+      <strong>左栏:主动管理 (Action)</strong>
+      <ul class="list-disc pl-4 mt-1 space-y-1 text-xs">
+        <li>仅展示需要"人"去处理的事情。</li>
+        <li>包含客户投诉(最急)和状态决策(最核心)。</li>
+        <li>"状态决策"卡片直接嵌入操作按钮,减少跳转。</li>
+      </ul>
+    </div>
+    <div>
+      <strong>右栏:监控预警 (Monitor)</strong>
+      <ul class="list-disc pl-4 mt-1 space-y-1 text-xs">
+        <li>按"交付"和"阶段"两大类拆分 Tab。</li>
+        <li>"阶段逾期"下设二级筛选 (建模/渲染/软装/后期)。</li>
+        <li>使用彩色标签 (Badge) 快速识别阶段类型。</li>
+      </ul>
+    </div>
+  </div>
+</div>
+
+<script>
+  lucide.createIcons();
+</script>
+</body>
+</html>

+ 369 - 0
src/test/todo-list-preview.html

@@ -0,0 +1,369 @@
+<!DOCTYPE html>
+<html lang="zh-CN">
+<head>
+  <meta charset="UTF-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1.0">
+  <title>智能待办清单 - 方案预览</title>
+  <!-- 引入 Tailwind CSS (通过 CDN 模拟 Angular 样式) -->
+  <script src="https://cdn.tailwindcss.com"></script>
+  <!-- 引入 Lucide 图标 -->
+  <script src="https://unpkg.com/lucide@latest"></script>
+  <style>
+    body {
+      background-color: #f8fafc;
+      font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
+      padding: 40px;
+      color: #1e293b;
+    }
+    
+    .container {
+      max-width: 480px; /* 模拟侧边栏宽度 */
+      margin: 0 auto;
+      background: white;
+      border-radius: 16px;
+      box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.1), 0 8px 10px -6px rgba(0, 0, 0, 0.1);
+      overflow: hidden;
+      border: 1px solid #e2e8f0;
+    }
+
+    .header {
+      padding: 20px;
+      border-bottom: 1px solid #f1f5f9;
+      background: white;
+    }
+
+    .stats-row {
+      display: flex;
+      gap: 12px;
+      margin-top: 12px;
+    }
+
+    .stat-badge {
+      display: flex;
+      align-items: center;
+      gap: 6px;
+      padding: 6px 12px;
+      border-radius: 20px;
+      font-size: 13px;
+      font-weight: 600;
+      cursor: pointer;
+      transition: all 0.2s;
+    }
+    
+    .stat-badge:hover { transform: translateY(-1px); }
+    .stat-badge.active { box-shadow: 0 2px 5px rgba(0,0,0,0.1); }
+
+    .stat-red { background: #fef2f2; color: #ef4444; border: 1px solid #fecaca; }
+    .stat-orange { background: #fff7ed; color: #f97316; border: 1px solid #fed7aa; }
+    .stat-yellow { background: #fefce8; color: #eab308; border: 1px solid #fef08a; }
+
+    .task-list {
+      padding: 16px;
+      background: #f8fafc;
+      min-height: 500px;
+    }
+
+    .section-title {
+      font-size: 12px;
+      font-weight: 600;
+      color: #94a3b8;
+      margin: 16px 0 8px 4px;
+      text-transform: uppercase;
+      letter-spacing: 0.5px;
+    }
+    .section-title:first-child { margin-top: 0; }
+
+    /* 卡片基础样式 */
+    .task-card {
+      background: white;
+      border-radius: 12px;
+      padding: 16px;
+      margin-bottom: 12px;
+      box-shadow: 0 1px 3px rgba(0,0,0,0.05);
+      border: 1px solid transparent;
+      transition: all 0.2s;
+      position: relative;
+      overflow: hidden;
+    }
+    
+    .task-card:hover {
+      box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
+      border-color: #e2e8f0;
+      transform: translateY(-1px);
+    }
+
+    /* 优先级边框 */
+    .card-p0 { border-left: 4px solid #ef4444; }
+    .card-p1 { border-left: 4px solid #f97316; }
+    .card-p2 { border-left: 4px solid #eab308; }
+
+    .card-header {
+      display: flex;
+      justify-content: space-between;
+      align-items: flex-start;
+      margin-bottom: 8px;
+    }
+
+    .project-name {
+      font-weight: 600;
+      font-size: 15px;
+      color: #0f172a;
+      display: flex;
+      align-items: center;
+      gap: 8px;
+    }
+
+    .designer-tag {
+      font-size: 11px;
+      color: #64748b;
+      background: #f1f5f9;
+      padding: 2px 6px;
+      border-radius: 4px;
+      font-weight: 500;
+    }
+
+    .time-tag {
+      font-size: 12px;
+      font-weight: 600;
+      padding: 2px 8px;
+      border-radius: 10px;
+    }
+    .tag-overdue { background: #fee2e2; color: #991b1b; }
+    .tag-warning { background: #ffedd5; color: #9a3412; }
+
+    .card-body {
+      font-size: 13px;
+      color: #475569;
+      line-height: 1.5;
+      margin-bottom: 12px;
+    }
+
+    .decision-box {
+      background: #f8fafc;
+      border-radius: 8px;
+      padding: 12px;
+      margin: 10px 0;
+      border: 1px dashed #cbd5e1;
+    }
+    
+    .decision-title {
+      font-size: 12px;
+      font-weight: 600;
+      color: #334155;
+      margin-bottom: 8px;
+      display: flex;
+      align-items: center;
+      gap: 6px;
+    }
+
+    .btn-group {
+      display: flex;
+      gap: 8px;
+    }
+
+    .btn {
+      flex: 1;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      gap: 6px;
+      padding: 8px;
+      border-radius: 6px;
+      font-size: 13px;
+      font-weight: 500;
+      cursor: pointer;
+      border: 1px solid transparent;
+      transition: all 0.15s;
+    }
+
+    .btn-primary { background: #3b82f6; color: white; }
+    .btn-primary:hover { background: #2563eb; }
+
+    .btn-secondary { background: white; border: 1px solid #e2e8f0; color: #475569; }
+    .btn-secondary:hover { background: #f8fafc; border-color: #cbd5e1; }
+
+    .btn-danger-ghost { background: #fef2f2; color: #dc2626; border: 1px solid transparent; }
+    .btn-danger-ghost:hover { background: #fee2e2; }
+
+    .btn-success-ghost { background: #f0fdf4; color: #16a34a; border: 1px solid transparent; }
+    .btn-success-ghost:hover { background: #dcfce7; }
+
+    .btn-xs { padding: 4px 8px; font-size: 12px; flex: none; }
+
+  </style>
+</head>
+<body>
+
+<div class="flex justify-center items-start gap-8">
+
+  <!-- 模拟移动端/侧边栏视图 -->
+  <div class="container">
+    
+    <!-- 顶部概览 -->
+    <div class="header">
+      <div class="flex justify-between items-center">
+        <h2 class="text-xl font-bold text-slate-800">待办事项</h2>
+        <button class="text-slate-400 hover:text-slate-600"><i data-lucide="refresh-cw" width="18"></i></button>
+      </div>
+      <div class="stats-row">
+        <div class="stat-badge stat-red active">
+          <i data-lucide="alert-circle" width="16"></i>
+          <span>客户 2</span>
+        </div>
+        <div class="stat-badge stat-orange">
+          <i data-lucide="help-circle" width="16"></i>
+          <span>待决策 3</span>
+        </div>
+        <div class="stat-badge stat-yellow">
+          <i data-lucide="clock" width="16"></i>
+          <span>逾期 4</span>
+        </div>
+      </div>
+    </div>
+
+    <div class="task-list">
+      
+      <!-- P0: 客户预警 -->
+      <div class="section-title">客户预警 (需立即处理)</div>
+      
+      <!-- 卡片1: 差评投诉 -->
+      <div class="task-card card-p0">
+        <div class="card-header">
+          <div class="project-name">
+            锦江上院-13号
+            <span class="designer-tag">王刚</span>
+          </div>
+          <span class="time-tag tag-overdue">投诉</span>
+        </div>
+        <div class="card-body">
+          <div class="flex items-start gap-2 text-red-600 font-medium mb-1">
+            <i data-lucide="message-square-warning" width="16" class="mt-1"></i>
+            客户反馈:"进度太慢了,发消息也没人回!"
+          </div>
+          <div class="text-xs text-slate-500 mt-2">最后回复: 昨天 14:30</div>
+        </div>
+        <div class="btn-group">
+          <button class="btn btn-primary"><i data-lucide="message-circle" width="16"></i> 联系客户</button>
+          <button class="btn btn-secondary"><i data-lucide="forward" width="16"></i> 转给客服</button>
+        </div>
+      </div>
+
+      <!-- P1: 状态决策 (核心业务) -->
+      <div class="section-title">状态决策 (小图已出)</div>
+
+      <!-- 卡片2: 决策 - 停滞还是对图 -->
+      <div class="task-card card-p1">
+        <div class="card-header">
+          <div class="project-name">
+            龙湖天街-B座
+            <span class="designer-tag">徐福静</span>
+          </div>
+          <span class="time-tag tag-warning">停滞?</span>
+        </div>
+        <div class="card-body">
+          小图已发送 3 天,目前无任何进展。请确认当前状态:
+        </div>
+        
+        <div class="decision-box">
+          <div class="decision-title"><i data-lucide="git-branch" width="14"></i> 请组长判断</div>
+          <div class="btn-group">
+            <button class="btn btn-success-ghost" onclick="toggleDecision(this)">
+              <i data-lucide="check-circle" width="16"></i> 客户已反馈
+              <span class="text-xs opacity-70 block mt-1">转对图期</span>
+            </button>
+            <button class="btn btn-danger-ghost">
+              <i data-lucide="pause-circle" width="16"></i> 客户未回复
+              <span class="text-xs opacity-70 block mt-1">转停滞期</span>
+            </button>
+          </div>
+        </div>
+      </div>
+
+      <!-- P2: 节点逾期 -->
+      <div class="section-title">节点逾期</div>
+
+      <!-- 卡片3: 小图逾期 -->
+      <div class="task-card card-p2">
+        <div class="card-header">
+          <div class="project-name">
+            万科城市花园
+            <span class="designer-tag">李婷</span>
+          </div>
+          <span class="time-tag tag-overdue">逾期2天</span>
+        </div>
+        <div class="card-body flex justify-between items-center">
+          <span>小图截止时间:11/25 (周一)</span>
+          <button class="btn btn-secondary btn-xs text-blue-600">
+            <i data-lucide="send" width="14"></i> 催办
+          </button>
+        </div>
+      </div>
+
+      <!-- 卡片4: 阶段交付逾期 -->
+      <div class="task-card card-p2">
+        <div class="card-header">
+          <div class="project-name">
+            保利国际广场
+            <span class="designer-tag">赵敏</span>
+          </div>
+          <span class="time-tag tag-overdue">交付逾期1天</span>
+        </div>
+        <div class="card-body">
+          <span>当前阶段:施工图深化</span>
+        </div>
+        <div class="btn-group">
+           <button class="btn btn-secondary text-xs"><i data-lucide="clock" width="14"></i> 延期</button>
+           <button class="btn btn-secondary text-xs"><i data-lucide="check" width="14"></i> 标记完成</button>
+        </div>
+      </div>
+      
+      <!-- 普通代办 (折叠) -->
+      <div class="mt-6 pt-4 border-t border-slate-200 text-center">
+        <button class="text-slate-400 text-sm flex items-center justify-center gap-2 hover:text-blue-500 transition-colors">
+          查看 5 条普通任务 <i data-lucide="chevron-down" width="16"></i>
+        </button>
+      </div>
+
+    </div>
+  </div>
+
+  <!-- 说明区域 -->
+  <div class="max-w-md text-slate-600">
+    <h3 class="text-lg font-bold mb-4 text-slate-800">方案一:智能流式清单 (Smart Task Stream)</h3>
+    <p class="mb-4 text-sm">此方案针对组长"快速决策、快速分发"的工作流设计,抛弃了传统的 Tab 分页,采用单列信息流。</p>
+    
+    <ul class="list-disc pl-5 space-y-2 text-sm">
+      <li><strong>自动优先级排序</strong>:系统自动将最紧急的(客户投诉、决策项)置顶,无需手动筛选。</li>
+      <li><strong>决策卡片 (核心)</strong>:针对"小图出图后无动作"的模糊地带,提供明确的二选一按钮(转对图 vs 转停滞),一键完成状态流转和责任划分。</li>
+      <li><strong>一键催办</strong>:针对逾期项目,直接提供催办入口。</li>
+      <li><strong>视觉降噪</strong>:去除了正常进行的任务,只显示异常和需介入项。</li>
+    </ul>
+  </div>
+
+</div>
+
+<script>
+  // 初始化图标
+  lucide.createIcons();
+
+  function toggleDecision(btn) {
+    // 模拟点击反馈
+    const originalHtml = btn.innerHTML;
+    btn.innerHTML = `<i data-lucide="loader" width="16" class="animate-spin"></i> 处理中...`;
+    lucide.createIcons();
+    
+    setTimeout(() => {
+      const card = btn.closest('.task-card');
+      card.style.transition = 'all 0.5s';
+      card.style.opacity = '0';
+      card.style.transform = 'translateX(100%)';
+      
+      setTimeout(() => {
+        card.remove();
+        alert('已将该项目转入[对图期],并生成代办任务给徐福静');
+      }, 500);
+    }, 800);
+  }
+</script>
+</body>
+</html>

+ 417 - 0
src/test/todo-section-v3.html

@@ -0,0 +1,417 @@
+<!DOCTYPE html>
+<html lang="zh-CN">
+<head>
+  <meta charset="UTF-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1.0">
+  <title>待办事项 - 双栏优化版</title>
+  <script src="https://cdn.tailwindcss.com"></script>
+  <script src="https://unpkg.com/lucide@latest"></script>
+  <style>
+    body { background-color: #f3f4f6; padding: 20px; font-family: system-ui, -apple-system, sans-serif; color: #1f2937; }
+    
+    /* 整体布局 */
+    .main-grid {
+      display: grid;
+      grid-template-columns: 400px 1fr; /* 左侧固定,右侧自适应 */
+      gap: 24px;
+      max-width: 1400px;
+      margin: 0 auto;
+      align-items: start;
+    }
+
+    /* 通用面板样式 */
+    .panel {
+      background: white;
+      border-radius: 12px;
+      box-shadow: 0 1px 3px rgba(0,0,0,0.05);
+      overflow: hidden;
+      border: 1px solid #e5e7eb;
+      display: flex;
+      flex-direction: column;
+      height: 800px; /* 固定高度,内容滚动 */
+    }
+
+    .panel-header {
+      padding: 16px 20px;
+      color: white;
+      display: flex;
+      align-items: center;
+      gap: 8px;
+      flex-shrink: 0;
+    }
+    .header-title { font-weight: 600; font-size: 16px; display: flex; align-items: center; gap: 8px; }
+    .header-count { background: rgba(255,255,255,0.2); padding: 2px 8px; border-radius: 12px; font-size: 12px; }
+    .header-desc { font-size: 12px; opacity: 0.9; margin-left: auto; }
+
+    .panel-body {
+      padding: 16px;
+      background: #f9fafb;
+      overflow-y: auto;
+      flex: 1;
+    }
+
+    /* 左栏:待办问题 (Issue) - 紫色系 */
+    .panel-left .panel-header { background: linear-gradient(135deg, #8b5cf6, #7c3aed); }
+    
+    .issue-card {
+      background: white;
+      border-radius: 8px;
+      padding: 16px;
+      margin-bottom: 12px;
+      border-left: 4px solid #ddd6fe;
+      box-shadow: 0 1px 2px rgba(0,0,0,0.05);
+      transition: all 0.2s;
+    }
+    .issue-card:hover { transform: translateY(-2px); box-shadow: 0 4px 6px -1px rgba(0,0,0,0.1); }
+    .issue-card.priority-high { border-left-color: #ef4444; }
+    
+    .issue-title { font-weight: 600; color: #1f2937; margin-bottom: 4px; font-size: 14px; }
+    .issue-meta { font-size: 12px; color: #6b7280; display: flex; gap: 12px; align-items: center; margin-bottom: 12px; }
+    .issue-project { background: #f3f4f6; padding: 2px 6px; border-radius: 4px; font-weight: 500; }
+    
+    /* 右栏:紧急事件 (Event) - 橙红系 */
+    .panel-right .panel-header { background: linear-gradient(135deg, #f97316, #ea580c); }
+
+    /* 顶部筛选区 */
+    .filter-tabs {
+      display: flex;
+      gap: 12px;
+      padding: 12px 16px;
+      background: white;
+      border-bottom: 1px solid #f3f4f6;
+      overflow-x: auto;
+    }
+    
+    .filter-tab {
+      padding: 6px 12px;
+      border-radius: 20px;
+      font-size: 13px;
+      font-weight: 500;
+      color: #64748b;
+      background: #f1f5f9;
+      border: 1px solid transparent;
+      cursor: pointer;
+      display: flex;
+      align-items: center;
+      gap: 6px;
+      transition: all 0.2s;
+      white-space: nowrap;
+    }
+    .filter-tab:hover { background: #e2e8f0; }
+    .filter-tab.active { background: #fff7ed; color: #ea580c; border-color: #fdba74; }
+    .filter-tab.active-red { background: #fef2f2; color: #dc2626; border-color: #fecaca; }
+
+    /* 二级筛选 (阶段细分) */
+    .sub-filters {
+      padding: 8px 16px;
+      background: #fff7ed;
+      display: flex;
+      gap: 8px;
+      border-bottom: 1px solid #fed7aa;
+      animation: slideDown 0.2s ease-out;
+    }
+    @keyframes slideDown { from { transform: translateY(-10px); opacity: 0; } to { transform: translateY(0); opacity: 1; } }
+
+    .sub-chip {
+      font-size: 11px;
+      padding: 2px 8px;
+      border-radius: 4px;
+      cursor: pointer;
+      color: #9a3412;
+    }
+    .sub-chip.active { background: #ea580c; color: white; font-weight: 600; }
+
+    /* 事件列表卡片 */
+    .event-card {
+      background: white;
+      border-radius: 10px;
+      padding: 16px;
+      margin-bottom: 12px;
+      border: 1px solid #e5e7eb;
+      display: grid;
+      grid-template-columns: 1fr auto; /* 左侧信息,右侧操作 */
+      gap: 16px;
+      position: relative;
+    }
+    .event-card:hover { border-color: #cbd5e1; box-shadow: 0 4px 6px -1px rgba(0,0,0,0.05); }
+    
+    /* 左侧标线 */
+    .card-line { position: absolute; left: 0; top: 0; bottom: 0; width: 4px; border-radius: 4px 0 0 4px; }
+    .line-red { background: #ef4444; } /* 客户 */
+    .line-orange { background: #f97316; } /* 决策 */
+    .line-blue { background: #3b82f6; } /* 建模 */
+    .line-green { background: #22c55e; } /* 软装 */
+    .line-yellow { background: #eab308; } /* 渲染 */
+    .line-purple { background: #a855f7; } /* 后期 */
+
+    .event-main { display: flex; flex-direction: column; justify-content: center; }
+    .event-header { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; }
+    .event-title { font-size: 15px; font-weight: 700; color: #111827; }
+    .event-tag { font-size: 11px; padding: 1px 6px; border-radius: 4px; font-weight: 500; background: #f3f4f6; color: #4b5563; }
+    
+    .event-desc { font-size: 13px; color: #4b5563; margin-bottom: 8px; line-height: 1.4; }
+    
+    .event-meta { font-size: 12px; color: #6b7280; display: flex; gap: 12px; align-items: center; }
+    .meta-highlight { color: #ef4444; font-weight: 600; background: #fef2f2; padding: 2px 6px; border-radius: 4px; }
+
+    /* 右侧操作区 */
+    .event-actions { 
+      display: flex; 
+      flex-direction: column; 
+      justify-content: center; 
+      gap: 8px; 
+      min-width: 100px; 
+      border-left: 1px dashed #e5e7eb;
+      padding-left: 16px;
+    }
+
+    .btn-action {
+      width: 100%;
+      padding: 6px 12px;
+      border-radius: 6px;
+      font-size: 12px;
+      font-weight: 500;
+      cursor: pointer;
+      text-align: center;
+      transition: all 0.15s;
+      border: 1px solid transparent;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      gap: 4px;
+    }
+    .btn-primary { background: #fff7ed; color: #c2410c; border-color: #ffedd5; }
+    .btn-primary:hover { background: #ffedd5; }
+    
+    .btn-default { background: white; color: #4b5563; border-color: #e5e7eb; }
+    .btn-default:hover { background: #f9fafb; border-color: #d1d5db; }
+
+    .btn-success { background: #f0fdf4; color: #15803d; border-color: #dcfce7; }
+    .btn-success:hover { background: #dcfce7; }
+
+    /* 状态决策专用 */
+    .decision-group { display: flex; gap: 8px; margin-top: 4px; }
+    .decision-btn { flex: 1; padding: 6px; font-size: 12px; border-radius: 6px; cursor: pointer; text-align: center; border: 1px solid; }
+    .btn-yes { background: #f0fdf4; border-color: #bbf7d0; color: #166534; }
+    .btn-no { background: #fef2f2; border-color: #fecaca; color: #991b1b; }
+
+  </style>
+</head>
+<body>
+
+<div class="main-grid">
+
+  <!-- 左栏:待办问题 (Issue) -->
+  <div class="panel panel-left">
+    <div class="panel-header">
+      <div class="header-title">
+        <i data-lucide="list-todo" width="20"></i> 待办问题
+      </div>
+      <div class="header-count">3</div>
+      <div class="header-desc">来自项目问题模块</div>
+    </div>
+    <div class="panel-body">
+      <!-- 问题 1 -->
+      <div class="issue-card">
+        <div class="issue-title">测试代办任务</div>
+        <div class="issue-meta">
+          <span class="issue-project">十二月旧-家装</span>
+          <span>小 task</span>
+        </div>
+        <div class="flex justify-between items-center">
+          <span class="text-xs text-slate-400">创建于 2天前 · 刘阿姨</span>
+          <button class="text-xs bg-slate-100 text-slate-600 px-3 py-1.5 rounded hover:bg-slate-200">查看详情</button>
+        </div>
+      </div>
+
+      <!-- 问题 2 -->
+      <div class="issue-card priority-high">
+        <div class="issue-title flex items-center gap-2">
+          需要进一步明确需求
+          <span class="text-[10px] bg-red-100 text-red-600 px-1 rounded">紧急</span>
+        </div>
+        <div class="issue-meta">
+          <span class="issue-project">十一月新-工装</span>
+          <span>bug</span>
+        </div>
+        <div class="flex justify-between items-center">
+          <span class="text-xs text-slate-400">创建于 1小时前 · 王刚</span>
+          <button class="text-xs bg-red-50 text-red-600 px-3 py-1.5 rounded hover:bg-red-100">立即处理</button>
+        </div>
+      </div>
+    </div>
+  </div>
+
+  <!-- 右栏:紧急事件 (Event) -->
+  <div class="panel panel-right">
+    <div class="panel-header">
+      <div class="header-title">
+        <i data-lucide="alert-triangle" width="20"></i> 紧急事件
+      </div>
+      <div class="header-count">12</div>
+      <div class="header-desc">自动计算截止/逾期</div>
+    </div>
+
+    <!-- 一级筛选 Tab -->
+    <div class="filter-tabs">
+      <div class="filter-tab" onclick="switchTab('all')">
+        全部 <span class="bg-slate-200 px-1.5 rounded-full text-[10px]">12</span>
+      </div>
+      <div class="filter-tab active-red" onclick="switchTab('customer')">
+        <i data-lucide="headphones" width="14"></i> 客户预警
+        <span class="bg-red-100 text-red-600 px-1.5 rounded-full text-[10px]">1</span>
+      </div>
+      <div class="filter-tab active" onclick="switchTab('phase')">
+        <i data-lucide="layers" width="14"></i> 阶段逾期
+        <span class="bg-orange-100 text-orange-600 px-1.5 rounded-full text-[10px]">5</span>
+      </div>
+      <div class="filter-tab" onclick="switchTab('delivery')">
+        <i data-lucide="clock" width="14"></i> 小图/交付
+        <span class="bg-slate-200 px-1.5 rounded-full text-[10px]">6</span>
+      </div>
+    </div>
+
+    <!-- 二级筛选 (阶段细分) - 默认显示 -->
+    <div class="sub-filters" id="subFilters">
+      <span class="text-[11px] text-orange-800 font-bold mr-2 self-center">阶段筛选:</span>
+      <span class="sub-chip active">全部</span>
+      <span class="sub-chip">建模 (2)</span>
+      <span class="sub-chip">渲染 (1)</span>
+      <span class="sub-chip">软装 (1)</span>
+      <span class="sub-chip">后期 (1)</span>
+    </div>
+
+    <div class="panel-body">
+      
+      <!-- 1. 客户预警 (P0) -->
+      <div class="event-card">
+        <div class="card-line line-red"></div>
+        <div class="event-main">
+          <div class="event-header">
+            <span class="event-title text-red-700">客户投诉进度慢</span>
+            <span class="event-tag bg-red-100 text-red-600">客户服务</span>
+          </div>
+          <div class="event-desc">项目「锦江上院-13号」客户反馈发消息未回,情绪激动。</div>
+          <div class="event-meta">
+            <span>负责人: 王刚</span>
+            <span class="text-slate-400">发生于 2小时前</span>
+          </div>
+        </div>
+        <div class="event-actions">
+          <button class="btn-action bg-red-50 text-red-600 border-red-100 hover:bg-red-100">
+            <i data-lucide="message-circle" width="14"></i> 安抚跟进
+          </button>
+        </div>
+      </div>
+
+      <!-- 2. 状态决策 (P1) -->
+      <div class="event-card">
+        <div class="card-line line-orange"></div>
+        <div class="event-main">
+          <div class="event-header">
+            <span class="event-title">小图已出,后续不明</span>
+            <span class="event-tag bg-orange-100 text-orange-600">状态决策</span>
+          </div>
+          <div class="event-meta mb-2">
+            <span class="issue-project">龙湖天街-B座</span>
+            <span>设计师: 徐福静</span>
+          </div>
+          <div class="text-xs text-slate-600 mb-2">小图发送已 3 天,系统未检测到下一步动作,请人工判断:</div>
+          
+          <div class="decision-group">
+            <button class="decision-btn btn-yes">
+              <i data-lucide="check" width="12" class="inline"></i> 客户反馈 → 对图
+            </button>
+            <button class="decision-btn btn-no">
+              <i data-lucide="pause" width="12" class="inline"></i> 未回复 → 停滞
+            </button>
+          </div>
+        </div>
+        <div class="event-actions">
+           <button class="btn-action btn-default">查看项目</button>
+        </div>
+      </div>
+
+      <!-- 3. 阶段逾期 - 建模 (P2) -->
+      <div class="event-card">
+        <div class="card-line line-blue"></div>
+        <div class="event-main">
+          <div class="event-header">
+            <span class="event-title">建模阶段滞后</span>
+            <span class="event-tag bg-blue-100 text-blue-600">建模</span>
+          </div>
+          <div class="event-meta">
+            <span class="issue-project">万科城市花园</span>
+            <span>负责人: 李婷</span>
+          </div>
+          <div class="event-meta mt-2">
+            <span class="meta-highlight">逾期 2 天</span>
+            <span>完成率: 30%</span>
+          </div>
+        </div>
+        <div class="event-actions">
+          <button class="btn-action btn-primary">
+            <i data-lucide="send" width="14"></i> 催办
+          </button>
+          <button class="btn-action btn-default">延期</button>
+        </div>
+      </div>
+
+      <!-- 4. 阶段逾期 - 渲染 (P2) -->
+      <div class="event-card">
+        <div class="card-line line-yellow"></div>
+        <div class="event-main">
+          <div class="event-header">
+            <span class="event-title">渲染即将超时</span>
+            <span class="event-tag bg-yellow-100 text-yellow-700">渲染</span>
+          </div>
+          <div class="event-meta">
+            <span class="issue-project">天鹅湖花园</span>
+            <span>负责人: 张伟</span>
+          </div>
+          <div class="event-meta mt-2">
+            <span class="text-orange-500 font-bold">今天 18:00 截止</span>
+            <span>完成率: 80%</span>
+          </div>
+        </div>
+        <div class="event-actions">
+          <button class="btn-action btn-success">
+             <i data-lucide="check-square" width="14"></i> 按时交付
+          </button>
+        </div>
+      </div>
+
+    </div>
+  </div>
+
+</div>
+
+<script>
+  lucide.createIcons();
+
+  function switchTab(tab) {
+    // 简单的切换逻辑示意
+    const subFilters = document.getElementById('subFilters');
+    if (tab === 'phase') {
+      subFilters.style.display = 'flex';
+    } else {
+      subFilters.style.display = 'none';
+    }
+    
+    // 更新 Tab 样式 (这里仅做 demo)
+    document.querySelectorAll('.filter-tab').forEach(el => {
+      el.classList.remove('active', 'active-red');
+      el.style.backgroundColor = '#f1f5f9';
+      el.style.color = '#64748b';
+      el.style.borderColor = 'transparent';
+    });
+    
+    if (tab === 'customer') {
+      event.currentTarget.classList.add('active-red');
+    } else {
+      event.currentTarget.classList.add('active');
+    }
+  }
+</script>
+</body>
+</html>

+ 340 - 0
src/test/todo-section-variants.html

@@ -0,0 +1,340 @@
+<!DOCTYPE html>
+<html lang="zh-CN">
+<head>
+  <meta charset="UTF-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1.0">
+  <title>待办事项优化方案对比</title>
+  <script src="https://cdn.tailwindcss.com"></script>
+  <script src="https://unpkg.com/lucide@latest"></script>
+  <style>
+    body { background-color: #f3f4f6; padding: 20px; font-family: system-ui, -apple-system, sans-serif; color: #1f2937; }
+    
+    /* 方案切换器 */
+    .variant-switcher {
+      display: flex;
+      justify-content: center;
+      gap: 16px;
+      margin-bottom: 24px;
+    }
+    .variant-btn {
+      padding: 8px 20px;
+      background: white;
+      border: 1px solid #e5e7eb;
+      border-radius: 20px;
+      font-size: 14px;
+      font-weight: 500;
+      color: #4b5563;
+      cursor: pointer;
+      transition: all 0.2s;
+      box-shadow: 0 1px 2px rgba(0,0,0,0.05);
+    }
+    .variant-btn:hover { background: #f9fafb; }
+    .variant-btn.active { background: #3b82f6; color: white; border-color: #3b82f6; box-shadow: 0 4px 6px -1px rgba(59, 130, 246, 0.3); }
+
+    /* 布局容器 */
+    .main-grid {
+      display: grid;
+      grid-template-columns: 320px 1fr; /* 左侧缩小,右侧空间更大 */
+      gap: 24px;
+      max-width: 1400px;
+      margin: 0 auto;
+      align-items: start;
+      height: 85vh;
+    }
+
+    /* 面板通用样式 */
+    .panel {
+      background: white;
+      border-radius: 12px;
+      box-shadow: 0 1px 3px rgba(0,0,0,0.05);
+      overflow: hidden;
+      border: 1px solid #e5e7eb;
+      display: flex;
+      flex-direction: column;
+      height: 100%;
+    }
+
+    .panel-header { padding: 12px 16px; display: flex; align-items: center; gap: 8px; flex-shrink: 0; border-bottom: 1px solid #f3f4f6; }
+    .header-title { font-weight: 600; font-size: 15px; }
+    .panel-body { padding: 12px; background: #f9fafb; overflow-y: auto; flex: 1; }
+
+    /* 左栏:待办问题 */
+    .issue-card {
+      background: white; padding: 12px; border-radius: 8px; margin-bottom: 10px;
+      border-left: 3px solid #a78bfa; box-shadow: 0 1px 2px rgba(0,0,0,0.05);
+    }
+    .issue-title { font-weight: 600; font-size: 13px; margin-bottom: 4px; }
+    .issue-sub { font-size: 11px; color: #6b7280; }
+
+    /* 右栏变体容器 */
+    .variant-container { height: 100%; display: none; flex-direction: column; }
+    .variant-container.active { display: flex; }
+
+    /* ================= 方案 A: 经典 Tab 增强版 ================= */
+    .tab-header { display: flex; gap: 8px; padding: 10px 16px; background: white; border-bottom: 1px solid #f3f4f6; overflow-x: auto; }
+    .tab-pill { 
+      padding: 4px 12px; border-radius: 16px; font-size: 12px; cursor: pointer; background: #f3f4f6; color: #64748b; transition: all 0.2s; display: flex; align-items: center; gap: 6px;
+    }
+    .tab-pill.active { background: #fff7ed; color: #ea580c; font-weight: 600; ring: 1px solid #fdba74; }
+    
+    .card-a {
+      background: white; padding: 14px; border-radius: 8px; margin-bottom: 10px; border: 1px solid #e5e7eb;
+      display: flex; justify-content: space-between; align-items: center;
+    }
+    .tag-phase { font-size: 10px; padding: 2px 6px; border-radius: 4px; background: #f1f5f9; color: #475569; margin-left: 6px; }
+    .tag-phase.mod { background: #eff6ff; color: #2563eb; } /* 建模 */
+    .tag-phase.render { background: #fefce8; color: #ca8a04; } /* 渲染 */
+
+    /* ================= 方案 B: 垂直平铺流 (无Tab) ================= */
+    .section-title { 
+      font-size: 12px; font-weight: 700; color: #9ca3af; margin: 16px 0 8px 4px; 
+      text-transform: uppercase; letter-spacing: 0.5px; display: flex; align-items: center; gap: 6px;
+    }
+    .section-title:first-child { margin-top: 4px; }
+    
+    .card-b {
+      background: white; padding: 12px 16px; border-radius: 8px; margin-bottom: 8px; 
+      border-left: 4px solid transparent; box-shadow: 0 1px 2px rgba(0,0,0,0.05);
+    }
+    .card-b.urgent { border-left-color: #ef4444; }
+    .card-b.warning { border-left-color: #f59e0b; }
+    .card-b.normal { border-left-color: #3b82f6; }
+
+    /* ================= 方案 C: 紧凑矩阵 (适合多条目) ================= */
+    .grid-container { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 12px; padding: 12px; }
+    .card-c {
+      background: white; padding: 12px; border-radius: 8px; border: 1px solid #e5e7eb;
+      display: flex; flex-direction: column; gap: 8px;
+    }
+    .card-c-header { display: flex; justify-content: space-between; align-items: center; font-size: 12px; color: #6b7280; }
+    .card-c-title { font-weight: 600; font-size: 13px; color: #111827; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
+    .progress-mini { height: 4px; background: #f3f4f6; border-radius: 2px; overflow: hidden; margin-top: 4px; }
+    .progress-bar { height: 100%; background: #3b82f6; width: 70%; }
+
+  </style>
+</head>
+<body>
+
+<div class="variant-switcher">
+  <button class="variant-btn active" onclick="showVariant('A')">方案 A: 经典Tab增强 (清晰分类)</button>
+  <button class="variant-btn" onclick="showVariant('B')">方案 B: 垂直平铺流 (全局概览)</button>
+  <button class="variant-btn" onclick="showVariant('C')">方案 C: 紧凑矩阵版 (高密度)</button>
+</div>
+
+<div class="main-grid">
+
+  <!-- 左栏:待办问题 (固定不变) -->
+  <div class="panel" style="border-top: 4px solid #8b5cf6;">
+    <div class="panel-header bg-purple-50">
+      <span class="header-title text-purple-900"><i data-lucide="list-todo" width="16"></i> 待办问题 (3)</span>
+    </div>
+    <div class="panel-body">
+      <div class="issue-card">
+        <div class="issue-title">需求变更确认</div>
+        <div class="issue-sub">项目: 龙湖天街-A座 · 昨天</div>
+      </div>
+      <div class="issue-card" style="border-left-color: #ef4444;">
+        <div class="issue-title text-red-600">施工图尺寸异常</div>
+        <div class="issue-sub">项目: 万科城市 · 2小时前</div>
+      </div>
+    </div>
+  </div>
+
+  <!-- 右栏:紧急事件 (变体区域) -->
+  <div class="panel" style="border-top: 4px solid #f97316;">
+    
+    <!-- 方案 A: 经典 Tab 增强 -->
+    <div id="variant-A" class="variant-container active">
+      <div class="panel-header bg-orange-50 justify-between">
+        <span class="header-title text-orange-900"><i data-lucide="alert-triangle" width="16"></i> 紧急事件监控</span>
+        <span class="text-xs text-orange-700 bg-orange-100 px-2 py-1 rounded">12 项异常</span>
+      </div>
+      
+      <!-- 一级 Tab -->
+      <div class="tab-header">
+        <div class="tab-pill">全部 (12)</div>
+        <div class="tab-pill">🔥 客户 (1)</div>
+        <div class="tab-pill active">📑 阶段逾期 (5)</div>
+        <div class="tab-pill">🕒 交付/小图 (6)</div>
+      </div>
+      
+      <!-- 二级筛选 (仅在阶段逾期显示) -->
+      <div class="flex gap-2 px-4 py-2 bg-orange-50/50 border-b border-orange-100 text-xs overflow-x-auto">
+        <span class="font-bold text-orange-800 flex-shrink-0 self-center mr-1">筛选:</span>
+        <span class="px-2 py-1 rounded bg-white border border-orange-200 text-orange-600 cursor-pointer">全部</span>
+        <span class="px-2 py-1 rounded bg-blue-50 text-blue-600 cursor-pointer">建模 (2)</span>
+        <span class="px-2 py-1 rounded bg-yellow-50 text-yellow-600 cursor-pointer">渲染 (1)</span>
+      </div>
+
+      <div class="panel-body">
+        <!-- 卡片 A1 -->
+        <div class="card-a">
+          <div>
+            <div class="flex items-center gap-2 mb-1">
+              <span class="font-bold text-sm">万科城市花园</span>
+              <span class="tag-phase mod">建模</span>
+            </div>
+            <div class="text-xs text-slate-500">负责人: 李婷 · 逾期 2 天</div>
+          </div>
+          <button class="text-xs bg-white border border-slate-200 px-3 py-1 rounded hover:bg-slate-50">催办</button>
+        </div>
+        
+        <!-- 卡片 A2 -->
+        <div class="card-a">
+          <div>
+            <div class="flex items-center gap-2 mb-1">
+              <span class="font-bold text-sm">天鹅湖花园</span>
+              <span class="tag-phase render">渲染</span>
+            </div>
+            <div class="text-xs text-slate-500">负责人: 张伟 · <span class="text-orange-500 font-medium">今天截止</span></div>
+          </div>
+          <button class="text-xs bg-green-50 text-green-600 border border-green-100 px-3 py-1 rounded">标记完成</button>
+        </div>
+      </div>
+    </div>
+
+    <!-- 方案 B: 垂直平铺流 -->
+    <div id="variant-B" class="variant-container">
+      <div class="panel-header bg-white border-b justify-between sticky top-0 z-10">
+        <span class="header-title text-slate-800">全局概览</span>
+        <div class="flex gap-2">
+          <span class="text-xs px-2 py-1 bg-red-100 text-red-600 rounded">1 急</span>
+          <span class="text-xs px-2 py-1 bg-orange-100 text-orange-600 rounded">5 警</span>
+        </div>
+      </div>
+      
+      <div class="panel-body">
+        <!-- 区块 1: 客户/决策 (置顶) -->
+        <div class="section-title text-red-500"><i data-lucide="siren" width="14"></i> 立即处理</div>
+        
+        <div class="card-b urgent flex justify-between items-center">
+          <div>
+            <div class="font-bold text-sm text-slate-800">锦江上院-13号 <span class="text-xs font-normal text-red-500 ml-1">投诉</span></div>
+            <div class="text-xs text-slate-500 mt-1">客户反馈进度慢,已 2 小时</div>
+          </div>
+          <button class="p-2 bg-red-50 rounded-full text-red-600 hover:bg-red-100"><i data-lucide="message-circle" width="16"></i></button>
+        </div>
+
+        <!-- 区块 2: 阶段逾期 -->
+        <div class="section-title text-orange-500 mt-4"><i data-lucide="layers" width="14"></i> 阶段进度滞后</div>
+        
+        <div class="card-b warning">
+          <div class="flex justify-between">
+            <span class="font-bold text-sm">万科城市花园</span>
+            <span class="text-xs bg-blue-50 text-blue-600 px-1.5 py-0.5 rounded">建模</span>
+          </div>
+          <div class="text-xs text-slate-500 mt-1 flex justify-between items-center">
+            <span>李婷 · 逾期2天</span>
+            <span class="text-orange-500 cursor-pointer">催办 ></span>
+          </div>
+        </div>
+        
+        <div class="card-b warning">
+          <div class="flex justify-between">
+            <span class="font-bold text-sm">麓湖生态城</span>
+            <span class="text-xs bg-purple-50 text-purple-600 px-1.5 py-0.5 rounded">后期</span>
+          </div>
+          <div class="text-xs text-slate-500 mt-1">王刚 · 逾期1天</div>
+        </div>
+
+        <!-- 区块 3: 交付截止 -->
+        <div class="section-title text-slate-500 mt-4"><i data-lucide="clock" width="14"></i> 交付/小图</div>
+        <div class="card-b normal">
+          <div class="font-bold text-sm">保利中心 <span class="text-xs font-normal text-slate-400 ml-2">小图截止</span></div>
+          <div class="text-xs text-slate-500 mt-1">今天 18:00</div>
+        </div>
+      </div>
+    </div>
+
+    <!-- 方案 C: 紧凑矩阵版 -->
+    <div id="variant-C" class="variant-container">
+      <div class="panel-header bg-white border-b">
+        <div class="flex items-center gap-4 text-sm w-full">
+          <span class="font-bold text-slate-800 border-b-2 border-slate-800 pb-3 -mb-3.5">所有 (12)</span>
+          <span class="text-slate-500 cursor-pointer pb-3 -mb-3">建模 (2)</span>
+          <span class="text-slate-500 cursor-pointer pb-3 -mb-3">渲染 (1)</span>
+          <span class="text-slate-500 cursor-pointer pb-3 -mb-3">软装 (1)</span>
+        </div>
+      </div>
+      
+      <div class="panel-body" style="padding: 0;">
+        <div class="grid-container">
+          
+          <!-- 矩阵卡片 -->
+          <div class="card-c border-l-4 border-l-red-500">
+            <div class="card-c-header">
+              <span class="text-red-500 font-bold text-xs">客户投诉</span>
+              <span>2h前</span>
+            </div>
+            <div class="card-c-title">锦江上院-13号</div>
+            <div class="text-xs text-slate-500">需立即安抚跟进</div>
+            <button class="w-full mt-1 bg-red-50 text-red-600 text-xs py-1 rounded">处理</button>
+          </div>
+
+          <div class="card-c border-l-4 border-l-orange-500">
+            <div class="card-c-header">
+              <span class="text-orange-500 font-bold text-xs">决策</span>
+              <span>已出图3天</span>
+            </div>
+            <div class="card-c-title">龙湖天街-B座</div>
+            <div class="flex gap-1 mt-1">
+              <button class="flex-1 bg-green-50 text-green-600 text-[10px] py-1 rounded">已反馈</button>
+              <button class="flex-1 bg-slate-50 text-slate-500 text-[10px] py-1 rounded">未回复</button>
+            </div>
+          </div>
+
+          <div class="card-c">
+            <div class="card-c-header">
+              <span class="text-blue-600 bg-blue-50 px-1.5 rounded text-[10px]">建模逾期</span>
+              <span class="text-red-500">-2天</span>
+            </div>
+            <div class="card-c-title">万科城市花园</div>
+            <div class="text-xs text-slate-500">李婷</div>
+            <div class="progress-mini"><div class="progress-bar bg-blue-500" style="width: 30%"></div></div>
+          </div>
+
+          <div class="card-c">
+            <div class="card-c-header">
+              <span class="text-purple-600 bg-purple-50 px-1.5 rounded text-[10px]">后期逾期</span>
+              <span class="text-red-500">-1天</span>
+            </div>
+            <div class="card-c-title">麓湖生态城</div>
+            <div class="text-xs text-slate-500">王刚</div>
+            <div class="progress-mini"><div class="progress-bar bg-purple-500" style="width: 80%"></div></div>
+          </div>
+          
+          <div class="card-c">
+            <div class="card-c-header">
+              <span class="text-yellow-600 bg-yellow-50 px-1.5 rounded text-[10px]">渲染截止</span>
+              <span class="text-orange-500">今天</span>
+            </div>
+            <div class="card-c-title">天鹅湖花园</div>
+            <div class="text-xs text-slate-500">张伟</div>
+            <div class="progress-mini"><div class="progress-bar bg-yellow-500" style="width: 60%"></div></div>
+          </div>
+
+        </div>
+      </div>
+    </div>
+
+  </div>
+
+</div>
+
+<script>
+  lucide.createIcons();
+
+  function showVariant(id) {
+    // 隐藏所有变体
+    document.querySelectorAll('.variant-container').forEach(el => el.classList.remove('active'));
+    // 显示选中的变体
+    document.getElementById('variant-' + id).classList.add('active');
+    
+    // 更新按钮状态
+    document.querySelectorAll('.variant-btn').forEach(el => el.classList.remove('active'));
+    event.currentTarget.classList.add('active');
+  }
+</script>
+
+</body>
+</html>

+ 344 - 0
src/test/urgent-small-events-preview.html

@@ -0,0 +1,344 @@
+<!DOCTYPE html>
+<html lang="zh-CN">
+<head>
+  <meta charset="UTF-8" />
+  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+  <title>小图/决策事件卡片优化预览</title>
+  <script src="https://cdn.tailwindcss.com"></script>
+  <script src="https://unpkg.com/lucide@latest"></script>
+  <style>
+    body {
+      background: #f3f4f6;
+      font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
+    }
+
+    .page-shell {
+      max-width: 1320px;
+      margin: 24px auto;
+      padding: 0 16px 24px;
+    }
+
+    .shadow-soft {
+      box-shadow: 0 10px 30px rgba(15, 23, 42, 0.12);
+    }
+
+    .event-card-shadow {
+      box-shadow: 0 8px 20px rgba(15, 23, 42, 0.06);
+    }
+
+    .status-chip {
+      font-size: 11px;
+      padding: 2px 8px;
+      border-radius: 999px;
+      font-weight: 600;
+      white-space: nowrap;
+    }
+
+    .event-card {
+      position: relative;
+      overflow: hidden;
+    }
+
+    .event-card::before {
+      content: '';
+      position: absolute;
+      inset: 0;
+      pointer-events: none;
+      border-radius: 0.75rem;
+      border: 1px solid rgba(148, 163, 184, 0.15);
+    }
+
+    .left-rail {
+      position: absolute;
+      inset-y: 0;
+      left: 0;
+      width: 4px;
+      border-radius: 0.75rem 0 0 0.75rem;
+    }
+  </style>
+</head>
+<body class="min-h-screen">
+  <div class="page-shell">
+    <!-- 顶部标题 -->
+    <header class="mb-6 flex items-center justify-between">
+      <div>
+        <h1 class="text-xl font-semibold text-slate-900 flex items-center gap-2">
+          <i data-lucide="monitor-pause" class="w-5 h-5 text-orange-500"></i>
+          小图/决策事件卡片优化预览
+        </h1>
+        <p class="mt-1 text-sm text-slate-500">
+          仅展示“小图/决策”标签下的 3 种核心业务场景:小图临近、小图逾期(对图期未跟进)、小图停滞期。
+        </p>
+      </div>
+      <span class="inline-flex items-center gap-1 rounded-full bg-orange-50 px-3 py-1 text-xs text-orange-700">
+        <span class="w-1.5 h-1.5 rounded-full bg-orange-500 animate-pulse"></span>
+        设计预览页面,不影响真实数据
+      </span>
+    </header>
+
+    <div class="grid grid-cols-[2fr,3fr] gap-6 items-start">
+      <!-- 左边:说明与流程示意 -->
+      <aside class="bg-white rounded-2xl shadow-soft border border-slate-200/60 overflow-hidden">
+        <div class="px-5 py-4 border-b border-slate-100 flex items-center gap-2 bg-slate-50/80">
+          <i data-lucide="git-branch" class="w-4 h-4 text-slate-500"></i>
+          <h2 class="text-sm font-semibold text-slate-800">小图处理流程摘要</h2>
+        </div>
+        <div class="px-5 py-4 space-y-4 text-xs text-slate-600">
+          <div>
+            <div class="font-semibold text-slate-700 mb-1 flex items-center gap-2">
+              <span class="w-1.5 h-1.5 rounded-full bg-emerald-400"></span>
+              临近截止 · 询问绘图员
+            </div>
+            <p>小图快到截止时间 → 组长/客服问绘图员能否按时交付:</p>
+            <ul class="mt-1 list-disc list-inside space-y-0.5">
+              <li>若<span class="font-semibold">可以按时</span> → 事件关闭,不再提示</li>
+              <li>若<span class="font-semibold">有风险</span> → 转为高风险 / 重点关注</li>
+            </ul>
+          </div>
+
+          <div>
+            <div class="font-semibold text-slate-700 mb-1 flex items-center gap-2">
+              <span class="w-1.5 h-1.5 rounded-full bg-rose-400"></span>
+              小图逾期 · 对图期未跟进
+            </div>
+            <p>客户已给出对图意见,但绘图员迟迟未改图或提交:</p>
+            <ul class="mt-1 list-disc list-inside space-y-0.5">
+              <li>完成交付 或 项目进入售后 → 事件关闭</li>
+              <li>需要时可同步创建<span class="font-semibold">代办事项</span>给组员跟进</li>
+            </ul>
+          </div>
+
+          <div>
+            <div class="font-semibold text-slate-700 mb-1 flex items-center gap-2">
+              <span class="w-1.5 h-1.5 rounded-full bg-amber-400"></span>
+              小图停滞期 · 客户长时间未反馈
+            </div>
+            <p>小图已发送,但客户长时间没有任何意见:</p>
+            <ul class="mt-1 list-disc list-inside space-y-0.5">
+              <li>客户终于反馈 → 转入<span class="font-semibold">对图期项目</span></li>
+              <li>确认暂停 / 不再跟进 → 事件关闭,可写归因备注</li>
+            </ul>
+          </div>
+        </div>
+      </aside>
+
+      <!-- 右边:卡片预览区域 -->
+      <section class="bg-white rounded-2xl shadow-soft border border-slate-200/70 overflow-hidden flex flex-col">
+        <!-- 头部 -->
+        <div class="px-6 py-4 border-b border-slate-100 flex items-center justify-between bg-gradient-to-r from-orange-50 to-amber-50">
+          <div class="flex items-center gap-2">
+            <span class="flex h-8 w-8 items-center justify-center rounded-full bg-orange-500 text-white text-sm shadow-md">
+              <i data-lucide="alert-triangle" class="w-4 h-4"></i>
+            </span>
+            <div>
+              <div class="text-sm font-semibold text-slate-900">紧急事件监控 · 小图/决策</div>
+              <div class="text-[11px] text-slate-500">围绕“小图临近 / 小图逾期 / 小图停滞期”三个职责场景设计卡片结构</div>
+            </div>
+          </div>
+          <div class="flex items-center gap-2 text-[11px]">
+            <span class="px-2 py-1 rounded-full bg-slate-900 text-slate-50 font-semibold">小图/决策 · 3</span>
+          </div>
+        </div>
+
+        <!-- 小图专属筛选条 -->
+        <div class="px-4 py-2.5 border-b border-slate-100 bg-white flex items-center gap-2 text-xs overflow-x-auto">
+          <span class="mr-1 text-[11px] font-semibold text-slate-500 flex-shrink-0">小图视图:</span>
+          <button class="px-3 py-1.5 rounded-full bg-slate-900 text-white font-semibold shadow-sm flex items-center gap-1 text-[11px] flex-shrink-0">
+            <span>全部小图</span>
+            <span class="inline-flex items-center justify-center rounded-full bg-slate-700 px-1.5 text-[10px]">3</span>
+          </button>
+          <button class="px-3 py-1.5 rounded-full bg-emerald-50 text-emerald-700 border border-emerald-100 flex items-center gap-1 text-[11px] flex-shrink-0">
+            临近截止
+          </button>
+          <button class="px-3 py-1.5 rounded-full bg-rose-50 text-rose-700 border border-rose-100 flex items-center gap-1 text-[11px] flex-shrink-0">
+            对图期逾期
+          </button>
+          <button class="px-3 py-1.5 rounded-full bg-amber-50 text-amber-800 border border-amber-100 flex items-center gap-1 text-[11px] flex-shrink-0">
+            停滞期项目
+          </button>
+        </div>
+
+        <!-- 卡片列表 -->
+        <div class="px-4 py-4 space-y-4 bg-slate-50/60 flex-1 overflow-y-auto">
+          <!-- 卡片 1:小图临近截止 -->
+          <article class="event-card relative rounded-xl bg-white p-4 pl-5 pr-4 flex gap-4 event-card-shadow">
+            <div class="left-rail bg-emerald-500/90"></div>
+            <div class="flex-1 min-w-0 flex flex-col gap-2">
+              <header class="flex items-start gap-2">
+                <div class="flex-1 min-w-0">
+                  <div class="flex items-center gap-2 mb-0.5">
+                    <h3 class="text-sm font-semibold text-slate-900 truncate">小图即将截止 · 万科城市花园-客餐厅</h3>
+                    <span class="status-chip bg-slate-100 text-slate-600">小图/决策</span>
+                  </div>
+                  <div class="flex items-center gap-2 text-[11px] text-slate-500">
+                    <span class="status-chip bg-emerald-50 text-emerald-700 border border-emerald-100 flex items-center gap-1">
+                      <i data-lucide="clock-3" class="w-3 h-3"></i>
+                      临近 · 还有 2 天
+                    </span>
+                  </div>
+                </div>
+              </header>
+
+              <p class="text-xs text-slate-600 leading-relaxed">
+                项目:<span class="font-medium">万科城市花园 · 客餐厅小图</span>,计划截止时间 <span class="font-medium">10-26 18:00</span>。
+                请与 <span class="font-medium">绘图员 张三</span> 确认是否可以按时交付。
+              </p>
+
+              <footer class="mt-1 flex items-center justify-between text-[11px] text-slate-500">
+                <div class="flex flex-wrap items-center gap-x-3 gap-y-1">
+                  <span class="inline-flex items-center gap-1">
+                    <i data-lucide="user" class="w-3 h-3"></i>
+                    绘图员:张三
+                  </span>
+                  <span class="inline-flex items-center gap-1">
+                    <i data-lucide="calendar" class="w-3 h-3"></i>
+                    创建于 10-20 09:30
+                  </span>
+                </div>
+              </footer>
+            </div>
+
+            <!-- 操作区 -->
+            <div class="flex flex-col gap-2 pl-3 border-l border-dashed border-slate-200 min-w-[140px] justify-center">
+              <button class="inline-flex items-center justify-center gap-1 rounded-md bg-emerald-500 hover:bg-emerald-600 text-white text-xs font-semibold px-3 py-1.5 shadow-sm">
+                <i data-lucide="check-circle-2" class="w-3.5 h-3.5"></i>
+                可以按时交付(隐藏本条)
+              </button>
+              <button class="inline-flex items-center justify-center gap-1 rounded-md bg-white hover:bg-amber-50 text-amber-700 text-[11px] font-medium px-3 py-1 border border-amber-200">
+                <i data-lucide="alert-octagon" class="w-3.5 h-3.5"></i>
+                有风险,需要重点关注
+              </button>
+            </div>
+          </article>
+
+          <!-- 卡片 2:小图逾期(对图期未跟进) -->
+          <article class="event-card relative rounded-xl bg-white p-4 pl-5 pr-4 flex gap-4 event-card-shadow">
+            <div class="left-rail bg-rose-500/95"></div>
+            <div class="flex-1 min-w-0 flex flex-col gap-2">
+              <header class="flex items-start gap-2">
+                <div class="flex-1 min-w-0">
+                  <div class="flex items-center gap-2 mb-0.5">
+                    <h3 class="text-sm font-semibold text-slate-900 truncate">小图对图逾期 · 龙湖天街-B座样板间</h3>
+                    <span class="status-chip bg-rose-50 text-rose-700">小图/对图期</span>
+                  </div>
+                  <div class="flex items-center gap-2 text-[11px] text-slate-500">
+                    <span class="status-chip bg-rose-50 text-rose-700 border border-rose-100 flex items-center gap-1">
+                      <i data-lucide="alert-triangle" class="w-3 h-3"></i>
+                      逾期 3 天
+                    </span>
+                  </div>
+                </div>
+              </header>
+
+              <p class="text-xs text-slate-600 leading-relaxed">
+                客户已于 <span class="font-medium">10-22 19:10</span> 提交对图意见,但
+                <span class="font-medium">绘图员 李四</span> 尚未完成改图或交付最新小图,存在服务风险。
+              </p>
+
+              <div class="text-[11px] text-slate-500 flex flex-wrap items-center gap-x-3 gap-y-1">
+                <span class="inline-flex items-center gap-1">
+                  <i data-lucide="file-text" class="w-3 h-3"></i>
+                  最近反馈:希望增加客厅储物、调整灯光氛围
+                </span>
+              </div>
+
+              <footer class="mt-1 flex items-center justify-between text-[11px] text-slate-500">
+                <div class="flex flex-wrap items-center gap-x-3 gap-y-1">
+                  <span class="inline-flex items-center gap-1">
+                    <i data-lucide="user" class="w-3 h-3"></i>
+                    绘图员:李四
+                  </span>
+                  <span class="inline-flex items-center gap-1">
+                    <i data-lucide="building-2" class="w-3 h-3"></i>
+                    项目:龙湖天街-B座
+                  </span>
+                </div>
+              </footer>
+            </div>
+
+            <!-- 操作区 -->
+            <div class="flex flex-col gap-2 pl-3 border-l border-dashed border-slate-200 min-w-[150px] justify-center">
+              <button class="inline-flex items-center justify-center gap-1 rounded-md bg-emerald-500 hover:bg-emerald-600 text-white text-xs font-semibold px-3 py-1.5 shadow-sm">
+                <i data-lucide="check-circle" class="w-3.5 h-3.5"></i>
+                已完成交付
+              </button>
+              <button class="inline-flex items-center justify-center gap-1 rounded-md bg-slate-900 hover:bg-slate-800 text-white text-[11px] font-medium px-3 py-1.5">
+                <i data-lucide="corner-right-up" class="w-3.5 h-3.5"></i>
+                进入售后阶段
+              </button>
+              <button class="inline-flex items-center justify-center gap-1 rounded-md bg-white hover:bg-slate-50 text-slate-600 text-[11px] font-medium px-3 py-1 border border-slate-200">
+                <i data-lucide="clipboard-list" class="w-3.5 h-3.5"></i>
+                创建跟进代办
+              </button>
+            </div>
+          </article>
+
+          <!-- 卡片 3:小图停滞期(客户长时间未反馈) -->
+          <article class="event-card relative rounded-xl bg-white p-4 pl-5 pr-4 flex gap-4 event-card-shadow">
+            <div class="left-rail bg-amber-500"></div>
+            <div class="flex-1 min-w-0 flex flex-col gap-2">
+              <header class="flex items-start gap-2">
+                <div class="flex-1 min-w-0">
+                  <div class="flex items-center gap-2 mb-0.5">
+                    <h3 class="text-sm font-semibold text-slate-900 truncate">小图停滞期 · 锦江上院-13号楼</h3>
+                    <span class="status-chip bg-amber-50 text-amber-800">小图/停滞</span>
+                  </div>
+                  <div class="flex items-center gap-2 text-[11px] text-slate-500">
+                    <span class="status-chip bg-amber-50 text-amber-800 border border-amber-100 flex items-center gap-1">
+                      <i data-lucide="hourglass" class="w-3 h-3"></i>
+                      已停滞 15 天
+                    </span>
+                  </div>
+                </div>
+              </header>
+
+              <p class="text-xs text-slate-600 leading-relaxed">
+                小图已于 <span class="font-medium">10-05 15:20</span> 发送给客户,目前仍未收到任何反馈。
+                请组长判断该项目当前应归入 <span class="font-medium">“对图期项目”</span> 还是继续停滞 / 不再跟进。
+              </p>
+
+              <div class="text-[11px] text-slate-500 flex flex-wrap items-center gap-x-3 gap-y-1">
+                <span class="inline-flex items-center gap-1">
+                  <i data-lucide="user" class="w-3 h-3"></i>
+                  绘图员:王五
+                </span>
+                <span class="inline-flex items-center gap-1">
+                  <i data-lucide="clock" class="w-3 h-3"></i>
+                  上次内部跟进:10-12 10:00
+                </span>
+              </div>
+
+              <footer class="mt-1 text-[11px] text-slate-500">
+                <span class="inline-flex items-center gap-1">
+                  <i data-lucide="sticky-note" class="w-3 h-3"></i>
+                  操作时可选择归因原因,并记录备注,便于后续复盘。
+                </span>
+              </footer>
+            </div>
+
+            <!-- 决策按钮区 -->
+            <div class="flex flex-col gap-2 pl-3 border-l border-dashed border-slate-200 min-w-[180px] justify-center">
+              <button class="inline-flex items-center justify-center gap-1 rounded-md bg-emerald-500 hover:bg-emerald-600 text-white text-xs font-semibold px-3 py-1.5 shadow-sm">
+                <i data-lucide="move-right" class="w-3.5 h-3.5"></i>
+                客户已反馈 · 转入对图期
+              </button>
+              <button class="inline-flex items-center justify-center gap-1 rounded-md bg-amber-50 hover:bg-amber-100 text-amber-800 text-[11px] font-medium px-3 py-1 border border-amber-200">
+                <i data-lucide="pause-circle" class="w-3.5 h-3.5"></i>
+                仍未反馈 · 继续停滞
+              </button>
+              <button class="inline-flex items-center justify-center gap-1 rounded-md bg-white hover:bg-slate-50 text-slate-600 text-[11px] font-medium px-3 py-1 border border-slate-200">
+                <i data-lucide="x-circle" class="w-3.5 h-3.5"></i>
+                不再跟进 / 关闭事件
+              </button>
+            </div>
+          </article>
+        </div>
+      </section>
+    </div>
+  </div>
+
+  <script>
+    lucide.createIcons();
+  </script>
+</body>
+</html>