433 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
			
		
		
	
	
			433 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
| <!--
 | |
|  * @Author: zhp
 | |
|  * @Date: 2023-11-06 15:15:30
 | |
|  * @LastEditTime: 2024-06-17 17:03:17
 | |
|  * @LastEditors: DY
 | |
|  * @Description:
 | |
| -->
 | |
| <template>
 | |
|   <el-drawer class="drawer" :visible.sync="visible" size="85%" @closed="$emit('destroy')">
 | |
|     <small-title slot="title" :no-padding="true">
 | |
|       {{ '详情' }}
 | |
|       <el-button type="primary" plain size="small" style="float: right" @click="exportDetail">导出</el-button>
 | |
|     </small-title>
 | |
|     <div ref="detail" class="detailBox">
 | |
|       <el-row :gutter="20">
 | |
|         <el-col :span="3">
 | |
|           <p class="title">工单号</p>
 | |
|           <p class="text">{{ dataForm.workOrderNumber }}</p>
 | |
|         </el-col>
 | |
|         <el-col :span="3">
 | |
|           <p class="title">订单号</p>
 | |
|           <p class="text">{{ dataForm.orderNumber }}</p>
 | |
|         </el-col>
 | |
|         <el-col :span="3">
 | |
|           <p class="title">工单类型</p>
 | |
|           <p class="text">{{ ['', '芯片工单', '组件类型', 'bipv类型'][dataForm.workOrderType] }}</p>
 | |
|         </el-col>
 | |
|         <el-col :span="3">
 | |
|           <p class="title">工单来源</p>
 | |
|           <p class="text">{{ ['', '手动', 'ERP'][dataForm.source] }}</p>
 | |
|         </el-col>
 | |
|         <el-col :span="3">
 | |
|           <p class="title">工艺流程</p>
 | |
|           <p class="text">{{ dataForm.process }}</p>
 | |
|         </el-col>
 | |
|         <el-col :span="3">
 | |
|           <p class="title">BOM</p>
 | |
|           <p class="text">{{ dataForm.bom }}</p>
 | |
|         </el-col>
 | |
|         <el-col :span="3">
 | |
|           <p class="title">工单状态</p>
 | |
|           <p class="text">{{ ['', '未开始', '生产中', '已完成'][dataForm.orderStatus] }}</p>
 | |
|         </el-col>
 | |
|         <el-col :span="3">
 | |
|           <p class="title">投入状态</p>
 | |
|           <p class="text">{{ getDictDataLabel('work_order_in_status', dataForm.inStatus) }}</p>
 | |
|         </el-col>
 | |
|       </el-row>
 | |
|       <el-row :gutter="20">
 | |
|         <el-col :span="3">
 | |
|           <p class="title">计划投入量</p>
 | |
|           <p class="text">{{ dataForm.plannedInvestment }}</p>
 | |
|         </el-col>
 | |
|         <el-col :span="3">
 | |
|           <p class="title">目标产量</p>
 | |
|           <p class="text">{{ dataForm.targetProduction }}</p>
 | |
|         </el-col>
 | |
|         <el-col :span="3">
 | |
|           <p class="title">实际投入</p>
 | |
|           <p class="text">{{ dataForm.actualInvestment }}</p>
 | |
|         </el-col>
 | |
|         <el-col :span="3">
 | |
|           <p class="title">实际产出</p>
 | |
|           <p class="text">{{ dataForm.actualProduction }}</p>
 | |
|         </el-col>
 | |
|         <el-col :span="3">
 | |
|           <p class="title">创建时间</p>
 | |
|           <p class="text">{{ parseTime(dataForm.createTime) }}</p>
 | |
|         </el-col>
 | |
|         <el-col :span="3">
 | |
|           <p class="title">开始时间</p>
 | |
|           <p class="text">{{ dataForm.startDate?.length > 0 ? dataForm.startDate[0] + '-' + dataForm.startDate[1] + '-' + dataForm.startDate[2] : '' }}</p>
 | |
|         </el-col>
 | |
|         <el-col :span="3">
 | |
|           <p class="title">完成时间</p>
 | |
|           <p class="text">{{ dataForm.endDate?.length > 0 ? dataForm.endDate[0] + '-' + dataForm.endDate[1] + '-' + dataForm.endDate[2] : '' }}</p>
 | |
|         </el-col>
 | |
|       </el-row>
 | |
|       <el-divider></el-divider>
 | |
|       <div class="chartDiv">
 | |
|         <div ref="bar" :style="{ height: '30vh', width: '40vw' }" />
 | |
