Login.vue 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. <script setup lang="ts">
  2. import {useUserStore} from '@/pinia'
  3. const thisYear = new Date().getFullYear()
  4. import {LockOutlined, UserOutlined} from '@ant-design/icons-vue'
  5. import {reactive, ref, watch} from 'vue'
  6. import {useRoute, useRouter} from 'vue-router'
  7. import gettext from '@/gettext'
  8. import {Form, message} from 'ant-design-vue'
  9. import auth from '@/api/auth'
  10. import install from '@/api/install'
  11. import SetLanguage from '@/components/SetLanguage/SetLanguage.vue'
  12. const route = useRoute()
  13. const router = useRouter()
  14. install.get_lock().then(async (r: { lock: boolean }) => {
  15. if (!r.lock) {
  16. await router.push('/install')
  17. }
  18. })
  19. const {$gettext} = gettext
  20. const loading = ref(false)
  21. const modelRef = reactive({
  22. username: '',
  23. password: ''
  24. })
  25. const rulesRef = reactive({
  26. username: [
  27. {
  28. required: true,
  29. message: () => $gettext('Please input your username!')
  30. }
  31. ],
  32. password: [
  33. {
  34. required: true,
  35. message: () => $gettext('Please input your password!')
  36. }
  37. ]
  38. })
  39. const {validate, validateInfos, clearValidate} = Form.useForm(modelRef, rulesRef)
  40. const onSubmit = () => {
  41. validate().then(async () => {
  42. loading.value = true
  43. await auth.login(modelRef.username, modelRef.password).then(async () => {
  44. message.success($gettext('Login successful'), 1)
  45. const next = (route.query?.next || '').toString() || '/'
  46. await router.push(next)
  47. }).catch(e => {
  48. message.error($gettext(e.message ?? 'Server error'))
  49. })
  50. loading.value = false
  51. })
  52. }
  53. const user = useUserStore()
  54. if (user.is_login) {
  55. const next = (route.query?.next || '').toString() || '/dashboard'
  56. router.push(next)
  57. }
  58. watch(() => gettext.current, () => {
  59. clearValidate()
  60. })
  61. </script>
  62. <template>
  63. <div class="container">
  64. <div class="login-form">
  65. <div class="project-title">
  66. <h1>Nginx UI</h1>
  67. </div>
  68. <a-form id="components-form-demo-normal-login">
  69. <a-form-item v-bind="validateInfos.username">
  70. <a-input
  71. v-model:value="modelRef.username"
  72. :placeholder="$gettext('Username')"
  73. >
  74. <template #prefix>
  75. <UserOutlined style="color: rgba(0, 0, 0, 0.25)"/>
  76. </template>
  77. </a-input>
  78. </a-form-item>
  79. <a-form-item v-bind="validateInfos.password">
  80. <a-input-password
  81. v-model:value="modelRef.password"
  82. :placeholder="$gettext('Password')"
  83. >
  84. <template #prefix>
  85. <LockOutlined style="color: rgba(0, 0, 0, 0.25)"/>
  86. </template>
  87. </a-input-password>
  88. </a-form-item>
  89. <a-form-item>
  90. <a-button @click="onSubmit" type="primary" :block="true" html-type="submit" :loading="loading">
  91. <translate>Login</translate>
  92. </a-button>
  93. </a-form-item>
  94. </a-form>
  95. <div class="footer">
  96. <p>Copyright © 2020 - {{ thisYear }} Nginx UI</p>
  97. Language
  98. <set-language class="set_lang" style="display: inline"/>
  99. </div>
  100. </div>
  101. </div>
  102. </template>
  103. <style lang="less">
  104. .container {
  105. display: flex;
  106. align-items: center;
  107. justify-content: center;
  108. height: 100%;
  109. .login-form {
  110. max-width: 400px;
  111. width: 80%;
  112. .project-title {
  113. margin: 50px;
  114. h1 {
  115. font-size: 50px;
  116. font-weight: 100;
  117. text-align: center;
  118. }
  119. }
  120. .anticon {
  121. color: #a8a5a5 !important;
  122. }
  123. .login-form-button {
  124. }
  125. .footer {
  126. padding: 30px;
  127. text-align: center;
  128. }
  129. }
  130. }
  131. </style>