project.service.ts 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835
  1. import { Injectable } from '@angular/core';
  2. import { Observable, of } from 'rxjs';
  3. import {
  4. Project,
  5. Task,
  6. RenderProgress,
  7. ModelCheckItem,
  8. CustomerFeedback,
  9. DesignerChange,
  10. Settlement,
  11. SkillTag,
  12. PerformanceData,
  13. MatchingOrder,
  14. ProjectStage
  15. } from '../models/project.model';
  16. // 材料统计数据接口
  17. interface MaterialStatistics {
  18. monthlyAdded: number;
  19. totalCostSaved: number;
  20. personalDownloads: number;
  21. }
  22. // 材料项接口
  23. interface MaterialItem {
  24. id: string;
  25. name: string;
  26. type: string;
  27. style: string;
  28. price: number;
  29. thumbnailUrl: string;
  30. downloadCount: number;
  31. tags: string[];
  32. costSaved: number;
  33. isNew: boolean;
  34. uploadTime: Date;
  35. }
  36. // 材料列表响应接口
  37. interface MaterialsResponse {
  38. materials: MaterialItem[];
  39. total: number;
  40. }
  41. // 异常历史记录接口
  42. interface ExceptionHistory {
  43. id: string;
  44. type: 'failed' | 'stuck' | 'quality' | 'other';
  45. description: string;
  46. submitTime: Date;
  47. status: '待处理' | '处理中' | '已解决';
  48. response?: string;
  49. }
  50. @Injectable({
  51. providedIn: 'root'
  52. })
  53. export class ProjectService {
  54. // 模拟数据 - 实际应用中应从API获取
  55. private projects: Project[] = [
  56. {
  57. id: 'proj-001',
  58. name: '现代风格客厅设计',
  59. customerName: '张三',
  60. customerTags: [
  61. { source: '朋友圈', needType: '硬装', preference: '现代', colorAtmosphere: '简约明亮' }
  62. ],
  63. highPriorityNeeds: ['需家具购买建议'],
  64. status: '进行中',
  65. currentStage: '需求沟通',
  66. stage: '需求沟通',
  67. createdAt: new Date('2025-09-01'),
  68. deadline: new Date('2025-09-15'),
  69. assigneeId: 'designer1',
  70. assigneeName: '设计师A',
  71. skillsRequired: ['现代风格', '硬装']
  72. },
  73. {
  74. id: '2',
  75. name: '宋式风格卧室设计',
  76. customerName: '李四',
  77. customerTags: [
  78. { source: '信息流', needType: '软装', preference: '宋式', colorAtmosphere: '典雅古朴' }
  79. ],
  80. highPriorityNeeds: [],
  81. status: '进行中',
  82. currentStage: '渲染',
  83. stage: '渲染',
  84. createdAt: new Date('2025-09-02'),
  85. deadline: new Date('2025-09-20'),
  86. assigneeId: 'designer1',
  87. assigneeName: '设计师A',
  88. skillsRequired: ['宋式风格', '软装']
  89. },
  90. {
  91. id: '3',
  92. name: '欧式风格厨房设计',
  93. customerName: '王五',
  94. customerTags: [
  95. { source: '朋友圈', needType: '硬装', preference: '欧式', colorAtmosphere: '豪华温馨' }
  96. ],
  97. highPriorityNeeds: ['需快速交付'],
  98. status: '已完成',
  99. currentStage: '投诉处理',
  100. stage: '投诉处理',
  101. createdAt: new Date('2025-08-20'),
  102. deadline: new Date('2025-09-05'),
  103. assigneeId: 'designer1',
  104. assigneeName: '设计师A',
  105. skillsRequired: ['欧式风格', '硬装']
  106. }
  107. ];
  108. private tasks: Task[] = [
  109. {
  110. id: 't1',
  111. projectId: '1',
  112. projectName: '现代风格客厅设计',
  113. title: '完成客厅建模',
  114. stage: '建模',
  115. deadline: new Date('2025-09-10'),
  116. isOverdue: false,
  117. isCompleted: false,
  118. priority: 'high',
  119. assignee: '设计师A',
  120. description: '根据客户需求完成客厅3D模型构建'
  121. },
  122. {
  123. id: 't2',
  124. projectId: '2',
  125. projectName: '宋式风格卧室设计',
  126. title: '确认渲染结果',
  127. stage: '渲染',
  128. deadline: new Date('2025-09-12'),
  129. isOverdue: false,
  130. isCompleted: false,
  131. priority: 'medium',
  132. assignee: '设计师B',
  133. description: '审核渲染效果并与客户确认'
  134. },
  135. {
  136. id: 't3',
  137. projectId: '1',
  138. projectName: '现代风格客厅设计',
  139. title: '处理客户反馈',
  140. stage: '渲染',
  141. deadline: new Date('2025-09-08'),
  142. isOverdue: true,
  143. isCompleted: false,
  144. priority: 'high',
  145. assignee: '客服',
  146. description: '整理客户反馈意见并传达给设计团队'
  147. }
  148. ];
  149. private renderProgresses: RenderProgress[] = [
  150. {
  151. id: 'rp1',
  152. projectId: '2',
  153. completionRate: 60,
  154. estimatedTimeRemaining: 1,
  155. status: '进行中',
  156. updatedAt: new Date()
  157. }
  158. ];
  159. private modelCheckItems: ModelCheckItem[] = [
  160. { id: 'm1', name: '尺寸准确性', isPassed: true },
  161. { id: 'm2', name: '比例协调性', isPassed: true },
  162. { id: 'm3', name: '户型匹配度', isPassed: false, notes: '需调整沙发位置' }
  163. ];
  164. private feedbacks: CustomerFeedback[] = [
  165. {
  166. id: 'f1',
  167. projectId: '1',
  168. content: '客厅设计不太满意,沙发的颜色和整体风格不太搭配',
  169. isSatisfied: false,
  170. problemLocation: '沙发区域',
  171. expectedEffect: '更宽敞舒适',
  172. referenceCase: '提供了参考图片',
  173. status: '待处理',
  174. createdAt: new Date('2025-09-07'),
  175. customerName: '张女士',
  176. rating: 2
  177. },
  178. {
  179. id: 'f2',
  180. projectId: '1',
  181. content: '整体设计很满意,特别是厨房的布局很合理,使用起来很方便',
  182. isSatisfied: true,
  183. problemLocation: '',
  184. expectedEffect: '',
  185. referenceCase: '',
  186. status: '已解决',
  187. createdAt: new Date('2025-09-05'),
  188. updatedAt: new Date('2025-09-06'),
  189. customerName: '张女士',
  190. rating: 5,
  191. response: '感谢您的认可,我们会继续努力为您提供更好的设计服务。'
  192. },
  193. {
  194. id: 'f3',
  195. projectId: '1',
  196. content: '卧室的灯光设计有些暗,希望能增加一些辅助照明',
  197. isSatisfied: false,
  198. problemLocation: '主卧室',
  199. expectedEffect: '更明亮温馨',
  200. referenceCase: '希望参考北欧风格的照明设计',
  201. status: '处理中',
  202. createdAt: new Date('2025-09-06'),
  203. customerName: '张女士',
  204. rating: 3
  205. },
  206. {
  207. id: 'f4',
  208. projectId: '2',
  209. content: '餐厅的家具选择很棒,质感和颜色都很满意',
  210. isSatisfied: true,
  211. problemLocation: '',
  212. expectedEffect: '',
  213. referenceCase: '',
  214. status: '已解决',
  215. createdAt: new Date('2025-09-04'),
  216. updatedAt: new Date('2025-09-05'),
  217. customerName: '李先生',
  218. rating: 4,
  219. response: '谢谢您的好评,我们精心挑选的家具能得到您的认可很开心。'
  220. },
  221. {
  222. id: 'f5',
  223. projectId: '2',
  224. content: '阳台的设计需要调整,现在的布局不太实用',
  225. isSatisfied: false,
  226. problemLocation: '阳台区域',
  227. expectedEffect: '更实用的储物和休闲空间',
  228. referenceCase: '希望有更多储物柜',
  229. status: '待处理',
  230. createdAt: new Date('2025-09-08'),
  231. customerName: '李先生',
  232. rating: 2
  233. },
  234. {
  235. id: 'f6',
  236. projectId: '3',
  237. content: '书房的设计非常棒,工作环境很舒适,书柜的设计也很实用',
  238. isSatisfied: true,
  239. problemLocation: '',
  240. expectedEffect: '',
  241. referenceCase: '',
  242. status: '已解决',
  243. createdAt: new Date('2025-09-03'),
  244. updatedAt: new Date('2025-09-04'),
  245. customerName: '王女士',
  246. rating: 5,
  247. response: '很高兴书房设计能满足您的工作需求,实用性一直是我们设计的重点。'
  248. },
  249. {
  250. id: 'f7',
  251. projectId: '3',
  252. content: '客厅的材质选择有些问题,地板的纹理和墙面不太协调',
  253. isSatisfied: false,
  254. problemLocation: '客厅地面',
  255. expectedEffect: '更协调的材质搭配',
  256. referenceCase: '希望参考现代简约风格',
  257. status: '处理中',
  258. createdAt: new Date('2025-09-07'),
  259. customerName: '王女士',
  260. rating: 3
  261. },
  262. {
  263. id: 'f8',
  264. projectId: '1',
  265. content: '儿童房的设计很用心,孩子很喜欢,安全性也考虑得很周到',
  266. isSatisfied: true,
  267. problemLocation: '',
  268. expectedEffect: '',
  269. referenceCase: '',
  270. status: '已解决',
  271. createdAt: new Date('2025-09-02'),
  272. updatedAt: new Date('2025-09-03'),
  273. customerName: '张女士',
  274. rating: 5,
  275. response: '孩子的安全和喜好是我们设计儿童房的首要考虑,很开心能得到小朋友的认可。'
  276. },
  277. {
  278. id: 'f9',
  279. projectId: '2',
  280. content: '厨房的收纳设计很实用,但是操作台的高度需要调整',
  281. isSatisfied: false,
  282. problemLocation: '厨房操作台',
  283. expectedEffect: '更符合人体工学的高度',
  284. referenceCase: '希望按照我的身高定制',
  285. status: '待处理',
  286. createdAt: new Date('2025-09-09'),
  287. customerName: '李先生',
  288. rating: 3
  289. },
  290. {
  291. id: 'f10',
  292. projectId: '3',
  293. content: '整体效果超出预期,设计师很专业,沟通也很顺畅',
  294. isSatisfied: true,
  295. problemLocation: '',
  296. expectedEffect: '',
  297. referenceCase: '',
  298. status: '已解决',
  299. createdAt: new Date('2025-09-01'),
  300. updatedAt: new Date('2025-09-02'),
  301. customerName: '王女士',
  302. rating: 5,
  303. response: '感谢您对我们团队的认可,专业和沟通是我们一直坚持的服务标准。'
  304. }
  305. ];
  306. private settlements: Settlement[] = [
  307. // 项目3的结算记录
  308. {
  309. id: 's1',
  310. projectId: '3',
  311. projectName: '欧式风格厨房设计',
  312. stage: '建模',
  313. amount: 3000,
  314. percentage: 30,
  315. status: '已结算',
  316. createdAt: new Date('2025-08-25'),
  317. settledAt: new Date('2025-09-01')
  318. },
  319. {
  320. id: 's2',
  321. projectId: '3',
  322. projectName: '欧式风格厨房设计',
  323. stage: '渲染',
  324. amount: 5000,
  325. percentage: 50,
  326. status: '已结算',
  327. createdAt: new Date('2025-08-28'),
  328. settledAt: new Date('2025-09-01')
  329. },
  330. {
  331. id: 's3',
  332. projectId: '3',
  333. projectName: '欧式风格厨房设计',
  334. stage: '渲染',
  335. amount: 2000,
  336. percentage: 20,
  337. status: '已结算',
  338. createdAt: new Date('2025-09-02'),
  339. settledAt: new Date('2025-09-05')
  340. },
  341. // 项目1的结算记录(当前项目)
  342. {
  343. id: 's4',
  344. projectId: 'proj-001',
  345. projectName: '现代风格客厅设计',
  346. stage: '建模',
  347. amount: 4500,
  348. percentage: 30,
  349. status: '已结算',
  350. createdAt: new Date('2025-09-01'),
  351. settledAt: new Date('2025-09-03')
  352. },
  353. {
  354. id: 's5',
  355. projectId: 'proj-001',
  356. projectName: '现代风格客厅设计',
  357. stage: '软装',
  358. amount: 3500,
  359. percentage: 25,
  360. status: '已结算',
  361. createdAt: new Date('2025-09-05'),
  362. settledAt: new Date('2025-09-08')
  363. },
  364. {
  365. id: 's6',
  366. projectId: 'proj-001',
  367. projectName: '现代风格客厅设计',
  368. stage: '渲染',
  369. amount: 4000,
  370. percentage: 30,
  371. status: '待结算',
  372. createdAt: new Date('2025-09-10')
  373. },
  374. {
  375. id: 's7',
  376. projectId: 'proj-001',
  377. projectName: '现代风格客厅设计',
  378. stage: '渲染',
  379. amount: 2000,
  380. percentage: 15,
  381. status: '待结算',
  382. createdAt: new Date('2025-09-12')
  383. },
  384. // 添加一些逾期的结算项
  385. {
  386. id: 's8',
  387. projectId: 'proj-001',
  388. projectName: '现代风格客厅设计',
  389. stage: '尾款结算',
  390. amount: 6000,
  391. percentage: 40,
  392. status: '待结算',
  393. createdAt: new Date('2025-08-15') // 超过30天,算作逾期
  394. },
  395. {
  396. id: 's9',
  397. projectId: 'proj-001',
  398. projectName: '现代风格客厅设计',
  399. stage: '方案确认',
  400. amount: 1500,
  401. percentage: 10,
  402. status: '待结算',
  403. createdAt: new Date('2025-08-20') // 逾期项目
  404. },
  405. // 项目2的结算记录
  406. {
  407. id: 's10',
  408. projectId: '2',
  409. projectName: '宋式风格卧室设计',
  410. stage: '建模',
  411. amount: 3200,
  412. percentage: 30,
  413. status: '已结算',
  414. createdAt: new Date('2025-09-03'),
  415. settledAt: new Date('2025-09-05')
  416. },
  417. {
  418. id: 's11',
  419. projectId: '2',
  420. projectName: '宋式风格卧室设计',
  421. stage: '软装',
  422. amount: 2800,
  423. percentage: 25,
  424. status: '待结算',
  425. createdAt: new Date('2025-09-08')
  426. },
  427. // 客服项目的尾款结算记录
  428. {
  429. id: 's12',
  430. projectId: '1', // 对应客服项目PRJ-2024-001
  431. projectName: '企业官网设计开发',
  432. stage: '尾款结算',
  433. amount: 50000,
  434. percentage: 100,
  435. status: '待结算',
  436. createdAt: new Date('2024-01-15'),
  437. dueDate: new Date('2024-02-15')
  438. },
  439. {
  440. id: 's13',
  441. projectId: '2', // 对应客服项目PRJ-2024-002
  442. projectName: '移动端APP开发',
  443. stage: '尾款结算',
  444. amount: 80000,
  445. percentage: 100,
  446. status: '逾期',
  447. createdAt: new Date('2024-01-10'),
  448. dueDate: new Date('2024-02-10')
  449. },
  450. {
  451. id: 's14',
  452. projectId: '3', // 对应客服项目PRJ-2024-003
  453. projectName: '电商平台升级',
  454. stage: '尾款结算',
  455. amount: 120000,
  456. percentage: 100,
  457. status: '已结算',
  458. createdAt: new Date('2024-01-08'),
  459. settledAt: new Date('2024-01-22'),
  460. dueDate: new Date('2024-02-08')
  461. },
  462. // 添加更多不同项目的尾款结算记录
  463. {
  464. id: 's15',
  465. projectId: '4',
  466. projectName: '品牌VI设计',
  467. stage: '尾款结算',
  468. amount: 35000,
  469. percentage: 100,
  470. status: '待结算',
  471. createdAt: new Date('2024-12-01'),
  472. dueDate: new Date('2024-12-31')
  473. },
  474. {
  475. id: 's16',
  476. projectId: '5',
  477. projectName: '小程序开发',
  478. stage: '尾款结算',
  479. amount: 45000,
  480. percentage: 100,
  481. status: '逾期',
  482. createdAt: new Date('2024-11-15'),
  483. dueDate: new Date('2024-12-15')
  484. },
  485. {
  486. id: 's17',
  487. projectId: '6',
  488. projectName: '网站重构项目',
  489. stage: '尾款结算',
  490. amount: 28000,
  491. percentage: 100,
  492. status: '已结算',
  493. createdAt: new Date('2024-12-10'),
  494. settledAt: new Date('2024-12-20'),
  495. dueDate: new Date('2025-01-10')
  496. },
  497. {
  498. id: 's18',
  499. projectId: '7',
  500. projectName: '数据可视化系统',
  501. stage: '尾款结算',
  502. amount: 95000,
  503. percentage: 100,
  504. status: '待结算',
  505. createdAt: new Date('2024-12-20'),
  506. dueDate: new Date('2025-01-20')
  507. },
  508. {
  509. id: 's19',
  510. projectId: '8',
  511. projectName: '智能家居控制系统',
  512. stage: '尾款结算',
  513. amount: 68000,
  514. percentage: 100,
  515. status: '逾期',
  516. createdAt: new Date('2024-10-30'),
  517. dueDate: new Date('2024-11-30')
  518. },
  519. {
  520. id: 's20',
  521. projectId: '9',
  522. projectName: '在线教育平台',
  523. stage: '尾款结算',
  524. amount: 150000,
  525. percentage: 100,
  526. status: '已结算',
  527. createdAt: new Date('2024-11-25'),
  528. settledAt: new Date('2024-12-15'),
  529. dueDate: new Date('2024-12-25')
  530. }
  531. ];
  532. private skillTags: SkillTag[] = [
  533. { id: 'sk1', name: '现代风格', level: 5, count: 10 },
  534. { id: 'sk2', name: '宋式风格', level: 3, count: 5 },
  535. { id: 'sk3', name: '硬装', level: 5, count: 8 },
  536. { id: 'sk4', name: '软装', level: 3, count: 4 }
  537. ];
  538. private performanceData: PerformanceData[] = [
  539. { month: '2025-08', projectCompletionRate: 90, customerSatisfaction: 95, deliveryOnTimeRate: 85 },
  540. { month: '2025-09', projectCompletionRate: 85, customerSatisfaction: 90, deliveryOnTimeRate: 90 },
  541. { month: '2025-10', projectCompletionRate: 95, customerSatisfaction: 92, deliveryOnTimeRate: 88 }
  542. ];
  543. private matchingOrders: MatchingOrder[] = [
  544. {
  545. id: 'mo1',
  546. projectName: '新中式风格书房设计',
  547. requiredSkills: ['宋式风格', '硬装'],
  548. matchRate: 90,
  549. customerLevel: '优质'
  550. },
  551. {
  552. id: 'mo2',
  553. projectName: '北欧风格餐厅设计',
  554. requiredSkills: ['现代风格', '软装'],
  555. matchRate: 80,
  556. customerLevel: '普通'
  557. }
  558. ];
  559. // 获取当前设计师的项目列表
  560. getProjects(): Observable<Project[]> {
  561. return of(this.projects);
  562. }
  563. // 获取项目详情
  564. getProjectById(id: string): Observable<Project | undefined> {
  565. return of(this.projects.find(project => project.id === id));
  566. }
  567. // 获取待办任务
  568. getTasks(mockSize?: number): Observable<Task[]> {
  569. if (typeof mockSize === 'number' && mockSize > 0) {
  570. const now = new Date(this.projects[0]?.deadline || new Date());
  571. const year = now.getFullYear();
  572. const month = now.getMonth();
  573. const pool = ['设计师A','设计师B','设计师C','设计师D','设计师E'];
  574. const prios: Array<'high'|'medium'|'low'> = ['high','medium','low'];
  575. const gen: Task[] = [];
  576. const daysInMonth = new Date(year, month + 1, 0).getDate();
  577. for (let i = 0; i < mockSize; i++) {
  578. const day = (i % daysInMonth) + 1;
  579. const deadline = new Date(year, month, day);
  580. gen.push({
  581. id: `m${i}`,
  582. projectId: String((i % this.projects.length) + 1),
  583. projectName: this.projects[i % this.projects.length].name,
  584. title: `Mock任务${i}`,
  585. stage: '建模',
  586. deadline,
  587. isOverdue: deadline < new Date(),
  588. isCompleted: false,
  589. priority: prios[i % prios.length],
  590. assignee: pool[i % pool.length],
  591. description: '性能压测生成'
  592. });
  593. }
  594. return of(gen);
  595. }
  596. return of(this.tasks);
  597. }
  598. // 标记任务完成
  599. markTaskAsCompleted(taskId: string): Observable<Task> {
  600. const task = this.tasks.find(t => t.id === taskId);
  601. if (task) {
  602. task.isCompleted = true;
  603. task.completedDate = new Date();
  604. }
  605. return of(task as Task);
  606. }
  607. // 获取渲染进度
  608. getRenderProgress(projectId: string): Observable<RenderProgress | undefined> {
  609. return of(this.renderProgresses.find(rp => rp.projectId === projectId));
  610. }
  611. // 获取模型检查清单
  612. getModelCheckItems(): Observable<ModelCheckItem[]> {
  613. return of(this.modelCheckItems);
  614. }
  615. // 更新模型检查项
  616. updateModelCheckItem(itemId: string, isPassed: boolean): Observable<ModelCheckItem> {
  617. const item = this.modelCheckItems.find(i => i.id === itemId);
  618. if (item) {
  619. item.isPassed = isPassed;
  620. }
  621. return of(item as ModelCheckItem);
  622. }
  623. // 获取客户反馈
  624. getCustomerFeedbacks(): Observable<CustomerFeedback[]> {
  625. return of(this.feedbacks);
  626. }
  627. // 更新反馈状态
  628. updateFeedbackStatus(feedbackId: string, status: '处理中' | '已解决'): Observable<CustomerFeedback> {
  629. const feedback = this.feedbacks.find(f => f.id === feedbackId);
  630. if (feedback) {
  631. feedback.status = status;
  632. feedback.updatedAt = new Date();
  633. }
  634. return of(feedback as CustomerFeedback);
  635. }
  636. // 获取结算记录
  637. getSettlements(): Observable<Settlement[]> {
  638. return of(this.settlements);
  639. }
  640. // 获取技能标签
  641. getSkillTags(): Observable<SkillTag[]> {
  642. return of(this.skillTags);
  643. }
  644. // 获取绩效数据
  645. getPerformanceData(): Observable<PerformanceData[]> {
  646. return of(this.performanceData);
  647. }
  648. // 获取匹配订单
  649. getMatchingOrders(): Observable<MatchingOrder[]> {
  650. return of(this.matchingOrders);
  651. }
  652. // 生成需求确认清单
  653. generateRequirementChecklist(projectId: string): Observable<string[]> {
  654. return of([
  655. '个性化需求已确认',
  656. '色彩氛围已确认',
  657. '硬装/软装范围已确认',
  658. '资料提交截止时间已确认'
  659. ]);
  660. }
  661. // 生成提醒话术
  662. generateReminderMessage(type: 'overdue' | 'stagnation'): Observable<string> {
  663. if (type === 'overdue') {
  664. return of('当前处于对图期,需1小时内回复,若您需时间梳理需求,可约定XX时间沟通');
  665. } else {
  666. return of('接下来将推进新项目,若需修改请提前1天预约');
  667. }
  668. }
  669. // 更新项目阶段
  670. updateProjectStage(projectId: string, stage: ProjectStage): Observable<Project | undefined> {
  671. const project = this.projects.find(p => p.id === projectId);
  672. if (project) {
  673. project.currentStage = stage;
  674. // 如果是投诉处理阶段,则将项目状态设置为已完成
  675. if (stage === '投诉处理') {
  676. project.status = '已完成';
  677. }
  678. }
  679. return of(project);
  680. }
  681. // 获取材料统计数据
  682. getMaterialStatistics(): Observable<MaterialStatistics> {
  683. return of({
  684. monthlyAdded: 15,
  685. totalCostSaved: 2800,
  686. personalDownloads: 42
  687. });
  688. }
  689. // 获取异常历史记录
  690. getExceptionHistories(projectId: string): Observable<ExceptionHistory[]> {
  691. return of([
  692. {
  693. id: 'eh1',
  694. type: 'quality',
  695. description: '光线效果不符合预期',
  696. submitTime: new Date('2025-09-05'),
  697. status: '已解决',
  698. response: '已调整灯光参数'
  699. },
  700. {
  701. id: 'eh2',
  702. type: 'stuck',
  703. description: '沙发尺寸需要调整',
  704. submitTime: new Date('2025-09-07'),
  705. status: '待处理'
  706. }
  707. ]);
  708. }
  709. // 更新收藏材料状态
  710. updateFavoriteMaterial(materialId: string, isFavorite: boolean): Observable<void> {
  711. // 模拟API调用
  712. console.log(`${isFavorite ? '添加' : '取消'}材料收藏:`, materialId);
  713. return of(void 0);
  714. }
  715. // 获取收藏材料列表
  716. getFavoriteMaterials(): Observable<string[]> {
  717. // 模拟返回收藏的材料ID列表
  718. return of(['mat1', 'mat3', 'mat5']);
  719. }
  720. // 获取材料列表
  721. getMaterials(
  722. searchQuery: string = '',
  723. filterType: string = '',
  724. filterStyle: string = '',
  725. filterPrice: string = '',
  726. page: number = 1,
  727. pageSize: number = 10
  728. ): Observable<MaterialsResponse> {
  729. // 模拟材料数据
  730. const mockMaterials: MaterialItem[] = [
  731. { id: 'mat1', name: '现代风格沙发', type: '家具', style: '现代', price: 2800, thumbnailUrl: 'https://picsum.photos/200/150', downloadCount: 120, tags: ['现代', '舒适', '客厅', '布艺'], costSaved: 500, isNew: false, uploadTime: new Date('2025-08-15') },
  732. { id: 'mat2', name: '宋式风格茶几', type: '家具', style: '宋式', price: 1500, thumbnailUrl: 'https://picsum.photos/200/151', downloadCount: 85, tags: ['宋式', '古典', '实木', '客厅'], costSaved: 300, isNew: true, uploadTime: new Date('2025-09-07') },
  733. { id: 'mat3', name: '欧式吊灯', type: '灯具', style: '欧式', price: 2200, thumbnailUrl: 'https://picsum.photos/200/152', downloadCount: 150, tags: ['欧式', '奢华', '客厅', '水晶'], costSaved: 450, isNew: false, uploadTime: new Date('2025-08-20') },
  734. { id: 'mat4', name: '中式地毯', type: '纺织品', style: '中式', price: 1800, thumbnailUrl: 'https://picsum.photos/200/153', downloadCount: 95, tags: ['中式', '传统', '卧室', '羊毛'], costSaved: 350, isNew: false, uploadTime: new Date('2025-08-25') },
  735. { id: 'mat5', name: '北欧风格窗帘', type: '纺织品', style: '北欧', price: 1200, thumbnailUrl: 'https://picsum.photos/200/154', downloadCount: 130, tags: ['北欧', '简约', '卧室', '亚麻'], costSaved: 250, isNew: true, uploadTime: new Date('2025-09-05') }
  736. ];
  737. // 简单的搜索和过滤逻辑
  738. let filtered = [...mockMaterials];
  739. if (searchQuery) {
  740. filtered = filtered.filter(m => m.name.toLowerCase().includes(searchQuery.toLowerCase()));
  741. }
  742. if (filterType) {
  743. filtered = filtered.filter(m => m.type === filterType);
  744. }
  745. if (filterStyle) {
  746. filtered = filtered.filter(m => m.style === filterStyle);
  747. }
  748. // 分页
  749. const startIndex = (page - 1) * pageSize;
  750. const paginated = filtered.slice(startIndex, startIndex + pageSize);
  751. return of({ materials: paginated, total: filtered.length });
  752. }
  753. // 记录材料下载
  754. recordMaterialDownload(materialId: string): Observable<void> {
  755. // 模拟下载记录
  756. console.log('记录材料下载:', materialId);
  757. return of(void 0);
  758. }
  759. // 创建项目
  760. createProject(projectData: {
  761. customerId: string;
  762. customerName: string;
  763. requirement: any;
  764. referenceCases: any[];
  765. tags: {
  766. demandType?: string;
  767. preferenceTags?: string[];
  768. followUpStatus?: string;
  769. };
  770. // 可选扩展字段:报价与指派信息
  771. quotation?: any;
  772. assignment?: any;
  773. orderAmount?: number;
  774. }): Observable<{ success: boolean; projectId: string }> {
  775. // 模拟API调用
  776. console.log('创建项目:', projectData);
  777. // 模拟返回创建的项目ID
  778. return of({ success: true, projectId: 'new-project-' + Date.now() });
  779. }
  780. // 创建项目群
  781. createProjectGroup(groupData: {
  782. customerId: string;
  783. customerName: string;
  784. tags?: {
  785. demandType?: string;
  786. preferenceTags?: string[];
  787. followUpStatus?: string;
  788. };
  789. }): Observable<{ success: boolean; groupId: string }> {
  790. // 模拟API调用
  791. console.log('创建项目群:', groupData);
  792. // 模拟返回创建的群组ID
  793. return of({ success: true, groupId: 'new-group-' + Date.now() });
  794. }
  795. }