|
@@ -0,0 +1,875 @@
|
|
|
+<template>
|
|
|
+ <div class="app-container">
|
|
|
+ <!--查询表单-->
|
|
|
+ <el-card class="operate-container" shadow="never">
|
|
|
+ <el-form :inline="true" class="demo-form-inline">
|
|
|
+ <el-form-item label="所属产线">
|
|
|
+ <el-select
|
|
|
+ v-model="zoneId"
|
|
|
+ clearable
|
|
|
+ placeholder="请选择"
|
|
|
+ style="width: 100%"
|
|
|
+ @change="getResourceList()"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="(item, index) in zoneList"
|
|
|
+ :key="index"
|
|
|
+ :label="item.name"
|
|
|
+ :value="item.value"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="任务类型">
|
|
|
+ <el-select
|
|
|
+ v-model="taskType"
|
|
|
+ clearable
|
|
|
+ placeholder="请选择"
|
|
|
+ style="width: 100%"
|
|
|
+ @change="getResourceList()"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="(item, index) in taskTypeList"
|
|
|
+ :key="index"
|
|
|
+ :label="item.name"
|
|
|
+ :value="item.key"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="选择设备">
|
|
|
+ <el-select
|
|
|
+ v-model="searchObj.resourceId"
|
|
|
+ clearable
|
|
|
+ placeholder="请选择"
|
|
|
+ style="width: 100%"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="(item, index) in resourceIds"
|
|
|
+ :key="index"
|
|
|
+ :label="item.name"
|
|
|
+ :value="item.id"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="生产时间">
|
|
|
+ <el-date-picker
|
|
|
+ v-model="searchObj.startDate"
|
|
|
+ placeholder="开始时间"
|
|
|
+ value-format="yyyy-MM-dd"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="-">
|
|
|
+ <el-date-picker
|
|
|
+ v-model="searchObj.endDate"
|
|
|
+ placeholder="结束时间"
|
|
|
+ value-format="yyyy-MM-dd"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="生产月份">
|
|
|
+ <el-date-picker
|
|
|
+ v-model="searchObj.month"
|
|
|
+ type="month"
|
|
|
+ placeholder="选择月"
|
|
|
+ value-format="yyyy-MM"
|
|
|
+ >
|
|
|
+ </el-date-picker>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="生产年份">
|
|
|
+ <el-date-picker
|
|
|
+ v-model="searchObj.years"
|
|
|
+ type="year"
|
|
|
+ placeholder="选择年"
|
|
|
+ value-format="yyyy"
|
|
|
+ >
|
|
|
+ </el-date-picker>
|
|
|
+ </el-form-item>
|
|
|
+ <el-button type="primary" icon="el-icon-search" @click="fetch()"
|
|
|
+ >查询</el-button
|
|
|
+ >
|
|
|
+ <el-button type="default" @click="resetData()">清空</el-button>
|
|
|
+
|
|
|
+ <el-button type="primary" icon="el-icon-download" @click="exportData()" v-show="false" >导出</el-button>
|
|
|
+ </el-form>
|
|
|
+ </el-card>
|
|
|
+ <!-- 列表数据 -->
|
|
|
+
|
|
|
+ <el-row :gutter="20">
|
|
|
+ <el-col :span="10">
|
|
|
+ <el-card class="box-card indicator-card" shadow="never">
|
|
|
+ <div slot="header" class="clearfix">
|
|
|
+ <span>设备综合效率</span>
|
|
|
+ </div>
|
|
|
+ <div class="item text">
|
|
|
+ <span class="formula">设备综合效率=时间开动率*性能开动率*合格品率</span>
|
|
|
+ </div>
|
|
|
+ <div class="item3 text">
|
|
|
+ <el-row :gutter="5">
|
|
|
+ <el-col :span="21">
|
|
|
+ <div>
|
|
|
+ <el-statistic title="设备综合效率">
|
|
|
+ <template slot="formatter">
|
|
|
+ <span class="like">
|
|
|
+ {{parseInt(this.avgActualTime * this.performanceRate /1260) || 0}}%
|
|
|
+ <i class="el-icon-s-flag" style="color: red"></i>
|
|
|
+ </span>
|
|
|
+ </template>
|
|
|
+ </el-statistic>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ </el-card>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="10">
|
|
|
+ <el-card class="box-card indicator-card" shadow="never">
|
|
|
+ <div slot="header" class="clearfix">
|
|
|
+ <span>设备完成率</span>
|
|
|
+ </div>
|
|
|
+ <div class="item text">
|
|
|
+ <span class="formula">设备完成率=完成任务数/待完成任务总数</span>
|
|
|
+ </div>
|
|
|
+ <div class="item3 text">
|
|
|
+ <el-row :gutter="5">
|
|
|
+ <el-col :span="7">
|
|
|
+ <div>
|
|
|
+ <el-statistic title="完成任务数">
|
|
|
+ <template slot="formatter">
|
|
|
+ <span class="like">
|
|
|
+ {{this.taskStatusData.finishNum || 0}}
|
|
|
+ <i class="el-icon-s-flag" style="color: red"></i>
|
|
|
+ </span>
|
|
|
+ </template>
|
|
|
+ </el-statistic>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="7">
|
|
|
+ <div>
|
|
|
+ <el-statistic title="待完成任务总数">
|
|
|
+ <template slot="formatter">
|
|
|
+ <span class="like">
|
|
|
+ {{parseInt(this.taskStatusData.unFinishNum + this.taskStatusData.finishNum) || 0}}
|
|
|
+ <i class="el-icon-s-flag" style="color: blue"></i>
|
|
|
+ </span>
|
|
|
+ </template>
|
|
|
+ </el-statistic>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="7">
|
|
|
+ <div>
|
|
|
+ <el-statistic title="设备完成率">
|
|
|
+ <template slot="formatter">
|
|
|
+ <span class="like" >
|
|
|
+ <a href="javascript:void(0)" @click="view('task')">{{this.taskStatusData.finishRate || 0}}%</a>
|
|
|
+ <i class="el-icon-star-on"
|
|
|
+ style="color:red"
|
|
|
+ ></i>
|
|
|
+ </span>
|
|
|
+ </template>
|
|
|
+ </el-statistic>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="item3 text">
|
|
|
+ <el-row :gutter="5">
|
|
|
+ <el-col :span="5">
|
|
|
+ <div>
|
|
|
+ <el-statistic title="AGV完成数">
|
|
|
+ <template slot="formatter">
|
|
|
+ <span class="like">
|
|
|
+ {{this.taskAGVData.finishNum || 0}}
|
|
|
+ <i class="el-icon-s-flag" style="color: red"></i>
|
|
|
+ </span>
|
|
|
+ </template>
|
|
|
+ </el-statistic>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="5">
|
|
|
+ <div>
|
|
|
+ <el-statistic title="AGV完成总数">
|
|
|
+ <template slot="formatter">
|
|
|
+ <span class="like">
|
|
|
+ {{parseInt(this.taskAGVData.totalNum) || 0}}
|
|
|
+ <i class="el-icon-s-flag" style="color: blue"></i>
|
|
|
+ </span>
|
|
|
+ </template>
|
|
|
+ </el-statistic>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="5">
|
|
|
+ <div>
|
|
|
+ <el-statistic title="AGV完成率">
|
|
|
+ <template slot="formatter">
|
|
|
+ <span class="like">
|
|
|
+ <a href="javascript:void(0)" @click="view('agv')">{{this.taskAGVData.finishRate || 0}}%</a>
|
|
|
+ </span>
|
|
|
+ </template>
|
|
|
+ </el-statistic>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="5">
|
|
|
+ <div>
|
|
|
+ <el-statistic title="平均运行时间">
|
|
|
+ <template slot="formatter">
|
|
|
+ <span class="like">
|
|
|
+ {{this.taskAGVData.avgRunTime || 0}}
|
|
|
+ </span>
|
|
|
+ </template>
|
|
|
+ </el-statistic>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </div>
|
|
|
+ </el-card>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+
|
|
|
+ <el-row :gutter="20">
|
|
|
+ <el-col :span="10">
|
|
|
+ <el-card class="box-card indicator-card" shadow="never">
|
|
|
+ <div slot="header" class="clearfix">
|
|
|
+ <span>时间开动率</span>
|
|
|
+ </div>
|
|
|
+ <div class="item text">
|
|
|
+ <div class="formula">时间开动率=开动时间/负荷时间</div>
|
|
|
+ <div class="formula">负荷时间=日历工作时间-故障停机时间</div>
|
|
|
+ <div class="formula">开动时间=负荷时间-故障停机时间-设备调整初始化时间</div>
|
|
|
+ </div>
|
|
|
+ <div class="item2 text">
|
|
|
+ <el-row :gutter="5">
|
|
|
+ <el-col :span="7">
|
|
|
+ <div>
|
|
|
+ <el-statistic title="日历工作时间">
|
|
|
+ <template slot="formatter">
|
|
|
+ 24小时/1440分钟
|
|
|
+ </template>
|
|
|
+ </el-statistic>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="7">
|
|
|
+ <div>
|
|
|
+ <el-statistic title="故障计划停机时间">
|
|
|
+ <template slot="formatter">
|
|
|
+ 3小时/180分钟
|
|
|
+ </template>
|
|
|
+ </el-statistic>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="7">
|
|
|
+ <div>
|
|
|
+ <el-statistic title="设备调整初始化时间">
|
|
|
+ <template slot="formatter">
|
|
|
+ 0.5小时/30分钟
|
|
|
+ </template>
|
|
|
+ </el-statistic>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </div>
|
|
|
+ <div class="item3 text">
|
|
|
+ <el-row :gutter="5">
|
|
|
+ <el-col :span="7">
|
|
|
+ <div>
|
|
|
+ <el-statistic title="开动时间(分钟)">
|
|
|
+ <template slot="formatter">
|
|
|
+ <span class="like">
|
|
|
+ {{this.avgActualTime || 0}}
|
|
|
+ <i class="el-icon-s-flag" style="color: red"></i>
|
|
|
+ </span>
|
|
|
+ </template>
|
|
|
+ </el-statistic>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="7">
|
|
|
+ <div>
|
|
|
+ <el-statistic title="负荷时间(分钟)">
|
|
|
+ <template slot="formatter">
|
|
|
+ <span class="like">
|
|
|
+ 1260
|
|
|
+ <i class="el-icon-s-flag" style="color: blue"></i>
|
|
|
+ </span>
|
|
|
+ </template>
|
|
|
+ </el-statistic>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="7">
|
|
|
+ <div>
|
|
|
+ <el-statistic title="时间开动率">
|
|
|
+ <template slot="formatter">
|
|
|
+ <span class="like">
|
|
|
+ {{parseInt(this.avgActualTime*100/1260) || 0}}%
|
|
|
+ <i class="el-icon-star-on"
|
|
|
+ style="color:red"
|
|
|
+ ></i>
|
|
|
+ </span>
|
|
|
+ </template>
|
|
|
+ </el-statistic>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </div>
|
|
|
+ </el-card>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="10">
|
|
|
+ <el-card class="box-card indicator-card" shadow="never">
|
|
|
+ <div slot="header" class="clearfix">
|
|
|
+ <span>故障超时时间</span>
|
|
|
+ </div>
|
|
|
+ <div class="item3 text">
|
|
|
+ <el-row :gutter="5">
|
|
|
+ <el-col :span="7">
|
|
|
+ <div>
|
|
|
+ <el-statistic title="超时数量">
|
|
|
+ <template slot="formatter">
|
|
|
+ <span class="like">
|
|
|
+ {{this.overTimeData.totalNum}}
|
|
|
+ </span>
|
|
|
+ </template>
|
|
|
+ </el-statistic>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="7">
|
|
|
+ <div>
|
|
|
+ <el-statistic title="故障超时(分钟)">
|
|
|
+ <template slot="formatter">
|
|
|
+ <span class="like">
|
|
|
+ {{this.overTimeData.overTimeVal || 0}}
|
|
|
+ </span>
|
|
|
+ </template>
|
|
|
+ </el-statistic>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="8">
|
|
|
+ <div>
|
|
|
+ <el-statistic title="故障平均超时(分钟)">
|
|
|
+ <template slot="formatter">
|
|
|
+ <span class="like">
|
|
|
+ {{this.overTimeData.avgOverTimeVal || 0}}
|
|
|
+ </span>
|
|
|
+ </template>
|
|
|
+ </el-statistic>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </div>
|
|
|
+ </el-card>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+
|
|
|
+ <el-row :gutter="5">
|
|
|
+ <el-col :span="10">
|
|
|
+ <el-card class="box-card indicator-card" shadow="never">
|
|
|
+ <div slot="header" class="clearfix">
|
|
|
+ <span>性能开动率</span>
|
|
|
+ </div>
|
|
|
+ <div class="item text">
|
|
|
+ <div class="formula">性能开动率=净开动率*速度开动率</div>
|
|
|
+ <div class="formula">净开动率=加工数量*实际加工周期/开动时间</div>
|
|
|
+ <div class="formula">速度开动率=理论加工周期/实际加工周期</div>
|
|
|
+ </div>
|
|
|
+ <div class="item2 text">
|
|
|
+ <el-row :gutter="5">
|
|
|
+ <el-col :span="7">
|
|
|
+ <div>
|
|
|
+ <el-statistic title="加工数量">
|
|
|
+ <template slot="formatter">
|
|
|
+ <span class="like">
|
|
|
+ {{tableData[0]? tableData[0].totalNum : 0}}
|
|
|
+ <i class="el-icon-s-flag" style="color: red"></i>
|
|
|
+ </span>
|
|
|
+ </template>
|
|
|
+ </el-statistic>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="8">
|
|
|
+ <div>
|
|
|
+ <el-statistic title="理论加工周期(分钟)">
|
|
|
+ <template slot="formatter">
|
|
|
+ <span class="like">
|
|
|
+ {{tableData[0]? parseInt(tableData[0].totalExpectTime) : 0}}
|
|
|
+ <i class="el-icon-s-flag" style="color: blue"></i>
|
|
|
+ </span>
|
|
|
+ </template>
|
|
|
+ </el-statistic>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="8">
|
|
|
+ <div>
|
|
|
+ <el-statistic title="实际加工周期(分钟)">
|
|
|
+ <template slot="formatter">
|
|
|
+ <span class="like">
|
|
|
+ {{tableData[0]? tableData[0].totalRealTime : 0}}
|
|
|
+ <i class="el-icon-star-on"
|
|
|
+ style="color:red"
|
|
|
+ ></i>
|
|
|
+ </span>
|
|
|
+ </template>
|
|
|
+ </el-statistic>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </div>
|
|
|
+ <div class="item3 text">
|
|
|
+ <el-row :gutter="5">
|
|
|
+ <el-col :span="21">
|
|
|
+ <div>
|
|
|
+ <el-statistic title="性能开动率">
|
|
|
+ <template slot="formatter">
|
|
|
+ <span class="like">
|
|
|
+ {{tableData[0] && tableData[0].totalRealTime!=0 ? parseInt(tableData[0].totalExpectTime * 100/tableData[0].totalRealTime) :0}}%
|
|
|
+ <i class="el-icon-star-on"
|
|
|
+ style="color:red"
|
|
|
+ ></i>
|
|
|
+ </span>
|
|
|
+ </template>
|
|
|
+ </el-statistic>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </div>
|
|
|
+ </el-card>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="10">
|
|
|
+ <el-card class="box-card indicator-card" shadow="never">
|
|
|
+ <div slot="header" class="clearfix">
|
|
|
+ <span>合格率</span>
|
|
|
+ </div>
|
|
|
+ <div class="item text">
|
|
|
+ <span class="formula">合格品率=合格品数量/加工数量</span>
|
|
|
+ </div>
|
|
|
+ </el-card>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+
|
|
|
+ <tenant-view
|
|
|
+ ref="view"
|
|
|
+ :dialog-visible="dialogVisible"
|
|
|
+ @close="viewClose"
|
|
|
+ />
|
|
|
+
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+// 【产品加工汇总】-API
|
|
|
+import productlineAvailabilityApi from "@/api/statisticalAnalysis/productlineAvailability";
|
|
|
+// 【弹出框】elementui组件
|
|
|
+import elDragDialog from "@/directive/el-drag-dialog";
|
|
|
+import Pagination from "@/components/Pagination";
|
|
|
+import TenantView from "./components/View"
|
|
|
+import areaMgrApi from "@/api/resourceProductMgr/areaMgr";
|
|
|
+export default {
|
|
|
+ name: "productStatistics",
|
|
|
+ directives: {
|
|
|
+ elDragDialog,
|
|
|
+ },
|
|
|
+ components: {TenantView},
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ tableData: [], // 讲师列表
|
|
|
+ formData: [],
|
|
|
+ total: 0, // 总记录数
|
|
|
+ page: 1, // 当前页码
|
|
|
+ limit: 10, // 每页记录数
|
|
|
+ page2: 1, // 当前页码
|
|
|
+ limit2: 10, // 每页记录数
|
|
|
+ total2: 0, // 总记录数
|
|
|
+ zoneId : "KT",
|
|
|
+ taskType: "1",
|
|
|
+ searchObj: {
|
|
|
+ month: "",
|
|
|
+ years: "",
|
|
|
+ resourceId: "",
|
|
|
+ }, // 查询条件
|
|
|
+ dialogVisible: false, //是否弹框
|
|
|
+ resourceIds:[],
|
|
|
+ zoneList: [{name:"框体类加工单元",value:"KT"},{name:"舱体类加工单元",value:"CT"},{name:"保障中心单元",value:"BZ"}],
|
|
|
+ taskTypeList: [{id:"1",name:"加工设备",key:"1"},{id:"2",name:"搬运设备",key:"2"}],
|
|
|
+ overTimeList:[],
|
|
|
+ overTimeData:{
|
|
|
+ totalNum:0,
|
|
|
+ overTimeVal: "",
|
|
|
+ avgOverTimeVal: "",
|
|
|
+ actuateTime: "",
|
|
|
+ actuateTimeRate: 0
|
|
|
+ },
|
|
|
+ avgActualTime:0,
|
|
|
+ taskStatusList:[],
|
|
|
+ taskStatusData:{
|
|
|
+ finishNum:0,
|
|
|
+ unFinishNum: 0,
|
|
|
+ finishRate: 0
|
|
|
+ },
|
|
|
+ taskAGVData:{
|
|
|
+ finishNum:0,
|
|
|
+ totalNum:0,
|
|
|
+ finishRate: 0,
|
|
|
+ avgRunTime: 0
|
|
|
+ },
|
|
|
+ performanceActualRate:0,
|
|
|
+ performanceRate:0,
|
|
|
+ row2: {},
|
|
|
+ totalNum: 0
|
|
|
+ };
|
|
|
+ },
|
|
|
+ computed: {},
|
|
|
+ // 实例已经在内存中创建好,此时data和methods已将ok,如果要操作data中的数据或是调用methods中的方法,最早只能在created中操作
|
|
|
+ created() {
|
|
|
+ // 加载列表数据
|
|
|
+ //this.getZoneList();
|
|
|
+ this.getResourceList();
|
|
|
+ this.fetch()
|
|
|
+ },
|
|
|
+ watch: {
|
|
|
+ loadingId: {
|
|
|
+ handler(val, oldVal) {
|
|
|
+ // 加载列表数据
|
|
|
+ this.fetch();
|
|
|
+ },
|
|
|
+ },
|
|
|
+ loadingDate: {
|
|
|
+ handler(val, oldVal) {
|
|
|
+ // 加载列表数据
|
|
|
+ this.fetch();
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ mounted() {},
|
|
|
+ methods: {
|
|
|
+ view(row) {
|
|
|
+ this.$refs.view.setOperatorDetailPerformance(row);
|
|
|
+ this.operatorViewVisible = true;
|
|
|
+ },
|
|
|
+ getResourceList(){
|
|
|
+ let params = {}
|
|
|
+
|
|
|
+ if(this.zoneId){
|
|
|
+ params.code = this.zoneId
|
|
|
+ }
|
|
|
+ if(this.taskType=="1"){
|
|
|
+ params.modeSpecification = "modeSpecification"
|
|
|
+ }else{
|
|
|
+ params.robot = "robot"
|
|
|
+ }
|
|
|
+ areaMgrApi.getByIndition(params).then(res => {
|
|
|
+ res = res.data;
|
|
|
+ console.log("产线下拉数据: ", res);
|
|
|
+ if(res.code == 0) {
|
|
|
+ this.resourceIds = res.data
|
|
|
+ if(this.resourceIds.length >= 1){
|
|
|
+ this.searchObj.resourceId = this.resourceIds[0].id
|
|
|
+ //this.fetch()
|
|
|
+ }else{
|
|
|
+ this.searchObj.resourceId = ""
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ fetch() {
|
|
|
+ let index = 0;
|
|
|
+ if(this.searchObj.startDate) index++;
|
|
|
+ if(this.searchObj.month) index++;
|
|
|
+ if(this.searchObj.years) index++;
|
|
|
+
|
|
|
+ if(index>1) {
|
|
|
+ this.$message({
|
|
|
+ message: "时间,月份,年份只能选择一个",
|
|
|
+ type: "warning"
|
|
|
+ })
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if(this.searchObj.resourceId=='' || this.searchObj.resourceId==null) return
|
|
|
+
|
|
|
+ this.tableKey = !this.tableKey;
|
|
|
+ let params = Object.keys(this.searchObj).filter((key) => this.searchObj[key] !== null && this.searchObj[key] !== "")
|
|
|
+ .reduce((acc, key) => ({ ...acc, [key]: this.searchObj[key] }), {});
|
|
|
+
|
|
|
+ if(this.taskType=="2"){
|
|
|
+ params.taskType = "2"
|
|
|
+ }
|
|
|
+ if(this.zoneId =='BZ'){
|
|
|
+ params.code = this.zoneId
|
|
|
+ }
|
|
|
+
|
|
|
+ productlineAvailabilityApi
|
|
|
+ .overTimeTaskSum(this.page, this.limit, params)
|
|
|
+ .then((response) => {
|
|
|
+ const res = response.data;
|
|
|
+ this.overTimeList = (res.data || []).records;
|
|
|
+ if(this.overTimeList){
|
|
|
+ this.overTimeData.totalNum = this.overTimeList[0]? this.overTimeList[0].totalNum : 0
|
|
|
+ this.overTimeData.overTimeVal = this.overTimeList[0]? this.overTimeList[0].totalRealTime - this.overTimeList[0].totalExpectTime : 0
|
|
|
+ this.overTimeData.avgOverTimeVal = this.overTimeList[0]? parseInt((this.overTimeList[0].totalRealTime - this.overTimeList[0].totalExpectTime)/(this.overTimeList[0].daySpan * this.overTimeList[0].totalNum )) : 0
|
|
|
+ this.overTimeData.actuateTime = this.overTimeList[0]? 1230 - parseInt(this.overTimeData.avgOverTimeVal) : 1230
|
|
|
+ this.overTimeData.actuateTimeRate = this.overTimeList[0]? parseInt(this.overTimeData.actuateTime* 100/1260) : 97
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ productlineAvailabilityApi.taskStatusSum(params).then((response) => {
|
|
|
+ const res = response.data;
|
|
|
+ this.taskStatusList = (res.data || {});
|
|
|
+ this.taskStatusData.finishNum = this.taskStatusList? parseInt(this.taskStatusList.finishNum) : 0
|
|
|
+ this.taskStatusData.unFinishNum = this.taskStatusList? parseInt(this.taskStatusList.unFinishNum) : 0
|
|
|
+ this.taskStatusData.finishRate = this.taskStatusList? parseInt(this.taskStatusData.finishNum * 100/(this.taskStatusData.finishNum+this.taskStatusData.unFinishNum)) : 0
|
|
|
+ })
|
|
|
+
|
|
|
+ productlineAvailabilityApi.taskAGVSum(params).then((response) => {
|
|
|
+ const res = response.data;
|
|
|
+ this.taskAGVData = (res.data || {});
|
|
|
+ this.taskAGVData.finishNum = this.taskAGVData? parseInt(this.taskAGVData.finishNum) : 0
|
|
|
+ this.taskAGVData.totalNum = this.taskAGVData? parseInt(this.taskAGVData.totalNum) : 0
|
|
|
+ this.taskAGVData.finishRate = this.taskAGVData? parseInt(this.taskAGVData.finishNum * 100/(this.taskAGVData.totalNum)) : 0
|
|
|
+ this.taskAGVData.avgRunTime = this.taskAGVData ? parseInt(this.taskAGVData.avgRunTime) : 0
|
|
|
+ })
|
|
|
+
|
|
|
+
|
|
|
+ let bool = this.taskType == "1"? true : false;
|
|
|
+ if(bool){
|
|
|
+ productlineAvailabilityApi
|
|
|
+ .deviceResourceSum(this.page, this.limit, params)
|
|
|
+ .then((response) => {
|
|
|
+ const res = response.data;
|
|
|
+ this.tableData = (res.data || []).records;
|
|
|
+ this.totalNum = 0
|
|
|
+ if(this.tableData){
|
|
|
+ this.tableData.forEach(item => {
|
|
|
+ this.totalNum += Number(item.totalNum)
|
|
|
+ })
|
|
|
+ }
|
|
|
+ //this.performanceActualRate = this.tableData[0] ? parseInt(this.tableData[0].totalExpectTime * this.tableData[0].totalNum/
|
|
|
+ let avgActualTime = this.tableData[0] ? parseInt(this.tableData[0].totalRealTime/this.tableData[0].daySpan) : 0
|
|
|
+ let errRealTime = this.tableData[0] ? parseInt((this.tableData[0].totalRealTime - this.tableData[0].totalExpectTime)/this.tableData[0].daySpan) : 0
|
|
|
+ this.avgActualTime = (avgActualTime - errRealTime < 1230)? avgActualTime - errRealTime : 1230
|
|
|
+ this.performanceRate = this.tableData[0] ? parseInt(this.tableData[0].totalExpectTime * 100/this.tableData[0].totalRealTime) : 0
|
|
|
+ this.total = (res.data || []).total;
|
|
|
+ });
|
|
|
+ }else{
|
|
|
+ productlineAvailabilityApi
|
|
|
+ .robotTaskSum(this.page, this.limit, params)
|
|
|
+ .then((response) => {
|
|
|
+ const res = response.data;
|
|
|
+ this.tableData = (res.data || []).records;
|
|
|
+ this.totalNum = 0
|
|
|
+ if(this.tableData){
|
|
|
+ this.tableData.forEach(item => {
|
|
|
+ this.totalNum += Number(item.totalNum)
|
|
|
+ })
|
|
|
+ }
|
|
|
+ let avgActualTime = this.tableData[0] ? parseInt(this.tableData[0].totalRealTime/this.tableData[0].daySpan) : 0
|
|
|
+ let errRealTime = this.tableData[0] ? parseInt((this.tableData[0].totalRealTime - this.tableData[0].totalExpectTime)/this.tableData[0].daySpan) : 0
|
|
|
+ this.avgActualTime = (avgActualTime - errRealTime < 1230)? avgActualTime - errRealTime : 1230
|
|
|
+ this.performanceRate = this.tableData[0] ? parseInt(this.tableData[0].totalExpectTime * 100/this.tableData[0].totalRealTime) : 0
|
|
|
+ this.total = (res.data || []).total;
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ },
|
|
|
+ //根据id查询
|
|
|
+ fetchDataById(row) {
|
|
|
+ //弹出框
|
|
|
+ this.row2 = row
|
|
|
+ this.dialogVisible = true;
|
|
|
+ const obj = {
|
|
|
+ resourceId: row.resourceId,
|
|
|
+ zoneId: row.zoneId,
|
|
|
+ startDate: this.searchObj.startDate,
|
|
|
+ endDate: this.searchObj.endDate,
|
|
|
+ month: this.searchObj.month,
|
|
|
+ years: this.searchObj.years
|
|
|
+ }
|
|
|
+ this.tableKey = !this.tableKey;
|
|
|
+ productlineAvailabilityApi
|
|
|
+ .deviceResourceDetail(this.page2,this.limit2,obj)
|
|
|
+ .then((response) => {
|
|
|
+ const res = response.data;
|
|
|
+ this.formData = (res.data || []).records;
|
|
|
+ this.total2 = (res.data || []).total;
|
|
|
+ });
|
|
|
+ },
|
|
|
+ // 每页记录数改变,size:回调参数,表示当前选中的“每页条数”
|
|
|
+ changePageSize(size) {
|
|
|
+ this.limit = size;
|
|
|
+ this.fetch();
|
|
|
+ },
|
|
|
+ // 改变页码,page:回调参数,表示当前选中的“页码”
|
|
|
+ changeCurrentPage(page) {
|
|
|
+ this.page = page;
|
|
|
+ this.fetch();
|
|
|
+ },
|
|
|
+ changePageSize2(size) {
|
|
|
+ this.limit2 = size;
|
|
|
+ console.log("执行")
|
|
|
+ this.fetchDataById(this.row2);
|
|
|
+ },
|
|
|
+ changeCurrentPage2(page) {
|
|
|
+ this.page2 = page;
|
|
|
+ console.log("执行")
|
|
|
+ this.fetchDataById(this.row2);
|
|
|
+ },
|
|
|
+ //清空
|
|
|
+ resetData() {
|
|
|
+ this.searchObj = {};
|
|
|
+ this.fetch();
|
|
|
+ },
|
|
|
+ viewClose() {
|
|
|
+ this.dialogVisible = false
|
|
|
+ },
|
|
|
+ view(type){
|
|
|
+ let value = type=='task'? this.taskStatusData.finishRate : this.taskAGVData.finishRate
|
|
|
+ if(value == null || value == 100) return false;
|
|
|
+ let params = Object.keys(this.searchObj).filter((key) => this.searchObj[key] !== null && this.searchObj[key] !== "")
|
|
|
+ .reduce((acc, key) => ({ ...acc, [key]: this.searchObj[key] }), {});
|
|
|
+ if(this.taskType=='2'){
|
|
|
+ params.taskType = '2'
|
|
|
+ }
|
|
|
+ //if(this.zoneId =='BZ'){
|
|
|
+ params.code = this.zoneId
|
|
|
+ //}
|
|
|
+ params.type = type
|
|
|
+ this.$refs.view.setTenant(params)
|
|
|
+ this.dialogVisible = true
|
|
|
+ },
|
|
|
+ cellClick(row, column) {
|
|
|
+ if (column["columnKey"] === "operation") {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ let flag = false;
|
|
|
+ this.selection.forEach((item) => {
|
|
|
+ if (item.id === row.id) {
|
|
|
+ flag = true;
|
|
|
+ this.$refs.table.toggleRowSelection(row);
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ if (!flag) {
|
|
|
+ this.$refs.table.toggleRowSelection(row, true);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ onSelectChange(selection) {
|
|
|
+ this.selection = selection;
|
|
|
+ },
|
|
|
+ getZoneList() {
|
|
|
+ areaMgrApi.getList({ status: 1 }).then((res) => {
|
|
|
+ res = res.data;
|
|
|
+ if (res.isSuccess) {
|
|
|
+ if(res.data){
|
|
|
+ this.zoneList = res.data.filter(item => item.name.indexOf('保障') ==-1)
|
|
|
+ this.zoneId = this.zoneList[1].id
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+ //导出
|
|
|
+ exportData() {
|
|
|
+ productlineAvailabilityApi.exportTaskResourceSum(this.searchObj).then((res) => {
|
|
|
+ if (!res) return;
|
|
|
+ const blob = new Blob([res.data], {
|
|
|
+ type: "application/vnd.ms-excel;",
|
|
|
+ });
|
|
|
+ const a = document.createElement("a");
|
|
|
+ // 生成文件路径
|
|
|
+ let href = window.URL.createObjectURL(blob);
|
|
|
+ a.href = href;
|
|
|
+ // 文件名中有中文 则对文件名进行转码
|
|
|
+ a.download = decodeURIComponent("任务资源汇总导出");
|
|
|
+ // 利用a标签做下载
|
|
|
+ document.body.appendChild(a);
|
|
|
+ a.click();
|
|
|
+ document.body.removeChild(a);
|
|
|
+ window.URL.revokeObjectURL(href);
|
|
|
+ this.allloading = false;
|
|
|
+ });
|
|
|
+ },
|
|
|
+ //
|
|
|
+ objectSpanMethod({ row, column, rowIndex, columnIndex }) {
|
|
|
+ if (columnIndex === 0 || columnIndex === 1 || columnIndex === 2) {
|
|
|
+ const _row = this.flitterData(this.formData).one[rowIndex];
|
|
|
+ const _col = _row > 0 ? 1 : 0;
|
|
|
+ return {
|
|
|
+ rowspan: _row,
|
|
|
+ colspan: _col,
|
|
|
+ };
|
|
|
+ }
|
|
|
+ },
|
|
|
+ /**合并表格的第一列,处理表格数据 */
|
|
|
+ flitterData(arr) {
|
|
|
+ let spanOneArr = [];
|
|
|
+ let concatOne = 0;
|
|
|
+ arr.forEach((item, index) => {
|
|
|
+ if (index === 0) {
|
|
|
+ spanOneArr.push(1);
|
|
|
+ } else {
|
|
|
+ //注意这里的quarterly是表格绑定的字段,根据自己的需求来改
|
|
|
+ if (item.quarterly === arr[index - 1].quarterly) {
|
|
|
+ //第一列需合并相同内容的判断条件
|
|
|
+ spanOneArr[concatOne] += 1;
|
|
|
+ spanOneArr.push(0);
|
|
|
+ } else {
|
|
|
+ spanOneArr.push(1);
|
|
|
+ concatOne = index;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ return {
|
|
|
+ one: spanOneArr,
|
|
|
+ };
|
|
|
+
|
|
|
+ }
|
|
|
+ },
|
|
|
+};
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+.indicator-card {
|
|
|
+ margin-top: 20px;
|
|
|
+ .item, .item2{
|
|
|
+ margin-bottom: 10px;
|
|
|
+ font-size: 14px;
|
|
|
+ color: #333;
|
|
|
+ font-weight: bold;
|
|
|
+
|
|
|
+ .formula{
|
|
|
+ font-size: 12px;
|
|
|
+ color: #999;
|
|
|
+ padding: 5px;
|
|
|
+ border-radius: 5px;
|
|
|
+ margin-left: 10px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .item3{
|
|
|
+ margin-top: 20px;
|
|
|
+ font-size: 18px;
|
|
|
+ color: #333;
|
|
|
+ font-weight: bold;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+>>> .item2 .el-statistic .con .number {
|
|
|
+
|
|
|
+ font-size: 14px;
|
|
|
+ font-weight: bold;
|
|
|
+ padding: 4px;
|
|
|
+}
|
|
|
+
|
|
|
+.like {
|
|
|
+ cursor: pointer;
|
|
|
+ font-size: 25px;
|
|
|
+ display: inline-block;
|
|
|
+ }
|
|
|
+ .like > a {
|
|
|
+ cursor: pointer;
|
|
|
+ text-decoration:underline;
|
|
|
+ color: #1900ffe2;
|
|
|
+ }
|
|
|
+
|
|
|
+.rowBtn {
|
|
|
+ margin: 0 5px;
|
|
|
+ color: #1890ff;
|
|
|
+}
|
|
|
+
|
|
|
+.rowBtn:hover {
|
|
|
+ opacity: 0.7;
|
|
|
+}
|
|
|
+</style>
|