|
|
@@ -3,27 +3,51 @@
|
|
|
<div class="login-content">
|
|
|
<!-- 登录输入框 -->
|
|
|
<div class="login-input">
|
|
|
- <div class="input-item">
|
|
|
- <el-input v-model="loginData.loginForm.tenantName" :prefix-icon="HomeFilled" placeholder="租户" />
|
|
|
- <el-input v-model="loginData.loginForm.username" :prefix-icon="Avatar" placeholder="账号" />
|
|
|
- <el-input
|
|
|
- v-model="loginData.loginForm.password"
|
|
|
- type="password"
|
|
|
- :prefix-icon="Lock"
|
|
|
- placeholder="密码"
|
|
|
- show-password
|
|
|
- />
|
|
|
+ <el-form
|
|
|
+ ref="loginFormRef"
|
|
|
+ :model="loginData.loginForm"
|
|
|
+ :rules="rules"
|
|
|
+ label-width="0px"
|
|
|
+ class="input-item"
|
|
|
+ >
|
|
|
+ <el-form-item prop="tenantName">
|
|
|
+ <el-input
|
|
|
+ v-model="loginData.loginForm.tenantName"
|
|
|
+ :prefix-icon="HomeFilled"
|
|
|
+ placeholder="租户"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item prop="username">
|
|
|
+ <el-input
|
|
|
+ v-model="loginData.loginForm.username"
|
|
|
+ :prefix-icon="Avatar"
|
|
|
+ placeholder="账号"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item prop="password">
|
|
|
+ <el-input
|
|
|
+ v-model="loginData.loginForm.password"
|
|
|
+ type="password"
|
|
|
+ :prefix-icon="Lock"
|
|
|
+ placeholder="密码"
|
|
|
+ show-password
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
<!-- 多选框 -->
|
|
|
<div class="check-box">
|
|
|
- <el-checkbox v-model="loginData.loginForm.rememberMe" label="记住我" size="large" />
|
|
|
+ <el-checkbox
|
|
|
+ v-model="loginData.loginForm.rememberMe"
|
|
|
+ label="记住我"
|
|
|
+ size="large"
|
|
|
+ />
|
|
|
<a href="javascript:;" class="forgot-password">忘记密码?</a>
|
|
|
</div>
|
|
|
|
|
|
<!-- 登录按钮 -->
|
|
|
- <el-button type="primary"
|
|
|
- @click="handleLogin">登录</el-button>
|
|
|
-
|
|
|
- </div>
|
|
|
+ <el-form-item>
|
|
|
+ <el-button type="primary" @click="handleLogin">登录</el-button>
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
</div>
|
|
|
</div>
|
|
|
</template>
|
|
|
@@ -32,71 +56,121 @@
|
|
|
import { ref, onMounted, computed } from 'vue'
|
|
|
import { useRouter } from 'vue-router'
|
|
|
import { HomeFilled, Avatar, Lock } from '@element-plus/icons-vue'
|
|
|
-import { ElLoading } from 'element-plus'
|
|
|
-import {getTenantIdByName, login} from "@/api/login/login.js";
|
|
|
+import { getTenantIdByName, login } from '@/api/login/login.js'
|
|
|
+import { ElLoading, ElMessage } from 'element-plus'
|
|
|
const router = useRouter()
|
|
|
|
|
|
+const loginFormRef = ref(null)
|
|
|
+
|
|
|
const loginData = ref({
|
|
|
tenantEnable: true,
|
|
|
loginForm: {
|
|
|
tenantName: '博雅智算',
|
|
|
username: 'admin',
|
|
|
- password: '',
|
|
|
+ password: 'admin123',
|
|
|
captchaVerification: '',
|
|
|
rememberMe: true // 默认记录我。如果不需要,可手动修改
|
|
|
}
|
|
|
})
|
|
|
|
|
|
const loginLoading = ref(false)
|
|
|
-
|
|
|
const loading = ref() // ElLoading.service 返回的实例
|
|
|
-
|
|
|
const tenantId = ref('')
|
|
|
+// 添加登录状态标识
|
|
|
+const isLoggedIn = ref(false)
|
|
|
+
|
|
|
+// 输入框校验
|
|
|
+const rules = {
|
|
|
+ tenantName: [{ required: true, message: '请输入租户名称', trigger: 'blur' }],
|
|
|
+ username: [{ required: true, message: '请输入账号', trigger: 'blur' }],
|
|
|
+ password: [{ required: true, message: '请输入密码', trigger: 'blur' }]
|
|
|
+}
|
|
|
|
|
|
// 获取租户 ID
|
|
|
const getTenantId = async () => {
|
|
|
if (loginData.value.tenantEnable === true) {
|
|
|
- const res = await getTenantIdByName(loginData.value.loginForm.tenantName)
|
|
|
- //记录租户id
|
|
|
- tenantId.value = res.data
|
|
|
+ try {
|
|
|
+ const res = await getTenantIdByName(loginData.value.loginForm.tenantName)
|
|
|
+ if (res && res.data) {
|
|
|
+ //记录租户id
|
|
|
+ tenantId.value = res.data
|
|
|
+ } else {
|
|
|
+ ElMessage.error('获取租户 ID 失败,请检查租户名称')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ ElMessage.error('获取租户 ID 出错,请重试')
|
|
|
+ console.error('获取租户 ID 错误:', error)
|
|
|
+ return
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
// 登录
|
|
|
-const handleLogin = async (params) => {
|
|
|
- loginLoading.value = true
|
|
|
- try {
|
|
|
+const handleLogin = async params => {
|
|
|
+ if (!loginFormRef.value) return
|
|
|
+ await loginFormRef.value.validate(async valid => {
|
|
|
+ if (valid) {
|
|
|
+ loginLoading.value = true
|
|
|
+ try {
|
|
|
+ await getTenantId()
|
|
|
+ const loginDataLoginForm = { ...loginData.value.loginForm }
|
|
|
+ loginDataLoginForm.captchaVerification = params?.captchaVerification
|
|
|
+ // 构建包含 headers 的请求参数
|
|
|
+ const res = await login(
|
|
|
+ {
|
|
|
+ 'Tenant-Id': tenantId.value
|
|
|
+ },
|
|
|
+ loginDataLoginForm
|
|
|
+ )
|
|
|
+ console.log('登录响应:', res) // 添加日志输出
|
|
|
+ if (!res) {
|
|
|
+ return
|
|
|
+ }
|
|
|
|
|
|
- await getTenantId()
|
|
|
+ //【补充】校验登录状态
|
|
|
+ //成功-失败-提示文字
|
|
|
+ // 校验登录状态,返回数据中 code 为 200 表示成功
|
|
|
+ if (res.code === 200) {
|
|
|
+ ElMessage.success('登录成功')
|
|
|
+ isLoggedIn.value = true
|
|
|
+ // 存储登录状态
|
|
|
+ if (loginData.value.loginForm.rememberMe) {
|
|
|
+ localStorage.setItem('isLoggedIn', 'true')
|
|
|
+ localStorage.setItem('token', res.data.token)
|
|
|
+ }
|
|
|
|
|
|
- //【补充】缺少form表单校验(登录框要改成form表单,并加入必填项,用什么div啊???换掉)
|
|
|
+ loading.value = ElLoading.service({
|
|
|
+ lock: true,
|
|
|
+ text: '正在加载系统中...',
|
|
|
+ background: 'rgba(0, 0, 0, 0.7)'
|
|
|
+ })
|
|
|
|
|
|
- const loginDataLoginForm = { ...loginData.value.loginForm }
|
|
|
- loginDataLoginForm.captchaVerification = params.captchaVerification
|
|
|
- // 构建包含 headers 的请求参数
|
|
|
- const res = await login({
|
|
|
- 'Tenant-Id': tenantId.value
|
|
|
- },loginDataLoginForm);
|
|
|
- if (!res) {
|
|
|
- return
|
|
|
+ // 登录成功后,跳转到指定的页面
|
|
|
+ router.push('/home')
|
|
|
+ } else {
|
|
|
+ ElMessage.error(res.message || '登录失败,请检查账号密码')
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ ElMessage.error('登录出错,请重试')
|
|
|
+ console.error('登录错误:', error)
|
|
|
+ } finally {
|
|
|
+ loginLoading.value = false
|
|
|
+ if (loading.value) {
|
|
|
+ loading.value.close()
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
+ })
|
|
|
+}
|
|
|
|
|
|
- //【补充】校验登录状态
|
|
|
- //成功-失败-提示文字
|
|
|
-
|
|
|
- loading.value = ElLoading.service({
|
|
|
- lock: true,
|
|
|
- text: '正在加载系统中...',
|
|
|
- background: 'rgba(0, 0, 0, 0.7)'
|
|
|
- })
|
|
|
-
|
|
|
- //登录成功后,跳转到指定的页面
|
|
|
+// 在组件挂载时检查登录状态
|
|
|
+onMounted(() => {
|
|
|
+ const storedStatus = localStorage.getItem('isLoggedIn')
|
|
|
+ if (storedStatus === 'true') {
|
|
|
+ isLoggedIn.value = true
|
|
|
router.push('/home')
|
|
|
-
|
|
|
- } finally {
|
|
|
- loginLoading.value = false
|
|
|
- loading.value.close()
|
|
|
}
|
|
|
-}
|
|
|
+})
|
|
|
</script>
|
|
|
|
|
|
<style scoped lang="scss">
|
|
|
@@ -119,7 +193,7 @@ const handleLogin = async (params) => {
|
|
|
.login-input {
|
|
|
width: rpx(210);
|
|
|
height: rpx(240);
|
|
|
- margin: auto;
|
|
|
+ margin: auto;
|
|
|
display: flex;
|
|
|
border-radius: rpx(10);
|
|
|
background-color: rgb(255, 255, 255, 0.3);
|
|
|
@@ -128,9 +202,30 @@ const handleLogin = async (params) => {
|
|
|
}
|
|
|
.input-item {
|
|
|
margin: auto;
|
|
|
- // margin-top: rpx(20);
|
|
|
- // color: white;
|
|
|
- // letter-spacing: rpx(5);
|
|
|
+}
|
|
|
+.input-item .el-form-item {
|
|
|
+ margin-bottom: 0;
|
|
|
+}
|
|
|
+.input-item .el-input {
|
|
|
+ width: rpx(180);
|
|
|
+ height: rpx(18);
|
|
|
+ margin-bottom: rpx(15);
|
|
|
+}
|
|
|
+.el-form-item ::v-deep(.el-form-item__error) {
|
|
|
+ top: 0;
|
|
|
+ padding-top: rpx(20);
|
|
|
+}
|
|
|
+.input-item .el-button {
|
|
|
+ width: rpx(180);
|
|
|
+ height: rpx(18);
|
|
|
+ color: black;
|
|
|
+ font-size: rpx(8);
|
|
|
+ letter-spacing: rpx(10);
|
|
|
+ border-radius: rpx(3);
|
|
|
+ margin: auto;
|
|
|
+ border: none;
|
|
|
+ background: linear-gradient(to bottom, #fee78a, #ffce1b);
|
|
|
+ box-shadow: 0 8px 8px rgb(0, 0, 0, 0.2);
|
|
|
}
|
|
|
.input-item .el-input {
|
|
|
width: rpx(180);
|
|
|
@@ -157,7 +252,7 @@ const handleLogin = async (params) => {
|
|
|
justify-content: space-between;
|
|
|
align-items: center;
|
|
|
}
|
|
|
-.check-box .el-checkbox{
|
|
|
+.check-box .el-checkbox {
|
|
|
color: white;
|
|
|
}
|
|
|
.check-box .forgot-password {
|