浏览代码

feat: 小程序基本样式布局

sunxiao 1 周之前
父节点
当前提交
3ea6dc7cb5

+ 11 - 0
.env.development

@@ -0,0 +1,11 @@
+# 页面标题
+VITE_APP_TITLE = 大模型微信端
+
+# 开发环境配置
+VITE_APP_ENV = 'development'
+
+# 图片路径
+VITE_IMGAGE_PATH = 'https://static.fuxicarbon.com/bigModel/wechat'
+
+# 开发环境
+VITE_APP_BASE_API =  http://192.168.40.18:8080

+ 19 - 0
.env.production

@@ -0,0 +1,19 @@
+# 页面标题
+VITE_APP_TITLE = 佳木斯智能语音客服
+
+# 生产环境配置
+VITE_APP_ENV = 'production'
+
+
+# 图片路径
+VITE_IMGAGE_PATH = 'https://agr-1253934376.cos.ap-shanghai.myqcloud.com/gzxsdsq'
+
+# 管理系统/开发环境
+# VITE_APP_BASE_API =  https://xsdev.agritechure.com/prod-api/
+VITE_APP_BASE_API =  https://xsd.agritechure.com/prod-api
+
+# 是否在打包时开启压缩,支持 gzip 和 brotli
+VITE_BUILD_COMPRESS = gzip
+
+VITE_APP_BASE_TEST = http://10.0.0.28:8080/
+VITE_APP_BASE_PROD = http://192.168.9.54:8080/

+ 6 - 0
package-lock.json

@@ -24,6 +24,7 @@
         "@dcloudio/uni-mp-xhs": "3.0.0-4020420240722002",
         "@dcloudio/uni-quickapp-webview": "3.0.0-4020420240722002",
         "@dcloudio/uni-ui": "^1.5.6",
+        "crypto-js": "^4.2.0",
         "pinia": "^2.2.0",
         "pinia-plugin-persistedstate": "^3.2.1",
         "sass": "^1.77.8",
@@ -5804,6 +5805,11 @@
         "node": ">= 8"
       }
     },
