feat(auth): 重构登录页视觉并移除修改密码入口
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 93 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 65 KiB |
@@ -1,8 +1,9 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, onMounted, ref } from 'vue'
|
||||
import { onMounted, ref } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
|
||||
import { getAuthErrorMessage, getCaptcha } from '@/api/auth'
|
||||
import hospitalLogo from '@/assets/hospital-logo.png'
|
||||
import type { CaptchaResponse, LoginRequest } from '@/types/auth'
|
||||
import { useLoginStore } from '@/stores/login'
|
||||
|
||||
@@ -18,7 +19,6 @@ const captchaLoading = ref(false)
|
||||
const errorMessage = ref('')
|
||||
const isSubmitting = ref(false)
|
||||
const passwordChanged = route.query.passwordChanged === '1'
|
||||
const passwordChangeRequested = computed(() => route.query.redirect === '/change-password')
|
||||
|
||||
async function loadCaptcha() {
|
||||
captchaLoading.value = true
|
||||
@@ -42,13 +42,6 @@ function getRedirectPath() {
|
||||
: '/workbench/home'
|
||||
}
|
||||
|
||||
function requestPasswordChange() {
|
||||
void router.replace({
|
||||
name: 'login',
|
||||
query: { ...route.query, redirect: '/change-password' },
|
||||
})
|
||||
}
|
||||
|
||||
async function handleLogin() {
|
||||
const normalizedUsername = username.value.trim()
|
||||
|
||||
@@ -103,33 +96,42 @@ onMounted(() => {
|
||||
|
||||
<template>
|
||||
<main class="login-page">
|
||||
<div class="login-visual" aria-hidden="true"></div>
|
||||
<div class="login-shade" aria-hidden="true"></div>
|
||||
|
||||
<div class="login-caption">
|
||||
<span class="login-badge">
|
||||
<img :src="hospitalLogo" alt="新华医院" />
|
||||
</span>
|
||||
<div class="login-caption-text">
|
||||
<b>上海交通大学医学院附属新华医院</b>
|
||||
<span>Xinhua Hospital Affiliated To Shanghai Jiao Tong University School Of Medicine</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form class="login-card" novalidate @submit.prevent="handleLogin">
|
||||
<div class="login-brand">
|
||||
<div class="login-brand-icon" aria-hidden="true">
|
||||
<svg width="26" height="26" viewBox="0 0 24 24" fill="none">
|
||||
<path
|
||||
d="M14 3v5h5M14 3H7a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V8l-5-5z"
|
||||
stroke="#fff"
|
||||
stroke-width="1.7"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="m9 13.5 2.5 2.5 4-4.5"
|
||||
d="M5.6 2.6v4.2M3.5 4.7h4.2"
|
||||
stroke="#fff"
|
||||
stroke-width="1.7"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path d="M9.7 16.3l1.1-3.1 6.3-6.3a1.41 1.41 0 0 1 2 2l-6.3 6.3-3.1 1.1z" fill="#fff" />
|
||||
<path d="M15.5 8.5l2 2" stroke="#9bd8e9" stroke-width="1.2" stroke-linecap="round" />
|
||||
<path
|
||||
d="M2.8 21.2c1.7 0 1.7-1.3 3.4-1.3s1.7 1.3 3.4 1.3 1.7-1.3 3.4-1.3 1.7 1.3 3.4 1.3 1.7-1.3 3.4-1.3"
|
||||
stroke="#fff"
|
||||
stroke-width="1.6"
|
||||
stroke-linecap="round"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div>
|
||||
<h1>医签通</h1>
|
||||
<p>MEDISIGN · 患者电子签系统</p>
|
||||
</div>
|
||||
<h1>医签通</h1>
|
||||
</div>
|
||||
|
||||
<p class="login-subtitle">安全留痕 · 高效签署 · 医患无忧</p>
|
||||
|
||||
<p v-if="passwordChanged" class="login-success" role="status">
|
||||
密码修改成功,请使用新密码重新登录
|
||||
</p>
|
||||
@@ -176,11 +178,7 @@ onMounted(() => {
|
||||
@click="loadCaptcha"
|
||||
>
|
||||
<span v-if="captchaLoading" class="captcha-spinner" aria-hidden="true" />
|
||||
<img
|
||||
v-else-if="captcha"
|
||||
:src="captcha.imageBase64"
|
||||
alt="图形验证码,点击刷新"
|
||||
/>
|
||||
<img v-else-if="captcha" :src="captcha.imageBase64" alt="图形验证码,点击刷新" />
|
||||
<span v-else class="captcha-retry">点击重试</span>
|
||||
</button>
|
||||
</div>
|
||||
@@ -191,15 +189,9 @@ onMounted(() => {
|
||||
<button class="login-submit" type="submit" :disabled="isSubmitting">
|
||||
{{ isSubmitting ? '登录中…' : '登 录' }}
|
||||
</button>
|
||||
<p v-if="passwordChangeRequested" class="login-change-hint" role="status">
|
||||
登录后将进入修改密码页面
|
||||
</p>
|
||||
<button class="login-change-link" type="button" @click="requestPasswordChange">
|
||||
修改密码
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<p class="login-footer">© 2026 医签通 MEDISIGN · 患者电子签署系统 V1.1 原型</p>
|
||||
<p class="login-footer">© 2026 上海交通大学医学院附属新华医院 · 医签通 MEDISIGN V1.1</p>
|
||||
</main>
|
||||
</template>
|
||||
|
||||
@@ -210,15 +202,84 @@ onMounted(() => {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: var(--login-gradient);
|
||||
background: #0e6e8c;
|
||||
}
|
||||
|
||||
.login-visual {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: url('@/assets/login-bg.jpg') center / cover no-repeat;
|
||||
}
|
||||
|
||||
.login-shade {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: linear-gradient(
|
||||
180deg,
|
||||
rgb(6 40 54 / 38%) 0%,
|
||||
rgb(6 40 54 / 0%) 28%,
|
||||
rgb(6 40 54 / 0%) 55%,
|
||||
rgb(6 40 54 / 52%) 100%
|
||||
);
|
||||
}
|
||||
|
||||
.login-caption {
|
||||
position: absolute;
|
||||
top: 28px;
|
||||
left: 34px;
|
||||
z-index: 2;
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
align-items: center;
|
||||
color: #fff;
|
||||
text-shadow: 0 2px 12px rgb(0 0 0 / 50%);
|
||||
}
|
||||
|
||||
.login-badge {
|
||||
display: flex;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
flex: none;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 3px;
|
||||
background: rgb(255 255 255 / 95%);
|
||||
border-radius: 50%;
|
||||
box-shadow: 0 4px 16px rgb(6 40 54 / 40%);
|
||||
}
|
||||
|
||||
.login-badge img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.login-caption-text b {
|
||||
display: block;
|
||||
font-size: 19px;
|
||||
font-weight: 700;
|
||||
letter-spacing: 1.5px;
|
||||
}
|
||||
|
||||
.login-caption-text span {
|
||||
display: block;
|
||||
margin-top: 5px;
|
||||
font-size: 10.5px;
|
||||
letter-spacing: 0.4px;
|
||||
opacity: 0.85;
|
||||
}
|
||||
|
||||
.login-card {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
width: 380px;
|
||||
padding: 30px 36px;
|
||||
padding: 34px 34px 30px;
|
||||
background: #fff;
|
||||
border-radius: 14px;
|
||||
box-shadow: var(--sh-login);
|
||||
box-shadow:
|
||||
0 24px 64px rgb(6 40 54 / 38%),
|
||||
0 4px 16px rgb(6 40 54 / 22%);
|
||||
}
|
||||
|
||||
.login-brand {
|
||||
@@ -226,13 +287,14 @@ onMounted(() => {
|
||||
gap: 12px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 8px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.login-brand-icon {
|
||||
display: grid;
|
||||
width: 46px;
|
||||
height: 46px;
|
||||
flex: none;
|
||||
place-items: center;
|
||||
border-radius: 12px;
|
||||
background: linear-gradient(135deg, var(--brand), #18a0c0);
|
||||
@@ -245,22 +307,8 @@ onMounted(() => {
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
.login-brand p {
|
||||
margin: 2px 0 0;
|
||||
color: #8aa7b3;
|
||||
font-size: 11px;
|
||||
letter-spacing: 2px;
|
||||
}
|
||||
|
||||
.login-subtitle {
|
||||
margin: 0 0 20px;
|
||||
color: var(--mut);
|
||||
font-size: 12px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.login-field {
|
||||
margin-bottom: 10px;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
|
||||
.login-field label {
|
||||
@@ -314,7 +362,6 @@ onMounted(() => {
|
||||
|
||||
.captcha-image-button:disabled {
|
||||
cursor: wait;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.captcha-image-button img {
|
||||
@@ -342,8 +389,8 @@ onMounted(() => {
|
||||
|
||||
.login-submit {
|
||||
width: 100%;
|
||||
margin-top: 6px;
|
||||
padding: 9px;
|
||||
margin-top: 10px;
|
||||
padding: 10px;
|
||||
color: #fff;
|
||||
font-size: 13px;
|
||||
font-weight: 700;
|
||||
@@ -380,41 +427,38 @@ onMounted(() => {
|
||||
}
|
||||
}
|
||||
|
||||
.login-change-hint {
|
||||
margin: 8px 0 0;
|
||||
color: var(--brand);
|
||||
font-size: 12px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.login-change-link {
|
||||
display: block;
|
||||
padding: 7px 12px;
|
||||
margin: 5px auto 0;
|
||||
color: var(--brand);
|
||||
font-size: 12px;
|
||||
background: transparent;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.login-change-link:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.login-footer {
|
||||
position: absolute;
|
||||
bottom: 18px;
|
||||
bottom: 16px;
|
||||
z-index: 2;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
color: rgb(255 255 255 / 55%);
|
||||
font-size: 12px;
|
||||
color: rgb(255 255 255 / 82%);
|
||||
font-size: 11.5px;
|
||||
text-align: center;
|
||||
text-shadow: 0 1px 6px rgb(0 0 0 / 45%);
|
||||
}
|
||||
|
||||
@media (max-width: 820px) {
|
||||
.login-caption-text span {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 520px) {
|
||||
.login-caption {
|
||||
top: 18px;
|
||||
left: 18px;
|
||||
}
|
||||
|
||||
.login-caption-text b {
|
||||
font-size: 16px;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
.login-card {
|
||||
width: calc(100% - 32px);
|
||||
padding: 32px 24px;
|
||||
padding: 28px 22px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user