| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807 | 
							- // 修复 OnDestroy 导入和使用
 
- import { Component, OnInit, OnDestroy, signal, computed } from '@angular/core';
 
- import { CommonModule } from '@angular/common';
 
- import { FormsModule } from '@angular/forms';
 
- import { RouterModule, Router, ActivatedRoute } from '@angular/router';
 
- import { ProjectService } from '../../../services/project.service';
 
- import { Project, Task, CustomerFeedback } from '../../../models/project.model';
 
- @Component({
 
-   selector: 'app-dashboard',
 
-   standalone: true,
 
-   imports: [CommonModule, FormsModule, RouterModule],
 
-   templateUrl: './dashboard.html',
 
-   styleUrls: ['./dashboard.scss', '../customer-service-styles.scss'],
 
-   providers: [ProjectService]
 
- }) 
 
- export class Dashboard implements OnInit, OnDestroy {
 
-   // 数据看板统计
 
-   stats = {
 
-     newConsultations: signal(12),
 
-     pendingAssignments: signal(5),
 
-     exceptionProjects: signal(2),
 
-     afterSalesCount: signal(15), // 售后服务数量
 
-     // 新增核心指标
 
-     conversionRateToday: signal(36), // 当日成交率(%)
 
-     pendingComplaints: signal(3),   // 待处理投诉数
 
-     unRepliedConsultations: signal(7), // 未回复咨询数
 
-     // 新客户触达统计
 
-     newCustomerReachCount: signal(8), // 新客户待触达数量
 
-     newCustomerConversionRate: signal(24), // 新客户转化率(%)
 
-     // 老客户回访统计
 
-     oldCustomerFollowUpCount: signal(6), // 老客户待回访数量
 
-     oldCustomerRetentionRate: signal(78) // 老客户留存率(%)
 
-   };
 
-   // 新增:新客户触达/老客户回访列表(增强版本,包含客户标签和策略)
 
-   newReachOutCustomers = signal<Array<{ 
 
-     name: string; 
 
-     demandType: string; 
 
-     lastContactAt: Date;
 
-     customerTag: 'value-sensitive' | 'price-sensitive';
 
-     recommendedPhrase: string;
 
-     caseStrategy: string;
 
-   }>>([]);
 
-   oldCustomerFollowUps = signal<Array<{ 
 
-     name: string; 
 
-     demandType: string; 
 
-     lastContactAt: Date;
 
-     customerTag: 'value-sensitive' | 'price-sensitive';
 
-     recommendedPhrase: string;
 
-     caseStrategy: string;
 
-   }>>([]);
 
-   urgentTasks = signal<Task[]>([]);
 
-   // 任务处理状态
 
-   taskProcessingState = signal<Partial<Record<string, { inProgress: boolean; progress: number }>>>({});
 
-   
 
-   // 新增:待跟进尾款项目列表
 
-   pendingFinalPaymentProjects = signal<Array<{
 
-     projectId: string;
 
-     projectName: string;
 
-     customerName: string;
 
-     customerPhone: string;
 
-     finalPaymentAmount: number;
 
-     notificationTime: Date;
 
-     status: 'pending_followup' | 'following_up' | 'payment_completed';
 
-     largeImagesSent?: boolean;
 
-   }>>([]);
 
-   
 
-   // 项目动态流
 
-   projectUpdates = signal<(Project | CustomerFeedback)[]>([]);
 
-   
 
-   // 搜索关键词
 
-   searchTerm = signal('');
 
-   
 
-   // 筛选后的项目更新
 
-   filteredUpdates = computed(() => {
 
-     if (!this.searchTerm()) return this.projectUpdates();
 
-     
 
-     return this.projectUpdates().filter(item => {
 
-       if ('name' in item) {
 
-         // 项目
 
-         return item.name.toLowerCase().includes(this.searchTerm().toLowerCase()) ||
 
-                item.customerName.toLowerCase().includes(this.searchTerm().toLowerCase()) ||
 
-                item.status.toLowerCase().includes(this.searchTerm().toLowerCase());
 
-       } else {
 
-         // 反馈
 
-         return 'content' in item && item.content.toLowerCase().includes(this.searchTerm().toLowerCase()) ||
 
-                'status' in item && item.status.toLowerCase().includes(this.searchTerm().toLowerCase());
 
-       }
 
-     });
 
-   });
 
-   currentDate = new Date();
 
-   
 
-   // 回到顶部按钮可见性信号
 
-   showBackToTopSignal = signal(false);
 
-   // 任务表单可见性
 
-   isTaskFormVisible = signal(false);
 
-   
 
-   // 新任务数据
 
-   newTask: Task = {
 
-     id: '',
 
-     projectId: '',
 
-     projectName: '',
 
-     title: '',
 
-     stage: '需求沟通',
 
-     deadline: new Date(),
 
-     isOverdue: false,
 
-     isCompleted: false,
 
-     priority: 'high',
 
-     assignee: '当前用户',
 
-     description: ''
 
-   };
 
-   
 
-   // 用于日期时间输入的属性
 
-   deadlineInput = '';
 
-   
 
-   // 预设快捷时长选项
 
-   timePresets = [
 
-     { label: '1小时内', hours: 1 },
 
-     { label: '3小时内', hours: 3 },
 
-     { label: '6小时内', hours: 6 },
 
-     { label: '12小时内', hours: 12 },
 
-     { label: '24小时内', hours: 24 }
 
-   ];
 
-   
 
-   // 选中的预设时长
 
-   selectedPreset = '';
 
-   
 
-   // 自定义时间弹窗可见性
 
-   isCustomTimeVisible = false;
 
-   
 
-   // 自定义选择的日期和时间
 
-   customDate = new Date();
 
-   customTime = '';
 
-   
 
-   // 错误提示信息
 
-   deadlineError = '';
 
-   
 
-   // 提交按钮是否禁用
 
-   isSubmitDisabled = false;
 
-   
 
-   // 下拉框可见性
 
-   deadlineDropdownVisible = false;
 
-   
 
-   // 日期范围限制
 
-   get todayDate(): string {
 
-     return new Date().toISOString().split('T')[0];
 
-   }
 
-   
 
-   get sevenDaysLaterDate(): string {
 
-     const date = new Date();
 
-     date.setDate(date.getDate() + 7);
 
-     return date.toISOString().split('T')[0];
 
-   }
 
-   constructor(
 
-     private projectService: ProjectService,
 
-     private router: Router,
 
-     private activatedRoute: ActivatedRoute
 
-   ) {}
 
-   ngOnInit(): void {
 
-     this.loadUrgentTasks();
 
-     this.loadProjectUpdates();
 
-     this.loadCRMQueues(); // 新增:加载新客户触达与老客户回访队列
 
-     this.loadPendingFinalPaymentProjects(); // 新增:加载待跟进尾款项目
 
-     
 
-     // 添加滚动事件监听
 
-     window.addEventListener('scroll', this.onScroll.bind(this));
 
-   }
 
-   // 添加滚动事件处理方法
 
-   private onScroll(): void {
 
-     this.showBackToTopSignal.set(window.scrollY > 300);
 
-   }
 
-   
 
-   // 添加显示回到顶部按钮的计算属性
 
-   showBackToTop = computed(() => this.showBackToTopSignal());
 
-   // 清理事件监听器
 
-   ngOnDestroy(): void {
 
-     window.removeEventListener('scroll', this.onScroll.bind(this));
 
-   }
 
-   // 添加scrollToTop方法
 
-   scrollToTop(): void {
 
-     window.scrollTo({
 
-       top: 0,
 
-       behavior: 'smooth'
 
-     });
 
-   }
 
-   // 查看人员考勤
 
-   viewAttendance(): void {
 
-     this.router.navigate(['/hr/attendance']);
 
-   }
 
-   
 
-   // 修改loadUrgentTasks方法,添加status属性
 
-   loadUrgentTasks(): void {
 
-     // 从服务获取任务数据,筛选出紧急任务
 
-     this.projectService.getTasks().subscribe(tasks => {
 
-       const filteredTasks = tasks.map(task => ({...task, status: task.isOverdue ? '已逾期' : task.isCompleted ? '已完成' : '进行中'}))
 
-         .filter(task => task.isOverdue || task.deadline.toDateString() === new Date().toDateString());
 
-       
 
-       this.urgentTasks.set(filteredTasks.sort((a, b) => {
 
-         // 按紧急程度排序
 
-         if (a.isOverdue && !b.isOverdue) return -1;
 
-         if (!a.isOverdue && b.isOverdue) return 1;
 
-         return a.deadline.getTime() - b.deadline.getTime();
 
-       }));
 
-     });
 
-   }
 
-   // 加载新客户触达与老客户回访数据(示例数据,后续可接入接口)
 
-   private loadCRMQueues(): void {
 
-     const now = new Date();
 
-     this.newReachOutCustomers.set([
 
-       { 
 
-         name: '陈女士', 
 
-         demandType: '全屋定制', 
 
-         lastContactAt: new Date(now.getTime() - 2 * 60 * 60 * 1000),
 
-         customerTag: 'value-sensitive',
 
-         recommendedPhrase: '我们的全屋定制方案注重品质与设计的完美结合,为您打造独一无二的家居空间',
 
-         caseStrategy: '推荐高端别墅案例,强调设计理念和材料品质'
 
-       },
 
-       { 
 
-         name: '赵先生', 
 
-         demandType: '厨房改造', 
 
-         lastContactAt: new Date(now.getTime() - 26 * 60 * 60 * 1000),
 
-         customerTag: 'price-sensitive',
 
-         recommendedPhrase: '我们的厨房改造方案性价比极高,在预算范围内实现最大化的功能提升',
 
-         caseStrategy: '推荐经济实用案例,突出成本控制和实用功能'
 
-       },
 
-       { 
 
-         name: '吴先生', 
 
-         demandType: '客厅软装', 
 
-         lastContactAt: new Date(now.getTime() - 5 * 60 * 60 * 1000),
 
-         customerTag: 'value-sensitive',
 
-         recommendedPhrase: '我们的软装设计师将为您量身定制,打造有品味的生活空间',
 
-         caseStrategy: '推荐精品软装案例,强调设计师专业度和美学价值'
 
-       }
 
-     ]);
 
-     this.oldCustomerFollowUps.set([
 
-       { 
 
-         name: '王女士', 
 
-         demandType: '别墅整装', 
 
-         lastContactAt: new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000),
 
-         customerTag: 'value-sensitive',
 
-         recommendedPhrase: '感谢您对我们的信任,我们将继续为您提供高品质的服务体验',
 
-         caseStrategy: '展示同档次别墅案例,强调服务品质和后续保障'
 
-       },
 
-       { 
 
-         name: '李先生', 
 
-         demandType: '卧室升级', 
 
-         lastContactAt: new Date(now.getTime() - 3 * 24 * 60 * 60 * 1000),
 
-         customerTag: 'price-sensitive',
 
-         recommendedPhrase: '我们为老客户准备了特别优惠,让您以更实惠的价格享受升级服务',
 
-         caseStrategy: '推荐性价比升级方案,提供老客户专属优惠'
 
-       },
 
-       { 
 
-         name: '孙女士', 
 
-         demandType: '卫生间翻新', 
 
-         lastContactAt: new Date(now.getTime() - 10 * 24 * 60 * 60 * 1000),
 
-         customerTag: 'value-sensitive',
 
-         recommendedPhrase: '基于您之前的项目经验,我们为您推荐更加精致的翻新方案',
 
-         caseStrategy: '展示精品卫生间案例,强调细节工艺和材料升级'
 
-       }
 
-     ]);
 
-   }
 
