Pārlūkot izejas kodu

Merge remote-tracking branch 'origin/master'

# Conflicts:
#	vite.config.js
sys5923812@126.com 2 nedēļas atpakaļ
vecāks
revīzija
91c8c230bd

+ 9 - 0
src/api/xjc-integratedmachine/common/aiChat.js

@@ -0,0 +1,9 @@
+import request from '@/utils/request'
+
+export function getAiChatRecordList(data) {
+    return request({
+        url: '/ai/chat/list',
+        method: 'get',
+        params : data
+    })
+}

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 5 - 0
src/assets/icons/svg/password_login.svg


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 5 - 0
src/assets/icons/svg/user_login.svg


BIN
src/assets/images/login/cognize.png


BIN
src/assets/images/login/decision.png


BIN
src/assets/images/login/environment.png


BIN
src/assets/images/login/home-login-left-background.png


BIN
src/assets/images/login/login-home-background.png


BIN
src/assets/images/login/login-page-background.png


BIN
src/assets/images/login/login-return.png


BIN
src/assets/images/login/plan.png


BIN
src/assets/images/login/wakeup.png


+ 90 - 37
src/layout/index.vue

@@ -1,19 +1,35 @@
 <template>
-    <div class="main">
-        <div class="top">
-            <img src="@/assets/images/index/0.png">
+    <div class="main home-login-page">
+        <div class="page-left">
+          <div class="page-left-style"></div>
+          <div class="page-left-text">数字化生涯学习一体机</div>
+          <div class="page-left-text-box">
+            <p>数字资源智能交互</p>
+            <p>唤醒学生生涯意识</p>
+            <p>一体融合深入互动</p>
+            <p>认知自我明晰路径</p>
+            <p>体验平台加强探索</p>
+            <p>助力学业稳步成功</p>
+            <p>全程辅导精准决策</p>
+            <p>规划行动促进成长</p>
+          </div>
         </div>
-        <div class="center">
-            <div class="c1">
-                <img src="@/assets/images/index/1.png">
-                <img src="@/assets/images/index/2.png" @click="indexJump('/xjc-integratedmachine/wakeup/index')">
-                <img src="@/assets/images/index/3.png" @click="indexJump('/xjc-integratedmachine/cognize/index')">
-            </div>
-            <div class="c2">
-                <img src="@/assets/images/index/4.png" @click="indexJump('/xjc-integratedmachine/environment/index')">
-                <img src="@/assets/images/index/5.png" @click="indexJump('/xjc-integratedmachine/decision/index')">
-                <img src="@/assets/images/index/6.png" @click="indexJump('/xjc-integratedmachine/plan/index')">
-            </div>
+        <div class="page-right">
+          <div class="img-box">
+            <img src="@/assets/images/login/wakeup.png" @click="indexJump('/xjc-integratedmachine/wakeup/index')">
+          </div>
+          <div class="img-box">
+            <img src="@/assets/images/login/cognize.png" @click="indexJump('/xjc-integratedmachine/cognize/index')">
+          </div>
+          <div class="img-box">
+            <img src="@/assets/images/login/environment.png" @click="indexJump('/xjc-integratedmachine/environment/index')">
+          </div>
+          <div class="img-box">
+            <img src="@/assets/images/login/decision.png" @click="indexJump('/xjc-integratedmachine/decision/index')">
+          </div>
+          <div class="img-box">
+            <img src="@/assets/images/login/plan.png"  @click="indexJump('/xjc-integratedmachine/plan/index')">
+          </div>
         </div>
     </div>
 </template>
@@ -41,37 +57,74 @@
                 })
             }
         })
-
-
     }
 </script>
 
 <style lang="scss" scoped>
-    .main {
-        align-items: center;
-        display: flex;
-        flex-direction: column;
-    }
 
