#
zzgtfwq
12 小时以前 9fd5e6fbcb1d8badf1835478d862ac40bfb60f3c
src/main/webapp/views/deviceOperate/wcsOperate.html
@@ -2,249 +2,141 @@
<html lang="en">
<head>
   <meta charset="utf-8">
   <title>环形穿梭车智能系统</title>
   <title>智能系统</title>
   <link rel="icon" href="../../static/images/favicon.ico" type="image/x-icon">
   <link rel="stylesheet" href="../../static/wcs/css/element.css">
   <link rel="stylesheet" href="../../static/wcs/css/indexHCDD.css">
   <link rel="stylesheet" href="../../static/wcs/css/element-ui.css">
   <script type="text/javascript" src="../../static/js/jquery/jquery-3.3.1.min.js"></script>
   <script type="text/javascript" src="../../static/js/common.js"></script>
   <script type="text/javascript" src="../../static/wcs/js/vue.min.js"></script>
   <script type="text/javascript" src="../../static/wcs/js/element.js"></script>
   <script type="text/javascript" src="../../static/wcs/js/testPosition.js"></script>
   <style>
      body {
         font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
         margin: 0;
         padding: 0;
         background-color: #a0d2eb;
         color: #ffffff;
         display: flex;
         justify-content: center;
         align-items: center;
         height: 100vh;
      }
      header {
         background-color: #2196F3;
         color: white;
         padding: 15px 20px;
         text-align: center;
         font-size: 24px;
         letter-spacing: 1px;
         box-shadow: 0 2px 5px rgba(0, 0, 0, 0.3);
      }
      .map {
         position: relative;
         width: 52vw;
         height: 80vh;
         border-radius: 50%;
         display: flex;
         justify-content: center;
         align-items: center;
      }
      .inner-ring, .outer-ring {
         position: absolute;
         border-radius: 50%;
      }
      .inner-ring {
         width: 72vh;
         height: 72vh;
         border: 4px solid #00E676;
         box-shadow: inset 0 0 30px rgba(0, 230, 118, 0.5), 0 0 20px rgba(0, 230, 118, 0.5);
      }
      .outer-ring {
         width: 80vh;
         height: 80vh;
         border: 4px solid #00E676;
         box-shadow: inset 0 0 30px rgba(0, 230, 118, 0.5), 0 0 20px rgba(0, 230, 118, 0.5);
      }
      .station {
         position: absolute;
         width: 20px;
         height: 14px;
         text-align: center;
         line-height: 1.5; /* 调整行高与字体大小的比值 */
         font-size: 10px; /* 设置更小的字体 */
         font-weight: bold;
         transition: transform 0.3s ease;
         background-color: #ab1839;
         transform: scale(1); /* 可选:如果不需要放大效果 */
      }
      .bus {
         font-size: 10px;
         background-color: #2196F3;
         border: 10px solid #ffffff;
         position: absolute;
         width: 15px;
         height: 15px;
         border-radius: 50%;
         text-align: center;
         line-height: 15px;
         font-weight: bold;
         transition: transform 0.3s ease;
      }
      .station:hover, .bus:hover {
         transform: scale(1.4);
         z-index: 999;
      .site-logo {
         position: absolute; /* 使用绝对定位,将Logo脱离正常文档流 */
         top: 10px; /* 距离顶部10像素,可根据需要调整 */
         left: 10px; /* 距离左侧10像素,可根据需要调整 */
         padding: 0; /* 移除原有的内边距 */
         text-align: left; /* 将图片对齐方式改为左对齐 */
         z-index: 1000; /* 确保Logo显示在最上层,避免被其他元素遮挡 */
      }
      .task-bar-left {
         position: fixed;
         top: 1%;
         /*transform: translateY(-50%);*/
         width: 25%; /* 设置宽度 */
         background-color: rgba(255, 255, 255, 0); /* 半透明背景 */
         border-radius: 5px;
         padding: 10px;
         box-shadow: 0 0 10px rgba(0, 0, 0, 0);
         z-index: 1000; /* 确保在其他元素之上 */
      }
      .task-bar-left1 {
         position: fixed;
         top: 8%;
         /*transform: translateY(-50%);*/
         width: 25%; /* 设置宽度 */
         background-color: rgba(255, 255, 255, 0); /* 半透明背景 */
         border-radius: 5px;
         padding: 10px;
         box-shadow: 0 0 10px rgba(0, 0, 0, 0);
         z-index: 1000; /* 确保在其他元素之上 */
      }
      .task-bar-right {
         position: fixed;
         top: 1%;
         /*transform: translateY(-50%);*/
         width: 25%; /* 设置宽度 */
         background-color: rgba(255, 255, 255, 0); /* 半透明背景 */
         border-radius: 5px;
         padding: 10px;
         box-shadow: 0 0 10px rgba(0, 0, 0, 0);
         z-index: 1000; /* 确保在其他元素之上 */
      }
      .task-bar-right1 {
         position: fixed;
         top: 5%;
         /*transform: translateY(-50%);*/
         width: 25%; /* 设置宽度 */
         background-color: rgba(255, 255, 255, 0); /* 半透明背景 */
         border-radius: 5px;
         padding: 10px;
         box-shadow: 0 0 10px rgba(0, 0, 0, 0);
         z-index: 1000; /* 确保在其他元素之上 */
      }
      .task-bar-div1 {
         /*width: 100%; !* 设置宽度 *!*/
         background-color: rgba(255, 255, 255, 0.8); /* 半透明背景 */
         box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
      }
      .left-task-bar {
         left: 20px; /* 距离左边的距离 */
         /*bottom: 100px;*/
      }
      .right-task-bar {
         /*bottom: 100px;*/
         right: 20px; /* 距离右边的距离 */
      }
      .el-table .warning-row {
         background: oldlace;
      }
      .el-table .success-row {
         background: #f0f9eb;
      }
      .container {
         width: 100vh;
         height: 72vh;
         position: absolute;
         /*background: #8c939d;*/
      }
      .bus-station {
         width: 100vh;
         height: 72vh;
         position: absolute;
         display: flex;
         /*background: #8c939d;*/
      }
      .bus-item-top {
         background: red;
         position: relative;
         width: 40px;
         height: 60px;
         line-height: 60px;
         top: 880px;
         text-align: center;
      }
      .bus-item-left {
         background: red;
         position: relative;
         width: 60px;
         height: 40px;
         line-height: 40px;
         left: 1230px;
         text-align: center;
      }
      .bus-item-left2 {
         background: red;
         position: relative;
         width: 60px;
         height: 40px;
         line-height: 40px;
         left: 1000px;
         text-align: center;
      .site-logo img {
         max-width: 80%; /* Logo最大宽度为容器宽度的80% */
         height: auto; /* 高度自动,保持比例 */
         max-height: 60px; /* 设置Logo最大高度 */
      }
   </style>
</head>
<body>
<!--<header>-->
<!--    环形穿梭车智能系统-->
<!--</header>-->
<div id="app">
   <div  class="map">
      <div v-if="licenseDayI <=30 ">
         <div style="color: red">{{licenseDay}}</div>
<div class="tech-background">
   <div class="grid-overlay"></div>
   <div class="glow-effect"></div>
   <div class="particles-container" id="particles-container"></div>
      </div>
      <svg class="container">
         <path d="M 1200,750
                        L 1200,100
                        C 1200,100 1200,50 1150,50
                        C 1150,50 1100,50 1100,100
                        L 1100,700
                        C 1100,700 1100,750 1050,750
                        L 60,750
                        C 60,750 10,750 10,800
                        C 10,800 10,850 60,850
                        L 1100,850
                        C 1100,850 1200,850 1200,750
"
              style="fill:none; stroke:blue; stroke-width:4;" />
      </svg>
      <div v-for="station in tableDataDev" class="station" :style="{ top: station.valueY + 'px', left: station.valueX + 'px' }">{{ station.index }}</div>
      <div>
<div id="app">
   <!-- 添加Logo -->
   <div class="site-logo">
      <img src="../../static/images/zy_logo_dark_color.png" alt="自动仓库WCS系统 Logo">
   </div>
   <div  class="map">
      <div class="system-control-panel">
         <div class="system-status">
            <div class="status-indicator" :class="valueSystem ? 'status-running' : 'status-stopped'"></div>
            <span class="status-text">{{ valueSystem ? '系统运行中' : '系统已停止' }}</span>
         </div>
         <div class="custom-switch">
         <el-switch
               style="display: block"
               v-model="valueSystem"
               active-color="#13ce66"
               inactive-color="#A64036"
               active-text="系统运行中..."
               inactive-text="系统已停止!"
               @change='upDateValueSystem'>
         </el-switch>
      </div>
      <div v-for="bus in tableDataRgv" class="bus" :style="{ top: bus.valueY + 'px', left: bus.valueX + 'px' , borderColor: bus.modeColor, backgroundColor: bus.statusColor}">{{ bus.index }}</div>
      </div>
      <div class="license-info" :class="getLicenseClass()"  v-if="licenseDayI <=30">
         <span class="license-icon">📄</span>
         {{ licenseDay }}
      </div>
      <!--        <div class="inner-ring"></div>-->
      <!--        <div class="outer-ring"></div>-->
      <!--            <div v-for="track in energyGatheringRing" class="inner-ring" :style="{  borderColor: track.trackColor , boxShadow :  'inset 0 0 30px '+track.radiationColor+', 0 0 20px '+track.radiationColor}"></div>-->
      <!--            <div v-for="track in energyGatheringRing" class="outer-ring" :style="{  borderColor: track.trackColor , boxShadow :  'inset 0 0 30px '+track.radiationColor+', 0 0 20px '+track.radiationColor}"></div>-->
      <svg class="container"
          viewBox="0 0 1200 850"
          preserveAspectRatio="xMidYMid meet">
         <path d="M 100,225 L 1100,225"
              style="fill:none; stroke:blue; stroke-width:3; stroke-dasharray:10,1;"/>
         <path d="M 100,625 L 1100,625"
              style="fill:none; stroke:blue; stroke-width:3; stroke-dasharray:10,1;"/>
      </svg>
      <div v-for="station in tableDataDev" class="station" :style="{
                top: convertToCSSPosition2(station.index,station.valueX, station.valueY).y + 'px',
                left: convertToCSSPosition2(station.index,station.valueX, station.valueY).x + 'px',
                backgroundColor: station.modeColor}">
         <div class="corner corner-tl"></div>
         <div class="corner corner-tr"></div>
         <div class="corner corner-bl"></div>
         <div class="corner corner-br"></div>
         {{ station.index }}
      </div>
      <!-- Buses -->
      <div v-for="bus in tableDataRgv" class="bus" :style="{
                top: convertToCSSPositionWithOffset(bus.valueX, bus.valueY).y + 'px',
                left: convertToCSSPositionWithOffset(bus.valueX, bus.valueY).x + 'px',
                animation: 'pulse ' +  bus.animation + 's infinite',
                borderColor: bus.modeColor, backgroundColor: bus.statusColor}">{{ bus.index }}
      </div>
   </div>
