project-detail.ts 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837
  1. import { Component, OnInit, signal, computed, ViewChild, AfterViewChecked } from '@angular/core';
  2. import { CommonModule } from '@angular/common';
  3. import { FormsModule, ReactiveFormsModule } from '@angular/forms';
  4. import { RouterModule, ActivatedRoute } from '@angular/router';
  5. import { MatDialog, MatDialogModule } from '@angular/material/dialog';
  6. import { ProjectService } from '../../../services/project.service';
  7. import { Project, Task, Message, FileItem, CustomerFeedback, Milestone } from '../../../models/project.model';
  8. import { ModificationRequestDialog } from './modification-request-dialog';
  9. import { ComplaintWarningDialog } from './complaint-warning-dialog';
  10. import { RefundRequestDialog } from './refund-request-dialog';
  11. // 定义项目阶段接口
  12. interface ProjectStage {
  13. name: string;
  14. completed: boolean;
  15. inProgress: boolean;
  16. startDate?: Date;
  17. endDate?: Date;
  18. responsible?: string;
  19. details?: string;
  20. }
  21. // 定义企业微信消息接口
  22. interface WechatMessage {
  23. sender: string;
  24. content: string;
  25. timestamp: Date;
  26. }
  27. // 定义历史咨询记录接口
  28. interface ConsultationRecord {
  29. id: string;
  30. date: Date;
  31. content: string;
  32. status: string;
  33. }
  34. // 定义合作项目接口
  35. interface CooperationProject {
  36. id: string;
  37. name: string;
  38. startDate: Date;
  39. endDate?: Date;
  40. status: string;
  41. description: string;
  42. }
  43. // 定义历史反馈接口
  44. interface HistoricalFeedback {
  45. id: string;
  46. date: Date;
  47. content: string;
  48. rating: number;
  49. response?: string;
  50. }
  51. @Component({
  52. selector: 'app-project-detail',
  53. standalone: true,
  54. imports: [CommonModule, FormsModule, ReactiveFormsModule, RouterModule, MatDialogModule],
  55. templateUrl: './project-detail.html',
  56. styleUrls: ['./project-detail.scss', '../customer-service-styles.scss']
  57. })
  58. export class ProjectDetail implements OnInit, AfterViewChecked {
  59. // 项目ID
  60. projectId = '';
  61. // 项目详情
  62. project = signal<Project | null>(null);
  63. // 添加 toggleSidebar 方法
  64. toggleSidebar(): void {
  65. // 这里可以实现侧边栏切换逻辑
  66. // 如果需要与全局状态交互,可以注入相应的服务
  67. console.log('Toggle sidebar');
  68. }
  69. // 项目里程碑
  70. milestones = signal<Milestone[]>([]);
  71. // 项目任务
  72. tasks = signal<Task[]>([]);
  73. // 项目消息
  74. messages = signal<Message[]>([]);
  75. // 项目文件
  76. files = signal<FileItem[]>([]);
  77. // 客户反馈
  78. feedbacks = signal<CustomerFeedback[]>([]);
  79. // 当前激活的标签页
  80. activeTab = signal('overview');
  81. // 新消息内容
  82. newMessage = signal('');
  83. // 项目阶段数据 - 进度时间轴
  84. projectStages: ProjectStage[] = [
  85. {
  86. name: '需求沟通',
  87. completed: true,
  88. inProgress: false,
  89. startDate: new Date('2023-06-01'),
  90. endDate: new Date('2023-06-08'),
  91. responsible: '客服小李',
  92. details: '完成客户需求确认、现场量房和初步方案讨论'
  93. },
  94. {
  95. name: '建模',
  96. completed: true,
  97. inProgress: false,
  98. startDate: new Date('2023-06-09'),
  99. endDate: new Date('2023-06-18'),
  100. responsible: '张设计师',
  101. details: '创建3D模型和基础渲染'
  102. },
  103. {
  104. name: '软装',
  105. completed: false,
  106. inProgress: true,
  107. startDate: new Date('2023-06-19'),
  108. responsible: '张设计师',
  109. details: '选择和搭配家具、灯具和装饰品'
  110. },
  111. {
  112. name: '渲染',
  113. completed: false,
  114. inProgress: false,
  115. startDate: new Date('2023-06-26'),
  116. responsible: '张设计师',
  117. details: '生成最终渲染图'
  118. },
  119. {
  120. name: '后期',
  121. completed: false,
  122. inProgress: false,
  123. startDate: new Date('2023-07-03'),
  124. responsible: '张设计师',
  125. details: '后期图像处理和优化'
  126. },
  127. {
  128. name: '投诉处理',
  129. completed: false,
  130. inProgress: false,
  131. startDate: new Date('2023-07-10'),
  132. endDate: new Date('2023-07-15'),
  133. responsible: '客服小李',
  134. details: '项目验收、交付和投诉处理'
  135. }
  136. ];
  137. // 企业微信聊天相关
  138. @ViewChild('wechatMessages') wechatMessagesContainer: any;
  139. wechatMessagesList: WechatMessage[] = [];
  140. wechatInput = '';
  141. scrollToBottom = false;
  142. // 历史服务记录相关
  143. consultationRecords = signal<ConsultationRecord[]>([]);
  144. cooperationProjects = signal<CooperationProject[]>([]);
  145. historicalFeedbacks = signal<HistoricalFeedback[]>([]);
  146. // 售后处理弹窗状态
  147. showModificationRequest = false;
  148. showComplaintWarning = false;
  149. showRefundRequest = false;
  150. // 项目状态颜色映射
  151. statusColors = {
  152. '进行中': 'primary',
  153. '待确认': 'warning',
  154. '已完成': 'success',
  155. '已暂停': 'secondary',
  156. '已取消': 'danger'
  157. };
  158. // 计算完成进度
  159. completionProgress = computed(() => {
  160. if (!this.tasks().length) return 0;
  161. const completedTasks = this.tasks().filter(task => task.isCompleted).length;
  162. return Math.round((completedTasks / this.tasks().length) * 100);
  163. });
  164. constructor(
  165. private route: ActivatedRoute,
  166. private projectService: ProjectService,
  167. private dialog: MatDialog
  168. ) {
  169. // 获取路由参数中的项目ID
  170. this.route.paramMap.subscribe(params => {
  171. this.projectId = params.get('id') || '';
  172. });
  173. }
  174. ngOnInit(): void {
  175. this.loadProjectDetails();
  176. }
  177. // 加载项目详情
  178. loadProjectDetails(): void {
  179. // 模拟从服务获取项目数据
  180. this.projectService.getProjectById(this.projectId).subscribe(project => {
  181. if (project) {
  182. this.project.set(project);
  183. }
  184. });
  185. // 加载模拟数据
  186. this.loadMockData();
  187. }
  188. // 加载模拟数据
  189. // 修复 loadMockData 方法中的任务对象,确保类型一致性
  190. loadMockData(): void {
  191. // 初始化企业微信聊天
  192. this.initWechatMessages();
  193. // 初始化历史服务记录
  194. this.initHistoricalServiceRecords();
  195. // 模拟里程碑数据
  196. this.milestones.set([
  197. {
  198. id: 'm1',
  199. title: '客户需求确认',
  200. description: '确认客户的装修需求和风格偏好',
  201. dueDate: new Date('2023-06-10'),
  202. completedDate: new Date('2023-06-08'),
  203. isCompleted: true
  204. },
  205. {
  206. id: 'm2',
  207. title: '设计方案提交',
  208. description: '提交初步设计方案供客户审阅',
  209. dueDate: new Date('2023-06-20'),
  210. completedDate: new Date('2023-06-18'),
  211. isCompleted: true
  212. },
  213. {
  214. id: 'm3',
  215. title: '方案修改与确认',
  216. description: '根据客户反馈修改并最终确认方案',
  217. dueDate: new Date('2023-06-25'),
  218. completedDate: undefined,
  219. isCompleted: false
  220. },
  221. {
  222. id: 'm4',
  223. title: '施工图制作',
  224. description: '制作详细的施工图纸',
  225. dueDate: new Date('2023-07-05'),
  226. completedDate: undefined,
  227. isCompleted: false
  228. },
  229. {
  230. id: 'm5',
  231. title: '项目验收',
  232. description: '客户验收最终成果',
  233. dueDate: new Date('2023-07-15'),
  234. completedDate: undefined,
  235. isCompleted: false
  236. }
  237. ]);
  238. // 模拟任务数据 - 确保所有任务对象都有完整的必填属性
  239. this.tasks.set([
  240. {
  241. id: 't1',
  242. title: '现场量房',
  243. description: '前往客户现场进行房屋测量',
  244. projectId: this.projectId,
  245. projectName: '现代简约风格三居室设计',
  246. assignee: '张设计师',
  247. deadline: new Date('2023-06-05'),
  248. completedDate: new Date('2023-06-04'),
  249. isCompleted: true,
  250. isOverdue: false,
  251. priority: 'high',
  252. stage: '需求沟通' // 添加 stage 属性,确保符合 Task 接口
  253. },
  254. {
  255. id: 't2',
  256. title: '设计初稿',
  257. description: '完成设计方案初稿',
  258. projectId: this.projectId,
  259. projectName: '现代简约风格三居室设计',
  260. assignee: '张设计师',
  261. deadline: new Date('2023-06-15'),
  262. completedDate: new Date('2023-06-14'),
  263. isCompleted: true,
  264. isOverdue: false,
  265. priority: 'high',
  266. stage: '建模'
  267. },
  268. {
  269. id: 't3',
  270. title: '客户沟通',
  271. description: '与客户沟通设计方案反馈',
  272. projectId: this.projectId,
  273. projectName: '现代简约风格三居室设计',
  274. assignee: '客服小李',
  275. deadline: new Date('2023-06-22'),
  276. completedDate: undefined,
  277. isCompleted: false,
  278. isOverdue: false,
  279. priority: 'medium',
  280. stage: '需求沟通'
  281. },
  282. {
  283. id: 't4',
  284. title: '方案修改',
  285. description: '根据客户反馈修改设计方案',
  286. projectId: this.projectId,
  287. projectName: '现代简约风格三居室设计',
  288. assignee: '张设计师',
  289. deadline: new Date('2023-06-28'),
  290. completedDate: undefined,
  291. isCompleted: false,
  292. isOverdue: false,
  293. priority: 'high',
  294. stage: '软装'
  295. },
  296. {
  297. id: 't5',
  298. title: '施工图绘制',
  299. description: '绘制详细的施工图纸',
  300. projectId: this.projectId,
  301. projectName: '现代简约风格三居室设计',
  302. assignee: '王设计师',
  303. deadline: new Date('2023-07-10'),
  304. completedDate: undefined,
  305. isCompleted: false,
  306. isOverdue: false,
  307. priority: 'medium',
  308. stage: '渲染'
  309. }
  310. ]);
  311. // 模拟消息数据
  312. this.messages.set([
  313. {
  314. id: 'msg1',
  315. sender: '客户王先生',
  316. content: '设计方案收到了,整体很满意,客厅的颜色可以再调整一下吗?',
  317. timestamp: new Date('2023-06-19T10:30:00'),
  318. isRead: true,
  319. type: 'text'
  320. },
  321. {
  322. id: 'msg2',
  323. sender: '客服小李',
  324. content: '好的,我们会根据您的需求调整客厅颜色方案,稍后给您发送修改后的效果图。',
  325. timestamp: new Date('2023-06-19T10:45:00'),
  326. isRead: true,
  327. type: 'text'
  328. },
  329. {
  330. id: 'msg3',
  331. sender: '张设计师',
  332. content: '修改后的客厅效果图已上传,请查收。',
  333. timestamp: new Date('2023-06-19T14:20:00'),
  334. isRead: true,
  335. type: 'text'
  336. },
  337. {
  338. id: 'msg4',
  339. sender: '客户王先生',
  340. content: '这个效果很好,就按照这个方案进行吧!',
  341. timestamp: new Date('2023-06-20T09:15:00'),
  342. isRead: true,
  343. type: 'text'
  344. },
  345. {
  346. id: 'msg5',
  347. sender: '客服小李',
  348. content: '收到,我们会尽快开始下一阶段的工作。',
  349. timestamp: new Date('2023-06-20T09:30:00'),
  350. isRead: true,
  351. type: 'text'
  352. }
  353. ]);
  354. // 模拟文件数据
  355. this.files.set([
  356. {
  357. id: 'file1',
  358. name: '设计方案初稿.pdf',
  359. type: 'document',
  360. size: '2.5MB',
  361. url: 'https://example.com/files/design-proposal.pdf',
  362. uploadedBy: '张设计师',
  363. uploadedAt: new Date('2023-06-15'),
  364. downloadCount: 12
  365. },
  366. {
  367. id: 'file2',
  368. name: '客厅效果图.png',
  369. type: 'image',
  370. size: '1.8MB',
  371. url: 'https://example.com/files/living-room.png',
  372. uploadedBy: '张设计师',
  373. uploadedAt: new Date('2023-06-18'),
  374. downloadCount: 8
  375. },
  376. {
  377. id: 'file3',
  378. name: '修改后客厅效果图.png',
  379. type: 'image',
  380. size: '2.1MB',
  381. url: 'https://example.com/files/living-room-revised.png',
  382. uploadedBy: '张设计师',
  383. uploadedAt: new Date('2023-06-19'),
  384. downloadCount: 5
  385. },
  386. {
  387. id: 'file4',
  388. name: '客户需求文档.docx',
  389. type: 'document',
  390. size: '1.2MB',
  391. url: 'https://example.com/files/requirements.docx',
  392. uploadedBy: '客服小李',
  393. uploadedAt: new Date('2023-06-05'),
  394. downloadCount: 10
  395. },
  396. {
  397. id: 'file5',
  398. name: '房屋测量数据.xlsx',
  399. type: 'spreadsheet',
  400. size: '0.8MB',
  401. url: 'https://example.com/files/measurement.xlsx',
  402. uploadedBy: '张设计师',
  403. uploadedAt: new Date('2023-06-04'),
  404. downloadCount: 7
  405. }
  406. ]);
  407. // 模拟客户反馈
  408. this.feedbacks.set([
  409. {
  410. id: 'fb1',
  411. projectId: this.projectId,
  412. customerName: '王先生',
  413. content: '对设计方案整体满意,但希望客厅颜色能更柔和一些。',
  414. rating: 4,
  415. createdAt: new Date('2023-06-19'),
  416. status: '已解决',
  417. response: '已根据您的需求调整了客厅颜色方案,详见最新上传的效果图。',
  418. isSatisfied: true
  419. }
  420. ]);
  421. }
  422. // 切换标签页
  423. switchTab(tab: string): void {
  424. this.activeTab.set(tab);
  425. }
  426. // 增强版发送消息功能
  427. sendMessage(): void {
  428. if (this.newMessage().trim()) {
  429. // 添加发送动画效果
  430. const sendBtn = document.querySelector('.message-actions .primary-btn');
  431. if (sendBtn) {
  432. sendBtn.classList.add('sending');
  433. setTimeout(() => sendBtn.classList.remove('sending'), 300);
  434. }
  435. const newMsg: Message = {
  436. id: `msg${Date.now()}`,
  437. sender: '客服小李',
  438. content: this.newMessage().trim(),
  439. timestamp: new Date(),
  440. isRead: true,
  441. type: 'text'
  442. };
  443. this.messages.set([...this.messages(), newMsg]);
  444. this.newMessage.set('');
  445. // 自动滚动到底部
  446. setTimeout(() => {
  447. const container = document.querySelector('.messages-list');
  448. if (container) {
  449. container.scrollTop = container.scrollHeight;
  450. }
  451. }, 100);
  452. }
  453. }
  454. // 增强版完成任务功能
  455. completeTask(taskId: string): void {
  456. // 添加完成动画效果
  457. const taskElement = document.querySelector(`.task-item[data-id="${taskId}"]`);
  458. if (taskElement) {
  459. taskElement.classList.add('completing');
  460. setTimeout(() => taskElement.classList.remove('completing'), 500);
  461. }
  462. this.tasks.set(
  463. this.tasks().map(task =>
  464. task.id === taskId
  465. ? { ...task, isCompleted: true, completedDate: new Date(), isOverdue: false }
  466. : task
  467. )
  468. );
  469. // 播放完成音效
  470. this.playSound('complete');
  471. }
  472. // 修复 completeMilestone 方法中的类型问题
  473. completeMilestone(milestoneId: string): void {
  474. this.milestones.set(
  475. this.milestones().map(milestone =>
  476. milestone.id === milestoneId
  477. ? { ...milestone, isCompleted: true, completedDate: new Date() }
  478. : milestone
  479. )
  480. );
  481. }
  482. // 增强 formatDate 和 formatDateTime 方法的类型安全
  483. formatDate(date: Date | string | null | undefined): string {
  484. if (!date) return '-';
  485. try {
  486. return new Date(date).toLocaleDateString('zh-CN', {
  487. year: 'numeric',
  488. month: '2-digit',
  489. day: '2-digit'
  490. });
  491. } catch (error) {
  492. console.error('日期格式化错误:', error);
  493. return '-';
  494. }
  495. }
  496. formatDateTime(date: Date | string | null | undefined): string {
  497. if (!date) return '-';
  498. try {
  499. return new Date(date).toLocaleString('zh-CN', {
  500. year: 'numeric',
  501. month: '2-digit',
  502. day: '2-digit',
  503. hour: '2-digit',
  504. minute: '2-digit'
  505. });
  506. } catch (error) {
  507. console.error('日期时间格式化错误:', error);
  508. return '-';
  509. }
  510. }
  511. // 下载文件
  512. downloadFile(file: FileItem): void {
  513. console.log('下载文件:', file.name);
  514. // 实际应用中,这里会处理文件下载逻辑
  515. }
  516. // 查看文件预览
  517. previewFile(file: FileItem): void {
  518. console.log('预览文件:', file.name);
  519. // 实际应用中,这里会打开文件预览
  520. }
  521. // 获取项目状态的CSS类名
  522. getProjectStatusClass(status: string | null | undefined): string {
  523. if (!status) return 'status-default';
  524. switch (status) {
  525. case '进行中':
  526. return 'status-active';
  527. case '待确认':
  528. return 'status-pending';
  529. case '已完成':
  530. return 'status-completed';
  531. default:
  532. return 'status-default';
  533. }
  534. }
  535. // 获取反馈客户名称(带安全检查)
  536. getFeedbackCustomerName(feedback: CustomerFeedback | undefined | null): string {
  537. if (!feedback) return '未知客户';
  538. return feedback.customerName || '未知客户';
  539. }
  540. // 获取反馈评分(带安全检查)
  541. getFeedbackRating(feedback: CustomerFeedback | undefined | null): number {
  542. if (!feedback) return 0;
  543. return feedback.rating || 0;
  544. }
  545. // 消息输入事件处理
  546. onMessageInput(event: Event): void {
  547. const target = event.target as HTMLTextAreaElement;
  548. this.newMessage.set(target.value);
  549. }
  550. // 添加正确的progressFillWidth计算属性
  551. progressFillWidth = computed(() => {
  552. return `${this.completionProgress()}%`;
  553. });
  554. // AfterViewChecked 接口实现,用于滚动到聊天窗口底部
  555. ngAfterViewChecked(): void {
  556. if (this.scrollToBottom && this.wechatMessagesContainer) {
  557. this.wechatMessagesContainer.nativeElement.scrollTop =
  558. this.wechatMessagesContainer.nativeElement.scrollHeight;
  559. this.scrollToBottom = false;
  560. }
  561. }
  562. // 初始化企业微信聊天
  563. initWechatMessages(): void {
  564. // 模拟企业微信聊天消息
  565. this.wechatMessagesList = [
  566. {
  567. sender: '客服小李',
  568. content: '您好,张先生,我们已经收到您的需求,正在为您制定设计方案。',
  569. timestamp: new Date('2023-06-01T10:30:00')
  570. },
  571. {
  572. sender: '张先生',
  573. content: '好的,我希望客厅光线充足,储物空间充足,并且使用环保材料。',
  574. timestamp: new Date('2023-06-01T10:35:00')
  575. },
  576. {
  577. sender: '客服小李',
  578. content: '明白了,我们会重点考虑这些需求。预计3天内可以完成初步方案。',
  579. timestamp: new Date('2023-06-01T10:40:00')
  580. },
  581. {
  582. sender: '张设计师',
  583. content: '您好,我是负责您项目的设计师小张。今天下午我会去现场量房,请问您方便吗?',
  584. timestamp: new Date('2023-06-02T14:00:00')
  585. },
  586. {
  587. sender: '张先生',
  588. content: '下午好的,我在小区门口等您。',
  589. timestamp: new Date('2023-06-02T14:05:00')
  590. },
  591. {
  592. sender: '张设计师',
  593. content: '已完成量房,正在制作初步设计方案。',
  594. timestamp: new Date('2023-06-05T18:30:00')
  595. },
  596. {
  597. sender: '客服小李',
  598. content: '张先生,初步设计方案已完成,您什么时候方便查看一下?',
  599. timestamp: new Date('2023-06-08T10:00:00')
  600. }
  601. ];
  602. // 确保滚动到底部
  603. setTimeout(() => {
  604. this.scrollToBottom = true;
  605. }, 100);
  606. }
  607. // 增强版发送企业微信消息
  608. sendWechatMessage(): void {
  609. if (!this.wechatInput.trim()) return;
  610. // 添加发送动画
  611. const sendBtn = document.querySelector('.wechat-input-area .send-btn');
  612. if (sendBtn) {
  613. sendBtn.classList.add('sending');
  614. setTimeout(() => sendBtn.classList.remove('sending'), 300);
  615. }
  616. const newMessage: WechatMessage = {
  617. sender: '客服小李',
  618. content: this.wechatInput.trim(),
  619. timestamp: new Date()
  620. };
  621. this.wechatMessagesList = [...this.wechatMessagesList, newMessage];
  622. this.wechatInput = '';
  623. this.scrollToBottom = true;
  624. // 播放发送音效
  625. this.playSound('message');
  626. // 模拟对方回复
  627. setTimeout(() => {
  628. const replyMessage: WechatMessage = {
  629. sender: '张先生',
  630. content: '收到,我稍后查看。',
  631. timestamp: new Date()
  632. };
  633. this.wechatMessagesList = [...this.wechatMessagesList, replyMessage];
  634. this.scrollToBottom = true;
  635. // 播放接收音效
  636. this.playSound('notification');
  637. }, 2000);
  638. }
  639. // 新增播放音效方法
  640. playSound(type: 'message' | 'notification' | 'complete'): void {
  641. // 实际项目中这里会播放对应的音效
  642. console.log(`播放${type}音效`);
  643. }
  644. // 初始化历史服务记录
  645. initHistoricalServiceRecords(): void {
  646. // 模拟过往咨询记录
  647. this.consultationRecords.set([
  648. {
  649. id: 'cons1',
  650. date: new Date('2023-01-15'),
  651. content: '咨询关于厨房改造的可行性和预算',
  652. status: '已解决'
  653. },
  654. {
  655. id: 'cons2',
  656. date: new Date('2023-03-20'),
  657. content: '询问装修材料环保认证相关问题',
  658. status: '已解决'
  659. },
  660. {
  661. id: 'cons3',
  662. date: new Date('2023-05-10'),
  663. content: '了解装修分期付款方案',
  664. status: '已解决'
  665. }
  666. ]);
  667. // 模拟合作项目记录
  668. this.cooperationProjects.set([
  669. {
  670. id: 'proj1',
  671. name: '2022年现代简约卧室设计项目',
  672. startDate: new Date('2022-08-15'),
  673. endDate: new Date('2022-10-30'),
  674. status: '已完成',
  675. description: '为客户设计并实施了现代简约风格的卧室改造,包括定制衣柜和床头背景墙'
  676. },
  677. {
  678. id: 'proj2',
  679. name: '2023年欧式厨房设计项目',
  680. startDate: new Date('2023-02-01'),
  681. endDate: new Date('2023-04-15'),
  682. status: '已完成',
  683. description: '设计并安装了全套欧式风格厨房,包括橱柜、台面和电器选型'
  684. }
  685. ]);
  686. // 模拟历史反馈/评价
  687. this.historicalFeedbacks.set([
  688. {
  689. id: 'fb1',
  690. date: new Date('2022-11-05'),
  691. content: '卧室设计非常满意,空间利用合理,风格符合预期',
  692. rating: 5,
  693. response: '感谢您的好评,我们会继续努力为您提供优质服务'
  694. },
  695. {
  696. id: 'fb2',
  697. date: new Date('2023-04-20'),
  698. content: '厨房装修质量很好,但工期比预期稍长',
  699. rating: 4,
  700. response: '感谢您的反馈,我们已经优化了施工流程,会在后续项目中改进'
  701. }
  702. ]);
  703. }
  704. // 格式化为时间显示
  705. formatTime(date: Date): string {
  706. if (!date) return '';
  707. return new Date(date).toLocaleTimeString('zh-CN', {
  708. hour: '2-digit',
  709. minute: '2-digit'
  710. });
  711. }
  712. // 获取当前日期的计算属性
  713. currentDate = computed(() => {
  714. return new Date();
  715. });
  716. // 售后处理入口方法
  717. openModificationRequest(): void {
  718. const dialogRef = this.dialog.open(ModificationRequestDialog, {
  719. width: '500px',
  720. data: {
  721. projectId: this.projectId,
  722. projectName: this.project()?.name || '现代简约风格三居室设计',
  723. projectStatus: this.project()?.status || '进行中'
  724. }
  725. });
  726. dialogRef.afterClosed().subscribe(result => {
  727. if (result) {
  728. console.log('申请修改提交成功', result);
  729. // 这里可以添加提交成功后的处理逻辑,如刷新数据、显示通知等
  730. }
  731. });
  732. }
  733. openComplaintWarning(): void {
  734. const dialogRef = this.dialog.open(ComplaintWarningDialog, {
  735. width: '500px',
  736. data: {
  737. projectId: this.projectId,
  738. projectName: this.project()?.name || '现代简约风格三居室设计'
  739. }
  740. });
  741. dialogRef.afterClosed().subscribe(result => {
  742. if (result) {
  743. console.log('投诉预警提交成功', result);
  744. // 这里可以添加提交成功后的处理逻辑
  745. }
  746. });
  747. }
  748. openRefundRequest(): void {
  749. const dialogRef = this.dialog.open(RefundRequestDialog, {
  750. width: '500px',
  751. data: {
  752. projectId: this.projectId,
  753. projectName: this.project()?.name || '现代简约风格三居室设计',
  754. projectAmount: 85000 // 模拟项目金额
  755. }
  756. });
  757. dialogRef.afterClosed().subscribe(result => {
  758. if (result) {
  759. console.log('申请退款提交成功', result);
  760. // 这里可以添加提交成功后的处理逻辑
  761. }
  762. });
  763. }
  764. }