fix: 更新健康监测模块页面与文档,新增静态服务配置
@@ -75,6 +75,14 @@ body { font-family: -apple-system, BlinkMacSystemFont, 'PingFang SC', 'Helvetica
|
||||
<img id="lightbox-img" src="" alt="放大预览">
|
||||
</div>
|
||||
<script>
|
||||
/* ===== file:// 协议 → 自动跳转到本地服务器 ===== */
|
||||
(function() {
|
||||
if (location.protocol === 'file:') {
|
||||
var search = location.search; /* 保留 ?file=...&title=... 参数 */
|
||||
location.href = 'http://localhost:8080/_templates/md-viewer.html' + search;
|
||||
}
|
||||
})();
|
||||
|
||||
const params = new URLSearchParams(location.search);
|
||||
const filePath = params.get('file');
|
||||
const title = params.get('title');
|
||||
@@ -113,7 +121,8 @@ if (title) {
|
||||
}
|
||||
if (filePath) {
|
||||
document.getElementById('doc-path').textContent = filePath;
|
||||
fetch(filePath)
|
||||
/* 用绝对路径(/ 开头),避免 <base href="../"> 在不同浏览器中解析不一致 */
|
||||
fetch('/' + filePath)
|
||||
.then(res => {
|
||||
if (!res.ok) throw new Error('文件未找到 (' + res.status + ')');
|
||||
return res.text();
|
||||
@@ -203,7 +212,7 @@ if (filePath) {
|
||||
content.querySelectorAll('img').forEach(img => {
|
||||
const src = img.getAttribute('src');
|
||||
if (src && !src.startsWith('http') && !src.startsWith('/') && !src.startsWith('data:')) {
|
||||
img.src = mdBase + src;
|
||||
img.src = '/' + mdBase + src;
|
||||
}
|
||||
});
|
||||
/* 绑定图片点击放大 */
|
||||
|
||||
@@ -149,10 +149,40 @@ body { background: var(--background); font-family: -apple-system, BlinkMacSystem
|
||||
.prd-item__status { font-size: 11px; padding: 2px 8px; border-radius: 10px; font-weight: 600; flex-shrink: 0; }
|
||||
.prd-item__status--ready { background: var(--green-light); color: #389e0d; border: 1px solid var(--green-border); }
|
||||
.prd-item__status--empty { background: #fffbe6; color: #d48806; border: 1px solid #ffe58f; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="header">
|
||||
|
||||
/* ===== file:// 协议 - 全屏启动遮罩 ===== */
|
||||
.launch-overlay { display: none; position: fixed; inset: 0; z-index: 99999; background: rgba(15,23,42,0.85); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); flex-direction: column; align-items: center; justify-content: center; font-family: -apple-system,BlinkMacSystemFont,'PingFang SC','Helvetica Neue','Segoe UI',sans-serif; }
|
||||
.launch-overlay--show { display: flex; }
|
||||
.launch-card { background: #fff; border-radius: 20px; padding: 40px 48px; text-align: center; box-shadow: 0 24px 80px rgba(0,0,0,0.4); max-width: 480px; width: 90%; animation: popIn .35s ease; }
|
||||
.launch-card__icon { width: 64px; height: 64px; border-radius: 50%; background: linear-gradient(135deg, #1677FF, #4facfe); display: flex; align-items: center; justify-content: center; margin: 0 auto 20px; font-size: 32px; color: #fff; }
|
||||
.launch-card__icon--ok { background: linear-gradient(135deg, #52c41a, #95de64); }
|
||||
.launch-card__title { font-size: 20px; font-weight: 700; color: #1a1a2e; margin-bottom: 8px; }
|
||||
.launch-card__sub { font-size: 14px; color: #5a607f; margin-bottom: 24px; line-height: 1.6; }
|
||||
.launch-card__btn { display: inline-flex; align-items: center; gap: 8px; padding: 12px 32px; font-size: 15px; font-weight: 600; color: #fff; background: linear-gradient(135deg, #1677FF, #4facfe); border: none; border-radius: 12px; cursor: pointer; text-decoration: none; transition: all .2s; box-shadow: 0 4px 16px rgba(22,119,255,0.35); }
|
||||
.launch-card__btn:hover { transform: translateY(-1px); box-shadow: 0 8px 24px rgba(22,119,255,0.45); }
|
||||
.launch-card__btn--outline { background: #fff; color: var(--primary); border: 1.5px solid var(--primary); box-shadow: none; }
|
||||
.launch-card__btn--outline:hover { background: var(--primary-light); box-shadow: 0 4px 12px rgba(22,119,255,0.15); }
|
||||
.launch-card__status { margin-top: 16px; font-size: 13px; color: var(--text-placeholder); }
|
||||
.launch-card__spinner { display: inline-block; width: 16px; height: 16px; border: 2px solid #e8ecf1; border-top-color: var(--primary); border-radius: 50%; animation: spin .7s linear infinite; vertical-align: middle; margin-right: 6px; }
|
||||
@keyframes spin { to { transform: rotate(360deg); } }
|
||||
.launch-card__actions { display: flex; gap: 10px; justify-content: center; flex-wrap: wrap; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- 本地服务器启动遮罩 -->
|
||||
<div class="launch-overlay" id="launch-overlay">
|
||||
<div class="launch-card">
|
||||
<div class="launch-card__icon" id="launch-icon">🚀</div>
|
||||
<div class="launch-card__title" id="launch-title">需要启动本地服务器</div>
|
||||
<div class="launch-card__sub" id="launch-sub">PRD文档预览等功能需要本地HTTP服务器</div>
|
||||
<div class="launch-card__actions" id="launch-actions">
|
||||
<a class="launch-card__btn" href="启动服务器.bat">⚡ 一键启动</a>
|
||||
<a class="launch-card__btn launch-card__btn--outline" href="http://localhost:8080/index.html">📖 直接打开原型</a>
|
||||
</div>
|
||||
<div class="launch-card__status" id="launch-status"><span class="launch-card__spinner"></span>等待服务器就绪...</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="header">
|
||||
<div class="header__inner">
|
||||
<div class="header__title">健康CQ升级项目 · 高保真交互原型</div>
|
||||
<div class="header__sub">点击模块卡片跳转至对应模块主页,点击页数徽章查看全部页面,点击PRD文档在线预览详细功能说明</div>
|
||||
@@ -162,8 +192,90 @@ body { background: var(--background); font-family: -apple-system, BlinkMacSystem
|
||||
<div class="main-content">
|
||||
<div id="tab-contents"></div>
|
||||
</div>
|
||||
<script>
|
||||
/* ===== SVG 图标 ===== */
|
||||
<script>
|
||||
/* ===== file:// 协议检测 & 服务器自动启动 ===== */
|
||||
(function() {
|
||||
if (location.protocol !== 'file:') return; /* 非 file:// 协议,无需处理 */
|
||||
|
||||
var overlay = document.getElementById('launch-overlay');
|
||||
var launchIcon = document.getElementById('launch-icon');
|
||||
var launchTitle = document.getElementById('launch-title');
|
||||
var launchSub = document.getElementById('launch-sub');
|
||||
var launchStatus = document.getElementById('launch-status');
|
||||
var launchActions = document.getElementById('launch-actions');
|
||||
|
||||
/* 步骤1: 先静默检测服务器是否已在运行(不显示遮罩) */
|
||||
function checkServer(callback) {
|
||||
var iframe = document.createElement('iframe');
|
||||
iframe.style.display = 'none';
|
||||
iframe.src = 'http://localhost:8080/index.html';
|
||||
var done = false;
|
||||
var t = setTimeout(function() {
|
||||
if (!done) { done = true; callback(false); }
|
||||
}, 2000);
|
||||
iframe.onload = function() {
|
||||
if (!done) { done = true; clearTimeout(t); callback(true); }
|
||||
};
|
||||
iframe.onerror = function() {
|
||||
if (!done) { done = true; clearTimeout(t); callback(false); }
|
||||
};
|
||||
document.body.appendChild(iframe);
|
||||
}
|
||||
|
||||
/* 步骤2: 服务器已运行 → 无感跳转 */
|
||||
function redirectToServer() {
|
||||
location.replace('http://localhost:8080/index.html');
|
||||
}
|
||||
|
||||
/* 步骤3: 显示遮罩 + 轮询 */
|
||||
function showOverlay() {
|
||||
overlay.classList.add('launch-overlay--show');
|
||||
launchIcon.textContent = '🚀';
|
||||
launchIcon.className = 'launch-card__icon';
|
||||
launchTitle.textContent = '需要启动本地服务器';
|
||||
launchSub.textContent = 'PRD文档预览等功能需要本地HTTP服务器,请双击项目根目录下的 启动服务器.bat';
|
||||
launchStatus.innerHTML = '<span class="launch-card__spinner"></span>等待服务器就绪...';
|
||||
launchActions.innerHTML = '<a class="launch-card__btn" href="启动服务器.bat">⚡ 一键启动</a> <a class="launch-card__btn launch-card__btn--outline" href="http://localhost:8080/index.html">📖 直接打开原型</a>';
|
||||
|
||||
/* 轮询:每2秒检测一次,最多30次(60秒) */
|
||||
var attempts = 0;
|
||||
var pollTimer = setInterval(function() {
|
||||
attempts++;
|
||||
checkServer(function(ok) {
|
||||
if (ok) {
|
||||
clearInterval(pollTimer);
|
||||
launchIcon.textContent = '✅';
|
||||
launchIcon.className = 'launch-card__icon launch-card__icon--ok';
|
||||
launchTitle.textContent = '服务器已就绪';
|
||||
launchSub.textContent = '即将自动跳转...';
|
||||
launchStatus.innerHTML = '<a href="http://localhost:8080/index.html" style="color:var(--primary)">立即跳转</a>';
|
||||
launchActions.innerHTML = '<a class="launch-card__btn launch-card__btn--outline" href="http://localhost:8080/index.html">📖 打开原型导航</a>';
|
||||
setTimeout(redirectToServer, 500);
|
||||
}
|
||||
});
|
||||
if (attempts >= 30) {
|
||||
clearInterval(pollTimer);
|
||||
launchTitle.textContent = '未检测到服务器';
|
||||
launchSub.textContent = '请确认 启动服务器.bat 已运行,然后刷新页面';
|
||||
launchStatus.innerHTML = '⏱ 等待超时(60秒)';
|
||||
launchActions.innerHTML = '<button class="launch-card__btn" onclick="location.reload()">🔄 刷新重试</button>';
|
||||
}
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
/* === 主流程:先静默检测 === */
|
||||
checkServer(function(running) {
|
||||
if (running) {
|
||||
/* 服务器已在运行 → 直接跳转,用户全程无感 */
|
||||
redirectToServer();
|
||||
} else {
|
||||
/* 服务器未运行 → 显示遮罩引导手动启动 */
|
||||
showOverlay();
|
||||
}
|
||||
});
|
||||
})();
|
||||
|
||||
/* ===== SVG 图标 ===== */
|
||||
const ICONS = {
|
||||
web: '<svg class="tab-nav__icon" viewBox="0 0 18 18" fill="none"><rect x="1" y="2" width="16" height="12" rx="2" stroke="currentColor" stroke-width="1.5"/><line x1="5" y1="16" x2="13" y2="16" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/><line x1="9" y1="14" x2="9" y2="16" stroke="currentColor" stroke-width="1.5"/></svg>',
|
||||
app: '<svg class="tab-nav__icon" viewBox="0 0 18 18" fill="none"><rect x="4" y="1" width="10" height="16" rx="2" stroke="currentColor" stroke-width="1.5"/><line x1="7.5" y1="14" x2="10.5" y2="14" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>',
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"cleanUrls": false,
|
||||
"directoryListing": false,
|
||||
"rewrites": [
|
||||
{ "source": "/", "destination": "/index.html" }
|
||||
]
|
||||
}
|
||||
@@ -69,11 +69,18 @@ tbody tr:hover{background:#F8FBFF;}
|
||||
.pagination span{font-size:var(--font-sm);color:var(--text-secondary);}
|
||||
.page-btn{width:32px;height:32px;border:1px solid var(--border);border-radius:var(--radius-sm);background:#fff;cursor:pointer;font-size:var(--font-sm);display:inline-flex;align-items:center;justify-content:center;transition:all .2s;}
|
||||
.page-btn:hover,.page-btn.active{background:var(--primary);color:#fff;border-color:var(--primary);}
|
||||
.detail-title{font-size:var(--font-lg);font-weight:600;margin-bottom:4px;}
|
||||
.detail-meta{font-size:var(--font-sm);color:var(--text-secondary);margin-bottom:16px;}
|
||||
.empty-state{text-align:center;padding:40px 20px;color:var(--text-placeholder);}
|
||||
.empty-state svg{width:64px;height:64px;margin-bottom:12px;opacity:0.3;}
|
||||
.empty-state__title{font-size:var(--font-sm);color:var(--text-secondary);}
|
||||
/* 单位信息卡片 */
|
||||
.info-card{background:#fff;border-radius:var(--radius-md);box-shadow:var(--shadow-sm);padding:24px;margin-bottom:16px;display:flex;align-items:center;gap:32px;}
|
||||
.info-card__avatar{width:56px;height:56px;border-radius:50%;background:var(--primary);color:#fff;display:flex;align-items:center;justify-content:center;font-size:20px;font-weight:600;flex-shrink:0;}
|
||||
.info-card__detail{display:flex;flex-direction:column;gap:6px;}
|
||||
.info-card__name{font-size:var(--font-lg);font-weight:600;color:var(--text-primary);}
|
||||
.info-card__meta{display:flex;gap:24px;font-size:var(--font-sm);color:var(--text-secondary);}
|
||||
.info-card__right{flex-shrink:0;margin-left:auto;}
|
||||
.info-card__date-filter{display:flex;align-items:center;gap:8px;}
|
||||
.info-card__date-filter label{font-size:var(--font-xs);color:var(--text-secondary);white-space:nowrap;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -126,16 +133,33 @@ tbody tr:hover{background:#F8FBFF;}
|
||||
<span class="sep">/</span>
|
||||
<span>健康现状</span>
|
||||
</div>
|
||||
<div class="detail-title" id="detailTitle"></div>
|
||||
<div class="detail-meta" id="detailMeta"></div>
|
||||
<!-- 单位信息卡片 -->
|
||||
<div class="info-card">
|
||||
<div class="info-card__detail">
|
||||
<div class="info-card__name" id="unitName">采油一厂</div>
|
||||
<div class="info-card__meta">
|
||||
<span id="unitTotal">总人数:1280</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="info-card__right">
|
||||
<div class="info-card__date-filter">
|
||||
<label>年份</label>
|
||||
<select class="filter-select" id="filterYear" onchange="onYearChange()" style="height:32px;min-width:110px;font-size:var(--font-xs);">
|
||||
<option value="2026">2026年</option>
|
||||
<option value="2025">2025年</option>
|
||||
<option value="2024">2024年</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Tab 切换 -->
|
||||
<div class="tab-bar">
|
||||
<div class="tab-item active" onclick="switchTab('a',this)">A类(人数)</div>
|
||||
<div class="tab-item" onclick="switchTab('b',this)">B类(人数)</div>
|
||||
<div class="tab-item" onclick="switchTab('c',this)">C类(人数)</div>
|
||||
<div class="tab-item" onclick="switchTab('d',this)">D类(人数)</div>
|
||||
<div class="tab-item" onclick="switchTab('e',this)">E类(人数)</div>
|
||||
<div class="tab-item active" onclick="switchTab('a',this)">A类(768)</div>
|
||||
<div class="tab-item" onclick="switchTab('b',this)">B类(256)</div>
|
||||
<div class="tab-item" onclick="switchTab('c',this)">C类(128)</div>
|
||||
<div class="tab-item" onclick="switchTab('d',this)">D类(89)</div>
|
||||
<div class="tab-item" onclick="switchTab('e',this)">E类(39)</div>
|
||||
</div>
|
||||
|
||||
<!-- A类面板 -->
|
||||
@@ -511,15 +535,22 @@ function resetPanel(cat) {
|
||||
renderPanel(cat, empData[cat]);
|
||||
}
|
||||
|
||||
/* ===== 年份切换 ===== */
|
||||
var currentYear = '2026';
|
||||
function onYearChange(){
|
||||
currentYear = document.getElementById('filterYear').value;
|
||||
// 可根据年份刷新页面数据
|
||||
}
|
||||
|
||||
/* ===== 初始化 ===== */
|
||||
(function() {
|
||||
var unit = getUrlParam('unit') || '采油一厂';
|
||||
var dept = getUrlParam('dept') || '';
|
||||
var displayName = unit + (dept ? ' - ' + dept : '');
|
||||
|
||||
document.getElementById('unitDept').textContent = displayName;
|
||||
document.getElementById('detailTitle').textContent = displayName + ' — 健康现状 详情';
|
||||
document.getElementById('detailMeta').textContent = '2026年 · A类768人 · B类256人 · C类128人 · D类89人 · E类39人';
|
||||
document.getElementById('unitDept').textContent = displayName;
|
||||
document.getElementById('unitName').textContent = displayName;
|
||||
document.getElementById('unitTotal').textContent = '总人数:1280';
|
||||
|
||||
// 渲染所有面板
|
||||
['a','b','c','d','e'].forEach(function(cat) { renderPanel(cat); });
|
||||
|
||||
@@ -63,8 +63,15 @@ tbody tr:hover{background:#F8FBFF;}
|
||||
.pagination span{font-size:var(--font-sm);color:var(--text-secondary);}
|
||||
.page-btn{width:32px;height:32px;border:1px solid var(--border);border-radius:var(--radius-sm);background:#fff;cursor:pointer;font-size:var(--font-sm);display:inline-flex;align-items:center;justify-content:center;transition:all .2s;}
|
||||
.page-btn:hover,.page-btn.active{background:var(--primary);color:#fff;border-color:var(--primary);}
|
||||
.detail-title{font-size:var(--font-lg);font-weight:600;margin-bottom:4px;}
|
||||
.detail-meta{font-size:var(--font-sm);color:var(--text-secondary);margin-bottom:16px;}
|
||||
/* 单位信息卡片 */
|
||||
.info-card{background:#fff;border-radius:var(--radius-md);box-shadow:var(--shadow-sm);padding:24px;margin-bottom:16px;display:flex;align-items:center;gap:32px;}
|
||||
.info-card__avatar{width:56px;height:56px;border-radius:50%;background:var(--primary);color:#fff;display:flex;align-items:center;justify-content:center;font-size:20px;font-weight:600;flex-shrink:0;}
|
||||
.info-card__detail{display:flex;flex-direction:column;gap:6px;}
|
||||
.info-card__name{font-size:var(--font-lg);font-weight:600;color:var(--text-primary);}
|
||||
.info-card__meta{display:flex;gap:24px;font-size:var(--font-sm);color:var(--text-secondary);}
|
||||
.info-card__right{flex-shrink:0;margin-left:auto;}
|
||||
.info-card__date-filter{display:flex;align-items:center;gap:8px;}
|
||||
.info-card__date-filter label{font-size:var(--font-xs);color:var(--text-secondary);white-space:nowrap;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -117,16 +124,33 @@ tbody tr:hover{background:#F8FBFF;}
|
||||
<span class="sep">/</span>
|
||||
<span>健康环境</span>
|
||||
</div>
|
||||
<div class="detail-title" id="detailTitle"></div>
|
||||
<div class="detail-meta" id="detailMeta"></div>
|
||||
<!-- 单位信息卡片 -->
|
||||
<div class="info-card">
|
||||
<div class="info-card__detail">
|
||||
<div class="info-card__name" id="unitName">采油一厂</div>
|
||||
<div class="info-card__meta">
|
||||
<span id="unitTotal">设备总数:39</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="info-card__right">
|
||||
<div class="info-card__date-filter">
|
||||
<label>年份</label>
|
||||
<select class="filter-select" id="filterYear" onchange="onYearChange()" style="height:32px;min-width:110px;font-size:var(--font-xs);">
|
||||
<option value="2026">2026年</option>
|
||||
<option value="2025">2025年</option>
|
||||
<option value="2024">2024年</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- [交互] Tab 切换 -->
|
||||
<div class="tab-bar">
|
||||
<div class="tab-item active" onclick="switchTab('indoor',this)">室内设备</div>
|
||||
<div class="tab-item" onclick="switchTab('outdoor',this)">室外设备</div>
|
||||
<div class="tab-item" onclick="switchTab('water',this)">水质设备</div>
|
||||
<div class="tab-item" onclick="switchTab('pollen',this)">花粉设备</div>
|
||||
<div class="tab-item" onclick="switchTab('alarm',this)">报警次数</div>
|
||||
<div class="tab-item active" onclick="switchTab('indoor',this)">室内设备(24)</div>
|
||||
<div class="tab-item" onclick="switchTab('outdoor',this)">室外设备(8)</div>
|
||||
<div class="tab-item" onclick="switchTab('water',this)">水质设备(5)</div>
|
||||
<div class="tab-item" onclick="switchTab('pollen',this)">花粉设备(2)</div>
|
||||
<div class="tab-item" onclick="switchTab('alarm',this)">报警次数(12)</div>
|
||||
</div>
|
||||
|
||||
<!-- 室内设备面板 -->
|
||||
@@ -495,13 +519,20 @@ function switchTab(tabName, elem) {
|
||||
document.getElementById('panel-' + tabName).classList.add('active');
|
||||
}
|
||||
|
||||
/* ===== 年份切换 ===== */
|
||||
var currentYear = '2026';
|
||||
function onYearChange(){
|
||||
currentYear = document.getElementById('filterYear').value;
|
||||
// 可根据年份刷新页面数据
|
||||
}
|
||||
|
||||
var unit = getUrlParam('unit') || '采油一厂';
|
||||
var dept = getUrlParam('dept') || '';
|
||||
var displayName = unit + (dept ? ' - ' + dept : '');
|
||||
|
||||
document.getElementById('unitDept').textContent = displayName;
|
||||
document.getElementById('detailTitle').textContent = displayName + ' — 健康环境 详情';
|
||||
document.getElementById('detailMeta').textContent = '2026年 · 设备总数 39';
|
||||
document.getElementById('unitName').textContent = displayName;
|
||||
document.getElementById('unitTotal').textContent = '设备总数:39';
|
||||
|
||||
// 根据URL参数自动切换tab
|
||||
var tab = getUrlParam('tab');
|
||||
|
||||
@@ -70,6 +70,15 @@ tbody tr:hover{background:#F8FBFF;}
|
||||
.empty-state{text-align:center;padding:40px 20px;color:var(--text-placeholder);}
|
||||
.empty-state svg{width:64px;height:64px;margin-bottom:12px;opacity:0.3;}
|
||||
.empty-state__title{font-size:var(--font-sm);color:var(--text-secondary);}
|
||||
/* 单位信息卡片 */
|
||||
.info-card{background:#fff;border-radius:var(--radius-md);box-shadow:var(--shadow-sm);padding:24px;margin-bottom:16px;display:flex;align-items:center;gap:32px;}
|
||||
.info-card__avatar{width:56px;height:56px;border-radius:50%;background:var(--primary);color:#fff;display:flex;align-items:center;justify-content:center;font-size:20px;font-weight:600;flex-shrink:0;}
|
||||
.info-card__detail{display:flex;flex-direction:column;gap:6px;}
|
||||
.info-card__name{font-size:var(--font-lg);font-weight:600;color:var(--text-primary);}
|
||||
.info-card__meta{display:flex;gap:24px;font-size:var(--font-sm);color:var(--text-secondary);}
|
||||
.info-card__right{flex-shrink:0;margin-left:auto;}
|
||||
.info-card__date-filter{display:flex;align-items:center;gap:8px;}
|
||||
.info-card__date-filter label{font-size:var(--font-xs);color:var(--text-secondary);white-space:nowrap;}
|
||||
/* 弹窗 */
|
||||
.modal-mask{position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0.45);z-index:500;display:flex;align-items:center;justify-content:center;opacity:0;pointer-events:none;transition:opacity .15s;}
|
||||
.modal-mask.show{opacity:1;pointer-events:auto;}
|
||||
@@ -135,10 +144,30 @@ tbody tr:hover{background:#F8FBFF;}
|
||||
<span>健康排查详情</span>
|
||||
</div>
|
||||
|
||||
<!-- 单位信息卡片 -->
|
||||
<div class="info-card">
|
||||
<div class="info-card__detail">
|
||||
<div class="info-card__name" id="unitName">采油一厂</div>
|
||||
<div class="info-card__meta">
|
||||
<span id="unitTotal">排查活动:5个</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="info-card__right">
|
||||
<div class="info-card__date-filter">
|
||||
<label>年份</label>
|
||||
<select class="filter-select" id="filterYear" onchange="onYearChange()" style="height:32px;min-width:110px;font-size:var(--font-xs);">
|
||||
<option value="2026">2026年</option>
|
||||
<option value="2025">2025年</option>
|
||||
<option value="2024">2024年</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Tab 切换 -->
|
||||
<div class="tab-bar">
|
||||
<div class="tab-item active" onclick="switchTab('activity-list',this)">活动列表</div>
|
||||
<div class="tab-item" onclick="switchTab('pending-emp',this)">未参加员工</div>
|
||||
<div class="tab-item active" onclick="switchTab('activity-list',this)">活动列表(5)</div>
|
||||
<div class="tab-item" onclick="switchTab('pending-emp',this)">未参加员工(8)</div>
|
||||
</div>
|
||||
|
||||
<!-- Tab1: 活动列表 -->
|
||||
@@ -731,14 +760,24 @@ function resetPendingEmpFilter(){
|
||||
renderPendingEmpTable(buildPendingEmpList());
|
||||
}
|
||||
|
||||
/* ===== 年份切换 ===== */
|
||||
var currentYear = '2026';
|
||||
function onYearChange(){
|
||||
currentYear = document.getElementById('filterYear').value;
|
||||
// 可根据年份刷新页面数据
|
||||
}
|
||||
|
||||
/* ===== 初始化 ===== */
|
||||
(function(){
|
||||
var unit = getUrlParam('unit') || '采油一厂';
|
||||
var dept = getUrlParam('dept') || '';
|
||||
var displayName = unit + (dept ? ' - ' + dept : '');
|
||||
document.getElementById('bcUnit').textContent = displayName;
|
||||
renderActivityList(activities);
|
||||
renderPendingEmpTable(buildPendingEmpList());
|
||||
var unit = getUrlParam('unit') || '采油一厂';
|
||||
var dept = getUrlParam('dept') || '';
|
||||
var displayName = unit + (dept ? ' - ' + dept : '');
|
||||
document.getElementById('bcUnit').textContent = displayName;
|
||||
// 填充单位信息卡片
|
||||
document.getElementById('unitName').textContent = displayName;
|
||||
document.getElementById('unitTotal').textContent = '排查活动:'+activities.length+'个';
|
||||
renderActivityList(activities);
|
||||
renderPendingEmpTable(buildPendingEmpList());
|
||||
// 根据URL参数自动切换tab
|
||||
var tab = getUrlParam('tab');
|
||||
if(tab){
|
||||
|
||||
@@ -63,8 +63,15 @@ tbody tr:hover{background:#F8FBFF;}
|
||||
.pagination span{font-size:var(--font-sm);color:var(--text-secondary);}
|
||||
.page-btn{width:32px;height:32px;border:1px solid var(--border);border-radius:var(--radius-sm);background:#fff;cursor:pointer;font-size:var(--font-sm);display:inline-flex;align-items:center;justify-content:center;transition:all .2s;}
|
||||
.page-btn:hover,.page-btn.active{background:var(--primary);color:#fff;border-color:var(--primary);}
|
||||
.detail-title{font-size:var(--font-lg);font-weight:600;margin-bottom:4px;}
|
||||
.detail-meta{font-size:var(--font-sm);color:var(--text-secondary);margin-bottom:16px;}
|
||||
/* 单位信息卡片 */
|
||||
.info-card{background:#fff;border-radius:var(--radius-md);box-shadow:var(--shadow-sm);padding:24px;margin-bottom:16px;display:flex;align-items:center;gap:32px;}
|
||||
.info-card__avatar{width:56px;height:56px;border-radius:50%;background:var(--primary);color:#fff;display:flex;align-items:center;justify-content:center;font-size:20px;font-weight:600;flex-shrink:0;}
|
||||
.info-card__detail{display:flex;flex-direction:column;gap:6px;}
|
||||
.info-card__name{font-size:var(--font-lg);font-weight:600;color:var(--text-primary);}
|
||||
.info-card__meta{display:flex;gap:24px;font-size:var(--font-sm);color:var(--text-secondary);}
|
||||
.info-card__right{flex-shrink:0;margin-left:auto;}
|
||||
.info-card__date-filter{display:flex;align-items:center;gap:8px;}
|
||||
.info-card__date-filter label{font-size:var(--font-xs);color:var(--text-secondary);white-space:nowrap;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -117,8 +124,25 @@ tbody tr:hover{background:#F8FBFF;}
|
||||
<span class="sep">/</span>
|
||||
<span>穿戴监测</span>
|
||||
</div>
|
||||
<div class="detail-title" id="detailTitle"></div>
|
||||
<div class="detail-meta" id="detailMeta"></div>
|
||||
<!-- 单位信息卡片 -->
|
||||
<div class="info-card">
|
||||
<div class="info-card__detail">
|
||||
<div class="info-card__name" id="unitName">采油一厂</div>
|
||||
<div class="info-card__meta">
|
||||
<span id="unitTotal">总设备数:90</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="info-card__right">
|
||||
<div class="info-card__date-filter">
|
||||
<label>年份</label>
|
||||
<select class="filter-select" id="filterYear" onchange="onYearChange()" style="height:32px;min-width:110px;font-size:var(--font-xs);">
|
||||
<option value="2026">2026年</option>
|
||||
<option value="2025">2025年</option>
|
||||
<option value="2024">2024年</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- [交互] Tab 切换 -->
|
||||
<div class="tab-bar">
|
||||
@@ -473,13 +497,20 @@ function switchTab(tabName, elem) {
|
||||
document.getElementById('panel-' + tabName).classList.add('active');
|
||||
}
|
||||
|
||||
/* ===== 年份切换 ===== */
|
||||
var currentYear = '2026';
|
||||
function onYearChange(){
|
||||
currentYear = document.getElementById('filterYear').value;
|
||||
// 可根据年份刷新页面数据
|
||||
}
|
||||
|
||||
var unit = getUrlParam('unit') || '采油一厂';
|
||||
var dept = getUrlParam('dept') || '';
|
||||
var displayName = unit + (dept ? ' - ' + dept : '');
|
||||
|
||||
document.getElementById('unitDept').textContent = displayName;
|
||||
document.getElementById('detailTitle').textContent = displayName + ' — 穿戴监测 详情';
|
||||
document.getElementById('detailMeta').textContent = '2026年 · 总设备数 90';
|
||||
document.getElementById('unitName').textContent = displayName;
|
||||
document.getElementById('unitTotal').textContent = '总设备数:90';
|
||||
|
||||
// 根据URL参数自动切换tab
|
||||
var tab = getUrlParam('tab');
|
||||
|
||||
|
Before Width: | Height: | Size: 89 KiB After Width: | Height: | Size: 62 KiB |
|
Before Width: | Height: | Size: 76 KiB After Width: | Height: | Size: 54 KiB |
|
Before Width: | Height: | Size: 92 KiB After Width: | Height: | Size: 61 KiB |
|
Before Width: | Height: | Size: 67 KiB After Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 82 KiB After Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 76 KiB After Width: | Height: | Size: 62 KiB |
|
Before Width: | Height: | Size: 88 KiB After Width: | Height: | Size: 55 KiB |
@@ -707,6 +707,7 @@
|
||||
<div style="background:#F0F7FF;border:1px solid #BAE0FF;border-radius:var(--radius-md);padding:10px 16px;flex-shrink:0;">
|
||||
<span style="font-size:var(--font-sm);color:#0958D9;">设备编码:<strong id="msDeviceCode">WD-2024-001</strong></span>
|
||||
</div>
|
||||
<button class="btn btn-primary btn-sm" onclick="showAddTypeForm()" style="flex-shrink:0;">+ 新增类型配置</button>
|
||||
</div>
|
||||
<div class="monitor-setting-list" id="monitorSettingList">
|
||||
<!-- 心率 -->
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
@echo off
|
||||
chcp 65001 >nul
|
||||
title 健康CQ原型 - 本地服务器
|
||||
cd /d "%~dp0"
|
||||
|
||||
echo ============================================
|
||||
echo 健康CQ升级项目 · 高保真交互原型
|
||||
echo ============================================
|
||||
echo.
|
||||
|
||||
:: ── 检查端口 8080 是否已被占用 ──
|
||||
netstat -ano 2>nul | findstr ":8080" | findstr "LISTENING" >nul
|
||||
if %errorlevel% equ 0 (
|
||||
echo [跳过] 端口 8080 已被占用,服务器已在运行。
|
||||
goto open_browser
|
||||
)
|
||||
|
||||
:: ── 优先 npx serve(配置了 serve.json),备选 Python ──
|
||||
where npx >nul 2>nul
|
||||
if %errorlevel% equ 0 (
|
||||
echo [启动] 使用 npx serve 启动服务器...
|
||||
start "健康CQ原型-服务器" /min cmd /c "npx --yes serve . -p 8080 --no-clipboard"
|
||||
goto wait_server
|
||||
)
|
||||
|
||||
where python >nul 2>nul
|
||||
if %errorlevel% equ 0 (
|
||||
echo [启动] 使用 Python 启动服务器...
|
||||
start "健康CQ原型-服务器" /min cmd /c "python -m http.server 8080"
|
||||
goto wait_server
|
||||
)
|
||||
|
||||
echo [错误] 未找到 Node.js (npx) 或 Python!
|
||||
echo 请安装 Node.js: https://nodejs.org/
|
||||
pause
|
||||
exit /b 1
|
||||
|
||||
:wait_server
|
||||
echo [等待] 服务器启动中...
|
||||
set /a COUNT=0
|
||||
:wait_loop
|
||||
set /a COUNT+=1
|
||||
powershell -NoProfile -Command "try {$r=Invoke-WebRequest -Uri 'http://localhost:8080/' -TimeoutSec 2 -UseBasicParsing; exit 0} catch {exit 1}" >nul 2>&1
|
||||
if %errorlevel% equ 0 (
|
||||
echo [就绪] 启动成功!(%COUNT%秒)
|
||||
goto open_browser
|
||||
)
|
||||
if %COUNT% geq 30 (
|
||||
echo [超时] 30秒未就绪,请检查是否被防火墙拦截
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
timeout /t 1 /nobreak >nul
|
||||
goto wait_loop
|
||||
|
||||
:open_browser
|
||||
echo [打开] 打开浏览器...
|
||||
start http://localhost:8080/
|
||||
echo.
|
||||
echo ✅ 完成!以后双击本文件即可一键启动。
|
||||
timeout /t 2 /nobreak >nul
|
||||
exit
|
||||