mirror of
https://github.com/continew-org/continew-admin-ui.git
synced 2025-11-10 14:57:09 +08:00
refactor(tenant): 优化租户相关代码
This commit is contained in:
@@ -5,19 +5,32 @@ export type * from './type'
|
|||||||
|
|
||||||
const BASE_URL = '/auth'
|
const BASE_URL = '/auth'
|
||||||
|
|
||||||
/** @desc 账号登录 */
|
const login = (req: T.AccountLoginReq | T.PhoneLoginReq | T.EmailLoginReq, tenantCode?: string) => {
|
||||||
export function accountLogin(req: T.AccountLoginReq) {
|
const headers = {}
|
||||||
return http.post<T.LoginResp>(`${BASE_URL}/login`, req)
|
if (tenantCode) {
|
||||||
|
headers['X-Tenant-Code'] = tenantCode
|
||||||
|
}
|
||||||
|
return http.requestNative({
|
||||||
|
url: `${BASE_URL}/login`,
|
||||||
|
data: req,
|
||||||
|
method: 'post',
|
||||||
|
headers,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @desc 手机号登录 */
|
/** @desc 账号登录 */
|
||||||
export function phoneLogin(req: T.PhoneLoginReq) {
|
export function accountLogin(req: T.AccountLoginReq, tenantCode?: string) {
|
||||||
return http.post<T.LoginResp>(`${BASE_URL}/login`, req)
|
return login(req, tenantCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @desc 邮箱登录 */
|
/** @desc 邮箱登录 */
|
||||||
export function emailLogin(req: T.EmailLoginReq) {
|
export function emailLogin(req: T.EmailLoginReq, tenantCode?: string) {
|
||||||
return http.post<T.LoginResp>(`${BASE_URL}/login`, req)
|
return login(req, tenantCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @desc 手机号登录 */
|
||||||
|
export function phoneLogin(req: T.PhoneLoginReq, tenantCode?: string) {
|
||||||
|
return login(req, tenantCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @desc 三方账号登录 */
|
/** @desc 三方账号登录 */
|
||||||
|
|||||||
@@ -335,6 +335,7 @@ export interface BasicConfig {
|
|||||||
SITE_TITLE: string
|
SITE_TITLE: string
|
||||||
SITE_COPYRIGHT: string
|
SITE_COPYRIGHT: string
|
||||||
SITE_BEIAN: string
|
SITE_BEIAN: string
|
||||||
|
TENANT_ENABLED: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 基础配置类型 */
|
/** 基础配置类型 */
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import type * as T from './type'
|
import type * as T from './type'
|
||||||
import http from '@/utils/http'
|
import http from '@/utils/http'
|
||||||
import type { TenantCommon } from '@/utils/tenant'
|
|
||||||
|
|
||||||
export type * from './type'
|
export type * from './type'
|
||||||
|
|
||||||
@@ -31,11 +30,6 @@ export function deleteTenant(id: string) {
|
|||||||
return http.del(`${BASE_URL}/${id}`)
|
return http.del(`${BASE_URL}/${id}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @desc 多租户通用信息查询 */
|
|
||||||
export const getTenantCommon = () => {
|
|
||||||
return http.get<TenantCommon>(`${BASE_URL}/common`)
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @desc 修改租户管理员密码 */
|
/** @desc 修改租户管理员密码 */
|
||||||
export const updateTenantAdminUserPwd = (data: any, id: string) => {
|
export const updateTenantAdminUserPwd = (data: any, id: string) => {
|
||||||
return http.put(`${BASE_URL}/${id}/admin/pwd`, data)
|
return http.put(`${BASE_URL}/${id}/admin/pwd`, data)
|
||||||
|
|||||||
@@ -1,168 +0,0 @@
|
|||||||
<template>
|
|
||||||
<a-modal
|
|
||||||
v-model:visible="visible"
|
|
||||||
title="选择租户"
|
|
||||||
hide-cancel
|
|
||||||
:closable="false"
|
|
||||||
:mask-closable="false"
|
|
||||||
:ok-loading="okLoading"
|
|
||||||
draggable
|
|
||||||
:width="width >= 500 ? 500 : '90%'"
|
|
||||||
@before-ok="confirm"
|
|
||||||
>
|
|
||||||
<div class="scrollable-container">
|
|
||||||
<a-radio-group v-model="tenantId" direction="vertical" class="scrollable-container-radio-group" @change="value => { setTenantId(value) }">
|
|
||||||
<a-radio :value="0" class="scrollable-container-radio">
|
|
||||||
<template #radio="{ checked }">
|
|
||||||
<a-space
|
|
||||||
align="start"
|
|
||||||
class="custom-radio-card"
|
|
||||||
:class="{ 'custom-radio-card-checked': checked }"
|
|
||||||
>
|
|
||||||
<div className="custom-radio-card-mask">
|
|
||||||
<div className="custom-radio-card-mask-dot" />
|
|
||||||
</div>
|
|
||||||
系统默认租户
|
|
||||||
</a-space>
|
|
||||||
</template>
|
|
||||||
</a-radio>
|
|
||||||
<template v-for="item in tenantList" :key="item.id">
|
|
||||||
<a-radio :value="item.id" class="scrollable-container-radio">
|
|
||||||
<template #radio="{ checked }">
|
|
||||||
<a-space
|
|
||||||
align="start"
|
|
||||||
class="custom-radio-card"
|
|
||||||
:class="{ 'custom-radio-card-checked': checked }"
|
|
||||||
>
|
|
||||||
<div className="custom-radio-card-mask">
|
|
||||||
<div className="custom-radio-card-mask-dot" />
|
|
||||||
</div>
|
|
||||||
{{ item.name }}
|
|
||||||
</a-space>
|
|
||||||
</template>
|
|
||||||
</a-radio>
|
|
||||||
</template>
|
|
||||||
</a-radio-group>
|
|
||||||
</div>
|
|
||||||
</a-modal>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { useWindowSize } from '@vueuse/core'
|
|
||||||
import { Message } from '@arco-design/web-vue'
|
|
||||||
import { getTenantId, setTenantId } from '@/utils/tenant'
|
|
||||||
import { getTenantCommon } from '@/apis/tenant/management'
|
|
||||||
|
|
||||||
const { width } = useWindowSize()
|
|
||||||
const visible = ref(false)
|
|
||||||
const okLoading = ref(false)
|
|
||||||
const tenantList = ref()
|
|
||||||
const tenantId = ref(getTenantId())
|
|
||||||
|
|
||||||
const confirm = async () => {
|
|
||||||
if (!getTenantId()) {
|
|
||||||
Message.error('请确认需要登录的租户')
|
|
||||||
return false
|
|
||||||
} else {
|
|
||||||
visible.value = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(async () => {
|
|
||||||
const tenantCommon = await getTenantCommon()
|
|
||||||
// 需要开启了多租户才显示租户选择款
|
|
||||||
if (tenantCommon && tenantCommon.data.isEnabled) {
|
|
||||||
if (tenantCommon.data.availableList.length > 0) {
|
|
||||||
const hostname = window.location.hostname
|
|
||||||
for (const item of tenantCommon.data.availableList) {
|
|
||||||
// 如果有域名匹配则直接设置对应租户
|
|
||||||
if (item.domain === hostname) {
|
|
||||||
setTenantId(item.id)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// 如果后台没有配置租户则是默认系统租户
|
|
||||||
setTenantId(0)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
tenantList.value = tenantCommon.data.availableList
|
|
||||||
visible.value = true
|
|
||||||
}
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.tenant-select{
|
|
||||||
width: 100%;
|
|
||||||
padding: 10px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.scrollable-container {
|
|
||||||
height: 300px;
|
|
||||||
overflow-y: auto;
|
|
||||||
scrollbar-width: none;
|
|
||||||
text-align: center;
|
|
||||||
&-radio-group{
|
|
||||||
width: 90%
|
|
||||||
}
|
|
||||||
&-radio{
|
|
||||||
padding: 7px 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.custom-radio-card {
|
|
||||||
padding: 10px 16px;
|
|
||||||
border: 1px solid var(--color-border-2);
|
|
||||||
border-radius: 4px;
|
|
||||||
width: 100%;
|
|
||||||
box-sizing: border-box;
|
|
||||||
white-space: nowrap;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.custom-radio-card-mask {
|
|
||||||
height: 14px;
|
|
||||||
width: 14px;
|
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
border-radius: 100%;
|
|
||||||
border: 1px solid var(--color-border-2);
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
.custom-radio-card-mask-dot {
|
|
||||||
width: 8px;
|
|
||||||
height: 8px;
|
|
||||||
border-radius: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.custom-radio-card-title {
|
|
||||||
color: var(--color-text-1);
|
|
||||||
font-size: 14px;
|
|
||||||
font-weight: bold;
|
|
||||||
margin-bottom: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.custom-radio-card:hover,
|
|
||||||
.custom-radio-card-checked,
|
|
||||||
.custom-radio-card:hover .custom-radio-card-mask,
|
|
||||||
.custom-radio-card-checked .custom-radio-card-mask{
|
|
||||||
border-color: rgb(var(--primary-6));
|
|
||||||
}
|
|
||||||
|
|
||||||
.custom-radio-card-checked {
|
|
||||||
background-color: var(--color-primary-light-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.custom-radio-card:hover .custom-radio-card-title,
|
|
||||||
.custom-radio-card-checked .custom-radio-card-title {
|
|
||||||
color: rgb(var(--primary-6));
|
|
||||||
}
|
|
||||||
|
|
||||||
.custom-radio-card-checked .custom-radio-card-mask-dot {
|
|
||||||
background-color: rgb(var(--primary-6));
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -68,6 +68,7 @@ const storeSetup = () => {
|
|||||||
siteConfig.SITE_TITLE = resMap.get('SITE_TITLE')
|
siteConfig.SITE_TITLE = resMap.get('SITE_TITLE')
|
||||||
siteConfig.SITE_COPYRIGHT = resMap.get('SITE_COPYRIGHT')
|
siteConfig.SITE_COPYRIGHT = resMap.get('SITE_COPYRIGHT')
|
||||||
siteConfig.SITE_BEIAN = resMap.get('SITE_BEIAN')
|
siteConfig.SITE_BEIAN = resMap.get('SITE_BEIAN')
|
||||||
|
siteConfig.TENANT_ENABLED = resMap.get('TENANT_ENABLED') === 'true'
|
||||||
document.title = resMap.get('SITE_TITLE')
|
document.title = resMap.get('SITE_TITLE')
|
||||||
document
|
document
|
||||||
.querySelector('link[rel="shortcut icon"]')
|
.querySelector('link[rel="shortcut icon"]')
|
||||||
@@ -122,6 +123,10 @@ const storeSetup = () => {
|
|||||||
const getForRecord = () => {
|
const getForRecord = () => {
|
||||||
return siteConfig.SITE_BEIAN
|
return siteConfig.SITE_BEIAN
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getTenantEnabled = () => {
|
||||||
|
return siteConfig.TENANT_ENABLED
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
...toRefs(settingConfig),
|
...toRefs(settingConfig),
|
||||||
...toRefs(siteConfig),
|
...toRefs(siteConfig),
|
||||||
@@ -138,6 +143,7 @@ const storeSetup = () => {
|
|||||||
getTitle,
|
getTitle,
|
||||||
getCopyright,
|
getCopyright,
|
||||||
getForRecord,
|
getForRecord,
|
||||||
|
getTenantEnabled,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -50,22 +50,22 @@ const storeSetup = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 登录
|
// 登录
|
||||||
const accountLogin = async (req: AccountLoginReq) => {
|
const accountLogin = async (req: AccountLoginReq, tenantCode?: string) => {
|
||||||
const res = await accountLoginApi({ ...req, clientId: import.meta.env.VITE_CLIENT_ID, authType: AuthTypeConstants.ACCOUNT })
|
const res = await accountLoginApi({ ...req, clientId: import.meta.env.VITE_CLIENT_ID, authType: AuthTypeConstants.ACCOUNT }, tenantCode)
|
||||||
setToken(res.data.token)
|
setToken(res.data.token)
|
||||||
token.value = res.data.token
|
token.value = res.data.token
|
||||||
}
|
}
|
||||||
|
|
||||||
// 邮箱登录
|
// 邮箱登录
|
||||||
const emailLogin = async (req: EmailLoginReq) => {
|
const emailLogin = async (req: EmailLoginReq, tenantCode?: string) => {
|
||||||
const res = await emailLoginApi({ ...req, clientId: import.meta.env.VITE_CLIENT_ID, authType: AuthTypeConstants.EMAIL })
|
const res = await emailLoginApi({ ...req, clientId: import.meta.env.VITE_CLIENT_ID, authType: AuthTypeConstants.EMAIL }, tenantCode)
|
||||||
setToken(res.data.token)
|
setToken(res.data.token)
|
||||||
token.value = res.data.token
|
token.value = res.data.token
|
||||||
}
|
}
|
||||||
|
|
||||||
// 手机号登录
|
// 手机号登录
|
||||||
const phoneLogin = async (req: PhoneLoginReq) => {
|
const phoneLogin = async (req: PhoneLoginReq, tenantCode?: string) => {
|
||||||
const res = await phoneLoginApi({ ...req, clientId: import.meta.env.VITE_CLIENT_ID, authType: AuthTypeConstants.PHONE })
|
const res = await phoneLoginApi({ ...req, clientId: import.meta.env.VITE_CLIENT_ID, authType: AuthTypeConstants.PHONE }, tenantCode)
|
||||||
setToken(res.data.token)
|
setToken(res.data.token)
|
||||||
token.value = res.data.token
|
token.value = res.data.token
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,17 +52,14 @@ const handleError = (msg: string) => {
|
|||||||
http.interceptors.request.use(
|
http.interceptors.request.use(
|
||||||
(config: AxiosRequestConfig) => {
|
(config: AxiosRequestConfig) => {
|
||||||
const token = getToken()
|
const token = getToken()
|
||||||
|
if (!config.headers) {
|
||||||
|
config.headers = {}
|
||||||
|
}
|
||||||
if (token) {
|
if (token) {
|
||||||
if (!config.headers) {
|
|
||||||
config.headers = {}
|
|
||||||
}
|
|
||||||
config.headers.Authorization = `Bearer ${token}`
|
config.headers.Authorization = `Bearer ${token}`
|
||||||
}
|
}
|
||||||
const tenantId = getTenantId()
|
const tenantId = getTenantId()
|
||||||
if (tenantId) {
|
if (tenantId) {
|
||||||
if (!config.headers) {
|
|
||||||
config.headers = {}
|
|
||||||
}
|
|
||||||
config.headers['X-Tenant-Id'] = tenantId
|
config.headers['X-Tenant-Id'] = tenantId
|
||||||
}
|
}
|
||||||
return config
|
return config
|
||||||
|
|||||||
@@ -8,6 +8,9 @@
|
|||||||
size="large"
|
size="large"
|
||||||
@submit="handleLogin"
|
@submit="handleLogin"
|
||||||
>
|
>
|
||||||
|
<a-form-item v-if="tenantEnabled" field="tenantCode" hide-label>
|
||||||
|
<a-input v-model="tenantCode" placeholder="请输入租户编码" allow-clear />
|
||||||
|
</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 />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
@@ -40,12 +43,17 @@
|
|||||||
<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 { useStorage } from '@vueuse/core'
|
import { useStorage } from '@vueuse/core'
|
||||||
|
import { computed } from 'vue'
|
||||||
import { getImageCaptcha } from '@/apis/common'
|
import { getImageCaptcha } from '@/apis/common'
|
||||||
import { useTabsStore, useUserStore } from '@/stores'
|
import { useAppStore, useTabsStore, useUserStore } from '@/stores'
|
||||||
import { encryptByRsa } from '@/utils/encrypt'
|
import { encryptByRsa } from '@/utils/encrypt'
|
||||||
|
|
||||||
|
const appStore = useAppStore()
|
||||||
|
const tenantEnabled = computed(() => appStore.getTenantEnabled())
|
||||||
|
|
||||||
const loginConfig = useStorage('login-config', {
|
const loginConfig = useStorage('login-config', {
|
||||||
rememberMe: true,
|
rememberMe: true,
|
||||||
|
tenantCode: '',
|
||||||
username: 'admin', // 演示默认值
|
username: 'admin', // 演示默认值
|
||||||
password: 'admin123', // 演示默认值
|
password: 'admin123', // 演示默认值
|
||||||
// username: debug ? 'admin' : '', // 演示默认值
|
// username: debug ? 'admin' : '', // 演示默认值
|
||||||
@@ -64,6 +72,7 @@ const form = reactive({
|
|||||||
uuid: '',
|
uuid: '',
|
||||||
expired: false,
|
expired: false,
|
||||||
})
|
})
|
||||||
|
const tenantCode = ref()
|
||||||
const rules: FormInstance['rules'] = {
|
const rules: FormInstance['rules'] = {
|
||||||
username: [{ required: true, message: '请输入用户名' }],
|
username: [{ required: true, message: '请输入用户名' }],
|
||||||
password: [{ required: true, message: '请输入密码' }],
|
password: [{ required: true, message: '请输入密码' }],
|
||||||
@@ -119,10 +128,11 @@ const handleLogin = async () => {
|
|||||||
password: encryptByRsa(form.password) || '',
|
password: encryptByRsa(form.password) || '',
|
||||||
captcha: form.captcha,
|
captcha: form.captcha,
|
||||||
uuid: form.uuid,
|
uuid: form.uuid,
|
||||||
})
|
}, 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
|
||||||
|
loginConfig.value.tenantCode = rememberMe ? tenantCode.value : ''
|
||||||
loginConfig.value.username = rememberMe ? form.username : ''
|
loginConfig.value.username = rememberMe ? form.username : ''
|
||||||
|
|
||||||
// 如果有重定向参数,解码并直接跳转到完整路径
|
// 如果有重定向参数,解码并直接跳转到完整路径
|
||||||
|
|||||||
@@ -8,6 +8,9 @@
|
|||||||
size="large"
|
size="large"
|
||||||
@submit="handleLogin"
|
@submit="handleLogin"
|
||||||
>
|
>
|
||||||
|
<a-form-item v-if="tenantEnabled" field="tenantCode" hide-label>
|
||||||
|
<a-input v-model="tenantCode" placeholder="请输入租户编码" allow-clear />
|
||||||
|
</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 />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
@@ -40,16 +43,21 @@
|
|||||||
|
|
||||||
<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 { useTabsStore, useUserStore } from '@/stores'
|
import { useAppStore, useTabsStore, useUserStore } from '@/stores'
|
||||||
import * as Regexp from '@/utils/regexp'
|
import * as Regexp from '@/utils/regexp'
|
||||||
|
|
||||||
|
const appStore = useAppStore()
|
||||||
|
const tenantEnabled = computed(() => appStore.getTenantEnabled())
|
||||||
|
|
||||||
const formRef = ref<FormInstance>()
|
const formRef = ref<FormInstance>()
|
||||||
const form = reactive({
|
const form = reactive({
|
||||||
email: '',
|
email: '',
|
||||||
captcha: '',
|
captcha: '',
|
||||||
})
|
})
|
||||||
|
const tenantCode = ref()
|
||||||
|
|
||||||
const rules: FormInstance['rules'] = {
|
const rules: FormInstance['rules'] = {
|
||||||
email: [
|
email: [
|
||||||
@@ -69,7 +77,7 @@ const handleLogin = async () => {
|
|||||||
const isInvalid = await formRef.value?.validate()
|
const isInvalid = await formRef.value?.validate()
|
||||||
if (isInvalid) return
|
if (isInvalid) return
|
||||||
loading.value = true
|
loading.value = true
|
||||||
await userStore.emailLogin(form)
|
await userStore.emailLogin(form, tenantCode.value)
|
||||||
tabsStore.reset()
|
tabsStore.reset()
|
||||||
const { redirect, ...othersQuery } = router.currentRoute.value.query
|
const { redirect, ...othersQuery } = router.currentRoute.value.query
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,9 @@
|
|||||||
size="large"
|
size="large"
|
||||||
@submit="handleLogin"
|
@submit="handleLogin"
|
||||||
>
|
>
|
||||||
|
<a-form-item v-if="tenantEnabled" field="tenantCode" hide-label>
|
||||||
|
<a-input v-model="tenantCode" placeholder="请输入租户编码" allow-clear />
|
||||||
|
</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 />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
@@ -41,15 +44,20 @@
|
|||||||
<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 { useTabsStore, useUserStore } from '@/stores'
|
import { useAppStore, useTabsStore, useUserStore } from '@/stores'
|
||||||
import * as Regexp from '@/utils/regexp'
|
import * as Regexp from '@/utils/regexp'
|
||||||
|
|
||||||
|
const appStore = useAppStore()
|
||||||
|
const tenantEnabled = computed(() => appStore.getTenantEnabled())
|
||||||
|
|
||||||
const formRef = ref<FormInstance>()
|
const formRef = ref<FormInstance>()
|
||||||
const form = reactive({
|
const form = reactive({
|
||||||
phone: '',
|
phone: '',
|
||||||
captcha: '',
|
captcha: '',
|
||||||
})
|
})
|
||||||
|
const tenantCode = ref()
|
||||||
|
|
||||||
const rules: FormInstance['rules'] = {
|
const rules: FormInstance['rules'] = {
|
||||||
phone: [
|
phone: [
|
||||||
@@ -69,7 +77,7 @@ const handleLogin = async () => {
|
|||||||
if (isInvalid) return
|
if (isInvalid) return
|
||||||
try {
|
try {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
await userStore.phoneLogin(form)
|
await userStore.phoneLogin(form, tenantCode.value)
|
||||||
tabsStore.reset()
|
tabsStore.reset()
|
||||||
const { redirect, ...othersQuery } = router.currentRoute.value.query
|
const { redirect, ...othersQuery } = router.currentRoute.value.query
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user