You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
155 lines
4.7 KiB
155 lines
4.7 KiB
<script lang="ts" setup> |
|
import { computed, reactive, ref, unref } from 'vue' |
|
import { Button, Form, Input } from 'ant-design-vue' |
|
import LoginFormTitle from './LoginFormTitle.vue' |
|
import { LoginStateEnum, useFormRules, useFormValid, useLoginState } from './useLogin' |
|
import { CountdownInput } from '@/components/CountDown' |
|
import { useI18n } from '@/hooks/web/useI18n' |
|
import { useMessage } from '@/hooks/web/useMessage' |
|
import { useUserStore } from '@/store/modules/user' |
|
import { usePermissionStore } from '@/store/modules/permission' |
|
import { useGlobSetting } from '@/hooks/setting' |
|
import { useDesign } from '@/hooks/web/useDesign' |
|
import * as authUtil from '@/utils/auth' |
|
|
|
import { Verify } from '@/components/Verifition' |
|
import { getTenantIdByName, sendSmsCode } from '@/api/base/login' |
|
|
|
const FormItem = Form.Item |
|
|
|
const { t } = useI18n() |
|
const { prefixCls } = useDesign('login') |
|
const { createMessage, notification, createErrorModal } = useMessage() |
|
const { handleBackLogin, getLoginState } = useLoginState() |
|
const { tenantEnable, captchaEnable } = useGlobSetting() |
|
const { getFormRules } = useFormRules() |
|
const userStore = useUserStore() |
|
const permissionStore = usePermissionStore() |
|
|
|
const formRef = ref() |
|
const loading = ref(false) |
|
|
|
const mobileCodeTimer = ref(0) |
|
const scene = ref(21) |
|
|
|
const verify = ref() |
|
const captchaType = ref('blockPuzzle') // blockPuzzle 滑块 clickWord 点击文字 |
|
|
|
const formData = reactive({ |
|
tenantName: '芋道源码', |
|
mobile: '', |
|
mobileCode: '', |
|
captchaVerification: '', |
|
}) |
|
|
|
const { validForm } = useFormValid(formRef) |
|
|
|
const getShow = computed(() => unref(getLoginState) === LoginStateEnum.MOBILE) |
|
|
|
// 获取验证码 |
|
async function getCode() { |
|
// 情况一,未开启:则直接登录 |
|
if (captchaEnable === 'false') { |
|
await handleLogin() |
|
} |
|
else { |
|
// 情况二,已开启:则展示验证码;只有完成验证码的情况,才进行登录 |
|
// 弹出验证码 |
|
verify.value.show() |
|
} |
|
} |
|
|
|
// 获取租户ID |
|
async function getTenantId() { |
|
if (tenantEnable === 'true') { |
|
const res = await getTenantIdByName(formData.tenantName) |
|
authUtil.setTenantId(res) |
|
} |
|
} |
|
|
|
async function handleLogin() { |
|
const data = await validForm() |
|
if (!data) |
|
return |
|
try { |
|
loading.value = true |
|
const userInfo = await userStore.smsLogin({ |
|
mobile: data.mobile, |
|
code: data.mobileCode, |
|
mode: 'none', // 不要默认的错误提示 |
|
}) |
|
if (userInfo) { |
|
await permissionStore.changePermissionCode(userInfo.permissions) |
|
notification.success({ |
|
message: t('sys.login.loginSuccessTitle'), |
|
description: `${t('sys.login.loginSuccessDesc')}: ${userInfo.user.nickname}`, |
|
duration: 3, |
|
}) |
|
} |
|
} |
|
catch (error) { |
|
createErrorModal({ |
|
title: t('sys.api.errorTip'), |
|
content: (error as unknown as Error).message || t('sys.api.networkExceptionMsg'), |
|
getContainer: () => document.body.querySelector(`.${prefixCls}`) || document.body, |
|
}) |
|
} |
|
finally { |
|
loading.value = false |
|
} |
|
} |
|
|
|
async function getSmsCode() { |
|
await getTenantId() |
|
if (mobileCodeTimer.value > 0) |
|
return |
|
const data = await validForm() |
|
if (!data) |
|
return |
|
const res = await sendSmsCode(formData.mobile, scene.value) |
|
if (res) { |
|
createMessage.success(t('common.successText')) |
|
mobileCodeTimer.value = 60 |
|
} |
|
} |
|
</script> |
|
|
|
<template> |
|
<div v-if="getShow"> |
|
<LoginFormTitle class="enter-x" /> |
|
<Form ref="formRef" class="enter-x p-4" :model="formData" :rules="getFormRules"> |
|
<FormItem name="tenantName" class="enter-x"> |
|
<Input |
|
v-if="tenantEnable === 'true'" |
|
v-model:value="formData.tenantName" |
|
size="large" |
|
:placeholder="t('sys.login.tenantName')" |
|
class="fix-auto-fill" |
|
/> |
|
</FormItem> |
|
<FormItem name="mobile" class="enter-x"> |
|
<Input v-model:value="formData.mobile" size="large" :placeholder="t('sys.login.mobile')" class="fix-auto-fill" /> |
|
</FormItem> |
|
<FormItem name="mobileCode" class="enter-x"> |
|
<CountdownInput |
|
v-model:value="formData.mobileCode" |
|
size="large" |
|
class="fix-auto-fill" |
|
:count="mobileCodeTimer" |
|
:send-code-api="getSmsCode" |
|
:placeholder="t('sys.login.smsCode')" |
|
/> |
|
</FormItem> |
|
|
|
<FormItem class="enter-x"> |
|
<Button type="primary" size="large" block :loading="loading" @click="getCode"> |
|
{{ t('sys.login.loginButton') }} |
|
</Button> |
|
<Button size="large" block class="mt-4" @click="handleBackLogin"> |
|
{{ t('sys.login.backSignIn') }} |
|
</Button> |
|
</FormItem> |
|
</Form> |
|
<Verify ref="verify" mode="pop" :captcha-type="captchaType" :img-size="{ width: '400px', height: '200px' }" @success="handleLogin" /> |
|
</div> |
|
</template>
|
|
|