Explorar el Código

feat(frontend): LoginView 改全屏左右分栏 + 下划线式输入框

- 布局从居中两栏改为全屏撑满(左深色品牌区 1.2fr + 右白表单)
- 左侧深色品牌区:功能直述文案替代营销口号
- 输入框从填充式改下划线式(underline-input 全局类)
- 按钮 radius 收窄到 4px,letter-spacing 加宽
- 底部辅助文案改大写小字
- 小屏隐藏左侧品牌区
wangkangyjy hace 3 semanas
padre
commit
4b1ba26255
Se han modificado 1 ficheros con 91 adiciones y 111 borrados
  1. 91 111
      frontend/src/views/auth/LoginView.vue

+ 91 - 111
frontend/src/views/auth/LoginView.vue

@@ -1,15 +1,16 @@
 <template>
   <div class="internal-login">
-    <section class="internal-login__brand">
-      <div class="internal-login__brand-main">
-        <img src="/logo.png" class="internal-login__logo" alt="医梦AI" />
-        <div>
-          <h1>OKR 绩效管理系统</h1>
-          <p>医梦AI 内部绩效运营工作台</p>
-          <svg class="medical-pulse" viewBox="0 0 220 24" aria-hidden="true" focusable="false">
-            <path d="M2 12h72l8-8 10 16 12-16 8 8h106" />
-          </svg>
-        </div>
+    <!-- 左:深色品牌区 -->
+    <section class="login-brand">
+      <div class="login-brand__top">
+        <img src="/logo.png" class="login-brand__logo" alt="医梦AI" />
+      </div>
+      <div class="login-brand__main">
+        <h1>绩效运营工作台</h1>
+        <p>目标对齐 · 进度可追溯<br>结果可解释 · 医疗级数据严谨</p>
+        <svg class="medical-pulse" viewBox="0 0 220 24" aria-hidden="true" focusable="false">
+          <path d="M2 12h72l8-8 10 16 12-16 8 8h106" />
+        </svg>
       </div>
       <svg class="molecule-mark" viewBox="0 0 180 150" aria-hidden="true" focusable="false">
         <path d="M48 44 92 28 134 58 116 112 62 112 48 44Z" />
@@ -21,41 +22,42 @@
       </svg>
     </section>
 
-    <section class="internal-login__panel med-panel">
+    <!-- 右:白表单区 -->
+    <section class="internal-login__panel">
       <div class="login-panel__header">
         <span class="login-panel__eyebrow">Internal Access</span>
         <h2>账号登录</h2>
       </div>
       <el-form :model="form" :rules="rules" ref="formRef" @submit.prevent="handleSubmit" class="login-form">
         <el-form-item prop="username">
+          <label class="field-label">用户名</label>
           <el-input
             v-model="form.username"
-            placeholder="用户名"
-            size="large"
-            class="custom-input"
+            placeholder="请输入用户名"
+            class="underline-input"
           />
         </el-form-item>
         <el-form-item prop="password">
+          <label class="field-label">密码</label>
           <el-input
             v-model="form.password"
             type="password"
-            placeholder="密码"
-            size="large"
             show-password
-            class="custom-input"
+            placeholder="请输入密码"
+            class="underline-input"
+            @keyup.enter="handleSubmit"
           />
         </el-form-item>
         <el-button
           class="login-btn"
-          size="large"
           native-type="submit"
           :loading="loading"
         >
-          登录
+          登 
         </el-button>
       </el-form>
       <div class="login-panel__footer">
-        <span class="login-help">账号由 HR 管理员创建,如需开通请联系组织管理员</span>
+        <span class="login-help uppercase-label">账号由 HR 管理员创建</span>
       </div>
     </section>
   </div>
