后端新增员工行为画像算法模块,支持标签规则引擎和评分计算, 完善员工模型、银行信息、序列化和导入逻辑,优化报销审批流 和工作流常量,增强 Hermes 同步和知识同步能力,前端新增费 用画像详情弹窗、雷达图和风险卡片组件,完善登录页和工作台 样式,优化文档中心和归档中心交互,补充单元测试。
601 lines
13 KiB
CSS
601 lines
13 KiB
CSS
.rail {
|
|
--rail-motion-duration: 220ms;
|
|
--rail-motion-ease: cubic-bezier(0.4, 0, 0.2, 1);
|
|
--rail-fade-duration: 110ms;
|
|
--rail-label-delay: 55ms;
|
|
|
|
position: sticky;
|
|
top: 0;
|
|
width: 100%;
|
|
height: var(--desktop-stage-height, 100dvh);
|
|
min-height: var(--desktop-stage-height, 100dvh);
|
|
min-width: 0;
|
|
display: flex;
|
|
flex-direction: column;
|
|
overflow: visible;
|
|
background: linear-gradient(180deg, rgba(255, 255, 255, 0.98), rgba(248, 250, 252, 0.96)), #fff;
|
|
border-right: 1px solid #dbe4ee;
|
|
box-shadow: 1px 0 0 rgba(15, 23, 42, 0.02);
|
|
z-index: 20;
|
|
contain: layout;
|
|
transform: translateZ(0);
|
|
transition:
|
|
background 240ms var(--ease),
|
|
box-shadow 240ms var(--ease);
|
|
}
|
|
|
|
.rail-brand {
|
|
position: relative;
|
|
min-height: 112px;
|
|
display: flex;
|
|
align-items: flex-start;
|
|
justify-content: flex-start;
|
|
gap: 12px;
|
|
padding: 54px 16px 8px;
|
|
overflow: visible;
|
|
transition:
|
|
min-height var(--rail-motion-duration) var(--rail-motion-ease),
|
|
padding var(--rail-motion-duration) var(--rail-motion-ease),
|
|
gap var(--rail-motion-duration) var(--rail-motion-ease);
|
|
will-change: min-height, padding, gap;
|
|
}
|
|
|
|
.brand-mark {
|
|
flex: 0 0 auto;
|
|
width: 32px;
|
|
height: 32px;
|
|
display: grid;
|
|
place-items: center;
|
|
color: var(--theme-primary-active);
|
|
border-radius: 4px;
|
|
overflow: hidden;
|
|
transform: translateY(-8px);
|
|
transition:
|
|
color 160ms var(--ease),
|
|
transform var(--rail-motion-duration) var(--rail-motion-ease);
|
|
will-change: transform;
|
|
}
|
|
|
|
.custom-logo {
|
|
width: 100%;
|
|
height: 100%;
|
|
object-fit: contain;
|
|
}
|
|
|
|
.brand-mark svg {
|
|
width: 32px;
|
|
height: 32px;
|
|
fill: currentColor;
|
|
}
|
|
|
|
.brand-name {
|
|
flex: 1 1 auto;
|
|
min-width: 0;
|
|
max-width: 124px;
|
|
color: #0f172a;
|
|
font-size: 16px;
|
|
font-weight: 800;
|
|
white-space: nowrap;
|
|
overflow: hidden;
|
|
transform: translateY(-8px);
|
|
transition:
|
|
max-width var(--rail-motion-duration) var(--rail-motion-ease),
|
|
opacity var(--rail-fade-duration) var(--rail-motion-ease) var(--rail-label-delay),
|
|
transform var(--rail-fade-duration) var(--rail-motion-ease) var(--rail-label-delay);
|
|
will-change: max-width, opacity, transform;
|
|
}
|
|
|
|
.rail-collapse-btn {
|
|
position: absolute;
|
|
right: -14px;
|
|
top: 55px;
|
|
z-index: 30;
|
|
width: 28px;
|
|
height: 28px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
cursor: pointer;
|
|
border: 1px solid #dbe4ee;
|
|
border-radius: 999px;
|
|
background: rgba(255, 255, 255, 0.96);
|
|
color: #64748b;
|
|
box-shadow:
|
|
0 8px 18px rgba(15, 23, 42, 0.12),
|
|
0 0 0 3px rgba(248, 250, 252, 0.92);
|
|
transition:
|
|
top var(--rail-motion-duration) var(--rail-motion-ease),
|
|
right var(--rail-motion-duration) var(--rail-motion-ease),
|
|
width var(--rail-motion-duration) var(--rail-motion-ease),
|
|
height var(--rail-motion-duration) var(--rail-motion-ease),
|
|
transform var(--rail-motion-duration) var(--rail-motion-ease),
|
|
background 180ms var(--ease),
|
|
border-color 180ms var(--ease),
|
|
color 180ms var(--ease),
|
|
box-shadow 180ms var(--ease);
|
|
}
|
|
|
|
.rail-collapse-btn:hover {
|
|
border-color: rgba(var(--theme-primary-rgb, 58, 124, 165), 0.28);
|
|
background: #fff;
|
|
color: var(--theme-primary-active);
|
|
box-shadow:
|
|
0 10px 22px rgba(var(--theme-primary-rgb, 58, 124, 165), 0.16),
|
|
0 0 0 3px rgba(248, 250, 252, 0.96);
|
|
}
|
|
|
|
.rail-collapse-btn .mdi {
|
|
font-size: 17px;
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
.rail-collapse-btn .mdi-chevron-left {
|
|
margin-left: 1px;
|
|
}
|
|
|
|
.rail-collapse-btn .mdi-chevron-right {
|
|
margin-right: 1px;
|
|
}
|
|
|
|
.rail-nav {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 8px;
|
|
padding: 4px 8px 16px;
|
|
overflow-y: auto;
|
|
overflow-x: hidden;
|
|
flex: 1;
|
|
transition:
|
|
padding var(--rail-motion-duration) var(--rail-motion-ease),
|
|
gap var(--rail-motion-duration) var(--rail-motion-ease);
|
|
will-change: padding, gap;
|
|
}
|
|
|
|
.nav-btn {
|
|
width: 100%;
|
|
min-height: 48px;
|
|
position: relative;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 12px;
|
|
padding: 0;
|
|
border: 1px solid transparent;
|
|
border-radius: 4px;
|
|
background: transparent;
|
|
color: #64748b;
|
|
text-align: left;
|
|
overflow: hidden;
|
|
transition:
|
|
gap var(--rail-motion-duration) var(--rail-motion-ease),
|
|
background 180ms var(--ease),
|
|
border-color 180ms var(--ease),
|
|
color 180ms var(--ease);
|
|
will-change: gap;
|
|
}
|
|
|
|
.nav-btn:hover {
|
|
background: rgba(var(--theme-primary-rgb, 58, 124, 165), 0.08);
|
|
color: var(--theme-primary-active);
|
|
}
|
|
|
|
.nav-btn.active {
|
|
background: var(--theme-primary-soft);
|
|
border-color: rgba(var(--theme-primary-rgb, 58, 124, 165), 0.18);
|
|
color: var(--theme-primary-active);
|
|
}
|
|
|
|
.nav-icon {
|
|
flex: 0 0 48px;
|
|
width: 48px;
|
|
height: 36px;
|
|
display: grid;
|
|
place-items: center;
|
|
border-radius: 4px;
|
|
color: currentColor;
|
|
transition: color 180ms var(--ease);
|
|
}
|
|
|
|
.nav-btn :deep(svg) {
|
|
width: 19px;
|
|
height: 19px;
|
|
stroke: currentColor;
|
|
stroke-width: 2;
|
|
fill: none;
|
|
stroke-linecap: round;
|
|
stroke-linejoin: round;
|
|
}
|
|
|
|
.nav-btn :deep(svg text) {
|
|
fill: currentColor;
|
|
stroke: none;
|
|
}
|
|
|
|
.nav-label {
|
|
flex: 1;
|
|
min-width: 0;
|
|
max-width: 128px;
|
|
color: currentColor;
|
|
font-size: 14px;
|
|
font-weight: 700;
|
|
white-space: nowrap;
|
|
overflow: hidden;
|
|
opacity: 1;
|
|
transition:
|
|
max-width var(--rail-motion-duration) var(--rail-motion-ease),
|
|
opacity var(--rail-fade-duration) var(--rail-motion-ease) var(--rail-label-delay),
|
|
transform var(--rail-fade-duration) var(--rail-motion-ease) var(--rail-label-delay);
|
|
will-change: max-width, opacity, transform;
|
|
}
|
|
|
|
.nav-badge {
|
|
flex: 0 0 auto;
|
|
min-width: 34px;
|
|
height: 22px;
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
padding: 0 8px;
|
|
border-radius: 999px;
|
|
background: #ff5b67;
|
|
color: #fff;
|
|
font-size: 12px;
|
|
font-weight: 800;
|
|
transition:
|
|
min-width var(--rail-motion-duration) var(--rail-motion-ease),
|
|
max-width var(--rail-motion-duration) var(--rail-motion-ease),
|
|
padding var(--rail-motion-duration) var(--rail-motion-ease),
|
|
opacity var(--rail-fade-duration) var(--rail-motion-ease) var(--rail-label-delay);
|
|
will-change: min-width, max-width, padding, opacity;
|
|
}
|
|
|
|
.nav-unread-dot {
|
|
flex: 0 0 auto;
|
|
width: 8px;
|
|
height: 8px;
|
|
border: 2px solid #fff;
|
|
border-radius: 999px;
|
|
background: #ef4444;
|
|
box-shadow: 0 6px 14px rgba(239, 68, 68, 0.26);
|
|
}
|
|
|
|
.rail-user {
|
|
position: relative;
|
|
min-width: 0;
|
|
min-height: 78px;
|
|
margin: 0;
|
|
padding: 16px 20px 18px;
|
|
border-top: 1px solid #edf2f7;
|
|
transition: padding var(--rail-motion-duration) var(--rail-motion-ease);
|
|
}
|
|
|
|
.user-summary {
|
|
position: relative;
|
|
min-width: 0;
|
|
min-height: 42px;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 10px;
|
|
padding: 4px;
|
|
color: #64748b;
|
|
border-radius: 4px;
|
|
cursor: pointer;
|
|
transition:
|
|
gap var(--rail-motion-duration) var(--rail-motion-ease),
|
|
padding var(--rail-motion-duration) var(--rail-motion-ease),
|
|
background 180ms var(--ease);
|
|
}
|
|
|
|
.rail-user:hover .user-summary {
|
|
background: rgba(255, 255, 255, 0.72);
|
|
}
|
|
|
|
.user-avatar {
|
|
flex: 0 0 36px;
|
|
width: 36px;
|
|
height: 36px;
|
|
display: grid;
|
|
place-items: center;
|
|
border: 2px solid #fff;
|
|
border-radius: 999px;
|
|
background: linear-gradient(135deg, var(--theme-primary), var(--theme-primary-active));
|
|
box-shadow: 0 6px 14px rgba(var(--theme-primary-rgb, 58, 124, 165), 0.18);
|
|
color: #fff;
|
|
font-size: 14px;
|
|
font-weight: 800;
|
|
transition:
|
|
flex-basis var(--rail-motion-duration) var(--rail-motion-ease),
|
|
width var(--rail-motion-duration) var(--rail-motion-ease),
|
|
height var(--rail-motion-duration) var(--rail-motion-ease);
|
|
}
|
|
|
|
.user-copy {
|
|
flex: 1;
|
|
min-width: 0;
|
|
max-width: 116px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 2px;
|
|
opacity: 1;
|
|
transition:
|
|
max-width var(--rail-motion-duration) var(--rail-motion-ease),
|
|
opacity var(--rail-fade-duration) var(--rail-motion-ease) var(--rail-label-delay),
|
|
transform var(--rail-fade-duration) var(--rail-motion-ease) var(--rail-label-delay);
|
|
will-change: max-width, opacity, transform;
|
|
}
|
|
|
|
.user-copy strong {
|
|
color: #334155;
|
|
font-size: 14px;
|
|
font-weight: 750;
|
|
white-space: nowrap;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
}
|
|
|
|
.user-copy span {
|
|
color: #64748b;
|
|
font-size: 12px;
|
|
white-space: nowrap;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
}
|
|
|
|
.user-summary .mdi {
|
|
flex: 0 0 18px;
|
|
font-size: 18px;
|
|
transition:
|
|
max-width var(--rail-motion-duration) var(--rail-motion-ease),
|
|
opacity var(--rail-fade-duration) var(--rail-motion-ease) var(--rail-label-delay);
|
|
will-change: max-width, opacity;
|
|
}
|
|
|
|
.user-menu {
|
|
position: absolute;
|
|
right: 20px;
|
|
bottom: calc(100% - 6px);
|
|
min-width: 132px;
|
|
padding: 8px;
|
|
border: 1px solid rgba(226, 232, 240, 0.96);
|
|
border-radius: 4px;
|
|
background: rgba(255, 255, 255, 0.98);
|
|
box-shadow: 0 16px 32px rgba(15, 23, 42, 0.1);
|
|
opacity: 0;
|
|
transform: translateY(8px);
|
|
pointer-events: none;
|
|
transition: all 180ms var(--ease);
|
|
z-index: 4;
|
|
}
|
|
|
|
.rail-user:hover .user-menu {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
pointer-events: auto;
|
|
}
|
|
|
|
.user-menu-item {
|
|
width: 100%;
|
|
height: 38px;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
padding: 0 12px;
|
|
border: 0;
|
|
border-radius: 4px;
|
|
background: transparent;
|
|
color: #dc2626;
|
|
font-size: 13px;
|
|
font-weight: 700;
|
|
transition: all 180ms var(--ease);
|
|
}
|
|
|
|
/* ========================================= */
|
|
/* COLLAPSED STATE */
|
|
/* ========================================= */
|
|
|
|
.rail-collapsed .rail-brand {
|
|
min-height: 136px;
|
|
justify-content: flex-start;
|
|
gap: 0;
|
|
padding: 52px 16px 8px;
|
|
}
|
|
|
|
.rail-collapsed .brand-mark {
|
|
width: 32px;
|
|
height: 32px;
|
|
margin: 0;
|
|
transform: translateY(-6px);
|
|
}
|
|
|
|
.rail-collapsed .brand-mark svg {
|
|
width: 32px;
|
|
height: 32px;
|
|
}
|
|
|
|
.rail-collapsed .brand-name {
|
|
position: absolute;
|
|
width: 1px;
|
|
height: 1px;
|
|
max-width: 0;
|
|
margin: 0;
|
|
opacity: 0;
|
|
overflow: hidden;
|
|
clip: rect(0 0 0 0);
|
|
pointer-events: none;
|
|
transform: translateX(-6px);
|
|
transition-delay: 0ms;
|
|
}
|
|
|
|
.rail-collapsed .rail-collapse-btn {
|
|
top: 96px;
|
|
right: -14px;
|
|
width: 28px;
|
|
height: 28px;
|
|
transform: none;
|
|
}
|
|
|
|
.rail-collapsed .rail-nav {
|
|
gap: 8px;
|
|
padding: 4px 8px 16px;
|
|
}
|
|
|
|
.rail-collapsed .nav-btn {
|
|
justify-content: flex-start;
|
|
gap: 0;
|
|
transform: translateX(0);
|
|
}
|
|
|
|
.rail-collapsed .nav-icon {
|
|
width: 48px;
|
|
height: 36px;
|
|
flex: 0 0 48px;
|
|
transform: translateX(0);
|
|
}
|
|
|
|
.rail-collapsed .nav-label {
|
|
max-width: 0;
|
|
opacity: 0;
|
|
transform: translateX(-6px);
|
|
transition-delay: 0ms;
|
|
}
|
|
|
|
.rail-collapsed .nav-badge {
|
|
max-width: 0;
|
|
min-width: 0;
|
|
padding: 0;
|
|
opacity: 0;
|
|
overflow: hidden;
|
|
transition-delay: 0ms;
|
|
}
|
|
|
|
.rail-collapsed .nav-unread-dot {
|
|
position: absolute;
|
|
top: 10px;
|
|
right: 11px;
|
|
width: 9px;
|
|
height: 9px;
|
|
}
|
|
|
|
.rail-collapsed {
|
|
overflow: visible;
|
|
}
|
|
|
|
.rail-collapsed .rail-user {
|
|
position: relative;
|
|
z-index: 6;
|
|
padding: 14px 8px;
|
|
overflow: visible;
|
|
}
|
|
|
|
.rail-collapsed .user-summary {
|
|
justify-content: center;
|
|
padding: 4px;
|
|
gap: 0;
|
|
}
|
|
|
|
.rail-user-menu-floating {
|
|
position: fixed;
|
|
z-index: 12000;
|
|
min-width: 132px;
|
|
padding: 8px;
|
|
border: 1px solid rgba(226, 232, 240, 0.96);
|
|
border-radius: 4px;
|
|
background: rgba(255, 255, 255, 0.98);
|
|
box-shadow: 0 16px 32px rgba(15, 23, 42, 0.14);
|
|
transform: translateY(-50%);
|
|
animation: railUserMenuIn 180ms var(--rail-motion-ease) both;
|
|
}
|
|
|
|
.rail-user-menu-floating .user-menu-item {
|
|
width: 100%;
|
|
}
|
|
|
|
:global(.rail-tooltip-popper) {
|
|
max-width: 180px;
|
|
padding: 7px 10px !important;
|
|
border: 1px solid rgba(var(--theme-primary-rgb, 58, 124, 165), 0.22) !important;
|
|
border-radius: 4px !important;
|
|
background: rgba(255, 255, 255, 0.98) !important;
|
|
color: #1f2937 !important;
|
|
box-shadow: 0 12px 28px rgba(15, 23, 42, 0.14) !important;
|
|
font-size: 12px;
|
|
font-weight: 700;
|
|
line-height: 1.4;
|
|
letter-spacing: 0;
|
|
}
|
|
|
|
:global(.rail-tooltip-popper.el-popper.is-light) {
|
|
border-color: rgba(var(--theme-primary-rgb, 58, 124, 165), 0.22) !important;
|
|
}
|
|
|
|
:global(.rail-tooltip-popper .el-popper__arrow::before) {
|
|
border-color: rgba(var(--theme-primary-rgb, 58, 124, 165), 0.22) !important;
|
|
background: rgba(255, 255, 255, 0.98) !important;
|
|
}
|
|
|
|
@keyframes railUserMenuIn {
|
|
from {
|
|
opacity: 0;
|
|
transform: translateY(-50%) translateX(-6px);
|
|
}
|
|
|
|
to {
|
|
opacity: 1;
|
|
transform: translateY(-50%) translateX(0);
|
|
}
|
|
}
|
|
|
|
.rail-collapsed .user-copy,
|
|
.rail-collapsed .user-summary .mdi {
|
|
max-width: 0;
|
|
opacity: 0;
|
|
overflow: hidden;
|
|
transform: translateX(-6px);
|
|
transition-delay: 0ms;
|
|
}
|
|
|
|
@media (max-width: 980px) and (min-width: 761px) {
|
|
.rail {
|
|
position: relative;
|
|
height: auto;
|
|
}
|
|
}
|
|
|
|
@media (max-width: 760px) {
|
|
.rail {
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
bottom: 0;
|
|
height: 100dvh;
|
|
min-height: 100dvh;
|
|
box-shadow: 4px 0 24px rgba(15, 23, 42, 0.08);
|
|
}
|
|
|
|
.rail-collapse-btn {
|
|
display: none !important;
|
|
}
|
|
|
|
.rail-nav {
|
|
padding: 12px;
|
|
}
|
|
|
|
.nav-btn {
|
|
min-height: 52px;
|
|
}
|
|
|
|
.nav-label {
|
|
font-size: 15px;
|
|
}
|
|
}
|
|
|
|
@media (prefers-reduced-motion: reduce) {
|
|
.rail *,
|
|
.rail *::before,
|
|
.rail *::after {
|
|
transition-duration: 120ms !important;
|
|
animation-duration: 120ms !important;
|
|
}
|
|
}
|