-   // 查看全部咨询列表
 
-   goToConsultationList(): void {
 
-     this.router.navigate(['/customer-service/consultation-list']);
 
-   }
 
-   
 
-   loadProjectUpdates(): void {
 
-     // 模拟项目更新数据
 
-     this.projectService.getProjects().subscribe(projects => {
 
-       this.projectService.getCustomerFeedbacks().subscribe(feedbacks => {
 
-         // 合并项目和反馈,按时间倒序排序
 
-         const updates: (Project | CustomerFeedback)[] = [
 
-           ...projects,
 
-           ...feedbacks
 
-         ].sort((a, b) => {
 
-           const dateA = 'createdAt' in a ? a.createdAt : new Date(a['updatedAt'] || a['deadline']);
 
-           const dateB = 'createdAt' in b ? b.createdAt : new Date(b['updatedAt'] || b['deadline']);
 
-           return dateB.getTime() - dateA.getTime();
 
-         }).slice(0, 20); // 限制显示20条
 
-         
 
-         this.projectUpdates.set(updates);
 
-       });
 
-     });
 
-   }
 
-   // 处理任务完成
 
-   markTaskAsCompleted(taskId: string): void {
 
-     this.urgentTasks.set(
 
-       this.urgentTasks().map(task => 
 
-         task.id === taskId ? { ...task, isCompleted: true, status: '已完成' } : task
 
-       )
 
-     );
 
-   }
 
