基于若依-Vue,接入静态HTML页面

发布于:2025-07-01 ⋅ 阅读:(15) ⋅ 点赞:(0)

1.在前端文件夹中RuoYi-Vue/ruoyi-ui/public创建相应的包

例如:我在这就创建了一个monitor包,并放入了相应的index.html模板

如图所示:

2.在首页创建了一个按钮,点击按钮

触发goTarget方法,跳转到相应页面

3.index.vue页面,主要用于在页面中嵌入一个 iframe(内嵌框架),并通过 postMessage 实现父子页面间的安全通信(传递身份认证 Token)

1. 组件功能概述

  • 核心作用:嵌入一个监控页面(/monitor/liujiaxia/index.html),并将当前用户的认证 Token 从父页面传递到 iframe 子页面。

  • 安全机制:通过 localStorage + postMessage 双保险传递 Token,确保 iframe 内页面能获取到授权信息。

<template>
  <div class="app-container">
    <div class="monitor-container">
      <iframe
        ref="monitorIframe"
        src="/monitor/liujiaxia/index.html"
        frameborder="0"
        width="100%"
        height="100%"
        style="border: none;"
        @load="onIframeLoad"
      ></iframe>
    </div>
  </div>
</template>

<script>
import { getToken } from '@/utils/auth'

export default {
  name: "LiuJiaXiaMonitor",
  data() {
    return {
      token: null
    };
  },
  mounted() {
    this.token = getToken();
    // 進入iframe時將token寫入localStorage
    localStorage.setItem('iframe_token', this.token);
    // 監聽iframe的請求
    window.addEventListener('message', this.onMessageFromIframe);
  },
  beforeDestroy() {
    window.removeEventListener('message', this.onMessageFromIframe);
  },
  methods: {
    onIframeLoad() {
      this.sendTokenToIframe();
    },
    onMessageFromIframe(event) {
      if (event.data && event.data.type === 'REQUEST_AUTH_TOKEN') {
        this.sendTokenToIframe();
      }
    },
    sendTokenToIframe() {
      const iframe = this.$refs.monitorIframe;
      if (iframe && iframe.contentWindow) {
        try {
          console.log('[iframe] 發送REQUEST_AUTH_TOKEN給父頁面');
          iframe.contentWindow.postMessage({
            type: 'AUTH_TOKEN',
            token: this.token
          }, '*');
        } catch (error) {
          console.error('向iframe傳遞token失敗:', error);
        }
      }
    }
  }
};
</script>

<style scoped>
.monitor-container {
  width: 100%;
  height: calc(100vh - 120px);
  overflow: hidden;
}

iframe {
  width: 100%;
  height: 100%;
  border: none;
}
</style> 

4.在HTML页面中,插入一个折线图

  <div style="width:100%;height:100%;margin-top:-40px;" id="dataChart" dg-chart-theme="{'color':'#faf7fa','actualBackgroundColor':'#030303'}">
    <!--最新200条数据折现图-->
  </div>

5.由于这是一个静态页面需要加入axios来请求后端的API

