ээээ
This commit is contained in:
parent
87bbd2844c
commit
0d0cec1f9f
3 changed files with 56 additions and 24 deletions
|
|
@ -4,6 +4,7 @@ import {
|
|||
DeleteOutlined,
|
||||
EditOutlined,
|
||||
EyeOutlined,
|
||||
LinkOutlined,
|
||||
} from '@ant-design/icons'
|
||||
import {
|
||||
Badge,
|
||||
|
|
@ -29,6 +30,7 @@ import { useState } from 'react'
|
|||
import { useNavigate, useParams } from 'react-router-dom'
|
||||
import { useAlerts, useAcknowledgeAlert, useResolveAlert, type AlertItem } from '../api/alerts'
|
||||
import { useDevice, useDeleteDevice, useObject } from '../api/objects'
|
||||
import { getDeviceWebUrl } from '../utils/deviceUrl'
|
||||
import { useSnapshots, useSnapshotDiff } from '../api/snapshots'
|
||||
import { useDeviceTasks, useTask, type Task } from '../api/tasks'
|
||||
import { DeviceEditModal } from '../components/DeviceEditModal'
|
||||
|
|
@ -397,6 +399,7 @@ export function DeviceDetailPage() {
|
|||
|
||||
const effectiveStatus = liveStatus?.status ?? device?.status ?? 'unknown'
|
||||
const effectivePing = liveStatus !== null ? liveStatus.ping_ms : (device?.last_ping_ms ?? null)
|
||||
const webUrl = device ? getDeviceWebUrl(device) : null
|
||||
|
||||
const handleDelete = async () => {
|
||||
try {
|
||||
|
|
@ -581,6 +584,18 @@ export function DeviceDetailPage() {
|
|||
</Col>
|
||||
<Col>
|
||||
<Space>
|
||||
{webUrl && (
|
||||
<Tooltip title={webUrl}>
|
||||
<Button
|
||||
icon={<LinkOutlined />}
|
||||
href={webUrl}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
Веб-интерфейс
|
||||
</Button>
|
||||
</Tooltip>
|
||||
)}
|
||||
<Button icon={<EditOutlined />} onClick={() => setEditOpen(true)}>
|
||||
Редактировать
|
||||
</Button>
|
||||
|
|
|
|||
|
|
@ -56,34 +56,11 @@ import { CategoryTag, DeviceStatusBadge } from '../components/StatusBadge'
|
|||
import { DeviceEditModal } from '../components/DeviceEditModal'
|
||||
import { DiscoveryDrawer } from '../components/DiscoveryDrawer'
|
||||
import { stripEmpty } from '../utils/form'
|
||||
import { getDeviceWebUrl } from '../utils/deviceUrl'
|
||||
import dayjs from 'dayjs'
|
||||
|
||||
const SERVER_CATEGORIES = new Set(['main_server', 'vm', 'router'])
|
||||
|
||||
/** Возвращает URL веб-интерфейса устройства или null, если ссылка не применима. */
|
||||
function getDeviceWebUrl(device: DeviceRow): string | null {
|
||||
const hostname = (device.hostname ?? '').toLowerCase()
|
||||
|
||||
// Proxmox — определяем по hostname
|
||||
if (hostname.includes('proxmox') || hostname.includes('pve')) {
|
||||
return `http://${device.ip}:8006`
|
||||
}
|
||||
|
||||
// RTSP-прокси (go2rtc/mediamtx) — определяем по capabilities
|
||||
if (device.capabilities?.includes('rtsp')) {
|
||||
return `http://${device.ip}:1984`
|
||||
}
|
||||
|
||||
switch (device.category) {
|
||||
case 'main_server': return `http://${device.ip}:80`
|
||||
case 'router': return `http://${device.ip}:80` // MikroTik WebFig
|
||||
case 'embedded': return `http://${device.ip}:5000`
|
||||
case 'camera': return `http://${device.ip}:80`
|
||||
// vm без proxmox/pve в hostname — asterisk, db и прочие, ссылка не нужна
|
||||
default: return null
|
||||
}
|
||||
}
|
||||
|
||||
const rackLabel = (name: string, type: string | null | undefined): string =>
|
||||
type ? `${name} ${type}` : name
|
||||
const DEVICE_COL_SPAN = 8
|
||||
|
|
|
|||
40
frontend/src/utils/deviceUrl.ts
Normal file
40
frontend/src/utils/deviceUrl.ts
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
import type { DeviceItem } from '../api/objects'
|
||||
|
||||
/**
|
||||
* Возвращает URL веб-интерфейса устройства или null, если ссылка не применима.
|
||||
*
|
||||
* Приоритет проверок:
|
||||
* 1. Proxmox — hostname содержит «proxmox» или «pve» → :8006
|
||||
* 2. RTSP-прокси (go2rtc/mediamtx) — capabilities содержит «rtsp»
|
||||
* ИЛИ device_meta.cls === «rtsp_server»
|
||||
* ИЛИ device_meta.plugin содержит «rtsp» → :1984
|
||||
* 3. Категория: main_server/:80, router (WebFig)/:80, embedded/:5000, camera/:80
|
||||
* 4. vm без proxmox/pve, io_board, bank_terminal, cash_register, other → null
|
||||
*/
|
||||
export function getDeviceWebUrl(device: DeviceItem): string | null {
|
||||
const hostname = (device.hostname ?? '').toLowerCase()
|
||||
const metaCls = String(device.device_meta?.cls ?? '').toLowerCase()
|
||||
const metaPlugin = String(device.device_meta?.plugin ?? '').toLowerCase()
|
||||
|
||||
// Proxmox
|
||||
if (hostname.includes('proxmox') || hostname.includes('pve')) {
|
||||
return `http://${device.ip}:8006`
|
||||
}
|
||||
|
||||
// RTSP-прокси (go2rtc / mediamtx)
|
||||
if (
|
||||
device.capabilities?.includes('rtsp') ||
|
||||
metaCls === 'rtsp_server' ||
|
||||
metaPlugin.includes('rtsp')
|
||||
) {
|
||||
return `http://${device.ip}:1984`
|
||||
}
|
||||
|
||||
switch (device.category) {
|
||||
case 'main_server': return `http://${device.ip}:80`
|
||||
case 'router': return `http://${device.ip}:80` // MikroTik WebFig
|
||||
case 'embedded': return `http://${device.ip}:5000`
|
||||
case 'camera': return `http://${device.ip}:80`
|
||||
default: return null
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue