You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

145 lines
10 KiB

import { defineComponent, ref, computed, useSSRContext } from 'vue';
import { ssrRenderAttrs, ssrInterpolate, ssrIncludeBooleanAttr, ssrLooseContain, ssrLooseEqual, ssrRenderAttr, ssrRenderList, ssrRenderClass, ssrRenderStyle } from 'vue/server-renderer';
import { u as useApi } from './useApi-B-E5eLsI.mjs';
import { u as useToast } from './useToast-CS21XT61.mjs';
import { h as healthLastRunText, S as STATUS_META, R as REGION_LABEL, p as parseCats, C as CAT_LABEL, P as PROBE_META, a as healthReason } from './svchealth-8zW8U1Ef.mjs';
import { _ as _export_sfc } from './server.mjs';
import './useLoading-D4zrSa2m.mjs';
import '../nitro/nitro.mjs';
import 'node:http';
import 'node:https';
import 'node:events';
import 'node:buffer';
import 'node:fs';
import 'node:path';
import 'node:crypto';
import 'node:url';
import '../routes/renderer.mjs';
import 'vue-bundle-renderer/runtime';
import 'unhead/server';
import 'devalue';
import 'unhead/utils';
import 'pinia';
import 'perfect-debounce';
const _sfc_main = /* @__PURE__ */ defineComponent({
__name: "svcinspect",
__ssrInlineRender: true,
setup(__props) {
useApi();
useToast();
const rows = ref([]);
const summary = ref({ total: 0, ok: 0, warn: 0, error: 0, skip: 0 });
const lastRun = ref(0);
const busy = ref(false);
const filterStatus = ref("");
const keyword = ref("");
const lastRunText = computed(() => healthLastRunText(lastRun.value));
const summaryCards = computed(() => [
{ key: "error", label: "不可用", value: summary.value.error, ico: "🚨", color: "#be123c", bg: "#ffe4e6" },
{ key: "warn", label: "有隐患", value: summary.value.warn, ico: "⚠️", color: "#b45309", bg: "#fef3c7" },
{ key: "ok", label: "正常", value: summary.value.ok, ico: "✅", color: "#047857", bg: "#d1fae5" },
{ key: "skip", label: "已停用", value: summary.value.skip, ico: "⏸️", color: "#64748b", bg: "#f1f5f9" },
{ key: "", label: "巡检配置总数", value: summary.value.total, ico: "📋", color: "#334155", bg: "#e2e8f0" }
]);
const filtered = computed(() => {
const kw = keyword.value.trim().toLowerCase();
return rows.value.filter((h) => {
if (filterStatus.value && h.status !== filterStatus.value) return false;
if (!kw) return true;
return `${h.name} ${h.svc_id} ${h.provider} ${h.app_name}`.toLowerCase().includes(kw);
});
});
function meta(s) {
return STATUS_META[s] || STATUS_META.skip;
}
function probeMeta(k) {
return PROBE_META[k] || PROBE_META.none;
}
function regionLabel(r) {
return REGION_LABEL[r] || `区域 ${r}`;
}
function catLabel(c) {
return CAT_LABEL[c] || `类别 ${c}`;
}
function cats(s) {
return parseCats(s);
}
function reason(h) {
return healthReason(h);
}
function timeText(ms) {
return healthLastRunText(ms);
}
function issuesOf(h) {
const all = (h.config_issues || []).map((s) => s.replace("[致命] ", ""));
const shown = reason(h);
return all.filter((s) => s !== shown && !shown.includes(s));
}
return (_ctx, _push, _parent, _attrs) => {
_push(`<div${ssrRenderAttrs(_attrs)} data-v-a9764f3a><div class="panel p-4 mb-5" data-v-a9764f3a><div class="flex flex-wrap items-center gap-3" data-v-a9764f3a><div class="flex items-center gap-2 mr-2" data-v-a9764f3a><h2 class="text-base font-bold text-slate-800" data-v-a9764f3a>服务巡检</h2><span class="text-xs text-slate-400" data-v-a9764f3a> 定时校验第三方服务配置并探测可用性 · 最近巡检 ${ssrInterpolate(lastRunText.value)}</span></div><div class="ml-auto flex items-center gap-2" data-v-a9764f3a><select class="select select-bordered select-sm w-32" data-v-a9764f3a><option value="" data-v-a9764f3a${ssrIncludeBooleanAttr(Array.isArray(filterStatus.value) ? ssrLooseContain(filterStatus.value, "") : ssrLooseEqual(filterStatus.value, "")) ? " selected" : ""}>全部状态</option><option value="error" data-v-a9764f3a${ssrIncludeBooleanAttr(Array.isArray(filterStatus.value) ? ssrLooseContain(filterStatus.value, "error") : ssrLooseEqual(filterStatus.value, "error")) ? " selected" : ""}>仅不可用</option><option value="warn" data-v-a9764f3a${ssrIncludeBooleanAttr(Array.isArray(filterStatus.value) ? ssrLooseContain(filterStatus.value, "warn") : ssrLooseEqual(filterStatus.value, "warn")) ? " selected" : ""}>仅有隐患</option><option value="ok" data-v-a9764f3a${ssrIncludeBooleanAttr(Array.isArray(filterStatus.value) ? ssrLooseContain(filterStatus.value, "ok") : ssrLooseEqual(filterStatus.value, "ok")) ? " selected" : ""}>仅正常</option><option value="skip" data-v-a9764f3a${ssrIncludeBooleanAttr(Array.isArray(filterStatus.value) ? ssrLooseContain(filterStatus.value, "skip") : ssrLooseEqual(filterStatus.value, "skip")) ? " selected" : ""}>仅已停用</option></select><input${ssrRenderAttr("value", keyword.value)} class="input input-bordered input-sm w-44" placeholder="搜索服务名/ID/服务商" data-v-a9764f3a><button class="btn btn-sm"${ssrIncludeBooleanAttr(busy.value) ? " disabled" : ""} data-v-a9764f3a>刷新</button><button class="btn btn-primary btn-sm text-white"${ssrIncludeBooleanAttr(busy.value) ? " disabled" : ""} data-v-a9764f3a>${ssrInterpolate(busy.value ? "巡检中…" : "立即巡检")}</button></div></div><div class="grid grid-cols-2 md:grid-cols-5 gap-3 mt-4" data-v-a9764f3a><!--[-->`);
ssrRenderList(summaryCards.value, (s) => {
_push(`<div class="${ssrRenderClass([{ on: filterStatus.value === s.key }, "sum-card"])}" data-v-a9764f3a><span class="sum-ico" style="${ssrRenderStyle({ background: s.bg, color: s.color })}" data-v-a9764f3a>${ssrInterpolate(s.ico)}</span><div data-v-a9764f3a><div class="sum-lbl" data-v-a9764f3a>${ssrInterpolate(s.label)}</div><div class="sum-val" style="${ssrRenderStyle({ color: s.color })}" data-v-a9764f3a>${ssrInterpolate(s.value)}</div></div></div>`);
});
_push(`<!--]--></div></div><div class="panel" data-v-a9764f3a><div class="panel-head" data-v-a9764f3a><span class="font-semibold text-slate-700 text-sm" data-v-a9764f3a>巡检明细</span><span class="text-xs text-slate-400" data-v-a9764f3a>共 ${ssrInterpolate(filtered.value.length)} 份配置</span><span class="ml-auto text-xs text-slate-400" data-v-a9764f3a> 一个服务在不同区域可能配着不同凭据,故按「服务 × 区域」分别巡检 </span></div><div class="overflow-x-auto" data-v-a9764f3a><table class="table w-full" data-v-a9764f3a><thead data-v-a9764f3a><tr data-v-a9764f3a><th data-v-a9764f3a>状态</th><th data-v-a9764f3a>服务</th><th data-v-a9764f3a>作用域 / 区域</th><th data-v-a9764f3a>类别</th><th data-v-a9764f3a>探测方式</th><th data-v-a9764f3a>巡检结论</th><th class="text-right" data-v-a9764f3a>耗时</th><th data-v-a9764f3a>检查时间</th><th data-v-a9764f3a></th></tr></thead><tbody data-v-a9764f3a><!--[-->`);
ssrRenderList(filtered.value, (h) => {
_push(`<tr data-v-a9764f3a><td data-v-a9764f3a><span class="st-badge" style="${ssrRenderStyle({ background: meta(h.status).bg, color: meta(h.status).color })}" data-v-a9764f3a>${ssrInterpolate(meta(h.status).label)}</span>`);
if (h.fail_streak > 1) {
_push(`<div class="streak" data-v-a9764f3a>连续 ${ssrInterpolate(h.fail_streak)} 次</div>`);
} else {
_push(`<!---->`);
}
_push(`</td><td data-v-a9764f3a><div class="font-semibold text-slate-700" data-v-a9764f3a>${ssrInterpolate(h.name || h.svc_id)}</div><div class="text-xs text-slate-400 font-mono" data-v-a9764f3a>${ssrInterpolate(h.svc_id)}`);
if (h.provider) {
_push(`<span data-v-a9764f3a> · ${ssrInterpolate(h.provider)}</span>`);
} else {
_push(`<!---->`);
}
_push(`</div></td><td data-v-a9764f3a><span class="chip chip-scope" data-v-a9764f3a>${ssrInterpolate(h.app_name || "全局默认")}</span>`);
if (h.region) {
_push(`<span class="chip chip-region" data-v-a9764f3a>${ssrInterpolate(regionLabel(h.region))}</span>`);
} else {
_push(`<span class="chip" data-v-a9764f3a>默认配置</span>`);
}
_push(`</td><td data-v-a9764f3a><!--[-->`);
ssrRenderList(cats(h.categories), (c) => {
_push(`<span class="chip" data-v-a9764f3a>${ssrInterpolate(catLabel(c))}</span>`);
});
_push(`<!--]-->`);
if (!cats(h.categories).length) {
_push(`<span class="text-xs text-slate-300" data-v-a9764f3a>—</span>`);
} else {
_push(`<!---->`);
}
_push(`</td><td data-v-a9764f3a><span class="${ssrRenderClass(["pk-" + h.probe_kind, "chip"])}"${ssrRenderAttr("title", probeMeta(h.probe_kind).hint)} data-v-a9764f3a>${ssrInterpolate(probeMeta(h.probe_kind).label)}</span></td><td class="reason-cell" data-v-a9764f3a><div class="${ssrRenderClass(h.status === "error" ? "text-rose-600" : "text-slate-500")}" data-v-a9764f3a>${ssrInterpolate(reason(h) || "—")}</div>`);
if (issuesOf(h).length) {
_push(`<div class="issue-list" data-v-a9764f3a><!--[-->`);
ssrRenderList(issuesOf(h), (i, idx) => {
_push(`<div class="issue" data-v-a9764f3a>· ${ssrInterpolate(i)}</div>`);
});
_push(`<!--]--></div>`);
} else {
_push(`<!---->`);
}
_push(`</td><td class="text-right text-xs text-slate-400" data-v-a9764f3a>${ssrInterpolate(h.probe_kind === "none" ? "—" : h.latency_ms + " ms")}</td><td class="text-xs text-slate-400" data-v-a9764f3a>${ssrInterpolate(timeText(h.checked_at))}</td><td data-v-a9764f3a><button class="btn btn-xs"${ssrIncludeBooleanAttr(busy.value) ? " disabled" : ""} data-v-a9764f3a>重测</button></td></tr>`);
});
_push(`<!--]-->`);
if (!filtered.value.length) {
_push(`<tr data-v-a9764f3a><td colspan="9" class="text-center text-slate-400 py-8" data-v-a9764f3a>${ssrInterpolate(rows.value.length ? "当前筛选下没有匹配的记录" : "暂无巡检记录,点击右上角「立即巡检」执行一次")}</td></tr>`);
} else {
_push(`<!---->`);
}
_push(`</tbody></table></div></div></div>`);
};
}
});
const _sfc_setup = _sfc_main.setup;
_sfc_main.setup = (props, ctx) => {
const ssrContext = useSSRContext();
(ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("pages/svcinspect.vue");
return _sfc_setup ? _sfc_setup(props, ctx) : void 0;
};
const svcinspect = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-a9764f3a"]]);
export { svcinspect as default };
//# sourceMappingURL=svcinspect-ApAZbGUu.mjs.map