diff --git a/src/api/login/index.ts b/src/api/login/index.ts
index 37eb491..dfbb76f 100644
--- a/src/api/login/index.ts
+++ b/src/api/login/index.ts
@@ -89,3 +89,29 @@ export const reqCheck = (data: any) => {
export const smsResetPassword = (data: any) => {
return request.post({ url: '/system/auth/reset-password', data })
}
+
+// 获取用户的租户列表(未登录状态)
+export interface UserTenantListVO {
+ username: string
+ password: string
+}
+
+export interface TenantInfo {
+ tenantId: number
+ tenantName: string
+ isDefault: boolean
+}
+
+export interface UserTenantListRespVO {
+ userId: number
+ username: string
+ nickname: string
+ tenants: TenantInfo[]
+}
+
+export const getUserTenantList = (data: UserTenantListVO) => {
+ return request.post({
+ url: '/system/auth/get-user-tenant-list',
+ data
+ })
+}
diff --git a/src/api/login/types.ts b/src/api/login/types.ts
index b5790e6..54e058b 100644
--- a/src/api/login/types.ts
+++ b/src/api/login/types.ts
@@ -1,4 +1,5 @@
export type UserLoginVO = {
+ tenantId?: number
username: string
password: string
captchaVerification: string
diff --git a/src/locales/zh-CN.ts b/src/locales/zh-CN.ts
index 3b6c2e9..e2349f1 100644
--- a/src/locales/zh-CN.ts
+++ b/src/locales/zh-CN.ts
@@ -128,7 +128,7 @@ export default {
remember: '记住我',
hasUser: '已有账号?去登录',
forgetPassword: '忘记密码?',
- tenantNamePlaceholder: '请输入租户名称',
+ tenantNamePlaceholder: '请选择要登录的小区',
usernamePlaceholder: '请输入用户名',
passwordPlaceholder: '请输入密码',
codePlaceholder: '请输入验证码',
@@ -455,4 +455,4 @@ export default {
preview: '预览'
},
'OAuth 2.0': 'OAuth 2.0' // 避免菜单名是 OAuth 2.0 时,一直 warn 报错
-}
\ No newline at end of file
+}
diff --git a/src/views/Login/components/LoginForm.vue b/src/views/Login/components/LoginForm.vue
index a7ceea7..56714bf 100644
--- a/src/views/Login/components/LoginForm.vue
+++ b/src/views/Login/components/LoginForm.vue
@@ -15,17 +15,6 @@
-
-
-
-
-
+
+
+
+
+
+
+
@@ -117,20 +125,28 @@ const redirect = ref('')
const loginLoading = ref(false)
const verify = ref()
const captchaType = ref('blockPuzzle') // blockPuzzle 滑块 clickWord 点击文字 pictureWord 文字验证码
+const tenantList = ref([])
+const isFetchingTenants = ref(false)
const getShow = computed(() => unref(getLoginState) === LoginStateEnum.LOGIN)
const LoginRules = {
- tenantName: [required],
username: [required],
- password: [required]
+ password: [required],
+ tenantId: [
+ {
+ required: true,
+ message: '请选择租户',
+ trigger: 'change'
+ }
+ ]
}
const loginData = reactive({
isShowPassword: false,
captchaEnable: import.meta.env.VITE_APP_CAPTCHA_ENABLE,
tenantEnable: import.meta.env.VITE_APP_TENANT_ENABLE,
loginForm: {
- tenantName: import.meta.env.VITE_APP_DEFAULT_LOGIN_TENANT || '',
+ tenantId: undefined as number | undefined,
username: import.meta.env.VITE_APP_DEFAULT_LOGIN_USERNAME || '',
password: import.meta.env.VITE_APP_DEFAULT_LOGIN_PASSWORD || '',
captchaVerification: '',
@@ -145,8 +161,94 @@ const socialList = [
{ icon: 'ant-design:alipay-circle-filled', type: 0 }
]
+// 获取租户列表
+const fetchTenantList = async () => {
+ if (loginData.tenantEnable !== 'true') {
+ return
+ }
+
+ const username = loginData.loginForm.username?.trim()
+ const password = loginData.loginForm.password?.trim()
+
+ // 只有当用户名和密码都不为空时才获取租户列表
+ if (!username || !password) {
+ return
+ }
+
+ // 防止重复请求
+ if (isFetchingTenants.value) {
+ return
+ }
+
+ isFetchingTenants.value = true
+
+ try {
+ const res = await LoginApi.getUserTenantList({
+ username,
+ password
+ })
+
+ if (!res || !res.tenants || res.tenants.length === 0) {
+ message.error('无权限访问该系统')
+ tenantList.value = []
+ loginData.loginForm.tenantId = undefined
+ return
+ }
+
+ tenantList.value = res.tenants
+
+ // 默认选中第一个租户
+ if (res.tenants.length > 0) {
+ loginData.loginForm.tenantId = res.tenants[0].tenantId
+ }
+ } catch (error) {
+ console.error('获取租户列表失败:', error)
+ tenantList.value = []
+ loginData.loginForm.tenantId = undefined
+ } finally {
+ isFetchingTenants.value = false
+ }
+}
+
// 获取验证码
const getCode = async () => {
+ // 如果开启了租户功能且还没有获取租户列表,先获取
+ if (loginData.tenantEnable === 'true' && tenantList.value.length === 0) {
+ const username = loginData.loginForm.username?.trim()
+ const password = loginData.loginForm.password?.trim()
+
+ if (!username || !password) {
+ message.error('请输入用户名和密码')
+ return
+ }
+
+ // 获取租户列表
+ await fetchTenantList()
+
+ // 如果获取后仍然没有租户列表,说明无权限
+ if (tenantList.value.length === 0) {
+ return
+ }
+
+ // 如果只有一个租户,自动选中并继续登录流程
+ if (tenantList.value.length === 1) {
+ loginData.loginForm.tenantId = tenantList.value[0].tenantId
+ // 单租户直接继续登录
+ } else {
+ // 如果有多个租户但未选择,提示用户选择
+ if (!loginData.loginForm.tenantId) {
+ message.error('请选择租户')
+ return
+ }
+ }
+ } else if (loginData.tenantEnable === 'true' && tenantList.value.length > 0) {
+ // 已有租户列表,验证是否已选择
+ if (!loginData.loginForm.tenantId) {
+ message.error('请选择租户')
+ return
+ }
+ }
+
// 情况一,未开启:则直接登录
if (loginData.captchaEnable === 'false') {
await handleLogin({})
@@ -156,11 +258,10 @@ const getCode = async () => {
verify.value.show()
}
}
-// 获取租户 ID
-const getTenantId = async () => {
- if (loginData.tenantEnable === 'true') {
- const res = await LoginApi.getTenantIdByName(loginData.loginForm.tenantName)
- authUtil.setTenantId(res)
+// 设置租户ID
+const setTenantId = () => {
+ if (loginData.loginForm.tenantId) {
+ authUtil.setTenantId(loginData.loginForm.tenantId)
}
}
// 记住我
@@ -171,8 +272,7 @@ const getLoginFormCache = () => {
...loginData.loginForm,
username: loginForm.username ? loginForm.username : loginData.loginForm.username,
password: loginForm.password ? loginForm.password : loginData.loginForm.password,
- rememberMe: loginForm.rememberMe,
- tenantName: loginForm.tenantName ? loginForm.tenantName : loginData.loginForm.tenantName
+ rememberMe: loginForm.rememberMe
}
}
}
@@ -182,7 +282,6 @@ const getTenantByWebsite = async () => {
const website = location.host
const res = await LoginApi.getTenantByWebsite(website)
if (res) {
- loginData.loginForm.tenantName = res.name
authUtil.setTenantId(res.id)
}
}
@@ -192,7 +291,7 @@ const loading = ref() // ElLoading.service 返回的实例
const handleLogin = async (params: any) => {
loginLoading.value = true
try {
- await getTenantId()
+ setTenantId()
const data = await validForm()
if (!data) {
return
@@ -236,8 +335,8 @@ const doSocialLogin = async (type: number) => {
} else {
loginLoading.value = true
if (loginData.tenantEnable === 'true') {
- // 尝试先通过 tenantName 获取租户
- await getTenantId()
+ // 尝试先通过 tenantId 获取租户
+ setTenantId()
// 如果获取不到,则需要弹出提示,进行处理
if (!authUtil.getTenantId()) {
try {