|
@@ -0,0 +1,315 @@
|
|
|
|
+import { Injectable } from '@angular/core';
|
|
|
|
+import { Observable, of } from 'rxjs';
|
|
|
|
+import {
|
|
|
|
+ Project,
|
|
|
|
+ Task,
|
|
|
|
+ RenderProgress,
|
|
|
|
+ ModelCheckItem,
|
|
|
|
+ CustomerFeedback,
|
|
|
|
+ DesignerChange,
|
|
|
|
+ Settlement,
|
|
|
|
+ SkillTag,
|
|
|
|
+ PerformanceData,
|
|
|
|
+ MatchingOrder,
|
|
|
|
+ ProjectStage
|
|
|
|
+} from '../models/project.model';
|
|
|
|
+
|
|
|
|
+@Injectable({
|
|
|
|
+ providedIn: 'root'
|
|
|
|
+})
|
|
|
|
+export class ProjectService {
|
|
|
|
+ // 模拟数据 - 实际应用中应从API获取
|
|
|
|
+ private projects: Project[] = [
|
|
|
|
+ {
|
|
|
|
+ id: '1',
|
|
|
|
+ name: '现代风格客厅设计',
|
|
|
|
+ customerName: '张三',
|
|
|
|
+ customerTags: [
|
|
|
|
+ { source: '朋友圈', needType: '硬装', preference: '现代', colorAtmosphere: '简约明亮' }
|
|
|
|
+ ],
|
|
|
|
+ highPriorityNeeds: ['需家具购买建议'],
|
|
|
|
+ status: '进行中',
|
|
|
|
+ currentStage: '建模',
|
|
|
|
+ createdAt: new Date('2025-09-01'),
|
|
|
|
+ deadline: new Date('2025-09-15'),
|
|
|
|
+ assigneeId: 'designer1',
|
|
|
|
+ assigneeName: '设计师A',
|
|
|
|
+ skillsRequired: ['现代风格', '硬装']
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ id: '2',
|
|
|
|
+ name: '宋式风格卧室设计',
|
|
|
|
+ customerName: '李四',
|
|
|
|
+ customerTags: [
|
|
|
|
+ { source: '信息流', needType: '软装', preference: '宋式', colorAtmosphere: '典雅古朴' }
|
|
|
|
+ ],
|
|
|
|
+ highPriorityNeeds: [],
|
|
|
|
+ status: '进行中',
|
|
|
|
+ currentStage: '渲染',
|
|
|
|
+ createdAt: new Date('2025-09-02'),
|
|
|
|
+ deadline: new Date('2025-09-20'),
|
|
|
|
+ assigneeId: 'designer1',
|
|
|
|
+ assigneeName: '设计师A',
|
|
|
|
+ skillsRequired: ['宋式风格', '软装']
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ id: '3',
|
|
|
|
+ name: '欧式风格厨房设计',
|
|
|
|
+ customerName: '王五',
|
|
|
|
+ customerTags: [
|
|
|
|
+ { source: '朋友圈', needType: '硬装', preference: '欧式', colorAtmosphere: '豪华温馨' }
|
|
|
|
+ ],
|
|
|
|
+ highPriorityNeeds: ['需快速交付'],
|
|
|
|
+ status: '已完成',
|
|
|
|
+ currentStage: '完成',
|
|
|
|
+ createdAt: new Date('2025-08-20'),
|
|
|
|
+ deadline: new Date('2025-09-05'),
|
|
|
|
+ assigneeId: 'designer1',
|
|
|
|
+ assigneeName: '设计师A',
|
|
|
|
+ skillsRequired: ['欧式风格', '硬装']
|
|
|
|
+ }
|
|
|
|
+ ];
|
|
|
|
+
|
|
|
|
+ private tasks: Task[] = [
|
|
|
|
+ {
|
|
|
|
+ id: 't1',
|
|
|
|
+ projectId: '1',
|
|
|
|
+ projectName: '现代风格客厅设计',
|
|
|
|
+ title: '完成客厅建模',
|
|
|
|
+ stage: '建模',
|
|
|
|
+ deadline: new Date('2025-09-10'),
|
|
|
|
+ isOverdue: false,
|
|
|
|
+ isCompleted: false
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ id: 't2',
|
|
|
|
+ projectId: '2',
|
|
|
|
+ projectName: '宋式风格卧室设计',
|
|
|
|
+ title: '确认渲染结果',
|
|
|
|
+ stage: '渲染',
|
|
|
|
+ deadline: new Date('2025-09-12'),
|
|
|
|
+ isOverdue: false,
|
|
|
|
+ isCompleted: false
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ id: 't3',
|
|
|
|
+ projectId: '1',
|
|
|
|
+ projectName: '现代风格客厅设计',
|
|
|
|
+ title: '处理客户反馈',
|
|
|
|
+ stage: '后期',
|
|
|
|
+ deadline: new Date('2025-09-08'),
|
|
|
|
+ isOverdue: true,
|
|
|
|
+ isCompleted: false
|
|
|
|
+ }
|
|
|
|
+ ];
|
|
|
|
+
|
|
|
|
+ private renderProgresses: RenderProgress[] = [
|
|
|
|
+ {
|
|
|
|
+ id: 'rp1',
|
|
|
|
+ projectId: '2',
|
|
|
|
+ completionRate: 60,
|
|
|
|
+ estimatedTimeRemaining: 1,
|
|
|
|
+ status: '进行中',
|
|
|
|
+ updatedAt: new Date()
|
|
|
|
+ }
|
|
|
|
+ ];
|
|
|
|
+
|
|
|
|
+ private modelCheckItems: ModelCheckItem[] = [
|
|
|
|
+ { id: 'm1', name: '尺寸准确性', isPassed: true },
|
|
|
|
+ { id: 'm2', name: '比例协调性', isPassed: true },
|
|
|
|
+ { id: 'm3', name: '户型匹配度', isPassed: false, notes: '需调整沙发位置' }
|
|
|
|
+ ];
|
|
|
|
+
|
|
|
|
+ private feedbacks: CustomerFeedback[] = [
|
|
|
|
+ {
|
|
|
|
+ id: 'f1',
|
|
|
|
+ projectId: '1',
|
|
|
|
+ content: '客厅设计不太满意',
|
|
|
|
+ isSatisfied: false,
|
|
|
|
+ problemLocation: '沙发区域',
|
|
|
|
+ expectedEffect: '更宽敞舒适',
|
|
|
|
+ referenceCase: '提供了参考图片',
|
|
|
|
+ status: '待处理',
|
|
|
|
+ createdAt: new Date('2025-09-07')
|
|
|
|
+ }
|
|
|
|
+ ];
|
|
|
|
+
|
|
|
|
+ private settlements: Settlement[] = [
|
|
|
|
+ {
|
|
|
|
+ id: 's1',
|
|
|
|
+ projectId: '3',
|
|
|
|
+ stage: '建模',
|
|
|
|
+ amount: 3000,
|
|
|
|
+ percentage: 30,
|
|
|
|
+ status: '已结算',
|
|
|
|
+ createdAt: new Date('2025-08-25'),
|
|
|
|
+ settledAt: new Date('2025-09-01')
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ id: 's2',
|
|
|
|
+ projectId: '3',
|
|
|
|
+ stage: '渲染',
|
|
|
|
+ amount: 5000,
|
|
|
|
+ percentage: 50,
|
|
|
|
+ status: '已结算',
|
|
|
|
+ createdAt: new Date('2025-08-28'),
|
|
|
|
+ settledAt: new Date('2025-09-01')
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ id: 's3',
|
|
|
|
+ projectId: '3',
|
|
|
|
+ stage: '后期',
|
|
|
|
+ amount: 2000,
|
|
|
|
+ percentage: 20,
|
|
|
|
+ status: '已结算',
|
|
|
|
+ createdAt: new Date('2025-09-02'),
|
|
|
|
+ settledAt: new Date('2025-09-05')
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ id: 's4',
|
|
|
|
+ projectId: '1',
|
|
|
|
+ stage: '建模',
|
|
|
|
+ amount: 3000,
|
|
|
|
+ percentage: 30,
|
|
|
|
+ status: '待结算',
|
|
|
|
+ createdAt: new Date('2025-09-06')
|
|
|
|
+ }
|
|
|
|
+ ];
|
|
|
|
+
|
|
|
|
+ private skillTags: SkillTag[] = [
|
|
|
|
+ { id: 'sk1', name: '现代风格', level: 5, count: 10 },
|
|
|
|
+ { id: 'sk2', name: '宋式风格', level: 3, count: 5 },
|
|
|
|
+ { id: 'sk3', name: '硬装', level: 5, count: 8 },
|
|
|
|
+ { id: 'sk4', name: '软装', level: 3, count: 4 }
|
|
|
|
+ ];
|
|
|
|
+
|
|
|
|
+ private performanceData: PerformanceData[] = [
|
|
|
|
+ { month: '2025-08', projectCompletionRate: 90, customerSatisfaction: 95, deliveryOnTimeRate: 85 },
|
|
|
|
+ { month: '2025-09', projectCompletionRate: 85, customerSatisfaction: 90, deliveryOnTimeRate: 90 },
|
|
|
|
+ { month: '2025-10', projectCompletionRate: 95, customerSatisfaction: 92, deliveryOnTimeRate: 88 }
|
|
|
|
+ ];
|
|
|
|
+
|
|
|
|
+ private matchingOrders: MatchingOrder[] = [
|
|
|
|
+ {
|
|
|
|
+ id: 'mo1',
|
|
|
|
+ projectName: '新中式风格书房设计',
|
|
|
|
+ requiredSkills: ['宋式风格', '硬装'],
|
|
|
|
+ matchRate: 90,
|
|
|
|
+ customerLevel: '优质'
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ id: 'mo2',
|
|
|
|
+ projectName: '北欧风格餐厅设计',
|
|
|
|
+ requiredSkills: ['现代风格', '软装'],
|
|
|
|
+ matchRate: 80,
|
|
|
|
+ customerLevel: '普通'
|
|
|
|
+ }
|
|
|
|
+ ];
|
|
|
|
+
|
|
|
|
+ // 获取当前设计师的项目列表
|
|
|
|
+ getProjects(): Observable<Project[]> {
|
|
|
|
+ return of(this.projects);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 获取项目详情
|
|
|
|
+ getProjectById(id: string): Observable<Project | undefined> {
|
|
|
|
+ return of(this.projects.find(project => project.id === id));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 获取待办任务
|
|
|
|
+ getTasks(): Observable<Task[]> {
|
|
|
|
+ return of(this.tasks);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 标记任务完成
|
|
|
|
+ markTaskAsCompleted(taskId: string): Observable<Task> {
|
|
|
|
+ const task = this.tasks.find(t => t.id === taskId);
|
|
|
|
+ if (task) {
|
|
|
|
+ task.isCompleted = true;
|
|
|
|
+ task.completedAt = new Date();
|
|
|
|
+ }
|
|
|
|
+ return of(task as Task);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 获取渲染进度
|
|
|
|
+ getRenderProgress(projectId: string): Observable<RenderProgress | undefined> {
|
|
|
|
+ return of(this.renderProgresses.find(rp => rp.projectId === projectId));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 获取模型检查清单
|
|
|
|
+ getModelCheckItems(): Observable<ModelCheckItem[]> {
|
|
|
|
+ return of(this.modelCheckItems);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 更新模型检查项
|
|
|
|
+ updateModelCheckItem(itemId: string, isPassed: boolean): Observable<ModelCheckItem> {
|
|
|
|
+ const item = this.modelCheckItems.find(i => i.id === itemId);
|
|
|
|
+ if (item) {
|
|
|
|
+ item.isPassed = isPassed;
|
|
|
|
+ }
|
|
|
|
+ return of(item as ModelCheckItem);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 获取客户反馈
|
|
|
|
+ getCustomerFeedbacks(): Observable<CustomerFeedback[]> {
|
|
|
|
+ return of(this.feedbacks);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 更新反馈状态
|
|
|
|
+ updateFeedbackStatus(feedbackId: string, status: '处理中' | '已解决'): Observable<CustomerFeedback> {
|
|
|
|
+ const feedback = this.feedbacks.find(f => f.id === feedbackId);
|
|
|
|
+ if (feedback) {
|
|
|
|
+ feedback.status = status;
|
|
|
|
+ feedback.updatedAt = new Date();
|
|
|
|
+ }
|
|
|
|
+ return of(feedback as CustomerFeedback);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 获取结算记录
|
|
|
|
+ getSettlements(): Observable<Settlement[]> {
|
|
|
|
+ return of(this.settlements);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 获取技能标签
|
|
|
|
+ getSkillTags(): Observable<SkillTag[]> {
|
|
|
|
+ return of(this.skillTags);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 获取绩效数据
|
|
|
|
+ getPerformanceData(): Observable<PerformanceData[]> {
|
|
|
|
+ return of(this.performanceData);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 获取匹配订单
|
|
|
|
+ getMatchingOrders(): Observable<MatchingOrder[]> {
|
|
|
|
+ return of(this.matchingOrders);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 生成需求确认清单
|
|
|
|
+ generateRequirementChecklist(projectId: string): Observable<string[]> {
|
|
|
|
+ return of([
|
|
|
|
+ '个性化需求已确认',
|
|
|
|
+ '色彩氛围已确认',
|
|
|
|
+ '硬装/软装范围已确认',
|
|
|
|
+ '资料提交截止时间已确认'
|
|
|
|
+ ]);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 生成提醒话术
|
|
|
|
+ generateReminderMessage(type: 'overdue' | 'stagnation'): Observable<string> {
|
|
|
|
+ if (type === 'overdue') {
|
|
|
|
+ return of('当前处于对图期,需1小时内回复,若您需时间梳理需求,可约定XX时间沟通');
|
|
|
|
+ } else {
|
|
|
|
+ return of('接下来将推进新项目,若需修改请提前1天预约');
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 更新项目阶段
|
|
|
|
+ updateProjectStage(projectId: string, stage: ProjectStage): Observable<Project | undefined> {
|
|
|
|
+ const project = this.projects.find(p => p.id === projectId);
|
|
|
|
+ if (project) {
|
|
|
|
+ project.currentStage = stage;
|
|
|
|
+ }
|
|
|
|
+ return of(project);
|
|
|
|
+ }
|
|
|
|
+}
|