| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219 |
- import { Component, OnInit } from '@angular/core';
- import { CommonModule } from '@angular/common';
- import { ActivatedRoute, Router } from '@angular/router';
- interface Case {
- id: string;
- name: string;
- coverImage: string;
- projectType: '工装' | '家装';
- spaceType: '平层' | '复式' | '别墅' | '自建房';
- renderingLevel: '高端' | '中端' | '低端';
- designer: string;
- team: string;
- area: number;
- styleTags: string[];
- customerReview?: string;
- viewCount: number;
- shareCount: number;
- favoriteCount: number;
- isFavorite: boolean;
- isExcellent: boolean;
- createdAt: Date;
- }
- @Component({
- selector: 'app-case-detail',
- standalone: true,
- imports: [CommonModule],
- templateUrl: './case-detail.component.html',
- styleUrls: ['./case-detail.component.scss']
- })
- export class CaseDetailComponent implements OnInit {
- case: Case | null = null;
- isInternalUser: boolean = true; // 可根据实际用户权限设置
- isLoading: boolean = true;
- caseId: string = '';
- constructor(
- private route: ActivatedRoute,
- private router: Router
- ) {}
- ngOnInit() {
- // 获取路由参数中的案例ID
- this.route.paramMap.subscribe(params => {
- this.caseId = params.get('id') || '';
- if (this.caseId) {
- this.loadCaseDetail(this.caseId);
- }
- });
- }
- private loadCaseDetail(caseId: string) {
- this.isLoading = true;
-
- // 模拟API调用,实际项目中应该调用真实的API
- setTimeout(() => {
- this.case = this.generateMockCase(caseId);
- this.isLoading = false;
-
- // 增加浏览次数
- if (this.case) {
- this.case.viewCount++;
- this.recordBehavior('case_view', this.case.id, {
- caseName: this.case.name,
- designer: this.case.designer,
- projectType: this.case.projectType,
- spaceType: this.case.spaceType
- });
- }
- }, 500);
- }
- private generateMockCase(caseId: string): Case {
- const projectTypes: ('工装' | '家装')[] = ['工装', '家装'];
- const spaceTypes: ('平层' | '复式' | '别墅' | '自建房')[] = ['平层', '复式', '别墅', '自建房'];
- const renderingLevels: ('高端' | '中端' | '低端')[] = ['高端', '中端', '低端'];
- const styles = ['现代', '中式', '欧式', '美式', '日式', '工业风', '极简风', '轻奢风'];
- const designers = ['张三', '李四', '王五', '赵六', '钱七'];
- const teams = ['设计一组', '设计二组', '设计三组', '设计四组'];
- const projectType = projectTypes[Math.floor(Math.random() * projectTypes.length)];
- const spaceType = spaceTypes[Math.floor(Math.random() * spaceTypes.length)];
- const renderingLevel = renderingLevels[Math.floor(Math.random() * renderingLevels.length)];
- const styleCount = Math.floor(Math.random() * 3) + 1;
- const styleTags = Array.from({ length: styleCount }, () =>
- styles[Math.floor(Math.random() * styles.length)]
- );
- return {
- id: caseId,
- name: `${projectType}${spaceType}设计案例 - ${caseId}`,
- coverImage: this.generatePlaceholderImage(800, 600, caseId),
- projectType,
- spaceType,
- renderingLevel,
- designer: designers[Math.floor(Math.random() * designers.length)],
- team: teams[Math.floor(Math.random() * teams.length)],
- area: Math.floor(Math.random() * 200) + 50,
- styleTags: [...new Set(styleTags)], // 去重
- customerReview: Math.random() > 0.3 ? `客户非常满意这次${projectType}设计,${spaceType}空间利用得很合理,设计师的专业水平很高,整体效果超出预期。` : undefined,
- viewCount: Math.floor(Math.random() * 1000),
- shareCount: Math.floor(Math.random() * 100),
- favoriteCount: Math.floor(Math.random() * 50),
- isFavorite: Math.random() > 0.7,
- isExcellent: Math.random() > 0.5,
- createdAt: new Date(Date.now() - Math.floor(Math.random() * 365 * 24 * 60 * 60 * 1000))
- };
- }
- private generatePlaceholderImage(width: number, height: number, seed: string): string {
- return `https://picsum.photos/seed/${seed}/${width}/${height}`;
- }
- goBack() {
- this.router.navigate(['/customer-service/case-library']);
- }
- toggleFavorite() {
- if (!this.case) return;
-
- const wasLiked = this.case.isFavorite;
- this.case.isFavorite = !this.case.isFavorite;
-
- if (this.case.isFavorite) {
- this.case.favoriteCount++;
- this.showToast('已收藏该案例', 'success');
-
- this.recordBehavior('case_favorite', this.case.id, {
- action: 'add',
- caseName: this.case.name,
- designer: this.case.designer
- });
- } else {
- this.case.favoriteCount = Math.max(0, this.case.favoriteCount - 1);
- this.showToast('已取消收藏', 'info');
-
- this.recordBehavior('case_favorite', this.case.id, {
- action: 'remove',
- caseName: this.case.name,
- designer: this.case.designer
- });
- }
- }
- shareCase() {
- if (!this.case) return;
-
- this.case.shareCount++;
-
- // 生成分享链接
- const shareLink = this.generateShareLink();
-
- // 复制到剪贴板
- navigator.clipboard.writeText(shareLink).then(() => {
- this.showToast('分享链接已复制到剪贴板', 'success');
- }).catch(() => {
- this.showToast('复制失败,请手动复制链接', 'error');
- });
-
- this.recordBehavior('share', this.case.id, {
- caseName: this.case.name,
- designer: this.case.designer,
- projectType: this.case.projectType
- });
- }
- generateShareLink(): string {
- if (!this.case) return '';
- return `${window.location.origin}/customer-service/case-detail/${this.case.id}?from=share&designer=${encodeURIComponent(this.case.designer)}`;
- }
- getFormattedDate(date: Date): string {
- return new Intl.DateTimeFormat('zh-CN', {
- year: 'numeric',
- month: 'long',
- day: 'numeric'
- }).format(new Date(date));
- }
- private recordBehavior(action: string, caseId: string, data?: any) {
- // 模拟行为记录,实际项目中应该调用真实的API
- console.log('行为记录:', {
- action,
- caseId,
- data,
- timestamp: new Date().toISOString(),
- userAgent: navigator.userAgent
- });
- }
- private showToast(message: string, type: 'success' | 'error' | 'info' = 'info') {
- // 简单的toast实现,实际项目中可以使用更完善的toast库
- const toast = document.createElement('div');
- toast.className = `toast toast-${type}`;
- toast.textContent = message;
- toast.style.cssText = `
- position: fixed;
- top: 20px;
- right: 20px;
- padding: 12px 20px;
- border-radius: 8px;
- color: white;
- font-size: 14px;
- z-index: 10000;
- animation: slideInRight 0.3s ease-out;
- background: ${type === 'success' ? '#34c759' : type === 'error' ? '#ff3b30' : '#007aff'};
- `;
-
- document.body.appendChild(toast);
-
- setTimeout(() => {
- toast.style.animation = 'slideOutRight 0.3s ease-in';
- setTimeout(() => {
- document.body.removeChild(toast);
- }, 300);
- }, 3000);
- }
- }
|