Browse Source

ue场景接入

hm 5 days ago
parent
commit
b4bce94738

+ 2 - 1
.env.development

@@ -8,7 +8,8 @@ VITE_APP_ENV = 'development'
 VITE_API_BASE_URL = ''
 
 #请求地址
-VITE_SERVICE_API_URL = 'http://10.1.162.189:3000'
+# VITE_SERVICE_API_URL = 'http://10.1.162.189:3000'
+VITE_SERVICE_API_URL = 'http://10.1.162.193:3000'
 
 
 

+ 2 - 1
.env.production

@@ -11,4 +11,5 @@ VITE_API_BASE_URL = ''
 VITE_BUILD_COMPRESS = gzip
 
 #请求地址
-VITE_SERVICE_API_URL = 'http://10.1.162.189:3000'
+# VITE_SERVICE_API_URL = 'http://10.1.162.189:3000'
+VITE_SERVICE_API_URL = 'http://10.1.162.193:3000'

+ 4 - 4
package-lock.json

@@ -14,7 +14,7 @@
         "@antv/x6-vue-shape": "^2.1.2",
         "@chenfengyuan/vue-carousel": "^2.0.0",
         "@jiaminghi/data-view": "^2.10.0",
-        "axios": "^1.7.9",
+        "axios": "^1.8.4",
         "dagre": "^0.8.5",
         "echarts": "^5.6.0",
         "echarts-gl": "^2.0.9",
