diff --git a/apps/miniprogram/src/pages/health/index.scss b/apps/miniprogram/src/pages/health/index.scss index eabf5f9..7e0a0bb 100644 --- a/apps/miniprogram/src/pages/health/index.scss +++ b/apps/miniprogram/src/pages/health/index.scss @@ -300,3 +300,50 @@ color: $tx; font-weight: 500; } + +/* ─── AI 建议卡片 ─── */ +.ai-suggestion-card { + background: $card; + border-radius: $r; + padding: 16px; + margin-bottom: 16px; + box-shadow: $shadow-sm; + border-left: 4px solid $pri; +} + +.ai-card-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 10px; +} + +.ai-card-title { + font-size: 15px; + font-weight: 600; + color: $tx; +} + +.ai-card-count { + font-size: 12px; + color: $acc; +} + +.ai-suggestion-item { + display: flex; + align-items: center; + gap: 8px; + padding: 6px 0; +} + +.ai-risk-dot { + width: 8px; + height: 8px; + border-radius: 50%; + flex-shrink: 0; +} + +.ai-suggestion-text { + font-size: 13px; + color: $tx2; +} diff --git a/apps/miniprogram/src/pages/health/index.tsx b/apps/miniprogram/src/pages/health/index.tsx index b3fbd2f..460719f 100644 --- a/apps/miniprogram/src/pages/health/index.tsx +++ b/apps/miniprogram/src/pages/health/index.tsx @@ -1,9 +1,10 @@ -import { useState } from 'react'; +import { useState, useEffect } from 'react'; import { View, Text, Input } from '@tarojs/components'; import Taro, { useDidShow } from '@tarojs/taro'; import { useHealthStore } from '../../stores/health'; import { useAuthStore } from '../../stores/auth'; import { inputVitalSign, getTrend } from '../../services/health'; +import { listPendingSuggestions, type AiSuggestionItem } from '../../services/ai-analysis'; import Loading from '../../components/Loading'; import './index.scss'; @@ -41,12 +42,23 @@ export default function Health() { const [saving, setSaving] = useState(false); const [trendData, setTrendData] = useState([]); const [trendLoading, setTrendLoading] = useState(false); + const [aiSuggestions, setAiSuggestions] = useState([]); useDidShow(() => { refreshToday(); loadTrend(activeTab); + loadAiSuggestions(); }); + const loadAiSuggestions = async () => { + try { + const items = await listPendingSuggestions(); + setAiSuggestions(items.slice(0, 3)); + } catch { + // 静默 + } + }; + const loadTrend = async (type: VitalType) => { setTrendLoading(true); try { @@ -162,6 +174,28 @@ export default function Health() { 健康数据 + {/* AI 建议卡片 */} + {aiSuggestions.length > 0 && ( + Taro.navigateTo({ url: '/pages/pkg-profile/settings/index' })}> + + AI 健康建议 + {aiSuggestions.length} 条待查看 + + {aiSuggestions.map((s) => { + const riskColor = s.risk_level === 'high' ? '#ef4444' : s.risk_level === 'medium' ? '#f59e0b' : '#22c55e'; + const typeLabel = s.suggestion_type === 'followup' ? '随访' : s.suggestion_type === 'appointment' ? '预约' : '预警'; + const params = s.params as Record | null; + const reason = (params?.reason as string) || (params?.message as string) || typeLabel; + return ( + + + {reason.slice(0, 40)} + + ); + })} + + )} + {/* 类型 Tab */} {VITAL_TABS.map((tab) => { diff --git a/apps/miniprogram/src/services/ai-analysis.ts b/apps/miniprogram/src/services/ai-analysis.ts index 73f3c81..b4c0125 100644 --- a/apps/miniprogram/src/services/ai-analysis.ts +++ b/apps/miniprogram/src/services/ai-analysis.ts @@ -22,3 +22,21 @@ export async function listAiAnalysis(page = 1, pageSize = 20) { export async function getAiAnalysisDetail(id: string) { return api.get(`/ai/analysis/${id}`); } + +export interface AiSuggestionItem { + id: string; + analysis_id: string; + suggestion_type: string; + risk_level: string; + params: Record | null; + status: string; + created_at: string; +} + +export async function listPendingSuggestions() { + const resp = await api.get<{ data: AiSuggestionItem[]; total: number }>( + '/ai/suggestions', + { status: 'pending' }, + ); + return resp.data || []; +}