14448af731
- 添加案例、新闻、产品详情页面的E2E测试 - 优化详情页面的客户端组件和页面逻辑 - 添加高性能Docker配置和Nginx配置 - 更新API服务和常量配置 - 添加性能优化文档和任务进度更新 - 修复ESLint错误和类型问题
152 lines
3.9 KiB
TypeScript
152 lines
3.9 KiB
TypeScript
import { apiClient } from './client';
|
|
import { Product, NewsItem, Service, ContentItem } from './types';
|
|
|
|
class ContentService {
|
|
async getProducts(featuredIds?: string[]): Promise<Product[]> {
|
|
try {
|
|
const data = await apiClient.get<ContentItem[]>('/api/content', {
|
|
type: 'product',
|
|
status: 'published',
|
|
});
|
|
|
|
let products = data.map(item => this.transformToProduct(item));
|
|
|
|
if (featuredIds && featuredIds.length > 0) {
|
|
products = products.filter(p => featuredIds.includes(p.id));
|
|
}
|
|
|
|
return products;
|
|
} catch (error) {
|
|
console.error('Failed to fetch products:', error);
|
|
return [];
|
|
}
|
|
}
|
|
|
|
async getNews(
|
|
categories?: string[],
|
|
limit?: number,
|
|
sortOrder: 'asc' | 'desc' = 'desc'
|
|
): Promise<NewsItem[]> {
|
|
try {
|
|
const data = await apiClient.get<ContentItem[]>('/api/content', {
|
|
type: 'news',
|
|
status: 'published',
|
|
});
|
|
|
|
let news = data.map(item => this.transformToNews(item));
|
|
|
|
if (categories && categories.length > 0) {
|
|
news = news.filter(n => categories.includes(n.category));
|
|
}
|
|
|
|
if (sortOrder === 'desc') {
|
|
news.sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime());
|
|
} else {
|
|
news.sort((a, b) => new Date(a.date).getTime() - new Date(b.date).getTime());
|
|
}
|
|
|
|
if (limit && limit > 0) {
|
|
news = news.slice(0, limit);
|
|
}
|
|
|
|
return news;
|
|
} catch (error) {
|
|
console.error('Failed to fetch news:', error);
|
|
return [];
|
|
}
|
|
}
|
|
|
|
async getServices(ids?: string[]): Promise<Service[]> {
|
|
try {
|
|
const data = await apiClient.get<ContentItem[]>('/api/content', {
|
|
type: 'service',
|
|
status: 'published',
|
|
});
|
|
|
|
let services = data.map(item => this.transformToService(item));
|
|
|
|
if (ids && ids.length > 0) {
|
|
services = services.filter(s => ids.includes(s.id));
|
|
}
|
|
|
|
return services;
|
|
} catch (error) {
|
|
console.error('Failed to fetch services:', error);
|
|
return [];
|
|
}
|
|
}
|
|
|
|
async getCases(limit?: number): Promise<NewsItem[]> {
|
|
try {
|
|
const data = await apiClient.get<ContentItem[]>('/api/content', {
|
|
type: 'case',
|
|
status: 'published',
|
|
});
|
|
|
|
let cases = data.map(item => this.transformToNews(item));
|
|
|
|
if (limit && limit > 0) {
|
|
cases = cases.slice(0, limit);
|
|
}
|
|
|
|
return cases;
|
|
} catch (error) {
|
|
console.error('Failed to fetch cases:', error);
|
|
return [];
|
|
}
|
|
}
|
|
|
|
private transformToProduct(item: ContentItem): Product {
|
|
const metadata = item.metadata || {};
|
|
return {
|
|
id: item.id,
|
|
title: item.title,
|
|
description: item.excerpt || '',
|
|
category: item.category || '',
|
|
features: metadata.features || [],
|
|
benefits: metadata.benefits || [],
|
|
pricing: metadata.pricing,
|
|
image: item.coverImage,
|
|
slug: item.slug,
|
|
};
|
|
}
|
|
|
|
private transformToNews(item: ContentItem): NewsItem {
|
|
return {
|
|
id: item.id,
|
|
title: item.title,
|
|
excerpt: item.excerpt || '',
|
|
content: item.content,
|
|
date: item.publishedAt ? this.formatDate(item.publishedAt) : this.formatDate(item.createdAt),
|
|
category: item.category || '公司新闻',
|
|
image: item.coverImage,
|
|
slug: item.slug,
|
|
};
|
|
}
|
|
|
|
private transformToService(item: ContentItem): Service {
|
|
const metadata = item.metadata || {};
|
|
return {
|
|
id: item.id,
|
|
title: item.title,
|
|
description: item.excerpt || '',
|
|
icon: metadata.icon || 'Code',
|
|
features: metadata.features || [],
|
|
benefits: metadata.benefits || [],
|
|
slug: item.slug,
|
|
};
|
|
}
|
|
|
|
private formatDate(dateString: string): string {
|
|
try {
|
|
const date = new Date(dateString);
|
|
const isoString = date.toISOString();
|
|
return isoString.split('T')[0] || dateString;
|
|
} catch {
|
|
return dateString;
|
|
}
|
|
}
|
|
}
|
|
|
|
export const contentService = new ContentService();
|