import { Component, signal, Inject, Output, EventEmitter } from '@angular/core'; import { CommonModule } from '@angular/common'; import { FormsModule, ReactiveFormsModule, FormBuilder, FormGroup, Validators } from '@angular/forms'; import { Router, RouterModule } from '@angular/router'; import { ProjectService } from '../../../services/project.service'; import { MatChipInputEvent } from '@angular/material/chips'; import { COMMA, ENTER } from '@angular/cdk/keycodes'; import { MatChipsModule } from '@angular/material/chips'; import { MatIconModule } from '@angular/material/icon'; import { MatSnackBar, MatSnackBarModule } from '@angular/material/snack-bar'; import { MatDialog, MatDialogModule, MAT_DIALOG_DATA } from '@angular/material/dialog'; import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; import { ProjectGroupDialog } from './project-group-dialog.component'; // 定义客户信息接口 interface Customer { id: string; name: string; phone: string; wechat?: string; avatar?: string; customerType?: string; // 新客户/老客户/VIP客户 source?: string; // 来源渠道 remark?: string; // 客户标签信息 demandType?: string; preferenceTags?: string[]; followUpStatus?: string; } // 定义需求信息接口 interface Requirement { style: string; budget: string; area: number; houseType: string; floor: number; decorationType: string; preferredDesigner?: string; specialRequirements?: string; referenceCases?: string[]; } // 标签选项定义 const DEMAND_TYPES = [ { value: 'price', label: '价格敏感' }, { value: 'quality', label: '质量敏感' }, { value: 'comprehensive', label: '综合要求' } ]; const FOLLOW_UP_STATUS = [ { value: 'quotation', label: '待报价' }, { value: 'confirm', label: '待确认需求' }, { value: 'lost', label: '已失联' } ]; // 预设的偏好标签选项 const PREFERENCE_TAG_OPTIONS = [ // 颜色偏好 '柔和色系', '明亮色系', '深色系', '中性色系', // 材质偏好 '环保材料', '实木', '大理石', '瓷砖', '地板', '墙纸', // 风格偏好 '现代简约', '北欧风格', '中式风格', '美式风格', '工业风', // 其他偏好 '智能家电', '收纳空间', '开放式厨房', '大窗户' ]; @Component({ selector: 'app-consultation-order', standalone: true, imports: [ CommonModule, FormsModule, ReactiveFormsModule, RouterModule, MatChipsModule, MatIconModule, MatSnackBarModule, MatDialogModule, MatProgressSpinnerModule ], templateUrl: './consultation-order.html', styleUrls: ['./consultation-order.scss', '../customer-service-styles.scss'] }) export class ConsultationOrder { // 搜索客户关键词 searchKeyword = signal(''); // 搜索结果列表 searchResults = signal([]); // 选中的客户 selectedCustomer = signal(null); // 报价范围 estimatedPriceRange = signal(''); // 匹配的案例 matchedCases = signal([]); // 表单提交状态 isSubmitting = signal(false); // 成功提示显示状态 showSuccessMessage = signal(false); // 下单时间(自动生成) orderTime = signal(''); // 项目需求卡片展开状态 isRequirementCardExpanded = signal(false); // 订单创建成功事件 @Output() orderCreated = new EventEmitter(); // 需求表单 requirementForm: FormGroup; // 客户表单 customerForm: FormGroup; // 项目配置表单 projectForm: FormGroup; // 样式选项 styleOptions = [ '现代简约', '北欧风', '工业风', '新中式', '法式轻奢', '日式', '美式', '混搭' ]; // 装修风格选项(用于项目配置) decorationStyles = [ { value: 'modern', label: '现代简约' }, { value: 'nordic', label: '北欧风' }, { value: 'industrial', label: '工业风' }, { value: 'chinese', label: '新中式' }, { value: 'french', label: '法式轻奢' }, { value: 'japanese', label: '日式' }, { value: 'american', label: '美式' }, { value: 'mixed', label: '混搭' } ]; // 项目小组选项 projectGroups = [ { value: 'design1', label: '设计一组' }, { value: 'design2', label: '设计二组' }, { value: 'design3', label: '设计三组' }, { value: 'premium', label: '高端定制组' }, { value: 'soft', label: '软装设计组' } ]; // 项目小组选项(兼容性) projectGroupOptions = [ '设计一组', '设计二组', '设计三组', '高端定制组', '软装设计组' ]; // 标签系统 demandTypes = DEMAND_TYPES; followUpStatus = FOLLOW_UP_STATUS; preferenceTagOptions = PREFERENCE_TAG_OPTIONS; addOnBlur = true; readonly separatorKeysCodes = [ENTER, COMMA] as const; preferenceTags: string[] = []; constructor( private fb: FormBuilder, private projectService: ProjectService, private snackBar: MatSnackBar, private dialog: MatDialog, private router: Router ) { // 初始化需求表单(保留兼容性) this.requirementForm = this.fb.group({ decorationType: ['', Validators.required], // 装修类型(必填) downPayment: ['', [Validators.required, Validators.min(0)]], // 首付款(必填) firstDraftDate: ['', Validators.required], // 首稿时间(必填) style: [''], // 装修风格(选填) projectGroup: [''], // 项目小组(选填) budget: ['', Validators.required], area: ['', [Validators.required, Validators.min(1)]], houseType: [''], // 改为非必填 floor: ['', Validators.min(1)], preferredDesigner: [''], specialRequirements: [''], referenceCases: [[]], priceDetails: [''] // 价格明细 }); // 初始化客户表单 this.customerForm = this.fb.group({ name: ['', Validators.required], phone: ['', [Validators.required, Validators.pattern(/^1[3-9]\d{9}$/)]], wechat: [''], customerType: ['新客户'], source: [''], remark: [''], demandType: [''], followUpStatus: [''] }); // 初始化项目配置表单 this.projectForm = this.fb.group({ style: ['', Validators.required], // 风格选择 projectGroup: ['', Validators.required], // 项目组匹配 downPaymentSetting: ['', Validators.required], // 首付款设置 downPaymentAmount: ['', [Validators.required, Validators.min(0)]], // 首付款填写 firstDraftConfirm: [false, Validators.requiredTrue], // 首稿时间确认 firstDraftDate: ['', Validators.required] // 首稿时间设置 }); // 自动生成下单时间 this.orderTime.set(new Date().toLocaleString('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit' })); // 监听表单值变化,自动计算报价和匹配案例 this.requirementForm.valueChanges.subscribe(() => { this.calculateEstimatedPrice(); this.matchCases(); }); } // 添加偏好标签 addPreferenceTag(event: MatChipInputEvent): void { const value = (event.value || '').trim(); // 添加标签,如果它不是空的,并且不在已有标签中 if (value && !this.preferenceTags.includes(value)) { this.preferenceTags.push(value); } // 清空输入框 if (event.input) { event.input.value = ''; } } // 删除偏好标签 removePreferenceTag(tag: string): void { const index = this.preferenceTags.indexOf(tag); if (index >= 0) { this.preferenceTags.splice(index, 1); } } // 从预设选项中添加标签 addFromPreset(tag: string): void { if (!this.preferenceTags.includes(tag)) { this.preferenceTags.push(tag); } } // 搜索客户 searchCustomer() { if (this.searchKeyword().length >= 2) { // 模拟搜索结果 this.searchResults.set([ { 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.set(customer); // 填充客户表单 this.customerForm.patchValue({ name: customer.name, phone: customer.phone, wechat: customer.wechat || '', customerType: customer.customerType || '新客户', source: customer.source || '', remark: customer.remark || '' }); // 如果是老客户,自动填充历史信息 if (customer.customerType === '老客户' || customer.customerType === 'VIP客户') { this.loadCustomerHistory(customer.id); } // 清空搜索结果 this.searchResults.set([]); this.searchKeyword.set(''); } // 清除选中的客户 clearSelectedCustomer() { this.selectedCustomer.set(null); this.customerForm.reset({ customerType: '新客户' }); } // 计算预估报价 calculateEstimatedPrice() { const { area, decorationType, style } = this.requirementForm.value; if (area && decorationType) { // 模拟报价计算逻辑 let basePrice = 0; switch (decorationType) { case '全包': basePrice = 1800; break; case '半包': basePrice = 1200; break; case '清包': basePrice = 800; break; case '旧房翻新': basePrice = 2000; break; case '局部改造': basePrice = 1500; break; default: basePrice = 1200; break; } // 风格加价 const stylePremium = ['法式轻奢', '新中式', '日式'].includes(style) ? 0.2 : 0; const totalPrice = area * basePrice * (1 + stylePremium); const lowerBound = Math.floor(totalPrice * 0.9); const upperBound = Math.ceil(totalPrice * 1.1); this.estimatedPriceRange.set( `¥${lowerBound.toLocaleString()} - ¥${upperBound.toLocaleString()}` ); } } // 匹配案例 matchCases() { const { style, houseType, area } = this.requirementForm.value; if (style && houseType && area) { // 模拟匹配案例 this.matchedCases.set([ { id: '101', name: `${style}风格 ${houseType}设计`, imageUrl: `https://picsum.photos/id/${30 + Math.floor(Math.random() * 10)}/300/200`, designer: '王设计师', area: area + '㎡', similarity: 92 }, { id: '102', name: `${houseType} ${style}案例展示`, imageUrl: `https://picsum.photos/id/${40 + Math.floor(Math.random() * 10)}/300/200`, designer: '张设计师', area: (area + 10) + '㎡', similarity: 85 } ]); } } // 选择参考案例 selectReferenceCase(caseItem: any) { const currentCases = this.requirementForm.get('referenceCases')?.value || []; if (!currentCases.includes(caseItem.id)) { this.requirementForm.patchValue({ referenceCases: [...currentCases, caseItem.id] }); } } // 移除参考案例 removeReferenceCase(caseId: string) { const currentCases = this.requirementForm.get('referenceCases')?.value || []; this.requirementForm.patchValue({ referenceCases: currentCases.filter((id: string) => id !== caseId) }); } // 提交表单 submitForm() { if (this.customerForm.valid) { this.isSubmitting.set(true); const formData = { customerInfo: this.customerForm.value, requirementInfo: this.requirementForm.value, estimatedPriceRange: this.estimatedPriceRange(), createdAt: new Date() }; // 模拟提交请求 setTimeout(() => { console.log('提交的表单数据:', formData); this.isSubmitting.set(false); this.showSuccessMessage.set(true); // 1秒后隐藏成功提示并跳转 setTimeout(() => { this.showSuccessMessage.set(false); // 发出订单创建成功事件,用于关闭弹窗 const orderData = { orderId: 'mock-9', customerName: formData.customerInfo.name, projectId: 'mock-9' }; this.orderCreated.emit(orderData); // 跳转到设计师项目详情页面,传递客服角色标识 this.router.navigate(['/designer/project-detail/mock-9'], { queryParams: { role: 'customer-service' } }); }, 1000); }, 1500); } } // 基于六项核心字段的最小创建可用性判断 minimalReady(): boolean { const nameCtrl = this.customerForm.get('name'); const phoneCtrl = this.customerForm.get('phone'); const styleCtrl = this.requirementForm.get('style'); const groupCtrl = this.requirementForm.get('projectGroup'); const downPaymentCtrl = this.requirementForm.get('downPayment'); const firstDraftDateCtrl = this.requirementForm.get('firstDraftDate'); const nameOk = !!nameCtrl?.value && nameCtrl.valid; const phoneOk = !!phoneCtrl?.value && phoneCtrl.valid; const styleOk = !!styleCtrl?.value; const groupOk = !!groupCtrl?.value; const downPaymentOk = downPaymentCtrl != null && downPaymentCtrl.valid && downPaymentCtrl.value !== null && downPaymentCtrl.value !== ''; const firstDraftOk = !!firstDraftDateCtrl?.value; return !!(nameOk && phoneOk && styleOk && groupOk && downPaymentOk && firstDraftOk); } // 创建项目(最小必填:姓名、手机、风格、项目组、首付款、首稿时间) createProjectMinimal() { const nameCtrl = this.customerForm.get('name'); const phoneCtrl = this.customerForm.get('phone'); const styleCtrl = this.requirementForm.get('style'); const groupCtrl = this.requirementForm.get('projectGroup'); const downPaymentCtrl = this.requirementForm.get('downPayment'); const firstDraftDateCtrl = this.requirementForm.get('firstDraftDate'); if (!nameCtrl?.value || !phoneCtrl?.value || !styleCtrl?.value || !groupCtrl?.value || downPaymentCtrl?.value === null || !firstDraftDateCtrl?.value) { this.snackBar.open('请完整填写姓名、手机、风格、项目组、首付款、首稿时间', '关闭', { duration: 3000 }); return; } this.isSubmitting.set(true); const payload = { customerId: 'temp-' + Date.now(), customerName: nameCtrl.value, requirement: { style: styleCtrl.value, projectGroup: groupCtrl.value, downPayment: Number(downPaymentCtrl?.value ?? 0), firstDraftDate: firstDraftDateCtrl?.value }, referenceCases: [], tags: { followUpStatus: '待分配' } }; this.projectService.createProject(payload).subscribe( (res: any) => { this.isSubmitting.set(false); if (res?.success) { this.showSuccessMessage.set(true); this.snackBar.open('项目创建成功', '关闭', { duration: 2000 }); // 延迟跳转到项目详情页面 setTimeout(() => { this.showSuccessMessage.set(false); // 发出订单创建成功事件,用于关闭弹窗 const orderData = { orderId: 'mock-9', customerName: nameCtrl.value, projectId: 'mock-9' }; this.orderCreated.emit(orderData); // 跳转到设计师项目详情页面,传递客服角色标识 this.router.navigate(['/designer/project-detail/mock-9'], { queryParams: { role: 'customer-service' } }); }, 1000); } else { this.snackBar.open('创建失败,请稍后重试', '关闭', { duration: 3000 }); } }, () => { this.isSubmitting.set(false); this.snackBar.open('创建失败,请稍后重试', '关闭', { duration: 3000 }); } ); } /** * 创建项目群 */ createProjectGroup() { // 先检查是否选择了客户 if (!this.selectedCustomer()) { this.snackBar.open('请先选择客户', '确定', { duration: 2000 }); return; } // 显示弹窗 this.dialog.open(ProjectGroupDialog, { width: '500px', data: { selectedCustomer: this.selectedCustomer(), demandType: this.customerForm.get('demandType')?.value, preferenceTags: this.preferenceTags, followUpStatus: this.customerForm.get('followUpStatus')?.value } }).afterClosed().subscribe(result => { if (result && result.confirm) { const tags = { demandType: result.demandType, preferenceTags: result.preferenceTags, followUpStatus: result.followUpStatus }; this.isSubmitting.set(true); this.projectService.createProjectGroup({ customerId: result.customerId, customerName: result.customerName, tags }).subscribe( (response: any) => { if (response.success) { this.snackBar.open(`项目群创建成功,群ID: ${response.groupId}`, '确定', { duration: 3000 }); } else { this.snackBar.open('项目群创建失败,请稍后重试', '确定', { duration: 2000 }); } this.isSubmitting.set(false); }, (error: any) => { this.snackBar.open('创建项目群时出错,请稍后重试', '确定', { duration: 2000 }); this.isSubmitting.set(false); } ); } }); } /** * 快速填写客户信息(通过姓名或手机号) */ quickFillCustomerInfo(keyword: string) { if (!keyword.trim()) { return; } // 模拟根据姓名或手机号查询客户信息 setTimeout(() => { // 这里应该调用实际的API来查询客户信息 const mockCustomer = { id: 'quick_' + Date.now(), name: keyword.includes('1') ? '李四' : keyword, phone: keyword.includes('1') ? keyword : '13900139000', wechat: 'lisi_wx', customerType: '老客户', source: '推荐介绍', avatar: '', demandType: 'quality', preferenceTags: ['北欧风格', '实木'], followUpStatus: 'confirm' }; this.selectedCustomer.set(mockCustomer); this.customerForm.patchValue({ name: mockCustomer.name, phone: mockCustomer.phone, wechat: mockCustomer.wechat, customerType: mockCustomer.customerType, source: mockCustomer.source, demandType: mockCustomer.demandType, followUpStatus: mockCustomer.followUpStatus }); this.preferenceTags = [...mockCustomer.preferenceTags]; this.snackBar.open('客户信息填写完成', '确定', { duration: 2000 }); }, 1000); } // 加载客户历史信息 loadCustomerHistory(customerId: string) { // 模拟加载客户历史信息 const mockHistory = { projects: [ { id: '1', name: '三室两厅装修', style: '现代简约', status: '已完成' }, { id: '2', name: '厨房改造', style: '北欧风', status: '进行中' } ], feedback: [ '对设计师服务很满意', '希望能加快施工进度', '材料质量很好' ], preferences: { style: 'modern', projectGroup: 'design1' } }; // 根据历史偏好预填充项目配置 if (mockHistory.preferences) { this.projectForm.patchValue({ style: mockHistory.preferences.style, projectGroup: mockHistory.preferences.projectGroup }); } this.snackBar.open('已自动填充客户历史偏好信息', '关闭', { duration: 3000, horizontalPosition: 'center', verticalPosition: 'top' }); } // 创建新客户 createNewCustomer() { // 重置表单为新客户状态 this.selectedCustomer.set(null); this.customerForm.reset({ customerType: '新客户' }); this.projectForm.reset(); this.searchKeyword.set(''); this.searchResults.set([]); } // 验证项目配置表单 isProjectFormValid(): boolean { return this.projectForm.valid && this.customerForm.valid; } // 获取首付款设置选项 getDownPaymentOptions() { return [ { value: '30', label: '30%' }, { value: '50', label: '50%' }, { value: '70', label: '70%' }, { value: 'custom', label: '自定义' } ]; } // 提交简化的订单 submitSimplifiedOrder() { if (!this.isProjectFormValid()) { this.snackBar.open('请完善必填信息', '关闭', { duration: 3000, horizontalPosition: 'center', verticalPosition: 'top' }); return; } this.isSubmitting.set(true); const orderData = { customer: this.customerForm.value, project: this.projectForm.value, orderTime: this.orderTime(), orderId: 'mock-' + Date.now(), // 模拟订单ID status: 'created' }; // 模拟提交 setTimeout(() => { this.isSubmitting.set(false); this.showSuccessMessage.set(true); this.snackBar.open('订单创建成功!', '关闭', { duration: 3000, horizontalPosition: 'center', verticalPosition: 'top' }); // 发射订单创建成功事件 this.orderCreated.emit(orderData); // 3秒后隐藏成功消息 setTimeout(() => { this.showSuccessMessage.set(false); }, 3000); }, 2000); } // 返回项目列表页面 goBackToProjectList() { this.router.navigate(['/customer-service/project-list']); } }