-   // 处理派单操作
 
-   handleAssignment(taskId: string): void {
 
-     // 标记任务为处理中
 
-     const task = this.urgentTasks().find(t => t.id === taskId);
 
-     if (task) {
 
-       // 初始化处理状态
 
-       this.taskProcessingState.update(state => ({
 
-         ...state,
 
-         [task.id]: { inProgress: true, progress: 0 }
 
-       }));
 
-       // 模拟处理进度
 
-       let progress = 0;
 
-       const interval = setInterval(() => {
 
-         progress += 10;
 
-         
 
-         this.taskProcessingState.update(state => ({
 
-           ...state,
 
-           [task.id]: { inProgress: progress < 100, progress }
 
-         }));
 
-         if (progress >= 100) {
 
-           clearInterval(interval);
 
-           
 
-           // 处理完成后从列表中移除该任务
 
-           this.urgentTasks.set(
 
-             this.urgentTasks().filter(t => t.id !== task.id)
 
-           );
 
-           
 
-           // 清除处理状态
 
-           this.taskProcessingState.update(state => {
 
-             const newState = { ...state };
 
-             delete newState[task.id];
 
-             return newState;
 
-           });
 
-         }
 
-       }, 300);
 
-     }
 
-     // 更新统计数据
 
-     this.stats.pendingAssignments.set(this.stats.pendingAssignments() - 1);
 
-   }
 
