1+ import { createResource , For , Show } from 'solid-js' ;
2+ import http from '@/lib/axios' ;
3+
4+ // 定义文章接口
5+ interface Post {
6+ id : string ;
7+ title : string ;
8+ slug : string ;
9+ excerpt : string | null ;
10+ featured_image : string | null ;
11+ published : boolean ;
12+ author_id : string ;
13+ created_at : string ;
14+ updated_at : string ;
15+ published_at : string ;
16+ labels : string [ ] ;
17+ }
18+
19+ // 格式化日期函数
20+ function formatDate ( dateString : string ) {
21+ const date = new Date ( dateString ) ;
22+ return date . toLocaleDateString ( "zh-CN" , {
23+ year : "numeric" ,
24+ month : "long" ,
25+ day : "numeric" ,
26+ } ) ;
27+ }
28+
29+ // 获取文章数据的函数
30+ async function fetchPosts ( ) : Promise < Post [ ] > {
31+ try {
32+ const response = await http . get < Post [ ] > ( "/posts" ) ;
33+
34+ // 检查响应格式,直接处理返回的数组数据
35+ if ( response && Array . isArray ( response ) ) {
36+ // 成功获取数据,API直接返回了文章数组
37+ return response . map ( ( post ) => ( {
38+ ...post ,
39+ featured_image : post . featured_image
40+ ? post . featured_image . replace ( / ` / g, "" ) . trim ( )
41+ : null ,
42+ } ) ) ;
43+ } else {
44+ // 响应格式不符合预期
45+ console . error ( 'API响应格式不符合预期:' , response ) ;
46+ return [ ] ;
47+ }
48+ } catch ( error ) {
49+ console . error ( '获取文章失败:' , error ) ;
50+ return [ ] ;
51+ }
52+ }
53+
54+ export default function BlogPosts ( ) {
55+ // 使用SolidJS的资源加载功能获取文章
56+ const [ posts ] = createResource < Post [ ] > ( fetchPosts ) ;
57+ return (
58+ < div class = "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 my-8" >
59+ < Show when = { ! posts . loading } fallback = { < div class = "col-span-full text-center" > 加载中...</ div > } >
60+ < Show
61+ when = { posts ( ) && posts ( ) . length > 0 }
62+ fallback = {
63+ < div class = "col-span-full text-center py-12" >
64+ < div class = "alert alert-info shadow-lg max-w-md mx-auto" >
65+ < svg
66+ xmlns = "http://www.w3.org/2000/svg"
67+ fill = "none"
68+ viewBox = "0 0 24 24"
69+ class = "stroke-current shrink-0 w-6 h-6"
70+ >
71+ < path
72+ stroke-linecap = "round"
73+ stroke-linejoin = "round"
74+ stroke-width = "2"
75+ d = "M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
76+ />
77+ </ svg >
78+ < span > 暂无文章,敬请期待!</ span >
79+ </ div >
80+ </ div >
81+ }
82+ >
83+ < For each = { posts ( ) } >
84+ { ( post ) => (
85+ < div class = "card bg-base-100 shadow-xl hover:shadow-2xl transition-shadow duration-300" >
86+ { post . featured_image && post . featured_image . trim ( ) !== "" && (
87+ < figure >
88+ < img src = { post . featured_image } alt = { post . title } class = "w-full h-48 object-cover" />
89+ </ figure >
90+ ) }
91+ < div class = "card-body" >
92+ < h2 class = "card-title" > { post . title } </ h2 >
93+ < p class = "text-sm opacity-70" > { formatDate ( post . published_at ) } </ p >
94+ < p class = "mt-2" > { post . excerpt || "" } </ p >
95+ { post . labels && post . labels . length > 0 && (
96+ < div class = "card-actions justify-start mt-3" >
97+ { post . labels . map ( ( tag ) => (
98+ < div class = "badge badge-outline" > { tag } </ div >
99+ ) ) }
100+ </ div >
101+ ) }
102+ < div class = "card-actions justify-end mt-4" >
103+ < a href = { `/blog/${ post . id } ` } class = "btn btn-primary btn-sm" > 阅读更多</ a >
104+ </ div >
105+ </ div >
106+ </ div >
107+ ) }
108+ </ For >
109+ </ Show >
110+ </ Show >
111+ </ div >
112+ ) ;
113+ }
0 commit comments