chenrong пре 1 година
родитељ
комит
e53fd37285

+ 13 - 10
src/App.vue

@@ -1,22 +1,25 @@
 <template>
   <div id="app">
     <router-view />
-    
+    <loginPopup />
   </div>
 </template>
 
 <script>
-
+import loginPopup from '@/views/homeComponents/loginPopup'
 export default  {
   name: 'App',
-    metaInfo() {
-        return {
-            title: this.$store.state.settings.dynamicTitle && this.$store.state.settings.title,
-            titleTemplate: title => {
-                return title ? `${title} - ${process.env.VUE_APP_TITLE}` : process.env.VUE_APP_TITLE
-            }
-        }
-    }
+  components: {
+    loginPopup
+  },
+  metaInfo() {
+      return {
+          title: this.$store.state.settings.dynamicTitle && this.$store.state.settings.title,
+          titleTemplate: title => {
+              return title ? `${title} - ${process.env.VUE_APP_TITLE}` : process.env.VUE_APP_TITLE
+          }
+      }
+  }
 }
 </script>
 <style lang="scss" scoped>

+ 6 - 0
src/api/chat.js

@@ -6,6 +6,12 @@ import { getToken } from "@/utils/auth";
 // setAbortController(controller)
 // const signal = controller.signal;
 
+export function getGuidanceApi(id) {
+  return request({
+    url: `/system/app/guidance/${id}`,
+    method: 'get',
+  })
+}
 // ai对话AXIOS
 // export function streamChatWithWebApi(data) {
 //   return request({

BIN
src/assets/images/播放/yyPlay.png


BIN
src/assets/images/播放/yyPlay1.png


+ 1 - 1
src/assets/styles/rcBase.scss

@@ -61,7 +61,7 @@
 }
 
 .el-dialog:not(.is-fullscreen) {
-	margin-top: 6vh !important;
+	margin-top: 6vh;
 }
 
 .el-dialog__wrapper.scrollbar .el-dialog .el-dialog__body {

+ 5 - 1
src/store/modules/app.js

@@ -4,13 +4,17 @@ const state = {
   sidebar: {
     opened: Cookies.get('sidebarStatus') ? !!+Cookies.get('sidebarStatus') : true,
     withoutAnimation: false,
-    hide: false
+    hide: false, 
   },
+  showPopup: false,
   device: 'desktop',
   size: Cookies.get('size') || 'medium'
 }
 
 const mutations = {
+  TOGGLE_POPUP: (state, status) => {
+    state.showPopup = status
+  },
   TOGGLE_SIDEBAR: state => {
     if (state.sidebar.hide) {
       return false;

+ 84 - 9
src/views/chat/index.vue

@@ -40,12 +40,24 @@
                     class="rounded-full w-14 h-14 object-cover"
                   />
                 </div>
-                <div class="message fex-1 ml-4 mt-2 p-2 rounded-r-md rounded-bl-md text-xs" >
-                  <div v-show="!item.content" class="loadingMessage" >
-                    <div v-loading="!item.content" element-loading-background="rgba(0, 0, 0, 0.0)"></div>
+                <div class="messageRight">
+                  <!-- <div class="yyPlay ml-4"></div> -->
+                  <div class="yyPlayBg mt-1 ml-6 w-16 p-1 cursor-pointer">
+                    <img class="yyPlay" src="@/assets/images/播放/yyPlay.png" alt="">
+                  </div>
+                  <div class="message mt-4 ml-4 p-3 rounded-r-md rounded-bl-md text-xs" >
+                    <div v-show="!item.content" class="loadingMessage" >
+                      <div v-loading="!item.content" element-loading-background="rgba(0, 0, 0, 0.0)"></div>
+                    </div>
+                    <p v-show="item.content">{{ item.content }} </p>
+                    <div class="messageOptions" v-show="returnMessage.length == 1">
+                      <div class="option" v-for="(item, index) in messageOptions" :key="index" @click="messageOptionClick(item.chatGuidance)">
+                        {{ item.chatGuidance }}
+                      </div>
+                    </div>
                   </div>
-                  <p v-show="item.content">{{ item.content }} </p>
                 </div>
+                
               </div>
               <!-- 用户发送的信息 -->
               <div v-if="item.role == 'user'" class="text-white mb-4 flex me" :key="index">
@@ -55,9 +67,12 @@
                     class="rounded-full w-14 h-14 object-cover"
                   />
                 </div>
-                <div class="message fex-1 mr-4  mt-2 p-2 rounded-l-md rounded-br-md text-xs">
-                  <p>{{ item.content }}</p>
+                <div class="messageRight">
+                  <div class="message mr-4 mt-4 p-3 rounded-l-md rounded-br-md text-xs">
+                    <p>{{ item.content }}</p>
+                  </div>
                 </div>
+                
               </div>
             </template>
           </div>
@@ -91,7 +106,7 @@
 
 <script>
 import Header from "@/views/homeComponents/Header.vue"
-import { streamChatWithWebApi } from "@/api/chat.js"
+import { streamChatWithWebApi, getGuidanceApi } from "@/api/chat.js"
 import { detailApi } from "@/api/detail.js"
 import { Message, MessageBox, Notification, Loading } from 'element-ui'
 export default {
@@ -100,6 +115,7 @@ export default {
   },
   data() {
     return {
+      messageOptions: [],
       info: {},
       messageLoading: false,
       returnMessage: [],
@@ -138,6 +154,13 @@ export default {
           })
           localStorage.setItem(`[userId:${123},aiId:${this.info.id}]`, JSON.stringify(this.returnMessage));
         }
+        this.getGuidance(id)
+      })
+    },
+    getGuidance(id) {
+      getGuidanceApi(id).then(res => {
+        console.log(res, '聊天引导');
+        this.messageOptions = res.data
       })
     },
     goBack() {
@@ -301,6 +324,11 @@ export default {
             this.noLogin(element)
             break;
           }
+          if(JSON.parse(element).code == 500) {
+            this.returnMessage.splice(this.returnMessage.length - 1, 1)
+            this.$message.error('系统错误请联系管理员')
+            break;
+          }
           let txt = JSON.parse(element).content
           this.returnMessage[this.returnMessage.length - 1].content += txt
         }
@@ -340,6 +368,10 @@ export default {
           }
       }
     },