@@ -92,61 +94,58 @@ async function handleSubmit() {
 
 <style scoped>
 .internal-login {
-  min-height: 100vh;
   display: grid;
-  grid-template-columns: minmax(320px, 460px) 420px;
-  align-items: center;
-  justify-content: center;
-  gap: 56px;
-  padding: 40px;
-  background: var(--color-bg);
+  grid-template-columns: 1.2fr 1fr;
+  min-height: 100vh;
+  width: 100%;
+  background: var(--color-surface);
 }
 
-.internal-login__brand {
+/* 左侧深色品牌区 */
+.login-brand {
   position: relative;
+  overflow: hidden;
+  background: linear-gradient(135deg, var(--color-login-brand-from), var(--color-login-brand-to));
+  padding: 28px 32px;
+  color: rgba(255, 255, 255, 1);
   display: flex;
-  align-items: flex-start;
+  flex-direction: column;
   justify-content: space-between;
-  gap: 20px;
-  min-height: 180px;
 }
-
-.internal-login__brand-main {
-  display: flex;
-  align-items: flex-start;
-  gap: 20px;
+.login-brand__top {
   position: relative;
   z-index: 1;
 }
-
-.internal-login__logo {
-  width: 120px;
-  height: 64px;
+.login-brand__logo {
+  width: 56px;
+  height: 30px;
   object-fit: contain;
-  flex-shrink: 0;
 }
-
-.internal-login__brand h1 {
-  margin: 8px 0 8px;
-  color: var(--color-text);
-  font-size: var(--font-size-3xl);
-  line-height: 1.2;
-  letter-spacing: 0;
+.login-brand__main {
+  position: relative;
+  z-index: 1;
 }
-
-.internal-login__brand p {
+.login-brand__main h1 {
   margin: 0;
-  color: var(--color-text-secondary);
-  font-size: var(--font-size-base);
+  font-size: 18px;
+  font-weight: 600;
+  color: rgba(255, 255, 255, 1);
+  letter-spacing: 0;
+}
+.login-brand__main p {
+  margin: 6px 0 0;
+  color: rgba(255, 255, 255, 0.55);
+  font-size: 11px;
+  line-height: 1.7;
 }
 
 .medical-pulse {
   display: block;
-  width: 220px;
-  height: 24px;
-  margin-top: 18px;
+  width: 100px;
+  height: 12px;
+  margin-top: 12px;
   color: var(--color-accent);
-  opacity: 0.65;
+  opacity: 0.6;
 }
 
 .medical-pulse path,
@@ -160,93 +159,74 @@ async function handleSubmit() {
 }
 
 .molecule-mark {
-  width: 180px;
-  height: 150px;
-  color: var(--color-brand);
-  opacity: 0.14;
-  flex-shrink: 0;
+  position: absolute;
+  right: -10px;
+  bottom: -10px;
+  width: 140px;
+  height: 120px;
+  color: var(--color-accent);
+  opacity: 0.08;
 }
 
+/* 右侧白表单区 */
 .internal-login__panel {
-  padding: 28px;
+  padding: 32px 40px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  max-width: 420px;
+  margin: 0 auto;
+  width: 100%;
 }
 
 .login-panel__header {
-  margin-bottom: 22px;
+  margin-bottom: 24px;
 }
-
 .login-panel__eyebrow {
   display: block;
   margin-bottom: 6px;
-  color: var(--color-accent-strong);
-  font-size: var(--font-size-xs);
+  color: var(--color-text-muted);
+  font-size: 8px;
   font-weight: 700;
-  letter-spacing: 1px;
+  letter-spacing: 1.5px;
   text-transform: uppercase;
 }
-
 .login-panel__header h2 {
   margin: 0;
   color: var(--color-text);
-  font-size: var(--font-size-xl);
+  font-size: 14px;
   font-weight: 500;
+  letter-spacing: 0.3px;
 }
 
-.login-form {
-  padding: 0;
-}
-
-.custom-input :deep(.el-input__wrapper) {
-  background: var(--color-surface-subtle);
-  border: 1px solid var(--color-border-soft);
-  box-shadow: none;
-}
-.custom-input :deep(.el-input__wrapper:hover) {
-  border-color: var(--color-accent);
-}
-.custom-input :deep(.el-input__wrapper.is-focus) {
-  border-color: var(--color-accent);
-  box-shadow: 0 0 0 1px var(--color-accent-focus);
-}
-.custom-input :deep(.el-input__inner) {
-  color: var(--color-text);
-}
-.custom-input :deep(.el-input__inner::placeholder) {
+.login-form { padding: 0; }
+.field-label {
+  display: block;
+  margin-bottom: 4px;
   color: var(--color-text-muted);
+  font-size: 8px;
+  font-weight: 700;
+  letter-spacing: 1px;
+  text-transform: uppercase;
 }
+
 .login-btn {
   width: 100%;
-  height: 44px;
-  background: var(--color-brand);
-  border: none;
-  color: var(--color-white);
-  font-size: var(--font-size-base);
+  border-radius: 4px;
+  letter-spacing: 0.5px;
   font-weight: 500;
-  letter-spacing: 0;
-  margin-top: 4px;
-}
-.login-btn:hover {
-  background: var(--color-brand-strong);
 }
 .login-panel__footer {
   text-align: center;
-  padding-top: 14px;
-}
-.login-help {
-  color: var(--color-text-muted);
-  font-size: var(--font-size-sm);
-  letter-spacing: 0;
+  padding-top: 16px;
 }
 
-@media (max-width: 900px) {
+@media (max-width: 768px) {
   .internal-login {
     grid-template-columns: 1fr;
-    gap: 24px;
-    padding: 24px;
   }
-
-  .internal-login__brand {
-    align-items: center;
+  .login-brand {
+    display: none;
   }
 }
 </style>