丸子 9 сар өмнө
parent
commit
667820b0a7

+ 1 - 3
package-lock.json

@@ -3578,7 +3578,6 @@
       "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==",
       "license": "MIT"
     },
-<<<<<<< HEAD
     "node_modules/js-tokens": {
       "version": "4.0.0",
       "resolved": "https://registry.npmmirror.com/js-tokens/-/js-tokens-4.0.0.tgz",
@@ -3609,14 +3608,13 @@
         "node": ">=6"
       }
     },
-=======
+
     "node_modules/jsencrypt": {
       "version": "3.3.2",
       "resolved": "https://registry.npmjs.org/jsencrypt/-/jsencrypt-3.3.2.tgz",
       "integrity": "sha512-arQR1R1ESGdAxY7ZheWr12wCaF2yF47v5qpB76TtV64H1pyGudk9Hvw8Y9tb/FiTIaaTRUyaSnm5T/Y53Ghm/A==",
       "license": "MIT"
     },
->>>>>>> dd4215d99894177fa83288566bef197bc3f222ab
     "node_modules/linkify-it": {
       "version": "5.0.0",
       "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz",

+ 1 - 1
src/api/questions.js

@@ -23,7 +23,7 @@ export async function sendChatMessageStream (
     onError,
     onClose
 ) {
-  return fetchEventSource(`http://59.110.91.129/admin-api/bjdxWeb/ai/dialogue-send-stream`, {
+  return fetchEventSource(`http://59.110.91.129:8080/admin-api/bjdxWeb/ai/dialogue-send-stream`, {
     method: 'post',
     headers: {
       'Content-Type': 'application/json',

+ 2 - 2
src/utils/request.js

@@ -17,8 +17,8 @@ const request = axios.create({
   // 它可以通过设置一个 `baseURL` 便于为 axios 实例的方法传递相对 URL
   // baseURL: isDev ? 'http://121.89.205.189:3000/admin' : 'http://121.89.205.189:3000/admin',
   //  baseURL: 'http://59.110.91.129:3000',
-  baseURL: 'http://192.168.110.8:8080/admin-api',
-  // baseURL: 'http://59.110.91.129/admin-api',
+  // baseURL: 'http://192.168.110.8:8080/admin-api',
+  baseURL: 'http://59.110.91.129/admin-api',
   // baseURL: 'http://127.0.0.1:8080/admin-api',/
 
   // baseURL: '/api',

+ 0 - 136
src/views/AILogin.vue

@@ -1,136 +0,0 @@
-<template>
-  <!-- 登录页面 -->
-  <div class="login-content">
-    <!-- 登录输入框 -->
-    <div class="login-input">
-      <div class="input-item">
-        <h2>AI课程</h2>
-        <el-input
-          v-model="tenant"
-          :prefix-icon="HomeFilled"
-          placeholder="租户"
-        />
-        <el-input v-model="account" :prefix-icon="Avatar" placeholder="账号" />
-        <el-input
-          v-model="password"
-          type="password"
-          :prefix-icon="Lock"
-          placeholder="密码"
-          show-password
-        />
-        <!-- 多选框 -->
-        <div class="check-box">
-          <el-checkbox v-model="checked" label="记住我" size="large" />
-          <a href="javascript:;" class="forgot-password">忘记密码?</a>
-        </div>
-
-        <!-- 登录按钮 -->
-        <el-button @click="LoginClick" type="primary">登录</el-button>
-      </div>
-    </div>
-  </div>
-</template>
-
-<script setup>
-import { ref, onMounted, computed } from 'vue'
-import { useRouter } from 'vue-router'
-import { HomeFilled, Avatar, Lock } from '@element-plus/icons-vue'
-import { TenantName } from '@/api/login.js'
-
-// 租户
-const tenant = ref('')
-// 账号
-const account = ref('')
-// 密码
-const password = ref('')
-// 选框
-const checked = ref()
-
-// 获取当前路由对象
-const router = useRouter()
-// 点击登录跳转首页
-const LoginClick = () => {
-  router.push('/home')
-}
-
-// 租户
-// const tenantName = 'exampleName'
-
-// TenantName({ name: tenantName }).then(res => {
-//   console.log('获取到的租户ID:', res.data)
-// }).catch(error => {
-//   console.error('获取租户ID失败:', error)
-// })
-
-</script>
-
-<style scoped lang="scss">
-@use 'sass:math';
-// 定义rpx转换函数
-@function rpx($px) {
-  @return math.div($px, 750) * 100vw;
-}
-.login-content {
-  position: fixed;
-  top: 0;
-  left: 0;
-  right: 0;
-  bottom: 0;
-  background: linear-gradient(to bottom, #001169, #8a78d0);
-  display: flex;
-  flex-direction: column;
-  gap: rpx(0);
-}
-.login-input {
-  width: rpx(200);
-  height: rpx(240);
-  margin: auto;
-  display: flex;
-  border-radius: rpx(10);
-  background-color: rgb(255, 255, 255, 0.3);
-  border: 1px white solid;
-  box-shadow: 0 8px 8px rgb(0, 0, 0, 0.3);
-}
-.input-item {
-  margin: auto;
-  margin-top: rpx(20);
-  color: white;
-}
-.input-item .el-input {
-  width: rpx(160);
-  height: rpx(18);
-  margin-bottom: rpx(15);
-}
-.input-item .el-button {
-  width: rpx(160);
-  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);
-}
-.input-item .el-button:hover,
-.input-item .el-button:focus,
-.input-item .el-button:active {
-  box-shadow: 0 8px 8px rgb(0, 0, 0, 0.2);
-}
-.check-box {
-  width: rpx(160);
-  height: rpx(18);
-  margin: auto;
-  display: flex;
-  justify-content: space-between;
-  align-items: center;
-}
-.check-box .el-checkbox {
-  color: white;
-}
-.check-box .forgot-password {
-  color: white;
-  font-size: rpx(6);
-  text-decoration: none;
-}
-</style>

+ 151 - 56
src/views/Login.vue

@@ -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 {

+ 1 - 2
vite.config.js

@@ -23,9 +23,8 @@ export default defineConfig({
   server: {
     host: '0.0.0.0',
     proxy: {
-
       '/admin-api': {
-        target: 'https://192.168.110.8:8080',
+        target: 'http://59.110.91.129',
         changeOrigin: true
       }
     }