feat: 健康体检模块批量上线「高级查询」条件构建器,侧边栏菜单收敛
- 检中/检后/检前多个列表页(个人档案、单位档案、体检预约跟踪、单位预约统计、指定防癌、必检项目、项目组合模板、结果动态综合统计、员工主数据等)将固定筛选下拉替换为「高级查询」动态条件构建器(字段/操作符/值/区间,支持增删行与清空),并移除冗余的性别/年龄/岗位/是否异常/体检医院/费用审核状态/防癌类型等固定筛选项 - 体检预约跟踪页重构:新增高级查询、轻提示,移除医院/性别/年龄范围/机构分类/是否上市/防癌项/体检状态/预约状态/前置机预约状态等固定筛选 - 侧边栏及 index.html SITE_MAP 收敛:体检预约、已选项目、已检员工三项入口注释下线,合并入「体检预约跟踪」
This commit is contained in:
@@ -168,6 +168,21 @@
|
||||
.year-picker__dropdown div{padding:8px 14px;font-size:var(--font-sm);cursor:pointer;}
|
||||
.year-picker__dropdown div:hover{background:var(--primary-light);}
|
||||
.year-picker__dropdown div.selected{color:var(--primary);font-weight:600;}
|
||||
/* 高级查询 */
|
||||
.adv-panel{background:#fff;border-radius:var(--radius-md);padding:16px 24px;margin-bottom:16px;box-shadow:var(--shadow-sm);display:none;}
|
||||
.adv-panel.open{display:block;}
|
||||
.adv-panel__head{font-size:var(--font-base);font-weight:600;margin-bottom:12px;}
|
||||
#advConditions{display:grid;grid-template-columns:1fr 1fr;gap:10px 16px;}
|
||||
.adv-cond-row{display:flex;align-items:center;gap:8px;margin-bottom:0;min-width:0;}
|
||||
.adv-field{min-width:140px;flex:1;}
|
||||
.adv-op{min-width:72px;flex:none;}
|
||||
.adv-value-wrap{display:flex;align-items:center;gap:8px;flex:1;min-width:0;max-width:none;}
|
||||
.adv-value{flex:1;min-width:0;}
|
||||
.adv-range-sep{color:var(--text-secondary);flex-shrink:0;}
|
||||
.adv-del{width:32px;height:32px;border:1px solid var(--border);border-radius:var(--radius-sm);background:#fff;color:var(--text-secondary);cursor:pointer;flex-shrink:0;font-size:var(--font-sm);line-height:1;}
|
||||
.adv-del:hover{color:var(--danger);border-color:var(--danger);}
|
||||
.adv-actions{display:flex;gap:12px;margin-top:2px;}
|
||||
.adv-arrow{font-size:10px;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -237,16 +252,20 @@
|
||||
<label>身份证号:</label>
|
||||
<input class="filter-input" type="text" id="fIdCard" placeholder="请输入" style="width:160px;min-width:unset;">
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label>异常员工:</label>
|
||||
<select class="filter-select" style="min-width:100px;" id="abnormalFilter">
|
||||
<option value="">全部</option>
|
||||
<option value="abnormal">是</option>
|
||||
<option value="normal">否</option>
|
||||
</select>
|
||||
</div>
|
||||
<button class="btn btn-primary" onclick="applyFilter()">查询</button>
|
||||
<button class="btn btn-default" onclick="resetFilter()">重置</button>
|
||||
<button class="btn btn-default" id="advToggle" onclick="toggleAdvanced()">高级查询 <span class="adv-arrow">▾</span></button>
|
||||
</div>
|
||||
|
||||
<!-- 高级查询 -->
|
||||
<div class="adv-panel" id="advPanel">
|
||||
<div class="adv-panel__head">高级查询</div>
|
||||
<div id="advConditions"></div>
|
||||
<div class="adv-actions">
|
||||
<button class="btn btn-default" onclick="addAdvCondition()">+ 添加条件</button>
|
||||
<button class="btn btn-primary" onclick="applyFilter()">查询</button>
|
||||
<button class="btn btn-default" onclick="clearAdvanced()">清空</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 操作栏 -->
|
||||
@@ -585,21 +604,135 @@ function hasAbnormal(r){
|
||||
for(var k in r.r){if(r.r[k][1])return true;}
|
||||
return false;
|
||||
}
|
||||
/* 按筛选条件取当前展示行:异常员工 + 姓名/员工编号/身份证号模糊匹配 */
|
||||
/* 按筛选条件取当前展示行:姓名模糊匹配 + 高级查询条件 */
|
||||
function getDisplayRows(){
|
||||
var v=document.getElementById('abnormalFilter').value;
|
||||
var name=document.getElementById('fName').value.trim();
|
||||
var empNo=document.getElementById('fEmpNo').value.trim();
|
||||
var idCard=document.getElementById('fIdCard').value.trim();
|
||||
var conds=readAdvancedConditions();
|
||||
return MASTER_ROWS.filter(function(r){
|
||||
if(v==='abnormal'&&!hasAbnormal(r))return false;
|
||||
if(v==='normal'&&hasAbnormal(r))return false;
|
||||
if(name&&r.name.indexOf(name)<0)return false;
|
||||
if(empNo&&r.empNo.indexOf(empNo)<0)return false;
|
||||
if(idCard&&r.idCard.indexOf(idCard)<0)return false;
|
||||
for(var i=0;i<conds.length;i++){if(!matchCondition(r,conds[i]))return false;}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
/* ============ 高级查询 ============ */
|
||||
var ADV_OPS=['包含','=','!=','>','>=','<','<=','范围'];
|
||||
var ADV_FIELD_OPTS='';
|
||||
/* 字段下拉选项:基本信息 + 全部体检项目(按一级分类分组,二级分类·项目名 去重) */
|
||||
function buildAdvFieldOpts(){
|
||||
var o='<optgroup label="基本信息">';
|
||||
BASE_COLS.forEach(function(c){if(c.key!=='idx')o+='<option value="'+c.key+'">'+c.label+'</option>';});
|
||||
o+='</optgroup>';
|
||||
ITEM_TREE.forEach(function(g){
|
||||
o+='<optgroup label="'+g.lvl1+'">';
|
||||
g.lvl2.forEach(function(s){
|
||||
s.items.forEach(function(it){o+='<option value="'+s.name+'|'+it+'">'+s.name+'·'+it+'</option>';});
|
||||
});
|
||||
o+='</optgroup>';
|
||||
});
|
||||
return o;
|
||||
}
|
||||
function advConditionRowHTML(){
|
||||
return '<div class="adv-cond-row">'
|
||||
+'<select class="filter-select adv-field">'+ADV_FIELD_OPTS+'</select>'
|
||||
+'<select class="filter-select adv-op" onchange="onAdvOpChange(this)">'+ADV_OPS.map(function(o){return '<option value="'+o+'">'+o+'</option>';}).join('')+'</select>'
|
||||
+'<span class="adv-value-wrap"><input class="filter-input adv-value" type="text" placeholder="请输入值"></span>'
|
||||
+'<button class="adv-del" type="button" title="删除该条件" onclick="removeAdvCondition(this)">✕</button>'
|
||||
+'</div>';
|
||||
}
|
||||
/* 运算符切换为"范围"时,值区域变成最小/最大两个输入框 */
|
||||
function onAdvOpChange(sel){
|
||||
var wrap=sel.parentElement.querySelector('.adv-value-wrap');
|
||||
var isRange=sel.value==='范围';
|
||||
var alreadyRange=!!wrap.querySelector('.adv-range-from');
|
||||
if(isRange&&!alreadyRange){
|
||||
wrap.innerHTML='<input class="filter-input adv-value adv-range-from" type="text" placeholder="最小值">'
|
||||
+'<span class="adv-range-sep">~</span>'
|
||||
+'<input class="filter-input adv-value adv-range-to" type="text" placeholder="最大值">';
|
||||
}else if(!isRange&&alreadyRange){
|
||||
wrap.innerHTML='<input class="filter-input adv-value" type="text" placeholder="请输入值">';
|
||||
}
|
||||
}
|
||||
function addAdvCondition(){
|
||||
document.getElementById('advConditions').insertAdjacentHTML('beforeend',advConditionRowHTML());
|
||||
}
|
||||
function removeAdvCondition(el){el.parentElement.remove();}
|
||||
function toggleAdvanced(){
|
||||
var p=document.getElementById('advPanel');
|
||||
var open=p.classList.toggle('open');
|
||||
var arr=document.getElementById('advToggle').querySelector('.adv-arrow');
|
||||
if(arr)arr.textContent=open?'▴':'▾';
|
||||
if(open&&!p.querySelector('.adv-cond-row'))addAdvCondition();
|
||||
}
|
||||
function clearAdvanced(){
|
||||
document.getElementById('advConditions').innerHTML='';
|
||||
renderBigTable();
|
||||
showToast('已清空高级查询条件');
|
||||
}
|
||||
/* 读取面板中已填值的条件(忽略值为空的行;范围条件任一边有值即计入) */
|
||||
function readAdvancedConditions(){
|
||||
var conds=[];
|
||||
document.querySelectorAll('#advConditions .adv-cond-row').forEach(function(row){
|
||||
var field=row.querySelector('.adv-field').value;
|
||||
var op=row.querySelector('.adv-op').value;
|
||||
if(op==='范围'){
|
||||
var from=row.querySelector('.adv-range-from').value.trim();
|
||||
var to=row.querySelector('.adv-range-to').value.trim();
|
||||
if(from!==''||to!=='')conds.push({field:field,op:op,from:from,to:to});
|
||||
}else{
|
||||
var value=row.querySelector('.adv-value').value.trim();
|
||||
if(value!=='')conds.push({field:field,op:op,value:value});
|
||||
}
|
||||
});
|
||||
return conds;
|
||||
}
|
||||
/* 取某字段在某员工上的值:基本信息直接用 key,项目结果取"结果"字符串 */
|
||||
function getFieldRaw(row,field){
|
||||
if(field.indexOf('|')>=0){
|
||||
var i=field.indexOf('|');
|
||||
var cat=field.slice(0,i),name=field.slice(i+1);
|
||||
var val=row.r[cat+'|'+name]||row.r[name];
|
||||
if(!val)val=[(CAT_DEFAULTS[cat]||['-'])[0]];
|
||||
return val[0];
|
||||
}
|
||||
return row[field];
|
||||
}
|
||||
/* 数值化:取结果中的首个数字 */
|
||||
function numericOf(v){
|
||||
var m=String(v).match(/[-+]?\d+(?:\.\d+)?/);
|
||||
return m?parseFloat(m[0]):null;
|
||||
}
|
||||
/* 单条条件匹配:包含/=/!= 按字符串,>、>=、<、<=、范围 按数值 */
|
||||
function matchCondition(row,cond){
|
||||
var raw=getFieldRaw(row,cond.field);
|
||||
var str=String(raw==null?'':raw);
|
||||
if(cond.op==='包含')return str.indexOf(cond.value)>=0;
|
||||
if(cond.op==='=')return str===cond.value;
|
||||
if(cond.op==='!=')return str!==cond.value;
|
||||
var n=numericOf(str);
|
||||
if(n===null)return false;
|
||||
if(cond.op==='范围'){
|
||||
if(cond.from!==''){
|
||||
var lo=parseFloat(cond.from);
|
||||
if(!isNaN(lo)&&n<lo)return false;
|
||||
}
|
||||
if(cond.to!==''){
|
||||
var hi=parseFloat(cond.to);
|
||||
if(!isNaN(hi)&&n>hi)return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
var c=parseFloat(cond.value);
|
||||
if(isNaN(c))return false;
|
||||
if(cond.op==='>')return n>c;
|
||||
if(cond.op==='>=')return n>=c;
|
||||
if(cond.op==='<')return n<c;
|
||||
if(cond.op==='<=')return n<=c;
|
||||
return true;
|
||||
}
|
||||
function renderBigTable(){
|
||||
document.getElementById('bigTable').innerHTML=buildHead()+buildBody();
|
||||
document.getElementById('pageTotal').textContent='共 '+getDisplayRows().length+' 条';
|
||||
@@ -789,7 +922,6 @@ function applyFilter(){
|
||||
showToast('查询完成');
|
||||
}
|
||||
function resetFilter(){
|
||||
document.getElementById('abnormalFilter').value='';
|
||||
document.getElementById('fName').value='';
|
||||
document.getElementById('fEmpNo').value='';
|
||||
document.getElementById('fIdCard').value='';
|
||||
@@ -797,6 +929,7 @@ function resetFilter(){
|
||||
showToast('已重置筛选条件');
|
||||
}
|
||||
renderBigTable();
|
||||
ADV_FIELD_OPTS=buildAdvFieldOpts();
|
||||
/* 体检年份选择控件 */
|
||||
function pickYear(el){
|
||||
var dp=el.parentElement,input=dp.parentElement.querySelector('input');
|
||||
|
||||
@@ -119,6 +119,25 @@
|
||||
.year-picker__dropdown div{padding:8px 14px;font-size:var(--font-sm);cursor:pointer;}
|
||||
.year-picker__dropdown div:hover{background:var(--primary-light);}
|
||||
.year-picker__dropdown div.selected{color:var(--primary);font-weight:600;}
|
||||
/* 高级查询 */
|
||||
.adv-panel{background:#fff;border-radius:var(--radius-md);padding:16px 24px;margin-bottom:16px;box-shadow:var(--shadow-sm);display:none;}
|
||||
.adv-panel.open{display:block;}
|
||||
.adv-panel__head{font-size:var(--font-base);font-weight:600;margin-bottom:12px;}
|
||||
#advConditions{display:grid;grid-template-columns:1fr 1fr;gap:10px 16px;}
|
||||
.adv-cond-row{display:flex;align-items:center;gap:8px;margin-bottom:0;min-width:0;}
|
||||
.adv-field{min-width:140px;flex:1;}
|
||||
.adv-op{min-width:72px;flex:none;}
|
||||
.adv-value-wrap{display:flex;align-items:center;gap:8px;flex:1;min-width:0;max-width:none;}
|
||||
.adv-value{flex:1;min-width:0;}
|
||||
.adv-range-sep{color:var(--text-secondary);flex-shrink:0;}
|
||||
.adv-del{width:32px;height:32px;border:1px solid var(--border);border-radius:var(--radius-sm);background:#fff;color:var(--text-secondary);cursor:pointer;flex-shrink:0;font-size:var(--font-sm);line-height:1;}
|
||||
.adv-del:hover{color:var(--danger);border-color:var(--danger);}
|
||||
.adv-actions{display:flex;gap:12px;margin-top:2px;}
|
||||
.adv-arrow{font-size:10px;}
|
||||
/* 轻提示 */
|
||||
.toast{position:fixed;top:76px;left:50%;transform:translateX(-50%) translateY(-16px);background:#fff;box-shadow:var(--shadow-md);border-radius:var(--radius-sm);padding:10px 20px;font-size:var(--font-sm);color:var(--text-primary);opacity:0;pointer-events:none;transition:all .25s;z-index:1000;display:flex;align-items:center;gap:8px;}
|
||||
.toast.show{opacity:1;transform:translateX(-50%) translateY(0);}
|
||||
.toast svg{flex-shrink:0;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -184,6 +203,18 @@
|
||||
</div>
|
||||
<button class="btn btn-primary">查询</button>
|
||||
<button class="btn btn-default">重置</button>
|
||||
<button class="btn btn-default" id="advToggle" onclick="toggleAdvanced()">高级查询 <span class="adv-arrow">▾</span></button>
|
||||
</div>
|
||||
|
||||
<!-- 高级查询 -->
|
||||
<div class="adv-panel" id="advPanel">
|
||||
<div class="adv-panel__head">高级查询</div>
|
||||
<div id="advConditions"></div>
|
||||
<div class="adv-actions">
|
||||
<button class="btn btn-default" onclick="addAdvCondition()">+ 添加条件</button>
|
||||
<button class="btn btn-primary" onclick="applyFilter()">查询</button>
|
||||
<button class="btn btn-default" onclick="clearAdvanced()">清空</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 操作栏 -->
|
||||
@@ -399,6 +430,114 @@ document.querySelectorAll('.year-picker>input').forEach(function(inp){
|
||||
document.addEventListener('click',function(){
|
||||
document.querySelectorAll('.year-picker__dropdown.open').forEach(function(d){d.classList.remove('open');});
|
||||
});
|
||||
/* ============ 高级查询 ============ */
|
||||
var ADV_OPS=['包含','=','!=','>','>=','<','<=','范围'];
|
||||
var ADV_ROW_SELECTOR='#unitTable tbody tr';
|
||||
var ADV_FIELDS=[
|
||||
{key:'unit',label:'单位',idx:1},{key:'dept',label:'部门',idx:2},{key:'year',label:'体检年份',idx:3},
|
||||
{key:'signHospital',label:'签约医院',idx:4},{key:'hospital',label:'承检医院',idx:5},{key:'range',label:'体检计划日期范围',idx:6},
|
||||
{key:'total',label:'总人数',idx:7},{key:'should',label:'应检人数',idx:8},{key:'selected',label:'已选项目人数',idx:9},
|
||||
{key:'booked',label:'已预约人数',idx:10},{key:'checked',label:'已检人数',idx:11},{key:'unchecked',label:'未检人数',idx:12},
|
||||
{key:'rate',label:'受检率',idx:13},{key:'detectRate',label:'检出率',idx:14},{key:'keyAbn',label:'重点指标异常人数',idx:15},
|
||||
{key:'ctaAbn',label:'冠脉CTA异常人数',idx:16},{key:'cancerAbn',label:'防癌筛查异常人数',idx:17},
|
||||
{key:'planFee',label:'计划总费用(元)',idx:18},{key:'actualFee',label:'实际总费用(元)',idx:19},{key:'perFee',label:'人均费用(元)',idx:20}
|
||||
];
|
||||
var ADV_FIELD_OPTS=ADV_FIELDS.map(function(f){return '<option value="'+f.key+'">'+f.label+'</option>';}).join('');
|
||||
function advConditionRowHTML(){
|
||||
return '<div class="adv-cond-row">'
|
||||
+'<select class="filter-select adv-field">'+ADV_FIELD_OPTS+'</select>'
|
||||
+'<select class="filter-select adv-op" onchange="onAdvOpChange(this)">'+ADV_OPS.map(function(o){return '<option value="'+o+'">'+o+'</option>';}).join('')+'</select>'
|
||||
+'<span class="adv-value-wrap"><input class="filter-input adv-value" type="text" placeholder="请输入值"></span>'
|
||||
+'<button class="adv-del" type="button" title="删除该条件" onclick="removeAdvCondition(this)">✕</button>'
|
||||
+'</div>';
|
||||
}
|
||||
function onAdvOpChange(sel){
|
||||
var wrap=sel.parentElement.querySelector('.adv-value-wrap');
|
||||
var isRange=sel.value==='范围';
|
||||
var alreadyRange=!!wrap.querySelector('.adv-range-from');
|
||||
if(isRange&&!alreadyRange){
|
||||
wrap.innerHTML='<input class="filter-input adv-value adv-range-from" type="text" placeholder="最小值">'
|
||||
+'<span class="adv-range-sep">~</span>'
|
||||
+'<input class="filter-input adv-value adv-range-to" type="text" placeholder="最大值">';
|
||||
}else if(!isRange&&alreadyRange){
|
||||
wrap.innerHTML='<input class="filter-input adv-value" type="text" placeholder="请输入值">';
|
||||
}
|
||||
}
|
||||
function addAdvCondition(){document.getElementById('advConditions').insertAdjacentHTML('beforeend',advConditionRowHTML());}
|
||||
function removeAdvCondition(el){el.parentElement.remove();}
|
||||
function toggleAdvanced(){
|
||||
var p=document.getElementById('advPanel');
|
||||
var open=p.classList.toggle('open');
|
||||
var arr=document.getElementById('advToggle').querySelector('.adv-arrow');
|
||||
if(arr)arr.textContent=open?'▴':'▾';
|
||||
if(open&&!p.querySelector('.adv-cond-row'))addAdvCondition();
|
||||
}
|
||||
function readAdvancedConditions(){
|
||||
var conds=[];
|
||||
document.querySelectorAll('#advConditions .adv-cond-row').forEach(function(row){
|
||||
var field=row.querySelector('.adv-field').value;
|
||||
var op=row.querySelector('.adv-op').value;
|
||||
if(op==='范围'){
|
||||
var from=row.querySelector('.adv-range-from').value.trim();
|
||||
var to=row.querySelector('.adv-range-to').value.trim();
|
||||
if(from!==''||to!=='')conds.push({field:field,op:op,from:from,to:to});
|
||||
}else{
|
||||
var value=row.querySelector('.adv-value').value.trim();
|
||||
if(value!=='')conds.push({field:field,op:op,value:value});
|
||||
}
|
||||
});
|
||||
return conds;
|
||||
}
|
||||
function fieldByKey(key){for(var i=0;i<ADV_FIELDS.length;i++){if(ADV_FIELDS[i].key===key)return ADV_FIELDS[i];}return null;}
|
||||
function getFieldRaw(tr,f){var td=tr.cells[f.idx];return td?td.textContent.trim():'';}
|
||||
function numericOf(v){var s=String(v).replace(/,/g,'').replace(/[¥¥]/g,'');var m=s.match(/[-+]?\d+(?:\.\d+)?/);return m?parseFloat(m[0]):null;}
|
||||
function matchCondition(tr,cond){
|
||||
var f=fieldByKey(cond.field);if(!f)return true;
|
||||
var str=getFieldRaw(tr,f);
|
||||
if(cond.op==='包含')return str.indexOf(cond.value)>=0;
|
||||
if(cond.op==='=')return str===cond.value;
|
||||
if(cond.op==='!=')return str!==cond.value;
|
||||
var n=numericOf(str);
|
||||
if(n===null)return false;
|
||||
if(cond.op==='范围'){
|
||||
if(cond.from!==''){var lo=parseFloat(cond.from);if(!isNaN(lo)&&n<lo)return false;}
|
||||
if(cond.to!==''){var hi=parseFloat(cond.to);if(!isNaN(hi)&&n>hi)return false;}
|
||||
return true;
|
||||
}
|
||||
var c=parseFloat(cond.value);if(isNaN(c))return false;
|
||||
if(cond.op==='>')return n>c;
|
||||
if(cond.op==='>=')return n>=c;
|
||||
if(cond.op==='<')return n<c;
|
||||
if(cond.op==='<=')return n<=c;
|
||||
return true;
|
||||
}
|
||||
function applyFilter(){
|
||||
var conds=readAdvancedConditions();
|
||||
document.querySelectorAll(ADV_ROW_SELECTOR).forEach(function(tr){
|
||||
var show=true;
|
||||
for(var i=0;i<conds.length;i++){if(!matchCondition(tr,conds[i])){show=false;break;}}
|
||||
tr.style.display=show?'':'none';
|
||||
});
|
||||
showToast('查询完成');
|
||||
}
|
||||
function clearAdvanced(){
|
||||
document.getElementById('advConditions').innerHTML='';
|
||||
document.querySelectorAll(ADV_ROW_SELECTOR).forEach(function(tr){tr.style.display='';});
|
||||
showToast('已清空高级查询条件');
|
||||
}
|
||||
/* 轻提示 */
|
||||
var toastTimer=null;
|
||||
function showToast(msg){
|
||||
document.getElementById('toastText').textContent=msg;
|
||||
var t=document.getElementById('toast');
|
||||
t.classList.add('show');clearTimeout(toastTimer);
|
||||
toastTimer=setTimeout(function(){t.classList.remove('show');},2400);
|
||||
}
|
||||
</script>
|
||||
<!-- 轻提示 -->
|
||||
<div class="toast" id="toast">
|
||||
<svg width="15" height="15" viewBox="0 0 15 15" fill="none"><circle cx="7.5" cy="7.5" r="6.5" fill="#52C41A"/><path d="M4.6 7.7l2 2 3.8-4" stroke="#fff" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||
<span id="toastText"></span>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -120,6 +120,25 @@
|
||||
.year-picker__dropdown div{padding:8px 14px;font-size:var(--font-sm);cursor:pointer;}
|
||||
.year-picker__dropdown div:hover{background:var(--primary-light);}
|
||||
.year-picker__dropdown div.selected{color:var(--primary);font-weight:600;}
|
||||
/* 高级查询 */
|
||||
.adv-panel{background:#fff;border-radius:var(--radius-md);padding:16px 24px;margin-bottom:16px;box-shadow:var(--shadow-sm);display:none;}
|
||||
.adv-panel.open{display:block;}
|
||||
.adv-panel__head{font-size:var(--font-base);font-weight:600;margin-bottom:12px;}
|
||||
#advConditions{display:grid;grid-template-columns:1fr 1fr;gap:10px 16px;}
|
||||
.adv-cond-row{display:flex;align-items:center;gap:8px;margin-bottom:0;min-width:0;}
|
||||
.adv-field{min-width:140px;flex:1;}
|
||||
.adv-op{min-width:72px;flex:none;}
|
||||
.adv-value-wrap{display:flex;align-items:center;gap:8px;flex:1;min-width:0;max-width:none;}
|
||||
.adv-value{flex:1;min-width:0;}
|
||||
.adv-range-sep{color:var(--text-secondary);flex-shrink:0;}
|
||||
.adv-del{width:32px;height:32px;border:1px solid var(--border);border-radius:var(--radius-sm);background:#fff;color:var(--text-secondary);cursor:pointer;flex-shrink:0;font-size:var(--font-sm);line-height:1;}
|
||||
.adv-del:hover{color:var(--danger);border-color:var(--danger);}
|
||||
.adv-actions{display:flex;gap:12px;margin-top:2px;}
|
||||
.adv-arrow{font-size:10px;}
|
||||
/* 轻提示 */
|
||||
.toast{position:fixed;top:76px;left:50%;transform:translateX(-50%) translateY(-16px);background:#fff;box-shadow:var(--shadow-md);border-radius:var(--radius-sm);padding:10px 20px;font-size:var(--font-sm);color:var(--text-primary);opacity:0;pointer-events:none;transition:all .25s;z-index:1000;display:flex;align-items:center;gap:8px;}
|
||||
.toast.show{opacity:1;transform:translateX(-50%) translateY(0);}
|
||||
.toast svg{flex-shrink:0;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -157,9 +176,9 @@
|
||||
常规体检
|
||||
</div>
|
||||
<div class="sidebar-subgroup__body">
|
||||
<a href="mid-appointment-track.html" class="sidebar-item active">体检预约</a>
|
||||
<a href="mid-selected-items.html" class="sidebar-item">已选项目</a>
|
||||
<a href="mid-participation.html" class="sidebar-item">已检员工</a>
|
||||
<!-- <a href="mid-appointment-track.html" class="sidebar-item active">体检预约</a> -->
|
||||
<!-- <a href="mid-selected-items.html" class="sidebar-item">已选项目</a> -->
|
||||
<!-- <a href="mid-participation.html" class="sidebar-item">已检员工</a> -->
|
||||
<a href="mid-appointment-track2.html" class="sidebar-item">体检预约跟踪</a>
|
||||
<a href="mid-unit-appointment.html" class="sidebar-item">单位预约人数统计</a>
|
||||
<a href="mid-hospital-realtime.html" class="sidebar-item">医院实时预约人数</a>
|
||||
@@ -213,12 +232,6 @@
|
||||
<option>请选择单位部门</option><option>公司机关</option><option>第一采油厂</option><option>第二采油厂</option><option>第三采油厂</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label>医院选择:</label>
|
||||
<select class="filter-select">
|
||||
<option>请选择医院</option><option>延安医院</option><option>泾河医院</option><option>市中心医院</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label>姓名:</label>
|
||||
<input class="filter-input" type="text" placeholder="请输入姓名" style="width:130px;min-width:unset;">
|
||||
@@ -231,53 +244,23 @@
|
||||
<label>身份证号:</label>
|
||||
<input class="filter-input" type="text" placeholder="请输入身份证号" style="width:180px;min-width:unset;">
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label>性别:</label>
|
||||
<select class="filter-select">
|
||||
<option>请选择性别</option><option>男</option><option>女</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label>年龄范围:</label>
|
||||
<select class="filter-select">
|
||||
<option>请选择年龄范围</option><option>年龄<35</option><option>35≤年龄<40</option><option>40≤年龄<45</option><option>年龄≥45</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label>机构分类:</label>
|
||||
<select class="filter-select">
|
||||
<option>请选择机构分类</option><option>子公司</option><option>三产公司</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label>是否上市员工:</label>
|
||||
<select class="filter-select">
|
||||
<option>请选择</option><option>是</option><option>否</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label>防癌项:</label>
|
||||
<select class="filter-select">
|
||||
<option>请选择防癌项</option><option>Septin9</option><option>CA724</option><option>两项都有</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label>体检状态:</label>
|
||||
<select class="filter-select">
|
||||
<option>请选择体检状态</option><option>未体检</option><option>体检中</option><option>已体检</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label>预约状态:</label>
|
||||
<select class="filter-select">
|
||||
<option>请选择预约状态</option><option>未预约</option><option>已预约</option><option>已取消预约</option>
|
||||
</select>
|
||||
</div>
|
||||
<button class="btn btn-primary">
|
||||
<svg width="14" height="14" viewBox="0 0 14 14" fill="none"><circle cx="6" cy="6" r="4" stroke="currentColor" stroke-width="1.4"/><path d="M10 10l2.5 2.5" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"/></svg>
|
||||
查询
|
||||
</button>
|
||||
<button class="btn btn-default">重置</button>
|
||||
<button class="btn btn-default" id="advToggle" onclick="toggleAdvanced()">高级查询 <span class="adv-arrow">▾</span></button>
|
||||
</div>
|
||||
|
||||
<!-- 高级查询 -->
|
||||
<div class="adv-panel" id="advPanel">
|
||||
<div class="adv-panel__head">高级查询</div>
|
||||
<div id="advConditions"></div>
|
||||
<div class="adv-actions">
|
||||
<button class="btn btn-default" onclick="addAdvCondition()">+ 添加条件</button>
|
||||
<button class="btn btn-primary" onclick="applyFilter()">查询</button>
|
||||
<button class="btn btn-default" onclick="clearAdvanced()">清空</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 操作栏 -->
|
||||
@@ -509,6 +492,117 @@ document.querySelectorAll('.year-picker>input').forEach(function(inp){
|
||||
document.addEventListener('click',function(){
|
||||
document.querySelectorAll('.year-picker__dropdown.open').forEach(function(d){d.classList.remove('open');});
|
||||
});
|
||||
/* ============ 高级查询 ============ */
|
||||
var ADV_OPS=['包含','=','!=','>','>=','<','<=','范围'];
|
||||
var ADV_ROW_SELECTOR='.table-card__content tbody tr';
|
||||
var ADV_FIELDS=[
|
||||
{key:'name',label:'姓名',idx:1},{key:'gender',label:'性别',idx:2},{key:'age',label:'年龄',idx:3},
|
||||
{key:'ageRange',label:'年龄范围',idx:4},{key:'idCard',label:'身份证号',idx:5},{key:'unit',label:'单位',idx:6},
|
||||
{key:'dept',label:'部门',idx:7},{key:'orgType',label:'机构分类',idx:8},{key:'empNo',label:'员工编号',idx:9},
|
||||
{key:'examCode',label:'体检编码',idx:10},{key:'empType',label:'用工形式',idx:11},{key:'marriage',label:'婚姻状态',idx:12},
|
||||
{key:'examType',label:'体检类型',idx:13},{key:'cancer',label:'防癌项',idx:14},{key:'listed',label:'是否上市员工',idx:15},
|
||||
{key:'hospital',label:'体检医院',idx:16},{key:'feeTotal',label:'体检总费用',idx:17},{key:'fee1',label:'必检费用',idx:18},
|
||||
{key:'fee2',label:'选检费用',idx:19},{key:'fee3',label:'妇科费用',idx:20},{key:'fee4',label:'防癌筛查费用',idx:21},
|
||||
{key:'bookStatus',label:'预约状态',idx:22},{key:'bookInfo',label:'体检预约信息',idx:23},{key:'bookDate',label:'预约日期',idx:24},
|
||||
{key:'examStatus',label:'体检状态',idx:25},{key:'examDate',label:'体检日期',idx:26},{key:'year',label:'体检年份',idx:27},
|
||||
{key:'plan',label:'体检计划',idx:28}
|
||||
];
|
||||
var ADV_FIELD_OPTS=ADV_FIELDS.map(function(f){return '<option value="'+f.key+'">'+f.label+'</option>';}).join('');
|
||||
function advConditionRowHTML(){
|
||||
return '<div class="adv-cond-row">'
|
||||
+'<select class="filter-select adv-field">'+ADV_FIELD_OPTS+'</select>'
|
||||
+'<select class="filter-select adv-op" onchange="onAdvOpChange(this)">'+ADV_OPS.map(function(o){return '<option value="'+o+'">'+o+'</option>';}).join('')+'</select>'
|
||||
+'<span class="adv-value-wrap"><input class="filter-input adv-value" type="text" placeholder="请输入值"></span>'
|
||||
+'<button class="adv-del" type="button" title="删除该条件" onclick="removeAdvCondition(this)">✕</button>'
|
||||
+'</div>';
|
||||
}
|
||||
function onAdvOpChange(sel){
|
||||
var wrap=sel.parentElement.querySelector('.adv-value-wrap');
|
||||
var isRange=sel.value==='范围';
|
||||
var alreadyRange=!!wrap.querySelector('.adv-range-from');
|
||||
if(isRange&&!alreadyRange){
|
||||
wrap.innerHTML='<input class="filter-input adv-value adv-range-from" type="text" placeholder="最小值">'
|
||||
+'<span class="adv-range-sep">~</span>'
|
||||
+'<input class="filter-input adv-value adv-range-to" type="text" placeholder="最大值">';
|
||||
}else if(!isRange&&alreadyRange){
|
||||
wrap.innerHTML='<input class="filter-input adv-value" type="text" placeholder="请输入值">';
|
||||
}
|
||||
}
|
||||
function addAdvCondition(){document.getElementById('advConditions').insertAdjacentHTML('beforeend',advConditionRowHTML());}
|
||||
function removeAdvCondition(el){el.parentElement.remove();}
|
||||
function toggleAdvanced(){
|
||||
var p=document.getElementById('advPanel');
|
||||
var open=p.classList.toggle('open');
|
||||
var arr=document.getElementById('advToggle').querySelector('.adv-arrow');
|
||||
if(arr)arr.textContent=open?'▴':'▾';
|
||||
if(open&&!p.querySelector('.adv-cond-row'))addAdvCondition();
|
||||
}
|
||||
function readAdvancedConditions(){
|
||||
var conds=[];
|
||||
document.querySelectorAll('#advConditions .adv-cond-row').forEach(function(row){
|
||||
var field=row.querySelector('.adv-field').value;
|
||||
var op=row.querySelector('.adv-op').value;
|
||||
if(op==='范围'){
|
||||
var from=row.querySelector('.adv-range-from').value.trim();
|
||||
var to=row.querySelector('.adv-range-to').value.trim();
|
||||
if(from!==''||to!=='')conds.push({field:field,op:op,from:from,to:to});
|
||||
}else{
|
||||
var value=row.querySelector('.adv-value').value.trim();
|
||||
if(value!=='')conds.push({field:field,op:op,value:value});
|
||||
}
|
||||
});
|
||||
return conds;
|
||||
}
|
||||
function fieldByKey(key){for(var i=0;i<ADV_FIELDS.length;i++){if(ADV_FIELDS[i].key===key)return ADV_FIELDS[i];}return null;}
|
||||
function getFieldRaw(tr,f){var td=tr.cells[f.idx];return td?td.textContent.trim():'';}
|
||||
function numericOf(v){var s=String(v).replace(/,/g,'').replace(/[¥¥]/g,'');var m=s.match(/[-+]?\d+(?:\.\d+)?/);return m?parseFloat(m[0]):null;}
|
||||
function matchCondition(tr,cond){
|
||||
var f=fieldByKey(cond.field);if(!f)return true;
|
||||
var str=getFieldRaw(tr,f);
|
||||
if(cond.op==='包含')return str.indexOf(cond.value)>=0;
|
||||
if(cond.op==='=')return str===cond.value;
|
||||
if(cond.op==='!=')return str!==cond.value;
|
||||
var n=numericOf(str);
|
||||
if(n===null)return false;
|
||||
if(cond.op==='范围'){
|
||||
if(cond.from!==''){var lo=parseFloat(cond.from);if(!isNaN(lo)&&n<lo)return false;}
|
||||
if(cond.to!==''){var hi=parseFloat(cond.to);if(!isNaN(hi)&&n>hi)return false;}
|
||||
return true;
|
||||
}
|
||||
var c=parseFloat(cond.value);if(isNaN(c))return false;
|
||||
if(cond.op==='>')return n>c;
|
||||
if(cond.op==='>=')return n>=c;
|
||||
if(cond.op==='<')return n<c;
|
||||
if(cond.op==='<=')return n<=c;
|
||||
return true;
|
||||
}
|
||||
function applyFilter(){
|
||||
var conds=readAdvancedConditions();
|
||||
document.querySelectorAll(ADV_ROW_SELECTOR).forEach(function(tr){
|
||||
var show=true;
|
||||
for(var i=0;i<conds.length;i++){if(!matchCondition(tr,conds[i])){show=false;break;}}
|
||||
tr.style.display=show?'':'none';
|
||||
});
|
||||
showToast('查询完成');
|
||||
}
|
||||
function clearAdvanced(){
|
||||
document.getElementById('advConditions').innerHTML='';
|
||||
document.querySelectorAll(ADV_ROW_SELECTOR).forEach(function(tr){tr.style.display='';});
|
||||
showToast('已清空高级查询条件');
|
||||
}
|
||||
/* 轻提示 */
|
||||
var toastTimer=null;
|
||||
function showToast(msg){
|
||||
document.getElementById('toastText').textContent=msg;
|
||||
var t=document.getElementById('toast');
|
||||
t.classList.add('show');clearTimeout(toastTimer);
|
||||
toastTimer=setTimeout(function(){t.classList.remove('show');},2400);
|
||||
}
|
||||
</script>
|
||||
<!-- 轻提示 -->
|
||||
<div class="toast" id="toast">
|
||||
<svg width="15" height="15" viewBox="0 0 15 15" fill="none"><circle cx="7.5" cy="7.5" r="6.5" fill="#52C41A"/><path d="M4.6 7.7l2 2 3.8-4" stroke="#fff" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||
<span id="toastText"></span>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -146,6 +146,25 @@
|
||||
.year-picker__dropdown div{padding:8px 14px;font-size:var(--font-sm);cursor:pointer;}
|
||||
.year-picker__dropdown div:hover{background:var(--primary-light);}
|
||||
.year-picker__dropdown div.selected{color:var(--primary);font-weight:600;}
|
||||
/* 高级查询 */
|
||||
.adv-panel{background:#fff;border-radius:var(--radius-md);padding:16px 24px;margin-bottom:16px;box-shadow:var(--shadow-sm);display:none;}
|
||||
.adv-panel.open{display:block;}
|
||||
.adv-panel__head{font-size:var(--font-base);font-weight:600;margin-bottom:12px;}
|
||||
[id^="advConditions"]{display:grid;grid-template-columns:1fr 1fr;gap:10px 16px;}
|
||||
.adv-cond-row{display:flex;align-items:center;gap:8px;margin-bottom:0;min-width:0;}
|
||||
.adv-field{min-width:140px;flex:1;}
|
||||
.adv-op{min-width:72px;flex:none;}
|
||||
.adv-value-wrap{display:flex;align-items:center;gap:8px;flex:1;min-width:0;max-width:none;}
|
||||
.adv-value{flex:1;min-width:0;}
|
||||
.adv-range-sep{color:var(--text-secondary);flex-shrink:0;}
|
||||
.adv-del{width:32px;height:32px;border:1px solid var(--border);border-radius:var(--radius-sm);background:#fff;color:var(--text-secondary);cursor:pointer;flex-shrink:0;font-size:var(--font-sm);line-height:1;}
|
||||
.adv-del:hover{color:var(--danger);border-color:var(--danger);}
|
||||
.adv-actions{display:flex;gap:12px;margin-top:2px;}
|
||||
.adv-arrow{font-size:10px;}
|
||||
/* 轻提示 */
|
||||
.toast{position:fixed;top:76px;left:50%;transform:translateX(-50%) translateY(-16px);background:#fff;box-shadow:var(--shadow-md);border-radius:var(--radius-sm);padding:10px 20px;font-size:var(--font-sm);color:var(--text-primary);opacity:0;pointer-events:none;transition:all .25s;z-index:1000;display:flex;align-items:center;gap:8px;}
|
||||
.toast.show{opacity:1;transform:translateX(-50%) translateY(0);}
|
||||
.toast svg{flex-shrink:0;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -183,9 +202,9 @@
|
||||
常规体检
|
||||
</div>
|
||||
<div class="sidebar-subgroup__body">
|
||||
<a href="mid-appointment-track.html" class="sidebar-item">体检预约</a>
|
||||
<a href="mid-selected-items.html" class="sidebar-item">已选项目</a>
|
||||
<a href="mid-participation.html" class="sidebar-item">已检员工</a>
|
||||
<!-- <a href="mid-appointment-track.html" class="sidebar-item">体检预约</a> -->
|
||||
<!-- <a href="mid-selected-items.html" class="sidebar-item">已选项目</a> -->
|
||||
<!-- <a href="mid-participation.html" class="sidebar-item">已检员工</a> -->
|
||||
<a href="mid-appointment-track2.html" class="sidebar-item active">体检预约跟踪</a>
|
||||
<a href="mid-unit-appointment.html" class="sidebar-item">单位预约人数统计</a>
|
||||
<a href="mid-hospital-realtime.html" class="sidebar-item">医院实时预约人数</a>
|
||||
@@ -249,77 +268,35 @@
|
||||
<option>请选择单位部门</option><option>公司机关</option><option>第一采油厂</option><option>第二采油厂</option><option>第三采油厂</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label>医院选择:</label>
|
||||
<select class="filter-select">
|
||||
<option>请选择医院</option><option>延安医院</option><option>泾河医院</option><option>市中心医院</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label>姓名:</label>
|
||||
<input class="filter-input" type="text" placeholder="请输入姓名" style="width:130px;min-width:unset;">
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label>员工编号:</label>
|
||||
<input class="filter-input" type="text" placeholder="请输入" style="width:140px;min-width:unset;">
|
||||
<input class="filter-input" type="text" placeholder="请输入员工编号" style="width:140px;min-width:unset;">
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label>身份证号:</label>
|
||||
<input class="filter-input" type="text" placeholder="请输入身份证号" style="width:180px;min-width:unset;">
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label>性别:</label>
|
||||
<select class="filter-select">
|
||||
<option>请选择性别</option><option>男</option><option>女</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label>年龄范围:</label>
|
||||
<select class="filter-select">
|
||||
<option>请选择年龄范围</option><option>年龄<35</option><option>35≤年龄<40</option><option>40≤年龄<45</option><option>年龄≥45</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label>机构分类:</label>
|
||||
<select class="filter-select">
|
||||
<option>请选择机构分类</option><option>子公司</option><option>三产公司</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label>是否上市员工:</label>
|
||||
<select class="filter-select">
|
||||
<option>请选择</option><option>是</option><option>否</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label>防癌项:</label>
|
||||
<select class="filter-select">
|
||||
<option>请选择防癌项</option><option>Septin9</option><option>CA724</option><option>两项都有</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label>体检状态:</label>
|
||||
<select class="filter-select">
|
||||
<option>请选择体检状态</option><option>未体检</option><option>体检中</option><option>已体检</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label>预约状态:</label>
|
||||
<select class="filter-select">
|
||||
<option>请选择预约状态</option><option>未预约</option><option>已预约</option><option>已取消预约</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label>前置机预约状态:</label>
|
||||
<select class="filter-select">
|
||||
<option>请选择前置机预约状态</option><option>未预约</option><option>预约成功</option><option>已取消预约</option><option>预约失败</option><option>预约中</option><option>取消预约失败</option>
|
||||
</select>
|
||||
</div>
|
||||
<button class="btn btn-primary">
|
||||
<svg width="14" height="14" viewBox="0 0 14 14" fill="none"><circle cx="6" cy="6" r="4" stroke="currentColor" stroke-width="1.4"/><path d="M10 10l2.5 2.5" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"/></svg>
|
||||
查询
|
||||
</button>
|
||||
<button class="btn btn-default">重置</button>
|
||||
<button class="btn btn-default" id="advToggle-should" onclick="toggleAdvanced('should')">高级查询 <span class="adv-arrow">▾</span></button>
|
||||
</div>
|
||||
|
||||
<!-- 高级查询 -->
|
||||
<div class="adv-panel" id="advPanel-should">
|
||||
<div class="adv-panel__head">高级查询</div>
|
||||
<div id="advConditions-should"></div>
|
||||
<div class="adv-actions">
|
||||
<button class="btn btn-default" onclick="addAdvCondition('should')">+ 添加条件</button>
|
||||
<button class="btn btn-primary" onclick="applyFilter('should')">查询</button>
|
||||
<button class="btn btn-default" onclick="clearAdvanced('should')">清空</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 操作栏 -->
|
||||
@@ -405,12 +382,6 @@
|
||||
<option>请选择单位部门</option><option>公司机关</option><option>第一采油厂</option><option>第二采油厂</option><option>第三采油厂</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label>医院选择:</label>
|
||||
<select class="filter-select">
|
||||
<option>请选择医院</option><option>延安医院</option><option>泾河医院</option><option>兴隆园医院</option><option>市中心医院</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label>姓名:</label>
|
||||
<input class="filter-input" type="text" placeholder="请输入姓名" style="width:130px;min-width:unset;">
|
||||
@@ -428,6 +399,18 @@
|
||||
查询
|
||||
</button>
|
||||
<button class="btn btn-default">重置</button>
|
||||
<button class="btn btn-default" id="advToggle-selected" onclick="toggleAdvanced('selected')">高级查询 <span class="adv-arrow">▾</span></button>
|
||||
</div>
|
||||
|
||||
<!-- 高级查询 -->
|
||||
<div class="adv-panel" id="advPanel-selected">
|
||||
<div class="adv-panel__head">高级查询</div>
|
||||
<div id="advConditions-selected"></div>
|
||||
<div class="adv-actions">
|
||||
<button class="btn btn-default" onclick="addAdvCondition('selected')">+ 添加条件</button>
|
||||
<button class="btn btn-primary" onclick="applyFilter('selected')">查询</button>
|
||||
<button class="btn btn-default" onclick="clearAdvanced('selected')">清空</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 操作栏 -->
|
||||
@@ -509,12 +492,6 @@
|
||||
<option>请选择单位部门</option><option>公司机关</option><option>第一采油厂</option><option>第二采油厂</option><option>第三采油厂</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label>医院选择:</label>
|
||||
<select class="filter-select">
|
||||
<option>请选择医院</option><option>延安医院</option><option>泾河医院</option><option>兴隆园医院</option><option>市中心医院</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label>姓名:</label>
|
||||
<input class="filter-input" type="text" placeholder="请输入姓名" style="width:130px;min-width:unset;">
|
||||
@@ -527,15 +504,23 @@
|
||||
<label>身份证号:</label>
|
||||
<input class="filter-input" type="text" placeholder="请输入身份证号" style="width:180px;min-width:unset;">
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label>体检编码:</label>
|
||||
<input class="filter-input" type="text" placeholder="请输入体检编码" style="width:150px;min-width:unset;">
|
||||
</div>
|
||||
<button class="btn btn-primary">
|
||||
<svg width="14" height="14" viewBox="0 0 14 14" fill="none"><circle cx="6" cy="6" r="4" stroke="currentColor" stroke-width="1.4"/><path d="M10 10l2.5 2.5" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"/></svg>
|
||||
查询
|
||||
</button>
|
||||
<button class="btn btn-default">重置</button>
|
||||
<button class="btn btn-default" id="advToggle-booked" onclick="toggleAdvanced('booked')">高级查询 <span class="adv-arrow">▾</span></button>
|
||||
</div>
|
||||
|
||||
<!-- 高级查询 -->
|
||||
<div class="adv-panel" id="advPanel-booked">
|
||||
<div class="adv-panel__head">高级查询</div>
|
||||
<div id="advConditions-booked"></div>
|
||||
<div class="adv-actions">
|
||||
<button class="btn btn-default" onclick="addAdvCondition('booked')">+ 添加条件</button>
|
||||
<button class="btn btn-primary" onclick="applyFilter('booked')">查询</button>
|
||||
<button class="btn btn-default" onclick="clearAdvanced('booked')">清空</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 操作栏 -->
|
||||
@@ -622,54 +607,38 @@
|
||||
<div class="filter-item">
|
||||
<label>单位部门:</label>
|
||||
<select class="filter-select">
|
||||
<option>请选择</option><option>公司机关</option><option>第一采油厂</option><option>第二采油厂</option><option>第三采油厂</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label>体检医院:</label>
|
||||
<select class="filter-select">
|
||||
<option>请选择</option><option>延安医院</option><option>市中心医院</option><option>矿区总医院</option>
|
||||
<option>请选择单位部门</option><option>公司机关</option><option>第一采油厂</option><option>第二采油厂</option><option>第三采油厂</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label>姓名:</label>
|
||||
<input class="filter-input" type="text" placeholder="请输入" style="width:130px;min-width:unset;">
|
||||
<input class="filter-input" type="text" placeholder="请输入姓名" style="width:130px;min-width:unset;">
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label>员工编号:</label>
|
||||
<input class="filter-input" type="text" placeholder="请输入" style="width:140px;min-width:unset;">
|
||||
<input class="filter-input" type="text" placeholder="请输入员工编号" style="width:140px;min-width:unset;">
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label>身份证号:</label>
|
||||
<input class="filter-input" type="text" placeholder="请输入" style="width:180px;min-width:unset;">
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label>体检编码:</label>
|
||||
<input class="filter-input" type="text" placeholder="请输入" style="width:150px;min-width:unset;">
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label>系统体检状态:</label>
|
||||
<select class="filter-select">
|
||||
<option>请选择</option><option>未体检</option><option>体检中</option><option>已体检</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label>医院体检状态:</label>
|
||||
<select class="filter-select">
|
||||
<option>请选择</option><option>未预约</option><option>已预约</option><option>体检中</option><option>已终审</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label>体检日期:</label>
|
||||
<input class="filter-input" type="date" style="width:150px;min-width:unset;">
|
||||
<span style="color:var(--text-secondary);">至</span>
|
||||
<input class="filter-input" type="date" style="width:150px;min-width:unset;">
|
||||
<input class="filter-input" type="text" placeholder="请输入身份证号" style="width:180px;min-width:unset;">
|
||||
</div>
|
||||
<button class="btn btn-primary">
|
||||
<svg width="14" height="14" viewBox="0 0 14 14" fill="none"><circle cx="6" cy="6" r="4" stroke="currentColor" stroke-width="1.4"/><path d="M10 10l2.5 2.5" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"/></svg>
|
||||
查询
|
||||
</button>
|
||||
<button class="btn btn-default">重置</button>
|
||||
<button class="btn btn-default" id="advToggle-participated" onclick="toggleAdvanced('participated')">高级查询 <span class="adv-arrow">▾</span></button>
|
||||
</div>
|
||||
|
||||
<!-- 高级查询 -->
|
||||
<div class="adv-panel" id="advPanel-participated">
|
||||
<div class="adv-panel__head">高级查询</div>
|
||||
<div id="advConditions-participated"></div>
|
||||
<div class="adv-actions">
|
||||
<button class="btn btn-default" onclick="addAdvCondition('participated')">+ 添加条件</button>
|
||||
<button class="btn btn-primary" onclick="applyFilter('participated')">查询</button>
|
||||
<button class="btn btn-default" onclick="clearAdvanced('participated')">清空</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 操作栏 -->
|
||||
@@ -1114,6 +1083,148 @@ document.querySelectorAll('.year-picker>input').forEach(function(inp){
|
||||
document.addEventListener('click',function(){
|
||||
document.querySelectorAll('.year-picker__dropdown.open').forEach(function(d){d.classList.remove('open');});
|
||||
});
|
||||
/* ============ 高级查询 ============ */
|
||||
var ADV_OPS=['包含','=','!=','>','>=','<','<=','范围'];
|
||||
var ADV_TABS={
|
||||
'should':{
|
||||
selector:'#tab-should .table-card__content tbody tr',
|
||||
fields:[
|
||||
{key:'name',label:'姓名',idx:1},{key:'empNo',label:'员工编号',idx:2},{key:'gender',label:'性别',idx:3},
|
||||
{key:'age',label:'年龄',idx:4},{key:'idCard',label:'身份证号',idx:5},{key:'unit',label:'单位',idx:6},
|
||||
{key:'dept',label:'部门',idx:7},{key:'orgType',label:'机构分类',idx:8},{key:'examCode',label:'体检编码',idx:9},
|
||||
{key:'empType',label:'用工形式',idx:10},{key:'marriage',label:'婚姻状态',idx:11},{key:'cancer',label:'防癌项',idx:12},
|
||||
{key:'listed',label:'是否上市员工',idx:13},{key:'bookStatus',label:'预约状态',idx:14},{key:'frontStatus',label:'前置机预约状态',idx:15},
|
||||
{key:'bookDate',label:'预约日期',idx:16},{key:'examStatus',label:'体检状态',idx:17},{key:'examDate',label:'体检日期',idx:18},
|
||||
{key:'year',label:'体检年份',idx:19},{key:'plan',label:'体检计划',idx:20}
|
||||
]
|
||||
},
|
||||
'selected':{
|
||||
selector:'#tab-selected .table-card__content tbody tr',
|
||||
fields:[
|
||||
{key:'name',label:'姓名',idx:1},{key:'empNo',label:'员工编号',idx:2},{key:'gender',label:'性别',idx:3},
|
||||
{key:'age',label:'年龄',idx:4},{key:'idCard',label:'身份证号',idx:5},{key:'unit',label:'单位',idx:6},
|
||||
{key:'dept',label:'部门',idx:7},{key:'hospital',label:'体检医院',idx:8},{key:'itemCount',label:'体检项目数',idx:9},
|
||||
{key:'feeTotal',label:'体检总费用',idx:10},{key:'fee1',label:'必检费用',idx:11},{key:'fee2',label:'选检费用',idx:12},
|
||||
{key:'fee3',label:'妇科费用',idx:13},{key:'fee4',label:'防癌筛查费用',idx:14},{key:'submitDate',label:'提交项目日期',idx:15},
|
||||
{key:'year',label:'体检年份',idx:16},{key:'plan',label:'体检计划',idx:17}
|
||||
]
|
||||
},
|
||||
'booked':{
|
||||
selector:'#tab-booked .table-card__content tbody tr',
|
||||
fields:[
|
||||
{key:'name',label:'姓名',idx:2},{key:'empNo',label:'员工编号',idx:3},{key:'gender',label:'性别',idx:4},
|
||||
{key:'age',label:'年龄',idx:5},{key:'idCard',label:'身份证号',idx:6},{key:'unit',label:'单位',idx:7},
|
||||
{key:'dept',label:'部门',idx:8},{key:'hospital',label:'体检医院',idx:9},{key:'examCode',label:'体检编码',idx:10},
|
||||
{key:'bookDate',label:'预约日期',idx:11},{key:'year',label:'体检年份',idx:12},{key:'plan',label:'体检计划',idx:13}
|
||||
]
|
||||
},
|
||||
'participated':{
|
||||
selector:'#tab-participated .table-card__content tbody tr',
|
||||
fields:[
|
||||
{key:'name',label:'姓名',idx:1},{key:'empNo',label:'员工编号',idx:2},{key:'gender',label:'性别',idx:3},
|
||||
{key:'age',label:'年龄',idx:4},{key:'idCard',label:'身份证号',idx:5},{key:'unit',label:'单位',idx:6},
|
||||
{key:'dept',label:'部门',idx:7},{key:'hospital',label:'体检医院',idx:8},{key:'examCode',label:'体检编码',idx:9},
|
||||
{key:'sysStatus',label:'系统体检状态',idx:10},{key:'hospStatus',label:'医院体检状态',idx:11},{key:'examDate',label:'体检日期',idx:12},
|
||||
{key:'checkedItems',label:'已检项/全部',idx:13},{key:'year',label:'体检年份',idx:14},{key:'plan',label:'体检计划',idx:15}
|
||||
]
|
||||
}
|
||||
};
|
||||
function fieldOpts(tabId){return ADV_TABS[tabId].fields.map(function(f){return '<option value="'+f.key+'">'+f.label+'</option>';}).join('');}
|
||||
function advConditionRowHTML(tabId){
|
||||
return '<div class="adv-cond-row">'
|
||||
+'<select class="filter-select adv-field">'+fieldOpts(tabId)+'</select>'
|
||||
+'<select class="filter-select adv-op" onchange="onAdvOpChange(this)">'+ADV_OPS.map(function(o){return '<option value="'+o+'">'+o+'</option>';}).join('')+'</select>'
|
||||
+'<span class="adv-value-wrap"><input class="filter-input adv-value" type="text" placeholder="请输入值"></span>'
|
||||
+'<button class="adv-del" type="button" title="删除该条件" onclick="removeAdvCondition(this)">✕</button>'
|
||||
+'</div>';
|
||||
}
|
||||
function onAdvOpChange(sel){
|
||||
var wrap=sel.parentElement.querySelector('.adv-value-wrap');
|
||||
var isRange=sel.value==='范围';
|
||||
var alreadyRange=!!wrap.querySelector('.adv-range-from');
|
||||
if(isRange&&!alreadyRange){
|
||||
wrap.innerHTML='<input class="filter-input adv-value adv-range-from" type="text" placeholder="最小值">'
|
||||
+'<span class="adv-range-sep">~</span>'
|
||||
+'<input class="filter-input adv-value adv-range-to" type="text" placeholder="最大值">';
|
||||
}else if(!isRange&&alreadyRange){
|
||||
wrap.innerHTML='<input class="filter-input adv-value" type="text" placeholder="请输入值">';
|
||||
}
|
||||
}
|
||||
function addAdvCondition(tabId){document.getElementById('advConditions-'+tabId).insertAdjacentHTML('beforeend',advConditionRowHTML(tabId));}
|
||||
function removeAdvCondition(el){el.parentElement.remove();}
|
||||
function toggleAdvanced(tabId){
|
||||
var p=document.getElementById('advPanel-'+tabId);
|
||||
var open=p.classList.toggle('open');
|
||||
var arr=document.getElementById('advToggle-'+tabId).querySelector('.adv-arrow');
|
||||
if(arr)arr.textContent=open?'▴':'▾';
|
||||
if(open&&!p.querySelector('.adv-cond-row'))addAdvCondition(tabId);
|
||||
}
|
||||
function readAdvancedConditions(tabId){
|
||||
var conds=[];
|
||||
document.querySelectorAll('#advConditions-'+tabId+' .adv-cond-row').forEach(function(row){
|
||||
var field=row.querySelector('.adv-field').value;
|
||||
var op=row.querySelector('.adv-op').value;
|
||||
if(op==='范围'){
|
||||
var from=row.querySelector('.adv-range-from').value.trim();
|
||||
var to=row.querySelector('.adv-range-to').value.trim();
|
||||
if(from!==''||to!=='')conds.push({field:field,op:op,from:from,to:to});
|
||||
}else{
|
||||
var value=row.querySelector('.adv-value').value.trim();
|
||||
if(value!=='')conds.push({field:field,op:op,value:value});
|
||||
}
|
||||
});
|
||||
return conds;
|
||||
}
|
||||
function fieldByKey(tabId,key){var fields=ADV_TABS[tabId].fields;for(var i=0;i<fields.length;i++){if(fields[i].key===key)return fields[i];}return null;}
|
||||
function getFieldRaw(tr,f){var td=tr.cells[f.idx];return td?td.textContent.trim():'';}
|
||||
function numericOf(v){var s=String(v).replace(/,/g,'').replace(/[¥¥]/g,'');var m=s.match(/[-+]?\d+(?:\.\d+)?/);return m?parseFloat(m[0]):null;}
|
||||
function matchCondition(tr,cond,tabId){
|
||||
var f=fieldByKey(tabId,cond.field);if(!f)return true;
|
||||
var str=getFieldRaw(tr,f);
|
||||
if(cond.op==='包含')return str.indexOf(cond.value)>=0;
|
||||
if(cond.op==='=')return str===cond.value;
|
||||
if(cond.op==='!=')return str!==cond.value;
|
||||
var n=numericOf(str);
|
||||
if(n===null)return false;
|
||||
if(cond.op==='范围'){
|
||||
if(cond.from!==''){var lo=parseFloat(cond.from);if(!isNaN(lo)&&n<lo)return false;}
|
||||
if(cond.to!==''){var hi=parseFloat(cond.to);if(!isNaN(hi)&&n>hi)return false;}
|
||||
return true;
|
||||
}
|
||||
var c=parseFloat(cond.value);if(isNaN(c))return false;
|
||||
if(cond.op==='>')return n>c;
|
||||
if(cond.op==='>=')return n>=c;
|
||||
if(cond.op==='<')return n<c;
|
||||
if(cond.op==='<=')return n<=c;
|
||||
return true;
|
||||
}
|
||||
function applyFilter(tabId){
|
||||
var conds=readAdvancedConditions(tabId);
|
||||
document.querySelectorAll(ADV_TABS[tabId].selector).forEach(function(tr){
|
||||
var show=true;
|
||||
for(var i=0;i<conds.length;i++){if(!matchCondition(tr,conds[i],tabId)){show=false;break;}}
|
||||
tr.style.display=show?'':'none';
|
||||
});
|
||||
showToast('查询完成');
|
||||
}
|
||||
function clearAdvanced(tabId){
|
||||
document.getElementById('advConditions-'+tabId).innerHTML='';
|
||||
document.querySelectorAll(ADV_TABS[tabId].selector).forEach(function(tr){tr.style.display='';});
|
||||
showToast('已清空高级查询条件');
|
||||
}
|
||||
/* 轻提示 */
|
||||
var toastTimer=null;
|
||||
function showToast(msg){
|
||||
document.getElementById('toastText').textContent=msg;
|
||||
var t=document.getElementById('toast');
|
||||
t.classList.add('show');clearTimeout(toastTimer);
|
||||
toastTimer=setTimeout(function(){t.classList.remove('show');},2400);
|
||||
}
|
||||
</script>
|
||||
<!-- 轻提示 -->
|
||||
<div class="toast" id="toast">
|
||||
<svg width="15" height="15" viewBox="0 0 15 15" fill="none"><circle cx="7.5" cy="7.5" r="6.5" fill="#52C41A"/><path d="M4.6 7.7l2 2 3.8-4" stroke="#fff" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||
<span id="toastText"></span>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -150,9 +150,9 @@
|
||||
常规体检
|
||||
</div>
|
||||
<div class="sidebar-subgroup__body">
|
||||
<a href="mid-appointment-track.html" class="sidebar-item">体检预约</a>
|
||||
<a href="mid-selected-items.html" class="sidebar-item">已选项目</a>
|
||||
<a href="mid-participation.html" class="sidebar-item">已检员工</a>
|
||||
<!-- <a href="mid-appointment-track.html" class="sidebar-item">体检预约</a> -->
|
||||
<!-- <a href="mid-selected-items.html" class="sidebar-item">已选项目</a> -->
|
||||
<!-- <a href="mid-participation.html" class="sidebar-item">已检员工</a> -->
|
||||
<a href="mid-appointment-track2.html" class="sidebar-item">体检预约跟踪</a>
|
||||
<a href="mid-unit-appointment.html" class="sidebar-item">单位预约人数统计</a>
|
||||
<a href="mid-hospital-realtime.html" class="sidebar-item">医院实时预约人数</a>
|
||||
|
||||
@@ -87,6 +87,25 @@
|
||||
/* 三级单位tab下才显示的部门列 */
|
||||
.col-dept{display:none;}
|
||||
body.level-3 .col-dept{display:table-cell;}
|
||||
/* 高级查询 */
|
||||
.adv-panel{background:#fff;border-radius:var(--radius-md);padding:16px 24px;margin-bottom:16px;box-shadow:var(--shadow-sm);display:none;}
|
||||
.adv-panel.open{display:block;}
|
||||
.adv-panel__head{font-size:var(--font-base);font-weight:600;margin-bottom:12px;}
|
||||
#advConditions{display:grid;grid-template-columns:1fr 1fr;gap:10px 16px;}
|
||||
.adv-cond-row{display:flex;align-items:center;gap:8px;margin-bottom:0;min-width:0;}
|
||||
.adv-field{min-width:140px;flex:1;}
|
||||
.adv-op{min-width:72px;flex:none;}
|
||||
.adv-value-wrap{display:flex;align-items:center;gap:8px;flex:1;min-width:0;max-width:none;}
|
||||
.adv-value{flex:1;min-width:0;}
|
||||
.adv-range-sep{color:var(--text-secondary);flex-shrink:0;}
|
||||
.adv-del{width:32px;height:32px;border:1px solid var(--border);border-radius:var(--radius-sm);background:#fff;color:var(--text-secondary);cursor:pointer;flex-shrink:0;font-size:var(--font-sm);line-height:1;}
|
||||
.adv-del:hover{color:var(--danger);border-color:var(--danger);}
|
||||
.adv-actions{display:flex;gap:12px;margin-top:2px;}
|
||||
.adv-arrow{font-size:10px;}
|
||||
/* 轻提示 */
|
||||
.toast{position:fixed;top:76px;left:50%;transform:translateX(-50%) translateY(-16px);background:#fff;box-shadow:var(--shadow-md);border-radius:var(--radius-sm);padding:10px 20px;font-size:var(--font-sm);color:var(--text-primary);opacity:0;pointer-events:none;transition:all .25s;z-index:1000;display:flex;align-items:center;gap:8px;}
|
||||
.toast.show{opacity:1;transform:translateX(-50%) translateY(0);}
|
||||
.toast svg{flex-shrink:0;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -124,9 +143,9 @@
|
||||
常规体检
|
||||
</div>
|
||||
<div class="sidebar-subgroup__body">
|
||||
<a href="mid-appointment-track.html" class="sidebar-item">体检预约</a>
|
||||
<a href="mid-selected-items.html" class="sidebar-item">已选项目</a>
|
||||
<a href="mid-participation.html" class="sidebar-item">已检员工</a>
|
||||
<!-- <a href="mid-appointment-track.html" class="sidebar-item">体检预约</a> -->
|
||||
<!-- <a href="mid-selected-items.html" class="sidebar-item">已选项目</a> -->
|
||||
<!-- <a href="mid-participation.html" class="sidebar-item">已检员工</a> -->
|
||||
<a href="mid-appointment-track2.html" class="sidebar-item">体检预约跟踪</a>
|
||||
<a href="mid-unit-appointment.html" class="sidebar-item">单位预约人数统计</a>
|
||||
<a href="mid-hospital-realtime.html" class="sidebar-item">医院实时预约人数</a>
|
||||
@@ -179,6 +198,18 @@
|
||||
查询
|
||||
</button>
|
||||
<button class="btn btn-default">重置</button>
|
||||
<button class="btn btn-default" id="advToggle" onclick="toggleAdvanced()">高级查询 <span class="adv-arrow">▾</span></button>
|
||||
</div>
|
||||
|
||||
<!-- 高级查询 -->
|
||||
<div class="adv-panel" id="advPanel">
|
||||
<div class="adv-panel__head">高级查询</div>
|
||||
<div id="advConditions"></div>
|
||||
<div class="adv-actions">
|
||||
<button class="btn btn-default" onclick="addAdvCondition()">+ 添加条件</button>
|
||||
<button class="btn btn-primary" onclick="applyFilter()">查询</button>
|
||||
<button class="btn btn-default" onclick="clearAdvanced()">清空</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 操作栏 -->
|
||||
@@ -246,6 +277,110 @@ function toggleSubgroup(header){
|
||||
var sub=active.closest('.sidebar-subgroup');
|
||||
if(sub)sub.classList.add('open');
|
||||
})();
|
||||
/* ============ 高级查询 ============ */
|
||||
var ADV_OPS=['包含','=','!=','>','>=','<','<=','范围'];
|
||||
var ADV_ROW_SELECTOR='.table-card__content tbody tr';
|
||||
var ADV_FIELDS=[
|
||||
{key:'unit',label:'单位',idx:1},{key:'dept',label:'部门',idx:2},{key:'should',label:'应体检人数',idx:3},
|
||||
{key:'booked',label:'已预约人数',idx:4},{key:'participated',label:'已参检人数',idx:5},{key:'unparticipated',label:'未参检人数',idx:6},
|
||||
{key:'unbooked',label:'未预约人数',idx:7},{key:'year',label:'体检年份',idx:8}
|
||||
];
|
||||
var ADV_FIELD_OPTS=ADV_FIELDS.map(function(f){return '<option value="'+f.key+'">'+f.label+'</option>';}).join('');
|
||||
function advConditionRowHTML(){
|
||||
return '<div class="adv-cond-row">'
|
||||
+'<select class="filter-select adv-field">'+ADV_FIELD_OPTS+'</select>'
|
||||
+'<select class="filter-select adv-op" onchange="onAdvOpChange(this)">'+ADV_OPS.map(function(o){return '<option value="'+o+'">'+o+'</option>';}).join('')+'</select>'
|
||||
+'<span class="adv-value-wrap"><input class="filter-input adv-value" type="text" placeholder="请输入值"></span>'
|
||||
+'<button class="adv-del" type="button" title="删除该条件" onclick="removeAdvCondition(this)">✕</button>'
|
||||
+'</div>';
|
||||
}
|
||||
function onAdvOpChange(sel){
|
||||
var wrap=sel.parentElement.querySelector('.adv-value-wrap');
|
||||
var isRange=sel.value==='范围';
|
||||
var alreadyRange=!!wrap.querySelector('.adv-range-from');
|
||||
if(isRange&&!alreadyRange){
|
||||
wrap.innerHTML='<input class="filter-input adv-value adv-range-from" type="text" placeholder="最小值">'
|
||||
+'<span class="adv-range-sep">~</span>'
|
||||
+'<input class="filter-input adv-value adv-range-to" type="text" placeholder="最大值">';
|
||||
}else if(!isRange&&alreadyRange){
|
||||
wrap.innerHTML='<input class="filter-input adv-value" type="text" placeholder="请输入值">';
|
||||
}
|
||||
}
|
||||
function addAdvCondition(){document.getElementById('advConditions').insertAdjacentHTML('beforeend',advConditionRowHTML());}
|
||||
function removeAdvCondition(el){el.parentElement.remove();}
|
||||
function toggleAdvanced(){
|
||||
var p=document.getElementById('advPanel');
|
||||
var open=p.classList.toggle('open');
|
||||
var arr=document.getElementById('advToggle').querySelector('.adv-arrow');
|
||||
if(arr)arr.textContent=open?'▴':'▾';
|
||||
if(open&&!p.querySelector('.adv-cond-row'))addAdvCondition();
|
||||
}
|
||||
function readAdvancedConditions(){
|
||||
var conds=[];
|
||||
document.querySelectorAll('#advConditions .adv-cond-row').forEach(function(row){
|
||||
var field=row.querySelector('.adv-field').value;
|
||||
var op=row.querySelector('.adv-op').value;
|
||||
if(op==='范围'){
|
||||
var from=row.querySelector('.adv-range-from').value.trim();
|
||||
var to=row.querySelector('.adv-range-to').value.trim();
|
||||
if(from!==''||to!=='')conds.push({field:field,op:op,from:from,to:to});
|
||||
}else{
|
||||
var value=row.querySelector('.adv-value').value.trim();
|
||||
if(value!=='')conds.push({field:field,op:op,value:value});
|
||||
}
|
||||
});
|
||||
return conds;
|
||||
}
|
||||
function fieldByKey(key){for(var i=0;i<ADV_FIELDS.length;i++){if(ADV_FIELDS[i].key===key)return ADV_FIELDS[i];}return null;}
|
||||
function getFieldRaw(tr,f){var td=tr.cells[f.idx];return td?td.textContent.trim():'';}
|
||||
function numericOf(v){var s=String(v).replace(/,/g,'').replace(/[¥¥]/g,'');var m=s.match(/[-+]?\d+(?:\.\d+)?/);return m?parseFloat(m[0]):null;}
|
||||
function matchCondition(tr,cond){
|
||||
var f=fieldByKey(cond.field);if(!f)return true;
|
||||
var str=getFieldRaw(tr,f);
|
||||
if(cond.op==='包含')return str.indexOf(cond.value)>=0;
|
||||
if(cond.op==='=')return str===cond.value;
|
||||
if(cond.op==='!=')return str!==cond.value;
|
||||
var n=numericOf(str);
|
||||
if(n===null)return false;
|
||||
if(cond.op==='范围'){
|
||||
if(cond.from!==''){var lo=parseFloat(cond.from);if(!isNaN(lo)&&n<lo)return false;}
|
||||
if(cond.to!==''){var hi=parseFloat(cond.to);if(!isNaN(hi)&&n>hi)return false;}
|
||||
return true;
|
||||
}
|
||||
var c=parseFloat(cond.value);if(isNaN(c))return false;
|
||||
if(cond.op==='>')return n>c;
|
||||
if(cond.op==='>=')return n>=c;
|
||||
if(cond.op==='<')return n<c;
|
||||
if(cond.op==='<=')return n<=c;
|
||||
return true;
|
||||
}
|
||||
function applyFilter(){
|
||||
var conds=readAdvancedConditions();
|
||||
document.querySelectorAll(ADV_ROW_SELECTOR).forEach(function(tr){
|
||||
var show=true;
|
||||
for(var i=0;i<conds.length;i++){if(!matchCondition(tr,conds[i])){show=false;break;}}
|
||||
tr.style.display=show?'':'none';
|
||||
});
|
||||
showToast('查询完成');
|
||||
}
|
||||
function clearAdvanced(){
|
||||
document.getElementById('advConditions').innerHTML='';
|
||||
document.querySelectorAll(ADV_ROW_SELECTOR).forEach(function(tr){tr.style.display='';});
|
||||
showToast('已清空高级查询条件');
|
||||
}
|
||||
/* 轻提示 */
|
||||
var toastTimer=null;
|
||||
function showToast(msg){
|
||||
document.getElementById('toastText').textContent=msg;
|
||||
var t=document.getElementById('toast');
|
||||
t.classList.add('show');clearTimeout(toastTimer);
|
||||
toastTimer=setTimeout(function(){t.classList.remove('show');},2400);
|
||||
}
|
||||
</script>
|
||||
<!-- 轻提示 -->
|
||||
<div class="toast" id="toast">
|
||||
<svg width="15" height="15" viewBox="0 0 15 15" fill="none"><circle cx="7.5" cy="7.5" r="6.5" fill="#52C41A"/><path d="M4.6 7.7l2 2 3.8-4" stroke="#fff" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||
<span id="toastText"></span>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -128,9 +128,9 @@
|
||||
常规体检
|
||||
</div>
|
||||
<div class="sidebar-subgroup__body">
|
||||
<a href="mid-appointment-track.html" class="sidebar-item">体检预约</a>
|
||||
<a href="mid-selected-items.html" class="sidebar-item">已选项目</a>
|
||||
<a href="mid-participation.html" class="sidebar-item">已检员工</a>
|
||||
<!-- <a href="mid-appointment-track.html" class="sidebar-item">体检预约</a> -->
|
||||
<!-- <a href="mid-selected-items.html" class="sidebar-item">已选项目</a> -->
|
||||
<!-- <a href="mid-participation.html" class="sidebar-item">已检员工</a> -->
|
||||
<a href="mid-appointment-track2.html" class="sidebar-item">体检预约跟踪</a>
|
||||
<a href="mid-unit-appointment.html" class="sidebar-item">单位预约人数统计</a>
|
||||
<a href="mid-hospital-realtime.html" class="sidebar-item">医院实时预约人数</a>
|
||||
|
||||
@@ -150,9 +150,9 @@
|
||||
常规体检
|
||||
</div>
|
||||
<div class="sidebar-subgroup__body">
|
||||
<a href="mid-appointment-track.html" class="sidebar-item">体检预约</a>
|
||||
<a href="mid-selected-items.html" class="sidebar-item">已选项目</a>
|
||||
<a href="mid-participation.html" class="sidebar-item">已检员工</a>
|
||||
<!-- <a href="mid-appointment-track.html" class="sidebar-item">体检预约</a> -->
|
||||
<!-- <a href="mid-selected-items.html" class="sidebar-item">已选项目</a> -->
|
||||
<!-- <a href="mid-participation.html" class="sidebar-item">已检员工</a> -->
|
||||
<a href="mid-appointment-track2.html" class="sidebar-item">体检预约跟踪</a>
|
||||
<a href="mid-unit-appointment.html" class="sidebar-item">单位预约人数统计</a>
|
||||
<a href="mid-hospital-realtime.html" class="sidebar-item">医院实时预约人数</a>
|
||||
|
||||
@@ -129,9 +129,9 @@
|
||||
常规体检
|
||||
</div>
|
||||
<div class="sidebar-subgroup__body">
|
||||
<a href="mid-appointment-track.html" class="sidebar-item">体检预约</a>
|
||||
<a href="mid-selected-items.html" class="sidebar-item">已选项目</a>
|
||||
<a href="mid-participation.html" class="sidebar-item">已检员工</a>
|
||||
<!-- <a href="mid-appointment-track.html" class="sidebar-item">体检预约</a> -->
|
||||
<!-- <a href="mid-selected-items.html" class="sidebar-item">已选项目</a> -->
|
||||
<!-- <a href="mid-participation.html" class="sidebar-item">已检员工</a> -->
|
||||
<a href="mid-appointment-track2.html" class="sidebar-item">体检预约跟踪</a>
|
||||
<a href="mid-unit-appointment.html" class="sidebar-item">单位预约人数统计</a>
|
||||
<a href="mid-hospital-realtime.html" class="sidebar-item">医院实时预约人数</a>
|
||||
|
||||
@@ -87,6 +87,25 @@
|
||||
/* 三级单位tab下才显示的部门列 */
|
||||
.col-dept{display:none;}
|
||||
body.level-3 .col-dept{display:table-cell;}
|
||||
/* 高级查询 */
|
||||
.adv-panel{background:#fff;border-radius:var(--radius-md);padding:16px 24px;margin-bottom:16px;box-shadow:var(--shadow-sm);display:none;}
|
||||
.adv-panel.open{display:block;}
|
||||
.adv-panel__head{font-size:var(--font-base);font-weight:600;margin-bottom:12px;}
|
||||
#advConditions{display:grid;grid-template-columns:1fr 1fr;gap:10px 16px;}
|
||||
.adv-cond-row{display:flex;align-items:center;gap:8px;margin-bottom:0;min-width:0;}
|
||||
.adv-field{min-width:140px;flex:1;}
|
||||
.adv-op{min-width:72px;flex:none;}
|
||||
.adv-value-wrap{display:flex;align-items:center;gap:8px;flex:1;min-width:0;max-width:none;}
|
||||
.adv-value{flex:1;min-width:0;}
|
||||
.adv-range-sep{color:var(--text-secondary);flex-shrink:0;}
|
||||
.adv-del{width:32px;height:32px;border:1px solid var(--border);border-radius:var(--radius-sm);background:#fff;color:var(--text-secondary);cursor:pointer;flex-shrink:0;font-size:var(--font-sm);line-height:1;}
|
||||
.adv-del:hover{color:var(--danger);border-color:var(--danger);}
|
||||
.adv-actions{display:flex;gap:12px;margin-top:2px;}
|
||||
.adv-arrow{font-size:10px;}
|
||||
/* 轻提示 */
|
||||
.toast{position:fixed;top:76px;left:50%;transform:translateX(-50%) translateY(-16px);background:#fff;box-shadow:var(--shadow-md);border-radius:var(--radius-sm);padding:10px 20px;font-size:var(--font-sm);color:var(--text-primary);opacity:0;pointer-events:none;transition:all .25s;z-index:1000;display:flex;align-items:center;gap:8px;}
|
||||
.toast.show{opacity:1;transform:translateX(-50%) translateY(0);}
|
||||
.toast svg{flex-shrink:0;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -124,9 +143,9 @@
|
||||
常规体检
|
||||
</div>
|
||||
<div class="sidebar-subgroup__body">
|
||||
<a href="mid-appointment-track.html" class="sidebar-item">体检预约</a>
|
||||
<a href="mid-selected-items.html" class="sidebar-item">已选项目</a>
|
||||
<a href="mid-participation.html" class="sidebar-item">已检员工</a>
|
||||
<!-- <a href="mid-appointment-track.html" class="sidebar-item">体检预约</a> -->
|
||||
<!-- <a href="mid-selected-items.html" class="sidebar-item">已选项目</a> -->
|
||||
<!-- <a href="mid-participation.html" class="sidebar-item">已检员工</a> -->
|
||||
<a href="mid-appointment-track2.html" class="sidebar-item">体检预约跟踪</a>
|
||||
<a href="mid-unit-appointment.html" class="sidebar-item">单位预约人数统计</a>
|
||||
<a href="mid-hospital-realtime.html" class="sidebar-item">医院实时预约人数</a>
|
||||
@@ -179,6 +198,18 @@
|
||||
查询
|
||||
</button>
|
||||
<button class="btn btn-default">重置</button>
|
||||
<button class="btn btn-default" id="advToggle" onclick="toggleAdvanced()">高级查询 <span class="adv-arrow">▾</span></button>
|
||||
</div>
|
||||
|
||||
<!-- 高级查询 -->
|
||||
<div class="adv-panel" id="advPanel">
|
||||
<div class="adv-panel__head">高级查询</div>
|
||||
<div id="advConditions"></div>
|
||||
<div class="adv-actions">
|
||||
<button class="btn btn-default" onclick="addAdvCondition()">+ 添加条件</button>
|
||||
<button class="btn btn-primary" onclick="applyFilter()">查询</button>
|
||||
<button class="btn btn-default" onclick="clearAdvanced()">清空</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 操作栏 -->
|
||||
@@ -246,6 +277,110 @@ function toggleSubgroup(header){
|
||||
var sub=active.closest('.sidebar-subgroup');
|
||||
if(sub)sub.classList.add('open');
|
||||
})();
|
||||
/* ============ 高级查询 ============ */
|
||||
var ADV_OPS=['包含','=','!=','>','>=','<','<=','范围'];
|
||||
var ADV_ROW_SELECTOR='.table-card__content tbody tr';
|
||||
var ADV_FIELDS=[
|
||||
{key:'unit',label:'单位',idx:1},{key:'dept',label:'部门',idx:2},{key:'should',label:'应体检人数',idx:3},
|
||||
{key:'questionnaire',label:'填写问卷人数',idx:4},{key:'booked',label:'已预约人数',idx:5},{key:'participated',label:'已参检人数',idx:6},
|
||||
{key:'unparticipated',label:'未参检人数',idx:7},{key:'unbooked',label:'未预约人数',idx:8},{key:'year',label:'体检年份',idx:9}
|
||||
];
|
||||
var ADV_FIELD_OPTS=ADV_FIELDS.map(function(f){return '<option value="'+f.key+'">'+f.label+'</option>';}).join('');
|
||||
function advConditionRowHTML(){
|
||||
return '<div class="adv-cond-row">'
|
||||
+'<select class="filter-select adv-field">'+ADV_FIELD_OPTS+'</select>'
|
||||
+'<select class="filter-select adv-op" onchange="onAdvOpChange(this)">'+ADV_OPS.map(function(o){return '<option value="'+o+'">'+o+'</option>';}).join('')+'</select>'
|
||||
+'<span class="adv-value-wrap"><input class="filter-input adv-value" type="text" placeholder="请输入值"></span>'
|
||||
+'<button class="adv-del" type="button" title="删除该条件" onclick="removeAdvCondition(this)">✕</button>'
|
||||
+'</div>';
|
||||
}
|
||||
function onAdvOpChange(sel){
|
||||
var wrap=sel.parentElement.querySelector('.adv-value-wrap');
|
||||
var isRange=sel.value==='范围';
|
||||
var alreadyRange=!!wrap.querySelector('.adv-range-from');
|
||||
if(isRange&&!alreadyRange){
|
||||
wrap.innerHTML='<input class="filter-input adv-value adv-range-from" type="text" placeholder="最小值">'
|
||||
+'<span class="adv-range-sep">~</span>'
|
||||
+'<input class="filter-input adv-value adv-range-to" type="text" placeholder="最大值">';
|
||||
}else if(!isRange&&alreadyRange){
|
||||
wrap.innerHTML='<input class="filter-input adv-value" type="text" placeholder="请输入值">';
|
||||
}
|
||||
}
|
||||
function addAdvCondition(){document.getElementById('advConditions').insertAdjacentHTML('beforeend',advConditionRowHTML());}
|
||||
function removeAdvCondition(el){el.parentElement.remove();}
|
||||
function toggleAdvanced(){
|
||||
var p=document.getElementById('advPanel');
|
||||
var open=p.classList.toggle('open');
|
||||
var arr=document.getElementById('advToggle').querySelector('.adv-arrow');
|
||||
if(arr)arr.textContent=open?'▴':'▾';
|
||||
if(open&&!p.querySelector('.adv-cond-row'))addAdvCondition();
|
||||
}
|
||||
function readAdvancedConditions(){
|
||||
var conds=[];
|
||||
document.querySelectorAll('#advConditions .adv-cond-row').forEach(function(row){
|
||||
var field=row.querySelector('.adv-field').value;
|
||||
var op=row.querySelector('.adv-op').value;
|
||||
if(op==='范围'){
|
||||
var from=row.querySelector('.adv-range-from').value.trim();
|
||||
var to=row.querySelector('.adv-range-to').value.trim();
|
||||
if(from!==''||to!=='')conds.push({field:field,op:op,from:from,to:to});
|
||||
}else{
|
||||
var value=row.querySelector('.adv-value').value.trim();
|
||||
if(value!=='')conds.push({field:field,op:op,value:value});
|
||||
}
|
||||
});
|
||||
return conds;
|
||||
}
|
||||
function fieldByKey(key){for(var i=0;i<ADV_FIELDS.length;i++){if(ADV_FIELDS[i].key===key)return ADV_FIELDS[i];}return null;}
|
||||
function getFieldRaw(tr,f){var td=tr.cells[f.idx];return td?td.textContent.trim():'';}
|
||||
function numericOf(v){var s=String(v).replace(/,/g,'').replace(/[¥¥]/g,'');var m=s.match(/[-+]?\d+(?:\.\d+)?/);return m?parseFloat(m[0]):null;}
|
||||
function matchCondition(tr,cond){
|
||||
var f=fieldByKey(cond.field);if(!f)return true;
|
||||
var str=getFieldRaw(tr,f);
|
||||
if(cond.op==='包含')return str.indexOf(cond.value)>=0;
|
||||
if(cond.op==='=')return str===cond.value;
|
||||
if(cond.op==='!=')return str!==cond.value;
|
||||
var n=numericOf(str);
|
||||
if(n===null)return false;
|
||||
if(cond.op==='范围'){
|
||||
if(cond.from!==''){var lo=parseFloat(cond.from);if(!isNaN(lo)&&n<lo)return false;}
|
||||
if(cond.to!==''){var hi=parseFloat(cond.to);if(!isNaN(hi)&&n>hi)return false;}
|
||||
return true;
|
||||
}
|
||||
var c=parseFloat(cond.value);if(isNaN(c))return false;
|
||||
if(cond.op==='>')return n>c;
|
||||
if(cond.op==='>=')return n>=c;
|
||||
if(cond.op==='<')return n<c;
|
||||
if(cond.op==='<=')return n<=c;
|
||||
return true;
|
||||
}
|
||||
function applyFilter(){
|
||||
var conds=readAdvancedConditions();
|
||||
document.querySelectorAll(ADV_ROW_SELECTOR).forEach(function(tr){
|
||||
var show=true;
|
||||
for(var i=0;i<conds.length;i++){if(!matchCondition(tr,conds[i])){show=false;break;}}
|
||||
tr.style.display=show?'':'none';
|
||||
});
|
||||
showToast('查询完成');
|
||||
}
|
||||
function clearAdvanced(){
|
||||
document.getElementById('advConditions').innerHTML='';
|
||||
document.querySelectorAll(ADV_ROW_SELECTOR).forEach(function(tr){tr.style.display='';});
|
||||
showToast('已清空高级查询条件');
|
||||
}
|
||||
/* 轻提示 */
|
||||
var toastTimer=null;
|
||||
function showToast(msg){
|
||||
document.getElementById('toastText').textContent=msg;
|
||||
var t=document.getElementById('toast');
|
||||
t.classList.add('show');clearTimeout(toastTimer);
|
||||
toastTimer=setTimeout(function(){t.classList.remove('show');},2400);
|
||||
}
|
||||
</script>
|
||||
<!-- 轻提示 -->
|
||||
<div class="toast" id="toast">
|
||||
<svg width="15" height="15" viewBox="0 0 15 15" fill="none"><circle cx="7.5" cy="7.5" r="6.5" fill="#52C41A"/><path d="M4.6 7.7l2 2 3.8-4" stroke="#fff" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||
<span id="toastText"></span>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -124,9 +124,9 @@
|
||||
常规体检
|
||||
</div>
|
||||
<div class="sidebar-subgroup__body">
|
||||
<a href="mid-appointment-track.html" class="sidebar-item">体检预约</a>
|
||||
<a href="mid-selected-items.html" class="sidebar-item">已选项目</a>
|
||||
<a href="mid-participation.html" class="sidebar-item">已检员工</a>
|
||||
<!-- <a href="mid-appointment-track.html" class="sidebar-item">体检预约</a> -->
|
||||
<!-- <a href="mid-selected-items.html" class="sidebar-item">已选项目</a> -->
|
||||
<!-- <a href="mid-participation.html" class="sidebar-item">已检员工</a> -->
|
||||
<a href="mid-appointment-track2.html" class="sidebar-item">体检预约跟踪</a>
|
||||
<a href="mid-unit-appointment.html" class="sidebar-item">单位预约人数统计</a>
|
||||
<a href="mid-hospital-realtime.html" class="sidebar-item">医院实时预约人数</a>
|
||||
|
||||
@@ -128,9 +128,9 @@
|
||||
常规体检
|
||||
</div>
|
||||
<div class="sidebar-subgroup__body">
|
||||
<a href="mid-appointment-track.html" class="sidebar-item">体检预约</a>
|
||||
<a href="mid-selected-items.html" class="sidebar-item">已选项目</a>
|
||||
<a href="mid-participation.html" class="sidebar-item">已检员工</a>
|
||||
<!-- <a href="mid-appointment-track.html" class="sidebar-item">体检预约</a> -->
|
||||
<!-- <a href="mid-selected-items.html" class="sidebar-item">已选项目</a> -->
|
||||
<!-- <a href="mid-participation.html" class="sidebar-item">已检员工</a> -->
|
||||
<a href="mid-appointment-track2.html" class="sidebar-item">体检预约跟踪</a>
|
||||
<a href="mid-unit-appointment.html" class="sidebar-item">单位预约人数统计</a>
|
||||
<a href="mid-hospital-realtime.html" class="sidebar-item active">医院实时预约人数</a>
|
||||
|
||||
@@ -147,9 +147,9 @@
|
||||
常规体检
|
||||
</div>
|
||||
<div class="sidebar-subgroup__body">
|
||||
<a href="mid-appointment-track.html" class="sidebar-item">体检预约</a>
|
||||
<a href="mid-selected-items.html" class="sidebar-item">已选项目</a>
|
||||
<a href="mid-participation.html" class="sidebar-item active">已检员工</a>
|
||||
<!-- <a href="mid-appointment-track.html" class="sidebar-item">体检预约</a> -->
|
||||
<!-- <a href="mid-selected-items.html" class="sidebar-item">已选项目</a> -->
|
||||
<!-- <a href="mid-participation.html" class="sidebar-item active">已检员工</a> -->
|
||||
<a href="mid-appointment-track2.html" class="sidebar-item">体检预约跟踪</a>
|
||||
<a href="mid-unit-appointment.html" class="sidebar-item">单位预约人数统计</a>
|
||||
<a href="mid-hospital-realtime.html" class="sidebar-item">医院实时预约人数</a>
|
||||
|
||||
@@ -147,9 +147,9 @@
|
||||
常规体检
|
||||
</div>
|
||||
<div class="sidebar-subgroup__body">
|
||||
<a href="mid-appointment-track.html" class="sidebar-item">体检预约</a>
|
||||
<a href="mid-selected-items.html" class="sidebar-item active">已选项目</a>
|
||||
<a href="mid-participation.html" class="sidebar-item">已检员工</a>
|
||||
<!-- <a href="mid-appointment-track.html" class="sidebar-item">体检预约</a> -->
|
||||
<!-- <a href="mid-selected-items.html" class="sidebar-item active">已选项目</a> -->
|
||||
<!-- <a href="mid-participation.html" class="sidebar-item">已检员工</a> -->
|
||||
<a href="mid-appointment-track2.html" class="sidebar-item">体检预约跟踪</a>
|
||||
<a href="mid-unit-appointment.html" class="sidebar-item">单位预约人数统计</a>
|
||||
<a href="mid-hospital-realtime.html" class="sidebar-item">医院实时预约人数</a>
|
||||
|
||||
@@ -96,6 +96,25 @@
|
||||
.year-picker__dropdown div{padding:8px 14px;font-size:var(--font-sm);cursor:pointer;}
|
||||
.year-picker__dropdown div:hover{background:var(--primary-light);}
|
||||
.year-picker__dropdown div.selected{color:var(--primary);font-weight:600;}
|
||||
/* 高级查询 */
|
||||
.adv-panel{background:#fff;border-radius:var(--radius-md);padding:16px 24px;margin-bottom:16px;box-shadow:var(--shadow-sm);display:none;}
|
||||
.adv-panel.open{display:block;}
|
||||
.adv-panel__head{font-size:var(--font-base);font-weight:600;margin-bottom:12px;}
|
||||
#advConditions{display:grid;grid-template-columns:1fr 1fr;gap:10px 16px;}
|
||||
.adv-cond-row{display:flex;align-items:center;gap:8px;margin-bottom:0;min-width:0;}
|
||||
.adv-field{min-width:140px;flex:1;}
|
||||
.adv-op{min-width:72px;flex:none;}
|
||||
.adv-value-wrap{display:flex;align-items:center;gap:8px;flex:1;min-width:0;max-width:none;}
|
||||
.adv-value{flex:1;min-width:0;}
|
||||
.adv-range-sep{color:var(--text-secondary);flex-shrink:0;}
|
||||
.adv-del{width:32px;height:32px;border:1px solid var(--border);border-radius:var(--radius-sm);background:#fff;color:var(--text-secondary);cursor:pointer;flex-shrink:0;font-size:var(--font-sm);line-height:1;}
|
||||
.adv-del:hover{color:var(--danger);border-color:var(--danger);}
|
||||
.adv-actions{display:flex;gap:12px;margin-top:2px;}
|
||||
.adv-arrow{font-size:10px;}
|
||||
/* 轻提示 */
|
||||
.toast{position:fixed;top:76px;left:50%;transform:translateX(-50%) translateY(-16px);background:#fff;box-shadow:var(--shadow-md);border-radius:var(--radius-sm);padding:10px 20px;font-size:var(--font-sm);color:var(--text-primary);opacity:0;pointer-events:none;transition:all .25s;z-index:1000;display:flex;align-items:center;gap:8px;}
|
||||
.toast.show{opacity:1;transform:translateX(-50%) translateY(0);}
|
||||
.toast svg{flex-shrink:0;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -133,9 +152,9 @@
|
||||
常规体检
|
||||
</div>
|
||||
<div class="sidebar-subgroup__body">
|
||||
<a href="mid-appointment-track.html" class="sidebar-item">体检预约</a>
|
||||
<a href="mid-selected-items.html" class="sidebar-item">已选项目</a>
|
||||
<a href="mid-participation.html" class="sidebar-item">已检员工</a>
|
||||
<!-- <a href="mid-appointment-track.html" class="sidebar-item">体检预约</a> -->
|
||||
<!-- <a href="mid-selected-items.html" class="sidebar-item">已选项目</a> -->
|
||||
<!-- <a href="mid-participation.html" class="sidebar-item">已检员工</a> -->
|
||||
<a href="mid-appointment-track2.html" class="sidebar-item">体检预约跟踪</a>
|
||||
<a href="mid-unit-appointment.html" class="sidebar-item active">单位预约人数统计</a>
|
||||
<a href="mid-hospital-realtime.html" class="sidebar-item">医院实时预约人数</a>
|
||||
@@ -200,6 +219,18 @@
|
||||
查询
|
||||
</button>
|
||||
<button class="btn btn-default">重置</button>
|
||||
<button class="btn btn-default" id="advToggle" onclick="toggleAdvanced()">高级查询 <span class="adv-arrow">▾</span></button>
|
||||
</div>
|
||||
|
||||
<!-- 高级查询 -->
|
||||
<div class="adv-panel" id="advPanel">
|
||||
<div class="adv-panel__head">高级查询</div>
|
||||
<div id="advConditions"></div>
|
||||
<div class="adv-actions">
|
||||
<button class="btn btn-default" onclick="addAdvCondition()">+ 添加条件</button>
|
||||
<button class="btn btn-primary" onclick="applyFilter()">查询</button>
|
||||
<button class="btn btn-default" onclick="clearAdvanced()">清空</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 操作栏 -->
|
||||
@@ -286,6 +317,110 @@ document.querySelectorAll('.year-picker>input').forEach(function(inp){
|
||||
document.addEventListener('click',function(){
|
||||
document.querySelectorAll('.year-picker__dropdown.open').forEach(function(d){d.classList.remove('open');});
|
||||
});
|
||||
/* ============ 高级查询 ============ */
|
||||
var ADV_OPS=['包含','=','!=','>','>=','<','<=','范围'];
|
||||
var ADV_ROW_SELECTOR='.table-card__content tbody tr';
|
||||
var ADV_FIELDS=[
|
||||
{key:'unit',label:'单位',idx:1},{key:'dept',label:'部门',idx:2},{key:'should',label:'应体检人数',idx:3},
|
||||
{key:'selected',label:'已选项目人数',idx:4},{key:'booked',label:'已预约人数',idx:5},{key:'participated',label:'已参检人数',idx:6},
|
||||
{key:'unparticipated',label:'未参检人数',idx:7},{key:'unbooked',label:'未预约人数',idx:8},{key:'year',label:'体检年份',idx:9}
|
||||
];
|
||||
var ADV_FIELD_OPTS=ADV_FIELDS.map(function(f){return '<option value="'+f.key+'">'+f.label+'</option>';}).join('');
|
||||
function advConditionRowHTML(){
|
||||
return '<div class="adv-cond-row">'
|
||||
+'<select class="filter-select adv-field">'+ADV_FIELD_OPTS+'</select>'
|
||||
+'<select class="filter-select adv-op" onchange="onAdvOpChange(this)">'+ADV_OPS.map(function(o){return '<option value="'+o+'">'+o+'</option>';}).join('')+'</select>'
|
||||
+'<span class="adv-value-wrap"><input class="filter-input adv-value" type="text" placeholder="请输入值"></span>'
|
||||
+'<button class="adv-del" type="button" title="删除该条件" onclick="removeAdvCondition(this)">✕</button>'
|
||||
+'</div>';
|
||||
}
|
||||
function onAdvOpChange(sel){
|
||||
var wrap=sel.parentElement.querySelector('.adv-value-wrap');
|
||||
var isRange=sel.value==='范围';
|
||||
var alreadyRange=!!wrap.querySelector('.adv-range-from');
|
||||
if(isRange&&!alreadyRange){
|
||||
wrap.innerHTML='<input class="filter-input adv-value adv-range-from" type="text" placeholder="最小值">'
|
||||
+'<span class="adv-range-sep">~</span>'
|
||||
+'<input class="filter-input adv-value adv-range-to" type="text" placeholder="最大值">';
|
||||
}else if(!isRange&&alreadyRange){
|
||||
wrap.innerHTML='<input class="filter-input adv-value" type="text" placeholder="请输入值">';
|
||||
}
|
||||
}
|
||||
function addAdvCondition(){document.getElementById('advConditions').insertAdjacentHTML('beforeend',advConditionRowHTML());}
|
||||
function removeAdvCondition(el){el.parentElement.remove();}
|
||||
function toggleAdvanced(){
|
||||
var p=document.getElementById('advPanel');
|
||||
var open=p.classList.toggle('open');
|
||||
var arr=document.getElementById('advToggle').querySelector('.adv-arrow');
|
||||
if(arr)arr.textContent=open?'▴':'▾';
|
||||
if(open&&!p.querySelector('.adv-cond-row'))addAdvCondition();
|
||||
}
|
||||
function readAdvancedConditions(){
|
||||
var conds=[];
|
||||
document.querySelectorAll('#advConditions .adv-cond-row').forEach(function(row){
|
||||
var field=row.querySelector('.adv-field').value;
|
||||
var op=row.querySelector('.adv-op').value;
|
||||
if(op==='范围'){
|
||||
var from=row.querySelector('.adv-range-from').value.trim();
|
||||
var to=row.querySelector('.adv-range-to').value.trim();
|
||||
if(from!==''||to!=='')conds.push({field:field,op:op,from:from,to:to});
|
||||
}else{
|
||||
var value=row.querySelector('.adv-value').value.trim();
|
||||
if(value!=='')conds.push({field:field,op:op,value:value});
|
||||
}
|
||||
});
|
||||
return conds;
|
||||
}
|
||||
function fieldByKey(key){for(var i=0;i<ADV_FIELDS.length;i++){if(ADV_FIELDS[i].key===key)return ADV_FIELDS[i];}return null;}
|
||||
function getFieldRaw(tr,f){var td=tr.cells[f.idx];return td?td.textContent.trim():'';}
|
||||
function numericOf(v){var s=String(v).replace(/,/g,'').replace(/[¥¥]/g,'');var m=s.match(/[-+]?\d+(?:\.\d+)?/);return m?parseFloat(m[0]):null;}
|
||||
function matchCondition(tr,cond){
|
||||
var f=fieldByKey(cond.field);if(!f)return true;
|
||||
var str=getFieldRaw(tr,f);
|
||||
if(cond.op==='包含')return str.indexOf(cond.value)>=0;
|
||||
if(cond.op==='=')return str===cond.value;
|
||||
if(cond.op==='!=')return str!==cond.value;
|
||||
var n=numericOf(str);
|
||||
if(n===null)return false;
|
||||
if(cond.op==='范围'){
|
||||
if(cond.from!==''){var lo=parseFloat(cond.from);if(!isNaN(lo)&&n<lo)return false;}
|
||||
if(cond.to!==''){var hi=parseFloat(cond.to);if(!isNaN(hi)&&n>hi)return false;}
|
||||
return true;
|
||||
}
|
||||
var c=parseFloat(cond.value);if(isNaN(c))return false;
|
||||
if(cond.op==='>')return n>c;
|
||||
if(cond.op==='>=')return n>=c;
|
||||
if(cond.op==='<')return n<c;
|
||||
if(cond.op==='<=')return n<=c;
|
||||
return true;
|
||||
}
|
||||
function applyFilter(){
|
||||
var conds=readAdvancedConditions();
|
||||
document.querySelectorAll(ADV_ROW_SELECTOR).forEach(function(tr){
|
||||
var show=true;
|
||||
for(var i=0;i<conds.length;i++){if(!matchCondition(tr,conds[i])){show=false;break;}}
|
||||
tr.style.display=show?'':'none';
|
||||
});
|
||||
showToast('查询完成');
|
||||
}
|
||||
function clearAdvanced(){
|
||||
document.getElementById('advConditions').innerHTML='';
|
||||
document.querySelectorAll(ADV_ROW_SELECTOR).forEach(function(tr){tr.style.display='';});
|
||||
showToast('已清空高级查询条件');
|
||||
}
|
||||
/* 轻提示 */
|
||||
var toastTimer=null;
|
||||
function showToast(msg){
|
||||
document.getElementById('toastText').textContent=msg;
|
||||
var t=document.getElementById('toast');
|
||||
t.classList.add('show');clearTimeout(toastTimer);
|
||||
toastTimer=setTimeout(function(){t.classList.remove('show');},2400);
|
||||
}
|
||||
</script>
|
||||
<!-- 轻提示 -->
|
||||
<div class="toast" id="toast">
|
||||
<svg width="15" height="15" viewBox="0 0 15 15" fill="none"><circle cx="7.5" cy="7.5" r="6.5" fill="#52C41A"/><path d="M4.6 7.7l2 2 3.8-4" stroke="#fff" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||
<span id="toastText"></span>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -113,9 +113,9 @@
|
||||
常规体检
|
||||
</div>
|
||||
<div class="sidebar-subgroup__body">
|
||||
<a href="mid-appointment-track.html" class="sidebar-item">体检预约</a>
|
||||
<a href="mid-selected-items.html" class="sidebar-item">已选项目</a>
|
||||
<a href="mid-participation.html" class="sidebar-item">已检员工</a>
|
||||
<!-- <a href="mid-appointment-track.html" class="sidebar-item">体检预约</a> -->
|
||||
<!-- <a href="mid-selected-items.html" class="sidebar-item">已选项目</a> -->
|
||||
<!-- <a href="mid-participation.html" class="sidebar-item">已检员工</a> -->
|
||||
<a href="mid-appointment-track2.html" class="sidebar-item">体检预约跟踪</a>
|
||||
<a href="mid-unit-appointment.html" class="sidebar-item">单位预约人数统计</a>
|
||||
<a href="mid-hospital-realtime.html" class="sidebar-item">医院实时预约人数</a>
|
||||
|
||||
@@ -109,10 +109,11 @@
|
||||
.adv-panel{background:#fff;border-radius:var(--radius-md);padding:16px 24px;margin-bottom:16px;box-shadow:var(--shadow-sm);display:none;}
|
||||
.adv-panel.open{display:block;}
|
||||
.adv-panel__head{font-size:var(--font-base);font-weight:600;margin-bottom:12px;}
|
||||
.adv-cond-row{display:flex;align-items:center;gap:8px;margin-bottom:10px;}
|
||||
.adv-field{min-width:210px;}
|
||||
.adv-op{min-width:90px;}
|
||||
.adv-value-wrap{display:flex;align-items:center;gap:8px;flex:1;max-width:440px;}
|
||||
#advConditions{display:grid;grid-template-columns:1fr 1fr;gap:10px 16px;}
|
||||
.adv-cond-row{display:flex;align-items:center;gap:8px;margin-bottom:0;min-width:0;}
|
||||
.adv-field{min-width:140px;flex:1;}
|
||||
.adv-op{min-width:72px;flex:none;}
|
||||
.adv-value-wrap{display:flex;align-items:center;gap:8px;flex:1;min-width:0;max-width:none;}
|
||||
.adv-value{flex:1;min-width:0;}
|
||||
.adv-range-sep{color:var(--text-secondary);flex-shrink:0;}
|
||||
.adv-del{width:32px;height:32px;border:1px solid var(--border);border-radius:var(--radius-sm);background:#fff;color:var(--text-secondary);cursor:pointer;flex-shrink:0;font-size:var(--font-sm);line-height:1;}
|
||||
@@ -263,14 +264,6 @@
|
||||
<label>身份证号:</label>
|
||||
<input class="filter-input" type="text" id="fIdCard" placeholder="请输入" style="width:160px;min-width:unset;">
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label>异常员工:</label>
|
||||
<select class="filter-select" style="min-width:100px;" id="abnormalFilter">
|
||||
<option value="">全部</option>
|
||||
<option value="abnormal">是</option>
|
||||
<option value="normal">否</option>
|
||||
</select>
|
||||
</div>
|
||||
<button class="btn btn-primary" onclick="applyFilter()">查询</button>
|
||||
<button class="btn btn-default" onclick="resetFilter()">重置</button>
|
||||
<button class="btn btn-default" id="advToggle" onclick="toggleAdvanced()">高级查询 <span class="adv-arrow">▾</span></button>
|
||||
@@ -558,16 +551,13 @@ function hasAbnormal(r){
|
||||
for(var k in r.r){if(r.r[k][1])return true;}
|
||||
return false;
|
||||
}
|
||||
/* 按筛选条件取当前展示行:异常员工 + 姓名/员工编号/身份证号模糊匹配 + 高级查询条件 */
|
||||
/* 按筛选条件取当前展示行:姓名模糊匹配 + 高级查询条件 */
|
||||
function getDisplayRows(){
|
||||
var v=document.getElementById('abnormalFilter').value;
|
||||
var name=document.getElementById('fName').value.trim();
|
||||
var empNo=document.getElementById('fEmpNo').value.trim();
|
||||
var idCard=document.getElementById('fIdCard').value.trim();
|
||||
var conds=readAdvancedConditions();
|
||||
return MASTER_ROWS.filter(function(r){
|
||||
if(v==='abnormal'&&!hasAbnormal(r))return false;
|
||||
if(v==='normal'&&hasAbnormal(r))return false;
|
||||
if(name&&r.name.indexOf(name)<0)return false;
|
||||
if(empNo&&r.empNo.indexOf(empNo)<0)return false;
|
||||
if(idCard&&r.idCard.indexOf(idCard)<0)return false;
|
||||
@@ -707,7 +697,6 @@ function applyFilter(){
|
||||
showToast('查询完成');
|
||||
}
|
||||
function resetFilter(){
|
||||
document.getElementById('abnormalFilter').value='';
|
||||
document.getElementById('fName').value='';
|
||||
document.getElementById('fEmpNo').value='';
|
||||
document.getElementById('fIdCard').value='';
|
||||
|
||||
@@ -170,6 +170,21 @@
|
||||
.report-note--conclusion{border:1px solid #FFD591;background:#FFF7E6;color:#873800;}
|
||||
.report-note--advice{border:1px solid #B7EB8F;background:#F6FFED;color:#389E0D;}
|
||||
.result-abnormal{color:var(--danger);font-weight:600;}
|
||||
/* 高级查询 */
|
||||
.adv-panel{background:#fff;border-radius:var(--radius-md);padding:16px 24px;margin-bottom:16px;box-shadow:var(--shadow-sm);display:none;}
|
||||
.adv-panel.open{display:block;}
|
||||
.adv-panel__head{font-size:var(--font-base);font-weight:600;margin-bottom:12px;}
|
||||
#advConditions{display:grid;grid-template-columns:1fr 1fr;gap:10px 16px;}
|
||||
.adv-cond-row{display:flex;align-items:center;gap:8px;margin-bottom:0;min-width:0;}
|
||||
.adv-field{min-width:140px;flex:1;}
|
||||
.adv-op{min-width:72px;flex:none;}
|
||||
.adv-value-wrap{display:flex;align-items:center;gap:8px;flex:1;min-width:0;max-width:none;}
|
||||
.adv-value{flex:1;min-width:0;}
|
||||
.adv-range-sep{color:var(--text-secondary);flex-shrink:0;}
|
||||
.adv-del{width:32px;height:32px;border:1px solid var(--border);border-radius:var(--radius-sm);background:#fff;color:var(--text-secondary);cursor:pointer;flex-shrink:0;font-size:var(--font-sm);line-height:1;}
|
||||
.adv-del:hover{color:var(--danger);border-color:var(--danger);}
|
||||
.adv-actions{display:flex;gap:12px;margin-top:2px;}
|
||||
.adv-arrow{font-size:10px;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -373,30 +388,18 @@
|
||||
<label>员工编号:</label>
|
||||
<input class="filter-input" type="text" id="fEmpNo" placeholder="请输入" oninput="applyListFilter()" style="min-width:130px;">
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label>性别:</label>
|
||||
<select class="filter-select filter-select--item" id="fGender" onchange="applyListFilter()">
|
||||
<option value="">全部</option><option>男</option><option>女</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label>年龄:</label>
|
||||
<select class="filter-select filter-select--item" id="fAge" onchange="applyListFilter()">
|
||||
<option value="">全部</option><option>20-29岁</option><option>30-39岁</option><option>40-49岁</option><option>50-59岁</option><option>60岁及以上</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label>岗位:</label>
|
||||
<select class="filter-select filter-select--item" id="fPos" onchange="applyListFilter()">
|
||||
<option value="">全部</option><option>采油工</option><option>集输工</option><option>技术员</option><option>管理岗</option><option>后勤岗</option><option>机关岗</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label>是否异常:</label>
|
||||
<select class="filter-select filter-select--item" id="fAbn" onchange="applyListFilter()">
|
||||
<option value="">全部</option><option value="yes">是</option><option value="no">否</option>
|
||||
</select>
|
||||
</div>
|
||||
<button class="btn btn-default" id="advToggle" onclick="toggleAdvanced()">高级查询 <span class="adv-arrow">▾</span></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 高级查询 -->
|
||||
<div class="adv-panel" id="advPanel">
|
||||
<div class="adv-panel__head">高级查询</div>
|
||||
<div id="advConditions"></div>
|
||||
<div class="adv-actions">
|
||||
<button class="btn btn-default" onclick="addAdvCondition()">+ 添加条件</button>
|
||||
<button class="btn btn-primary" onclick="applyListFilter()">查询</button>
|
||||
<button class="btn btn-default" onclick="clearAdvanced()">清空</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -783,23 +786,100 @@ function getListRows(){
|
||||
var unit=document.getElementById('fUnit').value;
|
||||
var name=document.getElementById('fName').value.trim();
|
||||
var empNo=document.getElementById('fEmpNo').value.trim();
|
||||
var gender=document.getElementById('fGender').value;
|
||||
var age=document.getElementById('fAge').value;
|
||||
var pos=document.getElementById('fPos').value;
|
||||
var abn=document.getElementById('fAbn').value;
|
||||
var conds=readAdvancedConditions();
|
||||
return LIST_ROWS.filter(function(r){
|
||||
if(unit&&r.unit!==unit)return false;
|
||||
if(name&&r.name.indexOf(name)<0)return false;
|
||||
if(empNo&&r.empNo.indexOf(empNo)<0)return false;
|
||||
if(gender&&r.gender!==gender)return false;
|
||||
if(age&&r.ageRange!==age)return false;
|
||||
if(pos&&r.position!==pos)return false;
|
||||
if(selectedCodes.length&&selectedCodes.indexOf(r.itemCode)<0)return false;
|
||||
if(abn==='yes'&&!r.abnormal)return false;
|
||||
if(abn==='no'&&r.abnormal)return false;
|
||||
for(var i=0;i<conds.length;i++){if(!matchCondition(r,conds[i]))return false;}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
/* ============ 高级查询 ============ */
|
||||
var ADV_OPS=['包含','=','!=','>','>=','<','<=','范围'];
|
||||
var ADV_FIELDS=[
|
||||
{key:'name',label:'姓名'},{key:'empNo',label:'员工编号'},{key:'gender',label:'性别'},
|
||||
{key:'age',label:'年龄'},{key:'ageRange',label:'年龄范围'},{key:'unit',label:'单位'},
|
||||
{key:'dept',label:'部门'},{key:'position',label:'岗位'},{key:'itemCode',label:'项目编码'},
|
||||
{key:'itemName',label:'体检项目'},{key:'abnormal',label:'是否异常'}
|
||||
];
|
||||
var ADV_FIELD_OPTS=ADV_FIELDS.map(function(f){return '<option value="'+f.key+'">'+f.label+'</option>';}).join('');
|
||||
function advConditionRowHTML(){
|
||||
return '<div class="adv-cond-row">'
|
||||
+'<select class="filter-select adv-field">'+ADV_FIELD_OPTS+'</select>'
|
||||
+'<select class="filter-select adv-op" onchange="onAdvOpChange(this)">'+ADV_OPS.map(function(o){return '<option value="'+o+'">'+o+'</option>';}).join('')+'</select>'
|
||||
+'<span class="adv-value-wrap"><input class="filter-input adv-value" type="text" placeholder="请输入值"></span>'
|
||||
+'<button class="adv-del" type="button" title="删除该条件" onclick="removeAdvCondition(this)">✕</button>'
|
||||
+'</div>';
|
||||
}
|
||||
function onAdvOpChange(sel){
|
||||
var wrap=sel.parentElement.querySelector('.adv-value-wrap');
|
||||
var isRange=sel.value==='范围';
|
||||
var alreadyRange=!!wrap.querySelector('.adv-range-from');
|
||||
if(isRange&&!alreadyRange){
|
||||
wrap.innerHTML='<input class="filter-input adv-value adv-range-from" type="text" placeholder="最小值">'
|
||||
+'<span class="adv-range-sep">~</span>'
|
||||
+'<input class="filter-input adv-value adv-range-to" type="text" placeholder="最大值">';
|
||||
}else if(!isRange&&alreadyRange){
|
||||
wrap.innerHTML='<input class="filter-input adv-value" type="text" placeholder="请输入值">';
|
||||
}
|
||||
}
|
||||
function addAdvCondition(){document.getElementById('advConditions').insertAdjacentHTML('beforeend',advConditionRowHTML());}
|
||||
function removeAdvCondition(el){el.parentElement.remove();}
|
||||
function toggleAdvanced(){
|
||||
var p=document.getElementById('advPanel');
|
||||
var open=p.classList.toggle('open');
|
||||
var arr=document.getElementById('advToggle').querySelector('.adv-arrow');
|
||||
if(arr)arr.textContent=open?'▴':'▾';
|
||||
if(open&&!p.querySelector('.adv-cond-row'))addAdvCondition();
|
||||
}
|
||||
function readAdvancedConditions(){
|
||||
var conds=[];
|
||||
document.querySelectorAll('#advConditions .adv-cond-row').forEach(function(row){
|
||||
var field=row.querySelector('.adv-field').value;
|
||||
var op=row.querySelector('.adv-op').value;
|
||||
if(op==='范围'){
|
||||
var from=row.querySelector('.adv-range-from').value.trim();
|
||||
var to=row.querySelector('.adv-range-to').value.trim();
|
||||
if(from!==''||to!=='')conds.push({field:field,op:op,from:from,to:to});
|
||||
}else{
|
||||
var value=row.querySelector('.adv-value').value.trim();
|
||||
if(value!=='')conds.push({field:field,op:op,value:value});
|
||||
}
|
||||
});
|
||||
return conds;
|
||||
}
|
||||
function getFieldRaw(row,field){
|
||||
if(field==='abnormal')return row.abnormal?'是':'否';
|
||||
return row[field];
|
||||
}
|
||||
function numericOf(v){var m=String(v).match(/[-+]?\d+(?:\.\d+)?/);return m?parseFloat(m[0]):null;}
|
||||
function matchCondition(row,cond){
|
||||
var raw=getFieldRaw(row,cond.field);
|
||||
var str=String(raw==null?'':raw);
|
||||
if(cond.op==='包含')return str.indexOf(cond.value)>=0;
|
||||
if(cond.op==='=')return str===cond.value;
|
||||
if(cond.op==='!=')return str!==cond.value;
|
||||
var n=numericOf(str);
|
||||
if(n===null)return false;
|
||||
if(cond.op==='范围'){
|
||||
if(cond.from!==''){var lo=parseFloat(cond.from);if(!isNaN(lo)&&n<lo)return false;}
|
||||
if(cond.to!==''){var hi=parseFloat(cond.to);if(!isNaN(hi)&&n>hi)return false;}
|
||||
return true;
|
||||
}
|
||||
var c=parseFloat(cond.value);if(isNaN(c))return false;
|
||||
if(cond.op==='>')return n>c;
|
||||
if(cond.op==='>=')return n>=c;
|
||||
if(cond.op==='<')return n<c;
|
||||
if(cond.op==='<=')return n<=c;
|
||||
return true;
|
||||
}
|
||||
function clearAdvanced(){
|
||||
document.getElementById('advConditions').innerHTML='';
|
||||
applyListFilter();
|
||||
showToast('已清空高级查询条件');
|
||||
}
|
||||
/* 分页状态 */
|
||||
var listPage=1,listPageSize=20;
|
||||
/* 页码窗口:首页/末页 + 当前页前后各2页 */
|
||||
|
||||
@@ -154,6 +154,25 @@
|
||||
.year-picker__dropdown div{padding:8px 14px;font-size:var(--font-sm);cursor:pointer;}
|
||||
.year-picker__dropdown div:hover{background:var(--primary-light);}
|
||||
.year-picker__dropdown div.selected{color:var(--primary);font-weight:600;}
|
||||
/* 高级查询 */
|
||||
.adv-panel{background:#fff;border-radius:var(--radius-md);padding:16px 24px;margin-bottom:16px;box-shadow:var(--shadow-sm);display:none;}
|
||||
.adv-panel.open{display:block;}
|
||||
.adv-panel__head{font-size:var(--font-base);font-weight:600;margin-bottom:12px;}
|
||||
#advConditions{display:grid;grid-template-columns:1fr 1fr;gap:10px 16px;}
|
||||
.adv-cond-row{display:flex;align-items:center;gap:8px;margin-bottom:0;min-width:0;}
|
||||
.adv-field{min-width:140px;flex:1;}
|
||||
.adv-op{min-width:72px;flex:none;}
|
||||
.adv-value-wrap{display:flex;align-items:center;gap:8px;flex:1;min-width:0;max-width:none;}
|
||||
.adv-value{flex:1;min-width:0;}
|
||||
.adv-range-sep{color:var(--text-secondary);flex-shrink:0;}
|
||||
.adv-del{width:32px;height:32px;border:1px solid var(--border);border-radius:var(--radius-sm);background:#fff;color:var(--text-secondary);cursor:pointer;flex-shrink:0;font-size:var(--font-sm);line-height:1;}
|
||||
.adv-del:hover{color:var(--danger);border-color:var(--danger);}
|
||||
.adv-actions{display:flex;gap:12px;margin-top:2px;}
|
||||
.adv-arrow{font-size:10px;}
|
||||
/* 轻提示 */
|
||||
.toast{position:fixed;top:76px;left:50%;transform:translateX(-50%) translateY(-16px);background:#fff;box-shadow:var(--shadow-md);border-radius:var(--radius-sm);padding:10px 20px;font-size:var(--font-sm);color:var(--text-primary);opacity:0;pointer-events:none;transition:all .25s;z-index:1000;display:flex;align-items:center;gap:8px;}
|
||||
.toast.show{opacity:1;transform:translateX(-50%) translateY(0);}
|
||||
.toast svg{flex-shrink:0;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -290,20 +309,20 @@
|
||||
<option>请选择</option><option>泾河医院</option><option>庆阳医院</option><option>延安医院</option><option>兴隆园医院</option><option>宁夏宝石花医院</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label>性别:</label>
|
||||
<select class="filter-select" style="min-width:90px;">
|
||||
<option>请选择</option><option>男</option><option>女</option><option>通用</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label>年龄区间:</label>
|
||||
<select class="filter-select">
|
||||
<option>请选择</option><option>年龄<35</option><option>35≤年龄<40</option><option>40≤年龄<45</option><option>年龄≥45</option>
|
||||
</select>
|
||||
</div>
|
||||
<button class="btn btn-primary">查询</button>
|
||||
<button class="btn btn-default">重置</button>
|
||||
<button class="btn btn-default" id="advToggle" onclick="toggleAdvanced()">高级查询 <span class="adv-arrow">▾</span></button>
|
||||
</div>
|
||||
|
||||
<!-- 高级查询 -->
|
||||
<div class="adv-panel" id="advPanel">
|
||||
<div class="adv-panel__head">高级查询</div>
|
||||
<div id="advConditions"></div>
|
||||
<div class="adv-actions">
|
||||
<button class="btn btn-default" onclick="addAdvCondition()">+ 添加条件</button>
|
||||
<button class="btn btn-primary" onclick="applyFilter()">查询</button>
|
||||
<button class="btn btn-default" onclick="clearAdvanced()">清空</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
@@ -1041,6 +1060,110 @@ document.querySelectorAll('.year-picker>input').forEach(function(inp){
|
||||
document.addEventListener('click',function(){
|
||||
document.querySelectorAll('.year-picker__dropdown.open').forEach(function(d){d.classList.remove('open');});
|
||||
});
|
||||
/* ============ 高级查询 ============ */
|
||||
var ADV_OPS=['包含','=','!=','>','>=','<','<=','范围'];
|
||||
var ADV_ROW_SELECTOR='.table-card__content tbody tr';
|
||||
var ADV_FIELDS=[
|
||||
{key:'hospital',label:'医院名称',idx:1},{key:'year',label:'体检年份',idx:2},{key:'tplName',label:'模板名称',idx:3},
|
||||
{key:'gender',label:'性别',idx:4},{key:'ageRange',label:'年龄区间',idx:5},{key:'discountType',label:'折扣类型',idx:6},
|
||||
{key:'discountValue',label:'折扣数值(元)',idx:7},{key:'discountPercent',label:'折扣百分比(%)',idx:8}
|
||||
];
|
||||
var ADV_FIELD_OPTS=ADV_FIELDS.map(function(f){return '<option value="'+f.key+'">'+f.label+'</option>';}).join('');
|
||||
function advConditionRowHTML(){
|
||||
return '<div class="adv-cond-row">'
|
||||
+'<select class="filter-select adv-field">'+ADV_FIELD_OPTS+'</select>'
|
||||
+'<select class="filter-select adv-op" onchange="onAdvOpChange(this)">'+ADV_OPS.map(function(o){return '<option value="'+o+'">'+o+'</option>';}).join('')+'</select>'
|
||||
+'<span class="adv-value-wrap"><input class="filter-input adv-value" type="text" placeholder="请输入值"></span>'
|
||||
+'<button class="adv-del" type="button" title="删除该条件" onclick="removeAdvCondition(this)">✕</button>'
|
||||
+'</div>';
|
||||
}
|
||||
function onAdvOpChange(sel){
|
||||
var wrap=sel.parentElement.querySelector('.adv-value-wrap');
|
||||
var isRange=sel.value==='范围';
|
||||
var alreadyRange=!!wrap.querySelector('.adv-range-from');
|
||||
if(isRange&&!alreadyRange){
|
||||
wrap.innerHTML='<input class="filter-input adv-value adv-range-from" type="text" placeholder="最小值">'
|
||||
+'<span class="adv-range-sep">~</span>'
|
||||
+'<input class="filter-input adv-value adv-range-to" type="text" placeholder="最大值">';
|
||||
}else if(!isRange&&alreadyRange){
|
||||
wrap.innerHTML='<input class="filter-input adv-value" type="text" placeholder="请输入值">';
|
||||
}
|
||||
}
|
||||
function addAdvCondition(){document.getElementById('advConditions').insertAdjacentHTML('beforeend',advConditionRowHTML());}
|
||||
function removeAdvCondition(el){el.parentElement.remove();}
|
||||
function toggleAdvanced(){
|
||||
var p=document.getElementById('advPanel');
|
||||
var open=p.classList.toggle('open');
|
||||
var arr=document.getElementById('advToggle').querySelector('.adv-arrow');
|
||||
if(arr)arr.textContent=open?'▴':'▾';
|
||||
if(open&&!p.querySelector('.adv-cond-row'))addAdvCondition();
|
||||
}
|
||||
function readAdvancedConditions(){
|
||||
var conds=[];
|
||||
document.querySelectorAll('#advConditions .adv-cond-row').forEach(function(row){
|
||||
var field=row.querySelector('.adv-field').value;
|
||||
var op=row.querySelector('.adv-op').value;
|
||||
if(op==='范围'){
|
||||
var from=row.querySelector('.adv-range-from').value.trim();
|
||||
var to=row.querySelector('.adv-range-to').value.trim();
|
||||
if(from!==''||to!=='')conds.push({field:field,op:op,from:from,to:to});
|
||||
}else{
|
||||
var value=row.querySelector('.adv-value').value.trim();
|
||||
if(value!=='')conds.push({field:field,op:op,value:value});
|
||||
}
|
||||
});
|
||||
return conds;
|
||||
}
|
||||
function fieldByKey(key){for(var i=0;i<ADV_FIELDS.length;i++){if(ADV_FIELDS[i].key===key)return ADV_FIELDS[i];}return null;}
|
||||
function getFieldRaw(tr,f){var td=tr.cells[f.idx];return td?td.textContent.trim():'';}
|
||||
function numericOf(v){var s=String(v).replace(/,/g,'').replace(/[¥¥]/g,'');var m=s.match(/[-+]?\d+(?:\.\d+)?/);return m?parseFloat(m[0]):null;}
|
||||
function matchCondition(tr,cond){
|
||||
var f=fieldByKey(cond.field);if(!f)return true;
|
||||
var str=getFieldRaw(tr,f);
|
||||
if(cond.op==='包含')return str.indexOf(cond.value)>=0;
|
||||
if(cond.op==='=')return str===cond.value;
|
||||
if(cond.op==='!=')return str!==cond.value;
|
||||
var n=numericOf(str);
|
||||
if(n===null)return false;
|
||||
if(cond.op==='范围'){
|
||||
if(cond.from!==''){var lo=parseFloat(cond.from);if(!isNaN(lo)&&n<lo)return false;}
|
||||
if(cond.to!==''){var hi=parseFloat(cond.to);if(!isNaN(hi)&&n>hi)return false;}
|
||||
return true;
|
||||
}
|
||||
var c=parseFloat(cond.value);if(isNaN(c))return false;
|
||||
if(cond.op==='>')return n>c;
|
||||
if(cond.op==='>=')return n>=c;
|
||||
if(cond.op==='<')return n<c;
|
||||
if(cond.op==='<=')return n<=c;
|
||||
return true;
|
||||
}
|
||||
function applyFilter(){
|
||||
var conds=readAdvancedConditions();
|
||||
document.querySelectorAll(ADV_ROW_SELECTOR).forEach(function(tr){
|
||||
var show=true;
|
||||
for(var i=0;i<conds.length;i++){if(!matchCondition(tr,conds[i])){show=false;break;}}
|
||||
tr.style.display=show?'':'none';
|
||||
});
|
||||
showToast('查询完成');
|
||||
}
|
||||
function clearAdvanced(){
|
||||
document.getElementById('advConditions').innerHTML='';
|
||||
document.querySelectorAll(ADV_ROW_SELECTOR).forEach(function(tr){tr.style.display='';});
|
||||
showToast('已清空高级查询条件');
|
||||
}
|
||||
/* 轻提示 */
|
||||
var toastTimer=null;
|
||||
function showToast(msg){
|
||||
document.getElementById('toastText').textContent=msg;
|
||||
var t=document.getElementById('toast');
|
||||
t.classList.add('show');clearTimeout(toastTimer);
|
||||
toastTimer=setTimeout(function(){t.classList.remove('show');},2400);
|
||||
}
|
||||
</script>
|
||||
<!-- 轻提示 -->
|
||||
<div class="toast" id="toast">
|
||||
<svg width="15" height="15" viewBox="0 0 15 15" fill="none"><circle cx="7.5" cy="7.5" r="6.5" fill="#52C41A"/><path d="M4.6 7.7l2 2 3.8-4" stroke="#fff" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||
<span id="toastText"></span>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -146,6 +146,25 @@
|
||||
.year-picker__dropdown div{padding:8px 14px;font-size:var(--font-sm);cursor:pointer;}
|
||||
.year-picker__dropdown div:hover{background:var(--primary-light);}
|
||||
.year-picker__dropdown div.selected{color:var(--primary);font-weight:600;}
|
||||
/* 高级查询 */
|
||||
.adv-panel{background:#fff;border-radius:var(--radius-md);padding:16px 24px;margin-bottom:16px;box-shadow:var(--shadow-sm);display:none;}
|
||||
.adv-panel.open{display:block;}
|
||||
.adv-panel__head{font-size:var(--font-base);font-weight:600;margin-bottom:12px;}
|
||||
#advConditions{display:grid;grid-template-columns:1fr 1fr;gap:10px 16px;}
|
||||
.adv-cond-row{display:flex;align-items:center;gap:8px;margin-bottom:0;min-width:0;}
|
||||
.adv-field{min-width:140px;flex:1;}
|
||||
.adv-op{min-width:72px;flex:none;}
|
||||
.adv-value-wrap{display:flex;align-items:center;gap:8px;flex:1;min-width:0;max-width:none;}
|
||||
.adv-value{flex:1;min-width:0;}
|
||||
.adv-range-sep{color:var(--text-secondary);flex-shrink:0;}
|
||||
.adv-del{width:32px;height:32px;border:1px solid var(--border);border-radius:var(--radius-sm);background:#fff;color:var(--text-secondary);cursor:pointer;flex-shrink:0;font-size:var(--font-sm);line-height:1;}
|
||||
.adv-del:hover{color:var(--danger);border-color:var(--danger);}
|
||||
.adv-actions{display:flex;gap:12px;margin-top:2px;}
|
||||
.adv-arrow{font-size:10px;}
|
||||
/* 轻提示 */
|
||||
.toast{position:fixed;top:76px;left:50%;transform:translateX(-50%) translateY(-16px);background:#fff;box-shadow:var(--shadow-md);border-radius:var(--radius-sm);padding:10px 20px;font-size:var(--font-sm);color:var(--text-primary);opacity:0;pointer-events:none;transition:all .25s;z-index:1000;display:flex;align-items:center;gap:8px;}
|
||||
.toast.show{opacity:1;transform:translateX(-50%) translateY(0);}
|
||||
.toast svg{flex-shrink:0;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -282,32 +301,20 @@
|
||||
<option>请选择</option><option>第一采油厂</option><option>第二采油厂</option><option>第三采油厂</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label>体检医院:</label>
|
||||
<select class="filter-select">
|
||||
<option>请选择</option><option>泾河医院</option><option>庆阳医院</option><option>延安医院</option><option>兴隆园医院</option><option>宁夏宝石花医院</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label>性别:</label>
|
||||
<select class="filter-select">
|
||||
<option>请选择</option><option>男</option><option>女</option><option>通用</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label>年龄范围:</label>
|
||||
<select class="filter-select">
|
||||
<option>请选择</option><option>年龄<35</option><option>35≤年龄<40</option><option>40≤年龄<45</option><option>年龄≥45</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label>费用审核状态:</label>
|
||||
<select class="filter-select">
|
||||
<option>请选择</option><option>审核通过</option><option>待审核</option><option>已拒绝</option><option>未提交</option>
|
||||
</select>
|
||||
</div>
|
||||
<button class="btn btn-primary">查询</button>
|
||||
<button class="btn btn-default">重置</button>
|
||||
<button class="btn btn-default" id="advToggle" onclick="toggleAdvanced()">高级查询 <span class="adv-arrow">▾</span></button>
|
||||
</div>
|
||||
|
||||
<!-- 高级查询 -->
|
||||
<div class="adv-panel" id="advPanel">
|
||||
<div class="adv-panel__head">高级查询</div>
|
||||
<div id="advConditions"></div>
|
||||
<div class="adv-actions">
|
||||
<button class="btn btn-default" onclick="addAdvCondition()">+ 添加条件</button>
|
||||
<button class="btn btn-primary" onclick="applyFilter()">查询</button>
|
||||
<button class="btn btn-default" onclick="clearAdvanced()">清空</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
@@ -992,6 +999,111 @@ document.querySelectorAll('.year-picker>input').forEach(function(inp){
|
||||
document.addEventListener('click',function(){
|
||||
document.querySelectorAll('.year-picker__dropdown.open').forEach(function(d){d.classList.remove('open');});
|
||||
});
|
||||
/* ============ 高级查询 ============ */
|
||||
var ADV_OPS=['包含','=','!=','>','>=','<','<=','范围'];
|
||||
var ADV_ROW_SELECTOR='.table-card__content tbody tr';
|
||||
var ADV_FIELDS=[
|
||||
{key:'comboName',label:'项目组合名称',idx:2},{key:'hospital',label:'承检医院',idx:3},{key:'unit',label:'单位',idx:4},
|
||||
{key:'year',label:'体检年份',idx:5},{key:'gender',label:'性别',idx:6},{key:'ageRange',label:'年龄范围',idx:7},
|
||||
{key:'declaredFee',label:'本次提交费用(元)',idx:8},{key:'auditStatus',label:'费用审核状态',idx:9},
|
||||
{key:'effectiveFee',label:'必检项目费用(已生效)',idx:10},{key:'genStatus',label:'生成状态',idx:11},{key:'genTime',label:'生成时间',idx:12}
|
||||
];
|
||||
var ADV_FIELD_OPTS=ADV_FIELDS.map(function(f){return '<option value="'+f.key+'">'+f.label+'</option>';}).join('');
|
||||
function advConditionRowHTML(){
|
||||
return '<div class="adv-cond-row">'
|
||||
+'<select class="filter-select adv-field">'+ADV_FIELD_OPTS+'</select>'
|
||||
+'<select class="filter-select adv-op" onchange="onAdvOpChange(this)">'+ADV_OPS.map(function(o){return '<option value="'+o+'">'+o+'</option>';}).join('')+'</select>'
|
||||
+'<span class="adv-value-wrap"><input class="filter-input adv-value" type="text" placeholder="请输入值"></span>'
|
||||
+'<button class="adv-del" type="button" title="删除该条件" onclick="removeAdvCondition(this)">✕</button>'
|
||||
+'</div>';
|
||||
}
|
||||
function onAdvOpChange(sel){
|
||||
var wrap=sel.parentElement.querySelector('.adv-value-wrap');
|
||||
var isRange=sel.value==='范围';
|
||||
var alreadyRange=!!wrap.querySelector('.adv-range-from');
|
||||
if(isRange&&!alreadyRange){
|
||||
wrap.innerHTML='<input class="filter-input adv-value adv-range-from" type="text" placeholder="最小值">'
|
||||
+'<span class="adv-range-sep">~</span>'
|
||||
+'<input class="filter-input adv-value adv-range-to" type="text" placeholder="最大值">';
|
||||
}else if(!isRange&&alreadyRange){
|
||||
wrap.innerHTML='<input class="filter-input adv-value" type="text" placeholder="请输入值">';
|
||||
}
|
||||
}
|
||||
function addAdvCondition(){document.getElementById('advConditions').insertAdjacentHTML('beforeend',advConditionRowHTML());}
|
||||
function removeAdvCondition(el){el.parentElement.remove();}
|
||||
function toggleAdvanced(){
|
||||
var p=document.getElementById('advPanel');
|
||||
var open=p.classList.toggle('open');
|
||||
var arr=document.getElementById('advToggle').querySelector('.adv-arrow');
|
||||
if(arr)arr.textContent=open?'▴':'▾';
|
||||
if(open&&!p.querySelector('.adv-cond-row'))addAdvCondition();
|
||||
}
|
||||
function readAdvancedConditions(){
|
||||
var conds=[];
|
||||
document.querySelectorAll('#advConditions .adv-cond-row').forEach(function(row){
|
||||
var field=row.querySelector('.adv-field').value;
|
||||
var op=row.querySelector('.adv-op').value;
|
||||
if(op==='范围'){
|
||||
var from=row.querySelector('.adv-range-from').value.trim();
|
||||
var to=row.querySelector('.adv-range-to').value.trim();
|
||||
if(from!==''||to!=='')conds.push({field:field,op:op,from:from,to:to});
|
||||
}else{
|
||||
var value=row.querySelector('.adv-value').value.trim();
|
||||
if(value!=='')conds.push({field:field,op:op,value:value});
|
||||
}
|
||||
});
|
||||
return conds;
|
||||
}
|
||||
function fieldByKey(key){for(var i=0;i<ADV_FIELDS.length;i++){if(ADV_FIELDS[i].key===key)return ADV_FIELDS[i];}return null;}
|
||||
function getFieldRaw(tr,f){var td=tr.cells[f.idx];return td?td.textContent.trim():'';}
|
||||
function numericOf(v){var s=String(v).replace(/,/g,'').replace(/[¥¥]/g,'');var m=s.match(/[-+]?\d+(?:\.\d+)?/);return m?parseFloat(m[0]):null;}
|
||||
function matchCondition(tr,cond){
|
||||
var f=fieldByKey(cond.field);if(!f)return true;
|
||||
var str=getFieldRaw(tr,f);
|
||||
if(cond.op==='包含')return str.indexOf(cond.value)>=0;
|
||||
if(cond.op==='=')return str===cond.value;
|
||||
if(cond.op==='!=')return str!==cond.value;
|
||||
var n=numericOf(str);
|
||||
if(n===null)return false;
|
||||
if(cond.op==='范围'){
|
||||
if(cond.from!==''){var lo=parseFloat(cond.from);if(!isNaN(lo)&&n<lo)return false;}
|
||||
if(cond.to!==''){var hi=parseFloat(cond.to);if(!isNaN(hi)&&n>hi)return false;}
|
||||
return true;
|
||||
}
|
||||
var c=parseFloat(cond.value);if(isNaN(c))return false;
|
||||
if(cond.op==='>')return n>c;
|
||||
if(cond.op==='>=')return n>=c;
|
||||
if(cond.op==='<')return n<c;
|
||||
if(cond.op==='<=')return n<=c;
|
||||
return true;
|
||||
}
|
||||
function applyFilter(){
|
||||
var conds=readAdvancedConditions();
|
||||
document.querySelectorAll(ADV_ROW_SELECTOR).forEach(function(tr){
|
||||
var show=true;
|
||||
for(var i=0;i<conds.length;i++){if(!matchCondition(tr,conds[i])){show=false;break;}}
|
||||
tr.style.display=show?'':'none';
|
||||
});
|
||||
showToast('查询完成');
|
||||
}
|
||||
function clearAdvanced(){
|
||||
document.getElementById('advConditions').innerHTML='';
|
||||
document.querySelectorAll(ADV_ROW_SELECTOR).forEach(function(tr){tr.style.display='';});
|
||||
showToast('已清空高级查询条件');
|
||||
}
|
||||
/* 轻提示 */
|
||||
var toastTimer=null;
|
||||
function showToast(msg){
|
||||
document.getElementById('toastText').textContent=msg;
|
||||
var t=document.getElementById('toast');
|
||||
t.classList.add('show');clearTimeout(toastTimer);
|
||||
toastTimer=setTimeout(function(){t.classList.remove('show');},2400);
|
||||
}
|
||||
</script>
|
||||
<!-- 轻提示 -->
|
||||
<div class="toast" id="toast">
|
||||
<svg width="15" height="15" viewBox="0 0 15 15" fill="none"><circle cx="7.5" cy="7.5" r="6.5" fill="#52C41A"/><path d="M4.6 7.7l2 2 3.8-4" stroke="#fff" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||
<span id="toastText"></span>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -153,6 +153,25 @@
|
||||
.year-picker__dropdown div{padding:8px 14px;font-size:var(--font-sm);cursor:pointer;}
|
||||
.year-picker__dropdown div:hover{background:var(--primary-light);}
|
||||
.year-picker__dropdown div.selected{color:var(--primary);font-weight:600;}
|
||||
/* 高级查询 */
|
||||
.adv-panel{background:#fff;border-radius:var(--radius-md);padding:16px 24px;margin-bottom:16px;box-shadow:var(--shadow-sm);display:none;}
|
||||
.adv-panel.open{display:block;}
|
||||
.adv-panel__head{font-size:var(--font-base);font-weight:600;margin-bottom:12px;}
|
||||
#advConditions{display:grid;grid-template-columns:1fr 1fr;gap:10px 16px;}
|
||||
.adv-cond-row{display:flex;align-items:center;gap:8px;margin-bottom:0;min-width:0;}
|
||||
.adv-field{min-width:140px;flex:1;}
|
||||
.adv-op{min-width:72px;flex:none;}
|
||||
.adv-value-wrap{display:flex;align-items:center;gap:8px;flex:1;min-width:0;max-width:none;}
|
||||
.adv-value{flex:1;min-width:0;}
|
||||
.adv-range-sep{color:var(--text-secondary);flex-shrink:0;}
|
||||
.adv-del{width:32px;height:32px;border:1px solid var(--border);border-radius:var(--radius-sm);background:#fff;color:var(--text-secondary);cursor:pointer;flex-shrink:0;font-size:var(--font-sm);line-height:1;}
|
||||
.adv-del:hover{color:var(--danger);border-color:var(--danger);}
|
||||
.adv-actions{display:flex;gap:12px;margin-top:2px;}
|
||||
.adv-arrow{font-size:10px;}
|
||||
/* 轻提示 */
|
||||
.toast{position:fixed;top:76px;left:50%;transform:translateX(-50%) translateY(-16px);background:#fff;box-shadow:var(--shadow-md);border-radius:var(--radius-sm);padding:10px 20px;font-size:var(--font-sm);color:var(--text-primary);opacity:0;pointer-events:none;transition:all .25s;z-index:1000;display:flex;align-items:center;gap:8px;}
|
||||
.toast.show{opacity:1;transform:translateX(-50%) translateY(0);}
|
||||
.toast svg{flex-shrink:0;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -300,33 +319,20 @@
|
||||
<label>身份证号:</label>
|
||||
<input class="filter-input" type="text" placeholder="请输入" style="min-width:160px;">
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label>性别:</label>
|
||||
<select class="filter-select" style="min-width:120px;">
|
||||
<option>请选择性别</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label>年龄范围:</label>
|
||||
<select class="filter-select">
|
||||
<option>请选择</option>
|
||||
<option>年龄<35</option>
|
||||
<option>35≤年龄<40</option>
|
||||
<option>40≤年龄<45</option>
|
||||
<option>年龄≥45</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label>防癌类型:</label>
|
||||
<select class="filter-select">
|
||||
<option>请选择</option>
|
||||
<option>Septin9</option>
|
||||
<option>CA724</option>
|
||||
<option>两项都有</option>
|
||||
</select>
|
||||
</div>
|
||||
<button class="btn btn-primary">查询</button>
|
||||
<button class="btn btn-default">重置</button>
|
||||
<button class="btn btn-default" id="advToggle" onclick="toggleAdvanced()">高级查询 <span class="adv-arrow">▾</span></button>
|
||||
</div>
|
||||
|
||||
<!-- 高级查询 -->
|
||||
<div class="adv-panel" id="advPanel">
|
||||
<div class="adv-panel__head">高级查询</div>
|
||||
<div id="advConditions"></div>
|
||||
<div class="adv-actions">
|
||||
<button class="btn btn-default" onclick="addAdvCondition()">+ 添加条件</button>
|
||||
<button class="btn btn-primary" onclick="applyFilter()">查询</button>
|
||||
<button class="btn btn-default" onclick="clearAdvanced()">清空</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
@@ -827,6 +833,114 @@ document.querySelectorAll('.year-picker>input').forEach(function(inp){
|
||||
document.addEventListener('click',function(){
|
||||
document.querySelectorAll('.year-picker__dropdown.open').forEach(function(d){d.classList.remove('open');});
|
||||
});
|
||||
/* ============ 高级查询 ============ */
|
||||
var ADV_OPS=['包含','=','!=','>','>=','<','<=','范围'];
|
||||
var ADV_ROW_SELECTOR='.table-card__content tbody tr';
|
||||
var ADV_FIELDS=[
|
||||
{key:'name',label:'姓名',idx:1},{key:'empNo',label:'员工编号',idx:2},{key:'gender',label:'性别',idx:3},
|
||||
{key:'age',label:'年龄',idx:4},{key:'ageRange',label:'年龄范围',idx:5},{key:'idCard',label:'身份证号',idx:6},
|
||||
{key:'phone',label:'手机号',idx:7},{key:'unit',label:'单位',idx:8},{key:'dept',label:'部门',idx:9},
|
||||
{key:'year',label:'体检年份',idx:10},{key:'plan',label:'体检计划',idx:11},{key:'planUnit',label:'体检计划单位',idx:12},
|
||||
{key:'cancerType',label:'防癌筛查类型',idx:13},{key:'cancerYear',label:'防癌检查年份',idx:14},
|
||||
{key:'s9Checked',label:'Septin9是否已检',idx:15},{key:'s9Abn',label:'Septin9检查异常',idx:16},{key:'s9Value',label:'Septin9项目值',idx:17},
|
||||
{key:'caChecked',label:'CA724是否已检',idx:18},{key:'caAbn',label:'CA724检查异常',idx:19},{key:'caValue',label:'CA724项目值',idx:20}
|
||||
];
|
||||
var ADV_FIELD_OPTS=ADV_FIELDS.map(function(f){return '<option value="'+f.key+'">'+f.label+'</option>';}).join('');
|
||||
function advConditionRowHTML(){
|
||||
return '<div class="adv-cond-row">'
|
||||
+'<select class="filter-select adv-field">'+ADV_FIELD_OPTS+'</select>'
|
||||
+'<select class="filter-select adv-op" onchange="onAdvOpChange(this)">'+ADV_OPS.map(function(o){return '<option value="'+o+'">'+o+'</option>';}).join('')+'</select>'
|
||||
+'<span class="adv-value-wrap"><input class="filter-input adv-value" type="text" placeholder="请输入值"></span>'
|
||||
+'<button class="adv-del" type="button" title="删除该条件" onclick="removeAdvCondition(this)">✕</button>'
|
||||
+'</div>';
|
||||
}
|
||||
function onAdvOpChange(sel){
|
||||
var wrap=sel.parentElement.querySelector('.adv-value-wrap');
|
||||
var isRange=sel.value==='范围';
|
||||
var alreadyRange=!!wrap.querySelector('.adv-range-from');
|
||||
if(isRange&&!alreadyRange){
|
||||
wrap.innerHTML='<input class="filter-input adv-value adv-range-from" type="text" placeholder="最小值">'
|
||||
+'<span class="adv-range-sep">~</span>'
|
||||
+'<input class="filter-input adv-value adv-range-to" type="text" placeholder="最大值">';
|
||||
}else if(!isRange&&alreadyRange){
|
||||
wrap.innerHTML='<input class="filter-input adv-value" type="text" placeholder="请输入值">';
|
||||
}
|
||||
}
|
||||
function addAdvCondition(){document.getElementById('advConditions').insertAdjacentHTML('beforeend',advConditionRowHTML());}
|
||||
function removeAdvCondition(el){el.parentElement.remove();}
|
||||
function toggleAdvanced(){
|
||||
var p=document.getElementById('advPanel');
|
||||
var open=p.classList.toggle('open');
|
||||
var arr=document.getElementById('advToggle').querySelector('.adv-arrow');
|
||||
if(arr)arr.textContent=open?'▴':'▾';
|
||||
if(open&&!p.querySelector('.adv-cond-row'))addAdvCondition();
|
||||
}
|
||||
function readAdvancedConditions(){
|
||||
var conds=[];
|
||||
document.querySelectorAll('#advConditions .adv-cond-row').forEach(function(row){
|
||||
var field=row.querySelector('.adv-field').value;
|
||||
var op=row.querySelector('.adv-op').value;
|
||||
if(op==='范围'){
|
||||
var from=row.querySelector('.adv-range-from').value.trim();
|
||||
var to=row.querySelector('.adv-range-to').value.trim();
|
||||
if(from!==''||to!=='')conds.push({field:field,op:op,from:from,to:to});
|
||||
}else{
|
||||
var value=row.querySelector('.adv-value').value.trim();
|
||||
if(value!=='')conds.push({field:field,op:op,value:value});
|
||||
}
|
||||
});
|
||||
return conds;
|
||||
}
|
||||
function fieldByKey(key){for(var i=0;i<ADV_FIELDS.length;i++){if(ADV_FIELDS[i].key===key)return ADV_FIELDS[i];}return null;}
|
||||
function getFieldRaw(tr,f){var td=tr.cells[f.idx];return td?td.textContent.trim():'';}
|
||||
function numericOf(v){var s=String(v).replace(/,/g,'').replace(/[¥¥]/g,'');var m=s.match(/[-+]?\d+(?:\.\d+)?/);return m?parseFloat(m[0]):null;}
|
||||
function matchCondition(tr,cond){
|
||||
var f=fieldByKey(cond.field);if(!f)return true;
|
||||
var str=getFieldRaw(tr,f);
|
||||
if(cond.op==='包含')return str.indexOf(cond.value)>=0;
|
||||
if(cond.op==='=')return str===cond.value;
|
||||
if(cond.op==='!=')return str!==cond.value;
|
||||
var n=numericOf(str);
|
||||
if(n===null)return false;
|
||||
if(cond.op==='范围'){
|
||||
if(cond.from!==''){var lo=parseFloat(cond.from);if(!isNaN(lo)&&n<lo)return false;}
|
||||
if(cond.to!==''){var hi=parseFloat(cond.to);if(!isNaN(hi)&&n>hi)return false;}
|
||||
return true;
|
||||
}
|
||||
var c=parseFloat(cond.value);if(isNaN(c))return false;
|
||||
if(cond.op==='>')return n>c;
|
||||
if(cond.op==='>=')return n>=c;
|
||||
if(cond.op==='<')return n<c;
|
||||
if(cond.op==='<=')return n<=c;
|
||||
return true;
|
||||
}
|
||||
function applyFilter(){
|
||||
var conds=readAdvancedConditions();
|
||||
document.querySelectorAll(ADV_ROW_SELECTOR).forEach(function(tr){
|
||||
var show=true;
|
||||
for(var i=0;i<conds.length;i++){if(!matchCondition(tr,conds[i])){show=false;break;}}
|
||||
tr.style.display=show?'':'none';
|
||||
});
|
||||
showToast('查询完成');
|
||||
}
|
||||
function clearAdvanced(){
|
||||
document.getElementById('advConditions').innerHTML='';
|
||||
document.querySelectorAll(ADV_ROW_SELECTOR).forEach(function(tr){tr.style.display='';});
|
||||
showToast('已清空高级查询条件');
|
||||
}
|
||||
/* 轻提示 */
|
||||
var toastTimer=null;
|
||||
function showToast(msg){
|
||||
document.getElementById('toastText').textContent=msg;
|
||||
var t=document.getElementById('toast');
|
||||
t.classList.add('show');clearTimeout(toastTimer);
|
||||
toastTimer=setTimeout(function(){t.classList.remove('show');},2400);
|
||||
}
|
||||
</script>
|
||||
<!-- 轻提示 -->
|
||||
<div class="toast" id="toast">
|
||||
<svg width="15" height="15" viewBox="0 0 15 15" fill="none"><circle cx="7.5" cy="7.5" r="6.5" fill="#52C41A"/><path d="M4.6 7.7l2 2 3.8-4" stroke="#fff" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||
<span id="toastText"></span>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user