生产监控看板
This commit is contained in:
parent
2c1e1845f4
commit
446fa9a0d1
@ -21,6 +21,7 @@ import {
|
|||||||
handleTree,
|
handleTree,
|
||||||
addBeginAndEndTime,
|
addBeginAndEndTime,
|
||||||
divide,
|
divide,
|
||||||
|
formatThousands
|
||||||
} from '@/utils/ruoyi';
|
} from '@/utils/ruoyi';
|
||||||
import Pagination from '@/components/Pagination';
|
import Pagination from '@/components/Pagination';
|
||||||
// 自定义表格工具扩展
|
// 自定义表格工具扩展
|
||||||
@ -45,6 +46,7 @@ Vue.prototype.resetForm = resetForm;
|
|||||||
Vue.prototype.getDictDatas = getDictDatas;
|
Vue.prototype.getDictDatas = getDictDatas;
|
||||||
Vue.prototype.getDictDatas2 = getDictDatas2;
|
Vue.prototype.getDictDatas2 = getDictDatas2;
|
||||||
Vue.prototype.getDictDataLabel = getDictDataLabel;
|
Vue.prototype.getDictDataLabel = getDictDataLabel;
|
||||||
|
Vue.prototype.formatThousands = formatThousands;
|
||||||
Vue.prototype.DICT_TYPE = DICT_TYPE;
|
Vue.prototype.DICT_TYPE = DICT_TYPE;
|
||||||
Vue.prototype.handleTree = handleTree;
|
Vue.prototype.handleTree = handleTree;
|
||||||
Vue.prototype.addBeginAndEndTime = addBeginAndEndTime;
|
Vue.prototype.addBeginAndEndTime = addBeginAndEndTime;
|
||||||
|
@ -295,3 +295,15 @@ export function getPath(path) {
|
|||||||
}
|
}
|
||||||
return Math.floor(divisor/dividend*100)/100;
|
return Math.floor(divisor/dividend*100)/100;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 通用千分位格式化函数
|
||||||
|
export function formatThousands(value) {
|
||||||
|
if (value === null || value === undefined) return '0'
|
||||||
|
|
||||||
|
// 清理已有逗号并转为数字
|
||||||
|
const numValue = Number(String(value).replace(/,/g, ''))
|
||||||
|
if (isNaN(numValue)) return '0'
|
||||||
|
|
||||||
|
// 支持小数处理
|
||||||
|
return numValue.toLocaleString('en-US')
|
||||||
|
}
|
@ -7,18 +7,20 @@
|
|||||||
<div class='dataBox' style='top:50px'>
|
<div class='dataBox' style='top:50px'>
|
||||||
<p>
|
<p>
|
||||||
<span class='text'>总投入片数</span>
|
<span class='text'>总投入片数</span>
|
||||||
<span class='precent precentG'>-18%</span>
|
<span class='precent' :class='{precentR:monthData?.inputNumChange>=0,precentG:monthData?.inputNumChange<0}'>{{monthData?.inputNumChange || '-'}}%</span>
|
||||||
<img src="../../../../assets/images/dataBoard/arrDown.png" alt="" width='5' height='15'>
|
<img v-show='monthData?.inputNumChange<0' src="../../../../assets/images/dataBoard/arrDown.png" alt="" width='5' height='15'>
|
||||||
|
<img v-show='monthData?.inputNumChange>=0' src="../../../../assets/images/dataBoard/arrUp.png" alt="" width='5' height='15'>
|
||||||
</p>
|
</p>
|
||||||
<p class='num'>261,938,984</p>
|
<p class='num'>{{monthData?.inputNum ? formatThousands(monthData.inputNum) : '-'}}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class='dataBox'style='top:180px'>
|
<div class='dataBox'style='top:180px'>
|
||||||
<p>
|
<p>
|
||||||
<span class='text'>总生产片数</span>
|
<span class='text'>总生产片数</span>
|
||||||
<span class='precent precentR'>+18%</span>
|
<span class='precent' :class='{precentR:monthData?.outputNumChange>=0,precentG:monthData?.outputNumChange<0}'>{{monthData?.outputNumChange || '-'}}%</span>
|
||||||
<img src="../../../../assets/images/dataBoard/arrUp.png" alt="" width='5' height='15'>
|
<img v-show='monthData?.outputNumChange<0' src="../../../../assets/images/dataBoard/arrDown.png" alt="" width='5' height='15'>
|
||||||
|
<img v-show='monthData?.outputNumChange>=0' src="../../../../assets/images/dataBoard/arrUp.png" alt="" width='5' height='15'>
|
||||||
</p>
|
</p>
|
||||||
<p class='num'>82,261,938,984</p>
|
<p class='num'>{{monthData?.outputNum ? formatThousands(monthData.outputNum) : '-'}}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -26,8 +28,25 @@
|
|||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: 'CenterBottomL',
|
name: 'CenterBottomL',
|
||||||
|
props: {
|
||||||
|
dataObj: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
dataObj(val) {
|
||||||
|
val.monthAndLastMonth && val.monthAndLastMonth.forEach(item => {
|
||||||
|
if (item.dataType === "本月") {
|
||||||
|
this.monthData = item
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {}
|
return {
|
||||||
|
monthData:{}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
methods: {}
|
methods: {}
|
||||||
}
|
}
|
||||||
|
@ -8,13 +8,13 @@
|
|||||||
<p>
|
<p>
|
||||||
<span class='text'>总投入片数</span>
|
<span class='text'>总投入片数</span>
|
||||||
</p>
|
</p>
|
||||||
<p class='num'>261,938,984</p>
|
<p class='num'>{{lastMonthData?.inputNum ? formatThousands(lastMonthData.inputNum) : '-'}}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class='dataBox'style='top:180px'>
|
<div class='dataBox'style='top:180px'>
|
||||||
<p>
|
<p>
|
||||||
<span class='text'>总生产片数</span>
|
<span class='text'>总生产片数</span>
|
||||||
</p>
|
</p>
|
||||||
<p class='num'>82,261,938,984</p>
|
<p class='num'>{{lastMonthData?.outputNum ? formatThousands(lastMonthData.outputNum) : '-'}}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -22,8 +22,25 @@
|
|||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: 'CenterBottomR',
|
name: 'CenterBottomR',
|
||||||
|
props: {
|
||||||
|
dataObj: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
dataObj(val) {
|
||||||
|
val.monthAndLastMonth && val.monthAndLastMonth.forEach(item => {
|
||||||
|
if (item.dataType === "上月") {
|
||||||
|
this.lastMonthData = item
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {}
|
return {
|
||||||
|
lastMonthData:{}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
methods: {}
|
methods: {}
|
||||||
}
|
}
|
||||||
|
@ -10,8 +10,20 @@
|
|||||||
<p><span class='eqTipTitle'>设备名称:</span><span class='eqTipNum'>{{eqTipMsg.name}}</span></p>
|
<p><span class='eqTipTitle'>设备名称:</span><span class='eqTipNum'>{{eqTipMsg.name}}</span></p>
|
||||||
<p><span class='eqTipTitle'>进口数量:</span><span class='eqTipNum'>{{eqTipMsg.input}}</span></p>
|
<p><span class='eqTipTitle'>进口数量:</span><span class='eqTipNum'>{{eqTipMsg.input}}</span></p>
|
||||||
<p><span class='eqTipTitle'>出口数量:</span><span class='eqTipNum'>{{eqTipMsg.output}}</span></p>
|
<p><span class='eqTipTitle'>出口数量:</span><span class='eqTipNum'>{{eqTipMsg.output}}</span></p>
|
||||||
<p><span class='eqTipTitle'>报警状态:</span><span class='eqTipNum'><img :src='dotY' width='16'/>{{eqTipMsg.alarm}}</span></p>
|
<p><span class='eqTipTitle'>报警状态:</span>
|
||||||
<p><span class='eqTipTitle'>在线状态:</span><span class='eqTipNum'><img :src='dotR' width='16'/>{{eqTipMsg.status}}</span></p>
|
<span class='eqTipNum'>
|
||||||
|
<img v-show='eqTipMsg.alarm' :src='dotY' width='16'/>
|
||||||
|
<img v-show='!eqTipMsg.alarm' :src='dotG' width='16'/>
|
||||||
|
{{eqTipMsg.alarm?'报警':'未报警'}}
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
<p><span class='eqTipTitle'>在线状态:</span>
|
||||||
|
<span class='eqTipNum'>
|
||||||
|
<img v-show='eqTipMsg.status' :src='dotG' width='16'/>
|
||||||
|
<img v-show='!eqTipMsg.status' :src='dotR' width='16'/>
|
||||||
|
{{eqTipMsg.status?'在线':'离线'}}
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<!-- 设备 -->
|
<!-- 设备 -->
|
||||||
<div class='eqBox'>
|
<div class='eqBox'>
|
||||||
@ -28,22 +40,22 @@
|
|||||||
<div class='centerTopTopBox'>
|
<div class='centerTopTopBox'>
|
||||||
<div style='display: inline-block;'>
|
<div style='display: inline-block;'>
|
||||||
<img src="../../../../assets/images/dataBoard/centerNumB.png" alt="" width='203'>
|
<img src="../../../../assets/images/dataBoard/centerNumB.png" alt="" width='203'>
|
||||||
<p class='num'>88%</p>
|
<p class='num'>{{dataObj?.productRate || '-'}}%</p>
|
||||||
<p class='title'>成品率</p>
|
<p class='title'>成品率</p>
|
||||||
</div>
|
</div>
|
||||||
<div style='display: inline-block;'>
|
<div style='display: inline-block;'>
|
||||||
<img src="../../../../assets/images/dataBoard/centerNumY.png" alt="" width='261'>
|
<img src="../../../../assets/images/dataBoard/centerNumY.png" alt="" width='261'>
|
||||||
<p class='num' style='width: 260px;padding-left: 20px;'>8,984</p>
|
<p class='num' style='width: 260px;padding-left: 20px;'>{{dataObj?.todayProduct ? formatThousands(dataObj.todayProduct) : '-'}}</p>
|
||||||
<p class='title' style='color:#FFB625'>今日产量</p>
|
<p class='title' style='color:#FFB625'>今日产量</p>
|
||||||
</div>
|
</div>
|
||||||
<div style='display: inline-block;'>
|
<div style='display: inline-block;'>
|
||||||
<img src="../../../../assets/images/dataBoard/centerNumY.png" alt="" width='261'>
|
<img src="../../../../assets/images/dataBoard/centerNumY.png" alt="" width='261'>
|
||||||
<p class='num' style='width: 260px;padding-left: 20px;'>12,948,984</p>
|
<p class='num' style='width: 260px;padding-left: 20px;'>{{dataObj?.monthProduct ? formatThousands(dataObj.monthProduct) : '-'}}</p>
|
||||||
<p class='title' style='color:#FFB625'>本月产量</p>
|
<p class='title' style='color:#FFB625'>本月产量</p>
|
||||||
</div>
|
</div>
|
||||||
<div style='display: inline-block;'>
|
<div style='display: inline-block;'>
|
||||||
<img src="../../../../assets/images/dataBoard/centerNumB.png" alt="" width='203'>
|
<img src="../../../../assets/images/dataBoard/centerNumB.png" alt="" width='203'>
|
||||||
<p class='num'>59</p>
|
<p class='num'>{{dataObj?.alarmNum ? formatThousands(dataObj.alarmNum) : '-'}}</p>
|
||||||
<p class='title'>设备报警数</p>
|
<p class='title'>设备报警数</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -59,7 +71,6 @@ export default {
|
|||||||
left: 0,
|
left: 0,
|
||||||
top: 0
|
top: 0
|
||||||
},
|
},
|
||||||
scaleNum:1,
|
|
||||||
dotY:require('../../../../assets/images/dataBoard/dotY.png'),
|
dotY:require('../../../../assets/images/dataBoard/dotY.png'),
|
||||||
dotR:require('../../../../assets/images/dataBoard/dotR.png'),
|
dotR:require('../../../../assets/images/dataBoard/dotR.png'),
|
||||||
dotG:require('../../../../assets/images/dataBoard/dotG.png'),
|
dotG:require('../../../../assets/images/dataBoard/dotG.png'),
|
||||||
@ -192,11 +203,29 @@ export default {
|
|||||||
scaleNum: {
|
scaleNum: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 1
|
default: 1
|
||||||
|
},
|
||||||
|
dataObj: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
scaleNum(val) {
|
scaleNum(val) {
|
||||||
this.scaleNum = val
|
this.scaleNum = val
|
||||||
|
},
|
||||||
|
dataObj(val) {
|
||||||
|
val.equipmentDets && val.equipmentDets.forEach(item => {
|
||||||
|
this.eqList.forEach(eq => {
|
||||||
|
if (eq.id == item.id) {
|
||||||
|
eq.name = item.name
|
||||||
|
eq.input = item.input
|
||||||
|
eq.output = item.output
|
||||||
|
eq.alarm = item.isError
|
||||||
|
eq.status = item.isRun
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
console.log(this.eqList)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {},
|
mounted() {},
|
||||||
@ -205,10 +234,10 @@ export default {
|
|||||||
handleMouseEnter(item, event) {
|
handleMouseEnter(item, event) {
|
||||||
this.showTooltip = true;
|
this.showTooltip = true;
|
||||||
this.eqTipMsg.name = item.name;
|
this.eqTipMsg.name = item.name;
|
||||||
// this.eqTipMsg.input = item.input;
|
this.eqTipMsg.input = item.input;
|
||||||
// this.eqTipMsg.output = item.output;
|
this.eqTipMsg.output = item.output;
|
||||||
// this.eqTipMsg.alarm = item.alarm;
|
this.eqTipMsg.alarm = item.alarm;
|
||||||
// this.eqTipMsg.status = item.status;
|
this.eqTipMsg.status = item.status;
|
||||||
this.updateTooltipPosition(event);
|
this.updateTooltipPosition(event);
|
||||||
},
|
},
|
||||||
handleMouseLeave() {
|
handleMouseLeave() {
|
||||||
@ -288,7 +317,7 @@ p{
|
|||||||
.eqBox {
|
.eqBox {
|
||||||
span{
|
span{
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
border: 1px solid red;
|
// border: 1px solid red;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<header class="dataBoardHeader">
|
<header class="dataBoardHeader">
|
||||||
<div class='topTitle'></div>
|
<div class='topTitle'></div>
|
||||||
<div class='time-chsoose'>
|
<!-- <div class='time-chsoose'>
|
||||||
<span class='title'>时间选择</span>
|
<span class='title'>时间选择</span>
|
||||||
<span class='time-show'>{{time}}</span>
|
<span class='time-show'>{{time}}</span>
|
||||||
<el-date-picker
|
<el-date-picker
|
||||||
@ -12,7 +12,7 @@
|
|||||||
style='position: absolute;right: 0px;width: 119px;top:-2px;opacity: 0;'
|
style='position: absolute;right: 0px;width: 119px;top:-2px;opacity: 0;'
|
||||||
>
|
>
|
||||||
</el-date-picker>
|
</el-date-picker>
|
||||||
</div>
|
</div> -->
|
||||||
<div
|
<div
|
||||||
type="text"
|
type="text"
|
||||||
class="screen-btn"
|
class="screen-btn"
|
||||||
@ -26,7 +26,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import moment from 'moment'
|
// import moment from 'moment'
|
||||||
export default {
|
export default {
|
||||||
name: 'DataBoardHeader',
|
name: 'DataBoardHeader',
|
||||||
props: {
|
props: {
|
||||||
@ -39,7 +39,7 @@ export default {
|
|||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
time: moment().format('YYYY-MM-DD')
|
// time: moment().format('YYYY-MM-DD')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {},
|
computed: {},
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
<svg-icon icon-class="dataBoard2" class='icon'/>
|
<svg-icon icon-class="dataBoard2" class='icon'/>
|
||||||
<span>投入产出及良品率</span>
|
<span>投入产出及良品率</span>
|
||||||
</div>
|
</div>
|
||||||
|
<div v-if='xData.length === 0' class='noData'>暂无数据</div>
|
||||||
|
<div v-else>
|
||||||
<div class="top_legend">
|
<div class="top_legend">
|
||||||
<span class="chart_legend_icon1">投入</span>
|
<span class="chart_legend_icon1">投入</span>
|
||||||
<span class="chart_legend_icon2">产出</span>
|
<span class="chart_legend_icon2">产出</span>
|
||||||
@ -11,21 +13,55 @@
|
|||||||
</div>
|
</div>
|
||||||
<div id='inOutputChart' style='width: 400px;height: 290px;'></div>
|
<div id='inOutputChart' style='width: 400px;height: 290px;'></div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import * as echarts from 'echarts';
|
import * as echarts from 'echarts';
|
||||||
export default {
|
export default {
|
||||||
name: 'LeftBottom',
|
name: 'LeftBottom',
|
||||||
data() {
|
props: {
|
||||||
return {}
|
dataObj: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
watch: {
|
||||||
|
dataObj(val) {
|
||||||
|
this.xData = []
|
||||||
|
this.inputData = []
|
||||||
|
this.outputData = []
|
||||||
|
this.goodRateData = []
|
||||||
|
val.monthBar && val.monthBar.forEach(item => {
|
||||||
|
this.xData.push(item.dataType)
|
||||||
|
this.inputData.push(item.inputNum)
|
||||||
|
this.outputData.push(item.outputNum)
|
||||||
|
this.goodRateData.push(item.goodRate)
|
||||||
|
})
|
||||||
this.initChart();
|
this.initChart();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
chartDom: '',
|
||||||
|
chart: '',
|
||||||
|
xData:[],
|
||||||
|
inputData:[],
|
||||||
|
outputData:[],
|
||||||
|
goodRateData:[],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {},
|
||||||
methods: {
|
methods: {
|
||||||
initChart() {
|
initChart() {
|
||||||
var chartDom = document.getElementById('inOutputChart');
|
if (
|
||||||
var myChart = echarts.init(chartDom);
|
this.chart !== null &&
|
||||||
|
this.chart !== '' &&
|
||||||
|
this.chart !== undefined
|
||||||
|
) {
|
||||||
|
this.chart.dispose() // 页面多次刷新会出现警告,Dom已经初始化了一个实例,这是销毁实例
|
||||||
|
}
|
||||||
|
this.chartDom = document.getElementById('inOutputChart')
|
||||||
|
this.chart = echarts.init(this.chartDom)
|
||||||
var option;
|
var option;
|
||||||
option = {
|
option = {
|
||||||
grid: { top: 40, right: 10, bottom: 5, left: 10, containLabel: true },
|
grid: { top: 40, right: 10, bottom: 5, left: 10, containLabel: true },
|
||||||
@ -34,12 +70,12 @@ export default {
|
|||||||
},
|
},
|
||||||
xAxis: {
|
xAxis: {
|
||||||
type: "category",
|
type: "category",
|
||||||
data: ['1月','2月','3月','4月','5月','6月','7月','8月','9月','10月','11月','12月'],
|
data: this.xData,
|
||||||
axisLabel: {
|
axisLabel: {
|
||||||
color: "#fff",
|
color: "#fff",
|
||||||
fontSize: 12,
|
fontSize: 10,
|
||||||
interval: 0,
|
interval: 0,
|
||||||
rotate:20
|
rotate:30
|
||||||
},
|
},
|
||||||
axisTick: { show: false },
|
axisTick: { show: false },
|
||||||
axisLine: {
|
axisLine: {
|
||||||
@ -110,7 +146,7 @@ export default {
|
|||||||
},
|
},
|
||||||
series: [
|
series: [
|
||||||
{
|
{
|
||||||
data: [1000,3000,2800,4200,5000,6000,7000,8000,9000,10000,11000,12000],
|
data: this.inputData,
|
||||||
type: "bar",
|
type: "bar",
|
||||||
barWidth: 10,
|
barWidth: 10,
|
||||||
barGap:0,
|
barGap:0,
|
||||||
@ -122,7 +158,7 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
data:[800,2900,2700,4100,4800,4900,5900,6800,7900,8900,9900,10000],
|
data:this.outputData,
|
||||||
type: "bar",
|
type: "bar",
|
||||||
barWidth: 10,
|
barWidth: 10,
|
||||||
itemStyle: {
|
itemStyle: {
|
||||||
@ -133,7 +169,7 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
data: [98,97,99,96,98,99,98,97,98,99,98,99],
|
data:this.goodRateData,
|
||||||
type: "line",
|
type: "line",
|
||||||
yAxisIndex: 1,
|
yAxisIndex: 1,
|
||||||
symbol:'circle',
|
symbol:'circle',
|
||||||
@ -149,7 +185,7 @@ export default {
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
option && myChart.setOption(option);
|
option && this.chart.setOption(option);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -230,6 +266,11 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.noData {
|
||||||
|
font-size: 24px;
|
||||||
|
text-align: center;
|
||||||
|
padding-top: 100px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
<style>
|
<style>
|
||||||
.qhd-chart-tooltip {
|
.qhd-chart-tooltip {
|
||||||
|
@ -19,12 +19,12 @@
|
|||||||
<div>总生产</div>
|
<div>总生产</div>
|
||||||
</div>
|
</div>
|
||||||
<div class='right-data' style="top:15px;">
|
<div class='right-data' style="top:15px;">
|
||||||
<p><span class='num'>932,261</span><span class='text'>片数</span></p>
|
<p><span class='num'>{{todayData?.inputNum ? formatThousands(todayData.inputNum) : '-'}}</span><span class='text'>片数</span></p>
|
||||||
<p><span class='num'>894</span><span class='text'>面积/㎡</span></p>
|
<p><span class='num'>{{todayData?.inputArea ? formatThousands(todayData.inputArea) : '-'}}</span><span class='text'>面积/㎡</span></p>
|
||||||
</div>
|
</div>
|
||||||
<div class='right-data' style="top:132px;">
|
<div class='right-data' style="top:132px;">
|
||||||
<p><span class='num'>932,261</span><span class='text'>片数</span></p>
|
<p><span class='num'>{{todayData?.outputNum ? formatThousands(todayData.outputNum) : '-'}}</span><span class='text'>片数</span></p>
|
||||||
<p><span class='num'>894</span><span class='text'>面积/㎡</span></p>
|
<p><span class='num'>{{todayData?.outputArea ? formatThousands(todayData.outputArea) : '-'}}</span><span class='text'>面积/㎡</span></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class='title-split'>
|
<div class='title-split'>
|
||||||
@ -42,12 +42,12 @@
|
|||||||
<div>总生产</div>
|
<div>总生产</div>
|
||||||
</div>
|
</div>
|
||||||
<div class='right-data' style="top:15px;">
|
<div class='right-data' style="top:15px;">
|
||||||
<p><span class='num'>932,261</span><span class='text'>片数</span></p>
|
<p><span class='num'>{{yesterdayData?.inputNum ? formatThousands(yesterdayData.inputNum) : '-'}}</span><span class='text'>片数</span></p>
|
||||||
<p><span class='num'>894</span><span class='text'>面积/㎡</span></p>
|
<p><span class='num'>{{yesterdayData?.inputArea ? formatThousands(yesterdayData.inputArea) : '-'}}</span><span class='text'>面积/㎡</span></p>
|
||||||
</div>
|
</div>
|
||||||
<div class='right-data' style="top:132px;">
|
<div class='right-data' style="top:132px;">
|
||||||
<p><span class='num'>932,261</span><span class='text'>片数</span></p>
|
<p><span class='num'>{{yesterdayData?.outputNum ? formatThousands(yesterdayData.outputNum) : '-'}}</span><span class='text'>片数</span></p>
|
||||||
<p><span class='num'>894</span><span class='text'>面积/㎡</span></p>
|
<p><span class='num'>{{yesterdayData?.outputArea ? formatThousands(yesterdayData.outputArea) : '-'}}</span><span class='text'>面积/㎡</span></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -55,8 +55,28 @@
|
|||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: 'LeftTop',
|
name: 'LeftTop',
|
||||||
|
props: {
|
||||||
|
dataObj: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
dataObj(val) {
|
||||||
|
val.todayAndYesterday && val.todayAndYesterday.forEach(item => {
|
||||||
|
if (item.dataType === "今日") {
|
||||||
|
this.todayData = item
|
||||||
|
} else {
|
||||||
|
this.yesterdayData = item
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {}
|
return {
|
||||||
|
todayData:{},
|
||||||
|
yesterdayData:{}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
methods: {}
|
methods: {}
|
||||||
}
|
}
|
||||||
|
@ -7,25 +7,11 @@
|
|||||||
<div class='rankingLeft'>
|
<div class='rankingLeft'>
|
||||||
<div class='rankingLeftTitle'>产量</div>
|
<div class='rankingLeftTitle'>产量</div>
|
||||||
<div class='rankingTypeBox'>
|
<div class='rankingTypeBox'>
|
||||||
<div>
|
<div style='margin-bottom: 10px;' v-for='(item,index) in teamProductionRank' :key='index'>
|
||||||
<img src="../../../../assets//images//dataBoard/ranking1.png" alt="" width='50'>
|
<img :src="require(`../../../../assets/images/dataBoard/ranking${index+1}.png`)" alt="" width="50">
|
||||||
<div class='rankingTextBox'>
|
<div class='rankingTextBox'>
|
||||||
<p class='text1'>班组1/片</p>
|
<p class='text1'>{{item.name}}/片</p>
|
||||||
<p class='text2'>261,938,984</p>
|
<p class='text2'>{{item?.value ? formatThousands(item.value) : '-'}}</p>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div style='margin: 10px 0;'>
|
|
||||||
<img src="../../../../assets//images//dataBoard/ranking2.png" alt="" width='50'>
|
|
||||||
<div class='rankingTextBox'>
|
|
||||||
<p class='text1'>班组1/片</p>
|
|
||||||
<p class='text2'>261,938,984</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<img src="../../../../assets//images//dataBoard/ranking3.png" alt="" width='50'>
|
|
||||||
<div class='rankingTextBox'>
|
|
||||||
<p class='text1'>班组1/片</p>
|
|
||||||
<p class='text2'>261,938,984</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -35,14 +21,14 @@
|
|||||||
成品率
|
成品率
|
||||||
</div>
|
</div>
|
||||||
<div class='rankingTypeBox' style='left: 120px;'>
|
<div class='rankingTypeBox' style='left: 120px;'>
|
||||||
<div>
|
<div style='margin-bottom: 10px;' v-for='(item,index) in teamRateRank' :key='index'>
|
||||||
<img src="../../../../assets//images//dataBoard/ranking1.png" alt="" width='50'>
|
<img :src="require(`../../../../assets/images/dataBoard/ranking${index+1}.png`)" alt="" width="50">
|
||||||
<div class='rankingTextBox'>
|
<div class='rankingTextBox'>
|
||||||
<p class='text1'>班组1</p>
|
<p class='text1'>{{item.name}}</p>
|
||||||
<p class='text2'>95<span style='font-size: 20px;'>.92%</span></p>
|
<p class='text2'>{{Math.trunc(item.value)}}<span style='font-size: 20px;'>.{{item.value1}}%</span></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div style='margin: 10px 0;'>
|
<!-- <div>
|
||||||
<img src="../../../../assets//images//dataBoard/ranking2.png" alt="" width='50'>
|
<img src="../../../../assets//images//dataBoard/ranking2.png" alt="" width='50'>
|
||||||
<div class='rankingTextBox'>
|
<div class='rankingTextBox'>
|
||||||
<p class='text1'>班组1</p>
|
<p class='text1'>班组1</p>
|
||||||
@ -55,7 +41,7 @@
|
|||||||
<p class='text1'>班组1</p>
|
<p class='text1'>班组1</p>
|
||||||
<p class='text2'>90<span style='font-size: 20px;'>.42%</span></p>
|
<p class='text2'>90<span style='font-size: 20px;'>.42%</span></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div> -->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -63,11 +49,49 @@
|
|||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: 'RightBottom',
|
name: 'RightBottom',
|
||||||
|
props: {
|
||||||
|
dataObj: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
dataObj(val) {
|
||||||
|
this.teamProductionRank = []
|
||||||
|
this.teamRateRank = []
|
||||||
|
val.teamProductionRank && val.teamProductionRank.forEach(item => {
|
||||||
|
let obj = {
|
||||||
|
name: item.name,
|
||||||
|
value: item.value,
|
||||||
|
rank: item.rank,
|
||||||
|
}
|
||||||
|
this.teamProductionRank.push(obj)
|
||||||
|
})
|
||||||
|
val.teamRateRank && val.teamRateRank.forEach(item => {
|
||||||
|
let obj = {
|
||||||
|
name: item.name,
|
||||||
|
value: item.value,
|
||||||
|
rank: item.rank,
|
||||||
|
value1: this.getPositiveDecimal(item.value)
|
||||||
|
}
|
||||||
|
this.teamRateRank.push(obj)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {}
|
return {
|
||||||
|
teamProductionRank:[],
|
||||||
|
teamRateRank:[]
|
||||||
|
}
|
||||||
},
|
},
|
||||||
mounted() {},
|
mounted() {},
|
||||||
methods: {}
|
methods: {
|
||||||
|
getPositiveDecimal(num) {
|
||||||
|
const str = Math.abs(num).toString();
|
||||||
|
const [, decimal] = str.split('.');
|
||||||
|
return decimal || '00';
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style lang='scss' scoped>
|
<style lang='scss' scoped>
|
||||||
|
@ -14,23 +14,26 @@
|
|||||||
<div class='box' style='width: 105px;'>
|
<div class='box' style='width: 105px;'>
|
||||||
<p class='name'>
|
<p class='name'>
|
||||||
<span style='margin-right: 3px;'>当日</span>
|
<span style='margin-right: 3px;'>当日</span>
|
||||||
<img src="../../../../assets/images/dataBoard/arrUp.png" alt="" width='5' height='15'>
|
<img v-show='nokSumDet.today >= nokSumDet.yesterday' src="../../../../assets/images/dataBoard/arrUp.png" alt="" width='5' height='15'>
|
||||||
|
<img v-show='nokSumDet.today < nokSumDet.yesterday' src="../../../../assets/images/dataBoard/arrDown.png" alt="" width='5' height='15'>
|
||||||
</p>
|
</p>
|
||||||
<p class='num'>283</p>
|
<p class='num'>{{nokSumDet?.today ? formatThousands(nokSumDet.today) : '-'}}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class='box' style='width: 115px;'>
|
<div class='box' style='width: 115px;'>
|
||||||
<p class='name'>
|
<p class='name'>
|
||||||
<span style='margin-right: 3px;'>本月</span>
|
<span style='margin-right: 3px;'>本月</span>
|
||||||
<img src="../../../../assets/images/dataBoard/arrDown.png" alt="" width='5' height='15'>
|
<img v-show='nokSumDet.month >= nokSumDet.lastMonth' src="../../../../assets/images/dataBoard/arrUp.png" alt="" width='5' height='15'>
|
||||||
|
<img v-show='nokSumDet.month < nokSumDet.lastMonth' src="../../../../assets/images/dataBoard/arrDown.png" alt="" width='5' height='15'>
|
||||||
</p>
|
</p>
|
||||||
<p class='num'>2,830</p>
|
<p class='num'>{{nokSumDet?.month ? formatThousands(nokSumDet.month) : '-'}}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class='box' style='width: 110px;'>
|
<div class='box' style='width: 110px;'>
|
||||||
<p class='name'>
|
<p class='name'>
|
||||||
<span style='margin-right: 3px;'>本年</span>
|
<span style='margin-right: 3px;'>本年</span>
|
||||||
<img src="../../../../assets/images/dataBoard/arrDown.png" alt="" width='5' height='15'>
|
<img v-show='nokSumDet.year >= nokSumDet.lastYear' src="../../../../assets/images/dataBoard/arrUp.png" alt="" width='5' height='15'>
|
||||||
|
<img v-show='nokSumDet.year < nokSumDet.lastYear' src="../../../../assets/images/dataBoard/arrDown.png" alt="" width='5' height='15'>
|
||||||
</p>
|
</p>
|
||||||
<p class='num'>32,830</p>
|
<p class='num'>{{nokSumDet?.year ? formatThousands(nokSumDet.year) : '-'}}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class='row' style='padding-top: 5px;'>
|
<div class='row' style='padding-top: 5px;'>
|
||||||
@ -38,19 +41,19 @@
|
|||||||
<p class='name'>
|
<p class='name'>
|
||||||
<span>昨日</span>
|
<span>昨日</span>
|
||||||
</p>
|
</p>
|
||||||
<p class='num'>283</p>
|
<p class='num'>{{nokSumDet?.yesterday ? formatThousands(nokSumDet.yesterday) : '-'}}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class='box' style='width: 115px;'>
|
<div class='box' style='width: 115px;'>
|
||||||
<p class='name'>
|
<p class='name'>
|
||||||
<span>上月</span>
|
<span>上月</span>
|
||||||
</p>
|
</p>
|
||||||
<p class='num'>2,830</p>
|
<p class='num'>{{nokSumDet?.lastMonth ? formatThousands(nokSumDet.lastMonth) : '-'}}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class='box' style='width: 110px;'>
|
<div class='box' style='width: 110px;'>
|
||||||
<p class='name'>
|
<p class='name'>
|
||||||
<span>上年</span>
|
<span>上年</span>
|
||||||
</p>
|
</p>
|
||||||
<p class='num'>32,830</p>
|
<p class='num'>{{nokSumDet?.lastYear ? formatThousands(nokSumDet.lastYear) : '-'}}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -73,29 +76,51 @@ const colors = [
|
|||||||
];
|
];
|
||||||
export default {
|
export default {
|
||||||
name: 'RightTop',
|
name: 'RightTop',
|
||||||
|
props: {
|
||||||
|
dataObj: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
dataObj(val) {
|
||||||
|
this.nokSumDet = val.nokSumDet
|
||||||
|
this.dataProps = []
|
||||||
|
val.nokPieDet && val.nokPieDet.forEach(item => {
|
||||||
|
let obj = {
|
||||||
|
value: item.num,
|
||||||
|
name: item.type
|
||||||
|
}
|
||||||
|
this.dataProps.push(obj)
|
||||||
|
})
|
||||||
|
this.initChart()
|
||||||
|
}
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
nokSumDet:{},
|
||||||
|
chartDom: '',
|
||||||
|
chart: '',
|
||||||
|
dataProps:[],
|
||||||
rangArrValue:[],
|
rangArrValue:[],
|
||||||
dataList:[],
|
dataList:[],
|
||||||
totalValue:0
|
totalValue:0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {},
|
||||||
this.initChart();
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
initChart() {
|
initChart() {
|
||||||
var chartDom = document.getElementById('defectSumChart');
|
if (
|
||||||
var myChart = echarts.init(chartDom);
|
this.chart !== null &&
|
||||||
|
this.chart !== '' &&
|
||||||
|
this.chart !== undefined
|
||||||
|
) {
|
||||||
|
this.chart.dispose() // 页面多次刷新会出现警告,Dom已经初始化了一个实例,这是销毁实例
|
||||||
|
}
|
||||||
|
this.chartDom = document.getElementById('defectSumChart')
|
||||||
|
this.chart = echarts.init(this.chartDom)
|
||||||
var option;
|
var option;
|
||||||
const dataProps = [
|
this.getPersonnelList(this.dataProps)
|
||||||
{value: 14,name:'缺陷1'},
|
|
||||||
{value: 20,name:'缺陷2'},
|
|
||||||
{value: 22,name:'缺陷3'},
|
|
||||||
{value: 14,name:'缺陷4'},
|
|
||||||
{value: 30,name:'缺陷5'}
|
|
||||||
]
|
|
||||||
this.getPersonnelList(dataProps)
|
|
||||||
option = {
|
option = {
|
||||||
color: colors,
|
color: colors,
|
||||||
graphic: [
|
graphic: [
|
||||||
@ -132,10 +157,6 @@ export default {
|
|||||||
type: "pie",
|
type: "pie",
|
||||||
radius: ["45%", "60%"],
|
radius: ["45%", "60%"],
|
||||||
center: ["50%", "50%"],
|
center: ["50%", "50%"],
|
||||||
// label: {
|
|
||||||
// formatter: "{d}%",
|
|
||||||
// color: "#fff",
|
|
||||||
// },
|
|
||||||
label:{
|
label:{
|
||||||
formatter:function(params){
|
formatter:function(params){
|
||||||
return `{color${params.dataIndex}|${params.percent}%}\n{style2|${params.name}}`
|
return `{color${params.dataIndex}|${params.percent}%}\n{style2|${params.name}}`
|
||||||
@ -161,7 +182,7 @@ export default {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
option && myChart.setOption(option);
|
option && this.chart.setOption(option);
|
||||||
},
|
},
|
||||||
getCoordinates(startArc, endArc) {
|
getCoordinates(startArc, endArc) {
|
||||||
const posi = [
|
const posi = [
|
||||||
|
@ -5,13 +5,13 @@
|
|||||||
:is-full-screen="isFullScreen"
|
:is-full-screen="isFullScreen"
|
||||||
@screenfullChange="screenfullChange"
|
@screenfullChange="screenfullChange"
|
||||||
/>
|
/>
|
||||||
<LeftTop />
|
<LeftTop :dataObj='dataObj'/>
|
||||||
<LeftBottom />
|
<LeftBottom :dataObj='dataObj'/>
|
||||||
<CenterTop :scaleNum='scaleNum'/>
|
<CenterTop :scaleNum='scaleNum' :dataObj='dataObj'/>
|
||||||
<CenterBottomL />
|
<CenterBottomL :dataObj='dataObj'/>
|
||||||
<CenterBottomR />
|
<CenterBottomR :dataObj='dataObj'/>
|
||||||
<RightTop />
|
<RightTop :dataObj='dataObj'/>
|
||||||
<RightBottom />
|
<RightBottom :dataObj='dataObj'/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -27,6 +27,8 @@ import RightTop from './components/RightTop.vue';
|
|||||||
import RightBottom from './components/RightBottom.vue';
|
import RightBottom from './components/RightBottom.vue';
|
||||||
import { debounce } from '@/utils/debounce';
|
import { debounce } from '@/utils/debounce';
|
||||||
import screenfull from 'screenfull';
|
import screenfull from 'screenfull';
|
||||||
|
import { getAccessToken } from '@/utils/auth';
|
||||||
|
import store from "@/store";
|
||||||
export default {
|
export default {
|
||||||
name: 'DataBoard',
|
name: 'DataBoard',
|
||||||
components: { DataBoardHeader,LeftTop,LeftBottom,CenterTop,CenterBottomL,CenterBottomR,RightTop,RightBottom },
|
components: { DataBoardHeader,LeftTop,LeftBottom,CenterTop,CenterBottomL,CenterBottomR,RightTop,RightBottom },
|
||||||
@ -35,12 +37,14 @@ export default {
|
|||||||
return {
|
return {
|
||||||
isFullScreen: false,
|
isFullScreen: false,
|
||||||
scaleNum: 0.8,
|
scaleNum: 0.8,
|
||||||
|
dataObj:{}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.init()
|
this.init()
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
console.log('dataBoard mounted')
|
||||||
this.boxReset = debounce(() => {
|
this.boxReset = debounce(() => {
|
||||||
this.resetSize()
|
this.resetSize()
|
||||||
}, 300)
|
}, 300)
|
||||||
@ -48,6 +52,10 @@ export default {
|
|||||||
window.addEventListener('resize', () => {
|
window.addEventListener('resize', () => {
|
||||||
this.boxReset()
|
this.boxReset()
|
||||||
})
|
})
|
||||||
|
this.getData()
|
||||||
|
},
|
||||||
|
destroyed() {
|
||||||
|
console.log('dataBoard destroyed')
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
sidebarOpened() {
|
sidebarOpened() {
|
||||||
@ -60,6 +68,53 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
getData() {
|
||||||
|
let _this = this;
|
||||||
|
const url = process.env.VUE_APP_BASE_API+'/admin-api/monitoring/message/subscribe/'+store.getters.userId+'-'+Date.now();
|
||||||
|
const token = getAccessToken()
|
||||||
|
const headers = new Headers({
|
||||||
|
'Authorization': `Bearer ${token}`,
|
||||||
|
'Content-Type': 'text/event-stream'
|
||||||
|
});
|
||||||
|
fetch(url, { headers })
|
||||||
|
.then(response => {
|
||||||
|
const reader = response.body.getReader();
|
||||||
|
const decoder = new TextDecoder();
|
||||||
|
const readStream = () => {
|
||||||
|
reader.read().then(({ done, value }) => {
|
||||||
|
if (done) {
|
||||||
|
console.log('SSE 连接关闭');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const data = decoder.decode(value);
|
||||||
|
console.log('收到消息:', data);
|
||||||
|
if (_this.isValidData(data)){
|
||||||
|
_this.upDateMsg(data);
|
||||||
|
}
|
||||||
|
readStream(); // 继续读取
|
||||||
|
}).catch(error => {
|
||||||
|
console.error('SSE 读取错误:', error);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
readStream();
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('SSE 连接失败:', error);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
isValidData (data) {
|
||||||
|
return data.trim().startsWith('data:{') && !data.includes('heartbeat');
|
||||||
|
},
|
||||||
|
upDateMsg(data) {
|
||||||
|
const jsonStr = data.replace(/^data:/, '').trim();
|
||||||
|
try {
|
||||||
|
const dataObj = JSON.parse(jsonStr);
|
||||||
|
this.dataObj = dataObj
|
||||||
|
console.log('dataObj',this.dataObj)
|
||||||
|
} catch (e) {
|
||||||
|
console.error('JSON 解析失败:', e);
|
||||||
|
}
|
||||||
|
},
|
||||||
change() {
|
change() {
|
||||||
this.isFullScreen = screenfull.isFullscreen
|
this.isFullScreen = screenfull.isFullscreen
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user