blob: 953af8a3c46cab9aaf6cb5f074c8c743208c7131 [file] [log] [blame]
22301014356527a2025-06-09 17:46:56 +08001import React, { useEffect, useMemo } from 'react';
2import { useDispatch } from 'react-redux';
3import { Input, Spin, Alert } from 'antd';
4import { SearchOutlined } from '@ant-design/icons';
5import type { Section, Artwork } from './types';
6import { initializeArtworks, selectFilteredArtworks, selectSearchTerm, selectWorkListError, selectWorkListLoading, setSearchTerm } from './workListSlice';
7import { useAppSelector } from '../../store/hooks';
8import { selectSections, selectCategoryLoading, selectCategoryError, initializeSections } from './categorySlice';
9import Category from './Category';
223010143d966302025-06-07 22:54:40 +080010
22301014356527a2025-06-09 17:46:56 +080011const Home: React.FC = () => {
12 const dispatch = useDispatch();
22301014bc4616f2025-06-03 16:59:44 +080013
22301014356527a2025-06-09 17:46:56 +080014 // 从Redux store获取状态
15 const sections = useAppSelector(selectSections);
16 const filteredArtworks = useAppSelector(selectFilteredArtworks);
17 const searchTerm = useAppSelector(selectSearchTerm);
18 const workListLoading = useAppSelector(selectWorkListLoading);
19 const workListError = useAppSelector(selectWorkListError);
20 const categoryLoading = useAppSelector(selectCategoryLoading);
21 const categoryError = useAppSelector(selectCategoryError);
223010143d966302025-06-07 22:54:40 +080022
22301014356527a2025-06-09 17:46:56 +080023 // 综合加载状态和错误状态
24 const loading = workListLoading || categoryLoading;
25 const error = workListError || categoryError;
223010143d966302025-06-07 22:54:40 +080026
22301014356527a2025-06-09 17:46:56 +080027 // 示例数据
28 const sampleSections: Section[] = [
29 {
30 id: 1,
31 childrenid: [1, 2, 3],
32 name: "数字艺术"
33 },
34 {
35 id: 2,
36 childrenid: [4, 5],
37 name: "传统绘画"
38 }
39 ];
223010143d966302025-06-07 22:54:40 +080040
22301014356527a2025-06-09 17:46:56 +080041 const sampleArtworks: Artwork[] = [
42 {
43 id: 1,
44 title: "未来城市概念设计",
45 author: "视觉设计师张三",
46 views: 1247,
47 category: {
48 id: 1,
49 name: "数字艺术",
50 children: ["概念设计", "建筑设计"]
51 },
52 description: "一个关于2050年智慧城市的概念设计作品,融合了可持续发展、人工智能和绿色科技的理念",
53 createTime: "2024-01-15T10:30:00Z",
54 cover: "https://picsum.photos/300/200?random=1"
55 },
56 {
57 id: 2,
58 title: "移动应用界面设计套件",
59 author: "UI设计师李四",
60 views: 856,
61 category: {
62 id: 2,
63 name: "界面设计",
64 children: ["UI/UX设计", "移动端设计"]
65 },
66 description: "一套完整的移动端UI设计规范和组件库,包含100+个精美界面和500+个设计组件",
67 createTime: "2024-02-20T14:15:00Z",
68 cover: "https://picsum.photos/300/200?random=2"
69 },
70 {
71 id: 3,
72 title: "React组件库开发指南",
73 author: "刘松林",
74 views: 432,
75 category: {
76 id: 3,
77 name: "程序开发",
78 children: ["前端开发", "React技术"]
79 },
80 description: "一套完整的企业级React组件库开发教程和源码,包含从设计到发布的完整流程",
81 createTime: "2024-03-10T09:45:00Z",
82 cover: "https://picsum.photos/300/200?random=3"
83 },
84 {
85 id: 4,
86 title: "机械战士3D模型",
87 author: "3D艺术家王五",
88 views: 789,
89 category: {
90 id: 1,
91 name: "数字艺术",
92 children: ["3D建模", "科幻设计"]
93 },
94 description: "一个高精度的科幻机械战士3D模型,包含完整的材质贴图和动画骨骼系统",
95 createTime: "2024-01-25T16:20:00Z",
96 cover: "https://picsum.photos/300/200?random=4"
97 },
98 {
99 id: 5,
100 title: "城市夜景摄影集",
101 author: "摄影师赵六",
102 views: 1123,
103 category: {
104 id: 4,
105 name: "摄影艺术",
106 children: ["摄影作品", "城市风光"]
107 },
108 description: "一组精美的城市夜景摄影作品,捕捉了都市夜晚的璀璨光影",
109 createTime: "2024-02-14T11:30:00Z",
110 cover: "https://picsum.photos/300/200?random=5"
111 },
112 {
113 id: 6,
114 title: "奇幻世界插画系列",
115 author: "插画师孙七",
116 views: 945,
117 category: {
118 id: 5,
119 name: "插画艺术",
120 children: ["插画艺术", "奇幻风格"]
121 },
122 description: "一套充满想象力的奇幻题材插画作品,包含角色设计、场景概念图和完整插图",
123 createTime: "2024-03-05T13:20:00Z",
124 cover: "https://picsum.photos/300/200?random=6"
125 }
126 ];
223010143d966302025-06-07 22:54:40 +0800127
22301014356527a2025-06-09 17:46:56 +0800128 // 初始化数据
129 useEffect(() => {
130 dispatch(initializeArtworks(sampleArtworks));
131 dispatch(initializeSections(sampleSections));
132 }, [dispatch]);
133
134 // 处理搜索输入
135 const handleSearchChange = (e: React.ChangeEvent<HTMLInputElement>) => {
136 dispatch(setSearchTerm(e.target.value));
137 };
138
139 // 根据分区ID获取对应的作品
140 const getArtworksBySection = useMemo(() => {
141 return (childrenIds: number[]): Artwork[] => {
142 return filteredArtworks.filter(artwork => childrenIds.includes(artwork.id));
143 };
144 }, [filteredArtworks]);
145
146 // 渲染加载状态
147 if (loading) {
148 return (
149 <div style={{
150 display: 'flex',
151 justifyContent: 'center',
152 alignItems: 'center',
153 height: '100vh'
154 }}>
155 <Spin size="large" tip="加载中..." />
156 </div>
157 );
158 }
159
160 // 渲染错误状态
161 if (error) {
162 return (
163 <div style={{ padding: '24px' }}>
164 <Alert
165 message="加载失败"
166 description={error}
167 type="error"
168 showIcon
169 />
170 </div>
171 );
172 }
173
174 return (
175 <div style={{
176 backgroundColor: '#f5f5f5',
177 minHeight: '100vh',
178 padding: '24px'
179 }}>
180 <div style={{ maxWidth: 1200, margin: '0 auto' }}>
181 {/* 搜索栏 */}
182 <div style={{ marginBottom: '32px' }}>
183 <Input
184 size="large"
185 placeholder="搜索作品标题、作者、分类..."
186 prefix={<SearchOutlined />}
187 value={searchTerm}
188 onChange={handleSearchChange}
189 style={{ maxWidth: 600, width: '100%' }}
190 allowClear
191 />
223010143d966302025-06-07 22:54:40 +0800192 </div>
223010143d966302025-06-07 22:54:40 +0800193
22301014356527a2025-06-09 17:46:56 +0800194 {/* 分区展示 */}
195 {sections.map((section) => {
196 const sectionArtworks = getArtworksBySection(section.childrenid);
22301014bc4616f2025-06-03 16:59:44 +0800197
22301014356527a2025-06-09 17:46:56 +0800198 return (
199 <Category
200 key={section.id}
201 section={section}
202 artworks={sectionArtworks}
203 />
204 );
205 })}
206
207 {/* 无搜索结果提示 */}
208 {searchTerm && filteredArtworks.length === 0 && (
209 <div style={{
210 textAlign: 'center',
211 padding: '48px 0',
212 color: '#999'
213 }}>
214 <p style={{ fontSize: 16 }}>未找到相关作品</p>
215 <p>尝试使用其他关键词搜索</p>
216 </div>
217 )}
218 </div>
219 </div>
220 );
221};
222
223export default Home;