浏览代码

no message

chenrong 1 年之前
父节点
当前提交
582fd99966

+ 1 - 1
.env.production

@@ -5,4 +5,4 @@ VUE_APP_TITLE = 元宇宙
 ENV = 'production'
 
 # 元宇宙/生产环境
-VUE_APP_BASE_API = '/dev-api'
+VUE_APP_BASE_API = 'http://aitest.api.rongcyl.cn'

+ 2 - 2
.gitignore

@@ -21,6 +21,6 @@ selenium-debug.log
 
 package-lock.json
 yarn.lock
-baseManagerDist.zip
-baseManagerDist/
+webDist.zip
+webDist/
 *.iml

+ 1 - 1
package.json

@@ -5,7 +5,7 @@
   "author": "榕创",
   "license": "MIT",
   "scripts": {
-    "dev": "set NODE_OPTIONS=--openssl-legacy-provider & vue-cli-service serve",
+    "dev": "vue-cli-service serve",
     "build:prod": "vue-cli-service build",
     "build:stage": "vue-cli-service build --mode staging",
     "preview": "node build/index.js --preview",

+ 18 - 18
src/api/chat.js

@@ -6,31 +6,31 @@ import request from '@/utils/request'
 // const signal = controller.signal;
 
 // ai对话AXIOS
-export function streamChatWithWebApi(data) {
-  return request({
-    url: '/system/test/auth/localAi',
-    headers: {
-      isToken: false,
-      returnData: true,
-      'Content-Type': 'application/json'
-    },
-    method: 'post',
-    data: data
-  })
-}
-// ai对话
 // export function streamChatWithWebApi(data) {
-//   return fetch(`${process.env.VUE_APP_BASE_API}/system/test/auth/localAi`, {
+//   return request({
+//     url: '/system/test/auth/localAi',
 //     headers: {
 //       isToken: false,
 //       returnData: true,
 //       'Content-Type': 'application/json'
 //     },
-//     method: 'POST',
-//     body: JSON.stringify(data),
-//     // credentials: 'include',
+//     method: 'post',
+//     data: data
 //   })
 // }
+// ai对话
+export function streamChatWithWebApi(data) {
+  return fetch(`${process.env.VUE_APP_BASE_API}/system/chat/localAiStream`, {
+    headers: {
+      isToken: false,
+      returnData: true,
+      'Content-Type': 'application/json'
+    },
+    method: 'POST',
+    body: JSON.stringify(data),
+    credentials: 'include',
+  })
+}
 // /system/chat/qwenChatHistory
 // /system/test/auth/localAi
-// http://localhost:8086/system/chat/streamChatWithWeb?content=牛肉怎么炒好吃
+// system/chat/localAiStream

+ 5 - 0
src/assets/styles/index.scss

@@ -207,6 +207,11 @@ button, input, optgroup, select, textarea {
 .buttonBg1 {
   background: linear-gradient(270deg, #5ea1f9, #d287f1);
 }
+
+.fontH5 {
+  font-size: 12px;
+}
+
 :root {
   --bg-color1: #d44165;
 }

+ 2 - 0
src/main.js

@@ -50,8 +50,10 @@ import DictTag from "@/components/DictTag";
 import VueMeta from "vue-meta";
 // 字典数据组件
 import DictData from "@/components/DictData";
+const baseApi = process.env.VUE_APP_BASE_API
 
 // 全局方法挂载
+Vue.prototype.baseApi = baseApi;
 Vue.prototype.getDicts = getDicts;
 Vue.prototype.getConfigKey = getConfigKey;
 Vue.prototype.parseTime = parseTime;

+ 30 - 21
src/views/chat/index.vue

@@ -12,10 +12,10 @@
       </div>
       <div class="content">
         <div class="leftImg">
-          <img src="https://fallfor.ai/public/img/uploads/11/img_1715399022390_00024-654400262.jpg" alt="">
+          <img :src="baseApi + info.picture" alt="">
           <div class="aiInfo">
             <span class="photo">
-              <img src="https://fallfor.ai/public/img/uploads/11/img_1715399064396_1 (2).gif">
+              <img :src="baseApi + info.picture">
             </span>
             <div class="info">
               <div class="name">{{ info.characterName }}</div>
@@ -35,15 +35,15 @@
                 <!-- ai返回的信息 -->
                 <div class="pt-2 photo">
                   <img
-                    src="https://fallfor.ai/public/img/uploads/11/img_1715399064396_1 (2).gif"
-                    class="rounded-full w-14"
+                    :src="baseApi + info.picture"
+                    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>
-                  <p v-show="item.content" v-html="item.content"> </p>
+                  <p v-show="item.content">{{ item.content }} </p>
                 </div>
               </div>
               <!-- 用户发送的信息 -->
@@ -51,7 +51,7 @@
                 <div class="pt-2 photo">
                   <img
                     src="@/assets/images/default_avatar_user.png"
-                    class="rounded-full w-14"
+                    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">
@@ -108,8 +108,10 @@ export default {
   watch: {
     returnMessage: {
       handler(newVal, lodVal) {
-        let messages = this.$refs.messages
-        messages.scrollTop = messages.scrollHeight
+        this.$nextTick(() => {
+          let messages = this.$refs.messages
+          messages.scrollTop = messages.scrollHeight
+        })
       },
       deep: true
     }
@@ -145,7 +147,7 @@ export default {
         this.getStreamChatWithWeb()
       }
     },
-    async getStreamChatWithWeb() {
+    async getStreamChatWithWeb_old() {
       this.messageLoading = true
       if (!this.content) {
         return
@@ -207,7 +209,7 @@ export default {
         index += 1
       }, 50)
     },
-    async getStreamChatWithWeb_old() {
+    async getStreamChatWithWeb() {
       this.messageLoading = true
       if (!this.content) {
         return
@@ -222,7 +224,7 @@ export default {
         HistoryMessage = HistoryMessage.slice(HistoryMessage.length - 1, 20)
       }
       let params = {
-        historyMessage: HistoryMessage || [],
+        HistoryMessage: HistoryMessage || [],
         characterId: this.info.id,
         prompt: this.content
       }
@@ -231,6 +233,9 @@ export default {
         role: 'assistant',
         content: ''
       })
+      // 清空输入框的值
+      this.content = ''
+
       let res = await streamChatWithWebApi(params)
       console.log(res, 'res');
       this.messageLoading = false
@@ -240,11 +245,6 @@ export default {
         this.returnMessage.splice(this.returnMessage.length - 1, 1)
         return
       }
-      // 清空输入框的值
-      this.content = ''
-
-      console.log(res, 'res>>>');
-      return
       const reader = res.body.getReader()
       const decoder=new TextDecoder()
       while(1){
@@ -270,18 +270,27 @@ export default {
         }
         
         //txt就是一个一个的字 然后添加到页面上就可以了
-        const txt = decoder.decode(value)
+        const txt = decoder.decode(value).split('data:')
         // const txt = decoder.decode(value)
-        
-        let data = JSON.parse(txt).message.content
-        console.log(data, 'data');
+        this.addMessage(txt)
+        // let data = JSON.parse(txt).message.content
+        // console.log(txt, 'txt');
         // if (this.isJSON(txt) && JSON.parse(txt).code != 200) {
         //   let data = JSON.parse(txt)
         //   this.$message.error(data.msg)
         //   this.returnMessage.splice(this.returnMessage.length - 1, 1)
         //   break;
         // }
-        this.returnMessage[this.returnMessage.length - 1].content += txt
+        
+      }
+    },
+    addMessage(value) {
+      for (let i = 0; i < value.length; i++) {
+        const element = value[i];
+        if (this.isJSON(element)) {
+          let txt = JSON.parse(element).content
+          this.returnMessage[this.returnMessage.length - 1].content += txt
+        }
       }
     },
     isJSON(str) {

+ 3 - 3
src/views/detail/index.vue

@@ -4,7 +4,7 @@
     <div class="text-white w-2/4 mx-auto">
       <div class="flex justify-between">
         <div>
-          <img src="https://fallfor.ai/public/img/uploads/11/img_1715399022390_00024-654400262.jpg" class="img w-40 h-40" />
+          <img :src="baseApi + info.picture" class="img w-40 h-40" />
           <div class="">
             <div>
               <button class="text-xs bg-gray-700 py-1 px-2 rounded mt-2 flex">
@@ -34,12 +34,12 @@
             <div class="flex items-center justify-between mt-3 pb-3" style="width: 150px;">
               <div class="flex items-center mr-2 text-gray-200">
                 <v-icon name="heart" scale="1.5"/>
-                <span class="ml-1">{{ 123 }}</span>
+                <span class="ml-1">{{ info.likeNum }}</span>
               </div>
               <div class="flex items-center mr-2 text-gray-200">
                 <!-- <i class="fas fa-comment mr-1"></i> -->
                 <v-icon name="star" scale="1.5"/>
-                <span class="ml-1">{{ 123 }}</span>
+                <span class="ml-1">{{ info.collections }}</span>
               </div>
               <!-- <div class="flex items-center">
                 <v-icon name="share" scale="1.5"/>

+ 9 - 7
src/views/home.vue

@@ -21,20 +21,22 @@ export default {
     }
   },
   mounted() {
+    this.pdIsMobile()
     let _this = this
     window.onresize = () => {
       setTimeout(() => {
-        if (_this.fIsMobile()) {
-          console.log('移动端');
-          _this.isMobile = true
-        } else {
-          console.log('pc端');
-          _this.isMobile = false
-        }
+        _this.pdIsMobile()
       }, 100)
     }
   },
   methods: {
+    pdIsMobile() {
+      if (this.fIsMobile()) {
+        this.isMobile = true
+      } else {
+        this.isMobile = false
+      }
+    },
     fIsMobile() {
       return /Android|iPhone|iPad|iPod|BlackBerry|webOS|Windows Phone|SymbianOS|IEMobile|Opera Mini/i.test(navigator.userAgent);
     }

+ 101 - 0
src/views/homeComponents/HeaderH5.vue

@@ -0,0 +1,101 @@
+<template>
+  <div class="fontH5 px-4 py-2">
+    <div class="flex items-center justify-end pb-2">
+      <div class="flex items-center">
+        
+        <button class="text-yellow-400 p-2">
+          <v-icon name="coins" scale="1"/>
+        </button>
+        <span class="text-yellow-400 text-lg mr-2">40</span>
+
+        <button class="text-white p-2">
+          <i class="fas el-icon-message-solid"></i>
+        </button>
+        <button class="text-white p-2">
+          <i class="fas el-icon-user-solid text-white mr-2"></i>
+        </button>
+      </div>
+    </div>
+    <div class="flex justify-center items-center">
+      <div class="relative flex-1">
+        <input
+          type="text"
+          placeholder="搜索"
+          class="searchInput w-full fontH5 pl-4 pr-10 py-2 rounded-md text-white placeholder-gray-400 focus:outline-none"
+          @keydown="Enterkey"
+          v-model="searchValue"
+        />
+        <button class="absolute inset-y-0 right-0 px-3 flex items-center fontH5 text-white rounded-r-md">
+          <i class="fas fa-search search-icon"></i>
+          <i class="el-icon-search"></i>
+        </button>
+      </div>
+      <button
+        class="text-white ml-2 cursor-pointer px-2 rounded-md"
+        style="background-color: var(--bg-color1); font-size: 11px;"
+        @click="goCreate"
+      >
+        <p>创建</p>
+        <p>机器人</p>
+      </button>
+    </div>
+    
+  </div>
+</template>
+
+<script>
+// 引入需要的图标
+import 'vue-awesome/icons/coins'
+
+export default {
+  props: ['searchName'],
+  data() {
+    return {
+      searchValue: ''
+    }
+  },
+  mounted() {
+    console.log(this.searchName, 'this.searchName');
+  },
+  watch: {
+    searchName: {
+      handler(val) {
+        // console.log(val, '监听searchName');
+        this.searchValue = val
+      },
+      immediate: true,
+    },
+  },
+  methods: {
+    Enterkey(e) {
+      if (e.keyCode == 13) {
+        this.toHomeSearch()
+      }
+    },
+    toHomeSearch() {
+      console.log(this.$route, 'this.$route');
+      if (this.$route.path == '/home') {
+        this.$emit('search', this.searchValue)
+      } else {
+        this.$router.push({
+          name: 'Home',
+          params: {
+            searchValue: this.searchValue
+          }
+        })
+      }
+    },
+    goCreate() {
+      this.$router.push('/create')
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.searchInput {
+  background-color: #ffffff00;
+  border: 1px solid #ffffff4d;
+}
+
+</style>

+ 37 - 30
src/views/homeComponents/HomeH5.vue

@@ -1,31 +1,31 @@
 <template>
   <div class="home bg-gray-900 comBg">
-    <Header @search="searchChange" :searchName="searchName" />
-    <div class="min-h-screen text-white">
-      <div class="container mx-auto py-3">
+    <HeaderH5 @search="searchChange" :searchName="searchName" />
+    <div class="min-h-screen text-white px-4">
+      <div class="container mx-auto py-2">
         <div class="flex mb-3">
           <div class="flex space-x-4">
-            <button class="px-3 py-2 rounded topActive">这是h5</button>
-            <button class="bg-gray-800 px-3 py-2 rounded">趋势</button>
-            <button class="bg-gray-800 px-3 py-2 rounded">最新</button>
+            <button class="px-3 py-2 rounded topActive fontH5">这是h5</button>
+            <button class="bg-gray-800 px-3 py-2 rounded fontH5">趋势</button>
+            <button class="bg-gray-800 px-3 py-2 rounded fontH5">最新</button>
           </div>
         </div>
-        <div class="flex flex-grow mb-3 items-center">
+        <div class="flex flex-wrap flex-grow mb-3 items-center">
           <input
             type="text"
             placeholder="搜索标签"
-            class="searchInput mr-2 px-3 py-2 rounded w-1/4 focus:border-blue-300 focus:outline-none focus:ring"
+            class="searchInput fontH5 w-full mr-2 px-3 py-2 mb-1 rounded focus:border-blue-300 focus:outline-none "
           />
           <div
             v-for="(item, index) in selectLabelObj"
             :key="index"
-            class="px-3 py-1 mx-1 rounded flex items-center cursor-pointer buttonBg1"
+            class="fontH5 px-3 py-1 mx-1 rounded flex items-center cursor-pointer buttonBg1"
             @click="clickLabel(item)"
           >
             {{ item.labelName }}
             <i class="fas el-icon-close text-white"></i>
           </div>
-          <el-button v-show="selectLabelObj.length > 0" class="textButton" type="text" @click="clearSelectLabel">移除所有</el-button>
+          <el-button v-show="selectLabelObj.length > 0" class="textButton mx-1" type="text" @click="clearSelectLabel">移除所有</el-button>
         </div>
         <div class="flex flex-wrap">
           <div
@@ -33,45 +33,48 @@
             :key="index"
             :class="[
               selectLabel.indexOf(item.id) != -1 ? 'buttonBg1' : 'labelButton',
-              'labelButton px-3 py-1 mx-1 mb-1 rounded flex items-center cursor-pointer'
+              'fontH5 labelButton px-3 py-1 mx-1 mb-1 rounded flex items-center cursor-pointer'
             ]" 
             @click="clickLabel(item)"
           >
             <i class="fas fa-fire text-yellow-500 mr-2"></i>
             {{ item.labelName }}({{item.num}})
           </div>
-          <div v-show="labelData.length > 8 && labelLength == 8" @click="labelLength = labelData.length"  class="labelButton px-3 py-1 mx-1 mb-1 rounded cursor-pointer">
+          <div v-show="labelData.length > 8 && labelLength == 8" @click="labelLength = labelData.length"  class="fontH5 labelButton px-3 py-1 mx-1 mb-1 rounded cursor-pointer">
             ....
           </div>
-          <div v-show="labelData.length > 8 && labelLength == 8" @click="labelLength = labelData.length" class="labelButton px-3 py-1 mx-1 mb-1 rounded cursor-pointer">
+          <div v-show="labelData.length > 8 && labelLength == 8" @click="labelLength = labelData.length" class="fontH5 labelButton px-3 py-1 mx-1 mb-1 rounded cursor-pointer">
             显示更多
           </div>
-          <div v-show="labelData.length > 8 && labelLength > 8" @click="labelLength = 8" class="labelButton px-3 py-1 mx-1 mb-1 rounded cursor-pointer">
+          <div v-show="labelData.length > 8 && labelLength > 8" @click="labelLength = 8" class="fontH5 labelButton px-3 py-1 mx-1 mb-1 rounded cursor-pointer">
             隐藏
           </div>
         </div>
 
-        <div class="grid grid-cols-5 gap-4 mt-4">
+        <div class="mt-4">
           <div
             v-for="(item, index) in characterList"
             :key="index"
             class="box2 rounded-lg overflow-hidden shadow-lg cursor-pointer"
             @click="toDetail(item)"
           >
-            <img v-if="item.id != 4" :src="url[index % 4]" class="w-full img" />
-            <img v-if="item.id == 4" src="https://fallfor.ai/public/img/uploads/11/img_1715399022390_00024-654400262.jpg" class="w-full img" />
-            <div class="p-3">
-              <h3 class="text-lg font-bold">{{ item.characterName }}</h3>
-              <p class="text-sm">
-                {{ item.prologue }}
-              </p>
+            
+            <div class="p-3 flex justify-between">
+              <img :src="baseApi + item.picture" class="w-24 h-24 img" />
+              <div class="ml-3 flex-1">
+                <h3 class="text-lg font-bold">{{ item.characterName }}</h3>
+                <p class="text-sm">
+                  {{ item.prologue }}
+                </p>
 
-              <div class="flex my-2 flex-wrap">
-                <div v-for="(item2, index2) in item.labelArr" :key="index2" class="m-0.5 tag px-2 py-1 rounded flex items-center text-xs">
-                  <!-- <i class="fas fa-smile text-yellow-400 mr-2"></i> -->
-                  {{ item2 }}
+                <div class="flex my-2 flex-wrap labels">
+                  <div v-for="(item2, index2) in item.labelArr" :key="index2" class="m-0.5 tag px-2 py-1 rounded flex items-center text-xs">
+                    <!-- <i class="fas fa-smile text-yellow-400 mr-2"></i> -->
+                    {{ item2 }}
+                  </div>
                 </div>
               </div>
+              
             </div>
             <div class="flex items-center justify-between mt-3 px-3 pb-3">
               <div class="flex items-center box1">
@@ -96,7 +99,7 @@
 </template>
 
 <script>
-import Header from "@/views/homeComponents/Header.vue"
+import HeaderH5 from "@/views/homeComponents/HeaderH5.vue"
 import { labelListApi, characterListApi } from "@/api/home.js"
 // 引入需要的图标
 import 'vue-awesome/icons/heart'
@@ -106,7 +109,7 @@ import 'vue-awesome/icons/star'
 export default {
   name: "HomeH5",
   components: {
-    Header
+    HeaderH5
   },
   data() {
     return {
@@ -253,7 +256,7 @@ export default {
   }
 
   p {
-    margin-top: 10px;
+    margin-top: 2px;
 
     b {
       font-weight: 700;
@@ -274,7 +277,7 @@ export default {
 }
 .textButton {
   color: #eee;
-  margin-left: 5px;
+  // margin-left: 5px;
 }
 .textButton:hover {
   color: #9333ea;
@@ -313,4 +316,8 @@ export default {
   object-fit: cover;
   object-position: top;
 }
+.labels {
+  max-height: 84px;
+  overflow-y: auto;
+}
 </style>

+ 18 - 7
src/views/homeComponents/HomePC.vue

@@ -55,25 +55,24 @@
           <div
             v-for="(item, index) in characterList"
             :key="index"
-            class="box2 rounded-lg overflow-hidden shadow-lg cursor-pointer"
+            class="box2 relative rounded-lg overflow-hidden shadow-lg cursor-pointer"
             @click="toDetail(item)"
           >
-            <img v-if="item.id != 4" :src="url[index % 4]" class="w-full img" />
-            <img v-if="item.id == 4" src="https://fallfor.ai/public/img/uploads/11/img_1715399022390_00024-654400262.jpg" class="w-full img" />
+            <img :src="baseApi + item.picture" class="w-full img" />
             <div class="p-3">
               <h3 class="text-lg font-bold">{{ item.characterName }}</h3>
-              <p class="text-sm">
+              <p class="prologue text-sm">
                 {{ item.prologue }}
               </p>
 
-              <div class="flex my-2 flex-wrap">
+              <div class="labels flex my-2 flex-wrap">
                 <div v-for="(item2, index2) in item.labelArr" :key="index2" class="m-0.5 tag px-2 py-1 rounded flex items-center text-xs">
                   <!-- <i class="fas fa-smile text-yellow-400 mr-2"></i> -->
                   {{ item2 }}
                 </div>
               </div>
             </div>
-            <div class="flex items-center justify-between mt-3 px-3 pb-3">
+            <div class="absolute w-full bottom-0 flex items-center justify-between mt-3 px-3 pb-3">
               <div class="flex items-center box1">
                 <v-icon name="heart" scale="1"/>
                 <span class="ml-1">{{ item.likeNum }}</span>
@@ -307,10 +306,22 @@ export default {
 .box2 {
   background: #ffffff0f; 
   border: 1px solid #ffffff2e;
+  height: 540px;
 }
 .img {
-  max-height: 220px;
+  height: 250px;
   object-fit: cover;
   object-position: top;
 }
+.labels {
+  max-height: 84px;
+  overflow-y: auto;
+}
+.prologue {
+  overflow:hidden;
+  text-overflow: ellipsis;
+  -webkit-line-clamp: 4;
+  display: -webkit-box;
+  -webkit-box-orient: vertical;
+}
 </style>

+ 4 - 4
vue.config.js

@@ -11,7 +11,7 @@ const { plugin } = require("postcss");
 
 const name = process.env.VUE_APP_TITLE || "元宇宙"; // 网页标题
 
-const port = process.env.port || process.env.npm_config_port || 80; // 端口
+const port = process.env.port || process.env.npm_config_port || 8088; // 端口
 
 // vue.config.js 配置说明
 //官方vue.config.js 参考文档 https://cli.vuejs.org/zh/config/#css-loaderoptions
@@ -22,7 +22,7 @@ module.exports = {
   // 例如 https://www.rcBase.vip/。如果应用被部署在一个子路径上,你就需要用这个选项指定这个子路径。例如,如果你的应用被部署在 https://www.rcBase.vip/admin/,则设置 baseUrl 为 /admin/。
   publicPath: process.env.NODE_ENV === "production" ? "/" : "/",
   // 在npm run build 或 yarn build 时 ,生成文件的目录名称(要和baseUrl的生产环境路径一致)(默认baseManagerDist)
-  outputDir: "baseManagerDist",
+  outputDir: "webDist",
   // 用于放置生成的静态资源 (js、css、img、fonts) 的;(项目打包之后,静态资源会放在这个文件夹下)
   assetsDir: "static",
   // 是否开启eslint保存检测,有效值:ture | false | 'error'
@@ -36,8 +36,8 @@ module.exports = {
     open: true,
     proxy: {
       [process.env.VUE_APP_BASE_API]: {
-        target: `http://192.168.0.101:8086`,
-        // target: `http://127.0.0.1:8090`,
+        target: `http://aitest.api.rongcyl.cn`,
+        // target: `http://192.168.0.104:8086`,
         changeOrigin: true,
         pathRewrite: {
           ["^" + process.env.VUE_APP_BASE_API]: "",