-   // 显示任务表单
 
-   showTaskForm(): void {
 
-     // 重置表单数据
 
-     this.newTask = {
 
-       id: '',
 
-       projectId: '',
 
-       projectName: '',
 
-       title: '',
 
-       stage: '需求沟通',
 
-       deadline: new Date(),
 
-       isOverdue: false,
 
-       isCompleted: false,
 
-       priority: 'high',
 
-       assignee: '当前用户',
 
-       description: ''
 
-     };
 
-     
 
-     // 重置相关状态
 
-     this.deadlineError = '';
 
-     this.isSubmitDisabled = false;
 
-     
 
-     // 计算并设置默认预设时长
 
-     this.setDefaultPreset();
 
-     
 
-     // 显示表单
 
-     this.isTaskFormVisible.set(true);
 
-     
 
-     // 添加iOS风格的面板显示动画
 
-     setTimeout(() => {
 
-       document.querySelector('.ios-panel')?.classList.add('ios-panel-visible');
 
-     }, 10);
 
-   }
 
-   
 
-   // 设置默认预设时长
 
-   private setDefaultPreset(): void {
 
-     const now = new Date();
 
-     const todayEnd = new Date(now);
 
-     todayEnd.setHours(23, 59, 59, 999);
 
-     
 
-     // 检查3小时后是否超过当天24:00
 
-     const threeHoursLater = new Date(now.getTime() + 3 * 60 * 60 * 1000);
 
-     
 
-     if (threeHoursLater <= todayEnd) {
 
-       // 3小时后未超过当天24:00,默认选中3小时内
 
-       this.selectedPreset = '3';
 
-       this.updatePresetDeadline(3);
 
-     } else {
 
-       // 3小时后超过当天24:00,默认选中当天24:00前
 
-       this.selectedPreset = 'today';
 
-       this.deadlineInput = todayEnd.toISOString().slice(0, 16);
 
-       this.newTask.deadline = todayEnd;
 
-     }
 
-   }
 
