|
@@ -18,6 +18,9 @@ import {homeRoutes} from "@/router/index.js";
|
|
|
// 加密密钥 (从环境变量获取)
|
|
// 加密密钥 (从环境变量获取)
|
|
|
const SECRET_KEY = import.meta.env.VITE_SECRET_KEY;
|
|
const SECRET_KEY = import.meta.env.VITE_SECRET_KEY;
|
|
|
|
|
|
|
|
|
|
+// 是否开启租户模式
|
|
|
|
|
+const tenantOpen = import.meta.env.VITE_APP_COMPULSORY_TENANT === 'true';
|
|
|
|
|
+
|
|
|
//需要删除的缓存key列表
|
|
//需要删除的缓存key列表
|
|
|
const CACHE_KEYS_TO_DELETE = [
|
|
const CACHE_KEYS_TO_DELETE = [
|
|
|
'userId',
|
|
'userId',
|
|
@@ -45,7 +48,7 @@ const decryptPassword = (encryptedPassword) => {
|
|
|
const createLoginData = () => {
|
|
const createLoginData = () => {
|
|
|
return ref({
|
|
return ref({
|
|
|
loginForm: {
|
|
loginForm: {
|
|
|
- tenantName: import.meta.env.VITE_APP_DEFAULT_LOGIN_TENANT || '',
|
|
|
|
|
|
|
+ tenantName: tenantOpen ? (import.meta.env.VITE_APP_DEFAULT_LOGIN_TENANT || '') : null,
|
|
|
username: import.meta.env.VITE_APP_DEFAULT_LOGIN_USERNAME || '',
|
|
username: import.meta.env.VITE_APP_DEFAULT_LOGIN_USERNAME || '',
|
|
|
password: import.meta.env.VITE_APP_DEFAULT_LOGIN_PASSWORD || '',
|
|
password: import.meta.env.VITE_APP_DEFAULT_LOGIN_PASSWORD || '',
|
|
|
smsCode: '', // 短信验证码字段
|
|
smsCode: '', // 短信验证码字段
|
|
@@ -91,8 +94,10 @@ const createVerificationCodeLogic = () => {
|
|
|
const getSmsCode = async (tenantId, tenantName, mobile) => {
|
|
const getSmsCode = async (tenantId, tenantName, mobile) => {
|
|
|
sendingCode.value = true
|
|
sendingCode.value = true
|
|
|
try {
|
|
try {
|
|
|
|
|
+ // 构建请求头,只有当 tenantId 存在时才添加 Tenant-Id
|
|
|
|
|
+ const headers = tenantId ? { 'Tenant-Id': tenantId } : {}
|
|
|
const res = await smsCode(
|
|
const res = await smsCode(
|
|
|
- { 'Tenant-Id': tenantId }, {
|
|
|
|
|
|
|
+ headers, {
|
|
|
tenantName,
|
|
tenantName,
|
|
|
mobile,
|
|
mobile,
|
|
|
scene: import.meta.env.VITE_APP_LOGIN_SMS_TEMPLATE_ID,
|
|
scene: import.meta.env.VITE_APP_LOGIN_SMS_TEMPLATE_ID,
|
|
@@ -147,10 +152,13 @@ const loginLogic = async (loginForm, tenantId, isAuthorized, router, redirectPat
|
|
|
loginLoading.value = true
|
|
loginLoading.value = true
|
|
|
try {
|
|
try {
|
|
|
let res
|
|
let res
|
|
|
|
|
+ // 构建请求头,只有当 tenantId 存在时才添加 Tenant-Id
|
|
|
|
|
+ const headers = tenantId ? { 'Tenant-Id': tenantId } : {}
|
|
|
|
|
+
|
|
|
if (!isAuthorized.value) {
|
|
if (!isAuthorized.value) {
|
|
|
// 未授权状态,使用短信验证码登录
|
|
// 未授权状态,使用短信验证码登录
|
|
|
res = await smsLogin(
|
|
res = await smsLogin(
|
|
|
- { 'Tenant-Id': tenantId }, {
|
|
|
|
|
|
|
+ headers, {
|
|
|
mobile: loginForm.phoneNumber,
|
|
mobile: loginForm.phoneNumber,
|
|
|
code: loginForm.smsCode,
|
|
code: loginForm.smsCode,
|
|
|
}
|
|
}
|
|
@@ -159,7 +167,7 @@ const loginLogic = async (loginForm, tenantId, isAuthorized, router, redirectPat
|
|
|
// 授权状态,使用账号密码登录
|
|
// 授权状态,使用账号密码登录
|
|
|
// 传输时使用明文密码,确保后端能正确处理
|
|
// 传输时使用明文密码,确保后端能正确处理
|
|
|
res = await login(
|
|
res = await login(
|
|
|
- { 'Tenant-Id': tenantId },
|
|
|
|
|
|
|
+ headers,
|
|
|
loginForm
|
|
loginForm
|
|
|
)
|
|
)
|
|
|
}
|
|
}
|
|
@@ -175,14 +183,14 @@ const loginLogic = async (loginForm, tenantId, isAuthorized, router, redirectPat
|
|
|
// 存储登录状态
|
|
// 存储登录状态
|
|
|
localStorage.setItem('isLoggedIn', 'true')
|
|
localStorage.setItem('isLoggedIn', 'true')
|
|
|
localStorage.setItem('token', res.data.accessToken)
|
|
localStorage.setItem('token', res.data.accessToken)
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 登录成功后存储用户ID
|
|
// 登录成功后存储用户ID
|
|
|
if (res.data.userId) {
|
|
if (res.data.userId) {
|
|
|
localStorage.setItem('userId', res.data.userId)
|
|
localStorage.setItem('userId', res.data.userId)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 总是存储用户名和租户名称
|
|
// 总是存储用户名和租户名称
|
|
|
- localStorage.setItem('tenantName', loginForm.tenantName)
|
|
|
|
|
|
|
+ localStorage.setItem('tenantName', res.data.tenantName)
|
|
|
// 存储记住我状态
|
|
// 存储记住我状态
|
|
|
localStorage.setItem('rememberMe', loginForm.rememberMe)
|
|
localStorage.setItem('rememberMe', loginForm.rememberMe)
|
|
|
|
|
|
|
@@ -212,6 +220,7 @@ const loginLogic = async (loginForm, tenantId, isAuthorized, router, redirectPat
|
|
|
} else if (res.code === 1002000009) {
|
|
} else if (res.code === 1002000009) {
|
|
|
// 未授权状态,切换到短信验证码登录
|
|
// 未授权状态,切换到短信验证码登录
|
|
|
ElMessage.warning(res.msg || '登录IP未被授权,请使用手机号短信验证码登录!')
|
|
ElMessage.warning(res.msg || '登录IP未被授权,请使用手机号短信验证码登录!')
|
|
|
|
|
+ loginForm.phoneNumber = res.data?.mobile
|
|
|
isAuthorized.value = false
|
|
isAuthorized.value = false
|
|
|
return false
|
|
return false
|
|
|
} else {
|
|
} else {
|
|
@@ -237,7 +246,7 @@ const loadLoginData = (loginData) => {
|
|
|
const storedPassword = localStorage.getItem('password')
|
|
const storedPassword = localStorage.getItem('password')
|
|
|
|
|
|
|
|
// 恢复登录信息到输入框
|
|
// 恢复登录信息到输入框
|
|
|
- if (storedTenantName) {
|
|
|
|
|
|
|
+ if (tenantOpen && storedTenantName) {
|
|
|
loginData.value.loginForm.tenantName = storedTenantName
|
|
loginData.value.loginForm.tenantName = storedTenantName
|
|
|
}
|
|
}
|
|
|
if (storedUserName) {
|
|
if (storedUserName) {
|
|
@@ -272,21 +281,27 @@ const generateRules = (isAuthorized) => {
|
|
|
return computed(() => {
|
|
return computed(() => {
|
|
|
if (isAuthorized.value) {
|
|
if (isAuthorized.value) {
|
|
|
// 授权状态:需要账号和密码
|
|
// 授权状态:需要账号和密码
|
|
|
- return {
|
|
|
|
|
- tenantName: [{ required: true, message: '请输入学校名称', trigger: 'blur' }],
|
|
|
|
|
|
|
+ const rules = {
|
|
|
username: [{ required: true, message: '请输入账号', trigger: 'blur' }],
|
|
username: [{ required: true, message: '请输入账号', trigger: 'blur' }],
|
|
|
password: [{ required: true, message: '请输入密码', trigger: 'blur' }]
|
|
password: [{ required: true, message: '请输入密码', trigger: 'blur' }]
|
|
|
}
|
|
}
|
|
|
|
|
+ if (tenantOpen) {
|
|
|
|
|
+ rules.tenantName = [{ required: true, message: '请输入学校名称', trigger: 'blur' }]
|
|
|
|
|
+ }
|
|
|
|
|
+ return rules
|
|
|
} else {
|
|
} else {
|
|
|
// 未授权状态:需要手机号和短信验证码
|
|
// 未授权状态:需要手机号和短信验证码
|
|
|
- return {
|
|
|
|
|
- tenantName: [{ required: true, message: '请输入学校名称', trigger: 'blur' }],
|
|
|
|
|
|
|
+ const rules = {
|
|
|
phoneNumber: [
|
|
phoneNumber: [
|
|
|
{ required: true, message: '请输入手机号', trigger: 'blur' },
|
|
{ required: true, message: '请输入手机号', trigger: 'blur' },
|
|
|
{ pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号格式', trigger: 'blur' }
|
|
{ pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号格式', trigger: 'blur' }
|
|
|
],
|
|
],
|
|
|
smsCode: [{ required: true, message: '请输入短信验证码', trigger: 'blur' }]
|
|
smsCode: [{ required: true, message: '请输入短信验证码', trigger: 'blur' }]
|
|
|
}
|
|
}
|
|
|
|
|
+ if (tenantOpen) {
|
|
|
|
|
+ rules.tenantName = [{ required: true, message: '请输入学校名称', trigger: 'blur' }]
|
|
|
|
|
+ }
|
|
|
|
|
+ return rules
|
|
|
}
|
|
}
|
|
|
})
|
|
})
|
|
|
}
|
|
}
|
|
@@ -302,16 +317,19 @@ const autoLogin = async (tenantName, username, password, router, redirectPath) =
|
|
|
background: 'rgba(0, 0, 0, 0.7)'
|
|
background: 'rgba(0, 0, 0, 0.7)'
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
- // 获取租户ID
|
|
|
|
|
- const tenantId = await getTenantId(tenantName)
|
|
|
|
|
|
|
+ // 获取租户ID,只有当 tenantOpen 为 true 时才获取
|
|
|
|
|
+ let tenantId = await getTenantId(tenantName)
|
|
|
if (!tenantId) {
|
|
if (!tenantId) {
|
|
|
// 租户验证失败
|
|
// 租户验证失败
|
|
|
return false
|
|
return false
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ // 构建请求头,只有当 tenantId 存在时才添加 Tenant-Id
|
|
|
|
|
+ const headers = tenantId ? { 'Tenant-Id': tenantId } : {}
|
|
|
|
|
+
|
|
|
// 执行登录
|
|
// 执行登录
|
|
|
const res = await login(
|
|
const res = await login(
|
|
|
- { 'Tenant-Id': tenantId },
|
|
|
|
|
|
|
+ headers,
|
|
|
{ tenantName, username, password }
|
|
{ tenantName, username, password }
|
|
|
)
|
|
)
|
|
|
|
|
|