Hua 2 kuukautta sitten
vanhempi
commit
a8cc076402
32 muutettua tiedostoa jossa 173 lisäystä ja 44 poistoa
  1. 4 4
      ruoyi-ui/.env.development
  2. 3 2
      ruoyi-ui/.env.production
  3. BIN
      ruoyi-ui/src/assets/上海水务首页图片包/上海城区洪涝仿真模型.png
  4. BIN
      ruoyi-ui/src/assets/上海水务首页图片包/上海市中心城区排水系统模型.png
  5. BIN
      ruoyi-ui/src/assets/上海水务首页图片包/模型介绍.png
  6. BIN
      ruoyi-ui/src/assets/上海水务首页图片包/模型名称和介绍.png
  7. BIN
      ruoyi-ui/src/assets/上海水务首页图片包/模型服务管理.png
  8. BIN
      ruoyi-ui/src/assets/上海水务首页图片包/模型标准化.png
  9. BIN
      ruoyi-ui/src/assets/上海水务首页图片包/模型标题.png
  10. BIN
      ruoyi-ui/src/assets/上海水务首页图片包/模型注册.png
  11. BIN
      ruoyi-ui/src/assets/上海水务首页图片包/模型监控.png
  12. BIN
      ruoyi-ui/src/assets/上海水务首页图片包/模型评价.png
  13. BIN
      ruoyi-ui/src/assets/上海水务首页图片包/浅蓝.png
  14. BIN
      ruoyi-ui/src/assets/上海水务首页图片包/深蓝.png
  15. BIN
      ruoyi-ui/src/assets/上海水务首页图片包/温带风暴潮预报模型.png
  16. BIN
      ruoyi-ui/src/assets/上海水务首页图片包/苏州河水系水情预报模型.png
  17. BIN
      ruoyi-ui/src/assets/上海水务首页图片包/项目标题.png
  18. BIN
      ruoyi-ui/src/assets/上海水务首页图片包/风暴潮.png
  19. BIN
      ruoyi-ui/src/assets/上海水务首页图片包/风暴潮模型.png
  20. BIN
      ruoyi-ui/src/assets/上海水务首页图片包/风暴潮背景.png
  21. BIN
      ruoyi-ui/src/assets/上海水务首页图片包/黄浦江水系水文分析预报数值模拟模型.png
  22. 1 1
      ruoyi-ui/src/permission.js
  23. 5 0
      ruoyi-ui/src/router/index.js
  24. 8 11
      ruoyi-ui/src/utils/websocket.js
  25. 1 1
      ruoyi-ui/src/views/login.vue
  26. 5 2
      ruoyi-ui/src/views/register/modelData/metaData.vue
  27. 7 7
      ruoyi-ui/src/views/service/info/editModel.vue
  28. 4 2
      ruoyi-ui/src/views/service/info/shenhe.vue
  29. 101 0
      ruoyi-ui/src/views/shouye.vue
  30. 5 2
      ruoyi-ui/src/views/standardization/modelUsing/index.vue
  31. 23 6
      ruoyi-ui/src/views/standardization/modeling/index.vue
  32. 6 6
      ruoyi-ui/vite.config.js

+ 4 - 4
ruoyi-ui/.env.development

@@ -9,10 +9,10 @@ VITE_APP_ENV = 'development'
 VITE_APP_BASE_Title = '/sh'
 # 若依管理系统/生产环境
 VITE_APP_BASE_API = '/sh-api'
-
-# VITE_DEV_PATH = 'http://localhost:8082'
-VITE_DEV_PATH = 'http://192.168.2.104:8082'
-VITE_WS_BASE_URL = '/websocket'
+VITE_APP_WEBSOCKET_PATH = '/websocket'
+VITE_DEV_PATH = 'http://localhost:8082'
+# VITE_DEV_PATH = 'http://192.168.2.104:8082'
+VITE_WS_BASE_URL = 'localhost:8082'
 # 是否在打包时开启压缩,支持 gzip 和 brotli
 VITE_BUILD_COMPRESS = gzip
 

+ 3 - 2
ruoyi-ui/.env.production

@@ -9,10 +9,11 @@ VITE_APP_ENV = 'production'
 VITE_APP_BASE_Title = '/sh'
 # 若依管理系统/生产环境
 VITE_APP_BASE_API = '/sh-api'
