feat(miniapp): SERS 教程入口与季节性防控提醒展示
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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) => (
|
||||
|
||||
Reference in New Issue
Block a user