<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>慢病健康管理系统 · ChronicCare</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.4.1/chart.umd.min.js"></script>
<link href="https://fonts.googleapis.com/css2?family=Lora:wght@400;600;700&family=Noto+Sans+SC:wght@300;400;500;600&display=swap" rel="stylesheet">
<style>
:root{
  --sage:#2d6a4f;--sage-mid:#40916c;--sage-light:#74c69d;--sage-pale:#d8f3dc;
  --mint:#b7e4c7;--white:#ffffff;--off:#f8faf9;
  --stone:#1b2d27;--stone-mid:#354f47;--stone-light:#5c7a6e;
  --text:#1e3a32;--text-mid:#4a6b60;--text-light:#7a9e94;--text-faint:#afc8bf;
  --border:#ddeee6;--border-strong:#b7d9c8;
  --amber:#e76f00;--amber-pale:#fff3e0;
  --rose:#c0392b;--rose-pale:#fdecea;
  --sky:#1565c0;--sky-pale:#e3f2fd;
  --gold:#b8860b;--gold-pale:#fffde7;
  --shadow:0 2px 20px rgba(45,106,79,.09);
  --shadow-lg:0 8px 40px rgba(45,106,79,.14);
  --r:12px;
  --sidebar:230px;
  --header:58px;
}
*{box-sizing:border-box;margin:0;padding:0;}
html,body{height:100%;font-family:'Noto Sans SC',sans-serif;background:var(--off);color:var(--text);font-size:14px;}

/* ── LAYOUT ── */
.app{display:flex;height:100vh;overflow:hidden;}

