import { Component, EventEmitter, OnInit, Output, Input, OnChanges, SimpleChanges } from '@angular/core'; import { FormBuilder, FormGroup, Validators, ReactiveFormsModule } from '@angular/forms'; import { CommonModule } from '@angular/common'; import { TeamAssignmentModalComponent, Designer } from '../team-assignment-modal/team-assignment-modal.component'; import { FormsModule } from '@angular/forms'; import { MatChipsModule } from '@angular/material/chips'; import { MatIconModule } from '@angular/material/icon'; // 定义客户信息接口 interface Customer { id: string; name: string; phone: string; wechat?: string; avatar?: string; customerType?: string; source?: string; remark?: string; demandType?: string; preferenceTags?: string[]; followUpStatus?: string; } @Component({ selector: 'app-consultation-order-panel', standalone: true, imports: [ CommonModule, ReactiveFormsModule, FormsModule, MatChipsModule, MatIconModule, TeamAssignmentModalComponent ], templateUrl: './consultation-order-panel.component.html', styleUrls: ['./consultation-order-panel.component.scss'] }) export class ConsultationOrderPanelComponent implements OnInit, OnChanges { @Output() orderCreated = new EventEmitter(); @Output() projectCreated = new EventEmitter(); // 新增项目创建成功事件 @Input() syncData: any = null; // 接收同步的订单数据 // 搜索客户关键词 searchKeyword = ''; // 搜索结果列表 searchResults: Customer[] = []; // 选中的客户 selectedCustomer: Customer | null = null; // 表单提交状态 isSubmitting = false; // 项目需求卡片展开状态 - 默认展开以便用户填写必填字段 isRequirementCardExpanded = true; // 需求表单 requirementForm: FormGroup; // 客户表单 customerForm: FormGroup; // 团队分配弹窗相关 showTeamAssignmentModal = false; selectedDesigner: Designer | null = null; // 新增:自动分配用的设计师池(与弹窗组件保持一致的数据结构) private allDesigners: Designer[] = [ { id: '1', name: '张设计师', role: '高级室内设计师', avatar: '/assets/images/default-avatar.svg', skills: ['现代简约', '北欧风格', '工业风'], workload: { level: 'low', percentage: 30, text: '轻度' }, recentTasks: [ { id: '1', name: '海景别墅设计', projectName: '海景别墅设计', stage: 'modeling', deadline: '2024-01-15' }, { id: '2', name: '现代公寓改造', projectName: '现代公寓改造', stage: 'rendering', deadline: '2024-01-20' } ] }, { id: '2', name: '李设计师', role: '资深设计总监', avatar: '/assets/images/default-avatar.svg', skills: ['欧式古典', '美式乡村', '中式传统'], workload: { level: 'medium', percentage: 65, text: '中度' }, recentTasks: [ { id: '3', name: '豪华会所设计', projectName: '豪华会所设计', stage: 'soft-decoration', deadline: '2024-01-18' }, { id: '4', name: '商业空间规划', projectName: '商业空间规划', stage: 'post-production', deadline: '2024-01-25' }, { id: '5', name: '私人定制住宅', projectName: '私人定制住宅', stage: 'modeling', deadline: '2024-02-01' } ] }, { id: '3', name: '王设计师', role: '创意设计师', avatar: '/assets/images/default-avatar.svg', skills: ['极简主义', '日式禅风', '斯堪的纳维亚'], workload: { level: 'high', percentage: 85, text: '重度' }, recentTasks: [ { id: '6', name: '艺术画廊设计', projectName: '艺术画廊设计', stage: 'rendering', deadline: '2024-01-12' }, { id: '7', name: '精品酒店套房', projectName: '精品酒店套房', stage: 'soft-decoration', deadline: '2024-01-16' }, { id: '8', name: '创意办公空间', projectName: '创意办公空间', stage: 'post-production', deadline: '2024-01-22' }, { id: '9', name: '高端住宅项目', projectName: '高端住宅项目', stage: 'modeling', deadline: '2024-01-28' } ] }, { id: '4', name: '陈设计师', role: '室内设计师', avatar: '/assets/images/default-avatar.svg', skills: ['新中式', '轻奢风格', '混搭风格'], workload: { level: 'low', percentage: 20, text: '轻度' }, recentTasks: [ { id: '10', name: '温馨家庭住宅', projectName: '温馨家庭住宅', stage: 'modeling', deadline: '2024-01-30' } ] }, // 新增:完全空闲的设计师用于自动分配展示 { id: '5', name: '赵设计师', role: '室内设计师', avatar: '/assets/images/default-avatar.svg', skills: ['现代简约', '北欧风格'], workload: { level: 'low', percentage: 0, text: '空闲' }, recentTasks: [] } ]; // 样式选项 styleOptions = [ '现代简约', '北欧风', '工业风', '新中式', '法式轻奢', '日式', '美式', '混搭' ]; // 项目小组选项 projectGroupOptions = [ '设计一组', '设计二组', '设计三组', '高端定制组', '软装设计组' ]; // 偏好标签选项 preferenceTagOptions = [ '柔和色系', '明亮色系', '深色系', '中性色系', '环保材料', '实木', '大理石', '瓷砖', '地板', '墙纸', '现代简约', '北欧风格', '中式风格', '美式风格', '工业风', '智能家电', '收纳空间', '开放式厨房', '大窗户' ]; preferenceTags: string[] = []; // 新标签输入 newTag = ''; // 角色上下文 roleContext: 'customer-service' | 'designer' | 'team-leader' = 'customer-service'; constructor(private fb: FormBuilder) { // 初始化需求表单 this.requirementForm = this.fb.group({ downPayment: ['', [Validators.required, Validators.min(0)]], budget: ['', Validators.required], area: ['', [Validators.required, Validators.min(1)]], smallImageTime: [''], largeImageTime: [''], houseType: [''], floor: ['', Validators.min(1)], preferredDesigner: [''], specialRequirements: [''], referenceCases: [[]], priceDetails: [''], // 新增字段 spaceRequirements: [''], designAngles: [''], specialAreaHandling: [''], materialRequirements: [''], lightingRequirements: [''] }); // 初始化客户表单 this.customerForm = this.fb.group({ wechat: [''], customerType: ['新客户'], source: [''], remark: [''], demandType: [''], followUpStatus: [''] }); } ngOnInit(): void { // 监听表单变化,实时更新阶段状态 this.customerForm.valueChanges.subscribe(() => { this.checkStageCompletion(); }); this.requirementForm.valueChanges.subscribe(() => { this.checkStageCompletion(); }); // 初始检查阶段状态 this.checkStageCompletion(); // 如果有同步数据,立即填充表单 if (this.syncData) { this.fillFormWithSyncData(this.syncData); } } ngOnChanges(changes: SimpleChanges): void { // 当syncData发生变化时,填充表单数据 if (changes['syncData'] && changes['syncData'].currentValue) { this.fillFormWithSyncData(changes['syncData'].currentValue); } } // 使用同步数据填充表单 private fillFormWithSyncData(data: any): void { if (data.customerInfo) { this.customerForm.patchValue(data.customerInfo); this.selectedCustomer = data.customerInfo; } if (data.requirementInfo) { this.requirementForm.patchValue(data.requirementInfo); } if (data.preferenceTags && Array.isArray(data.preferenceTags)) { this.preferenceTags = [...data.preferenceTags]; } // 更新阶段完成状态 this.checkStageCompletion(); } // 搜索客户 searchCustomer() { if (this.searchKeyword.length >= 2) { // 模拟搜索结果 this.searchResults = [ { id: '1', name: '张先生', phone: '138****5678', customerType: '老客户', source: '官网咨询', avatar: "data:image/svg+xml,%3Csvg width='64' height='40' xmlns='http://www.w3.org/2000/svg'%3E%3Crect width='100%25' height='100%25' fill='%23E6E6E6'/%3E%3Ctext x='50%25' y='50%25' font-family='Arial' font-size='13.333333333333334' font-weight='bold' text-anchor='middle' fill='%23555555' dy='0.3em'%3EIMG%3C/text%3E%3C/svg%3E" }, { id: '2', name: '李女士', phone: '139****1234', customerType: 'VIP客户', source: '推荐介绍', avatar: "data:image/svg+xml,%3Csvg width='65' height='40' xmlns='http://www.w3.org/2000/svg'%3E%3Crect width='100%25' height='100%25' fill='%23DCDCDC'/%3E%3Ctext x='50%25' y='50%25' font-family='Arial' font-size='13.333333333333334' font-weight='bold' text-anchor='middle' fill='%23555555' dy='0.3em'%3EIMG%3C/text%3E%3C/svg%3E" } ]; } } // 选择客户 selectCustomer(customer: Customer) { this.selectedCustomer = customer; // 填充客户表单 this.customerForm.patchValue({ name: customer.name, phone: customer.phone, wechat: customer.wechat || '', customerType: customer.customerType || '新客户', source: customer.source || '', remark: customer.remark || '' }); // 清空搜索结果 this.searchResults = []; this.searchKeyword = ''; } // 清除选中的客户 clearSelectedCustomer() { this.selectedCustomer = null; this.customerForm.reset({ customerType: '新客户' }); } // 添加偏好标签 addPreferenceTag(tag: string): void { if (tag && !this.preferenceTags.includes(tag)) { this.preferenceTags.push(tag); this.newTag = ''; // 清空输入框 } } // 删除偏好标签 removePreferenceTag(tag: string): void { const index = this.preferenceTags.indexOf(tag); if (index >= 0) { this.preferenceTags.splice(index, 1); } } // 流程状态管理 stageCompletionStatus = { customerInfo: false, projectRequirements: false, teamAssignment: false, orderConfirmation: false }; // 获取阶段状态文本 getStageStatusText(stage: keyof typeof this.stageCompletionStatus): string { if (this.stageCompletionStatus[stage]) { return '已完成'; } else { // 检查是否为未开始状态 const stages = ['customerInfo', 'projectRequirements', 'teamAssignment', 'orderConfirmation']; const currentIndex = stages.indexOf(stage); // 检查前面的阶段是否都已完成 let allPreviousCompleted = true; for (let i = 0; i < currentIndex; i++) { if (!this.stageCompletionStatus[stages[i] as keyof typeof this.stageCompletionStatus]) { allPreviousCompleted = false; break; } } return allPreviousCompleted ? '进行中' : '未进行'; } } // 获取阶段状态类名 getStageStatusClass(stage: keyof typeof this.stageCompletionStatus): string { if (this.stageCompletionStatus[stage]) { return 'stage-completed'; } else { // 检查是否为未开始状态 const stages = ['customerInfo', 'projectRequirements', 'teamAssignment', 'orderConfirmation']; const currentIndex = stages.indexOf(stage); // 检查前面的阶段是否都已完成 let allPreviousCompleted = true; for (let i = 0; i < currentIndex; i++) { if (!this.stageCompletionStatus[stages[i] as keyof typeof this.stageCompletionStatus]) { allPreviousCompleted = false; break; } } return allPreviousCompleted ? 'stage-in-progress' : 'stage-pending'; } } // 获取进度百分比 getProgressPercentage(): number { const completedStages = Object.values(this.stageCompletionStatus).filter(status => status).length; return Math.round((completedStages / 4) * 100); } // 检查阶段完成状态 private checkStageCompletion(): void { // 检查客户信息阶段 - 客户信息表单有效 this.stageCompletionStatus.customerInfo = this.customerForm.valid; // 检查项目需求阶段 - 需求表单有效 this.stageCompletionStatus.projectRequirements = this.requirementForm.valid; // 检查团队分配阶段 - 已选择设计师 this.stageCompletionStatus.teamAssignment = !!this.selectedDesigner; // 检查订单确认阶段 - 所有前面阶段都完成 this.stageCompletionStatus.orderConfirmation = this.stageCompletionStatus.customerInfo && this.stageCompletionStatus.projectRequirements && this.stageCompletionStatus.teamAssignment; } // 检查表单是否有效 isFormValid(): boolean { return this.customerForm.valid && this.requirementForm.valid; } // 检查是否可以创建订单(放宽条件:仅需表单有效即可点击创建,设计师由系统自动分配或人工分配) canCreateOrder(): boolean { return this.isFormValid(); } // 创建订单方法(支持自动分配空闲设计师) createOrder() { // 表单未通过校验则不允许创建 if (!this.isFormValid()) { return; } // 若尚未选择设计师,尝试自动分配空闲设计师 if (!this.selectedDesigner) { const assigned = this.autoAssignDesignerIfAvailable(); if (!assigned) { // 无空闲设计师:阻止创建并弹出分配弹窗 this.showTeamAssignmentModal = true; return; } } this.isSubmitting = true; // 构建完整的项目数据 const formData = { customerInfo: this.customerForm.value, requirementInfo: this.requirementForm.value, preferenceTags: this.preferenceTags, roleContext: this.roleContext, createdAt: new Date() }; const projectData = { customerInfo: this.customerForm.value, requirementInfo: this.requirementForm.value, preferenceTags: this.preferenceTags, assignedDesigner: this.selectedDesigner, createdAt: new Date() }; // 先触发订单创建事件(用于数据同步) this.orderCreated.emit(formData); // 再触发项目创建成功事件(用于阶段推进) this.projectCreated.emit(projectData); // 重置表单 this.customerForm.reset({ customerType: '新客户' }); this.requirementForm.reset(); this.preferenceTags = []; this.selectedCustomer = null; this.selectedDesigner = null; this.isSubmitting = false; } // 提交表单 - 保留原有逻辑但简化 submitForm() { this.createOrder(); } // 关闭团队分配弹窗 closeTeamAssignmentModal() { this.showTeamAssignmentModal = false; } // 确认团队分配 - 优化流程:同时触发订单创建和项目创建事件 confirmTeamAssignment(designer: Designer) { this.selectedDesigner = designer; this.showTeamAssignmentModal = false; this.isSubmitting = false; // 重置提交状态 // 更新阶段状态 this.checkStageCompletion(); // 构建完整的项目数据 const formData = { customerInfo: this.customerForm.value, requirementInfo: this.requirementForm.value, preferenceTags: this.preferenceTags, roleContext: this.roleContext, // 添加角色上下文信息 createdAt: new Date() }; const projectData = { customerInfo: this.customerForm.value, requirementInfo: this.requirementForm.value, preferenceTags: this.preferenceTags, assignedDesigner: designer, createdAt: new Date() }; // 先触发订单创建事件(用于数据同步) this.orderCreated.emit(formData); // 再触发项目创建成功事件(用于阶段推进) this.projectCreated.emit(projectData); // 重置表单 this.customerForm.reset({ customerType: '新客户' }); this.requirementForm.reset(); this.preferenceTags = []; this.selectedCustomer = null; } // 新增:查找空闲设计师(低负载且在项少于等于1) private findAvailableDesigners(): Designer[] { return this.allDesigners.filter(d => d.workload.level === 'low' && (d.recentTasks?.length || 0) === 0); } // 新增:自动随机分配空闲设计师 private autoAssignDesignerIfAvailable(): boolean { const candidates = this.findAvailableDesigners(); if (candidates.length === 0) { return false; } const randomIndex = Math.floor(Math.random() * candidates.length); this.selectedDesigner = candidates[randomIndex]; // 更新阶段状态(选择了设计师) this.checkStageCompletion(); return true; } }