<template>
|
<view>
|
<page-nav title="生产分析"></page-nav>
|
|
<view :style="{height:'1400rpx',overflow: 'scroll',background:'#0659FF'}">
|
<view class="body">
|
<view class="body_head">
|
<view class="body_head_title">生产看板</view>
|
<view>
|
<u-button type="" icon='calendar' iconColor="#0659FF" size="mini" @click="calendarShowTrue"
|
:text="calendarRange">
|
</u-button>
|
</view>
|
</view>
|
<view class="body_content" style="height: 330rpx;">
|
<view class="body_content_title">
|
<view>生产总览</view>
|
<uni-tooltip content="一段时间内的生产数据" style='margin-left: 10rpx;'>
|
<u-icon name="question-circle"></u-icon>
|
</uni-tooltip>
|
</view>
|
<view class="flex_between">
|
<view class="cont_item">
|
<view class="cont_item_title">计划数量</view>
|
<view class="cont_item_content">{{topData.plan_qty?topData.plan_qty:'0'}}</view>
|
</view>
|
<u-line direction="col" color="#ccc" style='margin-top: 35rpx;' length='60rpx'></u-line>
|
<view class="cont_item">
|
<view class="cont_item_title">完工数量</view>
|
<!-- <view class="cont_item_content">{{topData.end_qty?topData.end_qty:'0'}}</view> -->
|
<view class="cont_item_content">
|
{{topData.good_qty+topData.ng_qty+topData.laborbad_qty+topData.materielbad_qty ?topData.good_qty+topData.ng_qty+topData.laborbad_qty+topData.materielbad_qty:'0'}}
|
</view>
|
</view>
|
<u-line direction="col" color="#ccc" style='margin-top: 35rpx;' length='60rpx'></u-line>
|
<view class="cont_item">
|
<view class="cont_item_title">合格产出</view>
|
<view class="cont_item_content">{{topData.good_qty?topData.good_qty:'0'}}</view>
|
</view>
|
</view>
|
<view class="flex_between">
|
<view class="cont_item">
|
<view class="cont_item_title">缺陷产出</view>
|
<view class="cont_item_content">{{topData.ng_qty?topData.ng_qty:'0'}}</view>
|
</view>
|
<u-line direction="col" color="#ccc" style='margin-top: 35rpx;' length='60rpx'></u-line>
|
<view class="cont_item">
|
<view class="cont_item_title">工废产出</view>
|
<view class="cont_item_content">
|
{{topData.good_qty? topData.good_qty :'0'}}
|
</view>
|
</view>
|
<u-line direction="col" color="#ccc" style='margin-top: 35rpx;' length='60rpx'></u-line>
|
<view class="cont_item">
|
<view class="cont_item_title">料废产出</view>
|
<view class="cont_item_content">
|
{{topData.materielbad_qty ? topData.materielbad_qty :'0'}}
|
</view>
|
</view>
|
</view>
|
|
</view>
|
<view class="body_content">
|
<view class="body_content_title" style="margin-bottom: 0;">生产工单</view>
|
<view style="display: flex;justify-content: center;align-items: center;">
|
<!-- <view v-if="centerData.length===0" style="color: #c5c5c5;margin:120rpx auto;">暂无数据</view> -->
|
<echarts ref="pieEcharts" :option="pieOption" canvasId="pieEcharts"
|
style='width: 100%;height:360rpx;' />
|
</view>
|
|
</view>
|
<view class="body_content" style="height: 440rpx;">
|
<view class="body_content_title"
|
style="margin-bottom: 0;display: flex;justify-content: space-between;">
|
<view>不良统计Top5</view>
|
<view
|
style="background-color: #c5c5c5;padding: 5rpx;font-size: 12px;display: flex;border-radius: 6rpx;"
|
@click="operSheetShow=true">{{seleteValue}}
|
<u-icon :name="!operSheetShow?'arrow-down-fill':'arrow-up-fill'"></u-icon>
|
</view>
|
</view>
|
<view style="display: flex;justify-content: center;align-items: center;">
|
<!-- <view v-if="footerData.length===0" style="color: #c5c5c5;margin:120rpx auto;">暂无数据</view> -->
|
<echarts ref="barEcharts" :option="barOption" canvasId="barEcharts"
|
style='width: 100%;height:360rpx;' />
|
</view>
|
</view>
|
|
|
|
</view>
|
|
</view>
|
<uni-calendar ref="calendar" :range='true' :insert="false" @confirm="calendarConfirm" />
|
|
|
<u-picker :show="operSheetShow" :columns="columns" :itemHeight='55' :closeOnClickOverlay='true'
|
@close='operSheetShow=false' @confirm='operSheetShowConfirm' @cancel='operSheetShow=false'></u-picker>
|
|
</view>
|
</template>
|
|
|
<script>
|
import echarts from '../../components/echarts-uniapp/echarts-uniapp.vue'
|
import {
|
ProductionKanban
|
} from '../../config/api.js';
|
|
export default {
|
components: {
|
echarts
|
},
|
onLoad(option) {},
|
|
onPullDownRefresh() {
|
setTimeout(() => {
|
this.init(() => {
|
uni.stopPullDownRefresh();
|
})
|
}, 1000);
|
},
|
|
data() {
|
return {
|
topRightMessageCount: '',
|
|
calendarRange: new Date().getFullYear() + '-' + (new Date().getMonth() + 1).toString().padStart(
|
2, '0') + '-01' + '~' + new Date().toISOString().slice(0, 10),
|
|
operSheetShow: false, //切换不良统计Top5 底部滑出组件是否显示
|
|
columns: [ //按产品统计:prt 按工序统计:stp
|
['按产品统计', '按工序统计']
|
],
|
seleteValue: '按产品统计',
|
|
topData: {},
|
centerData: [],
|
footerData: [],
|
|
pieOption: {},
|
barOption: {},
|
|
|
}
|
},
|
created() {
|
|
},
|
mounted() {
|
this.init()
|
this.topRightMessageCount = uni.getStorageSync('topRightMessageCount')
|
|
this.getData()
|
|
|
},
|
methods: {
|
init() {
|
uni.stopPullDownRefresh()
|
},
|
// 获取安灯消息列表长度
|
getTopRightMessageCountIsChange(val) {
|
this.topRightMessageCount = val
|
},
|
async getData() {
|
const data = {
|
Ratetime: this.calendarRange,
|
defecttype: this.seleteValue === '按产品统计' ? 'prt' : 'stp',
|
}
|
const res = await ProductionKanban(data)
|
if (res.code === '200') {
|
|
this.topData = res.data.dt0[0]
|
this.centerData = res.data.dt1.map(({
|
wo_coum,
|
wo_status
|
}) => ({
|
name: wo_status + ' ' + wo_coum,
|
value: wo_coum
|
}))
|
this.footerData = res.data.dt2
|
|
this.getPieEcharts()
|
this.getTop5Echarts()
|
}
|
},
|
|
// 绘制生产工单图
|
getPieEcharts() {
|
|
let sum = 0
|
|
this.centerData.forEach(i => {
|
sum += i.value
|
})
|
|
|
this.pieOption = {
|
title: [{
|
text: '工单数',
|
subtext: sum + '个',
|
// textStyle: {
|
// fontSize: 20,
|
// color: "black"
|
// },
|
// subtextStyle: {
|
// fontSize: 20,
|
// color: 'black'
|
// },
|
textAlign: "center",
|
x: '33.5%',
|
y: '40%',
|
}],
|
legend: {
|
type: "scroll",
|
orient: 'vertical',
|
left: '70%',
|
align: 'left',
|
top: 'middle',
|
textStyle: {
|
color: '#8C8C8C'
|
},
|
height: 250
|
},
|
series: [{
|
name: '无数据',
|
type: 'pie',
|
center: ['35%', '50%'],
|
radius: ['40%', '65%'],
|
clockwise: false, //饼图的扇区是否是顺时针排布
|
avoidLabelOverlap: false,
|
label: {
|
normal: {
|
show: true,
|
position: 'outter',
|
formatter: function(parms) {
|
return parms.data.legendname
|
}
|
}
|
},
|
labelLine: {
|
normal: {
|
length: 5,
|
length2: 3,
|
smooth: true,
|
}
|
},
|
data: this.centerData
|
}]
|
};
|
},
|
//绘制不良统计Top5
|
getTop5Echarts() {
|
console.log(this.footerData);
|
const barData = this.footerData.map(i => i.defect_qty) //柱状图数据
|
const lineData = this.footerData.map(i => parseFloat((i.defect_qty * 100 / i.plan_qty).toFixed(
|
2))) //折线图图数据
|
const xData = this.seleteValue === '按产品统计' ? this.footerData.map(i => i.partname) : this.footerData.map(
|
i => i.stepname) //x轴数据
|
|
this.barOption = {
|
grid: {
|
left: '5%',
|
right: '5%',
|
bottom: '10%',
|
top: '12%',
|
containLabel: true
|
},
|
xAxis: [{
|
type: 'category',
|
data: xData,
|
axisPointer: {
|
type: 'shadow'
|
},
|
axisLabel: {
|
interval: 0,
|
// rotate: 40,
|
formatter: function(value) {
|
if (value.length > 4) {
|
return `${value.slice(0, 4)}...`;
|
}
|
return value;
|
},
|
}
|
}],
|
yAxis: [{
|
type: 'value',
|
// name: 'Precipitation',
|
min: 0,
|
max: Math.floor((Math.max(...barData) * 1.2)),
|
// interval: 4,
|
splitNumber: 4,
|
axisLabel: {
|
formatter: '{value}'
|
}
|
},
|
{
|
show: false,
|
type: 'value',
|
// name: 'Temperature',
|
min: 0,
|
max: Math.floor((Math.max(...lineData) * 1.2)),
|
// interval: 4,
|
splitNumber: 4,
|
axisLabel: {
|
formatter: '{value} %'
|
}
|
}
|
],
|
series: [{
|
name: 'Precipitation',
|
type: 'bar',
|
label: {
|
show: true
|
},
|
barWidth: 20,
|
itemStyle: {
|
color: '#356bff'
|
},
|
data: barData
|
},
|
{
|
name: 'Temperature',
|
type: 'line',
|
yAxisIndex: 1,
|
label: {
|
show: true,
|
|
},
|
itemStyle: {
|
color: '#0000ff',
|
"normal": {
|
"barBorderRadius": 0,
|
"label": {
|
"show": true,
|
"position": "top",
|
formatter: function(p) {
|
return p.value + '%';
|
}
|
}
|
}
|
},
|
data: lineData
|
}
|
]
|
};
|
},
|
operSheetShowConfirm(val) {
|
this.seleteValue = val.value[0]
|
this.operSheetShow = false
|
|
this.getData()
|
},
|
calendarConfirm(val) {
|
// this.calendarRange = val.range.before + '~' + val.range.after
|
if (val.range.before < val.range.after) {
|
this.calendarRange = val.range.before + '~' + val.range.after
|
} else {
|
this.calendarRange = val.range.after + '~' + val.range.before
|
}
|
|
if (val.range.before === '') {
|
this.calendarRange = new Date().toISOString().slice(0, 10) + '~' + val.range.after
|
}
|
if (val.range.after === '') {
|
this.calendarRange = val.range.before + '~' + new Date().toISOString().slice(0, 10)
|
}
|
if (val.range.before === '' && val.range.after === '') {
|
this.calendarRange = new Date().toISOString().slice(0, 10) + '~' + new Date().toISOString()
|
.slice(0,
|
10)
|
}
|
|
this.getData()
|
},
|
calendarShowTrue() {
|
this.$refs.calendar.open();
|
}
|
|
|
}
|
}
|
</script>
|
|
<style lang="scss" scoped>
|
@import url('@/style/global.css');
|
|
|
|
|
::v-deep .uicon-arrow-left>span {
|
display: block;
|
}
|
|
.body {
|
// min-height: 1382rpx;
|
background-color: #0659FF !important;
|
display: flex;
|
flex-direction: column;
|
padding: 20rpx 36rpx;
|
}
|
|
.body_head {
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
line-height: 40rpx;
|
height: 40rpx;
|
}
|
|
.body_head_title {
|
font-size: 36rpx;
|
// font-weight: 490;
|
color: #fff;
|
}
|
|
::v-deep .uni-select__input-placeholder {
|
color: #ccc;
|
}
|
|
::v-deep .uni-select__input-text {
|
color: #fff;
|
}
|
|
::v-deep .uniui-bottom {
|
color: #fff !important;
|
}
|
|
::v-deep .uniui-top {
|
color: #fff !important;
|
}
|
|
.body_content {
|
background-color: #fff;
|
// max-height: 390rpx;
|
margin: 12rpx 0;
|
border-radius: 10rpx;
|
display: flex;
|
flex-direction: column;
|
}
|
|
.body_content_title {
|
margin: 20rpx 30rpx 0;
|
font-size: 32rpx;
|
display: flex;
|
align-items: center;
|
font-weight: bolder;
|
}
|
|
::v-deep .uni-tooltip-popup {
|
width: 260rpx;
|
}
|
|
.cont_item {
|
width: 33%;
|
display: flex;
|
justify-content: center;
|
align-items: center;
|
height: 120rpx;
|
flex-direction: column;
|
line-height: 50rpx;
|
|
.cont_item_title {
|
color: #ccc;
|
font-size: 28rpx
|
}
|
|
.cont_item_content {
|
font-weight: bolder;
|
}
|
}
|
|
::v-deep .uicon-calendar {
|
font-size: 32rpx !important;
|
}
|
</style>
|