feat: 医疗点PAD端细节优化与管理端体检统计二级/三级单位切换
医疗点PAD端(other-module/medical-pad/): - 退出登录统一加二次确认(confirm弹窗后再回登录页) - 全站字段名规范:工号统一为员工编号 - 随访抽屉:新增/编辑双模式,任务中心带参进入编辑态隐藏搜索并回填员工信息、标题联动编辑随访 - 健康宣教抽屉:签字方式改为手写签名/签字图片二选一(图片上传预览),去掉负责人字段,活动资料加文件不超过10M提示 - 报告解读抽屉:新增查看详情模式(?view=1纯显示只读,隐藏删除/重新解读,签字静态化) - 非员工就诊抽屉:手机号改联系电话、去掉身份证自动解析的性别/年龄只读字段 - 员工档案详情:新增体检历史/分析报告/就诊记录/随访记录/就医推荐Tab,体检报告查看弹窗,就医推荐地图医疗点卡片 - 健康监测页:事件列表由表格改为双列卡片按事件类型着色,新增定位地图,搜索栏改为更多筛选展开收起,移除仅A01A34医疗点可见提示 - 床头呼叫等页面搜索栏统一重构为更多筛选展开收起 管理端健康体检(web-admin/health-checkup/): - 冠脉CTA/胃肠镜统计页新增二级/三级单位切换TAB,二级按单位聚合并隐藏部门列与部门筛选,三级按部门展示 - 新增受检率/检出率/患病率三列,表头问号悬浮气泡说明计算口径
This commit is contained in:
@@ -46,6 +46,25 @@
|
||||
.sidebar-subgroup .sidebar-subgroup>.sidebar-subgroup__header{font-size:12px;}
|
||||
/* 主内容 */
|
||||
.main{margin-left:240px;margin-top:56px;padding:24px;min-height:calc(100vh - 56px);}
|
||||
/* 单位级别TAB */
|
||||
.unit-level-tab{display:flex;align-items:center;gap:0;margin-bottom:16px;background:#fff;border-radius:var(--radius-md);box-shadow:var(--shadow-sm);padding:0 24px;border-bottom:1px solid var(--border);}
|
||||
.unit-level-tab__item{position:relative;padding:14px 20px;font-size:var(--font-sm);color:var(--text-secondary);cursor:pointer;transition:all .2s;user-select:none;}
|
||||
.unit-level-tab__item:hover{color:var(--primary);}
|
||||
.unit-level-tab__item.active{color:var(--primary);font-weight:500;}
|
||||
.unit-level-tab__item.active::after{content:'';position:absolute;left:0;right:0;bottom:0;height:2px;background:var(--primary);border-radius:1px;}
|
||||
/* 表头计算规则提示(问号+悬浮气泡) */
|
||||
.th-help{position:relative;display:inline-flex;align-items:center;justify-content:center;width:15px;height:15px;border-radius:50%;background:#BFBFBF;color:#fff;font-size:10px;font-weight:600;cursor:help;vertical-align:middle;margin-left:4px;}
|
||||
.th-help:hover{background:var(--primary);}
|
||||
.th-help__tip{visibility:hidden;opacity:0;position:absolute;top:calc(100% + 9px);left:50%;transform:translateX(-50%);background:rgba(0,0,0,0.8);color:#fff;font-size:var(--font-sm);font-weight:400;padding:7px 12px;border-radius:var(--radius-sm);white-space:nowrap;z-index:130;transition:opacity .15s;line-height:1.5;}
|
||||
.th-help__tip::before{content:'';position:absolute;top:-4px;left:50%;margin-left:-4px;width:8px;height:8px;background:rgba(0,0,0,0.8);transform:rotate(45deg);}
|
||||
.th-help__tip--right{left:auto;right:-7px;transform:none;}
|
||||
.th-help__tip--right::before{left:auto;right:11px;margin-left:0;}
|
||||
.th-help:hover .th-help__tip{visibility:visible;opacity:1;}
|
||||
/* 二级单位tab下隐藏部门列与部门筛选 */
|
||||
.col-dept{display:none;}
|
||||
body.level-3 .col-dept{display:table-cell;}
|
||||
.filter-item.filter-dept{display:none;}
|
||||
body.level-3 .filter-item.filter-dept{display:flex;}
|
||||
/* 筛选栏 */
|
||||
.filter-bar{background:#fff;border-radius:var(--radius-md);padding:20px 24px;margin-bottom:16px;box-shadow:var(--shadow-sm);display:flex;align-items:center;gap:16px;flex-wrap:wrap;}
|
||||
.filter-item{display:flex;align-items:center;gap:8px;}
|
||||
@@ -183,6 +202,12 @@
|
||||
|
||||
<!-- 主内容 -->
|
||||
<main class="main">
|
||||
<!-- 单位级别切换TAB -->
|
||||
<div class="unit-level-tab">
|
||||
<div class="unit-level-tab__item active" onclick="switchUnitLevel(this)">二级单位</div>
|
||||
<div class="unit-level-tab__item" onclick="switchUnitLevel(this)">三级单位</div>
|
||||
</div>
|
||||
|
||||
<!-- 筛选栏 -->
|
||||
<div class="filter-bar">
|
||||
<div class="filter-item">
|
||||
@@ -203,7 +228,7 @@
|
||||
<option value="">请选择单位</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<div class="filter-item filter-dept">
|
||||
<label>部门:</label>
|
||||
<select class="filter-select" id="f-dept" onchange="state.dept=this.value;state.page=1;renderTable();">
|
||||
<option value="">请选择部门</option>
|
||||
@@ -241,7 +266,7 @@
|
||||
<div class="table-card__content">
|
||||
<table id="statTable">
|
||||
<thead>
|
||||
<tr><th>单位</th><th>部门</th><th>应检人数</th><th>已体检人数</th><th>已预约人数</th><th>已出报告人数</th><th>未预约人数</th><th>体检年份</th></tr>
|
||||
<tr><th>单位</th><th class="col-dept">部门</th><th>应检人数</th><th>已体检人数</th><th>已预约人数</th><th>已出报告人数</th><th>未预约人数</th><th>受检率<span class="th-help">?<span class="th-help__tip">受检率 = 实际检查人数 ÷ 应检人数</span></span></th><th>检出率<span class="th-help">?<span class="th-help__tip">检出率 = 异常人数 ÷ 实际检查人数</span></span></th><th>患病率<span class="th-help">?<span class="th-help__tip th-help__tip--right">患病率 = 单病种异常人数 ÷ 实际参加检查人数</span></span></th><th>体检年份</th></tr>
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
@@ -254,32 +279,36 @@
|
||||
/* ============ 数据 ============ */
|
||||
/* 确定性伪随机(0-1),保证每次打开数据一致 */
|
||||
function pseudo(i){var x=Math.sin(i*127.1)*43758.5453;return x-Math.floor(x);}
|
||||
function mkRow(unit,dept,total,checked,booked){
|
||||
return {unit:unit,dept:dept,total:total,checked:checked,booked:booked,reported:0,unbooked:total-checked-booked,year:'2026'};
|
||||
/* 按总人数与种子确定性生成一行:受检率=已体检/应检;检出率=异常/已体检;患病率=单病种异常/已体检 */
|
||||
function mkRow(unit,dept,total,seed){
|
||||
var checked=Math.floor(total*(0.6+pseudo(seed+0.3)*0.35));
|
||||
var booked=Math.floor(total*(0.1+pseudo(seed+0.6)*0.2));
|
||||
var reported=Math.floor(checked*(0.88+pseudo(seed+0.8)*0.12));
|
||||
var abnormal=Math.max(0,Math.floor(checked*(0.15+pseudo(seed+1.1)*0.4)));
|
||||
var disease=Math.max(0,Math.floor(abnormal*(0.3+pseudo(seed+1.3)*0.5)));
|
||||
return {unit:unit,dept:dept,total:total,checked:checked,booked:booked,reported:reported,unbooked:Math.max(0,total-checked-booked),abnormal:abnormal,disease:disease,year:'2026'};
|
||||
}
|
||||
var rows=[];
|
||||
/* 参考图前10条(第二采油厂) */
|
||||
[['南梁采油作业区',205,0,4],['消防大队',88,0,1],['温台采油作业区',174,1,27],['樊家川采油作业区',161,0,15],['科技信息部',7,0,0],['西峰采油二区',206,0,5],['地质研究所',31,0,2],['西峰采油三区',158,0,10],['华池采油作业区',198,0,30],['马岭北采油作业区',174,0,11]].forEach(function(d){
|
||||
rows.push(mkRow('第二采油厂',d[0],d[1],d[2],d[3]));
|
||||
[['南梁采油作业区',205],['消防大队',88],['温台采油作业区',174],['樊家川采油作业区',161],['科技信息部',7],['西峰采油二区',206],['地质研究所',31],['西峰采油三区',158],['华池采油作业区',198],['马岭北采油作业区',174]].forEach(function(d,i){
|
||||
rows.push(mkRow('第二采油厂',d[0],d[1],1000+i));
|
||||
});
|
||||
var BASE_DEPTS=['采油作业一区','采油作业二区','采油作业三区','采油作业四区','采油作业五区','采油作业六区','集输作业区','地质研究所','工艺研究所','信息中心','安全环保科','生产运行科','经营管理科','人力资源科','财务资产科','物资供应站','维修抢修中心','消防大队','综合办公室','后勤服务部','质量监督站','培训站','离退休管理科','保卫科'];
|
||||
var EXTRA_UNITS=[['第三采油厂',24],['第四采油厂',24],['第五采油厂',24],['公用事业公司',24],['运输公司',24],['水电厂',24],['采气一厂',10]];
|
||||
/* 第二采油厂补充5条,其余单位按部门池生成,合计169条 */
|
||||
['采油作业一区','采油作业六区','集输作业区','生产运行科','保卫科'].forEach(function(dept,i){
|
||||
var idx=100+i,total=20+Math.floor(pseudo(idx)*260),checked=pseudo(idx+0.31)<0.12?1:0;
|
||||
var booked=Math.floor(pseudo(idx+0.67)*Math.min(35,Math.floor(total*0.18)));
|
||||
rows.push(mkRow('第二采油厂',dept,total,checked,booked));
|
||||
var idx=100+i,total=20+Math.floor(pseudo(idx)*260);
|
||||
rows.push(mkRow('第二采油厂',dept,total,idx));
|
||||
});
|
||||
var gi=0;
|
||||
EXTRA_UNITS.forEach(function(u){
|
||||
for(var i=0;i<u[1];i++){
|
||||
gi++;
|
||||
var idx=200+gi,total=20+Math.floor(pseudo(idx)*260),checked=pseudo(idx+0.31)<0.12?1:0;
|
||||
var booked=Math.floor(pseudo(idx+0.67)*Math.min(35,Math.floor(total*0.18)));
|
||||
rows.push(mkRow(u[0],BASE_DEPTS[i],total,checked,booked));
|
||||
var idx=200+gi,total=20+Math.floor(pseudo(idx)*260);
|
||||
rows.push(mkRow(u[0],BASE_DEPTS[i],total,idx));
|
||||
}
|
||||
});
|
||||
var state={unit:'',dept:'',year:'2026',page:1,pageSize:10};
|
||||
var state={unit:'',dept:'',year:'2026',page:1,pageSize:10,level:'level-2'};
|
||||
|
||||
/* ============ 筛选 ============ */
|
||||
function initUnitOptions(){
|
||||
@@ -346,16 +375,27 @@ function filteredRows(){
|
||||
return (!state.unit||r.unit===state.unit)&&(!state.dept||r.dept===state.dept)&&(!state.year||r.year===state.year);
|
||||
});
|
||||
}
|
||||
function ratePct(a,b){return b>0?(a/b*100).toFixed(1)+'%':'0.0%';}
|
||||
function aggregateRows(list){
|
||||
var map={};
|
||||
list.forEach(function(r){
|
||||
var u=map[r.unit];
|
||||
if(!u){u=map[r.unit]={unit:r.unit,dept:'',total:0,checked:0,booked:0,reported:0,unbooked:0,abnormal:0,disease:0,year:r.year};}
|
||||
u.total+=r.total;u.checked+=r.checked;u.booked+=r.booked;u.reported+=r.reported;u.unbooked+=r.unbooked;u.abnormal+=r.abnormal;u.disease+=r.disease;
|
||||
});
|
||||
return Object.keys(map).map(function(k){return map[k];});
|
||||
}
|
||||
function renderTable(){
|
||||
var list=filteredRows();
|
||||
if(state.level==='level-2')list=aggregateRows(list);
|
||||
var totalPages=Math.max(1,Math.ceil(list.length/state.pageSize));
|
||||
if(state.page>totalPages)state.page=totalPages;
|
||||
var start=(state.page-1)*state.pageSize;
|
||||
var pageRows=list.slice(start,start+state.pageSize);
|
||||
var tbody=document.querySelector('#statTable tbody');
|
||||
tbody.innerHTML=pageRows.length?pageRows.map(function(r){
|
||||
return '<tr><td>'+r.unit+'</td><td>'+r.dept+'</td><td>'+r.total+'</td><td>'+r.checked+'</td><td>'+r.booked+'</td><td>'+r.reported+'</td><td>'+r.unbooked+'</td><td>'+r.year+'</td></tr>';
|
||||
}).join(''):'<tr><td colspan="8" style="padding:0;border-bottom:none;"><div class="empty-tip">暂无数据</div></td></tr>';
|
||||
return '<tr><td>'+r.unit+'</td><td class="col-dept">'+r.dept+'</td><td>'+r.total+'</td><td>'+r.checked+'</td><td>'+r.booked+'</td><td>'+r.reported+'</td><td>'+r.unbooked+'</td><td>'+ratePct(r.checked,r.total)+'</td><td>'+ratePct(r.abnormal,r.checked)+'</td><td>'+ratePct(r.disease,r.checked)+'</td><td>'+r.year+'</td></tr>';
|
||||
}).join(''):'<tr><td colspan="11" style="padding:0;border-bottom:none;"><div class="empty-tip">暂无数据</div></td></tr>';
|
||||
renderPagination(list.length,totalPages);
|
||||
}
|
||||
|
||||
@@ -395,6 +435,17 @@ function jumpTo(totalPages){
|
||||
renderTable();
|
||||
}
|
||||
|
||||
/* 二级/三级单位切换:二级按单位聚合并隐藏部门;三级按部门展示 */
|
||||
function switchUnitLevel(el){
|
||||
var items=el.parentElement.querySelectorAll('.unit-level-tab__item');
|
||||
items.forEach(function(item){item.classList.remove('active');});
|
||||
el.classList.add('active');
|
||||
var tab=el.textContent.trim();
|
||||
state.level=(tab==='三级单位')?'level-3':'level-2';
|
||||
document.body.classList.toggle('level-3',state.level==='level-3');
|
||||
state.page=1;
|
||||
renderTable();
|
||||
}
|
||||
/* ============ 通用 ============ */
|
||||
function toggleSubgroup(header){
|
||||
header.parentElement.classList.toggle('open');
|
||||
|
||||
@@ -46,6 +46,25 @@
|
||||
.sidebar-subgroup .sidebar-subgroup>.sidebar-subgroup__header{font-size:12px;}
|
||||
/* 主内容 */
|
||||
.main{margin-left:240px;margin-top:56px;padding:24px;min-height:calc(100vh - 56px);}
|
||||
/* 单位级别TAB */
|
||||
.unit-level-tab{display:flex;align-items:center;gap:0;margin-bottom:16px;background:#fff;border-radius:var(--radius-md);box-shadow:var(--shadow-sm);padding:0 24px;border-bottom:1px solid var(--border);}
|
||||
.unit-level-tab__item{position:relative;padding:14px 20px;font-size:var(--font-sm);color:var(--text-secondary);cursor:pointer;transition:all .2s;user-select:none;}
|
||||
.unit-level-tab__item:hover{color:var(--primary);}
|
||||
.unit-level-tab__item.active{color:var(--primary);font-weight:500;}
|
||||
.unit-level-tab__item.active::after{content:'';position:absolute;left:0;right:0;bottom:0;height:2px;background:var(--primary);border-radius:1px;}
|
||||
/* 表头计算规则提示(问号+悬浮气泡) */
|
||||
.th-help{position:relative;display:inline-flex;align-items:center;justify-content:center;width:15px;height:15px;border-radius:50%;background:#BFBFBF;color:#fff;font-size:10px;font-weight:600;cursor:help;vertical-align:middle;margin-left:4px;}
|
||||
.th-help:hover{background:var(--primary);}
|
||||
.th-help__tip{visibility:hidden;opacity:0;position:absolute;top:calc(100% + 9px);left:50%;transform:translateX(-50%);background:rgba(0,0,0,0.8);color:#fff;font-size:var(--font-sm);font-weight:400;padding:7px 12px;border-radius:var(--radius-sm);white-space:nowrap;z-index:130;transition:opacity .15s;line-height:1.5;}
|
||||
.th-help__tip::before{content:'';position:absolute;top:-4px;left:50%;margin-left:-4px;width:8px;height:8px;background:rgba(0,0,0,0.8);transform:rotate(45deg);}
|
||||
.th-help__tip--right{left:auto;right:-7px;transform:none;}
|
||||
.th-help__tip--right::before{left:auto;right:11px;margin-left:0;}
|
||||
.th-help:hover .th-help__tip{visibility:visible;opacity:1;}
|
||||
/* 二级单位tab下隐藏部门列与部门筛选 */
|
||||
.col-dept{display:none;}
|
||||
body.level-3 .col-dept{display:table-cell;}
|
||||
.filter-item.filter-dept{display:none;}
|
||||
body.level-3 .filter-item.filter-dept{display:flex;}
|
||||
/* 筛选栏 */
|
||||
.filter-bar{background:#fff;border-radius:var(--radius-md);padding:20px 24px;margin-bottom:16px;box-shadow:var(--shadow-sm);display:flex;align-items:center;gap:16px;flex-wrap:wrap;}
|
||||
.filter-item{display:flex;align-items:center;gap:8px;}
|
||||
@@ -183,6 +202,12 @@
|
||||
|
||||
<!-- 主内容 -->
|
||||
<main class="main">
|
||||
<!-- 单位级别切换TAB -->
|
||||
<div class="unit-level-tab">
|
||||
<div class="unit-level-tab__item active" onclick="switchUnitLevel(this)">二级单位</div>
|
||||
<div class="unit-level-tab__item" onclick="switchUnitLevel(this)">三级单位</div>
|
||||
</div>
|
||||
|
||||
<!-- 筛选栏 -->
|
||||
<div class="filter-bar">
|
||||
<div class="filter-item">
|
||||
@@ -203,7 +228,7 @@
|
||||
<option value="">请选择单位</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<div class="filter-item filter-dept">
|
||||
<label>部门:</label>
|
||||
<select class="filter-select" id="f-dept" onchange="state.dept=this.value;state.page=1;renderTable();">
|
||||
<option value="">请选择部门</option>
|
||||
@@ -241,7 +266,7 @@
|
||||
<div class="table-card__content">
|
||||
<table id="statTable">
|
||||
<thead>
|
||||
<tr><th>单位</th><th>部门</th><th>应检人数</th><th>已体检人数</th><th>已预约人数</th><th>已出报告人数</th><th>未预约人数</th><th>体检年份</th></tr>
|
||||
<tr><th>单位</th><th class="col-dept">部门</th><th>应检人数</th><th>已体检人数</th><th>已预约人数</th><th>已出报告人数</th><th>未预约人数</th><th>受检率<span class="th-help">?<span class="th-help__tip">受检率 = 实际检查人数 ÷ 应检人数</span></span></th><th>检出率<span class="th-help">?<span class="th-help__tip">检出率 = 异常人数 ÷ 实际检查人数</span></span></th><th>患病率<span class="th-help">?<span class="th-help__tip th-help__tip--right">患病率 = 单病种异常人数 ÷ 实际参加检查人数</span></span></th><th>体检年份</th></tr>
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
@@ -254,32 +279,36 @@
|
||||
/* ============ 数据 ============ */
|
||||
/* 确定性伪随机(0-1),保证每次打开数据一致 */
|
||||
function pseudo(i){var x=Math.sin(i*127.1)*43758.5453;return x-Math.floor(x);}
|
||||
function mkRow(unit,dept,total,checked,booked){
|
||||
return {unit:unit,dept:dept,total:total,checked:checked,booked:booked,reported:0,unbooked:total-checked-booked,year:'2026'};
|
||||
/* 按总人数与种子确定性生成一行:受检率=已体检/应检;检出率=异常/已体检;患病率=单病种异常/已体检 */
|
||||
function mkRow(unit,dept,total,seed){
|
||||
var checked=Math.floor(total*(0.6+pseudo(seed+0.3)*0.35));
|
||||
var booked=Math.floor(total*(0.1+pseudo(seed+0.6)*0.2));
|
||||
var reported=Math.floor(checked*(0.88+pseudo(seed+0.8)*0.12));
|
||||
var abnormal=Math.max(0,Math.floor(checked*(0.15+pseudo(seed+1.1)*0.4)));
|
||||
var disease=Math.max(0,Math.floor(abnormal*(0.3+pseudo(seed+1.3)*0.5)));
|
||||
return {unit:unit,dept:dept,total:total,checked:checked,booked:booked,reported:reported,unbooked:Math.max(0,total-checked-booked),abnormal:abnormal,disease:disease,year:'2026'};
|
||||
}
|
||||
var rows=[];
|
||||
/* 参考图前10条(第二采油厂) */
|
||||
[['南梁采油作业区',205,0,4],['消防大队',88,0,1],['温台采油作业区',174,1,27],['樊家川采油作业区',161,0,15],['科技信息部',7,0,0],['西峰采油二区',206,0,5],['地质研究所',31,0,2],['西峰采油三区',158,0,10],['华池采油作业区',198,0,30],['马岭北采油作业区',174,0,11]].forEach(function(d){
|
||||
rows.push(mkRow('第二采油厂',d[0],d[1],d[2],d[3]));
|
||||
[['南梁采油作业区',205],['消防大队',88],['温台采油作业区',174],['樊家川采油作业区',161],['科技信息部',7],['西峰采油二区',206],['地质研究所',31],['西峰采油三区',158],['华池采油作业区',198],['马岭北采油作业区',174]].forEach(function(d,i){
|
||||
rows.push(mkRow('第二采油厂',d[0],d[1],1000+i));
|
||||
});
|
||||
var BASE_DEPTS=['采油作业一区','采油作业二区','采油作业三区','采油作业四区','采油作业五区','采油作业六区','集输作业区','地质研究所','工艺研究所','信息中心','安全环保科','生产运行科','经营管理科','人力资源科','财务资产科','物资供应站','维修抢修中心','消防大队','综合办公室','后勤服务部','质量监督站','培训站','离退休管理科','保卫科'];
|
||||
var EXTRA_UNITS=[['第三采油厂',24],['第四采油厂',24],['第五采油厂',24],['公用事业公司',24],['运输公司',24],['水电厂',24],['采气一厂',10]];
|
||||
/* 第二采油厂补充5条,其余单位按部门池生成,合计169条 */
|
||||
['采油作业一区','采油作业六区','集输作业区','生产运行科','保卫科'].forEach(function(dept,i){
|
||||
var idx=100+i,total=20+Math.floor(pseudo(idx)*260),checked=pseudo(idx+0.31)<0.12?1:0;
|
||||
var booked=Math.floor(pseudo(idx+0.67)*Math.min(35,Math.floor(total*0.18)));
|
||||
rows.push(mkRow('第二采油厂',dept,total,checked,booked));
|
||||
var idx=100+i,total=20+Math.floor(pseudo(idx)*260);
|
||||
rows.push(mkRow('第二采油厂',dept,total,idx));
|
||||
});
|
||||
var gi=0;
|
||||
EXTRA_UNITS.forEach(function(u){
|
||||
for(var i=0;i<u[1];i++){
|
||||
gi++;
|
||||
var idx=200+gi,total=20+Math.floor(pseudo(idx)*260),checked=pseudo(idx+0.31)<0.12?1:0;
|
||||
var booked=Math.floor(pseudo(idx+0.67)*Math.min(35,Math.floor(total*0.18)));
|
||||
rows.push(mkRow(u[0],BASE_DEPTS[i],total,checked,booked));
|
||||
var idx=200+gi,total=20+Math.floor(pseudo(idx)*260);
|
||||
rows.push(mkRow(u[0],BASE_DEPTS[i],total,idx));
|
||||
}
|
||||
});
|
||||
var state={unit:'',dept:'',year:'2026',page:1,pageSize:10};
|
||||
var state={unit:'',dept:'',year:'2026',page:1,pageSize:10,level:'level-2'};
|
||||
|
||||
/* ============ 筛选 ============ */
|
||||
function initUnitOptions(){
|
||||
@@ -346,16 +375,27 @@ function filteredRows(){
|
||||
return (!state.unit||r.unit===state.unit)&&(!state.dept||r.dept===state.dept)&&(!state.year||r.year===state.year);
|
||||
});
|
||||
}
|
||||
function ratePct(a,b){return b>0?(a/b*100).toFixed(1)+'%':'0.0%';}
|
||||
function aggregateRows(list){
|
||||
var map={};
|
||||
list.forEach(function(r){
|
||||
var u=map[r.unit];
|
||||
if(!u){u=map[r.unit]={unit:r.unit,dept:'',total:0,checked:0,booked:0,reported:0,unbooked:0,abnormal:0,disease:0,year:r.year};}
|
||||
u.total+=r.total;u.checked+=r.checked;u.booked+=r.booked;u.reported+=r.reported;u.unbooked+=r.unbooked;u.abnormal+=r.abnormal;u.disease+=r.disease;
|
||||
});
|
||||
return Object.keys(map).map(function(k){return map[k];});
|
||||
}
|
||||
function renderTable(){
|
||||
var list=filteredRows();
|
||||
if(state.level==='level-2')list=aggregateRows(list);
|
||||
var totalPages=Math.max(1,Math.ceil(list.length/state.pageSize));
|
||||
if(state.page>totalPages)state.page=totalPages;
|
||||
var start=(state.page-1)*state.pageSize;
|
||||
var pageRows=list.slice(start,start+state.pageSize);
|
||||
var tbody=document.querySelector('#statTable tbody');
|
||||
tbody.innerHTML=pageRows.length?pageRows.map(function(r){
|
||||
return '<tr><td>'+r.unit+'</td><td>'+r.dept+'</td><td>'+r.total+'</td><td>'+r.checked+'</td><td>'+r.booked+'</td><td>'+r.reported+'</td><td>'+r.unbooked+'</td><td>'+r.year+'</td></tr>';
|
||||
}).join(''):'<tr><td colspan="8" style="padding:0;border-bottom:none;"><div class="empty-tip">暂无数据</div></td></tr>';
|
||||
return '<tr><td>'+r.unit+'</td><td class="col-dept">'+r.dept+'</td><td>'+r.total+'</td><td>'+r.checked+'</td><td>'+r.booked+'</td><td>'+r.reported+'</td><td>'+r.unbooked+'</td><td>'+ratePct(r.checked,r.total)+'</td><td>'+ratePct(r.abnormal,r.checked)+'</td><td>'+ratePct(r.disease,r.checked)+'</td><td>'+r.year+'</td></tr>';
|
||||
}).join(''):'<tr><td colspan="11" style="padding:0;border-bottom:none;"><div class="empty-tip">暂无数据</div></td></tr>';
|
||||
renderPagination(list.length,totalPages);
|
||||
}
|
||||
|
||||
@@ -395,6 +435,17 @@ function jumpTo(totalPages){
|
||||
renderTable();
|
||||
}
|
||||
|
||||
/* 二级/三级单位切换:二级按单位聚合并隐藏部门;三级按部门展示 */
|
||||
function switchUnitLevel(el){
|
||||
var items=el.parentElement.querySelectorAll('.unit-level-tab__item');
|
||||
items.forEach(function(item){item.classList.remove('active');});
|
||||
el.classList.add('active');
|
||||
var tab=el.textContent.trim();
|
||||
state.level=(tab==='三级单位')?'level-3':'level-2';
|
||||
document.body.classList.toggle('level-3',state.level==='level-3');
|
||||
state.page=1;
|
||||
renderTable();
|
||||
}
|
||||
/* ============ 通用 ============ */
|
||||
function toggleSubgroup(header){
|
||||
header.parentElement.classList.toggle('open');
|
||||
|
||||
Reference in New Issue
Block a user