feat: 实现内容管理API及相关功能

refactor(services-section): 重构服务展示组件使用API数据
refactor(news-section): 重构新闻展示组件使用API数据
refactor(products-section): 重构产品展示组件使用API数据

test: 添加API客户端和服务钩子的单元测试
test(e2e): 添加配置验证和API响应格式的端到端测试

ci: 更新Playwright测试配置
This commit is contained in:
张翔
2026-03-13 18:55:25 +08:00
parent 72745456d2
commit ac2672729f
20 changed files with 3934 additions and 153 deletions
+32
View File
@@ -0,0 +1,32 @@
import { useState, useEffect } from 'react';
import { contentService } from '@/lib/api/services';
import { NewsItem } from '@/lib/api/types';
export function useNews(
categories?: string[],
limit?: number,
sortOrder: 'asc' | 'desc' = 'desc'
) {
const [news, setNews] = useState<NewsItem[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<Error | null>(null);
useEffect(() => {
async function fetchNews() {
try {
setLoading(true);
setError(null);
const data = await contentService.getNews(categories, limit, sortOrder);
setNews(data);
} catch (err) {
setError(err instanceof Error ? err : new Error('Failed to fetch news'));
} finally {
setLoading(false);
}
}
fetchNews();
}, [categories, limit, sortOrder]);
return { news, loading, error };
}
+28
View File
@@ -0,0 +1,28 @@
import { useState, useEffect } from 'react';
import { contentService } from '@/lib/api/services';
import { Product } from '@/lib/api/types';
export function useProducts(featuredIds?: string[]) {
const [products, setProducts] = useState<Product[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<Error | null>(null);
useEffect(() => {
async function fetchProducts() {
try {
setLoading(true);
setError(null);
const data = await contentService.getProducts(featuredIds);
setProducts(data);
} catch (err) {
setError(err instanceof Error ? err : new Error('Failed to fetch products'));
} finally {
setLoading(false);
}
}
fetchProducts();
}, [featuredIds]);
return { products, loading, error };
}
+28
View File
@@ -0,0 +1,28 @@
import { useState, useEffect } from 'react';
import { contentService } from '@/lib/api/services';
import { Service } from '@/lib/api/types';
export function useServices(ids?: string[]) {
const [services, setServices] = useState<Service[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<Error | null>(null);
useEffect(() => {
async function fetchServices() {
try {
setLoading(true);
setError(null);
const data = await contentService.getServices(ids);
setServices(data);
} catch (err) {
setError(err instanceof Error ? err : new Error('Failed to fetch services'));
} finally {
setLoading(false);
}
}
fetchServices();
}, [ids]);
return { services, loading, error };
}