+    "node_modules/crypto-js": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmmirror.com/crypto-js/-/crypto-js-4.2.0.tgz",
+      "integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q=="
+    },
     "node_modules/css-font-size-keywords": {
       "version": "1.0.0",
       "resolved": "https://registry.npmmirror.com/css-font-size-keywords/-/css-font-size-keywords-1.0.0.tgz",

+ 1 - 0
package.json

@@ -58,6 +58,7 @@
     "@dcloudio/uni-mp-xhs": "3.0.0-4020420240722002",
     "@dcloudio/uni-quickapp-webview": "3.0.0-4020420240722002",
     "@dcloudio/uni-ui": "^1.5.6",
+    "crypto-js": "^4.2.0",
     "pinia": "^2.2.0",
     "pinia-plugin-persistedstate": "^3.2.1",
     "sass": "^1.77.8",

+ 1 - 0
src/components/chat/ChatAnswer.vue

@@ -28,6 +28,7 @@ import { ref } from 'vue';
 <style lang="scss" scoped>
 .answer-container {
   padding-right: 64rpx;
+  padding-left: 20rpx;
 
   .answer-inner {
     padding: 24rpx;

+ 12 - 12
src/components/chat/ChatAsk.vue

@@ -14,19 +14,19 @@ import { ref } from 'vue';
 
 <style lang="scss" scoped>
 .ask-container {
-  // padding-left: 64rpx;
+  padding: 0 20rpx;
   margin-bottom: 32rpx;
-}
-.ask-inner {
-  display: flex;
-  justify-content: flex-end;
-  font-size: 28rpx;
-  color: #fff;
-  .ask-content {
-    display: inline-flex;
-    padding: 20rpx 24rpx;
-    border-radius: 30rpx 30rpx 4rpx 30rpx;
-    background: linear-gradient(88deg, #2A67F8 4.95%, #4892FF 93.07%);
+  .ask-inner {
+    display: flex;
+    justify-content: flex-end;
+    font-size: 28rpx;
+    color: #fff;
+    .ask-content {
+      display: inline-flex;
+      padding: 20rpx 24rpx;
+      border-radius: 30rpx 30rpx 4rpx 30rpx;
+      background: linear-gradient(88deg, #2A67F8 4.95%, #4892FF 93.07%);
+    }
   }
 }
 </style>

+ 80 - 0
src/components/chat/ChatInput.vue

@@ -0,0 +1,80 @@
+<script setup>
+const modelInpValue = defineModel();
+</script>
+
+<template>
+  <view class="chat-inp-container">
+    <view class="chat-inp-inner">
+      <div class="voice-btn">
+        <TheSvgIcon class="icon" src="icon-voice" size="42"></TheSvgIcon>
+      </div>
+      <view class="inp-inner">
+        <textarea
+          v-model="modelInpValue"
+          auto-height
+          :maxlength="1000"
+          class="chat-inp"
+          placeholder="输入您的问题或需求"
+          placeholder-style="color:#9A9A9A"
+        >
+        </textarea>
+      </view>
+      <view class="send-btn">
+        <TheSvgIcon class="icon" src="icon-send-plane" size="30"></TheSvgIcon>
+      </view>
+    </view>
+  </view>
+</template>
+
+<style lang="scss" scoped>
+.chat-inp-container {
+  padding: 0 24rpx;
+  box-sizing: content-box;
+
+  .chat-inp-inner {
+    display: flex;
+    padding: 26rpx 28rpx;
+    align-items: flex-end;
+    // align-items: center;
+    border-radius: 32rpx;
+    background: #FFF;
+    box-shadow: 0px 8rpx 16rpx 2rpx rgba(172, 200, 224, 0.20);
+
+    .voice-btn {
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      height: 56rpx;
+    }
+
+    .inp-inner {
+      width: 100%;
+      height: 100%;
+      margin-bottom: 8rpx;
+
+      .chat-inp {
+        width: 100%;
+        height: 100%;
+        max-height: 200rpx;
+        width: 100%;
+        height: 32rpx;
+        padding: 0 16rpx;
+        font-size: 28rpx;
+        color: #333;
+        box-sizing: border-box;
+      }
+    }
+
+    .send-btn {
+      flex-shrink: 0;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      width: 56rpx;
+      height: 56rpx;
+      border-radius: 100%;
+      background: #879AAF;
+    }
+  }
+}
+</style>

+ 51 - 0
src/components/chat/ChatTaskGroup.vue

@@ -0,0 +1,51 @@
+<script setup>
+const data = [
+  { label: '智能查数', key: 'smart' },
+  { label: '运行诊断', key: 'runing' },
+  { label: '公文往来', key: 'offical' },
+]
+</script>
+
+<template>
+  <!-- <scroll-view scroll-x="true"> </scroll-view> -->
+  <view class="task-group">
+    <view class="task-btn" v-for="item in data" :key="item.key">
+      <TheSvgIcon class="icon" :src="'icon-task-' + item.key" size="36"></TheSvgIcon>
+      <text class="text">{{ item.label }}</text>
+    </view>
+  </view>
+</template>
+
+<style lang="scss" scoped>
+.task-group {
+  display: flex;
+  width: 100%;
+  padding: 0 60rpx 16rpx 60rpx;
+  overflow: hidden;
+
+
+  .task-btn {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    width: 200rpx;
+    height: 76rpx;
+    border-radius: 8px;
+    background: #FFF;
+    color: #212121;
+    font-size: 26rpx;
+    font-weight: 500;
+    background: url('https://static.fuxicarbon.com/bigModel/wechat/layout/bg-task-left.svg') left top no-repeat,
+      url('https://static.fuxicarbon.com/bigModel/wechat/layout/bg-task-right.svg') right bottom no-repeat, #fff;
+    background-size: contain, contain;
+
+    .text {
+      margin-left: 8rpx;
+    }
+
+    &:not(:last-child) {
+      margin-right: 16rpx;
+    }
+  }
+}
+</style>

+ 17 - 2
src/components/chat/ChatWelcome.vue

@@ -29,7 +29,10 @@ defineProps({
 
     <view class="recommend-inner">
       <view class="question-card">
-        <text class="title">{{ cardTitle }}</text>
+        <view class="title-wrap">
+          <image src="https://static.fuxicarbon.com/bigModel/wechat/layout/icon-start.svg" alt=""  class="icon-start"/>
+          <text class="title">{{ cardTitle }}</text>
+        </view>
         <view class="list">
           <view class="item" v-for="item in cardContent" :key="item.id">
             <text class="text">{{ item.question }}</text>
@@ -43,6 +46,7 @@ defineProps({
 
 <style lang="scss" scoped>
 .chat-welcome {
+  padding-top: 56rpx;
   .weclome-inner {
     display: flex;
     align-items: center;
@@ -52,7 +56,7 @@ defineProps({
 
     .title {
       margin: 16rpx 0;
-      background: linear-gradient(90deg, #5C6883 0%, #212121 100%);
+      background: linear-gradient(90deg, #212121 0%, #5C6883 100%);
       background-clip: text;
       font-weight: bold;
       font-size: 36rpx;
@@ -64,6 +68,7 @@ defineProps({
       font-size: 24rpx;
       line-height: 44rpx;
       color: #7B909C;
+      font-weight: 400;
     }
   }
 
@@ -77,6 +82,16 @@ defineProps({
       font-size: 28rpx;
       font-weight: bold;
 
+      .title-wrap {
+        display: flex;
+        align-items: center;
+        .icon-start {
+          width: 40rpx;
+          height: 40rpx;
+          margin-right: 8rpx;
+        }
+      } 
+
       .title {
         background: var(--, linear-gradient(92deg, #5ABBF2 12.24%, #2454FF 63.2%));
         background-clip: text;

+ 3 - 0
src/components/chat/icon-send.svg

@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="28" height="28" viewBox="0 0 28 28" fill="none">
+  <circle cx="14" cy="14" r="14" fill="#879AAF"/>
+</svg>

+ 26 - 0
src/components/layout/BaseHeaderTools.vue

@@ -0,0 +1,26 @@
+<script setup>
+
+const emit = defineEmits(['on-history', 'on-add']);
+
+const onHistoryClick = () => emit('on-history');
+const onAddClick = () => emit('on-add');
+</script>
+
+<template>
+  <view class="header-tools-list">
+    <TheSvgIcon class="icon" src="icon-nav-history" size="40" @on-click="onHistoryClick"></TheSvgIcon>
+    <TheSvgIcon class="icon" src="icon-nav-add" size="40" @on-click="onAddClick"></TheSvgIcon>
+    <!-- <TheSvgIcon class="icon" src="icon-nav-voice" size="40"></TheSvgIcon> -->
+  </view>
+</template>
+
+<style lang="scss" scoped>
+.header-tools-list {
+  display: flex;
+  align-items: center;
+
+  & .icon:nth-child(2) {
+    margin: 0 20rpx;
+  }
+}
+</style>

+ 93 - 1
src/components/layout/BaseNavBar.vue

@@ -1,10 +1,29 @@
 <script setup>
+import { ref } from "vue";
+import { storeToRefs } from 'pinia';
+import { useChatStore } from '@/stores/modules/chatStore';
+
 defineProps({
   titleText: {
     type: String,
     default: ""
+  },
+  isDropdown: {
+    type: Boolean,
+    default: false
   }
 })
+
+const chatStore = useChatStore();
+
+const { dropdownList, titleActiveIndex, title } = storeToRefs(chatStore);
+
+const dropVisible = ref(false);
+
+const onDropdownChange = (index) => {
+  titleActiveIndex.value = index;
+  dropVisible.value = false;
+}
 </script>
 
 <template>
@@ -12,14 +31,37 @@ defineProps({
     <BaseStatusBar></BaseStatusBar>
     <uni-nav-bar :border="false" backgroundColor="rgba(0,0,0,0)" leftWidth="200rpx" rightWidth="200rpx">
       <template #left><slot></slot></template>
-      <view class="title">{{ titleText }}</view>
+      <view class="title" v-if="!isDropdown">{{ titleText }}</view>
+      <view class="title-dropdown" v-if="isDropdown" @click="dropVisible = !dropVisible">
+        <text class="en">LibraAI</text>
+        <text class="zh">{{ title }}</text>
+        <TheSvgIcon class="icon" src="icon-triangle" size="36" :style="{rotate: dropVisible ? '180deg' : '0deg'}"></TheSvgIcon>
+      </view>
       <template #right><slot name="right"></slot></template>
     </uni-nav-bar>
+
+    <view class="mask" v-show="dropVisible" @click="dropVisible = false"></view>
+
+    <view class="dropdown-list" v-show="dropVisible">
+      <view class="dropdown-item" v-for="item, index in dropdownList" :key="item.text" @click="onDropdownChange(index)">
+        <text>{{ item.text }}</text>
+        <TheSvgIcon class="icon" src="icon-check" size="32" v-show="titleActiveIndex == index"></TheSvgIcon>
+      </view>
+    </view>
   </view>
 </template>
 
 <style scoped lang="scss">
+.mask {
+  position: absolute;
+  width: 100vw;
+  height: 100vh;
+  background: rgba(0, 0, 0, 0);
+  z-index: 9;
+}
+
 .nav-bar-container {
+  position: relative;
   .title {
     width: 100%;
     height: 100%;
@@ -29,5 +71,55 @@ defineProps({
     font-size: 34rpx;
     color: #000;
   }
+
+  .title-dropdown {
+    position: relative;
+    width: 100%;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    font-size: 30rpx;
+    font-weight: 500;
+
+    .en {
+      color: #212121;
+      margin-right: 8rpx;
+    }
+    .zh {
+      color: #5C6883;
+    }
+  }
+
+  .dropdown-list {
+    position: absolute;
+    left: 50%;
+    bottom: -180rpx;
+    transform: translateX(-50%);
+    width: 284rpx;
+    height: 184rpx;
+    padding: 12rpx 36rpx;
+    margin: 0 auto;
+    background: #fff;
+    z-index: 10;
+    border-radius: 24rpx;
+    background: #FFF;
+    box-shadow: 0px 0px 16rpx 0px rgba(208, 208, 208, 0.25);
+    box-sizing: border-box;
+    color: #212121;
+    font-size: 30rpx;
+    font-weight: 500;
+    line-height: 40rpx;
+
+    .dropdown-item {
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      padding-top: 20rpx;
+      padding-bottom: 20rpx;
+    }
+    .dropdown-item:not(:last-child) {
+      border-bottom: 1px solid #F6F6F6;
+    }
+  }
 }
 </style>

+ 19 - 8
src/components/layout/BasePublicLayout.vue

@@ -71,7 +71,7 @@ onMounted(() => {
 </script>
 
 <template>
-  <view class="layout_container" :style="{ background: bgColor }">
+  <view class="layout-container" :style="{ background: bgColor }">
     <view class="header">
       <slot name="header"></slot>
     </view>
@@ -85,31 +85,42 @@ onMounted(() => {
       @scroll="onScroll"
     >
       <view class="scroll-content">
-        <slot name="content"></slot>
+        <slot name="content" class="content"></slot>
       </view>
     </scroll-view>
-    <view class="footer" v-if="isFooter">
-
+    <view class="footer" >
+      <slot name="footer"></slot>
       <!-- 这里需拆分出去 -->
-      <BaseTabBar></BaseTabBar>
+      <!-- <BaseTabBar></BaseTabBar> -->
     </view>
   </view>
 </template>
 
 <style lang="scss" scoped>
-.layout_container {
+.layout-container {
   display: flex;
   flex-flow: column;
-  justify-content: space-between;
   height: 100vh;
 
+  .header {
+    flex-shrink: 0;
+  }
+
   .scroll-view {
     flex: 1;
     overflow: hidden;
 
     .scroll-content {
-      padding-top: 56rpx;
+      display: flex;
+      width: 100%;
+      height: 100%;
     }
   }
+
+  .footer {
+    width: 100%;
+    flex-shrink: 0;
+    padding-bottom: env(safe-area-inset-bottom);
+  }
 }
 </style>

+ 14 - 6
src/pages.json

@@ -1,26 +1,34 @@
 {
   "pages": [
     {
-      "path": "pages/chat/chatView",
+      "path": "pages/answer/index",
       "style": {
         "navigationStyle": "custom",
-        "navigationBarTitleText": "对话窗口",
+        "navigationBarTitleText": "问答",
         "disableScroll": true
       }
     },
     {
-      "path": "pages/chat/index",
+      "path": "pages/home/index",
       "style": {
         "navigationStyle": "custom",
-        "navigationBarTitleText": "专家问答",
+        "navigationBarTitleText": "首页",
         "disableScroll": true
       }
     },
     {
-      "path": "pages/home/index",
+      "path": "pages/chat/chatView",
       "style": {
         "navigationStyle": "custom",
-        "navigationBarTitleText": "首页",
+        "navigationBarTitleText": "对话窗口",
+        "disableScroll": true
+      }
+    },
+    {
+      "path": "pages/chat/index",
+      "style": {
+        "navigationStyle": "custom",
+        "navigationBarTitleText": "专家问答",
         "disableScroll": true
       }
     },

+ 107 - 0
src/pages/answer/index.vue

@@ -0,0 +1,107 @@
+<script setup>
+import { onMounted, ref } from 'vue';
+import { useUserStore } from '@/stores/modules/userStore';
+import { useRecommend } from '@/composables/useRecommend';
+
+const userStore = useUserStore();
+
+const showRight = ref(null);
+
+const { recommendList } = useRecommend({ type: 0 });
+
+const inpValue = ref('');
+
+// const jumpChatView = () => {
+//   console.log("执行了");
+//   uni.navigateTo({ url: '/pages/chat/chatView' });
+// }
+
+
+// 点击历史记录
+const onHistory = () => {
+  console.log("history");
+  showRight.value.open();
+}
+
+// 新建会话
+const onAdd = () => {
+  console.log("add");
+}
+
+const closeDrawer = () => {
+  showRight.value.close();
+}
+
+onMounted(() => {
+  // setInterval(item => {
+  //   num.value = num.value + 1;
+  //   console.log( num.value );
+  // }, 1000)
+})
+
+</script>
+
+<template>
+  <BasePublicLayout>
+    <template #header>
+      <BaseNavBar titleText="专家问答" isDropdown>
+        <BaseHeaderTools @on-history="onHistory" @on-add="onAdd"></BaseHeaderTools>
+      </BaseNavBar>
+    </template>
+
+    <template #content>
+      <view class="chat-front-card" v-if="false">
+        <ChatWelcome
+          title="您好,我是LibraAI专家问答"
+          card-title="您可以试着问我:"
+          :sub-title="[
+            '期待与您一同规划和完成未来的工作',
+            '有任何重点或需讨论的事项,随时告诉我'
+          ]"
+          :card-content="recommendList">
+        </ChatWelcome>
+        <ChatTaskGroup></ChatTaskGroup>
+      </view>
+
+      <view class="qa-container">
+        <view clas="qa-item">
+          <ChatAsk></ChatAsk>
+          <ChatAnswer></ChatAnswer>
+        </view>
+      </view>
+    </template>
+
+    <template #footer>
+      <ChatInput v-model="inpValue"></ChatInput>
+    </template>
+  </BasePublicLayout>
+
+  <!-- 
+    TODO: 抽屉组件 
+    后续完善
+  -->
+  <!-- <uni-drawer ref="showRight" mode="right" :mask-click="false" width="640">
+    <scroll-view style="height: 100%;" scroll-y="true">
+      <button @click="closeDrawer" type="primary">关闭Drawer</button>
+      <view v-for="item in 60" :key="item">可滚动内容 {{ item }}</view>
+    </scroll-view>
+  </uni-drawer> -->
+</template>
+
+<style lang="scss" scoped>
+.chat-front-card {
+  width: 100vw;
+  height: 100%;
+  display: flex;
+  flex-flow: column;
+  justify-content: space-between;
+}
+
+.qa-container {
+  padding-top: 64rpx;
+}
+
+// .qu-item {
+//   padding: ;
+// }
+</style>

+ 19 - 1
src/pages/chat/chatView.vue

@@ -2,13 +2,29 @@
 import { ref } from 'vue';
 
 const val = ref('');
+const change = () => {
 
+  uni.downloadFile({
+  url: 'https://www.lilnong.top/static/pdf/B-4-RxJS%E5%9C%A8React%E4%B8%AD%E7%9A%84%E5%BA%94%E7%94%A8-%E9%BE%99%E9%80%B8%E6%A5%A0_.pdf',
+  success: function (res) {
+    var filePath = res.tempFilePath;
+    uni.openDocument({
+      filePath: filePath,
+      showMenu: true,
+      success: function (res) {
+        console.log('打开文档成功');
+      }
+    });
+  }
+});
+
+}
 </script>
 
 <template>
   <BasePublicLayout :is-footer="false">
     <template #header>
-      <BaseNavBar title-text="专家问答">
+      <BaseNavBar title-text="专家问答123">
         <view class="nav-btn_back">
           <TheSvgIcon class="icon" src="icon-back" size="40"></TheSvgIcon>
         </view>
@@ -16,9 +32,11 @@ const val = ref('');
     </template>
     <template #content>
       <view class="chat-container">
+
         <ChatAsk></ChatAsk>
         <ChatAnswer></ChatAnswer>
         <view class="chat-inp-container">
+          <view @click="change">按钮</view>
           TheSvgIcon
           <textarea v-model="val" auto-height :maxlength="1000"></textarea>
         </view>

+ 17 - 3
src/pages/home/index.vue

@@ -1,9 +1,23 @@
 <template>
-
   <BasePublicLayout>
+    <template #header>
+      <BaseNavBar titleText="专家问答">
+        <BaseHeaderTools></BaseHeaderTools>
+      </BaseNavBar>
+    </template>
     <template #content>
-      这是home
+    
     </template>
   </BasePublicLayout>
+</template>
+
+<style lang="scss" scoped>
+.header-tools-list {
+  display: flex;
+  align-items: center;
 
-</template>
+  & .icon:nth-child(2) {
+    margin: 0 20rpx;
+  }
+}
+</style>

+ 36 - 11
src/pages/login/index.vue

@@ -2,11 +2,15 @@
 import { ref, unref } from 'vue';
 import { userApi } from '@/api/login';
 import { useUserStore } from '@/stores/modules/userStore';
+import { AES_ECB_ENCRYPT } from "@/utils/crypto";
+
+const IMG_PATH = import.meta.env.VITE_IMGAGE_PATH;
 
 const REMOTE_PATH = {
-  logo    : 'https://static.fuxicarbon.com/bigModel/wechat/login/img-desc.png',
-  username: 'https://static.fuxicarbon.com/bigModel/wechat/login/icon-username.png',
-  password: 'https://static.fuxicarbon.com/bigModel/wechat/login/icon-password.png'
+  logoEn    : IMG_PATH +'/login/img-en-logo.svg',
+  logoZh    : IMG_PATH +'/login/img-zh-logo.svg',
+  username  : IMG_PATH + '/login/icon-username.png',
+  password  : IMG_PATH + '/login/icon-password.png'
 }
 
 const userStore = useUserStore();
@@ -14,7 +18,7 @@ const userStore = useUserStore();
 const showPasswordIcon = ref(false);
 const loading = ref(false);
 const loginFormData = ref({
-  username: 'test1',
+  username: 'test11',
   password: 'admin123',
   type: 0
 });
@@ -33,7 +37,7 @@ const handleSubmit = async () => {
   loading.value = true;
 
   try {
-    const { token } = await userApi.postLogin({ username, password, type: 0 });
+    const { token } = await userApi.postLogin({ username, password: AES_ECB_ENCRYPT(password), type: 0 });
 
     userStore.setUserInfo({ token });
 
@@ -57,7 +61,12 @@ const handleSubmit = async () => {
     <BaseNavBar title-text="登录" class="nav-bar"></BaseNavBar>
     <view class="login-content">
       <view class="logo-inner">
-        <image :src="REMOTE_PATH.logo" class="img-desc"></image>
+        <view class="en-logo"><image :src="REMOTE_PATH.logoEn" class="img"></image></view>
+        <view class="zh-logo"><image :src="REMOTE_PATH.logoZh" class="img"></image></view>
+        <view class="text-desc">
+          <text>国内首家水务行业大模型,赋能水务行业,为水务行业主体</text>
+          <text>提供创新应用和全面支持</text>
+        </view>
       </view>
       <view class="form-inner">
         <view class="login-form-item">
@@ -77,7 +86,7 @@ const handleSubmit = async () => {
         </button>
       </view>
       <view class="text-inner">
-        <text>人工智能运营体智慧决策助手</text>
+        <text>内容由AI生成,仅供参考</text>
       </view>
     </view>
   </view>
@@ -99,9 +108,25 @@ const handleSubmit = async () => {
     padding: 132rpx 60rpx 36rpx 60rpx;
 
     .logo-inner {
-      .img-desc {
-        width: 500rpx;
-        height: 96rpx;
+      .en-logo {
+        width: 152rpx;
+        height: 36rpx;
+      }
+      .zh-logo {
+        width: 360rpx;
+        height: 76rpx;
+      }
+      .img {
+        width: 100%;
+        height: 100%;
+      }
+      .text-desc {
+        display: flex;
+        align-items: start;
+        flex-flow: column;
+        font-size: 24rpx;
+        color: #595959;
+        line-height: 36rpx;
       }
     }
 
@@ -165,7 +190,7 @@ const handleSubmit = async () => {
       padding-bottom: 50rpx;
       font-size: 28rpx;
       text-align: center;
-      color: #727687;
+      color: rgba(114, 118, 135, 0.50);
     }
   }
 }

+ 30 - 0
src/stores/modules/chatStore.js

@@ -0,0 +1,30 @@
+import { ref, unref, computed } from "vue";
+import { defineStore } from "pinia";
+
+const dropdown = [
+  {
+    text: "专家问答",
+    url: "/pages/index/index"
+  },
+  {
+    text: "水质报警",
+    url: "/pages/index/index"
+  }
+]
+
+export const useChatStore = defineStore(
+  "chat",
+  () => {
+    
+    const dropdownList = ref(dropdown);
+    const titleActiveIndex = ref(0);
+
+    const title = computed(() => dropdownList.value[unref(titleActiveIndex)].text);
+
+    return {
+      dropdownList,
+      titleActiveIndex,
+      title,
+    };
+  }
+);

+ 10 - 0
src/utils/crypto.js

@@ -0,0 +1,10 @@
+import CryptoJS from 'crypto-js';
+const SECRET_KEY = 'qwertasdfg159753';
+export const AES_ECB_ENCRYPT = (text) => {
+  var keyHex = CryptoJS.enc.Utf8.parse(SECRET_KEY);
+  var messageHex = CryptoJS.enc.Utf8.parse(text);
+  var encrypted = CryptoJS.AES.encrypt(messageHex, keyHex, {
+    "mode": CryptoJS.mode.ECB
+  });
+  return encrypted.toString();
+}

+ 1 - 1
src/utils/https.js

@@ -1,7 +1,7 @@
 import { useUserStore } from "@/stores/modules/userStore";
 
 // 开发
-export const baseURL = 'http://10.0.0.28:8080';
+export const baseURL = import.meta.env.VITE_APP_BASE_API;
 
 const userStore = useUserStore();
 

+ 5 - 1
vite.config.js

@@ -3,7 +3,11 @@ import uni from '@dcloudio/vite-plugin-uni'
 // https://vitejs.dev/config/
 export default defineConfig({
   plugins: [
-    uni(),
+    uni({
+      vueOptions: {
+        reactivityTransform: true  // 启用响应性语法糖
+      }
+    }),
   ],
   transpileDependencies: ["@dcloudio/uni-ui"]
 })