@@ -2588,9 +2588,9 @@
       "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
     },
     "node_modules/axios": {
-      "version": "1.8.1",
-      "resolved": "https://registry.npmmirror.com/axios/-/axios-1.8.1.tgz",
-      "integrity": "sha512-NN+fvwH/kV01dYUQ3PTOZns4LWtWhOFCAhQ/pHb88WQ1hNe5V/dvFwc4VJcDL11LT9xSX0QtsR8sWUuyOuOq7g==",
+      "version": "1.8.4",
+      "resolved": "https://registry.npmmirror.com/axios/-/axios-1.8.4.tgz",
+      "integrity": "sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==",
       "dependencies": {
         "follow-redirects": "^1.15.6",
         "form-data": "^4.0.0",

+ 1 - 1
package.json

@@ -15,7 +15,7 @@
     "@antv/x6-vue-shape": "^2.1.2",
     "@chenfengyuan/vue-carousel": "^2.0.0",
     "@jiaminghi/data-view": "^2.10.0",
-    "axios": "^1.7.9",
+    "axios": "^1.8.4",
     "dagre": "^0.8.5",
     "echarts": "^5.6.0",
     "echarts-gl": "^2.0.9",

+ 2 - 1
public/peer-stream.js

@@ -212,7 +212,8 @@ class PeerStream extends HTMLVideoElement {
     this.token = this.dataset.token;
     const wsUrl =
       // 'ws:58.34.215.19:3000' +
-      'ws:10.1.162.189:3000' +
+      // 'ws:10.1.162.189:3000' +
+      'ws:10.1.162.193:3000' +
       `?sceneId=${this.sceneId}&token=${this.token}&&view_mode=${this.viewMode}`;
     this.ws = new WebSocket(wsUrl, 'peer-stream');
     this.ws.onerror;

BIN
src/assets/img/1743406628284.jpg


BIN
src/assets/img/1743407666346.jpg


BIN
src/assets/img/Snipaste_2025-03-31_15-55-37.png


BIN
src/assets/img/Snipaste_2025-03-31_15-56-44.png


BIN
src/assets/img/left_bg.png


BIN
src/assets/img/right_bg.png


BIN
src/assets/img/底部样式 (4).png


+ 57 - 33
src/components/UeMap.vue

@@ -1,16 +1,17 @@
 <template>
-  <div class="ue-option" :ref="(val) => getVideoRef(val)"></div>
+  <div class="ue-option" :ref="val => getVideoRef(val)"></div>
 </template>
 
-<script  setup>
-import { onMounted, ref } from 'vue';
-import { useStateManageStore } from '@/store/stateManage';
+<script setup>
+import { onMounted, ref } from 'vue'
+import { useStateManageStore } from '@/store/stateManage'
+import { getAuth } from '../utils/ueMap.js'
 
-const stateManage = useStateManageStore();
+const stateManage = useStateManageStore()
 
-const getVideoRef = (val) => {
-  stateManage.setVideoContainerRef(val);
-};
+const getVideoRef = val => {
+  stateManage.setVideoContainerRef(val)
+}
 
 // const handleViewScene = (sceneId: any) => {
 //   stateManage.wsConnect(videoContainerRef, sceneId, 'VIEWONLY', localStorage.getItem('token'));
@@ -19,60 +20,83 @@ const getVideoRef = (val) => {
 function getData(url = '', token = '') {
   return new Promise((resolve, reject) => {
     // 创建 XMLHttpRequest 对象
-    const xhr = new XMLHttpRequest();
+    const xhr = new XMLHttpRequest()
 
     // 配置 GET 请求
-    xhr.open('GET', url, true);
+    xhr.open('GET', url, true)
 
     // 如果提供了 token,设置 Authorization 头
     if (token) {
-      xhr.setRequestHeader('Authorization', `Bearer ${token}`);
+      xhr.setRequestHeader('Authorization', `Bearer ${token}`)
     }
 
     // 设置响应处理
     xhr.onload = () => {
       if (xhr.status >= 200 && xhr.status < 300) {
-        resolve(JSON.parse(xhr.responseText)); // 请求成功,解析 JSON 响应
+        resolve(JSON.parse(xhr.responseText)) // 请求成功,解析 JSON 响应
       } else {
-        reject(`Error: ${xhr.status}`); // 请求失败
+        reject(`Error: ${xhr.status}`) // 请求失败
       }
-    };
+    }
 
     // 设置错误处理
-    xhr.onerror = () => reject('Request failed');
+    xhr.onerror = () => reject('Request failed')
 
     // 发送 GET 请求
-    xhr.send();
-  });
+    xhr.send()
+  })
 }
 
-onMounted(() => {
-  const script = document.createElement('script');
+async function getUEAuth() {
+  try {
+    await getAuth({ username: 'JKTest', password: '123456' }).then(res => {
+      localStorage.setItem('token', res.access_token)
+      init()
+    })
+  } catch (error) {
+    console.error('获取 UE token 失败', error)
+  }
+}
+
+function init() {
+  const script = document.createElement('script')
   // script.src = '/pixel-streaming-client/peer-stream.js'; // 自定义元素文件的路径
-  console.log(import.meta.env);
-  script.src = import.meta.env.VITE_API_BASE_URL + '/peer-stream.js'; // 自定义元素文件的路径
-  script.async = true;
+  console.log(import.meta.env)
+  script.src = './peer-stream.js' // 自定义元素文件的路径
+  script.async = true
   script.onload = () => {
-    console.log('PeerStream custom element script loaded');
-  };
-  document.body.appendChild(script);
-  let token =localStorage.getItem('token')
-  console.log(token,'getItemToken')
+    console.log('PeerStream custom element script loaded')
+  }
+  document.body.appendChild(script)
+  let token = localStorage.getItem('token')
+  console.log(token, 'getItemToken')
   const fetchData = async () => {
     try {
-      const sceneList = await getData(import.meta.env.VITE_SERVICE_API_URL + '/scenePermission', localStorage.getItem('token'));
-      stateManage.fSceneList = sceneList[0]; // 设置场景列表数据到状态
+      const sceneList = await getData(import.meta.env.VITE_SERVICE_API_URL + '/scenePermission', localStorage.getItem('token'))
+
+      console.log(sceneList, 'sceneList')
+      stateManage.fSceneList = sceneList[0] // 设置场景列表数据到状态
+      console.log(stateManage.fSceneList, 'stateManage.fSceneList')
+      stateManage.handleOperateScene()
+     
     } catch (error) {
-      alert(error);
+      alert(error)
     }
-  };
-  fetchData();
-});
+  }
+  fetchData()
+}
+
+onMounted(() => {
+  getUEAuth()
+})
 </script>
 
 <style lang="scss" scoped>
 .ue-option {
   position: absolute;
+  top:0px;
+  left: 0px;
+  // z-index: 9992;
   // flex: 1;
   // height: 100%;
   // width: 100%;

+ 47 - 47
src/store/stateManage.js

@@ -75,41 +75,41 @@ export const useStateManageStore = defineStore('stateManage', () => {
       peerStreamRef.value.dataset.sceneId = sceneId;
       peerStreamRef.value.dataset.viewMode = view_mode;
       peerStreamRef.value.dataset.token = token ;
-      // peerStreamRef.value.style.width = '100%';
+      peerStreamRef.value.style.width = '100%';
       peerStreamRef.value.style.height = '100%';
       videoContainerRef.value.appendChild(peerStreamRef.value );
       //场景关闭按钮
 
       // 添加关闭场景按钮
-      const closeButton = document.createElement('button');
-      closeButton.innerText = '关闭场景';
-      closeButton.style.position = 'absolute';
-      closeButton.style.top = '10px';
-      closeButton.style.right = '10px';
-      closeButton.style.zIndex = '10';
-      closeButton.style.border = '1px solid gray';
-      closeButton.addEventListener('click', closeScene);
+      // const closeButton = document.createElement('button');
+      // closeButton.innerText = '关闭场景';
+      // closeButton.style.position = 'absolute';
+      // closeButton.style.top = '10px';
+      // closeButton.style.right = '10px';
+      // closeButton.style.zIndex = '10';
+      // closeButton.style.border = '1px solid gray';
+      // closeButton.addEventListener('click', closeScene);
 
       // 将关闭按钮添加到容器中
-      videoContainerRef.value.appendChild(closeButton);
+      // videoContainerRef.value.appendChild(closeButton);
       //场景事件
-      peerStreamRef.value.addEventListener('playing', () => {
-        console.log('连接成功');
-        connectFlag.value = true;
-        connectStatus.value = '连接成功' + `(${new Date().toTimeString().split(' ')[0]})`;
-        const start = document.querySelector('#start');
-        start.innerHTML = `
-          <span>关闭</span>
-        `;
-      });
-      peerStreamRef.value.addEventListener('disConnected', () => {
-        connectStatus.value = '连接断开' + `(${new Date().toTimeString().split(' ')[0]})`;
-        connectFlag.value = false;
-        const start = document.querySelector('#start');
-        start.innerHTML = `
-          <span>开始</span>
-        `;
-      });
+      // peerStreamRef.value.addEventListener('playing', () => {
+      //   console.log('连接成功');
+      //   connectFlag.value = true;
+      //   connectStatus.value = '连接成功' + `(${new Date().toTimeString().split(' ')[0]})`;
+      //   const start = document.querySelector('#start');
+      //   start.innerHTML = `
+      //     <span>关闭</span>
+      //   `;
+      // });
+      // peerStreamRef.value.addEventListener('disConnected', () => {
+      //   connectStatus.value = '连接断开' + `(${new Date().toTimeString().split(' ')[0]})`;
+      //   connectFlag.value = false;
+      //   const start = document.querySelector('#start');
+      //   start.innerHTML = `
+      //     <span>开始</span>
+      //   `;
+      // });
       peerStreamRef.value.addEventListener('message', (e) => {
         console.log(1111111);
         console.log(e);
@@ -118,26 +118,26 @@ export const useStateManageStore = defineStore('stateManage', () => {
         connectStatus.value = message + `(${new Date().toTimeString().split(' ')[0]})`;
       });
       //场景状态页面
-      const sceneMessageGetDiv = document.createElement('div');
-      sceneMessageGetDiv.style.position = 'absolute';
-      sceneMessageGetDiv.style.bottom = '0px';
-      sceneMessageGetDiv.style.right = '0px';
-      sceneMessageGetDiv.style.zIndex = '10';
-      sceneMessageGetDiv.style.width = '25%';
-      sceneMessageGetDiv.style.height = '30%';
-      sceneMessageGetDiv.style.backgroundColor = 'black';
-      sceneMessageGetDiv.style.borderRadius = '.5rem';
-      sceneMessageGetDiv.style.padding = '.5rem';
-      sceneMessageGetDiv.style.color = 'white';
-      sceneMessageGetDiv.style.border = '1px solid gray';
-      videoContainerRef.value.appendChild(sceneMessageGetDiv);
-      sceneMessageGetDiv.innerHTML = '场景状态';
-      (peerStreamRef.value).onplaying = () => {
-        setInterval(async () => {
-          const res = await getStats(peerStreamRef.value);
-          if (res) sceneMessageGetDiv.innerHTML = res?.replace(/\n/g, '<br />');
-        }, 1000); // Call your getStats function when the video starts playing
-      };
+      // const sceneMessageGetDiv = document.createElement('div');
+      // sceneMessageGetDiv.style.position = 'absolute';
+      // sceneMessageGetDiv.style.bottom = '0px';
+      // sceneMessageGetDiv.style.right = '0px';
+      // sceneMessageGetDiv.style.zIndex = '10';
+      // sceneMessageGetDiv.style.width = '25%';
+      // sceneMessageGetDiv.style.height = '30%';
+      // sceneMessageGetDiv.style.backgroundColor = 'black';
+      // sceneMessageGetDiv.style.borderRadius = '.5rem';
+      // sceneMessageGetDiv.style.padding = '.5rem';
+      // sceneMessageGetDiv.style.color = 'white';
+      // sceneMessageGetDiv.style.border = '1px solid gray';
+      // videoContainerRef.value.appendChild(sceneMessageGetDiv);
+      // sceneMessageGetDiv.innerHTML = '场景状态';
+      // (peerStreamRef.value).onplaying = () => {
+      //   setInterval(async () => {
+      //     const res = await getStats(peerStreamRef.value);
+      //     if (res) sceneMessageGetDiv.innerHTML = res?.replace(/\n/g, '<br />');
+      //   }, 1000); // Call your getStats function when the video starts playing
+      // };
     }
   };
 

+ 443 - 0
src/utils/request copy.js

@@ -0,0 +1,443 @@
+import axios from 'axios'
+import { ElNotification, ElMessageBox, ElMessage, ElLoading } from 'element-plus'
+// import { getToken } from '@/utils/auth'
+// import errorCode from '@/utils/errorCode'
+// import { tansParams, blobValidate } from '@/utils/ruoyi'
+// import cache from '@/plugins/cache'
+// import { saveAs } from 'file-saver'
+// import useUserStore from '@/store/modules/user'
+console.log(axios,'axios')
+
+import router from '../router/index'
+
+// let downloadLoadingInstance
+// // 是否显示重新登录
+// export let isRelogin = { show: false }
+
+console.log(import.meta.env.VITE_SERVICE_API_URL,'baseURL')
+axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
+// 创建axios实例
+const service = axios.create({
+  // axios中请求配置有baseURL选项,表示请求URL公共部分
+  baseURL: import.meta.env.VITE_SERVICE_API_URL,
+  // 超时
+  timeout: 50000
+})
+
+// // request拦截器
+service.interceptors.request.use(
+  config => {
+    // 是否需要设置 token
+    const isToken = (config.headers || {}).isToken === false
+    // 是否需要防止数据重复提交
+    const isRepeatSubmit = (config.headers || {}).repeatSubmit === false
+    if (getToken() && !isToken) {
+      config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
+    }
+    // get请求映射params参数
+    if (config.method === 'get' && config.params) {
+      let url = config.url + '?' + tansParams(config.params)
+      url = url.slice(0, -1)
+      config.params = {}
+      config.url = url
+    }
+    if (!isRepeatSubmit && (config.method === 'post' || config.method === 'put')) {
+      const requestObj = {
+        url: config.url,
+        data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data,
+        time: new Date().getTime()
+      }
+      const requestSize = Object.keys(JSON.stringify(requestObj)).length // 请求数据大小
+      const limitSize = 5 * 1024 * 1024 // 限制存放数据5M
+      if (requestSize >= limitSize) {
+        console.warn(`[${config.url}]: ` + '请求数据大小超出允许的5M限制,无法进行防重复提交验证。')
+        return config
+      }
+      const sessionObj = cache.session.getJSON('sessionObj')
+      if (sessionObj === undefined || sessionObj === null || sessionObj === '') {
+        cache.session.setJSON('sessionObj', requestObj)
+      } else {
+        const s_url = sessionObj.url // 请求地址
+        const s_data = sessionObj.data // 请求数据
+        const s_time = sessionObj.time // 请求时间
+        const interval = 1000 // 间隔时间(ms),小于此时间视为重复提交
+        if (s_data === requestObj.data && requestObj.time - s_time < interval && s_url === requestObj.url) {
+          const message = '数据正在处理,请勿重复提交'
+          console.warn(`[${s_url}]: ` + message)
+          return Promise.reject(new Error(message))
+        } else {
+          cache.session.setJSON('sessionObj', requestObj)
+        }
+      }
+    }
+    return config
+  },
+  error => {
+    console.log(error)
+    Promise.reject(error)
+  }
+)
+
+// // 响应拦截器
+service.interceptors.response.use(
+  res => {
+    // 未设置状态码则默认成功状态
+    const code = res.data.code || 200
+    // 获取错误信息
+    const msg = errorCode[code] || res.data.msg || errorCode['default']
+    if (+code == 599) {
+      ElMessage({ message: msg, type: 'error' })
+      sessionStorage.setItem('message', JSON.stringify(msg))
+      return router.push('/599')
+    }
+
+    // 二进制数据则直接返回
+    if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') {
+      return res.data
+    }
+    if (code === 401) {
+      if (!isRelogin.show) {
+        isRelogin.show = true
+        ElMessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', { confirmButtonText: '重新登录', cancelButtonText: '取消', type: 'warning' })
+          .then(() => {
+            isRelogin.show = false
+            useUserStore()
+              .logOut()
+              .then(() => {
+                location.href = '/catalog/index'
+              })
+          })
+          .catch(() => {
+            isRelogin.show = false
+          })
+      }
+      return Promise.reject('无效的会话,或者会话已过期,请重新登录。')
+    } else if (code === 500) {
+      ElMessage({ message: msg, type: 'error' })
+      return Promise.reject(new Error(msg))
+    } else if (code === 601) {
+      ElMessage({ message: msg, type: 'warning' })
+      return Promise.reject(new Error(msg))
+    } else if (code !== 200) {
+      ElNotification.error({ title: msg })
+      return Promise.reject('error')
+    } else {
+      return Promise.resolve(res.data)
+    }
+  },
+  error => {
+    console.log('err' + error)
+    let { message } = error
+    if (message == 'Network Error') {
+      message = '后端接口连接异常'
+    } else if (message.includes('timeout')) {
+      message = '系统接口请求超时'
+    } else if (message.includes('Request failed with status code')) {
+      message = '系统接口' + message.substr(message.length - 3) + '异常'
+    }
+    ElMessage({ message: message, type: 'error', duration: 5 * 1000 })
+    return Promise.reject(error)
+  }
+)
+
+// // 通用下载方法
+// export function download(url, params, filename, config, ContentType) {
+//   downloadLoadingInstance = ElLoading.service({ text: '正在下载数据,请稍候', background: 'rgba(0, 0, 0, 0.7)' })
+//   return service
+//     .post(url, params, {
+//       transformRequest: [
+//         params => {
+//           return tansParams(params)
+//         }
+//       ],
+//       headers: { 'Content-Type': ContentType || 'application/x-www-form-urlencoded' },
+//       responseType: 'blob',
+//       ...config
+//     })
+//     .then(async data => {
+//       const isBlob = blobValidate(data)
+//       if (isBlob) {
+//         const blob = new Blob([data])
+//         saveAs(blob, filename)
+//       } else {
+//         const resText = await data.text()
+//         const rspObj = JSON.parse(resText)
+//         const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default']
+//         ElMessage.error(errMsg)
+//       }
+//       downloadLoadingInstance.close()
+//     })
+//     .catch(r => {
+//       console.error(r)
+//       ElMessage.error('下载文件出现错误,请联系管理员!')
+//       downloadLoadingInstance.close()
+//     })
+// }
+
+// export const myRequestInstanceJson = axios.create({
+//   baseURL: import.meta.env.VITE_APP_BASE_API,
+//   method: 'post',
+//   headers: {
+//     Authorization: getToken()
+//   }
+// })
+
+// // request拦截器
+// myRequestInstanceJson.interceptors.request.use(
+//   config => {
+//     // 是否需要设置 token
+//     const isToken = (config.headers || {}).isToken === false
+//     // 是否需要防止数据重复提交
+//     const isRepeatSubmit = (config.headers || {}).repeatSubmit === false
+//     if (getToken() && !isToken) {
+//       config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
+//     }
+//     // get请求映射params参数
+//     if (config.method === 'get' && config.params) {
+//       let url = config.url + '?' + tansParams(config.params)
+//       url = url.slice(0, -1)
+//       config.params = {}
+//       config.url = url
+//     }
+//     if (!isRepeatSubmit && (config.method === 'post' || config.method === 'put')) {
+//       const requestObj = {
+//         url: config.url,
+//         data: config.data,
+//         time: new Date().getTime()
+//       }
+//       const requestSize = Object.keys(JSON.stringify(requestObj)).length // 请求数据大小
+//       const limitSize = 5 * 1024 * 1024 // 限制存放数据5M
+//       if (requestSize >= limitSize) {
+//         console.warn(`[${config.url}]: ` + '请求数据大小超出允许的5M限制,无法进行防重复提交验证。')
+//         return config
+//       }
+//       const sessionObj = cache.session.getJSON('sessionObj')
+//       if (sessionObj === undefined || sessionObj === null || sessionObj === '') {
+//         cache.session.setJSON('sessionObj', requestObj)
+//       } else {
+//         const s_url = sessionObj.url // 请求地址
+//         const s_data = sessionObj.data // 请求数据
+//         const s_time = sessionObj.time // 请求时间
+//         const interval = 1000 // 间隔时间(ms),小于此时间视为重复提交
+//         if (s_data === requestObj.data && requestObj.time - s_time < interval && s_url === requestObj.url) {
+//           const message = '数据正在处理,请勿重复提交'
+//           console.warn(`[${s_url}]: ` + message)
+//           return Promise.reject(new Error(message))
+//         } else {
+//           cache.session.setJSON('sessionObj', requestObj)
+//         }
+//       }
+//     }
+//     return config
+//   },
+//   error => {
+//     console.log(error)
+//     Promise.reject(error)
+//   }
+// )
+
+// // 响应拦截器
+// myRequestInstanceJson.interceptors.response.use(
+//   res => {
+//     // 未设置状态码则默认成功状态
+//     const code = res.data.code || '200'
+//     // 获取错误信息
+//     const msg = errorCode[code] || res.data.msg || errorCode['default']
+
+//     if (+code == 599) {
+//       ElMessage({ message: msg, type: 'error' })
+//       sessionStorage.setItem('message', JSON.stringify(msg))
+//       return router.push('/599')
+//     }
+//     // 二进制数据则直接返回
+//     if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') {
+//       return res.data
+//     }
+//     if (+code === 401) {
+//       if (!isRelogin.show) {
+//         isRelogin.show = true
+//         ElMessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', { confirmButtonText: '重新登录', cancelButtonText: '取消', type: 'warning' })
+//           .then(() => {
+//             isRelogin.show = false
+//             useUserStore()
+//               .logOut()
+//               .then(() => {
+//                 location.href = '/catalog/index'
+//               })
+//           })
+//           .catch(() => {
+//             isRelogin.show = false
+//           })
+//       }
+//       return Promise.reject('无效的会话,或者会话已过期,请重新登录。')
+//     } else if (+code === 500) {
+//       ElMessage({ message: msg, type: 'error' })
+//       return Promise.reject(new Error(msg))
+//     } else if (+code === 601) {
+//       ElMessage({ message: msg, type: 'warning' })
+//       return Promise.reject(new Error(msg))
+//     } else if (+code !== 200) {
+//       ElNotification.error({ title: msg })
+//       return Promise.reject('error')
+//     } else if (+code === 599) {
+//       ElMessage({ message: msg, type: 'error' })
+//       sessionStorage.setItem('message', JSON.stringify(msg))
+//       return router.push('/599')
+//     } else {
+//       return Promise.resolve(res.data)
+//     }
+//   },
+//   error => {
+//     console.log('err' + error)
+//     let { message } = error
+//     if (message == 'Network Error') {
+//       message = '后端接口连接异常'
+//     } else if (message.includes('timeout')) {
+//       message = '系统接口请求超时'
+//     } else if (message.includes('Request failed with status code')) {
+//       message = '系统接口' + message.substr(message.length - 3) + '异常'
+//     }
+//     ElMessage({ message: message, type: 'error', duration: 5 * 1000 })
+//     return Promise.reject(error)
+//   }
+// )
+
+// export const myRequestInstance = axios.create({
+//   baseURL: import.meta.env.VITE_APP_BASE_API,
+//   method: 'post',
+//   headers: {
+//     Authorization: getToken(),
+//     'Content-Type': 'application/x-www-form-urlencoded'
+//   },
+//   transformRequest: [
+//     data => {
+//       if (data) {
+//         let params = new FormData()
+//         let keys = Object.keys(data)
+//         keys.forEach(key => {
+//           params.append(key, data[key])
+//         })
+//         return params
+//       }
+//       return data
+//     }
+//   ]
+// })
+
+// // request拦截器
+// myRequestInstance.interceptors.request.use(
+//   config => {
+//     // 是否需要设置 token
+//     const isToken = (config.headers || {}).isToken === false
+//     // 是否需要防止数据重复提交
+//     const isRepeatSubmit = (config.headers || {}).repeatSubmit === false
+//     if (getToken() && !isToken) {
+//       config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
+//     }
+//     // get请求映射params参数
+//     if (config.method === 'get' && config.params) {
+//       let url = config.url + '?' + tansParams(config.params)
+//       url = url.slice(0, -1)
+//       config.params = {}
+//       config.url = url
+//     }
+//     if (!isRepeatSubmit && (config.method === 'post' || config.method === 'put')) {
+//       const requestObj = {
+//         url: config.url,
+//         data: config.data,
+//         time: new Date().getTime()
+//       }
+//       const requestSize = Object.keys(JSON.stringify(requestObj)).length // 请求数据大小
+//       const limitSize = 5 * 1024 * 1024 // 限制存放数据5M
+//       if (requestSize >= limitSize) {
+//         console.warn(`[${config.url}]: ` + '请求数据大小超出允许的5M限制,无法进行防重复提交验证。')
+//         return config
+//       }
+//       const sessionObj = cache.session.getJSON('sessionObj')
+//       if (sessionObj === undefined || sessionObj === null || sessionObj === '') {
+//         cache.session.setJSON('sessionObj', requestObj)
+//       } else {
+//         const s_url = sessionObj.url // 请求地址
+//         const s_data = sessionObj.data // 请求数据
+//         const s_time = sessionObj.time // 请求时间
+//         const interval = 1000 // 间隔时间(ms),小于此时间视为重复提交
+//         if (s_data === requestObj.data && requestObj.time - s_time < interval && s_url === requestObj.url) {
+//           const message = '数据正在处理,请勿重复提交'
+//           console.warn(`[${s_url}]: ` + message)
+//           return Promise.reject(new Error(message))
+//         } else {
+//           cache.session.setJSON('sessionObj', requestObj)
+//         }
+//       }
+//     }
+//     return config
+//   },
+//   error => {
+//     console.log(error)
+//     Promise.reject(error)
+//   }
+// )
+
+// // 响应拦截器
+// myRequestInstance.interceptors.response.use(
+//   res => {
+//     // 未设置状态码则默认成功状态
+//     const code = res.data.code || '200'
+//     // 获取错误信息
+//     const msg = errorCode[code] || res.data.msg || errorCode['default']
+//     if (+code == 599) {
+//       ElMessage({ message: msg, type: 'error' })
+//       sessionStorage.setItem('message', JSON.stringify(msg))
+//       return router.push('/599')
+//     }
+
+//     // 二进制数据则直接返回
+//     if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') {
+//       return res.data
+//     }
+//     if (+code === 401) {
+//       if (!isRelogin.show) {
+//         isRelogin.show = true
+//         ElMessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', { confirmButtonText: '重新登录', cancelButtonText: '取消', type: 'warning' })
+//           .then(() => {
+//             isRelogin.show = false
+//             useUserStore()
+//               .logOut()
+//               .then(() => {
+//                 location.href = '/catalog/index'
+//               })
+//           })
+//           .catch(() => {
+//             isRelogin.show = false
+//           })
+//       }
+//       return Promise.reject('无效的会话,或者会话已过期,请重新登录。')
+//     } else if (+code === 500) {
+//       ElMessage({ message: msg, type: 'error' })
+//       return Promise.reject(new Error(msg))
+//     } else if (+code === 601) {
+//       ElMessage({ message: msg, type: 'warning' })
+//       return Promise.reject(new Error(msg))
+//     } else if (+code !== 200) {
+//       ElNotification.error({ title: msg })
+//       return Promise.reject('error')
+//     } else {
+//       return Promise.resolve(res.data)
+//     }
+//   },
+//   error => {
+//     console.log('err' + error)
+//     let { message } = error
+//     if (message == 'Network Error') {
+//       message = '后端接口连接异常'
+//     } else if (message.includes('timeout')) {
+//       message = '系统接口请求超时'
+//     } else if (message.includes('Request failed with status code')) {
+//       message = '系统接口' + message.substr(message.length - 3) + '异常'
+//     }
+//     ElMessage({ message: message, type: 'error', duration: 5 * 1000 })
+//     return Promise.reject(error)
+//   }
+// )
+
+export default service

+ 35 - 426
src/utils/request.js

@@ -1,441 +1,50 @@
-import axios from 'axios'
-// import { ElNotification, ElMessageBox, ElMessage, ElLoading } from 'element-plus'
-// import { getToken } from '@/utils/auth'
-// import errorCode from '@/utils/errorCode'
-// import { tansParams, blobValidate } from '@/utils/ruoyi'
-// import cache from '@/plugins/cache'
-// import { saveAs } from 'file-saver'
-// import useUserStore from '@/store/modules/user'
+import axios from 'axios';
+import { ElMessage } from 'element-plus';
 
-import router from '../router/index'
-
-// let downloadLoadingInstance
-// // 是否显示重新登录
-// export let isRelogin = { show: false }
-
-axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
-// 创建axios实例
+// 创建 axios 实例
 const service = axios.create({
-  // axios中请求配置有baseURL选项,表示请求URL公共部分
-  baseURL: import.meta.env.VITE_APP_BASE_API,
-  // 超时
-  timeout: 10000
-})
+  baseURL: import.meta.env.VITE_SERVICE_API_URL, // 基础 API 地址
+  timeout: 1000 // 请求超时时间
+});
 
