diff --git a/web-admin/weight-management/action-record.html b/web-admin/weight-management/action-record.html index 0305ddf..c5c1254 100644 --- a/web-admin/weight-management/action-record.html +++ b/web-admin/weight-management/action-record.html @@ -113,6 +113,18 @@ body{font-family:-apple-system,BlinkMacSystemFont,'PingFang SC','Microsoft YaHei .tab-panel{display:none;} .tab-panel.active{display:block;} +/* 大Tab切换:员工数据 / 单位数据 */ +.data-tab-bar{display:inline-flex;gap:4px;background:#fff;border-radius:var(--radius-md);box-shadow:var(--shadow-sm);padding:4px;margin-bottom:16px;} +.data-tab-item{padding:8px 24px;font-size:var(--font-base);font-weight:500;cursor:pointer;border-radius:var(--radius-sm);color:var(--text-secondary);transition:all .2s;user-select:none;} +.data-tab-item:hover{color:var(--primary);background:#F0F8FF;} +.data-tab-item.active{background:var(--primary);color:#fff;} +.data-tab-panel{display:none;} +.data-tab-panel.active{display:block;} +/* 单位数据表格:取消全局固定列样式 */ +#unitTable thead th,#unitTable tbody td{position:static;width:auto;min-width:0;max-width:none;box-shadow:none;background:#fff;} +#unitTable thead th{background:#FAFAFA;} +#unitTable tbody tr:hover td{background:#F8FBFF;} + /* 筛选栏 */ .filter-bar{background:#fff;padding:20px 24px;display:flex;align-items:center;gap:16px;flex-wrap:wrap;} .filter-item{display:flex;align-items:center;gap:8px;} @@ -156,13 +168,13 @@ thead th{background:#FAFAFA;padding:10px 8px;text-align:center;font-size:var(--f tbody td{padding:12px 8px;text-align:center;font-size:var(--font-sm);color:var(--text-primary);border-bottom:1px solid #F0F0F0;white-space:nowrap;} tbody tr:last-child td{border-bottom:none;} tbody tr:hover{background:#F8FBFF;} -/* 前三列固定 */ -thead th:nth-child(1),tbody td:nth-child(1){position:sticky;left:0;z-index:6;background:#fff;width:220px;min-width:220px;max-width:220px;overflow:hidden;text-overflow:ellipsis;} -thead th:nth-child(1){z-index:8;background:#FAFAFA;} -thead th:nth-child(2),tbody td:nth-child(2){position:sticky;left:220px;z-index:5;background:#fff;width:64px;min-width:64px;max-width:64px;} -thead th:nth-child(2){z-index:7;background:#FAFAFA;} -thead th:nth-child(3),tbody td:nth-child(3){position:sticky;left:284px;z-index:4;background:#fff;width:100px;min-width:100px;max-width:100px;} -thead th:nth-child(3){z-index:6;background:#FAFAFA;} +/* 前三列固定(仅表头首行) */ +thead tr:first-child th:nth-child(1),tbody td:nth-child(1){position:sticky;left:0;z-index:6;background:#fff;width:220px;min-width:220px;max-width:220px;overflow:hidden;text-overflow:ellipsis;} +thead tr:first-child th:nth-child(1){z-index:8;background:#FAFAFA;} +thead tr:first-child th:nth-child(2),tbody td:nth-child(2){position:sticky;left:220px;z-index:5;background:#fff;width:64px;min-width:64px;max-width:64px;} +thead tr:first-child th:nth-child(2){z-index:7;background:#FAFAFA;} +thead tr:first-child th:nth-child(3),tbody td:nth-child(3){position:sticky;left:284px;z-index:4;background:#fff;width:100px;min-width:100px;max-width:100px;} +thead tr:first-child th:nth-child(3){z-index:6;background:#FAFAFA;} tbody tr:hover td:nth-child(1), tbody tr:hover td:nth-child(2), tbody tr:hover td:nth-child(3){background:#F8FBFF;} @@ -366,6 +378,14 @@ tbody tr:hover td:nth-child(3){background:#F8FBFF;} + +
+
员工数据
+
单位数据
+
+ + +
@@ -437,21 +457,7 @@ tbody tr:hover td:nth-child(3){background:#F8FBFF;}
- - - - - - - - - - - - - - - +
干预计划姓名员工编号性别年龄单位部门打卡次数 首次记录日期末次记录日期
@@ -462,6 +468,56 @@ tbody tr:hover td:nth-child(3){background:#F8FBFF;}
+ + + +
+ +
+
+ + + + +
+
+ + +
+ + +
+ +
+
+ 共 0 个单位 + +
+
+ + + + + + + + + + +
单位总人数三测人数三测率
+
+
+
@@ -1134,7 +1190,7 @@ function buildMeasureData(){ var dailyData = buildDailyData(); var measureData = buildMeasureData(); -var currentTab = 0; +var currentTab = 1; var currentSubTab = 'weight'; var sortAsc = false; var pageSize = 10; @@ -1306,6 +1362,7 @@ function selectDept1(elem, deptName, deptCode){ /* ===== 筛选 ===== */ function applyFilter(){ if(currentTab === 0){ applyFilter0(); } else { applyFilter1(); } + if(currentDataTab === 'unit'){ applyUnitFilter(); } } function applyFilter0(){ @@ -1402,6 +1459,81 @@ function resetFilter1(){ applyFilter1(); } +/* ===== 大Tab切换:员工数据 / 单位数据 ===== */ +var currentDataTab = 'employee'; +function switchDataTab(tab){ + currentDataTab = tab; + document.querySelectorAll('.data-tab-item').forEach(function(el){ + el.classList.toggle('active', el.dataset.dataTab === tab); + }); + document.querySelectorAll('.data-tab-panel').forEach(function(el){ + el.classList.toggle('active', el.dataset.dataPanel === tab); + }); + if(tab === 'unit'){ applyUnitFilter(); } +} + +/* ===== 单位数据:按单位聚合三测情况 ===== */ +var unitFilteredData = []; +function applyUnitFilter(){ + var dateFrom = document.getElementById('unitDateFrom').value; + var dateTo = document.getElementById('unitDateTo').value; + var unit = document.getElementById('unitSelect').value; + var map = {}; + measureData.weight.forEach(function(w, i){ + var dRec = measureData.diet[i], exRec = measureData.exercise[i]; + if(selectedPlanId && w.planId !== selectedPlanId) return; + var org = w.org; + if(unit && org !== unit) return; + if(!map[org]){ map[org] = {org:org, total:0, measured:0}; } + map[org].total++; + function inRange(rec){ + if(!rec.hasRecord) return false; + if(dateFrom && rec.lastDate !== '-' && rec.lastDate < dateFrom) return false; + if(dateTo && rec.firstDate > dateTo) return false; + return true; + } + if(inRange(w) && inRange(dRec) && inRange(exRec)) map[org].measured++; + }); + unitFilteredData = []; + for(var k in map){ + var m = map[k]; + m.rate = m.total ? +(m.measured / m.total * 100).toFixed(1) : 0; + unitFilteredData.push(m); + } + unitFilteredData.sort(function(a,b){ return b.total - a.total; }); + renderUnitTable(); +} + +function resetUnitFilter(){ + var now = new Date(); + var day = now.getDay(); day = day === 0 ? 7 : day; + var mon = new Date(now); mon.setDate(now.getDate() - day + 1); + var sun = new Date(now); sun.setDate(now.getDate() - day + 7); + document.getElementById('unitDateFrom').value = mon.getFullYear()+'-'+('0'+(mon.getMonth()+1)).slice(-2)+'-'+('0'+mon.getDate()).slice(-2); + document.getElementById('unitDateTo').value = sun.getFullYear()+'-'+('0'+(sun.getMonth()+1)).slice(-2)+'-'+('0'+sun.getDate()).slice(-2); + document.getElementById('unitSelect').value = ''; + applyUnitFilter(); +} + +function renderUnitTable(){ + var tbody = document.getElementById('unitTableBody'); + document.getElementById('unitCount').textContent = '共 ' + unitFilteredData.length + ' 个单位'; + if(unitFilteredData.length === 0){ + tbody.innerHTML = '暂无匹配数据'; + return; + } + var html = ''; + unitFilteredData.forEach(function(d){ + html += ''; + html += ''+esc(d.org)+''; + html += ''+d.total+''; + html += ''+d.measured+''; + html += ''+d.rate+'%'; + html += ''; + }); + tbody.innerHTML = html; +} + function updateTabBadges(){} /* ===== 更新统计卡片 ===== */ @@ -1482,6 +1614,49 @@ function renderDailyTable(){ tbody.innerHTML = html; } +/* ===== 渲染三测记录表头(体重tab为分组两行表头) ===== */ +function renderOverviewHeader(){ + var thead = document.getElementById('overviewThead'); + var sortTh = '打卡次数 '; + var html = ''; + if(currentSubTab === 'weight'){ + html += ''; + html += '干预计划'; + html += '姓名'; + html += '员工编号'; + html += '性别'; + html += '年龄'; + html += '单位'; + html += '部门'; + html += sortTh; + html += '首次记录日期'; + html += '末次记录日期'; + html += '末次记录数据'; + html += ''; + html += ''; + html += '身高'; + html += '体重'; + html += 'BMI'; + html += '体脂'; + html += '腰围'; + html += ''; + } else { + html += ''; + html += '干预计划'; + html += '姓名'; + html += '员工编号'; + html += '性别'; + html += '年龄'; + html += '单位'; + html += '部门'; + html += sortTh; + html += '首次记录日期'; + html += '末次记录日期'; + html += ''; + } + thead.innerHTML = html; +} + /* ===== 渲染三测记录表格 ===== */ function renderOverviewTable(){ var tbody = document.getElementById('tableBody1'); @@ -1490,8 +1665,10 @@ function renderOverviewTable(){ var totalPages = Math.ceil(filteredData.length / pageSize) || 1; document.getElementById('pageInfo1').textContent = '显示 ' + pageData.length + ' 条,共 ' + filteredData.length + ' 条记录'; document.getElementById('pageNum1').textContent = '第 ' + (currentPage + 1) + '/' + totalPages + ' 页'; + var isWeight = currentSubTab === 'weight'; + var colCount = isWeight ? 15 : 10; if(filteredData.length === 0){ - tbody.innerHTML = '暂无匹配数据'; + tbody.innerHTML = '暂无匹配数据'; return; } var html = ''; @@ -1507,6 +1684,14 @@ function renderOverviewTable(){ html += ''+d.checkinCount+''; html += ''+esc(d.firstDate)+''; html += ''+esc(d.lastDate)+''; + if(isWeight){ + var emp = baseEmployees.find(function(e){return e.empId === d.empId;}) || {}; + html += ''+(emp.height||'-')+''; + html += ''+(emp.weight||'-')+''; + html += ''+(emp.bmi?emp.bmi.toFixed(1):'-')+''; + html += ''+(emp.fat?emp.fat.toFixed(1):'-')+''; + html += ''+(emp.waist||'-')+''; + } html += ''; }); tbody.innerHTML = html; @@ -1518,10 +1703,11 @@ function switchSubTab(type){ document.querySelectorAll('.sub-tab-group .sub-tab-item').forEach(function(el){ el.classList.toggle('active', el.dataset.sub === type); }); - var titles = {weight:'体重记录', diet:'饮食记录', exercise:'运动记录'}; - document.getElementById('overviewTitle').textContent = titles[type] || type; + // 体重tab为分组两行表头,其余为单行表头 + renderOverviewHeader(); sortAsc = false; - document.getElementById('sortCount').classList.remove('asc','desc'); + var sortTh = document.getElementById('sortCount'); + if(sortTh){ sortTh.classList.remove('asc','desc'); var arrow = sortTh.querySelector('.sort-arrow'); if(arrow){ arrow.textContent = '↕'; } } // 重置记录状态为全部 document.querySelectorAll('.sub-tab-status .sub-tab-item').forEach(function(el){el.classList.toggle('active', el.dataset.status === 'all');}); applyFilter1(); @@ -2641,6 +2827,12 @@ document.addEventListener('click',function(e){ document.getElementById('filterDateFrom1').value = mon.getFullYear()+'-'+('0'+(mon.getMonth()+1)).slice(-2)+'-'+('0'+mon.getDate()).slice(-2); document.getElementById('filterDateTo1').value = sun.getFullYear()+'-'+('0'+(sun.getMonth()+1)).slice(-2)+'-'+('0'+sun.getDate()).slice(-2); + // 单位数据日期默认值为本周(周一到周日) + document.getElementById('unitDateFrom').value = mon.getFullYear()+'-'+('0'+(mon.getMonth()+1)).slice(-2)+'-'+('0'+mon.getDate()).slice(-2); + document.getElementById('unitDateTo').value = sun.getFullYear()+'-'+('0'+(sun.getMonth()+1)).slice(-2)+'-'+('0'+sun.getDate()).slice(-2); + applyUnitFilter(); + + renderOverviewHeader(); applyFilter1(); updateStatCards(); })();