浏览代码

feat: 增加统计界面, 停止回答, 字体外链

sunxiao 9 月之前
父节点
当前提交
e8538d3cd9

+ 5 - 0
src/api/chat.js

@@ -40,4 +40,9 @@ export const chatApi = {
    * 点赞 or 取消点赞
    */
   putIsSatisfiedAnswer: data => http.put(`/front/bigModel/chat/isSatisfiedAnswer`, data),
+
+  /**
+   * 停止流数据
+   */
+  getStopChatStream: params => http.get('/front/bigModel/warning/stopChat/' + params)
 }

+ 64 - 35
src/components/Chat/ChatAnswer.vue

@@ -35,10 +35,14 @@ const props = defineProps({
   loadingText: {
     type: String,
     default: '内容生成中...'
+  },
+  isVisibleStopBtn: {
+    type: Boolean,
+    default: false
   }
 })
 
-const emit = defineEmits(['on-click-icon']);
+const emit = defineEmits(['on-click-icon', 'on-click-stop']);
 
 const message = useMessage();
 
@@ -53,7 +57,11 @@ const handlLeToggleLike = async (state) => {
 
   isSatisfied < 2 ? message.success('感谢您的反馈') : message.success('已取消反馈');
 
-  emit('on-click-icon', params)
+  emit('on-click-icon', params);
+}
+
+const handleChatStop = () => {
+  emit('on-click-stop');
 }
 
 const handleCopy = () => {
@@ -72,21 +80,26 @@ const handleCopy = () => {
       <ChatText :content="content"></ChatText>
     </template>
 
-
     <template #button>
-      <ul class="answer-btn-group" v-if="!loading && toggleVisibleIcons">
-        <li class="btn" @click="handleCopy">
-          <SvgIcon name="chat-icon-copy" size="16" />
-        </li>
-        <li class="line"></li>
-        <li :class="['btn', { btn_active: isSatisfied == 1 }]">
-          <SvgIcon name="chat-icon-yes" size="16" @click="handlLeToggleLike(1)" />
-        </li>
-        <li class="line"></li>
-        <li :class="['btn', { btn_active: isSatisfied == 0 }]">
-          <SvgIcon name="chat-icon-no" size="16" @click="handlLeToggleLike(0)" />
-        </li>
-      </ul>
+      <div class="footer-wrap">
+        <div class="chat-stop-btn">
+          <span @click="handleChatStop" v-if="!delayLoading && loading && isVisibleStopBtn">停止生成</span>
+        </div>
+        <ul class="answer-btn-group" v-if="!loading && toggleVisibleIcons">
+          <li class="btn" @click="handleCopy">
+            <SvgIcon name="chat-icon-copy" size="16" />
+          </li>
+          <li class="line"></li>
+          <li :class="['btn', { btn_active: isSatisfied == 1 }]">
+            <SvgIcon name="chat-icon-yes" size="16" @click="handlLeToggleLike(1)" />
+          </li>
+          <li class="line"></li>
+          <li :class="['btn', { btn_active: isSatisfied == 0 }]">
+            <SvgIcon name="chat-icon-no" size="16" @click="handlLeToggleLike(0)" />
+          </li>
+        </ul>
+      </div>
+      
     </template>
 
   </ChatBaseCard>
@@ -118,34 +131,50 @@ const handleCopy = () => {
 
   .answer-card {
     @include flex(x, start, start);
-    // padding: 20px 20px 4px 20px;
     border-radius: 8px;
     background: #fff;
   }
 
-  .answer-btn-group {
-    @include flex(x, center, end);
-    padding-top: 6px;
+  .footer-wrap {
+    @include flex(x, cetner, between);
+    padding: 6px 0 0 5px;
+    color: #2454FF;
+
+    .chat-stop-btn {
+      font-size: 14px;
+      line-height: 34px;
+      span {
+        cursor: pointer;
+        &:hover {
+          color: #1D43CC;
+        }
+      }
+    }
+
+    .answer-btn-group {
+      @include flex(x, center, end);
 
-    .btn {
-      @include flex(x, center, center);
-      @include layout(28px, 28px, 4px);
-      color: #89909B;
-      cursor: pointer;
+      .btn {
+        @include flex(x, center, center);
+        @include layout(28px, 28px, 4px);
+        color: #89909B;
+        cursor: pointer;
 
-      &:hover,
-      &_active {
-        background: #DBEFFF;
-        color: #2454FF;
-      }
+        &:hover,
+        &_active {
+          background: #DBEFFF;
+          color: #2454FF;
+        }
 
-    }
+      }
 
-    .line {
-      @include layout(1px, 12px, 0);
-      margin: 0 5px;
-      background: #D3D0E1;
+      .line {
+        @include layout(1px, 12px, 0);
+        margin: 0 5px;
+        background: #D3D0E1;
+      }
     }
   }
+
 }
 </style>

+ 4 - 4
src/components/Chat/ChatInput.vue

@@ -48,8 +48,8 @@ const commonEmitEvent = (eventName) => {
 
 const handleInpEnter = (event) => {
   if (event.key === 'Enter' && !event.shiftKey) {
-    event.preventDefault()
-    commonEmitEvent('onEnter')
+    event.preventDefault();
+    commonEmitEvent('onEnter');
   }
 }
 
@@ -97,8 +97,8 @@ defineExpose({
     <NSwitch size="small" v-model:value="switchStatus"></NSwitch>
     <span class="text-[12px] text-[#9E9E9E]">使用搜索增强</span>
   </div>
-  <div class="masking-inner">
-    
+  <div class="masking-inner text-center text-[#2454FF]">
+    <!-- <span>停止生成</span> -->
   </div>
 </template>
 

+ 3 - 3
src/components/Layout/TheUserAvatar.vue

@@ -1,5 +1,5 @@
 <script lang="jsx">
-import { computed, defineComponent, unref, ref } from 'vue';
+import { defineComponent } from 'vue';
 import { useRouter } from 'vue-router';
 import { NPopover } from 'naive-ui';
 import { userApi } from '@/api/user';
@@ -66,7 +66,7 @@ const RenderUserAvatar = ({ store }) => {
     ),
     trigger: () => (
       <div class="flex items-center cursor-pointer">
-        <img src={user.avatar} alt="" class="w-[32px] mr-[10px] rounded-[50%]" />
+        <img src={user.avatar} alt="" class="w-[32px] h-[32px] mr-[10px] rounded-[50%]" />
         <span class="text-[#272D35] text-[12px]">{user.nickName}</span>
       </div>
     )
@@ -84,7 +84,7 @@ const RenderUserAvatar = ({ store }) => {
 }
 
 export default defineComponent({
-  setup (props, context) {
+  setup () {
 
     const userStore = useUserStore();
 

+ 8 - 0
src/composables/useChat.js

@@ -17,6 +17,13 @@ export const useChat = () => {
     chatDataSource.value[index] = chat;
   }
 
+  const stopChat = () => {
+    const length = unref(chatDataSource).length;
+    const index = length ? length - 1 : length;
+    const lastItem = chatDataSource.value[index];
+    chatDataSource.value[index] = { ...lastItem, loading: false, delayLoading: false };
+  }
+
   const clearChat = () => {
     chatDataSource.value = [];
   }
@@ -31,6 +38,7 @@ export const useChat = () => {
     createChat,
     addChat,
     updateChat,
+    stopChat,
     clearChat,
     updateById
   }

+ 8 - 0
src/router/index.js

@@ -9,6 +9,14 @@ const constantRouterMap = [
       title: "智慧总控"
     }
   },
+  {
+    path: '/count',
+    name: 'count',
+    component: () => import('@/views/count/index.vue'),
+    meta: {
+      title: "临时统计"
+    }
+  },
   {
     path: '/login',
     name: 'Login',

+ 16 - 2
src/views/answer/AnswerView.vue

@@ -161,6 +161,12 @@ const handeChatDelete = async (id) => {
   message.success('删除成功');
 }
 
+// 停止问题生成
+const onStopChatStream  = async ({ sessionId }) => {
+  await chatApi.getStopChatStream(sessionId);
+  return message.warning('已停止对话生成');
+}
+
 onMounted(() => {
   const question = chatStore.chatQuestion;
   if (Object.keys(question).length) {
@@ -200,8 +206,16 @@ onUnmounted(() => {
       <div class="conversation-item" v-if="chatDataSource.length">
         <template v-for="item in chatDataSource" :key="item.id">
           <ChatAsk :content="item.question" :sessionId="item.sessionId"></ChatAsk>
-          <ChatAnswer :id="item.id" :content="item.answer" :loading="item.loading" :delay-loading="item.delayLoading"
-            :isSatisfied="item.isSatisfied" @on-click-icon="params => updateById(params)"></ChatAnswer>
+          <ChatAnswer
+            :id="item.id"
+            :content="item.answer"
+            :loading="item.loading"
+            :delay-loading="item.delayLoading"
+            :isSatisfied="item.isSatisfied"
+            isVisibleStopBtn
+            @on-click-stop="onStopChatStream(item)"
+            @on-click-icon="params => updateById(params)">
+          </ChatAnswer>
         </template>
       </div>
 

+ 70 - 0
src/views/count/index.vue

@@ -0,0 +1,70 @@
+<script setup>
+import { ref } from 'vue';
+import { NButton, NSpace, NDrawer } from 'naive-ui';
+import { BaseButton, RecodeCardItem, TheSubMenu, TheChatView, ChatWelcome } from '@/components';
+import { ChatAsk, ChatAnswer, ChatInput } from '@/components/Chat';
+
+const visible = ref(false);
+
+const changeVisible = () => {
+  visible.value = !visible.value;
+}
+
+</script>
+
+<template>
+  <section class="page-container">
+    <header class="header">
+      <NSpace>
+        <n-button>下一页</n-button>
+        <n-button @click="changeVisible">显示错误id</n-button>
+      </NSpace>
+    </header>
+    <div class="main">
+      <div class="answer-block" v-for="item in 100">
+        <ChatAsk content="问题问题问题"></ChatAsk>
+        <ChatAnswer content="回答回答回答回答回答" :toggleVisibleIcons="false"></ChatAnswer>
+        <div class="answer-btns">
+          <NSpace>
+            <NButton type="success">对</NButton>
+            <NButton type="error">错</NButton>
+          </NSpace>
+        </div>
+      </div>
+    </div>
+  </section>
+
+  <NDrawer placement="right" v-model:show="visible" width="600">123123</NDrawer>
+</template>
+
+<style lang="scss" scoped>
+.page-container {
+  width: 100vw;
+  height: 100vh;
+  background: #edf7fc;
+
+  .header {
+    display: flex;
+    justify-content: center;
+    padding: 20px 0;
+    background: #fff;
+  }
+
+  .main {
+    width: 1000px;
+    height: calc(100% - 74px);
+    margin: 0 auto;
+    overflow-y: scroll;
+
+    .answer-block {
+      border-bottom: 1px solid #000000;
+      padding-bottom: 20px;
+    }
+
+    .answer-btns {
+      display: flex;
+      justify-content: flex-end;
+    }
+  }
+}
+</style>

+ 0 - 4
src/views/screen/ScreenView.vue

@@ -104,7 +104,6 @@ onBeforeUnmount(() => {
       <RouterLink to="/work" class="item item4">智能办公</RouterLink>
     </div>
     <div class="screen-container">
-      <!-- <div class="water-work-inner"></div> -->
       <div class="screen-container-main">
         <div class="left">
           <shuizhi :screenData="screenData"></shuizhi>
@@ -113,9 +112,6 @@ onBeforeUnmount(() => {
         </div>
         <div class="middle">
           <middleBox :dataTime="dataTime"></middleBox>
-          <!-- <div class="img-card">
-            <img src="@/assets/images/home/water-work.png" alt="" />
-          </div> -->
         </div>
         <div class="right">
           <ControlHelper></ControlHelper>

+ 2 - 2
src/views/screen/components/ControlHelper.vue

@@ -1,5 +1,5 @@
 <script setup>
-import { ref, watch, onMounted, onUnmounted } from 'vue';
+import { ref, onMounted, onUnmounted } from 'vue';
 import { screenApi } from '@/api/screen';
 import * as echarts from 'echarts';
 import dayjs from 'dayjs';
@@ -10,7 +10,6 @@ let echart = null;
 
 const echartRef = ref(null);
 const legendData = ref([]);
-const dateTime = ref();
 const dataSource = ref({});
 
 const windowResize = () => echart.resize();
@@ -43,6 +42,7 @@ onMounted(async () => {
 
 onUnmounted(() => {
   window.removeEventListener("resize", windowResize);
+  echart && echart.dispose();
 })
 
 </script>