Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
37a5b13120 | ||
|
|
40ce5b725b |
@@ -262,15 +262,6 @@ export const constantRouterMap = [
|
||||
requireAuth: true,
|
||||
keepAlive: true,
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/bigscreen/viewer/saleStatic',
|
||||
component: () => import('@/views/bigscreenDesigner/viewer/saleStatic'),
|
||||
hidden: true,
|
||||
meta: {
|
||||
requireAuth: true,
|
||||
keepAlive: true,
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/bigscreen/designer',
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -4,15 +4,12 @@
|
||||
|
||||
<header class="header">
|
||||
<div class="logo-section">
|
||||
<!-- <div class="logo-icon"></div> -->
|
||||
<div class="logo-icon"></div>
|
||||
<div class="title-text">
|
||||
<h1 class="main-title">国瑞药业工业互联网</h1>
|
||||
<!-- <span class="sub-title">Energy consumption monitoring platform-visualization of carbon peak indicatorsm</span> -->
|
||||
<h1 class="main-title">驾驶仓总屏-销售分析-生产组态</h1>
|
||||
<span class="sub-title">Energy consumption monitoring platform-visualization of carbon peak indicatorsm</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="link-section">
|
||||
<a v-for="item in Object.keys(linkList)" :key="item" :href="linkList[item]" target="_blank" rel="noopener noreferrer">{{item}}</a>
|
||||
</div>
|
||||
<div class="time-display">{{ currentTime }}</div>
|
||||
</header>
|
||||
|
||||
@@ -169,7 +166,6 @@ export default {
|
||||
charts: {},
|
||||
powerData: [],
|
||||
peakData: {},
|
||||
linkList: {},
|
||||
topStats: [
|
||||
|
||||
]
|
||||
@@ -187,7 +183,6 @@ export default {
|
||||
this.getPowerData()
|
||||
this.getTopStatsData()
|
||||
this.getPeakData()
|
||||
this.getlink()
|
||||
},
|
||||
beforeDestroy() {
|
||||
window.removeEventListener('resize', this.handleResize)
|
||||
@@ -196,16 +191,6 @@ export default {
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
getlink(){
|
||||
const {widgets} = this.dashboard
|
||||
if(widgets && widgets.length > 0){
|
||||
widgets.forEach(widget => {
|
||||
if(['销售分析','生产组态'].includes(widget.value.setup.layerName)){
|
||||
this.linkList[widget.value.setup.layerName] = widget.value.setup.linkAdress
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
async getPeakData(){
|
||||
const params={"chartProperties":{"本年存货周期":"text"},"setCode":"zp_cxxt_zb","chartType":"widget-text","contextData":{"qyear":"2026","reportCode":"ddddd"}}
|
||||
const params2={"chartProperties":{"平均销售交付周期_天":"text"},"setCode":"ping_jun_xiao_tian","chartType":"widget-text","contextData":{"reportCode":"ddddd"}}
|
||||
@@ -952,7 +937,7 @@ export default {
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
show: true,
|
||||
// max: parkData[0].value+300,
|
||||
max: parkData[0].value+300,
|
||||
|
||||
splitLine: {
|
||||
show: true,
|
||||
@@ -1079,23 +1064,13 @@ export default {
|
||||
}
|
||||
|
||||
.main-title {
|
||||
font-size:32px;
|
||||
font-size:24px;
|
||||
font-weight: bold;
|
||||
margin: 0;
|
||||
|
||||
background-clip: text;
|
||||
}
|
||||
.link-section{
|
||||
position: absolute;
|
||||
right: 200px;
|
||||
top: 10px;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
font-family: 'Courier New', monospace;
|
||||
a{
|
||||
margin-left: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.sub-title {
|
||||
font-size: 10px;
|
||||
|
||||
|
||||
@@ -1,259 +0,0 @@
|
||||
<!--
|
||||
* @Descripttion: 大屏设计器 -- 预览
|
||||
* @Author: Devli
|
||||
* @Date: 2021-3-13 11:04:24
|
||||
* @Last Modified by: Raod
|
||||
* @Last Modified time: 2022-5-6 11:04:24
|
||||
!-->
|
||||
<template>
|
||||
<div class="layout">
|
||||
<div :style="bigScreenStyle" class="drillDrownViewLayout">
|
||||
<!-- 关键优化 1: v-if 包裹整个渲染区域,避免空数据时渲染 -->
|
||||
<template v-if="dataLoaded">
|
||||
<!-- 关键优化 2: 分批渲染,避免一次性创建过多 DOM 节点 -->
|
||||
<static-content :dashboard="dashboard"></static-content>
|
||||
</template>
|
||||
</div>
|
||||
<el-dialog :title="''" class="dialogDrillDrown dialogDrillDrownView" :visible.sync="visiableDrillView">
|
||||
<drill-drown-view :screenData="screenData"></drill-drown-view>
|
||||
</el-dialog>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import staticContent from "./components/saleStatic";
|
||||
import DrillDrownView from "./drillDrownView";
|
||||
|
||||
import { detailDashboard } from "@/api/bigscreen";
|
||||
export default {
|
||||
name: "Login",
|
||||
components: {
|
||||
staticContent,
|
||||
DrillDrownView
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
bigScreenStyle: {},
|
||||
dashboard:{},
|
||||
widgets: [],
|
||||
screenData:{
|
||||
dashboard: { },
|
||||
widgets: []
|
||||
},
|
||||
visiableDrillView:false,
|
||||
dataLoaded: false, // 数据加载标志
|
||||
refreshTimer: null, // 定时刷新定时器
|
||||
renderBatches: [], // 分批渲染的批次
|
||||
batchSize: 10, // 每批渲染的组件数量 (轻量级)
|
||||
renderTimer: null, // 分批渲染定时器
|
||||
renderedCount: 0 // 已渲染的组件数量
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.getData();
|
||||
window.onresize=this.Debounce(this.setScale,500);
|
||||
},
|
||||
beforeDestroy() {
|
||||
console.log('[Viewer] beforeDestroy 开始清理资源');
|
||||
|
||||
// 1. 清除定时刷新定时器
|
||||
if (this.refreshTimer) {
|
||||
clearTimeout(this.refreshTimer);
|
||||
this.refreshTimer = null;
|
||||
console.log('[Viewer] 已清除定时刷新定时器');
|
||||
}
|
||||
|
||||
// 2. 清除分批渲染定时器
|
||||
if (this.renderTimer) {
|
||||
clearTimeout(this.renderTimer);
|
||||
this.renderTimer = null;
|
||||
console.log('[Viewer] 已清除分批渲染定时器');
|
||||
}
|
||||
|
||||
// 3. 清空大型数据引用,释放内存
|
||||
this.widgets = [];
|
||||
this.renderBatches = [];
|
||||
this.dashboard = {};
|
||||
this.screenData = { dashboard: {}, widgets: [] };
|
||||
|
||||
// 4. 移除 window 事件监听
|
||||
if (window.onresize) {
|
||||
window.onresize = null;
|
||||
}
|
||||
|
||||
console.log('[Viewer] 资源清理完成');
|
||||
},
|
||||
|
||||
methods: {
|
||||
oepnTheDrillView(val){
|
||||
this.screenData=val
|
||||
this.visiableDrillView=true
|
||||
},
|
||||
async getData() {
|
||||
try {
|
||||
const reportCode = 'salesAnalysis2026';
|
||||
const { code, data } = await detailDashboard(reportCode);
|
||||
if (code != 200) {
|
||||
console.error('[Viewer] 获取大屏数据失败:', code);
|
||||
return;
|
||||
}
|
||||
|
||||
this.dashboard = data.dashboard || {};
|
||||
const equipment = document.body.clientWidth;
|
||||
const ratioEquipment = equipment / data.dashboard.width;
|
||||
const ratioEquipmentHeight = window.innerHeight / data.dashboard.height;
|
||||
this.bigScreenStyle = {
|
||||
width: data.dashboard.width + "px",
|
||||
height: data.dashboard.height + "px",
|
||||
"background-color": data.dashboard.backgroundColor,
|
||||
"background-image": "url(" + data.dashboard.backgroundImage + ")",
|
||||
"background-position": "0% 0%",
|
||||
"background-size": "100% 100%",
|
||||
"background-repeat": "initial",
|
||||
"background-attachment": "initial",
|
||||
"background-origin": "initial",
|
||||
"background-clip": "initial",
|
||||
transform: `scale(${ratioEquipment}, ${ratioEquipmentHeight})`,
|
||||
"transform-origin": "0 0"
|
||||
};
|
||||
|
||||
// 关键优化:冻结组件数据,避免 Vue 的响应式系统占用大量内存
|
||||
const frozenWidgets = Object.freeze(data.dashboard.widgets.map((item, index) => {
|
||||
item.value.widgetId = item.value.setup.widgetId;
|
||||
item.value.widgetCode = item.value.setup.widgetCode;
|
||||
if (item.value.setup.componentLinkage && item.value.setup.componentLinkage.length) {
|
||||
this.$store.commit('SET_ALL_COMPONENT_LINKAGE', {
|
||||
index,
|
||||
widgetId: item.value.widgetId,
|
||||
linkageArr: item.value.setup.componentLinkage
|
||||
});
|
||||
}
|
||||
return item;
|
||||
}));
|
||||
|
||||
// 赋值给 widgets 用于分批渲染
|
||||
this.widgets = frozenWidgets;
|
||||
|
||||
console.log(`[Viewer] 数据加载完成,共 ${this.widgets.length} 个组件,开始分批渲染`);
|
||||
|
||||
// 标记数据已加载
|
||||
this.dataLoaded = true;
|
||||
|
||||
// 开始分批渲染组件
|
||||
this.startBatchRender();
|
||||
|
||||
// 定时刷新 - 保存定时器引用以便清理
|
||||
if(data.dashboard.refreshSeconds > 0) {
|
||||
this.refreshTimer = setTimeout(() => {
|
||||
console.log('[Viewer] 定时刷新触发');
|
||||
window.location.reload();
|
||||
}, data.dashboard.refreshSeconds * 1000);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('[Viewer] 获取数据异常:', error);
|
||||
this.dataLoaded = false;
|
||||
}
|
||||
},
|
||||
Debounce:(fn,t)=>{
|
||||
const delay=t||500;
|
||||
let timer=null;
|
||||
return(...args)=>{
|
||||
if(timer){
|
||||
clearTimeout(timer);
|
||||
}
|
||||
const context=this
|
||||
timer=setTimeout(()=>{
|
||||
fn.apply(context,args);
|
||||
},delay);
|
||||
}
|
||||
},
|
||||
setScale(){
|
||||
const scale=this.getScale();
|
||||
// this.bigScreenStyle.transform='scale('+scale.scalex+','+scale.scaley+')'
|
||||
this.bigScreenStyle.transform = `scale(${scale.scalex},${scale.scaley})`
|
||||
},
|
||||
getScale(){
|
||||
let width = this.dashboard.width
|
||||
let height = this.dashboard.height
|
||||
// 固定宽度比例
|
||||
const scalex = window.innerWidth / width
|
||||
// // 高度按相同比例缩放,但允许超出屏幕高度
|
||||
// const scaley = scalex
|
||||
// 高度按屏幕高度比例
|
||||
const scaley = window.innerHeight / height
|
||||
|
||||
return {
|
||||
scalex,
|
||||
scaley
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 分批渲染组件,避免一次性创建过多 DOM 节点导致页面卡顿
|
||||
*/
|
||||
startBatchRender() {
|
||||
this.renderedCount = 0;
|
||||
this.renderBatches = [];
|
||||
|
||||
const renderNextBatch = () => {
|
||||
if (this.renderedCount >= this.widgets.length) {
|
||||
console.log('[Viewer] 所有组件渲染完成,总数:', this.widgets.length);
|
||||
return;
|
||||
}
|
||||
|
||||
// 计算本批次要渲染的组件
|
||||
const start = this.renderedCount;
|
||||
const end = Math.min(start + this.batchSize, this.widgets.length);
|
||||
|
||||
// 使用 slice 创建新批次,避免引用原数组
|
||||
const batch = Object.freeze(this.widgets.slice(start, end));
|
||||
|
||||
// 添加到渲染批次
|
||||
this.renderBatches.push(batch);
|
||||
this.renderedCount = end;
|
||||
|
||||
console.log(`[Viewer] 渲染第 ${this.renderBatches.length} 批,组件 ${start}-${end-1}`);
|
||||
|
||||
// 继续渲染下一批
|
||||
if (this.renderedCount < this.widgets.length) {
|
||||
this.renderTimer = setTimeout(renderNextBatch, 100); // 每批间隔 100ms
|
||||
}
|
||||
};
|
||||
|
||||
// 开始渲染第一批
|
||||
renderNextBatch();
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.layout {
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
text-align: center;
|
||||
}
|
||||
.dialogDrillDrownView .el-dialog{
|
||||
width:auto;
|
||||
margin-top:0 !important;
|
||||
transform: scale(0.6, 0.6);
|
||||
.el-dialog__body{
|
||||
padding:0;
|
||||
max-height:calc(100vh - 34px);
|
||||
overflow:auto;
|
||||
&::-webkit-scrollbar {
|
||||
display: none; /* 隐藏滚动条 */
|
||||
}
|
||||
}
|
||||
.el-dialog__header .el-dialog__headerbtn{
|
||||
top: 6px;
|
||||
}
|
||||
}
|
||||
.bottom-text {
|
||||
width: 100%;
|
||||
color: #a0a0a0;
|
||||
position: fixed;
|
||||
bottom: 16px;
|
||||
z-index: 9999;
|
||||
}
|
||||
</style>
|
||||
@@ -146,15 +146,15 @@ export default {
|
||||
//获取url传参 ticket url
|
||||
const ticket = this.$route.query.ticket;
|
||||
let token = getToken();
|
||||
// console.log(ticket);
|
||||
// console.log(token);
|
||||
// this.logincasapi();
|
||||
console.log(ticket);
|
||||
console.log(token);
|
||||
if (ticket == undefined && token == null) {
|
||||
//跳转统一身份认证
|
||||
var isTs = true;
|
||||
if (isTs) {
|
||||
window.location.href = 'http://192.168.1.241/login?redirect=/lig/oauth2/oauth2/application&appid=330b4ecb60c9a6802b957fe1e5a5ecd3&url=http%3A%2F%2F192.168.1.241%3A8080%2F%23%2Flogin'+(this.redirect?'&ssUrl='+this.redirect:'');
|
||||
// window.location.href = 'http://localhost/login?redirect=/lig/oauth2/oauth2/application&appid=330b4ecb60c9a6802b957fe1e5a5ecd3&url=http%3A%2F%2Flocalhost%3A9528%2F%23%2Flogin'+(this.redirect?'&ssUrl='+this.redirect:'');
|
||||
|
||||
}
|
||||
} else if (ticket != undefined && token == null) {
|
||||
//请求登录
|
||||
|
||||
Reference in New Issue
Block a user