Files
X-Financial/document/development/ui/personal-workbench-home-reference.html
caoxiaozhu d0e946cf47 feat: 完善文档中心与报销申请交互及侧边栏重构
后端优化编排器报销查询和本体检测精度,增强报销单草稿保
存和附件回填逻辑,前端重构侧边栏组件支持折叠和图标导
航,完善文档中心状态筛选和详情提示,报销创建和审批详情
页优化会话管理和费用明细交互,新增助手应用服务和预设动
作工具函数,补充单元测试覆盖。
2026-05-25 13:35:39 +08:00

747 lines
18 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!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 {
--bg: #f4f7fb;
--panel: #ffffff;
--line: #e4ebf3;
--line-strong: #d6e1ed;
--text: #0f172a;
--muted: #64748b;
--soft: #f8fbff;
--green: #0f9f6e;
--green-dark: #047857;
--blue: #2563eb;
--amber: #b7791f;
--red: #d93025;
--shadow: 0 18px 44px rgba(15, 23, 42, 0.08);
font-family:
"Microsoft YaHei UI", "Microsoft YaHei", "PingFang SC",
"Noto Sans CJK SC", "Segoe UI", sans-serif;
}
* {
box-sizing: border-box;
}
body {
margin: 0;
min-height: 100vh;
background:
radial-gradient(circle at 18% 0%, rgba(16, 185, 129, 0.13), transparent 29%),
radial-gradient(circle at 86% 12%, rgba(37, 99, 235, 0.10), transparent 24%),
var(--bg);
color: var(--text);
}
.app {
width: 1440px;
min-height: 960px;
margin: 0 auto;
display: grid;
grid-template-columns: 84px 1fr;
background: rgba(255, 255, 255, 0.42);
}
.rail {
padding: 20px 12px;
background: #0f172a;
color: #cbd5e1;
display: grid;
grid-template-rows: auto 1fr auto;
gap: 24px;
}
.brand-mark {
width: 44px;
height: 44px;
margin: 0 auto;
border-radius: 14px;
display: grid;
place-items: center;
background: linear-gradient(135deg, #10b981, #2563eb);
color: white;
font-weight: 900;
letter-spacing: 0;
box-shadow: 0 12px 26px rgba(16, 185, 129, 0.24);
}
.nav {
display: grid;
gap: 12px;
align-content: start;
}
.nav-item {
height: 56px;
border-radius: 16px;
display: grid;
place-items: center;
color: #94a3b8;
font-size: 12px;
font-weight: 700;
}
.nav-item.active {
color: #ffffff;
background: rgba(255, 255, 255, 0.12);
box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.08);
}
.main {
padding: 22px 30px 30px;
display: grid;
grid-template-rows: auto 1fr;
gap: 18px;
}
.topbar {
height: 58px;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 4px;
}
.crumb strong {
display: block;
font-size: 22px;
line-height: 1.2;
font-weight: 800;
letter-spacing: 0;
}
.crumb span {
display: block;
margin-top: 6px;
color: var(--muted);
font-size: 13px;
}
.user-pill {
height: 38px;
display: inline-flex;
align-items: center;
gap: 10px;
padding: 0 12px 0 6px;
border: 1px solid var(--line);
border-radius: 999px;
background: rgba(255, 255, 255, 0.74);
color: #334155;
font-size: 13px;
font-weight: 700;
}
.avatar {
width: 28px;
height: 28px;
border-radius: 999px;
display: grid;
place-items: center;
background: #e8f7f0;
color: var(--green-dark);
font-weight: 900;
}
.content {
display: grid;
gap: 18px;
}
.hero {
position: relative;
overflow: hidden;
min-height: 254px;
display: grid;
grid-template-columns: 230px minmax(0, 1fr);
gap: 22px;
padding: 24px 28px 22px 20px;
border: 1px solid rgba(15, 159, 110, 0.16);
border-radius: 18px;
background:
linear-gradient(135deg, rgba(247, 255, 251, 0.98), rgba(255, 255, 255, 0.98) 55%, rgba(244, 249, 255, 0.96)),
var(--panel);
box-shadow: var(--shadow);
}
.hero::after {
content: "";
position: absolute;
width: 300px;
height: 300px;
right: -110px;
bottom: -138px;
border-radius: 50%;
background: rgba(16, 185, 129, 0.08);
}
.bot-wrap {
position: relative;
min-height: 206px;
display: flex;
align-items: end;
justify-content: center;
}
.bot-wrap::before {
content: "";
position: absolute;
left: 18px;
right: 18px;
bottom: 4px;
height: 58px;
border-radius: 50%;
background: rgba(16, 185, 129, 0.13);
filter: blur(13px);
}
.bot-wrap img {
position: relative;
width: 176px;
height: auto;
filter: drop-shadow(0 24px 26px rgba(15, 23, 42, 0.15));
}
.hero-copy {
position: relative;
z-index: 1;
display: grid;
align-content: center;
gap: 14px;
}
.hero-title {
margin: 0;
max-width: 860px;
font-size: 27px;
line-height: 1.32;
font-weight: 850;
letter-spacing: 0;
}
.hero-subtitle {
margin: 0;
max-width: 880px;
color: #53637a;
font-size: 14px;
line-height: 1.68;
}
.composer {
min-height: 58px;
display: grid;
grid-template-columns: minmax(0, 1fr) auto auto;
align-items: center;
gap: 10px;
padding: 8px;
border: 1px solid rgba(148, 163, 184, 0.28);
border-radius: 15px;
background: rgba(255, 255, 255, 0.92);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.74);
}
.composer-text {
padding: 0 12px;
color: #94a3b8;
font-size: 14px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.btn {
height: 42px;
border: 0;
border-radius: 11px;
padding: 0 16px;
display: inline-flex;
align-items: center;
justify-content: center;
gap: 8px;
font-size: 14px;
font-weight: 800;
white-space: nowrap;
}
.btn.secondary {
border: 1px solid rgba(15, 118, 110, 0.18);
background: linear-gradient(180deg, #ffffff, #f2faf7);
color: #0f766e;
}
.btn.primary {
background: linear-gradient(135deg, #10b981, #059669);
color: #ffffff;
box-shadow: 0 12px 24px rgba(16, 185, 129, 0.20);
}
.intent-grid {
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
gap: 14px;
}
.intent-card {
min-height: 116px;
padding: 18px;
border: 1px solid var(--line);
border-radius: 16px;
background: rgba(255, 255, 255, 0.92);
box-shadow: 0 10px 28px rgba(15, 23, 42, 0.055);
display: grid;
gap: 12px;
align-content: start;
}
.intent-top {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
}
.intent-icon {
width: 38px;
height: 38px;
border-radius: 12px;
display: grid;
place-items: center;
font-size: 14px;
font-weight: 900;
}
.intent-icon.green {
background: #e8f7f0;
color: var(--green-dark);
}
.intent-icon.blue {
background: #eff6ff;
color: var(--blue);
}
.intent-icon.amber {
background: #fff7e6;
color: var(--amber);
}
.intent-icon.slate {
background: #f1f5f9;
color: #475569;
}
.intent-arrow {
color: #94a3b8;
font-size: 18px;
font-weight: 800;
}
.intent-card h3 {
margin: 0;
color: var(--text);
font-size: 16px;
line-height: 1.35;
font-weight: 800;
}
.intent-card p {
margin: -6px 0 0;
color: var(--muted);
font-size: 13px;
line-height: 1.5;
}
.lower-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 18px;
}
.panel {
border: 1px solid var(--line);
border-radius: 16px;
background: rgba(255, 255, 255, 0.94);
box-shadow: 0 10px 26px rgba(15, 23, 42, 0.045);
overflow: hidden;
}
.panel-head {
min-height: 58px;
padding: 0 20px;
display: flex;
align-items: center;
justify-content: space-between;
border-bottom: 1px solid var(--line);
}
.panel-head h3 {
margin: 0;
font-size: 16px;
line-height: 1.2;
font-weight: 800;
}
.panel-head span {
color: var(--green-dark);
font-size: 13px;
font-weight: 800;
}
.rows {
padding: 2px 20px;
}
.row {
min-height: 70px;
display: grid;
grid-template-columns: 42px minmax(0, 1fr) auto;
align-items: center;
gap: 14px;
border-top: 1px solid #edf2f7;
}
.row:first-child {
border-top: 0;
}
.row-icon {
width: 38px;
height: 38px;
border-radius: 13px;
display: grid;
place-items: center;
background: #eefaf4;
color: var(--green-dark);
font-size: 12px;
font-weight: 900;
}
.row-copy {
min-width: 0;
}
.row-copy strong {
display: block;
font-size: 14px;
line-height: 1.35;
font-weight: 800;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.row-copy small {
display: block;
margin-top: 5px;
color: var(--muted);
font-size: 12px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.row-action {
min-width: 78px;
height: 34px;
border: 1px solid rgba(16, 185, 129, 0.26);
border-radius: 999px;
display: grid;
place-items: center;
color: var(--green-dark);
font-size: 12px;
font-weight: 800;
background: #f6fffb;
}
.amount {
font-size: 18px;
font-weight: 900;
text-align: right;
}
.status {
margin-left: 10px;
min-width: 92px;
height: 30px;
border-radius: 999px;
display: inline-grid;
place-items: center;
background: #eff6ff;
color: var(--blue);
font-size: 12px;
font-weight: 850;
}
.wide-panel {
display: grid;
grid-template-columns: 1.25fr 1fr;
gap: 0;
}
.policy-list {
border-left: 1px solid var(--line);
}
.mini-section {
min-height: 178px;
}
.mini-section .panel-head {
border-bottom: 0;
min-height: 50px;
}
.metric-strip {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 12px;
padding: 0 20px 20px;
}
.metric {
min-height: 88px;
border: 1px solid var(--line);
border-radius: 14px;
background: var(--soft);
padding: 14px;
}
.metric strong {
display: block;
font-size: 24px;
line-height: 1;
font-weight: 900;
}
.metric span {
display: block;
margin-top: 9px;
color: var(--muted);
font-size: 12px;
font-weight: 700;
}
@media (max-width: 1000px) {
.app {
width: 100%;
grid-template-columns: 1fr;
}
.rail {
display: none;
}
.main {
padding: 18px;
}
.hero,
.lower-grid,
.wide-panel {
grid-template-columns: 1fr;
}
.intent-grid {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
.policy-list {
border-left: 0;
border-top: 1px solid var(--line);
}
}
</style>
</head>
<body>
<main class="app">
<aside class="rail" aria-label="侧边导航">
<div class="brand-mark">XF</div>
<nav class="nav">
<div class="nav-item active">工作台</div>
<div class="nav-item">申请</div>
<div class="nav-item">审批</div>
<div class="nav-item">规则</div>
<div class="nav-item">知识</div>
</nav>
<div class="nav-item">设置</div>
</aside>
<section class="main">
<header class="topbar">
<div class="crumb">
<strong>个人工作台</strong>
<span>把费用申请、报销处理、进度查询和制度问答集中到一个入口。</span>
</div>
<div class="user-pill">
<span class="avatar">A</span>
<span>admin</span>
</div>
</header>
<div class="content">
<article class="hero">
<div class="bot-wrap">
<img src="../../../web/src/assets/robot-helper.png" alt="" />
</div>
<div class="hero-copy">
<h1 class="hero-title">admin描述您想做的事AI 会直接帮您处理</h1>
<p class="hero-subtitle">
我会自动识别您的意图,协助完成费用申请、报销、查询和制度问答等业务工作,
并把事情推进到可执行的下一步。
</p>
<div class="composer">
<div class="composer-text">例如:帮我查一下上周提交的差旅报销到哪一步了</div>
<button class="btn secondary">上传票据</button>
<button class="btn primary">开始处理</button>
</div>
</div>
</article>
<section class="intent-grid" aria-label="业务入口">
<article class="intent-card">
<div class="intent-top">
<span class="intent-icon green"></span>
<span class="intent-arrow"></span>
</div>
<h3>费用申请</h3>
<p>发起招待、差旅、采购等费用事项</p>
</article>
<article class="intent-card">
<div class="intent-top">
<span class="intent-icon blue"></span>
<span class="intent-arrow"></span>
</div>
<h3>报销处理</h3>
<p>上传票据,生成草稿并核对材料</p>
</article>
<article class="intent-card">
<div class="intent-top">
<span class="intent-icon amber"></span>
<span class="intent-arrow"></span>
</div>
<h3>进度查询</h3>
<p>查询单据状态、审批节点和到账情况</p>
</article>
<article class="intent-card">
<div class="intent-top">
<span class="intent-icon slate"></span>
<span class="intent-arrow"></span>
</div>
<h3>制度问答</h3>
<p>咨询标准、附件要求和可报销边界</p>
</article>
</section>
<section class="lower-grid">
<article class="panel">
<header class="panel-head">
<h3>报销待办</h3>
<span>查看全部</span>
</header>
<div class="rows">
<div class="row">
<span class="row-icon"></span>
<div class="row-copy">
<strong>业务招待报销建议补参与人员</strong>
<small>AI 建议:补充客户单位、客户人数、我方陪同人员</small>
</div>
<span class="row-action">去补充</span>
</div>
<div class="row">
<span class="row-icon"></span>
<div class="row-copy">
<strong>差旅报销单待提交</strong>
<small>补齐出发交通,可直接生成报销单</small>
</div>
<span class="row-action">继续填</span>
</div>
<div class="row">
<span class="row-icon"></span>
<div class="row-copy">
<strong>有 5 张票据未关联报销单</strong>
<small>其中 3 张疑似交通费,可合并生成交通报销</small>
</div>
<span class="row-action">去整理</span>
</div>
</div>
</article>
<article class="panel">
<header class="panel-head">
<h3>报销进度</h3>
<span>查看全部</span>
</header>
<div class="rows">
<div class="row">
<span class="row-icon"></span>
<div class="row-copy">
<strong>差旅报销</strong>
<small>提交时间2026-05-03</small>
</div>
<div><span class="amount">¥3,280</span><span class="status">主管审批中</span></div>
</div>
<div class="row">
<span class="row-icon"></span>
<div class="row-copy">
<strong>交通报销</strong>
<small>提交时间2026-05-02</small>
</div>
<div><span class="amount">¥126</span><span class="status">财务复核中</span></div>
</div>
<div class="row">
<span class="row-icon"></span>
<div class="row-copy">
<strong>办公采购</strong>
<small>提交时间2026-05-01</small>
</div>
<div><span class="amount">¥458</span><span class="status">已到账</span></div>
</div>
</div>
</article>
</section>
<section class="panel wide-panel">
<article class="mini-section">
<header class="panel-head">
<h3>智能概览</h3>
<span>本月</span>
</header>
<div class="metric-strip">
<div class="metric"><strong>12</strong><span>待处理事项</span></div>
<div class="metric"><strong>86%</strong><span>材料完整率</span></div>
<div class="metric"><strong>2.4天</strong><span>平均审批时长</span></div>
</div>
</article>
<article class="mini-section policy-list">
<header class="panel-head">
<h3>最新报销制度</h3>
<span>查看全部</span>
</header>
<div class="rows">
<div class="row">
<span class="row-icon"></span>
<div class="row-copy">
<strong>差旅报销管理办法2026版</strong>
<small>更新住宿标准与交通等级规则</small>
</div>
<span class="row-action">查看</span>
</div>
</div>
</article>
</section>
</div>
</section>
</main>
</body>
</html>