Browse Source

feat:基本布局

sunxiao 9 months ago
parent
commit
94e24a58d5

+ 6 - 0
package-lock.json

@@ -9,6 +9,7 @@
       "version": "0.0.0",
       "dependencies": {
         "axios": "^1.6.8",
+        "load-awesome": "^1.1.0",
         "naive-ui": "^2.38.2",
         "pinia": "^2.1.7",
         "sass": "^1.77.1",
@@ -4009,6 +4010,11 @@
       "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
       "dev": true
     },
+    "node_modules/load-awesome": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/load-awesome/-/load-awesome-1.1.0.tgz",
+      "integrity": "sha512-0ccQMaDrd7TzlYM2N5+WzB+VR5CMD6MjqC9UCOWaX+woC3ac+jGAWzBMDxtW6bCp0wnX1lTMP3s178Y5DZduag=="
+    },
     "node_modules/loader-utils": {
       "version": "1.4.2",
       "resolved": "https://registry.npmmirror.com/loader-utils/-/loader-utils-1.4.2.tgz",

+ 1 - 0
package.json

@@ -12,6 +12,7 @@
   },
   "dependencies": {
     "axios": "^1.6.8",
+    "load-awesome": "^1.1.0",
     "naive-ui": "^2.38.2",
     "pinia": "^2.1.7",
     "sass": "^1.77.1",

+ 23 - 1
src/App.vue

@@ -2,7 +2,9 @@
 import { RouterView } from 'vue-router';
 import { NConfigProvider } from 'naive-ui';
 import type { GlobalThemeOverrides } from 'naive-ui';
-// import { SelectProps, InputProps } from 'naive-ui'
+import { SelectProps, InputProps, TableProps } from 'naive-ui'
+
+import 'load-awesome/css/ball-running-dots.min.css';
 
 // type SelectThemeOverrides = NonNullable<SelectProps['themeOverrides']>
 // type SelectThemeOverrides = NonNullable<InputProps['themeOverrides']>
@@ -14,6 +16,7 @@ const primaryColor = '#1A2029';
 const themeOverrides: GlobalThemeOverrides = {
   common: {
     primaryColor: '#2454FF',
+    tableHeaderColor: '#F3F6F9'
   },
   Menu: {
     itemTextColor: primaryColor,
@@ -54,6 +57,15 @@ const themeOverrides: GlobalThemeOverrides = {
     tabFontSizeMedium: '12px',
     tabTextColorLine: '#272D35',
     tabFontWeightActive: 'bold'
+  },
+  DataTable: {
+    thTextColor: '#1A2029',
+    tdTextColor: primaryColor,
+    borderRadius: '4px',
+    borderColor: '#D7D7D7',
+    thPaddingMedium: '10px',
+    tdPaddingMedium: '10px',
+    // color
   }
   // Menu: {
   //   itemTextColorHorizontal: '#161616',
@@ -77,6 +89,16 @@ const themeOverrides: GlobalThemeOverrides = {
 <template>
   <NConfigProvider :theme-overrides="themeOverrides">
     <RouterView />
+    <!-- <div class="w-full h-36 bg-black px-3 py-4 relative">
+
+      <div style="color: #9988cd" class="la-ball-running-dots la-sm">
+        <div></div>
+        <div></div>
+        <div></div>
+        <div></div>
+        <div></div>
+      </div>
+    </div> -->
   </NConfigProvider>
 </template>
 

+ 1 - 1
src/components/BaseButton/index.vue

@@ -50,7 +50,7 @@ const handleClick = () => emit('click');
   color: #1D43CC;
 
   &:hover {
-    background: #ecf0f9;
+    background: #C1CAFF;
   }
 }
 </style>

+ 80 - 0
src/components/BaseCard/index.vue

@@ -0,0 +1,80 @@
+<script setup>
+import { SvgIcon } from '@/components';
+
+defineProps({
+  toggleVisibleIcons: {
+    type: Boolean,
+    default: false
+  }
+})
+</script>
+
+<template>
+  <div class="card-container">
+    <div class="card-inner">
+      <div class="chat-icon">
+        <SvgIcon name="common-logo" size="30" />
+      </div>
+      <div class="flex-1 pt-[6px] ml-[16px] text-[15px] leading-[24px]">
+        <slot />
+      </div>
+    </div>
+    <ul class="answer-btn-group" v-if="toggleVisibleIcons">
+      <li class="btn">
+        <SvgIcon name="chat-icon-copy" size="16" />
+      </li>
+      <li class="line"></li>
+      <li class="btn">
+        <SvgIcon name="chat-icon-yes" size="16" />
+      </li>
+      <li class="line"></li>
+      <li class="btn">
+        <SvgIcon name="chat-icon-no" size="16" />
+      </li>
+    </ul>
+  </div>
+</template>
+
+<style scoped lang="scss">
+.card-container {
+  margin-bottom: 20px;
+
+  .card-inner {
+    @include flex(x, start, start);
+    padding: 20px;
+    border-radius: 8px;
+    background: #fff;
+
+    .chat-icon{
+      width: 32px;
+      height: 32px;
+      border: 1px solid #E5ECF0;
+      border-radius: 50%;
+      flex-shrink: 0;
+    }
+  }
+
+  .answer-btn-group {
+    @include flex(x, center, end);
+    padding-top: 6px;
+
+    .btn {
+      @include flex(x, center, center);
+      @include layout(28px, 28px, 4px);
+      color: #89909B;
+      cursor: pointer;
+
+      &:hover {
+        background: #DBEFFF;
+        color: #2454FF;
+      }
+    }
+
+    .line {
+      @include layout(1px, 12px, 0);
+      margin: 0 5px;
+      background: #D3D0E1;
+    }
+  }
+}
+</style>

+ 54 - 0
src/components/ChatWelcome/index.vue

@@ -0,0 +1,54 @@
+<script setup>
+
+defineProps({
+  title: {
+    title: String,
+    default: String
+  },
+  subTitle: {
+    title: String,
+    default: []
+  },
+  cardTitle: {
+    title: String,
+    default: String
+  },
+  cardContent: {
+    title: String,
+    default: []
+  }
+});
+
+</script>
+
+<template>
+  <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]">{{ title }}</p>
+      <p class="text-[#333333] leading-[20px]" v-for="item, index in subTitle" :key="index">{{ item }}</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">{{ cardTitle }}</dt>
+      <dd
+        class=""
+        :class="[
+          'text-[15px]', 'text-[#2E5CFF]', 'leading-[21px]', 'cursor-pointer', 'hover:text-[#2E5CFF]/90',
+          {'mb-[19px]': index !== cardContent.length - 1 }
+        ]"
+        :key="index"
+        v-for="(item, index) in cardContent"
+      >
+        <span>{{ item }}</span>
+      </dd>
+    </dl>
+  </div>
+</template>
+
+<style setup lang="scss">
+
+</style>

+ 0 - 41
src/components/HelloWorld.vue

@@ -1,41 +0,0 @@
-<script setup lang="ts">
-defineProps<{
-  msg: string
-}>()
-</script>
-
-<template>
-  <div class="greetings">
-    <h1 class="green">{{ msg }}</h1>
-    <h3>
-      You’ve successfully created a project with
-      <a href="https://vitejs.dev/" target="_blank" rel="noopener">Vite</a> +
-      <a href="https://vuejs.org/" target="_blank" rel="noopener">Vue 3</a>. What's next?
-    </h3>
-  </div>
-</template>
-
-<style scoped>
-h1 {
-  font-weight: 500;
-  font-size: 2.6rem;
-  position: relative;
-  top: -10px;
-}
-
-h3 {
-  font-size: 1.2rem;
-}
-
-.greetings h1,
-.greetings h3 {
-  text-align: center;
-}
-
-@media (min-width: 1024px) {
-  .greetings h1,
-  .greetings h3 {
-    text-align: left;
-  }
-}
-</style>

+ 1 - 1
src/components/Layout/TheChatView.vue

@@ -30,7 +30,7 @@ const options = [
           </div>
         </BasePopover>
         <!-- 声音开关 -->
-        <SvgIcon name="tool-voice-open" :size="24" class="cursor-pointer"></SvgIcon>
+        <SvgIcon name="tool-voice-open" size="24" class="cursor-pointer"></SvgIcon>
         <!--分割线 -->
         <div class="h-[24px] border-r-[1px] border-color-[#D3D0E1]"></div>
         <!-- 水厂select -->

+ 2 - 2
src/components/Layout/TheLogo.vue

@@ -16,14 +16,14 @@ const changeCollapse = () => appStore.toggleSubMenuCollapse();
   <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>
+        <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>
+        <SvgIcon class="cursor-pointer" name="tool-arrow-history" size="20"></SvgIcon>
       </BasePopover>
     </div>
   </div>

+ 46 - 14
src/components/Layout/TheMenu.vue

@@ -1,14 +1,23 @@
-<script setup lang="tsx">
-import {  h } from 'vue'
-import { NMenu } from 'naive-ui'
-import { RouterLink } from 'vue-router'
+<script setup lang="jsx">
+import { h, watch, ref } from 'vue'
+import { useRoute, useRouter } from 'vue-router';
+import { NMenu, NScrollbar } from 'naive-ui'
 import SvgIcon from '@/components/SvgIcon/index.vue'
 
-function renderIcon(props: {name: string, size?: number, class?: string[], color?: string}) {
+const route = useRoute();
+const router = useRouter();
+
+const activeMenuKey = ref(route.path);
+
+watch(() => route.path, currentPath => { 
+  activeMenuKey.value = currentPath;
+})
+
+function renderIcon(props) {
   return () => h(SvgIcon, { ...props })
 }
 
-function renderChildrenIcon({ name, size = 20 }:{ name:string, size?: number }) {
+function renderChildrenIcon({ name, size = '20' }) {
   return () => (
     <div class="flex items-center justify-center">
       { renderIcon({ name, size, class: ['icon-default'] })() }
@@ -17,11 +26,11 @@ function renderChildrenIcon({ name, size = 20 }:{ name:string, size?: number })
   )
 }
 
-function renderLabel (val: string) {
-  return (<span class="pl-1 test">{ val }</span>);
+function renderLabel (val, url) {
+  return url ? (<a href={ url } target="_blank" class="pl-1">{ val }</a>) : (<span class="pl-1">{ val }</span>) ;
 }
 
-const menuOptions: MenuOption[] = [
+const menuOptions = [
   {
     label: () => renderLabel('智慧总控'),
     icon: renderIcon({name: 'menu-control'}),
@@ -30,7 +39,7 @@ const menuOptions: MenuOption[] = [
   {
     label: () => renderLabel('专家问答'),
     icon: renderIcon({name: 'menu-answers'}),
-    key: '/'
+    key: '/answer'
   },
   {
     label: () => renderLabel('智能分析'),
@@ -40,7 +49,7 @@ const menuOptions: MenuOption[] = [
       {
         label:() =>  renderLabel('水质报警'),
         icon: renderChildrenIcon({ name: 'menu-analyse-water' }),
-        key: 'key1',
+        key: '/water-warn',
       },
       {
         label: '生化报警',
@@ -67,12 +76,32 @@ const menuOptions: MenuOption[] = [
   {
     label: () => renderLabel('用户中心'),
     icon: renderIcon({ name: 'menu-help' }),
-    key: '/'
+    key: '/',
+    children: [
+      {
+        label: '账号管理',
+        icon: renderChildrenIcon({ name: 'menu-analyse-order' }),
+        key: '/account1',
+      },
+      {
+        label: '意见反馈',
+        icon: renderChildrenIcon({ name: 'menu-analyse-order' }),
+        key: '/account2',
+      },
+      {
+        // renderLabel('关于我们', 'https://www.sequoialibra.com/')
+        label: '关于我们',
+        icon: renderChildrenIcon({ name: 'menu-analyse-order' }),
+        url: 'https://www.sequoialibra.com/',
+        key: '/account3',
+      },
+    ]
   },
 ]
 
-const handleUpdateValue = () => {
-  console.log(123123);
+const handleUpdateValue = (key, { url }) => {
+  if (url) return window.open(url);
+  router.push(key);
 }
 
 </script>
@@ -82,9 +111,12 @@ const handleUpdateValue = () => {
     <n-menu
       :options="menuOptions"
       :icon-size="30"
+      v-model:value="activeMenuKey"
       @update:value="handleUpdateValue"
     >
     </n-menu>
+
+    
   </n-scrollbar>
 </template>
 

+ 1 - 1
src/components/Layout/TheSubMenu.vue

@@ -27,7 +27,7 @@ const handleLoad = () => emits('on-load');
 
     <div class="flex items-center justify-between w-full px-[11px] pb-[22px]">
       <p class="text-[#1A2029] text-[14px] font-bold">{{ title }}</p>
-      <SvgIcon name="tool-arrow-right" :size="20" class="cursor-pointer" @click="changeCollapse"></SvgIcon>
+      <SvgIcon name="tool-arrow-right" size="20" class="cursor-pointer" @click="changeCollapse"></SvgIcon>
     </div>
 
     <div class="w-full">

+ 0 - 0
src/components/Layout/test.vue


+ 0 - 88
src/components/TheWelcome.vue

@@ -1,88 +0,0 @@
-<script setup lang="ts">
-import WelcomeItem from './WelcomeItem.vue'
-import DocumentationIcon from './icons/IconDocumentation.vue'
-import ToolingIcon from './icons/IconTooling.vue'
-import EcosystemIcon from './icons/IconEcosystem.vue'
-import CommunityIcon from './icons/IconCommunity.vue'
-import SupportIcon from './icons/IconSupport.vue'
-</script>
-
-<template>
-  <WelcomeItem>
-    <template #icon>
-      <DocumentationIcon />
-    </template>
-    <template #heading>Documentation</template>
-
-    Vue’s
-    <a href="https://vuejs.org/" target="_blank" rel="noopener">official documentation</a>
-    provides you with all information you need to get started.
-  </WelcomeItem>
-
-  <WelcomeItem>
-    <template #icon>
-      <ToolingIcon />
-    </template>
-    <template #heading>Tooling</template>
-
-    This project is served and bundled with
-    <a href="https://vitejs.dev/guide/features.html" target="_blank" rel="noopener">Vite</a>. The
-    recommended IDE setup is
-    <a href="https://code.visualstudio.com/" target="_blank" rel="noopener">VSCode</a> +
-    <a href="https://github.com/johnsoncodehk/volar" target="_blank" rel="noopener">Volar</a>. If
-    you need to test your components and web pages, check out
-    <a href="https://www.cypress.io/" target="_blank" rel="noopener">Cypress</a> and
-    <a href="https://on.cypress.io/component" target="_blank" rel="noopener"
-      >Cypress Component Testing</a
-    >.
-
-    <br />
-
-    More instructions are available in <code>README.md</code>.
-  </WelcomeItem>
-
-  <WelcomeItem>
-    <template #icon>
-      <EcosystemIcon />
-    </template>
-    <template #heading>Ecosystem</template>
-
-    Get official tools and libraries for your project:
-    <a href="https://pinia.vuejs.org/" target="_blank" rel="noopener">Pinia</a>,
-    <a href="https://router.vuejs.org/" target="_blank" rel="noopener">Vue Router</a>,
-    <a href="https://test-utils.vuejs.org/" target="_blank" rel="noopener">Vue Test Utils</a>, and
-    <a href="https://github.com/vuejs/devtools" target="_blank" rel="noopener">Vue Dev Tools</a>. If
-    you need more resources, we suggest paying
-    <a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">Awesome Vue</a>
-    a visit.
-  </WelcomeItem>
-
-  <WelcomeItem>
-    <template #icon>
-      <CommunityIcon />
-    </template>
-    <template #heading>Community</template>
-
-    Got stuck? Ask your question on
-    <a href="https://chat.vuejs.org" target="_blank" rel="noopener">Vue Land</a>, our official
-    Discord server, or
-    <a href="https://stackoverflow.com/questions/tagged/vue.js" target="_blank" rel="noopener"
-      >StackOverflow</a
-    >. You should also subscribe to
-    <a href="https://news.vuejs.org" target="_blank" rel="noopener">our mailing list</a> and follow
-    the official
-    <a href="https://twitter.com/vuejs" target="_blank" rel="noopener">@vuejs</a>
-    twitter account for latest news in the Vue world.
-  </WelcomeItem>
-
-  <WelcomeItem>
-    <template #icon>
-      <SupportIcon />
-    </template>
-    <template #heading>Support Vue</template>
-
-    As an independent project, Vue relies on community backing for its sustainability. You can help
-    us by
-    <a href="https://vuejs.org/sponsor/" target="_blank" rel="noopener">becoming a sponsor</a>.
-  </WelcomeItem>
-</template>

+ 0 - 87
src/components/WelcomeItem.vue

@@ -1,87 +0,0 @@
-<template>
-  <div class="item">
-    <i>
-      <slot name="icon"></slot>
-    </i>
-    <div class="details">
-      <h3>
-        <slot name="heading"></slot>
-      </h3>
-      <slot></slot>
-    </div>
-  </div>
-</template>
-
-<style scoped>
-.item {
-  margin-top: 2rem;
-  display: flex;
-  position: relative;
-}
-
-.details {
-  flex: 1;
-  margin-left: 1rem;
-}
-
-i {
-  display: flex;
-  place-items: center;
-  place-content: center;
-  width: 32px;
-  height: 32px;
-
-  color: var(--color-text);
-}
-
-h3 {
-  font-size: 1.2rem;
-  font-weight: 500;
-  margin-bottom: 0.4rem;
-  color: var(--color-heading);
-}
-
-@media (min-width: 1024px) {
-  .item {
-    margin-top: 0;
-    padding: 0.4rem 0 1rem calc(var(--section-gap) / 2);
-  }
-
-  i {
-    top: calc(50% - 25px);
-    left: -26px;
-    position: absolute;
-    border: 1px solid var(--color-border);
-    background: var(--color-background);
-    border-radius: 8px;
-    width: 50px;
-    height: 50px;
-  }
-
-  .item:before {
-    content: ' ';
-    border-left: 1px solid var(--color-border);
-    position: absolute;
-    left: 0;
-    bottom: calc(50% + 25px);
-    height: calc(50% - 25px);
-  }
-
-  .item:after {
-    content: ' ';
-    border-left: 1px solid var(--color-border);
-    position: absolute;
-    left: 0;
-    top: calc(50% + 25px);
-    height: calc(50% - 25px);
-  }
-
-  .item:first-of-type:before {
-    display: none;
-  }
-
-  .item:last-of-type:after {
-    display: none;
-  }
-}
-</style>

+ 0 - 7
src/components/icons/IconCommunity.vue

@@ -1,7 +0,0 @@
-<template>
-  <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor">
-    <path
-      d="M15 4a1 1 0 1 0 0 2V4zm0 11v-1a1 1 0 0 0-1 1h1zm0 4l-.707.707A1 1 0 0 0 16 19h-1zm-4-4l.707-.707A1 1 0 0 0 11 14v1zm-4.707-1.293a1 1 0 0 0-1.414 1.414l1.414-1.414zm-.707.707l-.707-.707.707.707zM9 11v-1a1 1 0 0 0-.707.293L9 11zm-4 0h1a1 1 0 0 0-1-1v1zm0 4H4a1 1 0 0 0 1.707.707L5 15zm10-9h2V4h-2v2zm2 0a1 1 0 0 1 1 1h2a3 3 0 0 0-3-3v2zm1 1v6h2V7h-2zm0 6a1 1 0 0 1-1 1v2a3 3 0 0 0 3-3h-2zm-1 1h-2v2h2v-2zm-3 1v4h2v-4h-2zm1.707 3.293l-4-4-1.414 1.414 4 4 1.414-1.414zM11 14H7v2h4v-2zm-4 0c-.276 0-.525-.111-.707-.293l-1.414 1.414C5.42 15.663 6.172 16 7 16v-2zm-.707 1.121l3.414-3.414-1.414-1.414-3.414 3.414 1.414 1.414zM9 12h4v-2H9v2zm4 0a3 3 0 0 0 3-3h-2a1 1 0 0 1-1 1v2zm3-3V3h-2v6h2zm0-6a3 3 0 0 0-3-3v2a1 1 0 0 1 1 1h2zm-3-3H3v2h10V0zM3 0a3 3 0 0 0-3 3h2a1 1 0 0 1 1-1V0zM0 3v6h2V3H0zm0 6a3 3 0 0 0 3 3v-2a1 1 0 0 1-1-1H0zm3 3h2v-2H3v2zm1-1v4h2v-4H4zm1.707 4.707l.586-.586-1.414-1.414-.586.586 1.414 1.414z"
-    />
-  </svg>
-</template>

+ 0 - 7
src/components/icons/IconDocumentation.vue

@@ -1,7 +0,0 @@
-<template>
-  <svg xmlns="http://www.w3.org/2000/svg" width="20" height="17" fill="currentColor">
-    <path
-      d="M11 2.253a1 1 0 1 0-2 0h2zm-2 13a1 1 0 1 0 2 0H9zm.447-12.167a1 1 0 1 0 1.107-1.666L9.447 3.086zM1 2.253L.447 1.42A1 1 0 0 0 0 2.253h1zm0 13H0a1 1 0 0 0 1.553.833L1 15.253zm8.447.833a1 1 0 1 0 1.107-1.666l-1.107 1.666zm0-14.666a1 1 0 1 0 1.107 1.666L9.447 1.42zM19 2.253h1a1 1 0 0 0-.447-.833L19 2.253zm0 13l-.553.833A1 1 0 0 0 20 15.253h-1zm-9.553-.833a1 1 0 1 0 1.107 1.666L9.447 14.42zM9 2.253v13h2v-13H9zm1.553-.833C9.203.523 7.42 0 5.5 0v2c1.572 0 2.961.431 3.947 1.086l1.107-1.666zM5.5 0C3.58 0 1.797.523.447 1.42l1.107 1.666C2.539 2.431 3.928 2 5.5 2V0zM0 2.253v13h2v-13H0zm1.553 13.833C2.539 15.431 3.928 15 5.5 15v-2c-1.92 0-3.703.523-5.053 1.42l1.107 1.666zM5.5 15c1.572 0 2.961.431 3.947 1.086l1.107-1.666C9.203 13.523 7.42 13 5.5 13v2zm5.053-11.914C11.539 2.431 12.928 2 14.5 2V0c-1.92 0-3.703.523-5.053 1.42l1.107 1.666zM14.5 2c1.573 0 2.961.431 3.947 1.086l1.107-1.666C18.203.523 16.421 0 14.5 0v2zm3.5.253v13h2v-13h-2zm1.553 12.167C18.203 13.523 16.421 13 14.5 13v2c1.573 0 2.961.431 3.947 1.086l1.107-1.666zM14.5 13c-1.92 0-3.703.523-5.053 1.42l1.107 1.666C11.539 15.431 12.928 15 14.5 15v-2z"
-    />
-  </svg>
-</template>

+ 0 - 7
src/components/icons/IconEcosystem.vue

@@ -1,7 +0,0 @@
-<template>
-  <svg xmlns="http://www.w3.org/2000/svg" width="18" height="20" fill="currentColor">
-    <path
-      d="M11.447 8.894a1 1 0 1 0-.894-1.789l.894 1.789zm-2.894-.789a1 1 0 1 0 .894 1.789l-.894-1.789zm0 1.789a1 1 0 1 0 .894-1.789l-.894 1.789zM7.447 7.106a1 1 0 1 0-.894 1.789l.894-1.789zM10 9a1 1 0 1 0-2 0h2zm-2 2.5a1 1 0 1 0 2 0H8zm9.447-5.606a1 1 0 1 0-.894-1.789l.894 1.789zm-2.894-.789a1 1 0 1 0 .894 1.789l-.894-1.789zm2 .789a1 1 0 1 0 .894-1.789l-.894 1.789zm-1.106-2.789a1 1 0 1 0-.894 1.789l.894-1.789zM18 5a1 1 0 1 0-2 0h2zm-2 2.5a1 1 0 1 0 2 0h-2zm-5.447-4.606a1 1 0 1 0 .894-1.789l-.894 1.789zM9 1l.447-.894a1 1 0 0 0-.894 0L9 1zm-2.447.106a1 1 0 1 0 .894 1.789l-.894-1.789zm-6 3a1 1 0 1 0 .894 1.789L.553 4.106zm2.894.789a1 1 0 1 0-.894-1.789l.894 1.789zm-2-.789a1 1 0 1 0-.894 1.789l.894-1.789zm1.106 2.789a1 1 0 1 0 .894-1.789l-.894 1.789zM2 5a1 1 0 1 0-2 0h2zM0 7.5a1 1 0 1 0 2 0H0zm8.553 12.394a1 1 0 1 0 .894-1.789l-.894 1.789zm-1.106-2.789a1 1 0 1 0-.894 1.789l.894-1.789zm1.106 1a1 1 0 1 0 .894 1.789l-.894-1.789zm2.894.789a1 1 0 1 0-.894-1.789l.894 1.789zM8 19a1 1 0 1 0 2 0H8zm2-2.5a1 1 0 1 0-2 0h2zm-7.447.394a1 1 0 1 0 .894-1.789l-.894 1.789zM1 15H0a1 1 0 0 0 .553.894L1 15zm1-2.5a1 1 0 1 0-2 0h2zm12.553 2.606a1 1 0 1 0 .894 1.789l-.894-1.789zM17 15l.447.894A1 1 0 0 0 18 15h-1zm1-2.5a1 1 0 1 0-2 0h2zm-7.447-5.394l-2 1 .894 1.789 2-1-.894-1.789zm-1.106 1l-2-1-.894 1.789 2 1 .894-1.789zM8 9v2.5h2V9H8zm8.553-4.894l-2 1 .894 1.789 2-1-.894-1.789zm.894 0l-2-1-.894 1.789 2 1 .894-1.789zM16 5v2.5h2V5h-2zm-4.553-3.894l-2-1-.894 1.789 2 1 .894-1.789zm-2.894-1l-2 1 .894 1.789 2-1L8.553.106zM1.447 5.894l2-1-.894-1.789-2 1 .894 1.789zm-.894 0l2 1 .894-1.789-2-1-.894 1.789zM0 5v2.5h2V5H0zm9.447 13.106l-2-1-.894 1.789 2 1 .894-1.789zm0 1.789l2-1-.894-1.789-2 1 .894 1.789zM10 19v-2.5H8V19h2zm-6.553-3.894l-2-1-.894 1.789 2 1 .894-1.789zM2 15v-2.5H0V15h2zm13.447 1.894l2-1-.894-1.789-2 1 .894 1.789zM18 15v-2.5h-2V15h2z"
-    />
-  </svg>
-</template>

+ 0 - 7
src/components/icons/IconSupport.vue

@@ -1,7 +0,0 @@
-<template>
-  <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor">
-    <path
-      d="M10 3.22l-.61-.6a5.5 5.5 0 0 0-7.666.105 5.5 5.5 0 0 0-.114 7.665L10 18.78l8.39-8.4a5.5 5.5 0 0 0-.114-7.665 5.5 5.5 0 0 0-7.666-.105l-.61.61z"
-    />
-  </svg>
-</template>

+ 0 - 19
src/components/icons/IconTooling.vue

@@ -1,19 +0,0 @@
-<!-- This icon is from <https://github.com/Templarian/MaterialDesign>, distributed under Apache 2.0 (https://www.apache.org/licenses/LICENSE-2.0) license-->
-<template>
-  <svg
-    xmlns="http://www.w3.org/2000/svg"
-    xmlns:xlink="http://www.w3.org/1999/xlink"
-    aria-hidden="true"
-    role="img"
-    class="iconify iconify--mdi"
-    width="24"
-    height="24"
-    preserveAspectRatio="xMidYMid meet"
-    viewBox="0 0 24 24"
-  >
-    <path
-      d="M20 18v-4h-3v1h-2v-1H9v1H7v-1H4v4h16M6.33 8l-1.74 4H7v-1h2v1h6v-1h2v1h2.41l-1.74-4H6.33M9 5v1h6V5H9m12.84 7.61c.1.22.16.48.16.8V18c0 .53-.21 1-.6 1.41c-.4.4-.85.59-1.4.59H4c-.55 0-1-.19-1.4-.59C2.21 19 2 18.53 2 18v-4.59c0-.32.06-.58.16-.8L4.5 7.22C4.84 6.41 5.45 6 6.33 6H7V5c0-.55.18-1 .57-1.41C7.96 3.2 8.44 3 9 3h6c.56 0 1.04.2 1.43.59c.39.41.57.86.57 1.41v1h.67c.88 0 1.49.41 1.83 1.22l2.34 5.39z"
-      fill="currentColor"
-    ></path>
-  </svg>
-</template>

+ 33 - 0
src/components/index.js

@@ -0,0 +1,33 @@
+import BaseButton from './BaseButton';
+import BaseInput from './BaseInput';
+import BasePopover from './BasePopover';
+import BaseCard from './BaseCard';
+
+import TheChatView from './Layout/TheChatView';
+import TheLogo from './Layout/TheLogo';
+import TheMenu from './Layout/TheMenu';
+import ThePublicLayout from './Layout/ThePublicLayout';
+import TheSubMenu from './Layout/TheSubMenu';
+
+import RecodeCardItem from './RecodeCardItem';
+import ChatWelcome from "./ChatWelcome";
+import SvgIcon from './SvgIcon';
+
+export {
+
+  BaseButton,
+  BaseInput,
+  BasePopover,
+  BaseCard,
+  
+  TheChatView,
+  TheLogo,
+  TheMenu,
+  ThePublicLayout,
+  TheSubMenu,
+
+  RecodeCardItem,
+  ChatWelcome,
+  SvgIcon,
+
+}

+ 2 - 2
src/main.ts

@@ -1,7 +1,7 @@
-// import './assets/main.css'
+import 'virtual:svg-icons-register'
+
 import './assets/styles/tailwind.css'
 import './assets/styles/index.scss'
-import 'virtual:svg-icons-register'
 
 import { createApp } from 'vue'
 

+ 8 - 8
src/router/index.js

@@ -1,14 +1,8 @@
 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',
@@ -17,12 +11,18 @@ const router = createRouter({
         {
           path: 'answer',
           name: 'Answer',
-          component: () => import('@/views/answer/AnswerView.vue')
+          component: () => import('@/views/answer/AnswerView.vue'),
+          meta: {
+            title: '专家问答'
+          }
         },
         {
           path: 'water-warn',
           name: 'WaterWarn',
-          component: () => import('@/views/analyse/WaterView.vue')
+          component: () => import('@/views/analyse/WaterView.vue'),
+          meta: {
+            title: '水质报警'
+          }
         },
       ]
     },

+ 0 - 15
src/views/AboutView.vue

@@ -1,15 +0,0 @@
-<template>
-  <div class="about">
-    <h1>This is an about page</h1>
-  </div>
-</template>
-
-<style>
-@media (min-width: 1024px) {
-  .about {
-    min-height: 100vh;
-    display: flex;
-    align-items: center;
-  }
-}
-</style>

+ 0 - 9
src/views/HomeView.vue

@@ -1,9 +0,0 @@
-<script setup lang="ts">
-import TheWelcome from '../components/TheWelcome.vue'
-</script>
-
-<template>
-  <main>
-    <TheWelcome />
-  </main>
-</template>

+ 158 - 22
src/views/analyse/WaterView.vue

@@ -1,12 +1,63 @@
-<script setup>
-import { NTabs, NTab, NEllipsis } from 'naive-ui';
-import SvgIcon from '@/components/SvgIcon';
-import BaseButton from "@/components/BaseButton";
-import RecodeCardItem from '@/components/RecodeCardItem';
+<script setup lang="jsx">
+import { ref, h } from 'vue';
+import { NTabs, NTab, NEllipsis, NDataTable } from 'naive-ui';
+import {
+  BaseButton,
+  BaseInput,
+  BaseCard,
+  ChatWelcome,
+  SvgIcon,
+  RecodeCardItem,
+  TheSubMenu,
+  TheChatView,
+} from "@/components";
 
-import TheSubMenu from '@/components/Layout/TheSubMenu.vue';
-import TheChatView from '@/components/Layout/TheChatView.vue';
-import BaseInput from '@/components/BaseInput';
+
+
+const columns = [
+    {
+      title: "流量(m³/h)",
+      key: 'name',
+      titleAlign: 'center',
+      align: 'center',
+    },
+    {
+      title: 'COD(mg/L)',
+      key: 'age',
+      titleAlign: 'center',
+      align: 'center',
+    },
+    {
+      title: 'TN(mg/L)',
+      key: 'address',
+      titleAlign: 'center',
+      align: 'center',
+    },
+    {
+      title: 'NH3 -N(mg/L)',
+      key: 'tags',
+      titleAlign: 'center',
+      align: 'center',
+    },
+    {
+      title: '总磷TP(mg/L)',
+      key: 'actions',
+      titleAlign: 'center',
+      align: 'center',
+      render(row) {
+        // TODO: 需要调整,待后续请求参数确定
+        return (<span class={ row.actions > 7 ? 'text-[#F44C49] font-bold': 'text-[1A2029]' }>{row.actions} ↑</span>)
+      }
+    },
+    {
+      title: 'SS(mg/L)',
+      key: 'actions1',
+      titleAlign: 'center',
+      align: 'center',
+    }
+  ]
+
+const inWaterTableData = ref([{name: 1233, actions: "7.87"}])
 
 // 新建对话
 const handleCreateDialog = () => {
@@ -14,7 +65,7 @@ const handleCreateDialog = () => {
 }
 
 const handleLoad = () => {
-  console.log( "loading" )
+  console.log("loading")
 }
 </script>
 
@@ -32,11 +83,11 @@ const handleLoad = () => {
       </template>
       <div class="px-[12px] py-[14px] text-[#5e5e5e]">
         <div class="grid grid-cols-1 gap-[12px]">
-          <div class="card-item" v-for="item in 10">
-            <div class="status-tips status-tips_warning">
+          <div class="warning-item-inner" v-for="item in 10">
+            <div class="tips tips_warning">
               <span>报警中</span>
             </div>
-            <dl class="info-list">
+            <dl class="warning-info">
               <dt>
                 <n-ellipsis class="font-bold text-[#1A2029] leading-[20px]">进水总磷超标报警</n-ellipsis>
               </dt>
@@ -59,18 +110,83 @@ const handleLoad = () => {
         </div>
       </div>
     </TheSubMenu>
-    <TheChatView></TheChatView>
+
+    <TheChatView>
+
+      <ChatWelcome
+        title="您好,我是LibraAI工艺管控助手"
+        card-title="常见处理方案:" 
+          :sub-title="[
+          '报警分析功能具备实时监测与预警机制,检测到异常情况立即触发多种报警方式,推送相关',
+          '工作人员确保问题及时处理。报警时间为每小时警报,请大家及时处理。'
+        ]"
+        :card-content="[
+          '进水COD超标原因分析及常见的解决方案',
+          '进水TP超标原因分析及常见的解决方案',
+          '出水TN超标原因分析及常见的解决方案'
+        ]"
+        v-if="false"
+      />
+
+      <BaseCard>
+        <div class="waring-answer-wrapper">
+          <dl class="warning-inner warning-info_medium mb-[20px]">
+            <dt class="mb-[2px] font-bold text-[#1A2029] leading-[20px]">进水总磷报警</dt>
+            <dd><span>报警时间:2024-4-25 21:00</span></dd>
+            <dd><span class="text-[#F44C49]">报警值:7.87mg/L</span></dd>
+            <dd><span>标准值:7.1mg/L</span></dd>
+            <dd><span>报警级别:二级</span></dd>
+            <dd><span>报警次数:33</span></dd>
+            <dd><span>状态:报警中</span></dd>
+          </dl>
+          <div class="warning-table mb-[16px]">
+            <div class="title">
+              <span>当前进水数据:</span>
+            </div>
+            <div class="main">
+              <n-data-table
+                bordered
+                align="center"
+                :single-line="false"
+                :columns="columns"
+                :data="inWaterTableData"
+              />
+            </div>
+          </div>
+
+          <div class="warning-table">
+            <div class="title">
+              <span>当前出水数据:</span>
+            </div>
+            <div class="main">
+              <n-data-table
+                bordered
+                align="center"
+                :single-line="false"
+                :columns="columns"
+                :data="inWaterTableData"
+              />
+            </div>
+          </div>
+        </div>
+      </BaseCard>
+
+    </TheChatView>
   </section>
 </template>
 
 <style scoped lang="scss">
-.card-item {
+.base-card-container {
+  margin-bottom: 20px;
+}
+
+.warning-item-inner {
   position: relative;
   padding: 20px 8px 8px 8px;
   border-radius: 4px;
   background: #DDE5EF;
 
-  .status-tips {
+  .tips {
     position: absolute;
     width: 36px;
     height: 14px;
@@ -81,7 +197,8 @@ const handleLoad = () => {
     text-align: center;
     line-height: 14px;
 
-    &_warning, &_being {
+    &_warning,
+    &_being {
       color: #F44C49;
       background: #FFF0ED;
     }
@@ -96,14 +213,33 @@ const handleLoad = () => {
       background: #D5D5D5;
     }
   }
+}
+
+.warning-info {
+  line-height: 16px;
+  font-size: 11px;
+  color: #5E5E5E;
+
+  dd {
+    margin-top: 4px;
+  }
 
-  .info-list {
-    line-height: 16px;
-    font-size: 11px;
-    color: #5E5E5E;
+  &_medium {
+    line-height: 26px;
+    font-size: 15px;
+    color: #1A2029;
+  }
+}
 
-    dd {
-      margin-top: 4px;
+// 回答区域卡片
+.waring-answer-wrapper {
+  .warning-table {
+    .title {
+      margin-bottom: 8px;
+      line-height: 24px;
+      font-size: 15px;
+      font-weight: bold;
+      color: #1A2029;
     }
   }
 }

+ 3 - 3
tailwind.config.js

@@ -1,8 +1,8 @@
 /** @type {import('tailwindcss').Config} */
 export default {
-  content: [],
-  purge: ['./index.html', './src/**/*.{vue,js,ts,jsx,tsx}'],
-  darkMode: false,
+  // content: [],
+  content: ['./index.html', './src/**/*.{vue,js,ts,jsx,tsx}'],
+  // darkMode: false,
   theme: {
     extend: {},
   },