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.
 
 
 
 
 
 

436 lines
46 KiB

import { _ as __nuxt_component_0 } from './LangSelect-C_QPlcDf.mjs';
import { defineComponent, ref, reactive, computed, useSSRContext } from 'vue';
import { ssrRenderAttrs, ssrRenderStyle, ssrIncludeBooleanAttr, ssrLooseContain, ssrLooseEqual, ssrRenderList, ssrRenderAttr, ssrInterpolate, ssrRenderClass, ssrRenderComponent, ssrRenderDynamicModel } from 'vue/server-renderer';
import { u as useApi } from './useApi-B-E5eLsI.mjs';
import { u as useToast } from './useToast-CS21XT61.mjs';
import { _ as _export_sfc } from './server.mjs';
import './useLangOptions-DMhiAuTa.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 SCAT_MCP = 10;
const _sfc_main = /* @__PURE__ */ defineComponent({
__name: "serviceconfig",
__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: "印度" }
];
const SCAT = [
{ v: 1, label: "STT 语音识别", short: "STT", color: "#0369a1", bg: "#dbeafe" },
{ v: 8, label: "录音文件识别", short: "录音识别", color: "#0e7490", bg: "#cffafe" },
{ v: 2, label: "TTS 语音合成", short: "TTS", color: "#7c3aed", bg: "#ede9fe" },
{ v: 3, label: "MT 机器翻译", short: "MT", color: "#059669", bg: "#dcfce7" },
{ v: 4, label: "AST 端到端翻译", short: "AST", color: "#c2410c", bg: "#fff7ed" },
{ v: 5, label: "LLM 文本大模型", short: "文本LLM", color: "#b45309", bg: "#fef9c3" },
{ v: 9, label: "多媒体大模型", short: "多媒体LLM", color: "#9333ea", bg: "#f3e8ff" },
{ v: 7, label: "STS 端到端对话", short: "STS", color: "#be185d", bg: "#fce7f3" },
{ v: 6, label: "存储 OSS/COS", short: "存储", color: "#475569", bg: "#f1f5f9" },
{ v: 10, label: "MCP 服务", short: "MCP", color: "#0d9488", bg: "#ccfbf1" }
];
useApi();
useToast();
const scopeApp = ref("");
const scopeApps = ref([]);
function scatInfo(v) {
return SCAT.find((s) => s.v === v) || { short: "?", color: "#999", bg: "#eee", v: 0, label: "" };
}
function isMcpType() {
if (editType.value === SCAT_MCP) return true;
return !!curSvc.value && parseCats(curSvc.value.categories).includes(SCAT_MCP);
}
function parseCats(s) {
return (s || "").split(",").map((x) => parseInt(x) || 0).filter((x) => x > 0);
}
function encCount(s) {
return (s.fields || []).filter((f) => f.encrypted).length;
}
const backendReady = ref(true);
const allSvcs = ref([]);
const curSvc = ref(null);
const curRegion = ref(0);
const svcModalVisible = ref(false);
const detailMode = ref("default");
const editForm = reactive({ id: "", name: "", provider: "", description: "", enable: false });
const editType = ref(0);
const editFields = ref([]);
const selectedTemplateId = ref("");
const wizardStep = ref(1);
const overrideFields = ref([]);
const extraRegionFields = ref([]);
const regionLoading = ref(false);
const templates = ref([]);
const curRegionLabel = computed(() => {
const r = REGIONS.find((x) => x.value === curRegion.value);
return r ? r.label : "区域" + curRegion.value;
});
const groupedSvcs = computed(() => {
const groups = SCAT.map((sc) => ({
...sc,
items: allSvcs.value.filter((s) => parseCats(s.categories).includes(sc.v))
})).filter((g) => g.items.length);
const unclassified = allSvcs.value.filter((s) => !parseCats(s.categories).length);
if (unclassified.length) {
groups.push({ v: 0, label: "未分类", short: "未分类", color: "#64748b", bg: "#f1f5f9", items: unclassified });
}
return groups;
});
const templatesByCat = computed(() => {
return SCAT.map((sc) => ({
cat: sc.v,
label: sc.label,
items: templates.value.filter((t) => t.category === sc.v)
})).filter((g) => g.items.length);
});
const templatesForType = computed(() => templates.value.filter((t) => t.category === editType.value));
const syncVisible = ref(false);
ref(false);
const syncDesc = ref("");
const syncScopeNote = ref("");
const syncTargets = ref([]);
const syncRegionList = computed(() => REGIONS.filter((r) => r.value !== curRegion.value));
const tplModalVisible = ref(false);
const tplView = ref("list");
const tplEditing = ref(false);
const tplForm = reactive({ id: "", category: 2, provider: "", name: "", description: "" });
const tplFields = ref([]);
return (_ctx, _push, _parent, _attrs) => {
const _component_LangSelect = __nuxt_component_0;
_push(`<div${ssrRenderAttrs(_attrs)} data-v-4e0895d6>`);
if (!backendReady.value) {
_push(`<div class="mb-4 rounded-lg px-4 py-3 text-sm" style="${ssrRenderStyle({ "background": "#fffbeb", "border": "1px solid #fde68a", "color": "#92400e" })}" data-v-4e0895d6> ⚠ 「第三方服务配置」后端接口暂不可用(连接失败),请检查 console 服务是否运行。 </div>`);
} else {
_push(`<!---->`);
}
_push(`<div class="flex items-center justify-between mb-5" data-v-4e0895d6><div data-v-4e0895d6><h2 class="text-lg font-semibold text-slate-800" data-v-4e0895d6>第三方服务配置</h2><p class="text-xs text-slate-400 mt-1" data-v-4e0895d6>按服务类型分组管理已接入的第三方服务(火山引擎、阿里云、Azure 等)。默认展示<b data-v-4e0895d6>全局默认</b>配置,可切换到具体应用;区域默认<b data-v-4e0895d6>中国</b>,切换区域后点击卡片可为该区域覆盖字段值。</p></div><div class="flex items-center gap-3" data-v-4e0895d6><select class="select select-bordered select-sm" data-v-4e0895d6><option value="" data-v-4e0895d6${ssrIncludeBooleanAttr(Array.isArray(scopeApp.value) ? ssrLooseContain(scopeApp.value, "") : ssrLooseEqual(scopeApp.value, "")) ? " selected" : ""}>全局默认</option><!--[-->`);
ssrRenderList(scopeApps.value, (a) => {
_push(`<option${ssrRenderAttr("value", a)} data-v-4e0895d6${ssrIncludeBooleanAttr(Array.isArray(scopeApp.value) ? ssrLooseContain(scopeApp.value, a) : ssrLooseEqual(scopeApp.value, a)) ? " selected" : ""}>应用:${ssrInterpolate(a)}</option>`);
});
_push(`<!--]--></select><select class="select select-bordered select-sm" data-v-4e0895d6><option${ssrRenderAttr("value", 0)} data-v-4e0895d6${ssrIncludeBooleanAttr(Array.isArray(curRegion.value) ? ssrLooseContain(curRegion.value, 0) : ssrLooseEqual(curRegion.value, 0)) ? " selected" : ""}>默认(全区域)</option><!--[-->`);
ssrRenderList(REGIONS, (r) => {
_push(`<option${ssrRenderAttr("value", r.value)} data-v-4e0895d6${ssrIncludeBooleanAttr(Array.isArray(curRegion.value) ? ssrLooseContain(curRegion.value, r.value) : ssrLooseEqual(curRegion.value, r.value)) ? " selected" : ""}>${ssrInterpolate(r.label)}</option>`);
});
_push(`<!--]--></select><button class="btn btn-ghost btn-sm" data-v-4e0895d6>服务商模板</button><button class="btn btn-primary btn-sm text-white" data-v-4e0895d6>+ 添加服务</button></div></div>`);
if (curRegion.value !== 0) {
_push(`<div class="rounded-lg px-3 py-2 mb-4 text-xs" style="${ssrRenderStyle({ "background": "#fefce8", "border": "1px solid #fde047", "color": "#854d0e" })}" data-v-4e0895d6> ✦ 当前处于「${ssrInterpolate(curRegionLabel.value)}」区域视图:点击服务卡片编辑该区域的字段分叉(覆盖值 / 停用字段 / 区域专属字段)。要改服务本身的默认配置,请切回「默认(全区域)」。 </div>`);
} else {
_push(`<!---->`);
}
if (groupedSvcs.value.length) {
_push(`<div class="flex flex-col gap-6" data-v-4e0895d6><!--[-->`);
ssrRenderList(groupedSvcs.value, (g) => {
_push(`<section data-v-4e0895d6><div class="flex items-center gap-2 mb-3" data-v-4e0895d6><span class="cat-chip" style="${ssrRenderStyle({ color: g.color, background: g.bg })}" data-v-4e0895d6>${ssrInterpolate(g.short)}</span><h3 class="text-sm font-semibold text-slate-700" data-v-4e0895d6>${ssrInterpolate(g.label)}</h3><span class="text-xs text-slate-400" data-v-4e0895d6>${ssrInterpolate(g.items.length)} 个服务</span><div class="flex-1 h-px bg-slate-100 ml-2" data-v-4e0895d6></div></div><div class="svc-grid" data-v-4e0895d6><!--[-->`);
ssrRenderList(g.items, (s) => {
_push(`<div class="svc-card" data-v-4e0895d6><div class="flex items-start gap-3" data-v-4e0895d6><div class="svc-logo" style="${ssrRenderStyle({ background: s.color || "#6366f1" })}" data-v-4e0895d6>${ssrInterpolate(s.icon || (s.name || "").charAt(0))}</div><div style="${ssrRenderStyle({ "min-width": "0", "flex": "1" })}" data-v-4e0895d6><div class="flex items-center gap-2" data-v-4e0895d6><span class="font-semibold text-slate-800 text-sm truncate" data-v-4e0895d6>${ssrInterpolate(s.name)}</span><span class="${ssrRenderClass([s.enable ? "badge-success" : "badge-ghost", "badge badge-xs"])}" data-v-4e0895d6>${ssrInterpolate(s.enable ? "启用" : "停用")}</span></div><p class="text-[11px] text-slate-400 font-mono truncate mt-0.5"${ssrRenderAttr("title", s.id)} data-v-4e0895d6>${ssrInterpolate(s.id)}</p></div></div><p class="text-xs text-slate-500 mt-2 line-clamp-2" style="${ssrRenderStyle({ "min-height": "32px" })}" data-v-4e0895d6>${ssrInterpolate(s.description || "—")}</p><div class="flex flex-wrap items-center gap-1 mt-2" data-v-4e0895d6>`);
if (s.provider) {
_push(`<span class="provider-chip" data-v-4e0895d6>${ssrInterpolate(s.provider)}</span>`);
} else {
_push(`<!---->`);
}
_push(`<span class="field-count" data-v-4e0895d6>${ssrInterpolate((s.fields || []).length)} 字段</span>`);
if (encCount(s)) {
_push(`<span class="lock-badge" data-v-4e0895d6>🔒${ssrInterpolate(encCount(s))}</span>`);
} else {
_push(`<!---->`);
}
_push(`</div></div>`);
});
_push(`<!--]--><div class="svc-card add-card" data-v-4e0895d6><span class="text-2xl text-slate-300" data-v-4e0895d6>+</span><span class="text-xs text-slate-400 mt-1" data-v-4e0895d6>添加${ssrInterpolate(g.short)}服务</span></div></div></section>`);
});
_push(`<!--]--></div>`);
} else {
_push(`<div class="bg-white rounded-2xl border border-slate-100 shadow-sm text-center text-slate-300 py-20" data-v-4e0895d6><div class="text-5xl mb-3" data-v-4e0895d6>⚙️</div><p class="text-sm mb-4" data-v-4e0895d6>尚未配置任何第三方服务</p><button class="btn btn-primary btn-sm text-white" data-v-4e0895d6>+ 添加服务</button></div>`);
}
if (svcModalVisible.value) {
_push(`<div class="modal-overlay" data-v-4e0895d6><div class="svc-box" data-v-4e0895d6>`);
if (detailMode.value === "default" && curSvc.value) {
_push(`<!--[--><div class="flex items-center justify-between mb-5" data-v-4e0895d6><div class="flex items-center gap-3" data-v-4e0895d6><div class="svc-logo" style="${ssrRenderStyle({ background: curSvc.value.color || "#6366f1", width: "44px", height: "44px", fontSize: "20px" })}" data-v-4e0895d6>${ssrInterpolate(curSvc.value.icon || (curSvc.value.name || "").charAt(0))}</div><div data-v-4e0895d6><h3 class="text-base font-semibold text-slate-800" data-v-4e0895d6>${ssrInterpolate(curSvc.value.name)}</h3><p class="text-xs text-slate-400 mt-0.5" data-v-4e0895d6>${ssrInterpolate(curSvc.value.id)}`);
if (editForm.provider) {
_push(`<span data-v-4e0895d6> · 服务商 ${ssrInterpolate(editForm.provider)}</span>`);
} else {
_push(`<!---->`);
}
_push(`</p></div></div><div class="flex gap-2" data-v-4e0895d6><button class="btn btn-error btn-sm btn-outline" data-v-4e0895d6>删除服务</button><button class="btn btn-primary btn-sm text-white" data-v-4e0895d6>保存</button><button class="btn btn-ghost btn-sm" data-v-4e0895d6>关闭</button></div></div><div class="divider text-xs text-slate-400 my-3" data-v-4e0895d6>基本信息</div><div class="grid grid-cols-2 gap-4 mb-4" data-v-4e0895d6><div class="form-control" data-v-4e0895d6><label class="label" data-v-4e0895d6><span class="label-text" data-v-4e0895d6>服务名称 *</span></label><input${ssrRenderAttr("value", editForm.name)} class="input input-bordered" data-v-4e0895d6></div><div class="form-control" data-v-4e0895d6><label class="label" data-v-4e0895d6><span class="label-text" data-v-4e0895d6>启用</span></label><input${ssrIncludeBooleanAttr(Array.isArray(editForm.enable) ? ssrLooseContain(editForm.enable, null) : editForm.enable) ? " checked" : ""} type="checkbox" class="toggle toggle-primary mt-3" data-v-4e0895d6></div></div><div class="form-control mb-4" data-v-4e0895d6><label class="label" data-v-4e0895d6><span class="label-text" data-v-4e0895d6>服务描述</span></label><input${ssrRenderAttr("value", editForm.description)} class="input input-bordered" data-v-4e0895d6></div><div class="mb-4" data-v-4e0895d6><p class="text-sm font-medium text-slate-700 mb-2" data-v-4e0895d6>服务类型</p>`);
if (editType.value) {
_push(`<span class="cat-chip" style="${ssrRenderStyle({ color: scatInfo(editType.value).color, background: scatInfo(editType.value).bg })}" data-v-4e0895d6>${ssrInterpolate(scatInfo(editType.value).short)}</span>`);
} else {
_push(`<!---->`);
}
_push(`<span class="text-xs text-slate-500 ml-2" data-v-4e0895d6>${ssrInterpolate(editType.value ? scatInfo(editType.value).label : "未设置")}</span><span class="text-[11px] text-slate-400 ml-2" data-v-4e0895d6>(类型在创建时确定,不可更改)</span></div><div class="divider text-xs text-slate-400 my-3" data-v-4e0895d6>配置字段(全区域共用)</div><div data-v-4e0895d6>`);
if (!editFields.value.length) {
_push(`<p class="text-xs text-slate-400 py-4 text-center" data-v-4e0895d6>尚无字段,点击下方添加</p>`);
} else {
_push(`<div class="overflow-x-auto" data-v-4e0895d6><table class="table text-xs" data-v-4e0895d6><thead data-v-4e0895d6><tr data-v-4e0895d6><th class="w-44" data-v-4e0895d6>字段名</th><th data-v-4e0895d6>字段描述</th><th class="w-16 text-center" data-v-4e0895d6>加密</th><th data-v-4e0895d6>默认值</th><th class="w-12" data-v-4e0895d6></th></tr></thead><tbody data-v-4e0895d6><!--[-->`);
ssrRenderList(editFields.value, (f, i) => {
_push(`<tr data-v-4e0895d6><td data-v-4e0895d6><input class="field-input"${ssrRenderAttr("value", f.key)} placeholder="key"${ssrRenderAttr("title", f.key)} data-v-4e0895d6></td><td data-v-4e0895d6><input class="field-input"${ssrRenderAttr("value", f.description)} placeholder="用途描述" data-v-4e0895d6></td><td class="text-center" data-v-4e0895d6><input type="checkbox" class="checkbox checkbox-xs checkbox-primary"${ssrIncludeBooleanAttr(Array.isArray(f.encrypted) ? ssrLooseContain(f.encrypted, null) : f.encrypted) ? " checked" : ""} data-v-4e0895d6></td><td data-v-4e0895d6>`);
if (f.type === "langs") {
_push(ssrRenderComponent(_component_LangSelect, {
modelValue: f.def_value,
"onUpdate:modelValue": ($event) => f.def_value = $event,
multiple: true
}, null, _parent));
} else if (f.type === "lang") {
_push(ssrRenderComponent(_component_LangSelect, {
modelValue: f.def_value,
"onUpdate:modelValue": ($event) => f.def_value = $event
}, null, _parent));
} else if (f.encrypted) {
_push(`<!--[--><div class="relative" data-v-4e0895d6><input${ssrRenderAttr("type", f._show ? "text" : "password")} class="field-input pr-14"${ssrRenderDynamicModel(f._show ? "text" : "password", f.def_value, null)} placeholder="留空保留原值" data-v-4e0895d6><button type="button" class="absolute right-2 top-1/2 -translate-y-1/2 text-xs text-slate-400 hover:text-slate-700" data-v-4e0895d6>${ssrInterpolate(f._show ? "隐藏" : "显示")}</button></div><span class="lock-badge ml-1" data-v-4e0895d6>🔒 加密</span><!--]-->`);
} else if (isMcpType() && f.key === "type") {
_push(`<select class="field-input" data-v-4e0895d6><option value="0" data-v-4e0895d6${ssrIncludeBooleanAttr(Array.isArray(f.def_value) ? ssrLooseContain(f.def_value, "0") : ssrLooseEqual(f.def_value, "0")) ? " selected" : ""}>HTTP</option><option value="1" data-v-4e0895d6${ssrIncludeBooleanAttr(Array.isArray(f.def_value) ? ssrLooseContain(f.def_value, "1") : ssrLooseEqual(f.def_value, "1")) ? " selected" : ""}>SSE</option></select>`);
} else {
_push(`<input class="field-input"${ssrRenderAttr("value", f.def_value)} data-v-4e0895d6>`);
}
_push(`</td><td data-v-4e0895d6><button class="btn btn-ghost btn-xs text-error" data-v-4e0895d6>×</button></td></tr>`);
});
_push(`<!--]--></tbody></table></div>`);
}
_push(`<button class="btn btn-ghost btn-sm mt-2 text-primary" data-v-4e0895d6>+ 添加字段</button></div><!--]-->`);
} else if (detailMode.value === "new") {
_push(`<!--[--><div class="flex items-center justify-between mb-4" data-v-4e0895d6><h3 class="text-base font-semibold text-slate-800" data-v-4e0895d6>新增第三方服务</h3><button class="btn btn-ghost btn-sm" data-v-4e0895d6>取消</button></div><div class="wizard-steps mb-5" data-v-4e0895d6><div class="${ssrRenderClass([{ on: wizardStep.value >= 1, cur: wizardStep.value === 1 }, "wstep"])}" data-v-4e0895d6>① 服务类型`);
if (editType.value) {
_push(`<span data-v-4e0895d6> · ${ssrInterpolate(scatInfo(editType.value).short)}</span>`);
} else {
_push(`<!---->`);
}
_push(`</div><div class="wline" data-v-4e0895d6></div><div class="${ssrRenderClass([{ on: wizardStep.value >= 2, cur: wizardStep.value === 2, disabled: !editType.value }, "wstep"])}" data-v-4e0895d6>② 服务商`);
if (editForm.provider) {
_push(`<span data-v-4e0895d6> · ${ssrInterpolate(editForm.provider)}</span>`);
} else {
_push(`<!---->`);
}
_push(`</div><div class="wline" data-v-4e0895d6></div><div class="${ssrRenderClass([{ on: wizardStep.value >= 3, cur: wizardStep.value === 3, disabled: wizardStep.value < 3 }, "wstep"])}" data-v-4e0895d6>③ 配置</div></div>`);
if (wizardStep.value === 1) {
_push(`<!--[--><p class="text-sm text-slate-500 mb-3" data-v-4e0895d6>请选择要接入的服务类型(每个服务归属单一类型,独立配置):</p><div class="type-grid" data-v-4e0895d6><!--[-->`);
ssrRenderList(SCAT, (sc) => {
_push(`<div class="${ssrRenderClass([{ on: editType.value === sc.v }, "type-card"])}" data-v-4e0895d6><span class="cat-chip" style="${ssrRenderStyle({ color: sc.color, background: sc.bg })}" data-v-4e0895d6>${ssrInterpolate(sc.short)}</span><span class="text-sm text-slate-700 mt-2" data-v-4e0895d6>${ssrInterpolate(sc.label)}</span></div>`);
});
_push(`<!--]--></div><!--]-->`);
} else if (wizardStep.value === 2) {
_push(`<!--[--><div class="flex items-center justify-between mb-3" data-v-4e0895d6><p class="text-sm text-slate-500" data-v-4e0895d6>为「${ssrInterpolate(scatInfo(editType.value).label)}」选择服务商:</p><button class="btn btn-ghost btn-xs" data-v-4e0895d6>← 上一步</button></div><div class="type-grid" data-v-4e0895d6><!--[-->`);
ssrRenderList(templatesForType.value, (t) => {
_push(`<div class="${ssrRenderClass([{ on: selectedTemplateId.value === t.id }, "type-card"])}" data-v-4e0895d6><span class="provider-chip" data-v-4e0895d6>${ssrInterpolate(t.provider)}</span><span class="text-sm text-slate-700 mt-2" data-v-4e0895d6>${ssrInterpolate(t.name)}</span><span class="text-[11px] text-slate-400 mt-0.5" data-v-4e0895d6>${ssrInterpolate((t.fields || []).length)} 字段</span></div>`);
});
_push(`<!--]--><div class="type-card" data-v-4e0895d6><span class="provider-chip" style="${ssrRenderStyle({ "background": "#f1f5f9", "color": "#475569" })}" data-v-4e0895d6>自定义</span><span class="text-sm text-slate-700 mt-2" data-v-4e0895d6>空白自定义</span><span class="text-[11px] text-slate-400 mt-0.5" data-v-4e0895d6>手动添加字段</span></div></div>`);
if (!templatesForType.value.length) {
_push(`<p class="text-xs text-slate-400 mt-2" data-v-4e0895d6>该类型暂无内置模板,可选「空白自定义」,或到「服务商模板」新增。</p>`);
} else {
_push(`<!---->`);
}
_push(`<!--]-->`);
} else {
_push(`<!--[--><div class="flex items-center justify-between mb-3" data-v-4e0895d6><div class="flex items-center gap-2" data-v-4e0895d6><span class="cat-chip" style="${ssrRenderStyle({ color: scatInfo(editType.value).color, background: scatInfo(editType.value).bg })}" data-v-4e0895d6>${ssrInterpolate(scatInfo(editType.value).short)}</span>`);
if (editForm.provider) {
_push(`<span class="provider-chip" data-v-4e0895d6>${ssrInterpolate(editForm.provider)}</span>`);
} else {
_push(`<!---->`);
}
_push(`</div><div class="flex gap-2" data-v-4e0895d6><button class="btn btn-ghost btn-xs" data-v-4e0895d6>← 上一步</button><button class="btn btn-primary btn-sm text-white" data-v-4e0895d6>创建</button></div></div><div class="grid grid-cols-2 gap-4 mb-4" data-v-4e0895d6><div class="form-control" data-v-4e0895d6><label class="label" data-v-4e0895d6><span class="label-text" data-v-4e0895d6>服务ID * <span class="text-slate-400 text-xs" data-v-4e0895d6>(唯一,如 tts_azure)</span></span></label><input${ssrRenderAttr("value", editForm.id)} class="input input-bordered font-mono" placeholder="tts_azure" data-v-4e0895d6></div><div class="form-control" data-v-4e0895d6><label class="label" data-v-4e0895d6><span class="label-text" data-v-4e0895d6>服务名称 *</span></label><input${ssrRenderAttr("value", editForm.name)} class="input input-bordered" placeholder="微软 Azure TTS" data-v-4e0895d6></div></div><div class="grid grid-cols-2 gap-4 mb-4" data-v-4e0895d6><div class="form-control" data-v-4e0895d6><label class="label" data-v-4e0895d6><span class="label-text" data-v-4e0895d6>服务商标识 <span class="text-slate-400 text-xs" data-v-4e0895d6>(如 azure/alibaba)</span></span></label><input${ssrRenderAttr("value", editForm.provider)} class="input input-bordered font-mono" placeholder="azure" data-v-4e0895d6></div><div class="form-control" data-v-4e0895d6><label class="label" data-v-4e0895d6><span class="label-text" data-v-4e0895d6>启用</span></label><input${ssrIncludeBooleanAttr(Array.isArray(editForm.enable) ? ssrLooseContain(editForm.enable, null) : editForm.enable) ? " checked" : ""} type="checkbox" class="toggle toggle-primary mt-3" data-v-4e0895d6></div></div><div class="form-control mb-4" data-v-4e0895d6><label class="label" data-v-4e0895d6><span class="label-text" data-v-4e0895d6>服务描述</span></label><input${ssrRenderAttr("value", editForm.description)} class="input input-bordered" placeholder="简述该服务的用途" data-v-4e0895d6></div><div class="divider text-xs text-slate-400 my-3" data-v-4e0895d6>配置字段</div><div data-v-4e0895d6>`);
if (!editFields.value.length) {
_push(`<p class="text-xs text-slate-400 py-4 text-center" data-v-4e0895d6>尚无字段,选模板自动带出或点击下方添加</p>`);
} else {
_push(`<div class="overflow-x-auto" data-v-4e0895d6><table class="table text-xs" data-v-4e0895d6><thead data-v-4e0895d6><tr data-v-4e0895d6><th class="w-44" data-v-4e0895d6>字段名</th><th data-v-4e0895d6>字段描述</th><th class="w-16 text-center" data-v-4e0895d6>加密</th><th data-v-4e0895d6>默认值</th><th class="w-12" data-v-4e0895d6></th></tr></thead><tbody data-v-4e0895d6><!--[-->`);
ssrRenderList(editFields.value, (f, i) => {
_push(`<tr data-v-4e0895d6><td data-v-4e0895d6><input class="field-input"${ssrRenderAttr("value", f.key)} placeholder="key"${ssrRenderAttr("title", f.key)} data-v-4e0895d6></td><td data-v-4e0895d6><input class="field-input"${ssrRenderAttr("value", f.description)} placeholder="用途描述" data-v-4e0895d6></td><td class="text-center" data-v-4e0895d6><input type="checkbox" class="checkbox checkbox-xs checkbox-primary"${ssrIncludeBooleanAttr(Array.isArray(f.encrypted) ? ssrLooseContain(f.encrypted, null) : f.encrypted) ? " checked" : ""} data-v-4e0895d6></td><td data-v-4e0895d6>`);
if (f.type === "langs") {
_push(ssrRenderComponent(_component_LangSelect, {
modelValue: f.def_value,
"onUpdate:modelValue": ($event) => f.def_value = $event,
multiple: true
}, null, _parent));
} else if (f.type === "lang") {
_push(ssrRenderComponent(_component_LangSelect, {
modelValue: f.def_value,
"onUpdate:modelValue": ($event) => f.def_value = $event
}, null, _parent));
} else if (f.encrypted) {
_push(`<!--[--><div class="relative" data-v-4e0895d6><input${ssrRenderAttr("type", f._show ? "text" : "password")} class="field-input pr-14"${ssrRenderDynamicModel(f._show ? "text" : "password", f.def_value, null)} placeholder="留空保留原值" data-v-4e0895d6><button type="button" class="absolute right-2 top-1/2 -translate-y-1/2 text-xs text-slate-400 hover:text-slate-700" data-v-4e0895d6>${ssrInterpolate(f._show ? "隐藏" : "显示")}</button></div><span class="lock-badge ml-1" data-v-4e0895d6>🔒 加密</span><!--]-->`);
} else if (isMcpType() && f.key === "type") {
_push(`<select class="field-input" data-v-4e0895d6><option value="0" data-v-4e0895d6${ssrIncludeBooleanAttr(Array.isArray(f.def_value) ? ssrLooseContain(f.def_value, "0") : ssrLooseEqual(f.def_value, "0")) ? " selected" : ""}>HTTP</option><option value="1" data-v-4e0895d6${ssrIncludeBooleanAttr(Array.isArray(f.def_value) ? ssrLooseContain(f.def_value, "1") : ssrLooseEqual(f.def_value, "1")) ? " selected" : ""}>SSE</option></select>`);
} else {
_push(`<input class="field-input"${ssrRenderAttr("value", f.def_value)} data-v-4e0895d6>`);
}
_push(`</td><td data-v-4e0895d6><button class="btn btn-ghost btn-xs text-error" data-v-4e0895d6>×</button></td></tr>`);
});
_push(`<!--]--></tbody></table></div>`);
}
_push(`<button class="btn btn-ghost btn-sm mt-2 text-primary" data-v-4e0895d6>+ 添加字段</button></div><!--]-->`);
}
_push(`<!--]-->`);
} else if (detailMode.value === "region" && curSvc.value) {
_push(`<!--[-->`);
if (regionLoading.value) {
_push(`<div class="text-center py-10 text-slate-400" data-v-4e0895d6>加载中...</div>`);
} else {
_push(`<!--[--><div class="flex items-center justify-between mb-5" data-v-4e0895d6><div class="flex items-center gap-3" data-v-4e0895d6><div class="svc-logo" style="${ssrRenderStyle({ background: curSvc.value.color || "#6366f1", width: "44px", height: "44px", fontSize: "20px" })}" data-v-4e0895d6>${ssrInterpolate(curSvc.value.icon || (curSvc.value.name || "").charAt(0))}</div><div data-v-4e0895d6><h3 class="text-base font-semibold text-slate-800" data-v-4e0895d6>${ssrInterpolate(curSvc.value.name)}</h3><span class="badge badge-warning badge-sm mt-0.5" data-v-4e0895d6>${ssrInterpolate(curRegionLabel.value)} 分叉模式</span></div></div><div class="flex gap-2" data-v-4e0895d6><button class="btn btn-primary btn-sm text-white" data-v-4e0895d6>保存分叉</button><button class="btn btn-ghost btn-sm" data-v-4e0895d6>关闭</button></div></div><div class="rounded-lg px-3 py-2 mb-4 text-xs" style="${ssrRenderStyle({ "background": "#fefce8", "border": "1px solid #fde047", "color": "#854d0e" })}" data-v-4e0895d6> ✦ 当前编辑「${ssrInterpolate(curRegionLabel.value)}」的字段分叉:默认字段可覆盖值或勾选「不适用」停用;也可新增本区域专属字段。留空的覆盖字段继承默认值,加密字段留空保留已存储密文。 </div><p class="text-sm font-medium text-slate-700 mb-2" data-v-4e0895d6>默认字段</p><div class="overflow-x-auto" data-v-4e0895d6><table class="table text-xs" data-v-4e0895d6><thead data-v-4e0895d6><tr data-v-4e0895d6><th class="w-44" data-v-4e0895d6>字段名</th><th data-v-4e0895d6>字段描述</th><th class="w-24 text-center" data-v-4e0895d6>状态</th><th class="w-20 text-center" data-v-4e0895d6>本区域不适用</th><th data-v-4e0895d6>有效值</th></tr></thead><tbody data-v-4e0895d6><!--[-->`);
ssrRenderList(overrideFields.value, (f, i) => {
_push(`<tr class="${ssrRenderClass({ "opacity-50": f.disabled })}" data-v-4e0895d6><td class="font-mono text-slate-700 break-all"${ssrRenderAttr("title", f.key)} data-v-4e0895d6>${ssrInterpolate(f.key)}</td><td class="text-slate-500" data-v-4e0895d6>${ssrInterpolate(f.description)}</td><td class="text-center" data-v-4e0895d6>`);
if (f.disabled) {
_push(`<span class="disabled-badge" data-v-4e0895d6>停用</span>`);
} else if (f.is_overridden) {
_push(`<span class="override-badge" data-v-4e0895d6>覆盖</span>`);
} else {
_push(`<span class="inherit-badge" data-v-4e0895d6>继承</span>`);
}
_push(`</td><td class="text-center" data-v-4e0895d6><input type="checkbox" class="checkbox checkbox-xs"${ssrIncludeBooleanAttr(Array.isArray(f.disabled) ? ssrLooseContain(f.disabled, null) : f.disabled) ? " checked" : ""} data-v-4e0895d6></td><td data-v-4e0895d6>`);
if (f.type === "langs") {
_push(ssrRenderComponent(_component_LangSelect, {
modelValue: f._input,
"onUpdate:modelValue": ($event) => f._input = $event,
multiple: true,
disabled: f.disabled
}, null, _parent));
} else if (f.type === "lang") {
_push(ssrRenderComponent(_component_LangSelect, {
modelValue: f._input,
"onUpdate:modelValue": ($event) => f._input = $event,
disabled: f.disabled
}, null, _parent));
} else if (f.encrypted) {
_push(`<!--[--><div class="relative" data-v-4e0895d6><input${ssrRenderAttr("type", f._show ? "text" : "password")} class="field-input pr-14"${ssrRenderDynamicModel(f._show ? "text" : "password", f._input, null)}${ssrIncludeBooleanAttr(f.disabled) ? " disabled" : ""} placeholder="留空继承默认" data-v-4e0895d6><button type="button" class="absolute right-2 top-1/2 -translate-y-1/2 text-xs text-slate-400 hover:text-slate-700" data-v-4e0895d6>${ssrInterpolate(f._show ? "隐藏" : "显示")}</button></div><span class="lock-badge ml-1" data-v-4e0895d6>🔒</span><!--]-->`);
} else if (isMcpType() && f.key === "type") {
_push(`<select class="field-input"${ssrIncludeBooleanAttr(f.disabled) ? " disabled" : ""} data-v-4e0895d6><option value="" data-v-4e0895d6${ssrIncludeBooleanAttr(Array.isArray(f._input) ? ssrLooseContain(f._input, "") : ssrLooseEqual(f._input, "")) ? " selected" : ""}>继承默认</option><option value="0" data-v-4e0895d6${ssrIncludeBooleanAttr(Array.isArray(f._input) ? ssrLooseContain(f._input, "0") : ssrLooseEqual(f._input, "0")) ? " selected" : ""}>HTTP</option><option value="1" data-v-4e0895d6${ssrIncludeBooleanAttr(Array.isArray(f._input) ? ssrLooseContain(f._input, "1") : ssrLooseEqual(f._input, "1")) ? " selected" : ""}>SSE</option></select>`);
} else {
_push(`<input class="field-input"${ssrRenderAttr("value", f._input)}${ssrIncludeBooleanAttr(f.disabled) ? " disabled" : ""}${ssrRenderAttr("placeholder", "留空继承:" + (f.value || ""))} data-v-4e0895d6>`);
}
_push(`</td></tr>`);
});
_push(`<!--]-->`);
if (!overrideFields.value.length) {
_push(`<tr data-v-4e0895d6><td colspan="5" class="text-center text-slate-400 py-3" data-v-4e0895d6>该服务尚无默认字段</td></tr>`);
} else {
_push(`<!---->`);
}
_push(`</tbody></table></div><div class="divider text-xs text-slate-400 my-3" data-v-4e0895d6>${ssrInterpolate(curRegionLabel.value)} 专属字段</div><div data-v-4e0895d6>`);
if (!extraRegionFields.value.length) {
_push(`<p class="text-xs text-slate-400 py-2 text-center" data-v-4e0895d6>尚无区域专属字段,点击下方添加</p>`);
} else {
_push(`<div class="overflow-x-auto" data-v-4e0895d6><table class="table text-xs" data-v-4e0895d6><thead data-v-4e0895d6><tr data-v-4e0895d6><th class="w-44" data-v-4e0895d6>字段名</th><th data-v-4e0895d6>字段描述</th><th class="w-16 text-center" data-v-4e0895d6>加密</th><th data-v-4e0895d6>值</th><th class="w-12" data-v-4e0895d6></th></tr></thead><tbody data-v-4e0895d6><!--[-->`);
ssrRenderList(extraRegionFields.value, (f, i) => {
_push(`<tr data-v-4e0895d6><td data-v-4e0895d6><input class="field-input"${ssrRenderAttr("value", f.key)} placeholder="key"${ssrRenderAttr("title", f.key)} data-v-4e0895d6></td><td data-v-4e0895d6><input class="field-input"${ssrRenderAttr("value", f.description)} placeholder="用途描述" data-v-4e0895d6></td><td class="text-center" data-v-4e0895d6><input type="checkbox" class="checkbox checkbox-xs checkbox-primary"${ssrIncludeBooleanAttr(Array.isArray(f.encrypted) ? ssrLooseContain(f.encrypted, null) : f.encrypted) ? " checked" : ""} data-v-4e0895d6></td><td data-v-4e0895d6>`);
if (f.encrypted) {
_push(`<!--[--><div class="relative" data-v-4e0895d6><input${ssrRenderAttr("type", f._show ? "text" : "password")} class="field-input pr-14"${ssrRenderDynamicModel(f._show ? "text" : "password", f._input, null)} placeholder="留空保留原值" data-v-4e0895d6><button type="button" class="absolute right-2 top-1/2 -translate-y-1/2 text-xs text-slate-400 hover:text-slate-700" data-v-4e0895d6>${ssrInterpolate(f._show ? "隐藏" : "显示")}</button></div><span class="lock-badge ml-1" data-v-4e0895d6>🔒</span><!--]-->`);
} else {
_push(`<input class="field-input"${ssrRenderAttr("value", f._input)} data-v-4e0895d6>`);
}
_push(`</td><td data-v-4e0895d6><button class="btn btn-ghost btn-xs text-error" data-v-4e0895d6>×</button></td></tr>`);
});
_push(`<!--]--></tbody></table></div>`);
}
_push(`<button class="btn btn-ghost btn-sm mt-2 text-primary" data-v-4e0895d6>+ 添加区域专属字段</button></div><!--]-->`);
}
_push(`<!--]-->`);
} else {
_push(`<!---->`);
}
_push(`</div></div>`);
} else {
_push(`<!---->`);
}
_push(`<div class="modal-overlay" style="${ssrRenderStyle([
{ "z-index": "120" },
syncVisible.value ? null : { display: "none" }
])}" data-v-4e0895d6><div class="sync-box" data-v-4e0895d6><div class="flex items-start gap-3 mb-4" data-v-4e0895d6><div style="${ssrRenderStyle({ "width": "42px", "height": "42px", "background": "linear-gradient(135deg,#4f46e5,#7c3aed)", "border-radius": "13px", "display": "flex", "align-items": "center", "justify-content": "center", "flex-shrink": "0" })}" data-v-4e0895d6><svg style="${ssrRenderStyle({ "width": "20px", "height": "20px", "color": "#fff" })}" fill="none" viewBox="0 0 24 24" stroke="currentColor" data-v-4e0895d6><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z" data-v-4e0895d6></path></svg></div><div data-v-4e0895d6><h3 class="text-base font-semibold text-slate-800" data-v-4e0895d6>同步到其他区域</h3><p class="text-xs text-slate-400 mt-1" data-v-4e0895d6>${ssrInterpolate(syncDesc.value)}</p></div></div><div class="text-xs px-3 py-2 rounded-lg mb-3" style="${ssrRenderStyle({ "background": "#f0fdf4", "border": "1px solid #bbf7d0", "color": "#15803d" })}" data-v-4e0895d6>${syncScopeNote.value ?? ""}</div><div class="flex items-center justify-between mb-1" data-v-4e0895d6><span class="text-xs font-semibold text-slate-500" data-v-4e0895d6>选择目标区域</span><div class="flex gap-2" data-v-4e0895d6><button class="btn btn-ghost btn-xs" data-v-4e0895d6>全选</button><button class="btn btn-ghost btn-xs" data-v-4e0895d6>清空</button></div></div><div class="sync-region-grid" data-v-4e0895d6><!--[-->`);
ssrRenderList(syncRegionList.value, (r) => {
_push(`<label class="${ssrRenderClass([{ checked: syncTargets.value.includes(r.value) }, "sync-region-item"])}" data-v-4e0895d6><input type="checkbox" class="checkbox checkbox-xs checkbox-primary"${ssrIncludeBooleanAttr(syncTargets.value.includes(r.value)) ? " checked" : ""} data-v-4e0895d6><span data-v-4e0895d6>${ssrInterpolate(r.label)}</span></label>`);
});
_push(`<!--]--></div><p class="text-[11px] text-slate-400 mb-5" data-v-4e0895d6>⚠ 已勾选区域将被当前配置(值覆盖 / 区域专属字段 / 停用字段)整体替换;加密字段密文一并同步。</p><div class="flex gap-3 justify-end" data-v-4e0895d6><button class="btn btn-ghost" data-v-4e0895d6>仅保存当前区域</button><button class="btn btn-primary text-white" data-v-4e0895d6>保存并同步</button></div></div></div><div class="modal-overlay" style="${ssrRenderStyle([
{ "z-index": "130" },
tplModalVisible.value ? null : { display: "none" }
])}" data-v-4e0895d6><div class="tpl-box" data-v-4e0895d6>`);
if (tplView.value === "list") {
_push(`<!--[--><div class="flex items-center justify-between mb-4" data-v-4e0895d6><div data-v-4e0895d6><h3 class="text-base font-semibold text-slate-800" data-v-4e0895d6>服务商模板</h3><p class="text-xs text-slate-400 mt-1" data-v-4e0895d6>模板是字段预设,新增服务时可一键带出。内置模板可编辑;删除后重启会被重新补回。</p></div><div class="flex gap-2" data-v-4e0895d6><button class="btn btn-primary btn-sm text-white" data-v-4e0895d6>+ 新增模板</button><button class="btn btn-ghost btn-sm" data-v-4e0895d6>关闭</button></div></div><div class="tpl-list" data-v-4e0895d6><!--[-->`);
ssrRenderList(templatesByCat.value, (g) => {
_push(`<div class="mb-3" data-v-4e0895d6><p class="text-xs font-semibold text-slate-500 mb-1" data-v-4e0895d6>${ssrInterpolate(g.label)}</p><!--[-->`);
ssrRenderList(g.items, (t) => {
_push(`<div class="tpl-row" data-v-4e0895d6><div style="${ssrRenderStyle({ "min-width": "0", "flex": "1" })}" data-v-4e0895d6><div class="flex items-center gap-2" data-v-4e0895d6><span class="font-semibold text-sm text-slate-800 truncate" data-v-4e0895d6>${ssrInterpolate(t.name)}</span><span class="provider-chip" data-v-4e0895d6>${ssrInterpolate(t.provider)}</span>`);
if (t.builtin) {
_push(`<span class="badge badge-xs badge-ghost" data-v-4e0895d6>内置</span>`);
} else {
_push(`<!---->`);
}
_push(`</div><p class="text-xs text-slate-400 mt-0.5" data-v-4e0895d6>${ssrInterpolate(t.id)} · ${ssrInterpolate((t.fields || []).length)} 字段</p></div><div class="flex gap-1" data-v-4e0895d6><button class="btn btn-ghost btn-xs" data-v-4e0895d6>编辑</button><button class="btn btn-ghost btn-xs text-error" data-v-4e0895d6>删除</button></div></div>`);
});
_push(`<!--]--></div>`);
});
_push(`<!--]-->`);
if (!templates.value.length) {
_push(`<p class="text-xs text-slate-400 text-center py-6" data-v-4e0895d6>暂无模板</p>`);
} else {
_push(`<!---->`);
}
_push(`</div><!--]-->`);
} else {
_push(`<!--[--><div class="flex items-center justify-between mb-4" data-v-4e0895d6><h3 class="text-base font-semibold text-slate-800" data-v-4e0895d6>${ssrInterpolate(tplEditing.value ? "编辑模板" : "新增模板")}</h3><div class="flex gap-2" data-v-4e0895d6><button class="btn btn-ghost btn-sm" data-v-4e0895d6>返回</button><button class="btn btn-primary btn-sm text-white" data-v-4e0895d6>保存</button></div></div><div class="grid grid-cols-2 gap-3 mb-3" data-v-4e0895d6><div class="form-control" data-v-4e0895d6><label class="label" data-v-4e0895d6><span class="label-text text-xs" data-v-4e0895d6>模板ID *</span></label><input${ssrRenderAttr("value", tplForm.id)}${ssrIncludeBooleanAttr(tplEditing.value) ? " disabled" : ""} class="input input-bordered input-sm font-mono" placeholder="tts_azure" data-v-4e0895d6></div><div class="form-control" data-v-4e0895d6><label class="label" data-v-4e0895d6><span class="label-text text-xs" data-v-4e0895d6>类别 *</span></label><select class="select select-bordered select-sm" data-v-4e0895d6><!--[-->`);
ssrRenderList(SCAT, (sc) => {
_push(`<option${ssrRenderAttr("value", sc.v)} data-v-4e0895d6${ssrIncludeBooleanAttr(Array.isArray(tplForm.category) ? ssrLooseContain(tplForm.category, sc.v) : ssrLooseEqual(tplForm.category, sc.v)) ? " selected" : ""}>${ssrInterpolate(sc.label)}</option>`);
});
_push(`<!--]--></select></div><div class="form-control" data-v-4e0895d6><label class="label" data-v-4e0895d6><span class="label-text text-xs" data-v-4e0895d6>服务商标识 *</span></label><input${ssrRenderAttr("value", tplForm.provider)} class="input input-bordered input-sm font-mono" placeholder="azure" data-v-4e0895d6></div><div class="form-control" data-v-4e0895d6><label class="label" data-v-4e0895d6><span class="label-text text-xs" data-v-4e0895d6>展示名 *</span></label><input${ssrRenderAttr("value", tplForm.name)} class="input input-bordered input-sm" placeholder="微软 Azure TTS" data-v-4e0895d6></div></div><div class="form-control mb-3" data-v-4e0895d6><label class="label" data-v-4e0895d6><span class="label-text text-xs" data-v-4e0895d6>描述</span></label><input${ssrRenderAttr("value", tplForm.description)} class="input input-bordered input-sm" data-v-4e0895d6></div><p class="text-sm font-medium text-slate-700 mb-1" data-v-4e0895d6>字段</p><div class="overflow-x-auto" style="${ssrRenderStyle({ "max-height": "34vh" })}" data-v-4e0895d6><table class="table text-xs" data-v-4e0895d6><thead data-v-4e0895d6><tr data-v-4e0895d6><th class="w-44" data-v-4e0895d6>字段名</th><th data-v-4e0895d6>字段描述</th><th class="w-16 text-center" data-v-4e0895d6>加密</th><th data-v-4e0895d6>默认/提示值</th><th class="w-12" data-v-4e0895d6></th></tr></thead><tbody data-v-4e0895d6><!--[-->`);
ssrRenderList(tplFields.value, (f, i) => {
_push(`<tr data-v-4e0895d6><td data-v-4e0895d6><input class="field-input"${ssrRenderAttr("value", f.key)} placeholder="key"${ssrRenderAttr("title", f.key)} data-v-4e0895d6></td><td data-v-4e0895d6><input class="field-input"${ssrRenderAttr("value", f.description)} placeholder="用途描述" data-v-4e0895d6></td><td class="text-center" data-v-4e0895d6><input type="checkbox" class="checkbox checkbox-xs checkbox-primary"${ssrIncludeBooleanAttr(Array.isArray(f.encrypted) ? ssrLooseContain(f.encrypted, null) : f.encrypted) ? " checked" : ""} data-v-4e0895d6></td><td data-v-4e0895d6>`);
if (f.type === "langs") {
_push(ssrRenderComponent(_component_LangSelect, {
modelValue: f.def_value,
"onUpdate:modelValue": ($event) => f.def_value = $event,
multiple: true
}, null, _parent));
} else if (f.type === "lang") {
_push(ssrRenderComponent(_component_LangSelect, {
modelValue: f.def_value,
"onUpdate:modelValue": ($event) => f.def_value = $event
}, null, _parent));
} else {
_push(`<input class="field-input"${ssrRenderAttr("value", f.def_value)} placeholder="可留空" data-v-4e0895d6>`);
}
_push(`</td><td data-v-4e0895d6><button class="btn btn-ghost btn-xs text-error" data-v-4e0895d6>×</button></td></tr>`);
});
_push(`<!--]-->`);
if (!tplFields.value.length) {
_push(`<tr data-v-4e0895d6><td colspan="5" class="text-center text-slate-400 py-2" data-v-4e0895d6>尚无字段</td></tr>`);
} else {
_push(`<!---->`);
}
_push(`</tbody></table></div><button class="btn btn-ghost btn-sm mt-2 text-primary" data-v-4e0895d6>+ 添加字段</button><!--]-->`);
}
_push(`</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/serviceconfig.vue");
return _sfc_setup ? _sfc_setup(props, ctx) : void 0;
};
const serviceconfig = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-4e0895d6"]]);
export { serviceconfig as default };
//# sourceMappingURL=serviceconfig-BN6iazID.mjs.map