批量删除节点,一键屏蔽ip

This commit is contained in:
2026-06-19 20:37:19 +08:00
parent b56cfb7b1e
commit 2afd890de4
6 changed files with 328 additions and 1 deletions
+52
View File
@@ -76,6 +76,7 @@ type PendingDeleteAction =
| { kind: 'delete-message'; message: DeletableTextMessage }
| { kind: 'delete-node'; nodeId: string }
| { kind: 'purge-node'; nodeId: string }
| { kind: 'delete-displayed-nodes'; nodeIds: string[] }
| ({ kind: 'delete-and-block-node' } & NodeActionRequest)
let refreshTimer: number | undefined
let mapBoundsTimer: number | undefined
@@ -206,6 +207,9 @@ const deleteModalTitle = computed(() => {
if (action.kind === 'purge-node') {
return '确认删除节点'
}
if (action.kind === 'delete-displayed-nodes') {
return '确认删除所有显示的节点'
}
return '确认删除并屏蔽节点'
})
@@ -226,6 +230,9 @@ const deleteModalMessage = computed(() => {
if (action.kind === 'purge-node') {
return '确定要删除这个节点吗?将同时清理该节点的聊天消息和位置/遥测/路由/路径追踪等数据包记录,此操作不可撤销。'
}
if (action.kind === 'delete-displayed-nodes') {
return `确定要删除当前地图上显示的全部 ${action.nodeIds.length} 个节点吗?将逐个调用删除接口,此操作不可撤销。`
}
if (!action.message) {
return '确定要删除并屏蔽这个节点吗?请输入屏蔽原因。'
}
@@ -453,6 +460,22 @@ function requestPurgeNode(nodeId: string) {
pendingDeleteAction.value = { kind: 'purge-node', nodeId }
}
function requestDeleteDisplayedNodes() {
// 收集当前地图上正在显示的节点 ID(仅 type=node,跳过聚合点),并按筛选后的视图顺序去重。
const nodeIds = Array.from(
new Set(
mapItems.value
.filter((item): item is Extract<MapRenderable, { type: 'node' }> => item.type === 'node')
.map((item) => item.node_id),
),
)
if (nodeIds.length === 0) {
error.value = '当前地图上没有可删除的节点。'
return
}
pendingDeleteAction.value = { kind: 'delete-displayed-nodes', nodeIds }
}
function requestDeleteAndBlockNode(payload: NodeActionRequest) {
pendingDeleteAction.value = { kind: 'delete-and-block-node', ...payload }
}
@@ -483,6 +506,11 @@ async function confirmDeleteModal(payload: { reason?: string }) {
return
}
if (action.kind === 'delete-displayed-nodes') {
await deleteDisplayedNodes(action.nodeIds)
return
}
const reason = payload.reason?.trim()
if (!reason) {
return
@@ -571,6 +599,29 @@ async function purgeNodeById(nodeId: string) {
}
}
// 逐个调用 deleteNode 串行删除当前地图上显示的节点;某一个失败不阻断后续,最后汇总错误。
async function deleteDisplayedNodes(nodeIds: string[]) {
const failures: string[] = []
let lastErrorMessage = ''
for (const nodeId of nodeIds) {
try {
await deleteNode(nodeId)
await removeNodeFromLocalState(nodeId)
} catch (err) {
if (isNodeNotFoundError(err)) {
// 已经不在了,本地状态也同步移除即可
await removeNodeFromLocalState(nodeId)
continue
}
failures.push(nodeId)
lastErrorMessage = err instanceof Error ? err.message : String(err)
}
}
if (failures.length > 0) {
error.value = `部分节点删除失败(${failures.length}/${nodeIds.length}):${lastErrorMessage}`
}
}
async function deleteAndBlockNode(payload: NodeActionPayload) {
try {
if (payload.message) {
@@ -765,6 +816,7 @@ onBeforeUnmount(() => {
@clear-node="clearSelectedNode"
@delete-node="requestDeleteNode"
@purge-node="requestPurgeNode"
@delete-displayed-nodes="requestDeleteDisplayedNodes"
@delete-and-block-node="requestDeleteAndBlockNode"
/>
</section>