Merge branch 'master' of https://gitea.rk-health.com/yixiong/platform-prototype
This commit is contained in:
+2
-2
@@ -872,8 +872,8 @@ const SITE_MAP = [
|
||||
{label:'扫码溯源', file:'trace-query.html'},
|
||||
{label:'溯源链路', file:'trace-detail.html'}
|
||||
] },
|
||||
{ name:'西安应急中心大屏', dir:'other-module/emergency-screen/xian-center', entry:'index-v3.html', pages:[
|
||||
{label:'应急中心大屏', file:'index-v3.html'}
|
||||
{ name:'西安应急中心大屏', dir:'other-module/emergency-screen/xian-center', entry:'index-v4.html', pages:[
|
||||
{label:'应急中心大屏', file:'index-v4.html'}
|
||||
] },
|
||||
{ name:'标准版中心大屏', dir:'other-module/emergency-screen/standard-center', pages:[] },
|
||||
{ name:'九厂应急中心大屏', dir:'other-module/emergency-screen/jiuchang-center', pages:[] },
|
||||
|
||||
@@ -0,0 +1,751 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||
<title>应急求助 - 西安应急中心大屏</title>
|
||||
<style>
|
||||
/* ========== CSS Variables ========== */
|
||||
:root{
|
||||
--primary:#1890FF; --success:#52C41A; --warning:#FAAD14; --danger:#FF4D4F;
|
||||
--text-main:#E0F0FF; --text-sub:#8CB8D9; --text-dim:#4A6B8A;
|
||||
--panel-bg:rgba(10,30,60,0.55); --panel-border:rgba(24,144,255,0.15);
|
||||
--map-bg:#071224; --cyan:#00e5ff;
|
||||
}
|
||||
|
||||
/* ========== Reset & Base ========== */
|
||||
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0;}
|
||||
html,body{width:100%;height:100%;overflow:hidden;font-family:'PingFang SC','Microsoft YaHei','Helvetica Neue',sans-serif;
|
||||
background:var(--map-bg);color:var(--text-main);}
|
||||
|
||||
/* ========== Background ========== */
|
||||
body::before{content:'';position:fixed;inset:0;z-index:-1;
|
||||
background:radial-gradient(ellipse at 50% 40%,rgba(24,144,255,0.06) 0%,transparent 60%),
|
||||
linear-gradient(180deg,#0a1620 0%,#071224 100%);}
|
||||
|
||||
/* ========== Header ========== */
|
||||
.header{position:relative;height:64px;display:flex;align-items:center;justify-content:center;z-index:10;
|
||||
background:linear-gradient(180deg,rgba(10,25,50,0.96),rgba(10,22,44,0.9));
|
||||
border-bottom:1px solid rgba(24,144,255,0.2);}
|
||||
.header::after{content:'';position:absolute;bottom:0;left:0;right:0;height:1px;
|
||||
background:linear-gradient(90deg,transparent,rgba(0,229,255,0.4),transparent);}
|
||||
.header__title{font-size:22px;font-weight:700;letter-spacing:4px;
|
||||
background:linear-gradient(180deg,#E0F0FF,#8CB8D9);-webkit-background-clip:text;-webkit-text-fill-color:transparent;}
|
||||
.header__scan-line{position:absolute;bottom:0;left:0;right:0;height:1px;
|
||||
background:linear-gradient(90deg,transparent,rgba(0,229,255,0.5),transparent);animation:scanLine 3s linear infinite;}
|
||||
@keyframes scanLine{0%{transform:translateX(-100%);}100%{transform:translateX(100%);}}
|
||||
|
||||
/* ========== Main Layout ========== */
|
||||
.main{position:relative;height:calc(100vh - 64px);overflow:hidden;}
|
||||
|
||||
/* ========== Red Alert Banner ========== */
|
||||
.alert-banner{position:absolute;top:16px;left:50%;transform:translateX(-50%);z-index:20;
|
||||
display:flex;align-items:center;gap:10px;padding:12px 28px;border-radius:10px;
|
||||
background:rgba(10,22,48,0.96);border:2px solid rgba(255,77,79,0.5);
|
||||
animation:modalAlertPulse 1.2s ease-in-out infinite;
|
||||
box-shadow:0 4px 24px rgba(255,77,79,0.2);}
|
||||
.alert-banner__icon{width:20px;height:20px;flex-shrink:0;color:var(--danger);}
|
||||
.alert-banner__text{font-size:15px;font-weight:600;color:var(--danger);white-space:nowrap;}
|
||||
.alert-banner__close{height:28px;padding:0 14px;border-radius:14px;font-size:12px;cursor:pointer;
|
||||
border:1px solid rgba(255,77,79,0.4);background:rgba(255,77,79,0.15);color:var(--danger);
|
||||
font-weight:500;transition:all .2s;white-space:nowrap;}
|
||||
.alert-banner__close:hover{background:rgba(255,77,79,0.28);box-shadow:0 0 10px rgba(255,77,79,0.25);}
|
||||
@keyframes modalAlertPulse{
|
||||
0%,100%{border-color:rgba(255,77,79,0.3);box-shadow:0 0 12px rgba(255,77,79,0.1);}
|
||||
50%{border-color:rgba(255,77,79,0.9);box-shadow:0 0 28px rgba(255,77,79,0.45);}
|
||||
}
|
||||
|
||||
/* ========== Left Drawer ========== */
|
||||
.drawer{position:absolute;top:0;left:0;bottom:0;width:370px;z-index:15;overflow-y:auto;
|
||||
padding:16px 12px;display:flex;flex-direction:column;gap:12px;
|
||||
background:linear-gradient(90deg,rgba(10,22,44,0.92),rgba(10,22,44,0.6),transparent);}
|
||||
.drawer::-webkit-scrollbar{width:3px;}
|
||||
.drawer::-webkit-scrollbar-thumb{background:rgba(255,77,79,0.2);border-radius:2px;}
|
||||
|
||||
/* Drawer panel - 爆红边框 */
|
||||
.drawer-panel{background:rgba(10,22,48,0.94);border:2px solid rgba(255,77,79,0.5);border-radius:10px;
|
||||
overflow:hidden;animation:modalAlertPulse 1.2s ease-in-out infinite;
|
||||
position:relative;display:flex;flex-direction:column;}
|
||||
.drawer-section{padding:12px 16px;}
|
||||
.drawer-section + .drawer-section{border-top:1px solid rgba(255,255,255,0.06);}
|
||||
.drawer-section__title{font-size:12px;font-weight:600;color:var(--text-main);margin-bottom:8px;
|
||||
padding-left:10px;border-left:3px solid var(--danger);letter-spacing:0.5px;}
|
||||
|
||||
/* Employee info grid */
|
||||
.info-grid{display:grid;grid-template-columns:1fr 1fr;gap:6px 16px;}
|
||||
.info-item{display:flex;flex-direction:column;gap:1px;}
|
||||
.info-item--full{grid-column:1/-1;}
|
||||
.info-label{font-size:10px;color:var(--text-dim);letter-spacing:0.5px;}
|
||||
.info-value{font-size:12px;color:var(--text-main);}
|
||||
.info-tag{display:inline-block;padding:2px 8px;border-radius:3px;font-size:10px;font-weight:600;}
|
||||
.info-tag--danger{background:rgba(255,77,79,0.15);color:var(--danger);}
|
||||
.info-tag--video{background:rgba(0,229,255,0.1);color:var(--cyan);}
|
||||
|
||||
/* Portrait card sections */
|
||||
.portrait-section{margin-bottom:10px;}
|
||||
.portrait-section:last-child{margin-bottom:0;}
|
||||
.portrait-section__title{font-size:10px;font-weight:600;color:var(--text-sub);margin-bottom:5px;
|
||||
padding-left:8px;border-left:2px solid var(--text-dim);letter-spacing:0.5px;}
|
||||
.portrait-pop-tag{display:inline-block;padding:2px 10px;border-radius:3px;font-size:10px;font-weight:600;
|
||||
background:rgba(255,77,79,0.12);color:var(--danger);margin-bottom:6px;}
|
||||
.portrait-row{font-size:11px;color:var(--text-sub);line-height:1.7;}
|
||||
.portrait-row b{color:var(--text-main);font-weight:500;}
|
||||
|
||||
/* Critical allergy / drug row - red highlighted */
|
||||
.portrait-alert{display:flex;align-items:flex-start;gap:6px;padding:6px 10px;border-radius:5px;
|
||||
background:rgba(255,77,79,0.06);border:1px solid rgba(255,77,79,0.15);font-size:11px;line-height:1.6;}
|
||||
.portrait-alert__icon{color:var(--danger);flex-shrink:0;margin-top:1px;}
|
||||
.portrait-alert__text{flex:1;}
|
||||
.portrait-alert__text b{color:var(--danger);}
|
||||
|
||||
/* Key-value row for basic info */
|
||||
.portrait-kv{display:grid;grid-template-columns:1fr 1fr;gap:4px 14px;}
|
||||
.portrait-kv__item{display:flex;gap:6px;font-size:10px;line-height:1.6;}
|
||||
.portrait-kv__label{color:var(--text-dim);flex-shrink:0;}
|
||||
.portrait-kv__value{color:var(--text-main);font-weight:500;}
|
||||
|
||||
/* Disease list with years */
|
||||
.portrait-disease-list{display:flex;flex-direction:column;gap:2px;}
|
||||
.portrait-disease-item{display:flex;align-items:center;gap:6px;font-size:10px;color:var(--text-sub);line-height:1.6;}
|
||||
.portrait-disease-item::before{content:'';width:4px;height:4px;border-radius:50%;background:var(--danger);flex-shrink:0;opacity:0.5;}
|
||||
.portrait-disease-item b{color:var(--text-main);font-weight:500;}
|
||||
|
||||
/* Exam collapsible */
|
||||
.m-exam{border:1px solid rgba(255,255,255,0.08);border-radius:5px;overflow:hidden;}
|
||||
.m-exam__header{display:flex;align-items:center;gap:8px;padding:5px 10px;cursor:pointer;
|
||||
background:rgba(255,255,255,0.02);transition:background .2s;}
|
||||
.m-exam__header:hover{background:rgba(255,255,255,0.04);}
|
||||
.m-exam__title{font-size:10px;color:var(--text-sub);flex:1;}
|
||||
.m-exam__count{font-size:9px;padding:0 6px;border-radius:6px;background:rgba(255,77,79,0.12);color:var(--danger);}
|
||||
.m-exam__arrow{width:10px;height:10px;color:var(--text-dim);transition:transform .2s;}
|
||||
.m-exam--open .m-exam__arrow{transform:rotate(90deg);}
|
||||
.m-exam__body{display:none;padding:5px 10px;border-top:1px solid rgba(255,255,255,0.06);}
|
||||
.m-exam--open .m-exam__body{display:block;}
|
||||
.m-exam__row{display:flex;justify-content:space-between;align-items:center;padding:2px 0;font-size:10px;}
|
||||
.m-exam__name{color:var(--text-dim);}
|
||||
.m-exam__val{color:var(--danger);}
|
||||
|
||||
/* Wearable alert list */
|
||||
.wearable-alerts{display:flex;flex-direction:column;gap:3px;}
|
||||
.wearable-alert-item{display:flex;align-items:center;gap:6px;font-size:10px;padding:3px 8px;
|
||||
background:rgba(255,255,255,0.02);border-radius:3px;border-left:2px solid var(--danger);}
|
||||
.wearable-alert-item__time{color:var(--text-dim);flex-shrink:0;}
|
||||
.wearable-alert-item__type{color:var(--danger);font-weight:500;}
|
||||
|
||||
/* ========== Map Area ========== */
|
||||
.map-wrap{position:absolute;inset:0;overflow:hidden;
|
||||
background:radial-gradient(ellipse at 50% 45%,rgba(24,144,255,0.05) 0%,transparent 55%),var(--map-bg);}
|
||||
/* Grid lines */
|
||||
.map-grid{position:absolute;inset:0;pointer-events:none;}
|
||||
.map-grid line{stroke:rgba(24,144,255,0.06);stroke-width:0.5;}
|
||||
.map-grid line.major{stroke:rgba(24,144,255,0.12);stroke-width:0.8;}
|
||||
|
||||
/* Map area labels */
|
||||
.map-area{position:absolute;font-size:9px;color:rgba(140,184,217,0.3);transform:translate(-50%,-50%);pointer-events:none;white-space:nowrap;}
|
||||
|
||||
/* Employee marker */
|
||||
.emp-marker{position:absolute;z-index:12;transform:translate(-50%,-100%);
|
||||
animation:empBounce 1s ease-in-out infinite;}
|
||||
@keyframes empBounce{0%,100%{transform:translate(-50%,-100%) translateY(0);}50%{transform:translate(-50%,-100%) translateY(-6px);}}
|
||||
.emp-marker__ripple{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);
|
||||
width:60px;height:60px;border-radius:50%;border:2px solid var(--danger);
|
||||
animation:empRipple 1.5s ease-out infinite;}
|
||||
.emp-marker__ripple:nth-child(2){animation-delay:0.5s;}
|
||||
.emp-marker__ripple:nth-child(3){animation-delay:1s;}
|
||||
@keyframes empRipple{0%{transform:translate(-50%,-50%) scale(0.5);opacity:1;}100%{transform:translate(-50%,-50%) scale(2.8);opacity:0;}}
|
||||
.emp-marker__pin{width:36px;height:46px;position:relative;z-index:2;}
|
||||
.emp-marker__label{position:absolute;top:-28px;left:50%;transform:translateX(-50%);white-space:nowrap;
|
||||
font-size:10px;font-weight:600;background:rgba(255,77,79,0.2);color:var(--danger);
|
||||
padding:2px 10px;border-radius:4px;border:1px solid rgba(255,77,79,0.35);}
|
||||
|
||||
/* Resource markers */
|
||||
.map-marker{position:absolute;transform:translate(-50%,-100%);cursor:pointer;z-index:5;transition:all .2s;}
|
||||
.map-marker:hover{transform:translate(-50%,-100%) scale(1.2);z-index:10;}
|
||||
.map-marker__pin{width:28px;height:36px;}
|
||||
.map-marker__label{position:absolute;top:-22px;left:50%;transform:translateX(-50%);white-space:nowrap;
|
||||
font-size:9px;background:rgba(0,0,0,0.75);color:#fff;padding:2px 7px;border-radius:3px;pointer-events:none;}
|
||||
.map-marker__pulse{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);
|
||||
width:40px;height:40px;border-radius:50%;animation:pulse 2s ease-out infinite;}
|
||||
@keyframes pulse{0%{transform:translate(-50%,-50%) scale(0.5);opacity:1;}100%{transform:translate(-50%,-50%) scale(2);opacity:0;}}
|
||||
.map-marker--active{filter:drop-shadow(0 0 6px rgba(0,229,255,0.7));z-index:9 !important;}
|
||||
.map-marker--active .map-marker__pulse{animation-duration:1s !important;}
|
||||
|
||||
/* Route SVG lines */
|
||||
.route-svg{position:absolute;inset:0;width:100%;height:100%;z-index:6;pointer-events:none;}
|
||||
.route-svg line{animation:routeDash 0.8s linear infinite;}
|
||||
.route-svg line.active{opacity:1 !important;stroke-width:0.5;}
|
||||
@keyframes routeDash{0%{stroke-dashoffset:0;}100%{stroke-dashoffset:-18;}}
|
||||
|
||||
/* ========== Resource Panel (Right) ========== */
|
||||
.res-panel{position:absolute;top:24px;right:12px;bottom:24px;width:230px;z-index:15;display:flex;flex-direction:column;
|
||||
background:rgba(10,25,55,0.94);border:1px solid var(--panel-border);border-radius:10px;overflow:hidden;}
|
||||
.res-panel::before{content:'';position:absolute;top:0;left:0;width:10px;height:10px;
|
||||
border-top:1.5px solid rgba(24,144,255,0.35);border-left:1.5px solid rgba(24,144,255,0.35);border-radius:10px 0 0 0;}
|
||||
.res-panel::after{content:'';position:absolute;bottom:0;right:0;width:10px;height:10px;
|
||||
border-bottom:1.5px solid rgba(24,144,255,0.35);border-right:1.5px solid rgba(24,144,255,0.35);border-radius:0 0 10px 0;}
|
||||
.res-panel__header{padding:14px 14px 10px;border-bottom:1px solid var(--panel-border);}
|
||||
.res-panel__title{font-size:13px;font-weight:600;color:var(--cyan);text-align:center;}
|
||||
.res-panel__list{flex:1;overflow-y:auto;padding:8px 10px;}
|
||||
.res-panel__list::-webkit-scrollbar{width:3px;}
|
||||
.res-panel__list::-webkit-scrollbar-thumb{background:rgba(24,144,255,0.2);border-radius:2px;}
|
||||
.res-panel__item{display:flex;align-items:flex-start;gap:8px;padding:10px 8px;border-radius:6px;
|
||||
cursor:pointer;transition:all .2s;border-bottom:1px solid rgba(24,144,255,0.06);}
|
||||
.res-panel__item:last-child{border-bottom:none;}
|
||||
.res-panel__item:hover{background:rgba(24,144,255,0.08);}
|
||||
.res-panel__item--active{background:rgba(24,144,255,0.12) !important;}
|
||||
.res-panel__item--active .res-panel__item-name{color:var(--cyan);}
|
||||
.res-panel__item-dot{width:10px;height:10px;border-radius:50%;flex-shrink:0;margin-top:2px;}
|
||||
.res-panel__item-info{flex:1;min-width:0;}
|
||||
.res-panel__item-name{font-size:11px;color:var(--text-main);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
|
||||
.res-panel__item-cat{font-size:9px;color:var(--text-dim);margin-left:4px;}
|
||||
.res-panel__item-meta{font-size:10px;color:var(--text-dim);margin-top:2px;display:flex;gap:8px;}
|
||||
.res-panel__item-phone{font-size:10px;color:var(--cyan);margin-top:1px;font-weight:500;}
|
||||
|
||||
/* ========== Ambulance Support Panel ========== */
|
||||
.amb-panel{position:absolute;top:24px;right:256px;bottom:24px;width:240px;z-index:15;display:flex;flex-direction:column;
|
||||
background:rgba(10,25,55,0.94);border:1px solid rgba(250,173,20,0.4);border-radius:10px;overflow:hidden;
|
||||
animation:ambPanelPulse 2s ease-in-out infinite;}
|
||||
@keyframes ambPanelPulse{0%,100%{border-color:rgba(250,173,20,0.3);box-shadow:0 0 8px rgba(250,173,20,0.08);}
|
||||
50%{border-color:rgba(250,173,20,0.8);box-shadow:0 0 18px rgba(250,173,20,0.25);}}
|
||||
.amb-panel::before{content:'';position:absolute;top:0;left:0;width:10px;height:10px;
|
||||
border-top:1.5px solid rgba(250,173,20,0.4);border-left:1.5px solid rgba(250,173,20,0.4);border-radius:10px 0 0 0;}
|
||||
.amb-panel::after{content:'';position:absolute;bottom:0;right:0;width:10px;height:10px;
|
||||
border-bottom:1.5px solid rgba(250,173,20,0.4);border-right:1.5px solid rgba(250,173,20,0.4);border-radius:0 0 10px 0;}
|
||||
.amb-panel__header{display:flex;align-items:center;gap:8px;padding:12px 14px 10px;
|
||||
border-bottom:1px solid rgba(250,173,20,0.2);}
|
||||
.amb-panel__icon{width:20px;height:20px;color:var(--warning);flex-shrink:0;}
|
||||
.amb-panel__title{font-size:14px;font-weight:700;color:var(--warning);}
|
||||
.amb-panel__body{flex:1;overflow-y:auto;padding:12px 14px;}
|
||||
.amb-panel__body::-webkit-scrollbar{width:3px;}
|
||||
.amb-panel__body::-webkit-scrollbar-thumb{background:rgba(250,173,20,0.2);border-radius:2px;}
|
||||
.amb-panel__status{font-size:12px;font-weight:600;color:var(--success);margin-bottom:12px;
|
||||
display:flex;align-items:center;gap:5px;}
|
||||
.amb-panel__status::before{content:'';width:6px;height:6px;border-radius:50%;
|
||||
background:var(--success);box-shadow:0 0 6px var(--success);animation:pulse 2s ease-out infinite;}
|
||||
.amb-panel__section{margin-bottom:12px;}
|
||||
.amb-panel__section-title{font-size:11px;font-weight:600;color:var(--warning);margin-bottom:6px;
|
||||
padding-left:8px;border-left:3px solid var(--warning);}
|
||||
.amb-panel__row{display:flex;justify-content:space-between;align-items:center;padding:3px 0;font-size:11px;}
|
||||
.amb-panel__row-label{color:var(--text-dim);flex-shrink:0;}
|
||||
.amb-panel__row-value{color:var(--text-main);text-align:right;font-weight:500;}
|
||||
.amb-panel__eta{text-align:center;padding:12px 0 4px;font-size:20px;font-weight:700;color:#fff;
|
||||
text-shadow:0 0 12px rgba(250,173,20,0.5);}
|
||||
.amb-panel__eta-label{text-align:center;font-size:10px;color:var(--text-dim);margin-bottom:8px;}
|
||||
|
||||
/* Dispatched ambulance marker */
|
||||
.amb-marker{position:absolute;z-index:11;transform:translate(-50%,-100%);transition:all 2s ease;}
|
||||
.amb-marker__pin{width:30px;height:38px;}
|
||||
.amb-marker__label{position:absolute;top:-24px;left:50%;transform:translateX(-50%);white-space:nowrap;
|
||||
font-size:9px;font-weight:600;background:rgba(250,173,20,0.25);color:var(--warning);
|
||||
padding:2px 8px;border-radius:3px;border:1px solid rgba(250,173,20,0.35);}
|
||||
.amb-route{stroke:#FAAD14;stroke-width:0.5;stroke-dasharray:3 2;opacity:0.6;
|
||||
animation:routeDash 0.6s linear infinite;}
|
||||
|
||||
/* ========== Marker Tooltip ========== */
|
||||
.marker-popup{position:absolute;z-index:25;display:none;
|
||||
background:rgba(10,22,48,0.97);border:1px solid var(--panel-border);border-radius:8px;
|
||||
padding:10px 14px;min-width:180px;max-width:240px;pointer-events:none;
|
||||
box-shadow:0 4px 20px rgba(0,0,0,0.5),0 0 12px rgba(24,144,255,0.15);
|
||||
transform:translate(-50%,-100%);}
|
||||
.marker-popup::after{content:'';position:absolute;bottom:-6px;left:50%;transform:translateX(-50%);
|
||||
width:0;height:0;border-left:6px solid transparent;border-right:6px solid transparent;
|
||||
border-top:6px solid rgba(10,22,48,0.97);}
|
||||
.marker-popup--show{display:block;animation:popupFadeIn .2s ease;}
|
||||
@keyframes popupFadeIn{0%{opacity:0;transform:translate(-50%,calc(-100% - 6px));}100%{opacity:1;transform:translate(-50%,-100%);}}
|
||||
.marker-popup__name{font-size:13px;font-weight:600;color:var(--text-main);margin-bottom:4px;}
|
||||
.marker-popup__cat{font-size:10px;color:var(--text-dim);margin-bottom:6px;}
|
||||
.marker-popup__cat span{display:inline-block;width:8px;height:8px;border-radius:50%;margin-right:4px;vertical-align:middle;}
|
||||
.marker-popup__label{font-size:10px;color:var(--text-dim);margin-bottom:2px;letter-spacing:0.5px;}
|
||||
.marker-popup__addr{font-size:11px;color:var(--text-sub);line-height:1.5;margin-bottom:2px;}
|
||||
.marker-popup__phone{font-size:12px;color:var(--cyan);font-weight:600;}
|
||||
|
||||
/* ========== Toast ========== */
|
||||
.toast{position:fixed;top:80px;left:50%;transform:translateX(-50%);z-index:200;display:none;
|
||||
align-items:center;gap:8px;padding:10px 24px;border-radius:8px;font-size:13px;font-weight:500;
|
||||
background:rgba(10,22,48,0.96);border:1px solid;white-space:nowrap;}
|
||||
.toast--show{display:flex;animation:popupFadeIn .25s ease;}
|
||||
.toast--danger{border-color:var(--danger);box-shadow:0 6px 24px rgba(0,0,0,0.45),0 0 16px rgba(255,77,79,0.28);}
|
||||
.toast__dot{width:8px;height:8px;border-radius:50%;flex-shrink:0;}
|
||||
.toast--danger .toast__dot{background:var(--danger);box-shadow:0 0 8px var(--danger);}
|
||||
|
||||
/* ========== Floor plan overview ========== */
|
||||
.floor-plan{position:absolute;bottom:20px;left:50%;transform:translateX(-50%);z-index:10;
|
||||
display:flex;align-items:center;gap:16px;padding:8px 20px;border-radius:20px;
|
||||
background:rgba(10,22,48,0.85);border:1px solid var(--panel-border);
|
||||
font-size:10px;color:var(--text-sub);pointer-events:none;}
|
||||
.floor-plan__dot{width:6px;height:6px;border-radius:50%;}
|
||||
.floor-plan__dot--emp{background:var(--danger);box-shadow:0 0 6px var(--danger);}
|
||||
.floor-plan__item{display:flex;align-items:center;gap:4px;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- ========== Header ========== -->
|
||||
<header class="header">
|
||||
<div class="header__title">西安应急中心大屏</div>
|
||||
<div class="header__scan-line"></div>
|
||||
</header>
|
||||
|
||||
<!-- ========== Main ========== -->
|
||||
<div class="main">
|
||||
<!-- Alert Banner -->
|
||||
<div class="alert-banner">
|
||||
<svg class="alert-banner__icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<circle cx="12" cy="12" r="10"/>
|
||||
<path d="M12 8v4M12 16h.01"/>
|
||||
</svg>
|
||||
<span class="alert-banner__text">请注意,有员工发起应急求助</span>
|
||||
<button class="alert-banner__close" onclick="goBack()">关闭</button>
|
||||
</div>
|
||||
|
||||
<!-- Left Drawer -->
|
||||
<div class="drawer" id="drawer">
|
||||
<div class="drawer-panel">
|
||||
<!-- Section A: Employee Info -->
|
||||
<div class="drawer-section">
|
||||
<div class="drawer-section__title">员工信息</div>
|
||||
<div class="info-grid">
|
||||
<div class="info-item"><span class="info-label">姓名</span><span class="info-value">周丽华</span></div>
|
||||
<div class="info-item"><span class="info-label">性别</span><span class="info-value">女</span></div>
|
||||
<div class="info-item"><span class="info-label">年龄</span><span class="info-value">33岁</span></div>
|
||||
<div class="info-item"><span class="info-label">员工编号</span><span class="info-value">BH-2019-0521</span></div>
|
||||
<div class="info-item"><span class="info-label">手机号码</span><span class="info-value">13991358267</span></div>
|
||||
<div class="info-item"><span class="info-label">单位部门</span><span class="info-value">宝石花医院护理部</span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Section B: Event Info -->
|
||||
<div class="drawer-section">
|
||||
<div class="drawer-section__title">事件信息</div>
|
||||
<div class="info-grid">
|
||||
<div class="info-item">
|
||||
<span class="info-label">求助类型</span>
|
||||
<span class="info-value"><span class="info-tag info-tag--video">应急视频</span></span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">求助状态</span>
|
||||
<span class="info-value"><span class="info-tag info-tag--danger">待处理</span></span>
|
||||
</div>
|
||||
<div class="info-item info-item--full">
|
||||
<span class="info-label">求助时间</span>
|
||||
<span class="info-value">2026-06-23 14:48:35</span>
|
||||
</div>
|
||||
<div class="info-item info-item--full">
|
||||
<span class="info-label">详细地址</span>
|
||||
<span class="info-value">宝石花医院护理部大楼3层302室</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Section C: Person Portrait -->
|
||||
<div class="drawer-section">
|
||||
<div class="drawer-section__title">人物画像</div>
|
||||
|
||||
<!-- 1. 五类人群 -->
|
||||
<div class="portrait-section">
|
||||
<div class="portrait-section__title">五类人群</div>
|
||||
<div class="portrait-pop-tag">大病人群(心脑血管病)</div>
|
||||
</div>
|
||||
|
||||
<!-- 2. ⚠️ 过敏史(急救最优先) -->
|
||||
<div class="portrait-section">
|
||||
<div class="portrait-section__title">⚠️ 过敏史</div>
|
||||
<div class="portrait-alert">
|
||||
<svg class="portrait-alert__icon" width="14" height="14" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5"><path d="M8 1.5L15 14H1L8 1.5z"/><path d="M8 6v2.5M8 11.5h.01"/></svg>
|
||||
<div class="portrait-alert__text">
|
||||
<div>过敏史:<b>青霉素(过敏性休克)</b></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 3. 既往史 & 手术史 -->
|
||||
<div class="portrait-section">
|
||||
<div class="portrait-section__title">既往史</div>
|
||||
<div class="portrait-disease-list">
|
||||
<div class="portrait-disease-item"><b>冠心病</b>(2021年确诊,支架植入术后)</div>
|
||||
<div class="portrait-disease-item"><b>高血压</b>病史 5年,最高 180/110</div>
|
||||
<div class="portrait-disease-item"><b>2型糖尿病</b> 2年</div>
|
||||
<div class="portrait-disease-item"><b>手术史</b>:冠脉支架×2(2021.03)</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 4. 体检异常指标(可折叠) -->
|
||||
<div class="portrait-section">
|
||||
<div class="portrait-section__title">体检异常指标</div>
|
||||
<div class="m-exam" id="portraitExam">
|
||||
<div class="m-exam__header" onclick="togglePortraitExam()">
|
||||
<span class="m-exam__title">共4项异常</span>
|
||||
<span class="m-exam__count">4</span>
|
||||
<svg class="m-exam__arrow" viewBox="0 0 12 12" fill="none"><path d="M4 2.5L8 6 4 9.5" stroke="currentColor" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||
</div>
|
||||
<div class="m-exam__body">
|
||||
<div class="m-exam__row"><span class="m-exam__name">血压</span><span class="m-exam__val">偏高 148/95 mmHg</span></div>
|
||||
<div class="m-exam__row"><span class="m-exam__name">尿酸</span><span class="m-exam__val">偏高 520 μmol/L</span></div>
|
||||
<div class="m-exam__row"><span class="m-exam__name">血脂</span><span class="m-exam__val">异常 总胆固醇 6.8 mmol/L</span></div>
|
||||
<div class="m-exam__row"><span class="m-exam__name">血糖</span><span class="m-exam__val">偏高 7.2 mmol/L</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 5. 穿戴异常告警(可折叠) -->
|
||||
<div class="portrait-section">
|
||||
<div class="portrait-section__title">穿戴 · 近期异常告警</div>
|
||||
<div class="m-exam" id="portraitWearable">
|
||||
<div class="m-exam__header" onclick="togglePortraitWearable()">
|
||||
<span class="m-exam__title">共3次告警</span>
|
||||
<span class="m-exam__count">3</span>
|
||||
<svg class="m-exam__arrow" viewBox="0 0 12 12" fill="none"><path d="M4 2.5L8 6 4 9.5" stroke="currentColor" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||
</div>
|
||||
<div class="m-exam__body">
|
||||
<div class="wearable-alerts">
|
||||
<div class="wearable-alert-item">
|
||||
<span class="wearable-alert-item__time">06-23 14:32</span>
|
||||
<span class="wearable-alert-item__type">摔倒</span>
|
||||
</div>
|
||||
<div class="wearable-alert-item">
|
||||
<span class="wearable-alert-item__time">06-20 09:15</span>
|
||||
<span class="wearable-alert-item__type">心率异常 142bpm</span>
|
||||
</div>
|
||||
<div class="wearable-alert-item">
|
||||
<span class="wearable-alert-item__time">06-18 21:40</span>
|
||||
<span class="wearable-alert-item__type">血氧异常 89%</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 6. 基本体征 + 紧急联系人 -->
|
||||
<div class="portrait-section">
|
||||
<div class="portrait-section__title">基本体征</div>
|
||||
<div class="portrait-kv">
|
||||
<div class="portrait-kv__item"><span class="portrait-kv__label">血型</span><span class="portrait-kv__value">B 型 Rh(+)</span></div>
|
||||
<div class="portrait-kv__item"><span class="portrait-kv__label">身高</span><span class="portrait-kv__value">162 cm</span></div>
|
||||
<div class="portrait-kv__item"><span class="portrait-kv__label">体重</span><span class="portrait-kv__value">68 kg</span></div>
|
||||
<div class="portrait-kv__item"><span class="portrait-kv__label">BMI</span><span class="portrait-kv__value" style="color:var(--warning);">25.9</span></div>
|
||||
</div>
|
||||
<div style="margin-top:6px;font-size:10px;color:var(--text-dim);">
|
||||
紧急联系人:<span style="color:var(--cyan);font-weight:500;">李建国(配偶)</span> · <span style="color:var(--cyan);">139 9120 3368</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ========== Map ========== -->
|
||||
<div class="map-wrap" id="mapWrap" onclick="onMapClick(event)">
|
||||
<!-- Grid -->
|
||||
<svg class="map-grid" viewBox="0 0 100 100" preserveAspectRatio="none">
|
||||
<line x1="0" y1="25" x2="100" y2="25" class="major"/>
|
||||
<line x1="0" y1="50" x2="100" y2="50" class="major"/>
|
||||
<line x1="0" y1="75" x2="100" y2="75" class="major"/>
|
||||
<line x1="25" y1="0" x2="25" y2="100" class="major"/>
|
||||
<line x1="50" y1="0" x2="50" y2="100" class="major"/>
|
||||
<line x1="75" y1="0" x2="75" y2="100" class="major"/>
|
||||
</svg>
|
||||
|
||||
<!-- Area labels -->
|
||||
<div class="map-area" style="top:25%;left:30%;">宝石花医院</div>
|
||||
<div class="map-area" style="top:70%;left:60%;">庆阳医院</div>
|
||||
<div class="map-area" style="top:25%;left:12%;">兴隆医院</div>
|
||||
<div class="map-area" style="top:40%;left:35%;">采油一厂</div>
|
||||
<div class="map-area" style="top:50%;left:75%;">采油二厂</div>
|
||||
|
||||
<!-- Route SVG -->
|
||||
<svg class="route-svg" id="routeSvg" viewBox="0 0 100 100" preserveAspectRatio="none">
|
||||
<line id="routeHospital1" x1="50" y1="50" x2="30" y2="25" stroke="#1890FF" stroke-width="0.3" stroke-dasharray="1.5 0.8" opacity="0"/>
|
||||
<line id="routeHospital2" x1="50" y1="50" x2="75" y2="22" stroke="#722ED1" stroke-width="0.3" stroke-dasharray="1.5 0.8" opacity="0"/>
|
||||
<line id="routeHospital3" x1="50" y1="50" x2="60" y2="70" stroke="#1890FF" stroke-width="0.3" stroke-dasharray="2 1" opacity="0"/>
|
||||
<line id="routeClinic" x1="50" y1="50" x2="35" y2="40" stroke="#13C2C2" stroke-width="0.3" stroke-dasharray="1 0.8" opacity="0"/>
|
||||
<line id="routeAmbulance" x1="50" y1="50" x2="28" y2="65" stroke="#FAAD14" stroke-width="0.3" stroke-dasharray="1.2 0.8" opacity="0"/>
|
||||
<line id="routeAed" x1="50" y1="50" x2="42" y2="28" stroke="#FF4D4F" stroke-width="0.3" stroke-dasharray="0.8 0.8" opacity="0"/>
|
||||
<line id="routeFirstaid" x1="50" y1="50" x2="55" y2="72" stroke="#52C41A" stroke-width="0.3" stroke-dasharray="1.2 0.8" opacity="0"/>
|
||||
<!-- 派遣救护车路线 -->
|
||||
<line class="amb-route" x1="18" y1="15" x2="50" y2="50"/>
|
||||
</svg>
|
||||
|
||||
<!-- Employee marker -->
|
||||
<div class="emp-marker" style="top:50%;left:50%;">
|
||||
<div class="emp-marker__ripple"></div>
|
||||
<div class="emp-marker__ripple"></div>
|
||||
<div class="emp-marker__ripple"></div>
|
||||
<svg class="emp-marker__pin" viewBox="0 0 36 46" fill="none">
|
||||
<path d="M18 2C11 2 5 8 5 15c0 14 13 29 13 29s13-15 13-29c0-7-6-13-13-13z" fill="#FF4D4F" stroke="#fff" stroke-width="1.8"/>
|
||||
<circle cx="18" cy="15" r="6" fill="#fff"/>
|
||||
<circle cx="18" cy="15" r="3.5" fill="#FF4D4F"/>
|
||||
</svg>
|
||||
<div class="emp-marker__label">周丽华 · 当前位置</div>
|
||||
</div>
|
||||
|
||||
<!-- Resource markers -->
|
||||
<!-- 兴隆医院 -->
|
||||
<div class="map-marker" style="top:25%;left:30%;" data-key="hospital1" onclick="onMarkerClick(this,'hospital1');event.stopPropagation();">
|
||||
<div class="map-marker__pulse" style="background:rgba(24,144,255,0.2);"></div>
|
||||
<svg class="map-marker__pin" viewBox="0 0 28 36" fill="none"><path d="M14 2C8 2 3 7 3 13c0 10 11 21 11 21s11-11 11-21c0-6-5-11-11-11z" fill="#1890FF" stroke="#fff" stroke-width="1.5"/><path d="M10 13h8M14 9v8" stroke="#fff" stroke-width="2" stroke-linecap="round"/></svg>
|
||||
<div class="map-marker__label">兴隆医院</div>
|
||||
</div>
|
||||
<!-- 宝石花医院 -->
|
||||
<div class="map-marker" style="top:22%;left:75%;" data-key="hospital2" onclick="onMarkerClick(this,'hospital2');event.stopPropagation();">
|
||||
<div class="map-marker__pulse" style="background:rgba(114,46,209,0.2);"></div>
|
||||
<svg class="map-marker__pin" viewBox="0 0 28 36" fill="none"><path d="M14 2C8 2 3 7 3 13c0 10 11 21 11 21s11-11 11-21c0-6-5-11-11-11z" fill="#722ED1" stroke="#fff" stroke-width="1.5"/><path d="M10 13h8M14 9v8" stroke="#fff" stroke-width="2" stroke-linecap="round"/></svg>
|
||||
<div class="map-marker__label">宝石花医院</div>
|
||||
</div>
|
||||
<!-- 庆阳医院 -->
|
||||
<div class="map-marker" style="top:70%;left:60%;" data-key="hospital3" onclick="onMarkerClick(this,'hospital3');event.stopPropagation();">
|
||||
<div class="map-marker__pulse" style="background:rgba(24,144,255,0.2);"></div>
|
||||
<svg class="map-marker__pin" viewBox="0 0 28 36" fill="none"><path d="M14 2C8 2 3 7 3 13c0 10 11 21 11 21s11-11 11-21c0-6-5-11-11-11z" fill="#1890FF" stroke="#fff" stroke-width="1.5"/><path d="M10 13h8M14 9v8" stroke="#fff" stroke-width="2" stroke-linecap="round"/></svg>
|
||||
<div class="map-marker__label">庆阳医院</div>
|
||||
</div>
|
||||
<!-- 采油一厂医疗点 -->
|
||||
<div class="map-marker" style="top:40%;left:35%;" data-key="clinic" onclick="onMarkerClick(this,'clinic');event.stopPropagation();">
|
||||
<div class="map-marker__pulse" style="background:rgba(19,194,194,0.2);"></div>
|
||||
<svg class="map-marker__pin" viewBox="0 0 28 36" fill="none"><path d="M14 2C8 2 3 7 3 13c0 10 11 21 11 21s11-11 11-21c0-6-5-11-11-11z" fill="#13C2C2" stroke="#fff" stroke-width="1.5"/><rect x="9" y="11" width="10" height="6" rx="1" fill="#fff"/><path d="M12 14h4" stroke="#13C2C2" stroke-width="1.5"/></svg>
|
||||
<div class="map-marker__label">采油一厂医疗点</div>
|
||||
</div>
|
||||
<!-- 救护车 -->
|
||||
<div class="map-marker" style="top:65%;left:28%;" data-key="ambulance" onclick="onMarkerClick(this,'ambulance');event.stopPropagation();">
|
||||
<div class="map-marker__pulse" style="background:rgba(250,173,20,0.2);"></div>
|
||||
<svg class="map-marker__pin" viewBox="0 0 28 36" fill="none"><path d="M14 2C8 2 3 7 3 13c0 10 11 21 11 21s11-11 11-21c0-6-5-11-11-11z" fill="#FAAD14" stroke="#fff" stroke-width="1.5"/><rect x="8" y="10" width="12" height="6" rx="1" fill="#fff"/><path d="M10 13h2M16 13h2" stroke="#FAAD14" stroke-width="1.5"/></svg>
|
||||
<div class="map-marker__label">陕A·120-03</div>
|
||||
</div>
|
||||
<!-- AED -->
|
||||
<div class="map-marker" style="top:28%;left:42%;" data-key="aed" onclick="onMarkerClick(this,'aed');event.stopPropagation();">
|
||||
<div class="map-marker__pulse" style="background:rgba(255,77,79,0.2);"></div>
|
||||
<svg class="map-marker__pin" viewBox="0 0 28 36" fill="none"><path d="M14 2C8 2 3 7 3 13c0 10 11 21 11 21s11-11 11-21c0-6-5-11-11-11z" fill="#FF4D4F" stroke="#fff" stroke-width="1.5"/><path d="M14 8l2 4 4 1-3 3 1 4-4-2-4 2 1-4-3-3 4-1z" fill="#fff"/></svg>
|
||||
<div class="map-marker__label">AED-001</div>
|
||||
</div>
|
||||
<!-- 派遣救护车(实时位置) -->
|
||||
<div class="amb-marker" style="top:15%;left:18%;" id="ambDispatchMarker">
|
||||
<svg class="amb-marker__pin" viewBox="0 0 30 38" fill="none">
|
||||
<path d="M15 2C8 2 2 7 2 13c0 11 13 23 13 23s13-12 13-23c0-6-6-11-13-11z" fill="#FAAD14" stroke="#fff" stroke-width="1.5"/>
|
||||
<rect x="6" y="9" width="18" height="8" rx="2" fill="#fff"/>
|
||||
<path d="M8 11h3M19 11h3" stroke="#FAAD14" stroke-width="1.5"/>
|
||||
<path d="M12 13h6" stroke="#FAAD14" stroke-width="1"/>
|
||||
</svg>
|
||||
<div class="amb-marker__label">🚑 陕A·120-03(赶往中)</div>
|
||||
</div>
|
||||
|
||||
<!-- 急救包 -->
|
||||
<div class="map-marker" style="top:72%;left:55%;" data-key="firstaid" onclick="onMarkerClick(this,'firstaid');event.stopPropagation();">
|
||||
<div class="map-marker__pulse" style="background:rgba(82,196,26,0.2);"></div>
|
||||
<svg class="map-marker__pin" viewBox="0 0 28 36" fill="none"><path d="M14 2C8 2 3 7 3 13c0 10 11 21 11 21s11-11 11-21c0-6-5-11-11-11z" fill="#52C41A" stroke="#fff" stroke-width="1.5"/><rect x="7" y="10" width="14" height="10" rx="2" fill="#fff"/><path d="M11 13h2M15 13h2" stroke="#52C41A" stroke-width="1.5"/><path d="M13.5 11v2M12 12h3" stroke="#52C41A" stroke-width="1"/></svg>
|
||||
<div class="map-marker__label">急救包-001</div>
|
||||
</div>
|
||||
|
||||
<!-- Marker Popup -->
|
||||
<div class="marker-popup" id="markerPopup">
|
||||
<div class="marker-popup__name" id="popupName"></div>
|
||||
<div class="marker-popup__cat" id="popupCat"></div>
|
||||
<div class="marker-popup__label">所属单位</div>
|
||||
<div class="marker-popup__addr" id="popupUnit"></div>
|
||||
<div class="marker-popup__label" id="popupD1Label" style="display:none;"></div>
|
||||
<div class="marker-popup__addr" id="popupD1" style="display:none;"></div>
|
||||
<div class="marker-popup__label">详细地址</div>
|
||||
<div class="marker-popup__addr" id="popupAddr"></div>
|
||||
<div class="marker-popup__label">联系电话</div>
|
||||
<div class="marker-popup__phone" id="popupPhone"></div>
|
||||
</div>
|
||||
|
||||
<!-- Floor plan indicator -->
|
||||
<div class="floor-plan">
|
||||
<div class="floor-plan__item"><span class="floor-plan__dot floor-plan__dot--emp"></span> 员工位置</div>
|
||||
<span style="color:rgba(24,144,255,0.2);">|</span>
|
||||
<span>护理部大楼 3层 302室</span>
|
||||
<span style="color:rgba(24,144,255,0.2);">|</span>
|
||||
<span>宝石花医院院区</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ========== Ambulance Support Panel ========== -->
|
||||
<div class="amb-panel" id="ambPanel">
|
||||
<div class="amb-panel__header">
|
||||
<svg class="amb-panel__icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M3 17V7a2 2 0 012-2h9v8h7"/>
|
||||
<path d="M3 17h18"/>
|
||||
<circle cx="7.5" cy="17.5" r="2"/>
|
||||
<circle cx="17.5" cy="17.5" r="2"/>
|
||||
<path d="M15 8h4l2 3v4"/>
|
||||
</svg>
|
||||
<span class="amb-panel__title">救护车支援</span>
|
||||
</div>
|
||||
<div class="amb-panel__body">
|
||||
<div class="amb-panel__status">已派救护车前往支援</div>
|
||||
|
||||
<div class="amb-panel__section">
|
||||
<div class="amb-panel__section-title">🚑 救护车信息</div>
|
||||
<div class="amb-panel__row"><span class="amb-panel__row-label">车牌号</span><span class="amb-panel__row-value">陕A·120-03</span></div>
|
||||
<div class="amb-panel__row"><span class="amb-panel__row-label">所属医院</span><span class="amb-panel__row-value">兴隆医院</span></div>
|
||||
<div class="amb-panel__row"><span class="amb-panel__row-label">驾驶员</span><span class="amb-panel__row-value">赵刚</span></div>
|
||||
<div class="amb-panel__row"><span class="amb-panel__row-label">驾驶员电话</span><span class="amb-panel__row-value" style="color:var(--cyan);">138 9192 0816</span></div>
|
||||
</div>
|
||||
|
||||
<div class="amb-panel__section">
|
||||
<div class="amb-panel__section-title">👨⚕️ 随车信息</div>
|
||||
<div class="amb-panel__row"><span class="amb-panel__row-label">随行人</span><span class="amb-panel__row-value">李明辉(急救医生)</span></div>
|
||||
<div class="amb-panel__row"><span class="amb-panel__row-label">随行人电话</span><span class="amb-panel__row-value" style="color:var(--cyan);">139 9120 5578</span></div>
|
||||
<div class="amb-panel__row"><span class="amb-panel__row-label">目的地</span><span class="amb-panel__row-value">宝石花医院护理部大楼</span></div>
|
||||
<div class="amb-panel__row"><span class="amb-panel__row-label">备注</span><span class="amb-panel__row-value">已携带心电监护仪、除颤仪</span></div>
|
||||
</div>
|
||||
|
||||
<div class="amb-panel__eta-label">预计到达时间</div>
|
||||
<div class="amb-panel__eta">约 7 分钟</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ========== Right Resource Panel ========== -->
|
||||
<div class="res-panel" id="resPanel">
|
||||
<div class="res-panel__header">
|
||||
<div class="res-panel__title">就近急救资源</div>
|
||||
</div>
|
||||
<div class="res-panel__list" id="resList">
|
||||
<!-- Filled by JS -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Toast -->
|
||||
<div class="toast" id="toast">
|
||||
<span class="toast__dot"></span>
|
||||
<span id="toastMsg"></span>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
/* ========== Data ========== */
|
||||
var RESOURCE_DATA = {
|
||||
hospital1: {name:'兴隆医院', cat:'油田医院',catColor:'#1890FF',unit:'兴隆医院',addr:'西安市高陵区兴隆路88号门诊楼',phone:'029-8696 5120', dist:'2.4 km',time:'约8分钟'},
|
||||
hospital2: {name:'宝石花医院', cat:'合作医院',catColor:'#722ED1',unit:'宝石花医院',addr:'西安市高陵区宝石花大道126号综合楼',phone:'029-8671 9120', dist:'5.2 km',time:'约15分钟'},
|
||||
hospital3: {name:'庆阳医院', cat:'地方医院',catColor:'#1890FF',unit:'庆阳医院',addr:'甘肃省庆阳市庆城县北大街55号急诊楼',phone:'0934-3212 0120', dist:'3.6 km',time:'约11分钟'},
|
||||
clinic: {name:'采油一厂医疗点',cat:'医疗点',catColor:'#13C2C2',unit:'采油一厂',addr:'采油一厂生产基地综合楼1层医疗点',phone:'029-8696 8001', dist:'0.3 km',time:'约1分钟'},
|
||||
ambulance: {name:'陕A·120-03', cat:'救护车',catColor:'#FAAD14',unit:'兴隆医院',addr:'兴隆医院急救站停车场,24小时待命',phone:'189 9120 6603', dist:'2.2 km',time:'约7分钟'},
|
||||
aed: {name:'AED-001', cat:'AED设备',catColor:'#FF4D4F',unit:'采油一厂',addr:'采油一厂生产区B区办公楼大厅东侧走廊',phone:'138 9192 0086', dist:'0.5 km',time:'约2分钟'},
|
||||
firstaid: {name:'急救包-001', cat:'急救包',catColor:'#52C41A',unit:'采油一厂',addr:'采油一厂生产区B区办公楼大厅东侧走廊',phone:'138 9192 0091', dist:'0.8 km',time:'约3分钟', d1Label:'急救物品',d1:'止血带×5、创可贴×20、碘伏棉签×10、三角巾×2'}
|
||||
};
|
||||
|
||||
var ROUTE_LINE_IDS = {
|
||||
hospital1:'routeHospital1', hospital2:'routeHospital2', hospital3:'routeHospital3',
|
||||
clinic:'routeClinic', ambulance:'routeAmbulance', aed:'routeAed', firstaid:'routeFirstaid'
|
||||
};
|
||||
|
||||
var currentActiveKey = null;
|
||||
|
||||
/* ========== Build Resource List ========== */
|
||||
(function buildResList(){
|
||||
var list = document.getElementById('resList');
|
||||
var keys = ['clinic','aed','firstaid','ambulance','hospital1','hospital3','hospital2'];
|
||||
keys.forEach(function(key){
|
||||
var d = RESOURCE_DATA[key];
|
||||
var item = document.createElement('div');
|
||||
item.className = 'res-panel__item';
|
||||
item.setAttribute('data-key', key);
|
||||
item.onclick = function(){ selectResource(key); };
|
||||
item.innerHTML =
|
||||
'<div class="res-panel__item-dot" style="background:'+d.catColor+';box-shadow:0 0 6px '+d.catColor+';"></div>'+
|
||||
'<div class="res-panel__item-info">'+
|
||||
'<div class="res-panel__item-name">'+d.name+'<span class="res-panel__item-cat">'+d.cat+'</span></div>'+
|
||||
'<div class="res-panel__item-meta"><span>'+d.dist+'</span><span>'+d.time+'</span></div>'+
|
||||
'<div class="res-panel__item-phone">☎ '+d.phone+'</div>'+
|
||||
'</div>';
|
||||
list.appendChild(item);
|
||||
});
|
||||
})();
|
||||
|
||||
/* ========== Select Resource ========== */
|
||||
function selectResource(key){
|
||||
// Reset previous
|
||||
if(currentActiveKey){
|
||||
var prevLine = document.getElementById(ROUTE_LINE_IDS[currentActiveKey]);
|
||||
if(prevLine) prevLine.classList.remove('active');
|
||||
var prevMarker = document.querySelector('.map-marker[data-key="'+currentActiveKey+'"]');
|
||||
if(prevMarker) prevMarker.classList.remove('map-marker--active');
|
||||
var prevItem = document.querySelector('.res-panel__item[data-key="'+currentActiveKey+'"]');
|
||||
if(prevItem) prevItem.classList.remove('res-panel__item--active');
|
||||
}
|
||||
|
||||
if(currentActiveKey === key){ currentActiveKey = null; return; }
|
||||
|
||||
// Activate new
|
||||
var line = document.getElementById(ROUTE_LINE_IDS[key]);
|
||||
if(line) line.classList.add('active');
|
||||
var marker = document.querySelector('.map-marker[data-key="'+key+'"]');
|
||||
if(marker) marker.classList.add('map-marker--active');
|
||||
var item = document.querySelector('.res-panel__item[data-key="'+key+'"]');
|
||||
if(item) item.classList.add('res-panel__item--active');
|
||||
|
||||
currentActiveKey = key;
|
||||
|
||||
// Show tooltip
|
||||
var d = RESOURCE_DATA[key];
|
||||
var mEl = document.querySelector('.map-marker[data-key="'+key+'"]');
|
||||
if(mEl && d) showPopup(mEl, d);
|
||||
}
|
||||
|
||||
/* ========== Marker Click ========== */
|
||||
function onMarkerClick(el, key){
|
||||
selectResource(key);
|
||||
}
|
||||
|
||||
/* ========== Map Click (deselect) ========== */
|
||||
function onMapClick(e){
|
||||
if(e.target.closest('.map-marker')) return;
|
||||
hidePopup();
|
||||
if(currentActiveKey){
|
||||
var line = document.getElementById(ROUTE_LINE_IDS[currentActiveKey]);
|
||||
if(line) line.classList.remove('active');
|
||||
var marker = document.querySelector('.map-marker[data-key="'+currentActiveKey+'"]');
|
||||
if(marker) marker.classList.remove('map-marker--active');
|
||||
var item = document.querySelector('.res-panel__item[data-key="'+currentActiveKey+'"]');
|
||||
if(item) item.classList.remove('res-panel__item--active');
|
||||
currentActiveKey = null;
|
||||
}
|
||||
}
|
||||
|
||||
/* ========== Popup ========== */
|
||||
function showPopup(el, d){
|
||||
var popup = document.getElementById('markerPopup');
|
||||
var rect = el.getBoundingClientRect();
|
||||
var mapWrap = document.getElementById('mapWrap');
|
||||
var mapRect = mapWrap.getBoundingClientRect();
|
||||
popup.style.top = (rect.top - mapRect.top - 10) + 'px';
|
||||
popup.style.left = (rect.left - mapRect.left + rect.width/2) + 'px';
|
||||
document.getElementById('popupName').textContent = d.name;
|
||||
document.getElementById('popupCat').innerHTML = '<span style="background:'+d.catColor+';box-shadow:0 0 6px '+d.catColor+';"></span>'+d.cat;
|
||||
document.getElementById('popupUnit').textContent = d.unit||'--';
|
||||
document.getElementById('popupAddr').textContent = d.addr||'--';
|
||||
document.getElementById('popupPhone').textContent = d.phone||'--';
|
||||
// D1 row (e.g. 急救物品)
|
||||
var d1Label = document.getElementById('popupD1Label');
|
||||
var d1Val = document.getElementById('popupD1');
|
||||
if(d1Label && d1Val){
|
||||
if(d.d1Label){
|
||||
d1Label.style.display = ''; d1Val.style.display = '';
|
||||
d1Label.textContent = d.d1Label; d1Val.textContent = d.d1;
|
||||
}else{
|
||||
d1Label.style.display = 'none'; d1Val.style.display = 'none';
|
||||
}
|
||||
}
|
||||
popup.classList.add('marker-popup--show');
|
||||
}
|
||||
|
||||
function hidePopup(){
|
||||
document.getElementById('markerPopup').classList.remove('marker-popup--show');
|
||||
}
|
||||
|
||||
/* ========== Portrait Exam Toggle ========== */
|
||||
function togglePortraitExam(){
|
||||
var el = document.getElementById('portraitExam');
|
||||
el.classList.toggle('m-exam--open');
|
||||
}
|
||||
|
||||
function togglePortraitWearable(){
|
||||
var el = document.getElementById('portraitWearable');
|
||||
el.classList.toggle('m-exam--open');
|
||||
}
|
||||
|
||||
/* ========== Go Back ========== */
|
||||
function goBack(){
|
||||
window.location.href = 'index-v4.html';
|
||||
}
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user