B-44: intercompany ledger events, subject review and drill-down evidence

- migration 6: manual_records, ledger_event_revisions chain, current
  projections, source claims, subject suggestions, eligible_position_events
- ledger_events.py: bank-event reconciliation, reversal/adjustment/reopen,
  append-only revision chain and rebuildable current projection
- subjects.py: fixed subject mirror, draft suggestion dictionary, explicit
  administrator subject confirmation with expected_revision + idempotency
- manual_records.py: submit, approve new/link, return/exception/reverse,
  candidate hints, idempotent replay and concurrency-safe claims
- positions.py: Decimal aggregation, both-perspective conservation asserts,
  cutoff window, unresolved gross buckets, keyset pagination, evidence
  visibility (visible/masked/missing)
- server.py: admin + company intercompany APIs with tenant isolation (404 on
  cross-tenant reads, 403 on company writes) and auto reconcile wiring
- admin/company portals: balance directory, pair drill-down drawer, evidence
  drawer, subject/manual audit queue, company balance summary
- tests: ledger events, subjects, manual records, positions, HTTP API and
  migration persistence (233 total, all green)
This commit is contained in:
腾讯WorkBuddy
2026-08-19 11:58:25 +08:00
parent f99917321b
commit 85293b79df
18 changed files with 6902 additions and 142 deletions
+23 -12
View File
@@ -22,7 +22,7 @@
<div class="brand"><span class="brand-mark"></span><span class="brand-copy"><strong>金牛集团</strong><small>总账管理端</small></span></div>
<nav class="nav-list">
<button class="nav-item is-active" data-view="dashboard"><svg><use href="icons.svg#layout-dashboard"/></svg><span>管理总览</span></button>
<button class="nav-item" data-view="pair"><svg><use href="icons.svg#arrow-left-right"/></svg><span>往来查询</span></button>
<button class="nav-item" data-view="pair"><svg><use href="icons.svg#arrow-left-right"/></svg><span>往来余额</span></button>
<button class="nav-item" data-view="audit"><svg><use href="icons.svg#list-checks"/></svg><span>审核中心</span><b>6</b></button>
<button class="nav-item" data-view="flows"><svg><use href="icons.svg#file-spreadsheet"/></svg><span>流水管理</span></button>
<button class="nav-item" data-view="companies"><svg><use href="icons.svg#users"/></svg><span>公司与账号</span></button>
@@ -147,21 +147,21 @@
</section>
<section class="app-view" data-page="pair">
<header class="page-heading"><div><h1>往来查询</h1><p>公司对查询双方口径、科目和逐笔凭证</p></div></header>
<header class="page-heading"><div><h1>往来余额</h1><p>公司间往来余额目录、公司对明细与逐层追溯</p></div>
<span class="status neutral" id="balanceOpeningNote">期初不可用 · 仅显示期间净变动</span>
</header>
<section class="query-band">
<form class="pair-query-form" data-pair-form>
<label class="field"><span>本方公司</span><select name="from"><option>A公司</option><option>B公司</option><option>C公司</option><option>D公司</option><option>E公司</option><option>F公司</option></select></label>
<button class="swap-button" type="button" data-swap aria-label="交换公司" title="交换公司"><svg><use href="icons.svg#arrow-left-right"/></svg></button>
<label class="field"><span>对方公司</span><select name="to"><option>B公司</option><option>C公司</option><option>D公司</option><option>E公司</option><option>F公司</option><option>A公司</option></select></label>
<label class="field"><span>统计截止</span><input name="end" type="date" value="2026-07-31" /></label>
<form class="pair-query-form" data-balance-form>
<label class="field"><span>统计起始</span><input name="from" type="date" value="2026-01-01" /></label>
<label class="field"><span>统计截止</span><input name="cutoff" type="date" value="2026-07-31" /></label>
<label class="field"><span>币种</span><select name="currency"><option value="">全部币种</option><option value="CNY">CNY</option><option value="RMB">RMB</option></select></label>
<button class="button primary" type="submit"><svg><use href="icons.svg#search"/></svg>查询</button>
</form>
</section>
<section class="pair-report" id="pairReport">
<header class="pair-report-heading"><div><h2><span data-pair-from>A公司</span><span data-pair-to>B公司</span></h2><p id="pairPeriod">统计口径 2026.01.01—2026.07.31</p></div><span class="status warning" id="pairReviewStatus">含 1 笔待审核</span></header>
<div class="pair-balance-line"><div><span>期初余额</span><strong id="pairOpening">0.00</strong></div><div><span>本期借方</span><strong id="pairDebit">2,416.00</strong></div><div><span>本期贷方</span><strong id="pairCredit">1,136.00</strong></div><div class="pair-final"><span>期末结果</span><strong id="pairFinal">应收 1,280.00<small>万元</small></strong></div></div>
<div class="subject-strip"><button class="is-active" data-subject-filter="all" aria-pressed="true"><span>全部往来</span><strong data-subject-total="all">5 笔</strong></button><button data-subject-filter="应收" aria-pressed="false"><span>应收</span><strong data-subject-total="应收">1,280.00</strong></button><button data-subject-filter="其他应收" aria-pressed="false"><span>其他应收</span><strong data-subject-total="其他应收">640.00</strong></button><button data-subject-filter="应付" aria-pressed="false"><span>应付</span><strong data-subject-total="应付">728.00</strong></button><button data-subject-filter="其他应付" aria-pressed="false"><span>其他应付</span><strong data-subject-total="其他应付">408.00</strong></button></div>
<div class="table-scroll"><table class="data-table" id="pairTransactions"><thead><tr><th>交易日期</th><th>方向</th><th>科目</th><th>本方账户</th><th>对方账户</th><th>摘要</th><th>匹配</th><th class="number">金额(万元)</th></tr></thead><tbody><tr data-subject="应收"><td>2026.07.18</td><td>转出</td><td>应收</td><td>中信 · 5316</td><td>工行 · 9481</td><td>往来款</td><td><span class="status success">双边匹配</span></td><td class="number">1,000.00</td></tr><tr data-subject="应收"><td>2026.07.06</td><td>转入</td><td>应收</td><td>中信 · 5316</td><td>工行 · 9481</td><td>归还往来款</td><td><span class="status success">双边匹配</span></td><td class="number">320.00</td></tr><tr data-subject="其他应收"><td>2026.06.27</td><td>转出</td><td>其他应收</td><td>建行 · 0845</td><td>工行 · 9481</td><td>资金调拨</td><td><span class="status warning">单边待核</span></td><td class="number">600.00</td></tr></tbody></table></div>
<section class="panel company-ledger-panel" aria-label="公司余额目录">
<div class="panel-heading"><div><h2>公司余额目录</h2><p>每行余额都附带截止日、期初状态、本期借贷、结果与未决金额</p></div></div>
<div class="ledger-head is-balances"><span>公司</span><span>借方合计</span><span>贷方合计</span><span>期末结果</span><span>未决</span><span>截止日</span><span></span></div>
<div id="companyLedgers" class="company-ledgers" aria-live="polite"></div>
</section>
</section>
@@ -230,6 +230,17 @@
<footer><button type="button" class="button secondary" data-close-closing>取消</button><button class="button primary" type="submit">确认执行结账</button></footer>
</form>
</dialog>
<div class="drawer-scrim" id="drawerScrim" data-close-drawer aria-hidden="true"></div>
<aside class="drawer" id="evidenceDrawer" aria-label="往来明细与源行证据抽屉" aria-hidden="true">
<header class="drawer-header">
<div>
<div class="drawer-breadcrumb" id="drawerBreadcrumb"></div>
<h2 id="drawerTitle">往来明细</h2>
</div>
<button type="button" class="icon-button" data-close-drawer aria-label="关闭抽屉" title="关闭"><svg><use href="icons.svg#x"/></svg></button>
</header>
<div class="drawer-body" id="drawerBody" tabindex="-1"></div>
</aside>
<div class="toast-region" id="toastRegion" aria-live="polite"></div>
<script src="app.js"></script>
</body>