Files
pqs-9100_client/frontend/src/views/plan/autoTest/index.vue

841 lines
21 KiB
Vue
Raw Normal View History

2024-10-10 17:47:55 +08:00
<template>
<!-- 自动检测页面 -->
<div class="test">
<!-- 顶部筛选条件&返回按钮 -->
<!-- {{ printText }} -->
<div class="test_top">
<!-- style="pointer-events: none" -->
2024-11-14 18:40:58 +08:00
<svg-icon name="wind" spin></svg-icon>
<el-checkbox
v-for="(item, index) in detectionOptions"
v-model="item.selected"
:key="index"
:label="item.name"
></el-checkbox
>
2024-11-14 18:39:13 +08:00
<el-button type="primary" @click="handlePreTest">预检测</el-button>
<el-button type="primary" @click="handleAutoTest">正式检测</el-button>
<el-button type="primary" @click="handleBackDeviceList"
>返回首页</el-button
>
2024-11-14 18:40:58 +08:00
<el-select v-model="currentErrSysID" placeholder="请选择误差体系" autocomplete="off">
<el-option
v-for="plan in testErrSystDataList"
:key="plan.id"
:label="plan.label"
:value="plan.id">
</el-option>
</el-select>
<el-button type="primary" @click="handlePreTest">重新计算</el-button>
</div>
<div class="test_bot">
<div class="test_left">
2024-10-10 17:47:55 +08:00
<Tree ref="treeRef"></Tree>
</div>
<div class="test_right">
<el-descriptions
style="
width: 100%;
border-radius: 6px;
margin-bottom: 10px;
background-color: #fff;
padding: 10px;
"
:column="3"
border
>
<template #extra>
<el-progress
style="width: 80%"
:percentage="percentage"
:color="customColors"
/>
<div class="test_button">
<el-button
type="primary"
v-if="!isPause"
:icon="VideoPause"
@click="handlePauseTest"
>暂停检测</el-button
>
<el-button
type="warning"
v-if="isPause"
:icon="Refresh"
@click="handlePauseTest"
>继续检测</el-button
>
<el-button type="danger" :icon="Close" @click="handleFinishTest"
>停止检测</el-button
>
<!-- <el-button
2024-10-10 17:47:55 +08:00
type="danger"
v-if="!isPause"
:icon="Close"
@click="handlePauseTest"
>暂停检测</el-button
>
<el-button
type="warning"
v-if="isPause"
:icon="Refresh"
@click="handlePauseTest"
>继续检测</el-button
>
<el-button type="primary" :icon="Check" @click="handleFinishTest"
>完成检测</el-button
> -->
2024-10-10 17:47:55 +08:00
</div>
</template>
<!-- <el-descriptions-item width="0px" label="上送数据总数">
2024-10-10 17:47:55 +08:00
{{ num }}
</el-descriptions-item>
<el-descriptions-item width="0px" label="已上送数据数">
{{ num1 }}
</el-descriptions-item>
<el-descriptions-item width="0px" label="待上送数据数">
{{ num2 }}
</el-descriptions-item> -->
2024-10-10 17:47:55 +08:00
</el-descriptions>
<!-- 右侧列表 -->
<div class="right_table">
<!-- 模拟列表样式 -->
<!-- 表头设备 -->
<div class="table_left" v-if="false">
2024-10-10 17:47:55 +08:00
<p>测试项目</p>
<div v-for="(item, index) in deviceTestList" :key="index">
{{ item.name }}
</div>
</div>
<div class="table_right">
<div class="right_device_title">
<p v-for="(item, index) in deviceData" :key="index">
{{ item.name }}
</p>
</div>
<div class="right_device_status">
<div
class="status_info"
v-for="(item, index) in deviceTestList"
:key="index"
>
<!-- <p v-for="(vv, vvs) in item.children" :key="vvs">
2024-10-10 17:47:55 +08:00
{{ vv.status }}
</p> -->
<el-button
v-for="(vv, vvs) in item.children"
:key="vvs"
:type="vv.type"
text
@click="handleClick(item,index,vvs)"
>
{{ vv.label }}
</el-button>
2024-10-10 17:47:55 +08:00
</div>
</div>
</div>
</div>
<!-- 右侧状态加载 -->
<div class="right_status" ref="statusRef">
<!-- ,fontSize:index%5===0?'16px':'14px' -->
<p v-for="(item, index) in statusList" :key="index" :style="{color:index%5===0?'#F56C6C':'var(--el-text-color-regular)'}">
2024-10-10 17:47:55 +08:00
输入{{ item.remark }} -{{
item.status == 0 ? "输出完毕" : "输入中,请稍后!"
}}<br />
<span v-if="index == statusList.length - 1">...</span>
</p>
</div>
</div>
</div>
</div>
<ShowDataPopup ref='showDataPopup'/>
2024-10-10 17:47:55 +08:00
</template>
<script lang="ts" setup>
import { ref, onMounted, reactive, nextTick } from "vue";
import Tree from "./components/tree.vue";
import { data } from "@/api/plan/autoTest.json";
import { useTransition } from "@vueuse/core";
import { getPlanList } from "@/api/plan/planList";
import { ElMessage, ElMessageBox } from "element-plus";
import ShowDataPopup from './components/ShowDataPopup.vue'
2024-10-10 17:47:55 +08:00
import {
CirclePlus,
Delete,
EditPen,
Download,
Upload,
View,
Check,
Plus,
Refresh,
Search,
Close,
VideoPause,
2024-10-10 17:47:55 +08:00
} from "@element-plus/icons-vue";
2024-11-14 18:40:58 +08:00
import {dictPattern,dictTestState,dictReportState,dictResult,testPlanDataList,testSoureDataList,testScriptDataList,testErrSystDataList,planData,testFatherPlanList} from '@/api/plan/planData'
import { useRouter } from 'vue-router'
const router = useRouter()
const currentErrSysID = ref("2")
2024-10-10 17:47:55 +08:00
const treeRef = ref<any>();
const PopupVisible = ref(false)
const showDataPopup = ref()
//定义与预检测配置数组
const detectionOptions = ref([
{
id: 0,
name: "标准源通讯检测",//判断源通讯是否正常
selected: true,
},
{
id: 1,
name: "设备通讯检测",//判断设备的IP、Port、识别码、秘钥是否正常
selected: true,
},
{
id: 2,
name: "协议校验",//ICD报告触发测试
selected: true,
},
{
id: 3,
name: "相序校验",//判断装置的接线是否正确
selected: true,
},
{
id: 4,
name: "守时校验",//判断装置24小时内的守时误差是否小于1s
selected: true,
},
{
id: 5,
name: "通道系数校准",//通过私有协议与装置进行通讯,校准三相电压电流的通道系数
selected: true,
},
// {
// id: 6,
// name: "实时数据比对",
// },
// {
// id: 7,
// name: "录波数据比对",
// },
]);
const leftDeviceData = ref<any>([
// {
// id: 0,
// name: "设备1-预检测",
// status: 0,
// },
// {
// id: 1,
// name: "设备2-预检测",
// status: 1,
// },
// {
// id: 2,
// name: "设备3-预检测",
// status: 1,
// },
// {
// id: 3,
// name: "设备4-预检测",
// status: 0,
// },
// {
// id: 4,
// name: "设备5-预检测",
// status: 1,
// },
// {
// id: 5,
// name: "设备6-预检测",
// status: 0,
// },
]);
const initLeftDeviceData = () => {
leftDeviceData.value.map((item, index) => {
// handlePrintText(item.name, index);
});
};
2024-11-14 18:40:58 +08:00
const preTestData = [
{
"id": 0,
"name": "预检测项目",
"children": [
{
"scriptIdx":1,
"isChildNode":true,
"pid": "0-2",
"id": "0-2-2",
"name": "标准源通讯检测"
},
{
"scriptIdx":2,
"isChildNode":true,
"pid": "0-3",
"id": "0-3-1",
"name": "设备通讯检测"
},
{
"scriptIdx":3,
"isChildNode":true,
"pid": "0-3",
"id": "0-3-1",
"name": "协议校验"
},
{
"scriptIdx":4,
"isChildNode":true,
"pid": "0-3",
"id": "0-3-1",
"name": "相序校验"
},
{
"scriptIdx":5,
"isChildNode":true,
"pid": "0-3",
"id": "0-3-1",
"name": "守时校验"
},
{
"scriptIdx":6,
"isChildNode":true,
"pid": "0-3",
"id": "0-3-1",
"name": "通道系数校准"
}
]
}
]
// 弹出检测结果页面
const handleClick = (item,index,vvs) => {
//const data = "检测脚本为:"+item.name+";被检设备为:"+item.children.value.devID+";被检通道序号为:"+ item.children.monitorIndex;
console.log(vvs,index,item.name,item.children)
PopupVisible.value = true
showDataPopup.value.open()
};
//启动预检测
const handlePreTest = () => {
ElMessage.success("启动预检测");
2024-11-14 18:40:58 +08:00
getTreeData(preTestData)
// let count = 0;
// if (timer) {
// clearInterval(timer);
// count = 0;
// leftDeviceData.value = [];
// }
// if (count == 5) {
// count = 0;
// }
// else {
// timer = setInterval(async () => {
// count++;
// if (count > 15) return;
// await nextTick(() => {
// leftDeviceData.value.push({
// id: count,
// name: "设备" + count + "预检测",
// status: count % 2 == 0 ? 0 : 1,
// });
// });
// }, 2000);
// }
};
//进入检测流程
const handleAutoTest = () => {
2024-11-14 18:40:58 +08:00
ElMessage.success("启动正式检测");
getTreeData(data)
};
//返回设备列表
const handleBackDeviceList = () => {
router.push({
2024-11-14 18:40:58 +08:00
path: "/home/index",
});
};
2024-10-10 17:47:55 +08:00
// 表格配置项
const columns = reactive<ColumnProps<User.ResUserList>[]>([
{ type: "selection", fixed: "left", width: 70 },
2024-10-31 14:53:29 +08:00
// { dictType: "sort", label: "Sort", width: 80 },
// { dictType: "expand", label: "Expand", width: 85 },
2024-10-10 17:47:55 +08:00
{
prop: "planName",
label: "计划名称",
width: 120,
},
{
prop: "checkMode",
label: "检测模式",
width: 120,
render: (scope: any) => {
return scope.row.checkMode == 0
? "模拟式"
: scope.row.checkMode == 1
? "对比式"
: scope.row.checkMode == 2
? "数字式"
: scope.row.checkMode;
},
},
{
prop: "checkFrom",
label: "检测源",
width: 120,
render: (scope: any) => {
return scope.row.checkFrom == 0
? "标准源-福禄克-6100A"
: scope.row.checkFrom == 1
? "标准源-昂立-PF2"
: scope.row.checkFrom == 2
? "高精度设备-PQS882-1"
: scope.row.checkFrom;
},
},
{
prop: "numberFromName",
label: "源名称",
render: (scope: any) => {
return scope.row.numberFromName == 0
? "分钟统计数据最大值"
: scope.row.numberFromName == 1
? "分钟统计数据最小值"
: scope.row.numberFromName == 2
? "分钟统计数据CP95值"
: scope.row.numberFromName;
},
},
{
prop: "checkExe",
label: "检测脚本",
width: 120,
render: (scope: any) => {
return scope.row.checkExe == 0
? "国网入网检测脚本(单影响量-模拟式)"
: scope.row.checkExe == 1
? "国网入网检测脚本"
: scope.row.checkExe == 2
? "/"
: scope.row.checkExe;
},
},
{
prop: "wctx",
label: "误差体系",
width: 120,
render: (scope: any) => {
return scope.row.wctx == 0
? "Q/GDW 1650.2- 2016"
: scope.row.wctx == 1
? "Q/GDW 10650.2 - 2021"
: scope.row.wctx == 2
? "/"
: scope.row.wctx;
},
},
{
prop: "checkStatus",
label: "检测状态",
width: 120,
render: (scope: any) => {
return scope.row.checkStatus == 1
? "未检测"
: scope.row.checkStatus == 2
? "检测中"
: scope.row.checkStatus == 3
? "检测完成"
: scope.row.checkStatus;
},
},
{
prop: "checkReport",
label: "检测报告",
width: 120,
render: (scope: any) => {
return scope.row.checkReport == 1
? "未生成"
: scope.row.checkReport == 2
? "部分生成"
: scope.row.checkReport == 3
? "全部生成"
: scope.row.checkReport;
},
},
{
prop: "checkResult",
label: "检测结果",
width: 120,
render: (scope: any) => {
return scope.row.checkReport == 1
? "/"
: scope.row.checkReport == 2
? "符合"
: scope.row.checkReport == 3
? "不符合"
: scope.row.checkReport;
},
},
// { prop: "operation", label: "操作", fixed: "right", width: 250 },
]);
2024-11-14 18:40:58 +08:00
const getTreeData = (val) => {
treeRef.value && treeRef.value.getTreeData(val);
2024-10-10 17:47:55 +08:00
};
2024-11-14 18:40:58 +08:00
2024-10-10 17:47:55 +08:00
// ProTable 实例
const proTable = ref<ProTableInstance>();
// 如果表格需要初始化请求参数,直接定义传给 ProTable (之后每次请求都会自动带上该参数,此参数更改之后也会一直带上,改变此参数会自动刷新表格数据)
const initParam = reactive({ type: 1, pageNum: 1, pageSize: 10 });
// dataCallback 是对于返回的表格数据做处理,如果你后台返回的数据不是 list && total 这些字段,可以在这里进行处理成这些字段
// 或者直接去 hooks/useTable.ts 文件中把字段改为你后端对应的就行
const tableList = ref([]);
const dataCallback = (data: any) => {
return {
list: data || data.data || data.list,
total: data.length || data.total, //total
};
};
// 如果你想在请求之前对当前请求参数做一些操作可以自定义如下函数params 为当前所有的请求参数(包括分页),最后返回请求列表接口
// 默认不做操作就直接在 ProTable 组件上绑定 :requestApi="getUserList"
const getTableList = (params: any) => {
let newParams = JSON.parse(JSON.stringify(params));
newParams.createTime && (newParams.startTime = newParams.createTime[0]);
newParams.createTime && (newParams.endTime = newParams.createTime[1]);
delete newParams.createTime;
return getPlanList(newParams);
};
const percentage = ref(0);
const customColors = [
// { color: "red", percentage: 0 },
// { color: "red", percentage: 10 },
// { color: "red", percentage: 20 },
// { color: "red", percentage: 30 }, //红
// { color: "red", percentage: 40 },
// { color: "#e6a23c", percentage: 50 },
// { color: "#e6a23c", percentage: 60 },
// { color: "#e6a23c", percentage: 70 }, //黄
// { color: "#e6a23c", percentage: 80 }, //1989fa
// { color: "#e6a23c", percentage: 90 }, //1989fa
2024-10-10 17:47:55 +08:00
{ color: "#5cb87a", percentage: 100 }, //绿
];
//加载进度条
const refreshProgress = () => {
if (percentage.value < 100) {
percentage.value += 1;
2024-10-10 17:47:55 +08:00
num1.value += 1001;
num2.value -= 1001;
} else {
percentage.value = 0;
num1.value = 9999;
num2.value = 162001;
statusList.value = [];
deviceTestList.value = [];
statusId.value = 0;
}
};
let timer: any = ref("");
const statusTimer: any = ref("");
//检测列表数据
const deviceTestList = ref<any>([]);
//检测结果数据
const deviceList = ref<any>([]);
//前一个页面带过来的设备数据
const deviceData = ref([
{
id: 0,
name: "设备1通道1",
status: Math.floor(Math.random() * 4),
type:"info",
label:"/",
devID:"dev1",
monitorIndex:1,
2024-10-10 17:47:55 +08:00
},
{
id: 1,
name: "设备1通道2",
2024-10-10 17:47:55 +08:00
status: Math.floor(Math.random() * 4),
type:"success",
label:"√",
devID:"dev1",
monitorIndex:2,
2024-10-10 17:47:55 +08:00
},
{
id: 2,
name: "设备2通道1",
2024-10-10 17:47:55 +08:00
status: Math.floor(Math.random() * 4),
type:"danger",
label:"×",
devID:"dev2",
monitorIndex:1,
2024-10-10 17:47:55 +08:00
},
{
id: 3,
name: "设备3通道1",
2024-10-10 17:47:55 +08:00
status: Math.floor(Math.random() * 4),
type:"success",
label:"√",
devID:"dev3",
monitorIndex:1,
2024-10-10 17:47:55 +08:00
},
]);
const interValTest = () => {
timer.value = setInterval(() => {
deviceTestList.value.push({
id: 0,
name: `频率 ${statusId.value}Hz`,
children: deviceData.value,
// status: Math.floor(Math.random() * 4),
});
// console.log(deviceTestList.value,11111);
2024-10-10 17:47:55 +08:00
refreshProgress();
}, 2000);
statusTimer.value = setInterval(() => {
getStatusList();
statusList.value.map((item: any, index: any) => {
if (index == statusList.value.length - 1) {
item.status = 1;
} else {
item.status = 0;
}
});
}, 2000);
};
interValTest();
//暂停检测
const isPause = ref<boolean>(false);
const handlePauseTest = () => {
if (!isPause.value) {
clearInterval(timer.value);
clearInterval(statusTimer.value);
} else {
interValTest();
}
isPause.value = !isPause.value;
};
//完成检测
const handleFinishTest = () => {
ElMessage.success("完成检测");
};
// 表格拖拽排序
const sortTable = ({
newIndex,
oldIndex,
}: {
newIndex?: number;
oldIndex?: number;
}) => {
console.log(newIndex, oldIndex);
console.log(proTable.value?.tableData);
ElMessage.success("修改列表排序成功");
};
const num = ref(0),
num1 = ref(0),
num2 = ref(0);
const allUploadNum = useTransition(num, {
duration: 1500,
});
const isUploadNum = useTransition(num1, {
duration: 1500,
});
const notUploadNum = useTransition(num2, {
duration: 1500,
});
num.value = 172000;
num1.value = 9999;
num2.value = num.value - num1.value;
const statusList: any = ref([]);
let statusId = ref(0);
const statusRef = ref();
const getStatusList = () => {
statusId.value++;
statusList.value.push({
id: statusId.value,
remark: `频率 ${statusId.value}Hz`,
status: 0,
});
// console.log(statusRef.value.offsetHeight);
nextTick(() => {
if (statusRef.value)
statusRef.value.scrollTop = statusRef.value.scrollHeight;
});
};
2024-11-14 18:40:58 +08:00
2024-10-10 17:47:55 +08:00
onMounted(() => {
2024-11-14 18:40:58 +08:00
2024-10-10 17:47:55 +08:00
});
</script>
<style lang="scss" scoped>
.test {
width: 100%;
height: 100%;
box-sizing: border-box;
display: flex;
flex-direction: column;
2024-10-10 17:47:55 +08:00
justify-content: space-between;
.test_top {
width: 100%;
height: 50px;
display: flex;
background-color: #fff;
justify-content: flex-start;
align-items: center;
border-radius: 4px;
padding: 0 10px;
box-sizing: border-box;
.el-button {
margin-top: 10px;
margin-bottom: 10px;
margin-left: 20px;
}
2024-11-14 18:40:58 +08:00
.el-select {
margin-top: 10px;
margin-bottom: 10px;
margin-left: 20px;
}
}
.test_bot {
flex: 1;
margin-top: 10px;
display: flex;
height: calc(100vh - 240px);
2024-10-10 17:47:55 +08:00
.test_left {
max-width: 300px;
min-width: 200px;
width: 15%;
height: 100%;
overflow: auto;
padding-bottom: 20px;
box-sizing: border-box;
background-color: #fff;
border-radius: 6px;
padding: 5px !important;
box-sizing: border-box;
}
.test_right {
flex: 1;
height: 100%;
margin-left: 10px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between;
.right_table {
flex: 1;
// width: 100%;
// height: calc(100vh - 330px);
height: 100%;
flex: 1 !important;
height: calc(100vh - 560px);
border-radius: 4px;
background-color: #fff;
width: 100% !important;
display: flex;
padding: 10px;
box-sizing: border-box;
.table_left {
width: 150px;
height: 100%;
overflow: auto;
p {
line-height: 40px;
margin: 0;
width: 100px;
}
}
.table_right {
flex: 1;
display: flex;
overflow: auto;
flex-direction: column;
.right_device_title {
width: 100%;
display: flex;
justify-content: center;
2024-10-10 17:47:55 +08:00
// overflow-x: auto !important;
p {
flex: 1;
// max-width: 150px;
text-align: center;
2024-10-10 17:47:55 +08:00
width: auto;
padding: 0 10px;
margin: 0;
line-height: 40px;
}
}
.right_device_status {
width: 100%;
flex: 1;
.status_info {
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
.el-button {
2024-10-10 17:47:55 +08:00
flex: 1;
// max-width: 150px;
min-width: auto;
margin: 0;
padding: 0 10px;
text-align: left;
}
}
}
}
}
.right_status {
width: 100%;
height: 150px;
overflow: auto;
background-color: #fff;
border-radius: 4px;
margin-top: 10px;
padding: 10px 0 20px 10px;
box-sizing: border-box;
p {
height: 20px;
font-size: 14px;
margin: 0 !important;
}
:nth-last-child(1) {
margin-bottom: 40px;
}
}
}
}
2024-10-10 17:47:55 +08:00
}
::v-deep .header-button-lf {
clear: both !important;
}
::v-deep .el-descriptions__extra {
width: 100%;
display: flex;
justify-content: space-between;
.test_button {
width: auto;
display: flex;
align-items: center;
}
}
</style>