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.
125 lines
9.6 KiB
125 lines
9.6 KiB
import { defineComponent, ref, reactive, computed, useSSRContext } from 'vue';
|
|
import { ssrRenderAttrs, ssrRenderStyle, ssrRenderAttr, ssrIncludeBooleanAttr, ssrLooseContain, ssrLooseEqual, ssrRenderList, ssrInterpolate, ssrRenderClass } from 'vue/server-renderer';
|
|
import { u as useApi } from './useApi-DMQewX5_.mjs';
|
|
import { u as useToast } from './useToast-CS21XT61.mjs';
|
|
import './auth-QFkCoU1C.mjs';
|
|
import 'pinia';
|
|
import './server.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 'perfect-debounce';
|
|
import './useLoading-D4zrSa2m.mjs';
|
|
|
|
const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
__name: "mcpconfig",
|
|
__ssrInlineRender: true,
|
|
setup(__props) {
|
|
const REGIONS = [
|
|
{ value: 1, label: "中国" },
|
|
{ value: 2, label: "美国" },
|
|
{ value: 3, label: "东亚" },
|
|
{ value: 4, label: "东南亚" },
|
|
{ value: 5, label: "南亚" },
|
|
{ value: 6, label: "中东" },
|
|
{ value: 7, label: "欧洲" },
|
|
{ value: 8, label: "俄罗斯" },
|
|
{ value: 9, label: "非洲" },
|
|
{ value: 10, label: "南美" },
|
|
{ value: 11, label: "北美" },
|
|
{ value: 12, label: "大洋洲" },
|
|
{ value: 13, label: "巴西" },
|
|
{ value: 14, label: "印度" }
|
|
];
|
|
function regionLabel(v) {
|
|
const n = Number(v) || 0;
|
|
const r = REGIONS.find((x) => x.value === n);
|
|
if (r) return r.label;
|
|
return n === 0 ? "通用" : "区域" + n;
|
|
}
|
|
const TYPE_LABELS = { 0: "HTTP", 1: "SSE" };
|
|
function typeLabel(t) {
|
|
const n = Number(t) || 0;
|
|
return TYPE_LABELS[n] || String(t ?? "HTTP");
|
|
}
|
|
useApi();
|
|
useToast();
|
|
const view = ref("list");
|
|
const servers = ref([]);
|
|
const loading = ref(false);
|
|
const submitting = ref(false);
|
|
const isEditing = ref(false);
|
|
const regionFilter = ref(1);
|
|
const kwFilter = ref("");
|
|
const form = reactive({
|
|
id: "",
|
|
name: "",
|
|
region: 1,
|
|
type: 0,
|
|
url: "",
|
|
tools: "",
|
|
description: "",
|
|
enable: true
|
|
});
|
|
const filteredRows = computed(() => {
|
|
const kw = kwFilter.value.trim().toLowerCase();
|
|
if (!kw) return servers.value;
|
|
return servers.value.filter((s) => ((s.id || "") + (s.name || "")).toLowerCase().includes(kw));
|
|
});
|
|
return (_ctx, _push, _parent, _attrs) => {
|
|
_push(`<div${ssrRenderAttrs(_attrs)}><div style="${ssrRenderStyle(view.value === "list" ? null : { display: "none" })}"><div class="flex items-center justify-between mb-5"><div><h2 class="text-lg font-semibold text-slate-800">MCP 配置</h2><p class="text-xs text-slate-400 mt-1">MCP(模型上下文协议)服务器,按区域分组,所有应用共享。修改后各服务约 10 分钟内自动同步。</p></div><button class="btn btn-primary btn-sm text-white">+ 新增 MCP 服务</button></div><div class="flex items-center gap-3 mb-4"><span class="text-sm text-slate-500">区域筛选</span><select class="select select-bordered select-sm"><option${ssrRenderAttr("value", 0)}${ssrIncludeBooleanAttr(Array.isArray(regionFilter.value) ? ssrLooseContain(regionFilter.value, 0) : ssrLooseEqual(regionFilter.value, 0)) ? " selected" : ""}>全部区域</option><!--[-->`);
|
|
ssrRenderList(REGIONS, (r) => {
|
|
_push(`<option${ssrRenderAttr("value", r.value)}${ssrIncludeBooleanAttr(Array.isArray(regionFilter.value) ? ssrLooseContain(regionFilter.value, r.value) : ssrLooseEqual(regionFilter.value, r.value)) ? " selected" : ""}>${ssrInterpolate(r.label)}</option>`);
|
|
});
|
|
_push(`<!--]--></select><input${ssrRenderAttr("value", kwFilter.value)} class="input input-bordered input-sm w-48" placeholder="按ID/名称搜索"></div><div class="bg-white rounded-xl shadow-sm border border-slate-100"><div class="overflow-x-auto"><table class="table table-zebra"><thead><tr><th>服务ID</th><th>名称</th><th>区域</th><th>类型</th><th>地址</th><th>工具</th><th>状态</th><th class="text-right">操作</th></tr></thead><tbody>`);
|
|
if (loading.value) {
|
|
_push(`<tr><td colspan="8" class="text-center py-8"><span class="loading loading-spinner loading-sm"></span></td></tr>`);
|
|
} else if (!filteredRows.value.length) {
|
|
_push(`<tr><td colspan="8" class="text-center text-slate-400 py-8">暂无 MCP 服务</td></tr>`);
|
|
} else {
|
|
_push(`<!---->`);
|
|
}
|
|
_push(`<!--[-->`);
|
|
ssrRenderList(filteredRows.value, (s) => {
|
|
_push(`<tr><td class="font-mono text-sm font-medium">${ssrInterpolate(s.id || "")}</td><td class="text-sm">${ssrInterpolate(s.name || "")}</td><td><span class="badge badge-ghost badge-sm">${ssrInterpolate(regionLabel(s.region))}</span></td><td><span class="badge badge-sm badge-outline">${ssrInterpolate(typeLabel(s.type))}</span></td><td class="text-sm text-slate-500 max-w-xs truncate"${ssrRenderAttr("title", s.url || "")}>${ssrInterpolate(s.url || "")}</td><td class="text-sm text-slate-400">`);
|
|
if (s.tools && s.tools.trim()) {
|
|
_push(`<span>${ssrInterpolate(s.tools)}</span>`);
|
|
} else {
|
|
_push(`<span class="text-slate-300">全部</span>`);
|
|
}
|
|
_push(`</td><td>`);
|
|
if (s.enable) {
|
|
_push(`<span class="badge badge-success badge-sm text-white">启用</span>`);
|
|
} else {
|
|
_push(`<span class="badge badge-ghost badge-sm">停用</span>`);
|
|
}
|
|
_push(`</td><td class="text-right"><div class="inline-flex gap-1"><button class="btn btn-ghost btn-xs">编辑</button><button class="btn btn-ghost btn-xs text-red-500">删除</button></div></td></tr>`);
|
|
});
|
|
_push(`<!--]--></tbody></table></div></div></div><div style="${ssrRenderStyle(view.value === "form" ? null : { display: "none" })}"><div class="flex items-center gap-3 mb-5"><button class="btn btn-ghost btn-sm">← 返回列表</button><h2 class="text-lg font-semibold text-slate-800">${ssrInterpolate(isEditing.value ? "编辑 MCP 服务" : "新增 MCP 服务")}</h2></div><div class="bg-white rounded-xl shadow-sm border border-slate-100 p-6 max-w-2xl"><form><div class="grid grid-cols-2 gap-4"><div class="form-control mb-4"><label class="label"><span class="label-text font-medium">服务ID *</span></label><input${ssrRenderAttr("value", form.id)} type="text" class="${ssrRenderClass([{ "bg-slate-100": isEditing.value }, "input input-bordered w-full"])}"${ssrIncludeBooleanAttr(isEditing.value) ? " readonly" : ""} required placeholder="如 gaode_map"><span class="text-xs text-slate-400 mt-1">${ssrInterpolate(isEditing.value ? "编辑模式下不可修改" : "唯一标识,创建后不可修改")}</span></div><div class="form-control mb-4"><label class="label"><span class="label-text font-medium">名称</span></label><input${ssrRenderAttr("value", form.name)} type="text" class="input input-bordered w-full"></div><div class="form-control mb-4"><label class="label"><span class="label-text font-medium">区域 *</span></label><select class="select select-bordered w-full"><!--[-->`);
|
|
ssrRenderList(REGIONS, (r) => {
|
|
_push(`<option${ssrRenderAttr("value", r.value)}${ssrIncludeBooleanAttr(Array.isArray(form.region) ? ssrLooseContain(form.region, r.value) : ssrLooseEqual(form.region, r.value)) ? " selected" : ""}>${ssrInterpolate(r.label)}</option>`);
|
|
});
|
|
_push(`<!--]--></select></div><div class="form-control mb-4"><label class="label"><span class="label-text font-medium">类型</span></label><select class="select select-bordered w-full"><option${ssrRenderAttr("value", 0)}${ssrIncludeBooleanAttr(Array.isArray(form.type) ? ssrLooseContain(form.type, 0) : ssrLooseEqual(form.type, 0)) ? " selected" : ""}>HTTP</option><option${ssrRenderAttr("value", 1)}${ssrIncludeBooleanAttr(Array.isArray(form.type) ? ssrLooseContain(form.type, 1) : ssrLooseEqual(form.type, 1)) ? " selected" : ""}>SSE</option></select></div></div><div class="form-control mb-4"><label class="label"><span class="label-text font-medium">服务地址 (url)</span></label><input${ssrRenderAttr("value", form.url)} type="text" class="input input-bordered w-full font-mono text-sm" placeholder="https://..."></div><div class="form-control mb-4"><label class="label"><span class="label-text font-medium">启用工具 (tools)</span></label><input${ssrRenderAttr("value", form.tools)} type="text" class="input input-bordered w-full" placeholder="逗号分隔,留空表示全部启用"></div><div class="form-control mb-4"><label class="label"><span class="label-text font-medium">描述</span></label><input${ssrRenderAttr("value", form.description)} type="text" class="input input-bordered w-full"></div><div class="form-control mb-6"><label class="label cursor-pointer justify-start gap-3"><input${ssrIncludeBooleanAttr(Array.isArray(form.enable) ? ssrLooseContain(form.enable, null) : form.enable) ? " checked" : ""} type="checkbox" class="toggle toggle-primary"><span class="label-text font-medium">启用该服务</span></label></div><div class="flex gap-3"><button type="button" class="btn btn-ghost">取消</button><button type="submit" class="btn btn-primary text-white"${ssrIncludeBooleanAttr(submitting.value) ? " disabled" : ""}>保存</button></div></form></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/mcpconfig.vue");
|
|
return _sfc_setup ? _sfc_setup(props, ctx) : void 0;
|
|
};
|
|
|
|
export { _sfc_main as default };
|
|
//# sourceMappingURL=mcpconfig-BqT6PWeV.mjs.map
|
|
|