11-wms/src/views/OperationalOverview/storageCockpit.vue
2022-11-03 16:04:44 +08:00

747 lines
25 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!--
* @Author: zwq
* @Date: 2021-07-19 15:18:30
* @LastEditors: zwq
* @LastEditTime: 2022-11-03 16:03:03
* @Description:
-->
<template>
<div id="container" ref="container" class="visual-container">
<el-row
class="container-title"
:style="{
height: beilv * 88 + 'px',
lineHeight: beilv * 88 + 'px',
fontSize: beilv * 30 + 'px'
}"
>
<img src="../../assets/img/logo.png" style="width:1.1em;position:relative;top:.4em" alt="">
<el-button
type="text"
class="title-button"
:style="{ right: 33 * beilv + 'px', top: 37 * beilv + 'px' }"
@click="changeFullScreen"
>
<svg-icon v-if="isFullScreen" icon-class="unFullScreenView" />
<svg-icon v-else icon-class="fullScreenView" />
</el-button>
</el-row>
<el-row class="container-main">
<el-row :style="{ padding: '0 ' + 9 * beilv + 'px' }" :gutter="9 * beilv">
<el-col :span="8">
<el-row type="flex" class="h-full flex-col">
<el-col :style="{ margin: 8 * beilv + 'px' + ' 0' }" :span="24">
<base-container :beilv="beilv" :height="190" :title="'成品入库作业'" :title-icon="'入库管理'">
<div :style="{ fontSize: 13 * beilv + 'px' }">
<el-row :style="{ marginBottom: 15 * beilv + 'px'}">
<el-col :span="12"><div class="inTest" :style="{ padding: 9 * beilv + 'px'}"><span class="leftText">时间:</span><span class="rightText">2022.12.12 13:12:45</span></div></el-col>
<el-col :span="12"><div class="inTest" :style="{ padding: 9 * beilv + 'px'}"><span class="leftText">成品编码:</span><span class="rightText">34394233442</span></div></el-col>
</el-row>
<el-row :style="{ marginBottom: 15 * beilv + 'px'}">
<el-col :span="12"><div class="inTest" :style="{ padding: 9 * beilv + 'px'}"><span class="leftText">入库作业号:</span><span class="rightText">347384734</span></div></el-col>
<el-col :span="12"><div class="inTest" :style="{ padding: 9 * beilv + 'px'}"><span class="leftText">成品规格:</span><span class="rightText">234*345*34</span></div></el-col>
</el-row>
<el-row>
<el-col :span="12"><div class="inTest" :style="{ padding: 9 * beilv + 'px'}"><span class="leftText">执行叉车:</span><span class="rightText">叉车</span></div></el-col>
<el-col :span="12"><div class="inTest" :style="{ padding: 9 * beilv + 'px'}"><span class="leftText">库位:</span><span class="rightText">A区34货位3层</span></div></el-col>
</el-row>
</div>
</base-container>
</el-col>
<el-col :style="{ margin: 8 * beilv + 'px' + ' 0' }" :span="24">
<!-- 成品入库列队 -->
<base-container :beilv="beilv" :height="190" :title="'成品入库列队'" :title-icon="'编组'">
<div style="background:rgba(14, 32, 62, 1);border-radius:5px">
<base-table
:limit="10"
:beilv="beilv"
:table-config="inAndOutOfEachLine.tableProps"
:table-data="inAndOutOfEachLine.list"
/>
</div>
</base-container>
</el-col>
<el-col :style="{ margin: 8 * beilv + 'px' + ' 0' }" :span="24">
<base-container :beilv="beilv" :height="190" :title="'成品出库作业'" :title-icon="'出库管理'">
<div :style="{ fontSize: 13 * beilv + 'px' }">
<el-row :style="{ marginBottom: 10 * beilv + 'px'}">
<el-col :span="12"><div class="outTest" :style="{ padding: 7 * beilv + 'px'}"><span class="leftText">时间:</span><span class="rightText">2022.12.12 13:12:45</span></div></el-col>
<el-col :span="12"><div class="outTest" :style="{ padding: 7 * beilv + 'px'}"><span class="leftText">ERP订单:</span><span class="rightText">34394233442</span></div></el-col>
</el-row>
<el-row :style="{ marginBottom: 10 * beilv + 'px'}">
<el-col :span="12"><div class="outTest" :style="{ padding: 7 * beilv + 'px'}"><span class="leftText">成品编码:</span><span class="rightText">34394233442</span></div></el-col>
<el-col :span="12"><div class="outTest" :style="{ padding: 7 * beilv + 'px'}"><span class="leftText">出库作业号:</span><span class="rightText">347384734</span></div></el-col>
</el-row>
<el-row :style="{ marginBottom: 10 * beilv + 'px'}">
<el-col :span="12"><div class="outTest" :style="{ padding: 7 * beilv + 'px'}"><span class="leftText">成品规格:</span><span class="rightText">234*345*34</span></div></el-col>
<el-col :span="12"><div class="outTest" :style="{ padding: 7 * beilv + 'px'}"><span class="leftText">执行叉车:</span><span class="rightText">叉车</span></div></el-col>
</el-row>
<el-row>
<el-col :span="12"><div class="outTest" :style="{ padding: 7 * beilv + 'px'}"><span class="leftText">库位:</span><span class="rightText">A区34货位3层</span></div></el-col>
<el-col :span="12"><div class="outTest" :style="{ padding: 7 * beilv + 'px'}"><span class="leftText">库位前置区:</span><span class="rightText">A区34货位3层</span></div></el-col>
</el-row>
</div>
</base-container>
</el-col>
<el-col :style="{ margin: 8 * beilv + 'px' + ' 0' }" :span="24">
<!-- 成品入库列队 -->
<base-container :beilv="beilv" :height="190" :title="'成品出库列队'" :title-icon="'编组备份 2'">
<div style="background:rgba(14, 32, 62, 1);border-radius:5px">
<base-table
:limit="10"
:beilv="beilv"
:table-config="inAndOutOfEachLine.tableProps"
:table-data="inAndOutOfEachLine.list"
/>
</div>
</base-container>
</el-col>
</el-row>
</el-col>
<el-col :span="10">
<!-- 中间栏 -->
<el-row type="flex" class="h-full flex-col">
<el-col :style="{ margin: 8 * beilv + 'px' + ' 0' }" :span="24">
<base-container :beilv="beilv">
<storage-cockpit-area :beilv="beilv" />
</base-container>
</el-col>
</el-row>
</el-col>
<el-col :span="6">
<!-- 右边栏 设备工单管理 -->
<el-row type="flex" class="h-full flex-col">
<el-col :style="{ margin: 8 * beilv + 'px' + ' 0' }" :span="24">
<base-container :beilv="beilv" :title="'设备工单管理'" :title-icon="'编组(1)'">
<div class="div-box" :style="{textAlign: 'center', padding: 8 * beilv + 'px', paddingTop: 15 * beilv + 'px',marginBottom: 12 * beilv + 'px'}">
<span v-html="titleLeftSVG" />
<span style="color: #01CFCC; line-height: 18px;" :style="{ fontSize: 15 * beilv + 'px' }">
成品库存一览1
</span>
<div style="transform: rotateY(180deg); display: inline-block;" v-html="titleLeftSVG" />
<new-pie
:id="'pie-chart1'"
:show-center-title="true"
:legend-config="{ left: '1%', top: '30%', itemGap: 5 }"
:series-data="legendData1"
:beilv="beilv"
:height="226"
/>
</div>
<div class="div-box" :style="{textAlign: 'center', position: 'relative', padding: 8 * beilv + 'px', paddingTop: 15 * beilv + 'px', marginBottom: 12 * beilv + 'px'}">
<span v-html="titleLeftSVG" />
<span style="color: #01CFCC; line-height: 18px;" :style="{ fontSize: 15 * beilv + 'px' }">
成品库存一览2
</span>
<div style="transform: rotateY(180deg); display: inline-block;" v-html="titleLeftSVG" />
<new-bar
:name-list="clNameList"
:data-list="clDataList"
:height="226"
:beilv="beilv"
/>
<div class="barDiv" :style="{width: 345* beilv + 'px'}" />
</div>
<div class="div-box" :style="{textAlign: 'center', padding: 8 * beilv + 'px', paddingTop: 15 * beilv + 'px'}">
<span v-html="titleLeftSVG" />
<span style="color: #01CFCC; line-height: 18px;" :style="{ fontSize: 15 * beilv + 'px' }">
成品库存一览3
</span>
<div style="transform: rotateY(180deg); display: inline-block;" v-html="titleLeftSVG" />
<new-pie
:id="'pie-chart3'"
:show-center-title="true"
:legend-config="{ left: '1%', top: '30%', itemGap: 5 }"
:series-data="legendData3"
:beilv="beilv"
:height="226"
/>
</div>
</base-container>
</el-col>
</el-row>
</el-col>
</el-row>
</el-row>
</div>
</template>
<script>
import baseContainer from './components/baseContainer'
import baseTable from './components/baseTable'
import newPie from './components/newPie'
import newBar from './components/newBar'
import storageCockpitArea from './components/storageCockpitArea'
// import LineChart1 from './components/LineChart'
// import LineChart2 from './components/LineChart'
// import LinearBarChart from './components/linearBarChart'
import { mapGetters } from 'vuex'
import screenfull from 'screenfull'
// import BaseVideo from './components/baseVideo.vue'
import axios from '@/utils/request'
import moment from 'moment'
const legendData3 = [
{
name: 'A',
icon: 'circle',
value: 196
},
{
name: 'B',
icon: 'circle',
value: 111
},
{
name: 'C',
icon: 'circle',
value: 89
},
{
name: 'D',
icon: 'circle',
value: 77
},
{
name: 'E',
icon: 'circle',
value: 77
}
]
const legendData1 = [
{
name: 'A',
icon: 'circle',
value: 134
},
{
name: 'B',
icon: 'circle',
value: 125
},
{
name: 'C',
icon: 'circle',
value: 107
},
{
name: 'D',
icon: 'circle',
value: 61
},
{
name: 'E',
icon: 'circle',
value: 153
}
]
const clDataList = [
{
topColor: 'rgba(59, 76, 118, 0.2)',
bottomColor: '#49FBD6',
name: '库存',
data: [64, 91, 55, 65, 37, 77]
}
]
const clNameList = ['A', 'B', 'C', 'D', 'E', 'F']
const titleLeftSVG = `<svg
width="56px"
height="13px"
viewBox="0 0 56 13"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
>
<title>left</title>
<g id="2MES。2-6蓝底-7、8白底" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="2-5质量管理" transform="translate(-419.000000, -808.000000)" fill="#31A6AE">
<g id="编组-16备份-7" transform="translate(360.000000, 513.000000)">
<g id="编组-20备份" transform="translate(24.000000, 277.000000)">
<g id="编组-13备份" transform="translate(35.000000, 16.000000)">
<g
id="编组-2备份"
transform="translate(28.000000, 8.500000) scale(1, -1) translate(-28.000000, -8.500000) translate(0.000000, 2.000000)"
>
<polygon
id="路径-11"
points="47.1645736 7.79376563e-14 43 0 52.2664792 13 56 13"
></polygon>
<polygon
id="路径-11备份"
opacity="0.8"
points="36.1645736 7.79376563e-14 32 0 41.2664792 13 45 13"
></polygon>
<polygon
id="路径-11备份-3"
opacity="0.4"
points="14.1645736 7.79376563e-14 10 0 19.2664792 13 23 13"
></polygon>
<polygon
id="路径-11备份-2"
opacity="0.601434"
points="25.1645736 7.79376563e-14 21 0 30.2664792 13 34 13"
></polygon>
<polygon
id="路径-11备份-4"
opacity="0.201434"
points="4.16457365 7.79376563e-14 5.06480115e-16 0 9.26647921 13 13 13"
></polygon>
</g>
</g>
</g>
</g>
</g>
</g>
</svg>`
export default {
name: 'ProductionMonitoringCockpit',
components: {
baseContainer,
baseTable,
storageCockpitArea,
newPie,
newBar
// LineChart1,
// LineChart2,
// LinearBarChart
// BaseVideo
},
data() {
return {
legendData1,
legendData3,
clNameList,
clDataList,
inAndOutOfEachLine: {
tableProps: [
{ prop: 'test1', label: '作业号', align: 'center' },
{ prop: 'test2', label: '执行叉车', align: 'center' },
{ prop: 'test3', label: '成品编码', align: 'center' },
{ prop: 'test4', label: '成品规格', align: 'center' },
{ prop: 'test5', label: '库位', align: 'center' }
],
total: 0,
list: [
{
test1: '392849829',
test2: '叉车1',
test3: '392849829',
test4: '322*234*12',
test5: '库位1'
},
{
test1: '392849829',
test2: '叉车2',
test3: '392849829',
test4: '322*234*12',
test5: '库位2'
},
{
test1: '392849829',
test2: '叉车3',
test3: '392849829',
test4: '322*234*12',
test5: '库位3'
}
]
},
orderProcessList: [],
beilv: 1,
titleLeftSVG,
isFullScreen: false,
plInput: {},
plOutput: {},
plRate: {},
loadTable: false,
standardCategory: null
}
},
computed: {
...mapGetters(['sidebar'])
},
watch: {
isFullScreen: function(val) {
if (val) {
this.beilv = document.body.offsetWidth / 1920
} else {
this.beilv = document.getElementById('container').offsetWidth / 1920
}
},
'sidebar.opened': function(val) {
console.log(val)
if (!this.isFullScreen) {
setTimeout(() => {
this.beilv = document.getElementById('container').offsetWidth / 1920
}, 300)
}
}
},
created() {
this.init()
},
mounted() {
this.beilv = document.getElementById('container').offsetWidth / 1920
window.addEventListener('resize', () => {
if (this.isFullScreen) {
this.beilv = document.body.offsetWidth / 1920
} else {
this.beilv = document.getElementById('container').offsetWidth / 1920
}
})
},
methods: {
change() {
this.isFullScreen = screenfull.isFullscreen
},
init() {
if (screenfull.enabled) {
screenfull.on('change', this.change)
}
},
destroy() {
if (screenfull.enabled) {
screenfull.off('change', this.change)
}
},
changeFullScreen() {
if (!screenfull.enabled) {
this.$message({
message: 'you browser can not work',
type: 'warning'
})
return false
}
screenfull.toggle(this.$refs.container)
},
/**
* 当切换当天、一周、一个月数据时
* @param {string} chartId - '投入数量图', '产出数量图', '投入产出比'
* @param {string} optValue - '0','1','2'
*/
handleChangeOptions(chartId, optValue) {
let startTime
let endTime
const url = '/analysis/factory-monitor/pdlNumTime'
const method = 'post'
switch (optValue) {
case '0': {
const baseTime = moment().set({ hour: 0, minute: 0, second: 0 })
startTime = baseTime.format('YYYY-MM-DDTHH:mm:ss')
endTime = baseTime.set({ hour: 23, minute: 59, second: 59 }).format('YYYY-MM-DDTHH:mm:ss')
break
}
case '1': {
startTime = moment()
.subtract(1, 'week')
.set({ hour: 0, minute: 0, second: 0 })
.format('YYYY-MM-DDTHH:mm:ss')
endTime = moment().format('YYYY-MM-DDTHH:mm:ss')
break
}
case '2': {
startTime = moment()
.subtract(1, 'month')
.set({ hour: 0, minute: 0, second: 0 })
.format('YYYY-MM-DDTHH:mm:ss')
endTime = moment().format('YYYY-MM-DDTHH:mm:ss')
break
}
}
return axios({
url,
method,
data: {
startTime,
endTime
}
}).then(res => {
console.log('res', res)
switch (chartId) {
case '投入数量图':
this.plInput = {}
res.data.forEach(item => {
if (!this.standardCategory) {
this.standardCategory = item.series
}
item.data.forEach((category, index) => {
if (!isNaN(Number(category.time))) {
category.time = +category.time
}
if (this.plInput[item.pdName]) {
this.$set(this.plInput[item.pdName], [category.time], category.in)
} else {
this.$set(this.plInput, [item.pdName], { [category.time]: category.in })
}
})
})
/** 填充 key */
this.fillKey(this.plInput, this.standardCategory)
this.standardCategory = null
break
case '产出数量图':
this.plOutput = {}
res.data.forEach(item => {
if (!this.standardCategory) {
this.standardCategory = item.series
}
item.data.forEach((category, index) => {
if (!isNaN(Number(category.time))) {
category.time = +category.time
}
if (this.plOutput[item.pdName]) {
this.$set(this.plOutput[item.pdName], [category.time], category.out)
} else {
this.$set(this.plOutput, [item.pdName], { [category.time]: category.out })
}
})
})
/** 填充 key */
this.fillKey(this.plOutput, this.standardCategory)
this.standardCategory = null
break
case '投入产出比':
this.plRate = {}
res.data.forEach(item => {
if (!this.standardCategory) {
this.standardCategory = item.series
}
item.data.forEach((category, index) => {
if (!isNaN(Number(category.time))) {
category.time = +category.time
}
if (this.plRate[item.pdName]) {
this.$set(this.plRate[item.pdName], [category.time], category.rate)
} else {
this.$set(this.plRate, [item.pdName], { [category.time]: category.rate })
}
})
})
/** 填充 key */
this.fillKey(this.plRate, this.standardCategory)
this.standardCategory = null
break
case 'all':
res.data.forEach(item => {
/** 保存x轴的标准分类因为数据会有缺失标准分类用于校验哪些数据缺失 */
if (!this.standardCategory) {
this.standardCategory = item.series
}
/** if valid */
if (item.data.length) {
/** handle data */
item.data.forEach((category, index) => {
if (!isNaN(Number(category.time))) {
category.time = +category.time
}
if (this.plInput[item.pdName]) {
this.$set(this.plInput[item.pdName], [category.time], category.in)
} else {
this.$set(this.plInput, [item.pdName], { [category.time]: category.in })
}
if (this.plOutput[item.pdName]) {
this.$set(this.plOutput[item.pdName], [category.time], category.out)
} else {
this.$set(this.plOutput, [item.pdName], { [category.time]: category.out })
}
if (this.plRate[item.pdName]) {
this.$set(this.plRate[item.pdName], [category.time], category.rate)
} else {
this.$set(this.plRate, [item.pdName], { [category.time]: category.rate })
}
})
}
})
/** 填充 key */
this.fillKey(this.plInput, this.standardCategory)
this.fillKey(this.plOutput, this.standardCategory)
this.fillKey(this.plRate, this.standardCategory)
this.loadTable = true
this.standardCategory = null
break
}
})
},
fillKey(obj, keyList) {
for (const [legend, child] of Object.entries(obj)) {
/** 数量相等,就不继续执行了 */
if (Object.keys(child).length === keyList) return
const newChild = {}
keyList.forEach(key => {
if (!isNaN(Number(key))) {
key = +key
}
if (child[key] === undefined) {
newChild[key] = null
} else {
newChild[key] = child[key]
}
})
obj[legend] = newChild
}
}
}
}
</script>
<style lang="scss" scoped>
.visual-container {
width: 100%;
min-width: 960px;
background: url('../../assets/img/编组 6@2x.png') no-repeat;
background-size: cover;
.container-title {
width: 100%;
background: url('../../assets/img/OperationalOverview/title (2).png') no-repeat;
background-size: 100% 100%;
color: #fff;
text-align: center;
.title-button {
color: #00fff0;
font-size: 32px;
position: absolute;
}
}
.container-main {
padding: 16px;
}
}
.inTest {
background: url('../../assets/img/OperationalOverview/矩形@2x.png') no-repeat;
background-size: 100% 100%;
}
.outTest {
background: url('../../assets/img/OperationalOverview/矩形@2x(1).png') no-repeat;
background-size: 100% 100%;
}
.leftText{
display: inline-block;
width: 100px;
text-align: right;
}
.rightText{
color:rgba(255, 255, 255, 0.6)
}
.div-box {
background: transparent;
box-shadow: inset 0 0 16px 1px rgba(255, 255, 255, 0.5);
display: inline-block;
width: 100%;
border-radius: 4px;
}
.barDiv {
height: 46px;
opacity: 0.5;
position: absolute;
bottom: 40px;
left:55px;
transform: skewX(-30deg);
background: linear-gradient(180deg, rgba(59, 76, 118, 0) 0%, #49fbd6 100%);
border: 1px solid #3c7080;
}
.now-team-title {
margin: 0;
margin-top: -1em;
font-size: 1.2em;
line-height: 2em;
color: #fff;
}
.main-title {
text-align: center;
}
.now-secondary-title {
margin: 0;
font-size: 1em;
line-height: 2em;
color: #fff;
}
.now-team-content {
font-size: 3em;
line-height: 1em;
color: #52fff1;
text-align: center;
}
::v-deep .el-progress-bar__inner {
background-color: unset;
background-image: linear-gradient(to right, #4573fe, #47f8dc);
}
</style>
<style lang="scss">
.visual-container {
::-webkit-scrollbar {
width: 8px;
height: 8px;
background-color: transparent;
}
::-webkit-scrollbar-track-piece {
background: #1b2b3d;
}
::-webkit-scrollbar-corner {
background: #1b2b3d;
}
::-webkit-scrollbar-track {
width: 6px;
background: #1b2b3d;
-webkit-border-radius: 2em;
-moz-border-radius: 2em;
border-radius: 2em;
}
::-webkit-scrollbar-thumb {
background: rgba($color: #5bc4be, $alpha: 0.7);
background-clip: padding-box;
min-height: 28px;
-webkit-border-radius: 2em;
-moz-border-radius: 2em;
border-radius: 2em;
transition: background-color 0.3s;
cursor: pointer;
}
::-webkit-scrollbar-thumb:hover {
background-color: rgba($color: #5bc4be, $alpha: 1);
}
}
</style>
<style lang="scss" scoped>
.h-full {
height: calc(100vh - 150px);
}
.flex-col {
flex-direction: column;
.el-col {
flex-grow: 1;
flex-shrink: 1;
}
}
.custom-progress-bar >>> .el-progress-bar__outer {
background-color: #1d304b;
}
</style>