-
+VITE_APP_WEBSOCKET_PATH = '/websocket'
+# VITE_DEV_PATH = 'http://localhost:8082'
 VITE_DEV_PATH = 'http://localhost:8082'
 # 是否在打包时开启压缩,支持 gzip 和 brotli
-VITE_WS_BASE_URL = '/websocket'
+VITE_WS_BASE_URL = 'localhost:8082'
 
 VITE_BUILD_COMPRESS = gzip
 

BIN
ruoyi-ui/src/assets/上海水务首页图片包/上海城区洪涝仿真模型.png


BIN
ruoyi-ui/src/assets/上海水务首页图片包/上海市中心城区排水系统模型.png


BIN
ruoyi-ui/src/assets/上海水务首页图片包/模型介绍.png


BIN
ruoyi-ui/src/assets/上海水务首页图片包/模型名称和介绍.png


BIN
ruoyi-ui/src/assets/上海水务首页图片包/模型服务管理.png


BIN
ruoyi-ui/src/assets/上海水务首页图片包/模型标准化.png


BIN
ruoyi-ui/src/assets/上海水务首页图片包/模型标题.png


BIN
ruoyi-ui/src/assets/上海水务首页图片包/模型注册.png


BIN
ruoyi-ui/src/assets/上海水务首页图片包/模型监控.png


BIN
ruoyi-ui/src/assets/上海水务首页图片包/模型评价.png


BIN
ruoyi-ui/src/assets/上海水务首页图片包/浅蓝.png


BIN
ruoyi-ui/src/assets/上海水务首页图片包/深蓝.png


BIN
ruoyi-ui/src/assets/上海水务首页图片包/温带风暴潮预报模型.png


BIN
ruoyi-ui/src/assets/上海水务首页图片包/苏州河水系水情预报模型.png


BIN
ruoyi-ui/src/assets/上海水务首页图片包/项目标题.png


BIN
ruoyi-ui/src/assets/上海水务首页图片包/风暴潮.png


BIN
ruoyi-ui/src/assets/上海水务首页图片包/风暴潮模型.png


BIN
ruoyi-ui/src/assets/上海水务首页图片包/风暴潮背景.png


BIN
ruoyi-ui/src/assets/上海水务首页图片包/黄浦江水系水文分析预报数值模拟模型.png


+ 1 - 1
ruoyi-ui/src/permission.js

@@ -11,7 +11,7 @@ import usePermissionStore from "@/store/modules/permission";
 
 NProgress.configure({ showSpinner: false });
 
