Capture the confirmed sample-level JSON payload approach, field maps from the Excel sheets, and UI entry points for QC fill and market view. Co-authored-by: Cursor <cursoragent@cursor.com>
856 lines
41 KiB
HTML
856 lines
41 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="UTF-8" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||
<title>储存证质检信息 · 填写 / 查看 Demo</title>
|
||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet" />
|
||
<style>
|
||
:root {
|
||
--primary: #10b981;
|
||
--primary-dark: #059669;
|
||
--primary-bg: #ecfdf5;
|
||
--bg-page: #f8fafc;
|
||
--panel: #ffffff;
|
||
--text: #0f172a;
|
||
--text-secondary: #334155;
|
||
--text-muted: #64748b;
|
||
--border: #e2e8f0;
|
||
--border-mint: #d9e8e2;
|
||
--radius: 10px;
|
||
--radius-sm: 8px;
|
||
--shadow: 0 1px 3px rgba(15, 23, 42, 0.06);
|
||
--warning: #d97706;
|
||
--warning-bg: #fffbeb;
|
||
--danger: #dc2626;
|
||
--info: #64748b;
|
||
}
|
||
* { box-sizing: border-box; }
|
||
body {
|
||
margin: 0;
|
||
font-family: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
||
font-size: 14px;
|
||
line-height: 1.5;
|
||
color: var(--text);
|
||
background: var(--bg-page);
|
||
}
|
||
.page {
|
||
max-width: 1180px;
|
||
margin: 0 auto;
|
||
padding: 24px 20px 80px;
|
||
}
|
||
.hero { margin-bottom: 20px; max-width: 920px; }
|
||
.hero h1 {
|
||
margin: 0 0 8px;
|
||
font-size: 22px;
|
||
font-weight: 700;
|
||
letter-spacing: -0.02em;
|
||
}
|
||
.hero h1::before {
|
||
content: "";
|
||
display: inline-block;
|
||
width: 4px;
|
||
height: 1.1em;
|
||
margin-right: 10px;
|
||
vertical-align: -0.15em;
|
||
border-radius: 2px;
|
||
background: var(--primary);
|
||
}
|
||
.hero p { margin: 0 0 8px; color: var(--text-muted); }
|
||
.context-bar { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
|
||
.pill {
|
||
display: inline-flex; align-items: center; gap: 6px;
|
||
padding: 4px 10px; border-radius: 999px; font-size: 12px;
|
||
background: var(--primary-bg); color: var(--primary-dark);
|
||
border: 1px solid #a7f3d0;
|
||
}
|
||
.pill.muted {
|
||
background: #f1f5f9; color: var(--text-muted); border-color: var(--border);
|
||
}
|
||
|
||
/* Scene tabs */
|
||
.scene-tabs {
|
||
display: flex; flex-wrap: wrap; gap: 8px;
|
||
margin-bottom: 16px; padding: 4px;
|
||
background: #fff; border: 1px solid var(--border); border-radius: var(--radius);
|
||
}
|
||
.scene-tab {
|
||
border: 1px solid transparent; background: transparent;
|
||
padding: 8px 14px; border-radius: 8px; cursor: pointer;
|
||
font-size: 13px; font-weight: 500; color: var(--text-secondary);
|
||
}
|
||
.scene-tab:hover { background: #f8fafc; }
|
||
.scene-tab.active {
|
||
background: var(--primary-bg); color: var(--primary-dark);
|
||
border-color: #a7f3d0;
|
||
}
|
||
.scene { display: none; }
|
||
.scene.active { display: block; }
|
||
|
||
.section {
|
||
background: var(--panel);
|
||
border: 1px solid var(--border);
|
||
border-radius: var(--radius);
|
||
padding: 18px 20px;
|
||
margin-bottom: 16px;
|
||
box-shadow: var(--shadow);
|
||
}
|
||
.section-head {
|
||
display: flex; align-items: flex-start; justify-content: space-between;
|
||
gap: 12px; margin-bottom: 14px;
|
||
}
|
||
.section-head h2 {
|
||
margin: 0; font-size: 16px; font-weight: 600;
|
||
}
|
||
.section-head .hint { margin: 4px 0 0; font-size: 12px; color: var(--text-muted); }
|
||
|
||
.note {
|
||
padding: 10px 12px; border-radius: 8px;
|
||
background: var(--warning-bg); border: 1px solid #fde68a;
|
||
color: #92400e; font-size: 13px; margin-bottom: 14px;
|
||
}
|
||
.note.ok {
|
||
background: var(--primary-bg); border-color: #a7f3d0; color: var(--primary-dark);
|
||
}
|
||
|
||
/* QC card mock */
|
||
.protocol-bar {
|
||
display: flex; flex-wrap: wrap; gap: 10px 16px; align-items: center;
|
||
padding: 10px 12px; background: #f8fafc; border: 1px solid var(--border);
|
||
border-radius: 8px; margin-bottom: 12px; font-size: 13px;
|
||
}
|
||
.protocol-bar strong { color: var(--text); }
|
||
.sample-pills { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 12px; }
|
||
.sample-pill {
|
||
padding: 6px 12px; border-radius: 999px; font-size: 12px;
|
||
border: 1px solid var(--border); background: #fff; color: var(--text-secondary);
|
||
cursor: pointer;
|
||
}
|
||
.sample-pill.active {
|
||
border-color: var(--primary); background: var(--primary-bg); color: var(--primary-dark);
|
||
font-weight: 600;
|
||
}
|
||
.wo-card {
|
||
border: 1px solid var(--border-mint);
|
||
border-radius: 10px;
|
||
padding: 14px 16px;
|
||
background: #fff;
|
||
}
|
||
.wo-card-top {
|
||
display: flex; flex-wrap: wrap; justify-content: space-between;
|
||
gap: 10px; margin-bottom: 10px;
|
||
}
|
||
.wo-meta { font-size: 13px; color: var(--text-secondary); }
|
||
.wo-meta .code { font-weight: 600; color: var(--text); }
|
||
.tag {
|
||
display: inline-flex; align-items: center;
|
||
padding: 2px 8px; border-radius: 4px; font-size: 12px; font-weight: 500;
|
||
}
|
||
.tag.success { background: var(--primary-bg); color: var(--primary-dark); }
|
||
.tag.warning { background: var(--warning-bg); color: var(--warning); }
|
||
.tag.info { background: #f1f5f9; color: var(--info); }
|
||
.wo-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
|
||
.btn {
|
||
display: inline-flex; align-items: center; gap: 6px;
|
||
height: 32px; padding: 0 12px; border-radius: 8px;
|
||
border: 1px solid var(--border); background: #fff;
|
||
font-size: 13px; color: var(--text-secondary); cursor: pointer;
|
||
}
|
||
.btn:hover { border-color: #94a3b8; }
|
||
.btn.primary {
|
||
background: var(--primary); border-color: var(--primary);
|
||
color: #fff; font-weight: 500;
|
||
}
|
||
.btn.primary:hover { background: var(--primary-dark); border-color: var(--primary-dark); }
|
||
.btn.accent {
|
||
background: var(--primary-bg); border-color: #a7f3d0;
|
||
color: var(--primary-dark); font-weight: 500;
|
||
}
|
||
.btn.ghost { background: transparent; }
|
||
.btn.sm { height: 28px; padding: 0 10px; font-size: 12px; }
|
||
.btn-icon {
|
||
width: 14px; height: 14px; display: inline-block;
|
||
border: 1.5px solid currentColor; border-radius: 3px; opacity: 0.85;
|
||
}
|
||
|
||
/* Sample info table mock */
|
||
.toolbar {
|
||
display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
|
||
margin-bottom: 12px;
|
||
}
|
||
.toolbar .selected { font-size: 13px; color: var(--text-muted); margin-right: 4px; }
|
||
.table-wrap { overflow-x: auto; border: 1px solid var(--border); border-radius: 8px; }
|
||
table.list {
|
||
width: 100%; border-collapse: collapse; min-width: 900px;
|
||
}
|
||
table.list th, table.list td {
|
||
padding: 10px 12px; text-align: left; border-bottom: 1px solid var(--border);
|
||
font-size: 13px; white-space: nowrap;
|
||
}
|
||
table.list th {
|
||
background: #f8fafc; color: var(--text-muted); font-weight: 600; font-size: 12px;
|
||
}
|
||
table.list tr:nth-child(even) td { background: #fafafa; }
|
||
table.list tr:hover td { background: #f1f5f9; }
|
||
table.list tr.highlight td { background: #ecfdf5; }
|
||
.ops { display: flex; gap: 6px; flex-wrap: wrap; }
|
||
|
||
/* Dialog */
|
||
.dialog-mask {
|
||
position: fixed; inset: 0; background: rgba(15, 23, 42, 0.45);
|
||
display: none; align-items: flex-start; justify-content: center;
|
||
padding: 40px 16px; z-index: 50; overflow-y: auto;
|
||
backdrop-filter: none;
|
||
}
|
||
.dialog-mask.open { display: flex; }
|
||
.dialog {
|
||
width: min(920px, 100%);
|
||
background: #fff; border-radius: 12px;
|
||
box-shadow: 0 20px 40px rgba(15, 23, 42, 0.18);
|
||
display: flex; flex-direction: column;
|
||
max-height: calc(100vh - 80px);
|
||
}
|
||
.dialog.wide { width: min(1020px, 100%); }
|
||
.dialog-header {
|
||
display: flex; align-items: center; justify-content: space-between;
|
||
padding: 16px 20px; border-bottom: 1px solid var(--border);
|
||
flex-shrink: 0;
|
||
}
|
||
.dialog-header h3 { margin: 0; font-size: 16px; font-weight: 600; }
|
||
.dialog-header .sub {
|
||
margin: 4px 0 0; font-size: 12px; color: var(--text-muted); font-weight: 400;
|
||
}
|
||
.dialog-close {
|
||
width: 32px; height: 32px; border: none; background: #f1f5f9;
|
||
border-radius: 8px; cursor: pointer; font-size: 18px; color: var(--text-muted);
|
||
}
|
||
.dialog-body {
|
||
padding: 16px 20px; overflow-y: auto; flex: 1;
|
||
}
|
||
.dialog-footer {
|
||
display: flex; justify-content: flex-end; gap: 8px;
|
||
padding: 12px 20px; border-top: 1px solid var(--border);
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.ctx-row {
|
||
display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px;
|
||
margin-bottom: 16px; padding: 12px; background: #f8fafc;
|
||
border: 1px solid var(--border); border-radius: 8px;
|
||
}
|
||
@media (max-width: 800px) {
|
||
.ctx-row { grid-template-columns: 1fr 1fr; }
|
||
}
|
||
.ctx-item label {
|
||
display: block; font-size: 11px; color: var(--text-muted); margin-bottom: 2px;
|
||
}
|
||
.ctx-item .val { font-size: 13px; font-weight: 500; color: var(--text); }
|
||
|
||
.field-group {
|
||
border: 1px solid var(--border);
|
||
border-radius: 10px;
|
||
margin-bottom: 14px;
|
||
overflow: hidden;
|
||
}
|
||
.field-group-title {
|
||
padding: 10px 14px;
|
||
background: var(--primary-bg);
|
||
color: var(--primary-dark);
|
||
font-size: 13px; font-weight: 600;
|
||
border-bottom: 1px solid #a7f3d0;
|
||
}
|
||
.field-group-title.alt { background: #f1f5f9; color: var(--text-secondary); border-bottom-color: var(--border); }
|
||
.field-group-title.meta { background: #fffbeb; color: #92400e; border-bottom-color: #fde68a; }
|
||
.form-grid {
|
||
display: grid;
|
||
grid-template-columns: repeat(3, 1fr);
|
||
gap: 12px 14px;
|
||
padding: 14px;
|
||
}
|
||
@media (max-width: 900px) {
|
||
.form-grid { grid-template-columns: repeat(2, 1fr); }
|
||
}
|
||
@media (max-width: 560px) {
|
||
.form-grid { grid-template-columns: 1fr; }
|
||
}
|
||
.form-item { display: flex; flex-direction: column; gap: 4px; }
|
||
.form-item.span-2 { grid-column: span 2; }
|
||
.form-item.span-3 { grid-column: 1 / -1; }
|
||
.form-item label {
|
||
font-size: 11px; color: var(--text-muted); font-weight: 500;
|
||
}
|
||
.form-item input, .form-item select, .form-item textarea {
|
||
height: 36px; padding: 0 10px;
|
||
border: 1px solid var(--border); border-radius: 8px;
|
||
font-size: 13px; color: var(--text); background: #fff;
|
||
font-family: inherit;
|
||
}
|
||
.form-item textarea {
|
||
height: auto; min-height: 72px; padding: 8px 10px; resize: vertical;
|
||
}
|
||
.form-item input:disabled, .form-item textarea:disabled, .form-item select:disabled {
|
||
background: #f8fafc; color: var(--text-secondary);
|
||
}
|
||
.form-item.readonly .val-box {
|
||
min-height: 36px; padding: 8px 10px;
|
||
border: 1px solid var(--border); border-radius: 8px;
|
||
background: #f8fafc; font-size: 13px; color: var(--text-secondary);
|
||
white-space: pre-wrap;
|
||
}
|
||
|
||
.type-switch {
|
||
display: inline-flex; gap: 6px; margin-bottom: 12px;
|
||
}
|
||
.field-count {
|
||
font-size: 12px; color: var(--text-muted);
|
||
}
|
||
|
||
.flow {
|
||
display: flex; flex-wrap: wrap; gap: 8px; align-items: center;
|
||
font-size: 13px; color: var(--text-secondary);
|
||
}
|
||
.flow .step {
|
||
padding: 6px 10px; background: #fff; border: 1px solid var(--border);
|
||
border-radius: 8px;
|
||
}
|
||
.flow .arrow { color: var(--text-muted); }
|
||
|
||
.legend {
|
||
display: grid; grid-template-columns: 1fr 1fr; gap: 12px;
|
||
}
|
||
@media (max-width: 700px) {
|
||
.legend { grid-template-columns: 1fr; }
|
||
}
|
||
.legend-card {
|
||
border: 1px solid var(--border); border-radius: 10px; padding: 12px 14px;
|
||
background: #fff;
|
||
}
|
||
.legend-card h4 { margin: 0 0 8px; font-size: 14px; }
|
||
.legend-card ul {
|
||
margin: 0; padding-left: 18px; color: var(--text-secondary); font-size: 12px;
|
||
}
|
||
.legend-card li { margin-bottom: 4px; }
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div class="page">
|
||
<div class="hero">
|
||
<h1>储存证质检信息 · Demo</h1>
|
||
<p>
|
||
质检在「细胞存储质检」工单卡片上<strong>填写</strong>储存证质检信息(字段对齐 Excel 两个 sheet);
|
||
市场在「样本信息管理 · 细胞存储」上<strong>查看</strong>同一份数据,用于誊写到储存证。
|
||
</p>
|
||
<div class="context-bar">
|
||
<span class="pill">Excel:围产期造血干细胞</span>
|
||
<span class="pill">Excel:脐带间充质干细胞</span>
|
||
<span class="pill muted">质检工单 / 我的质检任务</span>
|
||
<span class="pill muted">样本信息管理</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="section">
|
||
<div class="section-head">
|
||
<div>
|
||
<h2>业务链路(示意)</h2>
|
||
<p class="hint">当前 Demo 不改业务逻辑,只对齐交互与字段分组</p>
|
||
</div>
|
||
</div>
|
||
<div class="flow">
|
||
<span class="step">质检完成检测</span>
|
||
<span class="arrow">→</span>
|
||
<span class="step" style="border-color:#a7f3d0;background:var(--primary-bg);color:var(--primary-dark);font-weight:600;">填写储存证质检信息</span>
|
||
<span class="arrow">→</span>
|
||
<span class="step">市场「样本信息」查看</span>
|
||
<span class="arrow">→</span>
|
||
<span class="step">誊写 / 办理储存证</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="scene-tabs" role="tablist">
|
||
<button type="button" class="scene-tab active" data-scene="overview">① 字段对照</button>
|
||
<button type="button" class="scene-tab" data-scene="qc-card">② 质检卡片入口</button>
|
||
<button type="button" class="scene-tab" data-scene="fill-hsc">③ 填写 · 围产期造血</button>
|
||
<button type="button" class="scene-tab" data-scene="fill-msc">④ 填写 · 脐带间充质</button>
|
||
<button type="button" class="scene-tab" data-scene="sample-info">⑤ 样本信息查看入口</button>
|
||
</div>
|
||
|
||
<!-- ① overview -->
|
||
<div class="scene active" id="scene-overview">
|
||
<div class="note ok">
|
||
两个 sheet 共用「身份键 + 母亲血检」骨架,检测报告区字段按样本类型分叉;右侧收尾字段也略有差异。
|
||
</div>
|
||
<div class="legend">
|
||
<div class="legend-card">
|
||
<h4>围产期造血干细胞(约 34 列)</h4>
|
||
<ul>
|
||
<li><strong>身份</strong>:序号、实验室流转编码、协议编码、母亲姓名</li>
|
||
<li><strong>采集运输</strong>:采集时间、运输温度</li>
|
||
<li><strong>造血干细胞检测报告</strong>:接收/处理/冻存时间、重量、冻存体积、TNC、CD34+、CD34+CD45dim、活性、细菌、HBsAg/HCV/TP/HIV、CMV-IgM</li>
|
||
<li><strong>母亲血液检测报告</strong>:HBsAg、HBV DNA、抗HCV、HCV RNA、抗TP、CMV IgM、抗HIV、HIV-1RNA</li>
|
||
<li><strong>收尾</strong>:HLA 分型、储存日期、储存年限、检测结果评论、报告发出日期</li>
|
||
</ul>
|
||
</div>
|
||
<div class="legend-card">
|
||
<h4>脐带间充质干细胞(约 34 列)</h4>
|
||
<ul>
|
||
<li><strong>额外</strong>:是否邮寄</li>
|
||
<li><strong>身份</strong>:序号、实验室流转编码、协议编码、母亲姓名</li>
|
||
<li><strong>采集运输</strong>:脐带采集时间、运输温度</li>
|
||
<li><strong>脐带间充质检测报告</strong>:接收/处理/冻存时间、储存总量(管)、可提供细胞类型/数量/存活率、内毒素/细菌/真菌/支原体、形态、免疫表型</li>
|
||
<li><strong>母亲血液检测报告</strong>:与造血 sheet 同一组 8 项</li>
|
||
<li><strong>收尾</strong>:检测结果评判、报告发出日期、储存日期(P2)、冷冻方式、储存温度、储存年限</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
<div class="section" style="margin-top:16px;">
|
||
<div class="section-head">
|
||
<div>
|
||
<h2>Demo 建议排除出「质检填写」的列</h2>
|
||
<p class="hint">这些更像列表管理列 / 市场侧信息,可在澄清时确认</p>
|
||
</div>
|
||
</div>
|
||
<p style="margin:0;font-size:13px;color:var(--text-secondary);">
|
||
建议默认<strong>只读预填、不让质检手填</strong>:序号、协议编码、母亲姓名(从样本/协议带出)。
|
||
「是否邮寄」偏市场物流,是否纳入质检表待确认。
|
||
「实验室流转编码」是否等于系统样本编码 / 入库编码,待确认。
|
||
</p>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ② qc card -->
|
||
<div class="scene" id="scene-qc-card">
|
||
<div class="section">
|
||
<div class="section-head">
|
||
<div>
|
||
<h2>质检工单 / 我的质检任务 · 细胞存储质检</h2>
|
||
<p class="hint">在工单卡片操作区新增「填写储存证质检信息」(示意高亮)</p>
|
||
</div>
|
||
</div>
|
||
<div class="note">入口放在<strong>工单卡片</strong>(非任务子卡「填写结果」),因为储存证信息是样本级整表,不是单项检测任务结果。</div>
|
||
|
||
<div class="protocol-bar">
|
||
<span>协议:<strong>ZKZX34000852</strong></span>
|
||
<span>客户:高居巧</span>
|
||
<span>来源:细胞存储</span>
|
||
</div>
|
||
<div class="sample-pills">
|
||
<span class="sample-pill active">B0000002 · 围产期造血干细胞</span>
|
||
<span class="sample-pill">B0000002-MSC · 脐带间充质(示意)</span>
|
||
</div>
|
||
<div class="wo-card">
|
||
<div class="wo-card-top">
|
||
<div class="wo-meta">
|
||
<div class="code">入库质检工单 WO-2026-1008-012</div>
|
||
<div style="margin-top:4px;">
|
||
<span class="tag success">已完成</span>
|
||
<span class="tag info" style="margin-left:6px;">结论:通过</span>
|
||
</div>
|
||
</div>
|
||
<div class="field-count">样本类型 → 决定弹窗字段模板</div>
|
||
</div>
|
||
<div class="wo-actions">
|
||
<button type="button" class="btn">查看</button>
|
||
<button type="button" class="btn">特殊样本</button>
|
||
<button type="button" class="btn accent" onclick="openFill('hsc')">
|
||
<span class="btn-icon"></span> 填写储存证质检信息
|
||
</button>
|
||
<button type="button" class="btn ghost">更多</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div style="height:14px;"></div>
|
||
<div class="wo-card" style="opacity:0.92;">
|
||
<div class="wo-card-top">
|
||
<div class="wo-meta">
|
||
<div class="code">入库质检工单 WO-2026-1009-003</div>
|
||
<div style="margin-top:4px;">
|
||
<span class="tag warning">进行中</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="wo-actions">
|
||
<button type="button" class="btn primary">配置检测</button>
|
||
<button type="button" class="btn accent" onclick="openFill('msc')">
|
||
<span class="btn-icon"></span> 填写储存证质检信息
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ③ fill HSC summary (opens dialog) -->
|
||
<div class="scene" id="scene-fill-hsc">
|
||
<div class="section">
|
||
<div class="section-head">
|
||
<div>
|
||
<h2>填写弹窗 · 围产期造血干细胞</h2>
|
||
<p class="hint">分组 = Excel 合并表头;三列栅格;长文本(HLA / 评论)跨列</p>
|
||
</div>
|
||
<button type="button" class="btn primary" onclick="openFill('hsc')">打开填写弹窗</button>
|
||
</div>
|
||
<p style="margin:0;font-size:13px;color:var(--text-muted);">
|
||
字段按 Excel sheet「围产期造血干细胞」展开:造血检测报告 15 项 + 母亲血检 8 项 + HLA/储存/评论/报告日。
|
||
</p>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ④ fill MSC -->
|
||
<div class="scene" id="scene-fill-msc">
|
||
<div class="section">
|
||
<div class="section-head">
|
||
<div>
|
||
<h2>填写弹窗 · 脐带间充质干细胞</h2>
|
||
<p class="hint">与造血模板共用母亲血检区块;检测报告与收尾字段不同</p>
|
||
</div>
|
||
<button type="button" class="btn primary" onclick="openFill('msc')">打开填写弹窗</button>
|
||
</div>
|
||
<p style="margin:0;font-size:13px;color:var(--text-muted);">
|
||
含「是否邮寄」、储存总量(管)、可提供细胞*、内毒素/真菌/支原体、冷冻方式、储存温度等。
|
||
</p>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ⑤ sample info -->
|
||
<div class="scene" id="scene-sample-info">
|
||
<div class="section">
|
||
<div class="section-head">
|
||
<div>
|
||
<h2>样本信息管理 · 细胞存储 Tab</h2>
|
||
<p class="hint">行操作增加「查看储存证的质检信息」;无数据时按钮可禁用或提示未填写</p>
|
||
</div>
|
||
</div>
|
||
<div class="toolbar">
|
||
<span class="selected">已选 0 项</span>
|
||
<button type="button" class="btn primary">登记入库</button>
|
||
<button type="button" class="btn">登记储存证</button>
|
||
<button type="button" class="btn">登记保险</button>
|
||
</div>
|
||
<div class="table-wrap">
|
||
<table class="list">
|
||
<thead>
|
||
<tr>
|
||
<th>样本编码</th>
|
||
<th>协议编码</th>
|
||
<th>母亲姓名</th>
|
||
<th>样本类型</th>
|
||
<th>质检</th>
|
||
<th>储存证</th>
|
||
<th>操作</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr class="highlight">
|
||
<td>B0000002</td>
|
||
<td>ZKZX34000852</td>
|
||
<td>高居巧</td>
|
||
<td>围产期造血干细胞</td>
|
||
<td><span class="tag success">已完成</span></td>
|
||
<td><span class="tag warning">未办理</span></td>
|
||
<td>
|
||
<div class="ops">
|
||
<button type="button" class="btn sm">查看</button>
|
||
<button type="button" class="btn sm accent" onclick="openView('hsc')">查看储存证的质检信息</button>
|
||
</div>
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td>BC0000003</td>
|
||
<td>ZKQD34000831</td>
|
||
<td>牛晨晨</td>
|
||
<td>脐带间充质干细胞</td>
|
||
<td><span class="tag success">已完成</span></td>
|
||
<td><span class="tag success">已办理</span></td>
|
||
<td>
|
||
<div class="ops">
|
||
<button type="button" class="btn sm">查看</button>
|
||
<button type="button" class="btn sm accent" onclick="openView('msc')">查看储存证的质检信息</button>
|
||
</div>
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td>B0000099</td>
|
||
<td>ZKZX34000999</td>
|
||
<td>示例未填</td>
|
||
<td>围产期造血干细胞</td>
|
||
<td><span class="tag warning">进行中</span></td>
|
||
<td><span class="tag info">—</span></td>
|
||
<td>
|
||
<div class="ops">
|
||
<button type="button" class="btn sm">查看</button>
|
||
<button type="button" class="btn sm" disabled style="opacity:0.45;cursor:not-allowed;">查看储存证的质检信息</button>
|
||
</div>
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Fill dialog -->
|
||
<div class="dialog-mask" id="fillMask" onclick="maskClose(event,'fillMask')">
|
||
<div class="dialog wide" role="dialog" aria-modal="true">
|
||
<div class="dialog-header">
|
||
<div>
|
||
<h3 id="fillTitle">填写储存证质检信息</h3>
|
||
<div class="sub" id="fillSub">按样本类型切换字段模板</div>
|
||
</div>
|
||
<button type="button" class="dialog-close" onclick="closeMask('fillMask')" aria-label="关闭">×</button>
|
||
</div>
|
||
<div class="dialog-body">
|
||
<div class="ctx-row">
|
||
<div class="ctx-item"><label>实验室流转编码</label><div class="val" id="ctxLab">B0000002</div></div>
|
||
<div class="ctx-item"><label>协议编码</label><div class="val" id="ctxProto">ZKZX34000852</div></div>
|
||
<div class="ctx-item"><label>母亲姓名</label><div class="val" id="ctxMother">高居巧</div></div>
|
||
<div class="ctx-item"><label>样本类型</label><div class="val" id="ctxType">围产期造血干细胞</div></div>
|
||
</div>
|
||
|
||
<div id="formHsc">
|
||
<div class="field-group">
|
||
<div class="field-group-title alt">采集与运输</div>
|
||
<div class="form-grid">
|
||
<div class="form-item"><label>造血干细胞采集时间</label><input value="2025年9月7日15时36分" /></div>
|
||
<div class="form-item"><label>运输温度 /℃</label><input value="17" /></div>
|
||
</div>
|
||
</div>
|
||
<div class="field-group">
|
||
<div class="field-group-title">造血干细胞检测报告</div>
|
||
<div class="form-grid">
|
||
<div class="form-item"><label>造血干细胞接收时间</label><input value="2025.9.8 9:00" /></div>
|
||
<div class="form-item"><label>处理时间</label><input value="2025.9.8 9:30" /></div>
|
||
<div class="form-item"><label>冻存时间</label><input value="2025.9.8 11:57" /></div>
|
||
<div class="form-item"><label>造血干细胞重量/g</label><input value="56" /></div>
|
||
<div class="form-item"><label>造血干细胞冻存体积/mL</label><input value="21.8" /></div>
|
||
<div class="form-item"><label>有核细胞数 TNC / *10E8</label><input value="2.28" /></div>
|
||
<div class="form-item"><label>CD34+ 细胞计数 / *10E6</label><input value="16.3" /></div>
|
||
<div class="form-item"><label>CD34+ CD45dim / *10E5</label><input value="1.27" /></div>
|
||
<div class="form-item"><label>细胞活性/%</label><input value="90.44" /></div>
|
||
<div class="form-item"><label>细菌检测</label><select><option>阴</option><option>阳</option><option>/</option></select></div>
|
||
<div class="form-item"><label>乙型肝炎病毒表面抗原(HBsAg)</label><select><option>阴</option><option>阳</option><option>/</option></select></div>
|
||
<div class="form-item"><label>丙型肝炎病毒抗体(抗HCV)</label><select><option>阴</option><option>阳</option><option>/</option></select></div>
|
||
<div class="form-item"><label>梅毒螺旋体特异性抗体(抗TP)</label><select><option>阴</option><option>阳</option><option>/</option></select></div>
|
||
<div class="form-item"><label>人类免疫缺陷病毒抗体(抗HIV-1/2)</label><select><option>阴</option><option>阳</option><option>/</option></select></div>
|
||
<div class="form-item"><label>巨细胞病毒 IgM 抗体 (CMV-IgM)</label><select><option>阴</option><option>阳</option><option>/</option></select></div>
|
||
</div>
|
||
</div>
|
||
<div class="field-group">
|
||
<div class="field-group-title">母亲血液检测报告</div>
|
||
<div class="form-grid">
|
||
<div class="form-item"><label>乙型肝炎病毒表面抗原(HBsAg)</label><select><option>阴</option><option>/</option></select></div>
|
||
<div class="form-item"><label>乙型肝炎病毒核酸(HBV DNA)</label><select><option>阴</option><option>/</option></select></div>
|
||
<div class="form-item"><label>丙型肝炎病毒抗体(抗HCV)</label><select><option>阴</option><option>/</option></select></div>
|
||
<div class="form-item"><label>丙型肝炎病毒核酸(HCV RNA)</label><select><option>阴</option><option>/</option></select></div>
|
||
<div class="form-item"><label>梅毒螺旋体特异性抗体(抗TP)</label><select><option>阴</option><option>/</option></select></div>
|
||
<div class="form-item"><label>巨细胞病毒 IgM 抗体 (CMV IgM)</label><select><option>阴</option><option>/</option></select></div>
|
||
<div class="form-item"><label>人类免疫缺陷病毒抗体(抗HIV-1/2)</label><select><option>阴</option><option>/</option></select></div>
|
||
<div class="form-item"><label>人类免疫缺陷病毒核酸(1型) (HIV-1RNA)</label><select><option>阴</option><option>/</option></select></div>
|
||
</div>
|
||
</div>
|
||
<div class="field-group">
|
||
<div class="field-group-title meta">储存证收尾信息</div>
|
||
<div class="form-grid">
|
||
<div class="form-item span-3"><label>HLA 分型</label><textarea>A 02:06/24:02
|
||
B 07:02(M)/57:01(T)
|
||
C 06:02/07:02
|
||
DRB1 13:01/15:01
|
||
DQB1 06:02/06:03</textarea></div>
|
||
<div class="form-item"><label>储存日期</label><input placeholder="YYYY-MM-DD" /></div>
|
||
<div class="form-item"><label>储存年限</label><input value="20" /></div>
|
||
<div class="form-item"><label>检测结果评论</label><input value="合格" /></div>
|
||
<div class="form-item"><label>报告发出日期</label><input placeholder="YYYY-MM-DD" /></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div id="formMsc" style="display:none;">
|
||
<div class="field-group">
|
||
<div class="field-group-title alt">采集与运输 / 邮寄</div>
|
||
<div class="form-grid">
|
||
<div class="form-item"><label>是否邮寄</label><select><option>是</option><option selected>否</option></select></div>
|
||
<div class="form-item"><label>脐带采集时间</label><input value="2025.11.25 15:49" /></div>
|
||
<div class="form-item"><label>运输温度 /℃</label><input value="" placeholder="可填「常温」或数值" /></div>
|
||
</div>
|
||
</div>
|
||
<div class="field-group">
|
||
<div class="field-group-title">脐带间充质干细胞检测报告</div>
|
||
<div class="form-grid">
|
||
<div class="form-item"><label>脐带接收时间</label><input value="2025.11.26 10:00" /></div>
|
||
<div class="form-item"><label>处理时间</label><input value="2025.11.26 16:00" /></div>
|
||
<div class="form-item"><label>冻存时间</label><input value="2025.12.21" /></div>
|
||
<div class="form-item"><label>储存总量(管)</label><input value="17" placeholder="Excel 中有 =0+17 公式" /></div>
|
||
<div class="form-item"><label>可提供细胞类型</label><input value="间充质干细胞" /></div>
|
||
<div class="form-item"><label>可提供细胞数量 / *10E7</label><input value="8.5" /></div>
|
||
<div class="form-item"><label>可提供细胞存活率 %</label><input value="97.1" /></div>
|
||
<div class="form-item"><label>内毒素检测</label><select><option>阴</option><option>阳</option><option>/</option></select></div>
|
||
<div class="form-item"><label>细菌检测</label><select><option>阴</option><option>/</option></select></div>
|
||
<div class="form-item"><label>真菌检测</label><select><option>阴</option><option>/</option></select></div>
|
||
<div class="form-item"><label>支原体检测</label><select><option>阴</option><option>/</option></select></div>
|
||
<div class="form-item"><label>可提供细胞形态</label><input value="短梭/贴壁型" /></div>
|
||
<div class="form-item span-2"><label>可提供细胞免疫表型特征</label><input value="符合间充质干细胞表型特性" /></div>
|
||
</div>
|
||
</div>
|
||
<div class="field-group">
|
||
<div class="field-group-title">母亲血液检测报告</div>
|
||
<div class="form-grid">
|
||
<div class="form-item"><label>乙型肝炎病毒表面抗原(HBsAg)</label><select><option>阴</option></select></div>
|
||
<div class="form-item"><label>乙型肝炎病毒核酸(HBV DNA)</label><select><option>/</option><option>阴</option></select></div>
|
||
<div class="form-item"><label>丙型肝炎病毒抗体(抗HCV)</label><select><option>阴</option></select></div>
|
||
<div class="form-item"><label>丙型肝炎病毒核酸(HCV RNA)</label><select><option>/</option><option>阴</option></select></div>
|
||
<div class="form-item"><label>梅毒螺旋体特异性抗体(抗TP)</label><select><option>阴</option></select></div>
|
||
<div class="form-item"><label>巨细胞病毒 IgM 抗体 (CMV IgM)</label><select><option>阴</option></select></div>
|
||
<div class="form-item"><label>人类免疫缺陷病毒抗体(抗HIV-1/2)</label><select><option>阴</option></select></div>
|
||
<div class="form-item"><label>人类免疫缺陷病毒核酸(1型) (HIV-1RNA)</label><select><option>阴</option></select></div>
|
||
</div>
|
||
</div>
|
||
<div class="field-group">
|
||
<div class="field-group-title meta">储存证收尾信息</div>
|
||
<div class="form-grid">
|
||
<div class="form-item"><label>检测结果评判</label><input value="合格" /></div>
|
||
<div class="form-item"><label>报告发出日期</label><input value="2026-03-14" /></div>
|
||
<div class="form-item"><label>储存日期 (P2冻存日期)</label><input value="2025.12.22" /></div>
|
||
<div class="form-item"><label>冷冻方式</label><input value="程序降温盒降温" /></div>
|
||
<div class="form-item"><label>储存温度</label><input value="-196℃" /></div>
|
||
<div class="form-item"><label>储存年限</label><input value="20" /></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dialog-footer">
|
||
<button type="button" class="btn" onclick="closeMask('fillMask')">取消</button>
|
||
<button type="button" class="btn primary" onclick="alert('Demo:保存成功(未接后端)'); closeMask('fillMask');">确定</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- View dialog -->
|
||
<div class="dialog-mask" id="viewMask" onclick="maskClose(event,'viewMask')">
|
||
<div class="dialog wide" role="dialog" aria-modal="true">
|
||
<div class="dialog-header">
|
||
<div>
|
||
<h3>查看储存证的质检信息</h3>
|
||
<div class="sub" id="viewSub">只读 · 字段与质检填写一致</div>
|
||
</div>
|
||
<button type="button" class="dialog-close" onclick="closeMask('viewMask')" aria-label="关闭">×</button>
|
||
</div>
|
||
<div class="dialog-body" id="viewBody">
|
||
<!-- filled by JS -->
|
||
</div>
|
||
<div class="dialog-footer">
|
||
<button type="button" class="btn primary" onclick="closeMask('viewMask')">关闭</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<script>
|
||
// Scene tabs
|
||
document.querySelectorAll('.scene-tab').forEach(function (tab) {
|
||
tab.addEventListener('click', function () {
|
||
document.querySelectorAll('.scene-tab').forEach(function (t) { t.classList.remove('active'); });
|
||
document.querySelectorAll('.scene').forEach(function (s) { s.classList.remove('active'); });
|
||
tab.classList.add('active');
|
||
document.getElementById('scene-' + tab.dataset.scene).classList.add('active');
|
||
});
|
||
});
|
||
|
||
function closeMask(id) {
|
||
document.getElementById(id).classList.remove('open');
|
||
}
|
||
function maskClose(e, id) {
|
||
if (e.target.id === id) closeMask(id);
|
||
}
|
||
|
||
function openFill(type) {
|
||
var isHsc = type === 'hsc';
|
||
document.getElementById('formHsc').style.display = isHsc ? '' : 'none';
|
||
document.getElementById('formMsc').style.display = isHsc ? 'none' : '';
|
||
document.getElementById('fillTitle').textContent = '填写储存证质检信息';
|
||
document.getElementById('fillSub').textContent = isHsc
|
||
? '模板:围产期造血干细胞(对齐 Excel sheet)'
|
||
: '模板:脐带间充质干细胞(对齐 Excel sheet)';
|
||
document.getElementById('ctxLab').textContent = isHsc ? 'B0000002' : 'BC0000003';
|
||
document.getElementById('ctxProto').textContent = isHsc ? 'ZKZX34000852' : 'ZKQD34000831';
|
||
document.getElementById('ctxMother').textContent = isHsc ? '高居巧' : '牛晨晨';
|
||
document.getElementById('ctxType').textContent = isHsc ? '围产期造血干细胞' : '脐带间充质干细胞';
|
||
document.getElementById('fillMask').classList.add('open');
|
||
}
|
||
|
||
function ro(label, val, span) {
|
||
var cls = 'form-item readonly' + (span ? ' span-' + span : '');
|
||
return '<div class="' + cls + '"><label>' + label + '</label><div class="val-box">' + (val || '—') + '</div></div>';
|
||
}
|
||
|
||
function openView(type) {
|
||
var isHsc = type === 'hsc';
|
||
document.getElementById('viewSub').textContent = isHsc
|
||
? '样本 B0000002 · 围产期造血干细胞 · 只读'
|
||
: '样本 BC0000003 · 脐带间充质干细胞 · 只读';
|
||
var html = '';
|
||
html += '<div class="ctx-row">' +
|
||
'<div class="ctx-item"><label>实验室流转编码</label><div class="val">' + (isHsc ? 'B0000002' : 'BC0000003') + '</div></div>' +
|
||
'<div class="ctx-item"><label>协议编码</label><div class="val">' + (isHsc ? 'ZKZX34000852' : 'ZKQD34000831') + '</div></div>' +
|
||
'<div class="ctx-item"><label>母亲姓名</label><div class="val">' + (isHsc ? '高居巧' : '牛晨晨') + '</div></div>' +
|
||
'<div class="ctx-item"><label>样本类型</label><div class="val">' + (isHsc ? '围产期造血干细胞' : '脐带间充质干细胞') + '</div></div>' +
|
||
'</div>';
|
||
|
||
if (isHsc) {
|
||
html += '<div class="field-group"><div class="field-group-title alt">采集与运输</div><div class="form-grid">' +
|
||
ro('造血干细胞采集时间', '2025年9月7日15时36分') +
|
||
ro('运输温度 /℃', '17') +
|
||
'</div></div>';
|
||
html += '<div class="field-group"><div class="field-group-title">造血干细胞检测报告</div><div class="form-grid">' +
|
||
ro('造血干细胞接收时间', '2025.9.8 9:00') +
|
||
ro('处理时间', '2025.9.8 9:30') +
|
||
ro('冻存时间', '2025.9.8 11:57') +
|
||
ro('造血干细胞重量/g', '56') +
|
||
ro('造血干细胞冻存体积/mL', '21.8') +
|
||
ro('有核细胞数 TNC / *10E8', '2.28') +
|
||
ro('CD34+ 细胞计数 / *10E6', '16.3') +
|
||
ro('CD34+ CD45dim / *10E5', '1.27') +
|
||
ro('细胞活性/%', '90.44') +
|
||
ro('细菌检测', '阴') +
|
||
ro('乙型肝炎病毒表面抗原(HBsAg)', '阴') +
|
||
ro('丙型肝炎病毒抗体(抗HCV)', '阴') +
|
||
ro('梅毒螺旋体特异性抗体(抗TP)', '阴') +
|
||
ro('人类免疫缺陷病毒抗体(抗HIV-1/2)', '阴') +
|
||
ro('巨细胞病毒 IgM 抗体 (CMV-IgM)', '阴') +
|
||
'</div></div>';
|
||
html += '<div class="field-group"><div class="field-group-title">母亲血液检测报告</div><div class="form-grid">' +
|
||
ro('HBsAg', '阴') + ro('HBV DNA', '阴') + ro('抗HCV', '阴') + ro('HCV RNA', '阴') +
|
||
ro('抗TP', '阴') + ro('CMV IgM', '阴') + ro('抗HIV-1/2', '阴') + ro('HIV-1RNA', '阴') +
|
||
'</div></div>';
|
||
html += '<div class="field-group"><div class="field-group-title meta">储存证收尾信息</div><div class="form-grid">' +
|
||
ro('HLA 分型', 'A 02:06/24:02\\nB 07:02(M)/57:01(T)\\nC 06:02/07:02\\nDRB1 13:01/15:01\\nDQB1 06:02/06:03', 3) +
|
||
ro('储存日期', '—') + ro('储存年限', '20') + ro('检测结果评论', '合格') + ro('报告发出日期', '—') +
|
||
'</div></div>';
|
||
} else {
|
||
html += '<div class="field-group"><div class="field-group-title alt">采集与运输 / 邮寄</div><div class="form-grid">' +
|
||
ro('是否邮寄', '—') + ro('脐带采集时间', '2025.11.25 15:49') + ro('运输温度 /℃', '—') +
|
||
'</div></div>';
|
||
html += '<div class="field-group"><div class="field-group-title">脐带间充质干细胞检测报告</div><div class="form-grid">' +
|
||
ro('脐带接收时间', '2025.11.26 10:00') + ro('处理时间', '2025.11.26 16:00') + ro('冻存时间', '2025.12.21') +
|
||
ro('储存总量(管)', '17') + ro('可提供细胞类型', '间充质干细胞') +
|
||
ro('可提供细胞数量 / *10E7', '8.5') + ro('可提供细胞存活率 %', '97.1') +
|
||
ro('内毒素检测', '阴') + ro('细菌检测', '阴') + ro('真菌检测', '阴') + ro('支原体检测', '阴') +
|
||
ro('可提供细胞形态', '短梭/贴壁型') +
|
||
ro('可提供细胞免疫表型特征', '符合间充质干细胞表型特性', 2) +
|
||
'</div></div>';
|
||
html += '<div class="field-group"><div class="field-group-title">母亲血液检测报告</div><div class="form-grid">' +
|
||
ro('HBsAg', '阴') + ro('HBV DNA', '/') + ro('抗HCV', '阴') + ro('HCV RNA', '/') +
|
||
ro('抗TP', '阴') + ro('CMV IgM', '阴') + ro('抗HIV-1/2', '阴') + ro('HIV-1RNA', '阴') +
|
||
'</div></div>';
|
||
html += '<div class="field-group"><div class="field-group-title meta">储存证收尾信息</div><div class="form-grid">' +
|
||
ro('检测结果评判', '合格') + ro('报告发出日期', '2026-03-14') +
|
||
ro('储存日期 (P2冻存日期)', '2025.12.22') + ro('冷冻方式', '程序降温盒降温') +
|
||
ro('储存温度', '-196℃') + ro('储存年限', '20') +
|
||
'</div></div>';
|
||
}
|
||
document.getElementById('viewBody').innerHTML = html;
|
||
document.getElementById('viewMask').classList.add('open');
|
||
}
|
||
</script>
|
||
</body>
|
||
</html>
|