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.
 
 
 
 
 
 

204 lines
16 KiB

import { defineComponent, ref, reactive, computed, useSSRContext } from 'vue';
import { ssrRenderAttrs, ssrRenderList, ssrRenderAttr, ssrIncludeBooleanAttr, ssrLooseContain, ssrLooseEqual, ssrInterpolate, ssrRenderStyle, ssrRenderClass } from 'vue/server-renderer';
import { u as useApi } from './useApi-B7CB0Cnn.mjs';
import { u as useToast } from './useToast-BwtTR9dH.mjs';
import { _ as _export_sfc } from './server.mjs';
import './auth-QFkCoU1C.mjs';
import 'pinia';
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';
const SCAT_STT = 1;
const SCAT_TTS = 2;
const SCAT_MT = 3;
const SCAT_AST = 4;
const _sfc_main = /* @__PURE__ */ defineComponent({
__name: "calltranslate",
__ssrInlineRender: true,
setup(__props) {
const LANGS = [
{ c: "zh", n: "中文" },
{ c: "en", n: "英文" },
{ c: "ja", n: "日语" },
{ c: "ko", n: "韩语" },
{ c: "fr", n: "法语" },
{ c: "de", n: "德语" },
{ c: "es", n: "西班牙语" },
{ c: "pt", n: "葡萄牙语" },
{ c: "ru", n: "俄语" },
{ c: "ar", n: "阿拉伯语" },
{ c: "th", n: "泰语" },
{ c: "vi", n: "越南语" },
{ c: "id", n: "印尼语" },
{ c: "ms", n: "马来语" },
{ c: "hi", n: "印地语" }
];
function langName(c) {
const x = LANGS.find((l) => l.c === c);
return x ? x.n : c || "";
}
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: "印度" }
];
useApi();
useToast();
const allSvcs = ref([]);
const pairs = ref([]);
const curRegion = ref(REGIONS.length ? REGIONS[0].value : 1);
const editorOpen = ref(false);
const editingPair = ref(null);
ref(0);
const ed = reactive({
src: "zh",
dst: "en",
bidir: false,
mode: 0,
asr: "",
mt: "",
tts: "",
ast: "",
enable: true
});
function svcsByCat(cat) {
return allSvcs.value.filter(
(s) => s.enable && (s.categories || "").split(",").map(Number).indexOf(cat) >= 0
);
}
function svcName(id) {
const s = allSvcs.value.find((x) => x.id === id);
return s ? s.name : id || "未配置";
}
const syncOpen = ref(false);
const syncDesc = ref("");
const syncTargets = ref([]);
const syncRegions = computed(() => REGIONS.filter((r) => r.value !== curRegion.value));
return (_ctx, _push, _parent, _attrs) => {
_push(`<div${ssrRenderAttrs(_attrs)} data-v-23837fd5><div class="flex items-center justify-between mb-5" data-v-23837fd5><div data-v-23837fd5><h2 class="text-lg font-semibold text-slate-800" data-v-23837fd5>通话翻译配置</h2><p class="text-xs text-slate-400 mt-1" data-v-23837fd5>按区域和语言对配置翻译服务。支持三段式(ASR→MT→TTS)和端到端 AST 两种模式。</p></div><div class="flex items-center gap-3" data-v-23837fd5><span class="text-sm text-slate-500" data-v-23837fd5>区域</span><select class="select select-bordered select-sm" data-v-23837fd5><!--[-->`);
ssrRenderList(REGIONS, (r) => {
_push(`<option${ssrRenderAttr("value", r.value)} data-v-23837fd5${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-primary btn-sm text-white" data-v-23837fd5>+ 新增语言对</button></div></div><div class="editor-panel" style="${ssrRenderStyle(editorOpen.value ? null : { display: "none" })}" data-v-23837fd5><div class="flex items-center justify-between mb-4" data-v-23837fd5><h3 class="font-semibold text-slate-800 text-sm" data-v-23837fd5>${ssrInterpolate(editingPair.value ? "编辑语言对" : "新增语言对")}</h3><button class="btn btn-ghost btn-xs" data-v-23837fd5>✕ 关闭</button></div><div class="grid grid-cols-3 gap-4 mb-4" data-v-23837fd5><div class="form-control" data-v-23837fd5><label class="label py-1" data-v-23837fd5><span class="label-text text-xs" data-v-23837fd5>源语言 *</span></label><select class="select select-bordered select-sm" data-v-23837fd5><!--[-->`);
ssrRenderList(LANGS, (l) => {
_push(`<option${ssrRenderAttr("value", l.c)} data-v-23837fd5${ssrIncludeBooleanAttr(Array.isArray(ed.src) ? ssrLooseContain(ed.src, l.c) : ssrLooseEqual(ed.src, l.c)) ? " selected" : ""}>${ssrInterpolate(l.n)}</option>`);
});
_push(`<!--]--></select></div><div class="form-control" data-v-23837fd5><label class="label py-1" data-v-23837fd5><span class="label-text text-xs" data-v-23837fd5>目标语言 *</span></label><select class="select select-bordered select-sm" data-v-23837fd5><!--[-->`);
ssrRenderList(LANGS, (l) => {
_push(`<option${ssrRenderAttr("value", l.c)} data-v-23837fd5${ssrIncludeBooleanAttr(Array.isArray(ed.dst) ? ssrLooseContain(ed.dst, l.c) : ssrLooseEqual(ed.dst, l.c)) ? " selected" : ""}>${ssrInterpolate(l.n)}</option>`);
});
_push(`<!--]--></select></div><div class="form-control" data-v-23837fd5><label class="label py-1" data-v-23837fd5><span class="label-text text-xs" data-v-23837fd5>双向</span></label><input${ssrIncludeBooleanAttr(Array.isArray(ed.bidir) ? ssrLooseContain(ed.bidir, null) : ed.bidir) ? " checked" : ""} type="checkbox" class="toggle toggle-primary mt-1" data-v-23837fd5></div></div><div class="flex gap-3 mb-4" data-v-23837fd5><div class="${ssrRenderClass([{ on: ed.mode === 0 }, "mtab"])}" data-v-23837fd5><div data-v-23837fd5><div class="font-bold text-sm" data-v-23837fd5>🧩 三段式拼接</div><div class="text-xs text-slate-400 mt-0.5" data-v-23837fd5>ASR → MT → TTS</div></div></div><div class="${ssrRenderClass([{ on: ed.mode === 1 }, "mtab"])}" data-v-23837fd5><div data-v-23837fd5><div class="font-bold text-sm" data-v-23837fd5>⚡ 端到端 AST</div><div class="text-xs text-slate-400 mt-0.5" data-v-23837fd5>单服务直接完成语音翻译</div></div></div></div><div data-v-23837fd5>`);
if (ed.mode === 0) {
_push(`<div class="grid grid-cols-3 gap-4" data-v-23837fd5><div class="form-control" data-v-23837fd5><label class="label py-1" data-v-23837fd5><span class="label-text text-xs" data-v-23837fd5>语音识别(ASR)</span></label><select class="select select-bordered select-sm" data-v-23837fd5>`);
if (!svcsByCat(SCAT_STT).length) {
_push(`<option value="" data-v-23837fd5${ssrIncludeBooleanAttr(Array.isArray(ed.asr) ? ssrLooseContain(ed.asr, "") : ssrLooseEqual(ed.asr, "")) ? " selected" : ""}>(无可用服务)</option>`);
} else {
_push(`<!---->`);
}
_push(`<!--[-->`);
ssrRenderList(svcsByCat(SCAT_STT), (s) => {
_push(`<option${ssrRenderAttr("value", s.id)} data-v-23837fd5${ssrIncludeBooleanAttr(Array.isArray(ed.asr) ? ssrLooseContain(ed.asr, s.id) : ssrLooseEqual(ed.asr, s.id)) ? " selected" : ""}>${ssrInterpolate(s.name)}</option>`);
});
_push(`<!--]--></select></div><div class="form-control" data-v-23837fd5><label class="label py-1" data-v-23837fd5><span class="label-text text-xs" data-v-23837fd5>机器翻译(MT)</span></label><select class="select select-bordered select-sm" data-v-23837fd5>`);
if (!svcsByCat(SCAT_MT).length) {
_push(`<option value="" data-v-23837fd5${ssrIncludeBooleanAttr(Array.isArray(ed.mt) ? ssrLooseContain(ed.mt, "") : ssrLooseEqual(ed.mt, "")) ? " selected" : ""}>(无可用服务)</option>`);
} else {
_push(`<!---->`);
}
_push(`<!--[-->`);
ssrRenderList(svcsByCat(SCAT_MT), (s) => {
_push(`<option${ssrRenderAttr("value", s.id)} data-v-23837fd5${ssrIncludeBooleanAttr(Array.isArray(ed.mt) ? ssrLooseContain(ed.mt, s.id) : ssrLooseEqual(ed.mt, s.id)) ? " selected" : ""}>${ssrInterpolate(s.name)}</option>`);
});
_push(`<!--]--></select></div><div class="form-control" data-v-23837fd5><label class="label py-1" data-v-23837fd5><span class="label-text text-xs" data-v-23837fd5>语音合成(TTS)</span></label><select class="select select-bordered select-sm" data-v-23837fd5>`);
if (!svcsByCat(SCAT_TTS).length) {
_push(`<option value="" data-v-23837fd5${ssrIncludeBooleanAttr(Array.isArray(ed.tts) ? ssrLooseContain(ed.tts, "") : ssrLooseEqual(ed.tts, "")) ? " selected" : ""}>(无可用服务)</option>`);
} else {
_push(`<!---->`);
}
_push(`<!--[-->`);
ssrRenderList(svcsByCat(SCAT_TTS), (s) => {
_push(`<option${ssrRenderAttr("value", s.id)} data-v-23837fd5${ssrIncludeBooleanAttr(Array.isArray(ed.tts) ? ssrLooseContain(ed.tts, s.id) : ssrLooseEqual(ed.tts, s.id)) ? " selected" : ""}>${ssrInterpolate(s.name)}</option>`);
});
_push(`<!--]--></select></div></div>`);
} else {
_push(`<div class="form-control max-w-xs" data-v-23837fd5><label class="label py-1" data-v-23837fd5><span class="label-text text-xs" data-v-23837fd5>端到端语音翻译服务(AST)</span></label><select class="select select-bordered select-sm" data-v-23837fd5>`);
if (!svcsByCat(SCAT_AST).length) {
_push(`<option value="" data-v-23837fd5${ssrIncludeBooleanAttr(Array.isArray(ed.ast) ? ssrLooseContain(ed.ast, "") : ssrLooseEqual(ed.ast, "")) ? " selected" : ""}>(无可用服务)</option>`);
} else {
_push(`<!---->`);
}
_push(`<!--[-->`);
ssrRenderList(svcsByCat(SCAT_AST), (s) => {
_push(`<option${ssrRenderAttr("value", s.id)} data-v-23837fd5${ssrIncludeBooleanAttr(Array.isArray(ed.ast) ? ssrLooseContain(ed.ast, s.id) : ssrLooseEqual(ed.ast, s.id)) ? " selected" : ""}>${ssrInterpolate(s.name)}</option>`);
});
_push(`<!--]--></select></div>`);
}
_push(`</div><div class="flex items-center justify-between pt-4 border-t border-slate-100 mt-4" data-v-23837fd5><label class="flex items-center gap-2 text-sm" data-v-23837fd5><input${ssrIncludeBooleanAttr(Array.isArray(ed.enable) ? ssrLooseContain(ed.enable, null) : ed.enable) ? " checked" : ""} type="checkbox" class="checkbox checkbox-sm checkbox-primary" data-v-23837fd5> 启用 </label><div class="flex gap-2" data-v-23837fd5><button class="btn btn-ghost btn-sm" data-v-23837fd5>取消</button><button class="btn btn-primary btn-sm text-white" data-v-23837fd5>保存</button></div></div></div><div class="grid grid-cols-1 gap-4" style="${ssrRenderStyle({ "grid-template-columns": "repeat(auto-fill,minmax(360px,1fr))" })}" data-v-23837fd5>`);
if (!pairs.value.length) {
_push(`<div class="col-span-full text-center py-20 text-slate-300" data-v-23837fd5><div class="text-5xl mb-3" data-v-23837fd5>🌐</div><p class="text-sm" data-v-23837fd5>当前区域暂无语言对配置</p></div>`);
} else {
_push(`<!---->`);
}
_push(`<!--[-->`);
ssrRenderList(pairs.value, (p) => {
_push(`<div class="pair-card" data-v-23837fd5><div class="flex items-center justify-between" data-v-23837fd5><div class="flex items-center gap-2" data-v-23837fd5><span class="lang-badge" data-v-23837fd5>${ssrInterpolate(langName(p.src_lang))}</span><span class="text-slate-400 font-bold text-lg" data-v-23837fd5>${ssrInterpolate(p.bidir ? "⇄" : "→")}</span><span class="lang-badge" data-v-23837fd5>${ssrInterpolate(langName(p.dst_lang))}</span></div><div class="flex items-center gap-2" data-v-23837fd5>`);
if (p.mode === 0) {
_push(`<span class="mode-badge mode-pipeline" data-v-23837fd5>三段式拼接</span>`);
} else {
_push(`<span class="mode-badge mode-e2e" data-v-23837fd5>端到端 AST</span>`);
}
if (p.enable) {
_push(`<span class="badge badge-success badge-xs" data-v-23837fd5>启用</span>`);
} else {
_push(`<span class="badge badge-ghost badge-xs" data-v-23837fd5>停用</span>`);
}
_push(`<button class="btn btn-ghost btn-xs text-error" data-v-23837fd5>删除</button></div></div>`);
if (p.mode === 0) {
_push(`<div class="flex flex-wrap items-center gap-2 mt-3" data-v-23837fd5><span class="svc-pill" style="${ssrRenderStyle({ "background": "#1664ff" })}" data-v-23837fd5>ASR: ${ssrInterpolate(svcName(p.asr_svc_id))}</span><span class="text-slate-300 text-sm" data-v-23837fd5>→</span><span class="svc-pill" style="${ssrRenderStyle({ "background": "#059669" })}" data-v-23837fd5>MT: ${ssrInterpolate(svcName(p.mt_svc_id))}</span><span class="text-slate-300 text-sm" data-v-23837fd5>→</span><span class="svc-pill" style="${ssrRenderStyle({ "background": "#7c3aed" })}" data-v-23837fd5>TTS: ${ssrInterpolate(svcName(p.tts_svc_id))}</span></div>`);
} else {
_push(`<div class="flex items-center gap-2 mt-3" data-v-23837fd5><span class="svc-pill" style="${ssrRenderStyle({ "background": "#f97316" })}" data-v-23837fd5>AST: ${ssrInterpolate(svcName(p.ast_svc_id))}</span></div>`);
}
_push(`</div>`);
});
_push(`<!--]--></div><div class="sync-overlay" style="${ssrRenderStyle(syncOpen.value ? null : { display: "none" })}" data-v-23837fd5><div class="sync-box" data-v-23837fd5><div class="flex items-start gap-3 mb-4" data-v-23837fd5><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-23837fd5><svg style="${ssrRenderStyle({ "width": "20px", "height": "20px", "color": "#fff" })}" fill="none" viewBox="0 0 24 24" stroke="currentColor" data-v-23837fd5><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-23837fd5></path></svg></div><div data-v-23837fd5><h3 class="text-base font-semibold text-slate-800" data-v-23837fd5>同步到其他区域</h3><p class="text-xs text-slate-400 mt-1" data-v-23837fd5>${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-23837fd5> ✦ 同步内容:服务组合(模式 + 各段服务)将被复制到目标区域。 </div><div class="flex items-center justify-between mb-1" data-v-23837fd5><span class="text-xs font-semibold text-slate-500" data-v-23837fd5>选择目标区域</span><div class="flex gap-2" data-v-23837fd5><button class="btn btn-ghost btn-xs" data-v-23837fd5>全选</button><button class="btn btn-ghost btn-xs" data-v-23837fd5>清空</button></div></div><div class="sync-region-grid" data-v-23837fd5><!--[-->`);
ssrRenderList(syncRegions.value, (r) => {
_push(`<label class="${ssrRenderClass([{ checked: syncTargets.value.includes(r.value) }, "sync-region-item"])}" data-v-23837fd5><input type="checkbox" class="checkbox checkbox-xs checkbox-primary"${ssrIncludeBooleanAttr(syncTargets.value.includes(r.value)) ? " checked" : ""} data-v-23837fd5><span data-v-23837fd5>${ssrInterpolate(r.label)}</span></label>`);
});
_push(`<!--]--></div><p class="text-[11px] text-slate-400 mb-5" data-v-23837fd5>⚠ 目标区域相同语言对已存在则覆盖,否则新建。</p><div class="flex gap-3 justify-end" data-v-23837fd5><button class="btn btn-ghost" data-v-23837fd5>仅保存当前区域</button><button class="btn btn-primary text-white" data-v-23837fd5>保存并同步</button></div></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/calltranslate.vue");
return _sfc_setup ? _sfc_setup(props, ctx) : void 0;
};
const calltranslate = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-23837fd5"]]);
export { calltranslate as default };
//# sourceMappingURL=calltranslate-qCADGfI8.mjs.map