</div>
<script>
   // 在Vue实例外添加粒子生成函数
   function createParticles() {
      const container = document.getElementById('particles-container');
      const particleCount = 30;
      for (let i = 0; i < particleCount; i++) {
         const particle = document.createElement('div');
         particle.classList.add('particle');
         // 随机大小和位置
         const size = Math.random() * 3 + 1;
         const posX = Math.random() * 100;
         const posY = Math.random() * 100;
         const delay = Math.random() * 15;
         particle.style.width = `${size}px`;
         particle.style.height = `${size}px`;
         particle.style.left = `${posX}vw`;
         particle.style.top = `${posY}vh`;
         particle.style.animationDelay = `${delay}s`;
         container.appendChild(particle);
      }
   }
   // 页面加载完成后创建粒子
   document.addEventListener('DOMContentLoaded', createParticles);
   // 在Vue实例外获取body尺寸
   function getBodySize() {
      return {
         width: document.body.clientWidth,
         height: document.body.clientHeight
      };
   }
   var app = new Vue({
      el: '#app',
      data: {
         containerSize: { width: 0, height: 0},
         bodySize: { width: 0, height: 0 },
         activeNames: ['1'],
         valueLeft: '0',
         valueLeft1: '0',
@@ -259,54 +151,31 @@
         tableDataLeft: [],
         tableDataLeft1: [],
         tableDataRight: [],
         tableDataRight1: [],
         devpPos1:[
            {dev_no: 116,pos:633980},
            {dev_no: 117,pos:604043},
            {dev_no: 118,pos:574323},
            {dev_no: 119,pos:559534},
            {dev_no: 120,pos:544682},
            {dev_no: 121,pos:514912},
            {dev_no: 122,pos:485227},
            {dev_no: 123,pos:470367},
            {dev_no: 124,pos:455514},
            {dev_no: 125,pos:425768},
            {dev_no: 126,pos:396268},
            {dev_no: 127,pos:381106},
            {dev_no: 128,pos:366311},
            {dev_no: 129,pos:336638},
            {dev_no: 130,pos:306820},
            {dev_no: 131,pos:277067},
            {dev_no: 132,pos:257418},
            {dev_no: 133,pos:217730},
         ],
         devpPos2:[
            {dev_no: 112,pos:891000},
            {dev_no: 113,pos:865000},
            {dev_no: 114,pos:800000},
            {dev_no: 115,pos:780000},
         ],
         devpPos3:[
            {dev_no: 101,pos:1269958},
            {dev_no: 102,pos:1243454},
            {dev_no: 103,pos:1229081},
            {dev_no: 104,pos:1202099},
            {dev_no: 105,pos:1187564},
            {dev_no: 106,pos:1160630},
            {dev_no: 107,pos:1146152},
            {dev_no: 108,pos:1119463},
            {dev_no: 109,pos:1105038},
            {dev_no: 110,pos:1077961},
            {dev_no: 111,pos:1063813},
         ],
         tableDataRight1: []
      },
      created(){
         this.init();
         this.devpPos1.reverse()
         this.devpPos3.reverse()
      },
      watch: {
      },
      // 在 mounted 中初始化尺寸和监听
      mounted() {
         this.updateContainerSize();
         this.updateBodySize();
         window.addEventListener('resize', this.handleResize);
      },
      beforeDestroy() {
         window.removeEventListener('resize', this.handleResize);
      },
      computed: {
         mappedStations() {
            return this.tableDataDev.map(station => ({
               ...station,
               position: this.convertToCSSPosition2(station.index,station.valueX, station.valueY)
            }));
         }
      },
      methods: {
         init(){
@@ -320,20 +189,133 @@
            this.getValueSystem()
            this.getLicenseDays()
            // 高频更新:小车和设备位置(1.5秒)
            setInterval(() => {
               this.getTableDataRgv()
               this.getTableDataDev()
               this.getTableDataTrack()
            }, 1000)
            // 高频更新:实时任务列表等(2秒)
            setInterval(() => {
               this.getTableDataLeft()
               this.getTableDataLeft1()
               this.getTableDataRight()
            }, 2000)
            // 高频更新:实时站点信息等(3秒)
            setInterval(() => {
               this.getTableDataDev()
            }, 3000)
            // 低频更新:任务列表等(10秒)
            setInterval(() => {
               this.getTableDataLeft1()
               this.getTableDataRight1()
               this.getValueSystem()
               this.getLicenseDays()
            }, 10*1000)
            }, 1000)
            // 低频更新:许可证信息(30秒)
            setInterval(() => {
               this.getLicenseDays()
            }, 30000)
            // 静态低频更新:PLC(1小时)
            setInterval(() => {
               this.getTableDataTrack()
            }, 60*60*1000)
         },
         // 获取容器实际尺寸
         updateContainerSize() {
            const mapEl = this.$el.querySelector('.map');
            this.containerSize = {
               width: mapEl.clientWidth,
               height: mapEl.clientHeight
            };
         },
         convertToCSSPositionWithOffset(svgX, svgY, radius) {
            const basePos = this.convertToCSSPosition(svgX, svgY);
            return {
               x: basePos.x-16.5,
               y: basePos.y-16.5
            };
         },
         // 更新body尺寸
         updateBodySize() {
            this.bodySize = getBodySize();
         },
         // 坐标转换函数
         convertToCSSPosition(svgX, svgY) {
            const svgWidth = 1200;  // SVG 原始宽度
            let svgWidthR = 0;  //
            const svgHeight = 850; // SVG 原始高度
            let svgHeightR = 0; //
            if (svgX>svgWidth/2){
               svgWidthR = (((svgX-svgWidth/2)/svgWidth) * this.containerSize.width) + this.bodySize.width/2 - this.bodySize.width*((1-0.52)/2);
            } else {
               svgWidthR = this.bodySize.width/2 - (((svgWidth/2 - svgX)/svgWidth) * this.containerSize.width)  - this.bodySize.width*((1-0.52)/2);
            }
            if (svgY>svgHeight/2){
               svgHeightR = (((svgY-svgHeight/2)/svgHeight) * this.containerSize.height) + this.bodySize.height/2 - this.bodySize.height*((1-0.72)/2);
            } else {
               svgHeightR = this.bodySize.height/2 - (((svgHeight/2 - svgY)/svgHeight) * this.containerSize.height)  - this.bodySize.height*((1-0.72)/2);
            }
            return {
               x: svgWidthR,
               y: svgHeightR
            };
         },
         // 坐标转换函数
         convertToCSSPosition2(devNo,svgX, svgY) {
            const svgWidth = 1200;  // SVG 原始宽度
            let svgWidthR = 0;  //
            const svgHeight = 850; // SVG 原始高度
            let svgHeightR = 0; //
            if (svgX>svgWidth/2){
               svgWidthR = (((svgX-svgWidth/2)/svgWidth) * this.containerSize.width) + this.bodySize.width/2 - this.bodySize.width*((1-0.52)/2);
            } else {
               svgWidthR = this.bodySize.width/2 - (((svgWidth/2 - svgX)/svgWidth) * this.containerSize.width)  - this.bodySize.width*((1-0.52)/2);
            }
            if (svgY>svgHeight/2){
               svgHeightR = (((svgY-svgHeight/2)/svgHeight) * this.containerSize.height) + this.bodySize.height/2 - this.bodySize.height*((1-0.72)/2);
            } else {
               svgHeightR = this.bodySize.height/2 - (((svgHeight/2 - svgY)/svgHeight) * this.containerSize.height)  - this.bodySize.height*((1-0.72)/2);
            }
            svgHeightR = svgHeightR-60;
            if(devNo>200){
               if (devNo>216){
                  svgHeightR = svgHeightR+80;
               }
            } else {
               if (devNo>116){
                  svgHeightR = svgHeightR+80;
               } else {
                  if(devNo === 114 || devNo === 112 ){
                     svgWidthR = svgWidthR-20;
                  } else {
                     svgWidthR = svgWidthR+40;
                  }
               }
            }
            if(devNo === 116){
               svgHeightR = svgHeightR-35;
            }
            return {
               x: svgWidthR,
               y: svgHeightR
            };
         },
         handleZoom(e) {
            const scaleDelta = e.deltaY > 0 ? 0.9 : 1.1;
            const currentScale = this.scale || 1;
            const newScale = Math.max(0.5, Math.min(2, currentScale * scaleDelta));
            // 应用缩放
            const svgEl = this.$el.querySelector('.container');
            svgEl.style.transform = `scale(${newScale})`;
            this.scale = newScale;
         },
         verifyPassword(callback) {
            this.$prompt('请输入管理员密码: root', '验证', {
               confirmButtonText: '确定',
@@ -350,11 +332,9 @@
            });
         },
         handleChange(val) {
            console.log(val);
            if (val.length === 0){
               valueRight = '0';
            } else {
               console.log("2222"+val);
               if (val.length >= 1){
                  this.handleChangeValueRight(1)
@@ -362,12 +342,9 @@
            }
         },
         handleChange1(val) {
            console.log(val);
            if (val.length === 0){
               valueRight1 = '0';
            } else {
               console.log("2222"+val);
               if (val.length >= 1){
                  this.handleChangeValueRight1(1)
               }
@@ -375,7 +352,7 @@
         },
         taskDelete(row) {
            let that = this;
            that.$confirm('确认要删除该任务吗?', '提示', {
            that.$confirm('确认要删除该设备吗?', '提示', {
               confirmButtonText: '确定',
               cancelButtonText: '取消',
               type: 'warning'
@@ -455,8 +432,6 @@
            });
         },
         handleChangeValueRight(val) {
            console.log("33333"+val);
            switch (val){
               case 1:
                  valueRight = '100';
@@ -471,8 +446,6 @@
            }
         },
         handleChangeValueRight1(val) {
            console.log("33333"+val);
            switch (val){
               case 1:
                  valueRight1 = '100';
@@ -493,6 +466,17 @@
               return 'success-row';
            }
            return '';
         },
         // 获取许可证样式类
         getLicenseClass() {
            if (this.licenseDayI > 30) {
               return 'normal';
            } else if (this.licenseDayI > 0) {
               return 'warning';
            } else {
               return 'expired';
            }
         },
         getLicenseDays(){
            let that = this;
@@ -549,7 +533,9 @@
                  method: 'POST',
                  success: function (res) {
                     if (res.code === 200) {
                        that.valueSystem = res.data.status;
                        that.$message.success(`状态更新成功`);
                     } else {
                        that.$message.error('状态更新失败');
                     }
                  }
               });
@@ -621,8 +607,6 @@
         },
         getTableDataRgv() {
            let that = this;
            // that.tableDataRgv = busPsto
            // return
            $.ajax({
               url: baseUrl + "/rgv/ring/through/rgv/position/data",
               headers: {
@@ -668,7 +652,12 @@
                  that.energyGatheringRing = res.data
               }
            });
         }
         },
         // 处理窗口大小变化
         handleResize: _.debounce(function() {
            this.updateContainerSize();
            this.updateBodySize();
         }, 100)
      }
   })