You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ElectronClient/tax-guidance/docs/预检取号-一键体检与智能提醒-预览.html

366 lines
18 KiB
HTML

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<!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>