-const whiteList = ["/login", "/register", "/forceResetPwd", "index"];
+const whiteList = ["/login", "/register", "/forceResetPwd", "index",'/shouye'];
 
 router.beforeEach((to, from, next) => {
   NProgress.start();

+ 5 - 0
ruoyi-ui/src/router/index.js

@@ -26,6 +26,11 @@ import Layout from '@/layout'
 
 // 公共路由
 export const constantRoutes = [
+    {
+        path: '/shouye',
+        component: () => import('@/views/shouye'),
+        hidden: true,
+    },
     {
         path: '/redirect',
         component: Layout,

+ 8 - 11
ruoyi-ui/src/utils/websocket.js

@@ -1,13 +1,10 @@
-
-
-export function createWebSocket(path = '/message') {
-  const baseUrl = import.meta.env.VITE_DEV_PATH
+export const getWebSocketUrl = (endpoint = '') => {
+  const protocol = window.location.protocol;
+  const host = window.location.host;
   
-  // 开发环境使用相对路径(走代理)
-  // 生产环境使用完整 WSS 地址
-  const url = import.meta.env.DEV 
-    ? `${baseUrl}${path}`
-    : `${baseUrl}${path}`
+  // 自动识别协议:HTTPS用wss,HTTP用ws
+  const wsProtocol = protocol === 'https:' ? 'wss:' : 'ws:';
+  const websocketPath = import.meta.env.VITE_APP_WEBSOCKET_PATH;
   
-  return new WebSocket(url)
-}
+  return `${wsProtocol}//${host}${websocketPath}${endpoint}`;
+};

+ 1 - 1
ruoyi-ui/src/views/login.vue

@@ -131,7 +131,7 @@ function handleLogin() {
           }
           return acc;
         }, {});
-        router.push('datamonitor/monitorservice');
+        router.push('shouye');
       }).catch(() => {
         loading.value = false;
         // 重新获取验证码

+ 5 - 2
ruoyi-ui/src/views/register/modelData/metaData.vue

@@ -71,11 +71,12 @@
     </div>
   </div>
   <el-dialog :title="title" @close="clearForm" v-model="dialogVisible" title="" width="30%"  destroy-on-close :key="tableKey">
-    <el-form :label-width="140" label-position="right" :disabled="isEdit" style="margin-left: 5%;margin-top: 2%;"  :model="formZu" class="demo-form-inline" ref="formRefZu" :rules="rulesZu">
+    <el-form :label-width="140" label-position="right" :disabled="isEdit" style="margin-left: 5%;margin-top: 2%;"  :model="formZu" class="demo-form-inline"
+     ref="formRefZu" :rules="rulesZu">
       <el-form-item label="元数据表名(英文):" prop="metaTable" style="" v-if="isAddTa">
         <el-input v-model="formZu.metaTable" style="width: 75%;" placeholder=""  resize="none"/>
       </el-form-item>
-      <el-form-item label="元数据表中文名:" prop="dsType" style="">
+      <el-form-item label="元数据表中文名:" prop="metaName" style="">
         <el-input v-model="formZu.metaName" style="width: 75%;" placeholder=""  resize="none"/>
       </el-form-item>
       <el-form-item label="元数据表说明:" prop="dsPort" style="">
@@ -248,6 +249,8 @@ const formZu = ref({
 });
 const rulesZu = reactive({
   metaTable: [{ required: true, message: '必填', trigger: 'blur' }],
+  metaName: [{ required: true, message: '必填', trigger: 'blur' }],
+  
 });
 const formRefZu = ref();
 const tableDataCanAdd = ref([])

+ 7 - 7
ruoyi-ui/src/views/service/info/editModel.vue

@@ -221,7 +221,7 @@
                     <el-option
                         v-for="item in gatewayRouters"
                         :key="item.value"
-                        :label="item.predicates"
+                        :label="item.serviceName"
                         :value="item.id"
                     />
                   </el-select>
@@ -583,7 +583,7 @@
                 <el-option
                     v-for="item in gatewayRouters"
                     :key="item.value"
-                    :label="item.predicates"
+                    :label="item.serviceName"
                     :value="item.id"
                 />
               </el-select>
@@ -1429,7 +1429,7 @@ async function delSer(row) {
     var par1  = {
       data:{id:parMdid.value}
     }
-    handleNodeClick(null,par1,null)
+    // handleNodeClick(null,par1,null)
     proxy.$modal.msgSuccess("删除成功");
   }).catch(() => {
   });
@@ -1509,7 +1509,7 @@ async function edSer() {
                   var par1  = {
                     data:{id:parMdid.value}
                   }
-                  handleNodeClick(null,par1,null)
+                  // handleNodeClick(null,par1,null)
                     getTreeLeft()
                   }
               })
@@ -1525,7 +1525,7 @@ async function edSer() {
             var par1  = {
               data:{id:parMdid.value}
             }
-            handleNodeClick(null,par1,null)
+            // handleNodeClick(null,par1,null)
           }
         }
         
@@ -1637,7 +1637,7 @@ async function addSer() {
                 var par1  = {
                   data:{id:parMdid.value}
                 }
-                handleNodeClick(null,par1,null)
+                // handleNodeClick(null,par1,null)
                 getTreeLeft()
               }
             })
@@ -1653,7 +1653,7 @@ async function addSer() {
           var par1  = {
             data:{id:parMdid.value}
           }
-          handleNodeClick(null,par1,null)
+          // handleNodeClick(null,par1,null)
         }
       }
     })

+ 4 - 2
ruoyi-ui/src/views/service/info/shenhe.vue

@@ -163,7 +163,7 @@
         <el-button @click="showShen"  type="primary" plain  size="mini" style="float: right;margin-right: 1%;margin-top: 1%;">审核该模型</el-button>
         <el-table 
           :data="tableData" 
-          style="width: 98%;margin-left: 1%;margin-top: 4%;"
+          style="width: 98%;margin-left: 1%;margin-top: 4%;height: 55vh;"
           :cell-style="{ padding:'5px' }"
           :header-cell-style="{height: heightAll*0.01+'px',}"
           :row-style="{ fontSize: '16px',textAlign:'center'}"
