zhouyuhao 7 месяцев назад
Родитель
Сommit
404efce3d3

+ 12 - 2
src/styles/elementui.scss

@@ -171,7 +171,7 @@ button.el-button.el-button--icon {
   }
 }
 // 初始为黑色
-.el-button.el-button--dark {
+button.el-button.el-button--dark {
   background-color: var(--color-btn-default-dark-bg);
   fill: var(--color-white);
   border: none;
@@ -183,7 +183,17 @@ button.el-button.el-button--icon {
     background-color: var(--color-btn-default-dark-hover-bg);
     fill: var(--color-btn-default-dark-hover-bg);
     span {
-      color: var(--color-btn-default-dark-hover) !important;
+      color: var(--color-btn-default-dark-hover);
+    }
+  }
+}
+button.el-button.el-button--dark.is-disabled {
+  opacity: 0.3;
+  &:hover {
+    background-color: var(--color-btn-default-dark-bg);
+    fill: var(--color-white);
+    span {
+      color: var(--color-white);
     }
   }
 }

+ 20 - 4
src/styles/icons/iconfont.css

@@ -1,9 +1,9 @@
 @font-face {
   font-family: "font_family"; /* Project id 4672385 */
-  src: url('iconfont.woff2?t=1744961152220') format('woff2'),
-       url('iconfont.woff?t=1744961152220') format('woff'),
-       url('iconfont.ttf?t=1744961152220') format('truetype'),
-       url('iconfont.svg?t=1744961152220#font_family') format('svg');
+  src: url('iconfont.woff2?t=1745286986564') format('woff2'),
+       url('iconfont.woff?t=1745286986564') format('woff'),
+       url('iconfont.ttf?t=1745286986564') format('truetype'),
+       url('iconfont.svg?t=1745286986564#font_family') format('svg');
 }
 
 .font_family {
@@ -14,6 +14,22 @@
   -moz-osx-font-smoothing: grayscale;
 }
 
+.icon-icon_good_b:before {
+  content: "\e713";
+}
+
+.icon-icon_notgood__filled_b:before {
+  content: "\e714";
+}
+
+.icon-icon_good__filled_b:before {
+  content: "\e715";
+}
+
+.icon-icon_notgood_b:before {
+  content: "\e716";
+}
+
 .icon-icon_send_b:before {
   content: "\e712";
 }

Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/styles/icons/iconfont.js


+ 8 - 0
src/styles/icons/iconfont.svg

@@ -14,6 +14,14 @@
     />
       <missing-glyph />
       
+      <glyph glyph-name="icon_good_b" unicode="&#59155;" d="M549.376 780.48c-38.272 0-73.6-20.608-92.352-53.888L297.408 444.032H135.04a32 32 0 0 1-32-32v-392.384a32 32 0 0 1 32-32h98.56v-0.128h64v0.128h430.72a96 96 0 0 1 92.352 69.952l90.24 320.256a96 96 0 0 1-92.352 122.048h-162.944V674.368c0 58.624-47.552 106.112-106.176 106.112zM297.6 51.648v328.32h18.56a32 32 0 0 1 27.776 16.32L512.704 695.04a42.112 42.112 0 0 0 78.848-20.736v-206.464a32 32 0 0 1 32-32h194.944a32 32 0 0 0 30.72-40.64l-90.24-320.32a32 32 0 0 0-30.72-23.296h-430.72z m-64 328.32v-328.32H167.04v328.32h66.56z"  horiz-adv-x="1088" />
+      
+      <glyph glyph-name="icon_notgood__filled_b" unicode="&#59156;" d="M488.576-69.568c38.272 0 73.6 20.608 92.416 53.952l159.36 282.176V723.328H309.76a96 96 0 0 1-92.352-70.016l-90.24-320.256a96 96 0 0 1 92.352-122.048h162.944v-174.464c0-58.624 47.552-106.112 106.112-106.112z m315.776 792.896V266.88h98.624a32 32 0 0 1 32 32V691.2a32 32 0 0 1-32 32h-98.56z"  horiz-adv-x="1088" />
+      
+      <glyph glyph-name="icon_good__filled_b" unicode="&#59157;" d="M574.4 780.48c-38.272 0-73.6-20.608-92.416-53.888L322.432 444.032H160a32 32 0 0 1-32-32v-392.384a32 32 0 0 1 32-32h98.56v456.32h64v-456.32h430.656a96 96 0 0 1 92.416 69.952l90.24 320.256a96 96 0 0 1-92.416 122.048h-162.944V674.368c0 58.624-47.488 106.112-106.112 106.112z"  horiz-adv-x="1088" />
+      
+      <glyph glyph-name="icon_notgood_b" unicode="&#59158;" d="M488.576-69.568c38.272 0 73.6 20.608 92.416 53.952l159.616 282.56h162.368a32 32 0 0 1 32 32V691.2a32 32 0 0 1-32 32H309.76a96 96 0 0 1-92.352-69.952l-90.24-320.256a96 96 0 0 1 92.352-122.048h162.944v-174.464c0-58.624 47.552-106.112 106.112-106.112z m36.672 85.44a42.112 42.112 0 0 0-78.72 20.672v206.464a32 32 0 0 1-32 32H219.52a32 32 0 0 0-30.784 40.704l90.24 320.256a32 32 0 0 0 30.784 23.36h430.656V330.88h-18.56a32 32 0 0 1-27.84-16.256l-168.768-298.88zM804.48 330.88V659.2h66.56v-328.32h-66.56z"  horiz-adv-x="1088" />
+      
       <glyph glyph-name="icon_send_b" unicode="&#59154;" d="M678.272 424.256l-460.928 225.92 56.32-225.92h404.608z m-403.712-76.8l-57.216-229.568 468.352 229.568H274.56z m601.664 65.28a32 32 0 0 0 0-57.472L164.672 6.592a32 32 0 0 0-45.184 36.48l83.072 333.184a32 32 0 0 1 0 15.488L119.488 724.992a32 32 0 0 0 45.184 36.48L876.16 412.736z"  horiz-adv-x="1088" />
       
       <glyph glyph-name="icon_sidebar__window_b" unicode="&#59151;" d="M740.352 809.28h132.16v-76.8h-132.16v76.8z m-72.448-102.592a25.6 25.6 0 0 0 25.6 25.6v76.8H119.04a102.4 102.4 0 0 1-102.4-102.4v-645.376a102.4 102.4 0 0 1 102.4-102.4H693.504v76.8a25.6 25.6 0 0 0-25.6 25.6v80.64h-76.8v-80.64c0-8.832 1.088-17.408 3.2-25.6H119.04a25.6 25.6 0 0 0-25.6 25.6V706.688c0 14.08 11.456 25.6 25.6 25.6h475.264c-2.112-8.192-3.2-16.768-3.2-25.6v-80.64h76.8v80.64z m251.072 25.6a25.6 25.6 0 0 0 25.6-25.6v-80.64h76.8v80.64a102.4 102.4 0 0 1-102.4 102.4v-76.8zM667.904 410.88V572.16h-76.8v-161.28h76.8z m276.672 161.28v-161.28h76.8V572.16h-76.8z m-276.672-376.384v161.28h-76.8v-161.28h76.8z m276.672 161.28v-161.28h76.8v161.28h-76.8z m0-215.04v-80.64a25.6 25.6 0 0 0-25.6-25.6v-76.8a102.4 102.4 0 0 1 102.4 102.4v80.64h-76.8zM541.632 406.592L433.28 514.944l-45.248-45.248 53.76-53.76H186.88v-64h254.784l-53.696-53.696 45.248-45.248 108.352 108.352a32 32 0 0 1 0 45.248z m330.88-370.88h-132.16v-76.8h132.16v76.8z"  horiz-adv-x="1088" />

BIN
src/styles/icons/iconfont.ttf


BIN
src/styles/icons/iconfont.woff


BIN
src/styles/icons/iconfont.woff2


+ 94 - 31
src/views/AIRobotChat/src/AIRobotChat.vue

@@ -1,7 +1,8 @@
 <script setup lang="ts">
+import AutoResizeTextarea from './components/AutoResizeTextarea.vue'
 const modalSize = ref('large')
 
-const inputVModel = ref()
+const userQuestion = ref()
 
 const isFooterInputFocus = ref(false)
 const textareaRef = ref(null)
@@ -37,6 +38,7 @@ const messages = ref([
   },
   {
     type: 'robot',
+    allowComments: true,
     content: 'Can you help me with my shipment?'
   },
   {
@@ -60,12 +62,12 @@ const progressStatus = {
 
 const progressInterval = ref()
 const handleSend = () => {
-  if (!inputVModel.value) return
+  if (!userQuestion.value) return
   messages.value.push({
     type: 'user',
-    content: inputVModel.value
+    content: userQuestion.value
   })
-  inputVModel.value = ''
+  userQuestion.value = ''
   textareaRef.value.style.height = '29px' // 重置高度
   queryTime.value = 0
   messages.value.push({
@@ -120,6 +122,8 @@ const handleClose = () => {
   progressInterval.value && clearInterval(progressInterval.value)
   emit('close')
 }
+// 评论icon
+const reviewStatus = ref()
 </script>
 
 <template>
@@ -168,6 +172,38 @@ const handleClose = () => {
           alt=""
         />
         {{ msg.content }}
+        <div class="review" v-if="msg.allowComments">
+          <div class="review-icon">
+            <el-button
+              v-if="reviewStatus !== 'good'"
+              class="el-button--text"
+              @click="reviewStatus = 'good'"
+            >
+              <span class="font_family icon-icon_good_b"></span>
+            </el-button>
+            <div v-if="reviewStatus === 'good'" style="width: 33px; text-align: center">
+              <span class="font_family icon-icon_good__filled_b"></span>
+            </div>
+            <el-button
+              v-if="reviewStatus !== 'noGood'"
+              class="el-button--text"
+              @click="reviewStatus = 'noGood'"
+            >
+              <span class="font_family icon-icon_notgood_b"></span>
+            </el-button>
+            <div v-if="reviewStatus === 'noGood'" style="width: 33px; text-align: center">
+              <span class="font_family icon-icon_notgood__filled_b"></span>
+            </div>
+          </div>
+          <div class="review-input-card">
+            <span class="font_family icon-icon_reject_b"></span>
+            <div class="review-input">
+              <AutoResizeTextarea v-model="userQuestion" />
+              <el-button class="el-button--dark" size="small">Submit</el-button>
+            </div>
+          </div>
+        </div>
+
         <img
           class="robot-bubble-img"
           v-if="msg.type === 'robot'"
@@ -192,19 +228,14 @@ const handleClose = () => {
     </div>
 
     <div class="footer-input" :class="[isFooterInputFocus ? 'focus-style' : '']">
-      <textarea
-        ref="textareaRef"
-        v-model="inputVModel"
-        class="input-area"
-        rows="1"
-        placeholder="Type your question here..."
-        @input="resize"
+      <AutoResizeTextarea
+        v-model="userQuestion"
         @focus="isFooterInputFocus = true"
         @blur="isFooterInputFocus = false"
       />
       <div
         class="input-icon"
-        :class="[inputVModel ? 'input-style' : 'disable']"
+        :class="[userQuestion ? 'input-style' : 'disable']"
         @click="handleSend"
       >
         <span class="font_family icon-icon_send_b"></span>
@@ -260,12 +291,44 @@ const handleClose = () => {
     gap: 16px;
     margin-top: 81px;
     padding: 0 16px;
+    overflow: auto;
     .message-item {
       position: relative;
       display: inline-block;
       padding: 11px 8px;
       margin-bottom: 7px;
       border-radius: 12px;
+      .review {
+        margin-top: 10px;
+        .review-icon {
+          display: flex;
+          align-items: center;
+          gap: 6px;
+        }
+        button.el-button + .el-button {
+          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;
+      }
+      .review-input {
+        padding: 8px;
+        border: 1px solid var(--color-border);
+        border-radius: 6px;
+      }
+      .el-button--text {
+        &:hover {
+          span {
+            color: var(--color-theme);
+          }
+        }
+      }
+
       .loading-img {
         width: 16px;
         height: 16px;
@@ -351,25 +414,25 @@ const handleClose = () => {
   .focus-style {
     border-color: var(--color-theme);
   }
-  .input-area {
-    width: 100%;
-    font-size: 14px;
-    line-height: 21px;
-    padding: 4px;
-    resize: none;
-    overflow-y: hidden; // 默认不显示滚动条
-    height: 40px; // 初始高度(1 行)
-    max-height: 100px; // 最多 4 行
-    box-sizing: border-box;
-    border: none;
-    outline-color: #fff;
-    border-radius: 8px;
-    transition: height 0.1s ease;
-    &::placeholder {
-      color: #b5b9bf;
-      opacity: 1;
-    }
-  }
+  // .input-area {
+  //   width: 100%;
+  //   font-size: 14px;
+  //   line-height: 21px;
+  //   padding: 4px;
+  //   resize: none;
+  //   overflow-y: hidden; // 默认不显示滚动条
+  //   height: 40px; // 初始高度(1 行)
+  //   max-height: 100px; // 最多 4 行
+  //   box-sizing: border-box;
+  //   border: none;
+  //   outline-color: #fff;
+  //   border-radius: 8px;
+  //   transition: height 0.1s ease;
+  //   &::placeholder {
+  //     color: #b5b9bf;
+  //     opacity: 1;
+  //   }
+  // }
   @keyframes loading-rotate {
     0% {
       transform: rotate(0deg);

+ 67 - 0
src/views/AIRobotChat/src/components/AutoResizeTextarea.vue

@@ -0,0 +1,67 @@
+<script setup lang="ts">
+const inputVModel = defineModel({ type: String })
+
+watch(
+  () => inputVModel.value,
+  () => {
+    textareaRef.value.style.height = '30px' // 重置高度
+  }
+)
+const textareaRef = ref(null)
+// 实现自适应高度(最多 4 行)
+const resize = () => {
+  const el = textareaRef.value
+  if (!el) return
+
+  el.style.height = 'auto' // 先清空旧高度
+  const scrollHeight = el.scrollHeight
+
+  const maxHeight = 92 // 四行时高度
+
+  if (scrollHeight <= maxHeight) {
+    el.style.overflowY = 'hidden'
+    el.style.height = scrollHeight + 'px'
+  } else {
+    el.style.overflowY = 'auto'
+    el.style.height = maxHeight + 'px'
+  }
+}
+const emit = defineEmits(['focus', 'blur'])
+</script>
+
+<template>
+  <textarea
+    ref="textareaRef"
+    v-model="inputVModel"
+    class="input-area"
+    rows="1"
+    placeholder="Type your question here..."
+    @input="resize"
+    @focus="emit('focus')"
+    @blur="emit('blur')"
+  />
+</template>
+
+<style lang="scss" scoped>
+.input-area {
+  width: 100%;
+  font-size: 14px;
+  line-height: 21px;
+  padding: 4px;
+  resize: none;
+  overflow-y: hidden; // 默认不显示滚动条
+  height: 30px; // 初始高度(1 行)
+  max-height: 92px; // 最多 4 行
+  box-sizing: border-box;
+  border: none;
+  outline-color: transparent;
+  outline: none;
+  background-color: transparent;
+  border-radius: 8px;
+  transition: height 0.1s ease;
+  &::placeholder {
+    color: #b5b9bf;
+    opacity: 1;
+  }
+}
+</style>

+ 4 - 0
src/views/Layout/src/LayoutView.vue

@@ -19,6 +19,9 @@ const isShowAIRobotChat = ref(true)
 const handleColseRobotChat = () => {
   isShowAIRobotChat.value = false
 }
+const onClick = () => {
+  isShowAIRobotChat.value = true
+}
 </script>
 <template>
   <el-container class="layout-container">
@@ -38,6 +41,7 @@ const handleColseRobotChat = () => {
 
     <!-- 右侧整体布局 -->
     <el-container style="min-width: 900px">
+      <el-button @click="onClick">测试</el-button>
       <!-- 顶部Header -->
       <el-header class="layout-header">
         <Header></Header>

Некоторые файлы не были показаны из-за большого количества измененных файлов