- 健康页:移除冗余"健康"标题栏,ScrollView scrollY 添加 height:0 修复 flex 高度分配 - 健康页:useReachBottom(页面级)替换为 ScrollView onScrollToLower,修复模拟器卡死 - RichArticle:新增 18 条 tag-style 规则(h1-h4/p/ul/ol/li/table/th/td 等),确保文章内容在小程序中正确渲染样式
55 lines
2.0 KiB
TypeScript
55 lines
2.0 KiB
TypeScript
import { memo, useMemo } from 'react';
|
|
import { View } from '@tarojs/components';
|
|
import { sanitizeHtml } from '@/utils/sanitize-html';
|
|
|
|
interface RichArticleProps {
|
|
html: string;
|
|
className?: string;
|
|
}
|
|
|
|
const TAG_STYLE = JSON.stringify({
|
|
h1: 'font-size:20px;font-weight:700;color:#2D2A26;margin:16px 0 8px',
|
|
h2: 'font-size:18px;font-weight:700;color:#2D2A26;margin:16px 0 8px',
|
|
h3: 'font-size:16px;font-weight:700;color:#2D2A26;margin:16px 0 8px',
|
|
h4: 'font-size:15px;font-weight:600;color:#2D2A26;margin:12px 0 6px',
|
|
p: 'font-size:16px;color:#2D2A26;line-height:1.85;margin-bottom:12px',
|
|
ul: 'padding-left:20px;margin:8px 0;font-size:16px;line-height:1.9;color:#2D2A26',
|
|
ol: 'padding-left:20px;margin:8px 0;font-size:16px;line-height:1.9;color:#2D2A26',
|
|
li: 'margin-bottom:4px',
|
|
blockquote: 'border-left:3px solid #C4623A;padding:6px 12px;color:#5A554F;margin:12px 0',
|
|
strong: 'font-weight:700;color:#2D2A26',
|
|
em: 'font-style:italic',
|
|
code: 'background:#F5F0EB;padding:2px 6px;border-radius:4px;font-size:14px;color:#C4623A',
|
|
pre: 'background:#F5F0EB;padding:12px;border-radius:8px;margin:14px 0;overflow-x:auto',
|
|
table: 'width:100%;border-collapse:collapse;margin:8px 0;font-size:14px',
|
|
th: 'border:1px solid #E8E2DC;padding:6px 8px;background:#FAF8F5;font-weight:600;text-align:left',
|
|
td: 'border:1px solid #E8E2DC;padding:6px 8px',
|
|
hr: 'border:none;border-top:1px dashed #D1D5DB;margin:14px 0',
|
|
img: 'max-width:100%;border-radius:8px;margin:8px 0;display:block',
|
|
a: 'color:#C4623A;text-decoration:none',
|
|
});
|
|
|
|
function prepareHtml(raw: string): string {
|
|
return sanitizeHtml(raw);
|
|
}
|
|
|
|
function RichArticle({ html, className }: RichArticleProps) {
|
|
const content = useMemo(() => prepareHtml(html), [html]);
|
|
|
|
if (!content) return null;
|
|
|
|
return (
|
|
<View className={className}>
|
|
<mp-html
|
|
content={content}
|
|
lazy-load
|
|
selectable
|
|
container-style="font-size:16px;color:#5A554F;line-height:1.8;word-break:break-word"
|
|
tag-style={TAG_STYLE}
|
|
/>
|
|
</View>
|
|
);
|
|
}
|
|
|
|
export default memo(RichArticle);
|