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.
1 lines
45 KiB
1 lines
45 KiB
import{_ as ct}from"./D4Um3zt0.js";import{g as rt,G as pt,C as vt,c as o,l as x,a as e,d as g,q as r,s as G,F as p,r as h,t as d,L as E,v as _,x as R,n as C,H as ye,y as m,A as z,z as _e,o as n,I as L,D as oe,p as bt,_ as mt}from"./DSy_gLdM.js";import{u as xt}from"./NtXZuCUg.js";import{u as yt}from"./EeX3zgoF.js";import"./DD3V9C6_.js";const _t={key:0,class:"mb-4 rounded-lg px-4 py-3 text-sm",style:{background:"#fffbeb",border:"1px solid #fde68a",color:"#92400e"}},ht={class:"flex items-center justify-between mb-5"},gt={class:"flex items-center gap-3"},kt=["value"],ft=["value"],wt={key:1,class:"rounded-lg px-3 py-2 mb-4 text-xs",style:{background:"#fefce8",border:"1px solid #fde047",color:"#854d0e"}},Vt={key:2,class:"flex flex-col gap-6"},Ct=["onClick"],Ut={class:"text-sm font-semibold text-slate-700"},St={class:"text-xs text-slate-400"},Tt={class:"svc-grid"},$t=["onClick"],At={class:"card-head"},Mt={class:"head-text"},Ft={class:"name-line"},zt=["title"],Lt=["title"],jt=["title"],Dt={class:"meta-row"},It=["title"],Et={class:"field-count"},Rt={key:1,class:"lock-badge"},Nt={class:"region-row"},Ot=["title"],Pt=["onClick"],Bt={class:"text-xs text-slate-400 mt-1"},Ht={key:3,class:"bg-white rounded-2xl border border-slate-100 shadow-sm text-center text-slate-300 py-20"},Gt={key:4,class:"modal-overlay"},Jt={class:"svc-box"},qt={class:"flex items-center justify-between mb-5"},Kt={class:"flex items-center gap-3"},Qt={class:"text-base font-semibold text-slate-800"},Wt={class:"text-xs text-slate-400 mt-0.5"},Xt={key:0},Yt={class:"flex gap-2"},Zt={class:"grid grid-cols-2 gap-4 mb-4"},el={class:"form-control"},tl={class:"form-control"},ll={class:"form-control mb-4"},sl={class:"mb-4"},nl={class:"text-xs text-slate-500 ml-2"},ol={key:0,class:"voice-card"},al={class:"flex items-center justify-between"},il={class:"flex items-center gap-2"},dl={class:"text-[11px] text-slate-400"},ul={key:0,class:"text-[11px] text-slate-400 mt-1"},cl={key:1,class:"voice-lang-list"},rl={class:"voice-lang"},pl={class:"voice-ids"},vl=["title"],bl={key:0},ml={key:2,class:"text-[11px] text-slate-400 mt-1"},xl={key:1,class:"rounded-lg px-3 py-2 mb-3 text-xs",style:{background:"#f0fdfa",border:"1px solid #99f6e4",color:"#0f766e"}},yl={key:0,class:"text-xs text-slate-400 py-4 text-center"},_l={key:1,class:"overflow-x-auto"},hl={class:"table text-xs"},gl=["onUpdate:modelValue","title"],kl=["onUpdate:modelValue"],fl={class:"text-center"},wl=["onUpdate:modelValue"],Vl={class:"relative"},Cl=["type","onUpdate:modelValue"],Ul=["onClick"],Sl=["onUpdate:modelValue"],Tl=["onUpdate:modelValue"],$l=["onClick"],Al={class:"wizard-steps mb-5"},Ml={key:0},Fl={key:0},zl={class:"type-grid"},Ll=["onClick"],jl={class:"text-sm text-slate-700 mt-2"},Dl={class:"flex items-center justify-between mb-3"},Il={class:"text-sm text-slate-500"},El={class:"type-grid"},Rl=["onClick"],Nl={class:"provider-chip"},Ol={class:"text-sm text-slate-700 mt-2"},Pl={class:"text-[11px] text-slate-400 mt-0.5"},Bl={key:0,class:"text-xs text-slate-400 mt-2"},Hl={class:"flex items-center justify-between mb-3"},Gl={class:"flex items-center gap-2"},Jl={key:0,class:"provider-chip"},ql={class:"flex gap-2"},Kl={class:"grid grid-cols-2 gap-4 mb-4"},Ql={class:"form-control"},Wl={class:"form-control"},Xl={class:"grid grid-cols-2 gap-4 mb-4"},Yl={class:"form-control"},Zl={class:"form-control"},es={class:"form-control mb-4"},ts={key:0,class:"voice-card"},ls={class:"flex items-center justify-between"},ss={class:"text-[11px] text-slate-400"},ns={key:0,class:"text-[11px] text-slate-400 mt-1"},os={key:1,class:"voice-lang-list"},as={class:"voice-lang"},is={class:"voice-ids"},ds=["title"],us={key:0},cs={key:2,class:"text-[11px] text-slate-400 mt-1"},rs={key:0,class:"text-xs text-slate-400 py-4 text-center"},ps={key:1,class:"overflow-x-auto"},vs={class:"table text-xs"},bs=["onUpdate:modelValue","title"],ms=["onUpdate:modelValue"],xs={class:"text-center"},ys=["onUpdate:modelValue"],_s={class:"relative"},hs=["type","onUpdate:modelValue"],gs=["onClick"],ks=["onUpdate:modelValue"],fs=["onUpdate:modelValue"],ws=["onClick"],Vs={key:0,class:"text-center py-10 text-slate-400"},Cs={class:"flex items-center justify-between mb-5"},Us={class:"flex items-center gap-3"},Ss={class:"text-base font-semibold text-slate-800"},Ts={class:"badge badge-warning badge-sm mt-0.5"},$s={class:"flex gap-2"},As={class:"rounded-lg px-3 py-2 mb-4 text-xs",style:{background:"#fefce8",border:"1px solid #fde047",color:"#854d0e"}},Ms={class:"overflow-x-auto"},Fs={class:"table text-xs"},zs=["title"],Ls={class:"text-slate-500"},js={class:"text-center"},Ds={key:0,class:"disabled-badge"},Is={key:1,class:"override-badge"},Es={key:2,class:"inherit-badge"},Rs={class:"text-center"},Ns=["onUpdate:modelValue"],Os={class:"relative"},Ps=["type","onUpdate:modelValue","disabled"],Bs=["onClick"],Hs=["onUpdate:modelValue","disabled"],Gs=["onUpdate:modelValue","disabled","placeholder"],Js={key:0},qs={class:"divider text-xs text-slate-400 my-3"},Ks={key:0,class:"text-xs text-slate-400 py-2 text-center"},Qs={key:1,class:"overflow-x-auto"},Ws={class:"table text-xs"},Xs=["onUpdate:modelValue","title"],Ys=["onUpdate:modelValue"],Zs={class:"text-center"},en=["onUpdate:modelValue"],tn={class:"relative"},ln=["type","onUpdate:modelValue"],sn=["onClick"],nn=["onUpdate:modelValue"],on=["onClick"],an={class:"modal-overlay",style:{"z-index":"120"}},dn={class:"sync-box"},un={class:"flex items-start gap-3 mb-4"},cn={style:{width:"42px",height:"42px",background:"linear-gradient(135deg,#4f46e5,#7c3aed)","border-radius":"13px",display:"flex","align-items":"center","justify-content":"center","flex-shrink":"0"}},rn={style:{width:"20px",height:"20px",color:"#fff"},fill:"none",viewBox:"0 0 24 24",stroke:"currentColor"},pn={class:"text-xs text-slate-400 mt-1"},vn=["innerHTML"],bn={class:"flex items-center justify-between mb-1"},mn={class:"flex gap-2"},xn={class:"sync-region-grid"},yn=["onClick"],_n=["checked","onClick"],hn={class:"modal-overlay",style:{"z-index":"130"}},gn={class:"tpl-box"},kn={class:"flex items-center justify-between mb-4"},fn={class:"flex gap-2"},wn={class:"tpl-list"},Vn={class:"text-xs font-semibold text-slate-500 mb-1"},Cn={style:{"min-width":"0",flex:"1"}},Un={class:"flex items-center gap-2"},Sn={class:"font-semibold text-sm text-slate-800 truncate"},Tn={class:"provider-chip"},$n={key:0,class:"badge badge-xs badge-ghost"},An={class:"text-xs text-slate-400 mt-0.5"},Mn={class:"flex gap-1"},Fn=["onClick"],zn=["onClick"],Ln={key:0,class:"text-xs text-slate-400 text-center py-6"},jn={class:"flex items-center justify-between mb-4"},Dn={class:"text-base font-semibold text-slate-800"},In={class:"flex gap-2"},En={class:"grid grid-cols-2 gap-3 mb-3"},Rn={class:"form-control"},Nn=["disabled"],On={class:"form-control"},Pn=["value"],Bn={class:"form-control"},Hn={class:"form-control"},Gn={class:"form-control mb-3"},Jn={class:"overflow-x-auto",style:{"max-height":"34vh"}},qn={class:"table text-xs"},Kn=["onUpdate:modelValue","title"],Qn=["onUpdate:modelValue"],Wn={class:"text-center"},Xn=["onUpdate:modelValue"],Yn=["onUpdate:modelValue"],Zn=["onClick"],eo={key:0},Ie=10,to=rt({__name:"serviceconfig",setup(lo){const J=[{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:"印度"}],q=[{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"}],{webApi:U,consoleApi:Ee}=xt(),{success:j,error:S}=yt(),M=m(""),ae=m([]);async function Re(){try{const s=await Ee("products/list",{});ae.value=(s??[]).map(l=>l.name).filter(Boolean)}catch{ae.value=[]}}function Ne(){$(),H()}function T(s){return q.find(l=>l.v===s)||{short:"?",color:"#999",bg:"#eee",v:0,label:""}}function le(){return y.value===Ie?!0:!!v.value&&se(v.value.categories).includes(Ie)}function se(s){return(s||"").split(",").map(l=>parseInt(l)||0).filter(l=>l>0)}function he(s){return(s.fields||[]).filter(l=>l.encrypted).length}function ie(s){const l=ce.value[s.id]||[],u=l.map(t=>J.find(i=>i.value===t)?.label||"区域"+t);return V.value===0?l.length?{text:l.length+" 区域分叉",cls:"has",title:"已分叉:"+u.join("、")}:{text:"全区域通用",cls:"plain",title:"未做任何区域分叉,各区域都用默认配置"}:l.includes(V.value)?{text:"本区域已分叉",cls:"has",title:P.value+"有独立的字段配置"}:{text:"继承默认",cls:"plain",title:P.value+"未分叉,使用默认配置"}}const ge=[2,4,7],k=m([]),N=m(!1),de=z(()=>ge.includes(y.value)),D=z(()=>{const s=new Map;for(const l of k.value)s.has(l.language)||s.set(l.language,[]),s.get(l.language).push(l);return Array.from(s,([l,u])=>({lang:l,items:u}))});function ke(s){const l=w.value.find(i=>i.key==="languages");if(!l||s&&(l.def_value||"").trim())return!1;const u=[],t=new Set;for(const i of k.value)t.has(i.language)||(t.add(i.language),u.push(i.language));return u.length?(l.def_value=u.join(","),!0):!1}async function fe(s){const l=(s||"").trim();if(k.value=[],!!l){N.value=!0;try{const u=await U("getttsvoices",{provider:l});k.value=u?.voices??[]}catch{k.value=[]}finally{N.value=!1}}}function Oe(){ke(!1)?j("已按音色表填入 "+D.value.length+" 种语言,保存后生效"):S("该服务商没有内置音色,或本服务没有 languages 字段")}const ue=m(!0),K=m([]),ce=m({}),v=m(null),V=m(0),Q=m(!1),O=m("default"),c=_e({id:"",name:"",provider:"",description:"",enable:!1}),y=m(0),w=m([]),W=m(""),f=m(1),X=m([]),I=m([]),re=m(!1),Y=m([]),P=z(()=>{const s=J.find(l=>l.value===V.value);return s?s.label:"区域"+V.value}),Z=z(()=>{const s=q.map(u=>({...u,items:K.value.filter(t=>se(t.categories).includes(u.v))})).filter(u=>u.items.length),l=K.value.filter(u=>!se(u.categories).length);return l.length&&s.push({v:0,label:"未分类",short:"未分类",color:"#64748b",bg:"#f1f5f9",items:l}),s}),B=_e({});function Pe(s){B[s]=!B[s]}const we=z(()=>Z.value.length>0&&Z.value.every(s=>B[s.v]));function Be(){const s=!we.value;Z.value.forEach(l=>{B[l.v]=s})}const He=z(()=>q.map(s=>({cat:s.v,label:s.label,items:Y.value.filter(l=>l.category===s.v)})).filter(s=>s.items.length));async function H(){try{const s=await U("getsvcconfigs",{app_name:M.value});K.value=s?.items??[],ce.value=s?.regions??{},ue.value=!0}catch{ue.value=!1,K.value=[],ce.value={};return}if(v.value){const s=K.value.find(l=>l.id===v.value.id);s&&(v.value=s)}}async function ne(){try{const s=await U("getsvctemplates",{});Y.value=s?.items??[]}catch{Y.value=[]}}function Ge(){$()}function Je(s){s&&(v.value=s,Q.value=!0,V.value===0?qe():Qe())}function $(){Q.value=!1,v.value=null}function qe(){const s=v.value;c.id=s.id,c.name=s.name||"",c.provider=s.provider||"",c.description=s.description||"",c.enable=!!s.enable,y.value=se(s.categories)[0]||0,w.value=JSON.parse(JSON.stringify(s.fields||[])).map(l=>({...l,_show:!1})),O.value="default"}function pe(s=0){v.value=null,c.id="",c.name="",c.provider="",c.description="",c.enable=!1,y.value=s,w.value=[],W.value="",f.value=s?2:1,O.value="new",Q.value=!0}const Ve=z(()=>Y.value.filter(s=>s.category===y.value));function Ke(s){y.value!==s&&(y.value=s,W.value="",c.provider="",w.value=[]),f.value=2}function Ce(s){s?(W.value=s.id,c.provider=s.provider||"",c.name||(c.name=s.name||""),c.id||(c.id=s.id||""),c.description||(c.description=s.description||""),w.value=(s.fields||[]).map(l=>({key:l.key,description:l.description,type:l.type||"",encrypted:!!l.encrypted,def_value:l.def_value||"",sort:l.sort,_show:!1}))):(W.value="",c.provider="",w.value=[]),f.value=3,c.provider&&ge.includes(y.value)&&fe(c.provider).then(()=>ke(!0))}function Ue(){w.value.push({key:"",description:"",encrypted:!1,def_value:"",sort:w.value.length,_show:!1})}function Se(s){w.value.splice(s,1),w.value.forEach((l,u)=>{l.sort=u})}async function Qe(){const s=v.value;re.value=!0,O.value="region";try{const u=(await U("getsvcregionoverride",{app_name:M.value,svc_id:s.id,region:V.value}))?.fields??[];X.value=u.filter(t=>!t.region_only).map(t=>({key:t.key,description:t.description,type:t.type||"",encrypted:!!t.encrypted,is_overridden:!!t.is_overridden,disabled:!!t.disabled,value:t.value||"",_input:t.encrypted?"":t.is_overridden&&t.value||"",_show:!1})),I.value=u.filter(t=>t.region_only).map(t=>({key:t.key,description:t.description,encrypted:!!t.encrypted,_input:t.encrypted?"":t.value||"",_show:!1}))}catch(l){S(l?.message??"加载区域分叉失败"),X.value=[],I.value=[]}finally{re.value=!1}}function We(){I.value.push({key:"",description:"",encrypted:!1,_input:"",_show:!1})}function Xe(s){I.value.splice(s,1)}function Ye(s){const l={name:c.name||"",provider:c.provider||"",description:c.description||"",categories:y.value?String(y.value):"",enable:c.enable||!1,fields:w.value.map(u=>({key:u.key,description:u.description,type:u.type||"",encrypted:u.encrypted,def_value:u.def_value,sort:u.sort}))};return s?l.id=c.id||"":l.id=v.value.id,l.app_name=M.value,l}function Ze(){const s={},l=[];X.value.forEach(t=>{s[t.key]=t._input||"",t.disabled&&l.push(t.key)});const u=I.value.filter(t=>(t.key||"").trim()).map((t,i)=>({key:t.key.trim(),description:t.description,encrypted:t.encrypted,def_value:t._input||"",sort:i}));return{overrides:s,disabled_keys:l,extra_fields:u}}async function Te(s){const l=s||!v.value;if(V.value===0){const u=Ye(l);if(!u.id||!u.name)return S("服务ID 和名称 必填"),!1;const t=l?"addsvcconfig":"updatesvcconfig";try{const i=await U(t,u);return v.value=i,await H(),j("保存成功"),!0}catch(i){return S(i?.message??"保存失败"),!1}}else{const{overrides:u,disabled_keys:t,extra_fields:i}=Ze();try{return await U("savesvcregionoverride",{app_name:M.value,svc_id:v.value.id,region:V.value,overrides:u,disabled_keys:t,extra_fields:i}),await H(),j("区域分叉已保存"),!0}catch(a){return S(a?.message??"保存失败"),!1}}}async function et(){if(v.value&&window.confirm("确定删除服务「"+v.value.name+"」及其所有区域分叉?")){try{await U("delsvcconfig",{app_name:M.value,id:v.value.id})}catch(s){S(s?.message??"删除失败");return}$(),j("已删除"),await H()}}const ve=m(!1),be=m(!1),$e=m(""),Ae=m(""),F=m([]),Me=z(()=>J.filter(s=>s.value!==V.value));function me(s){be.value=s;const l=v.value?v.value.name:c.name||"新服务",u=V.value===0;$e.value=u?"「"+l+"」默认配置将保存,可同步推送到其他区域。":"「"+l+"」在当前区域的字段分叉将保存,可同步到其他区域。",Ae.value=u?"✦ 同步内容:各字段<b>默认值</b>推送为目标区域「覆盖值」,目标区域原有分叉将被替换。":"✦ 同步内容:当前区域的值覆盖 / 区域专属字段 / 停用字段整体复制到目标区域。",F.value=[],ve.value=!0}function Fe(s){const l=F.value.indexOf(s);l>=0?F.value.splice(l,1):F.value.push(s)}function ze(s){F.value=s?Me.value.map(l=>l.value):[]}function Le(){ve.value=!1}async function tt(){Le(),await Te(be.value)&&$()}async function lt(){const s=F.value.slice();if(Le(),!await Te(be.value))return;const u=v.value?v.value.id:null;if(!s.length||!u){$();return}let t=0;try{t=(await U("syncsvctoregins",{app_name:M.value,svc_id:u,src_region:V.value,target_regions:s}))?.synced??0}catch(a){S(a?.message??"同步失败");return}await H();const i=s.map(a=>{const De=J.find(ut=>ut.value===a);return De?De.label:"区域"+a});j("已保存并同步到:"+i.join("、")+"("+t+" 个)"),$()}const xe=m(!1),ee=m("list"),te=m(!1),b=_e({id:"",category:2,provider:"",name:"",description:""}),A=m([]);function st(){ee.value="list",xe.value=!0,ne()}function nt(){xe.value=!1}function je(s){s?(te.value=!0,b.id=s.id,b.category=s.category||2,b.provider=s.provider||"",b.name=s.name||"",b.description=s.description||"",A.value=(s.fields||[]).map(l=>({key:l.key,description:l.description,type:l.type||"",encrypted:!!l.encrypted,def_value:l.def_value||"",sort:l.sort}))):(te.value=!1,b.id="",b.category=2,b.provider="",b.name="",b.description="",A.value=[]),ee.value="form"}function ot(){A.value.push({key:"",description:"",encrypted:!1,def_value:"",sort:A.value.length})}function at(s){A.value.splice(s,1),A.value.forEach((l,u)=>{l.sort=u})}async function it(){if(!b.id.trim()||!b.name.trim()||!b.provider.trim()){S("模板ID / 展示名 / 服务商标识 必填");return}const s={id:b.id.trim(),category:Number(b.category)||0,provider:b.provider.trim(),name:b.name.trim(),description:b.description.trim(),fields:A.value.map((l,u)=>({key:l.key,description:l.description,type:l.type||"",encrypted:l.encrypted,def_value:l.def_value,sort:u}))};try{await U(te.value?"updatesvctemplate":"addsvctemplate",s)}catch(l){S(l?.message??"保存失败");return}j("模板已保存"),await ne(),ee.value="list"}async function dt(s){if(window.confirm("确定删除模板「"+s.name+"」?"+(s.builtin?"(内置模板下次启动会被重新补回)":""))){try{await U("delsvctemplate",{id:s.id})}catch(l){S(l?.message??"删除失败");return}j("已删除"),await ne()}}return pt([()=>c.provider,de,Q],([s,l,u])=>{if(!u||!l){k.value=[];return}fe(s)},{immediate:!1}),vt(()=>{Re(),H(),ne()}),(s,l)=>{const u=ct;return n(),o("div",null,[ue.value?x("",!0):(n(),o("div",_t," ⚠ 「第三方服务配置」后端接口暂不可用(连接失败),请检查 console 服务是否运行。 ")),e("div",ht,[l[31]||(l[31]=e("div",null,[e("h2",{class:"text-lg font-semibold text-slate-800"},"第三方服务配置"),e("p",{class:"text-xs text-slate-400 mt-1"},[g("按服务类型分组管理已接入的第三方服务(火山引擎、阿里云、Azure 等)。默认展示"),e("b",null,"全局默认"),g("配置,可切换到具体应用;区域默认"),e("b",null,"中国"),g(",切换区域后点击卡片可为该区域覆盖字段值。")])],-1)),e("div",gt,[r(e("select",{"onUpdate:modelValue":l[0]||(l[0]=t=>M.value=t),class:"select select-bordered select-sm",onChange:Ne},[l[29]||(l[29]=e("option",{value:""},"全局默认",-1)),(n(!0),o(p,null,h(ae.value,t=>(n(),o("option",{key:t,value:t},"应用:"+d(t),9,kt))),128))],544),[[G,M.value]]),r(e("select",{"onUpdate:modelValue":l[1]||(l[1]=t=>V.value=t),class:"select select-bordered select-sm",onChange:Ge},[l[30]||(l[30]=e("option",{value:0},"默认(全区域)",-1)),(n(),o(p,null,h(J,t=>e("option",{key:t.value,value:t.value},d(t.label),9,ft)),64))],544),[[G,V.value,void 0,{number:!0}]]),e("button",{class:"btn btn-ghost btn-sm",onClick:Be},d(we.value?"展开全部":"折叠全部"),1),e("button",{class:"btn btn-ghost btn-sm",onClick:st},"服务商模板"),e("button",{class:"btn btn-primary btn-sm text-white",onClick:l[2]||(l[2]=t=>pe())},"+ 添加服务")])]),V.value!==0?(n(),o("div",wt," ✦ 当前处于「"+d(P.value)+"」区域视图:点击服务卡片编辑该区域的字段分叉(覆盖值 / 停用字段 / 区域专属字段)。要改服务本身的默认配置,请切回「默认(全区域)」。 ",1)):x("",!0),Z.value.length?(n(),o("div",Vt,[(n(!0),o(p,null,h(Z.value,t=>(n(),o("section",{key:t.v},[e("div",{class:"group-head",onClick:i=>Pe(t.v)},[e("span",{class:C(["fold-arrow",{folded:B[t.v]}])},"▾",2),e("span",{class:"cat-chip",style:E({color:t.color,background:t.bg})},d(t.short),5),e("h3",Ut,d(t.label),1),e("span",St,d(t.items.length)+" 个服务",1),l[32]||(l[32]=e("div",{class:"flex-1 h-px bg-slate-100 ml-2"},null,-1))],8,Ct),r(e("div",Tt,[(n(!0),o(p,null,h(t.items,i=>(n(),o("div",{key:i.id,class:C(["svc-card",{off:!i.enable}]),onClick:a=>Je(i)},[e("div",At,[e("div",{class:"svc-logo",style:E({background:i.color||"#6366f1"})},d(i.icon||(i.name||"").charAt(0)),5),e("div",Mt,[e("div",Ft,[e("span",{class:"svc-name",title:i.name},d(i.name),9,zt),e("span",{class:C(["state-chip",i.enable?"on":"off"])},d(i.enable?"启用":"停用"),3)]),e("p",{class:"svc-id",title:i.id},d(i.id),9,Lt)])]),e("p",{class:"svc-desc",title:i.description||""},d(i.description||"—"),9,jt),e("div",Dt,[i.provider?(n(),o("span",{key:0,class:"provider-chip",title:i.provider},d(i.provider),9,It)):x("",!0),e("span",Et,d((i.fields||[]).length)+" 字段",1),he(i)?(n(),o("span",Rt,"🔒"+d(he(i)),1)):x("",!0)]),e("div",Nt,[e("span",{class:C(["region-chip",ie(i).cls]),title:ie(i).title},d(ie(i).text),11,Ot)])],10,$t))),128)),e("div",{class:"svc-card add-card",onClick:i=>pe(t.v)},[l[33]||(l[33]=e("span",{class:"text-2xl text-slate-300"},"+",-1)),e("span",Bt,"添加"+d(t.short)+"服务",1)],8,Pt)],512),[[ye,!B[t.v]]])]))),128))])):(n(),o("div",Ht,[l[34]||(l[34]=e("div",{class:"text-5xl mb-3"},"⚙️",-1)),l[35]||(l[35]=e("p",{class:"text-sm mb-4"},"尚未配置任何第三方服务",-1)),e("button",{class:"btn btn-primary btn-sm text-white",onClick:l[3]||(l[3]=t=>pe())},"+ 添加服务")])),Q.value?(n(),o("div",Gt,[e("div",Jt,[O.value==="default"&&v.value?(n(),o(p,{key:0},[e("div",qt,[e("div",Kt,[e("div",{class:"svc-logo",style:E({background:v.value.color||"#6366f1",width:"44px",height:"44px",fontSize:"20px"})},d(v.value.icon||(v.value.name||"").charAt(0)),5),e("div",null,[e("h3",Qt,d(v.value.name),1),e("p",Wt,[g(d(v.value.id),1),c.provider?(n(),o("span",Xt," · 服务商 "+d(c.provider),1)):x("",!0)])])]),e("div",Yt,[e("button",{class:"btn btn-error btn-sm btn-outline",onClick:et},"删除服务"),e("button",{class:"btn btn-primary btn-sm text-white",onClick:l[4]||(l[4]=t=>me(!1))},"保存"),e("button",{class:"btn btn-ghost btn-sm",onClick:$},"关闭")])]),l[46]||(l[46]=e("div",{class:"divider text-xs text-slate-400 my-3"},"基本信息",-1)),e("div",Zt,[e("div",el,[l[36]||(l[36]=e("label",{class:"label"},[e("span",{class:"label-text"},"服务名称 *")],-1)),r(e("input",{"onUpdate:modelValue":l[5]||(l[5]=t=>c.name=t),class:"input input-bordered"},null,512),[[_,c.name]])]),e("div",tl,[l[37]||(l[37]=e("label",{class:"label"},[e("span",{class:"label-text"},"启用")],-1)),r(e("input",{"onUpdate:modelValue":l[6]||(l[6]=t=>c.enable=t),type:"checkbox",class:"toggle toggle-primary mt-3"},null,512),[[R,c.enable]])])]),e("div",ll,[l[38]||(l[38]=e("label",{class:"label"},[e("span",{class:"label-text"},"服务描述")],-1)),r(e("input",{"onUpdate:modelValue":l[7]||(l[7]=t=>c.description=t),class:"input input-bordered"},null,512),[[_,c.description]])]),e("div",sl,[l[39]||(l[39]=e("p",{class:"text-sm font-medium text-slate-700 mb-2"},"服务类型",-1)),y.value?(n(),o("span",{key:0,class:"cat-chip",style:E({color:T(y.value).color,background:T(y.value).bg})},d(T(y.value).short),5)):x("",!0),e("span",nl,d(y.value?T(y.value).label:"未设置"),1),l[40]||(l[40]=e("span",{class:"text-[11px] text-slate-400 ml-2"},"(类型在创建时确定,不可更改)",-1))]),de.value?(n(),o("div",ol,[e("div",al,[l[41]||(l[41]=e("span",{class:"text-sm font-medium text-slate-700"},"内置音色表",-1)),e("span",il,[e("span",dl,[N.value?(n(),o(p,{key:0},[g("加载中…")],64)):k.value.length?(n(),o(p,{key:1},[g(d(c.provider)+" · "+d(k.value.length)+" 个音色 / "+d(D.value.length)+" 种语言",1)],64)):(n(),o(p,{key:2},[g("未覆盖 "+d(c.provider||"该服务商"),1)],64))]),k.value.length?(n(),o("button",{key:0,class:"btn btn-ghost btn-xs",onClick:Oe},"填入 languages")):x("",!0)])]),!N.value&&!k.value.length?(n(),o("p",ul," 内置音色表里没有这家服务商,不影响接入——Agent 配音色时手填服务商的音色 id 即可。 ")):k.value.length?(n(),o("div",cl,[(n(!0),o(p,null,h(D.value,t=>(n(),o("div",{key:t.lang,class:"voice-lang-row"},[e("span",rl,d(t.lang),1),e("span",pl,[(n(!0),o(p,null,h(t.items,(i,a)=>(n(),o("span",{key:i.voice_id,class:"voice-pill",title:i.name},[g(d(i.gender===1?"♂":i.gender===2?"♀":"·")+" "+d(i.voice_id),1),a===0?(n(),o("em",bl,"默认")):x("",!0)],8,vl))),128))])]))),128))])):x("",!0),k.value.length?(n(),o("p",ml," 这 "+d(D.value.length)+" 种语言就是该服务能说的语言,已作为下方 languages 的预填值——通话翻译、AI 助手排查「这条链路有没有服务支持」看的就是它。 音色本身是代码里的常量表(后端 comm/ttsvoice.go),实际用哪个在 Agent 里按语言+性别选,同组第一个是默认。 ",1)):x("",!0)])):x("",!0),l[47]||(l[47]=e("div",{class:"divider text-xs text-slate-400 my-3"},"配置字段(全区域共用)",-1)),le()?(n(),o("div",xl,[...l[42]||(l[42]=[g(" ✦ MCP 服务与其他第三方服务同表存储(svc_config):这里填的 url/type/tools 为",-1),e("b",null,"全区域默认",-1),g("; 只在某些区域生效的地址,切到对应区域做分叉即可,卡片上会显示已分叉的区域数。 ",-1)])])):x("",!0),e("div",null,[w.value.length?(n(),o("div",_l,[e("table",hl,[l[45]||(l[45]=e("thead",null,[e("tr",null,[e("th",{class:"w-44"},"字段名"),e("th",null,"字段描述"),e("th",{class:"w-16 text-center"},"加密"),e("th",null,"默认值"),e("th",{class:"w-12"})])],-1)),e("tbody",null,[(n(!0),o(p,null,h(w.value,(t,i)=>(n(),o("tr",{key:i},[e("td",null,[r(e("input",{class:"field-input","onUpdate:modelValue":a=>t.key=a,placeholder:"key",title:t.key},null,8,gl),[[_,t.key]])]),e("td",null,[r(e("input",{class:"field-input","onUpdate:modelValue":a=>t.description=a,placeholder:"用途描述"},null,8,kl),[[_,t.description]])]),e("td",fl,[r(e("input",{type:"checkbox",class:"checkbox checkbox-xs checkbox-primary","onUpdate:modelValue":a=>t.encrypted=a},null,8,wl),[[R,t.encrypted]])]),e("td",null,[t.type==="langs"?(n(),L(u,{key:0,modelValue:t.def_value,"onUpdate:modelValue":a=>t.def_value=a,multiple:!0},null,8,["modelValue","onUpdate:modelValue"])):t.type==="lang"?(n(),L(u,{key:1,modelValue:t.def_value,"onUpdate:modelValue":a=>t.def_value=a},null,8,["modelValue","onUpdate:modelValue"])):t.encrypted?(n(),o(p,{key:2},[e("div",Vl,[r(e("input",{type:t._show?"text":"password",class:"field-input pr-14","onUpdate:modelValue":a=>t.def_value=a,placeholder:"留空保留原值"},null,8,Cl),[[oe,t.def_value]]),e("button",{type:"button",class:"absolute right-2 top-1/2 -translate-y-1/2 text-xs text-slate-400 hover:text-slate-700",onClick:a=>t._show=!t._show},d(t._show?"隐藏":"显示"),9,Ul)]),l[43]||(l[43]=e("span",{class:"lock-badge ml-1"},"🔒 加密",-1))],64)):le()&&t.key==="type"?r((n(),o("select",{key:3,class:"field-input","onUpdate:modelValue":a=>t.def_value=a},[...l[44]||(l[44]=[e("option",{value:"0"},"HTTP",-1),e("option",{value:"1"},"SSE",-1)])],8,Sl)),[[G,t.def_value]]):r((n(),o("input",{key:4,class:"field-input","onUpdate:modelValue":a=>t.def_value=a},null,8,Tl)),[[_,t.def_value]])]),e("td",null,[e("button",{class:"btn btn-ghost btn-xs text-error",onClick:a=>Se(i)},"×",8,$l)])]))),128))])])])):(n(),o("p",yl,"尚无字段,点击下方添加")),e("button",{class:"btn btn-ghost btn-sm mt-2 text-primary",onClick:Ue},"+ 添加字段")])],64)):O.value==="new"?(n(),o(p,{key:1},[e("div",{class:"flex items-center justify-between mb-4"},[l[48]||(l[48]=e("h3",{class:"text-base font-semibold text-slate-800"},"新增第三方服务",-1)),e("button",{class:"btn btn-ghost btn-sm",onClick:$},"取消")]),e("div",Al,[e("div",{class:C(["wstep",{on:f.value>=1,cur:f.value===1}]),onClick:l[8]||(l[8]=t=>f.value=1)},[l[49]||(l[49]=g("① 服务类型",-1)),y.value?(n(),o("span",Ml," · "+d(T(y.value).short),1)):x("",!0)],2),l[51]||(l[51]=e("div",{class:"wline"},null,-1)),e("div",{class:C(["wstep",{on:f.value>=2,cur:f.value===2,disabled:!y.value}]),onClick:l[9]||(l[9]=t=>y.value&&(f.value=2))},[l[50]||(l[50]=g("② 服务商",-1)),c.provider?(n(),o("span",Fl," · "+d(c.provider),1)):x("",!0)],2),l[52]||(l[52]=e("div",{class:"wline"},null,-1)),e("div",{class:C(["wstep",{on:f.value>=3,cur:f.value===3,disabled:f.value<3}])},"③ 配置",2)]),f.value===1?(n(),o(p,{key:0},[l[53]||(l[53]=e("p",{class:"text-sm text-slate-500 mb-3"},"请选择要接入的服务类型(每个服务归属单一类型,独立配置):",-1)),e("div",zl,[(n(),o(p,null,h(q,t=>e("div",{key:t.v,class:C(["type-card",{on:y.value===t.v}]),onClick:i=>Ke(t.v)},[e("span",{class:"cat-chip",style:E({color:t.color,background:t.bg})},d(t.short),5),e("span",jl,d(t.label),1)],10,Ll)),64))])],64)):f.value===2?(n(),o(p,{key:1},[e("div",Dl,[e("p",Il,"为「"+d(T(y.value).label)+"」选择服务商:",1),e("button",{class:"btn btn-ghost btn-xs",onClick:l[10]||(l[10]=t=>f.value=1)},"← 上一步")]),e("div",El,[(n(!0),o(p,null,h(Ve.value,t=>(n(),o("div",{key:t.id,class:C(["type-card",{on:W.value===t.id}]),onClick:i=>Ce(t)},[e("span",Nl,d(t.provider),1),e("span",Ol,d(t.name),1),e("span",Pl,d((t.fields||[]).length)+" 字段",1)],10,Rl))),128)),e("div",{class:"type-card",onClick:l[11]||(l[11]=t=>Ce(null))},[...l[54]||(l[54]=[e("span",{class:"provider-chip",style:{background:"#f1f5f9",color:"#475569"}},"自定义",-1),e("span",{class:"text-sm text-slate-700 mt-2"},"空白自定义",-1),e("span",{class:"text-[11px] text-slate-400 mt-0.5"},"手动添加字段",-1)])])]),Ve.value.length?x("",!0):(n(),o("p",Bl,"该类型暂无内置模板,可选「空白自定义」,或到「服务商模板」新增。"))],64)):(n(),o(p,{key:2},[e("div",Hl,[e("div",Gl,[e("span",{class:"cat-chip",style:E({color:T(y.value).color,background:T(y.value).bg})},d(T(y.value).short),5),c.provider?(n(),o("span",Jl,d(c.provider),1)):x("",!0)]),e("div",ql,[e("button",{class:"btn btn-ghost btn-xs",onClick:l[12]||(l[12]=t=>f.value=2)},"← 上一步"),e("button",{class:"btn btn-primary btn-sm text-white",onClick:l[13]||(l[13]=t=>me(!0))},"创建")])]),e("div",Kl,[e("div",Ql,[l[55]||(l[55]=e("label",{class:"label"},[e("span",{class:"label-text"},[g("服务ID * "),e("span",{class:"text-slate-400 text-xs"},"(唯一,如 tts_azure)")])],-1)),r(e("input",{"onUpdate:modelValue":l[14]||(l[14]=t=>c.id=t),class:"input input-bordered font-mono",placeholder:"tts_azure"},null,512),[[_,c.id]])]),e("div",Wl,[l[56]||(l[56]=e("label",{class:"label"},[e("span",{class:"label-text"},"服务名称 *")],-1)),r(e("input",{"onUpdate:modelValue":l[15]||(l[15]=t=>c.name=t),class:"input input-bordered",placeholder:"微软 Azure TTS"},null,512),[[_,c.name]])])]),e("div",Xl,[e("div",Yl,[l[57]||(l[57]=e("label",{class:"label"},[e("span",{class:"label-text"},[g("服务商标识 "),e("span",{class:"text-slate-400 text-xs"},"(如 azure/alibaba)")])],-1)),r(e("input",{"onUpdate:modelValue":l[16]||(l[16]=t=>c.provider=t),class:"input input-bordered font-mono",placeholder:"azure"},null,512),[[_,c.provider]])]),e("div",Zl,[l[58]||(l[58]=e("label",{class:"label"},[e("span",{class:"label-text"},"启用")],-1)),r(e("input",{"onUpdate:modelValue":l[17]||(l[17]=t=>c.enable=t),type:"checkbox",class:"toggle toggle-primary mt-3"},null,512),[[R,c.enable]])])]),e("div",es,[l[59]||(l[59]=e("label",{class:"label"},[e("span",{class:"label-text"},"服务描述")],-1)),r(e("input",{"onUpdate:modelValue":l[18]||(l[18]=t=>c.description=t),class:"input input-bordered",placeholder:"简述该服务的用途"},null,512),[[_,c.description]])]),de.value?(n(),o("div",ts,[e("div",ls,[l[60]||(l[60]=e("span",{class:"text-sm font-medium text-slate-700"},"内置音色表",-1)),e("span",ss,[N.value?(n(),o(p,{key:0},[g("加载中…")],64)):k.value.length?(n(),o(p,{key:1},[g(d(c.provider)+" · "+d(k.value.length)+" 个音色 / "+d(D.value.length)+" 种语言",1)],64)):(n(),o(p,{key:2},[g("未覆盖 "+d(c.provider||"该服务商"),1)],64))])]),!N.value&&!k.value.length?(n(),o("p",ns," 内置音色表里没有这家服务商,不影响接入——Agent 配音色时手填服务商的音色 id 即可。 ")):k.value.length?(n(),o("div",os,[(n(!0),o(p,null,h(D.value,t=>(n(),o("div",{key:t.lang,class:"voice-lang-row"},[e("span",as,d(t.lang),1),e("span",is,[(n(!0),o(p,null,h(t.items,(i,a)=>(n(),o("span",{key:i.voice_id,class:"voice-pill",title:i.name},[g(d(i.gender===1?"♂":i.gender===2?"♀":"·")+" "+d(i.voice_id),1),a===0?(n(),o("em",us,"默认")):x("",!0)],8,ds))),128))])]))),128))])):x("",!0),k.value.length?(n(),o("p",cs," 这 "+d(D.value.length)+" 种语言就是该服务能说的语言,已作为下方 languages 的预填值——通话翻译、AI 助手排查「这条链路有没有服务支持」看的就是它。 音色本身是代码里的常量表(后端 comm/ttsvoice.go),实际用哪个在 Agent 里按语言+性别选,同组第一个是默认。 ",1)):x("",!0)])):x("",!0),l[64]||(l[64]=e("div",{class:"divider text-xs text-slate-400 my-3"},"配置字段",-1)),e("div",null,[w.value.length?(n(),o("div",ps,[e("table",vs,[l[63]||(l[63]=e("thead",null,[e("tr",null,[e("th",{class:"w-44"},"字段名"),e("th",null,"字段描述"),e("th",{class:"w-16 text-center"},"加密"),e("th",null,"默认值"),e("th",{class:"w-12"})])],-1)),e("tbody",null,[(n(!0),o(p,null,h(w.value,(t,i)=>(n(),o("tr",{key:i},[e("td",null,[r(e("input",{class:"field-input","onUpdate:modelValue":a=>t.key=a,placeholder:"key",title:t.key},null,8,bs),[[_,t.key]])]),e("td",null,[r(e("input",{class:"field-input","onUpdate:modelValue":a=>t.description=a,placeholder:"用途描述"},null,8,ms),[[_,t.description]])]),e("td",xs,[r(e("input",{type:"checkbox",class:"checkbox checkbox-xs checkbox-primary","onUpdate:modelValue":a=>t.encrypted=a},null,8,ys),[[R,t.encrypted]])]),e("td",null,[t.type==="langs"?(n(),L(u,{key:0,modelValue:t.def_value,"onUpdate:modelValue":a=>t.def_value=a,multiple:!0},null,8,["modelValue","onUpdate:modelValue"])):t.type==="lang"?(n(),L(u,{key:1,modelValue:t.def_value,"onUpdate:modelValue":a=>t.def_value=a},null,8,["modelValue","onUpdate:modelValue"])):t.encrypted?(n(),o(p,{key:2},[e("div",_s,[r(e("input",{type:t._show?"text":"password",class:"field-input pr-14","onUpdate:modelValue":a=>t.def_value=a,placeholder:"留空保留原值"},null,8,hs),[[oe,t.def_value]]),e("button",{type:"button",class:"absolute right-2 top-1/2 -translate-y-1/2 text-xs text-slate-400 hover:text-slate-700",onClick:a=>t._show=!t._show},d(t._show?"隐藏":"显示"),9,gs)]),l[61]||(l[61]=e("span",{class:"lock-badge ml-1"},"🔒 加密",-1))],64)):le()&&t.key==="type"?r((n(),o("select",{key:3,class:"field-input","onUpdate:modelValue":a=>t.def_value=a},[...l[62]||(l[62]=[e("option",{value:"0"},"HTTP",-1),e("option",{value:"1"},"SSE",-1)])],8,ks)),[[G,t.def_value]]):r((n(),o("input",{key:4,class:"field-input","onUpdate:modelValue":a=>t.def_value=a},null,8,fs)),[[_,t.def_value]])]),e("td",null,[e("button",{class:"btn btn-ghost btn-xs text-error",onClick:a=>Se(i)},"×",8,ws)])]))),128))])])])):(n(),o("p",rs,"尚无字段,选模板自动带出或点击下方添加")),e("button",{class:"btn btn-ghost btn-sm mt-2 text-primary",onClick:Ue},"+ 添加字段")])],64))],64)):O.value==="region"&&v.value?(n(),o(p,{key:2},[re.value?(n(),o("div",Vs,"加载中...")):(n(),o(p,{key:1},[e("div",Cs,[e("div",Us,[e("div",{class:"svc-logo",style:E({background:v.value.color||"#6366f1",width:"44px",height:"44px",fontSize:"20px"})},d(v.value.icon||(v.value.name||"").charAt(0)),5),e("div",null,[e("h3",Ss,d(v.value.name),1),e("span",Ts,d(P.value)+" 分叉模式",1)])]),e("div",$s,[e("button",{class:"btn btn-primary btn-sm text-white",onClick:l[19]||(l[19]=t=>me(!1))},"保存分叉"),e("button",{class:"btn btn-ghost btn-sm",onClick:$},"关闭")])]),e("div",As," ✦ 当前编辑「"+d(P.value)+"」的字段分叉:默认字段可覆盖值或勾选「不适用」停用;也可新增本区域专属字段。留空的覆盖字段继承默认值,加密字段留空保留已存储密文。 ",1),l[71]||(l[71]=e("p",{class:"text-sm font-medium text-slate-700 mb-2"},"默认字段",-1)),e("div",Ms,[e("table",Fs,[l[68]||(l[68]=e("thead",null,[e("tr",null,[e("th",{class:"w-44"},"字段名"),e("th",null,"字段描述"),e("th",{class:"w-24 text-center"},"状态"),e("th",{class:"w-20 text-center"},"本区域不适用"),e("th",null,"有效值")])],-1)),e("tbody",null,[(n(!0),o(p,null,h(X.value,(t,i)=>(n(),o("tr",{key:i,class:C({"opacity-50":t.disabled})},[e("td",{class:"font-mono text-slate-700 break-all",title:t.key},d(t.key),9,zs),e("td",Ls,d(t.description),1),e("td",js,[t.disabled?(n(),o("span",Ds,"停用")):t.is_overridden?(n(),o("span",Is,"覆盖")):(n(),o("span",Es,"继承"))]),e("td",Rs,[r(e("input",{type:"checkbox",class:"checkbox checkbox-xs","onUpdate:modelValue":a=>t.disabled=a},null,8,Ns),[[R,t.disabled]])]),e("td",null,[t.type==="langs"?(n(),L(u,{key:0,modelValue:t._input,"onUpdate:modelValue":a=>t._input=a,multiple:!0,disabled:t.disabled},null,8,["modelValue","onUpdate:modelValue","disabled"])):t.type==="lang"?(n(),L(u,{key:1,modelValue:t._input,"onUpdate:modelValue":a=>t._input=a,disabled:t.disabled},null,8,["modelValue","onUpdate:modelValue","disabled"])):t.encrypted?(n(),o(p,{key:2},[e("div",Os,[r(e("input",{type:t._show?"text":"password",class:"field-input pr-14","onUpdate:modelValue":a=>t._input=a,disabled:t.disabled,placeholder:"留空继承默认"},null,8,Ps),[[oe,t._input]]),e("button",{type:"button",class:"absolute right-2 top-1/2 -translate-y-1/2 text-xs text-slate-400 hover:text-slate-700",onClick:a=>t._show=!t._show},d(t._show?"隐藏":"显示"),9,Bs)]),l[65]||(l[65]=e("span",{class:"lock-badge ml-1"},"🔒",-1))],64)):le()&&t.key==="type"?r((n(),o("select",{key:3,class:"field-input","onUpdate:modelValue":a=>t._input=a,disabled:t.disabled},[...l[66]||(l[66]=[e("option",{value:""},"继承默认",-1),e("option",{value:"0"},"HTTP",-1),e("option",{value:"1"},"SSE",-1)])],8,Hs)),[[G,t._input]]):r((n(),o("input",{key:4,class:"field-input","onUpdate:modelValue":a=>t._input=a,disabled:t.disabled,placeholder:"留空继承:"+(t.value||"")},null,8,Gs)),[[_,t._input]])])],2))),128)),X.value.length?x("",!0):(n(),o("tr",Js,[...l[67]||(l[67]=[e("td",{colspan:"5",class:"text-center text-slate-400 py-3"},"该服务尚无默认字段",-1)])]))])])]),e("div",qs,d(P.value)+" 专属字段",1),e("div",null,[I.value.length?(n(),o("div",Qs,[e("table",Ws,[l[70]||(l[70]=e("thead",null,[e("tr",null,[e("th",{class:"w-44"},"字段名"),e("th",null,"字段描述"),e("th",{class:"w-16 text-center"},"加密"),e("th",null,"值"),e("th",{class:"w-12"})])],-1)),e("tbody",null,[(n(!0),o(p,null,h(I.value,(t,i)=>(n(),o("tr",{key:i},[e("td",null,[r(e("input",{class:"field-input","onUpdate:modelValue":a=>t.key=a,placeholder:"key",title:t.key},null,8,Xs),[[_,t.key]])]),e("td",null,[r(e("input",{class:"field-input","onUpdate:modelValue":a=>t.description=a,placeholder:"用途描述"},null,8,Ys),[[_,t.description]])]),e("td",Zs,[r(e("input",{type:"checkbox",class:"checkbox checkbox-xs checkbox-primary","onUpdate:modelValue":a=>t.encrypted=a},null,8,en),[[R,t.encrypted]])]),e("td",null,[t.encrypted?(n(),o(p,{key:0},[e("div",tn,[r(e("input",{type:t._show?"text":"password",class:"field-input pr-14","onUpdate:modelValue":a=>t._input=a,placeholder:"留空保留原值"},null,8,ln),[[oe,t._input]]),e("button",{type:"button",class:"absolute right-2 top-1/2 -translate-y-1/2 text-xs text-slate-400 hover:text-slate-700",onClick:a=>t._show=!t._show},d(t._show?"隐藏":"显示"),9,sn)]),l[69]||(l[69]=e("span",{class:"lock-badge ml-1"},"🔒",-1))],64)):r((n(),o("input",{key:1,class:"field-input","onUpdate:modelValue":a=>t._input=a},null,8,nn)),[[_,t._input]])]),e("td",null,[e("button",{class:"btn btn-ghost btn-xs text-error",onClick:a=>Xe(i)},"×",8,on)])]))),128))])])])):(n(),o("p",Ks,"尚无区域专属字段,点击下方添加")),e("button",{class:"btn btn-ghost btn-sm mt-2 text-primary",onClick:We},"+ 添加区域专属字段")])],64))],64)):x("",!0)])])):x("",!0),r(e("div",an,[e("div",dn,[e("div",un,[e("div",cn,[(n(),o("svg",rn,[...l[72]||(l[72]=[e("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"},null,-1)])]))]),e("div",null,[l[73]||(l[73]=e("h3",{class:"text-base font-semibold text-slate-800"},"同步到其他区域",-1)),e("p",pn,d($e.value),1)])]),e("div",{class:"text-xs px-3 py-2 rounded-lg mb-3",style:{background:"#f0fdf4",border:"1px solid #bbf7d0",color:"#15803d"},innerHTML:Ae.value},null,8,vn),e("div",bn,[l[74]||(l[74]=e("span",{class:"text-xs font-semibold text-slate-500"},"选择目标区域",-1)),e("div",mn,[e("button",{class:"btn btn-ghost btn-xs",onClick:l[20]||(l[20]=t=>ze(!0))},"全选"),e("button",{class:"btn btn-ghost btn-xs",onClick:l[21]||(l[21]=t=>ze(!1))},"清空")])]),e("div",xn,[(n(!0),o(p,null,h(Me.value,t=>(n(),o("label",{key:t.value,class:C(["sync-region-item",{checked:F.value.includes(t.value)}]),onClick:i=>Fe(t.value)},[e("input",{type:"checkbox",class:"checkbox checkbox-xs checkbox-primary",checked:F.value.includes(t.value),onClick:bt(i=>Fe(t.value),["stop"])},null,8,_n),e("span",null,d(t.label),1)],10,yn))),128))]),l[75]||(l[75]=e("p",{class:"text-[11px] text-slate-400 mb-5"},"⚠ 已勾选区域将被当前配置(值覆盖 / 区域专属字段 / 停用字段)整体替换;加密字段密文一并同步。",-1)),e("div",{class:"flex gap-3 justify-end"},[e("button",{class:"btn btn-ghost",onClick:tt},"仅保存当前区域"),e("button",{class:"btn btn-primary text-white",onClick:lt},"保存并同步")])])],512),[[ye,ve.value]]),r(e("div",hn,[e("div",gn,[ee.value==="list"?(n(),o(p,{key:0},[e("div",kn,[l[76]||(l[76]=e("div",null,[e("h3",{class:"text-base font-semibold text-slate-800"},"服务商模板"),e("p",{class:"text-xs text-slate-400 mt-1"},"模板是字段预设,新增服务时可一键带出。内置模板可编辑;删除后重启会被重新补回。")],-1)),e("div",fn,[e("button",{class:"btn btn-primary btn-sm text-white",onClick:l[22]||(l[22]=t=>je())},"+ 新增模板"),e("button",{class:"btn btn-ghost btn-sm",onClick:nt},"关闭")])]),e("div",wn,[(n(!0),o(p,null,h(He.value,t=>(n(),o("div",{key:t.cat,class:"mb-3"},[e("p",Vn,d(t.label),1),(n(!0),o(p,null,h(t.items,i=>(n(),o("div",{key:i.id,class:"tpl-row"},[e("div",Cn,[e("div",Un,[e("span",Sn,d(i.name),1),e("span",Tn,d(i.provider),1),i.builtin?(n(),o("span",$n,"内置")):x("",!0)]),e("p",An,d(i.id)+" · "+d((i.fields||[]).length)+" 字段",1)]),e("div",Mn,[e("button",{class:"btn btn-ghost btn-xs",onClick:a=>je(i)},"编辑",8,Fn),e("button",{class:"btn btn-ghost btn-xs text-error",onClick:a=>dt(i)},"删除",8,zn)])]))),128))]))),128)),Y.value.length?x("",!0):(n(),o("p",Ln,"暂无模板"))])],64)):(n(),o(p,{key:1},[e("div",jn,[e("h3",Dn,d(te.value?"编辑模板":"新增模板"),1),e("div",In,[e("button",{class:"btn btn-ghost btn-sm",onClick:l[23]||(l[23]=t=>ee.value="list")},"返回"),e("button",{class:"btn btn-primary btn-sm text-white",onClick:it},"保存")])]),e("div",En,[e("div",Rn,[l[77]||(l[77]=e("label",{class:"label"},[e("span",{class:"label-text text-xs"},"模板ID *")],-1)),r(e("input",{"onUpdate:modelValue":l[24]||(l[24]=t=>b.id=t),disabled:te.value,class:"input input-bordered input-sm font-mono",placeholder:"tts_azure"},null,8,Nn),[[_,b.id]])]),e("div",On,[l[78]||(l[78]=e("label",{class:"label"},[e("span",{class:"label-text text-xs"},"类别 *")],-1)),r(e("select",{"onUpdate:modelValue":l[25]||(l[25]=t=>b.category=t),class:"select select-bordered select-sm"},[(n(),o(p,null,h(q,t=>e("option",{key:t.v,value:t.v},d(t.label),9,Pn)),64))],512),[[G,b.category,void 0,{number:!0}]])]),e("div",Bn,[l[79]||(l[79]=e("label",{class:"label"},[e("span",{class:"label-text text-xs"},"服务商标识 *")],-1)),r(e("input",{"onUpdate:modelValue":l[26]||(l[26]=t=>b.provider=t),class:"input input-bordered input-sm font-mono",placeholder:"azure"},null,512),[[_,b.provider]])]),e("div",Hn,[l[80]||(l[80]=e("label",{class:"label"},[e("span",{class:"label-text text-xs"},"展示名 *")],-1)),r(e("input",{"onUpdate:modelValue":l[27]||(l[27]=t=>b.name=t),class:"input input-bordered input-sm",placeholder:"微软 Azure TTS"},null,512),[[_,b.name]])])]),e("div",Gn,[l[81]||(l[81]=e("label",{class:"label"},[e("span",{class:"label-text text-xs"},"描述")],-1)),r(e("input",{"onUpdate:modelValue":l[28]||(l[28]=t=>b.description=t),class:"input input-bordered input-sm"},null,512),[[_,b.description]])]),l[84]||(l[84]=e("p",{class:"text-sm font-medium text-slate-700 mb-1"},"字段",-1)),e("div",Jn,[e("table",qn,[l[83]||(l[83]=e("thead",null,[e("tr",null,[e("th",{class:"w-44"},"字段名"),e("th",null,"字段描述"),e("th",{class:"w-16 text-center"},"加密"),e("th",null,"默认/提示值"),e("th",{class:"w-12"})])],-1)),e("tbody",null,[(n(!0),o(p,null,h(A.value,(t,i)=>(n(),o("tr",{key:i},[e("td",null,[r(e("input",{class:"field-input","onUpdate:modelValue":a=>t.key=a,placeholder:"key",title:t.key},null,8,Kn),[[_,t.key]])]),e("td",null,[r(e("input",{class:"field-input","onUpdate:modelValue":a=>t.description=a,placeholder:"用途描述"},null,8,Qn),[[_,t.description]])]),e("td",Wn,[r(e("input",{type:"checkbox",class:"checkbox checkbox-xs checkbox-primary","onUpdate:modelValue":a=>t.encrypted=a},null,8,Xn),[[R,t.encrypted]])]),e("td",null,[t.type==="langs"?(n(),L(u,{key:0,modelValue:t.def_value,"onUpdate:modelValue":a=>t.def_value=a,multiple:!0},null,8,["modelValue","onUpdate:modelValue"])):t.type==="lang"?(n(),L(u,{key:1,modelValue:t.def_value,"onUpdate:modelValue":a=>t.def_value=a},null,8,["modelValue","onUpdate:modelValue"])):r((n(),o("input",{key:2,class:"field-input","onUpdate:modelValue":a=>t.def_value=a,placeholder:"可留空"},null,8,Yn)),[[_,t.def_value]])]),e("td",null,[e("button",{class:"btn btn-ghost btn-xs text-error",onClick:a=>at(i)},"×",8,Zn)])]))),128)),A.value.length?x("",!0):(n(),o("tr",eo,[...l[82]||(l[82]=[e("td",{colspan:"5",class:"text-center text-slate-400 py-2"},"尚无字段",-1)])]))])])]),e("button",{class:"btn btn-ghost btn-sm mt-2 text-primary",onClick:ot},"+ 添加字段")],64))])],512),[[ye,xe.value]])])}}}),uo=mt(to,[["__scopeId","data-v-e10e0bc9"]]);export{uo as default};
|
|
|