|
|
<!DOCTYPE html>
|
|
|
<html lang="zh-CN">
|
|
|
<head>
|
|
|
<meta charset="UTF-8" />
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
|
<title>预检取号 · 一键体检 / 智能提醒 预览</title>
|
|
|
<style>
|
|
|
* { box-sizing: border-box; margin: 0; padding: 0; }
|
|
|
body {
|
|
|
font-family: "PingFang SC", "Microsoft YaHei", sans-serif;
|
|
|
background: #eef3f9;
|
|
|
color: #1e293b;
|
|
|
height: 100vh;
|
|
|
overflow: hidden;
|
|
|
}
|
|
|
.page {
|
|
|
height: 100vh;
|
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
|
}
|
|
|
.toolbar {
|
|
|
flex-shrink: 0;
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
gap: 16px;
|
|
|
padding: 12px 20px;
|
|
|
background: #fff;
|
|
|
border-bottom: 1px solid #d7e2ee;
|
|
|
box-shadow: 0 8px 24px rgba(30, 58, 138, 0.06);
|
|
|
}
|
|
|
.toolbar-left { display: flex; align-items: center; gap: 12px; flex-shrink: 0; }
|
|
|
.back-btn {
|
|
|
min-width: 84px; height: 40px; padding: 0 14px;
|
|
|
border: 1px solid #c7d7ea; border-radius: 10px;
|
|
|
background: #fff; color: #1e3a8a; font-weight: 600; cursor: pointer;
|
|
|
}
|
|
|
.title-wrap { padding-left: 12px; border-left: 3px solid #1d4ed8; }
|
|
|
.title { font-size: 18px; font-weight: 700; color: #1e3a8a; }
|
|
|
.sub { margin-top: 2px; font-size: 11px; color: #64748b; letter-spacing: 0.5px; }
|
|
|
.badge {
|
|
|
margin-left: 8px; padding: 2px 8px; border-radius: 999px;
|
|
|
font-size: 11px; color: #1d4ed8; background: #eff6ff; font-weight: 600;
|
|
|
}
|
|
|
.tool-input { display: flex; flex: 1; gap: 10px; min-width: 0; }
|
|
|
.search-field {
|
|
|
flex: 1; height: 42px; display: flex; align-items: center;
|
|
|
padding: 0 12px; background: #f4f7fb; border: 1px solid #d7e2ee; border-radius: 10px;
|
|
|
}
|
|
|
.search-label { margin-right: 8px; font-size: 12px; color: #64748b; font-weight: 600; white-space: nowrap; }
|
|
|
.search-field input {
|
|
|
flex: 1; border: 0; outline: none; background: transparent; font-size: 14px; color: #1e293b;
|
|
|
}
|
|
|
.tools-btn { display: flex; gap: 8px; flex-shrink: 0; }
|
|
|
.btn {
|
|
|
height: 42px; min-width: 88px; border: none; border-radius: 10px;
|
|
|
font-size: 14px; font-weight: 600; cursor: pointer;
|
|
|
}
|
|
|
.btn-primary { background: #2563eb; color: #fff; box-shadow: 0 6px 14px rgba(37, 99, 235, 0.22); }
|
|
|
.btn-ghost { background: #fff; color: #1e3a8a; border: 1px solid #c7d7ea; }
|
|
|
.table-wrap { flex: 1; min-height: 0; padding: 12px 16px; overflow: auto; }
|
|
|
.table-card {
|
|
|
background: #fff; border: 1px solid #d7e2ee; border-radius: 12px;
|
|
|
overflow: hidden; box-shadow: 0 10px 28px rgba(30, 58, 138, 0.05);
|
|
|
}
|
|
|
table { width: 100%; border-collapse: collapse; table-layout: fixed; }
|
|
|
th {
|
|
|
background: #f3f6fb; color: #475569; font-size: 13px; font-weight: 600;
|
|
|
padding: 10px 8px; border-bottom: 1px solid #e5e7eb; text-align: center;
|
|
|
}
|
|
|
td {
|
|
|
font-size: 12px; color: #1e293b; padding: 10px 8px;
|
|
|
border-bottom: 1px solid #f1f5f9; vertical-align: top; text-align: center;
|
|
|
}
|
|
|
tr:nth-child(even) td { background: #f8fafc; }
|
|
|
.col-name { width: 86px; }
|
|
|
.col-id { width: 128px; }
|
|
|
.col-phone { width: 108px; }
|
|
|
.col-ticket { width: 72px; }
|
|
|
.col-verify { width: 120px; }
|
|
|
.col-time { width: 148px; }
|
|
|
.col-photo { width: 72px; }
|
|
|
.col-health { width: 210px; text-align: left; }
|
|
|
.col-smart { width: 240px; text-align: left; }
|
|
|
.col-op { width: 168px; }
|
|
|
td.col-health, td.col-smart, th.col-health, th.col-smart { text-align: left; }
|
|
|
.summary { line-height: 1.55; color: #334155; cursor: pointer; }
|
|
|
.summary:hover { color: #1d4ed8; }
|
|
|
.warn-red { color: #dc2626; font-weight: 700; }
|
|
|
.warn-blue { color: #2563eb; font-weight: 700; }
|
|
|
.muted { color: #94a3b8; }
|
|
|
.link { color: #2563eb; background: none; border: 0; cursor: pointer; font-size: 12px; }
|
|
|
.row-actions { display: flex; gap: 4px; justify-content: flex-start; }
|
|
|
.table-action {
|
|
|
min-width: 56px; height: 28px; padding: 0 10px; border: none; border-radius: 8px;
|
|
|
font-size: 12px; cursor: pointer; color: #fff;
|
|
|
background-image: linear-gradient(to bottom right, #60a5fa, #1d4ed8);
|
|
|
}
|
|
|
.table-action.gray {
|
|
|
color: #111827; background: #e5e7eb; background-image: none;
|
|
|
}
|
|
|
.footer {
|
|
|
flex-shrink: 0; display: flex; justify-content: space-between; align-items: center;
|
|
|
padding: 10px 20px; background: #fff; border-top: 1px solid #d7e2ee;
|
|
|
}
|
|
|
.page-span { color: #1d4ed8; margin: 0 4px; font-weight: 700; }
|
|
|
.page-actions { display: flex; align-items: center; gap: 12px; }
|
|
|
.page-pill {
|
|
|
min-width: 92px; height: 42px; border-radius: 21px; background: #eef3f9;
|
|
|
display: flex; align-items: center; justify-content: center; font-weight: 600; color: #64748b;
|
|
|
}
|
|
|
.page-pill b { color: #1e3a8a; font-size: 18px; margin-right: 4px; }
|
|
|
.page-btn {
|
|
|
min-width: 112px; height: 42px; border-radius: 21px; border: 1px solid #c7d7ea;
|
|
|
background: #fff; color: #1e3a8a; font-weight: 600; cursor: pointer;
|
|
|
}
|
|
|
.page-btn.primary { background: #2563eb; border-color: #2563eb; color: #fff; }
|
|
|
.page-btn:disabled { opacity: 0.4; }
|
|
|
.mask {
|
|
|
display: none; position: fixed; inset: 0; background: rgba(15, 23, 42, 0.45);
|
|
|
align-items: center; justify-content: center; z-index: 50;
|
|
|
}
|
|
|
.mask.show { display: flex; }
|
|
|
.modal {
|
|
|
width: 560px; max-width: 92vw; max-height: 80vh; overflow: auto;
|
|
|
background: #fff; border-radius: 16px; box-shadow: 0 18px 48px rgba(30, 58, 138, 0.16);
|
|
|
}
|
|
|
.modal-head {
|
|
|
display: flex; align-items: center; justify-content: space-between;
|
|
|
padding: 16px 20px; border-bottom: 1px solid #eef2f7;
|
|
|
}
|
|
|
.modal-head h3 { color: #1e3a8a; font-size: 18px; }
|
|
|
.close { width: 32px; height: 32px; border: 0; border-radius: 16px; background: #eef3f9; cursor: pointer; }
|
|
|
.modal-body { padding: 16px 20px 20px; font-size: 14px; line-height: 1.7; }
|
|
|
.kv { margin-bottom: 8px; }
|
|
|
.kv b { color: #475569; font-weight: 600; }
|
|
|
.note { margin-top: 12px; font-size: 12px; color: #94a3b8; }
|
|
|
</style>
|
|
|
</head>
|
|
|
<body>
|
|
|
<div class="page">
|
|
|
<div class="toolbar">
|
|
|
<div class="toolbar-left">
|
|
|
<button class="back-btn" onclick="alert('预览页:返回仅作展示')">← 返回</button>
|
|
|
<div class="title-wrap">
|
|
|
<div class="title">预检取号 <span class="badge">展示预览</span></div>
|
|
|
<div class="sub">核验记录查询与现场取号 · 含一键体检 / 智能提醒示意</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
<div class="tool-input">
|
|
|
<label class="search-field"><span class="search-label">姓名</span><input id="qName" placeholder="模糊匹配" /></label>
|
|
|
<label class="search-field"><span class="search-label">身份证</span><input id="qId" placeholder="模糊匹配" /></label>
|
|
|
<label class="search-field"><span class="search-label">手机号</span><input id="qPhone" placeholder="模糊匹配" /></label>
|
|
|
</div>
|
|
|
<div class="tools-btn">
|
|
|
<button class="btn btn-primary" onclick="applyFilter()">查询</button>
|
|
|
<button class="btn btn-ghost" onclick="resetFilter()">重置</button>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<div class="table-wrap">
|
|
|
<div class="table-card">
|
|
|
<table>
|
|
|
<thead>
|
|
|
<tr>
|
|
|
<th class="col-name">姓名</th>
|
|
|
<th class="col-id">身份证</th>
|
|
|
<th class="col-phone">手机号</th>
|
|
|
<th class="col-ticket">票号</th>
|
|
|
<th class="col-verify">核验结果</th>
|
|
|
<th class="col-time">核验时间</th>
|
|
|
<th class="col-photo">查看照片</th>
|
|
|
<th class="col-health">一键体检</th>
|
|
|
<th class="col-smart">智能提醒</th>
|
|
|
<th class="col-op">操作</th>
|
|
|
</tr>
|
|
|
</thead>
|
|
|
<tbody id="tbody"></tbody>
|
|
|
</table>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<div class="footer">
|
|
|
<div>共<span class="page-span" id="totalText">0</span>条 · 每页 10 条</div>
|
|
|
<div class="page-actions">
|
|
|
<button class="page-btn" id="prevBtn" onclick="changePage(-1)">上一页</button>
|
|
|
<div class="page-pill"><b id="pageNum">1</b> / <span id="pageTotal">1</span></div>
|
|
|
<button class="page-btn primary" id="nextBtn" onclick="changePage(1)">下一页</button>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<div class="mask" id="mask" onclick="if(event.target.id==='mask') closeModal()">
|
|
|
<div class="modal">
|
|
|
<div class="modal-head">
|
|
|
<h3 id="modalTitle">详情</h3>
|
|
|
<button class="close" onclick="closeModal()">×</button>
|
|
|
</div>
|
|
|
<div class="modal-body" id="modalBody"></div>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<script>
|
|
|
const ALL = [
|
|
|
{
|
|
|
name: "戴瑾", idCard: "330123199001015626", phone: "13800138001", ticketId: "A003",
|
|
|
baishuiResp: "已采集,已注册", verifyTime: "2026-08-21 08:08:47", hasPhoto: true, needCollect: false,
|
|
|
health: { companyCount: 2, red: 1, blue: 0, violation: 12, undeclare: 0 },
|
|
|
smart: { tag: "涉税专业服务人员", total: 20, lowest: "非常满意", very: 20, basic: 0, bad: 0 }
|
|
|
},
|
|
|
{
|
|
|
name: "易华斌", idCard: "330102198512123318", phone: "13900139002", ticketId: "Q001",
|
|
|
baishuiResp: "已采集,已注册", verifyTime: "2026-08-21 08:22:10", hasPhoto: true, needCollect: false,
|
|
|
health: { companyCount: 21, red: 0, blue: 3, violation: 0, undeclare: 1 },
|
|
|
smart: { tag: "单位办税员", total: 8, lowest: "基本满意", very: 5, basic: 2, bad: 1 }
|
|
|
},
|
|
|
{
|
|
|
name: "王立君", idCard: "330106197803084215", phone: "13700137003", ticketId: "A002",
|
|
|
baishuiResp: "未采集,未注册", verifyTime: "2026-08-21 09:01:33", hasPhoto: false, needCollect: true,
|
|
|
health: { unavailable: true, reason: "未采集,暂无法体检" },
|
|
|
smart: { unavailable: true, reason: "未采集,暂无提醒" }
|
|
|
},
|
|
|
{
|
|
|
name: "潘国丹", idCard: "330108199206188429", phone: "15912341926", ticketId: "A001",
|
|
|
baishuiResp: "已采集,已注册", verifyTime: "2026-08-21 09:16:02", hasPhoto: true, needCollect: false,
|
|
|
health: { companyCount: 0, red: 0, blue: 0, violation: 0, undeclare: 0 },
|
|
|
smart: { tag: "", total: 0, lowest: "", very: 0, basic: 0, bad: 0 }
|
|
|
},
|
|
|
{
|
|
|
name: "许洪武", idCard: "350301198011220332", phone: "15988881926", ticketId: "C026",
|
|
|
baishuiResp: "未采集,未注册", verifyTime: "2026-08-21 11:16:40", hasPhoto: true, needCollect: true,
|
|
|
health: { unavailable: true, reason: "未采集,暂无法体检" },
|
|
|
smart: { tag: "", total: 2, lowest: "不满意", very: 0, basic: 1, bad: 1 }
|
|
|
},
|
|
|
{
|
|
|
name: "王莉", idCard: "350203199403157821", phone: "13805920011", ticketId: "Z029",
|
|
|
baishuiResp: "已采集,已注册", verifyTime: "2026-08-21 11:18:05", hasPhoto: true, needCollect: false,
|
|
|
health: { companyCount: 4, red: 1, blue: 1, violation: 3, undeclare: 2 },
|
|
|
smart: { tag: "自然人", total: 6, lowest: "非常满意", very: 6, basic: 0, bad: 0 }
|
|
|
},
|
|
|
{
|
|
|
name: "张凤云", idCard: "350102196812090219", phone: "", ticketId: "VC024",
|
|
|
baishuiResp: "已采集,已注册", verifyTime: "2026-08-21 11:20:18", hasPhoto: false, needCollect: false,
|
|
|
health: { companyCount: 1, red: 0, blue: 0, violation: 0, undeclare: 0 },
|
|
|
smart: { tag: "财务负责人", total: 1, lowest: "基本满意", very: 0, basic: 1, bad: 0 }
|
|
|
},
|
|
|
{
|
|
|
name: "李郁艳", idCard: "350582199808081234", phone: "13606001234", ticketId: "",
|
|
|
baishuiResp: "未采集,未注册", verifyTime: "2026-08-21 11:33:44", hasPhoto: true, needCollect: true,
|
|
|
health: { queryFail: true, reason: "体检查询失败" },
|
|
|
smart: { unavailable: true, reason: "暂无评价信息" }
|
|
|
}
|
|
|
];
|
|
|
|
|
|
const SIZE = 10;
|
|
|
let filtered = ALL.slice();
|
|
|
let page = 1;
|
|
|
|
|
|
const maskId = (v) => !v ? "-" : v.replace(/^(.{4}).*(.{4})$/, "$1********$2");
|
|
|
const maskPhone = (v) => !v ? "-" : v.replace(/^(.{3}).*(.{4})$/, "$1****$2");
|
|
|
|
|
|
function healthHtml(h) {
|
|
|
if (h.unavailable || h.queryFail) return `<span class="muted">${h.reason}</span>`;
|
|
|
if (!h.companyCount) return `0户关联企业`;
|
|
|
const parts = [`${h.companyCount}户关联企业`];
|
|
|
if (h.red) parts.push(`预警: <span class="warn-red">${h.red}户红色</span>`);
|
|
|
if (h.blue) parts.push(`预警: <span class="warn-blue">${h.blue}户蓝色</span>`);
|
|
|
if (h.violation) parts.push(`${h.violation}条未处理违法违章`);
|
|
|
if (h.undeclare) parts.push(`${h.undeclare}条未申报`);
|
|
|
return parts.join(";");
|
|
|
}
|
|
|
|
|
|
function smartHtml(s) {
|
|
|
if (s.unavailable) return `<span class="muted">${s.reason || "暂无提醒"}</span>`;
|
|
|
const tag = s.tag ? `标签: ${s.tag}` : "标签: 无";
|
|
|
if (!s.total) return `${tag};<span class="muted">无评价信息</span>`;
|
|
|
return `${tag};评价: ${s.total}次,最低评价: ${s.lowest}。非常满意${s.very}次,基本满意${s.basic}次,不满意${s.bad}次`;
|
|
|
}
|
|
|
|
|
|
function render() {
|
|
|
const totalPages = Math.max(1, Math.ceil(filtered.length / SIZE));
|
|
|
if (page > totalPages) page = totalPages;
|
|
|
const start = (page - 1) * SIZE;
|
|
|
const rows = filtered.slice(start, start + SIZE);
|
|
|
document.getElementById("tbody").innerHTML = rows.map((item, i) => `
|
|
|
<tr>
|
|
|
<td class="col-name">${item.name || "-"}</td>
|
|
|
<td class="col-id">${maskId(item.idCard)}</td>
|
|
|
<td class="col-phone">${maskPhone(item.phone)}</td>
|
|
|
<td class="col-ticket">${item.ticketId || "-"}</td>
|
|
|
<td class="col-verify">${item.baishuiResp || "-"}</td>
|
|
|
<td class="col-time">${item.verifyTime || "-"}</td>
|
|
|
<td class="col-photo">${item.hasPhoto ? '<button class="link" onclick="alert(\'预览:查看照片\')">查看照片</button>' : "-"}</td>
|
|
|
<td class="col-health"><div class="summary" onclick="openHealth(${start + i})">${healthHtml(item.health)}</div></td>
|
|
|
<td class="col-smart"><div class="summary" onclick="openSmart(${start + i})">${smartHtml(item.smart)}</div></td>
|
|
|
<td class="col-op">
|
|
|
<div class="row-actions">
|
|
|
<button class="table-action" onclick="alert('预览:取号')">取号</button>
|
|
|
<button class="table-action" onclick="alert('预览:健康报告')">健康报告</button>
|
|
|
${item.needCollect ? '<button class="table-action gray" onclick="alert(\'预览:采集\')">采集</button>' : ""}
|
|
|
</div>
|
|
|
</td>
|
|
|
</tr>
|
|
|
`).join("");
|
|
|
document.getElementById("totalText").textContent = filtered.length;
|
|
|
document.getElementById("pageNum").textContent = page;
|
|
|
document.getElementById("pageTotal").textContent = totalPages;
|
|
|
document.getElementById("prevBtn").disabled = page <= 1;
|
|
|
document.getElementById("nextBtn").disabled = page >= totalPages;
|
|
|
}
|
|
|
|
|
|
function applyFilter() {
|
|
|
const n = document.getElementById("qName").value.trim();
|
|
|
const id = document.getElementById("qId").value.trim();
|
|
|
const p = document.getElementById("qPhone").value.trim();
|
|
|
filtered = ALL.filter((x) =>
|
|
|
(!n || x.name.includes(n)) &&
|
|
|
(!id || x.idCard.includes(id)) &&
|
|
|
(!p || x.phone.includes(p))
|
|
|
);
|
|
|
page = 1;
|
|
|
render();
|
|
|
}
|
|
|
function resetFilter() {
|
|
|
document.getElementById("qName").value = "";
|
|
|
document.getElementById("qId").value = "";
|
|
|
document.getElementById("qPhone").value = "";
|
|
|
filtered = ALL.slice();
|
|
|
page = 1;
|
|
|
render();
|
|
|
}
|
|
|
function changePage(d) { page += d; render(); }
|
|
|
|
|
|
function openHealth(i) {
|
|
|
const item = filtered[i];
|
|
|
const h = item.health;
|
|
|
document.getElementById("modalTitle").textContent = `一键体检 · ${item.name}`;
|
|
|
document.getElementById("modalBody").innerHTML = h.unavailable || h.queryFail
|
|
|
? `<div class="kv">${h.reason}</div><div class="note">无可靠身份或采集未完成时,应明确提示,避免空白被理解成「没问题」。</div>`
|
|
|
: `<div class="kv"><b>关联企业:</b>${h.companyCount} 户</div>
|
|
|
<div class="kv"><b>红色预警:</b><span class="warn-red">${h.red} 户</span></div>
|
|
|
<div class="kv"><b>蓝色预警:</b><span class="warn-blue">${h.blue} 户</span></div>
|
|
|
<div class="kv"><b>未处理违法违章:</b>${h.violation} 条</div>
|
|
|
<div class="kv"><b>未申报:</b>${h.undeclare} 条</div>
|
|
|
<div class="note">此为展示用模拟数据。点击列表摘要可下钻到分户风险与申报明细(正式环境对接金三/风控)。</div>`;
|
|
|
document.getElementById("mask").classList.add("show");
|
|
|
}
|
|
|
function openSmart(i) {
|
|
|
const item = filtered[i];
|
|
|
const s = item.smart;
|
|
|
document.getElementById("modalTitle").textContent = `智能提醒 · ${item.name}`;
|
|
|
document.getElementById("modalBody").innerHTML = s.unavailable
|
|
|
? `<div class="kv">${s.reason}</div>`
|
|
|
: `<div class="kv"><b>人员标签:</b>${s.tag || "无"}</div>
|
|
|
<div class="kv"><b>评价次数:</b>${s.total} 次</div>
|
|
|
<div class="kv"><b>最低评价:</b>${s.lowest || "-"}</div>
|
|
|
<div class="kv"><b>非常满意 / 基本满意 / 不满意:</b>${s.very} / ${s.basic} / ${s.bad}</div>
|
|
|
<div class="note">此为展示用模拟数据。正式环境按身份证汇总窗口评价器历史记录。</div>`;
|
|
|
document.getElementById("mask").classList.add("show");
|
|
|
}
|
|
|
function closeModal() { document.getElementById("mask").classList.remove("show"); }
|
|
|
|
|
|
render();
|
|
|
</script>
|
|
|
</body>
|
|
|
</html>
|