| | |
| | | <div class="form"> |
| | | <h3 class="title">{{ $t('login.title') }}</h3> |
| | | <p class="sub-title">{{ $t('login.subTitle') }}</p> |
| | | <div v-if="initLoading" class="mt-6"> |
| | | <ElSkeleton :rows="6" animated /> |
| | | </div> |
| | | |
| | | <ElResult |
| | | v-else-if="initErrorMessage" |
| | | class="mt-6" |
| | | icon="error" |
| | | :title="$t('crud.messages.loadFailed')" |
| | | :sub-title="initErrorMessage" |
| | | > |
| | | <template #extra> |
| | | <ElButton type="primary" @click="handleRetryInit" v-ripple> |
| | | {{ $t('common.actions.reload') }} |
| | | </ElButton> |
| | | </template> |
| | | </ElResult> |
| | | |
| | | <ElForm |
| | | v-else |
| | | ref="formRef" |
| | | :model="formData" |
| | | :rules="rules" |
| | |
| | | class="custom-height" |
| | | :placeholder="$t('login.placeholder.username')" |
| | | v-model.trim="formData.username" |
| | | :disabled="loading" |
| | | /> |
| | | </ElFormItem> |
| | | <ElFormItem prop="password"> |
| | |
| | | type="password" |
| | | autocomplete="off" |
| | | show-password |
| | | :disabled="loading" |
| | | /> |
| | | </ElFormItem> |
| | | <ElFormItem v-if="requiresTenantSelection" prop="tenantId"> |
| | |
| | | filterable |
| | | :loading="tenantLoading" |
| | | :placeholder="$t('login.placeholder.tenant')" |
| | | :disabled="loading || tenantLoading" |
| | | > |
| | | <ElOption |
| | | v-for="tenant in tenantOptions" |
| | |
| | | </ElSelect> |
| | | </ElFormItem> |
| | | |
| | | <div class="flex-cb mt-2 text-sm"> |
| | | <ElCheckbox v-model="formData.rememberPassword">{{ |
| | | <div class="mt-2 text-sm"> |
| | | <ElCheckbox v-model="formData.rememberPassword" :disabled="loading">{{ |
| | | $t('login.rememberPwd') |
| | | }}</ElCheckbox> |
| | | <RouterLink class="text-theme" :to="{ name: 'ForgetPassword' }">{{ |
| | | $t('login.forgetPwd') |
| | | }}</RouterLink> |
| | | </div> |
| | | |
| | | <div style="margin-top: 30px"> |
| | |
| | | type="primary" |
| | | @click="handleSubmit" |
| | | :loading="loading" |
| | | :disabled="loading" |
| | | v-ripple |
| | | > |
| | | {{ $t('login.btnText') }} |
| | | </ElButton> |
| | | </div> |
| | | |
| | | <!-- <div class="mt-5 text-sm text-gray-600">--> |
| | | <!-- <span>{{ $t('login.noAccount') }}</span>--> |
| | | <!-- <RouterLink class="text-theme" :to="{ name: 'Register' }">{{--> |
| | | <!-- $t('login.register')--> |
| | | <!-- }}</RouterLink>--> |
| | | <!-- </div>--> |
| | | </ElForm> |
| | | </div> |
| | | </div> |
| | |
| | | : [] |
| | | })) |
| | | const loading = ref(false) |
| | | const initLoading = ref(true) |
| | | const initErrorMessage = ref('') |
| | | |
| | | const hydrateRememberedLogin = () => { |
| | | const rememberEnabled = |
| | |
| | | } |
| | | } |
| | | |
| | | const initializeLoginPage = async () => { |
| | | initLoading.value = true |
| | | initErrorMessage.value = '' |
| | | try { |
| | | await loadLoginSupports() |
| | | await nextTick() |
| | | formRef.value?.clearValidate() |
| | | } catch (error) { |
| | | tenantOptions.value = [] |
| | | formData.tenantId = '' |
| | | initErrorMessage.value = error?.message || t('httpMsg.requestFailed') |
| | | } finally { |
| | | initLoading.value = false |
| | | } |
| | | } |
| | | |
| | | const persistRememberedLogin = () => { |
| | | localStorage.setItem( |
| | | StorageConfig.LOGIN_REMEMBER_ENABLED_KEY, |
| | |
| | | } |
| | | |
| | | const handleSubmit = async () => { |
| | | if (!formRef.value) return |
| | | if (!formRef.value || initLoading.value || initErrorMessage.value) return |
| | | try { |
| | | const valid = await formRef.value.validate() |
| | | if (!valid) return |
| | |
| | | } |
| | | } |
| | | |
| | | const handleRetryInit = () => { |
| | | void initializeLoginPage() |
| | | } |
| | | |
| | | watch( |
| | | () => formData.tenantId, |
| | | (value) => { |
| | |
| | | |
| | | onMounted(async () => { |
| | | hydrateRememberedLogin() |
| | | await loadLoginSupports() |
| | | await nextTick() |
| | | formRef.value?.clearValidate() |
| | | await initializeLoginPage() |
| | | }) |
| | | |
| | | const showLoginSuccessNotice = () => { |