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

124 lines
5.3 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 defer src="/vue.js"></script>
<script defer src="/app.js"></script>
</head>
<body>
<div id="boot-indicator" class="boot-indicator">
<strong>HY App Monitor</strong>
<span>正在加载页面资源,请稍候。</span>
</div>
<noscript>
<div class="boot-indicator noscript-indicator">
<strong>浏览器已禁用 JavaScript</strong>
<span>当前页面依赖脚本渲染,请启用 JavaScript 后再访问。</span>
</div>
</noscript>
<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>