-    .top {
-        height: 20vh;
+    body,html{
+      margin: 0;
+      padding: 0;
     }
-
-    .center {
+    .home-login-page{
+      width: 1920px;
+      height: 1080px;
+      background: url('@/assets/images/login/login-home-background.png') no-repeat;
+      background-size: 100%;
+      display: flex;
+      .page-left{
+        background: url('@/assets/images/login/home-login-left-background.png') no-repeat;
+        background-size: 100%;
+        width: 483px;
+        height: 1080px;
         display: flex;
-        flex-direction: column;
-        height: 80vh;
-    }
-
-    .c1 {
-        height: 50vh;
+        justify-items: center;
+        align-items: center;
+        position: relative;
+        .page-left-style{
+          width: 24px;
+          height: 596px;
+          background: rgba(61,92,255,0.3);
+          border-radius: 60px 60px 60px 60px;
+          margin-left: 29px;
+        }
+        .page-left-text{
+          font-weight: bold;
+          width: 48px;
+          font-size: 45px;
+          color: #060606;
+          letter-spacing: 4px;
+          text-align: left;
+          position: relative;
+          left: -15px;
+        }
+      }
+      .page-left-text-box{
+        p{
+          font-weight: 400;
+          font-size: 32px;
+          color: #333333;
+          letter-spacing: 3px;
+        }
+      }
+      .page-right{
+        width: 70%;
         display: flex;
-        flex-direction: row;
-    }
+        justify-content:space-around;
+        align-items: center;
+        flex-wrap: wrap;
+        .img-box{
+          width: 330px;
+          height: 400px;
+          margin-left: 35px;
+          margin-right: 35px;
+          img{
+            width: 330px;
+            height: 400px;
+          }
 
-    .c2 {
-        height: 50vh;
-        display: flex;
-        flex-direction: row;
+        }
+
+      }
     }
 </style>

+ 8 - 1
src/router/index.js

@@ -6,6 +6,7 @@ import router_cognize from '@/router/router_cognize.js'
 import router_decision from '@/router/router_decision.js'
 import router_environment from '@/router/router_environment.js'
 import router_plan from '@/router/router_plan.js'
+import router_common from '@/router/router_common.js'
 
 // 公共路由
 export const constantRoutes = [
@@ -20,6 +21,11 @@ export const constantRoutes = [
         path: '/xjc_index',
         component: () => import('@/layout/index'),
     },
+    // //登录首页(门户页面)
+    // {
+    //     path: '/xjc-integratedmachine/login/home_login',
+    //     component: () => import('@/views/xjc-integratedmachine/login/home_login'),
+    // },
     //一体机登录首页
     {
         path: '/xjc-integratedmachine/login/login_index',
@@ -40,6 +46,7 @@ export const constantRoutes = [
         path: '/xjc-integratedmachine/login/student_forgetpass',
         component: () => import('@/views/xjc-integratedmachine/login/student_forgetpass.vue'),
     },
+
     //发送邮件
     {
         path: '/xjc-integratedmachine/components/sendtoemail',
@@ -180,7 +187,7 @@ export const dynamicRoutes = [
     }
 ]
 const routerArrs = [...router_wakeup.router, ...router_cognize.router, ...router_decision.router,
-    ...router_environment.router, ...router_plan.router, ...constantRoutes]
+    ...router_environment.router, ...router_plan.router, ...router_common.router, ...constantRoutes]
 
 /**
  * Note: 路由配置项

+ 1 - 1
src/router/router_common.js

@@ -1,7 +1,7 @@
 const router = [
     //AI智能问答
     {
-        path: '/xjc-integratedmachine/common/ai_chat',
+        path: '/xjc-integratedmachine/common/ai/chat',
         component: () => import('@/views/xjc-integratedmachine/common/ai/chat.vue'),
     },
 

+ 117 - 2
src/views/xjc-integratedmachine/common/ai/chat.vue

@@ -1,7 +1,102 @@
 <template>
-    
+    <div>
+        <div class="content-box">
+            <pre>{{ streamData }}</pre>
+            <span class="dot"></span>
+            <span class="dot"></span>
+        </div>
+
+        <el-button @click="stopMessage">停止回答</el-button>
+    </div>
 </template>
 
+<script setup>
+    import {getAiChatRecordList} from '@/api/xjc-integratedmachine/common/aiChat.js'
+    import { getToken } from '@/utils/auth'
+
+    let data = ref()
+    const streamData = ref(''); // 存储流式数据
+    const isLoading = ref(false); // 加载状态
+    let reader = null; // 读取器实例
+    let controller = null; // AbortController用于中止请求
+
+
+    // 查看所有聊天记录
+    list();
+    function list() {
+        getAiChatRecordList().then(resp =>{
+            console.log(resp)
+            data.value = resp;
+        })
+    }
+
+    const sendMessage = async() => {
+        try{
+            isLoading.value = true;
+            streamData.value = ''; // 清空之前的数据
+
+            // 创建AbortController以便可以中止请求
+            controller = new AbortController();
+
+            // 请求体
+            let form = {
+                "content": "你是谁?"
+            }
+            // 发送fetch请求
+            const response = await fetch('/dev-api/ai/chat/stream', {
+                method: 'POST',
+                headers: {
+                    'Content-Type': 'application/json',
+                    'Authorization': 'Bearer ' + getToken()
+                },
+                body: JSON.stringify(form)
+            });
+
+            // 获取可读流的读取器
+            reader = response.body.getReader();
+            const decoder = new TextDecoder('utf-8');
+
+            // 循环读取流数据
+            while (true) {
+                const { done, value } = await reader.read();
+                if (done) break; // 如果流读取完成则退出循环
+
+                // 解码并追加数据
+                let chunk = decoder.decode(value, { stream: true });
+                chunk = chunk.replace(/\n/g, '').replace(/data:/g, '')
+                streamData.value += chunk;
+            }
+        }catch (error) {
+            // 如果是手动中止,不显示错误
+            if (error.name !== 'AbortError') {
+                console.error('流式读取失败:', error);
+                streamData.value = 'Error: ' + error.message;
+            }
+        } finally {
+            isLoading.value = false;
+        }
+    }
+
+    const stopMessage = () => {
+        if (reader) {
+            // 取消读取
+            reader.cancel().catch(() => {});
+            reader = null;
+        }
+        if (controller) {
+            // 中止请求
+            controller.abort();
+            controller = null;
+        }
+        isLoading.value = false;
+    }
+
+    onMounted(()=>{
+        sendMessage()
+    })
+
+</script>
+
 <script>
     export default {
         name: "chat"
@@ -9,5 +104,25 @@
 </script>
 
 <style scoped>
-
+    .content-box {
+        max-height: 300px;
+        overflow-y: auto;
+        border: 1px solid #eee;
+        padding: 10px;
+        margin-top: 10px;
+        background: #f9f9f9;
+    }
+    pre {
+        white-space: pre-wrap;
+        word-wrap: break-word;
+    }
+    .dot {
+        display: inline-block;
+        margin-left: 5px;
+        width: 8px;
+        height: 8px;
+        background-color: #000000;
+        border-radius: 50%;
+        animation: pulse 1.2s infinite ease-in-out both;
+    }
 </style>

+ 116 - 21
src/views/xjc-integratedmachine/login/index.vue

@@ -1,32 +1,127 @@
 <template>
-
-    <div style="display: flex;flex-direction: column;align-items: center">
-        <el-button @click="jumpTo('/xjc-integratedmachine/login/student_login')">学生登录</el-button>
-        <el-button @click="jumpTo('/xjc-integratedmachine/login/visitor_login')">游客登录</el-button>
-        <div>欢迎访问新基础生涯唤醒一体机
-            www.shengyazhidao.com
+  <div class="login-page">
+    <div class="page-head">
+      <img class="head-icon" src="@/assets/images/login/login-return.png" alt="404" @click="router.go(-1)">
+    </div>
+    <div class="page-content">
+      <div class="content-background">
+        <div class="content-left">
+          <div class="content-form">
+            <p>新基础生涯</p>
+            <p>欢迎访问新基础生涯唤醒一体机</p>
+            <el-button class="btn btn1" @click="jumpTo('/xjc-integratedmachine/login/student_login')" type="primary" size="large">学生登录</el-button>
+            <el-button class="btn btn2" @click="jumpTo('/xjc-integratedmachine/login/visitor_login')" type="primary" size="large">游客登录</el-button>
+          </div>
         </div>
+      </div>
     </div>
-
-
+  </div>
 </template>
 
 <script setup>
-    const router = useRouter()
-    const route = useRoute()
-
-    const params = route.query
-
-    function jumpTo(path) {
-        router.push({
-            path: path,
-            query : {
-                modulePath : params.modulePath
-            }
-        })
+
+const router = useRouter()
+const route = useRoute()
+
+const params = route.query
+
+function jumpTo(path) {
+  router.push({
+    path: path,
+    query : {
+      modulePath : params.modulePath
+    }
+  })
+}
+function jumpReturn(path) {
+  router.push({
+    path: path,
+    query : {
+      modulePath : params.modulePath
     }
+  })
+}
+
 </script>
 
-<style scoped>
+<style scoped lang="scss">
+*{
+  margin: 0;
+  padding: 0;
+}
+.login-page{
+  background: url('@/assets/images/login/login-page-background.png') no-repeat;
+  background-size: 1920px 1080px;
+  z-index:10;
+  width: 100%;
+  height: 1080px;
+
+  .page-head{
+    position: absolute;
+    top: 0;
+    left: 0;
+    width:100%;
+    height: 123px;
+    //border: 1px solid;
+    background: #FFFFFF;
+    display: flex;
+    align-items: center;
+    .head-icon{
+      width: 74px;
+      height: 74px;
+      margin-left: 74px;
+    }
+  }
+  .page-content{
+    //background: #ECF2F6;
+    width: 100%;
+    position: absolute;
+    top: 123px;
+    bottom: 0px;
+    .content-background{
+
+    }
+    .content-left{
+      width: 600px;
+      //height: 100px;
+      //height: 1000px;
+      //border: 1px solid;
+      margin-left: 274px;
+      margin-top: 70px;
+      .content-form{
+        display: flex;
+        flex-direction:column;
+        align-items:center;
+        p:nth-child(1){
+          font-weight: bold;
+          font-size: 48px;
+          color: #414141;
+
+        }
+        p:nth-child(2){
+          font-weight: 300;
+          font-size: 36px;
+          color: #414141;
+          margin-top: 42px;
+        }
+        .btn{
+          margin-top: 97px;
+          width: 400px;
+          height: 150px;
+          ::v-deep.el-button>span{
+            font-size: 36px;
+            font-weight: 500;
+          }
+        }
+        .btn1{
+          background: #5956E9;
+        }
+        .btn2{
+          background: #87B8FF ;
+        }
+      }
+    }
+  }
+}
 
 </style>

+ 219 - 24
src/views/xjc-integratedmachine/login/student_forgetpass.vue

@@ -1,20 +1,82 @@
 <template>
-    身份证号
-    <el-input v-model="form.userName" @input="getSecret"></el-input>
-    新密码
-    <el-input type="password" v-model="form.password"></el-input>
-    确认新密码
-    <el-input type="password" v-model="form.reppassword"></el-input>
-    通过您的密保问题验证身份
-    保密问题
-    <el-input v-model="form.secretQuestion"></el-input>
-    保密答案
-    <el-input v-model="form.secretAnswer"></el-input>
-    <el-button @click="changePass">确认修改</el-button>
+  <div class="login-student-forgetpass-page">
+    <div class="page-head">
+      <img class="head-icon" src="@/assets/login/login-return.png" @click="router.go(-1)" alt="404">
+    </div>
+    <div class="page-content">
+      <div class="content-background">
+        <div class="content-left">
+          <div class="content-form">
+            <p>新基础生涯</p>
+            <p>欢迎访问新基础生涯唤醒一体机</p>
+            <div class="form-box">
+              <p>忘记密码</p>
+              <el-form ref="loginRef" :model="form" :rules="loginRules" class="login-form">
+                <el-form-item prop="userName">
+              <el-input
+                  style="background-color: #F5F9FA;"
+                  v-model="form.userName"
+                  @input="getSecret()"
+                  placeholder="请输入身份证号"
+                  class="form-box-input1"
+              >
+                <template #prefix>
+                  <svg-icon icon-class="user_login" class="el-input__icon input-icon"/>
+                </template>
+              </el-input>
+                </el-form-item>
+                <el-form-item prop="password">
+                  <el-input
+                  style="background-color: #F5F9FA;"
+                  v-model="form.password"
+                  placeholder="请输入新密码"
+                  class="form-box-input1"
+              >
+                <template #prefix>
+                  <svg-icon icon-class="password_login" class="el-input__icon input-icon"/>
+                </template>
+              </el-input>
+                </el-form-item>
+                <el-form-item prop="reppassword">
+               <el-input
+                  style="background-color: #F5F9FA;"
+                  v-model="form.reppassword"
+                  placeholder="请确认新密码"
+                  class="form-box-input1"
+              >
+                <template #prefix>
+                  <svg-icon icon-class="password_login" class="el-input__icon input-icon"/>
+                </template>
+              </el-input>
+                </el-form-item>
+              <p class="form-box-text1">
+                密保问题:{{form.secretQuestion}}
+              </p>
+                <el-form-item prop="secretAnswer">
+                   <el-input
+                  style="background-color: #F5F9FA;"
+                  v-model="form.secretAnswer"
+                  placeholder="请输入答案"
+                  class="form-box-input1"
+              >
+              </el-input>
+                </el-form-item>
+                <div style="display: flex;justify-content: center">
+                  <el-button class="form-box-btn1" @click="changePass">确认修改</el-button>
+                </div>
+              </el-form>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
 </template>
 
 <script setup>
     import {getSecretByUser,changPasswordBySecret} from '@/api/xjc-platform/xjc_index.js'
+    import {login} from "@/api/login.js";
+    import {setToken} from "@/utils/auth.js";
 
     const loading = ref(false)
     const router = useRouter()
@@ -26,9 +88,9 @@
     const form = ref({
         userName: '',
         password: '',
-        reppassowrd: '',
+        reppassword: '',
         secretQuestion: '',
-        secretAnswer: ''
+        secretAnswer: '',
     })
 
     function getSecret() {
@@ -38,25 +100,158 @@
             })
         }
     }
+
+    const loginRules = {
+      userName: [{required: true, trigger: "blur", message: "请输入您的身份证号"}],
+      password: [{required: true, trigger: "blur", message: "请输入您的密码"}],
+      reppassword: [{required: true, trigger: "blur", message: "请再次输入您的密码"}],
+      secretAnswer: [{required: true, trigger: "blur", message: "请输入您的密保问题"}],
+    }
+
     function  changePass() {
-        changPasswordBySecret(form.value).then(resp =>{
+      proxy.$refs.loginRef.validate(valid => {
+        if (valid) {
+          loading.value = true
+          changPasswordBySecret(form.value).then(resp =>{
             proxy.$modal.msgSuccess("修改密码成功")
             //跳转到主页
             router.push({
-                path : '/xjc_login',
-                query :{
-                    userName : form.value.userName,
-                    password : form.value.password,
-                    modulePath : params.modulePath
-                }
+              path : '/xjc-integratedmachine/login/student_login',
+              query :{
+                userName : form.value.userName,
+                password : form.value.password,
+                modulePath : params.modulePath
+              }
             })
-        })
-    }
+          })
+        }
+      })
 
+    }
 
+    function jumpReturn(path) {
+      router.push({
+        path: path,
+        query : {
+          modulePath : params.modulePath
+        }
+      })
+    }
 </script>
 
-<style scoped>
+<style scoped lang="scss">
 
+*{
+  margin: 0;
+  padding: 0;
+}
+.login-student-forgetpass-page{
+  background: url('@/assets/images/login/login-page-background.png') no-repeat;
+  background-size: 1920px 1080px;
+  z-index:10;
+  width: 100%;
+  height: 1080px;
+  .page-head{
+    position: absolute;
+    top: 0;
+    left: 0;
+    width:100%;
+    height: 123px;
+    //border: 1px solid;
+    background: #FFFFFF;
+    display: flex;
+    align-items: center;
+    .head-icon{
+      width: 74px;
+      height: 74px;
+      margin-left: 74px;
+    }
+  }
+  .page-content{
+    //background: #ECF2F6;
+    width: 100%;
+    position: absolute;
+    top: 123px;
+    bottom: 0;
+    .content-left{
+      width: 600px;
+      margin-left: 237px;
+      margin-top: 70px;
+      .content-form{
+        display: flex;
+        flex-direction:column;
+        align-items:center;
+        p:nth-child(1){
+          font-weight: bold;
+          font-size: 48px;
+          color: #414141;
+        }
+        p:nth-child(2){
+          font-weight: 300;
+          font-size: 36px;
+          color: #414141;
+          margin-top: 42px;
+        }
+        .form-box{
+          width: 490px;
+          margin-top: 29px;
+          background: #FFFFFF;
+          display: flex;
+          flex-direction: column;
+          align-items: center;
+          p:nth-child(1){
+            font-weight: 400;
+            font-size: 36px;
+            color: #666666;
+            margin-top: 24px;
+          }
+
+          .form-box-input1{
+            width: 445px;
+            height: 65px;
+            background: #F5F9FA;
+            border-radius: 5px 5px 5px 5px;
+            margin-top: 20px;
+            ::v-deep .el-input__wrapper{
+              background: #F5F9FA;
+              box-shadow: none;
+            }
+          }
+          .form-box-text{
+            font-weight: 400;
+            font-size: 16px;
+            color: #979797;
+            margin-top: 6px;
+          }
+          .form-box-text1{
+            font-weight: 400;
+            font-size: 16px;
+            color: #5956E9;
+            margin-top: 12px;
+          }
 
+          .form-box-btn1{
+            width: 255px;
+            height: 65px;
+            background-color: #5956E9;
+            border-radius: 33px 33px 33px 33px;
+            margin:16px auto 26px;
+            font-weight: 500;
+            font-size: 18px;
+            color: #FFFFFF;
+          }
+          .form-box-btn2{
+            width: 150px;
+            height: 57px;
+            background: #87B8FF;
+            border-radius: 10px 10px 10px 10px;
+            font-size: 16px;
+            color: #FFFFFF;
+          }
+
+        }
+      }
+    }
+  }
+}
 </style>

+ 185 - 41
src/views/xjc-integratedmachine/login/student_login.vue

@@ -1,54 +1,73 @@
 <template>
-
-    <div>
-        <el-form ref="loginRef" :model="loginForm" :rules="loginRules" class="login-form">
-            <h3 class="title">{{ title }}</h3>
-            <el-form-item prop="username">
-                <el-input
+    <div class="student-login-page">
+      <div class="page-head">
+        <img class="head-icon" src="@/assets/images/login/login-return.png" @click="router.go(-1)" alt="404">
+      </div>
+      <div class="page-content">
+        <div class="content-background">
+          <div class="content-left">
+            <div class="content-form">
+              <p>新基础生涯</p>
+              <p>欢迎访问新基础生涯唤醒一体机</p>
+              <div class="form-box">
+                <p>学生登录</p>
+                <el-form ref="loginRef" :model="loginForm" :rules="loginRules" class="login-form">
+                  <el-form-item prop="username">
+                    <el-input
                         v-model="loginForm.username"
                         type="text"
                         size="large"
                         auto-complete="off"
                         placeholder="身份证号"
-                >
-                    <template #prefix>
-                        <svg-icon icon-class="user" class="el-input__icon input-icon"/>
-                    </template>
-                </el-input>
-            </el-form-item>
-            <el-form-item prop="password">
-                <el-input
+                        class="form-box-input1"
+                    >
+                      <template #prefix>
+                        <svg-icon icon-class="user_login" class="el-input__icon input-icon"/>
+                      </template>
+                    </el-input>
+                  </el-form-item>
+                  <el-form-item prop="password">
+                    <el-input
                         v-model="loginForm.password"
                         type="password"
                         size="large"
                         auto-complete="off"
                         placeholder="密码"
+                        show-password
+                        class="form-box-input1"
                         @keyup.enter="handleLogin"
-                >
-                    <template #prefix>
-                        <svg-icon icon-class="password" class="el-input__icon input-icon"/>
-                    </template>
-                </el-input>
-            </el-form-item>
-
-            <el-form-item style="width:100%;">
-                <el-button
-                        :loading="loading"
-                        size="large"
-                        type="primary"
-                        style="width:100%;"
-                        @click.prevent="handleLogin"
-                >
-                    <span v-if="!loading">登 录</span>
-
-                    <span v-else>登 录 中...</span>
-                </el-button>
-                <el-button @click="forgetPass">忘记密码</el-button>
-                <div style="float: right;" v-if="register">
-                    <router-link class="link-type" :to="'/register'">立即注册</router-link>
-                </div>
-            </el-form-item>
-        </el-form>
+                    >
+                      <template #prefix>
+                        <svg-icon icon-class="password_login" class="el-input__icon input-icon"/>
+                      </template>
+                    </el-input>
+                  </el-form-item>
+                  <p class="form-box-text">首次登录请联系班主任获取账号密码</p>
+                  <el-form-item style="width:100%;">
+                    <div style="display: flex;flex-direction: column;width: 100%">
+                      <el-button
+                          :loading="loading"
+                          size="large"
+                          type="primary"
+                          class="form-box-btn1"
+                          @click.prevent="handleLogin"
+                      >
+                        <span v-if="!loading">登 录</span>
+                        <span v-else>登 录 中...</span>
+                      </el-button>
+                      <p class="form-box-text1" @click="forgetPass">
+                        忘记密码?
+                      </p>
+                   </div>
+                  </el-form-item>
+                </el-form>
+              </div>
+
+            </div>
+          </div>
+        </div>
+      </div>
+
     </div>
 </template>
 
@@ -85,11 +104,13 @@
                 loading.value = true
                 // 调用action的登录方法
                 loginForm.value.loginType = "1"
-                login(loginForm.value.username, loginForm.value.password, null, null, loginForm.value.loginType).then(resp => {
+                login(loginForm.value.username, loginForm.value.password, null, null, loginForm.value.loginType)
+                    .then(resp => {
                     setToken(resp.data.access_token)
                     router.push({
                         path: params.modulePath
                     })
+                      console.log("11",resp)
                 })
             }
         })
@@ -104,8 +125,131 @@
         })
     }
 
+    function jumpReturn(path) {
+      router.push({
+        path: path,
+        query : {
+          modulePath : params.modulePath
+        }
+      })
+    }
 </script>
 
-<style scoped>
+<style scoped lang="scss">
+*{
+  margin: 0;
+  padding: 0;
+}
+.student-login-page{
+  background: url('@/assets/images/login/login-page-background.png') no-repeat;
+  background-size: 1920px 1080px;
+  z-index:10;
+  width: 100%;
+  height: 1080px;
+  .page-head{
+    position: absolute;
+    top: 0;
+    left: 0;
+    width:100%;
+    height: 123px;
+    background: #FFFFFF;
+    display: flex;
+    align-items: center;
+    .head-icon{
+      width: 74px;
+      height: 74px;
+      margin-left: 74px;
+    }
+  }
+  .page-content{
+    //background: #ECF2F6;
+    width: 100%;
+    position: absolute;
+    top: 123px;
+    bottom: 0;
+    .content-left{
+      width: 600px;
+      margin-left: 237px;
+      margin-top: 70px;
+      .content-form{
+        display: flex;
+        flex-direction:column;
+        align-items:center;
+        p:nth-child(1){
+          font-weight: bold;
+          font-size: 48px;
+          color: #414141;
+
+        }
+        p:nth-child(2){
+          font-weight: 300;
+          font-size: 36px;
+          color: #414141;
+          margin-top: 42px;
+        }
+        .form-box{
+          width: 490px;
+          margin-top: 29px;
+          background: #FFFFFF;
+          display: flex;
+          flex-direction: column;
+          align-items: center;
+          p:nth-child(1){
+            font-weight: 400;
+            font-size: 36px;
+            color: #666666;
+            margin-top: 24px;
+          }
+
+          .form-box-input1{
+            width: 445px;
+            height: 65px;
+            background: #F5F9FA;
+            border-radius: 5px 5px 5px 5px;
+            margin-top: 20px;
+            ::v-deep .el-input__wrapper{
+              background: #F5F9FA;
+              box-shadow: none;
+            }
+
+
+          }
+          .form-box-text{
+            font-weight: 400;
+            font-size: 16px;
+            color: #979797;
+            margin-top: 6px;
+            text-align: center;
+          }
+          .form-box-text1{
+            font-weight: 400;
+            font-size: 16px;
+            color: #5956E9;
+            margin:9px auto 32px;
+            text-align: center;
+          }
 
+          .form-box-btn1{
+            width: 255px;
+            height: 65px;
+            background-color: #5956E9;
+            border-radius: 33px 33px 33px 33px;
+            margin:16px auto 9px;
+            font-weight: 500;
+            font-size: 18px;
+            color: #FFFFFF;
+          }
+          .form-box-btn2{
+            width: 150px;
+            height: 57px;
+            background: #87B8FF;
+            border-radius: 10px 10px 10px 10px;
+            font-size: 16px;
+            color: #FFFFFF;
+          }
+        }
+      }
+    }
+  }
+}
 </style>

+ 448 - 120
src/views/xjc-integratedmachine/login/visitor_login.vue

@@ -1,144 +1,472 @@
 <template>
-    <div>
-        游客登录
+  <div class="visitor-login-page">
+    <div class="page-head">
+      <img class="head-icon" src="@/assets/images/login/login-return.png" @click="router.go(-1)" alt="404">
     </div>
-    <div v-show="step == 1">
-        手机号
-        <el-input v-model="loginForm.userName"></el-input>
-        <el-button @click="phoneLogin">登录</el-button>
-    </div>
-    <div v-show="step == 2">
-        手机号
-        <el-input v-model="loginForm.userName"></el-input>
-        <el-button @click="getCheckCode">
-            <div v-show="seconds == 60">发送验证码</div>
-            <div v-show="seconds < 60 && seconds >=0">剩余{{seconds}}秒</div>
-        </el-button>
-        验证码
-        <el-input v-model="loginForm.checkCode"></el-input>
-        <el-button @click="validCheckCode">注册</el-button>
-    </div>
-    <div v-show="step == 3">
-        密码
-        <el-input type="password" v-model="loginForm.password"></el-input>
-        再次确认密码
-        <el-input type="password" v-model="loginForm.reppassword"></el-input>
-        高考省份:{{loginForm.areaId}}:{{loginForm.areaName}}
-        <div>
-            <span v-for="dict in gk_province" :key="dict.value" @click="chooseArea(dict.value,dict.label)">{{dict.label}}&nbsp;&nbsp;&nbsp;&nbsp;</span>
+    <div class="page-content">
+      <div class="content-background">
+        <div class="content-left">
+          <div class="content-form">
+            <p>新基础生涯</p>
+            <p>欢迎访问新基础生涯唤醒一体机</p>
+            <div v-show="step === 1" class="form-box">
+              <p>游客登录</p>
+              <el-form ref="loginRef" :model="loginForm" :rules="loginStepOneRules" class="login-form">
+                <el-form-item prop="userName">
+              <el-input
+                  style="background-color: #F5F9FA;"
+                  v-model="loginForm.userName"
+                  placeholder="请输入手机号"
+                  class="form-box-input1"
+              >
+                <template #prefix>
+                  <svg-icon icon-class="user_login" class="el-input__icon input-icon"/>
+                </template>
+              </el-input>
+            </el-form-item>
+              <p class="form-box-text">
+                未检测到该手机号 请先注册
+               </p>
+                <div style="display: flex;justify-content: center">
+                  <el-button class="form-box-btn1" @click="phoneLogin">登录</el-button>
+                </div>
+            </el-form>
+            </div>
+            <div v-show="step === 2" class="form-box">
+              <p>游客登录</p>
+              <el-form ref="loginStepTwoRef" :model="loginForm" :rules="loginStepTwoRules" class="login-form">
+                <el-form-item prop="userName">
+              <el-input
+                  style="background-color: #F5F9FA;"
+                  v-model="loginForm.userName"
+                  placeholder="请输入手机号"
+                  class="form-box-input1"
+              >
+                <template #prefix>
+                  <svg-icon icon-class="user_login" class="el-input__icon input-icon"/>
+                </template>
+                <template #suffix>
+                  <el-button  v-show="seconds === 60" class="form-box-btn2"  @click="getCheckCode">
+                    发送验证码
+                  </el-button>
+                  <el-button class="form-box-btn2" v-show="seconds < 60 && seconds >=0" @click="getCheckCode">
+                    剩余{{seconds}}秒
+                  </el-button>
+                </template>
+              </el-input>
+                </el-form-item>
+                 <el-form-item prop="checkCode">
+                   <el-input
+                       v-model="loginForm.checkCode"
+                       style="background-color: #F5F9FA;"
+                       placeholder="请输入验证码"
+                       class="form-box-input1"
+                   >
+                   </el-input>
+                </el-form-item>
+                {{loginForm.checkCodeText}}
+                <div style="display: flex;justify-content: center">
+                  <el-button class="form-box-btn1" @click="validCheckCode">下一步</el-button>
+                </div>
+              </el-form>
+            </div>
+            <div v-show="step === 3" class="form-box">
+              <p>游客登录</p>
+              <p class="form-box-text">
+                手机号通过验证 请设置密码 下次直接密码登录
+              </p>
+              <el-form ref="loginStepThreeRef" :model="loginForm" :rules="loginStepThreeRules" class="login-form">
+                <el-form-item prop="password">
+              <el-input
+                  style="background-color: #F5F9FA;"
+                  type="password"
+                  v-model="loginForm.password"
+                  placeholder="请输入密码"
+                  class="form-box-input1"
+                  show-password
+              >
+                <template #prefix>
+                  <svg-icon icon-class="password_login" class="el-input__icon input-icon"/>
+                </template>
+              </el-input>
+                </el-form-item>
+                <el-form-item prop="reppassword">
+              <el-input
+                  type="password"
+                  v-model="loginForm.reppassword"
+                  style="background-color: #F5F9FA;"
+                  placeholder="请再次输入密码"
+                  class="form-box-input1"
+                  show-password
+              >
+                <template #prefix>
+                  <svg-icon icon-class="password_login" class="el-input__icon input-icon"/>
+                </template>
+              </el-input>
+                </el-form-item>
+                <el-form-item prop="areaItem">
+              <el-select v-model="loginForm.areaItem"
+                         class="form-box-select"
+                         @change="chooseArea"  placeholder="选择高考省份">
+                <el-option
+                    v-for="item in register_province"
+                    :key="item.value"
+                    :label="item.label"
+                    :value="item">
+                </el-option>
+              </el-select>
+                </el-form-item>
+                <el-form-item prop="sex">
+              <el-select v-model="loginForm.sex"  class="form-box-select"  placeholder="选择性别">
+                <el-option
+                    v-for="item in sys_user_sex"
+                    :key="item.value"
+                    :label="item.label"
+                    :value="item.value">
+                </el-option>
+              </el-select>
+                </el-form-item>
+                <div style="display: flex;justify-content: center">
+                  <el-button class="form-box-btn1" @click="registHandler">注册</el-button>
+                </div>
+              </el-form>
+            </div>
+            <div v-show="step === 4" class="form-box">
+              <p>游客登录</p>
+              <el-form ref="loginStepFourRef" :model="loginForm" :rules="loginStepFourRules" class="login-form">
+                <el-form-item prop="userName">
+              <el-input
+                  style="background-color: #F5F9FA;"
+                  v-model="loginForm.userName"
+                  placeholder="请输入手机号"
+                  class="form-box-input1"
+              >
+                <template #prefix>
+<!--                  <el-icon class="el-input__icon"><user /></el-icon>-->
+                  <svg-icon icon-class="user_login" class="el-input__icon input-icon"/>
+                </template>
+              </el-input>
+                </el-form-item>
+                <el-form-item prop="password">
+              <el-input
+                  v-model="loginForm.password"
+                  style="background-color: #F5F9FA;"
+                  placeholder="请输入密码"
+                  class="form-box-input1"
+                  show-password
+              >
+                <template #prefix>
+                  <svg-icon icon-class="password_login" class="el-input__icon input-icon"/>
+                </template>
+              </el-input>
+                </el-form-item>
+              <p class="form-box-text">
+                检测您已使用到该手机号注册 请使用密码登录
+              </p>
+              <div style="display: flex;flex-direction: column;width: 100%">
+                <el-button class="form-box-btn1" @click="visitor_login">登录</el-button>
+<!--                <p class="form-box-text1" >-->
+<!--                  忘记密码?-->
+<!--                </p>-->
+              </div>
+              </el-form>
+            </div>
+          </div>
         </div>
-        <el-button @click="registHandler">注册</el-button>
-    </div>
-    <div v-show="step == 4">
-        手机号
-        <el-input v-model="loginForm.userName"></el-input>
-        密码
-        <el-input v-model="loginForm.password" type="password"></el-input>
-        <el-button @click="visitor_login">登录</el-button>
+      </div>
     </div>
-
+  </div>
 </template>
 
 <script setup>
 
-    import {getUserInfo, sendCheckCode, validCheckCodeAndRegister,regist} from '@/api/xjc-platform/xjc_index.js'
-    import {login} from '@/api/login'
-    import { setToken } from '@/utils/auth'
-    const loading = ref(false)
-    const router = useRouter()
-    const route = useRoute()
-    const {proxy} = getCurrentInstance()
-    const {rank, gk_province} = proxy.useDict('rank', 'gk_province')
-    const params = route.query
-    //1手机号 2-验证码注册 3-设置密码和省份
-
-    const step = ref(1)
-    const seconds = ref(60)
-
-
-
-    const loginForm = ref({
-        userName: '',
-        //一体机用户手机注册
-        businessType: '1',
-        checkCode: '',
-        areaId:null,
-        areaName: null,
-        password : '',
-        reppassword :''
-    })
-
-    function phoneLogin() {
-        getUserInfo(loginForm.value.userName).then(resp => {
-            if (resp.sysUser == null) {
-                //没有此人,需要注册
-                step.value = 2
-            } else {
-                step.value = 4
-            }
-        })
-    }
+import {getUserInfo, sendCheckCode, validCheckCodeAndRegister,regist} from '@/api/xjc-platform/xjc_index.js'
+import {login} from '@/api/login'
+import { setToken } from '@/utils/auth'
+const loading = ref(false)
+const router = useRouter()
+const route = useRoute()
+const {proxy} = getCurrentInstance()
+const {rank, gk_province,sys_user_sex,register_province} = proxy.useDict('rank', 'gk_province','sys_user_sex','register_province')
+const params = route.query
+//1手机号 2-验证码注册 3-设置密码和省份
+
+const step = ref(1)
+const seconds = ref(60)
 
-    function getCheckCode() {
-        sendCheckCode(loginForm.value).then(resp => {
-            console.log("一体机注册,验证码:", resp.checkCode)
-            //开始倒计数
-            secondsBegin()
-        })
-    }
 
-    function secondsBegin() {
-        seconds.value--;
-        if (seconds.value > 0) {
-            window.setTimeout(secondsBegin, 1000)
+
+const loginForm = ref({
+  userName: '',
+  //一体机用户手机注册
+  businessType: '1',
+  checkCode: '',
+  areaId:null,
+  areaName: null,
+  areaItem:null,
+  password : '',
+  reppassword :'',
+  sex:null,
+  checkCodeText:'',
+})
+
+const loginStepOneRules = {
+  userName: [{required: true, trigger: "blur", message: "请输入您的手机号"}]
+}
+const loginStepTwoRules = {
+  userName: [{required: true, trigger: "blur", message: "请输入您的手机号"}],
+  checkCode : [{required: true, trigger: "blur", message: "请输入验证码"}],
+}
+const loginStepThreeRules = {
+  password: [{required: true, trigger: "blur", message: "请输入密码"}],
+  reppassword: [{required: true, trigger: "blur", message: "请再次输入密码"}],
+  sex: [{required: true, trigger: "blur", message: "请选择性别"}],
+  areaItem: [{required: true, trigger: "blur", message: "请选择高考省份"}]
+}
+const loginStepFourRules = {
+  userName: [{required: true, trigger: "blur", message: "请输入您的手机号"}],
+  password: [{required: true, trigger: "blur", message: "请输入密码"}],
+}
+
+function phoneLogin() {
+  proxy.$refs.loginRef.validate(valid => {
+    if (valid) {
+      loading.value = true
+      getUserInfo(loginForm.value.userName).then(resp => {
+        if (resp.sysUser == null) {
+          //没有此人,需要注册
+          step.value = 2
         } else {
-            seconds.value = 60
+          step.value = 4
+        }
+      })
+    }
+  })
+}
+
+function getCheckCode() {
+  sendCheckCode(loginForm.value).then(resp => {
+    console.log("一体机注册,验证码:", resp.checkCode)
+    loginForm.value.checkCodeText =  resp.checkCode
+
+        //开始倒计数
+    secondsBegin()
+  })
+}
+
+function secondsBegin() {
+  seconds.value--;
+  if (seconds.value > 0) {
+    window.setTimeout(secondsBegin, 1000)
+  } else {
+    seconds.value = 60
+  }
+}
+
+function validCheckCode() {
+  proxy.$refs.loginStepTwoRef.validate(valid => {
+    if (valid) {
+      loading.value = true
+      validCheckCodeAndRegister(loginForm.value).then(resp => {
+        if (resp.codeValidResult == true) {
+          step.value = 3
         }
+      })
     }
+  })
 
-    function validCheckCode() {
-        validCheckCodeAndRegister(loginForm.value).then(resp => {
-            if (resp.codeValidResult == true) {
-                step.value = 3
+}
+function chooseArea(val) {
+  console.log("loginForm.value--",loginForm.value,val.target)
+  loginForm.value.areaId = loginForm.value.areaItem.value
+  loginForm.value.areaName = loginForm.value.areaItem.label
+  console.log("loginForm.value",loginForm.value)
+}
+
+
+function registHandler() {
+  proxy.$refs.loginStepThreeRef.validate(valid => {
+    if (valid) {
+      loading.value = true
+      if(loginForm.value.password != loginForm.value.reppassword){
+        proxy.$modal.msgError("密码不一致")
+      }else{
+        regist(loginForm.value).then(resp =>{
+          proxy.$modal.msgSuccess("注册成功")
+          //跳转到主页
+          router.push({
+            path : '/xjc_login',
+            query :{
+              userName : loginForm.value.userName,
+              password : loginForm.value.password,
+              modulePath : params.modulePath
             }
+          })
         })
+      }
     }
-    function chooseArea(areaId,areaName) {
-        loginForm.value.areaId = areaId
-        loginForm.value.areaName = areaName
+  })
+
+}
+function visitor_login(){
+  loading.value = true
+  // 调用action的登录方法
+  loginForm.value.loginType = "1"
+  proxy.$refs.loginStepFourRef.validate(valid => {
+    if (valid) {
+      loading.value = true
+      login(loginForm.value.userName, loginForm.value.password, null, null, loginForm.value.loginType).then(resp => {
+        setToken(resp.data.access_token)
+        router.push({
+          path: params.modulePath
+        })
+      })
     }
-    function registHandler() {
-        if(loginForm.value.password != loginForm.value.reppassword){
-            proxy.$modal.msgError("密码不一致")
-        }else{
-            regist(loginForm.value).then(resp =>{
-                proxy.$modal.msgSuccess("注册成功")
-                //跳转到主页
-                router.push({
-                    path : '/xjc_login',
-                    query :{
-                        userName : loginForm.value.userName,
-                        password : loginForm.value.password,
-                        modulePath : params.modulePath
-                    }
-                })
-            })
-        }
+  })
+}
+function jumpReturn(path) {
+  router.push({
+    path: path,
+    query : {
+      modulePath : params.modulePath
     }
-    function visitor_login(){
-        loading.value = true
-        // 调用action的登录方法
-        loginForm.value.loginType = "1"
-        login(loginForm.value.userName, loginForm.value.password, null, null, loginForm.value.loginType).then(resp => {
-            setToken(resp.data.access_token)
-            router.push({
-                path: params.modulePath
-            })
-        })
+  })
+}
+</script>
+
+<style scoped lang="scss">
+div,p,input{
+  margin: 0;
+  padding: 0;
+}
+.visitor-login-page{
+  background: url('@/assets/images/login/login-page-background.png') no-repeat;
+  background-size: 1920px 1080px;
+  z-index:10;
+  width: 100%;
+  height: 1080px;
+  .page-head{
+    position: absolute;
+    top: 0;
+    left: 0;
+    width:100%;
+    height: 123px;
+    background: #FFFFFF;
+    display: flex;
+    align-items: center;
+    .head-icon{
+      width: 74px;
+      height: 74px;
+      margin-left: 74px;
     }
+  }
+  .page-content{
+    width: 100%;
+    position: absolute;
+    top: 123px;
+    bottom: 0;
+    .content-left{
+      width: 600px;
+      margin-left: 237px;
+      margin-top: 70px;
+      .content-form{
+        display: flex;
+        flex-direction:column;
+        align-items:center;
+        p:nth-child(1){
+          font-weight: bold;
+          font-size: 48px;
+          color: #414141;
+        }
+        p:nth-child(2){
+          font-weight: 300;
+          font-size: 36px;
+          color: #414141;
+          margin-top: 42px;
+        }
+        .form-box{
+          width: 490px;
+          margin-top: 29px;
+          background: #FFFFFF;
+          display: flex;
+          flex-direction: column;
+          align-items: center;
+          p:nth-child(1){
+            font-weight: 400;
+            font-size: 36px;
+            color: #666666;
+            margin-top: 24px;
+          }
 
-</script>
+          .form-box-input1{
+            width: 445px;
+            height: 65px;
+            background: #F5F9FA;
+            border-radius: 5px 5px 5px 5px;
+            margin-top: 20px;
+            ::v-deep .el-input__wrapper{
+              background: #F5F9FA;
+              box-shadow: none;
+            }
+          }
+          .form-box-select {
+            width: 446px;
+            height: 65px;
+            background: #F5F9FA;
+            border-radius: 5px 5px 5px 5px;
+            margin-top: 20px;
 
-<style scoped>
+            ::v-deep .el-select__wrapper {
+              height: 65px;
+              background: #F5F9FA;
+              box-shadow: none;
+            }
+
+            ::v-deep .el-select-dropdown__item {
+              text-align: left; /* 或者 center,根据需要调整 */
+              padding-left: 30px !important;
+            }
+            ::v-deep .el-select-dropdown__item {
+              text-align: center !important; /* 使用 !important 来确保样式覆盖 */
+            }
+          }
+          .form-box-text{
+            font-weight: 400;
+            font-size: 16px;
+            color: #979797;
+            margin-top: 10px;
+            text-align: center;
+          }
+          .form-box-text1{
+            font-weight: 400;
+            font-size: 16px;
+            color: #5956E9;
+            margin-top: 9px;
+            text-align: center;
+          }
+          .form-box-btn1{
+            width: 255px;
+            height: 65px;
+            background-color: #5956E9;
+            border-radius: 33px 33px 33px 33px;
+            margin:16px auto 26px;
+            font-weight: 500;
+            font-size: 18px;
+            color: #FFFFFF;
+          }
+          .form-box-btn2{
+            width: 150px;
+            height: 57px;
+            background: #87B8FF;
+            border-radius: 10px 10px 10px 10px;
+            font-size: 16px;
+            color: #FFFFFF;
+          }
+
+        }
+      }
+    }
+  }
+}
 
 </style>