app.js · 约 8539 字符
1// 小草健康问诊 · 交互逻辑
2function docCard(d){
3 return `<div class="doc-card">
4 <div class="dc-avatar" style="background:${d.color}">${d.avatar}</div>
5 <div class="dc-info">
6 <div class="dc-name">${d.name} <span class="badge badge-hot" style="background:${d.color};color:var(--primary)">${d.title}</span></div>
7 <div class="dc-title">${d.dept} · ${d.desc}</div>
8 <div class="dc-tags">${d.tags.map(t=>'<span class="tag">'+t+'</span>').join('')}</div>
9 <div class="dc-foot">
10 <span class="dc-rate">👍 好评率 ${d.good}% · 已服务 ${d.sales} 人</span>
11 <button class="dc-btn" onclick="location.href='consult.html'">图文问诊</button>
12 </div>
13 </div>
14 </div>`;
15}
16
17// 首页
18let selSymptom = null;
19function renderIndex(){
20 document.getElementById('symptom-chips').innerHTML = SYMPTOMS.map(s=>`<span class="chip" onclick="pickSymptom(this,'${s}')">${s}</span>`).join('');
21 document.getElementById('doctor-list').innerHTML = DOCTORS.slice(0,3).map(docCard).join('');
22 document.getElementById('news-list').innerHTML = ARTICLES.map(a=>`
23 <div class="news-item" onclick="alert('📰 '+a.title)">
24 <div class="ni-img" style="background:${a.color}">${a.emoji}</div>
25 <div class="ni-info">
26 <div class="ni-title">${a.title}</div>
27 <div class="ni-meta">${a.cat} · ${a.reads}阅读 · ${a.time}</div>
28 </div>
29 </div>`).join('');
30}
31function pickSymptom(el,s){
32 document.querySelectorAll('.symptom-chips .chip').forEach(c=>c.classList.remove('active'));
33 el.classList.add('active'); selSymptom = s;
34 document.getElementById('sc-result').innerHTML = `✅ 已选择「${s}」<br>${SYMPTOM_MAP[s] || '建议就诊 全科门诊'}<br><a href="hospital.html" style="color:#fff;font-weight:600">立即去挂号 →</a>`;
35}
36
37// 医生列表
38let deptFilter = '全部', titleFilter = '全部';
39function renderDoctors(){
40 document.getElementById('dept-bar').innerHTML = DEPTS.map(d=>`<a href="javascript:void(0)" class="${d===deptFilter?'active':''}" onclick="setDept(this,'${d}')">${d}</a>`).join('');
41 let list = DOCTORS.filter(d=>(deptFilter==='全部'||d.dept===deptFilter) && (titleFilter==='全部'||d.title===titleFilter));
42 const el = document.getElementById('doctor-list');
43 el.innerHTML = list.length ? list.map(docCard).join('') : '<div class="empty"><div class="eicon">🩺</div><div>暂无匹配医生</div></div>';
44 document.querySelectorAll('#title-bar a').forEach(a=>{
45 a.classList.toggle('active', a.dataset.t===titleFilter);
46 a.style.color = a.dataset.t===titleFilter ? 'var(--primary)' : '#666';
47 a.style.borderBottom = a.dataset.t===titleFilter ? '2px solid var(--primary)' : 'none';
48 a.style.fontWeight = a.dataset.t===titleFilter ? '600' : '400';
49 });
50}
51function setDept(el,d){ deptFilter=d; renderDoctors(); }
52document.addEventListener('click', function(e){
53 const t = e.target.closest('#title-bar a');
54 if(t){ titleFilter = t.dataset.t; renderDoctors(); }
55});
56
57// 问诊聊天
58let chat = [...CHAT];
59let rxShown = false;
60function renderConsult(){
61 document.getElementById('chat-list').innerHTML = chat.map(c=>`
62 <div class="chat-item ${c.mine?'mine':'them'}">
63 <div class="ci-who">${c.who}</div>
64 <div class="ci-bubble">${c.text}</div>
65 </div>`).join('');
66 const rx = document.getElementById('rx-card');
67 if(rxShown){
68 rx.style.display = 'block';
69 document.getElementById('rx-list').innerHTML = RX.map(r=>`
70 <div class="rx-row"><span>💊 ${r.name}(${r.num})</span><span>${r.dose}</span></div>`).join('');
71 }
72 const input = document.getElementById('msg-input');
73 if(input) input.focus();
74}
75function sendMsg(){
76 const input = document.getElementById('msg-input');
77 const text = input.value.trim();
78 if(!text) return;
79 chat.push({who:'我', text, mine:true});
80 input.value = '';
81 renderConsult();
82 setTimeout(()=>{
83 chat.push({who:'医生 · 王志远', text:'收到,正在为您分析。根据描述建议注意休息,若症状加重请及时就医。已为您生成电子处方,可在线支付购药。', mine:false});
84 rxShown = true;
85 renderConsult();
86 }, 800);
87}
88function payRx(){ alert('🧾 电子处方支付\n\n订单金额:¥68.5\n药品:3种 · 支持配送上门(演示页)'); rxShown=false; renderConsult(); }
89
90// 挂号
91let selHosp = 0, selDate = 0, selSlot = null;
92function renderHospital(){
93 document.getElementById('hosp-list').innerHTML = HOSPITALS.map((h,i)=>`
94 <div class="hosp-card" onclick="pickHosp(${i})" style="border:${i===selHosp?'2px solid var(--primary)':'2px solid transparent'}">
95 <div class="hc-left">
96 <div class="hc-icon">${h.icon}</div>
97 <div><div class="hc-name">${h.name}</div><div class="hc-level">${h.level} · 剩余号源 ${h.num} 个</div></div>
98 </div>
99 <div class="hc-right"><div style="font-size:20px;color:${i===selHosp?'var(--primary)':'#ccc'}">${i===selHosp?'✓':'○'}</div></div>
100 </div>`).join('');
101 const days = ['今天','明天','周三','周四','周五','周六','周日'];
102 document.getElementById('date-row').innerHTML = days.map((d,i)=>{
103 const day = i + new Date().getDate();
104 return `<div class="date-cell ${i===selDate?'active':''}" onclick="pickDate(${i})">
105 <div class="d-week">${d}</div><div class="d-day">${String(day).padStart(2,'0')}</div>
106 </div>`;
107 }).join('');
108 document.getElementById('slot-list').innerHTML = SCHEDULE.map((s,i)=>`
109 <div class="slot-row">
110 <span class="sl-time">${s.time}</span>
111 <span class="sl-info">${s.avail>0?'剩余 '+s.avail+' 个号源':'已约满'}</span>
112 <button class="sl-btn ${s.avail>0?'avail':'sold'}" ${s.avail>0?'':'disabled'} onclick="pickSlot(${i})">${s.avail>0?(selSlot===i?'已选':'预约'):'约满'}</button>
113 </div>`).join('');
114}
115function pickHosp(i){ selHosp=i; renderHospital(); }
116function pickDate(i){ selDate=i; renderHospital(); }
117function pickSlot(i){ selSlot=i; renderHospital(); }
118function confirmBook(){
119 if(selSlot===null){ alert('请先选择就诊时段'); return; }
120 alert(`✅ 预约成功!\n\n${HOSPITALS[selHosp].name}\n${SCHEDULE[selSlot].time}\n就诊人:本人\n请提前15分钟到院取号(演示页)`);
121}
122
123// 用药与档案
124function renderMeds(){
125 document.getElementById('med-list').innerHTML = MEDS.map((m,i)=>`
126 <div class="med-card">
127 <div class="mc-icon">${m.icon}</div>
128 <div class="mc-info">
129 <div class="mc-name">${m.name}</div>
130 <div class="mc-dose">${m.dose}</div>
131 <div class="mc-time">⏰ ${m.time} 提醒</div>
132 </div>
133 <div class="switch ${m.on?'on':''}" onclick="toggleMed(${i},this)"></div>
134 </div>`).join('');
135 document.getElementById('health-grid').innerHTML = HEALTH.map(h=>`
136 <div class="health-card">
137 <div class="hc-val">${h.value}<small> ${h.unit}</small></div>
138 <div class="hc-label">${h.label}</div>
139 </div>`).join('');
140 document.getElementById('trend-card').innerHTML = `
141 <div style="font-size:13px;color:#666;margin-bottom:4px">${HEALTH[0].label} · 近7天</div>
142 <div class="trend-bar">${HEALTH[0].trend.map((v,i)=>{
143 const max = Math.max(...HEALTH[0].trend), min = Math.min(...HEALTH[0].trend);
144 const h = Math.max(10, Math.round(((v-min)/(max-min||1))*70));
145 return `<div class="tb-col"><div class="tb-bar" style="height:${h}px"></div><div class="tb-label">${i===6?'今天':'D'+(i+1)}</div></div>`;
146 }).join('')}</div>`;
147 document.getElementById('report-list').innerHTML = REPORTS.map(r=>`
148 <div class="report-item" onclick="alert('📄 '+r.name+'\n\n'+r.time+' · '+r.status)">
149 <div class="ri-icon">${r.icon}</div>
150 <div class="ri-info"><div class="ri-name">${r.name}</div><div class="ri-meta">${r.time}</div></div>
151 <span class="ri-status">${r.status} ›</span>
152 </div>`).join('');
153}
154function toggleMed(i,el){ el.classList.toggle('on'); alert(MEDS[i].on ? '⏰ 已开启「'+MEDS[i].name+'」提醒' : '🔕 已关闭「'+MEDS[i].name+'」提醒'); }
155
156// 我的
157function renderMine(){
158 document.getElementById('p-name').textContent = USER.name;
159 document.getElementById('p-level').textContent = USER.level;
160 document.getElementById('p-points').textContent = USER.points;
161 document.getElementById('p-records').textContent = USER.records;
162 document.getElementById('p-orders').textContent = USER.orders;
163}
164