gy-gateway/src/views/gateway/northboundtask.vue

620 lines
18 KiB
Vue

<template>
<div id="southdirection-box">
<div class="plat-config">
<h2>平台配置</h2>
<div class="btn-list">
<div class="btn-list-left">
<el-button type="primary" @click="addDeviceConfig">新增配置</el-button>
<!-- <el-button type="danger" @click="getDeviceConfig">删除</el-button>-->
</div>
<div class="btn-list-right">
<!-- <el-button type="primary" @click="getDeviceConfig">导出</el-button>-->
<!-- <el-button type="primary" @click="getDeviceConfig">导入</el-button>-->
<el-button type="primary" @click="getDeviceConfig">获取配置</el-button>
<el-button type="primary" @click="setDeviceConfig">设置配置</el-button>
</div>
</div>
<div class="table-box">
<el-table
ref="platConfigTableRef"
highlight-current-row
:data="platConfigList"
border
height="187"
:row-class-name="tableRowClassName"
:style="{ width: tabelBox + 'px', background: '#f2f2f2' }"
empty-text="配置为空"
>
<el-table-column type="index" label="序号" align="center" width="60" />
<el-table-column prop="PlatformIp" label="平台地址">
<template #default="scope">
<el-input v-model="scope.row.PlatformIp" placeholder="请输入平台地址" />
</template>
</el-table-column>
<el-table-column prop="type" label="上报格式">
<template #default="scope">
<el-select v-model="scope.row.type" placeholder="请选择上报格式">
<el-option v-for="item in uploadType" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</template>
</el-table-column>
<el-table-column prop="mqtt.user" label="用户名">
<template #default="scope">
<el-input v-model="scope.row.mqtt.user" placeholder="请输入用户名" />
</template>
</el-table-column>
<el-table-column prop="mqtt.passwd" label="密码">
<template #default="scope">
<el-input type="password" show-password v-model="scope.row.mqtt.passwd" placeholder="请输入密码" />
</template>
</el-table-column>
<el-table-column prop="mqtt.isUseSsl" label="ssl">
<template #default="scope">
<el-switch v-model="scope.row.mqtt.isUseSsl" />
</template>
</el-table-column>
<el-table-column prop="mqtt.isUseSslConf" label="ssl文件">
<template #default="scope">
<el-switch v-model="scope.row.mqtt.isUseSslConf" />
</template>
</el-table-column>
<el-table-column prop="pushConf.isUseResumeBrokenTransfer" label="断点续存">
<template #default="scope">
<el-switch v-model="scope.row.pushConf.isUseResumeBrokenTransfer" />
</template>
</el-table-column>
<el-table-column prop="tasks" label="任务ID">
<template #default="scope">
{{ scope.row.tasks ? scope.row.tasks.join() : '' }}
</template>
</el-table-column>
<el-table-column label="操作" width="140" align="center">
<template #default="scope">
<el-button link type="primary" size="small" @click="openCollectionModel(scope.row)">加解密配置</el-button>
<el-button link type="danger" size="small" @click="delDeviceConfig(scope.$index)">删除</el-button>
</template>
</el-table-column>
</el-table>
</div>
</div>
<div class="plat-config">
<h2>任务配置</h2>
<div class="table-box">
<el-table
ref="platConfigTableRef"
highlight-current-row
:data="taskList"
border
height="187"
:row-class-name="tableRowClassName"
@row-click="taskConfigClick"
:style="{ width: tabelBox + 'px', background: '#f2f2f2' }"
empty-text="配置为空"
>
<el-table-column type="index" label="序号" align="center" width="60" />
<el-table-column prop="taskId" label="任务ID" align="center">
<template #default="scope">
{{ scope.row.taskId }}
<!-- <el-input v-model="scope.row.taskId" placeholder="请输入任务ID" />-->
</template>
</el-table-column>
<el-table-column prop="uploadMode" label="上报策略">
<template #default="scope">
<el-autocomplete
v-model="scope.row.uploadMode"
:fetch-suggestions="querySearch"
clearable
class="inline-input w-50"
placeholder="请选择上报策略"
/>
</template>
</el-table-column>
</el-table>
</div>
</div>
<div class="data-config">
<h2>上报测点 {{ activeDeviceConfig.taskId }}</h2>
<div class="table-box">
<el-table
:data="activeDeviceConfig.dataIdEntire"
border
size="small"
height="100%"
ref="deviceDataTableRef"
:style="{ width: tabelBox + 'px' }"
empty-text="配置为空"
>
<el-table-column type="index" label="序号" align="center" width="60" fixed />
<el-table-column prop="equipId" label="设备ID" align="center" />
<el-table-column prop="idInfo[0].id" label="数据ID" align="center" />
<el-table-column prop="idInfo[0].uploadMode" label="上报策略" align="center" />
</el-table>
</div>
</div>
<el-dialog v-model="collectionModelShow" title="加解密配置" width="500" :before-close="handleClose">
<el-form ref="collectionRef" :model="collectionForm" label-width="auto" status-icon>
<h3>加密算法配置</h3>
<el-form-item label="启动">
<el-switch v-model="collectionForm.encrypt_1.enable" />
</el-form-item>
<el-row>
<el-col :span="12">
<el-form-item label="加密算法">
<el-select v-model="collectionForm.encrypt_1.algorithm" placeholder="选择加密算法">
<el-option label="AES" value="AES" />
<el-option label="DES" value="DES" />
<el-option label="SM4" value="SM4" />
<el-option label="RSA" value="RSA" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12" class="text-center">
<el-form-item label="加密key值">
<el-input v-model="collectionForm.encrypt_1.param.key" placeholder="请输入加密key值" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="加密模式">
<el-select v-model="collectionForm.encrypt_1.mode" placeholder="选择加密模式">
<el-option label="ECB" value="ECB" />
<el-option label="CBC" value="CBC" />
<el-option label="CTR" value="CTR" />
<el-option label="CFB" value="CFB" />
<el-option label="CFB1" value="CFB1" />
<el-option label="CFB8" value="CFB8" />
<el-option label="CFB128" value="CFB128" />
<el-option label="OFB" value="OFB" />
<el-option label="OFB128" value="OFB128" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12" class="text-center">
<el-form-item label="加密向量表">
<el-input v-model="collectionForm.encrypt_1.param.ivec" placeholder="请输入加密向量表" />
</el-form-item>
</el-col>
</el-row>
<el-form-item label="加密位数">
<el-select v-model="collectionForm.encrypt_1.bits" placeholder="选择加密位数">
<el-option label="128" value="128" />
<el-option label="192" value="192" />
<el-option label="256" value="256" />
</el-select>
</el-form-item>
<h3>解密算法配置</h3>
<el-form-item label="启动">
<el-switch v-model="collectionForm.decrypt_1.enable" />
</el-form-item>
<el-row>
<el-col :span="12">
<el-form-item label="加密算法">
<el-select v-model="collectionForm.decrypt_1.algorithm" placeholder="选择加密算法">
<el-option label="AES" value="AES" />
<el-option label="DES" value="DES" />
<el-option label="SM4" value="SM4" />
<el-option label="RSA" value="RSA" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12" class="text-center">
<el-form-item label="加密key值">
<el-input v-model="collectionForm.decrypt_1.param.key" placeholder="请输入加密key值" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="加密模式">
<el-select v-model="collectionForm.decrypt_1.mode" placeholder="选择加密模式">
<el-option label="ECB" value="ECB" />
<el-option label="CBC" value="CBC" />
<el-option label="CTR" value="CTR" />
<el-option label="CFB" value="CFB" />
<el-option label="CFB1" value="CFB1" />
<el-option label="CFB8" value="CFB8" />
<el-option label="CFB128" value="CFB128" />
<el-option label="OFB" value="OFB" />
<el-option label="OFB128" value="OFB128" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12" class="text-center">
<el-form-item label="加密向量表">
<el-input v-model="collectionForm.decrypt_1.param.ivec" placeholder="请输入加密向量表" />
</el-form-item>
</el-col>
</el-row>
<el-form-item label="加密位数">
<el-select v-model="collectionForm.decrypt_1.bits" placeholder="选择加密位数">
<el-option label="128" value="128" />
<el-option label="192" value="192" />
<el-option label="256" value="256" />
</el-select>
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="collectionModelShow = false">取消</el-button>
<el-button type="primary" @click="editCollection"> 确认 </el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script setup>
import { reactive, ref, onMounted, onUnmounted, computed, watch } from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus';
import { getPlatformConf, setPlatformConf } from '/@/api/gateway/northboundtask';
//上报策略
const uploadModeList = ref([
{ value: 'timer 10', link: 'timer 10' },
{ value: 'change 10', link: 'change 10' },
{ value: 'timer 10 || change 10', link: 'timer 10 || change 10' },
{ value: 'label LD200 up', link: 'label LD200 up' },
]);
const querySearch = (queryString, cb) => {
const results = queryString ? uploadModeList.value.filter(createFilter(queryString)) : uploadModeList.value;
// call callback function to return suggestions
cb(results);
};
const createFilter = (queryString) => {
return (restaurant) => {
return restaurant.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0;
};
};
//北向任务列表(后面换请求获取)
const taskList = ref([]);
const platConfigTableRef = ref();
const deviceDataTableRef = ref();
const tabelBox = ref(884);
const platConfigList = ref([]);
const uploadType = ref([
{ label: 'DT-MQTT-DEFAULT', value: 'DT-MQTT-DEFAULT' },
{ label: 'DT-MQTT-DEBUG', value: 'DT-MQTT-DEBUG' },
{ label: 'HN-MQTT-BJ', value: 'HN-MQTT-BJ' },
{ label: 'SC-MQTT-DEFAULT', value: 'SC-MQTT-DEFAULT' },
{ label: 'WG-MQTT-PuPu', value: 'WG-MQTT-PuPu' },
{ label: 'WG-MQTT-TengSheng', value: 'WG-MQTT-TengSheng' },
]);
//新增配置
const addDeviceConfig = () => {
let newDeviceConfig = {
PlatformIp: '',
tasks: ['T1', 'T2', 'T3', 'T4', 'T5'],
type: '',
mqtt: {
user: '',
passwd: '',
isUseSsl: false,
isUseSslConf: false,
sslConf: {
localCertificate_file: '/etc/custom/sslConf/pupu_core_3501000001.pem',
privateKey_file: '/etc/custom/sslConf/pupu_core_3501000001.prv',
},
},
pushConf: {
isRun: true,
isUseResumeBrokenTransfer: false,
broken: {
resume: { intervalTime_ms: 1000 },
filter: {
filter_s: 600,
relevanceTaskId: ['T1', 'T2', 'T3', 'T4', 'T5'],
},
},
},
encrypt_decrypt: {
encrypt_1: {
algorithm: 'AES',
param: {
mode: 'CBC',
key: '0123456789abcdef',
ivec: '0123456789abcdef',
bits: 128,
},
enable: false,
},
decrypt_1: {
algorithm: 'AES',
param: {
mode: 'CBC',
key: '0123456789abcdef',
ivec: '0123456789abcdef',
bits: 128,
},
enable: false,
},
},
};
console.log('platConfigList.value', platConfigTableRef.value);
platConfigList.value.push(newDeviceConfig);
};
//删除配置
const delDeviceConfig = (index) => {
console.log('当前点击的行号', index);
ElMessageBox.confirm('确认要删除该设备配置吗?', '告警', {
confirmButtonText: '确认',
cancelButtonText: '取消',
type: 'warning',
})
.then(() => {
platConfigList.value.splice(index, 1);
ElMessage({
type: 'success',
message: '删除成功',
});
})
.catch(() => {
ElMessage({
type: 'info',
message: '取消删除',
});
});
};
const getDeviceConfig = () => {
getPlatformConf({})
.then((response) => {
// 成功响应后的处理
console.log(response); // 打印响应数据
if (response.code == 0) {
//缓存上下行主题
platConfigList.value = response.data.PlatformPar || [];
taskList.value =
response.data.tasks.map((item) => {
if (item.dataIdEntire != []) {
let dataIdEntireList = [];
item.dataIdEntire.forEach((val) => {
val.idInfo.forEach((info) => {
dataIdEntireList.push({
equipId: val.equipId,
idInfo: [info],
});
});
});
item.dataIdEntire = dataIdEntireList;
}
return item;
}) || [];
// taskList.value = taskDataList;
console.log('格式化后数据', taskList.value);
if (!platConfigList.value.length) {
addDeviceConfig();
}
if (platConfigList.value.length) {
if (platConfigList.value.length > ActiveRowIndex.value) {
activeDeviceConfig.value = platConfigList.value[ActiveRowIndex.value];
} else {
activeDeviceConfig.value = platConfigList.value[0];
}
}
} else {
ElMessage.error(response.message);
}
})
.catch((error) => {
// 错误处理
console.error(error); // 打印错误信息
ElMessage.error(error);
});
};
const setDeviceConfig = () => {
console.log('提交配置', platConfigList.value);
setPlatformConf({ PlatformPar: platConfigList.value, tasks: taskList.value })
.then((response) => {
// 成功响应后的处理
console.log(response); // 打印响应数据
if (response.code == 0) {
ElMessage.success('保存成功');
} else {
ElMessage.error(response.message);
}
})
.catch((error) => {
// 错误处理
console.error(error); // 打印错误信息
ElMessage.error(error);
});
};
//当选中索引
const ActiveRowIndex = ref(0);
const collectionModelShow = ref(false);
const collectionRef = ref();
const collectionForm = ref({
// 加密配置
encrypt_1: {
// 加密算法
algorithm: 'AES',
// 加密参数
param: {
mode: 'CBC',
key: '0123456789abcdef',
ivec: '0123456789abcdef',
bits: 128,
},
// 是否启用加密
enable: false,
},
// 解密配置
decrypt_1: {
// 解密算法
algorithm: 'AES',
// 解密参数
param: {
mode: 'CBC',
key: '0123456789abcdef',
ivec: '0123456789abcdef',
bits: 128,
},
// 是否启用解密
enable: false,
},
});
//打开采集配置弹窗
const openCollectionModel = (row) => {
console.log('当前采集', row);
collectionForm.value = {
encrypt_1: row.encrypt_decrypt.encrypt_1,
decrypt_1: row.encrypt_decrypt.decrypt_1,
};
collectionModelShow.value = true;
};
const editCollection = () => {
platConfigList.value[ActiveRowIndex.value].encrypt_decrypt.encrypt_1 = collectionForm.value.encrypt_1;
platConfigList.value[ActiveRowIndex.value].encrypt_decrypt.decrypt_1 = collectionForm.value.decrypt_1;
collectionModelShow.value = false;
};
const activeDeviceConfig = ref({
PlatformIp: '',
tasks: ['T1', 'T2', 'T3', 'T4', 'T5'],
type: '',
mqtt: {
user: '',
passwd: '',
isUseSsl: false,
isUseSslConf: false,
sslConf: {
localCertificate_file: '/etc/custom/sslConf/pupu_core_3501000001.pem',
privateKey_file: '/etc/custom/sslConf/pupu_core_3501000001.prv',
},
},
pushConf: {
isRun: true,
isUseResumeBrokenTransfer: false,
broken: {
resume: { intervalTime_ms: 1000 },
filter: {
filter_s: 600,
relevanceTaskId: ['T1', 'T2', 'T3', 'T4', 'T5'],
},
},
},
encrypt_decrypt: {
encrypt_1: {
algorithm: 'AES',
param: {
mode: 'CBC',
key: '0123456789abcdef',
ivec: '0123456789abcdef',
bits: 128,
},
enable: false,
},
decrypt_1: {
algorithm: 'AES',
param: {
mode: 'CBC',
key: '0123456789abcdef',
ivec: '0123456789abcdef',
bits: 128,
},
enable: false,
},
},
});
watch(
() => ({ ...activeDeviceConfig.value }),
(newVal) => {
console.log('数据变化', newVal);
platConfigList.value[ActiveRowIndex.value] = newVal;
},
{ deep: true }
);
// const saveDeviceDataConfig = () => {
// platConfigList.value[ActiveRowIndex.value] = activeDeviceConfig.value;
// }
const tableRowClassName = ({ row, rowIndex }) => {
if (rowIndex === ActiveRowIndex.value) {
return 'selected-row';
}
return '';
};
//选择设备配置
const taskConfigClick = (e) => {
console.log(`current page:`, e);
activeDeviceConfig.value = e;
platConfigTableRef.value.toggleRowSelection(e);
ActiveRowIndex.value = platConfigList.value.indexOf(e);
// e.isDoubleClicked = !e.isDoubleClicked;
};
//更新表格宽度
const handleResize = () => {
deviceDataTableRef.value.doLayout();
tabelBox.value = window.innerWidth - 180 - 10;
};
onMounted(() => {
window.addEventListener('resize', handleResize);
getDeviceConfig();
handleResize();
// if(platConfigList.value[0]){
// activeDeviceConfig.value = platConfigList.value[0];
// platConfigTableRef.value.toggleRowSelection(platConfigList.value[0]);
// ActiveRowIndex.value = 0;
// }
});
onUnmounted(() => {
window.removeEventListener('resize', handleResize);
});
</script>
<style scoped lang="scss">
.el-table .double-clicked-row {
background-color: #f0f9eb;
}
:deep(.el-table .el-scrollbar) {
background: #fff;
}
#southdirection-box {
position: absolute;
width: 100%;
height: 100%;
.btn-list {
display: flex;
align-items: center;
justify-content: space-between;
padding: 10px 0;
}
.plat-config {
position: relative;
overflow-y: auto;
}
.data-config {
position: relative;
height: calc(100% - 278px - 226px);
.table-box {
position: absolute;
width: 100%;
height: calc(100% - 120px);
}
}
.table-box {
//position: absolute;
//width: 100%;
}
}
</style>
<style>
.selected-row {
background-color: #55e800;
}
</style>