<script src="/monitor/liujiaxia/js/jquery.min.js"></script>
		<script src="/monitor/liujiaxia/js/echarts.min.js"></script>
		<script src="/monitor/liujiaxia/js/fq.js"></script>
		<script src="/monitor/liujiaxia/js/axios.min.js"></script>
		<script>
			var lazyFun;
			var authToken = localStorage.getItem('iframe_token');
			if (!authToken) {
				window.parent.postMessage({ type: 'REQUEST_AUTH_TOKEN' }, '*');
			}

		    function init(el, width, height) {
		        var _el = document.getElementById(el);
		        var hScale = window.innerHeight / height;
		        var wScale = window.innerWidth / width;
		        _el.style.transform = 'scale(' + wScale + ',' + hScale + ')'
		    }
		    init('mainbody', 1920, 1080);
		    window.onresize = function() {
		        clearTimeout(lazyFun);
		        lazyFun = setTimeout(function() {
		            init('mainbody', 1920, 1080)
		        }, 600);
		    };

		    // 監聽來自父頁面的消息
		    window.addEventListener('message', function(event) {
		        if (event.data && event.data.type === 'AUTH_TOKEN') {
					var wasTokenMissing = !authToken;
		            authToken = event.data.token;
		            localStorage.setItem('iframe_token', authToken); // 写入localStorage,保存刷新後還在
		            if (wasTokenMissing) {
						fetchLatestData();
					}
		        }
		    });

		    // 初始化数据图表
		    var dataChart = echarts.init(document.getElementById('dataChart'));

		    //
		    function fetchLatestData() {
		        if (!authToken) {
		            console.error('[iframe] 未獲取到認證token,無法請求數據');
		            return;
		        }
		        // 使用axios調用後端接口
		        axios.get('/dev-api/screen/list2', {
		            headers: {
		                'Content-Type': 'application/json',
		                'Authorization': 'Bearer ' + authToken
		            }
		        })
		        .then(function(response) {

              console.log('获取数据成功:', response.data.data);
		            // 假設返回的數據格式為數組,取最新200條
		            var data = response.data.data ? response.data.data.slice(-200) : response.data.slice(-200);
		            updateChart(data);
		        })
		        .catch(function(error) {
		            console.error('获取数据失敗:', error);
		            // 接口失敗時直接報錯,不顯示模擬數據
		            throw error;
		        });
		    }

		    // 更新圖表
		    function updateChart(data) {
		        // 数据格式:使用dateTime作为时间,data1作为数值
		        var times = data.map(function(item) {
		            // 將ISO时间格式转换为更友好的显示格式
		            var date = new Date(item.dateTime);
		            return date.toLocaleTimeString('zh-CN', {
		                hour: '2-digit',
		                minute: '2-digit',
		                second: '2-digit'
		            });
		        });
		        var values = data.map(function(item) { return item.data1; });

		        var option = {
		            backgroundColor: 'transparent',
		            title: {
		                text: '最新数据监测',
		                textStyle: {
		                    color: '#faf7fa',
		                    fontSize: 14
		                },
		                left: 'center'
		            },
		            tooltip: {
		                trigger: 'axis',
		                backgroundColor: 'rgba(0,0,0,0.8)',
		                borderColor: '#faf7fa',
		                textStyle: {
		                    color: '#faf7fa'
		                },
		                formatter: function(params) {
		                    var dataIndex = params[0].dataIndex;
		                    var originalData = data[dataIndex];
		                    return '时间: ' + originalData.dateTime + '<br/>' +
		                           '数值: ' + params[0].value;
		                }
		            },
		            grid: {
		                left: '3%',
		                right: '4%',
		                bottom: '3%',
		                containLabel: true
		            },
		            xAxis: {
		                type: 'category',
		                data: times,
		                axisLine: {
		                    lineStyle: {
		                        color: '#faf7fa'
		                    }
		                },
		                axisLabel: {
		                    color: '#faf7fa',
		                    fontSize: 10,
		                    rotate: 45
		                }
		            },
		            yAxis: {
		                type: 'value',
		                axisLine: {
		                    lineStyle: {
		                        color: '#faf7fa'
		                    }
		                },
		                axisLabel: {
		                    color: '#faf7fa'
		                },
		                splitLine: {
		                    lineStyle: {
		                        color: 'rgba(250,247,250,0.2)'
		                    }
		                }
		            },
		            series: [{
		                name: '检測值',
		                type: 'line',
		                data: values,
		                smooth: true,
		                lineStyle: {
		                    color: '#00ff00',
		                    width: 2
		                },
		                itemStyle: {
		                    color: '#00ff00'
		                },
		                areaStyle: {
		                    color: {
		                        type: 'linear',
		                        x: 0,
		                        y: 0,
		                        x2: 0,
		                        y2: 1,
		                        colorStops: [{
		                            offset: 0, color: 'rgba(0,255,0,0.3)'
		                        }, {
		                            offset: 1, color: 'rgba(0,255,0,0.1)'
		                        }]
		                    }
		                }
		            }]
		        };

		        dataChart.setOption(option);
		    }

		    // 頁面加載完成後初始化圖表
		    $(document).ready(function() {
		        // 如果localStorage中已有token,則立即獲取數據
		        if (authToken) {
		            fetchLatestData();
		        }

		        // 每30秒更新一次數據(但需要檢查token)
		        setInterval(function() {
		            if (authToken) {
		                fetchLatestData();
		            }
		        }, 30000);
		    });
		</script>


网站公告

今日签到

点亮在社区的每一天
去签到