HEL-168: 公司端工作台待办按权威单边集合同步
确认成功后重拉 /api/company/workspace,去确认数字与本月待办共用同一口径; 新增公司端确认接口与 3→2→1→0 集成测试,失败/重复确认不误减。 Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: multica-agent <github@multica.ai>
This commit is contained in:
co-authored by
Cursor
multica-agent
parent
eefdc92ab6
commit
bf5754ee09
+235
-88
@@ -2548,100 +2548,245 @@ async function loadImportBatches() {
|
||||
if (foot) foot.textContent = batches.length ? `共 ${batches.length} 个批次` : "暂无批次";
|
||||
}
|
||||
|
||||
function refreshWorkspacePending() {
|
||||
const card = $("#workspaceTodos");
|
||||
if (!card) return;
|
||||
const count = $$(".list-row", card).length;
|
||||
const status = $("#workspacePendingStatus");
|
||||
if (status) status.textContent = `${count} 项待处理`;
|
||||
function formatWorkspaceAmount(amount, currency) {
|
||||
const n = Number(amount);
|
||||
const text = Number.isFinite(n)
|
||||
? n.toLocaleString("zh-CN", { minimumFractionDigits: 2, maximumFractionDigits: 2 })
|
||||
: String(amount ?? "—");
|
||||
return `${currency || "CNY"} ${text}`;
|
||||
}
|
||||
|
||||
function initReconcile() {
|
||||
const matchCards = $$("[data-match-card]");
|
||||
const subjectRows = $$("[data-subject-row]");
|
||||
if (!matchCards.length && !subjectRows.length) return;
|
||||
function applyCompanyWorkspace(payload) {
|
||||
const events = Array.isArray(payload?.unilateral_events) ? payload.unilateral_events : [];
|
||||
const pending = Number(payload?.pending_unilateral ?? events.length) || 0;
|
||||
const total = Number(payload?.pending_total ?? pending) || 0;
|
||||
state.workspace = { pending_unilateral: pending, pending_total: total, unilateral_events: events };
|
||||
|
||||
const cta = $("#workspaceUnilateralCta");
|
||||
if (cta) {
|
||||
cta.textContent = pending ? `去确认单边流水 (${pending})` : "单边流水已全部确认";
|
||||
cta.classList.toggle("btn-primary", pending > 0);
|
||||
}
|
||||
|
||||
const status = $("#workspacePendingStatus");
|
||||
if (status) {
|
||||
status.textContent = total ? `${total} 项待处理` : "已完成";
|
||||
status.className = `pill ${total ? "pill-warn" : "pill-success"}`;
|
||||
}
|
||||
|
||||
const sub = $("#workspaceTodoSub");
|
||||
if (sub) sub.textContent = total ? `权威待确认单边流水 ${pending} 笔` : "本月单边流水待办已清空";
|
||||
|
||||
const list = $("#workspaceTodoList");
|
||||
if (list) {
|
||||
list.replaceChildren();
|
||||
if (!events.length) {
|
||||
const empty = document.createElement("div");
|
||||
empty.className = "empty";
|
||||
empty.style.padding = "18px 16px";
|
||||
empty.innerHTML = '<div class="e-title">暂无待确认单边流水</div><div>刷新或重登后仍以服务端权威状态为准</div>';
|
||||
list.append(empty);
|
||||
} else {
|
||||
events.forEach((event) => {
|
||||
const row = document.createElement("div");
|
||||
row.className = "list-row";
|
||||
row.dataset.taskType = "match";
|
||||
row.dataset.eventId = String(event.event_id);
|
||||
row.innerHTML = `
|
||||
<span class="pill pill-danger">阻断</span>
|
||||
<div class="lr-main">
|
||||
<div class="lr-title">确认单边流水 · ${formatWorkspaceAmount(event.amount, event.currency)}</div>
|
||||
<div class="lr-sub">${event.counterparty_company_name || "对方待指定"} · ${event.effective_at || "—"}</div>
|
||||
</div>
|
||||
<button class="btn btn-sm" data-view-link="reconcile">去确认</button>`;
|
||||
list.append(row);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const foot = $("#workspaceTodoFoot");
|
||||
if (foot) {
|
||||
foot.innerHTML = total
|
||||
? `<span>处理完 ${total} 笔单边流水后,工作台数字与列表将同步归零</span>`
|
||||
: "<span>单边流水待办已完成</span>";
|
||||
}
|
||||
|
||||
const flowState = $("#workspaceConfirmState");
|
||||
if (flowState) flowState.textContent = pending ? `待处理 ${pending} 笔` : "已完成";
|
||||
const flowMeta = $("#workspaceConfirmMeta");
|
||||
if (flowMeta) {
|
||||
flowMeta.textContent = pending
|
||||
? `单边流水 ${pending} 笔待确认`
|
||||
: "已全部确认,等待集团结账";
|
||||
}
|
||||
|
||||
const countMatch = $("#count-match");
|
||||
if (countMatch) countMatch.textContent = String(pending);
|
||||
|
||||
const noticeTitle = $("#notice-title");
|
||||
const noticeBody = $("#notice-body");
|
||||
const notice = $("#blocking-notice");
|
||||
const matchedSummary = $("#matched-summary");
|
||||
const matchedList = $("#matched-list");
|
||||
const matchStack = $("#match-stack");
|
||||
let pendingMatch = matchCards.length;
|
||||
let pendingSubject = subjectRows.length;
|
||||
|
||||
function refreshCounts() {
|
||||
const countMatch = $("#count-match");
|
||||
const countSubject = $("#count-subject");
|
||||
if (countMatch) countMatch.textContent = pendingMatch;
|
||||
if (countSubject) countSubject.textContent = pendingSubject;
|
||||
const total = pendingMatch + pendingSubject;
|
||||
const badge = $('.side-nav a[data-view="reconcile"] .nav-badge');
|
||||
if (badge) {
|
||||
badge.textContent = total;
|
||||
badge.style.display = total ? "" : "none";
|
||||
}
|
||||
if (noticeTitle) {
|
||||
noticeTitle.textContent = total ? `${total} 项待确认,是 7 月结账的阻断项` : "全部确认完成";
|
||||
}
|
||||
if (noticeBody) {
|
||||
noticeBody.textContent = total
|
||||
? `含单边流水匹配 ${pendingMatch} 项、科目确认 ${pendingSubject} 项。请于 2026-08-29(7 月顺延结账日)前处理完毕,否则集团无法对贵公司执行 7 月结账。`
|
||||
: "本公司 2026-07 账期已具备结账条件,集团将于 08-29 统一执行结账。";
|
||||
}
|
||||
if (notice) {
|
||||
notice.classList.toggle("warn", total > 0);
|
||||
notice.classList.toggle("success", total === 0);
|
||||
}
|
||||
if (pendingMatch === 0) $('[data-task-type="match"]', $("#workspaceTodos"))?.remove();
|
||||
const matchRow = $('[data-task-type="match"]', $("#workspaceTodos"));
|
||||
if (matchRow) {
|
||||
const title = $(".lr-title", matchRow);
|
||||
if (title) title.textContent = `处理 ${pendingMatch} 笔单边流水确认`;
|
||||
}
|
||||
const subjectRow = $('[data-task-type="subject"]', $("#workspaceTodos"));
|
||||
if (subjectRow) {
|
||||
const title = $(".lr-title", subjectRow);
|
||||
if (title) title.textContent = `确认 ${pendingSubject} 笔其他应收科目`;
|
||||
}
|
||||
const flowState = $("#workspaceConfirmState");
|
||||
if (flowState) flowState.textContent = total ? `待处理 ${total} 笔` : "已完成";
|
||||
const flowMeta = $("#workspaceConfirmMeta");
|
||||
if (flowMeta) flowMeta.textContent = total ? `单边流水 ${pendingMatch} 笔 · 科目确认 ${pendingSubject} 笔` : "已全部确认,等待集团结账";
|
||||
refreshWorkspacePending();
|
||||
if (noticeTitle) {
|
||||
noticeTitle.textContent = pending
|
||||
? `${pending} 项单边流水待确认,是结账阻断项`
|
||||
: "单边流水已全部确认完成";
|
||||
}
|
||||
if (noticeBody) {
|
||||
noticeBody.textContent = pending
|
||||
? `工作台「去确认单边流水」与「本月待办」均读取同一权威集合(${pending} 笔)。确认成功后立即同步减一。`
|
||||
: "本公司单边流水待办已清空;刷新或重新登录后仍为 0。";
|
||||
}
|
||||
if (notice) {
|
||||
notice.classList.toggle("warn", pending > 0);
|
||||
notice.classList.toggle("success", pending === 0);
|
||||
}
|
||||
|
||||
matchCards.forEach((card) => {
|
||||
const confirmButton = $("[data-match-confirm]", card);
|
||||
const radios = $$('input[type="radio"]', card);
|
||||
radios.forEach((radio) => radio.addEventListener("change", () => { if (confirmButton) confirmButton.disabled = false; }));
|
||||
confirmButton?.addEventListener("click", () => {
|
||||
const summaryText = confirmButton.dataset.matchSummary || "已确认匹配";
|
||||
const badge = $('.side-nav a[data-view="reconcile"] .nav-badge');
|
||||
if (badge) {
|
||||
badge.textContent = pending;
|
||||
badge.style.display = pending ? "" : "none";
|
||||
}
|
||||
}
|
||||
|
||||
async function loadCompanyWorkspace() {
|
||||
const response = await fetch("/api/company/workspace").catch(() => null);
|
||||
if (response?.status === 401 || response?.status === 403) {
|
||||
window.location.href = "index.html";
|
||||
return null;
|
||||
}
|
||||
const result = await response?.json().catch(() => null);
|
||||
if (!response?.ok || !result || result.status !== "ok") {
|
||||
applyCompanyWorkspace({ pending_unilateral: 0, pending_total: 0, unilateral_events: [] });
|
||||
showToast("工作台待办读取失败", result?.message || "请稍后重试", "danger");
|
||||
return null;
|
||||
}
|
||||
applyCompanyWorkspace(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
function renderUnilateralMatchCard(event, peers) {
|
||||
const card = document.createElement("div");
|
||||
card.className = "card";
|
||||
card.dataset.matchCard = "true";
|
||||
card.dataset.eventId = String(event.event_id);
|
||||
card.dataset.revision = String(event.revision ?? "");
|
||||
const amountText = formatWorkspaceAmount(event.amount, event.currency);
|
||||
const peerName = event.counterparty_company_name || "对方待指定";
|
||||
const options = peers
|
||||
.filter((p) => Number(p.id) !== Number(event.own_company_id))
|
||||
.map((p) => {
|
||||
const selected = Number(p.id) === Number(event.counterparty_company_id) ? " selected" : "";
|
||||
return `<option value="${p.id}"${selected}>${p.name}</option>`;
|
||||
})
|
||||
.join("");
|
||||
card.innerHTML = `
|
||||
<div class="card-head">
|
||||
<span class="card-title">${event.effective_at || "—"} · <span class="num">${amountText}</span>
|
||||
<span class="sub">对方:${peerName}</span></span>
|
||||
<span class="pill pill-danger">单边</span>
|
||||
</div>
|
||||
<div class="detail-box" style="margin-bottom: 12px;">
|
||||
<dl class="kv">
|
||||
<dt>事件编号</dt><dd class="num">${event.event_id}</dd>
|
||||
<dt>状态</dt><dd>${event.status || event.classification || "待确认"}</dd>
|
||||
<dt>金额</dt><dd class="num">${amountText}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
<div class="field" style="margin-bottom: 14px;">
|
||||
<label>确认对方公司</label>
|
||||
<select class="select" data-counterparty-select>
|
||||
<option value="">请选择对方公司</option>
|
||||
${options}
|
||||
</select>
|
||||
<span class="hint">确认后按现有单边确认规则锁定对方参与方;工作台数字以服务端权威状态重拉。</span>
|
||||
</div>
|
||||
<div class="row">
|
||||
<button class="btn btn-primary" data-match-confirm disabled>确认匹配</button>
|
||||
<a class="btn btn-ghost" data-view-link="flows">查看本方流水</a>
|
||||
</div>`;
|
||||
const select = $("[data-counterparty-select]", card);
|
||||
const button = $("[data-match-confirm]", card);
|
||||
const syncEnabled = () => {
|
||||
if (button) button.disabled = !select?.value;
|
||||
};
|
||||
select?.addEventListener("change", syncEnabled);
|
||||
syncEnabled();
|
||||
button?.addEventListener("click", async () => {
|
||||
if (!select?.value || button.dataset.busy === "1") return;
|
||||
button.dataset.busy = "1";
|
||||
button.disabled = true;
|
||||
const requestKey = `company-confirm-${event.event_id}-${event.revision}-${select.value}`;
|
||||
const response = await fetch(`/api/company/transfer-events/${event.event_id}/confirm`, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
expected_revision: event.revision,
|
||||
request_key: requestKey,
|
||||
counterparty_company_id: Number(select.value),
|
||||
reason: "公司端确认单边流水",
|
||||
}),
|
||||
}).catch(() => null);
|
||||
if (response?.status === 401 || response?.status === 403) {
|
||||
window.location.href = "index.html";
|
||||
return;
|
||||
}
|
||||
const result = await response?.json().catch(() => ({}));
|
||||
if (!response?.ok) {
|
||||
button.dataset.busy = "0";
|
||||
syncEnabled();
|
||||
showToast("确认失败", result?.message || "请刷新后重试", "danger");
|
||||
// 失败不得本地误减:重拉权威状态
|
||||
await loadCompanyWorkspace();
|
||||
await renderReconcileMatchStack();
|
||||
return;
|
||||
}
|
||||
const matchedList = $("#matched-list");
|
||||
const matchedSummary = $("#matched-summary");
|
||||
if (matchedList) {
|
||||
const row = document.createElement("div");
|
||||
row.className = "list-row";
|
||||
const main = document.createElement("div");
|
||||
main.className = "lr-main";
|
||||
const title = document.createElement("div");
|
||||
title.className = "lr-title";
|
||||
title.textContent = summaryText;
|
||||
main.append(title);
|
||||
const pill = document.createElement("span");
|
||||
pill.className = "pill pill-success lr-side";
|
||||
pill.textContent = "已匹配";
|
||||
row.append(main, pill);
|
||||
row.innerHTML = `<div class="lr-main"><div class="lr-title">${amountText} · 已确认对方 ${select.selectedOptions[0]?.textContent || ""}</div></div><span class="pill pill-success lr-side">已匹配</span>`;
|
||||
matchedList.append(row);
|
||||
matchedSummary.style.display = "";
|
||||
card.remove();
|
||||
pendingMatch -= 1;
|
||||
if (pendingMatch === 0) {
|
||||
const empty = document.createElement("div");
|
||||
empty.className = "empty";
|
||||
empty.innerHTML = '<div class="e-title">单边流水已全部匹配</div><div>确认结果将同步至集团审核中心复核</div>';
|
||||
matchStack.append(empty);
|
||||
}
|
||||
refreshCounts();
|
||||
showToast("匹配已确认", "待办状态、操作人、时间和依据已同步更新", "success");
|
||||
});
|
||||
if (matchedSummary) matchedSummary.style.display = "";
|
||||
}
|
||||
if (result.workspace) applyCompanyWorkspace(result.workspace);
|
||||
else await loadCompanyWorkspace();
|
||||
await renderReconcileMatchStack();
|
||||
showToast("匹配已确认", "工作台待办已按权威状态同步", "success");
|
||||
});
|
||||
return card;
|
||||
}
|
||||
|
||||
async function loadCompanyPeerOptions() {
|
||||
if (Array.isArray(state.companyPeers) && state.companyPeers.length) return state.companyPeers;
|
||||
const response = await fetch("/api/company/companies").catch(() => null);
|
||||
const result = await response?.json().catch(() => null);
|
||||
const peers = Array.isArray(result?.companies) ? result.companies : [];
|
||||
state.companyPeers = peers;
|
||||
return peers;
|
||||
}
|
||||
|
||||
async function renderReconcileMatchStack() {
|
||||
const stack = $("#match-stack");
|
||||
if (!stack) return;
|
||||
const events = state.workspace?.unilateral_events || [];
|
||||
const peers = await loadCompanyPeerOptions();
|
||||
stack.replaceChildren();
|
||||
if (!events.length) {
|
||||
const empty = document.createElement("div");
|
||||
empty.className = "empty";
|
||||
empty.innerHTML = '<div class="e-title">单边流水已全部匹配</div><div>确认结果已同步至工作台权威待办</div>';
|
||||
stack.append(empty);
|
||||
return;
|
||||
}
|
||||
events.forEach((event) => stack.append(renderUnilateralMatchCard(event, peers)));
|
||||
}
|
||||
|
||||
function initReconcile() {
|
||||
const subjectRows = $$("[data-subject-row]");
|
||||
let pendingSubject = subjectRows.length;
|
||||
const countSubject = $("#count-subject");
|
||||
if (countSubject) countSubject.textContent = pendingSubject;
|
||||
|
||||
$$(".subject-confirm-btn").forEach((button) => {
|
||||
button.addEventListener("click", () => {
|
||||
@@ -2654,8 +2799,8 @@ function initReconcile() {
|
||||
const statusCell = $(".subject-status", row);
|
||||
statusCell.innerHTML = `<span class="pill pill-success">已确认 · ${subject}</span>`;
|
||||
pendingSubject -= 1;
|
||||
refreshCounts();
|
||||
showToast("科目已确认", "待办状态、操作人、时间和依据已同步更新", "success");
|
||||
if (countSubject) countSubject.textContent = pendingSubject;
|
||||
showToast("科目已确认", "科目确认仍为页面演示,不计入工作台权威待办", "success");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -2673,8 +2818,6 @@ function initReconcile() {
|
||||
}
|
||||
tabMatch?.addEventListener("click", () => switchTab("match"));
|
||||
tabSubject?.addEventListener("click", () => switchTab("subject"));
|
||||
|
||||
refreshCounts();
|
||||
}
|
||||
|
||||
function initNotifications() {
|
||||
@@ -2916,8 +3059,12 @@ function initCompany() {
|
||||
showToast("手工记录已撤回", "该记录已从审核队列中移除,需重新登记提交", "success");
|
||||
});
|
||||
|
||||
// ── 往来确认 ──
|
||||
// ── 往来确认 + 工作台权威待办 ──
|
||||
initReconcile();
|
||||
(async () => {
|
||||
await loadCompanyWorkspace();
|
||||
await renderReconcileMatchStack();
|
||||
})();
|
||||
|
||||
// ── 通知 ──
|
||||
initNotifications();
|
||||
|
||||
+13
-156
@@ -57,7 +57,7 @@
|
||||
</div>
|
||||
<div class="page-actions">
|
||||
<button class="btn" data-open-upload>上传流水</button>
|
||||
<button class="btn btn-primary" data-view-link="reconcile">去确认单边流水 (3)</button>
|
||||
<button class="btn btn-primary" id="workspaceUnilateralCta" data-view-link="reconcile">去确认单边流水 (0)</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -79,8 +79,8 @@
|
||||
</a>
|
||||
<a class="flow-step doing" data-view-link="reconcile" href="#reconcile">
|
||||
<div class="fs-top"><span class="fs-idx">03</span><span class="fs-dot"></span><span class="fs-name">往来确认</span></div>
|
||||
<div class="fs-state" id="workspaceConfirmState">待处理 5 笔</div>
|
||||
<div class="fs-meta" id="workspaceConfirmMeta">单边流水 3 笔 · 科目确认 2 笔</div>
|
||||
<div class="fs-state" id="workspaceConfirmState">加载中…</div>
|
||||
<div class="fs-meta" id="workspaceConfirmMeta">正在读取待确认单边流水</div>
|
||||
</a>
|
||||
<div class="flow-step wait">
|
||||
<div class="fs-top"><span class="fs-idx">04</span><span class="fs-dot"></span><span class="fs-name">管理复核</span></div>
|
||||
@@ -99,43 +99,12 @@
|
||||
<div class="stack">
|
||||
<div class="card" id="workspaceTodos">
|
||||
<div class="card-head">
|
||||
<span class="card-title">本月待办<span class="sub">本月任务 13/18 · 按处理顺序排列,前 3 项阻断结账</span></span>
|
||||
<span class="pill pill-warn" id="workspacePendingStatus">4 项待处理</span>
|
||||
<span class="card-title">本月待办<span class="sub" id="workspaceTodoSub">按权威待确认单边流水同步</span></span>
|
||||
<span class="pill pill-warn" id="workspacePendingStatus">加载中</span>
|
||||
</div>
|
||||
<div class="list-row" data-task-type="match" data-detail="task-match">
|
||||
<span class="pill pill-danger">阻断</span>
|
||||
<div class="lr-main">
|
||||
<div class="lr-title">处理 3 笔单边流水确认</div>
|
||||
<div class="lr-sub">选择对方银行流水作为证据后提交确认</div>
|
||||
</div>
|
||||
<button class="btn btn-sm" data-view-link="reconcile">去确认</button>
|
||||
</div>
|
||||
<div class="list-row" data-task-type="subject" data-detail="task-subject">
|
||||
<span class="pill pill-danger">阻断</span>
|
||||
<div class="lr-main">
|
||||
<div class="lr-title">确认 2 笔其他应收科目</div>
|
||||
<div class="lr-sub">核对后改判或维持原科目</div>
|
||||
</div>
|
||||
<button class="btn btn-sm" data-view-link="manual">去处理</button>
|
||||
</div>
|
||||
<div class="list-row" data-detail="task-upload">
|
||||
<span class="pill pill-danger">阻断</span>
|
||||
<div class="lr-main">
|
||||
<div class="lr-title">补传交行尾号 7710 账户 7 月流水</div>
|
||||
<div class="lr-sub">账户已登记,待总行审核通过后即可导入</div>
|
||||
</div>
|
||||
<button class="btn btn-sm" data-view-link="accounts">查看账户</button>
|
||||
</div>
|
||||
<div class="list-row" data-detail="task-reconcile">
|
||||
<span class="pill pill-muted">一般</span>
|
||||
<div class="lr-main">
|
||||
<div class="lr-title">核对与金牛置业 320 万往来</div>
|
||||
<div class="lr-sub">置业 8821 账户 7 月流水断档,需人工核对</div>
|
||||
</div>
|
||||
<button class="btn btn-sm" data-view-link="flows">去核对</button>
|
||||
</div>
|
||||
<div class="table-foot">
|
||||
<span>完成以上 4 项后,7 月账期即可提交集团结账</span>
|
||||
<div id="workspaceTodoList"></div>
|
||||
<div class="table-foot" id="workspaceTodoFoot">
|
||||
<span>正在读取待办…</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -463,130 +432,18 @@
|
||||
<div class="notice warn" id="blocking-notice" style="margin-bottom: 16px;">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" style="width: 18px; height: 18px; flex: none; margin-top: 1px;"><path d="M12 8v5M12 16.5v.01"/><path d="M10.3 4.1L2.8 17a2 2 0 0 0 1.7 3h15a2 2 0 0 0 1.7-3L13.7 4.1a2 2 0 0 0-3.4 0z"/></svg>
|
||||
<div>
|
||||
<div class="n-title" id="notice-title">5 项待确认,是 7 月结账的阻断项</div>
|
||||
<div class="n-body" id="notice-body">含单边流水匹配 3 项、科目确认 2 项。请于 2026-08-29(7 月顺延结账日)前处理完毕,否则集团无法对贵公司执行 7 月结账。</div>
|
||||
<div class="n-title" id="notice-title">正在读取待确认单边流水…</div>
|
||||
<div class="n-body" id="notice-body">工作台与往来确认共用同一权威待确认集合。</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tabs">
|
||||
<button type="button" class="active" id="tab-match" aria-pressed="true">单边流水匹配<span class="tab-count" id="count-match">3</span></button>
|
||||
<button type="button" class="active" id="tab-match" aria-pressed="true">单边流水匹配<span class="tab-count" id="count-match">0</span></button>
|
||||
<button type="button" id="tab-subject" aria-pressed="false">科目确认<span class="tab-count" id="count-subject">2</span></button>
|
||||
</div>
|
||||
|
||||
<section id="panel-match">
|
||||
<div class="stack" id="match-stack">
|
||||
<div class="card" data-match-card>
|
||||
<div class="card-head">
|
||||
<span class="card-title">2026-07-14 付 <span class="num amt-out">¥3,200,000.00</span> 给金牛置业<span class="sub">摘要:煤炭采购款</span></span>
|
||||
<span class="pill pill-danger">单边</span>
|
||||
</div>
|
||||
<div class="detail-box" style="margin-bottom: 12px;">
|
||||
<dl class="kv">
|
||||
<dt>本方流水号</dt><dd>MY-ICBC-3305-20260714-018</dd>
|
||||
<dt>本方账户</dt><dd>工商银行基本户 · 尾号 3305</dd>
|
||||
<dt>对方户名</dt><dd>河南金牛置业有限公司</dd>
|
||||
</dl>
|
||||
</div>
|
||||
<div class="field" style="margin-bottom: 14px;">
|
||||
<label>候选对方银行证据(选择 1 条进行匹配)</label>
|
||||
<label class="list-row" style="border: 1px solid var(--border); border-radius: var(--radius); padding: 10px 12px; margin-bottom: 8px; cursor: pointer;">
|
||||
<input type="radio" name="ev-1" style="width: auto;" />
|
||||
<div class="lr-main">
|
||||
<div class="lr-title">金牛置业 · 建设银行一般户 · 尾号 6642</div>
|
||||
<div class="lr-sub num">2026-07-14 收 ¥3,200,000.00 · 对方流水号 ZY-CCB-6642-20260714-006</div>
|
||||
</div>
|
||||
<span class="pill pill-success lr-side">匹配度 高</span>
|
||||
</label>
|
||||
<label class="list-row" style="border: 1px solid var(--border); border-radius: var(--radius); padding: 10px 12px; margin-bottom: 8px; cursor: pointer;">
|
||||
<input type="radio" name="ev-1" style="width: auto;" />
|
||||
<div class="lr-main">
|
||||
<div class="lr-title">金牛置业 · 中国银行基本户 · 尾号 8821</div>
|
||||
<div class="lr-sub num">2026-07-15 收 ¥3,200,000.00 · 对方流水号 ZY-BOC-8821-20260715-011</div>
|
||||
</div>
|
||||
<span class="pill pill-warn lr-side">匹配度 中</span>
|
||||
</label>
|
||||
<span class="hint">提示:置业中行尾号 8821 账户 07-06 至 07-16 流水断档,其 07-15 记录为对方后补手工记录,匹配度较低,请优先核对建行 6642。</span>
|
||||
</div>
|
||||
<div class="row">
|
||||
<button class="btn btn-primary" data-match-confirm disabled data-match-summary="2026-07-14 付 ¥3,200,000.00 给金牛置业 · 煤炭采购款 · 已匹配置业建行 6642 收款记录">确认匹配</button>
|
||||
<a class="btn btn-ghost" data-view-link="flows">查看本方流水</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card" data-match-card>
|
||||
<div class="card-head">
|
||||
<span class="card-title">2026-07-22 付 <span class="num amt-out">¥950,000.00</span> 给金牛物流<span class="sub">摘要:7 月矿区运输费</span></span>
|
||||
<span class="pill pill-danger">单边</span>
|
||||
</div>
|
||||
<div class="detail-box" style="margin-bottom: 12px;">
|
||||
<dl class="kv">
|
||||
<dt>本方流水号</dt><dd>MY-ICBC-3305-20260722-031</dd>
|
||||
<dt>本方账户</dt><dd>工商银行基本户 · 尾号 3305</dd>
|
||||
<dt>对方户名</dt><dd>河南金牛物流有限公司</dd>
|
||||
</dl>
|
||||
</div>
|
||||
<div class="field" style="margin-bottom: 14px;">
|
||||
<label>候选对方银行证据(选择 1 条进行匹配)</label>
|
||||
<label class="list-row" style="border: 1px solid var(--border); border-radius: var(--radius); padding: 10px 12px; margin-bottom: 8px; cursor: pointer;">
|
||||
<input type="radio" name="ev-2" style="width: auto;" />
|
||||
<div class="lr-main">
|
||||
<div class="lr-title">金牛物流 · 农业银行基本户 · 尾号 5508</div>
|
||||
<div class="lr-sub num">2026-07-22 收 ¥950,000.00 · 对方流水号 WL-ABC-5508-20260722-014</div>
|
||||
</div>
|
||||
<span class="pill pill-success lr-side">匹配度 高</span>
|
||||
</label>
|
||||
<label class="list-row" style="border: 1px solid var(--border); border-radius: var(--radius); padding: 10px 12px; margin-bottom: 8px; cursor: pointer;">
|
||||
<input type="radio" name="ev-2" style="width: auto;" />
|
||||
<div class="lr-main">
|
||||
<div class="lr-title">金牛物流 · 工商银行一般户 · 尾号 2201</div>
|
||||
<div class="lr-sub num">2026-07-23 收 ¥950,000.00 · 对方流水号 WL-ICBC-2201-20260723-002</div>
|
||||
</div>
|
||||
<span class="pill pill-warn lr-side">匹配度 中</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="row">
|
||||
<button class="btn btn-primary" data-match-confirm disabled data-match-summary="2026-07-22 付 ¥950,000.00 给金牛物流 · 7 月矿区运输费 · 已匹配物流农行 5508 收款记录">确认匹配</button>
|
||||
<a class="btn btn-ghost" data-view-link="flows">查看本方流水</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card" data-match-card>
|
||||
<div class="card-head">
|
||||
<span class="card-title">2026-07-09 收 <span class="num amt-in">¥1,860,000.00</span> 自金牛贸易<span class="sub">摘要:精煤销售款</span></span>
|
||||
<span class="pill pill-danger">单边</span>
|
||||
</div>
|
||||
<div class="detail-box" style="margin-bottom: 12px;">
|
||||
<dl class="kv">
|
||||
<dt>本方流水号</dt><dd>MY-BOC-9916-20260709-007</dd>
|
||||
<dt>本方账户</dt><dd>中国银行一般户 · 尾号 9916</dd>
|
||||
<dt>对方户名</dt><dd>河南金牛贸易有限公司</dd>
|
||||
</dl>
|
||||
</div>
|
||||
<div class="field" style="margin-bottom: 14px;">
|
||||
<label>候选对方银行证据(选择 1 条进行匹配)</label>
|
||||
<label class="list-row" style="border: 1px solid var(--border); border-radius: var(--radius); padding: 10px 12px; margin-bottom: 8px; cursor: pointer;">
|
||||
<input type="radio" name="ev-3" style="width: auto;" />
|
||||
<div class="lr-main">
|
||||
<div class="lr-title">金牛贸易 · 交通银行基本户 · 尾号 8077</div>
|
||||
<div class="lr-sub num">2026-07-09 付 ¥1,860,000.00 · 对方流水号 MY-BCM-8077-20260709-019</div>
|
||||
</div>
|
||||
<span class="pill pill-success lr-side">匹配度 高</span>
|
||||
</label>
|
||||
<label class="list-row" style="border: 1px solid var(--border); border-radius: var(--radius); padding: 10px 12px; margin-bottom: 8px; cursor: pointer;">
|
||||
<input type="radio" name="ev-3" style="width: auto;" />
|
||||
<div class="lr-main">
|
||||
<div class="lr-title">金牛贸易 · 中国银行一般户 · 尾号 3340</div>
|
||||
<div class="lr-sub num">2026-07-08 付 ¥1,860,000.00 · 对方流水号 MY-BOC-3340-20260708-021</div>
|
||||
</div>
|
||||
<span class="pill pill-warn lr-side">匹配度 中</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="row">
|
||||
<button class="btn btn-primary" data-match-confirm disabled data-match-summary="2026-07-09 收 ¥1,860,000.00 自金牛贸易 · 精煤销售款 · 已匹配贸易交行 8077 付款记录">确认匹配</button>
|
||||
<a class="btn btn-ghost" data-view-link="flows">查看本方流水</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="stack" id="match-stack"></div>
|
||||
|
||||
<div class="card" style="margin-top: 14px; display: none;" id="matched-summary">
|
||||
<div class="card-head">
|
||||
@@ -957,6 +814,6 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="toast-region" id="toastRegion" aria-live="polite"></div>
|
||||
<script src="app.js?v=6"></script>
|
||||
<script src="app.js?v=10"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user