|         <div ref="pie" :style="{ height: '30vh', width: '40vw' }" />
 | |
|       </div>
 | |
|       <div class="chartDiv">
 | |
|         <div ref="equipmentLine" :style="{ height: '30vh', width: '40vw' }" />
 | |
|         <div ref="line" v-show="dataForm.orderStatus === 2" :style="{ height: '30vh', width: '40vw' }" />
 | |
|       </div>
 | |
|     </div>
 | |
|   </el-drawer>
 | |
| 
 | |
| </template>
 | |
| 
 | |
| <script>
 | |
| // import basicAdd from './basic-add';
 | |
| import * as echarts from 'echarts'
 | |
| import resize from '@/mixins/resize'
 | |
| import { getWorkOrderDetail } from '@/api/produceData/order';
 | |
| import SmallTitle from './SmallTitle';
 | |
| import jsPDF from 'jspdf';
 | |
| import html2canvas from 'html2canvas';
 | |
| import { getDictDataLabel } from "@/utils/dict";
 | |
| 
 | |
| export default {
 | |
|   components: {
 | |
|     SmallTitle,
 | |
|   },
 | |
|   mixins: [resize],
 | |
|   props: {
 | |
|     date: {
 | |
|       type: Number,
 | |
|       default: 0
 | |
|     }
 | |
|   },
 | |
|   data() {
 | |
|     return {
 | |
|       lineChart: null,
 | |
|       pieChart: null,
 | |
|       barChart: null,
 | |
|       equipmentLineChart: null,
 | |
|       visible: false,
 | |
|       dataForm: {}
 | |
|     }
 | |
|   },
 | |
|   beforeDestroy() {
 | |
|     if (!this.chart) {
 | |
|       return
 | |
|     }
 | |
|     this.chart.dispose()
 | |
|     this.chart = null
 | |
|   },
 | |
|   mounted() {
 | |
|     // this.getCurrentTime()
 | |
|   },
 | |
|   methods: {
 | |
|     exportDetail() {
 | |
|       // 导出
 | |
|       const pdf = new jsPDF('l', 'pt', 'a4');
 | |
| 
 | |
|       const canvas = document.createElement('canvas')
 | |
|       
 | |
|       const element = this.$refs['detail'];
 | |
|       const width = pdf.internal.pageSize.getWidth()
 | |
|       const height = pdf.internal.pageSize.getHeight()
 | |
|       
 | |
|       canvas.width = width * 2
 | |
|       canvas.height = height * 2
 | |
| 
 | |
|       canvas.style.width = width + 'px'
 | |
|       canvas.style.height = height + 'px'
 | |
|       
 | |
|       const options = {
 | |
|         // scale: 2,
 | |
|         dpi: 300,
 | |
|         canvas: canvas,
 | |
|         useCORS: true
 | |
|       };
 | |
| 
 | |
|       html2canvas(element, options).then((canvas) => {
 | |
|         const imgData = canvas.toDataURL('image/png', 1.0);
 | |
|         pdf.addImage(imgData, 'PNG', 0, 0, width, height);
 | |
|         pdf.save(this.dataForm.workOrderNumber + '详情.pdf');
 | |
|       });
 | |
|     },
 | |
|     init(id) {
 | |
|       this.visible = true
 | |
|       this.$nextTick(() => {
 | |
|         this.initLineChart()
 | |
|       })
 | |
|       if (id) {
 | |
|         getWorkOrderDetail(id).then(res => {
 | |
|           if (res.code === 0) {
 | |
|             this.dataForm = res.data.prodWorkOrderDO
 | |
|             this.buildChart(this.dataForm)
 | |
|             // 在制品
 | |
|             const xAxisList = Object.keys(res.data.inProcessDis)
 | |
|             const yAxisList = Object.values(res.data.inProcessDis)
 | |
|             this.initEqLineChart(xAxisList, yAxisList)
 | |
|             // 趋势图
 | |
|             const seriesList = []
 | |
|             const dateList = []
 | |
|             res.data.his.forEach(element => {
 | |
|               seriesList.push(element.actualProduction)
 | |
|               dateList.push(element.recordTime[0] + '-' + element.recordTime[1] + '-' + element.recordTime[2])
 | |
|             })
 | |
|             this.initLineChart(dateList, seriesList)
 | |
|           }
 | |
|           // if (this.dataForm.orderStatus === 1) {
 | |
|           //   this.trend()
 | |
|           // }
 | |
|         })
 | |
|         // getEqNum(id).then(response => {
 | |
|         //   if (response.code === 0) {
 | |
|         //     const xAxisList = Object.keys(response.data)
 | |
|         //     const yAxisList = Object.values(response.data)
 | |
|         //     this.initEqLineChart(xAxisList, yAxisList)
 | |
|         //   }
 | |
|         // })
 | |
|         
 | |
|       }
 | |
|     },
 | |
|     trend() {
 | |
|       // 趋势图
 | |
|       getDailyTrend({ factory: this.dataForm.id }).then(trendRes => {
 | |
|         if (trendRes?.data.length > 0) {
 | |
|           const seriesList = []
 | |
|           const dateList = []
 | |
|           trendRes.data.forEach(element => {
 | |
|             seriesList.push(element.actualProduction)
 | |
|             dateList.push(element.recordTime[0] + '-' + element.recordTime[1] + '-' + element.recordTime[2])
 | |
|           })
 | |
|           this.initLineChart(dateList, seriesList)
 | |
|         }
 | |
|       })
 | |
|     },
 | |
|     buildChart(data) {
 | |
|       // 生产明细
 | |
|       const barList = [data.targetProduction, data.plannedInvestment, data.actualInvestment, data.actualProduction, data.wasteNum, data.reworkNum]
 | |
|       this.initChart(barList)
 | |
|       // 良品率
 | |
|       const pieList = [
 | |
|         { value: data.actualProduction, name: '实际产出' },
 | |
|         { value: data.wasteNum, name: '废品数量' },
 | |
|         { value: data.reworkNum, name: '待再加工数量' }
 | |
|       ]
 | |
|       this.initPieChart(pieList)
 | |
|     },
 | |
|     initChart(barData) {
 | |
|       this.barChart = echarts.init(this.$refs['bar'])
 | |
|       this.barChart.setOption({
 | |
|         title: {
 | |
|           text: '生产明细',
 | |
|           left: 'center'
 | |
|           // subtext: 'Fake Data'
 | |
|         },
 | |
|         tooltip: {
 | |
|           trigger: 'axis'
 | |
|         },
 | |
|         grid: { top: 100, right: 90, bottom: 10, left: 10, containLabel: true },
 | |
|         calculable: true,
 | |
|         grid: {
 | |
|           top: '20%',
 | |
|           left: "1%",
 | |
|           right: "3%",
 | |
|           bottom: "1%",
 | |
|           containLabel: true
 | |
|         },
 | |
|         xAxis: {
 | |
|           type: 'category',
 | |
|           data: ['目标产量', '计划投入量', '实际投入', '实际产出', '废品数量', '待再加工数量'],
 | |
|           axisLabel: {
 | |
|             rotate:45
 | |
|           }
 | |
|         },
 | |
|         yAxis: {
 | |
|           type: 'value'
 | |
|         },
 | |
|         series: [
 | |
|           {
 | |
|             data: barData,
 | |
|             type: 'bar',
 | |
|             barWidth: '40%'
 | |
|           }
 | |
|         ]
 | |
|       }, true)
 | |
|     },
 | |
|     initPieChart(pieData) {
 | |
|       this.pieChart = echarts.init(this.$refs['pie'])
 | |
|       this.pieChart.setOption({
 | |
|         title: {
 | |
|           text: !isNaN((pieData[0].value / (pieData[0].value + pieData[1].value)).toFixed(4) * 100) ? ( '产品良率 ' + (pieData[0].value / (pieData[0].value + pieData[1].value)).toFixed(4) * 100 + '%') : '产品良率 -',
 | |
|           left: 'center'
 | |
|           // subtext: 'Fake Data'
 | |
|         },
 | |
|         tooltip: {
 | |
|           trigger: 'item'
 | |
|         },
 | |
|         legend: {
 | |
|           top: '5%',
 | |
|           left: 'right',
 | |
|           orient: 'vertical'
 | |
|         },
 | |
|         series: [
 | |
|           {
 | |
|             // name: 'Access From',
 | |
|             type: 'pie',
 | |
|             radius: ['40%', '70%'],
 | |
|             avoidLabelOverlap: false,
 | |
|             label: {
 | |
|               show: false,
 | |
|               position: 'center'
 | |
|             },
 | |
|             emphasis: {
 | |
|               label: {
 | |
|                 show: false,
 | |
|                 fontSize: 40,
 | |
|                 fontWeight: 'bold'
 | |
|               }
 | |
|             },
 | |
|             labelLine: {
 | |
|               show: false
 | |
|             },
 | |
|             data: pieData
 | |
|           }
 | |
|         ]
 | |
|       }, true)
 | |
|     },
 | |
|     initEqLineChart(xAxisList, yAxisList) {
 | |
|       this.equipmentLineChart = echarts.init(this.$refs['equipmentLine'])
 | |
|       this.equipmentLineChart.setOption({
 | |
|         title: {
 | |
|           text: '待制品分布',
 | |
|           left: 'center'
 | |
|           // subtext: 'Fake Data'
 | |
|         },
 | |
|         tooltip: {
 | |
|           trigger: 'axis'
 | |
|         },
 | |
|         grid: { top: 100, right: 90, bottom: 10, left: 10, containLabel: true },
 | |
|         calculable: true,
 | |
|         grid: {
 | |
|           top: '20%',
 | |
|           left: "1%",
 | |
|           right: "3%",
 | |
|           bottom: "1%",
 | |
|           containLabel: true
 | |
|         },
 | |
|         xAxis: {
 | |
|           type: 'category',
 | |
|           data: xAxisList,
 | |
|           axisLabel: {
 | |
|             rotate:45,
 | |
|             // width: '10%'
 | |
|           }
 | |
|         },
 | |
|         yAxis: {
 | |
|           type: 'value'
 | |
|         },
 | |
|         series: [
 | |
|           {
 | |
|             data: yAxisList,
 | |
|             type: 'bar',
 | |
|             barWidth: '50%'
 | |
|           }
 | |
|         ]
 | |
|       }, true)
 | |
|     },
 | |
|     initLineChart(xAxisList, seriesList) {
 | |
|       this.lineChart = echarts.init(this.$refs['line'])
 | |
|       this.lineChart.setOption({
 | |
|         title: {
 | |
|           text: '历史趋势',
 | |
|           left: 'center' // 设置标题居中
 | |
|         },
 | |
|         tooltip: {
 | |
|           trigger: 'item'
 | |
|         },
 | |
|         xAxis: {
 | |
|           type: 'category',
 | |
|           data: xAxisList,
 | |
|           axisLabel: {
 | |
|             rotate:45
 | |
|           }
 | |
|         },
 | |
|         yAxis: {
 | |
|           type: 'value'
 | |
|         },
 | |
|         series: [
 | |
|           {
 | |
|             data: seriesList,
 | |
|             type: 'line'
 | |
|           }
 | |
|         ]
 | |
|       }, true)
 | |
|     }
 | |
|     // getCurrentTime() {
 | |
|     //   // new Date().Format("yyyy-MM-dd HH:mm:ss")
 | |
|     //   this.dataForm.logTime = new Date()
 | |
|     //   // this.dataForm.logTime = year + "-" + month + "-" + day;
 | |
|     //   console.log(this.dataForm.logTime);
 | |
|     // },
 | |
|   },
 | |
| };
 | |
