chore(login): 修改登录页组件,增加租户登录逻辑

This commit is contained in:
MoChou
2025-07-20 12:13:06 +08:00
parent d4397ffd57
commit e63bedc11b
5 changed files with 29 additions and 34 deletions

View File

@@ -2,8 +2,8 @@ import { defineStore } from 'pinia'
import { computed, ref } from 'vue' import { computed, ref } from 'vue'
export const useTenantStore = defineStore('tenant', () => { export const useTenantStore = defineStore('tenant', () => {
const tenantEnabled = ref(false) const tenantEnabled = ref<boolean>(false)
const tenantId = ref('') const tenantId = ref<string>()
const setTenantEnable = (status: boolean) => { const setTenantEnable = (status: boolean) => {
tenantEnabled.value = status tenantEnabled.value = status
@@ -13,16 +13,22 @@ export const useTenantStore = defineStore('tenant', () => {
} }
// 判断是否需要用户输入租户编码 // 判断是否需要用户输入租户编码
const needInputTenantId = computed(() => { const needInputTenantCode = computed(() => {
return tenantEnabled.value && !tenantId.value return tenantEnabled.value && !tenantId.value
}) })
// 新增:判断租户是否已正确配置
const isTenantConfigured = computed(() => {
return tenantEnabled.value && !!tenantId.value
})
return { return {
tenantEnabled, tenantEnabled,
tenantId, tenantId,
setTenantEnable, setTenantEnable,
setTenantId, setTenantId,
needInputTenantId, needInputTenantCode,
isTenantConfigured,
} }
}, { }, {
persist: { paths: ['tenantEnabled', 'tenantId'], storage: localStorage }, persist: { paths: ['tenantEnabled', 'tenantId'], storage: localStorage },

View File

@@ -8,8 +8,8 @@
size="large" size="large"
@submit="handleLogin" @submit="handleLogin"
> >
<a-form-item v-if="tenantStore.needInputTenantId" field="tenantCode" hide-label> <a-form-item v-if="tenantStore.needInputTenantCode" field="tenantCode" hide-label>
<a-input v-model="form.tenantCode" placeholder="请输入租户编码" allow-clear /> <a-input v-model="tenantCode" placeholder="请输入租户编码(不输入时为默认租户)" allow-clear />
</a-form-item> </a-form-item>
<a-form-item field="username" hide-label> <a-form-item field="username" hide-label>
<a-input v-model="form.username" placeholder="请输入用户名" allow-clear /> <a-input v-model="form.username" placeholder="请输入用户名" allow-clear />
@@ -61,7 +61,8 @@ const loginConfig = useStorage('login-config', {
const isCaptchaEnabled = ref(true) const isCaptchaEnabled = ref(true)
// 验证码图片 // 验证码图片
const captchaImgBase64 = ref() const captchaImgBase64 = ref()
// 租户编号
const tenantCode = ref()
const formRef = ref<FormInstance>() const formRef = ref<FormInstance>()
const form = reactive({ const form = reactive({
username: loginConfig.value.username, username: loginConfig.value.username,
@@ -69,19 +70,12 @@ const form = reactive({
captcha: '', captcha: '',
uuid: '', uuid: '',
expired: false, expired: false,
tenantCode: '', // 新增
}) })
// 校验规则部分 // 校验规则部分
const rules: FormInstance['rules'] = { const rules: FormInstance['rules'] = {
username: [{ required: true, message: '请输入用户名' }], username: [{ required: true, message: '请输入用户名' }],
password: [{ required: true, message: '请输入密码' }], password: [{ required: true, message: '请输入密码' }],
captcha: [{ required: isCaptchaEnabled.value, message: '请输入验证码' }], captcha: [{ required: isCaptchaEnabled.value, message: '请输入验证码' }],
tenantCode: [
{
required: tenantStore.needInputTenantId,
message: '请输入租户编码',
},
],
} }
// 验证码过期定时器 // 验证码过期定时器
@@ -129,17 +123,12 @@ const handleLogin = async () => {
if (isInvalid) return if (isInvalid) return
loading.value = true loading.value = true
let tenantCode
if (tenantStore.needInputTenantId) {
tenantCode = form.tenantCode
}
await userStore.accountLogin({ await userStore.accountLogin({
username: form.username, username: form.username,
password: encryptByRsa(form.password) || '', password: encryptByRsa(form.password) || '',
captcha: form.captcha, captcha: form.captcha,
uuid: form.uuid, uuid: form.uuid,
}, tenantCode) }, tenantCode.value)
tabsStore.reset() tabsStore.reset()
const { redirect, ...othersQuery } = router.currentRoute.value.query const { redirect, ...othersQuery } = router.currentRoute.value.query
const { rememberMe } = loginConfig.value const { rememberMe } = loginConfig.value

View File

@@ -8,8 +8,8 @@
size="large" size="large"
@submit="handleLogin" @submit="handleLogin"
> >
<a-form-item v-if="tenantEnabled" field="tenantCode" hide-label> <a-form-item v-if="tenantStore.needInputTenantCode" field="tenantCode" hide-label>
<a-input v-model="tenantCode" placeholder="请输入租户编码" allow-clear /> <a-input v-model="tenantCode" placeholder="请输入租户编码(不输入时为默认租户)" allow-clear />
</a-form-item> </a-form-item>
<a-form-item field="email" hide-label> <a-form-item field="email" hide-label>
<a-input v-model="form.email" placeholder="请输入邮箱" allow-clear /> <a-input v-model="form.email" placeholder="请输入邮箱" allow-clear />
@@ -43,14 +43,13 @@
<script setup lang="ts"> <script setup lang="ts">
import { type FormInstance, Message } from '@arco-design/web-vue' import { type FormInstance, Message } from '@arco-design/web-vue'
import { computed } from 'vue'
import type { BehaviorCaptchaReq } from '@/apis' import type { BehaviorCaptchaReq } from '@/apis'
// import { type BehaviorCaptchaReq, getEmailCaptcha } from '@/apis' // import { type BehaviorCaptchaReq, getEmailCaptcha } from '@/apis'
import { useAppStore, useTabsStore, useUserStore } from '@/stores' import { useTabsStore, useUserStore } from '@/stores'
import * as Regexp from '@/utils/regexp' import * as Regexp from '@/utils/regexp'
import { useTenantStore } from '@/stores/modules/tenant'
const appStore = useAppStore() const tenantStore = useTenantStore()
const tenantEnabled = computed(() => appStore.getTenantEnabled())
const formRef = ref<FormInstance>() const formRef = ref<FormInstance>()
const form = reactive({ const form = reactive({

View File

@@ -8,8 +8,8 @@
size="large" size="large"
@submit="handleLogin" @submit="handleLogin"
> >
<a-form-item v-if="tenantEnabled" field="tenantCode" hide-label> <a-form-item v-if="tenantStore.needInputTenantCode" field="tenantCode" hide-label>
<a-input v-model="tenantCode" placeholder="请输入租户编码" allow-clear /> <a-input v-model="tenantCode" placeholder="请输入租户编码(不输入时为默认租户)" allow-clear />
</a-form-item> </a-form-item>
<a-form-item field="phone" hide-label> <a-form-item field="phone" hide-label>
<a-input v-model="form.phone" placeholder="请输入手机号" :max-length="11" allow-clear /> <a-input v-model="form.phone" placeholder="请输入手机号" :max-length="11" allow-clear />
@@ -44,13 +44,12 @@
<script setup lang="ts"> <script setup lang="ts">
import { type FormInstance, Message } from '@arco-design/web-vue' import { type FormInstance, Message } from '@arco-design/web-vue'
// import type { BehaviorCaptchaReq } from '@/apis' // import type { BehaviorCaptchaReq } from '@/apis'
import { computed } from 'vue'
import { type BehaviorCaptchaReq, getSmsCaptcha } from '@/apis' import { type BehaviorCaptchaReq, getSmsCaptcha } from '@/apis'
import { useAppStore, useTabsStore, useUserStore } from '@/stores' import { useTabsStore, useUserStore } from '@/stores'
import * as Regexp from '@/utils/regexp' import * as Regexp from '@/utils/regexp'
import { useTenantStore } from '@/stores/modules/tenant'
const appStore = useAppStore() const tenantStore = useTenantStore()
const tenantEnabled = computed(() => appStore.getTenantEnabled())
const formRef = ref<FormInstance>() const formRef = ref<FormInstance>()
const form = reactive({ const form = reactive({

View File

@@ -78,10 +78,10 @@
<div class="list"> <div class="list">
<div v-if="isEmailLogin" class="mode item" @click="toggleLoginMode"><icon-user /> 账号/手机号登录</div> <div v-if="isEmailLogin" class="mode item" @click="toggleLoginMode"><icon-user /> 账号/手机号登录</div>
<div v-else class="mode item" @click="toggleLoginMode"><icon-email /> 邮箱登录</div> <div v-else class="mode item" @click="toggleLoginMode"><icon-email /> 邮箱登录</div>
<a class="item" title="使用 Gitee 账号登录" @click="onOauth('gitee')"> <a v-if="!tenantStore.isTenantConfigured" class="item" title="使用 Gitee 账号登录" @click="onOauth('gitee')">
<GiSvgIcon name="gitee" :size="24" /> <GiSvgIcon name="gitee" :size="24" />
</a> </a>
<a class="item" title="使用 GitHub 账号登录" @click="onOauth('github')"> <a v-if="tenantStore.isTenantConfigured" class="item" title="使用 GitHub 账号登录" @click="onOauth('github')">
<GiSvgIcon name="github" :size="24" /> <GiSvgIcon name="github" :size="24" />
</a> </a>
</div> </div>
@@ -102,8 +102,10 @@ import { useDevice } from '@/hooks'
import { getTenantIdByDomain, getTenantStatus } from '@/apis' import { getTenantIdByDomain, getTenantStatus } from '@/apis'
defineOptions({ name: 'Login' }) defineOptions({ name: 'Login' })
const appStore = useAppStore() const appStore = useAppStore()
const tenantStore = useTenantStore() const tenantStore = useTenantStore()
const { isDesktop } = useDevice() const { isDesktop } = useDevice()
const title = computed(() => appStore.getTitle()) const title = computed(() => appStore.getTitle())
const logo = computed(() => appStore.getLogo()) const logo = computed(() => appStore.getLogo())