Parcourir la source

feat: 合并预设问题暗黑模式

zhouyuhao il y a 7 mois
Parent
commit
983b3af45c

Fichier diff supprimé car celui-ci est trop grand
+ 0 - 0
src/styles/icons/iconfont.js


BIN
src/styles/icons/iconfont.ttf


BIN
src/styles/icons/iconfont.woff


BIN
src/styles/icons/iconfont.woff2


+ 26 - 22
src/views/AIRobotChat/src/AIRobotChat.vue

@@ -48,6 +48,7 @@ interface MessageItem {
 const messages = ref<MessageItem[]>([
   {
     type: 'robot',
+    isShowFeedback: true,
     content: 'You can click on Frequently Asked Questions above or type your own question'
   },
   {
@@ -57,7 +58,7 @@ const messages = ref<MessageItem[]>([
   {
     type: 'robot',
     feedback: '',
-    isShowFeedback: false,
+    isShowFeedback: true,
     isAnswer: true,
     content: 'Can you help me with my shipment?'
   },
@@ -81,14 +82,14 @@ const progressStatus = {
 }
 
 const progressInterval = ref()
-const handleSend = () => {
-  if (!userQuestion.value) return
+const handleSend = (question, isPresetQuestion = true) => {
+  if (!question) return
 
   messages.value.push({
     type: 'user',
-    content: userQuestion.value
+    content: question
   })
-  userQuestion.value = ''
+  !isPresetQuestion ? (question = '') : ''
   queryTime.value = 0
   messages.value.push({
     type: 'robot',
@@ -163,7 +164,7 @@ const handleClose = () => {
           <span @click="handleClose" class="font_family icon-icon_collapsed__to_widget_b"></span>
         </div>
       </div>
-      <AIQuestions :modalSize="modalSize"></AIQuestions>
+      <AIQuestions :modalSize="modalSize" @question="handleSend"></AIQuestions>
     </div>
     <div
       class="chat-messages"
@@ -183,12 +184,11 @@ const handleClose = () => {
         @mouseenter="msg.isShowFeedback = true"
         @mouseleave="msg.isShowFeedback = false"
       >
-        <!-- 请求失败后的提示icon -->
-        <span
+        <!-- 请求失败后的提示icon  -->
+        <div
           v-if="queryTime === -3 && index === messages.length - 1"
-          class="font_family icon-icon_warning_fill_b"
-          style="margin-top: 1px; color: #c9353f"
-        ></span>
+          class="pause-icon font_family icon-icon_warning_fill_b"
+        ></div>
         <!-- loading icon -->
         <img
           class="loading-img"
@@ -196,13 +196,14 @@ const handleClose = () => {
           src="./image/icon_loading.png"
           alt=""
         />
-        <p v-if="!msg.isAnswer">{{ msg.content }}</p>
+        <span v-if="!msg.isAnswer">{{ msg.content }}</span>
         <div v-else>
           <div v-html="renderedMessage" class="markdown-body"></div>
           <LoadingDots></LoadingDots>
           <div></div>
         </div>
-        <div class="review" v-if="msg.isShowFeedback && msg.isAnswer">
+        <!-- 评价 && msg.isAnswer -->
+        <div class="review" v-if="msg.isShowFeedback">
           <el-button
             v-if="msg.feedback !== 'good'"
             class="el-button--text"
@@ -254,7 +255,7 @@ const handleClose = () => {
       <div
         class="input-icon"
         :class="[userQuestion ? 'input-style' : 'disable']"
-        @click="handleSend"
+        @click="handleSend(userQuestion.value, false)"
       >
         <span class="font_family icon-icon_send_b"></span>
       </div>
@@ -339,14 +340,17 @@ const handleClose = () => {
           margin-left: 0px;
         }
       }
-      .review-input-card {
-        margin-top: 6px;
-        padding: 8px;
-        text-align: right;
-        box-shadow: 1px 1px 12px 0px rgba(0, 0, 0, 0.05);
-        border-radius: 6px;
-      }
 
+      .pause-icon {
+        height: 16px;
+        width: 16px;
+        margin-top: 1px;
+        margin-right: 4px;
+        color: #c9353f;
+        background-color: #fff;
+        border-radius: 50%;
+        border: none;
+      }
       .el-button--text {
         height: 16px;
         width: 16px;
@@ -365,7 +369,7 @@ const handleClose = () => {
         width: 16px;
         height: 16px;
         margin-top: -1px;
-        margin-right: 2px;
+        margin-right: 4px;
         animation: loading-rotate 2s linear infinite;
       }
 

+ 95 - 74
src/views/AIRobotChat/src/components/AIQuestions.vue

@@ -37,129 +37,150 @@ const DeQuestions = ref([
     isLong: false
   },
   {
-    label: 'List shipments with ETA changes in the last 30 days11111111111111111111111111111111111.',
-    value: 'List shipments with ETA changes in the last 30 days11111111111111111111111111111111111.',
+    label:
+      'List shipments with ETA changes in the last 30 days11111111111111111111111111111111111.',
+    value:
+      'List shipments with ETA changes in the last 30 days11111111111111111111111111111111111.',
     isLong: true
   },
   {
-    label: 'List shipments with ETA changes in the last 30 days1111111111111111111111111111111111122.',
-    value: 'List shipments with ETA changes in the last 30 days1111111111111111111111111111111111122.',
+    label:
+      'List shipments with ETA changes in the last 30 days1111111111111111111111111111111111122.',
+    value:
+      'List shipments with ETA changes in the last 30 days1111111111111111111111111111111111122.',
     isLong: true
   },
   {
-    label: 'List shipments with ETA changes in the last 30 days1111111111111111111111111111111111133.',
-    value: 'List shipments with ETA changes in the last 30 days1111111111111111111111111111111111133.',
+    label:
+      'List shipments with ETA changes in the last 30 days1111111111111111111111111111111111133.',
+    value:
+      'List shipments with ETA changes in the last 30 days1111111111111111111111111111111111133.',
     isLong: true
-  },
+  }
 ])
-const itemGroups = ref([]);
-const pages = ref([]);
+const itemGroups = ref([])
+const pages = ref([])
 // 随机显示方法
 const prepareGroups = () => {
-  const groups = [];
-  let currentGroup = [];
-  let currentHeight = 0;
+  const groups = []
+  let currentGroup = []
+  let currentHeight = 0
+
+  DeQuestions.value.forEach((item) => {
+    const itemHeight = item.isLong ? 2 : 1
 
-  DeQuestions.value.forEach(item => {
-    const itemHeight = item.isLong ? 2 : 1;
-    
     if (currentHeight + itemHeight > 4) {
-      groups.push(currentGroup);
-      currentGroup = [];
-      currentHeight = 0;
+      groups.push(currentGroup)
+      currentGroup = []
+      currentHeight = 0
     }
-    
-    currentGroup.push(item);
-    currentHeight += itemHeight;
-  });
+
+    currentGroup.push(item)
+    currentHeight += itemHeight
+  })
 
   // 添加最后一组
   if (currentGroup.length > 0) {
-    groups.push(currentGroup);
+    groups.push(currentGroup)
   }
 
-  itemGroups.value = groups;
+  itemGroups.value = groups
 }
 // 智能分页算法
 const generatePages = () => {
-  const result = [];
-  let currentPage = { row1: [], row2: [] };
-  let cursor = 0;
-  
-  while(cursor < DeQuestions.value.length) {
+  const result = []
+  let currentPage = { row1: [], row2: [] }
+  let cursor = 0
+
+  while (cursor < DeQuestions.value.length) {
     // 处理第一排
-    const currentItem = DeQuestions.value[cursor];
+    const currentItem = DeQuestions.value[cursor]
     // 第一排逻辑
-    if(currentItem.isLong) {
+    if (currentItem.isLong) {
       // 长文本独占第一排
-      currentPage.row1.push(currentItem);
-      cursor++;
+      currentPage.row1.push(currentItem)
+      cursor++
     } else {
       // 尝试取两个短文本
-      const nextItem = DeQuestions.value[cursor + 1];
-      if(nextItem && !nextItem.isLong) {
-        currentPage.row1.push(currentItem, nextItem);
-        cursor += 2;
+      const nextItem = DeQuestions.value[cursor + 1]
+      if (nextItem && !nextItem.isLong) {
+        currentPage.row1.push(currentItem, nextItem)
+        cursor += 2
       } else {
-        currentPage.row1.push(currentItem);
-        cursor++;
+        currentPage.row1.push(currentItem)
+        cursor++
       }
     }
 
     // 处理第二排
-    const remaining = DeQuestions.value.slice(cursor);
-    if(remaining.length > 0) {
-      const secondItem = remaining[0];
-      
-      if(secondItem.isLong) {
-        currentPage.row2.push(secondItem);
-        cursor++;
+    const remaining = DeQuestions.value.slice(cursor)
+    if (remaining.length > 0) {
+      const secondItem = remaining[0]
+
+      if (secondItem.isLong) {
+        currentPage.row2.push(secondItem)
+        cursor++
       } else {
-        const nextSecondItem = remaining[1];
-        if(nextSecondItem && !nextSecondItem.isLong) {
-          currentPage.row2.push(secondItem, nextSecondItem);
-          cursor += 2;
+        const nextSecondItem = remaining[1]
+        if (nextSecondItem && !nextSecondItem.isLong) {
+          currentPage.row2.push(secondItem, nextSecondItem)
+          cursor += 2
         } else {
-          currentPage.row2.push(secondItem);
-          cursor++;
+          currentPage.row2.push(secondItem)
+          cursor++
         }
       }
     }
 
     // 保存当前页
-    result.push(currentPage);
-    
+    result.push(currentPage)
+
     // 重置页面
-    currentPage = { row1: [], row2: [] };
+    currentPage = { row1: [], row2: [] }
   }
-  pages.value = result.filter(p => p.row1.length > 0);
+  pages.value = result.filter((p) => p.row1.length > 0)
   console.log(pages.value)
 }
 onMounted(() => {
   prepareGroups()
   generatePages()
-});
+})
+
+const emit = defineEmits<{ question: [string] }>()
+const clickQuestion = (question) => {
+  emit('question', question)
+}
 </script>
 <template>
   <div class="flex_center">
-    <div class="dialogue_content ">
+    <div class="dialogue_content">
       <div class="dialogue_content_title">
         <div class="dialogue_title_left">
-          <img class="dialogue_title_left_img" src="../image/icon_ai_robot48_b@2x.png" width="48px" />
+          <img
+            class="dialogue_title_left_img"
+            src="../image/icon_ai_robot48_b@2x.png"
+            width="48px"
+          />
           <div class="dialogue_title_left_text">Frequently Asked Questions</div>
         </div>
       </div>
-      <el-carousel v-if="props.modalSize === 'large'"  class="carousel large_carousel" :autoplay="false" height="115px" >
-        <el-carousel-item 
-          v-for="(page, index) in pages "
-          :key="index"
-        >
+      <el-carousel
+        v-if="props.modalSize === 'large'"
+        class="carousel large_carousel"
+        :autoplay="false"
+        height="115px"
+      >
+        <el-carousel-item v-for="(page, index) in pages" :key="index">
           <div class="dialogue_container dialogue_container_large">
             <div class="double-row-layout">
               <!-- 第一排 -->
               <div class="row first-row">
                 <template v-for="item in page.row1" :key="item.id">
-                  <div class="dialogue_content_item" :class="{ 'long-item': item.isLong }">
+                  <div
+                    @click="clickQuestion(item.label)"
+                    class="dialogue_content_item"
+                    :class="{ 'long-item': item.isLong }"
+                  >
                     {{ item.label }}
                   </div>
                 </template>
@@ -167,7 +188,11 @@ onMounted(() => {
               <!-- 第二排 -->
               <div class="row second-row">
                 <template v-for="item in page.row2" :key="item.id">
-                  <div class="dialogue_content_item" :class="{ 'long-item': item.isLong }">
+                  <div
+                    @click="clickQuestion(item.label)"
+                    class="dialogue_content_item"
+                    :class="{ 'long-item': item.isLong }"
+                  >
                     {{ item.label }}
                   </div>
                 </template>
@@ -176,17 +201,14 @@ onMounted(() => {
           </div>
         </el-carousel-item>
       </el-carousel>
-      <el-carousel v-else  class="carousel small_carousel" :autoplay="false" height="190px" >
-        <el-carousel-item 
-          v-for="(group, index) in itemGroups "
-          :key="index"
-        >
+      <el-carousel v-else class="carousel small_carousel" :autoplay="false" height="190px">
+        <el-carousel-item v-for="(group, index) in itemGroups" :key="index">
           <div class="dialogue_container">
-            <div 
+            <div
               class="dialogue_content_item"
               v-for="item in group"
               :key="item.label"
-              :class="{ 'long_item': item.isLong }"
+              :class="{ long_item: item.isLong }"
             >
               {{ item.label }}
             </div>
@@ -260,4 +282,3 @@ onMounted(() => {
   padding-bottom: 0 !important;
 }
 </style>
-

Certains fichiers n'ont pas été affichés car il y a eu trop de fichiers modifiés dans ce diff