This commit is contained in:
2022-11-07 14:54:47 +08:00
commit 8cfe73aaef
1227 changed files with 194899 additions and 0 deletions

View File

@@ -0,0 +1,134 @@
<template>
<div class="left-content-equipment-check">
<!-- <TechyFakeTable :table-props="tableProps" :table-data="tableData" />
<TechyFakeTable :table-props="tableProps2" :table-data="tableData2" /> -->
<div class="el-table-wrapper">
<!-- <TechyTable key="table-1" :showIndex="false" :table-config="tableProps" :table-data="tableData"></TechyTable> -->
<el-table
key="LeftContentEquipmentCheck1"
border
:data="tableData"
:header-cell-style="{ background: 'rgba(79,114,136,0.29)' }"
>
<el-table-column label="设备名称" prop="eqName" />
<el-table-column label="所属产线" prop="pl" />
<el-table-column label="提示等级" prop="warningLevel" />
<el-table-column label="提示等级" prop="checkContent" />
</el-table>
</div>
<!-- <div class="el-table-wrapper">
<el-table
key="LeftContentEquipmentCheck2"
border
:data="tableData2"
:header-cell-style="{ background: 'rgba(79,114,136,0.29)' }"
>
<el-table-column label="设备名称" prop="eqName" />
<el-table-column label="所属产线" prop="pl" />
<el-table-column label="提示等级" prop="warningLevel" />
<el-table-column label="提示等级" prop="checkContent" />
</el-table>
</div> -->
</div>
</template>
<script>
// import TechyFakeTable from './TechyFakeTable.vue'
// import TechyTable from './TechyTable.vue'
const tableProps = [
{ prop: 'eqName', label: '设备名称', width: 120, resizable: false },
{ prop: 'pl', label: '所属产线', width: 120, resizable: false },
{ prop: 'warningLevel', label: '提示等级', width: 120, resizable: false },
{ prop: 'checkContent', label: '提示等级', width: 120, resizable: false }
]
const tableData = [
{ eqName: 'A下片机', pl: '产线1', warningLevel: 1, checkContent: '巡检内容' },
{ eqName: '设备B', pl: '产线1', warningLevel: 1, checkContent: '巡检内容' }
// { eqName: '下片机', pl: '产线3', warningLevel: 3, checkContent: '巡检内容' },
// { eqName: '磨片机', pl: '产线2', warningLevel: 2, checkContent: '巡检内容' }
]
const tableData2 = [
{ eqName: 'A下片机', pl: '产线1', warningLevel: 1, checkContent: '巡检内容' },
{ eqName: '设备B', pl: '产线1', warningLevel: 1, checkContent: '巡检内容' }
// { eqName: '下片机', pl: '产线3', warningLevel: 3, checkContent: '巡检内容' },
// { eqName: '磨片机', pl: '产线2', warningLevel: 2, checkContent: '巡检内容' }
]
export default {
name: 'LeftContentEquipmentCheck',
components: {},
data() {
return { tableProps, tableData, tableData2 }
},
created() {},
mounted() {},
methods: {}
}
</script>
<style scoped>
.left-content-equipment-check {
display: flex;
gap: calc(100vmin / 1920 * 36);
}
.el-table-wrapper {
flex: 1;
}
.left-content-equipment-check > div {
overflow: hidden;
overflow-x: scroll;
}
.el-table-wrapper >>> * {
background: transparent;
}
.el-table-wrapper >>> .el-table::before,
.el-table-wrapper >>> .el-table--group::after,
.el-table-wrapper >>> .el-table--border::after {
background: transparent;
}
.el-table-wrapper >>> .el-table {
font-size: 8px;
background-color: transparent;
color: #fff9;
border: 0;
}
.el-table-wrapper >>> .el-table th.is-leaf,
.el-table-wrapper >>> .el-table td {
border-color: #0d1728;
padding: 0;
}
.el-table__row--striped:hover > td,
.el-table-wrapper >>> .el-table__row:hover > td {
background-color: rgba(79, 114, 136, 0.29) !important;
}
.el-table-wrapper >>> table {
border: unset;
}
.el-table-wrapper >>> thead {
color: #fff;
}
.el-table-wrapper >>> tr {
background: unset;
}
.el-table-wrapper >>> tbody td > div,
.el-table-wrapper >>> thead th > div {
white-space: nowrap;
}
.el-table-wrapper >>> th,
.el-table-wrapper >>> td {
padding: 0;
}
.el-table-wrapper >>> tbody > tr:nth-child(even) {
background: rgba(76, 97, 123, 0.2);
}
</style>

View File

@@ -0,0 +1,41 @@
<template>
<div class="left-content-monitoring">
<div v-for="imgUrl in images" :key="imgUrl" class="monitor-pic" :style="{ backgroundImage: `url(${imgUrl})` }" />
</div>
</template>
<script>
import { default as pic1 } from './assets/monitor/1.png'
import { default as pic2 } from './assets/monitor/2.png'
import { default as pic3 } from './assets/monitor/3.png'
export default {
name: '',
data() {
return {
images: [pic1, pic2, pic3]
}
},
created() {},
mounted() {},
methods: {}
}
</script>
<style scoped>
.left-content-monitoring {
width: 100%;
/* height: calc(100% - 48px); */
display: flex;
gap: calc(100vw / 1920 * 16);
}
.monitor-pic {
flex: 1;
height: 128px;
background-position: 100% 100%;
background-size: cover;
background-repeat: no-repeat;
}
</style>

View File

@@ -0,0 +1,134 @@
<template>
<div class="left-content-equipment-check">
<!-- <TechyFakeTable :table-props="tableProps" :table-data="tableData" />
<TechyFakeTable :table-props="tableProps2" :table-data="tableData2" /> -->
<div class="el-table-wrapper">
<!-- <TechyTable key="table-1" :showIndex="false" :table-config="tableProps" :table-data="tableData"></TechyTable> -->
<el-table
key="LeftContentOrder1"
border
:data="tableData"
:header-cell-style="{ background: 'rgba(79,114,136,0.29)' }"
>
<el-table-column label="订单编号" prop="orderCode" :show-overflow-tooltip="true" :resizable="true" />
<el-table-column label="客户名称" prop="clientName" :show-overflow-tooltip="true" :resizable="true" />
<el-table-column label="规格" prop="specs" :resizable="true" />
<el-table-column label="完成度" prop="finished" :resizable="true" />
</el-table>
</div>
<!-- <div class="el-table-wrapper">
<el-table
key="LeftContentOrder2"
border
:data="tableData2"
:header-cell-style="{ background: 'rgba(79,114,136,0.29)' }"
>
<el-table-column label="订单编号" prop="orderCode" :show-overflow-tooltip="true" :resizable="true" />
<el-table-column label="客户名称" prop="clientName" :show-overflow-tooltip="true" :resizable="true" />
<el-table-column label="规格" prop="specs" :resizable="true" />
<el-table-column label="完成度" prop="finished" :resizable="true" />
</el-table>
</div> -->
</div>
</template>
<script>
// import TechyFakeTable from './TechyFakeTable.vue'
// import TechyTable from './TechyTable.vue'
const tableData = [
{ orderCode: 'DD202200910', clientName: '中建材', specs: '50cm', finished: 80 },
{ orderCode: 'DD202200911', clientName: '蚌埠研究院', specs: '5mm', finished: 40 },
{ orderCode: 'DD202200912', clientName: '中建材', specs: '50cm', finished: 77 },
{ orderCode: 'DD202200913', clientName: '国资委', specs: '50cm', finished: 66 },
{ orderCode: 'DD202200914', clientName: '合肥新能源', specs: '50cm', finished: 55 },
{ orderCode: 'DD202200915', clientName: '中信科技', specs: '50cm', finished: 77 }
// { orderCode: 'DD202200916', clientName: 'H', specs: '50cm', finished: 33 }
]
const tableData2 = [
{ orderCode: 'DD202200910', clientName: '中建材', specs: '50cm', finished: 80 },
{ orderCode: 'DD202200911', clientName: '蚌埠研究院', specs: '5mm', finished: 40 },
{ orderCode: 'DD202200912', clientName: '中建材', specs: '50cm', finished: 77 },
{ orderCode: 'DD202200913', clientName: '国资委', specs: '50cm', finished: 66 },
{ orderCode: 'DD202200914', clientName: '合肥新能源', specs: '50cm', finished: 55 },
{ orderCode: 'DD202200915', clientName: '中信科技', specs: '50cm', finished: 77 }
// { orderCode: 'DD202200916', clientName: 'H', specs: '50cm', finished: 33 }
]
export default {
name: 'LeftContentOrder',
components: {},
data() {
return { tableData, tableData2 }
},
created() {},
mounted() {},
methods: {}
}
</script>
<style scoped>
.left-content-equipment-check {
display: flex;
gap: calc(100vw / 1920 * 16);
}
.el-table-wrapper {
flex: 1;
}
.left-content-equipment-check > div {
overflow: hidden;
overflow-x: scroll;
}
.el-table-wrapper >>> * {
background: transparent;
}
.el-table-wrapper >>> .el-table::before,
.el-table-wrapper >>> .el-table--group::after,
.el-table-wrapper >>> .el-table--border::after {
background: transparent;
}
.el-table-wrapper >>> .el-table {
font-size: 8px;
background-color: transparent;
color: #fff9;
border: 0;
}
.el-table-wrapper >>> .el-table th.is-leaf,
.el-table-wrapper >>> .el-table td {
border-color: #0d1728;
padding: 0;
}
.el-table__row--striped:hover > td,
.el-table-wrapper >>> .el-table__row:hover > td {
background-color: rgba(79, 114, 136, 0.29) !important;
}
.el-table-wrapper >>> table {
border: unset;
}
.el-table-wrapper >>> thead {
color: #fff;
}
.el-table-wrapper >>> tr {
background: unset;
}
.el-table-wrapper >>> tbody td > div,
.el-table-wrapper >>> thead th > div {
white-space: nowrap;
}
.el-table-wrapper >>> th,
.el-table-wrapper >>> td {
padding: 0;
}
.el-table-wrapper >>> tbody > tr:nth-child(even) {
background: rgba(76, 97, 123, 0.2);
}
</style>

View File

@@ -0,0 +1,72 @@
<template>
<div class="public-consume__inner">
<div class="water-area">
<TechyBarChart
:id="'water-chart'"
key="waterchart"
title="水"
:x-data="['自来水', '纯水', '循环水']"
:series-data="[8.2, 10, 6.1]"
/>
</div>
<div class="elec-area">
<TechyLineChart :id="'elec-chart'" key="elecchart" title="电" />
</div>
<div class="elec-gen-area">
<TechyLineChart :id="'elec-gen-chart'" key="elecgenchart" title="发电" />
</div>
<div class="gas-area">
<TechyBarChart
:id="'gas-chart'"
key="gaschart"
title="气"
:x-data="['天然气', '氧气', 'CDA']"
:series-data="[8.2, 10, 6.1]"
/>
</div>
</div>
</template>
<script>
import TechyBarChart from './TechyBarChart.vue'
import TechyLineChart from './TechyLineChart.vue'
export default {
name: 'LeftContentPublicConsume',
components: { TechyBarChart, TechyLineChart },
data() {
return {}
},
created() {},
mounted() {},
methods: {}
}
</script>
<style scoped>
.public-consume__inner {
height: calc(100% - 32px);
width: 100%;
display: grid;
grid-template-areas:
'water elec elec gas'
'water elec-gen elec-gen gas';
}
.water-area {
grid-area: water;
}
.gas-area {
grid-area: gas;
}
.elec-area {
grid-area: elec;
}
.elec-gen-area {
grid-area: elec-gen;
}
/* .elec-area,.elec-gen-area {
max-height: calc((100% - 32px) / 2 - 16px);
} */
</style>

View File

@@ -0,0 +1,108 @@
<template>
<div class="right-content-alert">
<div class="el-table-wrapper">
<el-table
key="RightContentAlertTable"
border
:data="tableData"
:header-cell-style="{ background: 'rgba(79,114,136,0.29)' }"
>
<el-table-column label="设备名称" prop="eqName" :show-overflow-tooltip="true" :resizable="true" />
<el-table-column label="所属产线" prop="plName" :show-overflow-tooltip="true" :resizable="true" />
<el-table-column label="故障等级" prop="level" :resizable="true" />
<el-table-column label="故障内容" prop="content" :resizable="true" />
<el-table-column label="累计时间(min)" prop="duration" :resizable="true" />
</el-table>
</div>
</div>
</template>
<script>
// import TechyFakeTable from './TechyFakeTable.vue'
// import TechyTable from './TechyTable.vue'
const tableData = [
{ eqName: 'A1下片机', plName: 'A', content: '123456', level: 3, duration: 10 },
{ eqName: '磨片机', plName: 'A', content: '123456', level: 2, duration: 20 },
{ eqName: 'B2钢化', plName: 'B', content: 'JQKA', level: 1, duration: 30 },
{ eqName: '上片机', plName: 'C', content: 'xxx', level: 3, duration: 1 },
{ eqName: '清洗机', plName: 'B', content: 'wowowowo', level: 2, duration: 2 }
]
export default {
name: 'RightContentAlert',
components: {},
data() {
return { tableData }
},
created() {},
mounted() {},
methods: {}
}
</script>
<style scoped>
.left-content-equipment-check {
display: flex;
gap: calc(100vw / 1920 * 16);
}
.el-table-wrapper {
flex: 1;
}
.left-content-equipment-check > div {
overflow: hidden;
overflow-x: scroll;
}
.el-table-wrapper >>> * {
background: transparent;
}
.el-table-wrapper >>> .el-table::before,
.el-table-wrapper >>> .el-table--group::after,
.el-table-wrapper >>> .el-table--border::after {
background: transparent;
}
.el-table-wrapper >>> .el-table {
font-size: 8px;
background-color: transparent;
color: #fff9;
border: 0;
}
.el-table-wrapper >>> .el-table th.is-leaf,
.el-table-wrapper >>> .el-table td {
border-color: #0d1728;
padding: 0;
}
.el-table__row--striped:hover > td,
.el-table-wrapper >>> .el-table__row:hover > td {
background-color: rgba(79, 114, 136, 0.29) !important;
}
.el-table-wrapper >>> table {
border: unset;
}
.el-table-wrapper >>> thead {
color: #fff;
}
.el-table-wrapper >>> tr {
background: unset;
}
.el-table-wrapper >>> tbody td > div,
.el-table-wrapper >>> thead th > div {
white-space: nowrap;
}
.el-table-wrapper >>> th,
.el-table-wrapper >>> td {
padding: 0;
}
.el-table-wrapper >>> tbody > tr:nth-child(even) {
background: rgba(76, 97, 123, 0.2);
}
</style>

View File

@@ -0,0 +1,98 @@
<template>
<div class="right-content-quality-analysis">
<div :id="id" ref="fault-pie-chart" class="fault-pie-chart" />
</div>
</template>
<script>
import echarts from 'echarts'
import resize from '@/views/OperationalOverview/components/mixins/resize'
export default {
name: 'RightContentFaultAnalysis',
mixins: [resize],
props: {
id: {
type: String,
default: 'default-id'
},
title: {
type: String,
default: 'default-title'
},
xData: {
type: Array,
default: () => []
},
seriesData: {
type: Array,
default: () => []
}
},
data() {
return {
chart: null,
option: {
title: {
left: 'center',
top: '30%',
text: '总共',
textStyle: {
color: '#888',
fontSize: 10
},
subtext: 880,
subtextStyle: {
color: '#fff',
fontSize: 24
}
},
series: [
{
name: 'Fault Analysis Chart',
type: 'pie',
radius: ['50%', '70%'],
avoidLabelOverlap: false,
label: {},
emphasis: {
label: {
show: true,
fontSize: '12'
}
},
data: Array(7)
.fill(0)
.map((_, index) => ({ value: Math.floor(Math.random() * 100), name: '设备' + index }))
}
]
}
}
},
mounted() {
this.$nextTick(() => {
console.log('here...')
if (!this.chart) this.chart = echarts.init(this.$refs['fault-pie-chart'])
this.chart.setOption(this.option)
})
},
beforeDestroy() {
if (this.chart) this.chart.dispose()
this.chart = null
},
methods: {}
}
</script>
<style scoped>
.right-content-quality-analysis {
height: calc(100% - 32px);
}
.fault-pie-chart {
height: 100%;
width: 100%;
}
.fault-pie-chart >>> div {
width: 100% !important;
}
</style>

View File

@@ -0,0 +1,149 @@
<template>
<div style="height: 10vh; width: 100%; ">
<div :id="id" ref="techy-line-chart" class="techy-chart" />
</div>
</template>
<script>
import echarts from 'echarts'
import resize from '@/views/OperationalOverview/components/mixins/resize'
export default {
name: 'ProductRateLineChart',
mixins: [resize],
props: {
id: {
type: String,
default: 'default-id'
},
title: {
type: String,
default: 'default-title'
},
xData: {
type: Array,
default: () => []
},
seriesData: {
type: Array,
default: () => []
}
},
data() {
return {
chart: null,
option: {
color: ['#59CBE8', '#E93CAC', '#E93CAC', '#FF7345', '#9452FF', '#6A6E87', '#52FFF1'],
grid: {
top: '5%',
left: 0,
right: '5%',
bottom: 0,
containLabel: true
},
xAxis: {
type: 'category',
boundaryGap: false,
// data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
data: Array(12)
.fill(0)
.map((_, idx) => (idx >= 10 ? idx : '0' + idx) + ':00'),
axisTick: {
show: false
},
axisLabel: {
fontSize: 8,
color: '#fffa'
},
axisLine: {
lineStyle: {
color: '#fff3'
}
}
},
yAxis: {
type: 'value',
axisLine: {
show: false
},
axisLabel: {
fontSize: 10,
color: '#fffa',
formatter: '{value} %'
},
axisTick: { show: false },
splitLine: {
lineStyle: {
color: '#fff3'
}
}
},
series: [
{
name: '产线1',
type: 'line',
symbol: 'none',
data: Array(12)
.fill(0)
.map(_ => Math.floor(Math.random() * 100))
},
{
name: '产线2',
type: 'line',
symbol: 'none',
data: Array(12)
.fill(0)
.map(_ => Math.floor(Math.random() * 100))
},
{
name: '产线3',
type: 'line',
symbol: 'none',
data: Array(12)
.fill(0)
.map(_ => Math.floor(Math.random() * 100))
},
{
name: '产线4',
type: 'line',
symbol: 'none',
data: Array(12)
.fill(0)
.map(_ => Math.floor(Math.random() * 100))
},
{
name: '产线5',
type: 'line',
symbol: 'none',
data: Array(12)
.fill(0)
.map(_ => Math.floor(Math.random() * 100))
}
]
}
}
},
mounted() {
this.$nextTick(() => {
console.log('here...')
if (!this.chart) this.chart = echarts.init(this.$refs['techy-line-chart'])
this.chart.setOption(this.option)
})
},
beforeDestroy() {
if (this.chart) this.chart.dispose()
this.chart = null
},
methods: {}
}
</script>
<style scoped>
.techy-chart {
height: 100%;
width: 100%;
}
.techy-chart >>> div {
width: 100% !important;
}
</style>

View File

@@ -0,0 +1,77 @@
<template>
<div class="right-content-quality-analysis">
<div v-for="item in datalist" :key="item.name" class="analysis-item">
<span class="absolute" :style="{ backgroundColor: item.color }" />
<span>{{ item.name }}</span>
<span>{{ item.value }}</span>
</div>
</div>
</template>
<script>
export default {
name: 'RightContentQualityAnalysis',
props: {},
data() {
return {
datalist: [
{ name: '热端', value: 20, color: '#0b88ff' },
{ name: '原片', value: 30, color: '#0bffa6' },
{ name: '上片', value: 27, color: '#e3ff0b' },
{ name: '磨边', value: 23, color: '#950bff' },
{ name: '原片', value: 30, color: '#0bffa6' },
{ name: '原片', value: 30, color: '#0bffa6' },
{ name: '上片', value: 27, color: '#e3ff0b' },
{ name: '磨边', value: 23, color: '#950bff' },
{ name: '镀膜', value: 10, color: '#ff0bc2' },
{ name: '清晰', value: 66, color: '#ff7d0b' }
]
}
},
created() {},
mounted() {},
methods: {}
}
</script>
<style scoped>
.right-content-quality-analysis {
height: calc(100% - 32px);
overflow: hidden;
overflow-y: scroll; /** 右边会有多的padding给滑道 */
display: grid;
grid-template-columns: 1fr 1fr;
grid-auto-rows: min-content;
gap: calc(100vw / 1920 * 8);
justify-content: end;
}
.analysis-item {
padding-left: 16px;
font-size: 12px;
line-height: 1.5;
display: flex;
align-items: center;
justify-content: space-between;
color: #fffc;
position: relative;
}
.analysis-item::before {
content: '';
position: absolute;
left: 4px;
width: 8px;
height: 8px;
border-radius: 50%;
background-color: attr(data-color color, blue);
}
.absolute {
position: absolute;
width: 8px;
height: 8px;
left: 3px;
border-radius: 50%;
}
</style>

View File

@@ -0,0 +1,127 @@
<template>
<div style="height: 12vh; width: 100%; ">
<div :id="id" ref="techy-line-chart" class="techy-chart" />
</div>
</template>
<script>
import echarts from 'echarts'
import resize from '@/views/OperationalOverview/components/mixins/resize'
export default {
name: 'RealtimeProductionHorizontalBarChart',
mixins: [resize],
props: {
id: {
type: String,
default: 'default-id'
},
title: {
type: String,
default: 'default-title'
},
xData: {
type: Array,
default: () => []
},
seriesData: {
type: Array,
default: () => []
}
},
data() {
return {
chart: null,
option: {
color: ['#FF7345', '#52FFF1', '#6A6E87', '#9452FFA6'],
grid: {
top: 0,
left: 0,
right: '5%',
bottom: 0,
containLabel: true
},
xAxis: {
type: 'value',
boundaryGap: [0, 0.001],
axisTick: {
show: false
},
axisLabel: {
fontSize: 8
// rotate: 10
},
axisLine: {
show: false,
lineStyle: {
color: '#fffa'
}
},
splitLine: {
lineStyle: {
color: '#fff3'
}
}
},
yAxis: {
type: 'category',
data: ['产线1', '产线2', '产线3', '产线4', '产线5', '产线6'],
axisLine: {
show: false
},
axisLabel: {
fontSize: 10,
color: '#fffa'
},
axisTick: { show: false },
splitLine: {
lineStyle: {
color: '#fffa'
}
}
},
series: [
{
name: '2011',
type: 'bar',
barWidth: 5,
data: Array(6)
.fill(0)
.map(value => Math.floor(Math.random() * 1000))
},
{
name: '2012',
type: 'bar',
barWidth: 5,
data: Array(6)
.fill(0)
.map(value => Math.floor(Math.random() * 1000))
}
]
}
}
},
mounted() {
this.$nextTick(() => {
console.log('here...')
if (!this.chart) this.chart = echarts.init(this.$refs['techy-line-chart'])
this.chart.setOption(this.option)
})
},
beforeDestroy() {
if (this.chart) this.chart.dispose()
this.chart = null
},
methods: {}
}
</script>
<style scoped>
.techy-chart {
height: 100%;
width: 100%;
}
.techy-chart >>> div {
width: 100% !important;
}
</style>

View File

@@ -0,0 +1,136 @@
<template>
<div :id="id" ref="techy-bar-chart" class="techy-chart" />
</template>
<script>
import echarts from 'echarts'
import resize from '@/views/OperationalOverview/components/mixins/resize'
export default {
name: 'TechyBarChart',
mixins: [resize],
/** Fn.1: 保证全屏切换时也刷新图表 应该在每个父组件为flex:1的echarts组件里都加上以确保能正确地伸缩 */
inject: ['resizeStatus'],
/** End Fn.1 */
props: {
id: {
type: String,
default: 'default-id'
},
title: {
type: String,
default: 'default-title'
},
xData: {
type: Array,
default: () => []
},
seriesData: {
type: Array,
default: () => []
}
},
data() {
const colors = ['#61A5E8', '#7ECF51', '#EECB5F']
return {
chart: null,
option: {
// default option
grid: {
top: '20%',
left: '8%',
bottom: '16px',
right: '8%'
},
title: {
text: this.title,
left: 'center',
textStyle: {
color: '#fffa',
fontSize: 12
}
},
xAxis: {
type: 'category',
data: this.xData,
axisTick: {
show: false
},
axisLabel: {
fontSize: 8
// rotate: 10
},
axisLine: {
lineStyle: {
color: '#fffa'
}
}
},
yAxis: {
type: 'value',
axisLine: {
show: false
},
axisLabel: {
fontSize: 10,
align: 'left',
color: '#fffa'
},
axisTick: { show: false },
splitLine: {
lineStyle: {
color: '#fffa'
}
}
},
series: {
type: 'bar',
barMaxWidth: 30,
data: this.seriesData.map((value, index) => ({
itemStyle: {
color: colors[index]
},
value
}))
}
}
}
},
computed: {
shouldResize() {
return this.resizeStatus()
}
},
watch: {
shouldResize(val, oldVal) {
setTimeout(() => {
this.chart.resize()
}, 250)
}
},
mounted() {
this.$nextTick(() => {
if (!this.chart) this.chart = echarts.init(this.$refs['techy-bar-chart'])
this.chart.setOption(this.option)
})
},
beforeDestroy() {
if (this.chart) this.chart.dispose()
this.chart = null
},
methods: {}
}
</script>
<style scoped>
.techy-chart {
height: 100%;
width: 100%;
}
.techy-chart >>> div {
width: 100% !important;
height: 100% !important;
}
</style>

View File

@@ -0,0 +1,20 @@
<template>
<div class="techy-box">
<slot />
</div>
</template>
<script>
export default {}
</script>
<style scoped>
.techy-box {
background: transparent;
box-shadow: inset 0 0 16px 1px rgba(255, 255, 255, 0.5);
display: inline-block;
height: 100%;
width: 100%;
border-radius: .25rem;
}
</style>

View File

@@ -0,0 +1,141 @@
<template>
<div class="techy-container">
<template v-if="showCorner">
<div class="line top left vertical" />
<div class="line top left horizontal" />
<div class="line top right vertical" />
<div class="line top right horizontal " />
<div class="line bottom right horizontal" />
<div class="line bottom right vertical" />
<div class="line bottom left vertical" />
<div class="line bottom left horizontal" />
</template>
<div class="container-title-wrapper">
<span class="container-icon" v-html="icon" />
<span class="container-title">{{ title }}</span>
</div>
<slot />
</div>
</template>
<script>
const defaultIcon = `<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>质量上报</title>
<g id="2MES。2-6蓝底-7、8白底" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="2-5质量管理" transform="translate(-384.000000, -254.000000)">
<g id="编组-16备份-6" transform="translate(360.000000, 230.000000)">
<g id="编组" transform="translate(24.000000, 24.000000)">
<polygon id="Fill-1" fill="#3B71B2" opacity="0" points="0 24 24 24 24 0 0 0"></polygon>
<path d="M22.6282,17.3303 C22.4272,17.3513 22.2812,17.5283 22.2982,17.7293 L22.2982,20.1493 L16.4582,20.1493 L16.4582,17.7403 C16.4582,17.5633 16.3152,17.4203 16.1382,17.4203 C15.9612,17.4203 15.8182,17.5633 15.8182,17.7403 L15.8182,20.1703 C15.7822,20.5643 16.0652,20.9183 16.4582,20.9703 L22.3082,20.9703 C22.7052,20.9233 22.9932,20.5683 22.9582,20.1703 L22.9582,17.7503 C22.9762,17.5523 22.8352,17.3763 22.6382,17.3503 L22.6282,17.3303 Z" id="Fill-3" fill="#6EF9E1"></path>
<path d="M15.8982,17.8 L15.8982,20.15 C15.8622,20.495 16.1052,20.809 16.4482,20.86 L22.2982,20.86 C22.6462,20.814 22.8942,20.499 22.8582,20.15 L22.8582,17.73 C22.8582,17.56 22.7482,17.42 22.6282,17.42 C22.4772,17.441 22.3702,17.578 22.3882,17.73 L22.3882,20.24 L16.3882,20.24 L16.3882,17.72 C16.3882,17.56 16.2782,17.43 16.1582,17.43 C16.0382,17.43 15.9382,17.56 15.9282,17.72 L15.8982,17.8 Z M22.2982,21.04 L16.4582,21.04 C16.0112,20.992 15.6832,20.598 15.7182,20.15 L15.7182,17.67 C15.7192,17.449 15.8992,17.271 16.1202,17.2729833 C16.3392,17.274 16.5172,17.45 16.5182,17.67 L16.5182,20.1 L22.1782,20.1 L22.1782,17.78 C22.1422,17.551 22.2992,17.336 22.5282,17.3 C22.7572,17.265 22.9722,17.421 23.0082,17.651 C23.0152,17.694 23.0152,17.738 23.0082,17.78 L23.0082,20.2 C23.0182,20.619 22.7132,20.98 22.2982,21.04 L22.2982,21.04 Z" id="Fill-5" fill="#6EF9E1"></path>
<path d="M19.7483,12.5002 C19.7033,12.4462 19.6443,12.4042 19.5783,12.3802 L19.1783,12.3802 C19.1103,12.4012 19.0513,12.4432 19.0083,12.5002 L17.5583,14.1302 C17.3733,14.3372 17.3913,14.6552 17.5983,14.8402 C17.8053,15.0242 18.1233,15.0072 18.3083,14.8002 L18.8783,14.1402 L18.8783,17.8992 C18.8773,17.9162 18.8773,17.9342 18.8783,17.9502 L18.8783,18.3002 C18.8833,18.5732 19.1043,18.7952 19.3783,18.8002 C19.6503,18.7942 19.8683,18.5722 19.8683,18.3002 L19.8683,14.0902 L20.4483,14.7502 C20.6333,14.9572 20.9513,14.9752 21.1583,14.7902 C21.3653,14.6042 21.3833,14.2872 21.1983,14.0802 L19.7483,12.5002 Z" id="Fill-7" fill="#6FFADE"></path>
<path d="M13.7781,19.5002 L3.0881,19.5002 C2.6541,19.5852 2.3721,20.0062 2.4571,20.4382 C2.5201,20.7582 2.7691,21.0072 3.0881,21.0692 L13.7981,21.0692 C14.2291,20.9722 14.4991,20.5432 14.4011,20.1122 C14.3321,19.8122 14.0981,19.5782 13.7981,19.5102 L13.7781,19.5002 Z" id="Fill-9" fill="#6FFADE"></path>
<path d="M17.2684,2.9104 L5.3984,2.9104 C3.7414,2.9104 2.3984,4.2534 2.3984,5.9104 L2.3984,15.3704 C2.3984,17.0264 3.7414,18.3704 5.3984,18.3704 L13.7084,18.3704 C14.0684,18.3704 14.3484,17.9504 14.3484,17.5904 C14.3484,17.2294 14.0684,16.8004 13.7084,16.8004 L5.7084,16.8004 C4.7694,16.8064 4.0034,16.0494 3.9984,15.1094 L3.9984,15.0904 L3.9984,6.1894 C3.9984,5.2674 4.7464,4.5194 5.6684,4.5194 L17.1184,4.5194 C18.0404,4.5194 18.7884,5.2674 18.7884,6.1894 L18.7884,10.2904 L18.7884,10.3804 L18.7884,10.4604 C18.8484,10.8524 19.2144,11.1234 19.6084,11.0634 C19.9794,11.0084 20.2454,10.6754 20.2184,10.3004 L20.2184,5.8704 C20.1974,4.2484 18.8904,2.9364 17.2684,2.9104" id="Fill-11" fill="#6FFADE"></path>
<path d="M22.6282,17.3303 C22.4272,17.3513 22.2812,17.5283 22.2982,17.7293 L22.2982,20.1493 L16.4582,20.1493 L16.4582,17.7403 C16.4582,17.5633 16.3152,17.4203 16.1382,17.4203 C15.9612,17.4203 15.8182,17.5633 15.8182,17.7403 L15.8182,20.1703 C15.7822,20.5643 16.0652,20.9183 16.4582,20.9703 L22.3082,20.9703 C22.7052,20.9233 22.9932,20.5683 22.9582,20.1703 L22.9582,17.7503 C22.9762,17.5523 22.8352,17.3763 22.6382,17.3503 L22.6282,17.3303 Z" id="Fill-13" fill="#6EF9E1"></path>
<path d="M22.6282,17.3303 C22.4272,17.3513 22.2812,17.5283 22.2982,17.7293 L22.2982,20.1493 L16.4582,20.1493 L16.4582,17.7403 C16.4582,17.5633 16.3152,17.4203 16.1382,17.4203 C15.9612,17.4203 15.8182,17.5633 15.8182,17.7403 L15.8182,20.1703 C15.7822,20.5643 16.0652,20.9183 16.4582,20.9703 L22.3082,20.9703 C22.7052,20.9233 22.9932,20.5683 22.9582,20.1703 L22.9582,17.7503 C22.9762,17.5523 22.8352,17.3763 22.6382,17.3503 L22.6282,17.3303 Z" id="Stroke-15" stroke="#6EF9E1" stroke-width="0.2"></path>
<path d="M19.7483,12.5002 C19.7033,12.4462 19.6443,12.4042 19.5783,12.3802 L19.1783,12.3802 C19.1103,12.4012 19.0513,12.4432 19.0083,12.5002 L17.5583,14.1302 C17.3733,14.3372 17.3913,14.6552 17.5983,14.8402 C17.8053,15.0242 18.1233,15.0072 18.3083,14.8002 L18.8783,14.1402 L18.8783,17.8992 C18.8773,17.9162 18.8773,17.9342 18.8783,17.9502 L18.8783,18.3002 C18.8833,18.5732 19.1043,18.7952 19.3783,18.8002 C19.6503,18.7942 19.8683,18.5722 19.8683,18.3002 L19.8683,14.0902 L20.4483,14.7502 C20.6333,14.9572 20.9513,14.9752 21.1583,14.7902 C21.3653,14.6042 21.3833,14.2872 21.1983,14.0802 L19.7483,12.5002 Z" id="Fill-17" fill="#6FFADE"></path>
<path d="M12.2967,6.8498 L11.9997,12.7348 C11.9267,13.1178 11.5587,13.3688 11.1757,13.2948 C10.8917,13.2418 10.6697,13.0188 10.6147,12.7348 L10.3057,6.8498 L10.3057,6.7878 C10.3937,6.2348 10.9127,5.8568 11.4647,5.9438 C11.8997,6.0118 12.2407,6.3528 12.3087,6.7878 C12.3137,6.8078 12.3137,6.8288 12.3087,6.8498 L12.2967,6.8498 Z M11.3077,15.4668 C10.9047,15.4878 10.5627,15.1778 10.5417,14.7758 C10.5217,14.3728 10.8317,14.0308 11.2337,14.0098 C11.6357,13.9898 11.9787,14.2988 11.9987,14.7018 C11.9997,14.7178 12.0007,14.7338 11.9997,14.7498 C12.0067,15.1388 11.6967,15.4598 11.3077,15.4668 Z" id="Fill-19" fill="#6EF9E1"></path>
<path d="M13.7781,19.5002 L3.0881,19.5002 C2.6541,19.5852 2.3721,20.0062 2.4571,20.4382 C2.5201,20.7582 2.7691,21.0072 3.0881,21.0692 L13.7981,21.0692 C14.2291,20.9722 14.4991,20.5432 14.4011,20.1122 C14.3321,19.8122 14.0981,19.5782 13.7981,19.5102 L13.7781,19.5002 Z" id="Fill-21" fill="#6FFADE"></path>
<path d="M17.2684,2.9104 L5.3984,2.9104 C3.7414,2.9104 2.3984,4.2534 2.3984,5.9104 L2.3984,15.3704 C2.3984,17.0264 3.7414,18.3704 5.3984,18.3704 L13.7084,18.3704 C14.0684,18.3704 14.3484,17.9504 14.3484,17.5904 C14.3484,17.2294 14.0684,16.8004 13.7084,16.8004 L5.7084,16.8004 C4.7694,16.8064 4.0034,16.0494 3.9984,15.1094 L3.9984,15.0904 L3.9984,6.1894 C3.9984,5.2674 4.7464,4.5194 5.6684,4.5194 L17.1184,4.5194 C18.0404,4.5194 18.7884,5.2674 18.7884,6.1894 L18.7884,10.2904 L18.7884,10.3804 L18.7884,10.4604 C18.8484,10.8524 19.2144,11.1234 19.6084,11.0634 C19.9794,11.0084 20.2454,10.6754 20.2184,10.3004 L20.2184,5.8704 C20.1974,4.2484 18.8904,2.9364 17.2684,2.9104" id="Fill-23" fill="#6FFADE"></path>
</g>
</g>
</g>
</g>
</svg>`
export default {
name: 'TechyContainer',
props: {
title: { type: String, default: '默认标题' },
icon: { type: String, default: defaultIcon },
showCorner: {
type: Boolean,
default: true
}
},
data() {
return {}
},
mounted() {}
}
</script>
<style scoped>
.techy-container {
border: 2px solid #52fff1;
border-image: linear-gradient(90deg, rgba(82, 255, 241, 0.6), rgba(95, 190, 249, 0), rgba(82, 255, 241, 0.6)) 2 2;
display: inline-block;
position: relative;
/* padding: 24px; */
padding: calc(100vw / 1920 * 22);
width: 100%;
height: 100%;
box-shadow: inset 0px 0px 20px 0px rgba(255, 255, 255, 0.15);
/* background: rgba(20, 69, 100, 0.425); */
background: rgba(6, 16, 39, 0.3);
backdrop-filter: blur(1px);
}
.line {
position: absolute;
background-color: #52fff1;
}
.horizontal {
/* height: 4px;
width: 24px; */
/* height: 0.325vh;
width: 3vh; */
height: calc(100vw / 1920 * 4);
width: calc(100vw / 1920 * 30);
}
.vertical {
/* height: 24px;
width: 4px; */
/* height: 3vh;
width: 0.325vh; */
height: calc(100vw / 1920 * 30);
width: calc(100vw / 1920 * 4);
}
.top {
top: -3px;
}
.left {
left: -3px;
}
.right {
right: -3px;
}
.bottom {
bottom: -3px;
}
.container-title-wrapper {
color: #52fff1;
display: flex;
align-items: center;
/* font-size: 18px;
line-height: 1;
height: 24px;
margin-bottom: 8px; */
/* font-size: 1.25vh;
line-height: 1;
height: 1.5vh;
margin-bottom: 1.25vh; */
font-size: calc((100vw / 1920) * 16);
line-height: 1;
height: calc((100vw / 1920) * 20);
margin-bottom: 1.5vh;
}
.container-title {
margin-left: 4px;
}
</style>

View File

@@ -0,0 +1,63 @@
<template>
<div class="techy-fake-table">
<div class="table-inner">
<section class="table-header" />
<section class="table-body" />
</div>
</div>
</template>
<script>
export default {
name: '',
props: {
tableProps: {
type: Array,
default: () => []
},
tableData: {
type: Array,
default: () => []
}
},
data() {
return {
headMap: {}
}
},
created() {},
mounted() {
this.renderHeadRow().then(() => {
this.renderCommonRow()
})
},
methods: {
renderHeadRow() {
return new Promise((resolve, reject) => {
// do something...
})
},
renderCommonRow() {
return new Promise((resolve, reject) => {
// do something...
})
}
}
}
</script>
<style scoped>
.techy-fake-table {
position: relative;
width: 100%;
height: 100px;
background: #3333;
overflow: hidden;
overflow-x: scroll;
}
.table-inner {
max-width: 10000px;
color: white;
white-space: nowrap;
}
</style>

View File

@@ -0,0 +1,154 @@
<template>
<header class="techy-header">
<img class="logo-img" src="./logo.png" alt="cnbm">
<span class="techy-header__title">{{ headTitle }}</span>
<div class="date">2022.10.14</div>
<div class="time">20:12:24</div>
<div class="fullscreen-btn">
<span style="color: #52fff1; margin-right: 8px;" @click="handleClick('home')" v-html="homeSvg" />
<span v-if="isFullScreen" @click="handleClick('fullscreen')" v-html="unfullScreenSvg" />
<span v-else @click="handleClick('fullscreen')" v-html="fullScreenSvg" />
</div>
</header>
</template>
<script>
// const homeSvg = `<svg width="32px" height="32px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
const homeSvg = `<svg style="width: 100%; height: 100%" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>首页</title>
<g id="1大屏" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="1大屏-数字工厂总览" transform="translate(-1824.000000, -46.000000)" fill-rule="nonzero">
<g id="首页" transform="translate(1824.000000, 46.000000)">
<rect id="矩形" fill="#000000" opacity="0" x="0" y="0" width="32" height="32"></rect>
<path d="M3.36212554,9.99760304 L14.4561021,2.03491762 C15.37881,1.37257076 16.62119,1.37257076 17.5438979,2.03491762 L28.6378745,9.99760304 C29.7265595,10.7789878 30.3723957,12.0369335 30.3723957,13.3770071 L30.3723957,26.217608 C30.3723957,28.5153002 28.5096576,30.3780383 26.2119654,30.3780383 L5.78803465,30.3780383 C3.49034244,30.3780383 1.62760433,28.5153002 1.62760433,26.217608 L1.62760433,13.3773853 C1.62760433,12.0371783 2.27333209,10.7790656 3.36212554,9.99760304 Z M4.68552062,11.8410519 C4.19052975,12.196239 3.89692996,12.7681449 3.89692996,13.3773853 L3.89692996,26.217608 C3.89692996,27.2620363 4.74360637,28.1087127 5.78803465,28.1087127 L26.2119654,28.1087127 C27.2563936,28.1087127 28.10307,27.2620363 28.10307,26.217608 L28.10307,13.3773853 C28.10307,12.7681449 27.8094702,12.196239 27.3144794,11.8410519 L16.2205028,3.87836647 C16.0887105,3.78379718 15.9112895,3.78379718 15.7794972,3.87836647 L4.68552062,11.8414301 L4.68552062,11.8410519 Z" id="形状" fill="#42D0CE"></path>
<path d="M16.25,17 C16.8972087,17 17.4295339,17.4918747 17.4935464,18.1221948 L17.5,18.25 L17.5,28.25 C17.5,28.9403559 16.9403559,29.5 16.25,29.5 C15.6027913,29.5 15.0704661,29.0081253 15.0064536,28.3778052 L15,28.25 L15,18.25 C15,17.5596441 15.5596441,17 16.25,17 Z" id="路径-3" fill="#42D0CE"></path>
</g>
</g>
</g>
</svg>`
// const fullScreenSvg = `<svg width="32px" height="32px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
const fullScreenSvg = `<svg style="width: 100%; height: 100%" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>编组 54备份</title>
<g id="2MES。2-6蓝底-7、8白底" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="2-4设备管理" transform="translate(-1864.000000, -162.000000)">
<g id="编组-54备份" transform="translate(1864.000000, 162.000000)">
<rect id="矩形" stroke="#979797" fill="#D8D8D8" opacity="0" x="0.5" y="0.5" width="31" height="31"></rect>
<path d="M26.7638125,1.45454545 L27.0177905,1.4628567 C27.4387521,1.49054436 27.8474996,1.58732758 28.2359531,1.75197014 C28.6866948,1.94029725 29.0896137,2.2117619 29.4389259,2.56107409 C29.7857111,2.90785927 30.0584977,3.31352185 30.2477734,3.76343947 C30.4456009,4.23019115 30.5454545,4.72555866 30.5454545,5.23618754 L30.5454545,5.23618754 L30.5454545,26.7638125 L30.5371433,27.0177905 C30.5094556,27.4387521 30.4126724,27.8474996 30.2480299,28.2359531 C30.0597028,28.6866948 29.7882381,29.0896137 29.4389259,29.4389259 C29.0921407,29.7857111 28.6864782,30.0584977 28.2365605,30.2477734 C27.7698088,30.4456009 27.2744413,30.5454545 26.7638125,30.5454545 L26.7638125,30.5454545 L5.23618754,30.5454545 L4.98220952,30.5371433 C4.56124792,30.5094556 4.15250044,30.4126724 3.7640469,30.2480299 C3.31330516,30.0597028 2.91038628,29.7882381 2.56107409,29.4389259 C2.21428891,29.0921407 1.94150232,28.6864782 1.75222663,28.2365605 C1.55439906,27.7698088 1.45454545,27.2744413 1.45454545,26.7638125 L1.45454545,26.7638125 L1.45454545,5.23618754 L1.4628567,4.98220952 C1.49054436,4.56124792 1.58732758,4.15250044 1.75197014,3.7640469 C1.94029725,3.31330516 2.2117619,2.91038628 2.56107409,2.56107409 C2.90785927,2.21428891 3.31352185,1.94150232 3.76343947,1.75222663 C4.23019115,1.55439906 4.72555866,1.45454545 5.23618754,1.45454545 L5.23618754,1.45454545 L26.7638125,1.45454545 Z M26.7638125,3.33876293 L5.23618754,3.33876293 L5.08796584,3.34447462 C4.10971624,3.42016081 3.33876293,4.23861746 3.33876293,5.23618754 L3.33876293,5.23618754 L3.33876293,26.7638125 L3.34447462,26.9120342 C3.42016081,27.8902838 4.23861746,28.6612371 5.23618754,28.6612371 L5.23618754,28.6612371 L26.7638125,28.6612371 L26.9120342,28.6555254 C27.8902838,28.5798392 28.6612371,27.7613825 28.6612371,26.7638125 L28.6612371,26.7638125 L28.6612371,5.23618754 L28.6555254,5.08796584 C28.5798392,4.10971624 27.7613825,3.33876293 26.7638125,3.33876293 L26.7638125,3.33876293 Z M6.64116798,17.2700375 L6.74890704,17.2784355 C7.20902464,17.3410097 7.56504512,17.7372269 7.56504512,18.2121946 L7.56504512,18.2121946 L7.56504512,23.06998 L12.2154875,18.4195377 L12.3038841,18.341579 C12.6723846,18.0557307 13.2096238,18.0817169 13.5474445,18.4195377 C13.9134169,18.7855101 13.9134169,19.3855223 13.5474445,19.7514947 L13.5474445,19.7514947 L8.86035653,24.4349549 L13.6953555,24.4349549 L13.8090001,24.4414765 C14.2937488,24.4974586 14.6711425,24.9068233 14.6639054,25.3965331 C14.6534571,25.9083109 14.2345395,26.3191724 13.7217698,26.3191724 L13.7217698,26.3191724 L6.64604887,26.3191724 L6.53329365,26.3126932 C6.05255502,26.2570589 5.68082765,25.8499062 5.68082765,25.3539511 L5.68082765,25.3539511 L5.68082765,18.2353071 L5.68737703,18.1218678 C5.74358847,17.6379293 6.15445128,17.2603996 6.64116798,17.2700375 L6.64116798,17.2700375 Z M25.3605547,5.68082765 L25.4723738,5.68728667 C25.9492196,5.74274215 26.3191724,6.14846553 26.3191724,6.6394453 L26.3191724,6.6394453 L26.3191724,13.7613912 L26.312623,13.8748304 C26.2564115,14.3587689 25.8455487,14.7362986 25.358832,14.7266607 C24.8478544,14.716179 24.4349549,14.2960073 24.4349549,13.7845036 L24.4349549,13.7845036 L24.4349549,8.93001999 L19.7845125,13.5804623 L19.6961159,13.658421 C19.3276154,13.9442693 18.7903762,13.9182831 18.4525555,13.5804623 C18.0865831,13.2144899 18.0865831,12.6144777 18.4525555,12.2485053 L18.4525555,12.2485053 L23.1360157,7.56504512 L18.3013427,7.56504512 L18.1876721,7.55852521 C17.7028859,7.50255928 17.3264448,7.09334546 17.3360737,6.60468076 C17.3465429,6.0916891 17.7654605,5.68082765 18.2782302,5.68082765 L18.2782302,5.68082765 L25.3605547,5.68082765 Z" id="形状结合" fill="#52FFF1" fill-rule="nonzero" opacity="0.79078311"></path>
</g>
</g>
</g>
</svg>`
// const unfullScreenSvg = `<svg width="32px" height="32px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
const unfullScreenSvg = `<svg style="width: 100%; height: 100%" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>编组 54备份 2</title>
<g id="3WMS。1、2、3、4、5、6" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="编组-54备份-2">
<rect id="矩形" stroke="#979797" fill="#D8D8D8" opacity="0" x="0.5" y="0.5" width="31" height="31"></rect>
<path d="M26.7638125,1.45454545 L27.0177905,1.4628567 C27.4387521,1.49054436 27.8474996,1.58732758 28.2359531,1.75197014 C28.6866948,1.94029725 29.0896137,2.2117619 29.4389259,2.56107409 C29.7857111,2.90785927 30.0584977,3.31352185 30.2477734,3.76343947 C30.4456009,4.23019115 30.5454545,4.72555866 30.5454545,5.23618754 L30.5454545,5.23618754 L30.5454545,26.7638125 L30.5371433,27.0177905 C30.5094556,27.4387521 30.4126724,27.8474996 30.2480299,28.2359531 C30.0597028,28.6866948 29.7882381,29.0896137 29.4389259,29.4389259 C29.0921407,29.7857111 28.6864782,30.0584977 28.2365605,30.2477734 C27.7698088,30.4456009 27.2744413,30.5454545 26.7638125,30.5454545 L26.7638125,30.5454545 L5.23618754,30.5454545 L4.98220952,30.5371433 C4.56124792,30.5094556 4.15250044,30.4126724 3.7640469,30.2480299 C3.31330516,30.0597028 2.91038628,29.7882381 2.56107409,29.4389259 C2.21428891,29.0921407 1.94150232,28.6864782 1.75222663,28.2365605 C1.55439906,27.7698088 1.45454545,27.2744413 1.45454545,26.7638125 L1.45454545,26.7638125 L1.45454545,5.23618754 L1.4628567,4.98220952 C1.49054436,4.56124792 1.58732758,4.15250044 1.75197014,3.7640469 C1.94029725,3.31330516 2.2117619,2.91038628 2.56107409,2.56107409 C2.90785927,2.21428891 3.31352185,1.94150232 3.76343947,1.75222663 C4.23019115,1.55439906 4.72555866,1.45454545 5.23618754,1.45454545 L5.23618754,1.45454545 L26.7638125,1.45454545 Z M26.7638125,3.33876293 L5.23618754,3.33876293 L5.08796584,3.34447462 C4.10971624,3.42016081 3.33876293,4.23861746 3.33876293,5.23618754 L3.33876293,5.23618754 L3.33876293,26.7638125 L3.34447462,26.9120342 C3.42016081,27.8902838 4.23861746,28.6612371 5.23618754,28.6612371 L5.23618754,28.6612371 L26.7638125,28.6612371 L26.9120342,28.6555254 C27.8902838,28.5798392 28.6612371,27.7613825 28.6612371,26.7638125 L28.6612371,26.7638125 L28.6612371,5.23618754 L28.6555254,5.08796584 C28.5798392,4.10971624 27.7613825,3.33876293 26.7638125,3.33876293 L26.7638125,3.33876293 Z M13.6987866,17.269857 L13.8115418,17.2763362 C14.2922804,17.3319705 14.6640078,17.7391232 14.6640078,18.2350783 L14.6640078,18.2350783 L14.6640078,25.3537223 L14.6574584,25.4671616 C14.6012469,25.9511001 14.1903841,26.3286298 13.7036674,26.3189919 L13.7036674,26.3189919 L13.5959284,26.3105939 C13.1358108,26.2480197 12.7797903,25.8518025 12.7797903,25.3768348 L12.7797903,25.3768348 L12.7797903,20.5190494 L8.12934794,25.1694917 L8.04095127,25.2474504 C7.67245079,25.5332987 7.13521162,25.5073124 6.79739091,25.1694917 C6.43141847,24.8035193 6.43141847,24.2035071 6.79739091,23.8375347 L6.79739091,23.8375347 L11.4844789,19.1540745 L6.64947993,19.1540745 L6.53583534,19.1475529 C6.05108664,19.0915708 5.67369292,18.6822061 5.68093001,18.1924962 C5.69137836,17.6807185 6.11029591,17.269857 6.62306566,17.269857 L6.62306566,17.269857 L13.6987866,17.269857 Z M18.2962333,5.68100813 C18.807211,5.69148979 19.2201105,6.11166149 19.2201105,6.62316519 L19.2201105,6.62316519 L19.2201105,11.4776488 L23.8705528,6.82720649 L23.9589495,6.74924786 C24.32745,6.46339956 24.8646892,6.48938577 25.2025099,6.82720649 C25.5684823,7.19317893 25.5684823,7.79319108 25.2025099,8.15916352 L25.2025099,8.15916352 L20.5190497,12.8426237 L25.3537226,12.8426237 L25.4673933,12.8491436 C25.9521795,12.9051095 26.3286206,13.3143234 26.3189917,13.8029881 C26.3085224,14.3159797 25.8896049,14.7268412 25.3768351,14.7268412 L25.3768351,14.7268412 L18.2945107,14.7268412 L18.1826915,14.7203822 C17.7058457,14.6649267 17.335893,14.2592033 17.335893,13.7682235 L17.335893,13.7682235 L17.335893,6.64627767 L17.3424424,6.53283844 C17.3986538,6.04889994 17.8095166,5.67137018 18.2962333,5.68100813 Z" id="形状结合" fill="#52FFF1" fill-rule="nonzero" opacity="0.79078311"></path>
</g>
</g>
</svg>`
export default {
name: 'TechyHeader',
props: ['headTitle'],
data() {
return {
fullScreenSvg,
homeSvg,
unfullScreenSvg,
isFullScreen: false
}
},
methods: {
handleClick(source) {
if (source === 'fullscreen') {
this.isFullScreen = !this.isFullScreen
this.$emit('toggle-full-screen', { full: this.isFullScreen })
} else if (source === 'home') {
this.$router.push('/')
}
}
}
}
</script>
<style scoped>
.techy-header {
background: transparent;
display: flex;
justify-content: center;
align-items: center;
position: relative;
color: white;
/* font-size: 24px; */
font-size: 2vh;
padding: calc(100vw / 1920 * 32) 0;
line-height: 1;
background: url(./header-longer.png) no-repeat;
/** 背景图片好像左右不对称 : */
/* background-position: bottom left 40px; */
/* background-size: cover; */
background-size: 100% 100%;
/* background-position: bottom left calc(100vw / 1920 * 40); */
background-position: bottom;
height: calc(100vmin / 1920 * 128);
}
.logo-img {
width: calc(100vmin / 1920 * 48);
}
.techy-header__title {
display: line-block;
margin-left: calc(100vmin / 1920 * 12);
/* font-size: 29px; */
font-size: calc(100vmin / 1920 * 48);
line-height: 41px;
letter-spacing: 4px;
text-shadow: 0px 0px 11px rgba(221, 237, 255, 0.34);
}
.date,
.time {
font-size: calc(100vmin / 1920 * 42);
line-height: 1.5;
/* font-size: 28px;
line-height: 36px; */
color: #49e1de;
letter-spacing: 0.8px;
position: absolute;
bottom: calc(100vmin / 1920 * 14 );
}
.date {
/* left: 72px; */
left: calc(100vmin / 1920 * 72);
}
.time {
/* right: 128px; */
right: calc(100vmin / 1920 * 186);
}
.fullscreen-btn {
/* height: 32px; */
cursor: pointer;
position: absolute;
/* right: 24px; */
/** techy-body 的内部 padding 值 */
right: calc(100vmin / 1920 * 32);
/* top: 42px; */
top: calc(100vmin / 1920 * 52);
bottom: 0;
}
.fullscreen-btn > span {
display: inline-block;
width: calc(100vmin / 1920 * 52);
height: calc(100vmin / 1920 * 52);
}
</style>

View File

@@ -0,0 +1,170 @@
<template>
<div :id="id" ref="techy-line-chart" class="techy-chart" />
</template>
<script>
import echarts from 'echarts'
import resize from '@/views/OperationalOverview/components/mixins/resize'
export default {
name: 'TechyLineChart',
mixins: [resize],
/** Fn.1: 保证全屏切换时也刷新图表 应该在每个父组件为flex:1的echarts组件里都加上以确保能正确地伸缩 */
inject: ['resizeStatus'],
/** End Fn.1 */
props: {
id: {
type: String,
default: 'default-id'
},
title: {
type: String,
default: 'default-title'
},
xData: {
type: Array,
default: () => []
},
seriesData: {
type: Array,
default: () => []
}
},
data() {
return {
chart: null,
option: {
title: {
text: this.title,
left: 'center',
textStyle: {
color: '#fffa',
fontSize: 12
}
},
color: ['#59CBE8', '#E93CAC', '#E93CAC', '#FF7345', '#9452FF', '#6A6E87', '#52FFF1'],
grid: {
top: '18px',
left: 0,
right: '5%',
bottom: 0,
containLabel: true
},
xAxis: {
type: 'category',
boundaryGap: false,
// data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
data: Array(12)
.fill(0)
.map((_, idx) => (idx >= 10 ? idx : '0' + idx) + ':00'),
axisTick: {
show: false
},
axisLabel: {
fontSize: 8,
color: '#fffa'
},
axisLine: {
lineStyle: {
color: '#fff3'
}
}
},
yAxis: {
type: 'value',
axisLine: {
show: false
},
axisLabel: {
fontSize: 10,
color: '#fffa',
formatter: '{value} %'
},
axisTick: { show: false },
splitLine: {
lineStyle: {
color: '#fff3'
}
}
},
series: [
{
name: '产线1',
type: 'line',
symbol: 'none',
data: Array(12)
.fill(0)
.map(_ => Math.floor(Math.random() * 100))
},
{
name: '产线2',
type: 'line',
symbol: 'none',
data: Array(12)
.fill(0)
.map(_ => Math.floor(Math.random() * 100))
},
{
name: '产线3',
type: 'line',
symbol: 'none',
data: Array(12)
.fill(0)
.map(_ => Math.floor(Math.random() * 100))
},
{
name: '产线4',
type: 'line',
symbol: 'none',
data: Array(12)
.fill(0)
.map(_ => Math.floor(Math.random() * 100))
},
{
name: '产线5',
type: 'line',
symbol: 'none',
data: Array(12)
.fill(0)
.map(_ => Math.floor(Math.random() * 100))
}
]
}
}
},
computed: {
shouldResize() {
return this.resizeStatus()
}
},
watch: {
shouldResize(val, oldVal) {
setTimeout(() => {
this.chart.resize()
}, 250)
}
},
mounted() {
this.$nextTick(() => {
if (!this.chart) this.chart = echarts.init(this.$refs['techy-line-chart'])
this.chart.setOption(this.option)
})
},
beforeDestroy() {
if (this.chart) this.chart.dispose()
this.chart = null
},
methods: {}
}
</script>
<style scoped>
.techy-chart {
height: 100%;
width: 100%;
}
.techy-chart >>> div {
width: 100% !important;
height: 100% !important;
}
</style>

View File

@@ -0,0 +1,188 @@
<!--
* @Date: 2020-12-14 09:07:03
* @LastEditors: gtz
* @LastEditTime: 2022-06-14 11:12:39
* @FilePath: \mt-bus-fe\src\views\OperationalOverview\components\baseTable.vue
* @Description:
-->
<template>
<div class="visual-base-table-container">
<el-table
v-loading="isLoading"
:header-cell-style="{background:'rgba(79,114,136,0.29)',color:'#fff',height: 28 * beilv + 'px',lineHeight: 28 * beilv + 'px',padding: 0,fontSize: 12 * beilv + 'px'}"
:row-style="setRowStyle"
:data="renderData"
border
style="width: 100%; background: transparent"
>
<el-table-column v-if="page && limit && showIndex" prop="_pageIndex" :label="'tableHeader.index' | i18nFilter" :width="70 * beilv" align="center" />
<el-table-column
v-for="(item, index) in renderTableHeadList"
:key="item.prop"
:show-overflow-tooltip="showOverflow"
v-bind="item"
>
<template slot-scope="scope">
<component :is="item.subcomponent" v-if="item.subcomponent" :key="index" :inject-data="{...scope.row, ...item}" @emitData="emitData" />
<span v-else>{{ scope.row[item.prop] | commonFilter(item.filter) }}</span>
</template>
</el-table-column>
<slot name="content" />
</el-table>
</div>
</template>
<script>
import { isObject, isString } from 'lodash'
export default {
name: 'TechyTable',
filters: {
commonFilter: (source, filterType = a => a) => {
return filterType(source)
}
},
props: {
tableData: {
type: Array,
required: true,
validator: val => val.filter(item => !isObject(item)).length === 0
},
tableConfig: {
type: Array,
required: true,
validator: val => val.filter(item => !isString(item.prop) || !isString(item.label)).length === 0
},
isLoading: {
type: Boolean,
required: false
},
page: {
type: Number,
required: false,
default: 1
},
limit: {
type: Number,
required: false,
default: 5
},
beilv: {
type: Number,
default: 1
},
showOverflow: {
type: Boolean,
default: true
},
showIndex: {
type: Boolean,
default: true
}
},
data() {
return {
tableConfigBak: [],
selectedBox: new Array(100).fill(true)
}
},
computed: {
renderData() {
if (this.tableData.length && !this.tableData[0]._pageIndex) {
this.tableData.forEach((item, index) => {
item._pageIndex = (this.page - 1) * this.limit + index + 1
})
}
return this.tableData.slice((this.page - 1) * this.limit, this.page * this.limit)
},
renderTableHeadList() {
return this.tableConfig.filter((item, index) => {
return this.selectedBox[index]
})
}
},
beforeMount() {
this.selectedBox = new Array(100).fill(true)
},
methods: {
emitData(val) {
this.$emit('emitFun', val)
},
setRowStyle(v) {
if (v.rowIndex % 2 === 0) {
return {
background: 'rgba(76,97,123,0.2)',
color: 'rgba(255,255,255,0.5)',
height: 26 * this.beilv + 'px',
lineHeight: 26 * this.beilv + 'px',
padding: 0,
fontSize: 12 * this.beilv + 'px'
}
} else {
return {
background: 'rgba(79,114,136,0.29)',
color: 'rgba(255,255,255,0.5)',
height: 26 * this.beilv + 'px',
lineHeight: 26 * this.beilv + 'px',
padding: 0,
fontSize: 12 * this.beilv + 'px'
}
}
},
setCellStyle(v) {
return {
lineHeight: 23 * this.beilv + 'px'
}
}
}
}
</script>
<style lang="scss">
@import "~@/styles/index.scss";
.visual-base-table-container {
.el-table {
border: 0;
}
.el-table::before,.el-table--border::after {
background-color: transparent;
}
.el-table th,td{
border-color: #0D1728 !important;
padding: 0;
}
.el-table tr {
background: transparent;
}
.el-table__row:hover > td {
background-color: rgba(79,114,136,0.29) !important;
}
.el-table__row--striped:hover > td {
background-color: rgba(79,114,136,0.29) !important;
}
// new
.el-table {
width: 100%;
.el-table__header-wrapper table, .el-table__body-wrapper table {
width: 100% !important;
}
.el-table__body, .el-table__footer, .el-table__header {
table-layout: auto;
}
}
}
.setting {
text-align: right;
padding: 15px;
.setting-box {
width: 100px;
}
i {
color: #aaa;
@extend .pointer;
}
}
</style>

View File

@@ -0,0 +1,37 @@
<template>
<div :id="containerId">
<!-- <div id="fullscreen_button" class="fullscreen-button fullscreen-open" title="Toggle fullscreen mode" /> -->
</div>
</template>
<script>
import * as v3dAppAPI from '../v3dApp/app.js'
export default {
name: 'V3DApp',
data() {
return { containerId: v3dAppAPI.CONTAINER_ID }
},
app: null,
mounted() {
v3dAppAPI.createApp().then(app => {
this.$options.app = app
const interval = setInterval(() => {
if (app.clock.running) {
this.$emit('3d-loaded')
clearInterval(interval)
}
}, 500)
})
},
beforeUnmount() {
if (this.$options.app) {
this.$options.app.dispose()
this.$options.app = null
}
}
}
</script>
<style scoped>
@import '../v3dApp/app.css';
</style>

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 491 KiB

View File

@@ -0,0 +1,90 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="1584px" height="88px" viewBox="0 0 1584 88" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>编组 12备份 6</title>
<defs>
<linearGradient x1="98.361014%" y1="49.8170126%" x2="-6.66133815e-14%" y2="49.768946%" id="linearGradient-1">
<stop stop-color="#3797C6" stop-opacity="0.31441215" offset="0%"></stop>
<stop stop-color="#52FFF1" offset="100%"></stop>
</linearGradient>
<linearGradient x1="50%" y1="-2.22044605e-14%" x2="50%" y2="100%" id="linearGradient-2">
<stop stop-color="#081C43" stop-opacity="0" offset="0%"></stop>
<stop stop-color="#27778E" stop-opacity="0.205883769" offset="57.0640297%"></stop>
<stop stop-color="#37A5B4" stop-opacity="0.311188811" offset="100%"></stop>
</linearGradient>
<linearGradient x1="98.361014%" y1="49.7685102%" x2="-6.66133815e-14%" y2="49.707703%" id="linearGradient-3">
<stop stop-color="#3797C6" stop-opacity="0.31441215" offset="0%"></stop>
<stop stop-color="#52FFF1" offset="100%"></stop>
</linearGradient>
<linearGradient x1="103.601203%" y1="52.4858599%" x2="-6.66133815e-14%" y2="48.1699424%" id="linearGradient-4">
<stop stop-color="#3797C6" stop-opacity="0" offset="0%"></stop>
<stop stop-color="#31A6AE" offset="100%"></stop>
</linearGradient>
<linearGradient x1="103.601203%" y1="50.001227%" x2="-6.66133815e-14%" y2="49.9990967%" id="linearGradient-5">
<stop stop-color="#31A6AE" offset="0%"></stop>
<stop stop-color="#3797C6" stop-opacity="0" offset="100%"></stop>
</linearGradient>
<linearGradient x1="103.601203%" y1="50.0398645%" x2="-6.66133815e-14%" y2="49.9706523%" id="linearGradient-6">
<stop stop-color="#31A6AE" offset="0%"></stop>
<stop stop-color="#3797C6" stop-opacity="0" offset="100%"></stop>
</linearGradient>
<linearGradient x1="103.601203%" y1="52.51872%" x2="-6.66133815e-14%" y2="48.1457513%" id="linearGradient-7">
<stop stop-color="#31A6AE" stop-opacity="0" offset="0%"></stop>
<stop stop-color="#31A6AE" offset="100%"></stop>
</linearGradient>
</defs>
<g id="2MES。2-6蓝底-7、8白底" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="2-2工单管理" transform="translate(-336.000000, -120.000000)">
<g id="编组-12备份-6" transform="translate(336.000000, 120.000000)">
<g id="编组-8" transform="translate(540.000000, 23.000000)"></g>
<g id="编组-4" transform="translate(0.000000, 1.000000)">
<polyline id="路径-9" stroke="url(#linearGradient-1)" stroke-width="2" points="1584 29 1475.99948 29 1444.71615 53.8660399 1055.55466 53.8660399 1016 86 745.5 86"></polyline>
<polygon id="路径-5" fill="url(#linearGradient-2)" points="1.18181818 0 1.18181818 28 48 28 83.0413946 54 437.5 54 475.858686 85 1016.2234 86 1055.55466 52.8660399 1445 52.2038341 1477 28 1584 28 1583.66667 0"></polygon>
<polyline id="路径-9" stroke="url(#linearGradient-3)" stroke-width="2" transform="translate(372.750000, 57.500000) scale(-1, 1) translate(-372.750000, -57.500000) " points="745.5 29 696.123664 29 664.544271 53.8660399 309.570312 53.8660399 269.641314 86 -3.7840499e-13 86"></polyline>
<g id="编组-3" transform="translate(43.807292, 29.000000)">
<polyline id="路径-10" stroke="url(#linearGradient-4)" stroke-width="2" points="404.207985 57 383.692708 40 315.348958 40"></polyline>
<ellipse id="椭圆形" fill="#31A6AE" cx="311.221354" cy="40" rx="3.30208333" ry="4"></ellipse>
<ellipse id="椭圆形备份" fill="#31A6AE" cx="238.575521" cy="40" rx="3.30208333" ry="4"></ellipse>
<g id="编组-2" transform="translate(250.132812, 35.000000)" fill="#31A6AE">
<polygon id="路径-11" points="42.7984852 5.99520433e-14 39.625 0 46.6862354 10 49.53125 10"></polygon>
<polygon id="路径-11备份" opacity="0.8" points="32.8922352 5.99520433e-14 29.71875 0 36.7799854 10 39.625 10"></polygon>
<polygon id="路径-11备份-3" opacity="0.4" points="13.0797352 5.99520433e-14 9.90625 0 16.9674854 10 19.8125 10"></polygon>
<polygon id="路径-11备份-2" opacity="0.601434" points="22.9859852 5.99520433e-14 19.8125 0 26.8737354 10 29.71875 10"></polygon>
<polygon id="路径-11备份-4" opacity="0.201434" points="3.17348521 5.99520433e-14 3.85947588e-16 0 7.06123536 10 9.90625 10"></polygon>
</g>
<g id="编组-2备份" transform="translate(48.429688, 0.000000)" fill="#31A6AE">
<polygon id="路径-11" points="64.1977278 8.9928065e-14 59.4375 0 70.029353 15 74.296875 15"></polygon>
<polygon id="路径-11备份" opacity="0.8" points="49.3383528 8.9928065e-14 44.578125 0 55.169978 15 59.4375 15"></polygon>
<polygon id="路径-11备份-3" opacity="0.4" points="19.6196028 8.9928065e-14 14.859375 0 25.451228 15 29.71875 15"></polygon>
<polygon id="路径-11备份-2" opacity="0.601434" points="34.4789778 8.9928065e-14 29.71875 0 40.310603 15 44.578125 15"></polygon>
<polygon id="路径-11备份-4" opacity="0.201434" points="4.76022781 8.9928065e-14 5.78921382e-16 0 10.591853 15 14.859375 15"></polygon>
</g>
<line x1="235.273437" y1="39.5" x2="-1.04857353e-14" y2="39.5" id="路径-12" stroke="url(#linearGradient-5)" stroke-width="2"></line>
<line x1="133.458333" y1="7.5" x2="215.993" y2="8" id="路径-13" stroke="url(#linearGradient-6)" stroke-width="2"></line>
</g>
<g id="编组-3备份" transform="translate(1245.379488, 57.500000) scale(-1, 1) translate(-1245.379488, -57.500000) translate(1043.566269, 29.000000)">
<polyline id="路径-10" stroke="url(#linearGradient-7)" stroke-width="2" points="403.62644 57 383.111163 40 315.348958 40"></polyline>
<ellipse id="椭圆形" fill="#31A6AE" cx="311.221354" cy="40" rx="3.30208333" ry="4"></ellipse>
<ellipse id="椭圆形备份" fill="#31A6AE" cx="238.575521" cy="40" rx="3.30208333" ry="4"></ellipse>
<g id="编组-2" transform="translate(250.132812, 35.000000)" fill="#31A6AE">
<polygon id="路径-11" points="42.7984852 5.99520433e-14 39.625 0 46.6862354 10 49.53125 10"></polygon>
<polygon id="路径-11备份" opacity="0.8" points="32.8922352 5.99520433e-14 29.71875 0 36.7799854 10 39.625 10"></polygon>
<polygon id="路径-11备份-3" opacity="0.4" points="13.0797352 5.99520433e-14 9.90625 0 16.9674854 10 19.8125 10"></polygon>
<polygon id="路径-11备份-2" opacity="0.601434" points="22.9859852 5.99520433e-14 19.8125 0 26.8737354 10 29.71875 10"></polygon>
<polygon id="路径-11备份-4" opacity="0.201434" points="3.17348521 5.99520433e-14 3.85947588e-16 0 7.06123536 10 9.90625 10"></polygon>
</g>
<g id="编组-2备份" transform="translate(7.429688, 0.000000)" fill="#31A6AE">
<polygon id="路径-11" points="64.1977278 8.9928065e-14 59.4375 0 70.029353 15 74.296875 15"></polygon>
<polygon id="路径-11备份" opacity="0.8" points="49.3383528 8.9928065e-14 44.578125 0 55.169978 15 59.4375 15"></polygon>
<polygon id="路径-11备份-3" opacity="0.4" points="19.6196028 8.9928065e-14 14.859375 0 25.451228 15 29.71875 15"></polygon>
<polygon id="路径-11备份-2" opacity="0.601434" points="34.4789778 8.9928065e-14 29.71875 0 40.310603 15 44.578125 15"></polygon>
<polygon id="路径-11备份-4" opacity="0.201434" points="4.76022781 8.9928065e-14 5.78921382e-16 0 10.591853 15 14.859375 15"></polygon>
</g>
<line x1="235.273437" y1="39.5" x2="-1.04857353e-14" y2="39.5" id="路径-12" stroke="url(#linearGradient-5)" stroke-width="2"></line>
<line x1="92.4583333" y1="7.5" x2="174.993" y2="8" id="路径-13" stroke="url(#linearGradient-6)" stroke-width="2"></line>
</g>
</g>
<path d="M1537.5,0.5 L1537.5,87.5 L0.5,87.5 L0.5,0.5 L1537.5,0.5 Z" id="矩形" stroke="#979797" opacity="0"></path>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

View File

@@ -0,0 +1,258 @@
<template>
<div id="v3d-outter" ref="v3d-outter">
<!-- <V3DApp @3d-loaded="handle3DLoaded" /> -->
<!-- 正式内容: -->
<!-- <div v-if="showPage" id="v3d-main-content"> -->
<div v-if="true" id="v3d-main-content">
<techy-header :head-title="'合肥新能源数字工厂总览'" @toggle-full-screen="toggleFullScreen" />
<section id="techy-body-part">
<div class="upper-part">
<div class="techy-body-part__left">
<techy-container title="订单完成情况" style="flex: 0;">
<LeftContentOrder />
</techy-container>
<techy-container title="公用工程消耗" style="flex:1;">
<LeftContentPublicConsume />
</techy-container>
</div>
<div class="techy-body-part__middle">
<TechyBox>
<div class="flex">
<p>
<b>产线名称 :</b>
<span>A产线</span>
</p>
<p>
<b>设备名称 :</b>
<span>清洗机</span>
</p>
<p>
<b>累计加工数量 :</b>
<span>20</span>
</p>
<p>
<b>通信状态 :</b>
<span class="round-dot">运行中</span>
</p>
</div>
</TechyBox>
</div>
<div class="techy-body-part__right">
<techy-container title="实时产量和能耗" style="flex: 0">
<RightContentRealtimeProduction />
</techy-container>
<div class="techy-body-part__right-col-2">
<techy-container title="工序质量分析">
<RightContentQualityAnalysis />
</techy-container>
</div>
<techy-container title="产线成品率" style="flex: 0;">
<RightContentProductRate />
</techy-container>
</div>
</div>
<!-- 底部 -->
<div class="bottom-part">
<div style="width: 25%; min-width: 480px; min-height: 240px; height: 20vh;">
<techy-container title="设备巡检提示" style="flex: 0;">
<LeftContentEquipmentCheck />
</techy-container>
</div>
<div style="flex: 1;">
<techy-container title="现场实时监控">
<LeftContentMonitor />
</techy-container>
</div>
<div>
<techy-container title="缺陷分类分析">
<RightContentFaultAnalysis />
</techy-container>
</div>
<div style="width: 25%; min-width: 480px;">
<techy-container title="设备报警提示" style="flex: 0;">
<RightContentAlert />
</techy-container>
</div>
</div>
</section>
</div>
</div>
</template>
<script>
import V3DApp from './components/V3DApp.vue'
import TechyHeader from './components/TechyHeader.vue'
import TechyContainer from './components/TechyContainer.vue'
import LeftContentMonitor from './components/LeftContentMonitor.vue'
import LeftContentEquipmentCheck from './components/LeftContentEquipmentCheck.vue'
import LeftContentOrder from './components/LeftContentOrder.vue'
import LeftContentPublicConsume from './components/LeftContentPublicConsume.vue'
import RightContentAlert from './components/RightContentAlert.vue'
import RightContentRealtimeProduction from './components/RightContentRealtimeProduction.vue'
import RightContentProductRate from './components/RightContentProductRate.vue'
import RightContentQualityAnalysis from './components/RightContentQualityAnalysis.vue'
import RightContentFaultAnalysis from './components/RightContentFaultAnalysis.vue'
import TechyBox from './components/TechyBox.vue'
import screenfull from 'screenfull'
export default {
name: '',
components: {
V3DApp,
TechyHeader,
TechyContainer,
LeftContentMonitor,
LeftContentEquipmentCheck,
LeftContentOrder,
LeftContentPublicConsume,
RightContentAlert,
RightContentRealtimeProduction,
RightContentProductRate,
RightContentQualityAnalysis,
RightContentFaultAnalysis,
TechyBox
},
data() {
return {
showPage: false,
toggleResize: 'toggle-1' // <=== no need to worry this
}
},
provide() {
return { resizeStatus: () => this.toggleResize }
},
created() {},
mounted() {},
methods: {
/** 全屏切换 */
toggleFullScreen() {
if (!screenfull.enabled) {
this.$message({
message: 'you browser can not work',
type: 'warning'
})
return false
}
screenfull.toggle(this.$refs['v3d-outter'])
this.toggleResize = this.toggleResize === 'toggle-1' ? 'toggle-2' : 'toggle-1'
},
handle3DLoaded() {
this.showPage = true
}
}
}
</script>
<style>
#v3d-outter {
width: 100vw;
height: 100vh;
background-image: url('../../assets/img/cockpit/cockpit-back.png');
background-size: cover;
background-position: center;
font: 14px/1.5 tahoma, arial, 'Hiragino Sans GB', '\5b8b\4f53', sans-serif;
color: #4d4d4d;
-webkit-font-smoothing: antialiased;
font-weight: 300;
position: relative;
}
#v3d-main-content {
width: 100%;
height: 100%;
background: transparent;
z-index: 3;
display: flex;
flex-direction: column;
font: initial;
}
#techy-body-part {
flex: 1 1;
display: flex;
/* gap: 16px; */
gap: calc(100vmin / 1920 * 36);
flex-direction: column;
}
.upper-part {
flex: 1 1;
padding: calc(100vmin / 1920 * 36);
padding-bottom: 0;
display: flex;
justify-content: space-between;
}
.bottom-part {
padding: 0 calc(100vmin / 1920 * 36) calc(100vmin / 1920 * 36);
display: flex;
/* gap: 16px; */
gap: calc(100vmin / 1920 * 36);
}
.techy-body-part__left,
.techy-body-part__right {
height: 100%;
width: 25%;
min-width: 480px;
overflow: hidden;
/* background: rgba(20, 69, 100, 0.425);
backdrop-filter: blur(2px); */
display: flex;
flex-direction: column;
gap: calc(100vmin / 1920 * 36);
}
/* .techy-body-part__left {
width: 35%;
} */
.techy-body-part__right-col-2 {
flex: 1;
display: flex;
gap: calc(100vmin / 1920 * 36);
}
.techy-body-part__middle {
position: absolute;
top: 12%;
left: 36%;
height: 96px;
width: 128px;
}
.flex {
padding: 12px;
display: flex;
flex-direction: column;
}
.flex p {
margin: 0;
padding: 0;
font-size: 12px;
line-height: 1.5;
color: #fff;
}
.flex p > span {
position: relative;
padding-left: 6px;
}
.round-dot::before {
content: '';
position: absolute;
top: 5px;
left: -3px;
width: 8px;
height: 8px;
background-color: rgb(82, 231, 82);
border-radius: 4px;
}
</style>

View File

@@ -0,0 +1,34 @@
/* __V3D_TEMPLATE__ - template-based file; delete this line to prevent this file from being updated */
#v3d-container {
position: absolute;
top: 0px;
left: 0px;
width: 100%;
height: 100%;
}
.fullscreen-button {
position: absolute;
top: 5px;
right: 5px;
width: 50px;
height: 50px;
cursor: pointer;
background-size: 100% 100%;
display: none;
z-index: 1;
}
.fullscreen-open {
background-image: url('media/fullscreen_open.svg');
}
.fullscreen-close {
background-image: url('media/fullscreen_close.svg');
}
/* removes tap blinking on ios devices */
* {
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}

View File

@@ -0,0 +1,234 @@
/* __V3D_TEMPLATE__ - template-based file; delete this line to prevent this file from being updated */
/* eslint-disable */
var CONTAINER_ID = 'v3d-container';
/**
* Path to prepend to request URLs for the scene .gltf file and the visual logic
* .js file.
*/
var REL_URL_PREFIX = 'v3dApp/';
/**
* Load the visual logic .js and/or .xml file or not. The Puzzles Editor is
* currently not fully supported.
* See: https://www.soft8soft.com/docs/manual/en/programmers_guide/Integration-with-Reactjs-Vuejs.html#using_the_puzzles_editor
*/
var LOAD_LOGIC_FILES = true;
function createApp() {
var params = v3d.AppUtils.getPageParams();
var PUZZLES_DIR = '/puzzles/';
var logicURL = params.logic ? params.logic : '__LOGIC__visual_logic.js'.replace('__LOGIC__', REL_URL_PREFIX);
var sceneURL = params.load ? params.load : '__URL__app.gltf'.replace('__URL__', REL_URL_PREFIX);
if (!sceneURL) {
console.log('No scene URL specified');
return;
}
// some puzzles can benefit from cache
v3d.Cache.enabled = true;
return new Promise(function(resolve) {
if (LOAD_LOGIC_FILES) {
if (v3d.AppUtils.isXML(logicURL)) {
var logicURLJS = logicURL.match(/(.*)\.xml$/)[1] + '.js';
new v3d.PuzzlesLoader().loadEditorWithLogic(PUZZLES_DIR, logicURLJS,
function() {
var initOptions = v3d.PL ? v3d.PL.execInitPuzzles({
container: CONTAINER_ID }).initOptions
: { useFullscreen: true };
var appInstance = loadScene(sceneURL, initOptions);
v3d.PE.viewportUseAppInstance(appInstance);
resolve(appInstance);
}
);
} else if (v3d.AppUtils.isJS(logicURL)) {
new v3d.PuzzlesLoader().loadLogic(logicURL, function() {
var initOptions = v3d.PL ? v3d.PL.execInitPuzzles({
container: CONTAINER_ID }).initOptions
: { useFullscreen: true };
resolve(loadScene(sceneURL, initOptions));
});
} else {
resolve(loadScene(sceneURL, { useFullscreen: true }));
}
} else {
resolve(loadScene(sceneURL, { useFullscreen: true }));
}
}).catch(function(err) {
console.error(err);
});
}
function loadScene(sceneURL, initOptions) {
initOptions = initOptions || {};
var ctxSettings = {};
if (initOptions.useBkgTransp) ctxSettings.alpha = true;
if (initOptions.preserveDrawBuf) ctxSettings.preserveDrawingBuffer = true;
var preloader = initOptions.useCustomPreloader
? createCustomPreloader(initOptions.preloaderProgressCb,
initOptions.preloaderEndCb)
: new v3d.SimplePreloader({ container: CONTAINER_ID });
if (v3d.PE) {
puzzlesEditorPreparePreloader(preloader);
}
var app = new v3d.App(CONTAINER_ID, ctxSettings, preloader);
if (initOptions.useBkgTransp) {
app.clearBkgOnLoad = true;
app.renderer.setClearColor(0x000000, 0);
}
// namespace for communicating with code generated by Puzzles
app.ExternalInterface = {};
prepareExternalInterface(app);
if (initOptions.preloaderStartCb) initOptions.preloaderStartCb();
if (initOptions.useFullscreen) {
initFullScreen();
} else {
var fsButton = document.getElementById('fullscreen_button');
if (fsButton) fsButton.style.display = 'none';
}
sceneURL = initOptions.useCompAssets ? sceneURL + '.xz' : sceneURL;
app.loadScene(sceneURL, function() {
app.enableControls();
app.run();
if (v3d.PE) v3d.PE.updateAppInstance(app);
if (v3d.PL) v3d.PL.init(app, initOptions);
runCode(app);
}, null, function() {
console.log('Can\'t load the scene ' + sceneURL);
});
return app;
}
function createCustomPreloader(updateCb, finishCb) {
function CustomPreloader() {
v3d.Preloader.call(this);
}
CustomPreloader.prototype = Object.assign(Object.create(v3d.Preloader.prototype), {
onUpdate: function(percentage) {
v3d.Preloader.prototype.onUpdate.call(this, percentage);
if (updateCb) updateCb(percentage);
},
onFinish: function() {
v3d.Preloader.prototype.onFinish.call(this);
if (finishCb) finishCb();
}
});
return new CustomPreloader();
}
/**
* Modify the app's preloader to track the loading process in the Puzzles Editor.
*/
function puzzlesEditorPreparePreloader(preloader) {
var _onUpdate = preloader.onUpdate.bind(preloader);
preloader.onUpdate = function(percentage) {
_onUpdate(percentage);
v3d.PE.loadingUpdateCb(percentage);
}
var _onFinish = preloader.onFinish.bind(preloader);
preloader.onFinish = function() {
_onFinish();
v3d.PE.loadingFinishCb();
}
}
function initFullScreen() {
var fsButton = document.getElementById('fullscreen_button');
if (!fsButton) return;
var container = document.getElementById(CONTAINER_ID);
if (document.fullscreenEnabled ||
document.webkitFullscreenEnabled ||
document.mozFullScreenEnabled ||
document.msFullscreenEnabled)
fsButton.style.display = 'inline';
fsButton.addEventListener('click', function(event) {
event.stopPropagation();
if (document.fullscreenElement ||
document.webkitFullscreenElement ||
document.mozFullScreenElement ||
document.msFullscreenElement) {
exitFullscreen();
} else
requestFullscreen(container);
});
function changeFullscreen() {
if (document.fullscreenElement ||
document.webkitFullscreenElement ||
document.mozFullScreenElement ||
document.msFullscreenElement) {
fsButton.classList.remove('fullscreen-open');
fsButton.classList.add('fullscreen-close');
} else {
fsButton.classList.remove('fullscreen-close');
fsButton.classList.add('fullscreen-open');
}
}
document.addEventListener('webkitfullscreenchange', changeFullscreen);
document.addEventListener('mozfullscreenchange', changeFullscreen);
document.addEventListener('msfullscreenchange', changeFullscreen);
document.addEventListener('fullscreenchange', changeFullscreen);
function requestFullscreen(elem) {
if (elem.requestFullscreen)
elem.requestFullscreen();
else if (elem.mozRequestFullScreen)
elem.mozRequestFullScreen();
else if (elem.webkitRequestFullscreen)
elem.webkitRequestFullscreen();
else if (elem.msRequestFullscreen)
elem.msRequestFullscreen();
}
function exitFullscreen() {
if (document.exitFullscreen)
document.exitFullscreen();
else if (document.mozCancelFullScreen)
document.mozCancelFullScreen();
else if (document.webkitExitFullscreen)
document.webkitExitFullscreen();
else if (document.msExitFullscreen)
document.msExitFullscreen();
}
}
function prepareExternalInterface(app) {
// register functions in the app.ExternalInterface to call them from Puzzles, e.g:
// app.ExternalInterface.myJSFunction = function() {
// console.log('Hello, World!');
// }
}
function runCode(app) {
// add your code here, e.g. console.log('Hello, World!');
}
export { createApp, CONTAINER_ID };

View File

@@ -0,0 +1,105 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="62"
height="62"
viewBox="0 0 16.404167 16.404167"
version="1.1"
id="svg2719">
<defs
id="defs2713">
<linearGradient
gradientTransform="rotate(-180,255.67833,614.731)"
xlink:href="#linearGradient2768"
id="linearGradient2673"
x1="501.88306"
y1="942.95502"
x2="508.08038"
y2="935.61182"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient2768">
<stop
style="stop-color:#414141;stop-opacity:1"
offset="0"
id="stop2764" />
<stop
style="stop-color:#767676;stop-opacity:1"
offset="1"
id="stop2766" />
</linearGradient>
<linearGradient
gradientTransform="translate(-493.24109,-653.06985)"
xlink:href="#linearGradient2648"
id="linearGradient2665"
x1="495.62714"
y1="948.00964"
x2="508.85629"
y2="934.78046"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient2648">
<stop
style="stop-color:#ebebeb;stop-opacity:1"
offset="0"
id="stop2644" />
<stop
style="stop-color:#ffffff;stop-opacity:1"
offset="1"
id="stop2646" />
</linearGradient>
<filter
style="color-interpolation-filters:sRGB"
id="filter2688"
x="-0.12"
width="1.24"
y="-0.12"
height="1.24">
<feGaussianBlur
stdDeviation="0.66145835"
id="feGaussianBlur2690" />
</filter>
</defs>
<metadata
id="metadata2716">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="layer1"
transform="translate(0,-280.59582)">
<g
id="g2754"
transform="translate(-0.79853618,0.47271794)">
<rect
rx="0"
ry="1.376092"
y="281.7106"
x="2.3860359"
height="13.229167"
width="13.229167"
id="rect2614"
style="display:inline;opacity:1;fill:#000000;fill-opacity:0.53005461;fill-rule:nonzero;stroke:none;stroke-width:0.71784258;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers stroke fill;filter:url(#filter2688)" />
<path
id="rect2603"
d="M 3.7621171,281.7106 H 14.2391 c 0.762355,0 1.376092,0.61374 1.376092,1.37609 v 10.47699 c 0,0.76235 -0.613737,1.37609 -1.376092,1.37609 H 3.7621171 c -0.7623549,0 -1.3760919,-0.61374 -1.3760919,-1.37609 v -10.47699 c 0,-0.76235 0.613737,-1.37609 1.3760919,-1.37609 z"
style="display:inline;opacity:1;fill:url(#linearGradient2665);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.71784258;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers stroke fill" />
<path
id="rect2605"
d="M 9.0089403,293.54618 H 4.4659401 c -0.39995,0 -0.72192,-0.32198 -0.72192,-0.72192 v -4.49623 c 0,-0.39994 0.50644,-0.7845 0.9865,-0.32421 0.48006,0.46029 4.2498102,4.07528 4.7127902,4.53146 0.46297,0.45619 0.15571,1.0109 -0.43437,1.0109 z"
style="display:inline;opacity:1;fill:url(#linearGradient2673);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers stroke fill" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

@@ -0,0 +1,105 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="62"
height="62"
viewBox="0 0 16.404167 16.404167"
version="1.1"
id="svg2719">
<defs
id="defs2713">
<linearGradient
gradientTransform="translate(-493.24109,-653.06985)"
xlink:href="#linearGradient2768"
id="linearGradient2673"
x1="501.88306"
y1="942.95502"
x2="508.08038"
y2="935.61182"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient2768">
<stop
style="stop-color:#414141;stop-opacity:1"
offset="0"
id="stop2764" />
<stop
style="stop-color:#767676;stop-opacity:1"
offset="1"
id="stop2766" />
</linearGradient>
<linearGradient
gradientTransform="translate(-493.24109,-653.06985)"
xlink:href="#linearGradient2648"
id="linearGradient2665"
x1="495.62714"
y1="948.00964"
x2="508.85629"
y2="934.78046"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient2648">
<stop
style="stop-color:#ebebeb;stop-opacity:1"
offset="0"
id="stop2644" />
<stop
style="stop-color:#ffffff;stop-opacity:1"
offset="1"
id="stop2646" />
</linearGradient>
<filter
style="color-interpolation-filters:sRGB"
id="filter2688"
x="-0.12"
width="1.24"
y="-0.12"
height="1.24">
<feGaussianBlur
stdDeviation="0.66145835"
id="feGaussianBlur2690" />
</filter>
</defs>
<metadata
id="metadata2716">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="layer1"
transform="translate(0,-280.59582)">
<g
id="g2754"
transform="translate(-0.79853618,0.47271794)">
<rect
rx="0"
ry="1.376092"
y="281.7106"
x="2.3860359"
height="13.229167"
width="13.229167"
id="rect2614"
style="display:inline;opacity:1;fill:#000000;fill-opacity:0.53005461;fill-rule:nonzero;stroke:none;stroke-width:0.71784258;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers stroke fill;filter:url(#filter2688)" />
<path
id="rect2603"
d="M 3.7621171,281.7106 H 14.2391 c 0.762355,0 1.376092,0.61374 1.376092,1.37609 v 10.47699 c 0,0.76235 -0.613737,1.37609 -1.376092,1.37609 H 3.7621171 c -0.7623549,0 -1.3760919,-0.61374 -1.3760919,-1.37609 v -10.47699 c 0,-0.76235 0.613737,-1.37609 1.3760919,-1.37609 z"
style="display:inline;opacity:1;fill:url(#linearGradient2665);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.71784258;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers stroke fill" />
<path
id="rect2605"
d="m 9.1066291,282.84597 h 4.5429999 c 0.39995,0 0.72192,0.32198 0.72192,0.72192 v 4.49623 c 0,0.39994 -0.50644,0.7845 -0.9865,0.32421 -0.48006,-0.46029 -4.24981,-4.07528 -4.7127901,-4.53146 -0.46297,-0.45619 -0.1557099,-1.0109 0.4343702,-1.0109 z"
style="display:inline;opacity:1;fill:url(#linearGradient2673);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers stroke fill" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

@@ -0,0 +1,235 @@
<template>
<div class="choicepart-container">
<div class="choicepat-navbar">
<navbar :showhome="false" :show-title="true" />
</div>
<div class="choicepart-box">
<div
v-for="(item, index) in routeList"
:key="item.path"
class="choicepart-item"
@click="handelClick(item, index)"
>
<!-- :style="{ background: colorArr.colorList[index % 9] }" -->
<div class="choicepart-item-border">
<img :src="require(`../../assets/img/choicepart/${item.name}.png`)" alt="">
</div>
<div class="choicepart-item-title" :title="item.meta.title">{{ item.meta.title }}</div>
</div>
</div>
</div>
</template>
<script>
// import db from '@/utils/indexDB'
import { mapGetters } from 'vuex'
// import { constantRoutes } from '@/router'
import { Navbar } from '@/layout/components'
import { downLoadBGP } from '@/api/user'
import store from '@/store'
import { blobToBase64 } from '@/utils/blobToBase64'
const colorList = ['#8080ff', '#ff8080', '#b004fb', '#ff409f', '#00caca', '#8080c0', '#cccc00', '#ff8040', '#0c4d9e']
const colorList1 = ['#b4b4ff', '#ffb4b4', '#c648fb', '#ff86c2', '#66f6f6', '#a2a2f3', '#ffff9a', '#ffc3a5', '#367cd4']
export default {
name: 'ChoicePart',
components: { Navbar },
data() {
return {
baseImg: require('../../assets/img/login-back.jpg'),
coverImgUrl: localStorage.getItem('backImg') || '',
rowNum: 1,
colorArr: {
colorList,
colorList1
},
windowWidth: 0,
dbConnect: null
}
},
computed: {
routeList() {
const cangoList = []
const permission_routes = store.getters.permission_routes
permission_routes.map(item => {
if (!item.hidden && item.meta) {
cangoList.push(item)
}
})
const formatList = cangoList.map((item, index) => {
return this.setIndex(item, index)
})
return formatList
},
...mapGetters(['language', 'dictList', 'dictObj'])
},
created() {
this.windowWidth = window.innerWidth
// this.dbConnect = db({
// DBName: 'back_img',
// version: '1.0',
// params: [
// { name: 'id', unique: true },
// { name: 'imgUrl', unique: true }
// ]
// })
// const request = this.dbConnect.openDB()
// request.onsuccess = () => {
// // const result = this.dbConnect.search('back_img', 'id', 1)
// }
},
mounted() {
console.log(this.dictList, this.dictObj)
this.getPic()
},
methods: {
getPic() {
// edit here
downLoadBGP().then(response => {
if (response.data.size) {
blobToBase64(response.data).then(res => {
this.coverImgUrl = res
localStorage.setItem('backImg', res)
// const result = this.dbConnect.search('back_img', 'id', 1)
// if (result.result) {
// this.dbConnect.update({
// id: 1,
// imgUrl: res
// })
// } else {
// this.dbConnect.add({
// id: 1,
// imgUrl: res
// })
// }
})
// this.coverImgUrl = response.data
// const temp = response.data.split('/')
// temp.splice(0, 2)
// this.coverImgUrl = 'http://zzdhg.mes.picaiba.com/' + temp.join('/')
}
})
},
resize() {},
handelClick(item, index) {
this.$store.dispatch('app/setChoicepart', index)
if (item.meta.unuse) {
this.$message.warning(this.$t('choisePart.module'))
} else {
this.toRouter(item)
}
},
toRouter(item) {
if (item.children) {
this.toRouter(item.children[0])
} else {
this.$router.push({ name: item.name })
}
},
setIndex(list, index) {
list.meta.routeIndex = index
if (list.children) {
list.children.map(item => {
this.setIndex(item, index)
})
}
return list
}
}
}
</script>
<style lang="scss" scoped>
.choicepart-container {
min-width: 100%;
min-height: 100vh;
// background: linear-gradient(-45deg, rgb(25, 25, 200), rgb(0, 100, 200));
background: url('../../assets/img/choicepart/choicepart-back.jpg') repeat;
background-size: 100% 100%;
overflow-x: scroll;
.choicepart-box {
width: 1440px;
margin: 0 auto;
margin: 0 auto;
padding-top: 16vh;
min-height: 100vh;
.choicepart-item {
display: inline-block;
width: 208px;
height: 258px;
margin: 40px;
background: url('../../assets/img/choicepart/choice-item-back.png') no-repeat;
background-size: 100% 100%;
// border: 1px dashed #fff;
// box-shadow: 0 2px 10px rgba(0, 0, 0, 0.5);
top: 0;
border-radius: 5px;
overflow: hidden;
cursor: pointer;
position: relative;
img {
width: 208px;
height: 258px;
}
.choicepart-item-border {
height: 100%;
border-radius: 5px;
// padding: 0 5px;
line-height: 32px;
font-size: 28px;
font-weight: lighter;
color: #2c6bd8;
overflow: hidden;
}
.choicepart-item-title {
overflow: hidden;
padding: 0 10px;
text-overflow: ellipsis;
white-space: nowrap;
position: absolute;
bottom: 0;
left: 2px;
right: 2px;
text-align: center;
color: #fff;
font-size: 16px;
line-height: 48px;
height: 48px;
letter-spacing: 2px;
background-color: rgba($color: #0b58ff, $alpha: 0.45);
}
}
.choicepart-item:hover {
.choicepart-item-title {
background-color: rgba($color: #0b58ff, $alpha: 1);
}
}
}
.choicepat-navbar {
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 10;
}
}
::-webkit-scrollbar-track-piece {
//滚动条凹槽的颜色,还可以设置边框属性
background: rgba(255, 255, 255, 0.1);
}
::-webkit-scrollbar {
//滚动条的宽度
width: 9px;
height: 9px;
}
::-webkit-scrollbar-thumb {
//滚动条的设置
background-color: #dddddd;
background-clip: padding-box;
min-height: 28px;
border-radius: 9px;
}
::-webkit-scrollbar-thumb:hover {
background-color: #bbb;
}
</style>

View File

@@ -0,0 +1,358 @@
<template>
<div style="height: calc(100vh - 30px - 97px); padding: 10px 16px;">
<div class="grid">
<!-- 效率 -->
<div class="outter-wrapper efficiency" @click="handleClick('efficiency')">
<div class="inner-content">
<div class="inner-content__head">
<div>
<span class="icon">
<svg
width="24px"
height="24px"
viewBox="0 0 24 24"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
>
<title>效率</title>
<defs>
<linearGradient id="linearGradient-1" x1="50%" y1="0%" x2="50%" y2="100%">
<stop stop-color="#76E1FF" offset="0%" />
<stop stop-color="#1FACFD" offset="100%" />
</linearGradient>
</defs>
<g id="2MES。2-6蓝底-7、8白底" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="2-8数据分析" transform="translate(-460.000000, -277.000000)" fill-rule="nonzero">
<g id="编组-9" transform="translate(460.000000, 276.000000)">
<g id="生产和加工情况" transform="translate(0.000000, 1.000000)">
<rect id="矩形" fill="#000000" opacity="0" x="0" y="0" width="24" height="24" />
<path
id="形状"
d="M8.14453125,15.590625 C8.14453125,14.5851563 8.34140625,13.6101563 8.73046875,12.6914063 C9.10546875,11.803125 9.6421875,11.0085938 10.3265625,10.3242188 C11.0109375,9.63984375 11.8054687,9.103125 12.69375,8.728125 C13.6125,8.3390625 14.5875,8.1421875 15.5929688,8.1421875 C16.5984375,8.1421875 17.5734375,8.3390625 18.4921875,8.728125 C18.7757813,8.84765625 19.0476562,8.98359375 19.3125,9.1359375 L19.3125,2.9484375 C19.3125,2.62734375 19.0523437,2.3671875 18.73125,2.3671875 L13.1625,2.3671875 C13.1742187,2.42109375 13.1789063,2.475 13.1789063,2.53125 L13.1789063,5.653125 C13.1789063,6.103125 12.8132813,6.46875 12.3632813,6.46875 L9.3140625,6.46875 C8.8640625,6.46875 8.4984375,6.103125 8.4984375,5.653125 L8.4984375,2.53359375 C8.4984375,2.47734375 8.503125,2.4234375 8.51484375,2.36953125 L2.94609375,2.36953125 C2.625,2.36953125 2.36484375,2.6296875 2.36484375,2.95078125 L2.36484375,18.8085938 C2.36484375,19.1296875 2.625,19.3898438 2.94609375,19.3898438 L9.18515625,19.3898438 C9.0140625,19.1015625 8.86171875,18.8015625 8.73046875,18.4921875 C8.34140625,17.5710938 8.14453125,16.5960938 8.14453125,15.590625 Z M15.5929687,9.5484375 C12.2554687,9.5484375 9.55078125,12.253125 9.55078125,15.590625 C9.55078125,18.928125 12.2554687,21.6328125 15.5929687,21.6328125 C18.9304687,21.6328125 21.6351562,18.928125 21.6351562,15.590625 C21.6351562,12.253125 18.9304687,9.5484375 15.5929687,9.5484375 Z M18.2226562,16.425 C17.5429687,17.1046875 16.5609375,17.3015625 15.7078125,17.015625 L14.1023438,18.6210938 C13.678125,19.0453125 12.9867187,19.0453125 12.5625,18.6210938 C12.1382813,18.196875 12.1382813,17.5054688 12.5625,17.08125 L14.1679688,15.4757813 C13.8820312,14.6226563 14.0765625,13.640625 14.7585937,12.9609375 C15.4921875,12.2273438 16.5726562,12.05625 17.4679687,12.4453125 L15.8953125,14.0179688 L16.1507812,15.0234375 L17.165625,15.2882813 L18.7382812,13.715625 C19.1273437,14.6132812 18.9539062,15.69375 18.2226562,16.425 L18.2226562,16.425 Z M13.0640625,17.6296875 C13.0640625,17.8046918 13.1574262,17.9664025 13.3089844,18.0539047 C13.4605426,18.1414068 13.6472699,18.1414068 13.7988281,18.0539047 C13.9503863,17.9664025 14.04375,17.8046918 14.04375,17.6296875 C14.04375,17.4546832 13.9503863,17.2929725 13.7988281,17.2054703 C13.6472699,17.1179682 13.4605426,17.1179682 13.3089844,17.2054703 C13.1574262,17.2929725 13.0640625,17.4546832 13.0640625,17.6296875 Z"
fill="url(#linearGradient-1)"
/>
</g>
</g>
</g>
</g>
</svg>
</span>
<span class="letter-space-2">效率</span>
</div>
<h1>Efficiency</h1>
</div>
<ul class="inner-content__features">
<li>
<span class="dot" />
<span>设备效率汇总分析</span>
</li>
<li>
<span class="dot" />
<span>订单加工效率分析</span>
</li>
<li>
<span class="dot" />
<span>订单/产能分析</span>
</li>
</ul>
</div>
</div>
<!-- 设备异常 -->
<div class="outter-wrapper exception" @click="handleClick('exception')">
<div class="inner-content">
<div class="inner-content__head">
<div>
<span class="icon">
<svg
width="24px"
height="24px"
viewBox="0 0 24 24"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
>
<title>设备异常</title>
<defs>
<linearGradient id="linearGradient-2" x1="50%" y1="0%" x2="50%" y2="100%">
<stop stop-color="#FFBEBE" offset="0%" />
<stop stop-color="#FF4545" offset="100%" />
</linearGradient>
</defs>
<g id="2MES。2-6蓝底-7、8白底" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="2-8数据分析" transform="translate(-1236.000000, -277.000000)" fill-rule="nonzero">
<g id="编组-19" transform="translate(1236.000036, 276.000000)">
<g id="异常" transform="translate(0.000000, 1.000142)">
<rect
id="矩形"
fill="#000000"
opacity="0"
x="0"
y="0"
width="23.9998583"
height="23.9998583"
/>
<path
id="形状"
d="M11.9999201,1.99997632 C10.0657204,1.98903257 8.20490927,2.739826 6.8199711,4.09008421 C5.4676747,5.42710649 4.70462356,7.2483539 4.7000035,9.15001444 L4.7000035,18.9098966 L19.2198373,18.9098966 L19.2198373,9.14999491 C19.2181621,7.24575011 18.4505466,5.42222692 17.0898502,4.09006468 C15.7289706,2.75887754 13.9035726,2.00936373 11.9999006,1.99997632 L11.9999201,1.99997632 Z M11.3999238,16.5699304 L11.1899251,11.8399591 L7.6099663,11.8399591 L12.3098792,5.91005364 L12.7098768,9.73001092 L16.1098561,9.85001019 L11.359885,16.5699304 L11.3999238,16.5699304 Z M1.99999348,20.9098649 C1.99737133,20.6190554 2.11102797,20.3392384 2.31572705,20.1326576 C2.52042613,19.9260769 2.79919147,19.8098716 3.09001328,19.8098716 L20.909827,19.8098716 C21.1981147,19.8134614 21.4739139,19.9280863 21.6798223,20.1298892 C21.8822311,20.3394413 21.9967278,20.618537 21.9998009,20.9098649 C21.9998009,21.511844 21.5118061,21.9998583 20.909827,21.9998583 L3.09001328,21.9998583 C2.48803418,21.9998583 1.99999348,21.511844 1.99999348,20.9098649 L1.99999348,20.9098649 Z"
fill="url(#linearGradient-2)"
/>
</g>
</g>
</g>
</g>
</svg>
</span>
<span class="letter-space-2">设备异常</span>
</div>
<h1>Unit Exception</h1>
</div>
<ul class="inner-content__features">
<li>
<span class="dot" />
<span>设备异常分析</span>
</li>
</ul>
</div>
</div>
<!-- 质量异常 -->
<div class="outter-wrapper quality" @click="handleClick('quality')">
<div class="inner-content">
<div class="inner-content__head">
<div>
<span class="icon">
<svg
width="24px"
height="24px"
viewBox="0 0 24 24"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
>
<title>质量异常</title>
<defs>
<linearGradient id="linearGradient-3" x1="50%" y1="-35.9917859%" x2="50%" y2="100%">
<stop stop-color="#F933FE" offset="0%" />
<stop stop-color="#735EEE" offset="100%" />
</linearGradient>
</defs>
<g id="2MES。2-6蓝底-7、8白底" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="2-8数据分析" transform="translate(-460.000000, -741.000000)" fill-rule="nonzero">
<g id="编组-18" transform="translate(460.000000, 740.000000)">
<g id="出库on" transform="translate(0.000000, 1.000000)">
<rect id="矩形" fill="#000000" opacity="0" x="0" y="0" width="24" height="24" />
<path
id="形状结合"
d="M18.3505903,6.65853839 L18.3505903,20.5806612 C18.3505903,20.7702295 18.1969321,20.9238877 18.0073638,20.9238877 L3.41933878,20.9238877 C3.22977052,20.9238877 3.07611233,20.7702295 3.07611233,20.5806612 L3.07611233,6.65853839 L18.3505903,6.65853839 Z M20.9238877,3.07611233 L20.9238877,20.9151997 L19.7907041,20.9151997 L19.7907041,3.07611233 L20.9238877,3.07611233 Z M11.2356824,8.75416325 L6.53576955,14.6840687 L10.1157283,14.6840687 L10.3231123,19.3601123 L15.0356594,12.6941198 L11.63568,12.5741205 L11.2356824,8.75416325 Z M16.3135198,3.08480025 C16.4315455,3.08480025 16.5412922,3.14544223 16.6041039,3.24536587 L18.1023088,5.62885904 L3.32441522,5.62885904 L4.82259866,3.24536587 C4.88541044,3.14544223 4.9951571,3.08480025 5.11318276,3.08480025 L16.3135198,3.08480025 Z"
fill="url(#linearGradient-3)"
/>
</g>
</g>
</g>
</g>
</svg>
</span>
<span class="letter-space-2">质量异常</span>
</div>
<h1>Abnormal Quality</h1>
</div>
<ul class="inner-content__features">
<li>
<span class="dot" />
<span>设备效率汇总分析</span>
</li>
<li>
<span class="dot" />
<span>订单加工效率分析</span>
</li>
<li>
<span class="dot" />
<span>订单/产能分析</span>
</li>
</ul>
</div>
</div>
<!-- 自定义 -->
<div class="outter-wrapper customize" @click="handleClick('customize')">
<div class="inner-content">
<div class="inner-content__head">
<div>
<span class="icon">
<svg
width="24px"
height="24px"
viewBox="0 0 24 24"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
>
<title>编组 15</title>
<defs>
<linearGradient id="linearGradient-4" x1="50%" y1="0.100295608%" x2="50%" y2="100%">
<stop stop-color="#FFD730" offset="0%" />
<stop stop-color="#FF9D4F" offset="100%" />
</linearGradient>
</defs>
<g id="2MES。2-6蓝底-7、8白底" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="2-8数据分析" transform="translate(-1231.000000, -747.000000)" fill-rule="nonzero">
<g id="编组-8" transform="translate(1231.000000, 746.000000)">
<g id="编组-15" transform="translate(0.000000, 1.000000)">
<g id="追加" fill="#000000" opacity="0">
<rect id="矩形" x="0" y="0" width="24" height="24" />
</g>
<path
id="形状结合"
d="M16.4322694,5.34917373 C17.6095644,5.34917373 18.5728058,6.31241512 18.5728058,7.48971015 L18.5728058,7.48971015 L18.5728058,20.3329286 C18.5728058,21.5102237 17.6095644,22.4734651 16.4322694,22.4734651 L16.4322694,22.4734651 L3.58905088,22.4734651 C2.41175585,22.4734651 1.44851447,21.5102237 1.44851447,20.3329286 L1.44851447,20.3329286 L1.44851447,7.48971015 C1.44851447,6.31241512 2.41175585,5.34917373 3.58905088,5.34917373 L3.58905088,5.34917373 Z M10.0106601,9.63024656 C9.47552602,9.63024656 8.94039192,10.1653807 8.94039192,10.7005148 L8.94039192,12.8410512 L6.7998555,12.8410512 C6.2647214,12.8410512 5.7295873,13.3761853 5.7295873,13.9113194 C5.7295873,14.4464535 6.2647214,14.9815876 6.7998555,14.9815876 L8.94039192,14.9815876 L8.94039192,17.122124 C8.94039192,17.6572581 9.47552602,18.1923922 10.0106601,18.1923922 C10.5457942,18.1923922 11.0809283,17.6572581 11.0809283,17.122124 L11.0809283,14.9815876 L13.2214648,14.9815876 C13.7565989,14.9815876 14.291733,14.4464535 14.291733,13.9113194 C14.291733,13.3761853 13.7565989,12.8410512 13.2214648,12.8410512 L11.0809283,12.8410512 L11.0809283,10.7005148 C11.0809283,10.1653807 10.5457942,9.63024656 10.0106601,9.63024656 Z M20.4109491,1 C21.5882441,1 22.5514855,1.96324139 22.5514855,3.14053642 L22.5514855,15.9837549 C22.5514855,17.1610499 21.5882441,18.1242913 20.4109491,18.1242913 L19.7890134,18.1242913 L19.7890134,5.93020465 C19.7890134,4.82563515 18.8935829,3.93020465 17.7890134,3.93020465 L5.42719421,3.93020465 L5.42719421,3.14053642 C5.42719421,1.96324139 6.3904356,1 7.56773062,1 L20.4109491,1 Z"
fill="url(#linearGradient-4)"
/>
</g>
</g>
</g>
</g>
</svg>
</span>
<span class="letter-space-2">自定义</span>
</div>
<h1>Customize</h1>
</div>
</div>
</div>
<!-- done grid -->
</div>
</div>
</template>
<script>
export default {
name: 'DataAnalysisHome',
data() {
return {}
},
methods: {
handleClick(entry) {
switch (entry) {
case 'efficiency':
this.$router.push({ name: 'EquipmentEfficiency' })
break
case 'exception':
this.$router.push({ name: 'EquipmentException' })
break
case 'quality':
// this.$router.push({ name: 'ProductQuality' })
this.$router.push({ name: 'EquipmentStatus' }) // 设备状态时序图 是目前开放的路由
break
case 'customize':
break
}
}
}
}
</script>
<style scoped>
.grid {
height: 100%;
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr;
gap: 16px;
}
.grid > div {
border-radius: 16px;
background-repeat: no-repeat;
background-size: auto 102%;
background-position: right;
cursor: pointer;
transition: all 0.3s cubic-bezier(0.23, 1, 0.32, 1);
}
.grid > div:hover {
transform: scale(1.0125);
box-shadow: 0 0 6px 1px rgba(0, 0, 0, 0.1);
}
.efficiency {
background: url(./svgs/b1.svg), white;
}
.exception {
background: url(./svgs/b2.svg), white;
}
.quality {
background: url(./svgs/b3.svg), white;
}
.customize {
background: url(./svgs/b4.svg), white;
}
.outter-wrapper {
display: flex;
justify-content: flex-start;
align-items: center;
}
.inner-content {
color: #161616;
transform: translateX(100px);
}
.inner-content__head > div {
/* height: 24px; */
display: flex;
align-items: center;
font-size: 18px;
line-height: 25px;
letter-spacing: 6px;
}
.icon {
margin-right: 14px;
}
.inner-content__head > h1 {
font-size: 30px;
line-height: 42px;
font-weight: 400;
margin: 6px 0;
}
ul.inner-content__features {
margin: 24px 0 0;
padding: 0;
list-style: none;
}
.dot {
display: inline-block;
width: 6px;
height: 6px;
border-radius: 1px;
margin-right: 8px;
background-color: #0b58ff;
}
.dot + span {
letter-spacing: 2px;
font-size: 18px;
line-height: 25px;
color: rgba(22, 22, 22, 0.7);
}
ul.inner-content__features > li {
display: flex;
align-items: center;
}
ul.inner-content__features > li:not(:last-child) {
margin-bottom: 8px;
}
</style>

View File

@@ -0,0 +1,55 @@
<!--
* @Author: gtz
* @Date: 2022-06-06 15:34:34
* @LastEditors: gtz
* @LastEditTime: 2022-06-09 17:46:08
* @Description: file content
* @FilePath: \mt-bus-fe\src\views\DataAnalysis\components\ExceptionEqBtn.vue
-->
<template>
<span>
<el-button ref="hoverButton" class="hover-button" type="text" size="small" @mouseenter.native="enterButton" @mouseleave.native="leaveButton">
{{ injectData.equipmentName }}
<hover-box ref="hoverBox" :inject-data="injectData" :button-width="buttonWidth" />
</el-button>
</span>
</template>
<script>
import Vue from 'vue'
import hoverBox from './hoverBox'
export default {
components: { hoverBox },
props: {
injectData: {
type: Object,
default: () => ({})
}
},
data() {
return {
buttonWidth: 0
}
},
created() {
Vue.set(this.injectData, 'title', this.$t('module.dataAnalysis.equipmentException.eqTitle'))
},
mounted() {
this.buttonWidth = this.$refs.hoverButton.$el.offsetWidth
},
methods: {
enterButton() {
this.$refs.hoverBox.init()
},
leaveButton() {
this.$refs.hoverBox.remove()
}
}
}
</script>
<style lang="scss" scoped>
.hover-button {
position: relative;
}
</style>

View File

@@ -0,0 +1,219 @@
<template>
<div :id="id" :class="className" :style="{height:height,width:width}" />
</template>
<script>
import echarts from 'echarts'
import resize from './mixins/resize'
const colorList = ['#FFB61F', '#283D68', '#5AD8A6', '#E97466']
const shadowList = ['rgba(255, 179, 24, 0.5)', 'rgba(53, 66, 93, 0.5)', 'rgba(90, 216, 166, 0.6)', 'rgba(233, 116, 102, 0.5)']
export default {
mixins: [resize],
props: {
className: {
type: String,
default: 'chart'
},
id: {
type: String,
default: 'chart'
},
width: {
type: String,
default: '200px'
},
height: {
type: String,
default: '200px'
},
chartData: {
type: Object,
default: () => {}
}
},
data() {
return {
chart: null
}
},
watch: {
chartData: {
handler: function(val) {
this.initChart()
}
// deep: true
}
},
mounted() {
this.initChart()
},
beforeDestroy() {
if (!this.chart) {
return
}
this.chart.dispose()
this.chart = null
},
methods: {
initChart() {
this.chart = echarts.init(document.getElementById(this.id))
this.chart.setOption({
// backgroundColor: '#394056',
tooltip: {
trigger: 'axis',
padding: 0,
backgroundColor: 'transparent',
renderMode: 'html',
textStyle: {
color: 'rgba(0, 0, 0, 0.85)',
fontSize: 12,
lineHeight: 14
},
formatter: function(param) {
var text = ''
const paramItem = param.map(item => {
return `<div style="display: flex; min-width: 150px">
<span>
<span style="display: inline-block; width: 4px; height: 4px; border-radius: 4px; background-color: ${item.color}; position: relative; top: -3px"></span>
<span>${item.seriesName}</span>
</span>
<span style="flex: 1;text-align: right">${item.value}</span>
</div>`
})
text = `<div class="line-tooltip">
<p style="margin: 0">${param[0].name}</p>
${paramItem.join('')}
</div>`
return text
}
},
color: colorList,
legend: {
top: 0,
data: ['设备CT', '设备TT', '产线CT', '产线TT'],
right: '4%',
textStyle: {
fontSize: 12,
color: '#8C8C8C'
}
},
grid: {
top: 50,
left: '2%',
right: '2%',
bottom: '2%',
containLabel: true
},
xAxis: [{
type: 'category',
boundaryGap: false,
axisLine: {
lineStyle: {
color: '#57617B'
}
},
data: this.chartData.timeArr
}],
yAxis: [{
type: 'value',
name: '',
axisTick: {
show: false
},
axisLine: {
lineStyle: {
color: '#57617B'
}
},
axisLabel: {
margin: 10,
textStyle: {
fontSize: 14
}
},
splitLine: {
lineStyle: {
color: 'rgba(0, 0, 0, .15)'
}
}
}],
series: [{
name: '设备CT',
type: 'line',
symbol: 'circle',
symbolSize: 5,
showSymbol: false,
lineStyle: {
normal: {
width: 2,
shadowBlur: 4,
shadowColor: shadowList[0],
shadowOffsetY: 2
}
},
data: this.chartData.eqCT
}, {
name: '设备TT',
type: 'line',
symbol: 'circle',
symbolSize: 5,
showSymbol: false,
lineStyle: {
normal: {
width: 2,
shadowBlur: 4,
shadowColor: shadowList[1],
shadowOffsetY: 2
}
},
data: this.chartData.eqTT
}, {
name: '产线CT',
type: 'line',
symbol: 'circle',
symbolSize: 5,
showSymbol: false,
lineStyle: {
normal: {
width: 2,
shadowBlur: 4,
shadowColor: shadowList[2],
shadowOffsetY: 2
}
},
data: this.chartData.lineCT
}, {
name: '产线TT',
type: 'line',
symbol: 'circle',
symbolSize: 5,
showSymbol: false,
lineStyle: {
normal: {
width: 2,
shadowBlur: 4,
shadowColor: shadowList[3],
shadowOffsetY: 2
}
},
data: this.chartData.lineTT
}]
})
}
}
}
</script>
<style lang="scss">
.line-tooltip{
background: #FFFFFF;
box-shadow: 0px 2px 6px 0px rgba(154, 170, 164, 0.5);
border-radius: 4px;
opacity: 0.85;
backdrop-filter: blur(23px);
padding: 8px;
}
</style>

View File

@@ -0,0 +1,178 @@
<template>
<div :id="id" :class="className" :style="{height:height,width:width}" />
</template>
<script>
import echarts from 'echarts'
import resize from './mixins/resize'
const colorList = ['#FFB61F', '#283D68', '#5AD8A6', '#E97466']
const shadowList = ['rgba(255, 179, 24, 0.5)', 'rgba(53, 66, 93, 0.5)', 'rgba(90, 216, 166, 0.6)', 'rgba(233, 116, 102, 0.5)']
export default {
mixins: [resize],
props: {
className: {
type: String,
default: 'chart'
},
id: {
type: String,
default: 'chart'
},
width: {
type: String,
default: '200px'
},
height: {
type: String,
default: '200px'
},
chartData: {
type: Array,
default: () => {}
}
},
data() {
return {
chart: null
}
},
watch: {
chartData: {
handler: function(val) {
this.initChart()
},
deep: true
}
},
mounted() {
this.initChart()
},
beforeDestroy() {
if (!this.chart) {
return
}
this.chart.dispose()
this.chart = null
},
methods: {
initChart() {
this.chart = echarts.init(document.getElementById(this.id))
this.chart.setOption({
// backgroundColor: '#394056',
tooltip: {
trigger: 'axis',
padding: 0,
backgroundColor: 'transparent',
renderMode: 'html',
textStyle: {
color: 'rgba(0, 0, 0, 0.85)',
fontSize: 12,
lineHeight: 14
},
formatter: function(param) {
var text = ''
const paramItem = param.map(item => {
return `<div style="display: flex; min-width: 150px">
<span>
<span style="display: inline-block; width: 4px; height: 4px; border-radius: 4px; background-color: ${item.color}; position: relative; top: -3px"></span>
<span>${item.seriesName}</span>
</span>
<span style="flex: 1;text-align: right">${item.value}</span>
</div>`
})
text = `<div class="line-tooltip">
<p style="margin: 0">${param[0].name}</p>
${paramItem.join('')}
</div>`
return text
}
},
color: colorList,
legend: {
top: 0,
data: this.chartData.map(item => {
return item.name
}),
right: '4%',
textStyle: {
fontSize: 12,
color: '#8C8C8C'
}
},
grid: {
top: 50,
left: '2%',
right: '2%',
bottom: '2%',
containLabel: true
},
xAxis: [{
type: 'category',
boundaryGap: false,
axisLine: {
lineStyle: {
color: '#57617B'
}
},
data: this.chartData[0].timeArr
}],
yAxis: [{
type: 'value',
name: '',
axisTick: {
show: false
},
axisLine: {
lineStyle: {
color: '#57617B'
}
},
axisLabel: {
margin: 10,
textStyle: {
fontSize: 14
}
},
splitLine: {
lineStyle: {
color: 'rgba(0, 0, 0, .15)'
}
}
}],
series: this.chartData.map((item, index) => {
return {
name: item.name,
type: 'line',
symbol: 'circle',
symbolSize: 5,
showSymbol: false,
lineStyle: {
normal: {
width: 2,
shadowBlur: 4,
shadowColor: shadowList[index % 4],
shadowOffsetY: 2
}
},
data: item.data
}
})
})
}
}
}
</script>
<style lang="scss">
.line-tooltip{
background: #FFFFFF;
box-shadow: 0px 2px 6px 0px rgba(154, 170, 164, 0.5);
border-radius: 4px;
opacity: 0.85;
backdrop-filter: blur(23px);
padding: 8px;
}
</style>

View File

@@ -0,0 +1,324 @@
<!--
/*
* @Author: lb
* @Date: 2022-07-24 13:30:00
* @LastEditTime: 2022-07-28 09:30:00
* @LastEditors: lb
* @Description: 设备效率分析-echarts图
*/
-->
<template>
<div class="graph-area">
<span class="close-btn" @click="close">
<svg
xmlns="http://www.w3.org/2000/svg"
style="height: 100%; width: 100%;"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
stroke-width="2"
>
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
</svg>
</span>
<div class="close-row" style="padding-left: 8px;">
<el-radio-group v-model="dataType" class="head-radio-group" size="small" @change="setLegend">
<el-radio-button label="百分比" />
<el-radio-button label="时间" />
</el-radio-group>
<el-radio-group
v-if="1"
v-model="searchType"
class="head-radio-group"
style="margin-left: 8px;"
size="small"
@change="handleRadioGroupChanged"
>
<el-radio-button v-for="(opt, index) in searchRadioOptions" :key="index" :label="opt" />
</el-radio-group>
</div>
<div id="trend-graph" class="real-graph" style="width: 100%; height: 500px;" />
</div>
</template>
<script>
import echarts from 'echarts'
import { getOEE } from '@/api/DataAnalysis/equipmentEfficiency'
import { refineData } from '@/utils/helpers'
import moment from 'moment'
class EchartConfigs {
constructor() {
this.color = ['#e91e63', '#4caf50', '#3f51b5', '#ffc107', '#607d8b']
this.title = {
text: '时间区间走势',
top: 0,
left: 'center',
textStyle: {
fontWeight: 'bold',
fontSize: 18,
lineHeight: 18
}
}
this.tooltip = {
trigger: 'axis',
// 将axisPointer设置得更显眼一点
axisPointer: {
type: 'shadow'
}
}
// legend
this.legend = {
icon: 'circle',
top: 24,
left: 'center',
padding: 8,
itemGap: 8,
data: [] // 动态设置
}
this.xAxis = {
type: 'category',
data: [] // 动态设置
// https://tushuo.baidu.com/wave/index#/manufacture/dta9pydmexfdhc0sg/999
}
this.yAxis = {
type: 'value'
}
this.series = [] // 动态设置
}
setTitle(val) {
this.title.text = val
}
setLegend(val) {
this.legend.data.splice(0)
if (Array.isArray(val)) {
this.legend.data = val
} else {
console.error('setLegend() 只接受数组参数')
}
}
setXAxis(val) {
// console.log('in setXAxis(): ', val)
this.xAxis.data.splice(0)
if (Array.isArray(val)) {
this.xAxis.data = val
} else {
console.error('setXAxis() 只接受数组参数')
}
}
setSeries(val) {
this.series.splice(0)
if (Array.isArray(val)) {
this.series = val
} else {
console.error('setSeries() 只接受数组参数')
}
}
}
export default {
name: 'EquipmentEfficiencyGraph',
props: {},
data() {
return {
searchType: '无间隔',
searchRadioOptions: ['无间隔', '按月', '按周', '按天'],
dataType: '时间',
dataRadioOptions: ['时间', '百分比'],
config: new EchartConfigs(),
chart: null,
rateList: [], // 对请求来的数据分流
timeList: [],
xAxis: [], // 动态设置
injectData: null
}
},
methods: {
async initChart() {
this.config.setTitle(this.injectData.equipmentName + ' 时间区间走势')
await this.getList()
this.setLegend()
},
init(data) {
this.injectData = data
if (!this.chart) {
this.chart = echarts.init(document.getElementById('trend-graph'))
// this.chart.setOption(this.config)
this.initChart()
}
},
close() {
this.$emit('close-graph')
},
makeQuerys() {
const searchTypeMap = {
无间隔: 1,
按月: 2,
按周: 3,
按天: 4
}
return {
// current: 1,
// size: 999,
// ftId: this.injectData.factoryId , // 工厂id
// wsId: this.injectData.workSequenceId , // 工段id
// productlines: ['1409788336610934786'], // 产线ids 这几项都暂时不需要
type: searchTypeMap[this.searchType],
eqId: this.injectData.equipmentId,
startTime: this.injectData.startTime, // '2022-06-14T00:00:00'
endTime: this.injectData.endTime
}
},
getList() {
const params = this.makeQuerys()
// 发起请求
return getOEE(params).then(res => {
this.timeList.splice(0)
this.rateList.splice(0)
this.xAxis.splice(0)
if (res.data) {
// 分流
res.data.map(item => {
const time = moment(item.time)
if (this.searchType === '按月') {
this.xAxis.push(`${time.year()}${time.month() + 1}`)
} else if (this.searchType === '按周') {
this.xAxis.push(`${time.format('YYYY-MM-DD')}`)
} else if (this.searchType === '按天') {
this.xAxis.push(`${time.format('YY-M-D')}`)
} else {
this.xAxis.push(`${time.format('YYYY-MM-DD')}`)
}
this.timeList.push(refineData(item, ['workTime', 'stopTime', 'downTime']))
this.rateList.push(
refineData(item, ['workRate', 'stopRate', 'downRate', 'peEfficiency', 'timeEfficiency', 'oee', 'teep'])
)
})
// 设置横轴
this.config.setXAxis(JSON.parse(JSON.stringify(this.xAxis)))
}
})
},
async handleRadioGroupChanged() {
// 获取数据且设置横轴
await this.getList()
// 设置legend和数据
this.setLegend()
},
setLegend() {
// 设置legend
const legendMap = {
百分比: ['工作时长比率', '停机时长比率', '故障时长比率', '速度开动率', '时间开动率', 'OEE', 'TEEP'],
时间: ['工作时长', '停机时长', '故障时长']
}
this.config.setLegend(legendMap[this.dataType])
this.setData()
// 重新绘制
this.renderGraph()
},
setData() {
if (this.dataType === '时间') {
const workTimeList = []
const stopTimeList = []
const downTimeList = []
this.timeList.map(item => {
workTimeList.push(item.workTime)
stopTimeList.push(item.stopTime)
downTimeList.push(item.downTime)
})
this.config.setSeries([
{ name: '工作时长', type: 'bar', data: workTimeList },
{ name: '停机时长', type: 'bar', data: stopTimeList },
{ name: '故障时长', type: 'bar', data: downTimeList }
])
} else {
// 百分比
const workRateList = []
const stopRateList = []
const downRateList = []
const peEfficiencyList = []
const timeEfficiencyList = []
const oeeList = []
const teepList = []
this.rateList.map(item => {
workRateList.push(item.workRate)
stopRateList.push(item.stopRate)
downRateList.push(item.downRate)
peEfficiencyList.push(item.peEfficiency)
timeEfficiencyList.push(item.timeEfficiency)
oeeList.push(item.oee)
teepList.push(item.teep)
})
this.config.setSeries([
{ name: '工作时长比率', type: 'bar', data: workRateList },
{ name: '停机时长比率', type: 'bar', data: stopRateList },
{ name: '故障时长比率', type: 'bar', data: downRateList },
{ name: '速度开动率', type: 'bar', data: peEfficiencyList },
{ name: '时间开动率', type: 'bar', data: timeEfficiencyList },
{ name: 'OEE', type: 'bar', data: oeeList },
{ name: 'TEEP', type: 'bar', data: teepList }
])
}
},
// 重新绘制图形
renderGraph() {
// console.log('latest config: ', this.config)
this.chart.setOption(this.config, {
notMerge: true
})
}
}
}
</script>
<style scoped>
.graph-area {
margin-top: 18px;
/* background: #f0f0f0; */
width: 100%;
min-height: 200px;
position: relative;
}
.close-row {
position: relative;
padding: 8px 0;
}
.close-btn {
position: absolute;
z-index: 1;
top: 10px;
right: 10px;
display: inline-block;
width: 20px;
height: 20px;
cursor: pointer;
transition: color 0.3s linear;
}
.close-btn:hover {
color: #0b58ff;
}
.head-radio-group >>> .el-radio-button__orig-radio:checked + .el-radio-button__inner {
background-color: #0b58ff;
border-color: #0b58ff;
}
</style>

View File

@@ -0,0 +1,88 @@
<!--
* @Author: lb
* @Date: 2022-07-22 13:30:00
* @LastEditors: lb
* @LastEditTime: 2022-07-22 13:30:00
* @Description: 设备状态时序图 - 弹窗
-->
<template>
<el-dialog :visible.sync="visible" title="选择一个设备" width="40%" @close="visible = false">
<el-select v-model="eqId">
<el-option v-for="eq in eqList" :key="eq.id" :label="eq.name" :value="eq.id" />
</el-select>
<div slot="footer">
<el-button @click="visible = false">{{ 'btn.back' | i18nFilter }}</el-button>
<el-button type="primary" @click="onConfirm">{{ 'btn.confirm' | i18nFilter }}</el-button>
</div>
</el-dialog>
</template>
<script>
import { getEquipmentList, getStatus } from '@/api/DataAnalysis/equipmentStatus'
export default {
name: 'EquipmentStatusDialog',
props: ['wsId'],
data() {
return {
visible: false,
eqId: null,
eqList: [],
equipment: null,
// queryCondition: {
// productlines: [],
// wsId: null,
// startTime: null,
// endTime: null
// }
queryCondition: null
}
},
mounted() {
this.fetchList('equipment')
},
methods: {
init(data) {
this.visible = true
this.queryCondition = data
},
fetchList(type) {
switch (type) {
case 'equipment': {
const query = this.wsId ? { workshopSectionId: this.wsId } : {}
return getEquipmentList(query).then(res => {
if (res.data) {
this.eqList = res.data.map(item => ({ id: item.id, name: item.name }))
} else {
this.eqList.splice(0)
}
})
}
}
},
onConfirm() {
if (this.eqId) {
// 获取 equipment 数据
getStatus({ ...this.queryCondition, eqId: this.eqId }).then(res => {
if (res.data && res.data.length > 0) {
this.equipment = res.data
// console.log('eq: ', this.equipment)
// 返回
this.onClose()
}
})
} else {
this.$message({
message: this.$t('module.basicData.visual.hints.selectEqFirst'),
type: 'error',
duration: 1500
})
}
},
onClose() {
this.visible = false
this.$emit('add-equipment', this.equipment)
}
}
}
</script>

View File

@@ -0,0 +1,73 @@
<!--
* @Author: gtz
* @Date: 2022-06-06 15:34:34
* @LastEditors: gtz
* @LastEditTime: 2022-06-09 17:45:35
* @Description: file content
* @FilePath: \mt-bus-fe\src\views\DataAnalysis\components\hoverBox.vue
-->
<template>
<div v-if="visible" class="hover-box" :style="{ left: buttonWidth + 'px' }">
<el-row class="hover-box-title">
{{ injectData.title }} <span style="margin: 0 16px">|</span> {{ injectData.line }} {{ injectData.process }} {{ injectData.equipmentName }} {{ moment(new Date()).format('YYYY-MM-DD') }}
</el-row>
<el-row class="hover-box-main" />
</div>
</template>
<script>
import moment from 'moment'
export default {
props: {
injectData: {
type: Object,
default: () => ({})
},
buttonWidth: {
type: Number,
default: () => 0
}
},
data() {
return {
visible: false,
moment
}
},
methods: {
init() {
this.visible = true
},
remove() {
this.visible = false
}
}
}
</script>
<style lang="scss" scoped>
.hover-box{
position: absolute;
left: 0;
top: 0;
min-width: 600px;
background: #020F1B;
color: #fff;
border-radius: 4px;
opacity: 0.85;
backdrop-filter: blur(6px);
background: #000;
z-index: 1;
font-size: 14px;
text-align: left;
.hover-box-title {
height: 48px;
line-height: 48px;
padding: 0 16px;
border-bottom: 1px solid rgba(255, 255, 255, .45);
}
.hover-box-main{
height: 50px;
}
}
</style>

View File

@@ -0,0 +1,56 @@
import { debounce } from '@/utils'
export default {
data() {
return {
$_sidebarElm: null,
$_resizeHandler: null
}
},
mounted() {
this.initListener()
},
activated() {
if (!this.$_resizeHandler) {
// avoid duplication init
this.initListener()
}
// when keep-alive chart activated, auto resize
this.resize()
},
beforeDestroy() {
this.destroyListener()
},
deactivated() {
this.destroyListener()
},
methods: {
// use $_ for mixins properties
// https://vuejs.org/v2/style-guide/index.html#Private-property-names-essential
$_sidebarResizeHandler(e) {
if (e.propertyName === 'width') {
this.$_resizeHandler()
}
},
initListener() {
this.$_resizeHandler = debounce(() => {
this.resize()
}, 100)
window.addEventListener('resize', this.$_resizeHandler)
this.$_sidebarElm = document.getElementsByClassName('sidebar-container')[0]
this.$_sidebarElm && this.$_sidebarElm.addEventListener('transitionend', this.$_sidebarResizeHandler)
},
destroyListener() {
window.removeEventListener('resize', this.$_resizeHandler)
this.$_resizeHandler = null
this.$_sidebarElm && this.$_sidebarElm.removeEventListener('transitionend', this.$_sidebarResizeHandler)
},
resize() {
const { chart } = this
chart && chart.resize()
}
}
}

View File

@@ -0,0 +1,439 @@
<!--
/*
* @Author: lb
* @Date: 2022-03-24 13:30:00
* @LastEditTime: 2022-05-10 18:38:24
* @LastEditors: gtz
* @Description: 拆分了搜索区和功能按钮区增加了toptitle
*/
-->
<template>
<div>
<div class="app-container">
<head-form :form-config="headFormConfig" @headBtnClick="btnClick" />
<transition mode="out-in" name="slide-to-left">
<equipment-efficiency-graph v-if="showGraph" key="graph" ref="eegraph" @close-graph="showGraph = false" />
<base-table
v-else
key="table"
:page="listQuery.current"
:limit="listQuery.size"
:table-config="tableProps"
:table-data="dataList"
:is-loading="listLoading"
:index-config="{ align: 'left', fixed: 'left' }"
@emitFun="handleTableEvents"
/>
</transition>
</div>
<!-- <div class="app-container">
<el-radio-group v-model="chartType" class="data-analysis-radio" size="mini" @change="changeChartType">
<el-radio-button v-for="(item, index) in chartDataArr" :key="index" :label="index">
{{ item.equipmentName }}
</el-radio-button>
</el-radio-group>
<Line-chart :chart-data="chartDataItem" width="100%" height="400px" />
</div> -->
</div>
</template>
<script>
import i18n from '@/lang'
import HeadForm from '@/components/basicData/HeadForm'
import BaseTable from '@/components/BaseTable/index-compound'
// import LineChart from '@/components/Charts/LineChart'
import { getLineList, getFactoryList, getOEE } from '@/api/DataAnalysis/equipmentEfficiency'
import moment from 'moment'
import commonBtn from '@/components/BaseTable/subcomponents/CommonBtn.vue'
import EquipmentEfficiencyGraph from './components/equipmentEfficiencyGraph.vue'
// import { timeFormatter } from '@/filters'
/**
* 表格表头配置项 TypeScript接口注释
* tableConfig<ConfigItem> = []
*
* Interface ConfigItem = {
* prop: string,
* label: string,
* width: string,
* align: string,
* subcomponent: function,
* filter: function
* }
*
*
*/
const tableProps = [
{
// label: '工厂',
label: i18n.t('module.dataAnalysis.equipmentEfficiency.factory'),
prop: 'factoryName'
},
{
// label: '产线',
label: i18n.t('module.dataAnalysis.equipmentEfficiency.line'),
prop: 'pdName'
},
{
// label: '工序',
label: i18n.t('module.dataAnalysis.equipmentEfficiency.process'),
prop: 'wsName'
},
{
// label: '设备',
label: i18n.t('module.dataAnalysis.equipmentEfficiency.eq'),
prop: 'eqName'
},
{
// label: '有效时间(h)',
label: i18n.t('module.dataAnalysis.equipmentEfficiency.time.efficient'),
children: [
{
prop: 'workTime',
// label: '工作时长(小时)',
label: i18n.t('module.dataAnalysis.equipmentEfficiency.time.work'),
width: 120,
filter: val => `${val} ${i18n.t('module.dataAnalysis.equipmentEfficiency.hour')}`
},
{
prop: 'workRate',
// label: '工作时长比率',
label: i18n.t('module.dataAnalysis.equipmentEfficiency.rate.work'),
width: 120,
filter: val => (val * 100).toFixed(2) + '%'
}
]
},
{
// label: '关机时间(h)',
label: i18n.t('module.dataAnalysis.equipmentEfficiency.time.off'),
children: [
{
prop: 'stopTime',
// label: '停机时长(小时)',
label: i18n.t('module.dataAnalysis.equipmentEfficiency.time.stop'),
width: 120,
filter: val => `${val} ${i18n.t('module.dataAnalysis.equipmentEfficiency.hour')}`
},
{
prop: 'stopRate',
// label: '停机比率',
label: i18n.t('module.dataAnalysis.equipmentEfficiency.rate.stop'),
filter: val => (val * 100).toFixed(2) + '%'
}
]
},
{
// label: '中断损失',
label: i18n.t('module.dataAnalysis.equipmentEfficiency.lost'),
children: [
{
prop: 'downTime',
// label: '故障时长(小时)',
label: i18n.t('module.dataAnalysis.equipmentEfficiency.time.down'),
width: 120,
filter: val => `${val} ${i18n.t('module.dataAnalysis.equipmentEfficiency.hour')}`
},
{
prop: 'downRate',
// label: '故障比率',
label: i18n.t('module.dataAnalysis.equipmentEfficiency.rate.down'),
filter: val => (val * 100).toFixed(2) + '%'
},
{
prop: 'timeEfficiency',
// label: '时间开动率',
label: i18n.t('module.dataAnalysis.equipmentEfficiency.timeRun'),
filter: val => (val * 100).toFixed(2) + '%'
}
]
},
{
// label: '速度损失',
label: i18n.t('module.dataAnalysis.equipmentEfficiency.speedLost'),
children: [
{
prop: 'realYield',
// label: '实际加工速度',
label: i18n.t('module.dataAnalysis.equipmentEfficiency.speed.real'),
width: 120,
filter: val => `${val} / ${i18n.t('module.dataAnalysis.equipmentEfficiency.hour')}`
}, // 片/小时
{
prop: 'designYield',
// label: '理论加工速度',
label: i18n.t('module.dataAnalysis.equipmentEfficiency.speed.thero'),
width: 120,
filter: val => `${val} / ${i18n.t('module.dataAnalysis.equipmentEfficiency.hour')}`
},
{
prop: 'peEfficiency',
// label: '速度开动率',
label: i18n.t('module.dataAnalysis.equipmentEfficiency.speed.rate'),
width: 120,
filter: val => (val * 100).toFixed(2) + '%'
}
]
},
// {
// prop: 'goodRate',
// label: '良品率' // 暂时先隐藏
// },
{
label: 'OEE',
prop: 'oee',
filter: val => (val * 100).toFixed(2) + '%'
},
{
label: 'TEEP',
prop: 'teep',
filter: val => (val * 100).toFixed(2) + '%'
},
{
// label: '操作',
label: i18n.t('module.dataAnalysis.equipmentEfficiency.operate'),
subcomponent: commonBtn,
emitFullData: true,
buttonContent: i18n.t('module.dataAnalysis.equipmentEfficiency.viewTrend'),
// buttonContent: '查看趋势',
actionName: 'view-trend'
}
]
export default {
name: 'EquipmentEfficiency',
components: { BaseTable, HeadForm, EquipmentEfficiencyGraph /** LineChart */ },
data() {
return {
addOrUpdateVisible: false,
tableProps,
dataList: [],
total: 0,
listLoading: false,
listQuery: {
current: 1,
size: 20
},
lineList: [],
headFormConfig: [
// label: i18n.t('module.dataAnalysis.productionLineBalance.line'),
// placeholder: this.$t('module.dataAnalysis.productionLineBalance.line'),
// width: 300,
{
type: 'select',
label: i18n.t('module.dataAnalysis.equipmentEfficiency.factory'),
placeholder: i18n.t('module.dataAnalysis.equipmentEfficiency.factory'),
// label: '工厂',
param: 'factoryId',
selectOptions: []
},
{
type: 'select',
label: i18n.t('module.dataAnalysis.equipmentEfficiency.line'),
placeholder: i18n.t('module.dataAnalysis.equipmentEfficiency.line'),
// label: '产线',
param: 'productLineIds',
multiple: true,
selectOptions: []
},
{
// 对于日期2022-7-1 ~ 2022-7-1 要转换为 2022/7/1T00:02:00 - 2022/7/2T00:02:00
type: 'select',
label: i18n.t('module.dataAnalysis.equipmentEfficiency.timeType'),
param: 'dateFilterType',
defaultSelect: 0,
selectOptions: [{ id: 0, name: i18n.t('module.dataAnalysis.equipmentEfficiency.rangeType') }, { id: 1, name: i18n.t('module.dataAnalysis.equipmentEfficiency.dateType') }],
index: 2, // 记录下当前配置项的index省的遍历的开销; index 和 extraOptions 要配合
extraOptions: [
{
elDatePickerKey: '8dkfl', // 防止el-date-picker飞到左上角
parent: 'dateFilterType',
// 时间段选择
type: 'datePicker',
label: i18n.t('module.dataAnalysis.equipmentEfficiency.range'),
dateType: 'daterange',
format: 'yyyy-MM-dd',
// valueFormat: 'yyyy-MM-dd',
defaultTime: ['00:00:00', '00:00:00'],
rangeSeparator: '-',
startPlaceholder: this.$t('module.dataAnalysis.productionLineBalance.startTime'),
endPlaceholder: this.$t('module.dataAnalysis.productionLineBalance.endTime'),
param: 'timeValue'
},
{
elDatePickerKey: '0lkfl',
parent: 'dateFilterType',
// 日期选择
type: 'datePicker',
label: i18n.t('module.dataAnalysis.equipmentEfficiency.date'),
dateType: 'date',
placeholder: i18n.t('module.dataAnalysis.equipmentEfficiency.hint.chooseTime'),
format: 'yyyy-MM-dd',
// valueFormat: 'yyyy-MM-dd', // 需要返回Date()
param: 'timeValue'
}
]
},
{
type: 'button',
btnName: 'btn.search',
name: 'search',
color: 'primary'
}
],
headFormValue: {},
showGraph: false
}
},
created() {
this.fetchList('factory')
this.fetchList('product-line')
// this.getList() // 时间间隔必填
},
methods: {
// 获取各种列表
fetchList(type) {
switch (type) {
case 'factory':
return getFactoryList().then(res => {
if (res.data) {
this.headFormConfig[0].selectOptions = res.data.map(factory => ({ id: factory.id, name: factory.name }))
// 设置defaultSelect
this.headFormConfig[0].defaultSelect = this.headFormConfig[0].selectOptions[0].id
}
})
case 'product-line':
return getLineList().then(res => {
if (res.data) {
this.headFormConfig[1].selectOptions = res.data.map(line => ({ id: line.id, name: line.name }))
// 设置defaultSelect
this.headFormConfig[1].defaultSelect = [this.headFormConfig[1].selectOptions[0].id]
}
})
}
},
// 获取首页列表
getList() {
// this.listLoading = true
const ftId = this.headFormValue.factoryId ? this.headFormValue.factoryId : ''
const productlines = this.headFormValue.productLineIds.length ? this.headFormValue.productLineIds : []
const { startTime, endTime } = this.getTimeRange()
getOEE({ ...this.listQuery, type: 1, ftId, productlines, startTime, endTime })
.then(res => {
this.dataList = res.data
// this.listLoading = false
})
.catch(err => {
if (err.message === '该时间段内设备未连接到数据库') {
this.dataList.splice(0)
}
})
},
// 顶部查询按钮
btnClick(val) {
this.headFormValue = val
if (this.headFormValue.btnName === 'search') {
this.getList()
}
this.showGraph = false
},
// handlers
handleTableEvents({ action, data }) {
// 有查看趋势和保留待用的OEE对比图(此者暂时不做)
switch (action) {
case 'view-trend':
this.viewTrends(data)
break
case 'view-oee-compare':
break
}
},
getTimeRange() {
let startTime
let endTime
if (this.headFormValue.timeValue instanceof Array) {
startTime = this.headFormValue.timeValue[0]
? moment(this.headFormValue.timeValue[0]).format('YYYY-MM-DDTHH:mm:ss')
: '' // 强制axios使用北京时间
endTime = this.headFormValue.timeValue[1]
? moment(this.headFormValue.timeValue[1]).format('YYYY-MM-DDTHH:mm:ss')
: ''
} else {
if (this.headFormValue.timeValue) {
startTime = moment(this.headFormValue.timeValue).format('YYYY-MM-DDTHH:mm:ss')
endTime = moment(startTime)
.add(1, 'd')
.format('YYYY-MM-DDTHH:mm:ss')
} else {
startTime = ''
endTime = ''
}
}
return { startTime, endTime }
},
viewTrends(data) {
const { startTime, endTime } = this.getTimeRange()
const injectData = {
// 时间段
startTime,
endTime,
// 设备id
equipmentId: data.eqId,
equipmentName: data.eqName,
// 时间类型, type 按年,按月,按日等
type: 1, // 默认 type 1, 1无间隔2按月分隔3按周分隔4按天分隔
// 时长数据: 工作时长, 停机时长,故障时长
workTime: data.workTime,
stopTime: data.stopTime,
downTime: data.downTime,
// 比例数据: 工作时长比率停机时长比率故障时长比率速度开动率OEETEEP
workRate: data.workRate,
stopRate: data.stopRate,
downRate: data.downRate,
peEfficiency: data.peEfficiency,
timeEfficiency: data.timeEfficiency
}
// console.log('trends data: ', data)
this.showGraph = true
setTimeout(() => {
// console.log('befoer graph: ', this.$refs.eegraph)
this.$refs.eegraph.init(injectData) // 注入初始数据,这些数据在组件内部用作条件,有可能会被更改
}, 600) // 动画是500ms
}
}
}
</script>
<style scoped>
.slide-to-left-enter-active,
.slide-to-left-leave-active {
transition: all 0.5s;
}
.slide-to-left-enter {
transform: translateX(10px);
opacity: 0;
}
.slide-to-left-leave-to {
transform: translateX(-10px);
opacity: 0;
}
.slide-to-left-leave,
.slide-to-left-enter-to {
transform: translateX(0);
}
</style>

View File

@@ -0,0 +1,240 @@
<!--
* @Author: gtz
* @Date: 2022-03-24 13:30:00
* @LastEditTime: 2022-07-25 09:58:51
* @LastEditors: lb
* @Description: 设备异常分析
-->
<template>
<div>
<div class="app-container">
<head-form :form-config="headFormConfig" @headBtnClick="btnClick" />
<base-table
:page="listQuery.current"
:limit="listQuery.size"
:table-config="tableProps"
:table-data="dataList"
:is-loading="listLoading"
@emitFun="handleTableEvents"
/>
</div>
</div>
</template>
<script>
import i18n from '@/lang'
import HeadForm from '@/components/basicData/HeadForm'
import BaseTable from '@/components/BaseTable/index'
// import ExceptionEqBtn from './components/ExceptionEqBtn'
import { getLineList, getEquipmentExceptionAnalysis } from '@/api/DataAnalysis/equipmentException'
import moment from 'moment'
import commonBtn from '@/components/BaseTable/subcomponents/CommonBtn.vue'
// import { timeFormatter } from '@/filters'
/**
* 表格表头配置项 TypeScript接口注释
* tableConfig<ConfigItem> = []
*
* Interface ConfigItem = {
* prop: string,
* label: string,
* width: string,
* align: string,
* subcomponent: function,
* filter: function
* }
*
*
*/
const tableProps = [
{
prop: 'pdName',
label: i18n.t('module.dataAnalysis.equipmentEfficiency.lineName')
// label: '产线名称'
},
{
prop: 'wsName',
label: i18n.t('module.dataAnalysis.equipmentException.process')
// label: '工序'
},
{
prop: 'eqName',
label: i18n.t('module.dataAnalysis.equipmentEfficiency.eq')
// label: '设备'
// subcomponent: ExceptionEqBtn
},
{
prop: 'mtbf',
label: i18n.t('module.dataAnalysis.equipmentEfficiency.mtbf'),
// label: '平均故障间隔时间[MTBF] (h)',
width: 230
},
{
prop: 'mttr',
label: i18n.t('module.dataAnalysis.equipmentEfficiency.mttr'),
// label: '平均维修时间[MTTR] (h)',
width: 230
},
{
prop: 'workTime',
label: i18n.t('module.dataAnalysis.equipmentEfficiency.time.work')
// label: '工作时长 (h)'
},
{
prop: 'downTime',
label: i18n.t('module.dataAnalysis.equipmentEfficiency.time.down')
// label: '故障时长 (h)'
},
{
prop: 'downCount',
label: i18n.t('module.dataAnalysis.equipmentEfficiency.downCount')
// label: '故障次数'
},
{
prop: '故障详情',
label: i18n.t('module.dataAnalysis.equipmentEfficiency.downDetail'),
// label: '故障详情',
subcomponent: commonBtn,
buttonContent: i18n.t('module.dataAnalysis.equipmentEfficiency.viewDetail'),
// buttonContent: '查看详情',
actionName: 'view-detail',
emitFullData: true
}
]
export default {
name: 'EquipmentExceptionAnalysis',
components: { BaseTable, HeadForm },
data() {
return {
tableProps,
dataList: [],
total: 0,
listLoading: false,
listQuery: {
current: 1,
size: 10
},
headFormConfig: [
{
type: 'datePicker',
label: i18n.t('module.basicData.visual.valueRequired.month') + '(' + i18n.t('module.dataAnalysis.equipmentEfficiency.required') + ')',
dateType: 'month',
format: 'yyyy-MM',
valueFormat: 'yyyy-MM-ddTHH:mm:ss',
placeholder: i18n.t('module.dataAnalysis.equipmentException.time'),
param: 'searchTime',
defaultSelect: new Date()
},
{
type: 'select',
label: i18n.t('module.dataAnalysis.equipmentException.line'),
placeholder: i18n.t('module.dataAnalysis.equipmentException.line'),
param: 'productLineId',
width: 300,
selectOptions: [],
defaultSelect: ''
},
{
type: 'button',
btnName: 'btn.search',
name: 'search',
color: 'primary'
}
],
headFormValue: {},
startTime: null,
endTime: null
}
},
created() {
this.fetchList('line')
},
methods: {
handleTableEvents({ action, data }) {
if (action === 'view-detail') {
// 获取数据并跳转到 厂务-报警管理
this.$router.push({
name: 'EquipmentAlarm',
params: {
eqName: data.eqName,
startTimeProp: this.startTime,
endTimeProp: this.endTime
}
})
}
},
fetchList(type) {
switch (type) {
case 'line':
return getLineList().then(res => {
if (res.data) {
this.headFormConfig[1].selectOptions = res.data.map(line => ({ id: line.id, name: line.name }))
// 设置defaultSelect
this.headFormConfig[1].defaultSelect = this.headFormConfig[1].selectOptions[0].id
}
})
}
},
getList() {
const DEFAULT_TYPE = 1
const productlines = this.headFormValue.productLineId ? [this.headFormValue.productLineId] : []
this.startTime = this.headFormValue.searchTime
? moment(this.headFormValue.searchTime)
.set({ date: 1, hour: 0, minute: 0, second: 0, millisecond: 0 })
.format('YYYY-MM-DDTHH:mm:ss')
: 0
this.endTime = this.startTime
? moment(this.startTime)
.add(1, 'M')
.format('YYYY-MM-DDTHH:mm:ss')
: 0
const type = DEFAULT_TYPE
if (this.startTime === 0 && this.endTime === 0) {
this.$message({
message: i18n.t('module.dataAnalysis.equipmentEfficiency.hint.chooseTime'),
type: 'error',
duration: 1500
})
} else {
getEquipmentExceptionAnalysis({ productlines, startTime: this.startTime, endTime: this.endTime, type }).then(
res => {
if (res.data) {
this.dataList = res.data
} else {
this.dataList.splice(0)
}
}
)
}
},
btnClick(val) {
this.headFormValue = val
if (this.headFormValue.btnName === 'search') {
this.getList()
}
}
}
}
</script>
<style lang="scss">
.exception-container {
.el-table {
overflow: visible;
.el-table__body-wrapper {
overflow: visible;
}
}
.el-table .cell {
overflow: visible;
}
}
</style>

View File

@@ -0,0 +1,367 @@
<!--
/*
* @Author: lb
* @Date: 2022-07-21 13:30:00
* @LastEditors: lb
* @LastEditTime: 2022-07-21 13:30:00
* @Description: 设备产量时序图
*/
-->
<template>
<div>
<div class="app-container">
<head-form :form-config="headFormConfig" @headBtnClick="btnClick" />
<transition mode="out-in" name="slide-to-left">
<equipment-efficiency-graph v-if="showGraph" key="graph" ref="eegraph" @close-graph="showGraph = false" />
<base-table
v-else
key="table"
:page="listQuery.current"
:limit="listQuery.size"
:table-config="tableProps"
:table-data="dataList"
:is-loading="listLoading"
:index-config="{ align: 'left', fixed: 'left' }"
@emitFun="handleTableEvents"
/>
</transition>
</div>
<!-- <div class="app-container">
<el-radio-group v-model="chartType" class="data-analysis-radio" size="mini" @change="changeChartType">
<el-radio-button v-for="(item, index) in chartDataArr" :key="index" :label="index">
{{ item.equipmentName }}
</el-radio-button>
</el-radio-group>
<Line-chart :chart-data="chartDataItem" width="100%" height="400px" />
</div> -->
</div>
</template>
<script>
// import i18n from '@/lang'
import HeadForm from '@/components/basicData/HeadForm'
import BaseTable from '@/components/BaseTable/index-compound'
// import LineChart from '@/components/Charts/LineChart'
import { getLineList, getFactoryList, getOEE } from '@/api/DataAnalysis/equipmentEfficiency'
import moment from 'moment'
import commonBtn from '@/components/BaseTable/subcomponents/CommonBtn.vue'
import EquipmentEfficiencyGraph from './components/equipmentEfficiencyGraph.vue'
// import { timeFormatter } from '@/filters'
/**
* 表格表头配置项 TypeScript接口注释
* tableConfig<ConfigItem> = []
*
* Interface ConfigItem = {
* prop: string,
* label: string,
* width: string,
* align: string,
* subcomponent: function,
* filter: function
* }
*
*
*/
const tableProps = [
{
label: '工厂',
prop: 'factoryName'
},
{
label: '产线',
prop: 'pdName'
},
{
label: '工序',
prop: 'wsName'
},
{
label: '设备',
prop: 'eqName'
},
{
label: '有效时间(h)',
children: [
{ prop: 'workTime', label: '工作时长(小时)', width: 120, filter: val => `${val} 小时` },
{ prop: 'workRate', label: '工作时长比率', width: 120, filter: val => (val * 100).toFixed(2) + '%' }
]
},
{
label: '关机时间(h)',
children: [
{ prop: 'stopTime', label: '停机时长(小时)', width: 120, filter: val => `${val} 小时` },
{ prop: 'stopRate', label: '停机比率', filter: val => (val * 100).toFixed(2) + '%' }
]
},
{
label: '中断损失',
children: [
{ prop: 'downTime', label: '故障时长(小时)', width: 120, filter: val => `${val} 小时` },
{ prop: 'downRate', label: '故障比率', filter: val => (val * 100).toFixed(2) + '%' }
]
},
{
label: '速度损失',
children: [
{ prop: 'realYield', label: '实际加工速度', width: 120, filter: val => `${val} 片/小时` }, // 片/小时
{ prop: 'designYield', label: '理论加工速度', width: 120, filter: val => `${val} 片/小时` },
{ prop: 'peEfficiency', label: '速度开动率', width: 120, filter: val => (val * 100).toFixed(2) + '%' }
]
},
// {
// prop: 'goodRate',
// label: '良品率' // 暂时先隐藏
// },
{
label: 'OEE',
prop: 'oee',
filter: val => (val * 100).toFixed(2) + '%'
},
{
label: 'TEEP',
prop: 'teep',
filter: val => (val * 100).toFixed(2) + '%'
},
{
label: '操作',
subcomponent: commonBtn,
emitFullData: true,
buttonContent: '查看趋势',
actionName: 'view-trend'
}
]
export default {
name: 'EquipmentEfficiency',
components: { BaseTable, HeadForm, EquipmentEfficiencyGraph /** LineChart */ },
data() {
return {
addOrUpdateVisible: false,
tableProps,
dataList: [],
total: 0,
listLoading: false,
listQuery: {
current: 1,
size: 20
},
lineList: [],
headFormConfig: [
// label: i18n.t('module.dataAnalysis.productionLineBalance.line'),
// placeholder: this.$t('module.dataAnalysis.productionLineBalance.line'),
// width: 300,
{
type: 'select',
label: '工厂',
param: 'factoryId',
selectOptions: []
},
{
type: 'select',
label: '产线',
param: 'productLineIds',
multiple: true,
selectOptions: []
},
{
// 对于日期2022-7-1 ~ 2022-7-1 要转换为 2022/7/1T00:02:00 - 2022/7/2T00:02:00
type: 'select',
label: '时间类型',
param: 'dateFilterType',
defaultSelect: 0,
selectOptions: [{ id: 0, name: '按时间段' }, { id: 1, name: '按日期' }],
index: 2, // 记录下当前配置项的index省的遍历的开销; index 和 extraOptions 要配合
extraOptions: [
{
elDatePickerKey: '8dkfl', // 防止el-date-picker飞到左上角
parent: 'dateFilterType',
// 时间段选择
type: 'datePicker',
label: '时间段',
dateType: 'daterange',
format: 'yyyy-MM-dd',
// valueFormat: 'yyyy-MM-dd',
defaultTime: ['00:00:00', '00:00:00'],
rangeSeparator: '-',
startPlaceholder: this.$t('module.dataAnalysis.productionLineBalance.startTime'),
endPlaceholder: this.$t('module.dataAnalysis.productionLineBalance.endTime'),
param: 'timeValue'
},
{
elDatePickerKey: '0lkfl',
parent: 'dateFilterType',
// 日期选择
type: 'datePicker',
label: '日期',
dateType: 'date',
placeholder: '选择日期',
format: 'yyyy-MM-dd',
// valueFormat: 'yyyy-MM-dd', // 需要返回Date()
param: 'timeValue'
}
]
},
{
type: 'button',
btnName: 'btn.search',
name: 'search',
color: 'primary'
}
],
headFormValue: {},
showGraph: false
}
},
created() {
this.fetchList('factory')
this.fetchList('product-line')
// this.getList() // 时间间隔必填
},
methods: {
// 获取各种列表
fetchList(type) {
switch (type) {
case 'factory':
return getFactoryList().then(res => {
if (res.data) {
this.headFormConfig[0].selectOptions = res.data.map(factory => ({ id: factory.id, name: factory.name }))
// 设置defaultSelect
this.headFormConfig[0].defaultSelect = this.headFormConfig[0].selectOptions[0].id
}
})
case 'product-line':
return getLineList().then(res => {
if (res.data) {
this.headFormConfig[1].selectOptions = res.data.map(line => ({ id: line.id, name: line.name }))
// 设置defaultSelect
this.headFormConfig[1].defaultSelect = [this.headFormConfig[1].selectOptions[0].id]
}
})
}
},
// 获取首页列表
getList() {
// this.listLoading = true
const ftId = this.headFormValue.factoryId ? this.headFormValue.factoryId : ''
const productlines = this.headFormValue.productLineIds.length ? this.headFormValue.productLineIds : []
let startTime
let endTime
if (this.headFormValue.timeValue instanceof Array) {
startTime = this.headFormValue.timeValue[0]
? moment(this.headFormValue.timeValue[0]).format('YYYY-MM-DDTHH:mm:ss')
: '' // 强制axios使用北京时间
endTime = this.headFormValue.timeValue[1]
? moment(this.headFormValue.timeValue[1]).format('YYYY-MM-DDTHH:mm:ss')
: ''
} else {
if (this.headFormValue.timeValue) {
startTime = moment(this.headFormValue.timeValue)
.add(2, 'm')
.format('YYYY-MM-DDTHH:mm:ss')
endTime = moment(startTime)
.add(1, 'd')
.format('YYYY-MM-DDTHH:mm:ss')
} else {
startTime = ''
endTime = ''
}
}
getOEE({ ...this.listQuery, type: 1, ftId, productlines, startTime, endTime })
.then(res => {
this.dataList = res.data
// this.listLoading = false
})
.catch(err => {
if (err.message === '该时间段内设备未连接到数据库') {
this.dataList.splice(0)
}
})
},
// 顶部查询按钮
btnClick(val) {
this.headFormValue = val
if (this.headFormValue.btnName === 'search') {
this.getList()
}
this.showGraph = false
},
// handlers
handleTableEvents({ action, data }) {
// 有查看趋势和保留待用的OEE对比图(此者暂时不做)
switch (action) {
case 'view-trend':
this.viewTrends(data)
break
case 'view-oee-compare':
break
}
},
viewTrends(data) {
const startTime = this.headFormValue.timeValue[0]
? moment(this.headFormValue.timeValue[0]).format('YYYY-MM-DDTHH:mm:ss')
: '' // 强制axios使用北京时间
const endTime = this.headFormValue.timeValue[1]
? moment(this.headFormValue.timeValue[1]).format('YYYY-MM-DDTHH:mm:ss')
: ''
const injectData = {
// 时间段
startTime,
endTime,
// 设备id
equipmentId: data.eqId,
equipmentName: data.eqName,
// 时间类型, type 按年,按月,按日等
type: 1, // 默认 type 1, 1无间隔2按月分隔3按周分隔4按天分隔
// 时长数据: 工作时长, 停机时长,故障时长
workTime: data.workTime,
stopTime: data.stopTime,
downTime: data.downTime,
// 比例数据: 工作时长比率停机时长比率故障时长比率速度开动率OEETEEP
workRate: data.workRate,
stopRate: data.stopRate,
downRate: data.downRate,
peEfficiency: data.peEfficiency
}
console.log('trends data: ', data)
this.showGraph = true
setTimeout(() => {
console.log('befoer graph: ', this.$refs.eegraph)
this.$refs.eegraph.init(injectData) // 注入初始数据,这些数据在组件内部用作条件,有可能会被更改
}, 600) // 动画是500ms
}
}
}
</script>
<style scoped>
.slide-to-left-enter-active,
.slide-to-left-leave-active {
transition: all 0.5s;
}
.slide-to-left-enter {
transform: translateX(10px);
opacity: 0;
}
.slide-to-left-leave-to {
transform: translateX(-10px);
opacity: 0;
}
.slide-to-left-leave,
.slide-to-left-enter-to {
transform: translateX(0);
}
</style>

View File

@@ -0,0 +1,656 @@
<!--
/*
* @Author: lb
* @Date: 2022-07-21 13:30:00
* @LastEditors: lb
* @LastEditTime: 2022-07-21 13:30:00
* @Description: 设备状态时序图
*/
-->
<template>
<div class="app-container">
<head-form
class="head-form"
style="padding-top: 8px;"
:form-config="headFormConfig"
@headBtnClick="btnClick"
@select-changed="handleHeadSelectChanged"
/>
<div class="time-chart" style="margin-top: 10px;">
<div
v-show="equipmentCount > 0"
id="time-chart__inner"
ref="time-chart__inner"
class="time-chart__inner"
style="width: 100%; min-height: 50vh;"
:style="{ height: autoHeight + 'px' }"
/>
<div v-show="equipmentCount === 0">{{ $t('module.basicData.visual.hints.searchFirst') }}</div>
</div>
<eq-dialog v-if="addOrUpdateVisible" ref="addOrUpdate" :ws-id="wsId" @add-equipment="addEquipmentToSeriesData" />
</div>
</template>
<script>
import i18n from '@/lang'
// import { timeFormatter } from '@/filters'
import HeadForm from '@/components/basicData/HeadForm'
import { getLineList, getWorkSequenceList, getStatus } from '@/api/DataAnalysis/equipmentStatus'
import moment from 'moment'
import echarts from 'echarts'
import EqDialog from './components/equipmentStatus--dialog.vue'
/**
* 表格表头配置项 TypeScript接口注释
* tableConfig<ConfigItem> = []
*
* Interface ConfigItem = {
* prop: string,
* label: string,
* width: string,
* align: string,
* subcomponent: function,
* filter: function
* }
*
*
*/
function renderItem(params, api) {
var categoryIndex = api.value(0)
var start = api.coord([api.value(1), categoryIndex])
var end = api.coord([api.value(2), categoryIndex])
var height = 32
return {
type: 'rect',
shape: echarts.graphic.clipRectByRect(
{
x: start[0],
y: start[1] - height / 2,
width: end[0] - start[0],
height: height
},
{
x: params.coordSys.x,
y: params.coordSys.y,
width: params.coordSys.width,
height: params.coordSys.height
}
),
style: api.style()
}
}
class ChartOption {
constructor() {
this.color = ['#4caf50', '#ffb300', '#e53935']
this.legend = {
data: [
i18n.t('module.basicData.visual.echartLegends.working'),
i18n.t('module.basicData.visual.echartLegends.stop'),
i18n.t('module.basicData.visual.echartLegends.breakdown')
],
bottom: '0%',
selectedMode: false,
textStyle: {
color: '#000'
}
}
this.tooltip = {
formatter: function(params) {
return (
moment(params.value[1]).format('YYYY-MM-DD HH:mm:ss') +
' - ' +
moment(params.value[2]).format('YYYY-MM-DD HH:mm:ss') +
' : ' +
params.name
)
}
}
this.title = {
text: i18n.t('module.basicData.visual.echartTitles.eqStatus'),
left: 'center'
}
this.xAxis = {
type: 'time',
// min: +new Date().setHours(0, 0, 0, 0),
splitNumber: 24,
interval: 3600 * 1000,
axisTick: {
show: true,
alignWithLabel: true
},
axisLine: {
show: true
},
axisLabel: {
formatter: function(val) {
const time = new Date(val)
const hour = time.getHours()
const minute = time.getMinutes()
const hours = hour >= 10 ? hour + '' : '0' + hour
const minutes = minute >= 10 ? minute + '' : '0' + minute
return hours + ':' + minutes
}
}
}
this.yAxis = {
// data: Object.keys(eqData).map(item => eqData[item].name)
data: []
}
this.series = [
{ name: i18n.t('module.basicData.visual.echartLegends.working'), type: 'bar', data: [] },
{ name: i18n.t('module.basicData.visual.echartLegends.stop'), type: 'bar', data: [] },
{ name: i18n.t('module.basicData.visual.echartLegends.breakdown'), type: 'bar', data: [] },
{
type: 'custom',
renderItem: renderItem,
itemStyle: {
opacity: 0.8
},
encode: {
x: [1, 2],
y: 0
},
data: []
}
]
}
setTitle(title) {
this.title.text = title
}
// date: 服务器返回来的日期时间数据
setXAxis(date) {
// this.xAxis.min = +new Date(date).setHours(0)
this.xAxis.min = +new Date(date).setHours(0, 0, 0, 0)
this.xAxis.max = this.xAxis.min + 3600 * 1000 * 24
}
setYAxis(data) {
this.yAxis.data = data
}
setData(data) {
this.series[3].data = data
}
}
export default {
name: 'SxtEquipmentStatus',
components: { HeadForm, EqDialog },
data() {
return {
addOrUpdateVisible: false,
dataList: [],
total: 0,
listLoading: false,
listQuery: {
current: 1,
size: 20
},
headFormConfig: [
{
type: 'select',
// label: '产线',
label: i18n.t('module.dataAnalysis.equipmentEfficiency.line'),
param: 'productLineId',
// multiple: true,
selectOptions: [],
defaultSelect: '',
onchange: true
},
{
type: 'select',
// label: '工序',
label: i18n.t('module.dataAnalysis.equipmentEfficiency.process'),
param: 'workSequenceId',
// multiple: true,
selectOptions: [],
defaultSelect: ''
},
{
// 对于日期2022-7-1 ~ 2022-7-1 要转换为 2022/7/1T00:02:00 - 2022/7/2T00:02:00
type: 'datePicker',
// label: '日期',
label: i18n.t('module.dataAnalysis.equipmentEfficiency.date'),
dateType: 'date',
placeholder: this.$t('module.basicData.visual.hints.selectDate'),
param: 'date',
defaultSelect: new Date()
},
{
type: 'button',
btnName: 'btn.search',
name: 'search',
color: 'primary'
},
{
type: 'button',
btnName: `+ ${i18n.t('module.dataAnalysis.equipmentEfficiency.addEq')}`,
name: 'add-eq',
color: 'success'
}
],
headFormValue: {},
chart: null,
chartOption: new ChartOption(),
equipments: {},
startTime: null,
state: ['正常', '停机', '故障'],
colors: ['#4caf50', '#ffb300', '#e53935'],
queryBuffer: {},
wsId: null
}
},
computed: {
autoHeight: function() {
return Object.keys(this.equipments).length * 100 || 500
},
equipmentCount: function() {
return Object.keys(this.equipments).length
}
},
updated() {
if (this.chart) this.chart.resize()
},
mounted() {
this.fetchList('product-line').then(() => {
this.fetchList('work-section')
})
this.$nextTick(() => {
this.initChart()
})
},
methods: {
initChart() {
if (!this.chart) {
this.chart = echarts.init(this.$refs['time-chart__inner'])
// 获取数据
// const today = new Date(new Date().setHours(0,0,0,0))
// getStatus({
// productlines: this.headFormConfig[0].defaultSelect,
// wsId: this.headFormConfig[1].defaultSelect,
// startTime: today,
// endTime: new Date(today.getTime() + 3600 * 1000 * 24)
// }).then(res => {})
}
},
// handlers
async handleHeadSelectChanged(data) {
if (data.param === 'productLineId') {
this.headFormConfig[0].defaultSelect = data.value
await this.fetchList('work-section')
}
},
// 获取各种列表
fetchList(type) {
switch (type) {
case 'work-section': {
return getWorkSequenceList({ productionLineId: this.headFormConfig[0].defaultSelect }).then(res => {
if (res.data && res.data.length) {
this.headFormConfig[1].selectOptions = res.data.map(ws => ({ id: ws.id, name: ws.name }))
// 设置defaultSelect
this.wsId = this.headFormConfig[1].selectOptions[0].id
this.headFormConfig[1].defaultSelect = this.headFormConfig[1].selectOptions[0].id
} else {
this.headFormConfig[1].selectOptions.splice(0)
this.headFormConfig[1].defaultSelect = null
}
})
}
case 'product-line':
return getLineList().then(res => {
if (res.data) {
this.headFormConfig[0].selectOptions = res.data.map(line => ({ id: line.id, name: line.name }))
// 设置defaultSelect
this.headFormConfig[0].defaultSelect = this.headFormConfig[0].selectOptions[0].id
}
})
}
},
// 把服务器数据按照设备分组
transformDataToEquipments(dataList) {
const equipments = {}
dataList.map(item => {
if (equipments[item.eqId]) {
// 如果设备已存在
equipments[item.eqId].name = item.eqName
equipments[item.eqId].status.push({
startTime: +new Date(item.startTime),
endTime: +new Date(item.endTime),
status: this.state[item.status] // 0 正常、1 停机、2 故障
})
} else {
equipments[item.eqId] = {
name: item.eqName,
status: [
{
startTime: +new Date(item.startTime),
endTime: +new Date(item.endTime),
status: this.state[item.status] // 0 正常、1 停机、2 故障
}
]
}
}
})
// console.log('items --- ', equipments)
return equipments
},
// 把分组好的设备数据转换为echarts需要的series数据
transformEquipmentsToSeries(equipments) {
const seriesData = []
Object.entries(equipments).map(([key, item], index) => {
item.status.forEach(status => {
seriesData.push({
name: status.status,
value: [index, status.startTime, status.endTime],
itemStyle: {
normal: {
color:
status.status === '正常'
? '#4caf50'
: status.status === '停机'
? '#ffb300'
: status.status === '故障'
? '#e53935'
: null
}
}
})
})
})
return seriesData
},
// 顶部查询按钮
btnClick(val) {
this.headFormValue = val
if (this.headFormValue.btnName === 'search') {
const productlines = this.headFormValue.productLineId ? [this.headFormValue.productLineId] : []
const wsId = this.headFormValue.workSequenceId || ''
const date = this.headFormValue.date || new Date()
const startTime = moment(new Date(date.setHours(0, 0, 0, 0))).format('YYYY-MM-DDTHH:mm:ss')
const endTime = moment(new Date(date.setHours(0, 0, 0, 0)))
.add(1, 'd')
.format('YYYY-MM-DDTHH:mm:ss')
this.$set(this.queryBuffer, 'productlines', productlines)
this.$set(this.queryBuffer, 'wsId', wsId)
this.$set(this.queryBuffer, 'startTime', startTime)
this.$set(this.queryBuffer, 'endTime', endTime)
getStatus({
productlines,
wsId,
startTime,
endTime
}).then(res => {
if (res.data && res.data.length > 0) {
this.dataList = res.data
// this.dataList = [
// {
// eqId: 'eq-001',
// eqName: 'A1预热机',
// startTime: '2022-05-04T00:30:34',
// endTime: '2022-05-04T08:30:34',
// status: 0
// },
// {
// eqId: 'eq-001',
// eqName: 'A1预热机',
// startTime: '2022-05-04T08:30:34',
// endTime: '2022-05-04T09:30:34',
// status: 1
// },
// {
// eqId: 'eq-001',
// eqName: 'A1预热机',
// startTime: '2022-05-04T09:30:34',
// endTime: '2022-05-04T11:30:34',
// status: 2
// },
// {
// eqId: 'eq-001',
// eqName: 'A1预热机',
// startTime: '2022-05-04T11:30:34',
// endTime: '2022-05-04T13:30:34',
// status: 1
// },
// {
// eqId: 'eq-001',
// eqName: 'A1预热机',
// startTime: '2022-05-04T13:30:34',
// endTime: '2022-05-04T18:30:34',
// status: 0
// },
// {
// eqId: 'eq-001',
// eqName: 'A1预热机',
// startTime: '2022-05-04T18:30:34',
// endTime: '2022-05-05T00:00:00',
// status: 1
// },
// {
// eqId: 'eq-002',
// eqName: 'A2预热机',
// startTime: '2022-05-04T01:30:34',
// endTime: '2022-05-04T08:30:34',
// status: 2
// },
// {
// eqId: 'eq-002',
// eqName: 'A2预热机',
// startTime: '2022-05-04T08:30:34',
// endTime: '2022-05-04T18:30:34',
// status: 2
// },
// {
// eqId: 'eq-002',
// eqName: 'A2预热机',
// startTime: '2022-05-04T18:30:34',
// endTime: '2022-05-04T22:30:34',
// status: 0
// },
// {
// eqId: 'eq-002',
// eqName: 'A2预热机',
// startTime: '2022-05-04T22:30:34',
// endTime: '2022-05-04T23:30:34',
// status: 1
// },
// {
// eqId: 'eq-002',
// eqName: 'A2预热机',
// startTime: '2022-05-04T23:30:34',
// endTime: '2022-05-05T00:00:00',
// status: 2
// },
// {
// eqId: 'eq-0003',
// eqName: 'A3预热机',
// startTime: '2022-05-04T00:00:00',
// endTime: '2022-05-04T08:30:34',
// status: 0
// },
// {
// eqId: 'eq-0003',
// eqName: 'A3预热机',
// startTime: '2022-05-04T08:30:34',
// endTime: '2022-05-04T18:30:34',
// status: 2
// },
// {
// eqId: 'eq-0003',
// eqName: 'A3预热机',
// startTime: '2022-05-04T18:30:34',
// endTime: '2022-05-04T22:30:34',
// status: 1
// },
// {
// eqId: 'eq-0003',
// eqName: 'A3预热机',
// startTime: '2022-05-04T22:30:34',
// endTime: '2022-05-04T23:30:34',
// status: 1
// },
// {
// eqId: 'eq-004',
// eqName: 'A4预热机',
// startTime: '2022-05-04T01:30:34',
// endTime: '2022-05-04T04:30:34',
// status: 2
// },
// {
// eqId: 'eq-004',
// eqName: 'A4预热机',
// startTime: '2022-05-04T04:30:34',
// endTime: '2022-05-04T08:30:34',
// status: 0
// },
// {
// eqId: 'eq-004',
// eqName: 'A4预热机',
// startTime: '2022-05-04T08:30:34',
// endTime: '2022-05-04T11:30:34',
// status: 1
// },
// {
// eqId: 'eq-004',
// eqName: 'A4预热机',
// startTime: '2022-05-04T11:30:34',
// endTime: '2022-05-04T13:30:34',
// status: 2
// },
// {
// eqId: 'eq-004',
// eqName: 'A4预热机',
// startTime: '2022-05-04T13:30:34',
// endTime: '2022-05-04T18:30:34',
// status: 1
// },
// {
// eqId: 'eq-005',
// eqName: 'A4预热机',
// startTime: '2022-05-04T18:30:34',
// endTime: '2022-05-04T20:30:34',
// status: 1
// },
// {
// eqId: 'eq-005',
// eqName: 'A5预热机',
// startTime: '2022-05-04T08:30:34',
// endTime: '2022-05-04T18:30:34',
// status: 0
// },
// {
// eqId: 'eq-005',
// eqName: 'A5预热机',
// startTime: '2022-05-04T18:30:34',
// endTime: '2022-05-04T20:30:34',
// status: 2
// },
// {
// eqId: 'eq-005',
// eqName: 'A5预热机',
// startTime: '2022-05-04T20:30:34',
// endTime: '2022-05-04T22:30:34',
// status: 1
// },
// {
// eqId: 'eq-005',
// eqName: 'A5预热机',
// startTime: '2022-05-04T22:30:34',
// endTime: '2022-05-04T23:30:34',
// status: 0
// },
// {
// eqId: 'eq-005',
// eqName: 'A5预热机',
// startTime: '2022-05-04T23:30:34',
// endTime: '2022-05-05T00:30:34',
// status: 1
// }
// ]
this.equipments = this.transformDataToEquipments(this.dataList)
this.chartOption.setYAxis(Object.keys(this.equipments).map(item => this.equipments[item].name))
this.chartOption.setXAxis(this.dataList[0].startTime)
this.chartOption.setData(this.transformEquipmentsToSeries(this.equipments))
this.renderChart()
} else {
this.dataList.splice(0)
}
})
} else if (this.headFormValue.btnName === 'add-eq') {
if (this.equipmentCount === 0) {
this.$message({
message: this.$t('module.basicData.visual.hints.searchFirst'),
type: 'warning',
duration: 1500
})
} else {
// 添加设备
// console.log('添加设备')
this.addOrUpdateVisible = true
this.$nextTick(() => {
// console.log('ref', this.$refs.addOrUpdate)
this.$refs.addOrUpdate.init(this.queryBuffer)
})
}
// 1.get eq
// const testEq = {
// code: 0,
// data: [
// { eqId: 'eq-006', eqName: 'A6预热机', startTime: '2022-05-04T00:00:00', endTime: '2022-05-04T01:30:34', status: 1 },
// { eqId: 'eq-006', eqName: 'A6预热机', startTime: '2022-05-04T01:30:34', endTime: '2022-05-04T03:00:34', status: 0 },
// { eqId: 'eq-006', eqName: 'A6预热机', startTime: '2022-05-04T03:00:34', endTime: '2022-05-04T06:30:00', status: 2 },
// { eqId: 'eq-006', eqName: 'A6预热机', startTime: '2022-05-04T06:30:00', endTime: '2022-05-04T12:30:00', status: 0 },
// { eqId: 'eq-006', eqName: 'A6预热机', startTime: '2022-05-04T12:30:00', endTime: '2022-05-04T13:30:00', status: 1 },
// { eqId: 'eq-006', eqName: 'A6预热机', startTime: '2022-05-04T13:30:00', endTime: '2022-05-04T18:30:34', status: 0 },
// { eqId: 'eq-006', eqName: 'A6预热机', startTime: '2022-05-04T18:30:34', endTime: '2022-05-04T19:30:34', status: 2 },
// { eqId: 'eq-006', eqName: 'A6预热机', startTime: '2022-05-04T19:30:34', endTime: '2022-05-04T22:00:00', status: 0 },
// { eqId: 'eq-006', eqName: 'A6预热机', startTime: '2022-05-04T22:00:00', endTime: '2022-05-04T23:00:00', status: 1 },
// { eqId: 'eq-006', eqName: 'A6预热机', startTime: '2022-05-04T23:00:00', endTime: '2022-05-05T00:00:00', status: 2 },
// ]
// }
// this.addEquipmentToSeriesData(testEq.data)
}
},
addEquipmentToSeriesData(dataList) {
const newEq = this.transformDataToEquipments(dataList)
this.$set(this.equipments, Object.keys(newEq)[0], newEq[Object.keys(newEq)[0]])
this.chartOption.setYAxis(Object.keys(this.equipments).map(item => this.equipments[item].name))
this.chartOption.setData(this.transformEquipmentsToSeries(this.equipments))
this.renderChart()
},
renderChart() {
// console.log('rendering chart: ', this.chartOption)
this.chart.setOption(this.chartOption)
}
}
}
</script>
<style scoped>
.head-form >>> .el-date-editor .el-input__prefix {
left: unset;
right: 5px;
color: #0b58ff;
}
.head-form >>> .el-date-editor .el-input__suffix {
left: 5px;
right: unset;
color: #0b58ff;
}
</style>

View File

@@ -0,0 +1,366 @@
<!--
/*
* @Author: lb
* @Date: 2022-03-24 13:30:00
* @LastEditTime: 2022-05-10 18:38:27
* @LastEditors: gtz
* @Description: 拆分了搜索区和功能按钮区增加了toptitle
*/
-->
<template>
<div>
<div class="app-container">
<top-title />
<head-form
:form-config="headFormConfig"
@headBtnClick="btnClick"
/>
<base-table
:page="listQuery.current"
:limit="listQuery.size"
:table-config="trueTableProps.length ? trueTableProps: tableProps"
:table-data="tableData.length ? tableData : []"
:span-method="spanMethod"
:is-loading="listLoading"
:index-config="{ align: 'left', fixed: 'left' }"
/>
</div>
<div class="app-container">
<el-radio-group v-model="chartType" class="data-analysis-radio" size="mini" @change="changeChartType">
<el-radio-button v-for="(item, index) in chartDataArr" :key="index" :label="index">{{ item.equipmentName }}</el-radio-button>
</el-radio-group>
<Line-chart :chart-data="chartDataItem" width="100%" height="400px" />
</div>
</div>
</template>
<script>
import Vue from 'vue'
import i18n from '@/lang'
import TopTitle from '@/components/TopTitle'
import HeadForm from '@/components/basicData/HeadForm'
import BaseTable from '@/components/BaseTable/index-compound'
import LineChart from '@/components/Charts/LineChart'
import { lineList } from '@/api/DataAnalysis/productionLineBalance'
// import { timeFormatter } from '@/filters'
/**
* 表格表头配置项 TypeScript接口注释
* tableConfig<ConfigItem> = []
*
* Interface ConfigItem = {
* prop: string,
* label: string,
* width: string,
* align: string,
* subcomponent: function,
* filter: function
* }
*
*
*/
const tableProps = [
{
prop: 'process',
label: i18n.t('module.dataAnalysis.productionLineBalance.process'),
align: 'center',
fixed: 'left'
},
{
prop: 'equipmentName',
label: i18n.t('module.dataAnalysis.productionLineBalance.equipmentName'),
align: 'center',
fixed: 'left'
}
]
const testData = [
{
process: '清洗',
data: [
{
equipmentName: '上料清洗1',
data: [
{
time: '2022-5-6',
eqCT: 0.46,
eqTT: 0.12,
lineCT: 0.68,
lineTT: 0.25
},
{
time: '2022-5-7',
eqCT: 0.34,
eqTT: 0.25,
lineCT: 0.42,
lineTT: 0.4733
},
{
time: '2022-5-8',
eqCT: 0.01,
eqTT: 0.62,
lineCT: 0.73,
lineTT: 0.45
}
]
},
{
equipmentName: '上料清洗2',
data: [
{
time: '2022-5-6',
eqCT: 0.46,
eqTT: 0.62,
lineCT: 0.24,
lineTT: 0.70
},
{
time: '2022-5-7',
eqCT: 0.32,
eqTT: 0.58,
lineCT: 0.46,
lineTT: 0.80
},
{
time: '2022-5-8',
eqCT: 0.35,
eqTT: 0.83,
lineCT: 0.29,
lineTT: 0.90
}
]
}
]
},
{
process: '磨边',
data: [
{
equipmentName: '磨边1',
data: [
{
time: '2022-5-6',
eqCT: 0.16,
eqTT: 0.42,
lineCT: 0.85,
lineTT: 0.26
},
{
time: '2022-5-7',
eqCT: 0.31,
eqTT: 0.21,
lineCT: 0.11,
lineTT: 0.46
},
{
time: '2022-5-8',
eqCT: 0.82,
eqTT: 0.25,
lineCT: 0.09,
lineTT: 0.23
}
]
},
{
equipmentName: '磨边2',
data: [
{
time: '2022-5-6',
eqCT: 0.33,
eqTT: 0.62,
lineCT: 0.37,
lineTT: 0.22
},
{
time: '2022-5-7',
eqCT: 0.32,
eqTT: 0.24,
lineCT: 0.21,
lineTT: 0.25
},
{
time: '2022-5-8',
eqCT: 0.11,
eqTT: 0.23,
lineCT: 0.45,
lineTT: 0.21
}
]
}
]
}
]
export default {
name: 'ProductPool',
components: { TopTitle, BaseTable, HeadForm, LineChart },
filters: {
statusFilter(status) {
const statusMap = {
published: 'success',
draft: 'info',
deleted: 'danger'
}
return statusMap[status]
}
},
data() {
return {
addOrUpdateVisible: false,
trueWidth: 240,
tableProps,
testData,
tableData: [],
list: [],
total: 0,
listLoading: false,
listQuery: {
current: 1,
size: 10
},
lineList: [],
headFormConfig: [
{
type: 'select',
label: i18n.t('module.dataAnalysis.productionLineBalance.line'),
placeholder: this.$t('module.dataAnalysis.productionLineBalance.line'),
param: 'line',
width: 300,
selectOptions: []
},
{
type: 'datePicker',
label: this.$t('module.dataAnalysis.productionLineBalance.time'),
dateType: 'daterange',
format: 'yyyy-MM-dd',
valueFormat: 'yyyy-MM-dd',
rangeSeparator: '-',
startPlaceholder: this.$t('module.dataAnalysis.productionLineBalance.startTime'),
endPlaceholder: this.$t('module.dataAnalysis.productionLineBalance.endTime'),
param: 'searchTime'
},
{
type: 'button',
btnName: 'btn.search',
name: 'search',
color: 'primary'
}
],
trueTableProps: [],
headFormValue: {},
numArr: [],
chartDataArr: [],
chartType: 0,
chartDataItem: {}
}
},
created() {
this.getLineList()
this.getList()
},
methods: {
// 获取产线列表
getLineList() {
lineList({ current: 1, size: 999 }).then(res => {
if (res.code === 0) {
this.lineList = res.data.records
Vue.set(this.headFormConfig[0], 'selectOptions', this.lineList)
}
console.log(res)
})
},
getList() {
this.numArr = []
let num = 0
const tableConfig = []
this.chartDataArr = []
const dataArr = this.testData.map((item, index) => {
let dataArr = []
if (item.data) {
this.chartDataArr = this.chartDataArr.concat(item.data)
num += item.data.length
this.numArr.push(num)
dataArr = item.data.map((z, idx) => {
const dataArr = {}
z.data.forEach(i => {
// 动态生成tableConfig
if (index === 0 && idx === 0) {
tableConfig.push({
label: i.time,
children: [
{ prop: i.time + 'eqCT', label: '设备CT' },
{ prop: i.time + 'eqTT', label: '设备TT' },
{ prop: i.time + 'lineCT', label: '产线CT' },
{ prop: i.time + 'lineTT', label: '产线TT' }
]
})
}
// 合并数据集
dataArr[i.time + 'eqCT'] = i.eqCT
dataArr[i.time + 'eqTT'] = i.eqTT
dataArr[i.time + 'lineCT'] = i.lineCT
dataArr[i.time + 'lineTT'] = i.lineTT
dataArr.process = item.process
dataArr.equipmentName = z.equipmentName
})
return dataArr
})
}
return dataArr
})
this.trueTableProps = this.tableProps.concat(tableConfig)
this.tableData = this.flatten(dataArr)
this.$nextTick(() => {
this.changeChartType(this.chartType)
})
},
changeChartType(idx) {
const chartDataItem = {
timeArr: [],
eqCT: [],
eqTT: [],
lineCT: [],
lineTT: []
}
this.chartDataArr[idx].data.forEach(item => {
chartDataItem.timeArr.push(item.time)
chartDataItem.eqCT.push(item.eqCT)
chartDataItem.eqTT.push(item.eqTT)
chartDataItem.lineCT.push(item.lineCT)
chartDataItem.lineTT.push(item.lineTT)
})
this.chartDataItem = chartDataItem
},
spanMethod({ rowIndex, columnIndex }) {
if (columnIndex === 1) {
if (rowIndex === 0) {
return [this.numArr[0], 1]
} else if (this.numArr.indexOf(rowIndex) >= 0) {
const rowNum = this.numArr[this.numArr.indexOf(rowIndex) + 1] - this.numArr[this.numArr.indexOf(rowIndex)]
return [rowNum, 1]
} else {
return [0, 0]
}
}
},
// 数组扁平
flatten(arr) {
var res = []
for (var i = 0; i < arr.length; i++) {
if (Array.isArray(arr[i])) {
res = res.concat(this.flatten(arr[i]))
} else {
res.push(arr[i])
}
}
return res
},
btnClick(val) {
this.headFormValue = val
if (this.headFormValue.btnName === 'search') {
this.getList()
}
}
}
}
</script>

View File

@@ -0,0 +1,366 @@
<!--
/*
* @Author: lb
* @Date: 2022-03-24 13:30:00
* @LastEditTime: 2022-05-10 18:38:25
* @LastEditors: gtz
* @Description: 拆分了搜索区和功能按钮区增加了toptitle
*/
-->
<template>
<div>
<div class="app-container">
<top-title />
<head-form
:form-config="headFormConfig"
@headBtnClick="btnClick"
/>
<base-table
:page="listQuery.current"
:limit="listQuery.size"
:table-config="trueTableProps.length ? trueTableProps: tableProps"
:table-data="tableData.length ? tableData : []"
:span-method="spanMethod"
:is-loading="listLoading"
:index-config="{ align: 'left', fixed: 'left' }"
/>
</div>
<div class="app-container">
<el-radio-group v-model="chartType" class="data-analysis-radio" size="mini" @change="changeChartType">
<el-radio-button v-for="(item, index) in chartDataArr" :key="index" :label="index">{{ item.equipmentName }}</el-radio-button>
</el-radio-group>
<Line-chart :chart-data="chartDataItem" width="100%" height="400px" />
</div>
</div>
</template>
<script>
import Vue from 'vue'
import i18n from '@/lang'
import TopTitle from '@/components/TopTitle'
import HeadForm from '@/components/basicData/HeadForm'
import BaseTable from '@/components/BaseTable/index-compound'
import LineChart from '@/components/Charts/LineChart'
import { lineList } from '@/api/DataAnalysis/productionLineBalance'
// import { timeFormatter } from '@/filters'
/**
* 表格表头配置项 TypeScript接口注释
* tableConfig<ConfigItem> = []
*
* Interface ConfigItem = {
* prop: string,
* label: string,
* width: string,
* align: string,
* subcomponent: function,
* filter: function
* }
*
*
*/
const tableProps = [
{
prop: 'process',
label: i18n.t('module.dataAnalysis.productionLineBalance.process'),
align: 'center',
fixed: 'left'
},
{
prop: 'equipmentName',
label: i18n.t('module.dataAnalysis.productionLineBalance.equipmentName'),
align: 'center',
fixed: 'left'
}
]
const testData = [
{
process: '清洗',
data: [
{
equipmentName: '上料清洗1',
data: [
{
time: '2022-5-6',
eqCT: 0.46,
eqTT: 0.12,
lineCT: 0.68,
lineTT: 0.25
},
{
time: '2022-5-7',
eqCT: 0.34,
eqTT: 0.25,
lineCT: 0.42,
lineTT: 0.4733
},
{
time: '2022-5-8',
eqCT: 0.01,
eqTT: 0.62,
lineCT: 0.73,
lineTT: 0.45
}
]
},
{
equipmentName: '上料清洗2',
data: [
{
time: '2022-5-6',
eqCT: 0.46,
eqTT: 0.62,
lineCT: 0.24,
lineTT: 0.70
},
{
time: '2022-5-7',
eqCT: 0.32,
eqTT: 0.58,
lineCT: 0.46,
lineTT: 0.80
},
{
time: '2022-5-8',
eqCT: 0.35,
eqTT: 0.83,
lineCT: 0.29,
lineTT: 0.90
}
]
}
]
},
{
process: '磨边',
data: [
{
equipmentName: '磨边1',
data: [
{
time: '2022-5-6',
eqCT: 0.16,
eqTT: 0.42,
lineCT: 0.85,
lineTT: 0.26
},
{
time: '2022-5-7',
eqCT: 0.31,
eqTT: 0.21,
lineCT: 0.11,
lineTT: 0.46
},
{
time: '2022-5-8',
eqCT: 0.82,
eqTT: 0.25,
lineCT: 0.09,
lineTT: 0.23
}
]
},
{
equipmentName: '磨边2',
data: [
{
time: '2022-5-6',
eqCT: 0.33,
eqTT: 0.62,
lineCT: 0.37,
lineTT: 0.22
},
{
time: '2022-5-7',
eqCT: 0.32,
eqTT: 0.24,
lineCT: 0.21,
lineTT: 0.25
},
{
time: '2022-5-8',
eqCT: 0.11,
eqTT: 0.23,
lineCT: 0.45,
lineTT: 0.21
}
]
}
]
}
]
export default {
name: 'ProductPool',
components: { TopTitle, BaseTable, HeadForm, LineChart },
filters: {
statusFilter(status) {
const statusMap = {
published: 'success',
draft: 'info',
deleted: 'danger'
}
return statusMap[status]
}
},
data() {
return {
addOrUpdateVisible: false,
trueWidth: 240,
tableProps,
testData,
tableData: [],
list: [],
total: 0,
listLoading: false,
listQuery: {
current: 1,
size: 10
},
lineList: [],
headFormConfig: [
{
type: 'select',
label: i18n.t('module.dataAnalysis.productionLineBalance.line'),
placeholder: this.$t('module.dataAnalysis.productionLineBalance.line'),
param: 'line',
width: 300,
selectOptions: []
},
{
type: 'datePicker',
label: this.$t('module.dataAnalysis.productionLineBalance.time'),
dateType: 'daterange',
format: 'yyyy-MM-dd',
valueFormat: 'yyyy-MM-dd',
rangeSeparator: '-',
startPlaceholder: this.$t('module.dataAnalysis.productionLineBalance.startTime'),
endPlaceholder: this.$t('module.dataAnalysis.productionLineBalance.endTime'),
param: 'searchTime'
},
{
type: 'button',
btnName: 'btn.search',
name: 'search',
color: 'primary'
}
],
trueTableProps: [],
headFormValue: {},
numArr: [],
chartDataArr: [],
chartType: 0,
chartDataItem: {}
}
},
created() {
this.getLineList()
this.getList()
},
methods: {
// 获取产线列表
getLineList() {
lineList({ current: 1, size: 999 }).then(res => {
if (res.code === 0) {
this.lineList = res.data.records
Vue.set(this.headFormConfig[0], 'selectOptions', this.lineList)
}
console.log(res)
})
},
getList() {
this.numArr = []
let num = 0
const tableConfig = []
this.chartDataArr = []
const dataArr = this.testData.map((item, index) => {
let dataArr = []
if (item.data) {
this.chartDataArr = this.chartDataArr.concat(item.data)
num += item.data.length
this.numArr.push(num)
dataArr = item.data.map((z, idx) => {
const dataArr = {}
z.data.forEach(i => {
// 动态生成tableConfig
if (index === 0 && idx === 0) {
tableConfig.push({
label: i.time,
children: [
{ prop: i.time + 'eqCT', label: '设备CT' },
{ prop: i.time + 'eqTT', label: '设备TT' },
{ prop: i.time + 'lineCT', label: '产线CT' },
{ prop: i.time + 'lineTT', label: '产线TT' }
]
})
}
// 合并数据集
dataArr[i.time + 'eqCT'] = i.eqCT
dataArr[i.time + 'eqTT'] = i.eqTT
dataArr[i.time + 'lineCT'] = i.lineCT
dataArr[i.time + 'lineTT'] = i.lineTT
dataArr.process = item.process
dataArr.equipmentName = z.equipmentName
})
return dataArr
})
}
return dataArr
})
this.trueTableProps = this.tableProps.concat(tableConfig)
this.tableData = this.flatten(dataArr)
this.$nextTick(() => {
this.changeChartType(this.chartType)
})
},
changeChartType(idx) {
const chartDataItem = {
timeArr: [],
eqCT: [],
eqTT: [],
lineCT: [],
lineTT: []
}
this.chartDataArr[idx].data.forEach(item => {
chartDataItem.timeArr.push(item.time)
chartDataItem.eqCT.push(item.eqCT)
chartDataItem.eqTT.push(item.eqTT)
chartDataItem.lineCT.push(item.lineCT)
chartDataItem.lineTT.push(item.lineTT)
})
this.chartDataItem = chartDataItem
},
spanMethod({ rowIndex, columnIndex }) {
if (columnIndex === 1) {
if (rowIndex === 0) {
return [this.numArr[0], 1]
} else if (this.numArr.indexOf(rowIndex) >= 0) {
const rowNum = this.numArr[this.numArr.indexOf(rowIndex) + 1] - this.numArr[this.numArr.indexOf(rowIndex)]
return [rowNum, 1]
} else {
return [0, 0]
}
}
},
// 数组扁平
flatten(arr) {
var res = []
for (var i = 0; i < arr.length; i++) {
if (Array.isArray(arr[i])) {
res = res.concat(this.flatten(arr[i]))
} else {
res.push(arr[i])
}
}
return res
},
btnClick(val) {
this.headFormValue = val
if (this.headFormValue.btnName === 'search') {
this.getList()
}
}
}
}
</script>

View File

@@ -0,0 +1,366 @@
<!--
/*
* @Author: lb
* @Date: 2022-03-24 13:30:00
* @LastEditTime: 2022-05-10 18:38:26
* @LastEditors: gtz
* @Description: 拆分了搜索区和功能按钮区增加了toptitle
*/
-->
<template>
<div>
<div class="app-container">
<top-title />
<head-form
:form-config="headFormConfig"
@headBtnClick="btnClick"
/>
<base-table
:page="listQuery.current"
:limit="listQuery.size"
:table-config="trueTableProps.length ? trueTableProps: tableProps"
:table-data="tableData.length ? tableData : []"
:span-method="spanMethod"
:is-loading="listLoading"
:index-config="{ align: 'left', fixed: 'left' }"
/>
</div>
<div class="app-container">
<el-radio-group v-model="chartType" class="data-analysis-radio" size="mini" @change="changeChartType">
<el-radio-button v-for="(item, index) in chartDataArr" :key="index" :label="index">{{ item.equipmentName }}</el-radio-button>
</el-radio-group>
<Line-chart :chart-data="chartDataItem" width="100%" height="400px" />
</div>
</div>
</template>
<script>
import Vue from 'vue'
import i18n from '@/lang'
import TopTitle from '@/components/TopTitle'
import HeadForm from '@/components/basicData/HeadForm'
import BaseTable from '@/components/BaseTable/index-compound'
import LineChart from '@/components/Charts/LineChart'
import { lineList } from '@/api/DataAnalysis/productionLineBalance'
// import { timeFormatter } from '@/filters'
/**
* 表格表头配置项 TypeScript接口注释
* tableConfig<ConfigItem> = []
*
* Interface ConfigItem = {
* prop: string,
* label: string,
* width: string,
* align: string,
* subcomponent: function,
* filter: function
* }
*
*
*/
const tableProps = [
{
prop: 'process',
label: i18n.t('module.dataAnalysis.productionLineBalance.process'),
align: 'center',
fixed: 'left'
},
{
prop: 'equipmentName',
label: i18n.t('module.dataAnalysis.productionLineBalance.equipmentName'),
align: 'center',
fixed: 'left'
}
]
const testData = [
{
process: '清洗',
data: [
{
equipmentName: '上料清洗1',
data: [
{
time: '2022-5-6',
eqCT: 0.46,
eqTT: 0.12,
lineCT: 0.68,
lineTT: 0.25
},
{
time: '2022-5-7',
eqCT: 0.34,
eqTT: 0.25,
lineCT: 0.42,
lineTT: 0.4733
},
{
time: '2022-5-8',
eqCT: 0.01,
eqTT: 0.62,
lineCT: 0.73,
lineTT: 0.45
}
]
},
{
equipmentName: '上料清洗2',
data: [
{
time: '2022-5-6',
eqCT: 0.46,
eqTT: 0.62,
lineCT: 0.24,
lineTT: 0.70
},
{
time: '2022-5-7',
eqCT: 0.32,
eqTT: 0.58,
lineCT: 0.46,
lineTT: 0.80
},
{
time: '2022-5-8',
eqCT: 0.35,
eqTT: 0.83,
lineCT: 0.29,
lineTT: 0.90
}
]
}
]
},
{
process: '磨边',
data: [
{
equipmentName: '磨边1',
data: [
{
time: '2022-5-6',
eqCT: 0.16,
eqTT: 0.42,
lineCT: 0.85,
lineTT: 0.26
},
{
time: '2022-5-7',
eqCT: 0.31,
eqTT: 0.21,
lineCT: 0.11,
lineTT: 0.46
},
{
time: '2022-5-8',
eqCT: 0.82,
eqTT: 0.25,
lineCT: 0.09,
lineTT: 0.23
}
]
},
{
equipmentName: '磨边2',
data: [
{
time: '2022-5-6',
eqCT: 0.33,
eqTT: 0.62,
lineCT: 0.37,
lineTT: 0.22
},
{
time: '2022-5-7',
eqCT: 0.32,
eqTT: 0.24,
lineCT: 0.21,
lineTT: 0.25
},
{
time: '2022-5-8',
eqCT: 0.11,
eqTT: 0.23,
lineCT: 0.45,
lineTT: 0.21
}
]
}
]
}
]
export default {
name: 'ProductPool',
components: { TopTitle, BaseTable, HeadForm, LineChart },
filters: {
statusFilter(status) {
const statusMap = {
published: 'success',
draft: 'info',
deleted: 'danger'
}
return statusMap[status]
}
},
data() {
return {
addOrUpdateVisible: false,
trueWidth: 240,
tableProps,
testData,
tableData: [],
list: [],
total: 0,
listLoading: false,
listQuery: {
current: 1,
size: 10
},
lineList: [],
headFormConfig: [
{
type: 'select',
label: i18n.t('module.dataAnalysis.productionLineBalance.line'),
placeholder: this.$t('module.dataAnalysis.productionLineBalance.line'),
param: 'line',
width: 300,
selectOptions: []
},
{
type: 'datePicker',
label: this.$t('module.dataAnalysis.productionLineBalance.time'),
dateType: 'daterange',
format: 'yyyy-MM-dd',
valueFormat: 'yyyy-MM-dd',
rangeSeparator: '-',
startPlaceholder: this.$t('module.dataAnalysis.productionLineBalance.startTime'),
endPlaceholder: this.$t('module.dataAnalysis.productionLineBalance.endTime'),
param: 'searchTime'
},
{
type: 'button',
btnName: 'btn.search',
name: 'search',
color: 'primary'
}
],
trueTableProps: [],
headFormValue: {},
numArr: [],
chartDataArr: [],
chartType: 0,
chartDataItem: {}
}
},
created() {
this.getLineList()
this.getList()
},
methods: {
// 获取产线列表
getLineList() {
lineList({ current: 1, size: 999 }).then(res => {
if (res.code === 0) {
this.lineList = res.data.records
Vue.set(this.headFormConfig[0], 'selectOptions', this.lineList)
}
console.log(res)
})
},
getList() {
this.numArr = []
let num = 0
const tableConfig = []
this.chartDataArr = []
const dataArr = this.testData.map((item, index) => {
let dataArr = []
if (item.data) {
this.chartDataArr = this.chartDataArr.concat(item.data)
num += item.data.length
this.numArr.push(num)
dataArr = item.data.map((z, idx) => {
const dataArr = {}
z.data.forEach(i => {
// 动态生成tableConfig
if (index === 0 && idx === 0) {
tableConfig.push({
label: i.time,
children: [
{ prop: i.time + 'eqCT', label: '设备CT' },
{ prop: i.time + 'eqTT', label: '设备TT' },
{ prop: i.time + 'lineCT', label: '产线CT' },
{ prop: i.time + 'lineTT', label: '产线TT' }
]
})
}
// 合并数据集
dataArr[i.time + 'eqCT'] = i.eqCT
dataArr[i.time + 'eqTT'] = i.eqTT
dataArr[i.time + 'lineCT'] = i.lineCT
dataArr[i.time + 'lineTT'] = i.lineTT
dataArr.process = item.process
dataArr.equipmentName = z.equipmentName
})
return dataArr
})
}
return dataArr
})
this.trueTableProps = this.tableProps.concat(tableConfig)
this.tableData = this.flatten(dataArr)
this.$nextTick(() => {
this.changeChartType(this.chartType)
})
},
changeChartType(idx) {
const chartDataItem = {
timeArr: [],
eqCT: [],
eqTT: [],
lineCT: [],
lineTT: []
}
this.chartDataArr[idx].data.forEach(item => {
chartDataItem.timeArr.push(item.time)
chartDataItem.eqCT.push(item.eqCT)
chartDataItem.eqTT.push(item.eqTT)
chartDataItem.lineCT.push(item.lineCT)
chartDataItem.lineTT.push(item.lineTT)
})
this.chartDataItem = chartDataItem
},
spanMethod({ rowIndex, columnIndex }) {
if (columnIndex === 1) {
if (rowIndex === 0) {
return [this.numArr[0], 1]
} else if (this.numArr.indexOf(rowIndex) >= 0) {
const rowNum = this.numArr[this.numArr.indexOf(rowIndex) + 1] - this.numArr[this.numArr.indexOf(rowIndex)]
return [rowNum, 1]
} else {
return [0, 0]
}
}
},
// 数组扁平
flatten(arr) {
var res = []
for (var i = 0; i < arr.length; i++) {
if (Array.isArray(arr[i])) {
res = res.concat(this.flatten(arr[i]))
} else {
res.push(arr[i])
}
}
return res
},
btnClick(val) {
this.headFormValue = val
if (this.headFormValue.btnName === 'search') {
this.getList()
}
}
}
}
</script>

View File

@@ -0,0 +1,366 @@
<!--
/*
* @Author: lb
* @Date: 2022-03-24 13:30:00
* @LastEditTime: 2022-06-02 11:25:37
* @LastEditors: gtz
* @Description: 拆分了搜索区和功能按钮区增加了toptitle
*/
-->
<template>
<div>
<div class="app-container">
<top-title />
<head-form
:form-config="headFormConfig"
@headBtnClick="btnClick"
/>
<base-table
:page="listQuery.current"
:limit="listQuery.size"
:table-config="trueTableProps.length ? trueTableProps: tableProps"
:table-data="tableData.length ? tableData : []"
:span-method="spanMethod"
:is-loading="listLoading"
:index-config="{ align: 'left', fixed: 'left' }"
/>
</div>
<div class="app-container">
<el-radio-group v-model="chartType" class="data-analysis-radio" size="mini" @change="changeChartType">
<el-radio-button v-for="(item, index) in chartDataArr" :key="index" :label="index">{{ item.equipmentName }}</el-radio-button>
</el-radio-group>
<Line-chart :chart-data="chartDataItem" width="100%" height="400px" />
</div>
</div>
</template>
<script>
import Vue from 'vue'
import i18n from '@/lang'
import TopTitle from '@/components/TopTitle'
import HeadForm from '@/components/basicData/HeadForm'
import BaseTable from '@/components/BaseTable/index-compound'
import LineChart from './components/LineChartBalance'
import { lineList } from '@/api/DataAnalysis/productionLineBalance'
// import { timeFormatter } from '@/filters'
/**
* 表格表头配置项 TypeScript接口注释
* tableConfig<ConfigItem> = []
*
* Interface ConfigItem = {
* prop: string,
* label: string,
* width: string,
* align: string,
* subcomponent: function,
* filter: function
* }
*
*
*/
const tableProps = [
{
prop: 'process',
label: i18n.t('module.dataAnalysis.productionLineBalance.process'),
align: 'center',
fixed: 'left'
},
{
prop: 'equipmentName',
label: i18n.t('module.dataAnalysis.productionLineBalance.equipmentName'),
align: 'center',
fixed: 'left'
}
]
const testData = [
{
process: '清洗',
data: [
{
equipmentName: '上料清洗1',
data: [
{
time: '2022-5-6',
eqCT: 0.46,
eqTT: 0.12,
lineCT: 0.68,
lineTT: 0.25
},
{
time: '2022-5-7',
eqCT: 0.34,
eqTT: 0.25,
lineCT: 0.42,
lineTT: 0.4733
},
{
time: '2022-5-8',
eqCT: 0.01,
eqTT: 0.62,
lineCT: 0.73,
lineTT: 0.45
}
]
},
{
equipmentName: '上料清洗2',
data: [
{
time: '2022-5-6',
eqCT: 0.46,
eqTT: 0.62,
lineCT: 0.24,
lineTT: 0.70
},
{
time: '2022-5-7',
eqCT: 0.32,
eqTT: 0.58,
lineCT: 0.46,
lineTT: 0.80
},
{
time: '2022-5-8',
eqCT: 0.35,
eqTT: 0.83,
lineCT: 0.29,
lineTT: 0.90
}
]
}
]
},
{
process: '磨边',
data: [
{
equipmentName: '磨边1',
data: [
{
time: '2022-5-6',
eqCT: 0.16,
eqTT: 0.42,
lineCT: 0.85,
lineTT: 0.26
},
{
time: '2022-5-7',
eqCT: 0.31,
eqTT: 0.21,
lineCT: 0.11,
lineTT: 0.46
},
{
time: '2022-5-8',
eqCT: 0.82,
eqTT: 0.25,
lineCT: 0.09,
lineTT: 0.23
}
]
},
{
equipmentName: '磨边2',
data: [
{
time: '2022-5-6',
eqCT: 0.33,
eqTT: 0.62,
lineCT: 0.37,
lineTT: 0.22
},
{
time: '2022-5-7',
eqCT: 0.32,
eqTT: 0.24,
lineCT: 0.21,
lineTT: 0.25
},
{
time: '2022-5-8',
eqCT: 0.11,
eqTT: 0.23,
lineCT: 0.45,
lineTT: 0.21
}
]
}
]
}
]
export default {
name: 'ProductPool',
components: { TopTitle, BaseTable, HeadForm, LineChart },
filters: {
statusFilter(status) {
const statusMap = {
published: 'success',
draft: 'info',
deleted: 'danger'
}
return statusMap[status]
}
},
data() {
return {
addOrUpdateVisible: false,
trueWidth: 240,
tableProps,
testData,
tableData: [],
list: [],
total: 0,
listLoading: false,
listQuery: {
current: 1,
size: 10
},
lineList: [],
headFormConfig: [
{
type: 'select',
label: i18n.t('module.dataAnalysis.productionLineBalance.line'),
placeholder: this.$t('module.dataAnalysis.productionLineBalance.line'),
param: 'line',
width: 300,
selectOptions: []
},
{
type: 'datePicker',
label: this.$t('module.dataAnalysis.productionLineBalance.time'),
dateType: 'daterange',
format: 'yyyy-MM-dd',
valueFormat: 'yyyy-MM-dd',
rangeSeparator: '-',
startPlaceholder: this.$t('module.dataAnalysis.productionLineBalance.startTime'),
endPlaceholder: this.$t('module.dataAnalysis.productionLineBalance.endTime'),
param: 'searchTime'
},
{
type: 'button',
btnName: 'btn.search',
name: 'search',
color: 'primary'
}
],
trueTableProps: [],
headFormValue: {},
numArr: [],
chartDataArr: [],
chartType: 0,
chartDataItem: {}
}
},
created() {
this.getLineList()
this.getList()
},
methods: {
// 获取产线列表
getLineList() {
lineList({ current: 1, size: 999 }).then(res => {
if (res.code === 0) {
this.lineList = res.data.records
Vue.set(this.headFormConfig[0], 'selectOptions', this.lineList)
}
console.log(res)
})
},
getList() {
this.numArr = []
let num = 0
const tableConfig = []
this.chartDataArr = []
const dataArr = this.testData.map((item, index) => {
let dataArr = []
if (item.data) {
this.chartDataArr = this.chartDataArr.concat(item.data)
num += item.data.length
this.numArr.push(num)
dataArr = item.data.map((z, idx) => {
const dataArr = {}
z.data.forEach(i => {
// 动态生成tableConfig
if (index === 0 && idx === 0) {
tableConfig.push({
label: i.time,
children: [
{ prop: i.time + 'eqCT', label: '设备CT' },
{ prop: i.time + 'eqTT', label: '设备TT' },
{ prop: i.time + 'lineCT', label: '产线CT' },
{ prop: i.time + 'lineTT', label: '产线TT' }
]
})
}
// 合并数据集
dataArr[i.time + 'eqCT'] = i.eqCT
dataArr[i.time + 'eqTT'] = i.eqTT
dataArr[i.time + 'lineCT'] = i.lineCT
dataArr[i.time + 'lineTT'] = i.lineTT
dataArr.process = item.process
dataArr.equipmentName = z.equipmentName
})
return dataArr
})
}
return dataArr
})
this.trueTableProps = this.tableProps.concat(tableConfig)
this.tableData = this.flatten(dataArr)
this.$nextTick(() => {
this.changeChartType(this.chartType)
})
},
changeChartType(idx) {
const chartDataItem = {
timeArr: [],
eqCT: [],
eqTT: [],
lineCT: [],
lineTT: []
}
this.chartDataArr[idx].data.forEach(item => {
chartDataItem.timeArr.push(item.time)
chartDataItem.eqCT.push(item.eqCT)
chartDataItem.eqTT.push(item.eqTT)
chartDataItem.lineCT.push(item.lineCT)
chartDataItem.lineTT.push(item.lineTT)
})
this.chartDataItem = chartDataItem
},
spanMethod({ rowIndex, columnIndex }) {
if (columnIndex === 1) {
if (rowIndex === 0) {
return [this.numArr[0], 1]
} else if (this.numArr.indexOf(rowIndex) >= 0) {
const rowNum = this.numArr[this.numArr.indexOf(rowIndex) + 1] - this.numArr[this.numArr.indexOf(rowIndex)]
return [rowNum, 1]
} else {
return [0, 0]
}
}
},
// 数组扁平
flatten(arr) {
var res = []
for (var i = 0; i < arr.length; i++) {
if (Array.isArray(arr[i])) {
res = res.concat(this.flatten(arr[i]))
} else {
res.push(arr[i])
}
}
return res
},
btnClick(val) {
this.headFormValue = val
if (this.headFormValue.btnName === 'search') {
this.getList()
}
}
}
}
</script>

View File

@@ -0,0 +1,366 @@
<!--
/*
* @Author: lb
* @Date: 2022-03-24 13:30:00
* @LastEditTime: 2022-05-10 18:38:28
* @LastEditors: gtz
* @Description: 拆分了搜索区和功能按钮区增加了toptitle
*/
-->
<template>
<div>
<div class="app-container">
<top-title />
<head-form
:form-config="headFormConfig"
@headBtnClick="btnClick"
/>
<base-table
:page="listQuery.current"
:limit="listQuery.size"
:table-config="trueTableProps.length ? trueTableProps: tableProps"
:table-data="tableData.length ? tableData : []"
:span-method="spanMethod"
:is-loading="listLoading"
:index-config="{ align: 'left', fixed: 'left' }"
/>
</div>
<div class="app-container">
<el-radio-group v-model="chartType" class="data-analysis-radio" size="mini" @change="changeChartType">
<el-radio-button v-for="(item, index) in chartDataArr" :key="index" :label="index">{{ item.equipmentName }}</el-radio-button>
</el-radio-group>
<Line-chart :chart-data="chartDataItem" width="100%" height="400px" />
</div>
</div>
</template>
<script>
import Vue from 'vue'
import i18n from '@/lang'
import TopTitle from '@/components/TopTitle'
import HeadForm from '@/components/basicData/HeadForm'
import BaseTable from '@/components/BaseTable/index-compound'
import LineChart from '@/components/Charts/LineChart'
import { lineList } from '@/api/DataAnalysis/productionLineBalance'
// import { timeFormatter } from '@/filters'
/**
* 表格表头配置项 TypeScript接口注释
* tableConfig<ConfigItem> = []
*
* Interface ConfigItem = {
* prop: string,
* label: string,
* width: string,
* align: string,
* subcomponent: function,
* filter: function
* }
*
*
*/
const tableProps = [
{
prop: 'process',
label: i18n.t('module.dataAnalysis.productionLineBalance.process'),
align: 'center',
fixed: 'left'
},
{
prop: 'equipmentName',
label: i18n.t('module.dataAnalysis.productionLineBalance.equipmentName'),
align: 'center',
fixed: 'left'
}
]
const testData = [
{
process: '清洗',
data: [
{
equipmentName: '上料清洗1',
data: [
{
time: '2022-5-6',
eqCT: 0.46,
eqTT: 0.12,
lineCT: 0.68,
lineTT: 0.25
},
{
time: '2022-5-7',
eqCT: 0.34,
eqTT: 0.25,
lineCT: 0.42,
lineTT: 0.4733
},
{
time: '2022-5-8',
eqCT: 0.01,
eqTT: 0.62,
lineCT: 0.73,
lineTT: 0.45
}
]
},
{
equipmentName: '上料清洗2',
data: [
{
time: '2022-5-6',
eqCT: 0.46,
eqTT: 0.62,
lineCT: 0.24,
lineTT: 0.70
},
{
time: '2022-5-7',
eqCT: 0.32,
eqTT: 0.58,
lineCT: 0.46,
lineTT: 0.80
},
{
time: '2022-5-8',
eqCT: 0.35,
eqTT: 0.83,
lineCT: 0.29,
lineTT: 0.90
}
]
}
]
},
{
process: '磨边',
data: [
{
equipmentName: '磨边1',
data: [
{
time: '2022-5-6',
eqCT: 0.16,
eqTT: 0.42,
lineCT: 0.85,
lineTT: 0.26
},
{
time: '2022-5-7',
eqCT: 0.31,
eqTT: 0.21,
lineCT: 0.11,
lineTT: 0.46
},
{
time: '2022-5-8',
eqCT: 0.82,
eqTT: 0.25,
lineCT: 0.09,
lineTT: 0.23
}
]
},
{
equipmentName: '磨边2',
data: [
{
time: '2022-5-6',
eqCT: 0.33,
eqTT: 0.62,
lineCT: 0.37,
lineTT: 0.22
},
{
time: '2022-5-7',
eqCT: 0.32,
eqTT: 0.24,
lineCT: 0.21,
lineTT: 0.25
},
{
time: '2022-5-8',
eqCT: 0.11,
eqTT: 0.23,
lineCT: 0.45,
lineTT: 0.21
}
]
}
]
}
]
export default {
name: 'ProductPool',
components: { TopTitle, BaseTable, HeadForm, LineChart },
filters: {
statusFilter(status) {
const statusMap = {
published: 'success',
draft: 'info',
deleted: 'danger'
}
return statusMap[status]
}
},
data() {
return {
addOrUpdateVisible: false,
trueWidth: 240,
tableProps,
testData,
tableData: [],
list: [],
total: 0,
listLoading: false,
listQuery: {
current: 1,
size: 10
},
lineList: [],
headFormConfig: [
{
type: 'select',
label: i18n.t('module.dataAnalysis.productionLineBalance.line'),
placeholder: this.$t('module.dataAnalysis.productionLineBalance.line'),
param: 'line',
width: 300,
selectOptions: []
},
{
type: 'datePicker',
label: this.$t('module.dataAnalysis.productionLineBalance.time'),
dateType: 'daterange',
format: 'yyyy-MM-dd',
valueFormat: 'yyyy-MM-dd',
rangeSeparator: '-',
startPlaceholder: this.$t('module.dataAnalysis.productionLineBalance.startTime'),
endPlaceholder: this.$t('module.dataAnalysis.productionLineBalance.endTime'),
param: 'searchTime'
},
{
type: 'button',
btnName: 'btn.search',
name: 'search',
color: 'primary'
}
],
trueTableProps: [],
headFormValue: {},
numArr: [],
chartDataArr: [],
chartType: 0,
chartDataItem: {}
}
},
created() {
this.getLineList()
this.getList()
},
methods: {
// 获取产线列表
getLineList() {
lineList({ current: 1, size: 999 }).then(res => {
if (res.code === 0) {
this.lineList = res.data.records
Vue.set(this.headFormConfig[0], 'selectOptions', this.lineList)
}
console.log(res)
})
},
getList() {
this.numArr = []
let num = 0
const tableConfig = []
this.chartDataArr = []
const dataArr = this.testData.map((item, index) => {
let dataArr = []
if (item.data) {
this.chartDataArr = this.chartDataArr.concat(item.data)
num += item.data.length
this.numArr.push(num)
dataArr = item.data.map((z, idx) => {
const dataArr = {}
z.data.forEach(i => {
// 动态生成tableConfig
if (index === 0 && idx === 0) {
tableConfig.push({
label: i.time,
children: [
{ prop: i.time + 'eqCT', label: '设备CT' },
{ prop: i.time + 'eqTT', label: '设备TT' },
{ prop: i.time + 'lineCT', label: '产线CT' },
{ prop: i.time + 'lineTT', label: '产线TT' }
]
})
}
// 合并数据集
dataArr[i.time + 'eqCT'] = i.eqCT
dataArr[i.time + 'eqTT'] = i.eqTT
dataArr[i.time + 'lineCT'] = i.lineCT
dataArr[i.time + 'lineTT'] = i.lineTT
dataArr.process = item.process
dataArr.equipmentName = z.equipmentName
})
return dataArr
})
}
return dataArr
})
this.trueTableProps = this.tableProps.concat(tableConfig)
this.tableData = this.flatten(dataArr)
this.$nextTick(() => {
this.changeChartType(this.chartType)
})
},
changeChartType(idx) {
const chartDataItem = {
timeArr: [],
eqCT: [],
eqTT: [],
lineCT: [],
lineTT: []
}
this.chartDataArr[idx].data.forEach(item => {
chartDataItem.timeArr.push(item.time)
chartDataItem.eqCT.push(item.eqCT)
chartDataItem.eqTT.push(item.eqTT)
chartDataItem.lineCT.push(item.lineCT)
chartDataItem.lineTT.push(item.lineTT)
})
this.chartDataItem = chartDataItem
},
spanMethod({ rowIndex, columnIndex }) {
if (columnIndex === 1) {
if (rowIndex === 0) {
return [this.numArr[0], 1]
} else if (this.numArr.indexOf(rowIndex) >= 0) {
const rowNum = this.numArr[this.numArr.indexOf(rowIndex) + 1] - this.numArr[this.numArr.indexOf(rowIndex)]
return [rowNum, 1]
} else {
return [0, 0]
}
}
},
// 数组扁平
flatten(arr) {
var res = []
for (var i = 0; i < arr.length; i++) {
if (Array.isArray(arr[i])) {
res = res.concat(this.flatten(arr[i]))
} else {
res.push(arr[i])
}
}
return res
},
btnClick(val) {
this.headFormValue = val
if (this.headFormValue.btnName === 'search') {
this.getList()
}
}
}
}
</script>

View File

@@ -0,0 +1,85 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="760px" height="448px" viewBox="0 0 760 448" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>编组 2</title>
<defs>
<polygon id="path-1" points="0 -4.27662013e-14 214.404053 -4.27662013e-14 214.404053 48.1504621 0 48.1504621"></polygon>
<path d="M5.57956265,12.1973234 C8.60838355,20.9628083 13.7399658,25.3455507 20.9743095,25.3455507 C28.443568,25.3455507 33.5047058,20.6735527 36.1577231,11.3295567 C36.2182356,9.32201038 35.2169365,8.27845018 33.153826,8.19887614 C31.4022231,8.19887614 30.4009241,9.24243634 30.1499289,11.3295567 C28.1501922,17.3091917 25.0083979,20.2990091 20.724546,20.2990091 C16.440694,20.2990091 13.2602339,17.3091917 11.1831657,11.3295567 C11.0144939,10.9094545 10.8237671,10.3893545 10.6109852,9.76925682 C10.2918123,8.83911031 9.40335273,8.18294318 8.36627677,8.19887614 C6.90412214,8.19887614 5.84652771,8.82131661 5.5309207,10.0967548 C5.34596416,10.8442054 5.4812103,11.9126892 5.57956265,12.1973234 Z" id="path-3"></path>
<filter x="-39.1%" y="-70.0%" width="178.1%" height="240.0%" filterUnits="objectBoundingBox" id="filter-4">
<feOffset dx="0" dy="0" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
<feGaussianBlur stdDeviation="4" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
<feColorMatrix values="0 0 0 0 0.673666159 0 0 0 0 1 0 0 0 0 0.984382187 0 0 0 0.91873361 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
</filter>
<polygon id="path-5" points="0 -4.27662013e-14 214.404053 -4.27662013e-14 214.404053 48.1504621 0 48.1504621"></polygon>
<path d="M5.57956265,12.1973234 C8.60838355,20.9628083 13.7399658,25.3455507 20.9743095,25.3455507 C28.443568,25.3455507 33.5047058,20.6735527 36.1577231,11.3295567 C36.2182356,9.32201038 35.2169365,8.27845018 33.153826,8.19887614 C31.4022231,8.19887614 30.4009241,9.24243634 30.1499289,11.3295567 C28.1501922,17.3091917 25.0083979,20.2990091 20.724546,20.2990091 C16.440694,20.2990091 13.2602339,17.3091917 11.1831657,11.3295567 C11.0144939,10.9094545 10.8237671,10.3893545 10.6109852,9.76925682 C10.2918123,8.83911031 9.40335273,8.18294318 8.36627677,8.19887614 C6.90412214,8.19887614 5.84652771,8.82131661 5.5309207,10.0967548 C5.34596416,10.8442054 5.4812103,11.9126892 5.57956265,12.1973234 Z" id="path-7"></path>
<filter x="-39.1%" y="-70.0%" width="178.1%" height="240.0%" filterUnits="objectBoundingBox" id="filter-8">
<feOffset dx="0" dy="0" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
<feGaussianBlur stdDeviation="4" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
<feColorMatrix values="0 0 0 0 0.673666159 0 0 0 0 1 0 0 0 0 0.984382187 0 0 0 0.91873361 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
</filter>
</defs>
<g id="2MES。2-6蓝底-7、8白底" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="2-8数据分析" transform="translate(-360.000000, -136.000000)">
<g id="编组-2" transform="translate(360.000000, 136.000000)">
<rect id="矩形" fill="#FFFFFF" x="0" y="0" width="760" height="448" rx="16"></rect>
<g id="编组" transform="translate(201.000000, 97.000000)">
<g id="编组-20备份" transform="translate(47.000000, 0.000000)">
<path d="M0,351 C53.8507958,350.926647 89.0431188,346.198793 105.576969,336.816439 C156.368998,307.993824 200.936366,260.178098 241.85251,260.178098 C333.19458,260.178098 289.51308,202.776137 359.015543,206.778947 C428.518007,210.781758 441.673051,219.253462 470.376726,215.91769 C489.512509,213.693843 503.386934,204.72128 512,189 L512,335 C512,343.836556 504.836556,351 496,351 L0,351 L0,351 Z" id="路径-2" fill="#3E8EF7" opacity="0.065419"></path>
<path d="M458,0 C480.643675,0 499,18.3563253 499,41 C499,63.6436747 480.643675,82 458,82 C435.356325,82 417,63.6436747 417,41 C417,18.3563253 435.356325,0 458,0 Z M458.5,19 C445.521308,19 435,28.8497355 435,41 C435,53.1502645 445.521308,63 458.5,63 C471.478692,63 482,53.1502645 482,41 C482,28.8497355 471.478692,19 458.5,19 Z" id="形状结合备份-4" fill="#3E8EF7" opacity="0.045419"></path>
<path d="M346.5,12 C358.926407,12 369,22.0735931 369,34.5 C369,46.9264069 358.926407,57 346.5,57 C334.073593,57 324,46.9264069 324,34.5 C324,22.0735931 334.073593,12 346.5,12 Z M346.5,22 C339.596441,22 334,27.5964406 334,34.5 C334,41.4035594 339.596441,47 346.5,47 C353.403559,47 359,41.4035594 359,34.5 C359,27.5964406 353.403559,22 346.5,22 Z" id="形状结合备份-5" fill="#3E8EF7" opacity="0.065419"></path>
<path d="M80,196 C89.3888407,196 97,203.611159 97,213 C97,222.388841 89.3888407,230 80,230 C70.6111593,230 63,222.388841 63,213 C63,203.611159 70.6111593,196 80,196 Z M80.5,204 C75.2532949,204 71,208.253295 71,213.5 C71,218.746705 75.2532949,223 80.5,223 C85.7467051,223 90,218.746705 90,213.5 C90,208.253295 85.7467051,204 80.5,204 Z" id="形状结合备份-6" fill="#3E8EF7" opacity="0.065419"></path>
<g id="编组-10" transform="translate(149.807335, 86.694209)">
<g id="编组-5">
<path d="M206.834478,-4.97379915e-14 C210.148186,-4.97379915e-14 212.834478,2.6862915 212.834478,6 L212.834478,8.45712477 C212.834478,11.7708333 210.148186,14.4571248 206.834478,14.4571248 L189.874367,14.4579525 L189.874,23.901 L207.506978,23.9015679 C228.493798,23.9015679 245.506978,40.9147474 245.506978,61.9015679 L245.506,73.445 L252.734713,73.4458001 L252.73554,60.9298001 C252.73554,57.6160916 255.421832,54.9298001 258.73554,54.9298001 L261.192665,54.9298001 C264.506374,54.9298001 267.192665,57.6160916 267.192665,60.9298001 L267.192665,100.463808 C267.192665,103.777517 264.506374,106.463808 261.192665,106.463808 L258.73554,106.463808 C255.421832,106.463808 252.73554,103.777517 252.73554,100.463808 L252.734713,87.9468001 L245.506,87.946 L245.506978,104.325677 C245.506978,125.312498 228.493798,142.325677 207.506978,142.325677 L203.25,142.325 L214.853517,163.320944 C215.794899,165.024386 215.820634,166.987051 215.093414,168.641558 L223.845093,168.641358 C227.158801,168.641358 229.845093,171.327649 229.845093,174.641358 L229.845093,177.142269 C229.845093,180.455978 227.158801,183.142269 223.845093,183.142269 L52.7215124,183.142269 C49.4078039,183.142269 46.7215124,180.455978 46.7215124,177.142269 L46.7215124,174.641358 C46.7215124,171.327649 49.4078039,168.641358 52.7215124,168.641358 L64.1098327,168.64121 C64.0682145,167.739882 64.2300318,166.81545 64.6209497,165.934775 L75.1,142.325 L69.0596272,142.325677 C48.0728067,142.325677 31.0596272,125.312498 31.0596272,104.325677 L31.059,102.595 L13.7079359,102.596256 C11.1497208,103.127674 8.47545775,101.929543 7.20422433,99.554504 L7.08920299,99.328413 L0.598378697,85.8858686 L0.530618722,85.7406136 C-0.830028497,82.7191399 0.516337362,79.166729 3.53781104,77.8060818 L3.53781104,77.8060818 L5.69478619,76.8347405 C8.6593408,75.4997254 12.147832,76.7688411 13.561558,79.6966778 L13.561558,79.6966778 L17.832,88.5417994 L31.059,88.54 L31.0596272,61.9015679 C31.0596272,40.9147474 48.0728067,23.9015679 69.0596272,23.9015679 L175.373,23.901 L175.373367,14.4579525 L94.6843675,14.4571248 C91.370659,14.4571248 88.6843675,11.7708333 88.6843675,8.45712477 L88.6843675,6 C88.6843675,2.6862915 91.370659,-7.81597009e-14 94.6843675,-7.81597009e-14 L206.834478,-4.97379915e-14 Z M201.264,168.641 L186.721,142.325 L90.926,142.325 L79.245,168.641 L201.264,168.641 Z" id="形状结合" fill="#FFFFFF"></path>
<g id="矩形" transform="translate(30.649063, 94.175215)">
<mask id="mask-2" fill="white">
<use xlink:href="#path-1"></use>
</mask>
<g id="蒙版" transform="translate(107.202027, 24.075231) scale(1, -1) translate(-107.202027, -24.075231) "></g>
<path d="M38.410564,-70.2736474 L176.857915,-70.2736474 C197.844735,-70.2736474 214.857915,-53.2604679 214.857915,-32.2736474 L214.857915,10.1504621 C214.857915,31.1372826 197.844735,48.1504621 176.857915,48.1504621 L38.410564,48.1504621 C17.4237435,48.1504621 0.410564037,31.1372826 0.410564037,10.1504621 L0.410564037,-32.2736474 C0.410564037,-53.2604679 17.4237435,-70.2736474 38.410564,-70.2736474 Z" fill="#B6D5FF" mask="url(#mask-2)"></path>
</g>
<g id="编组-7" transform="translate(42.752700, 40.298752)">
<path d="M20.9743095,0 C32.5581008,-2.12790794e-15 41.9486191,9.39051824 41.9486191,20.9743095 L41.9486191,65.6965222 C41.9486191,77.2803135 32.5581008,86.6708318 20.9743095,86.6708318 C9.39051824,86.6708318 2.46555849e-13,77.2803135 2.27373675e-13,65.6965222 L2.27373675e-13,20.9743095 C2.2595507e-13,9.39051824 9.39051824,2.12790794e-15 20.9743095,0 Z" id="矩形备份-11" fill="#0B3872"></path>
<path d="M0.375965575,53.6310115 L42.3245846,53.6310115 L42.1872738,65.69788 C42.0550314,77.3193244 32.5965063,86.6708318 20.9743095,86.6708318 C9.52158217,86.6708318 0.237312245,77.3865618 0.237312245,65.9338345 C0.237312245,65.8551811 0.237759732,65.7765283 0.238654684,65.69788 L0.375965575,53.6310115 L0.375965575,53.6310115 Z" id="矩形备份-11" fill="#082D5D"></path>
<g id="路径-3" transform="translate(20.799655, 16.772071) rotate(-180.000000) translate(-20.799655, -16.772071) ">
<use fill="black" fill-opacity="1" filter="url(#filter-4)" xlink:href="#path-3"></use>
<use fill="#76E1FF" fill-rule="evenodd" xlink:href="#path-3"></use>
</g>
<ellipse id="椭圆形" fill="#0B3872" cx="108.498643" cy="10.5846541" rx="6.4088168" ry="6.44175101"></ellipse>
<rect id="矩形" fill="#0B3872" x="51.9845315" y="4.1429031" width="41.9486191" height="12.883502" rx="5"></rect>
</g>
</g>
<g id="编组-5" transform="translate(0.000000, 0.310304)">
<path d="M206.834478,-4.97379915e-14 C210.148186,-4.97379915e-14 212.834478,2.6862915 212.834478,6 L212.834478,8.45712477 C212.834478,11.7708333 210.148186,14.4571248 206.834478,14.4571248 L189.874367,14.4579525 L189.874,23.901 L207.506978,23.9015679 C228.493798,23.9015679 245.506978,40.9147474 245.506978,61.9015679 L245.506,73.445 L252.734713,73.4458001 L252.73554,60.9298001 C252.73554,57.6160916 255.421832,54.9298001 258.73554,54.9298001 L261.192665,54.9298001 C264.506374,54.9298001 267.192665,57.6160916 267.192665,60.9298001 L267.192665,100.463808 C267.192665,103.777517 264.506374,106.463808 261.192665,106.463808 L258.73554,106.463808 C255.421832,106.463808 252.73554,103.777517 252.73554,100.463808 L252.734713,87.9468001 L245.506,87.946 L245.506978,104.325677 C245.506978,125.312498 228.493798,142.325677 207.506978,142.325677 L69.0596272,142.325677 C48.0728067,142.325677 31.0596272,125.312498 31.0596272,104.325677 L31.059,102.595 L13.7079359,102.596256 C11.1497208,103.127674 8.47545775,101.929543 7.20422433,99.554504 L7.08920299,99.328413 L0.598378697,85.8858686 L0.530618722,85.7406136 C-0.830028497,82.7191399 0.516337362,79.166729 3.53781104,77.8060818 L3.53781104,77.8060818 L5.69478619,76.8347405 C8.6593408,75.4997254 12.147832,76.7688411 13.561558,79.6966778 L13.561558,79.6966778 L17.832,88.5417994 L31.059,88.54 L31.0596272,61.9015679 C31.0596272,40.9147474 48.0728067,23.9015679 69.0596272,23.9015679 L175.373,23.901 L175.373367,14.4579525 L94.6843675,14.4571248 C91.370659,14.4571248 88.6843675,11.7708333 88.6843675,8.45712477 L88.6843675,6 C88.6843675,2.6862915 91.370659,-7.81597009e-14 94.6843675,-7.81597009e-14 L206.834478,-4.97379915e-14 Z" id="形状结合" fill="#CDE3FF"></path>
<g id="矩形" transform="translate(30.649063, 105.810435)">
<mask id="mask-6" fill="white">
<use xlink:href="#path-5"></use>
</mask>
<g id="蒙版" transform="translate(107.202027, 24.075231) scale(1, -1) translate(-107.202027, -24.075231) "></g>
<path d="M38.410564,-70.2736474 L176.857915,-70.2736474 C197.844735,-70.2736474 214.857915,-53.2604679 214.857915,-32.2736474 L214.857915,10.1504621 C214.857915,31.1372826 197.844735,48.1504621 176.857915,48.1504621 L38.410564,48.1504621 C17.4237435,48.1504621 0.410564037,31.1372826 0.410564037,10.1504621 L0.410564037,-32.2736474 C0.410564037,-53.2604679 17.4237435,-70.2736474 38.410564,-70.2736474 Z" fill="#BBD8FF" mask="url(#mask-6)"></path>
</g>
<rect id="矩形备份-5" fill="#BBD8FF" x="46.7215124" y="168.338659" width="183.12358" height="14.5009114" rx="6"></rect>
<path d="M58.47837,152.011506 L78.314618,151.951194 C79.6936183,151.947002 81.0319739,152.417954 82.104466,153.284798 L89.4150721,159.193616 C91.1696507,160.611759 91.4423856,163.183758 90.0242425,164.938337 C89.2497155,165.89661 88.0840259,166.454082 86.8518823,166.455465 L58.5005631,166.487291 C55.1868567,166.49101 52.4975514,163.807736 52.4938315,160.49403 C52.4938265,160.489535 52.4938265,160.48504 52.4938316,160.480545 L52.4966164,158.004729 C52.5003328,154.700778 55.1744324,152.021551 58.47837,152.011506 Z" id="矩形备份-4" fill="#BBD8FF" transform="translate(75.435374, 159.219377) rotate(-66.000000) translate(-75.435374, -159.219377) "></path>
<path d="M187.295644,151.635686 L221.182576,151.679105 C224.490275,151.683343 227.170639,154.363702 227.174884,157.6714 L227.17805,160.138786 C227.182303,163.452492 224.499461,166.142229 221.185755,166.146482 C221.180626,166.146488 221.175497,166.146488 221.170368,166.146482 L187.283435,166.103063 C183.975737,166.098825 181.295372,163.418466 181.291127,160.110768 L181.287961,157.643381 C181.283708,154.329675 183.96655,151.639938 187.280256,151.635686 C187.285385,151.635679 187.290514,151.635679 187.295644,151.635686 Z" id="矩形备份-6" fill="#BBD8FF" transform="translate(204.233006, 158.891084) rotate(61.000000) translate(-204.233006, -158.891084) "></path>
<rect id="矩形" fill="#FFFFFF" x="30.6490632" y="102.28536" width="214.857915" height="12.7987421"></rect>
<g id="编组-7" transform="translate(42.752700, 51.933972)">
<path d="M20.9743095,0 C32.5581008,-2.12790794e-15 41.9486191,9.39051824 41.9486191,20.9743095 L41.9486191,65.6965222 C41.9486191,77.2803135 32.5581008,86.6708318 20.9743095,86.6708318 C9.39051824,86.6708318 1.74111383e-13,77.2803135 1.65587351e-13,65.6965222 L1.65587351e-13,20.9743095 C1.64168745e-13,9.39051824 9.39051824,2.12790794e-15 20.9743095,0 Z" id="矩形备份-11" fill="#0B3872"></path>
<path d="M0.372625905,53.6310115 L41.9486191,53.6310115 L41.810427,65.8841571 C41.6805273,77.4020461 32.306618,86.6708318 20.7879966,86.6708318 C9.43585545,86.6708318 0.23312677,77.4681031 0.23312677,66.115962 C0.23312677,66.0386918 0.233562482,65.9614223 0.234433886,65.8841571 L0.372625905,53.6310115 L0.372625905,53.6310115 Z" id="矩形备份-11" fill="#082D5D"></path>
<g id="路径-3" transform="translate(20.799655, 16.772071) rotate(-180.000000) translate(-20.799655, -16.772071) ">
<use fill="black" fill-opacity="1" filter="url(#filter-8)" xlink:href="#path-7"></use>
<use fill="#76E1FF" fill-rule="evenodd" xlink:href="#path-7"></use>
</g>
<ellipse id="椭圆形" fill="#0B3872" cx="108.498643" cy="10.5846541" rx="6.4088168" ry="6.44175101"></ellipse>
<rect id="矩形" fill="#0B3872" x="51.9845315" y="4.1429031" width="41.9486191" height="12.883502" rx="5"></rect>
</g>
</g>
<path d="M89.1061808,7.50438355 L212.621559,7.50438355 L212.594724,8.43235705 C212.500889,11.6771693 209.8434,14.25892 206.597231,14.25892 L189.729901,14.25892 L189.729901,14.25892 L189.729901,23.9015679 L175.321118,23.9015679 L175.321118,14.25892 L95.0868668,14.25892 C91.7731583,14.25892 89.0868668,11.5726285 89.0868668,8.25891996 C89.0868668,8.20109024 89.0877028,8.14326354 89.0893747,8.08545799 L89.1061808,7.50438355 L89.1061808,7.50438355 Z" id="矩形备份-8" fill="#BBD8FF"></path>
<path d="M226.808121,73.8163859 L278.342129,73.8163859 L278.315974,74.7116117 C278.221194,77.9557026 275.564008,80.536389 272.318533,80.536389 L259.587734,80.536389 L259.587734,80.536389 L259.587734,87.7735556 L245.104906,87.7735556 L245.104906,80.536389 L232.789646,80.536389 C229.475937,80.536389 226.789646,77.8500975 226.789646,74.536389 C226.789646,74.477972 226.790499,74.4195582 226.792205,74.3611662 L226.808121,73.8163859 L226.808121,73.8163859 Z" id="矩形备份-13" fill="#BBD8FF" transform="translate(252.476959, 80.794971) rotate(-270.000000) translate(-252.476959, -80.794971) "></path>
<path d="M30.6139215,94.6706281 L14.9632783,94.6706281 L6.09671567,77.1022162 C2.2440363,78.515948 0.317696611,80.858403 0.317696611,84.1295809 C0.300117238,84.8172674 1.38558703,87.976049 2.12193513,89.0363479 C2.61283386,89.7432138 4.27470868,93.3170744 7.10755958,99.7579297 C8.5530083,101.649753 10.7592996,102.595665 13.7264334,102.595665 C16.6935673,102.595665 22.32273,102.595665 30.6139215,102.595665 L30.6139215,94.6706281 Z" id="路径-4" fill="#BBD8FF"></path>
</g>
</g>
<path d="M559,216 C542.879783,245.699954 516.824232,260.549932 480.833347,260.549932 C406.30192,260.549932 370.458217,285.556142 317.731335,298.892227 C265.004453,312.228312 219.807926,286.195141 158.61132,296.318152 C127.731549,300.520278 99.2104465,318.913861 47.9008216,330.426433 C22.8938292,336.037364 6.92688865,342.89522 0,351 L543,351 C551.836556,351 559,343.836556 559,335 L559,216 L559,216 Z" id="路径-5" fill="#3E8EF7" opacity="0.065419"></path>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 18 KiB

View File

@@ -0,0 +1,77 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="760px" height="448px" viewBox="0 0 760 448" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>编组 2备份</title>
<defs>
<path d="M52.7664058,139.5 C54.4232601,139.5 55.7664058,140.843146 55.7664058,142.5 L55.7664058,142.5 L55.7664058,158.1 L79.0024081,158.1 L79.0024081,142.5 C79.0024081,140.843146 80.3455538,139.5 82.0024081,139.5 L82.0024081,139.5 L113.180012,139.5 C114.836866,139.5 116.180012,140.843146 116.180012,142.5 L116.180012,142.5 L116.180012,158.1 L137.96,158.1 L137.960265,158.146664 L198.317881,158.146664 L198.317,158.1 L198.476821,158.1 C201.715218,158.1 204.354393,160.665575 204.472683,163.875062 L204.476821,164.1 L204.476821,180 C204.476821,183.313708 201.79053,186 198.476821,186 L198.476821,186 L6,186 C2.6862915,186 4.05812251e-16,183.313708 0,180 L0,180 L0,164.1 C-1.29399067e-15,160.786292 2.6862915,158.1 6,158.1 L6,158.1 L18.5888019,158.1 L18.5888019,142.5 C18.5888019,140.843146 19.9319476,139.5 21.5888019,139.5 L21.5888019,139.5 Z M195.182,123.178 L195.182,144.596 L139.416,144.596 L139.416,123.178 L195.182,123.178 Z M179.18242,0 C188.018976,5.48217835e-15 195.18242,7.163444 195.18242,16 L195.18242,16 L195.182,109.629 L139.416,109.629 L139.416015,53.5 C139.416015,49.7145483 136.411231,46.6309013 132.656664,46.504059 L132.416015,46.5 L67.4136062,46.5 C63.547613,46.5 60.4136062,49.6340068 60.4136062,53.5 L60.4136062,53.5 L60.4136062,93.0027995 C60.4136062,95.5693774 58.3329837,97.6499999 55.7664058,97.6499999 L55.7664058,97.6499999 C55.7664058,105.358132 49.5245382,111.6 41.8248044,111.6 L41.8248044,111.6 L41.8248044,125.5528 C41.8248044,128.119377 39.7441818,130.2 37.1776038,130.2 C34.6110259,130.2 32.5304033,128.119377 32.5304033,125.5528 L32.5304033,125.5528 L32.5304033,111.6 L32.2190624,111.596592 C24.6631102,111.431035 18.5888019,105.254082 18.5888019,97.6583985 L18.5888019,97.6583985 L18.5888019,97.6499999 L18.3760795,97.6452178 C15.9082392,97.5340348 13.9416015,95.4980836 13.9416015,93.0027995 L13.9416015,93.0027995 L13.9416015,16 C13.9416015,7.163444 21.1050455,1.623249e-15 29.9416015,0 L29.9416015,0 Z" id="path-1"></path>
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-3">
<stop stop-color="#76E1FF" offset="0%"></stop>
<stop stop-color="#1FACFD" offset="100%"></stop>
</linearGradient>
<path d="M25.8675497,7.39072848 C25.8675497,12.8331106 20.0769014,17.2450331 12.9337748,17.2450331 C5.79064824,17.2450331 0,12.8331106 0,7.39072848 L0,7.39072848 Z" id="path-4"></path>
<filter x="-46.4%" y="-121.8%" width="192.8%" height="343.5%" filterUnits="objectBoundingBox" id="filter-5">
<feOffset dx="0" dy="0" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
<feGaussianBlur stdDeviation="4" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
<feColorMatrix values="0 0 0 0 1 0 0 0 0 0.443137255 0 0 0 0 0.443137255 0 0 0 1 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
</filter>
<rect id="path-6" x="0" y="0" width="25.8675497" height="3.69536424" rx="1.84768212"></rect>
<filter x="-46.4%" y="-324.7%" width="192.8%" height="749.5%" filterUnits="objectBoundingBox" id="filter-7">
<feOffset dx="0" dy="0" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
<feGaussianBlur stdDeviation="4" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
<feColorMatrix values="0 0 0 0 1 0 0 0 0 0.443137255 0 0 0 0 0.443137255 0 0 0 1 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
</filter>
</defs>
<g id="2MES。2-6蓝底-7、8白底" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="2-8数据分析" transform="translate(-1136.000000, -136.000000)">
<g id="编组-2备份" transform="translate(1136.000000, 136.000000)">
<rect id="矩形" fill="#FFFFFF" x="0" y="0" width="760" height="448" rx="16"></rect>
<g id="编组" transform="translate(201.000000, 97.000000)">
<path d="M559,216 C542.879783,245.699954 516.824232,260.549932 480.833347,260.549932 C406.30192,260.549932 370.458217,285.556142 317.731335,298.892227 C265.004453,312.228312 219.807926,286.195141 158.61132,296.318152 C127.731549,300.520278 99.2104465,318.913861 47.9008216,330.426433 C22.8938292,336.037364 6.92688865,342.89522 0,351 L543,351 C551.836556,351 559,343.836556 559,335 L559,216 L559,216 Z" id="路径-5" fill="#FFEFEF" opacity="0.599772135"></path>
<g id="编组-20备份" transform="translate(47.000000, 0.000000)">
<path d="M0,351 C53.8507958,350.926647 89.0431188,346.198793 105.576969,336.816439 C156.368998,307.993824 200.936366,260.178098 241.85251,260.178098 C333.19458,260.178098 289.51308,202.776137 359.015543,206.778947 C428.518007,210.781758 441.673051,219.253462 470.376726,215.91769 C489.512509,213.693843 503.386934,204.72128 512,189 L512,335 C512,343.836556 504.836556,351 496,351 L0,351 L0,351 Z" id="路径-2" fill="#FF94AE" opacity="0.065419"></path>
<g id="编组-31备份" transform="translate(182.454730, 91.979835)">
<g id="路径-9">
<mask id="mask-2" fill="white">
<use xlink:href="#path-1"></use>
</mask>
<use id="蒙版" fill="#FFEFEF" fill-rule="nonzero" xlink:href="#path-1"></use>
<g id="编组-19" mask="url(#mask-2)">
<g transform="translate(38.185430, -121.947020)">
<text id="Processing" font-family="PingFangSC-Light, PingFang SC" font-size="30" font-weight="300">
<tspan x="0" y="72.589404" fill="#161616">Processing</tspan>
</text>
<g id="编组-3" stroke-width="1" fill-rule="evenodd">
<text id="进工业炉加工" font-family="PingFangSC-Regular, PingFang SC" font-size="18" font-weight="normal" letter-spacing="2" fill="#161616">
<tspan x="39.4172185" y="20.5496689">进工业炉加工</tspan>
</text>
<g id="生产和加工情况" fill-rule="nonzero">
<rect id="矩形" fill="#000000" opacity="0" x="0" y="0" width="29.5629139" height="29.5629139"></rect>
<path d="M10.0323365,19.204346 C10.0323365,17.9658216 10.2748448,16.7648282 10.7540873,15.6331229 C11.2160079,14.5389487 11.8771316,13.5602546 12.7201366,12.7172496 C13.5631416,11.8742446 14.5418357,11.2131209 15.6360099,10.7512003 C16.7677152,10.2719578 17.9687086,10.0294495 19.207233,10.0294495 C20.4457575,10.0294495 21.6467508,10.2719578 22.7784561,10.7512003 C23.1277835,10.8984375 23.4626759,11.0658837 23.7889073,11.2535389 L23.7889073,3.63185017 C23.7889073,3.23633071 23.4684499,2.91587334 23.0729305,2.91587334 L16.2134106,2.91587334 C16.2278456,2.98227442 16.2336196,3.0486755 16.2336196,3.11796358 L16.2336196,6.96345199 C16.2336196,7.51775662 15.7832471,7.96812914 15.2289425,7.96812914 L11.4729512,7.96812914 C10.9186465,7.96812914 10.468274,7.51775662 10.468274,6.96345199 L10.468274,3.12085058 C10.468274,3.0515625 10.474048,2.98516142 10.488483,2.91876035 L3.62896316,2.91876035 C3.23344371,2.91876035 2.91298634,3.23921772 2.91298634,3.63473717 L2.91298634,23.1682016 C2.91298634,23.563721 3.23344371,23.8841784 3.62896316,23.8841784 L11.314166,23.8841784 C11.1034147,23.529077 10.9157595,23.1595406 10.7540873,22.7784561 C10.2748448,21.6438638 10.0323365,20.4428704 10.0323365,19.204346 Z M19.207233,11.7616515 C15.0961403,11.7616515 11.7645385,15.0932533 11.7645385,19.204346 C11.7645385,23.3154387 15.0961403,26.6470406 19.207233,26.6470406 C23.3183257,26.6470406 26.6499276,23.3154387 26.6499276,19.204346 C26.6499276,15.0932533 23.3183257,11.7616515 19.207233,11.7616515 Z M22.4464507,20.2321192 C21.6092198,21.0693502 20.3995654,21.3118584 19.3486962,20.959644 L17.3710989,22.9372413 C16.8485513,23.4597889 15.9968853,23.4597889 15.4743377,22.9372413 C14.9517901,22.4146937 14.9517901,21.5630277 15.4743377,21.0404801 L17.451935,19.0628829 C17.0997206,18.0120137 17.3393419,16.8023593 18.1794599,15.9651283 C19.0830919,15.0614963 20.4140004,14.850745 21.5168357,15.3299876 L19.5796565,17.2671668 L19.8943398,18.5056912 L21.1444123,18.8319226 L23.0815915,16.8947434 C23.560834,18.0004656 23.3471958,19.3313742 22.4464507,20.2321192 L22.4464507,20.2321192 Z M16.0921565,21.7160389 C16.0921565,21.9316071 16.2071607,22.1308004 16.3938483,22.2385845 C16.5805359,22.3463687 16.8105444,22.3463687 16.997232,22.2385845 C17.1839196,22.1308004 17.2989238,21.9316071 17.2989238,21.7160389 C17.2989238,21.5004707 17.1839196,21.3012774 16.997232,21.1934933 C16.8105444,21.0857091 16.5805359,21.0857091 16.3938483,21.1934933 C16.2071607,21.3012774 16.0921565,21.5004707 16.0921565,21.7160389 Z" id="形状" fill="url(#linearGradient-3)"></path>
</g>
</g>
</g>
</g>
<path d="M37.5695364,133.604033 L37.5695364,131.771161 L37.5695364,43.4632955 C37.5695364,34.6267395 44.7329804,27.4632955 53.5695364,27.4632955 L152.139073,27.4632955 C160.975629,27.4632955 168.139073,34.6267395 168.139073,43.4632955 L168.139073,151.371829 L168.139073,151.371829 L136.252536,151.371829 L136.252536,54.7942507 L67.094725,54.7942507 L67.094725,133.604033 L37.5695364,133.604033 Z" fill="#FFE0E0" mask="url(#mask-2)"></path>
<rect id="矩形" fill="#FFE0E0" mask="url(#mask-2)" x="-2.46357616" y="171.218543" width="206.940397" height="14.781457"></rect>
</g>
<g id="编组-30" transform="translate(23.403974, 89.920530)">
<g id="形状结合">
<use fill="black" fill-opacity="1" filter="url(#filter-5)" xlink:href="#path-4"></use>
<use fill="#FF7171" fill-rule="evenodd" xlink:href="#path-4"></use>
</g>
<rect id="矩形" fill="#5F0612" x="1.23178808" y="55.4304636" width="24.6357616" height="12.3178808" rx="2"></rect>
<g id="矩形备份-14">
<use fill="black" fill-opacity="1" filter="url(#filter-7)" xlink:href="#path-6"></use>
<use fill="#FF7171" fill-rule="evenodd" xlink:href="#path-6"></use>
</g>
<rect id="矩形备份-9" fill="#5F0612" x="61.589404" y="55.4304636" width="24.6357616" height="12.3178808" rx="2"></rect>
</g>
</g>
<path d="M458,0 C480.643675,0 499,18.3563253 499,41 C499,63.6436747 480.643675,82 458,82 C435.356325,82 417,63.6436747 417,41 C417,18.3563253 435.356325,0 458,0 Z M458.5,19 C445.521308,19 435,28.8497355 435,41 C435,53.1502645 445.521308,63 458.5,63 C471.478692,63 482,53.1502645 482,41 C482,28.8497355 471.478692,19 458.5,19 Z" id="形状结合备份-4" fill="#FF94AE" opacity="0.065419"></path>
<path d="M346.5,12 C358.926407,12 369,22.0735931 369,34.5 C369,46.9264069 358.926407,57 346.5,57 C334.073593,57 324,46.9264069 324,34.5 C324,22.0735931 334.073593,12 346.5,12 Z M346.5,22 C339.596441,22 334,27.5964406 334,34.5 C334,41.4035594 339.596441,47 346.5,47 C353.403559,47 359,41.4035594 359,34.5 C359,27.5964406 353.403559,22 346.5,22 Z" id="形状结合备份-5" fill="#FF94AE" opacity="0.065419"></path>
<path d="M70,196 C84.9116882,196 97,208.088312 97,223 C97,237.911688 84.9116882,250 70,250 C55.0883118,250 43,237.911688 43,223 C43,208.088312 55.0883118,196 70,196 Z M70,207.911765 C61.6669977,207.911765 54.9117647,214.666998 54.9117647,223 C54.9117647,231.333002 61.6669977,238.088235 70,238.088235 C78.3330023,238.088235 85.0882353,231.333002 85.0882353,223 C85.0882353,214.666998 78.3330023,207.911765 70,207.911765 Z" id="形状结合备份-6" fill="#FF94AE" opacity="0.065419"></path>
</g>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 12 KiB

View File

@@ -0,0 +1,69 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="760px" height="448px" viewBox="0 0 760 448" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>编组 2备份 2</title>
<defs>
<linearGradient x1="15.9441543%" y1="46.8290015%" x2="100%" y2="52.3317319%" id="linearGradient-1">
<stop stop-color="#EAEAFF" offset="0%"></stop>
<stop stop-color="#E4E4FF" offset="100%"></stop>
</linearGradient>
<path d="M204.456333,0 L198.6215,0 C180.286843,0 165.438854,14.8091575 165.415135,33.0958648 L165.343978,122.873425 C165.343978,133.802867 156.449416,142.650511 145.491316,142.650511 L5.6925197,142.650511 C2.53791503,142.650511 0,145.181789 0,148.328143 L0,171.984944 C0,175.131299 2.53791503,177.662577 5.6925197,177.662577 L19.354567,177.662577 C19.781506,164.722306 30.4549804,154.360628 43.5240569,154.360628 C56.5931333,154.360628 67.2666078,164.722306 67.6935467,177.662577 L126.302781,177.662577 C126.72972,164.722306 137.403194,154.360628 150.472271,154.360628 C163.541347,154.360628 174.214822,164.722306 174.641761,177.662577 C186.121675,177.662577 195.419457,168.389111 195.419457,156.939219 L195.419457,42.8188101 C195.419457,35.7690833 201.159415,30.0441375 208.227627,30.0441375 C211.382231,30.0441375 213.920245,27.5128597 213.920245,24.3665052 L213.920245,9.46272046 C213.943865,4.23456741 209.698194,0 204.456333,0 Z" id="path-2"></path>
<path d="M5.70865422,58.0122699 L73.046988,58.0122699 C82.1094766,58.0122699 89.4355828,50.6656341 89.4355828,41.6309363 L89.4355828,5.70612491 C89.4355828,2.54398069 86.8904745,0 83.7269286,0 L5.70865422,0 C2.54510834,0 0,2.54398069 0,5.70612491 L0,52.306145 C0,55.4682892 2.54510834,58.0122699 5.70865422,58.0122699 Z" id="path-4"></path>
<path d="M5.63122767,90.6441718 L47.1615317,90.6441718 C50.2821704,90.6441718 52.7927594,88.1249701 52.7927594,84.993626 L52.7927594,29.4299259 C52.7927594,26.3221257 55.3268118,23.7793801 58.4474505,23.7793801 C61.5446257,23.7793801 64.0552147,21.2366345 64.0552147,18.1288344 L64.0552147,5.65054577 C64.0552147,2.51920166 61.5446257,0 58.4239871,0 L5.63122767,0 C2.510589,0 0,2.51920166 0,5.65054577 L0,84.993626 C0,88.1249701 2.510589,90.6441718 5.63122767,90.6441718 Z" id="path-6"></path>
<path d="M-6.64723926,74.9325153 L29.6104294,74.9325153 C31.2791426,74.9325153 32.6319018,73.5797561 32.6319018,71.9110429 C32.6319018,70.2423298 31.2791426,68.8895706 29.6104294,68.8895706 L-6.64723926,68.8895706 C-8.31595239,68.8895706 -9.66871166,70.2423298 -9.66871166,71.9110429 C-9.66871166,73.5797561 -8.31595239,74.9325153 -6.64723926,74.9325153 Z" id="path-8"></path>
<filter x="-28.4%" y="-198.6%" width="156.7%" height="497.2%" filterUnits="objectBoundingBox" id="filter-9">
<feOffset dx="0" dy="0" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
<feGaussianBlur stdDeviation="4" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
<feColorMatrix values="0 0 0 0 0.976470588 0 0 0 0 0.2 0 0 0 0 0.996078431 0 0 0 1 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
</filter>
</defs>
<g id="2MES。2-6蓝底-7、8白底" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="2-8数据分析" transform="translate(-360.000000, -600.000000)">
<g id="编组-2备份-2" transform="translate(360.000000, 600.000000)">
<rect id="矩形" fill="#FFFFFF" x="0" y="0" width="760" height="448" rx="16"></rect>
<path d="M575.951613,79.5 C589.23317,79.5 600,90.2668296 600,103.548387 C600,116.829945 589.23317,127.596774 575.951613,127.596774 C562.670055,127.596774 551.903226,116.829945 551.903226,103.548387 C551.903226,90.2668296 562.670055,79.5 575.951613,79.5 Z M577.096774,90.9516129 C569.507313,90.9516129 563.354839,96.5913808 563.354839,103.548387 C563.354839,110.505393 569.507313,116.145161 577.096774,116.145161 C584.686236,116.145161 590.83871,110.505393 590.83871,103.548387 C590.83871,96.5913808 584.686236,90.9516129 577.096774,90.9516129 Z" id="形状结合备份-2" fill="#E5E5FF" opacity="0.436918713"></path>
<path d="M678.822581,158.145161 C688.309407,158.145161 696,165.835754 696,175.322581 C696,184.809407 688.309407,192.5 678.822581,192.5 C669.335754,192.5 661.645161,184.809407 661.645161,175.322581 C661.645161,165.835754 669.335754,158.145161 678.822581,158.145161 Z M678.822581,165.322581 C673.299733,165.322581 668.822581,169.799733 668.822581,175.322581 C668.822581,180.845428 673.299733,185.322581 678.822581,185.322581 C684.345428,185.322581 688.822581,180.845428 688.822581,175.322581 C688.822581,169.799733 684.345428,165.322581 678.822581,165.322581 Z" id="形状结合备份-3" fill="#E5E5FF" opacity="0.33435192"></path>
<path d="M51.8225806,379.5 C61.3094074,379.5 69,387.190593 69,396.677419 C69,406.164246 61.3094074,413.854839 51.8225806,413.854839 C42.3357539,413.854839 34.6451613,406.164246 34.6451613,396.677419 C34.6451613,387.190593 42.3357539,379.5 51.8225806,379.5 Z M51.8225806,386.677419 C46.2997331,386.677419 41.8225806,391.154572 41.8225806,396.677419 C41.8225806,402.200267 46.2997331,406.677419 51.8225806,406.677419 C57.3454281,406.677419 61.8225806,402.200267 61.8225806,396.677419 C61.8225806,391.154572 57.3454281,386.677419 51.8225806,386.677419 Z" id="形状结合备份-8" fill="#E5E5FF" opacity="0.33435192"></path>
<path d="M183,448 C207.354878,425.471056 229.686941,412.240546 249.996189,408.308471 C355.668539,387.849239 370.402999,416.757902 400.639869,408.308471 C455.598803,392.950673 442.737068,332.559851 499.076713,332.559851 C555.416358,332.559851 539.868526,235.110915 606.011743,257.861336 C672.154961,280.611758 699.323201,299.03438 720.688207,257.861336 C734.931544,230.412641 748.035475,213.208091 760,206.247685 L760,432 C760,440.836556 752.836556,448 744,448 L183,448 L183,448 Z" id="路径-2" fill="#E5E5FF" opacity="0.296545"></path>
<path d="M760,318 C732.214554,319.105946 702.781665,322.383441 671.701335,327.832485 C625.080839,336.006051 619.654127,377.013633 549.022246,389.585627 C478.390365,402.157622 419.458588,369.447932 357.032061,398.115916 C315.414376,417.227905 289.070356,433.855933 278,448 L743.95538,448 C752.789791,447.994507 759.952347,440.83441 759.960872,432.000001 L760,318 L760,318 Z" id="路径-8" fill="url(#linearGradient-1)" opacity="0.353427"></path>
<g id="编组-14" transform="translate(437.794479, 185.000000)">
<g id="编组-11">
<g id="路径-7">
<mask id="mask-3" fill="white">
<use xlink:href="#path-2"></use>
</mask>
<use id="蒙版" fill="#E9E9FF" fill-rule="nonzero" xlink:href="#path-2"></use>
<path d="M213.374672,14.5030675 L193.340971,14.5030675 C186.204928,17.1363377 182.636906,24.0269529 182.636906,35.1749133 C182.636906,46.3228736 182.636906,84.2050211 182.636906,148.821356 C182.425805,156.199679 178.400117,160.66298 170.559842,162.21126 C158.799429,164.533679 193.336744,162.21126 128.931654,162.21126 C85.9949273,162.21126 43.0177094,162.21126 0,162.21126 L0.11822616,178.871166 L199.813315,178.871166 L216.337423,17.5913823 L213.374672,14.5030675 Z" fill="#DDDDFC" mask="url(#mask-3)"></path>
</g>
<path d="M44.0609224,163.16834 C34.2738911,162.856499 26.2859464,170.844443 26.5977881,180.631475 C26.8856419,189.482981 34.0819885,196.703315 42.9574826,196.991169 C52.7445138,197.303011 60.7324585,189.315066 60.4206168,179.528035 C60.132763,170.676528 52.9124286,163.456194 44.0609224,163.16834 Z" id="路径" fill="#DDDDFC" fill-rule="nonzero"></path>
<path d="M150.416751,163.16834 C140.629719,162.856499 132.641775,170.844443 132.953616,180.631475 C133.24147,189.482981 140.437817,196.703315 149.313311,196.991169 C159.100342,197.303011 167.088287,189.315066 166.776445,179.528035 C166.488591,170.676528 159.268257,163.456194 150.416751,163.16834 Z" id="路径" fill="#DDDDFC" fill-rule="nonzero"></path>
</g>
<g id="编组-13" transform="translate(0.000000, 30.214724)">
<g id="编组-12" transform="translate(61.638037, 0.000000)">
<g id="矩形" transform="translate(0.000000, 42.300613)">
<mask id="mask-5" fill="white">
<use xlink:href="#path-4"></use>
</mask>
<use id="蒙版" fill="#E9E9FF" fill-rule="nonzero" xlink:href="#path-4"></use>
<rect fill="#DDDDFC" mask="url(#mask-5)" transform="translate(44.717791, 43.509202) scale(1, -1) translate(-44.717791, -43.509202) " x="0" y="29.006135" width="89.4355828" height="29.006135"></rect>
</g>
<path d="M17.7378203,32.6319018 L70.4891736,32.6319018 C73.6212852,32.6319018 76.1411043,30.1378922 76.1411043,27.0378615 L76.1411043,5.59404032 C76.1411043,2.49400964 73.6212852,0 70.4891736,0 L17.7378203,0 C14.6057087,0 12.0858896,2.49400964 12.0858896,5.59404032 L12.0858896,27.0378615 C12.0858896,30.1378922 14.6057087,32.6319018 17.7378203,32.6319018 Z" id="路径" fill="#E9E9FF" fill-rule="nonzero"></path>
<path d="M10.0597257,67.6809816 L24.989354,67.6809816 C25.8758007,67.6809816 26.5889571,66.3877914 26.5889571,64.7803681 L26.5889571,53.6613497 C26.5889571,52.0539264 25.8758007,50.7607362 24.989354,50.7607362 L10.0597257,50.7607362 C9.17327905,50.7607362 8.4601227,52.0539264 8.4601227,53.6613497 L8.4601227,64.7803681 C8.4601227,66.3877914 9.17327905,67.6809816 10.0597257,67.6809816 Z" id="路径备份-2" fill="#1E1A64" fill-rule="nonzero"></path>
<path d="M10.0597257,93.0613497 L24.989354,93.0613497 C25.8758007,93.0613497 26.5889571,91.7681595 26.5889571,90.1607362 L26.5889571,79.0417178 C26.5889571,77.4342945 25.8758007,76.1411043 24.989354,76.1411043 L10.0597257,76.1411043 C9.17327905,76.1411043 8.4601227,77.4342945 8.4601227,79.0417178 L8.4601227,90.1607362 C8.4601227,91.7681595 9.17327905,93.0613497 10.0597257,93.0613497 Z" id="路径备份-3" fill="#1E1A64" fill-rule="nonzero"></path>
</g>
<g id="路径-6" transform="translate(0.000000, 9.668712)">
<mask id="mask-7" fill="white">
<use xlink:href="#path-6"></use>
</mask>
<use id="蒙版" fill="#E9E9FF" fill-rule="nonzero" xlink:href="#path-6"></use>
<path d="M64.8927126,12.0858896 L42.2576687,12.0858896 C38.9439602,12.0858896 36.2576687,14.7721811 36.2576687,18.0858896 L36.2576687,94.2699387 L36.2576687,94.2699387 L57.6996966,94.2699387 L57.6996966,30.3548945 L68.8895706,26.575992 L64.8927126,12.0858896 Z" fill="#DDDDFC" mask="url(#mask-7)"></path>
</g>
<g id="路径备份-4" transform="translate(11.481595, 71.911043) rotate(-90.000000) translate(-11.481595, -71.911043) ">
<use fill="black" fill-opacity="1" filter="url(#filter-9)" xlink:href="#path-8"></use>
<use fill="#F933FE" fill-rule="evenodd" xlink:href="#path-8"></use>
</g>
</g>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 11 KiB

View File

@@ -0,0 +1,76 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="760px" height="448px" viewBox="0 0 760 448" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>编组 17</title>
<defs>
<rect id="path-1" x="19.526039" y="1.15770612" width="98" height="11" rx="5.5"></rect>
<filter x="-12.2%" y="-109.1%" width="124.5%" height="318.2%" filterUnits="objectBoundingBox" id="filter-2">
<feOffset dx="0" dy="0" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
<feGaussianBlur stdDeviation="4" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
<feColorMatrix values="0 0 0 0 1 0 0 0 0 0.647058824 0 0 0 0 0.11372549 0 0 0 1 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
</filter>
<rect id="path-3" x="19.526039" y="0.157706119" width="98" height="11" rx="5.5"></rect>
<filter x="-12.2%" y="-109.1%" width="124.5%" height="318.2%" filterUnits="objectBoundingBox" id="filter-4">
<feOffset dx="0" dy="0" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
<feGaussianBlur stdDeviation="4" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
<feColorMatrix values="0 0 0 0 1 0 0 0 0 0.647058824 0 0 0 0 0.11372549 0 0 0 1 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
</filter>
<rect id="path-5" x="19.526039" y="0.157706119" width="98" height="11" rx="5.5"></rect>
<filter x="-12.2%" y="-109.1%" width="124.5%" height="318.2%" filterUnits="objectBoundingBox" id="filter-6">
<feOffset dx="0" dy="0" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
<feGaussianBlur stdDeviation="4" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
<feColorMatrix values="0 0 0 0 1 0 0 0 0 0.647058824 0 0 0 0 0.11372549 0 0 0 1 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
</filter>
<rect id="path-7" x="33.7695142" y="-3.75716541" width="22" height="145"></rect>
</defs>
<g id="2MES。2-6蓝底-7、8白底" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="2-8数据分析" transform="translate(-1136.000000, -600.000000)">
<g id="编组-17" transform="translate(1136.000000, 600.000000)">
<rect id="矩形备份-3" fill="#FFFFFF" x="0" y="0" width="760" height="448" rx="16"></rect>
<path d="M207.288696,284 C236.283645,284 259.788696,307.505051 259.788696,336.5 C259.788696,365.494949 236.283645,389 207.288696,389 C178.293746,389 154.788696,365.494949 154.788696,336.5 C154.788696,307.505051 178.293746,284 207.288696,284 Z M207.998155,303.864865 C189.582444,303.864865 174.653561,318.793748 174.653561,337.209459 C174.653561,355.625171 189.582444,370.554054 207.998155,370.554054 C226.413866,370.554054 241.34275,355.625171 241.34275,337.209459 C241.34275,318.793748 226.413866,303.864865 207.998155,303.864865 Z" id="形状结合备份-7" fill="#FFC49A" opacity="0.083664"></path>
<g id="编组-6" transform="translate(191.788696, 81.395307)">
<path d="M0,366.604693 C59.762951,366.527338 98.8189583,361.54156 117.168022,351.647359 C173.536391,321.252348 222.996708,270.828073 268.404942,270.828073 C369.775248,270.828073 321.298056,210.294593 398.431035,214.515773 C475.564015,218.736954 490.163321,227.670825 522.018307,224.153073 C543.254964,221.807906 558.652629,212.345851 568.211304,195.766909 L568.211304,350.604693 C568.211304,359.441249 561.04786,366.604693 552.211304,366.604693 L0,366.604693 L0,366.604693 Z" id="路径-2备份" fill="#FEBE93" opacity="0.110351562"></path>
<path d="M226.904445,0 C244.301415,0 258.404445,14.1030304 258.404445,31.5 C258.404445,48.8969696 244.301415,63 226.904445,63 C209.507475,63 195.404445,48.8969696 195.404445,31.5 C195.404445,14.1030304 209.507475,0 226.904445,0 Z M226.904445,14.472973 C217.030489,14.472973 209.026067,22.0962326 209.026067,31.5 C209.026067,40.9037674 217.030489,48.527027 226.904445,48.527027 C236.778401,48.527027 244.782823,40.9037674 244.782823,31.5 C244.782823,22.0962326 236.778401,14.472973 226.904445,14.472973 Z" id="形状结合备份-7" fill="#FFC49A" opacity="0.183663504"></path>
<path d="M497.279896,97.5845278 C509.430161,97.5845278 519.279896,107.434263 519.279896,119.584528 C519.279896,131.734792 509.430161,141.584528 497.279896,141.584528 C485.129632,141.584528 475.279896,131.734792 475.279896,119.584528 C475.279896,107.434263 485.129632,97.5845278 497.279896,97.5845278 Z M497.279896,107.362306 C490.529749,107.362306 485.057674,112.834381 485.057674,119.584528 C485.057674,126.334675 490.529749,131.80675 497.279896,131.80675 C504.030043,131.80675 509.502118,126.334675 509.502118,119.584528 C509.502118,112.834381 504.030043,107.362306 497.279896,107.362306 Z" id="形状结合备份-10" fill="#FFC49A" opacity="0.195568266"></path>
<path d="M568.211304,229.564363 C551.825455,259.713189 525.340556,274.787602 488.756606,274.787602 C412.997037,274.787602 376.562696,300.171746 322.96697,313.709386 C269.371245,327.247027 223.429961,300.820402 161.224946,311.096408 C129.836333,315.362043 100.845254,334.033619 48.6901401,345.720186 C23.2710779,351.415919 7.04103119,358.377421 0,366.604693 L552.211304,366.604693 C561.04786,366.604693 568.211304,359.441249 568.211304,350.604693 L568.211304,229.564363 L568.211304,229.564363 Z" id="路径-5备份" fill="#FFC49A" opacity="0.101888021"></path>
<g id="编组-33" transform="translate(247.211304, 89.604693)">
<path d="M144,12 C157.254834,12 168,22.745166 168,36 L168,188 C168,201.254834 157.254834,212 144,212 L24,212 C10.745166,212 1.623249e-15,201.254834 0,188 L0,36 C-1.623249e-15,22.745166 10.745166,12 24,12 L25,12 L25,28 C25,32.3349143 28.4478378,35.8645429 32.7508207,35.9961932 L33,36 L135,36 C139.418278,36 143,32.418278 143,28 L143,28 L143,12 L144,12 Z" id="形状结合" fill="#FFEFDB"></path>
<path d="M25.5794702,69.3609272 L200.755065,69.3609272 L201.349945,121.37295 C201.400067,125.755252 204.966833,129.281457 209.349422,129.281457 L225.57947,129.281457 L225.57947,129.281457 L225.57947,130.360927 C225.57947,143.615761 214.834304,154.360927 201.57947,154.360927 L49.5794702,154.360927 C36.3246362,154.360927 25.5794702,143.615761 25.5794702,130.360927 L25.5794702,69.3609272 L25.5794702,69.3609272 Z" id="矩形" fill="#FFE5C5" transform="translate(125.579470, 111.860927) rotate(-90.000000) translate(-125.579470, -111.860927) "></path>
<g id="编组-34" transform="translate(27.008124, 71.038146)">
<rect id="矩形" fill="#5F2F06" x="0" y="0" width="12" height="12" rx="6"></rect>
<g id="矩形备份-31">
<use fill="black" fill-opacity="1" filter="url(#filter-2)" xlink:href="#path-1"></use>
<use fill="#FFAE12" fill-rule="evenodd" xlink:href="#path-1"></use>
</g>
</g>
<g id="编组-34备份" transform="translate(27.008124, 98.038146)">
<rect id="矩形" fill="#5F2F06" x="0" y="0" width="12" height="12" rx="6"></rect>
<g id="矩形备份-31">
<use fill="black" fill-opacity="1" filter="url(#filter-4)" xlink:href="#path-3"></use>
<use fill="#FFAE12" fill-rule="evenodd" xlink:href="#path-3"></use>
</g>
</g>
<g id="编组-34备份-2" transform="translate(27.008124, 148.038146)">
<rect id="矩形" fill="#5F2F06" x="0" y="0" width="12" height="12" rx="6"></rect>
<g id="矩形备份-31">
<use fill="black" fill-opacity="1" filter="url(#filter-6)" xlink:href="#path-5"></use>
<use fill="#FFAE12" fill-rule="evenodd" xlink:href="#path-5"></use>
</g>
</g>
<g id="编组-32" transform="translate(130.999615, 69.000000)">
<path d="M80.9929007,25.3239988 C85.1936525,18.0493952 82.5831854,8.72645586 75.2018643,4.72015238 L69.8008977,1.79826188 C62.8396519,-1.98212223 54.1681,0.3825005 50.0573643,7.16008157 L39.0003855,25.4143666 L70.2059702,44 L80.9929007,25.3239988 Z M34.6944049,32 L0.699111239,92.2741491 L0.000385469649,125.006402 C-0.028934822,126.536508 1.62031238,127.511575 2.92782367,126.71652 L31.3513362,109.615343 L66.0003855,49.5362072 L34.6944049,32 Z" id="形状" fill="#FFEFDB" fill-rule="nonzero"></path>
<g id="形状备份" transform="translate(0.410412, 1.596776)">
<mask id="mask-8" fill="white">
<use xlink:href="#path-7"></use>
</mask>
<g id="蒙版" transform="translate(44.769514, 68.742835) rotate(29.000000) translate(-44.769514, -68.742835) "></g>
<path d="M80.5824885,23.727223 C84.7832403,16.4526193 82.1727731,7.12968001 74.7914521,3.12337653 L69.3904855,0.20148603 C62.4292397,-3.57889808 53.7576877,-1.21427535 49.6469521,5.56330572 L38.5899732,23.8175907 L69.795558,42.4032242 L80.5824885,23.727223 Z M34.2839926,30.4032242 L0.288698998,90.6773733 L-0.410026771,123.409627 C-0.439347063,124.939732 1.20990014,125.914799 2.51741143,125.119744 L30.940924,108.018567 L65.5899732,47.9394313 L34.2839926,30.4032242 Z" fill="#FFE5C5" fill-rule="nonzero" mask="url(#mask-8)"></path>
</g>
</g>
<rect id="矩形" fill="#FFEFDB" x="32" y="0" width="102" height="29" rx="8"></rect>
<path d="M32,15 L134,15 L134,21 C134,25.418278 130.418278,29 126,29 L40,29 C35.581722,29 32,25.418278 32,21 L32,15 L32,15 Z" id="矩形" fill="#FFE5C5"></path>
</g>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 10 KiB

View File

@@ -0,0 +1,273 @@
<!--
/*
* @Author: lb
* @Date: 2022-03-24 13:30:00
* @LastEditTime: 2022-05-16 10:00:20
* @LastEditors: gtz
* @Description: 拆分了搜索区和功能按钮区增加了toptitle
*/
-->
<template>
<div>
<div class="app-container">
<top-title />
<head-form
:form-config="headFormConfig"
@headBtnClick="btnClick"
/>
<base-table
:page="listQuery.current"
:limit="listQuery.size"
:table-config="trueTableProps.length ? trueTableProps: tableProps"
:table-data="tableData.length ? tableData : []"
:is-loading="listLoading"
:index-config="{ align: 'left', fixed: 'left' }"
/>
</div>
<div class="app-container">
<top-title base-title="产品量" />
<Line-chart :chart-data="chartData" width="100%" height="400px" />
</div>
</div>
</template>
<script>
import Vue from 'vue'
import i18n from '@/lang'
import TopTitle from '@/components/TopTitle'
import HeadForm from '@/components/basicData/HeadForm'
import BaseTable from '@/components/BaseTable/index-compound'
import LineChart from './components/LineChartYield'
import { lineList } from '@/api/DataAnalysis/productionLineBalance'
// import { timeFormatter } from '@/filters'
/**
* 表格表头配置项 TypeScript接口注释
* tableConfig<ConfigItem> = []
*
* Interface ConfigItem = {
* prop: string,
* label: string,
* width: string,
* align: string,
* subcomponent: function,
* filter: function
* }
*
*
*/
const tableProps = [
{
prop: 'productName',
label: i18n.t('module.dataAnalysis.yield.productName'),
align: 'center',
fixed: 'left'
},
{
prop: 'productSpecifications',
label: i18n.t('module.dataAnalysis.yield.productSpecifications'),
align: 'center',
fixed: 'left'
}
]
const testData = [
{
productName: '产品1',
productSpecifications: '100cm*100cm',
data: [
{ time: '02-01', value: 23 },
{ time: '02-02', value: 24 },
{ time: '02-03', value: 45 },
{ time: '02-04', value: 83 },
{ time: '02-05', value: 13 },
{ time: '02-06', value: 52 },
{ time: '02-07', value: 46 },
{ time: '02-08', value: 123 },
{ time: '02-09', value: 31 },
{ time: '02-10', value: 13 },
{ time: '02-11', value: 23 },
{ time: '02-12', value: 24 },
{ time: '02-13', value: 45 },
{ time: '02-14', value: 83 },
{ time: '02-15', value: 13 },
{ time: '02-16', value: 52 },
{ time: '02-17', value: 46 },
{ time: '02-18', value: 123 },
{ time: '02-19', value: 31 },
{ time: '02-20', value: 13 },
{ time: '02-21', value: 23 },
{ time: '02-22', value: 24 },
{ time: '02-23', value: 45 },
{ time: '02-24', value: 83 },
{ time: '02-25', value: 13 },
{ time: '02-26', value: 52 },
{ time: '02-27', value: 46 },
{ time: '02-28', value: 123 }
]
},
{
productName: '产品2',
productSpecifications: '100cm*100cm',
data: [
{ time: '02-01', value: 33 },
{ time: '02-02', value: 64 },
{ time: '02-03', value: 15 },
{ time: '02-04', value: 53 },
{ time: '02-05', value: 33 },
{ time: '02-06', value: 22 },
{ time: '02-07', value: 66 },
{ time: '02-08', value: 13 },
{ time: '02-09', value: 51 },
{ time: '02-10', value: 23 },
{ time: '02-11', value: 63 },
{ time: '02-12', value: 44 },
{ time: '02-13', value: 15 },
{ time: '02-14', value: 43 },
{ time: '02-15', value: 23 },
{ time: '02-16', value: 42 },
{ time: '02-17', value: 56 },
{ time: '02-18', value: 33 },
{ time: '02-19', value: 121 },
{ time: '02-20', value: 33 },
{ time: '02-21', value: 33 },
{ time: '02-22', value: 44 },
{ time: '02-23', value: 15 },
{ time: '02-24', value: 53 },
{ time: '02-25', value: 23 },
{ time: '02-26', value: 32 },
{ time: '02-27', value: 56 },
{ time: '02-28', value: 23 }
]
}
]
export default {
name: 'ProductPool',
components: { TopTitle, BaseTable, HeadForm, LineChart },
filters: {
statusFilter(status) {
const statusMap = {
published: 'success',
draft: 'info',
deleted: 'danger'
}
return statusMap[status]
}
},
data() {
return {
addOrUpdateVisible: false,
trueWidth: 240,
tableProps,
testData,
tableData: [],
list: [],
total: 0,
listLoading: false,
listQuery: {
current: 1,
size: 10
},
lineList: [],
headFormConfig: [
{
type: 'select',
label: i18n.t('module.dataAnalysis.yield.line'),
placeholder: this.$t('module.dataAnalysis.yield.line'),
param: 'line',
width: 300,
selectOptions: []
},
{
type: 'datePicker',
label: this.$t('module.dataAnalysis.yield.time'),
dateType: 'month',
format: 'yyyy-MM',
valueFormat: 'yyyy-MM',
param: 'searchTime'
},
{
type: 'button',
btnName: 'btn.search',
name: 'search',
color: 'primary'
}
],
trueTableProps: [],
headFormValue: {},
numArr: [],
chartData: [],
chartType: 0
}
},
created() {
this.getLineList()
this.getList()
},
methods: {
// 获取产线列表
getLineList() {
lineList({ current: 1, size: 999 }).then(res => {
if (res.code === 0) {
this.lineList = res.data.records
Vue.set(this.headFormConfig[0], 'selectOptions', this.lineList)
}
console.log(res)
})
},
getList() {
this.numArr = []
const tableConfig = []
this.chartData = []
const tableData = this.testData.map((item, index) => {
const tableDataArr = {}
if (item.data) {
const dataArr = item.data.map(i => {
if (index === 0) {
this.numArr.push(i.time)
tableConfig.push({
label: i.time,
prop: i.time
})
}
tableDataArr[i.time] = i.value
return i.value
})
this.chartData.push({
name: item.productName,
data: dataArr,
timeArr: this.numArr
})
}
return {
...item,
...tableDataArr
}
})
this.$nextTick(() => {
this.trueTableProps = this.tableProps.concat(tableConfig)
this.tableData = this.flatten(tableData)
})
},
// 数组扁平
flatten(arr) {
var res = []
for (var i = 0; i < arr.length; i++) {
if (Array.isArray(arr[i])) {
res = res.concat(this.flatten(arr[i]))
} else {
res.push(arr[i])
}
}
return res
},
btnClick(val) {
this.headFormValue = val
if (this.headFormValue.btnName === 'search') {
this.getList()
}
}
}
}
</script>

View File

@@ -0,0 +1,7 @@
<!--
* @Date: 2021-03-04 15:27:27
* @LastEditors: guo
* @LastEditTime: 2021-03-04 15:27:27
* @FilePath: \basic-admin\src\views\DictManager\index.vue
* @Description:
-->

View File

@@ -0,0 +1,114 @@
<!--
* @Date: 2021-01-11 09:24:41
* @LastEditors: guo
* @LastEditTime: 2021-02-25 16:04:49
* @FilePath: \basic-admin\src\views\EquipmentManager\StatusSetting\EditForm.vue
* @Description: 子页面
-->
<template>
<div>
<el-dialog v-bind="$attrs" title="修改设备状态" v-on="$listeners" @open="onOpen" @close="onClose">
<el-form ref="elForm" :model="formData" :rules="rules" size="medium" label-width="120px">
<el-form-item label="设备状态" prop="status">
<el-select v-model="formData.status" placeholder="请选择下拉选择设备状态" clearable :style="{width: '100%'}">
<el-option
v-for="(item, index) in statusOptions"
:key="index"
:label="item.label"
:value="item.value"
:disabled="item.disabled"
/>
</el-select>
</el-form-item>
</el-form>
<div slot="footer">
<el-button @click="close">{{ 'btn.cancel' | i18nFilter }}</el-button>
<el-button type="primary" @click="handelConfirm">{{ 'btn.confirm' | i18nFilter }}</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { editStatusSetting } from '@/api/equipment/index'
export default {
components: {},
inheritAttrs: false,
props: {
targetInfo: {
type: Object,
default: () => ({})
}
},
data() {
return {
formData: {
status: undefined,
oldStatus: null,
id: null
},
rules: {
status: [{
required: true,
message: '请选择下拉选择设备状态',
trigger: 'change'
}]
},
statusOptions: [{
'label': 'productive',
'value': 0
}, {
'label': 'standby',
'value': 1
}, {
'label': 'unscheduled downtime',
'value': 2
}, {
'label': 'scheduled downtime',
'value': 3
}, {
'label': 'engineering',
'value': 4
}, {
'label': 'non-scheduled',
'value': 5
}]
}
},
computed: {},
watch: {},
created() {},
mounted() {},
methods: {
onOpen() {
this.formData.id = this.targetInfo.id
this.formData.oldStatus = this.targetInfo.status
},
onClose() {
this.$refs['elForm'].resetFields()
},
close() {
this.$emit('update:visible', false)
},
handelConfirm() {
this.$refs['elForm'].validate(async valid => {
if (!valid) return
const result = await editStatusSetting({
...this.formData,
id: this.targetInfo?.id
})
if (result.code === 0) {
this.$message({
type: 'success',
message: '修改状态成功!'
})
this.$emit('done')
this.close()
}
})
}
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,156 @@
<!--
* @Date: 2020-12-15 15:36:52
* @LastEditors: gtz
* @LastEditTime: 2022-07-25 10:32:06
* @FilePath: \mt-bus-fe\src\views\EquipmentManager\Analysis\index.vue
* @Description:
-->
<template>
<div class="usermanager-container">
<div class="method-btn-area">
<el-input v-model="listQuery.keywords" placeholder="设备编码或名称" style="width: 200px;" clearable />
<el-button type="primary" @click="getList">{{ 'btn.search' | i18nFilter }}</el-button>
</div>
<base-table :table-config="tableProps" :table-data="list" :is-loading="listLoading" :page="listQuery.current" :limit="listQuery.size">
<method-btn slot="handleBtn" :method-list="tableBtn" @clickBtn="handleClick" />
</base-table>
<pagination v-show="total > listQuery.size" :total="total" :page.sync="listQuery.current" :limit.sync="listQuery.size" @pagination="getList" />
<edit-form :visible.sync="showEditDialog" :target-info="{id: curEditId, status: curStatus}" @done="getList" />
</div>
</template>
<script>
// import dataDict from '@/filters/DataDict'
// edit here
const colorTable = {
'0': 'rgb(155,187,89)',
'1': 'rgb(255,255,0)',
'2': 'rgb(192,80,77)',
'3': 'rgb(247,150,70)',
'4': 'rgb(79,129,189)',
'5': 'rgb(0,0,0)'
}
const tableBtn = [{
type: 'edit',
btnName: 'btn.edit'
}]
const tableProps = [{
prop: 'code',
label: '设备编号',
align: 'center'
}, {
prop: 'name',
label: '设备名称',
align: 'center'
}, {
prop: 'status',
label: '设备类型',
align: 'center'
}, {
prop: 'color',
label: '车间',
align: 'center'
}, {
prop: 'color',
label: '工作时间累计',
align: 'center'
}, {
prop: 'color',
label: '维修次数',
align: 'center'
}, {
prop: 'color',
label: '保养次数',
align: 'center'
}, {
prop: 'remark',
label: '备注',
align: 'center'
}]
import EditForm from './EditForm'
import BaseTable from '@/components/BaseTable'
// edit here
import { getStatusSettingList } from '@/api/equipment'
import Pagination from '@/components/Pagination'
import MethodBtn from '@/components/BaseTable/subcomponents/MethodBtn'
export default {
name: 'OrgManager',
components: {
Pagination,
BaseTable,
MethodBtn,
EditForm
},
props: {},
data() {
return {
tableBtn,
tableProps,
list: [],
total: 0,
listLoading: true,
showDialog: false,
curEditId: null,
curStatus: null,
showEditDialog: false,
listQuery: {
current: 1,
size: 10,
keywords: ''
}
}
},
created() {
this.getList()
// this.listLoading = false
},
mounted() {},
methods: {
handleClick(raw) {
console.log(raw)
switch (raw.type) {
case 'edit':
this.showEditDialog = true
this.curEditId = raw.data.id
this.curStatus = raw.data.status
break
}
},
async getList() {
this.listLoading = true
// edit here
const res = await getStatusSettingList(this.listQuery)
if (res.code === 0) {
this.list = res.data.records ? res.data.records.map(item => {
return {
...item,
color: colorTable[item.status]
}
}) : []
this.total = res.data.total
this.listLoading = false
}
}
}
}
</script>
<style lang="scss" scoped>
.usermanager-container {
padding: 20px;
.method-btn-area {
padding: 15px 30px;
margin: 10px 0 20px 0;
border: 1px solid #dfe6ec;
}
}
.edit-input {
padding-right: 100px;
}
.cancel-btn {
position: absolute;
right: 15px;
top: 10px;
}
</style>

View File

@@ -0,0 +1,160 @@
<!--
* @Date: 2021-01-12 09:37:27
* @LastEditors: fzq
* @LastEditTime: 2022-09-13 15:58:12
* @FilePath: \mt-bus-fe\src\views\EquipmentManager\BOMManager\AddForm.vue
* @Description: 物料BOM添加弹窗页面
-->
<template>
<div>
<el-dialog v-bind="$attrs" :title="$t('module.equipmentManager.bom.addDialogTitle')" class="dialog" width="45%" v-on="$listeners" @open="onOpen" @close="onClose">
<el-form ref="elForm" :model="formData" :rules="rules" size="medium" label-width="110px">
<el-row :gutter="20">
<!-- 设备类型名称 -->
<el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.bom.equipmentName')" prop="equipmentTypeId">
<el-select v-model="formData.equipmentTypeId" :placeholder="$t('module.equipmentManager.bom.placeholderequipmentName')" clearable :style="{width: '100%'}">
<el-option
v-for="(item, index) in dict.device"
:key="index"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
</el-col>
<!-- 设备配方名称 -->
<el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.bom.name')" prop="name">
<el-input v-model="formData.name" :placeholder="$t('module.equipmentManager.bom.name')" clearable :style="{width: '100%'}" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<!-- 设备配方编码 -->
<el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.bom.code')" prop="code">
<el-input v-model="formData.code" :placeholder="$t('module.equipmentManager.bom.code')" clearable :style="{width: '100%'}" />
</el-form-item>
</el-col>
<!-- 备注 -->
<el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.bom.remark')" prop="remark">
<el-input v-model="formData.remark" :placeholder="$t('module.equipmentManager.bom.placeholderremark')" clearable :style="{width: '100%'}" />
</el-form-item>
</el-col>
<!-- 激活状态 -->
<el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.bom.enabled')" prop="enabled" required>
<el-switch v-model="formData.enabled" :active-value="1" :inactive-value="0" />
</el-form-item>
</el-col>
</el-row>
</el-form>
<div slot="footer">
<el-button @click="close">{{ 'btn.cancel' | i18nFilter }}</el-button>
<el-button type="primary" @click="handelConfirm">{{ 'btn.confirm' | i18nFilter }}</el-button>
<!-- :loading="waiting" -->
</div>
</el-dialog>
</div>
</template>
<script>
import { addBOM } from '@/api/equipment/bom'
import { getDictDeviceTypePage, getDictBom } from '@/api/dict'
import i18n from '@/lang'
export default {
components: {},
inheritAttrs: false,
props: [],
data() {
return {
waiting: false,
formData: {
equipmentTypeId: undefined,
code: undefined,
name: undefined,
enabled: 1,
remark: undefined
},
rules: {
equipmentTypeId: [{
required: true,
message: i18n.t('module.equipmentManager.bom.placeholderEquipmentType'),
trigger: 'change'
}],
code: [{
required: false,
message: i18n.t('module.equipmentManager.bom.placeholderCode'),
trigger: 'blur'
}],
name: [{
required: true,
message: i18n.t('module.equipmentManager.bom.placeholderName'),
trigger: 'blur'
}],
remark: []
},
dict: {
device: [],
bom: []
}
}
},
computed: {},
watch: {},
created() {},
mounted() {
this.getDict()
},
methods: {
onOpen() {},
onClose() {
this.$refs['elForm'].resetFields()
},
close() {
this.$emit('update:visible', false)
},
handelConfirm() {
// this.waiting = true
this.$refs['elForm'].validate(async valid => {
if (!valid) {
// this.waiting = false
return
}
this.dict.bom.map(item => {
if (item.code === this.formData.code) {
this.formData.name = item.name
}
})
const result = await addBOM(this.formData)
// this.waiting = false
console.log(1)
if (result.code === 0) {
this.$message({
type: 'success',
message: '添加成功!'
})
this.$emit('done')
this.close()
}
})
},
async getDict() {
const result = await getDictDeviceTypePage({
current: 1,
size: 999
})
this.dict.device = result
const res = await getDictBom({
current: 1,
size: 999
})
this.dict.bom = res
}
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,359 @@
<!--
* @Date: 2021-01-12 09:37:27
* @LastEditors: fzq
* @LastEditTime: 2022-09-14 16:42:29
* @FilePath: \mt-bus-fe\src\views\EquipmentManager\BOMManager\EditForm.vue
* @Description: 物料BOM编辑弹窗页面
-->
<template>
<div>
<el-drawer v-bind="$attrs" :title="readonly ? $t('module.equipmentManager.bom.detailDialogTitle') : $t('module.equipmentManager.bom.editDialogTitle')" :show-close="false" :wrapper-closable="true" class="drawer" size="60%" v-on="$listeners" @open="onOpen" @close="onClose">
<span slot="title">
<small-title :no-padding="true">
<!-- {{ readonly ? 'btn.detail' : !dataForm.id ? 'btn.add' : 'btn.edit' | i18nFilter }} -->
{{ readonly ? $t('module.equipmentManager.bom.detailDialogTitle') : $t('module.equipmentManager.bom.editDialogTitle') }}
</small-title>
</span>
<el-divider />
<div class="content">
<div class="visual-part">
<el-form ref="elForm" :model="formData" :rules="rules" size="medium" label-position="top">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.bom.equipmentName')" prop="equipmentTypeId">
<el-select v-model="formData.equipmentTypeId" :placeholder="$t('module.equipmentManager.bom.placeholderequipmentName')" clearable :style="{width: '100%'}" :disabled="readonly">
<el-option
v-for="(item, index) in dict.device"
:key="index"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.bom.name')" prop="name">
<el-input v-model="formData.name" :placeholder="$t('module.equipmentManager.bom.name')" clearable :style="{width: '100%'}" :disabled="readonly" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.bom.code')" prop="code">
<el-input v-model="formData.code" :placeholder="$t('module.equipmentManager.bom.code')" clearable :style="{width: '100%'}" :disabled="readonly" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.bom.remark')" prop="remark">
<el-input v-model="formData.remark" :placeholder="$t('module.equipmentManager.bom.placeholderremark')" clearable :style="{width: '100%'}" :disabled="readonly" />
</el-form-item>
</el-col>
</el-row>
<el-form-item :label="$t('module.equipmentManager.bom.enabled')" prop="enabled" required>
<el-switch v-model="formData.enabled" :active-value="1" :inactive-value="0" :disabled="readonly" />
</el-form-item>
</el-form>
</div>
</div>
<template>
<!-- <el-divider>{{ $t('module.equipmentManager.bomdetail.title') }}</el-divider> -->
<!-- <div class="method-btn-area"> -->
<!-- <el-button v-if="!readonly" type="primary" style="float: right;margin: 0 20px;" @click="showDialog = true">{{ 'btn.add' | i18nFilter }}</el-button>
<el-button type="primary" plain icon="el-icon-arrow-left" @click="turnBack">{{ 'btn.back' | i18nFilter }}</el-button> -->
<!-- <el-button style="float: right;" @click="resetForm">重置</el-button> -->
<!-- </div> -->
<base-table
:top-btn-config="topBtnConfig"
:table-config="tableProps"
:table-data="list"
:is-loading="listLoading"
:page="listQuery.current"
:limit="listQuery.size"
@clickTopBtn="clickTopBtn"
>
<method-btn v-if="!readonly" slot="handleBtn" :width="80" :method-list="tableBtn" @clickBtn="handleClick" />
</base-table>
<pagination
v-show="total > 0"
:total="total"
:page-sizes="[3, 5, 10, 20]"
:page.sync="listQuery.current"
:limit.sync="listQuery.size"
@pagination="getList"
/>
</template>
<add-form :visible.sync="showDialog" :target-info="{id: listQuery.id}" @done="getList" />
<edit-form :visible.sync="showEditDialog" :target-info="{id: curEditId, fatherId: listQuery.id}" @done="getList" />
<div style="position: absolute; bottom: 24px; right: 24px;">
<el-button v-if="!readonly" @click="resetForm">{{ 'btn.reset' | i18nFilter }}</el-button>
<el-button v-if="readonly" type="primary" @click="close">{{ 'btn.confirm' | i18nFilter }}</el-button>
<el-button v-if="!readonly" type="primary" @click="handelConfirm">{{ 'btn.submit' | i18nFilter }}</el-button>
</div>
</el-drawer>
</div>
</template>
<script>
const topBtnConfig = [
{
type: 'add',
btnName: 'btn.add'
}
]
const tableBtn = [{
type: 'edit',
btnName: 'btn.edit'
}, {
type: 'delete',
btnName: 'btn.delete'
}]
const tableProps = [{
prop: 'materialCode',
label: i18n.t('module.equipmentManager.bomdetail.materialId'),
align: 'center'
}, {
prop: 'materialName',
label: i18n.t('module.equipmentManager.bomdetail.materialName'),
align: 'center'
}, {
prop: 'unit',
label: i18n.t('module.equipmentManager.bomdetail.unit'),
filter: newBasicData('1'),
align: 'center'
}, {
prop: 'quantity',
label: i18n.t('module.equipmentManager.bomdetail.quantity'),
align: 'center'
}, {
prop: 'remark',
label: i18n.t('module.equipmentManager.bomdetail.remark'),
align: 'center'
}]
import SmallTitle from '@/components/BaseDrawer/components/SmallTitle.vue'
import AddForm from './subpage/AddForm'
import EditForm from './subpage/EditForm'
import { getBOMInfo, editBOM, getDeviceBOMList, delDeviceBOM } from '@/api/equipment/bom'
import { getDictDeviceTypePage, getDictBom } from '@/api/dict'
import i18n from '@/lang'
import BaseTable from '@/components/BaseTable'
import MethodBtn from '@/components/BaseTable/subcomponents/MethodBtn'
import Pagination from '@/components/Pagination'
import newBasicData from '@/filters/newBasicData'
export default {
components: { Pagination, BaseTable, MethodBtn, AddForm, EditForm, SmallTitle },
inheritAttrs: false,
props: {
targetInfo: {
type: Object,
default: () => ({})
},
readonly: {
type: Boolean,
default: () => false
}
},
data() {
return {
topBtnConfig,
tableBtn,
tableProps,
list: [],
total: 0,
listLoading: true,
showDialog: false,
curEditId: null,
showEditDialog: false,
listQuery: {
enabled: 1,
id: null,
current: 1,
size: 3,
keywords: ''
},
formData: {
equipmentTypeId: undefined,
code: undefined,
name: undefined,
enabled: 1,
remark: undefined
},
rules: {
equipmentTypeId: [{
required: true,
message: i18n.t('module.equipmentManager.bom.placeholderEquipmentType'),
trigger: 'change'
}],
code: [{
required: false,
message: i18n.t('module.equipmentManager.bom.placeholderCode'),
trigger: 'blur'
}],
name: [{
required: true,
message: i18n.t('module.equipmentManager.bom.placeholderName'),
trigger: 'blur'
}],
remark: []
},
dict: {
device: [],
bom: []
}
}
},
computed: {},
watch: {},
// created() {},
// mounted() {
// this.getDict()
// },
created() {},
mounted() {},
methods: {
async onOpen() {
await this.getDict()
await this.getDetail()
await this.getList()
},
onClose() {
this.$refs['elForm'].resetFields()
},
close() {
this.$emit('update:visible', false)
},
handelConfirm() {
this.$refs['elForm'].validate(async valid => {
if (!valid) return
this.dict.bom.map(item => {
if (item.code === this.formData.code) {
this.formData.name = item.name
}
})
const result = await editBOM({
...this.formData,
// eslint-disable-next-line no-undef
id: this.targetInfo?.id
})
if (result.code === 0) {
this.$message({
type: 'success',
message: '修改成功!'
})
this.$emit('done')
this.close()
}
})
},
async getDetail() {
const result = await getBOMInfo({
// eslint-disable-next-line no-undef
id: this.targetInfo.id
})
if (result.code === 0) {
this.formData = result.data
// console.log(result)
}
},
async getDict() {
const result = await getDictDeviceTypePage({
current: 1,
size: 999
})
// console.log(result)
this.dict.device = result
const res = await getDictBom({
current: this.listQuery.current,
size: this.listQuery.size
})
this.dict.bom = res
},
async getList() {
this.listLoading = true
// edit here
this.listQuery.id = this.targetInfo.id
this.listQuery.keywords = this.targetInfo.id
// console.log(this.listQuery)
const res = await getDeviceBOMList(this.listQuery)
if (res.code === 0) {
this.list = res.data.records
this.total = res.data.total
this.listLoading = false
// console.log(res)
}
},
handleClick(raw) {
// console.log(raw)
switch (raw.type) {
case 'delete':
this.$confirm(i18n.t('deleteMsgBox.content'), i18n.t('deleteMsgBox.hint'), {
confirmButtonText: i18n.t('btn.confirm'),
cancelButtonText: i18n.t('btn.cancel'),
type: 'warning'
}).then(async() => {
// 走接口
const result = await delDeviceBOM({
id: raw.data.id
})
if (result.code === 0) {
this.$message({
type: 'success',
message: i18n.t('deleteMsgBox.doneMsg')
})
this.getList()
}
})
break
case 'edit':
this.showEditDialog = true
this.curEditId = raw.data.id
break
}
},
turnBack() {
this.$emit('update:visible', false)
},
clickTopBtn(val) {
if (val === 'add') {
this.showDialog = true// 新增
}
},
resetForm() {
this.$refs['elForm'].resetFields()
}
}
}
</script>
<style scoped>
.custom-dialog >>> .el-dialog__body {
padding: 30px 24px;
}
.drawer >>> .el-drawer {
border-radius: 8px 0 0 8px;
}
.drawer >>> .el-form-item__label {
padding: 0;
}
.drawer >>> .el-drawer__header {
padding: 0;
margin: 32px 0 8px 32px;
}
.drawer >>> .content {
padding: 0 24px 30px;
display: flex;
flex-direction: column;
height: 40%;
}
.drawer >>> .visual-part {
flex: 1 auto;
max-height: 76vh;
overflow: hidden;
overflow-y: scroll;
padding-right: 10px; /* 调整滚动条样式 */
}
</style>

View File

@@ -0,0 +1,31 @@
<!--
* @Date: 2021-02-20 10:45:21
* @LastEditors: gtz
* @LastEditTime: 2022-06-15 15:34:49
* @FilePath: \mt-bus-fe\src\views\EquipmentManager\BOMManager\components\statusBtn.vue
* @Description:
-->
<template>
<el-switch v-model="injectData.enabled" :active-value="1" :inactive-value="0" @change="changeStatus" />
</template>
<script>
import { editBOM } from '@/api/equipment/bom'
export default {
props: {
injectData: {
type: Object,
default: () => ({})
}
},
methods: {
async changeStatus() {
const result = await editBOM(this.injectData)
if (result.code === 0) {
this.$message.success(this.$t('module.equipmentManager.bom.succeeded'))
this.$emit('emitData')
}
}
}
}
</script>

View File

@@ -0,0 +1,211 @@
<!--
/*
* @Date: 2022-04-18
* @LastEditTime: 2022-08-03 09:55:20
* @LastEditors: fzq
* @FilePath: \mt-bus-fe\src\views\EquipmentManager\BOMManager\index.vue
* @Description:
*/
-->
<template>
<div class="app-container">
<!-- <top-title /> -->
<head-form
:form-config="headFormConfig"
@headBtnClick="btnClick"
/>
<base-table
:top-btn-config="topBtnConfig"
:table-config="tableProps"
:table-data="list"
:is-loading="listLoading"
:page="listQuery.current"
:limit="listQuery.size"
@clickTopBtn="clickTopBtn"
@emitFun="getList"
>
<method-btn slot="handleBtn" :width="120" :method-list="tableBtn" @clickBtn="handleClick" />
</base-table>
<pagination
v-show="total > 0"
:total="total"
:page.sync="listQuery.current"
:limit.sync="listQuery.size"
@pagination="getList()"
/>
<add-form :visible.sync="showDialog" @done="getList" />
<edit-form :visible.sync="showEditDialog" :readonly="readonly" :target-info="{id: curEditId}" @done="getList" />
<!-- <detail-form :visible.sync="showdetailDialog" :target-info="{id: curDetailId}" @done="getList" /> -->
</div>
</template>
<script>
import statusBtn from './components/statusBtn'
const topBtnConfig = [
{
type: 'add',
btnName: 'btn.add'
}
]
// edit here
const tableBtn = [{
type: 'edit',
btnName: 'btn.edit'
}, {
type: 'detail',
btnName: 'btn.detail'
}, {
type: 'delete',
btnName: 'btn.delete'
}
]
const tableProps = [{
prop: 'equipmentTypeCode',
label: i18n.t('module.equipmentManager.bom.equipmentCode')
}, {
prop: 'equipmentType',
label: i18n.t('module.equipmentManager.bom.equipmentName')
}, {
prop: 'code',
label: i18n.t('module.equipmentManager.bom.code')
}, {
prop: 'name',
label: i18n.t('module.equipmentManager.bom.name')
}, {
prop: 'enabled',
label: i18n.t('module.equipmentManager.bom.enabled'),
subcomponent: statusBtn
}, {
prop: 'remark',
label: i18n.t('module.equipmentManager.bom.remark')
}]
import AddForm from './AddForm'
import EditForm from './EditForm'
// import DetailForm from './subpage/detail'
// import TopTitle from '@/components/TopTitle'
import HeadForm from '@/components/basicData/HeadForm'
import BaseTable from '@/components/BaseTable'
// edit here
import { getBOMList, delBOM } from '@/api/equipment/bom'
// , getMaterialList
import { objFilter } from '@/utils'
import Pagination from '@/components/Pagination'
import MethodBtn from '@/components/BaseTable/subcomponents/MethodBtn'
import i18n from '@/lang'
export default {
name: 'OrgManager',
components: { HeadForm, Pagination, BaseTable, MethodBtn, AddForm, EditForm },
props: {},
data() {
return {
topBtnConfig,
tableBtn,
tableProps,
list: [],
total: 0,
listLoading: true,
showDialog: false,
curEditId: null,
curDetailId: null,
showDetailDialog: false,
showEditDialog: false,
readonly: false,
listQuery: {
current: 1,
size: 20,
keywords: ''
},
headFormConfig: [
{
type: 'input',
label: i18n.t('module.basicData.visual.keyword'),
placeholder: this.$t('module.equipmentManager.bom.searchPlaceholder'),
param: 'keywords'
},
{
type: 'button',
btnName: 'btn.search',
name: 'search',
color: 'primary'
}
],
headFormValue: {}
}
},
created() {
this.getList()
// this.listLoading = false
},
mounted() {},
methods: {
handleClick(raw) {
switch (raw.type) {
case 'delete':
this.$confirm(i18n.t('deleteMsgBox.content'), i18n.t('deleteMsgBox.hint'), {
confirmButtonText: i18n.t('btn.confirm'),
cancelButtonText: i18n.t('btn.cancel'),
type: 'warning'
}).then(async() => {
// 走接口
const result = await delBOM({
id: raw.data.id
})
if (result.code === 0) {
this.$message({
type: 'success',
message: i18n.t('deleteMsgBox.doneMsg')
})
this.getList()
}
})
break
case 'edit':
this.showEditDialog = true
this.readonly = false
this.curEditId = raw.data.id
break
case 'detail':
// this.$router.push({
// name: 'DeviceBOMManage',
// query: {
// id: raw.data.id
// }
// })
// this.showDetailDialog = true
// this.curDetailId = raw.data.id
this.showEditDialog = true
this.readonly = true
this.curEditId = raw.data.id
break
}
},
async getList() {
this.listLoading = true
// edit here
this.listQuery.keywords = this.headFormValue.keywords
const res = await getBOMList(objFilter(this.listQuery))
if (res.code === 0) {
this.list = res.data.records ? res.data.records : []
this.total = res.data.total
this.listLoading = false
}
},
btnClick(val) {
this.headFormValue = val
// 如果点击的是搜索栏的其他按钮在这里继续写判断
if (this.headFormValue.btnName === 'search') {
this.getList()
}
},
clickTopBtn(val) {
if (val === 'add') {
this.showDialog = true// 新增
}
}
}
}
</script>
<style lang="scss" scoped>
</style>

View File

@@ -0,0 +1,176 @@
<!--
* @Date: 2021-01-09 16:25:11
* @LastEditors: fzq
* @LastEditTime: 2022-09-13 16:01:10
* @FilePath: \mt-bus-fe\src\views\EquipmentManager\BOMManager\subpage\AddForm.vue
* @Description: 子页面
-->
<template>
<div>
<el-dialog v-bind="$attrs" :title="$t('module.equipmentManager.bomdetail.addDialogTitle')" class="dialog" width="45%" append-to-body v-on="$listeners" @open="onOpen" @close="onClose">
<el-form ref="elForm" :model="formData" :rules="rules" size="medium" label-width="90px">
<el-row :gutter="20">
<!-- 物料名称 -->
<el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.bomdetail.materialName')" prop="materialId">
<el-select v-model="formData.materialId" :placeholder="$t('module.equipmentManager.bomdetail.placeholdermaterialName')" clearable :style="{width: '100%'}" @change="handleMaterialChange">
<el-option
v-for="(item, index) in dict.material"
:key="index"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
</el-col>
<!-- 单位 -->
<el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.bomdetail.unit')" prop="unit">
<el-select v-model="formData.unit" :placeholder="$t('module.equipmentManager.bomdetail.placeholderunit')" disabled :style="{width: '100%'}">
<el-option
v-for="(item, index) in dict.unit"
:key="index"
:label="item.dataName"
:value="item.dataCode"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<!-- 数量 -->
<el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.bomdetail.quantity')" prop="quantity">
<el-input v-model="formData.quantity" type="number" :placeholder="$t('module.equipmentManager.bomdetail.placeholderquantity')" :min="0" clearable :style="{width: '100%'}" />
</el-form-item>
</el-col>
<!-- 状态 -->
<el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.bomdetail.remark')" prop="remark">
<el-input v-model="formData.remark" :placeholder="$t('module.equipmentManager.bomdetail.placeholderremark')" clearable :style="{width: '100%'}" />
</el-form-item>
</el-col>
</el-row>
</el-form>
<div slot="footer">
<el-button @click="close">{{ 'btn.cancel' | i18nFilter }}</el-button>
<el-button type="primary" :loading="waiting" @click="handelConfirm">{{ 'btn.confirm' | i18nFilter }}</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { addDeviceBOM } from '@/api/equipment/bom'
import { getDictMaterial } from '@/api/dict'
import i18n from '@/lang'
export default {
components: {},
inheritAttrs: false,
props: {
targetInfo: {
type: Object,
default: () => ({})
}
},
data() {
return {
waiting: false,
formData: {
materialId: null,
unit: undefined,
quantity: undefined,
remark: undefined,
equipmentBomId: undefined
},
rules: {
materialId: [{
required: true,
message: i18n.t('module.equipmentManager.bomdetail.placeholdermaterialName'),
trigger: 'change'
}],
unit: [{
required: true,
message: i18n.t('module.equipmentManager.bomdetail.placeholderunit'),
trigger: 'blur'
}],
quantity: [{
required: true,
trigger: 'blur',
validator: (rule, value, callback) => {
if (value) {
if (value <= 0) {
callback(new Error('数量应该为正值'))
} else {
callback()
}
} else {
callback(new Error('请输入数字'))
}
}
}],
remark: [{
required: false,
message: i18n.t('module.equipmentManager.bomdetail.placeholderremark'),
trigger: 'blur'
}]
},
dict: {
material: [],
unit: JSON.parse(localStorage.getItem('dictObj'))['1']
}
}
},
computed: {},
watch: {},
created() {
this.getDict()
},
mounted() {},
methods: {
onOpen() {
this.formData.equipmentBomId = this.targetInfo.id
},
onClose() {
this.$refs['elForm'].resetFields()
},
close() {
this.$emit('update:visible', false)
},
handleMaterialChange(mid) {
const m = this.dict.material.find(item => item.id === mid)
if (m) {
this.formData.unit = m.unit || ''
console.log('unit', m.unit, this.dict.unit)
} else {
this.formData.unit = ''
}
},
handelConfirm() {
this.waiting = true
this.$refs['elForm'].validate(async valid => {
if (!valid) {
this.waiting = false
return
}
const result = await addDeviceBOM(this.formData)
this.waiting = false
if (result.code === 0) {
this.$message({
type: 'success',
message: '添加成功!'
})
this.$emit('done')
this.close()
}
})
},
async getDict() {
const result = await getDictMaterial()
this.dict.material = result
}
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,184 @@
<!--
* @Date: 2021-01-09 16:25:11
* @LastEditors: fzq
* @LastEditTime: 2022-09-14 10:51:51
* @FilePath: \mt-bus-fe\src\views\EquipmentManager\BOMManager\subpage\EditForm.vue
* @Description: 子页面
-->
<template>
<div>
<!-- append-to-body 可以解决新增/编辑导致的不高亮 -->
<el-dialog v-bind="$attrs" :title="$t('module.equipmentManager.bomdetail.editDialogTitle')" class="dialog" width="45%" append-to-body v-on="$listeners" @open="onOpen" @close="onClose">
<el-form ref="elForm" :model="formData" :rules="rules" size="medium" label-width="90px">
<el-row :gutter="20">
<!-- 物料名称 -->
<el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.bomdetail.materialName')" prop="materialId">
<el-select v-model="formData.materialId" :placeholder="$t('module.equipmentManager.bomdetail.placeholdermaterialName')" clearable :style="{width: '100%'}" @change="handleMaterialChange">
<el-option
v-for="(item, index) in dict.material"
:key="index"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
</el-col>
<!-- 单位 -->
<el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.bomdetail.unit')" prop="unit">
<el-select v-model="formData.unit" :placeholder="$t('module.equipmentManager.bomdetail.placeholderunit')" disabled :style="{width: '100%'}">
<el-option
v-for="(item, index) in dict.unit"
:key="index"
:label="item.dataName"
:value="item.dataCode"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<!-- 数量 -->
<el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.bomdetail.quantity')" prop="quantity">
<el-input v-model="formData.quantity" :placeholder="$t('module.equipmentManager.bomdetail.placeholderquantity')" clearable :style="{width: '100%'}" />
</el-form-item>
</el-col>
<!-- 备注 -->
<el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.bomdetail.remark')" prop="remark">
<el-input v-model="formData.remark" :placeholder="$t('module.equipmentManager.bomdetail.placeholderremark')" clearable :style="{width: '100%'}" />
</el-form-item>
</el-col>
</el-row>
</el-form>
<div slot="footer">
<el-button @click="close">{{ 'btn.cancel' | i18nFilter }}</el-button>
<el-button type="primary" @click="handelConfirm">{{ 'btn.confirm' | i18nFilter }}</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { editDeviceBOM, getDeviceBOMInfo } from '@/api/equipment/bom'
import { getDictMaterial } from '@/api/dict'
export default {
components: {},
inheritAttrs: false,
props: {
targetInfo: {
type: Object,
default: () => ({})
}
},
data() {
return {
formData: {
materialId: undefined,
unit: undefined,
quantity: undefined,
remark: undefined,
id: undefined,
equipmentId: undefined
},
rules: {
materialId: [{
required: true,
message: '请输入物料名称',
trigger: 'change'
}],
unit: [{
required: true,
message: '请输入单位',
trigger: 'blur'
}],
quantity: [{
required: true,
trigger: 'blur',
validator: (rule, value, callback) => {
if (value) {
if (value <= 0) {
callback(new Error('数量应该为正值'))
} else {
callback()
}
} else {
callback(new Error('请输入数字'))
}
}
}],
remark: [{
required: false,
message: '请输入备注',
trigger: 'blur'
}]
},
dict: {
// unit: JSON.parse(localStorage.getItem('dictObj'))['1392033901169348609'],
unit: JSON.parse(localStorage.getItem('dictObj'))['1'],
material: []
}
}
},
computed: {},
watch: {},
created() {
},
mounted() {
this.getDict()
},
methods: {
onOpen() {
this.formData
this.getInfo()
},
onClose() {
this.$refs['elForm'].resetFields()
},
close() {
this.$emit('update:visible', false)
},
handleMaterialChange(mid) {
const m = this.dict.material.find(item => item.id === mid)
if (m) {
this.formData.unit = m.unit || ''
} else {
this.formData.unit = ''
}
},
handelConfirm() {
this.$refs['elForm'].validate(async valid => {
if (!valid) return
const result = await editDeviceBOM(this.formData)
console.log(this.formData)
if (result.code === 0) {
this.$message({
type: 'success',
message: '修改成功!'
})
this.$emit('done')
this.close()
}
})
},
async getInfo() {
const result = await getDeviceBOMInfo({
id: this.targetInfo.id
})
// console.log(result)
if (result.code === 0) {
this.formData = result.data
console.log(result)
}
},
async getDict() {
const result = await getDictMaterial()
this.dict.material = result
}
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,232 @@
<!--
* @Date: 2020-12-15 15:36:52
* @LastEditors: fzq
* @LastEditTime: 2022-07-27 17:05:21
* @FilePath: \mt-bus-fe\src\views\EquipmentManager\BOMManager\subpage\detail.vue
* @Description:
-->
<template>
<div class="bom-form-container">
<el-form ref="elForm" :model="formData" size="medium" label-width="150px">
<el-form-item :label="$t('module.equipmentManager.bom.equipmentName')" prop="equipmentTypeName">
<el-input :value="equipmentTypeName" :style="{width: '100%'}" :disabled="pagetype" />
</el-form-item>
<el-form-item :label="$t('module.equipmentManager.bom.code')" prop="code">
<el-input v-model="formData.code" :style="{width: '100%'}" :disabled="pagetype" />
</el-form-item>
<el-form-item :label="$t('module.equipmentManager.bom.name')" prop="name">
<el-input v-model="formData.name" :style="{width: '100%'}" :disabled="pagetype" />
</el-form-item>
<el-form-item :label="$t('module.equipmentManager.bom.enabled')" prop="enabled" required>
<el-switch v-model="formData.enabled" :disabled="pagetype" :active-value="1" :inactive-value="0" />
</el-form-item>
<el-form-item :label="$t('module.equipmentManager.bom.remark')" prop="remark">
<el-input v-model="formData.remark" :style="{width: '100%'}" :disabled="pagetype" />
</el-form-item>
</el-form>
<div class="sub-table-container">
<el-divider>{{ $t('module.equipmentManager.bomdetail.title') }}</el-divider>
<div class="method-btn-area">
<el-button type="primary" style="float: right;margin: 0 20px;" @click="showDialog = true">{{ 'btn.add' | i18nFilter }}</el-button>
<el-button type="primary" plain icon="el-icon-arrow-left" @click="turnBack">{{ 'btn.back' | i18nFilter }}</el-button>
<!-- <el-button style="float: right;" @click="resetForm">重置</el-button> -->
</div>
<base-table :table-config="tableProps" :table-data="list" :is-loading="listLoading" :page="listQuery.current" :limit="listQuery.size">
<method-btn slot="handleBtn" :width="80" :method-list="tableBtn" @clickBtn="handleClick" />
</base-table>
</div>
<pagination v-show="total > listQuery.size" :total="total" :page.sync="listQuery.current" :limit.sync="listQuery.size" @pagination="getList" />
<add-form :visible.sync="showDialog" :target-info="{id: listQuery.id}" @done="getList" />
<edit-form :visible.sync="showEditDialog" :target-info="{id: curEditId, fatherId: listQuery.id}" @done="getList" />
</div>
</template>
<script>
// import CheckDetail from '@/components/BaseTable/subcomponents/CheckDetail'
// import dataDict from '@/filters/DataDict'
// edit here
const tableBtn = [{
type: 'edit',
btnName: 'btn.edit'
}, {
type: 'delete',
btnName: 'btn.delete'
}]
const tableProps = [{
prop: 'materialCode',
label: i18n.t('module.equipmentManager.bomdetail.materialId'),
align: 'center'
}, {
prop: 'materialName',
label: i18n.t('module.equipmentManager.bomdetail.materialName'),
align: 'center'
}, {
prop: 'unit',
label: i18n.t('module.equipmentManager.bomdetail.unit'),
align: 'center'
}, {
prop: 'quantity',
label: i18n.t('module.equipmentManager.bomdetail.quantity'),
align: 'center'
}, {
prop: 'remark',
label: i18n.t('module.equipmentManager.bomdetail.remark'),
align: 'center'
}]
import AddForm from './AddForm'
import EditForm from './EditForm'
import BaseTable from '@/components/BaseTable'
// edit here
// import { objFilter } from '@/utils'
import { getDeviceBOMList, delDeviceBOM, getBOMInfo } from '@/api/equipment/bom'
import { getDictDevice } from '@/api/dict'
import { dictChange, dictFilter } from '@/utils'
import Pagination from '@/components/Pagination'
import MethodBtn from '@/components/BaseTable/subcomponents/MethodBtn'
import i18n from '@/lang'
export default {
name: 'BOMForm',
components: { Pagination, BaseTable, MethodBtn, AddForm, EditForm },
props: {},
data() {
return {
tableBtn,
tableProps,
list: [],
total: 0,
listLoading: true,
showDialog: false,
curEditId: null,
showEditDialog: false,
listQuery: {
enabled: 1,
id: null,
current: 1,
size: 10,
keywords: ''
},
equipmentName: undefined,
formData: {
equipmentCode: undefined,
code: undefined,
name: undefined,
enabled: 1,
remark: undefined
},
dict: {
deviceTable: {}
}
}
},
computed: {
pagetype() {
return true
// return false
}
},
async created() {
console.log(this.$route.query)
this.listQuery.id = this.$route.query.id
this.listQuery.keywords = this.$route.query.id
await this.getDict()
await this.getDetail()
await this.getList()
// this.listLoading = false
},
mounted() {},
methods: {
handleClick(raw) {
console.log(raw)
switch (raw.type) {
case 'delete':
this.$confirm(i18n.t('deleteMsgBox.content'), i18n.t('deleteMsgBox.hint'), {
confirmButtonText: i18n.t('btn.confirm'),
cancelButtonText: i18n.t('btn.cancel'),
type: 'warning'
}).then(async() => {
// 走接口
const result = await delDeviceBOM({
id: raw.data.id
})
if (result.code === 0) {
this.$message({
type: 'success',
message: i18n.t('deleteMsgBox.doneMsg')
})
this.getList()
}
})
break
case 'edit':
this.showEditDialog = true
this.curEditId = raw.data.id
break
}
},
async getList() {
this.listLoading = true
// edit here
const res = await getDeviceBOMList(this.listQuery)
if (res.code === 0) {
this.list = res.data.records
this.total = res.data.total
this.listLoading = false
}
},
async getDetail() {
const result = await getBOMInfo({
id: this.listQuery.id
})
if (result.code === 0) {
this.formData = result.data
this.equipmentName = dictFilter(this.dict.deviceTable, { key: 'id', value: 'name' })(result.data.equipmentId)
// console.log(result)
}
},
submitForm() {
this.$refs['elForm'].validate(valid => {
if (!valid) return
// TODO 提交表单
})
},
resetForm() {
this.$refs['elForm'].resetFields()
},
saveForm() {},
async getDict() {
const result = await getDictDevice({
current: 1,
size: 999
})
this.dict.deviceTable = dictChange(result, { key: 'id', value: 'name' })
},
turnBack() {
this.$router.go(-1)
}
}
}
</script>
<style lang="scss" scoped>
@import "@/styles/mixin.scss";
.bom-form-container {
padding: 20px;
.method-btn-area {
padding: 15px 30px;
margin: 10px 0 20px 0;
border: 1px solid #dfe6ec;
@include clearfix;
}
.sub-table-container {
margin-top: 80px;
}
}
.edit-input {
padding-right: 100px;
}
.cancel-btn {
position: absolute;
right: 15px;
top: 10px;
}
</style>

View File

@@ -0,0 +1,203 @@
<template>
<div>
<el-dialog v-bind="$attrs" title="添加备品备件" v-on="$listeners" @open="onOpen" @close="onClose">
<el-form ref="elForm" :model="formData" :rules="rules" size="medium" label-width="100px">
<el-form-item label="备件编码" prop="name">
<el-input v-model="formData.code" placeholder="请输入备件编码" clearable :style="{width: '100%'}" />
</el-form-item>
<el-form-item label="备件名称" prop="name">
<el-input v-model="formData.name" placeholder="请输入备件名称" clearable :style="{width: '100%'}" />
</el-form-item>
<el-form-item label="备件型号" prop="sparePartModel">
<el-input
v-model="formData.sparePartModel"
placeholder="请输入备件型号"
clearable
:style="{width: '100%'}"
/>
</el-form-item>
<el-form-item label="外部编码" prop="externalCode">
<el-input
v-model="formData.externalCode"
placeholder="请输入备件型号"
clearable
:style="{width: '100%'}"
/>
</el-form-item>
<el-form-item label="单位" prop="accessoryUnit">
<el-select v-model="formData.accessoryUnit" placeholder="请选择单位" clearable :style="{width: '100%'}">
<el-option
v-for="(item, index) in accessoryUnitOptions"
:key="index"
:label="item.label"
:value="item.value"
:disabled="item.disabled"
/>
</el-select>
</el-form-item>
<el-form-item label="批次号" prop="batchNumber">
<el-input v-model="formData.batchNumber" type="number" placeholder="请输入批次号" clearable :style="{width: '100%'}" />
</el-form-item>
<el-form-item label="数量" prop="accessoryNumber">
<el-input v-model="formData.accessoryNumber" type="number" placeholder="请输入数量" clearable :style="{width: '100%'}" />
</el-form-item>
<el-form-item label="进厂时间" prop="entryTime">
<el-date-picker
v-model="formData.entryTime"
format="yyyy-MM-dd"
:style="{width: '100%'}"
placeholder="请选择进厂时间"
clearable
/>
</el-form-item>
<el-form-item label="供应商" prop="supplierId">
<el-select v-model="formData.supplierId" placeholder="请选择供应商" clearable :style="{width: '100%'}">
<el-option
v-for="(item, index) in supplierIdOptions"
:key="index"
:label="item.label"
:value="item.value"
:disabled="item.disabled"
/>
</el-select>
</el-form-item>
<el-form-item label="接收人" prop="receiver">
<el-input v-model="formData.receiver" placeholder="请输入接收人" clearable :style="{width: '100%'}" />
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="formData.remark" placeholder="请输入备注" clearable :style="{width: '100%'}" />
</el-form-item>
</el-form>
<div slot="footer">
<el-button @click="close">{{ 'btn.cancel' | i18nFilter }}</el-button>
<el-button type="primary" @click="handelConfirm">{{ 'btn.confirm' | i18nFilter }}</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { addSapre } from '@/api/equipment/spare'
export default {
components: {},
inheritAttrs: false,
props: [],
data() {
return {
formData: {
code: undefined,
name: undefined,
sparePartModel: undefined,
accessoryUnit: undefined,
batchNumber: undefined,
accessoryNumber: undefined,
entryTime: null,
supplierId: undefined,
receiver: undefined,
remark: undefined,
externalCode: undefined
},
rules: {
code: [{
required: false,
message: '请输入备件编码',
trigger: 'blur'
}],
name: [{
required: true,
message: '请输入备件名称',
trigger: 'blur'
}],
sparePartModel: [{
required: true,
message: '请输入备件型号',
trigger: 'blur'
}],
accessoryUnit: [{
required: true,
message: '请选择单位',
trigger: 'change'
}],
externalCode: [{
required: true,
message: '请输入外部编码',
trigger: 'blur'
}],
batchNumber: [{
required: true,
message: '请输入批次号',
trigger: 'blur'
}],
accessoryNumber: [{
required: true,
message: '请输入数量',
trigger: 'blur'
}],
entryTime: [{
required: true,
message: '请选择进厂时间',
trigger: 'change'
}],
supplierId: [{
required: true,
message: '请选择供应商',
trigger: 'change'
}],
receiver: [{
required: true,
message: '请输入接收人',
trigger: 'blur'
}],
remark: [{
required: false,
message: '请输入备注',
trigger: 'blur'
}]
},
accessoryUnitOptions: [{
'label': '选项一',
'value': 1
}, {
'label': '选项二',
'value': 2
}],
supplierIdOptions: [{
'label': '选项一',
'value': 1
}, {
'label': '选项二',
'value': 2
}]
}
},
computed: {},
watch: {},
created() {},
mounted() {},
methods: {
onOpen() {},
onClose() {
this.$refs['elForm'].resetFields()
},
close() {
this.$emit('update:visible', false)
},
handelConfirm() {
this.$refs['elForm'].validate(async valid => {
if (!valid) return
const result = await addSapre(this.formData)
if (result.code === 0) {
this.$message({
type: 'success',
message: '添加成功!'
})
this.$emit('done')
this.close()
}
})
}
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,222 @@
<template>
<div>
<el-dialog v-bind="$attrs" title="编辑备品备件" v-on="$listeners" @open="onOpen" @close="onClose">
<el-form ref="elForm" :model="formData" :rules="rules" size="medium" label-width="100px">
<el-form-item label="备件编码" prop="name">
<el-input v-model="formData.code" placeholder="请输入备件编码" clearable :style="{width: '100%'}" />
</el-form-item>
<el-form-item label="备件名称" prop="name">
<el-input v-model="formData.name" placeholder="请输入备件名称" clearable :style="{width: '100%'}" />
</el-form-item>
<el-form-item label="备件型号" prop="sparePartModel">
<el-input
v-model="formData.sparePartModel"
placeholder="请输入备件型号"
clearable
:style="{width: '100%'}"
/>
</el-form-item>
<el-form-item label="外部编码" prop="externalCode">
<el-input
v-model="formData.externalCode"
placeholder="请输入备件型号"
clearable
:style="{width: '100%'}"
/>
</el-form-item>
<el-form-item label="单位" prop="accessoryUnit">
<el-select v-model="formData.accessoryUnit" placeholder="请选择单位" clearable :style="{width: '100%'}">
<el-option
v-for="(item, index) in accessoryUnitOptions"
:key="index"
:label="item.label"
:value="item.value"
:disabled="item.disabled"
/>
</el-select>
</el-form-item>
<el-form-item label="批次号" prop="batchNumber">
<el-input v-model="formData.batchNumber" type="number" placeholder="请输入批次号" clearable :style="{width: '100%'}" />
</el-form-item>
<el-form-item label="数量" prop="accessoryNumber">
<el-input v-model="formData.accessoryNumber" type="number" placeholder="请输入数量" clearable :style="{width: '100%'}" />
</el-form-item>
<el-form-item label="进厂时间" prop="entryTime">
<el-date-picker
v-model="formData.entryTime"
format="yyyy-MM-dd"
:style="{width: '100%'}"
placeholder="请选择进厂时间"
clearable
/>
</el-form-item>
<el-form-item label="供应商" prop="supplierId">
<el-select v-model="formData.supplierId" placeholder="请选择供应商" clearable :style="{width: '100%'}">
<el-option
v-for="(item, index) in supplierIdOptions"
:key="index"
:label="item.label"
:value="item.value"
:disabled="item.disabled"
/>
</el-select>
</el-form-item>
<el-form-item label="接收人" prop="receiver">
<el-input v-model="formData.receiver" placeholder="请输入接收人" clearable :style="{width: '100%'}" />
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="formData.remark" placeholder="请输入备注" clearable :style="{width: '100%'}" />
</el-form-item>
</el-form>
<div slot="footer">
<el-button @click="close">{{ 'btn.cancel' | i18nFilter }}</el-button>
<el-button type="primary" @click="handelConfirm">{{ 'btn.confirm' | i18nFilter }}</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { getSpareInfo, editSpare } from '@/api/equipment/spare'
export default {
components: {},
inheritAttrs: false,
props: {
targetInfo: {
type: Object,
default: () => ({})
}
},
data() {
return {
formData: {
code: undefined,
name: undefined,
sparePartModel: undefined,
accessoryUnit: undefined,
batchNumber: undefined,
accessoryNumber: undefined,
entryTime: null,
supplierId: undefined,
receiver: undefined,
remark: undefined,
externalCode: undefined
},
rules: {
code: [{
required: true,
message: '请输入备件编码',
trigger: 'blur'
}],
externalCode: [{
required: true,
message: '请输入外部编码',
trigger: 'blur'
}],
name: [{
required: true,
message: '请输入备件名称',
trigger: 'blur'
}],
sparePartModel: [{
required: true,
message: '请输入备件型号',
trigger: 'blur'
}],
accessoryUnit: [{
required: true,
message: '请选择单位',
trigger: 'change'
}],
batchNumber: [{
required: true,
message: '请输入批次号',
trigger: 'blur'
}],
accessoryNumber: [{
required: true,
message: '请输入数量',
trigger: 'blur'
}],
entryTime: [{
required: true,
message: '请选择进厂时间',
trigger: 'change'
}],
supplierId: [{
required: true,
message: '请选择供应商',
trigger: 'change'
}],
receiver: [{
required: true,
message: '请输入接收人',
trigger: 'blur'
}],
remark: [{
required: false,
message: '请输入备注',
trigger: 'blur'
}]
},
accessoryUnitOptions: [{
'label': '选项一',
'value': 1
}, {
'label': '选项二',
'value': 2
}],
supplierIdOptions: [{
'label': '选项一',
'value': 1
}, {
'label': '选项二',
'value': 2
}]
}
},
computed: {},
watch: {},
created() {},
mounted() {},
methods: {
onOpen() {
this.getDetail()
},
onClose() {
this.$refs['elForm'].resetFields()
},
close() {
this.$emit('update:visible', false)
},
handelConfirm() {
this.$refs['elForm'].validate(async valid => {
if (!valid) return
const result = await editSpare({
...this.formData,
id: this.targetInfo?.id
})
if (result.code === 0) {
this.$message({
type: 'success',
message: '修改成功!'
})
this.$emit('done')
this.close()
}
})
},
async getDetail() {
const result = await getSpareInfo({
id: this.targetInfo?.id
})
if (result.code === 0) {
this.formData = result.data
// console.log(result)
}
}
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,167 @@
<!--
* @Date: 2020-12-15 15:36:52
* @LastEditors: guo
* @LastEditTime: 2021-03-20 17:51:55
* @FilePath: \basic-admin\src\views\EquipmentManager\DeviceMonitoring\index.vue
* @Description:
-->
<template>
<div class="usermanager-container">
<div class="method-btn-area">
<el-input v-model="listQuery.keywords" :placeholder="$t('module.equipmentManager.monitoring.searchPlaceholder')" style="width: 200px;" clearable />
<el-button @click="getList">{{ 'btn.search' | i18nFilter }}</el-button>
<!-- <el-button type="primary" @click="showDialog = true">{{ 'btn.add' | i18nFilter }}</el-button> -->
</div>
<base-table :table-config="tableProps" :table-data="list" :is-loading="listLoading" :page="listQuery.current" :limit="listQuery.size">
<method-btn slot="handleBtn" :method-list="tableBtn" @clickBtn="handleClick" />
</base-table>
<pagination v-show="total > listQuery.size" :total="total" :page.sync="listQuery.current" :limit.sync="listQuery.size" @pagination="getList" />
<add-form :visible.sync="showDialog" @done="getList" />
<edit-form :visible.sync="showEditDialog" :target-info="{id: curEditId}" @done="getList" />
</div>
</template>
<script>
// import dataDict from '@/filters/DataDict'
// edit here
import { timeFormatter } from '@/filters'
const statusTableFilter = value => {
const table = {
'0': 'productive',
'1': 'standby',
'2': 'unscheduled downtime',
'3': 'scheduled downtime',
'4': 'engineering',
'5': 'non-scheduled'
}
return table[value] ? table[value] : value
}
const tableBtn = [{
type: 'detail',
btnName: 'btn.detail'
}]
const tableProps = [{
prop: 'code',
label: i18n.t('module.equipmentManager.monitoring.code'),
align: 'center'
}, {
prop: 'name',
label: i18n.t('module.equipmentManager.monitoring.name'),
align: 'center'
}, {
prop: 'status',
label: i18n.t('module.equipmentManager.monitoring.status'),
align: 'center',
filter: statusTableFilter
}, {
prop: 'startTime',
label: i18n.t('module.equipmentManager.monitoring.startTime'),
align: 'center',
filter: timeFormatter
// filter: dataDict('enableState')
}, {
prop: 'totalCount',
label: i18n.t('module.equipmentManager.monitoring.totalCount'),
align: 'center'
}, {
prop: 'repairTime',
label: i18n.t('module.equipmentManager.monitoring.repairTime'),
align: 'center',
filter: timeFormatter
}]
import AddForm from './AddForm'
import EditForm from './EditForm'
import BaseTable from '@/components/BaseTable'
// edit here
import { getDeviceMonitoringList } from '@/api/equipment/monitoring'
import { getDictSupplier } from '@/api/dict/index'
import { dictChange, dictFilter } from '@/utils'
import Pagination from '@/components/Pagination'
import MethodBtn from '@/components/BaseTable/subcomponents/MethodBtn'
import i18n from '@/lang'
export default {
name: 'OrgManager',
components: { Pagination, BaseTable, MethodBtn, AddForm, EditForm },
props: {},
data() {
return {
tableBtn,
tableProps: [],
list: [],
total: 0,
listLoading: true,
showDialog: false,
curEditId: null,
showEditDialog: false,
listQuery: {
current: 1,
size: 10,
keywords: ''
},
dict: {
supplier: []
}
}
},
async created() {
await this.getDict()
await this.preprocess()
await this.getList()
// this.listLoading = false
},
mounted() {},
methods: {
handleClick(raw) {
console.log(raw)
switch (raw.type) {
case 'detail':
// this.showEditDialog = true
this.curEditId = raw.data.id
break
}
},
async getList() {
this.listLoading = true
// edit here
const res = await getDeviceMonitoringList(this.listQuery)
if (res.code === 0) {
this.list = res.data
this.total = res.data.total
this.listLoading = false
}
},
async getDict() {
const result = await getDictSupplier()
this.dict.supplier = result.data
},
async preprocess() {
this.tableProps = tableProps.map(item => {
if (this.dict[item.prop]) {
console.log(dictChange(this.dict[item.prop], { key: 'id', value: 'name' }))
item.filter = dictFilter(dictChange(this.dict[item.prop], { key: 'id', value: 'name' }))
}
return item
})
}
}
}
</script>
<style lang="scss" scoped>
.usermanager-container {
padding: 20px;
.method-btn-area {
padding: 15px 30px;
margin: 10px 0 20px 0;
border: 1px solid #dfe6ec;
}
}
.edit-input {
padding-right: 100px;
}
.cancel-btn {
position: absolute;
right: 15px;
top: 10px;
}
</style>

View File

@@ -0,0 +1,422 @@
<template>
<div ref="cockpit-container-equipment" class="visual-container">
<techy-header :head-title="'合肥新能源数字工厂设备管理驾驶舱'" @toggle-full-screen="changeFullScreen" />
<!-- <section class="techy-body" :key="refreshKey"> -->
<section class="techy-body">
<div class="tech-body__col-1">
<div class="row-1">
<div class="equipment-exception">
<!-- 设备报修/异常上报 -->
<techy-container :title="'设备报修/异常上报'" :icon="equipmentExceptionSVG">
<div class="table-wrapper">
<techy-table
:page="1"
:limit="7"
:show-index="false"
:table-config="equipmentExceptionProps"
:table-data="equipmentExceptionDatalist"
/>
</div>
</techy-container>
</div>
<div class="equipment-alarm">
<!-- 设备异常报警 -->
<techy-container :title="'设备异常报警'" :icon="equipmentAlarmSVG">
<div class="table-wrapper">
<techy-table
:page="1"
:limit="7"
:show-index="false"
:table-config="equipmentAlarmProps"
:table-data="equipmentAlarmDatalist"
/>
</div>
</techy-container>
</div>
</div>
<div class="row-2">
<!-- 设备分析 -->
<techy-container :title="'设备分析'" :icon="equipmentAnalysisSVG">
<select id="productLine" name="productLine" class="product-line-selection">
<option value="1">产线一</option>
<option value="2">产线二</option>
<option value="3">产线三</option>
</select>
<div class="grid columns-2" style="height: calc(100% - 32px)">
<div class="pl-jdl">
<TechyBox style="padding: calc(100vh / 1920 * 24)">
<h2
:style="{
margin: 0,
padding: 0,
fontWeight: 'normal',
color: '#01CFCC',
lineHeight: '18px',
fontSize: '0.85vw'
}"
>
<!-- fontSize: '15px', -->
各产线稼动率
</h2>
<pl-jdl-chart />
</TechyBox>
</div>
<div class="eqs-oee-mtbr-btbf grid grid-2-3">
<EquipmentAnalysisBox
v-for="(item, index) in equipmentAnalysisData"
:key="index"
:name="item.name"
:oee="item.oee"
:mtbf="item.mtbf"
:mtbr="item.mtbr"
/>
</div>
</div>
</techy-container>
</div>
<div class="row-3">
<!-- 设备备件管理 -->
<techy-container :title="'设备备件管理'" :icon="equipmentOrderSVG">
<techy-table
:page="1"
:limit="7"
:show-index="false"
:table-config="sparepartsProps"
:table-data="sparepartsDatalist"
/>
</techy-container>
</div>
</div>
<div class="tech-body__col-2">
<techy-container :title="'设备工单管理'" :icon="equipmentOrderSVG">
<!-- 设备工单管理 -->
<div class="techy-container__inner">
<div>
<TechyAnalysisHeader>突发性维护</TechyAnalysisHeader>
<TechyVerticalTable :table-props="rightSideProps" :data-list="rightSideDatalist" />
</div>
<div>
<TechyAnalysisHeader>计划内保养</TechyAnalysisHeader>
<TechyVerticalTable :table-props="rightSideProps" :data-list="rightSideDatalist" />
</div>
<div>
<TechyAnalysisHeader>防御性维护</TechyAnalysisHeader>
<TechyVerticalTable :table-props="rightSideProps" :data-list="rightSideDatalist" />
</div>
<div>
<TechyAnalysisHeader>点检工单</TechyAnalysisHeader>
<TechyVerticalTable :table-props="rightSideProps" :data-list="rightSideDatalist" />
</div>
</div>
</techy-container>
</div>
</section>
</div>
</template>
<script>
import TechyContainer from './components/TechyContainer.vue'
import TechyHeader from './components/TechyHeader.vue'
import TechyBox from './components/TechyBox.vue'
import TechyTable from './components/TechyTable.vue'
import TechyAnalysisHeader from './components/TechyAnalysisHeader.vue'
import EquipmentAnalysisBox from './components/EquipmentAnalysisBox.vue'
import TechyVerticalTable from './components/TechyVerticalTable.vue'
import plJdlChart from './components/charts/pl-JDL-Chart.vue'
import {
equipmentExceptionProps,
equipmentExceptionDatalist,
equipmentAlarmProps,
equipmentAlarmDatalist,
OEE_PER_LINE,
equipmentAnalysisData,
sparepartsProps,
sparepartsDatalist,
rightSideProps,
rightSideDatalist
} from './mockData'
import { mapGetters } from 'vuex'
import screenfull from 'screenfull'
const equipmentExceptionSVG = `<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>setting tools</title>
<g id="2MES。2-6蓝底-7、8白底" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="2-4设备管理" transform="translate(-384.000000, -254.000000)">
<g id="编组-16备份-6" transform="translate(360.000000, 230.000000)">
<g id="编组" transform="translate(24.000000, 24.000000)">
<polygon id="Fill-1" fill="#3B71B2" opacity="0" points="0 24 24 24 24 0 0 0"></polygon>
<path d="M5.8599,18.0898 C6.4089,18.6418 7.3019,18.6448 7.8539,18.0958 C7.8559,18.0938 7.8579,18.0918 7.8599,18.0898 L14.5199,11.4298 L14.8899,11.4998 L15.0599,11.4998 C16.6169,11.7418 18.1089,10.7848 18.5399,9.2698 L18.2299,9.6198 C17.1349,10.6718 15.4049,10.6718 14.3099,9.6198 C13.2319,8.5358 13.2319,6.7838 14.3099,5.6998 L14.5999,5.4098 C13.0609,5.8908 12.1389,7.4618 12.4699,9.0398 L12.5499,9.4098 L5.8809,16.0798 C5.6139,16.3438 5.4659,16.7048 5.46982098,17.0798 C5.4729,17.4538 5.6199,17.8118 5.8809,18.0798 L5.8599,18.0898 Z M6.8599,19.8698 C6.1109,19.8828 5.3889,19.5898 4.8599,19.0598 C3.7809,17.9838 3.7769,16.2358 4.8529,15.1568 C4.8559,15.1538 4.8579,15.1518 4.8599,15.1498 L11.0099,8.9898 C10.7039,6.6548 12.2459,4.4768 14.5499,3.9898 L14.7799,3.9398 L15.0899,3.9398 C15.6049,3.8968 16.0939,4.1748 16.3199,4.6398 C16.4859,5.0968 16.3549,5.6088 15.9899,5.9298 L15.2299,6.6898 C14.6769,7.2388 14.6749,8.1318 15.2239,8.6838 L15.2299,8.6898 C15.7859,9.2338 16.6739,9.2338 17.2299,8.6898 L17.9899,7.9198 C18.2099,7.6868 18.5099,7.5478 18.8299,7.5298 C19.1509,7.5208 19.4599,7.6568 19.6709,7.8998 C19.9429,8.2518 20.0459,8.7058 19.9499,9.1398 C19.5749,11.5408 17.3609,13.2088 14.9499,12.9098 L8.7999,19.0598 C8.2859,19.5748 7.5889,19.8668 6.8599,19.8698 L6.8599,19.8698 Z" id="Fill-5" fill="#6FFADE"></path>
<path d="M16.9399,20.1099 L13.4609,16.6299 C13.3319,16.4919 13.3319,16.2779 13.4609,16.1399 L14.9399,14.6699 C15.0699,14.5349 15.2859,14.5309 15.4199,14.6609 C15.4239,14.6639 15.4269,14.6669 15.4299,14.6699 L18.9099,18.1499 C19.4619,18.7019 19.4619,19.5979 18.9099,20.1499 C18.3579,20.7019 17.4619,20.7019 16.9099,20.1499 L16.9399,20.1099 Z" id="Fill-7" fill="#6FFADE"></path>
<polygon id="Fill-9" fill="#6FFADE" points="5.6499 7.6899 4.6199 7.1499 3.3899 5.4299 4.3799 4.4399 6.0999 5.6699 6.6399 6.7099 9.0399 9.1199 8.0599 10.1099"></polygon>
<path d="M5.3901,18.6099 C4.5621,17.8059 4.5411,16.4829 5.3451,15.6549 C5.3601,15.6399 5.3741,15.6249 5.3901,15.6099 L11.7891,9.2099 C11.3521,7.1479 12.6671,5.1199 14.7301,4.6799 L14.9301,4.6799 L15.1501,4.6799 C15.7401,4.6799 15.9301,5.1099 15.5501,5.4899 L14.7891,6.2499 C13.9611,7.0789 13.9611,8.4219 14.7891,9.2499 C15.6191,10.0789 16.9611,10.0789 17.7891,9.2499 L18.5501,8.4899 C18.6531,8.3769 18.7971,8.3079 18.9501,8.2999 C19.2201,8.2999 19.4301,8.5999 19.3501,9.1099 C19.0271,11.1909 17.0811,12.6169 15.0001,12.2999 L14.7901,12.2999 L8.3901,18.6999 C7.5861,19.5279 6.2631,19.5479 5.4351,18.7449 C5.4191,18.7299 5.4051,18.7149 5.3901,18.6999 L5.3901,18.6099 Z" id="Stroke-13" stroke="#6FFADE" stroke-width="1.5"></path>
<path d="M16.9399,20.1099 L13.4609,16.6299 C13.3319,16.4919 13.3319,16.2779 13.4609,16.1399 L14.9399,14.6699 C15.0699,14.5349 15.2859,14.5309 15.4199,14.6609 C15.4239,14.6639 15.4269,14.6669 15.4299,14.6699 L18.9099,18.1499 C19.4619,18.7019 19.4619,19.5979 18.9099,20.1499 C18.3579,20.7019 17.4619,20.7019 16.9099,20.1499 L16.9399,20.1099 Z" id="Fill-15" fill="#6FFADE"></path>
<polygon id="Fill-17" fill="#6FFADE" points="5.6499 7.6899 4.6199 7.1499 3.3899 5.4299 4.3799 4.4399 6.0999 5.6699 6.6399 6.7099 9.0399 9.1199 8.0599 10.1099"></polygon>
</g>
</g>
</g>
</g>
</svg>`
const equipmentAlarmSVG = `<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>hatplus</title>
<defs>
<linearGradient x1="100%" y1="100%" x2="20.318998%" y2="7.84095011e-14%" id="linearGradient-1">
<stop stop-color="#4BFFC8" offset="0%"></stop>
<stop stop-color="#45F2EC" offset="100%"></stop>
</linearGradient>
</defs>
<g id="2MES。2-6蓝底-7、8白底" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="2-4设备管理" transform="translate(-998.000000, -254.000000)">
<g id="编组-16备份-8" transform="translate(974.000000, 230.000000)">
<g id="编组-6" transform="translate(24.000000, 24.000000)">
<rect id="矩形" x="0" y="0" width="24" height="24"></rect>
<g id="异常" transform="translate(3.000000, 3.000000)" fill-rule="nonzero">
<rect id="矩形" fill="#000000" opacity="0" x="0" y="0" width="17" height="17"></rect>
<path d="M9.00003613,1.00009438 C7.45266489,0.991339384 5.96400493,1.59197413 4.85604619,2.6721807 C3.77420104,3.74179852 3.16375561,5.19879645 3.16005953,6.72012488 L3.16005953,14.5280306 L14.7760126,14.5280306 L14.7760126,6.72010926 C14.7746725,5.19671341 14.1605756,3.73789487 13.0720104,2.67216507 C11.9832986,1.60721536 10.5229694,1.00760431 9.0000205,1.00009438 L9.00003613,1.00009438 Z M8.52003548,12.6560576 L8.35203526,8.87208057 L5.48804703,8.87208057 L9.24800521,4.12815624 L9.56800564,7.18412206 L12.2880093,7.28012148 L8.48800418,12.6560576 L8.52003548,12.6560576 Z M1.00003551,16.1280053 C0.997937773,15.8953576 1.08886376,15.671504 1.25262424,15.5062394 C1.41638472,15.3409748 1.63939864,15.2480106 1.87205781,15.2480106 L16.1280144,15.2480106 C16.3586463,15.2508825 16.5792874,15.3425823 16.7440153,15.5040247 C16.9059435,15.6716664 16.9975415,15.894943 17,16.1280053 C17,16.6095886 16.6096013,17 16.1280144,17 L1.87205781,17 C1.39047096,17 1.00003551,16.6095886 1.00003551,16.1280053 L1.00003551,16.1280053 Z" id="形状" fill="url(#linearGradient-1)"></path>
</g>
</g>
</g>
</g>
</g>
</svg>`
const equipmentOrderSVG = `<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>编组</title>
<defs>
<polygon id="path-1" points="0 0 16.1800204 0 16.1800204 18.6799449 0 18.6799449"></polygon>
<polygon id="path-3" points="0 0 16.1800204 0 16.1800204 18.6799449 0 18.6799449"></polygon>
</defs>
<g id="2MES。2-6蓝底-7、8白底" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="2-4设备管理" transform="translate(-1532.000000, -254.000000)">
<g id="编组-6" transform="translate(1508.000000, 230.000000)">
<g id="编组" transform="translate(24.000000, 24.000000)">
<polygon id="Fill-1" fill="#3B71B2" opacity="0" points="0 24 24 24 24 0 0 0"></polygon>
<path d="M9.0701,20.7905 C9.0691,21.0755 9.2221,21.3395 9.4701,21.4795 C9.7211,21.6205 10.0281,21.6205 10.2801,21.4795 C10.5301,21.3405 10.6871,21.0765 10.6901,20.7905 C10.6761,20.3375 10.2981,19.9815 9.8451,19.9955 C9.7131,20.0005 9.5851,20.0355 9.4701,20.1005 C9.2201,20.2395 9.0671,20.5045 9.0701,20.7905" id="Fill-3" fill="#6EF9E1"></path>
<path d="M17.7101951,12.2602 C17.7092,12.5452 17.8622,12.8092 18.1102,12.9492 C18.3612,13.0902 18.6682,13.0902 18.9202,12.9492 C19.1702,12.8102 19.3272,12.5472 19.3302,12.2602 C19.3262,11.9702 19.1702,11.7042 18.9202,11.5602 C18.6682,11.4192 18.3612,11.4192 18.1102,11.5602 C17.8612,11.7052 17.7101951,11.9722 17.7101951,12.2602" id="Fill-5" fill="#6EF9E1"></path>
<g transform="translate(3.140000, 2.930055)">
<mask id="mask-2" fill="white">
<use xlink:href="#path-1"></use>
</mask>
<g id="Clip-8"></g>
<path d="M14.85,0 L1.35,0 C0.61,-0.00595509266 0.006,0.590044907 0,1.33004491 L0,1.34004491 L0,17.3400449 C0,18.0800449 0.6,18.6800449 1.34,18.6800449 L1.35,18.6800449 L6.75,18.6800449 L6.75,17.0800449 L2.75,17.0800449 C2.121,17.0850449 1.605,16.5790449 1.6,15.9500449 L1.6,15.9390449 L1.6,2.72904491 C1.6,2.10104491 2.11,1.59004491 2.74,1.59004491 L2.75,1.59004491 L13.41,1.59004491 C14.041,1.59004491 14.555,2.09904491 14.56,2.72904491 L14.56,9.33004491 L16.1800204,9.33004491 L16.1800204,1.33004491 C16.182,0.972044907 16.037,0.629044907 15.78,0.380044907 C15.531,0.138044907 15.198,0.00104490734 14.85,0" id="Fill-7" fill="#6EF9E1" mask="url(#mask-2)"></path>
</g>
<g transform="translate(6.579800, 7.340500)">
<path d="M12.3702,11.45 C12.3812,12.322 11.6832,13.038 10.8102,13.05 C9.9372,13.06 9.2222,12.362 9.2102,11.489 C9.1992,10.617 9.8982,9.901 10.7702,9.88897334 L10.7902,9.88897334 C11.6572,9.884 12.3652,10.583 12.3702,11.449 L12.3702,11.45 Z M14.3102,12.13 L13.6802,11.66 C13.6862,11.59 13.6862,11.519 13.6802,11.45 C13.6852,11.377 13.6852,11.303 13.6802,11.229 L14.3102,10.769 C14.4802,10.635 14.5222,10.394 14.4102,10.21 L13.7202,9.05 C13.6362,8.915 13.4892,8.832 13.3302,8.83 C13.2812,8.819 13.2292,8.819 13.1802,8.83 L12.4302,9.109 C12.3072,9.028 12.1762,8.958 12.0402,8.899 L11.9302,8.149 C11.8992,7.931 11.7102,7.772 11.4902,7.779 L10.0802,7.779 C9.8632,7.781 9.6792,7.936 9.6402,8.149 L9.5402,8.899 L9.1502,9.109 L8.4102,8.83 L8.2502,8.83 C8.0922,8.826 7.9452,8.911 7.8702,9.05 L7.1602,10.21 C7.0502,10.397 7.0972,10.638 7.2702,10.769 L7.8902,11.229 L7.8902,11.45 C7.8852,11.519 7.8852,11.59 7.8902,11.66 L7.2702,12.13 C7.0992,12.258 7.0512,12.495 7.1602,12.679 L7.8602,13.849 C7.9452,13.984 8.0912,14.067 8.2502,14.069 C8.3002,14.079 8.3502,14.079 8.4002,14.069 L9.1402,13.779 C9.2642,13.864 9.3942,13.937 9.5302,14 L9.6402,14.75 C9.6792,14.963 9.8632,15.118 10.0802,15.12 L11.4902,15.12 C11.7102,15.127 11.8992,14.968 11.9302,14.75 L12.0402,14 C12.1772,13.94 12.3082,13.866 12.4302,13.779 L13.1802,14.069 C13.2292,14.079 13.2812,14.079 13.3302,14.069 C13.4912,14.073 13.6402,13.988 13.7202,13.849 L14.4202,12.679 C14.5242,12.494 14.4782,12.261 14.3102,12.13 L14.3102,12.13 Z" id="Fill-9" fill="#6FFADE"></path>
<path d="M9.4102,0.739 C9.4102,1.229 9.2002,1.469 8.8002,1.469 L2.9202,1.469 C2.5102,1.469 2.3102,1.229 2.3102,0.739 C2.3102,0.25 2.5102,0 2.9202,0 L8.8002,0 C9.2002,0 9.4102,0.25 9.4102,0.739" id="Fill-11" fill="#6EF9E1"></path>
<path d="M7.4102,4.6599 C7.4102,5.1599 7.2002,5.3989 6.7902,5.3989 L2.8702,5.3989 C2.4502,5.3989 2.2502,5.1599 2.2502,4.6599 C2.2502,4.1599 2.4502,3.9299 2.8702,3.9299 L6.7902,3.9299 C7.2002,3.9299 7.4102,4.1699 7.4102,4.6599" id="Fill-13" fill="#6EF9E1"></path>
<path d="M5.4102,8.5896 C5.4102,9.0796 5.2002,9.3296 4.7802,9.3296 L2.8802,9.3296 C2.4602,9.3296 2.2502,9.0796 2.2502,8.5896 C2.2502,8.0996 2.4602,7.8596 2.8802,7.8596 L4.7802,7.8596 C5.2002,7.8596 5.4102,8.0996 5.4102,8.5896" id="Fill-15" fill="#6EF9E1"></path>
<path d="M0.73,0.0095 L0.75,0.0095 C1.153,0.0095 1.48,0.3365 1.48,0.7385 L1.48,0.7495 C1.48,1.1535 1.153,1.4795 0.75,1.4795 L0.73,1.4795 C0.327,1.4795 0,1.1535 0,0.7495 L0,0.7385 C0,0.3365 0.327,0.0095 0.73,0.0095" id="Fill-17" fill="#6DF8E1"></path>
<path d="M0.73,3.9695 L0.75,3.9695 C1.153,3.9695 1.48,4.2965 1.48,4.6995 L1.48,4.7095 C1.48,5.1135 1.153,5.4395 0.75,5.4395 L0.73,5.4395 C0.327,5.4395 0,5.1135 0,4.7095 L0,4.6995 C0,4.2965 0.327,3.9695 0.73,3.9695" id="Fill-19" fill="#6DF8E1"></path>
<path d="M0.73,7.9197 L0.75,7.9197 C1.153,7.9197 1.48,8.2457 1.48,8.6487 L1.48,8.6597 C1.48,9.0627 1.153,9.3897 0.75,9.3897 L0.73,9.3897 C0.327,9.3897 0,9.0627 0,8.6597 L0,8.6487 C0,8.2457 0.327,7.9197 0.73,7.9197" id="Fill-21" fill="#6DF8E1"></path>
</g>
<path d="M9.0701,20.7905 C9.0691,21.0755 9.2221,21.3395 9.4701,21.4795 C9.7211,21.6205 10.0281,21.6205 10.2801,21.4795 C10.5301,21.3405 10.6871,21.0765 10.6901,20.7905 C10.6761,20.3375 10.2981,19.9815 9.8451,19.9955 C9.7131,20.0005 9.5851,20.0355 9.4701,20.1005 C9.2201,20.2395 9.0671,20.5045 9.0701,20.7905" id="Fill-23" fill="#6EF9E1"></path>
<path d="M17.7101951,12.2602 C17.7092,12.5452 17.8622,12.8092 18.1102,12.9492 C18.3612,13.0902 18.6682,13.0902 18.9202,12.9492 C19.1702,12.8102 19.3272,12.5472 19.3302,12.2602 C19.3262,11.9702 19.1702,11.7042 18.9202,11.5602 C18.6682,11.4192 18.3612,11.4192 18.1102,11.5602 C17.8612,11.7052 17.7101951,11.9722 17.7101951,12.2602" id="Fill-25" fill="#6EF9E1"></path>
<g transform="translate(3.140000, 2.930055)">
<mask id="mask-4" fill="white">
<use xlink:href="#path-3"></use>
</mask>
<g id="Clip-28"></g>
<path d="M14.85,0 L1.35,0 C0.61,-0.00595509266 0.006,0.590044907 0,1.33004491 L0,1.34004491 L0,17.3400449 C0,18.0800449 0.6,18.6800449 1.34,18.6800449 L1.35,18.6800449 L6.75,18.6800449 L6.75,17.0800449 L2.75,17.0800449 C2.121,17.0850449 1.605,16.5790449 1.6,15.9500449 L1.6,15.9390449 L1.6,2.72904491 C1.6,2.10104491 2.11,1.59004491 2.74,1.59004491 L2.75,1.59004491 L13.41,1.59004491 C14.041,1.59004491 14.555,2.09904491 14.56,2.72904491 L14.56,9.33004491 L16.1800204,9.33004491 L16.1800204,1.33004491 C16.182,0.972044907 16.037,0.629044907 15.78,0.380044907 C15.531,0.138044907 15.198,0.00104490734 14.85,0" id="Fill-27" fill="#6EF9E1" mask="url(#mask-4)"></path>
</g>
<g transform="translate(6.579800, 7.340500)">
<path d="M12.3702,11.45 C12.3812,12.322 11.6832,13.038 10.8102,13.05 C9.9372,13.06 9.2222,12.362 9.2102,11.489 C9.1992,10.617 9.8982,9.901 10.7702,9.88897334 L10.7902,9.88897334 C11.6572,9.884 12.3652,10.583 12.3702,11.449 L12.3702,11.45 Z M14.3102,12.13 L13.6802,11.66 C13.6862,11.59 13.6862,11.519 13.6802,11.45 C13.6852,11.377 13.6852,11.303 13.6802,11.229 L14.3102,10.769 C14.4802,10.635 14.5222,10.394 14.4102,10.21 L13.7202,9.05 C13.6362,8.915 13.4892,8.832 13.3302,8.83 C13.2812,8.819 13.2292,8.819 13.1802,8.83 L12.4302,9.109 C12.3072,9.028 12.1762,8.958 12.0402,8.899 L11.9302,8.149 C11.8992,7.931 11.7102,7.772 11.4902,7.779 L10.0802,7.779 C9.8632,7.781 9.6792,7.936 9.6402,8.149 L9.5402,8.899 L9.1502,9.109 L8.4102,8.83 L8.2502,8.83 C8.0922,8.826 7.9452,8.911 7.8702,9.05 L7.1602,10.21 C7.0502,10.397 7.0972,10.638 7.2702,10.769 L7.8902,11.229 L7.8902,11.45 C7.8852,11.519 7.8852,11.59 7.8902,11.66 L7.2702,12.13 C7.0992,12.258 7.0512,12.495 7.1602,12.679 L7.8602,13.849 C7.9452,13.984 8.0912,14.067 8.2502,14.069 C8.3002,14.079 8.3502,14.079 8.4002,14.069 L9.1402,13.779 C9.2642,13.864 9.3942,13.937 9.5302,14 L9.6402,14.75 C9.6792,14.963 9.8632,15.118 10.0802,15.12 L11.4902,15.12 C11.7102,15.127 11.8992,14.968 11.9302,14.75 L12.0402,14 C12.1772,13.94 12.3082,13.866 12.4302,13.779 L13.1802,14.069 C13.2292,14.079 13.2812,14.079 13.3302,14.069 C13.4912,14.073 13.6402,13.988 13.7202,13.849 L14.4202,12.679 C14.5242,12.494 14.4782,12.261 14.3102,12.13 L14.3102,12.13 Z" id="Fill-29" fill="#6FFADE"></path>
<path d="M9.4102,0.739 C9.4102,1.229 9.2002,1.469 8.8002,1.469 L2.9202,1.469 C2.5102,1.469 2.3102,1.229 2.3102,0.739 C2.3102,0.25 2.5102,0 2.9202,0 L8.8002,0 C9.2002,0 9.4102,0.25 9.4102,0.739" id="Fill-31" fill="#6EF9E1"></path>
<path d="M7.4102,4.6599 C7.4102,5.1599 7.2002,5.3989 6.7902,5.3989 L2.8702,5.3989 C2.4502,5.3989 2.2502,5.1599 2.2502,4.6599 C2.2502,4.1599 2.4502,3.9299 2.8702,3.9299 L6.7902,3.9299 C7.2002,3.9299 7.4102,4.1699 7.4102,4.6599" id="Fill-33" fill="#6EF9E1"></path>
<path d="M5.4102,8.5896 C5.4102,9.0796 5.2002,9.3296 4.7802,9.3296 L2.8802,9.3296 C2.4602,9.3296 2.2502,9.0796 2.2502,8.5896 C2.2502,8.0996 2.4602,7.8596 2.8802,7.8596 L4.7802,7.8596 C5.2002,7.8596 5.4102,8.0996 5.4102,8.5896" id="Fill-35" fill="#6EF9E1"></path>
<path d="M0.73,0.0095 L0.75,0.0095 C1.153,0.0095 1.48,0.3365 1.48,0.7385 L1.48,0.7495 C1.48,1.1535 1.153,1.4795 0.75,1.4795 L0.73,1.4795 C0.327,1.4795 0,1.1535 0,0.7495 L0,0.7385 C0,0.3365 0.327,0.0095 0.73,0.0095" id="Fill-37" fill="#6DF8E1"></path>
<path d="M0.73,3.9695 L0.75,3.9695 C1.153,3.9695 1.48,4.2965 1.48,4.6995 L1.48,4.7095 C1.48,5.1135 1.153,5.4395 0.75,5.4395 L0.73,5.4395 C0.327,5.4395 0,5.1135 0,4.7095 L0,4.6995 C0,4.2965 0.327,3.9695 0.73,3.9695" id="Fill-39" fill="#6DF8E1"></path>
<path d="M0.73,7.9197 L0.75,7.9197 C1.153,7.9197 1.48,8.2457 1.48,8.6487 L1.48,8.6597 C1.48,9.0627 1.153,9.3897 0.75,9.3897 L0.73,9.3897 C0.327,9.3897 0,9.0627 0,8.6597 L0,8.6487 C0,8.2457 0.327,7.9197 0.73,7.9197" id="Fill-41" fill="#6DF8E1"></path>
</g>
</g>
</g>
</g>
</g>
</svg>`
const equipmentAnalysisSVG = `<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>analysis</title>
<g id="2MES。2-6蓝底-7、8白底" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="2-4设备管理" transform="translate(-384.000000, -533.000000)">
<g id="编组-16备份-7" transform="translate(360.000000, 509.000000)">
<g id="编组" transform="translate(24.000000, 24.000000)">
<polygon id="Fill-1" fill="#3B71B2" opacity="0" points="0 24 24 24 24 0 0 0"></polygon>
<path d="M14.6801,7.8401 L14.6801,8.4001 C14.6801,8.6761 14.9041,8.9001 15.1801,8.9001 L15.1901,8.9001 C15.4661,8.9001 15.6901,8.6761 15.6901,8.4001 L15.6901,6.5001 C15.6901,6.2241 15.4661,6.0001 15.1901,6.0001 L13.2701,6.0001 C13.0171,6.0301 12.8281,6.2451 12.8301,6.5001 C12.8271,6.7561 13.0161,6.9751 13.2701,7.0101 L13.8301,7.0101 L11.3301,8.7501 L10.3301,7.4201 C10.1241,7.1751 9.7671,7.1231 9.5001,7.3001 L5.8001,10.0001 C5.5381,10.1941 5.4831,10.5631 5.6761,10.8251 C5.6781,10.8261 5.6791,10.8281 5.6801,10.8301 C5.7951,10.9901 5.9821,11.0841 6.1801,11.0801 C6.3021,11.0791 6.4201,11.0331 6.5101,10.9501 L9.7501,8.5801 L10.7501,9.9101 C10.9571,10.1591 11.3251,10.1981 11.5801,10.0001 L14.6501,7.8801 L14.6801,7.8401 Z" id="Fill-3" fill="#6FFADE"></path>
<path d="M16.7601,17.7502146 C15.1691,17.7552 13.8751,16.4712 13.8700791,14.8802 C13.8641,13.2892 15.1491,11.9952 16.7401,11.9901791 C18.3301,11.9842 19.6241,13.2702 19.6301,14.8592 C19.6301,14.8662 19.6301,14.8732 19.6301,14.8802 C19.6191,16.4602 18.3411,17.7392 16.7601,17.7502146 M21.8101,19.7002 L19.8101,17.7002 C20.5281,16.9382 20.9261,15.9282 20.9201,14.8802 C20.9201,12.5772 19.0531,10.7102 16.7501,10.7102 C14.4471,10.7102 12.5801,12.5772 12.5801,14.8802 C12.5801,17.1832 14.4471,19.0502 16.7501,19.0502 C17.4471,19.0422 18.1341,18.8672 18.7501,18.5402 L20.8301,20.6202 C20.9511,20.7492 21.1231,20.8192 21.3001,20.8102 C21.4731,20.8162 21.6411,20.7472 21.7601,20.6202 C22.0261,20.4132 22.0741,20.0302 21.8671,19.7642 C21.8501,19.7412 21.8301,19.7202 21.8101,19.7002" id="Fill-5" fill="#6FFADE"></path>
<path d="M6.9901,15.3196 C6.8671,15.3196 6.7501,15.2726 6.6601,15.1896 C6.5781,15.0986 6.5321,14.9816 6.5301,14.8596 L6.5301,12.5006 C6.5061,12.3216 6.5881,12.1456 6.7401,12.0496 C6.8911,11.9486 7.0891,11.9486 7.2401,12.0496 C7.3921,12.1456 7.4741,12.3216 7.4501,12.5006 L7.4501,14.8596 C7.4481,14.9846 7.3981,15.1026 7.3101,15.1896 C7.2241,15.2736 7.1091,15.3196 6.9901,15.3196" id="Fill-7" fill="#6FFADE"></path>
<path d="M9.2601,15.3196 C9.0171,15.3256 8.8151,15.1326 8.8091,14.8906 C8.8091,14.8806 8.8091,14.8706 8.8101,14.8596 L8.8101,11.1206 C8.8471,10.8686 9.0811,10.6956 9.3321,10.7326 C9.5331,10.7616 9.6901,10.9206 9.7201,11.1206 L9.7201,14.8496 C9.7241,14.9756 9.6771,15.0986 9.5901,15.1896 C9.5001,15.2726 9.3821,15.3196 9.2601,15.3196" id="Fill-9" fill="#6FFADE"></path>
<path d="M11.5399,15.3196 C11.4169,15.3196 11.2999,15.2726 11.2099,15.1896 C11.1289,15.0986 11.0819,14.9816 11.0799,14.8596 L11.0799,13.2196 C11.0809,12.9656 11.2869,12.7596 11.5409,12.7605964 C11.7939,12.7605964 11.9989,12.9666 11.9999,13.2196 L11.9999,14.8596 C11.9989,14.9846 11.9489,15.1026 11.8599,15.1896 C11.7739,15.2736 11.6599,15.3196 11.5399,15.3196" id="Fill-11" fill="#6FFADE"></path>
<path d="M13.35,19.2297 L2.65,19.2297 C2.259,19.2607 1.967,19.6017 1.997,19.9937 C1.998,20.0017 1.999,20.0107 2,20.0197 C1.96,20.4107 2.244,20.7587 2.634,20.7987 C2.64,20.7987 2.645,20.7997 2.65,20.7997 L13.35,20.7997 C13.784,20.7147 14.066,20.2937 13.981,19.8607 C13.918,19.5417 13.669,19.2917 13.35,19.2297" id="Fill-13" fill="#6FFADE"></path>
<path d="M16.8002,2.6301 L4.9402,2.6301 C3.2832,2.6301 1.9402,3.9731 1.9402,5.6301 L1.9402,15.0801 C1.9402,16.7361 3.2832,18.0801 4.9402,18.0801 L11.5402,18.0801 C11.9002,18.0801 12.1802,17.6601 12.1802,17.3001 C12.1802,16.9401 11.9002,16.5101 11.5402,16.5101 L5.2202,16.5101 C4.2862,16.5211 3.5212,15.7741 3.5102,14.8401 C3.5092,14.8261 3.5092,14.8141 3.5102,14.8001 L3.5102,5.9001 C3.5152,4.9801 4.2602,4.2351 5.1802,4.2301 L16.6402,4.2301 C17.5622,4.2301 18.3102,4.9781 18.3102,5.9001 L18.3102,10.0101 L18.3102,10.1001 C18.3042,10.1231 18.3042,10.1471 18.3102,10.1701 C18.3732,10.5131 18.6722,10.7611 19.0202,10.7601 C19.4212,10.7491 19.7402,10.4211 19.7402,10.0201 L19.7402,5.6301 C19.7402,3.9961 18.4332,2.6621 16.8002,2.6301" id="Fill-15" fill="#6FFADE"></path>
<path d="M14.6801,7.8401 L14.6801,8.4001 C14.6801,8.6761 14.9041,8.9001 15.1801,8.9001 L15.1901,8.9001 C15.4661,8.9001 15.6901,8.6761 15.6901,8.4001 L15.6901,6.5001 C15.6901,6.2241 15.4661,6.0001 15.1901,6.0001 L13.2701,6.0001 C13.0171,6.0301 12.8281,6.2451 12.8301,6.5001 C12.8271,6.7561 13.0161,6.9751 13.2701,7.0101 L13.8301,7.0101 L11.3301,8.7501 L10.3301,7.4201 C10.1241,7.1751 9.7671,7.1231 9.5001,7.3001 L5.8001,10.0001 C5.5381,10.1941 5.4831,10.5631 5.6761,10.8251 C5.6781,10.8261 5.6791,10.8281 5.6801,10.8301 C5.7951,10.9901 5.9821,11.0841 6.1801,11.0801 C6.3021,11.0791 6.4201,11.0331 6.5101,10.9501 L9.7501,8.5801 L10.7501,9.9101 C10.9571,10.1591 11.3251,10.1981 11.5801,10.0001 L14.6501,7.8801 L14.6801,7.8401 Z" id="Fill-17" fill="#6FFADE"></path>
<path d="M16.7601,17.7502146 C15.1691,17.7552 13.8751,16.4712 13.8700791,14.8802 C13.8641,13.2892 15.1491,11.9952 16.7401,11.9901791 C18.3301,11.9842 19.6241,13.2702 19.6301,14.8592 C19.6301,14.8662 19.6301,14.8732 19.6301,14.8802 C19.6191,16.4602 18.3411,17.7392 16.7601,17.7502146 M21.8101,19.7002 L19.8101,17.7002 C20.5281,16.9382 20.9261,15.9282 20.9201,14.8802 C20.9201,12.5772 19.0531,10.7102 16.7501,10.7102 C14.4471,10.7102 12.5801,12.5772 12.5801,14.8802 C12.5801,17.1832 14.4471,19.0502 16.7501,19.0502 C17.4471,19.0422 18.1341,18.8672 18.7501,18.5402 L20.8301,20.6202 C20.9511,20.7492 21.1231,20.8192 21.3001,20.8102 C21.4731,20.8162 21.6411,20.7472 21.7601,20.6202 C22.0261,20.4132 22.0741,20.0302 21.8671,19.7642 C21.8501,19.7412 21.8301,19.7202 21.8101,19.7002" id="Fill-19" fill="#6FFADE"></path>
<path d="M6.9901,15.3196 C6.8671,15.3196 6.7501,15.2726 6.6601,15.1896 C6.5781,15.0986 6.5321,14.9816 6.5301,14.8596 L6.5301,12.5006 C6.5061,12.3216 6.5881,12.1456 6.7401,12.0496 C6.8911,11.9486 7.0891,11.9486 7.2401,12.0496 C7.3921,12.1456 7.4741,12.3216 7.4501,12.5006 L7.4501,14.8596 C7.4481,14.9846 7.3981,15.1026 7.3101,15.1896 C7.2241,15.2736 7.1091,15.3196 6.9901,15.3196" id="Fill-21" fill="#6FFADE"></path>
<path d="M9.2601,15.3196 C9.0171,15.3256 8.8151,15.1326 8.8091,14.8906 C8.8091,14.8806 8.8091,14.8706 8.8101,14.8596 L8.8101,11.1206 C8.8471,10.8686 9.0811,10.6956 9.3321,10.7326 C9.5331,10.7616 9.6901,10.9206 9.7201,11.1206 L9.7201,14.8496 C9.7241,14.9756 9.6771,15.0986 9.5901,15.1896 C9.5001,15.2726 9.3821,15.3196 9.2601,15.3196" id="Fill-23" fill="#6FFADE"></path>
<path d="M11.5399,15.3196 C11.4169,15.3196 11.2999,15.2726 11.2099,15.1896 C11.1289,15.0986 11.0819,14.9816 11.0799,14.8596 L11.0799,13.2196 C11.0809,12.9656 11.2869,12.7596 11.5409,12.7605964 C11.7939,12.7605964 11.9989,12.9666 11.9999,13.2196 L11.9999,14.8596 C11.9989,14.9846 11.9489,15.1026 11.8599,15.1896 C11.7739,15.2736 11.6599,15.3196 11.5399,15.3196" id="Fill-25" fill="#6FFADE"></path>
<path d="M13.35,19.2297 L2.65,19.2297 C2.259,19.2607 1.967,19.6017 1.997,19.9937 C1.998,20.0017 1.999,20.0107 2,20.0197 C1.96,20.4107 2.244,20.7587 2.634,20.7987 C2.64,20.7987 2.645,20.7997 2.65,20.7997 L13.35,20.7997 C13.784,20.7147 14.066,20.2937 13.981,19.8607 C13.918,19.5417 13.669,19.2917 13.35,19.2297" id="Fill-27" fill="#6FFADE"></path>
<path d="M16.8002,2.6301 L4.9402,2.6301 C3.2832,2.6301 1.9402,3.9731 1.9402,5.6301 L1.9402,15.0801 C1.9402,16.7361 3.2832,18.0801 4.9402,18.0801 L11.5402,18.0801 C11.9002,18.0801 12.1802,17.6601 12.1802,17.3001 C12.1802,16.9401 11.9002,16.5101 11.5402,16.5101 L5.2202,16.5101 C4.2862,16.5211 3.5212,15.7741 3.5102,14.8401 C3.5092,14.8261 3.5092,14.8141 3.5102,14.8001 L3.5102,5.9001 C3.5152,4.9801 4.2602,4.2351 5.1802,4.2301 L16.6402,4.2301 C17.5622,4.2301 18.3102,4.9781 18.3102,5.9001 L18.3102,10.0101 L18.3102,10.1001 C18.3042,10.1231 18.3042,10.1471 18.3102,10.1701 C18.3732,10.5131 18.6722,10.7611 19.0202,10.7601 C19.4212,10.7491 19.7402,10.4211 19.7402,10.0201 L19.7402,5.6301 C19.7402,3.9961 18.4332,2.6621 16.8002,2.6301" id="Fill-29" fill="#6FFADE"></path>
</g>
</g>
</g>
</g>
</svg>`
export default {
name: 'EquipmentManageHome',
components: {
plJdlChart,
TechyContainer,
TechyHeader,
TechyBox,
TechyVerticalTable,
TechyTable,
TechyAnalysisHeader,
EquipmentAnalysisBox
},
directives: {
'auto-shrink-and-grow': function(el, binding) {
console.log('el', el, binding)
}
},
props: {},
data() {
return {
equipmentExceptionSVG,
equipmentAlarmSVG,
equipmentOrderSVG,
equipmentAnalysisSVG,
equipmentExceptionProps,
equipmentExceptionDatalist,
equipmentAlarmProps,
equipmentAlarmDatalist,
OEE_PER_LINE,
equipmentAnalysisData,
sparepartsProps,
sparepartsDatalist,
rightSideProps,
rightSideDatalist
// refreshKey: 0
}
},
computed: {
...mapGetters(['sidebar'])
},
mounted() {
// window.addEventListener('resize', () => {
// console.log('resizing....')
// this.refreshSize++
// this.$nextTick(() => {
// this.$forceUpdate()
// })
// }) // 不可行
},
methods: {
changeFullScreen() {
if (!screenfull.enabled) {
this.$message({
message: 'you browser can not work',
type: 'warning'
})
return false
}
screenfull.toggle(this.$refs['cockpit-container-equipment'])
}
}
}
</script>
<style scoped>
.visual-container {
width: 100%;
min-width: 1280px;
/* height: calc(100vh - 128px); */
background: url('./assets/bg.png') no-repeat;
background-size: cover;
overflow: hidden;
position: relative;
}
.techy-body {
height: calc(100vh - 64px);
width: 100%;
/* overflow: hidden; */
/* padding: 24px; */
padding: calc(100vw / 1920 * 24);
/* display: grid;
grid-template-columns: 3fr 1fr; */
display: flex;
gap: calc(100vw / 1920 * 16);
}
.tech-body__col-1 {
height: calc(100% - 28px);
flex: 1 3;
display: flex;
flex-direction: column;
gap: calc(100vw / 1920 * 16);
}
.tech-body__col-2 {
flex: 1 1;
max-width: 25%;
height: calc(100% - 28px);
}
.techy-container__inner {
display: flex;
flex-direction: column;
gap: 0.8vh;
height: calc(100% - 4vh);
/* overflow-y: scroll; */
overflow-y: hidden;
}
.techy-container__inner > div {
flex: 1 1;
}
.row-1 {
flex: 1;
display: flex;
gap: calc(100vw / 1920 * 16);
}
.equipment-exception {
flex: 3 1;
}
.equipment-alarm {
flex: 2 1;
}
.grid {
display: grid;
}
.columns-2 {
grid-template-columns: 1fr 3fr;
/* gap: 8px; */
gap: 0.5vw;
}
.grid-2-3 {
grid-template-columns: repeat(3, 1fr);
grid-template-rows: 1fr 1fr;
/* gap: 4px; */
gap: 0.6vh 0.3vw;
}
.product-line-selection {
border: none;
outline: none;
border-radius: 2px 4px 4px 2px;
background: #31878c45;
/* opacity: 0.29; */
color: white;
position: absolute;
padding: 0.5vh;
width: 5vw;
font-size: 12px;
line-height: 18px;
top: calc(1vh + 8px);
left: calc(5vw + 32px);
}
</style>

View File

@@ -0,0 +1,442 @@
<template>
<!-- <div class="form-container"> -->
<div>
<el-dialog v-bind="$attrs" :title="$t('module.equipmentManager.maintainlog.maintainAdd')" class="dialog" width="50%" v-on="$listeners" @open="onOpen" @close="onClose">
<!-- <div class="method-btn-area">
<el-button type="primary" plain icon="el-icon-arrow-left" @click="turnBack">{{ 'btn.back' | i18nFilter }}</el-button>
</div> -->
<el-form ref="elForm" :model="formData" :rules="rules" label-width="110px">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item v-if="orderId" :label="$t('module.equipmentManager.maintainplan.maintenanceOrderNumber')" prop="maintenanceOrderNumber">
<el-input v-model="formData.orderNumber" :placeholder="$t('module.equipmentManager.maintainlog.placeholdermaintenanceOrderNumber')" :disabled="valDisabled" :style="{width: '100%'}" />
</el-form-item>
<el-form-item :label="$t('module.equipmentManager.maintainlog.equipmentId')" prop="equipmentId">
<el-select
v-model="formData.equipmentName"
:placeholder="$t('module.equipmentManager.maintainlog.placeholderequipmentId')"
:disabled="valDisabled"
:style="{width: '100%'}"
filterable
@input="changeEq"
>
<el-option
v-for="(item, index) in dict.device"
:key="index"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.maintainlog.maintenanceOrderNumber')" prop="logMaintenanceOrderNumber">
<el-input v-model="formData.logMaintenanceOrderNumber" :placeholder="$t('module.equipmentManager.maintainlog.placeholdermaintenanceOrderNumber')" clearable :style="{width: '100%'}" />
</el-form-item>
</el-col>
</el-row>
<!-- <el-col :span="24">
<el-form-item :label="$t('module.equipmentManager.maintainlog.maintainNextTime')" prop="nextMaintenanceTime">
<el-date-picker
v-model="formData.nextMaintenanceTime"
type="datetime"
:style="{width: '100%'}"
:placeholder="$t('module.equipmentManager.maintainlog.placeholdermaintainNextTime')"
clearable
/>
</el-form-item>
</el-col> -->
<el-row :gutter="20">
<el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.maintainlog.maintainStartTime')" prop="actualStartTime">
<el-date-picker
v-model="formData.actualStartTime"
type="datetime"
:style="{width: '100%'}"
:placeholder="$t('module.equipmentManager.maintainlog.placeholdermaintainStartTime')"
clearable
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.maintainlog.maintainEndTime')" prop="actualEndTime">
<el-date-picker
v-model="formData.actualEndTime"
type="datetime"
:style="{width: '100%'}"
:placeholder="$t('module.equipmentManager.maintainlog.placeholdermaintainEndTime')"
clearable
/>
</el-form-item>
</el-col>
</el-row>
<el-form-item :label="$t('module.equipmentManager.maintainlog.maintainWorkerId')" prop="maintainWorker">
<el-select
v-model="formData.maintainWorker"
:placeholder="$t('module.equipmentManager.maintainlog.placeholdermaintainWorkerId')"
clearable
multiple
:style="{width: '100%'}"
@input="changeWorker"
>
<el-option
v-for="(item, index) in dict.worker"
:key="index"
:label="item.name"
:value="item.name"
/>
</el-select>
</el-form-item>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.maintainlog.maintainDuration')" prop="maintainDuration">
<el-input v-model="formData.maintainDuration" :placeholder="$t('module.equipmentManager.maintainlog.placeholdermaintainDuration')" clearable :style="{width: '100%'}" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.maintainplan.status')" prop="status">
<el-select
v-model="formData.status"
:placeholder="$t('module.equipmentManager.maintainplan.placeholderstatus')"
clearable
:style="{width: '100%'}"
>
<el-option
:label="$t('module.equipmentManager.repair.undone')"
:value="0"
/>
<el-option
:label="$t('module.equipmentManager.repair.done')"
:value="1"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
<!-- <el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.maintainplan.maintainType')" prop="maintainType">
<el-select
v-model="formData.maintainType"
:placeholder="$i18nForm(['placeholder.input', $t('module.equipmentManager.maintainlog.placeholdermaintainType')])"
celearable
:style="{width: '100%'}"
>
<el-option
v-for="(item, index) in dict.maintainType"
:key="index"
:label="item.dataName"
:value="item.id"
/>
</el-select>
</el-form-item>
</el-col> -->
<el-form-item :label="$t('module.equipmentManager.maintainlog.maintenanceDetail')" prop="maintenanceDes">
<el-input
v-model="formData.maintenanceDes"
type="textarea"
:placeholder="$t('module.equipmentManager.maintainlog.placeholdermaintenanceDetail')"
:autosize="{minRows: 4, maxRows: 4}"
:style="{width: '100%'}"
/>
</el-form-item>
<el-form-item :label="$t('module.equipmentManager.maintainlog.annex')" prop="annex">
<el-upload
ref="annex"
:data="dataObj"
name="files"
:file-list="fileList"
:action="uploadPath"
:before-upload="annexBeforeUpload"
:on-success="handleSuccess"
class="btn"
>
<el-button class="uploadButton" icon="el-icon-upload2">{{ 'btn.upload' | i18nFilter }}</el-button>
</el-upload>
</el-form-item>
<el-form-item :label="$t('module.equipmentManager.maintainlog.remark')" prop="remark">
<el-input v-model="formData.remark" :placeholder="$t('module.equipmentManager.maintainlog.placeholderremark')" clearable :style="{width: '100%'}" />
</el-form-item>
</el-form>
<div slot="footer">
<el-button @click="resetForm">{{ 'btn.reset' | i18nFilter }}</el-button>
<el-button type="primary" @click="submitForm">{{ 'btn.submit' | i18nFilter }}</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
// getLogCode
import { uploadPath } from '@/api/basic'
import { addMaintainLog, getMaintainPlan } from '@/api/equipment/maintain'
import { getDictDevice, getDictWorker } from '@/api/dict'
import i18n from '@/lang'
import { timeIsBefore } from '@/utils'
import { dataDictionaryDataList } from '@/api/basicData/dataDictionary'
export default {
components: {},
inheritAttrs: false,
props: {
targetInfo: {
type: Object,
default: () => ({})
}
},
data() {
return {
uploadPath,
annexfileList: [],
fileList: [],
dataObj: { typeCode: 'file' },
formData: {
equipmentId: undefined,
equipmentName: undefined,
logMaintenanceOrderNumber: undefined,
nextMaintenanceTime: null,
actualStartTime: null,
maintainWorker: '',
maintainWorkerId: undefined,
actualEndTime: undefined,
maintenanceDes: undefined,
maintainDuration: undefined,
file: null,
annex: null,
remark: undefined,
status: undefined,
orderNumber: undefined,
id: undefined
},
rules: {
equipmentId: [{
required: true,
message: i18n.t('module.equipmentManager.maintainlog.placeholderequipmentId'),
trigger: 'change'
}],
logMaintenanceOrderNumber: [{
required: false,
message: i18n.t('module.equipmentManager.maintainlog.placeholdermaintenanceOrderNumber'),
trigger: 'change'
}],
maintainType: [{
required: false,
message: i18n.t('module.equipmentManager.maintainlog.placeholdermaintainType'),
trigger: 'blur'
}],
nextMaintenanceTime: [{
required: false,
message: i18n.t('module.equipmentManager.maintainlog.placeholdermaintainNextTime'),
trigger: 'change'
}],
maintainDuration: [{
required: false,
message: i18n.t('module.equipmentManager.maintainplan.placeholdermaintainDuration'),
trigger: 'blur'
}],
actualStartTime: [{
required: true,
message: i18n.t('module.equipmentManager.maintainlog.placeholderactualStartTime'),
trigger: 'change'
}],
actualEndTime: [{
required: true,
message: i18n.t('module.equipmentManager.maintainlog.placeholderactualEndTime'),
trigger: 'change'
}],
maintainWorker: [{
required: false,
message: i18n.t('module.equipmentManager.maintainlog.placeholdermaintainWorkerId'),
trigger: 'change'
}],
maintenanceDes: [{
required: false,
message: i18n.t('module.equipmentManager.maintainlog.placeholdermaintenanceDetail'),
trigger: 'blur'
}],
status: [{
required: true,
message: i18n.t('module.equipmentManager.maintainplan.placeholderstatus'),
trigger: 'blur'
}],
remark: []
},
dict: {
device: [],
worker: [],
maintainType: []
},
// 控制添加选项是否disable
valDisabled: false
}
},
computed: {
orderId() {
return this.$route.query.orderId
}
},
watch: {},
created() {},
mounted() {
this.formData.maintainPlanId = this.$route.query.orderId
this.getInfo()
this.getDict()
},
methods: {
onOpen() {
console.log(this.orderId)
console.log(this.targetInfo)
},
onClose() {
this.$refs['elForm'].resetFields()
this.fileList = []
},
close() {
this.$emit('update:visible', false)
},
submitForm() {
console.log(this.formData)
this.$refs['elForm'].validate(async valid => {
if (!valid) return
// TODO 提交表单
if (this.formData.actualStartTime && this.formData.actualEndTime && !timeIsBefore(this.formData.actualStartTime, this.formData.actualEndTime)) {
this.$message({
type: 'error',
message: i18n.t('module.equipmentManager.maintainplan.sort')
})
return console.log('拦截')
}
if (this.formData.maintainWorker) {
this.formData.maintainWorker = this.formData.maintainWorker.join(',')
} else {
this.formData.maintainWorker = ''
}
// this.formData.maintainWorkerId = this.formData.maintainWorkerId.join(',')
console.log(this.formData)
await addMaintainLog(this.formData).then(res => {
if (res.code === 0) {
this.$message({
type: 'success',
message: i18n.t('module.equipmentManager.bom.succeeded')
})
// this.$router.go(-1)
this.$emit('done')
this.close()
}
}).catch(res => {
if (res.code !== 0) {
this.formData.maintainWorker = this.formData.maintainWorker.split(',')
// console.log(this.formData.maintainWorkerId)
}
})
})
},
resetForm() {
this.$refs['elForm'].resetFields()
},
annexBeforeUpload(file) {
const isRightSize = file.size / 1024 / 1024 < 2
if (!isRightSize) {
this.$message.error(i18n.t('module.equipmentManager.sparepart.large'))
}
return isRightSize
},
handleSuccess(res, file) {
// console.log(res)
this.fileList.push({ name: file.name, id: res.data[0].id })
const arr = this.fileList.map(item => {
return {
name: item.name,
id: item.id
}
})
let str = ''
arr.forEach((v) => {
str += v.name + ':' + v.id + ';'
})
this.formData.annex = str.slice(0, -1)
},
async getDict() {
// const result3 = await getLogCode()
// if (result3.code === 0) {
// this.formData.logMaintenanceOrderNumber = result3.data
// }
const result = await getDictDevice({
current: 1,
size: 999
})
this.dict.device = result
// console.log(result)
const result2 = await getDictWorker()
this.dict.worker = result2
const listQuery = {
current: 1,
size: 500
}
// 获取保养类型
await dataDictionaryDataList(Object.assign(listQuery, {
dictTypeId: '1393401964580093954'
})).then(response => {
if (response.data.records) {
this.dict.maintainType = response.data.records
console.log(this.dict.maintainType)
}
})
},
turnBack() {
this.$router.go(-1)
},
async getInfo() {
if (this.orderId) {
this.valDisabled = true
const result = await getMaintainPlan({
id: this.orderId,
current: 1,
size: 10
})
if (result.code === 0) {
// console.log(result)
// 根据equipmentId查询equipmentName
// const res = await getEqListDetail({
// current: 1,
// size: 999,
// id: result.data[0].equipmentId
// })
// console.log(res)
this.formData.equipmentId = result.data[0].equipmentId
this.formData.equipmentName = result.data[0].equipmentName
this.formData.status = result.data[0].status
this.formData.maintenanceOrderNumber = result.data[0].maintenanceOrderNumber
this.formData.orderNumber = result.data[0].maintenanceOrderNumber
// console.log(this.formData.equipmentId)
}
}
},
changeEq(val) {
this.formData.equipmentId = val
},
changeWorker(val) {
// console.log(val)
}
}
}
</script>
<style lang="scss">
.form-container {
padding: 30px;
.method-btn-area {
padding: 15px 30px;
margin: 10px 0 20px 0;
border: 1px solid #dfe6ec;
}
}
.el-upload__tip {
line-height: 1.2;
}
/* 上传按钮样式 */
.uploadButton{
width: 106px;
height: 32px;
background: #FFFFFF;
border-radius: 4px;
border: 1px solid #D9D9D9;
}
</style>

View File

@@ -0,0 +1,426 @@
<template>
<!-- <div class="form-container"> -->
<div>
<el-dialog v-bind="$attrs" :title="readonly ? $t('module.equipmentManager.maintainlog.maintainDetail') : $t('module.equipmentManager.maintainlog.maintainEdit')" class="dialog" width="50%" v-on="$listeners" @open="onOpen" @close="onClose">
<!-- <div class="method-btn-area">
<el-button type="primary" plain icon="el-icon-arrow-left" @click="turnBack">{{ 'btn.back' | i18nFilter }}</el-button>
</div> -->
<el-form ref="elForm" :model="formData" :rules="rules" label-width="110px">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item v-if="targetInfo.orderId" :label="$t('module.equipmentManager.maintainplan.maintenanceOrderNumber')" prop="maintenanceOrderNumber">
<el-input v-model="formData.maintenanceOrderNumber" :placeholder="$t('module.equipmentManager.maintainlog.placeholdermaintenanceOrderNumber')" :disabled="valDisabled" :style="{width: '100%'}" />
</el-form-item>
<el-form-item :label="$t('module.equipmentManager.maintainlog.equipmentId')" prop="equipmentId">
<!-- equipmentName Id -->
<el-select
v-model="formData.equipmentName"
:placeholder="$t('module.equipmentManager.maintainlog.placeholderequipmentId')"
clearable
:style="{width: '100%'}"
:disabled="readonly"
filterable
@input="changeEq"
>
<el-option
v-for="(item, index) in dict.device"
:key="index"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.maintainlog.maintenanceOrderNumber')" prop="logMaintenanceOrderNumber">
<el-input v-model="formData.logMaintenanceOrderNumber" :placeholder="$t('module.equipmentManager.maintainlog.placeholdermaintenanceOrderNumber')" clearable :style="{width: '100%'}" :disabled="readonly" />
</el-form-item>
</el-col>
</el-row>
<!-- <el-col :span="23">
<el-form-item label="是否结束保养" prop="field104" required>
<el-switch v-model="formData.field104" />
</el-form-item>
</el-col> -->
<!-- <el-col :span="24">
<el-form-item :label="$t('module.equipmentManager.maintainlog.maintainNextTime')" prop="nextMaintenanceTime">
<el-date-picker
v-model="formData.nextMaintenanceTime"
type="datetime"
:style="{width: '100%'}"
:placeholder="$t('module.equipmentManager.maintainlog.placeholdermaintainNextTime')"
clearable
/>
</el-form-item>
</el-col> -->
<el-row :gutter="20">
<el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.maintainlog.maintainStartTime')" prop="actualStartTime">
<el-date-picker
v-model="formData.actualStartTime"
type="datetime"
:style="{width: '100%'}"
:disabled="readonly"
:placeholder="$t('module.equipmentManager.maintainlog.placeholdermaintainStartTime')"
clearable
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.maintainlog.maintainEndTime')" prop="actualEndTime">
<el-date-picker
v-model="formData.actualEndTime"
type="datetime"
:style="{width: '100%'}"
:disabled="readonly"
:placeholder="$t('module.equipmentManager.maintainlog.placeholdermaintainEndTime')"
clearable
/>
</el-form-item>
</el-col>
</el-row>
<el-form-item :label="$t('module.equipmentManager.maintainlog.maintainWorkerId')" prop="maintainWorker">
<el-select
v-model="formData.maintainWorker"
:placeholder="$t('module.equipmentManager.maintainlog.placeholdermaintainWorkerId')"
clearable
multiple
:style="{width: '100%'}"
:disabled="readonly"
>
<el-option
v-for="(item, index) in dict.worker"
:key="index"
:label="item.name"
:value="item.name"
/>
</el-select>
</el-form-item>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.maintainlog.maintainDuration')" prop="maintainDuration">
<el-input v-model="formData.maintainDuration" :placeholder="$t('module.equipmentManager.maintainlog.placeholdermaintainDuration')" clearable :style="{width: '100%'}" :disabled="readonly" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.maintainplan.status')" prop="status">
<el-select
v-model="formData.status"
:placeholder="$t('module.equipmentManager.maintainplan.placeholderstatus')"
clearable
:style="{width: '100%'}"
:disabled="readonly"
>
<el-option
:label="$t('module.equipmentManager.repair.undone')"
:value="0"
/>
<el-option
:label="$t('module.equipmentManager.repair.done')"
:value="1"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-form-item :label="$t('module.equipmentManager.maintainlog.maintenanceDetail')" prop="maintenanceDes">
<el-input
v-model="formData.maintenanceDes"
type="textarea"
:placeholder="$t('module.equipmentManager.maintainlog.placeholdermaintenanceDetail')"
:autosize="{minRows: 4, maxRows: 4}"
:style="{width: '100%'}"
:disabled="readonly"
/>
</el-form-item>
<el-form-item :label="$t('module.equipmentManager.maintainlog.annex')" prop="annex">
<el-upload
ref="annex"
:data="dataObj"
name="files"
:file-list="fileList"
:action="uploadPath"
:show-file-list="true"
:before-upload="annexBeforeUpload"
:on-success="handleSuccess"
:on-preview="openFile"
class="btn"
:disabled="readonly"
>
<el-button class="uploadButton" icon="el-icon-upload2">{{ 'btn.upload' | i18nFilter }}</el-button>
</el-upload>
</el-form-item>
<el-form-item :label="$t('module.equipmentManager.maintainlog.remark')" prop="remark">
<el-input v-model="formData.remark" :placeholder="$t('module.equipmentManager.maintainlog.placeholderremark')" clearable :style="{width: '100%'}" />
</el-form-item>
</el-form>
<!-- <el-form-item size="large">
<el-button type="primary" @click="submitForm">{{ 'btn.submit' | i18nFilter }}</el-button>
<el-button @click="resetForm">{{ 'btn.reset' | i18nFilter }}</el-button>
</el-form-item> -->
<div slot="footer">
<el-button v-if="!readonly" @click="resetForm">{{ 'btn.reset' | i18nFilter }}</el-button>
<el-button v-if="readonly" @click="close">{{ 'btn.cancel' | i18nFilter }}</el-button>
<el-button v-if="!readonly" type="primary" @click="submitForm">{{ 'btn.submit' | i18nFilter }}</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { editMaintainLog, getMaintainLog } from '@/api/equipment/maintain'
import { getDictDevice, getDictWorker } from '@/api/dict'
import i18n from '@/lang'
import { timeIsBefore } from '@/utils'
import { uploadPath } from '@/api/basic'
export default {
components: {},
inheritAttrs: false,
props: {
targetInfo: {
type: Object,
default: () => ({})
},
readonly: {
type: Boolean,
default: () => false
}
},
data() {
return {
formData: {
equipmentId: undefined,
equipmentName: undefined,
logMaintenanceOrderNumber: undefined,
field104: false,
nextMaintenanceTime: null,
actualStartTime: null,
maintainWorkerIdId: undefined,
maintainWorker: '',
maintainDuration: undefined,
actualEndTime: undefined,
maintenanceDes: undefined,
field110: null,
remark: undefined,
status: undefined,
annex: undefined
},
rules: {
equipmentName: [{
required: true,
message: i18n.t('module.equipmentManager.maintainlog.placeholderequipmentId'),
trigger: 'change'
}],
logMaintenanceOrderNumber: [{
required: false,
message: i18n.t('module.equipmentManager.maintainlog.placeholdermaintenanceOrderNumber'),
trigger: 'change'
}],
maintainWorkerId: [{
required: false,
message: i18n.t('module.equipmentManager.maintainlog.placeholdermaintainWorkerId'),
trigger: 'change'
}],
nextMaintenanceTime: [{
required: false,
message: i18n.t('module.equipmentManager.maintainlog.placeholdermaintainNextTime'),
trigger: 'change'
}],
actualStartTime: [{
required: false,
message: i18n.t('module.equipmentManager.maintainlog.placeholderactualStartTime'),
trigger: 'change'
}],
actualEndTime: [{
required: false,
message: i18n.t('module.equipmentManager.maintainlog.placeholderactualEndTime'),
trigger: 'change'
}],
maintainDuration: [{
required: false,
message: i18n.t('module.equipmentManager.maintainplan.placeholdermaintainDuration'),
trigger: 'blur'
}],
maintenanceDes: [{
required: false,
message: i18n.t('module.equipmentManager.maintainlog.placeholdermaintenanceDetail'),
trigger: 'blur'
}],
status: [{
required: false,
message: i18n.t('module.equipmentManager.maintainplan.placeholderstatus'),
trigger: 'blur'
}],
remark: []
},
uploadPath,
fileList: [],
dataObj: { typeCode: 'file' },
dict: {
device: [],
worker: []
}
}
},
computed: {
// orderId() {
// return this.$route.query.orderId
// },
// id() {
// return this.$route.query.id
// }
},
watch: {},
created() {},
mounted() {
// this.getDict()
// this.getInfo()
},
methods: {
onOpen() {
this.getDict()
this.getInfo()
},
onClose() {
this.$refs['elForm'].resetFields()
this.fileList = []
},
close() {
this.$emit('update:visible', false)
},
submitForm() {
this.$refs['elForm'].validate(async valid => {
if (!valid) return
// TODO 提交表单
if (this.formData.actualStartTime && this.formData.actualEndTime && !timeIsBefore(this.formData.actualStartTime, this.formData.actualEndTime)) {
this.$message({
type: 'error',
message: i18n.t('module.equipmentManager.maintainplan.sort')
})
return console.log('拦截')
}
if (this.formData.maintainWorker) {
this.formData.maintainWorker = this.formData.maintainWorker.join(',')
} else {
this.formData.maintainWorker = ''
}
// this.formData.maintainWorkerId = this.formData.maintainWorkerId.join(',')
// this.formData.maintainWorker = this.formData.maintainWorker.join(',')
// console.log(this.formData)
await editMaintainLog(this.formData).then(res => {
if (res.code === 0) {
this.$message({
type: 'success',
message: i18n.t('module.equipmentManager.bom.succeeded')
})
// this.$router.go(-1)
this.$emit('done')
this.close()
}
}).catch(res => {
if (res.code !== 0) {
// this.formData.maintainWorkerId = this.formData.maintainWorkerId.split(',')
this.formData.maintainWorker = this.formData.maintainWorker.split(',')
// console.log(this.formData.maintainWorkerId)
}
})
})
},
resetForm() {
this.$refs['elForm'].resetFields()
},
annexBeforeUpload(file) {
const isRightSize = file.size / 1024 / 1024 < 2
if (!isRightSize) {
this.$message.error(i18n.t('module.equipmentManager.sparepart.large'))
}
return isRightSize
},
openFile(file) {
// console.log(file)
window.open(`${location.origin}/api/common/attachment/downloadFile?type=file&attachmentId=${file.id}`)
},
handleSuccess(res, file) {
// console.log(res)
this.fileList.push({ name: file.name, id: res.data[0].id })
const arr = this.fileList.map(item => {
return {
name: item.name,
id: item.id
}
})
let str = ''
arr.forEach((v) => {
str += v.name + ':' + v.id + ';'
})
this.formData.annex = str.slice(0, -1)
},
async getInfo() {
console.log(this.targetInfo.id)
const result = await getMaintainLog({
// id: this.id
id: this.targetInfo.id
})
console.log(result)
if (result.code === 0) {
this.formData = result.data
// this.formData.equipmentId = this.id
// this.formData.equipmentId = this.targetInfo.id
// this.formData.maintainWorkerId = this.formData.maintainWorkerId.split(',')
this.formData.maintainWorker = this.formData.maintainWorker.split(',')
// console.log(this.formData)
if (this.formData.annex) {
const arr = this.formData.annex.split(';').map(v => {
const obj = {}
const a = v.split(':')
obj.name = a[0]
obj.id = a[1]
return obj
})
this.fileList = arr
console.log(this.fileList)
}
}
},
async getDict() {
const result = await getDictDevice({
current: 1,
size: 999
})
this.dict.device = result
console.log(result)
const result2 = await getDictWorker()
this.dict.worker = result2
},
turnBack() {
this.$router.go(-1)
},
// 监测select下拉框输入获取equipmentId
changeEq(val) {
this.formData.equipmentId = val
console.log(val)
}
}
}
</script>
<style lang="scss">
.form-container {
padding: 30px;
.method-btn-area {
padding: 15px 30px;
margin: 10px 0 20px 0;
border: 1px solid #dfe6ec;
}
}
.el-upload__tip {
line-height: 1.2;
}
/* 上传按钮样式 */
.uploadButton{
width: 106px;
height: 32px;
background: #FFFFFF;
border-radius: 4px;
border: 1px solid #D9D9D9;
}
</style>

View File

@@ -0,0 +1,551 @@
<!--
/*
* @Date: 2022-04-19
* @LastEditTime: 2022-08-03 09:50:17
* @LastEditors: fzq
@FilePath: \basic-admin\src\views\EquipmentManager\MaintainLog\index.vue
* @Description:
-->
<template>
<div class="app-container">
<!-- <top-title /> -->
<head-form
:form-config="headFormConfig"
@headBtnClick="btnClick"
/>
<base-table
:top-btn-config="topBtnConfig"
:table-config="tableProps"
:table-data="list"
:is-loading="listLoading"
:page="listQuery.current"
:limit="listQuery.size"
:height="tableH"
@clickTopBtn="clickTopBtn"
>
<method-btn slot="handleBtn" :width="120" :method-list="tableBtn" :is-fixed="true" @clickBtn="handleClick" />
</base-table>
<pagination v-show="total > 0" :total="total" :page.sync="listQuery.current" :limit.sync="listQuery.size" @pagination="getList" />
<!-- 新增弹窗 -->
<!-- :order-id="{orderId: orderId}" -->
<add-form :visible.sync="showDialog" :order-id="{orderId: orderId}" @done="getList" />
<!-- 编辑/详情弹窗 -->
<edit-form :readonly="readonly" :visible.sync="showEditDialog" :target-info="{id: curEditId}" @done="getList" />
<!-- 更新详情 弹窗-->
</div>
</template>
<script>
import { tableHeight } from '@/utils/index'
import dataDict from '@/filters/DataDict'
// import TopTitle from '@/components/TopTitle'
import HeadForm from '@/components/basicData/HeadForm'
import { timeFormatter } from '@/filters'
import { getDictWorker } from '@/api/dict'
const topBtnConfig = [
{
type: 'add',
btnName: 'btn.add'
}
]
const tableBtn = [{
type: 'detail',
btnName: 'btn.detail'
}, {
type: 'edit',
btnName: 'btn.edit'
}, {
type: 'delete',
btnName: 'btn.delete'
}]
const tableProps = [{
prop: 'equipmentName',
label: i18n.t('module.equipmentManager.maintainlog.equipmentId')
}, {
prop: 'logMaintenanceOrderNumber',
label: i18n.t('module.equipmentManager.maintainlog.maintenanceOrderNumber')
}, {
prop: 'status',
label: i18n.t('module.equipmentManager.maintainlog.status'),
filter: dataDict('doneStatus')
// }, {
// prop: 'logMaintenanceOrderNumber',
// label: i18n.t('module.equipmentManager.maintainlog.maintenanceOrderNumber'),
// isFixed: true
}, {
prop: 'actualStartTime',
label: i18n.t('module.equipmentManager.maintainlog.maintainStartTime'),
filter: timeFormatter
}, {
prop: 'actualEndTime',
label: i18n.t('module.equipmentManager.maintainlog.maintainEndTime'),
filter: timeFormatter
}, {
prop: 'maintainWorker',
label: i18n.t('module.equipmentManager.maintainlog.maintainWorker')
}, {
prop: 'maintainDuration',
label: i18n.t('module.equipmentManager.maintainlog.maintainDuration')
},
// {
// prop: 'equipmentCode',
// label: i18n.t('module.equipmentManager.maintainlog.equipmentCode'),
// isFixed: true
// // filter: dataDict('enableState')
// },
// {
// prop: 'nextMaintenanceTime',
// label: i18n.t('module.equipmentManager.maintainlog.nextMaintenanceTime'),
// isFixed: true,
// filter: timeFormatter
// },
// {
// prop: 'maintenanceDes',
// label: '保养记录',
// isFixed: true
// // filter: dataDict('enableState')
// },
{
prop: 'planned',
label: i18n.t('module.equipmentManager.maintainlog.planned')
}]
const tablePropsOnly = [{
prop: 'logMaintenanceOrderNumber',
label: i18n.t('module.equipmentManager.maintainlog.maintenanceOrderNumber')
}, {
prop: 'actualStartTime',
label: i18n.t('module.equipmentManager.maintainlog.maintainStartTime'),
filter: timeFormatter
}, {
prop: 'actualEndTime',
label: i18n.t('module.equipmentManager.maintainlog.maintainEndTime'),
filter: timeFormatter
}, {
prop: 'maintainDuration',
label: i18n.t('module.equipmentManager.maintainlog.maintainDuration')
},
{
prop: 'relatePlan',
label: i18n.t('module.equipmentManager.maintainlog.isplan'),
show: false
},
{
prop: 'status',
label: i18n.t('module.equipmentManager.maintainplan.status'),
filter: dataDict('doneStatus')
},
{
prop: 'equipmentCode',
label: i18n.t('module.equipmentManager.maintainlog.equipmentCode')
// filter: dataDict('enableState')
},
// {
// prop: 'nextMaintenanceTime',
// label: i18n.t('module.equipmentManager.maintainlog.nextMaintenanceTime'),
// isFixed: true,
// filter: timeFormatter
// },
// {
// prop: 'maintenanceDes',
// label: '保养记录',
// isFixed: true
// // filter: dataDict('enableState')
// },
{
prop: 'remark',
label: i18n.t('module.equipmentManager.maintainlog.remark')
}]
import BaseTable from '@/components/BaseTable'
// edit here
import { getMaintainLogList, delMaintainLog, getSingleMaintainLogList, getEqList } from '@/api/equipment/maintain'
import AddForm from './AddLog'
import EditForm from './EditLog'
import Pagination from '@/components/Pagination'
import MethodBtn from '@/components/BaseTable/subcomponents/MethodBtn'
import { objFilter } from '@/utils'
import i18n from '@/lang'
import { dataDictionaryDataList } from '@/api/basicData/dataDictionary'
// import VisualImgInfoVue from '@/views/basicData/components/VisualImgInfo.vue'
export default {
name: 'OrgManager',
components: { HeadForm, Pagination, BaseTable, MethodBtn, AddForm, EditForm },
props: {},
data() {
return {
topBtnConfig,
tableBtn,
tableProps,
tableH: tableHeight(280),
tablePropsOnly,
list: [],
total: 0,
listLoading: true,
showDialog: false,
curEditId: null,
showEditDialog: false,
readonly: false,
listQuery: {
maintainPlanId: null,
current: 1,
size: 20,
startTime: '',
endTime: '',
relatePlan: 0,
// maintainType: null,
equipmentId: null,
equipmentName: null
// maintainWorkerId: undefined
},
date: null,
array: [],
defaultProps: {
children: 'children',
label: 'label'
},
eqIdArr: [],
maintainTypeArr: [],
workeArr: [],
headFormConfig: [],
headFormValue: {},
result2: []
}
},
computed: {
orderId() {
return this.$route.query.orderId
}
},
watch: {
orderId: function() {
this.isShowSearch()
}
},
created() {
this.isShowSearch()
},
mounted() {
// 固定表头,表格的最大高度随页面的高度自动调整
window.addEventListener('resize', () => {
this.tableH = tableHeight(280)
})
this.getEquipmentList()
this.getDict()
},
methods: {
handleClick(raw) {
console.log(raw)
switch (raw.type) {
case 'delete':
this.$confirm(i18n.t('deleteMsgBox.content'), i18n.t('deleteMsgBox.hint'), {
confirmButtonText: i18n.t('btn.confirm'),
cancelButtonText: i18n.t('btn.cancel'),
type: 'warning'
}).then(async() => {
// 走接口
const result = await delMaintainLog({
id: raw.data.id
})
if (result.code === 0) {
this.$message({
type: 'success',
message: i18n.t('deleteMsgBox.doneMsg')
})
this.getList()
}
})
break
case 'detail':
this.showEditDialog = true
this.readonly = true
this.curEditId = raw.data.id
break
case 'edit':
// this.$router.push({
// name: 'MaintainEditLog',
// query: {
// id: raw.data.id
// }
// })
// console.log(raw)
this.showEditDialog = true
this.readonly = false
this.curEditId = raw.data.id
break
}
},
async getList() {
// console.log(this.headFormValue)
this.listLoading = true
// edit here
if (this.orderId) {
console.log(this.orderId)
this.listQuery.startTime = this.headFormValue.searchTime ? this.headFormValue.searchTime[0] : ''
this.listQuery.endTime = this.headFormValue.searchTime ? this.headFormValue.searchTime[1] : ''
this.listQuery.equipmentName = this.headFormValue.equipmentName
this.listQuery.equipmentId = this.headFormValue.equipmentId
this.listQuery.relatePlan = this.headFormValue.relatePlan ? this.headFormValue.relatePlan : '0'
this.listQuery.maintainPlanId = this.orderId
// const res = await getMaintainLogList(objFilter({
// current: this.listQuery.current,
// size: this.listQuery.size,
// startTime: this.listQuery.startTime,
// endTime: this.listQuery.endTime,
// relatePlan: 0,
// maintainPlanId: this.orderId,
// equipmentName: this.listQuery.equipmentName
// }))
const res = await getMaintainLogList(objFilter(this.listQuery))
console.log(this.listQuery)
if (res.code === 0) {
this.list = res.data
console.log(res)
// this.total = res.data.total
this.listLoading = false
}
} else {
// if (this.headFormValue.worker) {
// console.log(this.headFormValue.worker)
// this.listQuery.maintainWorkerId = this.headFormValue.worker.join(',')
// }
// this.listQuery.equipmentId = this.headFormValue.equipmentId
this.listQuery.equipmentName = this.headFormValue.equipmentName ? this.headFormValue.equipmentName : null
this.listQuery.relatePlan = this.headFormValue.relatePlan ? this.headFormValue.relatePlan : '0'
// this.listQuery.maintainType = this.headFormValue.maintainType
this.listQuery.startTime = this.headFormValue.searchTime ? this.headFormValue.searchTime[0] : null
this.listQuery.endTime = this.headFormValue.searchTime ? this.headFormValue.searchTime[1] : null
console.log(this.listQuery)
const result = await getSingleMaintainLogList(this.listQuery)
// console.log(result)
if (result.code === 0) {
this.list = result.data.records ? result.data.records : []
// 用于显示relatePlan是否显示成汉字
// this.list.forEach(item => {
// if (item.relatePlan === -1) {
// item.relatePlan = '否'
// } else if (item.relatePlan === 1) {
// item.relatePlan = '是'
// }
// })
// work名字与id之间的转化
// console.log(this.list[0].maintainWorker.split(','))
for (var i = 0; i < this.result2.length; i++) {
this.list.forEach(item => {
// item.maintenanceWorker = item.maintenanceWorker.split(',')
if (item.maintainWorker === this.result2.id) {
item.maintainWorker = this.result2.name
}
})
}
this.total = result.data.total
// console.log(this.result2)
console.log(result)
this.listLoading = false
}
}
},
async getEquipmentList() {
const res = await getEqList({
current: 1,
size: 999
})
this.getList()
if (res.code === 0) {
this.eqIdArr = res.data.records.map(item => {
return {
id: item.name,
name: item.name
}
})
// console.log(res)
this.headFormConfig[0].selectOptions = this.eqIdArr
}
},
async getDict() {
const listQuery = {
current: 1,
size: 500
}
await dataDictionaryDataList(Object.assign(listQuery, {
dictTypeId: '1393401964580093954'
})).then(response => {
if (response.data.records) {
this.maintainTypeArr = response.data.records.map(item => {
return {
id: item.id,
name: item.dataName
}
})
// this.headFormConfig[2].selectOptions = this.maintainTypeArr
}
})
this.result2 = await getDictWorker()
// this.workeArr = result2
// this.headFormConfig[3].selectOptions = this.workeArr
// console.log(this.result2)
},
toAddPage() {
this.$router.push({
name: 'MaintainAddLog',
query: {
orderId: this.orderId
}
})
},
isShowSearch() {
if (this.orderId) {
this.headFormConfig = [
{
type: 'select',
label: this.$t('module.equipmentManager.maintainplan.placeholderequipmentId'),
selectOptions: [],
param: 'equipmentName'
},
// {
// type: 'datePicker',
// label: this.$t('module.equipmentManager.maintainlog.maintainlogTime'),
// dateType: 'daterange',
// rangeSeparator: '-',
// startPlaceholder: this.$t('module.equipmentManager.maintainlog.startTime'),
// endPlaceholder: this.$t('module.equipmentManager.maintainlog.endTime'),
// param: 'searchTime'
// },
{
type: 'button',
btnName: 'btn.search',
name: 'search',
color: 'primary'
},
{
type: 'button',
btnName: 'btn.back',
name: 'back',
color: 'primary'
}
]
} else {
this.headFormConfig = [
{
type: 'select',
label: this.$t('module.equipmentManager.maintainlog.equipment'),
selectOptions: [],
param: 'equipmentName'
},
{
type: 'select',
label: this.$t('module.equipmentManager.maintainlog.isplan'),
selectOptions: [
{ id: '0', name: this.$t('module.equipmentManager.maintainlog.planAll') },
{ id: '1', name: this.$t('module.equipmentManager.maintainlog.planYes') },
{ id: '-1', name: this.$t('module.equipmentManager.maintainlog.planNo') }
],
defaultSelect: '0',
param: 'relatePlan'
},
// {
// type: 'select',
// label: this.$t('module.equipmentManager.maintainlog.maintainType'),
// selectOptions: [],
// param: 'maintainType'
// },
// {
// type: 'select',
// label: this.$t('module.equipmentManager.maintainlog.maintainWorkerId'),
// selectOptions: [],
// param: 'worker',
// multiple: true
// },
{
type: 'datePicker',
label: this.$t('module.equipmentManager.maintainlog.maintainlogTime'),
dateType: 'daterange',
format: 'yyyy-MM-dd hh:mm:ss',
valueFormat: 'yyyy-MM-dd hh:mm:ss',
rangeSeparator: '-',
startPlaceholder: this.$t('module.equipmentManager.maintainlog.startTime'),
endPlaceholder: this.$t('module.equipmentManager.maintainlog.endTime'),
param: 'searchTime'
},
{
type: 'button',
btnName: 'btn.search',
name: 'search',
color: 'primary'
// },
// {
// type: 'button',
// btnName: 'btn.add',
// name: 'add',
// color: 'primary'
// },
// {
// type: 'button',
// btnName: 'btn.export',
// name: 'export',
// color: 'success'
}
]
// this.headFormConfig[0].selectOptions = this.eqIdArr
// this.headFormConfig[2].selectOptions = this.maintainTypeArr
// this.headFormConfig[3].selectOptions = this.workeArr
}
},
btnClick(val) {
this.headFormValue = val
// 如果点击的是搜索栏的其他按钮在这里继续写判断
if (this.headFormValue.btnName === 'search') {
this.getList()
} else if (this.headFormValue.btnName === 'add') {
this.toAddPage()
this.showDialog = true// 新增
} else if (this.headFormValue.btnName === 'back') {
this.$router.push({
name: 'MaintainPlan'
})
}
},
clickTopBtn(val) {
if (val === 'add') {
// this.toAddPage()// 新增
this.showDialog = true// 弹窗新增
this.orderId = this.$route.query.orderId
} else if (this.headFormValue.btnName === 'export') {
this.exportExcel()
}
}
// exportExcel() {
// const params = {
// current: 1,
// size: 999,
// equipmentId: this.headFormValue.equipmentId,
// equipmentName: this.headFormValue.equipmentName,
// startTime: this.headFormValue.searchTime ? this.headFormValue.searchTime[0] : null,
// endTime: this.headFormValue.searchTime ? this.headFormValue.searchTime[1] : null
// }
// this.$nextTick(() => {
// exportFile(params).then(response => {
// let fileName = ''
// const contentDisposition = response.headers['content-disposition']
// if (contentDisposition) {
// fileName = contentDisposition.slice(contentDisposition.indexOf('filename=') + 9)
// }
// const blob = new Blob([response.data])
// const reader = new FileReader()
// reader.readAsDataURL(blob)
// reader.onload = (e) => {
// const a = document.createElement('a')
// a.download = fileName
// a.href = e.target.result
// document.body.appendChild(a)
// a.click()
// document.body.removeChild(a)
// }
// })
// })
// },
}
}
</script>
<style lang="scss" scoped>
</style>

View File

@@ -0,0 +1,390 @@
<template>
<div>
<el-dialog v-bind="$attrs" :title="$t('module.equipmentManager.maintainplan.addDialogTitle')" class="dialog" width="50%" v-on="$listeners" @open="onOpen" @close="onClose">
<el-form ref="elForm" :model="formData" :rules="rules" label-width="110px">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.maintainplan.maintenanceOrderNumber')" prop="maintenanceOrderNumber">
<el-input
v-model="formData.maintenanceOrderNumber"
:placeholder="$t('module.equipmentManager.maintainplan.placeholdermaintenanceOrderNumber')"
clearable
:style="{width: '100%'}"
/>
</el-form-item>
<!-- <el-form-item :label="$t('module.equipmentManager.maintainplan.maintainDuration')" prop="maintainDuration">
<el-input v-model="formData.maintainDuration" :placeholder="$t('module.equipmentManager.maintainplan.placeholdermaintainDuration')" clearable :style="{width: '100%'}" />
</el-form-item> -->
</el-col>
<el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.maintainplan.equipmentId')" prop="equipmentId">
<el-select
v-model="formData.equipmentId"
:placeholder="$t('module.equipmentManager.maintainplan.placeholderequipmentId')"
clearable
filterable
:style="{width: '100%'}"
@change="getCode($event)"
>
<el-option
v-for="(item, index) in dict.device"
:key="index"
:label="item.name"
:value="item.id"
:disabled="item.disabled"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-form-item :label="$t('module.equipmentManager.maintainplan.maintainType')" prop="maintainTypeId">
<el-select
v-model="formData.maintainTypeId"
:placeholder="$t('module.equipmentManager.maintainplan.placeholdermaintainType')"
clearable
:style="{width: '100%'}"
>
<el-option
v-for="(item, index) in dict.maintainType"
:key="index"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
<!-- <el-form-item :label="$t('module.equipmentManager.maintainplan.equipmentCode')" prop="equipmentCode">
<el-input v-model="formData.equipmentCode" :placeholder="$t('module.equipmentManager.maintainplan.placeholderequipmentCode')" :style="{width: '100%'}" />
</el-form-item> -->
<!-- <el-form-item :label="$t('module.equipmentManager.maintainplan.erpIdentification')" prop="erpIdentification">
<el-input v-model="formData.erpIdentification" :placeholder="$t('module.equipmentManager.maintainplan.placeholdererpIdentification')" clearable :style="{width: '100%'}" />
</el-form-item> -->
<el-row :gutter="20">
<el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.maintainplan.maintainStartTime')" prop="maintainStartTime">
<el-date-picker
v-model="formData.maintainStartTime"
type="datetime"
:style="{width: '100%'}"
:placeholder="$t('module.equipmentManager.maintainplan.placeholdermaintainStartTime')"
clearable
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.maintainplan.maintainEndTime')" prop="maintainEndTime">
<el-date-picker
v-model="formData.maintainEndTime"
type="datetime"
:style="{width: '100%'}"
:placeholder="$t('module.equipmentManager.maintainplan.placeholdermaintainEndTime')"
clearable
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.maintainplan.maintainDuration')" prop="maintainDuration">
<el-input v-model="formData.maintainDuration" :placeholder="$t('module.equipmentManager.maintainplan.maintainDuration')" clearable :style="{width: '100%'}" />
</el-form-item>
<!-- <el-form-item :label="$t('module.equipmentManager.maintainplan.maintainWorkerId')" prop="maintainWorkerId">
<el-select v-model="formData.maintainWorkerId" multiple placeholder="请选择">
<el-option
v-for="(item,index) in dict.worker"
:key="index"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item> -->
</el-col>
<el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.maintainplan.maintenancePeriodId')" prop="maintenancePeriodId">
<!-- <el-input v-model="formData.maintenancePeriodId" :placeholder="$t('module.equipmentManager.maintainplan.placeholdermaintenancePeriodId')" :style="{width: '100%'}" /> -->
<el-select
v-model="formData.maintenancePeriodId"
:placeholder="$t('module.equipmentManager.maintainplan.placeholdermaintenancePeriodId')"
clearable
:style="{width: '100%'}"
>
<el-option
v-for="(item, index) in dict.maintainPeriodList"
:key="index"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-form-item :label="$t('module.equipmentManager.maintainplan.maintainFuncDesc')" prop="maintainFuncDesc">
<el-input v-model="formData.maintainFuncDesc" :placeholder="$t('module.equipmentManager.maintainplan.placeholdermaintainFuncDesc')" clearable :style="{width: '100%'}" />
</el-form-item>
<!-- <el-form-item :label="$t('module.equipmentManager.maintainplan.status')" prop="status">
<el-select
v-model="formData.status"
:placeholder="$t('module.equipmentManager.maintainplan.placeholderstatus')"
clearable
:style="{width: '100%'}"
>
<el-option
:label="$t('module.equipmentManager.repair.undone')"
:value="0"
/>
<el-option
:label="$t('module.equipmentManager.repair.done')"
:value="1"
/>
</el-select>
</el-form-item> -->
<el-form-item :label="$t('module.equipmentManager.maintainplan.remark')" prop="remark">
<el-input v-model="formData.remark" :placeholder="$t('module.equipmentManager.maintainplan.placeholderremark')" clearable :style="{width: '100%'}" />
</el-form-item>
<el-form-item :label="$t('module.equipmentManager.maintainlog.annex')" prop="annex">
<el-upload
ref="annex"
:data="dataObj"
name="files"
:file-list="fileList"
:action="uploadPath"
:before-upload="annexBeforeUpload"
:on-success="handleSuccess"
class="btn"
>
<el-button class="uploadButton" icon="el-icon-upload2">{{ 'btn.upload' | i18nFilter }}</el-button>
</el-upload>
</el-form-item>
</el-form>
<div slot="footer">
<el-button @click="close">{{ 'btn.cancel' | i18nFilter }}</el-button>
<el-button type="primary" @click="handelConfirm">{{ 'btn.confirm' | i18nFilter }}</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { timeIsBefore } from '@/utils'
import { addMaintainPlan, getPlanCode } from '@/api/equipment/maintain'
import { getDictDevice, maintainPeriod, getDictWorker, getDictRepairType } from '@/api/dict'
import { uploadPath } from '@/api/basic'
import { equipmentInfoDetail } from '@/api/basicData/Equipment/equipmentInfo'
// import { dataDictionaryDataList } from '@/api/basicData/dataDictionary'
import i18n from '@/lang'
export default {
components: {},
inheritAttrs: false,
props: [],
data() {
return {
uploadPath,
annexfileList: [],
fileList: [],
dataObj: { typeCode: 'file' },
formData: {
maintenanceOrderNumber: null,
maintenancePeriod: undefined,
equipmentId: undefined,
maintainStartTime: null,
maintainEndTime: null,
status: 0,
maintainFuncDesc: null,
remark: undefined,
annexUrl: null,
maintainWorkerId: null,
groupId: undefined,
maintainTypeId: undefined
},
rules: {
// maintenanceOrderNumber: [{
// required: true,
// message: i18n.t('module.equipmentManager.maintainplan.placeholdermaintenanceOrderNumber'),
// trigger: 'blur'
// }],
maintenancePeriodId: [{
required: true,
message: i18n.t('module.equipmentManager.maintainplan.placeholdermaintenancePeriodId'),
trigger: 'change'
}],
equipmentId: [{
required: true,
message: i18n.t('module.equipmentManager.maintainplan.placeholderequipmentId'),
trigger: 'change'
}],
// maintainStartTime: [{
// required: true,
// message: i18n.t('module.equipmentManager.maintainplan.placeholdermaintainStartTime'),
// trigger: 'change'
// }],
maintainEndTime: [{
required: false,
message: i18n.t('module.equipmentManager.maintainplan.placeholdermaintainEndTime'),
trigger: 'change'
}],
// lastMaintainTime: [{
// required: true,
// message: i18n.t('module.equipmentManager.maintainplan.placeholderlastMaintainTime'),
// trigger: 'change'
// }],
// nextMaintainTime: [{
// required: true,
// message: i18n.t('module.equipmentManager.maintainplan.placeholdernextMaintainTime'),
// trigger: 'change'
// }],
remark: [{
required: false,
message: i18n.t('module.equipmentManager.maintainplan.placeholderremark'),
trigger: 'blur'
}],
maintainDuration: [{
required: false,
message: i18n.t('module.equipmentManager.maintainplan.placeholdermaintainDuration'),
trigger: 'blur'
}, {
pattern: /^(0|[1-9][0-9]*)$/,
message: i18n.t('module.equipmentManager.maintainplan.int'),
trigger: 'blur'
}],
maintainFuncDesc: [{
required: false,
message: i18n.t('module.equipmentManager.maintainplan.placeholdermaintainFuncDesc'),
trigger: 'blur'
}],
maintainType: [{
required: false,
message: i18n.t('module.equipmentManager.maintainplan.placeholdermaintainType'),
trigger: 'blur'
}],
erpIdentification: [{
required: false,
message: i18n.t('module.equipmentManager.maintainplan.placeholdererpIdentification'),
trigger: 'blur'
}]
},
dict: {
device: [],
maintainPeriodList: [],
worker: [],
maintainType: []
}
}
},
computed: {},
watch: {},
created() {
this.getDict()
},
mounted() {},
methods: {
async onOpen() {
const result = await getPlanCode()
if (result.code === 0) {
this.formData.maintenanceOrderNumber = result.data
}
},
onClose() {
this.$refs['elForm'].resetFields()
this.fileList = []
},
close() {
this.$emit('update:visible', false)
},
handelConfirm() {
this.$refs['elForm'].validate(async valid => {
if (!valid) return
// this.formData.maintainWorkerId = this.formData.maintainWorkerId.join(',')
// TODO 提交表单
if (this.formData.maintainStartTime && this.formData.maintainEndTime && !timeIsBefore(this.formData.maintainStartTime, this.formData.maintainEndTime)) {
this.$message({
type: 'error',
message: i18n.t('module.equipmentManager.maintainplan.sort')
})
return console.log('拦截')
}
console.log(this.formData)
await addMaintainPlan(this.formData).then(res => {
if (res.code === 0) {
this.$message({
type: 'success',
message: i18n.t('module.equipmentManager.bom.succeeded')
})
this.$emit('done')
this.close()
}
}).catch(res => {
if (res.code !== 0) {
// this.formData.maintainWorkerId = this.formData.maintainWorkerId.split(',')
// console.log(this.formData.maintainWorkerId)
}
})
})
},
async getCode($event) {
const result = await equipmentInfoDetail($event)
if (result.code === 0) {
console.log(result)
this.formData.equipmentCode = result.data.code
this.formData.maintenancePeriodId = result.data.maintenanceCycle
this.$forceUpdate()
}
},
annexBeforeUpload(file) {
const isRightSize = file.size / 1024 / 1024 < 2
if (!isRightSize) {
this.$message.error(i18n.t('module.equipmentManager.sparepart.large'))
}
return isRightSize
},
handleSuccess(res, file) {
// console.log(res)
this.fileList.push({ name: file.name, id: res.data[0].id })
const arr = this.fileList.map(item => {
return {
name: item.name,
id: item.id
}
})
let str = ''
arr.forEach((v) => {
str += v.name + ':' + v.id + ';'
})
this.formData.annexUrl = str.slice(0, -1)
},
async getDict() {
const result = await getDictDevice({
current: 1,
size: 999
})
this.dict.device = result
const result2 = await maintainPeriod()
this.dict.maintainPeriodList = result2
// console.log(result2)
const result3 = await getDictRepairType()
this.dict.maintainType = result3
console.log(result3)
const result4 = await getDictWorker()
this.dict.worker = result4
// const listQuery = {
// current: 1,
// size: 500
// }
// await dataDictionaryDataList(Object.assign(listQuery, {
// dictTypeId: '1393401964580093954'
// })).then(response => {
// if (response.data.records) {
// this.dict.maintainType = response.data.records
// }
// })
}
}
}
</script>
<style>
/* 上传按钮样式 */
.uploadButton{
width: 106px;
height: 32px;
background: #FFFFFF;
border-radius: 4px;
border: 1px solid #D9D9D9;
}
</style>

View File

@@ -0,0 +1,480 @@
<template>
<div>
<el-dialog v-bind="$attrs" :title="readonly ? $t('module.equipmentManager.maintainplan.maintainPlanDetail') : $t('module.equipmentManager.maintainplan.editDialogTitle')" class="dialog" width="50%" v-on="$listeners" @open="onOpen" @close="onClose">
<el-form ref="elForm" :model="formData" :rules="rules" label-width="110px">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.maintainplan.maintenanceOrderNumber')" prop="maintenanceOrderNumber">
<el-input
v-model="formData.maintenanceOrderNumber"
:placeholder="$t('module.equipmentManager.maintainplan.placeholdermaintenanceOrderNumber')"
clearable
:style="{width: '100%'}"
:disabled="readonly"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<!-- <el-form-item :label="$t('module.equipmentManager.maintainplan.maintainDuration')" prop="maintainDuration">
<el-input v-model="formData.maintainDuration" :placeholder="$t('module.equipmentManager.maintainplan.placeholdermaintainDuration')" clearable :style="{width: '100%'}" />
</el-form-item> -->
<el-form-item :label="$t('module.equipmentManager.maintainplan.equipmentId')" prop="equipmentId">
<el-select
v-model="formData.equipmentId"
:placeholder="$t('module.equipmentManager.maintainplan.placeholderequipmentId')"
clearable
filterable
:style="{width: '100%'}"
:disabled="readonly"
@change="getCode($event)"
>
<el-option
v-for="(item, index) in dict.device"
:key="index"
:label="item.name"
:value="item.id"
:disabled="item.disabled"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
<!-- <el-form-item :label="$t('module.equipmentManager.maintainplan.equipmentCode')" prop="equipmentCode">
<el-input v-model="formData.equipmentCode" disabled :placeholder="$t('module.equipmentManager.maintainplan.placeholderequipmentCode')" clearable :style="{width: '100%'}" />
</el-form-item> -->
<el-form-item :label="$t('module.equipmentManager.maintainplan.maintainType')" prop="maintainTypeId">
<el-select
v-model="formData.maintainTypeId"
:placeholder="$i18nForm(['placeholder.input', $t('module.equipmentManager.maintainplan.placeholdermaintainType')])"
clearable
:style="{width: '100%'}"
:disabled="readonly"
>
<el-option
v-for="(item, index) in dict.maintainType"
:key="index"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
<!-- <el-form-item :label="$t('module.equipmentManager.maintainplan.maintainWorkerId')" prop="maintainWorkerId">
<el-select v-model="formData.maintainWorkerId" :disabled="readonly" multiple placeholder="请选择">
<el-option
v-for="(item,index) in dict.worker"
:key="index"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item> -->
<!-- <el-form-item v-if="readonly" :label="$t('module.equipmentManager.maintainplan.lastMaintainWorkerId')">
<el-select v-model="lastFormData.maintainWorkerId" :placeholder="$t('module.equipmentManager.maintainplan.lastMaintainWorkerId')" disabled multiple>
<el-option
v-for="(item,index) in dict.worker"
:key="index"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item> -->
<!-- <el-form-item :label="$t('module.equipmentManager.maintainplan.erpIdentification')" prop="erpIdentification">
<el-input v-model="formData.erpIdentification" :disabled="readonly" :placeholder="$t('module.equipmentManager.maintainplan.placeholdererpIdentification')" clearable :style="{width: '100%'}" />
</el-form-item> -->
<!-- <el-form-item :label="$t('module.equipmentManager.maintainplan.lastMaintainTime')" prop="lastMaintainTime">
<el-date-picker
v-model="formData.lastMaintainTime"
type="datetime"
:style="{width: '100%'}"
:placeholder="$t('module.equipmentManager.maintainplan.placeholderlastMaintainTime')"
disabled
/>
</el-form-item>
<el-form-item :label="$t('module.equipmentManager.maintainplan.nextMaintainTime')" prop="nextMaintainTime">
<el-date-picker
v-model="formData.nextMaintainTime"
type="datetime"
:style="{width: '100%'}"
:placeholder="$t('module.equipmentManager.maintainplan.placeholdernextMaintainTime')"
disabled
/>
</el-form-item> -->
<el-row :gutter="20">
<el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.maintainplan.maintainStartTime')" prop="maintainStartTime">
<el-date-picker
v-model="formData.maintainStartTime"
type="datetime"
:style="{width: '100%'}"
:placeholder="$t('module.equipmentManager.maintainplan.placeholdermaintainStartTime')"
clearable
:disabled="readonly"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.maintainplan.maintainEndTime')" prop="maintainEndTime">
<el-date-picker
v-model="formData.maintainEndTime"
type="datetime"
:style="{width: '100%'}"
:placeholder="$t('module.equipmentManager.maintainplan.placeholdermaintainEndTime')"
clearable
:disabled="readonly"
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.maintainplan.maintainDuration')" prop="maintainDuration">
<el-input v-model="formData.maintainDuration" :placeholder="$t('module.equipmentManager.maintainplan.maintainDuration')" clearable :style="{width: '100%'}" :disabled="readonly" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.maintainplan.maintenancePeriodId')" prop="maintenancePeriodId">
<!-- <el-input v-model="formData.maintenancePeriodId" disabled :placeholder="$t('module.equipmentManager.maintainplan.placeholdermaintenancePeriodId')" :style="{width: '100%'}" /> -->
<el-select
v-model="formData.maintenancePeriodId"
:placeholder="$t('module.equipmentManager.maintainplan.placeholdermaintenancePeriodId')"
clearable
:style="{width: '100%'}"
:disabled="readonly"
>
<el-option
v-for="(item, index) in dict.maintainPeriodList"
:key="index"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
<!-- <el-form-item v-if="readonly" :label="$t('module.equipmentManager.maintainplan.lastMaintainStartTime')">
<el-date-picker
v-model="lastFormData.maintainStartTime"
type="datetime"
:style="{width: '100%'}"
clearable
disabled
/>
</el-form-item>
<el-form-item v-if="readonly" :label="$t('module.equipmentManager.maintainplan.lastMaintainEndTime')">
<el-date-picker
v-model="lastFormData.maintainEndTime"
type="datetime"
:style="{width: '100%'}"
clearable
disabled
/>
</el-form-item> -->
<!-- <el-form-item :label="$t('module.equipmentManager.maintainplan.status')" prop="status">
<el-select
v-model="formData.status"
:placeholder="$t('module.equipmentManager.maintainplan.placeholderstatus')"
clearable
:style="{width: '100%'}"
:disabled="readonly"
>
<el-option
label="未完成"
:value="0"
/>
<el-option
label="已完成"
:value="1"
/>
</el-select>
</el-form-item> -->
<el-form-item :label="$t('module.equipmentManager.maintainplan.maintainFuncDesc')" prop="maintainFuncDesc">
<el-input v-model="formData.maintainFuncDesc" :disabled="readonly" :placeholder="$t('module.equipmentManager.maintainplan.placeholdermaintainFuncDesc')" clearable :style="{width: '100%'}" />
</el-form-item>
<el-form-item :label="$t('module.equipmentManager.maintainplan.remark')" prop="remark">
<el-input v-model="formData.remark" :disabled="readonly" :placeholder="$t('module.equipmentManager.maintainplan.placeholderremark')" clearable :style="{width: '100%'}" />
</el-form-item>
<el-form-item :label="$t('module.equipmentManager.maintainlog.annex')" prop="annex">
<el-upload
ref="annex"
:data="dataObj"
name="files"
:file-list="fileList"
:action="uploadPath"
:show-file-list="true"
:before-upload="annexBeforeUpload"
:on-success="handleSuccess"
:on-preview="openFile"
class="btn"
:disabled="readonly"
>
<!-- size="small" type="primary" icon="el-icon-upload2"-->
<el-button :disabled="readonly" class="uploadButton" icon="el-icon-upload2">{{ 'btn.upload' | i18nFilter }}</el-button>
</el-upload>
</el-form-item>
</el-form>
<div slot="footer">
<el-button @click="close">{{ 'btn.cancel' | i18nFilter }}</el-button>
<el-button v-if="!readonly" type="primary" @click="handelConfirm">{{ 'btn.confirm' | i18nFilter }}</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { timeIsBefore } from '@/utils'
import { editMaintainPlan, getMaintainPlan } from '@/api/equipment/maintain'
import { maintainPeriod, getDictWorker, getDictRepairType } from '@/api/dict'
import i18n from '@/lang'
import { uploadPath } from '@/api/basic'
import { equipmentInfoDetail } from '@/api/basicData/Equipment/equipmentInfo'
// import { dataDictionaryDataList } from '@/api/basicData/dataDictionary'
import { getEqList } from '@/api/equipment/eqManager'
export default {
components: {},
inheritAttrs: false,
props: {
targetInfo: {
type: Object,
default: () => ({})
},
readonly: {
type: Boolean,
default: () => false
}
},
data() {
return {
formData: {
maintenanceOrderNumber: undefined,
maintenancePeriodId: undefined,
equipmentId: undefined,
maintainStartTime: null,
maintainEndTime: null,
remark: undefined,
annexUrl: undefined,
maintainTypeId: undefined
},
lastFormData: {
maintainStartTime: null,
maintainEndTime: null,
maintainWorkerId: []
},
uploadPath,
fileList: [],
dataObj: { typeCode: 'file' },
rules: {
maintenanceOrderNumber: [{
required: true,
message: i18n.t('module.equipmentManager.maintainplan.placeholdermaintenanceOrderNumber'),
trigger: 'blur'
}],
maintenancePeriodId: [{
required: false,
message: i18n.t('module.equipmentManager.maintainplan.placeholdermaintenancePeriodId'),
trigger: 'change'
}],
equipmentId: [{
required: true,
message: i18n.t('module.equipmentManager.maintainplan.placeholderequipmentId'),
trigger: 'change'
}],
maintainStartTime: [{
required: false,
message: i18n.t('module.equipmentManager.maintainplan.placeholdermaintainStartTime'),
trigger: 'change'
}],
maintainEndTime: [{
required: false,
message: i18n.t('module.equipmentManager.maintainplan.placeholdermaintainEndTime'),
trigger: 'change'
}],
remark: [{
required: false,
message: i18n.t('module.equipmentManager.maintainplan.placeholderremark'),
trigger: 'blur'
}],
maintainDuration: [{
required: false,
message: i18n.t('module.equipmentManager.maintainplan.placeholdermaintainDuration'),
trigger: 'blur'
}, {
pattern: /^(0|[1-9][0-9]*)$/,
message: i18n.t('module.equipmentManager.maintainplan.int'),
trigger: 'blur'
}]
},
maintenancePeriodOptions: [{
'label': i18n.t('module.equipmentManager.equipmentVisualization.Week'),
'value': 'week'
}, {
'label': i18n.t('module.equipmentManager.equipmentVisualization.Month'),
'value': 'month'
}, {
'label': i18n.t('module.equipmentManager.equipmentVisualization.Year'),
'value': 'year'
}],
dict: {
device: [],
maintainPeriodList: []
}
}
},
computed: {},
watch: {},
created() {
this.getDict()
},
mounted() {},
methods: {
openFile(file) {
// console.log(file)
window.open(`${location.origin}/api/common/attachment/downloadFile?type=file&attachmentId=${file.id}`)
},
onOpen() {
this.getInfo()
},
onClose() {
this.$refs['elForm'].resetFields()
this.fileList = []
},
close() {
this.$emit('update:visible', false)
},
handelConfirm() {
// console.log(this.formData)
// console.log(this.formData.maintainDuration)
this.$refs['elForm'].validate(async valid => {
if (!valid) return
// this.formData.maintainWorkerId = this.formData.maintainWorkerId.join(',')
// TODO 提交表单
if (this.formData.maintainStartTime && this.formData.maintainEndTime && !timeIsBefore(this.formData.maintainStartTime, this.formData.maintainEndTime)) {
this.$message({
type: 'error',
message: i18n.t('module.equipmentManager.maintainplan.sort')
})
return console.log('拦截')
}
const result = await editMaintainPlan(this.formData)
if (result.code === 0) {
this.$message({
type: 'success',
message: i18n.t('module.equipmentManager.bom.succeeded')
})
this.$emit('done')
this.close()
}
})
},
annexBeforeUpload(file) {
const isRightSize = file.size / 1024 / 1024 < 2
if (!isRightSize) {
this.$message.error(i18n.t('module.equipmentManager.sparepart.large'))
}
return isRightSize
},
handleSuccess(res, file) {
// console.log(res)
this.fileList.push({ name: file.name, id: res.data[0].id })
const arr = this.fileList.map(item => {
return {
name: item.name,
id: item.id
}
})
let str = ''
arr.forEach((v) => {
str += v.name + ':' + v.id + ';'
})
this.formData.annexUrl = str.slice(0, -1)
},
async getCode($event) {
const result = await equipmentInfoDetail($event)
if (result.code === 0) {
this.formData.equipmentCode = result.data.code
this.formData.maintenancePeriodId = result.data.maintenanceCycle
this.$forceUpdate()
}
},
async getInfo() {
const result = await getMaintainPlan({
// eslint-disable-next-line no-undef
id: this.targetInfo?.id,
current: 1,
size: 10
})
if (result.code === 0) {
// console.log(result)
this.formData = result.data[0]
// console.log(this.formData)
if (this.readonly && this.formData.lastMaintainPlanId) {
this.getLastInfo(this.formData.lastMaintainPlanId)
}
// console.log(this.formData.annexUrl)
// this.formData.maintainWorker = this.formData.maintainWorker.split(',')
if (this.formData.annexUrl) {
const arr = this.formData.annexUrl.split(';').map(v => {
const obj = {}
const a = v.split(':')
obj.name = a[0]
obj.id = a[1]
return obj
})
this.fileList = arr
console.log(this.fileList)
}
}
},
async getLastInfo(id) {
const result = await getMaintainPlan({
id,
current: 1,
size: 10
})
if (result.code === 0 && result.data.records.length > 0) {
this.lastFormData = result.data.records[0]
this.lastFormData.maintainWorker = this.lastFormData.maintainWorker.split(',')
}
},
async getDict() {
const result = await getEqList({
current: 1,
size: 999
})
this.dict.device = result.data.records
const result2 = await maintainPeriod()
this.dict.maintainPeriodList = result2
const result3 = await getDictRepairType()
this.dict.maintainType = result3
const result4 = await getDictWorker()
console.log(result4)
this.dict.worker = result4
// const listQuery = {
// current: 1,
// size: 500
// }
// await dataDictionaryDataList(Object.assign(listQuery, {
// dictTypeId: '1393401964580093954'
// })).then(response => {
// if (response.data.records) {
// this.dict.maintainType = response.data.records
// }
// })
}
}
}
</script>
<style>
/* 上传按钮样式 */
.uploadButton{
width: 106px;
height: 32px;
background: #FFFFFF;
border-radius: 4px;
border: 1px solid #D9D9D9;
}
.uploadIcon{
background: url('../../../assets/img/uploadIcon.png')no-repeat;
width: 14px;
height: 14px;
}
</style>

View File

@@ -0,0 +1,289 @@
<!--
/*
* @Date: 2022-04-18
* @LastEditTime: 2022-08-09 12:15:13
* @LastEditors: fzq
* @FilePath: \basic-admin\src\views\EquipmentManager\MaintainPlan\index.vue
* @Description:
*/
-->
<template>
<div class="app-container">
<!-- <top-title /> -->
<head-form
:form-config="headFormConfig"
@headBtnClick="btnClick"
/>
<base-table
:top-btn-config="topBtnConfig"
:table-config="tableProps"
:table-data="list"
:is-loading="listLoading"
:page="listQuery.current"
:limit="listQuery.size"
:height="tableH"
@clickTopBtn="clickTopBtn"
>
<method-btn slot="handleBtn" :width="160" :method-list="tableBtn" @clickBtn="handleClick" />
</base-table>
<pagination v-show="total > 0" :total="total" :page.sync="listQuery.current" :limit.sync="listQuery.size" @pagination="getList" />
<add-form :visible.sync="showDialog" @done="getList" />
<edit-form :readonly="readonly" :visible.sync="showEditDialog" :target-info="{id: curEditId}" @done="getList" />
<router-view />
</div>
</template>
<script>
import { tableHeight } from '@/utils/index'
// import dataDict from '@/filters/DataDict'
// import TopTitle from '@/components/TopTitle'
import HeadForm from '@/components/basicData/HeadForm'
// edit here
import { timeFormatter } from '@/filters'
const topBtnConfig = [
{
type: 'add',
btnName: 'btn.add'
}
]
const tableBtn = [{
type: 'detail',
btnName: 'btn.detail'
}, {
type: 'edit',
btnName: 'btn.edit'
}, {
type: 'issue',
btnName: i18n.t('module.equipmentManager.maintainplan.checklog')
}, {
type: 'delete',
btnName: 'btn.delete'
}
]
// 暂时隐藏
const tableProps = [{
prop: 'equipmentName',
label: i18n.t('module.equipmentManager.maintainplan.equipmentId')
// filter: dataDict('enableState')
}, {
prop: 'maintenanceOrderNumber',
label: i18n.t('module.equipmentManager.maintainplan.maintenanceOrderNumber')
},
// {
// prop: 'status',
// label: i18n.t('module.equipmentManager.maintainplan.status'),
// filter: dataDict('doneStatus')
// },
// {
// prop: 'groupName',
// label: i18n.t('module.equipmentManager.maintainplan.EquipmentGrouping'),
// isFixed: true
// },
{
prop: 'maintainStartTime',
label: i18n.t('module.equipmentManager.maintainplan.maintainStartTime'),
filter: timeFormatter
},
{
prop: 'maintainEndTime',
label: i18n.t('module.equipmentManager.maintainplan.maintainEndTime'),
filter: timeFormatter
},
{
prop: 'maintainDuration',
label: i18n.t('module.equipmentManager.maintainplan.maintainDuration')
}, {
prop: 'maintenancePeriod',
label: i18n.t('module.equipmentManager.maintainplan.maintenancePeriodId')
},
{
prop: 'maintainType',
label: i18n.t('module.equipmentManager.maintainplan.maintainType')
// filter: dataDict('doneStatus')
},
{
prop: 'remark',
label: i18n.t('module.equipmentManager.maintainplan.remark')
}
]
import AddForm from './AddForm'
import EditForm from './EditForm'
import BaseTable from '@/components/BaseTable'
import { objFilter } from '@/utils'
// edit here
import { getMaintainPlanPage, delMaintainPlan } from '@/api/equipment/maintain'
import { getRepairDictDevice } from '@/api/dict'
// import { dataDictionaryDataList } from '@/api/basicData/dataDictionary'
import Pagination from '@/components/Pagination'
import MethodBtn from '@/components/BaseTable/subcomponents/MethodBtn'
import i18n from '@/lang'
export default {
name: 'OrgManager',
components: { HeadForm, Pagination, BaseTable, MethodBtn, AddForm, EditForm },
props: {},
data() {
return {
topBtnConfig,
tableBtn,
tableProps,
tableH: tableHeight(280),
list: [],
total: 0,
listLoading: true,
showDialog: false,
curEditId: null,
showEditDialog: false,
readonly: false,
listQuery: {
current: 1,
size: 20,
status: null,
equipmentId: null,
startTime: null,
endTime: null
},
defaultProps: {
children: 'children',
label: 'label'
},
headFormConfig: [
{
type: 'select',
label: this.$t('module.equipmentManager.maintainplan.placeholderequipmentId'),
selectOptions: [],
param: 'equipmentName'
},
// {
// type: 'select',
// label: this.$t('module.equipmentManager.maintainplan.searchPlaceholder'),
// selectOptions: [{ id: '0', name: i18n.t('module.equipmentManager.repair.undone') }, { id: '1', name: i18n.t('module.equipmentManager.repair.done') }],
// param: 'status'
// },
{
type: 'datePicker',
label: '',
dateType: 'daterange',
format: 'yyyy-MM-dd hh:mm:ss',
valueFormat: 'yyyy-MM-dd hh:mm:ss',
rangeSeparator: '-',
startPlaceholder: this.$t('module.equipmentManager.maintainplan.startTime'),
endPlaceholder: this.$t('module.equipmentManager.maintainplan.endTime'),
param: 'searchTime'
},
{
type: 'button',
btnName: 'btn.search',
name: 'search',
color: 'primary'
// },
// {
// type: 'button',
// btnName: 'btn.add',
// name: 'add',
// color: 'primary'
}
],
headFormValue: {}
}
},
created() {
this.getList()
// this.listLoading = false
this.getDict()
},
mounted() {
// 固定表头,表格的最大高度随页面的高度自动调整
window.addEventListener('resize', () => {
this.tableH = tableHeight(280)
})
},
methods: {
handleNodeClick() {},
handleClick(raw) {
console.log(raw)
switch (raw.type) {
case 'delete':
this.$confirm(i18n.t('deleteMsgBox.content'), i18n.t('deleteMsgBox.hint'), {
confirmButtonText: i18n.t('btn.confirm'),
cancelButtonText: i18n.t('btn.cancel'),
type: 'warning'
}).then(async() => {
// 走接口
const result = await delMaintainPlan({
id: raw.data.id
})
if (result.code === 0) {
this.$message({
type: 'success',
message: i18n.t('deleteMsgBox.doneMsg')
})
}
this.getList()
})
break
case 'detail':
this.showEditDialog = true
this.readonly = true
this.curEditId = raw.data.id
break
case 'edit':
this.showEditDialog = true
this.readonly = false
this.curEditId = raw.data.id
break
case 'issue':
this.$router.push({
name: 'MaintainLog',
query: {
orderId: raw.data.id
}
})
break
}
},
async getDict() {
const result = await getRepairDictDevice({
current: 1,
size: 999
})
// console.log(result)
this.headFormConfig[0].selectOptions = result
},
async getList() {
this.listLoading = true
// edit here
this.listQuery.status = this.headFormValue.status
this.listQuery.equipmentId = this.headFormValue.equipmentId
this.listQuery.equipmentName = this.headFormValue.equipmentName
this.listQuery.id = this.headFormValue.id
this.listQuery.startTime = this.headFormValue.searchTime ? this.headFormValue.searchTime[0] : ''
this.listQuery.endTime = this.headFormValue.searchTime ? this.headFormValue.searchTime[1] : ''
// console.log(objFilter(this.listQuery))
const res = await getMaintainPlanPage(objFilter(this.listQuery))
// 接口问题接口没有返回total等
if (res.code === 0) {
this.list = res.data.records ? res.data.records : []
// console.log(this.list)
console.log(res)
this.total = res.data.total
this.listLoading = false
}
},
btnClick(val) {
this.headFormValue = val
// 如果点击的是搜索栏的其他按钮在这里继续写判断
if (this.headFormValue.btnName === 'search') {
this.getList()
} else if (this.headFormValue.btnName === 'add') {
this.showDialog = true// 新增
}
},
clickTopBtn(val) {
if (val === 'add') {
this.showDialog = true// 新增
}
}
}
}
</script>

View File

@@ -0,0 +1,429 @@
<template>
<!-- <div class="form-container"> -->
<div>
<el-dialog v-bind="$attrs" :title="$t('module.equipmentManager.repair.repairExpertAdd')" class="dialog" width="45%" v-on="$listeners" @open="onOpen" @close="onClose">
<!-- <div class="method-btn-area">
<el-button type="primary" plain icon="el-icon-arrow-left" @click="turnBack">{{ 'btn.back' | i18nFilter }}</el-button>
</div> -->
<!-- <el-row :gutter="15" class="page-form-container"> -->
<!-- <el-row :gutter="15" class="page-form-container"> -->
<!-- <div class="method-btn-area">
<el-button type="primary" plain icon="el-icon-arrow-left" @click="turnBack">{{ 'btn.back' | i18nFilter }}</el-button>
</div> -->
<el-form ref="elForm" :model="formData" :rules="rules" size="medium" label-width="110px">
<el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.repair.repairOrderNumber')" prop="repairOrderNumber">
<el-input
v-model="formData.repairOrderNumber"
:placeholder="$t('module.equipmentManager.repair.placeholderrepairOrderNumber')"
clearable
:style="{width: '100%'}"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.repair.equipmentId')" prop="equipmentId">
<el-select
v-model="formData.equipmentId"
:placeholder="$t('module.equipmentManager.repair.placeholderequipmentId')"
clearable
:style="{width: '100%'}"
>
<el-option
v-for="(item, index) in dict.device"
:key="index"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
</el-col>
<!-- <el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.repair.maintenanceStatus')" prop="maintenanceStatus">
<el-select
v-model="formData.maintenanceStatus"
:placeholder="$t('module.equipmentManager.repair.placeholdermaintenanceStatus')"
clearable
:style="{width: '100%'}"
>
<el-option
label="未完成"
:value="0"
/>
<el-option
label="已完成"
:value="1"
/>
</el-select>
</el-form-item>
</el-col> -->
<el-col :span="24">
<el-form-item :label="$t('module.equipmentManager.repair.maintenanceWorker')" prop="maintenanceWorker">
<el-select
v-model="formData.maintenanceWorker"
:placeholder="$t('module.equipmentManager.repair.placeholdermaintenanceWorker')"
clearable
multiple
:style="{width: '100%'}"
>
<el-option
v-for="(item, index) in dict.worker"
:key="index"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.repair.equipmentPosition')" prop="equipmentPosition">
<el-input v-model="formData.equipmentPosition" :placeholder="$t('module.equipmentManager.repair.placeholderequipmentPosition')" clearable :style="{width: '100%'}" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.repair.workerContactInformation')" prop="workerContactInformation">
<el-input
v-model="formData.workerContactInformation"
:placeholder="$t('module.equipmentManager.repair.placeholderworkerContactInformation')"
clearable
:style="{width: '100%'}"
/>
</el-form-item>
</el-col>
<el-col :span="9">
<el-form-item :label="$t('module.equipmentManager.repair.timeOfFailure')" prop="timeOfFailure">
<el-date-picker
v-model="formData.timeOfFailure"
format="yyyy-MM-dd"
value-format="yyyy-MM-ddTHH:mm:ss"
:style="{width: '100%'}"
:placeholder="$t('module.equipmentManager.repair.placeholdertimeOfFailure')"
clearable
/>
</el-form-item>
</el-col>
<!-- <el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.repair.faultLevel')" prop="faultLevel">
<el-select v-model="formData.faultLevel" :placeholder="$t('module.equipmentManager.repair.placeholderfaultLevel')" clearable :style="{width: '100%'}">
<el-option
v-for="(item, index) in dict.faultLevel"
:key="index"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
</el-col> -->
<el-col :span="15">
<el-form-item :label="$t('module.equipmentManager.repair.timerange')" prop="maintenanceStartTime">
<el-date-picker
v-model="dateRange"
type="datetimerange"
:style="{width: '100%'}"
:start-placeholder="$t('module.equipmentManager.repair.startDate')"
:end-placeholder="$t('module.equipmentManager.repair.endDate')"
clearable
@change="dateChange"
/>
</el-form-item>
</el-col>
<!-- <el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.repair.repairMode')" prop="repairMode">
<el-select
v-model="formData.repairMode"
:placeholder="$t('module.equipmentManager.repair.placeholderrepairMode')"
clearable
:style="{width: '100%'}"
>
<el-option
v-for="(item, index) in dict.repairType"
:key="index"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
</el-col> -->
<el-col :span="24">
<el-form-item :label="$t('module.equipmentManager.repair.faultDetail')" prop="faultDetail">
<el-input
v-model="formData.faultDetail"
type="textarea"
:placeholder="$t('module.equipmentManager.repair.placeholderfaultDetail')"
:autosize="{minRows: 4, maxRows: 4}"
:maxlength="200"
:style="{width: '100%'}"
/>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item :label="$t('module.equipmentManager.repair.maintenanceDetail')" prop="maintenanceDetail">
<el-input
v-model="formData.maintenanceDetail"
type="textarea"
:placeholder="$t('module.equipmentManager.repair.placeholdermaintenanceDetail')"
:autosize="{minRows: 4, maxRows: 4}"
:maxlength="200"
:style="{width: '100%'}"
/>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item :label="$t('module.equipmentManager.repair.annex')" prop="annex">
<single-file :file-id="formData.annex" @done="uploadSuccess" />
</el-form-item>
</el-col>
<!-- <el-col :span="24">
<el-form-item :label="$t('module.equipmentManager.repair.repairTools')" prop="repairTools">
<el-input v-model="formData.repairTools" :placeholder="$t('module.equipmentManager.repair.placeholderrepairTools')" clearable :style="{width: '100%'}" />
</el-form-item>
</el-col> -->
<el-col :span="24">
<el-form-item :label="$t('module.equipmentManager.repair.remark')" prop="remark">
<el-input v-model="formData.remark" :placeholder="$t('module.equipmentManager.repair.placeholderremark')" clearable :style="{width: '100%'}" />
</el-form-item>
</el-col>
</el-form>
<div slot="footer">
<el-button type="primary" @click="submitForm">{{ 'btn.submit' | i18nFilter }}</el-button>
<el-button @click="resetForm">{{ 'btn.reset' | i18nFilter }}</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { uploadPath } from '@/api/basic'
import { add } from '@/api/equipment/knowledge'
import { getDictDevice, getDictRepairType, getDictWorker, faultLevelList } from '@/api/dict'
import SingleFile from '@/components/Upload/SingleFile'
import i18n from '@/lang'
export default {
components: {
SingleFile
},
inheritAttrs: false,
props: {
targetInfo: {
type: Object,
default: () => ({})
}
},
data() {
return {
formData: {
repairOrderNumber: undefined,
equipmentId: undefined,
equipmentName: undefined,
maintenanceWorker: [],
maintenanceStatus: undefined,
equipmentPosition: undefined,
workerContactInformation: undefined,
timeOfFailure: undefined,
faultLevel: undefined,
maintenanceStartTime: null,
maintenanceFinishTime: null,
repairMode: undefined,
faultDetail: undefined,
maintenanceDetail: undefined,
annex: '',
repairTools: undefined,
remark: undefined
},
dateRange: null,
rules: {
repairOrderNumber: [{
required: false,
message: i18n.t('module.equipmentManager.repair.placeholderrepairOrderNumber'),
trigger: 'blur'
}],
equipmentId: [{
required: true,
message: i18n.t('module.equipmentManager.repair.placeholderequipmentId'),
trigger: 'change'
}],
maintenanceWorker: [{
required: false,
message: i18n.t('module.equipmentManager.repair.placeholdermaintenanceWorker'),
trigger: 'blur'
}],
maintenanceStatus: [{
required: false,
message: i18n.t('module.equipmentManager.repair.placeholdermaintenanceStatus'),
trigger: 'blur'
}],
equipmentPosition: [{
required: false,
message: i18n.t('module.equipmentManager.repair.placeholderequipmentPosition'),
trigger: 'blur'
}],
workerContactInformation: [{
required: false,
message: i18n.t('module.equipmentManager.repair.placeholderworkerContactInformation'),
trigger: 'blur'
}],
timeOfFailure: [{
required: false,
message: i18n.t('module.equipmentManager.repair.placeholdertimeOfFailure'),
trigger: 'change'
}],
faultLevel: [{
required: false,
message: i18n.t('module.equipmentManager.repair.placeholderfaultLevel'),
trigger: 'change'
}],
repairMode: [{
required: false,
message: i18n.t('module.equipmentManager.repair.placeholderrepairMode'),
trigger: 'change'
}],
faultDetail: [{
required: false,
message: i18n.t('module.equipmentManager.repair.placeholderfaultDetail'),
trigger: 'blur'
}],
maintenanceDetail: [{
required: false,
message: i18n.t('module.equipmentManager.repair.placeholdermaintenanceDetail'),
trigger: 'blur'
}],
remark: [{
required: false,
message: i18n.t('module.equipmentManager.repair.placeholderremark'),
trigger: 'blur'
}],
maintenanceStartTime: [{
required: true,
message: i18n.t('module.equipmentManager.sparepart.placeholdertime'),
trigger: 'blur'
}],
maintenanceFinishTime: [{
required: true,
message: i18n.t('module.equipmentManager.sparepart.placeholdertime'),
trigger: 'blur'
}]
},
annexAction: uploadPath,
annexfileList: [],
dict: {
device: [],
repairType: [],
worker: [],
faultLevel: []
},
deviceObj: {}
}
},
computed: {},
watch: {},
created() {},
mounted() {
this.getDict()
},
methods: {
onOpen() {},
onClose() {
// this.$refs['elForm'].resetFields()
this.resetForm()
this.fileList = []
},
close() {
this.$emit('update:visible', false)
},
uploadSuccess(id) {
console.log(id)
this.formData.annex = id
},
dateChange(date) {
console.log(date)
this.formData.maintenanceStartTime = date[0]
this.formData.maintenanceFinishTime = date[1]
},
submitForm() {
console.log(this.formData)
this.$refs['elForm'].validate(async valid => {
if (!valid) return
// TODO 提交表单
this.formData.equipmentName = this.deviceObj[this.formData.equipmentId]
if (this.formData.maintenanceWorker) {
this.formData.maintenanceWorker = this.formData.maintenanceWorker.join(',')
}
const result = await add(this.formData)
if (result.code === 0) {
this.$message({
type: 'success',
message: '添加成功!'
})
// this.$router.go(-1)
this.$emit('done')
this.close()
}
})
},
resetForm() {
this.$refs['elForm'].resetFields()
this.dateRange = null
this.formData.maintenanceStartTime = null
this.formData.maintenanceFinishTime = null
},
annexBeforeUpload(file) {
const isRightSize = file.size / 1024 / 1024 < 10
if (!isRightSize) {
this.$message.error('文件大小超过 10MB')
}
return isRightSize
},
async getDict() {
const result = await getDictDevice({
current: 1,
size: 999
})
this.dict.device = result
result.map(item => {
this.deviceObj[item.id] = item.name
})
const result2 = await getDictRepairType()
this.dict.repairType = result2
const result3 = await getDictWorker()
this.dict.worker = result3
const result4 = await faultLevelList()
this.dict.faultLevel = result4
// const result5 = await getCode()
// this.formData.repairOrderNumber = result5.data
},
turnBack() {
this.$router.go(-1)
}
// equipmentIdChange(index) {
// this.formData.equipmentName = this.dict.device[index]
// }
}
}
</script>
<style lang="scss">
// .page-form-container {
// padding: 20px;
// .method-btn-area {
// padding: 15px 30px;
// margin: 10px 0 20px 0;
// border: 1px solid #dfe6ec;
// }
// }
// .form-container {
// padding-top: 40px;
// }
// .el-upload__tip {
// line-height: 1.2;
// }
.form-container {
padding: 30px;
.method-btn-area {
padding: 15px 30px;
margin: 10px 0 20px 0;
border: 1px solid #dfe6ec;
}
}
.el-upload__tip {
line-height: 1.2;
}
</style>

View File

@@ -0,0 +1,446 @@
<template>
<!-- <div class="form-container"> -->
<div>
<el-dialog v-bind="$attrs" :title="readonly ? $t('module.equipmentManager.repair.repairExpertDetail') : $t('module.equipmentManager.repair.repairExpertEdit')" class="dialog" width="45%" v-on="$listeners" @open="onOpen" @close="onClose">
<!-- <div class="method-btn-area">
<el-button type="primary" plain icon="el-icon-arrow-left" @click="turnBack">{{ 'btn.back' | i18nFilter }}</el-button>
</div> -->
<!-- <el-row :gutter="15" class="page-form-container"> -->
<!-- <el-row :gutter="15" class="page-form-container"> -->
<!-- <div class="method-btn-area">
<el-button type="primary" plain icon="el-icon-arrow-left" @click="turnBack">{{ 'btn.back' | i18nFilter }}</el-button>
</div> -->
<el-form ref="elForm" :model="formData" :rules="rules" size="medium" label-width="110px">
<el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.repair.repairOrderNumber')" prop="repairOrderNumber">
<el-input
v-model="formData.repairOrderNumber"
:placeholder="$t('module.equipmentManager.repair.placeholderrepairOrderNumber')"
clearable
:style="{width: '100%'}"
:disabled="readonly"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.repair.equipmentId')" prop="equipmentId">
<el-select
v-model="formData.equipmentId"
:placeholder="$t('module.equipmentManager.repair.placeholderequipmentId')"
clearable
:style="{width: '100%'}"
:disabled="readonly"
>
<el-option
v-for="(item, index) in dict.device"
:key="index"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
</el-col>
<!-- <el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.repair.maintenanceStatus')" prop="maintenanceStatus">
<el-select
v-model="formData.maintenanceStatus"
:placeholder="$t('module.equipmentManager.repair.placeholdermaintenanceStatus')"
clearable
:disabled="readonly"
:style="{width: '100%'}"
>
<el-option
label="未完成"
:value="0"
/>
<el-option
label="已完成"
:value="1"
/>
</el-select>
</el-form-item>
</el-col> -->
<el-col :span="24">
<el-form-item :label="$t('module.equipmentManager.repair.maintenanceWorker')" prop="maintenanceWorker">
<el-select
v-model="formData.maintenanceWorker"
:placeholder="$t('module.equipmentManager.repair.placeholdermaintenanceWorker')"
clearable
multiple
:disabled="readonly"
:style="{width: '100%'}"
>
<el-option
v-for="(item, index) in dict.worker"
:key="index"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.repair.equipmentPosition')" prop="equipmentPosition">
<el-input v-model="formData.equipmentPosition" :placeholder="$t('module.equipmentManager.repair.placeholderequipmentPosition')" clearable :style="{width: '100%'}" :disabled="readonly" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.repair.workerContactInformation')" prop="workerContactInformation">
<el-input
v-model="formData.workerContactInformation"
:placeholder="$t('module.equipmentManager.repair.placeholderworkerContactInformation')"
clearable
:style="{width: '100%'}"
:disabled="readonly"
/>
</el-form-item>
</el-col>
<el-col :span="9">
<el-form-item :label="$t('module.equipmentManager.repair.timeOfFailure')" prop="timeOfFailure">
<el-date-picker
v-model="formData.timeOfFailure"
format="yyyy-MM-dd"
:style="{width: '100%'}"
:placeholder="$t('module.equipmentManager.repair.placeholdertimeOfFailure')"
clearable
:disabled="readonly"
/>
</el-form-item>
</el-col>
<!-- <el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.repair.faultLevel')" prop="faultLevel">
<el-select v-model="formData.faultLevel" :placeholder="$t('module.equipmentManager.repair.placeholderfaultLevel')" clearable :style="{width: '100%'}" :disabled="readonly">
<el-option
v-for="(item, index) in dict.faultLevel"
:key="index"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
</el-col> -->
<el-col :span="15">
<el-form-item :label="$t('module.equipmentManager.repair.timerange')" prop="maintenanceStartTime">
<el-date-picker
v-model="dateRange"
type="datetimerange"
:style="{width: '100%'}"
:start-placeholder="$t('module.equipmentManager.repair.startDate')"
:end-placeholder="$t('module.equipmentManager.repair.endDate')"
clearable
:disabled="readonly"
@change="dateChange"
/>
</el-form-item>
</el-col>
<!-- <el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.repair.repairMode')" prop="repairMode">
<el-select
v-model="formData.repairMode"
:placeholder="$t('module.equipmentManager.repair.placeholderrepairMode')"
clearable
:style="{width: '100%'}"
:disabled="readonly"
>
<el-option
v-for="(item, index) in dict.repairType"
:key="index"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
</el-col> -->
<el-col :span="24">
<el-form-item :label="$t('module.equipmentManager.repair.faultDetail')" prop="faultDetail">
<el-input
v-model="formData.faultDetail"
type="textarea"
:placeholder="$t('module.equipmentManager.repair.placeholderfaultDetail')"
:autosize="{minRows: 4, maxRows: 4}"
:style="{width: '100%'}"
:maxlength="200"
:disabled="readonly"
/>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item :label="$t('module.equipmentManager.repair.maintenanceDetail')" prop="maintenanceDetail">
<el-input
v-model="formData.maintenanceDetail"
type="textarea"
:placeholder="$t('module.equipmentManager.repair.placeholdermaintenanceDetail')"
:autosize="{minRows: 4, maxRows: 4}"
:style="{width: '100%'}"
:maxlength="200"
:disabled="readonly"
/>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item :label="$t('module.equipmentManager.repair.annex')" prop="annex">
<single-file :file-id="formData.annex" :disabled="readonly" @done="uploadSuccess" />
</el-form-item>
</el-col>
<!-- <el-col :span="24">
<el-form-item :label="$t('module.equipmentManager.repair.repairTools')" prop="repairTools">
<el-input v-model="formData.repairTools" :disabled="readonly" :placeholder="$t('module.equipmentManager.repair.placeholderrepairTools')" clearable :style="{width: '100%'}" />
</el-form-item>
</el-col> -->
<el-col :span="24">
<el-form-item :label="$t('module.equipmentManager.repair.remark')" prop="remark">
<el-input v-model="formData.remark" :placeholder="$t('module.equipmentManager.repair.placeholderremark')" clearable :style="{width: '100%'}" :disabled="readonly" />
</el-form-item>
</el-col>
</el-form>
<div slot="footer">
<el-button v-if="!readonly" type="primary" @click="submitForm">{{ 'btn.submit' | i18nFilter }}</el-button>
<el-button v-if="!readonly" @click="resetForm">{{ 'btn.reset' | i18nFilter }}</el-button>
<el-button v-if="readonly" @click="close">{{ 'btn.cancel' | i18nFilter }}</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { edit, getInfo } from '@/api/equipment/knowledge'
import { getDictDevice, getDictRepairType, getDictWorker, faultLevelList } from '@/api/dict'
import SingleFile from '@/components/Upload/SingleFile'
import i18n from '@/lang'
export default {
components: {
SingleFile
},
props: {
targetInfo: {
type: Object,
default: () => ({})
},
readonly: {
type: Boolean,
default: () => false
}
},
data() {
return {
formData: {
repairOrderNumber: undefined,
equipmentId: undefined,
maintenanceWorker: [],
maintenanceStatus: null,
equipmentPosition: undefined,
workerContactInformation: undefined,
timeOfFailure: undefined,
faultLevel: undefined,
maintenanceStartTime: null,
maintenanceFinishTime: null,
repairMode: undefined,
faultDetail: undefined,
maintenanceDetail: undefined,
annex: '',
repairTools: undefined,
remark: undefined
},
dateRange: null,
rules: {
repairOrderNumber: [{
required: false,
message: i18n.t('module.equipmentManager.repair.placeholderrepairOrderNumber'),
trigger: 'blur'
}],
equipmentId: [{
required: true,
message: i18n.t('module.equipmentManager.repair.placeholderequipmentId'),
trigger: 'change'
}],
maintenanceWorker: [{
required: false,
message: i18n.t('module.equipmentManager.repair.placeholdermaintenanceWorker'),
trigger: 'blur'
}],
maintenanceStatus: [{
required: false,
message: i18n.t('module.equipmentManager.repair.placeholdermaintenanceStatus'),
trigger: 'blur'
}],
equipmentPosition: [{
required: false,
message: i18n.t('module.equipmentManager.repair.placeholderequipmentPosition'),
trigger: 'blur'
}],
workerContactInformation: [{
required: false,
message: i18n.t('module.equipmentManager.repair.placeholderworkerContactInformation'),
trigger: 'blur'
}],
timeOfFailure: [{
required: false,
message: i18n.t('module.equipmentManager.repair.placeholdertimeOfFailure'),
trigger: 'change'
}],
faultLevel: [{
required: false,
message: i18n.t('module.equipmentManager.repair.placeholderfaultLevel'),
trigger: 'change'
}],
repairMode: [{
required: false,
message: i18n.t('module.equipmentManager.repair.placeholderrepairMode'),
trigger: 'change'
}],
faultDetail: [{
required: false,
message: i18n.t('module.equipmentManager.repair.placeholderfaultDetail'),
trigger: 'blur'
}],
maintenanceDetail: [{
required: false,
message: i18n.t('module.equipmentManager.repair.placeholdermaintenanceDetail'),
trigger: 'blur'
}],
remark: [{
required: false,
message: i18n.t('module.equipmentManager.repair.placeholderremark'),
trigger: 'blur'
}],
maintenanceStartTime: [{
required: true,
message: i18n.t('module.equipmentManager.sparepart.placeholdertime'),
trigger: 'blur'
}],
maintenanceFinishTime: [{
required: true,
message: i18n.t('module.equipmentManager.sparepart.placeholdertime'),
trigger: 'blur'
}]
},
dict: {
device: [],
repairType: [],
worker: [],
faultLevel: []
},
deviceObj: {}
}
},
computed: {
// readonly() {
// return this.$route.query.type === 'readonly'
// },
id() {
// return this.$route.query.id
return this.targetInfo.id
}
},
watch: {},
created() {},
mounted() {
// this.getDict()
// this.getInfo()
},
methods: {
onOpen() {
this.getDict()
this.getInfo()
},
onClose() {
this.$refs['elForm'].resetFields()
this.fileList = []
},
close() {
this.$emit('update:visible', false)
},
uploadSuccess(id) {
console.log(id)
this.formData.annex = id
},
dateChange(date) {
this.formData.maintenanceStartTime = date[0]
this.formData.maintenanceFinishTime = date[1]
},
submitForm() {
this.$refs['elForm'].validate(async valid => {
if (!valid) return
// TODO 提交表单
if (this.dateRange) {
this.formData.maintenanceStartTime = this.dateRange[0]
this.formData.maintenanceFinishTime = this.dateRange[1]
} else {
this.formData.maintenanceStartTime = ''
this.formData.maintenanceFinishTime = ''
}
if (this.formData.maintenanceWorker) {
this.formData.maintenanceWorker = this.formData.maintenanceWorker.join(',')
}
this.formData.equipmentName = this.deviceObj[this.formData.equipmentId]
const result = await edit(this.formData)
if (result.code === 0) {
this.$message({
type: 'success',
message: '修改成功!'
})
// this.$router.go(-1)
this.$emit('done')
this.close()
}
})
},
resetForm() {
this.$refs['elForm'].resetFields()
this.dateRange = null
this.formData.maintenanceStartTime = null
this.formData.maintenanceFinishTime = null
},
async getDict() {
const result = await getDictDevice({
current: 1,
size: 999
})
this.dict.device = result
result.map(item => {
this.deviceObj[item.id] = item.name
})
const result2 = await getDictRepairType()
this.dict.repairType = result2
const result3 = await getDictWorker()
this.dict.worker = result3
const result4 = await faultLevelList()
this.dict.faultLevel = result4
},
async getInfo() {
const result = await getInfo({
id: this.id
})
if (result.code === 0) {
this.formData = result.data
if (this.formData.maintenanceStartTime && this.formData.maintenanceFinishTime) {
this.dateRange = [this.formData.maintenanceStartTime, this.formData.maintenanceFinishTime]
}
if (this.formData.maintenanceWorker) {
this.formData.maintenanceWorker = this.formData.maintenanceWorker.split(',')
}
}
},
turnBack() {
this.$router.go(-1)
}
}
}
</script>
<style lang="scss">
.page-form-container {
padding: 20px;
.method-btn-area {
padding: 15px 30px;
margin: 10px 0 20px 0;
border: 1px solid #dfe6ec;
}
}
.form-container {
padding-top: 40px;
}
.el-upload__tip {
line-height: 1.2;
}
</style>

View File

@@ -0,0 +1,50 @@
<!--
* @Date: 2021-02-20 10:45:21
* @LastEditors: gtz
* @LastEditTime: 2022-06-15 14:57:06
* @FilePath: \mt-bus-fe\src\views\EquipmentManager\MaintenanceExpertlibrary\components\DataDictFilter.vue
* @Description:
-->
<template>
<span @click="emitClick">
{{ result }}
</span>
</template>
<script>
import { dictChange } from '@/utils'
export default {
props: {
injectData: {
type: Object,
default: () => ({})
}
},
data() {
return {
dict: {}
}
},
computed: {
result() {
return this.injectData[this.injectData.prop].split(',').map(item => {
return this.dict[item]
}).join(',')
}
},
created() {
this.getDict()
},
methods: {
emitClick() {
console.log(this.injectData)
},
async getDict() {
if (this.injectData.filter) {
const result = await this.injectData.filter()
this.dict = dictChange(result, { key: 'id', value: 'name' })
}
}
}
}
</script>

View File

@@ -0,0 +1,300 @@
<!--
/*
* @Date: 2022-04-18
* @LastEditTime: 2022-08-25 17:04:53
* @LastEditors: fzq
* @FilePath: \mt-bus-fe\src\views\EquipmentManager\MaintenanceExpertlibrary\index.vue
* @Description:
*/
-->
<template>
<div class="app-container">
<!-- <top-title /> -->
<head-form
:form-config="headFormConfig"
@headBtnClick="btnClick"
/>
<base-table
:top-btn-config="topBtnConfig"
:table-config="tableProps"
:table-data="list"
:is-loading="listLoading"
:page="listQuery.current"
:limit="listQuery.size"
@clickTopBtn="clickTopBtn"
>
<method-btn slot="handleBtn" :width="120" :method-list="tableBtn" @clickBtn="handleClick" />
</base-table>
<!-- total > listQuery.size -->
<pagination v-show="total > 0" :total="total" :page.sync="listQuery.current" :limit.sync="listQuery.size" @pagination="getList" />
<!-- 新增弹窗 -->
<!-- :order-id="{orderId: orderId}" -->
<add-form :visible.sync="showDialog" @done="getList" />
<!-- 编辑/详情弹窗 -->
<edit-form :readonly="readonly" :visible.sync="showEditDialog" :target-info="{id: curEditId}" @done="getList" />
</div>
</template>
<script>
// import dataDict from '@/filters/DataDict'
import DictFilter from './components/DataDictFilter'
// import TopTitle from '@/components/TopTitle'
import HeadForm from '@/components/basicData/HeadForm'
// edit here
import { timeFormatter } from '@/filters'
const topBtnConfig = [
{
type: 'add',
btnName: 'btn.add'
}
]
const tableBtn = [{
type: 'edit',
btnName: 'btn.edit'
}, {
type: 'detail',
btnName: 'btn.detail'
}, {
type: 'delete',
btnName: 'btn.delete'
}]
const tableProps = [{
prop: 'createTime',
label: i18n.t('module.equipmentManager.repair.createTime'),
filter: timeFormatter
}, {
prop: 'repairOrderNumber',
label: i18n.t('module.equipmentManager.repair.repairOrderNumber')
}, {
prop: 'maintenanceStartTime',
label: i18n.t('module.equipmentManager.repair.maintenanceStartTime'),
filter: timeFormatter
}, {
prop: 'maintenanceFinishTime',
label: i18n.t('module.equipmentManager.repair.maintenanceFinishTime'),
filter: timeFormatter
// }, {
// prop: 'maintenanceStatus',
// label: i18n.t('module.equipmentManager.repair.maintenanceStatus'),
// filter: dataDict('doneStatus')
}, {
prop: 'maintenanceDuration',
label: i18n.t('module.equipmentManager.repair.maintenanceDuration')
}, {
prop: 'equipmentName',
label: i18n.t('module.equipmentManager.repair.equipmentName')
}, {
prop: 'maintenanceWorker',
label: i18n.t('module.equipmentManager.repair.maintenanceWorker'),
subcomponent: DictFilter,
filter: getDictWorker
}, {
prop: 'workerContactInformation',
label: i18n.t('module.equipmentManager.repair.workerContactInformation')
}, {
prop: 'remark',
label: i18n.t('module.equipmentManager.repair.remark')
}]
import AddForm from './AddMaintenanceExpertLibrary'
import EditForm from './EditMaintenanceExpertLibrary'
import BaseTable from '@/components/BaseTable'
// edit here
import { objFilter } from '@/utils'
import { getRepairDictDevice } from '@/api/dict'
import { list, del } from '@/api/equipment/knowledge'
import { getDictWorker } from '@/api/dict'
import Pagination from '@/components/Pagination'
import MethodBtn from '@/components/BaseTable/subcomponents/MethodBtn'
import i18n from '@/lang'
export default {
name: 'OrgManager',
components: { HeadForm, Pagination, BaseTable, MethodBtn, AddForm, EditForm },
props: {},
data() {
return {
topBtnConfig,
tableBtn,
tableProps,
datepicker: [],
list: [],
total: 0,
listLoading: true,
showDialog: false,
curEditId: null,
showEditDialog: false,
readonly: false,
listQuery: {
current: 1,
size: 20,
equipmentName: '',
equipmentId: '',
id: '',
startTime: null,
endTime: null,
maintenanceStatus: 1
},
defaultProps: {
children: 'children',
label: 'label'
},
headFormConfig: [
{
type: 'input',
label: this.$t('module.equipmentManager.repair.searchPlaceholder'),
param: 'equipmentName'
},
// {
// type: 'input',
// label: this.$t('module.equipmentManager.repair.searchPlaceholder'),
// placeholder: this.$t('module.equipmentManager.repair.searchPlaceholder'),
// param: 'equipmentName'
// },
// {
// type: 'select',
// label: i18n.t('module.basicData.staff.State'),
// selectOptions: [
// { id: 1, name: i18n.t('module.equipmentManager.repair.done') },
// { id: 0, name: i18n.t('module.equipmentManager.repair.undone') }
// ],
// param: 'maintenanceStatus'
// },
{
type: 'datePicker',
label: '',
dateType: 'daterange',
rangeSeparator: '-',
startPlaceholder: this.$t('module.equipmentManager.repair.startDate'),
endPlaceholder: this.$t('module.equipmentManager.repair.endDate'),
param: 'searchTime'
},
{
type: 'button',
btnName: 'btn.search',
name: 'search',
color: 'primary'
}
// {
// type: 'button',
// btnName: 'btn.add',
// name: 'add',
// color: 'primary'
// },
// {
// type: 'button',
// btnName: 'btn.export',
// name: 'export',
// color: 'success'
// }
],
headFormValue: {}
}
},
created() {
this.getDict()
// this.listLoading = false
this.getList()
},
mounted() {},
methods: {
handleClick(raw) {
// console.log(raw)
switch (raw.type) {
case 'delete':
this.$confirm(i18n.t('deleteMsgBox.content'), i18n.t('deleteMsgBox.hint'), {
confirmButtonText: i18n.t('btn.confirm'),
cancelButtonText: i18n.t('btn.cancel'),
type: 'warning'
}).then(async() => {
// 走接口
const result = await del({
id: raw.data.id
})
if (result.code === 0) {
this.$message({
type: 'success',
message: i18n.t('deleteMsgBox.doneMsg')
})
this.getList()
}
})
break
case 'edit':
// this.$router.push({
// name: 'EditMaintenanceExpertLibrary',
// query: {
// id: raw.data.id
// }
// })
this.showEditDialog = true
this.readonly = false
this.curEditId = raw.data.id
break
case 'detail':
// this.$router.push({
// name: 'EditMaintenanceExpertLibrary',
// query: {
// id: raw.data.id,
// type: 'readonly'
// }
// })
this.showEditDialog = true
this.readonly = true
this.curEditId = raw.data.id
break
}
},
async getList() {
this.listLoading = true
// edit here
console.log(this.headFormValue)
this.listQuery.equipmentName = this.headFormValue.equipmentName
this.listQuery.equipmentId = this.headFormValue.equipmentId
this.listQuery.startTime = this.headFormValue.searchTime ? this.headFormValue.searchTime[0] : null
this.listQuery.endTime = this.headFormValue.searchTime ? this.headFormValue.searchTime[1] : null
this.listQuery.maintenanceStatus = this.headFormValue.maintenanceStatus
const res = await list(objFilter(this.listQuery))
console.log(res)
if (res.code === 0) {
this.list = res.data.records || []
this.total = res.data.total
this.listLoading = false
}
},
async getDict() {
const result = await getRepairDictDevice({
current: 1,
size: 999
})
this.headFormConfig[0].selectOptions = result
this.getList()
},
toAddPage() {
this.$router.push({
name: 'AddMaintenanceExpertLibrary'
})
},
btnClick(val) {
this.headFormValue = val
// 如果点击的是搜索栏的其他按钮在这里继续写判断
if (this.headFormValue.btnName === 'search') {
this.getList()
} else if (this.headFormValue.btnName === 'add') {
// this.toAddPage()
this.showDialog = true// 弹窗新增
} else if (this.headFormValue.btnName === 'export') {
this.exportExcel()
}
},
clickTopBtn(val) {
if (val === 'add') {
// this.toAddPage()// 新增
this.showDialog = true// 弹窗新增
}
}
}
}
</script>
<style lang="scss" scoped>
</style>

View File

@@ -0,0 +1,127 @@
<!--
* @Author: your name
* @Date: 2021-06-26 16:53:05
* @LastEditTime: 2021-06-29 17:30:31
* @LastEditors: Please set LastEditors
* @Description: In User Settings Edit
* @FilePath: \mt-bus-fe\src\views\EquipmentManager\ProcessData\Details.vue
-->
<template>
<div>
<div id="main" style="width: 1000px;height: 800px;" />
</div>
</template>
<script>
import { getProcess } from '@/api/equipment/process'
// import * as echarts from 'echarts'
import echarts from 'echarts'
export default {
data() {
return {
eventId: this.$route.query.eventId,
ParameterName: this.$route.query.ParameterName,
charts: '',
opinionData: ['3', '2', '4', '4', '5'],
time: [],
value: [],
upperLimit: '',
lowerLimit: '',
y: []
}
},
mounted() {
this.getData()
},
methods: {
async getData() {
const result = await getProcess({
eventId: this.eventId
})
if (result.code === 0) {
console.log(result.data)
this.lowerLimit = result.data[1].lowerLimit
this.upperLimit = result.data[1].upperLimit
this.y = [this.lowerLimit - 10, this.lowerLimit - 5, this.lowerLimit, this.lowerLimit * 1 + 5, this.upperLimit, this.upperLimit * 1 + 5, this.upperLimit * 1 + 10]
console.log(this.y)
result.data.forEach(element => {
this.time.unshift(element.createTime.slice(11))
this.value.unshift(element.parameterValue)
})
console.log(this.value)
var data = [
[this.time[0], this.value[0]],
[this.time[1], this.value[1]],
[this.time[2], this.value[2]],
[this.time[3], this.value[3]],
[this.time[4], this.value[4]],
[this.time[5], this.value[5]],
[this.time[6], this.value[6]],
[this.time[7], this.value[7]],
[this.time[8], this.value[8]],
[this.time[9], this.value[9]],
[this.time[10], this.value[10]]
]
var chartDom = document.getElementById('main')
var myChart = echarts.init(chartDom)
var option
option = {
xAxis: {
name: '时间/分钟',
axisLabel: {
show: true,
inside: false, // 是否朝内
rotate: 0, // 旋转角度
margin: 5, // 刻度标签与轴线之间的距离
color: '#999'
},
data: this.time
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
yAxis: {
// scale: true,
name: this.ParameterName,
min: this.lowerLimit * 1 - 10,
max: this.upperLimit * 1 + 10
},
legend: {
data: ['标准值']
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
series: [{
data: data,
type: 'scatter',
markArea: {
data: [
[{
yAxis: this.lowerLimit * 1,
itemStyle: {
color: '#81b22f'
}
}, {
yAxis: this.upperLimit
}]
]
}
}]
}
option && myChart.setOption(option)
}
}
}
}
</script>
<style lang="scss" scoped>
</style>

View File

@@ -0,0 +1,303 @@
<!--
* @Author: your name
* @Date: 2021-06-25 10:17:15
* @LastEditTime: 2021-06-29 21:17:15
* @LastEditors: Please set LastEditors
* @Description: In User Settings Edit
* @FilePath: \mt-bus-fe\src\views\EquipmentManager\ProcessData\ProcessData.vue
-->
<template>
<div>
<div class="image">
<img class="Toughened" src="../../../assets/img/Toughenedfurnace.png" alt="">
<div class="box t-data">
<el-tag class="one">上部1: {{ top }}</el-tag>
<el-tag class="two">上部2:{{ top }} </el-tag>
<el-tag class="three">上部3:{{ top }} </el-tag>
</div>
<div class="box b-data">
<el-tag class="one" style="height:50px">下部1: {{ bottom }} <br> 下部风栅高度 5 mm </el-tag>
<el-tag class="five" style="height:50px">下部2:{{ bottom }} <br> 下部风栅高度 5 mm </el-tag>
<el-tag class="six" style="height:50px">下部3:{{ bottom }} <br> 下部风栅高度 5 mm</el-tag>
</div>
<div class="box rate">
<el-tag size=" medium">传输速率:0.05m/ms </el-tag>
</div>
</div>
<div class="left">
<el-row>
<el-col :span="24">
<el-card class="box-card">
<div class="text item">
高压风机1电流: 11A
</div>
<div class="text item">
高压风机2电流: 11A
</div>
<div class="text item">
低压风机1电流: 11A
</div>
<div class="text item">
低压风机2电流: 11A
</div>
</el-card>
</el-col>
</el-row>
</div>
<div class="right">
<el-row>
<el-col :span="24">
<el-card class="box-card">
<div class="text item">
自检合格率:98%
</div>
<div class="text item">
人工检合格率:99%
</div>
<div class="text item">
下电包装合格率:99.8%
</div>
</el-card>
</el-col>
</el-row>
</div>
<el-col :span="16">
<el-table
:data="tableData"
border
style="width: 100%"
>
<el-table-column
label="序号"
type="index"
width="200"
align="center"
/>
<el-table-column
prop="ParameterName"
label="参数名称"
width="200"
align="center"
/>
<el-table-column
prop="ParametersCode"
label="参数编码"
width="200"
align="center"
/>
<el-table-column
prop="currentValue"
label="当前值"
width="200"
align="center"
/>
<el-table-column
prop="StandardValues"
label="标准值"
width="200"
align="center"
/>
<el-table-column
fixed="right"
label="操作"
width="200"
align="center"
>
<template slot-scope="o">
<el-button
type="text"
size="small"
@click="handleShow(o.row)"
>
详情
</el-button>
</template>
</el-table-column>
</el-table>
</el-col>
</div>
</template>
<script>
export default {
data() {
return {
tem: [715, 710, 705, 700, 690],
tem1: [725, 720, 715, 705, 695],
top: '',
bottom: '',
current: [11, 13, 15, 14, 18],
cur: '',
qualified: [99, 99.8, 99.1, 99.5, 99.6],
qua: '',
list: [],
listLoading: true,
height: [5, 4, 3, 8, 6],
gaodu: '',
tableData: [{
ParameterName: '上部温度℃',
ParametersCode: '213123213',
currentValue: '710',
StandardValues: '715',
eventId: 10001
}, {
ParameterName: '下部温度℃',
ParametersCode: '2131231',
currentValue: '705',
StandardValues: '710',
eventId: 10002
}, {
ParameterName: '急冷风压',
ParametersCode: '3123214',
currentValue: '6500',
StandardValues: '710',
eventId: 10003
}, {
ParameterName: '冷却时间',
ParametersCode: '443434343',
currentValue: '50',
StandardValues: '710',
eventId: 10004
}, {
ParameterName: '冷却风压',
ParametersCode: '434343434',
currentValue: '4500',
StandardValues: '710',
eventId: 10005
}]
}
},
mounted() {
this.changeOne()
this.changeTwo()
this.changeCurrent()
this.changeQualified()
this.changeheight()
},
methods: {
changeOne() {
setInterval(() => {
for (let i = 0; i < this.tem.length; i++) {
setTimeout(() => {
this.top = this.tem[i]
}, 500 * i)
}
}, 500)
},
changeTwo() {
setInterval(() => {
for (let i = 0; i < this.tem.length; i++) {
setTimeout(() => {
this.bottom = this.tem[i]
// console.log(this.tem[i])
}, 500 * i)
}
}, 2500)
},
changeQualified() {
setInterval(() => {
for (let i = 0; i < this.qualified.length; i++) {
setTimeout(() => {
this.qua = this.qualified[i]
}, 500 * i)
}
}, 2500)
},
handleShow(obj) {
const eventId = obj.eventId
const ParameterName = obj.ParameterName
console.log(eventId)
console.log(ParameterName)
this.$router.push({
path: 'Details',
query: {
eventId: eventId,
ParameterName: ParameterName }
})
}
}
}
</script>
<style lang="scss" scoped>
.image{
display: flex;
justify-content: center;
}
.two{
margin-left: 150px;
}
.el-tag{
font-size: 20px;
text-align: center;
}
.three{
margin-left: 80px;
}
.five{
margin-left: 70px;
}
.six{
margin-left: 50px;
}
.Toughened{
width: 80%;
}
.box {
width: 800px;
.top {
text-align: center;
}
.left {
float: left;
width: 60px;
}
.right {
float: right;
width: 60px;
}
.bottom {
clear: both;
text-align: center;
}
.item {
margin: 4px;
}
.left .el-tooltip__popper,
.right .el-tooltip__popper {
padding: 8px 10px;
}
}
.t-data{
position: absolute;
left: 50%;
top: 23%;
}
.b-data{
position: absolute;
left: 50%;
top: 50%;
}
.rate{
position: absolute;
left: 30%;
top: 50%;
}
.left{
position: absolute;
top: 25%;
left: 3%;
}
.right{
position: absolute;
top: 20%;
left: 87%;
}
</style>

View File

@@ -0,0 +1,132 @@
<!--
* @Date: 2022-04-19
* @LastEditTime: 2022-04-19
* @LastEditors: juzi
* @FilePath: \mt-bus-fe\src\views\EquipmentManager\ProcessData\Processequipment.vue
*/
-->
<template>
<div class="app-container">
<top-title />
<head-form
:form-config="headFormConfig"
@headBtnClick="btnClick"
/>
<base-table
:table-config="tableProps"
:table-data="list"
:is-loading="listLoading"
:page="listQuery.current"
:limit="listQuery.size"
/>
<pagination v-show="total > listQuery.size" :total="total" :page.sync="listQuery.current" :limit.sync="listQuery.size" @pagination="getList" />
</div>
</template>
<script>
import TopTitle from '@/components/TopTitle'
import HeadForm from '@/components/basicData/HeadForm'
import BaseTable from '@/components/BaseTable'
import Pagination from '@/components/Pagination'
import i18n from '@/lang'
const topBtnConfig = [
{
type: 'add',
btnName: 'btn.add'
}
]
const tableProps = [{
prop: 'name',
label: '产品名称',
align: 'center'
}, {
prop: 'ParametersCode',
label: '规格说明',
align: 'center'
}, {
prop: 'Devicename',
label: '设备名称',
align: 'center'
},
{
prop: 'processname',
label: '工艺名称',
align: 'center'
},
{
prop: 'processcode',
label: '工艺编码',
align: 'center'
},
{
prop: 'Processversion',
label: '工艺版本',
align: 'center'
}, {
prop: 'pass',
label: '合格率(%)',
align: 'center'
},
{
prop: 'eventId',
label: '分析',
align: 'center'
}]
export default {
components: { TopTitle, HeadForm, Pagination, BaseTable },
data() {
return {
topBtnConfig,
total: 0,
list: [{
name: '35611325',
ParametersCode: '213123213',
Devicename: '钢化炉',
processname: '715',
processcode: '154812',
Processversion: '1.02',
pass: '99.9',
eventId: 10001
}],
listLoading: false,
tableProps,
listQuery: {
current: 1,
size: 10
},
headFormConfig: [
{
type: 'input',
label: i18n.t('module.equipmentManager.processequipment.productInfo'),
placeholder: this.$t('module.equipmentManager.processequipment.productInfo'),
param: 'productInfo'
},
{
type: 'input',
label: i18n.t('module.equipmentManager.processequipment.processname'),
placeholder: this.$t('module.equipmentManager.processequipment.processname'),
param: 'processname'
},
{
type: 'button',
btnName: 'btn.search',
name: 'search',
color: 'primary'
}
],
headFormValue: {}
}
},
methods: {
getList() {},
btnClick(val) {
this.headFormValue = val
// 如果点击的是搜索栏的其他按钮在这里继续写判断
if (this.headFormValue.btnName === 'search') {
// this.getList()
}
}
}
}
</script>

View File

@@ -0,0 +1,106 @@
<!--
* @Author: your name
* @Date: 2021-06-28 15:31:00
* @LastEditTime: 2021-06-29 21:05:31
* @LastEditors: Please set LastEditors
* @Description: In User Settings Edit
* @FilePath: \mt-bus-fe\src\views\EquipmentManager\ProcessData\Three.vue
-->
<template>
<div>
<div id="main" style="width: 1000px;height: 800px;" />
</div>
</template>
<script>
import echarts from 'echarts'
export default {
data() {
return {
key: 11111
}
},
mounted() {
this.getData()
},
methods: {
async getData() {
var chartDom = document.getElementById('main')
var myChart = echarts.init(chartDom)
var option
option = {
title: {
text: '钢化炉影响因素对比图',
top: 10,
left: 10
},
tooltip: {
trigger: 'item',
backgroundColor: 'rgba(0,0,250,0.2)'
},
legend: {
type: 'scroll',
bottom: 10,
data: (function() {
var list = []
for (var i = 1; i < 10; i++) {
list.push('产品' + i)
}
return list
})()
},
visualMap: {
top: 'middle',
right: 10,
show: false,
color: ['red', 'blue'],
calculable: true
},
radar: {
indicator: [
{ text: '上部温度', max: 1 },
{ text: '下部温度', max: 1 },
{ text: '急冷风压', max: 1 },
{ text: '急冷时间', max: 1 },
{ text: '冷却风压', max: 1 }
]
},
series: (function() {
var series = []
for (var i = 1; i < 10; i++) {
series.push({
name: '',
type: 'radar',
symbol: 'none',
lineStyle: {
width: 1
},
emphasis: {
areaStyle: {
color: 'rgba(0,250,0,0.3)'
}
},
data: [{
value: [
(10 - i) * 0.2 * 0.5,
(10 - i) * 0.11,
i * 0.2 * 0.4,
i / 8 * 0.5,
i * 0.1
],
name: '产品' + i
}]
})
}
return series
})()
}
option && myChart.setOption(option)
}
}
}
</script>
<style lang="scss" scoped>
</style>

View File

@@ -0,0 +1,146 @@
<!--
* @Date: 2021-02-01 16:12:13
* @LastEditors: gtz
* @LastEditTime: 2021-04-23 16:43:32
* @FilePath: \basic-admin\src\views\EquipmentManager\RecipeManager\AddForm.vue
* @Description: 添加设备类型配方
-->
<template>
<div>
<el-dialog v-bind="$attrs" :title="$t('module.equipmentManager.recipe.addDialogTitle')" v-on="$listeners" @open="onOpen" @close="onClose">
<el-form ref="elForm" :model="formData" :rules="rules" size="medium" label-width="90px">
<el-form-item :label="$t('module.equipmentManager.recipe.name')" prop="name">
<el-input v-model="formData.name" :placeholder="$t('module.equipmentManager.recipe.placeholdername')" clearable :style="{width: '100%'}" />
</el-form-item>
<el-form-item :label="$t('module.equipmentManager.recipe.equipmentId')" prop="equipmentId">
<el-select
v-model="formData.equipmentId"
:placeholder="$t('module.equipmentManager.recipe.placeholderdevice')"
clearable
filterable
:style="{width: '100%'}"
>
<el-option
v-for="(item, index) in dict.deviceId"
:key="index"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
<el-form-item :label="$t('module.equipmentManager.recipe.code')" prop="code">
<el-input v-model="formData.code" :placeholder="$t('module.equipmentManager.recipe.placeholdercode')" clearable :style="{width: '100%'}" />
</el-form-item>
<el-form-item :label="$t('module.equipmentManager.recipe.description')" prop="description">
<el-input v-model="formData.description" :placeholder="$t('module.equipmentManager.recipe.placeholderdescription')" clearable :style="{width: '100%'}" />
</el-form-item>
<el-form-item :label="$t('module.equipmentManager.recipe.activationState')" prop="activationState" required>
<el-switch v-model="formData.activationState" :active-value="1" :inactive-value="0" />
</el-form-item>
<el-form-item :label="$t('module.equipmentManager.recipe.enabled')" prop="enabled" required>
<el-switch v-model="formData.enabled" :active-value="1" :inactive-value="0" />
</el-form-item>
<el-form-item :label="$t('module.equipmentManager.recipe.remark')" prop="remark">
<el-input v-model="formData.remark" :placeholder="$t('module.equipmentManager.recipe.placeholderremark')" clearable :style="{width: '100%'}" />
</el-form-item>
</el-form>
<div slot="footer">
<el-button @click="close">{{ 'btn.cancel' | i18nFilter }}</el-button>
<el-button type="primary" @click="handelConfirm">{{ 'btn.confirm' | i18nFilter }}</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { getDictDevice } from '@/api/dict'
import { addDeviceRecipe, getDeviceRecipeCode } from '@/api/equipment/recipe'
import i18n from '@/lang'
export default {
components: {},
inheritAttrs: false,
props: [],
data() {
return {
formData: {
name: undefined,
equipmentId: undefined,
code: undefined,
description: undefined,
activationState: 0,
enabled: 1,
remark: undefined
},
rules: {
name: [{
required: true,
message: i18n.t('module.quality.plan.notEmpty'),
trigger: 'blur'
}],
equipmentId: [{
required: true,
message: i18n.t('module.quality.plan.notEmpty'),
trigger: 'change'
}],
code: [{
required: true,
message: i18n.t('module.quality.plan.notEmpty'),
trigger: 'blur'
}],
description: [{
required: false,
message: '请输入配方描述',
trigger: 'blur'
}],
remark: []
},
dict: {
deviceId: []
}
}
},
computed: {},
watch: {},
created() {},
mounted() {
this.getDict()
},
methods: {
async onOpen() {
const result = await getDeviceRecipeCode()
if (result.code === 0) {
this.formData.code = result.data
}
},
onClose() {
this.$refs['elForm'].resetFields()
},
close() {
this.$emit('update:visible', false)
},
handelConfirm() {
this.$refs['elForm'].validate(async valid => {
if (!valid) return
const result = await addDeviceRecipe(this.formData)
if (result.code === 0) {
this.$message({
type: 'success',
message: '添加成功!'
})
this.$emit('done')
this.close()
}
})
},
async getDict() {
const result = await getDictDevice({
current: 1,
size: 999
})
this.dict.deviceId = result
}
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,159 @@
<!--
* @Date: 2021-02-01 16:12:13
* @LastEditors: Please set LastEditors
* @LastEditTime: 2021-05-10 16:56:32
* @FilePath: \basic-admin\src\views\EquipmentManager\RecipeManager\EditForm.vue
* @Description: 编辑设备类型配方
-->
<template>
<div>
<el-dialog v-bind="$attrs" :title="$t('module.equipmentManager.recipe.editDialogTitle')" v-on="$listeners" @open="onOpen" @close="onClose">
<el-form ref="elForm" :model="formData" :rules="rules" size="medium" label-width="90px">
<el-form-item :label="$t('module.equipmentManager.recipe.name')" prop="name">
<el-input v-model="formData.name" :placeholder="$t('module.equipmentManager.recipe.placeholdername')" clearable :style="{width: '100%'}" />
</el-form-item>
<el-form-item :label="$t('module.equipmentManager.recipe.equipmentId')" prop="equipmentId">
<el-select
v-model="formData.equipmentId"
:placeholder="$t('module.equipmentManager.recipe.placeholderdevice')"
clearable
filterable
:style="{width: '100%'}"
>
<el-option
v-for="(item, index) in dict.deviceId"
:key="index"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
<el-form-item :label="$t('module.equipmentManager.recipe.code')" prop="code">
<el-input v-model="formData.code" :placeholder="$t('module.equipmentManager.recipe.placeholdercode')" clearable :style="{width: '100%'}" />
</el-form-item>
<el-form-item :label="$t('module.equipmentManager.recipe.description')" prop="description">
<el-input v-model="formData.description" :placeholder="$t('module.equipmentManager.recipe.placeholderdescription')" clearable :style="{width: '100%'}" />
</el-form-item>
<el-form-item :label="$t('module.equipmentManager.recipe.activationState')" prop="activationState" required>
<el-switch v-model="formData.activationState" :active-value="1" :inactive-value="0" />
</el-form-item>
<el-form-item :label="$t('module.equipmentManager.recipe.enabled')" prop="enabled" required>
<el-switch v-model="formData.enabled" :active-value="1" :inactive-value="0" />
</el-form-item>
<el-form-item :label="$t('module.equipmentManager.recipe.remark')" prop="remark">
<el-input v-model="formData.remark" :placeholder="$t('module.equipmentManager.recipe.placeholderremark')" clearable :style="{width: '100%'}" />
</el-form-item>
</el-form>
<div slot="footer">
<el-button @click="close">{{ 'btn.cancel' | i18nFilter }}</el-button>
<el-button type="primary" @click="handelConfirm">{{ 'btn.confirm' | i18nFilter }}</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { getDictDevice } from '@/api/dict'
import { editDeviceRecipe, getDeviceRecipe } from '@/api/equipment/recipe'
import i18n from '@/lang'
export default {
components: {},
inheritAttrs: false,
props: {
targetInfo: {
type: Object,
default: () => ({})
}
},
data() {
return {
formData: {
name: undefined,
equipmentId: undefined,
code: undefined,
description: undefined,
activationState: 1,
enabled: 1,
remark: undefined
},
rules: {
name: [{
required: true,
message: i18n.t('module.quality.plan.notEmpty'),
trigger: 'blur'
}],
equipmentId: [{
required: true,
message: i18n.t('module.quality.plan.notEmpty'),
trigger: 'change'
}],
code: [{
required: true,
message: i18n.t('module.quality.plan.notEmpty'),
trigger: 'blur'
}],
description: [{
required: false,
message: '请输入配方描述',
trigger: 'blur'
}],
remark: []
},
dict: {
deviceId: []
}
}
},
computed: {},
watch: {},
created() {},
mounted() {
this.getDict()
},
methods: {
onOpen() {
this.getInfo()
},
onClose() {
this.$refs['elForm'].resetFields()
},
close() {
this.$emit('update:visible', false)
},
handelConfirm() {
this.$refs['elForm'].validate(async valid => {
if (!valid) return
console.log(this.formData.activationState)
console.log(this.formData.enabled)
const result = await editDeviceRecipe(this.formData)
if (result.code === 0) {
this.$message({
type: 'success',
message: '修改成功!'
})
this.$emit('done')
this.close()
}
})
},
async getInfo() {
const result = await getDeviceRecipe({
// eslint-disable-next-line no-undef
id: this.targetInfo?.id
})
if (result.code === 0) {
this.formData = result.data
}
},
async getDict() {
const result = await getDictDevice({
current: 1,
size: 999
})
this.dict.deviceId = result
}
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,231 @@
<!--
/*
* @Date: 2022-04-18
* @LastEditTime: 2022-04-18
* @LastEditors: juzi
* @FilePath: \basic-admin\src\views\EquipmentManager\RecipeManager\index.vue
* @Description:
*/
-->
<template>
<div class="app-container">
<top-title />
<head-form
:form-config="headFormConfig"
@headBtnClick="btnClick"
/>
<base-table
:top-btn-config="topBtnConfig"
:table-config="tableProps"
:table-data="list"
:is-loading="listLoading"
:page="listQuery.current"
:limit="listQuery.size"
@clickTopBtn="clickTopBtn"
>
<method-btn slot="handleBtn" :method-list="tableBtn" @clickBtn="handleClick" />
</base-table>
<pagination
v-show="total > 0"
:total="total"
:page.sync="listQuery.current"
:limit.sync="listQuery.size"
@pagination="getList()"
/>
<add-form :visible.sync="showDialog" @done="getList" />
<edit-form :visible.sync="showEditDialog" :target-info="{id: curEditId}" @done="getList" />
</div>
</template>
<script>
import dataDict from '@/filters/DataDict'
import TopTitle from '@/components/TopTitle'
import HeadForm from '@/components/basicData/HeadForm'
const topBtnConfig = [
{
type: 'add',
btnName: 'btn.add'
}
]
// edit here
const tableBtn = [{
type: 'edit',
btnName: 'btn.edit'
}, {
type: 'detail',
btnName: 'btn.detail'
}, {
type: 'delete',
btnName: 'btn.delete'
}
]
const tableProps = [{
prop: 'equipmentId',
label: i18n.t('module.equipmentManager.recipe.equipmentId'),
align: 'center',
subcomponent: DictFilter,
filter: getDictDevice
}, {
prop: 'name',
label: i18n.t('module.equipmentManager.recipe.name'),
align: 'center'
}, {
prop: 'code',
label: i18n.t('module.equipmentManager.recipe.code'),
align: 'center'
}, {
prop: 'activationState',
label: i18n.t('module.equipmentManager.recipe.activationState'),
align: 'center',
filter: dataDict('enableState')
}, {
prop: 'enabled',
label: i18n.t('module.equipmentManager.recipe.enabled'),
align: 'center',
filter: dataDict('enableState')
}, {
prop: 'remark',
label: i18n.t('module.equipmentManager.recipe.remark'),
align: 'center'
}]
import AddForm from './AddForm'
import EditForm from './EditForm'
import BaseTable from '@/components/BaseTable'
import { objFilter } from '@/utils'
import { getDictDevice } from '@/api/dict'
// edit here
import { getDeviceRecipeList, delDeviceRecipe } from '@/api/equipment/recipe'
import DictFilter from '@/components/BaseTable/subcomponents/DataDictFilter'
import Pagination from '@/components/Pagination'
import MethodBtn from '@/components/BaseTable/subcomponents/MethodBtn'
import i18n from '@/lang'
export default {
name: 'OrgManager',
components: { TopTitle, HeadForm, Pagination, BaseTable, MethodBtn, AddForm, EditForm },
props: {},
data() {
return {
topBtnConfig,
tableBtn,
tableProps,
list: [],
total: 0,
listLoading: true,
showDialog: false,
curEditId: null,
showEditDialog: false,
listQuery: {
current: 1,
size: 10,
equipmentId: null,
equipmentRecipeName: ''
},
defaultProps: {
children: 'children',
label: 'label'
},
headFormConfig: [
{
type: 'input',
label: i18n.t('module.basicData.visual.keyword'),
placeholder: this.$t('module.equipmentManager.recipe.searchPlaceholder'),
param: 'equipmentRecipeName'
},
{
type: 'select',
label: this.$t('module.equipmentManager.recipe.deviceselect'),
selectOptions: [],
param: 'equipmentId'
},
{
type: 'button',
btnName: 'btn.search',
name: 'search',
color: 'primary'
}
],
headFormValue: {}
}
},
created() {
this.getDict()
// this.listLoading = false
},
mounted() {},
methods: {
handleNodeClick() {},
handleClick(raw) {
console.log(raw)
switch (raw.type) {
case 'delete':
this.$confirm(i18n.t('deleteMsgBox.content'), i18n.t('deleteMsgBox.hint'), {
confirmButtonText: i18n.t('btn.confirm'),
cancelButtonText: i18n.t('btn.cancel'),
type: 'warning'
}).then(async() => {
// 走接口
const result = await delDeviceRecipe({
id: raw.data.id
})
if (result.code === 0) {
this.$message({
type: 'success',
message: i18n.t('deleteMsgBox.doneMsg')
})
this.getList()
}
})
break
case 'edit':
this.showEditDialog = true
this.curEditId = raw.data.id
break
case 'detail':
this.$router.push({
name: 'RecipeParamManage',
query: {
id: raw.data.id
}
})
break
}
},
async getList() {
this.listLoading = true
// edit here
this.listQuery.equipmentId = this.headFormValue.equipmentId
this.listQuery.equipmentRecipeName = this.headFormValue.equipmentRecipeName
const res = await getDeviceRecipeList(objFilter(this.listQuery))
if (res.code === 0) {
console.log(res)
this.list = res.data
// this.total = res.data.total err:返回值没有返回分页信息
this.listLoading = false
}
},
async getDict() {
const result = await getDictDevice({
current: 1,
size: 999
})
this.headFormConfig[1].selectOptions = result
this.getList()
},
btnClick(val) {
this.headFormValue = val
// 如果点击的是搜索栏的其他按钮在这里继续写判断
if (this.headFormValue.btnName === 'search') {
this.getList()
}
},
clickTopBtn(val) {
if (val === 'add') {
this.showDialog = true// 新增
}
}
}
}
</script>
<style lang="scss" scoped>
</style>

View File

@@ -0,0 +1,118 @@
<!--
* @Date: 2021-01-09 16:25:11
* @LastEditors: guo
* @LastEditTime: 2021-03-20 15:46:42
* @FilePath: \basic-admin\src\views\EquipmentManager\RecipeManager\subpage\AddForm.vue
* @Description: 设备配方添加参数
-->
<template>
<div>
<el-dialog v-bind="$attrs" :title="$t('module.equipmentManager.recipeDetail.addDialogTitle')" v-on="$listeners" @open="onOpen" @close="onClose">
<el-form ref="elForm" :model="formData" :rules="rules" size="medium" label-width="150px">
<el-form-item :label="$t('module.equipmentManager.recipeDetail.recipeParam')" prop="equipmentParameterId">
<el-select
v-model="formData.equipmentParameterId"
:placeholder="$t('module.equipmentManager.recipeDetail.placeholderrecipeParam')"
clearable
:style="{width: '100%'}"
>
<el-option
v-for="(item, index) in dict.param"
:key="index"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
<el-form-item :label="$t('module.equipmentManager.recipeDetail.paramValue')" prop="paramValue">
<el-input v-model="formData.paramValue" :placeholder="$t('module.equipmentManager.recipeDetail.placeholderparamValue')" clearable :style="{width: '100%'}" />
</el-form-item>
<el-form-item :label="$t('module.equipmentManager.recipeDetail.remark')" prop="remark">
<el-input v-model="formData.remark" :placeholder="$t('module.equipmentManager.recipeDetail.placeholderremark')" clearable :style="{width: '100%'}" />
</el-form-item>
</el-form>
<div slot="footer">
<el-button @click="close">{{ 'btn.cancel' | i18nFilter }}</el-button>
<el-button type="primary" @click="handelConfirm">{{ 'btn.confirm' | i18nFilter }}</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { addDeviceRecipeParam } from '@/api/equipment/recipe'
import { equipmentTypeParam } from '@/api/dict'
import i18n from '@/lang'
export default {
components: {},
inheritAttrs: false,
props: {
targetInfo: {
type: Object,
default: () => ({})
}
},
data() {
return {
formData: {
equipmentParameterId: undefined,
equipmentRecipeId: null,
paramValue: undefined,
remark: undefined
},
rules: {
equipmentParameterId: [{
required: true,
message: i18n.t('module.equipmentManager.recipeDetail.placeholderrecipeParam'),
trigger: 'change'
}],
paramValue: [{
required: true,
message: i18n.t('module.equipmentManager.recipeDetail.placeholderparamValue'),
trigger: 'blur'
}],
remark: []
},
dict: {
param: []
}
}
},
computed: {},
watch: {},
created() {},
mounted() {},
methods: {
onOpen() {
this.formData.equipmentRecipeId = this.targetInfo?.id
this.getDict(this.targetInfo?.equipmentType)
},
onClose() {
this.$refs['elForm'].resetFields()
},
close() {
this.$emit('update:visible', false)
},
handelConfirm() {
this.$refs['elForm'].validate(async valid => {
if (!valid) return
const result = await addDeviceRecipeParam(this.formData)
if (result.code === 0) {
this.$message({
type: 'success',
message: '添加成功!'
})
this.$emit('done')
this.close()
}
})
},
async getDict(id) {
const result = await equipmentTypeParam(id)
this.dict.param = result
}
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,127 @@
<!--
* @Date: 2021-01-09 16:25:11
* @LastEditors: guo
* @LastEditTime: 2021-03-20 15:56:09
* @FilePath: \basic-admin\src\views\EquipmentManager\RecipeManager\subpage\EditForm.vue
* @Description: 设备配方添加参数
-->
<template>
<div>
<el-dialog v-bind="$attrs" :title="$t('module.equipmentManager.recipeDetail.editDialogTitle')" v-on="$listeners" @open="onOpen" @close="onClose">
<el-form ref="elForm" :model="formData" :rules="rules" size="medium" label-width="120px">
<el-form-item :label="$t('module.equipmentManager.recipeDetail.recipeParam')" prop="equipmentParameterId">
<el-select
v-model="formData.equipmentParameterId"
:placeholder="$t('module.equipmentManager.recipeDetail.placeholderrecipeParam')"
clearable
:style="{width: '100%'}"
>
<el-option
v-for="(item, index) in dict.param"
:key="index"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
<el-form-item :label="$t('module.equipmentManager.recipeDetail.paramValue')" prop="paramValue">
<el-input v-model="formData.paramValue" :placeholder="$t('module.equipmentManager.recipeDetail.placeholderparamValue')" clearable :style="{width: '100%'}" />
</el-form-item>
<el-form-item :label="$t('module.equipmentManager.recipeDetail.remark')" prop="remark">
<el-input v-model="formData.remark" :placeholder="$t('module.equipmentManager.recipeDetail.placeholderremark')" clearable :style="{width: '100%'}" />
</el-form-item>
</el-form>
<div slot="footer">
<el-button @click="close">{{ 'btn.cancel' | i18nFilter }}</el-button>
<el-button type="primary" @click="handelConfirm">{{ 'btn.confirm' | i18nFilter }}</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { editDeviceRecipeParam, getDeviceRecipeParam } from '@/api/equipment/recipe'
import { equipmentTypeParam } from '@/api/dict'
import i18n from '@/lang'
export default {
components: {},
inheritAttrs: false,
props: {
targetInfo: {
type: Object,
default: () => ({})
}
},
data() {
return {
formData: {
equipmentParameterId: undefined,
equipmentRecipeId: null,
paramValue: undefined,
remark: undefined
},
rules: {
equipmentParameterId: [{
required: true,
message: i18n.t('module.equipmentManager.recipeDetail.placeholderrecipeParam'),
trigger: 'change'
}],
paramValue: [{
required: true,
message: i18n.t('module.equipmentManager.recipeDetail.placeholderparamValue'),
trigger: 'blur'
}],
remark: []
},
dict: {
param: []
}
}
},
computed: {},
watch: {},
created() {},
mounted() {},
methods: {
onOpen() {
// this.formData.equipmentRecipeId = this.targetInfo?.id
this.getInfo()
this.getDict(this.targetInfo?.equipmentType)
},
onClose() {
this.$refs['elForm'].resetFields()
},
close() {
this.$emit('update:visible', false)
},
handelConfirm() {
this.$refs['elForm'].validate(async valid => {
if (!valid) return
const result = await editDeviceRecipeParam(this.formData)
if (result.code === 0) {
this.$message({
type: 'success',
message: '添加成功!'
})
this.$emit('done')
this.close()
}
})
},
async getDict(id) {
const result = await equipmentTypeParam(id)
this.dict.param = result
},
async getInfo() {
const result = await getDeviceRecipeParam({
id: this.targetInfo?.id
})
if (result.code === 0) {
this.formData = result.data
}
}
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,269 @@
<!--
* @Date: 2020-12-15 15:36:52
* @LastEditors: gtz
* @LastEditTime: 2021-04-23 16:45:56
* @FilePath: \basic-admin\src\views\EquipmentManager\RecipeManager\subpage\detail.vue
* @Description:
-->
<template>
<div class="bom-form-container">
<div class="method-btn-area">
<el-button type="primary" plain icon="el-icon-arrow-left" @click="turnBack">{{ 'btn.back' | i18nFilter }}</el-button>
</div>
<el-form ref="elForm" :model="formData" size="medium" label-width="150px">
<el-form-item :label="$t('module.equipmentManager.recipe.equipmentId')" prop="equipmentId">
<el-select
v-model="formData.equipmentId"
:placeholder="$t('module.equipmentManager.recipe.placeholderdevice')"
clearable
disabled
filterable
:style="{width: '100%'}"
>
<el-option
v-for="(item, index) in dict.deviceId"
:key="index"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
<el-form-item :label="$t('module.equipmentManager.recipe.code')" prop="code">
<el-input v-model="formData.code" :style="{width: '100%'}" :disabled="pagetype" />
</el-form-item>
<el-form-item :label="$t('module.equipmentManager.recipe.name')" prop="name">
<el-input v-model="formData.name" :style="{width: '100%'}" :disabled="pagetype" />
</el-form-item>
<el-form-item :label="$t('module.equipmentManager.recipe.description')" prop="description">
<el-input v-model="formData.description" :style="{width: '100%'}" :disabled="pagetype" />
</el-form-item>
<el-form-item :label="$t('module.equipmentManager.recipe.activationState')" prop="activationState" required>
<el-switch v-model="formData.activationState" :disabled="pagetype" :active-value="1" :inactive-value="0" />
</el-form-item>
<el-form-item :label="$t('module.equipmentManager.recipe.enabled')" prop="enabled" required>
<el-switch v-model="formData.enabled" :disabled="pagetype" :active-value="1" :inactive-value="0" />
</el-form-item>
<el-form-item :label="$t('module.equipmentManager.recipe.remark')" prop="remark">
<el-input v-model="formData.remark" :style="{width: '100%'}" :disabled="pagetype" />
</el-form-item>
</el-form>
<!-- <div class="sub-table-container">
<el-divider>{{ $t('module.equipmentManager.recipeDetail.title') }}</el-divider>
<div class="method-btn-area">
<el-button type="primary" style="float: right;margin: 0 20px;" @click="showDialog = true">{{ 'btn.add' | i18nFilter }}</el-button>
</div>
<base-table :table-config="tableProps" :table-data="list" :is-loading="listLoading" :page="listQuery.current" :limit="listQuery.size">
<method-btn slot="handleBtn" :method-list="tableBtn" @clickBtn="handleClick" />
</base-table>
</div> -->
<!-- <pagination v-show="total > listQuery.size" :total="total" :page.sync="listQuery.current" :limit.sync="listQuery.size" @pagination="getList" /> -->
<!-- <add-form :visible.sync="showDialog" :target-info="{id: listQuery.equipmentRecipeId, equipmentType: formData.equipmentType }" @done="getList" />
<edit-form :visible.sync="showEditDialog" :target-info="{id: curEditId, fatherId: listQuery.equipmentRecipeId, equipmentType: formData.equipmentType}" @done="getList" /> -->
</div>
</template>
<script>
// import CheckDetail from '@/components/BaseTable/subcomponents/CheckDetail'
// import dataDict from '@/filters/DataDict'
// edit here
const tableBtn = [{
type: 'edit',
btnName: 'btn.edit'
}, {
type: 'delete',
btnName: 'btn.delete'
}]
const tableProps = [{
prop: 'paramCode',
label: i18n.t('module.equipmentManager.recipeDetail.paramCode'),
align: 'center'
}, {
prop: 'paramName',
label: i18n.t('module.equipmentManager.recipeDetail.paramName'),
align: 'center'
}, {
prop: 'type',
label: i18n.t('module.equipmentManager.recipeDetail.type'),
align: 'center'
}, {
prop: 'minValue',
label: i18n.t('module.equipmentManager.recipeDetail.minValue'),
align: 'center'
}, {
prop: 'maxValue',
label: i18n.t('module.equipmentManager.recipeDetail.maxValue'),
align: 'center'
}, {
prop: 'defaultValue',
label: i18n.t('module.equipmentManager.recipeDetail.defaultValue'),
align: 'center'
}, {
prop: 'unit',
label: i18n.t('module.equipmentManager.recipeDetail.unit'),
align: 'center'
}, {
prop: 'remark',
label: i18n.t('module.equipmentManager.recipeDetail.remark'),
align: 'center'
}]
// import AddForm from './AddForm'
// import EditForm from './EditForm'
// import BaseTable from '@/components/BaseTable'
// import MethodBtn from '@/components/BaseTable/subcomponents/MethodBtn'
// edit here
// import { objFilter } from '@/utils'
import { getDictDevice } from '@/api/dict'
import { getDeviceRecipeParamList, getDeviceRecipe, delDeviceRecipeParam } from '@/api/equipment/recipe'
// import { dictChange } from '@/utils'
// import Pagination from '@/components/Pagination'
import i18n from '@/lang'
export default {
name: 'BOMForm',
// components: { Pagination, BaseTable, MethodBtn, AddForm, EditForm },
props: {},
data() {
return {
tableBtn,
tableProps,
list: [],
total: 0,
listLoading: true,
showDialog: false,
curEditId: null,
showEditDialog: false,
listQuery: {
enabled: 1,
equipmentRecipeId: null,
current: 1,
size: 10
},
formData: {
equipmentCode: undefined,
equipmentName: undefined,
code: undefined,
name: undefined,
enabled: 1,
remark: undefined
},
dict: {
deviceId: {}
}
}
},
computed: {
pagetype() {
return true
// return false
},
typeName() {
if (this.dict.equipmentTypeTable) {
return this.dict.equipmentTypeTable[this.formData.equipmentType]
} else {
return this.formData.equipmentType
}
}
},
created() {
console.log(this.$route.query)
this.listQuery.equipmentRecipeId = this.$route.query.id
this.getDict()
this.getDetail()
this.getList()
// this.listLoading = false
},
mounted() {},
methods: {
handleClick(raw) {
console.log(raw)
switch (raw.type) {
case 'delete':
this.$confirm(i18n.t('deleteMsgBox.content'), i18n.t('deleteMsgBox.hint'), {
confirmButtonText: i18n.t('btn.confirm'),
cancelButtonText: i18n.t('btn.cancel'),
type: 'warning'
}).then(async() => {
// 走接口
const result = await delDeviceRecipeParam({
id: raw.data.id
})
if (result.code === 0) {
this.$message({
type: 'success',
message: i18n.t('deleteMsgBox.doneMsg')
})
this.getList()
}
})
break
case 'edit':
this.showEditDialog = true
this.curEditId = raw.data.id
break
}
},
async getList() {
this.listLoading = true
// edit here
const res = await getDeviceRecipeParamList(this.listQuery)
if (res.code === 0) {
this.list = res.data.records ? res.data.records : []
this.total = res.data.total
this.listLoading = false
}
},
async getDetail() {
const result = await getDeviceRecipe({
id: this.listQuery.equipmentRecipeId
})
if (result.code === 0) {
this.formData = result.data
// console.log(result)
}
},
submitForm() {
this.$refs['elForm'].validate(valid => {
if (!valid) return
// TODO 提交表单
})
},
resetForm() {
this.$refs['elForm'].resetFields()
},
saveForm() {},
async getDict() {
const result = await getDictDevice({
current: 1,
size: 999
})
this.dict.deviceId = result
},
turnBack() {
this.$router.go(-1)
}
}
}
</script>
<style lang="scss" scoped>
@import "@/styles/mixin.scss";
.bom-form-container {
padding: 20px;
.method-btn-area {
padding: 15px 30px;
margin: 10px 0 20px 0;
border: 1px solid #dfe6ec;
@include clearfix;
}
.sub-table-container {
margin-top: 80px;
}
}
.edit-input {
padding-right: 100px;
}
.cancel-btn {
position: absolute;
right: 15px;
top: 10px;
}
</style>

View File

@@ -0,0 +1,449 @@
<template>
<!-- <div class="form-container"> -->
<div>
<el-dialog v-bind="$attrs" :title="$t('module.equipmentManager.repair.repairAdd')" class="dialog" width="60%" v-on="$listeners" @open="onOpen" @close="onClose">
<!-- <div class="method-btn-area">
<el-button type="primary" plain icon="el-icon-arrow-left" @click="turnBack">{{ 'btn.back' | i18nFilter }}</el-button>
</div> -->
<!-- <el-row :gutter="15" class="page-form-container"> -->
<!-- 返回键 -->
<!-- <div class="method-btn-area">
<el-button type="primary" plain icon="el-icon-arrow-left" @click="turnBack">{{ 'btn.back' | i18nFilter }}</el-button>
</div> -->
<el-form ref="elForm" :model="formData" :rules="rules" size="medium" label-width="110px">
<el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.repair.repairOrderNumber')" prop="repairOrderNumber">
<el-input
v-model="formData.repairOrderNumber"
:placeholder="$t('module.equipmentManager.repair.placeholderrepairOrderNumber')"
clearable
:style="{width: '100%'}"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.repair.equipmentId')" prop="equipmentId">
<el-select
v-model="formData.equipmentId"
:placeholder="$t('module.equipmentManager.repair.placeholderequipmentId')"
clearable
:style="{width: '100%'}"
>
<!-- :value="{ 'equipmentId': item.id, 'equipmentName': item.name }" -->
<el-option
v-for="(item, index) in dict.device"
:key="index"
:label="item.name"
:value="item.id"
@click.native="getEquipmentName(item)"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.repair.maintenanceStatus')" prop="maintenanceStatus">
<el-select
v-model="formData.maintenanceStatus"
:placeholder="$t('module.equipmentManager.repair.placeholdermaintenanceStatus')"
clearable
:style="{width: '100%'}"
>
<el-option
:label="$t('module.equipmentManager.repair.undone')"
:value="0"
/>
<el-option
:label="$t('module.equipmentManager.repair.done')"
:value="1"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.repair.maintenanceWorker')" prop="maintenanceWorker">
<el-select
v-model="formData.maintenanceWorker"
:placeholder="$t('module.equipmentManager.repair.placeholdermaintenanceWorker')"
multiple
clearable
:style="{width: '100%'}"
>
<el-option
v-for="(item, index) in dict.worker"
:key="index"
:label="item.name"
:value="item.name"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.repair.workerContactInformation')" prop="workerContactInformation">
<el-input
v-model="formData.workerContactInformation"
:placeholder="$t('module.equipmentManager.repair.placeholderworkerContactInformation')"
clearable
:style="{width: '100%'}"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.repair.faultLevel')" prop="faultLevel">
<el-select v-model="formData.faultLevel" :placeholder="$t('module.equipmentManager.repair.placeholderfaultLevel')" clearable :style="{width: '100%'}">
<!-- <el-option
v-for="(item, index) in dict.faultLevel"
:key="index"
:label="item.name"
:value="item.id"
/> -->
<el-option
v-for="item in faultLevelList"
:key="item.dataCode"
:label="item.dataName"
:value="item.dataCode"
/>
</el-select>
</el-form-item>
</el-col>
<!-- <el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.repair.equipmentPosition')" prop="equipmentPosition">
<el-input v-model="formData.equipmentPosition" :placeholder="$t('module.equipmentManager.repair.placeholderequipmentPosition')" clearable :style="{width: '100%'}" />
</el-form-item>
</el-col> -->
<el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.repair.equipmentPosition')" prop="equipmentPosition">
<el-select
v-model="formData.equipmentPosition"
:placeholder="$t('module.equipmentManager.repair.placeholderequipmentPosition')"
clearable
:style="{width: '100%'}"
>
<el-option
v-for="(item, index) in dict.workshop"
:key="index"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.repair.timeOfFailure')" prop="timeOfFailure">
<el-date-picker
v-model="formData.timeOfFailure"
format="yyyy-MM-dd"
value-format="yyyy-MM-ddTHH:mm:ss"
:style="{width: '100%'}"
:placeholder="$t('module.equipmentManager.repair.placeholdertimeOfFailure')"
clearable
/>
</el-form-item>
</el-col>
<el-col :span="24">
<el-row>
<el-col :span="15">
<el-form-item :label="$t('module.equipmentManager.repair.timerange')" prop="maintenanceStartTime">
<el-date-picker
v-model="dateRange"
type="datetimerange"
:style="{width: '100%'}"
:start-placeholder="$t('module.equipmentManager.repair.startDate')"
:end-placeholder="$t('module.equipmentManager.repair.endDate')"
clearable
@change="dateChange"
/>
</el-form-item>
</el-col>
<el-col :span="9">
<el-form-item :label="$t('module.equipmentManager.repair.repairMode')" prop="repairMode">
<el-select
v-model="formData.repairMode"
:placeholder="$t('module.equipmentManager.repair.placeholderrepairMode')"
clearable
:style="{width: '100%'}"
>
<el-option
v-for="(item, index) in dict.repairType"
:key="index"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
</el-col>
<el-col :span="24">
<el-form-item :label="$t('module.equipmentManager.repair.faultDetail')" prop="faultDetail">
<el-input
v-model="formData.faultDetail"
type="textarea"
:placeholder="$t('module.equipmentManager.repair.placeholderfaultDetail')"
:autosize="{minRows: 4, maxRows: 4}"
:maxlength="200"
:style="{width: '100%'}"
/>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item :label="$t('module.equipmentManager.repair.maintenanceDetail')" prop="maintenanceDetail">
<el-input
v-model="formData.maintenanceDetail"
type="textarea"
:placeholder="$t('module.equipmentManager.repair.placeholdermaintenanceDetail')"
:autosize="{minRows: 4, maxRows: 4}"
:maxlength="200"
:style="{width: '100%'}"
/>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item :label="$t('module.equipmentManager.repair.annex')" prop="annex">
<single-file :file-id="formData.annex" @done="uploadSuccess" />
</el-form-item>
</el-col>
<!-- <el-col :span="24">
<el-form-item :label="$t('module.equipmentManager.repair.repairTools')" prop="repairTools">
<el-input v-model="formData.repairTools" :placeholder="$t('module.equipmentManager.repair.placeholderrepairTools')" clearable :style="{width: '100%'}" />
</el-form-item>
</el-col> -->
<el-col :span="24">
<el-form-item :label="$t('module.equipmentManager.repair.remark')" prop="remark">
<el-input v-model="formData.remark" :placeholder="$t('module.equipmentManager.repair.placeholderremark')" clearable :style="{width: '100%'}" />
</el-form-item>
</el-col>
</el-form>
<div slot="footer">
<el-button type="primary" @click="submitForm">{{ 'btn.submit' | i18nFilter }}</el-button>
<el-button @click="resetForm">{{ 'btn.reset' | i18nFilter }}</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { uploadPath } from '@/api/basic'
import { addRepairInfo } from '@/api/equipment/repair'
import { getDictDevice, getDictRepairType, getDictWorker, getWorkshop } from '@/api/dict'
import SingleFile from '@/components/Upload/SingleFile'
import i18n from '@/lang'
export default {
components: {
SingleFile
},
inheritAttrs: false,
props: {
targetInfo: {
type: Object,
default: () => ({})
}
},
data() {
return {
formData: {
repairOrderNumber: undefined,
equipmentId: undefined,
equipmentName: undefined,
maintenanceWorker: undefined,
maintenanceStatus: undefined,
equipmentPosition: undefined,
workerContactInformation: undefined,
timeOfFailure: undefined,
faultLevel: undefined,
maintenanceStartTime: null,
maintenanceFinishTime: null,
repairMode: undefined,
faultDetail: undefined,
maintenanceDetail: undefined,
annex: '',
repairTools: undefined,
remark: undefined
},
dateRange: null,
rules: {
repairOrderNumber: [{
required: true,
message: i18n.t('module.equipmentManager.repair.placeholderrepairOrderNumber'),
trigger: 'blur'
}],
equipmentId: [{
required: true,
message: i18n.t('module.equipmentManager.repair.placeholderequipmentId'),
trigger: 'change'
}],
maintenanceWorker: [{
required: false,
message: i18n.t('module.equipmentManager.repair.placeholdermaintenanceWorker'),
trigger: 'blur'
}],
maintenanceStatus: [{
required: false,
message: i18n.t('module.equipmentManager.repair.placeholdermaintenanceStatus'),
trigger: 'blur'
}],
equipmentPosition: [{
required: false,
message: i18n.t('module.equipmentManager.repair.placeholderequipmentPosition'),
trigger: 'blur'
}],
workerContactInformation: [{
required: false,
message: i18n.t('module.equipmentManager.repair.placeholderworkerContactInformation'),
trigger: 'blur'
}, {
pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
message: i18n.t('module.equipmentManager.maintainplan.mobile'),
trigger: 'blur'
}],
timeOfFailure: [{
required: true,
message: i18n.t('module.equipmentManager.repair.placeholdertimeOfFailure'),
trigger: 'change'
}],
faultLevel: [{
required: false,
message: i18n.t('module.equipmentManager.repair.placeholderfaultLevel'),
trigger: 'change'
}],
repairMode: [{
required: false,
message: i18n.t('module.equipmentManager.repair.placeholderrepairMode'),
trigger: 'change'
}],
maintenanceStartTime: [{
required: true,
message: i18n.t('module.equipmentManager.repair.placeholderrepairMode'),
trigger: 'change'
}],
faultDetail: [{
required: false,
message: i18n.t('module.equipmentManager.repair.placeholderfaultDetail'),
trigger: 'blur'
}],
maintenanceDetail: [{
required: false,
message: i18n.t('module.equipmentManager.repair.placeholdermaintenanceDetail'),
trigger: 'blur'
}],
remark: [{
required: false,
message: i18n.t('module.equipmentManager.repair.placeholderremark'),
trigger: 'blur'
}]
},
annexAction: uploadPath,
annexfileList: [],
faultLevelList: JSON.parse(localStorage.getItem('dictObj'))['1382922999706947585'],
dict: {
device: [],
repairType: [],
worker: [],
faultLevel: [],
workshop: []
}
}
},
computed: {},
watch: {},
created() {},
mounted() {
this.getDict()
},
methods: {
onOpen() {},
onClose() {
this.$refs['elForm'].resetFields()
this.fileList = []
},
close() {
this.$emit('update:visible', false)
},
uploadSuccess(id) {
console.log(id)
this.formData.annex = id
},
dateChange(date) {
console.log(date)
this.formData.maintenanceStartTime = date[0]
this.formData.maintenanceFinishTime = date[1]
},
submitForm() {
console.log(this.formData)
this.$refs['elForm'].validate(async valid => {
if (!valid) return
if (this.formData.maintenanceWorker) {
this.formData.maintenanceWorker = this.formData.maintenanceWorker.join(',')
}
// TODO 提交表单
const result = await addRepairInfo(this.formData)
if (result.code === 0) {
this.$message({
type: 'success',
message: i18n.t('module.equipmentManager.bom.succeeded')
})
// this.$router.go(-1)
this.$emit('done')
this.close()
}
})
},
resetForm() {
this.$refs['elForm'].resetFields()
this.dateRange = null
this.formData.maintenanceStartTime = null
this.formData.maintenanceFinishTime = null
},
annexBeforeUpload(file) {
const isRightSize = file.size / 1024 / 1024 < 10
if (!isRightSize) {
this.$message.error(i18n.t('module.equipmentManager.sparepart.larger'))
}
return isRightSize
},
async getDict() {
const result = await getDictDevice({
current: 1,
size: 999
})
this.dict.device = result
const result2 = await getDictRepairType()
this.dict.repairType = result2
const result3 = await getDictWorker()
this.dict.worker = result3
// const result4 = await faultLevelList()
// this.dict.faultLevel = result4
// const result5 = await getCode()
// this.formData.repairOrderNumber = result5.data
const result5 = await getWorkshop({
current: 1,
size: 999
})
this.dict.workshop = result5
},
turnBack() {
this.$router.go(-1)
},
getEquipmentName(val) {
console.log(val)
this.formData.equipmentName = val.name
}
}
}
</script>
<style lang="scss">
.page-form-container {
padding: 20px;
.method-btn-area {
padding: 15px 30px;
margin: 10px 0 20px 0;
border: 1px solid #dfe6ec;
}
}
.form-container {
padding-top: 40px;
}
.el-upload__tip {
line-height: 1.2;
}
</style>

View File

@@ -0,0 +1,485 @@
<template>
<!-- <div class="form-container"> -->
<div>
<el-dialog v-bind="$attrs" :title="readonly ? $t('module.equipmentManager.repair.repairDetail') : $t('module.equipmentManager.repair.repairEdit')" class="dialog" width="60%" v-on="$listeners" @open="onOpen" @close="onClose">
<!-- <div class="method-btn-area">
<el-button type="primary" plain icon="el-icon-arrow-left" @click="turnBack">{{ 'btn.back' | i18nFilter }}</el-button>
</div> -->
<!-- <el-row :gutter="15" class="page-form-container"> -->
<!-- 返回键 -->
<!-- <div class="method-btn-area">
<el-button type="primary" plain icon="el-icon-arrow-left" @click="turnBack">{{ 'btn.back' | i18nFilter }}</el-button>
</div> -->
<el-form ref="elForm" :model="formData" :rules="rules" size="medium" label-width="110px">
<el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.repair.repairOrderNumber')" prop="repairOrderNumber">
<el-input
v-model="formData.repairOrderNumber"
:placeholder="$t('module.equipmentManager.repair.placeholderrepairOrderNumber')"
clearable
:style="{width: '100%'}"
:disabled="readonly"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.repair.equipmentId')" prop="equipmentId">
<el-select
v-model="formData.equipmentId"
:placeholder="$t('module.equipmentManager.repair.placeholderequipmentId')"
clearable
:style="{width: '100%'}"
:disabled="readonly"
>
<el-option
v-for="(item, index) in dict.device"
:key="index"
:label="item.name"
:value="item.id"
@click.native="getEquipmentName(item)"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.repair.maintenanceStatus')" prop="maintenanceStatus">
<el-select
v-model="formData.maintenanceStatus"
:placeholder="$t('module.equipmentManager.repair.placeholdermaintenanceStatus')"
clearable
:disabled="readonly"
:style="{width: '100%'}"
>
<el-option
:label="$t('module.equipmentManager.repair.undone')"
:value="0"
/>
<el-option
:label="$t('module.equipmentManager.repair.done')"
:value="1"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.repair.maintenanceWorker')" prop="maintenanceWorker">
<el-select
v-model="formData.maintenanceWorker"
:placeholder="$t('module.equipmentManager.repair.placeholdermaintenanceWorker')"
clearable
multiple
:disabled="readonly"
:style="{width: '100%'}"
>
<el-option
v-for="(item, index) in dict.worker"
:key="index"
:label="item.name"
:value="item.name"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.repair.workerContactInformation')" prop="workerContactInformation">
<el-input
v-model="formData.workerContactInformation"
:placeholder="$t('module.equipmentManager.repair.placeholderworkerContactInformation')"
clearable
:style="{width: '100%'}"
:disabled="readonly"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.repair.timeOfFailure')" prop="timeOfFailure">
<el-date-picker
v-model="formData.timeOfFailure"
format="yyyy-MM-dd"
:style="{width: '100%'}"
:placeholder="$t('module.equipmentManager.repair.placeholdertimeOfFailure')"
clearable
:disabled="readonly"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.repair.faultLevel')" prop="faultLevel">
<el-select v-model="formData.faultLevel" :placeholder="$t('module.equipmentManager.repair.placeholderfaultLevel')" clearable :style="{width: '100%'}" :disabled="readonly">
<!-- <el-option
v-for="(item, index) in dict.faultLevel"
:key="index"
:label="item.name"
:value="item.id"
/> -->
<el-option
v-for="item in faultLevelList"
:key="item.dataCode"
:label="item.dataName"
:value="item.dataCode"
/>
</el-select>
</el-form-item>
</el-col>
<!-- <el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.repair.equipmentPosition')" prop="equipmentPosition">
<el-input v-model="formData.equipmentPosition" :placeholder="$t('module.equipmentManager.repair.placeholderequipmentPosition')" clearable :style="{width: '100%'}" :disabled="readonly" />
</el-form-item>
</el-col> -->
<el-col :span="12">
<el-form-item :label="$t('module.equipmentManager.repair.equipmentPosition')" prop="equipmentPosition">
<el-select
v-model="formData.equipmentPosition"
:placeholder="$t('module.equipmentManager.repair.placeholderequipmentPosition')"
clearable
:disabled="readonly"
:style="{width: '100%'}"
>
<el-option
v-for="(item, index) in dict.workshop"
:key="index"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="24">
<el-row>
<el-col :span="15">
<el-form-item :label="$t('module.equipmentManager.repair.timerange')" prop="maintenanceStartTime">
<el-date-picker
v-model="dateRange"
type="datetimerange"
:style="{width: '100%'}"
:start-placeholder="$t('module.equipmentManager.repair.startDate')"
:end-placeholder="$t('module.equipmentManager.repair.endDate')"
clearable
:disabled="readonly"
@change="dateChange"
/>
</el-form-item>
</el-col>
<el-col :span="9">
<el-form-item :label="$t('module.equipmentManager.repair.repairMode')" prop="repairMode">
<el-select
v-model="formData.repairMode"
:placeholder="$t('module.equipmentManager.repair.placeholderrepairMode')"
clearable
:style="{width: '100%'}"
:disabled="readonly"
>
<el-option
v-for="(item, index) in dict.repairType"
:key="index"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
</el-col>
<el-col :span="24">
<el-form-item :label="$t('module.equipmentManager.repair.faultDetail')" prop="faultDetail">
<el-input
v-model="formData.faultDetail"
type="textarea"
:placeholder="$t('module.equipmentManager.repair.placeholderfaultDetail')"
:autosize="{minRows: 4, maxRows: 4}"
:style="{width: '100%'}"
:maxlength="200"
:disabled="readonly"
/>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item :label="$t('module.equipmentManager.repair.maintenanceDetail')" prop="maintenanceDetail">
<el-input
v-model="formData.maintenanceDetail"
type="textarea"
:placeholder="$t('module.equipmentManager.repair.placeholdermaintenanceDetail')"
:autosize="{minRows: 4, maxRows: 4}"
:style="{width: '100%'}"
:maxlength="200"
:disabled="readonly"
/>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item :label="$t('module.equipmentManager.repair.annex')" prop="annex">
<single-file :file-id="formData.annex" :disabled="readonly" @done="uploadSuccess" />
</el-form-item>
</el-col>
<!-- <el-col :span="24">
<el-form-item :label="$t('module.equipmentManager.repair.repairTools')" prop="repairTools">
<el-input v-model="formData.repairTools" :disabled="readonly" :placeholder="$t('module.equipmentManager.repair.placeholderrepairTools')" clearable :style="{width: '100%'}" />
</el-form-item>
</el-col> -->
<el-col :span="24">
<el-form-item :label="$t('module.equipmentManager.repair.remark')" prop="remark">
<el-input v-model="formData.remark" :placeholder="$t('module.equipmentManager.repair.placeholderremark')" clearable :style="{width: '100%'}" :disabled="readonly" />
</el-form-item>
</el-col>
</el-form>
<div slot="footer">
<el-button v-if="!readonly" type="primary" @click="submitForm">{{ 'btn.submit' | i18nFilter }}</el-button>
<el-button v-if="!readonly" @click="resetForm">{{ 'btn.reset' | i18nFilter }}</el-button>
<el-button v-if="readonly" @click="close">{{ 'btn.cancel' | i18nFilter }}</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { editRepairInfo, getRepairInfo } from '@/api/equipment/repair'
import { getDictDevice, getDictRepairType, getDictWorker, faultLevelList, getWorkshop } from '@/api/dict'
import SingleFile from '@/components/Upload/SingleFile'
import i18n from '@/lang'
export default {
components: {
SingleFile
},
props: {
targetInfo: {
type: Object,
default: () => ({})
},
readonly: {
type: Boolean,
default: () => false
}
},
data() {
return {
formData: {
repairOrderNumber: undefined,
equipmentId: undefined,
maintenanceWorker: undefined,
maintenanceStatus: null,
equipmentPosition: undefined,
workerContactInformation: undefined,
timeOfFailure: undefined,
faultLevel: undefined,
maintenanceStartTime: null,
maintenanceFinishTime: null,
repairMode: undefined,
faultDetail: undefined,
maintenanceDetail: undefined,
annex: '',
repairTools: undefined,
remark: undefined
},
dateRange: null,
rules: {
repairOrderNumber: [{
required: true,
message: i18n.t('module.equipmentManager.repair.placeholderrepairOrderNumber'),
trigger: 'blur'
}],
equipmentId: [{
required: true,
message: i18n.t('module.equipmentManager.repair.placeholderequipmentId'),
trigger: 'change'
}],
maintenanceWorker: [{
required: false,
message: i18n.t('module.equipmentManager.repair.placeholdermaintenanceWorker'),
trigger: 'blur'
}],
maintenanceStatus: [{
required: false,
message: i18n.t('module.equipmentManager.repair.placeholdermaintenanceStatus'),
trigger: 'blur'
}],
equipmentPosition: [{
required: false,
message: i18n.t('module.equipmentManager.repair.placeholderequipmentPosition'),
trigger: 'blur'
}],
workerContactInformation: [{
required: false,
message: i18n.t('module.equipmentManager.repair.placeholderworkerContactInformation'),
trigger: 'blur'
}, {
pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
message: i18n.t('module.equipmentManager.maintainplan.mobile'),
trigger: 'blur'
}],
timeOfFailure: [{
required: false,
message: i18n.t('module.equipmentManager.repair.placeholdertimeOfFailure'),
trigger: 'change'
}],
faultLevel: [{
required: false,
message: i18n.t('module.equipmentManager.repair.placeholderfaultLevel'),
trigger: 'change'
}],
repairMode: [{
required: false,
message: i18n.t('module.equipmentManager.repair.placeholderrepairMode'),
trigger: 'change'
}],
faultDetail: [{
required: false,
message: i18n.t('module.equipmentManager.repair.placeholderfaultDetail'),
trigger: 'blur'
}],
maintenanceDetail: [{
required: false,
message: i18n.t('module.equipmentManager.repair.placeholdermaintenanceDetail'),
trigger: 'blur'
}],
remark: [{
required: false,
message: i18n.t('module.equipmentManager.repair.placeholderremark'),
trigger: 'blur'
}]
},
faultLevelList: JSON.parse(localStorage.getItem('dictObj'))['1382922999706947585'],
dict: {
device: [],
repairType: [],
worker: [],
faultLevel: [],
workshop: []
}
}
},
computed: {
// readonly() {
// // return this.$route.query.type === 'readonly'
// return this.targetInfo.readonly === 'readonly'
// },
id() {
// return this.$route.query.id
return this.targetInfo.id
}
},
watch: {},
created() {},
mounted() {
// this.getDict()
// this.getInfo()
},
methods: {
onOpen() {
this.getDict()
this.getInfo()
},
onClose() {
this.$refs['elForm'].resetFields()
this.fileList = []
},
close() {
this.$emit('update:visible', false)
},
uploadSuccess(id) {
console.log(id)
this.formData.annex = id
},
dateChange(date) {
this.formData.maintenanceStartTime = date[0]
this.formData.maintenanceFinishTime = date[1]
},
submitForm() {
this.$refs['elForm'].validate(async valid => {
if (!valid) return
// TODO 提交表单
if (this.dateRange) {
this.formData.maintenanceStartTime = this.dateRange[0]
this.formData.maintenanceFinishTime = this.dateRange[1]
} else {
this.formData.maintenanceStartTime = ''
this.formData.maintenanceFinishTime = ''
}
if (this.formData.maintenanceWorker) {
this.formData.maintenanceWorker = this.formData.maintenanceWorker.join(',')
}
const result = await editRepairInfo(this.formData)
if (result.code === 0) {
this.$message({
type: 'success',
message: i18n.t('module.equipmentManager.bom.succeeded')
})
// this.$router.go(-1)
this.$emit('done')
this.close()
}
})
},
resetForm() {
this.$refs['elForm'].resetFields()
this.dateRange = null
this.formData.maintenanceStartTime = null
this.formData.maintenanceFinishTime = null
},
annexBeforeUpload(file) {
const isRightSize = file.size / 1024 / 1024 < 10
if (!isRightSize) {
this.$message.error(i18n.t('module.equipmentManager.sparepart.larger'))
}
return isRightSize
},
async getDict() {
const result = await getDictDevice({
current: 1,
size: 999
})
this.dict.device = result
const result2 = await getDictRepairType()
this.dict.repairType = result2
const result3 = await getDictWorker()
this.dict.worker = result3
const result4 = await faultLevelList()
this.dict.faultLevel = result4
const result5 = await getWorkshop({
current: 1,
size: 999
})
this.dict.workshop = result5
},
async getInfo() {
const result = await getRepairInfo({
id: this.id
})
if (result.code === 0) {
this.formData = result.data
this.formData.faultLevel = result.data.faultLevel ? result.data.faultLevel + '' : ''
if (this.formData.maintenanceStartTime && this.formData.maintenanceFinishTime) {
this.dateRange = [this.formData.maintenanceStartTime, this.formData.maintenanceFinishTime]
}
if (this.formData.maintenanceWorker) {
this.formData.maintenanceWorker = this.formData.maintenanceWorker.split(',')
}
}
console.log(this.formData)
},
turnBack() {
this.$router.go(-1)
},
getEquipmentName(val) {
console.log(val)
this.formData.equipmentName = val.name
}
}
}
</script>
<style lang="scss">
.page-form-container {
padding: 20px;
.method-btn-area {
padding: 15px 30px;
margin: 10px 0 20px 0;
border: 1px solid #dfe6ec;
}
}
.form-container {
padding-top: 40px;
}
.el-upload__tip {
line-height: 1.2;
}
</style>

View File

@@ -0,0 +1,45 @@
<!--
* @Author: gtz
* @Date: 2022-04-08 11:08:46
* @LastEditors: fzq
* @LastEditTime: 2022-09-02 11:12:27
* @Description: file content
* @FilePath: \mt-bus-fe\src\views\FactoryManage\components\Alarm-status.vue
-->
<template slot-scope="scope">
<el-tag v-if="injectData.maintenanceStatus == 0||injectData.maintenanceStatus == 1" size="mini" :type="injectData.maintenanceStatus == 0||injectData.maintenanceStatus == 1 ? statusTypeList[injectData.maintenanceStatus] : ''">
{{ injectData.maintenanceStatus == 0||injectData.maintenanceStatus == 1 ? statusList[injectData.maintenanceStatus] : '' }}
</el-tag>
</template>
<script>
import i18n from '@/lang'
export default {
props: {
injectData: {
type: Object,
default: () => ({})
}
},
data() {
return {
statusList: {
0: i18n.t('module.equipmentManager.repair.undone'),
1: i18n.t('module.equipmentManager.repair.done')
},
statusTypeList: {
0: 'danger',
1: 'success'
}
}
},
methods: {}
}
</script>
<style scoped>
</style>

View File

@@ -0,0 +1,386 @@
<!--
/*
* @Date: 2022-04-18
* @LastEditTime: 2022-09-02 10:33:18
* @LastEditors: fzq
* @FilePath: \basic-admin\src\views\EquipmentManager\RepairManager\index.vue
* @Description:
*/
-->
<template>
<div class="app-container">
<!-- <top-title /> -->
<head-form
:form-config="headFormConfig"
@headBtnClick="btnClick"
/>
<base-table
:top-btn-config="topBtnConfig"
:table-config="tableProps"
:table-data="list"
:is-loading="listLoading"
:page="listQuery.current"
:limit="listQuery.size"
:height="tableH"
@clickTopBtn="clickTopBtn"
>
<method-btn slot="handleBtn" :width="trueWidth" :method-list="tableBtn" :is-fixed="true" @clickBtn="handleClick" />
</base-table>
<pagination v-show="total > 0" :total="total" :page.sync="listQuery.current" :limit.sync="listQuery.size" @pagination="getList" />
<!-- 新增弹窗 -->
<!-- :order-id="{orderId: orderId}" -->
<add-form :visible.sync="showDialog" @done="getList" />
<!-- 编辑/详情弹窗 -->
<edit-form :readonly="readonly" :visible.sync="showEditDialog" :target-info="{id: curEditId}" @done="getList" />
</div>
</template>
<script>
import { tableHeight } from '@/utils/index'
// import dataDict from '@/filters/DataDict'
// import DictFilter from '@/components/BaseTable/subcomponents/DataDictFilter'
// import TopTitle from '@/components/TopTitle'
import HeadForm from '@/components/basicData/HeadForm'
// edit here
import { timeFormatter } from '@/filters'
const topBtnConfig = [
{
type: 'add',
btnName: 'btn.add'
}
]
const tableBtn = [{
type: 'edit',
btnName: 'btn.edit'
}, {
type: 'detail',
btnName: 'btn.detail'
}, {
type: 'delete',
btnName: 'btn.delete'
}]
const tableProps = [{
prop: 'createTime',
label: i18n.t('module.equipmentManager.repair.createTime'),
filter: timeFormatter,
width: '180px'
}, {
prop: 'repairOrderNumber',
label: i18n.t('module.equipmentManager.repair.repairOrderNumber')
}, {
prop: 'maintenanceStartTime',
label: i18n.t('module.equipmentManager.repair.maintenanceStartTime'),
filter: timeFormatter,
width: '180px'
}, {
prop: 'maintenanceFinishTime',
label: i18n.t('module.equipmentManager.repair.maintenanceFinishTime'),
filter: timeFormatter,
width: '180px'
}, {
prop: 'maintenanceStatus',
label: i18n.t('module.equipmentManager.repair.maintenanceStatus'),
// filter: dataDict('doneStatus')
subcomponent: Status
}, {
prop: 'maintenanceDuration',
label: i18n.t('module.equipmentManager.repair.maintenanceDuration')
}, {
prop: 'equipmentName',
label: i18n.t('module.equipmentManager.repair.equipmentName')
// filter: dataDict('enableState')
}, {
prop: 'maintenanceWorker',
label: i18n.t('module.equipmentManager.repair.maintenanceWorker')
// subcomponent: DictFilter,
// filter: getDictWorker
}, {
prop: 'workerContactInformation',
label: i18n.t('module.equipmentManager.repair.workerContactInformation')
// filter: dataDict('enableState')
}, {
prop: 'remark',
label: i18n.t('module.equipmentManager.repair.remark')
}]
import AddForm from './AddRepair'
import EditForm from './EditRepair'
import BaseTable from '@/components/BaseTable'
// edit here
import { objFilter } from '@/utils'
import { getRepairDictDevice } from '@/api/dict'
import { getRepairList, delRepairInfo } from '@/api/equipment/repair'
// import { getDictWorker } from '@/api/dict'
import Pagination from '@/components/Pagination'
import MethodBtn from '@/components/BaseTable/subcomponents/MethodBtn'
import i18n from '@/lang'
import Status from './components/Status.vue'
export default {
name: 'OrgManager',
components: { HeadForm, Pagination, BaseTable, MethodBtn, AddForm, EditForm },
props: {},
data() {
return {
topBtnConfig,
tableBtn,
tableProps,
tableH: tableHeight(280),
datepicker: [],
list: [],
total: 0,
trueWidth: 120,
listLoading: true,
showDialog: false,
curEditId: null,
showEditDialog: false,
readonly: false,
listQuery: {
current: 1,
size: 20,
equipmentName: '',
// equipmentId: '',
id: '',
startTime: null,
endTime: null,
maintenanceStatus: 1
},
defaultProps: {
children: 'children',
label: 'label'
},
headFormConfig: [
{
type: 'select',
label: this.$t('module.equipmentManager.repair.searchPlaceholder'),
param: 'equipmentName',
selectOptions: [],
defaultSelect: ''
},
// {
// type: 'input',
// label: this.$t('module.equipmentManager.repair.searchPlaceholder'),
// placeholder: this.$t('module.equipmentManager.repair.searchPlaceholder'),
// param: 'equipmentName'
// },
{
type: 'select',
label: i18n.t('module.basicData.staff.State'),
selectOptions: [
{ id: 1, name: i18n.t('module.equipmentManager.repair.done') },
{ id: 0, name: i18n.t('module.equipmentManager.repair.undone') }
],
param: 'maintenanceStatus'
},
{
type: 'datePicker',
label: '',
dateType: 'daterange',
rangeSeparator: '-',
startPlaceholder: this.$t('module.equipmentManager.repair.startDate'),
endPlaceholder: this.$t('module.equipmentManager.repair.endDate'),
param: 'searchTime',
format: 'yyyy-MM-dd hh:mm:ss',
valueFormat: 'yyyy-MM-dd hh:mm:ss'
},
{
type: 'button',
btnName: 'btn.search',
name: 'search',
color: 'primary'
// },
// {
// type: 'button',
// btnName: 'btn.add',
// name: 'add',
// color: 'primary'
// },
// {
// type: 'button',
// btnName: 'btn.export',
// name: 'export',
// color: 'success'
}
],
headFormValue: {}
}
},
created() {
this.getDict()
// this.listLoading = false
this.getList()
},
mounted() {
// 固定表头,表格的最大高度随页面的高度自动调整
window.addEventListener('resize', () => {
this.tableH = tableHeight(280)
})
},
methods: {
handleClick(raw) {
console.log(raw)
switch (raw.type) {
case 'delete':
this.$confirm(i18n.t('deleteMsgBox.content'), i18n.t('deleteMsgBox.hint'), {
confirmButtonText: i18n.t('btn.confirm'),
cancelButtonText: i18n.t('btn.cancel'),
type: 'warning'
}).then(async() => {
// 走接口
const result = await delRepairInfo({
id: raw.data.id
})
if (result.code === 0) {
this.$message({
type: 'success',
message: i18n.t('deleteMsgBox.doneMsg')
})
this.getList()
}
})
break
case 'edit':
// this.$router.push({
// name: 'EditRepair',
// query: {
// id: raw.data.id
// }
// })
this.showEditDialog = true
this.readonly = false
this.curEditId = raw.data.id
break
case 'detail':
// this.$router.push({
// name: 'EditRepair',
// query: {
// id: raw.data.id,
// type: 'readonly'
// }
// })
this.showEditDialog = true
this.readonly = true
this.curEditId = raw.data.id
break
}
},
async getList() {
this.listLoading = true
// edit here
// console.log(this.headFormValue)
this.listQuery.equipmentName = this.headFormValue.equipmentName
// this.listQuery.equipmentId = this.headFormValue.equipmentId
// this.listQuery.id = this.headFormValue.id
this.listQuery.startTime = this.headFormValue.searchTime ? this.headFormValue.searchTime[0] : null
this.listQuery.endTime = this.headFormValue.searchTime ? this.headFormValue.searchTime[1] : null
this.listQuery.maintenanceStatus = this.headFormValue.maintenanceStatus
const res = await getRepairList(objFilter(this.listQuery))
// console.log(this.listQuery)
if (res.code === 0) {
this.list = res.data.records ? res.data.records : []
console.log(res)
if (this.list.maintenanceWorker) {
this.list.maintenanceWorker = this.list.maintenanceWorker.split(',')
}
// 采用map方法也可以提取json变为数组格式
// this.headFormConfig[0].selectOptions = this.list.map(function(val) {
// return {
// name: val.equipmentName,
// id: val.id
// }
// })
// console.log(this.headFormConfig[0].selectOptions[0])
this.total = res.data.total
this.listLoading = false
}
},
async getDict() {
const result = await getRepairDictDevice({
current: 1,
size: 999
})
// console.log(this.headFormConfig[0].selectOptions)
// console.log(result)
this.headFormConfig[0].selectOptions = result
this.getList()
},
// querySearch(queryString, cb) {
// var dataList = this.dataList
// var results = queryString ? dataList.filter(this.createFilter(queryString)) : dataList
// // 调用 callback 返回建议列表的数据
// cb(results)
// },
// createFilter(queryString) {
// return (dataList) => {
// return (dataList.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0)
// }
// },
// loadAll() {
// var arr = []
// for (var i = 0; i < this.list.length; i++) {
// arr.push({ 'value': this.list[i].equipmentName })
// }
// console.log(arr)
// return arr
// },
// handleSelect(item) {
// console.log(item)
// },
toAddPage() {
this.$router.push({
name: 'AddRepair'
})
},
// exportExcel() {
// const params = {
// current: 1,
// size: 999,
// equipmentId: this.headFormValue.equipmentId,
// equipmentName: this.headFormValue.equipmentName,
// startTime: this.headFormValue.searchTime ? this.headFormValue.searchTime[0] : null,
// endTime: this.headFormValue.searchTime ? this.headFormValue.searchTime[1] : null
// }
// this.$nextTick(() => {
// exportFile(params).then(response => {
// let fileName = ''
// const contentDisposition = response.headers['content-disposition']
// if (contentDisposition) {
// fileName = contentDisposition.slice(contentDisposition.indexOf('filename=') + 9)
// }
// const blob = new Blob([response.data])
// const reader = new FileReader()
// reader.readAsDataURL(blob)
// reader.onload = (e) => {
// const a = document.createElement('a')
// a.download = fileName
// a.href = e.target.result
// document.body.appendChild(a)
// a.click()
// document.body.removeChild(a)
// }
// })
// })
// },
btnClick(val) {
this.headFormValue = val
// 如果点击的是搜索栏的其他按钮在这里继续写判断
if (this.headFormValue.btnName === 'search') {
this.getList()
} else if (this.headFormValue.btnName === 'add') {
// this.toAddPage()
this.showDialog = true// 弹窗新增
} else if (this.headFormValue.btnName === 'export') {
this.exportExcel()
}
},
clickTopBtn(val) {
if (val === 'add') {
// this.toAddPage()// 新增
this.showDialog = true// 弹窗新增
}
}
}
}
</script>
<style lang="scss" scoped>
</style>

View File

@@ -0,0 +1,132 @@
<!--
* @Date: 2021-01-11 09:24:41
* @LastEditors: Please set LastEditors
* @LastEditTime: 2021-05-11 10:54:22
* @FilePath: \basic-admin\src\views\EquipmentManager\StatusSetting\EditForm.vue
* @Description: 子页面
-->
<template>
<div>
<el-dialog v-bind="$attrs" title="修改设备状态" v-on="$listeners" @open="onOpen" @close="onClose">
<el-form ref="elForm" :model="formData" :rules="rules" size="medium" label-width="90px">
<el-form-item :label="$t('module.equipmentManager.statusSetting.devicestatus')" prop="status">
<el-select v-model="formData.status" :placeholder="$t('module.equipmentManager.statusSetting.placeholderdevicestatus')" clearable :style="{width: '600px'}">
<el-option
v-for="(item, index) in statusOptions"
:key="index"
:label="item.name"
:value="item.id"
/>
</el-select>
<div style="position: relative;">
<el-tooltip placement="top" style="position: absolute;top: -34px;right: -18px;">
<div slot="content"><img src="../../../assets/img/status.png" alt=""></div>
<el-button type="text" icon="el-icon-question" />
</el-tooltip>
</div>
</el-form-item>
<el-form-item :label="$t('module.equipmentManager.statusSetting.controlStatus')" prop="controlStatus">
<el-select v-model="formData.controlStatus" :placeholder="$t('module.equipmentManager.statusSetting.placeholdercontrolStatus')" clearable :style="{width: '630px'}">
<el-option
v-for="(item, index) in controlStatusOptions"
:key="index"
:label="item.name"
:value="item.value"
/>
</el-select>
</el-form-item>
</el-form>
<div slot="footer">
<el-button @click="close">{{ 'btn.cancel' | i18nFilter }}</el-button>
<el-button type="primary" @click="handelConfirm">{{ 'btn.confirm' | i18nFilter }}</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { editStatusSetting } from '@/api/equipment/index'
import { statusList } from '@/api/dict'
import i18n from '@/lang'
export default {
components: {},
inheritAttrs: false,
props: {
targetInfo: {
type: Object,
default: () => ({})
}
},
data() {
return {
formData: {
status: null,
oldStatus: null,
id: null,
controlStatus: null
},
rules: {
status: [{
required: true,
message: i18n.t('module.equipmentManager.statusSetting.placeholderdevicestatus'),
trigger: 'change'
}],
controlStatus: [{
required: true,
message: i18n.t('module.equipmentManager.statusSetting.placeholdercontrolStatus'),
trigger: 'change'
}]
},
statusOptions: [],
controlStatusOptions: [
{ name: this.$t('module.equipmentManager.statusSetting.controlStatusLocal'), value: 0 },
{ name: this.$t('module.equipmentManager.statusSetting.controlStatusOnline'), value: 1 }
]
}
},
computed: {},
watch: {},
created() {},
mounted() {
this.getDict()
},
methods: {
onOpen() {
this.formData.id = this.targetInfo.id
this.formData.status = String(this.targetInfo.status)
this.formData.oldStatus = String(this.targetInfo.status)
this.formData.controlStatus = this.targetInfo.controlStatus
},
onClose() {
this.$refs['elForm'].resetFields()
},
close() {
this.$emit('update:visible', false)
},
handelConfirm() {
this.$refs['elForm'].validate(async valid => {
if (!valid) return
const result = await editStatusSetting({
...this.formData,
// eslint-disable-next-line no-undef
id: this.targetInfo?.id
})
if (result.code === 0) {
this.$message({
type: 'success',
message: '修改状态成功!'
})
this.$emit('done')
this.close()
}
})
},
async getDict() {
const result = await statusList()
this.statusOptions = result
}
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,209 @@
<!--
/*
* @Date: 2022-04-18
* @LastEditTime: 2022-04-18
* @LastEditors: juzi
* @FilePath: \basic-admin\src\views\EquipmentManager\StatusSetting\index.vue
* @Description:
*/
-->
<template>
<div class="app-container">
<top-title />
<head-form
:form-config="headFormConfig"
@headBtnClick="btnClick"
/>
<base-table
:table-config="tableProps"
:table-data="list"
:is-loading="listLoading"
:page="listQuery.current"
:limit="listQuery.size"
>
<method-btn slot="handleBtn" :method-list="tableBtn" @clickBtn="handleClick" />
</base-table>
<pagination v-show="total > 0" :total="total" :page.sync="listQuery.current" :limit.sync="listQuery.size" @pagination="getList" />
<edit-form :visible.sync="showEditDialog" :target-info="{id: curEditId, status: curStatus}" @done="getList" />
</div>
</template>
<script>
// import dataDict from '@/filters/DataDict'
import ColorSqua from '@/components/BaseTable/subcomponents/ColorSqua'
import equipment from '@/filters/equipment'
import TopTitle from '@/components/TopTitle'
import HeadForm from '@/components/basicData/HeadForm'
// edit here
// const statusTableFilter = value => {
// const table = {
// '0': 'productive',
// '1': 'standby',
// '2': 'unscheduled downtime',
// '3': 'scheduled downtime',
// '4': 'engineering',
// '5': 'non-scheduled'
// }
// return table[value] ? table[value] : value
// }
// const colorTable = {
// '0': 'rgb(155,187,89)',
// '1': 'rgb(255,255,0)',
// '2': 'rgb(192,80,77)',
// '3': 'rgb(247,150,70)',
// '4': 'rgb(79,129,189)',
// '5': 'rgb(0,0,0)'
// }
const tableBtn = [{
type: 'edit',
btnName: 'btn.edit'
}]
const tableProps = [{
prop: 'code',
label: i18n.t('module.equipmentManager.statusSetting.code'),
align: 'center'
}, {
prop: 'name',
label: i18n.t('module.equipmentManager.statusSetting.name'),
align: 'center'
}, {
prop: 'controlStatus',
label: i18n.t('module.equipmentManager.statusSetting.controlStatus'),
align: 'center',
filter: equipment('controlStatus')
}, {
prop: 'communication',
label: i18n.t('module.equipmentManager.statusSetting.communication'),
align: 'center',
filter: equipment('communication')
}, {
prop: 'equipmentStatusName',
label: i18n.t('module.equipmentManager.statusSetting.status'),
align: 'center'
}, {
prop: 'equipmentStatusColor',
label: i18n.t('module.equipmentManager.statusSetting.color'),
align: 'center',
subcomponent: ColorSqua
// filter: dataDict('enableState')
}, {
prop: 'description',
label: i18n.t('module.equipmentManager.statusSetting.description'),
align: 'center'
}]
import EditForm from './EditForm'
import BaseTable from '@/components/BaseTable'
// edit here
import { getStatusSettingList } from '@/api/equipment'
import { statusList } from '@/api/dict'
import Pagination from '@/components/Pagination'
import MethodBtn from '@/components/BaseTable/subcomponents/MethodBtn'
import i18n from '@/lang'
export default {
name: 'OrgManager',
components: {
TopTitle,
HeadForm,
Pagination,
BaseTable,
MethodBtn,
EditForm
},
props: {},
data() {
return {
tableBtn,
tableProps,
list: [],
total: 0,
listLoading: true,
showDialog: false,
curEditId: null,
curStatus: null,
showEditDialog: false,
listQuery: {
current: 1,
size: 10,
equipmentName: ''
},
headFormConfig: [
{
type: 'input',
label: this.$t('module.equipmentManager.statusSetting.searchPlaceholder'),
placeholder: this.$t('module.equipmentManager.statusSetting.searchPlaceholder'),
param: 'equipmentName'
},
{
type: 'select',
label: this.$t('module.equipmentManager.statusSetting.searchPlaceholder2'),
selectOptions: [],
param: 'status'
},
{
type: 'button',
btnName: 'btn.search',
name: 'search',
color: 'primary'
}
],
headFormValue: {}
}
},
created() {
this.getList()
this.getDict()
// this.listLoading = false
},
mounted() {},
methods: {
handleClick(raw) {
console.log(raw)
switch (raw.type) {
case 'edit':
this.showEditDialog = true
this.curEditId = raw.data.id
this.curStatus = raw.data.status
break
}
},
async getList() {
this.listLoading = true
// edit here
this.listQuery.equipmentName = this.headFormValue.equipmentName
this.listQuery.status = this.headFormValue.status
if (this.listQuery.status === '') {
delete this.listQuery.status
}
const res = await getStatusSettingList(this.listQuery)
if (res.code === 0) {
this.list = res.data.records
// this.list = res.data.records ? res.data.records.map(item => {
// return {
// ...item,
// color: colorTable[item.status]
// }
// }) : []
this.total = res.data.total
this.listLoading = false
}
},
async getDict() {
const result = await statusList()
this.headFormConfig[1].selectOptions = result
},
btnClick(val) {
this.headFormValue = val
// 如果点击的是搜索栏的其他按钮在这里继续写判断
if (this.headFormValue.btnName === 'search') {
this.getList()
}
}
}
}
</script>
<style lang="scss" scoped>
</style>

View File

@@ -0,0 +1,55 @@
<!--
* @Date: 2021-02-20 10:45:21
* @LastEditors: guo
* @LastEditTime: 2021-03-16 14:36:29
* @FilePath: \basic-admin\src\views\EquipmentManager\TypeParamSetting\ColorSqua.vue
* @Description:
-->
<template>
<span class="color-squa" :style="{'color': color}" @click="emitClick">
{{ statusName }}
</span>
</template>
<script>
const colorTable = {
'0': 'rgb(155,187,89)',
'1': 'rgb(255,255,0)',
'2': 'rgb(192,80,77)',
'3': 'rgb(247,150,70)',
'4': 'rgb(79,129,189)',
'5': 'rgb(0,0,0)'
}
const statusTableFilter = value => {
const table = {
'0': 'productive',
'1': 'standby',
'2': 'unscheduled downtime',
'3': 'scheduled downtime',
'4': 'engineering',
'5': 'non-scheduled'
}
return table[value] ? table[value] : value
}
export default {
props: {
injectData: {
type: Object,
default: () => ({})
}
},
computed: {
color() {
return colorTable[this.injectData.status]
},
statusName() {
return statusTableFilter(this.injectData.status)
}
},
methods: {
emitClick() {
console.log(this.injectData)
}
}
}
</script>

View File

@@ -0,0 +1,86 @@
<!--
* @Date: 2020-12-15 15:36:52
* @LastEditors: gtz
* @LastEditTime: 2021-04-23 15:48:58
* @FilePath: \basic-admin\src\views\EquipmentManager\TypeParamSetting\detail.vue
* @Description: 设备类型参数列表
-->
<template>
<div class="usermanager-container">
<div class="info-box">
<span class="type">{{ $t('module.equipmentManager.baseinfo.name') }}: {{ info.name }}</span>
<span class="code">{{ $t('module.equipmentManager.baseinfo.code') }}: {{ info.code }}</span>
</div>
<el-tabs type="border-card">
<el-tab-pane :label="$t('module.equipmentManager.baseinfo.deviceTypeParam')">
<param-page />
</el-tab-pane>
<el-tab-pane :label="$t('module.equipmentManager.baseinfo.deviceTypeEvent')">
<event-page />
</el-tab-pane>
<el-tab-pane :label="$t('module.equipmentManager.baseinfo.deviceTypeAlarm')">
<alarm-page />
</el-tab-pane>
</el-tabs>
</div>
</template>
<script>
import { getDeviceInfo } from '@/api/equipment/param'
import ParamPage from './subpage/param'
import EventPage from './subpage/event'
import AlarmPage from './subpage/alarm'
export default {
name: 'OrgManager',
components: { ParamPage, EventPage, AlarmPage },
props: {},
data() {
return {
info: {}
}
},
computed: {
id() {
return this.$route.query.id
}
},
mounted() {
this.getInfo()
},
methods: {
async getInfo() {
const result = await getDeviceInfo({
id: this.id
})
if (result.code === 0) {
this.info = result.data
}
}
}
}
</script>
<style lang="scss" scoped>
.usermanager-container {
padding: 20px;
.info-box {
padding: 40px 5px;
.code {
margin-left: 40px;
}
}
.method-btn-area {
padding: 15px 30px;
margin: 10px 0 20px 0;
border: 1px solid #dfe6ec;
}
}
.edit-input {
padding-right: 100px;
}
.cancel-btn {
position: absolute;
right: 15px;
top: 10px;
}
</style>

View File

@@ -0,0 +1,127 @@
<!--
* @Date: 2020-12-15 15:36:52
* @LastEditors: Please set LastEditors
* @LastEditTime: 2021-06-29 19:25:49
* @FilePath: \basic-admin\src\views\EquipmentManager\TypeParamSetting\index.vue
* @Description: 设备类型参数列表
-->
<template>
<div class="app-container">
<top-title />
<head-form
:form-config="headFormConfig"
@headBtnClick="btnClick"
/>
<base-table :table-config="tableProps" :table-data="list" :is-loading="listLoading" :page="listQuery.current" :limit="listQuery.size">
<method-btn slot="handleBtn" :method-list="tableBtn" @clickBtn="handleClick" />
</base-table>
<pagination v-show="total > listQuery.size" :total="total" :page.sync="listQuery.current" :limit.sync="listQuery.size" @pagination="getList" />
</div>
</template>
<script>
// import dataDict from '@/filters/DataDict'
// edit here
const tableBtn = [{
type: 'detail',
btnName: 'btn.detail'
}]
const tableProps = [{
prop: 'code',
label: i18n.t('module.equipmentManager.baseinfo.code'),
align: 'center'
}, {
prop: 'name',
label: i18n.t('module.equipmentManager.baseinfo.name'),
align: 'center'
}, {
prop: 'remark',
label: i18n.t('module.equipmentManager.baseinfo.remark'),
align: 'center'
}]
import BaseTable from '@/components/BaseTable'
import TopTitle from '@/components/TopTitle'
import HeadForm from '@/components/basicData/HeadForm'
// edit here
import { getDeviceList } from '@/api/equipment/param'
import Pagination from '@/components/Pagination'
import MethodBtn from '@/components/BaseTable/subcomponents/MethodBtn'
import i18n from '@/lang'
export default {
name: 'OrgManager',
components: { TopTitle, HeadForm, Pagination, BaseTable, MethodBtn },
props: {},
data() {
return {
tableBtn,
tableProps,
list: [],
total: 0,
listLoading: true,
listQuery: {
current: 1,
size: 10,
name: '',
code: ''
},
headFormConfig: [
{
type: 'input',
label: i18n.t('module.basicData.visual.keyword'),
placeholder: this.$t('module.equipmentManager.baseinfo.searchPlaceholder'),
param: 'keywords'
},
{
type: 'button',
btnName: 'btn.search',
name: 'search',
color: 'primary'
}
],
headFormValue: {}
}
},
created() {
this.getList()
},
mounted() {},
methods: {
handleClick(raw) {
console.log(raw)
switch (raw.type) {
case 'detail':
this.$router.push({
name: 'TypeParamDetail',
query: {
id: raw.data.id
}
})
break
}
},
async getList() {
this.listLoading = true
// edit here
this.listQuery.name = this.headFormValue.keywords
this.listQuery.code = this.headFormValue.keywords
const res = await getDeviceList(this.listQuery)
if (res.code === 0) {
this.list = res.data.records ? res.data.records : []
this.total = res.data.total
this.listLoading = false
}
},
btnClick(val) {
this.headFormValue = val
// 如果点击的是搜索栏的其他按钮在这里继续写判断
if (this.headFormValue.btnName === 'search') {
this.getList()
}
}
}
}
</script>
<style lang="scss" scoped>
</style>

View File

@@ -0,0 +1,132 @@
<!--
* @Date: 2021-01-18 10:47:42
* @LastEditors: gtz
* @LastEditTime: 2021-04-23 15:57:43
* @FilePath: \basic-admin\src\views\EquipmentManager\TypeParamSetting\subpage\alarm\addForm.vue
* @Description:
-->
<template>
<div>
<el-dialog v-bind="$attrs" :title="$t('module.equipmentManager.baseinfoalarm.addDialogTitle')" v-on="$listeners" @open="onOpen" @close="onClose">
<el-form ref="elForm" :model="formData" :rules="rules" size="medium" label-width="150px">
<el-form-item :label="$t('module.equipmentManager.baseinfoalarm.alarmId')" prop="alarmId">
<el-input v-model="formData.alarmId" clearable :style="{width: '100%'}" type="number" />
</el-form-item>
<el-form-item :label="$t('module.equipmentManager.baseinfoalarm.alarmName')" prop="alarmName">
<el-input v-model="formData.alarmName" clearable :style="{width: '100%'}" />
</el-form-item>
<el-form-item :label="$t('module.equipmentManager.baseinfoalarm.alarmCode')" prop="alarmCode">
<el-input v-model="formData.alarmCode" clearable :style="{width: '100%'}" />
</el-form-item>
<el-form-item :label="$t('module.equipmentManager.baseinfoalarm.category')" prop="category">
<el-input v-model="formData.category" clearable :style="{width: '100%'}" />
</el-form-item>
<el-form-item :label="$t('module.equipmentManager.baseinfoalarm.enabled')" prop="enabled">
<el-switch v-model="formData.enabled" :active-value="1" :inactive-value="0" />
</el-form-item>
<!-- <el-form-item :label="$t('module.equipmentManager.baseinfoalarm.description')" prop="description">
<el-input v-model="formData.description" clearable :style="{width: '100%'}" />
</el-form-item> -->
<el-form-item :label="$t('module.equipmentManager.baseinfoalarm.remark')" prop="remark">
<el-input v-model="formData.remark" clearable :style="{width: '100%'}" />
</el-form-item>
</el-form>
<div slot="footer">
<el-button @click="close">取消</el-button>
<el-button type="primary" @click="handelConfirm">确定</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { addDeviceAlarmSetting, getDeviceAlarmCode } from '@/api/equipment/param'
import i18n from '@/lang'
export default {
components: {},
inheritAttrs: false,
props: {
targetInfo: {
type: Object,
default: () => ({})
}
},
data() {
return {
formData: {
alarmId: undefined,
alarmName: undefined,
alarmCode: undefined,
category: undefined,
enabled: 1,
description: undefined,
remark: undefined,
equipmentId: undefined
},
rules: {
alarmId: [{
required: true,
message: i18n.t('module.equipmentManager.baseinfoalarm.placeholderalarmId'),
trigger: 'blur'
}],
alarmName: [{
required: true,
message: i18n.t('module.equipmentManager.baseinfoalarm.placeholderalarmName'),
trigger: 'blur'
}],
alarmCode: [{
required: true,
message: i18n.t('module.equipmentManager.baseinfoalarm.placeholderalarmCode'),
trigger: 'blur'
}],
category: [{
required: true,
message: i18n.t('module.equipmentManager.baseinfoalarm.placeholdercategory'),
trigger: 'blur'
}],
description: [],
remark: []
}
}
},
computed: {},
watch: {},
created() {},
mounted() {},
methods: {
onOpen() {
this.formData.equipmentId = this.targetInfo?.id
this.getCode()
},
onClose() {
this.$refs['elForm'].resetFields()
},
close() {
this.$emit('update:visible', false)
},
handelConfirm() {
this.$refs['elForm'].validate(async valid => {
if (!valid) return
const result = await addDeviceAlarmSetting(this.formData)
if (result.code === 0) {
this.$message({
type: 'success',
message: '添加成功!'
})
this.$emit('done')
this.close()
}
})
},
async getCode() {
const result = await getDeviceAlarmCode()
if (result.code === 0) {
this.formData.alarmCode = result.data
}
}
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,134 @@
<!--
* @Date: 2021-01-18 10:47:42
* @LastEditors: gtz
* @LastEditTime: 2021-04-23 15:58:05
* @FilePath: \basic-admin\src\views\EquipmentManager\TypeParamSetting\subpage\alarm\editForm.vue
* @Description:
-->
<template>
<div>
<el-dialog v-bind="$attrs" :title="$t('module.equipmentManager.baseinfoalarm.editDialogTitle')" v-on="$listeners" @open="onOpen" @close="onClose">
<el-form ref="elForm" :model="formData" :rules="rules" size="medium" label-width="150px">
<el-form-item :label="$t('module.equipmentManager.baseinfoalarm.alarmId')" prop="alarmId">
<el-input v-model="formData.alarmId" clearable :style="{width: '100%'}" type="number" />
</el-form-item>
<el-form-item :label="$t('module.equipmentManager.baseinfoalarm.alarmName')" prop="alarmName">
<el-input v-model="formData.alarmName" clearable :style="{width: '100%'}" />
</el-form-item>
<el-form-item :label="$t('module.equipmentManager.baseinfoalarm.alarmCode')" prop="alarmCode">
<el-input v-model="formData.alarmCode" clearable :style="{width: '100%'}" />
</el-form-item>
<el-form-item :label="$t('module.equipmentManager.baseinfoalarm.category')" prop="category">
<el-input v-model="formData.category" clearable :style="{width: '100%'}" />
</el-form-item>
<el-form-item :label="$t('module.equipmentManager.baseinfoalarm.enabled')" prop="enabled">
<el-switch v-model="formData.enabled" :active-value="1" :inactive-value="0" />
</el-form-item>
<!-- <el-form-item :label="$t('module.equipmentManager.baseinfoalarm.description')" prop="description">
<el-input v-model="formData.description" clearable :style="{width: '100%'}" />
</el-form-item> -->
<el-form-item :label="$t('module.equipmentManager.baseinfoalarm.remark')" prop="remark">
<el-input v-model="formData.remark" clearable :style="{width: '100%'}" />
</el-form-item>
</el-form>
<div slot="footer">
<el-button @click="close">{{ 'btn.cancel' | i18nFilter }}</el-button>
<el-button type="primary" @click="handelConfirm">{{ 'btn.confirm' | i18nFilter }}</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { editDeviceAlarmSetting, getDeviceAlarmSetting } from '@/api/equipment/param'
import i18n from '@/lang'
export default {
components: {},
inheritAttrs: false,
props: {
targetInfo: {
type: Object,
default: () => ({})
}
},
data() {
return {
formData: {
alarmId: undefined,
alarmName: undefined,
alarmCode: undefined,
category: undefined,
enabled: 1,
description: undefined,
remark: undefined,
equipmentId: undefined
},
rules: {
alarmId: [{
required: true,
message: i18n.t('module.equipmentManager.baseinfoalarm.placeholderalarmId'),
trigger: 'blur'
}],
alarmName: [{
required: true,
message: i18n.t('module.equipmentManager.baseinfoalarm.placeholderalarmName'),
trigger: 'blur'
}],
alarmCode: [{
required: true,
message: i18n.t('module.equipmentManager.baseinfoalarm.placeholderalarmCode'),
trigger: 'blur'
}],
category: [{
required: true,
message: i18n.t('module.equipmentManager.baseinfoalarm.placeholdercategory'),
trigger: 'blur'
}],
description: [],
remark: []
}
}
},
computed: {},
watch: {},
created() {},
mounted() {},
methods: {
onOpen() {
this.formData.equipmentId = this.targetInfo.equipmentId
this.formData.id = this.targetInfo.id
this.getInfo()
},
onClose() {
this.$refs['elForm'].resetFields()
},
close() {
this.$emit('update:visible', false)
},
handelConfirm() {
this.$refs['elForm'].validate(async valid => {
if (!valid) return
const result = await editDeviceAlarmSetting(this.formData)
if (result.code === 0) {
this.$message({
type: 'success',
message: '添加成功!'
})
this.$emit('done')
this.close()
}
})
},
async getInfo() {
const result = await getDeviceAlarmSetting({
id: this.formData.id
})
if (result.code === 0) {
this.formData = result.data
}
}
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,153 @@
<!--
* @Date: 2020-12-15 15:36:52
* @LastEditors: Please set LastEditors
* @LastEditTime: 2021-06-29 20:29:18
* @FilePath: \basic-admin\src\views\EquipmentManager\TypeParamSetting\subpage\alarm\index.vue
* @Description: 设备类型参数列表
-->
<template>
<div class="param-subpage-container">
<div class="method-btn-area">
<el-input v-model="listQuery.keywords" :placeholder="$t('module.equipmentManager.baseinfoalarm.searchPlaceholder')" style="width: 200px;" clearable />
<el-button @click="getList">{{ 'btn.search' | i18nFilter }}</el-button>
<el-button type="primary" @click="showDialog = true">{{ 'btn.add' | i18nFilter }}</el-button>
</div>
<base-table :table-config="tableProps" :table-data="list" :is-loading="listLoading" :page="listQuery.current" :limit="listQuery.size">
<method-btn slot="handleBtn" :method-list="tableBtn" :is-fixed="false" :width="180" @clickBtn="handleClick" />
</base-table>
<pagination v-show="total > listQuery.size" :total="total" :page.sync="listQuery.current" :limit.sync="listQuery.size" @pagination="getList" />
<add-form :visible.sync="showDialog" :target-info="{id: listQuery.equipmentId}" @done="getList" />
<edit-form :visible.sync="showEditDialog" :target-info="{id: curEditId, equipmentId: listQuery.equipmentId }" @done="getList" />
</div>
</template>
<script>
// import dataDict from '@/filters/DataDict'
// edit here
const tableBtn = [{
type: 'edit',
btnName: 'btn.edit'
}, {
type: 'delete',
btnName: 'btn.delete'
}]
const tableProps = [{
prop: 'alarmId',
label: i18n.t('module.equipmentManager.baseinfoalarm.alarmId'),
align: 'center'
}, {
prop: 'alarmName',
label: i18n.t('module.equipmentManager.baseinfoalarm.alarmName'),
align: 'center'
}, {
prop: 'alarmCode',
label: i18n.t('module.equipmentManager.baseinfoalarm.alarmCode'),
align: 'center'
}, {
prop: 'category',
label: i18n.t('module.equipmentManager.baseinfoalarm.category'),
align: 'center'
}, {
prop: 'remark',
label: i18n.t('module.equipmentManager.baseinfoalarm.remark'),
align: 'center'
}]
import BaseTable from '@/components/BaseTable'
// edit here
import { getDeviceAlarmSettingList, delDeviceAlarmSetting } from '@/api/equipment/param'
import AddForm from './addForm'
import EditForm from './editForm'
import Pagination from '@/components/Pagination'
import MethodBtn from '@/components/BaseTable/subcomponents/MethodBtn'
import i18n from '@/lang'
export default {
name: 'OrgManager',
components: { Pagination, BaseTable, MethodBtn, AddForm, EditForm },
props: {},
data() {
return {
tableBtn,
tableProps,
list: [],
total: 0,
listLoading: true,
showDialog: false,
curEditId: null,
showEditDialog: false,
listQuery: {
current: 1,
size: 10,
equipmentId: null
}
}
},
created() {
this.listQuery.equipmentId = this.$route.query.id
this.getList()
// this.listLoading = false
},
mounted() {},
methods: {
handleClick(raw) {
console.log(raw)
switch (raw.type) {
case 'delete':
this.$confirm(i18n.t('deleteMsgBox.content'), i18n.t('deleteMsgBox.hint'), {
confirmButtonText: i18n.t('btn.confirm'),
cancelButtonText: i18n.t('btn.cancel'),
type: 'warning'
}).then(async() => {
// 走接口
const result = await delDeviceAlarmSetting({
id: raw.data.id
})
if (result.code === 0) {
this.$message({
type: 'success',
message: i18n.t('deleteMsgBox.doneMsg')
})
this.getList()
}
})
break
case 'edit':
this.showEditDialog = true
this.curEditId = raw.data.id
break
}
},
async getList(val) {
this.listLoading = true
// edit here
// console.log(this.listQuery
console.log(val)
console.log(this.listQuery.current)
const res = await getDeviceAlarmSettingList(this.listQuery)
if (res.code === 0) {
this.list = res.data.records ? res.data.records : []
this.total = res.data.total
this.listLoading = false
}
}
}
}
</script>
<style lang="scss" scoped>
.param-subpage-container {
padding: 40px;
.method-btn-area {
padding: 15px 30px;
margin: 10px 0 20px 0;
border: 1px solid #dfe6ec;
}
}
.edit-input {
padding-right: 100px;
}
.cancel-btn {
position: absolute;
right: 15px;
top: 10px;
}
</style>

View File

@@ -0,0 +1,131 @@
<!--
* @Date: 2021-01-18 10:47:42
* @LastEditors: gtz
* @LastEditTime: 2021-04-23 15:59:17
* @FilePath: \basic-admin\src\views\EquipmentManager\TypeParamSetting\subpage\event\addForm.vue
* @Description:
-->
<template>
<div>
<el-dialog v-bind="$attrs" :title="$t('module.equipmentManager.baseinfoevent.addDialogTitle')" v-on="$listeners" @open="onOpen" @close="onClose">
<el-form ref="elForm" :model="formData" :rules="rules" size="medium" label-width="150px">
<el-form-item :label="$t('module.equipmentManager.baseinfoevent.eventId')" prop="eventId">
<el-input v-model="formData.eventId" clearable :style="{width: '100%'}" type="number" />
</el-form-item>
<el-form-item :label="$t('module.equipmentManager.baseinfoevent.eventName')" prop="eventName">
<el-input v-model="formData.eventName" clearable :style="{width: '100%'}" />
</el-form-item>
<el-form-item :label="$t('module.equipmentManager.baseinfoevent.eventCode')" prop="eventCode">
<el-input v-model="formData.eventCode" clearable :style="{width: '100%'}" />
</el-form-item>
<!-- <el-form-item :label="$t('module.equipmentManager.baseinfoevent.category')" prop="category">
<el-input v-model="formData.category" clearable :style="{width: '100%'}" />
</el-form-item> -->
<el-form-item :label="$t('module.equipmentManager.baseinfoevent.enabled')" prop="enabled">
<el-switch v-model="formData.enabled" :active-value="1" :inactive-value="0" />
</el-form-item>
<el-form-item :label="$t('module.equipmentManager.baseinfoevent.description')" prop="description">
<el-input v-model="formData.description" clearable :style="{width: '100%'}" />
</el-form-item>
<el-form-item :label="$t('module.equipmentManager.baseinfoevent.remark')" prop="remark">
<el-input v-model="formData.remark" clearable :style="{width: '100%'}" />
</el-form-item>
</el-form>
<div slot="footer">
<el-button @click="close">{{ 'btn.cancel' | i18nFilter }}</el-button>
<el-button type="primary" @click="handelConfirm">{{ 'btn.confirm' | i18nFilter }}</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { addDeviceEventSetting, getDeviceEventCode } from '@/api/equipment/param'
import i18n from '@/lang'
export default {
components: {},
inheritAttrs: false,
props: {
targetInfo: {
type: Object,
default: () => ({})
}
},
data() {
return {
formData: {
eventId: undefined,
eventName: undefined,
eventCode: undefined,
category: undefined,
enabled: 1,
description: undefined,
remark: undefined,
equipmentId: undefined
},
rules: {
eventId: [{
required: true,
message: i18n.t('module.equipmentManager.baseinfoevent.placeholdereventId'),
trigger: 'blur'
}],
eventName: [{
required: true,
message: i18n.t('module.equipmentManager.baseinfoevent.placeholdereventName'),
trigger: 'blur'
}],
eventCode: [{
required: true,
message: i18n.t('module.equipmentManager.baseinfoevent.placeholdereventCode'),
trigger: 'blur'
}],
category: [{
required: false,
message: i18n.t('module.equipmentManager.baseinfoevent.placeholdercategory'),
trigger: 'blur'
}],
description: [],
remark: []
}
}
},
computed: {},
watch: {},
created() {},
mounted() {},
methods: {
onOpen() {
this.formData.equipmentId = this.targetInfo.id
this.getCode()
},
onClose() {
this.$refs['elForm'].resetFields()
},
close() {
this.$emit('update:visible', false)
},
handelConfirm() {
this.$refs['elForm'].validate(async valid => {
if (!valid) return
const result = await addDeviceEventSetting(this.formData)
if (result.code === 0) {
this.$message({
type: 'success',
message: '添加成功!'
})
this.$emit('done')
this.close()
}
})
},
async getCode() {
const result = await getDeviceEventCode()
if (result.code === 0) {
this.formData.eventCode = result.data
}
}
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,134 @@
<!--
* @Date: 2021-01-18 10:47:42
* @LastEditors: gtz
* @LastEditTime: 2021-04-23 15:59:53
* @FilePath: \basic-admin\src\views\EquipmentManager\TypeParamSetting\subpage\event\editForm.vue
* @Description:
-->
<template>
<div>
<el-dialog v-bind="$attrs" :title="$t('module.equipmentManager.baseinfoevent.editDialogTitle')" v-on="$listeners" @open="onOpen" @close="onClose">
<el-form ref="elForm" :model="formData" :rules="rules" size="medium" label-width="150px">
<el-form-item :label="$t('module.equipmentManager.baseinfoevent.eventId')" prop="eventId">
<el-input v-model="formData.eventId" clearable :style="{width: '100%'}" type="number" />
</el-form-item>
<el-form-item :label="$t('module.equipmentManager.baseinfoevent.eventName')" prop="eventName">
<el-input v-model="formData.eventName" clearable :style="{width: '100%'}" />
</el-form-item>
<el-form-item :label="$t('module.equipmentManager.baseinfoevent.eventCode')" prop="eventCode">
<el-input v-model="formData.eventCode" clearable :style="{width: '100%'}" />
</el-form-item>
<!-- <el-form-item :label="$t('module.equipmentManager.baseinfoevent.category')" prop="category">
<el-input v-model="formData.category" clearable :style="{width: '100%'}" />
</el-form-item> -->
<el-form-item :label="$t('module.equipmentManager.baseinfoevent.enabled')" prop="enabled">
<el-switch v-model="formData.enabled" :active-value="1" :inactive-value="0" />
</el-form-item>
<el-form-item :label="$t('module.equipmentManager.baseinfoevent.description')" prop="description">
<el-input v-model="formData.description" clearable :style="{width: '100%'}" />
</el-form-item>
<el-form-item :label="$t('module.equipmentManager.baseinfoevent.remark')" prop="remark">
<el-input v-model="formData.remark" clearable :style="{width: '100%'}" />
</el-form-item>
</el-form>
<div slot="footer">
<el-button @click="close">{{ 'btn.cancel' | i18nFilter }}</el-button>
<el-button type="primary" @click="handelConfirm">{{ 'btn.confirm' | i18nFilter }}</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { editDeviceEventSetting, getDeviceEventSetting } from '@/api/equipment/param'
import i18n from '@/lang'
export default {
components: {},
inheritAttrs: false,
props: {
targetInfo: {
type: Object,
default: () => ({})
}
},
data() {
return {
formData: {
eventId: undefined,
eventName: undefined,
eventCode: undefined,
category: undefined,
enabled: 1,
description: undefined,
remark: undefined,
equipmentId: undefined
},
rules: {
eventId: [{
required: true,
message: i18n.t('module.equipmentManager.baseinfoevent.placeholdereventId'),
trigger: 'blur'
}],
eventName: [{
required: true,
message: i18n.t('module.equipmentManager.baseinfoevent.placeholdereventName'),
trigger: 'blur'
}],
eventCode: [{
required: true,
message: i18n.t('module.equipmentManager.baseinfoevent.placeholdereventCode'),
trigger: 'blur'
}],
category: [{
required: false,
message: i18n.t('module.equipmentManager.baseinfoevent.placeholdercategory'),
trigger: 'blur'
}],
description: [],
remark: []
}
}
},
computed: {},
watch: {},
created() {},
mounted() {},
methods: {
onOpen() {
this.formData.equipmentId = this.targetInfo.equipmentId
this.formData.id = this.targetInfo.id
this.getInfo()
},
onClose() {
this.$refs['elForm'].resetFields()
},
close() {
this.$emit('update:visible', false)
},
handelConfirm() {
this.$refs['elForm'].validate(async valid => {
if (!valid) return
const result = await editDeviceEventSetting(this.formData)
if (result.code === 0) {
this.$message({
type: 'success',
message: '修改成功!'
})
this.$emit('done')
this.close()
}
})
},
async getInfo() {
const result = await getDeviceEventSetting({
id: this.formData.id
})
if (result.code === 0) {
this.formData = result.data
}
}
}
}
</script>
<style>
</style>

Some files were not shown because too many files have changed in this diff Show More