-// // request拦截器
+// 请求拦截器
 service.interceptors.request.use(
-  config => {
-    // 是否需要设置 token
-    const isToken = (config.headers || {}).isToken === false
-    // 是否需要防止数据重复提交
-    const isRepeatSubmit = (config.headers || {}).repeatSubmit === false
-    if (getToken() && !isToken) {
-      config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
-    }
-    // get请求映射params参数
-    if (config.method === 'get' && config.params) {
-      let url = config.url + '?' + tansParams(config.params)
-      url = url.slice(0, -1)
-      config.params = {}
-      config.url = url
+  (config) => {
+    // 在请求前附加 token
+    const token = localStorage.getItem('token');
+    if (token) {
+      config.headers['Authorization'] = `Bearer ${token}`;
     }
-    if (!isRepeatSubmit && (config.method === 'post' || config.method === 'put')) {
-      const requestObj = {
-        url: config.url,
-        data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data,
-        time: new Date().getTime()
-      }
-      const requestSize = Object.keys(JSON.stringify(requestObj)).length // 请求数据大小
-      const limitSize = 5 * 1024 * 1024 // 限制存放数据5M
-      if (requestSize >= limitSize) {
-        console.warn(`[${config.url}]: ` + '请求数据大小超出允许的5M限制,无法进行防重复提交验证。')
-        return config
-      }
-      const sessionObj = cache.session.getJSON('sessionObj')
-      if (sessionObj === undefined || sessionObj === null || sessionObj === '') {
-        cache.session.setJSON('sessionObj', requestObj)
-      } else {
-        const s_url = sessionObj.url // 请求地址
-        const s_data = sessionObj.data // 请求数据
-        const s_time = sessionObj.time // 请求时间
-        const interval = 1000 // 间隔时间(ms),小于此时间视为重复提交
-        if (s_data === requestObj.data && requestObj.time - s_time < interval && s_url === requestObj.url) {
-          const message = '数据正在处理,请勿重复提交'
-          console.warn(`[${s_url}]: ` + message)
-          return Promise.reject(new Error(message))
-        } else {
-          cache.session.setJSON('sessionObj', requestObj)
-        }
-      }
-    }
-    return config
+    return config;
   },
-  error => {
-    console.log(error)
-    Promise.reject(error)
+  (error) => {
+    console.error('请求错误:', error);
+    return Promise.reject(error);
   }
-)
+);
 
-// // 响应拦截器
+// 响应拦截器
 service.interceptors.response.use(
-  res => {
-    // 未设置状态码则默认成功状态
-    const code = res.data.code || 200
-    // 获取错误信息
-    const msg = errorCode[code] || res.data.msg || errorCode['default']
-    if (+code == 599) {
-      ElMessage({ message: msg, type: 'error' })
-      sessionStorage.setItem('message', JSON.stringify(msg))
-      return router.push('/599')
-    }
-
-    // 二进制数据则直接返回
-    if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') {
-      return res.data
-    }
-    if (code === 401) {
-      if (!isRelogin.show) {
-        isRelogin.show = true
-        ElMessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', { confirmButtonText: '重新登录', cancelButtonText: '取消', type: 'warning' })
-          .then(() => {
-            isRelogin.show = false
-            useUserStore()
-              .logOut()
-              .then(() => {
-                location.href = '/catalog/index'
-              })
-          })
-          .catch(() => {
-            isRelogin.show = false
-          })
-      }
-      return Promise.reject('无效的会话,或者会话已过期,请重新登录。')
-    } else if (code === 500) {
-      ElMessage({ message: msg, type: 'error' })
-      return Promise.reject(new Error(msg))
-    } else if (code === 601) {
-      ElMessage({ message: msg, type: 'warning' })
-      return Promise.reject(new Error(msg))
-    } else if (code !== 200) {
-      ElNotification.error({ title: msg })
-      return Promise.reject('error')
+  (response) => {
+    // 直接返回数据
+    if (response.status === 200 || response.status === 201) {
+      return response.data;
     } else {
-      return Promise.resolve(res.data)
+      ElMessage.error(response.data.message || '请求失败');
+      return Promise.reject(response.data);
     }
   },
-  error => {
-    console.log('err' + error)
-    let { message } = error
-    if (message == 'Network Error') {
-      message = '后端接口连接异常'
-    } else if (message.includes('timeout')) {
-      message = '系统接口请求超时'
-    } else if (message.includes('Request failed with status code')) {
-      message = '系统接口' + message.substr(message.length - 3) + '异常'
+  (error) => {
+    // 处理 HTTP 错误
+    if (error.response && error.response.status === 401) {
+      ElMessage.error('登录已过期,请重新登录');
+      localStorage.removeItem('token');
+      window.location.href = '/login';
+    } else {
+      ElMessage.error(error.response?.data?.message || '请求失败');
     }
-    ElMessage({ message: message, type: 'error', duration: 5 * 1000 })
-    return Promise.reject(error)
+    return Promise.reject(error);
   }
-)
-
-// // 通用下载方法
-// export function download(url, params, filename, config, ContentType) {
-//   downloadLoadingInstance = ElLoading.service({ text: '正在下载数据,请稍候', background: 'rgba(0, 0, 0, 0.7)' })
-//   return service
-//     .post(url, params, {
-//       transformRequest: [
-//         params => {
-//           return tansParams(params)
-//         }
-//       ],
-//       headers: { 'Content-Type': ContentType || 'application/x-www-form-urlencoded' },
-//       responseType: 'blob',
-//       ...config
-//     })
-//     .then(async data => {
-//       const isBlob = blobValidate(data)
-//       if (isBlob) {
-//         const blob = new Blob([data])
-//         saveAs(blob, filename)
-//       } else {
-//         const resText = await data.text()
-//         const rspObj = JSON.parse(resText)
-//         const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default']
-//         ElMessage.error(errMsg)
-//       }
-//       downloadLoadingInstance.close()
-//     })
-//     .catch(r => {
-//       console.error(r)
-//       ElMessage.error('下载文件出现错误,请联系管理员!')
-//       downloadLoadingInstance.close()
-//     })
-// }
-
-// export const myRequestInstanceJson = axios.create({
-//   baseURL: import.meta.env.VITE_APP_BASE_API,
-//   method: 'post',
-//   headers: {
-//     Authorization: getToken()
-//   }
-// })
-
-// // request拦截器
-// myRequestInstanceJson.interceptors.request.use(
-//   config => {
-//     // 是否需要设置 token
-//     const isToken = (config.headers || {}).isToken === false
-//     // 是否需要防止数据重复提交
-//     const isRepeatSubmit = (config.headers || {}).repeatSubmit === false
-//     if (getToken() && !isToken) {
-//       config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
-//     }
-//     // get请求映射params参数
-//     if (config.method === 'get' && config.params) {
-//       let url = config.url + '?' + tansParams(config.params)
-//       url = url.slice(0, -1)
-//       config.params = {}
-//       config.url = url
-//     }
-//     if (!isRepeatSubmit && (config.method === 'post' || config.method === 'put')) {
-//       const requestObj = {
-//         url: config.url,
-//         data: config.data,
-//         time: new Date().getTime()
-//       }
-//       const requestSize = Object.keys(JSON.stringify(requestObj)).length // 请求数据大小
-//       const limitSize = 5 * 1024 * 1024 // 限制存放数据5M
-//       if (requestSize >= limitSize) {
-//         console.warn(`[${config.url}]: ` + '请求数据大小超出允许的5M限制,无法进行防重复提交验证。')
-//         return config
-//       }
-//       const sessionObj = cache.session.getJSON('sessionObj')
-//       if (sessionObj === undefined || sessionObj === null || sessionObj === '') {
-//         cache.session.setJSON('sessionObj', requestObj)
-//       } else {
-//         const s_url = sessionObj.url // 请求地址
-//         const s_data = sessionObj.data // 请求数据
-//         const s_time = sessionObj.time // 请求时间
-//         const interval = 1000 // 间隔时间(ms),小于此时间视为重复提交
-//         if (s_data === requestObj.data && requestObj.time - s_time < interval && s_url === requestObj.url) {
-//           const message = '数据正在处理,请勿重复提交'
-//           console.warn(`[${s_url}]: ` + message)
-//           return Promise.reject(new Error(message))
-//         } else {
-//           cache.session.setJSON('sessionObj', requestObj)
-//         }
-//       }
-//     }
-//     return config
-//   },
-//   error => {
-//     console.log(error)
-//     Promise.reject(error)
-//   }
-// )
-
-// // 响应拦截器
-// myRequestInstanceJson.interceptors.response.use(
-//   res => {
-//     // 未设置状态码则默认成功状态
-//     const code = res.data.code || '200'
-//     // 获取错误信息
-//     const msg = errorCode[code] || res.data.msg || errorCode['default']
-
-//     if (+code == 599) {
-//       ElMessage({ message: msg, type: 'error' })
-//       sessionStorage.setItem('message', JSON.stringify(msg))
-//       return router.push('/599')
-//     }
-//     // 二进制数据则直接返回
-//     if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') {
-//       return res.data
-//     }
-//     if (+code === 401) {
-//       if (!isRelogin.show) {
-//         isRelogin.show = true
-//         ElMessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', { confirmButtonText: '重新登录', cancelButtonText: '取消', type: 'warning' })
-//           .then(() => {
-//             isRelogin.show = false
-//             useUserStore()
-//               .logOut()
-//               .then(() => {
-//                 location.href = '/catalog/index'
-//               })
-//           })
-//           .catch(() => {
-//             isRelogin.show = false
-//           })
-//       }
-//       return Promise.reject('无效的会话,或者会话已过期,请重新登录。')
-//     } else if (+code === 500) {
-//       ElMessage({ message: msg, type: 'error' })
-//       return Promise.reject(new Error(msg))
-//     } else if (+code === 601) {
-//       ElMessage({ message: msg, type: 'warning' })
-//       return Promise.reject(new Error(msg))
-//     } else if (+code !== 200) {
-//       ElNotification.error({ title: msg })
-//       return Promise.reject('error')
-//     } else if (+code === 599) {
-//       ElMessage({ message: msg, type: 'error' })
-//       sessionStorage.setItem('message', JSON.stringify(msg))
-//       return router.push('/599')
-//     } else {
-//       return Promise.resolve(res.data)
-//     }
-//   },
-//   error => {
-//     console.log('err' + error)
-//     let { message } = error
-//     if (message == 'Network Error') {
-//       message = '后端接口连接异常'
-//     } else if (message.includes('timeout')) {
-//       message = '系统接口请求超时'
-//     } else if (message.includes('Request failed with status code')) {
-//       message = '系统接口' + message.substr(message.length - 3) + '异常'
-//     }
-//     ElMessage({ message: message, type: 'error', duration: 5 * 1000 })
-//     return Promise.reject(error)
-//   }
-// )
-
-// export const myRequestInstance = axios.create({
-//   baseURL: import.meta.env.VITE_APP_BASE_API,
-//   method: 'post',
-//   headers: {
-//     Authorization: getToken(),
-//     'Content-Type': 'application/x-www-form-urlencoded'
-//   },
-//   transformRequest: [
-//     data => {
-//       if (data) {
-//         let params = new FormData()
-//         let keys = Object.keys(data)
-//         keys.forEach(key => {
-//           params.append(key, data[key])
-//         })
-//         return params
-//       }
-//       return data
-//     }
-//   ]
-// })
-
-// // request拦截器
-// myRequestInstance.interceptors.request.use(
-//   config => {
-//     // 是否需要设置 token
-//     const isToken = (config.headers || {}).isToken === false
-//     // 是否需要防止数据重复提交
-//     const isRepeatSubmit = (config.headers || {}).repeatSubmit === false
-//     if (getToken() && !isToken) {
-//       config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
-//     }
-//     // get请求映射params参数
-//     if (config.method === 'get' && config.params) {
-//       let url = config.url + '?' + tansParams(config.params)
-//       url = url.slice(0, -1)
-//       config.params = {}
-//       config.url = url
-//     }
-//     if (!isRepeatSubmit && (config.method === 'post' || config.method === 'put')) {
-//       const requestObj = {
-//         url: config.url,
-//         data: config.data,
-//         time: new Date().getTime()
-//       }
-//       const requestSize = Object.keys(JSON.stringify(requestObj)).length // 请求数据大小
-//       const limitSize = 5 * 1024 * 1024 // 限制存放数据5M
-//       if (requestSize >= limitSize) {
-//         console.warn(`[${config.url}]: ` + '请求数据大小超出允许的5M限制,无法进行防重复提交验证。')
-//         return config
-//       }
-//       const sessionObj = cache.session.getJSON('sessionObj')
-//       if (sessionObj === undefined || sessionObj === null || sessionObj === '') {
-//         cache.session.setJSON('sessionObj', requestObj)
-//       } else {
-//         const s_url = sessionObj.url // 请求地址
-//         const s_data = sessionObj.data // 请求数据
-//         const s_time = sessionObj.time // 请求时间
-//         const interval = 1000 // 间隔时间(ms),小于此时间视为重复提交
-//         if (s_data === requestObj.data && requestObj.time - s_time < interval && s_url === requestObj.url) {
-//           const message = '数据正在处理,请勿重复提交'
-//           console.warn(`[${s_url}]: ` + message)
-//           return Promise.reject(new Error(message))
-//         } else {
-//           cache.session.setJSON('sessionObj', requestObj)
-//         }
-//       }
-//     }
-//     return config
-//   },
-//   error => {
-//     console.log(error)
-//     Promise.reject(error)
-//   }
-// )
-
-// // 响应拦截器
-// myRequestInstance.interceptors.response.use(
-//   res => {
-//     // 未设置状态码则默认成功状态
-//     const code = res.data.code || '200'
-//     // 获取错误信息
-//     const msg = errorCode[code] || res.data.msg || errorCode['default']
-//     if (+code == 599) {
-//       ElMessage({ message: msg, type: 'error' })
-//       sessionStorage.setItem('message', JSON.stringify(msg))
-//       return router.push('/599')
-//     }
-
-//     // 二进制数据则直接返回
-//     if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') {
-//       return res.data
-//     }
-//     if (+code === 401) {
-//       if (!isRelogin.show) {
-//         isRelogin.show = true
-//         ElMessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', { confirmButtonText: '重新登录', cancelButtonText: '取消', type: 'warning' })
-//           .then(() => {
-//             isRelogin.show = false
-//             useUserStore()
-//               .logOut()
-//               .then(() => {
-//                 location.href = '/catalog/index'
-//               })
-//           })
-//           .catch(() => {
-//             isRelogin.show = false
-//           })
-//       }
-//       return Promise.reject('无效的会话,或者会话已过期,请重新登录。')
-//     } else if (+code === 500) {
-//       ElMessage({ message: msg, type: 'error' })
-//       return Promise.reject(new Error(msg))
-//     } else if (+code === 601) {
-//       ElMessage({ message: msg, type: 'warning' })
-//       return Promise.reject(new Error(msg))
-//     } else if (+code !== 200) {
-//       ElNotification.error({ title: msg })
-//       return Promise.reject('error')
-//     } else {
-//       return Promise.resolve(res.data)
-//     }
-//   },
-//   error => {
-//     console.log('err' + error)
-//     let { message } = error
-//     if (message == 'Network Error') {
-//       message = '后端接口连接异常'
-//     } else if (message.includes('timeout')) {
-//       message = '系统接口请求超时'
-//     } else if (message.includes('Request failed with status code')) {
-//       message = '系统接口' + message.substr(message.length - 3) + '异常'
-//     }
-//     ElMessage({ message: message, type: 'error', duration: 5 * 1000 })
-//     return Promise.reject(error)
-//   }
-// )
+);
 
-// export default service
+export default service;

+ 11 - 0
src/utils/ueMap.js

@@ -0,0 +1,11 @@
+import request from '@/utils/request'
+
+
+// 获取UE token 
+export function getAuth (data) {
+  return request({
+    url: '/auth/login',
+    method: 'post',
+    data
+  })
+}

+ 70 - 69
src/views/index.vue

@@ -10,8 +10,7 @@
         </div>
         <div class="home_container_header-left_tab">
           <div class="button-container">
-            <div v-for="(item, index) in buttons" :key="index" class="parallelogram-button"
-              :class="{ highlight: commonStore.activeIndex === index }" @click="setActive(index, item)">
+            <div v-for="(item, index) in buttons" :key="index" class="parallelogram-button" :class="{ highlight: commonStore.activeIndex === index }" @click="setActive(index, item)">
               <div class="text-container" :class="{ 'text-container-highlight': activeIndex === index }">
                 {{ item.title }}
               </div>
@@ -37,94 +36,84 @@
       <RightPage :activeIndex="activeIndex"></RightPage>
     </div>
 
+    <div class="bg_left"></div>
+    <div class="bg_right"></div>
+
     <!-- 底部片区图层按钮 -->
     <AreaLayerSwitch></AreaLayerSwitch>
   </div>
 </template>
 <script setup>
-import UeMap from '../components/UeMap.vue';
-import AreaLayerSwitch from "../components/AreaLayerSwitch/index";
-import LeftPage from "./left/index.vue";
-import RightPage from "./right/index.vue";
-import { storeToRefs } from "pinia";
-import { useUserStore } from "../store/user";
-import { useCommonStore } from "../store/common.js";
-import {
-  ref,
-  reactive,
-  toRefs,
-  onBeforeMount,
-  onMounted,
-  onUnmounted,
-  watch,
-} from "vue";
-import axios from 'axios';
-
-const submitForm = async (e) => {
+import UeMap from '../components/UeMap.vue'
+import AreaLayerSwitch from '../components/AreaLayerSwitch/index'
+import LeftPage from './left/index.vue'
+import RightPage from './right/index.vue'
+import { storeToRefs } from 'pinia'
+import { useUserStore } from '../store/user'
+import { useCommonStore } from '../store/common.js'
+import { ref, reactive, toRefs, onBeforeMount, onMounted, onUnmounted, watch } from 'vue'
+import { getAuth } from '../utils/ueMap.js'
+
+
+
+async function getUEAuth() {
   try {
-    const response = await axios.post(import.meta.env.VITE_SERVICE_API_URL + '/auth/login', {
-      // username: ruleForm.username,
-      // password: ruleForm.password
-      username: 'JKTest',
-      password: '123456'
-    });
-      localStorage.setItem('token', response.data.access_token);
-
-    // if (response.status === 201) {
-    //   localStorage.setItem('token', response.data.access_token);
-    //   // router.push('/home');
-    // }
+    await getAuth({ username: 'JKTest', password: '123456' }).then(res => {
+      if (res.code === 201) {
+        console.log(res, 'res99')
+        localStorage.setItem('token', res.access_token)
+      }
+    })
   } catch (error) {
-    alert('登陆失败');
-    console.log(error);
+    console.error('获取 UE token 失败', error)
   }
-};
+}
 
-let userStore = useUserStore();
-let commonStore = useCommonStore();
+let userStore = useUserStore()
+let commonStore = useCommonStore()
 
-console.log(userStore, "useUserStore");
-let { name, age } = storeToRefs(userStore);
-const currentTime = ref("");
+console.log(userStore, 'useUserStore')
+let { name, age } = storeToRefs(userStore)
+const currentTime = ref('')
 // 更新当前时间的函数
 // 更新当前时间的函数
 const updateTime = () => {
-  const now = new Date();
+  const now = new Date()
 
   // 格式化为 2025-02-25 10:39:05
-  const year = now.getFullYear();
-  const month = String(now.getMonth() + 1).padStart(2, "0"); // 月份从 0 开始,需加 1
-  const day = String(now.getDate()).padStart(2, "0");
-  const hours = String(now.getHours()).padStart(2, "0");
-  const minutes = String(now.getMinutes()).padStart(2, "0");
-  const seconds = String(now.getSeconds()).padStart(2, "0");
-
-  currentTime.value = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
-};
+  const year = now.getFullYear()
+  const month = String(now.getMonth() + 1).padStart(2, '0') // 月份从 0 开始,需加 1
+  const day = String(now.getDate()).padStart(2, '0')
+  const hours = String(now.getHours()).padStart(2, '0')
+  const minutes = String(now.getMinutes()).padStart(2, '0')
+  const seconds = String(now.getSeconds()).padStart(2, '0')
+
+  currentTime.value = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
+}
 // 设置定时器每秒更新一次
-let timer;
+let timer
 onMounted(() => {
-  submitForm()
-  updateTime(); // 初始化时更新时间
-  timer = setInterval(updateTime, 1000); // 每秒更新
-  activeIndex.value = commonStore.getActiveIndex();
-});
+  // getUEAuth()
+  updateTime() // 初始化时更新时间
+  timer = setInterval(updateTime, 1000) // 每秒更新
+  activeIndex.value = commonStore.getActiveIndex()
+})
 
 // 清理定时器
 onUnmounted(() => {
-  clearInterval(timer);
-});
+  clearInterval(timer)
+})
 
 let buttons = ref([
-  { id: 0, title: "报告处置", active: true },
-  { id: 1, title: "处置进展", active: false },
-]);
-let activeIndex = ref(0); // 存储当前高亮按钮的索引
+  { id: 0, title: '报告处置', active: true },
+  { id: 1, title: '处置进展', active: false }
+])
+let activeIndex = ref(0) // 存储当前高亮按钮的索引
 
