瀏覽代碼

feat: 实现ai功能部分暗黑模式样式

zhouyuhao 7 月之前
父節點
當前提交
9ad7da13d1

+ 14 - 2
src/styles/theme.scss

@@ -76,8 +76,6 @@
   --color-border: #eaebed;
   --color-select-border: #eaebed;
   --border-color-2: #eaebed;
-  --color-border-1: #e8eaee;
-  --color-border-2: #eaebed;
 
   --color-mune-active-bg: #fdf5f1;
 
@@ -282,6 +280,13 @@
   --color-system-border-1: #e8eaee;
   --color-system-input-border: #e8eaee;
   --color-personal-preference-bg: #f5f7fa;
+
+  --color-ai-chat-header-bg-gradient-begin: #eaecff;
+  --color-ai-chat-header-bg-gradient-end: #fefdff;
+  --color-ai-user-bubble-bg-gradient-begin: #ffede6;
+  --color-ai-user-bubble-bg-gradient-end: #f2f4f7;
+  --input-border: #eaebed;
+  --color-pause-btn-bg: #fff1e6;
 }
 
 :root.dark {
@@ -456,4 +461,11 @@
       fill: var(--color-white);
     }
   }
+
+  --color-ai-chat-header-bg-gradient-begin: #484f82;
+  --color-ai-chat-header-bg-gradient-end: #31363d;
+  --color-ai-user-bubble-bg-gradient-begin: #716763;
+  --color-ai-user-bubble-bg-gradient-end: #5c6a7d;
+  --input-border: #656f7d;
+  --color-pause-btn-bg: #453b36;
 }

+ 68 - 87
src/views/AIRobotChat/src/AIRobotChat.vue

@@ -1,32 +1,23 @@
 <script setup lang="ts">
 import AutoResizeTextarea from './components/AutoResizeTextarea.vue'
-const modalSize = ref('large')
+import userBubbleLight from './image/userBubbleLight.png'
+import userBubbleDark from './image/userBubbleDark.png'
+import robotBubbleLight from './image/robotBubbleLight.png'
+import robotBubbleDark from './image/robotBubbleDark.png'
+import { useThemeStore } from '@/stores/modules/theme'
 
+const themeStore = useThemeStore()
+const modalSize = ref('large')
 const userQuestion = ref()
 
 const isFooterInputFocus = ref(false)
-const textareaRef = ref(null)
-// 实现自适应高度(最多 4 行)
-const resize = () => {
-  const el = textareaRef.value
-  if (!el) return
-
-  el.style.height = 'auto' // 先清空旧高度
-  const scrollHeight = el.scrollHeight
-
-  const maxHeight = 100 // 四行时高度
-
-  if (scrollHeight <= maxHeight) {
-    el.style.overflowY = 'hidden'
-    el.style.height = scrollHeight + 'px'
-  } else {
-    el.style.overflowY = 'auto'
-    el.style.height = maxHeight + 'px'
-  }
-}
 
