|
@@ -4,9 +4,9 @@
|
|
|
<div class="site-row">
|
|
|
<div class="site-progress" :style="`width: ${currentProgress}%`"></div>
|
|
|
<div class="site-label">
|
|
|
- <div class="site-node" v-for="(item,index) in checkList" :key="item.modelId">
|
|
|
- <div :class="['site',index<=cIndex && cIndex!=null?'normal':'un-info ']" />
|
|
|
- <div :class="['site-name',{'active-site-name':index<=cIndex && cIndex!=null}]">{{item.modelName}}</div>
|
|
|
+ <div class="site-node" v-for="(item,index) in checkList" :key="item.ccId">
|
|
|
+ <div :class="['site',index<=cIndex && cIndex!=null?'normal':'un-info ']"/>
|
|
|
+ <div :class="['site-name',{'active-site-name':index<=cIndex && cIndex!=null}]">{{ item.className }}</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
@@ -14,65 +14,58 @@
|
|
|
|
|
|
<div class="site-content mt10">
|
|
|
<div class="check-status">
|
|
|
- <el-button type="primary" :loading="cLoading" @click="handleNowCheck(checkList.length)" style="padding:16px 22px;">
|
|
|
+ <el-button type="primary" :loading="cLoading" @click="onNowCheck"
|
|
|
+ style="padding:16px 22px;">
|
|
|
立即巡检
|
|
|
</el-button>
|
|
|
- <span class="check-progress">
|
|
|
- <span class="t-span">巡检进度:</span>
|
|
|
- <el-progress type="circle" :percentage="currentProgress" width="50" stroke-width="4" :color="colors">
|
|
|
- <template #default="{ percentage }">
|
|
|
- <span class="percentage-value">{{ percentage }}%</span>
|
|
|
- </template>
|
|
|
- </el-progress>
|
|
|
+ <span class="check-progress" v-if="cLoading">
|
|
|
+ <span class="t-span">巡检进度:</span>
|
|
|
+ <el-progress type="circle" :percentage="currentProgress" width="50" stroke-width="4" :color="colors">
|
|
|
+ <template #default="{ percentage }">
|
|
|
+ <span class="percentage-value">{{ percentage }}%</span>
|
|
|
+ </template>
|
|
|
+ </el-progress>
|
|
|
+ </span>
|
|
|
+ <span class="check-progress" v-else>
|
|
|
+ <span class="t-span" style="font-size: 14px;font-weight: 400" v-show="nowCheck.checkResult">
|
|
|
+ {{ nowCheck.checkResult }}
|
|
|
+ </span>
|
|
|
</span>
|
|
|
<span>
|
|
|
<span v-show="checkTime" class="check-time">
|
|
|
+ <span v-if="checkFlag" style="margin-right: 10px">
|
|
|
+ <el-button size="small" @click="handleDialog('setting')" icon="Setting">巡检记录配置</el-button>
|
|
|
+ <el-button size="small" @click="handleDialog('report')" icon="Document">
|
|
|
+ 巡查报告查看
|
|
|
+ </el-button>
|
|
|
+ </span>
|
|
|
<span class="t-span">巡检时间:</span>
|
|
|
- <span class="check-time">{{parseTime(checkTime, '{y}-{m}-{d} {h}:{mi}:{s}')}}</span>
|
|
|
+ <span class="check-time">{{ parseTime(checkTime, '{y}-{m}-{d} {h}:{mi}:{s}') }}</span>
|
|
|
</span>
|
|
|
</span>
|
|
|
</div>
|
|
|
- <div class="progress-bar">
|
|
|
- <div class="progress-bar-inner" :style="`width: ${currentProgress}%`"/>
|
|
|
- </div>
|
|
|
|
|
|
- <div class="check-info">
|
|
|
- <div class="sub-col">
|
|
|
- <el-icon :size="46" color="#409EFF"><Timer /></el-icon>
|
|
|
- <div class="s-c-text">
|
|
|
- {{cIndex!=null?cIndex+1:0}}/{{checkList.length}}<br/>已检测模型</div>
|
|
|
- </div>
|
|
|
- <div class="sub-col">
|
|
|
- <el-icon :size="46" color="#409EFF"><Compass /></el-icon>
|
|
|
- <div class="s-c-text">{{cIndex!=null?Math.ceil((totalErrorCount/checkList.length)*(cIndex+1)):0}}/{{totalErrorCount}}<br/>已检测指标</div>
|
|
|
- </div>
|
|
|
- <div class="sub-col">
|
|
|
- <el-icon :size="46" color="#409EFF"><Warning /></el-icon>
|
|
|
- <div class="s-c-text">
|
|
|
- <span class="s-c-num">{{totalError}}</span>
|
|
|
- <br/>已发现问题</div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <el-table :data="listData" style="width: 100%" border class="mt20">
|
|
|
- <el-table-column prop="class" label="分类" width="180" />
|
|
|
- <el-table-column prop="option" label="巡检项" />
|
|
|
- <el-table-column label="巡检进度" align="center" width="180">
|
|
|
+ <el-table :data="listData" style="width: 100%" border class="mt20" :span-method="spanMethod">
|
|
|
+ <el-table-column prop="className" label="分类" width="180" align="center"/>
|
|
|
+ <el-table-column prop="checkName" label="巡检项"/>
|
|
|
+ <el-table-column label="巡检结果" width="160" align="center">
|
|
|
<template #default="{row}">
|
|
|
<span v-if="checkTime">
|
|
|
- <el-icon size="25" color="#90a4ae" class="rotate" v-if="row.checkProess!=='done'"><Loading /></el-icon>
|
|
|
- <el-icon size="25" color="#388e3c" v-else><CircleCheck /></el-icon>
|
|
|
+ <span v-if="row.resultL">
|
|
|
+ {{ row.resultL }}
|
|
|
+ </span>
|
|
|
+ <el-icon size="25" color="#388e3c" class="rotate" v-else><Loading/></el-icon>
|
|
|
</span>
|
|
|
<span v-else>-</span>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
- <el-table-column label="巡检结果" align="center" width="180">
|
|
|
+ <el-table-column prop="remark" label="备注" align="center" width="160">
|
|
|
<template #default="{row}">
|
|
|
<span v-if="checkTime">
|
|
|
- <el-icon size="25" color="#90a4ae" class="rotate" v-if="!row.checkResult"><Loading /></el-icon>
|
|
|
- <span v-else class="check-result">
|
|
|
- <el-icon size="20" color="#e43"><WarnTriangleFilled /></el-icon>
|
|
|
- <span class="res-text">{{row.checkResult}} 项</span>
|
|
|
+ <span v-if="row.resultR" :style="`color:${row.resultR === '正常'?'#1ab43f':'#e43'}`">
|
|
|
+ {{ row.resultR }}
|
|
|
</span>
|
|
|
+ <el-icon size="25" color="#388e3c" class="rotate" v-else><Loading/></el-icon>
|
|
|
</span>
|
|
|
<span v-else>-</span>
|
|
|
</template>
|
|
@@ -80,138 +73,158 @@
|
|
|
</el-table>
|
|
|
</div>
|
|
|
|
|
|
- <div class="btn-center-row" v-if="checkFlag">
|
|
|
- <el-button type="primary" plain @click="visible=true">巡查报告查看</el-button>
|
|
|
- </div>
|
|
|
-
|
|
|
- <el-dialog v-model="visible" width="1000" title="巡检报告查看">
|
|
|
- <check-history />
|
|
|
+ <el-dialog v-model="isComponent.visible" width="1000" :title="isComponent.title" style="margin-top:2vh!important">
|
|
|
+ <component :is="isComponent.component" :crId="nowCheck.crId" :spanMethod="spanMethod"/>
|
|
|
</el-dialog>
|
|
|
+
|
|
|
</div>
|
|
|
</template>
|
|
|
<script setup lang="ts">
|
|
|
-import {getCheckList,getCheckModel} from "@/api/hl/bm"
|
|
|
+import {chkcCheck, listChkc} from "@/api/check/chkc"
|
|
|
import {onMounted} from "vue";
|
|
|
-import {Timer,Compass,Warning,Loading,CircleCheck,WarnTriangleFilled} from "@element-plus/icons-vue"
|
|
|
-import checkHistory from "./widget/checkHistory.vue"
|
|
|
-import {useRoute,useRouter} from "vue-router"
|
|
|
+import {Loading} from "@element-plus/icons-vue";
|
|
|
+import nCheckReport from "./widget/nCheckReport.vue"
|
|
|
+import nCheckList from "./widget/nCheckList.vue"
|
|
|
+
|
|
|
const checkList = ref([])
|
|
|
-const cLoading = ref(false)
|
|
|
-const currentProgress = ref(0)
|
|
|
-const cIndex=ref(null)
|
|
|
const listData = ref([])
|
|
|
+const currentProgress = ref(0)
|
|
|
+const cIndex = ref(null)
|
|
|
+const cLoading = ref(false)
|
|
|
const checkTime = ref(null)
|
|
|
-const totalError=ref(0)
|
|
|
-const totalErrorCount = ref(0)
|
|
|
+const nowCheck = ref({})
|
|
|
const checkFlag = ref(false)
|
|
|
-const visible = ref(false)
|
|
|
-
|
|
|
-const route = useRoute()
|
|
|
-const router = useRouter()
|
|
|
+const isComponent = ref({
|
|
|
+ visible: false,
|
|
|
+ title: "",
|
|
|
+ component: nCheckReport
|
|
|
+})
|
|
|
|
|
|
const colors = [
|
|
|
- { color: '#bbdefb', percentage: 20 },
|
|
|
- { color: '#90caf9', percentage: 40 },
|
|
|
- { color: '#64b5f6', percentage: 60 },
|
|
|
- { color: '#2196f3', percentage: 80 },
|
|
|
- { color: '#1e88e5', percentage: 100 },
|
|
|
+ {color: '#bbdefb', percentage: 20},
|
|
|
+ {color: '#90caf9', percentage: 40},
|
|
|
+ {color: '#64b5f6', percentage: 60},
|
|
|
+ {color: '#2196f3', percentage: 80},
|
|
|
+ {color: '#1e88e5', percentage: 100},
|
|
|
]
|
|
|
|
|
|
-onMounted( ()=>{
|
|
|
- if(!route.query.check && localStorage.getItem("listData")){
|
|
|
+onMounted(() => {
|
|
|
+ if (localStorage.getItem("listData")) {
|
|
|
return restoreCache()
|
|
|
}
|
|
|
- getListData()
|
|
|
+ getListChkc()
|
|
|
})
|
|
|
|
|
|
+const handleDialog = (action) => {
|
|
|
+ if (action === 'report') {
|
|
|
+ isComponent.value = {
|
|
|
+ visible: true,
|
|
|
+ title: "巡检报告查看",
|
|
|
+ component: nCheckReport
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ isComponent.value = {
|
|
|
+ visible: true,
|
|
|
+ title: "巡检记录配置",
|
|
|
+ component: nCheckList
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
|
|
|
-async function getListData(){
|
|
|
- const res = await getCheckList();
|
|
|
- checkList.value = res.data
|
|
|
- listData.value = res.data[0].classList
|
|
|
- route.query.check && handleNowCheck(checkList.value.length)
|
|
|
+const restoreCache = () => {
|
|
|
+ listData.value = JSON.parse(localStorage.getItem("listData"))
|
|
|
+ nowCheck.value = JSON.parse(localStorage.getItem("nowCheck"))
|
|
|
+ checkList.value = uniqueByKey(listData.value, 'className')
|
|
|
+ checkFlag.value = true
|
|
|
+ // cIndex.value = listData.value.length - 1
|
|
|
+ checkTime.value = nowCheck.value.checkTime
|
|
|
+ currentProgress.value = 100
|
|
|
}
|
|
|
|
|
|
-function convertTime(milliseconds) {
|
|
|
- // 将毫秒转换为秒
|
|
|
- let seconds = Math.floor(milliseconds / 1000);
|
|
|
+const spanMethod = ({row, column, rowIndex}) => {
|
|
|
+ if (column.property === "className") {
|
|
|
+ const currentClass = listData.value[rowIndex].className;
|
|
|
+ const prevClass = listData.value[rowIndex - 1]?.className;
|
|
|
+ if (currentClass !== prevClass) {
|
|
|
+ let rowspan = 1;
|
|
|
+ for (let i = rowIndex + 1; i < listData.value.length; i++) {
|
|
|
+ if (listData.value[i].className === currentClass) {
|
|
|
+ rowspan++;
|
|
|
+ } else {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return {rowspan, colspan: 1};
|
|
|
+ } else {
|
|
|
+ return {rowspan: 0, colspan: 0};
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
|
|
|
- // 计算小时、分钟和秒
|
|
|
- let hours = Math.floor(seconds / 3600);
|
|
|
- let minutes = Math.floor((seconds % 3600) / 60);
|
|
|
- let remainingSeconds = seconds % 60;
|
|
|
+const uniqueByKey = (array, key) => {
|
|
|
+ const map = new Map();
|
|
|
+ array.forEach(item => map.set(item[key], item));
|
|
|
+ return Array.from(map.values());
|
|
|
+}
|
|
|
|
|
|
- // 格式化为00:00:00的形式
|
|
|
- return padZero(hours) + ":" + padZero(minutes) + ":" + padZero(remainingSeconds);
|
|
|
+const getListChkc = async () => {
|
|
|
+ const {rows} = await listChkc({pageSize: 100})
|
|
|
+ listData.value = rows
|
|
|
+ checkList.value = uniqueByKey(rows, 'className')
|
|
|
}
|
|
|
|
|
|
-// 在数字前面补零,确保两位数的格式
|
|
|
-function padZero(number) {
|
|
|
+const padZero = (number) => {
|
|
|
return (number < 10 ? "0" : "") + number;
|
|
|
}
|
|
|
|
|
|
-function getRandomInt(min, max) {
|
|
|
- // Math.random() 生成一个 0 到 1 之间的随机数
|
|
|
- // max - min + 1 是生成随机数的范围
|
|
|
- // Math.floor() 向下取整,确保生成的是整数
|
|
|
+const getRandomInt = (min, max) => {
|
|
|
return Math.floor(Math.random() * (max - min + 1)) + min;
|
|
|
}
|
|
|
|
|
|
-function handleNowCheck(sub){
|
|
|
- if(!cLoading.value){
|
|
|
- checkFlag.value = false
|
|
|
- if(localStorage.getItem("listData")){
|
|
|
- removeCache()
|
|
|
- !route.query.check && getListData()
|
|
|
- }
|
|
|
+const onNowCheck = async () => {
|
|
|
+ const {data} = await chkcCheck()
|
|
|
+ nowCheck.value = data
|
|
|
+ handleCheck(0)
|
|
|
+}
|
|
|
+
|
|
|
+const handleCheck = (i) => {
|
|
|
+ if (!cLoading.value) {
|
|
|
cLoading.value = true;
|
|
|
cIndex.value = null;
|
|
|
- totalError.value = 0;
|
|
|
- totalErrorCount.value=0;
|
|
|
+ currentProgress.value = 0;
|
|
|
checkTime.value = new Date();
|
|
|
+ checkFlag.value = false
|
|
|
+ if (localStorage.getItem("listData")) {
|
|
|
+ localStorage.removeItem("listData")
|
|
|
+ localStorage.removeItem("nowCheck")
|
|
|
+ }
|
|
|
}
|
|
|
- let index = checkList.value.length-sub
|
|
|
- currentProgress.value = Number(Number(index / checkList.value.length * 100).toFixed(2))
|
|
|
- if(index > checkList.value.length-1) {
|
|
|
- saveCache()
|
|
|
- return cLoading.value = false
|
|
|
- }
|
|
|
- setTimeout(async ()=>{
|
|
|
- await getCheckModel(checkList.value[index].modelId)
|
|
|
- totalErrorCount.value= 413
|
|
|
- listData.value[index].checkProess = 'done'
|
|
|
- let e = Math.ceil(Math.random()*100)
|
|
|
- totalError.value += e
|
|
|
- listData.value[index].checkResult = e
|
|
|
- cIndex.value = index
|
|
|
- handleNowCheck(sub-1)
|
|
|
- }, getRandomInt(500, 500))
|
|
|
-}
|
|
|
-
|
|
|
-function saveCache(){
|
|
|
- localStorage.setItem("listData", JSON.stringify(listData.value))
|
|
|
- localStorage.setItem("errorInfo",JSON.stringify({totalErrorCount:totalErrorCount.value,totalError:totalError.value,checkTime:checkTime.value}))
|
|
|
- localStorage.setItem("checkList",JSON.stringify(checkList.value))
|
|
|
- checkFlag.value = true
|
|
|
- router.replace({path:"/hl/check"})
|
|
|
-}
|
|
|
|
|
|
-function removeCache(){
|
|
|
- localStorage.removeItem("listData")
|
|
|
- localStorage.removeItem("errorInfo")
|
|
|
- localStorage.removeItem("checkList")
|
|
|
-}
|
|
|
-
|
|
|
-function restoreCache(){
|
|
|
- listData.value = JSON.parse(localStorage.getItem("listData"))
|
|
|
- checkList.value = JSON.parse(localStorage.getItem("checkList"))
|
|
|
- const errorInfo = JSON.parse(localStorage.getItem("errorInfo"))
|
|
|
- cIndex.value = checkList.value.length-1
|
|
|
- totalErrorCount.value = errorInfo.totalErrorCount
|
|
|
- totalError.value = errorInfo.totalError
|
|
|
- checkTime.value = errorInfo.checkTime
|
|
|
- currentProgress.value = 100
|
|
|
- checkFlag.value = true
|
|
|
+ const randomStep = getRandomInt(2, 5);
|
|
|
+ const index = Math.min(i + randomStep, listData.value.length - 1);
|
|
|
+
|
|
|
+ if (i < listData.value.length) {
|
|
|
+ setTimeout(() => {
|
|
|
+ currentProgress.value = Number(((index + 1) / listData.value.length * 100).toFixed(1));
|
|
|
+
|
|
|
+ for (let j = i; j <= index; j++) {
|
|
|
+ const item = listData.value[j];
|
|
|
+ const detail = nowCheck.value.detailList.find(cItem => cItem.ccId === item.ccId);
|
|
|
+
|
|
|
+ if (detail) {
|
|
|
+ const {resultL, resultR, remark} = detail;
|
|
|
+ listData.value[j] = {...item, resultL, resultR, remark};
|
|
|
+ }
|
|
|
+ }
|
|
|
+ handleCheck(index + 1);
|
|
|
+ }, getRandomInt(1000, 3000));
|
|
|
+ } else {
|
|
|
+ cLoading.value = false;
|
|
|
+ currentProgress.value = 100;
|
|
|
+ checkFlag.value = true
|
|
|
+ localStorage.setItem("nowCheck", JSON.stringify(nowCheck.value))
|
|
|
+ localStorage.setItem("listData", JSON.stringify(listData.value))
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
|