801 lines
22 KiB
HTML
801 lines
22 KiB
HTML
<!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>
|
|
:root {
|
|
--primary: #246bfe;
|
|
--primary-soft: #e9f0ff;
|
|
--cyan: #00a9d6;
|
|
--green: #0aa66a;
|
|
--orange: #f59e0b;
|
|
--red: #ef4444;
|
|
--text: #1f2937;
|
|
--muted: #667085;
|
|
--line: #dbe7ff;
|
|
--panel: rgba(255, 255, 255, 0.88);
|
|
--bg: #f5f9ff;
|
|
--shadow: 0 18px 50px rgba(36, 107, 254, 0.12);
|
|
}
|
|
|
|
* {
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
body {
|
|
margin: 0;
|
|
min-height: 100vh;
|
|
color: var(--text);
|
|
font-family: "Inter", "PingFang SC", "Microsoft YaHei", Arial, sans-serif;
|
|
background:
|
|
radial-gradient(circle at 12% 10%, rgba(36, 107, 254, 0.14), transparent 30%),
|
|
radial-gradient(circle at 85% 8%, rgba(0, 169, 214, 0.13), transparent 28%),
|
|
linear-gradient(135deg, #f7fbff 0%, #eef6ff 48%, #ffffff 100%);
|
|
}
|
|
|
|
body::before {
|
|
content: "";
|
|
position: fixed;
|
|
inset: 0;
|
|
pointer-events: none;
|
|
opacity: 0.58;
|
|
background-image:
|
|
linear-gradient(rgba(36, 107, 254, 0.08) 1px, transparent 1px),
|
|
linear-gradient(90deg, rgba(36, 107, 254, 0.08) 1px, transparent 1px);
|
|
background-size: 28px 28px;
|
|
mask-image: linear-gradient(to bottom, black, transparent 75%);
|
|
}
|
|
|
|
.page {
|
|
position: relative;
|
|
width: min(1440px, calc(100% - 40px));
|
|
margin: 0 auto;
|
|
padding: 28px 0 44px;
|
|
}
|
|
|
|
.hero {
|
|
display: grid;
|
|
grid-template-columns: 1.4fr 0.8fr;
|
|
gap: 20px;
|
|
align-items: stretch;
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.hero-card,
|
|
.panel,
|
|
.metric-card {
|
|
border: 1px solid rgba(145, 178, 255, 0.46);
|
|
border-radius: 22px;
|
|
background: var(--panel);
|
|
box-shadow: var(--shadow);
|
|
backdrop-filter: blur(16px);
|
|
}
|
|
|
|
.hero-card {
|
|
position: relative;
|
|
overflow: hidden;
|
|
padding: 30px;
|
|
}
|
|
|
|
.hero-card::after {
|
|
content: "";
|
|
position: absolute;
|
|
right: -80px;
|
|
top: -80px;
|
|
width: 240px;
|
|
height: 240px;
|
|
border-radius: 50%;
|
|
background: radial-gradient(circle, rgba(36, 107, 254, 0.18), transparent 68%);
|
|
}
|
|
|
|
.eyebrow {
|
|
display: inline-flex;
|
|
gap: 8px;
|
|
align-items: center;
|
|
padding: 7px 12px;
|
|
border: 1px solid rgba(36, 107, 254, 0.18);
|
|
border-radius: 999px;
|
|
color: var(--primary);
|
|
background: rgba(36, 107, 254, 0.08);
|
|
font-size: 13px;
|
|
font-weight: 700;
|
|
}
|
|
|
|
.pulse {
|
|
width: 8px;
|
|
height: 8px;
|
|
border-radius: 50%;
|
|
background: var(--green);
|
|
box-shadow: 0 0 0 6px rgba(10, 166, 106, 0.14);
|
|
}
|
|
|
|
h1 {
|
|
margin: 18px 0 10px;
|
|
font-size: clamp(30px, 4vw, 48px);
|
|
letter-spacing: -1px;
|
|
}
|
|
|
|
.hero p {
|
|
margin: 0;
|
|
max-width: 760px;
|
|
color: var(--muted);
|
|
line-height: 1.8;
|
|
}
|
|
|
|
.hero-side {
|
|
padding: 24px;
|
|
display: grid;
|
|
gap: 14px;
|
|
}
|
|
|
|
.status-chip {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
padding: 14px 16px;
|
|
border-radius: 16px;
|
|
background: linear-gradient(135deg, rgba(36, 107, 254, 0.08), rgba(255, 255, 255, 0.88));
|
|
border: 1px solid rgba(36, 107, 254, 0.12);
|
|
}
|
|
|
|
.status-chip strong {
|
|
font-size: 20px;
|
|
color: var(--primary);
|
|
}
|
|
|
|
.metrics {
|
|
display: grid;
|
|
grid-template-columns: repeat(4, 1fr);
|
|
gap: 16px;
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.metric-card {
|
|
padding: 18px;
|
|
min-height: 116px;
|
|
}
|
|
|
|
.metric-label {
|
|
color: var(--muted);
|
|
font-size: 13px;
|
|
}
|
|
|
|
.metric-value {
|
|
margin-top: 12px;
|
|
font-size: 28px;
|
|
font-weight: 800;
|
|
color: var(--primary);
|
|
word-break: break-all;
|
|
}
|
|
|
|
.metric-foot {
|
|
margin-top: 8px;
|
|
color: var(--muted);
|
|
font-size: 12px;
|
|
}
|
|
|
|
.layout {
|
|
display: grid;
|
|
grid-template-columns: 380px 1fr;
|
|
gap: 20px;
|
|
}
|
|
|
|
.panel {
|
|
padding: 20px;
|
|
}
|
|
|
|
.panel-title {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
gap: 12px;
|
|
margin-bottom: 16px;
|
|
}
|
|
|
|
.panel-title h2 {
|
|
margin: 0;
|
|
font-size: 18px;
|
|
}
|
|
|
|
.badge {
|
|
padding: 5px 10px;
|
|
border-radius: 999px;
|
|
color: var(--primary);
|
|
background: var(--primary-soft);
|
|
font-size: 12px;
|
|
font-weight: 700;
|
|
}
|
|
|
|
.form-grid {
|
|
display: grid;
|
|
gap: 14px;
|
|
}
|
|
|
|
.field {
|
|
display: grid;
|
|
gap: 7px;
|
|
}
|
|
|
|
label {
|
|
color: #344054;
|
|
font-size: 13px;
|
|
font-weight: 700;
|
|
}
|
|
|
|
input,
|
|
select {
|
|
width: 100%;
|
|
height: 42px;
|
|
border: 1px solid var(--line);
|
|
border-radius: 12px;
|
|
outline: none;
|
|
padding: 0 12px;
|
|
color: var(--text);
|
|
background: rgba(255, 255, 255, 0.92);
|
|
transition: 0.18s ease;
|
|
}
|
|
|
|
input:focus,
|
|
select:focus {
|
|
border-color: var(--primary);
|
|
box-shadow: 0 0 0 4px rgba(36, 107, 254, 0.12);
|
|
}
|
|
|
|
.two {
|
|
display: grid;
|
|
grid-template-columns: 1fr 1fr;
|
|
gap: 12px;
|
|
}
|
|
|
|
.actions {
|
|
display: grid;
|
|
grid-template-columns: 1fr 1fr;
|
|
gap: 10px;
|
|
margin-top: 6px;
|
|
}
|
|
|
|
button {
|
|
height: 42px;
|
|
border: 0;
|
|
border-radius: 12px;
|
|
cursor: pointer;
|
|
color: #fff;
|
|
background: linear-gradient(135deg, var(--primary), #4f8cff);
|
|
font-weight: 800;
|
|
box-shadow: 0 10px 24px rgba(36, 107, 254, 0.22);
|
|
transition: transform 0.18s ease, box-shadow 0.18s ease;
|
|
}
|
|
|
|
button:hover {
|
|
transform: translateY(-1px);
|
|
box-shadow: 0 14px 30px rgba(36, 107, 254, 0.28);
|
|
}
|
|
|
|
button.secondary {
|
|
color: var(--primary);
|
|
border: 1px solid rgba(36, 107, 254, 0.22);
|
|
background: #fff;
|
|
box-shadow: none;
|
|
}
|
|
|
|
button.green {
|
|
background: linear-gradient(135deg, var(--green), #32c28a);
|
|
}
|
|
|
|
button.orange {
|
|
background: linear-gradient(135deg, var(--orange), #fbbf24);
|
|
}
|
|
|
|
.tabs {
|
|
display: flex;
|
|
gap: 10px;
|
|
flex-wrap: wrap;
|
|
margin-bottom: 16px;
|
|
}
|
|
|
|
.tab {
|
|
padding: 10px 14px;
|
|
border: 1px solid var(--line);
|
|
border-radius: 999px;
|
|
color: var(--muted);
|
|
background: #fff;
|
|
cursor: pointer;
|
|
font-size: 13px;
|
|
font-weight: 800;
|
|
}
|
|
|
|
.tab.active {
|
|
color: #fff;
|
|
background: linear-gradient(135deg, var(--primary), var(--cyan));
|
|
border-color: transparent;
|
|
}
|
|
|
|
.table-wrap {
|
|
overflow: auto;
|
|
border: 1px solid rgba(145, 178, 255, 0.38);
|
|
border-radius: 16px;
|
|
background: #fff;
|
|
}
|
|
|
|
table {
|
|
width: 100%;
|
|
min-width: 980px;
|
|
border-collapse: collapse;
|
|
}
|
|
|
|
th,
|
|
td {
|
|
padding: 13px 14px;
|
|
text-align: left;
|
|
border-bottom: 1px solid #edf2ff;
|
|
font-size: 13px;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
th {
|
|
position: sticky;
|
|
top: 0;
|
|
z-index: 1;
|
|
color: #31507a;
|
|
background: linear-gradient(180deg, #f6f9ff, #ffffff);
|
|
font-weight: 900;
|
|
}
|
|
|
|
tr:hover td {
|
|
background: #f8fbff;
|
|
}
|
|
|
|
.tag {
|
|
display: inline-flex;
|
|
padding: 4px 9px;
|
|
border-radius: 999px;
|
|
color: var(--primary);
|
|
background: var(--primary-soft);
|
|
font-size: 12px;
|
|
font-weight: 800;
|
|
}
|
|
|
|
.log {
|
|
min-height: 170px;
|
|
max-height: 340px;
|
|
overflow: auto;
|
|
padding: 14px;
|
|
border: 1px solid rgba(145, 178, 255, 0.38);
|
|
border-radius: 16px;
|
|
background: #fbfdff;
|
|
color: #344054;
|
|
font-family: Consolas, Monaco, monospace;
|
|
font-size: 12px;
|
|
line-height: 1.7;
|
|
white-space: pre-wrap;
|
|
}
|
|
|
|
.hint {
|
|
margin-top: 12px;
|
|
color: var(--muted);
|
|
font-size: 12px;
|
|
line-height: 1.7;
|
|
}
|
|
|
|
@media (max-width: 1100px) {
|
|
.hero,
|
|
.layout,
|
|
.metrics {
|
|
grid-template-columns: 1fr;
|
|
}
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<main class="page">
|
|
<section class="hero">
|
|
<div class="hero-card">
|
|
<span class="eyebrow"><span class="pulse"></span> Finance Settlement Console</span>
|
|
<h1>财务结算中心</h1>
|
|
<p>
|
|
面向供应商与分销商的日结、月结费用查询和结算处理页面。支持汇总查询、账单预览、结算单创建、审批提交、审批回调和结算单追踪。
|
|
</p>
|
|
</div>
|
|
<div class="hero-card hero-side">
|
|
<div class="status-chip">
|
|
<span>接口状态</span>
|
|
<strong id="apiStatus">Ready</strong>
|
|
</div>
|
|
<div class="status-chip">
|
|
<span>当前模式</span>
|
|
<strong id="modeText">供应商 / 日结</strong>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="metrics">
|
|
<div class="metric-card">
|
|
<div class="metric-label">销售金额</div>
|
|
<div class="metric-value" id="salesAmount">0.00000000</div>
|
|
<div class="metric-foot">sales_amount</div>
|
|
</div>
|
|
<div class="metric-card">
|
|
<div class="metric-label">结算金额</div>
|
|
<div class="metric-value" id="settlementAmount">0.00000000</div>
|
|
<div class="metric-foot">settlement_amount</div>
|
|
</div>
|
|
<div class="metric-card">
|
|
<div class="metric-label">平台收入</div>
|
|
<div class="metric-value" id="platformIncomeAmount">0.00000000</div>
|
|
<div class="metric-foot">platform_income_amount</div>
|
|
</div>
|
|
<div class="metric-card">
|
|
<div class="metric-label">账单数量</div>
|
|
<div class="metric-value" id="billCount">0</div>
|
|
<div class="metric-foot">bill_count</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="layout">
|
|
<aside class="panel">
|
|
<div class="panel-title">
|
|
<h2>查询条件</h2>
|
|
<span class="badge">Light Tech UI</span>
|
|
</div>
|
|
|
|
<div class="form-grid">
|
|
<div class="field">
|
|
<label>账本机构 accounting_orgid</label>
|
|
<input id="accountingOrgid" placeholder="请输入账本机构ID" />
|
|
</div>
|
|
|
|
<div class="two">
|
|
<div class="field">
|
|
<label>对手方类型</label>
|
|
<select id="counterpartyType">
|
|
<option value="supplier">供应商 supplier</option>
|
|
<option value="reseller">分销商 reseller</option>
|
|
</select>
|
|
</div>
|
|
<div class="field">
|
|
<label>账期类型</label>
|
|
<select id="periodType">
|
|
<option value="day">日结 day</option>
|
|
<option value="month">月结 month</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="field">
|
|
<label>对手方机构 counterparty_orgid</label>
|
|
<input id="counterpartyOrgid" placeholder="汇总可不填;预览/创建必填" />
|
|
</div>
|
|
|
|
<div class="two">
|
|
<div class="field">
|
|
<label>开始日期</label>
|
|
<input id="startDate" type="date" />
|
|
</div>
|
|
<div class="field">
|
|
<label>结束日期</label>
|
|
<input id="endDate" type="date" />
|
|
</div>
|
|
</div>
|
|
|
|
<div class="two">
|
|
<div class="field">
|
|
<label>页码</label>
|
|
<input id="currentPage" type="number" min="1" value="1" />
|
|
</div>
|
|
<div class="field">
|
|
<label>每页数量</label>
|
|
<input id="pageSize" type="number" min="1" value="20" />
|
|
</div>
|
|
</div>
|
|
|
|
<div class="field">
|
|
<label>结算单 ID settlement_id</label>
|
|
<input id="settlementId" placeholder="提交审批/详情时填写" />
|
|
</div>
|
|
|
|
<div class="field">
|
|
<label>用户 ID userid</label>
|
|
<input id="userid" placeholder="创建/提交审批时填写" />
|
|
</div>
|
|
|
|
<div class="field">
|
|
<label>审批 ID apv_id / approval_id</label>
|
|
<input id="approvalId" placeholder="审批回调时填写" />
|
|
</div>
|
|
|
|
<div class="field">
|
|
<label>审批状态</label>
|
|
<select id="approvalStatus">
|
|
<option value="agree">agree 审批通过</option>
|
|
<option value="start">start 审批中</option>
|
|
<option value="refuse">refuse 拒绝</option>
|
|
<option value="terminate">terminate 撤销</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="actions">
|
|
<button onclick="querySummary()">汇总查询</button>
|
|
<button class="secondary" onclick="previewSettlement()">预览明细</button>
|
|
<button class="green" onclick="createSettlement()">创建结算单</button>
|
|
<button class="orange" onclick="submitSettlement()">提交审批</button>
|
|
<button class="secondary" onclick="queryList()">结算单列表</button>
|
|
<button class="secondary" onclick="queryDetail()">结算单详情</button>
|
|
<button onclick="approvalCallback()">审批回调</button>
|
|
<button class="secondary" onclick="clearResult()">清空结果</button>
|
|
</div>
|
|
|
|
<div class="hint">
|
|
推荐流程:汇总查询 -> 预览明细 -> 创建结算单 -> 提交审批 -> 审批回调。接口路径默认按 `/bill/*.dspy` 调用。
|
|
</div>
|
|
</div>
|
|
</aside>
|
|
|
|
<section class="panel">
|
|
<div class="panel-title">
|
|
<h2>结算数据</h2>
|
|
<span class="badge" id="resultBadge">等待查询</span>
|
|
</div>
|
|
|
|
<div class="tabs">
|
|
<button class="tab active" onclick="switchView('table')">数据表格</button>
|
|
<button class="tab" onclick="switchView('raw')">接口返回</button>
|
|
</div>
|
|
|
|
<div id="tableView" class="table-wrap">
|
|
<table>
|
|
<thead id="tableHead">
|
|
<tr>
|
|
<th>提示</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="tableBody">
|
|
<tr>
|
|
<td>请先执行查询</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<pre id="rawView" class="log" style="display: none;">暂无数据</pre>
|
|
</section>
|
|
</section>
|
|
</main>
|
|
|
|
<script>
|
|
const API = {
|
|
summary: "/bill/finance_settlement_summary.dspy",
|
|
preview: "/bill/finance_settlement_preview.dspy",
|
|
create: "/bill/finance_settlement_create.dspy",
|
|
list: "/bill/finance_settlement_list.dspy",
|
|
detail: "/bill/finance_settlement_detail.dspy",
|
|
submit: "/bill/finance_settlement_submit.dspy",
|
|
callback: "/bill/finance_settlement_apv_callback.dspy"
|
|
};
|
|
|
|
const moneyFields = ["sales_amount", "settlement_amount", "platform_income_amount"];
|
|
let lastResponse = null;
|
|
|
|
function $(id) {
|
|
return document.getElementById(id);
|
|
}
|
|
|
|
function value(id) {
|
|
return $(id).value.trim();
|
|
}
|
|
|
|
function basePayload() {
|
|
return {
|
|
accounting_orgid: value("accountingOrgid"),
|
|
counterparty_type: value("counterpartyType"),
|
|
period_type: value("periodType"),
|
|
start_date: value("startDate"),
|
|
end_date: value("endDate"),
|
|
period_start: value("startDate"),
|
|
period_end: value("endDate"),
|
|
counterparty_orgid: value("counterpartyOrgid"),
|
|
current_page: Number(value("currentPage") || 1),
|
|
page_size: Number(value("pageSize") || 20)
|
|
};
|
|
}
|
|
|
|
function compact(obj) {
|
|
return Object.fromEntries(
|
|
Object.entries(obj).filter(([, v]) => v !== "" && v !== null && v !== undefined)
|
|
);
|
|
}
|
|
|
|
async function postJson(url, payload) {
|
|
$("apiStatus").textContent = "Loading";
|
|
$("resultBadge").textContent = "请求中";
|
|
const response = await fetch(url, {
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json" },
|
|
body: JSON.stringify(compact(payload))
|
|
});
|
|
const text = await response.text();
|
|
try {
|
|
return JSON.parse(text);
|
|
} catch (error) {
|
|
return { status: false, msg: "接口未返回 JSON", raw: text };
|
|
}
|
|
}
|
|
|
|
function setModeText() {
|
|
const typeText = value("counterpartyType") === "supplier" ? "供应商" : "分销商";
|
|
const periodText = value("periodType") === "day" ? "日结" : "月结";
|
|
$("modeText").textContent = `${typeText} / ${periodText}`;
|
|
}
|
|
|
|
function updateMetrics(data) {
|
|
const summary = data?.summary || data?.data?.summary || {};
|
|
$("salesAmount").textContent = formatMoney(summary.sales_amount);
|
|
$("settlementAmount").textContent = formatMoney(summary.settlement_amount);
|
|
$("platformIncomeAmount").textContent = formatMoney(summary.platform_income_amount);
|
|
$("billCount").textContent = summary.bill_count ?? 0;
|
|
}
|
|
|
|
function formatMoney(value) {
|
|
const number = Number(value || 0);
|
|
return Number.isFinite(number) ? number.toFixed(8) : "0.00000000";
|
|
}
|
|
|
|
function normalizeRows(resp) {
|
|
const data = resp?.data || {};
|
|
if (Array.isArray(data.items)) return data.items;
|
|
if (Array.isArray(data)) return data;
|
|
if (data.settlement) return [data.settlement, ...(data.items || [])];
|
|
return [];
|
|
}
|
|
|
|
function render(resp) {
|
|
lastResponse = resp;
|
|
$("rawView").textContent = JSON.stringify(resp, null, 2);
|
|
$("apiStatus").textContent = resp?.status ? "Success" : "Failed";
|
|
$("resultBadge").textContent = resp?.status ? "请求成功" : "请求失败";
|
|
updateMetrics(resp?.data || {});
|
|
|
|
const rows = normalizeRows(resp);
|
|
if (!rows.length) {
|
|
$("tableHead").innerHTML = "<tr><th>提示</th></tr>";
|
|
$("tableBody").innerHTML = `<tr><td>${escapeHtml(resp?.msg || "暂无数据")}</td></tr>`;
|
|
return;
|
|
}
|
|
|
|
const columns = Array.from(
|
|
rows.reduce((set, row) => {
|
|
Object.keys(flatten(row)).forEach(key => set.add(key));
|
|
return set;
|
|
}, new Set())
|
|
).slice(0, 14);
|
|
|
|
$("tableHead").innerHTML = `<tr>${columns.map(col => `<th>${escapeHtml(col)}</th>`).join("")}</tr>`;
|
|
$("tableBody").innerHTML = rows.map(row => {
|
|
const flat = flatten(row);
|
|
return `<tr>${columns.map(col => `<td>${formatCell(col, flat[col])}</td>`).join("")}</tr>`;
|
|
}).join("");
|
|
}
|
|
|
|
function flatten(obj, prefix = "", output = {}) {
|
|
Object.entries(obj || {}).forEach(([key, val]) => {
|
|
const path = prefix ? `${prefix}.${key}` : key;
|
|
if (val && typeof val === "object" && !Array.isArray(val)) {
|
|
flatten(val, path, output);
|
|
} else {
|
|
output[path] = Array.isArray(val) ? JSON.stringify(val) : val;
|
|
}
|
|
});
|
|
return output;
|
|
}
|
|
|
|
function formatCell(key, val) {
|
|
if (moneyFields.some(field => key.endsWith(field))) {
|
|
return `<strong>${formatMoney(val)}</strong>`;
|
|
}
|
|
if (key.endsWith("status") && val) {
|
|
return `<span class="tag">${escapeHtml(val)}</span>`;
|
|
}
|
|
return escapeHtml(val ?? "");
|
|
}
|
|
|
|
function escapeHtml(value) {
|
|
return String(value)
|
|
.replaceAll("&", "&")
|
|
.replaceAll("<", "<")
|
|
.replaceAll(">", ">")
|
|
.replaceAll('"', """)
|
|
.replaceAll("'", "'");
|
|
}
|
|
|
|
function requireFields(payload, fields) {
|
|
const missing = fields.filter(field => !payload[field]);
|
|
if (missing.length) {
|
|
const resp = { status: false, msg: `缺少参数: ${missing.join(", ")}` };
|
|
render(resp);
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
async function querySummary() {
|
|
setModeText();
|
|
const payload = basePayload();
|
|
if (!requireFields(payload, ["accounting_orgid", "counterparty_type", "period_type", "start_date", "end_date"])) return;
|
|
render(await postJson(API.summary, payload));
|
|
}
|
|
|
|
async function previewSettlement() {
|
|
setModeText();
|
|
const payload = basePayload();
|
|
if (!requireFields(payload, ["accounting_orgid", "counterparty_type", "counterparty_orgid", "period_start", "period_end"])) return;
|
|
render(await postJson(API.preview, payload));
|
|
}
|
|
|
|
async function createSettlement() {
|
|
setModeText();
|
|
const payload = { ...basePayload(), userid: value("userid") };
|
|
if (!requireFields(payload, ["accounting_orgid", "counterparty_type", "counterparty_orgid", "period_start", "period_end"])) return;
|
|
render(await postJson(API.create, payload));
|
|
}
|
|
|
|
async function queryList() {
|
|
setModeText();
|
|
const payload = basePayload();
|
|
if (!requireFields(payload, ["accounting_orgid"])) return;
|
|
render(await postJson(API.list, payload));
|
|
}
|
|
|
|
async function queryDetail() {
|
|
const payload = {
|
|
settlement_id: value("settlementId"),
|
|
current_page: Number(value("currentPage") || 1),
|
|
page_size: Number(value("pageSize") || 100)
|
|
};
|
|
if (!requireFields(payload, ["settlement_id"])) return;
|
|
render(await postJson(API.detail, payload));
|
|
}
|
|
|
|
async function submitSettlement() {
|
|
const payload = {
|
|
settlement_id: value("settlementId"),
|
|
userid: value("userid"),
|
|
business_name: "财务结算"
|
|
};
|
|
if (!requireFields(payload, ["settlement_id", "userid"])) return;
|
|
render(await postJson(API.submit, payload));
|
|
}
|
|
|
|
async function approvalCallback() {
|
|
const payload = {
|
|
apv_id: value("approvalId"),
|
|
status: value("approvalStatus")
|
|
};
|
|
if (!requireFields(payload, ["apv_id", "status"])) return;
|
|
render(await postJson(API.callback, payload));
|
|
}
|
|
|
|
function switchView(view) {
|
|
document.querySelectorAll(".tab").forEach(tab => tab.classList.remove("active"));
|
|
event.target.classList.add("active");
|
|
$("tableView").style.display = view === "table" ? "block" : "none";
|
|
$("rawView").style.display = view === "raw" ? "block" : "none";
|
|
}
|
|
|
|
function clearResult() {
|
|
lastResponse = null;
|
|
$("rawView").textContent = "暂无数据";
|
|
$("tableHead").innerHTML = "<tr><th>提示</th></tr>";
|
|
$("tableBody").innerHTML = "<tr><td>请先执行查询</td></tr>";
|
|
$("apiStatus").textContent = "Ready";
|
|
$("resultBadge").textContent = "等待查询";
|
|
updateMetrics({});
|
|
}
|
|
|
|
setModeText();
|
|
$("counterpartyType").addEventListener("change", setModeText);
|
|
$("periodType").addEventListener("change", setModeText);
|
|
</script>
|
|
</body>
|
|
</html>
|