-// 初始挂载和内容变化都触发 resize
-onMounted(() => nextTick(resize))
+const userBubbleImg = computed(() => {
+  return themeStore.theme === 'light' ? userBubbleLight : userBubbleDark
+})
+const robotBubbleImg = computed(() => {
+  return themeStore.theme === 'light' ? robotBubbleLight : robotBubbleDark
+})
 
 interface MessageItem {
   type: 'robot' | 'user'
@@ -47,7 +38,7 @@ const messages = ref<MessageItem[]>([
   {
     type: 'robot',
     feedback: '',
-    isShowFeedback: true,
+    isShowFeedback: false,
     isAnswer: true,
     content: 'Can you help me with my shipment?'
   },
@@ -73,12 +64,12 @@ const progressStatus = {
 const progressInterval = ref()
 const handleSend = () => {
   if (!userQuestion.value) return
+
   messages.value.push({
     type: 'user',
     content: userQuestion.value
   })
   userQuestion.value = ''
-  textareaRef.value.style.height = '29px' // 重置高度
   queryTime.value = 0
   messages.value.push({
     type: 'robot',
@@ -132,14 +123,6 @@ const handleClose = () => {
   progressInterval.value && clearInterval(progressInterval.value)
   emit('close')
 }
-
-// 关闭反馈意见
-const handleCloseFeedback = (msg) => {
-  msg.isFeedback = true
-  setTimeout(() => {
-    msg.isShowFeedback = false
-  }, 3000)
-}
 </script>
 
 <template>
@@ -191,48 +174,36 @@ const handleCloseFeedback = (msg) => {
         />
         {{ msg.content }}
         <div class="review" v-if="msg.isShowFeedback && msg.isAnswer">
-          <div class="review-icon">
-            <el-button
-              v-if="msg.feedback !== 'good'"
-              class="el-button--text"
-              @click="msg.feedback = 'good'"
-            >
-              <span class="font_family icon-icon_good_b"></span>
-            </el-button>
-            <div v-if="msg.feedback === 'good'" style="width: 16px; text-align: center">
-              <span
-                style="color: var(--color-theme); font-size: 14px"
-                class="font_family icon-icon_good__filled_b"
-              ></span>
-            </div>
-            <el-button
-              v-if="msg.feedback !== 'noGood'"
-              class="el-button--text"
-              @click="msg.feedback = 'noGood'"
-            >
-              <span class="font_family icon-icon_notgood_b"></span>
-            </el-button>
-            <div v-if="msg.feedback === 'noGood'" style="width: 16px; text-align: center">
-              <span
-                style="color: var(--color-theme); font-size: 14px"
-                class="font_family icon-icon_notgood__filled_b"
-              ></span>
-            </div>
+          <el-button
+            v-if="msg.feedback !== 'good'"
+            class="el-button--text"
+            @click="msg.feedback = 'good'"
+          >
+            <span class="font_family icon-icon_good_b"></span>
+          </el-button>
+          <div v-if="msg.feedback === 'good'" style="width: 16px; text-align: center">
+            <span
+              style="color: var(--color-theme); font-size: 14px"
+              class="font_family icon-icon_good__filled_b"
+            ></span>
+          </div>
+          <el-button
+            v-if="msg.feedback !== 'noGood'"
+            class="el-button--text"
+            @click="msg.feedback = 'noGood'"
+          >
+            <span class="font_family icon-icon_notgood_b"></span>
+          </el-button>
+          <div v-if="msg.feedback === 'noGood'" style="width: 16px; text-align: center">
+            <span
+              style="color: var(--color-theme); font-size: 14px"
+              class="font_family icon-icon_notgood__filled_b"
+            ></span>
           </div>
         </div>
 
-        <img
-          class="robot-bubble-img"
-          v-if="msg.type === 'robot'"
-          src="./image/robotBubbleLight.png"
-          alt=""
-        />
-        <img
-          class="user-bubble-img"
-          v-else-if="msg.type === 'user'"
-          src="./image/userBubbleLight.png"
-          alt=""
-        />
+        <img class="robot-bubble-img" v-if="msg.type === 'robot'" :src="robotBubbleImg" alt="" />
+        <img class="user-bubble-img" v-else-if="msg.type === 'user'" :src="userBubbleImg" alt="" />
         <!-- 暂停回答 icon -->
         <div
           class="pause-btn"
@@ -272,12 +243,18 @@ const handleCloseFeedback = (msg) => {
   display: flex;
   flex-direction: column;
   border-radius: 12px;
+  border: 1px solid var(--color-border);
   box-shadow: 4px 4px 32px 0px rgba(0, 0, 0, 0.2);
-  background-color: #fff;
+  background-color: var(--color-dialog-body-bg);
   overflow: hidden;
   .top-section {
     height: 150px;
-    background: linear-gradient(to bottom, #eaecff 10%, #eaecff 10%, #fefdff 100%);
+    background: linear-gradient(
+      to bottom,
+      var(--color-ai-chat-header-bg-gradient-begin) 10%,
+      var(--color-ai-chat-header-bg-gradient-begin) 10%,
+      var(--color-ai-chat-header-bg-gradient-end) 100%
+    );
     .header {
       display: flex;
       justify-content: space-between;
@@ -316,21 +293,20 @@ const handleCloseFeedback = (msg) => {
       padding: 11px 8px;
       margin-bottom: 7px;
       border-radius: 12px;
+      background-color: var(--scoring-bg-color);
       .review {
         position: absolute;
         bottom: -24px;
         left: 0;
+        display: flex;
+        align-items: center;
+        gap: 13px;
         width: 100%;
-        height: 50px;
+        height: 30px;
         margin-top: 10px;
         padding-left: 30px;
-        padding-top: 30px;
+        padding-top: 10px;
 
-        .review-icon {
-          display: flex;
-          align-items: center;
-          gap: 10px;
-        }
         button.el-button + .el-button {
           margin-left: 0px;
         }
@@ -375,7 +351,7 @@ const handleCloseFeedback = (msg) => {
         height: 16px;
         width: 16px;
         border-radius: 50%;
-        background-color: #fff1e6;
+        background-color: var(--color-customize-column-right-section-bg);
         .dot {
           height: 5px;
           width: 5px;
@@ -388,7 +364,7 @@ const handleCloseFeedback = (msg) => {
       color: #b5b9bf;
     }
     .robot-bubble {
-      background: #f2f4f7;
+      background: var(--scoring-bg-color);
       align-self: flex-start;
       .robot-bubble-img {
         position: absolute;
@@ -398,7 +374,11 @@ const handleCloseFeedback = (msg) => {
     }
     .user-bubble {
       align-self: flex-end;
-      background: linear-gradient(to right, #ffede6, #f2f4f7);
+      background: linear-gradient(
+        to right,
+        var(--color-ai-user-bubble-bg-gradient-begin),
+        var(--color-ai-user-bubble-bg-gradient-end)
+      );
       .user-bubble-img {
         position: absolute;
         right: 0;
@@ -413,7 +393,7 @@ const handleCloseFeedback = (msg) => {
     padding: 4px 12px;
     padding-right: 4px;
     margin: 12px 16px;
-    border: 1px solid #eaebed;
+    border: 1px solid var(--input-border);
     border-radius: 20px;
     box-sizing: border-box;
     .input-icon {
@@ -438,10 +418,11 @@ const handleCloseFeedback = (msg) => {
         background-color: #d56200;
       }
     }
+    &.focus-style {
+      border: 1px solid var(--color-theme);
+    }
   }
-  .focus-style {
-    border-color: var(--color-theme);
-  }
+
   // .input-area {
   //   width: 100%;
   //   font-size: 14px;

二進制
src/views/AIRobotChat/src/image/robotBubbleDark.png


二進制
src/views/AIRobotChat/src/image/userBubbleDark.png