import { Component, signal, Inject } from '@angular/core'; import { CommonModule } from '@angular/common'; import { FormsModule, ReactiveFormsModule, FormBuilder, FormGroup, Validators } from '@angular/forms'; import { 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); // 需求表单 requirementForm: FormGroup; // 客户表单 customerForm: FormGroup; // 样式选项 styleOptions = [ '现代简约', '北欧风', '工业风', '新中式', '法式轻奢', '日式', '美式', '混搭' ]; // 户型选项 houseTypeOptions = [ '一室一厅', '两室一厅', '两室两厅', '三室一厅', '三室两厅', '四室两厅', '复式', '别墅', '其他' ]; // 装修类型选项 decorationTypeOptions = [ '全包', '半包', '清包', '旧房翻新', '局部改造' ]; // 标签系统 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 ) { // 初始化需求表单 this.requirementForm = this.fb.group({ style: ['', Validators.required], budget: ['', Validators.required], area: ['', [Validators.required, Validators.min(1)]], houseType: ['', Validators.required], floor: ['', Validators.min(1)], decorationType: ['', Validators.required], preferredDesigner: [''], specialRequirements: [''], referenceCases: [[]] }); // 初始化客户表单 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.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 || '' }); // 清空搜索结果 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.requirementForm.valid && 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); // 3秒后隐藏成功提示 setTimeout(() => { this.showSuccessMessage.set(false); }, 3000); }, 1500); } } // 创建项目 createProject() { if (!this.selectedCustomer()) { this.snackBar.open('请先选择客户', '关闭', { duration: 3000 }); return; } if (this.requirementForm.invalid) { this.snackBar.open('请完善需求信息', '关闭', { duration: 3000 }); return; } const selectedCustomer = this.selectedCustomer()!; const projectData = { customerId: selectedCustomer.id, customerName: selectedCustomer.name, requirement: this.requirementForm.value, referenceCases: this.requirementForm.get('referenceCases')?.value || [], tags: { demandType: this.customerForm.get('demandType')?.value, preferenceTags: this.preferenceTags, followUpStatus: this.customerForm.get('followUpStatus')?.value } }; this.projectService.createProject(projectData).subscribe( (response: any) => { this.snackBar.open('项目创建成功', '关闭', { duration: 3000 }); }, (error: any) => { 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); } ); } }); } }