Files
X-Financial/web/src/assets/styles/views/login-view.css
caoxiaozhu 96c2e1099a feat(web): 统一平台管理员判定与 AI 工作台申请预览动作接入
- authUser 抽出 resolveAuthUserAdminFlag,统一 isAdmin 解析(含 superadmin、role_codes、中英文角色名),accessControl 复用同一逻辑
- 登录态、应用外壳路由、系统状态接入统一管理员判定,LoginView 与相关 composable 配套调整
- AI 工作台申请提交改为调用新的 /application-preview-action 接口,草稿保存仍走 orchestrator;预审模型补充重叠冲突提示与阻断判断
- 同步更新 accessControl/api-request/ai 预览动作等前端测试
2026-06-20 14:42:04 +08:00

785 lines
14 KiB
CSS
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.
.login-page {
position: relative;
min-height: var(--desktop-stage-height, 100dvh);
display: grid;
grid-template-columns: minmax(620px, .96fr) minmax(520px, .84fr);
justify-content: center;
align-items: center;
gap: clamp(32px, 4.8vw, 76px);
padding: 48px clamp(40px, 5vw, 86px);
overflow: hidden;
background:
linear-gradient(120deg, rgba(var(--theme-primary-rgb, 58, 124, 165), .10), transparent 34%),
linear-gradient(105deg, #f8fafc 0%, #f5faff 44%, #f8fafc 100%);
}
.login-page::before {
content: "";
position: absolute;
inset: 0;
z-index: 0;
background:
linear-gradient(90deg, rgba(15,23,42,.045) 1px, transparent 1px),
linear-gradient(0deg, rgba(15,23,42,.04) 1px, transparent 1px),
radial-gradient(circle at 28% 72%, rgba(var(--theme-primary-rgb, 58, 124, 165), .10), transparent 28%),
radial-gradient(circle at 75% 22%, rgba(37,99,235,.06), transparent 30%);
background-size: 72px 72px, 72px 72px, auto, auto;
mask-image: linear-gradient(100deg, rgba(0,0,0,.7), rgba(0,0,0,.32) 48%, rgba(0,0,0,.16));
pointer-events: none;
}
.login-page::after {
content: "";
position: absolute;
left: -9vw;
top: 13vh;
z-index: 0;
width: min(820px, 58vw);
height: min(560px, 64vh);
border: 1px solid rgba(148,163,184,.22);
border-radius: 8px;
background:
linear-gradient(90deg, transparent 0 28%, rgba(15,23,42,.055) 28% calc(28% + 1px), transparent calc(28% + 1px)),
repeating-linear-gradient(0deg, transparent 0 35px, rgba(15,23,42,.05) 36px),
linear-gradient(135deg, rgba(255,255,255,.74), rgba(var(--theme-primary-rgb, 58, 124, 165), .10));
box-shadow: 0 34px 80px rgba(15,23,42,.08);
transform: rotate(-7deg);
pointer-events: none;
}
.page-brand {
position: absolute;
top: 38px;
left: clamp(42px, 6vw, 86px);
z-index: 2;
display: inline-flex;
align-items: center;
gap: 10px;
color: #111827;
font-size: 22px;
font-weight: 900;
}
:deep(.logo-mark) {
width: 34px;
height: 34px;
display: inline-grid;
place-items: center;
color: var(--theme-primary-active);
}
:deep(.logo-mark svg) {
width: 34px;
height: 34px;
fill: currentColor;
}
.hero {
position: relative;
z-index: 1;
align-self: stretch;
display: grid;
align-content: center;
justify-items: start;
padding-top: 40px;
transform: translateX(34px);
}
.eyebrow-text {
color: var(--theme-primary-active);
font-size: 14px;
font-weight: 900;
letter-spacing: .08em;
text-transform: uppercase;
}
.hero h1 {
margin-top: 16px;
color: #0f172a;
font-size: clamp(38px, 3.8vw, 54px);
line-height: 1.12;
font-weight: 950;
}
.hero-lead {
margin-top: 14px;
color: #111827;
font-size: clamp(23px, 2.15vw, 31px);
font-weight: 800;
}
.hero-sub {
margin-top: 14px;
color: #64748b;
font-size: 16px;
font-weight: 600;
}
.hero-stage {
position: relative;
width: min(760px, 100%);
height: 350px;
margin-top: 22px;
margin-left: 0;
}
.hero-stage::before {
content: "";
position: absolute;
left: 285px;
bottom: 38px;
width: 230px;
height: 62px;
border-radius: 50%;
background: linear-gradient(90deg, rgba(var(--theme-primary-rgb, 58, 124, 165), .14), rgba(37,99,235,.08));
filter: blur(4px);
}
.flow-line {
position: absolute;
z-index: 0;
display: block;
border: 1px solid rgba(var(--theme-primary-rgb, 58, 124, 165), .22);
border-left: 0;
border-bottom: 0;
border-radius: 0 8px 0 0;
}
.flow-line::after {
content: "";
position: absolute;
right: -3px;
top: -4px;
width: 8px;
height: 8px;
border-radius: 999px;
background: var(--theme-primary);
box-shadow: 0 0 0 5px rgba(var(--theme-primary-rgb, 58, 124, 165), .12);
}
.flow-a {
left: 190px;
top: 76px;
width: 170px;
height: 72px;
}
.flow-b {
left: 190px;
bottom: 96px;
width: 142px;
height: 82px;
transform: scaleY(-1);
}
.flow-c {
right: 182px;
top: 96px;
width: 132px;
height: 70px;
transform: scaleX(-1);
}
.metric-card,
.document-card,
.round-badge {
position: absolute;
border: 1px solid rgba(215, 224, 234, .86);
background: rgba(255,255,255,.78);
box-shadow: 0 18px 36px rgba(65, 88, 110, .10);
backdrop-filter: blur(16px);
}
.metric-card {
z-index: 2;
width: 166px;
min-height: 110px;
display: grid;
gap: 7px;
padding: 17px 18px;
border-radius: 8px;
}
.metric-card span {
color: #334155;
font-size: 13px;
font-weight: 800;
}
.metric-card strong {
color: #0f172a;
font-size: 25px;
line-height: 1;
font-weight: 900;
}
.metric-card small {
color: #64748b;
font-size: 12px;
font-weight: 700;
}
.up { color: var(--success); }
.danger { color: #ef4444; }
.amount { left: 20px; top: 20px; }
.risk { left: 42px; bottom: 24px; }
.audit { right: 22px; top: 24px; }
.sla { right: 40px; bottom: 20px; }
.mini-bars {
height: 30px;
display: flex;
align-items: end;
gap: 6px;
margin-top: 2px;
}
.mini-bars i {
width: 14px;
border-radius: 4px 4px 0 0;
background: linear-gradient(180deg, #93c5fd, #dbeafe);
}
.mini-bars i:nth-child(1) { height: 11px; }
.mini-bars i:nth-child(2) { height: 18px; }
.mini-bars i:nth-child(3) { height: 24px; }
.mini-bars i:nth-child(4) { height: 32px; }
.document-card {
z-index: 1;
left: 286px;
top: 44px;
width: 220px;
height: 214px;
padding: 28px 28px;
border-radius: 8px;
transform: rotate(2deg);
}
.document-card span {
color: #1e293b;
font-size: 18px;
font-weight: 900;
}
.document-card > i {
display: block;
height: 10px;
margin-top: 22px;
border-radius: 999px;
background: #e4ebf5;
}
.document-card > i:nth-of-type(2) { width: 78%; margin-top: 16px; }
.document-card > i:nth-of-type(3) { width: 54%; margin-top: 16px; }
.doc-check {
position: absolute;
right: -16px;
bottom: -12px;
width: 54px;
height: 54px;
display: grid;
place-items: center;
border-radius: 999px;
background: linear-gradient(135deg, var(--theme-primary), var(--theme-primary-active));
color: #fff;
font-size: 27px;
box-shadow: 0 14px 28px rgba(var(--theme-primary-rgb, 58, 124, 165), .22);
}
.shield-art {
position: absolute;
z-index: 3;
left: 316px;
bottom: 0;
width: 155px;
height: 155px;
object-fit: contain;
filter: drop-shadow(0 22px 24px rgba(125, 91, 54, .16));
}
.round-badge {
z-index: 4;
width: 58px;
height: 58px;
display: grid;
place-items: center;
border-radius: 999px;
color: #3b82f6;
font-size: 24px;
font-weight: 950;
}
.round-badge.ai {
left: 258px;
top: 30px;
width: 52px;
height: 52px;
color: #3b82f6;
font-size: 21px;
box-shadow: 0 14px 30px rgba(59,130,246,.14);
}
.feature-strip {
width: min(760px, 100%);
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 18px;
margin-top: 18px;
margin-left: 0;
}
.feature-strip article {
min-height: 78px;
display: grid;
grid-template-columns: 42px minmax(0, 1fr);
align-items: center;
gap: 12px;
padding: 12px 14px;
border: 1px solid rgba(215, 224, 234, .82);
border-radius: 6px;
background: rgba(255,255,255,.76);
box-shadow: 0 12px 30px rgba(65, 88, 110, .08);
backdrop-filter: blur(16px);
}
.feature-strip article > span {
width: 40px;
height: 40px;
display: grid;
place-items: center;
border-radius: 11px;
font-size: 21px;
}
.feature-strip .primary { background: var(--theme-primary-soft); color: var(--theme-primary-active); }
.feature-strip .red { background: #fee2e2; color: #ef4444; }
.feature-strip .blue { background: #dbeafe; color: #3b82f6; }
.feature-strip strong {
color: #0f172a;
font-size: 15px;
font-weight: 900;
}
.feature-strip p {
display: block;
margin-top: 3px;
color: #64748b;
font-size: 11.5px;
line-height: 1.45;
}
.login-card {
position: relative;
z-index: 1;
width: 100%;
max-width: 560px;
justify-self: center;
display: grid;
padding: 58px 60px 44px;
border: 1px solid rgba(215, 224, 234, .96);
border-radius: 8px;
background: rgba(255,255,255,.86);
box-shadow: 0 24px 64px rgba(65, 88, 110, .16);
backdrop-filter: blur(18px);
}
.card-brand {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 12px;
color: #0f172a;
font-size: 22px;
font-weight: 950;
}
.card-head {
margin-top: 24px;
text-align: center;
}
.card-head h2 {
color: #0f172a;
font-size: 34px;
line-height: 1.15;
font-weight: 950;
}
.card-head p {
margin-top: 12px;
color: #64748b;
font-size: 16px;
}
.login-form {
display: grid;
gap: 16px;
margin-top: 30px;
}
.field {
position: relative;
display: flex;
align-items: center;
min-height: 52px;
}
.field > .mdi {
position: absolute;
left: 16px;
color: #64748b;
font-size: 19px;
}
.field input,
.field select {
width: 100%;
height: 52px;
padding: 0 50px 0 48px;
border: 1px solid #d7e0ea;
border-radius: 8px;
background: rgba(255,255,255,.86);
color: #0f172a;
font-size: 15px;
transition: border-color 160ms ease, box-shadow 160ms ease, background 160ms ease;
}
.field select {
appearance: none;
cursor: pointer;
}
.field input::placeholder {
color: #94a3b8;
}
.field input:focus,
.field select:focus {
border-color: var(--theme-primary);
background: #fff;
box-shadow: 0 0 0 3px var(--theme-focus-ring, rgba(58, 124, 165, .14));
outline: none;
}
.field-select-chevron {
position: absolute;
right: 12px;
width: 34px;
height: 34px;
display: grid;
place-items: center;
border-radius: 8px;
color: #64748b;
pointer-events: none;
}
.field-icon-btn {
position: absolute;
right: 12px;
width: 34px;
height: 34px;
display: grid;
place-items: center;
border: 0;
border-radius: 8px;
background: transparent;
color: #64748b;
}
.field-icon-btn:hover {
background: #f1f5f9;
color: var(--theme-primary-active);
}
.form-meta {
display: flex;
align-items: center;
justify-content: space-between;
gap: 16px;
margin-top: 2px;
}
.login-error {
padding: 12px 14px;
border: 1px solid rgba(239, 68, 68, .18);
border-radius: 8px;
background: #fef2f2;
color: #b91c1c;
font-size: 13px;
line-height: 1.55;
}
.remember {
display: inline-flex;
align-items: center;
gap: 8px;
color: #334155;
font-size: 14px;
}
.remember input {
width: 16px;
height: 16px;
accent-color: var(--theme-primary);
}
.link-btn {
border: 0;
background: transparent;
color: #2563eb;
font-size: 14px;
font-weight: 700;
}
.submit-btn,
.sso-btn {
height: 52px;
display: inline-flex;
align-items: center;
justify-content: center;
gap: 10px;
border-radius: 8px;
font-size: 17px;
font-weight: 900;
}
.submit-btn {
margin-top: 4px;
border: 0;
background: linear-gradient(135deg, var(--theme-primary), var(--theme-primary-active));
color: #fff;
box-shadow: 0 16px 30px rgba(var(--theme-primary-rgb, 58, 124, 165), .20);
}
.submit-btn:hover {
background: linear-gradient(135deg, var(--theme-primary-hover), var(--theme-primary-active));
}
.submit-btn:disabled,
.sso-btn:disabled {
cursor: not-allowed;
}
/* 登录中SSO 按钮置灰,登录按钮保持主色并显示 spinner */
.sso-btn:disabled {
opacity: .6;
box-shadow: none;
}
.submit-btn:disabled {
opacity: 1;
box-shadow: 0 16px 30px rgba(var(--theme-primary-rgb, 58, 124, 165), .20);
}
/*
* 登录中表单态:用户名 / 密码 / 租户 / 记住账号 / 忘记密码全部置灰禁用,
* 让视觉焦点集中在正在校验的登录按钮上
*/
.login-form.is-submitting .field input,
.login-form.is-submitting .field select {
background: #f1f5f9;
border-color: #e2e8f0;
color: #94a3b8;
cursor: not-allowed;
}
.login-form.is-submitting .field input::placeholder {
color: #cbd5e1;
}
.login-form.is-submitting .field > .mdi,
.login-form.is-submitting .field-icon-btn,
.login-form.is-submitting .field-select-chevron {
color: #cbd5e1;
opacity: .5;
pointer-events: none;
}
.login-form.is-submitting .remember,
.login-form.is-submitting .link-btn {
opacity: .55;
pointer-events: none;
}
/* 登录按钮内的旋转 loading */
.submit-btn__spinner {
width: 20px;
height: 20px;
border: 2.5px solid rgba(255, 255, 255, .4);
border-top-color: #fff;
border-radius: 999px;
animation: loginSubmitSpin 720ms linear infinite;
}
@keyframes loginSubmitSpin {
to {
transform: rotate(360deg);
}
}
@media (prefers-reduced-motion: reduce) {
.submit-btn__spinner {
animation-duration: 1800ms;
}
}
.divider {
position: relative;
display: grid;
place-items: center;
height: 28px;
color: #94a3b8;
font-size: 13px;
}
.divider::before {
content: "";
position: absolute;
left: 0;
right: 0;
top: 50%;
height: 1px;
background: #e2e8f0;
}
.divider span {
position: relative;
padding: 0 16px;
background: rgba(255,255,255,.9);
}
.sso-btn {
border: 1px solid var(--theme-primary);
background: rgba(255,255,255,.78);
color: var(--theme-primary-active);
}
.sso-btn:hover {
background: var(--theme-primary-soft);
}
.security-note {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 8px;
margin-top: 34px;
color: #64748b;
font-size: 13px;
}
.security-note .mdi {
color: #94a3b8;
}
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
@media (max-width: 1280px) {
.login-page {
grid-template-columns: minmax(520px, 1fr) minmax(480px, 540px);
gap: 44px;
padding-inline: 48px;
}
.hero-stage {
transform: scale(.88);
transform-origin: left center;
margin-bottom: -32px;
}
.feature-strip {
width: 520px;
gap: 14px;
margin-left: 0;
}
.login-card { max-width: 500px; }
}
@media (max-height: 840px) and (min-width: 981px) {
.hero {
padding-top: 18px;
}
.hero-stage {
margin-top: 16px;
transform: scale(.9);
transform-origin: left center;
margin-bottom: -22px;
}
.login-card {
padding-block: 38px 28px;
}
.card-head {
margin-top: 18px;
}
.login-form {
gap: 14px;
margin-top: 24px;
}
.security-note {
margin-top: 24px;
}
}
@media (max-width: 980px) {
.login-page {
min-height: var(--desktop-stage-height, 100dvh);
grid-template-columns: 1fr;
padding: 92px 28px 28px;
overflow: auto;
}
.page-brand {
top: 24px;
left: 24px;
}
.hero {
display: none;
transform: none;
}
.login-card {
max-width: 520px;
padding: 40px 28px 30px;
}
}
@media (max-width: 520px) {
.login-page {
padding-inline: 22px;
}
.login-card {
padding: 32px 22px 24px;
border-radius: 8px;
}
.card-head h2 {
font-size: 30px;
}
.form-meta {
align-items: flex-start;
flex-direction: column;
gap: 10px;
}
}