feat: 检后模块新增影像数据管理菜单
This commit is contained in:
@@ -1,5 +1,17 @@
|
||||
# 健康体检模块 CHANGELOG
|
||||
|
||||
## [Unreleased] 2026-09-18
|
||||
|
||||
### Added
|
||||
- 检后侧边栏新增「体检影像管理」二级菜单(位于冠脉CTA体检分组之后),复刻老系统 data-center-vue3 `views/imc` 四个列表页为纯 HTML 原型:
|
||||
- `post-imc-user.html`(用户体检信息):筛选(姓名/身份证号/体检年份/医院名称);行勾选 + 批量删除;主表列(单位信息/姓名/身份证号/体检年份/医院名称/体检编号/创建日期);行首箭头展开子表(检查项目名称/处理状态/影像信息·预览/影像报告·查看,无数据显示「暂无/无文件」);操作列编辑/详情/删除 + 编辑弹窗(7 字段)+ 详情弹窗
|
||||
- `post-imc-class.html`(用户影像文件分类):筛选(影像分类/检查项目名称/处理状态);操作栏新增/导出/导入 + 批量删除;列(影像分类/检查项目名称/影像文件类型/报告文件类型/处理状态/检查结果/错误信息/出报告时间/创建日期),检查结果与错误信息长文本截断、悬停显示全文;操作列编辑/详情/删除 + 新增/编辑弹窗(10 字段)+ 详情弹窗
|
||||
- `post-imc-info.html`(用户影像文件详细):筛选(文件类型/患者ID/研究实例ID);操作栏新增/导出/导入 + 批量删除;列(文件类型·影像/报告标签/影像序号/错误信息/文件地址·下载/dcm实例ID/研究实例ID/患者ID/研究ID/创建日期);操作列编辑/详情/删除 + 新增/编辑弹窗(10 字段)+ 详情弹窗
|
||||
- `post-imc-log.html`(文件处理日志):筛选(身份证号/体检年份/体检编号/影像分类/处理状态);行勾选 + 批量删除;列(医院名称/姓名/身份证号/体检年份/体检编号/影像分类/json数据·截断/文件地址·下载zip/文件大小MB/处理状态/错误信息/传输开始/传输完成/解析开始/解析完成时间),默认按传输开始时间倒序;操作列详情/删除 + 详情弹窗(15 字段含 json 数据代码块)
|
||||
- 数据字典沿用老系统:影像分类(超声/CT/MRI/X射线/心电)、处理状态(新建/待解析/失败/解析中/成功/失败待重试/最终失败,彩色标签)、文件类型(影像/报告)
|
||||
- `index.html` SITE_MAP 健康体检模块新增「用户体检信息/用户影像文件分类/用户影像文件详细/文件处理日志」四个入口
|
||||
- 25 个检后页面侧边栏统一新增「体检影像管理」分组(21 个存量页面批量同步 + 4 个新页面自身 active 指向)
|
||||
|
||||
## [Unreleased] 2026-09-17
|
||||
|
||||
### Changed
|
||||
|
||||
@@ -198,6 +198,18 @@
|
||||
<a href="post-cta-stat.html" class="sidebar-item">冠脉CTA体检统计</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sidebar-subgroup">
|
||||
<div class="sidebar-subgroup__header" onclick="toggleSubgroup(this)">
|
||||
<svg class="arrow" viewBox="0 0 12 12"><path d="M4 2l4 4-4 4" fill="none" stroke-width="1.5" stroke-linecap="round"/></svg>
|
||||
体检影像管理
|
||||
</div>
|
||||
<div class="sidebar-subgroup__body">
|
||||
<a href="post-imc-user.html" class="sidebar-item">用户体检信息</a>
|
||||
<a href="post-imc-class.html" class="sidebar-item">用户影像文件分类</a>
|
||||
<a href="post-imc-info.html" class="sidebar-item">用户影像文件详细</a>
|
||||
<a href="post-imc-log.html" class="sidebar-item">文件处理日志</a>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<!-- 主内容 -->
|
||||
|
||||
@@ -181,6 +181,18 @@
|
||||
<a href="post-cta-stat.html" class="sidebar-item">冠脉CTA体检统计</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sidebar-subgroup">
|
||||
<div class="sidebar-subgroup__header" onclick="toggleSubgroup(this)">
|
||||
<svg class="arrow" viewBox="0 0 12 12"><path d="M4 2l4 4-4 4" fill="none" stroke-width="1.5" stroke-linecap="round"/></svg>
|
||||
体检影像管理
|
||||
</div>
|
||||
<div class="sidebar-subgroup__body">
|
||||
<a href="post-imc-user.html" class="sidebar-item">用户体检信息</a>
|
||||
<a href="post-imc-class.html" class="sidebar-item">用户影像文件分类</a>
|
||||
<a href="post-imc-info.html" class="sidebar-item">用户影像文件详细</a>
|
||||
<a href="post-imc-log.html" class="sidebar-item">文件处理日志</a>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<!-- 主内容 -->
|
||||
|
||||
@@ -208,6 +208,18 @@
|
||||
<a href="post-cta-stat.html" class="sidebar-item">冠脉CTA体检统计</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sidebar-subgroup">
|
||||
<div class="sidebar-subgroup__header" onclick="toggleSubgroup(this)">
|
||||
<svg class="arrow" viewBox="0 0 12 12"><path d="M4 2l4 4-4 4" fill="none" stroke-width="1.5" stroke-linecap="round"/></svg>
|
||||
体检影像管理
|
||||
</div>
|
||||
<div class="sidebar-subgroup__body">
|
||||
<a href="post-imc-user.html" class="sidebar-item">用户体检信息</a>
|
||||
<a href="post-imc-class.html" class="sidebar-item">用户影像文件分类</a>
|
||||
<a href="post-imc-info.html" class="sidebar-item">用户影像文件详细</a>
|
||||
<a href="post-imc-log.html" class="sidebar-item">文件处理日志</a>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<!-- 主内容 -->
|
||||
|
||||
@@ -172,6 +172,18 @@
|
||||
<a href="post-cta-stat.html" class="sidebar-item">冠脉CTA体检统计</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sidebar-subgroup">
|
||||
<div class="sidebar-subgroup__header" onclick="toggleSubgroup(this)">
|
||||
<svg class="arrow" viewBox="0 0 12 12"><path d="M4 2l4 4-4 4" fill="none" stroke-width="1.5" stroke-linecap="round"/></svg>
|
||||
体检影像管理
|
||||
</div>
|
||||
<div class="sidebar-subgroup__body">
|
||||
<a href="post-imc-user.html" class="sidebar-item">用户体检信息</a>
|
||||
<a href="post-imc-class.html" class="sidebar-item">用户影像文件分类</a>
|
||||
<a href="post-imc-info.html" class="sidebar-item">用户影像文件详细</a>
|
||||
<a href="post-imc-log.html" class="sidebar-item">文件处理日志</a>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<!-- 主内容 -->
|
||||
|
||||
@@ -239,6 +239,18 @@
|
||||
<a href="post-cta-stat.html" class="sidebar-item">冠脉CTA体检统计</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sidebar-subgroup">
|
||||
<div class="sidebar-subgroup__header" onclick="toggleSubgroup(this)">
|
||||
<svg class="arrow" viewBox="0 0 12 12"><path d="M4 2l4 4-4 4" fill="none" stroke-width="1.5" stroke-linecap="round"/></svg>
|
||||
体检影像管理
|
||||
</div>
|
||||
<div class="sidebar-subgroup__body">
|
||||
<a href="post-imc-user.html" class="sidebar-item">用户体检信息</a>
|
||||
<a href="post-imc-class.html" class="sidebar-item">用户影像文件分类</a>
|
||||
<a href="post-imc-info.html" class="sidebar-item">用户影像文件详细</a>
|
||||
<a href="post-imc-log.html" class="sidebar-item">文件处理日志</a>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<!-- 主内容 -->
|
||||
|
||||
@@ -198,6 +198,18 @@
|
||||
<a href="post-cta-stat.html" class="sidebar-item active">冠脉CTA体检统计</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sidebar-subgroup">
|
||||
<div class="sidebar-subgroup__header" onclick="toggleSubgroup(this)">
|
||||
<svg class="arrow" viewBox="0 0 12 12"><path d="M4 2l4 4-4 4" fill="none" stroke-width="1.5" stroke-linecap="round"/></svg>
|
||||
体检影像管理
|
||||
</div>
|
||||
<div class="sidebar-subgroup__body">
|
||||
<a href="post-imc-user.html" class="sidebar-item">用户体检信息</a>
|
||||
<a href="post-imc-class.html" class="sidebar-item">用户影像文件分类</a>
|
||||
<a href="post-imc-info.html" class="sidebar-item">用户影像文件详细</a>
|
||||
<a href="post-imc-log.html" class="sidebar-item">文件处理日志</a>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<!-- 主内容 -->
|
||||
|
||||
@@ -206,6 +206,18 @@
|
||||
<a href="post-cta-stat.html" class="sidebar-item">冠脉CTA体检统计</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sidebar-subgroup">
|
||||
<div class="sidebar-subgroup__header" onclick="toggleSubgroup(this)">
|
||||
<svg class="arrow" viewBox="0 0 12 12"><path d="M4 2l4 4-4 4" fill="none" stroke-width="1.5" stroke-linecap="round"/></svg>
|
||||
体检影像管理
|
||||
</div>
|
||||
<div class="sidebar-subgroup__body">
|
||||
<a href="post-imc-user.html" class="sidebar-item">用户体检信息</a>
|
||||
<a href="post-imc-class.html" class="sidebar-item">用户影像文件分类</a>
|
||||
<a href="post-imc-info.html" class="sidebar-item">用户影像文件详细</a>
|
||||
<a href="post-imc-log.html" class="sidebar-item">文件处理日志</a>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<!-- 主内容 -->
|
||||
|
||||
@@ -181,6 +181,18 @@
|
||||
<a href="post-cta-stat.html" class="sidebar-item">冠脉CTA体检统计</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sidebar-subgroup">
|
||||
<div class="sidebar-subgroup__header" onclick="toggleSubgroup(this)">
|
||||
<svg class="arrow" viewBox="0 0 12 12"><path d="M4 2l4 4-4 4" fill="none" stroke-width="1.5" stroke-linecap="round"/></svg>
|
||||
体检影像管理
|
||||
</div>
|
||||
<div class="sidebar-subgroup__body">
|
||||
<a href="post-imc-user.html" class="sidebar-item">用户体检信息</a>
|
||||
<a href="post-imc-class.html" class="sidebar-item">用户影像文件分类</a>
|
||||
<a href="post-imc-info.html" class="sidebar-item">用户影像文件详细</a>
|
||||
<a href="post-imc-log.html" class="sidebar-item">文件处理日志</a>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<!-- 主内容 -->
|
||||
|
||||
@@ -194,6 +194,18 @@
|
||||
<a href="post-cta-stat.html" class="sidebar-item">冠脉CTA体检统计</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sidebar-subgroup">
|
||||
<div class="sidebar-subgroup__header" onclick="toggleSubgroup(this)">
|
||||
<svg class="arrow" viewBox="0 0 12 12"><path d="M4 2l4 4-4 4" fill="none" stroke-width="1.5" stroke-linecap="round"/></svg>
|
||||
体检影像管理
|
||||
</div>
|
||||
<div class="sidebar-subgroup__body">
|
||||
<a href="post-imc-user.html" class="sidebar-item">用户体检信息</a>
|
||||
<a href="post-imc-class.html" class="sidebar-item">用户影像文件分类</a>
|
||||
<a href="post-imc-info.html" class="sidebar-item">用户影像文件详细</a>
|
||||
<a href="post-imc-log.html" class="sidebar-item">文件处理日志</a>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<!-- 主内容 -->
|
||||
|
||||
@@ -198,6 +198,18 @@
|
||||
<a href="post-cta-stat.html" class="sidebar-item">冠脉CTA体检统计</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sidebar-subgroup">
|
||||
<div class="sidebar-subgroup__header" onclick="toggleSubgroup(this)">
|
||||
<svg class="arrow" viewBox="0 0 12 12"><path d="M4 2l4 4-4 4" fill="none" stroke-width="1.5" stroke-linecap="round"/></svg>
|
||||
体检影像管理
|
||||
</div>
|
||||
<div class="sidebar-subgroup__body">
|
||||
<a href="post-imc-user.html" class="sidebar-item">用户体检信息</a>
|
||||
<a href="post-imc-class.html" class="sidebar-item">用户影像文件分类</a>
|
||||
<a href="post-imc-info.html" class="sidebar-item">用户影像文件详细</a>
|
||||
<a href="post-imc-log.html" class="sidebar-item">文件处理日志</a>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<!-- 主内容 -->
|
||||
|
||||
@@ -181,6 +181,18 @@
|
||||
<a href="post-cta-stat.html" class="sidebar-item">冠脉CTA体检统计</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sidebar-subgroup">
|
||||
<div class="sidebar-subgroup__header" onclick="toggleSubgroup(this)">
|
||||
<svg class="arrow" viewBox="0 0 12 12"><path d="M4 2l4 4-4 4" fill="none" stroke-width="1.5" stroke-linecap="round"/></svg>
|
||||
体检影像管理
|
||||
</div>
|
||||
<div class="sidebar-subgroup__body">
|
||||
<a href="post-imc-user.html" class="sidebar-item">用户体检信息</a>
|
||||
<a href="post-imc-class.html" class="sidebar-item">用户影像文件分类</a>
|
||||
<a href="post-imc-info.html" class="sidebar-item">用户影像文件详细</a>
|
||||
<a href="post-imc-log.html" class="sidebar-item">文件处理日志</a>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<!-- 主内容 -->
|
||||
|
||||
@@ -208,6 +208,18 @@
|
||||
<a href="post-cta-stat.html" class="sidebar-item">冠脉CTA体检统计</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sidebar-subgroup">
|
||||
<div class="sidebar-subgroup__header" onclick="toggleSubgroup(this)">
|
||||
<svg class="arrow" viewBox="0 0 12 12"><path d="M4 2l4 4-4 4" fill="none" stroke-width="1.5" stroke-linecap="round"/></svg>
|
||||
体检影像管理
|
||||
</div>
|
||||
<div class="sidebar-subgroup__body">
|
||||
<a href="post-imc-user.html" class="sidebar-item">用户体检信息</a>
|
||||
<a href="post-imc-class.html" class="sidebar-item">用户影像文件分类</a>
|
||||
<a href="post-imc-info.html" class="sidebar-item">用户影像文件详细</a>
|
||||
<a href="post-imc-log.html" class="sidebar-item">文件处理日志</a>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<!-- 主内容 -->
|
||||
|
||||
@@ -0,0 +1,619 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>健康体检 - 用户影像文件分类 | 健康CQ原型</title>
|
||||
<style>
|
||||
*{box-sizing:border-box;margin:0;padding:0;}
|
||||
body{font-family:-apple-system,BlinkMacSystemFont,'PingFang SC','Microsoft YaHei',sans-serif;background:#F5F7FA;color:#333;min-width:1280px;}
|
||||
:root{
|
||||
--primary:#1890FF;--primary-light:#E6F7FF;--success:#52C41A;--warning:#FAAD14;--danger:#FF4D4F;
|
||||
--text-primary:#333;--text-secondary:#666;--text-placeholder:#999;--border:#E8E8E8;--background:#F5F7FA;
|
||||
--font-xs:11px;--font-sm:13px;--font-base:15px;--font-lg:17px;--font-xl:20px;--font-xxl:24px;
|
||||
--radius-sm:4px;--radius-md:8px;--radius-lg:12px;
|
||||
--shadow-sm:0 1px 4px rgba(0,0,0,0.08);--shadow-md:0 4px 12px rgba(0,0,0,0.12);
|
||||
}
|
||||
.top-bar{display:flex;align-items:center;height:56px;background:#001529;padding:0 24px;position:fixed;top:0;left:0;right:0;z-index:100;}
|
||||
.top-bar__logo{display:flex;align-items:center;gap:8px;color:#fff;font-size:var(--font-lg);font-weight:600;white-space:nowrap;width:240px;flex-shrink:0;}
|
||||
.top-bar__logo svg{width:28px;height:28px;}
|
||||
.top-bar__nav{display:flex;align-items:center;gap:4px;flex:1;}
|
||||
.top-bar__nav a{color:rgba(255,255,255,0.65);text-decoration:none;padding:6px 16px;border-radius:var(--radius-sm);font-size:var(--font-sm);transition:all .2s;}
|
||||
.top-bar__nav a:hover{color:#fff;background:rgba(255,255,255,0.08);}
|
||||
.top-bar__nav a.active{color:#fff;background:var(--primary);}
|
||||
.top-bar__right{display:flex;align-items:center;gap:16px;color:rgba(255,255,255,0.65);font-size:var(--font-sm);}
|
||||
.top-bar__right .btn-back{color:rgba(255,255,255,0.65);cursor:pointer;display:flex;align-items:center;gap:4px;text-decoration:none;}
|
||||
.top-bar__right .btn-back:hover{color:#fff;}
|
||||
.avatar{width:32px;height:32px;border-radius:50%;background:#1890FF;display:flex;align-items:center;justify-content:center;color:#fff;font-size:var(--font-sm);cursor:pointer;}
|
||||
.sidebar{position:fixed;top:56px;left:0;bottom:0;width:240px;background:#001529;overflow-y:auto;z-index:90;padding-top:8px;}
|
||||
.sidebar-menu__title{color:rgba(255,255,255,0.35);font-size:var(--font-xs);padding:16px 24px 8px;text-transform:uppercase;letter-spacing:.5px;}
|
||||
.sidebar-item{display:flex;align-items:center;gap:8px;padding:10px 24px;color:rgba(255,255,255,0.65);font-size:var(--font-sm);cursor:pointer;transition:all .15s;text-decoration:none;}
|
||||
.sidebar-item:hover{color:#fff;background:rgba(255,255,255,0.06);}
|
||||
.sidebar-item.active{color:#fff;background:var(--primary);}
|
||||
.sidebar-subgroup__header{display:flex;align-items:center;gap:6px;padding:10px 24px;color:rgba(255,255,255,0.65);font-size:var(--font-sm);cursor:pointer;transition:all .15s;user-select:none;}
|
||||
.sidebar-subgroup__header:hover{color:rgba(255,255,255,0.85);background:rgba(255,255,255,0.04);}
|
||||
.sidebar-subgroup__header .arrow{width:10px;height:10px;transition:transform .2s;flex-shrink:0;}
|
||||
.sidebar-subgroup__header .arrow path{stroke:rgba(255,255,255,0.45);}
|
||||
.sidebar-subgroup.open>.sidebar-subgroup__header{color:rgba(255,255,255,0.85);}
|
||||
.sidebar-subgroup.open>.sidebar-subgroup__header .arrow{transform:rotate(90deg);}
|
||||
.sidebar-subgroup__body{display:none;padding-left:16px;}
|
||||
.sidebar-subgroup.open>.sidebar-subgroup__body{display:block;}
|
||||
.sidebar-subgroup__body .sidebar-item{padding-left:36px;font-size:12px;}
|
||||
.sidebar-subgroup .sidebar-subgroup{padding-left:12px;}
|
||||
.sidebar-subgroup .sidebar-subgroup .sidebar-item{padding-left:40px;}
|
||||
.sidebar-subgroup .sidebar-subgroup>.sidebar-subgroup__header{font-size:12px;}
|
||||
.main{margin-left:240px;margin-top:56px;padding:24px;min-height:calc(100vh - 56px);}
|
||||
.filter-bar{background:#fff;border-radius:var(--radius-md);padding:20px 24px;margin-bottom:16px;box-shadow:var(--shadow-sm);display:flex;align-items:center;gap:16px;flex-wrap:wrap;}
|
||||
.filter-item{display:flex;align-items:center;gap:8px;}
|
||||
.filter-item label{font-size:var(--font-sm);color:var(--text-secondary);white-space:nowrap;}
|
||||
.filter-input{height:36px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 12px;font-size:var(--font-sm);color:var(--text-primary);outline:none;background:#fff;min-width:170px;}
|
||||
.filter-input:focus{border-color:var(--primary);}
|
||||
.filter-input::placeholder{color:var(--text-placeholder);}
|
||||
.filter-select{height:36px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 28px 0 12px;font-size:var(--font-sm);color:var(--text-primary);outline:none;background:#fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%23999'/%3E%3C/svg%3E") no-repeat right 10px center;appearance:none;cursor:pointer;min-width:140px;}
|
||||
.filter-select:focus{border-color:var(--primary);}
|
||||
.filter-select.placeholder{color:var(--text-placeholder);}
|
||||
.btn{height:36px;padding:0 16px;border-radius:var(--radius-sm);font-size:var(--font-sm);cursor:pointer;border:none;transition:all .2s;display:inline-flex;align-items:center;gap:6px;}
|
||||
.btn-primary{background:var(--primary);color:#fff;}.btn-primary:hover{background:#40a9ff;}
|
||||
.btn-default{background:#fff;color:var(--text-primary);border:1px solid var(--border);}.btn-default:hover{color:var(--primary);border-color:var(--primary);}
|
||||
.table-card{background:#fff;border-radius:var(--radius-md);box-shadow:var(--shadow-sm);overflow:hidden;}
|
||||
.table-card__content{overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch;}
|
||||
.table-card__content table{min-width:100%;white-space:nowrap;}
|
||||
table{width:100%;border-collapse:collapse;}
|
||||
thead th{background:#FAFAFA;padding:12px 16px;text-align:center;font-size:var(--font-sm);color:var(--text-secondary);font-weight:500;border-bottom:1px solid var(--border);white-space:nowrap;}
|
||||
tbody td{padding:14px 16px;font-size:var(--font-sm);color:var(--text-primary);border-bottom:1px solid var(--border);white-space:nowrap;text-align:center;}
|
||||
tbody tr:last-child td{border-bottom:none;}
|
||||
tbody tr:hover{background:#F8FBFF;}
|
||||
#classTable thead th:last-child{position:sticky;right:0;background:#FAFAFA;border-left:1px solid var(--border);}
|
||||
#classTable tbody td:last-child{position:sticky;right:0;background:#fff;border-left:1px solid var(--border);}
|
||||
#classTable tbody tr:hover td:last-child{background:#F8FBFF;}
|
||||
.link{color:var(--primary);cursor:pointer;font-size:var(--font-sm);}.link:hover{color:#40a9ff;}
|
||||
.link-danger{color:var(--danger);cursor:pointer;font-size:var(--font-sm);}.link-danger:hover{color:#ff7875;}
|
||||
.empty-tip{padding:48px 0;text-align:center;font-size:var(--font-sm);color:var(--text-placeholder);}
|
||||
.muted{color:var(--text-placeholder);}
|
||||
.tag{display:inline-flex;align-items:center;padding:2px 10px;border-radius:10px;font-size:var(--font-xs);}
|
||||
.tag-blue{background:#E6F7FF;color:#1890FF;}
|
||||
.tag-green{background:#F6FFED;color:#52C41A;}
|
||||
.tag-orange{background:#FFF7E6;color:#FA8C16;}
|
||||
.tag-red{background:#FFF1F0;color:#FF4D4F;}
|
||||
.tag-gray{background:#FAFAFA;color:#999;}
|
||||
.pagination{display:flex;align-items:center;justify-content:flex-end;padding:16px 24px;gap:8px;border-top:1px solid var(--border);flex-wrap:wrap;}
|
||||
.pagination span{font-size:var(--font-sm);color:var(--text-secondary);}
|
||||
.page-btn{width:32px;height:32px;border:1px solid var(--border);border-radius:var(--radius-sm);background:#fff;cursor:pointer;font-size:var(--font-sm);display:inline-flex;align-items:center;justify-content:center;transition:all .2s;color:var(--text-primary);}
|
||||
.page-btn:hover:not(:disabled),.page-btn.active{background:var(--primary);color:#fff;border-color:var(--primary);}
|
||||
.page-btn:disabled{color:var(--text-placeholder);cursor:not-allowed;background:#FAFAFA;}
|
||||
.page-ellipsis{width:24px;text-align:center;color:var(--text-placeholder);font-size:var(--font-sm);}
|
||||
.page-size{height:32px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 24px 0 10px;font-size:var(--font-sm);color:var(--text-primary);background:#fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%23999'/%3E%3C/svg%3E") no-repeat right 8px center;appearance:none;cursor:pointer;outline:none;}
|
||||
.page-jump input{width:48px;height:32px;border:1px solid var(--border);border-radius:var(--radius-sm);text-align:center;font-size:var(--font-sm);outline:none;margin:0 4px;}
|
||||
.page-jump input:focus{border-color:var(--primary);}
|
||||
.modal-mask{display:none;position:fixed;inset:0;background:rgba(0,0,0,0.45);z-index:200;overflow-y:auto;}
|
||||
.modal-mask.open{display:flex;align-items:flex-start;justify-content:center;padding:60px 24px;}
|
||||
.modal{width:640px;max-width:100%;background:#fff;border-radius:var(--radius-md);box-shadow:var(--shadow-md);display:flex;flex-direction:column;max-height:calc(100vh - 120px);}
|
||||
.modal__header{display:flex;align-items:center;gap:12px;padding:16px 20px;border-bottom:1px solid var(--border);flex-shrink:0;}
|
||||
.modal__close{cursor:pointer;color:var(--text-secondary);display:flex;align-items:center;transition:color .2s;}
|
||||
.modal__close:hover{color:var(--danger);}
|
||||
.modal__title{font-size:var(--font-base);font-weight:600;}
|
||||
.modal__body{padding:20px;overflow-y:auto;}
|
||||
.modal__footer{display:flex;justify-content:flex-end;gap:12px;padding:14px 20px;border-top:1px solid var(--border);flex-shrink:0;}
|
||||
.form-item{margin-bottom:16px;}
|
||||
.form-item:last-child{margin-bottom:0;}
|
||||
.form-label{font-size:var(--font-sm);color:var(--text-secondary);margin-bottom:6px;display:flex;align-items:center;gap:4px;font-weight:500;}
|
||||
.form-label .required{color:var(--danger);}
|
||||
.form-input{width:100%;height:36px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 12px;font-size:var(--font-sm);color:var(--text-primary);outline:none;background:#fff;}
|
||||
.form-input:focus{border-color:var(--primary);box-shadow:0 0 0 2px rgba(24,144,255,0.2);}
|
||||
.form-input::placeholder{color:var(--text-placeholder);}
|
||||
.form-select{width:100%;height:36px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 28px 0 12px;font-size:var(--font-sm);color:var(--text-primary);outline:none;background:#fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%23999'/%3E%3C/svg%3E") no-repeat right 10px center;appearance:none;cursor:pointer;}
|
||||
.form-select:focus{border-color:var(--primary);}
|
||||
.form-textarea{width:100%;border:1px solid var(--border);border-radius:var(--radius-sm);padding:8px 12px;font-size:var(--font-sm);color:var(--text-primary);outline:none;background:#fff;resize:vertical;min-height:72px;font-family:inherit;}
|
||||
.form-textarea:focus{border-color:var(--primary);box-shadow:0 0 0 2px rgba(24,144,255,0.2);}
|
||||
.detail-table{width:100%;border-collapse:collapse;border:1px solid var(--border);}
|
||||
.detail-table th,.detail-table td{border-bottom:1px solid var(--border);text-align:left;padding:12px 16px;font-size:var(--font-sm);}
|
||||
.detail-table tr:last-child td{border-bottom:none;}
|
||||
.detail-table th{width:130px;background:#FAFAFA;color:var(--text-secondary);font-weight:500;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="top-bar">
|
||||
<div class="top-bar__logo">
|
||||
<svg viewBox="0 0 28 28" fill="none"><rect width="28" height="28" rx="6" fill="#1890FF"/><path d="M7 14h14M14 7v14" stroke="#fff" stroke-width="2.5" stroke-linecap="round"/></svg>
|
||||
健康体检
|
||||
</div>
|
||||
<nav class="top-bar__nav">
|
||||
<a href="archive-personal.html">档案</a>
|
||||
<a href="config-material-notice.html">基础配置</a>
|
||||
<a href="pre-hospital-scope.html">检前</a>
|
||||
<a href="mid-appointment-track.html">检中</a>
|
||||
<a href="post-unit-count.html" class="active">检后</a>
|
||||
<a href="exception-dirty.html">异常事件</a>
|
||||
</nav>
|
||||
<div class="top-bar__right">
|
||||
<a class="btn-back" href="../../index.html">
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M10 3L5 8l5 5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
|
||||
返回首页
|
||||
</a>
|
||||
<div class="avatar">管</div>
|
||||
<span style="color:rgba(255,255,255,0.65);">系统管理员 ▾</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<aside class="sidebar">
|
||||
<div class="sidebar-menu__title">检后</div>
|
||||
<div class="sidebar-subgroup">
|
||||
<div class="sidebar-subgroup__header" onclick="toggleSubgroup(this)">
|
||||
<svg class="arrow" viewBox="0 0 12 12"><path d="M4 2l4 4-4 4" fill="none" stroke-width="1.5" stroke-linecap="round"/></svg>
|
||||
常规体检
|
||||
</div>
|
||||
<div class="sidebar-subgroup__body">
|
||||
<a href="post-report-employee.html" class="sidebar-item">常规体检报告</a>
|
||||
<a href="post-employee-master.html" class="sidebar-item">员工体检大表</a>
|
||||
<a href="post-illness-personnel.html" class="sidebar-item">大病人员信息</a>
|
||||
<a href="post-indicator-notify.html" class="sidebar-item">指标异常通知</a>
|
||||
<a href="post-report-unmatched.html" class="sidebar-item">体检报告未匹配项目</a>
|
||||
<div class="sidebar-subgroup">
|
||||
<div class="sidebar-subgroup__header" onclick="toggleSubgroup(this)">
|
||||
<svg class="arrow" viewBox="0 0 12 12"><path d="M4 2l4 4-4 4" fill="none" stroke-width="1.5" stroke-linecap="round"/></svg>
|
||||
体检统计汇总
|
||||
</div>
|
||||
<div class="sidebar-subgroup__body">
|
||||
<a href="post-unit-count.html" class="sidebar-item">单位体检人数统计</a>
|
||||
<a href="post-unit-cost-stat.html" class="sidebar-item">单位体检费用统计</a>
|
||||
<a href="post-hospital-count.html" class="sidebar-item">医院体检人数统计</a>
|
||||
<a href="post-doctor-count.html" class="sidebar-item">医生检查人数统计</a>
|
||||
<a href="post-item-stat.html" class="sidebar-item">医院体检项目统计</a>
|
||||
<a href="post-cancer-screening.html" class="sidebar-item">防癌筛查人数统计</a>
|
||||
<a href="post-standard-stat.html" class="sidebar-item">系统标准化项目统计</a>
|
||||
<a href="post-contracted-hospital.html" class="sidebar-item">签约医院人数统计</a>
|
||||
<a href="post-key-indicator-stat.html" class="sidebar-item">重点指标异常统计</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sidebar-subgroup">
|
||||
<div class="sidebar-subgroup__header" onclick="toggleSubgroup(this)">
|
||||
<svg class="arrow" viewBox="0 0 12 12"><path d="M4 2l4 4-4 4" fill="none" stroke-width="1.5" stroke-linecap="round"/></svg>
|
||||
病种信息管理
|
||||
</div>
|
||||
<div class="sidebar-subgroup__body">
|
||||
<a href="post-disease-info.html" class="sidebar-item">病种信息配置</a>
|
||||
<a href="post-conclusion-disease.html" class="sidebar-item">体检结论关联病种</a>
|
||||
<a href="post-auto-select-disease.html" class="sidebar-item">员工病种信息</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sidebar-subgroup">
|
||||
<div class="sidebar-subgroup__header" onclick="toggleSubgroup(this)">
|
||||
<svg class="arrow" viewBox="0 0 12 12"><path d="M4 2l4 4-4 4" fill="none" stroke-width="1.5" stroke-linecap="round"/></svg>
|
||||
胃肠镜体检
|
||||
</div>
|
||||
<div class="sidebar-subgroup__body">
|
||||
<a href="post-report-gastro.html" class="sidebar-item">胃肠镜体检报告</a>
|
||||
<a href="post-gastro-stat.html" class="sidebar-item">胃肠镜体检统计</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sidebar-subgroup">
|
||||
<div class="sidebar-subgroup__header" onclick="toggleSubgroup(this)">
|
||||
<svg class="arrow" viewBox="0 0 12 12"><path d="M4 2l4 4-4 4" fill="none" stroke-width="1.5" stroke-linecap="round"/></svg>
|
||||
冠脉CTA体检
|
||||
</div>
|
||||
<div class="sidebar-subgroup__body">
|
||||
<a href="post-cta-report.html" class="sidebar-item">冠脉CTA体检报告</a>
|
||||
<a href="post-cta-stat.html" class="sidebar-item">冠脉CTA体检统计</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sidebar-subgroup">
|
||||
<div class="sidebar-subgroup__header" onclick="toggleSubgroup(this)">
|
||||
<svg class="arrow" viewBox="0 0 12 12"><path d="M4 2l4 4-4 4" fill="none" stroke-width="1.5" stroke-linecap="round"/></svg>
|
||||
体检影像管理
|
||||
</div>
|
||||
<div class="sidebar-subgroup__body">
|
||||
<a href="post-imc-user.html" class="sidebar-item">用户体检信息</a>
|
||||
<a href="post-imc-class.html" class="sidebar-item active">用户影像文件分类</a>
|
||||
<a href="post-imc-info.html" class="sidebar-item">用户影像文件详细</a>
|
||||
<a href="post-imc-log.html" class="sidebar-item">文件处理日志</a>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<main class="main">
|
||||
<div class="filter-bar">
|
||||
<div class="filter-item">
|
||||
<label>影像分类:</label>
|
||||
<select class="filter-select placeholder" id="f-imgclass" onchange="this.classList.toggle('placeholder',!this.value)">
|
||||
<option value="">请选择影像分类</option>
|
||||
<option value="超声">超声</option>
|
||||
<option value="CT">CT</option>
|
||||
<option value="MRI">MRI</option>
|
||||
<option value="X射线">X射线</option>
|
||||
<option value="心电">心电</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label>检查项目名称:</label>
|
||||
<input class="filter-input" type="text" id="f-name" placeholder="请输入检查项目名称" style="min-width:180px;">
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label>处理状态:</label>
|
||||
<select class="filter-select placeholder" id="f-status" onchange="this.classList.toggle('placeholder',!this.value)">
|
||||
<option value="">请选择处理状态</option>
|
||||
<option value="1">新建</option>
|
||||
<option value="2">待解析</option>
|
||||
<option value="4">解析中</option>
|
||||
<option value="5">成功</option>
|
||||
<option value="6">失败待重试</option>
|
||||
<option value="3">失败</option>
|
||||
<option value="7">最终失败</option>
|
||||
</select>
|
||||
</div>
|
||||
<div style="margin-left:auto;display:flex;gap:12px;">
|
||||
<button class="btn btn-primary" onclick="doQuery()">
|
||||
<svg width="14" height="14" viewBox="0 0 14 14" fill="none"><circle cx="6" cy="6" r="4.5" stroke="#fff" stroke-width="1.4"/><path d="M9.5 9.5l3 3" stroke="#fff" stroke-width="1.4" stroke-linecap="round"/></svg>
|
||||
查询
|
||||
</button>
|
||||
<button class="btn btn-default" onclick="doReset()">
|
||||
<svg width="14" height="14" viewBox="0 0 14 14" fill="none"><path d="M12 7a5 5 0 1 1-1.5-3.6M12 1.5V4h-2.5" stroke="#666" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||
重置
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="display:flex;gap:12px;margin-bottom:16px;align-items:center;">
|
||||
<button class="btn btn-primary" onclick="openForm(null)">
|
||||
<svg width="14" height="14" viewBox="0 0 14 14" fill="none"><path d="M7 2v10M2 7h10" stroke="#fff" stroke-width="1.6" stroke-linecap="round"/></svg>
|
||||
新增
|
||||
</button>
|
||||
<button class="btn btn-default" onclick="exportList()">
|
||||
<svg width="14" height="14" viewBox="0 0 14 14" fill="none"><path d="M7 2v7M4 6l3 3 3-3M2 12.5h10" stroke="#666" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||
导出
|
||||
</button>
|
||||
<button class="btn btn-default" onclick="importList()">
|
||||
<svg width="14" height="14" viewBox="0 0 14 14" fill="none"><path d="M7 9V2M4 5l3-3 3 3M2 12.5h10" stroke="#666" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||
导入
|
||||
</button>
|
||||
<button class="btn btn-default" onclick="batchDelete()" style="margin-left:auto;">
|
||||
<svg width="14" height="14" viewBox="0 0 14 14" fill="none"><path d="M2 3.5h10M5.5 3.5V2h3v1.5M3.5 3.5l.7 8.5h5.6l.7-8.5" stroke="#666" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||
批量删除
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="table-card">
|
||||
<div class="table-card__content">
|
||||
<table id="classTable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width:48px;"><input type="checkbox" id="checkAll" onclick="toggleCheckAll(this)"></th>
|
||||
<th style="width:56px;">序号</th>
|
||||
<th>影像分类</th>
|
||||
<th>检查项目名称</th>
|
||||
<th>影像文件类型</th>
|
||||
<th>报告文件类型</th>
|
||||
<th>处理状态</th>
|
||||
<th>检查结果</th>
|
||||
<th>错误信息</th>
|
||||
<th>出报告时间</th>
|
||||
<th>创建日期</th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="tbody"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="pagination" id="pagination"></div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<div class="modal-mask" id="formMask" onclick="if(event.target===this)closeForm()">
|
||||
<div class="modal">
|
||||
<div class="modal__header">
|
||||
<span class="modal__close" onclick="closeForm()">
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M3.5 3.5l9 9M12.5 3.5l-9 9" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"/></svg>
|
||||
</span>
|
||||
<span class="modal__title" id="formTitle">新增用户影像文件分类</span>
|
||||
</div>
|
||||
<div class="modal__body">
|
||||
<div class="form-item">
|
||||
<div class="form-label">用户体检信息ID</div>
|
||||
<input class="form-input" id="formMuid" type="text" placeholder="请输入用户体检信息ID">
|
||||
</div>
|
||||
<div class="form-item">
|
||||
<div class="form-label"><span class="required">*</span> 影像分类</div>
|
||||
<select class="form-select" id="formImgclass">
|
||||
<option value="超声">超声</option>
|
||||
<option value="CT">CT</option>
|
||||
<option value="MRI">MRI</option>
|
||||
<option value="X射线">X射线</option>
|
||||
<option value="心电">心电</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-item">
|
||||
<div class="form-label"><span class="required">*</span> 检查项目名称</div>
|
||||
<input class="form-input" id="formName" type="text" placeholder="请输入检查项目名称">
|
||||
</div>
|
||||
<div class="form-item">
|
||||
<div class="form-label">影像文件类型</div>
|
||||
<select class="form-select" id="formImgtype">
|
||||
<option value="非DICOM">非DICOM</option>
|
||||
<option value="dic">dic</option>
|
||||
<option value="dcm">dcm</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-item">
|
||||
<div class="form-label">报告文件类型</div>
|
||||
<select class="form-select" id="formReptype">
|
||||
<option value="png">png</option>
|
||||
<option value="jpg">jpg</option>
|
||||
<option value="pdf">pdf</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-item">
|
||||
<div class="form-label">处理状态</div>
|
||||
<select class="form-select" id="formStatus">
|
||||
<option value="1">新建</option>
|
||||
<option value="2">待解析</option>
|
||||
<option value="3">失败</option>
|
||||
<option value="4">解析中</option>
|
||||
<option value="5">成功</option>
|
||||
<option value="6">失败待重试</option>
|
||||
<option value="7">最终失败</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-item">
|
||||
<div class="form-label">检查结果</div>
|
||||
<textarea class="form-textarea" id="formContent" placeholder="请输入检查结果"></textarea>
|
||||
</div>
|
||||
<div class="form-item">
|
||||
<div class="form-label">错误信息</div>
|
||||
<textarea class="form-textarea" id="formMsg" placeholder="请输入错误信息"></textarea>
|
||||
</div>
|
||||
<div class="form-item">
|
||||
<div class="form-label">出报告时间</div>
|
||||
<input class="form-input" id="formReportdate" type="text" placeholder="如 2026-08-15 12:00:00">
|
||||
</div>
|
||||
<div class="form-item">
|
||||
<div class="form-label">创建日期</div>
|
||||
<input class="form-input" id="formCreatetime" type="text" placeholder="如 2026-08-15 11:30:00">
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal__footer">
|
||||
<button class="btn btn-default" onclick="closeForm()">取消</button>
|
||||
<button class="btn btn-primary" onclick="saveForm()">保存</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal-mask" id="detailMask" onclick="if(event.target===this)closeDetail()">
|
||||
<div class="modal">
|
||||
<div class="modal__header">
|
||||
<span class="modal__close" onclick="closeDetail()">
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M3.5 3.5l9 9M12.5 3.5l-9 9" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"/></svg>
|
||||
</span>
|
||||
<span class="modal__title">用户影像文件分类详情</span>
|
||||
</div>
|
||||
<div class="modal__body" id="detailBody"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var handleStatusMap={1:'新建',2:'待解析',3:'失败',4:'解析中',5:'成功',6:'失败待重试',7:'最终失败'};
|
||||
function statusTag(s){
|
||||
var cls='tag-gray';
|
||||
if(s===5)cls='tag-green';
|
||||
else if(s===4||s===6)cls='tag-orange';
|
||||
else if(s===3||s===7)cls='tag-red';
|
||||
else if(s===1)cls='tag-blue';
|
||||
return '<span class="tag '+cls+'">'+handleStatusMap[s]+'</span>';
|
||||
}
|
||||
var rows=[
|
||||
{imgClass:'CT',name:'胸部CT平扫',imgType:'dcm',repType:'pdf',status:5,content:'双肺纹理清晰,未见明显异常密度影,纵隔及肺门未见肿大淋巴结。',msg:'',reportDate:'2026-08-15 12:00:00',createTime:'2026-08-15 11:30:00',muId:'MU1001'},
|
||||
{imgClass:'MRI',name:'头颅MRI平扫',imgType:'dcm',repType:'pdf',status:5,content:'颅脑平扫未见明显异常信号影,脑室系统形态正常。',msg:'',reportDate:'2026-08-15 13:10:00',createTime:'2026-08-15 12:30:00',muId:'MU1001'},
|
||||
{imgClass:'超声',name:'腹部超声',imgType:'非DICOM',repType:'png',status:4,content:'',msg:'',reportDate:'',createTime:'2026-08-15 14:00:00',muId:'MU1001'},
|
||||
{imgClass:'CT',name:'胸部CT平扫',imgType:'dcm',repType:'pdf',status:5,content:'双肺纹理清晰,右肺上叶见微小结节影,建议随访。',msg:'',reportDate:'2026-08-15 15:20:00',createTime:'2026-08-15 14:50:00',muId:'MU1002'},
|
||||
{imgClass:'心电',name:'心电图',imgType:'非DICOM',repType:'jpg',status:5,content:'窦性心律,正常心电图。',msg:'',reportDate:'2026-08-15 15:40:00',createTime:'2026-08-15 15:10:00',muId:'MU1002'},
|
||||
{imgClass:'X射线',name:'胸部X射线',imgType:'dcm',repType:'jpg',status:7,content:'',msg:'DICOM标签解析失败:缺少 PatientID 标签',reportDate:'',createTime:'2026-08-15 16:00:00',muId:'MU1003'},
|
||||
{imgClass:'超声',name:'腹部超声',imgType:'非DICOM',repType:'png',status:6,content:'',msg:'文件服务器上传超时,等待重试',reportDate:'',createTime:'2026-08-15 16:20:00',muId:'MU1003'},
|
||||
{imgClass:'CT',name:'冠脉CTA',imgType:'dcm',repType:'pdf',status:2,content:'',msg:'',reportDate:'',createTime:'2026-08-16 09:12:00',muId:'MU1004'},
|
||||
{imgClass:'CT',name:'胸部CT平扫',imgType:'dcm',repType:'pdf',status:5,content:'双肺纹理清晰,未见明显异常。',msg:'',reportDate:'2025-08-20 16:00:00',createTime:'2025-08-20 15:30:00',muId:'MU1018'},
|
||||
{imgClass:'MRI',name:'头颅MRI平扫',imgType:'dcm',repType:'pdf',status:5,content:'颅脑平扫未见明显异常。',msg:'',reportDate:'2025-08-20 16:30:00',createTime:'2025-08-20 16:00:00',muId:'MU1018'},
|
||||
{imgClass:'超声',name:'腹部超声',imgType:'非DICOM',repType:'png',status:5,content:'肝胆胰脾肾未见明显异常。',msg:'',reportDate:'2025-08-21 10:00:00',createTime:'2025-08-21 09:30:00',muId:'MU1021'},
|
||||
{imgClass:'超声',name:'腹部超声',imgType:'非DICOM',repType:'png',status:7,content:'',msg:'报告文件格式与声明类型不一致',reportDate:'',createTime:'2025-08-21 11:00:00',muId:'MU1021'}
|
||||
];
|
||||
var state={imgclass:'',name:'',status:'',page:1,pageSize:10};
|
||||
|
||||
function doQuery(){
|
||||
state.imgclass=document.getElementById('f-imgclass').value;
|
||||
state.name=document.getElementById('f-name').value.trim();
|
||||
state.status=document.getElementById('f-status').value;
|
||||
state.page=1;
|
||||
renderTable();
|
||||
}
|
||||
function doReset(){
|
||||
var ic=document.getElementById('f-imgclass');ic.value='';ic.classList.add('placeholder');
|
||||
document.getElementById('f-name').value='';
|
||||
var st=document.getElementById('f-status');st.value='';st.classList.add('placeholder');
|
||||
state.imgclass='';state.name='';state.status='';
|
||||
state.page=1;
|
||||
renderTable();
|
||||
}
|
||||
|
||||
function filteredRows(){
|
||||
return rows.filter(function(r){
|
||||
if(state.imgclass&&r.imgClass!==state.imgclass)return false;
|
||||
if(state.name&&r.name.indexOf(state.name)===-1)return false;
|
||||
if(state.status&&String(r.status)!==state.status)return false;
|
||||
return true;
|
||||
});
|
||||
}
|
||||
function renderTable(){
|
||||
var list=filteredRows();
|
||||
var totalPages=Math.max(1,Math.ceil(list.length/state.pageSize));
|
||||
if(state.page>totalPages)state.page=totalPages;
|
||||
var start=(state.page-1)*state.pageSize;
|
||||
var pageRows=list.slice(start,start+state.pageSize);
|
||||
var tbody=document.getElementById('tbody');
|
||||
tbody.innerHTML=pageRows.length?pageRows.map(function(r,pos){
|
||||
var idx=rows.indexOf(r);
|
||||
var content=r.content?r.content:'<span class="muted">—</span>';
|
||||
if(r.content&&r.content.length>18)content='<span title="'+r.content+'">'+r.content.slice(0,18)+'…</span>';
|
||||
var msg=r.msg?r.msg:'<span class="muted">—</span>';
|
||||
if(r.msg&&r.msg.length>18)msg='<span title="'+r.msg+'">'+r.msg.slice(0,18)+'…</span>';
|
||||
return '<tr>'
|
||||
+'<td><input type="checkbox" class="row-check" data-idx="'+idx+'"></td>'
|
||||
+'<td>'+(start+pos+1)+'</td>'
|
||||
+'<td>'+r.imgClass+'</td><td>'+r.name+'</td><td>'+r.imgType+'</td><td>'+r.repType+'</td>'
|
||||
+'<td>'+statusTag(r.status)+'</td><td style="text-align:left;">'+content+'</td><td style="text-align:left;">'+msg+'</td>'
|
||||
+'<td>'+(r.reportDate||'<span class="muted">—</span>')+'</td><td>'+r.createTime+'</td>'
|
||||
+'<td><span class="link" onclick="openForm('+idx+')">编辑</span> <span class="link" style="margin-left:8px;" onclick="openDetail('+idx+')">详情</span> <span class="link-danger" style="margin-left:8px;" onclick="deleteRow('+idx+')">删除</span></td>'
|
||||
+'</tr>';
|
||||
}).join(''):'<tr><td colspan="12"><div class="empty-tip">暂无数据</div></td></tr>';
|
||||
var all=tbody.querySelectorAll('.row-check');
|
||||
var checked=tbody.querySelectorAll('.row-check:checked');
|
||||
document.getElementById('checkAll').checked=all.length>0&&all.length===checked.length;
|
||||
renderPagination(list.length,totalPages);
|
||||
}
|
||||
|
||||
function pageSeq(p,last){
|
||||
var seq=[];
|
||||
if(last<=7){for(var i=1;i<=last;i++)seq.push(i);return seq;}
|
||||
if(p<=4){seq=[1,2,3,4,5,'...',last];}
|
||||
else if(p>=last-3){seq=[1,'...',last-4,last-3,last-2,last-1,last];}
|
||||
else{seq=[1,'...',p-1,p,p+1,'...',last];}
|
||||
return seq;
|
||||
}
|
||||
function renderPagination(total,totalPages){
|
||||
var html='<span>共 '+total+' 条数据</span>';
|
||||
if(totalPages>1){
|
||||
html+='<button class="page-btn"'+(state.page===1?' disabled':'')+' onclick="goPage('+(state.page-1)+')"><</button>';
|
||||
pageSeq(state.page,totalPages).forEach(function(p){
|
||||
if(p==='...')html+='<span class="page-ellipsis">...</span>';
|
||||
else html+='<button class="page-btn'+(p===state.page?' active':'')+'" onclick="goPage('+p+')">'+p+'</button>';
|
||||
});
|
||||
html+='<button class="page-btn"'+(state.page===totalPages?' disabled':'')+' onclick="goPage('+(state.page+1)+')">></button>';
|
||||
}
|
||||
html+='<select class="page-size" onchange="changeSize(this.value)">'
|
||||
+[10,20,50].map(function(n){return '<option value="'+n+'"'+(n===state.pageSize?' selected':'')+'>'+n+'条/页</option>';}).join('')
|
||||
+'</select>';
|
||||
html+='<span class="page-jump">跳至<input type="number" id="jumpInput" min="1" value="'+state.page+'" onkeydown="if(event.key===\'Enter\')jumpTo('+totalPages+')">页<button class="page-btn" onclick="jumpTo('+totalPages+')">跳</button></span>';
|
||||
document.getElementById('pagination').innerHTML=html;
|
||||
}
|
||||
function goPage(p){state.page=p;renderTable();}
|
||||
function changeSize(v){state.pageSize=parseInt(v,10);state.page=1;renderTable();}
|
||||
function jumpTo(totalPages){
|
||||
var input=document.getElementById('jumpInput');
|
||||
var p=parseInt(input.value,10);
|
||||
if(isNaN(p)||p<1)p=1;
|
||||
if(p>totalPages)p=totalPages;
|
||||
state.page=p;
|
||||
renderTable();
|
||||
}
|
||||
|
||||
function toggleCheckAll(cb){
|
||||
document.querySelectorAll('.row-check').forEach(function(c){c.checked=cb.checked;});
|
||||
}
|
||||
function checkedIdx(){
|
||||
var arr=[];
|
||||
document.querySelectorAll('.row-check:checked').forEach(function(c){arr.push(parseInt(c.dataset.idx,10));});
|
||||
return arr;
|
||||
}
|
||||
function batchDelete(){
|
||||
var idxs=checkedIdx();
|
||||
if(!idxs.length){alert('请先勾选要删除的记录');return;}
|
||||
if(!confirm('确认删除选中的 '+idxs.length+' 条记录?'))return;
|
||||
idxs.sort(function(a,b){return b-a;}).forEach(function(i){rows.splice(i,1);});
|
||||
renderTable();
|
||||
}
|
||||
function deleteRow(idx){
|
||||
if(!confirm('确认删除该影像文件分类记录?'))return;
|
||||
rows.splice(idx,1);
|
||||
renderTable();
|
||||
}
|
||||
function exportList(){alert('导出当前筛选结果(Excel)');}
|
||||
function importList(){alert('导入影像文件分类数据(Excel)');}
|
||||
|
||||
var editingIdx=null;
|
||||
function openForm(idx){
|
||||
editingIdx=idx;
|
||||
document.getElementById('formTitle').textContent=idx===null?'新增用户影像文件分类':'编辑用户影像文件分类';
|
||||
if(idx===null){
|
||||
document.getElementById('formMuid').value='';
|
||||
document.getElementById('formImgclass').value='超声';
|
||||
document.getElementById('formName').value='';
|
||||
document.getElementById('formImgtype').value='dcm';
|
||||
document.getElementById('formReptype').value='pdf';
|
||||
document.getElementById('formStatus').value='1';
|
||||
document.getElementById('formContent').value='';
|
||||
document.getElementById('formMsg').value='';
|
||||
document.getElementById('formReportdate').value='';
|
||||
document.getElementById('formCreatetime').value='';
|
||||
}else{
|
||||
var r=rows[idx];
|
||||
document.getElementById('formMuid').value=r.muId;
|
||||
document.getElementById('formImgclass').value=r.imgClass;
|
||||
document.getElementById('formName').value=r.name;
|
||||
document.getElementById('formImgtype').value=r.imgType;
|
||||
document.getElementById('formReptype').value=r.repType;
|
||||
document.getElementById('formStatus').value=String(r.status);
|
||||
document.getElementById('formContent').value=r.content;
|
||||
document.getElementById('formMsg').value=r.msg;
|
||||
document.getElementById('formReportdate').value=r.reportDate;
|
||||
document.getElementById('formCreatetime').value=r.createTime;
|
||||
}
|
||||
document.getElementById('formMask').classList.add('open');
|
||||
}
|
||||
function closeForm(){document.getElementById('formMask').classList.remove('open');}
|
||||
function saveForm(){
|
||||
var name=document.getElementById('formName').value.trim();
|
||||
if(!name){alert('请输入检查项目名称');return;}
|
||||
var data={
|
||||
imgClass:document.getElementById('formImgclass').value,
|
||||
name:name,
|
||||
imgType:document.getElementById('formImgtype').value,
|
||||
repType:document.getElementById('formReptype').value,
|
||||
status:parseInt(document.getElementById('formStatus').value,10),
|
||||
content:document.getElementById('formContent').value.trim(),
|
||||
msg:document.getElementById('formMsg').value.trim(),
|
||||
reportDate:document.getElementById('formReportdate').value.trim(),
|
||||
createTime:document.getElementById('formCreatetime').value.trim(),
|
||||
muId:document.getElementById('formMuid').value.trim()
|
||||
};
|
||||
if(editingIdx===null){
|
||||
rows.unshift(data);
|
||||
}else{
|
||||
rows[editingIdx]=data;
|
||||
}
|
||||
closeForm();
|
||||
renderTable();
|
||||
}
|
||||
|
||||
function openDetail(idx){
|
||||
var r=rows[idx];
|
||||
document.getElementById('detailBody').innerHTML=
|
||||
'<table class="detail-table"><tbody>'
|
||||
+'<tr><th>用户体检信息ID</th><td>'+r.muId+'</td></tr>'
|
||||
+'<tr><th>影像分类</th><td>'+r.imgClass+'</td></tr>'
|
||||
+'<tr><th>检查项目名称</th><td>'+r.name+'</td></tr>'
|
||||
+'<tr><th>影像文件类型</th><td>'+r.imgType+'</td></tr>'
|
||||
+'<tr><th>报告文件类型</th><td>'+r.repType+'</td></tr>'
|
||||
+'<tr><th>处理状态</th><td>'+handleStatusMap[r.status]+'</td></tr>'
|
||||
+'<tr><th>检查结果</th><td>'+(r.content||'<span class="muted">—</span>')+'</td></tr>'
|
||||
+'<tr><th>错误信息</th><td>'+(r.msg||'<span class="muted">—</span>')+'</td></tr>'
|
||||
+'<tr><th>出报告时间</th><td>'+(r.reportDate||'<span class="muted">—</span>')+'</td></tr>'
|
||||
+'<tr><th>创建日期</th><td>'+r.createTime+'</td></tr>'
|
||||
+'</tbody></table>';
|
||||
document.getElementById('detailMask').classList.add('open');
|
||||
}
|
||||
function closeDetail(){document.getElementById('detailMask').classList.remove('open');}
|
||||
document.addEventListener('keydown',function(e){
|
||||
if(e.key==='Escape'){closeForm();closeDetail();}
|
||||
});
|
||||
|
||||
function toggleSubgroup(header){
|
||||
header.parentElement.classList.toggle('open');
|
||||
}
|
||||
(function(){
|
||||
renderTable();
|
||||
var active=document.querySelector('.sidebar-item.active');
|
||||
if(!active)return;
|
||||
var sub=active.closest('.sidebar-subgroup');
|
||||
while(sub){ sub.classList.add('open'); sub=sub.parentElement.closest('.sidebar-subgroup'); }
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,580 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>健康体检 - 用户影像文件详细 | 健康CQ原型</title>
|
||||
<style>
|
||||
*{box-sizing:border-box;margin:0;padding:0;}
|
||||
body{font-family:-apple-system,BlinkMacSystemFont,'PingFang SC','Microsoft YaHei',sans-serif;background:#F5F7FA;color:#333;min-width:1280px;}
|
||||
:root{
|
||||
--primary:#1890FF;--primary-light:#E6F7FF;--success:#52C41A;--warning:#FAAD14;--danger:#FF4D4F;
|
||||
--text-primary:#333;--text-secondary:#666;--text-placeholder:#999;--border:#E8E8E8;--background:#F5F7FA;
|
||||
--font-xs:11px;--font-sm:13px;--font-base:15px;--font-lg:17px;--font-xl:20px;--font-xxl:24px;
|
||||
--radius-sm:4px;--radius-md:8px;--radius-lg:12px;
|
||||
--shadow-sm:0 1px 4px rgba(0,0,0,0.08);--shadow-md:0 4px 12px rgba(0,0,0,0.12);
|
||||
}
|
||||
.top-bar{display:flex;align-items:center;height:56px;background:#001529;padding:0 24px;position:fixed;top:0;left:0;right:0;z-index:100;}
|
||||
.top-bar__logo{display:flex;align-items:center;gap:8px;color:#fff;font-size:var(--font-lg);font-weight:600;white-space:nowrap;width:240px;flex-shrink:0;}
|
||||
.top-bar__logo svg{width:28px;height:28px;}
|
||||
.top-bar__nav{display:flex;align-items:center;gap:4px;flex:1;}
|
||||
.top-bar__nav a{color:rgba(255,255,255,0.65);text-decoration:none;padding:6px 16px;border-radius:var(--radius-sm);font-size:var(--font-sm);transition:all .2s;}
|
||||
.top-bar__nav a:hover{color:#fff;background:rgba(255,255,255,0.08);}
|
||||
.top-bar__nav a.active{color:#fff;background:var(--primary);}
|
||||
.top-bar__right{display:flex;align-items:center;gap:16px;color:rgba(255,255,255,0.65);font-size:var(--font-sm);}
|
||||
.top-bar__right .btn-back{color:rgba(255,255,255,0.65);cursor:pointer;display:flex;align-items:center;gap:4px;text-decoration:none;}
|
||||
.top-bar__right .btn-back:hover{color:#fff;}
|
||||
.avatar{width:32px;height:32px;border-radius:50%;background:#1890FF;display:flex;align-items:center;justify-content:center;color:#fff;font-size:var(--font-sm);cursor:pointer;}
|
||||
.sidebar{position:fixed;top:56px;left:0;bottom:0;width:240px;background:#001529;overflow-y:auto;z-index:90;padding-top:8px;}
|
||||
.sidebar-menu__title{color:rgba(255,255,255,0.35);font-size:var(--font-xs);padding:16px 24px 8px;text-transform:uppercase;letter-spacing:.5px;}
|
||||
.sidebar-item{display:flex;align-items:center;gap:8px;padding:10px 24px;color:rgba(255,255,255,0.65);font-size:var(--font-sm);cursor:pointer;transition:all .15s;text-decoration:none;}
|
||||
.sidebar-item:hover{color:#fff;background:rgba(255,255,255,0.06);}
|
||||
.sidebar-item.active{color:#fff;background:var(--primary);}
|
||||
.sidebar-subgroup__header{display:flex;align-items:center;gap:6px;padding:10px 24px;color:rgba(255,255,255,0.65);font-size:var(--font-sm);cursor:pointer;transition:all .15s;user-select:none;}
|
||||
.sidebar-subgroup__header:hover{color:rgba(255,255,255,0.85);background:rgba(255,255,255,0.04);}
|
||||
.sidebar-subgroup__header .arrow{width:10px;height:10px;transition:transform .2s;flex-shrink:0;}
|
||||
.sidebar-subgroup__header .arrow path{stroke:rgba(255,255,255,0.45);}
|
||||
.sidebar-subgroup.open>.sidebar-subgroup__header{color:rgba(255,255,255,0.85);}
|
||||
.sidebar-subgroup.open>.sidebar-subgroup__header .arrow{transform:rotate(90deg);}
|
||||
.sidebar-subgroup__body{display:none;padding-left:16px;}
|
||||
.sidebar-subgroup.open>.sidebar-subgroup__body{display:block;}
|
||||
.sidebar-subgroup__body .sidebar-item{padding-left:36px;font-size:12px;}
|
||||
.sidebar-subgroup .sidebar-subgroup{padding-left:12px;}
|
||||
.sidebar-subgroup .sidebar-subgroup .sidebar-item{padding-left:40px;}
|
||||
.sidebar-subgroup .sidebar-subgroup>.sidebar-subgroup__header{font-size:12px;}
|
||||
.main{margin-left:240px;margin-top:56px;padding:24px;min-height:calc(100vh - 56px);}
|
||||
.filter-bar{background:#fff;border-radius:var(--radius-md);padding:20px 24px;margin-bottom:16px;box-shadow:var(--shadow-sm);display:flex;align-items:center;gap:16px;flex-wrap:wrap;}
|
||||
.filter-item{display:flex;align-items:center;gap:8px;}
|
||||
.filter-item label{font-size:var(--font-sm);color:var(--text-secondary);white-space:nowrap;}
|
||||
.filter-input{height:36px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 12px;font-size:var(--font-sm);color:var(--text-primary);outline:none;background:#fff;min-width:190px;}
|
||||
.filter-input:focus{border-color:var(--primary);}
|
||||
.filter-input::placeholder{color:var(--text-placeholder);}
|
||||
.filter-select{height:36px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 28px 0 12px;font-size:var(--font-sm);color:var(--text-primary);outline:none;background:#fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%23999'/%3E%3C/svg%3E") no-repeat right 10px center;appearance:none;cursor:pointer;min-width:130px;}
|
||||
.filter-select:focus{border-color:var(--primary);}
|
||||
.filter-select.placeholder{color:var(--text-placeholder);}
|
||||
.btn{height:36px;padding:0 16px;border-radius:var(--radius-sm);font-size:var(--font-sm);cursor:pointer;border:none;transition:all .2s;display:inline-flex;align-items:center;gap:6px;}
|
||||
.btn-primary{background:var(--primary);color:#fff;}.btn-primary:hover{background:#40a9ff;}
|
||||
.btn-default{background:#fff;color:var(--text-primary);border:1px solid var(--border);}.btn-default:hover{color:var(--primary);border-color:var(--primary);}
|
||||
.table-card{background:#fff;border-radius:var(--radius-md);box-shadow:var(--shadow-sm);overflow:hidden;}
|
||||
.table-card__content{overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch;}
|
||||
.table-card__content table{min-width:100%;white-space:nowrap;}
|
||||
table{width:100%;border-collapse:collapse;}
|
||||
thead th{background:#FAFAFA;padding:12px 16px;text-align:center;font-size:var(--font-sm);color:var(--text-secondary);font-weight:500;border-bottom:1px solid var(--border);white-space:nowrap;}
|
||||
tbody td{padding:14px 16px;font-size:var(--font-sm);color:var(--text-primary);border-bottom:1px solid var(--border);white-space:nowrap;text-align:center;}
|
||||
tbody tr:last-child td{border-bottom:none;}
|
||||
tbody tr:hover{background:#F8FBFF;}
|
||||
#infoTable thead th:last-child{position:sticky;right:0;background:#FAFAFA;border-left:1px solid var(--border);}
|
||||
#infoTable tbody td:last-child{position:sticky;right:0;background:#fff;border-left:1px solid var(--border);}
|
||||
#infoTable tbody tr:hover td:last-child{background:#F8FBFF;}
|
||||
.link{color:var(--primary);cursor:pointer;font-size:var(--font-sm);}.link:hover{color:#40a9ff;}
|
||||
.link-danger{color:var(--danger);cursor:pointer;font-size:var(--font-sm);}.link-danger:hover{color:#ff7875;}
|
||||
.empty-tip{padding:48px 0;text-align:center;font-size:var(--font-sm);color:var(--text-placeholder);}
|
||||
.muted{color:var(--text-placeholder);}
|
||||
.tag{display:inline-flex;align-items:center;padding:2px 10px;border-radius:10px;font-size:var(--font-xs);}
|
||||
.tag-blue{background:#E6F7FF;color:#1890FF;}
|
||||
.tag-purple{background:#F9F0FF;color:#722ED1;}
|
||||
.pagination{display:flex;align-items:center;justify-content:flex-end;padding:16px 24px;gap:8px;border-top:1px solid var(--border);flex-wrap:wrap;}
|
||||
.pagination span{font-size:var(--font-sm);color:var(--text-secondary);}
|
||||
.page-btn{width:32px;height:32px;border:1px solid var(--border);border-radius:var(--radius-sm);background:#fff;cursor:pointer;font-size:var(--font-sm);display:inline-flex;align-items:center;justify-content:center;transition:all .2s;color:var(--text-primary);}
|
||||
.page-btn:hover:not(:disabled),.page-btn.active{background:var(--primary);color:#fff;border-color:var(--primary);}
|
||||
.page-btn:disabled{color:var(--text-placeholder);cursor:not-allowed;background:#FAFAFA;}
|
||||
.page-ellipsis{width:24px;text-align:center;color:var(--text-placeholder);font-size:var(--font-sm);}
|
||||
.page-size{height:32px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 24px 0 10px;font-size:var(--font-sm);color:var(--text-primary);background:#fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%23999'/%3E%3C/svg%3E") no-repeat right 8px center;appearance:none;cursor:pointer;outline:none;}
|
||||
.page-jump input{width:48px;height:32px;border:1px solid var(--border);border-radius:var(--radius-sm);text-align:center;font-size:var(--font-sm);outline:none;margin:0 4px;}
|
||||
.page-jump input:focus{border-color:var(--primary);}
|
||||
.modal-mask{display:none;position:fixed;inset:0;background:rgba(0,0,0,0.45);z-index:200;overflow-y:auto;}
|
||||
.modal-mask.open{display:flex;align-items:flex-start;justify-content:center;padding:60px 24px;}
|
||||
.modal{width:640px;max-width:100%;background:#fff;border-radius:var(--radius-md);box-shadow:var(--shadow-md);display:flex;flex-direction:column;max-height:calc(100vh - 120px);}
|
||||
.modal__header{display:flex;align-items:center;gap:12px;padding:16px 20px;border-bottom:1px solid var(--border);flex-shrink:0;}
|
||||
.modal__close{cursor:pointer;color:var(--text-secondary);display:flex;align-items:center;transition:color .2s;}
|
||||
.modal__close:hover{color:var(--danger);}
|
||||
.modal__title{font-size:var(--font-base);font-weight:600;}
|
||||
.modal__body{padding:20px;overflow-y:auto;}
|
||||
.modal__footer{display:flex;justify-content:flex-end;gap:12px;padding:14px 20px;border-top:1px solid var(--border);flex-shrink:0;}
|
||||
.form-item{margin-bottom:16px;}
|
||||
.form-item:last-child{margin-bottom:0;}
|
||||
.form-label{font-size:var(--font-sm);color:var(--text-secondary);margin-bottom:6px;display:flex;align-items:center;gap:4px;font-weight:500;}
|
||||
.form-label .required{color:var(--danger);}
|
||||
.form-input{width:100%;height:36px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 12px;font-size:var(--font-sm);color:var(--text-primary);outline:none;background:#fff;}
|
||||
.form-input:focus{border-color:var(--primary);box-shadow:0 0 0 2px rgba(24,144,255,0.2);}
|
||||
.form-input::placeholder{color:var(--text-placeholder);}
|
||||
.form-select{width:100%;height:36px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 28px 0 12px;font-size:var(--font-sm);color:var(--text-primary);outline:none;background:#fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%23999'/%3E%3C/svg%3E") no-repeat right 10px center;appearance:none;cursor:pointer;}
|
||||
.form-select:focus{border-color:var(--primary);}
|
||||
.form-textarea{width:100%;border:1px solid var(--border);border-radius:var(--radius-sm);padding:8px 12px;font-size:var(--font-sm);color:var(--text-primary);outline:none;background:#fff;resize:vertical;min-height:72px;font-family:inherit;}
|
||||
.form-textarea:focus{border-color:var(--primary);box-shadow:0 0 0 2px rgba(24,144,255,0.2);}
|
||||
.detail-table{width:100%;border-collapse:collapse;border:1px solid var(--border);}
|
||||
.detail-table th,.detail-table td{border-bottom:1px solid var(--border);text-align:left;padding:12px 16px;font-size:var(--font-sm);word-break:break-all;}
|
||||
.detail-table tr:last-child td{border-bottom:none;}
|
||||
.detail-table th{width:130px;background:#FAFAFA;color:var(--text-secondary);font-weight:500;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="top-bar">
|
||||
<div class="top-bar__logo">
|
||||
<svg viewBox="0 0 28 28" fill="none"><rect width="28" height="28" rx="6" fill="#1890FF"/><path d="M7 14h14M14 7v14" stroke="#fff" stroke-width="2.5" stroke-linecap="round"/></svg>
|
||||
健康体检
|
||||
</div>
|
||||
<nav class="top-bar__nav">
|
||||
<a href="archive-personal.html">档案</a>
|
||||
<a href="config-material-notice.html">基础配置</a>
|
||||
<a href="pre-hospital-scope.html">检前</a>
|
||||
<a href="mid-appointment-track.html">检中</a>
|
||||
<a href="post-unit-count.html" class="active">检后</a>
|
||||
<a href="exception-dirty.html">异常事件</a>
|
||||
</nav>
|
||||
<div class="top-bar__right">
|
||||
<a class="btn-back" href="../../index.html">
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M10 3L5 8l5 5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
|
||||
返回首页
|
||||
</a>
|
||||
<div class="avatar">管</div>
|
||||
<span style="color:rgba(255,255,255,0.65);">系统管理员 ▾</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<aside class="sidebar">
|
||||
<div class="sidebar-menu__title">检后</div>
|
||||
<div class="sidebar-subgroup">
|
||||
<div class="sidebar-subgroup__header" onclick="toggleSubgroup(this)">
|
||||
<svg class="arrow" viewBox="0 0 12 12"><path d="M4 2l4 4-4 4" fill="none" stroke-width="1.5" stroke-linecap="round"/></svg>
|
||||
常规体检
|
||||
</div>
|
||||
<div class="sidebar-subgroup__body">
|
||||
<a href="post-report-employee.html" class="sidebar-item">常规体检报告</a>
|
||||
<a href="post-employee-master.html" class="sidebar-item">员工体检大表</a>
|
||||
<a href="post-illness-personnel.html" class="sidebar-item">大病人员信息</a>
|
||||
<a href="post-indicator-notify.html" class="sidebar-item">指标异常通知</a>
|
||||
<a href="post-report-unmatched.html" class="sidebar-item">体检报告未匹配项目</a>
|
||||
<div class="sidebar-subgroup">
|
||||
<div class="sidebar-subgroup__header" onclick="toggleSubgroup(this)">
|
||||
<svg class="arrow" viewBox="0 0 12 12"><path d="M4 2l4 4-4 4" fill="none" stroke-width="1.5" stroke-linecap="round"/></svg>
|
||||
体检统计汇总
|
||||
</div>
|
||||
<div class="sidebar-subgroup__body">
|
||||
<a href="post-unit-count.html" class="sidebar-item">单位体检人数统计</a>
|
||||
<a href="post-unit-cost-stat.html" class="sidebar-item">单位体检费用统计</a>
|
||||
<a href="post-hospital-count.html" class="sidebar-item">医院体检人数统计</a>
|
||||
<a href="post-doctor-count.html" class="sidebar-item">医生检查人数统计</a>
|
||||
<a href="post-item-stat.html" class="sidebar-item">医院体检项目统计</a>
|
||||
<a href="post-cancer-screening.html" class="sidebar-item">防癌筛查人数统计</a>
|
||||
<a href="post-standard-stat.html" class="sidebar-item">系统标准化项目统计</a>
|
||||
<a href="post-contracted-hospital.html" class="sidebar-item">签约医院人数统计</a>
|
||||
<a href="post-key-indicator-stat.html" class="sidebar-item">重点指标异常统计</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sidebar-subgroup">
|
||||
<div class="sidebar-subgroup__header" onclick="toggleSubgroup(this)">
|
||||
<svg class="arrow" viewBox="0 0 12 12"><path d="M4 2l4 4-4 4" fill="none" stroke-width="1.5" stroke-linecap="round"/></svg>
|
||||
病种信息管理
|
||||
</div>
|
||||
<div class="sidebar-subgroup__body">
|
||||
<a href="post-disease-info.html" class="sidebar-item">病种信息配置</a>
|
||||
<a href="post-conclusion-disease.html" class="sidebar-item">体检结论关联病种</a>
|
||||
<a href="post-auto-select-disease.html" class="sidebar-item">员工病种信息</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sidebar-subgroup">
|
||||
<div class="sidebar-subgroup__header" onclick="toggleSubgroup(this)">
|
||||
<svg class="arrow" viewBox="0 0 12 12"><path d="M4 2l4 4-4 4" fill="none" stroke-width="1.5" stroke-linecap="round"/></svg>
|
||||
胃肠镜体检
|
||||
</div>
|
||||
<div class="sidebar-subgroup__body">
|
||||
<a href="post-report-gastro.html" class="sidebar-item">胃肠镜体检报告</a>
|
||||
<a href="post-gastro-stat.html" class="sidebar-item">胃肠镜体检统计</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sidebar-subgroup">
|
||||
<div class="sidebar-subgroup__header" onclick="toggleSubgroup(this)">
|
||||
<svg class="arrow" viewBox="0 0 12 12"><path d="M4 2l4 4-4 4" fill="none" stroke-width="1.5" stroke-linecap="round"/></svg>
|
||||
冠脉CTA体检
|
||||
</div>
|
||||
<div class="sidebar-subgroup__body">
|
||||
<a href="post-cta-report.html" class="sidebar-item">冠脉CTA体检报告</a>
|
||||
<a href="post-cta-stat.html" class="sidebar-item">冠脉CTA体检统计</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sidebar-subgroup">
|
||||
<div class="sidebar-subgroup__header" onclick="toggleSubgroup(this)">
|
||||
<svg class="arrow" viewBox="0 0 12 12"><path d="M4 2l4 4-4 4" fill="none" stroke-width="1.5" stroke-linecap="round"/></svg>
|
||||
体检影像管理
|
||||
</div>
|
||||
<div class="sidebar-subgroup__body">
|
||||
<a href="post-imc-user.html" class="sidebar-item">用户体检信息</a>
|
||||
<a href="post-imc-class.html" class="sidebar-item">用户影像文件分类</a>
|
||||
<a href="post-imc-info.html" class="sidebar-item active">用户影像文件详细</a>
|
||||
<a href="post-imc-log.html" class="sidebar-item">文件处理日志</a>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<main class="main">
|
||||
<div class="filter-bar">
|
||||
<div class="filter-item">
|
||||
<label>文件类型:</label>
|
||||
<select class="filter-select placeholder" id="f-filetype" onchange="this.classList.toggle('placeholder',!this.value)">
|
||||
<option value="">请选择文件类型</option>
|
||||
<option value="影像">影像</option>
|
||||
<option value="报告">报告</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label>患者ID:</label>
|
||||
<input class="filter-input" type="text" id="f-patient" placeholder="请输入患者ID" style="min-width:160px;">
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label>研究实例ID:</label>
|
||||
<input class="filter-input" type="text" id="f-study" placeholder="请输入研究实例ID" style="min-width:220px;">
|
||||
</div>
|
||||
<div style="margin-left:auto;display:flex;gap:12px;">
|
||||
<button class="btn btn-primary" onclick="doQuery()">
|
||||
<svg width="14" height="14" viewBox="0 0 14 14" fill="none"><circle cx="6" cy="6" r="4.5" stroke="#fff" stroke-width="1.4"/><path d="M9.5 9.5l3 3" stroke="#fff" stroke-width="1.4" stroke-linecap="round"/></svg>
|
||||
查询
|
||||
</button>
|
||||
<button class="btn btn-default" onclick="doReset()">
|
||||
<svg width="14" height="14" viewBox="0 0 14 14" fill="none"><path d="M12 7a5 5 0 1 1-1.5-3.6M12 1.5V4h-2.5" stroke="#666" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||
重置
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="display:flex;gap:12px;margin-bottom:16px;align-items:center;">
|
||||
<button class="btn btn-primary" onclick="openForm(null)">
|
||||
<svg width="14" height="14" viewBox="0 0 14 14" fill="none"><path d="M7 2v10M2 7h10" stroke="#fff" stroke-width="1.6" stroke-linecap="round"/></svg>
|
||||
新增
|
||||
</button>
|
||||
<button class="btn btn-default" onclick="exportList()">
|
||||
<svg width="14" height="14" viewBox="0 0 14 14" fill="none"><path d="M7 2v7M4 6l3 3 3-3M2 12.5h10" stroke="#666" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||
导出
|
||||
</button>
|
||||
<button class="btn btn-default" onclick="importList()">
|
||||
<svg width="14" height="14" viewBox="0 0 14 14" fill="none"><path d="M7 9V2M4 5l3-3 3 3M2 12.5h10" stroke="#666" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||
导入
|
||||
</button>
|
||||
<button class="btn btn-default" onclick="batchDelete()" style="margin-left:auto;">
|
||||
<svg width="14" height="14" viewBox="0 0 14 14" fill="none"><path d="M2 3.5h10M5.5 3.5V2h3v1.5M3.5 3.5l.7 8.5h5.6l.7-8.5" stroke="#666" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||
批量删除
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="table-card">
|
||||
<div class="table-card__content">
|
||||
<table id="infoTable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width:48px;"><input type="checkbox" id="checkAll" onclick="toggleCheckAll(this)"></th>
|
||||
<th style="width:56px;">序号</th>
|
||||
<th>文件类型</th>
|
||||
<th>影像序号</th>
|
||||
<th>错误信息</th>
|
||||
<th>文件地址</th>
|
||||
<th>dcm实例ID</th>
|
||||
<th>研究实例ID</th>
|
||||
<th>患者ID</th>
|
||||
<th>研究ID</th>
|
||||
<th>创建日期</th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="tbody"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="pagination" id="pagination"></div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<div class="modal-mask" id="formMask" onclick="if(event.target===this)closeForm()">
|
||||
<div class="modal">
|
||||
<div class="modal__header">
|
||||
<span class="modal__close" onclick="closeForm()">
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M3.5 3.5l9 9M12.5 3.5l-9 9" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"/></svg>
|
||||
</span>
|
||||
<span class="modal__title" id="formTitle">新增用户影像文件详细</span>
|
||||
</div>
|
||||
<div class="modal__body">
|
||||
<div class="form-item">
|
||||
<div class="form-label">用户影像文件分类ID</div>
|
||||
<input class="form-input" id="formMuicid" type="text" placeholder="请输入用户影像文件分类ID">
|
||||
</div>
|
||||
<div class="form-item">
|
||||
<div class="form-label"><span class="required">*</span> 文件类型</div>
|
||||
<select class="form-select" id="formFiletype">
|
||||
<option value="影像">影像</option>
|
||||
<option value="报告">报告</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-item">
|
||||
<div class="form-label">影像序号</div>
|
||||
<input class="form-input" id="formImageno" type="text" placeholder="请输入影像序号">
|
||||
</div>
|
||||
<div class="form-item">
|
||||
<div class="form-label">错误信息</div>
|
||||
<textarea class="form-textarea" id="formMsg" placeholder="请输入错误信息"></textarea>
|
||||
</div>
|
||||
<div class="form-item">
|
||||
<div class="form-label"><span class="required">*</span> 文件地址</div>
|
||||
<input class="form-input" id="formFileurl" type="text" placeholder="请输入文件地址">
|
||||
</div>
|
||||
<div class="form-item">
|
||||
<div class="form-label">dcm实例ID</div>
|
||||
<input class="form-input" id="formInsid" type="text" placeholder="请输入dcm实例ID">
|
||||
</div>
|
||||
<div class="form-item">
|
||||
<div class="form-label">研究实例ID</div>
|
||||
<input class="form-input" id="formStudyins" type="text" placeholder="请输入研究实例ID">
|
||||
</div>
|
||||
<div class="form-item">
|
||||
<div class="form-label">患者ID</div>
|
||||
<input class="form-input" id="formPatient" type="text" placeholder="请输入患者ID">
|
||||
</div>
|
||||
<div class="form-item">
|
||||
<div class="form-label">研究ID</div>
|
||||
<input class="form-input" id="formStudyid" type="text" placeholder="请输入研究ID">
|
||||
</div>
|
||||
<div class="form-item">
|
||||
<div class="form-label">创建日期</div>
|
||||
<input class="form-input" id="formCreatetime" type="text" placeholder="如 2026-08-15 11:30:00">
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal__footer">
|
||||
<button class="btn btn-default" onclick="closeForm()">取消</button>
|
||||
<button class="btn btn-primary" onclick="saveForm()">保存</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal-mask" id="detailMask" onclick="if(event.target===this)closeDetail()">
|
||||
<div class="modal">
|
||||
<div class="modal__header">
|
||||
<span class="modal__close" onclick="closeDetail()">
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M3.5 3.5l9 9M12.5 3.5l-9 9" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"/></svg>
|
||||
</span>
|
||||
<span class="modal__title">用户影像文件详细</span>
|
||||
</div>
|
||||
<div class="modal__body" id="detailBody"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var rows=[
|
||||
{fileType:'影像',imageNo:'1',msg:'',fileUrl:'/files/imc/PE20260001/chest/1.dcm',insId:'1.2.840.113619.6.55.201.1',studyInsId:'1.2.840.113619.6.55.201',patientId:'PAT0001',studyId:'1.2.840.113619.6.55.201',createTime:'2026-08-15 11:30:00',muicId:'MC1001'},
|
||||
{fileType:'影像',imageNo:'2',msg:'',fileUrl:'/files/imc/PE20260001/chest/2.dcm',insId:'1.2.840.113619.6.55.202.1',studyInsId:'1.2.840.113619.6.55.202',patientId:'PAT0001',studyId:'1.2.840.113619.6.55.202',createTime:'2026-08-15 11:30:10',muicId:'MC1001'},
|
||||
{fileType:'报告',imageNo:'1',msg:'',fileUrl:'/files/imc/PE20260001/chest/report.pdf',insId:'',studyInsId:'1.2.840.113619.6.55.201',patientId:'PAT0001',studyId:'1.2.840.113619.6.55.201',createTime:'2026-08-15 12:00:00',muicId:'MC1001'},
|
||||
{fileType:'影像',imageNo:'1',msg:'',fileUrl:'/files/imc/PE20260001/mri/1.dcm',insId:'1.2.840.113619.6.55.203.1',studyInsId:'1.2.840.113619.6.55.203',patientId:'PAT0001',studyId:'1.2.840.113619.6.55.203',createTime:'2026-08-15 12:30:00',muicId:'MC1002'},
|
||||
{fileType:'报告',imageNo:'1',msg:'',fileUrl:'/files/imc/PE20260001/mri/report.pdf',insId:'',studyInsId:'1.2.840.113619.6.55.203',patientId:'PAT0001',studyId:'1.2.840.113619.6.55.203',createTime:'2026-08-15 13:10:00',muicId:'MC1002'},
|
||||
{fileType:'报告',imageNo:'1',msg:'',fileUrl:'/files/imc/PE20260002/chest/report.pdf',insId:'',studyInsId:'1.2.840.113619.6.55.301',patientId:'PAT0002',studyId:'1.2.840.113619.6.55.301',createTime:'2026-08-15 15:20:00',muicId:'MC1004'},
|
||||
{fileType:'影像',imageNo:'1',msg:'DICOM标签解析失败:缺少 PatientID 标签',fileUrl:'/files/imc/PE20260003/xray/1.dcm',insId:'1.2.840.113619.6.55.401.1',studyInsId:'1.2.840.113619.6.55.401',patientId:'',studyId:'1.2.840.113619.6.55.401',createTime:'2026-08-15 16:00:00',muicId:'MC1006'},
|
||||
{fileType:'报告',imageNo:'1',msg:'',fileUrl:'/files/imc/PE20260002/ecg/report.jpg',insId:'',studyInsId:'1.2.840.113619.6.55.302',patientId:'PAT0002',studyId:'1.2.840.113619.6.55.302',createTime:'2026-08-15 15:40:00',muicId:'MC1005'},
|
||||
{fileType:'影像',imageNo:'1',msg:'',fileUrl:'/files/imc/PE20250018/chest/1.dcm',insId:'1.2.840.113619.6.55.501.1',studyInsId:'1.2.840.113619.6.55.501',patientId:'PAT0005',studyId:'1.2.840.113619.6.55.501',createTime:'2025-08-20 15:30:00',muicId:'MC1009'},
|
||||
{fileType:'报告',imageNo:'1',msg:'',fileUrl:'/files/imc/PE20250018/chest/report.pdf',insId:'',studyInsId:'1.2.840.113619.6.55.501',patientId:'PAT0005',studyId:'1.2.840.113619.6.55.501',createTime:'2025-08-20 16:00:00',muicId:'MC1009'},
|
||||
{fileType:'报告',imageNo:'1',msg:'报告文件格式与声明类型不一致',fileUrl:'/files/imc/PE20250021/us/report.png',insId:'',studyInsId:'1.2.840.113619.6.55.602',patientId:'PAT0006',studyId:'1.2.840.113619.6.55.602',createTime:'2025-08-21 11:00:00',muicId:'MC1012'}
|
||||
];
|
||||
var state={filetype:'',patient:'',study:'',page:1,pageSize:10};
|
||||
|
||||
function fileTypeTag(t){
|
||||
return t==='影像'?'<span class="tag tag-blue">影像</span>':'<span class="tag tag-purple">报告</span>';
|
||||
}
|
||||
function doQuery(){
|
||||
state.filetype=document.getElementById('f-filetype').value;
|
||||
state.patient=document.getElementById('f-patient').value.trim();
|
||||
state.study=document.getElementById('f-study').value.trim();
|
||||
state.page=1;
|
||||
renderTable();
|
||||
}
|
||||
function doReset(){
|
||||
var ft=document.getElementById('f-filetype');ft.value='';ft.classList.add('placeholder');
|
||||
document.getElementById('f-patient').value='';
|
||||
document.getElementById('f-study').value='';
|
||||
state.filetype='';state.patient='';state.study='';
|
||||
state.page=1;
|
||||
renderTable();
|
||||
}
|
||||
|
||||
function filteredRows(){
|
||||
return rows.filter(function(r){
|
||||
if(state.filetype&&r.fileType!==state.filetype)return false;
|
||||
if(state.patient&&r.patientId.indexOf(state.patient)===-1)return false;
|
||||
if(state.study&&r.studyInsId.indexOf(state.study)===-1)return false;
|
||||
return true;
|
||||
});
|
||||
}
|
||||
function renderTable(){
|
||||
var list=filteredRows();
|
||||
var totalPages=Math.max(1,Math.ceil(list.length/state.pageSize));
|
||||
if(state.page>totalPages)state.page=totalPages;
|
||||
var start=(state.page-1)*state.pageSize;
|
||||
var pageRows=list.slice(start,start+state.pageSize);
|
||||
var tbody=document.getElementById('tbody');
|
||||
tbody.innerHTML=pageRows.length?pageRows.map(function(r,pos){
|
||||
var idx=rows.indexOf(r);
|
||||
var msg=r.msg?r.msg:'<span class="muted">—</span>';
|
||||
if(r.msg&&r.msg.length>18)msg='<span title="'+r.msg+'">'+r.msg.slice(0,18)+'…</span>';
|
||||
return '<tr>'
|
||||
+'<td><input type="checkbox" class="row-check" data-idx="'+idx+'"></td>'
|
||||
+'<td>'+(start+pos+1)+'</td>'
|
||||
+'<td>'+fileTypeTag(r.fileType)+'</td><td>'+r.imageNo+'</td><td style="text-align:left;">'+msg+'</td>'
|
||||
+'<td><span class="link" onclick="downloadFile(\''+r.fileUrl+'\')">下载</span></td>'
|
||||
+'<td>'+(r.insId||'<span class="muted">—</span>')+'</td><td>'+r.studyInsId+'</td><td>'+(r.patientId||'<span class="muted">—</span>')+'</td>'
|
||||
+'<td>'+r.studyId+'</td><td>'+r.createTime+'</td>'
|
||||
+'<td><span class="link" onclick="openForm('+idx+')">编辑</span> <span class="link" style="margin-left:8px;" onclick="openDetail('+idx+')">详情</span> <span class="link-danger" style="margin-left:8px;" onclick="deleteRow('+idx+')">删除</span></td>'
|
||||
+'</tr>';
|
||||
}).join(''):'<tr><td colspan="12"><div class="empty-tip">暂无数据</div></td></tr>';
|
||||
var all=tbody.querySelectorAll('.row-check');
|
||||
var checked=tbody.querySelectorAll('.row-check:checked');
|
||||
document.getElementById('checkAll').checked=all.length>0&&all.length===checked.length;
|
||||
renderPagination(list.length,totalPages);
|
||||
}
|
||||
|
||||
function pageSeq(p,last){
|
||||
var seq=[];
|
||||
if(last<=7){for(var i=1;i<=last;i++)seq.push(i);return seq;}
|
||||
if(p<=4){seq=[1,2,3,4,5,'...',last];}
|
||||
else if(p>=last-3){seq=[1,'...',last-4,last-3,last-2,last-1,last];}
|
||||
else{seq=[1,'...',p-1,p,p+1,'...',last];}
|
||||
return seq;
|
||||
}
|
||||
function renderPagination(total,totalPages){
|
||||
var html='<span>共 '+total+' 条数据</span>';
|
||||
if(totalPages>1){
|
||||
html+='<button class="page-btn"'+(state.page===1?' disabled':'')+' onclick="goPage('+(state.page-1)+')"><</button>';
|
||||
pageSeq(state.page,totalPages).forEach(function(p){
|
||||
if(p==='...')html+='<span class="page-ellipsis">...</span>';
|
||||
else html+='<button class="page-btn'+(p===state.page?' active':'')+'" onclick="goPage('+p+')">'+p+'</button>';
|
||||
});
|
||||
html+='<button class="page-btn"'+(state.page===totalPages?' disabled':'')+' onclick="goPage('+(state.page+1)+')">></button>';
|
||||
}
|
||||
html+='<select class="page-size" onchange="changeSize(this.value)">'
|
||||
+[10,20,50].map(function(n){return '<option value="'+n+'"'+(n===state.pageSize?' selected':'')+'>'+n+'条/页</option>';}).join('')
|
||||
+'</select>';
|
||||
html+='<span class="page-jump">跳至<input type="number" id="jumpInput" min="1" value="'+state.page+'" onkeydown="if(event.key===\'Enter\')jumpTo('+totalPages+')">页<button class="page-btn" onclick="jumpTo('+totalPages+')">跳</button></span>';
|
||||
document.getElementById('pagination').innerHTML=html;
|
||||
}
|
||||
function goPage(p){state.page=p;renderTable();}
|
||||
function changeSize(v){state.pageSize=parseInt(v,10);state.page=1;renderTable();}
|
||||
function jumpTo(totalPages){
|
||||
var input=document.getElementById('jumpInput');
|
||||
var p=parseInt(input.value,10);
|
||||
if(isNaN(p)||p<1)p=1;
|
||||
if(p>totalPages)p=totalPages;
|
||||
state.page=p;
|
||||
renderTable();
|
||||
}
|
||||
|
||||
function downloadFile(url){
|
||||
alert('下载文件:'+url);
|
||||
}
|
||||
function toggleCheckAll(cb){
|
||||
document.querySelectorAll('.row-check').forEach(function(c){c.checked=cb.checked;});
|
||||
}
|
||||
function checkedIdx(){
|
||||
var arr=[];
|
||||
document.querySelectorAll('.row-check:checked').forEach(function(c){arr.push(parseInt(c.dataset.idx,10));});
|
||||
return arr;
|
||||
}
|
||||
function batchDelete(){
|
||||
var idxs=checkedIdx();
|
||||
if(!idxs.length){alert('请先勾选要删除的记录');return;}
|
||||
if(!confirm('确认删除选中的 '+idxs.length+' 条记录?'))return;
|
||||
idxs.sort(function(a,b){return b-a;}).forEach(function(i){rows.splice(i,1);});
|
||||
renderTable();
|
||||
}
|
||||
function deleteRow(idx){
|
||||
if(!confirm('确认删除该影像文件记录?'))return;
|
||||
rows.splice(idx,1);
|
||||
renderTable();
|
||||
}
|
||||
function exportList(){alert('导出当前筛选结果(Excel)');}
|
||||
function importList(){alert('导入影像文件详细数据(Excel)');}
|
||||
|
||||
var editingIdx=null;
|
||||
function openForm(idx){
|
||||
editingIdx=idx;
|
||||
document.getElementById('formTitle').textContent=idx===null?'新增用户影像文件详细':'编辑用户影像文件详细';
|
||||
if(idx===null){
|
||||
document.getElementById('formMuicid').value='';
|
||||
document.getElementById('formFiletype').value='影像';
|
||||
document.getElementById('formImageno').value='';
|
||||
document.getElementById('formMsg').value='';
|
||||
document.getElementById('formFileurl').value='';
|
||||
document.getElementById('formInsid').value='';
|
||||
document.getElementById('formStudyins').value='';
|
||||
document.getElementById('formPatient').value='';
|
||||
document.getElementById('formStudyid').value='';
|
||||
document.getElementById('formCreatetime').value='';
|
||||
}else{
|
||||
var r=rows[idx];
|
||||
document.getElementById('formMuicid').value=r.muicId;
|
||||
document.getElementById('formFiletype').value=r.fileType;
|
||||
document.getElementById('formImageno').value=r.imageNo;
|
||||
document.getElementById('formMsg').value=r.msg;
|
||||
document.getElementById('formFileurl').value=r.fileUrl;
|
||||
document.getElementById('formInsid').value=r.insId;
|
||||
document.getElementById('formStudyins').value=r.studyInsId;
|
||||
document.getElementById('formPatient').value=r.patientId;
|
||||
document.getElementById('formStudyid').value=r.studyId;
|
||||
document.getElementById('formCreatetime').value=r.createTime;
|
||||
}
|
||||
document.getElementById('formMask').classList.add('open');
|
||||
}
|
||||
function closeForm(){document.getElementById('formMask').classList.remove('open');}
|
||||
function saveForm(){
|
||||
var fileUrl=document.getElementById('formFileurl').value.trim();
|
||||
if(!fileUrl){alert('请输入文件地址');return;}
|
||||
var data={
|
||||
muicId:document.getElementById('formMuicid').value.trim(),
|
||||
fileType:document.getElementById('formFiletype').value,
|
||||
imageNo:document.getElementById('formImageno').value.trim(),
|
||||
msg:document.getElementById('formMsg').value.trim(),
|
||||
fileUrl:fileUrl,
|
||||
insId:document.getElementById('formInsid').value.trim(),
|
||||
studyInsId:document.getElementById('formStudyins').value.trim(),
|
||||
patientId:document.getElementById('formPatient').value.trim(),
|
||||
studyId:document.getElementById('formStudyid').value.trim(),
|
||||
createTime:document.getElementById('formCreatetime').value.trim()
|
||||
};
|
||||
if(editingIdx===null){
|
||||
rows.unshift(data);
|
||||
}else{
|
||||
rows[editingIdx]=data;
|
||||
}
|
||||
closeForm();
|
||||
renderTable();
|
||||
}
|
||||
|
||||
function openDetail(idx){
|
||||
var r=rows[idx];
|
||||
document.getElementById('detailBody').innerHTML=
|
||||
'<table class="detail-table"><tbody>'
|
||||
+'<tr><th>用户影像文件分类ID</th><td>'+r.muicId+'</td></tr>'
|
||||
+'<tr><th>文件类型</th><td>'+r.fileType+'</td></tr>'
|
||||
+'<tr><th>影像序号</th><td>'+r.imageNo+'</td></tr>'
|
||||
+'<tr><th>错误信息</th><td>'+(r.msg||'<span class="muted">—</span>')+'</td></tr>'
|
||||
+'<tr><th>文件地址</th><td>'+r.fileUrl+'</td></tr>'
|
||||
+'<tr><th>dcm实例ID</th><td>'+(r.insId||'<span class="muted">—</span>')+'</td></tr>'
|
||||
+'<tr><th>研究实例ID</th><td>'+r.studyInsId+'</td></tr>'
|
||||
+'<tr><th>患者ID</th><td>'+(r.patientId||'<span class="muted">—</span>')+'</td></tr>'
|
||||
+'<tr><th>研究ID</th><td>'+r.studyId+'</td></tr>'
|
||||
+'<tr><th>创建日期</th><td>'+r.createTime+'</td></tr>'
|
||||
+'</tbody></table>';
|
||||
document.getElementById('detailMask').classList.add('open');
|
||||
}
|
||||
function closeDetail(){document.getElementById('detailMask').classList.remove('open');}
|
||||
document.addEventListener('keydown',function(e){
|
||||
if(e.key==='Escape'){closeForm();closeDetail();}
|
||||
});
|
||||
|
||||
function toggleSubgroup(header){
|
||||
header.parentElement.classList.toggle('open');
|
||||
}
|
||||
(function(){
|
||||
renderTable();
|
||||
var active=document.querySelector('.sidebar-item.active');
|
||||
if(!active)return;
|
||||
var sub=active.closest('.sidebar-subgroup');
|
||||
while(sub){ sub.classList.add('open'); sub=sub.parentElement.closest('.sidebar-subgroup'); }
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,520 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>健康体检 - 文件处理日志 | 健康CQ原型</title>
|
||||
<style>
|
||||
*{box-sizing:border-box;margin:0;padding:0;}
|
||||
body{font-family:-apple-system,BlinkMacSystemFont,'PingFang SC','Microsoft YaHei',sans-serif;background:#F5F7FA;color:#333;min-width:1280px;}
|
||||
:root{
|
||||
--primary:#1890FF;--primary-light:#E6F7FF;--success:#52C41A;--warning:#FAAD14;--danger:#FF4D4F;
|
||||
--text-primary:#333;--text-secondary:#666;--text-placeholder:#999;--border:#E8E8E8;--background:#F5F7FA;
|
||||
--font-xs:11px;--font-sm:13px;--font-base:15px;--font-lg:17px;--font-xl:20px;--font-xxl:24px;
|
||||
--radius-sm:4px;--radius-md:8px;--radius-lg:12px;
|
||||
--shadow-sm:0 1px 4px rgba(0,0,0,0.08);--shadow-md:0 4px 12px rgba(0,0,0,0.12);
|
||||
}
|
||||
.top-bar{display:flex;align-items:center;height:56px;background:#001529;padding:0 24px;position:fixed;top:0;left:0;right:0;z-index:100;}
|
||||
.top-bar__logo{display:flex;align-items:center;gap:8px;color:#fff;font-size:var(--font-lg);font-weight:600;white-space:nowrap;width:240px;flex-shrink:0;}
|
||||
.top-bar__logo svg{width:28px;height:28px;}
|
||||
.top-bar__nav{display:flex;align-items:center;gap:4px;flex:1;}
|
||||
.top-bar__nav a{color:rgba(255,255,255,0.65);text-decoration:none;padding:6px 16px;border-radius:var(--radius-sm);font-size:var(--font-sm);transition:all .2s;}
|
||||
.top-bar__nav a:hover{color:#fff;background:rgba(255,255,255,0.08);}
|
||||
.top-bar__nav a.active{color:#fff;background:var(--primary);}
|
||||
.top-bar__right{display:flex;align-items:center;gap:16px;color:rgba(255,255,255,0.65);font-size:var(--font-sm);}
|
||||
.top-bar__right .btn-back{color:rgba(255,255,255,0.65);cursor:pointer;display:flex;align-items:center;gap:4px;text-decoration:none;}
|
||||
.top-bar__right .btn-back:hover{color:#fff;}
|
||||
.avatar{width:32px;height:32px;border-radius:50%;background:#1890FF;display:flex;align-items:center;justify-content:center;color:#fff;font-size:var(--font-sm);cursor:pointer;}
|
||||
.sidebar{position:fixed;top:56px;left:0;bottom:0;width:240px;background:#001529;overflow-y:auto;z-index:90;padding-top:8px;}
|
||||
.sidebar-menu__title{color:rgba(255,255,255,0.35);font-size:var(--font-xs);padding:16px 24px 8px;text-transform:uppercase;letter-spacing:.5px;}
|
||||
.sidebar-item{display:flex;align-items:center;gap:8px;padding:10px 24px;color:rgba(255,255,255,0.65);font-size:var(--font-sm);cursor:pointer;transition:all .15s;text-decoration:none;}
|
||||
.sidebar-item:hover{color:#fff;background:rgba(255,255,255,0.06);}
|
||||
.sidebar-item.active{color:#fff;background:var(--primary);}
|
||||
.sidebar-subgroup__header{display:flex;align-items:center;gap:6px;padding:10px 24px;color:rgba(255,255,255,0.65);font-size:var(--font-sm);cursor:pointer;transition:all .15s;user-select:none;}
|
||||
.sidebar-subgroup__header:hover{color:rgba(255,255,255,0.85);background:rgba(255,255,255,0.04);}
|
||||
.sidebar-subgroup__header .arrow{width:10px;height:10px;transition:transform .2s;flex-shrink:0;}
|
||||
.sidebar-subgroup__header .arrow path{stroke:rgba(255,255,255,0.45);}
|
||||
.sidebar-subgroup.open>.sidebar-subgroup__header{color:rgba(255,255,255,0.85);}
|
||||
.sidebar-subgroup.open>.sidebar-subgroup__header .arrow{transform:rotate(90deg);}
|
||||
.sidebar-subgroup__body{display:none;padding-left:16px;}
|
||||
.sidebar-subgroup.open>.sidebar-subgroup__body{display:block;}
|
||||
.sidebar-subgroup__body .sidebar-item{padding-left:36px;font-size:12px;}
|
||||
.sidebar-subgroup .sidebar-subgroup{padding-left:12px;}
|
||||
.sidebar-subgroup .sidebar-subgroup .sidebar-item{padding-left:40px;}
|
||||
.sidebar-subgroup .sidebar-subgroup>.sidebar-subgroup__header{font-size:12px;}
|
||||
.main{margin-left:240px;margin-top:56px;padding:24px;min-height:calc(100vh - 56px);}
|
||||
.filter-bar{background:#fff;border-radius:var(--radius-md);padding:20px 24px;margin-bottom:16px;box-shadow:var(--shadow-sm);display:flex;align-items:center;gap:16px;flex-wrap:wrap;}
|
||||
.filter-item{display:flex;align-items:center;gap:8px;}
|
||||
.filter-item label{font-size:var(--font-sm);color:var(--text-secondary);white-space:nowrap;}
|
||||
.filter-input{height:36px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 12px;font-size:var(--font-sm);color:var(--text-primary);outline:none;background:#fff;min-width:160px;}
|
||||
.filter-input:focus{border-color:var(--primary);}
|
||||
.filter-input::placeholder{color:var(--text-placeholder);}
|
||||
.filter-select{height:36px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 28px 0 12px;font-size:var(--font-sm);color:var(--text-primary);outline:none;background:#fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%23999'/%3E%3C/svg%3E") no-repeat right 10px center;appearance:none;cursor:pointer;min-width:130px;}
|
||||
.filter-select:focus{border-color:var(--primary);}
|
||||
.filter-select.placeholder{color:var(--text-placeholder);}
|
||||
.btn{height:36px;padding:0 16px;border-radius:var(--radius-sm);font-size:var(--font-sm);cursor:pointer;border:none;transition:all .2s;display:inline-flex;align-items:center;gap:6px;}
|
||||
.btn-primary{background:var(--primary);color:#fff;}.btn-primary:hover{background:#40a9ff;}
|
||||
.btn-default{background:#fff;color:var(--text-primary);border:1px solid var(--border);}.btn-default:hover{color:var(--primary);border-color:var(--primary);}
|
||||
.year-picker{position:relative;}
|
||||
.year-picker .filter-input{padding-right:30px;cursor:pointer;min-width:100px;}
|
||||
.year-picker>svg{position:absolute;right:9px;top:50%;transform:translateY(-50%);pointer-events:none;}
|
||||
.year-picker__dropdown{display:none;position:absolute;top:40px;left:0;width:100px;background:#fff;border:1px solid var(--border);border-radius:var(--radius-sm);box-shadow:var(--shadow-md);z-index:50;max-height:180px;overflow-y:auto;}
|
||||
.year-picker__dropdown.open{display:block;}
|
||||
.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;}
|
||||
.table-card{background:#fff;border-radius:var(--radius-md);box-shadow:var(--shadow-sm);overflow:hidden;}
|
||||
.table-card__content{overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch;}
|
||||
.table-card__content table{min-width:100%;white-space:nowrap;}
|
||||
table{width:100%;border-collapse:collapse;}
|
||||
thead th{background:#FAFAFA;padding:12px 16px;text-align:center;font-size:var(--font-sm);color:var(--text-secondary);font-weight:500;border-bottom:1px solid var(--border);white-space:nowrap;}
|
||||
tbody td{padding:14px 16px;font-size:var(--font-sm);color:var(--text-primary);border-bottom:1px solid var(--border);white-space:nowrap;text-align:center;}
|
||||
tbody tr:last-child td{border-bottom:none;}
|
||||
tbody tr:hover{background:#F8FBFF;}
|
||||
#logTable thead th:last-child{position:sticky;right:0;background:#FAFAFA;border-left:1px solid var(--border);}
|
||||
#logTable tbody td:last-child{position:sticky;right:0;background:#fff;border-left:1px solid var(--border);}
|
||||
#logTable tbody tr:hover td:last-child{background:#F8FBFF;}
|
||||
.link{color:var(--primary);cursor:pointer;font-size:var(--font-sm);}.link:hover{color:#40a9ff;}
|
||||
.link-danger{color:var(--danger);cursor:pointer;font-size:var(--font-sm);}.link-danger:hover{color:#ff7875;}
|
||||
.empty-tip{padding:48px 0;text-align:center;font-size:var(--font-sm);color:var(--text-placeholder);}
|
||||
.muted{color:var(--text-placeholder);}
|
||||
.mono{font-family:Consolas,Menlo,monospace;font-size:var(--font-xs);color:var(--text-secondary);}
|
||||
.tag{display:inline-flex;align-items:center;padding:2px 10px;border-radius:10px;font-size:var(--font-xs);}
|
||||
.tag-blue{background:#E6F7FF;color:#1890FF;}
|
||||
.tag-green{background:#F6FFED;color:#52C41A;}
|
||||
.tag-orange{background:#FFF7E6;color:#FA8C16;}
|
||||
.tag-red{background:#FFF1F0;color:#FF4D4F;}
|
||||
.tag-gray{background:#FAFAFA;color:#999;}
|
||||
.pagination{display:flex;align-items:center;justify-content:flex-end;padding:16px 24px;gap:8px;border-top:1px solid var(--border);flex-wrap:wrap;}
|
||||
.pagination span{font-size:var(--font-sm);color:var(--text-secondary);}
|
||||
.page-btn{width:32px;height:32px;border:1px solid var(--border);border-radius:var(--radius-sm);background:#fff;cursor:pointer;font-size:var(--font-sm);display:inline-flex;align-items:center;justify-content:center;transition:all .2s;color:var(--text-primary);}
|
||||
.page-btn:hover:not(:disabled),.page-btn.active{background:var(--primary);color:#fff;border-color:var(--primary);}
|
||||
.page-btn:disabled{color:var(--text-placeholder);cursor:not-allowed;background:#FAFAFA;}
|
||||
.page-ellipsis{width:24px;text-align:center;color:var(--text-placeholder);font-size:var(--font-sm);}
|
||||
.page-size{height:32px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 24px 0 10px;font-size:var(--font-sm);color:var(--text-primary);background:#fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%23999'/%3E%3C/svg%3E") no-repeat right 8px center;appearance:none;cursor:pointer;outline:none;}
|
||||
.page-jump input{width:48px;height:32px;border:1px solid var(--border);border-radius:var(--radius-sm);text-align:center;font-size:var(--font-sm);outline:none;margin:0 4px;}
|
||||
.page-jump input:focus{border-color:var(--primary);}
|
||||
.modal-mask{display:none;position:fixed;inset:0;background:rgba(0,0,0,0.45);z-index:200;overflow-y:auto;}
|
||||
.modal-mask.open{display:flex;align-items:flex-start;justify-content:center;padding:60px 24px;}
|
||||
.modal{width:680px;max-width:100%;background:#fff;border-radius:var(--radius-md);box-shadow:var(--shadow-md);display:flex;flex-direction:column;max-height:calc(100vh - 120px);}
|
||||
.modal__header{display:flex;align-items:center;gap:12px;padding:16px 20px;border-bottom:1px solid var(--border);flex-shrink:0;}
|
||||
.modal__close{cursor:pointer;color:var(--text-secondary);display:flex;align-items:center;transition:color .2s;}
|
||||
.modal__close:hover{color:var(--danger);}
|
||||
.modal__title{font-size:var(--font-base);font-weight:600;}
|
||||
.modal__body{padding:20px;overflow-y:auto;}
|
||||
.detail-table{width:100%;border-collapse:collapse;border:1px solid var(--border);}
|
||||
.detail-table th,.detail-table td{border-bottom:1px solid var(--border);text-align:left;padding:12px 16px;font-size:var(--font-sm);word-break:break-all;}
|
||||
.detail-table tr:last-child td{border-bottom:none;}
|
||||
.detail-table th{width:130px;background:#FAFAFA;color:var(--text-secondary);font-weight:500;}
|
||||
.json-box{background:#FAFAFA;border:1px solid var(--border);border-radius:var(--radius-sm);padding:12px;font-family:Consolas,Menlo,monospace;font-size:var(--font-xs);color:var(--text-secondary);white-space:pre-wrap;word-break:break-all;max-height:200px;overflow-y:auto;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="top-bar">
|
||||
<div class="top-bar__logo">
|
||||
<svg viewBox="0 0 28 28" fill="none"><rect width="28" height="28" rx="6" fill="#1890FF"/><path d="M7 14h14M14 7v14" stroke="#fff" stroke-width="2.5" stroke-linecap="round"/></svg>
|
||||
健康体检
|
||||
</div>
|
||||
<nav class="top-bar__nav">
|
||||
<a href="archive-personal.html">档案</a>
|
||||
<a href="config-material-notice.html">基础配置</a>
|
||||
<a href="pre-hospital-scope.html">检前</a>
|
||||
<a href="mid-appointment-track.html">检中</a>
|
||||
<a href="post-unit-count.html" class="active">检后</a>
|
||||
<a href="exception-dirty.html">异常事件</a>
|
||||
</nav>
|
||||
<div class="top-bar__right">
|
||||
<a class="btn-back" href="../../index.html">
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M10 3L5 8l5 5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
|
||||
返回首页
|
||||
</a>
|
||||
<div class="avatar">管</div>
|
||||
<span style="color:rgba(255,255,255,0.65);">系统管理员 ▾</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<aside class="sidebar">
|
||||
<div class="sidebar-menu__title">检后</div>
|
||||
<div class="sidebar-subgroup">
|
||||
<div class="sidebar-subgroup__header" onclick="toggleSubgroup(this)">
|
||||
<svg class="arrow" viewBox="0 0 12 12"><path d="M4 2l4 4-4 4" fill="none" stroke-width="1.5" stroke-linecap="round"/></svg>
|
||||
常规体检
|
||||
</div>
|
||||
<div class="sidebar-subgroup__body">
|
||||
<a href="post-report-employee.html" class="sidebar-item">常规体检报告</a>
|
||||
<a href="post-employee-master.html" class="sidebar-item">员工体检大表</a>
|
||||
<a href="post-illness-personnel.html" class="sidebar-item">大病人员信息</a>
|
||||
<a href="post-indicator-notify.html" class="sidebar-item">指标异常通知</a>
|
||||
<a href="post-report-unmatched.html" class="sidebar-item">体检报告未匹配项目</a>
|
||||
<div class="sidebar-subgroup">
|
||||
<div class="sidebar-subgroup__header" onclick="toggleSubgroup(this)">
|
||||
<svg class="arrow" viewBox="0 0 12 12"><path d="M4 2l4 4-4 4" fill="none" stroke-width="1.5" stroke-linecap="round"/></svg>
|
||||
体检统计汇总
|
||||
</div>
|
||||
<div class="sidebar-subgroup__body">
|
||||
<a href="post-unit-count.html" class="sidebar-item">单位体检人数统计</a>
|
||||
<a href="post-unit-cost-stat.html" class="sidebar-item">单位体检费用统计</a>
|
||||
<a href="post-hospital-count.html" class="sidebar-item">医院体检人数统计</a>
|
||||
<a href="post-doctor-count.html" class="sidebar-item">医生检查人数统计</a>
|
||||
<a href="post-item-stat.html" class="sidebar-item">医院体检项目统计</a>
|
||||
<a href="post-cancer-screening.html" class="sidebar-item">防癌筛查人数统计</a>
|
||||
<a href="post-standard-stat.html" class="sidebar-item">系统标准化项目统计</a>
|
||||
<a href="post-contracted-hospital.html" class="sidebar-item">签约医院人数统计</a>
|
||||
<a href="post-key-indicator-stat.html" class="sidebar-item">重点指标异常统计</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sidebar-subgroup">
|
||||
<div class="sidebar-subgroup__header" onclick="toggleSubgroup(this)">
|
||||
<svg class="arrow" viewBox="0 0 12 12"><path d="M4 2l4 4-4 4" fill="none" stroke-width="1.5" stroke-linecap="round"/></svg>
|
||||
病种信息管理
|
||||
</div>
|
||||
<div class="sidebar-subgroup__body">
|
||||
<a href="post-disease-info.html" class="sidebar-item">病种信息配置</a>
|
||||
<a href="post-conclusion-disease.html" class="sidebar-item">体检结论关联病种</a>
|
||||
<a href="post-auto-select-disease.html" class="sidebar-item">员工病种信息</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sidebar-subgroup">
|
||||
<div class="sidebar-subgroup__header" onclick="toggleSubgroup(this)">
|
||||
<svg class="arrow" viewBox="0 0 12 12"><path d="M4 2l4 4-4 4" fill="none" stroke-width="1.5" stroke-linecap="round"/></svg>
|
||||
胃肠镜体检
|
||||
</div>
|
||||
<div class="sidebar-subgroup__body">
|
||||
<a href="post-report-gastro.html" class="sidebar-item">胃肠镜体检报告</a>
|
||||
<a href="post-gastro-stat.html" class="sidebar-item">胃肠镜体检统计</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sidebar-subgroup">
|
||||
<div class="sidebar-subgroup__header" onclick="toggleSubgroup(this)">
|
||||
<svg class="arrow" viewBox="0 0 12 12"><path d="M4 2l4 4-4 4" fill="none" stroke-width="1.5" stroke-linecap="round"/></svg>
|
||||
冠脉CTA体检
|
||||
</div>
|
||||
<div class="sidebar-subgroup__body">
|
||||
<a href="post-cta-report.html" class="sidebar-item">冠脉CTA体检报告</a>
|
||||
<a href="post-cta-stat.html" class="sidebar-item">冠脉CTA体检统计</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sidebar-subgroup">
|
||||
<div class="sidebar-subgroup__header" onclick="toggleSubgroup(this)">
|
||||
<svg class="arrow" viewBox="0 0 12 12"><path d="M4 2l4 4-4 4" fill="none" stroke-width="1.5" stroke-linecap="round"/></svg>
|
||||
体检影像管理
|
||||
</div>
|
||||
<div class="sidebar-subgroup__body">
|
||||
<a href="post-imc-user.html" class="sidebar-item">用户体检信息</a>
|
||||
<a href="post-imc-class.html" class="sidebar-item">用户影像文件分类</a>
|
||||
<a href="post-imc-info.html" class="sidebar-item">用户影像文件详细</a>
|
||||
<a href="post-imc-log.html" class="sidebar-item active">文件处理日志</a>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<main class="main">
|
||||
<div class="filter-bar">
|
||||
<div class="filter-item">
|
||||
<label>身份证号:</label>
|
||||
<input class="filter-input" type="text" id="f-idcard" placeholder="请输入身份证号" style="min-width:170px;">
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label>体检年份:</label>
|
||||
<div class="year-picker">
|
||||
<input class="filter-input" type="text" readonly value="2026" id="f-year">
|
||||
<svg width="14" height="14" viewBox="0 0 14 14" fill="none"><rect x="1.5" y="2.5" width="11" height="10" rx="1.5" stroke="#999" stroke-width="1.2"/><path d="M1.5 5.5h11M4.5 1v3M9.5 1v3" stroke="#999" stroke-width="1.2" stroke-linecap="round"/></svg>
|
||||
<div class="year-picker__dropdown" id="yearDropdown">
|
||||
<div class="selected" onclick="pickYear(this)">2026</div>
|
||||
<div onclick="pickYear(this)">2025</div>
|
||||
<div onclick="pickYear(this)">2024</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label>体检编号:</label>
|
||||
<input class="filter-input" type="text" id="f-peid" placeholder="请输入体检编号" style="min-width:160px;">
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label>影像分类:</label>
|
||||
<select class="filter-select placeholder" id="f-imgclass" onchange="this.classList.toggle('placeholder',!this.value)">
|
||||
<option value="">请选择影像分类</option>
|
||||
<option value="超声">超声</option>
|
||||
<option value="CT">CT</option>
|
||||
<option value="MRI">MRI</option>
|
||||
<option value="X射线">X射线</option>
|
||||
<option value="心电">心电</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label>处理状态:</label>
|
||||
<select class="filter-select placeholder" id="f-status" onchange="this.classList.toggle('placeholder',!this.value)">
|
||||
<option value="">请选择处理状态</option>
|
||||
<option value="1">新建</option>
|
||||
<option value="2">待解析</option>
|
||||
<option value="4">解析中</option>
|
||||
<option value="5">成功</option>
|
||||
<option value="6">失败待重试</option>
|
||||
<option value="3">失败</option>
|
||||
<option value="7">最终失败</option>
|
||||
</select>
|
||||
</div>
|
||||
<div style="margin-left:auto;display:flex;gap:12px;">
|
||||
<button class="btn btn-primary" onclick="doQuery()">
|
||||
<svg width="14" height="14" viewBox="0 0 14 14" fill="none"><circle cx="6" cy="6" r="4.5" stroke="#fff" stroke-width="1.4"/><path d="M9.5 9.5l3 3" stroke="#fff" stroke-width="1.4" stroke-linecap="round"/></svg>
|
||||
查询
|
||||
</button>
|
||||
<button class="btn btn-default" onclick="doReset()">
|
||||
<svg width="14" height="14" viewBox="0 0 14 14" fill="none"><path d="M12 7a5 5 0 1 1-1.5-3.6M12 1.5V4h-2.5" stroke="#666" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||
重置
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 操作栏 -->
|
||||
<div style="display:flex;gap:12px;margin-bottom:16px;align-items:center;">
|
||||
<button class="btn btn-default" onclick="batchDelete()">
|
||||
<svg width="14" height="14" viewBox="0 0 14 14" fill="none"><path d="M2 3.5h10M5.5 3.5V2h3v1.5M3.5 3.5l.7 8.5h5.6l.7-8.5" stroke="#666" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||
批量删除
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="table-card">
|
||||
<div class="table-card__content">
|
||||
<table id="logTable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width:48px;"><input type="checkbox" id="checkAll" onclick="toggleCheckAll(this)"></th>
|
||||
<th style="width:56px;">序号</th>
|
||||
<th>医院名称</th>
|
||||
<th>姓名</th>
|
||||
<th>身份证号</th>
|
||||
<th>体检年份</th>
|
||||
<th>体检编号</th>
|
||||
<th>影像分类</th>
|
||||
<th>json数据</th>
|
||||
<th>文件地址</th>
|
||||
<th>文件大小(MB)</th>
|
||||
<th>处理状态</th>
|
||||
<th>错误信息</th>
|
||||
<th>传输开始时间</th>
|
||||
<th>传输完成时间</th>
|
||||
<th>解析开始时间</th>
|
||||
<th>解析完成时间</th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="tbody"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="pagination" id="pagination"></div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<div class="modal-mask" id="detailMask" onclick="if(event.target===this)closeDetail()">
|
||||
<div class="modal">
|
||||
<div class="modal__header">
|
||||
<span class="modal__close" onclick="closeDetail()">
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M3.5 3.5l9 9M12.5 3.5l-9 9" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"/></svg>
|
||||
</span>
|
||||
<span class="modal__title">文件处理日志详情</span>
|
||||
</div>
|
||||
<div class="modal__body" id="detailBody"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var handleStatusMap={1:'新建',2:'待解析',3:'失败',4:'解析中',5:'成功',6:'失败待重试',7:'最终失败'};
|
||||
function statusTag(s){
|
||||
var cls='tag-gray';
|
||||
if(s===5)cls='tag-green';
|
||||
else if(s===4||s===6)cls='tag-orange';
|
||||
else if(s===3||s===7)cls='tag-red';
|
||||
else if(s===1)cls='tag-blue';
|
||||
return '<span class="tag '+cls+'">'+handleStatusMap[s]+'</span>';
|
||||
}
|
||||
/* 按传输开始时间倒序 */
|
||||
var rows=[
|
||||
{hospitalName:'重庆市人民医院',realname:'张伟',idCard:'500103197805121234',medicalYear:'2026',peId:'PE20260001',imgClass:'CT',jsonContent:'{"hospitalId":"H001","hospitalName":"重庆市人民医院","peId":"PE20260001","items":[{"name":"胸部CT平扫","type":"CT"},{"name":"头颅MRI平扫","type":"MRI"},{"name":"腹部超声","type":"超声"}]}',zipFileUrl:'/files/imc/PE20260001.zip',zipSize:128.5,status:5,msg:'',startTime:'2026-08-15 10:00:00',endTime:'2026-08-15 10:02:15',parseStartTime:'2026-08-15 10:05:00',parseEndTime:'2026-08-15 12:00:00'},
|
||||
{hospitalName:'重庆医科大学附属第一医院',realname:'李芳',idCard:'500107198812053467',medicalYear:'2026',peId:'PE20260002',imgClass:'CT',jsonContent:'{"hospitalId":"H002","hospitalName":"重庆医科大学附属第一医院","peId":"PE20260002","items":[{"name":"胸部CT平扫","type":"CT"},{"name":"心电图","type":"心电"}]}',zipFileUrl:'/files/imc/PE20260002.zip',zipSize:96.2,status:5,msg:'',startTime:'2026-08-15 11:00:00',endTime:'2026-08-15 11:01:30',parseStartTime:'2026-08-15 11:05:00',parseEndTime:'2026-08-15 13:00:00'},
|
||||
{hospitalName:'陆军军医大学西南医院',realname:'王强',idCard:'500105199203154567',medicalYear:'2026',peId:'PE20260003',imgClass:'X射线',jsonContent:'{"hospitalId":"H003","hospitalName":"陆军军医大学西南医院","peId":"PE20260003","items":[{"name":"胸部X射线","type":"X射线"},{"name":"腹部超声","type":"超声"}]}',zipFileUrl:'/files/imc/PE20260003.zip',zipSize:64.8,status:7,msg:'DICOM标签解析失败:缺少 PatientID 标签',startTime:'2026-08-15 13:40:00',endTime:'2026-08-15 13:42:10',parseStartTime:'2026-08-15 13:45:00',parseEndTime:'2026-08-15 14:10:00'},
|
||||
{hospitalName:'陆军特色医学中心',realname:'赵敏',idCard:'500104199001011234',medicalYear:'2026',peId:'PE20260004',imgClass:'CT',jsonContent:'{"hospitalId":"H004","hospitalName":"陆军特色医学中心","peId":"PE20260004","items":[{"name":"冠脉CTA","type":"CT"}]}',zipFileUrl:'/files/imc/PE20260004.zip',zipSize:210.3,status:2,msg:'',startTime:'2026-08-16 09:10:00',endTime:'2026-08-16 09:12:00',parseStartTime:'',parseEndTime:''},
|
||||
{hospitalName:'重庆市人民医院',realname:'陈刚',idCard:'500106198503094567',medicalYear:'2025',peId:'PE20250018',imgClass:'CT',jsonContent:'{"hospitalId":"H001","hospitalName":"重庆市人民医院","peId":"PE20250018","items":[{"name":"胸部CT平扫","type":"CT"},{"name":"头颅MRI平扫","type":"MRI"},{"name":"腹部超声","type":"超声"},{"name":"心电图","type":"心电"}]}',zipFileUrl:'/files/imc/PE20250018.zip',zipSize:152.7,status:5,msg:'',startTime:'2025-08-20 15:20:00',endTime:'2025-08-20 15:23:00',parseStartTime:'2025-08-20 15:30:00',parseEndTime:'2025-08-20 17:00:00'},
|
||||
{hospitalName:'重庆医科大学附属第一医院',realname:'刘洋',idCard:'500102199511223456',medicalYear:'2025',peId:'PE20250021',imgClass:'超声',jsonContent:'{"hospitalId":"H002","hospitalName":"重庆医科大学附属第一医院","peId":"PE20250021","items":[{"name":"胸部CT平扫","type":"CT"},{"name":"腹部超声","type":"超声"}]}',zipFileUrl:'/files/imc/PE20250021.zip',zipSize:88.9,status:7,msg:'报告文件格式与声明类型不一致',startTime:'2025-08-21 10:00:00',endTime:'2025-08-21 10:02:00',parseStartTime:'2025-08-21 10:10:00',parseEndTime:'2025-08-21 11:00:00'}
|
||||
];
|
||||
var state={idcard:'',year:'2026',peid:'',imgclass:'',status:'',page:1,pageSize:10};
|
||||
|
||||
function toggleYear(){document.getElementById('yearDropdown').classList.toggle('open');}
|
||||
function pickYear(el){
|
||||
document.getElementById('f-year').value=el.textContent.trim();
|
||||
document.getElementById('yearDropdown').classList.remove('open');
|
||||
document.querySelectorAll('#yearDropdown div').forEach(function(d){d.classList.remove('selected');});
|
||||
el.classList.add('selected');
|
||||
}
|
||||
document.getElementById('f-year').addEventListener('click',toggleYear);
|
||||
document.addEventListener('click',function(e){
|
||||
if(!e.target.closest('.year-picker'))document.getElementById('yearDropdown').classList.remove('open');
|
||||
});
|
||||
|
||||
function doQuery(){
|
||||
state.idcard=document.getElementById('f-idcard').value.trim();
|
||||
state.year=document.getElementById('f-year').value.trim();
|
||||
state.peid=document.getElementById('f-peid').value.trim();
|
||||
state.imgclass=document.getElementById('f-imgclass').value;
|
||||
state.status=document.getElementById('f-status').value;
|
||||
state.page=1;
|
||||
renderTable();
|
||||
}
|
||||
function doReset(){
|
||||
document.getElementById('f-idcard').value='';
|
||||
document.getElementById('f-year').value='2026';
|
||||
document.querySelectorAll('#yearDropdown div').forEach(function(d){
|
||||
d.classList.toggle('selected',d.textContent.trim()==='2026');
|
||||
});
|
||||
document.getElementById('f-peid').value='';
|
||||
var ic=document.getElementById('f-imgclass');ic.value='';ic.classList.add('placeholder');
|
||||
var st=document.getElementById('f-status');st.value='';st.classList.add('placeholder');
|
||||
state.idcard='';state.year='2026';state.peid='';state.imgclass='';state.status='';
|
||||
state.page=1;
|
||||
renderTable();
|
||||
}
|
||||
|
||||
function filteredRows(){
|
||||
return rows.filter(function(r){
|
||||
if(state.idcard&&r.idCard.indexOf(state.idcard)===-1)return false;
|
||||
if(state.year&&r.medicalYear!==state.year)return false;
|
||||
if(state.peid&&r.peId.indexOf(state.peid)===-1)return false;
|
||||
if(state.imgclass&&r.imgClass!==state.imgclass)return false;
|
||||
if(state.status&&String(r.status)!==state.status)return false;
|
||||
return true;
|
||||
});
|
||||
}
|
||||
function renderTable(){
|
||||
var list=filteredRows();
|
||||
var totalPages=Math.max(1,Math.ceil(list.length/state.pageSize));
|
||||
if(state.page>totalPages)state.page=totalPages;
|
||||
var start=(state.page-1)*state.pageSize;
|
||||
var pageRows=list.slice(start,start+state.pageSize);
|
||||
var tbody=document.getElementById('tbody');
|
||||
tbody.innerHTML=pageRows.length?pageRows.map(function(r,pos){
|
||||
var idx=rows.indexOf(r);
|
||||
var json=r.jsonContent;
|
||||
if(json.length>24)json='<span class="mono" title="'+r.jsonContent.replace(/"/g,'"')+'">'+r.jsonContent.slice(0,24)+'…</span>';
|
||||
else json='<span class="mono">'+json+'</span>';
|
||||
var msg=r.msg?r.msg:'<span class="muted">—</span>';
|
||||
if(r.msg&&r.msg.length>18)msg='<span title="'+r.msg+'">'+r.msg.slice(0,18)+'…</span>';
|
||||
return '<tr>'
|
||||
+'<td><input type="checkbox" class="row-check" data-idx="'+idx+'"></td>'
|
||||
+'<td>'+(start+pos+1)+'</td>'
|
||||
+'<td>'+r.hospitalName+'</td><td>'+r.realname+'</td><td>'+r.idCard+'</td><td>'+r.medicalYear+'</td>'
|
||||
+'<td>'+r.peId+'</td><td>'+r.imgClass+'</td><td>'+json+'</td>'
|
||||
+'<td><span class="link" onclick="downloadFile(\''+r.zipFileUrl+'\')">下载</span></td>'
|
||||
+'<td>'+r.zipSize+'</td><td>'+statusTag(r.status)+'</td><td style="text-align:left;">'+msg+'</td>'
|
||||
+'<td>'+r.startTime+'</td><td>'+r.endTime+'</td><td>'+(r.parseStartTime||'<span class="muted">—</span>')+'</td><td>'+(r.parseEndTime||'<span class="muted">—</span>')+'</td>'
|
||||
+'<td><span class="link" onclick="openDetail('+idx+')">详情</span> <span class="link-danger" style="margin-left:8px;" onclick="deleteRow('+idx+')">删除</span></td>'
|
||||
+'</tr>';
|
||||
}).join(''):'<tr><td colspan="18"><div class="empty-tip">暂无数据</div></td></tr>';
|
||||
var all=tbody.querySelectorAll('.row-check');
|
||||
var checked=tbody.querySelectorAll('.row-check:checked');
|
||||
document.getElementById('checkAll').checked=all.length>0&&all.length===checked.length;
|
||||
renderPagination(list.length,totalPages);
|
||||
}
|
||||
|
||||
function pageSeq(p,last){
|
||||
var seq=[];
|
||||
if(last<=7){for(var i=1;i<=last;i++)seq.push(i);return seq;}
|
||||
if(p<=4){seq=[1,2,3,4,5,'...',last];}
|
||||
else if(p>=last-3){seq=[1,'...',last-4,last-3,last-2,last-1,last];}
|
||||
else{seq=[1,'...',p-1,p,p+1,'...',last];}
|
||||
return seq;
|
||||
}
|
||||
function renderPagination(total,totalPages){
|
||||
var html='<span>共 '+total+' 条数据</span>';
|
||||
if(totalPages>1){
|
||||
html+='<button class="page-btn"'+(state.page===1?' disabled':'')+' onclick="goPage('+(state.page-1)+')"><</button>';
|
||||
pageSeq(state.page,totalPages).forEach(function(p){
|
||||
if(p==='...')html+='<span class="page-ellipsis">...</span>';
|
||||
else html+='<button class="page-btn'+(p===state.page?' active':'')+'" onclick="goPage('+p+')">'+p+'</button>';
|
||||
});
|
||||
html+='<button class="page-btn"'+(state.page===totalPages?' disabled':'')+' onclick="goPage('+(state.page+1)+')">></button>';
|
||||
}
|
||||
html+='<select class="page-size" onchange="changeSize(this.value)">'
|
||||
+[10,20,50].map(function(n){return '<option value="'+n+'"'+(n===state.pageSize?' selected':'')+'>'+n+'条/页</option>';}).join('')
|
||||
+'</select>';
|
||||
html+='<span class="page-jump">跳至<input type="number" id="jumpInput" min="1" value="'+state.page+'" onkeydown="if(event.key===\'Enter\')jumpTo('+totalPages+')">页<button class="page-btn" onclick="jumpTo('+totalPages+')">跳</button></span>';
|
||||
document.getElementById('pagination').innerHTML=html;
|
||||
}
|
||||
function goPage(p){state.page=p;renderTable();}
|
||||
function changeSize(v){state.pageSize=parseInt(v,10);state.page=1;renderTable();}
|
||||
function jumpTo(totalPages){
|
||||
var input=document.getElementById('jumpInput');
|
||||
var p=parseInt(input.value,10);
|
||||
if(isNaN(p)||p<1)p=1;
|
||||
if(p>totalPages)p=totalPages;
|
||||
state.page=p;
|
||||
renderTable();
|
||||
}
|
||||
|
||||
function downloadFile(url){
|
||||
alert('下载文件:'+url);
|
||||
}
|
||||
function deleteRow(idx){
|
||||
if(!confirm('确认删除该文件处理日志记录?'))return;
|
||||
rows.splice(idx,1);
|
||||
renderTable();
|
||||
}
|
||||
|
||||
function toggleCheckAll(cb){
|
||||
document.querySelectorAll('.row-check').forEach(function(c){c.checked=cb.checked;});
|
||||
}
|
||||
function checkedIdx(){
|
||||
var arr=[];
|
||||
document.querySelectorAll('.row-check:checked').forEach(function(c){arr.push(parseInt(c.dataset.idx,10));});
|
||||
return arr;
|
||||
}
|
||||
function batchDelete(){
|
||||
var idxs=checkedIdx();
|
||||
if(!idxs.length){alert('请先勾选要删除的记录');return;}
|
||||
if(!confirm('确认删除选中的 '+idxs.length+' 条记录?'))return;
|
||||
idxs.sort(function(a,b){return b-a;}).forEach(function(i){rows.splice(i,1);});
|
||||
renderTable();
|
||||
}
|
||||
|
||||
function openDetail(idx){
|
||||
var r=rows[idx];
|
||||
document.getElementById('detailBody').innerHTML=
|
||||
'<table class="detail-table"><tbody>'
|
||||
+'<tr><th>医院名称</th><td>'+r.hospitalName+'</td></tr>'
|
||||
+'<tr><th>姓名</th><td>'+r.realname+'</td></tr>'
|
||||
+'<tr><th>身份证号</th><td>'+r.idCard+'</td></tr>'
|
||||
+'<tr><th>体检年份</th><td>'+r.medicalYear+'</td></tr>'
|
||||
+'<tr><th>体检编号</th><td>'+r.peId+'</td></tr>'
|
||||
+'<tr><th>影像分类</th><td>'+r.imgClass+'</td></tr>'
|
||||
+'<tr><th>json数据</th><td><div class="json-box">'+r.jsonContent+'</div></td></tr>'
|
||||
+'<tr><th>文件地址</th><td>'+r.zipFileUrl+'</td></tr>'
|
||||
+'<tr><th>文件大小(MB)</th><td>'+r.zipSize+'</td></tr>'
|
||||
+'<tr><th>处理状态</th><td>'+handleStatusMap[r.status]+'</td></tr>'
|
||||
+'<tr><th>错误信息</th><td>'+(r.msg||'<span class="muted">—</span>')+'</td></tr>'
|
||||
+'<tr><th>传输开始时间</th><td>'+r.startTime+'</td></tr>'
|
||||
+'<tr><th>传输完成时间</th><td>'+r.endTime+'</td></tr>'
|
||||
+'<tr><th>解析开始时间</th><td>'+(r.parseStartTime||'<span class="muted">—</span>')+'</td></tr>'
|
||||
+'<tr><th>解析完成时间</th><td>'+(r.parseEndTime||'<span class="muted">—</span>')+'</td></tr>'
|
||||
+'</tbody></table>';
|
||||
document.getElementById('detailMask').classList.add('open');
|
||||
}
|
||||
function closeDetail(){document.getElementById('detailMask').classList.remove('open');}
|
||||
document.addEventListener('keydown',function(e){
|
||||
if(e.key==='Escape')closeDetail();
|
||||
});
|
||||
|
||||
function toggleSubgroup(header){
|
||||
header.parentElement.classList.toggle('open');
|
||||
}
|
||||
(function(){
|
||||
renderTable();
|
||||
var active=document.querySelector('.sidebar-item.active');
|
||||
if(!active)return;
|
||||
var sub=active.closest('.sidebar-subgroup');
|
||||
while(sub){ sub.classList.add('open'); sub=sub.parentElement.closest('.sidebar-subgroup'); }
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,658 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>健康体检 - 用户体检信息 | 健康CQ原型</title>
|
||||
<style>
|
||||
*{box-sizing:border-box;margin:0;padding:0;}
|
||||
body{font-family:-apple-system,BlinkMacSystemFont,'PingFang SC','Microsoft YaHei',sans-serif;background:#F5F7FA;color:#333;min-width:1280px;}
|
||||
:root{
|
||||
--primary:#1890FF;--primary-light:#E6F7FF;--success:#52C41A;--warning:#FAAD14;--danger:#FF4D4F;
|
||||
--text-primary:#333;--text-secondary:#666;--text-placeholder:#999;--border:#E8E8E8;--background:#F5F7FA;
|
||||
--font-xs:11px;--font-sm:13px;--font-base:15px;--font-lg:17px;--font-xl:20px;--font-xxl:24px;
|
||||
--radius-sm:4px;--radius-md:8px;--radius-lg:12px;
|
||||
--shadow-sm:0 1px 4px rgba(0,0,0,0.08);--shadow-md:0 4px 12px rgba(0,0,0,0.12);
|
||||
}
|
||||
/* 顶部导航 */
|
||||
.top-bar{display:flex;align-items:center;height:56px;background:#001529;padding:0 24px;position:fixed;top:0;left:0;right:0;z-index:100;}
|
||||
.top-bar__logo{display:flex;align-items:center;gap:8px;color:#fff;font-size:var(--font-lg);font-weight:600;white-space:nowrap;width:240px;flex-shrink:0;}
|
||||
.top-bar__logo svg{width:28px;height:28px;}
|
||||
.top-bar__nav{display:flex;align-items:center;gap:4px;flex:1;}
|
||||
.top-bar__nav a{color:rgba(255,255,255,0.65);text-decoration:none;padding:6px 16px;border-radius:var(--radius-sm);font-size:var(--font-sm);transition:all .2s;}
|
||||
.top-bar__nav a:hover{color:#fff;background:rgba(255,255,255,0.08);}
|
||||
.top-bar__nav a.active{color:#fff;background:var(--primary);}
|
||||
.top-bar__right{display:flex;align-items:center;gap:16px;color:rgba(255,255,255,0.65);font-size:var(--font-sm);}
|
||||
.top-bar__right .btn-back{color:rgba(255,255,255,0.65);cursor:pointer;display:flex;align-items:center;gap:4px;text-decoration:none;}
|
||||
.top-bar__right .btn-back:hover{color:#fff;}
|
||||
.avatar{width:32px;height:32px;border-radius:50%;background:#1890FF;display:flex;align-items:center;justify-content:center;color:#fff;font-size:var(--font-sm);cursor:pointer;}
|
||||
/* 侧边栏 */
|
||||
.sidebar{position:fixed;top:56px;left:0;bottom:0;width:240px;background:#001529;overflow-y:auto;z-index:90;padding-top:8px;}
|
||||
.sidebar-menu__title{color:rgba(255,255,255,0.35);font-size:var(--font-xs);padding:16px 24px 8px;text-transform:uppercase;letter-spacing:.5px;}
|
||||
.sidebar-item{display:flex;align-items:center;gap:8px;padding:10px 24px;color:rgba(255,255,255,0.65);font-size:var(--font-sm);cursor:pointer;transition:all .15s;text-decoration:none;}
|
||||
.sidebar-item:hover{color:#fff;background:rgba(255,255,255,0.06);}
|
||||
.sidebar-item.active{color:#fff;background:var(--primary);}
|
||||
.sidebar-subgroup__header{display:flex;align-items:center;gap:6px;padding:10px 24px;color:rgba(255,255,255,0.65);font-size:var(--font-sm);cursor:pointer;transition:all .15s;user-select:none;}
|
||||
.sidebar-subgroup__header:hover{color:rgba(255,255,255,0.85);background:rgba(255,255,255,0.04);}
|
||||
.sidebar-subgroup__header .arrow{width:10px;height:10px;transition:transform .2s;flex-shrink:0;}
|
||||
.sidebar-subgroup__header .arrow path{stroke:rgba(255,255,255,0.45);}
|
||||
.sidebar-subgroup.open>.sidebar-subgroup__header{color:rgba(255,255,255,0.85);}
|
||||
.sidebar-subgroup.open>.sidebar-subgroup__header .arrow{transform:rotate(90deg);}
|
||||
.sidebar-subgroup__body{display:none;padding-left:16px;}
|
||||
.sidebar-subgroup.open>.sidebar-subgroup__body{display:block;}
|
||||
.sidebar-subgroup__body .sidebar-item{padding-left:36px;font-size:12px;}
|
||||
.sidebar-subgroup .sidebar-subgroup{padding-left:12px;}
|
||||
.sidebar-subgroup .sidebar-subgroup .sidebar-item{padding-left:40px;}
|
||||
.sidebar-subgroup .sidebar-subgroup>.sidebar-subgroup__header{font-size:12px;}
|
||||
/* 主内容 */
|
||||
.main{margin-left:240px;margin-top:56px;padding:24px;min-height:calc(100vh - 56px);}
|
||||
/* 筛选栏 */
|
||||
.filter-bar{background:#fff;border-radius:var(--radius-md);padding:20px 24px;margin-bottom:16px;box-shadow:var(--shadow-sm);display:flex;align-items:center;gap:16px;flex-wrap:wrap;}
|
||||
.filter-item{display:flex;align-items:center;gap:8px;}
|
||||
.filter-item label{font-size:var(--font-sm);color:var(--text-secondary);white-space:nowrap;}
|
||||
.filter-input{height:36px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 12px;font-size:var(--font-sm);color:var(--text-primary);outline:none;background:#fff;min-width:200px;}
|
||||
.filter-input:focus{border-color:var(--primary);}
|
||||
.filter-input::placeholder{color:var(--text-placeholder);}
|
||||
.btn{height:36px;padding:0 16px;border-radius:var(--radius-sm);font-size:var(--font-sm);cursor:pointer;border:none;transition:all .2s;display:inline-flex;align-items:center;gap:6px;}
|
||||
.btn-primary{background:var(--primary);color:#fff;}.btn-primary:hover{background:#40a9ff;}
|
||||
.btn-default{background:#fff;color:var(--text-primary);border:1px solid var(--border);}.btn-default:hover{color:var(--primary);border-color:var(--primary);}
|
||||
/* 体检年份选择控件 */
|
||||
.year-picker{position:relative;}
|
||||
.year-picker .filter-input{padding-right:30px;cursor:pointer;min-width:110px;}
|
||||
.year-picker>svg{position:absolute;right:9px;top:50%;transform:translateY(-50%);pointer-events:none;}
|
||||
.year-picker__dropdown{display:none;position:absolute;top:40px;left:0;width:110px;background:#fff;border:1px solid var(--border);border-radius:var(--radius-sm);box-shadow:var(--shadow-md);z-index:50;max-height:180px;overflow-y:auto;}
|
||||
.year-picker__dropdown.open{display:block;}
|
||||
.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;}
|
||||
/* 表格 */
|
||||
.table-card{background:#fff;border-radius:var(--radius-md);box-shadow:var(--shadow-sm);overflow:hidden;}
|
||||
.table-card__content{overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch;}
|
||||
.table-card__content table{min-width:100%;white-space:nowrap;}
|
||||
table{width:100%;border-collapse:collapse;}
|
||||
thead th{background:#FAFAFA;padding:12px 16px;text-align:center;font-size:var(--font-sm);color:var(--text-secondary);font-weight:500;border-bottom:1px solid var(--border);white-space:nowrap;}
|
||||
tbody td{padding:14px 16px;font-size:var(--font-sm);color:var(--text-primary);border-bottom:1px solid var(--border);white-space:nowrap;text-align:center;}
|
||||
tbody tr:last-child td{border-bottom:none;}
|
||||
tbody tr:hover{background:#F8FBFF;}
|
||||
#userTable thead th:last-child{position:sticky;right:0;background:#FAFAFA;border-left:1px solid var(--border);}
|
||||
#userTable tbody td:last-child{position:sticky;right:0;background:#fff;border-left:1px solid var(--border);}
|
||||
#userTable tbody tr:hover td:last-child{background:#F8FBFF;}
|
||||
.link{color:var(--primary);cursor:pointer;font-size:var(--font-sm);}.link:hover{color:#40a9ff;}
|
||||
.link-danger{color:var(--danger);cursor:pointer;font-size:var(--font-sm);}.link-danger:hover{color:#ff7875;}
|
||||
.empty-tip{padding:48px 0;text-align:center;font-size:var(--font-sm);color:var(--text-placeholder);}
|
||||
/* 展开列 */
|
||||
.expand-toggle{display:inline-flex;width:20px;height:20px;align-items:center;justify-content:center;cursor:pointer;color:var(--text-placeholder);transition:transform .2s,color .2s;}
|
||||
.expand-toggle svg{transition:transform .2s;}
|
||||
.expand-toggle.open{color:var(--primary);}
|
||||
.expand-toggle.open svg{transform:rotate(90deg);}
|
||||
/* 展开子表 */
|
||||
.expand-row td{background:#FAFBFC;padding:0 !important;text-align:left !important;}
|
||||
.expand-row:hover td{background:#FAFBFC !important;}
|
||||
.inner-wrap{padding:12px 20px 16px 52px;}
|
||||
.inner-table{width:100%;border:1px solid var(--border);border-collapse:collapse;background:#fff;}
|
||||
.inner-table th{background:#F5F7FA;padding:9px 14px;font-size:var(--font-sm);color:var(--text-secondary);font-weight:500;border:1px solid var(--border);text-align:center;white-space:nowrap;}
|
||||
.inner-table td{padding:10px 14px;font-size:var(--font-sm);color:var(--text-primary);border:1px solid var(--border);text-align:center;white-space:nowrap;}
|
||||
.inner-empty{color:var(--text-placeholder);font-style:italic;font-size:var(--font-xs);}
|
||||
/* 状态标签 */
|
||||
.tag{display:inline-flex;align-items:center;padding:2px 10px;border-radius:10px;font-size:var(--font-xs);}
|
||||
.tag-blue{background:#E6F7FF;color:#1890FF;}
|
||||
.tag-green{background:#F6FFED;color:#52C41A;}
|
||||
.tag-orange{background:#FFF7E6;color:#FA8C16;}
|
||||
.tag-red{background:#FFF1F0;color:#FF4D4F;}
|
||||
.tag-gray{background:#FAFAFA;color:#999;}
|
||||
/* 分页 */
|
||||
.pagination{display:flex;align-items:center;justify-content:flex-end;padding:16px 24px;gap:8px;border-top:1px solid var(--border);flex-wrap:wrap;}
|
||||
.pagination span{font-size:var(--font-sm);color:var(--text-secondary);}
|
||||
.page-btn{width:32px;height:32px;border:1px solid var(--border);border-radius:var(--radius-sm);background:#fff;cursor:pointer;font-size:var(--font-sm);display:inline-flex;align-items:center;justify-content:center;transition:all .2s;color:var(--text-primary);}
|
||||
.page-btn:hover:not(:disabled),.page-btn.active{background:var(--primary);color:#fff;border-color:var(--primary);}
|
||||
.page-btn:disabled{color:var(--text-placeholder);cursor:not-allowed;background:#FAFAFA;}
|
||||
.page-ellipsis{width:24px;text-align:center;color:var(--text-placeholder);font-size:var(--font-sm);}
|
||||
.page-size{height:32px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 24px 0 10px;font-size:var(--font-sm);color:var(--text-primary);background:#fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%23999'/%3E%3C/svg%3E") no-repeat right 8px center;appearance:none;cursor:pointer;outline:none;}
|
||||
.page-jump input{width:48px;height:32px;border:1px solid var(--border);border-radius:var(--radius-sm);text-align:center;font-size:var(--font-sm);outline:none;margin:0 4px;}
|
||||
.page-jump input:focus{border-color:var(--primary);}
|
||||
/* 弹窗 */
|
||||
.modal-mask{display:none;position:fixed;inset:0;background:rgba(0,0,0,0.45);z-index:200;overflow-y:auto;}
|
||||
.modal-mask.open{display:flex;align-items:flex-start;justify-content:center;padding:60px 24px;}
|
||||
.modal{width:560px;max-width:100%;background:#fff;border-radius:var(--radius-md);box-shadow:var(--shadow-md);display:flex;flex-direction:column;max-height:calc(100vh - 120px);}
|
||||
.modal__header{display:flex;align-items:center;gap:12px;padding:16px 20px;border-bottom:1px solid var(--border);flex-shrink:0;}
|
||||
.modal__close{cursor:pointer;color:var(--text-secondary);display:flex;align-items:center;transition:color .2s;}
|
||||
.modal__close:hover{color:var(--danger);}
|
||||
.modal__title{font-size:var(--font-base);font-weight:600;}
|
||||
.modal__body{padding:20px;overflow-y:auto;}
|
||||
/* 详情 */
|
||||
.detail-table{width:100%;border-collapse:collapse;border:1px solid var(--border);}
|
||||
.detail-table th,.detail-table td{border-bottom:1px solid var(--border);text-align:left;padding:12px 16px;font-size:var(--font-sm);}
|
||||
.detail-table tr:last-child td{border-bottom:none;}
|
||||
.detail-table th{width:120px;background:#FAFAFA;color:var(--text-secondary);font-weight:500;}
|
||||
/* 表单 */
|
||||
.form-item{margin-bottom:16px;}
|
||||
.form-item:last-child{margin-bottom:0;}
|
||||
.form-label{font-size:var(--font-sm);color:var(--text-secondary);margin-bottom:6px;display:flex;align-items:center;gap:4px;font-weight:500;}
|
||||
.form-label .required{color:var(--danger);}
|
||||
.form-input{width:100%;height:36px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 12px;font-size:var(--font-sm);color:var(--text-primary);outline:none;background:#fff;}
|
||||
.form-input:focus{border-color:var(--primary);box-shadow:0 0 0 2px rgba(24,144,255,0.2);}
|
||||
.form-input::placeholder{color:var(--text-placeholder);}
|
||||
.modal__footer{display:flex;justify-content:flex-end;gap:12px;padding:14px 20px;border-top:1px solid var(--border);flex-shrink:0;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- 顶部导航 -->
|
||||
<div class="top-bar">
|
||||
<div class="top-bar__logo">
|
||||
<svg viewBox="0 0 28 28" fill="none"><rect width="28" height="28" rx="6" fill="#1890FF"/><path d="M7 14h14M14 7v14" stroke="#fff" stroke-width="2.5" stroke-linecap="round"/></svg>
|
||||
健康体检
|
||||
</div>
|
||||
<nav class="top-bar__nav">
|
||||
<a href="archive-personal.html">档案</a>
|
||||
<a href="config-material-notice.html">基础配置</a>
|
||||
<a href="pre-hospital-scope.html">检前</a>
|
||||
<a href="mid-appointment-track.html">检中</a>
|
||||
<a href="post-unit-count.html" class="active">检后</a>
|
||||
<a href="exception-dirty.html">异常事件</a>
|
||||
</nav>
|
||||
<div class="top-bar__right">
|
||||
<a class="btn-back" href="../../index.html">
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M10 3L5 8l5 5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
|
||||
返回首页
|
||||
</a>
|
||||
<div class="avatar">管</div>
|
||||
<span style="color:rgba(255,255,255,0.65);">系统管理员 ▾</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 侧边栏 -->
|
||||
<aside class="sidebar">
|
||||
<div class="sidebar-menu__title">检后</div>
|
||||
<div class="sidebar-subgroup">
|
||||
<div class="sidebar-subgroup__header" onclick="toggleSubgroup(this)">
|
||||
<svg class="arrow" viewBox="0 0 12 12"><path d="M4 2l4 4-4 4" fill="none" stroke-width="1.5" stroke-linecap="round"/></svg>
|
||||
常规体检
|
||||
</div>
|
||||
<div class="sidebar-subgroup__body">
|
||||
<a href="post-report-employee.html" class="sidebar-item">常规体检报告</a>
|
||||
<a href="post-employee-master.html" class="sidebar-item">员工体检大表</a>
|
||||
<a href="post-illness-personnel.html" class="sidebar-item">大病人员信息</a>
|
||||
<a href="post-indicator-notify.html" class="sidebar-item">指标异常通知</a>
|
||||
<a href="post-report-unmatched.html" class="sidebar-item">体检报告未匹配项目</a>
|
||||
<div class="sidebar-subgroup">
|
||||
<div class="sidebar-subgroup__header" onclick="toggleSubgroup(this)">
|
||||
<svg class="arrow" viewBox="0 0 12 12"><path d="M4 2l4 4-4 4" fill="none" stroke-width="1.5" stroke-linecap="round"/></svg>
|
||||
体检统计汇总
|
||||
</div>
|
||||
<div class="sidebar-subgroup__body">
|
||||
<a href="post-unit-count.html" class="sidebar-item">单位体检人数统计</a>
|
||||
<a href="post-unit-cost-stat.html" class="sidebar-item">单位体检费用统计</a>
|
||||
<a href="post-hospital-count.html" class="sidebar-item">医院体检人数统计</a>
|
||||
<a href="post-doctor-count.html" class="sidebar-item">医生检查人数统计</a>
|
||||
<a href="post-item-stat.html" class="sidebar-item">医院体检项目统计</a>
|
||||
<a href="post-cancer-screening.html" class="sidebar-item">防癌筛查人数统计</a>
|
||||
<a href="post-standard-stat.html" class="sidebar-item">系统标准化项目统计</a>
|
||||
<a href="post-contracted-hospital.html" class="sidebar-item">签约医院人数统计</a>
|
||||
<a href="post-key-indicator-stat.html" class="sidebar-item">重点指标异常统计</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sidebar-subgroup">
|
||||
<div class="sidebar-subgroup__header" onclick="toggleSubgroup(this)">
|
||||
<svg class="arrow" viewBox="0 0 12 12"><path d="M4 2l4 4-4 4" fill="none" stroke-width="1.5" stroke-linecap="round"/></svg>
|
||||
病种信息管理
|
||||
</div>
|
||||
<div class="sidebar-subgroup__body">
|
||||
<a href="post-disease-info.html" class="sidebar-item">病种信息配置</a>
|
||||
<a href="post-conclusion-disease.html" class="sidebar-item">体检结论关联病种</a>
|
||||
<a href="post-auto-select-disease.html" class="sidebar-item">员工病种信息</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sidebar-subgroup">
|
||||
<div class="sidebar-subgroup__header" onclick="toggleSubgroup(this)">
|
||||
<svg class="arrow" viewBox="0 0 12 12"><path d="M4 2l4 4-4 4" fill="none" stroke-width="1.5" stroke-linecap="round"/></svg>
|
||||
胃肠镜体检
|
||||
</div>
|
||||
<div class="sidebar-subgroup__body">
|
||||
<a href="post-report-gastro.html" class="sidebar-item">胃肠镜体检报告</a>
|
||||
<a href="post-gastro-stat.html" class="sidebar-item">胃肠镜体检统计</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sidebar-subgroup">
|
||||
<div class="sidebar-subgroup__header" onclick="toggleSubgroup(this)">
|
||||
<svg class="arrow" viewBox="0 0 12 12"><path d="M4 2l4 4-4 4" fill="none" stroke-width="1.5" stroke-linecap="round"/></svg>
|
||||
冠脉CTA体检
|
||||
</div>
|
||||
<div class="sidebar-subgroup__body">
|
||||
<a href="post-cta-report.html" class="sidebar-item">冠脉CTA体检报告</a>
|
||||
<a href="post-cta-stat.html" class="sidebar-item">冠脉CTA体检统计</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sidebar-subgroup">
|
||||
<div class="sidebar-subgroup__header" onclick="toggleSubgroup(this)">
|
||||
<svg class="arrow" viewBox="0 0 12 12"><path d="M4 2l4 4-4 4" fill="none" stroke-width="1.5" stroke-linecap="round"/></svg>
|
||||
体检影像管理
|
||||
</div>
|
||||
<div class="sidebar-subgroup__body">
|
||||
<a href="post-imc-user.html" class="sidebar-item active">用户体检信息</a>
|
||||
<a href="post-imc-class.html" class="sidebar-item">用户影像文件分类</a>
|
||||
<a href="post-imc-info.html" class="sidebar-item">用户影像文件详细</a>
|
||||
<a href="post-imc-log.html" class="sidebar-item">文件处理日志</a>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<!-- 主内容 -->
|
||||
<main class="main">
|
||||
<!-- 筛选栏 -->
|
||||
<div class="filter-bar">
|
||||
<div class="filter-item">
|
||||
<label>姓名:</label>
|
||||
<input class="filter-input" type="text" id="f-name" placeholder="请输入姓名" style="min-width:140px;">
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label>身份证号:</label>
|
||||
<input class="filter-input" type="text" id="f-idcard" placeholder="请输入身份证号" style="min-width:180px;">
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label>体检年份:</label>
|
||||
<div class="year-picker">
|
||||
<input class="filter-input" type="text" readonly value="2026" id="f-year">
|
||||
<svg width="14" height="14" viewBox="0 0 14 14" fill="none"><rect x="1.5" y="2.5" width="11" height="10" rx="1.5" stroke="#999" stroke-width="1.2"/><path d="M1.5 5.5h11M4.5 1v3M9.5 1v3" stroke="#999" stroke-width="1.2" stroke-linecap="round"/></svg>
|
||||
<div class="year-picker__dropdown" id="yearDropdown">
|
||||
<div class="selected" onclick="pickYear(this)">2026</div>
|
||||
<div onclick="pickYear(this)">2025</div>
|
||||
<div onclick="pickYear(this)">2024</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label>医院名称:</label>
|
||||
<input class="filter-input" type="text" id="f-hospital" placeholder="请输入医院名称" style="min-width:180px;">
|
||||
</div>
|
||||
<div style="margin-left:auto;display:flex;gap:12px;">
|
||||
<button class="btn btn-primary" onclick="doQuery()">
|
||||
<svg width="14" height="14" viewBox="0 0 14 14" fill="none"><circle cx="6" cy="6" r="4.5" stroke="#fff" stroke-width="1.4"/><path d="M9.5 9.5l3 3" stroke="#fff" stroke-width="1.4" stroke-linecap="round"/></svg>
|
||||
查询
|
||||
</button>
|
||||
<button class="btn btn-default" onclick="doReset()">
|
||||
<svg width="14" height="14" viewBox="0 0 14 14" fill="none"><path d="M12 7a5 5 0 1 1-1.5-3.6M12 1.5V4h-2.5" stroke="#666" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||
重置
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 操作栏 -->
|
||||
<div style="display:flex;gap:12px;margin-bottom:16px;align-items:center;">
|
||||
<button class="btn btn-default" onclick="batchDelete()">
|
||||
<svg width="14" height="14" viewBox="0 0 14 14" fill="none"><path d="M2 3.5h10M5.5 3.5V2h3v1.5M3.5 3.5l.7 8.5h5.6l.7-8.5" stroke="#666" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||
批量删除
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- 数据表格 -->
|
||||
<div class="table-card">
|
||||
<div class="table-card__content">
|
||||
<table id="userTable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width:48px;"><input type="checkbox" id="checkAll" onclick="toggleCheckAll(this)"></th>
|
||||
<th style="width:56px;">序号</th>
|
||||
<th style="width:48px;"></th>
|
||||
<th>单位信息</th>
|
||||
<th>姓名</th>
|
||||
<th>身份证号</th>
|
||||
<th>体检年份</th>
|
||||
<th>医院名称</th>
|
||||
<th>体检编号</th>
|
||||
<th>创建日期</th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="tbody"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="pagination" id="pagination"></div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<!-- 编辑弹窗 -->
|
||||
<div class="modal-mask" id="formMask" onclick="if(event.target===this)closeForm()">
|
||||
<div class="modal">
|
||||
<div class="modal__header">
|
||||
<span class="modal__close" onclick="closeForm()">
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M3.5 3.5l9 9M12.5 3.5l-9 9" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"/></svg>
|
||||
</span>
|
||||
<span class="modal__title" id="formTitle">编辑用户体检信息</span>
|
||||
</div>
|
||||
<div class="modal__body">
|
||||
<div class="form-item">
|
||||
<div class="form-label">单位信息</div>
|
||||
<input class="form-input" id="formUnit" type="text" placeholder="请输入单位信息">
|
||||
</div>
|
||||
<div class="form-item">
|
||||
<div class="form-label"><span class="required">*</span> 姓名</div>
|
||||
<input class="form-input" id="formName" type="text" placeholder="请输入姓名">
|
||||
</div>
|
||||
<div class="form-item">
|
||||
<div class="form-label"><span class="required">*</span> 身份证号</div>
|
||||
<input class="form-input" id="formIdcard" type="text" placeholder="请输入身份证号">
|
||||
</div>
|
||||
<div class="form-item">
|
||||
<div class="form-label">体检年份</div>
|
||||
<input class="form-input" id="formYear" type="text" placeholder="请输入体检年份">
|
||||
</div>
|
||||
<div class="form-item">
|
||||
<div class="form-label">体检编号</div>
|
||||
<input class="form-input" id="formPeid" type="text" placeholder="请输入体检编号">
|
||||
</div>
|
||||
<div class="form-item">
|
||||
<div class="form-label">医院ID</div>
|
||||
<input class="form-input" id="formHospid" type="text" placeholder="请输入医院ID">
|
||||
</div>
|
||||
<div class="form-item">
|
||||
<div class="form-label">医院名称</div>
|
||||
<input class="form-input" id="formHospital" type="text" placeholder="请输入医院名称">
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal__footer">
|
||||
<button class="btn btn-default" onclick="closeForm()">取消</button>
|
||||
<button class="btn btn-primary" onclick="saveForm()">保存</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 详情弹窗 -->
|
||||
<div class="modal-mask" id="detailMask" onclick="if(event.target===this)closeDetail()">
|
||||
<div class="modal">
|
||||
<div class="modal__header">
|
||||
<span class="modal__close" onclick="closeDetail()">
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M3.5 3.5l9 9M12.5 3.5l-9 9" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"/></svg>
|
||||
</span>
|
||||
<span class="modal__title">用户体检信息详情</span>
|
||||
</div>
|
||||
<div class="modal__body" id="detailBody"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
/* ============ 数据 ============ */
|
||||
var handleStatusMap={1:'新建',2:'待解析',3:'失败',4:'解析中',5:'成功',6:'失败待重试',7:'最终失败'};
|
||||
function statusTag(s){
|
||||
var cls='tag-gray';
|
||||
if(s===5)cls='tag-green';
|
||||
else if(s===4||s===6)cls='tag-orange';
|
||||
else if(s===3||s===7)cls='tag-red';
|
||||
else if(s===1)cls='tag-blue';
|
||||
return '<span class="tag '+cls+'">'+handleStatusMap[s]+'</span>';
|
||||
}
|
||||
var users=[
|
||||
{unit:'公司机关',realname:'张伟',idCard:'500103197805121234',medicalYear:'2026',hospitalName:'重庆市人民医院',hospitalId:'H001',peId:'PE20260001',createTime:'2026-08-15 10:23:45',children:[
|
||||
{name:'胸部CT平扫',status:5,studies:['1.2.840.113619.6.55.201','1.2.840.113619.6.55.202'],files:['report_chest_001.pdf']},
|
||||
{name:'头颅MRI平扫',status:5,studies:['1.2.840.113619.6.55.203'],files:['report_mri_001.pdf']},
|
||||
{name:'腹部超声',status:4,studies:['1.2.840.113619.6.55.204'],files:[]}
|
||||
]},
|
||||
{unit:'第一采油厂',realname:'李芳',idCard:'500107198812053467',medicalYear:'2026',hospitalName:'重庆医科大学附属第一医院',hospitalId:'H002',peId:'PE20260002',createTime:'2026-08-15 11:02:18',children:[
|
||||
{name:'胸部CT平扫',status:5,studies:['1.2.840.113619.6.55.301'],files:['report_chest_002.pdf']},
|
||||
{name:'心电图',status:5,studies:['1.2.840.113619.6.55.302'],files:['report_ecg_002.pdf']}
|
||||
]},
|
||||
{unit:'第二采油厂',realname:'王强',idCard:'500105199203154567',medicalYear:'2026',hospitalName:'陆军军医大学西南医院',hospitalId:'H003',peId:'PE20260003',createTime:'2026-08-15 13:45:09',children:[
|
||||
{name:'胸部X射线',status:7,studies:['1.2.840.113619.6.55.401'],files:[]},
|
||||
{name:'腹部超声',status:6,studies:['1.2.840.113619.6.55.402'],files:[]}
|
||||
]},
|
||||
{unit:'公共事务中心',realname:'赵敏',idCard:'500104199001011234',medicalYear:'2026',hospitalName:'陆军特色医学中心',hospitalId:'H004',peId:'PE20260004',createTime:'2026-08-16 09:12:33',children:[
|
||||
{name:'冠脉CTA',status:2,studies:[],files:[]}
|
||||
]},
|
||||
{unit:'公司机关',realname:'陈刚',idCard:'500106198503094567',medicalYear:'2025',hospitalName:'重庆市人民医院',hospitalId:'H001',peId:'PE20250018',createTime:'2025-08-20 15:30:00',children:[
|
||||
{name:'胸部CT平扫',status:5,studies:['1.2.840.113619.6.55.501'],files:['report_chest_018.pdf']},
|
||||
{name:'头颅MRI平扫',status:5,studies:['1.2.840.113619.6.55.502'],files:['report_mri_018.pdf']},
|
||||
{name:'腹部超声',status:5,studies:['1.2.840.113619.6.55.503'],files:['report_us_018.pdf']},
|
||||
{name:'心电图',status:5,studies:['1.2.840.113619.6.55.504'],files:['report_ecg_018.pdf']}
|
||||
]},
|
||||
{unit:'第一采油厂',realname:'刘洋',idCard:'500102199511223456',medicalYear:'2025',hospitalName:'重庆医科大学附属第一医院',hospitalId:'H002',peId:'PE20250021',createTime:'2025-08-21 10:05:52',children:[
|
||||
{name:'胸部CT平扫',status:5,studies:['1.2.840.113619.6.55.601'],files:['report_chest_021.pdf']},
|
||||
{name:'腹部超声',status:7,studies:['1.2.840.113619.6.55.602'],files:[]}
|
||||
]}
|
||||
];
|
||||
var state={name:'',idcard:'',year:'2026',hospital:'',page:1,pageSize:10};
|
||||
var expanded={};
|
||||
|
||||
/* ============ 年份选择 ============ */
|
||||
function toggleYear(){document.getElementById('yearDropdown').classList.toggle('open');}
|
||||
function pickYear(el){
|
||||
document.getElementById('f-year').value=el.textContent.trim();
|
||||
document.getElementById('yearDropdown').classList.remove('open');
|
||||
document.querySelectorAll('#yearDropdown div').forEach(function(d){d.classList.remove('selected');});
|
||||
el.classList.add('selected');
|
||||
}
|
||||
document.getElementById('f-year').addEventListener('click',toggleYear);
|
||||
document.addEventListener('click',function(e){
|
||||
if(!e.target.closest('.year-picker'))document.getElementById('yearDropdown').classList.remove('open');
|
||||
});
|
||||
|
||||
/* ============ 查询/重置 ============ */
|
||||
function doQuery(){
|
||||
state.name=document.getElementById('f-name').value.trim();
|
||||
state.idcard=document.getElementById('f-idcard').value.trim();
|
||||
state.year=document.getElementById('f-year').value.trim();
|
||||
state.hospital=document.getElementById('f-hospital').value.trim();
|
||||
state.page=1;
|
||||
expanded={};
|
||||
renderTable();
|
||||
}
|
||||
function doReset(){
|
||||
document.getElementById('f-name').value='';
|
||||
document.getElementById('f-idcard').value='';
|
||||
document.getElementById('f-year').value='2026';
|
||||
document.querySelectorAll('#yearDropdown div').forEach(function(d){
|
||||
d.classList.toggle('selected',d.textContent.trim()==='2026');
|
||||
});
|
||||
document.getElementById('f-hospital').value='';
|
||||
state.name='';state.idcard='';state.year='2026';state.hospital='';
|
||||
state.page=1;
|
||||
expanded={};
|
||||
renderTable();
|
||||
}
|
||||
|
||||
/* ============ 表格渲染 ============ */
|
||||
function filteredIdx(){
|
||||
var list=[];
|
||||
users.forEach(function(u,i){
|
||||
if(state.name&&u.realname.indexOf(state.name)===-1)return;
|
||||
if(state.idcard&&u.idCard.indexOf(state.idcard)===-1)return;
|
||||
if(state.year&&u.medicalYear!==state.year)return;
|
||||
if(state.hospital&&u.hospitalName.indexOf(state.hospital)===-1)return;
|
||||
list.push(i);
|
||||
});
|
||||
return list;
|
||||
}
|
||||
function renderTable(){
|
||||
var list=filteredIdx();
|
||||
var totalPages=Math.max(1,Math.ceil(list.length/state.pageSize));
|
||||
if(state.page>totalPages)state.page=totalPages;
|
||||
var start=(state.page-1)*state.pageSize;
|
||||
var pageIdx=list.slice(start,start+state.pageSize);
|
||||
var tbody=document.getElementById('tbody');
|
||||
tbody.innerHTML=pageIdx.length?pageIdx.map(function(i,pos){
|
||||
var u=users[i];
|
||||
var isOpen=!!expanded[i];
|
||||
var html='<tr>'
|
||||
+'<td><input type="checkbox" class="row-check" data-idx="'+i+'"></td>'
|
||||
+'<td>'+(start+pos+1)+'</td>'
|
||||
+'<td><span class="expand-toggle'+(isOpen?' open':'')+'" onclick="toggleExpand('+i+')">'
|
||||
+'<svg width="12" height="12" viewBox="0 0 12 12"><path d="M4 2l4 4-4 4" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>'
|
||||
+'</span></td>'
|
||||
+'<td>'+u.unit+'</td><td>'+u.realname+'</td><td>'+u.idCard+'</td><td>'+u.medicalYear+'</td>'
|
||||
+'<td>'+u.hospitalName+'</td><td>'+u.peId+'</td><td>'+u.createTime+'</td>'
|
||||
+'<td><span class="link" onclick="openForm('+i+')">编辑</span> <span class="link" style="margin-left:8px;" onclick="openDetail('+i+')">详情</span> <span class="link-danger" style="margin-left:8px;" onclick="deleteRow('+i+')">删除</span></td>'
|
||||
+'</tr>';
|
||||
if(isOpen)html+=renderExpandRow(i);
|
||||
return html;
|
||||
}).join(''):'<tr><td colspan="11"><div class="empty-tip">暂无数据</div></td></tr>';
|
||||
var all=tbody.querySelectorAll('.row-check');
|
||||
var checked=tbody.querySelectorAll('.row-check:checked');
|
||||
document.getElementById('checkAll').checked=all.length>0&&all.length===checked.length;
|
||||
renderPagination(list.length,totalPages);
|
||||
}
|
||||
function renderExpandRow(i){
|
||||
var u=users[i];
|
||||
var body='';
|
||||
if(!u.children.length){
|
||||
body='<tr><td colspan="4"><div class="inner-empty" style="padding:16px 0;text-align:center;">暂无检查项目数据</div></td></tr>';
|
||||
}else{
|
||||
body=u.children.map(function(c){
|
||||
var studiesHtml=c.studies.length?c.studies.map(function(s){
|
||||
return '<span class="link" style="margin-right:6px;" onclick="previewStudy(\''+s+'\')">预览</span>';
|
||||
}).join(''):'<span class="inner-empty">暂无</span>';
|
||||
var filesHtml=c.files.length?c.files.map(function(f){
|
||||
return '<span class="link" style="margin-right:6px;" onclick="viewReport(\''+f+'\')">查看</span>';
|
||||
}).join(''):'<span class="inner-empty">无文件</span>';
|
||||
return '<tr><td>'+c.name+'</td><td>'+statusTag(c.status)+'</td><td>'+studiesHtml+'</td><td>'+filesHtml+'</td></tr>';
|
||||
}).join('');
|
||||
}
|
||||
return '<tr class="expand-row"><td colspan="11"><div class="inner-wrap">'
|
||||
+'<table class="inner-table"><thead><tr>'
|
||||
+'<th>检查项目名称</th><th>处理状态</th><th>影像信息</th><th>影像报告</th>'
|
||||
+'</tr></thead><tbody>'+body+'</tbody></table>'
|
||||
+'</div></td></tr>';
|
||||
}
|
||||
function toggleExpand(i){
|
||||
if(expanded[i])delete expanded[i];else expanded[i]=true;
|
||||
renderTable();
|
||||
}
|
||||
|
||||
/* ============ 分页 ============ */
|
||||
function pageSeq(p,last){
|
||||
var seq=[];
|
||||
if(last<=7){for(var i=1;i<=last;i++)seq.push(i);return seq;}
|
||||
if(p<=4){seq=[1,2,3,4,5,'...',last];}
|
||||
else if(p>=last-3){seq=[1,'...',last-4,last-3,last-2,last-1,last];}
|
||||
else{seq=[1,'...',p-1,p,p+1,'...',last];}
|
||||
return seq;
|
||||
}
|
||||
function renderPagination(total,totalPages){
|
||||
var html='<span>共 '+total+' 条数据</span>';
|
||||
if(totalPages>1){
|
||||
html+='<button class="page-btn"'+(state.page===1?' disabled':'')+' onclick="goPage('+(state.page-1)+')"><</button>';
|
||||
pageSeq(state.page,totalPages).forEach(function(p){
|
||||
if(p==='...')html+='<span class="page-ellipsis">...</span>';
|
||||
else html+='<button class="page-btn'+(p===state.page?' active':'')+'" onclick="goPage('+p+')">'+p+'</button>';
|
||||
});
|
||||
html+='<button class="page-btn"'+(state.page===totalPages?' disabled':'')+' onclick="goPage('+(state.page+1)+')">></button>';
|
||||
}
|
||||
html+='<select class="page-size" onchange="changeSize(this.value)">'
|
||||
+[10,20,50].map(function(n){return '<option value="'+n+'"'+(n===state.pageSize?' selected':'')+'>'+n+'条/页</option>';}).join('')
|
||||
+'</select>';
|
||||
html+='<span class="page-jump">跳至<input type="number" id="jumpInput" min="1" value="'+state.page+'" onkeydown="if(event.key===\'Enter\')jumpTo('+totalPages+')">页<button class="page-btn" onclick="jumpTo('+totalPages+')">跳</button></span>';
|
||||
document.getElementById('pagination').innerHTML=html;
|
||||
}
|
||||
function goPage(p){state.page=p;renderTable();}
|
||||
function changeSize(v){state.pageSize=parseInt(v,10);state.page=1;renderTable();}
|
||||
function jumpTo(totalPages){
|
||||
var input=document.getElementById('jumpInput');
|
||||
var p=parseInt(input.value,10);
|
||||
if(isNaN(p)||p<1)p=1;
|
||||
if(p>totalPages)p=totalPages;
|
||||
state.page=p;
|
||||
renderTable();
|
||||
}
|
||||
|
||||
/* ============ 影像预览/报告 ============ */
|
||||
function previewStudy(sid){
|
||||
alert('影像预览(Orthanc Web Viewer)\n研究实例ID:'+sid);
|
||||
}
|
||||
function viewReport(furl){
|
||||
alert('下载影像报告\n文件:'+furl);
|
||||
}
|
||||
|
||||
/* ============ 删除 ============ */
|
||||
function deleteRow(idx){
|
||||
var u=users[idx];
|
||||
if(!confirm('确认删除「'+u.realname+'」的体检影像信息?'))return;
|
||||
users.splice(idx,1);
|
||||
delete expanded[idx];
|
||||
renderTable();
|
||||
}
|
||||
|
||||
/* ============ 勾选 / 批量删除 ============ */
|
||||
function toggleCheckAll(cb){
|
||||
document.querySelectorAll('.row-check').forEach(function(c){c.checked=cb.checked;});
|
||||
}
|
||||
function checkedIdx(){
|
||||
var arr=[];
|
||||
document.querySelectorAll('.row-check:checked').forEach(function(c){arr.push(parseInt(c.dataset.idx,10));});
|
||||
return arr;
|
||||
}
|
||||
function batchDelete(){
|
||||
var idxs=checkedIdx();
|
||||
if(!idxs.length){alert('请先勾选要删除的记录');return;}
|
||||
if(!confirm('确认删除选中的 '+idxs.length+' 条体检影像信息?'))return;
|
||||
idxs.sort(function(a,b){return b-a;}).forEach(function(i){users.splice(i,1);delete expanded[i];});
|
||||
renderTable();
|
||||
}
|
||||
|
||||
/* ============ 详情 ============ */
|
||||
function openDetail(idx){
|
||||
var u=users[idx];
|
||||
document.getElementById('detailBody').innerHTML=
|
||||
'<table class="detail-table"><tbody>'
|
||||
+'<tr><th>单位信息</th><td>'+u.unit+'</td></tr>'
|
||||
+'<tr><th>姓名</th><td>'+u.realname+'</td></tr>'
|
||||
+'<tr><th>身份证号</th><td>'+u.idCard+'</td></tr>'
|
||||
+'<tr><th>体检年份</th><td>'+u.medicalYear+'</td></tr>'
|
||||
+'<tr><th>体检编号</th><td>'+u.peId+'</td></tr>'
|
||||
+'<tr><th>医院ID</th><td>'+u.hospitalId+'</td></tr>'
|
||||
+'<tr><th>医院名称</th><td>'+u.hospitalName+'</td></tr>'
|
||||
+'</tbody></table>';
|
||||
document.getElementById('detailMask').classList.add('open');
|
||||
}
|
||||
function closeDetail(){document.getElementById('detailMask').classList.remove('open');}
|
||||
|
||||
/* ============ 编辑 ============ */
|
||||
var editingIdx=null;
|
||||
function openForm(idx){
|
||||
editingIdx=idx;
|
||||
document.getElementById('formTitle').textContent='编辑用户体检信息';
|
||||
var u=users[idx];
|
||||
document.getElementById('formUnit').value=u.unit;
|
||||
document.getElementById('formName').value=u.realname;
|
||||
document.getElementById('formIdcard').value=u.idCard;
|
||||
document.getElementById('formYear').value=u.medicalYear;
|
||||
document.getElementById('formPeid').value=u.peId;
|
||||
document.getElementById('formHospid').value=u.hospitalId;
|
||||
document.getElementById('formHospital').value=u.hospitalName;
|
||||
document.getElementById('formMask').classList.add('open');
|
||||
}
|
||||
function closeForm(){document.getElementById('formMask').classList.remove('open');}
|
||||
function saveForm(){
|
||||
var name=document.getElementById('formName').value.trim();
|
||||
var idcard=document.getElementById('formIdcard').value.trim();
|
||||
if(!name){alert('请输入姓名');return;}
|
||||
if(!idcard){alert('请输入身份证号');return;}
|
||||
var u=users[editingIdx];
|
||||
u.unit=document.getElementById('formUnit').value.trim();
|
||||
u.realname=name;
|
||||
u.idCard=idcard;
|
||||
u.medicalYear=document.getElementById('formYear').value.trim();
|
||||
u.peId=document.getElementById('formPeid').value.trim();
|
||||
u.hospitalId=document.getElementById('formHospid').value.trim();
|
||||
u.hospitalName=document.getElementById('formHospital').value.trim();
|
||||
closeForm();
|
||||
renderTable();
|
||||
}
|
||||
document.addEventListener('keydown',function(e){
|
||||
if(e.key==='Escape'){closeForm();closeDetail();}
|
||||
});
|
||||
|
||||
/* ============ 通用 ============ */
|
||||
function toggleSubgroup(header){
|
||||
header.parentElement.classList.toggle('open');
|
||||
}
|
||||
/* 页面加载时自动展开当前页面所在的子分组 */
|
||||
(function(){
|
||||
renderTable();
|
||||
var active=document.querySelector('.sidebar-item.active');
|
||||
if(!active)return;
|
||||
var sub=active.closest('.sidebar-subgroup');
|
||||
while(sub){ sub.classList.add('open'); sub=sub.parentElement.closest('.sidebar-subgroup'); }
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -180,6 +180,18 @@
|
||||
<a href="post-cta-stat.html" class="sidebar-item">冠脉CTA体检统计</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sidebar-subgroup">
|
||||
<div class="sidebar-subgroup__header" onclick="toggleSubgroup(this)">
|
||||
<svg class="arrow" viewBox="0 0 12 12"><path d="M4 2l4 4-4 4" fill="none" stroke-width="1.5" stroke-linecap="round"/></svg>
|
||||
体检影像管理
|
||||
</div>
|
||||
<div class="sidebar-subgroup__body">
|
||||
<a href="post-imc-user.html" class="sidebar-item">用户体检信息</a>
|
||||
<a href="post-imc-class.html" class="sidebar-item">用户影像文件分类</a>
|
||||
<a href="post-imc-info.html" class="sidebar-item">用户影像文件详细</a>
|
||||
<a href="post-imc-log.html" class="sidebar-item">文件处理日志</a>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<!-- 主内容 -->
|
||||
|
||||
@@ -172,6 +172,18 @@
|
||||
<a href="post-cta-stat.html" class="sidebar-item">冠脉CTA体检统计</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sidebar-subgroup">
|
||||
<div class="sidebar-subgroup__header" onclick="toggleSubgroup(this)">
|
||||
<svg class="arrow" viewBox="0 0 12 12"><path d="M4 2l4 4-4 4" fill="none" stroke-width="1.5" stroke-linecap="round"/></svg>
|
||||
体检影像管理
|
||||
</div>
|
||||
<div class="sidebar-subgroup__body">
|
||||
<a href="post-imc-user.html" class="sidebar-item">用户体检信息</a>
|
||||
<a href="post-imc-class.html" class="sidebar-item">用户影像文件分类</a>
|
||||
<a href="post-imc-info.html" class="sidebar-item">用户影像文件详细</a>
|
||||
<a href="post-imc-log.html" class="sidebar-item">文件处理日志</a>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<!-- 主内容 -->
|
||||
|
||||
@@ -205,6 +205,18 @@
|
||||
<a href="post-cta-stat.html" class="sidebar-item">冠脉CTA体检统计</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sidebar-subgroup">
|
||||
<div class="sidebar-subgroup__header" onclick="toggleSubgroup(this)">
|
||||
<svg class="arrow" viewBox="0 0 12 12"><path d="M4 2l4 4-4 4" fill="none" stroke-width="1.5" stroke-linecap="round"/></svg>
|
||||
体检影像管理
|
||||
</div>
|
||||
<div class="sidebar-subgroup__body">
|
||||
<a href="post-imc-user.html" class="sidebar-item">用户体检信息</a>
|
||||
<a href="post-imc-class.html" class="sidebar-item">用户影像文件分类</a>
|
||||
<a href="post-imc-info.html" class="sidebar-item">用户影像文件详细</a>
|
||||
<a href="post-imc-log.html" class="sidebar-item">文件处理日志</a>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<!-- 主内容 -->
|
||||
|
||||
@@ -207,6 +207,18 @@
|
||||
<a href="post-cta-stat.html" class="sidebar-item">冠脉CTA体检统计</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sidebar-subgroup">
|
||||
<div class="sidebar-subgroup__header" onclick="toggleSubgroup(this)">
|
||||
<svg class="arrow" viewBox="0 0 12 12"><path d="M4 2l4 4-4 4" fill="none" stroke-width="1.5" stroke-linecap="round"/></svg>
|
||||
体检影像管理
|
||||
</div>
|
||||
<div class="sidebar-subgroup__body">
|
||||
<a href="post-imc-user.html" class="sidebar-item">用户体检信息</a>
|
||||
<a href="post-imc-class.html" class="sidebar-item">用户影像文件分类</a>
|
||||
<a href="post-imc-info.html" class="sidebar-item">用户影像文件详细</a>
|
||||
<a href="post-imc-log.html" class="sidebar-item">文件处理日志</a>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<!-- 主内容 -->
|
||||
|
||||
@@ -258,6 +258,18 @@
|
||||
<a href="post-cta-stat.html" class="sidebar-item">冠脉CTA体检统计</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sidebar-subgroup">
|
||||
<div class="sidebar-subgroup__header" onclick="toggleSubgroup(this)">
|
||||
<svg class="arrow" viewBox="0 0 12 12"><path d="M4 2l4 4-4 4" fill="none" stroke-width="1.5" stroke-linecap="round"/></svg>
|
||||
体检影像管理
|
||||
</div>
|
||||
<div class="sidebar-subgroup__body">
|
||||
<a href="post-imc-user.html" class="sidebar-item">用户体检信息</a>
|
||||
<a href="post-imc-class.html" class="sidebar-item">用户影像文件分类</a>
|
||||
<a href="post-imc-info.html" class="sidebar-item">用户影像文件详细</a>
|
||||
<a href="post-imc-log.html" class="sidebar-item">文件处理日志</a>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<!-- 主内容 -->
|
||||
|
||||
@@ -191,6 +191,18 @@
|
||||
<a href="post-cta-stat.html" class="sidebar-item">冠脉CTA体检统计</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sidebar-subgroup">
|
||||
<div class="sidebar-subgroup__header" onclick="toggleSubgroup(this)">
|
||||
<svg class="arrow" viewBox="0 0 12 12"><path d="M4 2l4 4-4 4" fill="none" stroke-width="1.5" stroke-linecap="round"/></svg>
|
||||
体检影像管理
|
||||
</div>
|
||||
<div class="sidebar-subgroup__body">
|
||||
<a href="post-imc-user.html" class="sidebar-item">用户体检信息</a>
|
||||
<a href="post-imc-class.html" class="sidebar-item">用户影像文件分类</a>
|
||||
<a href="post-imc-info.html" class="sidebar-item">用户影像文件详细</a>
|
||||
<a href="post-imc-log.html" class="sidebar-item">文件处理日志</a>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<!-- 主内容 -->
|
||||
|
||||
@@ -181,6 +181,18 @@
|
||||
<a href="post-cta-stat.html" class="sidebar-item">冠脉CTA体检统计</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sidebar-subgroup">
|
||||
<div class="sidebar-subgroup__header" onclick="toggleSubgroup(this)">
|
||||
<svg class="arrow" viewBox="0 0 12 12"><path d="M4 2l4 4-4 4" fill="none" stroke-width="1.5" stroke-linecap="round"/></svg>
|
||||
体检影像管理
|
||||
</div>
|
||||
<div class="sidebar-subgroup__body">
|
||||
<a href="post-imc-user.html" class="sidebar-item">用户体检信息</a>
|
||||
<a href="post-imc-class.html" class="sidebar-item">用户影像文件分类</a>
|
||||
<a href="post-imc-info.html" class="sidebar-item">用户影像文件详细</a>
|
||||
<a href="post-imc-log.html" class="sidebar-item">文件处理日志</a>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<!-- 主内容 -->
|
||||
|
||||
@@ -202,6 +202,18 @@
|
||||
<a href="post-cta-stat.html" class="sidebar-item">冠脉CTA体检统计</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sidebar-subgroup">
|
||||
<div class="sidebar-subgroup__header" onclick="toggleSubgroup(this)">
|
||||
<svg class="arrow" viewBox="0 0 12 12"><path d="M4 2l4 4-4 4" fill="none" stroke-width="1.5" stroke-linecap="round"/></svg>
|
||||
体检影像管理
|
||||
</div>
|
||||
<div class="sidebar-subgroup__body">
|
||||
<a href="post-imc-user.html" class="sidebar-item">用户体检信息</a>
|
||||
<a href="post-imc-class.html" class="sidebar-item">用户影像文件分类</a>
|
||||
<a href="post-imc-info.html" class="sidebar-item">用户影像文件详细</a>
|
||||
<a href="post-imc-log.html" class="sidebar-item">文件处理日志</a>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<!-- 主内容 -->
|
||||
|
||||
@@ -211,6 +211,18 @@
|
||||
<a href="post-cta-stat.html" class="sidebar-item">冠脉CTA体检统计</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sidebar-subgroup">
|
||||
<div class="sidebar-subgroup__header" onclick="toggleSubgroup(this)">
|
||||
<svg class="arrow" viewBox="0 0 12 12"><path d="M4 2l4 4-4 4" fill="none" stroke-width="1.5" stroke-linecap="round"/></svg>
|
||||
体检影像管理
|
||||
</div>
|
||||
<div class="sidebar-subgroup__body">
|
||||
<a href="post-imc-user.html" class="sidebar-item">用户体检信息</a>
|
||||
<a href="post-imc-class.html" class="sidebar-item">用户影像文件分类</a>
|
||||
<a href="post-imc-info.html" class="sidebar-item">用户影像文件详细</a>
|
||||
<a href="post-imc-log.html" class="sidebar-item">文件处理日志</a>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<!-- 主内容 -->
|
||||
|
||||
Reference in New Issue
Block a user