fix(mp): 文章详情页对齐 mp-04 原型 — 流式布局+底部浮动栏

- 标题 22px serif bold(原型值),元信息 13px tx3
- 正文 15px tx2 lineHeight:1.8 首行缩进(原型值)
- 去掉分段白卡片,改为统一背景流式布局
- 新增底部浮动栏:收藏+分享按钮
- 分隔线 1px bdL
This commit is contained in:
iven
2026-05-17 15:53:03 +08:00
parent d5ec250184
commit b84becfbea
2 changed files with 87 additions and 73 deletions

View File

@@ -1,65 +1,41 @@
@import '../../../styles/variables.scss'; @import '../../../styles/variables.scss';
@import '../../../styles/mixins.scss';
// PageShell 已接管min-height, background, padding // 文章详情页 — 对齐原型 docs/design/mp-04-article-report.html → ArticleDetail
.article-header { .article-detail-page {
background: $card; padding-bottom: 80px;
padding: var(--tk-gap-xl);
margin-bottom: 2px;
} }
.article-title { .article-title {
font-size: var(--tk-font-hero); font-family: Georgia, 'Times New Roman', serif;
font-weight: bold; font-size: var(--tk-font-h2);
font-weight: 700;
color: $tx; color: $tx;
display: block; display: block;
line-height: 1.4; line-height: 1.4;
margin-bottom: var(--tk-gap-md); margin-bottom: var(--tk-gap-sm);
} }
.article-meta { .article-meta {
display: flex; display: flex;
align-items: center;
gap: var(--tk-gap-md); gap: var(--tk-gap-md);
flex-wrap: wrap; font-size: var(--tk-font-cap);
color: $tx3;
margin-bottom: var(--tk-gap-md);
} }
.article-category { .article-divider {
font-size: var(--tk-font-body); height: 1px;
color: var(--tk-pri); background: $bd-l;
background: var(--tk-pri-l); margin-bottom: var(--tk-section-gap);
padding: var(--tk-gap-2xs) var(--tk-gap-sm);
border-radius: $r-sm;
} }
.article-author { .article-body {
font-size: var(--tk-font-h2); font-size: 15px;
color: $tx2; color: $tx2;
} line-height: 1.8;
.article-date { // RichText 内部样式
font-size: var(--tk-font-h2);
color: var(--tk-text-secondary);
}
.article-summary {
background: $card;
padding: var(--tk-gap-lg) var(--tk-gap-xl);
margin-bottom: 2px;
}
.summary-text {
font-size: var(--tk-font-h1);
color: $tx2;
line-height: 1.6;
}
.article-content {
background: $card;
padding: var(--tk-gap-xl);
// RichText 内部样式优化
h1, h2, h3 { h1, h2, h3 {
font-weight: bold; font-weight: bold;
color: $tx; color: $tx;
@@ -67,10 +43,8 @@
} }
p { p {
font-size: var(--tk-font-body-lg);
color: $tx;
line-height: 1.8;
margin-bottom: var(--tk-gap-md); margin-bottom: var(--tk-gap-md);
text-indent: 2em;
} }
img { img {
@@ -80,6 +54,44 @@
} }
} }
.article-bottom-bar {
position: fixed;
bottom: 0;
left: 0;
right: 0;
height: 60px;
background: $card;
border-top: 1px solid $bd-l;
display: flex;
align-items: center;
justify-content: center;
gap: 32px;
padding: 0 var(--tk-page-padding);
z-index: 10;
}
.article-action-btn {
display: flex;
flex-direction: column;
align-items: center;
gap: 2px;
&:active {
opacity: var(--tk-touch-feedback-opacity);
}
}
.article-action-icon {
font-size: 20px;
color: $tx3;
line-height: 1;
}
.article-action-text {
font-size: var(--tk-font-micro);
color: $tx3;
}
.loading-state, .loading-state,
.empty-state { .empty-state {
display: flex; display: flex;
@@ -90,6 +102,6 @@
.loading-text, .loading-text,
.empty-text { .empty-text {
font-size: var(--tk-font-body-lg); font-size: var(--tk-font-body);
color: var(--tk-text-secondary); color: $tx3;
} }

View File

@@ -63,36 +63,38 @@ export default function ArticleDetail() {
); );
} }
const handleCollect = () => {
Taro.showToast({ title: '已收藏', icon: 'success' });
};
const handleShare = () => {
Taro.showShareMenu({ withShareTicket: true });
};
return ( return (
<PageShell className={modeClass}> <PageShell padding="md" safeBottom={false} scroll={false} className={`article-detail-page ${modeClass}`}>
{/* 文章头部 */} <Text className='article-title'>{article.title}</Text>
<View className='article-header'>
<Text className='article-title'>{article.title}</Text> <View className='article-meta'>
<View className='article-meta'> {article.author && <Text>{article.author}</Text>}
{article.category && ( {article.published_at && <Text>{article.published_at.slice(0, 10)}</Text>}
<Text className='article-category'>{article.category}</Text>
)}
{article.author && (
<Text className='article-author'>{article.author}</Text>
)}
{article.published_at && (
<Text className='article-date'>{article.published_at.slice(0, 10)}</Text>
)}
</View>
</View> </View>
{/* 摘要 */} <View className='article-divider' />
{article.summary && (
<View className='article-summary'>
<Text className='summary-text'>{article.summary}</Text>
</View>
)}
{/* 正文 */} <View className='article-body'>
<View className='article-content'> <RichText nodes={sanitizeHtml(article.content || '')} />
<RichText </View>
nodes={sanitizeHtml(article.content || '')}
/> <View className='article-bottom-bar'>
<View className='article-action-btn' onClick={handleCollect}>
<Text className='article-action-icon'></Text>
<Text className='article-action-text'></Text>
</View>
<View className='article-action-btn' onClick={handleShare}>
<Text className='article-action-icon'></Text>
<Text className='article-action-text'></Text>
</View>
</View> </View>
</PageShell> </PageShell>
); );