Browse Source

feat: 基本布局

whh 9 months ago
parent
commit
c98ff1b629

+ 33 - 1
src/App.vue

@@ -2,12 +2,19 @@
 import { RouterView } from 'vue-router';
 import { NConfigProvider } from 'naive-ui';
 import type { GlobalThemeOverrides } from 'naive-ui';
+import { SelectProps, InputProps } from 'naive-ui'
 
+// type SelectThemeOverrides = NonNullable<SelectProps['themeOverrides']>
+type SelectThemeOverrides = NonNullable<InputProps['themeOverrides']>
 const primaryColor = '#1A2029';
 
+/**
+ * js 文件下使用这个做类型提示
+ * @type import('naive-ui').GlobalThemeOverrides
+ */
 const themeOverrides: GlobalThemeOverrides = {
   common: {
-    // primaryColor: '#2A68FF',
+    primaryColor: '#2454FF',
   },
   Menu: {
     itemTextColor: primaryColor,
@@ -18,6 +25,30 @@ const themeOverrides: GlobalThemeOverrides = {
     itemColorActive: '#FCFDFE',
     itemColorActiveHover: '#FCFDFE',
     arrowColorChildActive: primaryColor
+  },
+  Scrollbar: {
+    width: '2px',
+  },
+  Select: {
+    peers: {
+      InternalSelection: {
+        textColor: '5E5E5E',
+        borderHover: '1px solid #2454FF',
+        borderFocus: '1px solid #2454FF',
+        placeholderColor: '#ccc',
+        borderRadius: '8px'
+      }
+    },
+  },
+  Input: {
+    border: '0px',
+    borderHover: '0px ',
+    borderFocus: '0px ',
+    borderFocusWarning: '0px',
+    boxShadowFocus: 'none',
+    fontSizeMedium: '15px',
+    textColor: '#1A2029',
+    placeholderColor: 'rgba(158, 158, 158, 0.6)',
   }
   // Menu: {
   //   itemTextColorHorizontal: '#161616',
@@ -50,6 +81,7 @@ header {
   background: $el-bg-color;
   line-height: 1.5;
   max-height: 100vh;
+
   img {
     width: 200px;
   }

+ 1 - 0
src/assets/base.css

@@ -19,6 +19,7 @@
   --vt-c-text-light-2: rgba(60, 60, 60, 0.66);
   --vt-c-text-dark-1: var(--vt-c-white);
   --vt-c-text-dark-2: rgba(235, 235, 235, 0.64);
+
 }
 
 /* semantic color variables for this project */

BIN
src/assets/images/chat/img-avatar.png


BIN
src/assets/images/chat/img-user-avatar.png


BIN
src/assets/images/menu/bg-warn-card.png


+ 0 - 0
src/assets/images/warn-text.png → src/assets/images/menu/bg-warn-text.png


+ 8 - 0
src/assets/styles/mixins.scss

@@ -22,4 +22,12 @@ $flex-params: (
   @if $justify {
     justify-content: map-get($flex-params, $justify);
   }
+}
+
+@mixin textLine($num: 1) {
+  word-break: break-all;
+  overflow: hidden;
+  display: -webkit-box;
+  -webkit-line-clamp: $num;
+  -webkit-box-orient: vertical;
 }

+ 5 - 0
src/assets/svgs/tool/add-circle.svg

@@ -0,0 +1,5 @@
+<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M6.99999 12.8333C10.2217 12.8333 12.8333 10.2217 12.8333 7C12.8333 3.77834 10.2217 1.16667 6.99999 1.16667C3.77833 1.16667 1.16666 3.77834 1.16666 7C1.16666 10.2217 3.77833 12.8333 6.99999 12.8333Z" fill="white"/>
+<path d="M7 4.66666V9.33333" stroke="#2454FF" stroke-width="1.16667" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M4.66666 7H9.33332" stroke="#2454FF" stroke-width="1.16667" stroke-linecap="round" stroke-linejoin="round"/>
+</svg>

+ 5 - 0
src/assets/svgs/tool/arrow-history.svg

@@ -0,0 +1,5 @@
+<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M3.63643 3.95453V6.49998H6.18189" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M3 10C3 13.866 6.134 17 10 17C13.866 17 17 13.866 17 10C17 6.134 13.866 3 10 3C7.4093 3 5.14729 4.40739 3.93687 6.49934" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M10.0017 5.79999L10.0013 10.0031L12.9691 12.9709" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"/>
+</svg>

+ 7 - 0
src/assets/svgs/tool/arrow-right.svg

@@ -0,0 +1,7 @@
+<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M3.33334 4.375H16.6667" stroke="#4F5866" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M10 8.125H16.6667" stroke="#4F5866" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M10 11.875H16.6667" stroke="#4F5866" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M3.33334 15.625H16.6667" stroke="#4F5866" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M6.66668 7.91667L3.33334 10L6.66668 12.0833V7.91667Z" stroke="#4F5866" stroke-width="1.3" stroke-linejoin="round"/>
+</svg>

+ 6 - 0
src/assets/svgs/tool/bucket-del.svg

@@ -0,0 +1,6 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M2.66666 5H13.3333L12.3333 14.6667H3.66666L2.66666 5Z" stroke="#5E5E5E" stroke-linejoin="round"/>
+<path d="M6.66733 8.33411V11.6675" stroke="#5E5E5E" stroke-linecap="round"/>
+<path d="M9.33414 8.33313V11.6657" stroke="#5E5E5E" stroke-linecap="round"/>
+<path d="M4 4.99997L9.4414 1L12 5" stroke="#5E5E5E" stroke-linecap="round" stroke-linejoin="round"/>
+</svg>

+ 3 - 0
src/assets/svgs/tool/send-plane.svg

@@ -0,0 +1,3 @@
+<svg width="20" height="17" viewBox="0 0 20 17" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M18.3115 1.01251L1.07151 7.66505C0.0999644 8.03994 0.124302 8.58477 1.12105 8.88053L5.28659 10.1165L6.98025 15.156C7.20199 15.8158 7.78124 15.9549 8.27673 15.4641L10.4617 13.2996L14.7749 16.4603C15.3352 16.871 15.9114 16.6549 16.0626 15.9733L19.21 1.79099C19.3609 1.11135 18.9591 0.762598 18.3115 1.01251ZM15.688 4.21907L8.33426 10.771C8.20203 10.8888 8.08237 11.1223 8.06401 11.2951L7.73936 14.3473C7.70291 14.6901 7.58473 14.7042 7.47574 14.3757L6.05281 10.0865C5.99715 9.91873 6.0734 9.71306 6.22203 9.62392L15.5479 4.03026C16.1422 3.67381 16.2055 3.75799 15.688 4.21907Z" fill="white"/>
+</svg>

+ 5 - 0
src/assets/svgs/tool/voice-open.svg

@@ -0,0 +1,5 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M12 3V21C8.5 21 5.89925 16.4195 5.89925 16.4195H3C2.44771 16.4195 2 15.9718 2 15.4195V8.5054C2 7.9531 2.44771 7.5054 3 7.5054H5.89925C5.89925 7.5054 8.5 3 12 3Z" stroke="#272D35" stroke-width="1.5" stroke-linejoin="round"/>
+<path d="M16 7.5C16.3116 7.77825 16.5941 8.08985 16.8421 8.4294C17.5694 9.4252 18 10.6611 18 12C18 13.3273 17.5768 14.5534 16.8609 15.5447C16.6084 15.8943 16.3196 16.2147 16 16.5" stroke="#272D35" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M17.1179 20.5928C20.0418 18.8476 22 15.6525 22 12C22 8.40425 20.1021 5.25175 17.2535 3.48953" stroke="#272D35" stroke-width="1.5" stroke-linecap="round"/>
+</svg>

+ 25 - 0
src/components/BaseButton/index.vue

@@ -0,0 +1,25 @@
+<script setup>
+
+</script>
+
+<template>
+  <button class="
+    custom-btn
+    flex items-center justify-center
+    w-full py-[10px] rounded-[6px]
+    bg-[#2454FF]
+    text-[#fff] text-[14px]
+    space-x-[6px] leading-[20px]
+  ">
+    <SvgIcon name="tool-add-circle"></SvgIcon>
+    <span>新建对话</span>
+  </button>
+</template>
+
+<style scoped lang="scss">
+.custom-btn {
+  &:hover {
+    background: #1D43CC;
+  }
+}
+</style>

+ 21 - 0
src/components/BasePopover/index.vue

@@ -0,0 +1,21 @@
+<script setup>
+import { defineProps } from 'vue';
+import { NPopover } from 'naive-ui';
+
+defineProps(['placement', 'content'])
+
+</script>
+
+<template>
+  <NPopover
+    raw
+    :placement="placement"
+    trigger="hover"
+    :arrow-style="{ background: 'rgba(0, 0, 0, 0.6)' }"
+  >
+    <template #trigger>
+      <slot></slot>
+    </template>
+    <div class="px-[8px] py-[4px] rounded-[6px] text-[12px] text-white leading-[20px] bg-black/[0.6]">{{ content }}</div>
+  </NPopover>
+</template>

+ 104 - 0
src/components/Layout/TheChatLayout.vue

@@ -0,0 +1,104 @@
+<script setup>
+import { RouterView } from 'vue-router';
+import { NScrollbar } from 'naive-ui';
+
+import TheLogo from './TheLogo.vue';
+import SvgIcon from '@/components/SvgIcon';
+import TheMenu from "@/components/Layout/TheMenu.vue";
+
+</script>
+
+<template>
+
+  <div class="viewport">
+    <!-- 侧边栏 -->
+    <aside class="aside-container flex flex-col items-center justify-between w-[240px] h-full">
+      <div class="aside-main_top flex-1 w-full overflow-hidden">
+        <TheLogo />
+        <div class="menu-cotainer">
+          <NScrollbar style="height: 100%;">
+            <TheMenu />
+          </NScrollbar>
+        </div>
+      </div>
+      <div class="aside-main_bottom w-full px-[20px]">
+        <dl class="warn-content px-[12px] py-[12px]">
+          <dt class="w-[64px] h-[20px] mb-[12px] text-[16px] flex items-center justify-center">
+            <img src="@/assets/images/menu/bg-warn-text.png" alt="">
+          </dt>
+          <dd class="info">
+            <SvgIcon name="menu-warn-tips"></SvgIcon>
+            <span class="pl-[4px] block">您有100个报警信息,请解决</span>
+          </dd>
+          <dd class="info">
+            <SvgIcon name="menu-warn-tips"></SvgIcon>
+            <span class="pl-[4px] block">您有100个报警信息,请解决</span>
+          </dd>
+        </dl>
+      </div>
+    </aside>
+    <!-- 主体 -->
+    <main class="main-container">
+      <RouterView />
+    </main>
+  </div>
+</template>
+
+<style scoped lang="scss">
+.viewport {
+  @include flex(x, start, start);
+  width: 100vw;
+  height: 100vh;
+  overflow: hidden;
+  background: linear-gradient(180deg, #F3F7FC 0%, #E4EAF7 100%);
+
+  .aside-container {
+    // background: #F2F7FC;
+
+    .menu-cotainer {
+      height: calc(100% - 56px);
+      overflow: hidden;
+    }
+
+    .aside-main_bottom {
+      height: 100px;
+      margin-bottom: 78px;
+
+      .warn-content {
+        border: 1px solid #fff;
+        border-radius: 6px;
+        background: #FAF5F7 url("@/assets/images/menu/bg-warn-card.png") right bottom no-repeat;
+
+        .info {
+          display: flex;
+          align-items: center;
+          font-size: 12px;
+          color: #333;
+          cursor: pointer;
+
+          span {
+            text-overflow: ellipsis;
+            overflow: hidden;
+            word-break: break-all;
+            white-space: nowrap;
+          }
+
+          &:not(:last-child) {
+            margin-bottom: 10px;
+          }
+
+          &:hover {
+            color: #5E5E5E;
+          }
+        }
+      }
+    }
+  }
+
+  .main-container {
+    flex: 1;
+    height: 100%;
+    // background: orange;
+  }
+}
+</style>

+ 52 - 0
src/components/Layout/TheLogo.vue

@@ -0,0 +1,52 @@
+<script setup>
+import { storeToRefs } from 'pinia';
+import { useAppStore } from '@/stores/modules/app';
+import { NPopover } from 'naive-ui';
+
+import SvgIcon from '@/components/SvgIcon';
+import BasePopover from "@/components/BasePopover"
+
+const appStore = useAppStore();
+const { subMenuCollapse } = storeToRefs(appStore);
+
+const changeCollapse = () => appStore.toggleSubMenuCollapse();
+</script>
+
+<template>
+  <div class="logo-main flex items-center justify-between py-[14px] px-[20px]">
+    <div class="title flex items-center space-x-2">
+      <div class="w-[28px] h-[28px]">
+        <SvgIcon name="common-logo" :size="28"></SvgIcon>
+      </div>
+      <span class="block w-[70px] font-[10px]">人工智能运营体智慧决策助手</span>
+    </div>
+    <!-- 图标 -->
+    <div class="icon-group flex items-center justify-center"  @click="changeCollapse" v-show="!subMenuCollapse">
+      <BasePopover placement="right" content="历史记录">
+        <SvgIcon class="cursor-pointer" name="tool-arrow-history" :size="20"></SvgIcon>
+      </BasePopover>
+    </div>
+  </div>
+</template>
+
+<style scoped lang="scss">
+.logo-main {
+  font-family: AlimamaShuHeiTi;
+
+  .title {
+    font-size: 10px;
+    line-height: 12px;
+  }
+
+  .icon-group {
+    width: 24px;
+    height: 24px;
+    border-radius: 6px;
+    color: #4F5866;
+    &:hover {
+      color: #2454FF;
+      background: #fff;
+    }
+  }
+}
+</style>

+ 8 - 7
src/components/Layout/TheMenu.vue

@@ -4,7 +4,6 @@ import { NMenu } from 'naive-ui'
 import { RouterLink } from 'vue-router'
 import SvgIcon from '@/components/SvgIcon/index.vue'
 
-
 function renderIcon(props: {name: string, size?: number, class?: string[], color?: string}) {
   return () => h(SvgIcon, { ...props })
 }
@@ -79,12 +78,14 @@ const handleUpdateValue = () => {
 </script>
 
 <template>
-  <n-menu
-    :options="menuOptions"
-    :icon-size="30"
-    @update:value="handleUpdateValue"
-  >
-  </n-menu>
+  <n-scrollbar style="height: 100%">
+    <n-menu
+      :options="menuOptions"
+      :icon-size="30"
+      @update:value="handleUpdateValue"
+    >
+    </n-menu>
+  </n-scrollbar>
 </template>
 
 <style scoped lang="scss">

+ 5 - 4
src/components/SvgIcon/index.vue

@@ -1,9 +1,9 @@
 <template>
-  <n-icon :size="size" :color="color">
-    <svg aria-hidden="true">
-      <use :xlink:href="symbolId" />
+  <!-- <n-icon :size="size" :color="color"> -->
+    <svg aria-hidden="true" :width="size" :height="size" class="svg-icon">
+      <use :xlink:href="symbolId" fill="currentColor"/>
     </svg>
-  </n-icon>
+  <!-- </n-icon> -->
 </template>
 
 <script setup lang="ts">
@@ -34,6 +34,7 @@ const symbolId = computed(() => `#${props.prefix}-${props.name}`)
 
 <style>
 .svg-icon {
+  outline: none;
   /* color: #fff; */
 }
 </style>

+ 1 - 1
src/main.ts

@@ -6,7 +6,7 @@ import 'virtual:svg-icons-register'
 import { createApp } from 'vue'
 
 import App from './App.vue'
-import router from './router'
+import router from './router/index.js'
 import pinia from './stores'
 
 import SvgIcon from '@/components/SvgIcon/index.vue'

+ 27 - 0
src/router/index.js

@@ -0,0 +1,27 @@
+import { createRouter, createWebHistory } from 'vue-router'
+import HomeView from '../views/HomeView.vue'
+
+const router = createRouter({
+  history: createWebHistory(import.meta.env.BASE_URL),
+  routes: [
+    // {
+    //   path: '/',
+    //   name: 'home',
+    //   component: HomeView
+    // },
+    {
+      path: '/',
+      name: 'theBaseLayout',
+      component: () => import('@/components/Layout/TheChatLayout.vue'),
+      children: [
+        {
+          path: 'analyse',
+          name: 'Analyse',
+          component: () => import('@/views/answer/AnswerView.vue')
+        }
+      ]
+    },
+  ]
+})
+
+export default router

+ 0 - 23
src/router/index.ts

@@ -1,23 +0,0 @@
-import { createRouter, createWebHistory } from 'vue-router'
-import HomeView from '../views/HomeView.vue'
-
-const router = createRouter({
-  history: createWebHistory(import.meta.env.BASE_URL),
-  routes: [
-    {
-      path: '/',
-      name: 'home',
-      component: HomeView
-    },
-    {
-      path: '/analyse',
-      name: 'analyse',
-      // route level code-splitting
-      // this generates a separate chunk (About.[hash].js) for this route
-      // which is lazy-loaded when the route is visited.
-      component: () => import('@/views/answer/AnswerView.vue')
-    }
-  ]
-})
-
-export default router

+ 18 - 0
src/stores/modules/app.js

@@ -0,0 +1,18 @@
+import { ref, computed } from 'vue'
+import { defineStore } from 'pinia'
+
+export const useAppStore = defineStore('app', () => {
+  const subMenuCollapse  = ref(true);
+
+  const toggleSubMenuCollapse = () => {
+    subMenuCollapse.value = !subMenuCollapse.value;
+  }
+
+  const count = ref(0)
+  const doubleCount = computed(() => count.value * 2)
+  function increment() {
+    count.value++
+  }
+
+  return { subMenuCollapse, toggleSubMenuCollapse}
+})

+ 218 - 65
src/views/answer/AnswerView.vue

@@ -1,95 +1,248 @@
-<script setup>
+<script setup lang="jsx">
+import { ref } from "vue";
+import { storeToRefs } from 'pinia';
+import { NScrollbar, NSelect, NInput, NSwitch } from 'naive-ui';
+import { useAppStore } from '@/stores/modules/app';
 import SvgIcon from '@/components/SvgIcon';
-import TheMenu from "@/components/Layout/TheMenu.vue";
+import BaseButton from "@/components/BaseButton";
+import BasePopover from "@/components/BasePopover";
+
+const appStore = useAppStore();
+const { subMenuCollapse } = storeToRefs(appStore);
+
+const inputInstRef = ref(null);
+const inputValue = ref(null);
+const isFocusState = ref(false);
+const value = ref();
+const options = [
+  {
+    label: "水厂的名称不要太长",
+    value: 'song0',
+  },
+  {
+    label: '信义污水厂',
+    value: 'song1'
+  },
+]
+
+const changeCollapse = () => appStore.toggleSubMenuCollapse();
+
+const renderAvatar = () => {
+  return (
+    <div></div>
+  )
+}
+
+const focusInput = _ => isFocusState.value = true;
+
+const blurInput = _ => isFocusState.value = false;
+
+const handleInpFocus = () => {
+  console.log(123);
+  inputInstRef.value?.focus()
+}
 </script>
 
 <template>
-  <div class="viewport">
-    <aside class="aside-container w-60 h-full">
-      <div class="logo-main py-[14px] px-[20px]">
-        <div class="title flex items-center space-x-2">
-          <div class="w-[28px] h-[28px]">
-            <SvgIcon name="common-logo" :size="28"></SvgIcon>
-          </div>
-          <span class="block w-[70px] font-[10px]">人工智能运营体智慧决策助手</span>
+  <section class="flex items-start h-full">
+    <div class="sub-menu-container w-[190px] h-full py-[18px]" v-show="subMenuCollapse">
+      <div class="px-[11px]">
+        <!-- 操作 -->
+        <div class="flex items-center justify-between">
+          <p class="text-[#1A2029] text-[14px] font-bold">历史记录</p>
+          <SvgIcon name="tool-arrow-right" :size="20" class="cursor-pointer" @click="changeCollapse"></SvgIcon>
+        </div>
+        <!-- 新增对话 -->
+        <div class="create-btn py-[22px]">
+          <BaseButton></BaseButton>
         </div>
       </div>
-
-      <div class="menu-cotainer">
-        <TheMenu></TheMenu>
+      <!-- 历史列表 -->
+      <div class="
+        history-content
+        text-[12px]  text-[#5E5E5E] leading-[20px]
+      ">
+        <NScrollbar class="h-full">
+          <ul class="history-list pr-[4px]">
+            <li class="history-item" v-for="item in 100" :key="item">
+              <p class="content">曝气池产生茶色也许文字很很少</p>
+              <p class="time flex item-center justify-between w-full mt-[2px]">
+                <span>2024-04-26 10:12:13</span>
+                <SvgIcon name="tool-bucket-del" size="16" class="del-icon cursor-pointer hidden"></SvgIcon>
+              </p>
+            </li>
+          </ul>
+        </NScrollbar>
       </div>
+    </div>
+    <div class="chat-container h-full flex-1 ">
+      <!-- chat header -->
+      <div class="chat-wrapper w-full h-full rounded-[20px]">
+        <div class="chat-header flex items-center justify-end py-[24px] pr-[18px] space-x-[16px]">
+          <!-- 数字人设置 -->
+          <BasePopover placement="bottom" content="数字人设置">
+            <div class="avatar rounded-full w-[24px] h-[24px]">
+              <img src="@/assets/images/chat/img-avatar.png" alt="" class="cursor-pointer">
+            </div>
+          </BasePopover>
+          <!-- 声音开关 -->
+          <SvgIcon name="tool-voice-open" :size="24" class="cursor-pointer"></SvgIcon>
+          <!--分割线 -->
+          <div class="h-[24px] border-r-[1px] border-color-[#D3D0E1]"></div>
+          <!-- 水厂select -->
+          <NSelect v-model:value="value" placeholder="123" :options="options" class="w-[114px]" size="medium"
+            :consistent-menu-width="false" />
+          <!-- 用户头像 -->
+          <div class="flex items-center">
+            <img src="@/assets/images/chat/img-user-avatar.png" alt="" class="w-[32px] mr-[10px] cursor-pointer">
+            <span class="text-[#272D35] text-[12px]">我的昵称</span>
+          </div>
+        </div>
 
-      <div class="warn-container px-[20px]">
-        <dl class="warn-content px-[12px] py-[12px]">
-          <dt class="title h-[20px] mb-[12px] text-[16px]"></dt>
-          <dd class="info">
-            <SvgIcon name="menu-warn-tips"></SvgIcon>
-            <span class="pl-[4px]">您有100个报警信息,请解决</span>
-          </dd>
-          <dd class="info">
-            <SvgIcon name="menu-warn-tips"></SvgIcon>
-            <span class="pl-[4px]">您有100个报警信息,请解决</span>
-          </dd>
-        </dl>
-      </div>
-    </aside>
-  </div>
+        <main class="chat-main w-[800px] h-full m-auto flex flex-col justify-between">
+          <!-- TODO:这里需要抽离 -->
+          <!-- chat 内容区域 -->
+          <div class="chat-welcome">
+            <div class="
+              welcome
+              flex flex-col items-center justify-between
+              text-center
+            ">
+              <SvgIcon name="common-logo" size="56"></SvgIcon>
+              <p class="py-[10px] text-[#1A2029] text-[36px] font-bold leading-[50px]">您好,我是LibraAI专家问答</p>
+              <p class="text-[#333333] leading-[20px]">期待与您一同规划和完成未来的工作。有任何重点或需讨论的事项,随时告诉我。</p>
+            </div>
+            <!-- 问答列表 -->
+            <dl class="answer-list rounded-[8px] bg-white py-[30px] pl-[82px] mt-[36px]">
+              <dt class="mb-[18px] text-[20px] text-[#1A2029] leading-[28px] font-bold">您可以试着问我:</dt>
+              <dd class="mb-[19px] text-[15px] text-[#2E5CFF] leading-[21px] cursor-pointer">帮我做一份如何快速入手污水处理厂的相关工作的学习计划?
+              </dd>
+              <dd class="mb-[19px] text-[15px] text-[#2E5CFF] leading-[21px] cursor-pointer">硝化作用的速度快慢与哪些因素有关?</dd>
+              <dd class="text-[15px] text-[#2E5CFF] leading-[21px] cursor-pointer">污泥回流比如何计算?</dd>
+            </dl>
+          </div>
 
+          <div class="chat-footer">
+            <div class="chat-inp-inner border-[1px]" :class="[{'border-[#2454FF]': isFocusState}]" @click="handleInpFocus">
+              <div class="inp-wrapper flex-1" >
+                <NInput
+                  class="flex-1"
+                  ref="inputInstRef"
+                  v-model:value="inputValue"
+                  type="textarea"
+                  size="medium"
+                  placeholder="输入您的问题或需求,Enter发送,Shift+Enter换行" 
+                  :autosize="{ minRows: 1, maxRows: 5 }"
+                  @focus="focusInput"
+                  @blur="blurInput"
+                />
+              </div>
+              <div class="submit-btn">
+                <button class="btn bg-[#1A2029] hover:bg-[#3C4148]">
+                  <SvgIcon name="tool-send-plane" size="22"></SvgIcon>
+                </button>
+              </div>
+            </div>
+            <div class="switch-inner pt-[8px] space-x-[6px]">
+              <NSwitch size="small"></NSwitch>
+              <span class="text-[12px] text-[#9E9E9E]">使用搜索增强</span>
+            </div>
+          </div>
+
+        </main>
+
+      </div>
+    </div>
+  </section>
 </template>
 
 <style scoped lang="scss">
-.warn-container {
-  height: 100px;
+.chat-main {
+  height: calc(100% - 82px);
+}
 
-  .warn-content {
-    border: 1px solid #fff;
-    border-radius: 6px;
-    background: #FAF5F7;
+.chat-footer {
+  padding-bottom: 30px;
 
-    .title {
-      background: url("@/assets/images/warn-text.png") left center no-repeat;
-      background-size: 62px 14px;
-    }
+  .chat-inp-inner {
+    position: relative;
+    @include flex(x, center, between);
+    border-radius: 8px;
+    background: #fff;
+    box-shadow: 0px 3px 12px 0px #97D3FF40;
 
-    .info {
-      display: flex;
-      align-items: center;
-      font-size: 12px;
-      color: #333;
-      cursor: pointer;
+    .inp-wrapper {
+      padding: 17px 0px 17px 34px;
+    }
 
-      &:not(:last-child) {
-        margin-bottom: 10px;
-      }
+    .submit-btn {
+      @include flex(x, center, center);
+      width: 84px;
 
-      &:hover {
-        color: #5E5E5E;
+      .btn {
+        @include flex(x, center, center);
+        width: 50px;
+        height: 32px;
+        border-radius: 32px;
+        transition: all .3s;
       }
     }
   }
 }
 
-.viewport {
-  @include flex(y, start, start);
-  width: 100vw;
-  height: 100vh;
-  background: #F2F6FC;
-}
+.chat-container {
+  padding: 20px 20px 20px 0;
 
-.aside-container {
-  border-right: 1px solid #DBE5ED;
+  .chat-wrapper {
+    border: 1px solid #fff;
+    background: linear-gradient(180deg, rgba(238, 253, 255, 0.5) 0%, rgba(231, 243, 252, 0.5) 100%);
+  }
 }
 
-.menu-cotainer {
-  // padding: 0 7px;
-}
+.sub-menu-container {
+  border-left: 1px solid #DBE6EE;
 
-.logo-main {
-  font-family: AlimamaShuHeiTi;
+  .history-content {
+    height: calc(100% - 106px);
 
-  .title {
-    font-size: 10px;
-    line-height: 12px;
+    .history-item {
+      position: relative;
+      @include flex(y, start, center);
+      height: 60px;
+      padding: 0 10px 0 12px;
+      transition: bakground .3s;
+      cursor: pointer;
+
+      .content {
+        @include textLine(1);
+      }
+
+      &:hover {
+        border-radius: 2px;
+        background-color: #F5F8FA;
+        box-shadow: 0.5px 0.5px 4px 0px #93A1B233;
+        overflow: hidden;
+
+        .content {
+          color: #325DF3;
+        }
+
+        .del-icon {
+          display: block;
+        }
+
+        &::before {
+          position: absolute;
+          top: 0;
+          left: 0px;
+          display: block;
+          content: " ";
+          width: 2px;
+          height: 100%;
+          background: #325DF3;
+        }
+      }
+    }
   }
 }
 </style>