修改补召

This commit is contained in:
guanj
2026-06-16 09:56:38 +08:00
parent 56b8158f4a
commit d85dba8bf8
2 changed files with 103 additions and 90 deletions

View File

@@ -8,10 +8,7 @@
name="el-icon-BellFilled" name="el-icon-BellFilled"
size="18" size="18"
/> />
<span <span class="nav-menu-text" v-if="globalPopUpRef?.eventList?.length > 0">
class="nav-menu-text"
v-if="globalPopUpRef?.eventList?.length > 0"
>
{{ globalPopUpRef.eventList.length > 99 ? '99+' : globalPopUpRef.eventList.length }} {{ globalPopUpRef.eventList.length > 99 ? '99+' : globalPopUpRef.eventList.length }}
</span> </span>
</div> </div>
@@ -49,7 +46,7 @@ import { logout } from '@/api/user-boot/user'
import Config from './config.vue' import Config from './config.vue'
import PopupPwd from './popup/password.vue' import PopupPwd from './popup/password.vue'
import AdminInfo from './popup/adminInfo.vue' import AdminInfo from './popup/adminInfo.vue'
const { replace } = useRouter()
// 环境标识 // 环境标识
const IS_LNQR = import.meta.env.VITE_NAME === 'LNqr' const IS_LNQR = import.meta.env.VITE_NAME === 'LNqr'
@@ -64,7 +61,7 @@ const globalPopUpRef = ref()
// 状态 // 状态
const state = reactive({ const state = reactive({
currentNavMenu: '', currentNavMenu: ''
}) })
// 打开暂降事件 // 打开暂降事件
@@ -106,7 +103,7 @@ const handleLogout = async () => {
redirectToCasLogout() redirectToCasLogout()
} else { } else {
// 普通环境直接跳登录页 // 普通环境直接跳登录页
window.location.href = '/login' replace('/login')
} }
} }
} }
@@ -122,12 +119,6 @@ const clearLocalData = () => {
// 清空标签页 // 清空标签页
navTabs.closeTabs() navTabs.closeTabs()
// 清 Cookie
document.cookie.split(';').forEach(cookie => {
const name = cookie.split('=')[0].trim()
document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;`
})
console.log('✅ 本地数据已全部清空') console.log('✅ 本地数据已全部清空')
} }
@@ -136,6 +127,11 @@ const redirectToCasLogout = () => {
const casLogoutUrl = const casLogoutUrl =
'http://privilege-epri.dcloud.ln.dc.sgcc.com.cn/cas/logout?service=http://privilege-epri.dcloud.ln.dc.sgcc.com.cn/cas/login?service=http://PQMonitoring.dcloud.ln.dc.sgcc.com.cn' 'http://privilege-epri.dcloud.ln.dc.sgcc.com.cn/cas/logout?service=http://privilege-epri.dcloud.ln.dc.sgcc.com.cn/cas/login?service=http://PQMonitoring.dcloud.ln.dc.sgcc.com.cn'
window.location.href = casLogoutUrl window.location.href = casLogoutUrl
// 清 Cookie
document.cookie.split(';').forEach(cookie => {
const name = cookie.split('=')[0].trim()
document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;`
})
} }
</script> </script>
@@ -216,8 +212,14 @@ const redirectToCasLogout = () => {
} }
@keyframes twinkle { @keyframes twinkle {
0% { transform: scale(0); } 0% {
80% { transform: scale(1.2); } transform: scale(0);
100% { transform: scale(1); } }
80% {
transform: scale(1.2);
}
100% {
transform: scale(1);
}
} }
</style> </style>

View File

