import { View, Text } from '@tarojs/components';
import Taro from '@tarojs/taro';
import { safeNavigateTo } from '@/utils/navigate';
import { useAuthStore } from '../../stores/auth';
import { useElderClass } from '../../hooks/useElderClass';
import GuestGuard from '../../components/GuestGuard';
import Loading from '../../components/Loading';
import PageShell from '@/components/ui/PageShell';
import ContentCard from '@/components/ui/ContentCard';
import SegmentTabs from '../../components/SegmentTabs';
import { useHealthOverview, VITAL_TABS, type VitalType } from './useHealthOverview';
import { submitSuggestionFeedback } from '../../services/ai-analysis';
import './index.scss';
const QUICK_ENTRIES = [
{ label: '录入体征', icon: '✏', color: 'input', path: '/pages/pkg-health/input/index' },
{ label: '健康趋势', icon: '📈', color: 'trend', path: '/pages/pkg-health/trend/index' },
{ label: '我的报告', icon: '📋', color: 'report', path: '/pages/pkg-profile/reports/index' },
{ label: '健康档案', icon: '健', color: 'med', path: '/pages/pkg-profile/health-records/index' },
] as const;
function statusClass(status?: string): string {
if (!status) return '';
if (status === 'high' || status === 'abnormal') return 'vital-warn';
if (status === 'low') return 'vital-warn';
return 'vital-ok';
}
function formatDate(): string {
const d = new Date();
const month = d.getMonth() + 1;
const day = d.getDate();
const weekDays = ['日', '一', '二', '三', '四', '五', '六'];
return `${month}月${day}日 周${weekDays[d.getDay()]}`;
}
export default function Health() {
const user = useAuthStore((s) => s.user);
const modeClass = useElderClass();
const {
todaySummary, loading, error, activeTab, trendData, trendLoading,
aiSuggestions, thresholds, alertCount, handleTabChange, fetchData,
} = useHealthOverview();
if (!user) {
return ;
}
if (error) {
return (
健康总览
);
}
const maxTrendValue = trendData.reduce((max, d) => Math.max(max, d.value), 1);
const dayLabels = ['日', '一', '二', '三', '四', '五', '六'];
const summary = todaySummary || {};
const vitals = [
{ label: '血压', value: summary.blood_pressure ? `${summary.blood_pressure.systolic}/${summary.blood_pressure.diastolic}` : '—', unit: 'mmHg', status: summary.blood_pressure?.status },
{ label: '心率', value: summary.heart_rate ? `${summary.heart_rate.value}` : '—', unit: 'bpm', status: summary.heart_rate?.status },
{ label: '血糖', value: summary.blood_sugar ? `${summary.blood_sugar.value}` : '—', unit: 'mmol/L', status: summary.blood_sugar?.status },
{ label: '体重', value: summary.weight ? `${summary.weight.value}` : '—', unit: 'kg', status: summary.weight?.status },
];
const recordedCount = vitals.filter((v) => v.value !== '—').length;
const getThresholdValue = (type: VitalType): number | null => {
if (!thresholds.length) return null;
const th = thresholds;
if (type === 'blood_pressure') {
const v = th.find((t) => t.indicator === 'systolic_bp' && t.level === 'high');
return v?.threshold_value ?? 140;
}
if (type === 'heart_rate') {
const v = th.find((t) => t.indicator === 'heart_rate' && t.level === 'high');
return v?.threshold_value ?? 100;
}
if (type === 'blood_sugar') {
const v = th.find((t) => t.indicator === 'blood_sugar_fasting' && t.level === 'high');
return v?.threshold_value ?? 6.1;
}
return null;
};
return (
健康总览
{formatDate()}
{/* 今日体征 hero 卡片 */}
今日体征
{recordedCount > 0 && (
已记录 {recordedCount} 项
)}
{loading ? : (
{vitals.map((v) => (
{v.value}
{v.unit}
{v.label}
))}
)}
{/* 快捷入口 — 横排 4 格图标 */}
{QUICK_ENTRIES.map((e) => (
safeNavigateTo(e.path)}
>
{e.icon}
{e.label}
))}
{/* 告警横幅 */}
{alertCount > 0 && (
safeNavigateTo('/pages/pkg-health/alerts/index')}
>
{alertCount} 条待处理告警
›
)}
{/* AI 建议 */}
{aiSuggestions.length > 0 && (
AI 健康建议
{aiSuggestions.length} 条
{aiSuggestions.map((s) => {
const riskCls = s.risk_level === 'high' ? 'ai-risk-high' : s.risk_level === 'medium' ? 'ai-risk-medium' : 'ai-risk-low';
const params = s.params as Record | null;
const reason = (params?.reason as string) || (params?.message as string) || '健康建议';
return (
{
if (s.suggestion_type === 'appointment') safeNavigateTo('/pages/appointment/create/index');
else if (s.suggestion_type === 'followup') safeNavigateTo('/pages/pkg-profile/followups/index');
}}>
{reason.slice(0, 50)}
{
try { await submitSuggestionFeedback(s.id, 'adopt'); Taro.showToast({ title: '已采纳', icon: 'success' }); fetchData(); }
catch { Taro.showToast({ title: '操作失败', icon: 'none' }); }
}}>
采纳
{
try { await submitSuggestionFeedback(s.id, 'ignore'); Taro.showToast({ title: '已忽略', icon: 'success' }); fetchData(); }
catch { Taro.showToast({ title: '操作失败', icon: 'none' }); }
}}>
忽略
{
try { await submitSuggestionFeedback(s.id, 'consult'); safeNavigateTo('/pages/consultation/index'); }
catch { Taro.showToast({ title: '操作失败', icon: 'none' }); }
}}>
咨询医生
);
})}
)}
{/* 7天趋势 */}
近 7 天趋势
{trendLoading ? : trendData.length === 0 ? (
暂无趋势数据
) : (
{(() => {
const tv = getThresholdValue(activeTab);
if (tv) {
const pct = Math.min(95, (tv / maxTrendValue) * 100);
return (
{tv}
);
}
return null;
})()}
{trendData.map((point, i) => {
const heightPct = Math.max(8, (point.value / maxTrendValue) * 100);
const tv = getThresholdValue(activeTab);
const isAbnormal = tv ? point.value >= tv : false;
const dayOfWeek = new Date(point.date).getDay();
return (
{dayLabels[dayOfWeek]}
);
})}
)}
{/* 健康资讯入口 */}
safeNavigateTo('/pages/article/index')}>
最新健康资讯 ›
);
}