diff --git a/src/views/bigscreenDesigner/viewer/components/static.vue b/src/views/bigscreenDesigner/viewer/components/static.vue index bc60a92..2c85120 100644 --- a/src/views/bigscreenDesigner/viewer/components/static.vue +++ b/src/views/bigscreenDesigner/viewer/components/static.vue @@ -27,7 +27,7 @@ 同比 - {{ stat.change }} + {{ stat.change }}% @@ -39,64 +39,34 @@
-
- 碳中和比率 +
+ + 生产数据分析 + +
-
-
-
能耗分布结构
-
+
-
任务时间安排
-
-
-
-
- 碳中和进度 - 60% -
-
- 年减排目标 - 254.50t +
+
- 产销协同 + 主要产品销售情况(毛利率) - +
-
-
- - 生产 - 35% -
-
- - 动力 - 28% -
-
- - 照明 - 22% -
-
- - 空调 - 15% -
-
+
@@ -129,59 +99,48 @@
- 财务分析 + 产销协同
+
+
+
产销率
+
{{peakData['产销率']}}%
+
周转率
+
{{peakData['周转率']}}%
+
+
+
平均交付周期
+
{{peakData['平均交付周期']}}天
+
订单准时率
+
{{peakData['订单准时率']}}
+
+
+
- 市场分析 -
- - - -
+ + 产能分析 +
+ 销售收入排行 +
-
+
+ 单位:万
-
-
- - 生产 - 254.50 -
-
- - 动力 - 180.30 -
-
- - 照明 - 125.60 -
-
- - 空调 - 98.20 -
-
- - 其他 - 56.80 -
-
+
@@ -195,18 +154,21 @@ import * as echarts from 'echarts' import {getData} from '@/api/bigscreen' export default { name: 'EnergyPlatform', + props: { + dashboard: { + type: Object, + default: ()=>{} + } + }, data() { return { currentTime: '', trendTab: '7', charts: {}, powerData: [], + peakData: {}, topStats: [ - { value: '2425', unit: 'kw.h', label: '当日用电量', change: '+12%', changeType: 'up' }, - { value: '101441', unit: 'kw.h', label: '当月用电量', change: '+24%', changeType: 'up' }, - { value: '987414', unit: 'kw.h', label: '当年用电量', change: '+28%', changeType: 'up' }, - { value: '2425', unit: 't', label: '当日用水量', change: '+31%', changeType: 'up' }, - + ] } }, @@ -221,6 +183,7 @@ export default { }, 1000) this.getPowerData() this.getTopStatsData() + this.getPeakData() }, beforeDestroy() { window.removeEventListener('resize', this.handleResize) @@ -229,6 +192,29 @@ export default { }) }, methods: { + 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"}} + const {code, data} = await getData(params); + const res = await getData(params2); + if(code != 200){ + console.error('[Viewer] 获取大屏数据失败:', code); + return; + } + this.peakData ={ + '产销率' :data[0]['本年产销率'], + '周转率' : data[0]['本年存货周转率'], + '订单准时率' : res.data[0]['平均销售交付周期_天'], + } + const {widgets} = this.dashboard + if(widgets && widgets.length > 0){ + widgets.forEach(widget => { + if(widget.value.widgetId === "fiauqt0od7"){ + this.peakData['订单准时率'] = widget.value.setup.text+widget.value.setup.joinText + } + }) + } + }, async getPowerData(){ let params={"chartProperties":{"dzr":"text"},"setCode":"nhsj","chartType":"widget-text","contextData":{"reportCode":"ddddd"}} const {code, data} = await getData(params); @@ -248,9 +234,14 @@ export default { async getTopStatsData(){ let params={"chartProperties":{"营收":"text"},"setCode":"zp_zb","chartType":"widget-text","contextData":{"reportCode":"ddddd"}} let paramsTb={"chartProperties":{"本月毛利同比_百分比":"text"},"setCode":"ben_maoli_tongbi","chartType":"widget-text","contextData":{"reportCode":"ddddd"}} + let paramsTb2={"chartProperties":{"本年毛利":"text","本年营业额":"text"},"setCode":"local_year","chartType":"widget-text","contextData":{"reportCode":"ddddd"}} + let paramsKcje={"chartProperties":{"库存金额":"text"},"setCode":"zp_kcje","chartType":"widget-text","contextData":{"reportCode":"ddddd"}} + let paramsCxxtZb={"chartProperties":{"本年存货周期":"text"},"setCode":"zp_cxxt_zb","chartType":"widget-text","contextData":{"qyear":"2026","reportCode":"ddddd"}} const {code, data} = await getData(params); const res = await getData(paramsTb); - + const res2 = await getData(paramsTb2); + const res3 = await getData(paramsKcje); + const res4 = await getData(paramsCxxtZb); if(code != 200){ console.error('[Viewer] 获取大屏数据失败:', code); return; @@ -260,10 +251,13 @@ export default { "本月毛利": '万', "负债总额": '亿元', "资产总额": '亿元', + '库存金额': '万', + '存货周期': '天', } - const tbChange = {'本月毛利':res.data[0]['本月毛利同比_百分比']} + const tbChange = {'本月毛利':res.data[0]['本月毛利同比_百分比'],'营收':res2.data[0]['本年营业额']} + this.topStats = Object.keys(topStatsUnit).map((item) => ({ - value: data[0][item], + value: data[0][item]||res3.data[0][item]||res4.data[0]['本年'+item], unit: topStatsUnit[item], label: item, change:tbChange[item], @@ -381,9 +375,30 @@ export default { initGanttChart() { if (!this.$refs.ganttChart) return const chart = echarts.init(this.$refs.ganttChart) - - const values = [947, 340, 36] - + + let yData = [] + const {widgets} = this.dashboard + const values=[] + let seriesData=[] + let colors=[] + if(widgets && widgets.length > 0){ + widgets.forEach(widget => { + if(widget.value.widgetId === "24q62cb3ywe"){ + yData=[...new Set(widget.value.data.staticData.map(item => item.axis))] + seriesData=[...new Set(widget.value.data.staticData.map(item => item.name))].map(item=>{return {name:item,values:[],axis:[]}}) + colors=widget.value.setup.customColor.map(item=>item.color) + widget.value.data.staticData.forEach(item=>{ + seriesData.forEach(series=>{ + if(series.name===item.name){ + series.values.push(item.data) + series.axis.push(item.axis) + } + }) + + }) + } + }) + } const option = { backgroundColor: 'transparent', tooltip: { @@ -391,23 +406,35 @@ export default { backgroundColor: 'rgba(15, 42, 66, 0.9)', borderColor: '#61c8ee', textStyle: { color: '#fff' }, - formatter: '{b}: {c}' + formatter: (params) => { + let result = `${params.seriesName}
`; + seriesData.forEach((series,index1)=>{ + series.values.forEach((item,index)=>{ + if(series.axis[index]===params.name){ + result += ` + ${series.name}:${item}万元
`; + } + }) + + }) + return result; + } }, grid: { - left: '15%', - right: '25%', - top: '10%', - bottom: '10%', + left: '0', + right:'0', + top:'0', + bottom: '0', containLabel: true }, xAxis: { type: 'value', show: false, - max: 100 + max: 2000 }, yAxis: { type: 'category', - data: ['照明', '动力', '生产'], + data: yData, axisLine: { show: false }, axisTick: { show: false }, axisLabel: { @@ -417,108 +444,148 @@ export default { } }, graphic: [ - { - type: 'text', - left: '80%', - top: '12%', - style: { - text: '36', - fill: '#fff', - fontSize: 16, - fontWeight: 'bold' + + ], + series: [ + ] + } + option.series=seriesData.map((item,index)=>{ + return { + type: 'bar', + stack: 'total', + barWidth: 8, + itemStyle: { + color: colors[index], + + }, + data: item.values, + name: item.name, + } + }) + chart.setOption(option) + this.charts.gantt = chart + }, + + async initRoseChart() { + if (!this.$refs.roseChart) return + const chart = echarts.init(this.$refs.roseChart) + let dates = [] + let lineData = [] + let barData = [] + let barData2=[] + + let params={"chartProperties":{"本年累计毛利(万)":"bar","毛利同比变动":"line","去年累计毛利(万)":"bar","货品名称":"xAxis"},"setCode":"zhuyao_maoli_zongcang","chartType":"widget-barlinechart","contextData":{"startTime":"","endTime":"","reportCode":"ddddd"}} + const {code,data}=await getData(params) + if(code!=200){ + return + } + console.log(data) + dates=data.map(item=>{return item['货品名称']}) + lineData=data.map(item=>{return item['毛利同比变动']}) + barData=data.map(item=>{return item['去年累计毛利(万)']}) + barData2=data.map(item=>{return item['本年累计毛利(万)']}) + const option = { + backgroundColor: 'transparent', + tooltip: { + trigger: 'axis', + backgroundColor: 'rgba(15, 42, 66, 0.9)', + borderColor: '#61c8ee', + textStyle: { color: '#fff' } + }, + grid: { + left: '8%', + right: '3%', + top: '12%', + bottom: '12%', + containLabel: true + }, + xAxis: { + type: 'category', + data: dates, + + axisLine: { lineStyle: { color: 'rgba(107, 140, 174, 0.3)' } }, + axisTick: { show: false }, + axisLabel: { + color: '#cccccc', + hideOverlap: false, + interval: 0, + fontSize: 12, + margin: 8, + // 👇 核心:超出自动省略 + 鼠标悬浮显示完整 + formatter: function (value) { + if (value.length > 5) { + return value.slice(0,5) + '...'; + } + return value; } }, + }, + yAxis: [ { - type: 'text', - left: '80%', - top: '45%', - style: { - text: '340', - fill: '#fff', - fontSize: 16, - fontWeight: 'bold' - } + type: 'value', + position: 'left', + splitLine: { lineStyle: { color: 'rgba(107, 140, 174, 0.1)' } }, + axisLine: { show: false }, + axisTick: { show: false }, + axisLabel: { color: '#6b8cae', fontSize: 8 } }, { - type: 'text', - left: '80%', - top: '78%', - style: { - text: '947', - fill: '#fff', - fontSize: 16, - fontWeight: 'bold' - } + type: 'value', + position: 'right', + splitLine: { show: false }, + axisLine: { show: false }, + axisTick: { show: false }, + axisLabel: { color: '#6b8cae', fontSize: 8 } } ], series: [ { type: 'bar', - stack: 'total', - barWidth: 18, + name: '本年累计毛利', + data: barData2, + yAxisIndex: 0, itemStyle: { - color: '#ff4d4f', - borderRadius: [0, 0, 0, 0] + color: { + type: 'linear', + x: 0, y: 0, x2: 0, y2: 1, + colorStops: [ + { offset: 0, color: 'rgba(255,127,80, 1)' }, + { offset: 1, color: 'rgba(255,127,80, 0.1)' } + ] + }, + borderRadius: [3, 3, 0, 0] }, - data: [10, 8, 15] + barWidth: 7 }, { type: 'bar', - stack: 'total', - barWidth: 18, + name: '去年累计毛利', + data: barData, + yAxisIndex: 0, itemStyle: { - color: '#ff9f43', - borderRadius: [0, 0, 0, 0] + color: { + type: 'linear', + x: 0, y: 0, x2: 0, y2: 1, + colorStops: [ + { offset: 0, color: 'rgba(24, 144, 255, 1)' }, + { offset: 1, color: 'rgba(24, 144, 255, 0.1)' } + ] + }, + borderRadius: [3, 3, 0, 0] }, - data: [5, 3, 5] + barWidth: 7 }, + { - type: 'bar', - stack: 'total', - barWidth: 18, - itemStyle: { - color: '#1890ff', - borderRadius: [0, 4, 4, 0] - }, - data: [85, 89, 80] - } - ] - } - - chart.setOption(option) - this.charts.gantt = chart - }, - - initRoseChart() { - if (!this.$refs.roseChart) return - const chart = echarts.init(this.$refs.roseChart) - const option = { - backgroundColor: 'transparent', - tooltip: { - trigger: 'item', - backgroundColor: 'rgba(15, 42, 66, 0.9)', - borderColor: '#61c8ee', - textStyle: { color: '#fff' }, - formatter: '{b}: {c}%' - }, - series: [ - { - type: 'pie', - radius: ['10%', '70%'], - center: ['50%', '50%'], - roseType: 'area', - itemStyle: { - borderRadius: 4, - borderColor: 'rgba(15, 42, 66, 1)', - borderWidth: 2 - }, - label: { show: false }, - data: [ - { value: 35, name: '生产', itemStyle: { color: '#1890ff' } }, - { value: 28, name: '动力', itemStyle: { color: '#73d5ff' } }, - { value: 22, name: '照明', itemStyle: { color: '#b3e0ff' } }, - { value: 15, name: '空调', itemStyle: { color: '#d9edff' } } - ] + type: 'line', + name: '毛利同比变动', + data: lineData, + smooth: true, + yAxisIndex: 1, + itemStyle: { color: '#ff4d4f' }, + lineStyle: { width: 2 }, + symbol: 'circle', + symbolSize: 3 } ] } @@ -529,23 +596,26 @@ export default { initScatterChart() { if (!this.$refs.scatterChart) return const chart = echarts.init(this.$refs.scatterChart) - const hours = Array.from({ length: 24 }, (_, i) => `${i}`) - const scatterData = [] + let hours = [] - for (let i = 0; i < 30; i++) { - const hour = Math.floor(Math.random() * 24) - const value = Math.random() * 60 + 40 - let size = value / 8 - let color - if (size > 10) { - color = '#1890ff' - } else if (size > 6) { - color = '#73d5ff' - } else { - color = '#ff4d4f' - } - scatterData.push([hour, 50, size, color]) + let scatterData = [] + let lineData = [] + const {widgets} = this.dashboard + const colors={ + 50:'#1890ff', + 60:'#73d5ff', + 70:'#ff4d4f', } + if(widgets && widgets.length > 0){ + widgets.forEach(widget => { + if(widget.value.widgetId === "1vsidsxecdg"){ + lineData = widget.value.data.staticData.map(item => item.line) + hours=widget.value.data.staticData.map(item => item.axis) + scatterData = widget.value.data.staticData.map(item => [item.axis, 50, (item.bar/5).toFixed(2), colors[item.bar > 70 ? 70 : item.bar > 60 ? 60 : 50]]) + } + }) + } + const option = { backgroundColor: 'transparent', @@ -555,14 +625,33 @@ export default { borderColor: '#61c8ee', textStyle: { color: '#fff' }, formatter: (params) => { - return `时间: ${params.value[0]}:00
功率: ${params.value[2].toFixed(2)} kw` + // params 是当前鼠标所在的系列数据(散点 或 折线) + // 获取当前 X 轴坐标索引 + const dataIndex = params.dataIndex; + + // // 从图表实例中拿到所有系列的原始数据 + const scatterVal = parseFloat((scatterData[dataIndex][2]*5).toFixed(2)); // 散点数据 + const scatterColor = scatterData[dataIndex] ? scatterData[dataIndex][3] : '#ccc'; + const lineVal = lineData[dataIndex]; // 折线数据 + const lineColor = '#ff4d4f'; + const hour = hours[dataIndex]; // X轴时间 + let result = `${hour}
`; + if (scatterVal) { + result += ` + 毛利:${scatterVal}万元
`; + } + + // // 显示折线(净利润)信息 + result += `净利润:${lineVal ? lineVal : '--'}万元`; + + return result; } }, grid: { - left: '12%', - right: '3%', - top: '5%', - bottom: '15%', + left: '0', + right: '0', + top: '0', + bottom: '0', containLabel: true }, xAxis: { @@ -570,7 +659,7 @@ export default { data: hours, axisLine: { lineStyle: { color: 'rgba(107, 140, 174, 0.3)' } }, axisTick: { show: false }, - axisLabel: { color: '#6b8cae', fontSize: 8, interval: 3 } + axisLabel: { color: '#fff', fontSize: 14, } }, yAxis: { type: 'value', @@ -581,14 +670,26 @@ export default { { type: 'scatter', data: scatterData, + name:'毛利', symbolSize: (val) => val[2] * 2, itemStyle: { color: (params) => params.value[3], opacity: 0.85 } + }, + { + type: 'line', + name: '净利利润', + data: lineData, + smooth: true, + itemStyle: { color: '#ff4d4f' }, + lineStyle: { width: 2 }, + symbol: 'circle', + symbolSize: 3 } ] } + chart.setOption(option) this.charts.scatter = chart }, @@ -676,21 +777,19 @@ export default { this.charts.trend = chart }, - initParkChart() { + async initParkChart() { if (!this.$refs.parkChart) return const chart = echarts.init(this.$refs.parkChart) - - const parkData = [ - { name: '园区2#', value: 1000 }, - { name: '园区3#', value: 720 }, - { name: '园区4#', value: 610 }, - { name: '园区5#', value: 500 }, - { name: '园区6#', value: 430 }, - { name: '园区7#', value: 310 }, - { name: '园区8#', value: 220 }, - { name: '园区9#', value: 130 } - ] - + const params ={"chartProperties":{},"setCode":"xssrph","chartType":"widget-table","contextData":{"month":"3","year":"2026","pageSize":"20","currentPage":"1","reportCode":"ddddd"}} + const {code,data} = await getData(params); + if(code != 200){ + console.error('[Viewer] 获取大屏数据失败:', code); + return; + } + const parkData = data.map(d => ({ + name: d.hpmc, + value: d.xse + })).splice(0, 10) const option = { backgroundColor: 'transparent', tooltip: { @@ -698,18 +797,19 @@ export default { backgroundColor: 'rgba(15, 42, 66, 0.95)', borderColor: '#61c8ee', textStyle: { color: '#fff' }, - formatter: '{b}: {c}' + formatter: '{b}: {c}万' }, grid: { - left: '8%', - right: '28%', - bottom: '15%', - top: '8%', + left: '0', + right: '0', + bottom: '0', + top: '0', containLabel: true }, xAxis: { type: 'category', data: parkData.map(d => d.name), + axisLine: { lineStyle: { color: '#555' @@ -718,23 +818,62 @@ export default { axisTick: { show: false }, axisLabel: { color: '#cccccc', + hideOverlap: false, + interval: 0, fontSize: 12, - margin: 8 - } + margin: 8, + // 👇 核心:超出自动省略 + 鼠标悬浮显示完整 + formatter: function (value) { + if (value.length > 3) { + return value.slice(0,3) + '...'; + } + return value; + } + }, + axisPointer: { + show: true + }, + dataZoom: [ + { + type: 'slider', // 底部滑动条 + show: false, // 隐藏滑动条(只保留滚动能力) + xAxisIndex: [0], + start: 0, + end: 100 + }, + { + type: 'inside', // 内置滚动(鼠标滚轮/拖拽滚动) + xAxisIndex: [0], + start: 0, + end: 100, + zoomLock: true // 禁止缩放,只允许滚动 + } + ] }, yAxis: { type: 'value', - show: false, - max: 1200 + show: true, + max: parkData[0].value+300, + + splitLine: { + show: true, + lineStyle: { + color: 'rgba(255, 255, 255, 0.15)', // 柔和的浅色线(可改颜色) + width: 1, + type: 'solid' + } + } }, series: [ { - name: '能耗', + name: '销售额', type: 'pictorialBar', symbol: 'diamond', - symbolSize: ['70%', '100%'], + symbolSize: ['180%', '100%'], symbolPosition: 'end', - symbolOffset: [0, '50%'], + + symbolRepeat: false, + symbol: 'path://M0,0 Q-5,85 -50,100 L50,100 Q5,85 0,0 Z', itemStyle: { color: { type: 'linear', @@ -749,8 +888,7 @@ export default { show: true, position: 'top', color: '#ff6f46', - fontSize: 14, - fontWeight: 'bold', + fontSize: 10, formatter: '{c}' }, data: parkData.map(d => d.value) @@ -872,9 +1010,9 @@ export default { } .stats-grid { - display: grid; - grid-template-columns: repeat(4, 1fr); - gap: 15px; + display: flex; + justify-content: space-between; + } .stat-item { @@ -916,7 +1054,7 @@ export default { border: 1px solid #fff; } .stat-item .stat-change { - font-size: 10px; + font-size: 12px; font-weight: bold; padding: 2px 6px; border-radius: 10px; @@ -1005,7 +1143,12 @@ export default { background: rgba(97, 200, 238, 0.3); color: #fff; } - +.carbon-card{ + background: rgb(32, 37, 43); + border: 2px solid rgb(49, 56, 66); + border-radius: 5px; + border-bottom: 0; +} .carbon-content { display: flex; height: 170px; @@ -1059,7 +1202,11 @@ export default { font-weight: bold; color: #fff; } - +.energy-card{ + background: rgb(32, 37, 43); + border: 2px solid rgb(49, 56, 66); + border-radius: 5px; +} .energy-content { display: flex; height: 200px; @@ -1174,10 +1321,39 @@ export default { border-radius-bottom-right: 5px; border-top: 0; margin-bottom: 15px; + .peak-desc{ + display: flex; + color: #fff; + padding: 10px 15px; + .desc-item{ + flex: 1; + align-items: flex-start; + line-height: 1.5; + .desc-label{ + text-align:left; + font-size: 14px; + color: #fff; + } + .desc-value{ + font-size: 20px; + } + } + } } .peak-content { display: flex; - flex-direction: column; + padding: 0 15px ; + align-items: center; + .peak-cai-icon{ + font-size: 26px; + color: #fff; + border: 1px solid #fff; + height: 60px; + width: 60px; + line-height: 58px; + text-align: center; + + } } .peak-stats { @@ -1189,7 +1365,11 @@ export default { font-weight: bold; color: #1890ff; } - +.park-card{ + background: rgb(32, 37, 43); + border: 2px solid rgb(49, 56, 66); + border-radius: 5px; +} .peak-unit { font-size: 12px; color: #6b8cae; @@ -1219,10 +1399,16 @@ export default { } .scatter-chart { - height: 70px; + height: 120px; padding: 0 10px 10px; + width: calc(100% - 60px); +} +.trend-card{ + background: rgb(32, 37, 43); + border: 2px solid rgb(49, 56, 66); + border-radius: 5px; + margin-bottom: 15px; } - .trend-tabs { gap: 3px; } @@ -1240,6 +1426,7 @@ export default { .park-chart { flex: 1; height: 160px; + width: 100%; } .park-legend { diff --git a/src/views/bigscreenDesigner/viewer/static.vue b/src/views/bigscreenDesigner/viewer/static.vue index 4b24742..afeeca2 100644 --- a/src/views/bigscreenDesigner/viewer/static.vue +++ b/src/views/bigscreenDesigner/viewer/static.vue @@ -11,7 +11,7 @@
@@ -94,7 +94,6 @@ export default { try { const reportCode = 'demotest'; const { code, data } = await detailDashboard(reportCode); - console.log(data) if (code != 200) { console.error('[Viewer] 获取大屏数据失败:', code); return;