@@ -906,9 +906,11 @@ async function handleNodeClick(node,data,event){
 }
 async function getTreeLeft(){
   var par = {
+
     params:{
       level:'2',
-      devkind:'APP'
+      devkind:'APP',
+      mdAudit:'0'
     }
   }
   await modelTreeSelect(par).then(res=>{

+ 101 - 0
ruoyi-ui/src/views/shouye.vue

@@ -0,0 +1,101 @@
+<template>
+    <div style="height: 100vh;background-color: #dcecef;">
+        <img style="position: absolute;left: 2%;top: 3%;width: 58%;z-index: 100;height: 6%;"  src="@/assets/上海水务首页图片包/项目标题.png" alt="">
+    <el-carousel 
+    :interval="4000" 
+    height="auto"
+    arrow="always"
+    autoplay
+    >
+        <el-carousel-item style="height: 80vh">
+            <img style="height: 100%;width: 100%;"  src="@/assets/上海水务首页图片包/上海城区洪涝仿真模型.png" alt="">
+        </el-carousel-item>
+        <el-carousel-item style="height: 80vh">
+            <img style="height: 100%;width: 100%;"  src="@/assets/上海水务首页图片包/风暴潮模型.png" alt="">
+        </el-carousel-item>
+        <el-carousel-item style="height: 80vh">
+            <img style="height: 100%;width: 100%;"  src="@/assets/上海水务首页图片包/黄浦江水系水文分析预报数值模拟模型.png" alt="">
+        </el-carousel-item>
+        <el-carousel-item style="height: 80vh">
+            <img style="height: 100%;width: 100%;"  src="@/assets/上海水务首页图片包/上海城区洪涝仿真模型.png" alt="">
+        </el-carousel-item>
+        <el-carousel-item style="height: 80vh">
+            <img style="height: 100%;width: 100%;"  src="@/assets/上海水务首页图片包/苏州河水系水情预报模型.png" alt="">
+        </el-carousel-item>
+        <el-carousel-item style="height: 80vh">
+            <img style="height: 100%;width: 100%;"  src="@/assets/上海水务首页图片包/上海市中心城区排水系统模型.png" alt="">
+        </el-carousel-item>
+        <el-carousel-item style="height: 80vh">
+            <img style="height: 100%;width: 100%;"  src="@/assets/上海水务首页图片包/温带风暴潮预报模型.png" alt="">
+        </el-carousel-item>
+    </el-carousel>
+    </div>
+    <div style="position: absolute;height: 30vh;z-index: 100;top: 70%;width: 100%;">
+        <div style="display: flex;width: 98%;margin-left: 1%;"> 
+            <div style="width: 25vw;height: 29vh;margin-left: 1%;cursor: pointer;" class="back1" @click="pushto('platform/componentReg')">
+                <div style="width: 100%;color: #dcecef;text-align: center;font-size: 1.5rem;margin-top:5%;">模型注册管理</div>
+                <img style="height: 80%;width: 80%;margin-left: 10%;margin-top: 2%;"  src="@/assets/上海水务首页图片包/模型注册.png" alt="">
+            </div>
+            <div style="width: 25vw;height: 29vh;margin-left: 1%;cursor: pointer;" class="back2" @click="pushto('register/edtiModel')">
+                <div style="width: 100%;color: #dcecef;text-align: center;font-size: 1.5rem;margin-top:5%;">模型服务管理</div>
+                <img style="height: 80%;width: 80%;margin-left: 10%;margin-top: 2%;"  src="@/assets/上海水务首页图片包/模型服务管理.png" alt="">
+            </div>
+            <div style="width: 25vw;height: 29vh;margin-left: 1%;cursor: pointer;" class="back1" @click="pushto('standardization/modelUsing')">
+                <div style="width: 100%;color: #dcecef;text-align: center;font-size: 1.5rem;margin-top:5%;">模型标准化开发</div>
+                <img style="height: 80%;width: 80%;margin-left: 10%;margin-top: 2%;"  src="@/assets/上海水务首页图片包/模型标准化.png" alt="">
+            </div>
+            <div style="width: 25vw;height: 29vh;margin-left: 1%;cursor: pointer;" class="back2" @click="pushto('datamonitor/model_operation_monitoring')">
+                <div style="width: 100%;color: #dcecef;text-align: center;font-size: 1.5rem;margin-top:5%;">模型监控管理</div>
+                <img style="height: 80%;width: 80%;margin-left: 10%;margin-top: 2%;"  src="@/assets/上海水务首页图片包/模型监控.png" alt="">
+            </div>
+            <div style="width: 25vw;height: 29vh;margin-left: 1%;cursor: pointer;" class="back1" @click="pushto('evaluate/score')">
+                <div style="width: 100%;color: #dcecef;text-align: center;font-size: 1.5rem;margin-top:5%;">模型评价管理</div>
+                <img style="height: 80%;width: 80%;margin-left: 10%;margin-top: 2%;"  src="@/assets/上海水务首页图片包/模型评价.png" alt="">
+            </div>
+            
+        </div>
+    </div>
+</template>
+<script setup>
+import { useRouter } from 'vue-router'
+
+const router = useRouter()
+const carouseData = [
+  { 
+    id: 1, 
+    url: new URL('@/assets/上海水务首页图片包/风暴潮.png', import.meta.url).href 
+  },
+  { 
+    id: 2, 
+    url: new URL('@/assets/上海水务首页图片包/风暴潮.png', import.meta.url).href 
+  },
+  { 
+    id: 3, 
+    url: new URL('@/assets/上海水务首页图片包/风暴潮.png', import.meta.url).href 
+  },
+]
+function pushto(routers){
+    router.push(routers);
+}
+
+</script>
+<style scoped>
+.back1{
+    background-image:url('@/assets/上海水务首页图片包/浅蓝.png');
+    background-repeat: no-repeat;
+    background-position: center center;
+}
+.back1:hover {
+  transform: translateY(-20px);
+  box-shadow: 0 8px 15px rgba(0, 0, 0, 0.2);
+}
+.back2{
+    background-image:url('@/assets/上海水务首页图片包/深蓝.png');
+    background-repeat: no-repeat;
+    background-position: center center;
+}
+.back2:hover {
+  transform: translateY(-20px);
+  box-shadow: 0 8px 15px rgba(0, 0, 0, 0.2);
+}
+</style>

+ 5 - 2
ruoyi-ui/src/views/standardization/modelUsing/index.vue

@@ -30,6 +30,9 @@
         <div style="display: flex;width: 100%;">
           <div style="margin-left: 8%;margin-top: 5%;width: 60%;">
             {{ item.appTitle }}
+            <div style="margin-top: 10%;font-size: 14px;">
+                模型描述:{{ item.appNote }}
+            </div>
           </div>
           <!-- <img style="width: 90px;height: 90px;margin-left: 0%;margin-top: 8%;border-radius: 12px;" :src="item.appIcon" v-if="item.appIcon!==null"
                alt="">
@@ -38,6 +41,7 @@
                <img style="width: 90px;height: 90px;margin-left: 0%;margin-top: 8%;border-radius: 12px;"  src="@/assets/images/defaultModel.png"
                alt="">
         </div>
+        
         <div>
           <el-tag style="margin-left: 8%;margin-top: -1%;">应用</el-tag>
         </div>
@@ -191,6 +195,7 @@ const resetHoverIndex = () => {
 
 function goFlow(item) {
   store.commit('setId', item.appId);
+  
   proxy.$router.push({path: '/standardization/modeling'});
 }
 function clearForm(){
@@ -376,14 +381,12 @@ function getList() {
     pageSize: 12,
     pageNum: pageNum.value,
   }
-  const parUrl = import.meta.env.VITE_APP_BASE_API 
   getModellist(par).then(res => {
     modelList.value = res.rows
     total.value = res.total
     modelList.value.forEach(item=>{
       item.appIcon = item.appIcon
     })
-    console.log(parUrl)
   })
 }
 

+ 23 - 6
ruoyi-ui/src/views/standardization/modeling/index.vue

@@ -3,6 +3,7 @@
     <!-- <el-button type="primary" @click="saveFlow">测试</el-button> -->
     <div style="display: flex;margin-left: 1%;padding-top: 0.5%;position: absolute;z-index: 1000;justify-content: space-between;width: 98%;align-items: center;"> 
       <el-icon size="large" style="cursor: pointer" @click="back"><Back /></el-icon>
+      <div style="margin-left:1% ;">{{flowName}}</div>
       <el-button @click="delWholeFlow" style="margin-left: auto;" type="danger" size="mini">删除</el-button>
       <!-- <el-button style="margin-left: 1%;" type="info" size="mini" plain @click="toImage">导出为图片</el-button> -->
       <el-button style="margin-left: 1%;" type="primary" size="mini" @click="saveFlow">保存</el-button>
@@ -250,9 +251,9 @@
           <el-checkbox-button key="service" label="service">
             服务
           </el-checkbox-button>
-          <el-checkbox-button key="tool" label="tool">
+          <!-- <el-checkbox-button key="tool" label="tool">
             工具
-          </el-checkbox-button>
+          </el-checkbox-button> -->
       </el-checkbox-group>
         <el-input
           v-if="checkboxGroup1.includes('service')"
@@ -703,7 +704,7 @@ import {useVueFlow, VueFlow ,MarkerType } from '@vue-flow/core'
 import SpecialNode from './components/SpecialNode.vue'
 import SpecialEdge from './components/SpecialEdge.vue'
 import {getPtServiceList,getSerDe} from "@/api/service/info.js";
-import { createWebSocket } from '@/utils/websocket'
+import { getWebSocketUrl } from '@/utils/websocket'
 import { getToken } from '@/utils/auth'
 import {getModelList2} from "@/api/register/regCom.js";
 import {copyObject} from "@/utils/index.js";
@@ -711,6 +712,7 @@ import {getModelingDe,addModelingFlow,editModelingFlow,delFlow,runflow} from "@/
 import { useStore } from 'vuex';
 import {Handle, Position} from '@vue-flow/core'
 import { computed } from 'vue';
+import {getModellist} from '@/api/standardization/modeling'
 import { modelTreeSelect,testService } from "@/api/service/info";
 // import { toRaw, isReactive, isProxy } from 'vue';
 const {
@@ -1191,11 +1193,14 @@ async function startTest(){
   messages.value = []
   const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
   const host = window.location.host;
-  ws.value = createWebSocket('/websocket/message')
+  console.log('ws://' + host + '/websocket/websocket/message')
+  ws.value = getWebSocketUrl('/websocket/message')
+  // ws.value = new WebSocket('wss://10.91.9.204:18082/websocket/websocket/message')
+  // ws.value = new WebSocket('wss://' + host + '/websocket/websocket/message')
+  
   ws.value.onopen = () => {
     connected.value = true;
   };
-  
   ws.value.onmessage = (event) => {
     messages.value.push(event.data); // 存储接收到的消息
   };
@@ -1715,7 +1720,18 @@ const disconnect = () => {
     ws.value = null;
   }
 };
-
+const flowName = ref()
+function getName() {
+  const count = computed(() => store.getters.id)
+  getModellist().then(res => {
+    res.rows.forEach(item=>{
+      console.log(item.appId,count)
+      if(item.appId === count.value){
+        flowName.value = item.appTitle
+      }
+    })
+  })
+}
 // 组件卸载时自动断开连接
 onUnmounted(() => {
   disconnect();
@@ -1724,6 +1740,7 @@ onMounted(() => {
   // connect()
   getTreeLeft()
   getList();
+  getName()
 })
 watch(messages, (newMessages) => {
   newMessages.forEach(item=>{

+ 6 - 6
ruoyi-ui/vite.config.js

@@ -40,12 +40,12 @@ export default defineConfig(({mode, command}) => {
                 //     changeOrigin: true,
                 //     rewrite: (p) => p.replace(/^\/profile\/upload/, '/profile/upload')
                 // },
-                // https://cn.vitejs.dev/config/#server-proxy
-                 '/websocket': {
-                    target: env.VITE_DEV_PATH, // 你的后端 WebSocket 服务器地址
-                    changeOrigin: true, // 修改请求头中的 Origin
-                    ws: true,           // 启用 WebSocket 代理支持 [1,2,9,10,11](@ref)
-                    // rewrite: (path) => path.replace(/^\/websocket/, '') // 可选:重写路径 [1,2,9](@ref)
+                // https://cn.vitejs.dev/config/#server-proxy   
+                '/websocket': {  // 这是你在前端代码中请求的路径标识
+                    target: 'ws://你的后端服务器IP:端口号', // 你后端WebSocket服务的实际地址
+                    changeOrigin: true,
+                    ws: true, // 关键:启用WebSocket代理
+                    rewrite: (path) => path.replace(/^\/websocket/, '') // 可选的路径重写
                 },
                 '/sh-api': {
                     target: env.VITE_DEV_PATH,