/* ── SIDEBAR ── */
.sidebar{
  width:var(--sidebar);min-width:var(--sidebar);
  background:var(--stone);
  display:flex;flex-direction:column;overflow:hidden;
}
.brand{
  padding:18px 16px 14px;
  border-bottom:1px solid rgba(255,255,255,.07);
}
.brand-row{display:flex;align-items:center;gap:10px;}
.brand-icon{
  width:36px;height:36px;border-radius:10px;
  background:linear-gradient(135deg,var(--sage-light),var(--sage-mid));
  display:flex;align-items:center;justify-content:center;
  font-size:18px;flex-shrink:0;
}
.brand-title{font-family:'Lora',serif;font-size:16px;font-weight:700;color:#fff;line-height:1.1;}
.brand-sub{font-size:10px;color:rgba(255,255,255,.4);letter-spacing:1px;margin-top:2px;}

.nav{flex:1;padding:10px 10px;overflow-y:auto;}
.nav::-webkit-scrollbar{width:0;}
.nav-group{margin-bottom:18px;}
.nav-group-label{font-size:10px;color:rgba(255,255,255,.3);letter-spacing:1.5px;text-transform:uppercase;padding:0 8px;margin-bottom:6px;}
.nav-item{
  display:flex;align-items:center;gap:9px;
  padding:8px 10px;border-radius:8px;
  cursor:pointer;color:rgba(255,255,255,.55);
  font-size:13px;transition:all .15s;margin-bottom:1px;
}
.nav-item:hover{background:rgba(255,255,255,.07);color:rgba(255,255,255,.85);}
.nav-item.active{background:rgba(116,198,157,.18);color:var(--sage-light);}
.nav-item .ni{font-size:15px;width:20px;text-align:center;flex-shrink:0;}
.nav-badge{margin-left:auto;background:var(--amber);color:#fff;font-size:10px;font-weight:700;padding:1px 6px;border-radius:10px;}

.sidebar-user{
  padding:12px 14px;border-top:1px solid rgba(255,255,255,.07);
  display:flex;align-items:center;gap:10px;
}
.su-avatar{
  width:32px;height:32px;border-radius:50%;
  background:linear-gradient(135deg,var(--sage-light),var(--sage));
  display:flex;align-items:center;justify-content:center;
  font-size:13px;font-weight:700;color:#fff;flex-shrink:0;
}
.su-name{font-size:13px;font-weight:500;color:rgba(255,255,255,.85);}
.su-role{font-size:10px;color:rgba(255,255,255,.35);}

/* ── MAIN ── */
.main{flex:1;display:flex;flex-direction:column;overflow:hidden;}
.topbar{
  height:var(--header);min-height:var(--header);
  background:var(--white);border-bottom:1px solid var(--border);
  display:flex;align-items:center;padding:0 24px;gap:16px;
}
.topbar-title{font-family:'Lora',serif;font-size:19px;font-weight:600;color:var(--text);}
.topbar-sub{font-size:12px;color:var(--text-light);margin-top:1px;}
.topbar-right{margin-left:auto;display:flex;align-items:center;gap:10px;}
.live-indicator{display:flex;align-items:center;gap:5px;font-size:11px;color:var(--text-light);}
.live-dot{width:7px;height:7px;border-radius:50%;background:var(--sage-mid);animation:pulse 2s infinite;}
@keyframes pulse{0%,100%{opacity:1;}50%{opacity:.4;}}

.content{flex:1;overflow-y:auto;padding:20px 24px;}
.content::-webkit-scrollbar{width:4px;}
.content::-webkit-scrollbar-thumb{background:var(--border-strong);border-radius:4px;}

.page{display:none;}
.page.active{display:block;animation:rise .2s ease;}
@keyframes rise{from{opacity:0;transform:translateY(5px);}to{opacity:1;transform:none;}}

/* ── BUTTONS ── */
.btn{
  display:inline-flex;align-items:center;gap:6px;
  padding:8px 16px;border:none;border-radius:8px;
  font-family:'Noto Sans SC',sans-serif;
  font-size:13px;font-weight:500;cursor:pointer;transition:all .15s;
}
.btn-primary{background:var(--sage-mid);color:#fff;}
.btn-primary:hover{background:var(--sage);box-shadow:0 4px 12px rgba(64,145,108,.3);}
.btn-outline{background:transparent;color:var(--sage-mid);border:1.5px solid var(--sage-mid);}
.btn-outline:hover{background:var(--sage-pale);}
.btn-ghost{background:var(--off);color:var(--text-mid);border:1px solid var(--border);}
.btn-ghost:hover{border-color:var(--sage-light);color:var(--sage-mid);}
.btn-danger{background:var(--rose-pale);color:var(--rose);border:1px solid #f5b7b1;}
.btn-danger:hover{background:#fad7d4;}
.btn-amber{background:var(--amber-pale);color:var(--amber);border:1px solid #ffd9a0;}
.btn-sm{padding:5px 12px;font-size:12px;}
.btn-xs{padding:3px 8px;font-size:11px;}

/* ── CARDS ── */
.card{
  background:var(--white);border:1px solid var(--border);
  border-radius:var(--r);padding:20px 22px;
  margin-bottom:16px;box-shadow:var(--shadow);
}
.card-hd{
  display:flex;align-items:center;justify-content:space-between;
  margin-bottom:16px;padding-bottom:12px;
  border-bottom:1px solid var(--border);
}
.card-title{font-size:14px;font-weight:600;color:var(--text);display:flex;align-items:center;gap:7px;}
.card-title .ct-icon{font-size:16px;}

/* KPI */
.kpi-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:14px;margin-bottom:16px;}
.kpi{
  background:var(--white);border:1px solid var(--border);
  border-radius:var(--r);padding:16px 18px;
  box-shadow:var(--shadow);position:relative;overflow:hidden;
  transition:transform .2s;
}
.kpi:hover{transform:translateY(-2px);box-shadow:var(--shadow-lg);}
.kpi::after{
  content:'';position:absolute;bottom:0;left:0;right:0;height:3px;
}
.kpi.green::after{background:linear-gradient(90deg,var(--sage-mid),var(--sage-light));}
.kpi.amber::after{background:var(--amber);}
.kpi.rose::after{background:var(--rose);}
.kpi.sky::after{background:var(--sky);}
.kpi-label{font-size:11px;color:var(--text-light);letter-spacing:.5px;margin-bottom:6px;}
.kpi-val{font-family:'Lora',serif;font-size:28px;font-weight:700;color:var(--text);line-height:1;}
.kpi-val span{font-size:13px;color:var(--text-light);font-family:'Noto Sans SC',sans-serif;margin-left:3px;}
.kpi-sub{font-size:11px;color:var(--text-faint);margin-top:4px;}
.kpi-glyph{position:absolute;right:14px;top:12px;font-size:26px;opacity:.1;}

/* PILLS */
.pill{display:inline-flex;align-items:center;gap:4px;padding:2px 9px;border-radius:20px;font-size:11px;font-weight:500;}
.pill-green{background:var(--sage-pale);color:var(--sage);}
.pill-amber{background:var(--amber-pale);color:var(--amber);}
.pill-rose{background:var(--rose-pale);color:var(--rose);}
.pill-sky{background:var(--sky-pale);color:var(--sky);}
.pill-gold{background:var(--gold-pale);color:var(--gold);}
.pill-gray{background:#f0f4f2;color:var(--text-light);}
.pill-dot{width:5px;height:5px;border-radius:50%;background:currentColor;}

/* TABLE */
.tbl-wrap{overflow-x:auto;}
table{width:100%;border-collapse:collapse;}
thead th{padding:9px 12px;text-align:left;font-size:11px;color:var(--text-light);letter-spacing:.8px;text-transform:uppercase;border-bottom:1.5px solid var(--border);white-space:nowrap;font-weight:500;}
tbody td{padding:11px 12px;border-bottom:1px solid var(--border);color:var(--text);font-size:13px;vertical-align:middle;}
tbody tr:last-child td{border-bottom:none;}
tbody tr:hover td{background:var(--off);}

/* FORMS */
.fg{display:flex;flex-direction:column;gap:5px;}
.fg-grid{display:grid;grid-template-columns:1fr 1fr;gap:12px;}
.fg-grid.c3{grid-template-columns:1fr 1fr 1fr;}
.fg.full{grid-column:1/-1;}
.fg label{font-size:11px;color:var(--text-mid);font-weight:500;letter-spacing:.5px;text-transform:uppercase;}
.fi{
  padding:8px 11px;border:1.5px solid var(--border);border-radius:8px;
  background:var(--off);color:var(--text);
  font-family:'Noto Sans SC',sans-serif;font-size:13px;
  outline:none;transition:border-color .15s,background .15s;
}
.fi:focus{border-color:var(--sage-mid);background:var(--white);}
.fi-select option{background:var(--white);}
.fi-ta{resize:vertical;min-height:72px;}
.form-actions{display:flex;justify-content:flex-end;gap:8px;margin-top:14px;}

/* MODAL */
.overlay{
  display:none;position:fixed;inset:0;
  background:rgba(27,45,39,.5);backdrop-filter:blur(3px);
  z-index:600;align-items:center;justify-content:center;
}
.overlay.show{display:flex;animation:fadeIn .2s;}
@keyframes fadeIn{from{opacity:0;}to{opacity:1;}}
.modal{
  background:var(--white);border:1px solid var(--border);
  border-radius:16px;padding:26px 30px;
  width:90%;max-width:560px;max-height:88vh;overflow-y:auto;
  box-shadow:var(--shadow-lg);
}
.modal-lg{max-width:720px;}
.modal-hd{display:flex;align-items:center;justify-content:space-between;margin-bottom:18px;}
.modal-title{font-family:'Lora',serif;font-size:18px;font-weight:600;color:var(--text);}
.modal-close{background:none;border:none;color:var(--text-light);font-size:20px;cursor:pointer;line-height:1;}
.modal-close:hover{color:var(--text);}

/* PROGRESS */
.prog{height:6px;background:var(--border);border-radius:3px;overflow:hidden;}
.prog-bar{height:100%;border-radius:3px;transition:width .4s;}
.pb-green{background:linear-gradient(90deg,var(--sage-mid),var(--sage-light));}
.pb-amber{background:var(--amber);}
.pb-rose{background:var(--rose);}
.pb-sky{background:var(--sky);}

/* SEARCH */
.search-wrap{
  display:flex;align-items:center;gap:8px;
  background:var(--off);border:1.5px solid var(--border);
  border-radius:8px;padding:7px 12px;flex:1;max-width:280px;
}
.search-wrap input{background:none;border:none;outline:none;color:var(--text);font-family:'Noto Sans SC',sans-serif;font-size:13px;flex:1;}
.search-wrap input::placeholder{color:var(--text-faint);}

/* TABS */
.tabs{display:flex;gap:0;border-bottom:1.5px solid var(--border);margin-bottom:16px;}
.tab{padding:8px 16px;cursor:pointer;font-size:13px;color:var(--text-light);border-bottom:2px solid transparent;margin-bottom:-1.5px;transition:all .15s;}
.tab:hover{color:var(--text);}
.tab.active{color:var(--sage-mid);border-bottom-color:var(--sage-mid);font-weight:500;}

/* TIMELINE */
.tl{padding-left:18px;border-left:2px solid var(--border);}
.tl-item{position:relative;padding:0 0 14px 18px;}
.tl-item::before{content:'';position:absolute;left:-23px;top:5px;width:9px;height:9px;border-radius:50%;background:var(--sage-mid);border:2px solid var(--white);}
.tl-time{font-size:11px;color:var(--text-faint);margin-bottom:2px;}
.tl-title{font-size:13px;font-weight:500;margin-bottom:2px;}
.tl-desc{font-size:12px;color:var(--text-light);}

/* HEALTH CHART BOXES */
.chart-box{position:relative;height:200px;}
.chart-box-lg{position:relative;height:260px;}

/* ALERT */
.alert{
  display:flex;align-items:flex-start;gap:10px;
  padding:11px 14px;border-radius:9px;margin-bottom:10px;
}
.alert-rose{background:var(--rose-pale);border:1px solid #f5c6c6;}
.alert-amber{background:var(--amber-pale);border:1px solid #ffd9a0;}
.alert-green{background:var(--sage-pale);border:1px solid var(--mint);}
.alert-sky{background:var(--sky-pale);border:1px solid #90caf9;}
.alert-icon{font-size:16px;flex-shrink:0;margin-top:1px;}
.alert-body{flex:1;}
.alert-title{font-size:13px;font-weight:600;margin-bottom:2px;}
.alert-desc{font-size:12px;color:var(--text-mid);}

/* MEDICINE CARDS */
.med-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:12px;}
.med-card{
  background:var(--off);border:1.5px solid var(--border);
  border-radius:10px;padding:14px 16px;
  transition:border-color .15s,transform .15s;
}
.med-card:hover{border-color:var(--sage-light);transform:translateY(-1px);}
.med-card.taken{border-color:var(--sage-light);background:var(--sage-pale);}
.med-card.missed{border-color:#f5c6c6;background:var(--rose-pale);}
.med-name{font-size:14px;font-weight:600;margin-bottom:4px;}
.med-dose{font-size:12px;color:var(--text-mid);}
.med-time{font-size:11px;color:var(--text-faint);margin-top:2px;}
.med-actions{margin-top:10px;display:flex;gap:6px;}

/* DRAWER */
.drawer{
  position:fixed;right:-500px;top:0;bottom:0;width:480px;
  background:var(--white);border-left:1px solid var(--border);
  z-index:500;transition:right .3s cubic-bezier(.4,0,.2,1);
  display:flex;flex-direction:column;box-shadow:var(--shadow-lg);
}
.drawer.open{right:0;}
.drawer-hd{padding:18px 22px;border-bottom:1px solid var(--border);display:flex;align-items:center;justify-content:space-between;}
.drawer-body{flex:1;overflow-y:auto;padding:18px 22px;}
.drawer-body::-webkit-scrollbar{width:3px;}
.drawer-body::-webkit-scrollbar-thumb{background:var(--border-strong);}
.drawer-footer{padding:14px 22px;border-top:1px solid var(--border);display:flex;gap:8px;}

/* EDUCATION CARDS */
.edu-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:14px;}
.edu-card{
  background:var(--white);border:1px solid var(--border);
  border-radius:var(--r);overflow:hidden;cursor:pointer;
  transition:transform .2s,box-shadow .2s;
  box-shadow:var(--shadow);
}
.edu-card:hover{transform:translateY(-3px);box-shadow:var(--shadow-lg);}
.edu-banner{height:80px;display:flex;align-items:center;justify-content:center;font-size:36px;}
.edu-body{padding:14px 16px;}
.edu-tag{font-size:10px;letter-spacing:.8px;text-transform:uppercase;font-weight:600;margin-bottom:6px;}
.edu-title{font-size:14px;font-weight:600;margin-bottom:6px;color:var(--text);}
.edu-desc{font-size:12px;color:var(--text-mid);line-height:1.6;}
.edu-footer{padding:10px 16px;border-top:1px solid var(--border);display:flex;align-items:center;justify-content:space-between;}

/* TOAST */
.toast-wrap{position:fixed;bottom:22px;right:22px;z-index:9999;display:flex;flex-direction:column;gap:8px;}
.toast{
  background:var(--white);border:1px solid var(--border);border-radius:10px;
  padding:11px 16px;display:flex;align-items:center;gap:10px;
  box-shadow:0 8px 30px rgba(0,0,0,.12);animation:slideUp .3s ease;
  font-size:13px;min-width:220px;max-width:320px;
}
@keyframes slideUp{from{opacity:0;transform:translateY(10px);}to{opacity:1;transform:none;}}
.toast.success{border-left:3px solid var(--sage-mid);}
.toast.error{border-left:3px solid var(--rose);}
.toast.info{border-left:3px solid var(--sky);}
.toast.warning{border-left:3px solid var(--amber);}

/* VITAL SIGN CARDS */
.vital-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:12px;}
.vital-card{
  background:var(--off);border:1.5px solid var(--border);
  border-radius:10px;padding:14px 16px;
}
.vital-label{font-size:11px;color:var(--text-light);letter-spacing:.5px;margin-bottom:6px;}
.vital-val{font-family:'Lora',serif;font-size:24px;font-weight:700;color:var(--text);}
.vital-unit{font-size:12px;color:var(--text-light);font-family:'Noto Sans SC',sans-serif;margin-left:3px;}
.vital-status{font-size:11px;margin-top:4px;}
.vital-normal{color:var(--sage-mid);}
.vital-high{color:var(--rose);}
.vital-low{color:var(--amber);}

/* EMPTY */
.empty{text-align:center;padding:36px 20px;color:var(--text-faint);}
.empty-icon{font-size:36px;margin-bottom:8px;opacity:.4;}
.empty-text{font-size:13px;}

/* EXPORT GRID */
.export-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:12px;margin-top:14px;}
.exp-card{
  background:var(--off);border:1.5px solid var(--border);
  border-radius:10px;padding:18px;cursor:pointer;
  text-align:center;transition:all .2s;
}
.exp-card:hover{border-color:var(--sage-mid);transform:translateY(-2px);background:var(--sage-pale);}
.exp-icon{font-size:30px;margin-bottom:8px;}
.exp-name{font-size:14px;font-weight:600;color:var(--text);margin-bottom:3px;}
.exp-desc{font-size:11px;color:var(--text-light);}

/* SECTION DIVIDER */
.sec{display:flex;align-items:center;justify-content:space-between;margin:0 0 12px;}
.sec-label{font-size:12px;font-weight:600;color:var(--text-light);text-transform:uppercase;letter-spacing:.8px;}

/* HEALTH SCORE RING */
.score-wrap{text-align:center;padding:8px 0;}
.score-big{font-family:'Lora',serif;font-size:52px;font-weight:700;color:var(--sage-mid);line-height:1;}
.score-label{font-size:12px;color:var(--text-light);margin-top:4px;}

/* RESPONSIVE */
@media(max-width:900px){
  .kpi-grid{grid-template-columns:repeat(2,1fr);}
  .edu-grid{grid-template-columns:repeat(2,1fr);}
  .med-grid{grid-template-columns:1fr 1fr;}
  .fg-grid,.fg-grid.c3{grid-template-columns:1fr;}
}
</style>
</head>
<body>
<div class="app">

<!-- ══════════════ SIDEBAR ══════════════ -->
<aside class="sidebar">
  <div class="brand">
    <div class="brand-row">
      <div class="brand-icon">🌿</div>
      <div>
        <div class="brand-title">ChronicCare</div>
        <div class="brand-sub">慢病管理系统</div>
      </div>
    </div>
  </div>
  <nav class="nav">
    <div class="nav-group">
      <div class="nav-group-label">核心功能</div>
      <div class="nav-item active" onclick="nav(this,'dashboard')"><span class="ni">🏠</span>健康总览</div>
      <div class="nav-item" onclick="nav(this,'patients')"><span class="ni">👥</span>患者档案</div>
      <div class="nav-item" onclick="nav(this,'vitals')"><span class="ni">📊</span>健康监测</div>
      <div class="nav-item" onclick="nav(this,'medicine')"><span class="ni">💊</span>用药管理<span class="nav-badge">3</span></div>
      <div class="nav-item" onclick="nav(this,'followup')"><span class="ni">📅</span>远程随访<span class="nav-badge">5</span></div>
    </div>
    <div class="nav-group">
      <div class="nav-group-label">工具</div>
      <div class="nav-item" onclick="nav(this,'alerts')"><span class="ni">🔔</span>异常提醒<span class="nav-badge" id="alert-badge">4</span></div>
      <div class="nav-item" onclick="nav(this,'education')"><span class="ni">📚</span>健康教育</div>
      <div class="nav-item" onclick="nav(this,'reports')"><span class="ni">📤</span>报表导出</div>
      <div class="nav-item" onclick="nav(this,'settings')"><span class="ni">⚙️</span>系统设置</div>
    </div>
  </nav>
  <div class="sidebar-user">
    <div class="su-avatar">王</div>
    <div>
      <div class="su-name">王医生</div>
      <div class="su-role">主治医师 · 心内科</div>
    </div>
  </div>
</aside>

<!-- ══════════════ MAIN ══════════════ -->
<div class="main">
  <div class="topbar">
    <div>
      <div class="topbar-title" id="tb-title">健康总览</div>
      <div class="topbar-sub" id="tb-sub">今日共有 8 项待处理事项</div>
    </div>
    <div class="topbar-right">
      <div class="live-indicator">
        <div class="live-dot"></div><span>实时监控中</span>
      </div>
      <button class="btn btn-ghost btn-sm" onclick="openModal('modal-addpt')">＋ 新增患者</button>
      <button class="btn btn-primary btn-sm" onclick="openModal('modal-addvital')">📥 录入指标</button>
    </div>
  </div>

  <div class="content">

    <!-- ════ DASHBOARD ════ -->
    <div class="page active" id="page-dashboard">
      <div class="kpi-grid">
        <div class="kpi green">
          <div class="kpi-label">在管患者</div>
          <div class="kpi-val">1,147<span>人</span></div>
          <div class="kpi-sub">↑ 本月新增 31 人</div>
          <div class="kpi-glyph">👥</div>
        </div>
        <div class="kpi amber">
          <div class="kpi-label">今日提醒</div>
          <div class="kpi-val">48<span>条</span></div>
          <div class="kpi-sub">用药+随访提醒</div>
          <div class="kpi-glyph">🔔</div>
        </div>
        <div class="kpi rose">
          <div class="kpi-label">异常预警</div>
          <div class="kpi-val">4<span>项</span></div>
          <div class="kpi-sub">需立即关注</div>
          <div class="kpi-glyph">⚠️</div>
        </div>
        <div class="kpi sky">
          <div class="kpi-label">随访完成率</div>
          <div class="kpi-val">89<span>%</span></div>
          <div class="kpi-sub">本月 312 次</div>
          <div class="kpi-glyph">📅</div>
        </div>
      </div>

      <!-- Alerts -->
      <div class="card">
        <div class="card-hd">
          <div class="card-title"><span class="ct-icon">⚠️</span>今日异常预警</div>
          <button class="btn btn-ghost btn-sm" onclick="nav(document.querySelector('[onclick*=alerts]'),'alerts')">查看全部</button>
        </div>
        <div class="alert alert-rose">
          <div class="alert-icon">🔴</div>
          <div class="alert-body">
            <div class="alert-title">张伟民 – 血糖严重偏高</div>
            <div class="alert-desc">空腹血糖 14.2 mmol/L（正常范围 3.9–6.1），需紧急处置</div>
          </div>
          <button class="btn btn-danger btn-sm" onclick="openDrawer('P1001')">查看</button>
        </div>
        <div class="alert alert-rose">
          <div class="alert-icon">🔴</div>
          <div class="alert-body">
            <div class="alert-title">李秀英 – 血压危急值</div>
            <div class="alert-desc">收缩压 182 mmHg，超出安全阈值，请立即联系患者</div>
          </div>
          <button class="btn btn-danger btn-sm" onclick="openDrawer('P1002')">查看</button>
        </div>
        <div class="alert alert-amber">
          <div class="alert-icon">🟡</div>
          <div class="alert-body">
            <div class="alert-title">王建国 – 用药依从性下降</div>
            <div class="alert-desc">连续 3 天漏服降压药，本周依从率 57%</div>
          </div>
          <button class="btn btn-amber btn-sm" onclick="openDrawer('P1003')">提醒</button>
        </div>
        <div class="alert alert-amber">
          <div class="alert-icon">🟡</div>
          <div class="alert-body">
            <div class="alert-title">刘 静 – 体重异常增加</div>
            <div class="alert-desc">本月体重增加 4.2kg，心衰患者需警惕水肿</div>
          </div>
          <button class="btn btn-amber btn-sm">提醒</button>
        </div>
      </div>

      <div style="display:grid;grid-template-columns:3fr 2fr;gap:16px;">
        <div class="card">
          <div class="card-hd">
            <div class="card-title"><span class="ct-icon">📈</span>血糖 / 血压趋势（近7天）</div>
            <div style="display:flex;gap:8px;">
              <span class="pill pill-green">血糖</span>
              <span class="pill pill-sky">血压</span>
            </div>
          </div>
          <div class="chart-box-lg"><canvas id="dashTrendChart"></canvas></div>
        </div>
        <div class="card">
          <div class="card-hd">
            <div class="card-title"><span class="ct-icon">🥧</span>疾病类型分布</div>
          </div>
          <div class="chart-box-lg"><canvas id="diseaseChart"></canvas></div>
        </div>
      </div>

      <div style="display:grid;grid-template-columns:1fr 1fr;gap:16px;">
        <div class="card">
          <div class="card-hd">
            <div class="card-title"><span class="ct-icon">💊</span>今日用药提醒</div>
            <span class="pill pill-amber">待服 3 人</span>
          </div>
          <div id="dash-meds"></div>
        </div>
        <div class="card">
          <div class="card-hd">
            <div class="card-title"><span class="ct-icon">🕐</span>近期随访记录</div>
          </div>
          <div class="tl" id="dash-timeline"></div>
        </div>
      </div>
    </div>

    <!-- ════ PATIENTS ════ -->
    <div class="page" id="page-patients">
      <div class="card" style="padding:14px 18px;margin-bottom:14px;">
        <div style="display:flex;align-items:center;gap:10px;flex-wrap:wrap;">
          <div class="search-wrap"><span>🔍</span><input id="pt-search" type="text" placeholder="搜索患者姓名、ID、诊断…" oninput="filterPt()"></div>
          <select class="fi fi-select" style="width:130px;" id="pt-fs" onchange="filterPt()">
            <option value="">全部疾病</option>
            <option>糖尿病</option><option>高血压</option><option>冠心病</option><option>慢阻肺</option><option>慢性肾病</option>
          </select>
          <select class="fi fi-select" style="width:120px;" id="pt-fst" onchange="filterPt()">
            <option value="">全部状态</option>
            <option>管理中</option><option>待随访</option><option>病情稳定</option><option>病情恶化</option>
          </select>
          <button class="btn btn-primary btn-sm" onclick="openModal('modal-addpt')">＋ 新增患者</button>
          <button class="btn btn-ghost btn-sm" onclick="exportData('patients')">📤 导出</button>
        </div>
      </div>
      <div class="card">
        <div class="tbl-wrap">
          <table>
            <thead><tr><th>ID</th><th>姓名</th><th>年龄/性别</th><th>主要诊断</th><th>健康评分</th><th>用药状态</th><th>状态</th><th>最后随访</th><th>操作</th></tr></thead>
            <tbody id="pt-tbody"></tbody>
          </table>
          <div class="empty" id="pt-empty" style="display:none;"><div class="empty-icon">👥</div><div class="empty-text">未找到匹配患者</div></div>
        </div>
        <div style="display:flex;align-items:center;justify-content:space-between;margin-top:12px;padding-top:12px;border-top:1px solid var(--border);">
          <span style="font-size:12px;color:var(--text-light);" id="pt-count">共 0 名患者</span>
          <div style="display:flex;gap:6px;">
            <button class="btn btn-ghost btn-sm">« 上页</button>
            <button class="btn btn-outline btn-sm">1</button>
            <button class="btn btn-ghost btn-sm">2</button>
            <button class="btn btn-ghost btn-sm">下页 »</button>
          </div>
        </div>
      </div>
    </div>

    <!-- ════ VITALS ════ -->
    <div class="page" id="page-vitals">
      <div style="display:flex;gap:10px;margin-bottom:14px;flex-wrap:wrap;">
        <button class="btn btn-primary btn-sm" onclick="openModal('modal-addvital')">＋ 录入指标</button>
        <select class="fi fi-select" style="width:180px;" id="vital-pt" onchange="loadPatientVitals()">
          <option value="">选择患者查看</option>
        </select>
        <select class="fi fi-select" style="width:110px;" id="vital-days" onchange="renderVitalCharts()">
          <option value="7">近7天</option>
          <option value="14">近14天</option>
          <option value="30">近30天</option>
        </select>
      </div>
      <div class="vital-grid" style="margin-bottom:16px;" id="vital-summary"></div>
      <div style="display:grid;grid-template-columns:1fr 1fr;gap:16px;">
        <div class="card">
          <div class="card-hd"><div class="card-title"><span class="ct-icon">🩸</span>血糖变化趋势</div></div>
          <div class="chart-box-lg"><canvas id="glucoseChart"></canvas></div>
        </div>
        <div class="card">
          <div class="card-hd"><div class="card-title"><span class="ct-icon">❤️</span>血压变化趋势</div></div>
          <div class="chart-box-lg"><canvas id="bpChart"></canvas></div>
        </div>
      </div>
      <div class="card">
        <div class="card-hd">
          <div class="card-title"><span class="ct-icon">📋</span>健康指标记录</div>
          <button class="btn btn-ghost btn-sm" onclick="exportData('vitals')">📤 导出</button>
        </div>
        <div class="tbl-wrap">
          <table>
            <thead><tr><th>日期</th><th>患者</th><th>血糖(mmol/L)</th><th>收缩压(mmHg)</th><th>舒张压(mmHg)</th><th>心率(bpm)</th><th>体重(kg)</th><th>状态评估</th></tr></thead>
            <tbody id="vital-tbody"></tbody>
          </table>
        </div>
      </div>
    </div>

    <!-- ════ MEDICINE ════ -->
    <div class="page" id="page-medicine">
      <div style="display:flex;gap:10px;margin-bottom:14px;flex-wrap:wrap;">
        <button class="btn btn-primary" onclick="openModal('modal-addmed')">＋ 添加处方</button>
        <button class="btn btn-ghost" onclick="openModal('modal-schedule-all')">📅 批量提醒设置</button>
      </div>
      <div class="card">
        <div class="card-hd">
          <div class="card-title"><span class="ct-icon">⏰</span>今日用药任务</div>
          <span id="med-stats" class="pill pill-green">全部按时</span>
        </div>
        <div class="med-grid" id="med-grid"></div>
      </div>
      <div class="card">
        <div class="card-hd">
          <div class="card-title"><span class="ct-icon">📋</span>患者处方列表</div>
          <button class="btn btn-ghost btn-sm" onclick="exportData('medicine')">📤 导出</button>
        </div>
        <div class="tbl-wrap">
          <table>
            <thead><tr><th>患者</th><th>药品名称</th><th>规格</th><th>用法用量</th><th>服药时间</th><th>依从率</th><th>状态</th><th>操作</th></tr></thead>
            <tbody id="med-tbody"></tbody>
          </table>
        </div>
      </div>
    </div>

    <!-- ════ FOLLOWUP ════ -->
    <div class="page" id="page-followup">
      <div style="display:flex;gap:10px;margin-bottom:14px;flex-wrap:wrap;">
        <button class="btn btn-primary" onclick="openModal('modal-addfu')">＋ 安排随访</button>
        <button class="btn btn-ghost" onclick="openModal('modal-sms')">📱 发送提醒</button>
        <button class="btn btn-ghost btn-sm" onclick="exportData('followup')">📤 导出计划</button>
      </div>
      <div class="tabs">
        <div class="tab active" onclick="fuTab(this,'all')">全部</div>
        <div class="tab" onclick="fuTab(this,'today')">今日（3）</div>
        <div class="tab" onclick="fuTab(this,'week')">本周（12）</div>
        <div class="tab" onclick="fuTab(this,'done')">已完成</div>
        <div class="tab" onclick="fuTab(this,'overdue')">逾期</div>
      </div>
      <div class="card">
        <div class="tbl-wrap">
          <table>
            <thead><tr><th>随访ID</th><th>患者</th><th>疾病</th><th>随访方式</th><th>计划时间</th><th>状态</th><th>医生</th><th>操作</th></tr></thead>
            <tbody id="fu-tbody"></tbody>
          </table>
        </div>
      </div>
    </div>

    <!-- ════ ALERTS ════ -->
    <div class="page" id="page-alerts">
      <div class="tabs">
        <div class="tab active" onclick="alertTab(this,'all')">全部（4）</div>
        <div class="tab" onclick="alertTab(this,'critical')">🔴 危急（2）</div>
        <div class="tab" onclick="alertTab(this,'warning')">🟡 预警（2）</div>
        <div class="tab" onclick="alertTab(this,'handled')">✅ 已处理</div>
      </div>
      <div id="alerts-list"></div>
    </div>

    <!-- ════ EDUCATION ════ -->
    <div class="page" id="page-education">
      <div style="display:flex;align-items:center;gap:10px;margin-bottom:16px;flex-wrap:wrap;">
        <div class="search-wrap"><span>🔍</span><input type="text" placeholder="搜索健康知识…"></div>
        <select class="fi fi-select" style="width:130px;">
          <option>全部类别</option><option>糖尿病</option><option>高血压</option><option>心脏病</option><option>饮食营养</option><option>运动康复</option>
        </select>
        <button class="btn btn-primary btn-sm" onclick="openModal('modal-send-edu')">📤 推送给患者</button>
      </div>
      <div class="edu-grid" id="edu-grid"></div>
    </div>

    <!-- ════ REPORTS ════ -->
    <div class="page" id="page-reports">
      <div class="card">
        <div class="card-hd">
          <div class="card-title"><span class="ct-icon">📤</span>报表导出中心</div>
        </div>
        <p style="font-size:13px;color:var(--text-mid);margin-bottom:4px;">选择导出格式和数据范围，系统将自动生成报表文件</p>
        <div class="export-grid">
          <div class="exp-card" onclick="doExport('excel')">
            <div class="exp-icon">📊</div>
            <div class="exp-name">Excel 报表</div>
            <div class="exp-desc">完整数据明细，适合二次分析</div>
          </div>
          <div class="exp-card" onclick="doExport('csv')">
            <div class="exp-icon">📄</div>
            <div class="exp-name">CSV 格式</div>
            <div class="exp-desc">通用数据格式，兼容各系统</div>
          </div>
          <div class="exp-card" onclick="doExport('pdf')">
            <div class="exp-icon">📑</div>
            <div class="exp-name">PDF 报告</div>
            <div class="exp-desc">格式化报告，可直接打印归档</div>
          </div>
          <div class="exp-card" onclick="doExport('json')">
            <div class="exp-icon">🔗</div>
            <div class="exp-name">JSON 接口</div>
            <div class="exp-desc">对接HIS、EMR等医院信息系统</div>
          </div>
        </div>
      </div>
      <div class="card">
        <div class="card-hd"><div class="card-title"><span class="ct-icon">⚙️</span>导出配置</div></div>
        <div class="fg-grid c3">
          <div class="fg"><label class="form-label">数据类型</label>
            <select class="fi fi-select" id="exp-type"><option>全部数据</option><option>患者档案</option><option>健康指标</option><option>用药记录</option><option>随访记录</option></select>
          </div>
          <div class="fg"><label class="form-label">开始日期</label><input type="date" class="fi" id="exp-start"></div>
          <div class="fg"><label class="form-label">结束日期</label><input type="date" class="fi" id="exp-end"></div>
          <div class="fg"><label class="form-label">科室筛选</label>
            <select class="fi fi-select"><option>全部科室</option><option>心内科</option><option>内分泌科</option><option>肾内科</option><option>呼吸科</option></select>
          </div>
          <div class="fg"><label class="form-label">疾病类型</label>
            <select class="fi fi-select"><option>全部</option><option>糖尿病</option><option>高血压</option><option>冠心病</option></select>
          </div>
          <div class="fg" style="align-self:flex-end;">
            <button class="btn btn-primary" style="width:100%;" onclick="doExport('excel')">🚀 生成并下载</button>
          </div>
        </div>
      </div>
      <!-- Monthly Stats Chart -->
      <div class="card">
        <div class="card-hd"><div class="card-title"><span class="ct-icon">📊</span>月度健康管理统计</div></div>
        <div class="chart-box-lg"><canvas id="reportChart"></canvas></div>
      </div>
    </div>

    <!-- ════ SETTINGS ════ -->
    <div class="page" id="page-settings">
      <div class="card">
        <div class="card-hd"><div class="card-title"><span class="ct-icon">🔔</span>提醒规则设置</div></div>
        <div class="fg-grid">
          <div class="fg"><label>血糖高值预警阈值（mmol/L）</label><input type="number" class="fi" value="7.0" step="0.1"></div>
          <div class="fg"><label>血糖低值预警阈值（mmol/L）</label><input type="number" class="fi" value="3.9" step="0.1"></div>
          <div class="fg"><label>血压高值预警（收缩压 mmHg）</label><input type="number" class="fi" value="140"></div>
          <div class="fg"><label>提前提醒时间</label>
            <select class="fi fi-select"><option>提前30分钟</option><option>提前1小时</option><option>提前2小时</option></select>
          </div>
        </div>
      </div>
      <div class="card">
        <div class="card-hd"><div class="card-title"><span class="ct-icon">📱</span>短信提醒模板</div></div>
        <div class="fg-grid">
          <div class="fg full"><label>用药提醒模板</label>
            <textarea class="fi fi-ta">尊敬的{患者姓名}，您好！现在是{时间}，请按时服用{药品名称} {剂量}，保持健康生活！如有不适请及时联系{医生姓名}：{电话}。</textarea>
          </div>
          <div class="fg full"><label>随访提醒模板</label>
            <textarea class="fi fi-ta">尊敬的{患者姓名}，您的定期随访时间为{随访时间}，请提前准备好近期健康数据。如需改期请提前告知。</textarea>
          </div>
        </div>
        <div class="form-actions">
          <button class="btn btn-ghost">恢复默认</button>
          <button class="btn btn-primary" onclick="toast('设置已保存','success')">保存设置</button>
        </div>
      </div>
    </div>

  </div><!-- /content -->
</div><!-- /main -->
</div><!-- /app -->

<!-- ══════ MODALS ══════ -->

<!-- Add Patient -->
<div class="overlay" id="modal-addpt">
  <div class="modal">
    <div class="modal-hd">
      <div class="modal-title">🆕 新增患者档案</div>
      <button class="modal-close" onclick="closeModal('modal-addpt')">✕</button>
    </div>
    <div class="fg-grid">
      <div class="fg"><label>姓名 *</label><input type="text" class="fi" id="np-name" placeholder="患者姓名"></div>
      <div class="fg"><label>年龄</label><input type="number" class="fi" id="np-age" placeholder="岁"></div>
      <div class="fg"><label>性别</label><select class="fi fi-select" id="np-sex"><option>男</option><option>女</option></select></div>
      <div class="fg"><label>联系电话 *</label><input type="tel" class="fi" id="np-phone" placeholder="手机号码"></div>
      <div class="fg"><label>主要诊断 *</label>
        <select class="fi fi-select" id="np-disease"><option>糖尿病</option><option>高血压</option><option>冠心病</option><option>慢阻肺</option><option>慢性肾病</option></select>
      </div>
      <div class="fg"><label>病情严重程度</label>
        <select class="fi fi-select" id="np-severity"><option>轻度</option><option>中度</option><option>重度</option></select>
      </div>
      <div class="fg"><label>责任医生</label><input type="text" class="fi" id="np-doctor" placeholder="主治医师姓名"></div>
      <div class="fg"><label>科室</label>
        <select class="fi fi-select" id="np-dept"><option>心内科</option><option>内分泌科</option><option>肾内科</option><option>呼吸科</option></select>
      </div>
      <div class="fg full"><label>治疗方案摘要</label><textarea class="fi fi-ta" id="np-plan" placeholder="当前治疗方案、用药情况等…"></textarea></div>
      <div class="fg full"><label>备注</label><textarea class="fi fi-ta" id="np-note" placeholder="过敏史、特殊注意事项…"></textarea></div>
    </div>
    <div class="form-actions">
      <button class="btn btn-ghost" onclick="closeModal('modal-addpt')">取消</button>
      <button class="btn btn-primary" onclick="submitPatient()">保存档案</button>
    </div>
  </div>
</div>

<!-- Add Vital -->
<div class="overlay" id="modal-addvital">
  <div class="modal">
    <div class="modal-hd">
      <div class="modal-title">📥 录入健康指标</div>
      <button class="modal-close" onclick="closeModal('modal-addvital')">✕</button>
    </div>
    <div class="fg-grid c3">
      <div class="fg"><label>选择患者 *</label><select class="fi fi-select" id="vt-pt"></select></div>
      <div class="fg"><label>记录日期</label><input type="date" class="fi" id="vt-date"></div>
      <div class="fg"><label>记录时间</label><input type="time" class="fi" id="vt-time"></div>
      <div class="fg"><label>血糖（mmol/L）</label><input type="number" class="fi" id="vt-glucose" placeholder="如：6.2" step="0.1"></div>
      <div class="fg"><label>收缩压（mmHg）</label><input type="number" class="fi" id="vt-sbp" placeholder="如：120"></div>
      <div class="fg"><label>舒张压（mmHg）</label><input type="number" class="fi" id="vt-dbp" placeholder="如：80"></div>
      <div class="fg"><label>心率（bpm）</label><input type="number" class="fi" id="vt-hr" placeholder="如：72"></div>
      <div class="fg"><label>体重（kg）</label><input type="number" class="fi" id="vt-weight" placeholder="如：65.5" step="0.1"></div>
      <div class="fg"><label>血氧饱和度（%）</label><input type="number" class="fi" id="vt-spo2" placeholder="如：98"></div>
      <div class="fg full"><label>症状描述</label><textarea class="fi fi-ta" id="vt-note" placeholder="当前症状、自觉不适…" style="min-height:56px;"></textarea></div>
    </div>
    <div class="form-actions">
      <button class="btn btn-ghost" onclick="closeModal('modal-addvital')">取消</button>
      <button class="btn btn-primary" onclick="submitVital()">保存指标</button>
    </div>
  </div>
</div>

<!-- Add Medicine -->
<div class="overlay" id="modal-addmed">
  <div class="modal">
    <div class="modal-hd">
      <div class="modal-title">💊 添加处方药物</div>
      <button class="modal-close" onclick="closeModal('modal-addmed')">✕</button>
    </div>
    <div class="fg-grid">
      <div class="fg"><label>选择患者 *</label><select class="fi fi-select" id="med-pt"></select></div>
      <div class="fg"><label>药品名称 *</label><input type="text" class="fi" id="med-name" placeholder="药品通用名称"></div>
      <div class="fg"><label>规格</label><input type="text" class="fi" id="med-spec" placeholder="如：500mg/片"></div>
      <div class="fg"><label>用法用量 *</label><input type="text" class="fi" id="med-dose" placeholder="如：每日2次，每次1片"></div>
      <div class="fg"><label>服药时间</label>
        <select class="fi fi-select" id="med-time"><option>早餐前</option><option>早餐后</option><option>午餐后</option><option>晚餐前</option><option>晚餐后</option><option>睡前</option></select>
      </div>
      <div class="fg"><label>疗程天数</label><input type="number" class="fi" id="med-days" placeholder="天" value="30"></div>
      <div class="fg full"><label>注意事项</label><textarea class="fi fi-ta" id="med-note" placeholder="服药注意、禁忌事项…" style="min-height:56px;"></textarea></div>
    </div>
    <div class="form-actions">
      <button class="btn btn-ghost" onclick="closeModal('modal-addmed')">取消</button>
      <button class="btn btn-primary" onclick="submitMed()">保存处方</button>
    </div>
  </div>
</div>

<!-- Add Followup -->
<div class="overlay" id="modal-addfu">
  <div class="modal">
    <div class="modal-hd">
      <div class="modal-title">📅 安排随访</div>
      <button class="modal-close" onclick="closeModal('modal-addfu')">✕</button>
    </div>
    <div class="fg-grid">
      <div class="fg"><label>选择患者 *</label><select class="fi fi-select" id="fu-pt"></select></div>
      <div class="fg"><label>随访方式</label>
        <select class="fi fi-select" id="fu-type"><option>电话随访</option><option>视频随访</option><option>门诊随访</option><option>上门随访</option></select>
      </div>
      <div class="fg"><label>计划日期 *</label><input type="date" class="fi" id="fu-date"></div>
      <div class="fg"><label>计划时间</label><input type="time" class="fi" id="fu-time" value="10:00"></div>
      <div class="fg"><label>随访医生</label><input type="text" class="fi" id="fu-doctor" placeholder="负责医生"></div>
      <div class="fg"><label>随访主题</label>
        <select class="fi fi-select" id="fu-topic"><option>常规复查</option><option>药物调整</option><option>并发症筛查</option><option>康复指导</option></select>
      </div>
      <div class="fg full"><label>随访重点</label><textarea class="fi fi-ta" id="fu-note" placeholder="本次随访关注的重点问题…" style="min-height:56px;"></textarea></div>
    </div>
    <div class="form-actions">
      <button class="btn btn-ghost" onclick="closeModal('modal-addfu')">取消</button>
      <button class="btn btn-primary" onclick="submitFollowup()">确认安排</button>
    </div>
  </div>
</div>

<!-- SMS -->
<div class="overlay" id="modal-sms">
  <div class="modal">
    <div class="modal-hd">
      <div class="modal-title">📱 发送健康提醒</div>
      <button class="modal-close" onclick="closeModal('modal-sms')">✕</button>
    </div>
    <div class="fg-grid">
      <div class="fg full"><label>发送对象</label>
        <select class="fi fi-select"><option>本周随访患者（12人）</option><option>今日用药提醒患者（48人）</option><option>血糖异常患者（4人）</option><option>全部在管患者</option></select>
      </div>
      <div class="fg full"><label>消息内容</label>
        <textarea class="fi fi-ta" style="min-height:100px;">尊敬的患者，您好！您的定期随访时间临近，请保持按时用药，记录每日健康指标。如有不适请及时就医。祝您身体健康！</textarea>
      </div>
    </div>
    <div style="display:flex;align-items:center;justify-content:space-between;margin:10px 0;">
      <span style="font-size:12px;color:var(--text-mid);">预计发送：<strong style="color:var(--sage-mid);">12 条</strong></span>
      <span style="font-size:12px;color:var(--text-mid);">预计费用：<strong style="color:var(--amber);">¥ 1.20</strong></span>
    </div>
    <div class="form-actions">
      <button class="btn btn-ghost" onclick="closeModal('modal-sms')">取消</button>
      <button class="btn btn-primary" onclick="sendSMS()">📤 确认发送</button>
    </div>
  </div>
</div>

<!-- Edu Modal -->
<div class="overlay" id="modal-send-edu">
  <div class="modal">
    <div class="modal-hd">
      <div class="modal-title">📤 推送健康教育内容</div>
      <button class="modal-close" onclick="closeModal('modal-send-edu')">✕</button>
    </div>
    <div class="fg-grid">
      <div class="fg full"><label>推送对象</label>
        <select class="fi fi-select"><option>糖尿病患者（342人）</option><option>高血压患者（289人）</option><option>全部在管患者</option></select>
      </div>
      <div class="fg full"><label>推送方式</label>
        <select class="fi fi-select"><option>系统消息 + 短信</option><option>仅系统消息</option><option>仅短信</option></select>
      </div>
    </div>
    <div class="form-actions">
      <button class="btn btn-ghost" onclick="closeModal('modal-send-edu')">取消</button>
      <button class="btn btn-primary" onclick="closeModal('modal-send-edu');toast('健康教育内容已推送成功','success')">确认推送</button>
    </div>
  </div>
</div>

<!-- Patient Drawer -->
<div class="drawer" id="patient-drawer">
  <div class="drawer-hd">
    <div style="font-family:'Lora',serif;font-size:17px;font-weight:600;" id="dw-name">患者详情</div>
    <button class="modal-close" onclick="closeDrawer()">✕</button>
  </div>
  <div class="drawer-body" id="dw-body"></div>
  <div class="drawer-footer">
    <button class="btn btn-primary btn-sm" onclick="openModal('modal-addvital')">录入指标</button>
    <button class="btn btn-outline btn-sm" onclick="openModal('modal-addfu')">安排随访</button>
    <button class="btn btn-ghost btn-sm" onclick="openModal('modal-sms')">发提醒</button>
  </div>
</div>

<!-- Toast -->
<div class="toast-wrap" id="toast-wrap"></div>

<script>
// ══════ DATA ══════
const pick=a=>a[Math.floor(Math.random()*a.length)];
const rnd=(a,b)=>Math.floor(Math.random()*(b-a+1))+a;
const fmtDate=d=>d.toISOString().slice(0,10);
const today=fmtDate(new Date());

const DISEASES=['糖尿病','高血压','冠心病','慢阻肺','慢性肾病'];
const DOCTORS=['李明医生','张华医生','陈静医生','刘伟医生','王芳医生'];
const DEPTS=['心内科','内分泌科','肾内科','呼吸科'];
const FU_TYPES=['电话随访','视频随访','门诊随访','上门随访'];
const SN=['张','李','王','刘','陈','杨','赵','黄','周','吴'];
const GN=['明','伟','芳','丽','军','磊','涛','静','超','敏'];

function genName(){return pick(SN)+pick(GN)+(Math.random()>.6?pick(GN):'');}
function rndDate(d){const dt=new Date();dt.setDate(dt.getDate()+d);return fmtDate(dt);}

// Patients
let patients=Array.from({length:20},(_,i)=>({
  id:`P${String(1001+i).padStart(4,'0')}`,
  name:genName(), age:rnd(38,80), sex:Math.random()>.5?'男':'女',
  phone:`13${rnd(100000000,999999999)}`,
  disease:pick(DISEASES), severity:pick(['轻度','中度','重度']),
  doctor:pick(DOCTORS), dept:pick(DEPTS),
  status:pick(['管理中','待随访','病情稳定','病情恶化']),
  lastVisit:rndDate(-rnd(1,30)), nextVisit:rndDate(rnd(1,21)),
  score:rnd(55,95), compliance:rnd(60,100),
  plan:'', note:'',
  history:[
    {date:rndDate(-60),type:pick(FU_TYPES),result:'血糖/血压控制良好'},
    {date:rndDate(-30),type:pick(FU_TYPES),result:'调整用药方案'},
  ]
}));

// Vitals
let vitals=Array.from({length:30},(_,i)=>{
  const p=pick(patients);
  const d=new Date(); d.setDate(d.getDate()-rnd(0,30));
  return {
    date:fmtDate(d), patient:p.name, patientId:p.id,
    glucose:parseFloat((rnd(40,160)/10).toFixed(1)),
    sbp:rnd(100,185), dbp:rnd(60,115),
    hr:rnd(58,105), weight:parseFloat((rnd(480,900)/10).toFixed(1)),
    spo2:rnd(92,100), note:''
  };
}).sort((a,b)=>b.date.localeCompare(a.date));

// Medicines
const DRUGS=['二甲双胍','格列吡嗪','阿卡波糖','胰岛素','氨氯地平','厄贝沙坦','美托洛尔','阿托伐他汀','阿司匹林','沙丁胺醇'];
let medicines=patients.slice(0,12).flatMap((p,i)=>[{
  patient:p.name, patientId:p.id, drug:pick(DRUGS),
  spec:'500mg/片', dose:'每日2次，每次1片',
  time:pick(['早餐前','早餐后','晚餐后','睡前']),
  days:rnd(30,90), compliance:rnd(65,100),
  status:pick(['按时服用','偶尔漏服','经常漏服']),
  note:''
}]);

// Followups
let followups=Array.from({length:16},(_,i)=>{
  const p=pick(patients);
  return {
    id:`FU${String(2001+i).padStart(4,'0')}`,
    patient:p.name, patientId:p.id, disease:p.disease,
    type:pick(FU_TYPES), doctor:p.doctor,
    date:rndDate(rnd(-3,14)),
    status:pick(['待执行','已完成','逾期','已取消']),
    topic:pick(['常规复查','药物调整','并发症筛查','康复指导']),
    note:''
  };
});

// ══════ NAVIGATION ══════
const PAGE_META={
  dashboard:['健康总览','今日共有 8 项待处理事项'],
  patients:['患者档案','管理所有慢病患者健康档案'],
  vitals:['健康监测','实时监控患者健康指标数据'],
  medicine:['用药管理','处方管理与服药提醒跟踪'],
  followup:['远程随访','安排与跟踪患者定期随访'],
  alerts:['异常提醒','查看并处理所有健康异常预警'],
  education:['健康教育','向患者推送个性化健康知识'],
  reports:['报表导出','生成与下载健康管理报表'],
  settings:['系统设置','配置提醒规则与系统参数'],
};

function nav(el,name){
  document.querySelectorAll('.nav-item').forEach(n=>n.classList.remove('active'));
  el.classList.add('active');
  document.querySelectorAll('.page').forEach(p=>p.classList.remove('active'));
  document.getElementById('page-'+name).classList.add('active');
  const[t,s]=PAGE_META[name]||[name,''];
  document.getElementById('tb-title').textContent=t;
  document.getElementById('tb-sub').textContent=s;
  if(name==='patients')renderPatients();
  if(name==='vitals'){renderVitals();renderVitalCharts();}
  if(name==='medicine'){renderMedicine();}
  if(name==='followup')renderFollowups();
  if(name==='alerts')renderAlerts('all');
  if(name==='education')renderEducation();
  if(name==='reports')renderReportChart();
}

// ══════ DASHBOARD ══════
function renderDashboard(){
  // Trend chart
  const labels=['周一','周二','周三','周四','周五','周六','周日'];
  const glucoseData=[7.2,6.8,8.1,7.5,6.9,7.8,7.1];
  const bpData=[135,128,142,138,131,145,133];
  const ctx=document.getElementById('dashTrendChart').getContext('2d');
  new Chart(ctx,{type:'line',data:{labels,datasets:[
    {label:'平均血糖(mmol/L)',data:glucoseData,borderColor:'#40916c',backgroundColor:'rgba(64,145,108,.08)',fill:true,tension:.4,yAxisID:'y',pointRadius:4},
    {label:'平均收缩压(mmHg)',data:bpData,borderColor:'#1565c0',backgroundColor:'rgba(21,101,192,.06)',fill:true,tension:.4,yAxisID:'y1',pointRadius:4},
  ]},options:{responsive:true,maintainAspectRatio:false,plugins:{legend:{labels:{font:{size:11},color:'#5c7a6e'}}},scales:{
    x:{ticks:{color:'#7a9e94'}},
    y:{type:'linear',position:'left',ticks:{color:'#40916c'},title:{display:true,text:'血糖',color:'#40916c',font:{size:10}}},
    y1:{type:'linear',position:'right',ticks:{color:'#1565c0'},title:{display:true,text:'血压',color:'#1565c0',font:{size:10}},grid:{drawOnChartArea:false}}
  }}});

  const ctx2=document.getElementById('diseaseChart').getContext('2d');
  new Chart(ctx2,{type:'doughnut',data:{
    labels:DISEASES,
    datasets:[{data:[30,25,18,12,15],backgroundColor:['#40916c','#1565c0','#e76f00','#c0392b','#b8860b'],borderWidth:0}]
  },options:{responsive:true,maintainAspectRatio:false,plugins:{legend:{position:'bottom',labels:{font:{size:11},color:'#4a6b60',padding:8}}}}});

  // Today meds
  const todayPts=patients.slice(0,5);
  document.getElementById('dash-meds').innerHTML=todayPts.map((p,i)=>`
    <div style="display:flex;align-items:center;gap:10px;padding:9px 0;border-bottom:1px solid var(--border);${i===todayPts.length-1?'border:none;':''}">
      <div style="width:34px;height:34px;border-radius:50%;background:var(--sage-pale);display:flex;align-items:center;justify-content:center;font-size:13px;font-weight:700;color:var(--sage);flex-shrink:0;">${p.name[0]}</div>
      <div style="flex:1;"><div style="font-size:13px;font-weight:500;">${p.name}</div><div style="font-size:11px;color:var(--text-light);">${pick(DRUGS)} · ${pick(['早餐前','晚餐后','睡前'])}</div></div>
      <span class="pill ${i<2?'pill-amber':'pill-green'}">${i<2?'待服药':'已服药'}</span>
    </div>
  `).join('');

  // Timeline
  const tls=[
    {time:'今日 14:22',t:'完成随访 – 张伟民',d:'电话随访，血糖控制良好'},
    {time:'今日 10:05',t:'指标录入 – 李秀英',d:'血压 182/98 mmHg，已预警'},
    {time:'昨日 16:30',t:'调整方案 – 王建国',d:'增加降压药剂量'},
    {time:'昨日 09:00',t:'用药提醒发送',d:'共发送 48 条服药提醒'},
  ];
  document.getElementById('dash-timeline').innerHTML=tls.map(t=>`
    <div class="tl-item"><div class="tl-time">${t.time}</div><div class="tl-title">${t.t}</div><div class="tl-desc">${t.d}</div></div>
  `).join('');
}

// ══════ PATIENTS ══════
function statusPill(s){const m={管理中:'pill-green',待随访:'pill-amber',病情稳定:'pill-sky',病情恶化:'pill-rose'};return `<span class="pill ${m[s]||'pill-gray'}"><span class="pill-dot"></span>${s}</span>`;}
function compliancePill(c){return c>=80?'pill-green':c>=60?'pill-amber':'pill-rose';}

function renderPatients(list){
  const data=list||patients;
  const tb=document.getElementById('pt-tbody');
  document.getElementById('pt-count').textContent=`共 ${data.length} 名患者`;
  if(!data.length){tb.innerHTML='';document.getElementById('pt-empty').style.display='block';return;}
  document.getElementById('pt-empty').style.display='none';
  tb.innerHTML=data.map(p=>`<tr>
    <td style="font-family:monospace;color:var(--sage);font-size:12px;">${p.id}</td>
    <td style="font-weight:600;">${p.name}</td>
    <td>${p.age}岁 / ${p.sex}</td>
    <td><span class="pill pill-sky">${p.disease}</span></td>
    <td>
      <div style="display:flex;align-items:center;gap:8px;">
        <div class="prog" style="width:60px;"><div class="prog-bar ${p.score>=80?'pb-green':p.score>=60?'pb-amber':'pb-rose'}" style="width:${p.score}%"></div></div>
        <span style="font-size:12px;font-weight:600;">${p.score}</span>
      </div>
    </td>
    <td><span class="pill ${compliancePill(p.compliance)}">${p.compliance}%</span></td>
    <td>${statusPill(p.status)}</td>
    <td style="font-size:12px;color:var(--text-light);">${p.lastVisit}</td>
    <td style="display:flex;gap:5px;">
      <button class="btn btn-ghost btn-xs" onclick="openDrawer('${p.id}')">档案</button>
      <button class="btn btn-outline btn-xs" onclick="openModal('modal-addvital')">录指标</button>
    </td>
  </tr>`).join('');
}

function filterPt(){
  const q=document.getElementById('pt-search').value.toLowerCase();
  const ds=document.getElementById('pt-fs').value;
  const st=document.getElementById('pt-fst').value;
  renderPatients(patients.filter(p=>
    (!q||(p.name+p.id+p.disease).toLowerCase().includes(q))&&
    (!ds||p.disease===ds)&&(!st||p.status===st)
  ));
}

// ══════ VITALS ══════
let glucoseChartInst=null, bpChartInst=null;

function populateVitalPtSelect(){
  const sel=document.getElementById('vital-pt');
  sel.innerHTML='<option value="">选择患者查看</option>'+patients.map(p=>`<option value="${p.id}">${p.name}（${p.id}）</option>`).join('');
}

function renderVitals(){
  populateVitalPtSelect();
  const latest=vitals[0]||{glucose:7.1,sbp:128,dbp:82,hr:72,weight:65,spo2:98};
  document.getElementById('vital-summary').innerHTML=`
    <div class="vital-card"><div class="vital-label">最新血糖</div>
      <div class="vital-val">${latest.glucose}<span class="vital-unit">mmol/L</span></div>
      <div class="vital-status ${latest.glucose>7?'vital-high':latest.glucose<3.9?'vital-low':'vital-normal'}">${latest.glucose>7?'↑ 偏高':latest.glucose<3.9?'↓ 偏低':'✓ 正常'}</div>
    </div>
    <div class="vital-card"><div class="vital-label">最新血压</div>
      <div class="vital-val">${latest.sbp}/${latest.dbp}<span class="vital-unit">mmHg</span></div>
      <div class="vital-status ${latest.sbp>140?'vital-high':'vital-normal'}">${latest.sbp>140?'↑ 偏高':'✓ 正常'}</div>
    </div>
    <div class="vital-card"><div class="vital-label">心率</div>
      <div class="vital-val">${latest.hr}<span class="vital-unit">bpm</span></div>
      <div class="vital-status ${latest.hr>100?'vital-high':latest.hr<60?'vital-low':'vital-normal'}">${latest.hr>100?'↑ 偏快':latest.hr<60?'↓ 偏慢':'✓ 正常'}</div>
    </div>
    <div class="vital-card"><div class="vital-label">血氧饱和度</div>
      <div class="vital-val">${latest.spo2}<span class="vital-unit">%</span></div>
      <div class="vital-status ${latest.spo2<95?'vital-low':'vital-normal'}">${latest.spo2<95?'↓ 偏低':'✓ 正常'}</div>
    </div>`;

  // Vitals table
  document.getElementById('vital-tbody').innerHTML=vitals.slice(0,20).map(v=>{
    const gst=v.glucose>7?'pill-rose':v.glucose<3.9?'pill-amber':'pill-green';
    const bst=v.sbp>140?'pill-rose':v.sbp<100?'pill-amber':'pill-green';
    return `<tr>
      <td style="font-size:12px;">${v.date}</td>
      <td style="font-weight:500;">${v.patient}</td>
      <td><span class="pill ${gst}">${v.glucose}</span></td>
      <td>${v.sbp}</td><td>${v.dbp}</td><td>${v.hr}</td><td>${v.weight}</td>
      <td>${v.sbp>140||v.glucose>7?'<span class="pill pill-rose">异常</span>':'<span class="pill pill-green">正常</span>'}</td>
    </tr>`;
  }).join('');
}

function renderVitalCharts(){
  const days=parseInt(document.getElementById('vital-days').value)||7;
  const labels=Array.from({length:days},(_,i)=>{const d=new Date();d.setDate(d.getDate()-days+i+1);return `${d.getMonth()+1}/${d.getDate()}`;});
  const glucoseData=labels.map(()=>parseFloat((rnd(55,140)/10).toFixed(1)));
  const sbpData=labels.map(()=>rnd(110,165));
  const dbpData=sbpData.map(v=>v-rnd(35,55));

  const opt={responsive:true,maintainAspectRatio:false,plugins:{legend:{labels:{font:{size:11},color:'#5c7a6e'}}},scales:{x:{ticks:{color:'#7a9e94',font:{size:11}}},y:{ticks:{color:'#7a9e94'},grid:{color:'rgba(0,0,0,.04)'}}}};

  if(glucoseChartInst)glucoseChartInst.destroy();
  glucoseChartInst=new Chart(document.getElementById('glucoseChart').getContext('2d'),{type:'line',data:{labels,datasets:[
    {label:'空腹血糖',data:glucoseData,borderColor:'#40916c',backgroundColor:'rgba(64,145,108,.1)',fill:true,tension:.4,pointRadius:4},
    {label:'安全上限(7.0)',data:labels.map(()=>7.0),borderColor:'#e76f00',borderDash:[4,4],borderWidth:1.5,pointRadius:0,fill:false},
  ]},options:opt});

  if(bpChartInst)bpChartInst.destroy();
  bpChartInst=new Chart(document.getElementById('bpChart').getContext('2d'),{type:'line',data:{labels,datasets:[
    {label:'收缩压',data:sbpData,borderColor:'#1565c0',backgroundColor:'rgba(21,101,192,.08)',fill:true,tension:.4,pointRadius:4},
    {label:'舒张压',data:dbpData,borderColor:'#74c69d',backgroundColor:'rgba(116,198,157,.08)',fill:true,tension:.4,pointRadius:4},
  ]},options:opt});
}

function loadPatientVitals(){renderVitalCharts();}

// ══════ MEDICINE ══════
function renderMedicine(){
  const missed=medicines.filter(m=>m.status==='经常漏服').length;
  document.getElementById('med-stats').innerHTML=missed>0?`<span class="pill pill-rose">${missed}人漏服</span>`:'<span class="pill pill-green">全部按时</span>';

  // Med grid (today reminders)
  const todayMeds=medicines.slice(0,6);
  document.getElementById('med-grid').innerHTML=todayMeds.map((m,i)=>{
    const taken=i>2;const missed=i===1;
    return `<div class="med-card ${taken?'taken':missed?'missed':''}">
      <div class="med-name">💊 ${m.drug}</div>
      <div class="med-dose">${m.dose}</div>
      <div class="med-time">⏰ ${m.time} · ${m.patient}</div>
      <div class="med-actions">
        ${taken?`<span class="pill pill-green">✓ 已服药</span>`:
          `<button class="btn btn-primary btn-xs" onclick="markTaken(this)">✓ 已服药</button>
           <button class="btn btn-ghost btn-xs" onclick="toast('已记录漏服并发送提醒','warning')">漏服</button>`}
      </div>
    </div>`;
  }).join('');

  // Medicine table
  document.getElementById('med-tbody').innerHTML=medicines.map(m=>`<tr>
    <td style="font-weight:500;">${m.patient}</td>
    <td>${m.drug}</td>
    <td style="color:var(--text-light);font-size:12px;">${m.spec}</td>
    <td style="font-size:12px;">${m.dose}</td>
    <td>${m.time}</td>
    <td><span class="pill ${compliancePill(m.compliance)}">${m.compliance}%</span></td>
    <td><span class="pill ${m.status==='按时服用'?'pill-green':m.status==='偶尔漏服'?'pill-amber':'pill-rose'}">${m.status}</span></td>
    <td style="display:flex;gap:5px;">
      <button class="btn btn-ghost btn-xs" onclick="toast('提醒已发送给患者','success')">提醒</button>
      <button class="btn btn-danger btn-xs" onclick="toast('处方已停用','info')">停用</button>
    </td>
  </tr>`).join('');
}

function markTaken(btn){
  const card=btn.closest('.med-card');
  card.classList.add('taken');
  card.querySelector('.med-actions').innerHTML='<span class="pill pill-green">✓ 已服药</span>';
  toast('服药记录已更新','success');
}

// ══════ FOLLOWUP ══════
const fuClass={待执行:'pill-amber',已完成:'pill-green',逾期:'pill-rose',已取消:'pill-gray'};
function renderFollowups(list){
  const data=list||followups;
  document.getElementById('fu-tbody').innerHTML=data.map(f=>`<tr>
    <td style="font-family:monospace;color:var(--sage);font-size:12px;">${f.id}</td>
    <td style="font-weight:500;">${f.patient}</td>
    <td><span class="pill pill-sky">${f.disease}</span></td>
    <td>${f.type}</td>
    <td>${f.date}</td>
    <td><span class="pill ${fuClass[f.status]||'pill-gray'}"><span class="pill-dot"></span>${f.status}</span></td>
    <td style="font-size:12px;color:var(--text-light);">${f.doctor}</td>
    <td style="display:flex;gap:5px;">
      <button class="btn btn-ghost btn-xs" onclick="completeFU('${f.id}')">完成</button>
      <button class="btn btn-outline btn-xs" onclick="openModal('modal-sms')">提醒</button>
    </td>
  </tr>`).join('');
}
function fuTab(el,filter){
  document.querySelectorAll('.tab').forEach(t=>t.classList.remove('active'));el.classList.add('active');
  const map={all:followups,today:followups.filter(f=>f.date===today),week:followups.slice(0,10),done:followups.filter(f=>f.status==='已完成'),overdue:followups.filter(f=>f.status==='逾期')};
  renderFollowups(map[filter]);
}
function completeFU(id){const f=followups.find(x=>x.id===id);if(f){f.status='已完成';renderFollowups();toast('随访已标记完成','success');}}

// ══════ ALERTS ══════
const ALERTS=[
  {type:'critical',title:'张伟民 – 血糖严重偏高',desc:'空腹血糖 14.2 mmol/L，超出危急值（>13.9），需立即处置',time:'今日 08:32',pid:'P1001'},
  {type:'critical',title:'李秀英 – 血压危急值',desc:'收缩压 182 mmHg，高血压危象风险，请立即联系患者',time:'今日 09:15',pid:'P1002'},
  {type:'warning',title:'王建国 – 连续漏服用药',desc:'连续3天未服用降压药，依从率降至57%，需干预',time:'今日 10:00',pid:'P1003'},
  {type:'warning',title:'刘 静 – 体重异常增加',desc:'1个月内体重增加4.2kg，心力衰竭患者需警惕水钠潴留',time:'今日 11:20',pid:'P1004'},
];
function renderAlerts(filter){
  const data=filter==='all'?ALERTS:filter==='handled'?[]:ALERTS.filter(a=>a.type===filter);
  document.getElementById('alerts-list').innerHTML=data.length?data.map(a=>`
    <div class="alert ${a.type==='critical'?'alert-rose':'alert-amber'}" style="margin-bottom:10px;">
      <div class="alert-icon">${a.type==='critical'?'🔴':'🟡'}</div>
      <div class="alert-body">
        <div class="alert-title">${a.title}</div>
        <div class="alert-desc">${a.desc}</div>
        <div style="font-size:11px;color:var(--text-faint);margin-top:4px;">⏱ ${a.time}</div>
      </div>
      <div style="display:flex;flex-direction:column;gap:6px;">
        <button class="btn ${a.type==='critical'?'btn-danger':'btn-amber'} btn-sm" onclick="openDrawer('${a.pid}')">查看档案</button>
        <button class="btn btn-ghost btn-sm" onclick="this.closest('.alert').remove();toast('已标记为已处理','success')">已处理</button>
      </div>
    </div>
  `).join(''):
  filter==='handled'?'<div class="empty"><div class="empty-icon">✅</div><div class="empty-text">所有预警均已处理</div></div>':
  '<div class="empty"><div class="empty-icon">🎉</div><div class="empty-text">当前无此类预警</div></div>';
}
function alertTab(el,filter){document.querySelectorAll('.tab').forEach(t=>t.classList.remove('active'));el.classList.add('active');renderAlerts(filter);}

// ══════ EDUCATION ══════
const EDU_DATA=[
  {icon:'🩸',color:'#d8f3dc',tag:'糖尿病',tagColor:'pill-green',title:'血糖自我监测指南',desc:'教您如何正确使用血糖仪，理解血糖读数，制定合理的监测计划。',reads:'1.2k'},
  {icon:'❤️',color:'#e3f2fd',tag:'高血压',tagColor:'pill-sky',title:'低盐饮食实践方案',desc:'每天6g食盐的实操方法，教您识别隐藏盐分，轻松降低血压。',reads:'987'},
  {icon:'🚶',color:'#fff3e0',tag:'运动康复',tagColor:'pill-amber',title:'慢病患者安全运动指南',desc:'针对慢性病患者设计的安全运动方案，包括强度、频率和注意事项。',reads:'756'},
  {icon:'💊',color:'#fdecea',tag:'用药管理',tagColor:'pill-rose',title:'如何提高服药依从性',desc:'8个实用技巧帮助您养成按时服药的习惯，避免漏服和忘服。',reads:'1.5k'},
  {icon:'🥗',color:'#d8f3dc',tag:'饮食营养',tagColor:'pill-green',title:'糖尿病饮食交换份法',desc:'用食物交换份轻松规划一日三餐，平衡营养又控制血糖。',reads:'634'},
  {icon:'😴',color:'#e8eaf6',tag:'生活方式',tagColor:'pill-gold',title:'睡眠质量与慢病管理',desc:'充足优质睡眠对血糖、血压控制的重要性及改善睡眠的实用方法。',reads:'521'},
];
function renderEducation(){
  document.getElementById('edu-grid').innerHTML=EDU_DATA.map(e=>`
    <div class="edu-card">
      <div class="edu-banner" style="background:${e.color};">${e.icon}</div>
      <div class="edu-body">
        <div class="edu-tag"><span class="pill ${e.tagColor}">${e.tag}</span></div>
        <div class="edu-title">${e.title}</div>
        <div class="edu-desc">${e.desc}</div>
      </div>
      <div class="edu-footer">
        <span style="font-size:11px;color:var(--text-faint);">👁 ${e.reads} 次阅读</span>
        <button class="btn btn-outline btn-xs" onclick="openModal('modal-send-edu')">推送</button>
      </div>
    </div>
  `).join('');
}

// ══════ REPORT CHART ══════
let reportChartInst=null;
function renderReportChart(){
  if(reportChartInst)return;
  const labels=['8月','9月','10月','11月','12月','1月'];
  reportChartInst=new Chart(document.getElementById('reportChart').getContext('2d'),{type:'bar',data:{labels,datasets:[
    {label:'新增患者',data:[28,35,31,42,38,31],backgroundColor:'rgba(64,145,108,.5)',borderColor:'#40916c',borderWidth:1.5},
    {label:'完成随访',data:[245,278,262,310,298,278],backgroundColor:'rgba(21,101,192,.4)',borderColor:'#1565c0',borderWidth:1.5},
    {label:'异常预警',data:[12,8,15,9,11,4],backgroundColor:'rgba(192,57,43,.4)',borderColor:'#c0392b',borderWidth:1.5},
  ]},options:{responsive:true,maintainAspectRatio:false,plugins:{legend:{labels:{font:{size:11},color:'#5c7a6e'}}},scales:{x:{ticks:{color:'#7a9e94'}},y:{ticks:{color:'#7a9e94'},grid:{color:'rgba(0,0,0,.04)'}}}}});
}

// ══════ DRAWER ══════
function openDrawer(pid){
  const p=patients.find(x=>x.id===pid)||patients[0];
  document.getElementById('dw-name').textContent=`${p.name}（${p.id}）`;
  document.getElementById('dw-body').innerHTML=`
    <div style="display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-bottom:16px;">
      ${[['年龄/性别',p.age+'岁 / '+p.sex],['联系电话',p.phone],['主要诊断',p.disease],['病情程度',p.severity],['责任医生',p.doctor],['科室',p.dept]].map(([k,v])=>`
        <div style="background:var(--off);border:1px solid var(--border);border-radius:8px;padding:9px 11px;">
          <div style="font-size:10px;color:var(--text-faint);text-transform:uppercase;letter-spacing:.5px;">${k}</div>
          <div style="font-size:13px;font-weight:500;margin-top:2px;">${v}</div>
        </div>`).join('')}
    </div>
    <div style="margin-bottom:14px;">
      <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:5px;">
        <span style="font-size:12px;color:var(--text-mid);">健康评分</span>
        <span style="font-size:13px;font-weight:700;color:${p.score>=80?'var(--sage-mid)':p.score>=60?'var(--amber)':'var(--rose)'};">${p.score}/100</span>
      </div>
      <div class="prog"><div class="prog-bar ${p.score>=80?'pb-green':p.score>=60?'pb-amber':'pb-rose'}" style="width:${p.score}%"></div></div>
    </div>
    <div style="margin-bottom:14px;">
      <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:5px;">
        <span style="font-size:12px;color:var(--text-mid);">用药依从率</span>
        <span style="font-size:13px;font-weight:700;color:${p.compliance>=80?'var(--sage-mid)':p.compliance>=60?'var(--amber)':'var(--rose)'};">${p.compliance}%</span>
      </div>
      <div class="prog"><div class="prog-bar ${compliancePill(p.compliance).replace('pill-','pb-')}" style="width:${p.compliance}%"></div></div>
    </div>
    <div style="font-size:12px;color:var(--text-light);text-transform:uppercase;letter-spacing:.5px;margin-bottom:8px;">随访记录</div>
    <div class="tl">
      ${p.history.map(h=>`<div class="tl-item"><div class="tl-time">${h.date}</div><div class="tl-title">${h.type}</div><div class="tl-desc">${h.result}</div></div>`).join('')}
    </div>
    <div style="margin-top:14px;background:var(--off);border:1px solid var(--border);border-radius:8px;padding:11px;">
      <div style="font-size:11px;color:var(--text-faint);margin-bottom:4px;">下次随访</div>
      <div style="font-size:15px;font-weight:600;color:${p.nextVisit<today?'var(--rose)':'var(--sage-mid)'};">${p.nextVisit}</div>
    </div>
  `;
  document.getElementById('patient-drawer').classList.add('open');
}
function closeDrawer(){document.getElementById('patient-drawer').classList.remove('open');}

// ══════ MODALS ══════
function openModal(id){document.getElementById(id).classList.add('show');}
function closeModal(id){document.getElementById(id).classList.remove('show');}

function populateSelects(){
  const ptOpts=patients.map(p=>`<option value="${p.id}">${p.name}（${p.id}）</option>`).join('');
  ['vt-pt','med-pt','fu-pt'].forEach(id=>{const el=document.getElementById(id);if(el)el.innerHTML=ptOpts;});
  const vitPt=document.getElementById('vital-pt');
  if(vitPt)vitPt.innerHTML='<option value="">选择患者查看</option>'+ptOpts;
}

function submitPatient(){
  const name=document.getElementById('np-name').value.trim();
  const phone=document.getElementById('np-phone').value.trim();
  if(!name||!phone){toast('请填写姓名和联系电话','error');return;}
  const p={
    id:`P${String(1001+patients.length).padStart(4,'0')}`,
    name,age:parseInt(document.getElementById('np-age').value)||50,
    sex:document.getElementById('np-sex').value,phone,
    disease:document.getElementById('np-disease').value,
    severity:document.getElementById('np-severity').value,
    doctor:document.getElementById('np-doctor').value||pick(DOCTORS),
    dept:document.getElementById('np-dept').value,
    status:'待随访',lastVisit:today,nextVisit:rndDate(14),
    score:rnd(60,90),compliance:rnd(70,95),
    plan:document.getElementById('np-plan').value,
    note:document.getElementById('np-note').value,history:[]
  };
  patients.unshift(p);
  populateSelects();
  closeModal('modal-addpt');
  renderPatients();
  toast(`✅ 患者 ${name} 档案已建立`,'success');
  ['np-name','np-phone','np-age','np-plan','np-note'].forEach(id=>document.getElementById(id).value='');
}

function submitVital(){
  const ptId=document.getElementById('vt-pt').value;
  const glucose=parseFloat(document.getElementById('vt-glucose').value);
  const sbp=parseInt(document.getElementById('vt-sbp').value);
  if(!ptId||isNaN(glucose)){toast('请选择患者并填写血糖值','error');return;}
  const p=patients.find(x=>x.id===ptId);
  vitals.unshift({
    date:document.getElementById('vt-date').value||today,
    patient:p?p.name:'未知',patientId:ptId,glucose,
    sbp:sbp||0,dbp:parseInt(document.getElementById('vt-dbp').value)||0,
    hr:parseInt(document.getElementById('vt-hr').value)||0,
    weight:parseFloat(document.getElementById('vt-weight').value)||0,
    spo2:parseInt(document.getElementById('vt-spo2').value)||0,
    note:document.getElementById('vt-note').value
  });
  closeModal('modal-addvital');
  if(glucose>13.9||sbp>180){toast('⚠️ 检测到危急值，已触发预警','error');}
  else if(glucose>7||sbp>140){toast('⚠️ 指标偏高，已记录并预警','warning');}
  else{toast('✅ 健康指标已保存','success');}
  renderVitals();
}

function submitMed(){
  const ptId=document.getElementById('med-pt').value;
  const name=document.getElementById('med-name').value.trim();
  if(!ptId||!name){toast('请选择患者并填写药品名称','error');return;}
  const p=patients.find(x=>x.id===ptId);
  medicines.unshift({
    patient:p?p.name:'未知',patientId:ptId,drug:name,
    spec:document.getElementById('med-spec').value||'按需',
    dose:document.getElementById('med-dose').value||'遵医嘱',
    time:document.getElementById('med-time').value,
    days:parseInt(document.getElementById('med-days').value)||30,
    compliance:100,status:'按时服用',note:document.getElementById('med-note').value
  });
  closeModal('modal-addmed');
  renderMedicine();
  toast(`✅ 已为 ${p?p.name:'患者'} 添加处方：${name}`,'success');
}

function submitFollowup(){
  const ptId=document.getElementById('fu-pt').value;
  const date=document.getElementById('fu-date').value;
  if(!ptId||!date){toast('请选择患者和随访日期','error');return;}
  const p=patients.find(x=>x.id===ptId);
  followups.unshift({
    id:`FU${String(2001+followups.length).padStart(4,'0')}`,
    patient:p?p.name:'未知',patientId:ptId,disease:p?p.disease:'',
    type:document.getElementById('fu-type').value,
    doctor:document.getElementById('fu-doctor').value||pick(DOCTORS),
    date,status:'待执行',
    topic:document.getElementById('fu-topic').value,
    note:document.getElementById('fu-note').value
  });
  closeModal('modal-addfu');
  renderFollowups();
  toast(`✅ 随访已安排：${p?p.name:''} · ${date}`,'success');
}

function sendSMS(){closeModal('modal-sms');toast('📱 短信已成功发送给 12 名患者','success');}

// ══════ EXPORT ══════
function exportData(type){
  const headers={
    patients:['患者ID','姓名','年龄','性别','电话','诊断','状态','健康评分','最后随访'],
    vitals:['日期','患者','血糖','收缩压','舒张压','心率','体重'],
    medicine:['患者','药品','规格','用法','服药时间','依从率','状态'],
    followup:['随访ID','患者','疾病','方式','日期','状态','医生'],
  };
  const rows={
    patients:patients.map(p=>[p.id,p.name,p.age,p.sex,p.phone,p.disease,p.status,p.score,p.lastVisit]),
    vitals:vitals.map(v=>[v.date,v.patient,v.glucose,v.sbp,v.dbp,v.hr,v.weight]),
    medicine:medicines.map(m=>[m.patient,m.drug,m.spec,m.dose,m.time,m.compliance+'%',m.status]),
    followup:followups.map(f=>[f.id,f.patient,f.disease,f.type,f.date,f.status,f.doctor]),
  };
  const h=headers[type]||headers.patients;
  const r=rows[type]||rows.patients;
  const csv=[h,...r].map(row=>row.map(v=>`"${v||''}"`).join(',')).join('\n');
  const blob=new Blob(['\uFEFF'+csv],{type:'text/csv;charset=utf-8;'});
  const url=URL.createObjectURL(blob);
  const a=document.createElement('a');
  a.href=url;a.download=`慢病管理_${type}_${today}.csv`;a.click();
  URL.revokeObjectURL(url);
  toast('📥 报表已下载','success');
}

function doExport(fmt){
  if(fmt==='csv'||fmt==='excel')exportData('patients');
  else toast(`${fmt.toUpperCase()} 格式报告（完整版功能）`,'info');
}

// ══════ TOAST ══════
function toast(msg,type='info'){
  const icons={success:'✅',error:'❌',warning:'⚠️',info:'ℹ️'};
  const el=document.createElement('div');
  el.className=`toast ${type}`;
  el.innerHTML=`<span>${icons[type]||'ℹ️'}</span><span>${msg}</span>`;
  document.getElementById('toast-wrap').appendChild(el);
  setTimeout(()=>{el.style.opacity='0';el.style.transition='opacity .3s';},3200);
  setTimeout(()=>el.remove(),3600);
}

// ══════ INIT ══════
(function init(){
  // Set default dates
  const d=new Date();
  document.getElementById('exp-end').value=today;
  const s=new Date();s.setMonth(s.getMonth()-1);
  document.getElementById('exp-start').value=fmtDate(s);
  document.getElementById('vt-date').value=today;
  document.getElementById('vt-time').value=new Date().toTimeString().slice(0,5);
  document.getElementById('fu-date').value=rndDate(7);

  populateSelects();
  renderDashboard();
  renderPatients();
  renderMedicine();

  // Close drawer on outside click
  document.addEventListener('click',e=>{
    const dw=document.getElementById('patient-drawer');
    if(dw.classList.contains('open')&&!dw.contains(e.target)&&!e.target.closest('[onclick*=openDrawer]'))closeDrawer();
  });

  // Reminder check every minute
  setInterval(()=>{
    const now=new Date();
    if(now.getSeconds()<15&&now.getMinutes()%15===0){
      toast('💊 用药提醒：有患者需要服药','warning');
    }
  },15000);
})();
</script>
</body>
</html>