-function setActive (index, item) {
+function setActive(index, item) {
   // 切换高亮按钮,点击时高亮切换
-  activeIndex.value = index;
-  commonStore.setActiveIndex(index);
+  activeIndex.value = index
+  commonStore.setActiveIndex(index)
 }
 </script>
 <style lang="scss" scoped>
@@ -146,6 +135,7 @@ function setActive (index, item) {
   background: url(../assets/img/大标题.png) no-repeat;
   background-size: 100% 100%;
   position: relative;
+  z-index: 999;
 
   .home_container_header-left {
     position: absolute;
@@ -266,7 +256,7 @@ function setActive (index, item) {
       .icon-img {
         width: 40px;
         height: 40px;
-        background-image: url("../assets/img/通讯录@2x.png");
+        background-image: url('../assets/img/通讯录@2x.png');
         background-size: 100% 100%;
       }
 
@@ -293,7 +283,7 @@ function setActive (index, item) {
     .duoyun {
       width: 35px;
       height: 35px;
-      background-image: url("../assets/img/多云.png");
+      background-image: url('../assets/img/多云.png');
       background-size: 100% 100%;
     }
 
@@ -313,6 +303,9 @@ function setActive (index, item) {
   }
 }
 
+
+
+
 // 左侧样式
 .home_content_left {
   position: absolute;
@@ -320,7 +313,15 @@ function setActive (index, item) {
   top: 108px;
   width: 1124px;
   height: 945px;
-  // background-color: pink;
+  
+  // left: 0px;
+  // top: 30px;
+  // height: 1080px;
+  // width: 1250px;
+  // background:rgba(0, 0, 0, 0.2) url(../assets/img/left_bg.png) no-repeat;
+  // background-size: 100% 100%;
+  // background: url(../assets/img/Snipaste_2025-03-31_15-55-37.png)no-repeat;
+  // background-size: 100% 100%;
 }
 
 // 右侧

+ 2 - 0
src/views/left/index.vue

@@ -93,6 +93,8 @@ function changeRiskView() {
 .left_container {
   width: 100%;
   height: 100%;
+  width: 1124px;
+  height: 945px;
 
   .left_container_header-left_tab {
     .button-container {

+ 79 - 0
src/views/left/modules/components/dialog/MapTools copy.vue

@@ -0,0 +1,79 @@
+<template>
+  <div class="tools_container">
+    <div v-for="item in tools" :key="item.name" @click="selectTool(item.name)" :class="{ active: activeTool === item.name }" class="tools_item">
+      <img :src="getToolImg(item.name)" alt="" />
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { ref, onMounted } from 'vue'
+
+// 公共路径
+const basePath = '../../../../../assets/img/'
+
+// 工具配置数据
+const tools = ref([
+  {
+    name: '风险列表',
+    img: '风险列表1.png',
+    activeImg: '风险列表2.png'
+  },
+  {
+    name: '图例',
+    img: '图例1.png',
+    activeImg: '图例2.png'
+  },
+  {
+    name: '色阶图',
+    img: '色阶图1.png',
+    activeImg: '色阶图2.png'
+  }
+])
+
+// 当前激活的工具
+const activeTool = ref('')
+
+// 预处理图片路径
+const imgMap = ref({})
+
+// 选择工具
+const selectTool = name => {
+  activeTool.value = name
+}
+
+// 预加载图片路径
+onMounted(() => {
+  tools.value.forEach(item => {
+    imgMap.value[item.name] = {
+      default: new URL(`${basePath}${item.img}`, import.meta.url).href,
+      active: new URL(`${basePath}${item.activeImg}`, import.meta.url).href
+    }
+  })
+})
+
+// 获取工具图片
+const getToolImg = name => {
+  return activeTool.value === name ? imgMap.value[name]?.active : imgMap.value[name]?.default
+}
+</script>
+
+<style lang="scss" scoped>
+.tools_container {
+  width: 51px;
+  height: 191px;
+  display: flex;
+  flex-direction: column;
+  gap: 20px;
+  align-items: center;
+  justify-content: space-between;
+  position: absolute;
+  top: 70px;
+  right: -61px;
+}
+.tools_item {
+  width: 51px;
+  height: 51px;
+  cursor: pointer;
+}
+</style>

+ 22 - 7
src/views/left/modules/components/dialog/MapTools.vue

@@ -1,6 +1,12 @@
 <template>
   <div class="tools_container">
-    <div v-for="item in tools" :key="item.name" @click="selectTool(item.name)" :class="{ active: activeTool === item.name }" class="tools_item">
+    <div
+      v-for="item in tools"
+      :key="item.name"
+      @click="toggleTool(item.name)"
+      :class="{ active: activeTools.has(item.name) }"
+      class="tools_item"
+    >
       <img :src="getToolImg(item.name)" alt="" />
     </div>
   </div>
@@ -31,15 +37,19 @@ const tools = ref([
   }
 ])
 
-// 当前激活的工具
-const activeTool = ref('')
+// 当前激活的工具,使用 Set 存储多选
+const activeTools = ref(new Set())
 
 // 预处理图片路径
 const imgMap = ref({})
 
-// 选择工具
-const selectTool = name => {
-  activeTool.value = name
+// 切换工具高亮状态
+const toggleTool = name => {
+  if (activeTools.value.has(name)) {
+    activeTools.value.delete(name) // 取消激活
+  } else {
+    activeTools.value.add(name) // 激活
+  }
 }
 
 // 预加载图片路径
@@ -54,7 +64,7 @@ onMounted(() => {
 
 // 获取工具图片
 const getToolImg = name => {
-  return activeTool.value === name ? imgMap.value[name]?.active : imgMap.value[name]?.default
+  return activeTools.value.has(name) ? imgMap.value[name]?.active : imgMap.value[name]?.default
 }
 </script>
 
@@ -75,5 +85,10 @@ const getToolImg = name => {
   width: 51px;
   height: 51px;
   cursor: pointer;
+  transition: transform 0.2s ease-in-out;
+
+  &.active {
+    transform: scale(1.1); // 激活时稍微放大
+  }
 }
 </style>