HEL-162: 按方案A重做首页一体卡片主从区域

合并公司往来合计/明细为一张共享头卡片;左侧改列表行选中态,右侧加汇总条与克制空态;取消固定大高度,模块内滚动。

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: multica-agent <github@multica.ai>
This commit is contained in:
施工员
2026-08-26 15:40:07 +00:00
co-authored by Cursor multica-agent
parent b42b6481f5
commit 5b3ebad757
3 changed files with 438 additions and 92 deletions
+65 -40
View File
@@ -5,7 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="金牛集团管理端" /> <meta name="description" content="金牛集团管理端" />
<title>管理端 · 金牛集团</title> <title>管理端 · 金牛集团</title>
<link rel="stylesheet" href="design-system.css?v=6" /> <link rel="stylesheet" href="design-system.css?v=7" />
</head> </head>
<body data-portal="admin"> <body data-portal="admin">
<a class="skip-link" href="#main-content">跳到主要内容</a> <a class="skip-link" href="#main-content">跳到主要内容</a>
@@ -82,49 +82,74 @@
</div> </div>
</div> </div>
<div class="card" id="companyMasterDetail" style="margin-top: 14px; padding: 0; overflow: hidden;"> <div class="card dash-master" id="companyMasterDetail">
<div class="card-head dash-master-head">
<span class="card-title" style="min-width: 0;">
公司往来合计 · 往来明细
<span class="sub" id="dashListSub">单位:万元 · 左侧选择公司,右侧查看其往来明细</span>
</span>
<div class="dash-master-head-actions">
<span class="meta" id="dashMasterMeta"></span>
<input class="input" id="company-search" aria-label="搜索公司" placeholder="搜索公司…" />
</div>
</div>
<div class="grid grid-480-1 dash-master-split"> <div class="grid grid-480-1 dash-master-split">
<div class="dash-master-pane dash-master-pane--list"> <div class="dash-master-pane dash-master-pane--list">
<div class="card-head dash-master-head"> <div class="dash-company-list" id="dashCompanyRows" role="listbox" aria-label="公司往来合计">
<span class="card-title" style="min-width: 0;">公司往来合计<span class="sub" id="dashListSub" style="display: inline; margin-left: 6px;">单位:万元</span></span> <div class="dash-company-loading muted">加载中…</div>
<input class="input" id="company-search" aria-label="搜索公司" placeholder="搜索…" style="width: 120px; min-height: 28px; padding: 4px 8px; flex: none;" />
</div>
<div class="table-wrap dash-master-scroll">
<table class="ds-table ds-table--compact" id="dashCompanyTable">
<thead>
<tr>
<th>公司</th>
<th class="num-col">明细笔数</th>
<th class="num-col">期末净值</th>
<th id="dashStatusHead">状态</th>
</tr>
</thead>
<tbody id="dashCompanyRows">
<tr class="loading-row"><td colspan="4">加载中…</td></tr>
</tbody>
</table>
</div> </div>
</div> </div>
<div class="dash-master-pane"> <div class="dash-master-pane dash-master-pane--detail">
<div class="card-head dash-master-head"> <div class="dash-detail-toolbar">
<span class="card-title" id="dashDetailTitle">公司往来明细<span class="sub" id="dashDetailSub">选择左侧公司查看会计式分级明细</span></span> <div class="dash-detail-heading">
<span class="dash-detail-name" id="dashDetailTitle">请选择左侧公司</span>
<span class="meta" id="dashDetailSub">按对方公司分组 · 二级默认收起 · 已确认 / 待确认分列</span>
</div>
</div> </div>
<div class="table-wrap dash-master-scroll" id="dashDetailWrap"> <div class="dash-detail-summary" id="dashDetailSummary" hidden>
<table class="ds-table ds-table--compact" id="dashDetailTable"> <div class="dash-summary-item">
<thead> <span class="dash-summary-label">笔数</span>
<tr> <span class="dash-summary-value num" id="dashSumCount">0</span>
<th>对方 / 摘要</th> </div>
<th class="num-col">笔数</th> <div class="dash-summary-item">
<th class="num-col">期初</th> <span class="dash-summary-label">期初</span>
<th class="num-col">本期借方</th> <span class="dash-summary-value num" id="dashSumOpening"></span>
<th class="num-col">本期贷方</th> </div>
<th class="num-col">期末</th> <div class="dash-summary-item">
</tr> <span class="dash-summary-label">本期借方</span>
</thead> <span class="dash-summary-value num" id="dashSumDebit">0.00</span>
<tbody id="dashDetailRows"> </div>
<tr><td colspan="6" class="muted">请选择左侧公司</td></tr> <div class="dash-summary-item">
</tbody> <span class="dash-summary-label">本期贷方</span>
</table> <span class="dash-summary-value num" id="dashSumCredit">0.00</span>
</div>
<div class="dash-summary-item">
<span class="dash-summary-label">期末</span>
<span class="dash-summary-value num" id="dashSumEnding">0.00</span>
</div>
</div>
<div class="dash-detail-body" id="dashDetailBody">
<div class="table-wrap dash-master-scroll" id="dashDetailWrap">
<table class="ds-table ds-table--compact" id="dashDetailTable">
<thead>
<tr>
<th>对方 / 摘要</th>
<th class="num-col">笔数</th>
<th class="num-col">期初</th>
<th class="num-col">本期借方</th>
<th class="num-col">本期贷方</th>
<th class="num-col">期末</th>
</tr>
</thead>
<tbody id="dashDetailRows">
<tr><td colspan="6" class="muted">请选择左侧公司</td></tr>
</tbody>
</table>
</div>
<div class="dash-detail-empty" id="dashDetailEmpty" hidden>
<div class="e-title">该公司期间内暂无已归集往来</div>
<div class="e-desc" id="dashDetailEmptyDesc">期初 — · 导入流水并归集后在此展示</div>
</div>
</div> </div>
</div> </div>
</div> </div>
@@ -917,6 +942,6 @@
</div> </div>
</div> </div>
<div class="toast-region" id="toastRegion" aria-live="polite"></div> <div class="toast-region" id="toastRegion" aria-live="polite"></div>
<script src="app.js?v=6"></script> <script src="app.js?v=7"></script>
</body> </body>
</html> </html>
+144 -38
View File
@@ -1161,33 +1161,43 @@ function updateDashAuditCard(audit) {
} }
function renderDashCompanyRows(companies, selectedId) { function renderDashCompanyRows(companies, selectedId) {
const tbody = $("#dashCompanyRows"); const list = $("#dashCompanyRows");
if (!tbody) return; if (!list) return;
if (!companies.length) { if (!companies.length) {
tbody.innerHTML = '<tr><td colspan="4" class="muted">暂无公司或尚无归集往来</td></tr>'; list.innerHTML = '<div class="dash-company-empty muted">暂无公司或尚无归集往来</div>';
return; return;
} }
tbody.replaceChildren(...companies.map((company) => { const monthLabel = state.dashPeriodMonth ? `${state.dashPeriodMonth}` : "";
const tr = document.createElement("tr"); list.replaceChildren(...companies.map((company) => {
tr.className = "clickable"; const item = document.createElement("div");
tr.dataset.companyId = company.id; item.className = "dash-company-item";
item.setAttribute("role", "option");
item.dataset.companyId = company.id;
item.tabIndex = 0;
if (String(company.id) === String(selectedId)) { if (String(company.id) === String(selectedId)) {
tr.classList.add("is-selected"); item.classList.add("is-selected");
item.setAttribute("aria-selected", "true");
} else {
item.setAttribute("aria-selected", "false");
} }
const nameTd = document.createElement("td"); const main = document.createElement("div");
nameTd.className = "dash-company-name"; main.className = "dash-company-main";
nameTd.title = company.name; const name = document.createElement("span");
nameTd.textContent = company.name; name.className = "dash-company-name";
const countTd = document.createElement("td"); name.title = company.name;
countTd.className = "num-col"; name.textContent = company.name;
countTd.textContent = String(company.detail_count ?? 0); const meta = document.createElement("span");
const netTd = document.createElement("td"); meta.className = "dash-company-meta";
netTd.className = `num-col ${netClass(company.net_wan)}`; const statusLabel = company.period_status_label || "—";
netTd.textContent = formatWan(company.net_wan); meta.textContent = monthLabel
const statusTd = document.createElement("td"); ? `${company.detail_count ?? 0}笔 · ${monthLabel} ${statusLabel}`
statusTd.innerHTML = statusPill(company.period_status_label); : `${company.detail_count ?? 0}笔 · ${statusLabel}`;
tr.append(nameTd, countTd, netTd, statusTd); main.append(name, meta);
return tr; const net = document.createElement("span");
net.className = `dash-company-net ${netClass(company.net_wan)}`;
net.textContent = formatWan(company.net_wan);
item.append(main, net);
return item;
})); }));
} }
@@ -1199,22 +1209,94 @@ function chevronSvg(expanded) {
return '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" style="width:12px;height:12px;display:inline-block;vertical-align:-1px;margin-right:6px;"><path d="m9 18 6-6-6-6"/></svg>'; return '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" style="width:12px;height:12px;display:inline-block;vertical-align:-1px;margin-right:6px;"><path d="m9 18 6-6-6-6"/></svg>';
} }
function renderDashDetail(payload, { expandFirst = false } = {}) { function formatPlainWan(value) {
const num = Number(value);
if (!Number.isFinite(num)) return "0.00";
return Math.abs(num).toLocaleString("zh-CN", { minimumFractionDigits: 2, maximumFractionDigits: 2 });
}
function updateDashDetailSummary(company, payload) {
const bar = $("#dashDetailSummary");
if (!bar) return;
if (!company) {
bar.hidden = true;
return;
}
bar.hidden = false;
const count = payload?.groups
? payload.groups.reduce((sum, g) => sum + Number(g.count || 0), 0)
: Number(company.detail_count || 0);
const debit = payload?.groups
? payload.groups.reduce((sum, g) => sum + Number(g.debit_wan || 0), 0)
: Number(company.debit_wan || 0);
const credit = payload?.groups
? payload.groups.reduce((sum, g) => sum + Number(g.credit_wan || 0), 0)
: Number(company.credit_wan || 0);
const ending = payload?.groups
? payload.groups.reduce((sum, g) => sum + Number(g.ending_wan || 0), 0)
: Number(company.net_wan || 0);
const setText = (id, text, className = "") => {
const el = $(id);
if (!el) return;
el.textContent = text;
el.className = `dash-summary-value num ${className}`.trim();
};
setText("#dashSumCount", String(count));
setText("#dashSumOpening", "—", "meta");
setText("#dashSumDebit", formatPlainWan(debit));
setText("#dashSumCredit", formatPlainWan(credit));
setText("#dashSumEnding", formatWan(ending), netClass(ending));
}
function showDashDetailEmpty(company) {
const wrap = $("#dashDetailWrap");
const empty = $("#dashDetailEmpty");
const desc = $("#dashDetailEmptyDesc");
if (wrap) wrap.hidden = true;
if (empty) empty.hidden = false;
if (desc) {
const cutoff = state.dashCutoff || "—";
// 方案 A 空态:两行克制说明;期初口径仍为不可用(—),不伪造 0.00
desc.textContent = `期初 — · 截至 ${cutoff} 无明细记录 · 导入流水并归集后在此展示`;
}
updateDashDetailSummary(null);
}
function showDashDetailTable() {
const wrap = $("#dashDetailWrap");
const empty = $("#dashDetailEmpty");
if (wrap) wrap.hidden = false;
if (empty) empty.hidden = true;
}
function renderDashDetail(payload, { expandFirst = false, company = null } = {}) {
const tbody = $("#dashDetailRows"); const tbody = $("#dashDetailRows");
const title = $("#dashDetailTitle"); const title = $("#dashDetailTitle");
if (!tbody) return; if (!tbody) return;
const selected = company || (state.dashCompanies || []).find(
(c) => String(c.id) === String(payload?.company_id || state.dashSelectedId)
) || null;
if (!payload) { if (!payload) {
if (title) title.textContent = "请选择左侧公司";
showDashDetailTable();
tbody.innerHTML = '<tr><td colspan="6" class="muted">请选择左侧公司</td></tr>'; tbody.innerHTML = '<tr><td colspan="6" class="muted">请选择左侧公司</td></tr>';
updateDashDetailSummary(null);
return; return;
} }
if (title) { if (title) title.textContent = payload.company_name || selected?.name || "公司往来明细";
title.innerHTML = `公司往来明细 · ${payload.company_name}<span class="sub" id="dashDetailSub">按对方公司分组 · 二级默认收起 · 期初待 B-45</span>`; const sub = $("#dashDetailSub");
} if (sub) sub.textContent = "按对方公司分组 · 二级默认收起 · 已确认 / 待确认分列";
const groups = payload.groups || []; const groups = payload.groups || [];
if (!groups.length) { if (!groups.length) {
tbody.innerHTML = '<tr><td colspan="6" class="muted">该公司区间内暂无已归集往来</td></tr>'; showDashDetailEmpty(selected || { detail_count: 0, debit_wan: 0, credit_wan: 0, net_wan: 0 });
tbody.replaceChildren();
return; return;
} }
showDashDetailTable();
updateDashDetailSummary(selected, payload);
const rows = []; const rows = [];
groups.forEach((group, index) => { groups.forEach((group, index) => {
const expanded = expandFirst && index === 0; const expanded = expandFirst && index === 0;
@@ -1268,7 +1350,12 @@ async function resolveDashStartDate() {
async function loadDashCompanyDetail(companyId) { async function loadDashCompanyDetail(companyId) {
if (!companyId) return; if (!companyId) return;
state.dashSelectedId = companyId; state.dashSelectedId = companyId;
const company = (state.dashCompanies || []).find((c) => String(c.id) === String(companyId)) || null;
renderDashCompanyRows(state.dashCompanies || [], companyId); renderDashCompanyRows(state.dashCompanies || [], companyId);
const title = $("#dashDetailTitle");
if (title && company) title.textContent = company.name;
updateDashDetailSummary(company, null);
showDashDetailTable();
const tbody = $("#dashDetailRows"); const tbody = $("#dashDetailRows");
if (tbody) tbody.innerHTML = '<tr class="loading-row"><td colspan="6">加载中…</td></tr>'; if (tbody) tbody.innerHTML = '<tr class="loading-row"><td colspan="6">加载中…</td></tr>';
const from = await resolveDashStartDate(); const from = await resolveDashStartDate();
@@ -1278,7 +1365,7 @@ async function loadDashCompanyDetail(companyId) {
return; return;
} }
const result = await response.json().catch(() => null); const result = await response.json().catch(() => null);
renderDashDetail(result); renderDashDetail(result, { company });
} }
async function loadAdminDashboard() { async function loadAdminDashboard() {
@@ -1286,22 +1373,30 @@ async function loadAdminDashboard() {
const from = await resolveDashStartDate(); const from = await resolveDashStartDate();
const response = await fetch(`/api/admin/dashboard?from=${encodeURIComponent(from)}`).catch(() => null); const response = await fetch(`/api/admin/dashboard?from=${encodeURIComponent(from)}`).catch(() => null);
if (!response?.ok) { if (!response?.ok) {
$("#dashCompanyRows").innerHTML = '<tr><td colspan="4" class="muted">总览加载失败</td></tr>'; $("#dashCompanyRows").innerHTML = '<div class="dash-company-empty muted">总览加载失败</div>';
return; return;
} }
const data = await response.json().catch(() => null); const data = await response.json().catch(() => null);
if (!data || data.status !== "ok") { if (!data || data.status !== "ok") {
$("#dashCompanyRows").innerHTML = '<tr><td colspan="4" class="muted">总览加载失败</td></tr>'; $("#dashCompanyRows").innerHTML = '<div class="dash-company-empty muted">总览加载失败</div>';
return; return;
} }
state.dashCompanies = data.companies || []; state.dashCompanies = data.companies || [];
state.dashFrom = data.from_date; state.dashFrom = data.from_date;
state.dashCutoff = data.cutoff; state.dashCutoff = data.cutoff;
state.dashPeriodMonth = data.period_month;
updateDashAuditCard(data.audit); updateDashAuditCard(data.audit);
const statusHead = $("#dashStatusHead");
if (statusHead && data.period_month) statusHead.textContent = `${data.period_month}月状态`;
const listSub = $("#dashListSub"); const listSub = $("#dashListSub");
if (listSub) listSub.textContent = `${data.from_date}${data.cutoff} · 单位:万元`; if (listSub) {
listSub.textContent = `${data.from_date}${data.cutoff} · 单位:万元 · 左侧选择公司,右侧查看其往来明细`;
}
const meta = $("#dashMasterMeta");
if (meta) {
const totals = data.totals || {};
const companyCount = totals.company_count ?? state.dashCompanies.length;
const detailCount = totals.detail_count ?? 0;
meta.textContent = `${companyCount} 家公司 · 明细 ${detailCount}`;
}
const selected = state.dashSelectedId || state.dashCompanies[0]?.id; const selected = state.dashSelectedId || state.dashCompanies[0]?.id;
renderDashCompanyRows(state.dashCompanies, selected); renderDashCompanyRows(state.dashCompanies, selected);
if (selected) await loadDashCompanyDetail(selected); if (selected) await loadDashCompanyDetail(selected);
@@ -1309,10 +1404,21 @@ async function loadAdminDashboard() {
function initDashboard() { function initDashboard() {
if (!$("#companyMasterDetail")) return; if (!$("#companyMasterDetail")) return;
const selectCompany = (companyId) => {
if (!companyId) return;
loadDashCompanyDetail(companyId);
};
$("#dashCompanyRows")?.addEventListener("click", (event) => { $("#dashCompanyRows")?.addEventListener("click", (event) => {
const tr = event.target.closest("tr[data-company-id]"); const item = event.target.closest(".dash-company-item[data-company-id]");
if (!tr) return; if (!item) return;
loadDashCompanyDetail(tr.dataset.companyId); selectCompany(item.dataset.companyId);
});
$("#dashCompanyRows")?.addEventListener("keydown", (event) => {
if (event.key !== "Enter" && event.key !== " ") return;
const item = event.target.closest(".dash-company-item[data-company-id]");
if (!item) return;
event.preventDefault();
selectCompany(item.dataset.companyId);
}); });
$("#dashDetailRows")?.addEventListener("click", (event) => { $("#dashDetailRows")?.addEventListener("click", (event) => {
const tr = event.target.closest("tr[data-peer-group]"); const tr = event.target.closest("tr[data-peer-group]");
@@ -1330,8 +1436,8 @@ function initDashboard() {
}); });
$("#company-search")?.addEventListener("input", function () { $("#company-search")?.addEventListener("input", function () {
const q = this.value.trim(); const q = this.value.trim();
$$("#dashCompanyRows tr[data-company-id]").forEach((tr) => { $$("#dashCompanyRows .dash-company-item[data-company-id]").forEach((item) => {
tr.style.display = (!q || tr.textContent.includes(q)) ? "" : "none"; item.style.display = (!q || item.textContent.includes(q)) ? "" : "none";
}); });
}); });
loadAdminDashboard(); loadAdminDashboard();
+229 -14
View File
@@ -216,23 +216,176 @@ p { margin: 0; }
/* 管理端首页主从:左栏约 480px(定稿 HEL-153),右侧明细更宽 */ /* 管理端首页主从:左栏约 480px(定稿 HEL-153),右侧明细更宽 */
.grid-480-1 { grid-template-columns: minmax(0, 480px) minmax(0, 1fr); align-items: stretch; } .grid-480-1 { grid-template-columns: minmax(0, 480px) minmax(0, 1fr); align-items: stretch; }
/* 方案 A:一体卡片 · 分栏主从(HEL-162) */
.dash-master {
margin-top: 14px;
padding: 0;
overflow: hidden;
}
.dash-master-head {
padding: 12px 16px 10px;
margin-bottom: 0;
gap: 10px;
border-bottom: 1px solid var(--border);
flex-wrap: wrap;
}
.dash-master-head .card-title .sub {
display: inline;
margin-left: 6px;
}
.dash-master-head-actions {
display: flex;
align-items: center;
gap: 10px;
flex: none;
margin-left: auto;
}
.dash-master-head-actions .input {
width: 132px;
min-height: 28px;
padding: 4px 8px;
flex: none;
}
.dash-master-split { .dash-master-split {
gap: 0; gap: 0;
height: 492px; /* 少数据自适应;整卡(含共享头)目标约 340px;多数据模块内滚动 */
max-height: 300px;
} }
.dash-master-pane { .dash-master-pane {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
min-width: 0; min-width: 0;
min-height: 0; min-height: 0;
overflow: hidden;
} }
.dash-master-pane--list { .dash-master-pane--list {
border-right: 1px solid var(--border); border-right: 1px solid var(--border);
} }
.dash-master-head { .dash-company-list {
padding: 10px 14px 8px; flex: 1;
margin-bottom: 0; min-height: 0;
gap: 8px; overflow: auto;
}
.dash-company-loading,
.dash-company-empty {
padding: 16px;
font-size: 13px;
}
.dash-company-item {
display: flex;
align-items: center;
gap: 12px;
padding: 8px 14px 8px 16px;
border-bottom: 1px solid var(--border);
cursor: pointer;
transition: background 0.12s ease;
}
.dash-company-item:last-child {
border-bottom: 0;
}
.dash-company-item:hover {
background: var(--fg-soft);
}
.dash-company-item.is-selected {
background: var(--accent-soft);
box-shadow: inset 3px 0 0 var(--accent);
padding-left: 13px;
}
.dash-company-item.is-selected:hover {
background: var(--accent-soft);
}
.dash-company-main {
min-width: 0;
flex: 1;
}
.dash-company-name {
display: block;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
font-size: 13.5px;
font-weight: 550;
color: var(--fg);
line-height: 1.35;
}
.dash-company-meta {
display: block;
margin-top: 2px;
font-size: 12px;
color: var(--muted);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.dash-company-net {
flex: none;
font-family: var(--font-mono);
font-variant-numeric: tabular-nums;
font-size: 13px;
font-weight: 600;
text-align: right;
min-width: 4.5em;
}
.dash-detail-toolbar {
padding: 10px 14px 0;
flex: none;
}
.dash-detail-heading {
display: flex;
flex-direction: column;
gap: 2px;
min-width: 0;
}
.dash-detail-name {
font-size: 14px;
font-weight: 650;
color: var(--fg);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.dash-detail-summary {
display: grid;
grid-template-columns: repeat(5, minmax(0, 1fr));
gap: 0;
margin: 10px 14px 0;
border: 1px solid var(--border);
border-radius: var(--radius);
background: var(--bg);
flex: none;
}
.dash-summary-item {
padding: 8px 10px;
border-right: 1px solid var(--border);
min-width: 0;
}
.dash-summary-item:last-child {
border-right: 0;
}
.dash-summary-label {
display: block;
font-family: var(--font-mono);
font-size: 11px;
letter-spacing: 0.04em;
color: var(--muted);
margin-bottom: 2px;
}
.dash-summary-value {
display: block;
font-size: 13px;
font-weight: 600;
color: var(--fg);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.dash-detail-body {
flex: 1;
min-height: 0;
display: flex;
flex-direction: column;
position: relative;
margin-top: 8px;
} }
.dash-master-scroll { .dash-master-scroll {
border: 0; border: 0;
@@ -241,6 +394,32 @@ p { margin: 0; }
min-height: 0; min-height: 0;
overflow: auto; overflow: auto;
} }
.dash-detail-empty {
flex: 1;
min-height: 120px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
text-align: center;
padding: 20px 24px;
color: var(--muted);
font-size: 13px;
}
.dash-detail-empty .e-title {
font-weight: 600;
color: var(--fg);
margin-bottom: 6px;
}
.dash-detail-empty .e-desc {
max-width: 360px;
line-height: 1.55;
}
.dash-master-scroll[hidden],
.dash-detail-empty[hidden],
.dash-detail-summary[hidden] {
display: none !important;
}
.ds-table.ds-table--compact { .ds-table.ds-table--compact {
min-width: 0; min-width: 0;
} }
@@ -248,18 +427,16 @@ p { margin: 0; }
.ds-table.ds-table--compact td { .ds-table.ds-table--compact td {
padding: 6px 12px; padding: 6px 12px;
} }
.ds-table.ds-table--compact th {
font-size: 11px;
white-space: nowrap;
}
.ds-table tbody tr.is-selected { .ds-table tbody tr.is-selected {
background: var(--accent-soft); background: var(--accent-soft);
} }
.ds-table tbody tr.is-selected:hover { .ds-table tbody tr.is-selected:hover {
background: var(--accent-soft); background: var(--accent-soft);
} }
.dash-company-name {
white-space: nowrap;
max-width: 280px;
overflow: hidden;
text-overflow: ellipsis;
}
.row { display: flex; align-items: center; gap: 10px; } .row { display: flex; align-items: center; gap: 10px; }
.row-between { display: flex; align-items: center; justify-content: space-between; gap: 12px; } .row-between { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.stack { display: flex; flex-direction: column; gap: 14px; } .stack { display: flex; flex-direction: column; gap: 14px; }
@@ -271,15 +448,53 @@ p { margin: 0; }
@media (max-width: 1100px) { @media (max-width: 1100px) {
.grid-4, .grid-5 { grid-template-columns: repeat(2, minmax(0, 1fr)); } .grid-4, .grid-5 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid-3, .grid-2-1, .grid-1-2, .grid-3-2, .grid-480-1 { grid-template-columns: minmax(0, 1fr); } .grid-3, .grid-2-1, .grid-1-2, .grid-3-2, .grid-480-1 { grid-template-columns: minmax(0, 1fr); }
.dash-master-split { height: auto; max-height: none; } .dash-master-split {
.dash-master-pane--list { border-right: 0; border-bottom: 1px solid var(--border); } max-height: none;
.dash-master-pane { max-height: 420px; } }
.dash-master-pane--list {
border-right: 0;
border-bottom: 1px solid var(--border);
max-height: 280px;
}
.dash-master-pane--detail {
max-height: 420px;
}
.dash-detail-summary {
grid-template-columns: repeat(3, minmax(0, 1fr));
}
.dash-summary-item:nth-child(3) {
border-right: 0;
}
.dash-summary-item:nth-child(n+4) {
border-top: 1px solid var(--border);
}
} }
@media (max-width: 860px) { @media (max-width: 860px) {
.shell { grid-template-columns: 1fr; } .shell { grid-template-columns: 1fr; }
.sidebar { position: static; height: auto; } .sidebar { position: static; height: auto; }
.grid-2 { grid-template-columns: 1fr; } .grid-2 { grid-template-columns: 1fr; }
.content { padding: 16px 16px 48px; } .content { padding: 16px 16px 48px; }
.dash-master-head-actions {
width: 100%;
margin-left: 0;
justify-content: space-between;
}
.dash-master-head-actions .input {
flex: 1;
width: auto;
}
.dash-detail-summary {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
.dash-summary-item:nth-child(2n) {
border-right: 0;
}
.dash-summary-item:nth-child(3) {
border-right: 1px solid var(--border);
}
.dash-summary-item:nth-child(n+3) {
border-top: 1px solid var(--border);
}
} }
/* ─── 数据表 ────────────────────────────────────────────────────── */ /* ─── 数据表 ────────────────────────────────────────────────────── */