| </script>
 | |
| <style scoped>
 | |
| .chartDiv {
 | |
|   display: flex;
 | |
|   justify-content: space-between;
 | |
|   width: 100%;
 | |
|   padding: 5px;
 | |
|   padding-left: 30px;
 | |
| }
 | |
|   .drawer >>> .el-drawer {
 | |
|   border-radius: 8px 0 0 8px;
 | |
| }
 | |
| 
 | |
| .drawer >>> .el-form-item__label {
 | |
|   padding: 0;
 | |
| }
 | |
| 
 | |
| .drawer >>> .el-drawer__header {
 | |
|   margin: 0;
 | |
|   padding: 32px 32px 24px;
 | |
|   border-bottom: 1px solid #dcdfe6;
 | |
|   /* margin-bottom: 30px; */
 | |
| }
 | |
| .detailBox p {
 | |
|   margin: 0;
 | |
|   padding: 0 32px;
 | |
| }
 | |
| .detailBox .title {
 | |
|   /* width: 56px; */
 | |
|   /* height: 14px; */
 | |
|   font-family: Source Han Sans CN, Source Han Sans CN;
 | |
|   font-weight: 400;
 | |
|   font-size: 14px;
 | |
|   color: rgba(0, 0, 0, 0.85);
 | |
|   line-height: 16px;
 | |
|   text-align: left;
 | |
|   font-style: normal;
 | |
|   text-transform: none;
 | |
| }
 | |
| .detailBox .text {
 | |
|   font-size: 14px;
 | |
|   font-weight: 400;
 | |
|   color: rgba(102,102,102,0.75);
 | |
|   padding-bottom: 20px;
 | |
| }
 | |
| .detailBox {
 | |
|   padding-top: 30px;
 | |
|   width: 99%;
 | |
| }
 | |
| </style>
 |