@@ -56,15 +56,16 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="通讯状态"> <el-form-item label="通讯状态">
<el-select v-model="tableStore.table.params.comFlagStatus" clearable placeholder="请选择通讯状态" <el-select v-model="tableStore.table.params.comFlagStatus" clearable placeholder="请选择通讯状态"
style="width: 100%" > style="width: 100%">
<el-option label="正常" value="1" /> <el-option label="正常" value="1" />
<el-option label="中断" value="0" /> <el-option label="中断" value="0" />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="筛选数据"> <el-form-item label="筛选数据">
<el-input v-model="tableStore.table.params.searchValue" clearable placeholder="请输入关键字"></el-input> <el-input v-model="tableStore.table.params.searchValue" clearable
placeholder="请输入关键字"></el-input>
</el-form-item> </el-form-item>
</template> </template>
<template #operation> <template #operation>
@@ -86,9 +87,10 @@
</div> </div>
<el-dialog v-model="timePopUp" draggable title="补招" width="500"> <el-dialog v-model="timePopUp" draggable title="补招" width="500">
补招时间: 补招时间:
<el-date-picker v-model="timeData" type="datetimerange" format="YYYY-MM-DD HH:mm:00" <el-date-picker v-model="timeData" type="datetimerange" format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:00" range-separator="" date-format="YYYY-MM-DD" time-format="HH:mm:00" value-format="YYYY-MM-DD HH:mm:ss" range-separator="" date-format="YYYY-MM-DD" time-format="HH:mm:ss"
start-placeholder="开始日期" end-placeholder="结束日期" style="width: 400px" :disabledDate="disabledDate" /> start-placeholder="开始日期" end-placeholder="结束日期" style="width: 400px" :disabledDate="disabledDate"
:default-time="defaultTimeRange" />
<template #footer> <template #footer>
<div class="dialog-footer"> <div class="dialog-footer">
<el-button @click="timePopUp = false">取消</el-button> <el-button @click="timePopUp = false">取消</el-button>
@@ -148,6 +150,10 @@ const classificationData = dictData.getBasicData('Statistical_Type', ['Report_Ty
const treeData = ref([]) const treeData = ref([])
const idArr = ref([]) const idArr = ref([])
const timeData = ref([]) const timeData = ref([])
const defaultTimeRange: [Date, Date] = [
new Date(2000, 0, 1, 0, 0, 0),
new Date(2000, 0, 1, 23, 59, 59)
]
const logList: any = ref([]) const logList: any = ref([])
const activeName = ref(0) const activeName = ref(0)
const getTreeData = async () => { const getTreeData = async () => {
@@ -207,7 +213,7 @@ const tableStore = new TableStore({
{ {
title: '网络参数', title: '网络参数',
field: 'ip', field: 'ip',
align: 'center',width:'120px', align: 'center', width: '120px',
formatter: function (row) { formatter: function (row) {
return row.cellValue ? row.cellValue : '/' return row.cellValue ? row.cellValue : '/'
} }
@@ -297,7 +303,7 @@ const tableStore = new TableStore({
// tableStore.table.params.searchEndTime = tableHeaderRef.value.datePickerRef.timeValue[1] // tableStore.table.params.searchEndTime = tableHeaderRef.value.datePickerRef.timeValue[1]
}, },
loadCallback: () => { loadCallback: () => {
tableStore.table.data = tree2List(filterTreeByKeyword( tableStore.table.data,tableStore.table.params.searchValue), Math.random() * 1000) tableStore.table.data = tree2List(filterTreeByKeyword(tableStore.table.data, tableStore.table.params.searchValue), Math.random() * 1000)
tableStore.table.column[0].title = formData.value.statisticalType.name tableStore.table.column[0].title = formData.value.statisticalType.name
chartsRef.value && chartsRef.value.getTableStoreParams(tableStore.table.params) chartsRef.value && chartsRef.value.getTableStoreParams(tableStore.table.params)
@@ -322,7 +328,7 @@ tableStore.table.params.statisticalType = []
tableStore.table.params.scale = [] tableStore.table.params.scale = []
tableStore.table.params.manufacturer = [] tableStore.table.params.manufacturer = []
tableStore.table.params.loadType = [] tableStore.table.params.loadType = []
tableStore.table.params.comFlagStatus='' tableStore.table.params.comFlagStatus = ''
provide('tableStore', tableStore) provide('tableStore', tableStore)
const tree2List = (list: any, id?: string) => { const tree2List = (list: any, id?: string) => {
//存储结果的数组 //存储结果的数组
@@ -363,65 +369,65 @@ const tree2List = (list: any, id?: string) => {
* @returns {Array} 筛选后的嵌套树形数据,保持原层级 * @returns {Array} 筛选后的嵌套树形数据,保持原层级
*/ */
function filterTreeByKeyword(treeData, keyword) { function filterTreeByKeyword(treeData, keyword) {
// 关键词为空,直接返回原树(深拷贝,避免修改原数据) // 关键词为空,直接返回原树(深拷贝,避免修改原数据)
if (!keyword || keyword.trim() === '') { if (!keyword || keyword.trim() === '') {
return JSON.parse(JSON.stringify(treeData)); return JSON.parse(JSON.stringify(treeData));
} }
const targetKey = keyword.trim(); const targetKey = keyword.trim();
// 存储需要保留的节点ID匹配节点+所有上级+所有下级) // 存储需要保留的节点ID匹配节点+所有上级+所有下级)
const keepIdSet = new Set(); const keepIdSet = new Set();
// 第一步递归遍历树形标记所有需要保留的节点ID // 第一步递归遍历树形标记所有需要保留的节点ID
const markKeepNodes = (node, parentNodes = []) => { const markKeepNodes = (node, parentNodes = []) => {
// 1. 若当前节点名称包含关键词,标记自身+所有上级+所有下级 // 1. 若当前节点名称包含关键词,标记自身+所有上级+所有下级
const isMatch = node.name && node.name.includes(targetKey); const isMatch = node.name && node.name.includes(targetKey);
if (isMatch) { if (isMatch) {
// 标记自身 // 标记自身
keepIdSet.add(node.id); keepIdSet.add(node.id);
// 标记所有上级父节点 // 标记所有上级父节点
parentNodes.forEach(pNode => keepIdSet.add(pNode.id)); parentNodes.forEach(pNode => keepIdSet.add(pNode.id));
// 标记所有下级子节点(递归) // 标记所有下级子节点(递归)
const markChildren = (childNode) => { const markChildren = (childNode) => {
keepIdSet.add(childNode.id); keepIdSet.add(childNode.id);
if (childNode.children && childNode.children.length) { if (childNode.children && childNode.children.length) {
childNode.children.forEach(markChildren); childNode.children.forEach(markChildren);
}
};
if (node.children && node.children.length) {
node.children.forEach(markChildren);
}
} }
};
if (node.children && node.children.length) {
node.children.forEach(markChildren);
}
}
// 2. 递归遍历子节点传递当前节点的上级链parentNodes + 当前节点) // 2. 递归遍历子节点传递当前节点的上级链parentNodes + 当前节点)
if (node.children && node.children.length) { if (node.children && node.children.length) {
node.children.forEach(child => markKeepNodes(child, [...parentNodes, node])); node.children.forEach(child => markKeepNodes(child, [...parentNodes, node]));
} }
}; };
// 遍历根节点,开始标记 // 遍历根节点,开始标记
treeData.forEach(rootNode => markKeepNodes(rootNode)); treeData.forEach(rootNode => markKeepNodes(rootNode));
// 第二步:递归重构树形,只保留标记过的节点,保持层级 // 第二步:递归重构树形,只保留标记过的节点,保持层级
const rebuildTree = (node) => { const rebuildTree = (node) => {
// 若当前节点无需保留直接返回null // 若当前节点无需保留直接返回null
if (!keepIdSet.has(node.id)) { if (!keepIdSet.has(node.id)) {
return null; return null;
} }
// 深拷贝当前节点,避免修改原数据 // 深拷贝当前节点,避免修改原数据
const newNode = { ...node }; const newNode = { ...node };
// 递归处理子节点,过滤掉无需保留的,只保留有效子节点 // 递归处理子节点,过滤掉无需保留的,只保留有效子节点
if (newNode.children && newNode.children.length) { if (newNode.children && newNode.children.length) {
const newChildren = newNode.children.map(child => rebuildTree(child)).filter(Boolean); const newChildren = newNode.children.map(child => rebuildTree(child)).filter(Boolean);
newNode.children = newChildren; newNode.children = newChildren;
} else { } else {
newNode.children = []; newNode.children = [];
} }
return newNode; return newNode;
}; };
// 重构根节点过滤掉null的根节点 // 重构根节点过滤掉null的根节点
const filteredTree = treeData.map(rootNode => rebuildTree(rootNode)).filter(Boolean); const filteredTree = treeData.map(rootNode => rebuildTree(rootNode)).filter(Boolean);
return filteredTree; return filteredTree;
} }
@@ -478,24 +484,29 @@ const makeUpSubmit = () => {
reCallStartTime: timeData.value[0] reCallStartTime: timeData.value[0]
} }
socket(form) setTimeout(() => {
timePopUp.value = false socket(form)
logPopUp.value = true timePopUp.value = false
logPopUp.value = true
}, 500)
} }
const socket = async (form: any) => { const socket = async (form: any) => {
const url = (localStorage.getItem('WebSocketUrl2') || 'null')//'ws://192.168.1.67:10405/api/recell/') const url = (localStorage.getItem('WebSocketUrl2') || 'null')//'ws://192.168.1.68:10405/api/recell/'
logList.value = [] logList.value = []
await dataSocket.socketServe.connect(`${url}${adminInfo.id}`) await dataSocket.socketServe.connect(`${url}${adminInfo.id}`)
await dataSocket.socketServe.send(form) setTimeout(() => {
dataSocket.socketServe.send(form)
}, 500)
logList.value.push({ logList.value.push({
type: '', type: '',
time: formatDate(new Date(), 'YYYY-MM-DD HH:mm:ss'), time: formatDate(new Date(), 'YYYY-MM-DD HH:mm:ss'),
name: '开始补召,请稍等...', name: '开始补召,请稍等...',
}) })
await dataSocket.socketServe.registerCallBack('message', (res: any) => { await dataSocket.socketServe.registerCallBack('message', (res: any) => {
if (res.code == undefined) return
logList.value.push({ logList.value.push({
type: res.code == 500 ? 'error' : '', type: res.code == 500 ? 'error' : '',
time: formatDate(new Date(), 'YYYY-MM-DD HH:mm:ss'), time: formatDate(new Date(), 'YYYY-MM-DD HH:mm:ss'),
name: res.message name: res.message
}) })