diff --git a/CLAUDE.md b/CLAUDE.md index e3b4e998..39f261d5 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -64,13 +64,20 @@ cd deploy/console && ./dev-deploy.sh # 不带参数 → 交互选环 # 生产:先构建带版本号的镜像,再部署 cd deploy/console && ./prod-build.sh 0.2.1 yunyan # 第 2 个参数选公司(yunyan|lingpu),省略则交互选 -cd deploy/console && ./prod-deploy.sh 0.2.1 # 用 COMPANY=lingpu 前缀可换仓库,须与构建时一致 +cd deploy/console && ./prod-deploy.sh 0.2.1 yunyan # 第 2 个参数选生产环境,须与构建时所选公司一致;省略则交互选 ``` **镜像仓库按公司区分**,地址/账号统一在 [deploy/registry-profiles.sh](deploy/registry-profiles.sh)(换仓库只改这一处,各脚本 source 它): - `yunyan` → `registry.voitrans.net`(仓库实体在广州机 8.138.86.223) - `lingpu` → `registry.lingpu.net`(灵谱香港机) +**生产镜像名也按公司区分**,映射同在 `registry-profiles.sh` 的 `prod_image_name()`(build 与 deploy 共用一份,防漂移): +云雁沿用历史名 `yunyan-admin`/`console-a11`/`voitrans-a11`;灵谱用 `starpivot-*` 新名。 + +admin/console 的 `prod-deploy.sh` 已改为**多生产环境档案**(`env_profile()`,同 `dev-deploy.sh` 的写法): +- `yunyan` → 47.253.88.66(美国阿里云),目录 `/home/work/yunyan-admin`、`/home/work/console-a11` +- `lingpu` → 8.166.114.65(广州阿里云),目录 `/home/work/starpivot/{admin,console}`,密钥 `~/.ssh/lingpu-gz.pem` + `dev-deploy.sh <环境>` 只做镜像部署:构建推送 → 远端 pull 重启,**不上传** 服务器上的真实 `.env` / `confs/*.yaml`(只下发 `*.example` 模板)。 ## 后端架构(lego 框架) diff --git a/apps/admin/.output/nitro.json b/apps/admin/.output/nitro.json index 99561202..515259bd 100644 --- a/apps/admin/.output/nitro.json +++ b/apps/admin/.output/nitro.json @@ -1,5 +1,5 @@ { - "date": "2026-07-31T11:02:02.337Z", + "date": "2026-08-03T09:06:00.336Z", "preset": "node-server", "framework": { "name": "nuxt", diff --git a/apps/admin/.output/public/_nuxt/C1u1NIe5.js b/apps/admin/.output/public/_nuxt/B0TjgAkR.js similarity index 97% rename from apps/admin/.output/public/_nuxt/C1u1NIe5.js rename to apps/admin/.output/public/_nuxt/B0TjgAkR.js index 842ed81c..2c820959 100644 --- a/apps/admin/.output/public/_nuxt/C1u1NIe5.js +++ b/apps/admin/.output/public/_nuxt/B0TjgAkR.js @@ -1 +1 @@ -import{g as K,B as z,c as l,p as b,H as D,a as t,l as E,F as k,r as C,t as r,m as N,v as S,O as A,x as d,y as I,o as a,d as P}from"./Ccu6Xgpt.js";import{u as q}from"./Um-KoueI.js";import{u as O}from"./DvwKXRUn.js";import"./CH2ZVAK2.js";const Y={class:"flex items-center justify-between mb-5"},G={class:"bg-white rounded-xl shadow-sm border border-slate-100"},J={class:"overflow-x-auto"},Q={class:"table table-zebra"},R={key:0},W={key:1},X={class:"font-mono text-sm"},Z={class:"font-medium"},tt={class:"text-sm text-slate-500"},et={class:"text-sm"},st={key:1,class:"text-slate-300"},nt={class:"text-sm text-slate-500"},ot={class:"flex gap-1"},lt=["onClick"],at=["onClick"],it={class:"flex items-center gap-3 mb-5"},rt={class:"text-lg font-semibold text-slate-800"},dt={class:"bg-white rounded-xl shadow-sm border border-slate-100 p-6 max-w-2xl"},ut={class:"form-control mb-4"},ct={class:"form-control mb-4"},mt={class:"form-control mb-6"},bt={class:"space-y-2"},vt={key:0,class:"text-xs text-slate-400"},pt={class:"badge badge-lg gap-1 bg-slate-100 border-slate-200"},ft=["onClick"],xt={class:"flex gap-2 mt-2"},gt=["onKeydown"],ht={class:"flex gap-3"},_t=["disabled"],Mt=K({__name:"provider",setup(yt){const{webApi:f}=q(),{success:M,error:x,warn:F}=O(),v=d("list"),p=d([]),g=d(!1),h=d(!1),c=d(!1),i=d([]),m=d(""),o=I({id:0,name:"",description:""});function L(s){return s?Number(s).toString(16).toUpperCase():""}function _(s){return(s||"").split(",").map(e=>e.trim()).filter(Boolean)}function T(s){if(!s)return"-";const e=new Date(s*1e3);return e.getFullYear()+"-"+String(e.getMonth()+1).padStart(2,"0")+"-"+String(e.getDate()).padStart(2,"0")+" "+String(e.getHours()).padStart(2,"0")+":"+String(e.getMinutes()).padStart(2,"0")}async function y(){g.value=!0;try{const s=await f("getsolutionproviders",{});p.value=s?.providers??[]}catch(s){x(s?.message??"获取方案商列表失败"),p.value=[]}finally{g.value=!1}}function w(){v.value="list",y()}function V(s){s?(c.value=!0,o.id=s.id,o.name=s.name||"",o.description=s.description||"",i.value=_(s.contactmails)):(c.value=!1,o.id=0,o.name="",o.description="",i.value=[]),m.value="",v.value="form"}function $(){const s=m.value.trim();if(s){if(i.value.includes(s)){F("邮箱已存在");return}i.value.push(s),m.value=""}}function U(s){i.value.splice(s,1)}async function j(){h.value=!0;try{const s={provider:{name:o.name,description:o.description,contactmails:i.value.join(",")}};c.value&&(s.provider.id=Number(o.id)),await f(c.value?"updatesolutionprovider":"addsolutionprovider",s),M("保存成功"),w()}catch(s){x(s?.message??"保存失败")}finally{h.value=!1}}function H(s){window.confirm(`确定删除方案商 "${s.name}" 吗?`)&&f("delsolutionprovider",{id:s.id}).then(()=>{M("删除成功"),y()}).catch(e=>x(e?.message??"删除失败"))}return z(y),(s,e)=>(a(),l("div",null,[b(t("div",null,[t("div",Y,[e[6]||(e[6]=t("h2",{class:"text-lg font-semibold text-slate-800"},"方案商列表",-1)),t("button",{class:"btn btn-primary btn-sm text-white",onClick:e[0]||(e[0]=n=>V())},"+ 新增方案商")]),t("div",G,[t("div",J,[t("table",Q,[e[9]||(e[9]=t("thead",null,[t("tr",null,[t("th",null,"ID"),t("th",null,"方案商名称"),t("th",null,"描述"),t("th",null,"联系邮箱"),t("th",null,"创建时间"),t("th",null,"操作")])],-1)),t("tbody",null,[g.value?(a(),l("tr",R,[...e[7]||(e[7]=[t("td",{colspan:"6",class:"text-center py-8"},[t("span",{class:"loading loading-spinner loading-sm"})],-1)])])):p.value.length?E("",!0):(a(),l("tr",W,[...e[8]||(e[8]=[t("td",{colspan:"6",class:"text-center text-slate-400 py-8"},"暂无数据",-1)])])),(a(!0),l(k,null,C(p.value,n=>(a(),l("tr",{key:n.id},[t("td",X,r(L(n.id)),1),t("td",Z,r(n.name),1),t("td",tt,r(n.description||""),1),t("td",et,[_(n.contactmails).length?(a(!0),l(k,{key:0},C(_(n.contactmails),(u,B)=>(a(),l("span",{key:B,class:"badge badge-ghost badge-sm mr-1"},r(u),1))),128)):(a(),l("span",st,"-"))]),t("td",nt,r(T(n.createtime)),1),t("td",null,[t("div",ot,[t("button",{class:"btn btn-ghost btn-xs",onClick:u=>V(n)},"编辑",8,lt),t("button",{class:"btn btn-ghost btn-xs text-red-500",onClick:u=>H(n)},"删除",8,at)])])]))),128))])])])])],512),[[D,v.value==="list"]]),b(t("div",null,[t("div",it,[t("button",{class:"btn btn-ghost btn-sm",onClick:e[1]||(e[1]=n=>w())},"← 返回列表"),t("h2",rt,r(c.value?"编辑方案商":"新增方案商"),1)]),t("div",dt,[t("form",{onSubmit:N(j,["prevent"])},[t("div",ut,[e[10]||(e[10]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"方案商名称 *")],-1)),b(t("input",{"onUpdate:modelValue":e[2]||(e[2]=n=>o.name=n),type:"text",class:"input input-bordered w-full",required:""},null,512),[[S,o.name]])]),t("div",ct,[e[11]||(e[11]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"描述")],-1)),b(t("textarea",{"onUpdate:modelValue":e[3]||(e[3]=n=>o.description=n),class:"textarea textarea-bordered w-full",rows:"3"},null,512),[[S,o.description]])]),t("div",mt,[e[13]||(e[13]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"联系邮箱")],-1)),t("div",bt,[i.value.length?E("",!0):(a(),l("p",vt,"暂无邮箱")),(a(!0),l(k,null,C(i.value,(n,u)=>(a(),l("div",{key:u,class:"flex items-center gap-2"},[t("span",pt,[e[12]||(e[12]=t("svg",{class:"h-3 w-3 text-slate-400",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor"},[t("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"})],-1)),P(" "+r(n),1)]),t("button",{type:"button",class:"btn btn-ghost btn-xs text-red-400 hover:text-red-600",onClick:B=>U(u)},"×",8,ft)]))),128))]),t("div",xt,[b(t("input",{"onUpdate:modelValue":e[4]||(e[4]=n=>m.value=n),type:"email",class:"input input-bordered input-sm flex-1",placeholder:"输入邮箱地址",onKeydown:A(N($,["prevent"]),["enter"])},null,40,gt),[[S,m.value]]),t("button",{type:"button",class:"btn btn-outline btn-sm btn-primary",onClick:$},"添加")])]),t("div",ht,[t("button",{type:"button",class:"btn btn-ghost",onClick:e[5]||(e[5]=n=>w())},"取消"),t("button",{type:"submit",class:"btn btn-primary text-white",disabled:h.value},"保存",8,_t)])],32)])],512),[[D,v.value==="form"]])]))}});export{Mt as default}; +import{g as K,B as z,c as l,p as b,H as D,a as t,l as E,F as k,r as C,t as r,m as N,v as S,O as A,x as d,y as I,o as a,d as P}from"./mElhLwm2.js";import{u as q}from"./C6twYRfy.js";import{u as O}from"./FVTAbpot.js";import"./qig5Qp6S.js";const Y={class:"flex items-center justify-between mb-5"},G={class:"bg-white rounded-xl shadow-sm border border-slate-100"},J={class:"overflow-x-auto"},Q={class:"table table-zebra"},R={key:0},W={key:1},X={class:"font-mono text-sm"},Z={class:"font-medium"},tt={class:"text-sm text-slate-500"},et={class:"text-sm"},st={key:1,class:"text-slate-300"},nt={class:"text-sm text-slate-500"},ot={class:"flex gap-1"},lt=["onClick"],at=["onClick"],it={class:"flex items-center gap-3 mb-5"},rt={class:"text-lg font-semibold text-slate-800"},dt={class:"bg-white rounded-xl shadow-sm border border-slate-100 p-6 max-w-2xl"},ut={class:"form-control mb-4"},ct={class:"form-control mb-4"},mt={class:"form-control mb-6"},bt={class:"space-y-2"},vt={key:0,class:"text-xs text-slate-400"},pt={class:"badge badge-lg gap-1 bg-slate-100 border-slate-200"},ft=["onClick"],xt={class:"flex gap-2 mt-2"},gt=["onKeydown"],ht={class:"flex gap-3"},_t=["disabled"],Mt=K({__name:"provider",setup(yt){const{webApi:f}=q(),{success:M,error:x,warn:F}=O(),v=d("list"),p=d([]),g=d(!1),h=d(!1),c=d(!1),i=d([]),m=d(""),o=I({id:0,name:"",description:""});function L(s){return s?Number(s).toString(16).toUpperCase():""}function _(s){return(s||"").split(",").map(e=>e.trim()).filter(Boolean)}function T(s){if(!s)return"-";const e=new Date(s*1e3);return e.getFullYear()+"-"+String(e.getMonth()+1).padStart(2,"0")+"-"+String(e.getDate()).padStart(2,"0")+" "+String(e.getHours()).padStart(2,"0")+":"+String(e.getMinutes()).padStart(2,"0")}async function y(){g.value=!0;try{const s=await f("getsolutionproviders",{});p.value=s?.providers??[]}catch(s){x(s?.message??"获取方案商列表失败"),p.value=[]}finally{g.value=!1}}function w(){v.value="list",y()}function V(s){s?(c.value=!0,o.id=s.id,o.name=s.name||"",o.description=s.description||"",i.value=_(s.contactmails)):(c.value=!1,o.id=0,o.name="",o.description="",i.value=[]),m.value="",v.value="form"}function $(){const s=m.value.trim();if(s){if(i.value.includes(s)){F("邮箱已存在");return}i.value.push(s),m.value=""}}function U(s){i.value.splice(s,1)}async function j(){h.value=!0;try{const s={provider:{name:o.name,description:o.description,contactmails:i.value.join(",")}};c.value&&(s.provider.id=Number(o.id)),await f(c.value?"updatesolutionprovider":"addsolutionprovider",s),M("保存成功"),w()}catch(s){x(s?.message??"保存失败")}finally{h.value=!1}}function H(s){window.confirm(`确定删除方案商 "${s.name}" 吗?`)&&f("delsolutionprovider",{id:s.id}).then(()=>{M("删除成功"),y()}).catch(e=>x(e?.message??"删除失败"))}return z(y),(s,e)=>(a(),l("div",null,[b(t("div",null,[t("div",Y,[e[6]||(e[6]=t("h2",{class:"text-lg font-semibold text-slate-800"},"方案商列表",-1)),t("button",{class:"btn btn-primary btn-sm text-white",onClick:e[0]||(e[0]=n=>V())},"+ 新增方案商")]),t("div",G,[t("div",J,[t("table",Q,[e[9]||(e[9]=t("thead",null,[t("tr",null,[t("th",null,"ID"),t("th",null,"方案商名称"),t("th",null,"描述"),t("th",null,"联系邮箱"),t("th",null,"创建时间"),t("th",null,"操作")])],-1)),t("tbody",null,[g.value?(a(),l("tr",R,[...e[7]||(e[7]=[t("td",{colspan:"6",class:"text-center py-8"},[t("span",{class:"loading loading-spinner loading-sm"})],-1)])])):p.value.length?E("",!0):(a(),l("tr",W,[...e[8]||(e[8]=[t("td",{colspan:"6",class:"text-center text-slate-400 py-8"},"暂无数据",-1)])])),(a(!0),l(k,null,C(p.value,n=>(a(),l("tr",{key:n.id},[t("td",X,r(L(n.id)),1),t("td",Z,r(n.name),1),t("td",tt,r(n.description||""),1),t("td",et,[_(n.contactmails).length?(a(!0),l(k,{key:0},C(_(n.contactmails),(u,B)=>(a(),l("span",{key:B,class:"badge badge-ghost badge-sm mr-1"},r(u),1))),128)):(a(),l("span",st,"-"))]),t("td",nt,r(T(n.createtime)),1),t("td",null,[t("div",ot,[t("button",{class:"btn btn-ghost btn-xs",onClick:u=>V(n)},"编辑",8,lt),t("button",{class:"btn btn-ghost btn-xs text-red-500",onClick:u=>H(n)},"删除",8,at)])])]))),128))])])])])],512),[[D,v.value==="list"]]),b(t("div",null,[t("div",it,[t("button",{class:"btn btn-ghost btn-sm",onClick:e[1]||(e[1]=n=>w())},"← 返回列表"),t("h2",rt,r(c.value?"编辑方案商":"新增方案商"),1)]),t("div",dt,[t("form",{onSubmit:N(j,["prevent"])},[t("div",ut,[e[10]||(e[10]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"方案商名称 *")],-1)),b(t("input",{"onUpdate:modelValue":e[2]||(e[2]=n=>o.name=n),type:"text",class:"input input-bordered w-full",required:""},null,512),[[S,o.name]])]),t("div",ct,[e[11]||(e[11]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"描述")],-1)),b(t("textarea",{"onUpdate:modelValue":e[3]||(e[3]=n=>o.description=n),class:"textarea textarea-bordered w-full",rows:"3"},null,512),[[S,o.description]])]),t("div",mt,[e[13]||(e[13]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"联系邮箱")],-1)),t("div",bt,[i.value.length?E("",!0):(a(),l("p",vt,"暂无邮箱")),(a(!0),l(k,null,C(i.value,(n,u)=>(a(),l("div",{key:u,class:"flex items-center gap-2"},[t("span",pt,[e[12]||(e[12]=t("svg",{class:"h-3 w-3 text-slate-400",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor"},[t("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"})],-1)),P(" "+r(n),1)]),t("button",{type:"button",class:"btn btn-ghost btn-xs text-red-400 hover:text-red-600",onClick:B=>U(u)},"×",8,ft)]))),128))]),t("div",xt,[b(t("input",{"onUpdate:modelValue":e[4]||(e[4]=n=>m.value=n),type:"email",class:"input input-bordered input-sm flex-1",placeholder:"输入邮箱地址",onKeydown:A(N($,["prevent"]),["enter"])},null,40,gt),[[S,m.value]]),t("button",{type:"button",class:"btn btn-outline btn-sm btn-primary",onClick:$},"添加")])]),t("div",ht,[t("button",{type:"button",class:"btn btn-ghost",onClick:e[5]||(e[5]=n=>w())},"取消"),t("button",{type:"submit",class:"btn btn-primary text-white",disabled:h.value},"保存",8,_t)])],32)])],512),[[D,v.value==="form"]])]))}});export{Mt as default}; diff --git a/apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/CO60jE1q.js b/apps/admin/.output/public/_nuxt/BIXaKwU_.js similarity index 97% rename from apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/CO60jE1q.js rename to apps/admin/.output/public/_nuxt/BIXaKwU_.js index b8cdd4ee..ee501bab 100644 --- a/apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/CO60jE1q.js +++ b/apps/admin/.output/public/_nuxt/BIXaKwU_.js @@ -1 +1 @@ -import{g as R,k as j,B as G,c as l,a as e,d as p,F as u,r as h,N as L,l as A,t as d,m as g,p as m,v as N,s as O,x as v,z as k,y as B,o as i,O as D,n as w,q as H,_ as J}from"./Ccu6Xgpt.js";import{u as Q}from"./Um-KoueI.js";import{u as W}from"./DvwKXRUn.js";import"./CH2ZVAK2.js";const X={class:"flex items-start justify-between mb-5 flex-wrap gap-3"},Y={key:0,class:"bg-white rounded-xl border border-slate-100 py-16 text-center"},Z={key:1,class:"bg-white rounded-xl border border-slate-100 py-16 text-center text-slate-400"},tt={key:2,class:"app-grid"},et=["onClick","onKeydown"],st={class:"ac-head"},at={class:"ac-logo"},nt={class:"min-w-0 flex-1"},ot={class:"ac-title"},lt={class:"ac-meta"},it={key:0,class:"chip"},dt={class:"ac-remark"},rt={class:"ac-stats"},ct={class:"ac-stat"},pt={class:"ac-stat"},ut={class:"ac-stat"},mt={class:"ac-regions"},vt={key:1,class:"text-xs text-slate-300"},bt=["onClick"],ft=["onClick"],xt=["onClick"],_t={key:0,class:"app-card orphan"},yt={class:"orphan-list"},ht={class:"min-w-0"},gt={class:"text-sm font-medium text-slate-700 truncate"},kt={class:"text-[11px] text-slate-400 font-mono"},wt=["onUpdate:modelValue"],Ct=["value"],$t=["disabled","onClick"],Vt={class:"modal-box max-w-lg"},Ut={class:"font-bold text-lg"},Mt={class:"form-control"},At={class:"form-control"},Nt={class:"form-control"},zt={class:"flex items-center gap-2 cursor-pointer pt-1"},St={class:"modal-action"},Bt=R({__name:"index",setup(Dt){const{consoleApi:r}=Q(),{success:C,error:b}=W(),F=j(),f=v([]),$=v([]),V=v(!1),c=B({}),T=k(()=>{const a=new Map;for(const t of $.value){const s=t.app_name||"";a.has(s)||a.set(s,[]),a.get(s).push(t)}return a}),z=k(()=>f.value.map(a=>{const t=T.value.get(a.name)||[];return{product:a,deployments:t,okCount:t.filter(s=>s.status!=="pending").length,pendingCount:t.filter(s=>s.status==="pending").length}})),U=k(()=>{const a=new Set(f.value.map(t=>t.name));return $.value.filter(t=>!t.app_name||!a.has(t.app_name))}),K=k(()=>z.value.length+(U.value.length?1:0));function P(a){return(a||"?").charAt(0).toUpperCase()}function x(a){F.push(`/apps/${encodeURIComponent(a)}`)}async function _(){V.value=!0;try{const[a,t]=await Promise.all([r("products/list",{}),r("apps/list",{})]);f.value=a??[],$.value=t??[]}catch(a){b(a?.message??"获取应用列表失败")}finally{V.value=!1}}const y=v(null),M=v(!1),n=B({id:0,name:"",image_name:"",remark:"",enabled:!0});function S(a){M.value=!!a,n.id=a?.id??0,n.name=a?.name??"",n.image_name=a?.image_name??"",n.remark=a?.remark??"",n.enabled=a?!!a.enabled:!0,y.value?.showModal()}async function q(){const a={name:n.name,image_name:n.image_name,remark:n.remark,enabled:n.enabled};let t="products/add";M.value&&n.id&&(a.id=Number(n.id),t="products/update");try{await r(t,a),C("保存成功"),y.value?.close(),await _()}catch(s){b(s?.message??"保存失败")}}function E(a){window.confirm(`删除应用「${a.name}」?(其下若有区域部署将被拒绝)`)&&r("products/del",{id:a.id}).then(()=>{C("已删除"),_()}).catch(t=>b(t?.message??"删除失败"))}async function I(a){const t=c[a.id];if(t)try{await r("apps/assign",{id:a.id,app_name:t}),C(`已归位到「${t}」`),delete c[a.id],await _()}catch(s){b(s?.message??"归位失败")}}return G(_),(a,t)=>(i(),l("div",null,[e("div",X,[t[7]||(t[7]=e("div",null,[e("h2",{class:"text-lg font-semibold text-slate-800"},"应用中心"),e("p",{class:"text-sm text-slate-400 mt-1 max-w-3xl"},[p(" 一张卡片 = 一个 "),e("span",{class:"chip chip-app"},"应用"),p(",卡片里是它在各区域的 "),e("span",{class:"chip chip-dep"},"部署"),p(" 概况。 点卡片进入应用详情:编辑应用、部署新环境、升级服务、改各项配置。 ")])],-1)),e("button",{class:"btn btn-primary btn-sm text-white",onClick:t[0]||(t[0]=s=>S())},"+ 添加应用")]),V.value?(i(),l("div",Y,[...t[8]||(t[8]=[e("span",{class:"loading loading-spinner loading-sm"},null,-1)])])):K.value?(i(),l("div",tt,[(i(!0),l(u,null,h(z.value,s=>(i(),l("article",{key:s.product.name,class:w(["app-card",{off:!s.product.enabled}]),tabindex:"0",role:"button",onClick:o=>x(s.product.name),onKeydown:[D(g(o=>x(s.product.name),["prevent"]),["enter"]),D(g(o=>x(s.product.name),["prevent"]),["space"])]},[e("div",st,[e("div",at,d(P(s.product.name)),1),e("div",nt,[e("div",ot,d(s.product.name),1),e("div",lt,d(s.product.image_name?"🐳 "+s.product.image_name:"未设置默认镜像"),1)]),s.product.enabled?A("",!0):(i(),l("span",it,"停用"))]),e("p",dt,d(s.product.remark||"—"),1),e("div",rt,[e("div",ct,[e("div",{class:w(["ac-stat-n",{zero:!s.deployments.length}])},d(s.deployments.length),3),t[9]||(t[9]=e("div",{class:"ac-stat-l"},"部署",-1))]),e("div",pt,[e("div",{class:w(["ac-stat-n",{zero:!s.okCount}])},d(s.okCount),3),t[10]||(t[10]=e("div",{class:"ac-stat-l"},"已接入",-1))]),e("div",ut,[e("div",{class:w(["ac-stat-n",s.pendingCount?"warn":"zero"])},d(s.pendingCount),3),t[11]||(t[11]=e("div",{class:"ac-stat-l"},"待部署",-1))])]),e("div",mt,[s.deployments.length?(i(!0),l(u,{key:0},h(s.deployments,o=>(i(),l("span",{key:o.id,class:"chip chip-dep"},[p(d(o.region||"未指定"),1),o.status==="pending"?(i(),l(u,{key:0},[p(" · 待部署")],64)):A("",!0)]))),128)):(i(),l("span",vt,"还没有任何部署"))]),e("div",{class:"ac-foot",onClick:t[1]||(t[1]=g(()=>{},["stop"]))},[e("button",{class:"btn btn-ghost btn-xs",onClick:o=>S(s.product)},"编辑",8,bt),e("button",{class:"btn btn-ghost btn-xs text-red-500",onClick:o=>E(s.product)},"删除",8,ft),e("button",{class:"btn btn-primary btn-xs text-white",onClick:o=>x(s.product.name)},"进入详情 →",8,xt)])],42,et))),128)),U.value.length?(i(),l("article",_t,[t[13]||(t[13]=L('
未分组部署
需要归位到某个应用
待归位

未填所属应用名、或应用已被删除的历史部署。选一个应用把它归位,之后就能在该应用详情里管理。

',2)),e("div",yt,[(i(!0),l(u,null,h(U.value,s=>(i(),l("div",{key:s.id,class:"orphan-row"},[e("div",ht,[e("div",gt,d(s.name||"部署#"+s.id),1),e("div",kt,"#"+d(s.id)+" · "+d(s.region||"未指定区域"),1)]),m(e("select",{"onUpdate:modelValue":o=>c[s.id]=o,class:"select select-bordered select-xs w-32"},[t[12]||(t[12]=e("option",{value:""},"选择应用…",-1)),(i(!0),l(u,null,h(f.value,o=>(i(),l("option",{key:o.id,value:o.name},d(o.name),9,Ct))),128))],8,wt),[[H,c[s.id]]]),e("button",{class:"btn btn-xs",disabled:!c[s.id],onClick:o=>I(s)},"归位",8,$t)]))),128))])])):A("",!0)])):(i(),l("div",Z," 暂无应用,先「添加应用」 ")),e("dialog",{ref_key:"appDlg",ref:y,class:"modal"},[e("div",Vt,[e("h3",Ut,d(M.value?"编辑应用":"添加应用"),1),t[19]||(t[19]=e("p",{class:"text-xs text-slate-400 mt-1"}," 应用名是关联键:部署、账号作用域、第三方服务配置都按它挂载,改名会断开已有关联。 ",-1)),e("form",{class:"mt-4 space-y-3",onSubmit:g(q,["prevent"])},[e("div",Mt,[t[14]||(t[14]=e("label",{class:"label py-1"},[e("span",{class:"label-text text-sm font-medium"},"应用名 *")],-1)),m(e("input",{"onUpdate:modelValue":t[2]||(t[2]=s=>n.name=s),type:"text",class:"input input-bordered input-sm w-full",required:"",placeholder:"如 Voitrans"},null,512),[[N,n.name]])]),e("div",At,[t[15]||(t[15]=e("label",{class:"label py-1"},[e("span",{class:"label-text text-sm font-medium"},"默认镜像名")],-1)),m(e("input",{"onUpdate:modelValue":t[3]||(t[3]=s=>n.image_name=s),type:"text",class:"input input-bordered input-sm w-full font-mono text-xs",placeholder:"voitrans-a11(新建部署时预填)"},null,512),[[N,n.image_name]])]),e("div",Nt,[t[16]||(t[16]=e("label",{class:"label py-1"},[e("span",{class:"label-text text-sm font-medium"},"备注")],-1)),m(e("input",{"onUpdate:modelValue":t[4]||(t[4]=s=>n.remark=s),type:"text",class:"input input-bordered input-sm w-full"},null,512),[[N,n.remark]])]),e("label",zt,[m(e("input",{"onUpdate:modelValue":t[5]||(t[5]=s=>n.enabled=s),type:"checkbox",class:"toggle toggle-primary toggle-sm"},null,512),[[O,n.enabled]]),t[17]||(t[17]=e("span",{class:"text-sm"},"启用",-1))]),e("div",St,[e("button",{type:"button",class:"btn btn-ghost btn-sm",onClick:t[6]||(t[6]=s=>y.value?.close())},"取消"),t[18]||(t[18]=e("button",{type:"submit",class:"btn btn-primary btn-sm text-white"},"保存",-1))])],32)]),t[20]||(t[20]=e("form",{method:"dialog",class:"modal-backdrop"},[e("button",null,"close")],-1))],512)]))}}),qt=J(Bt,[["__scopeId","data-v-6c9af955"]]);export{qt as default}; +import{g as R,k as j,B as G,c as l,a as e,d as p,F as u,r as h,N as L,l as A,t as d,m as g,p as m,v as N,s as O,x as v,z as k,y as B,o as i,O as D,n as w,q as H,_ as J}from"./mElhLwm2.js";import{u as Q}from"./C6twYRfy.js";import{u as W}from"./FVTAbpot.js";import"./qig5Qp6S.js";const X={class:"flex items-start justify-between mb-5 flex-wrap gap-3"},Y={key:0,class:"bg-white rounded-xl border border-slate-100 py-16 text-center"},Z={key:1,class:"bg-white rounded-xl border border-slate-100 py-16 text-center text-slate-400"},tt={key:2,class:"app-grid"},et=["onClick","onKeydown"],st={class:"ac-head"},at={class:"ac-logo"},nt={class:"min-w-0 flex-1"},ot={class:"ac-title"},lt={class:"ac-meta"},it={key:0,class:"chip"},dt={class:"ac-remark"},rt={class:"ac-stats"},ct={class:"ac-stat"},pt={class:"ac-stat"},ut={class:"ac-stat"},mt={class:"ac-regions"},vt={key:1,class:"text-xs text-slate-300"},bt=["onClick"],ft=["onClick"],xt=["onClick"],_t={key:0,class:"app-card orphan"},yt={class:"orphan-list"},ht={class:"min-w-0"},gt={class:"text-sm font-medium text-slate-700 truncate"},kt={class:"text-[11px] text-slate-400 font-mono"},wt=["onUpdate:modelValue"],Ct=["value"],$t=["disabled","onClick"],Vt={class:"modal-box max-w-lg"},Ut={class:"font-bold text-lg"},Mt={class:"form-control"},At={class:"form-control"},Nt={class:"form-control"},zt={class:"flex items-center gap-2 cursor-pointer pt-1"},St={class:"modal-action"},Bt=R({__name:"index",setup(Dt){const{consoleApi:r}=Q(),{success:C,error:b}=W(),F=j(),f=v([]),$=v([]),V=v(!1),c=B({}),T=k(()=>{const a=new Map;for(const t of $.value){const s=t.app_name||"";a.has(s)||a.set(s,[]),a.get(s).push(t)}return a}),z=k(()=>f.value.map(a=>{const t=T.value.get(a.name)||[];return{product:a,deployments:t,okCount:t.filter(s=>s.status!=="pending").length,pendingCount:t.filter(s=>s.status==="pending").length}})),U=k(()=>{const a=new Set(f.value.map(t=>t.name));return $.value.filter(t=>!t.app_name||!a.has(t.app_name))}),K=k(()=>z.value.length+(U.value.length?1:0));function P(a){return(a||"?").charAt(0).toUpperCase()}function x(a){F.push(`/apps/${encodeURIComponent(a)}`)}async function _(){V.value=!0;try{const[a,t]=await Promise.all([r("products/list",{}),r("apps/list",{})]);f.value=a??[],$.value=t??[]}catch(a){b(a?.message??"获取应用列表失败")}finally{V.value=!1}}const y=v(null),M=v(!1),n=B({id:0,name:"",image_name:"",remark:"",enabled:!0});function S(a){M.value=!!a,n.id=a?.id??0,n.name=a?.name??"",n.image_name=a?.image_name??"",n.remark=a?.remark??"",n.enabled=a?!!a.enabled:!0,y.value?.showModal()}async function q(){const a={name:n.name,image_name:n.image_name,remark:n.remark,enabled:n.enabled};let t="products/add";M.value&&n.id&&(a.id=Number(n.id),t="products/update");try{await r(t,a),C("保存成功"),y.value?.close(),await _()}catch(s){b(s?.message??"保存失败")}}function E(a){window.confirm(`删除应用「${a.name}」?(其下若有区域部署将被拒绝)`)&&r("products/del",{id:a.id}).then(()=>{C("已删除"),_()}).catch(t=>b(t?.message??"删除失败"))}async function I(a){const t=c[a.id];if(t)try{await r("apps/assign",{id:a.id,app_name:t}),C(`已归位到「${t}」`),delete c[a.id],await _()}catch(s){b(s?.message??"归位失败")}}return G(_),(a,t)=>(i(),l("div",null,[e("div",X,[t[7]||(t[7]=e("div",null,[e("h2",{class:"text-lg font-semibold text-slate-800"},"应用中心"),e("p",{class:"text-sm text-slate-400 mt-1 max-w-3xl"},[p(" 一张卡片 = 一个 "),e("span",{class:"chip chip-app"},"应用"),p(",卡片里是它在各区域的 "),e("span",{class:"chip chip-dep"},"部署"),p(" 概况。 点卡片进入应用详情:编辑应用、部署新环境、升级服务、改各项配置。 ")])],-1)),e("button",{class:"btn btn-primary btn-sm text-white",onClick:t[0]||(t[0]=s=>S())},"+ 添加应用")]),V.value?(i(),l("div",Y,[...t[8]||(t[8]=[e("span",{class:"loading loading-spinner loading-sm"},null,-1)])])):K.value?(i(),l("div",tt,[(i(!0),l(u,null,h(z.value,s=>(i(),l("article",{key:s.product.name,class:w(["app-card",{off:!s.product.enabled}]),tabindex:"0",role:"button",onClick:o=>x(s.product.name),onKeydown:[D(g(o=>x(s.product.name),["prevent"]),["enter"]),D(g(o=>x(s.product.name),["prevent"]),["space"])]},[e("div",st,[e("div",at,d(P(s.product.name)),1),e("div",nt,[e("div",ot,d(s.product.name),1),e("div",lt,d(s.product.image_name?"🐳 "+s.product.image_name:"未设置默认镜像"),1)]),s.product.enabled?A("",!0):(i(),l("span",it,"停用"))]),e("p",dt,d(s.product.remark||"—"),1),e("div",rt,[e("div",ct,[e("div",{class:w(["ac-stat-n",{zero:!s.deployments.length}])},d(s.deployments.length),3),t[9]||(t[9]=e("div",{class:"ac-stat-l"},"部署",-1))]),e("div",pt,[e("div",{class:w(["ac-stat-n",{zero:!s.okCount}])},d(s.okCount),3),t[10]||(t[10]=e("div",{class:"ac-stat-l"},"已接入",-1))]),e("div",ut,[e("div",{class:w(["ac-stat-n",s.pendingCount?"warn":"zero"])},d(s.pendingCount),3),t[11]||(t[11]=e("div",{class:"ac-stat-l"},"待部署",-1))])]),e("div",mt,[s.deployments.length?(i(!0),l(u,{key:0},h(s.deployments,o=>(i(),l("span",{key:o.id,class:"chip chip-dep"},[p(d(o.region||"未指定"),1),o.status==="pending"?(i(),l(u,{key:0},[p(" · 待部署")],64)):A("",!0)]))),128)):(i(),l("span",vt,"还没有任何部署"))]),e("div",{class:"ac-foot",onClick:t[1]||(t[1]=g(()=>{},["stop"]))},[e("button",{class:"btn btn-ghost btn-xs",onClick:o=>S(s.product)},"编辑",8,bt),e("button",{class:"btn btn-ghost btn-xs text-red-500",onClick:o=>E(s.product)},"删除",8,ft),e("button",{class:"btn btn-primary btn-xs text-white",onClick:o=>x(s.product.name)},"进入详情 →",8,xt)])],42,et))),128)),U.value.length?(i(),l("article",_t,[t[13]||(t[13]=L('
未分组部署
需要归位到某个应用
待归位

未填所属应用名、或应用已被删除的历史部署。选一个应用把它归位,之后就能在该应用详情里管理。

',2)),e("div",yt,[(i(!0),l(u,null,h(U.value,s=>(i(),l("div",{key:s.id,class:"orphan-row"},[e("div",ht,[e("div",gt,d(s.name||"部署#"+s.id),1),e("div",kt,"#"+d(s.id)+" · "+d(s.region||"未指定区域"),1)]),m(e("select",{"onUpdate:modelValue":o=>c[s.id]=o,class:"select select-bordered select-xs w-32"},[t[12]||(t[12]=e("option",{value:""},"选择应用…",-1)),(i(!0),l(u,null,h(f.value,o=>(i(),l("option",{key:o.id,value:o.name},d(o.name),9,Ct))),128))],8,wt),[[H,c[s.id]]]),e("button",{class:"btn btn-xs",disabled:!c[s.id],onClick:o=>I(s)},"归位",8,$t)]))),128))])])):A("",!0)])):(i(),l("div",Z," 暂无应用,先「添加应用」 ")),e("dialog",{ref_key:"appDlg",ref:y,class:"modal"},[e("div",Vt,[e("h3",Ut,d(M.value?"编辑应用":"添加应用"),1),t[19]||(t[19]=e("p",{class:"text-xs text-slate-400 mt-1"}," 应用名是关联键:部署、账号作用域、第三方服务配置都按它挂载,改名会断开已有关联。 ",-1)),e("form",{class:"mt-4 space-y-3",onSubmit:g(q,["prevent"])},[e("div",Mt,[t[14]||(t[14]=e("label",{class:"label py-1"},[e("span",{class:"label-text text-sm font-medium"},"应用名 *")],-1)),m(e("input",{"onUpdate:modelValue":t[2]||(t[2]=s=>n.name=s),type:"text",class:"input input-bordered input-sm w-full",required:"",placeholder:"如 Voitrans"},null,512),[[N,n.name]])]),e("div",At,[t[15]||(t[15]=e("label",{class:"label py-1"},[e("span",{class:"label-text text-sm font-medium"},"默认镜像名")],-1)),m(e("input",{"onUpdate:modelValue":t[3]||(t[3]=s=>n.image_name=s),type:"text",class:"input input-bordered input-sm w-full font-mono text-xs",placeholder:"voitrans-a11(新建部署时预填)"},null,512),[[N,n.image_name]])]),e("div",Nt,[t[16]||(t[16]=e("label",{class:"label py-1"},[e("span",{class:"label-text text-sm font-medium"},"备注")],-1)),m(e("input",{"onUpdate:modelValue":t[4]||(t[4]=s=>n.remark=s),type:"text",class:"input input-bordered input-sm w-full"},null,512),[[N,n.remark]])]),e("label",zt,[m(e("input",{"onUpdate:modelValue":t[5]||(t[5]=s=>n.enabled=s),type:"checkbox",class:"toggle toggle-primary toggle-sm"},null,512),[[O,n.enabled]]),t[17]||(t[17]=e("span",{class:"text-sm"},"启用",-1))]),e("div",St,[e("button",{type:"button",class:"btn btn-ghost btn-sm",onClick:t[6]||(t[6]=s=>y.value?.close())},"取消"),t[18]||(t[18]=e("button",{type:"submit",class:"btn btn-primary btn-sm text-white"},"保存",-1))])],32)]),t[20]||(t[20]=e("form",{method:"dialog",class:"modal-backdrop"},[e("button",null,"close")],-1))],512)]))}}),qt=J(Bt,[["__scopeId","data-v-6c9af955"]]);export{qt as default}; diff --git a/apps/admin/.output/public/_nuxt/BtOu2QXF.js b/apps/admin/.output/public/_nuxt/BJhUngVd.js similarity index 99% rename from apps/admin/.output/public/_nuxt/BtOu2QXF.js rename to apps/admin/.output/public/_nuxt/BJhUngVd.js index 0817ba22..65f16f76 100644 --- a/apps/admin/.output/public/_nuxt/BtOu2QXF.js +++ b/apps/admin/.output/public/_nuxt/BJhUngVd.js @@ -1 +1 @@ -import{_ as Xe}from"./szhsDUYv.js";import{g as Ye,B as Ze,c as a,l as h,a as e,d as M,p as c,q as I,F as b,r as k,t as d,m as Ve,L as D,v as y,s as L,n as A,H as Ue,x as m,y as Ce,z as q,o,I as z,C as Z,_ as et}from"./Ccu6Xgpt.js";import{u as tt}from"./Um-KoueI.js";import{u as lt}from"./DvwKXRUn.js";import"./ChQPCk92.js";import"./CH2ZVAK2.js";const st={key:0,class:"mb-4 rounded-lg px-4 py-3 text-sm",style:{background:"#fffbeb",border:"1px solid #fde68a",color:"#92400e"}},ot={class:"flex items-center justify-between mb-5"},nt={class:"flex items-center gap-3"},at=["value"],it=["value"],dt={key:1,class:"rounded-lg px-3 py-2 mb-4 text-xs",style:{background:"#fefce8",border:"1px solid #fde047",color:"#854d0e"}},ut={key:2,class:"flex flex-col gap-6"},rt={class:"flex items-center gap-2 mb-3"},ct={class:"text-sm font-semibold text-slate-700"},pt={class:"text-xs text-slate-400"},vt={class:"svc-grid"},bt=["onClick"],mt={class:"flex items-start gap-3"},xt={style:{"min-width":"0",flex:"1"}},yt={class:"flex items-center gap-2"},_t={class:"font-semibold text-slate-800 text-sm truncate"},ht=["title"],kt={class:"text-xs text-slate-500 mt-2 line-clamp-2",style:{"min-height":"32px"}},gt={class:"flex flex-wrap items-center gap-1 mt-2"},ft={key:0,class:"provider-chip"},wt={class:"field-count"},Vt={key:1,class:"lock-badge"},Ut=["onClick"],Ct={class:"text-xs text-slate-400 mt-1"},St={key:3,class:"bg-white rounded-2xl border border-slate-100 shadow-sm text-center text-slate-300 py-20"},Tt={class:"svc-box"},$t={class:"flex items-center justify-between mb-5"},Mt={class:"flex items-center gap-3"},At={class:"text-base font-semibold text-slate-800"},zt={class:"text-xs text-slate-400 mt-0.5"},Ft={key:0},Dt={class:"flex gap-2"},Lt={class:"grid grid-cols-2 gap-4 mb-4"},jt={class:"form-control"},Et={class:"form-control"},It={class:"form-control mb-4"},Nt={class:"mb-4"},Rt={class:"text-xs text-slate-500 ml-2"},Bt={key:0,class:"text-xs text-slate-400 py-4 text-center"},Ot={key:1,class:"overflow-x-auto"},Ht={class:"table text-xs"},Pt=["onUpdate:modelValue","title"],Jt=["onUpdate:modelValue"],qt={class:"text-center"},Gt=["onUpdate:modelValue"],Kt={class:"relative"},Qt=["type","onUpdate:modelValue"],Wt=["onClick"],Xt=["onUpdate:modelValue"],Yt=["onUpdate:modelValue"],Zt=["onClick"],el={class:"wizard-steps mb-5"},tl={key:0},ll={key:0},sl={class:"type-grid"},ol=["onClick"],nl={class:"text-sm text-slate-700 mt-2"},al={class:"flex items-center justify-between mb-3"},il={class:"text-sm text-slate-500"},dl={class:"type-grid"},ul=["onClick"],rl={class:"provider-chip"},cl={class:"text-sm text-slate-700 mt-2"},pl={class:"text-[11px] text-slate-400 mt-0.5"},vl={key:0,class:"text-xs text-slate-400 mt-2"},bl={class:"flex items-center justify-between mb-3"},ml={class:"flex items-center gap-2"},xl={key:0,class:"provider-chip"},yl={class:"flex gap-2"},_l={class:"grid grid-cols-2 gap-4 mb-4"},hl={class:"form-control"},kl={class:"form-control"},gl={class:"grid grid-cols-2 gap-4 mb-4"},fl={class:"form-control"},wl={class:"form-control"},Vl={class:"form-control mb-4"},Ul={key:0,class:"text-xs text-slate-400 py-4 text-center"},Cl={key:1,class:"overflow-x-auto"},Sl={class:"table text-xs"},Tl=["onUpdate:modelValue","title"],$l=["onUpdate:modelValue"],Ml={class:"text-center"},Al=["onUpdate:modelValue"],zl={class:"relative"},Fl=["type","onUpdate:modelValue"],Dl=["onClick"],Ll=["onUpdate:modelValue"],jl=["onUpdate:modelValue"],El=["onClick"],Il={key:0,class:"text-center py-10 text-slate-400"},Nl={class:"flex items-center justify-between mb-5"},Rl={class:"flex items-center gap-3"},Bl={class:"text-base font-semibold text-slate-800"},Ol={class:"badge badge-warning badge-sm mt-0.5"},Hl={class:"flex gap-2"},Pl={class:"rounded-lg px-3 py-2 mb-4 text-xs",style:{background:"#fefce8",border:"1px solid #fde047",color:"#854d0e"}},Jl={class:"overflow-x-auto"},ql={class:"table text-xs"},Gl=["title"],Kl={class:"text-slate-500"},Ql={class:"text-center"},Wl={key:0,class:"disabled-badge"},Xl={key:1,class:"override-badge"},Yl={key:2,class:"inherit-badge"},Zl={class:"text-center"},es=["onUpdate:modelValue"],ts={class:"relative"},ls=["type","onUpdate:modelValue","disabled"],ss=["onClick"],os=["onUpdate:modelValue","disabled"],ns=["onUpdate:modelValue","disabled","placeholder"],as={key:0},is={class:"divider text-xs text-slate-400 my-3"},ds={key:0,class:"text-xs text-slate-400 py-2 text-center"},us={key:1,class:"overflow-x-auto"},rs={class:"table text-xs"},cs=["onUpdate:modelValue","title"],ps=["onUpdate:modelValue"],vs={class:"text-center"},bs=["onUpdate:modelValue"],ms={class:"relative"},xs=["type","onUpdate:modelValue"],ys=["onClick"],_s=["onUpdate:modelValue"],hs=["onClick"],ks={class:"modal-overlay",style:{"z-index":"120"}},gs={class:"sync-box"},fs={class:"flex items-start gap-3 mb-4"},ws={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"}},Vs={style:{width:"20px",height:"20px",color:"#fff"},fill:"none",viewBox:"0 0 24 24",stroke:"currentColor"},Us={class:"text-xs text-slate-400 mt-1"},Cs=["innerHTML"],Ss={class:"flex items-center justify-between mb-1"},Ts={class:"flex gap-2"},$s={class:"sync-region-grid"},Ms=["onClick"],As=["checked","onClick"],zs={class:"modal-overlay",style:{"z-index":"130"}},Fs={class:"tpl-box"},Ds={class:"flex items-center justify-between mb-4"},Ls={class:"flex gap-2"},js={class:"tpl-list"},Es={class:"text-xs font-semibold text-slate-500 mb-1"},Is={style:{"min-width":"0",flex:"1"}},Ns={class:"flex items-center gap-2"},Rs={class:"font-semibold text-sm text-slate-800 truncate"},Bs={class:"provider-chip"},Os={key:0,class:"badge badge-xs badge-ghost"},Hs={class:"text-xs text-slate-400 mt-0.5"},Ps={class:"flex gap-1"},Js=["onClick"],qs=["onClick"],Gs={key:0,class:"text-xs text-slate-400 text-center py-6"},Ks={class:"flex items-center justify-between mb-4"},Qs={class:"text-base font-semibold text-slate-800"},Ws={class:"flex gap-2"},Xs={class:"grid grid-cols-2 gap-3 mb-3"},Ys={class:"form-control"},Zs=["disabled"],eo={class:"form-control"},to=["value"],lo={class:"form-control"},so={class:"form-control"},oo={class:"form-control mb-3"},no={class:"overflow-x-auto",style:{"max-height":"34vh"}},ao={class:"table text-xs"},io=["onUpdate:modelValue","title"],uo=["onUpdate:modelValue"],ro={class:"text-center"},co=["onUpdate:modelValue"],po=["onUpdate:modelValue"],vo=["onClick"],bo={key:0},Se=10,mo=Ye({__name:"serviceconfig",setup(xo){const G=[{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:"印度"}],N=[{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:V,consoleApi:Te}=tt(),{success:j,error:U}=lt(),T=m(""),ee=m([]);async function $e(){try{const s=await Te("products/list",{});ee.value=(s??[]).map(l=>l.name).filter(Boolean)}catch{ee.value=[]}}function Me(){w(),X()}function C(s){return N.find(l=>l.v===s)||{short:"?",color:"#999",bg:"#eee",v:0,label:""}}function te(){return x.value===Se?!0:!!p.value&&K(p.value.categories).includes(Se)}function K(s){return(s||"").split(",").map(l=>parseInt(l)||0).filter(l=>l>0)}function ue(s){return(s.fields||[]).filter(l=>l.encrypted).length}const le=m(!0),R=m([]),p=m(null),f=m(0),Q=m(!1),E=m("default"),u=Ce({id:"",name:"",provider:"",description:"",enable:!1}),x=m(0),g=m([]),B=m(""),_=m(1),O=m([]),F=m([]),se=m(!1),H=m([]),W=q(()=>{const s=G.find(l=>l.value===f.value);return s?s.label:"区域"+f.value}),re=q(()=>{const s=N.map(r=>({...r,items:R.value.filter(t=>K(t.categories).includes(r.v))})).filter(r=>r.items.length),l=R.value.filter(r=>!K(r.categories).length);return l.length&&s.push({v:0,label:"未分类",short:"未分类",color:"#64748b",bg:"#f1f5f9",items:l}),s}),Ae=q(()=>N.map(s=>({cat:s.v,label:s.label,items:H.value.filter(l=>l.category===s.v)})).filter(s=>s.items.length));async function X(){try{const s=await V("getsvcconfigs",{app_name:T.value});R.value=s?.items??[],le.value=!0}catch{le.value=!1,R.value=[];return}if(p.value){const s=R.value.find(l=>l.id===p.value.id);s&&(p.value=s)}}async function Y(){try{const s=await V("getsvctemplates",{});H.value=s?.items??[]}catch{H.value=[]}}function ze(){w()}function Fe(s){s&&(p.value=s,Q.value=!0,f.value===0?De():je())}function w(){Q.value=!1,p.value=null}function De(){const s=p.value;u.id=s.id,u.name=s.name||"",u.provider=s.provider||"",u.description=s.description||"",u.enable=!!s.enable,x.value=K(s.categories)[0]||0,g.value=JSON.parse(JSON.stringify(s.fields||[])).map(l=>({...l,_show:!1})),E.value="default"}function oe(s=0){p.value=null,u.id="",u.name="",u.provider="",u.description="",u.enable=!1,x.value=s,g.value=[],B.value="",_.value=s?2:1,E.value="new",Q.value=!0}const ce=q(()=>H.value.filter(s=>s.category===x.value));function Le(s){x.value!==s&&(x.value=s,B.value="",u.provider="",g.value=[]),_.value=2}function pe(s){s?(B.value=s.id,u.provider=s.provider||"",u.name||(u.name=s.name||""),u.id||(u.id=s.id||""),u.description||(u.description=s.description||""),g.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}))):(B.value="",u.provider="",g.value=[]),_.value=3}function ve(){g.value.push({key:"",description:"",encrypted:!1,def_value:"",sort:g.value.length,_show:!1})}function be(s){g.value.splice(s,1),g.value.forEach((l,r)=>{l.sort=r})}async function je(){const s=p.value;se.value=!0,E.value="region";try{const r=(await V("getsvcregionoverride",{app_name:T.value,svc_id:s.id,region:f.value}))?.fields??[];O.value=r.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})),F.value=r.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){U(l?.message??"加载区域分叉失败"),O.value=[],F.value=[]}finally{se.value=!1}}function Ee(){F.value.push({key:"",description:"",encrypted:!1,_input:"",_show:!1})}function Ie(s){F.value.splice(s,1)}function Ne(s){const l={name:u.name||"",provider:u.provider||"",description:u.description||"",categories:x.value?String(x.value):"",enable:u.enable||!1,fields:g.value.map(r=>({key:r.key,description:r.description,type:r.type||"",encrypted:r.encrypted,def_value:r.def_value,sort:r.sort}))};return s?l.id=u.id||"":l.id=p.value.id,l.app_name=T.value,l}function Re(){const s={},l=[];O.value.forEach(t=>{s[t.key]=t._input||"",t.disabled&&l.push(t.key)});const r=F.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:r}}async function me(s){const l=s||!p.value;if(f.value===0){const r=Ne(l);if(!r.id||!r.name)return U("服务ID 和名称 必填"),!1;const t=l?"addsvcconfig":"updatesvcconfig";try{const i=await V(t,r);return p.value=i,await X(),j("保存成功"),!0}catch(i){return U(i?.message??"保存失败"),!1}}else{const{overrides:r,disabled_keys:t,extra_fields:i}=Re();try{return await V("savesvcregionoverride",{app_name:T.value,svc_id:p.value.id,region:f.value,overrides:r,disabled_keys:t,extra_fields:i}),j("区域分叉已保存"),!0}catch(n){return U(n?.message??"保存失败"),!1}}}async function Be(){if(p.value&&window.confirm("确定删除服务「"+p.value.name+"」及其所有区域分叉?")){try{await V("delsvcconfig",{app_name:T.value,id:p.value.id})}catch(s){U(s?.message??"删除失败");return}w(),j("已删除"),await X()}}const ne=m(!1),ae=m(!1),xe=m(""),ye=m(""),$=m([]),_e=q(()=>G.filter(s=>s.value!==f.value));function ie(s){ae.value=s;const l=p.value?p.value.name:u.name||"新服务",r=f.value===0;xe.value=r?"「"+l+"」默认配置将保存,可同步推送到其他区域。":"「"+l+"」在当前区域的字段分叉将保存,可同步到其他区域。",ye.value=r?"✦ 同步内容:各字段默认值推送为目标区域「覆盖值」,目标区域原有分叉将被替换。":"✦ 同步内容:当前区域的值覆盖 / 区域专属字段 / 停用字段整体复制到目标区域。",$.value=[],ne.value=!0}function he(s){const l=$.value.indexOf(s);l>=0?$.value.splice(l,1):$.value.push(s)}function ke(s){$.value=s?_e.value.map(l=>l.value):[]}function ge(){ne.value=!1}async function Oe(){ge(),await me(ae.value)&&w()}async function He(){const s=$.value.slice();if(ge(),!await me(ae.value))return;const r=p.value?p.value.id:null;if(!s.length||!r){w();return}let t=0;try{t=(await V("syncsvctoregins",{app_name:T.value,svc_id:r,src_region:f.value,target_regions:s}))?.synced??0}catch(n){U(n?.message??"同步失败");return}const i=s.map(n=>{const we=G.find(We=>We.value===n);return we?we.label:"区域"+n});j("已保存并同步到:"+i.join("、")+"("+t+" 个)"),w()}const de=m(!1),P=m("list"),J=m(!1),v=Ce({id:"",category:2,provider:"",name:"",description:""}),S=m([]);function Pe(){P.value="list",de.value=!0,Y()}function Je(){de.value=!1}function fe(s){s?(J.value=!0,v.id=s.id,v.category=s.category||2,v.provider=s.provider||"",v.name=s.name||"",v.description=s.description||"",S.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}))):(J.value=!1,v.id="",v.category=2,v.provider="",v.name="",v.description="",S.value=[]),P.value="form"}function qe(){S.value.push({key:"",description:"",encrypted:!1,def_value:"",sort:S.value.length})}function Ge(s){S.value.splice(s,1),S.value.forEach((l,r)=>{l.sort=r})}async function Ke(){if(!v.id.trim()||!v.name.trim()||!v.provider.trim()){U("模板ID / 展示名 / 服务商标识 必填");return}const s={id:v.id.trim(),category:Number(v.category)||0,provider:v.provider.trim(),name:v.name.trim(),description:v.description.trim(),fields:S.value.map((l,r)=>({key:l.key,description:l.description,type:l.type||"",encrypted:l.encrypted,def_value:l.def_value,sort:r}))};try{await V(J.value?"updatesvctemplate":"addsvctemplate",s)}catch(l){U(l?.message??"保存失败");return}j("模板已保存"),await Y(),P.value="list"}async function Qe(s){if(window.confirm("确定删除模板「"+s.name+"」?"+(s.builtin?"(内置模板下次启动会被重新补回)":""))){try{await V("delsvctemplate",{id:s.id})}catch(l){U(l?.message??"删除失败");return}j("已删除"),await Y()}}return Ze(()=>{$e(),X(),Y()}),(s,l)=>{const r=Xe;return o(),a("div",null,[le.value?h("",!0):(o(),a("div",st," ⚠ 「第三方服务配置」后端接口暂不可用(连接失败),请检查 console 服务是否运行。 ")),e("div",ot,[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"},[M("按服务类型分组管理已接入的第三方服务(火山引擎、阿里云、Azure 等)。默认展示"),e("b",null,"全局默认"),M("配置,可切换到具体应用;区域默认"),e("b",null,"中国"),M(",切换区域后点击卡片可为该区域覆盖字段值。")])],-1)),e("div",nt,[c(e("select",{"onUpdate:modelValue":l[0]||(l[0]=t=>T.value=t),class:"select select-bordered select-sm",onChange:Me},[l[29]||(l[29]=e("option",{value:""},"全局默认",-1)),(o(!0),a(b,null,k(ee.value,t=>(o(),a("option",{key:t,value:t},"应用:"+d(t),9,at))),128))],544),[[I,T.value]]),c(e("select",{"onUpdate:modelValue":l[1]||(l[1]=t=>f.value=t),class:"select select-bordered select-sm",onChange:ze},[l[30]||(l[30]=e("option",{value:0},"默认(全区域)",-1)),(o(),a(b,null,k(G,t=>e("option",{key:t.value,value:t.value},d(t.label),9,it)),64))],544),[[I,f.value,void 0,{number:!0}]]),e("button",{class:"btn btn-ghost btn-sm",onClick:Pe},"服务商模板"),e("button",{class:"btn btn-primary btn-sm text-white",onClick:l[2]||(l[2]=t=>oe())},"+ 添加服务")])]),f.value!==0?(o(),a("div",dt," ✦ 当前处于「"+d(W.value)+"」区域视图:点击服务卡片编辑该区域的字段分叉(覆盖值 / 停用字段 / 区域专属字段)。要改服务本身的默认配置,请切回「默认(全区域)」。 ",1)):h("",!0),re.value.length?(o(),a("div",ut,[(o(!0),a(b,null,k(re.value,t=>(o(),a("section",{key:t.v},[e("div",rt,[e("span",{class:"cat-chip",style:D({color:t.color,background:t.bg})},d(t.short),5),e("h3",ct,d(t.label),1),e("span",pt,d(t.items.length)+" 个服务",1),l[32]||(l[32]=e("div",{class:"flex-1 h-px bg-slate-100 ml-2"},null,-1))]),e("div",vt,[(o(!0),a(b,null,k(t.items,i=>(o(),a("div",{key:i.id,class:"svc-card",onClick:n=>Fe(i)},[e("div",mt,[e("div",{class:"svc-logo",style:D({background:i.color||"#6366f1"})},d(i.icon||(i.name||"").charAt(0)),5),e("div",xt,[e("div",yt,[e("span",_t,d(i.name),1),e("span",{class:A(["badge badge-xs",i.enable?"badge-success":"badge-ghost"])},d(i.enable?"启用":"停用"),3)]),e("p",{class:"text-[11px] text-slate-400 font-mono truncate mt-0.5",title:i.id},d(i.id),9,ht)])]),e("p",kt,d(i.description||"—"),1),e("div",gt,[i.provider?(o(),a("span",ft,d(i.provider),1)):h("",!0),e("span",wt,d((i.fields||[]).length)+" 字段",1),ue(i)?(o(),a("span",Vt,"🔒"+d(ue(i)),1)):h("",!0)])],8,bt))),128)),e("div",{class:"svc-card add-card",onClick:i=>oe(t.v)},[l[33]||(l[33]=e("span",{class:"text-2xl text-slate-300"},"+",-1)),e("span",Ct,"添加"+d(t.short)+"服务",1)],8,Ut)])]))),128))])):(o(),a("div",St,[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=>oe())},"+ 添加服务")])),Q.value?(o(),a("div",{key:4,class:"modal-overlay",onClick:Ve(w,["self"])},[e("div",Tt,[E.value==="default"&&p.value?(o(),a(b,{key:0},[e("div",$t,[e("div",Mt,[e("div",{class:"svc-logo",style:D({background:p.value.color||"#6366f1",width:"44px",height:"44px",fontSize:"20px"})},d(p.value.icon||(p.value.name||"").charAt(0)),5),e("div",null,[e("h3",At,d(p.value.name),1),e("p",zt,[M(d(p.value.id),1),u.provider?(o(),a("span",Ft," · 服务商 "+d(u.provider),1)):h("",!0)])])]),e("div",Dt,[e("button",{class:"btn btn-error btn-sm btn-outline",onClick:Be},"删除服务"),e("button",{class:"btn btn-primary btn-sm text-white",onClick:l[4]||(l[4]=t=>ie(!1))},"保存"),e("button",{class:"btn btn-ghost btn-sm",onClick:w},"关闭")])]),l[44]||(l[44]=e("div",{class:"divider text-xs text-slate-400 my-3"},"基本信息",-1)),e("div",Lt,[e("div",jt,[l[36]||(l[36]=e("label",{class:"label"},[e("span",{class:"label-text"},"服务名称 *")],-1)),c(e("input",{"onUpdate:modelValue":l[5]||(l[5]=t=>u.name=t),class:"input input-bordered"},null,512),[[y,u.name]])]),e("div",Et,[l[37]||(l[37]=e("label",{class:"label"},[e("span",{class:"label-text"},"启用")],-1)),c(e("input",{"onUpdate:modelValue":l[6]||(l[6]=t=>u.enable=t),type:"checkbox",class:"toggle toggle-primary mt-3"},null,512),[[L,u.enable]])])]),e("div",It,[l[38]||(l[38]=e("label",{class:"label"},[e("span",{class:"label-text"},"服务描述")],-1)),c(e("input",{"onUpdate:modelValue":l[7]||(l[7]=t=>u.description=t),class:"input input-bordered"},null,512),[[y,u.description]])]),e("div",Nt,[l[39]||(l[39]=e("p",{class:"text-sm font-medium text-slate-700 mb-2"},"服务类型",-1)),x.value?(o(),a("span",{key:0,class:"cat-chip",style:D({color:C(x.value).color,background:C(x.value).bg})},d(C(x.value).short),5)):h("",!0),e("span",Rt,d(x.value?C(x.value).label:"未设置"),1),l[40]||(l[40]=e("span",{class:"text-[11px] text-slate-400 ml-2"},"(类型在创建时确定,不可更改)",-1))]),l[45]||(l[45]=e("div",{class:"divider text-xs text-slate-400 my-3"},"配置字段(全区域共用)",-1)),e("div",null,[g.value.length?(o(),a("div",Ot,[e("table",Ht,[l[43]||(l[43]=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,[(o(!0),a(b,null,k(g.value,(t,i)=>(o(),a("tr",{key:i},[e("td",null,[c(e("input",{class:"field-input","onUpdate:modelValue":n=>t.key=n,placeholder:"key",title:t.key},null,8,Pt),[[y,t.key]])]),e("td",null,[c(e("input",{class:"field-input","onUpdate:modelValue":n=>t.description=n,placeholder:"用途描述"},null,8,Jt),[[y,t.description]])]),e("td",qt,[c(e("input",{type:"checkbox",class:"checkbox checkbox-xs checkbox-primary","onUpdate:modelValue":n=>t.encrypted=n},null,8,Gt),[[L,t.encrypted]])]),e("td",null,[t.type==="langs"?(o(),z(r,{key:0,modelValue:t.def_value,"onUpdate:modelValue":n=>t.def_value=n,multiple:!0},null,8,["modelValue","onUpdate:modelValue"])):t.type==="lang"?(o(),z(r,{key:1,modelValue:t.def_value,"onUpdate:modelValue":n=>t.def_value=n},null,8,["modelValue","onUpdate:modelValue"])):t.encrypted?(o(),a(b,{key:2},[e("div",Kt,[c(e("input",{type:t._show?"text":"password",class:"field-input pr-14","onUpdate:modelValue":n=>t.def_value=n,placeholder:"留空保留原值"},null,8,Qt),[[Z,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:n=>t._show=!t._show},d(t._show?"隐藏":"显示"),9,Wt)]),l[41]||(l[41]=e("span",{class:"lock-badge ml-1"},"🔒 加密",-1))],64)):te()&&t.key==="type"?c((o(),a("select",{key:3,class:"field-input","onUpdate:modelValue":n=>t.def_value=n},[...l[42]||(l[42]=[e("option",{value:"0"},"HTTP",-1),e("option",{value:"1"},"SSE",-1)])],8,Xt)),[[I,t.def_value]]):c((o(),a("input",{key:4,class:"field-input","onUpdate:modelValue":n=>t.def_value=n},null,8,Yt)),[[y,t.def_value]])]),e("td",null,[e("button",{class:"btn btn-ghost btn-xs text-error",onClick:n=>be(i)},"×",8,Zt)])]))),128))])])])):(o(),a("p",Bt,"尚无字段,点击下方添加")),e("button",{class:"btn btn-ghost btn-sm mt-2 text-primary",onClick:ve},"+ 添加字段")])],64)):E.value==="new"?(o(),a(b,{key:1},[e("div",{class:"flex items-center justify-between mb-4"},[l[46]||(l[46]=e("h3",{class:"text-base font-semibold text-slate-800"},"新增第三方服务",-1)),e("button",{class:"btn btn-ghost btn-sm",onClick:w},"取消")]),e("div",el,[e("div",{class:A(["wstep",{on:_.value>=1,cur:_.value===1}]),onClick:l[8]||(l[8]=t=>_.value=1)},[l[47]||(l[47]=M("① 服务类型",-1)),x.value?(o(),a("span",tl," · "+d(C(x.value).short),1)):h("",!0)],2),l[49]||(l[49]=e("div",{class:"wline"},null,-1)),e("div",{class:A(["wstep",{on:_.value>=2,cur:_.value===2,disabled:!x.value}]),onClick:l[9]||(l[9]=t=>x.value&&(_.value=2))},[l[48]||(l[48]=M("② 服务商",-1)),u.provider?(o(),a("span",ll," · "+d(u.provider),1)):h("",!0)],2),l[50]||(l[50]=e("div",{class:"wline"},null,-1)),e("div",{class:A(["wstep",{on:_.value>=3,cur:_.value===3,disabled:_.value<3}])},"③ 配置",2)]),_.value===1?(o(),a(b,{key:0},[l[51]||(l[51]=e("p",{class:"text-sm text-slate-500 mb-3"},"请选择要接入的服务类型(每个服务归属单一类型,独立配置):",-1)),e("div",sl,[(o(),a(b,null,k(N,t=>e("div",{key:t.v,class:A(["type-card",{on:x.value===t.v}]),onClick:i=>Le(t.v)},[e("span",{class:"cat-chip",style:D({color:t.color,background:t.bg})},d(t.short),5),e("span",nl,d(t.label),1)],10,ol)),64))])],64)):_.value===2?(o(),a(b,{key:1},[e("div",al,[e("p",il,"为「"+d(C(x.value).label)+"」选择服务商:",1),e("button",{class:"btn btn-ghost btn-xs",onClick:l[10]||(l[10]=t=>_.value=1)},"← 上一步")]),e("div",dl,[(o(!0),a(b,null,k(ce.value,t=>(o(),a("div",{key:t.id,class:A(["type-card",{on:B.value===t.id}]),onClick:i=>pe(t)},[e("span",rl,d(t.provider),1),e("span",cl,d(t.name),1),e("span",pl,d((t.fields||[]).length)+" 字段",1)],10,ul))),128)),e("div",{class:"type-card",onClick:l[11]||(l[11]=t=>pe(null))},[...l[52]||(l[52]=[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)])])]),ce.value.length?h("",!0):(o(),a("p",vl,"该类型暂无内置模板,可选「空白自定义」,或到「服务商模板」新增。"))],64)):(o(),a(b,{key:2},[e("div",bl,[e("div",ml,[e("span",{class:"cat-chip",style:D({color:C(x.value).color,background:C(x.value).bg})},d(C(x.value).short),5),u.provider?(o(),a("span",xl,d(u.provider),1)):h("",!0)]),e("div",yl,[e("button",{class:"btn btn-ghost btn-xs",onClick:l[12]||(l[12]=t=>_.value=2)},"← 上一步"),e("button",{class:"btn btn-primary btn-sm text-white",onClick:l[13]||(l[13]=t=>ie(!0))},"创建")])]),e("div",_l,[e("div",hl,[l[53]||(l[53]=e("label",{class:"label"},[e("span",{class:"label-text"},[M("服务ID * "),e("span",{class:"text-slate-400 text-xs"},"(唯一,如 tts_azure)")])],-1)),c(e("input",{"onUpdate:modelValue":l[14]||(l[14]=t=>u.id=t),class:"input input-bordered font-mono",placeholder:"tts_azure"},null,512),[[y,u.id]])]),e("div",kl,[l[54]||(l[54]=e("label",{class:"label"},[e("span",{class:"label-text"},"服务名称 *")],-1)),c(e("input",{"onUpdate:modelValue":l[15]||(l[15]=t=>u.name=t),class:"input input-bordered",placeholder:"微软 Azure TTS"},null,512),[[y,u.name]])])]),e("div",gl,[e("div",fl,[l[55]||(l[55]=e("label",{class:"label"},[e("span",{class:"label-text"},[M("服务商标识 "),e("span",{class:"text-slate-400 text-xs"},"(如 azure/alibaba)")])],-1)),c(e("input",{"onUpdate:modelValue":l[16]||(l[16]=t=>u.provider=t),class:"input input-bordered font-mono",placeholder:"azure"},null,512),[[y,u.provider]])]),e("div",wl,[l[56]||(l[56]=e("label",{class:"label"},[e("span",{class:"label-text"},"启用")],-1)),c(e("input",{"onUpdate:modelValue":l[17]||(l[17]=t=>u.enable=t),type:"checkbox",class:"toggle toggle-primary mt-3"},null,512),[[L,u.enable]])])]),e("div",Vl,[l[57]||(l[57]=e("label",{class:"label"},[e("span",{class:"label-text"},"服务描述")],-1)),c(e("input",{"onUpdate:modelValue":l[18]||(l[18]=t=>u.description=t),class:"input input-bordered",placeholder:"简述该服务的用途"},null,512),[[y,u.description]])]),l[61]||(l[61]=e("div",{class:"divider text-xs text-slate-400 my-3"},"配置字段",-1)),e("div",null,[g.value.length?(o(),a("div",Cl,[e("table",Sl,[l[60]||(l[60]=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,[(o(!0),a(b,null,k(g.value,(t,i)=>(o(),a("tr",{key:i},[e("td",null,[c(e("input",{class:"field-input","onUpdate:modelValue":n=>t.key=n,placeholder:"key",title:t.key},null,8,Tl),[[y,t.key]])]),e("td",null,[c(e("input",{class:"field-input","onUpdate:modelValue":n=>t.description=n,placeholder:"用途描述"},null,8,$l),[[y,t.description]])]),e("td",Ml,[c(e("input",{type:"checkbox",class:"checkbox checkbox-xs checkbox-primary","onUpdate:modelValue":n=>t.encrypted=n},null,8,Al),[[L,t.encrypted]])]),e("td",null,[t.type==="langs"?(o(),z(r,{key:0,modelValue:t.def_value,"onUpdate:modelValue":n=>t.def_value=n,multiple:!0},null,8,["modelValue","onUpdate:modelValue"])):t.type==="lang"?(o(),z(r,{key:1,modelValue:t.def_value,"onUpdate:modelValue":n=>t.def_value=n},null,8,["modelValue","onUpdate:modelValue"])):t.encrypted?(o(),a(b,{key:2},[e("div",zl,[c(e("input",{type:t._show?"text":"password",class:"field-input pr-14","onUpdate:modelValue":n=>t.def_value=n,placeholder:"留空保留原值"},null,8,Fl),[[Z,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:n=>t._show=!t._show},d(t._show?"隐藏":"显示"),9,Dl)]),l[58]||(l[58]=e("span",{class:"lock-badge ml-1"},"🔒 加密",-1))],64)):te()&&t.key==="type"?c((o(),a("select",{key:3,class:"field-input","onUpdate:modelValue":n=>t.def_value=n},[...l[59]||(l[59]=[e("option",{value:"0"},"HTTP",-1),e("option",{value:"1"},"SSE",-1)])],8,Ll)),[[I,t.def_value]]):c((o(),a("input",{key:4,class:"field-input","onUpdate:modelValue":n=>t.def_value=n},null,8,jl)),[[y,t.def_value]])]),e("td",null,[e("button",{class:"btn btn-ghost btn-xs text-error",onClick:n=>be(i)},"×",8,El)])]))),128))])])])):(o(),a("p",Ul,"尚无字段,选模板自动带出或点击下方添加")),e("button",{class:"btn btn-ghost btn-sm mt-2 text-primary",onClick:ve},"+ 添加字段")])],64))],64)):E.value==="region"&&p.value?(o(),a(b,{key:2},[se.value?(o(),a("div",Il,"加载中...")):(o(),a(b,{key:1},[e("div",Nl,[e("div",Rl,[e("div",{class:"svc-logo",style:D({background:p.value.color||"#6366f1",width:"44px",height:"44px",fontSize:"20px"})},d(p.value.icon||(p.value.name||"").charAt(0)),5),e("div",null,[e("h3",Bl,d(p.value.name),1),e("span",Ol,d(W.value)+" 分叉模式",1)])]),e("div",Hl,[e("button",{class:"btn btn-primary btn-sm text-white",onClick:l[19]||(l[19]=t=>ie(!1))},"保存分叉"),e("button",{class:"btn btn-ghost btn-sm",onClick:w},"关闭")])]),e("div",Pl," ✦ 当前编辑「"+d(W.value)+"」的字段分叉:默认字段可覆盖值或勾选「不适用」停用;也可新增本区域专属字段。留空的覆盖字段继承默认值,加密字段留空保留已存储密文。 ",1),l[68]||(l[68]=e("p",{class:"text-sm font-medium text-slate-700 mb-2"},"默认字段",-1)),e("div",Jl,[e("table",ql,[l[65]||(l[65]=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,[(o(!0),a(b,null,k(O.value,(t,i)=>(o(),a("tr",{key:i,class:A({"opacity-50":t.disabled})},[e("td",{class:"font-mono text-slate-700 break-all",title:t.key},d(t.key),9,Gl),e("td",Kl,d(t.description),1),e("td",Ql,[t.disabled?(o(),a("span",Wl,"停用")):t.is_overridden?(o(),a("span",Xl,"覆盖")):(o(),a("span",Yl,"继承"))]),e("td",Zl,[c(e("input",{type:"checkbox",class:"checkbox checkbox-xs","onUpdate:modelValue":n=>t.disabled=n},null,8,es),[[L,t.disabled]])]),e("td",null,[t.type==="langs"?(o(),z(r,{key:0,modelValue:t._input,"onUpdate:modelValue":n=>t._input=n,multiple:!0,disabled:t.disabled},null,8,["modelValue","onUpdate:modelValue","disabled"])):t.type==="lang"?(o(),z(r,{key:1,modelValue:t._input,"onUpdate:modelValue":n=>t._input=n,disabled:t.disabled},null,8,["modelValue","onUpdate:modelValue","disabled"])):t.encrypted?(o(),a(b,{key:2},[e("div",ts,[c(e("input",{type:t._show?"text":"password",class:"field-input pr-14","onUpdate:modelValue":n=>t._input=n,disabled:t.disabled,placeholder:"留空继承默认"},null,8,ls),[[Z,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:n=>t._show=!t._show},d(t._show?"隐藏":"显示"),9,ss)]),l[62]||(l[62]=e("span",{class:"lock-badge ml-1"},"🔒",-1))],64)):te()&&t.key==="type"?c((o(),a("select",{key:3,class:"field-input","onUpdate:modelValue":n=>t._input=n,disabled:t.disabled},[...l[63]||(l[63]=[e("option",{value:""},"继承默认",-1),e("option",{value:"0"},"HTTP",-1),e("option",{value:"1"},"SSE",-1)])],8,os)),[[I,t._input]]):c((o(),a("input",{key:4,class:"field-input","onUpdate:modelValue":n=>t._input=n,disabled:t.disabled,placeholder:"留空继承:"+(t.value||"")},null,8,ns)),[[y,t._input]])])],2))),128)),O.value.length?h("",!0):(o(),a("tr",as,[...l[64]||(l[64]=[e("td",{colspan:"5",class:"text-center text-slate-400 py-3"},"该服务尚无默认字段",-1)])]))])])]),e("div",is,d(W.value)+" 专属字段",1),e("div",null,[F.value.length?(o(),a("div",us,[e("table",rs,[l[67]||(l[67]=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,[(o(!0),a(b,null,k(F.value,(t,i)=>(o(),a("tr",{key:i},[e("td",null,[c(e("input",{class:"field-input","onUpdate:modelValue":n=>t.key=n,placeholder:"key",title:t.key},null,8,cs),[[y,t.key]])]),e("td",null,[c(e("input",{class:"field-input","onUpdate:modelValue":n=>t.description=n,placeholder:"用途描述"},null,8,ps),[[y,t.description]])]),e("td",vs,[c(e("input",{type:"checkbox",class:"checkbox checkbox-xs checkbox-primary","onUpdate:modelValue":n=>t.encrypted=n},null,8,bs),[[L,t.encrypted]])]),e("td",null,[t.encrypted?(o(),a(b,{key:0},[e("div",ms,[c(e("input",{type:t._show?"text":"password",class:"field-input pr-14","onUpdate:modelValue":n=>t._input=n,placeholder:"留空保留原值"},null,8,xs),[[Z,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:n=>t._show=!t._show},d(t._show?"隐藏":"显示"),9,ys)]),l[66]||(l[66]=e("span",{class:"lock-badge ml-1"},"🔒",-1))],64)):c((o(),a("input",{key:1,class:"field-input","onUpdate:modelValue":n=>t._input=n},null,8,_s)),[[y,t._input]])]),e("td",null,[e("button",{class:"btn btn-ghost btn-xs text-error",onClick:n=>Ie(i)},"×",8,hs)])]))),128))])])])):(o(),a("p",ds,"尚无区域专属字段,点击下方添加")),e("button",{class:"btn btn-ghost btn-sm mt-2 text-primary",onClick:Ee},"+ 添加区域专属字段")])],64))],64)):h("",!0)])])):h("",!0),c(e("div",ks,[e("div",gs,[e("div",fs,[e("div",ws,[(o(),a("svg",Vs,[...l[69]||(l[69]=[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[70]||(l[70]=e("h3",{class:"text-base font-semibold text-slate-800"},"同步到其他区域",-1)),e("p",Us,d(xe.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:ye.value},null,8,Cs),e("div",Ss,[l[71]||(l[71]=e("span",{class:"text-xs font-semibold text-slate-500"},"选择目标区域",-1)),e("div",Ts,[e("button",{class:"btn btn-ghost btn-xs",onClick:l[20]||(l[20]=t=>ke(!0))},"全选"),e("button",{class:"btn btn-ghost btn-xs",onClick:l[21]||(l[21]=t=>ke(!1))},"清空")])]),e("div",$s,[(o(!0),a(b,null,k(_e.value,t=>(o(),a("label",{key:t.value,class:A(["sync-region-item",{checked:$.value.includes(t.value)}]),onClick:i=>he(t.value)},[e("input",{type:"checkbox",class:"checkbox checkbox-xs checkbox-primary",checked:$.value.includes(t.value),onClick:Ve(i=>he(t.value),["stop"])},null,8,As),e("span",null,d(t.label),1)],10,Ms))),128))]),l[72]||(l[72]=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:Oe},"仅保存当前区域"),e("button",{class:"btn btn-primary text-white",onClick:He},"保存并同步")])])],512),[[Ue,ne.value]]),c(e("div",zs,[e("div",Fs,[P.value==="list"?(o(),a(b,{key:0},[e("div",Ds,[l[73]||(l[73]=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",Ls,[e("button",{class:"btn btn-primary btn-sm text-white",onClick:l[22]||(l[22]=t=>fe())},"+ 新增模板"),e("button",{class:"btn btn-ghost btn-sm",onClick:Je},"关闭")])]),e("div",js,[(o(!0),a(b,null,k(Ae.value,t=>(o(),a("div",{key:t.cat,class:"mb-3"},[e("p",Es,d(t.label),1),(o(!0),a(b,null,k(t.items,i=>(o(),a("div",{key:i.id,class:"tpl-row"},[e("div",Is,[e("div",Ns,[e("span",Rs,d(i.name),1),e("span",Bs,d(i.provider),1),i.builtin?(o(),a("span",Os,"内置")):h("",!0)]),e("p",Hs,d(i.id)+" · "+d((i.fields||[]).length)+" 字段",1)]),e("div",Ps,[e("button",{class:"btn btn-ghost btn-xs",onClick:n=>fe(i)},"编辑",8,Js),e("button",{class:"btn btn-ghost btn-xs text-error",onClick:n=>Qe(i)},"删除",8,qs)])]))),128))]))),128)),H.value.length?h("",!0):(o(),a("p",Gs,"暂无模板"))])],64)):(o(),a(b,{key:1},[e("div",Ks,[e("h3",Qs,d(J.value?"编辑模板":"新增模板"),1),e("div",Ws,[e("button",{class:"btn btn-ghost btn-sm",onClick:l[23]||(l[23]=t=>P.value="list")},"返回"),e("button",{class:"btn btn-primary btn-sm text-white",onClick:Ke},"保存")])]),e("div",Xs,[e("div",Ys,[l[74]||(l[74]=e("label",{class:"label"},[e("span",{class:"label-text text-xs"},"模板ID *")],-1)),c(e("input",{"onUpdate:modelValue":l[24]||(l[24]=t=>v.id=t),disabled:J.value,class:"input input-bordered input-sm font-mono",placeholder:"tts_azure"},null,8,Zs),[[y,v.id]])]),e("div",eo,[l[75]||(l[75]=e("label",{class:"label"},[e("span",{class:"label-text text-xs"},"类别 *")],-1)),c(e("select",{"onUpdate:modelValue":l[25]||(l[25]=t=>v.category=t),class:"select select-bordered select-sm"},[(o(),a(b,null,k(N,t=>e("option",{key:t.v,value:t.v},d(t.label),9,to)),64))],512),[[I,v.category,void 0,{number:!0}]])]),e("div",lo,[l[76]||(l[76]=e("label",{class:"label"},[e("span",{class:"label-text text-xs"},"服务商标识 *")],-1)),c(e("input",{"onUpdate:modelValue":l[26]||(l[26]=t=>v.provider=t),class:"input input-bordered input-sm font-mono",placeholder:"azure"},null,512),[[y,v.provider]])]),e("div",so,[l[77]||(l[77]=e("label",{class:"label"},[e("span",{class:"label-text text-xs"},"展示名 *")],-1)),c(e("input",{"onUpdate:modelValue":l[27]||(l[27]=t=>v.name=t),class:"input input-bordered input-sm",placeholder:"微软 Azure TTS"},null,512),[[y,v.name]])])]),e("div",oo,[l[78]||(l[78]=e("label",{class:"label"},[e("span",{class:"label-text text-xs"},"描述")],-1)),c(e("input",{"onUpdate:modelValue":l[28]||(l[28]=t=>v.description=t),class:"input input-bordered input-sm"},null,512),[[y,v.description]])]),l[81]||(l[81]=e("p",{class:"text-sm font-medium text-slate-700 mb-1"},"字段",-1)),e("div",no,[e("table",ao,[l[80]||(l[80]=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,[(o(!0),a(b,null,k(S.value,(t,i)=>(o(),a("tr",{key:i},[e("td",null,[c(e("input",{class:"field-input","onUpdate:modelValue":n=>t.key=n,placeholder:"key",title:t.key},null,8,io),[[y,t.key]])]),e("td",null,[c(e("input",{class:"field-input","onUpdate:modelValue":n=>t.description=n,placeholder:"用途描述"},null,8,uo),[[y,t.description]])]),e("td",ro,[c(e("input",{type:"checkbox",class:"checkbox checkbox-xs checkbox-primary","onUpdate:modelValue":n=>t.encrypted=n},null,8,co),[[L,t.encrypted]])]),e("td",null,[t.type==="langs"?(o(),z(r,{key:0,modelValue:t.def_value,"onUpdate:modelValue":n=>t.def_value=n,multiple:!0},null,8,["modelValue","onUpdate:modelValue"])):t.type==="lang"?(o(),z(r,{key:1,modelValue:t.def_value,"onUpdate:modelValue":n=>t.def_value=n},null,8,["modelValue","onUpdate:modelValue"])):c((o(),a("input",{key:2,class:"field-input","onUpdate:modelValue":n=>t.def_value=n,placeholder:"可留空"},null,8,po)),[[y,t.def_value]])]),e("td",null,[e("button",{class:"btn btn-ghost btn-xs text-error",onClick:n=>Ge(i)},"×",8,vo)])]))),128)),S.value.length?h("",!0):(o(),a("tr",bo,[...l[79]||(l[79]=[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:qe},"+ 添加字段")],64))])],512),[[Ue,de.value]])])}}}),wo=et(mo,[["__scopeId","data-v-4e0895d6"]]);export{wo as default}; +import{_ as Xe}from"./CglQi8MB.js";import{g as Ye,B as Ze,c as a,l as h,a as e,d as M,p as c,q as I,F as b,r as k,t as d,m as Ve,L as D,v as y,s as L,n as A,H as Ue,x as m,y as Ce,z as q,o,I as z,C as Z,_ as et}from"./mElhLwm2.js";import{u as tt}from"./C6twYRfy.js";import{u as lt}from"./FVTAbpot.js";import"./ChQPCk92.js";import"./qig5Qp6S.js";const st={key:0,class:"mb-4 rounded-lg px-4 py-3 text-sm",style:{background:"#fffbeb",border:"1px solid #fde68a",color:"#92400e"}},ot={class:"flex items-center justify-between mb-5"},nt={class:"flex items-center gap-3"},at=["value"],it=["value"],dt={key:1,class:"rounded-lg px-3 py-2 mb-4 text-xs",style:{background:"#fefce8",border:"1px solid #fde047",color:"#854d0e"}},ut={key:2,class:"flex flex-col gap-6"},rt={class:"flex items-center gap-2 mb-3"},ct={class:"text-sm font-semibold text-slate-700"},pt={class:"text-xs text-slate-400"},vt={class:"svc-grid"},bt=["onClick"],mt={class:"flex items-start gap-3"},xt={style:{"min-width":"0",flex:"1"}},yt={class:"flex items-center gap-2"},_t={class:"font-semibold text-slate-800 text-sm truncate"},ht=["title"],kt={class:"text-xs text-slate-500 mt-2 line-clamp-2",style:{"min-height":"32px"}},gt={class:"flex flex-wrap items-center gap-1 mt-2"},ft={key:0,class:"provider-chip"},wt={class:"field-count"},Vt={key:1,class:"lock-badge"},Ut=["onClick"],Ct={class:"text-xs text-slate-400 mt-1"},St={key:3,class:"bg-white rounded-2xl border border-slate-100 shadow-sm text-center text-slate-300 py-20"},Tt={class:"svc-box"},$t={class:"flex items-center justify-between mb-5"},Mt={class:"flex items-center gap-3"},At={class:"text-base font-semibold text-slate-800"},zt={class:"text-xs text-slate-400 mt-0.5"},Ft={key:0},Dt={class:"flex gap-2"},Lt={class:"grid grid-cols-2 gap-4 mb-4"},jt={class:"form-control"},Et={class:"form-control"},It={class:"form-control mb-4"},Nt={class:"mb-4"},Rt={class:"text-xs text-slate-500 ml-2"},Bt={key:0,class:"text-xs text-slate-400 py-4 text-center"},Ot={key:1,class:"overflow-x-auto"},Ht={class:"table text-xs"},Pt=["onUpdate:modelValue","title"],Jt=["onUpdate:modelValue"],qt={class:"text-center"},Gt=["onUpdate:modelValue"],Kt={class:"relative"},Qt=["type","onUpdate:modelValue"],Wt=["onClick"],Xt=["onUpdate:modelValue"],Yt=["onUpdate:modelValue"],Zt=["onClick"],el={class:"wizard-steps mb-5"},tl={key:0},ll={key:0},sl={class:"type-grid"},ol=["onClick"],nl={class:"text-sm text-slate-700 mt-2"},al={class:"flex items-center justify-between mb-3"},il={class:"text-sm text-slate-500"},dl={class:"type-grid"},ul=["onClick"],rl={class:"provider-chip"},cl={class:"text-sm text-slate-700 mt-2"},pl={class:"text-[11px] text-slate-400 mt-0.5"},vl={key:0,class:"text-xs text-slate-400 mt-2"},bl={class:"flex items-center justify-between mb-3"},ml={class:"flex items-center gap-2"},xl={key:0,class:"provider-chip"},yl={class:"flex gap-2"},_l={class:"grid grid-cols-2 gap-4 mb-4"},hl={class:"form-control"},kl={class:"form-control"},gl={class:"grid grid-cols-2 gap-4 mb-4"},fl={class:"form-control"},wl={class:"form-control"},Vl={class:"form-control mb-4"},Ul={key:0,class:"text-xs text-slate-400 py-4 text-center"},Cl={key:1,class:"overflow-x-auto"},Sl={class:"table text-xs"},Tl=["onUpdate:modelValue","title"],$l=["onUpdate:modelValue"],Ml={class:"text-center"},Al=["onUpdate:modelValue"],zl={class:"relative"},Fl=["type","onUpdate:modelValue"],Dl=["onClick"],Ll=["onUpdate:modelValue"],jl=["onUpdate:modelValue"],El=["onClick"],Il={key:0,class:"text-center py-10 text-slate-400"},Nl={class:"flex items-center justify-between mb-5"},Rl={class:"flex items-center gap-3"},Bl={class:"text-base font-semibold text-slate-800"},Ol={class:"badge badge-warning badge-sm mt-0.5"},Hl={class:"flex gap-2"},Pl={class:"rounded-lg px-3 py-2 mb-4 text-xs",style:{background:"#fefce8",border:"1px solid #fde047",color:"#854d0e"}},Jl={class:"overflow-x-auto"},ql={class:"table text-xs"},Gl=["title"],Kl={class:"text-slate-500"},Ql={class:"text-center"},Wl={key:0,class:"disabled-badge"},Xl={key:1,class:"override-badge"},Yl={key:2,class:"inherit-badge"},Zl={class:"text-center"},es=["onUpdate:modelValue"],ts={class:"relative"},ls=["type","onUpdate:modelValue","disabled"],ss=["onClick"],os=["onUpdate:modelValue","disabled"],ns=["onUpdate:modelValue","disabled","placeholder"],as={key:0},is={class:"divider text-xs text-slate-400 my-3"},ds={key:0,class:"text-xs text-slate-400 py-2 text-center"},us={key:1,class:"overflow-x-auto"},rs={class:"table text-xs"},cs=["onUpdate:modelValue","title"],ps=["onUpdate:modelValue"],vs={class:"text-center"},bs=["onUpdate:modelValue"],ms={class:"relative"},xs=["type","onUpdate:modelValue"],ys=["onClick"],_s=["onUpdate:modelValue"],hs=["onClick"],ks={class:"modal-overlay",style:{"z-index":"120"}},gs={class:"sync-box"},fs={class:"flex items-start gap-3 mb-4"},ws={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"}},Vs={style:{width:"20px",height:"20px",color:"#fff"},fill:"none",viewBox:"0 0 24 24",stroke:"currentColor"},Us={class:"text-xs text-slate-400 mt-1"},Cs=["innerHTML"],Ss={class:"flex items-center justify-between mb-1"},Ts={class:"flex gap-2"},$s={class:"sync-region-grid"},Ms=["onClick"],As=["checked","onClick"],zs={class:"modal-overlay",style:{"z-index":"130"}},Fs={class:"tpl-box"},Ds={class:"flex items-center justify-between mb-4"},Ls={class:"flex gap-2"},js={class:"tpl-list"},Es={class:"text-xs font-semibold text-slate-500 mb-1"},Is={style:{"min-width":"0",flex:"1"}},Ns={class:"flex items-center gap-2"},Rs={class:"font-semibold text-sm text-slate-800 truncate"},Bs={class:"provider-chip"},Os={key:0,class:"badge badge-xs badge-ghost"},Hs={class:"text-xs text-slate-400 mt-0.5"},Ps={class:"flex gap-1"},Js=["onClick"],qs=["onClick"],Gs={key:0,class:"text-xs text-slate-400 text-center py-6"},Ks={class:"flex items-center justify-between mb-4"},Qs={class:"text-base font-semibold text-slate-800"},Ws={class:"flex gap-2"},Xs={class:"grid grid-cols-2 gap-3 mb-3"},Ys={class:"form-control"},Zs=["disabled"],eo={class:"form-control"},to=["value"],lo={class:"form-control"},so={class:"form-control"},oo={class:"form-control mb-3"},no={class:"overflow-x-auto",style:{"max-height":"34vh"}},ao={class:"table text-xs"},io=["onUpdate:modelValue","title"],uo=["onUpdate:modelValue"],ro={class:"text-center"},co=["onUpdate:modelValue"],po=["onUpdate:modelValue"],vo=["onClick"],bo={key:0},Se=10,mo=Ye({__name:"serviceconfig",setup(xo){const G=[{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:"印度"}],N=[{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:V,consoleApi:Te}=tt(),{success:j,error:U}=lt(),T=m(""),ee=m([]);async function $e(){try{const s=await Te("products/list",{});ee.value=(s??[]).map(l=>l.name).filter(Boolean)}catch{ee.value=[]}}function Me(){w(),X()}function C(s){return N.find(l=>l.v===s)||{short:"?",color:"#999",bg:"#eee",v:0,label:""}}function te(){return x.value===Se?!0:!!p.value&&K(p.value.categories).includes(Se)}function K(s){return(s||"").split(",").map(l=>parseInt(l)||0).filter(l=>l>0)}function ue(s){return(s.fields||[]).filter(l=>l.encrypted).length}const le=m(!0),R=m([]),p=m(null),f=m(0),Q=m(!1),E=m("default"),u=Ce({id:"",name:"",provider:"",description:"",enable:!1}),x=m(0),g=m([]),B=m(""),_=m(1),O=m([]),F=m([]),se=m(!1),H=m([]),W=q(()=>{const s=G.find(l=>l.value===f.value);return s?s.label:"区域"+f.value}),re=q(()=>{const s=N.map(r=>({...r,items:R.value.filter(t=>K(t.categories).includes(r.v))})).filter(r=>r.items.length),l=R.value.filter(r=>!K(r.categories).length);return l.length&&s.push({v:0,label:"未分类",short:"未分类",color:"#64748b",bg:"#f1f5f9",items:l}),s}),Ae=q(()=>N.map(s=>({cat:s.v,label:s.label,items:H.value.filter(l=>l.category===s.v)})).filter(s=>s.items.length));async function X(){try{const s=await V("getsvcconfigs",{app_name:T.value});R.value=s?.items??[],le.value=!0}catch{le.value=!1,R.value=[];return}if(p.value){const s=R.value.find(l=>l.id===p.value.id);s&&(p.value=s)}}async function Y(){try{const s=await V("getsvctemplates",{});H.value=s?.items??[]}catch{H.value=[]}}function ze(){w()}function Fe(s){s&&(p.value=s,Q.value=!0,f.value===0?De():je())}function w(){Q.value=!1,p.value=null}function De(){const s=p.value;u.id=s.id,u.name=s.name||"",u.provider=s.provider||"",u.description=s.description||"",u.enable=!!s.enable,x.value=K(s.categories)[0]||0,g.value=JSON.parse(JSON.stringify(s.fields||[])).map(l=>({...l,_show:!1})),E.value="default"}function oe(s=0){p.value=null,u.id="",u.name="",u.provider="",u.description="",u.enable=!1,x.value=s,g.value=[],B.value="",_.value=s?2:1,E.value="new",Q.value=!0}const ce=q(()=>H.value.filter(s=>s.category===x.value));function Le(s){x.value!==s&&(x.value=s,B.value="",u.provider="",g.value=[]),_.value=2}function pe(s){s?(B.value=s.id,u.provider=s.provider||"",u.name||(u.name=s.name||""),u.id||(u.id=s.id||""),u.description||(u.description=s.description||""),g.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}))):(B.value="",u.provider="",g.value=[]),_.value=3}function ve(){g.value.push({key:"",description:"",encrypted:!1,def_value:"",sort:g.value.length,_show:!1})}function be(s){g.value.splice(s,1),g.value.forEach((l,r)=>{l.sort=r})}async function je(){const s=p.value;se.value=!0,E.value="region";try{const r=(await V("getsvcregionoverride",{app_name:T.value,svc_id:s.id,region:f.value}))?.fields??[];O.value=r.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})),F.value=r.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){U(l?.message??"加载区域分叉失败"),O.value=[],F.value=[]}finally{se.value=!1}}function Ee(){F.value.push({key:"",description:"",encrypted:!1,_input:"",_show:!1})}function Ie(s){F.value.splice(s,1)}function Ne(s){const l={name:u.name||"",provider:u.provider||"",description:u.description||"",categories:x.value?String(x.value):"",enable:u.enable||!1,fields:g.value.map(r=>({key:r.key,description:r.description,type:r.type||"",encrypted:r.encrypted,def_value:r.def_value,sort:r.sort}))};return s?l.id=u.id||"":l.id=p.value.id,l.app_name=T.value,l}function Re(){const s={},l=[];O.value.forEach(t=>{s[t.key]=t._input||"",t.disabled&&l.push(t.key)});const r=F.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:r}}async function me(s){const l=s||!p.value;if(f.value===0){const r=Ne(l);if(!r.id||!r.name)return U("服务ID 和名称 必填"),!1;const t=l?"addsvcconfig":"updatesvcconfig";try{const i=await V(t,r);return p.value=i,await X(),j("保存成功"),!0}catch(i){return U(i?.message??"保存失败"),!1}}else{const{overrides:r,disabled_keys:t,extra_fields:i}=Re();try{return await V("savesvcregionoverride",{app_name:T.value,svc_id:p.value.id,region:f.value,overrides:r,disabled_keys:t,extra_fields:i}),j("区域分叉已保存"),!0}catch(n){return U(n?.message??"保存失败"),!1}}}async function Be(){if(p.value&&window.confirm("确定删除服务「"+p.value.name+"」及其所有区域分叉?")){try{await V("delsvcconfig",{app_name:T.value,id:p.value.id})}catch(s){U(s?.message??"删除失败");return}w(),j("已删除"),await X()}}const ne=m(!1),ae=m(!1),xe=m(""),ye=m(""),$=m([]),_e=q(()=>G.filter(s=>s.value!==f.value));function ie(s){ae.value=s;const l=p.value?p.value.name:u.name||"新服务",r=f.value===0;xe.value=r?"「"+l+"」默认配置将保存,可同步推送到其他区域。":"「"+l+"」在当前区域的字段分叉将保存,可同步到其他区域。",ye.value=r?"✦ 同步内容:各字段默认值推送为目标区域「覆盖值」,目标区域原有分叉将被替换。":"✦ 同步内容:当前区域的值覆盖 / 区域专属字段 / 停用字段整体复制到目标区域。",$.value=[],ne.value=!0}function he(s){const l=$.value.indexOf(s);l>=0?$.value.splice(l,1):$.value.push(s)}function ke(s){$.value=s?_e.value.map(l=>l.value):[]}function ge(){ne.value=!1}async function Oe(){ge(),await me(ae.value)&&w()}async function He(){const s=$.value.slice();if(ge(),!await me(ae.value))return;const r=p.value?p.value.id:null;if(!s.length||!r){w();return}let t=0;try{t=(await V("syncsvctoregins",{app_name:T.value,svc_id:r,src_region:f.value,target_regions:s}))?.synced??0}catch(n){U(n?.message??"同步失败");return}const i=s.map(n=>{const we=G.find(We=>We.value===n);return we?we.label:"区域"+n});j("已保存并同步到:"+i.join("、")+"("+t+" 个)"),w()}const de=m(!1),P=m("list"),J=m(!1),v=Ce({id:"",category:2,provider:"",name:"",description:""}),S=m([]);function Pe(){P.value="list",de.value=!0,Y()}function Je(){de.value=!1}function fe(s){s?(J.value=!0,v.id=s.id,v.category=s.category||2,v.provider=s.provider||"",v.name=s.name||"",v.description=s.description||"",S.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}))):(J.value=!1,v.id="",v.category=2,v.provider="",v.name="",v.description="",S.value=[]),P.value="form"}function qe(){S.value.push({key:"",description:"",encrypted:!1,def_value:"",sort:S.value.length})}function Ge(s){S.value.splice(s,1),S.value.forEach((l,r)=>{l.sort=r})}async function Ke(){if(!v.id.trim()||!v.name.trim()||!v.provider.trim()){U("模板ID / 展示名 / 服务商标识 必填");return}const s={id:v.id.trim(),category:Number(v.category)||0,provider:v.provider.trim(),name:v.name.trim(),description:v.description.trim(),fields:S.value.map((l,r)=>({key:l.key,description:l.description,type:l.type||"",encrypted:l.encrypted,def_value:l.def_value,sort:r}))};try{await V(J.value?"updatesvctemplate":"addsvctemplate",s)}catch(l){U(l?.message??"保存失败");return}j("模板已保存"),await Y(),P.value="list"}async function Qe(s){if(window.confirm("确定删除模板「"+s.name+"」?"+(s.builtin?"(内置模板下次启动会被重新补回)":""))){try{await V("delsvctemplate",{id:s.id})}catch(l){U(l?.message??"删除失败");return}j("已删除"),await Y()}}return Ze(()=>{$e(),X(),Y()}),(s,l)=>{const r=Xe;return o(),a("div",null,[le.value?h("",!0):(o(),a("div",st," ⚠ 「第三方服务配置」后端接口暂不可用(连接失败),请检查 console 服务是否运行。 ")),e("div",ot,[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"},[M("按服务类型分组管理已接入的第三方服务(火山引擎、阿里云、Azure 等)。默认展示"),e("b",null,"全局默认"),M("配置,可切换到具体应用;区域默认"),e("b",null,"中国"),M(",切换区域后点击卡片可为该区域覆盖字段值。")])],-1)),e("div",nt,[c(e("select",{"onUpdate:modelValue":l[0]||(l[0]=t=>T.value=t),class:"select select-bordered select-sm",onChange:Me},[l[29]||(l[29]=e("option",{value:""},"全局默认",-1)),(o(!0),a(b,null,k(ee.value,t=>(o(),a("option",{key:t,value:t},"应用:"+d(t),9,at))),128))],544),[[I,T.value]]),c(e("select",{"onUpdate:modelValue":l[1]||(l[1]=t=>f.value=t),class:"select select-bordered select-sm",onChange:ze},[l[30]||(l[30]=e("option",{value:0},"默认(全区域)",-1)),(o(),a(b,null,k(G,t=>e("option",{key:t.value,value:t.value},d(t.label),9,it)),64))],544),[[I,f.value,void 0,{number:!0}]]),e("button",{class:"btn btn-ghost btn-sm",onClick:Pe},"服务商模板"),e("button",{class:"btn btn-primary btn-sm text-white",onClick:l[2]||(l[2]=t=>oe())},"+ 添加服务")])]),f.value!==0?(o(),a("div",dt," ✦ 当前处于「"+d(W.value)+"」区域视图:点击服务卡片编辑该区域的字段分叉(覆盖值 / 停用字段 / 区域专属字段)。要改服务本身的默认配置,请切回「默认(全区域)」。 ",1)):h("",!0),re.value.length?(o(),a("div",ut,[(o(!0),a(b,null,k(re.value,t=>(o(),a("section",{key:t.v},[e("div",rt,[e("span",{class:"cat-chip",style:D({color:t.color,background:t.bg})},d(t.short),5),e("h3",ct,d(t.label),1),e("span",pt,d(t.items.length)+" 个服务",1),l[32]||(l[32]=e("div",{class:"flex-1 h-px bg-slate-100 ml-2"},null,-1))]),e("div",vt,[(o(!0),a(b,null,k(t.items,i=>(o(),a("div",{key:i.id,class:"svc-card",onClick:n=>Fe(i)},[e("div",mt,[e("div",{class:"svc-logo",style:D({background:i.color||"#6366f1"})},d(i.icon||(i.name||"").charAt(0)),5),e("div",xt,[e("div",yt,[e("span",_t,d(i.name),1),e("span",{class:A(["badge badge-xs",i.enable?"badge-success":"badge-ghost"])},d(i.enable?"启用":"停用"),3)]),e("p",{class:"text-[11px] text-slate-400 font-mono truncate mt-0.5",title:i.id},d(i.id),9,ht)])]),e("p",kt,d(i.description||"—"),1),e("div",gt,[i.provider?(o(),a("span",ft,d(i.provider),1)):h("",!0),e("span",wt,d((i.fields||[]).length)+" 字段",1),ue(i)?(o(),a("span",Vt,"🔒"+d(ue(i)),1)):h("",!0)])],8,bt))),128)),e("div",{class:"svc-card add-card",onClick:i=>oe(t.v)},[l[33]||(l[33]=e("span",{class:"text-2xl text-slate-300"},"+",-1)),e("span",Ct,"添加"+d(t.short)+"服务",1)],8,Ut)])]))),128))])):(o(),a("div",St,[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=>oe())},"+ 添加服务")])),Q.value?(o(),a("div",{key:4,class:"modal-overlay",onClick:Ve(w,["self"])},[e("div",Tt,[E.value==="default"&&p.value?(o(),a(b,{key:0},[e("div",$t,[e("div",Mt,[e("div",{class:"svc-logo",style:D({background:p.value.color||"#6366f1",width:"44px",height:"44px",fontSize:"20px"})},d(p.value.icon||(p.value.name||"").charAt(0)),5),e("div",null,[e("h3",At,d(p.value.name),1),e("p",zt,[M(d(p.value.id),1),u.provider?(o(),a("span",Ft," · 服务商 "+d(u.provider),1)):h("",!0)])])]),e("div",Dt,[e("button",{class:"btn btn-error btn-sm btn-outline",onClick:Be},"删除服务"),e("button",{class:"btn btn-primary btn-sm text-white",onClick:l[4]||(l[4]=t=>ie(!1))},"保存"),e("button",{class:"btn btn-ghost btn-sm",onClick:w},"关闭")])]),l[44]||(l[44]=e("div",{class:"divider text-xs text-slate-400 my-3"},"基本信息",-1)),e("div",Lt,[e("div",jt,[l[36]||(l[36]=e("label",{class:"label"},[e("span",{class:"label-text"},"服务名称 *")],-1)),c(e("input",{"onUpdate:modelValue":l[5]||(l[5]=t=>u.name=t),class:"input input-bordered"},null,512),[[y,u.name]])]),e("div",Et,[l[37]||(l[37]=e("label",{class:"label"},[e("span",{class:"label-text"},"启用")],-1)),c(e("input",{"onUpdate:modelValue":l[6]||(l[6]=t=>u.enable=t),type:"checkbox",class:"toggle toggle-primary mt-3"},null,512),[[L,u.enable]])])]),e("div",It,[l[38]||(l[38]=e("label",{class:"label"},[e("span",{class:"label-text"},"服务描述")],-1)),c(e("input",{"onUpdate:modelValue":l[7]||(l[7]=t=>u.description=t),class:"input input-bordered"},null,512),[[y,u.description]])]),e("div",Nt,[l[39]||(l[39]=e("p",{class:"text-sm font-medium text-slate-700 mb-2"},"服务类型",-1)),x.value?(o(),a("span",{key:0,class:"cat-chip",style:D({color:C(x.value).color,background:C(x.value).bg})},d(C(x.value).short),5)):h("",!0),e("span",Rt,d(x.value?C(x.value).label:"未设置"),1),l[40]||(l[40]=e("span",{class:"text-[11px] text-slate-400 ml-2"},"(类型在创建时确定,不可更改)",-1))]),l[45]||(l[45]=e("div",{class:"divider text-xs text-slate-400 my-3"},"配置字段(全区域共用)",-1)),e("div",null,[g.value.length?(o(),a("div",Ot,[e("table",Ht,[l[43]||(l[43]=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,[(o(!0),a(b,null,k(g.value,(t,i)=>(o(),a("tr",{key:i},[e("td",null,[c(e("input",{class:"field-input","onUpdate:modelValue":n=>t.key=n,placeholder:"key",title:t.key},null,8,Pt),[[y,t.key]])]),e("td",null,[c(e("input",{class:"field-input","onUpdate:modelValue":n=>t.description=n,placeholder:"用途描述"},null,8,Jt),[[y,t.description]])]),e("td",qt,[c(e("input",{type:"checkbox",class:"checkbox checkbox-xs checkbox-primary","onUpdate:modelValue":n=>t.encrypted=n},null,8,Gt),[[L,t.encrypted]])]),e("td",null,[t.type==="langs"?(o(),z(r,{key:0,modelValue:t.def_value,"onUpdate:modelValue":n=>t.def_value=n,multiple:!0},null,8,["modelValue","onUpdate:modelValue"])):t.type==="lang"?(o(),z(r,{key:1,modelValue:t.def_value,"onUpdate:modelValue":n=>t.def_value=n},null,8,["modelValue","onUpdate:modelValue"])):t.encrypted?(o(),a(b,{key:2},[e("div",Kt,[c(e("input",{type:t._show?"text":"password",class:"field-input pr-14","onUpdate:modelValue":n=>t.def_value=n,placeholder:"留空保留原值"},null,8,Qt),[[Z,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:n=>t._show=!t._show},d(t._show?"隐藏":"显示"),9,Wt)]),l[41]||(l[41]=e("span",{class:"lock-badge ml-1"},"🔒 加密",-1))],64)):te()&&t.key==="type"?c((o(),a("select",{key:3,class:"field-input","onUpdate:modelValue":n=>t.def_value=n},[...l[42]||(l[42]=[e("option",{value:"0"},"HTTP",-1),e("option",{value:"1"},"SSE",-1)])],8,Xt)),[[I,t.def_value]]):c((o(),a("input",{key:4,class:"field-input","onUpdate:modelValue":n=>t.def_value=n},null,8,Yt)),[[y,t.def_value]])]),e("td",null,[e("button",{class:"btn btn-ghost btn-xs text-error",onClick:n=>be(i)},"×",8,Zt)])]))),128))])])])):(o(),a("p",Bt,"尚无字段,点击下方添加")),e("button",{class:"btn btn-ghost btn-sm mt-2 text-primary",onClick:ve},"+ 添加字段")])],64)):E.value==="new"?(o(),a(b,{key:1},[e("div",{class:"flex items-center justify-between mb-4"},[l[46]||(l[46]=e("h3",{class:"text-base font-semibold text-slate-800"},"新增第三方服务",-1)),e("button",{class:"btn btn-ghost btn-sm",onClick:w},"取消")]),e("div",el,[e("div",{class:A(["wstep",{on:_.value>=1,cur:_.value===1}]),onClick:l[8]||(l[8]=t=>_.value=1)},[l[47]||(l[47]=M("① 服务类型",-1)),x.value?(o(),a("span",tl," · "+d(C(x.value).short),1)):h("",!0)],2),l[49]||(l[49]=e("div",{class:"wline"},null,-1)),e("div",{class:A(["wstep",{on:_.value>=2,cur:_.value===2,disabled:!x.value}]),onClick:l[9]||(l[9]=t=>x.value&&(_.value=2))},[l[48]||(l[48]=M("② 服务商",-1)),u.provider?(o(),a("span",ll," · "+d(u.provider),1)):h("",!0)],2),l[50]||(l[50]=e("div",{class:"wline"},null,-1)),e("div",{class:A(["wstep",{on:_.value>=3,cur:_.value===3,disabled:_.value<3}])},"③ 配置",2)]),_.value===1?(o(),a(b,{key:0},[l[51]||(l[51]=e("p",{class:"text-sm text-slate-500 mb-3"},"请选择要接入的服务类型(每个服务归属单一类型,独立配置):",-1)),e("div",sl,[(o(),a(b,null,k(N,t=>e("div",{key:t.v,class:A(["type-card",{on:x.value===t.v}]),onClick:i=>Le(t.v)},[e("span",{class:"cat-chip",style:D({color:t.color,background:t.bg})},d(t.short),5),e("span",nl,d(t.label),1)],10,ol)),64))])],64)):_.value===2?(o(),a(b,{key:1},[e("div",al,[e("p",il,"为「"+d(C(x.value).label)+"」选择服务商:",1),e("button",{class:"btn btn-ghost btn-xs",onClick:l[10]||(l[10]=t=>_.value=1)},"← 上一步")]),e("div",dl,[(o(!0),a(b,null,k(ce.value,t=>(o(),a("div",{key:t.id,class:A(["type-card",{on:B.value===t.id}]),onClick:i=>pe(t)},[e("span",rl,d(t.provider),1),e("span",cl,d(t.name),1),e("span",pl,d((t.fields||[]).length)+" 字段",1)],10,ul))),128)),e("div",{class:"type-card",onClick:l[11]||(l[11]=t=>pe(null))},[...l[52]||(l[52]=[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)])])]),ce.value.length?h("",!0):(o(),a("p",vl,"该类型暂无内置模板,可选「空白自定义」,或到「服务商模板」新增。"))],64)):(o(),a(b,{key:2},[e("div",bl,[e("div",ml,[e("span",{class:"cat-chip",style:D({color:C(x.value).color,background:C(x.value).bg})},d(C(x.value).short),5),u.provider?(o(),a("span",xl,d(u.provider),1)):h("",!0)]),e("div",yl,[e("button",{class:"btn btn-ghost btn-xs",onClick:l[12]||(l[12]=t=>_.value=2)},"← 上一步"),e("button",{class:"btn btn-primary btn-sm text-white",onClick:l[13]||(l[13]=t=>ie(!0))},"创建")])]),e("div",_l,[e("div",hl,[l[53]||(l[53]=e("label",{class:"label"},[e("span",{class:"label-text"},[M("服务ID * "),e("span",{class:"text-slate-400 text-xs"},"(唯一,如 tts_azure)")])],-1)),c(e("input",{"onUpdate:modelValue":l[14]||(l[14]=t=>u.id=t),class:"input input-bordered font-mono",placeholder:"tts_azure"},null,512),[[y,u.id]])]),e("div",kl,[l[54]||(l[54]=e("label",{class:"label"},[e("span",{class:"label-text"},"服务名称 *")],-1)),c(e("input",{"onUpdate:modelValue":l[15]||(l[15]=t=>u.name=t),class:"input input-bordered",placeholder:"微软 Azure TTS"},null,512),[[y,u.name]])])]),e("div",gl,[e("div",fl,[l[55]||(l[55]=e("label",{class:"label"},[e("span",{class:"label-text"},[M("服务商标识 "),e("span",{class:"text-slate-400 text-xs"},"(如 azure/alibaba)")])],-1)),c(e("input",{"onUpdate:modelValue":l[16]||(l[16]=t=>u.provider=t),class:"input input-bordered font-mono",placeholder:"azure"},null,512),[[y,u.provider]])]),e("div",wl,[l[56]||(l[56]=e("label",{class:"label"},[e("span",{class:"label-text"},"启用")],-1)),c(e("input",{"onUpdate:modelValue":l[17]||(l[17]=t=>u.enable=t),type:"checkbox",class:"toggle toggle-primary mt-3"},null,512),[[L,u.enable]])])]),e("div",Vl,[l[57]||(l[57]=e("label",{class:"label"},[e("span",{class:"label-text"},"服务描述")],-1)),c(e("input",{"onUpdate:modelValue":l[18]||(l[18]=t=>u.description=t),class:"input input-bordered",placeholder:"简述该服务的用途"},null,512),[[y,u.description]])]),l[61]||(l[61]=e("div",{class:"divider text-xs text-slate-400 my-3"},"配置字段",-1)),e("div",null,[g.value.length?(o(),a("div",Cl,[e("table",Sl,[l[60]||(l[60]=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,[(o(!0),a(b,null,k(g.value,(t,i)=>(o(),a("tr",{key:i},[e("td",null,[c(e("input",{class:"field-input","onUpdate:modelValue":n=>t.key=n,placeholder:"key",title:t.key},null,8,Tl),[[y,t.key]])]),e("td",null,[c(e("input",{class:"field-input","onUpdate:modelValue":n=>t.description=n,placeholder:"用途描述"},null,8,$l),[[y,t.description]])]),e("td",Ml,[c(e("input",{type:"checkbox",class:"checkbox checkbox-xs checkbox-primary","onUpdate:modelValue":n=>t.encrypted=n},null,8,Al),[[L,t.encrypted]])]),e("td",null,[t.type==="langs"?(o(),z(r,{key:0,modelValue:t.def_value,"onUpdate:modelValue":n=>t.def_value=n,multiple:!0},null,8,["modelValue","onUpdate:modelValue"])):t.type==="lang"?(o(),z(r,{key:1,modelValue:t.def_value,"onUpdate:modelValue":n=>t.def_value=n},null,8,["modelValue","onUpdate:modelValue"])):t.encrypted?(o(),a(b,{key:2},[e("div",zl,[c(e("input",{type:t._show?"text":"password",class:"field-input pr-14","onUpdate:modelValue":n=>t.def_value=n,placeholder:"留空保留原值"},null,8,Fl),[[Z,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:n=>t._show=!t._show},d(t._show?"隐藏":"显示"),9,Dl)]),l[58]||(l[58]=e("span",{class:"lock-badge ml-1"},"🔒 加密",-1))],64)):te()&&t.key==="type"?c((o(),a("select",{key:3,class:"field-input","onUpdate:modelValue":n=>t.def_value=n},[...l[59]||(l[59]=[e("option",{value:"0"},"HTTP",-1),e("option",{value:"1"},"SSE",-1)])],8,Ll)),[[I,t.def_value]]):c((o(),a("input",{key:4,class:"field-input","onUpdate:modelValue":n=>t.def_value=n},null,8,jl)),[[y,t.def_value]])]),e("td",null,[e("button",{class:"btn btn-ghost btn-xs text-error",onClick:n=>be(i)},"×",8,El)])]))),128))])])])):(o(),a("p",Ul,"尚无字段,选模板自动带出或点击下方添加")),e("button",{class:"btn btn-ghost btn-sm mt-2 text-primary",onClick:ve},"+ 添加字段")])],64))],64)):E.value==="region"&&p.value?(o(),a(b,{key:2},[se.value?(o(),a("div",Il,"加载中...")):(o(),a(b,{key:1},[e("div",Nl,[e("div",Rl,[e("div",{class:"svc-logo",style:D({background:p.value.color||"#6366f1",width:"44px",height:"44px",fontSize:"20px"})},d(p.value.icon||(p.value.name||"").charAt(0)),5),e("div",null,[e("h3",Bl,d(p.value.name),1),e("span",Ol,d(W.value)+" 分叉模式",1)])]),e("div",Hl,[e("button",{class:"btn btn-primary btn-sm text-white",onClick:l[19]||(l[19]=t=>ie(!1))},"保存分叉"),e("button",{class:"btn btn-ghost btn-sm",onClick:w},"关闭")])]),e("div",Pl," ✦ 当前编辑「"+d(W.value)+"」的字段分叉:默认字段可覆盖值或勾选「不适用」停用;也可新增本区域专属字段。留空的覆盖字段继承默认值,加密字段留空保留已存储密文。 ",1),l[68]||(l[68]=e("p",{class:"text-sm font-medium text-slate-700 mb-2"},"默认字段",-1)),e("div",Jl,[e("table",ql,[l[65]||(l[65]=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,[(o(!0),a(b,null,k(O.value,(t,i)=>(o(),a("tr",{key:i,class:A({"opacity-50":t.disabled})},[e("td",{class:"font-mono text-slate-700 break-all",title:t.key},d(t.key),9,Gl),e("td",Kl,d(t.description),1),e("td",Ql,[t.disabled?(o(),a("span",Wl,"停用")):t.is_overridden?(o(),a("span",Xl,"覆盖")):(o(),a("span",Yl,"继承"))]),e("td",Zl,[c(e("input",{type:"checkbox",class:"checkbox checkbox-xs","onUpdate:modelValue":n=>t.disabled=n},null,8,es),[[L,t.disabled]])]),e("td",null,[t.type==="langs"?(o(),z(r,{key:0,modelValue:t._input,"onUpdate:modelValue":n=>t._input=n,multiple:!0,disabled:t.disabled},null,8,["modelValue","onUpdate:modelValue","disabled"])):t.type==="lang"?(o(),z(r,{key:1,modelValue:t._input,"onUpdate:modelValue":n=>t._input=n,disabled:t.disabled},null,8,["modelValue","onUpdate:modelValue","disabled"])):t.encrypted?(o(),a(b,{key:2},[e("div",ts,[c(e("input",{type:t._show?"text":"password",class:"field-input pr-14","onUpdate:modelValue":n=>t._input=n,disabled:t.disabled,placeholder:"留空继承默认"},null,8,ls),[[Z,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:n=>t._show=!t._show},d(t._show?"隐藏":"显示"),9,ss)]),l[62]||(l[62]=e("span",{class:"lock-badge ml-1"},"🔒",-1))],64)):te()&&t.key==="type"?c((o(),a("select",{key:3,class:"field-input","onUpdate:modelValue":n=>t._input=n,disabled:t.disabled},[...l[63]||(l[63]=[e("option",{value:""},"继承默认",-1),e("option",{value:"0"},"HTTP",-1),e("option",{value:"1"},"SSE",-1)])],8,os)),[[I,t._input]]):c((o(),a("input",{key:4,class:"field-input","onUpdate:modelValue":n=>t._input=n,disabled:t.disabled,placeholder:"留空继承:"+(t.value||"")},null,8,ns)),[[y,t._input]])])],2))),128)),O.value.length?h("",!0):(o(),a("tr",as,[...l[64]||(l[64]=[e("td",{colspan:"5",class:"text-center text-slate-400 py-3"},"该服务尚无默认字段",-1)])]))])])]),e("div",is,d(W.value)+" 专属字段",1),e("div",null,[F.value.length?(o(),a("div",us,[e("table",rs,[l[67]||(l[67]=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,[(o(!0),a(b,null,k(F.value,(t,i)=>(o(),a("tr",{key:i},[e("td",null,[c(e("input",{class:"field-input","onUpdate:modelValue":n=>t.key=n,placeholder:"key",title:t.key},null,8,cs),[[y,t.key]])]),e("td",null,[c(e("input",{class:"field-input","onUpdate:modelValue":n=>t.description=n,placeholder:"用途描述"},null,8,ps),[[y,t.description]])]),e("td",vs,[c(e("input",{type:"checkbox",class:"checkbox checkbox-xs checkbox-primary","onUpdate:modelValue":n=>t.encrypted=n},null,8,bs),[[L,t.encrypted]])]),e("td",null,[t.encrypted?(o(),a(b,{key:0},[e("div",ms,[c(e("input",{type:t._show?"text":"password",class:"field-input pr-14","onUpdate:modelValue":n=>t._input=n,placeholder:"留空保留原值"},null,8,xs),[[Z,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:n=>t._show=!t._show},d(t._show?"隐藏":"显示"),9,ys)]),l[66]||(l[66]=e("span",{class:"lock-badge ml-1"},"🔒",-1))],64)):c((o(),a("input",{key:1,class:"field-input","onUpdate:modelValue":n=>t._input=n},null,8,_s)),[[y,t._input]])]),e("td",null,[e("button",{class:"btn btn-ghost btn-xs text-error",onClick:n=>Ie(i)},"×",8,hs)])]))),128))])])])):(o(),a("p",ds,"尚无区域专属字段,点击下方添加")),e("button",{class:"btn btn-ghost btn-sm mt-2 text-primary",onClick:Ee},"+ 添加区域专属字段")])],64))],64)):h("",!0)])])):h("",!0),c(e("div",ks,[e("div",gs,[e("div",fs,[e("div",ws,[(o(),a("svg",Vs,[...l[69]||(l[69]=[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[70]||(l[70]=e("h3",{class:"text-base font-semibold text-slate-800"},"同步到其他区域",-1)),e("p",Us,d(xe.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:ye.value},null,8,Cs),e("div",Ss,[l[71]||(l[71]=e("span",{class:"text-xs font-semibold text-slate-500"},"选择目标区域",-1)),e("div",Ts,[e("button",{class:"btn btn-ghost btn-xs",onClick:l[20]||(l[20]=t=>ke(!0))},"全选"),e("button",{class:"btn btn-ghost btn-xs",onClick:l[21]||(l[21]=t=>ke(!1))},"清空")])]),e("div",$s,[(o(!0),a(b,null,k(_e.value,t=>(o(),a("label",{key:t.value,class:A(["sync-region-item",{checked:$.value.includes(t.value)}]),onClick:i=>he(t.value)},[e("input",{type:"checkbox",class:"checkbox checkbox-xs checkbox-primary",checked:$.value.includes(t.value),onClick:Ve(i=>he(t.value),["stop"])},null,8,As),e("span",null,d(t.label),1)],10,Ms))),128))]),l[72]||(l[72]=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:Oe},"仅保存当前区域"),e("button",{class:"btn btn-primary text-white",onClick:He},"保存并同步")])])],512),[[Ue,ne.value]]),c(e("div",zs,[e("div",Fs,[P.value==="list"?(o(),a(b,{key:0},[e("div",Ds,[l[73]||(l[73]=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",Ls,[e("button",{class:"btn btn-primary btn-sm text-white",onClick:l[22]||(l[22]=t=>fe())},"+ 新增模板"),e("button",{class:"btn btn-ghost btn-sm",onClick:Je},"关闭")])]),e("div",js,[(o(!0),a(b,null,k(Ae.value,t=>(o(),a("div",{key:t.cat,class:"mb-3"},[e("p",Es,d(t.label),1),(o(!0),a(b,null,k(t.items,i=>(o(),a("div",{key:i.id,class:"tpl-row"},[e("div",Is,[e("div",Ns,[e("span",Rs,d(i.name),1),e("span",Bs,d(i.provider),1),i.builtin?(o(),a("span",Os,"内置")):h("",!0)]),e("p",Hs,d(i.id)+" · "+d((i.fields||[]).length)+" 字段",1)]),e("div",Ps,[e("button",{class:"btn btn-ghost btn-xs",onClick:n=>fe(i)},"编辑",8,Js),e("button",{class:"btn btn-ghost btn-xs text-error",onClick:n=>Qe(i)},"删除",8,qs)])]))),128))]))),128)),H.value.length?h("",!0):(o(),a("p",Gs,"暂无模板"))])],64)):(o(),a(b,{key:1},[e("div",Ks,[e("h3",Qs,d(J.value?"编辑模板":"新增模板"),1),e("div",Ws,[e("button",{class:"btn btn-ghost btn-sm",onClick:l[23]||(l[23]=t=>P.value="list")},"返回"),e("button",{class:"btn btn-primary btn-sm text-white",onClick:Ke},"保存")])]),e("div",Xs,[e("div",Ys,[l[74]||(l[74]=e("label",{class:"label"},[e("span",{class:"label-text text-xs"},"模板ID *")],-1)),c(e("input",{"onUpdate:modelValue":l[24]||(l[24]=t=>v.id=t),disabled:J.value,class:"input input-bordered input-sm font-mono",placeholder:"tts_azure"},null,8,Zs),[[y,v.id]])]),e("div",eo,[l[75]||(l[75]=e("label",{class:"label"},[e("span",{class:"label-text text-xs"},"类别 *")],-1)),c(e("select",{"onUpdate:modelValue":l[25]||(l[25]=t=>v.category=t),class:"select select-bordered select-sm"},[(o(),a(b,null,k(N,t=>e("option",{key:t.v,value:t.v},d(t.label),9,to)),64))],512),[[I,v.category,void 0,{number:!0}]])]),e("div",lo,[l[76]||(l[76]=e("label",{class:"label"},[e("span",{class:"label-text text-xs"},"服务商标识 *")],-1)),c(e("input",{"onUpdate:modelValue":l[26]||(l[26]=t=>v.provider=t),class:"input input-bordered input-sm font-mono",placeholder:"azure"},null,512),[[y,v.provider]])]),e("div",so,[l[77]||(l[77]=e("label",{class:"label"},[e("span",{class:"label-text text-xs"},"展示名 *")],-1)),c(e("input",{"onUpdate:modelValue":l[27]||(l[27]=t=>v.name=t),class:"input input-bordered input-sm",placeholder:"微软 Azure TTS"},null,512),[[y,v.name]])])]),e("div",oo,[l[78]||(l[78]=e("label",{class:"label"},[e("span",{class:"label-text text-xs"},"描述")],-1)),c(e("input",{"onUpdate:modelValue":l[28]||(l[28]=t=>v.description=t),class:"input input-bordered input-sm"},null,512),[[y,v.description]])]),l[81]||(l[81]=e("p",{class:"text-sm font-medium text-slate-700 mb-1"},"字段",-1)),e("div",no,[e("table",ao,[l[80]||(l[80]=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,[(o(!0),a(b,null,k(S.value,(t,i)=>(o(),a("tr",{key:i},[e("td",null,[c(e("input",{class:"field-input","onUpdate:modelValue":n=>t.key=n,placeholder:"key",title:t.key},null,8,io),[[y,t.key]])]),e("td",null,[c(e("input",{class:"field-input","onUpdate:modelValue":n=>t.description=n,placeholder:"用途描述"},null,8,uo),[[y,t.description]])]),e("td",ro,[c(e("input",{type:"checkbox",class:"checkbox checkbox-xs checkbox-primary","onUpdate:modelValue":n=>t.encrypted=n},null,8,co),[[L,t.encrypted]])]),e("td",null,[t.type==="langs"?(o(),z(r,{key:0,modelValue:t.def_value,"onUpdate:modelValue":n=>t.def_value=n,multiple:!0},null,8,["modelValue","onUpdate:modelValue"])):t.type==="lang"?(o(),z(r,{key:1,modelValue:t.def_value,"onUpdate:modelValue":n=>t.def_value=n},null,8,["modelValue","onUpdate:modelValue"])):c((o(),a("input",{key:2,class:"field-input","onUpdate:modelValue":n=>t.def_value=n,placeholder:"可留空"},null,8,po)),[[y,t.def_value]])]),e("td",null,[e("button",{class:"btn btn-ghost btn-xs text-error",onClick:n=>Ge(i)},"×",8,vo)])]))),128)),S.value.length?h("",!0):(o(),a("tr",bo,[...l[79]||(l[79]=[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:qe},"+ 添加字段")],64))])],512),[[Ue,de.value]])])}}}),wo=et(mo,[["__scopeId","data-v-4e0895d6"]]);export{wo as default}; diff --git a/apps/admin/.output/public/_nuxt/BPYtLuIu.js b/apps/admin/.output/public/_nuxt/BMQvQYtl.js similarity index 96% rename from apps/admin/.output/public/_nuxt/BPYtLuIu.js rename to apps/admin/.output/public/_nuxt/BMQvQYtl.js index 9abc27e3..3502cc80 100644 --- a/apps/admin/.output/public/_nuxt/BPYtLuIu.js +++ b/apps/admin/.output/public/_nuxt/BMQvQYtl.js @@ -1 +1 @@ -import{_ as o,o as s,c as a,a as t,t as r}from"./Ccu6Xgpt.js";import{u as i}from"./oiJG5Pzc.js";const u={class:"antialiased bg-white dark:bg-[#020420] dark:text-white font-sans grid min-h-screen overflow-hidden place-content-center text-[#020420] tracking-wide"},c={class:"max-w-520px text-center"},l=["textContent"],d=["textContent"],p=["textContent"],f={__name:"error-500",props:{appName:{type:String,default:"Nuxt"},status:{type:Number,default:500},statusText:{type:String,default:"Internal server error"},description:{type:String,default:"This page is temporarily unavailable."},refresh:{type:String,default:"Refresh this page"}},setup(e){const n=e;return i({title:`${n.status} - ${n.statusText} | ${n.appName}`,script:[{innerHTML:`!function(){const e=document.createElement("link").relList;if(!(e&&e.supports&&e.supports("modulepreload"))){for(const e of document.querySelectorAll('link[rel="modulepreload"]'))r(e);new MutationObserver(e=>{for(const o of e)if("childList"===o.type)for(const e of o.addedNodes)"LINK"===e.tagName&&"modulepreload"===e.rel&&r(e)}).observe(document,{childList:!0,subtree:!0})}function r(e){if(e.ep)return;e.ep=!0;const r=function(e){const r={};return e.integrity&&(r.integrity=e.integrity),e.referrerPolicy&&(r.referrerPolicy=e.referrerPolicy),"use-credentials"===e.crossOrigin?r.credentials="include":"anonymous"===e.crossOrigin?r.credentials="omit":r.credentials="same-origin",r}(e);fetch(e.href,r)}}();`}],style:[{innerHTML:'*,:after,:before{box-sizing:border-box;border-width:0;border-style:solid;border-color:var(--un-default-border-color,#e5e7eb)}:after,:before{--un-content:""}html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}h1,h2{font-size:inherit;font-weight:inherit}h1,h2,p{margin:0}*,:after,:before{--un-rotate:0;--un-rotate-x:0;--un-rotate-y:0;--un-rotate-z:0;--un-scale-x:1;--un-scale-y:1;--un-scale-z:1;--un-skew-x:0;--un-skew-y:0;--un-translate-x:0;--un-translate-y:0;--un-translate-z:0;--un-pan-x: ;--un-pan-y: ;--un-pinch-zoom: ;--un-scroll-snap-strictness:proximity;--un-ordinal: ;--un-slashed-zero: ;--un-numeric-figure: ;--un-numeric-spacing: ;--un-numeric-fraction: ;--un-border-spacing-x:0;--un-border-spacing-y:0;--un-ring-offset-shadow:0 0 transparent;--un-ring-shadow:0 0 transparent;--un-shadow-inset: ;--un-shadow:0 0 transparent;--un-ring-inset: ;--un-ring-offset-width:0px;--un-ring-offset-color:#fff;--un-ring-width:0px;--un-ring-color:rgba(147,197,253,.5);--un-blur: ;--un-brightness: ;--un-contrast: ;--un-drop-shadow: ;--un-grayscale: ;--un-hue-rotate: ;--un-invert: ;--un-saturate: ;--un-sepia: ;--un-backdrop-blur: ;--un-backdrop-brightness: ;--un-backdrop-contrast: ;--un-backdrop-grayscale: ;--un-backdrop-hue-rotate: ;--un-backdrop-invert: ;--un-backdrop-opacity: ;--un-backdrop-saturate: ;--un-backdrop-sepia: }'}]}),(h,m)=>(s(),a("div",u,[t("div",c,[t("h1",{class:"font-semibold leading-none mb-4 sm:text-[110px] tabular-nums text-[80px]",textContent:r(e.status)},null,8,l),t("h2",{class:"font-semibold mb-2 sm:text-3xl text-2xl",textContent:r(e.statusText)},null,8,d),t("p",{class:"mb-4 px-2 text-[#64748B] text-md",textContent:r(e.description)},null,8,p)])]))}},x=o(f,[["__scopeId","data-v-2c2ce9e3"]]);export{x as default}; +import{_ as o,o as s,c as a,a as t,t as r}from"./mElhLwm2.js";import{u as i}from"./OLpUuA7c.js";const u={class:"antialiased bg-white dark:bg-[#020420] dark:text-white font-sans grid min-h-screen overflow-hidden place-content-center text-[#020420] tracking-wide"},c={class:"max-w-520px text-center"},l=["textContent"],d=["textContent"],p=["textContent"],f={__name:"error-500",props:{appName:{type:String,default:"Nuxt"},status:{type:Number,default:500},statusText:{type:String,default:"Internal server error"},description:{type:String,default:"This page is temporarily unavailable."},refresh:{type:String,default:"Refresh this page"}},setup(e){const n=e;return i({title:`${n.status} - ${n.statusText} | ${n.appName}`,script:[{innerHTML:`!function(){const e=document.createElement("link").relList;if(!(e&&e.supports&&e.supports("modulepreload"))){for(const e of document.querySelectorAll('link[rel="modulepreload"]'))r(e);new MutationObserver(e=>{for(const o of e)if("childList"===o.type)for(const e of o.addedNodes)"LINK"===e.tagName&&"modulepreload"===e.rel&&r(e)}).observe(document,{childList:!0,subtree:!0})}function r(e){if(e.ep)return;e.ep=!0;const r=function(e){const r={};return e.integrity&&(r.integrity=e.integrity),e.referrerPolicy&&(r.referrerPolicy=e.referrerPolicy),"use-credentials"===e.crossOrigin?r.credentials="include":"anonymous"===e.crossOrigin?r.credentials="omit":r.credentials="same-origin",r}(e);fetch(e.href,r)}}();`}],style:[{innerHTML:'*,:after,:before{box-sizing:border-box;border-width:0;border-style:solid;border-color:var(--un-default-border-color,#e5e7eb)}:after,:before{--un-content:""}html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}h1,h2{font-size:inherit;font-weight:inherit}h1,h2,p{margin:0}*,:after,:before{--un-rotate:0;--un-rotate-x:0;--un-rotate-y:0;--un-rotate-z:0;--un-scale-x:1;--un-scale-y:1;--un-scale-z:1;--un-skew-x:0;--un-skew-y:0;--un-translate-x:0;--un-translate-y:0;--un-translate-z:0;--un-pan-x: ;--un-pan-y: ;--un-pinch-zoom: ;--un-scroll-snap-strictness:proximity;--un-ordinal: ;--un-slashed-zero: ;--un-numeric-figure: ;--un-numeric-spacing: ;--un-numeric-fraction: ;--un-border-spacing-x:0;--un-border-spacing-y:0;--un-ring-offset-shadow:0 0 transparent;--un-ring-shadow:0 0 transparent;--un-shadow-inset: ;--un-shadow:0 0 transparent;--un-ring-inset: ;--un-ring-offset-width:0px;--un-ring-offset-color:#fff;--un-ring-width:0px;--un-ring-color:rgba(147,197,253,.5);--un-blur: ;--un-brightness: ;--un-contrast: ;--un-drop-shadow: ;--un-grayscale: ;--un-hue-rotate: ;--un-invert: ;--un-saturate: ;--un-sepia: ;--un-backdrop-blur: ;--un-backdrop-brightness: ;--un-backdrop-contrast: ;--un-backdrop-grayscale: ;--un-backdrop-hue-rotate: ;--un-backdrop-invert: ;--un-backdrop-opacity: ;--un-backdrop-saturate: ;--un-backdrop-sepia: }'}]}),(h,m)=>(s(),a("div",u,[t("div",c,[t("h1",{class:"font-semibold leading-none mb-4 sm:text-[110px] tabular-nums text-[80px]",textContent:r(e.status)},null,8,l),t("h2",{class:"font-semibold mb-2 sm:text-3xl text-2xl",textContent:r(e.statusText)},null,8,d),t("p",{class:"mb-4 px-2 text-[#64748B] text-md",textContent:r(e.description)},null,8,p)])]))}},x=o(f,[["__scopeId","data-v-2c2ce9e3"]]);export{x as default}; diff --git a/apps/admin/.output/public/_nuxt/B8Fu162H.js b/apps/admin/.output/public/_nuxt/BRt-3vKG.js similarity index 99% rename from apps/admin/.output/public/_nuxt/B8Fu162H.js rename to apps/admin/.output/public/_nuxt/BRt-3vKG.js index e88ce332..f6f32c7f 100644 --- a/apps/admin/.output/public/_nuxt/B8Fu162H.js +++ b/apps/admin/.output/public/_nuxt/BRt-3vKG.js @@ -1,4 +1,4 @@ -import{g as ce,j as Ce,k as fe,o as a,c as o,a as e,d as b,l as k,F as M,r as F,n as O,t as i,m as _e,p as h,v as E,q as re,s as ye,x as N,y as ee,z as W,A as Te,_ as me,B as ke,C as Me,D as Ne,E as De,G as xe,H as Ie,b as Se,I as Ue}from"./Ccu6Xgpt.js";import{u as ge}from"./Um-KoueI.js";import{u as be}from"./DvwKXRUn.js";import"./CH2ZVAK2.js";const Ve={class:"card"},Ae={class:"card-head"},Oe={key:0,class:"py-14 text-center text-slate-400 text-sm"},Ee={class:"min-w-0"},Re={class:"dep-name"},je={class:"truncate"},Le={key:0,class:"chip chip-warn"},ze={key:1,class:"chip chip-ok"},Be={key:2,class:"chip"},qe={class:"dep-sub"},Pe=["title"],Fe={class:"flex items-center gap-1.5"},He={key:0,class:"text-[10.5px] text-amber-700",title:"latest 是可变 tag,升级后无法从列表看出实际版本"},Je={class:"min-w-0"},Ge={class:"dep-acts"},Ye=["onClick"],Ke=["onClick"],Qe=["disabled","title","onClick"],We=["onClick"],Xe=["disabled","onClick"],Ze=["disabled","onClick"],et=["onClick"],tt={class:"modal-box max-w-3xl"},st={class:"font-bold text-lg"},lt={key:0,class:"tabs tabs-boxed bg-slate-100 w-fit my-3"},nt={class:"grid grid-cols-2 gap-3"},at={class:"form-control"},ot=["value"],it={class:"form-control"},dt=["placeholder"],rt={class:"grid grid-cols-2 gap-3"},ut={class:"form-control"},pt=["value"],ct={class:"form-control"},mt={class:"label py-1"},gt={class:"label-text text-sm font-medium"},bt={value:0},vt=["value"],xt={class:"grid grid-cols-3 gap-3"},ft={class:"form-control"},_t={class:"form-control"},yt=["placeholder"],kt={class:"form-control"},ht={class:"form-control"},$t={class:"label py-1"},wt={class:"label-text text-sm font-medium"},Ct={class:"form-control"},Tt={key:0,class:"text-sm space-y-0.5"},Mt={class:"form-control"},Nt={class:"flex items-center gap-2 cursor-pointer"},Dt={class:"modal-action"},It=["disabled"],St=["disabled"],Ut={key:1,class:"text-[11px] text-slate-400 text-right"},Vt={class:"modal-box max-w-2xl"},At={class:"text-sm text-slate-500 mt-1"},Ot={class:"grid grid-cols-[76px_1fr] gap-x-3 gap-y-1 text-xs mt-4"},Et={class:"mt-3"},Rt={class:"flex items-center justify-between mb-1"},jt=["disabled"],Lt={key:0,class:"flex gap-2"},zt=["disabled"],Bt={value:""},qt=["value"],Pt=["value"],Ft=["disabled"],Ht=["disabled"],Jt={key:2,class:"text-xs text-amber-600 mt-1"},Gt={key:3,class:"text-xs text-amber-600 mt-1"},Yt={key:0,class:"mt-3"},Kt={class:"flex items-center gap-2 text-xs mb-1"},Qt={key:0,class:"loading loading-spinner loading-xs text-amber-500"},Wt={key:1,class:"text-green-600 font-semibold"},Xt={key:2,class:"text-red-600 font-semibold"},Zt={class:"text-slate-400"},es={class:"modal-action"},ts=["disabled"],ss=["disabled"],ls={method:"dialog",class:"modal-backdrop"},ns=["disabled"],as={class:"modal-box"},os={class:"text-sm text-slate-500 mt-1"},is={class:"grid grid-cols-2 gap-3 mt-4"},ds={key:0,class:"text-sm mt-3"},rs={key:0,class:"bg-slate-50 border border-slate-200 rounded-lg p-3"},us={class:"flex justify-between items-center text-xs mb-1.5"},ps={class:"text-slate-600"},cs={class:"font-mono text-slate-400"},ms=["value"],gs={class:"mt-2 text-xs space-y-0.5"},bs={key:1,class:"text-red-600"},vs={key:2,class:"bg-green-50 border border-green-100 rounded-lg p-3"},xs={class:"grid grid-cols-2 gap-x-4 gap-y-1 text-xs text-slate-600 mb-2"},fs={class:"border-t border-green-100 pt-2 text-xs"},_s={class:"text-slate-500"},ys={class:"font-mono text-slate-700"},ks={class:"modal-action"},hs=["disabled"],$s=["disabled"],ws={method:"dialog",class:"modal-backdrop"},Cs=["disabled"],Ts=ce({__name:"AppDeployTab",props:{appName:{},defaultImage:{},deployments:{},envs:{}},emits:["refresh","configure"],setup(P,{expose:R,emit:H}){const J=P,L=H,{consoleApi:S}=ge(),{success:$,error:g}=be(),x=Ce(),G=fe(),Y=["中国","美国","东亚","东南亚","南亚","中东","欧洲","俄罗斯","非洲","南美","北美","大洋洲","巴西","印度"];function V(d){const t=(d||"").match(/\/([^/?]+)\?/);return t?t[1]:d?"(自定义)":"未配置"}function f(d){const t=(d||"").trim();return!!t&&t!=="latest"}function z(d){return d?J.envs.find(t=>t.id===d)?.name??"#"+d:""}function j(d){let t=(d.base_url||"").trim().replace(/\/+$/,"");if(!t){g("该部署未配置对外地址(base_url)");return}/^https?:\/\//i.test(t)||(t="https://"+t),window.open(t+"/swagger/index.html","_blank","noopener")}function A(d){window.confirm(`向部署 #${d} 发送一条配置 reload 事件?`)&&S("config/notify",{app_id:d,type:"all",action:"reload"}).then(t=>$("已发送 → "+(t&&t.subject))).catch(t=>g(t?.message??"发送失败"))}function ae(d){window.confirm(`删除部署「${d.name||"#"+d.id}」?(不影响应用自身的库)`)&&S("apps/del",{id:d.id}).then(()=>{$("已删除"),L("refresh")}).catch(t=>g(t?.message??"删除失败"))}const K=N(null),D=N(!1),y=N("existing"),m=ee({id:0,name:"",region:"",env_id:0,base_url:"",service_dsn:"",deploy_dir:"",image_name:"",image_tag:"",remark:"",enabled:!0}),_=N(!1),X=N(!1),I=ee({show:!1,apiOk:!1,apiMsg:"",dbOk:!1,dbMsg:""}),v=W(()=>{const d=new Set(J.deployments.filter(t=>t.id!==m.id).map(t=>t.region).filter(Boolean));return Y.filter(t=>!d.has(t)||t===m.region)});function s(){_.value=!1,I.show=!1}function c(d){y.value=d,s()}function r(){D.value=!1,y.value="existing",Object.assign(m,{id:0,name:"",region:"",env_id:0,base_url:"",service_dsn:"",deploy_dir:"",image_name:J.defaultImage,image_tag:"",remark:"",enabled:!0}),s(),K.value?.showModal()}function u(d){D.value=!0,y.value=d.status==="pending"?"deploy":"existing",Object.assign(m,{id:d.id,name:d.name||"",region:d.region||"",env_id:d.env_id||0,base_url:d.base_url||"",service_dsn:d.service_dsn||"",deploy_dir:d.deploy_dir||"",image_name:d.image_name||"",image_tag:d.image_tag||"",remark:d.remark||"",enabled:!!d.enabled}),s(),K.value?.showModal()}async function te(){const d=m.base_url.trim(),t=m.service_dsn.trim();if(!d||!t){g("请先填应用地址和业务库 DSN");return}X.value=!0;try{const l=await S("apps/test",{base_url:d,service_dsn:t});I.apiOk=!!l.api_ok,I.apiMsg=l.api_msg,I.dbOk=!!l.db_ok,I.dbMsg=l.db_msg,I.show=!0,_.value=!!l.ok,_.value?$("检测通过,可以保存"):g("检测未通过")}catch(l){g(l?.message??"测试失败")}finally{X.value=!1}}async function ue(){if(!m.name.trim()){g("请填部署名称");return}if(!D.value&&y.value==="existing"&&!_.value){g("请先「测试连接」通过再保存");return}if(y.value==="deploy"&&!m.env_id){g("请选择部署目标环境");return}const d={app_name:J.appName,status:y.value==="deploy"?"pending":"existing",name:m.name,region:m.region,env_id:Number(m.env_id)||0,base_url:y.value==="deploy"?"":m.base_url,service_dsn:m.service_dsn,deploy_dir:m.deploy_dir,image_name:m.image_name,image_tag:m.image_tag,remark:m.remark,enabled:m.enabled};let t="apps/add";D.value&&m.id&&(d.id=Number(m.id),t="apps/update");try{await S(t,d),$("保存成功"),K.value?.close(),L("refresh")}catch(l){g(l?.message??"保存失败")}}const Z=N(null),se=N(null),n=ee({id:0,label:"",envName:"",deployDir:"",tag:"",tags:[],tagMode:"list",tagsLoading:!1,tagsError:"",log:"",show:!1,running:!1,ok:!1,canRun:!1,btnText:"开始升级"});function B(d){n.id=d.id,n.label="部署:"+(d.name||"部署#"+d.id)+(d.region?" · "+d.region:""),n.envName=z(d.env_id),n.deployDir=d.deploy_dir||"",n.tag=d.image_tag||"",n.tags=[],n.tagMode="list",n.tagsError="",n.log="",n.show=!1,n.running=!1,n.ok=!1,n.canRun=!!(d.env_id&&(d.deploy_dir||"").trim()),n.btnText="开始升级",Z.value?.showModal(),n.canRun&&q()}async function q(){if(n.id){n.tagsLoading=!0,n.tagsError="";try{const d=await S("apps/tags",{id:n.id});n.tags=d.tags||[],n.tagMode="list",(!n.tag||!n.tags.includes(n.tag))&&(n.tag=n.tags.find(t=>t!=="latest")||n.tag||"")}catch(d){n.tagsError=d?.message??"拉取失败"}finally{n.tagsLoading=!1}}}async function Q(){if(n.running)return;if(!n.canRun){const U=[];n.envName||U.push("绑定环境节点"),n.deployDir||U.push("填写部署目录"),window.alert(`无法升级:请先关闭本弹窗,点该部署的「编辑」完成 —— ${U.join("、")},保存后再来升级。`);return}const d=(n.tag||"").trim();if(!f(d)&&!window.confirm(`未选择明确版本号(当前 = ${d||"空 → 后端回退 latest"})。 +import{g as ce,j as Ce,k as fe,o as a,c as o,a as e,d as b,l as k,F as M,r as F,n as O,t as i,m as _e,p as h,v as E,q as re,s as ye,x as N,y as ee,z as W,A as Te,_ as me,B as ke,C as Me,D as Ne,E as De,G as xe,H as Ie,b as Se,I as Ue}from"./mElhLwm2.js";import{u as ge}from"./C6twYRfy.js";import{u as be}from"./FVTAbpot.js";import"./qig5Qp6S.js";const Ve={class:"card"},Ae={class:"card-head"},Oe={key:0,class:"py-14 text-center text-slate-400 text-sm"},Ee={class:"min-w-0"},Re={class:"dep-name"},je={class:"truncate"},Le={key:0,class:"chip chip-warn"},ze={key:1,class:"chip chip-ok"},Be={key:2,class:"chip"},qe={class:"dep-sub"},Pe=["title"],Fe={class:"flex items-center gap-1.5"},He={key:0,class:"text-[10.5px] text-amber-700",title:"latest 是可变 tag,升级后无法从列表看出实际版本"},Je={class:"min-w-0"},Ge={class:"dep-acts"},Ye=["onClick"],Ke=["onClick"],Qe=["disabled","title","onClick"],We=["onClick"],Xe=["disabled","onClick"],Ze=["disabled","onClick"],et=["onClick"],tt={class:"modal-box max-w-3xl"},st={class:"font-bold text-lg"},lt={key:0,class:"tabs tabs-boxed bg-slate-100 w-fit my-3"},nt={class:"grid grid-cols-2 gap-3"},at={class:"form-control"},ot=["value"],it={class:"form-control"},dt=["placeholder"],rt={class:"grid grid-cols-2 gap-3"},ut={class:"form-control"},pt=["value"],ct={class:"form-control"},mt={class:"label py-1"},gt={class:"label-text text-sm font-medium"},bt={value:0},vt=["value"],xt={class:"grid grid-cols-3 gap-3"},ft={class:"form-control"},_t={class:"form-control"},yt=["placeholder"],kt={class:"form-control"},ht={class:"form-control"},$t={class:"label py-1"},wt={class:"label-text text-sm font-medium"},Ct={class:"form-control"},Tt={key:0,class:"text-sm space-y-0.5"},Mt={class:"form-control"},Nt={class:"flex items-center gap-2 cursor-pointer"},Dt={class:"modal-action"},It=["disabled"],St=["disabled"],Ut={key:1,class:"text-[11px] text-slate-400 text-right"},Vt={class:"modal-box max-w-2xl"},At={class:"text-sm text-slate-500 mt-1"},Ot={class:"grid grid-cols-[76px_1fr] gap-x-3 gap-y-1 text-xs mt-4"},Et={class:"mt-3"},Rt={class:"flex items-center justify-between mb-1"},jt=["disabled"],Lt={key:0,class:"flex gap-2"},zt=["disabled"],Bt={value:""},qt=["value"],Pt=["value"],Ft=["disabled"],Ht=["disabled"],Jt={key:2,class:"text-xs text-amber-600 mt-1"},Gt={key:3,class:"text-xs text-amber-600 mt-1"},Yt={key:0,class:"mt-3"},Kt={class:"flex items-center gap-2 text-xs mb-1"},Qt={key:0,class:"loading loading-spinner loading-xs text-amber-500"},Wt={key:1,class:"text-green-600 font-semibold"},Xt={key:2,class:"text-red-600 font-semibold"},Zt={class:"text-slate-400"},es={class:"modal-action"},ts=["disabled"],ss=["disabled"],ls={method:"dialog",class:"modal-backdrop"},ns=["disabled"],as={class:"modal-box"},os={class:"text-sm text-slate-500 mt-1"},is={class:"grid grid-cols-2 gap-3 mt-4"},ds={key:0,class:"text-sm mt-3"},rs={key:0,class:"bg-slate-50 border border-slate-200 rounded-lg p-3"},us={class:"flex justify-between items-center text-xs mb-1.5"},ps={class:"text-slate-600"},cs={class:"font-mono text-slate-400"},ms=["value"],gs={class:"mt-2 text-xs space-y-0.5"},bs={key:1,class:"text-red-600"},vs={key:2,class:"bg-green-50 border border-green-100 rounded-lg p-3"},xs={class:"grid grid-cols-2 gap-x-4 gap-y-1 text-xs text-slate-600 mb-2"},fs={class:"border-t border-green-100 pt-2 text-xs"},_s={class:"text-slate-500"},ys={class:"font-mono text-slate-700"},ks={class:"modal-action"},hs=["disabled"],$s=["disabled"],ws={method:"dialog",class:"modal-backdrop"},Cs=["disabled"],Ts=ce({__name:"AppDeployTab",props:{appName:{},defaultImage:{},deployments:{},envs:{}},emits:["refresh","configure"],setup(P,{expose:R,emit:H}){const J=P,L=H,{consoleApi:S}=ge(),{success:$,error:g}=be(),x=Ce(),G=fe(),Y=["中国","美国","东亚","东南亚","南亚","中东","欧洲","俄罗斯","非洲","南美","北美","大洋洲","巴西","印度"];function V(d){const t=(d||"").match(/\/([^/?]+)\?/);return t?t[1]:d?"(自定义)":"未配置"}function f(d){const t=(d||"").trim();return!!t&&t!=="latest"}function z(d){return d?J.envs.find(t=>t.id===d)?.name??"#"+d:""}function j(d){let t=(d.base_url||"").trim().replace(/\/+$/,"");if(!t){g("该部署未配置对外地址(base_url)");return}/^https?:\/\//i.test(t)||(t="https://"+t),window.open(t+"/swagger/index.html","_blank","noopener")}function A(d){window.confirm(`向部署 #${d} 发送一条配置 reload 事件?`)&&S("config/notify",{app_id:d,type:"all",action:"reload"}).then(t=>$("已发送 → "+(t&&t.subject))).catch(t=>g(t?.message??"发送失败"))}function ae(d){window.confirm(`删除部署「${d.name||"#"+d.id}」?(不影响应用自身的库)`)&&S("apps/del",{id:d.id}).then(()=>{$("已删除"),L("refresh")}).catch(t=>g(t?.message??"删除失败"))}const K=N(null),D=N(!1),y=N("existing"),m=ee({id:0,name:"",region:"",env_id:0,base_url:"",service_dsn:"",deploy_dir:"",image_name:"",image_tag:"",remark:"",enabled:!0}),_=N(!1),X=N(!1),I=ee({show:!1,apiOk:!1,apiMsg:"",dbOk:!1,dbMsg:""}),v=W(()=>{const d=new Set(J.deployments.filter(t=>t.id!==m.id).map(t=>t.region).filter(Boolean));return Y.filter(t=>!d.has(t)||t===m.region)});function s(){_.value=!1,I.show=!1}function c(d){y.value=d,s()}function r(){D.value=!1,y.value="existing",Object.assign(m,{id:0,name:"",region:"",env_id:0,base_url:"",service_dsn:"",deploy_dir:"",image_name:J.defaultImage,image_tag:"",remark:"",enabled:!0}),s(),K.value?.showModal()}function u(d){D.value=!0,y.value=d.status==="pending"?"deploy":"existing",Object.assign(m,{id:d.id,name:d.name||"",region:d.region||"",env_id:d.env_id||0,base_url:d.base_url||"",service_dsn:d.service_dsn||"",deploy_dir:d.deploy_dir||"",image_name:d.image_name||"",image_tag:d.image_tag||"",remark:d.remark||"",enabled:!!d.enabled}),s(),K.value?.showModal()}async function te(){const d=m.base_url.trim(),t=m.service_dsn.trim();if(!d||!t){g("请先填应用地址和业务库 DSN");return}X.value=!0;try{const l=await S("apps/test",{base_url:d,service_dsn:t});I.apiOk=!!l.api_ok,I.apiMsg=l.api_msg,I.dbOk=!!l.db_ok,I.dbMsg=l.db_msg,I.show=!0,_.value=!!l.ok,_.value?$("检测通过,可以保存"):g("检测未通过")}catch(l){g(l?.message??"测试失败")}finally{X.value=!1}}async function ue(){if(!m.name.trim()){g("请填部署名称");return}if(!D.value&&y.value==="existing"&&!_.value){g("请先「测试连接」通过再保存");return}if(y.value==="deploy"&&!m.env_id){g("请选择部署目标环境");return}const d={app_name:J.appName,status:y.value==="deploy"?"pending":"existing",name:m.name,region:m.region,env_id:Number(m.env_id)||0,base_url:y.value==="deploy"?"":m.base_url,service_dsn:m.service_dsn,deploy_dir:m.deploy_dir,image_name:m.image_name,image_tag:m.image_tag,remark:m.remark,enabled:m.enabled};let t="apps/add";D.value&&m.id&&(d.id=Number(m.id),t="apps/update");try{await S(t,d),$("保存成功"),K.value?.close(),L("refresh")}catch(l){g(l?.message??"保存失败")}}const Z=N(null),se=N(null),n=ee({id:0,label:"",envName:"",deployDir:"",tag:"",tags:[],tagMode:"list",tagsLoading:!1,tagsError:"",log:"",show:!1,running:!1,ok:!1,canRun:!1,btnText:"开始升级"});function B(d){n.id=d.id,n.label="部署:"+(d.name||"部署#"+d.id)+(d.region?" · "+d.region:""),n.envName=z(d.env_id),n.deployDir=d.deploy_dir||"",n.tag=d.image_tag||"",n.tags=[],n.tagMode="list",n.tagsError="",n.log="",n.show=!1,n.running=!1,n.ok=!1,n.canRun=!!(d.env_id&&(d.deploy_dir||"").trim()),n.btnText="开始升级",Z.value?.showModal(),n.canRun&&q()}async function q(){if(n.id){n.tagsLoading=!0,n.tagsError="";try{const d=await S("apps/tags",{id:n.id});n.tags=d.tags||[],n.tagMode="list",(!n.tag||!n.tags.includes(n.tag))&&(n.tag=n.tags.find(t=>t!=="latest")||n.tag||"")}catch(d){n.tagsError=d?.message??"拉取失败"}finally{n.tagsLoading=!1}}}async function Q(){if(n.running)return;if(!n.canRun){const U=[];n.envName||U.push("绑定环境节点"),n.deployDir||U.push("填写部署目录"),window.alert(`无法升级:请先关闭本弹窗,点该部署的「编辑」完成 —— ${U.join("、")},保存后再来升级。`);return}const d=(n.tag||"").trim();if(!f(d)&&!window.confirm(`未选择明确版本号(当前 = ${d||"空 → 后端回退 latest"})。 latest 是可变 tag,升级后列表无法体现具体版本号,确定继续?`)||!window.confirm(`确认升级【${n.label}】? 目标版本:${d||"latest"} 将 SSH 连到「${n.envName}」,在 ${n.deployDir} 执行 docker compose 拉新镜像并重启容器。`))return;n.running=!0,n.show=!0,n.ok=!1,n.log="",n.btnText="升级中…";let t=null,l=!1;function w(U){n.log+=(n.log?` diff --git a/apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/DSpyBzHW.js b/apps/admin/.output/public/_nuxt/Bf3Eg9kO.js similarity index 97% rename from apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/DSpyBzHW.js rename to apps/admin/.output/public/_nuxt/Bf3Eg9kO.js index 87c8bf26..7655e129 100644 --- a/apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/DSpyBzHW.js +++ b/apps/admin/.output/public/_nuxt/Bf3Eg9kO.js @@ -1 +1 @@ -import{g as I,B as J,c as a,p,H as j,a as e,F as g,r as h,q,v as y,t as d,l as K,m as Q,x as r,y as W,z as w,o as i}from"./Ccu6Xgpt.js";import{u as X}from"./Um-KoueI.js";import{u as Y}from"./DvwKXRUn.js";import"./CH2ZVAK2.js";const Z={class:"flex items-center justify-between mb-5"},ee=["disabled"],te={class:"flex items-center gap-3 mb-4 flex-wrap"},se=["value"],le=["disabled"],ne=["value"],oe={key:0,class:"bg-white rounded-xl shadow-sm border border-slate-100 text-center text-slate-400 py-16"},ae={class:"text-sm"},ie={key:1,class:"bg-white rounded-xl shadow-sm border border-slate-100"},ue={class:"overflow-x-auto"},de={class:"table"},re={key:0},pe={key:1},me={class:"bg-slate-100/80"},ve={colspan:"4",class:"py-2"},ce={class:"font-semibold text-slate-600 text-sm"},be={class:"text-xs text-slate-400 ml-2"},fe={class:"font-mono text-sm font-medium"},xe=["title"],ge={class:"text-sm text-slate-400"},ye={class:"text-right"},we={class:"inline-flex gap-1"},_e=["onClick"],ke=["onClick"],he={class:"flex items-center gap-3 mb-5"},Ce={class:"text-lg font-semibold text-slate-800"},$e={class:"text-xs text-slate-400"},Ve={class:"bg-white rounded-xl shadow-sm border border-slate-100 p-6 max-w-2xl"},Ae={class:"form-control mb-4"},Ne={class:"form-control mb-4"},Se={class:"form-control mb-4"},Ue={class:"form-control mb-6"},De={class:"flex gap-3"},Le=["disabled"],qe=I({__name:"appconfig",setup(Be){const{consoleApi:v}=X(),{success:D,error:c}=Y(),_=r("list"),b=r([]),C=r([]),m=r(""),u=r(0),f=r([]),$=r(!1),V=r(!1),k=r(!1),A=r(""),n=W({id:0,group:"",key:"",value:"",description:""}),N=w(()=>[...new Set(b.value.map(s=>s.app_name||s.name).filter(Boolean))].sort()),L=w(()=>b.value.filter(s=>(s.app_name||s.name)===m.value));function B(s){const t=C.value.find(U=>U.id===s.env_id),l=t?t.name||t.code:s.env_id?`环境#${s.env_id}`:"未关联环境",o=s.status==="pending"?"(待部署)":"";return s.region?`${l} · ${s.region}${o}`:`${l}${o}`}const O=w(()=>{const s=b.value.find(t=>t.id===u.value);return s?`${s.app_name||s.name} · ${B(s)}`:""}),M=w(()=>{const s=A.value.trim().toLowerCase();return s?f.value.filter(t=>((t.group||"")+(t.key||"")).toLowerCase().includes(s)):f.value}),R=w(()=>{const s={};return M.value.forEach(l=>{const o=l.group||"";(s[o]=s[o]||[]).push(l)}),Object.keys(s).sort((l,o)=>l===""?-1:o===""?1:l({key:l,label:l||"未分组",items:s[l]}))});async function T(){try{const[s,t]=await Promise.all([v("apps/list",{}),v("envs/list",{})]);b.value=s??[],C.value=t??[],!m.value&&N.value.length&&(m.value=N.value[0],E(),await x())}catch(s){c(s?.message??"获取应用列表失败"),b.value=[],C.value=[]}}function E(){const s=L.value,t=s.find(l=>l.status!=="pending")??s[0];u.value=t?.id??0}function z(){E(),x()}async function x(){if(!u.value){f.value=[];return}$.value=!0;try{const s=await v("appcfg/list",{app_id:u.value});f.value=s?.items??[]}catch(s){c(s?.message??"获取配置失败"),f.value=[]}finally{$.value=!1}}function H(){x()}function S(){_.value="list",x()}function F(s){s?(k.value=!0,n.id=s.id||0,n.group=s.group||"",n.key=s.key||"",n.value=s.value||"",n.description=s.description||""):(k.value=!1,n.id=0,n.group="",n.key="",n.value="",n.description=""),_.value="form"}async function P(){if(!u.value){c("请先选择应用和部署环境");return}V.value=!0;try{const s={app_id:u.value,group:n.group.trim(),key:n.key.trim(),value:n.value,description:n.description.trim()};k.value?(s.id=Number(n.id),await v("appcfg/update",s)):await v("appcfg/add",s),D("保存成功"),S()}catch(s){c(s?.message??"保存失败")}finally{V.value=!1}}function G(s){window.confirm("确定删除该配置项吗?")&&v("appcfg/del",{app_id:u.value,ids:[s.id]}).then(()=>{D("删除成功"),x()}).catch(t=>c(t?.message??"删除失败"))}return J(T),(s,t)=>(i(),a("div",null,[p(e("div",null,[e("div",Z,[t[10]||(t[10]=e("div",null,[e("h2",{class:"text-lg font-semibold text-slate-800"},"应用环境配置"),e("p",{class:"text-xs text-slate-400 mt-1"},"应用自有的 key/value 配置(音乐、OSS 等),直接读写所选应用的业务库。结构同「全局环境配置」但不分区域。")],-1)),e("button",{class:"btn btn-primary btn-sm text-white",disabled:!u.value,onClick:t[0]||(t[0]=l=>F())},"+ 新增配置",8,ee)]),e("div",te,[t[13]||(t[13]=e("span",{class:"text-sm text-slate-500"},"应用",-1)),p(e("select",{"onUpdate:modelValue":t[1]||(t[1]=l=>m.value=l),class:"select select-bordered select-sm min-w-40",onChange:z},[t[11]||(t[11]=e("option",{value:"",disabled:""},"请选择应用",-1)),(i(!0),a(g,null,h(N.value,l=>(i(),a("option",{key:l,value:l},d(l),9,se))),128))],544),[[q,m.value]]),t[14]||(t[14]=e("span",{class:"text-sm text-slate-500"},"部署环境",-1)),p(e("select",{"onUpdate:modelValue":t[2]||(t[2]=l=>u.value=l),class:"select select-bordered select-sm min-w-48",disabled:!m.value,onChange:H},[t[12]||(t[12]=e("option",{value:0,disabled:""},"请选择环境",-1)),(i(!0),a(g,null,h(L.value,l=>(i(),a("option",{key:l.id,value:l.id},d(B(l)),9,ne))),128))],40,le),[[q,u.value,void 0,{number:!0}]]),p(e("input",{"onUpdate:modelValue":t[3]||(t[3]=l=>A.value=l),class:"input input-bordered input-sm w-48",placeholder:"按分组/键搜索"},null,512),[[y,A.value]])]),u.value?(i(),a("div",ie,[e("div",ue,[e("table",de,[t[18]||(t[18]=e("thead",null,[e("tr",null,[e("th",null,"键"),e("th",null,"值"),e("th",null,"描述"),e("th",{class:"text-right"},"操作")])],-1)),e("tbody",null,[$.value?(i(),a("tr",re,[...t[16]||(t[16]=[e("td",{colspan:"4",class:"text-center py-8"},[e("span",{class:"loading loading-spinner loading-sm"})],-1)])])):M.value.length?K("",!0):(i(),a("tr",pe,[...t[17]||(t[17]=[e("td",{colspan:"4",class:"text-center text-slate-400 py-8"},"暂无配置",-1)])])),(i(!0),a(g,null,h(R.value,l=>(i(),a(g,{key:l.key},[e("tr",me,[e("td",ve,[e("span",ce,"▸ "+d(l.label),1),e("span",be,d(l.items.length)+" 项",1)])]),(i(!0),a(g,null,h(l.items,o=>(i(),a("tr",{key:o.id,class:"hover"},[e("td",fe,d(o.key||""),1),e("td",{class:"text-sm text-slate-500 max-w-xs truncate",title:o.value||""},d(o.value||""),9,xe),e("td",ge,d(o.description||""),1),e("td",ye,[e("div",we,[e("button",{class:"btn btn-ghost btn-xs",onClick:U=>F(o)},"编辑",8,_e),e("button",{class:"btn btn-ghost btn-xs text-red-500",onClick:U=>G(o)},"删除",8,ke)])])]))),128))],64))),128))])])])])):(i(),a("div",oe,[t[15]||(t[15]=e("div",{class:"text-4xl mb-2"},"🗂️",-1)),e("p",ae,d(m.value?"该应用还没有部署环境,请先在「应用中心」为它部署一个环境":"请先在上方选择应用和部署环境"),1)]))],512),[[j,_.value==="list"]]),p(e("div",null,[e("div",he,[e("button",{class:"btn btn-ghost btn-sm",onClick:t[4]||(t[4]=l=>S())},"← 返回列表"),e("h2",Ce,d(k.value?"编辑配置":"新增配置"),1),e("span",$e,"配置目标:"+d(O.value),1)]),e("div",Ve,[e("form",{onSubmit:Q(P,["prevent"])},[e("div",Ae,[t[19]||(t[19]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"分组 (group)")],-1)),p(e("input",{"onUpdate:modelValue":t[5]||(t[5]=l=>n.group=l),type:"text",class:"input input-bordered w-full",placeholder:"如 music / oss / other"},null,512),[[y,n.group]])]),e("div",Ne,[t[20]||(t[20]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"键 (key) *")],-1)),p(e("input",{"onUpdate:modelValue":t[6]||(t[6]=l=>n.key=l),type:"text",class:"input input-bordered w-full",required:"",placeholder:"如 oss_access_key"},null,512),[[y,n.key]])]),e("div",Se,[t[21]||(t[21]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"值 (value)")],-1)),p(e("textarea",{"onUpdate:modelValue":t[7]||(t[7]=l=>n.value=l),class:"textarea textarea-bordered w-full font-mono text-sm",rows:"3"},null,512),[[y,n.value]])]),e("div",Ue,[t[22]||(t[22]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"描述")],-1)),p(e("input",{"onUpdate:modelValue":t[8]||(t[8]=l=>n.description=l),type:"text",class:"input input-bordered w-full"},null,512),[[y,n.description]])]),e("div",De,[e("button",{type:"button",class:"btn btn-ghost",onClick:t[9]||(t[9]=l=>S())},"取消"),e("button",{type:"submit",class:"btn btn-primary text-white",disabled:V.value},"保存",8,Le)])],32)])],512),[[j,_.value==="form"]])]))}});export{qe as default}; +import{g as I,B as J,c as a,p,H as j,a as e,F as g,r as h,q,v as y,t as d,l as K,m as Q,x as r,y as W,z as w,o as i}from"./mElhLwm2.js";import{u as X}from"./C6twYRfy.js";import{u as Y}from"./FVTAbpot.js";import"./qig5Qp6S.js";const Z={class:"flex items-center justify-between mb-5"},ee=["disabled"],te={class:"flex items-center gap-3 mb-4 flex-wrap"},se=["value"],le=["disabled"],ne=["value"],oe={key:0,class:"bg-white rounded-xl shadow-sm border border-slate-100 text-center text-slate-400 py-16"},ae={class:"text-sm"},ie={key:1,class:"bg-white rounded-xl shadow-sm border border-slate-100"},ue={class:"overflow-x-auto"},de={class:"table"},re={key:0},pe={key:1},me={class:"bg-slate-100/80"},ve={colspan:"4",class:"py-2"},ce={class:"font-semibold text-slate-600 text-sm"},be={class:"text-xs text-slate-400 ml-2"},fe={class:"font-mono text-sm font-medium"},xe=["title"],ge={class:"text-sm text-slate-400"},ye={class:"text-right"},we={class:"inline-flex gap-1"},_e=["onClick"],ke=["onClick"],he={class:"flex items-center gap-3 mb-5"},Ce={class:"text-lg font-semibold text-slate-800"},$e={class:"text-xs text-slate-400"},Ve={class:"bg-white rounded-xl shadow-sm border border-slate-100 p-6 max-w-2xl"},Ae={class:"form-control mb-4"},Ne={class:"form-control mb-4"},Se={class:"form-control mb-4"},Ue={class:"form-control mb-6"},De={class:"flex gap-3"},Le=["disabled"],qe=I({__name:"appconfig",setup(Be){const{consoleApi:v}=X(),{success:D,error:c}=Y(),_=r("list"),b=r([]),C=r([]),m=r(""),u=r(0),f=r([]),$=r(!1),V=r(!1),k=r(!1),A=r(""),n=W({id:0,group:"",key:"",value:"",description:""}),N=w(()=>[...new Set(b.value.map(s=>s.app_name||s.name).filter(Boolean))].sort()),L=w(()=>b.value.filter(s=>(s.app_name||s.name)===m.value));function B(s){const t=C.value.find(U=>U.id===s.env_id),l=t?t.name||t.code:s.env_id?`环境#${s.env_id}`:"未关联环境",o=s.status==="pending"?"(待部署)":"";return s.region?`${l} · ${s.region}${o}`:`${l}${o}`}const O=w(()=>{const s=b.value.find(t=>t.id===u.value);return s?`${s.app_name||s.name} · ${B(s)}`:""}),M=w(()=>{const s=A.value.trim().toLowerCase();return s?f.value.filter(t=>((t.group||"")+(t.key||"")).toLowerCase().includes(s)):f.value}),R=w(()=>{const s={};return M.value.forEach(l=>{const o=l.group||"";(s[o]=s[o]||[]).push(l)}),Object.keys(s).sort((l,o)=>l===""?-1:o===""?1:l({key:l,label:l||"未分组",items:s[l]}))});async function T(){try{const[s,t]=await Promise.all([v("apps/list",{}),v("envs/list",{})]);b.value=s??[],C.value=t??[],!m.value&&N.value.length&&(m.value=N.value[0],E(),await x())}catch(s){c(s?.message??"获取应用列表失败"),b.value=[],C.value=[]}}function E(){const s=L.value,t=s.find(l=>l.status!=="pending")??s[0];u.value=t?.id??0}function z(){E(),x()}async function x(){if(!u.value){f.value=[];return}$.value=!0;try{const s=await v("appcfg/list",{app_id:u.value});f.value=s?.items??[]}catch(s){c(s?.message??"获取配置失败"),f.value=[]}finally{$.value=!1}}function H(){x()}function S(){_.value="list",x()}function F(s){s?(k.value=!0,n.id=s.id||0,n.group=s.group||"",n.key=s.key||"",n.value=s.value||"",n.description=s.description||""):(k.value=!1,n.id=0,n.group="",n.key="",n.value="",n.description=""),_.value="form"}async function P(){if(!u.value){c("请先选择应用和部署环境");return}V.value=!0;try{const s={app_id:u.value,group:n.group.trim(),key:n.key.trim(),value:n.value,description:n.description.trim()};k.value?(s.id=Number(n.id),await v("appcfg/update",s)):await v("appcfg/add",s),D("保存成功"),S()}catch(s){c(s?.message??"保存失败")}finally{V.value=!1}}function G(s){window.confirm("确定删除该配置项吗?")&&v("appcfg/del",{app_id:u.value,ids:[s.id]}).then(()=>{D("删除成功"),x()}).catch(t=>c(t?.message??"删除失败"))}return J(T),(s,t)=>(i(),a("div",null,[p(e("div",null,[e("div",Z,[t[10]||(t[10]=e("div",null,[e("h2",{class:"text-lg font-semibold text-slate-800"},"应用环境配置"),e("p",{class:"text-xs text-slate-400 mt-1"},"应用自有的 key/value 配置(音乐、OSS 等),直接读写所选应用的业务库。结构同「全局环境配置」但不分区域。")],-1)),e("button",{class:"btn btn-primary btn-sm text-white",disabled:!u.value,onClick:t[0]||(t[0]=l=>F())},"+ 新增配置",8,ee)]),e("div",te,[t[13]||(t[13]=e("span",{class:"text-sm text-slate-500"},"应用",-1)),p(e("select",{"onUpdate:modelValue":t[1]||(t[1]=l=>m.value=l),class:"select select-bordered select-sm min-w-40",onChange:z},[t[11]||(t[11]=e("option",{value:"",disabled:""},"请选择应用",-1)),(i(!0),a(g,null,h(N.value,l=>(i(),a("option",{key:l,value:l},d(l),9,se))),128))],544),[[q,m.value]]),t[14]||(t[14]=e("span",{class:"text-sm text-slate-500"},"部署环境",-1)),p(e("select",{"onUpdate:modelValue":t[2]||(t[2]=l=>u.value=l),class:"select select-bordered select-sm min-w-48",disabled:!m.value,onChange:H},[t[12]||(t[12]=e("option",{value:0,disabled:""},"请选择环境",-1)),(i(!0),a(g,null,h(L.value,l=>(i(),a("option",{key:l.id,value:l.id},d(B(l)),9,ne))),128))],40,le),[[q,u.value,void 0,{number:!0}]]),p(e("input",{"onUpdate:modelValue":t[3]||(t[3]=l=>A.value=l),class:"input input-bordered input-sm w-48",placeholder:"按分组/键搜索"},null,512),[[y,A.value]])]),u.value?(i(),a("div",ie,[e("div",ue,[e("table",de,[t[18]||(t[18]=e("thead",null,[e("tr",null,[e("th",null,"键"),e("th",null,"值"),e("th",null,"描述"),e("th",{class:"text-right"},"操作")])],-1)),e("tbody",null,[$.value?(i(),a("tr",re,[...t[16]||(t[16]=[e("td",{colspan:"4",class:"text-center py-8"},[e("span",{class:"loading loading-spinner loading-sm"})],-1)])])):M.value.length?K("",!0):(i(),a("tr",pe,[...t[17]||(t[17]=[e("td",{colspan:"4",class:"text-center text-slate-400 py-8"},"暂无配置",-1)])])),(i(!0),a(g,null,h(R.value,l=>(i(),a(g,{key:l.key},[e("tr",me,[e("td",ve,[e("span",ce,"▸ "+d(l.label),1),e("span",be,d(l.items.length)+" 项",1)])]),(i(!0),a(g,null,h(l.items,o=>(i(),a("tr",{key:o.id,class:"hover"},[e("td",fe,d(o.key||""),1),e("td",{class:"text-sm text-slate-500 max-w-xs truncate",title:o.value||""},d(o.value||""),9,xe),e("td",ge,d(o.description||""),1),e("td",ye,[e("div",we,[e("button",{class:"btn btn-ghost btn-xs",onClick:U=>F(o)},"编辑",8,_e),e("button",{class:"btn btn-ghost btn-xs text-red-500",onClick:U=>G(o)},"删除",8,ke)])])]))),128))],64))),128))])])])])):(i(),a("div",oe,[t[15]||(t[15]=e("div",{class:"text-4xl mb-2"},"🗂️",-1)),e("p",ae,d(m.value?"该应用还没有部署环境,请先在「应用中心」为它部署一个环境":"请先在上方选择应用和部署环境"),1)]))],512),[[j,_.value==="list"]]),p(e("div",null,[e("div",he,[e("button",{class:"btn btn-ghost btn-sm",onClick:t[4]||(t[4]=l=>S())},"← 返回列表"),e("h2",Ce,d(k.value?"编辑配置":"新增配置"),1),e("span",$e,"配置目标:"+d(O.value),1)]),e("div",Ve,[e("form",{onSubmit:Q(P,["prevent"])},[e("div",Ae,[t[19]||(t[19]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"分组 (group)")],-1)),p(e("input",{"onUpdate:modelValue":t[5]||(t[5]=l=>n.group=l),type:"text",class:"input input-bordered w-full",placeholder:"如 music / oss / other"},null,512),[[y,n.group]])]),e("div",Ne,[t[20]||(t[20]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"键 (key) *")],-1)),p(e("input",{"onUpdate:modelValue":t[6]||(t[6]=l=>n.key=l),type:"text",class:"input input-bordered w-full",required:"",placeholder:"如 oss_access_key"},null,512),[[y,n.key]])]),e("div",Se,[t[21]||(t[21]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"值 (value)")],-1)),p(e("textarea",{"onUpdate:modelValue":t[7]||(t[7]=l=>n.value=l),class:"textarea textarea-bordered w-full font-mono text-sm",rows:"3"},null,512),[[y,n.value]])]),e("div",Ue,[t[22]||(t[22]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"描述")],-1)),p(e("input",{"onUpdate:modelValue":t[8]||(t[8]=l=>n.description=l),type:"text",class:"input input-bordered w-full"},null,512),[[y,n.description]])]),e("div",De,[e("button",{type:"button",class:"btn btn-ghost",onClick:t[9]||(t[9]=l=>S())},"取消"),e("button",{type:"submit",class:"btn btn-primary text-white",disabled:V.value},"保存",8,Le)])],32)])],512),[[j,_.value==="form"]])]))}});export{qe as default}; diff --git a/apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/D-7b2ops.js b/apps/admin/.output/public/_nuxt/Bpb__dU6.js similarity index 98% rename from apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/D-7b2ops.js rename to apps/admin/.output/public/_nuxt/Bpb__dU6.js index 3579ef9b..91550823 100644 --- a/apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/D-7b2ops.js +++ b/apps/admin/.output/public/_nuxt/Bpb__dU6.js @@ -1 +1 @@ -import{g as Z,j as $,B as ee,c as l,a as e,p as v,q as P,l as D,F as y,r as h,v as w,O as te,m as se,t as i,d as j,x as u,z as _,y as ne,o}from"./Ccu6Xgpt.js";import{u as le}from"./Um-KoueI.js";import{u as oe}from"./DvwKXRUn.js";import"./CH2ZVAK2.js";const ae={class:"space-y-6"},ie={class:"bg-white rounded-xl shadow-sm border border-slate-100 p-4"},re={class:"flex items-end gap-3 flex-wrap"},de={class:"form-control"},ue={key:0,value:""},ce=["value"],pe={class:"form-control"},me={key:0,value:""},ve=["value"],be={class:"form-control"},fe=["onKeydown"],xe={key:0,class:"bg-white rounded-xl shadow-sm border border-slate-100 p-12 text-center text-slate-400"},ge={key:1,class:"space-y-5"},ye={class:"bg-white rounded-xl shadow-sm border border-slate-100 p-5 flex items-center gap-4"},he=["src"],we={key:1,class:"w-14 h-14 rounded-full bg-indigo-100 text-indigo-600 flex items-center justify-center text-xl font-bold"},_e={class:"text-lg font-semibold text-slate-800"},ke={class:"text-xs text-slate-400 font-mono mt-0.5"},Ie={class:"ml-auto flex items-center gap-3"},Ae={class:"badge badge-primary badge-outline"},Ue={class:"px-5 py-3 border-b border-slate-50 text-sm font-semibold text-slate-700"},Ve={class:"px-5 py-3 grid grid-cols-1 md:grid-cols-2 gap-x-8"},Ce={class:"text-xs text-slate-400 shrink-0"},De={class:"text-sm text-slate-700 break-all text-right"},Ne={class:"modal-box max-w-md"},Me={class:"text-xs text-slate-400 mb-4"},Se={class:"font-mono text-slate-600"},Ge={class:"grid grid-cols-3 gap-3"},Be={class:"form-control"},Pe={class:"form-control"},je={class:"form-control"},Le=Z({__name:"users",setup(qe){const{webApi:N,consoleApi:q}=le(),{success:T,error:M,warn:c}=oe(),b=$(),E={cn:"中国",us:"美国",hw:"海外",ea:"东亚",sea:"东南亚",sa:"南亚",me:"中东",eu:"欧洲",ru:"俄罗斯",af:"非洲",sam:"南美",nam:"北美",oc:"大洋洲",br:"巴西",in:"印度"};function F(s){return E[s]||s||"默认"}const f=u([]),p=u(""),m=u(""),k=u(""),r=u(null),S=u("请输入查询条件后点击「搜索」"),I=u(""),x=u(""),K=_(()=>[1,2,3].includes(b.identity)),g=u(null),a=ne({vipday:0,trademin:0,meetmin:0}),A=_(()=>{const s=[];return f.value.forEach(t=>{s.includes(t.name)||s.push(t.name)}),s}),U=_(()=>f.value.filter(s=>s.name===p.value));function G(){const s=U.value;m.value=s.length?s[0].id:""}function L(s){return s?new Date(s*1e3).toLocaleString():"-"}function O(s){return s?"是":"否"}function R(s){return s===1?"男":s===2?"女":"未知"}function V(s){return s==null||s===""?"-":s}const z=[{title:"基本信息",rows:[["uid","UID"],["name","用户名"],["account","登录账号"],["mail","邮箱"],["phone","手机号"],["gender","性别","gender"],["language","语言"],["version","版本"],["channel","渠道"],["State","状态"],["country_code","国家码"],["continent_code","大洲码"],["servicetag","服务区"],["phonemodel","手机型号"],["phonemac","设备ID"]]},{title:"第三方登录",rows:[["wxopenid","微信 openid"],["googleopenid","Google openid"],["facebookopenid","Facebook openid"],["appleopenid","Apple openid"]]},{title:"会员与积分",rows:[["viplv","VIP等级"],["vipexptime","VIP到期","ts"],["aichatintegral","AI积分"],["aichattotalintegral","AI累计积分"],["tradeintegral","翻译积分"],["tradetotalintegral","翻译累计积分"],["meetintegral","会议积分"],["meettotalintegral","会议累计积分"],["lastbindproductid","最后绑定产品ID"],["isactivatecode","已领激活码","bool"],["isgiveaway","首次绑定赠送","bool"]]},{title:"时间",rows:[["createtime","注册时间","ts"],["lastsgintime","最后登录","ts"],["canceltime","注销时间","ts"]]}];function H(s,t){const n=t[2],d=s[t[0]];return n==="ts"?L(d):n==="bool"?O(d):n==="gender"?R(d):V(d)}const J=_(()=>{const s=r.value;return s?String(s.name||s.uid||"?").charAt(0).toUpperCase():"?"});async function C(){if(!p.value){c("请选择应用");return}if(!m.value){c("请选择区域");return}const s=k.value.trim();if(!s){c("请输入用户UID");return}const t=Number(m.value);I.value=t,x.value=s,b.setCurrentApp(t);try{const n=await N("getuserinfo",{uid:s});r.value=n||{}}catch(n){M(n?.message||"查询失败"),r.value=null,S.value=n?.message||"未找到该用户"}}function Q(){if(!x.value){c("请先查询用户");return}a.vipday=0,a.trademin=0,a.meetmin=0,g.value?.showModal()}function W(){g.value?.close()}async function X(){const s=Number(a.vipday)||0,t=Number(a.trademin)||0,n=Number(a.meetmin)||0;if(s<0||t<0||n<0){c("数量不能为负");return}if(!s&&!t&&!n){c("请至少填写一项");return}if(!I.value||!x.value){c("请先查询用户");return}b.setCurrentApp(Number(I.value));try{await N("giftuserresource",{uid:x.value,vipday:s,trademin:t,meetmin:n}),T("赠送成功"),g.value?.close(),C()}catch(d){M(d?.message||"赠送失败")}}function B(){const s=A.value;if(!s.length){p.value="",m.value="";return}p.value=s[0],G()}async function Y(){if(b.identity===3){f.value=(b.appbinds||[]).map(s=>({id:s.id,name:s.name,region:s.region,enabled:!0})),B();return}try{const s=await q("apps/list",{});f.value=(s||[]).filter(t=>t.enabled)}catch{f.value=[]}B()}return ee(Y),(s,t)=>(o(),l("div",ae,[e("div",ie,[e("div",re,[e("div",de,[t[6]||(t[6]=e("label",{class:"label py-1"},[e("span",{class:"label-text text-xs"},"应用")],-1)),v(e("select",{"onUpdate:modelValue":t[0]||(t[0]=n=>p.value=n),class:"select select-bordered select-sm",style:{"min-width":"180px"},onChange:G},[A.value.length?D("",!0):(o(),l("option",ue,"无可用应用")),(o(!0),l(y,null,h(A.value,n=>(o(),l("option",{key:n,value:n},i(n),9,ce))),128))],544),[[P,p.value]])]),e("div",pe,[t[7]||(t[7]=e("label",{class:"label py-1"},[e("span",{class:"label-text text-xs"},"区域")],-1)),v(e("select",{"onUpdate:modelValue":t[1]||(t[1]=n=>m.value=n),class:"select select-bordered select-sm",style:{"min-width":"140px"}},[U.value.length?D("",!0):(o(),l("option",me,"无可用区域")),(o(!0),l(y,null,h(U.value,n=>(o(),l("option",{key:n.id,value:n.id},i(F(n.region)),9,ve))),128))],512),[[P,m.value]])]),e("div",be,[t[8]||(t[8]=e("label",{class:"label py-1"},[e("span",{class:"label-text text-xs"},"用户UID")],-1)),v(e("input",{"onUpdate:modelValue":t[2]||(t[2]=n=>k.value=n),type:"text",class:"input input-bordered input-sm",style:{"min-width":"240px"},placeholder:"输入用户 UID",onKeydown:te(se(C,["prevent"]),["enter"])},null,40,fe),[[w,k.value]])]),e("button",{class:"btn btn-primary btn-sm text-white",onClick:C},"搜索")]),t[9]||(t[9]=e("p",{class:"text-xs text-slate-400 mt-2"},"选择应用与区域后输入 UID,直接查询该部署业务库中的用户信息。",-1))]),r.value?(o(),l("div",ge,[e("div",ye,[r.value.avatar?(o(),l("img",{key:0,src:r.value.avatar,class:"w-14 h-14 rounded-full object-cover border border-slate-100"},null,8,he)):(o(),l("div",we,i(J.value),1)),e("div",null,[e("div",_e,i(V(r.value.name)),1),e("div",ke,i(V(r.value.uid)),1)]),e("div",Ie,[e("span",Ae,"VIP "+i(r.value.viplv||0),1),K.value?(o(),l("button",{key:0,class:"btn btn-success btn-sm text-white",onClick:Q},"赠送资源点")):D("",!0)])]),(o(),l(y,null,h(z,n=>e("div",{key:n.title,class:"bg-white rounded-xl shadow-sm border border-slate-100 overflow-hidden"},[e("div",Ue,i(n.title),1),e("div",Ve,[(o(!0),l(y,null,h(n.rows,d=>(o(),l("div",{key:d[0],class:"flex justify-between gap-3 py-1.5 border-b border-slate-50"},[e("span",Ce,i(d[1]),1),e("span",De,i(H(r.value,d)),1)]))),128))])])),64))])):(o(),l("div",xe,i(S.value),1)),e("dialog",{ref_key:"giftModal",ref:g,class:"modal"},[e("div",Ne,[t[15]||(t[15]=e("h3",{class:"font-bold text-lg mb-1 text-slate-800"},"赠送资源点",-1)),e("p",Me,[t[10]||(t[10]=j("目标用户 UID:",-1)),e("span",Se,i(x.value),1),t[11]||(t[11]=j("。代理账号将从自己的资源点余额中扣减,超管/管理员无消耗。",-1))]),e("div",Ge,[e("div",Be,[t[12]||(t[12]=e("label",{class:"label py-1"},[e("span",{class:"label-text text-sm"},"VIP天数")],-1)),v(e("input",{"onUpdate:modelValue":t[3]||(t[3]=n=>a.vipday=n),type:"number",class:"input input-bordered",min:"0"},null,512),[[w,a.vipday,void 0,{number:!0}]])]),e("div",Pe,[t[13]||(t[13]=e("label",{class:"label py-1"},[e("span",{class:"label-text text-sm"},"翻译分钟")],-1)),v(e("input",{"onUpdate:modelValue":t[4]||(t[4]=n=>a.trademin=n),type:"number",class:"input input-bordered",min:"0"},null,512),[[w,a.trademin,void 0,{number:!0}]])]),e("div",je,[t[14]||(t[14]=e("label",{class:"label py-1"},[e("span",{class:"label-text text-sm"},"会议分钟")],-1)),v(e("input",{"onUpdate:modelValue":t[5]||(t[5]=n=>a.meetmin=n),type:"number",class:"input input-bordered",min:"0"},null,512),[[w,a.meetmin,void 0,{number:!0}]])])]),e("div",{class:"modal-action"},[e("button",{class:"btn btn-sm",onClick:W},"取消"),e("button",{class:"btn btn-success btn-sm text-white",onClick:X},"确认赠送")])]),t[16]||(t[16]=e("form",{method:"dialog",class:"modal-backdrop"},[e("button",null,"close")],-1))],512)]))}});export{Le as default}; +import{g as Z,j as $,B as ee,c as l,a as e,p as v,q as P,l as D,F as y,r as h,v as w,O as te,m as se,t as i,d as j,x as u,z as _,y as ne,o}from"./mElhLwm2.js";import{u as le}from"./C6twYRfy.js";import{u as oe}from"./FVTAbpot.js";import"./qig5Qp6S.js";const ae={class:"space-y-6"},ie={class:"bg-white rounded-xl shadow-sm border border-slate-100 p-4"},re={class:"flex items-end gap-3 flex-wrap"},de={class:"form-control"},ue={key:0,value:""},ce=["value"],pe={class:"form-control"},me={key:0,value:""},ve=["value"],be={class:"form-control"},fe=["onKeydown"],xe={key:0,class:"bg-white rounded-xl shadow-sm border border-slate-100 p-12 text-center text-slate-400"},ge={key:1,class:"space-y-5"},ye={class:"bg-white rounded-xl shadow-sm border border-slate-100 p-5 flex items-center gap-4"},he=["src"],we={key:1,class:"w-14 h-14 rounded-full bg-indigo-100 text-indigo-600 flex items-center justify-center text-xl font-bold"},_e={class:"text-lg font-semibold text-slate-800"},ke={class:"text-xs text-slate-400 font-mono mt-0.5"},Ie={class:"ml-auto flex items-center gap-3"},Ae={class:"badge badge-primary badge-outline"},Ue={class:"px-5 py-3 border-b border-slate-50 text-sm font-semibold text-slate-700"},Ve={class:"px-5 py-3 grid grid-cols-1 md:grid-cols-2 gap-x-8"},Ce={class:"text-xs text-slate-400 shrink-0"},De={class:"text-sm text-slate-700 break-all text-right"},Ne={class:"modal-box max-w-md"},Me={class:"text-xs text-slate-400 mb-4"},Se={class:"font-mono text-slate-600"},Ge={class:"grid grid-cols-3 gap-3"},Be={class:"form-control"},Pe={class:"form-control"},je={class:"form-control"},Le=Z({__name:"users",setup(qe){const{webApi:N,consoleApi:q}=le(),{success:T,error:M,warn:c}=oe(),b=$(),E={cn:"中国",us:"美国",hw:"海外",ea:"东亚",sea:"东南亚",sa:"南亚",me:"中东",eu:"欧洲",ru:"俄罗斯",af:"非洲",sam:"南美",nam:"北美",oc:"大洋洲",br:"巴西",in:"印度"};function F(s){return E[s]||s||"默认"}const f=u([]),p=u(""),m=u(""),k=u(""),r=u(null),S=u("请输入查询条件后点击「搜索」"),I=u(""),x=u(""),K=_(()=>[1,2,3].includes(b.identity)),g=u(null),a=ne({vipday:0,trademin:0,meetmin:0}),A=_(()=>{const s=[];return f.value.forEach(t=>{s.includes(t.name)||s.push(t.name)}),s}),U=_(()=>f.value.filter(s=>s.name===p.value));function G(){const s=U.value;m.value=s.length?s[0].id:""}function L(s){return s?new Date(s*1e3).toLocaleString():"-"}function O(s){return s?"是":"否"}function R(s){return s===1?"男":s===2?"女":"未知"}function V(s){return s==null||s===""?"-":s}const z=[{title:"基本信息",rows:[["uid","UID"],["name","用户名"],["account","登录账号"],["mail","邮箱"],["phone","手机号"],["gender","性别","gender"],["language","语言"],["version","版本"],["channel","渠道"],["State","状态"],["country_code","国家码"],["continent_code","大洲码"],["servicetag","服务区"],["phonemodel","手机型号"],["phonemac","设备ID"]]},{title:"第三方登录",rows:[["wxopenid","微信 openid"],["googleopenid","Google openid"],["facebookopenid","Facebook openid"],["appleopenid","Apple openid"]]},{title:"会员与积分",rows:[["viplv","VIP等级"],["vipexptime","VIP到期","ts"],["aichatintegral","AI积分"],["aichattotalintegral","AI累计积分"],["tradeintegral","翻译积分"],["tradetotalintegral","翻译累计积分"],["meetintegral","会议积分"],["meettotalintegral","会议累计积分"],["lastbindproductid","最后绑定产品ID"],["isactivatecode","已领激活码","bool"],["isgiveaway","首次绑定赠送","bool"]]},{title:"时间",rows:[["createtime","注册时间","ts"],["lastsgintime","最后登录","ts"],["canceltime","注销时间","ts"]]}];function H(s,t){const n=t[2],d=s[t[0]];return n==="ts"?L(d):n==="bool"?O(d):n==="gender"?R(d):V(d)}const J=_(()=>{const s=r.value;return s?String(s.name||s.uid||"?").charAt(0).toUpperCase():"?"});async function C(){if(!p.value){c("请选择应用");return}if(!m.value){c("请选择区域");return}const s=k.value.trim();if(!s){c("请输入用户UID");return}const t=Number(m.value);I.value=t,x.value=s,b.setCurrentApp(t);try{const n=await N("getuserinfo",{uid:s});r.value=n||{}}catch(n){M(n?.message||"查询失败"),r.value=null,S.value=n?.message||"未找到该用户"}}function Q(){if(!x.value){c("请先查询用户");return}a.vipday=0,a.trademin=0,a.meetmin=0,g.value?.showModal()}function W(){g.value?.close()}async function X(){const s=Number(a.vipday)||0,t=Number(a.trademin)||0,n=Number(a.meetmin)||0;if(s<0||t<0||n<0){c("数量不能为负");return}if(!s&&!t&&!n){c("请至少填写一项");return}if(!I.value||!x.value){c("请先查询用户");return}b.setCurrentApp(Number(I.value));try{await N("giftuserresource",{uid:x.value,vipday:s,trademin:t,meetmin:n}),T("赠送成功"),g.value?.close(),C()}catch(d){M(d?.message||"赠送失败")}}function B(){const s=A.value;if(!s.length){p.value="",m.value="";return}p.value=s[0],G()}async function Y(){if(b.identity===3){f.value=(b.appbinds||[]).map(s=>({id:s.id,name:s.name,region:s.region,enabled:!0})),B();return}try{const s=await q("apps/list",{});f.value=(s||[]).filter(t=>t.enabled)}catch{f.value=[]}B()}return ee(Y),(s,t)=>(o(),l("div",ae,[e("div",ie,[e("div",re,[e("div",de,[t[6]||(t[6]=e("label",{class:"label py-1"},[e("span",{class:"label-text text-xs"},"应用")],-1)),v(e("select",{"onUpdate:modelValue":t[0]||(t[0]=n=>p.value=n),class:"select select-bordered select-sm",style:{"min-width":"180px"},onChange:G},[A.value.length?D("",!0):(o(),l("option",ue,"无可用应用")),(o(!0),l(y,null,h(A.value,n=>(o(),l("option",{key:n,value:n},i(n),9,ce))),128))],544),[[P,p.value]])]),e("div",pe,[t[7]||(t[7]=e("label",{class:"label py-1"},[e("span",{class:"label-text text-xs"},"区域")],-1)),v(e("select",{"onUpdate:modelValue":t[1]||(t[1]=n=>m.value=n),class:"select select-bordered select-sm",style:{"min-width":"140px"}},[U.value.length?D("",!0):(o(),l("option",me,"无可用区域")),(o(!0),l(y,null,h(U.value,n=>(o(),l("option",{key:n.id,value:n.id},i(F(n.region)),9,ve))),128))],512),[[P,m.value]])]),e("div",be,[t[8]||(t[8]=e("label",{class:"label py-1"},[e("span",{class:"label-text text-xs"},"用户UID")],-1)),v(e("input",{"onUpdate:modelValue":t[2]||(t[2]=n=>k.value=n),type:"text",class:"input input-bordered input-sm",style:{"min-width":"240px"},placeholder:"输入用户 UID",onKeydown:te(se(C,["prevent"]),["enter"])},null,40,fe),[[w,k.value]])]),e("button",{class:"btn btn-primary btn-sm text-white",onClick:C},"搜索")]),t[9]||(t[9]=e("p",{class:"text-xs text-slate-400 mt-2"},"选择应用与区域后输入 UID,直接查询该部署业务库中的用户信息。",-1))]),r.value?(o(),l("div",ge,[e("div",ye,[r.value.avatar?(o(),l("img",{key:0,src:r.value.avatar,class:"w-14 h-14 rounded-full object-cover border border-slate-100"},null,8,he)):(o(),l("div",we,i(J.value),1)),e("div",null,[e("div",_e,i(V(r.value.name)),1),e("div",ke,i(V(r.value.uid)),1)]),e("div",Ie,[e("span",Ae,"VIP "+i(r.value.viplv||0),1),K.value?(o(),l("button",{key:0,class:"btn btn-success btn-sm text-white",onClick:Q},"赠送资源点")):D("",!0)])]),(o(),l(y,null,h(z,n=>e("div",{key:n.title,class:"bg-white rounded-xl shadow-sm border border-slate-100 overflow-hidden"},[e("div",Ue,i(n.title),1),e("div",Ve,[(o(!0),l(y,null,h(n.rows,d=>(o(),l("div",{key:d[0],class:"flex justify-between gap-3 py-1.5 border-b border-slate-50"},[e("span",Ce,i(d[1]),1),e("span",De,i(H(r.value,d)),1)]))),128))])])),64))])):(o(),l("div",xe,i(S.value),1)),e("dialog",{ref_key:"giftModal",ref:g,class:"modal"},[e("div",Ne,[t[15]||(t[15]=e("h3",{class:"font-bold text-lg mb-1 text-slate-800"},"赠送资源点",-1)),e("p",Me,[t[10]||(t[10]=j("目标用户 UID:",-1)),e("span",Se,i(x.value),1),t[11]||(t[11]=j("。代理账号将从自己的资源点余额中扣减,超管/管理员无消耗。",-1))]),e("div",Ge,[e("div",Be,[t[12]||(t[12]=e("label",{class:"label py-1"},[e("span",{class:"label-text text-sm"},"VIP天数")],-1)),v(e("input",{"onUpdate:modelValue":t[3]||(t[3]=n=>a.vipday=n),type:"number",class:"input input-bordered",min:"0"},null,512),[[w,a.vipday,void 0,{number:!0}]])]),e("div",Pe,[t[13]||(t[13]=e("label",{class:"label py-1"},[e("span",{class:"label-text text-sm"},"翻译分钟")],-1)),v(e("input",{"onUpdate:modelValue":t[4]||(t[4]=n=>a.trademin=n),type:"number",class:"input input-bordered",min:"0"},null,512),[[w,a.trademin,void 0,{number:!0}]])]),e("div",je,[t[14]||(t[14]=e("label",{class:"label py-1"},[e("span",{class:"label-text text-sm"},"会议分钟")],-1)),v(e("input",{"onUpdate:modelValue":t[5]||(t[5]=n=>a.meetmin=n),type:"number",class:"input input-bordered",min:"0"},null,512),[[w,a.meetmin,void 0,{number:!0}]])])]),e("div",{class:"modal-action"},[e("button",{class:"btn btn-sm",onClick:W},"取消"),e("button",{class:"btn btn-success btn-sm text-white",onClick:X},"确认赠送")])]),t[16]||(t[16]=e("form",{method:"dialog",class:"modal-backdrop"},[e("button",null,"close")],-1))],512)]))}});export{Le as default}; diff --git a/apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/BOUWbQhH.js b/apps/admin/.output/public/_nuxt/BqjD6jMG.js similarity index 98% rename from apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/BOUWbQhH.js rename to apps/admin/.output/public/_nuxt/BqjD6jMG.js index 3e9a14e0..07da1f39 100644 --- a/apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/BOUWbQhH.js +++ b/apps/admin/.output/public/_nuxt/BqjD6jMG.js @@ -1 +1 @@ -import{g as $e,B as Se,c as i,a as t,p,q as M,F as g,r as x,H as P,t as a,d as S,I as re,n as C,v as Y,L as ce,l as m,s as Ue,b as pe,m as z,x as u,y as je,z as U,A as Ie,o,_ as Ne}from"./Ccu6Xgpt.js";import{u as Re}from"./Um-KoueI.js";import{u as Te}from"./DvwKXRUn.js";import{l as ve}from"./ChQPCk92.js";import{_ as D}from"./szhsDUYv.js";import"./CH2ZVAK2.js";const Be={class:"flex items-center justify-between mb-5 flex-wrap gap-3"},Ee={class:"flex items-center gap-3 flex-wrap"},Oe=["value"],Me=["value"],ze={class:"flex items-center justify-between mb-5"},De={class:"flex items-center gap-3"},Ge={class:"font-semibold text-slate-800 text-sm"},qe={class:"region-chip"},Fe={class:"ed-section"},Pe={class:"lang-row"},Ye={class:"lang-field"},He={class:"flex items-center justify-between"},We={class:"any-toggle"},Je=["checked"],Ke={key:0,class:"any-box"},Qe={class:"dir-col"},Xe=["title"],Ze={class:"dir-tip"},et={class:"lang-field"},tt={class:"flex items-center justify-between"},st={class:"any-toggle"},lt=["checked"],nt={key:0,class:"any-box"},at={class:"grid grid-cols-3 gap-3 mt-3"},ot=["value"],it={class:"ed-section"},ut={class:"grid grid-cols-2 gap-3"},dt={value:"",disabled:""},rt=["label"],ct=["value"],pt={key:0,class:"agent-preview"},vt={class:"text-xs text-slate-500"},bt={key:0,class:"text-[11px] text-slate-400"},gt={key:1,class:"text-[11px] text-amber-600"},mt={key:1,class:"ed-warn"},ft={class:"ed-footer"},yt={class:"flex items-center gap-2 text-sm cursor-pointer"},xt={key:0,class:"text-center py-20 text-slate-300"},_t={key:1,class:"rule-list"},kt=["onClick"],ht={class:"prio-cell"},At={class:"prio"},wt={class:"order"},Ct={class:"cond-cell"},Vt={class:"flex items-center gap-2 flex-wrap"},Lt={class:"text-slate-400 font-bold"},$t={key:0,class:"text-[11px] text-slate-400 mt-1"},St={key:0},Ut={class:"agent-cell"},jt={class:"text-xs text-slate-700"},It={class:"text-xs text-slate-500"},Nt={class:"text-right"},Rt={key:0,class:"badge badge-success badge-xs mr-2"},Tt={key:1,class:"badge badge-ghost badge-xs mr-2"},Bt=["onClick"],Et={class:"ct-box"},Ot={class:"grid grid-cols-2 gap-3"},Mt={class:"text-sm font-semibold text-slate-800 mb-1"},zt={class:"text-xs text-slate-600"},Dt={key:0},Gt={key:1,class:"text-sm text-amber-700"},qt={class:"flex gap-3 justify-end mt-5"},Ft={class:"ct-overlay"},Pt={class:"ct-box"},Yt={class:"text-xs text-slate-400 mb-3"},Ht={class:"flex items-center justify-between mb-1"},Wt={class:"flex gap-2"},Jt={class:"sync-region-grid"},Kt=["onClick"],Qt=["checked","onClick"],Xt={class:"flex gap-3 justify-end"},Zt=["disabled"],H="*",es=$e({__name:"calltranslate",setup(ts){const V=[{value:1,label:"中国"},{value:2,label:"美国"},{value:3,label:"东亚"},{value:4,label:"东南亚"},{value:5,label:"南亚"},{value:6,label:"中东"},{value:7,label:"欧洲"},{value:8,label:"俄罗斯"},{value:9,label:"非洲"},{value:10,label:"南美"},{value:11,label:"北美"},{value:12,label:"大洋洲"},{value:13,label:"巴西"},{value:14,label:"印度"}];function W(s){return V.find(e=>e.value===s)?.label??"区域"+s}const _={translate:{label:"🧩 三段式翻译",color:"#059669",bg:"#dcfce7"},"ast-translate":{label:"🚀 端到端翻译",color:"#c2410c",bg:"#fff7ed"}};function G(s){return s&&_[s]?_[s].label:s||"未知"}function J(s){const e=s?_[s]:void 0;return e?{background:e.bg,color:e.color}:{background:"#f1f5f9",color:"#64748b"}}const{webApi:k,consoleApi:be}=Re(),{success:q,error:v}=Te(),f=u(""),F=u([]),L=u(V[0].value),j=u([]),h=u([]),I=u(!1),A=u(null),K=u(null),Q=u(0),n=je({name:"",srcLangs:"",dstLangs:"",srcAny:!1,dstAny:!1,bidir:!0,region:0,priority:100,agentId:"",remark:"",enable:!0}),X=U(()=>h.value.filter(s=>s.type in _)),ge=U(()=>Object.keys(_).map(s=>({type:s,label:_[s].label,items:X.value.filter(e=>e.type===s)})).filter(s=>s.items.length)),b=U(()=>h.value.find(s=>s.id===n.agentId)||null),Z=U(()=>{const s=b.value;if(!s||!s.support_langs)return"";const e=s.support_langs.split(",").map(y=>y.trim()).filter(Boolean);if(!e.length)return"";const c=[...n.srcAny?[]:n.srcLangs.split(","),...n.dstAny?[]:n.dstLangs.split(",")].map(y=>y.trim()).filter(Boolean).filter(y=>!e.includes(y));return c.length?`Agent「${s.name||s.id}」未声明支持:${c.join("、")}`:""});function $(s){return(s||"").trim()===H}function w(s){if($(s))return"任意语言";const e=(s||"").split(",").map(l=>l.trim()).filter(Boolean);return e.length?e.length<=3?e.map(l=>ve(l)).join("、"):e.slice(0,3).map(l=>ve(l)).join("、")+` 等 ${e.length} 种`:"—"}function me(s){return h.value.find(e=>e.id===s)?.name||s||"未配置"}function ee(s){return h.value.find(e=>e.id===s)?.type||""}async function fe(){try{const s=await be("products/list",{});F.value=(s??[]).map(e=>e.name).filter(Boolean)}catch{F.value=[]}}async function ye(){try{const s=await k("getagents",{app_name:f.value});h.value=s?.items??[]}catch{h.value=[]}}async function N(){try{const s=await k("getcalltranslaterules",{app_name:f.value,region:L.value});j.value=s?.items??[]}catch(s){v(s?.message??"加载失败"),j.value=[]}}async function te(){await Promise.all([ye(),N()])}function se(){Ie(()=>K.value?.scrollIntoView({behavior:"smooth",block:"nearest"}))}function le(s){n.name=s?.name??"",n.srcAny=$(s?.src_langs),n.dstAny=$(s?.dst_langs),n.srcLangs=n.srcAny?"":s?.src_langs??"",n.dstLangs=n.dstAny?"":s?.dst_langs??"",n.bidir=s?!!s.bidir:!0,n.region=s?s.region:L.value,n.priority=s?.priority??100,n.agentId=s?.agent_id??"",n.remark=s?.remark??"",n.enable=s?s.enable!==!1:!0}function xe(){A.value=null,le(null),I.value=!0,se()}function _e(s){A.value=s,le(s),I.value=!0,se()}function R(){I.value=!1,A.value=null}function ne(s){s==="src"?(n.srcAny=!n.srcAny,n.srcAny&&(n.srcLangs="")):(n.dstAny=!n.dstAny,n.dstAny&&(n.dstLangs=""))}function ke(){return{id:A.value?A.value.id:0,app_name:f.value,region:n.region,name:n.name.trim(),src_langs:n.srcAny?H:n.srcLangs,dst_langs:n.dstAny?H:n.dstLangs,bidir:n.bidir,agent_id:n.agentId,priority:n.priority||0,enable:n.enable,remark:n.remark.trim()}}async function ae(){const s=ke();if(!s.src_langs)return v("源语言必选(或勾选「任意语言」)"),!1;if(!s.dst_langs)return v("目标语言必选(或勾选「任意语言」)"),!1;if(!s.agent_id)return v("请选择翻译 Agent"),!1;try{const e=await k("savecalltranslaterule",s);return Q.value=e?.id??0,await N(),!0}catch(e){return v(e?.message??"保存失败"),!1}}async function he(){await ae()&&(R(),q("保存成功"))}function Ae(s){window.confirm(`确定删除规则「${s.name||"#"+s.id}」吗?`)&&k("delcalltranslaterules",{ids:[s.id]}).then(()=>{q("已删除"),N()}).catch(e=>v(e?.message??"删除失败"))}const T=u(!1),oe=u(""),r=u([]),ie=U(()=>V.filter(s=>s.value!==n.region));function we(){if(!n.agentId){v("请先选择翻译 Agent");return}oe.value=`将「${n.srcAny?"任意语言":w(n.srcLangs)} ${n.bidir?"⇄":"→"} ${n.dstAny?"任意语言":w(n.dstLangs)}」这条规则复制到其他区域。`,r.value=[],T.value=!0}function ue(s){const e=r.value.indexOf(s);e>=0?r.value.splice(e,1):r.value.push(s)}function de(s){r.value=s?ie.value.map(e=>e.value):[]}async function Ce(){const s=[...r.value];if(T.value=!1,!!await ae()){R();try{const e=await k("synccalltranslaterules",{rule_ids:[Q.value],target_regions:s});q(`已保存并同步到:${s.map(W).join("、")}(${e?.synced??0} 条)`)}catch(e){v(e?.message??"同步失败")}}}const B=u(!1),E=u("zh-CN"),O=u("en-US"),d=u(null);function Ve(){d.value=null,B.value=!0}async function Le(){if(!E.value||!O.value){v("请选择源语言与目标语言");return}try{d.value=await k("testcalltranslaterule",{app_name:f.value,region:L.value,src_lang:E.value,dst_lang:O.value})}catch(s){v(s?.message??"试算失败")}}return Se(async()=>{await fe(),await te()}),(s,e)=>(o(),i("div",null,[t("div",Be,[e[23]||(e[23]=t("div",null,[t("h2",{class:"text-lg font-semibold text-slate-800"},"通话翻译规则"),t("p",{class:"text-xs text-slate-400 mt-1"}," 一条规则覆盖「多源语言 × 多目标语言」,命中后走它指定的 Agent。多条规则按优先级从高到低匹配,第一条命中的生效。 ")],-1)),t("div",Ee,[e[21]||(e[21]=t("span",{class:"text-sm text-slate-500"},"作用域",-1)),p(t("select",{"onUpdate:modelValue":e[0]||(e[0]=l=>f.value=l),class:"select select-bordered select-sm",onChange:te},[e[20]||(e[20]=t("option",{value:""},"全局默认",-1)),(o(!0),i(g,null,x(F.value,l=>(o(),i("option",{key:l,value:l},a(l),9,Oe))),128))],544),[[M,f.value]]),e[22]||(e[22]=t("span",{class:"text-sm text-slate-500"},"区域",-1)),p(t("select",{"onUpdate:modelValue":e[1]||(e[1]=l=>L.value=l),class:"select select-bordered select-sm",onChange:N},[(o(),i(g,null,x(V,l=>t("option",{key:l.value,value:l.value},a(l.label),9,Me)),64))],544),[[M,L.value,void 0,{number:!0}]]),t("button",{class:"btn btn-ghost btn-sm",onClick:Ve},"🔍 选路试算"),t("button",{class:"btn btn-primary btn-sm text-white",onClick:xe},"+ 新增规则")])]),p(t("div",{ref_key:"editorRef",ref:K,class:"editor-panel"},[t("div",ze,[t("div",De,[t("h3",Ge,a(A.value?"编辑规则":"新增规则"),1),t("span",qe,a(f.value||"全局默认"),1)]),t("button",{class:"btn btn-ghost btn-xs",onClick:R},"✕ 关闭")]),t("section",Fe,[e[32]||(e[32]=t("div",{class:"ed-section-title"},"匹配条件",-1)),t("div",Pe,[t("div",Ye,[t("div",He,[e[25]||(e[25]=t("span",{class:"ed-label"},"源语言",-1)),t("label",We,[t("input",{type:"checkbox",class:"checkbox checkbox-xs checkbox-primary",checked:n.srcAny,onChange:e[2]||(e[2]=l=>ne("src"))},null,40,Je),e[24]||(e[24]=S(" 任意语言 ",-1))])]),n.srcAny?(o(),i("div",Ke,"任意源语言")):(o(),re(D,{key:1,modelValue:n.srcLangs,"onUpdate:modelValue":e[3]||(e[3]=l=>n.srcLangs=l),multiple:""},null,8,["modelValue"]))]),t("div",Qe,[t("button",{type:"button",class:C(["dir-btn",{on:n.bidir}]),title:n.bidir?"点击改为单向":"点击改为双向(反向也走这条规则)",onClick:e[4]||(e[4]=l=>n.bidir=!n.bidir)},a(n.bidir?"⇄":"→"),11,Xe),t("span",Ze,a(n.bidir?"双向互译":"单向翻译"),1)]),t("div",et,[t("div",tt,[e[27]||(e[27]=t("span",{class:"ed-label"},"目标语言",-1)),t("label",st,[t("input",{type:"checkbox",class:"checkbox checkbox-xs checkbox-primary",checked:n.dstAny,onChange:e[5]||(e[5]=l=>ne("dst"))},null,40,lt),e[26]||(e[26]=S(" 任意语言 ",-1))])]),n.dstAny?(o(),i("div",nt,"任意目标语言")):(o(),re(D,{key:1,modelValue:n.dstLangs,"onUpdate:modelValue":e[6]||(e[6]=l=>n.dstLangs=l),multiple:""},null,8,["modelValue"]))])]),t("div",at,[t("div",null,[e[29]||(e[29]=t("span",{class:"ed-label"},"生效区域",-1)),p(t("select",{"onUpdate:modelValue":e[7]||(e[7]=l=>n.region=l),class:"select select-bordered select-sm w-full"},[e[28]||(e[28]=t("option",{value:0},"全部区域(兜底)",-1)),(o(),i(g,null,x(V,l=>t("option",{key:l.value,value:l.value},a(l.label),9,ot)),64))],512),[[M,n.region,void 0,{number:!0}]])]),t("div",null,[e[30]||(e[30]=t("span",{class:"ed-label"},"优先级(越大越先匹配)",-1)),p(t("input",{"onUpdate:modelValue":e[8]||(e[8]=l=>n.priority=l),type:"number",class:"input input-bordered input-sm w-full"},null,512),[[Y,n.priority,void 0,{number:!0}]])]),t("div",null,[e[31]||(e[31]=t("span",{class:"ed-label"},"规则名(便于识别)",-1)),p(t("input",{"onUpdate:modelValue":e[9]||(e[9]=l=>n.name=l),class:"input input-bordered input-sm w-full",placeholder:"如 中日韩端到端"},null,512),[[Y,n.name]])])])]),t("section",it,[e[35]||(e[35]=t("div",{class:"ed-section-title"},"命中后使用的 Agent",-1)),t("div",ut,[t("div",null,[e[33]||(e[33]=t("span",{class:"ed-label"},[S("翻译 Agent "),t("i",{class:"req"},"*")],-1)),p(t("select",{"onUpdate:modelValue":e[10]||(e[10]=l=>n.agentId=l),class:"select select-bordered select-sm w-full"},[t("option",dt,a(X.value.length?"请选择 Agent":"(无可用 Agent,请先去 Agent 配置里创建)"),1),(o(!0),i(g,null,x(ge.value,l=>(o(),i("optgroup",{key:l.type,label:l.label},[(o(!0),i(g,null,x(l.items,c=>(o(),i("option",{key:c.id,value:c.id},a(c.name||c.id),9,ct))),128))],8,rt))),128))],512),[[M,n.agentId]])]),t("div",null,[e[34]||(e[34]=t("span",{class:"ed-label"},"备注",-1)),p(t("input",{"onUpdate:modelValue":e[11]||(e[11]=l=>n.remark=l),class:"input input-bordered input-sm w-full",placeholder:"可留空"},null,512),[[Y,n.remark]])])]),b.value?(o(),i("div",pt,[t("span",{class:"type-badge",style:ce(J(b.value.type))},a(G(b.value.type)),5),t("span",vt,a(b.value.description||"(无描述)"),1),b.value.support_langs?(o(),i("span",bt,"支持:"+a(b.value.support_langs),1)):m("",!0),b.value.enable?m("",!0):(o(),i("span",gt,"⚠ 该 Agent 当前为停用状态"))])):m("",!0),Z.value?(o(),i("p",mt,"⚠ "+a(Z.value),1)):m("",!0)]),t("div",ft,[t("label",yt,[p(t("input",{"onUpdate:modelValue":e[12]||(e[12]=l=>n.enable=l),type:"checkbox",class:"checkbox checkbox-sm checkbox-primary"},null,512),[[Ue,n.enable]]),e[36]||(e[36]=t("span",null,"启用",-1)),e[37]||(e[37]=t("span",{class:"text-xs text-slate-400"},"停用的规则不参与选路",-1))]),t("div",{class:"flex gap-2"},[t("button",{class:"btn btn-ghost btn-sm",onClick:R},"取消"),t("button",{class:"btn btn-outline btn-sm",onClick:we},"保存并同步…"),t("button",{class:"btn btn-primary btn-sm text-white",onClick:he},"保存")])])],512),[[P,I.value]]),j.value.length?(o(),i("div",_t,[e[39]||(e[39]=t("div",{class:"rule-head"},[t("span",null,"优先级"),t("span",null,"匹配条件"),t("span",null,"Agent"),t("span",null,"区域"),t("span",{class:"text-right"},"操作")],-1)),(o(!0),i(g,null,x(j.value,(l,c)=>(o(),i("div",{key:l.id,class:C(["rule-row",{off:!l.enable}]),onClick:y=>_e(l)},[t("div",ht,[t("span",At,a(l.priority),1),t("span",wt,"#"+a(c+1),1)]),t("div",Ct,[t("div",Vt,[t("span",{class:C(["lang-badge",{any:$(l.src_langs)}])},a(w(l.src_langs)),3),t("span",Lt,a(l.bidir?"⇄":"→"),1),t("span",{class:C(["lang-badge",{any:$(l.dst_langs)}])},a(w(l.dst_langs)),3)]),l.name||l.remark?(o(),i("div",$t,[S(a(l.name),1),l.remark?(o(),i("span",St," · "+a(l.remark),1)):m("",!0)])):m("",!0)]),t("div",Ut,[t("span",{class:"type-badge",style:ce(J(ee(l.agent_id)))},a(G(ee(l.agent_id))),5),t("span",jt,a(me(l.agent_id)),1)]),t("div",It,a(l.region===0?"全部区域":W(l.region)),1),t("div",Nt,[l.enable?(o(),i("span",Rt,"启用")):(o(),i("span",Tt,"停用")),t("button",{class:"btn btn-ghost btn-xs text-error",onClick:z(y=>Ae(l),["stop"])},"删除",8,Bt)])],10,kt))),128))])):(o(),i("div",xt,[...e[38]||(e[38]=[t("div",{class:"text-5xl mb-3"},"🌐",-1),t("p",{class:"text-sm"},"当前区域还没有翻译规则",-1),t("p",{class:"text-xs mt-1"},"建议先加一条「任意 → 任意」的兜底规则,再往上叠精确规则",-1)])])),p(t("div",{class:"ct-overlay",onClick:e[16]||(e[16]=z(l=>B.value=!1,["self"]))},[t("div",Et,[e[42]||(e[42]=t("h3",{class:"text-base font-semibold text-slate-800 mb-1"},"选路试算",-1)),e[43]||(e[43]=t("p",{class:"text-xs text-slate-400 mb-4"},"用后端运行时同一套匹配逻辑,算一遍这个方向实际会走哪条规则。",-1)),t("div",Ot,[t("div",null,[e[40]||(e[40]=t("span",{class:"ed-label"},"源语言",-1)),pe(D,{modelValue:E.value,"onUpdate:modelValue":e[13]||(e[13]=l=>E.value=l)},null,8,["modelValue"])]),t("div",null,[e[41]||(e[41]=t("span",{class:"ed-label"},"目标语言",-1)),pe(D,{modelValue:O.value,"onUpdate:modelValue":e[14]||(e[14]=l=>O.value=l)},null,8,["modelValue"])])]),d.value?(o(),i("div",{key:0,class:C(["test-result",{miss:!d.value.matched}])},[d.value.matched?(o(),i(g,{key:0},[t("div",Mt," 命中规则:"+a(d.value.rule?.name||"#"+d.value.rule?.id)+"(优先级 "+a(d.value.rule?.priority)+") ",1),t("div",zt,[S(a(w(d.value.rule?.src_langs))+" "+a(d.value.rule?.bidir?"⇄":"→")+" "+a(w(d.value.rule?.dst_langs))+" · Agent:"+a(d.value.agent?.name||d.value.rule?.agent_id)+" ",1),d.value.agent?(o(),i("span",Dt,"("+a(G(d.value.agent.type))+")",1)):m("",!0)])],64)):(o(),i("div",Gt,"没有任何规则命中 —— 这个方向的通话翻译会不可用,建议补一条兜底规则。"))],2)):m("",!0),t("div",qt,[t("button",{class:"btn btn-ghost",onClick:e[15]||(e[15]=l=>B.value=!1)},"关闭"),t("button",{class:"btn btn-primary text-white",onClick:Le},"试算")])])],512),[[P,B.value]]),p(t("div",Ft,[t("div",Pt,[e[45]||(e[45]=t("h3",{class:"text-base font-semibold text-slate-800 mb-1"},"同步到其他区域",-1)),t("p",Yt,a(oe.value),1),e[46]||(e[46]=t("div",{class:"text-xs px-3 py-2 rounded-lg mb-3",style:{background:"#f0fdf4",border:"1px solid #bbf7d0",color:"#15803d"}}," ✦ 同步内容:语言条件、Agent、优先级、启停状态一并复制到目标区域。 ",-1)),t("div",Ht,[e[44]||(e[44]=t("span",{class:"text-xs font-semibold text-slate-500"},"选择目标区域",-1)),t("div",Wt,[t("button",{class:"btn btn-ghost btn-xs",onClick:e[17]||(e[17]=l=>de(!0))},"全选"),t("button",{class:"btn btn-ghost btn-xs",onClick:e[18]||(e[18]=l=>de(!1))},"清空")])]),t("div",Jt,[(o(!0),i(g,null,x(ie.value,l=>(o(),i("label",{key:l.value,class:C(["sync-region-item",{checked:r.value.includes(l.value)}]),onClick:z(c=>ue(l.value),["prevent"])},[t("input",{type:"checkbox",class:"checkbox checkbox-xs checkbox-primary",checked:r.value.includes(l.value),onClick:z(c=>ue(l.value),["stop"])},null,8,Qt),t("span",null,a(l.label),1)],10,Kt))),128))]),e[47]||(e[47]=t("p",{class:"text-[11px] text-slate-400 mb-5"},"⚠ 目标区域已有「同 Agent + 同语言条件」的规则则覆盖,否则新建。",-1)),t("div",Xt,[t("button",{class:"btn btn-ghost",onClick:e[19]||(e[19]=l=>T.value=!1)},"取消"),t("button",{class:"btn btn-primary text-white",disabled:!r.value.length,onClick:Ce}," 保存并同步"+a(r.value.length?"("+r.value.length+" 个区域)":""),9,Zt)])])],512),[[P,T.value]])]))}}),us=Ne(es,[["__scopeId","data-v-c0bab860"]]);export{us as default}; +import{g as $e,B as Se,c as i,a as t,p,q as M,F as g,r as x,H as P,t as a,d as S,I as re,n as C,v as Y,L as ce,l as m,s as Ue,b as pe,m as z,x as u,y as je,z as U,A as Ie,o,_ as Ne}from"./mElhLwm2.js";import{u as Re}from"./C6twYRfy.js";import{u as Te}from"./FVTAbpot.js";import{l as ve}from"./ChQPCk92.js";import{_ as D}from"./CglQi8MB.js";import"./qig5Qp6S.js";const Be={class:"flex items-center justify-between mb-5 flex-wrap gap-3"},Ee={class:"flex items-center gap-3 flex-wrap"},Oe=["value"],Me=["value"],ze={class:"flex items-center justify-between mb-5"},De={class:"flex items-center gap-3"},Ge={class:"font-semibold text-slate-800 text-sm"},qe={class:"region-chip"},Fe={class:"ed-section"},Pe={class:"lang-row"},Ye={class:"lang-field"},He={class:"flex items-center justify-between"},We={class:"any-toggle"},Je=["checked"],Ke={key:0,class:"any-box"},Qe={class:"dir-col"},Xe=["title"],Ze={class:"dir-tip"},et={class:"lang-field"},tt={class:"flex items-center justify-between"},st={class:"any-toggle"},lt=["checked"],nt={key:0,class:"any-box"},at={class:"grid grid-cols-3 gap-3 mt-3"},ot=["value"],it={class:"ed-section"},ut={class:"grid grid-cols-2 gap-3"},dt={value:"",disabled:""},rt=["label"],ct=["value"],pt={key:0,class:"agent-preview"},vt={class:"text-xs text-slate-500"},bt={key:0,class:"text-[11px] text-slate-400"},gt={key:1,class:"text-[11px] text-amber-600"},mt={key:1,class:"ed-warn"},ft={class:"ed-footer"},yt={class:"flex items-center gap-2 text-sm cursor-pointer"},xt={key:0,class:"text-center py-20 text-slate-300"},_t={key:1,class:"rule-list"},kt=["onClick"],ht={class:"prio-cell"},At={class:"prio"},wt={class:"order"},Ct={class:"cond-cell"},Vt={class:"flex items-center gap-2 flex-wrap"},Lt={class:"text-slate-400 font-bold"},$t={key:0,class:"text-[11px] text-slate-400 mt-1"},St={key:0},Ut={class:"agent-cell"},jt={class:"text-xs text-slate-700"},It={class:"text-xs text-slate-500"},Nt={class:"text-right"},Rt={key:0,class:"badge badge-success badge-xs mr-2"},Tt={key:1,class:"badge badge-ghost badge-xs mr-2"},Bt=["onClick"],Et={class:"ct-box"},Ot={class:"grid grid-cols-2 gap-3"},Mt={class:"text-sm font-semibold text-slate-800 mb-1"},zt={class:"text-xs text-slate-600"},Dt={key:0},Gt={key:1,class:"text-sm text-amber-700"},qt={class:"flex gap-3 justify-end mt-5"},Ft={class:"ct-overlay"},Pt={class:"ct-box"},Yt={class:"text-xs text-slate-400 mb-3"},Ht={class:"flex items-center justify-between mb-1"},Wt={class:"flex gap-2"},Jt={class:"sync-region-grid"},Kt=["onClick"],Qt=["checked","onClick"],Xt={class:"flex gap-3 justify-end"},Zt=["disabled"],H="*",es=$e({__name:"calltranslate",setup(ts){const V=[{value:1,label:"中国"},{value:2,label:"美国"},{value:3,label:"东亚"},{value:4,label:"东南亚"},{value:5,label:"南亚"},{value:6,label:"中东"},{value:7,label:"欧洲"},{value:8,label:"俄罗斯"},{value:9,label:"非洲"},{value:10,label:"南美"},{value:11,label:"北美"},{value:12,label:"大洋洲"},{value:13,label:"巴西"},{value:14,label:"印度"}];function W(s){return V.find(e=>e.value===s)?.label??"区域"+s}const _={translate:{label:"🧩 三段式翻译",color:"#059669",bg:"#dcfce7"},"ast-translate":{label:"🚀 端到端翻译",color:"#c2410c",bg:"#fff7ed"}};function G(s){return s&&_[s]?_[s].label:s||"未知"}function J(s){const e=s?_[s]:void 0;return e?{background:e.bg,color:e.color}:{background:"#f1f5f9",color:"#64748b"}}const{webApi:k,consoleApi:be}=Re(),{success:q,error:v}=Te(),f=u(""),F=u([]),L=u(V[0].value),j=u([]),h=u([]),I=u(!1),A=u(null),K=u(null),Q=u(0),n=je({name:"",srcLangs:"",dstLangs:"",srcAny:!1,dstAny:!1,bidir:!0,region:0,priority:100,agentId:"",remark:"",enable:!0}),X=U(()=>h.value.filter(s=>s.type in _)),ge=U(()=>Object.keys(_).map(s=>({type:s,label:_[s].label,items:X.value.filter(e=>e.type===s)})).filter(s=>s.items.length)),b=U(()=>h.value.find(s=>s.id===n.agentId)||null),Z=U(()=>{const s=b.value;if(!s||!s.support_langs)return"";const e=s.support_langs.split(",").map(y=>y.trim()).filter(Boolean);if(!e.length)return"";const c=[...n.srcAny?[]:n.srcLangs.split(","),...n.dstAny?[]:n.dstLangs.split(",")].map(y=>y.trim()).filter(Boolean).filter(y=>!e.includes(y));return c.length?`Agent「${s.name||s.id}」未声明支持:${c.join("、")}`:""});function $(s){return(s||"").trim()===H}function w(s){if($(s))return"任意语言";const e=(s||"").split(",").map(l=>l.trim()).filter(Boolean);return e.length?e.length<=3?e.map(l=>ve(l)).join("、"):e.slice(0,3).map(l=>ve(l)).join("、")+` 等 ${e.length} 种`:"—"}function me(s){return h.value.find(e=>e.id===s)?.name||s||"未配置"}function ee(s){return h.value.find(e=>e.id===s)?.type||""}async function fe(){try{const s=await be("products/list",{});F.value=(s??[]).map(e=>e.name).filter(Boolean)}catch{F.value=[]}}async function ye(){try{const s=await k("getagents",{app_name:f.value});h.value=s?.items??[]}catch{h.value=[]}}async function N(){try{const s=await k("getcalltranslaterules",{app_name:f.value,region:L.value});j.value=s?.items??[]}catch(s){v(s?.message??"加载失败"),j.value=[]}}async function te(){await Promise.all([ye(),N()])}function se(){Ie(()=>K.value?.scrollIntoView({behavior:"smooth",block:"nearest"}))}function le(s){n.name=s?.name??"",n.srcAny=$(s?.src_langs),n.dstAny=$(s?.dst_langs),n.srcLangs=n.srcAny?"":s?.src_langs??"",n.dstLangs=n.dstAny?"":s?.dst_langs??"",n.bidir=s?!!s.bidir:!0,n.region=s?s.region:L.value,n.priority=s?.priority??100,n.agentId=s?.agent_id??"",n.remark=s?.remark??"",n.enable=s?s.enable!==!1:!0}function xe(){A.value=null,le(null),I.value=!0,se()}function _e(s){A.value=s,le(s),I.value=!0,se()}function R(){I.value=!1,A.value=null}function ne(s){s==="src"?(n.srcAny=!n.srcAny,n.srcAny&&(n.srcLangs="")):(n.dstAny=!n.dstAny,n.dstAny&&(n.dstLangs=""))}function ke(){return{id:A.value?A.value.id:0,app_name:f.value,region:n.region,name:n.name.trim(),src_langs:n.srcAny?H:n.srcLangs,dst_langs:n.dstAny?H:n.dstLangs,bidir:n.bidir,agent_id:n.agentId,priority:n.priority||0,enable:n.enable,remark:n.remark.trim()}}async function ae(){const s=ke();if(!s.src_langs)return v("源语言必选(或勾选「任意语言」)"),!1;if(!s.dst_langs)return v("目标语言必选(或勾选「任意语言」)"),!1;if(!s.agent_id)return v("请选择翻译 Agent"),!1;try{const e=await k("savecalltranslaterule",s);return Q.value=e?.id??0,await N(),!0}catch(e){return v(e?.message??"保存失败"),!1}}async function he(){await ae()&&(R(),q("保存成功"))}function Ae(s){window.confirm(`确定删除规则「${s.name||"#"+s.id}」吗?`)&&k("delcalltranslaterules",{ids:[s.id]}).then(()=>{q("已删除"),N()}).catch(e=>v(e?.message??"删除失败"))}const T=u(!1),oe=u(""),r=u([]),ie=U(()=>V.filter(s=>s.value!==n.region));function we(){if(!n.agentId){v("请先选择翻译 Agent");return}oe.value=`将「${n.srcAny?"任意语言":w(n.srcLangs)} ${n.bidir?"⇄":"→"} ${n.dstAny?"任意语言":w(n.dstLangs)}」这条规则复制到其他区域。`,r.value=[],T.value=!0}function ue(s){const e=r.value.indexOf(s);e>=0?r.value.splice(e,1):r.value.push(s)}function de(s){r.value=s?ie.value.map(e=>e.value):[]}async function Ce(){const s=[...r.value];if(T.value=!1,!!await ae()){R();try{const e=await k("synccalltranslaterules",{rule_ids:[Q.value],target_regions:s});q(`已保存并同步到:${s.map(W).join("、")}(${e?.synced??0} 条)`)}catch(e){v(e?.message??"同步失败")}}}const B=u(!1),E=u("zh-CN"),O=u("en-US"),d=u(null);function Ve(){d.value=null,B.value=!0}async function Le(){if(!E.value||!O.value){v("请选择源语言与目标语言");return}try{d.value=await k("testcalltranslaterule",{app_name:f.value,region:L.value,src_lang:E.value,dst_lang:O.value})}catch(s){v(s?.message??"试算失败")}}return Se(async()=>{await fe(),await te()}),(s,e)=>(o(),i("div",null,[t("div",Be,[e[23]||(e[23]=t("div",null,[t("h2",{class:"text-lg font-semibold text-slate-800"},"通话翻译规则"),t("p",{class:"text-xs text-slate-400 mt-1"}," 一条规则覆盖「多源语言 × 多目标语言」,命中后走它指定的 Agent。多条规则按优先级从高到低匹配,第一条命中的生效。 ")],-1)),t("div",Ee,[e[21]||(e[21]=t("span",{class:"text-sm text-slate-500"},"作用域",-1)),p(t("select",{"onUpdate:modelValue":e[0]||(e[0]=l=>f.value=l),class:"select select-bordered select-sm",onChange:te},[e[20]||(e[20]=t("option",{value:""},"全局默认",-1)),(o(!0),i(g,null,x(F.value,l=>(o(),i("option",{key:l,value:l},a(l),9,Oe))),128))],544),[[M,f.value]]),e[22]||(e[22]=t("span",{class:"text-sm text-slate-500"},"区域",-1)),p(t("select",{"onUpdate:modelValue":e[1]||(e[1]=l=>L.value=l),class:"select select-bordered select-sm",onChange:N},[(o(),i(g,null,x(V,l=>t("option",{key:l.value,value:l.value},a(l.label),9,Me)),64))],544),[[M,L.value,void 0,{number:!0}]]),t("button",{class:"btn btn-ghost btn-sm",onClick:Ve},"🔍 选路试算"),t("button",{class:"btn btn-primary btn-sm text-white",onClick:xe},"+ 新增规则")])]),p(t("div",{ref_key:"editorRef",ref:K,class:"editor-panel"},[t("div",ze,[t("div",De,[t("h3",Ge,a(A.value?"编辑规则":"新增规则"),1),t("span",qe,a(f.value||"全局默认"),1)]),t("button",{class:"btn btn-ghost btn-xs",onClick:R},"✕ 关闭")]),t("section",Fe,[e[32]||(e[32]=t("div",{class:"ed-section-title"},"匹配条件",-1)),t("div",Pe,[t("div",Ye,[t("div",He,[e[25]||(e[25]=t("span",{class:"ed-label"},"源语言",-1)),t("label",We,[t("input",{type:"checkbox",class:"checkbox checkbox-xs checkbox-primary",checked:n.srcAny,onChange:e[2]||(e[2]=l=>ne("src"))},null,40,Je),e[24]||(e[24]=S(" 任意语言 ",-1))])]),n.srcAny?(o(),i("div",Ke,"任意源语言")):(o(),re(D,{key:1,modelValue:n.srcLangs,"onUpdate:modelValue":e[3]||(e[3]=l=>n.srcLangs=l),multiple:""},null,8,["modelValue"]))]),t("div",Qe,[t("button",{type:"button",class:C(["dir-btn",{on:n.bidir}]),title:n.bidir?"点击改为单向":"点击改为双向(反向也走这条规则)",onClick:e[4]||(e[4]=l=>n.bidir=!n.bidir)},a(n.bidir?"⇄":"→"),11,Xe),t("span",Ze,a(n.bidir?"双向互译":"单向翻译"),1)]),t("div",et,[t("div",tt,[e[27]||(e[27]=t("span",{class:"ed-label"},"目标语言",-1)),t("label",st,[t("input",{type:"checkbox",class:"checkbox checkbox-xs checkbox-primary",checked:n.dstAny,onChange:e[5]||(e[5]=l=>ne("dst"))},null,40,lt),e[26]||(e[26]=S(" 任意语言 ",-1))])]),n.dstAny?(o(),i("div",nt,"任意目标语言")):(o(),re(D,{key:1,modelValue:n.dstLangs,"onUpdate:modelValue":e[6]||(e[6]=l=>n.dstLangs=l),multiple:""},null,8,["modelValue"]))])]),t("div",at,[t("div",null,[e[29]||(e[29]=t("span",{class:"ed-label"},"生效区域",-1)),p(t("select",{"onUpdate:modelValue":e[7]||(e[7]=l=>n.region=l),class:"select select-bordered select-sm w-full"},[e[28]||(e[28]=t("option",{value:0},"全部区域(兜底)",-1)),(o(),i(g,null,x(V,l=>t("option",{key:l.value,value:l.value},a(l.label),9,ot)),64))],512),[[M,n.region,void 0,{number:!0}]])]),t("div",null,[e[30]||(e[30]=t("span",{class:"ed-label"},"优先级(越大越先匹配)",-1)),p(t("input",{"onUpdate:modelValue":e[8]||(e[8]=l=>n.priority=l),type:"number",class:"input input-bordered input-sm w-full"},null,512),[[Y,n.priority,void 0,{number:!0}]])]),t("div",null,[e[31]||(e[31]=t("span",{class:"ed-label"},"规则名(便于识别)",-1)),p(t("input",{"onUpdate:modelValue":e[9]||(e[9]=l=>n.name=l),class:"input input-bordered input-sm w-full",placeholder:"如 中日韩端到端"},null,512),[[Y,n.name]])])])]),t("section",it,[e[35]||(e[35]=t("div",{class:"ed-section-title"},"命中后使用的 Agent",-1)),t("div",ut,[t("div",null,[e[33]||(e[33]=t("span",{class:"ed-label"},[S("翻译 Agent "),t("i",{class:"req"},"*")],-1)),p(t("select",{"onUpdate:modelValue":e[10]||(e[10]=l=>n.agentId=l),class:"select select-bordered select-sm w-full"},[t("option",dt,a(X.value.length?"请选择 Agent":"(无可用 Agent,请先去 Agent 配置里创建)"),1),(o(!0),i(g,null,x(ge.value,l=>(o(),i("optgroup",{key:l.type,label:l.label},[(o(!0),i(g,null,x(l.items,c=>(o(),i("option",{key:c.id,value:c.id},a(c.name||c.id),9,ct))),128))],8,rt))),128))],512),[[M,n.agentId]])]),t("div",null,[e[34]||(e[34]=t("span",{class:"ed-label"},"备注",-1)),p(t("input",{"onUpdate:modelValue":e[11]||(e[11]=l=>n.remark=l),class:"input input-bordered input-sm w-full",placeholder:"可留空"},null,512),[[Y,n.remark]])])]),b.value?(o(),i("div",pt,[t("span",{class:"type-badge",style:ce(J(b.value.type))},a(G(b.value.type)),5),t("span",vt,a(b.value.description||"(无描述)"),1),b.value.support_langs?(o(),i("span",bt,"支持:"+a(b.value.support_langs),1)):m("",!0),b.value.enable?m("",!0):(o(),i("span",gt,"⚠ 该 Agent 当前为停用状态"))])):m("",!0),Z.value?(o(),i("p",mt,"⚠ "+a(Z.value),1)):m("",!0)]),t("div",ft,[t("label",yt,[p(t("input",{"onUpdate:modelValue":e[12]||(e[12]=l=>n.enable=l),type:"checkbox",class:"checkbox checkbox-sm checkbox-primary"},null,512),[[Ue,n.enable]]),e[36]||(e[36]=t("span",null,"启用",-1)),e[37]||(e[37]=t("span",{class:"text-xs text-slate-400"},"停用的规则不参与选路",-1))]),t("div",{class:"flex gap-2"},[t("button",{class:"btn btn-ghost btn-sm",onClick:R},"取消"),t("button",{class:"btn btn-outline btn-sm",onClick:we},"保存并同步…"),t("button",{class:"btn btn-primary btn-sm text-white",onClick:he},"保存")])])],512),[[P,I.value]]),j.value.length?(o(),i("div",_t,[e[39]||(e[39]=t("div",{class:"rule-head"},[t("span",null,"优先级"),t("span",null,"匹配条件"),t("span",null,"Agent"),t("span",null,"区域"),t("span",{class:"text-right"},"操作")],-1)),(o(!0),i(g,null,x(j.value,(l,c)=>(o(),i("div",{key:l.id,class:C(["rule-row",{off:!l.enable}]),onClick:y=>_e(l)},[t("div",ht,[t("span",At,a(l.priority),1),t("span",wt,"#"+a(c+1),1)]),t("div",Ct,[t("div",Vt,[t("span",{class:C(["lang-badge",{any:$(l.src_langs)}])},a(w(l.src_langs)),3),t("span",Lt,a(l.bidir?"⇄":"→"),1),t("span",{class:C(["lang-badge",{any:$(l.dst_langs)}])},a(w(l.dst_langs)),3)]),l.name||l.remark?(o(),i("div",$t,[S(a(l.name),1),l.remark?(o(),i("span",St," · "+a(l.remark),1)):m("",!0)])):m("",!0)]),t("div",Ut,[t("span",{class:"type-badge",style:ce(J(ee(l.agent_id)))},a(G(ee(l.agent_id))),5),t("span",jt,a(me(l.agent_id)),1)]),t("div",It,a(l.region===0?"全部区域":W(l.region)),1),t("div",Nt,[l.enable?(o(),i("span",Rt,"启用")):(o(),i("span",Tt,"停用")),t("button",{class:"btn btn-ghost btn-xs text-error",onClick:z(y=>Ae(l),["stop"])},"删除",8,Bt)])],10,kt))),128))])):(o(),i("div",xt,[...e[38]||(e[38]=[t("div",{class:"text-5xl mb-3"},"🌐",-1),t("p",{class:"text-sm"},"当前区域还没有翻译规则",-1),t("p",{class:"text-xs mt-1"},"建议先加一条「任意 → 任意」的兜底规则,再往上叠精确规则",-1)])])),p(t("div",{class:"ct-overlay",onClick:e[16]||(e[16]=z(l=>B.value=!1,["self"]))},[t("div",Et,[e[42]||(e[42]=t("h3",{class:"text-base font-semibold text-slate-800 mb-1"},"选路试算",-1)),e[43]||(e[43]=t("p",{class:"text-xs text-slate-400 mb-4"},"用后端运行时同一套匹配逻辑,算一遍这个方向实际会走哪条规则。",-1)),t("div",Ot,[t("div",null,[e[40]||(e[40]=t("span",{class:"ed-label"},"源语言",-1)),pe(D,{modelValue:E.value,"onUpdate:modelValue":e[13]||(e[13]=l=>E.value=l)},null,8,["modelValue"])]),t("div",null,[e[41]||(e[41]=t("span",{class:"ed-label"},"目标语言",-1)),pe(D,{modelValue:O.value,"onUpdate:modelValue":e[14]||(e[14]=l=>O.value=l)},null,8,["modelValue"])])]),d.value?(o(),i("div",{key:0,class:C(["test-result",{miss:!d.value.matched}])},[d.value.matched?(o(),i(g,{key:0},[t("div",Mt," 命中规则:"+a(d.value.rule?.name||"#"+d.value.rule?.id)+"(优先级 "+a(d.value.rule?.priority)+") ",1),t("div",zt,[S(a(w(d.value.rule?.src_langs))+" "+a(d.value.rule?.bidir?"⇄":"→")+" "+a(w(d.value.rule?.dst_langs))+" · Agent:"+a(d.value.agent?.name||d.value.rule?.agent_id)+" ",1),d.value.agent?(o(),i("span",Dt,"("+a(G(d.value.agent.type))+")",1)):m("",!0)])],64)):(o(),i("div",Gt,"没有任何规则命中 —— 这个方向的通话翻译会不可用,建议补一条兜底规则。"))],2)):m("",!0),t("div",qt,[t("button",{class:"btn btn-ghost",onClick:e[15]||(e[15]=l=>B.value=!1)},"关闭"),t("button",{class:"btn btn-primary text-white",onClick:Le},"试算")])])],512),[[P,B.value]]),p(t("div",Ft,[t("div",Pt,[e[45]||(e[45]=t("h3",{class:"text-base font-semibold text-slate-800 mb-1"},"同步到其他区域",-1)),t("p",Yt,a(oe.value),1),e[46]||(e[46]=t("div",{class:"text-xs px-3 py-2 rounded-lg mb-3",style:{background:"#f0fdf4",border:"1px solid #bbf7d0",color:"#15803d"}}," ✦ 同步内容:语言条件、Agent、优先级、启停状态一并复制到目标区域。 ",-1)),t("div",Ht,[e[44]||(e[44]=t("span",{class:"text-xs font-semibold text-slate-500"},"选择目标区域",-1)),t("div",Wt,[t("button",{class:"btn btn-ghost btn-xs",onClick:e[17]||(e[17]=l=>de(!0))},"全选"),t("button",{class:"btn btn-ghost btn-xs",onClick:e[18]||(e[18]=l=>de(!1))},"清空")])]),t("div",Jt,[(o(!0),i(g,null,x(ie.value,l=>(o(),i("label",{key:l.value,class:C(["sync-region-item",{checked:r.value.includes(l.value)}]),onClick:z(c=>ue(l.value),["prevent"])},[t("input",{type:"checkbox",class:"checkbox checkbox-xs checkbox-primary",checked:r.value.includes(l.value),onClick:z(c=>ue(l.value),["stop"])},null,8,Qt),t("span",null,a(l.label),1)],10,Kt))),128))]),e[47]||(e[47]=t("p",{class:"text-[11px] text-slate-400 mb-5"},"⚠ 目标区域已有「同 Agent + 同语言条件」的规则则覆盖,否则新建。",-1)),t("div",Xt,[t("button",{class:"btn btn-ghost",onClick:e[19]||(e[19]=l=>T.value=!1)},"取消"),t("button",{class:"btn btn-primary text-white",disabled:!r.value.length,onClick:Ce}," 保存并同步"+a(r.value.length?"("+r.value.length+" 个区域)":""),9,Zt)])])],512),[[P,T.value]])]))}}),us=Ne(es,[["__scopeId","data-v-c0bab860"]]);export{us as default}; diff --git a/apps/admin/.output/public/_nuxt/C3hsc2UX.js b/apps/admin/.output/public/_nuxt/BuCQ8FwD.js similarity index 98% rename from apps/admin/.output/public/_nuxt/C3hsc2UX.js rename to apps/admin/.output/public/_nuxt/BuCQ8FwD.js index d71e4517..3547f046 100644 --- a/apps/admin/.output/public/_nuxt/C3hsc2UX.js +++ b/apps/admin/.output/public/_nuxt/BuCQ8FwD.js @@ -1 +1 @@ -import{g as D,B as F,c as n,p as i,H as $,a as e,F as b,r as y,q as B,v,l as j,t as r,m as q,x as d,y as I,z as E,o as u}from"./Ccu6Xgpt.js";import{u as O}from"./Um-KoueI.js";import{u as T}from"./DvwKXRUn.js";import"./CH2ZVAK2.js";const z={class:"flex items-center justify-between mb-5"},G={class:"flex items-center gap-3 mb-4"},H=["value"],J={class:"bg-white rounded-xl shadow-sm border border-slate-100"},K={class:"overflow-x-auto"},P={class:"table"},Q={key:0},W={key:1},X={class:"bg-slate-100/80"},Y={colspan:"4",class:"py-2"},Z={class:"font-semibold text-slate-600 text-sm"},ee={class:"text-xs text-slate-400 ml-2"},te={class:"font-mono text-sm font-medium"},le=["title"],se={class:"text-sm text-slate-400"},oe={class:"text-right"},ae={class:"inline-flex gap-1"},ne=["onClick"],ie=["onClick"],ue={class:"flex items-center gap-3 mb-5"},re={class:"text-lg font-semibold text-slate-800"},de={class:"bg-white rounded-xl shadow-sm border border-slate-100 p-6 max-w-2xl"},me={class:"grid grid-cols-2 gap-4"},be={class:"form-control mb-4"},ve=["value"],pe={class:"form-control mb-4"},ce={class:"form-control mb-4"},fe={class:"form-control mb-4"},ge={class:"form-control mb-6"},xe={class:"flex gap-3"},ye=["disabled"],Ve=D({__name:"globalconfig",setup(we){const V=[{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:"印度"}],{webApi:p}=O(),{success:U,error:w}=T(),c=d("list"),f=d([]),k=d(!1),_=d(!1),g=d(!1),m=d(1),h=d(""),s=I({id:0,region:1,group:"",key:"",value:"",description:""}),N=E(()=>{const o=h.value.trim().toLowerCase();return o?f.value.filter(t=>((t.group||"")+(t.key||"")).toLowerCase().includes(o)):f.value}),L=E(()=>{const o={};return N.value.forEach(l=>{const a=l.group||"";(o[a]=o[a]||[]).push(l)}),Object.keys(o).sort((l,a)=>l===""?-1:a===""?1:l({key:l,label:l||"未分组",items:o[l]}))});async function x(){k.value=!0;try{const o=await p("getglobalconfigs",{region:m.value});f.value=o?.items??[]}catch(o){w(o?.message??"获取配置失败"),f.value=[]}finally{k.value=!1}}function C(){c.value="list",x()}function S(o){o?(g.value=!0,s.id=o.id||0,s.region=o.region||1,s.group=o.group||"",s.key=o.key||"",s.value=o.value||"",s.description=o.description||""):(g.value=!1,s.id=0,s.region=m.value>0?m.value:1,s.group="",s.key="",s.value="",s.description=""),c.value="form"}async function M(){_.value=!0;try{const o={region:Number(s.region)||0,group:s.group.trim(),key:s.key.trim(),value:s.value,description:s.description.trim()};g.value?(o.id=Number(s.id),await p("updateglobalconfig",o)):await p("addglobalconfig",o),U("保存成功"),C()}catch(o){w(o?.message??"保存失败")}finally{_.value=!1}}function R(o){window.confirm("确定删除该配置项吗?")&&p("delglobalconfig",{ids:[o.id]}).then(()=>{U("删除成功"),x()}).catch(t=>w(t?.message??"删除失败"))}return F(x),(o,t)=>(u(),n("div",null,[i(e("div",null,[e("div",z,[t[10]||(t[10]=e("div",null,[e("h2",{class:"text-lg font-semibold text-slate-800"},"全局环境配置"),e("p",{class:"text-xs text-slate-400 mt-1"},"全局第三方服务配置(AI / 翻译等),按区域分组,所有应用共享。修改后各服务约 10 分钟内自动同步。")],-1)),e("button",{class:"btn btn-primary btn-sm text-white",onClick:t[0]||(t[0]=l=>S())},"+ 新增配置")]),e("div",G,[t[11]||(t[11]=e("span",{class:"text-sm text-slate-500"},"区域",-1)),i(e("select",{"onUpdate:modelValue":t[1]||(t[1]=l=>m.value=l),class:"select select-bordered select-sm",onChange:x},[(u(),n(b,null,y(V,l=>e("option",{key:l.value,value:l.value},r(l.label),9,H)),64))],544),[[B,m.value,void 0,{number:!0}]]),i(e("input",{"onUpdate:modelValue":t[2]||(t[2]=l=>h.value=l),class:"input input-bordered input-sm w-48",placeholder:"按分组/键搜索"},null,512),[[v,h.value]])]),e("div",J,[e("div",K,[e("table",P,[t[14]||(t[14]=e("thead",null,[e("tr",null,[e("th",null,"键"),e("th",null,"值"),e("th",null,"描述"),e("th",{class:"text-right"},"操作")])],-1)),e("tbody",null,[k.value?(u(),n("tr",Q,[...t[12]||(t[12]=[e("td",{colspan:"4",class:"text-center py-8"},[e("span",{class:"loading loading-spinner loading-sm"})],-1)])])):N.value.length?j("",!0):(u(),n("tr",W,[...t[13]||(t[13]=[e("td",{colspan:"4",class:"text-center text-slate-400 py-8"},"暂无配置",-1)])])),(u(!0),n(b,null,y(L.value,l=>(u(),n(b,{key:l.key},[e("tr",X,[e("td",Y,[e("span",Z,"▸ "+r(l.label),1),e("span",ee,r(l.items.length)+" 项",1)])]),(u(!0),n(b,null,y(l.items,a=>(u(),n("tr",{key:a.id,class:"hover"},[e("td",te,r(a.key||""),1),e("td",{class:"text-sm text-slate-500 max-w-xs truncate",title:a.value||""},r(a.value||""),9,le),e("td",se,r(a.description||""),1),e("td",oe,[e("div",ae,[e("button",{class:"btn btn-ghost btn-xs",onClick:A=>S(a)},"编辑",8,ne),e("button",{class:"btn btn-ghost btn-xs text-red-500",onClick:A=>R(a)},"删除",8,ie)])])]))),128))],64))),128))])])])])],512),[[$,c.value==="list"]]),i(e("div",null,[e("div",ue,[e("button",{class:"btn btn-ghost btn-sm",onClick:t[3]||(t[3]=l=>C())},"← 返回列表"),e("h2",re,r(g.value?"编辑配置":"新增配置"),1)]),e("div",de,[e("form",{onSubmit:q(M,["prevent"])},[e("div",me,[e("div",be,[t[15]||(t[15]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"区域 *")],-1)),i(e("select",{"onUpdate:modelValue":t[4]||(t[4]=l=>s.region=l),class:"select select-bordered w-full"},[(u(),n(b,null,y(V,l=>e("option",{key:l.value,value:l.value},r(l.label),9,ve)),64))],512),[[B,s.region,void 0,{number:!0}]])]),e("div",pe,[t[16]||(t[16]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"分组 (group)")],-1)),i(e("input",{"onUpdate:modelValue":t[5]||(t[5]=l=>s.group=l),type:"text",class:"input input-bordered w-full",placeholder:"如 ai / translate / asr"},null,512),[[v,s.group]])])]),e("div",ce,[t[17]||(t[17]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"键 (key) *")],-1)),i(e("input",{"onUpdate:modelValue":t[6]||(t[6]=l=>s.key=l),type:"text",class:"input input-bordered w-full",required:"",placeholder:"如 openai_api_key"},null,512),[[v,s.key]])]),e("div",fe,[t[18]||(t[18]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"值 (value)")],-1)),i(e("textarea",{"onUpdate:modelValue":t[7]||(t[7]=l=>s.value=l),class:"textarea textarea-bordered w-full font-mono text-sm",rows:"3"},null,512),[[v,s.value]])]),e("div",ge,[t[19]||(t[19]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"描述")],-1)),i(e("input",{"onUpdate:modelValue":t[8]||(t[8]=l=>s.description=l),type:"text",class:"input input-bordered w-full"},null,512),[[v,s.description]])]),e("div",xe,[e("button",{type:"button",class:"btn btn-ghost",onClick:t[9]||(t[9]=l=>C())},"取消"),e("button",{type:"submit",class:"btn btn-primary text-white",disabled:_.value},"保存",8,ye)])],32)])],512),[[$,c.value==="form"]])]))}});export{Ve as default}; +import{g as D,B as F,c as n,p as i,H as $,a as e,F as b,r as y,q as B,v,l as j,t as r,m as q,x as d,y as I,z as E,o as u}from"./mElhLwm2.js";import{u as O}from"./C6twYRfy.js";import{u as T}from"./FVTAbpot.js";import"./qig5Qp6S.js";const z={class:"flex items-center justify-between mb-5"},G={class:"flex items-center gap-3 mb-4"},H=["value"],J={class:"bg-white rounded-xl shadow-sm border border-slate-100"},K={class:"overflow-x-auto"},P={class:"table"},Q={key:0},W={key:1},X={class:"bg-slate-100/80"},Y={colspan:"4",class:"py-2"},Z={class:"font-semibold text-slate-600 text-sm"},ee={class:"text-xs text-slate-400 ml-2"},te={class:"font-mono text-sm font-medium"},le=["title"],se={class:"text-sm text-slate-400"},oe={class:"text-right"},ae={class:"inline-flex gap-1"},ne=["onClick"],ie=["onClick"],ue={class:"flex items-center gap-3 mb-5"},re={class:"text-lg font-semibold text-slate-800"},de={class:"bg-white rounded-xl shadow-sm border border-slate-100 p-6 max-w-2xl"},me={class:"grid grid-cols-2 gap-4"},be={class:"form-control mb-4"},ve=["value"],pe={class:"form-control mb-4"},ce={class:"form-control mb-4"},fe={class:"form-control mb-4"},ge={class:"form-control mb-6"},xe={class:"flex gap-3"},ye=["disabled"],Ve=D({__name:"globalconfig",setup(we){const V=[{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:"印度"}],{webApi:p}=O(),{success:U,error:w}=T(),c=d("list"),f=d([]),k=d(!1),_=d(!1),g=d(!1),m=d(1),h=d(""),s=I({id:0,region:1,group:"",key:"",value:"",description:""}),N=E(()=>{const o=h.value.trim().toLowerCase();return o?f.value.filter(t=>((t.group||"")+(t.key||"")).toLowerCase().includes(o)):f.value}),L=E(()=>{const o={};return N.value.forEach(l=>{const a=l.group||"";(o[a]=o[a]||[]).push(l)}),Object.keys(o).sort((l,a)=>l===""?-1:a===""?1:l({key:l,label:l||"未分组",items:o[l]}))});async function x(){k.value=!0;try{const o=await p("getglobalconfigs",{region:m.value});f.value=o?.items??[]}catch(o){w(o?.message??"获取配置失败"),f.value=[]}finally{k.value=!1}}function C(){c.value="list",x()}function S(o){o?(g.value=!0,s.id=o.id||0,s.region=o.region||1,s.group=o.group||"",s.key=o.key||"",s.value=o.value||"",s.description=o.description||""):(g.value=!1,s.id=0,s.region=m.value>0?m.value:1,s.group="",s.key="",s.value="",s.description=""),c.value="form"}async function M(){_.value=!0;try{const o={region:Number(s.region)||0,group:s.group.trim(),key:s.key.trim(),value:s.value,description:s.description.trim()};g.value?(o.id=Number(s.id),await p("updateglobalconfig",o)):await p("addglobalconfig",o),U("保存成功"),C()}catch(o){w(o?.message??"保存失败")}finally{_.value=!1}}function R(o){window.confirm("确定删除该配置项吗?")&&p("delglobalconfig",{ids:[o.id]}).then(()=>{U("删除成功"),x()}).catch(t=>w(t?.message??"删除失败"))}return F(x),(o,t)=>(u(),n("div",null,[i(e("div",null,[e("div",z,[t[10]||(t[10]=e("div",null,[e("h2",{class:"text-lg font-semibold text-slate-800"},"全局环境配置"),e("p",{class:"text-xs text-slate-400 mt-1"},"全局第三方服务配置(AI / 翻译等),按区域分组,所有应用共享。修改后各服务约 10 分钟内自动同步。")],-1)),e("button",{class:"btn btn-primary btn-sm text-white",onClick:t[0]||(t[0]=l=>S())},"+ 新增配置")]),e("div",G,[t[11]||(t[11]=e("span",{class:"text-sm text-slate-500"},"区域",-1)),i(e("select",{"onUpdate:modelValue":t[1]||(t[1]=l=>m.value=l),class:"select select-bordered select-sm",onChange:x},[(u(),n(b,null,y(V,l=>e("option",{key:l.value,value:l.value},r(l.label),9,H)),64))],544),[[B,m.value,void 0,{number:!0}]]),i(e("input",{"onUpdate:modelValue":t[2]||(t[2]=l=>h.value=l),class:"input input-bordered input-sm w-48",placeholder:"按分组/键搜索"},null,512),[[v,h.value]])]),e("div",J,[e("div",K,[e("table",P,[t[14]||(t[14]=e("thead",null,[e("tr",null,[e("th",null,"键"),e("th",null,"值"),e("th",null,"描述"),e("th",{class:"text-right"},"操作")])],-1)),e("tbody",null,[k.value?(u(),n("tr",Q,[...t[12]||(t[12]=[e("td",{colspan:"4",class:"text-center py-8"},[e("span",{class:"loading loading-spinner loading-sm"})],-1)])])):N.value.length?j("",!0):(u(),n("tr",W,[...t[13]||(t[13]=[e("td",{colspan:"4",class:"text-center text-slate-400 py-8"},"暂无配置",-1)])])),(u(!0),n(b,null,y(L.value,l=>(u(),n(b,{key:l.key},[e("tr",X,[e("td",Y,[e("span",Z,"▸ "+r(l.label),1),e("span",ee,r(l.items.length)+" 项",1)])]),(u(!0),n(b,null,y(l.items,a=>(u(),n("tr",{key:a.id,class:"hover"},[e("td",te,r(a.key||""),1),e("td",{class:"text-sm text-slate-500 max-w-xs truncate",title:a.value||""},r(a.value||""),9,le),e("td",se,r(a.description||""),1),e("td",oe,[e("div",ae,[e("button",{class:"btn btn-ghost btn-xs",onClick:A=>S(a)},"编辑",8,ne),e("button",{class:"btn btn-ghost btn-xs text-red-500",onClick:A=>R(a)},"删除",8,ie)])])]))),128))],64))),128))])])])])],512),[[$,c.value==="list"]]),i(e("div",null,[e("div",ue,[e("button",{class:"btn btn-ghost btn-sm",onClick:t[3]||(t[3]=l=>C())},"← 返回列表"),e("h2",re,r(g.value?"编辑配置":"新增配置"),1)]),e("div",de,[e("form",{onSubmit:q(M,["prevent"])},[e("div",me,[e("div",be,[t[15]||(t[15]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"区域 *")],-1)),i(e("select",{"onUpdate:modelValue":t[4]||(t[4]=l=>s.region=l),class:"select select-bordered w-full"},[(u(),n(b,null,y(V,l=>e("option",{key:l.value,value:l.value},r(l.label),9,ve)),64))],512),[[B,s.region,void 0,{number:!0}]])]),e("div",pe,[t[16]||(t[16]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"分组 (group)")],-1)),i(e("input",{"onUpdate:modelValue":t[5]||(t[5]=l=>s.group=l),type:"text",class:"input input-bordered w-full",placeholder:"如 ai / translate / asr"},null,512),[[v,s.group]])])]),e("div",ce,[t[17]||(t[17]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"键 (key) *")],-1)),i(e("input",{"onUpdate:modelValue":t[6]||(t[6]=l=>s.key=l),type:"text",class:"input input-bordered w-full",required:"",placeholder:"如 openai_api_key"},null,512),[[v,s.key]])]),e("div",fe,[t[18]||(t[18]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"值 (value)")],-1)),i(e("textarea",{"onUpdate:modelValue":t[7]||(t[7]=l=>s.value=l),class:"textarea textarea-bordered w-full font-mono text-sm",rows:"3"},null,512),[[v,s.value]])]),e("div",ge,[t[19]||(t[19]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"描述")],-1)),i(e("input",{"onUpdate:modelValue":t[8]||(t[8]=l=>s.description=l),type:"text",class:"input input-bordered w-full"},null,512),[[v,s.description]])]),e("div",xe,[e("button",{type:"button",class:"btn btn-ghost",onClick:t[9]||(t[9]=l=>C())},"取消"),e("button",{type:"submit",class:"btn btn-primary text-white",disabled:_.value},"保存",8,ye)])],32)])],512),[[$,c.value==="form"]])]))}});export{Ve as default}; diff --git a/apps/admin/.output/public/_nuxt/CFdmUKvC.js b/apps/admin/.output/public/_nuxt/C-2gsgTH.js similarity index 95% rename from apps/admin/.output/public/_nuxt/CFdmUKvC.js rename to apps/admin/.output/public/_nuxt/C-2gsgTH.js index 7e015b5e..d1cc98fd 100644 --- a/apps/admin/.output/public/_nuxt/CFdmUKvC.js +++ b/apps/admin/.output/public/_nuxt/C-2gsgTH.js @@ -1 +1 @@ -import{g as h,j as x,k as w,B as y,c as r,a as e,t as d,l as b,m as _,p as v,v as g,n as k,y as B,x as u,o as p,_ as M}from"./Ccu6Xgpt.js";const A={class:"login-bg flex items-center justify-center px-4"},z={class:"login-card"},C={class:"text-center"},S={style:{"font-size":"22px","font-weight":"700",color:"#0F172A",margin:"0 0 4px"}},T={key:0,class:"login-error show"},V={style:{width:"16px",height:"16px","flex-shrink":"0"},fill:"none",viewBox:"0 0 24 24",stroke:"currentColor"},j={style:{"margin-bottom":"16px"}},D={style:{"margin-bottom":"24px"}},q=h({__name:"index",setup(L){const a=x(),c=w(),o=B({account:"",password:""}),l=u(!1),n=u(""),m=u("Admin");y(async()=>{if(a.restore(),a.token){c.push("/dashboard");return}try{const t=(await $fetch("/web/api/api_getsiteinfo",{method:"POST",body:{}}))?.data?.sitename;t&&(m.value=t+" Admin",a.setSiteTitle(t))}catch{}});async function f(){l.value=!0,n.value="";try{const s=await $fetch("/web/api/api_login",{method:"POST",body:{account:o.account,password:o.password}});s.code===0&&s.data?(a.setLoginData(s.data),c.push("/dashboard")):n.value=s.msg||"登录失败"}catch{n.value="网络错误,请检查连接"}finally{l.value=!1}}return(s,t)=>(p(),r("div",A,[e("div",z,[e("div",C,[t[2]||(t[2]=e("div",{class:"logo-icon"},[e("svg",{class:"h-7 w-7 text-white",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor"},[e("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M9.75 17L9 20l-1 1h8l-1-1-.75-3M3 13h18M5 17h14a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"})])],-1)),e("h1",S,d(m.value),1),t[3]||(t[3]=e("p",{style:{"font-size":"13px",color:"#94A3B8",margin:"0 0 32px"}},"管理控制台",-1))]),n.value?(p(),r("div",T,[(p(),r("svg",V,[...t[4]||(t[4]=[e("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"},null,-1)])])),e("span",null,d(n.value),1)])):b("",!0),e("form",{onSubmit:_(f,["prevent"])},[e("div",j,[t[5]||(t[5]=e("label",{class:"login-label"},"账号",-1)),v(e("input",{"onUpdate:modelValue":t[0]||(t[0]=i=>o.account=i),type:"text",class:"login-input",placeholder:"请输入管理员账号",autocomplete:"username",required:""},null,512),[[g,o.account]])]),e("div",D,[t[6]||(t[6]=e("label",{class:"login-label"},"密码",-1)),v(e("input",{"onUpdate:modelValue":t[1]||(t[1]=i=>o.password=i),type:"password",class:"login-input",placeholder:"请输入密码",autocomplete:"current-password",required:""},null,512),[[g,o.password]])]),e("button",{type:"submit",class:k(["login-btn",{loading:l.value}])},d(l.value?"登录中...":"登 录"),3)],32),t[7]||(t[7]=e("p",{style:{"text-align":"center","font-size":"11px",color:"#94A3B8","margin-top":"24px"}}," © 2025 Admin Console · v1.0.1 ",-1))])]))}}),O=M(q,[["__scopeId","data-v-3a3bca03"]]);export{O as default}; +import{g as h,j as x,k as w,B as y,c as r,a as e,t as d,l as b,m as _,p as v,v as g,n as k,y as B,x as u,o as p,_ as M}from"./mElhLwm2.js";const A={class:"login-bg flex items-center justify-center px-4"},z={class:"login-card"},C={class:"text-center"},S={style:{"font-size":"22px","font-weight":"700",color:"#0F172A",margin:"0 0 4px"}},T={key:0,class:"login-error show"},V={style:{width:"16px",height:"16px","flex-shrink":"0"},fill:"none",viewBox:"0 0 24 24",stroke:"currentColor"},j={style:{"margin-bottom":"16px"}},D={style:{"margin-bottom":"24px"}},q=h({__name:"index",setup(L){const a=x(),c=w(),o=B({account:"",password:""}),l=u(!1),n=u(""),m=u("Admin");y(async()=>{if(a.restore(),a.token){c.push("/dashboard");return}try{const t=(await $fetch("/web/api/api_getsiteinfo",{method:"POST",body:{}}))?.data?.sitename;t&&(m.value=t+" Admin",a.setSiteTitle(t))}catch{}});async function f(){l.value=!0,n.value="";try{const s=await $fetch("/web/api/api_login",{method:"POST",body:{account:o.account,password:o.password}});s.code===0&&s.data?(a.setLoginData(s.data),c.push("/dashboard")):n.value=s.msg||"登录失败"}catch{n.value="网络错误,请检查连接"}finally{l.value=!1}}return(s,t)=>(p(),r("div",A,[e("div",z,[e("div",C,[t[2]||(t[2]=e("div",{class:"logo-icon"},[e("svg",{class:"h-7 w-7 text-white",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor"},[e("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M9.75 17L9 20l-1 1h8l-1-1-.75-3M3 13h18M5 17h14a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"})])],-1)),e("h1",S,d(m.value),1),t[3]||(t[3]=e("p",{style:{"font-size":"13px",color:"#94A3B8",margin:"0 0 32px"}},"管理控制台",-1))]),n.value?(p(),r("div",T,[(p(),r("svg",V,[...t[4]||(t[4]=[e("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"},null,-1)])])),e("span",null,d(n.value),1)])):b("",!0),e("form",{onSubmit:_(f,["prevent"])},[e("div",j,[t[5]||(t[5]=e("label",{class:"login-label"},"账号",-1)),v(e("input",{"onUpdate:modelValue":t[0]||(t[0]=i=>o.account=i),type:"text",class:"login-input",placeholder:"请输入管理员账号",autocomplete:"username",required:""},null,512),[[g,o.account]])]),e("div",D,[t[6]||(t[6]=e("label",{class:"login-label"},"密码",-1)),v(e("input",{"onUpdate:modelValue":t[1]||(t[1]=i=>o.password=i),type:"password",class:"login-input",placeholder:"请输入密码",autocomplete:"current-password",required:""},null,512),[[g,o.password]])]),e("button",{type:"submit",class:k(["login-btn",{loading:l.value}])},d(l.value?"登录中...":"登 录"),3)],32),t[7]||(t[7]=e("p",{style:{"text-align":"center","font-size":"11px",color:"#94A3B8","margin-top":"24px"}}," © 2025 Admin Console · v1.0.1 ",-1))])]))}}),O=M(q,[["__scopeId","data-v-3a3bca03"]]);export{O as default}; diff --git a/apps/admin/.output/public/_nuxt/aWlcN8xt.js b/apps/admin/.output/public/_nuxt/C2WfoPPr.js similarity index 84% rename from apps/admin/.output/public/_nuxt/aWlcN8xt.js rename to apps/admin/.output/public/_nuxt/C2WfoPPr.js index 95a486ef..c2e90f2c 100644 --- a/apps/admin/.output/public/_nuxt/aWlcN8xt.js +++ b/apps/admin/.output/public/_nuxt/C2WfoPPr.js @@ -1 +1 @@ -import{g as t,B as n,P as a,c as o,a as s,o as c}from"./Ccu6Xgpt.js";const i={class:"py-16 text-center text-slate-400"},m=t({__name:"mcpconfig",setup(l){return n(()=>{a("/serviceconfig")}),(r,e)=>(c(),o("div",i,[...e[0]||(e[0]=[s("span",{class:"loading loading-spinner loading-sm"},null,-1),s("p",{class:"text-sm mt-3"},"MCP 配置已并入「第三方服务配置」,正在跳转…",-1)])]))}});export{m as default}; +import{g as t,B as n,P as a,c as o,a as s,o as c}from"./mElhLwm2.js";const i={class:"py-16 text-center text-slate-400"},m=t({__name:"mcpconfig",setup(l){return n(()=>{a("/serviceconfig")}),(r,e)=>(c(),o("div",i,[...e[0]||(e[0]=[s("span",{class:"loading loading-spinner loading-sm"},null,-1),s("p",{class:"text-sm mt-3"},"MCP 配置已并入「第三方服务配置」,正在跳转…",-1)])]))}});export{m as default}; diff --git a/apps/admin/.output/public/_nuxt/Um-KoueI.js b/apps/admin/.output/public/_nuxt/C6twYRfy.js similarity index 90% rename from apps/admin/.output/public/_nuxt/Um-KoueI.js rename to apps/admin/.output/public/_nuxt/C6twYRfy.js index c84946a6..ea7eebb6 100644 --- a/apps/admin/.output/public/_nuxt/Um-KoueI.js +++ b/apps/admin/.output/public/_nuxt/C6twYRfy.js @@ -1 +1 @@ -import{j as w,k as d}from"./Ccu6Xgpt.js";import{u as h}from"./CH2ZVAK2.js";async function f(o,i,a){const e=w(),u=d(),s={"Content-Type":"application/json"};e.token&&(s.Authorization=e.token),a&&Object.assign(s,a);const t=await fetch(o,{method:"POST",headers:s,body:JSON.stringify(i)});if(!t.ok)throw new Error(`HTTP error: ${t.status}`);const n=await t.json();if(n.code===18)throw e.logout(),u.push("/"),new Error(n.msg||"Unauthorized");if(n.code!==0)throw new Error(n.msg||"Unknown error");return n.data}const y=/^(get|list|load|query|fetch|search|count|stat|export|check)/i;function g(o){return!y.test(o)}function A(){const o=w(),{begin:i,end:a}=h();async function e(t,n){const r={};if(o.currentAppId&&(r["X-App-Id"]=String(o.currentAppId)),!g(t))return f(`/web/api/api_${t}`,n??{},r);i();try{return await f(`/web/api/api_${t}`,n??{},r)}finally{a()}}async function u(t,n){return f(`/console/api/${t}`,n??{})}async function s(t,n){const r=t.type||"application/octet-stream",c=await e("getcostoken",{path:n,filename:t.name,content_type:r}),p=c.upload_url||c.url||"";if(!p)throw new Error("未获取到上传地址:请确认已在【第三方服务配置→存储】配置并启用「阿里云 OSS」");const l=await fetch(p,{method:"PUT",headers:{"Content-Type":r},body:t});if(!l.ok)throw new Error(`Upload failed: ${l.status}`);return c.url||p.split("?")[0]}return{webApi:e,consoleApi:u,uploadFile:s}}export{A as u}; +import{j as w,k as d}from"./mElhLwm2.js";import{u as h}from"./qig5Qp6S.js";async function f(o,i,a){const e=w(),u=d(),s={"Content-Type":"application/json"};e.token&&(s.Authorization=e.token),a&&Object.assign(s,a);const t=await fetch(o,{method:"POST",headers:s,body:JSON.stringify(i)});if(!t.ok)throw new Error(`HTTP error: ${t.status}`);const n=await t.json();if(n.code===18)throw e.logout(),u.push("/"),new Error(n.msg||"Unauthorized");if(n.code!==0)throw new Error(n.msg||"Unknown error");return n.data}const y=/^(get|list|load|query|fetch|search|count|stat|export|check)/i;function g(o){return!y.test(o)}function A(){const o=w(),{begin:i,end:a}=h();async function e(t,n){const r={};if(o.currentAppId&&(r["X-App-Id"]=String(o.currentAppId)),!g(t))return f(`/web/api/api_${t}`,n??{},r);i();try{return await f(`/web/api/api_${t}`,n??{},r)}finally{a()}}async function u(t,n){return f(`/console/api/${t}`,n??{})}async function s(t,n){const r=t.type||"application/octet-stream",c=await e("getcostoken",{path:n,filename:t.name,content_type:r}),p=c.upload_url||c.url||"";if(!p)throw new Error("未获取到上传地址:请确认已在【第三方服务配置→存储】配置并启用「阿里云 OSS」");const l=await fetch(p,{method:"PUT",headers:{"Content-Type":r},body:t});if(!l.ok)throw new Error(`Upload failed: ${l.status}`);return c.url||p.split("?")[0]}return{webApi:e,consoleApi:u,uploadFile:s}}export{A as u}; diff --git a/apps/admin/.output/public/_nuxt/BQIhlerM.js b/apps/admin/.output/public/_nuxt/CRsHkMZx.js similarity index 99% rename from apps/admin/.output/public/_nuxt/BQIhlerM.js rename to apps/admin/.output/public/_nuxt/CRsHkMZx.js index ef33ff31..303e02e6 100644 --- a/apps/admin/.output/public/_nuxt/BQIhlerM.js +++ b/apps/admin/.output/public/_nuxt/CRsHkMZx.js @@ -1 +1 @@ -import{g as ue,y as P,B as ce,c as o,p as i,H as B,a as e,l as g,F as h,r as C,t as r,m as Y,v,q as L,d as j,s as Q,x as b,z as be,o as a,n as me}from"./Ccu6Xgpt.js";import{u as pe}from"./Um-KoueI.js";import{u as ve}from"./DvwKXRUn.js";import"./CH2ZVAK2.js";const fe={class:"flex items-center justify-between mb-5"},ge={class:"bg-white rounded-xl shadow-sm border border-slate-100"},xe={class:"overflow-x-auto"},ye={class:"table table-zebra text-sm"},we={key:0},ke={key:1},he={class:"font-mono text-sm"},_e=["src"],Ve={key:1,class:"w-10 h-10 rounded bg-slate-100 flex items-center justify-center text-slate-300"},Ce={class:"font-medium"},Ue={class:"badge badge-outline badge-sm"},Ee={class:"text-sm"},Ie={key:0},Ne={key:1,class:"text-slate-300"},$e={class:"text-xs text-slate-500"},De={class:"flex gap-1"},Be=["onClick"],Le=["onClick"],Se=["onClick"],Me={class:"flex items-center gap-3 mb-5"},Te={class:"text-lg font-semibold text-slate-800"},ze={class:"bg-white rounded-xl shadow-sm border border-slate-100 p-6 max-w-3xl"},Fe={class:"form-control mb-4"},Oe={class:"grid grid-cols-2 gap-4 mb-4"},Pe={class:"form-control"},je=["value"],Ae={class:"form-control"},qe=["value"],He={class:"grid grid-cols-2 gap-4 mb-4"},Je={class:"form-control"},Ke={class:"form-control"},Ye={class:"grid grid-cols-2 gap-4 mb-4"},Qe={class:"form-control"},Re={class:"mb-4"},Ge={class:"grid grid-cols-3 gap-4"},We={class:"form-control"},Xe={class:"form-control"},Ze={class:"form-control"},et={class:"form-control mb-4"},tt={class:"flex items-start gap-4"},st={class:"flex-1"},lt={class:"flex items-center gap-2"},nt=["disabled"],ot={key:0,class:"loading loading-spinner loading-xs"},at={key:0},it=["src"],dt={class:"grid grid-cols-3 gap-4 mb-4"},rt={class:"form-control"},ut={class:"form-control"},ct={class:"form-control"},bt={class:"grid grid-cols-3 gap-3 mb-6"},mt=["onUpdate:modelValue"],pt={class:"text-sm"},vt={class:"flex gap-3"},ft=["disabled"],gt={key:0,class:"loading loading-spinner loading-xs"},xt={class:"flex items-center gap-3 mb-5"},yt={class:"text-lg font-semibold text-slate-800"},wt={key:0,class:"bg-white rounded-xl shadow-sm border border-slate-100 p-4 mb-5"},kt={class:"flex items-center gap-6 text-sm flex-wrap"},ht={class:"font-mono"},_t={class:"badge badge-primary badge-sm"},Vt={class:"text-xs"},Ct={class:"text-xs max-w-md truncate"},Ut={class:"bg-white rounded-xl shadow-sm border border-slate-100 p-5 mb-5"},Et={class:"grid grid-cols-2 gap-4 mb-3"},It={class:"form-control"},Nt={class:"form-control"},$t={class:"form-control mb-3"},Dt={class:"flex items-center gap-3"},Bt={class:"flex items-center gap-2 cursor-pointer"},Lt=["disabled"],St={key:0,class:"loading loading-spinner loading-xs"},Mt={class:"bg-white rounded-xl shadow-sm border border-slate-100"},Tt={class:"overflow-x-auto"},zt={class:"table table-zebra text-sm"},Ft={key:0},Ot={key:0,class:"badge badge-success badge-xs ml-1"},Pt={class:"text-sm"},jt={class:"text-xs text-slate-400 max-w-xs truncate"},At={class:"flex gap-1"},qt={key:0,class:"text-xs text-slate-400"},Ht=["onClick"],Jt=["onClick"],Wt=ue({__name:"product",setup(Kt){const{webApi:p,uploadFile:A}=pe(),{success:x,error:f,warn:S}=ve(),R={0:"未知",1:"经典蓝牙",2:"BLE双端",3:"BLE单端",4:"录音笔",5:"智能眼镜",6:"激活码卡片"},G={0:"未知",1:"经典蓝牙耳机",2:"BLE双端",3:"BLE单端",4:"智能录音笔",5:"智能眼镜",6:"激活码卡片"},y=[{key:"iscanbindagain",label:"可重复绑定奖励"},{key:"iscontinuouschat",label:"连续对话"},{key:"eqenable",label:"EQ 均衡器"},{key:"keyenable",label:"按键控制"},{key:"workmodeenable",label:"工作模式"},{key:"callmodeenable",label:"通话模式"},{key:"ledenable",label:"LED 灯"},{key:"finddeviceenable",label:"查找设备"},{key:"noisereductionenable",label:"降噪"},{key:"shutdownenable",label:"定时关机"},{key:"showcasebattery",label:"充电盒电量"},{key:"wakeupenable",label:"唤醒控制"},{key:"broadcastpeertranslate",label:"播报对方翻译"},{key:"hideaiassistant",label:"隐藏AI助手"}],w=b("list"),U=b([]),q=b({}),M=b([]),T=b(!1),E=b(!1),_=b(!1);function W(){const l={};return y.forEach(t=>{l[t.key]=!1}),l}const n=P({id:0,devicename:"",brandid:0,devicetype:0,scanuuid:"",devicecodecount:1,productimage:"",channel:"official",bindrewardvpitime:0,bindrewardtranslate:0,bindrewardmeeting:0,toggles:W()}),c=P({platform_id:"",platform_key:"",tui:""});function H(l){return l?Number(l).toString(16).toUpperCase():""}function X(l){return y.filter(t=>!!l[t.key]).length}async function z(){T.value=!0;try{const l=await p("getbrands",{}),t={};(l?.brands??[]).forEach(m=>{t[m.id]=m.brand}),q.value=t;const s=await p("getproducts",{});U.value=s?.products??[]}catch(l){f(l?.message??"获取产品列表失败"),U.value=[]}finally{T.value=!1}}async function Z(){try{const l=await p("getbrands",{});M.value=l?.brands??[]}catch{M.value=[]}}function I(){w.value="list",z()}function J(l){if(Z(),l){_.value=!0,n.id=l.id,n.devicename=l.devicename||"",n.brandid=l.brandid||0,n.devicetype=l.devicetype||0,n.scanuuid=l.scanuuid||"",n.devicecodecount=l.devicecodecount===2?2:1,n.productimage=l.productimage||"",n.channel=l.channel||"official",n.bindrewardvpitime=l.bindrewardvpitime||0,n.bindrewardtranslate=l.bindrewardtranslate||0,n.bindrewardmeeting=l.bindrewardmeeting||0;let t={};try{t=l.channelextra?JSON.parse(l.channelextra):{}}catch{t={}}c.platform_id=t.platform_id||"",c.platform_key=t.platform_key||"",c.tui=t.tui||"",y.forEach(s=>{n.toggles[s.key]=!!l[s.key]})}else _.value=!1,n.id=0,n.devicename="",n.brandid=0,n.devicetype=0,n.scanuuid="",n.devicecodecount=1,n.productimage="",n.channel="official",n.bindrewardvpitime=0,n.bindrewardtranslate=0,n.bindrewardmeeting=0,c.platform_id="",c.platform_key="",c.tui="",y.forEach(t=>{n.toggles[t.key]=!1});w.value="form"}async function ee(){E.value=!0;try{let l="";n.channel==="mobile"&&(l=JSON.stringify({platform_id:c.platform_id||"",platform_key:c.platform_key||"",tui:c.tui||""}));const t={devicename:n.devicename,brandid:Number(n.brandid)||0,devicetype:Number(n.devicetype)||0,scanuuid:n.scanuuid,devicecodecount:Number(n.devicecodecount)||1,productimage:n.productimage,channel:n.channel,channelextra:l,bindrewardvpitime:Number(n.bindrewardvpitime)||0,bindrewardtranslate:Number(n.bindrewardtranslate)||0,bindrewardmeeting:Number(n.bindrewardmeeting)||0};y.forEach(s=>{t[s.key]=n.toggles[s.key]}),_.value&&(t.id=Number(n.id)),await p(_.value?"updateproduct":"addproduct",{product:t}),x("保存成功"),I()}catch(l){f(l?.message??"保存失败")}finally{E.value=!1}}function te(l){window.confirm(`确定删除产品 "${l.devicename}" 吗?`)&&p("delproduct",{id:l.id}).then(()=>{x("已删除"),z()}).catch(t=>f(t?.message??"删除失败"))}const F=b(null),N=b(!1);function se(l){F.value=l.target.files?.[0]??null}async function le(){if(!F.value){S("请先选择图片");return}N.value=!0;try{const l=n.id?`product/${n.id}/images/`:"product/images/",t=await A(F.value,l);n.productimage=t,x("上传成功")}catch(l){f(l?.message??"上传失败")}finally{N.value=!1}}const d=b(null),V=b([]),$=b(!1),u=P({version:"",desc:"",isuse:!1}),k=b(null),ne=be(()=>!!u.version.trim()&&!!k.value);function O(l){return!!d.value?.versionid&&l.id===d.value.versionid}async function oe(l){w.value="version",d.value=null,V.value=[],u.version="",u.desc="",u.isuse=!1,k.value=null;try{const t=await p("getproduct",{id:l.id});d.value=t?.product??l}catch{d.value=l}await D(l.id)}async function D(l){try{const t=await p("getproductversions",{pid:l});V.value=t?.versions??[]}catch{V.value=[]}}function ae(l){k.value=l.target.files?.[0]??null}async function K(l){if(!d.value)return f("产品信息未加载"),!1;const t={...d.value,versionid:l.id};try{await p("updateproduct",{product:t});const s=await p("getproduct",{id:t.id});return d.value=s?.product??t,!0}catch(s){return f(s?.message??"切换失败"),!1}}function ie(l){window.confirm(`确定将版本 "${l.version}" 设为当前使用版本?`)&&K(l).then(t=>{t&&(x("切换成功"),d.value&&D(d.value.id))})}async function de(){const l=d.value?.id;if(!l){f("产品ID不存在");return}if(!u.version.trim()){S("请输入版本号");return}if(!k.value){S("请选择固件文件");return}$.value=!0;try{const t=await A(k.value,`product/${l}/`),s=await p("addproductversion",{version:{productid:l,version:u.version.trim(),description:u.desc,updatepackageaddress:t},isuse:!1});x("添加成功"),u.isuse&&s?.version&&await K(s.version),u.version="",u.desc="",u.isuse=!1,k.value=null,await D(l)}catch(t){f(t?.message??"添加失败")}finally{$.value=!1}}function re(l){if(d.value?.versionid===l.id){f("不能删除当前使用中的版本");return}window.confirm("删除此版本?")&&p("delproductversion",{id:l.id}).then(()=>{x("已删除"),d.value&&D(d.value.id)}).catch(t=>f(t?.message??"删除失败"))}return ce(z),(l,t)=>(a(),o("div",null,[i(e("div",null,[e("div",fe,[t[20]||(t[20]=e("h2",{class:"text-lg font-semibold text-slate-800"},"产品列表",-1)),e("button",{class:"btn btn-primary btn-sm text-white",onClick:t[0]||(t[0]=s=>J())},"+ 新增产品")]),e("div",ge,[e("div",xe,[e("table",ye,[t[24]||(t[24]=e("thead",null,[e("tr",null,[e("th",null,"ID"),e("th",null,"图片"),e("th",null,"名称"),e("th",null,"品牌商"),e("th",null,"类型"),e("th",null,"版本"),e("th",null,"功能"),e("th",null,"操作")])],-1)),e("tbody",null,[T.value?(a(),o("tr",we,[...t[21]||(t[21]=[e("td",{colspan:"8",class:"text-center py-8"},[e("span",{class:"loading loading-spinner loading-sm"})],-1)])])):U.value.length?g("",!0):(a(),o("tr",ke,[...t[22]||(t[22]=[e("td",{colspan:"8",class:"text-center text-slate-400 py-8"},"暂无数据",-1)])])),(a(!0),o(h,null,C(U.value,s=>(a(),o("tr",{key:s.id},[e("td",he,r(H(s.id)),1),e("td",null,[s.productimage?(a(),o("img",{key:0,src:s.productimage,class:"w-10 h-10 rounded object-cover"},null,8,_e)):(a(),o("div",Ve,[...t[23]||(t[23]=[e("svg",{class:"h-5 w-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor"},[e("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"})],-1)])]))]),e("td",Ce,r(s.devicename),1),e("td",null,r(q.value[s.brandid]||""),1),e("td",null,[e("span",Ue,r(R[s.devicetype]||s.devicetype),1)]),e("td",Ee,[s.version?(a(),o("span",Ie,r(s.version),1)):(a(),o("span",Ne,"-"))]),e("td",null,[e("span",$e,r(X(s))+"/14",1)]),e("td",null,[e("div",De,[e("button",{class:"btn btn-ghost btn-xs",onClick:m=>J(s)},"编辑",8,Be),e("button",{class:"btn btn-ghost btn-xs text-indigo-600",onClick:m=>oe(s)},"版本",8,Le),e("button",{class:"btn btn-ghost btn-xs text-red-500",onClick:m=>te(s)},"删除",8,Se)])])]))),128))])])])])],512),[[B,w.value==="list"]]),i(e("div",null,[e("div",Me,[e("button",{class:"btn btn-ghost btn-sm",onClick:t[1]||(t[1]=s=>I())},"← 返回列表"),e("h2",Te,r(_.value?"编辑产品":"新增产品"),1)]),e("div",ze,[e("form",{onSubmit:Y(ee,["prevent"])},[t[43]||(t[43]=e("h3",{class:"text-sm font-semibold text-slate-500 mb-3"},"基本信息",-1)),e("div",Fe,[t[25]||(t[25]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"产品名称 *")],-1)),i(e("input",{"onUpdate:modelValue":t[2]||(t[2]=s=>n.devicename=s),type:"text",class:"input input-bordered w-full",required:""},null,512),[[v,n.devicename]])]),e("div",Oe,[e("div",Pe,[t[27]||(t[27]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"所属品牌商")],-1)),i(e("select",{"onUpdate:modelValue":t[3]||(t[3]=s=>n.brandid=s),class:"select select-bordered w-full"},[t[26]||(t[26]=e("option",{value:0},"请选择",-1)),(a(!0),o(h,null,C(M.value,s=>(a(),o("option",{key:s.id,value:s.id},r(s.brand),9,je))),128))],512),[[L,n.brandid,void 0,{number:!0}]])]),e("div",Ae,[t[28]||(t[28]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"设备类型")],-1)),i(e("select",{"onUpdate:modelValue":t[4]||(t[4]=s=>n.devicetype=s),class:"select select-bordered w-full"},[(a(),o(h,null,C(G,(s,m)=>e("option",{key:m,value:Number(m)},r(s),9,qe)),64))],512),[[L,n.devicetype,void 0,{number:!0}]])])]),e("div",He,[e("div",Je,[t[29]||(t[29]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"扫描UUID")],-1)),i(e("input",{"onUpdate:modelValue":t[5]||(t[5]=s=>n.scanuuid=s),type:"text",class:"input input-bordered w-full"},null,512),[[v,n.scanuuid]])]),e("div",Ke,[t[31]||(t[31]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"设备码数量(每副)")],-1)),i(e("select",{"onUpdate:modelValue":t[6]||(t[6]=s=>n.devicecodecount=s),class:"select select-bordered w-full"},[...t[30]||(t[30]=[e("option",{value:1},"单份 (1个/副)",-1),e("option",{value:2},"双份 (2个/副)",-1)])],512),[[L,n.devicecodecount,void 0,{number:!0}]])])]),e("div",Ye,[e("div",Qe,[t[33]||(t[33]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"渠道方")],-1)),i(e("select",{"onUpdate:modelValue":t[7]||(t[7]=s=>n.channel=s),class:"select select-bordered w-full"},[...t[32]||(t[32]=[e("option",{value:"official"},"官方",-1),e("option",{value:"mobile"},"移动",-1)])],512),[[L,n.channel]])])]),i(e("div",Re,[e("div",Ge,[e("div",We,[t[34]||(t[34]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"移动平台ID")],-1)),i(e("input",{"onUpdate:modelValue":t[8]||(t[8]=s=>c.platform_id=s),type:"text",class:"input input-bordered w-full",placeholder:"移动平台分配的 ID"},null,512),[[v,c.platform_id]])]),e("div",Xe,[t[35]||(t[35]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"移动平台KEY")],-1)),i(e("input",{"onUpdate:modelValue":t[9]||(t[9]=s=>c.platform_key=s),type:"text",class:"input input-bordered w-full",placeholder:"移动平台分配的 KEY"},null,512),[[v,c.platform_key]])]),e("div",Ze,[t[36]||(t[36]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"TUI(8位)")],-1)),i(e("input",{"onUpdate:modelValue":t[10]||(t[10]=s=>c.tui=s),type:"text",maxlength:"8",class:"input input-bordered w-full",placeholder:"CMEI 前缀,如 11113396"},null,512),[[v,c.tui]])])])],512),[[B,n.channel==="mobile"]]),e("div",et,[t[38]||(t[38]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"产品图片")],-1)),e("div",tt,[e("div",st,[i(e("input",{"onUpdate:modelValue":t[11]||(t[11]=s=>n.productimage=s),type:"text",class:"input input-bordered w-full input-sm mb-2",placeholder:"图片URL(可手动输入或上传)"},null,512),[[v,n.productimage]]),e("div",lt,[e("input",{type:"file",accept:"image/*",class:"file-input file-input-bordered file-input-sm flex-1",onChange:se},null,32),e("button",{type:"button",class:"btn btn-outline btn-sm btn-primary",disabled:N.value,onClick:le},[N.value?(a(),o("span",ot)):g("",!0),t[37]||(t[37]=j("上传 ",-1))],8,nt)])]),n.productimage?(a(),o("div",at,[e("img",{src:n.productimage,class:"w-20 h-20 object-cover rounded-lg border"},null,8,it)])):g("",!0)])]),t[44]||(t[44]=e("div",{class:"divider text-sm text-slate-400"},"绑定奖励设置",-1)),e("div",dt,[e("div",rt,[t[39]||(t[39]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"VIP时长(天)")],-1)),i(e("input",{"onUpdate:modelValue":t[12]||(t[12]=s=>n.bindrewardvpitime=s),type:"number",min:"0",class:"input input-bordered w-full"},null,512),[[v,n.bindrewardvpitime,void 0,{number:!0}]])]),e("div",ut,[t[40]||(t[40]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"翻译时长(分钟)")],-1)),i(e("input",{"onUpdate:modelValue":t[13]||(t[13]=s=>n.bindrewardtranslate=s),type:"number",min:"0",class:"input input-bordered w-full"},null,512),[[v,n.bindrewardtranslate,void 0,{number:!0}]])]),e("div",ct,[t[41]||(t[41]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"会议时长(分钟)")],-1)),i(e("input",{"onUpdate:modelValue":t[14]||(t[14]=s=>n.bindrewardmeeting=s),type:"number",min:"0",class:"input input-bordered w-full"},null,512),[[v,n.bindrewardmeeting,void 0,{number:!0}]])])]),t[45]||(t[45]=e("div",{class:"divider text-sm text-slate-400"},"功能开关",-1)),e("div",bt,[(a(),o(h,null,C(y,s=>e("label",{key:s.key,class:"flex items-center gap-2 cursor-pointer"},[i(e("input",{"onUpdate:modelValue":m=>n.toggles[s.key]=m,type:"checkbox",class:"toggle toggle-primary toggle-sm"},null,8,mt),[[Q,n.toggles[s.key]]]),e("span",pt,r(s.label),1)])),64))]),e("div",vt,[e("button",{type:"button",class:"btn btn-ghost",onClick:t[15]||(t[15]=s=>I())},"取消"),e("button",{type:"submit",class:"btn btn-primary text-white",disabled:E.value},[E.value?(a(),o("span",gt)):g("",!0),t[42]||(t[42]=j("保存 ",-1))],8,ft)])],32)])],512),[[B,w.value==="form"]]),i(e("div",null,[e("div",xt,[e("button",{class:"btn btn-ghost btn-sm",onClick:t[16]||(t[16]=s=>I())},"← 返回产品列表"),e("h2",yt,"版本管理 - "+r(d.value?.devicename||""),1)]),d.value?(a(),o("div",wt,[e("div",kt,[t[46]||(t[46]=e("span",{class:"text-slate-400"},"产品ID:",-1)),e("span",ht,r(H(d.value.id)),1),t[47]||(t[47]=e("span",{class:"text-slate-400"},"当前版本:",-1)),e("span",_t,r(d.value.version||"无"),1),t[48]||(t[48]=e("span",{class:"text-slate-400"},"版本ID:",-1)),e("span",Vt,r(d.value.versionid||"无"),1),t[49]||(t[49]=e("span",{class:"text-slate-400"},"更新包:",-1)),e("span",Ct,r(d.value.updatepackageaddress||"无"),1)])])):g("",!0),e("div",Ut,[t[55]||(t[55]=e("h3",{class:"text-sm font-semibold text-slate-700 mb-3"},"添加新版本",-1)),e("form",{onSubmit:Y(de,["prevent"])},[e("div",Et,[e("div",It,[t[50]||(t[50]=e("label",{class:"label"},[e("span",{class:"label-text text-xs"},"版本号 *")],-1)),i(e("input",{"onUpdate:modelValue":t[17]||(t[17]=s=>u.version=s),type:"text",class:"input input-bordered input-sm w-full",placeholder:"如 1.2.0"},null,512),[[v,u.version]])]),e("div",Nt,[t[51]||(t[51]=e("label",{class:"label"},[e("span",{class:"label-text text-xs"},"描述")],-1)),i(e("input",{"onUpdate:modelValue":t[18]||(t[18]=s=>u.desc=s),type:"text",class:"input input-bordered input-sm w-full",placeholder:"版本描述"},null,512),[[v,u.desc]])])]),e("div",$t,[t[52]||(t[52]=e("label",{class:"label"},[e("span",{class:"label-text text-xs"},"OTA 更新包 *")],-1)),e("input",{type:"file",class:"file-input file-input-bordered file-input-sm w-full",accept:".bin,.hex,.zip,.gz,.tar,.ota,.ufw,.fot",onChange:ae},null,32)]),e("div",Dt,[e("label",Bt,[i(e("input",{"onUpdate:modelValue":t[19]||(t[19]=s=>u.isuse=s),type:"checkbox",class:"checkbox checkbox-primary checkbox-sm"},null,512),[[Q,u.isuse]]),t[53]||(t[53]=e("span",{class:"text-sm"},"设为当前使用版本",-1))]),e("button",{type:"submit",class:"btn btn-primary btn-sm text-white ml-auto",disabled:!ne.value||$.value},[$.value?(a(),o("span",St)):g("",!0),t[54]||(t[54]=j("添加版本 ",-1))],8,Lt)])],32)]),e("div",Mt,[e("div",Tt,[e("table",zt,[t[57]||(t[57]=e("thead",null,[e("tr",null,[e("th",null,"ID"),e("th",null,"版本号"),e("th",null,"描述"),e("th",null,"更新包地址"),e("th",null,"操作")])],-1)),e("tbody",null,[V.value.length?g("",!0):(a(),o("tr",Ft,[...t[56]||(t[56]=[e("td",{colspan:"5",class:"text-center text-slate-400 py-8"},"暂无版本",-1)])])),(a(!0),o(h,null,C(V.value,s=>(a(),o("tr",{key:s.id},[e("td",null,r(s.id),1),e("td",null,[e("span",{class:me(["badge badge-sm",O(s)?"badge-primary":"badge-outline"])},r(s.version),3),O(s)?(a(),o("span",Ot,"当前")):g("",!0)]),e("td",Pt,r(s.description||""),1),e("td",jt,r(s.updatepackageaddress||""),1),e("td",null,[e("div",At,[O(s)?(a(),o("span",qt,"使用中")):(a(),o(h,{key:1},[e("button",{class:"btn btn-ghost btn-xs text-indigo-600",onClick:m=>ie(s)},"设为当前",8,Ht),e("button",{class:"btn btn-ghost btn-xs text-red-500",onClick:m=>re(s)},"删除",8,Jt)],64))])])]))),128))])])])])],512),[[B,w.value==="version"]])]))}});export{Wt as default}; +import{g as ue,y as P,B as ce,c as o,p as i,H as B,a as e,l as g,F as h,r as C,t as r,m as Y,v,q as L,d as j,s as Q,x as b,z as be,o as a,n as me}from"./mElhLwm2.js";import{u as pe}from"./C6twYRfy.js";import{u as ve}from"./FVTAbpot.js";import"./qig5Qp6S.js";const fe={class:"flex items-center justify-between mb-5"},ge={class:"bg-white rounded-xl shadow-sm border border-slate-100"},xe={class:"overflow-x-auto"},ye={class:"table table-zebra text-sm"},we={key:0},ke={key:1},he={class:"font-mono text-sm"},_e=["src"],Ve={key:1,class:"w-10 h-10 rounded bg-slate-100 flex items-center justify-center text-slate-300"},Ce={class:"font-medium"},Ue={class:"badge badge-outline badge-sm"},Ee={class:"text-sm"},Ie={key:0},Ne={key:1,class:"text-slate-300"},$e={class:"text-xs text-slate-500"},De={class:"flex gap-1"},Be=["onClick"],Le=["onClick"],Se=["onClick"],Me={class:"flex items-center gap-3 mb-5"},Te={class:"text-lg font-semibold text-slate-800"},ze={class:"bg-white rounded-xl shadow-sm border border-slate-100 p-6 max-w-3xl"},Fe={class:"form-control mb-4"},Oe={class:"grid grid-cols-2 gap-4 mb-4"},Pe={class:"form-control"},je=["value"],Ae={class:"form-control"},qe=["value"],He={class:"grid grid-cols-2 gap-4 mb-4"},Je={class:"form-control"},Ke={class:"form-control"},Ye={class:"grid grid-cols-2 gap-4 mb-4"},Qe={class:"form-control"},Re={class:"mb-4"},Ge={class:"grid grid-cols-3 gap-4"},We={class:"form-control"},Xe={class:"form-control"},Ze={class:"form-control"},et={class:"form-control mb-4"},tt={class:"flex items-start gap-4"},st={class:"flex-1"},lt={class:"flex items-center gap-2"},nt=["disabled"],ot={key:0,class:"loading loading-spinner loading-xs"},at={key:0},it=["src"],dt={class:"grid grid-cols-3 gap-4 mb-4"},rt={class:"form-control"},ut={class:"form-control"},ct={class:"form-control"},bt={class:"grid grid-cols-3 gap-3 mb-6"},mt=["onUpdate:modelValue"],pt={class:"text-sm"},vt={class:"flex gap-3"},ft=["disabled"],gt={key:0,class:"loading loading-spinner loading-xs"},xt={class:"flex items-center gap-3 mb-5"},yt={class:"text-lg font-semibold text-slate-800"},wt={key:0,class:"bg-white rounded-xl shadow-sm border border-slate-100 p-4 mb-5"},kt={class:"flex items-center gap-6 text-sm flex-wrap"},ht={class:"font-mono"},_t={class:"badge badge-primary badge-sm"},Vt={class:"text-xs"},Ct={class:"text-xs max-w-md truncate"},Ut={class:"bg-white rounded-xl shadow-sm border border-slate-100 p-5 mb-5"},Et={class:"grid grid-cols-2 gap-4 mb-3"},It={class:"form-control"},Nt={class:"form-control"},$t={class:"form-control mb-3"},Dt={class:"flex items-center gap-3"},Bt={class:"flex items-center gap-2 cursor-pointer"},Lt=["disabled"],St={key:0,class:"loading loading-spinner loading-xs"},Mt={class:"bg-white rounded-xl shadow-sm border border-slate-100"},Tt={class:"overflow-x-auto"},zt={class:"table table-zebra text-sm"},Ft={key:0},Ot={key:0,class:"badge badge-success badge-xs ml-1"},Pt={class:"text-sm"},jt={class:"text-xs text-slate-400 max-w-xs truncate"},At={class:"flex gap-1"},qt={key:0,class:"text-xs text-slate-400"},Ht=["onClick"],Jt=["onClick"],Wt=ue({__name:"product",setup(Kt){const{webApi:p,uploadFile:A}=pe(),{success:x,error:f,warn:S}=ve(),R={0:"未知",1:"经典蓝牙",2:"BLE双端",3:"BLE单端",4:"录音笔",5:"智能眼镜",6:"激活码卡片"},G={0:"未知",1:"经典蓝牙耳机",2:"BLE双端",3:"BLE单端",4:"智能录音笔",5:"智能眼镜",6:"激活码卡片"},y=[{key:"iscanbindagain",label:"可重复绑定奖励"},{key:"iscontinuouschat",label:"连续对话"},{key:"eqenable",label:"EQ 均衡器"},{key:"keyenable",label:"按键控制"},{key:"workmodeenable",label:"工作模式"},{key:"callmodeenable",label:"通话模式"},{key:"ledenable",label:"LED 灯"},{key:"finddeviceenable",label:"查找设备"},{key:"noisereductionenable",label:"降噪"},{key:"shutdownenable",label:"定时关机"},{key:"showcasebattery",label:"充电盒电量"},{key:"wakeupenable",label:"唤醒控制"},{key:"broadcastpeertranslate",label:"播报对方翻译"},{key:"hideaiassistant",label:"隐藏AI助手"}],w=b("list"),U=b([]),q=b({}),M=b([]),T=b(!1),E=b(!1),_=b(!1);function W(){const l={};return y.forEach(t=>{l[t.key]=!1}),l}const n=P({id:0,devicename:"",brandid:0,devicetype:0,scanuuid:"",devicecodecount:1,productimage:"",channel:"official",bindrewardvpitime:0,bindrewardtranslate:0,bindrewardmeeting:0,toggles:W()}),c=P({platform_id:"",platform_key:"",tui:""});function H(l){return l?Number(l).toString(16).toUpperCase():""}function X(l){return y.filter(t=>!!l[t.key]).length}async function z(){T.value=!0;try{const l=await p("getbrands",{}),t={};(l?.brands??[]).forEach(m=>{t[m.id]=m.brand}),q.value=t;const s=await p("getproducts",{});U.value=s?.products??[]}catch(l){f(l?.message??"获取产品列表失败"),U.value=[]}finally{T.value=!1}}async function Z(){try{const l=await p("getbrands",{});M.value=l?.brands??[]}catch{M.value=[]}}function I(){w.value="list",z()}function J(l){if(Z(),l){_.value=!0,n.id=l.id,n.devicename=l.devicename||"",n.brandid=l.brandid||0,n.devicetype=l.devicetype||0,n.scanuuid=l.scanuuid||"",n.devicecodecount=l.devicecodecount===2?2:1,n.productimage=l.productimage||"",n.channel=l.channel||"official",n.bindrewardvpitime=l.bindrewardvpitime||0,n.bindrewardtranslate=l.bindrewardtranslate||0,n.bindrewardmeeting=l.bindrewardmeeting||0;let t={};try{t=l.channelextra?JSON.parse(l.channelextra):{}}catch{t={}}c.platform_id=t.platform_id||"",c.platform_key=t.platform_key||"",c.tui=t.tui||"",y.forEach(s=>{n.toggles[s.key]=!!l[s.key]})}else _.value=!1,n.id=0,n.devicename="",n.brandid=0,n.devicetype=0,n.scanuuid="",n.devicecodecount=1,n.productimage="",n.channel="official",n.bindrewardvpitime=0,n.bindrewardtranslate=0,n.bindrewardmeeting=0,c.platform_id="",c.platform_key="",c.tui="",y.forEach(t=>{n.toggles[t.key]=!1});w.value="form"}async function ee(){E.value=!0;try{let l="";n.channel==="mobile"&&(l=JSON.stringify({platform_id:c.platform_id||"",platform_key:c.platform_key||"",tui:c.tui||""}));const t={devicename:n.devicename,brandid:Number(n.brandid)||0,devicetype:Number(n.devicetype)||0,scanuuid:n.scanuuid,devicecodecount:Number(n.devicecodecount)||1,productimage:n.productimage,channel:n.channel,channelextra:l,bindrewardvpitime:Number(n.bindrewardvpitime)||0,bindrewardtranslate:Number(n.bindrewardtranslate)||0,bindrewardmeeting:Number(n.bindrewardmeeting)||0};y.forEach(s=>{t[s.key]=n.toggles[s.key]}),_.value&&(t.id=Number(n.id)),await p(_.value?"updateproduct":"addproduct",{product:t}),x("保存成功"),I()}catch(l){f(l?.message??"保存失败")}finally{E.value=!1}}function te(l){window.confirm(`确定删除产品 "${l.devicename}" 吗?`)&&p("delproduct",{id:l.id}).then(()=>{x("已删除"),z()}).catch(t=>f(t?.message??"删除失败"))}const F=b(null),N=b(!1);function se(l){F.value=l.target.files?.[0]??null}async function le(){if(!F.value){S("请先选择图片");return}N.value=!0;try{const l=n.id?`product/${n.id}/images/`:"product/images/",t=await A(F.value,l);n.productimage=t,x("上传成功")}catch(l){f(l?.message??"上传失败")}finally{N.value=!1}}const d=b(null),V=b([]),$=b(!1),u=P({version:"",desc:"",isuse:!1}),k=b(null),ne=be(()=>!!u.version.trim()&&!!k.value);function O(l){return!!d.value?.versionid&&l.id===d.value.versionid}async function oe(l){w.value="version",d.value=null,V.value=[],u.version="",u.desc="",u.isuse=!1,k.value=null;try{const t=await p("getproduct",{id:l.id});d.value=t?.product??l}catch{d.value=l}await D(l.id)}async function D(l){try{const t=await p("getproductversions",{pid:l});V.value=t?.versions??[]}catch{V.value=[]}}function ae(l){k.value=l.target.files?.[0]??null}async function K(l){if(!d.value)return f("产品信息未加载"),!1;const t={...d.value,versionid:l.id};try{await p("updateproduct",{product:t});const s=await p("getproduct",{id:t.id});return d.value=s?.product??t,!0}catch(s){return f(s?.message??"切换失败"),!1}}function ie(l){window.confirm(`确定将版本 "${l.version}" 设为当前使用版本?`)&&K(l).then(t=>{t&&(x("切换成功"),d.value&&D(d.value.id))})}async function de(){const l=d.value?.id;if(!l){f("产品ID不存在");return}if(!u.version.trim()){S("请输入版本号");return}if(!k.value){S("请选择固件文件");return}$.value=!0;try{const t=await A(k.value,`product/${l}/`),s=await p("addproductversion",{version:{productid:l,version:u.version.trim(),description:u.desc,updatepackageaddress:t},isuse:!1});x("添加成功"),u.isuse&&s?.version&&await K(s.version),u.version="",u.desc="",u.isuse=!1,k.value=null,await D(l)}catch(t){f(t?.message??"添加失败")}finally{$.value=!1}}function re(l){if(d.value?.versionid===l.id){f("不能删除当前使用中的版本");return}window.confirm("删除此版本?")&&p("delproductversion",{id:l.id}).then(()=>{x("已删除"),d.value&&D(d.value.id)}).catch(t=>f(t?.message??"删除失败"))}return ce(z),(l,t)=>(a(),o("div",null,[i(e("div",null,[e("div",fe,[t[20]||(t[20]=e("h2",{class:"text-lg font-semibold text-slate-800"},"产品列表",-1)),e("button",{class:"btn btn-primary btn-sm text-white",onClick:t[0]||(t[0]=s=>J())},"+ 新增产品")]),e("div",ge,[e("div",xe,[e("table",ye,[t[24]||(t[24]=e("thead",null,[e("tr",null,[e("th",null,"ID"),e("th",null,"图片"),e("th",null,"名称"),e("th",null,"品牌商"),e("th",null,"类型"),e("th",null,"版本"),e("th",null,"功能"),e("th",null,"操作")])],-1)),e("tbody",null,[T.value?(a(),o("tr",we,[...t[21]||(t[21]=[e("td",{colspan:"8",class:"text-center py-8"},[e("span",{class:"loading loading-spinner loading-sm"})],-1)])])):U.value.length?g("",!0):(a(),o("tr",ke,[...t[22]||(t[22]=[e("td",{colspan:"8",class:"text-center text-slate-400 py-8"},"暂无数据",-1)])])),(a(!0),o(h,null,C(U.value,s=>(a(),o("tr",{key:s.id},[e("td",he,r(H(s.id)),1),e("td",null,[s.productimage?(a(),o("img",{key:0,src:s.productimage,class:"w-10 h-10 rounded object-cover"},null,8,_e)):(a(),o("div",Ve,[...t[23]||(t[23]=[e("svg",{class:"h-5 w-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor"},[e("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"})],-1)])]))]),e("td",Ce,r(s.devicename),1),e("td",null,r(q.value[s.brandid]||""),1),e("td",null,[e("span",Ue,r(R[s.devicetype]||s.devicetype),1)]),e("td",Ee,[s.version?(a(),o("span",Ie,r(s.version),1)):(a(),o("span",Ne,"-"))]),e("td",null,[e("span",$e,r(X(s))+"/14",1)]),e("td",null,[e("div",De,[e("button",{class:"btn btn-ghost btn-xs",onClick:m=>J(s)},"编辑",8,Be),e("button",{class:"btn btn-ghost btn-xs text-indigo-600",onClick:m=>oe(s)},"版本",8,Le),e("button",{class:"btn btn-ghost btn-xs text-red-500",onClick:m=>te(s)},"删除",8,Se)])])]))),128))])])])])],512),[[B,w.value==="list"]]),i(e("div",null,[e("div",Me,[e("button",{class:"btn btn-ghost btn-sm",onClick:t[1]||(t[1]=s=>I())},"← 返回列表"),e("h2",Te,r(_.value?"编辑产品":"新增产品"),1)]),e("div",ze,[e("form",{onSubmit:Y(ee,["prevent"])},[t[43]||(t[43]=e("h3",{class:"text-sm font-semibold text-slate-500 mb-3"},"基本信息",-1)),e("div",Fe,[t[25]||(t[25]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"产品名称 *")],-1)),i(e("input",{"onUpdate:modelValue":t[2]||(t[2]=s=>n.devicename=s),type:"text",class:"input input-bordered w-full",required:""},null,512),[[v,n.devicename]])]),e("div",Oe,[e("div",Pe,[t[27]||(t[27]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"所属品牌商")],-1)),i(e("select",{"onUpdate:modelValue":t[3]||(t[3]=s=>n.brandid=s),class:"select select-bordered w-full"},[t[26]||(t[26]=e("option",{value:0},"请选择",-1)),(a(!0),o(h,null,C(M.value,s=>(a(),o("option",{key:s.id,value:s.id},r(s.brand),9,je))),128))],512),[[L,n.brandid,void 0,{number:!0}]])]),e("div",Ae,[t[28]||(t[28]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"设备类型")],-1)),i(e("select",{"onUpdate:modelValue":t[4]||(t[4]=s=>n.devicetype=s),class:"select select-bordered w-full"},[(a(),o(h,null,C(G,(s,m)=>e("option",{key:m,value:Number(m)},r(s),9,qe)),64))],512),[[L,n.devicetype,void 0,{number:!0}]])])]),e("div",He,[e("div",Je,[t[29]||(t[29]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"扫描UUID")],-1)),i(e("input",{"onUpdate:modelValue":t[5]||(t[5]=s=>n.scanuuid=s),type:"text",class:"input input-bordered w-full"},null,512),[[v,n.scanuuid]])]),e("div",Ke,[t[31]||(t[31]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"设备码数量(每副)")],-1)),i(e("select",{"onUpdate:modelValue":t[6]||(t[6]=s=>n.devicecodecount=s),class:"select select-bordered w-full"},[...t[30]||(t[30]=[e("option",{value:1},"单份 (1个/副)",-1),e("option",{value:2},"双份 (2个/副)",-1)])],512),[[L,n.devicecodecount,void 0,{number:!0}]])])]),e("div",Ye,[e("div",Qe,[t[33]||(t[33]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"渠道方")],-1)),i(e("select",{"onUpdate:modelValue":t[7]||(t[7]=s=>n.channel=s),class:"select select-bordered w-full"},[...t[32]||(t[32]=[e("option",{value:"official"},"官方",-1),e("option",{value:"mobile"},"移动",-1)])],512),[[L,n.channel]])])]),i(e("div",Re,[e("div",Ge,[e("div",We,[t[34]||(t[34]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"移动平台ID")],-1)),i(e("input",{"onUpdate:modelValue":t[8]||(t[8]=s=>c.platform_id=s),type:"text",class:"input input-bordered w-full",placeholder:"移动平台分配的 ID"},null,512),[[v,c.platform_id]])]),e("div",Xe,[t[35]||(t[35]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"移动平台KEY")],-1)),i(e("input",{"onUpdate:modelValue":t[9]||(t[9]=s=>c.platform_key=s),type:"text",class:"input input-bordered w-full",placeholder:"移动平台分配的 KEY"},null,512),[[v,c.platform_key]])]),e("div",Ze,[t[36]||(t[36]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"TUI(8位)")],-1)),i(e("input",{"onUpdate:modelValue":t[10]||(t[10]=s=>c.tui=s),type:"text",maxlength:"8",class:"input input-bordered w-full",placeholder:"CMEI 前缀,如 11113396"},null,512),[[v,c.tui]])])])],512),[[B,n.channel==="mobile"]]),e("div",et,[t[38]||(t[38]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"产品图片")],-1)),e("div",tt,[e("div",st,[i(e("input",{"onUpdate:modelValue":t[11]||(t[11]=s=>n.productimage=s),type:"text",class:"input input-bordered w-full input-sm mb-2",placeholder:"图片URL(可手动输入或上传)"},null,512),[[v,n.productimage]]),e("div",lt,[e("input",{type:"file",accept:"image/*",class:"file-input file-input-bordered file-input-sm flex-1",onChange:se},null,32),e("button",{type:"button",class:"btn btn-outline btn-sm btn-primary",disabled:N.value,onClick:le},[N.value?(a(),o("span",ot)):g("",!0),t[37]||(t[37]=j("上传 ",-1))],8,nt)])]),n.productimage?(a(),o("div",at,[e("img",{src:n.productimage,class:"w-20 h-20 object-cover rounded-lg border"},null,8,it)])):g("",!0)])]),t[44]||(t[44]=e("div",{class:"divider text-sm text-slate-400"},"绑定奖励设置",-1)),e("div",dt,[e("div",rt,[t[39]||(t[39]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"VIP时长(天)")],-1)),i(e("input",{"onUpdate:modelValue":t[12]||(t[12]=s=>n.bindrewardvpitime=s),type:"number",min:"0",class:"input input-bordered w-full"},null,512),[[v,n.bindrewardvpitime,void 0,{number:!0}]])]),e("div",ut,[t[40]||(t[40]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"翻译时长(分钟)")],-1)),i(e("input",{"onUpdate:modelValue":t[13]||(t[13]=s=>n.bindrewardtranslate=s),type:"number",min:"0",class:"input input-bordered w-full"},null,512),[[v,n.bindrewardtranslate,void 0,{number:!0}]])]),e("div",ct,[t[41]||(t[41]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"会议时长(分钟)")],-1)),i(e("input",{"onUpdate:modelValue":t[14]||(t[14]=s=>n.bindrewardmeeting=s),type:"number",min:"0",class:"input input-bordered w-full"},null,512),[[v,n.bindrewardmeeting,void 0,{number:!0}]])])]),t[45]||(t[45]=e("div",{class:"divider text-sm text-slate-400"},"功能开关",-1)),e("div",bt,[(a(),o(h,null,C(y,s=>e("label",{key:s.key,class:"flex items-center gap-2 cursor-pointer"},[i(e("input",{"onUpdate:modelValue":m=>n.toggles[s.key]=m,type:"checkbox",class:"toggle toggle-primary toggle-sm"},null,8,mt),[[Q,n.toggles[s.key]]]),e("span",pt,r(s.label),1)])),64))]),e("div",vt,[e("button",{type:"button",class:"btn btn-ghost",onClick:t[15]||(t[15]=s=>I())},"取消"),e("button",{type:"submit",class:"btn btn-primary text-white",disabled:E.value},[E.value?(a(),o("span",gt)):g("",!0),t[42]||(t[42]=j("保存 ",-1))],8,ft)])],32)])],512),[[B,w.value==="form"]]),i(e("div",null,[e("div",xt,[e("button",{class:"btn btn-ghost btn-sm",onClick:t[16]||(t[16]=s=>I())},"← 返回产品列表"),e("h2",yt,"版本管理 - "+r(d.value?.devicename||""),1)]),d.value?(a(),o("div",wt,[e("div",kt,[t[46]||(t[46]=e("span",{class:"text-slate-400"},"产品ID:",-1)),e("span",ht,r(H(d.value.id)),1),t[47]||(t[47]=e("span",{class:"text-slate-400"},"当前版本:",-1)),e("span",_t,r(d.value.version||"无"),1),t[48]||(t[48]=e("span",{class:"text-slate-400"},"版本ID:",-1)),e("span",Vt,r(d.value.versionid||"无"),1),t[49]||(t[49]=e("span",{class:"text-slate-400"},"更新包:",-1)),e("span",Ct,r(d.value.updatepackageaddress||"无"),1)])])):g("",!0),e("div",Ut,[t[55]||(t[55]=e("h3",{class:"text-sm font-semibold text-slate-700 mb-3"},"添加新版本",-1)),e("form",{onSubmit:Y(de,["prevent"])},[e("div",Et,[e("div",It,[t[50]||(t[50]=e("label",{class:"label"},[e("span",{class:"label-text text-xs"},"版本号 *")],-1)),i(e("input",{"onUpdate:modelValue":t[17]||(t[17]=s=>u.version=s),type:"text",class:"input input-bordered input-sm w-full",placeholder:"如 1.2.0"},null,512),[[v,u.version]])]),e("div",Nt,[t[51]||(t[51]=e("label",{class:"label"},[e("span",{class:"label-text text-xs"},"描述")],-1)),i(e("input",{"onUpdate:modelValue":t[18]||(t[18]=s=>u.desc=s),type:"text",class:"input input-bordered input-sm w-full",placeholder:"版本描述"},null,512),[[v,u.desc]])])]),e("div",$t,[t[52]||(t[52]=e("label",{class:"label"},[e("span",{class:"label-text text-xs"},"OTA 更新包 *")],-1)),e("input",{type:"file",class:"file-input file-input-bordered file-input-sm w-full",accept:".bin,.hex,.zip,.gz,.tar,.ota,.ufw,.fot",onChange:ae},null,32)]),e("div",Dt,[e("label",Bt,[i(e("input",{"onUpdate:modelValue":t[19]||(t[19]=s=>u.isuse=s),type:"checkbox",class:"checkbox checkbox-primary checkbox-sm"},null,512),[[Q,u.isuse]]),t[53]||(t[53]=e("span",{class:"text-sm"},"设为当前使用版本",-1))]),e("button",{type:"submit",class:"btn btn-primary btn-sm text-white ml-auto",disabled:!ne.value||$.value},[$.value?(a(),o("span",St)):g("",!0),t[54]||(t[54]=j("添加版本 ",-1))],8,Lt)])],32)]),e("div",Mt,[e("div",Tt,[e("table",zt,[t[57]||(t[57]=e("thead",null,[e("tr",null,[e("th",null,"ID"),e("th",null,"版本号"),e("th",null,"描述"),e("th",null,"更新包地址"),e("th",null,"操作")])],-1)),e("tbody",null,[V.value.length?g("",!0):(a(),o("tr",Ft,[...t[56]||(t[56]=[e("td",{colspan:"5",class:"text-center text-slate-400 py-8"},"暂无版本",-1)])])),(a(!0),o(h,null,C(V.value,s=>(a(),o("tr",{key:s.id},[e("td",null,r(s.id),1),e("td",null,[e("span",{class:me(["badge badge-sm",O(s)?"badge-primary":"badge-outline"])},r(s.version),3),O(s)?(a(),o("span",Ot,"当前")):g("",!0)]),e("td",Pt,r(s.description||""),1),e("td",jt,r(s.updatepackageaddress||""),1),e("td",null,[e("div",At,[O(s)?(a(),o("span",qt,"使用中")):(a(),o(h,{key:1},[e("button",{class:"btn btn-ghost btn-xs text-indigo-600",onClick:m=>ie(s)},"设为当前",8,Ht),e("button",{class:"btn btn-ghost btn-xs text-red-500",onClick:m=>re(s)},"删除",8,Jt)],64))])])]))),128))])])])])],512),[[B,w.value==="version"]])]))}});export{Wt as default}; diff --git a/apps/admin/.output/public/_nuxt/C_VX9uKy.js b/apps/admin/.output/public/_nuxt/C_VX9uKy.js new file mode 100644 index 00000000..65a2ba10 --- /dev/null +++ b/apps/admin/.output/public/_nuxt/C_VX9uKy.js @@ -0,0 +1 @@ +import{_ as Lt}from"./DuRQSWLc.js";import{u as it}from"./C6twYRfy.js";import{h as Nt,R as $t,a as Rt}from"./PN667bHc.js";import{g as ct,B as dt,o,c as l,a as s,t as r,l as F,G as Ot,b as K,w as lt,d as I,F as b,r as g,n as G,x as v,z as h,_ as ut,j as Vt,p as J,q as Z,y as rt,L as H}from"./mElhLwm2.js";import"./qig5Qp6S.js";const Tt={class:"ab-head"},qt={class:"ab-ico"},zt={class:"ab-title"},It={key:0,class:"ab-sub"},Ht={class:"ab-sub"},Gt={key:0,class:"ab-list"},Ut={class:"ab-name"},jt={key:0,class:"ab-chip"},Pt={class:"ab-chip ab-chip-scope"},Yt={class:"ab-msg"},Wt={key:1,class:"ab-streak"},Jt={key:0,class:"ab-more"},Zt=12,Kt=ct({__name:"SvcAlertBanner",setup(_t,{expose:C}){const{webApi:N}=it(),w=v([]),p=v(0),y=v(0),A=v(0),k=v(!1),x=v(!1),E=h(()=>Nt(A.value));function U(c){const m=c.app_name?c.app_name:"全局";return c.region?`${m} · ${$t[c.region]||"区域"+c.region}`:m}function $(c){return Rt(c)}async function M(){try{const c=await N("getsvcalerts",{limit:Zt});w.value=c.alerts||[],p.value=c.error_count||0,y.value=c.warn_count||0,A.value=c.last_run||0,x.value=p.value+y.value>w.value.length,k.value=p.value>0}catch{w.value=[],p.value=0,y.value=0}}return dt(M),C({load:M}),(c,m)=>{const R=Lt;return p.value+y.value>0?(o(),l("div",{key:0,class:G(["alert-banner",p.value>0?"lv-error":"lv-warn"])},[s("div",Tt,[s("span",qt,r(p.value>0?"🚨":"⚠️"),1),s("div",zt,[s("strong",null,r(p.value>0?`${p.value} 项第三方服务不可用`:`${y.value} 项第三方服务存在隐患`),1),p.value>0&&y.value>0?(o(),l("span",It,",另有 "+r(y.value)+" 项隐患",1)):F("",!0),s("span",Ht," · 最近巡检 "+r(Ot(E)),1)]),s("button",{class:"ab-btn",onClick:m[0]||(m[0]=d=>k.value=!k.value)},r(k.value?"收起":"展开详情"),1),K(R,{to:"/svcinspect",class:"ab-btn ab-btn-primary"},{default:lt(()=>[...m[1]||(m[1]=[I("前往巡检",-1)])]),_:1})]),k.value?(o(),l("div",Gt,[(o(!0),l(b,null,g(w.value,d=>(o(),l("div",{key:`${d.app_name}/${d.svc_id}/${d.region}`,class:"ab-item"},[s("span",{class:G(["ab-dot",d.status==="error"?"d-error":"d-warn"])},null,2),s("span",Ut,r(d.name||d.svc_id),1),d.provider?(o(),l("span",jt,r(d.provider),1)):F("",!0),s("span",Pt,r(U(d)),1),s("span",Yt,r($(d)),1),d.fail_streak>1?(o(),l("span",Wt,"连续失败 "+r(d.fail_streak)+" 次",1)):F("",!0)]))),128)),x.value?(o(),l("div",Jt,[I(" 仅显示前 "+r(w.value.length)+" 条,其余请到",1),K(R,{to:"/svcinspect",class:"ab-link"},{default:lt(()=>[...m[2]||(m[2]=[I("服务巡检",-1)])]),_:1}),m[3]||(m[3]=I("查看 ",-1))])):F("",!0)])):F("",!0)],2)):F("",!0)}}}),Qt=Object.assign(ut(Kt,[["__scopeId","data-v-3dd2fb7c"]]),{__name:"SvcAlertBanner"}),Xt={class:"panel p-4 mb-5"},te={class:"flex flex-wrap items-end gap-3"},ee={class:"form-control"},se=["value"],ae={class:"form-control"},ne=["value"],oe={class:"form-control"},le=["value"],re={class:"grid grid-cols-2 md:grid-cols-4 gap-3 mb-8"},ie={class:"body"},ce={class:"lbl"},de={class:"val"},ue={class:"today-wrap mb-8"},_e={class:"sec-title hero",style:{"margin-bottom":"16px"}},ve={class:"tag",style:{color:"#0369a1",background:"#dbeafe"}},pe={class:"grid grid-cols-2 md:grid-cols-4 gap-4"},me={class:"today-card-top"},fe={class:"lbl"},ye={class:"val"},be={class:"foot"},ge={key:0,class:"delta up"},he={class:"grid grid-cols-1 xl:grid-cols-2 gap-6"},ke={class:"panel-head"},Ee=["stroke"],Fe=["d"],we={class:"font-semibold text-slate-700 text-sm"},xe={key:0,class:"ml-auto text-xs text-slate-400"},Ce={key:1,class:"ml-auto flex items-center gap-1"},De=["onClick"],Ae={class:"px-5 py-4"},Me={class:"grid grid-cols-2 sm:grid-cols-3 gap-2.5"},Se={class:"stat-label"},Be={class:"stat-val"},Le={key:0,style:{height:"170px","margin-top":"1rem"}},Ne=ct({__name:"dashboard",setup(_t){const C=Vt(),{webApi:N,consoleApi:w}=it(),p=[["cn","中国"],["us","美国"],["ea","东亚"],["sea","东南亚"],["sa","南亚"],["me","中东"],["eu","欧洲"],["ru","俄罗斯"],["af","非洲"],["sam","南美"],["nam","北美"],["oc","大洋洲"],["br","巴西"],["in","印度"]],y={new_user_count:["👥","#EEF2FF","#6366F1"],active_user_count:["🟢","#ECFDF5","#10B981"],bind_device_count:["📱","#E0F2FE","#0EA5E9"],qr_active_count:["🔳","#FCE7F3","#EC4899"],order_paid_count:["🧾","#FEF3C7","#F59E0B"],order_paid_amount:["💰","#FEE2E2","#EF4444"],pay_user_count:["⭐","#FFF7ED","#F97316"],meet_second:["🎙️","#CFFAFE","#22D3EE"],trade_second:["🌐","#F3E8FF","#8B5CF6"]},A=[["new_user_count","累计用户",!1],["bind_device_count","累计绑定设备",!1],["qr_active_count","累计二维码激活",!1],["order_paid_count","累计支付订单",!1],["order_paid_amount","累计支付金额",!0],["meet_second","累计会议时长",!1],["trade_second","累计翻译时长",!1]],k=[["new_user_count","新增用户",!1],["active_user_count","活跃用户",!1],["qr_active_count","二维码激活",!1],["order_paid_count","支付订单",!1],["order_paid_amount","支付金额",!0],["pay_user_count","付费用户",!1],["meet_second","会议时长",!1,!0],["trade_second","翻译时长",!1,!0]],x=[{key:"user",title:"用户增长",color:"#6366F1",tint:"#EEF2FF",icon:"M17 20h5v-2a4 4 0 00-3-3.87M9 20H4v-2a4 4 0 013-3.87m6-1.13a4 4 0 10-4-4 4 4 0 004 4z",stats:[["new_user_count","新增用户"],["active_user_count","活跃用户"],["login_user_count","登录用户"],["login_count","登录次数"]],lines:[["new_user_count","新增用户","#6366F1"],["active_user_count","活跃用户","#34D399"]]},{key:"device",title:"设备激活绑定",color:"#0EA5E9",tint:"#E0F2FE",icon:"M12 18h.01M8 21h8a2 2 0 002-2V5a2 2 0 00-2-2H8a2 2 0 00-2 2v14a2 2 0 002 2z",stats:[["active_device_count","已激活"],["bind_device_count","已绑定"]],lines:[["active_device_count","已激活","#0EA5E9"],["bind_device_count","已绑定","#818CF8"]]},{key:"qrcode",title:"二维码激活",color:"#EC4899",tint:"#FCE7F3",icon:"M12 4v1m6 11h2m-6 0h-1v4m-6-4H5m14 0h-2m-6-7H5m0 0V5m0 4v6m14-6V5h-4M5 5h4M5 19h4m6 0h4v-4M4 4h6v6H4V4zm10 0h6v6h-6V4zM4 14h6v6H4v-6z",stats:[["qr_active_count","二维码激活次数"]],lines:[["qr_active_count","二维码激活","#EC4899"]]},{key:"order",title:"订单支付",color:"#F59E0B",tint:"#FEF3C7",icon:"M3 3h2l.4 2M7 13h10l4-8H5.4M7 13L5.4 5M7 13l-2.293 2.293c-.63.63-.184 1.707.707 1.707H17m0 0a2 2 0 100 4 2 2 0 000-4zm-8 2a2 2 0 11-4 0 2 2 0 014 0z",stats:[["order_create_count","创建订单"],["order_paid_count","支付订单"],["order_failed_count","失败订单"],["pay_user_count","付费用户"],["order_paid_amount","支付金额",!0],["order_create_amount","创建金额",!0]],lines:[["order_paid_count","支付订单","#F59E0B"],["order_create_count","创建订单","#FCD34D"]]},{key:"meeting",title:"会议",color:"#22D3EE",tint:"#CFFAFE",icon:"M15 10l4.553-2.276A1 1 0 0121 8.618v6.764a1 1 0 01-1.447.894L15 14M5 18h8a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v8a2 2 0 002 2z",stats:[["meet_count","会议次数"],["meet_second","会议时长",!1,!0],["grant_meet_second","发放会议时长",!1,!0]],lines:[["meet_count","会议次数","#22D3EE"],["meet_second","会议时长(秒)","#0EA5E9"]]},{key:"translate",title:"翻译",color:"#8B5CF6",tint:"#F3E8FF",icon:"M3 5h12M9 3v2m1.048 9.5A18.022 18.022 0 016.412 9m6.088 9h7M11 21l5-10 5 10M12.751 5C11.783 10.77 8.07 15.61 3 18.129",stats:[["trade_count","翻译次数"],["trade_second","翻译时长",!1,!0],["trade_words","翻译字数"],["grant_trade_second","发放翻译时长",!1,!0]],lines:[["trade_count","翻译次数","#8B5CF6"],["trade_second","翻译时长(秒)","#A78BFA"]]}],E=h(()=>C.identity===3),U=h(()=>C.apps),$=h(()=>C.regions),M=h(()=>C.products.map(t=>parseInt(t)).filter(t=>!isNaN(t))),c=["new_user_count","active_user_count","qr_active_count"],m=h(()=>E.value?A.filter(t=>!c.includes(t[0])):A),R=h(()=>E.value?k.filter(t=>!c.includes(t[0])):k),d=h(()=>E.value?x.filter(t=>t.key!=="user"&&t.key!=="qrcode"):x),vt=[[7,"7天"],[30,"30天"],[90,"90天"],[0,"全部"]],u=rt({app:"",region:"",product:""}),O=v([]),j=v([]),pt=h(()=>E.value&&$.value.length?p.filter(t=>$.value.includes(t[0])).map(t=>({value:t[0],label:t[1]})):p.map(t=>({value:t[0],label:t[1]}))),Q=v({}),X=v({}),P=v({}),tt=v({}),et=v("实时"),Y=v({}),V=rt({});x.forEach(t=>{V[t.key]=30});function T(t){const e=t.getFullYear(),n=("0"+(t.getMonth()+1)).slice(-2),a=("0"+t.getDate()).slice(-2);return parseInt(e+n+a)}function mt(t){if(!t)return{start:0,end:0};const e=new Date,n=new Date;return n.setDate(n.getDate()-(t-1)),{start:T(n),end:T(e)}}function ft(t,e){return t=Number(t)||0,e?"¥"+(t/100).toLocaleString(void 0,{minimumFractionDigits:2,maximumFractionDigits:2}):t.toLocaleString()}function yt(t){t=Math.max(0,Math.floor(Number(t)||0));const e=Math.floor(t/3600),n=Math.floor(t%3600/60),a=t%60;return e>0?e+"时"+n+"分":n>0?n+"分"+a+"秒":a+"秒"}function W(t,e,n){return n?yt(t):ft(t,e)}function bt(t){const e=String(t);return e.length===8?e.slice(4,6)+"-"+e.slice(6,8):e}function gt(t,e){return t=Number(t)||0,e=Number(e)||0,e===0?t>0?null:0:(t-e)/e*100}function S(t){return y[t]||["📊","#f1f5f9","#94a3b8"]}function ht(t){const e=t[0]==="bind_device_count"||t[0]==="active_device_count"?X.value:Q.value,n=t[0]==="meet_second"||t[0]==="trade_second";return W(e[t[0]],t[2],n)}function kt(t){return W(P.value[t[0]],t[2],!!t[3])}function B(t){const e=gt(P.value[t[0]],tt.value[t[0]]);if(e===null)return{type:"new",arrow:"",abs:""};const n=e>0?"up":e<0?"down":"flat",a=e>0?"▲":e<0?"▼":"—";return{type:n,arrow:a,abs:Math.abs(e).toFixed(1)}}function Et(t,e){return W((Y.value[t.key]||{})[e[0]],e[2],e[3])}function q(){const t={};return u.app!==""&&(t.app_id=u.app),u.region!==""&&(t.region=u.region),u.product!==""&&(t.product_id=parseInt(String(u.product))),t}function st(){const t={};return u.product!==""&&(t.product_id=parseInt(String(u.product))),t}async function D(t,e){try{return{code:0,data:await N(t,e)??{}}}catch{return null}}async function Ft(){const t=await D("getstatssummary",q());Q.value=t&&t.code===0&&t.data?t.data:{};const e=await D("getstatssummary",st());X.value=e&&e.code===0&&e.data?e.data:{}}async function wt(){const t=T(new Date),e=new Date;e.setDate(e.getDate()-1);const n=T(e),a=q();a.start_day=t,a.end_day=t;const i=q();i.start_day=n,i.end_day=n;const f=await D("getstatssummary",a);P.value=f&&f.code===0&&f.data?f.data:{};const _=await D("getstatssummary",i);tt.value=_&&_.code===0&&_.data?_.data:{};const z=new Date,St=("0"+(z.getMonth()+1)).slice(-2),Bt=("0"+z.getDate()).slice(-2);et.value=St+"-"+Bt+" 实时"}async function at(t){let e;if(t.key==="device")e=st();else{const _=mt(V[t.key]);e=q(),e.start_day=_.start,e.end_day=_.end}const n=await D("getstatssummary",e),a=n&&n.code===0&&n.data?n.data:{};if(Y.value={...Y.value,[t.key]:a},t.key==="device")return;const i=await D("getstatstrend",e),f=i&&i.code===0?i.data||[]:[];Dt(t,f)}function xt(t,e){V[t]=e;const n=x.find(a=>a.key===t);n&&at(n)}function nt(){Ft(),wt(),d.value.forEach(t=>at(t))}const ot={},L={};function Ct(t,e){e&&(ot[t]=e)}function Dt(t,e){const n=window.Chart,a=ot[t.key];if(!n||!a)return;const i=e.map(_=>bt(_.stat_day)),f=t.lines.map(_=>({label:_[1],data:e.map(z=>Number(z[_[0]])||0),borderColor:_[2],backgroundColor:_[2]+"22",tension:.35,fill:!0,pointRadius:0,borderWidth:2}));if(L[t.key]){L[t.key].data.labels=i,L[t.key].data.datasets=f,L[t.key].update();return}L[t.key]=new n(a,{type:"line",data:{labels:i,datasets:f},options:{responsive:!0,maintainAspectRatio:!1,plugins:{legend:{position:"bottom",labels:{boxWidth:10,padding:12,font:{size:11}}}},scales:{x:{ticks:{maxTicksLimit:8,font:{size:10},color:"#94a3b8"},grid:{display:!1}},y:{beginAtZero:!0,ticks:{precision:0,maxTicksLimit:5,font:{size:10},color:"#94a3b8"},grid:{color:"#f1f5f9"}}},interaction:{mode:"index",intersect:!1}}})}async function At(){if(E.value)O.value=U.value.map(t=>({value:t,label:t}));else try{const t=await w("apps/list",{}),e=Array.isArray(t)?t:[];O.value=e.map(n=>({value:n.name||"",label:n.name||"应用#"+n.id}))}catch{O.value=[]}try{const t=await N("getproducts",{});let e=t&&t.products?t.products:[];E.value&&M.value.length&&(e=e.filter(n=>M.value.includes(n.id))),j.value=e.map(n=>({value:n.id,label:(n.devicename||"产品#"+n.id)+" (#"+n.id+")"}))}catch{j.value=[]}}function Mt(){return new Promise(t=>{if(window.Chart)return t();const e=document.createElement("script");e.src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.min.js",e.onload=()=>t(),e.onerror=()=>t(),document.head.appendChild(e)})}return dt(async()=>{await Mt(),await At(),nt()}),(t,e)=>{const n=Qt;return o(),l("div",null,[K(n),s("div",Xt,[s("div",te,[s("div",ee,[e[4]||(e[4]=s("label",{class:"label py-1"},[s("span",{class:"label-text text-xs text-slate-500"},"应用")],-1)),J(s("select",{"onUpdate:modelValue":e[0]||(e[0]=a=>u.app=a),class:"select select-bordered select-sm w-40"},[e[3]||(e[3]=s("option",{value:""},"全部应用",-1)),(o(!0),l(b,null,g(O.value,a=>(o(),l("option",{key:a.value,value:a.value},r(a.label),9,se))),128))],512),[[Z,u.app]])]),s("div",ae,[e[6]||(e[6]=s("label",{class:"label py-1"},[s("span",{class:"label-text text-xs text-slate-500"},"区域")],-1)),J(s("select",{"onUpdate:modelValue":e[1]||(e[1]=a=>u.region=a),class:"select select-bordered select-sm w-32"},[e[5]||(e[5]=s("option",{value:""},"全部区域",-1)),(o(!0),l(b,null,g(pt.value,a=>(o(),l("option",{key:a.value,value:a.value},r(a.label),9,ne))),128))],512),[[Z,u.region]])]),s("div",oe,[e[8]||(e[8]=s("label",{class:"label py-1"},[s("span",{class:"label-text text-xs text-slate-500"},"产品")],-1)),J(s("select",{"onUpdate:modelValue":e[2]||(e[2]=a=>u.product=a),class:"select select-bordered select-sm w-48"},[e[7]||(e[7]=s("option",{value:""},"全部产品",-1)),(o(!0),l(b,null,g(j.value,a=>(o(),l("option",{key:a.value,value:a.value},r(a.label),9,le))),128))],512),[[Z,u.product]])]),s("button",{class:"btn btn-primary btn-sm text-white",onClick:nt},"查询"),e[9]||(e[9]=s("span",{class:"text-xs text-slate-400 ml-auto self-center"},"顶部为全量总览;各版面右上角可单独选时间周期",-1))])]),e[14]||(e[14]=s("div",{class:"sec-title muted"},[s("span",{class:"bar",style:{background:"#cbd5e1"}}),s("h2",null,"累计数据"),s("span",{class:"sub"},"全量累计 · 随筛选条件变化")],-1)),s("div",re,[(o(!0),l(b,null,g(m.value,a=>(o(),l("div",{key:a[0],class:"cum-card"},[s("span",{class:"ico",style:H({background:S(a[0])[1]})},r(S(a[0])[0]),5),s("div",ie,[s("div",ce,r(a[1]),1),s("div",de,r(ht(a)),1)])]))),128))]),s("div",ue,[s("div",_e,[e[10]||(e[10]=s("span",{class:"bar",style:{background:"linear-gradient(180deg,#0EA5E9,#22D3EE)"}},null,-1)),e[11]||(e[11]=s("h2",null,"今日数据",-1)),s("span",ve,r(et.value),1),e[12]||(e[12]=s("span",{class:"sub"},"今日 0 点至现在 · 含较昨日同比(设备类无日期维度,仅见累计)",-1))]),s("div",pe,[(o(!0),l(b,null,g(R.value,a=>(o(),l("div",{key:a[0],class:"today-card"},[s("span",{class:"accent",style:H({background:S(a[0])[2]})},null,4),s("div",me,[s("span",fe,r(a[1]),1),s("span",{class:"ico",style:H({background:S(a[0])[1]})},r(S(a[0])[0]),5)]),s("div",ye,r(kt(a)),1),s("div",be,[B(a).type==="new"?(o(),l("span",ge,"新")):B(a).type!=="none"?(o(),l("span",{key:1,class:G(["delta",B(a).type])},r(B(a).arrow)+" "+r(B(a).abs)+"%",3)):F("",!0),e[13]||(e[13]=s("span",null,"较昨日",-1))])]))),128))])]),e[15]||(e[15]=s("div",{class:"sec-title"},[s("span",{class:"bar",style:{background:"linear-gradient(180deg,#10B981,#22D3EE)"}}),s("h2",null,"趋势分析"),s("span",{class:"sub"},"各版面右上角可独立选择时间周期")],-1)),s("div",he,[(o(!0),l(b,null,g(d.value,a=>(o(),l("div",{key:a.key,class:"panel"},[s("div",ke,[s("span",{class:"panel-dot",style:H({background:a.tint})},[(o(),l("svg",{width:"17",height:"17",fill:"none",viewBox:"0 0 24 24",stroke:a.color},[s("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:a.icon},null,8,Fe)],8,Ee))],4),s("span",we,r(a.title),1),a.key==="device"?(o(),l("span",xe,"当前累计 · 无日期维度")):(o(),l("div",Ce,[(o(),l(b,null,g(vt,i=>s("button",{key:i[0],class:G(["tbtn",{"tbtn-on":i[0]===V[a.key]}]),onClick:f=>xt(a.key,Number(i[0]))},r(i[1]),11,De)),64))]))]),s("div",Ae,[s("div",Me,[(o(!0),l(b,null,g(a.stats,i=>(o(),l("div",{key:i[0],class:"stat-box"},[s("div",Se,r(i[1]),1),s("div",Be,r(Et(a,i)),1)]))),128))]),a.key!=="device"?(o(),l("div",Le,[s("canvas",{ref_for:!0,ref:i=>Ct(a.key,i)},null,512)])):F("",!0)])]))),128))])])}}}),qe=ut(Ne,[["__scopeId","data-v-0c034b8c"]]);export{qe as default}; diff --git a/apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/BgemqguF.js b/apps/admin/.output/public/_nuxt/CcYro5R2.js similarity index 99% rename from apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/BgemqguF.js rename to apps/admin/.output/public/_nuxt/CcYro5R2.js index 06e7e8f3..81ea5f57 100644 --- a/apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/BgemqguF.js +++ b/apps/admin/.output/public/_nuxt/CcYro5R2.js @@ -1 +1 @@ -import{g as Ce,B as $e,c as n,a as e,d,p as N,q as K,F as c,r as V,t as i,l as f,G as Ne,v as de,s as ce,x as _,y as ue,z as E,o as a,n as y,_ as Ve}from"./Ccu6Xgpt.js";import{u as Ae}from"./Um-KoueI.js";import{u as Ue}from"./DvwKXRUn.js";import{L as re}from"./ChQPCk92.js";import"./CH2ZVAK2.js";const Le={class:"scopebar"},Me={class:"flex items-center gap-2"},Se=["value"],De=["value"],Oe={class:"text-[11px] text-slate-400"},Be={key:0,class:"bg-white rounded-xl border border-slate-100 py-16 text-center"},Ee={key:0,class:"alert alert-warning py-2 text-sm mb-4"},Te={class:"card"},je={class:"card-head"},ze={class:"flex gap-2 shrink-0"},Fe=["disabled"],Ge=["disabled"],He={class:"probe-bar"},Ie=["value"],Ke={key:0,class:"probe-out"},Pe={key:1,class:"probe-out bad"},Re={key:0,class:"py-10 text-center text-slate-400 text-sm"},We={class:"min-w-0"},Xe={class:"svc-prov"},qe={class:"flex flex-wrap gap-1"},Je={key:0,class:"lang"},Qe={key:1,class:"text-[11px] text-slate-400"},Ye={class:"svc-cost"},Ze={key:1,class:"text-slate-300"},et=["checked","disabled","onChange"],tt={class:"svc-acts"},st=["disabled","onClick"],lt=["disabled","onClick"],nt=["onClick"],at=["onClick"],it={class:"card mt-4"},ot={class:"card-head"},dt={class:"flex gap-2 shrink-0"},ct=["disabled"],ut=["disabled"],rt={key:0,class:"py-10 text-center text-slate-400 text-sm"},vt={class:"min-w-0"},bt={class:"svc-name"},_t={class:"svc-prov"},pt={class:"svc-cost"},mt={key:1,class:"text-slate-300"},gt=["checked","disabled","onChange"],ht={class:"svc-acts"},ft=["disabled","onClick"],kt=["disabled","onClick"],xt=["onClick"],yt=["onClick"],wt={class:"card mt-4"},Ct={class:"card-head"},$t=["disabled"],Nt={class:"mode-bar"},Vt={class:"flex items-center gap-2 cursor-pointer shrink-0"},At=["checked","disabled"],Ut={class:"mode-txt"},Lt={key:0,class:"py-10 text-center text-slate-400 text-sm"},Mt={class:"grid place-items-center"},St=["checked","disabled","onChange"],Dt={class:"min-w-0"},Ot={class:"svc-name"},Bt={key:0,title:"多媒体大模型,能识图"},Et={key:1,class:"chip chip-app ml-1"},Tt={class:"svc-prov"},jt={class:"svc-cost"},zt={key:1,class:"text-slate-300"},Ft=["checked","disabled","title","onChange"],Gt=["checked","disabled","onChange"],Ht={class:"svc-acts"},It=["onClick"],Kt=["onClick"],Pt={class:"modal-box max-w-md"},Rt={class:"font-bold text-lg"},Wt={class:"mt-4 space-y-3"},Xt={class:"form-control"},qt=["value"],Jt={key:0,class:"text-[11px] text-amber-600 mt-1"},Qt={class:"form-control"},Yt={class:"label py-1"},Zt={class:"label-text text-sm font-medium"},es={key:0,class:"flex gap-4"},ts={class:"flex items-center gap-2 cursor-pointer"},ss={class:"flex items-center gap-2 cursor-pointer"},ls={class:"modal-action"},ns=["disabled"],as={class:"modal-box max-w-sm"},is={class:"text-xs text-slate-400 mt-1"},os={class:"modal-action"},ds=["disabled"],cs=Ce({__name:"meetingsvc",setup(us){const{webApi:S,consoleApi:ve}=Ae(),{success:P,error:A}=Ue(),se=[{value:1,label:"中国"},{value:2,label:"美国"},{value:3,label:"东亚"},{value:4,label:"东南亚"},{value:5,label:"南亚"},{value:6,label:"中东"},{value:7,label:"欧洲"},{value:8,label:"俄罗斯"},{value:9,label:"非洲"},{value:10,label:"南美"},{value:11,label:"北美"},{value:12,label:"大洋洲"},{value:13,label:"巴西"},{value:14,label:"印度"}];function be(l){return se.find(t=>t.value===l)?.label??"区域"+l}const R=_([]),w=_(""),C=_(0),D=_([]),T=_([]),W=_({1:[8],2:[3],3:[5,9]}),U=_(!1),le=_(!1),X=_(!1),L=_(!1),r=_(!1),m=_("zh-CN"),j=_(null),z=_(null),g=_(1),v=ue({svc_id:"",cost_hint:0,is_default:!1,client_visible:!1}),k=ue({row_id:0,name:"",kind:1,cost_hint:0});function _e(l){return l===1?"识别":l===2?"翻译":"总结"}function ne(l){return l===1?"元/小时":l===2?"元/百万字符":"元/百万token"}function q(l){return re.find(t=>t.code===l)?.name??l}function ae(l,t){return(l||"").split(",").map(s=>Number(s.trim())).includes(t)}const F=E(()=>{const l=new Map;for(const t of T.value)l.set(t.id,t);return l});function x(l){return F.value.get(l)?.name??l}function J(l){return F.value.get(l)?.provider??"?"}function M(l){return F.value.get(l)?.languages??""}function pe(l){return ae(F.value.get(l)?.categories??"",9)}function b(l){return D.value.filter(t=>t.kind===l).sort((t,s)=>t.priority-s.priority)}function O(l){const t=W.value[String(l)]??[],s=new Set(D.value.filter(o=>o.kind===l).map(o=>o.svc_id));return T.value.filter(o=>!s.has(o.id)&&o.categories.split(",").some(u=>t.includes(Number(u.trim()))))}function G(l,t){const s=M(l);return s?s.split(",").map(o=>o.trim()).includes(t):!0}const h=E(()=>b(1).find(l=>l.enabled&&G(l.svc_id,m.value))??null),$=E(()=>b(2).find(l=>l.enabled)??null);function me(l){return h.value?.row_id!==l.row_id&&(!l.enabled||!G(l.svc_id,m.value))}function ge(l){return h.value?.row_id===l.row_id?"ok":!l.enabled||!G(l.svc_id,m.value)?"no":""}function he(l){return h.value?.row_id===l.row_id?M(l.svc_id)?`✓ 当前源语言(${q(m.value)})由它承接`:"✓ 未限定语言,先落到它(实际支持由引擎判断)":l.enabled?G(l.svc_id,m.value)?"备用:前面都跳过时接手":`不支持 ${q(m.value)}(${m.value}),跳过 → 顺延下一个`:"已停用,跳过"}const H=E(()=>b(3).find(l=>l.is_default)??null),Q=E(()=>b(3).filter(l=>l.enabled&&l.client_visible));async function fe(){try{const l=await ve("products/list",{});R.value=(l??[]).map(t=>t.name).filter(Boolean)}catch{R.value=[]}}async function p(){X.value=!0;try{const l=await S("getechoorch",{app_name:w.value,region:C.value});D.value=l?.items??[],T.value=l?.available??[],W.value=l?.kind_cats??W.value,U.value=!!l?.setting?.llm_client_choice,le.value=(!!w.value||C.value!==0)&&(D.value.length>0||U.value)}catch(l){A(l?.message??"加载失败")}finally{X.value=!1}}async function Y(l){await S("saveechoorch",{app_name:w.value,region:C.value,orch:l})}function Z(l){g.value=l,v.svc_id="",v.cost_hint=0,v.is_default=!1,v.client_visible=!1,j.value?.showModal()}async function ke(){if(v.svc_id){L.value=!0;try{const l=b(g.value),t=l.length?l[l.length-1].priority+10:10;await Y({kind:g.value,svc_id:v.svc_id,priority:t,cost_hint:Number(v.cost_hint)||0,is_default:g.value===3?v.is_default:!1,client_visible:g.value===3?v.client_visible:!1,enabled:!0}),P("已添加"),j.value?.close(),await p()}catch(l){A(l?.message??"添加失败")}finally{L.value=!1}}}async function B(l,t){r.value=!0;try{await Y({...l,...t}),await p()}catch(s){A(s?.message??"操作失败"),await p()}finally{r.value=!1}}async function ee(l){if(confirm(`从本段移除「${x(l.svc_id)}」?(不影响第三方服务配置里的服务本身)`))try{await S("delechoorch",{row_id:l.row_id}),P("已移除"),await p()}catch(t){A(t?.message??"移除失败")}}async function ie(l){r.value=!0;try{await S("reorderechoorch",{items:l.map((t,s)=>({row_id:t.row_id,priority:(s+1)*10}))}),await p()}catch(t){A(t?.message??"排序失败"),await p()}finally{r.value=!1}}function I(l,t,s){const o=[...b(l)],u=t+s;if(u<0||u>=o.length)return;const we=o[t];o[t]=o[u],o[u]=we,ie(o)}function oe(l){const t=[...b(l)].sort((s,o)=>s.enabled!==o.enabled?s.enabled?-1:1:(s.cost_hint||Number.MAX_VALUE)-(o.cost_hint||Number.MAX_VALUE));ie(t)}function te(l){k.row_id=l.row_id,k.name=x(l.svc_id),k.kind=l.kind,k.cost_hint=l.cost_hint,z.value?.showModal()}async function xe(){const l=D.value.find(t=>t.row_id===k.row_id);if(l){L.value=!0;try{await Y({...l,cost_hint:Number(k.cost_hint)||0}),P("已保存"),z.value?.close(),await p()}catch(t){A(t?.message??"保存失败")}finally{L.value=!1}}}async function ye(){r.value=!0;try{await S("saveechoorchsetting",{app_name:w.value,region:C.value,llm_client_choice:!U.value}),await p()}catch(l){A(l?.message??"保存失败"),await p()}finally{r.value=!1}}return $e(async()=>{await fe(),await p()}),(l,t)=>(a(),n("div",null,[t[44]||(t[44]=e("div",{class:"flex items-start justify-between mb-4 flex-wrap gap-3"},[e("div",null,[e("h2",{class:"text-lg font-semibold text-slate-800"},"会议记录服务"),e("p",{class:"text-xs text-slate-400 mt-1 max-w-3xl"},[d(" 识别 / 翻译 / 总结三段,从"),e("b",null,"第三方服务配置"),d("里选已配好的服务来编排(不再单独填凭据)。 "),e("span",{class:"text-slate-500"},"先配「全局默认」作兜底,再按应用 / 区域覆盖"),d("——没配覆盖的应用自动继承全局默认。 ")])])],-1)),e("div",Le,[e("div",Me,[t[17]||(t[17]=e("span",{class:"text-xs text-slate-500 font-semibold"},"作用域",-1)),N(e("select",{"onUpdate:modelValue":t[0]||(t[0]=s=>w.value=s),class:"select select-bordered select-sm",onChange:p},[t[15]||(t[15]=e("option",{value:""},"全局默认(兜底)",-1)),(a(!0),n(c,null,V(R.value,s=>(a(),n("option",{key:s,value:s},"应用:"+i(s),9,Se))),128))],544),[[K,w.value]]),N(e("select",{"onUpdate:modelValue":t[1]||(t[1]=s=>C.value=s),class:"select select-bordered select-sm",onChange:p},[t[16]||(t[16]=e("option",{value:0},"全区域",-1)),(a(),n(c,null,V(se,s=>e("option",{key:s.value,value:s.value},i(s.label),9,De)),64))],544),[[K,C.value,void 0,{number:!0}]])]),e("span",Oe,[d(i(w.value?`正在编辑「${w.value}」`:"正在编辑全局默认")+i(C.value?` · ${be(C.value)}`:" · 全区域")+" ",1),le.value?(a(),n(c,{key:0},[d("(覆盖全局默认)")],64)):f("",!0)])]),X.value?(a(),n("div",Be,[...t[18]||(t[18]=[e("span",{class:"loading loading-spinner loading-sm"},null,-1)])])):(a(),n(c,{key:1},[T.value.length?f("",!0):(a(),n("div",Ee,[...t[19]||(t[19]=[e("span",null,[d(" 该作用域没有可选服务。先去"),e("b",null,"第三方服务配置"),d("添加「录音文件识别 / 机器翻译 / 文本或多媒体大模型」类的服务 (全局默认或该应用作用域),这里才能选。 ")],-1)])])),e("div",Te,[e("div",je,[t[20]||(t[20]=e("div",null,[e("div",{class:"card-title"},"识别(录音文件转写)"),e("div",{class:"card-desc"},[d("按顺序找"),e("b",null,"第一个「已启用 + 支持源语言」"),d('的服务,不支持则跳到下一个。把便宜的排前面即"优先用性价比高的"。')])],-1)),e("div",ze,[e("button",{class:"btn btn-xs",disabled:b(1).length<2||r.value,onClick:t[2]||(t[2]=s=>oe(1))},"⇅ 按参考单价重排",8,Fe),e("button",{class:"btn btn-primary btn-xs text-white",disabled:!O(1).length,onClick:t[3]||(t[3]=s=>Z(1))},"+ 添加识别服务",8,Ge)])]),e("div",He,[t[21]||(t[21]=e("span",{class:"text-xs text-slate-500 font-semibold"},"选路预览",-1)),N(e("select",{"onUpdate:modelValue":t[4]||(t[4]=s=>m.value=s),class:"select select-bordered select-xs w-44 text-xs"},[(a(!0),n(c,null,V(Ne(re),s=>(a(),n("option",{key:s.code,value:s.code},i(s.code)+" · "+i(s.name),9,Ie))),128))],512),[[K,m.value]]),h.value?(a(),n("span",Ke,[d("命中 "+i(x(h.value.svc_id)),1),h.value.cost_hint?(a(),n(c,{key:0},[d(" · ¥"+i(h.value.cost_hint)+"/时",1)],64)):f("",!0)])):(a(),n("span",Pe,"无可用服务 —— "+i(q(m.value))+" 会转写失败",1))]),b(1).length?f("",!0):(a(),n("div",Re,"暂无识别服务,点右上「+ 添加识别服务」")),(a(!0),n(c,null,V(b(1),(s,o)=>(a(),n("div",{key:s.row_id,class:y(["svc asr",{hit:h.value&&h.value.row_id===s.row_id,off:!s.enabled}])},[e("div",{class:y(["svc-rank",{hit:h.value&&h.value.row_id===s.row_id}])},i(o+1),3),e("div",We,[e("div",{class:y(["svc-name",{skip:me(s)}])},i(x(s.svc_id)),3),e("div",Xe,i(J(s.svc_id))+" · "+i(s.svc_id),1)]),e("div",qe,[M(s.svc_id)?(a(),n(c,{key:0},[(a(!0),n(c,null,V(M(s.svc_id).split(",").slice(0,5),u=>(a(),n("span",{key:u,class:y(["lang",{on:u===m.value}])},i(u),3))),128)),M(s.svc_id).split(",").length>5?(a(),n("span",Je,"+"+i(M(s.svc_id).split(",").length-5),1)):f("",!0)],64)):(a(),n("span",Qe,"未限定"))]),e("div",Ye,[s.cost_hint?(a(),n(c,{key:0},[d("¥"+i(s.cost_hint),1),t[22]||(t[22]=e("small",null," /时",-1))],64)):(a(),n("span",Ze,"—"))]),e("div",null,[e("input",{type:"checkbox",class:"toggle toggle-success toggle-sm",checked:s.enabled,disabled:r.value,onChange:u=>B(s,{enabled:!s.enabled})},null,40,et)]),e("div",tt,[e("button",{class:"arrow",disabled:o===0||r.value,"aria-label":"上移",onClick:u=>I(1,o,-1)},"↑",8,st),e("button",{class:"arrow",disabled:o===b(1).length-1||r.value,"aria-label":"下移",onClick:u=>I(1,o,1)},"↓",8,lt),e("button",{class:"btn btn-ghost btn-xs",onClick:u=>te(s)},"单价",8,nt),e("button",{class:"btn btn-ghost btn-xs text-red-500",onClick:u=>ee(s)},"移除",8,at)]),e("div",{class:y(["svc-why",ge(s)])},i(he(s)),3)],2))),128))]),e("div",it,[e("div",ot,[t[23]||(t[23]=e("div",null,[e("div",{class:"card-title"},"翻译"),e("div",{class:"card-desc"},[d("按顺序取"),e("b",null,"第一个已启用"),d("的服务;调用失败自动回退下一个。")])],-1)),e("div",dt,[e("button",{class:"btn btn-xs",disabled:b(2).length<2||r.value,onClick:t[5]||(t[5]=s=>oe(2))},"⇅ 按参考单价重排",8,ct),e("button",{class:"btn btn-primary btn-xs text-white",disabled:!O(2).length,onClick:t[6]||(t[6]=s=>Z(2))},"+ 添加翻译服务",8,ut)])]),b(2).length?f("",!0):(a(),n("div",rt,"暂无翻译服务")),(a(!0),n(c,null,V(b(2),(s,o)=>(a(),n("div",{key:s.row_id,class:y(["svc mt",{hit:$.value&&$.value.row_id===s.row_id,off:!s.enabled}])},[e("div",{class:y(["svc-rank",{hit:$.value&&$.value.row_id===s.row_id}])},i(o+1),3),e("div",vt,[e("div",bt,i(x(s.svc_id)),1),e("div",_t,i(J(s.svc_id))+" · "+i(s.svc_id),1)]),e("div",pt,[s.cost_hint?(a(),n(c,{key:0},[d("¥"+i(s.cost_hint),1),t[24]||(t[24]=e("small",null," /百万字符",-1))],64)):(a(),n("span",mt,"—"))]),e("div",null,[e("input",{type:"checkbox",class:"toggle toggle-success toggle-sm",checked:s.enabled,disabled:r.value,onChange:u=>B(s,{enabled:!s.enabled})},null,40,gt)]),e("div",ht,[e("button",{class:"arrow",disabled:o===0||r.value,"aria-label":"上移",onClick:u=>I(2,o,-1)},"↑",8,ft),e("button",{class:"arrow",disabled:o===b(2).length-1||r.value,"aria-label":"下移",onClick:u=>I(2,o,1)},"↓",8,kt),e("button",{class:"btn btn-ghost btn-xs",onClick:u=>te(s)},"单价",8,xt),e("button",{class:"btn btn-ghost btn-xs text-red-500",onClick:u=>ee(s)},"移除",8,yt)]),e("div",{class:y(["svc-why",s.enabled?$.value&&$.value.row_id===s.row_id?"ok":"":"no"])},[s.enabled?$.value&&$.value.row_id===s.row_id?(a(),n(c,{key:1},[d("✓ 默认由它承接,失败顺延")],64)):(a(),n(c,{key:2},[d("备用:前面失败时接手")],64)):(a(),n(c,{key:0},[d("已停用,跳过")],64))],2)],2))),128))]),e("div",wt,[e("div",Ct,[t[25]||(t[25]=e("div",null,[e("div",{class:"card-title"},"总结(大模型)"),e("div",{class:"card-desc"},[d("后台指定默认模型,客户端可在允许范围内自选。带 🖼 的是"),e("b",null,"多媒体大模型"),d(",能识别会议里的图片。")])],-1)),e("button",{class:"btn btn-primary btn-xs text-white shrink-0",disabled:!O(3).length,onClick:t[7]||(t[7]=s=>Z(3))},"+ 添加模型",8,$t)]),e("div",Nt,[e("label",Vt,[e("input",{type:"checkbox",class:"toggle toggle-primary toggle-sm",checked:U.value,disabled:r.value,onChange:ye},null,40,At),t[26]||(t[26]=e("span",{class:"text-sm font-semibold text-slate-700"},"允许客户端指定模型",-1))]),e("p",Ut,[U.value?(a(),n(c,{key:0},[t[27]||(t[27]=d(" 前端能选 ",-1)),e("b",null,i(Q.value.length),1),t[28]||(t[28]=d(" 个模型",-1)),Q.value.length?(a(),n(c,{key:0},[d(":"+i(Q.value.map(s=>x(s.svc_id)).join("、")),1)],64)):(a(),n(c,{key:1},[d("(一个都没勾「前端可见」,等同强制默认)")],64)),t[29]||(t[29]=d("。不传则用默认 ",-1)),e("b",null,i(H.value?x(H.value.svc_id):"—"),1),t[30]||(t[30]=d("。 ",-1))],64)):(a(),n(c,{key:1},[t[31]||(t[31]=d(" 前端不下发模型列表,一律走默认模型 ",-1)),e("b",null,i(H.value?x(H.value.svc_id):"—"),1),t[32]||(t[32]=d(";客户端传了也忽略。 ",-1))],64))])]),b(3).length?f("",!0):(a(),n("div",Lt,"暂无模型")),(a(!0),n(c,null,V(b(3),s=>(a(),n("div",{key:s.row_id,class:y(["svc llm",{isdefault:s.is_default,off:!s.enabled}])},[e("div",Mt,[e("input",{type:"radio",name:"llmdef",class:"radio radio-primary radio-xs",checked:s.is_default,disabled:!s.enabled||r.value,onChange:o=>B(s,{is_default:!0})},null,40,St)]),e("div",Dt,[e("div",Ot,[d(i(x(s.svc_id))+" ",1),pe(s.svc_id)?(a(),n("span",Bt,"🖼")):f("",!0),s.is_default?(a(),n("span",Et,"默认")):f("",!0)]),e("div",Tt,i(J(s.svc_id))+" · "+i(s.svc_id),1)]),e("div",jt,[s.cost_hint?(a(),n(c,{key:0},[d("¥"+i(s.cost_hint),1),t[33]||(t[33]=e("small",null," /百万token",-1))],64)):(a(),n("span",zt,"—"))]),e("div",null,[e("input",{type:"checkbox",class:"toggle toggle-success toggle-sm",checked:s.client_visible,disabled:!U.value||!s.enabled||r.value,title:U.value?"":"先打开「允许客户端指定模型」",onChange:o=>B(s,{client_visible:!s.client_visible})},null,40,Ft)]),e("div",null,[e("input",{type:"checkbox",class:"toggle toggle-success toggle-sm",checked:s.enabled,disabled:r.value,onChange:o=>B(s,{enabled:!s.enabled})},null,40,Gt)]),e("div",Ht,[e("button",{class:"btn btn-ghost btn-xs",onClick:o=>te(s)},"单价",8,It),e("button",{class:"btn btn-ghost btn-xs text-red-500",onClick:o=>ee(s)},"移除",8,Kt)])],2))),128)),t[34]||(t[34]=e("div",{class:"col-h llm-h"},[e("div"),e("div"),e("div",null,"参考单价"),e("div",null,"前端可见"),e("div",null,"启用"),e("div")],-1))])],64)),e("dialog",{ref_key:"addDlg",ref:j,class:"modal"},[e("div",Pt,[e("h3",Rt,"添加"+i(_e(g.value))+"服务",1),t[40]||(t[40]=e("p",{class:"text-xs text-slate-400 mt-1"},"从第三方服务配置里选一个已配好的服务加入本段编排。",-1)),e("div",Wt,[e("div",Xt,[t[36]||(t[36]=e("label",{class:"label py-1"},[e("span",{class:"label-text text-sm font-medium"},"服务")],-1)),N(e("select",{"onUpdate:modelValue":t[8]||(t[8]=s=>v.svc_id=s),class:"select select-bordered select-sm"},[t[35]||(t[35]=e("option",{value:""},"请选择服务…",-1)),(a(!0),n(c,null,V(O(g.value),s=>(a(),n("option",{key:s.id,value:s.id},i(s.name)+i(g.value===3&&ae(s.categories,9)?" 🖼":"")+"("+i(s.provider||s.id)+") ",9,qt))),128))],512),[[K,v.svc_id]]),O(g.value).length?f("",!0):(a(),n("span",Jt,"没有可添加的服务了(都加过了,或服务池里没这类服务)。"))]),e("div",Qt,[e("label",Yt,[e("span",Zt,"参考单价("+i(ne(g.value))+",可空)",1)]),N(e("input",{"onUpdate:modelValue":t[9]||(t[9]=s=>v.cost_hint=s),type:"number",step:"0.01",min:"0",class:"input input-bordered input-sm font-mono text-xs",placeholder:"0"},null,512),[[de,v.cost_hint,void 0,{number:!0}]]),t[37]||(t[37]=e("span",{class:"text-[11px] text-slate-400 mt-1"},"仅用于排序/展示,填你的实付价。",-1))]),g.value===3?(a(),n("div",es,[e("label",ts,[N(e("input",{"onUpdate:modelValue":t[10]||(t[10]=s=>v.is_default=s),type:"checkbox",class:"toggle toggle-primary toggle-sm"},null,512),[[ce,v.is_default]]),t[38]||(t[38]=e("span",{class:"text-sm"},"设为默认",-1))]),e("label",ss,[N(e("input",{"onUpdate:modelValue":t[11]||(t[11]=s=>v.client_visible=s),type:"checkbox",class:"toggle toggle-success toggle-sm"},null,512),[[ce,v.client_visible]]),t[39]||(t[39]=e("span",{class:"text-sm"},"前端可见",-1))])])):f("",!0)]),e("div",ls,[e("button",{class:"btn btn-ghost btn-sm",onClick:t[12]||(t[12]=s=>j.value?.close())},"取消"),e("button",{class:"btn btn-primary btn-sm text-white",disabled:!v.svc_id||L.value,onClick:ke},i(L.value?"添加中…":"添加"),9,ns)])]),t[41]||(t[41]=e("form",{method:"dialog",class:"modal-backdrop"},[e("button",null,"close")],-1))],512),e("dialog",{ref_key:"costDlg",ref:z,class:"modal"},[e("div",as,[t[42]||(t[42]=e("h3",{class:"font-bold text-lg"},"参考单价",-1)),e("p",is,i(k.name)+"("+i(ne(k.kind))+")",1),N(e("input",{"onUpdate:modelValue":t[13]||(t[13]=s=>k.cost_hint=s),type:"number",step:"0.01",min:"0",class:"input input-bordered input-sm w-full font-mono text-xs mt-3",placeholder:"0"},null,512),[[de,k.cost_hint,void 0,{number:!0}]]),e("div",os,[e("button",{class:"btn btn-ghost btn-sm",onClick:t[14]||(t[14]=s=>z.value?.close())},"取消"),e("button",{class:"btn btn-primary btn-sm text-white",disabled:L.value,onClick:xe},"保存",8,ds)])]),t[43]||(t[43]=e("form",{method:"dialog",class:"modal-backdrop"},[e("button",null,"close")],-1))],512)]))}}),ms=Ve(cs,[["__scopeId","data-v-4edbf244"]]);export{ms as default}; +import{g as Ce,B as $e,c as n,a as e,d,p as N,q as K,F as c,r as V,t as i,l as f,G as Ne,v as de,s as ce,x as _,y as ue,z as E,o as a,n as y,_ as Ve}from"./mElhLwm2.js";import{u as Ae}from"./C6twYRfy.js";import{u as Ue}from"./FVTAbpot.js";import{L as re}from"./ChQPCk92.js";import"./qig5Qp6S.js";const Le={class:"scopebar"},Me={class:"flex items-center gap-2"},Se=["value"],De=["value"],Oe={class:"text-[11px] text-slate-400"},Be={key:0,class:"bg-white rounded-xl border border-slate-100 py-16 text-center"},Ee={key:0,class:"alert alert-warning py-2 text-sm mb-4"},Te={class:"card"},je={class:"card-head"},ze={class:"flex gap-2 shrink-0"},Fe=["disabled"],Ge=["disabled"],He={class:"probe-bar"},Ie=["value"],Ke={key:0,class:"probe-out"},Pe={key:1,class:"probe-out bad"},Re={key:0,class:"py-10 text-center text-slate-400 text-sm"},We={class:"min-w-0"},Xe={class:"svc-prov"},qe={class:"flex flex-wrap gap-1"},Je={key:0,class:"lang"},Qe={key:1,class:"text-[11px] text-slate-400"},Ye={class:"svc-cost"},Ze={key:1,class:"text-slate-300"},et=["checked","disabled","onChange"],tt={class:"svc-acts"},st=["disabled","onClick"],lt=["disabled","onClick"],nt=["onClick"],at=["onClick"],it={class:"card mt-4"},ot={class:"card-head"},dt={class:"flex gap-2 shrink-0"},ct=["disabled"],ut=["disabled"],rt={key:0,class:"py-10 text-center text-slate-400 text-sm"},vt={class:"min-w-0"},bt={class:"svc-name"},_t={class:"svc-prov"},pt={class:"svc-cost"},mt={key:1,class:"text-slate-300"},gt=["checked","disabled","onChange"],ht={class:"svc-acts"},ft=["disabled","onClick"],kt=["disabled","onClick"],xt=["onClick"],yt=["onClick"],wt={class:"card mt-4"},Ct={class:"card-head"},$t=["disabled"],Nt={class:"mode-bar"},Vt={class:"flex items-center gap-2 cursor-pointer shrink-0"},At=["checked","disabled"],Ut={class:"mode-txt"},Lt={key:0,class:"py-10 text-center text-slate-400 text-sm"},Mt={class:"grid place-items-center"},St=["checked","disabled","onChange"],Dt={class:"min-w-0"},Ot={class:"svc-name"},Bt={key:0,title:"多媒体大模型,能识图"},Et={key:1,class:"chip chip-app ml-1"},Tt={class:"svc-prov"},jt={class:"svc-cost"},zt={key:1,class:"text-slate-300"},Ft=["checked","disabled","title","onChange"],Gt=["checked","disabled","onChange"],Ht={class:"svc-acts"},It=["onClick"],Kt=["onClick"],Pt={class:"modal-box max-w-md"},Rt={class:"font-bold text-lg"},Wt={class:"mt-4 space-y-3"},Xt={class:"form-control"},qt=["value"],Jt={key:0,class:"text-[11px] text-amber-600 mt-1"},Qt={class:"form-control"},Yt={class:"label py-1"},Zt={class:"label-text text-sm font-medium"},es={key:0,class:"flex gap-4"},ts={class:"flex items-center gap-2 cursor-pointer"},ss={class:"flex items-center gap-2 cursor-pointer"},ls={class:"modal-action"},ns=["disabled"],as={class:"modal-box max-w-sm"},is={class:"text-xs text-slate-400 mt-1"},os={class:"modal-action"},ds=["disabled"],cs=Ce({__name:"meetingsvc",setup(us){const{webApi:S,consoleApi:ve}=Ae(),{success:P,error:A}=Ue(),se=[{value:1,label:"中国"},{value:2,label:"美国"},{value:3,label:"东亚"},{value:4,label:"东南亚"},{value:5,label:"南亚"},{value:6,label:"中东"},{value:7,label:"欧洲"},{value:8,label:"俄罗斯"},{value:9,label:"非洲"},{value:10,label:"南美"},{value:11,label:"北美"},{value:12,label:"大洋洲"},{value:13,label:"巴西"},{value:14,label:"印度"}];function be(l){return se.find(t=>t.value===l)?.label??"区域"+l}const R=_([]),w=_(""),C=_(0),D=_([]),T=_([]),W=_({1:[8],2:[3],3:[5,9]}),U=_(!1),le=_(!1),X=_(!1),L=_(!1),r=_(!1),m=_("zh-CN"),j=_(null),z=_(null),g=_(1),v=ue({svc_id:"",cost_hint:0,is_default:!1,client_visible:!1}),k=ue({row_id:0,name:"",kind:1,cost_hint:0});function _e(l){return l===1?"识别":l===2?"翻译":"总结"}function ne(l){return l===1?"元/小时":l===2?"元/百万字符":"元/百万token"}function q(l){return re.find(t=>t.code===l)?.name??l}function ae(l,t){return(l||"").split(",").map(s=>Number(s.trim())).includes(t)}const F=E(()=>{const l=new Map;for(const t of T.value)l.set(t.id,t);return l});function x(l){return F.value.get(l)?.name??l}function J(l){return F.value.get(l)?.provider??"?"}function M(l){return F.value.get(l)?.languages??""}function pe(l){return ae(F.value.get(l)?.categories??"",9)}function b(l){return D.value.filter(t=>t.kind===l).sort((t,s)=>t.priority-s.priority)}function O(l){const t=W.value[String(l)]??[],s=new Set(D.value.filter(o=>o.kind===l).map(o=>o.svc_id));return T.value.filter(o=>!s.has(o.id)&&o.categories.split(",").some(u=>t.includes(Number(u.trim()))))}function G(l,t){const s=M(l);return s?s.split(",").map(o=>o.trim()).includes(t):!0}const h=E(()=>b(1).find(l=>l.enabled&&G(l.svc_id,m.value))??null),$=E(()=>b(2).find(l=>l.enabled)??null);function me(l){return h.value?.row_id!==l.row_id&&(!l.enabled||!G(l.svc_id,m.value))}function ge(l){return h.value?.row_id===l.row_id?"ok":!l.enabled||!G(l.svc_id,m.value)?"no":""}function he(l){return h.value?.row_id===l.row_id?M(l.svc_id)?`✓ 当前源语言(${q(m.value)})由它承接`:"✓ 未限定语言,先落到它(实际支持由引擎判断)":l.enabled?G(l.svc_id,m.value)?"备用:前面都跳过时接手":`不支持 ${q(m.value)}(${m.value}),跳过 → 顺延下一个`:"已停用,跳过"}const H=E(()=>b(3).find(l=>l.is_default)??null),Q=E(()=>b(3).filter(l=>l.enabled&&l.client_visible));async function fe(){try{const l=await ve("products/list",{});R.value=(l??[]).map(t=>t.name).filter(Boolean)}catch{R.value=[]}}async function p(){X.value=!0;try{const l=await S("getechoorch",{app_name:w.value,region:C.value});D.value=l?.items??[],T.value=l?.available??[],W.value=l?.kind_cats??W.value,U.value=!!l?.setting?.llm_client_choice,le.value=(!!w.value||C.value!==0)&&(D.value.length>0||U.value)}catch(l){A(l?.message??"加载失败")}finally{X.value=!1}}async function Y(l){await S("saveechoorch",{app_name:w.value,region:C.value,orch:l})}function Z(l){g.value=l,v.svc_id="",v.cost_hint=0,v.is_default=!1,v.client_visible=!1,j.value?.showModal()}async function ke(){if(v.svc_id){L.value=!0;try{const l=b(g.value),t=l.length?l[l.length-1].priority+10:10;await Y({kind:g.value,svc_id:v.svc_id,priority:t,cost_hint:Number(v.cost_hint)||0,is_default:g.value===3?v.is_default:!1,client_visible:g.value===3?v.client_visible:!1,enabled:!0}),P("已添加"),j.value?.close(),await p()}catch(l){A(l?.message??"添加失败")}finally{L.value=!1}}}async function B(l,t){r.value=!0;try{await Y({...l,...t}),await p()}catch(s){A(s?.message??"操作失败"),await p()}finally{r.value=!1}}async function ee(l){if(confirm(`从本段移除「${x(l.svc_id)}」?(不影响第三方服务配置里的服务本身)`))try{await S("delechoorch",{row_id:l.row_id}),P("已移除"),await p()}catch(t){A(t?.message??"移除失败")}}async function ie(l){r.value=!0;try{await S("reorderechoorch",{items:l.map((t,s)=>({row_id:t.row_id,priority:(s+1)*10}))}),await p()}catch(t){A(t?.message??"排序失败"),await p()}finally{r.value=!1}}function I(l,t,s){const o=[...b(l)],u=t+s;if(u<0||u>=o.length)return;const we=o[t];o[t]=o[u],o[u]=we,ie(o)}function oe(l){const t=[...b(l)].sort((s,o)=>s.enabled!==o.enabled?s.enabled?-1:1:(s.cost_hint||Number.MAX_VALUE)-(o.cost_hint||Number.MAX_VALUE));ie(t)}function te(l){k.row_id=l.row_id,k.name=x(l.svc_id),k.kind=l.kind,k.cost_hint=l.cost_hint,z.value?.showModal()}async function xe(){const l=D.value.find(t=>t.row_id===k.row_id);if(l){L.value=!0;try{await Y({...l,cost_hint:Number(k.cost_hint)||0}),P("已保存"),z.value?.close(),await p()}catch(t){A(t?.message??"保存失败")}finally{L.value=!1}}}async function ye(){r.value=!0;try{await S("saveechoorchsetting",{app_name:w.value,region:C.value,llm_client_choice:!U.value}),await p()}catch(l){A(l?.message??"保存失败"),await p()}finally{r.value=!1}}return $e(async()=>{await fe(),await p()}),(l,t)=>(a(),n("div",null,[t[44]||(t[44]=e("div",{class:"flex items-start justify-between mb-4 flex-wrap gap-3"},[e("div",null,[e("h2",{class:"text-lg font-semibold text-slate-800"},"会议记录服务"),e("p",{class:"text-xs text-slate-400 mt-1 max-w-3xl"},[d(" 识别 / 翻译 / 总结三段,从"),e("b",null,"第三方服务配置"),d("里选已配好的服务来编排(不再单独填凭据)。 "),e("span",{class:"text-slate-500"},"先配「全局默认」作兜底,再按应用 / 区域覆盖"),d("——没配覆盖的应用自动继承全局默认。 ")])])],-1)),e("div",Le,[e("div",Me,[t[17]||(t[17]=e("span",{class:"text-xs text-slate-500 font-semibold"},"作用域",-1)),N(e("select",{"onUpdate:modelValue":t[0]||(t[0]=s=>w.value=s),class:"select select-bordered select-sm",onChange:p},[t[15]||(t[15]=e("option",{value:""},"全局默认(兜底)",-1)),(a(!0),n(c,null,V(R.value,s=>(a(),n("option",{key:s,value:s},"应用:"+i(s),9,Se))),128))],544),[[K,w.value]]),N(e("select",{"onUpdate:modelValue":t[1]||(t[1]=s=>C.value=s),class:"select select-bordered select-sm",onChange:p},[t[16]||(t[16]=e("option",{value:0},"全区域",-1)),(a(),n(c,null,V(se,s=>e("option",{key:s.value,value:s.value},i(s.label),9,De)),64))],544),[[K,C.value,void 0,{number:!0}]])]),e("span",Oe,[d(i(w.value?`正在编辑「${w.value}」`:"正在编辑全局默认")+i(C.value?` · ${be(C.value)}`:" · 全区域")+" ",1),le.value?(a(),n(c,{key:0},[d("(覆盖全局默认)")],64)):f("",!0)])]),X.value?(a(),n("div",Be,[...t[18]||(t[18]=[e("span",{class:"loading loading-spinner loading-sm"},null,-1)])])):(a(),n(c,{key:1},[T.value.length?f("",!0):(a(),n("div",Ee,[...t[19]||(t[19]=[e("span",null,[d(" 该作用域没有可选服务。先去"),e("b",null,"第三方服务配置"),d("添加「录音文件识别 / 机器翻译 / 文本或多媒体大模型」类的服务 (全局默认或该应用作用域),这里才能选。 ")],-1)])])),e("div",Te,[e("div",je,[t[20]||(t[20]=e("div",null,[e("div",{class:"card-title"},"识别(录音文件转写)"),e("div",{class:"card-desc"},[d("按顺序找"),e("b",null,"第一个「已启用 + 支持源语言」"),d('的服务,不支持则跳到下一个。把便宜的排前面即"优先用性价比高的"。')])],-1)),e("div",ze,[e("button",{class:"btn btn-xs",disabled:b(1).length<2||r.value,onClick:t[2]||(t[2]=s=>oe(1))},"⇅ 按参考单价重排",8,Fe),e("button",{class:"btn btn-primary btn-xs text-white",disabled:!O(1).length,onClick:t[3]||(t[3]=s=>Z(1))},"+ 添加识别服务",8,Ge)])]),e("div",He,[t[21]||(t[21]=e("span",{class:"text-xs text-slate-500 font-semibold"},"选路预览",-1)),N(e("select",{"onUpdate:modelValue":t[4]||(t[4]=s=>m.value=s),class:"select select-bordered select-xs w-44 text-xs"},[(a(!0),n(c,null,V(Ne(re),s=>(a(),n("option",{key:s.code,value:s.code},i(s.code)+" · "+i(s.name),9,Ie))),128))],512),[[K,m.value]]),h.value?(a(),n("span",Ke,[d("命中 "+i(x(h.value.svc_id)),1),h.value.cost_hint?(a(),n(c,{key:0},[d(" · ¥"+i(h.value.cost_hint)+"/时",1)],64)):f("",!0)])):(a(),n("span",Pe,"无可用服务 —— "+i(q(m.value))+" 会转写失败",1))]),b(1).length?f("",!0):(a(),n("div",Re,"暂无识别服务,点右上「+ 添加识别服务」")),(a(!0),n(c,null,V(b(1),(s,o)=>(a(),n("div",{key:s.row_id,class:y(["svc asr",{hit:h.value&&h.value.row_id===s.row_id,off:!s.enabled}])},[e("div",{class:y(["svc-rank",{hit:h.value&&h.value.row_id===s.row_id}])},i(o+1),3),e("div",We,[e("div",{class:y(["svc-name",{skip:me(s)}])},i(x(s.svc_id)),3),e("div",Xe,i(J(s.svc_id))+" · "+i(s.svc_id),1)]),e("div",qe,[M(s.svc_id)?(a(),n(c,{key:0},[(a(!0),n(c,null,V(M(s.svc_id).split(",").slice(0,5),u=>(a(),n("span",{key:u,class:y(["lang",{on:u===m.value}])},i(u),3))),128)),M(s.svc_id).split(",").length>5?(a(),n("span",Je,"+"+i(M(s.svc_id).split(",").length-5),1)):f("",!0)],64)):(a(),n("span",Qe,"未限定"))]),e("div",Ye,[s.cost_hint?(a(),n(c,{key:0},[d("¥"+i(s.cost_hint),1),t[22]||(t[22]=e("small",null," /时",-1))],64)):(a(),n("span",Ze,"—"))]),e("div",null,[e("input",{type:"checkbox",class:"toggle toggle-success toggle-sm",checked:s.enabled,disabled:r.value,onChange:u=>B(s,{enabled:!s.enabled})},null,40,et)]),e("div",tt,[e("button",{class:"arrow",disabled:o===0||r.value,"aria-label":"上移",onClick:u=>I(1,o,-1)},"↑",8,st),e("button",{class:"arrow",disabled:o===b(1).length-1||r.value,"aria-label":"下移",onClick:u=>I(1,o,1)},"↓",8,lt),e("button",{class:"btn btn-ghost btn-xs",onClick:u=>te(s)},"单价",8,nt),e("button",{class:"btn btn-ghost btn-xs text-red-500",onClick:u=>ee(s)},"移除",8,at)]),e("div",{class:y(["svc-why",ge(s)])},i(he(s)),3)],2))),128))]),e("div",it,[e("div",ot,[t[23]||(t[23]=e("div",null,[e("div",{class:"card-title"},"翻译"),e("div",{class:"card-desc"},[d("按顺序取"),e("b",null,"第一个已启用"),d("的服务;调用失败自动回退下一个。")])],-1)),e("div",dt,[e("button",{class:"btn btn-xs",disabled:b(2).length<2||r.value,onClick:t[5]||(t[5]=s=>oe(2))},"⇅ 按参考单价重排",8,ct),e("button",{class:"btn btn-primary btn-xs text-white",disabled:!O(2).length,onClick:t[6]||(t[6]=s=>Z(2))},"+ 添加翻译服务",8,ut)])]),b(2).length?f("",!0):(a(),n("div",rt,"暂无翻译服务")),(a(!0),n(c,null,V(b(2),(s,o)=>(a(),n("div",{key:s.row_id,class:y(["svc mt",{hit:$.value&&$.value.row_id===s.row_id,off:!s.enabled}])},[e("div",{class:y(["svc-rank",{hit:$.value&&$.value.row_id===s.row_id}])},i(o+1),3),e("div",vt,[e("div",bt,i(x(s.svc_id)),1),e("div",_t,i(J(s.svc_id))+" · "+i(s.svc_id),1)]),e("div",pt,[s.cost_hint?(a(),n(c,{key:0},[d("¥"+i(s.cost_hint),1),t[24]||(t[24]=e("small",null," /百万字符",-1))],64)):(a(),n("span",mt,"—"))]),e("div",null,[e("input",{type:"checkbox",class:"toggle toggle-success toggle-sm",checked:s.enabled,disabled:r.value,onChange:u=>B(s,{enabled:!s.enabled})},null,40,gt)]),e("div",ht,[e("button",{class:"arrow",disabled:o===0||r.value,"aria-label":"上移",onClick:u=>I(2,o,-1)},"↑",8,ft),e("button",{class:"arrow",disabled:o===b(2).length-1||r.value,"aria-label":"下移",onClick:u=>I(2,o,1)},"↓",8,kt),e("button",{class:"btn btn-ghost btn-xs",onClick:u=>te(s)},"单价",8,xt),e("button",{class:"btn btn-ghost btn-xs text-red-500",onClick:u=>ee(s)},"移除",8,yt)]),e("div",{class:y(["svc-why",s.enabled?$.value&&$.value.row_id===s.row_id?"ok":"":"no"])},[s.enabled?$.value&&$.value.row_id===s.row_id?(a(),n(c,{key:1},[d("✓ 默认由它承接,失败顺延")],64)):(a(),n(c,{key:2},[d("备用:前面失败时接手")],64)):(a(),n(c,{key:0},[d("已停用,跳过")],64))],2)],2))),128))]),e("div",wt,[e("div",Ct,[t[25]||(t[25]=e("div",null,[e("div",{class:"card-title"},"总结(大模型)"),e("div",{class:"card-desc"},[d("后台指定默认模型,客户端可在允许范围内自选。带 🖼 的是"),e("b",null,"多媒体大模型"),d(",能识别会议里的图片。")])],-1)),e("button",{class:"btn btn-primary btn-xs text-white shrink-0",disabled:!O(3).length,onClick:t[7]||(t[7]=s=>Z(3))},"+ 添加模型",8,$t)]),e("div",Nt,[e("label",Vt,[e("input",{type:"checkbox",class:"toggle toggle-primary toggle-sm",checked:U.value,disabled:r.value,onChange:ye},null,40,At),t[26]||(t[26]=e("span",{class:"text-sm font-semibold text-slate-700"},"允许客户端指定模型",-1))]),e("p",Ut,[U.value?(a(),n(c,{key:0},[t[27]||(t[27]=d(" 前端能选 ",-1)),e("b",null,i(Q.value.length),1),t[28]||(t[28]=d(" 个模型",-1)),Q.value.length?(a(),n(c,{key:0},[d(":"+i(Q.value.map(s=>x(s.svc_id)).join("、")),1)],64)):(a(),n(c,{key:1},[d("(一个都没勾「前端可见」,等同强制默认)")],64)),t[29]||(t[29]=d("。不传则用默认 ",-1)),e("b",null,i(H.value?x(H.value.svc_id):"—"),1),t[30]||(t[30]=d("。 ",-1))],64)):(a(),n(c,{key:1},[t[31]||(t[31]=d(" 前端不下发模型列表,一律走默认模型 ",-1)),e("b",null,i(H.value?x(H.value.svc_id):"—"),1),t[32]||(t[32]=d(";客户端传了也忽略。 ",-1))],64))])]),b(3).length?f("",!0):(a(),n("div",Lt,"暂无模型")),(a(!0),n(c,null,V(b(3),s=>(a(),n("div",{key:s.row_id,class:y(["svc llm",{isdefault:s.is_default,off:!s.enabled}])},[e("div",Mt,[e("input",{type:"radio",name:"llmdef",class:"radio radio-primary radio-xs",checked:s.is_default,disabled:!s.enabled||r.value,onChange:o=>B(s,{is_default:!0})},null,40,St)]),e("div",Dt,[e("div",Ot,[d(i(x(s.svc_id))+" ",1),pe(s.svc_id)?(a(),n("span",Bt,"🖼")):f("",!0),s.is_default?(a(),n("span",Et,"默认")):f("",!0)]),e("div",Tt,i(J(s.svc_id))+" · "+i(s.svc_id),1)]),e("div",jt,[s.cost_hint?(a(),n(c,{key:0},[d("¥"+i(s.cost_hint),1),t[33]||(t[33]=e("small",null," /百万token",-1))],64)):(a(),n("span",zt,"—"))]),e("div",null,[e("input",{type:"checkbox",class:"toggle toggle-success toggle-sm",checked:s.client_visible,disabled:!U.value||!s.enabled||r.value,title:U.value?"":"先打开「允许客户端指定模型」",onChange:o=>B(s,{client_visible:!s.client_visible})},null,40,Ft)]),e("div",null,[e("input",{type:"checkbox",class:"toggle toggle-success toggle-sm",checked:s.enabled,disabled:r.value,onChange:o=>B(s,{enabled:!s.enabled})},null,40,Gt)]),e("div",Ht,[e("button",{class:"btn btn-ghost btn-xs",onClick:o=>te(s)},"单价",8,It),e("button",{class:"btn btn-ghost btn-xs text-red-500",onClick:o=>ee(s)},"移除",8,Kt)])],2))),128)),t[34]||(t[34]=e("div",{class:"col-h llm-h"},[e("div"),e("div"),e("div",null,"参考单价"),e("div",null,"前端可见"),e("div",null,"启用"),e("div")],-1))])],64)),e("dialog",{ref_key:"addDlg",ref:j,class:"modal"},[e("div",Pt,[e("h3",Rt,"添加"+i(_e(g.value))+"服务",1),t[40]||(t[40]=e("p",{class:"text-xs text-slate-400 mt-1"},"从第三方服务配置里选一个已配好的服务加入本段编排。",-1)),e("div",Wt,[e("div",Xt,[t[36]||(t[36]=e("label",{class:"label py-1"},[e("span",{class:"label-text text-sm font-medium"},"服务")],-1)),N(e("select",{"onUpdate:modelValue":t[8]||(t[8]=s=>v.svc_id=s),class:"select select-bordered select-sm"},[t[35]||(t[35]=e("option",{value:""},"请选择服务…",-1)),(a(!0),n(c,null,V(O(g.value),s=>(a(),n("option",{key:s.id,value:s.id},i(s.name)+i(g.value===3&&ae(s.categories,9)?" 🖼":"")+"("+i(s.provider||s.id)+") ",9,qt))),128))],512),[[K,v.svc_id]]),O(g.value).length?f("",!0):(a(),n("span",Jt,"没有可添加的服务了(都加过了,或服务池里没这类服务)。"))]),e("div",Qt,[e("label",Yt,[e("span",Zt,"参考单价("+i(ne(g.value))+",可空)",1)]),N(e("input",{"onUpdate:modelValue":t[9]||(t[9]=s=>v.cost_hint=s),type:"number",step:"0.01",min:"0",class:"input input-bordered input-sm font-mono text-xs",placeholder:"0"},null,512),[[de,v.cost_hint,void 0,{number:!0}]]),t[37]||(t[37]=e("span",{class:"text-[11px] text-slate-400 mt-1"},"仅用于排序/展示,填你的实付价。",-1))]),g.value===3?(a(),n("div",es,[e("label",ts,[N(e("input",{"onUpdate:modelValue":t[10]||(t[10]=s=>v.is_default=s),type:"checkbox",class:"toggle toggle-primary toggle-sm"},null,512),[[ce,v.is_default]]),t[38]||(t[38]=e("span",{class:"text-sm"},"设为默认",-1))]),e("label",ss,[N(e("input",{"onUpdate:modelValue":t[11]||(t[11]=s=>v.client_visible=s),type:"checkbox",class:"toggle toggle-success toggle-sm"},null,512),[[ce,v.client_visible]]),t[39]||(t[39]=e("span",{class:"text-sm"},"前端可见",-1))])])):f("",!0)]),e("div",ls,[e("button",{class:"btn btn-ghost btn-sm",onClick:t[12]||(t[12]=s=>j.value?.close())},"取消"),e("button",{class:"btn btn-primary btn-sm text-white",disabled:!v.svc_id||L.value,onClick:ke},i(L.value?"添加中…":"添加"),9,ns)])]),t[41]||(t[41]=e("form",{method:"dialog",class:"modal-backdrop"},[e("button",null,"close")],-1))],512),e("dialog",{ref_key:"costDlg",ref:z,class:"modal"},[e("div",as,[t[42]||(t[42]=e("h3",{class:"font-bold text-lg"},"参考单价",-1)),e("p",is,i(k.name)+"("+i(ne(k.kind))+")",1),N(e("input",{"onUpdate:modelValue":t[13]||(t[13]=s=>k.cost_hint=s),type:"number",step:"0.01",min:"0",class:"input input-bordered input-sm w-full font-mono text-xs mt-3",placeholder:"0"},null,512),[[de,k.cost_hint,void 0,{number:!0}]]),e("div",os,[e("button",{class:"btn btn-ghost btn-sm",onClick:t[14]||(t[14]=s=>z.value?.close())},"取消"),e("button",{class:"btn btn-primary btn-sm text-white",disabled:L.value,onClick:xe},"保存",8,ds)])]),t[43]||(t[43]=e("form",{method:"dialog",class:"modal-backdrop"},[e("button",null,"close")],-1))],512)]))}}),ms=Ve(cs,[["__scopeId","data-v-4edbf244"]]);export{ms as default}; diff --git a/apps/admin/.output/public/_nuxt/szhsDUYv.js b/apps/admin/.output/public/_nuxt/CglQi8MB.js similarity index 97% rename from apps/admin/.output/public/_nuxt/szhsDUYv.js rename to apps/admin/.output/public/_nuxt/CglQi8MB.js index bb2f2989..23e18c3d 100644 --- a/apps/admin/.output/public/_nuxt/szhsDUYv.js +++ b/apps/admin/.output/public/_nuxt/CglQi8MB.js @@ -1 +1 @@ -import{L as y,l as x}from"./ChQPCk92.js";import{g as V,c as t,F as u,a as l,n as C,r,l as g,t as o,z as h,o as s,d as B,_ as N}from"./Ccu6Xgpt.js";const L={class:"lang-select"},O={class:"lang-chip-name"},S=["onClick"],j={key:0,class:"lang-empty"},z={key:0,class:"lang-dd"},F={class:"lang-dd-sum"},I={class:"lang-dd-panel"},T=["checked","onChange"],$={class:"lang-opt-code"},w={class:"lang-opt-name"},A=["value","disabled"],D=["value"],E=V({__name:"LangSelect",props:{modelValue:{},multiple:{type:Boolean,default:!1},disabled:{type:Boolean,default:!1},options:{default:void 0}},emits:["update:modelValue"],setup(c,{emit:f}){const d=c,m=f,p=h(()=>d.options&&d.options.length?d.options:y),i=h(()=>(d.modelValue||"").split(",").map(a=>a.trim()).filter(Boolean));function v(a){return x(a)}function _(a){if(d.disabled)return;const n=i.value.slice(),e=n.indexOf(a);e>=0?n.splice(e,1):n.push(a),m("update:modelValue",n.join(","))}function b(a){m("update:modelValue",a.target.value)}return(a,n)=>(s(),t("div",L,[c.multiple?(s(),t(u,{key:0},[l("div",{class:C(["lang-chips",{"lang-disabled":c.disabled}])},[(s(!0),t(u,null,r(i.value,e=>(s(),t("span",{key:e,class:"lang-chip"},[B(o(e),1),l("span",O,o(v(e)),1),l("button",{type:"button",class:"lang-x",onClick:k=>_(e)},"×",8,S)]))),128)),i.value.length?g("",!0):(s(),t("span",j,"未选择语言"))],2),c.disabled?g("",!0):(s(),t("details",z,[l("summary",F,"+ 选择语言(已选 "+o(i.value.length)+")",1),l("div",I,[(s(!0),t(u,null,r(p.value,e=>(s(),t("label",{key:e.code,class:"lang-opt"},[l("input",{type:"checkbox",class:"checkbox checkbox-xs checkbox-primary",checked:i.value.includes(e.code),onChange:k=>_(e.code)},null,40,T),l("span",$,o(e.code),1),l("span",w,o(e.name),1)]))),128))])]))],64)):(s(),t("select",{key:1,class:"select select-bordered select-sm w-full text-xs",value:c.modelValue,disabled:c.disabled,onChange:b},[n[0]||(n[0]=l("option",{value:""},"(未设置)",-1)),(s(!0),t(u,null,r(p.value,e=>(s(),t("option",{key:e.code,value:e.code},o(e.code)+" · "+o(e.name),9,D))),128))],40,A))]))}}),q=Object.assign(N(E,[["__scopeId","data-v-4903af59"]]),{__name:"LangSelect"});export{q as _}; +import{L as y,l as x}from"./ChQPCk92.js";import{g as V,c as t,F as u,a as l,n as C,r,l as g,t as o,z as h,o as s,d as B,_ as N}from"./mElhLwm2.js";const L={class:"lang-select"},O={class:"lang-chip-name"},S=["onClick"],j={key:0,class:"lang-empty"},z={key:0,class:"lang-dd"},F={class:"lang-dd-sum"},I={class:"lang-dd-panel"},T=["checked","onChange"],$={class:"lang-opt-code"},w={class:"lang-opt-name"},A=["value","disabled"],D=["value"],E=V({__name:"LangSelect",props:{modelValue:{},multiple:{type:Boolean,default:!1},disabled:{type:Boolean,default:!1},options:{default:void 0}},emits:["update:modelValue"],setup(c,{emit:f}){const d=c,m=f,p=h(()=>d.options&&d.options.length?d.options:y),i=h(()=>(d.modelValue||"").split(",").map(a=>a.trim()).filter(Boolean));function v(a){return x(a)}function _(a){if(d.disabled)return;const n=i.value.slice(),e=n.indexOf(a);e>=0?n.splice(e,1):n.push(a),m("update:modelValue",n.join(","))}function b(a){m("update:modelValue",a.target.value)}return(a,n)=>(s(),t("div",L,[c.multiple?(s(),t(u,{key:0},[l("div",{class:C(["lang-chips",{"lang-disabled":c.disabled}])},[(s(!0),t(u,null,r(i.value,e=>(s(),t("span",{key:e,class:"lang-chip"},[B(o(e),1),l("span",O,o(v(e)),1),l("button",{type:"button",class:"lang-x",onClick:k=>_(e)},"×",8,S)]))),128)),i.value.length?g("",!0):(s(),t("span",j,"未选择语言"))],2),c.disabled?g("",!0):(s(),t("details",z,[l("summary",F,"+ 选择语言(已选 "+o(i.value.length)+")",1),l("div",I,[(s(!0),t(u,null,r(p.value,e=>(s(),t("label",{key:e.code,class:"lang-opt"},[l("input",{type:"checkbox",class:"checkbox checkbox-xs checkbox-primary",checked:i.value.includes(e.code),onChange:k=>_(e.code)},null,40,T),l("span",$,o(e.code),1),l("span",w,o(e.name),1)]))),128))])]))],64)):(s(),t("select",{key:1,class:"select select-bordered select-sm w-full text-xs",value:c.modelValue,disabled:c.disabled,onChange:b},[n[0]||(n[0]=l("option",{value:""},"(未设置)",-1)),(s(!0),t(u,null,r(p.value,e=>(s(),t("option",{key:e.code,value:e.code},o(e.code)+" · "+o(e.name),9,D))),128))],40,A))]))}}),q=Object.assign(N(E,[["__scopeId","data-v-4903af59"]]),{__name:"LangSelect"});export{q as _}; diff --git a/apps/admin/.output/public/_nuxt/CCYeqIml.js b/apps/admin/.output/public/_nuxt/CvHBDjjq.js similarity index 98% rename from apps/admin/.output/public/_nuxt/CCYeqIml.js rename to apps/admin/.output/public/_nuxt/CvHBDjjq.js index a5cbc5b0..a277e5ca 100644 --- a/apps/admin/.output/public/_nuxt/CCYeqIml.js +++ b/apps/admin/.output/public/_nuxt/CvHBDjjq.js @@ -1 +1 @@ -import{g as M,B as P,c as r,p as n,H as V,a as t,l as R,F as H,r as I,t as i,m as z,v as a,s as L,x as b,y as E,z as O,o as u,n as T,d as q}from"./Ccu6Xgpt.js";import{u as G}from"./Um-KoueI.js";import{u as K}from"./DvwKXRUn.js";import"./CH2ZVAK2.js";const Y={class:"flex items-center justify-between mb-5"},J={class:"bg-white rounded-xl shadow-sm border border-slate-100"},Q={class:"overflow-x-auto"},W={class:"table table-zebra text-sm"},X={key:0},Z={key:1},tt={class:"font-mono"},st={class:"font-medium"},et={class:"font-mono text-xs text-slate-500"},lt={class:"text-xs text-slate-500"},ot={key:0,class:"text-green-600"},nt={key:1,class:"text-slate-400"},at={class:"flex gap-1"},dt=["onClick"],it=["onClick"],rt={class:"flex items-center gap-3 mb-5"},ut={class:"text-lg font-semibold text-slate-800"},pt={class:"bg-white rounded-xl shadow-sm border border-slate-100 p-6 max-w-3xl"},mt={class:"grid grid-cols-2 gap-4"},bt={class:"form-control"},ft={class:"form-control"},ct={class:"grid grid-cols-3 gap-4"},xt={class:"form-control col-span-2"},vt={class:"form-control"},gt={class:"form-control mt-4"},yt={class:"form-control mt-4"},_t={class:"grid grid-cols-2 gap-4"},kt={class:"form-control"},wt={class:"form-control"},ht={class:"form-control"},St={class:"form-control"},Vt={class:"grid grid-cols-2 gap-4"},Ut={class:"form-control"},Ct={class:"form-control"},Ht={class:"grid grid-cols-2 gap-4 mt-4"},It={class:"form-control"},Et={class:"form-control"},Tt={class:"form-control mt-4"},Dt={class:"flex items-center gap-2 mt-4"},Nt={class:"flex items-center gap-2 cursor-pointer"},$t={class:"mt-4 text-sm space-y-0.5"},jt={class:"flex gap-3 mt-6"},At=["disabled"],Bt=["disabled"],Lt=M({__name:"environments",setup(Ft){const{consoleApi:c}=G(),{success:_,error:m}=K(),x=b("list"),v=b([]),k=b(!1),g=b(!1),f=b(!1),y=b(!1),d=E({show:!1,ok:!1,ssh_ok:!1,ssh_msg:"",etcd_ok:!1,etcd_msg:"",redis_ok:!1,redis_msg:"",nats_ok:!1,nats_msg:""}),D=O(()=>[{key:"ssh",label:"SSH 部署机",ok:d.ssh_ok,msg:d.ssh_msg},{key:"etcd",label:"ETCD",ok:d.etcd_ok,msg:d.etcd_msg},{key:"redis",label:"Redis",ok:d.redis_ok,msg:d.redis_msg},{key:"nats",label:"NATS",ok:d.nats_ok,msg:d.nats_msg}]);function w(){return{id:0,name:"",code:"",remark:"",enabled:!0,ssh_host:"",ssh_port:22,ssh_user:"root",ssh_private_key:"",registry:"",registry_user:"",registry_pass:"",docker_network:"1panel-network",etcd_servers:"",redis_addr:"",redis_pwd:"",nats_url:""}}const l=E(w());function U(o){Object.assign(l,w(),o)}function N(o){return o.ssh_host?`${o.ssh_user||"root"}@${o.ssh_host}:${o.ssh_port||22}`:"-"}function $(o){return o.registry||"-"}async function h(){k.value=!0;try{const o=await c("envs/list",{});v.value=o??[]}catch(o){m(o?.message??"获取环境列表失败"),v.value=[]}finally{k.value=!1}}function p(){f.value=!1,d.show=!1}function S(){x.value="list",h()}function C(o){o?(g.value=!0,U(o)):(g.value=!1,U(w())),p(),x.value="form"}async function j(){if(!l.ssh_host.trim()){m("请先填 SSH 主机");return}y.value=!0;try{const o=await c("envs/test",{...l});Object.assign(d,o,{show:!0}),f.value=!!o.ok,f.value?_("SSH 握手成功,可以保存"):m("SSH 未通过,请检查主机/私钥/用户")}catch(o){m(o?.message??"测试失败")}finally{y.value=!1}}async function A(){if(!f.value){m("请先「测试连接」通过再保存");return}const o={...l};let s="envs/add";g.value&&l.id?(o.id=Number(l.id),s="envs/update"):delete o.id;try{await c(s,o),_("保存成功"),S()}catch(e){m(e?.message??"失败")}}function B(o){window.confirm(`删除环境 #${o} ?(该环境下若有应用关联将被拒绝)`)&&c("envs/del",{id:o}).then(()=>{_("已删除"),h()}).catch(s=>m(s?.message??"失败"))}return P(h),(o,s)=>(u(),r("div",null,[n(t("div",null,[t("div",Y,[s[19]||(s[19]=t("div",null,[t("h2",{class:"text-lg font-semibold text-slate-800"},"环境节点(部署服务器)"),t("p",{class:"text-sm text-slate-400 mt-1"},"部署服务器节点(如 上海 / 日本 / 新加坡):远端 IP、SSH 登录账号与私钥、私有镜像仓库、区域共享基础设施。应用管理里「部署到目标环境」从这里选择、两边对应;下一期即可从页面直接更新服务/部署应用。密钥加密存储,不回显明文。")],-1)),t("button",{class:"btn btn-primary btn-sm text-white",onClick:s[0]||(s[0]=e=>C())},"+ 新增节点")]),t("div",J,[t("div",Q,[t("table",W,[s[22]||(s[22]=t("thead",null,[t("tr",null,[t("th",null,"ID"),t("th",null,"名称"),t("th",null,"区域码"),t("th",null,"SSH 目标"),t("th",null,"镜像仓库"),t("th",null,"启用"),t("th",null,"操作")])],-1)),t("tbody",null,[k.value?(u(),r("tr",X,[...s[20]||(s[20]=[t("td",{colspan:"7",class:"text-center py-8"},[t("span",{class:"loading loading-spinner loading-sm"})],-1)])])):v.value.length?R("",!0):(u(),r("tr",Z,[...s[21]||(s[21]=[t("td",{colspan:"7",class:"text-center text-slate-400 py-8"},"暂无环境",-1)])])),(u(!0),r(H,null,I(v.value,e=>(u(),r("tr",{key:e.id},[t("td",tt,i(e.id),1),t("td",st,i(e.name||""),1),t("td",null,i(e.code||""),1),t("td",et,i(N(e)),1),t("td",lt,i($(e)),1),t("td",null,[e.enabled?(u(),r("span",ot,"是")):(u(),r("span",nt,"否"))]),t("td",null,[t("div",at,[t("button",{class:"btn btn-ghost btn-xs",onClick:F=>C(e)},"编辑",8,dt),t("button",{class:"btn btn-ghost btn-xs text-red-500",onClick:F=>B(e.id)},"删除",8,it)])])]))),128))])])])])],512),[[V,x.value==="list"]]),n(t("div",null,[t("div",rt,[t("button",{class:"btn btn-ghost btn-sm",onClick:s[1]||(s[1]=e=>S())},"← 返回"),t("h2",ut,i(g.value?"编辑节点":"新增节点"),1)]),t("div",pt,[t("form",{onSubmit:z(A,["prevent"])},[t("div",mt,[t("div",bt,[s[23]||(s[23]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"名称 *")],-1)),n(t("input",{"onUpdate:modelValue":s[2]||(s[2]=e=>l.name=e),type:"text",class:"input input-bordered w-full",required:"",placeholder:"如 上海生产"},null,512),[[a,l.name]])]),t("div",ft,[s[24]||(s[24]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"区域码")],-1)),n(t("input",{"onUpdate:modelValue":s[3]||(s[3]=e=>l.code=e),type:"text",class:"input input-bordered w-full",list:"env-code-list",placeholder:"shanghai / japan / singapore"},null,512),[[a,l.code]]),s[25]||(s[25]=t("datalist",{id:"env-code-list"},[t("option",{value:"shanghai"}),t("option",{value:"japan"}),t("option",{value:"singapore"})],-1))])]),s[41]||(s[41]=t("div",{class:"divider text-xs text-slate-400 mt-6"},"SSH 部署目标",-1)),t("div",ct,[t("div",xt,[s[26]||(s[26]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"SSH 主机")],-1)),n(t("input",{"onUpdate:modelValue":s[4]||(s[4]=e=>l.ssh_host=e),type:"text",class:"input input-bordered w-full",placeholder:"139.224.212.237",onInput:p},null,544),[[a,l.ssh_host]])]),t("div",vt,[s[27]||(s[27]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"端口")],-1)),n(t("input",{"onUpdate:modelValue":s[5]||(s[5]=e=>l.ssh_port=e),type:"number",class:"input input-bordered w-full",placeholder:"22",onInput:p},null,544),[[a,l.ssh_port,void 0,{number:!0}]])])]),t("div",gt,[s[28]||(s[28]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"SSH 用户")],-1)),n(t("input",{"onUpdate:modelValue":s[6]||(s[6]=e=>l.ssh_user=e),type:"text",class:"input input-bordered w-full",placeholder:"root",onInput:p},null,544),[[a,l.ssh_user]])]),t("div",yt,[s[29]||(s[29]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"SSH 私钥 (PEM)")],-1)),n(t("textarea",{"onUpdate:modelValue":s[7]||(s[7]=e=>l.ssh_private_key=e),class:"textarea textarea-bordered w-full font-mono text-xs h-28",placeholder:"-----BEGIN OPENSSH PRIVATE KEY-----",onInput:p},null,544),[[a,l.ssh_private_key]]),s[30]||(s[30]=t("span",{class:"text-xs text-slate-400 mt-1"},"加密存储;编辑时显示 [encrypted] 表示不改,如需更换直接粘贴新私钥。",-1))]),s[42]||(s[42]=t("div",{class:"divider text-xs text-slate-400 mt-6"},"私有镜像仓库 + Docker 网络",-1)),t("div",_t,[t("div",kt,[s[31]||(s[31]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"仓库地址")],-1)),n(t("input",{"onUpdate:modelValue":s[8]||(s[8]=e=>l.registry=e),type:"text",class:"input input-bordered w-full",placeholder:"docker-registry.ideapsound.com"},null,512),[[a,l.registry]])]),t("div",wt,[s[32]||(s[32]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"Docker 网络")],-1)),n(t("input",{"onUpdate:modelValue":s[9]||(s[9]=e=>l.docker_network=e),type:"text",class:"input input-bordered w-full",placeholder:"1panel-network"},null,512),[[a,l.docker_network]])]),t("div",ht,[s[33]||(s[33]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"仓库账号")],-1)),n(t("input",{"onUpdate:modelValue":s[10]||(s[10]=e=>l.registry_user=e),type:"text",class:"input input-bordered w-full",autocomplete:"off"},null,512),[[a,l.registry_user]])]),t("div",St,[s[34]||(s[34]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"仓库密码")],-1)),n(t("input",{"onUpdate:modelValue":s[11]||(s[11]=e=>l.registry_pass=e),type:"password",class:"input input-bordered w-full",autocomplete:"new-password",placeholder:"[encrypted]"},null,512),[[a,l.registry_pass]])])]),s[43]||(s[43]=t("div",{class:"divider text-xs text-slate-400 mt-6"},"节点共享集群服务",-1)),s[44]||(s[44]=t("p",{class:"text-xs text-slate-400 -mt-2 mb-2"},"该服务器上各应用共用的地址。各应用自己的部署目录、业务库 DSN、镜像、redis 库号等,在「应用管理 → 部署到目标环境」里按应用填。",-1)),t("div",Vt,[t("div",Ut,[s[35]||(s[35]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"ETCD")],-1)),n(t("input",{"onUpdate:modelValue":s[12]||(s[12]=e=>l.etcd_servers=e),type:"text",class:"input input-bordered w-full font-mono text-xs",placeholder:"etcd:2379",onInput:p},null,544),[[a,l.etcd_servers]])]),t("div",Ct,[s[36]||(s[36]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"NATS")],-1)),n(t("input",{"onUpdate:modelValue":s[13]||(s[13]=e=>l.nats_url=e),type:"text",class:"input input-bordered w-full font-mono text-xs",placeholder:"nats://nats:4222",onInput:p},null,544),[[a,l.nats_url]])])]),t("div",Ht,[t("div",It,[s[37]||(s[37]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"Redis 地址")],-1)),n(t("input",{"onUpdate:modelValue":s[14]||(s[14]=e=>l.redis_addr=e),type:"text",class:"input input-bordered w-full font-mono text-xs",placeholder:"redis:6379",onInput:p},null,544),[[a,l.redis_addr]])]),t("div",Et,[s[38]||(s[38]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"Redis 密码")],-1)),n(t("input",{"onUpdate:modelValue":s[15]||(s[15]=e=>l.redis_pwd=e),type:"password",class:"input input-bordered w-full",autocomplete:"new-password",placeholder:"[encrypted]"},null,512),[[a,l.redis_pwd]])])]),t("div",Tt,[s[39]||(s[39]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"备注")],-1)),n(t("input",{"onUpdate:modelValue":s[16]||(s[16]=e=>l.remark=e),type:"text",class:"input input-bordered w-full"},null,512),[[a,l.remark]])]),t("div",Dt,[t("label",Nt,[n(t("input",{"onUpdate:modelValue":s[17]||(s[17]=e=>l.enabled=e),type:"checkbox",class:"toggle toggle-primary toggle-sm"},null,512),[[L,l.enabled]]),s[40]||(s[40]=t("span",{class:"text-sm"},"启用",-1))])]),n(t("div",$t,[(u(!0),r(H,null,I(D.value,e=>(u(),r("div",{key:e.key,class:T(e.ok?"text-green-700":"text-red-600")},[t("span",{class:T(e.ok?"text-green-600":"text-red-500")},i(e.ok?"✓":"✗"),3),q(" "+i(e.label)+":"+i(e.msg),1)],2))),128))],512),[[V,d.show]]),t("div",jt,[t("button",{type:"button",class:"btn btn-ghost",onClick:s[18]||(s[18]=e=>S())},"取消"),t("button",{type:"button",class:"btn btn-outline",disabled:y.value,onClick:j},i(y.value?"测试中...":"测试连接"),9,At),t("button",{type:"submit",class:"btn btn-primary text-white",disabled:!f.value},"保存",8,Bt)]),s[45]||(s[45]=t("p",{class:"text-xs text-slate-400 mt-2"},"需先「测试连接」(SSH 握手成功即可保存;基础设施逐项仅作提示)。",-1))],32)])],512),[[V,x.value==="form"]])]))}});export{Lt as default}; +import{g as M,B as P,c as r,p as n,H as V,a as t,l as R,F as H,r as I,t as i,m as z,v as a,s as L,x as b,y as E,z as O,o as u,n as T,d as q}from"./mElhLwm2.js";import{u as G}from"./C6twYRfy.js";import{u as K}from"./FVTAbpot.js";import"./qig5Qp6S.js";const Y={class:"flex items-center justify-between mb-5"},J={class:"bg-white rounded-xl shadow-sm border border-slate-100"},Q={class:"overflow-x-auto"},W={class:"table table-zebra text-sm"},X={key:0},Z={key:1},tt={class:"font-mono"},st={class:"font-medium"},et={class:"font-mono text-xs text-slate-500"},lt={class:"text-xs text-slate-500"},ot={key:0,class:"text-green-600"},nt={key:1,class:"text-slate-400"},at={class:"flex gap-1"},dt=["onClick"],it=["onClick"],rt={class:"flex items-center gap-3 mb-5"},ut={class:"text-lg font-semibold text-slate-800"},pt={class:"bg-white rounded-xl shadow-sm border border-slate-100 p-6 max-w-3xl"},mt={class:"grid grid-cols-2 gap-4"},bt={class:"form-control"},ft={class:"form-control"},ct={class:"grid grid-cols-3 gap-4"},xt={class:"form-control col-span-2"},vt={class:"form-control"},gt={class:"form-control mt-4"},yt={class:"form-control mt-4"},_t={class:"grid grid-cols-2 gap-4"},kt={class:"form-control"},wt={class:"form-control"},ht={class:"form-control"},St={class:"form-control"},Vt={class:"grid grid-cols-2 gap-4"},Ut={class:"form-control"},Ct={class:"form-control"},Ht={class:"grid grid-cols-2 gap-4 mt-4"},It={class:"form-control"},Et={class:"form-control"},Tt={class:"form-control mt-4"},Dt={class:"flex items-center gap-2 mt-4"},Nt={class:"flex items-center gap-2 cursor-pointer"},$t={class:"mt-4 text-sm space-y-0.5"},jt={class:"flex gap-3 mt-6"},At=["disabled"],Bt=["disabled"],Lt=M({__name:"environments",setup(Ft){const{consoleApi:c}=G(),{success:_,error:m}=K(),x=b("list"),v=b([]),k=b(!1),g=b(!1),f=b(!1),y=b(!1),d=E({show:!1,ok:!1,ssh_ok:!1,ssh_msg:"",etcd_ok:!1,etcd_msg:"",redis_ok:!1,redis_msg:"",nats_ok:!1,nats_msg:""}),D=O(()=>[{key:"ssh",label:"SSH 部署机",ok:d.ssh_ok,msg:d.ssh_msg},{key:"etcd",label:"ETCD",ok:d.etcd_ok,msg:d.etcd_msg},{key:"redis",label:"Redis",ok:d.redis_ok,msg:d.redis_msg},{key:"nats",label:"NATS",ok:d.nats_ok,msg:d.nats_msg}]);function w(){return{id:0,name:"",code:"",remark:"",enabled:!0,ssh_host:"",ssh_port:22,ssh_user:"root",ssh_private_key:"",registry:"",registry_user:"",registry_pass:"",docker_network:"1panel-network",etcd_servers:"",redis_addr:"",redis_pwd:"",nats_url:""}}const l=E(w());function U(o){Object.assign(l,w(),o)}function N(o){return o.ssh_host?`${o.ssh_user||"root"}@${o.ssh_host}:${o.ssh_port||22}`:"-"}function $(o){return o.registry||"-"}async function h(){k.value=!0;try{const o=await c("envs/list",{});v.value=o??[]}catch(o){m(o?.message??"获取环境列表失败"),v.value=[]}finally{k.value=!1}}function p(){f.value=!1,d.show=!1}function S(){x.value="list",h()}function C(o){o?(g.value=!0,U(o)):(g.value=!1,U(w())),p(),x.value="form"}async function j(){if(!l.ssh_host.trim()){m("请先填 SSH 主机");return}y.value=!0;try{const o=await c("envs/test",{...l});Object.assign(d,o,{show:!0}),f.value=!!o.ok,f.value?_("SSH 握手成功,可以保存"):m("SSH 未通过,请检查主机/私钥/用户")}catch(o){m(o?.message??"测试失败")}finally{y.value=!1}}async function A(){if(!f.value){m("请先「测试连接」通过再保存");return}const o={...l};let s="envs/add";g.value&&l.id?(o.id=Number(l.id),s="envs/update"):delete o.id;try{await c(s,o),_("保存成功"),S()}catch(e){m(e?.message??"失败")}}function B(o){window.confirm(`删除环境 #${o} ?(该环境下若有应用关联将被拒绝)`)&&c("envs/del",{id:o}).then(()=>{_("已删除"),h()}).catch(s=>m(s?.message??"失败"))}return P(h),(o,s)=>(u(),r("div",null,[n(t("div",null,[t("div",Y,[s[19]||(s[19]=t("div",null,[t("h2",{class:"text-lg font-semibold text-slate-800"},"环境节点(部署服务器)"),t("p",{class:"text-sm text-slate-400 mt-1"},"部署服务器节点(如 上海 / 日本 / 新加坡):远端 IP、SSH 登录账号与私钥、私有镜像仓库、区域共享基础设施。应用管理里「部署到目标环境」从这里选择、两边对应;下一期即可从页面直接更新服务/部署应用。密钥加密存储,不回显明文。")],-1)),t("button",{class:"btn btn-primary btn-sm text-white",onClick:s[0]||(s[0]=e=>C())},"+ 新增节点")]),t("div",J,[t("div",Q,[t("table",W,[s[22]||(s[22]=t("thead",null,[t("tr",null,[t("th",null,"ID"),t("th",null,"名称"),t("th",null,"区域码"),t("th",null,"SSH 目标"),t("th",null,"镜像仓库"),t("th",null,"启用"),t("th",null,"操作")])],-1)),t("tbody",null,[k.value?(u(),r("tr",X,[...s[20]||(s[20]=[t("td",{colspan:"7",class:"text-center py-8"},[t("span",{class:"loading loading-spinner loading-sm"})],-1)])])):v.value.length?R("",!0):(u(),r("tr",Z,[...s[21]||(s[21]=[t("td",{colspan:"7",class:"text-center text-slate-400 py-8"},"暂无环境",-1)])])),(u(!0),r(H,null,I(v.value,e=>(u(),r("tr",{key:e.id},[t("td",tt,i(e.id),1),t("td",st,i(e.name||""),1),t("td",null,i(e.code||""),1),t("td",et,i(N(e)),1),t("td",lt,i($(e)),1),t("td",null,[e.enabled?(u(),r("span",ot,"是")):(u(),r("span",nt,"否"))]),t("td",null,[t("div",at,[t("button",{class:"btn btn-ghost btn-xs",onClick:F=>C(e)},"编辑",8,dt),t("button",{class:"btn btn-ghost btn-xs text-red-500",onClick:F=>B(e.id)},"删除",8,it)])])]))),128))])])])])],512),[[V,x.value==="list"]]),n(t("div",null,[t("div",rt,[t("button",{class:"btn btn-ghost btn-sm",onClick:s[1]||(s[1]=e=>S())},"← 返回"),t("h2",ut,i(g.value?"编辑节点":"新增节点"),1)]),t("div",pt,[t("form",{onSubmit:z(A,["prevent"])},[t("div",mt,[t("div",bt,[s[23]||(s[23]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"名称 *")],-1)),n(t("input",{"onUpdate:modelValue":s[2]||(s[2]=e=>l.name=e),type:"text",class:"input input-bordered w-full",required:"",placeholder:"如 上海生产"},null,512),[[a,l.name]])]),t("div",ft,[s[24]||(s[24]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"区域码")],-1)),n(t("input",{"onUpdate:modelValue":s[3]||(s[3]=e=>l.code=e),type:"text",class:"input input-bordered w-full",list:"env-code-list",placeholder:"shanghai / japan / singapore"},null,512),[[a,l.code]]),s[25]||(s[25]=t("datalist",{id:"env-code-list"},[t("option",{value:"shanghai"}),t("option",{value:"japan"}),t("option",{value:"singapore"})],-1))])]),s[41]||(s[41]=t("div",{class:"divider text-xs text-slate-400 mt-6"},"SSH 部署目标",-1)),t("div",ct,[t("div",xt,[s[26]||(s[26]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"SSH 主机")],-1)),n(t("input",{"onUpdate:modelValue":s[4]||(s[4]=e=>l.ssh_host=e),type:"text",class:"input input-bordered w-full",placeholder:"139.224.212.237",onInput:p},null,544),[[a,l.ssh_host]])]),t("div",vt,[s[27]||(s[27]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"端口")],-1)),n(t("input",{"onUpdate:modelValue":s[5]||(s[5]=e=>l.ssh_port=e),type:"number",class:"input input-bordered w-full",placeholder:"22",onInput:p},null,544),[[a,l.ssh_port,void 0,{number:!0}]])])]),t("div",gt,[s[28]||(s[28]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"SSH 用户")],-1)),n(t("input",{"onUpdate:modelValue":s[6]||(s[6]=e=>l.ssh_user=e),type:"text",class:"input input-bordered w-full",placeholder:"root",onInput:p},null,544),[[a,l.ssh_user]])]),t("div",yt,[s[29]||(s[29]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"SSH 私钥 (PEM)")],-1)),n(t("textarea",{"onUpdate:modelValue":s[7]||(s[7]=e=>l.ssh_private_key=e),class:"textarea textarea-bordered w-full font-mono text-xs h-28",placeholder:"-----BEGIN OPENSSH PRIVATE KEY-----",onInput:p},null,544),[[a,l.ssh_private_key]]),s[30]||(s[30]=t("span",{class:"text-xs text-slate-400 mt-1"},"加密存储;编辑时显示 [encrypted] 表示不改,如需更换直接粘贴新私钥。",-1))]),s[42]||(s[42]=t("div",{class:"divider text-xs text-slate-400 mt-6"},"私有镜像仓库 + Docker 网络",-1)),t("div",_t,[t("div",kt,[s[31]||(s[31]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"仓库地址")],-1)),n(t("input",{"onUpdate:modelValue":s[8]||(s[8]=e=>l.registry=e),type:"text",class:"input input-bordered w-full",placeholder:"docker-registry.ideapsound.com"},null,512),[[a,l.registry]])]),t("div",wt,[s[32]||(s[32]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"Docker 网络")],-1)),n(t("input",{"onUpdate:modelValue":s[9]||(s[9]=e=>l.docker_network=e),type:"text",class:"input input-bordered w-full",placeholder:"1panel-network"},null,512),[[a,l.docker_network]])]),t("div",ht,[s[33]||(s[33]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"仓库账号")],-1)),n(t("input",{"onUpdate:modelValue":s[10]||(s[10]=e=>l.registry_user=e),type:"text",class:"input input-bordered w-full",autocomplete:"off"},null,512),[[a,l.registry_user]])]),t("div",St,[s[34]||(s[34]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"仓库密码")],-1)),n(t("input",{"onUpdate:modelValue":s[11]||(s[11]=e=>l.registry_pass=e),type:"password",class:"input input-bordered w-full",autocomplete:"new-password",placeholder:"[encrypted]"},null,512),[[a,l.registry_pass]])])]),s[43]||(s[43]=t("div",{class:"divider text-xs text-slate-400 mt-6"},"节点共享集群服务",-1)),s[44]||(s[44]=t("p",{class:"text-xs text-slate-400 -mt-2 mb-2"},"该服务器上各应用共用的地址。各应用自己的部署目录、业务库 DSN、镜像、redis 库号等,在「应用管理 → 部署到目标环境」里按应用填。",-1)),t("div",Vt,[t("div",Ut,[s[35]||(s[35]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"ETCD")],-1)),n(t("input",{"onUpdate:modelValue":s[12]||(s[12]=e=>l.etcd_servers=e),type:"text",class:"input input-bordered w-full font-mono text-xs",placeholder:"etcd:2379",onInput:p},null,544),[[a,l.etcd_servers]])]),t("div",Ct,[s[36]||(s[36]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"NATS")],-1)),n(t("input",{"onUpdate:modelValue":s[13]||(s[13]=e=>l.nats_url=e),type:"text",class:"input input-bordered w-full font-mono text-xs",placeholder:"nats://nats:4222",onInput:p},null,544),[[a,l.nats_url]])])]),t("div",Ht,[t("div",It,[s[37]||(s[37]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"Redis 地址")],-1)),n(t("input",{"onUpdate:modelValue":s[14]||(s[14]=e=>l.redis_addr=e),type:"text",class:"input input-bordered w-full font-mono text-xs",placeholder:"redis:6379",onInput:p},null,544),[[a,l.redis_addr]])]),t("div",Et,[s[38]||(s[38]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"Redis 密码")],-1)),n(t("input",{"onUpdate:modelValue":s[15]||(s[15]=e=>l.redis_pwd=e),type:"password",class:"input input-bordered w-full",autocomplete:"new-password",placeholder:"[encrypted]"},null,512),[[a,l.redis_pwd]])])]),t("div",Tt,[s[39]||(s[39]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"备注")],-1)),n(t("input",{"onUpdate:modelValue":s[16]||(s[16]=e=>l.remark=e),type:"text",class:"input input-bordered w-full"},null,512),[[a,l.remark]])]),t("div",Dt,[t("label",Nt,[n(t("input",{"onUpdate:modelValue":s[17]||(s[17]=e=>l.enabled=e),type:"checkbox",class:"toggle toggle-primary toggle-sm"},null,512),[[L,l.enabled]]),s[40]||(s[40]=t("span",{class:"text-sm"},"启用",-1))])]),n(t("div",$t,[(u(!0),r(H,null,I(D.value,e=>(u(),r("div",{key:e.key,class:T(e.ok?"text-green-700":"text-red-600")},[t("span",{class:T(e.ok?"text-green-600":"text-red-500")},i(e.ok?"✓":"✗"),3),q(" "+i(e.label)+":"+i(e.msg),1)],2))),128))],512),[[V,d.show]]),t("div",jt,[t("button",{type:"button",class:"btn btn-ghost",onClick:s[18]||(s[18]=e=>S())},"取消"),t("button",{type:"button",class:"btn btn-outline",disabled:y.value,onClick:j},i(y.value?"测试中...":"测试连接"),9,At),t("button",{type:"submit",class:"btn btn-primary text-white",disabled:!f.value},"保存",8,Bt)]),s[45]||(s[45]=t("p",{class:"text-xs text-slate-400 mt-2"},"需先「测试连接」(SSH 握手成功即可保存;基础设施逐项仅作提示)。",-1))],32)])],512),[[V,x.value==="form"]])]))}});export{Lt as default}; diff --git a/apps/admin/.output/public/_nuxt/zsrSRWp_.js b/apps/admin/.output/public/_nuxt/CyqrlMkw.js similarity index 71% rename from apps/admin/.output/public/_nuxt/zsrSRWp_.js rename to apps/admin/.output/public/_nuxt/CyqrlMkw.js index 22edd108..350e3f1f 100644 --- a/apps/admin/.output/public/_nuxt/zsrSRWp_.js +++ b/apps/admin/.output/public/_nuxt/CyqrlMkw.js @@ -1 +1 @@ -import{_ as t,o,c as s,R as c}from"./Ccu6Xgpt.js";const r={},a={class:"min-h-screen","data-theme":"corporate"};function n(e,_){return o(),s("div",a,[c(e.$slots,"default")])}const l=t(r,[["render",n]]);export{l as default}; +import{_ as t,o,c as s,R as c}from"./mElhLwm2.js";const r={},a={class:"min-h-screen","data-theme":"corporate"};function n(e,_){return o(),s("div",a,[c(e.$slots,"default")])}const l=t(r,[["render",n]]);export{l as default}; diff --git a/apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/CAgv4ClK.js b/apps/admin/.output/public/_nuxt/D-lUY2ZC.js similarity index 98% rename from apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/CAgv4ClK.js rename to apps/admin/.output/public/_nuxt/D-lUY2ZC.js index c1ff44c2..84334e2a 100644 --- a/apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/CAgv4ClK.js +++ b/apps/admin/.output/public/_nuxt/D-lUY2ZC.js @@ -1,4 +1,4 @@ -import{g as G,B as K,Q as P,c as a,a as e,d as u,p as x,q as M,F as f,r as U,v as Q,s as Y,t as n,x as i,z as E,o,n as F,l as I,_ as Z}from"./Ccu6Xgpt.js";import{u as J}from"./Um-KoueI.js";import{u as W}from"./DvwKXRUn.js";import"./CH2ZVAK2.js";const X=globalThis.setInterval,$={class:"flex items-center justify-between mb-4 flex-wrap gap-3"},tt={class:"flex items-center gap-2 flex-wrap"},et=["value"],st={class:"flex items-center gap-1 text-xs text-slate-500 cursor-pointer"},lt={class:"flex items-center gap-4 mb-3 text-xs text-slate-500"},nt={class:"text-slate-700"},at={class:"text-slate-700"},ot={class:"text-slate-700"},rt={class:"muted"},ut={class:"panel overflow-hidden"},it={id:"logBody",style:{"max-height":"calc(100vh - 230px)","overflow-y":"auto"}},ct={key:0,class:"text-center text-slate-400 py-10"},dt={key:1,class:"text-center text-red-400 py-10"},vt={key:2,class:"text-center text-slate-400 py-10"},pt={class:"t"},mt={class:"app-name"},ft={key:0,class:"unreg",title:"该应用名未在 console 注册,快照已收到但不会写入统计库"},gt={key:1,class:"muted"},xt={class:"muted"},_t={class:"muted"},yt={class:"muted"},bt={key:0,class:"muted"},ht={class:"t"},wt={key:0,class:"late"},kt=G({__name:"statlog",setup(Ct){const{webApi:A}=J(),{success:O,error:R}=W(),z={cn:"中国",us:"美国",ea:"东亚",sea:"东南亚",sa:"南亚",me:"中东",eu:"欧洲",ru:"俄罗斯",af:"非洲",sam:"南美",nam:"北美",oc:"大洋洲",br:"巴西",in:"印度"};function D(l){return l?z[l]||l:"-"}const c=i([]),_=i(!1),g=i(""),L=i("-"),N=i("-"),y=i(""),v=i(0),b=i(""),h=i(""),w=i(!1);let d=null;function p(l=0){const s=new Date(Date.now()+l*864e5),t=new Intl.DateTimeFormat("en-CA",{timeZone:"Asia/Shanghai",year:"numeric",month:"2-digit",day:"2-digit"}).format(s);return parseInt(t.replace(/-/g,""),10)}function k(l){const s=""+l;return s.length===8?s.slice(0,4)+"-"+s.slice(4,6)+"-"+s.slice(6,8):s}function C(l){if(!l)return"--";const s=new Date(l*1e3),t=r=>r<10?"0"+r:""+r;return t(s.getHours())+":"+t(s.getMinutes())+":"+t(s.getSeconds())}function S(l){return l?"0x"+(l>>>0).toString(16).toUpperCase():"全部"}const V=E(()=>[{value:p(0),label:"今天 "+k(p(0))},{value:p(-1),label:"昨天 "+k(p(-1))}]);function B(l){return l==="error"?{cls:"lv-error",txt:"解析失败"}:l==="warn"?{cls:"lv-warn",txt:"未落库"}:{cls:"lv-info",txt:"已落库"}}function H(l){return!!(l.snap_ts&&l.ts&&l.ts-l.snap_ts>120)}const T=E(()=>{const l=b.value,s=h.value.trim().toLowerCase();return c.value.filter(t=>!(l&&t.level!==l||s&&((t.app||"")+" "+(t.region||"")+" "+D(t.region)+" "+(t.product_id||"")+" "+S(t.product_id)+" "+(t.stat_day||"")).toLowerCase().indexOf(s)<0))});async function m(){_.value=!0,g.value="";try{const l=await A("getstatlogs",{day:v.value||0});c.value=l?.entries||[],L.value=l?.total!=null?l.total:c.value.length,N.value=c.value.length?C(c.value[0].ts):"--"}catch(l){g.value=l?.message||"网络异常"}finally{_.value=!1}}async function j(){const l=v.value||0,s=V.value.find(r=>r.value===l),t=s?s.label:""+l;if(window.confirm("确定清空「"+t+`」的接收流水吗? +import{g as G,B as K,Q as P,c as a,a as e,d as u,p as x,q as M,F as f,r as U,v as Q,s as Y,t as n,x as i,z as E,o,n as F,l as I,_ as Z}from"./mElhLwm2.js";import{u as J}from"./C6twYRfy.js";import{u as W}from"./FVTAbpot.js";import"./qig5Qp6S.js";const X=globalThis.setInterval,$={class:"flex items-center justify-between mb-4 flex-wrap gap-3"},tt={class:"flex items-center gap-2 flex-wrap"},et=["value"],st={class:"flex items-center gap-1 text-xs text-slate-500 cursor-pointer"},lt={class:"flex items-center gap-4 mb-3 text-xs text-slate-500"},nt={class:"text-slate-700"},at={class:"text-slate-700"},ot={class:"text-slate-700"},rt={class:"muted"},ut={class:"panel overflow-hidden"},it={id:"logBody",style:{"max-height":"calc(100vh - 230px)","overflow-y":"auto"}},ct={key:0,class:"text-center text-slate-400 py-10"},dt={key:1,class:"text-center text-red-400 py-10"},vt={key:2,class:"text-center text-slate-400 py-10"},pt={class:"t"},mt={class:"app-name"},ft={key:0,class:"unreg",title:"该应用名未在 console 注册,快照已收到但不会写入统计库"},gt={key:1,class:"muted"},xt={class:"muted"},_t={class:"muted"},yt={class:"muted"},bt={key:0,class:"muted"},ht={class:"t"},wt={key:0,class:"late"},kt=G({__name:"statlog",setup(Ct){const{webApi:A}=J(),{success:O,error:R}=W(),z={cn:"中国",us:"美国",ea:"东亚",sea:"东南亚",sa:"南亚",me:"中东",eu:"欧洲",ru:"俄罗斯",af:"非洲",sam:"南美",nam:"北美",oc:"大洋洲",br:"巴西",in:"印度"};function D(l){return l?z[l]||l:"-"}const c=i([]),_=i(!1),g=i(""),L=i("-"),N=i("-"),y=i(""),v=i(0),b=i(""),h=i(""),w=i(!1);let d=null;function p(l=0){const s=new Date(Date.now()+l*864e5),t=new Intl.DateTimeFormat("en-CA",{timeZone:"Asia/Shanghai",year:"numeric",month:"2-digit",day:"2-digit"}).format(s);return parseInt(t.replace(/-/g,""),10)}function k(l){const s=""+l;return s.length===8?s.slice(0,4)+"-"+s.slice(4,6)+"-"+s.slice(6,8):s}function C(l){if(!l)return"--";const s=new Date(l*1e3),t=r=>r<10?"0"+r:""+r;return t(s.getHours())+":"+t(s.getMinutes())+":"+t(s.getSeconds())}function S(l){return l?"0x"+(l>>>0).toString(16).toUpperCase():"全部"}const V=E(()=>[{value:p(0),label:"今天 "+k(p(0))},{value:p(-1),label:"昨天 "+k(p(-1))}]);function B(l){return l==="error"?{cls:"lv-error",txt:"解析失败"}:l==="warn"?{cls:"lv-warn",txt:"未落库"}:{cls:"lv-info",txt:"已落库"}}function H(l){return!!(l.snap_ts&&l.ts&&l.ts-l.snap_ts>120)}const T=E(()=>{const l=b.value,s=h.value.trim().toLowerCase();return c.value.filter(t=>!(l&&t.level!==l||s&&((t.app||"")+" "+(t.region||"")+" "+D(t.region)+" "+(t.product_id||"")+" "+S(t.product_id)+" "+(t.stat_day||"")).toLowerCase().indexOf(s)<0))});async function m(){_.value=!0,g.value="";try{const l=await A("getstatlogs",{day:v.value||0});c.value=l?.entries||[],L.value=l?.total!=null?l.total:c.value.length,N.value=c.value.length?C(c.value[0].ts):"--"}catch(l){g.value=l?.message||"网络异常"}finally{_.value=!1}}async function j(){const l=v.value||0,s=V.value.find(r=>r.value===l),t=s?s.label:""+l;if(window.confirm("确定清空「"+t+`」的接收流水吗? 只清除本核对面板的记录,不影响已落库的统计数据。 清空后可重新触发埋点,观察是否正常进来。`))try{const r=await A("clearstatlogs",{day:l});O("已清空 "+(r&&r.cleared!=null?r.cleared:0)+" 条"),m()}catch(r){R("清空失败:"+(r?.message||"网络异常"))}}function q(){w.value?(d=X(m,15e3),y.value="· 每 15 秒自动刷新"):(d&&clearInterval(d),d=null,y.value="")}return K(()=>{v.value=p(0),m()}),P(()=>{d&&clearInterval(d)}),(l,s)=>(o(),a("div",null,[e("div",$,[s[6]||(s[6]=e("div",null,[e("h2",{class:"text-lg font-bold text-slate-700"},"统计日志"),e("p",{class:"text-xs text-slate-400 mt-0.5"},[u("console 从 NATS 收到的「当日统计快照」接收流水(最新在前,按接收时间分天存 Redis)。各业务部署每个同步周期/启动时/0点 推送一次当日绝对快照,console 收到后覆盖落库。用于核对每个部署是否在正常汇报;带 "),e("span",{class:"unreg"},"未注册"),u(" 的应用快照已收到但"),e("b",null,"不会落库"),u("(应用名需与 console 注册表完全一致)。")])],-1)),e("div",tt,[x(e("select",{"onUpdate:modelValue":s[0]||(s[0]=t=>v.value=t),class:"select select-bordered select-sm",onChange:m},[(o(!0),a(f,null,U(V.value,t=>(o(),a("option",{key:t.value,value:t.value},n(t.label),9,et))),128))],544),[[M,v.value,void 0,{number:!0}]]),x(e("select",{"onUpdate:modelValue":s[1]||(s[1]=t=>b.value=t),class:"select select-bordered select-sm"},[...s[4]||(s[4]=[e("option",{value:""},"全部级别",-1),e("option",{value:"info"},"已落库",-1),e("option",{value:"warn"},"未落库",-1),e("option",{value:"error"},"解析失败",-1)])],512),[[M,b.value]]),x(e("input",{"onUpdate:modelValue":s[2]||(s[2]=t=>h.value=t),class:"input input-bordered input-sm w-44",placeholder:"筛选 应用/区域/产品"},null,512),[[Q,h.value]]),e("label",st,[x(e("input",{"onUpdate:modelValue":s[3]||(s[3]=t=>w.value=t),type:"checkbox",class:"checkbox checkbox-xs",onChange:q},null,544),[[Y,w.value]]),s[5]||(s[5]=u(" 自动刷新 ",-1))]),e("button",{class:"btn btn-primary btn-sm text-white",onClick:m},"刷新"),e("button",{class:"btn btn-outline btn-error btn-sm",title:"清空本日核对流水(不影响已落库的统计数据),清空后可重新观察埋点是否正常进来",onClick:j},"清空本日")])]),e("div",lt,[e("span",null,[s[7]||(s[7]=u("该日保留 ",-1)),e("b",nt,n(L.value),1),s[8]||(s[8]=u(" 条",-1))]),e("span",null,[s[9]||(s[9]=u("当前显示 ",-1)),e("b",at,n(T.value.length),1),s[10]||(s[10]=u(" 条",-1))]),e("span",null,[s[11]||(s[11]=u("最近接收 ",-1)),e("b",ot,n(N.value),1)]),e("span",rt,n(y.value),1)]),e("div",ut,[s[12]||(s[12]=e("div",{id:"logHead"},[e("div",null,"接收时间"),e("div",null,"级别"),e("div",null,"应用 · 区域 · 产品"),e("div",null,"统计日"),e("div",null,"指标摘要 / 说明"),e("div",null,"快照时间")],-1)),e("div",it,[_.value?(o(),a("div",ct,"加载中...")):g.value?(o(),a("div",dt,"加载失败:"+n(g.value),1)):T.value.length?(o(!0),a(f,{key:3},U(T.value,(t,r)=>(o(),a("div",{key:r,class:"logrow"},[e("div",pt,n(C(t.ts)),1),e("div",null,[e("span",{class:F(["lv",B(t.level).cls])},n(B(t.level).txt),3)]),e("div",null,[t.app?(o(),a(f,{key:0},[e("span",mt,n(t.app),1),t.registered?I("",!0):(o(),a("span",ft,"未注册"))],64)):(o(),a("span",gt,"(无应用名)")),e("span",xt," · "+n(D(t.region)),1),e("span",_t," · "+n(S(t.product_id)),1)]),e("div",yt,n(t.stat_day?k(t.stat_day):"-"),1),e("div",null,[t.msg?(o(),a(f,{key:0},[e("span",{class:F(t.level==="error"?"text-red-600":"text-amber-600")},n(t.msg),3),t.summary?(o(),a("span",bt," · "+n(t.summary),1)):I("",!0)],64)):(o(),a(f,{key:1},[u(n(t.summary||"无增量"),1)],64))]),e("div",ht,[u(n(C(t.snap_ts)),1),H(t)?(o(),a("span",wt,"迟到"+n(t.ts-t.snap_ts)+"s",1)):I("",!0)])]))),128)):(o(),a("div",vt,n(c.value.length?"无匹配记录":"该日暂无接收记录"),1))])])]))}}),Lt=Z(kt,[["__scopeId","data-v-742ee359"]]);export{Lt as default}; diff --git a/apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/DdRUm5PD.js b/apps/admin/.output/public/_nuxt/DACw1I5K.js similarity index 98% rename from apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/DdRUm5PD.js rename to apps/admin/.output/public/_nuxt/DACw1I5K.js index c9f05c93..82b72fce 100644 --- a/apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/DdRUm5PD.js +++ b/apps/admin/.output/public/_nuxt/DACw1I5K.js @@ -1 +1 @@ -import{g as at,E as it,B as dt,c as l,p as r,H as C,a as s,l as L,F as v,r as g,t as u,v as _,q as K,G as B,J as G,K as ut,M as rt,d as m,x as b,y as R,o,n as pt,s as j,_ as ct}from"./Ccu6Xgpt.js";import{u as mt}from"./Um-KoueI.js";import{u as bt}from"./DvwKXRUn.js";import"./CH2ZVAK2.js";const xt={class:"flex items-center justify-between mb-4"},vt={class:"bg-white rounded-xl shadow-sm border border-slate-100 overflow-hidden"},ft={class:"table table-sm"},yt={key:0},gt={key:1},kt={class:"font-mono"},wt={class:"font-medium"},_t={key:0,class:"text-green-600 text-xs"},ht={key:1,class:"text-slate-400 text-xs"},Ct={key:0,class:"text-xs text-slate-500"},St={key:1,class:"text-xs text-slate-300"},Vt={key:0,class:"text-xs text-slate-500"},Ut={key:1,class:"text-xs text-slate-300"},Et={key:2,class:"text-xs text-slate-300"},It={key:3,class:"text-[11px] text-emerald-600 mt-0.5"},$t={class:"text-xs text-slate-500"},Mt={class:"flex gap-1 justify-end"},Nt=["onClick"],At=["onClick"],Lt=["onClick"],jt=["onClick"],Dt={class:"flex items-center gap-3 mb-5"},Pt={class:"text-lg font-semibold text-slate-800"},Tt={class:"bg-white rounded-xl shadow-sm border border-slate-100 p-6 max-w-2xl"},Ot={class:"grid grid-cols-2 gap-3"},Bt=["disabled"],Gt={class:"col-span-2"},Rt={class:"mt-4 border-t border-slate-100 pt-4"},Ft={class:"flex items-center justify-between mb-1"},qt={class:"flex gap-1"},zt={class:"text-xs text-slate-500 mb-1.5"},Ht={key:0,class:"text-amber-500 ml-1"},Jt={class:"flex flex-wrap gap-2"},Kt=["value"],Qt={class:"mt-4 border-t border-slate-100 pt-4"},Wt={class:"mb-3"},Xt={class:"flex flex-wrap gap-2"},Yt=["value"],Zt={key:1,class:"text-xs text-slate-300"},ts={class:"mb-3"},ss={class:"flex flex-wrap gap-2"},es=["value"],ns={class:"max-h-56 overflow-y-auto pr-1 border border-slate-100 rounded-lg p-2"},ls={key:0,class:"text-xs text-slate-300"},os={key:1,class:"text-xs text-slate-300"},as={class:"text-[11px] font-semibold text-slate-500 mb-1 sticky top-0 bg-white py-0.5"},is={class:"flex flex-wrap gap-2"},ds=["value"],us={class:"flex gap-3 justify-end mt-6"},rs=["disabled"],ps={class:"modal-box max-w-md"},cs={class:"text-xs text-slate-400 mb-3"},ms={class:"font-medium text-slate-600"},bs={class:"text-emerald-600"},xs={class:"grid grid-cols-3 gap-3"},vs={class:"modal-action"},fs=at({__name:"accounts",setup(ys){const{webApi:F,consoleApi:f}=mt(),{success:S,error:k,warn:Q}=bt(),W={1:"超管",2:"管理员",3:"代理",4:"运营"},X={1:"badge-error",2:"badge-primary",3:"badge-warning",4:"badge-info"},Y=[["cn","中国"],["us","美国"],["ea","东亚"],["sea","东南亚"],["sa","南亚"],["me","中东"],["eu","欧洲"],["ru","俄罗斯"],["af","非洲"],["sam","南美"],["nam","北美"],["oc","大洋洲"],["br","巴西"],["in","印度"]],V=b("list"),U=b([]),E=b([]),D=b(!1),I=b(!1),y=b(0),a=R({username:"",password:"",identity:2,enabled:"1",remark:""}),i=R({access:[],apps:[],regions:[],products:[]}),h=b([]),P=b(!1);function x(n){return(n||"").split(",").map(t=>t.trim()).filter(t=>t)}function $(n){return n.join(",")}function q(n){const t=[];return n.apps&&t.push("应用:"+x(n.apps).length),n.regions&&t.push("区域:"+x(n.regions).length),n.products&&t.push("产品:"+x(n.products).length),n.access&&t.push("页面:"+x(n.access).length),t}async function M(){D.value=!0;try{try{E.value=await f("apps/list",{})??[]}catch{E.value=[]}const n=await f("accounts/list",{});U.value=n??[]}catch(n){k(n?.message??"获取账号列表失败"),U.value=[]}finally{D.value=!1}}async function Z(){P.value=!0,h.value=[];try{const[n,t]=await Promise.all([F("getbrands",{}),F("getproducts",{})]),e=n?.brands??[],d=t?.products??[],w={};e.forEach(c=>{w[c.id]=c.brand||"品牌商#"+c.id});const N={};d.forEach(c=>{const A=String(c.brandid||0);(N[A]=N[A]||[]).push(c)});const ot=Object.keys(N).sort((c,A)=>(parseInt(c)||0)-(parseInt(A)||0));h.value=ot.map(c=>({fid:c,label:w[c]||(parseInt(c)?"品牌商#"+c:"未分组"),products:N[c]??[]}))}catch{h.value=[]}finally{P.value=!1}}function z(n){y.value=n?n.id:0,a.username=n&&n.username||"",a.password="",a.identity=n?n.identity:2,a.enabled=n&&!n.enabled?"0":"1",a.remark=n&&n.remark||"",i.access=x(n?.access),a.identity===2&&!i.access.length&&(i.access=G.slice()),i.apps=x(n?.apps),i.regions=x(n?.regions),i.products=x(n?.products),Z(),V.value="form"}it(()=>a.identity,n=>{n===2&&i.access.length===0&&(i.access=G.slice())});function T(){V.value="list",M()}async function tt(){const n=a.identity,t={identity:n,enabled:a.enabled==="1",remark:a.remark.trim(),access:"",apps:"",regions:"",products:""};n!==1&&(t.access=$(i.access)),(n===3||n===4)&&(t.apps=$(i.apps),t.regions=$(i.regions),t.products=$(i.products)),I.value=!0;try{if(y.value)t.id=y.value,await f("accounts/update",t);else{if(t.username=a.username.trim(),t.password=a.password,!t.username||!t.password){k("用户名和密码必填"),I.value=!1;return}await f("accounts/add",t)}S("已保存"),T()}catch(e){k(e?.message??"保存失败")}finally{I.value=!1}}async function st(n,t){const e=window.prompt("为账号【"+t+"】设置新密码:");if(e)try{await f("accounts/resetpwd",{id:n,password:e}),S("密码已重置")}catch(d){k(d?.message??"失败")}}function et(n,t){window.confirm("确认删除账号【"+t+"】?该操作不可恢复。")&&f("accounts/del",{id:n}).then(()=>{S("已删除"),M()}).catch(e=>k(e?.message??"失败"))}const O=b(null),H=b(0),p=R({name:"",cur:"",vipday:0,trademin:0,meetmin:0});function nt(n){H.value=n.id,p.name=n.username||"#"+n.id,p.cur="VIP"+(n.balance_vipday||0)+"天 · 翻译"+(n.balance_trademin||0)+"分 · 会议"+(n.balance_meetmin||0)+"分",p.vipday=0,p.trademin=0,p.meetmin=0,O.value?.showModal()}function J(){O.value?.close()}async function lt(){const n=Number(p.vipday)||0,t=Number(p.trademin)||0,e=Number(p.meetmin)||0;if(!n&&!t&&!e){Q("请至少填写一项");return}try{await f("accounts/topup",{account_id:H.value,vipday:n,trademin:t,meetmin:e}),S("余额已更新"),J(),M()}catch(d){k(d?.message??"操作失败")}}return dt(M),(n,t)=>(o(),l("div",null,[r(s("div",null,[s("div",xt,[t[21]||(t[21]=s("div",null,[s("h2",{class:"text-lg font-bold text-slate-700"},"后台账号"),s("p",{class:"text-xs text-slate-400 mt-0.5"},"超管 / 管理员 / 代理 / 运营。代理·运营可绑定应用·区域·产品,登录后仪表盘按绑定限制。")],-1)),s("button",{class:"btn btn-primary btn-sm text-white",onClick:t[0]||(t[0]=e=>z())},"+ 新建账号")]),s("div",vt,[s("table",ft,[t[24]||(t[24]=s("thead",null,[s("tr",{class:"text-slate-500"},[s("th",null,"ID"),s("th",null,"用户名"),s("th",null,"角色"),s("th",null,"状态"),s("th",null,"绑定作用域"),s("th",null,"备注"),s("th",{class:"text-right"},"操作")])],-1)),s("tbody",null,[D.value?(o(),l("tr",yt,[...t[22]||(t[22]=[s("td",{colspan:"7",class:"text-center text-slate-400 py-8"},"加载中...",-1)])])):U.value.length?L("",!0):(o(),l("tr",gt,[...t[23]||(t[23]=[s("td",{colspan:"7",class:"text-center text-slate-400 py-8"},"暂无账号(引导超管不在此列)",-1)])])),(o(!0),l(v,null,g(U.value,e=>(o(),l("tr",{key:e.id},[s("td",kt,u(e.id),1),s("td",wt,u(e.username||""),1),s("td",null,[s("span",{class:pt(["badge badge-sm",X[e.identity]||""])},u(W[e.identity]||e.identity),3)]),s("td",null,[e.enabled?(o(),l("span",_t,"启用")):(o(),l("span",ht,"停用"))]),s("td",null,[e.identity===3||e.identity===4?(o(),l(v,{key:0},[q(e).length?(o(),l("span",Ct,u(q(e).join(" · ")),1)):(o(),l("span",St,"未绑定(不限)"))],64)):e.identity===2?(o(),l(v,{key:1},[e.access?(o(),l("span",Vt,"菜单:"+u(x(e.access).length),1)):(o(),l("span",Ut,"默认(除SaaS/系统管理)"))],64)):(o(),l("span",Et,"全部权限")),e.identity===3?(o(),l("div",It," 余额 VIP"+u(e.balance_vipday||0)+"天 · 翻译"+u(e.balance_trademin||0)+"分 · 会议"+u(e.balance_meetmin||0)+"分 ",1)):L("",!0)]),s("td",$t,u(e.remark||""),1),s("td",null,[s("div",Mt,[e.identity===3?(o(),l("button",{key:0,class:"btn btn-ghost btn-xs text-emerald-600",onClick:d=>nt(e)},"充值",8,Nt)):L("",!0),s("button",{class:"btn btn-ghost btn-xs",onClick:d=>z(e)},"编辑",8,At),s("button",{class:"btn btn-ghost btn-xs text-amber-600",onClick:d=>st(e.id,e.username)},"改密",8,Lt),s("button",{class:"btn btn-ghost btn-xs text-red-500",onClick:d=>et(e.id,e.username)},"删除",8,jt)])])]))),128))])])])],512),[[C,V.value==="list"]]),r(s("div",null,[s("div",Dt,[s("button",{class:"btn btn-ghost btn-sm",onClick:t[1]||(t[1]=e=>T())},"← 返回列表"),s("h2",Pt,u(y.value?"编辑账号 #"+y.value:"新建账号"),1)]),s("div",Tt,[s("div",Ot,[s("div",null,[t[25]||(t[25]=s("label",{class:"text-xs text-slate-500"},"用户名",-1)),r(s("input",{"onUpdate:modelValue":t[2]||(t[2]=e=>a.username=e),disabled:!!y.value,class:"input input-bordered input-sm w-full",placeholder:"登录用户名"},null,8,Bt),[[_,a.username]])]),r(s("div",null,[t[26]||(t[26]=s("label",{class:"text-xs text-slate-500"},"密码",-1)),r(s("input",{"onUpdate:modelValue":t[3]||(t[3]=e=>a.password=e),type:"password",class:"input input-bordered input-sm w-full",placeholder:"登录密码"},null,512),[[_,a.password]])],512),[[C,!y.value]]),s("div",null,[t[28]||(t[28]=s("label",{class:"text-xs text-slate-500"},"角色",-1)),r(s("select",{"onUpdate:modelValue":t[4]||(t[4]=e=>a.identity=e),class:"select select-bordered select-sm w-full"},[...t[27]||(t[27]=[s("option",{value:2},"管理员(默认除 SaaS/系统管理外全部)",-1),s("option",{value:3},"代理(外部,按绑定限制)",-1),s("option",{value:4},"运营(内部,按绑定限制)",-1),s("option",{value:1},"超管(全部权限)",-1)])],512),[[K,a.identity,void 0,{number:!0}]])]),s("div",null,[t[30]||(t[30]=s("label",{class:"text-xs text-slate-500"},"状态",-1)),r(s("select",{"onUpdate:modelValue":t[5]||(t[5]=e=>a.enabled=e),class:"select select-bordered select-sm w-full"},[...t[29]||(t[29]=[s("option",{value:"1"},"启用",-1),s("option",{value:"0"},"停用",-1)])],512),[[K,a.enabled]])]),s("div",Gt,[t[31]||(t[31]=s("label",{class:"text-xs text-slate-500"},"备注",-1)),r(s("input",{"onUpdate:modelValue":t[6]||(t[6]=e=>a.remark=e),class:"input input-bordered input-sm w-full",placeholder:"可选"},null,512),[[_,a.remark]])])]),r(s("div",Rt,[s("div",Ft,[t[32]||(t[32]=s("div",{class:"text-sm font-semibold text-slate-600"},"菜单权限",-1)),s("div",qt,[s("button",{type:"button",class:"btn btn-ghost btn-xs",onClick:t[7]||(t[7]=e=>i.access=B(G).slice())},"管理员默认"),s("button",{type:"button",class:"btn btn-ghost btn-xs",onClick:t[8]||(t[8]=e=>i.access=B(ut).slice())},"全选"),s("button",{type:"button",class:"btn btn-ghost btn-xs",onClick:t[9]||(t[9]=e=>i.access=[])},"清空")])]),t[33]||(t[33]=s("p",{class:"text-xs text-slate-400 mb-3"},"管理员默认开放除「SaaS 管理 / 系统管理」以外的全部菜单(权限留空时按默认生效);代理/运营需显式勾选。",-1)),(o(!0),l(v,null,g(B(rt),e=>(o(),l("div",{key:e.label,class:"mb-2.5"},[s("div",zt,[m(u(e.label),1),e.restricted?(o(),l("span",Ht,"(管理员默认不开放)")):L("",!0)]),s("div",Jt,[(o(!0),l(v,null,g(e.items,d=>(o(),l("label",{key:d.id,class:"chk"},[r(s("input",{"onUpdate:modelValue":t[10]||(t[10]=w=>i.access=w),type:"checkbox",value:d.id},null,8,Kt),[[j,i.access]]),m(u(d.label),1)]))),128))])]))),128))],512),[[C,a.identity!==1]]),r(s("div",Qt,[t[37]||(t[37]=s("div",{class:"text-sm font-semibold text-slate-600 mb-2"},[m("作用域绑定 "),s("span",{class:"text-xs text-slate-400 font-normal"},"(代理/运营生效;限制仪表盘数据范围)")],-1)),s("div",Wt,[t[34]||(t[34]=s("div",{class:"text-xs text-slate-500 mb-1.5"},[m("绑定应用 "),s("span",{class:"text-slate-300"},"(仪表盘只显示这些应用数据;不勾=不限)")],-1)),s("div",Xt,[E.value.length?(o(!0),l(v,{key:0},g(E.value,e=>(o(),l("label",{key:e.id,class:"chk"},[r(s("input",{"onUpdate:modelValue":t[11]||(t[11]=d=>i.apps=d),type:"checkbox",value:e.name},null,8,Yt),[[j,i.apps]]),m(u(e.name||"应用#"+e.id),1)]))),128)):(o(),l("span",Zt,"无注册应用"))])]),s("div",ts,[t[35]||(t[35]=s("div",{class:"text-xs text-slate-500 mb-1.5"},[m("绑定区域 "),s("span",{class:"text-slate-300"},"(不勾=不限)")],-1)),s("div",ss,[(o(),l(v,null,g(Y,e=>s("label",{key:e[0],class:"chk"},[r(s("input",{"onUpdate:modelValue":t[12]||(t[12]=d=>i.regions=d),type:"checkbox",value:e[0]},null,8,es),[[j,i.regions]]),m(u(e[1]),1)])),64))])]),s("div",null,[t[36]||(t[36]=s("div",{class:"text-xs text-slate-500 mb-1.5"},[m("绑定产品 "),s("span",{class:"text-slate-300"},"(按厂家分组;仪表盘只显示这些产品数据;不勾=不限)")],-1)),s("div",ns,[P.value?(o(),l("span",ls,"加载产品中...")):h.value.length?(o(!0),l(v,{key:2},g(h.value,e=>(o(),l("div",{key:e.fid,class:"mb-2 last:mb-0"},[s("div",as,"🏭 "+u(e.label),1),s("div",is,[(o(!0),l(v,null,g(e.products,d=>(o(),l("label",{key:d.id,class:"chk"},[r(s("input",{"onUpdate:modelValue":t[13]||(t[13]=w=>i.products=w),type:"checkbox",value:String(d.id)},null,8,ds),[[j,i.products]]),m(u((d.devicename||"产品")+" #"+d.id),1)]))),128))])]))),128)):(o(),l("span",os,"无产品"))])])],512),[[C,a.identity===3||a.identity===4]]),s("div",us,[s("button",{class:"btn btn-ghost btn-sm",onClick:t[14]||(t[14]=e=>T())},"取消"),s("button",{class:"btn btn-primary btn-sm text-white",disabled:I.value,onClick:t[15]||(t[15]=e=>tt())},"保存",8,rs)])])],512),[[C,V.value==="form"]]),s("dialog",{ref_key:"topupModal",ref:O,class:"modal"},[s("div",ps,[t[43]||(t[43]=s("h3",{class:"font-bold text-lg mb-1"},"充值 / 调整资源点",-1)),s("p",cs,[t[38]||(t[38]=m("代理:",-1)),s("span",ms,u(p.name),1),t[39]||(t[39]=m("。填增量(可填负数下调),当前余额:",-1)),s("span",bs,u(p.cur),1)]),s("div",xs,[s("div",null,[t[40]||(t[40]=s("label",{class:"text-xs text-slate-500"},"VIP天数",-1)),r(s("input",{"onUpdate:modelValue":t[16]||(t[16]=e=>p.vipday=e),type:"number",class:"input input-bordered input-sm w-full"},null,512),[[_,p.vipday,void 0,{number:!0}]])]),s("div",null,[t[41]||(t[41]=s("label",{class:"text-xs text-slate-500"},"翻译分钟",-1)),r(s("input",{"onUpdate:modelValue":t[17]||(t[17]=e=>p.trademin=e),type:"number",class:"input input-bordered input-sm w-full"},null,512),[[_,p.trademin,void 0,{number:!0}]])]),s("div",null,[t[42]||(t[42]=s("label",{class:"text-xs text-slate-500"},"会议分钟",-1)),r(s("input",{"onUpdate:modelValue":t[18]||(t[18]=e=>p.meetmin=e),type:"number",class:"input input-bordered input-sm w-full"},null,512),[[_,p.meetmin,void 0,{number:!0}]])])]),s("div",vs,[s("button",{class:"btn btn-ghost btn-sm",onClick:t[19]||(t[19]=e=>J())},"取消"),s("button",{class:"btn btn-primary btn-sm text-white",onClick:t[20]||(t[20]=e=>lt())},"确认")])]),t[44]||(t[44]=s("form",{method:"dialog",class:"modal-backdrop"},[s("button",null,"close")],-1))],512)]))}}),hs=ct(fs,[["__scopeId","data-v-06dca20b"]]);export{hs as default}; +import{g as at,E as it,B as dt,c as l,p as r,H as C,a as s,l as L,F as v,r as g,t as u,v as _,q as K,G as B,J as G,K as ut,M as rt,d as m,x as b,y as R,o,n as pt,s as j,_ as ct}from"./mElhLwm2.js";import{u as mt}from"./C6twYRfy.js";import{u as bt}from"./FVTAbpot.js";import"./qig5Qp6S.js";const xt={class:"flex items-center justify-between mb-4"},vt={class:"bg-white rounded-xl shadow-sm border border-slate-100 overflow-hidden"},ft={class:"table table-sm"},yt={key:0},gt={key:1},kt={class:"font-mono"},wt={class:"font-medium"},_t={key:0,class:"text-green-600 text-xs"},ht={key:1,class:"text-slate-400 text-xs"},Ct={key:0,class:"text-xs text-slate-500"},St={key:1,class:"text-xs text-slate-300"},Vt={key:0,class:"text-xs text-slate-500"},Ut={key:1,class:"text-xs text-slate-300"},Et={key:2,class:"text-xs text-slate-300"},It={key:3,class:"text-[11px] text-emerald-600 mt-0.5"},$t={class:"text-xs text-slate-500"},Mt={class:"flex gap-1 justify-end"},Nt=["onClick"],At=["onClick"],Lt=["onClick"],jt=["onClick"],Dt={class:"flex items-center gap-3 mb-5"},Pt={class:"text-lg font-semibold text-slate-800"},Tt={class:"bg-white rounded-xl shadow-sm border border-slate-100 p-6 max-w-2xl"},Ot={class:"grid grid-cols-2 gap-3"},Bt=["disabled"],Gt={class:"col-span-2"},Rt={class:"mt-4 border-t border-slate-100 pt-4"},Ft={class:"flex items-center justify-between mb-1"},qt={class:"flex gap-1"},zt={class:"text-xs text-slate-500 mb-1.5"},Ht={key:0,class:"text-amber-500 ml-1"},Jt={class:"flex flex-wrap gap-2"},Kt=["value"],Qt={class:"mt-4 border-t border-slate-100 pt-4"},Wt={class:"mb-3"},Xt={class:"flex flex-wrap gap-2"},Yt=["value"],Zt={key:1,class:"text-xs text-slate-300"},ts={class:"mb-3"},ss={class:"flex flex-wrap gap-2"},es=["value"],ns={class:"max-h-56 overflow-y-auto pr-1 border border-slate-100 rounded-lg p-2"},ls={key:0,class:"text-xs text-slate-300"},os={key:1,class:"text-xs text-slate-300"},as={class:"text-[11px] font-semibold text-slate-500 mb-1 sticky top-0 bg-white py-0.5"},is={class:"flex flex-wrap gap-2"},ds=["value"],us={class:"flex gap-3 justify-end mt-6"},rs=["disabled"],ps={class:"modal-box max-w-md"},cs={class:"text-xs text-slate-400 mb-3"},ms={class:"font-medium text-slate-600"},bs={class:"text-emerald-600"},xs={class:"grid grid-cols-3 gap-3"},vs={class:"modal-action"},fs=at({__name:"accounts",setup(ys){const{webApi:F,consoleApi:f}=mt(),{success:S,error:k,warn:Q}=bt(),W={1:"超管",2:"管理员",3:"代理",4:"运营"},X={1:"badge-error",2:"badge-primary",3:"badge-warning",4:"badge-info"},Y=[["cn","中国"],["us","美国"],["ea","东亚"],["sea","东南亚"],["sa","南亚"],["me","中东"],["eu","欧洲"],["ru","俄罗斯"],["af","非洲"],["sam","南美"],["nam","北美"],["oc","大洋洲"],["br","巴西"],["in","印度"]],V=b("list"),U=b([]),E=b([]),D=b(!1),I=b(!1),y=b(0),a=R({username:"",password:"",identity:2,enabled:"1",remark:""}),i=R({access:[],apps:[],regions:[],products:[]}),h=b([]),P=b(!1);function x(n){return(n||"").split(",").map(t=>t.trim()).filter(t=>t)}function $(n){return n.join(",")}function q(n){const t=[];return n.apps&&t.push("应用:"+x(n.apps).length),n.regions&&t.push("区域:"+x(n.regions).length),n.products&&t.push("产品:"+x(n.products).length),n.access&&t.push("页面:"+x(n.access).length),t}async function M(){D.value=!0;try{try{E.value=await f("apps/list",{})??[]}catch{E.value=[]}const n=await f("accounts/list",{});U.value=n??[]}catch(n){k(n?.message??"获取账号列表失败"),U.value=[]}finally{D.value=!1}}async function Z(){P.value=!0,h.value=[];try{const[n,t]=await Promise.all([F("getbrands",{}),F("getproducts",{})]),e=n?.brands??[],d=t?.products??[],w={};e.forEach(c=>{w[c.id]=c.brand||"品牌商#"+c.id});const N={};d.forEach(c=>{const A=String(c.brandid||0);(N[A]=N[A]||[]).push(c)});const ot=Object.keys(N).sort((c,A)=>(parseInt(c)||0)-(parseInt(A)||0));h.value=ot.map(c=>({fid:c,label:w[c]||(parseInt(c)?"品牌商#"+c:"未分组"),products:N[c]??[]}))}catch{h.value=[]}finally{P.value=!1}}function z(n){y.value=n?n.id:0,a.username=n&&n.username||"",a.password="",a.identity=n?n.identity:2,a.enabled=n&&!n.enabled?"0":"1",a.remark=n&&n.remark||"",i.access=x(n?.access),a.identity===2&&!i.access.length&&(i.access=G.slice()),i.apps=x(n?.apps),i.regions=x(n?.regions),i.products=x(n?.products),Z(),V.value="form"}it(()=>a.identity,n=>{n===2&&i.access.length===0&&(i.access=G.slice())});function T(){V.value="list",M()}async function tt(){const n=a.identity,t={identity:n,enabled:a.enabled==="1",remark:a.remark.trim(),access:"",apps:"",regions:"",products:""};n!==1&&(t.access=$(i.access)),(n===3||n===4)&&(t.apps=$(i.apps),t.regions=$(i.regions),t.products=$(i.products)),I.value=!0;try{if(y.value)t.id=y.value,await f("accounts/update",t);else{if(t.username=a.username.trim(),t.password=a.password,!t.username||!t.password){k("用户名和密码必填"),I.value=!1;return}await f("accounts/add",t)}S("已保存"),T()}catch(e){k(e?.message??"保存失败")}finally{I.value=!1}}async function st(n,t){const e=window.prompt("为账号【"+t+"】设置新密码:");if(e)try{await f("accounts/resetpwd",{id:n,password:e}),S("密码已重置")}catch(d){k(d?.message??"失败")}}function et(n,t){window.confirm("确认删除账号【"+t+"】?该操作不可恢复。")&&f("accounts/del",{id:n}).then(()=>{S("已删除"),M()}).catch(e=>k(e?.message??"失败"))}const O=b(null),H=b(0),p=R({name:"",cur:"",vipday:0,trademin:0,meetmin:0});function nt(n){H.value=n.id,p.name=n.username||"#"+n.id,p.cur="VIP"+(n.balance_vipday||0)+"天 · 翻译"+(n.balance_trademin||0)+"分 · 会议"+(n.balance_meetmin||0)+"分",p.vipday=0,p.trademin=0,p.meetmin=0,O.value?.showModal()}function J(){O.value?.close()}async function lt(){const n=Number(p.vipday)||0,t=Number(p.trademin)||0,e=Number(p.meetmin)||0;if(!n&&!t&&!e){Q("请至少填写一项");return}try{await f("accounts/topup",{account_id:H.value,vipday:n,trademin:t,meetmin:e}),S("余额已更新"),J(),M()}catch(d){k(d?.message??"操作失败")}}return dt(M),(n,t)=>(o(),l("div",null,[r(s("div",null,[s("div",xt,[t[21]||(t[21]=s("div",null,[s("h2",{class:"text-lg font-bold text-slate-700"},"后台账号"),s("p",{class:"text-xs text-slate-400 mt-0.5"},"超管 / 管理员 / 代理 / 运营。代理·运营可绑定应用·区域·产品,登录后仪表盘按绑定限制。")],-1)),s("button",{class:"btn btn-primary btn-sm text-white",onClick:t[0]||(t[0]=e=>z())},"+ 新建账号")]),s("div",vt,[s("table",ft,[t[24]||(t[24]=s("thead",null,[s("tr",{class:"text-slate-500"},[s("th",null,"ID"),s("th",null,"用户名"),s("th",null,"角色"),s("th",null,"状态"),s("th",null,"绑定作用域"),s("th",null,"备注"),s("th",{class:"text-right"},"操作")])],-1)),s("tbody",null,[D.value?(o(),l("tr",yt,[...t[22]||(t[22]=[s("td",{colspan:"7",class:"text-center text-slate-400 py-8"},"加载中...",-1)])])):U.value.length?L("",!0):(o(),l("tr",gt,[...t[23]||(t[23]=[s("td",{colspan:"7",class:"text-center text-slate-400 py-8"},"暂无账号(引导超管不在此列)",-1)])])),(o(!0),l(v,null,g(U.value,e=>(o(),l("tr",{key:e.id},[s("td",kt,u(e.id),1),s("td",wt,u(e.username||""),1),s("td",null,[s("span",{class:pt(["badge badge-sm",X[e.identity]||""])},u(W[e.identity]||e.identity),3)]),s("td",null,[e.enabled?(o(),l("span",_t,"启用")):(o(),l("span",ht,"停用"))]),s("td",null,[e.identity===3||e.identity===4?(o(),l(v,{key:0},[q(e).length?(o(),l("span",Ct,u(q(e).join(" · ")),1)):(o(),l("span",St,"未绑定(不限)"))],64)):e.identity===2?(o(),l(v,{key:1},[e.access?(o(),l("span",Vt,"菜单:"+u(x(e.access).length),1)):(o(),l("span",Ut,"默认(除SaaS/系统管理)"))],64)):(o(),l("span",Et,"全部权限")),e.identity===3?(o(),l("div",It," 余额 VIP"+u(e.balance_vipday||0)+"天 · 翻译"+u(e.balance_trademin||0)+"分 · 会议"+u(e.balance_meetmin||0)+"分 ",1)):L("",!0)]),s("td",$t,u(e.remark||""),1),s("td",null,[s("div",Mt,[e.identity===3?(o(),l("button",{key:0,class:"btn btn-ghost btn-xs text-emerald-600",onClick:d=>nt(e)},"充值",8,Nt)):L("",!0),s("button",{class:"btn btn-ghost btn-xs",onClick:d=>z(e)},"编辑",8,At),s("button",{class:"btn btn-ghost btn-xs text-amber-600",onClick:d=>st(e.id,e.username)},"改密",8,Lt),s("button",{class:"btn btn-ghost btn-xs text-red-500",onClick:d=>et(e.id,e.username)},"删除",8,jt)])])]))),128))])])])],512),[[C,V.value==="list"]]),r(s("div",null,[s("div",Dt,[s("button",{class:"btn btn-ghost btn-sm",onClick:t[1]||(t[1]=e=>T())},"← 返回列表"),s("h2",Pt,u(y.value?"编辑账号 #"+y.value:"新建账号"),1)]),s("div",Tt,[s("div",Ot,[s("div",null,[t[25]||(t[25]=s("label",{class:"text-xs text-slate-500"},"用户名",-1)),r(s("input",{"onUpdate:modelValue":t[2]||(t[2]=e=>a.username=e),disabled:!!y.value,class:"input input-bordered input-sm w-full",placeholder:"登录用户名"},null,8,Bt),[[_,a.username]])]),r(s("div",null,[t[26]||(t[26]=s("label",{class:"text-xs text-slate-500"},"密码",-1)),r(s("input",{"onUpdate:modelValue":t[3]||(t[3]=e=>a.password=e),type:"password",class:"input input-bordered input-sm w-full",placeholder:"登录密码"},null,512),[[_,a.password]])],512),[[C,!y.value]]),s("div",null,[t[28]||(t[28]=s("label",{class:"text-xs text-slate-500"},"角色",-1)),r(s("select",{"onUpdate:modelValue":t[4]||(t[4]=e=>a.identity=e),class:"select select-bordered select-sm w-full"},[...t[27]||(t[27]=[s("option",{value:2},"管理员(默认除 SaaS/系统管理外全部)",-1),s("option",{value:3},"代理(外部,按绑定限制)",-1),s("option",{value:4},"运营(内部,按绑定限制)",-1),s("option",{value:1},"超管(全部权限)",-1)])],512),[[K,a.identity,void 0,{number:!0}]])]),s("div",null,[t[30]||(t[30]=s("label",{class:"text-xs text-slate-500"},"状态",-1)),r(s("select",{"onUpdate:modelValue":t[5]||(t[5]=e=>a.enabled=e),class:"select select-bordered select-sm w-full"},[...t[29]||(t[29]=[s("option",{value:"1"},"启用",-1),s("option",{value:"0"},"停用",-1)])],512),[[K,a.enabled]])]),s("div",Gt,[t[31]||(t[31]=s("label",{class:"text-xs text-slate-500"},"备注",-1)),r(s("input",{"onUpdate:modelValue":t[6]||(t[6]=e=>a.remark=e),class:"input input-bordered input-sm w-full",placeholder:"可选"},null,512),[[_,a.remark]])])]),r(s("div",Rt,[s("div",Ft,[t[32]||(t[32]=s("div",{class:"text-sm font-semibold text-slate-600"},"菜单权限",-1)),s("div",qt,[s("button",{type:"button",class:"btn btn-ghost btn-xs",onClick:t[7]||(t[7]=e=>i.access=B(G).slice())},"管理员默认"),s("button",{type:"button",class:"btn btn-ghost btn-xs",onClick:t[8]||(t[8]=e=>i.access=B(ut).slice())},"全选"),s("button",{type:"button",class:"btn btn-ghost btn-xs",onClick:t[9]||(t[9]=e=>i.access=[])},"清空")])]),t[33]||(t[33]=s("p",{class:"text-xs text-slate-400 mb-3"},"管理员默认开放除「SaaS 管理 / 系统管理」以外的全部菜单(权限留空时按默认生效);代理/运营需显式勾选。",-1)),(o(!0),l(v,null,g(B(rt),e=>(o(),l("div",{key:e.label,class:"mb-2.5"},[s("div",zt,[m(u(e.label),1),e.restricted?(o(),l("span",Ht,"(管理员默认不开放)")):L("",!0)]),s("div",Jt,[(o(!0),l(v,null,g(e.items,d=>(o(),l("label",{key:d.id,class:"chk"},[r(s("input",{"onUpdate:modelValue":t[10]||(t[10]=w=>i.access=w),type:"checkbox",value:d.id},null,8,Kt),[[j,i.access]]),m(u(d.label),1)]))),128))])]))),128))],512),[[C,a.identity!==1]]),r(s("div",Qt,[t[37]||(t[37]=s("div",{class:"text-sm font-semibold text-slate-600 mb-2"},[m("作用域绑定 "),s("span",{class:"text-xs text-slate-400 font-normal"},"(代理/运营生效;限制仪表盘数据范围)")],-1)),s("div",Wt,[t[34]||(t[34]=s("div",{class:"text-xs text-slate-500 mb-1.5"},[m("绑定应用 "),s("span",{class:"text-slate-300"},"(仪表盘只显示这些应用数据;不勾=不限)")],-1)),s("div",Xt,[E.value.length?(o(!0),l(v,{key:0},g(E.value,e=>(o(),l("label",{key:e.id,class:"chk"},[r(s("input",{"onUpdate:modelValue":t[11]||(t[11]=d=>i.apps=d),type:"checkbox",value:e.name},null,8,Yt),[[j,i.apps]]),m(u(e.name||"应用#"+e.id),1)]))),128)):(o(),l("span",Zt,"无注册应用"))])]),s("div",ts,[t[35]||(t[35]=s("div",{class:"text-xs text-slate-500 mb-1.5"},[m("绑定区域 "),s("span",{class:"text-slate-300"},"(不勾=不限)")],-1)),s("div",ss,[(o(),l(v,null,g(Y,e=>s("label",{key:e[0],class:"chk"},[r(s("input",{"onUpdate:modelValue":t[12]||(t[12]=d=>i.regions=d),type:"checkbox",value:e[0]},null,8,es),[[j,i.regions]]),m(u(e[1]),1)])),64))])]),s("div",null,[t[36]||(t[36]=s("div",{class:"text-xs text-slate-500 mb-1.5"},[m("绑定产品 "),s("span",{class:"text-slate-300"},"(按厂家分组;仪表盘只显示这些产品数据;不勾=不限)")],-1)),s("div",ns,[P.value?(o(),l("span",ls,"加载产品中...")):h.value.length?(o(!0),l(v,{key:2},g(h.value,e=>(o(),l("div",{key:e.fid,class:"mb-2 last:mb-0"},[s("div",as,"🏭 "+u(e.label),1),s("div",is,[(o(!0),l(v,null,g(e.products,d=>(o(),l("label",{key:d.id,class:"chk"},[r(s("input",{"onUpdate:modelValue":t[13]||(t[13]=w=>i.products=w),type:"checkbox",value:String(d.id)},null,8,ds),[[j,i.products]]),m(u((d.devicename||"产品")+" #"+d.id),1)]))),128))])]))),128)):(o(),l("span",os,"无产品"))])])],512),[[C,a.identity===3||a.identity===4]]),s("div",us,[s("button",{class:"btn btn-ghost btn-sm",onClick:t[14]||(t[14]=e=>T())},"取消"),s("button",{class:"btn btn-primary btn-sm text-white",disabled:I.value,onClick:t[15]||(t[15]=e=>tt())},"保存",8,rs)])])],512),[[C,V.value==="form"]]),s("dialog",{ref_key:"topupModal",ref:O,class:"modal"},[s("div",ps,[t[43]||(t[43]=s("h3",{class:"font-bold text-lg mb-1"},"充值 / 调整资源点",-1)),s("p",cs,[t[38]||(t[38]=m("代理:",-1)),s("span",ms,u(p.name),1),t[39]||(t[39]=m("。填增量(可填负数下调),当前余额:",-1)),s("span",bs,u(p.cur),1)]),s("div",xs,[s("div",null,[t[40]||(t[40]=s("label",{class:"text-xs text-slate-500"},"VIP天数",-1)),r(s("input",{"onUpdate:modelValue":t[16]||(t[16]=e=>p.vipday=e),type:"number",class:"input input-bordered input-sm w-full"},null,512),[[_,p.vipday,void 0,{number:!0}]])]),s("div",null,[t[41]||(t[41]=s("label",{class:"text-xs text-slate-500"},"翻译分钟",-1)),r(s("input",{"onUpdate:modelValue":t[17]||(t[17]=e=>p.trademin=e),type:"number",class:"input input-bordered input-sm w-full"},null,512),[[_,p.trademin,void 0,{number:!0}]])]),s("div",null,[t[42]||(t[42]=s("label",{class:"text-xs text-slate-500"},"会议分钟",-1)),r(s("input",{"onUpdate:modelValue":t[18]||(t[18]=e=>p.meetmin=e),type:"number",class:"input input-bordered input-sm w-full"},null,512),[[_,p.meetmin,void 0,{number:!0}]])])]),s("div",vs,[s("button",{class:"btn btn-ghost btn-sm",onClick:t[19]||(t[19]=e=>J())},"取消"),s("button",{class:"btn btn-primary btn-sm text-white",onClick:t[20]||(t[20]=e=>lt())},"确认")])]),t[44]||(t[44]=s("form",{method:"dialog",class:"modal-backdrop"},[s("button",null,"close")],-1))],512)]))}}),hs=ct(fs,[["__scopeId","data-v-06dca20b"]]);export{hs as default}; diff --git a/apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/Sgx9LvLK.js b/apps/admin/.output/public/_nuxt/DG0IG_4u.js similarity index 99% rename from apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/Sgx9LvLK.js rename to apps/admin/.output/public/_nuxt/DG0IG_4u.js index 7dfa80e2..204836f4 100644 --- a/apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/Sgx9LvLK.js +++ b/apps/admin/.output/public/_nuxt/DG0IG_4u.js @@ -1 +1 @@ -import{g as W,B as X,c as r,a as t,p as a,q as Q,F,r as N,H as T,t as l,l as Z,m as tt,v as b,s as et,x as i,y as B,o as u}from"./Ccu6Xgpt.js";import{u as st}from"./Um-KoueI.js";import{u as nt}from"./DvwKXRUn.js";import"./CH2ZVAK2.js";const ot={class:"space-y-6"},lt={class:"bg-white rounded-xl shadow-sm border border-slate-100 p-4"},at={class:"flex items-end gap-3 flex-wrap"},dt={class:"form-control"},rt=["value"],it={class:"form-control"},ut=["disabled"],ct={class:"bg-white rounded-xl shadow-sm border border-slate-100"},mt={class:"overflow-x-auto"},bt={class:"table table-zebra"},pt={key:0},vt={key:1},ft={colspan:"9",class:"text-center text-slate-400 py-8"},xt={class:"font-mono text-base font-bold text-indigo-700"},gt={class:"text-sm"},wt={class:"text-sm"},ht={class:"text-sm text-slate-500"},yt={class:"text-sm"},kt={class:"text-sm"},_t={class:"text-sm"},Ct={key:0,class:"badge badge-success badge-sm text-white"},Vt={key:1,class:"badge badge-ghost badge-sm"},Mt={class:"flex gap-1"},Ut=["onClick"],Dt=["onClick"],Qt=["onClick"],Ft=["onClick"],Nt={class:"flex items-center gap-3 mb-5"},Tt={class:"text-lg font-semibold text-slate-800"},qt={class:"bg-white rounded-xl shadow-sm border border-slate-100 p-6 max-w-2xl"},Lt={class:"form-control mb-4"},St=["value"],Bt={class:"form-control mb-4"},Et={class:"grid grid-cols-3 gap-3 mb-4"},$t={class:"form-control"},Rt={class:"form-control"},jt={class:"form-control"},It={class:"grid grid-cols-2 gap-3 mb-4"},Ht={class:"form-control"},Pt={class:"form-control"},zt={class:"form-control mb-6"},At={class:"label cursor-pointer justify-start gap-3"},Yt={class:"modal-box max-w-md"},Gt={class:"flex flex-col items-center gap-4"},Jt={class:"text-center"},Kt={class:"font-mono text-2xl font-bold text-indigo-700 tracking-widest"},Ot="https://cdn.jsdelivr.net/gh/davidshimjs/qrcodejs/qrcode.min.js",se=W({__name:"code",setup(Wt){const{webApi:c}=st(),{success:g,error:p,warn:w}=nt(),h=i("list"),C=i(!1),v=i(!1),m=i(0),V=i(-1),y=i([]),M=i([]),k=i([]),U=B({}),o=B({code:"",productid:0,remark:"",bindrewardvpitime:0,bindrewardtranslate:0,bindrewardmeeting:0,maxuses:0,expire:"",disabled:!1});function E(n){return n?new Date(n*1e3).toLocaleString():"永久"}function $(n){if(!n)return"";const e=new Date(n*1e3),s=d=>d<10?"0"+d:""+d;return e.getFullYear()+"-"+s(e.getMonth()+1)+"-"+s(e.getDate())+"T"+s(e.getHours())+":"+s(e.getMinutes())}function R(n){return n?Math.floor(new Date(n).getTime()/1e3):0}function j(n){return U[n.brandid]||(n.brandid?"品牌商#"+n.brandid:"-")}function I(n){const e=k.value.find(s=>s.id===n.productid);return e?e.devicename||"#"+n.productid:n.productid?"#"+n.productid:"-"}function _(){h.value="list",f()}function H(){_()}async function f(){C.value=!0;try{const n=await c("getfactorypubliccodes",{brandid:m.value,status:V.value});y.value=n?.codes??[]}catch(n){p(n?.message??"获取公码列表失败"),y.value=[]}finally{C.value=!1}}function q(n){if(!m.value){w("请先选择品牌商");return}n?(v.value=!0,o.code=n.code,o.productid=n.productid||0,o.remark=n.remark||"",o.bindrewardvpitime=n.bindrewardvpitime||0,o.bindrewardtranslate=n.bindrewardtranslate||0,o.bindrewardmeeting=n.bindrewardmeeting||0,o.maxuses=n.maxuses||0,o.expire=$(n.expiretime),o.disabled=n.status===1):(v.value=!1,o.code="",o.productid=0,o.remark="",o.bindrewardvpitime=0,o.bindrewardtranslate=0,o.bindrewardmeeting=0,o.maxuses=0,o.expire="",o.disabled=!1),h.value="form"}async function P(){const n={productid:Number(o.productid)||0,remark:o.remark,maxuses:Number(o.maxuses)||0,expiretime:R(o.expire),bindrewardvpitime:Number(o.bindrewardvpitime)||0,bindrewardtranslate:Number(o.bindrewardtranslate)||0,bindrewardmeeting:Number(o.bindrewardmeeting)||0};try{if(v.value)n.code=o.code,n.status=o.disabled?1:0,await c("updatefactorypubliccode",n),g("保存成功");else{n.brandid=m.value;const e=await c("createfactorypubliccode",n);g("新公码已生成:"+(e?.code?.code||""))}_()}catch(e){p(e?.message??"保存失败")}}async function z(n){const e=n.status===0?1:0;try{await c("updatefactorypubliccode",{code:n.code,productid:n.productid||0,remark:n.remark||"",status:e,maxuses:n.maxuses||0,expiretime:n.expiretime||0,bindrewardvpitime:n.bindrewardvpitime||0,bindrewardtranslate:n.bindrewardtranslate||0,bindrewardmeeting:n.bindrewardmeeting||0}),g(e===1?"已停用":"已启用"),f()}catch(s){p(s?.message??"操作失败")}}function A(n){window.confirm(`确定删除公码 "${n}" 吗?删除后该码无法再被领取(已领取记录保留)`)&&c("delfactorypubliccode",{code:n}).then(()=>{g("删除成功"),f()}).catch(e=>p(e?.message??"删除失败"))}const L=i(null),D=i(null),x=i("");function Y(){return new Promise((n,e)=>{const s=window;if(s.QRCode){n(s.QRCode);return}const d=document.createElement("script");d.src=Ot,d.onload=()=>n(s.QRCode),d.onerror=()=>e(new Error("二维码库加载失败")),document.head.appendChild(d)})}async function G(n){x.value=n,L.value?.showModal();let e;try{e=await Y()}catch{p("二维码库加载失败");return}const s=D.value;!s||!e||(s.innerHTML="",new e(s,{text:n,width:240,height:240,colorDark:"#1E293B",colorLight:"#FFFFFF",correctLevel:e.CorrectLevel.H}))}function S(){const n=D.value;if(!n)return"";const e=n.querySelector("canvas");if(e)return e.toDataURL("image/png");const s=n.querySelector("img");return s?s.src:""}function J(){const n=S();if(!n){w("二维码尚未生成");return}const e=document.createElement("a");e.href=n,e.download="publiccode_"+x.value+".png",document.body.appendChild(e),e.click(),document.body.removeChild(e)}function K(){const n=S();if(!n){w("二维码尚未生成");return}const e=window.open("","_blank");if(!e){w("浏览器拦截了打印窗口");return}e.document.write(""+x.value+'

'+x.value+"

新用户扫码领取奖励

+ + diff --git a/apps/admin/app/pages/dashboard.vue b/apps/admin/app/pages/dashboard.vue index 9b63d8a2..58ae93cc 100644 --- a/apps/admin/app/pages/dashboard.vue +++ b/apps/admin/app/pages/dashboard.vue @@ -1,5 +1,8 @@