HEL-177: 公司端按方案 A 实现转账往来四层页面

工作台概览小卡 + 侧栏入口;总览/对方汇总/明细/原始流水抽屉接入 HEL-175/176 接口;无期初时展示期间净变动;模块内用 info 品蓝。

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: multica-agent <github@multica.ai>
This commit is contained in:
总工
2026-08-27 13:45:19 +00:00
co-authored by Cursor multica-agent
parent 96309eb2cc
commit b27016d71d
7 changed files with 1352 additions and 18 deletions
+246 -14
View File
@@ -5,7 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="金牛集团公司业务端" />
<title>公司业务端 · 金牛集团</title>
<link rel="stylesheet" href="design-system.css?v=5" />
<link rel="stylesheet" href="design-system.css?v=6" />
</head>
<body data-portal="company">
<a class="skip-link" href="#main-content">跳到主要内容</a>
@@ -22,6 +22,7 @@
<a data-view="upload" href="#upload"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7"><path d="M12 16V4m0 0l-4 4m4-4l4 4"/><path d="M4 15v3a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-3"/></svg><span class="nav-label">流水导入</span></a>
<a data-view="manual" href="#manual"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7"><path d="M12 20h9"/><path d="M16.5 3.5a2.1 2.1 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z"/></svg><span class="nav-label">手工记录</span></a>
<a data-view="flows" href="#flows"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7"><path d="M4 6h16M4 12h16M4 18h10"/></svg><span class="nav-label">流水管理</span></a>
<a data-view="transfers" href="#transfers"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7"><path d="M7 7h13v3l-4-2.5L20 5V8"/><path d="M17 17H4v-3l4 2.5L4 19v-3"/><rect x="3" y="3" width="18" height="18" rx="2"/></svg><span class="nav-label">转账往来</span><span class="nav-badge" id="transfersNavBadge" hidden>0</span></a>
<a data-view="reconcile" href="#reconcile"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7"><path d="M9 11.5l2 2 4-4.5"/><rect x="4" y="3" width="16" height="18" rx="2"/></svg><span class="nav-label">往来确认</span><span class="nav-badge">5</span></a>
<div class="nav-group">账户与消息</div>
<a data-view="accounts" href="#accounts"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7"><rect x="3" y="5" width="18" height="14" rx="2"/><path d="M3 10h18"/></svg><span class="nav-label">银行账户</span></a>
@@ -141,29 +142,29 @@
</div>
<div class="stack">
<div class="card">
<div class="card" id="workspaceTransfersCard">
<div class="card-head">
<span class="card-title">本公司往来合计<span class="sub">2026-01-01 至 2026-08-20 · 与管理端口径一致 · 单位:万元</span></span>
<span class="card-title">转账往来概览<span class="sub" id="workspaceTransfersSub">加载中…</span></span>
</div>
<div class="mini-stats">
<div class="mini-stats" id="workspaceTransfersStats">
<div class="mini-stat">
<div class="ms-label">借方合计</div>
<div class="ms-value">18,420.50<span class="unit">万元</span></div>
<div class="ms-label">转入合计</div>
<div class="ms-value pos" id="wsTfIn"></div>
</div>
<div class="mini-stat">
<div class="ms-label">贷方合计</div>
<div class="ms-value">12,386.00<span class="unit">万元</span></div>
<div class="ms-label">转出合计</div>
<div class="ms-value neg" id="wsTfOut"></div>
</div>
<div class="mini-stat">
<div class="ms-label">明细笔数</div>
<div class="ms-value">128<span class="unit"></span></div>
<div class="ms-label" id="wsTfNetLabel">期间净变动</div>
<div class="ms-value" id="wsTfNet"></div>
</div>
<div class="mini-stat">
<div class="ms-label">期末净往来 · 应收方向</div>
<div class="ms-value pos">+6,034.50<span class="unit">万元</span></div>
<div class="ms-label">待确认 · 不计入合计</div>
<div class="ms-value" id="wsTfPending" style="color: var(--warn);"></div>
</div>
</div>
<button class="btn btn-ghost" data-view-link="flows" style="width: 100%; margin-top: 12px;">查看本公司逐笔流水</button>
<button class="btn btn-ghost" data-view-link="transfers" style="width: 100%; margin-top: 12px;">查看转账往来明细</button>
</div>
<div class="card">
@@ -421,6 +422,214 @@
</div>
</section>
<section class="app-view" data-page="transfers">
<div id="transfersOverviewLayer">
<div class="page-head">
<div>
<h1>转账往来</h1>
<p class="page-sub" id="transfersPageSub">加载本公司与集团内其他公司的转账往来…</p>
</div>
<div class="page-actions">
<button class="btn" type="button" id="transfersExportBtn">导出台账</button>
<button class="btn btn-primary" type="button" id="transfersGoConfirm" data-view-link="reconcile" hidden>去确认待确认</button>
</div>
</div>
<div id="transfersLoading" class="card" hidden>
<div class="grid grid-4" style="margin-bottom: 14px;">
<div class="skeleton" style="height: 88px;"></div>
<div class="skeleton" style="height: 88px;"></div>
<div class="skeleton" style="height: 88px;"></div>
<div class="skeleton" style="height: 88px;"></div>
</div>
<div class="skeleton skeleton-line" style="width: 70%;"></div>
<div class="skeleton skeleton-line" style="width: 92%;"></div>
<div class="skeleton skeleton-line" style="width: 55%; margin-bottom: 0;"></div>
<div class="loading-inline" style="margin-top: 16px;">加载中,正在计算往来余额…</div>
</div>
<div id="transfersError" class="notice danger" hidden>
<div>
<div class="n-title">转账往来数据加载失败</div>
<div class="n-body" id="transfersErrorBody">服务器连接异常。为避免误读,本页不展示任何金额。</div>
</div>
<div class="row" style="margin-top: 12px; gap: 8px;">
<button class="btn btn-primary" type="button" id="transfersRetryBtn">重新加载</button>
</div>
</div>
<div id="transfersEmpty" class="card" hidden>
<div class="grid grid-4" id="transfersEmptyStats"></div>
<div class="empty" style="margin-top: 14px;">
<div class="e-title">该期间暂无转账往来</div>
<div>可能尚未导入流水,或集团内往来确认尚未完成。导入本公司银行流水后,系统会自动计算公司间往来。</div>
<div class="row" style="justify-content: center; margin-top: 14px; gap: 8px;">
<button class="btn btn-primary" type="button" data-view-link="upload">去导入流水</button>
<button class="btn" type="button" data-view-link="accounts">查看银行账户</button>
</div>
</div>
</div>
<div id="transfersData" hidden>
<div class="grid grid-4" id="transfersStatGrid">
<div class="card stat-card">
<div class="stat-label"><span class="stat-dot info"></span>往来公司数</div>
<div class="stat-value" id="tfStatCompanies"><span class="unit"></span></div>
<div class="stat-foot" id="tfStatCompaniesFoot">统计窗口内有往来的对方公司</div>
</div>
<div class="card stat-card">
<div class="stat-label"><span class="stat-dot success"></span>本期转入 · 流入</div>
<div class="stat-value amt-in" id="tfStatIn"></div>
<div class="stat-foot">已确认转入合计 · 待确认不计入</div>
</div>
<div class="card stat-card">
<div class="stat-label"><span class="stat-dot danger"></span>本期转出 · 流出</div>
<div class="stat-value amt-out" id="tfStatOut"></div>
<div class="stat-foot">已确认转出合计 · 待确认不计入</div>
</div>
<div class="card stat-card">
<div class="stat-label"><span class="stat-dot info"></span><span id="tfStatNetTitle">期间净变动</span></div>
<div class="stat-value" id="tfStatNet"></div>
<div class="stat-foot" id="tfStatNetFoot">正数=应收方向 · 负数=应付方向</div>
</div>
</div>
<div class="xfer-split" id="transfersSplit" style="margin-top: 14px;">
<div class="xfer-split-pane confirmed">
<div class="xfer-split-head">
<span class="pill pill-success">已确认</span>
<span class="meta" id="tfConfirmedCount">0 笔</span>
</div>
<div class="xfer-split-value num" id="tfConfirmedNet"></div>
<div class="xfer-split-note">计入上方合计与期间净变动</div>
</div>
<div class="xfer-split-pane pending">
<div class="xfer-split-head">
<span class="pill pill-warn">待确认</span>
<span class="meta" id="tfPendingCount">0 笔</span>
</div>
<div class="xfer-split-value num" id="tfPendingAmount"></div>
<div class="xfer-split-note">单列展示,不计入已确认合计</div>
</div>
</div>
<div class="card" style="margin-top: 14px;">
<div class="card-head">
<span class="card-title">按对方公司查看<span class="sub">点击行进入该公司往来明细</span></span>
<span class="pill pill-info">仅本公司数据</span>
</div>
<div class="table-wrap" style="border: 0;">
<table class="ds-table" id="transfersCpTable">
<thead>
<tr>
<th>对方公司</th>
<th class="num-col">已确认转入</th>
<th class="num-col">已确认转出</th>
<th class="num-col">净往来</th>
<th>方向</th>
<th>待确认</th>
<th>最近往来日</th>
</tr>
</thead>
<tbody id="transfersCpBody"></tbody>
<tfoot id="transfersCpFoot"></tfoot>
</table>
</div>
</div>
<div class="notice info" style="margin-top: 14px;">
<div class="n-title">口径说明</div>
<div class="n-body">仅含集团内公司间转账(HEL-169)。已确认与待确认严格分开;待确认不计入合计。起算日/期初未就绪时展示「期间净变动」,不得当作期末余额。银行原始流水只读,调整须走冲销/调整单留痕。</div>
</div>
</div>
</div>
<div id="transfersDetailLayer" hidden>
<div class="page-head">
<div>
<button class="btn btn-ghost" type="button" id="transfersBackBtn" style="padding-left: 0; margin-bottom: 4px;">← 返回总览</button>
<h1 id="transfersDetailTitle">往来明细</h1>
<p class="page-sub" id="transfersDetailSub">筛选后加载更多 · 单位:万元</p>
</div>
<div class="page-actions">
<button class="btn" type="button" id="transfersDetailExportBtn">导出台账</button>
</div>
</div>
<div class="grid grid-3" id="transfersDetailStats" style="margin-bottom: 14px;">
<div class="card stat-card">
<div class="stat-label">往来笔数</div>
<div class="stat-value" id="tfDetailCount"></div>
<div class="stat-foot" id="tfDetailCountFoot">当前筛选</div>
</div>
<div class="card stat-card">
<div class="stat-label">转入 · 流入</div>
<div class="stat-value amt-in" id="tfDetailIn"></div>
</div>
<div class="card stat-card">
<div class="stat-label">转出 · 流出</div>
<div class="stat-value amt-out" id="tfDetailOut"></div>
</div>
</div>
<form class="filters" id="transfersFilterForm" novalidate>
<div class="field">
<label for="tfFilterDirection">方向</label>
<select class="select" id="tfFilterDirection" name="direction">
<option value="">全部</option>
<option value="in">转入</option>
<option value="out">转出</option>
</select>
</div>
<div class="field">
<label for="tfFilterState">确认状态</label>
<select class="select" id="tfFilterState" name="state">
<option value="">全部</option>
<option value="confirmed">已确认</option>
<option value="pending">待确认</option>
</select>
</div>
<div class="field">
<label for="tfFilterFrom">日期起</label>
<input class="input num-input" id="tfFilterFrom" name="from" type="date" />
</div>
<div class="field">
<label for="tfFilterTo">日期止</label>
<input class="input num-input" id="tfFilterTo" name="to" type="date" />
</div>
<button class="btn" type="button" id="tfFilterReset">清空筛选</button>
<button class="btn btn-primary" type="submit">查询</button>
</form>
<div class="table-wrap">
<table class="ds-table" id="transfersEventTable">
<thead>
<tr>
<th>日期</th>
<th class="wrap">摘要</th>
<th>方向</th>
<th class="num-col">金额(万元)</th>
<th>状态</th>
<th></th>
</tr>
</thead>
<tbody id="transfersEventBody"></tbody>
</table>
<div class="empty" id="transfersEventEmpty" hidden>
<div class="e-title">当前筛选条件下没有流水</div>
<div>可清空筛选后重试,或返回总览查看其他对方公司。</div>
<div class="row" style="justify-content: center; margin-top: 12px;">
<button class="btn" type="button" id="tfEmptyClear">清空筛选</button>
</div>
</div>
<div class="table-foot">
<span id="transfersEventFoot">共 0 笔</span>
<button class="btn btn-sm" type="button" id="transfersLoadMore" hidden>加载更多</button>
</div>
</div>
</div>
</section>
<section class="app-view" data-page="reconcile">
<div class="page-head">
<div>
@@ -813,7 +1022,30 @@
</form>
</div>
</div>
<aside class="drawer" id="transferEvidenceDrawer" aria-label="银行原始流水" aria-hidden="true">
<div class="drawer-head">
<div>
<span class="pill pill-info" id="tfEvTag">银行原始流水 · 只读</span>
<h2 class="d-title" id="tfEvTitle">原始流水</h2>
<p class="d-desc" id="tfEvDesc"></p>
</div>
<button type="button" class="icon-button" data-close-transfer-evidence aria-label="关闭" title="关闭">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7"><path d="M6 6l12 12M18 6L6 18"/></svg>
</button>
</div>
<div class="drawer-body">
<dl class="kv" id="tfEvFields"></dl>
</div>
<div class="drawer-tip">
<strong>铁律提示</strong>
银行原始流水永远只读。金额或归属有误时,须由管理员通过冲销/调整单留痕处理,本页不得直接改数。
</div>
<div class="drawer-foot">
<button type="button" class="btn" data-close-transfer-evidence>关闭</button>
</div>
</aside>
<div class="toast-region" id="toastRegion" aria-live="polite"></div>
<script src="app.js?v=11"></script>
<script src="app.js?v=12"></script>
</body>
</html>