1473 lines
42 KiB
HTML
1473 lines
42 KiB
HTML
|
|
<!doctype html>
|
|||
|
|
<html lang="zh-CN">
|
|||
|
|
<head>
|
|||
|
|
<meta charset="utf-8">
|
|||
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|||
|
|
<title>X-Financial 预算费用规划推荐模型方案</title>
|
|||
|
|
<style>
|
|||
|
|
:root {
|
|||
|
|
color-scheme: light;
|
|||
|
|
--bg: #f5f7f4;
|
|||
|
|
--surface: #ffffff;
|
|||
|
|
--surface-soft: #f9fbf8;
|
|||
|
|
--ink: #132019;
|
|||
|
|
--ink-soft: #526257;
|
|||
|
|
--muted: #718075;
|
|||
|
|
--line: #dbe4dc;
|
|||
|
|
--line-strong: #c5d2c7;
|
|||
|
|
--green: #0f766e;
|
|||
|
|
--green-dark: #0b4f49;
|
|||
|
|
--green-soft: #e4f5f2;
|
|||
|
|
--blue: #2563eb;
|
|||
|
|
--blue-soft: #e8f0ff;
|
|||
|
|
--amber: #b45309;
|
|||
|
|
--amber-soft: #fff3d7;
|
|||
|
|
--red: #c2410c;
|
|||
|
|
--red-soft: #fff0e8;
|
|||
|
|
--plum: #7c2d12;
|
|||
|
|
--plum-soft: #f8eee8;
|
|||
|
|
--shadow: 0 16px 34px rgba(37, 48, 40, 0.08);
|
|||
|
|
--radius: 8px;
|
|||
|
|
--mono: "Cascadia Code", "JetBrains Mono", Consolas, monospace;
|
|||
|
|
--font: "Microsoft YaHei UI", "Microsoft YaHei", "PingFang SC", "Segoe UI", sans-serif;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
* {
|
|||
|
|
box-sizing: border-box;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
html {
|
|||
|
|
scroll-behavior: smooth;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
body {
|
|||
|
|
margin: 0;
|
|||
|
|
background:
|
|||
|
|
linear-gradient(180deg, rgba(228, 245, 242, 0.9), rgba(245, 247, 244, 0.82) 310px),
|
|||
|
|
var(--bg);
|
|||
|
|
color: var(--ink);
|
|||
|
|
font-family: var(--font);
|
|||
|
|
font-size: 14px;
|
|||
|
|
line-height: 1.68;
|
|||
|
|
letter-spacing: 0;
|
|||
|
|
overflow-wrap: anywhere;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
a {
|
|||
|
|
color: inherit;
|
|||
|
|
text-decoration: none;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
code {
|
|||
|
|
padding: 2px 6px;
|
|||
|
|
border-radius: 6px;
|
|||
|
|
background: rgba(15, 118, 110, 0.08);
|
|||
|
|
color: var(--green-dark);
|
|||
|
|
font-family: var(--mono);
|
|||
|
|
font-size: 0.92em;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
pre {
|
|||
|
|
margin: 0;
|
|||
|
|
min-width: 0;
|
|||
|
|
max-width: 100%;
|
|||
|
|
padding: 16px;
|
|||
|
|
overflow: auto;
|
|||
|
|
border: 1px solid var(--line);
|
|||
|
|
border-radius: var(--radius);
|
|||
|
|
background: #101a16;
|
|||
|
|
color: #eef8f4;
|
|||
|
|
font-family: var(--mono);
|
|||
|
|
font-size: 12.5px;
|
|||
|
|
line-height: 1.72;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.layout {
|
|||
|
|
display: grid;
|
|||
|
|
grid-template-columns: 270px minmax(0, 1fr);
|
|||
|
|
min-height: 100dvh;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.sidebar {
|
|||
|
|
position: sticky;
|
|||
|
|
top: 0;
|
|||
|
|
height: 100dvh;
|
|||
|
|
padding: 24px 18px;
|
|||
|
|
border-right: 1px solid var(--line);
|
|||
|
|
background: rgba(255, 255, 255, 0.9);
|
|||
|
|
backdrop-filter: blur(18px);
|
|||
|
|
overflow: auto;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.brand {
|
|||
|
|
display: flex;
|
|||
|
|
gap: 12px;
|
|||
|
|
align-items: center;
|
|||
|
|
padding-bottom: 22px;
|
|||
|
|
border-bottom: 1px solid var(--line);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.brand-mark {
|
|||
|
|
display: grid;
|
|||
|
|
width: 40px;
|
|||
|
|
height: 40px;
|
|||
|
|
place-items: center;
|
|||
|
|
border-radius: 8px;
|
|||
|
|
background: #12342f;
|
|||
|
|
color: #fff;
|
|||
|
|
font-weight: 850;
|
|||
|
|
box-shadow: 0 12px 20px rgba(15, 79, 73, 0.24);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.brand-title {
|
|||
|
|
font-size: 15px;
|
|||
|
|
font-weight: 850;
|
|||
|
|
line-height: 1.25;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.brand-subtitle {
|
|||
|
|
margin-top: 3px;
|
|||
|
|
color: var(--muted);
|
|||
|
|
font-size: 12px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.nav-label {
|
|||
|
|
margin: 22px 0 8px;
|
|||
|
|
color: var(--muted);
|
|||
|
|
font-size: 12px;
|
|||
|
|
font-weight: 750;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.nav {
|
|||
|
|
display: grid;
|
|||
|
|
gap: 5px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.nav a {
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
min-height: 36px;
|
|||
|
|
padding: 7px 10px;
|
|||
|
|
border-radius: 8px;
|
|||
|
|
color: var(--ink-soft);
|
|||
|
|
font-size: 13px;
|
|||
|
|
font-weight: 700;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.nav a:hover {
|
|||
|
|
background: var(--green-soft);
|
|||
|
|
color: var(--green-dark);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.nav-dot {
|
|||
|
|
width: 7px;
|
|||
|
|
height: 7px;
|
|||
|
|
margin-right: 10px;
|
|||
|
|
border-radius: 99px;
|
|||
|
|
background: var(--line-strong);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.nav a:hover .nav-dot {
|
|||
|
|
background: var(--green);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.side-note {
|
|||
|
|
margin-top: 24px;
|
|||
|
|
padding: 12px;
|
|||
|
|
border: 1px solid var(--line);
|
|||
|
|
border-radius: var(--radius);
|
|||
|
|
background: var(--surface-soft);
|
|||
|
|
color: var(--ink-soft);
|
|||
|
|
font-size: 12px;
|
|||
|
|
line-height: 1.55;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
main {
|
|||
|
|
min-width: 0;
|
|||
|
|
padding: 34px 44px 58px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.hero {
|
|||
|
|
display: grid;
|
|||
|
|
grid-template-columns: minmax(0, 1.1fr) minmax(330px, 0.9fr);
|
|||
|
|
gap: 22px;
|
|||
|
|
align-items: stretch;
|
|||
|
|
margin-bottom: 22px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.hero-copy {
|
|||
|
|
min-width: 0;
|
|||
|
|
padding: 30px;
|
|||
|
|
border: 1px solid var(--line);
|
|||
|
|
border-radius: var(--radius);
|
|||
|
|
background: rgba(255, 255, 255, 0.88);
|
|||
|
|
box-shadow: var(--shadow);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.eyebrow {
|
|||
|
|
display: inline-flex;
|
|||
|
|
gap: 8px;
|
|||
|
|
align-items: center;
|
|||
|
|
margin-bottom: 14px;
|
|||
|
|
color: var(--green-dark);
|
|||
|
|
font-size: 12px;
|
|||
|
|
font-weight: 850;
|
|||
|
|
text-transform: uppercase;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.eyebrow::before {
|
|||
|
|
content: "";
|
|||
|
|
width: 24px;
|
|||
|
|
height: 2px;
|
|||
|
|
border-radius: 99px;
|
|||
|
|
background: var(--green);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
h1,
|
|||
|
|
h2,
|
|||
|
|
h3 {
|
|||
|
|
margin: 0;
|
|||
|
|
line-height: 1.28;
|
|||
|
|
letter-spacing: 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
h1 {
|
|||
|
|
max-width: 760px;
|
|||
|
|
color: #0b1f1b;
|
|||
|
|
font-size: 34px;
|
|||
|
|
font-weight: 900;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.lead {
|
|||
|
|
max-width: 780px;
|
|||
|
|
margin: 16px 0 0;
|
|||
|
|
color: var(--ink-soft);
|
|||
|
|
font-size: 15px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.hero-actions {
|
|||
|
|
display: flex;
|
|||
|
|
flex-wrap: wrap;
|
|||
|
|
gap: 10px;
|
|||
|
|
margin-top: 22px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.tag {
|
|||
|
|
display: inline-flex;
|
|||
|
|
align-items: center;
|
|||
|
|
min-height: 30px;
|
|||
|
|
padding: 5px 10px;
|
|||
|
|
border: 1px solid var(--line);
|
|||
|
|
border-radius: 999px;
|
|||
|
|
background: var(--surface-soft);
|
|||
|
|
color: var(--ink-soft);
|
|||
|
|
font-size: 12px;
|
|||
|
|
font-weight: 750;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.hero-panel {
|
|||
|
|
display: grid;
|
|||
|
|
gap: 10px;
|
|||
|
|
min-width: 0;
|
|||
|
|
padding: 18px;
|
|||
|
|
border: 1px solid var(--line);
|
|||
|
|
border-radius: var(--radius);
|
|||
|
|
background: #16342f;
|
|||
|
|
color: #ecf8f5;
|
|||
|
|
box-shadow: var(--shadow);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.signal-row {
|
|||
|
|
display: flex;
|
|||
|
|
justify-content: space-between;
|
|||
|
|
gap: 14px;
|
|||
|
|
padding: 12px;
|
|||
|
|
border: 1px solid rgba(236, 248, 245, 0.14);
|
|||
|
|
border-radius: 8px;
|
|||
|
|
background: rgba(255, 255, 255, 0.06);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.signal-row strong {
|
|||
|
|
display: block;
|
|||
|
|
font-size: 13px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.signal-row > div:first-child {
|
|||
|
|
min-width: 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.signal-row span {
|
|||
|
|
display: block;
|
|||
|
|
margin-top: 3px;
|
|||
|
|
color: rgba(236, 248, 245, 0.72);
|
|||
|
|
font-size: 12px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.signal-value {
|
|||
|
|
flex: 0 0 auto;
|
|||
|
|
color: #bff4e8;
|
|||
|
|
font-weight: 900;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
section {
|
|||
|
|
min-width: 0;
|
|||
|
|
margin-top: 18px;
|
|||
|
|
padding: 24px;
|
|||
|
|
border: 1px solid var(--line);
|
|||
|
|
border-radius: var(--radius);
|
|||
|
|
background: rgba(255, 255, 255, 0.92);
|
|||
|
|
box-shadow: 0 8px 20px rgba(37, 48, 40, 0.04);
|
|||
|
|
scroll-margin-top: 20px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.section-head {
|
|||
|
|
display: flex;
|
|||
|
|
align-items: flex-start;
|
|||
|
|
justify-content: space-between;
|
|||
|
|
gap: 22px;
|
|||
|
|
margin-bottom: 16px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.section-head h2 {
|
|||
|
|
font-size: 22px;
|
|||
|
|
font-weight: 900;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.section-head p {
|
|||
|
|
max-width: 680px;
|
|||
|
|
margin: 6px 0 0;
|
|||
|
|
color: var(--ink-soft);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.section-kicker {
|
|||
|
|
color: var(--green);
|
|||
|
|
font-size: 12px;
|
|||
|
|
font-weight: 850;
|
|||
|
|
white-space: nowrap;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.grid-2,
|
|||
|
|
.grid-3,
|
|||
|
|
.grid-4 {
|
|||
|
|
display: grid;
|
|||
|
|
gap: 12px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.grid-2 {
|
|||
|
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.grid-3 {
|
|||
|
|
grid-template-columns: repeat(3, minmax(0, 1fr));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.grid-4 {
|
|||
|
|
grid-template-columns: repeat(4, minmax(0, 1fr));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.card,
|
|||
|
|
.metric,
|
|||
|
|
.lane,
|
|||
|
|
.phase,
|
|||
|
|
.check-item {
|
|||
|
|
border: 1px solid var(--line);
|
|||
|
|
border-radius: var(--radius);
|
|||
|
|
background: var(--surface);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.card {
|
|||
|
|
min-width: 0;
|
|||
|
|
padding: 16px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.card h3,
|
|||
|
|
.lane h3,
|
|||
|
|
.phase h3 {
|
|||
|
|
color: var(--ink);
|
|||
|
|
font-size: 15px;
|
|||
|
|
font-weight: 850;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.card p,
|
|||
|
|
.lane p,
|
|||
|
|
.phase p {
|
|||
|
|
margin: 8px 0 0;
|
|||
|
|
color: var(--ink-soft);
|
|||
|
|
font-size: 13px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.metric {
|
|||
|
|
min-width: 0;
|
|||
|
|
padding: 14px;
|
|||
|
|
background: linear-gradient(180deg, #fff, var(--surface-soft));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.metric-label {
|
|||
|
|
color: var(--muted);
|
|||
|
|
font-size: 12px;
|
|||
|
|
font-weight: 750;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.metric-value {
|
|||
|
|
margin-top: 6px;
|
|||
|
|
color: var(--ink);
|
|||
|
|
font-size: 22px;
|
|||
|
|
font-weight: 900;
|
|||
|
|
line-height: 1.1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.metric-desc {
|
|||
|
|
margin-top: 7px;
|
|||
|
|
color: var(--ink-soft);
|
|||
|
|
font-size: 12px;
|
|||
|
|
line-height: 1.5;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.pill-list {
|
|||
|
|
display: flex;
|
|||
|
|
flex-wrap: wrap;
|
|||
|
|
gap: 8px;
|
|||
|
|
margin-top: 12px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.pill {
|
|||
|
|
display: inline-flex;
|
|||
|
|
align-items: center;
|
|||
|
|
min-height: 28px;
|
|||
|
|
padding: 4px 9px;
|
|||
|
|
border-radius: 999px;
|
|||
|
|
background: var(--green-soft);
|
|||
|
|
color: var(--green-dark);
|
|||
|
|
font-size: 12px;
|
|||
|
|
font-weight: 750;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.flow {
|
|||
|
|
display: grid;
|
|||
|
|
grid-template-columns: repeat(5, minmax(0, 1fr));
|
|||
|
|
gap: 10px;
|
|||
|
|
margin-top: 14px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.flow-step {
|
|||
|
|
position: relative;
|
|||
|
|
min-height: 120px;
|
|||
|
|
padding: 14px;
|
|||
|
|
border: 1px solid var(--line);
|
|||
|
|
border-radius: var(--radius);
|
|||
|
|
background: var(--surface-soft);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.flow-step:not(:last-child)::after {
|
|||
|
|
content: "";
|
|||
|
|
position: absolute;
|
|||
|
|
top: 50%;
|
|||
|
|
right: -9px;
|
|||
|
|
width: 8px;
|
|||
|
|
height: 8px;
|
|||
|
|
border-top: 2px solid var(--line-strong);
|
|||
|
|
border-right: 2px solid var(--line-strong);
|
|||
|
|
transform: translateY(-50%) rotate(45deg);
|
|||
|
|
background: transparent;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.flow-number {
|
|||
|
|
display: inline-grid;
|
|||
|
|
width: 24px;
|
|||
|
|
height: 24px;
|
|||
|
|
place-items: center;
|
|||
|
|
margin-bottom: 9px;
|
|||
|
|
border-radius: 6px;
|
|||
|
|
background: var(--green);
|
|||
|
|
color: #fff;
|
|||
|
|
font-size: 12px;
|
|||
|
|
font-weight: 900;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.flow-step strong {
|
|||
|
|
display: block;
|
|||
|
|
font-size: 13px;
|
|||
|
|
line-height: 1.35;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.flow-step span {
|
|||
|
|
display: block;
|
|||
|
|
margin-top: 6px;
|
|||
|
|
color: var(--ink-soft);
|
|||
|
|
font-size: 12px;
|
|||
|
|
line-height: 1.5;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.architecture {
|
|||
|
|
display: grid;
|
|||
|
|
gap: 10px;
|
|||
|
|
margin-top: 12px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.lane {
|
|||
|
|
display: grid;
|
|||
|
|
grid-template-columns: 160px minmax(0, 1fr);
|
|||
|
|
gap: 14px;
|
|||
|
|
padding: 14px;
|
|||
|
|
align-items: start;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.lane h3 {
|
|||
|
|
color: var(--green-dark);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.lane ul,
|
|||
|
|
.card ul,
|
|||
|
|
.phase ul,
|
|||
|
|
.quality-list {
|
|||
|
|
margin: 9px 0 0;
|
|||
|
|
padding-left: 18px;
|
|||
|
|
color: var(--ink-soft);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
li + li {
|
|||
|
|
margin-top: 5px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.formula-grid {
|
|||
|
|
display: grid;
|
|||
|
|
grid-template-columns: minmax(0, 1fr) minmax(300px, 0.8fr);
|
|||
|
|
gap: 14px;
|
|||
|
|
align-items: start;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.callout {
|
|||
|
|
padding: 16px;
|
|||
|
|
border: 1px solid var(--line);
|
|||
|
|
border-left: 4px solid var(--green);
|
|||
|
|
border-radius: var(--radius);
|
|||
|
|
background: var(--green-soft);
|
|||
|
|
color: var(--green-dark);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.callout strong {
|
|||
|
|
display: block;
|
|||
|
|
margin-bottom: 6px;
|
|||
|
|
font-weight: 900;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.score-band {
|
|||
|
|
display: grid;
|
|||
|
|
gap: 9px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.band {
|
|||
|
|
display: grid;
|
|||
|
|
grid-template-columns: 120px 82px minmax(0, 1fr);
|
|||
|
|
gap: 10px;
|
|||
|
|
align-items: center;
|
|||
|
|
padding: 11px 12px;
|
|||
|
|
border: 1px solid var(--line);
|
|||
|
|
border-radius: var(--radius);
|
|||
|
|
background: var(--surface-soft);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.band strong {
|
|||
|
|
font-size: 13px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.band-score {
|
|||
|
|
font-family: var(--mono);
|
|||
|
|
font-size: 12px;
|
|||
|
|
font-weight: 850;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.band span {
|
|||
|
|
color: var(--ink-soft);
|
|||
|
|
font-size: 12px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.band.recommended {
|
|||
|
|
border-color: #a6ded3;
|
|||
|
|
background: var(--green-soft);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.band.caution {
|
|||
|
|
border-color: #f0cf88;
|
|||
|
|
background: var(--amber-soft);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.band.review {
|
|||
|
|
border-color: #b8c9f5;
|
|||
|
|
background: var(--blue-soft);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.band.block {
|
|||
|
|
border-color: #efb69a;
|
|||
|
|
background: var(--red-soft);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.phase {
|
|||
|
|
min-width: 0;
|
|||
|
|
padding: 16px;
|
|||
|
|
border-top: 4px solid var(--green);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.phase:nth-child(2) {
|
|||
|
|
border-top-color: var(--blue);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.phase:nth-child(3) {
|
|||
|
|
border-top-color: var(--amber);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.phase:nth-child(4) {
|
|||
|
|
border-top-color: var(--red);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.screen {
|
|||
|
|
display: grid;
|
|||
|
|
grid-template-columns: 1fr 1fr;
|
|||
|
|
gap: 12px;
|
|||
|
|
padding: 14px;
|
|||
|
|
border: 1px solid var(--line);
|
|||
|
|
border-radius: var(--radius);
|
|||
|
|
background: #f8faf8;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.screen-block {
|
|||
|
|
min-width: 0;
|
|||
|
|
min-height: 74px;
|
|||
|
|
padding: 12px;
|
|||
|
|
border: 1px solid var(--line);
|
|||
|
|
border-radius: var(--radius);
|
|||
|
|
background: var(--surface);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.screen-block.wide {
|
|||
|
|
grid-column: 1 / -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.screen-block strong {
|
|||
|
|
display: block;
|
|||
|
|
font-size: 13px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.screen-block span {
|
|||
|
|
display: block;
|
|||
|
|
margin-top: 5px;
|
|||
|
|
color: var(--ink-soft);
|
|||
|
|
font-size: 12px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.checklist {
|
|||
|
|
display: grid;
|
|||
|
|
gap: 9px;
|
|||
|
|
margin-top: 12px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.check-item {
|
|||
|
|
display: flex;
|
|||
|
|
gap: 10px;
|
|||
|
|
align-items: flex-start;
|
|||
|
|
padding: 12px;
|
|||
|
|
color: var(--ink-soft);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.check-item input {
|
|||
|
|
width: 16px;
|
|||
|
|
height: 16px;
|
|||
|
|
margin-top: 4px;
|
|||
|
|
accent-color: var(--green);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.check-item strong {
|
|||
|
|
display: block;
|
|||
|
|
color: var(--ink);
|
|||
|
|
font-size: 13px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.check-item span {
|
|||
|
|
display: block;
|
|||
|
|
margin-top: 3px;
|
|||
|
|
font-size: 12px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.check-item:has(input:checked) {
|
|||
|
|
background: var(--green-soft);
|
|||
|
|
color: var(--green-dark);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.check-item:has(input:checked) strong,
|
|||
|
|
.check-item:has(input:checked) span {
|
|||
|
|
text-decoration: line-through;
|
|||
|
|
text-decoration-thickness: 1px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.split-note {
|
|||
|
|
display: grid;
|
|||
|
|
grid-template-columns: 1fr 1fr;
|
|||
|
|
gap: 12px;
|
|||
|
|
margin-top: 12px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.note-green,
|
|||
|
|
.note-amber {
|
|||
|
|
padding: 14px;
|
|||
|
|
border-radius: var(--radius);
|
|||
|
|
font-size: 13px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.note-green {
|
|||
|
|
border: 1px solid #a6ded3;
|
|||
|
|
background: var(--green-soft);
|
|||
|
|
color: var(--green-dark);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.note-amber {
|
|||
|
|
border: 1px solid #f0cf88;
|
|||
|
|
background: var(--amber-soft);
|
|||
|
|
color: #74460b;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.footer {
|
|||
|
|
margin-top: 24px;
|
|||
|
|
color: var(--muted);
|
|||
|
|
font-size: 12px;
|
|||
|
|
text-align: center;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
@media (max-width: 1100px) {
|
|||
|
|
.layout {
|
|||
|
|
grid-template-columns: 1fr;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.sidebar {
|
|||
|
|
position: static;
|
|||
|
|
height: auto;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.nav {
|
|||
|
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.hero,
|
|||
|
|
.grid-4,
|
|||
|
|
.flow,
|
|||
|
|
.formula-grid {
|
|||
|
|
grid-template-columns: 1fr;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.flow-step:not(:last-child)::after {
|
|||
|
|
display: none;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
@media (max-width: 760px) {
|
|||
|
|
main {
|
|||
|
|
padding: 22px 14px 38px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.sidebar {
|
|||
|
|
padding: 16px 14px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.brand {
|
|||
|
|
padding-bottom: 14px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.nav-label {
|
|||
|
|
margin: 14px 0 8px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.nav {
|
|||
|
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|||
|
|
gap: 4px 8px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.nav a {
|
|||
|
|
min-height: 32px;
|
|||
|
|
padding: 6px 8px;
|
|||
|
|
font-size: 12px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.side-note {
|
|||
|
|
margin-top: 14px;
|
|||
|
|
padding: 10px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.signal-row {
|
|||
|
|
display: grid;
|
|||
|
|
grid-template-columns: 1fr;
|
|||
|
|
gap: 4px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.signal-value {
|
|||
|
|
justify-self: start;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.hero-copy,
|
|||
|
|
section {
|
|||
|
|
padding: 18px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
h1 {
|
|||
|
|
font-size: 26px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.grid-2,
|
|||
|
|
.grid-3,
|
|||
|
|
.split-note,
|
|||
|
|
.screen,
|
|||
|
|
.lane,
|
|||
|
|
.band {
|
|||
|
|
grid-template-columns: 1fr;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
</style>
|
|||
|
|
</head>
|
|||
|
|
<body>
|
|||
|
|
<div class="layout">
|
|||
|
|
<aside class="sidebar">
|
|||
|
|
<div class="brand">
|
|||
|
|
<div class="brand-mark">BF</div>
|
|||
|
|
<div>
|
|||
|
|
<div class="brand-title">预算费用模型方案</div>
|
|||
|
|
<div class="brand-subtitle">Budget & Fee Recommendation</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="nav-label">方案目录</div>
|
|||
|
|
<nav class="nav" aria-label="页面目录">
|
|||
|
|
<a href="#summary"><span class="nav-dot"></span>方案结论</a>
|
|||
|
|
<a href="#loop"><span class="nav-dot"></span>业务闭环</a>
|
|||
|
|
<a href="#architecture"><span class="nav-dot"></span>模型架构</a>
|
|||
|
|
<a href="#features"><span class="nav-dot"></span>数据与特征</a>
|
|||
|
|
<a href="#formula"><span class="nav-dot"></span>计算口径</a>
|
|||
|
|
<a href="#score"><span class="nav-dot"></span>评分推荐</a>
|
|||
|
|
<a href="#applicant-profile"><span class="nav-dot"></span>画像公式</a>
|
|||
|
|
<a href="#output"><span class="nav-dot"></span>输出协议</a>
|
|||
|
|
<a href="#ui"><span class="nav-dot"></span>审批展示</a>
|
|||
|
|
<a href="#roadmap"><span class="nav-dot"></span>落地路线</a>
|
|||
|
|
<a href="#acceptance"><span class="nav-dot"></span>验收清单</a>
|
|||
|
|
</nav>
|
|||
|
|
|
|||
|
|
<div class="side-note">
|
|||
|
|
版本:2026-05-27<br>
|
|||
|
|
定位:在原“预算费用管控评分模型”基础上,升级为可上线评审的规划推荐模型方案。
|
|||
|
|
</div>
|
|||
|
|
</aside>
|
|||
|
|
|
|||
|
|
<main>
|
|||
|
|
<header class="hero">
|
|||
|
|
<div class="hero-copy">
|
|||
|
|
<div class="eyebrow">X-Financial Model Proposal</div>
|
|||
|
|
<h1>预算费用规划推荐模型方案</h1>
|
|||
|
|
<p class="lead">
|
|||
|
|
这个模型不只是给审批页打一个分,而是把“预算是否够、费用是否合理、是否影响预算节奏、下一步该怎么处理”整理成可解释、可审计、可持续迭代的推荐结果。
|
|||
|
|
</p>
|
|||
|
|
<div class="hero-actions">
|
|||
|
|
<span class="tag">规则模型优先</span>
|
|||
|
|
<span class="tag">硬约束可审计</span>
|
|||
|
|
<span class="tag">LLM 只做解释层</span>
|
|||
|
|
<span class="tag">审批反馈可回流</span>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="hero-panel" aria-label="关键决策信号">
|
|||
|
|
<div class="signal-row">
|
|||
|
|
<div>
|
|||
|
|
<strong>模型主目标</strong>
|
|||
|
|
<span>帮预算管理者快速判断是否可承接</span>
|
|||
|
|
</div>
|
|||
|
|
<div class="signal-value">Recommend</div>
|
|||
|
|
</div>
|
|||
|
|
<div class="signal-row">
|
|||
|
|
<div>
|
|||
|
|
<strong>第一版边界</strong>
|
|||
|
|
<span>不替代人工审批,不让 LLM 直接做硬判断</span>
|
|||
|
|
</div>
|
|||
|
|
<div class="signal-value">Guarded</div>
|
|||
|
|
</div>
|
|||
|
|
<div class="signal-row">
|
|||
|
|
<div>
|
|||
|
|
<strong>核心口径</strong>
|
|||
|
|
<span>扣除当前申请已预占,避免重复计算</span>
|
|||
|
|
</div>
|
|||
|
|
<div class="signal-value">Traceable</div>
|
|||
|
|
</div>
|
|||
|
|
<div class="signal-row">
|
|||
|
|
<div>
|
|||
|
|
<strong>迭代方向</strong>
|
|||
|
|
<span>规则评分 + 历史基准 + 解释生成</span>
|
|||
|
|
</div>
|
|||
|
|
<div class="signal-value">V1 → V3</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</header>
|
|||
|
|
|
|||
|
|
<section id="summary">
|
|||
|
|
<div class="section-head">
|
|||
|
|
<div>
|
|||
|
|
<h2>方案结论</h2>
|
|||
|
|
<p>建议把模型定位为“预算审批辅助决策引擎”,输出结构化推荐和解释依据,而不是单纯的页面分数。</p>
|
|||
|
|
</div>
|
|||
|
|
<div class="section-kicker">Executive Summary</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="grid-4">
|
|||
|
|
<div class="metric">
|
|||
|
|
<div class="metric-label">推荐动作</div>
|
|||
|
|
<div class="metric-value">4 类</div>
|
|||
|
|
<div class="metric-desc">建议通过、谨慎通过、需要复核、不建议直接通过。</div>
|
|||
|
|
</div>
|
|||
|
|
<div class="metric">
|
|||
|
|
<div class="metric-label">核心评分</div>
|
|||
|
|
<div class="metric-value">100 分</div>
|
|||
|
|
<div class="metric-desc">预算安全优先,费用必要性与信息完整度共同影响。</div>
|
|||
|
|
</div>
|
|||
|
|
<div class="metric">
|
|||
|
|
<div class="metric-label">硬性约束</div>
|
|||
|
|
<div class="metric-value">3 条</div>
|
|||
|
|
<div class="metric-desc">超预算、强阻断控制、预算池无法匹配必须显式处理。</div>
|
|||
|
|
</div>
|
|||
|
|
<div class="metric">
|
|||
|
|
<div class="metric-label">上线策略</div>
|
|||
|
|
<div class="metric-value">分阶段</div>
|
|||
|
|
<div class="metric-desc">先确定性规则,再接入历史基准和解释层。</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="split-note">
|
|||
|
|
<div class="note-green">
|
|||
|
|
<strong>推荐采用的产品口径:</strong>
|
|||
|
|
分数不是结论本身,结论应由“推荐动作 + 风险等级 + 触发依据 + 可执行建议”共同表达。
|
|||
|
|
</div>
|
|||
|
|
<div class="note-amber">
|
|||
|
|
<strong>需要避免的方向:</strong>
|
|||
|
|
不要让 LLM 直接判断是否通过,也不要只用一个综合分覆盖预算、业务必要性、历史异常等不同原因。
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</section>
|
|||
|
|
|
|||
|
|
<section id="loop">
|
|||
|
|
<div class="section-head">
|
|||
|
|
<div>
|
|||
|
|
<h2>业务闭环</h2>
|
|||
|
|
<p>模型要服务完整预算链路:预算池建立、申请预占、审批推荐、报销核销、结果反馈。</p>
|
|||
|
|
</div>
|
|||
|
|
<div class="section-kicker">Business Loop</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="flow">
|
|||
|
|
<div class="flow-step">
|
|||
|
|
<span class="flow-number">1</span>
|
|||
|
|
<strong>预算计划建立</strong>
|
|||
|
|
<span>按部门、项目、科目、成本中心形成预算池和预警线。</span>
|
|||
|
|
</div>
|
|||
|
|
<div class="flow-step">
|
|||
|
|
<span class="flow-number">2</span>
|
|||
|
|
<strong>费用申请预占</strong>
|
|||
|
|
<span>申请提交后先占用预算,避免后续审批期间额度被重复使用。</span>
|
|||
|
|
</div>
|
|||
|
|
<div class="flow-step">
|
|||
|
|
<span class="flow-number">3</span>
|
|||
|
|
<strong>预算审批推荐</strong>
|
|||
|
|
<span>预算管理者看到风险等级、计算依据、建议动作和补充要求。</span>
|
|||
|
|
</div>
|
|||
|
|
<div class="flow-step">
|
|||
|
|
<span class="flow-number">4</span>
|
|||
|
|
<strong>报销与核销</strong>
|
|||
|
|
<span>申请通过后生成报销草稿,实际报销后转为已核销金额。</span>
|
|||
|
|
</div>
|
|||
|
|
<div class="flow-step">
|
|||
|
|
<span class="flow-number">5</span>
|
|||
|
|
<strong>结果反馈回流</strong>
|
|||
|
|
<span>记录审批采纳、驳回原因、实际报销差异,反哺后续规则。</span>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</section>
|
|||
|
|
|
|||
|
|
<section id="architecture">
|
|||
|
|
<div class="section-head">
|
|||
|
|
<div>
|
|||
|
|
<h2>模型架构</h2>
|
|||
|
|
<p>采用“上下文构建 → 特征计算 → 硬约束判定 → 综合评分 → 推荐解释 → 反馈沉淀”的分层结构。</p>
|
|||
|
|
</div>
|
|||
|
|
<div class="section-kicker">Model Layers</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="architecture">
|
|||
|
|
<div class="lane">
|
|||
|
|
<h3>上下文层</h3>
|
|||
|
|
<div>
|
|||
|
|
<p>统一组装申请单、预算池、历史费用、项目计划和审批身份,形成模型输入快照。</p>
|
|||
|
|
<ul>
|
|||
|
|
<li>复用 <code>build_claim_budget_context()</code> 的预算上下文。</li>
|
|||
|
|
<li>补充申请事由、地点、费用类型、项目编号、附件摘要。</li>
|
|||
|
|
<li>保留计算时刻的预算快照,方便事后审计。</li>
|
|||
|
|
</ul>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="lane">
|
|||
|
|
<h3>特征层</h3>
|
|||
|
|
<div>
|
|||
|
|
<p>把业务数据转换成可解释特征,而不是直接把原始字段丢给模型。</p>
|
|||
|
|
<ul>
|
|||
|
|
<li>预算容量:审批前可用、审批后使用率、超预算金额。</li>
|
|||
|
|
<li>单笔影响:本次金额占预算比例、是否突破预算节奏。</li>
|
|||
|
|
<li>必要性证据:事由、项目、地点、附件、业务场景是否完整。</li>
|
|||
|
|
<li>历史基准:同部门、同项目、同费用类型的历史均值和波动。</li>
|
|||
|
|
</ul>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="lane">
|
|||
|
|
<h3>决策层</h3>
|
|||
|
|
<div>
|
|||
|
|
<p>先执行硬规则,再计算综合分,确保强管控场景不会被其他维度“平均掉”。</p>
|
|||
|
|
<ul>
|
|||
|
|
<li>硬规则:超预算、预算池阻断、预算无法匹配、关键字段缺失。</li>
|
|||
|
|
<li>综合评分:预算安全、费用影响、规划匹配、历史异常、信息完整。</li>
|
|||
|
|
<li>分档输出:recommended、caution、review、block、reference。</li>
|
|||
|
|
</ul>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="lane">
|
|||
|
|
<h3>解释层</h3>
|
|||
|
|
<div>
|
|||
|
|
<p>第一版直接用模板解释;后续允许 LLM 改写语气,但不能改写分数、等级和硬性结论。</p>
|
|||
|
|
<ul>
|
|||
|
|
<li>解释必须引用结构化依据,不允许凭空补充原因。</li>
|
|||
|
|
<li>建议要能变成审批动作,例如补充材料、拆分费用、调整预算。</li>
|
|||
|
|
<li>所有展示文案保留对应的 <code>basis_code</code>,方便追踪。</li>
|
|||
|
|
</ul>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</section>
|
|||
|
|
|
|||
|
|
<section id="features">
|
|||
|
|
<div class="section-head">
|
|||
|
|
<div>
|
|||
|
|
<h2>数据与特征</h2>
|
|||
|
|
<p>模型输入需要覆盖“预算是否够”和“费用是否该花”两条线,避免只看额度、不看业务必要性。</p>
|
|||
|
|
</div>
|
|||
|
|
<div class="section-kicker">Feature Design</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="grid-3">
|
|||
|
|
<div class="card">
|
|||
|
|
<h3>预算上下文</h3>
|
|||
|
|
<ul>
|
|||
|
|
<li><code>budget_applicable</code>:是否纳入预算管控。</li>
|
|||
|
|
<li><code>matched</code>:是否匹配到预算池。</li>
|
|||
|
|
<li><code>total_amount</code>、<code>reserved_amount</code>、<code>consumed_amount</code>。</li>
|
|||
|
|
<li><code>current_reserved_amount</code>:当前申请已预占金额。</li>
|
|||
|
|
<li><code>warning_threshold</code>、<code>control_action</code>。</li>
|
|||
|
|
</ul>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="card">
|
|||
|
|
<h3>申请单主数据</h3>
|
|||
|
|
<ul>
|
|||
|
|
<li>申请金额、费用类型、申请事由。</li>
|
|||
|
|
<li>业务地点、项目编号、成本中心。</li>
|
|||
|
|
<li>直属领导意见、附件摘要。</li>
|
|||
|
|
<li>申请时间、期望发生时间、是否紧急。</li>
|
|||
|
|
</ul>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="card">
|
|||
|
|
<h3>增强特征</h3>
|
|||
|
|
<ul>
|
|||
|
|
<li>同类费用历史均值与分位数。</li>
|
|||
|
|
<li>部门剩余预算消耗速度。</li>
|
|||
|
|
<li>项目里程碑与预算计划匹配度。</li>
|
|||
|
|
<li>申请人近期预算占用频次。</li>
|
|||
|
|
</ul>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="pill-list" aria-label="特征分组">
|
|||
|
|
<span class="pill">预算容量</span>
|
|||
|
|
<span class="pill">单笔影响</span>
|
|||
|
|
<span class="pill">预算节奏</span>
|
|||
|
|
<span class="pill">业务必要性</span>
|
|||
|
|
<span class="pill">历史异常</span>
|
|||
|
|
<span class="pill">信息完整度</span>
|
|||
|
|
<span class="pill">审批反馈</span>
|
|||
|
|
</div>
|
|||
|
|
</section>
|
|||
|
|
|
|||
|
|
<section id="formula">
|
|||
|
|
<div class="section-head">
|
|||
|
|
<div>
|
|||
|
|
<h2>计算口径</h2>
|
|||
|
|
<p>申请提交时已经发生预算预占,所以审批分析必须扣除当前申请已预占金额,避免重复计算。</p>
|
|||
|
|
</div>
|
|||
|
|
<div class="section-kicker">Calculation</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="formula-grid">
|
|||
|
|
<pre><code>已使用基数 = 已预占金额 + 已核销金额 - 当前申请已预占金额
|
|||
|
|
审批前可用预算 = 预算总额度 - 已使用基数
|
|||
|
|
审批后占用 = 已使用基数 + 本次申请金额
|
|||
|
|
此次费用占预算 = 本次申请金额 / 预算总额度
|
|||
|
|
审批后使用率 = 审批后占用 / 预算总额度
|
|||
|
|
超预算金额 = max(本次申请金额 - 审批前可用预算, 0)</code></pre>
|
|||
|
|
|
|||
|
|
<div class="callout">
|
|||
|
|
<strong>关键原则</strong>
|
|||
|
|
如果当前申请在提交阶段已经进入 <code>reserved_amount</code>,审批页就不能再把它当成新增占用直接叠加。否则预算管理者看到的风险会被放大,尤其是大额申请会明显失真。
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</section>
|
|||
|
|
|
|||
|
|
<section id="score">
|
|||
|
|
<div class="section-head">
|
|||
|
|
<div>
|
|||
|
|
<h2>评分推荐</h2>
|
|||
|
|
<p>建议采用“硬规则优先 + 加权评分”的组合。硬规则决定是否必须复核或阻断,评分用于排序和解释风险程度。</p>
|
|||
|
|
</div>
|
|||
|
|
<div class="section-kicker">Decision Strategy</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="grid-2">
|
|||
|
|
<div class="card">
|
|||
|
|
<h3>建议权重</h3>
|
|||
|
|
<ul>
|
|||
|
|
<li>预算安全:40 分,覆盖可用额度、审批后使用率、超预算金额。</li>
|
|||
|
|
<li>单笔影响:18 分,判断本次费用对预算池的冲击。</li>
|
|||
|
|
<li>规划匹配:16 分,比较项目计划、预算周期和费用发生时间。</li>
|
|||
|
|
<li>历史基准:14 分,识别同类费用异常偏高或频繁占用。</li>
|
|||
|
|
<li>信息完整:12 分,衡量事由、项目、地点、附件是否足够。</li>
|
|||
|
|
</ul>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="score-band">
|
|||
|
|
<div class="band recommended">
|
|||
|
|
<strong>recommended</strong>
|
|||
|
|
<div class="band-score">85-100</div>
|
|||
|
|
<span>预算充足、信息完整、费用影响可承接,建议通过。</span>
|
|||
|
|
</div>
|
|||
|
|
<div class="band caution">
|
|||
|
|
<strong>caution</strong>
|
|||
|
|
<div class="band-score">70-84</div>
|
|||
|
|
<span>预算可承接但影响较明显,建议谨慎通过并关注后续节奏。</span>
|
|||
|
|
</div>
|
|||
|
|
<div class="band review">
|
|||
|
|
<strong>review</strong>
|
|||
|
|
<div class="band-score">50-69</div>
|
|||
|
|
<span>存在信息缺口、历史异常或接近预警线,需要复核。</span>
|
|||
|
|
</div>
|
|||
|
|
<div class="band block">
|
|||
|
|
<strong>block</strong>
|
|||
|
|
<div class="band-score">0-49</div>
|
|||
|
|
<span>超预算或触发强管控动作,不建议直接通过。</span>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="split-note">
|
|||
|
|
<div class="note-green">
|
|||
|
|
<strong>硬规则示例:</strong>
|
|||
|
|
<code>control_action = block</code> 且超预算时,直接进入 <code>block</code>;预算池未匹配时输出 <code>reference</code>,不能伪装成低风险。
|
|||
|
|
</div>
|
|||
|
|
<div class="note-amber">
|
|||
|
|
<strong>推荐动作要具体:</strong>
|
|||
|
|
不只写“需关注”,而要给出“补充业务必要性、拆分费用、调整预算池、发起预算调剂”等可执行动作。
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</section>
|
|||
|
|
|
|||
|
|
<section id="applicant-profile">
|
|||
|
|
<div class="section-head">
|
|||
|
|
<div>
|
|||
|
|
<h2>申请人费用画像公式</h2>
|
|||
|
|
<p>画像只用于调整复核强度和审核建议,不能直接把申请人定义为“异常人员”。核心是用同组基准解释个人费用节奏是否偏离。</p>
|
|||
|
|
</div>
|
|||
|
|
<div class="section-kicker">Applicant Profile</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="formula-grid">
|
|||
|
|
<pre><code>申请人画像风险分 =
|
|||
|
|
高频申请分 * 20%
|
|||
|
|
+ 高金额占用分 * 25%
|
|||
|
|
+ 同组偏离分 * 25%
|
|||
|
|
+ 历史调减退回分 * 15%
|
|||
|
|
+ 本次申请偏离分 * 15%
|
|||
|
|
|
|||
|
|
等级:
|
|||
|
|
0-39 正常
|
|||
|
|
40-59 需关注
|
|||
|
|
60-79 重点复核
|
|||
|
|
80-100 强复核 / 升级审批</code></pre>
|
|||
|
|
|
|||
|
|
<div class="callout">
|
|||
|
|
<strong>同组基准口径</strong>
|
|||
|
|
同组不按全公司粗暴比较,而应按 <code>部门 + 岗位 + 费用类型 + 城市等级 + 项目类型 + 近 90/180 天</code> 聚合。销售、项目经理和研发不能混在一个基准池里比较。
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="grid-3" style="margin-top: 12px;">
|
|||
|
|
<div class="card">
|
|||
|
|
<h3>出差天数建议</h3>
|
|||
|
|
<pre><code>同类基准天数 = peer_group.travel_days_p75
|
|||
|
|
天数偏离率 = 本次出差天数 / 同类基准天数
|
|||
|
|
建议天数 = min(
|
|||
|
|
本次出差天数,
|
|||
|
|
同类基准天数 + 业务缓冲天数
|
|||
|
|
)</code></pre>
|
|||
|
|
<p>当偏离率超过 1.5 时,建议补充行程安排或压缩天数;超过 2.0 时进入重点复核。</p>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="card">
|
|||
|
|
<h3>出差费用建议</h3>
|
|||
|
|
<pre><code>本次日均费用 = 本次申请金额 / 本次出差天数
|
|||
|
|
日均费用偏离率 =
|
|||
|
|
本次日均费用 / 同城市同职级日均基准
|
|||
|
|
建议金额上限 =
|
|||
|
|
建议天数 * 日均基准 * 容忍系数</code></pre>
|
|||
|
|
<p>容忍系数第一版建议使用 1.15 到 1.20,避免模型因为小幅波动给出过硬建议。</p>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="card">
|
|||
|
|
<h3>招待费用建议</h3>
|
|||
|
|
<pre><code>人均招待金额 = 本次招待金额 / 参与人数
|
|||
|
|
人均偏离率 = 人均招待金额 / 招待标准上限
|
|||
|
|
同客户招待频率 = 近 90 天同客户招待次数
|
|||
|
|
个人招待分位 = 个人近 90 天招待金额在同组分位</code></pre>
|
|||
|
|
<p>人均偏离率超过 1.2 时建议调低标准;同客户 90 天内多次招待时要求补充客户推进阶段。</p>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="split-note">
|
|||
|
|
<div class="note-green">
|
|||
|
|
<strong>建议生成公式:</strong>
|
|||
|
|
<code>审核建议强度 = max(画像风险等级, 本次偏离等级, 硬规则等级)</code>。展示时必须说明是哪一类指标触发,而不是只给一个结论。
|
|||
|
|
</div>
|
|||
|
|
<div class="note-amber">
|
|||
|
|
<strong>审核建议示例:</strong>
|
|||
|
|
“该申请人近 90 天费用占用处于同组 P88,本次出差天数为同类 P75 的 1.67 倍。建议将 5 天调整为 4 天,或补充客户拜访安排和项目阶段说明。”
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</section>
|
|||
|
|
|
|||
|
|
<section id="output">
|
|||
|
|
<div class="section-head">
|
|||
|
|
<div>
|
|||
|
|
<h2>输出协议</h2>
|
|||
|
|
<p>接口输出需要同时服务审批页展示、看板统计和后续审计,因此自然语言必须和结构化字段分开。</p>
|
|||
|
|
</div>
|
|||
|
|
<div class="section-kicker">API Contract</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<pre><code>{
|
|||
|
|
"score": 82,
|
|||
|
|
"rating": "caution",
|
|||
|
|
"risk_level": "medium",
|
|||
|
|
"recommendation": "cautious_approve",
|
|||
|
|
"summary": "预算整体可承接,但本次费用对预算池已有明显影响。",
|
|||
|
|
"metrics": {
|
|||
|
|
"claim_amount": "12000.00",
|
|||
|
|
"total_amount": "50000.00",
|
|||
|
|
"available_before_approval": "38000.00",
|
|||
|
|
"claim_amount_ratio": "24.00",
|
|||
|
|
"after_usage_rate": "72.00",
|
|||
|
|
"over_budget_amount": "0.00"
|
|||
|
|
},
|
|||
|
|
"applicant_profile": {
|
|||
|
|
"profile_score": 66,
|
|||
|
|
"profile_level": "review",
|
|||
|
|
"peer_percentile": 88,
|
|||
|
|
"travel_days_ratio": "1.67",
|
|||
|
|
"daily_cost_ratio": "1.34",
|
|||
|
|
"suggested_days": 4,
|
|||
|
|
"suggested_amount_cap": "6800.00"
|
|||
|
|
},
|
|||
|
|
"evidence": [
|
|||
|
|
{
|
|||
|
|
"basis_code": "budget.after_usage_rate.warning_near",
|
|||
|
|
"text": "审批后预算使用率为 72.00%,接近预警区间。"
|
|||
|
|
}
|
|||
|
|
],
|
|||
|
|
"suggested_actions": [
|
|||
|
|
{
|
|||
|
|
"action": "approve_with_note",
|
|||
|
|
"text": "可继续审批,但建议备注本次费用对应的项目阶段和后续预算节奏。"
|
|||
|
|
}
|
|||
|
|
],
|
|||
|
|
"explainable_snapshot": {
|
|||
|
|
"budget_no": "BUD-TEST",
|
|||
|
|
"control_action": "warn",
|
|||
|
|
"warning_threshold": "80.00"
|
|||
|
|
}
|
|||
|
|
}</code></pre>
|
|||
|
|
</section>
|
|||
|
|
|
|||
|
|
<section id="ui">
|
|||
|
|
<div class="section-head">
|
|||
|
|
<div>
|
|||
|
|
<h2>审批展示</h2>
|
|||
|
|
<p>预算管理者最需要看到的是“为什么是这个建议”和“如果要通过,还要补什么”。页面不应只展示一个分数。</p>
|
|||
|
|
</div>
|
|||
|
|
<div class="section-kicker">Approval UX</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="screen">
|
|||
|
|
<div class="screen-block wide">
|
|||
|
|
<strong>顶部结论条</strong>
|
|||
|
|
<span>展示推荐动作、风险等级、综合分和一句话摘要,例如“谨慎通过:预算可承接,但审批后使用率接近预警线”。</span>
|
|||
|
|
</div>
|
|||
|
|
<div class="screen-block">
|
|||
|
|
<strong>关键指标</strong>
|
|||
|
|
<span>本次金额、预算总额、审批前可用、审批后使用率、超预算金额。</span>
|
|||
|
|
</div>
|
|||
|
|
<div class="screen-block">
|
|||
|
|
<strong>触发依据</strong>
|
|||
|
|
<span>逐条展示规则依据,保留 basis_code,方便定位到模型逻辑。</span>
|
|||
|
|
</div>
|
|||
|
|
<div class="screen-block">
|
|||
|
|
<strong>建议动作</strong>
|
|||
|
|
<span>通过、谨慎通过、补充材料、拆分费用、预算调剂、退回修改。</span>
|
|||
|
|
</div>
|
|||
|
|
<div class="screen-block">
|
|||
|
|
<strong>申请人费用画像</strong>
|
|||
|
|
<span>展示近 90 天频率、金额分位、天数偏离率和建议压缩区间,只作为审批参考。</span>
|
|||
|
|
</div>
|
|||
|
|
<div class="screen-block">
|
|||
|
|
<strong>审批反馈</strong>
|
|||
|
|
<span>记录预算管理者是否采纳建议,以及不采纳时的原因。</span>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</section>
|
|||
|
|
|
|||
|
|
<section id="roadmap">
|
|||
|
|
<div class="section-head">
|
|||
|
|
<div>
|
|||
|
|
<h2>落地路线</h2>
|
|||
|
|
<p>先把确定性口径做稳,再逐步接入历史基准和解释层,避免第一版就变成难以审计的黑盒。</p>
|
|||
|
|
</div>
|
|||
|
|
<div class="section-kicker">Implementation</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="grid-4">
|
|||
|
|
<div class="phase">
|
|||
|
|
<h3>P0:口径对齐</h3>
|
|||
|
|
<p>确认预算预占、审批前可用、审批后占用的计算口径。</p>
|
|||
|
|
<ul>
|
|||
|
|
<li>梳理预算上下文字段。</li>
|
|||
|
|
<li>固化不重复计算规则。</li>
|
|||
|
|
<li>定义输出协议。</li>
|
|||
|
|
</ul>
|
|||
|
|
</div>
|
|||
|
|
<div class="phase">
|
|||
|
|
<h3>P1:规则评分</h3>
|
|||
|
|
<p>上线可审计的确定性模型,覆盖预算审批主流程。</p>
|
|||
|
|
<ul>
|
|||
|
|
<li>实现特征计算。</li>
|
|||
|
|
<li>实现硬规则和分档。</li>
|
|||
|
|
<li>补齐单元测试。</li>
|
|||
|
|
</ul>
|
|||
|
|
</div>
|
|||
|
|
<div class="phase">
|
|||
|
|
<h3>P2:历史基准</h3>
|
|||
|
|
<p>引入同类费用历史均值、部门消耗速度和预算节奏。</p>
|
|||
|
|
<ul>
|
|||
|
|
<li>沉淀历史统计任务。</li>
|
|||
|
|
<li>增加异常检测特征。</li>
|
|||
|
|
<li>看板展示采纳率。</li>
|
|||
|
|
</ul>
|
|||
|
|
</div>
|
|||
|
|
<div class="phase">
|
|||
|
|
<h3>P3:解释增强</h3>
|
|||
|
|
<p>在结构化依据上增加 LLM 文案层,提升可读性。</p>
|
|||
|
|
<ul>
|
|||
|
|
<li>LLM 不改分数和等级。</li>
|
|||
|
|
<li>解释引用 basis_code。</li>
|
|||
|
|
<li>增加人工反馈闭环。</li>
|
|||
|
|
</ul>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</section>
|
|||
|
|
|
|||
|
|
<section id="acceptance">
|
|||
|
|
<div class="section-head">
|
|||
|
|
<div>
|
|||
|
|
<h2>验收清单</h2>
|
|||
|
|
<p>下面的清单会保存在当前浏览器本地,方便后续评审和开发跟踪。</p>
|
|||
|
|
</div>
|
|||
|
|
<div class="section-kicker">Checklist</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="checklist">
|
|||
|
|
<label class="check-item">
|
|||
|
|
<input type="checkbox" data-check="contract">
|
|||
|
|
<span>
|
|||
|
|
<strong>输出协议稳定</strong>
|
|||
|
|
<span>评分、等级、推荐动作、指标、依据、建议动作都有结构化字段。</span>
|
|||
|
|
</span>
|
|||
|
|
</label>
|
|||
|
|
<label class="check-item">
|
|||
|
|
<input type="checkbox" data-check="double-count">
|
|||
|
|
<span>
|
|||
|
|
<strong>预算预占不重复计算</strong>
|
|||
|
|
<span>测试覆盖当前申请已预占、未预占、部分预占三类场景。</span>
|
|||
|
|
</span>
|
|||
|
|
</label>
|
|||
|
|
<label class="check-item">
|
|||
|
|
<input type="checkbox" data-check="hard-rules">
|
|||
|
|
<span>
|
|||
|
|
<strong>硬规则不可被平均抵消</strong>
|
|||
|
|
<span>超预算和 block 控制动作必须进入高风险或阻断建议。</span>
|
|||
|
|
</span>
|
|||
|
|
</label>
|
|||
|
|
<label class="check-item">
|
|||
|
|
<input type="checkbox" data-check="ui">
|
|||
|
|
<span>
|
|||
|
|
<strong>审批页展示可解释</strong>
|
|||
|
|
<span>预算管理者能看到风险原因、计算指标和可执行下一步。</span>
|
|||
|
|
</span>
|
|||
|
|
</label>
|
|||
|
|
<label class="check-item">
|
|||
|
|
<input type="checkbox" data-check="applicant-profile">
|
|||
|
|
<span>
|
|||
|
|
<strong>申请人画像公式可审计</strong>
|
|||
|
|
<span>同组基准、偏离率、建议天数、建议金额上限都能追溯到结构化字段。</span>
|
|||
|
|
</span>
|
|||
|
|
</label>
|
|||
|
|
<label class="check-item">
|
|||
|
|
<input type="checkbox" data-check="feedback">
|
|||
|
|
<span>
|
|||
|
|
<strong>审批反馈可回流</strong>
|
|||
|
|
<span>记录采纳、覆盖、退回、预算调剂等结果,为后续模型迭代准备数据。</span>
|
|||
|
|
</span>
|
|||
|
|
</label>
|
|||
|
|
<label class="check-item">
|
|||
|
|
<input type="checkbox" data-check="llm-boundary">
|
|||
|
|
<span>
|
|||
|
|
<strong>LLM 边界清晰</strong>
|
|||
|
|
<span>LLM 只改写解释文案,不参与硬性通过、阻断和预算额度计算。</span>
|
|||
|
|
</span>
|
|||
|
|
</label>
|
|||
|
|
</div>
|
|||
|
|
</section>
|
|||
|
|
|
|||
|
|
<div class="footer">
|
|||
|
|
X-Financial · 预算费用规划推荐模型方案 · 适用于预算审批、费用申请和报销核销闭环。
|
|||
|
|
</div>
|
|||
|
|
</main>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<script>
|
|||
|
|
const storagePrefix = "x-financial-budget-model-plan:";
|
|||
|
|
|
|||
|
|
document.querySelectorAll("[data-check]").forEach((checkbox) => {
|
|||
|
|
const key = storagePrefix + checkbox.dataset.check;
|
|||
|
|
checkbox.checked = localStorage.getItem(key) === "1";
|
|||
|
|
checkbox.addEventListener("change", () => {
|
|||
|
|
localStorage.setItem(key, checkbox.checked ? "1" : "0");
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
</script>
|
|||
|
|
</body>
|
|||
|
|
</html>
|