feat(miniapp): SERS 教程入口与季节性防控提醒展示

This commit is contained in:
weijuesen
2026-08-12 15:52:52 +08:00
parent a5caa480c1
commit 62fbbaf917
3 changed files with 82 additions and 16 deletions
@@ -130,6 +130,47 @@
margin-top: 4rpx;
}
.seasonCard {
background: linear-gradient(135deg, $color-primary 0%, $color-primary-dark 100%);
border-radius: $radius-lg;
padding: $spacing-lg;
box-shadow: $shadow-card;
margin-bottom: $spacing-md;
}
.seasonHeader {
display: flex;
align-items: center;
gap: $spacing-sm;
margin-bottom: $spacing-sm;
}
.seasonBadge {
font-size: $font-size-xs;
color: $color-primary;
background: rgba(255, 255, 255, 0.9);
padding: 4rpx $spacing-sm;
border-radius: $radius-round;
flex-shrink: 0;
}
.seasonTitle {
font-size: $font-size-lg;
font-weight: $font-weight-semibold;
color: $color-text-white;
flex: 1;
min-width: 0;
}
.seasonContent {
display: block;
font-size: $font-size-sm;
color: rgba(255, 255, 255, 0.95);
line-height: $line-height-loose;
white-space: pre-wrap;
word-break: break-all;
}
.diseaseList {
display: flex;
flex-direction: column;
+39 -16
View File
@@ -5,6 +5,8 @@ import styles from './index.module.scss';
import {
listAIGuides,
listLAMPGuides,
listSERSGuides,
listSeasonalTips,
listDiseases,
getStageHints,
type Disease,
@@ -15,6 +17,7 @@ import {
const GUIDE_LABELS: Record<string, string> = {
ai_guide: 'AI 解读',
lamp_guide: 'LAMP 教程',
sers_guide: 'SERS 教程',
};
const STAGE_OPTIONS = [
@@ -24,6 +27,14 @@ const STAGE_OPTIONS = [
{ key: 'pupa', label: '蛹期' },
];
const currentSeason = (() => {
const m = new Date().getMonth() + 1;
if (m >= 3 && m <= 5) return '春季';
if (m >= 6 && m <= 8) return '夏季';
if (m >= 9 && m <= 11) return '秋季';
return '冬季';
})();
const CATEGORY_LABELS: Record<string, string> = {
viral: '病毒性',
fungal: '真菌性',
@@ -35,7 +46,7 @@ const CATEGORY_LABELS: Record<string, string> = {
const KnowledgePage: React.FC = () => {
const [diseases, setDiseases] = useState<Disease[]>([]);
const [guides, setGuides] = useState<KnowledgeArticle[]>([]);
const [lampGuides, setLampGuides] = useState<KnowledgeArticle[]>([]);
const [seasonalTips, setSeasonalTips] = useState<KnowledgeArticle[]>([]);
const [stage, setStage] = useState('young');
const [stageHints, setStageHints] = useState<StageHint[]>([]);
const [loading, setLoading] = useState(true);
@@ -53,14 +64,16 @@ const KnowledgePage: React.FC = () => {
const fetchData = useCallback(async () => {
try {
const [diseaseRes, guideRes, lampRes] = await Promise.all([
const [diseaseRes, guideRes, lampRes, sersRes, seasonalRes] = await Promise.all([
listDiseases().catch(() => [] as Disease[]),
listAIGuides().catch(() => [] as KnowledgeArticle[]),
listLAMPGuides().catch(() => [] as KnowledgeArticle[]),
listSERSGuides().catch(() => [] as KnowledgeArticle[]),
listSeasonalTips().catch(() => [] as KnowledgeArticle[]),
]);
setDiseases(diseaseRes);
setGuides(guideRes);
setLampGuides(lampRes);
setGuides([...guideRes, ...lampRes, ...sersRes]);
setSeasonalTips(seasonalRes);
} catch (err) {
console.error('[Knowledge] 数据加载失败:', err);
Taro.showToast({
@@ -85,7 +98,7 @@ const KnowledgePage: React.FC = () => {
});
const openGuide = (a: KnowledgeArticle) => {
Taro.navigateTo({ url: `/pages/knowledge/detail/index?kind=ai_guide&id=${a.id}` });
Taro.navigateTo({ url: `/pages/knowledge/detail/index?kind=article&id=${a.id}` });
};
const openDisease = (d: Disease) => {
@@ -105,17 +118,6 @@ const KnowledgePage: React.FC = () => {
</View>
))}
{lampGuides.map((a) => (
<View key={a.id} className={styles.guideCard} onClick={() => openGuide(a)}>
<View className={styles.guideHeader}>
<Text className={styles.guideBadge}>{GUIDE_LABELS[a.kind] || a.kind}</Text>
<Text className={styles.guideArrow}></Text>
</View>
<Text className={styles.guideTitle}>{a.title}</Text>
{a.summary ? <Text className={styles.guideSummary}>{a.summary}</Text> : null}
</View>
))}
<Text className={styles.sectionTitle}></Text>
<View className={styles.stageChips}>
{STAGE_OPTIONS.map((opt) => (
@@ -153,6 +155,27 @@ const KnowledgePage: React.FC = () => {
))
)}
<Text className={styles.sectionTitle}></Text>
{seasonalTips
.filter((t) => t.title.startsWith(currentSeason))
.map((t) => (
<View key={t.id} className={styles.seasonCard} onClick={() => openGuide(t)}>
<View className={styles.seasonHeader}>
<Text className={styles.seasonBadge}> {currentSeason}</Text>
<Text className={styles.seasonTitle}>{t.title}</Text>
</View>
<Text className={styles.seasonContent}>{t.content}</Text>
</View>
))}
<View className={styles.diseaseList}>
{seasonalTips.map((t) => (
<View key={t.id} className={styles.guideCard} onClick={() => openGuide(t)}>
<Text className={styles.guideTitle}>{t.title}</Text>
{t.summary ? <Text className={styles.guideSummary}>{t.summary}</Text> : null}
</View>
))}
</View>
<Text className={styles.sectionTitle}></Text>
<View className={styles.diseaseList}>
{diseases.map((d) => (