-   
 
-   // 处理预设时长选择
 
-   handlePresetSelection(preset: string): void {
 
-     this.selectedPreset = preset;
 
-     this.deadlineError = '';
 
-     
 
-     if (preset === 'custom') {
 
-       // 打开自定义时间选择器
 
-       this.openCustomTimePicker();
 
-     } else if (preset === 'today') {
 
-       // 设置为当天24:00前
 
-       const now = new Date();
 
-       const todayEnd = new Date(now);
 
-       todayEnd.setHours(23, 59, 59, 999);
 
-       
 
-       this.deadlineInput = todayEnd.toISOString().slice(0, 16);
 
-       this.newTask.deadline = todayEnd;
 
-     } else {
 
-       // 计算预设时长的截止时间
 
-       const hours = parseInt(preset);
 
-       this.updatePresetDeadline(hours);
 
-     }
 
-   }
 
-   
 
-   // 更新预设时长的截止时间
 
-   private updatePresetDeadline(hours: number): void {
 
-     const now = new Date();
 
-     const deadline = new Date(now.getTime() + hours * 60 * 60 * 1000);
 
-     
 
-     this.deadlineInput = deadline.toISOString().slice(0, 16);
 
-     this.newTask.deadline = deadline;
 
-   }
 
-   
 
-   // 打开自定义时间选择器
 
-   openCustomTimePicker(): void {
 
-     // 重置自定义时间
 
-     this.customDate = new Date();
 
-     const now = new Date();
 
-     this.customTime = `${now.getHours().toString().padStart(2, '0')}:${now.getMinutes().toString().padStart(2, '0')}`;
 
-     
 
-     // 显示自定义时间弹窗
 
-     this.isCustomTimeVisible = true;
 
-     
 
-     // 添加iOS风格的弹窗动画
 
-     setTimeout(() => {
 
-       document.querySelector('.custom-time-modal')?.classList.add('modal-visible');
 
-     }, 10);
 
-   }
 
-   
 
-   // 关闭自定义时间选择器
 
-   closeCustomTimePicker(): void {
 
-     // 添加iOS风格的弹窗关闭动画
 
-     const modal = document.querySelector('.custom-time-modal');
 
-     if (modal) {
 
-       modal.classList.remove('modal-visible');
 
-       setTimeout(() => {
 
-         this.isCustomTimeVisible = false;
 
-       }, 300);
 
-     } else {
 
-       this.isCustomTimeVisible = false;
 
-     }
 
-   }
 
-   
 
-   // 处理自定义时间选择
 
-   handleCustomTimeSelection(): void {
 
-     const [hours, minutes] = this.customTime.split(':').map(Number);
 
-     const selectedDateTime = new Date(this.customDate);
 
-     selectedDateTime.setHours(hours, minutes, 0, 0);
 
-     
 
-     // 验证选择的时间是否有效
 
-     if (this.validateDeadline(selectedDateTime)) {
 
-       this.deadlineInput = selectedDateTime.toISOString().slice(0, 16);
 
-       this.newTask.deadline = selectedDateTime;
 
-       this.closeCustomTimePicker();
 
-     }
 
-   }
 
-   
 
-   // 验证截止时间是否有效
 
