Login.vue 4.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. <script setup lang="ts">
  2. import { reactive, ref } from 'vue'
  3. import { useRouter } from 'vue-router'
  4. import { ElMessage } from 'element-plus'
  5. import { setAuthInfo } from '../utils/auth'
  6. const router = useRouter()
  7. const form = reactive({ username: 'admin', password: 'admin123' })
  8. const busy = ref(false)
  9. const showPassword = ref(false)
  10. async function submit() {
  11. if (busy.value) return
  12. busy.value = true
  13. try {
  14. // 跳过登录验证,直接写入模拟令牌进入系统
  15. await setAuthInfo({ accessToken: 'mock-token-' + Date.now(), displayName: form.username || '管理员' })
  16. ElMessage.success('登录成功')
  17. await router.replace('/dashboard')
  18. } finally {
  19. busy.value = false
  20. }
  21. }
  22. </script>
  23. <template>
  24. <div class="mock-login">
  25. <section class="login-panel" aria-labelledby="login-title">
  26. <div class="brand login-brand"><span class="brand-mark">H</span>
  27. <div class="brand-text">
  28. <strong>HS 仓储运营台</strong>
  29. <small>WAREHOUSE OPS · 上海闵行仓</small>
  30. </div>
  31. </div>
  32. <h1 id="login-title">登录系统</h1>
  33. <p class="login-desc">使用内部账号进入仓储基础 ERP,登录后所有操作将自动记录操作人。</p>
  34. <form class="login-form" @submit.prevent="submit">
  35. <div class="form-field">
  36. <label class="field-label">用户名</label>
  37. <input v-model="form.username" class="field-input" placeholder="请输入用户名" autocomplete="username" />
  38. </div>
  39. <div class="form-field">
  40. <label class="field-label">密码</label>
  41. <input v-model="form.password" :type="showPassword ? 'text' : 'password'" class="field-input" placeholder="请输入密码" autocomplete="current-password" />
  42. <button type="button" class="toggle-password" @click="showPassword = !showPassword" :aria-label="showPassword ? '隐藏密码' : '显示密码'">
  43. <svg v-if="showPassword" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg>
  44. <svg v-else viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24"/><line x1="1" y1="1" x2="23" y2="23"/></svg>
  45. </button>
  46. </div>
  47. <el-button type="primary" class="login-submit" :loading="busy" native-type="submit">继 续</el-button>
  48. </form>
  49. <footer>仅限内部操作 · 登录后进入上海闵行仓工作台</footer>
  50. </section>
  51. </div>
  52. </template>
  53. <style scoped>
  54. .mock-login { min-height: 100vh; display: flex; align-items: center; justify-content: center; background: linear-gradient(135deg, #f0f7ff 0%, #e8f4f8 100%); padding: 24px; }
  55. .login-panel { width: 100%; max-width: 480px; background: #fff; border-radius: 24px; padding: 48px 40px 36px; box-shadow: 0 8px 40px rgba(0, 0, 0, 0.06); }
  56. .login-brand { display: flex; align-items: center; gap: 14px; margin-bottom: 32px; }
  57. .brand-mark { width: 52px; height: 52px; border-radius: 14px; background: #3b82f6; color: #fff; display: flex; align-items: center; justify-content: center; font-weight: 700; font-size: 26px; }
  58. .brand-text { display: flex; flex-direction: column; gap: 4px; }
  59. .brand-text strong { font-size: 18px; font-weight: 600; color: #111827; }
  60. .brand-text small { font-size: 11px; color: #6b7280; letter-spacing: 0.3px; }
  61. .login-panel h1 { font-size: 25px; font-weight: 700; margin: 0 0 12px; color: #111827; }
  62. .login-desc { font-size: 13px; color: #6b7280; line-height: 1.7; margin: 0 0 32px; }
  63. .login-form { display: flex; flex-direction: column; gap: 20px; }
  64. .form-field { position: relative; display: flex; align-items: center; border: 1px solid #dbeafe; border-radius: 20px; padding: 0 24px; height: 64px; background: #fff; transition: border-color 0.2s; }
  65. .form-field:focus-within { border-color: #3b82f6; }
  66. .field-label { flex-shrink: 0; width: 100px; font-size: 13px; color: #6b7280; font-weight: 500; }
  67. .field-input { flex: 1; border: none; outline: none; font-size: 14px; color: #111827; background: transparent; }
  68. .field-input::placeholder { color: #9ca3af; }
  69. .toggle-password { position: absolute; right: 24px; top: 50%; transform: translateY(-50%); background: none; border: none; cursor: pointer; color: #9ca3af; padding: 4px; display: flex; align-items: center; justify-content: center; }
  70. .toggle-password:hover { color: #6b7280; }
  71. .toggle-password svg { width: 22px; height: 22px; }
  72. .login-submit { width: 100%; height: 56px; font-size: 18px; font-weight: 600; border-radius: 14px; margin-top: 12px; background: #3b82f6; border: none; }
  73. .login-submit:hover { background: #2563eb; }
  74. .login-panel footer { margin-top: 28px; text-align: center; font-size: 11px; color: #9ca3af; }
  75. </style>