hy-app-monitor/static/index.html
2026-04-22 00:07:30 +08:00

108 lines
4.2 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>HY App Monitor</title>
<link rel="stylesheet" href="/app.css" />
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
<script defer src="/app.js"></script>
</head>
<body>
<div id="app" v-cloak class="shell">
<header class="hero">
<div class="hero-copy">
<p class="eyebrow">HY / Deploy Monitor</p>
<h1>内网服务实时巡检面板</h1>
<p class="hero-text">
页面本身不直接请求内网服务。所有探测都由 deploy 机器代发,适合直接通过公网 6666 访问。
</p>
</div>
<div class="hero-side">
<div class="stat-block">
<span>总服务数</span>
<strong>{{ summary.total }}</strong>
</div>
<div class="stat-block ok">
<span>正常</span>
<strong>{{ summary.ok }}</strong>
</div>
<div class="stat-block bad">
<span>异常</span>
<strong>{{ summary.down }}</strong>
</div>
</div>
</header>
<section class="toolbar">
<div class="toolbar-left">
<button :class="['filter-chip', filter === 'all' ? 'active' : '']" @click="filter = 'all'">全部</button>
<button :class="['filter-chip', filter === 'down' ? 'active' : '']" @click="filter = 'down'">只看异常</button>
<button :class="['filter-chip', filter === 'java' ? 'active' : '']" @click="filter = 'java'">Java</button>
<button :class="['filter-chip', filter === 'golang' ? 'active' : '']" @click="filter = 'golang'">Golang</button>
</div>
<div class="toolbar-right">
<input v-model.trim="keyword" class="search" placeholder="搜索主机 / 服务 / IP" />
<button class="refresh" @click="refresh" :disabled="loading">{{ loading ? '刷新中...' : '立即刷新' }}</button>
</div>
</section>
<section class="meta-strip">
<span>最后刷新:{{ formattedUpdatedAt }}</span>
<span v-if="error" class="bad-text">加载失败:{{ error }}</span>
<span v-else>自动刷新10 秒</span>
</section>
<section class="hosts">
<article v-for="group in groupedHosts" :key="group.host" class="host-panel">
<header class="host-header">
<div>
<h2>{{ group.host }}</h2>
<p>{{ group.ip }} · {{ group.groupLabel }}</p>
</div>
<div class="host-badges">
<span class="badge neutral">{{ group.items.length }} 项</span>
<span :class="['badge', group.downCount > 0 ? 'bad' : 'ok']">
{{ group.downCount > 0 ? `${group.downCount} 异常` : '全部正常' }}
</span>
</div>
</header>
<div class="service-grid">
<div v-for="item in group.items" :key="item.host + '-' + item.service" class="service-card">
<div class="service-top">
<div>
<div class="service-name">{{ item.service }}</div>
<div class="service-kind">{{ item.kind }}</div>
</div>
<div :class="['status-pill', item.ok ? 'ok' : 'bad']">
<span class="dot"></span>
{{ item.ok ? 'UP' : 'DOWN' }}
</div>
</div>
<div class="service-data">
<div>
<small>HTTP</small>
<strong>{{ item.statusCode || '-' }}</strong>
</div>
<div>
<small>耗时</small>
<strong>{{ item.latencyMs }}ms</strong>
</div>
<div>
<small>端口</small>
<strong>{{ item.port }}</strong>
</div>
</div>
<div class="service-url">{{ item.url }}</div>
<div class="service-detail">{{ item.detail || '无返回内容' }}</div>
</div>
</div>
</article>
</section>
</div>
</body>
</html>