-   validateDeadline(deadline: Date): boolean {
 
-     const now = new Date();
 
-     
 
-     if (deadline < now) {
 
-       this.deadlineError = '截止时间不能早于当前时间,请重新选择';
 
-       this.isSubmitDisabled = true;
 
-       return false;
 
-     }
 
-     
 
-     this.deadlineError = '';
 
-     this.isSubmitDisabled = false;
 
-     return true;
 
-   }
 
-   
 
-   // 获取显示的截止时间文本
 
-   getDisplayDeadline(): string {
 
-     if (!this.deadlineInput) return '';
 
-     
 
-     try {
 
-       const date = new Date(this.deadlineInput);
 
-       return date.toLocaleString('zh-CN', {
 
-         year: 'numeric',
 
-         month: '2-digit',
 
-         day: '2-digit',
 
-         hour: '2-digit',
 
-         minute: '2-digit'
 
-       });
 
-     } catch (error) {
 
-       return '';
 
-     }
 
-   }
 
-   
 
-   // 隐藏任务表单
 
-   hideTaskForm(): void {
 
-     // 添加iOS风格的面板隐藏动画
 
-     const panel = document.querySelector('.ios-panel');
 
-     if (panel) {
 
-       panel.classList.remove('ios-panel-visible');
 
-       setTimeout(() => {
 
-         this.isTaskFormVisible.set(false);
 
-       }, 300);
 
-     } else {
 
-       this.isTaskFormVisible.set(false);
 
-     }
 
-   }
 
-   
 
-   // 处理添加任务表单提交
 
-   handleAddTaskSubmit(): void {
 
-     // 验证表单数据
 
-     if (!this.newTask.title.trim() || !this.newTask.projectName.trim() || !this.deadlineInput || this.isSubmitDisabled) {
 
-       // 在实际应用中,这里应该显示错误提示
 
-       alert('请填写必填字段(任务标题、项目名称、截止时间)');
 
-       return;
 
-     }
 
-     
 
-     // 创建新任务
 
-     const taskToAdd: Task = {
 
-       ...this.newTask,
 
-       id: `task-${Date.now()}`,
 
-       projectId: `project-${Math.floor(Math.random() * 1000)}`,
 
-       deadline: new Date(this.deadlineInput),
 
-       isOverdue: new Date(this.deadlineInput) < new Date()
 
-     };
 
-     
 
-     // 添加到任务列表
 
-     this.urgentTasks.set([taskToAdd, ...this.urgentTasks()]);
 
-     
 
-     // 更新统计数据
 
-     this.stats.pendingAssignments.set(this.stats.pendingAssignments() + 1);
 
-     
 
-     // 隐藏表单
 
-     this.hideTaskForm();
 
-   }
 
-   
 
-   // 添加新的紧急事项
 
-   addUrgentTask(): void {
 
-     // 调用显示表单方法
 
-     this.showTaskForm();
 
-   }
 
-   // 新咨询数图标点击处理
 
-   handleNewConsultationsClick(): void {
 
-     this.navigateToDetail('consultations');
 
-   }
 
-   // 待派单数图标点击处理
 
-   handlePendingAssignmentsClick(): void {
 
-     this.navigateToDetail('assignments');
 
-   }
 
-   // 异常项目图标点击处理
 
-   handleExceptionProjectsClick(): void {
 
-     this.navigateToDetail('exceptions');
 
-   }
 
-   handleAfterSalesClick(): void {
 
-     this.router.navigate(['/customer-service/after-sales']);
 
-   }
 
-   // 导航到详情页
 
