<script setup name="testBatch">
|
import { ref, reactive, computed, watch, onMounted, onActivated } from "vue";
|
import ycCard from "@/components/ycCard.vue";
|
import devCard from "./devCard.vue";
|
import paramContent from "./paramContent.vue";
|
import jhParamContent from "./jhParamContent.vue";
|
import { useRoute, useRouter } from "vue-router";
|
import battCountContent from "./battCountContent.vue";
|
|
import { cancelContPl, controllerActmParam, stopA200ParamPl } from "./api.js";
|
|
import useElement from "@/hooks/useElement.js";
|
const { $alert, $loading, $message, $confirm } = useElement();
|
|
import useDevsRt from "@/hooks/useDevsRt";
|
const { list: devList } = useDevsRt();
|
|
const $route = useRoute();
|
const $router = useRouter();
|
const devType = ref(1);
|
const keyWord = ref("");
|
const testVisible = ref(false);
|
const testGroupIdx = ref();
|
const jhyBattCountVisible = ref(false);
|
|
const list = reactive({
|
// 总的选中
|
selectedList: { 1: [], 2: [] },
|
// 筛选后的数据
|
resData: { 1: [], 2: [] },
|
});
|
// 总的选中后的数据
|
const selectData = computed(() => {
|
let getItem = (v) =>
|
devList.value[v].filter((vv) => list.selectedList[v].includes(vv.devId));
|
return {
|
1: getItem(1),
|
2: getItem(2),
|
};
|
});
|
watch(devList, (val, old) => {
|
// console.log("val ch", val, old, "=============");
|
if ((val[1].length || val[2].length) && !(old[1].length || old[2].length)) {
|
initCheck();
|
}
|
filterList();
|
});
|
|
function filterList() {
|
let idx = devType.value;
|
list.resData[idx] = devList.value[idx].filter(
|
(v) => ("" + v.devIdcode).indexOf(keyWord.value) > -1
|
);
|
}
|
function typeChange(params) {
|
filterList();
|
if ($route.query.devType) {
|
// console.log('t', $route.query.devType, '=============');
|
$router.replace({ query: { ...$route.query, devType: undefined } });
|
}
|
}
|
// 初始选中 是根据设备的batchState判断是否是批量的 是就选中
|
function initCheck(params) {
|
[1, 2].forEach((idx) => {
|
list.selectedList[idx] = devList.value[idx]
|
.filter((v) => v.batchState == 1)
|
.map((v) => v.devId);
|
});
|
}
|
function checkAll() {
|
let idx = devType.value;
|
let _add = list.resData[idx]
|
.filter((v) => v.devOnline && !v.state.isTesting)
|
.map((v) => v.devId);
|
|
// 处理selectedList 只会有添加
|
let _arr = _add.filter((v) => !list.selectedList[idx].includes(v));
|
|
list.selectedList[idx].push(..._arr);
|
}
|
function checkInvert() {
|
let idx = devType.value;
|
let old = list.selectedList[idx].filter((v) =>
|
list.resData[idx].some((vv) => vv.devId == v)
|
);
|
let val = list.resData[idx]
|
.filter((v) => v.devOnline && !v.state.isTesting)
|
.filter((v) => !old.includes(v.devId))
|
.map((v) => v.devId);
|
// 处理selectedList
|
let addList = val.filter((v) => !old.includes(v));
|
let removeList = old.filter((v) => !val.includes(v));
|
// 移除
|
list.selectedList[idx] = list.selectedList[idx].filter(
|
(v) => !removeList.includes(v)
|
);
|
// 添加
|
list.selectedList[idx].push(...addList);
|
}
|
function clearAll() {
|
let idx = devType.value;
|
let old = list.selectedList[idx].filter((v) =>
|
list.resData[idx].some((vv) => vv.devId == v)
|
);
|
|
// 处理selectedList 只会有移除
|
list.selectedList[idx] = list.selectedList[idx].filter(
|
(v) => !old.includes(v)
|
);
|
}
|
|
// 是否有设备批量中
|
// 一体机 isTesting 为0
|
// 均衡仪 moduleStatusInt 不属于[3,4,6,7,9,10]中的一种
|
const isBatch = computed(() => {
|
let getItem = (vv) => selectData.value[vv].some((v) => v.batchState == 1);
|
return {
|
1: getItem(1),
|
2: getItem(2),
|
};
|
});
|
|
// 是否可以结束批量
|
// 除去掉线的设备 所有此类型的设备状态都为非测试状态
|
// 一体机 isTesting 为0
|
// 均衡仪 moduleStatusInt 不属于[3,4,6,7,9,10]中的一种
|
const canStopBatch = computed(() => {
|
let getItem = (vv) =>
|
selectData.value[vv]
|
.filter((v) => v.devOnline == 1)
|
.every((v) => v.state.isTesting == 0) &&
|
selectData.value[vv].length > 0 &&
|
selectData.value[vv].some((v) => v.batchState == 1);
|
return {
|
1: getItem(1),
|
2: getItem(2),
|
};
|
});
|
// 结束批量
|
function stopBatch(type) {
|
let devIds = devs.value.map((v) => v.devId);
|
cancelContPl(devIds)
|
.then((res) => {
|
let { code, data } = res.data;
|
if (code && data) {
|
console.log(data);
|
}
|
})
|
.catch((err) => {
|
console.log(err);
|
});
|
}
|
|
const devs = computed(() => {
|
return selectData.value[devType.value];
|
});
|
|
function goDetails(dev) {
|
if (!dev.devOnline) {
|
return false;
|
}
|
|
$router.push("/test-details?type=" + dev.devType + "&devId=" + dev.devId);
|
}
|
|
function test(groupIdx) {
|
// if (2 == devType.value) {
|
// } else {
|
// testGroupIdx.value = undefined;
|
// }
|
testGroupIdx.value = groupIdx;
|
testVisible.value = true;
|
}
|
|
function stopTest(groupIdx) {
|
let devIds = devs.value.map((v) => v.devId);
|
let loading = $loading();
|
stopA200ParamPl(devIds)
|
.then((res) => {
|
let { code, data, data2 } = res.data;
|
loading.close();
|
let failList = [];
|
let successList = [];
|
Object.keys(data2).forEach((v) => {
|
if (200 == data2[v].code) {
|
successList.push(v);
|
} else {
|
failList.push(v);
|
}
|
});
|
if (code && data && successList.length) {
|
$message.success("操作成功");
|
if (failList.length) {
|
let failNames = props.devs
|
.filter((v) => failList.some((vv) => vv == v.devId))
|
.map((v) => v.devIdcode);
|
|
$alert(`操作失败的设备列表:${failNames.join(", ")}。`);
|
}
|
close();
|
} else {
|
$message.error("操作失败");
|
}
|
})
|
.catch((err) => {
|
loading.close();
|
$message.error("操作失败");
|
console.log(err);
|
});
|
}
|
|
function controlTest(groupIdx, ctrlType) {
|
// * 2暂停 * 3继续 * 4 停止
|
let loading = $loading();
|
controllerActmParam(currentDevId.value, groupIdx, ctrlType)
|
.then((res) => {
|
loading.close();
|
let { code, data, msg } = res.data;
|
if (200 == code) {
|
$message.success("操作成功");
|
console.log(data);
|
} else {
|
$message.error("操作失败:" + msg);
|
}
|
})
|
.catch((err) => {
|
loading.close();
|
$message.error("操作失败:" + err);
|
console.log(err);
|
});
|
}
|
|
function setBattCount() {
|
jhyBattCountVisible.value = true;
|
}
|
|
onMounted(() => {});
|
onActivated(() => {
|
if ($route.query.devType) {
|
devType.value = $route.query.devType * 1;
|
}
|
filterList();
|
});
|
</script>
|
|
<template>
|
<!-- 批量测试 -->
|
<div class="page">
|
<div class="p-left">
|
<div class="filter">
|
<el-input
|
v-model="keyWord"
|
class="key-word"
|
@input="filterList"
|
placeholder="请您输入您要查找的设备"
|
>
|
<template #suffix>
|
<el-icon class="el-input__icon" color="#42f4b5"><search /></el-icon>
|
</template>
|
</el-input>
|
</div>
|
<div class="tabs">
|
<el-radio-group
|
v-model="devType"
|
@change="typeChange"
|
size="default"
|
is-button
|
>
|
<el-radio-button :value="1">充放电一体机</el-radio-button>
|
<el-radio-button :value="2">均衡测试仪</el-radio-button>
|
</el-radio-group>
|
</div>
|
<div class="list-wrap posR">
|
<div class="list pos-full">
|
<el-checkbox-group
|
:disabled="isBatch[devType]"
|
v-model="list.selectedList[devType]"
|
>
|
<el-checkbox
|
class="item"
|
v-for="item in list.resData[devType]"
|
:key="item.devId"
|
:disabled="!item.devOnline || !!item.state.isTesting"
|
:value="item.devId"
|
>{{ item.devIdcode }}</el-checkbox
|
>
|
</el-checkbox-group>
|
<!-- <div class="item" v-for="item in list" :key="item.name">
|
{{ item.name }}
|
</div> -->
|
</div>
|
</div>
|
<div class="btn-grp">
|
<el-button class="btn" :disabled="isBatch[devType]" @click="checkAll"
|
>全选</el-button
|
>
|
<el-button class="btn" :disabled="isBatch[devType]" @click="checkInvert"
|
>反选</el-button
|
>
|
<el-button class="btn" :disabled="isBatch[devType]" @click="clearAll"
|
>取消选择</el-button
|
>
|
<!-- <div class="btn" @click="updateList">更新至右侧</div> -->
|
</div>
|
</div>
|
<yc-card class="p-header">
|
<template #tools>
|
<template v-if="1 == devType">
|
<el-button
|
size="small"
|
v-if="canStopBatch[1]"
|
class="btn-start btn-grp0"
|
@click="stopBatch"
|
>结束批量</el-button
|
>
|
<el-button
|
size="small"
|
:disabled="!selectData[devType].length"
|
class="btn-start"
|
@click="test"
|
>启动测试</el-button
|
>
|
<el-button
|
size="small"
|
:disabled="!selectData[devType].length"
|
class="btn-start"
|
@click="stopTest"
|
>停止测试</el-button
|
>
|
</template>
|
<template v-else>
|
<el-button
|
size="small"
|
class="btn-start btn-grp1"
|
@click="setBattCount"
|
>设置组数</el-button
|
>
|
<el-button
|
size="small"
|
v-if="canStopBatch[2]"
|
class="btn-start btn-grp0"
|
@click="stopBatch"
|
>结束批量</el-button
|
>
|
<!-- 组1控制-->
|
<el-dropdown
|
class="control-group grp1"
|
type="primary"
|
trigger="click"
|
>
|
组1控制
|
<template #dropdown>
|
<el-dropdown-menu>
|
<el-dropdown-item @click="test(0)">启动组1</el-dropdown-item>
|
<el-dropdown-item @click="controlTest(0, 2)"
|
>暂停组1</el-dropdown-item
|
>
|
<el-dropdown-item @click="controlTest(0, 3)"
|
>继续组1</el-dropdown-item
|
>
|
<el-dropdown-item @click="controlTest(0, 4)"
|
>停止组1</el-dropdown-item
|
>
|
</el-dropdown-menu>
|
</template>
|
</el-dropdown>
|
<!-- <el-button
|
size="small"
|
:disabled="!selectData[devType].length"
|
class="btn-start btn-grp1"
|
@click="test(0)"
|
>启动组1</el-button
|
>
|
<el-button
|
size="small"
|
:disabled="!selectData[devType].length"
|
class="btn-start btn-grp1"
|
@click="test(0)"
|
>暂停组1</el-button
|
> -->
|
<!-- 组2控制 -->
|
<el-dropdown
|
class="control-group grp2"
|
type="primary"
|
trigger="click"
|
>
|
组2控制
|
<template #dropdown>
|
<el-dropdown-menu>
|
<el-dropdown-item @click="test(1)">启动组2</el-dropdown-item>
|
<el-dropdown-item @click="controlTest(1, 2)"
|
>暂停组2</el-dropdown-item
|
>
|
<el-dropdown-item @click="controlTest(1, 3)"
|
>继续组2</el-dropdown-item
|
>
|
<el-dropdown-item @click="controlTest(1, 4)"
|
>停止组2</el-dropdown-item
|
>
|
</el-dropdown-menu>
|
</template>
|
</el-dropdown>
|
<!-- <el-button
|
size="small"
|
:disabled="!selectData[devType].length"
|
class="btn-start btn-grp2"
|
@click="test(1)"
|
>启动组2</el-button
|
>
|
<el-button
|
size="small"
|
:disabled="!selectData[devType].length"
|
class="btn-start btn-grp2"
|
@click="test(1)"
|
>停止组2</el-button
|
> -->
|
</template>
|
</template>
|
<div class="card-content">
|
<div class="label">设备类型</div>
|
<div class="value">
|
{{ { 1: "充放电一体机", 2: "均衡测试仪" }[devType] }}
|
</div>
|
<div class="label">已选择设备总数量</div>
|
<div class="value">{{ selectData[devType].length }}</div>
|
<div class="label">批量测试状态</div>
|
<div class="value">未开始</div>
|
</div>
|
</yc-card>
|
<yc-card class="p-content">
|
<template v-if="selectData[devType].length">
|
<div class="list-scroller pos-full">
|
<dev-card
|
v-for="dev in selectData[devType]"
|
:key="dev.devId"
|
@click="goDetails(dev)"
|
:devIdcode="dev.devIdcode"
|
:onLine="!!dev.devOnline"
|
:devType="dev.devType"
|
></dev-card>
|
</div>
|
</template>
|
<div class="empty" v-else>请选择要批量测试的设备</div>
|
</yc-card>
|
<!-- 弹窗 -->
|
<el-dialog
|
title="设置测试参数"
|
v-model="testVisible"
|
:close-on-click-modal="false"
|
class="dialog-center"
|
width="700px"
|
center
|
>
|
<template v-if="1 == devType">
|
<param-content
|
v-model="testVisible"
|
v-if="testVisible"
|
:isBatch="true"
|
:devs="devs"
|
></param-content>
|
</template>
|
<template v-if="2 == devType">
|
<jh-param-content
|
v-model="testVisible"
|
v-if="testVisible"
|
:isBatch="true"
|
:grpIdx="testGroupIdx"
|
:devs="devs"
|
></jh-param-content>
|
</template>
|
</el-dialog>
|
<!-- 设置均衡仪组数 -->
|
<el-dialog
|
title="设置均衡仪电池组数"
|
v-model="jhyBattCountVisible"
|
:close-on-click-modal="false"
|
class="dialog-center"
|
width="600px"
|
center
|
>
|
<batt-count-content
|
v-model="jhyBattCountVisible"
|
v-if="jhyBattCountVisible"
|
:isBatch="true"
|
:devs="devs"
|
></batt-count-content>
|
</el-dialog>
|
</div>
|
</template>
|
|
<style scoped lang="less">
|
.page {
|
height: 100%;
|
padding: 8px;
|
display: grid;
|
grid-template-rows: 50px 1fr;
|
grid-template-columns: 340px 1fr;
|
gap: 12px;
|
|
.p-left {
|
grid-row-start: span 2;
|
background: #1a585d;
|
display: flex;
|
flex-direction: column;
|
.filter {
|
padding: 6px;
|
.key-word {
|
// margin: 6px;
|
}
|
:deep(.el-input__inner) {
|
background: transparent;
|
color: #fff;
|
&::placeholder {
|
color: #b0b7b4;
|
}
|
}
|
:deep(.el-input__wrapper) {
|
background-color: rgba(66, 244, 181, 0.1);
|
box-shadow: 0 0 0 1px #42f4b5 inset;
|
}
|
}
|
.tabs {
|
display: flex;
|
justify-content: center;
|
}
|
.btn-grp {
|
display: grid;
|
// grid-template-rows: 1fr 1fr;
|
grid-template-columns: 1fr 1fr 1fr;
|
justify-items: center;
|
gap: 6px;
|
padding: 6px;
|
.btn {
|
cursor: pointer;
|
background: #0ff;
|
border-radius: 6px;
|
border: 0 none;
|
color: #333;
|
width: 6em;
|
text-align: center;
|
font-weight: bold;
|
&.is-disabled,
|
&.is-disabled:hover {
|
background: #ccc;
|
cursor: not-allowed;
|
}
|
}
|
}
|
.list-wrap {
|
flex: 1;
|
margin: 6px;
|
.list {
|
border: 1px solid #0ff;
|
overflow-y: auto;
|
padding-left: 4em;
|
padding-top: 6px;
|
.item {
|
height: 38px;
|
display: flex;
|
align-items: center;
|
position: relative;
|
color: #0ff;
|
cursor: pointer;
|
&:hover {
|
background: rgba(100, 216, 216, 0.3);
|
}
|
&::before {
|
content: "";
|
position: absolute;
|
left: -2em;
|
top: 50%;
|
width: 1.8em;
|
border-top: 1px solid #0ff;
|
}
|
&::after {
|
content: "";
|
position: absolute;
|
top: 50%;
|
left: -2em;
|
|
height: 100%;
|
border-left: 1px solid #0ff;
|
}
|
&:last-of-type {
|
&::after {
|
content: none;
|
}
|
}
|
}
|
}
|
}
|
}
|
|
.p-header {
|
.btn-start {
|
cursor: pointer;
|
padding: 2px 12px;
|
margin-top: 8px;
|
border-radius: 6px;
|
background: #0ff;
|
color: #333;
|
font-size: 12px;
|
border: 0 none;
|
&.btn-grp0 {
|
background: rgb(231, 181, 0);
|
}
|
&.btn-grp1 {
|
background: rgb(0, 231, 231);
|
}
|
&.btn-grp2 {
|
background: rgb(0, 231, 112);
|
}
|
&.is-disabled,
|
&.is-disabled:hover {
|
background: #ccc;
|
cursor: not-allowed;
|
}
|
}
|
.card-content {
|
height: 100%;
|
// padding: 0 400px 0 20px;
|
padding: 0 320px 0 20px;
|
display: grid;
|
// grid-template-columns: repeat(3, 10em 1fr);
|
grid-template-columns: 5em 1fr 9em 1fr 8em 2fr;
|
place-content: center center;
|
place-items: center start;
|
font-size: 18px;
|
color: #0ff;
|
gap: 8px;
|
.label {
|
justify-self: end;
|
&::after {
|
content: ":";
|
}
|
}
|
}
|
}
|
.p-content {
|
position: relative;
|
overflow: hidden;
|
.list-scroller {
|
top: 8px;
|
bottom: 8px;
|
min-height: 0;
|
display: grid;
|
grid-template-columns: repeat(auto-fill, 230px);
|
overflow-y: auto;
|
gap: 24px;
|
// justify-content: center;
|
place-content: start center;
|
}
|
}
|
.empty {
|
height: 100%;
|
display: flex;
|
justify-content: center;
|
align-items: center;
|
font-size: 22px;
|
font-weight: bold;
|
color: #fff;
|
}
|
|
.control-group {
|
margin-top: 8px;
|
margin-right: 8px;
|
&.grp1 {
|
margin-left: 8px;
|
}
|
cursor: pointer;
|
& > :deep(span) {
|
color: #000;
|
display: inline-block;
|
background: #0ff;
|
padding: 4px 8px;
|
border-radius: 6px;
|
}
|
&.grp2 {
|
& > :deep(span) {
|
background: rgb(0, 231, 112);
|
}
|
}
|
}
|
}
|
</style>
|