docs: 更新视觉方向预览页与部署组件需求说明

- 设计/视觉方向预览.html 同步当前视觉体系(品牌色、语义三色、菜单
  图标),作为前端视觉落地的对照稿
- 部署组件需求说明.docx 精简冗余章节

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
liuwenxin 2026-10-22 19:47:19 +08:00
parent e61800dcdc
commit 1f65913002
2 changed files with 656 additions and 88 deletions

View File

@ -5,7 +5,12 @@
<title>衍水工资系统 · 视觉方向预览</title>
<style>
/* ============================================================
设计体系 v3(质感版):中性灰白 · 靛蓝点缀 · 微质感
设计体系 v4(同步已交付模块):中性灰白 · 靛蓝点缀 · 微质感
v3 → v4 变更(2026-10-22):设计稿与已交付功能对齐
1) 侧栏菜单改为真实路由分组(5 组 + 首页 = 21 项),组可折叠
2) 首页工作台按真实四区块重画(总览 / 待办 / 预警 / 动态)
3) 新增 §09:月结、审批、报表、打印稿(v3 缺 M3/M4 页面)
4) token 与 frontend/src/assets/styles/index.css 对齐
质感来源(而非装饰):
1) 表面微渐变 —— 1–2% 明度差,暗示受光方向
2) 半透明描边 —— 边界在不同底色上自然融合
@ -17,7 +22,7 @@
:root {
--ys-indigo: #2e4ba8;
--ys-indigo-hi: #3a58bc; /* 渐变亮端 */
--ys-indigo-deep: #243c8b;
--ys-indigo-deep: #223a85; /* 深靛蓝:与 index.css 的 --ys-indigo-deep 一致 */
--ys-indigo-wash: #edf1fa;
--ys-paper: #ffffff;
--ys-mist: #f4f5f8; /* 页面底 */
@ -240,6 +245,7 @@
.aside .logo { font-family: var(--ys-font-brand); font-size: 15px; font-weight: 500; letter-spacing: 0.3em; color: var(--ys-ink); padding: 0 10px; }
.aside .logo-sub { font-size: 11px; color: var(--ys-ink-3); letter-spacing: 0.06em; padding: 0 10px; margin-top: 4px; }
.menu-group { margin-top: 26px; }
.aside .menu-group + .menu-group { margin-top: 12px; }
.menu-label { font-size: 11px; letter-spacing: 0.1em; color: var(--ys-ink-3); padding: 0 10px; margin-bottom: 8px; }
.menu-item {
display: flex; align-items: center; gap: 10px; padding: 9px 10px; border-radius: var(--ys-radius-sm);
@ -332,7 +338,7 @@
.spec-table td.good { color: var(--ys-ink); }
/* ---------- 首页仪表盘(Bento Grid) ---------- */
.bento { display: grid; grid-template-columns: repeat(4, 1fr); grid-auto-rows: 102px; gap: 14px; }
.bento { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); grid-auto-rows: 102px; gap: 14px; }
.bento-card {
background: linear-gradient(180deg, #ffffff, #fcfcfe);
border: 1px solid var(--ys-line); border-radius: var(--ys-radius);
@ -353,21 +359,22 @@
.bento-card:nth-child(6) { animation-delay: 225ms; }
.bento-card:nth-child(7) { animation-delay: 270ms; }
.bento-card:nth-child(8) { animation-delay: 315ms; }
.bento-card:nth-child(9) { animation-delay: 360ms; }
.bento-card:nth-child(10) { animation-delay: 405ms; }
@keyframes rise { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: translateY(0); } }
@media (prefers-reduced-motion: reduce) {
.bento-card, .login-card { animation: none; transition: none; }
}
.b-2x2 { grid-column: span 2; grid-row: span 2; }
.b-2x1 { grid-column: span 2; }
.b-eyebrow { font-size: 12px; font-weight: 500; letter-spacing: 0.04em; color: var(--ys-ink-2); }
.b-big { font-size: 30px; font-weight: 600; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; line-height: 1.15; margin-top: auto; }
.b-big small { font-size: 13px; font-weight: 500; color: var(--ys-ink-3); margin-left: 4px; letter-spacing: 0; }
.b-num { font-size: 24px; font-weight: 600; letter-spacing: -0.01em; font-variant-numeric: tabular-nums; line-height: 1.2; margin-top: auto; }
.b-num small { font-size: 12px; font-weight: 400; color: var(--ys-ink-3); margin-left: 3px; }
.b-sub { font-size: 11px; color: var(--ys-ink-3); margin-top: 3px; }
.b-full { grid-column: span 4; }
.b-eyebrow { display: flex; align-items: center; gap: 8px; font-size: 12px; letter-spacing: 0.04em; color: var(--ys-ink-3); }
.b-eyebrow-gap { margin-top: 12px; }
.b-num { font-size: 26px; font-weight: 600; letter-spacing: -0.01em; font-variant-numeric: tabular-nums; line-height: 1.2; margin-top: 10px; }
.b-num small { font-size: 12px; font-weight: 400; color: var(--ys-ink-3); margin-left: 4px; }
.b-sub { font-size: 12px; color: var(--ys-ink-3); margin-top: 4px; }
.b-up { color: var(--ys-ok); font-weight: 500; }
.b-todo { display: flex; align-items: baseline; gap: 8px; font-size: 13px; color: var(--ys-ink-2); }
.b-todo .cnt { color: var(--ys-indigo); font-weight: 600; font-variant-numeric: tabular-nums; }
/* 待办 / 预警列表:超出部分在卡内滚动,卡片高度不被列表撑开 */
.todo-list, .warning-list { max-height: 178px; margin-top: 8px; overflow-y: auto; }
/* ---------- 登录页 ---------- */
.login-shot { border: 1px solid var(--ys-line); border-radius: 14px; overflow: hidden; box-shadow: 0 12px 40px rgba(28, 35, 51, 0.1); }
@ -410,6 +417,119 @@
}
.login-btn { width: 100%; height: 38px; margin-top: 6px; font-size: 14px; }
/* ---------- 菜单分组(路由 meta.group 派生的可折叠组) ---------- */
.menu-group-head {
display: flex; align-items: center; justify-content: space-between;
padding: 9px 10px; margin-bottom: 4px; border-radius: var(--ys-radius-sm);
font-size: 11px; letter-spacing: 0.1em; color: var(--ys-ink-3);
}
.menu-group.open .menu-group-head { color: var(--ys-indigo); background: rgba(255, 255, 255, 0.45); }
.menu-group-head .chev { width: 11px; height: 11px; flex: none; opacity: 0.55; }
.menu-group.open .menu-group-head .chev { opacity: 0.9; transform: rotate(90deg); }
/* ---------- 工作台卡片内的列表行 ---------- */
.b-count {
min-width: 20px; padding: 0 6px; border-radius: 9px; text-align: center;
font-size: 11px; line-height: 18px; color: var(--ys-indigo);
background: var(--ys-indigo-wash); font-variant-numeric: tabular-nums;
}
.b-row { display: flex; align-items: baseline; gap: 8px; font-size: 12.5px; color: var(--ys-ink-2); }
.b-row .t { color: var(--ys-ink); font-weight: 500; }
.b-row .m { margin-left: auto; color: var(--ys-ink-3); font-size: 11.5px; font-variant-numeric: tabular-nums; white-space: nowrap; }
.b-tag {
display: inline-block; flex: none; padding: 1px 7px; border-radius: 4px;
font-size: 11px; line-height: 1.6; white-space: nowrap;
}
.b-tag-warn { color: var(--ys-warn); background: var(--ys-warn-wash-1); }
.b-tag-danger { color: var(--ys-danger); background: var(--ys-danger-wash); }
.b-tag-info { color: var(--ys-indigo); background: var(--ys-indigo-wash); }
.b-tag-ok { color: var(--ys-ok); background: var(--ys-ok-wash-1); }
.b-empty { font-size: 12px; color: var(--ys-ink-3); margin-top: 6px; }
/* 最近动态:时间 / 模块·动作 / 摘要 / 操作人 —— 四段各自成块,不并排挤在一行 */
.b-act {
display: flex; align-items: center; gap: 10px;
font-size: 12px; color: var(--ys-ink-2);
padding: 5px 0; border-bottom: 1px dashed var(--ys-line-soft);
}
.b-act:last-child { border-bottom: 0; }
.b-act .tm { width: 108px; flex: none; color: var(--ys-ink-3); font-size: 11.5px; font-variant-numeric: tabular-nums; }
.b-act .sum { flex: 1; color: var(--ys-ink); }
.b-act .us { flex: none; width: 56px; text-align: right; color: var(--ys-ink-3); font-size: 11.5px; }
/* 常用操作:靛蓝淡底按钮,悬停才显边框 —— 一排多个入口不靠实心按钮抢注意力 */
.b-links { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 10px; }
.b-op {
padding: 6px 14px; border-radius: 6px; font-size: 13px; font-family: inherit;
color: var(--ys-indigo); background: var(--ys-indigo-wash);
border: 1px solid transparent; cursor: pointer;
transition: all 150ms var(--ys-ease);
}
.b-op:hover { border-color: var(--ys-indigo); }
/* 图表容器:与实现同高(150px) */
.chart { height: 150px; margin-top: 6px; }
/* ---------- 状态标签(月结 / 审批) ---------- */
.pill-lock { color: var(--ys-indigo); background: linear-gradient(180deg, #eef2fc, #e5eaf8); }
.pill-reject { color: var(--ys-danger); background: linear-gradient(180deg, #fbeded, #f6e3e3); }
.pill-draft { color: var(--ys-ink-2); background: linear-gradient(180deg, #f4f5f8, #eff1f5); }
.pill-wait { color: var(--ys-warn); background: linear-gradient(180deg, var(--ys-warn-wash-1), var(--ys-warn-wash-2)); }
/* ---------- §09 内容区画布(沿用 §04 的顶栏与内容底,省略侧栏) ---------- */
.canvas {
border: 1px solid var(--ys-line); border-radius: 14px; overflow: hidden;
background: var(--ys-mist); box-shadow: 0 12px 40px rgba(28, 35, 51, 0.1);
}
.canvas .topbar { height: 46px; }
.split { display: grid; grid-template-columns: 1fr 296px; gap: 14px; align-items: start; }
/* 详情面板:实际为右侧抽屉(遮罩 + 面板),此处并列展示便于看清内容 */
.panel {
background: linear-gradient(180deg, #ffffff, #fcfcfe);
border: 1px solid var(--ys-line); border-radius: var(--ys-radius);
box-shadow: var(--ys-shadow-card); padding: 16px 18px;
}
.panel-title { font-size: 13px; font-weight: 600; display: flex; align-items: center; justify-content: space-between; }
.panel-sub { font-size: 11px; color: var(--ys-ink-3); margin-top: 2px; }
.kv { display: grid; grid-template-columns: 72px 1fr; gap: 6px 10px; margin-top: 12px; font-size: 12.5px; }
.kv dt { color: var(--ys-ink-3); }
.kv dd { color: var(--ys-ink); }
.kv dd .num { font-variant-numeric: tabular-nums; }
table.grid.dense th { padding: 7px 12px; }
table.grid.dense td { padding: 7px 12px; font-size: 12.5px; }
.cell-num { text-align: right; font-variant-numeric: tabular-nums; }
.cell-strong { font-weight: 600; }
/* 状态机条:月结的生命周期 */
.flow { display: flex; align-items: center; gap: 0; margin: 4px 0 2px; flex-wrap: wrap; }
.flow-step {
display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--ys-ink-2);
padding: 4px 10px 4px 12px; background: linear-gradient(180deg, #ffffff, #fbfcfe);
border: 1px solid var(--ys-line); position: relative; white-space: nowrap;
}
.flow-step:first-child { border-radius: var(--ys-radius-sm) 0 0 var(--ys-radius-sm); }
.flow-step:last-child { border-radius: 0 var(--ys-radius-sm) var(--ys-radius-sm) 0; }
.flow-step + .flow-step { border-left: 0; }
.flow-step .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--ys-ink-3); }
.flow-step.done { color: var(--ys-ink); }
.flow-step.done .dot { background: var(--ys-ok); }
.flow-step.cur { color: var(--ys-indigo); font-weight: 500; background: var(--ys-indigo-wash); border-color: rgba(46, 75, 168, 0.3); }
.flow-step.cur .dot { background: var(--ys-indigo); }
.flow-step.rejected .dot { background: var(--ys-danger); }
.flow-step.rejected { color: var(--ys-danger); }
/* 打印稿(A4):独立顶层路由,浏览器打印只出报表本身 */
.sheet {
width: 460px; background: #fff; border: 1px solid var(--ys-line);
box-shadow: var(--ys-shadow-card); padding: 26px 28px 24px;
}
.sheet h4 { font-size: 15px; font-weight: 600; text-align: center; }
.sheet .sheet-meta { font-size: 11px; color: var(--ys-ink-3); text-align: center; margin-top: 4px; }
.sheet .block-title { font-size: 12px; font-weight: 600; margin: 14px 0 6px; }
.sheet table { width: 100%; border-collapse: collapse; font-size: 11px; font-variant-numeric: tabular-nums; }
.sheet th, .sheet td { border: 1px solid #d9dde5; padding: 4px 7px; }
.sheet th { background: #f6f7f9; font-weight: 500; color: var(--ys-ink-2); text-align: left; }
.sheet td.num { text-align: right; }
.sheet .sign-row { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; margin-top: 22px; font-size: 11px; color: var(--ys-ink-3); }
.sheet .sign-row div { border-top: 1px solid var(--ys-line); padding-top: 5px; }
/* 方案 B:居中卡片 */
.login-center {
position: relative; overflow: hidden;
@ -466,6 +586,11 @@
<div class="brand">衍水集团</div>
<h1>营销人员工资管理系统 · 视觉方向</h1>
<div class="sub">企业级扁平 · 轻质感 · Bento 布局 · 品牌色点缀 · 微动效 · 精致文案</div>
<div class="sub" style="margin-top:6px">
<b style="color:var(--ys-ink);font-weight:500">v4(2026-10-22 同步版)</b>
—— 本稿与已交付功能对齐:菜单按真实路由分组、工作台按真实四区块重画,并补齐月结 / 审批 / 报表 / 打印稿。
视觉语言沿用 v3 质感版,未改色板、未改字体、未改组件基调。
</div>
<div class="waterline"></div>
<div class="tags">
<span class="tag">表面微渐变(受光)</span>
@ -475,6 +600,8 @@
<span class="tag">2% 噪点</span>
<span class="tag">等宽数字</span>
<span class="tag">120–180ms 轻动效</span>
<span class="tag">21 项菜单 · 5 组</span>
<span class="tag">工作台四区块</span>
</div>
</header>
@ -523,6 +650,31 @@
<div class="use">成功/警示/危险,浅底微渐变 + 深字</div></div>
</div>
</div>
<div class="comp-card" style="margin-top:16px">
<h3>落地对照 · 设计值 ↔ 代码实现(2026-10-22 核对)</h3>
<table class="spec-table">
<tr><td>靛蓝</td><td>#2E4BA8</td><td class="num">index.css:<code>--ys-indigo</code> / <code>--el-color-primary</code></td><td class="num">已落地</td></tr>
<tr><td>靛蓝亮端</td><td>#3A58BC</td><td class="num">仅设计稿(按钮微渐变上端)</td><td class="num">设计值</td></tr>
<tr><td>深靛蓝</td><td>#223A85</td><td class="num">index.css:<code>--ys-indigo-deep</code>(EP dark-2 为 #253C86)</td><td class="num">已落地</td></tr>
<tr><td>EP 色阶</td><td>light-3…9 / dark-2</td><td class="num">index.css:<code>--el-color-primary-light-3/5/7/8/9</code>、<code>--el-color-primary-dark-2</code></td><td class="num">已落地</td></tr>
<tr><td>墨 / 次墨 / 弱墨</td><td>#1C2333 · #5B6577 · #9AA3B2</td><td class="num">index.css:<code>--ys-ink</code> / <code>--ys-ink-2</code> / <code>--ys-ink-3</code></td><td class="num">已落地</td></tr>
<tr><td>界线</td><td>rgba(28,35,51,.09)</td><td class="num">index.css:<code>--ys-line</code></td><td class="num">已落地</td></tr>
<tr><td>纸白 / 雾灰</td><td>#FFFFFF→#FCFCFE · #F4F5F8</td><td class="num">index.css:<code>--ys-paper</code> / <code>--ys-mist</code></td><td class="num">已落地</td></tr>
<tr><td>语义色</td><td>#1E9E6A · #C98A1B · #C94F4F</td><td class="num">index.css:<code>--el-color-success/warning/danger/error</code> 全阶覆盖</td><td class="num">已落地</td></tr>
<tr><td>确认框琥珀</td><td>#B7791F(底 #FBF3E4)</td><td class="num">index.css:<code>.ys-confirm-box</code> 图标与底色</td><td class="num">已落地</td></tr>
<tr><td>菜单图标</td><td>16px 线性 · 静止 0.7</td><td class="num"><code>menuIcons.ts</code> 注册表(Element Plus 图标库,具名导入可摇树)</td><td class="num">已落地</td></tr>
</table>
<div class="note">
<b>语义三色已按本稿规范值落地</b>(2026-10-22):在 <code>index.css</code> 的 <code>:root</code> 覆盖
<code>--el-color-success/warning/danger/error</code> 及其 light-3/5/7/8/9、dark-2 与 <code>-rgb</code> 变体,
色阶同样按 Element Plus「主色与白色混合」公式预计算——<code>-rgb</code> 一并覆盖,否则半透明底色仍是旧的黄绿色。
<br>
<b>菜单图标</b>取自 Element Plus 图标库而非本稿的手绘线性稿:同一套语义 key 注册在
<code>components/layout/menuIcons.ts</code>,路由只写 <code>meta.icon</code>;视觉口径不变
(16px、静止 0.7 / 激活 1、右间距 9px),并统一取<b>线性</b>变体、禁用 <code>*-filled</code>——
同一层级混用实心与线性图标会让菜单不像一套语言。
</div>
</div>
</section>
<!-- ============ 字体与数字 ============ -->
@ -622,8 +774,11 @@
首页
</div>
</div>
<div class="menu-group">
<div class="menu-label">系统管理</div>
<div class="menu-group open">
<div class="menu-group-head">
<span>系统管理</span>
<svg class="chev" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M6 3.5 10.5 8 6 12.5"/></svg>
</div>
<div class="menu-item">
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><circle cx="8" cy="5.5" r="2.5"/><path d="M3 13.5c0-2.5 2.2-4 5-4s5 1.5 5 4"/></svg>
用户管理
@ -640,9 +795,41 @@
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><path d="M3 5h10M3 11h10"/><circle cx="6" cy="5" r="1.6"/><circle cx="10" cy="11" r="1.6"/></svg>
计提参数
</div>
<div class="menu-item">
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><path d="M4 13.5V3.5h8v10M3 13.5h10M6.5 6h3M6.5 9h3"/></svg>
公司信息
</div>
<div class="menu-item">
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3.5" width="10" height="9" rx="1.5"/><path d="M5.6 8.2 7.1 9.7l3.3-3.4"/></svg>
审批管理
</div>
<div class="menu-item">
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><path d="M4 4.5h8M4 8h8M4 11.5h5"/></svg>
操作日志
日志查询
</div>
</div>
<div class="menu-group">
<div class="menu-group-head">
<span>基础数据</span>
<svg class="chev" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M6 3.5 10.5 8 6 12.5"/></svg>
</div>
</div>
<div class="menu-group">
<div class="menu-group-head">
<span>业务数据</span>
<svg class="chev" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M6 3.5 10.5 8 6 12.5"/></svg>
</div>
</div>
<div class="menu-group">
<div class="menu-group-head">
<span>绩效工资</span>
<svg class="chev" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M6 3.5 10.5 8 6 12.5"/></svg>
</div>
</div>
<div class="menu-group">
<div class="menu-group-head">
<span>报表统计</span>
<svg class="chev" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M6 3.5 10.5 8 6 12.5"/></svg>
</div>
</div>
<div class="aside-foot">
@ -722,6 +909,25 @@
质感的三层材料:<b>侧栏</b>灰渐变(沉)→ <b>内容底</b>雾灰 + 顶部受光 → <b>卡片</b>纸白微渐变 + 半透明描边 + 分层阴影。
当前项白底浮起,白色被灰托住,不再扎眼。
</div>
<div class="comp-card" style="margin-top:16px">
<h3>菜单全览(按真实路由分组 · 2026-10-22 核对)</h3>
<table class="spec-table">
<tr><td>首页</td><td>首页(工作台:总览 / 待办 / 预警 / 动态)</td><td class="num">顶层项 · 管理员 / 财务 / 领导</td></tr>
<tr><td>系统管理</td><td>用户管理、角色管理、岗位角色、计提参数、公司信息、审批管理、日志查询</td><td class="num">可折叠组 · 当前组自动展开</td></tr>
<tr><td>基础数据</td><td>人员管理、产品管理、客户管理</td><td class="num">可折叠组 · 登录即可见</td></tr>
<tr><td>业务数据</td><td>业务管理、发货管理、回款管理、客户评级计算器</td><td class="num">可折叠组 · 登录即可见</td></tr>
<tr><td>绩效工资</td><td>绩效台账、月度结算</td><td class="num">可折叠组 · 月结写权限限管理员与营销后勤</td></tr>
<tr><td>报表统计</td><td>个人绩效明细、部门绩效汇总、业务统计、回款统计</td><td class="num">可折叠组 · 限管理员 / 财务 / 领导</td></tr>
<tr><td>不进菜单</td><td>报表打印视图(独立顶层路由)</td><td class="num">浏览器打印只出报表本身</td></tr>
</table>
<div class="note">
侧栏是<b>单列树</b>:组标题可折叠,当前页所在组默认展开,当前项白底浮起 + 左侧 2px 靛蓝竖条。
菜单图标(16px、静止 0.7 / 激活 1、组标题不加图标)已于 2026-10-22 落地:
路由 <code>meta.icon</code> 只写语义 key,图标注册在 <code>menuIcons.ts</code>。
本稿画的是手绘线性稿,实际取自 Element Plus 图标库的线性变体——<b>形状以图标库为准</b>,
尺寸、透明度与间距口径保持一致。
</div>
</div>
</section>
<!-- ============ 首页仪表盘 ============ -->
@ -740,26 +946,33 @@
</div>
</div>
<div class="menu-group">
<div class="menu-label">系统管理</div>
<div class="menu-item">
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><circle cx="8" cy="5.5" r="2.5"/><path d="M3 13.5c0-2.5 2.2-4 5-4s5 1.5 5 4"/></svg>
用户管理
<div class="menu-group-head">
<span>系统管理</span>
<svg class="chev" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M6 3.5 10.5 8 6 12.5"/></svg>
</div>
<div class="menu-item">
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linejoin="round"><path d="M8 2 13 4v4c0 3-2 5-5 6-3-1-5-3-5-6V4Z"/></svg>
角色管理
</div>
<div class="menu-group">
<div class="menu-group-head">
<span>基础数据</span>
<svg class="chev" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M6 3.5 10.5 8 6 12.5"/></svg>
</div>
<div class="menu-item">
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><rect x="2.5" y="3.5" width="11" height="9" rx="1.5"/><circle cx="6" cy="7.5" r="1.2"/><path d="M4.5 11c.3-1 1-1.5 1.5-1.5s1.2.5 1.5 1.5M9.5 6.5h2M9.5 9h2"/></svg>
岗位角色
</div>
<div class="menu-group">
<div class="menu-group-head">
<span>业务数据</span>
<svg class="chev" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M6 3.5 10.5 8 6 12.5"/></svg>
</div>
<div class="menu-item">
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><path d="M3 5h10M3 11h10"/><circle cx="6" cy="5" r="1.6"/><circle cx="10" cy="11" r="1.6"/></svg>
计提参数
</div>
<div class="menu-group">
<div class="menu-group-head">
<span>绩效工资</span>
<svg class="chev" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M6 3.5 10.5 8 6 12.5"/></svg>
</div>
<div class="menu-item">
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><path d="M4 4.5h8M4 8h8M4 11.5h5"/></svg>
操作日志
</div>
<div class="menu-group">
<div class="menu-group-head">
<span>报表统计</span>
<svg class="chev" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M6 3.5 10.5 8 6 12.5"/></svg>
</div>
</div>
<div class="aside-foot">
@ -769,78 +982,110 @@
</aside>
<div class="main">
<div class="topbar">
<div class="crumb"><b>仪表盘</b></div>
<div class="crumb"><b>首页</b></div>
<div class="who"><span class="avatar">管</span><span>管理员</span><span class="logout">退出登录</span></div>
</div>
<div class="content">
<div class="page-head">
<div>
<h1>仪表盘</h1>
<div class="desc">数据截至今日 06:00 · 12 笔回款待核算</div>
<h1>工作台</h1>
<div class="desc">经营绩效总览 · 待办与风险集中处置 · 最近动态</div>
<div class="waterline"></div>
</div>
</div>
<div class="filter" style="margin-bottom:14px">
<div class="input" style="width:140px;display:flex;align-items:center;justify-content:space-between">2026-10 <span style="color:var(--ys-ink-3)">▾</span></div>
<button class="btn btn-primary">刷新</button>
<span class="spacer"></span>
<span style="font-size:12px;color:var(--ys-ink-3)">数据截至 2026-10-22 06:00 · 口径:本月已核算批次</span>
</div>
<div class="bento">
<div class="bento-card b-2x2">
<!-- 经营绩效总览:KPI -->
<div class="bento-card">
<div class="b-eyebrow">本月绩效总额</div>
<div class="b-big" style="color:var(--ys-indigo)">268,430.16<small>元</small></div>
<div class="b-sub">较上月 <span class="b-up">+12.4%</span> · 已核销 86 笔</div>
<div id="chartPerf" style="width:100%;height:40px;margin-top:12px"></div>
</div>
<div class="bento-card b-2x2">
<div class="b-eyebrow">近 6 个月回款</div>
<div class="b-sub" style="margin-top:2px">单位:万元</div>
<div id="chartRev" style="width:100%;height:78px;margin-top:auto"></div>
</div>
<div class="bento-card b-2x1">
<div class="b-eyebrow">待办</div>
<div style="margin-top:auto;display:flex;flex-direction:column;gap:4px">
<div class="b-todo"><span class="cnt">12 笔</span>回款待核算</div>
<div class="b-todo"><span class="cnt">3 笔</span>业务归属待确认</div>
</div>
<div class="b-num">268,430.16<small>元</small></div>
</div>
<div class="bento-card">
<div class="b-head"><div class="b-eyebrow">营销人员</div>
<svg class="b-icon" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><circle cx="8" cy="5.5" r="2.5"/><path d="M3 13.5c0-2.5 2.2-4 5-4s5 1.5 5 4"/></svg>
</div>
<div class="b-eyebrow">本月应付绩效</div>
<div class="b-num">241,876.40<small>元</small></div>
</div>
<div class="bento-card">
<div class="b-eyebrow">核算人数</div>
<div class="b-num">36<small>人</small></div>
</div>
<div class="bento-card">
<div class="b-head"><div class="b-eyebrow">岗位角色</div>
<svg class="b-icon" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><rect x="2.5" y="3.5" width="11" height="9" rx="1.5"/><circle cx="6" cy="7.5" r="1.2"/><path d="M4.5 11c.3-1 1-1.5 1.5-1.5s1.2.5 1.5 1.5M9.5 6.5h2M9.5 9h2"/></svg>
</div>
<div class="b-num">3<small>个</small></div>
<div class="b-eyebrow">营销团队</div>
<div class="b-num">4<small>个</small></div>
<div class="b-sub">月结:草稿</div>
</div>
<div class="bento-card b-2x1">
<!-- 经营绩效总览:图表 -->
<div class="bento-card b-2x2">
<div class="b-eyebrow">近 6 个月绩效</div>
<div id="chartPerf" class="chart"></div>
</div>
<div class="bento-card b-2x2">
<div class="b-eyebrow">近 6 个月回款</div>
<div id="chartRev" class="chart"></div>
</div>
<!-- 待办事项 -->
<div class="bento-card b-2x2">
<div class="b-eyebrow">待办事项 <span class="b-count">2</span></div>
<div class="todo-list">
<div class="b-row"><span class="t">月度结算 · YS202610</span><span class="m">张岚 · 10-21 14:32</span></div>
<div class="b-row"><span class="t">二次分配方案 · SP20261003</span><span class="m">王浩 · 10-21 11:08</span></div>
</div>
<div class="b-eyebrow b-eyebrow-gap">回款未指定批次 <span class="b-count">1</span></div>
<div class="todo-list" style="max-height:26px">
<div class="b-row"><span class="t">BS20261018 · 86,400.00</span><span class="m">10-21</span></div>
</div>
<div class="b-eyebrow b-eyebrow-gap">T+ 同步失败</div>
<div class="b-empty">同步模块未启用(待 T+ 对接)</div>
</div>
<!-- 风险预警 -->
<div class="bento-card b-2x2">
<div class="b-eyebrow">风险预警 <span class="b-count">2</span></div>
<div class="warning-list">
<div class="b-row"><span class="b-tag b-tag-danger">资金</span><span class="t">回款逾期 128 天</span><span class="m">BS20260703</span></div>
<div class="b-row"><span class="b-tag b-tag-warn">时效</span><span class="t">审批超时 5 天</span><span class="m">YS202609</span></div>
</div>
<div class="b-eyebrow b-eyebrow-gap">同步异常预警</div>
<div class="b-empty">同步模块未启用(待 T+ 对接)</div>
</div>
<!-- 最近动态 -->
<div class="bento-card b-full">
<div class="b-eyebrow">最近动态
<span style="margin-left:auto;font-size:11px;color:var(--ys-ink-3);border:1px solid var(--ys-line);border-radius:var(--ys-radius-sm);padding:1px 8px;background:#fff">全部模块 ▾</span>
</div>
<div class="todo-list" style="max-height:40px;margin-top:4px">
<div class="b-act"><span class="tm">10-22 09:12</span><span class="b-tag b-tag-info">核算 · 月结</span><span class="sum">生成 2026-10 月结草稿,绩效合计 268,430.16 元</span><span class="us">张岚</span></div>
<div class="b-act"><span class="tm">10-21 16:40</span><span class="b-tag b-tag-info">回款 · 新增</span><span class="sum">录入回款 86,400.00 元(业务 BS20261018)</span><span class="us">王浩</span></div>
</div>
</div>
<!-- 常用操作 -->
<div class="bento-card b-full">
<div class="b-eyebrow">常用操作</div>
<div class="row" style="margin-top:auto">
<button class="btn btn-primary" style="height:30px;font-size:12px;padding:0 13px">录入回款</button>
<button class="btn btn-default" style="height:30px;font-size:12px;padding:0 13px">计提参数</button>
<button class="btn btn-default" style="height:30px;font-size:12px;padding:0 13px">岗位角色</button>
<div class="b-links">
<button class="b-op">录入回款</button>
<button class="b-op">绩效台账</button>
<button class="b-op">月度结算</button>
<button class="b-op">报表统计</button>
</div>
</div>
<div class="bento-card">
<div class="b-head"><div class="b-eyebrow">计提参数</div>
<svg class="b-icon" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><path d="M3 5h10M3 11h10"/><circle cx="6" cy="5" r="1.6"/><circle cx="10" cy="11" r="1.6"/></svg>
</div>
<div class="b-num">16<small>项</small></div>
<div class="b-sub">版本 P20260101-00</div>
</div>
<div class="bento-card">
<div class="b-head"><div class="b-eyebrow">T+ 同步</div>
<svg class="b-icon" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><path d="M13 8a5 5 0 1 1-1.5-3.5"/><path d="M13 2.5V5h-2.5"/></svg>
</div>
<div class="b-num" style="color:var(--ys-ok)">正常</div>
<div class="b-sub">每周一 06:00</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="note">
<b>Bento Grid</b>:大小不一的卡片按重要性排布——绩效总额与回款趋势占 2×2 主角位,数字型指标 1×1 紧凑排列。
卡片入场为 <b>45ms 交错上浮(320ms)</b>,悬停抬升 2px、阴影加深——打开预览即可看到微动效。
<b>Bento Grid(4 列 · 102px 行高)</b>:KPI 四格 1×1 起手 → 绩效 / 回款趋势各占 2×2 →
待办与预警并排 2×2 → 最近动态与常用操作整行铺满(<code>b-full</code>)。
卡片入场 <b>45ms 交错上浮(320ms)</b>,悬停抬升 2px、影加深。
待办与预警的列表<b>在卡内滚动</b>(上限 178px)——条目再多也不撑开网格,行高恒定。
</div>
</section>
@ -932,20 +1177,339 @@
</div>
</section>
<!-- ============ 已交付模块页面(M3/M4) ============ -->
<section class="section" id="sec-m34">
<h2>09 · 已交付模块页面(M3 / M4)</h2>
<div class="note" style="margin-top:-6px;margin-bottom:18px">
v3 稿只画到「系统管理 + 首页 + 登录页」;此后<b>绩效核算、月结、审批、报表、工作台</b>均已交付,
本节按实现补齐。以下页面沿用 §04 的同一侧栏与顶栏,<b>只画内容区</b>。
</div>
<!-- 09-1 月度结算 -->
<div class="app-shot">
<div class="canvas">
<div class="topbar">
<div class="crumb">绩效工资 <span>/</span> <b>月度结算</b></div>
<div class="who"><span class="avatar">管</span><span>管理员</span><span class="logout">退出登录</span></div>
</div>
<div class="content">
<div class="page-head">
<div>
<h1>月度结算</h1>
<div class="desc">按月生成绩效结算批次;送审后锁定,人数与金额不再随源数据变化</div>
<div class="waterline"></div>
</div>
<button class="btn btn-primary">生成月结</button>
</div>
<div class="comp-card" style="margin-bottom:14px;padding:16px 20px">
<div class="b-eyebrow" style="margin-bottom:12px">月结生命周期</div>
<div class="flow">
<div class="flow-step done"><span class="dot"></span>草稿</div>
<div class="flow-step cur"><span class="dot"></span>待审批</div>
<div class="flow-step"><span class="dot"></span>已审定(锁定)</div>
<div class="flow-step rejected"><span class="dot"></span>已驳回 → 回到草稿</div>
</div>
</div>
<div class="filter">
<input class="input" placeholder="状态:全部" style="width:130px" />
<button class="btn btn-primary">查询</button>
<button class="btn btn-default">重置</button>
<span class="spacer"></span>
</div>
<div class="card">
<table class="grid">
<thead>
<tr><th style="width:110px">结算月份</th><th style="width:150px">状态</th><th style="width:115px">绩效合计</th><th style="width:115px">应付合计</th><th style="width:70px">人数</th><th style="width:140px">审批单号</th><th style="width:140px">提交时间</th><th style="width:130px">操作</th></tr>
</thead>
<tbody>
<tr>
<td>2026-10</td>
<td><span class="pill pill-wait">待审批</span></td>
<td class="cell-num">268,430.16</td>
<td class="cell-num">241,876.40</td>
<td class="cell-num">36</td>
<td class="cell-code">YS202610</td>
<td class="cell-muted">2026-10-21 14:32</td>
<td class="cell-actions"><a>详情</a><a class="muted">撤回</a></td>
</tr>
<tr>
<td>2026-09</td>
<td><span class="pill pill-lock">已审定(锁定)</span></td>
<td class="cell-num">251,904.72</td>
<td class="cell-num">226,338.10</td>
<td class="cell-num">35</td>
<td class="cell-code">YS202609</td>
<td class="cell-muted">2026-09-28 10:12</td>
<td class="cell-actions"><a>详情</a><a class="muted" title="已锁定的月结不可修改">调整单</a></td>
</tr>
<tr>
<td>2026-08</td>
<td><span class="pill pill-reject">已驳回</span></td>
<td class="cell-num">232,117.55</td>
<td class="cell-num">208,640.02</td>
<td class="cell-num">34</td>
<td class="cell-code">YS202608</td>
<td class="cell-muted">2026-08-29 16:40</td>
<td class="cell-actions"><a>详情</a><a>重新送审</a></td>
</tr>
</tbody>
</table>
<div class="card-foot">
<div class="pager">
<span class="pg">‹</span><span class="pg cur">1</span><span class="pg">›</span>
<span style="margin-left:10px">共 10 条</span>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="note">
月结是<b>锁点</b>:审定后绩效与应付合计不可改,只能靠调整单纠偏,状态条与列表同步体现这件事。
状态标签分四档——草稿(中性灰)、待审批(琥珀)、已审定(靛蓝)、已驳回(砖红),
颜色之外还有文字,不靠颜色单独表意。
</div>
<!-- 09-2 审批管理 -->
<div class="app-shot" style="margin-top:26px">
<div class="canvas">
<div class="topbar">
<div class="crumb">系统管理 <span>/</span> <b>审批管理</b></div>
<div class="who"><span class="avatar">财</span><span>财务</span><span class="logout">退出登录</span></div>
</div>
<div class="content">
<div class="page-head">
<div>
<h1>审批管理</h1>
<div class="desc">月度结算、二次分配方案、调整单的复核与审定;送审内容以快照留存</div>
<div class="waterline"></div>
</div>
</div>
<div class="filter">
<input class="input" placeholder="单号或业务编号" />
<input class="input" placeholder="状态:全部" style="width:130px" />
<input class="input" placeholder="类型:全部" style="width:130px" />
<button class="btn btn-primary">查询</button>
<button class="btn btn-default">重置</button>
<span class="spacer"></span>
</div>
<div class="split">
<div class="card">
<table class="grid">
<thead>
<tr><th style="width:140px">审批单号</th><th style="width:120px">类型</th><th style="width:60px">版本</th><th>引用单号</th><th style="width:110px">状态</th><th style="width:90px">提交人</th><th style="width:140px">提交时间</th></tr>
</thead>
<tbody>
<tr>
<td class="cell-code">YS202610</td>
<td>月度结算</td>
<td class="cell-num">v2</td>
<td class="cell-code">2026-10</td>
<td><span class="pill pill-wait">待财务复核</span></td>
<td>张岚</td>
<td class="cell-muted">10-21 14:32</td>
</tr>
<tr>
<td class="cell-code">SP20261003</td>
<td>二次分配方案</td>
<td class="cell-num">v1</td>
<td class="cell-code">BS20261018</td>
<td><span class="pill pill-wait">待领导审核</span></td>
<td>王浩</td>
<td class="cell-muted">10-21 11:08</td>
</tr>
<tr>
<td class="cell-code">AD20261007</td>
<td>调整单</td>
<td class="cell-num">v3</td>
<td class="cell-code">BS20261009</td>
<td><span class="pill pill-ok">已通过</span></td>
<td>李敏</td>
<td class="cell-muted">10-20 17:45</td>
</tr>
<tr>
<td class="cell-code">YS202609</td>
<td>月度结算</td>
<td class="cell-num">v1</td>
<td class="cell-code">2026-09</td>
<td><span class="pill pill-reject">已驳回</span></td>
<td>张岚</td>
<td class="cell-muted">09-28 10:12</td>
</tr>
</tbody>
</table>
</div>
<div class="panel">
<div class="panel-title">审批详情 <span class="b-tag b-tag-warn">待财务复核</span></div>
<div class="panel-sub">送审内容为快照,与源单据当前值无关</div>
<dl class="kv">
<dt>审批单号</dt><dd class="num">YS202610</dd>
<dt>类型</dt><dd>月度结算</dd>
<dt>版本</dt><dd class="num">v2</dd>
<dt>提交人</dt><dd>张岚 · 2026-10-21 14:32</dd>
<dt>结算月份</dt><dd class="num">2026-10</dd>
<dt>绩效合计</dt><dd class="num">268,430.16 元</dd>
<dt>应付合计</dt><dd class="num">241,876.40 元</dd>
<dt>核算人数</dt><dd class="num">36 人</dd>
</dl>
<div class="row" style="margin-top:16px">
<button class="btn btn-primary" style="flex:1">通过</button>
<button class="btn btn-danger" style="flex:1">驳回</button>
</div>
<div class="note" style="margin-top:12px;font-size:12px">
驳回必须写明原因——审批意见与送审快照一起留痕。
</div>
</div>
</div>
</div>
</div>
</div>
<div class="note">
审批详情是<b>抽屉</b>(此处与列表并列展示以便看清内容):右侧滑入,遮罩 + 面板。
列表与详情的关键字段——<b>版本号</b>与<b>状态</b>——必须同时可见,审批人才能判断自己看的是哪一版。
送审内容不变则不重复提单、不新增版本号。
</div>
<!-- 09-3 报表统计 -->
<div class="app-shot" style="margin-top:26px">
<div class="canvas">
<div class="topbar">
<div class="crumb">报表统计 <span>/</span> <b>个人绩效明细</b></div>
<div class="who"><span class="avatar">领</span><span>领导</span><span class="logout">退出登录</span></div>
</div>
<div class="content">
<div class="page-head">
<div>
<h1>个人绩效明细</h1>
<div class="desc">按月核对每一笔业务的绩效与应付金额;口径与月结一致</div>
<div class="waterline"></div>
</div>
</div>
<div class="filter">
<input class="input" placeholder="月份:2026-10" style="width:120px" />
<input class="input" placeholder="人员:全部" style="width:120px" />
<input class="input" placeholder="产品类别:全部" style="width:130px" />
<input class="input" placeholder="岗位:全部" style="width:110px" />
<button class="btn btn-primary">查询</button>
<button class="btn btn-default">重置</button>
<span class="spacer"></span>
<button class="btn btn-default">导出 Excel</button>
<button class="btn btn-default">打印</button>
</div>
<div class="card">
<table class="grid dense">
<thead>
<tr><th style="width:140px">合同编号</th><th style="width:92px">发货日</th><th style="width:92px">回款日</th><th style="width:72px">回款天数</th><th style="width:92px">产品类别</th><th style="width:92px">客户类型</th><th style="width:82px">岗位</th><th style="width:92px">计提比例</th><th style="width:82px">权重R</th><th style="width:104px">绩效</th><th style="width:104px">应付</th></tr>
</thead>
<tbody>
<tr>
<td class="cell-code">BS20261018</td><td>2026-10-08</td><td>2026-10-21</td>
<td class="cell-num">13</td><td>市政水利</td><td>市政单位</td><td>营销员</td>
<td class="cell-num">5‰</td><td class="cell-num">0.85</td>
<td class="cell-num cell-strong">4,320.00</td><td class="cell-num">3,928.00</td>
</tr>
<tr>
<td class="cell-code">BS20261021</td><td>2026-10-11</td><td>2026-10-22</td>
<td class="cell-num">11</td><td>轨道交通</td><td>建设单位</td><td>营销员</td>
<td class="cell-num">5‰</td><td class="cell-num">0.85</td>
<td class="cell-num cell-strong">2,100.00</td><td class="cell-num">1,910.00</td>
</tr>
<tr>
<td class="cell-code">BS20261009</td><td>2026-09-26</td><td>2026-10-09</td>
<td class="cell-num">13</td><td>市政水利</td><td>市政单位</td><td>营销经理</td>
<td class="cell-num">5‰</td><td class="cell-num">0.12</td>
<td class="cell-num cell-strong">1,860.00</td><td class="cell-num">1,690.00</td>
</tr>
<tr>
<td class="cell-code">BS20261012</td><td>2026-10-02</td><td>2026-10-15</td>
<td class="cell-num">13</td><td>混合业务</td><td>经销单位</td><td>信息员</td>
<td class="cell-num">1‰</td><td class="cell-num">1.00</td>
<td class="cell-num cell-strong">860.00</td><td class="cell-num">782.00</td>
</tr>
</tbody>
</table>
<div class="card-foot">
<div class="pager">
<span class="pg">‹</span><span class="pg cur">1</span><span class="pg">2</span><span class="pg">›</span>
<span style="margin-left:10px">共 128 条 · 每页 10 条</span>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="note">
报表是<b>密集表</b>:行高与字号各降半档(12.5px / 7px 内距),但金额仍用等宽数字右对齐、绩效列加粗——
密集不等于看不清。首列可展开查看该合同的分摊明细。
</div>
<!-- 09-4 打印视图 -->
<div class="app-shot" style="margin-top:26px">
<div class="canvas" style="background:#eceef2">
<div class="topbar">
<div class="crumb"><b>报表打印</b> <span style="color:var(--ys-ink-3)">/ 个人绩效工资明细表</span></div>
<div class="who"><button class="btn btn-primary" style="height:30px;font-size:12px">打印 / 另存为 PDF</button></div>
</div>
<div class="content" style="display:flex;justify-content:center;padding:28px 22px">
<div class="sheet">
<h4>个人绩效工资明细表</h4>
<div class="sheet-meta">统计月份:2026-10 | 打印时间:2026-10-22 09:41 | 模板版本 V1.2</div>
<div class="block-title">一、团队分成汇总</div>
<table>
<thead><tr><th>团队</th><th style="text-align:right">人数</th><th style="text-align:right">绩效合计</th><th style="text-align:right">应付合计</th></tr></thead>
<tbody>
<tr><td>市政一部</td><td class="num">12</td><td class="num">96,412.30</td><td class="num">87,735.99</td></tr>
<tr><td>市政二部</td><td class="num">9</td><td class="num">71,845.16</td><td class="num">65,379.60</td></tr>
<tr><td>轨道交通组</td><td class="num">7</td><td class="num">54,102.44</td><td class="num">49,233.22</td></tr>
</tbody>
</table>
<div class="block-title">二、按客户类型对比</div>
<table>
<thead><tr><th>客户类型</th><th style="text-align:right">笔数</th><th style="text-align:right">绩效合计</th><th style="text-align:right">占比</th></tr></thead>
<tbody>
<tr><td>市政单位</td><td class="num">46</td><td class="num">132,806.90</td><td class="num">49.5%</td></tr>
<tr><td>建设单位</td><td class="num">31</td><td class="num">82,904.55</td><td class="num">30.9%</td></tr>
<tr><td>经销单位</td><td class="num">18</td><td class="num">52,718.71</td><td class="num">19.6%</td></tr>
</tbody>
</table>
<div class="block-title">三、对账汇总</div>
<table>
<tbody>
<tr><td>台账绩效合计</td><td class="num">268,430.16 元</td></tr>
<tr><td>调整单影响</td><td class="num">−3,120.00 元</td></tr>
<tr><td>月结应付合计</td><td class="num">241,876.40 元</td></tr>
</tbody>
</table>
<div class="sign-row">
<div>制表:____________</div>
<div>复核:____________</div>
<div>审批:____________</div>
</div>
</div>
</div>
</div>
</div>
<div class="note">
打印视图是<b>独立顶层路由</b>,不挂侧栏与顶栏——浏览器打印只出报表本身,PDF 由打印对话框「另存为 PDF」导出。
打印稿是<b>纸面产物</b>,与屏幕稿不同源:白底、实线表格、章节编号、签字栏,不带任何阴影与圆角。
超出打印行数上限时只打前 N 行,并在稿面上明确提示,不静默截断。
</div>
</section>
</div>
<script src="echarts.min.js"></script>
<script>
/* 仪表盘图表:ECharts 定制主题(圆角柱 / 无网格线 / 浅灰轴标签)——实施时前端引入 echarts 依赖 */
/* 工作台图表:ECharts 定制主题(圆角柱 / 无网格线 / 浅灰轴标签)——实施时前端引入 echarts 依赖 */
const chartFont = "'Noto Sans SC','PingFang SC',sans-serif";
const rev = echarts.init(document.getElementById('chartRev'), null, { renderer: 'svg' });
rev.setOption({
grid: { left: 0, right: 0, top: 6, bottom: 20, containLabel: true },
grid: { left: 8, right: 12, top: 18, bottom: 4, containLabel: true },
xAxis: {
type: 'category', data: ['5月', '6月', '7月', '8月', '9月', '10月'],
axisLine: { show: false }, axisTick: { show: false },
axisLine: { lineStyle: { color: 'rgba(28,35,51,.15)' } }, axisTick: { show: false },
axisLabel: { color: '#9aa3b2', fontSize: 9, margin: 10, fontFamily: chartFont }
},
yAxis: { type: 'value', show: false },
yAxis: { type: 'value', show: false, splitLine: { show: false } },
series: [{
type: 'bar', barWidth: 22, data: [34, 42, 30, 48, 38, 56],
itemStyle: {
@ -958,15 +1522,19 @@
});
const perf = echarts.init(document.getElementById('chartPerf'), null, { renderer: 'svg' });
perf.setOption({
grid: { left: 0, right: 0, top: 6, bottom: 2 },
xAxis: { type: 'category', show: false, boundaryGap: false, data: [1, 2, 3, 4, 5, 6, 7] },
yAxis: { type: 'value', show: false, min: 0 },
grid: { left: 8, right: 12, top: 18, bottom: 4, containLabel: true },
xAxis: {
type: 'category', data: ['5月', '6月', '7月', '8月', '9月', '10月'],
axisLine: { lineStyle: { color: 'rgba(28,35,51,.15)' } }, axisTick: { show: false },
axisLabel: { color: '#9aa3b2', fontSize: 9, margin: 10, fontFamily: chartFont }
},
yAxis: { type: 'value', show: false, splitLine: { show: false } },
series: [{
type: 'line', data: [8, 13, 10, 19, 23, 29, 33], smooth: 0.4, symbol: 'none',
lineStyle: { color: '#2e4ba8', width: 1.6 },
type: 'line', data: [186, 204, 178, 232, 251, 268], smooth: 0.4, symbol: 'none',
lineStyle: { color: '#2e4ba8', width: 2 },
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: 'rgba(46,75,168,.10)' }, { offset: 1, color: 'rgba(46,75,168,0)' }
{ offset: 0, color: 'rgba(46,75,168,.22)' }, { offset: 1, color: 'rgba(46,75,168,0)' }
])
}
}]

Binary file not shown.