-   private navigateToDetail(type: 'consultations' | 'assignments' | 'exceptions'): void {
 
-     const routeMap = {
 
-       consultations: '/customer-service/consultation-list',
 
-       assignments: '/customer-service/assignment-list',
 
-       exceptions: '/customer-service/exception-list'
 
-     };
 
-     
 
-     console.log('导航到:', routeMap[type]);
 
-     console.log('当前路由:', this.router.url);
 
-     
 
-     // 添加iOS风格页面过渡动画
 
-     document.body.classList.add('ios-page-transition');
 
-     setTimeout(() => {
 
-       this.router.navigateByUrl(routeMap[type])
 
-         .then(navResult => {
 
-           console.log('导航结果:', navResult);
 
-           if (!navResult) {
 
-             console.error('导航失败,检查路由配置');
 
-           }
 
-         })
 
-         .catch(err => {
 
-           console.error('导航错误:', err);
 
-         });
 
-       
 
-       setTimeout(() => {
 
-         document.body.classList.remove('ios-page-transition');
 
-       }, 300);
 
-     }, 100);
 
-   }
 
-   // 格式化日期
 
-   formatDate(date: Date | string): string {
 
-     if (!date) return '';
 
-     try {
 
-       return new Date(date).toLocaleString('zh-CN', {
 
-         month: '2-digit',
 
-         day: '2-digit',
 
-         hour: '2-digit',
 
-         minute: '2-digit'
 
-       });
 
-     } catch (error) {
 
-       console.error('日期格式化错误:', error);
 
-       return '';
 
-     }
 
-   }
 
-   // 添加安全获取客户名称的方法
 
- getCustomerName(update: Project | CustomerFeedback): string {
 
-   if ('customerName' in update && update.customerName) {
 
-     return update.customerName;
 
-   } else if ('projectId' in update) {
 
-     // 查找相关项目获取客户名称
 
-     return '客户反馈';
 
-   }
 
-   return '未知客户';
 
- }
 
-   // 优化的日期格式化方法
 
-   getFormattedDate(update: Project | CustomerFeedback): string {
 
-     if (!update) return '';
 
-     
 
-     if ('createdAt' in update && update.createdAt) {
 
-       return this.formatDate(update.createdAt);
 
-     } else if ('updatedAt' in update && update.updatedAt) {
 
-       return this.formatDate(update.updatedAt);
 
-     } else if ('deadline' in update && update.deadline) {
 
-       return this.formatDate(update.deadline);
 
-     }
 
-     return '';
 
-   }
 
-   // 添加获取状态的安全方法
 
- getUpdateStatus(update: Project | CustomerFeedback): string {
 
-   if ('status' in update && update.status) {
 
-     return update.status;
 
-   }
 
-   return '已更新';
 
- }
 
-   // 添加getTaskStatus方法的正确实现
 
-   getTaskStatus(task: Task): string {
 
-     if (!task) return '未知状态';
 
-     if (task.isCompleted) return '已完成';
 
-     if (task.isOverdue) return '已逾期';
 
-     return '进行中';
 
-   }
 
-   // 添加getUpdateStatusClass方法的正确实现
 
-   getUpdateStatusClass(update: Project | CustomerFeedback): string {
 
-     if ('name' in update) {
 
-       // 项目
 
-       switch (update.status) {
 
-         case '进行中': return 'status-active';
 
-         case '已完成': return 'status-completed';
 
-         case '已暂停': return 'status-paused';
 
-         default: return 'status-pending';
 
-       }
 
-     } else {
 
-       // 反馈
 
-       switch (update.status) {
 
-         case '已解决': return 'status-completed';
 
-         case '处理中': return 'status-active';
 
-         default: return 'status-pending';
 
-       }
 
-     }
 
-   }
 
-   // 新增:加载待跟进尾款项目
 