+    messageOptionClick(value) {
+      this.content = value
+      this.getStreamChatWithWeb()
+    },
   }
 }
 </script>
@@ -473,12 +505,39 @@ export default {
 .messages::-webkit-scrollbar {
   width: 0px;
 }
+.messageRight {
+  max-width: calc(100% - 72px);
+  min-width: 400px;
+}
+.yyPlayBg {
+  background: rgba(103, 103, 168, 1);
+  border-radius: 999px;
+  position: absolute;
+}
+
+.yyPlay {
+  width: 12px;
+  height: 12px;
+  // background: url('../../assets/images/播放/yyPlay.gif') no-repeat;
+  // background-size: 170% 170%;
+  // background-position: 50% 50%;
+  // animation: heart-burst steps(28) 0.9s infinite both;
+  // animation-play-state: paused;
+  // height: 50px;
+  // background: #fff;
+}
 .message {
   background: #ffffff0f;
   border: 1px solid #5b5b5e;
-  max-width: calc(100% - 72px);
+  
   // flex: 1;
-  min-width: 80px;
+  
+}
+.messageUser {
+  background: #ffffff0f;
+  border: 1px solid #5b5b5e;
+  max-width: calc(100% - 72px);
+  min-width: 400px;
 }
 .photo {
   width: 56px;
@@ -493,6 +552,22 @@ export default {
   width: 100%;
   height: 100%;
 }
+.messageOptions {
+  // margin-top: 20px;
+  display: flex;
+  flex-wrap: wrap;
+  justify-content: space-around;
+  .option {
+    background: #ade4ff32;
+    border: 1px solid #5b5b5e;
+    border-radius: 10px;
+    padding: 10px;
+    width: 40%;
+    height: 50px;
+    margin-top: 10px;
+    cursor: pointer;
+  }
+}
 </style>
 <style scoped>
   .loadingMessage >>> .el-loading-parent--relative {

+ 34 - 0
src/views/chat/indexH5.vue

@@ -89,6 +89,7 @@
 
 <script>
 import { streamChatWithWebApi } from "@/api/chat.js"
+// import { Message, MessageBox, Notification, Loading } from 'element-ui'
 import { detailApi } from "@/api/detail.js"
 export default {
   data() {
@@ -289,11 +290,44 @@ export default {
       for (let i = 0; i < value.length; i++) {
         const element = value[i];
         if (this.isJSON(element)) {
+          if(JSON.parse(element).code == 401) {
+            this.returnMessage.splice(this.returnMessage.length - 1, 1)
+            this.noLogin(element)
+            break;
+          }
+          if(JSON.parse(element).code == 500) {
+            this.returnMessage.splice(this.returnMessage.length - 1, 1)
+            this.$message.error('系统错误请联系管理员')
+            break;
+          }
           let txt = JSON.parse(element).content
           this.returnMessage[this.returnMessage.length - 1].content += txt
         }
       }
     },
+    noLogin(value) {
+      this.$message.error(value.content)
+      this.$store.dispatch("LogOut").then(() => {
+        this.$router.push({ path: "/loginH5" });
+      });
+      // let _this = this
+      // MessageBox.confirm(
+      //   value.content,
+      //   "系统提示",
+      //   {
+      //     confirmButtonText: "前往登录",
+      //     cancelButtonText: "取消",
+      //     type: "warning",
+      //   }
+      // )
+      // .then(() => {
+      //   // isRelogin.show = false;
+        
+      // })
+      // .catch(() => {
+      //   // isRelogin.show = false;
+      // });
+    },
     isJSON(str) {
       if (typeof str == 'string') {
           try {

+ 10 - 19
src/views/homeComponents/Header.vue

@@ -63,7 +63,7 @@
         </div>
       </div>
     </div>
-    <el-dialog
+    <!-- <el-dialog
       class="dialog"
       :visible.sync="showPopup"
       append-to-body
@@ -73,7 +73,6 @@
       <div slot="title" class="popupTitle">
         {{ popupType == 'login' ? '登录' : '注册'}}
       </div>
-      <!-- 登录表单 -->
       <el-form class="form" :rules="loginRules" v-if="popupType == 'login'" ref="formLogin" :model="formLogin" label-width="0">
         <el-form-item label="" prop="account">
           <el-input v-model="formLogin.account" placeholder="账号"></el-input>
@@ -81,9 +80,6 @@
         <el-form-item label="" prop="password">
           <el-input v-model="formLogin.password" placeholder="密码" show-password></el-input>
         </el-form-item>
-        <!-- <el-form-item label="">
-          <span class="textButton">忘记密码</span>
-        </el-form-item> -->
         <el-form-item label="">
           <button
             class="formButton text-white text-lg mr-3 cursor-pointer px-3 py-2 rounded-md w-full"
@@ -100,7 +96,6 @@
           </span>
         </el-form-item>
       </el-form>
-      <!-- 注册表单 -->
       <el-form class="form" :rules="registerRules" v-if="popupType == 'register'" ref="formRegister" :model="formRegister" label-width="0">
         <el-form-item label="" prop="account"> 
           <el-input v-model="formRegister.account" placeholder="账号"></el-input>
@@ -121,7 +116,7 @@
           </button>
         </el-form-item>
       </el-form>
-    </el-dialog>
+    </el-dialog> -->
   </div>
 </template>
 
@@ -130,8 +125,12 @@
 import 'vue-awesome/icons/coins'
 import { register } from "@/api/login.js"
 import { getToken, setToken, removeToken } from '@/utils/auth'
+import LoginContent from '@/views/homeComponents/login.vue'
 export default {
   props: ['searchName'],
+  components: {
+    LoginContent
+  },
   data() {
     return {
       showPopup: false,
@@ -185,11 +184,9 @@ export default {
       this.showPopup = false
     },
     showLogin() {
-      this.showPopup = true
-      this.popupType = 'login'
-      this.$nextTick(() =>{
-        this.$refs.formLogin.resetFields()
-      })
+      this.$store.commit('app/TOGGLE_POPUP', true)
+      // this.popupType = 'login'
+      
       
     },
     showRegister() {
@@ -254,13 +251,7 @@ export default {
 </script>
 
 <style lang="scss" scoped>
-.popupTitle {
-  text-align: center;
-  font-size: 22px;
-  font-weight: 600;
-  color: var(--bg-color1);
-  letter-spacing: 6px;
-}
+
 .searchInput {
   background-color: #ffffff00;
   border: 1px solid #ffffff4d;

+ 54 - 0
src/views/homeComponents/HomePC.vue

@@ -3,6 +3,23 @@
     <Header @search="searchChange" :searchName="searchName" />
     <div class="min-h-screen text-white">
       <div class="container mx-auto py-3">
+        <div class="historysBox w-full mb-4">
+          <div class="mb-2 text-xl">继续聊天</div>
+          <el-carousel :autoplay="false" arrow="always" height="10rem" indicator-position="none">
+            <el-carousel-item v-for="item in 4" :key="item">
+              <div class="historys px-20 w-full whitespace-nowrap overflow-x-auto">
+                <div class="history w-full overflow-hidden rounded cursor-pointer inline-block" v-for="(item, index) in 5" :key="index">
+                  <img src="@/assets/images/1.png" class="historyImg w-full h-40" />
+                  <div class="absolute infoBg w-full h-24">
+                    <p class="text-center">聊天信息1</p>
+                    <p class="text-center">聊天信息2</p>
+                  </div>
+                </div>
+              </div>
+            </el-carousel-item>
+          </el-carousel>
+          
+        </div>
         <div class="flex mb-3">
           <div class="flex space-x-4">
             <button class="px-3 py-2 rounded topActive">热门</button>
@@ -109,6 +126,7 @@ export default {
   },
   data() {
     return {
+      historys: [],
       labelLength: 8,
       searchName: '',
       labelData: [],
@@ -324,4 +342,40 @@ export default {
   display: -webkit-box;
   -webkit-box-orient: vertical;
 }
+.historysBox {
+  .historys {
+    display: grid;
+    grid-gap: 10px;
+    grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr 1fr;
+  }
+  .historys::-webkit-scrollbar { 
+    width: 0; /* 隐藏滚动条 */
+  }
+  .history {
+    position: relative;
+    overflow: hidden;
+    justify-self: center;
+    .historyImg {
+      position: relative;
+      object-fit: cover;
+      object-position: top;
+      
+    }
+    .infoBg {
+      background: rgba(0, 0, 0, 0.5);
+      transition: bottom 0.2s;
+      bottom: -6rem;
+    }
+  }
+  .history:hover {
+    .infoBg {
+      bottom: 0;
+    }
+  }
+}
 </style>
+<style scoped>
+.historysBox >>> .el-carousel__arrow {
+  background: var(--bg-color1);
+}
+</style>

+ 133 - 0
src/views/homeComponents/login.vue

@@ -0,0 +1,133 @@
+<template>
+  <div class="login">
+    <!-- 登录表单 -->
+    <el-form class="form" :rules="loginRules" ref="formLogin" :model="formLogin" label-width="0">
+      <el-form-item label="" prop="account">
+        <el-input v-model="formLogin.account" placeholder="手机号">
+          <template slot="prepend">+86</template>
+        </el-input>
+      </el-form-item>
+      <el-form-item label="" prop="code">
+        <el-input v-model="formLogin.code" placeholder="验证码">
+          <template slot="append">
+            <el-button :disabled="codeTime > -1" @click="getCode" style="width: 112px;">
+              {{ codeTime > -1 ? `${codeTime}s` : '获取验证码' }}
+            </el-button>
+          </template>
+        </el-input>
+      </el-form-item>
+      <!-- <el-form-item label="" prop="password">
+        <el-input v-model="formLogin.password" placeholder="密码" show-password></el-input>
+      </el-form-item> -->
+      <!-- <el-form-item label="">
+        <span class="textButton">忘记密码</span>
+      </el-form-item> -->
+      <el-form-item label="">
+        <button
+          
+          class="formButton text-white text-lg mr-3 cursor-pointer px-3 py-2 rounded-md w-full"
+          style="background-color: var(--bg-color1);"
+          @click="clickLogin"
+        >
+          登录
+        </button>
+      </el-form-item>
+      <el-form-item label="" prop="checked">
+        <el-checkbox class="checkbox" v-model="checked"></el-checkbox>
+        勾选即代表您已同意<span class="text-blue-500">《用户协议》</span>和<span class="text-blue-500">《隐私政策》</span>
+      </el-form-item>
+      <!-- <el-form-item label="">
+        <span style="font-size: 1rem;">
+          还没有账号吗?
+          <span class="textButton" @click="popupType = 'register'">注册</span>
+        </span>
+      </el-form-item> -->
+    </el-form>
+  </div>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      codeTime: -1,
+      codeInterval: null,
+      checked: false,
+      formLogin: {
+        account: null,
+        password: null,
+      },
+      loginRules: {
+        account: [
+          { required: true, message: '请输入手机号', trigger: 'blur' },
+        ],
+        password: [
+          { required: true, message: '请输入用户密码', trigger: 'blur' },
+        ],
+      },
+    }
+  },
+  computed: {
+    showPopup() {
+      return this.$store.state.app.showPopup
+    }
+  },
+  watch: {
+    showPopup(value) {
+      if (value) {
+        this.$nextTick(() =>{
+            this.$refs.formLogin.resetFields()
+        })
+      }
+    }
+  },
+  methods: {
+    getCode() {
+      this.codeTime = 60
+      this.codeInterval = setInterval(() => {
+        this.codeTime = this.codeTime - 1
+        if (this.codeTime < 0) {
+          clearInterval(this.codeInterval)
+        }
+      }, 1000)
+    },
+    clickLogin() {
+      this.$refs.formLogin.validate((valid) => {
+        if (valid) {
+          if (!this.checked) {
+            this.$confirm('请阅读并接受用户协议和隐私政策', '提示', {
+              confirmButtonText: '确定',
+              cancelButtonText: '取消',
+              type: 'warning'
+            }).then(() => {})
+            return
+          }
+          this.$store.dispatch('Login', this.formLogin).then(() => {
+            this.$message({
+              message: '登录成功',
+              type: 'success'
+            });
+            this.showPopup = false
+          })
+        }
+      })
+    },
+  }
+}
+</script>
+
+<style scoped>
+  .textButton {
+    font-size: 1rem;
+    color: var(--bg-color1);
+    cursor: pointer;
+  }
+  .formButton {
+    letter-spacing: 4px;
+  }
+  .form >>> .el-input__inner {
+    font-size: 1rem;
+    padding: 5px 15px;
+    height: 40px;
+  }
+</style>

+ 51 - 0
src/views/homeComponents/loginPopup.vue

@@ -0,0 +1,51 @@
+<template>
+  <el-dialog
+    class="dialog"
+    :visible.sync="$store.state.app.showPopup"
+    append-to-body
+    top="50vh"
+    width="30%"
+    :before-close="handleClose">
+    <div slot="title" class="popupTitle">
+      手机号快捷登录
+    </div>
+    <LoginContent />
+  </el-dialog>
+</template>
+
+<script>
+import LoginContent from '@/views/homeComponents/login.vue'
+export default {
+  components: {
+    LoginContent
+  },
+  
+  mounted() {
+  },
+  methods: {
+    
+    handleClose() {
+      this.$store.commit('app/TOGGLE_POPUP', false)
+    },
+  }
+}
+</script>
+
+<style scoped>
+.popupTitle {
+  text-align: center;
+  font-size: 20px;
+  /* font-weight: 600; */
+  color: #34343c;
+  letter-spacing: 2px;
+}
+.dialog >>> .el-dialog {
+  transform: translateY(-50%);
+}
+.dialog >>> .el-dialog__body {
+  padding: 20px;
+}
+.dialog >>> .el-dialog {
+  border-radius: 10px;
+}
+</style>