2 changed files with 36 additions and 22 deletions
+14 -12
View File
@@ -95,18 +95,20 @@ database:
path: ${DATA_DIR}/${SERVICE_NAME}.db path: ${DATA_DIR}/${SERVICE_NAME}.db
mysql: mysql:
dsn: "" dsn: ""
web: web:
enabled: true enabled: true
host: 0.0.0.0 port_enabled: true
port: 8080 socket_enabled: true
socket_path: ${SOCKET_PATH} host: 0.0.0.0
static_dir: ${INSTALL_DIR}/dist port: 8080
admin: socket_path: ${SOCKET_PATH}
username: admin static_dir: ${INSTALL_DIR}/dist
password: ${ADMIN_PASSWORD} admin:
session_secret: "" username: admin
# 前端经 HTTPS(nginx 反代)访问时保持 true;纯 HTTP 部署需改回 false password: ${ADMIN_PASSWORD}
session_secure: true session_secret: ""
# 前端经 HTTPS(nginx 反代)访问时保持 true;纯 HTTP 部署需改回 false
session_secure: true
console_log: console_log:
web: true web: true
mqtt: true mqtt: true
+22 -10
View File
@@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue' import { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue'
import { adminLogout, createNodeBlockingRule, deleteNode, deleteTextMessage, getAdminMe, getChannels, getHealth, getMapReportViewport, getNodeInfo, getPositions, getTextMessages, purgeNode } from './api' import { adminLogout, createNodeBlockingRule, deleteNode, deleteTextMessage, getAdminMe, getChannels, getHealth, getMapReportViewport, getMapReports, getNodeInfo, getPositions, getTextMessages, purgeNode } from './api'
import AdminBlockingManagement from './components/AdminBlockingManagement.vue' import AdminBlockingManagement from './components/AdminBlockingManagement.vue'
import AdminBot from './components/AdminBot.vue' import AdminBot from './components/AdminBot.vue'
import AdminBotDirect from './components/AdminBotDirect.vue' import AdminBotDirect from './components/AdminBotDirect.vue'
@@ -476,20 +476,32 @@ function requestPurgeNode(nodeId: string) {
pendingDeleteAction.value = { kind: 'purge-node', nodeId } pendingDeleteAction.value = { kind: 'purge-node', nodeId }
} }
function requestDeleteDisplayedNodes() { async function requestDeleteDisplayedNodes() {
// 收集当前地图上正在显示的节点 ID(仅 type=node,跳过聚合点),并按筛选后的视图顺序去重。 // 收集当前地图上正在显示的节点 ID(仅 type=node,跳过聚合点),并按筛选后的视图顺序去重。
const nodeIds = Array.from( const nodeIds = new Set(
new Set( mapItems.value
mapItems.value .filter((item): item is Extract<MapRenderable, { type: 'node' }> => item.type === 'node')
.filter((item): item is Extract<MapRenderable, { type: 'node' }> => item.type === 'node') .map((item) => item.node_id),
.map((item) => item.node_id),
),
) )
if (nodeIds.length === 0) { // 聚合状态下视口接口只返回聚合点(无 node_id),改按当前视野 bounds 分页拉取全部节点 ID。
if (mapViewportMode.value === 'clusters' && currentMapBounds.value) {
const pageSize = 500
for (let offset = 0; ; offset += pageSize) {
const response = await getMapReports(pageSize, offset, currentMapBounds.value)
for (const report of response.items) {
nodeIds.add(report.node_id)
}
const loaded = offset + response.items.length
if (response.items.length === 0 || loaded >= (response.total ?? loaded)) {
break
}
}
}
if (nodeIds.size === 0) {
error.value = '当前地图上没有可删除的节点。' error.value = '当前地图上没有可删除的节点。'
return return
} }
pendingDeleteAction.value = { kind: 'delete-displayed-nodes', nodeIds } pendingDeleteAction.value = { kind: 'delete-displayed-nodes', nodeIds: Array.from(nodeIds) }
} }
function requestDeleteAndBlockNode(payload: NodeActionRequest) { function requestDeleteAndBlockNode(payload: NodeActionRequest) {