-   loadPendingFinalPaymentProjects(): void {
 
-     // 模拟数据,实际应该从API获取
 
-     const mockProjects = [
 
-       {
 
-         projectId: 'P001',
 
-         projectName: '现代简约客厅设计',
 
-         customerName: '张女士',
 
-         customerPhone: '138****8888',
 
-         finalPaymentAmount: 15000,
 
-         notificationTime: new Date(Date.now() - 2 * 60 * 60 * 1000), // 2小时前
 
-         status: 'pending_followup' as const,
 
-         largeImagesSent: false
 
-       },
 
-       {
 
-         projectId: 'P002',
 
-         projectName: '北欧风格卧室装修',
 
-         customerName: '李先生',
 
-         customerPhone: '139****9999',
 
-         finalPaymentAmount: 22000,
 
-         notificationTime: new Date(Date.now() - 4 * 60 * 60 * 1000), // 4小时前
 
-         status: 'following_up' as const,
 
-         largeImagesSent: false
 
-       },
 
-       {
 
-         projectId: 'P003',
 
-         projectName: '工业风办公室设计',
 
-         customerName: '王总',
 
-         customerPhone: '137****7777',
 
-         finalPaymentAmount: 35000,
 
-         notificationTime: new Date(Date.now() - 6 * 60 * 60 * 1000), // 6小时前
 
-         status: 'payment_completed' as const,
 
-         largeImagesSent: false
 
-       }
 
-     ];
 
-     
 
-     this.pendingFinalPaymentProjects.set(mockProjects);
 
-   }
 
-   // 新增:格式化日期时间
 
-   formatDateTime(date: Date): string {
 
-     const now = new Date();
 
-     const diffMs = now.getTime() - date.getTime();
 
-     const diffHours = Math.floor(diffMs / (1000 * 60 * 60));
 
-     const diffMinutes = Math.floor(diffMs / (1000 * 60));
 
-     if (diffMinutes < 60) {
 
-       return `${diffMinutes}分钟前`;
 
-     } else if (diffHours < 24) {
 
-       return `${diffHours}小时前`;
 
-     } else {
 
-       return date.toLocaleDateString('zh-CN', { 
 
-         month: 'short', 
 
-         day: 'numeric',
 
-         hour: '2-digit',
 
-         minute: '2-digit'
 
-       });
 
-     }
 
-   }
 
-   // 新增:获取支付状态文本
 
-   getPaymentStatusText(status: string): string {
 
-     switch (status) {
 
-       case 'pending_followup': return '待跟进';
 
-       case 'following_up': return '跟进中';
 
-       case 'payment_completed': return '已支付';
 
-       default: return '未知状态';
 
-     }
 
-   }
 
-   // 新增:开始跟进尾款
 
-   followUpFinalPayment(projectId: string): void {
 
-     const projects = this.pendingFinalPaymentProjects();
 
-     const updatedProjects = projects.map(project => {
 
-       if (project.projectId === projectId) {
 
-         return { ...project, status: 'following_up' as const };
 
-       }
 
-       return project;
 
-     });
 
-     this.pendingFinalPaymentProjects.set(updatedProjects);
 
-     
 
-     console.log(`开始跟进项目 ${projectId} 的尾款`);
 
-     // 这里可以添加实际的跟进逻辑,比如发送消息、创建任务等
 
-   }
 
-   // 新增:一键发送大图
 
-   sendLargeImages(projectId: string): void {
 
-     const projects = this.pendingFinalPaymentProjects();
 
-     const project = projects.find(p => p.projectId === projectId);
 
-     
 
-     if (!project) return;
 
-     
 
-     console.log(`正在为项目 ${projectId} 发送大图到企业微信...`);
 
-     
 
-     // 模拟发送过程
 
-     setTimeout(() => {
 
-       const updatedProjects = projects.map(p => {
 
-         if (p.projectId === projectId) {
 
-           return { ...p, largeImagesSent: true };
 
-         }
 
-         return p;
 
-       });
 
-       this.pendingFinalPaymentProjects.set(updatedProjects);
 
-       
 
-       console.log(`✅ 项目 ${projectId} 大图已成功发送到企业微信服务群`);
 
-       console.log(`📱 已同步发送支付成功与大图交付通知`);
 
-       
 
-       alert(`🎉 大图发送成功!
 
- ✅ 已完成操作:
 
- • 大图已发送至企业微信服务群
 
- • 已通知客户支付成功
 
- • 已确认大图交付完成
 
- 项目:${project.projectName}
 
- 客户:${project.customerName}`);
 
-     }, 2000);
 
-   }
 
- }
 
 
  |