Przeglądaj źródła

Merge branch 'master' of http://121.40.40.223:3000/zizhong.wang/dtScreen

hebotao 3 tygodni temu
rodzic
commit
d8fd335128

BIN
src/assets/map/end.png


BIN
src/assets/map/start.png


+ 123 - 89
src/components/TongzhouTrafficMap.vue

@@ -104,7 +104,7 @@ export default {
       this.storeStatusCoordsToLocalStorage();
     });
 
-    if (this.$route.path === '/home') {
+    if (this.$route.path === '/home' || this.$route.path === '/watch') {
       this.privateStyle.legend = { right: "25%" };
     }
   },
@@ -638,69 +638,98 @@ export default {
         const isAbnormal = ["离线", "降级", "故障"].includes(config.name);
         const isRoute = ["干线协调", "勤务路线"].includes(config.name);
 
-        // 动态计算尺寸:起终点最大,异常点次之,普通点最小
-        const size = (type === 'start' || type === 'end') ? '22px' : (isAbnormal ? '30px' : '14px');
-        const sizeNumber = parseInt(size, 10);
-        const paddingNumber = (isAbnormal || type === 'start' || type === 'end') ? 0 : 2;
-        const outerSizeNumber = sizeNumber + paddingNumber * 2;
-
-        // 边框样式:起终点用实白边框
-        const borderStyle = (type === 'start' || type === 'end')
-          ? '2px solid #fff'
-          : '1.5px solid rgba(255,255,255,0.7)';
-
-        // 生成异常状态的图标路径
-        let markerContent = '';
-        if (isAbnormal) {
-          const iconName = config.name === '离线' ? 'lixian' : config.name === '降级' ? 'jiangji' : 'guzhang';
-          markerContent = `
-            <div class="pure-light-node ${isAbnormal ? 'breathe' : ''}"
-                style="
-                  width: ${size};
-                  height: ${size};
-                  background: transparent;
-                  box-shadow: none;
-                  border: none;
-                  box-sizing: content-box;
-                  display: flex;
-                  justify-content: center;
-                  align-items: center;
-                  cursor: pointer;
-                  padding: ${paddingNumber}px;
-                ">
-              <img src="${require(`@/assets/images/icon_${iconName}.png`)}" style="width: 100%; height: 100%; object-fit: contain;" />
-            </div>
-          `;
-        } else {
-          markerContent = `
-            <div class="pure-light-node ${isAbnormal ? 'breathe' : ''} ${isRoute ? 'route-node' : ''}"
-                style="
-                  width: ${size};
-                  height: ${size};
-                  background: ${config.color || '#999'};
-                  box-shadow: ${isRoute ? 'none' : `0 0 8px ${config.color}`};
-                  border: ${isRoute ? 'none' : borderStyle};
-                  box-sizing: content-box;
-                  display: flex;
-                  justify-content: center;
-                  align-items: center;
-                  color: #fff;
-                  border-radius: 50%;
-                  cursor: pointer;
-                  padding: ${paddingNumber}px;
-                ">
-              <span style="transform: scale(0.8); font-weight: bold; font-size: 12px;">${displayText}</span>
-            </div>
-          `;
-        }
+      // 动态计算尺寸:起终点最大,异常点次之,普通点最小
+      const isStartEnd = type === 'start' || type === 'end';
+      const size = isStartEnd ? '24px' : (isAbnormal ? '30px' : '14px');
+      const sizeNumber = parseInt(size, 10);
+      const paddingNumber = (isAbnormal || isStartEnd) ? 0 : 2;
+      const outerSizeNumber = sizeNumber + paddingNumber * 2;
+
+      // 边框样式:起终点用实白边框
+      const borderStyle = isStartEnd
+        ? '2px solid #fff'
+        : '1.5px solid rgba(255,255,255,0.7)';
+
+      // 生成标记内容
+      let markerContent = '';
+      if (isStartEnd) {
+        const iconPath = type === 'start' 
+          ? require('@/assets/map/start.png') 
+          : require('@/assets/map/end.png');
+        markerContent = `
+          <div class="pure-light-node start-end-node"
+              style="
+                width: ${size};
+                height: 30px;
+                background: transparent;
+                border: none;
+                display: flex;
+                justify-content: center;
+                align-items: flex-end;
+                cursor: pointer;
+                transform-origin: bottom center;
+              ">
+            <img src="${iconPath}" style="width: 100%; height: auto; object-fit: contain; pointer-events: none;" />
+          </div>
+        `;
+      } else if (isAbnormal) {
+        const iconName = config.name === '离线' ? 'lixian' : config.name === '降级' ? 'jiangji' : 'guzhang';
+        markerContent = `
+          <div class="pure-light-node ${isAbnormal ? 'breathe' : ''}"
+              style="
+                width: ${size};
+                height: ${size};
+                background: transparent;
+                box-shadow: none;
+                border: none;
+                box-sizing: content-box;
+                display: flex;
+                justify-content: center;
+                align-items: center;
+                cursor: pointer;
+                padding: ${paddingNumber}px;
+              ">
+            <img src="${require(`@/assets/images/icon_${iconName}.png`)}" style="width: 100%; height: 100%; object-fit: contain;" />
+          </div>
+        `;
+      } else {
+        markerContent = `
+          <div class="pure-light-node ${isAbnormal ? 'breathe' : ''} ${isRoute ? 'route-node' : ''}"
+              style="
+                width: ${size};
+                height: ${size};
+                background: ${config.color || '#999'};
+                box-shadow: ${isRoute ? 'none' : `0 0 8px ${config.color}`};
+                border: ${isRoute ? 'none' : borderStyle};
+                box-sizing: content-box;
+                display: flex;
+                justify-content: center;
+                align-items: center;
+                color: #fff;
+                border-radius: 50%;
+                cursor: pointer;
+                padding: ${paddingNumber}px;
+              ">
+            <span style="transform: scale(0.8); font-weight: bold; font-size: 12px;">${displayText}</span>
+          </div>
+        `;
+      }
+
+      // 计算偏移量:起点终点底部对齐,其他中心对齐
+      let markerOffset;
+      if (isStartEnd) {
+        // 设置 24px 宽 30px 高,偏移量设置为底部中心对齐
+        markerOffset = new this.AMap.Pixel(-12, -30);
+      } else {
+        markerOffset = new this.AMap.Pixel(-Math.round(outerSizeNumber / 2), -Math.round(outerSizeNumber / 2));
+      }
 
-        const marker = new this.AMap.Marker({
-          position: [lng, lat],
-          // 这里的 type 已经从参数拿到了,不会报错了
-          zIndex: (type === 'start' || type === 'end') ? 120 : (isAbnormal ? 110 : 100),
-          content: markerContent,
-          offset: new this.AMap.Pixel(-Math.round(outerSizeNumber / 2), -Math.round(outerSizeNumber / 2)),
-          extData: {
+      const marker = new this.AMap.Marker({
+        position: [lng, lat],
+        zIndex: isStartEnd ? 120 : (isAbnormal ? 110 : 100),
+        content: markerContent,
+        offset: markerOffset,
+        extData: {
             ...config,
             position: [lng, lat],
             statusColor: config.color || '#999',
@@ -933,35 +962,40 @@ export default {
       this.legendVisible = !this.legendVisible;
     },
 
-    // 按4:4:4比例提取故障、离线、降级坐标点并存储到localStorage
+    // 按4:4:4比例提取故障、离线、降级路口信息并存储到localStorage
     storeStatusCoordsToLocalStorage() {
-      // 从分类好的路口数据中获取故障、离线、降级的坐标
-      const faultCoords = (this.statusIntersections["故障"] || []).slice(0, 4).map(item => [
-        item["位置-经度"],
-        item["位置-纬度"]
-      ]).filter(coord => coord[0] && coord[1]);
-
-      const offlineCoords = (this.statusIntersections["离线"] || []).slice(0, 4).map(item => [
-        item["位置-经度"],
-        item["位置-纬度"]
-      ]).filter(coord => coord[0] && coord[1]);
-
-      const degradedCoords = (this.statusIntersections["降级"] || []).slice(0, 4).map(item => [
-        item["位置-经度"],
-        item["位置-纬度"]
-      ]).filter(coord => coord[0] && coord[1]);
-
-      // 组合成12个元素的数组
-      const statusCoords = [...faultCoords, ...offlineCoords, ...degradedCoords];
-
-      // 存储到localStorage
-      statusCoords.forEach((coords, index) => {
-        if (coords && coords.length === 2) {
-          localStorage.setItem(`pos${index + 1}`, coords.join(','));
-        }
+      const alarmTypes = [
+        { status: "故障", titles: ["通讯中断", "灯组故障", "相位冲突", "绿冲突"], level: "high", type: "error" },
+        { status: "离线", titles: ["信号机离线", "信号机离线", "通讯中断", "检测器异常"], level: "mid", type: "warning" },
+        { status: "降级", titles: ["降级黄闪", "降级黄闪", "方案切换异常", "检测器异常"], level: "mid", type: "warning" },
+      ];
+
+      const alarmList = [];
+      let id = 1;
+
+      alarmTypes.forEach(({ status, titles, level, type }) => {
+        (this.statusIntersections[status] || []).slice(0, 4).forEach((item, i) => {
+          const lng = item["位置-经度"];
+          const lat = item["位置-纬度"];
+          const name = item["路口名称"] || "";
+          if (!lng || !lat) return;
+          alarmList.push({
+            id: `A${String(id).padStart(3, "0")}`,
+            title: titles[i] || titles[0],
+            loc: name,
+            level,
+            type,
+            description: `${name}-${titles[i] || titles[0]}`,
+            position: [lng, lat],
+          });
+          // 保持原有的 pos1-pos12 存储,兼容其他可能的引用
+          localStorage.setItem(`pos${id}`, `${lng},${lat}`);
+          id++;
+        });
       });
 
-      console.log('状态坐标已存储到localStorage');
+      localStorage.setItem("alarmListFromMap", JSON.stringify(alarmList));
+      console.log('状态坐标及告警数据已存储到localStorage');
     },
     // 公开方法:将经纬度转换为像素坐标
     lngLatToPixel(lng, lat) {

+ 1 - 1
src/components/ui/XgVideoPlayer.vue

@@ -130,7 +130,7 @@ export default {
                 videoFillMode: this.fillMode,
                 isLive: this.live,
 
-                closeVideoClick: false,
+                closeVideoClick: true,
                 closeVideoDblclick: true,
                 enableContextmenu: false,
                 keyShortcut: false,

+ 9 - 9
src/styles/base.css

@@ -142,8 +142,8 @@ html, body {
 .glow-text {
   position: relative;
 
-  /* 渐变文字 */
-  background: linear-gradient(45deg, #0033ff, #00aaff, #00ddff);
+  /* 渐变文字:蓝 → 浅蓝 → 白(无绿色) */
+  background: linear-gradient(45deg, #0044ff, #409cff, #ffffff);
   -webkit-background-clip: text;
   color: transparent;
 
@@ -157,25 +157,25 @@ html, body {
   inset: 0;
   z-index: -1;
 
-  background: linear-gradient(45deg, #0033ff, #00aaff, #00ddff);
+  background: linear-gradient(45deg, #0044ff, #409cff, #ffffff);
   -webkit-background-clip: text;
   color: transparent;
 
   animation: glowBreathe 2.5s ease-in-out infinite;
 }
 
-/* 主体呼吸(控制亮度) */
+/* 主体呼吸(控制亮度)- 蓝白色光晕 */
 @keyframes glowTextBreathe {
   0%, 100% {
     text-shadow:
-      0 0 4px rgba(0, 170, 255, 0.4),
-      0 0 8px rgba(0, 170, 255, 0.3);
+      0 0 4px rgba(64, 156, 255, 0.4),
+      0 0 8px rgba(64, 156, 255, 0.3);
   }
   50% {
     text-shadow:
-      0 0 10px rgba(0, 255, 255, 0.9),
-      0 0 20px rgba(0, 255, 255, 0.7),
-      0 0 40px rgba(0, 255, 255, 0.5);
+      0 0 10px rgba(255, 255, 255, 0.9),
+      0 0 20px rgba(64, 156, 255, 0.8),
+      0 0 40px rgba(0, 68, 255, 0.6);
   }
 }
 

+ 15 - 5
src/views/Home.vue

@@ -196,11 +196,21 @@ export default {
       ]);
       this.controlInfoData = controlData || [];
       
-      // 处理故障报警数据,使用从API获取的12条数据
-      let originalAlarms = alarmData?.list || alarmData || [];
-      
-      // 组合成12条数据
-      this.alarmData = originalAlarms;
+      // 优先使用地图生成的告警数据(与地图点位完全匹配)
+      const mapAlarms = localStorage.getItem('alarmListFromMap');
+      if (mapAlarms) {
+        try {
+          const parsed = JSON.parse(mapAlarms);
+          this.alarmData = parsed.map((a, i) => ({
+            ...a,
+            time: new Date(Date.now() - i * 180000).toLocaleTimeString(),
+          }));
+        } catch (e) {
+          this.alarmData = alarmData?.list || alarmData || [];
+        }
+      } else {
+        this.alarmData = alarmData?.list || alarmData || [];
+      }
       
       this.tableData = taskData?.list || taskData || [];
       this.keyIntersectionData = keyData || [];