Browse Source
apps/admin/.output 与 apps/admin/node_modules 此前被纳入 git 跟踪(共 18425 个文件), 每跑一次 nuxt build 就产生数百个哈希文件的增删,真实代码 diff 被完全淹没。 部署不依赖仓库里这份产物:apps/admin/Dockerfile 是 COPY . . 之后 RUN pnpm build 在镜像内重新构建,且 .dockerignore 已排除 node_modules/.nuxt/.output——仓库里这份 从来没被用到过。 只从索引移除(git rm --cached),磁盘文件保留,本地 dev/build 不受影响。 .gitignore 同时补上此前遗漏的 .DS_Store。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>main
18426 changed files with 12 additions and 3172394 deletions
@ -1,15 +0,0 @@ |
|||
{ |
|||
"date": "2026-08-15T09:07:22.851Z", |
|||
"preset": "node-server", |
|||
"framework": { |
|||
"name": "nuxt", |
|||
"version": "4.4.8" |
|||
}, |
|||
"versions": { |
|||
"nitro": "2.13.4" |
|||
}, |
|||
"commands": { |
|||
"preview": "node server/index.mjs" |
|||
}, |
|||
"config": {} |
|||
} |
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1 +0,0 @@ |
|||
const o=[{value:"cn",label:"国内"},{value:"hw",label:"海外"}],t=new Set(["cn","china","中国","国内"]);function E(e){const n=(e||"").trim();return n?t.has(n.toLowerCase())?"cn":"hw":""}function r(e){const n=E(e);return n?n==="cn"?"国内":"海外":"未指定"}export{o as R,E as n,r}; |
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1 +0,0 @@ |
|||
import{_ as t,o,c as s,S as c}from"./6O01ZZML.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}; |
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1 +0,0 @@ |
|||
import{e as y,aa as h,ab as w,A as g,j as d,k as b}from"./6O01ZZML.js";const k="$s";function A(...t){const s=typeof t[t.length-1]=="string"?t.pop():void 0;typeof t[0]!="string"&&t.unshift(s);const[a,o]=t;if(!a||typeof a!="string")throw new TypeError("[nuxt] [useState] key must be a string: "+a);if(o!==void 0&&typeof o!="function")throw new Error("[nuxt] [useState] init must be a function: "+o);const i=k+a,r=y(),n=h(r.payload.state,i);if(o&&(r._state[i]??={_default:o}),n.value===void 0&&o){const e=o();if(w(e))return r.payload.state[i]=e,e;n.value=e}return n}function m(){const t=A("app:loading",()=>0),s=g(()=>t.value>0);function a(){t.value++}function o(){t.value=Math.max(0,t.value-1)}return{count:t,loading:s,begin:a,end:o}}async function f(t,s,a){const o=d(),i=b(),r={"Content-Type":"application/json"};o.token&&(r.Authorization=o.token),a&&Object.assign(r,a);const n=await fetch(t,{method:"POST",headers:r,body:JSON.stringify(s)});if(!n.ok)throw new Error(`HTTP error: ${n.status}`);const e=await n.json();if(e.code===18)throw o.logout(),i.push("/"),new Error(e.msg||"Unauthorized");if(e.code!==0)throw new Error(e.msg||"Unknown error");return e.data}const S=/^(get|list|load|query|fetch|search|count|stat|export|check)/i;function v(t){return!S.test(t)}function x(){const t=d(),{begin:s,end:a}=m();async function o(n,e){const u={};if(t.currentAppId&&(u["X-App-Id"]=String(t.currentAppId)),!v(n))return f(`/web/api/api_${n}`,e??{},u);s();try{return await f(`/web/api/api_${n}`,e??{},u)}finally{a()}}async function i(n,e){return f(`/console/api/${n}`,e??{})}async function r(n,e){const u=n.type||"application/octet-stream",c=await o("getcostoken",{path:e,filename:n.name,content_type:u}),p=c.upload_url||c.url||"";if(!p)throw new Error("未获取到上传地址:请确认已在【第三方服务配置→存储】配置并启用「阿里云 OSS」");const l=await fetch(p,{method:"PUT",headers:{"Content-Type":u},body:n});if(!l.ok)throw new Error(`Upload failed: ${l.status}`);return c.url||p.split("?")[0]}return{webApi:o,consoleApi:i,uploadFile:r}}export{m as a,A as b,x as u}; |
|||
File diff suppressed because one or more lines are too long
@ -1 +0,0 @@ |
|||
import{L as y,l as x}from"./DD3V9C6_.js";import{g as V,c as t,F as u,a as l,n as C,r,l as g,t as o,A as h,o as s,d as B,_ as N}from"./6O01ZZML.js";const L={class:"lang-select"},O={class:"lang-chip-name"},S=["onClick"],j={key:0,class:"lang-empty"},A={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"},z=["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",A,[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,z))]))}}),q=Object.assign(N(E,[["__scopeId","data-v-4903af59"]]),{__name:"LangSelect"});export{q as _}; |
|||
@ -1 +0,0 @@ |
|||
import{u as a,e as s,h as u,i as r,f as h}from"./6O01ZZML.js";function i(t){const e=t||s();return e.ssrContext?.head||e.runWithContext(()=>{if(u()){const n=r(h);if(!n)throw new Error("[nuxt] [unhead] Missing Unhead instance.");return n}})}function d(t,e={}){const n=e.head||i(e.nuxt);return a(t,{head:n,...e})}export{d as u}; |
|||
File diff suppressed because one or more lines are too long
@ -1,4 +0,0 @@ |
|||
import{g as G,C as K,Q as P,c as a,a as e,d as u,q as g,s as U,F as f,r as B,v as Q,x as Y,t as n,y as i,A as E,o,n as F,l as A,_ as Z}from"./6O01ZZML.js";import{u as J}from"./BgasD__e.js";import{u as W}from"./xsgK-Nup.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 注册,快照已收到但不会写入统计库"},_t={key:1,class:"muted"},gt={class:"muted"},xt={class:"muted"},yt={class:"muted"},bt={class:"muted"},ht={key:0,class:"muted"},wt={class:"t"},kt={key:0,class:"late"},Ct=G({__name:"statlog",setup(Tt){const{webApi:I}=J(),{success:O,error:R}=W(),H={cn:"中国",us:"美国",ea:"东亚",sea:"东南亚",sa:"南亚",me:"中东",eu:"欧洲",ru:"俄罗斯",af:"非洲",sam:"南美",nam:"北美",oc:"大洋洲",br:"巴西",in:"印度"};function D(l){return l?H[l]||l:"-"}const c=i([]),x=i(!1),_=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 M(l){return l==="error"?{cls:"lv-error",txt:"解析失败"}:l==="warn"?{cls:"lv-warn",txt:"未落库"}:{cls:"lv-info",txt:"已落库"}}function j(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.channel_id||"")+" "+(t.stat_day||"")).toLowerCase().indexOf(s)<0))});async function m(){x.value=!0,_.value="";try{const l=await I("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){_.value=l?.message||"网络异常"}finally{x.value=!1}}async function q(){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 I("clearstatlogs",{day:l});O("已清空 "+(r&&r.cleared!=null?r.cleared:0)+" 条"),m()}catch(r){R("清空失败:"+(r?.message||"网络异常"))}}function z(){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,[g(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,B(V.value,t=>(o(),a("option",{key:t.value,value:t.value},n(t.label),9,et))),128))],544),[[U,v.value,void 0,{number:!0}]]),g(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),[[U,b.value]]),g(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,[g(e("input",{"onUpdate:modelValue":s[3]||(s[3]=t=>w.value=t),type:"checkbox",class:"checkbox checkbox-xs",onChange:z},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:q},"清空本日")])]),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,[x.value?(o(),a("div",ct,"加载中...")):_.value?(o(),a("div",dt,"加载失败:"+n(_.value),1)):T.value.length?(o(!0),a(f,{key:3},B(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",M(t.level).cls])},n(M(t.level).txt),3)]),e("div",null,[t.app?(o(),a(f,{key:0},[e("span",mt,n(t.app),1),t.registered?A("",!0):(o(),a("span",ft,"未注册"))],64)):(o(),a("span",_t,"(无应用名)")),e("span",gt," · "+n(D(t.region)),1),e("span",xt," · "+n(S(t.product_id)),1),e("span",yt," · "+n(t.channel_id||"未分配渠道"),1)]),e("div",bt,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",ht," · "+n(t.summary),1)):A("",!0)],64)):(o(),a(f,{key:1},[u(n(t.summary||"无增量"),1)],64))]),e("div",wt,[u(n(C(t.snap_ts)),1),j(t)?(o(),a("span",kt,"迟到"+n(t.ts-t.snap_ts)+"s",1)):A("",!0)])]))),128)):(o(),a("div",vt,n(c.value.length?"无匹配记录":"该日暂无接收记录"),1))])])]))}}),Lt=Z(Ct,[["__scopeId","data-v-e7a3debc"]]);export{Lt as default};
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1 +0,0 @@ |
|||
import{_ as o,o as s,c as a,a as t,t as r}from"./6O01ZZML.js";import{u as i}from"./BvvkbLjV.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}; |
|||
File diff suppressed because one or more lines are too long
@ -1 +0,0 @@ |
|||
const a=[{code:"zh-CN",name:"中文(简体)"},{code:"zh-TW",name:"中文(繁体)"},{code:"zh-HK",name:"中文(香港)"},{code:"yue-HK",name:"粤语"},{code:"en-US",name:"英语(美国)"},{code:"en-GB",name:"英语(英国)"},{code:"ja-JP",name:"日语"},{code:"ko-KR",name:"韩语"},{code:"id-ID",name:"印尼语"},{code:"es-ES",name:"西班牙语(西)"},{code:"es-MX",name:"西班牙语(墨)"},{code:"pt-BR",name:"葡萄牙语(巴西)"},{code:"pt-PT",name:"葡萄牙语(葡)"},{code:"de-DE",name:"德语"},{code:"fr-FR",name:"法语"},{code:"it-IT",name:"意大利语"},{code:"nl-NL",name:"荷兰语"},{code:"pl-PL",name:"波兰语"},{code:"ru-RU",name:"俄语"},{code:"uk-UA",name:"乌克兰语"},{code:"tr-TR",name:"土耳其语"},{code:"vi-VN",name:"越南语"},{code:"th-TH",name:"泰语"},{code:"ms-MY",name:"马来语"},{code:"fil-PH",name:"菲律宾语"},{code:"ar-SA",name:"阿拉伯语"}],o={"bg-BG":"保加利亚语","cs-CZ":"捷克语","da-DK":"丹麦语","el-GR":"希腊语","et-EE":"爱沙尼亚语","fa-IR":"波斯语","fi-FI":"芬兰语","hi-IN":"印地语","hr-HR":"克罗地亚语","hu-HU":"匈牙利语","is-IS":"冰岛语","lt-LT":"立陶宛语","lv-LV":"拉脱维亚语","nb-NO":"挪威语","ro-RO":"罗马尼亚语","sk-SK":"斯洛伐克语","sl-SI":"斯洛文尼亚语","sr-RS":"塞尔维亚语","sv-SE":"瑞典语","tl-PH":"菲律宾语","he-IL":"希伯来语","bn-BD":"孟加拉语","ta-IN":"泰米尔语","ur-PK":"乌尔都语","ca-ES":"加泰罗尼亚语","sw-KE":"斯瓦希里语","af-ZA":"南非荷兰语","mk-MK":"马其顿语"};function d(e){const n=a.find(c=>c.code===e);return n?n.name:o[e]||e}const m=[...a,...Object.entries(o).map(([e,n])=>({code:e,name:n}))].sort((e,n)=>e.code<n.code?-1:1);export{m as A,a as L,d as l}; |
|||
@ -1 +0,0 @@ |
|||
import{g as h,j as x,k as w,C as y,c as r,a as e,t as d,l as b,p as _,q as v,v as f,n as k,z as M,y as u,o as p,_ as z}from"./6O01ZZML.js";const A={class:"login-bg flex items-center justify-center px-4"},B={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"}},q={style:{"margin-bottom":"24px"}},D=h({__name:"index",setup(L){const a=x(),c=w(),o=M({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 g(){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",B,[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:_(g,["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),[[f,o.account]])]),e("div",q,[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),[[f,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=z(D,[["__scopeId","data-v-4f88fb34"]]);export{O as default}; |
|||
@ -1,2 +0,0 @@ |
|||
import{u as r}from"./xsgK-Nup.js";import{g as x,c as i,a as t,t as o,l as f,o as l}from"./6O01ZZML.js";const b={key:0,class:"modal modal-open"},u={class:"modal-box max-w-md"},p={class:"font-bold text-base mb-1"},y={class:"rounded-xl border border-slate-200 bg-slate-50 p-3 space-y-2"},g={class:"flex items-center justify-between gap-3"},v={class:"font-mono font-semibold text-sm"},_={class:"flex items-center justify-between gap-3"},w={class:"font-mono font-semibold text-sm"},h={key:0,class:"mt-3 text-xs text-emerald-600"},k={key:1,class:"mt-3 text-xs text-amber-600"},C={class:"modal-action"},T=x({__name:"AccountCredentialDialog",props:{info:{}},emits:["close"],setup(s){const n=s,{success:c,warn:m}=r();async function d(){if(!n.info)return;const a=`用户名:${n.info.username} |
|||
初始密码:${n.info.password}`;try{await navigator.clipboard.writeText(a),c("凭据已复制")}catch{m("复制失败,请手工记录")}}return(a,e)=>s.info?(l(),i("div",b,[t("div",u,[t("h3",p,o(s.info.title),1),e[3]||(e[3]=t("p",{class:"text-xs text-slate-400 mb-3"},"初始密码仅在此显示一次,关闭后无法再查看(如需重设请到「后台账号」改密)。",-1)),t("div",y,[t("div",g,[e[1]||(e[1]=t("span",{class:"text-xs text-slate-500"},"登录用户名",-1)),t("span",v,o(s.info.username),1)]),t("div",_,[e[2]||(e[2]=t("span",{class:"text-xs text-slate-500"},"初始密码",-1)),t("span",w,o(s.info.password),1)])]),s.info.mailTo?(l(),i("div",h," ✓ 凭据已邮件发送至 "+o(s.info.mailTo),1)):(l(),i("div",k," ⚠ 凭据未能邮件送达"+o(s.info.mailError?":"+s.info.mailError:"")+",请手工转达上面的用户名和密码。 ",1)),t("div",C,[t("button",{class:"btn btn-ghost btn-sm",onClick:d},"复制"),t("button",{class:"btn btn-primary btn-sm text-white",onClick:e[0]||(e[0]=$=>a.$emit("close"))},"我已记录,关闭")])])])):f("",!0)}}),D=Object.assign(T,{__name:"AccountCredentialDialog"});export{D as _};
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1 +0,0 @@ |
|||
.lang-select[data-v-4903af59]{font-size:12px}.lang-chips[data-v-4903af59]{display:flex;flex-wrap:wrap;gap:4px;margin-bottom:4px;min-height:22px}.lang-disabled[data-v-4903af59]{opacity:.5;pointer-events:none}.lang-chip[data-v-4903af59]{display:inline-flex;align-items:center;gap:2px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11px;background:#ede9fe;color:#6d28d9;padding:1px 6px;border-radius:9999px}.lang-chip-name[data-v-4903af59],.lang-x[data-v-4903af59]{color:#a78bfa;margin-left:3px}.lang-x[data-v-4903af59]{font-weight:700;line-height:1}.lang-x[data-v-4903af59]:hover{color:#6d28d9}.lang-empty[data-v-4903af59]{font-size:11px;color:#94a3b8}.lang-dd[data-v-4903af59]{position:relative}.lang-dd-sum[data-v-4903af59]{cursor:pointer;font-size:12px;color:#7c3aed;list-style:none;-webkit-user-select:none;-moz-user-select:none;user-select:none}.lang-dd-sum[data-v-4903af59]::-webkit-details-marker{display:none}.lang-dd-panel[data-v-4903af59]{position:absolute;z-index:30;margin-top:4px;background:#fff;border:1px solid #e2e8f0;border-radius:8px;box-shadow:0 8px 24px #0f172a24;padding:6px;max-height:260px;overflow-y:auto;width:230px}.lang-opt[data-v-4903af59]{display:flex;align-items:center;gap:6px;padding:3px 6px;border-radius:6px;cursor:pointer}.lang-opt[data-v-4903af59]:hover{background:#f1f5f9}.lang-opt-code[data-v-4903af59]{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;color:#334155}.lang-opt-name[data-v-4903af59]{color:#94a3b8} |
|||
@ -1 +0,0 @@ |
|||
const a={1:"中国",2:"美国",3:"东亚",4:"东南亚",5:"南亚",6:"中东",7:"欧洲",8:"俄罗斯",9:"非洲",10:"南美",11:"北美",12:"大洋洲",13:"巴西",14:"印度"},o={1:"STT",2:"TTS",3:"MT",4:"AST",5:"文本LLM",6:"存储",7:"STS",8:"录音识别",9:"多媒体LLM",10:"MCP"},l={error:{label:"不可用",color:"#be123c",bg:"#ffe4e6"},warn:{label:"有隐患",color:"#b45309",bg:"#fef3c7"},ok:{label:"正常",color:"#047857",bg:"#d1fae5"},skip:{label:"已停用",color:"#64748b",bg:"#f1f5f9"}},s={credential:{label:"凭据已验证",hint:"已用真实凭据调通服务商接口"},reachable:{label:"仅连通性",hint:"地址可达,但未验证凭据是否有效"},none:{label:"未探测",hint:"暂无该服务商的探针,可用性未经验证"}};function i(r){const e=r.config_issues||[],n=e.filter(t=>t.startsWith("[致命] "));return n.length?n.map(t=>t.replace("[致命] ","")).join(";"):r.status==="error"?r.probe_msg||"巡检失败":e.length?e.join(";"):r.probe_kind==="none"?r.probe_msg||"未验证可用性":r.probe_msg||""}function f(r){if(!r)return"尚未执行";const e=Date.now()-r;return e<6e4?"刚刚":e<36e5?`${Math.floor(e/6e4)} 分钟前`:e<864e5?`${Math.floor(e/36e5)} 小时前`:new Date(r).toLocaleString("zh-CN",{hour12:!1})}function b(r){return(r||"").split(",").map(e=>Number(e.trim())).filter(e=>!Number.isNaN(e)&&e>0)}export{o as C,s as P,a as R,l as S,i as a,f as h,b as p}; |
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1 +0,0 @@ |
|||
import{g as t,C as n,P as a,c as o,a as s,o as c}from"./6O01ZZML.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}; |
|||
@ -1 +0,0 @@ |
|||
.chk[data-v-a2832f1b]{display:flex;align-items:center;gap:6px;padding:5px 9px;border:1px solid #e2e8f0;border-radius:8px;font-size:12px;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none}.chk[data-v-a2832f1b]:hover{background:#f8fafc}.chk input[data-v-a2832f1b]{width:14px;height:14px} |
|||
@ -1 +0,0 @@ |
|||
.type-tag[data-v-dcf87e76]{font-size:12px;font-weight:700;padding:3px 10px;border-radius:8px}.agent-grid[data-v-dcf87e76]{display:grid;gap:12px;grid-template-columns:repeat(auto-fill,minmax(300px,1fr))}.agent-card[data-v-dcf87e76]{background:#fff;border:1px solid #eef2f7;border-radius:14px;padding:14px 16px;cursor:pointer;transition:all .15s}.agent-card[data-v-dcf87e76]:hover{border-color:#c7d2fe;box-shadow:0 4px 14px #6366f114}.svc-pill[data-v-dcf87e76]{display:inline-flex;align-items:center;font-size:10px;font-weight:600;padding:2px 8px;border-radius:7px;color:#fff}.ag-overlay[data-v-dcf87e76]{position:fixed;inset:0;background:#0f172a73;z-index:100;display:flex;align-items:center;justify-content:center;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);padding:24px}.ag-box[data-v-dcf87e76]{background:#fff;border-radius:18px;padding:24px;width:780px;max-width:96vw;max-height:90vh;overflow-y:auto;box-shadow:0 24px 80px #0000002e}.scope-chip[data-v-dcf87e76]{font-size:11px;font-weight:600;padding:2px 9px;border-radius:6px;background:#eef2ff;color:#4338ca}.ed-section[data-v-dcf87e76]{padding:14px 0;border-top:1px dashed #eef2f7}.ed-section[data-v-dcf87e76]:first-of-type{padding-top:0;border-top:none}.ed-section-title[data-v-dcf87e76]{font-size:11px;font-weight:700;letter-spacing:.04em;color:#94a3b8;margin-bottom:10px}.ed-label[data-v-dcf87e76]{display:block;font-size:11px;color:#64748b;margin-bottom:4px}.ed-label.inline[data-v-dcf87e76]{display:inline-block;margin-left:6px}.ed-tip[data-v-dcf87e76]{font-size:11px;color:#94a3b8;margin-top:8px}.req[data-v-dcf87e76]{color:#dc2626;font-style:normal}.type-row[data-v-dcf87e76]{display:grid;grid-template-columns:repeat(4,1fr);gap:10px}.ttab[data-v-dcf87e76]{display:flex;flex-direction:column;gap:3px;padding:11px 12px;border-radius:10px;border:1.5px solid #e2e8f0;background:#fff;cursor:pointer;transition:all .15s;text-align:left}.ttab[data-v-dcf87e76]:hover:not(:disabled){border-color:#c7d2fe;background:#f8fafc}.ttab.on[data-v-dcf87e76]{border-color:#6366f1;background:linear-gradient(135deg,#eef2ff,#f5f3ff)}.ttab.locked[data-v-dcf87e76]{opacity:.45;cursor:not-allowed}.ttab-title[data-v-dcf87e76]{font-weight:700;font-size:12px;color:#1e293b}.ttab-desc[data-v-dcf87e76]{font-size:10px;color:#94a3b8}.slot-row[data-v-dcf87e76]{display:flex;align-items:flex-end;gap:10px}.slot-item[data-v-dcf87e76]{flex:1;min-width:0}.slot-arrow[data-v-dcf87e76]{color:#cbd5e1;padding-bottom:8px;flex-shrink:0}.stage-tag[data-v-dcf87e76]{display:inline-block;font-size:10px;font-weight:700;padding:1px 7px;border-radius:5px;color:#fff;vertical-align:middle}.var-row[data-v-dcf87e76],.voice-row[data-v-dcf87e76]{display:flex;align-items:center;gap:8px;margin-bottom:6px}.mcp-grid[data-v-dcf87e76]{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:8px}.mcp-item[data-v-dcf87e76]{display:flex;align-items:center;gap:8px;min-width:0;padding:7px 10px;border:1.5px solid #e2e8f0;border-radius:9px;font-size:12.5px;color:#475569;cursor:pointer;transition:all .15s}.mcp-item[data-v-dcf87e76]:hover{border-color:#c7d2fe;background:#f8fafc}.mcp-item.on[data-v-dcf87e76]{border-color:#6366f1;background:#eef2ff;color:#4338ca}.ed-footer[data-v-dcf87e76]{display:flex;align-items:center;justify-content:space-between;gap:12px;padding-top:14px;border-top:1px solid #eef2f7}@media(max-width:860px){.type-row[data-v-dcf87e76]{grid-template-columns:repeat(2,1fr)}.slot-row[data-v-dcf87e76]{flex-direction:column;align-items:stretch}.slot-arrow[data-v-dcf87e76]{display:none}} |
|||
@ -1 +0,0 @@ |
|||
{"id":"15e7ab28-16d6-4f4e-8edd-c6a8122f81cf","timestamp":1786784834591} |
|||
@ -1 +0,0 @@ |
|||
{"id":"15e7ab28-16d6-4f4e-8edd-c6a8122f81cf","timestamp":1786784834591,"prerendered":[]} |
|||
@ -1 +0,0 @@ |
|||
.rule-list[data-v-0fc4ec7d]{background:#fff;border:1px solid #eef2f7;border-radius:14px;overflow:hidden}.rule-head[data-v-0fc4ec7d],.rule-row[data-v-0fc4ec7d]{display:grid;grid-template-columns:92px 1fr 220px 92px 160px;gap:12px;align-items:center;padding:11px 16px}.rule-head[data-v-0fc4ec7d]{font-size:11px;font-weight:700;color:#94a3b8;background:#f8fafc;border-bottom:1px solid #eef2f7}.rule-row[data-v-0fc4ec7d]{border-bottom:1px solid #f6f8fb;cursor:pointer;transition:background .15s}.rule-row[data-v-0fc4ec7d]:last-child{border-bottom:none}.rule-row[data-v-0fc4ec7d]:hover{background:#f8fafc}.rule-row.off[data-v-0fc4ec7d]{opacity:.55}.prio-cell[data-v-0fc4ec7d]{display:flex;align-items:baseline;gap:6px}.prio[data-v-0fc4ec7d]{font-size:15px;font-weight:800;color:#4338ca}.order[data-v-0fc4ec7d]{font-size:10px;color:#cbd5e1}.cond-cell[data-v-0fc4ec7d]{min-width:0}.agent-cell[data-v-0fc4ec7d]{display:flex;align-items:center;gap:6px;min-width:0}.lang-badge[data-v-0fc4ec7d]{font-size:12px;font-weight:700;padding:3px 10px;border-radius:8px;background:#eef2ff;color:#4338ca}.lang-badge.any[data-v-0fc4ec7d]{background:#f1f5f9;color:#64748b;font-style:italic}.type-badge[data-v-0fc4ec7d]{font-size:10px;font-weight:700;padding:2px 7px;border-radius:5px;white-space:nowrap}.editor-panel[data-v-0fc4ec7d]{background:#fff;border-radius:16px;border:1px solid #c7d2fe;box-shadow:0 8px 32px #6366f11a;padding:22px;margin-bottom:16px}.region-chip[data-v-0fc4ec7d]{font-size:11px;font-weight:600;padding:2px 9px;border-radius:6px;background:#eef2ff;color:#4338ca}.ed-section[data-v-0fc4ec7d]{padding:14px 0;border-top:1px dashed #eef2f7}.ed-section[data-v-0fc4ec7d]:first-of-type{padding-top:0;border-top:none}.ed-section-title[data-v-0fc4ec7d]{font-size:11px;font-weight:700;letter-spacing:.04em;color:#94a3b8;margin-bottom:10px}.ed-label[data-v-0fc4ec7d]{display:block;font-size:11px;color:#64748b;margin-bottom:4px}.ed-warn[data-v-0fc4ec7d]{font-size:11px;color:#b45309;margin-top:8px}.req[data-v-0fc4ec7d]{color:#dc2626;font-style:normal}.any-toggle[data-v-0fc4ec7d]{gap:5px;font-size:11px;cursor:pointer}.any-box[data-v-0fc4ec7d],.any-toggle[data-v-0fc4ec7d]{display:flex;align-items:center;color:#64748b}.any-box[data-v-0fc4ec7d]{height:34px;padding:0 12px;border-radius:8px;border:1.5px dashed #cbd5e1;background:#f8fafc;font-size:12px;font-style:italic}.lang-row[data-v-0fc4ec7d]{display:grid;grid-template-columns:1fr 92px 1fr;align-items:start;gap:12px}.lang-field[data-v-0fc4ec7d]{min-width:0}.dir-col[data-v-0fc4ec7d]{display:flex;flex-direction:column;align-items:center;gap:4px;padding-top:22px}.dir-btn[data-v-0fc4ec7d]{width:46px;height:32px;border-radius:9px;border:1.5px solid #e2e8f0;background:#f8fafc;color:#64748b;font-size:17px;line-height:1;cursor:pointer;transition:all .15s}.dir-btn[data-v-0fc4ec7d]:hover{border-color:#c7d2fe;background:#f5f3ff;color:#4338ca}.dir-btn.on[data-v-0fc4ec7d]{border-color:#6366f1;background:#eef2ff;color:#4338ca}.dir-tip[data-v-0fc4ec7d]{font-size:10px;color:#94a3b8;white-space:nowrap}.agent-preview[data-v-0fc4ec7d]{gap:8px;margin-top:10px;padding:8px 12px;border-radius:9px;background:#f8fafc;border:1px solid #eef2f7}.agent-preview[data-v-0fc4ec7d],.ed-footer[data-v-0fc4ec7d]{display:flex;align-items:center;flex-wrap:wrap}.ed-footer[data-v-0fc4ec7d]{justify-content:space-between;gap:12px;padding-top:14px;border-top:1px solid #eef2f7}.ct-overlay[data-v-0fc4ec7d]{position:fixed;inset:0;background:#0f172a73;z-index:100;display:flex;align-items:center;justify-content:center;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);padding:24px}.ct-box[data-v-0fc4ec7d]{background:#fff;border-radius:20px;padding:28px;width:560px;max-width:95vw;box-shadow:0 24px 80px #0000002e}.sync-region-grid[data-v-0fc4ec7d]{display:grid;grid-template-columns:repeat(4,1fr);gap:8px;margin:14px 0}.sync-region-item[data-v-0fc4ec7d]{display:flex;align-items:center;gap:7px;padding:8px 10px;border-radius:9px;border:1.5px solid #e2e8f0;cursor:pointer;transition:all .15s;font-size:13px;font-weight:500;color:#475569}.sync-region-item[data-v-0fc4ec7d]:hover{border-color:#c7d2fe;background:#f5f3ff}.sync-region-item.checked[data-v-0fc4ec7d]{border-color:#6366f1;background:#eef2ff;color:#4338ca}.test-result[data-v-0fc4ec7d]{margin-top:14px;padding:12px 14px;border-radius:10px;background:#eef2ff;border:1px solid #c7d2fe}.test-result.miss[data-v-0fc4ec7d]{background:#fffbeb;border-color:#fde68a}@media(max-width:1000px){.rule-head[data-v-0fc4ec7d],.rule-row[data-v-0fc4ec7d]{grid-template-columns:70px 1fr 150px}.rule-head[data-v-0fc4ec7d]>:nth-child(4),.rule-row[data-v-0fc4ec7d]>:nth-child(4){display:none}}@media(max-width:860px){.lang-row[data-v-0fc4ec7d]{grid-template-columns:1fr}.dir-col[data-v-0fc4ec7d]{flex-direction:row;padding-top:0}} |
|||
@ -1 +0,0 @@ |
|||
.group-tag[data-v-66a7d845]{font-size:12px;font-weight:700;padding:3px 10px;border-radius:8px}.ch-grid[data-v-66a7d845]{display:grid;gap:12px;grid-template-columns:repeat(auto-fill,minmax(280px,1fr))}.ch-card[data-v-66a7d845]{background:#fff;border:1px solid #eef2f7;border-radius:14px;padding:14px 16px;cursor:pointer;transition:all .15s}.ch-card[data-v-66a7d845]:hover{border-color:#c7d2fe;box-shadow:0 4px 14px #6366f114}.ch-card.off[data-v-66a7d845]{opacity:.55}.ch-empty[data-v-66a7d845]{border-style:dashed;background:#fafbfc;display:flex;flex-direction:column;justify-content:center;align-items:center;min-height:92px}.ch-empty[data-v-66a7d845]:hover{border-color:#c7d2fe;background:#f8fafc}.status-badge[data-v-66a7d845]{font-size:10px;font-weight:700;padding:2px 8px;border-radius:6px;white-space:nowrap}.ver-row[data-v-66a7d845]{display:flex;gap:14px;margin-top:10px;flex-wrap:wrap}.ver-box[data-v-66a7d845]{display:flex;flex-direction:column}.ver-label[data-v-66a7d845]{font-size:10px;color:#94a3b8}.ver-val[data-v-66a7d845]{font-size:13px;font-weight:700;color:#1e293b;font-family:SF Mono,Menlo,monospace}.ver-val.warn[data-v-66a7d845]{color:#b45309}.ver-val.review[data-v-66a7d845]{color:#7c3aed}.flag[data-v-66a7d845]{font-size:10px;font-weight:600;padding:2px 7px;border-radius:5px;background:#f1f5f9;color:#475569}.flag-warn[data-v-66a7d845]{background:#fef3c7;color:#b45309}.flag-off[data-v-66a7d845]{background:#fee2e2;color:#b91c1c}.pay-pill[data-v-66a7d845]{font-size:10px;font-weight:600;padding:2px 8px;border-radius:6px;background:#eef2ff;color:#4338ca}.pay-pill.missing[data-v-66a7d845]{background:#fef3c7;color:#b45309}.pay-warn[data-v-66a7d845]{background:#fffbeb;border:1px solid #fde68a;color:#92400e;border-radius:12px;padding:12px 14px;margin-bottom:16px}.warn-pill[data-v-66a7d845]{display:inline-block;margin-right:8px;padding:1px 8px;border-radius:6px;background:#fef3c7}.scope-tip[data-v-66a7d845]{background:#f8fafc;border:1px solid #eef2f7;color:#64748b;font-size:12px;border-radius:10px;padding:9px 13px;margin-bottom:16px}.ch-overlay[data-v-66a7d845]{position:fixed;inset:0;background:#0f172a73;z-index:100;display:flex;align-items:center;justify-content:center;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);padding:24px}.ch-box[data-v-66a7d845]{background:#fff;border-radius:18px;padding:24px;width:700px;max-width:96vw;max-height:90vh;overflow-y:auto;box-shadow:0 24px 80px #0000002e}.scope-chip[data-v-66a7d845]{font-size:11px;font-weight:600;padding:2px 9px;border-radius:6px;background:#eef2ff;color:#4338ca}.ed-section[data-v-66a7d845]{padding:14px 0;border-top:1px dashed #eef2f7}.ed-section[data-v-66a7d845]:first-of-type{padding-top:0;border-top:none}.ed-section-title[data-v-66a7d845]{font-size:11px;font-weight:700;letter-spacing:.04em;color:#94a3b8;margin-bottom:10px}.ed-label[data-v-66a7d845]{display:block;font-size:11px;color:#64748b;margin-bottom:4px}.ed-warn[data-v-66a7d845]{color:#b45309}.ed-tip[data-v-66a7d845],.ed-warn[data-v-66a7d845]{font-size:11px;margin-top:8px}.ed-tip[data-v-66a7d845]{color:#94a3b8}.req[data-v-66a7d845]{color:#dc2626;font-style:normal}.link[data-v-66a7d845]{color:#4f46e5;cursor:pointer;text-decoration:underline}.pay-grid[data-v-66a7d845]{display:grid;grid-template-columns:repeat(3,1fr);gap:8px}.pay-item[data-v-66a7d845]{display:flex;align-items:center;gap:7px;padding:8px 10px;border-radius:9px;border:1.5px solid #e2e8f0;cursor:pointer;font-size:13px;color:#475569;transition:all .15s}.pay-item[data-v-66a7d845]:hover{border-color:#c7d2fe;background:#f8fafc}.pay-item.checked[data-v-66a7d845]{border-color:#6366f1;background:#eef2ff;color:#4338ca}.pay-miss[data-v-66a7d845]{font-size:10px;color:#b45309;background:#fef3c7;padding:1px 5px;border-radius:4px;margin-left:auto}.ed-footer[data-v-66a7d845]{display:flex;align-items:center;justify-content:space-between;gap:12px;padding-top:14px;border-top:1px solid #eef2f7}@media(max-width:860px){.pay-grid[data-v-66a7d845]{grid-template-columns:repeat(2,1fr)}} |
|||
File diff suppressed because one or more lines are too long
@ -1 +0,0 @@ |
|||
.fade-enter-active[data-v-c1ace0c2],.fade-leave-active[data-v-c1ace0c2]{transition:opacity .15s ease}.fade-enter-from[data-v-c1ace0c2],.fade-leave-to[data-v-c1ace0c2]{opacity:0} |
|||
File diff suppressed because one or more lines are too long
@ -1 +0,0 @@ |
|||
.grid[data-v-52418c85]{display:grid}.mb-2[data-v-52418c85]{margin-bottom:.5rem}.mb-4[data-v-52418c85]{margin-bottom:1rem}.max-w-520px[data-v-52418c85]{max-width:520px}.min-h-screen[data-v-52418c85]{min-height:100vh}.w-full[data-v-52418c85]{width:100%}.flex[data-v-52418c85]{display:flex}.place-content-center[data-v-52418c85]{place-content:center}.items-center[data-v-52418c85]{align-items:center}.justify-center[data-v-52418c85]{justify-content:center}.overflow-hidden[data-v-52418c85]{overflow:hidden}.bg-white[data-v-52418c85]{--un-bg-opacity:1;background-color:rgb(255 255 255/var(--un-bg-opacity))}.px-2[data-v-52418c85]{padding-left:.5rem;padding-right:.5rem}.text-center[data-v-52418c85]{text-align:center}.text-\[80px\][data-v-52418c85]{font-size:80px}.text-2xl[data-v-52418c85]{font-size:1.5rem;line-height:2rem}.text-sm[data-v-52418c85]{font-size:.875rem;line-height:1.25rem}.text-\[\#020420\][data-v-52418c85]{--un-text-opacity:1;color:rgb(2 4 32/var(--un-text-opacity))}.text-\[\#64748B\][data-v-52418c85]{--un-text-opacity:1;color:rgb(100 116 139/var(--un-text-opacity))}.hover\:text-\[\#00DC82\][data-v-52418c85]:hover{--un-text-opacity:1;color:rgb(0 220 130/var(--un-text-opacity))}.font-medium[data-v-52418c85]{font-weight:500}.font-semibold[data-v-52418c85]{font-weight:600}.leading-none[data-v-52418c85]{line-height:1}.tracking-wide[data-v-52418c85]{letter-spacing:.025em}.font-sans[data-v-52418c85]{font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji}.tabular-nums[data-v-52418c85]{--un-numeric-spacing:tabular-nums;font-variant-numeric:var(--un-ordinal) var(--un-slashed-zero) var(--un-numeric-figure) var(--un-numeric-spacing) var(--un-numeric-fraction)}.underline[data-v-52418c85]{text-decoration-line:underline}.underline-offset-3[data-v-52418c85]{text-underline-offset:3px}.antialiased[data-v-52418c85]{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}@media(prefers-color-scheme:dark){.dark\:bg-\[\#020420\][data-v-52418c85]{--un-bg-opacity:1;background-color:rgb(2 4 32/var(--un-bg-opacity))}.dark\:text-white[data-v-52418c85]{--un-text-opacity:1;color:rgb(255 255 255/var(--un-text-opacity))}}@media(min-width:640px){.sm\:text-\[110px\][data-v-52418c85]{font-size:110px}.sm\:text-3xl[data-v-52418c85]{font-size:1.875rem;line-height:2.25rem}} |
|||
@ -1 +0,0 @@ |
|||
.grid[data-v-2c2ce9e3]{display:grid}.mb-2[data-v-2c2ce9e3]{margin-bottom:.5rem}.mb-4[data-v-2c2ce9e3]{margin-bottom:1rem}.max-w-520px[data-v-2c2ce9e3]{max-width:520px}.min-h-screen[data-v-2c2ce9e3]{min-height:100vh}.place-content-center[data-v-2c2ce9e3]{place-content:center}.overflow-hidden[data-v-2c2ce9e3]{overflow:hidden}.bg-white[data-v-2c2ce9e3]{--un-bg-opacity:1;background-color:rgb(255 255 255/var(--un-bg-opacity))}.px-2[data-v-2c2ce9e3]{padding-left:.5rem;padding-right:.5rem}.text-center[data-v-2c2ce9e3]{text-align:center}.text-\[80px\][data-v-2c2ce9e3]{font-size:80px}.text-2xl[data-v-2c2ce9e3]{font-size:1.5rem;line-height:2rem}.text-\[\#020420\][data-v-2c2ce9e3]{--un-text-opacity:1;color:rgb(2 4 32/var(--un-text-opacity))}.text-\[\#64748B\][data-v-2c2ce9e3]{--un-text-opacity:1;color:rgb(100 116 139/var(--un-text-opacity))}.font-semibold[data-v-2c2ce9e3]{font-weight:600}.leading-none[data-v-2c2ce9e3]{line-height:1}.tracking-wide[data-v-2c2ce9e3]{letter-spacing:.025em}.font-sans[data-v-2c2ce9e3]{font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji}.tabular-nums[data-v-2c2ce9e3]{--un-numeric-spacing:tabular-nums;font-variant-numeric:var(--un-ordinal) var(--un-slashed-zero) var(--un-numeric-figure) var(--un-numeric-spacing) var(--un-numeric-fraction)}.antialiased[data-v-2c2ce9e3]{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}@media(prefers-color-scheme:dark){.dark\:bg-\[\#020420\][data-v-2c2ce9e3]{--un-bg-opacity:1;background-color:rgb(2 4 32/var(--un-bg-opacity))}.dark\:text-white[data-v-2c2ce9e3]{--un-text-opacity:1;color:rgb(255 255 255/var(--un-text-opacity))}}@media(min-width:640px){.sm\:text-\[110px\][data-v-2c2ce9e3]{font-size:110px}.sm\:text-3xl[data-v-2c2ce9e3]{font-size:1.875rem;line-height:2.25rem}} |
|||
@ -1 +0,0 @@ |
|||
.login-bg[data-v-4f88fb34]{min-height:100vh;background:linear-gradient(135deg,#0f172a,#1e293b 50%,#0f172a);position:relative;overflow:hidden}.login-bg[data-v-4f88fb34]:before{content:"";position:absolute;top:-50%;left:-50%;width:200%;height:200%;background:radial-gradient(ellipse at 30% 20%,rgba(99,102,241,.15) 0,transparent 50%),radial-gradient(ellipse at 70% 80%,rgba(139,92,246,.1) 0,transparent 50%);animation:bgFloat-4f88fb34 20s ease-in-out infinite}@keyframes bgFloat-4f88fb34{0%,to{transform:translate(0)}50%{transform:translate(-2%,2%)}}.login-card[data-v-4f88fb34]{background:#fffffff2;-webkit-backdrop-filter:blur(20px);backdrop-filter:blur(20px);border:1px solid hsla(0,0%,100%,.2);border-radius:20px;box-shadow:0 25px 80px #0000004d,0 8px 32px #00000026;padding:40px;width:100%;max-width:420px;animation:cardIn-4f88fb34 .6s cubic-bezier(.16,1,.3,1)}@keyframes cardIn-4f88fb34{0%{opacity:0;transform:translateY(20px) scale(.96)}to{opacity:1;transform:translateY(0) scale(1)}}.logo-icon[data-v-4f88fb34]{width:56px;height:56px;background:linear-gradient(135deg,#4f46e5,#7c3aed);border-radius:16px;display:flex;align-items:center;justify-content:center;margin:0 auto 20px;box-shadow:0 8px 24px #4f46e559}.login-input[data-v-4f88fb34]{width:100%;padding:12px 16px;border:1.5px solid #e2e8f0;border-radius:10px;font-size:14px;color:#334155;background:#f8fafc;transition:all .2s;outline:none}.login-input[data-v-4f88fb34]:focus{border-color:#6366f1;background:#fff;box-shadow:0 0 0 3px #6366f11a}.login-input[data-v-4f88fb34]::-moz-placeholder{color:#cbd5e1}.login-input[data-v-4f88fb34]::placeholder{color:#cbd5e1}.login-btn[data-v-4f88fb34]{width:100%;padding:12px;border:none;border-radius:10px;background:linear-gradient(135deg,#4f46e5,#6366f1);color:#fff;font-size:15px;font-weight:600;cursor:pointer;transition:all .3s;box-shadow:0 4px 16px #4f46e54d}.login-btn[data-v-4f88fb34]:hover{background:linear-gradient(135deg,#4338ca,#4f46e5);transform:translateY(-2px);box-shadow:0 8px 24px #4f46e566}.login-btn[data-v-4f88fb34]:active{transform:translateY(0)}.login-btn.loading[data-v-4f88fb34]{opacity:.7;pointer-events:none}.login-label[data-v-4f88fb34]{display:block;font-size:13px;font-weight:500;color:#64748b;margin-bottom:6px}.login-error[data-v-4f88fb34]{background:#fef2f2;border:1px solid #fecaca;color:#dc2626;padding:10px 14px;border-radius:10px;font-size:13px;margin-bottom:16px;display:none}.login-error.show[data-v-4f88fb34]{display:flex;align-items:center;gap:8px} |
|||
@ -1 +0,0 @@ |
|||
.app-grid[data-v-80f99751]{display:grid;grid-template-columns:repeat(auto-fill,minmax(310px,1fr));gap:16px}.app-card[data-v-80f99751]{background:#fff;border:1px solid #eef2f7;border-radius:16px;overflow:hidden;box-shadow:0 1px 2px #0f172a0a,0 4px 16px #0f172a08;cursor:pointer;position:relative;display:flex;flex-direction:column;transition:transform .14s ease,box-shadow .14s ease,border-color .14s ease}.app-card[data-v-80f99751]:hover{transform:translateY(-2px);box-shadow:0 10px 40px #0f172a1f;border-color:#e2e8f0}.app-card[data-v-80f99751]:focus-visible{outline:2px solid #4f46e5;outline-offset:2px}.app-card[data-v-80f99751]:before{content:"";position:absolute;inset:0 0 auto;height:3px;background:linear-gradient(90deg,#4f46e5,#7c3aed)}.app-card.off[data-v-80f99751]:before{background:#94a3b8}.app-card.orphan[data-v-80f99751]{cursor:default;border-color:#fde68a}.app-card.orphan[data-v-80f99751]:before{background:#f59e0b}.app-card.orphan[data-v-80f99751]:hover{transform:none}.ac-head[data-v-80f99751]{padding:18px 18px 12px;display:flex;gap:13px;align-items:flex-start}.ac-logo[data-v-80f99751]{width:44px;height:44px;border-radius:12px;flex-shrink:0;color:#fff;background:linear-gradient(135deg,#4f46e5,#7c3aed);display:grid;place-items:center;font-weight:800;font-size:18px;box-shadow:0 5px 14px #4f46e547}.app-card.off .ac-logo[data-v-80f99751]{background:#94a3b8;box-shadow:none}.app-card.orphan .ac-logo[data-v-80f99751]{background:#f59e0b;box-shadow:none}.ac-title[data-v-80f99751]{font-size:15.5px;font-weight:700;color:#1e293b;letter-spacing:-.01em}.ac-meta[data-v-80f99751]{font-size:11.5px;color:#94a3b8;margin-top:3px}.ac-remark[data-v-80f99751]{font-size:12px;color:#64748b;padding:0 18px 14px;margin:0;min-height:2.4em}.ac-stats[data-v-80f99751]{display:grid;grid-template-columns:repeat(3,1fr);border-top:1px solid #eef2f7;background:#fcfcfd}.ac-stat[data-v-80f99751]{padding:11px 8px;text-align:center;border-right:1px solid #eef2f7}.ac-stat[data-v-80f99751]:last-child{border-right:0}.ac-stat-n[data-v-80f99751]{font-size:17px;font-weight:700;line-height:1.2;color:#1e293b;font-family:SF Mono,Menlo,monospace;font-variant-numeric:tabular-nums}.ac-stat-n.warn[data-v-80f99751]{color:#b45309}.ac-stat-n.zero[data-v-80f99751]{color:#cbd5e1}.ac-stat-l[data-v-80f99751]{font-size:10px;color:#94a3b8;margin-top:2px;letter-spacing:.03em}.ac-regions[data-v-80f99751]{padding:11px 18px;gap:5px;flex-wrap:wrap;align-items:center;min-height:42px}.ac-foot[data-v-80f99751],.ac-regions[data-v-80f99751]{display:flex;border-top:1px solid #eef2f7}.ac-foot[data-v-80f99751]{padding:10px 14px;gap:6px;justify-content:flex-end;margin-top:auto}.orphan-list[data-v-80f99751]{border-top:1px solid #eef2f7}.orphan-row[data-v-80f99751]{display:flex;align-items:center;gap:8px;padding:9px 16px;border-bottom:1px solid #f8fafc}.orphan-row[data-v-80f99751]:last-child{border-bottom:0}.chip[data-v-80f99751]{display:inline-flex;align-items:center;font-size:10.5px;font-weight:700;padding:2px 7px;border-radius:5px;background:#f1f5f9;color:#64748b}.chip-app[data-v-80f99751]{background:#eef2ff;color:#4338ca}.chip-dep[data-v-80f99751]{background:#ecfeff;color:#0e7490}.chip-warn[data-v-80f99751]{background:#fef3c7;color:#b45309} |
|||
File diff suppressed because one or more lines are too long
@ -1 +0,0 @@ |
|||
.panel[data-v-5eb39361]{background:#fff;border:1px solid #f1f5f9;border-radius:16px;box-shadow:0 1px 2px #0000000a}.tpl-grid[data-v-5eb39361]{display:grid;gap:14px;grid-template-columns:repeat(auto-fill,minmax(280px,1fr))}.tpl-card[data-v-5eb39361]{background:#fff;border:1px solid #eef2f7;border-radius:16px;padding:16px;cursor:pointer;transition:all .15s;display:flex;flex-direction:column;gap:10px;box-shadow:0 1px 2px #0000000a}.tpl-card[data-v-5eb39361]:hover{border-color:#c7d2fe;box-shadow:0 6px 18px #0f172a14;transform:translateY(-1px)}.tc-top[data-v-5eb39361]{display:flex;align-items:flex-start;gap:11px}.tc-ico[data-v-5eb39361]{width:40px;height:40px;border-radius:11px;flex-shrink:0;overflow:hidden;background:linear-gradient(135deg,#eef2ff,#e0e7ff);color:#4338ca;display:flex;align-items:center;justify-content:center;font-weight:700;font-size:17px}.tc-ico img[data-v-5eb39361]{width:100%;height:100%;-o-object-fit:cover;object-fit:cover}.tc-title[data-v-5eb39361]{font-weight:600;font-size:14.5px;color:#1e293b;line-height:1.35}.tc-tid[data-v-5eb39361],.tc-title[data-v-5eb39361]{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tc-tid[data-v-5eb39361]{font-size:11px;color:#94a3b8;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;margin-top:2px}.tc-desc[data-v-5eb39361]{font-size:12.5px;color:#64748b;line-height:1.55;min-height:39px;display:-webkit-box;-webkit-line-clamp:2;line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.tc-tags[data-v-5eb39361]{gap:4px;min-height:20px}.tc-foot[data-v-5eb39361],.tc-tags[data-v-5eb39361]{display:flex;flex-wrap:wrap}.tc-foot[data-v-5eb39361]{align-items:center;gap:6px;padding-top:9px;border-top:1px solid #f8fafc}.tc-go[data-v-5eb39361]{font-size:11.5px;color:#6366f1;font-weight:600}.chip[data-v-5eb39361]{display:inline-block;font-size:11px;padding:1px 7px;border-radius:999px;background:#f1f5f9;color:#64748b;white-space:nowrap}.chip-type[data-v-5eb39361]{background:#e0e7ff;color:#4338ca}.chip-lang[data-v-5eb39361]{background:#cffafe;color:#0e7490}.chip-warn[data-v-5eb39361]{background:#fef3c7;color:#b45309}.chip-primary[data-v-5eb39361]{background:#d1fae5;color:#047857}.lang-pill[data-v-5eb39361]{display:inline-flex;align-items:center;gap:5px;font-size:11.5px;padding:3px 9px;border-radius:999px;border:1px solid #e2e8f0;background:#f8fafc;color:#64748b;cursor:pointer;transition:all .12s;font-family:ui-monospace,SFMono-Regular,Menlo,monospace}.lang-pill[data-v-5eb39361]:hover{border-color:#c7d2fe;color:#4338ca}.lang-pill.on[data-v-5eb39361]{background:#4338ca;border-color:#4338ca;color:#fff}.lang-pill.primary[data-v-5eb39361]:not(.on){background:#ecfdf5;border-color:#a7f3d0;color:#047857}.lp-name[data-v-5eb39361]{font-family:inherit;opacity:.75;font-size:11px}.lang-pill.on .lp-name[data-v-5eb39361]{opacity:.9}.lang-picker[data-v-5eb39361]{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:3px;max-height:260px;overflow-y:auto;border:1px solid #eef2f7;border-radius:10px;padding:8px}.lang-opt[data-v-5eb39361]{display:flex;align-items:center;gap:6px;padding:3px 5px;border-radius:6px;cursor:pointer;font-size:12px}.lang-opt[data-v-5eb39361]:hover{background:#f8fafc}.lo-code[data-v-5eb39361]{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;color:#475569}.lo-name[data-v-5eb39361]{color:#94a3b8;font-size:11px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap} |
|||
@ -1 +0,0 @@ |
|||
import{_ as s}from"./CDB8L8go.js";import{_ as a,o as i,c as u,a as t,t as n,b as c,w as l,d}from"./6O01ZZML.js";import{u as f}from"./BvvkbLjV.js";const p={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"},m={class:"max-w-520px text-center"},h=["textContent"],b=["textContent"],x=["textContent"],g={class:"flex items-center justify-center w-full"},y={__name:"error-404",props:{appName:{type:String,default:"Nuxt"},status:{type:Number,default:404},statusText:{type:String,default:"Page not found"},description:{type:String,default:"Sorry, the page you are looking for could not be found."},backHome:{type:String,default:"Go back home"}},setup(e){const r=e;return f({title:`${r.status} - ${r.statusText} | ${r.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}a{color:inherit;text-decoration: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: }'}]}),(k,_)=>{const o=s;return i(),u("div",p,[t("div",m,[t("h1",{class:"font-semibold leading-none mb-4 sm:text-[110px] tabular-nums text-[80px]",textContent:n(e.status)},null,8,h),t("h2",{class:"font-semibold mb-2 sm:text-3xl text-2xl",textContent:n(e.statusText)},null,8,b),t("p",{class:"mb-4 px-2 text-[#64748B] text-md",textContent:n(e.description)},null,8,x),t("div",g,[c(o,{to:"/",class:"font-medium hover:text-[#00DC82] text-sm underline underline-offset-3"},{default:l(()=>[d(n(e.backHome),1)]),_:1})])])])}}},z=a(y,[["__scopeId","data-v-52418c85"]]);export{z as default}; |
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1 +0,0 @@ |
|||
.panel[data-v-e7a3debc]{background:#fff;border:1px solid #f1f5f9;border-radius:16px;box-shadow:0 1px 2px #0000000a}.logrow[data-v-e7a3debc]{display:grid;grid-template-columns:80px 64px 210px 92px 1fr 104px;gap:10px;align-items:start;padding:6px 12px;border-bottom:1px solid #f1f5f9;font-size:12px}.logrow[data-v-e7a3debc]:hover{background:#f8fafc}.logrow .t[data-v-e7a3debc]{font-family:ui-monospace,Menlo,monospace;color:#64748b}.lv[data-v-e7a3debc]{font-size:10px;font-weight:700;padding:1px 6px;border-radius:6px;white-space:nowrap}.lv-info[data-v-e7a3debc]{background:#dcfce7;color:#15803d}.lv-warn[data-v-e7a3debc]{background:#fef9c3;color:#a16207}.lv-error[data-v-e7a3debc]{background:#fee2e2;color:#b91c1c}.late[data-v-e7a3debc]{font-size:10px;color:#a16207;background:#fef3c7;border-radius:5px;padding:0 4px;margin-left:4px}.muted[data-v-e7a3debc]{color:#94a3b8}.app-name[data-v-e7a3debc]{font-weight:600;color:#0f172a}.unreg[data-v-e7a3debc]{font-size:10px;color:#b45309;background:#fef3c7;border-radius:5px;padding:0 5px;margin-left:5px;white-space:nowrap}#logHead[data-v-e7a3debc]{display:grid;grid-template-columns:80px 64px 210px 92px 1fr 104px;gap:10px;padding:7px 12px;font-size:11px;color:#94a3b8;border-bottom:1px solid #e2e8f0;background:#f8fafc} |
|||
@ -1 +0,0 @@ |
|||
.panel[data-v-a9764f3a]{background:#fff;border:1px solid #f1f5f9;border-radius:16px;box-shadow:0 1px 2px #0000000a;overflow:hidden}.panel-head[data-v-a9764f3a]{padding:12px 18px;gap:10px;border-bottom:1px solid #f8fafc;flex-wrap:wrap}.panel-head[data-v-a9764f3a],.sum-card[data-v-a9764f3a]{display:flex;align-items:center}.sum-card[data-v-a9764f3a]{gap:11px;background:#f8fafc;border:1px solid #eef2f7;border-radius:12px;padding:10px 13px;cursor:pointer;transition:all .15s}.sum-card[data-v-a9764f3a]:hover{border-color:#cbd5e1}.sum-card.on[data-v-a9764f3a]{border-color:#0f172a;background:#fff;box-shadow:inset 0 0 0 1px #0f172a}.sum-ico[data-v-a9764f3a]{width:30px;height:30px;border-radius:9px;display:flex;align-items:center;justify-content:center;flex-shrink:0;font-size:14px}.sum-lbl[data-v-a9764f3a]{font-size:11.5px;color:#94a3b8;line-height:1.2}.sum-val[data-v-a9764f3a]{font-size:19px;font-weight:700;line-height:1.3;letter-spacing:-.01em}.st-badge[data-v-a9764f3a]{font-size:11px;font-weight:700;padding:2px 9px;border-radius:999px;white-space:nowrap}.streak[data-v-a9764f3a]{font-size:10.5px;color:#be123c;margin-top:3px;font-weight:600}.chip[data-v-a9764f3a]{display:inline-block;font-size:11px;padding:1px 7px;border-radius:999px;background:#f1f5f9;color:#64748b;margin-right:4px;white-space:nowrap}.chip-scope[data-v-a9764f3a]{background:#e0e7ff;color:#4338ca}.chip-region[data-v-a9764f3a]{background:#cffafe;color:#0e7490}.pk-credential[data-v-a9764f3a]{background:#d1fae5;color:#047857}.pk-reachable[data-v-a9764f3a]{background:#fef3c7;color:#b45309}.pk-none[data-v-a9764f3a]{background:#f1f5f9;color:#94a3b8}.reason-cell[data-v-a9764f3a]{max-width:420px;font-size:12px;line-height:1.5}.issue-list[data-v-a9764f3a]{margin-top:3px}.issue[data-v-a9764f3a]{font-size:11px;color:#94a3b8} |
|||
@ -1 +0,0 @@ |
|||
.cat-card[data-v-6ea4e757]{padding:18px 20px;border-radius:16px;border:1px solid #eef2f7;background:#fff;cursor:pointer;transition:all .15s}.cat-card[data-v-6ea4e757]:hover{border-color:#c7d2fe;box-shadow:0 8px 24px #6366f11a;transform:translateY(-2px)}.cat-icon[data-v-6ea4e757]{width:46px;height:46px;border-radius:13px;display:flex;align-items:center;justify-content:center;color:#fff;flex-shrink:0}.provider-card[data-v-6ea4e757]{padding:12px 14px;border-radius:13px;border:1.5px solid #eef2f7;background:#fff;cursor:pointer;transition:all .15s}.provider-card[data-v-6ea4e757]:hover{border-color:#c7d2fe}.provider-card.active[data-v-6ea4e757]{border-color:#6366f1;background:linear-gradient(135deg,#eef2ff,#faf5ff);box-shadow:0 4px 14px #6366f11f}.provider-card.is-default[data-v-6ea4e757]{box-shadow:inset 0 0 0 1.5px #10b981}.provider-logo[data-v-6ea4e757]{width:34px;height:34px;border-radius:9px;display:flex;align-items:center;justify-content:center;color:#fff;font-weight:800;font-size:12px;letter-spacing:-.02em}.default-pick[data-v-6ea4e757]{display:inline-flex;align-items:center;gap:5px;font-size:11px;font-weight:600;color:#94a3b8;cursor:pointer;padding:3px 8px;border-radius:7px;border:1px solid #eef2f7;transition:all .15s}.default-pick[data-v-6ea4e757]:hover{border-color:#c7d2fe;color:#6366f1}.default-pick.on[data-v-6ea4e757]{color:#15803d;background:#dcfce7;border-color:#bbf7d0}.lock-tag[data-v-6ea4e757]{font-size:10px;font-weight:600;color:#dc2626;background:#fef2f2;padding:1px 6px;border-radius:5px} |
|||
@ -1 +0,0 @@ |
|||
import{b as a}from"./BgasD__e.js";let i=0;function f(){const o=a("app:toasts",()=>[]);function e(s,t="info",r=3e3){const n=++i;o.value.push({id:n,type:t,msg:s}),r>0&&setTimeout(()=>{o.value=o.value.filter(u=>u.id!==n)},r)}return{toasts:o,toast:e,success:(s,t)=>e(s,"success",t),error:(s,t)=>e(s,"error",t),info:(s,t)=>e(s,"info",t),warn:(s,t)=>e(s,"warning",t)}}export{f as u}; |
|||
@ -1,19 +0,0 @@ |
|||
import { escapeHtml } from '@vue/shared'; |
|||
|
|||
const _messages = { |
|||
"appName": "Nuxt", |
|||
"status": 500, |
|||
"statusText": "Internal server error", |
|||
"description": "This page is temporarily unavailable.", |
|||
"refresh": "Refresh this page" |
|||
}; |
|||
const template = (messages) => { |
|||
messages = { |
|||
..._messages, |
|||
...messages |
|||
}; |
|||
return "<!DOCTYPE html><html lang=\"en\"><head><title>" + escapeHtml(messages.status) + " - " + escapeHtml(messages.statusText) + " | " + escapeHtml(messages.appName) + "</title><meta charset=\"utf-8\"><meta content=\"width=device-width,initial-scale=1.0,minimum-scale=1.0\" name=\"viewport\"><script>!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)}}();<\/script><style>*,: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: }.grid{display:grid}.mb-2{margin-bottom:.5rem}.mb-4{margin-bottom:1rem}.max-w-520px{max-width:520px}.min-h-screen{min-height:100vh}.place-content-center{place-content:center}.overflow-hidden{overflow:hidden}.bg-white{--un-bg-opacity:1;background-color:rgb(255 255 255/var(--un-bg-opacity))}.px-2{padding-left:.5rem;padding-right:.5rem}.text-center{text-align:center}.text-\\[80px\\]{font-size:80px}.text-2xl{font-size:1.5rem;line-height:2rem}.text-\\[\\#020420\\]{--un-text-opacity:1;color:rgb(2 4 32/var(--un-text-opacity))}.text-\\[\\#64748B\\]{--un-text-opacity:1;color:rgb(100 116 139/var(--un-text-opacity))}.font-semibold{font-weight:600}.leading-none{line-height:1}.tracking-wide{letter-spacing:.025em}.font-sans{font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji}.tabular-nums{--un-numeric-spacing:tabular-nums;font-variant-numeric:var(--un-ordinal) var(--un-slashed-zero) var(--un-numeric-figure) var(--un-numeric-spacing) var(--un-numeric-fraction)}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}@media(prefers-color-scheme:dark){.dark\\:bg-\\[\\#020420\\]{--un-bg-opacity:1;background-color:rgb(2 4 32/var(--un-bg-opacity))}.dark\\:text-white{--un-text-opacity:1;color:rgb(255 255 255/var(--un-text-opacity))}}@media(min-width:640px){.sm\\:text-\\[110px\\]{font-size:110px}.sm\\:text-3xl{font-size:1.875rem;line-height:2.25rem}}</style></head><body 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\"><div class=\"max-w-520px text-center\"><h1 class=\"font-semibold leading-none mb-4 sm:text-[110px] tabular-nums text-[80px]\">" + escapeHtml(messages.status) + "</h1><h2 class=\"font-semibold mb-2 sm:text-3xl text-2xl\">" + escapeHtml(messages.statusText) + "</h2><p class=\"mb-4 px-2 text-[#64748B] text-md\">" + escapeHtml(messages.description) + "</p></div></body></html>"; |
|||
}; |
|||
|
|||
export { template }; |
|||
//# sourceMappingURL=error-500.mjs.map
|
|||
@ -1 +0,0 @@ |
|||
{"version":3,"file":"error-500.mjs","sources":["../../../../node_modules/.pnpm/@nuxt+nitro-server@4.4.8_@babel+plugin-syntax-typescript@7.29.7_@babel+core@7.29.7__db0_5045ebd3802f96c9dd021f3300fcdf4c/node_modules/@nuxt/nitro-server/dist/runtime/templates/error-500.mjs"],"names":[],"mappings":"","x_google_ignoreList":[0]} |
|||
@ -1,38 +0,0 @@ |
|||
import { defineComponent, mergeProps, useSSRContext } from 'vue'; |
|||
import { ssrRenderAttrs, ssrInterpolate } from 'vue/server-renderer'; |
|||
import { u as useToast } from './useToast-MBvLaNjH.mjs'; |
|||
|
|||
const _sfc_main = /* @__PURE__ */ defineComponent({ |
|||
__name: "AccountCredentialDialog", |
|||
__ssrInlineRender: true, |
|||
props: { |
|||
info: {} |
|||
}, |
|||
emits: ["close"], |
|||
setup(__props) { |
|||
useToast(); |
|||
return (_ctx, _push, _parent, _attrs) => { |
|||
if (__props.info) { |
|||
_push(`<div${ssrRenderAttrs(mergeProps({ class: "modal modal-open" }, _attrs))}><div class="modal-box max-w-md"><h3 class="font-bold text-base mb-1">${ssrInterpolate(__props.info.title)}</h3><p class="text-xs text-slate-400 mb-3">初始密码仅在此显示一次,关闭后无法再查看(如需重设请到「后台账号」改密)。</p><div class="rounded-xl border border-slate-200 bg-slate-50 p-3 space-y-2"><div class="flex items-center justify-between gap-3"><span class="text-xs text-slate-500">登录用户名</span><span class="font-mono font-semibold text-sm">${ssrInterpolate(__props.info.username)}</span></div><div class="flex items-center justify-between gap-3"><span class="text-xs text-slate-500">初始密码</span><span class="font-mono font-semibold text-sm">${ssrInterpolate(__props.info.password)}</span></div></div>`); |
|||
if (__props.info.mailTo) { |
|||
_push(`<div class="mt-3 text-xs text-emerald-600"> ✓ 凭据已邮件发送至 ${ssrInterpolate(__props.info.mailTo)}</div>`); |
|||
} else { |
|||
_push(`<div class="mt-3 text-xs text-amber-600"> ⚠ 凭据未能邮件送达${ssrInterpolate(__props.info.mailError ? ":" + __props.info.mailError : "")},请手工转达上面的用户名和密码。 </div>`); |
|||
} |
|||
_push(`<div class="modal-action"><button class="btn btn-ghost btn-sm">复制</button><button class="btn btn-primary btn-sm text-white">我已记录,关闭</button></div></div></div>`); |
|||
} else { |
|||
_push(`<!---->`); |
|||
} |
|||
}; |
|||
} |
|||
}); |
|||
const _sfc_setup = _sfc_main.setup; |
|||
_sfc_main.setup = (props, ctx) => { |
|||
const ssrContext = useSSRContext(); |
|||
(ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("components/AccountCredentialDialog.vue"); |
|||
return _sfc_setup ? _sfc_setup(props, ctx) : void 0; |
|||
}; |
|||
const __nuxt_component_0 = Object.assign(_sfc_main, { __name: "AccountCredentialDialog" }); |
|||
|
|||
export { __nuxt_component_0 as _ }; |
|||
//# sourceMappingURL=AccountCredentialDialog-D37zgaXm.mjs.map
|
|||
@ -1 +0,0 @@ |
|||
{"version":3,"file":"AccountCredentialDialog-D37zgaXm.mjs","sources":["../../../../node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/AccountCredentialDialog-D37zgaXm.js"],"names":[],"mappings":"","x_google_ignoreList":[0]} |
|||
@ -1,8 +0,0 @@ |
|||
import { A as AppDeployTab_vue_vue_type_style_index_0_scoped_c511dcb4_lang } from './_name_-styles-1.mjs-BmcUDjex.mjs'; |
|||
|
|||
const AppDeployTabStyles_4FdVYf2u = [ |
|||
AppDeployTab_vue_vue_type_style_index_0_scoped_c511dcb4_lang |
|||
]; |
|||
|
|||
export { AppDeployTabStyles_4FdVYf2u as default }; |
|||
//# sourceMappingURL=AppDeployTab-styles.4FdVYf2u.mjs.map
|
|||
@ -1 +0,0 @@ |
|||
{"version":3,"file":"AppDeployTab-styles.4FdVYf2u.mjs","sources":["../../../../node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/AppDeployTab-styles.4FdVYf2u.mjs"],"names":["style_0"],"mappings":"","x_google_ignoreList":[0]} |
|||
@ -1,8 +0,0 @@ |
|||
import { A as AppModuleTab_vue_vue_type_style_index_0_scoped_ff0e4b71_lang } from './_name_-styles-2.mjs-BXCS7H7R.mjs'; |
|||
|
|||
const AppModuleTabStyles__mOVrlE = [ |
|||
AppModuleTab_vue_vue_type_style_index_0_scoped_ff0e4b71_lang |
|||
]; |
|||
|
|||
export { AppModuleTabStyles__mOVrlE as default }; |
|||
//# sourceMappingURL=AppModuleTab-styles._m-oVrlE.mjs.map
|
|||
@ -1 +0,0 @@ |
|||
{"version":3,"file":"AppModuleTab-styles._m-oVrlE.mjs","sources":["../../../../node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/AppModuleTab-styles._m-oVrlE.mjs"],"names":["style_0"],"mappings":"","x_google_ignoreList":[0]} |
|||
@ -1,69 +0,0 @@ |
|||
import { defineComponent, computed, mergeProps, useSSRContext } from 'vue'; |
|||
import { ssrRenderAttrs, ssrRenderClass, ssrRenderList, ssrInterpolate, ssrIncludeBooleanAttr, ssrRenderAttr } from 'vue/server-renderer'; |
|||
import { L as LANG_OPTIONS, l as langName } from './useLangOptions-CXXbv5NM.mjs'; |
|||
import { _ as _export_sfc } from './server.mjs'; |
|||
|
|||
const _sfc_main = /* @__PURE__ */ defineComponent({ |
|||
__name: "LangSelect", |
|||
__ssrInlineRender: true, |
|||
props: { |
|||
modelValue: {}, |
|||
multiple: { type: Boolean, default: false }, |
|||
disabled: { type: Boolean, default: false }, |
|||
options: { default: void 0 } |
|||
}, |
|||
emits: ["update:modelValue"], |
|||
setup(__props, { emit: __emit }) { |
|||
const props = __props; |
|||
const opts = computed(() => props.options && props.options.length ? props.options : LANG_OPTIONS); |
|||
const selected = computed( |
|||
() => (props.modelValue || "").split(",").map((s) => s.trim()).filter(Boolean) |
|||
); |
|||
function nameOf(code) { |
|||
return langName(code); |
|||
} |
|||
return (_ctx, _push, _parent, _attrs) => { |
|||
_push(`<div${ssrRenderAttrs(mergeProps({ class: "lang-select" }, _attrs))} data-v-4903af59>`); |
|||
if (__props.multiple) { |
|||
_push(`<!--[--><div class="${ssrRenderClass([{ "lang-disabled": __props.disabled }, "lang-chips"])}" data-v-4903af59><!--[-->`); |
|||
ssrRenderList(selected.value, (code) => { |
|||
_push(`<span class="lang-chip" data-v-4903af59>${ssrInterpolate(code)}<span class="lang-chip-name" data-v-4903af59>${ssrInterpolate(nameOf(code))}</span><button type="button" class="lang-x" data-v-4903af59>×</button></span>`); |
|||
}); |
|||
_push(`<!--]-->`); |
|||
if (!selected.value.length) { |
|||
_push(`<span class="lang-empty" data-v-4903af59>未选择语言</span>`); |
|||
} else { |
|||
_push(`<!---->`); |
|||
} |
|||
_push(`</div>`); |
|||
if (!__props.disabled) { |
|||
_push(`<details class="lang-dd" data-v-4903af59><summary class="lang-dd-sum" data-v-4903af59>+ 选择语言(已选 ${ssrInterpolate(selected.value.length)})</summary><div class="lang-dd-panel" data-v-4903af59><!--[-->`); |
|||
ssrRenderList(opts.value, (o) => { |
|||
_push(`<label class="lang-opt" data-v-4903af59><input type="checkbox" class="checkbox checkbox-xs checkbox-primary"${ssrIncludeBooleanAttr(selected.value.includes(o.code)) ? " checked" : ""} data-v-4903af59><span class="lang-opt-code" data-v-4903af59>${ssrInterpolate(o.code)}</span><span class="lang-opt-name" data-v-4903af59>${ssrInterpolate(o.name)}</span></label>`); |
|||
}); |
|||
_push(`<!--]--></div></details>`); |
|||
} else { |
|||
_push(`<!---->`); |
|||
} |
|||
_push(`<!--]-->`); |
|||
} else { |
|||
_push(`<select class="select select-bordered select-sm w-full text-xs"${ssrRenderAttr("value", __props.modelValue)}${ssrIncludeBooleanAttr(__props.disabled) ? " disabled" : ""} data-v-4903af59><option value="" data-v-4903af59>(未设置)</option><!--[-->`); |
|||
ssrRenderList(opts.value, (o) => { |
|||
_push(`<option${ssrRenderAttr("value", o.code)} data-v-4903af59>${ssrInterpolate(o.code)} · ${ssrInterpolate(o.name)}</option>`); |
|||
}); |
|||
_push(`<!--]--></select>`); |
|||
} |
|||
_push(`</div>`); |
|||
}; |
|||
} |
|||
}); |
|||
const _sfc_setup = _sfc_main.setup; |
|||
_sfc_main.setup = (props, ctx) => { |
|||
const ssrContext = useSSRContext(); |
|||
(ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("components/LangSelect.vue"); |
|||
return _sfc_setup ? _sfc_setup(props, ctx) : void 0; |
|||
}; |
|||
const __nuxt_component_0 = /* @__PURE__ */ Object.assign(_export_sfc(_sfc_main, [["__scopeId", "data-v-4903af59"]]), { __name: "LangSelect" }); |
|||
|
|||
export { __nuxt_component_0 as _ }; |
|||
//# sourceMappingURL=LangSelect-Bvw-e1Cn.mjs.map
|
|||
@ -1 +0,0 @@ |
|||
{"version":3,"file":"LangSelect-Bvw-e1Cn.mjs","sources":["../../../../node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/LangSelect-Bvw-e1Cn.js"],"names":[],"mappings":"","x_google_ignoreList":[0]} |
|||
@ -1,8 +0,0 @@ |
|||
const LangSelect_vue_vue_type_style_index_0_scoped_4903af59_lang = ".lang-select[data-v-4903af59]{font-size:12px}.lang-chips[data-v-4903af59]{display:flex;flex-wrap:wrap;gap:4px;margin-bottom:4px;min-height:22px}.lang-disabled[data-v-4903af59]{opacity:.5;pointer-events:none}.lang-chip[data-v-4903af59]{display:inline-flex;align-items:center;gap:2px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11px;background:#ede9fe;color:#6d28d9;padding:1px 6px;border-radius:9999px}.lang-chip-name[data-v-4903af59],.lang-x[data-v-4903af59]{color:#a78bfa;margin-left:3px}.lang-x[data-v-4903af59]{font-weight:700;line-height:1}.lang-x[data-v-4903af59]:hover{color:#6d28d9}.lang-empty[data-v-4903af59]{font-size:11px;color:#94a3b8}.lang-dd[data-v-4903af59]{position:relative}.lang-dd-sum[data-v-4903af59]{cursor:pointer;font-size:12px;color:#7c3aed;list-style:none;-webkit-user-select:none;-moz-user-select:none;user-select:none}.lang-dd-sum[data-v-4903af59]::-webkit-details-marker{display:none}.lang-dd-panel[data-v-4903af59]{position:absolute;z-index:30;margin-top:4px;background:#fff;border:1px solid #e2e8f0;border-radius:8px;box-shadow:0 8px 24px #0f172a24;padding:6px;max-height:260px;overflow-y:auto;width:230px}.lang-opt[data-v-4903af59]{display:flex;align-items:center;gap:6px;padding:3px 6px;border-radius:6px;cursor:pointer}.lang-opt[data-v-4903af59]:hover{background:#f1f5f9}.lang-opt-code[data-v-4903af59]{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;color:#334155}.lang-opt-name[data-v-4903af59]{color:#94a3b8}"; |
|||
|
|||
const LangSelectStyles_Bi81RebM = [ |
|||
LangSelect_vue_vue_type_style_index_0_scoped_4903af59_lang |
|||
]; |
|||
|
|||
export { LangSelectStyles_Bi81RebM as default }; |
|||
//# sourceMappingURL=LangSelect-styles.Bi81RebM.mjs.map
|
|||
@ -1 +0,0 @@ |
|||
{"version":3,"file":"LangSelect-styles.Bi81RebM.mjs","sources":["../../../../node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/LangSelect-styles-1.mjs-BjhBSOse.js","../../../../node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/LangSelect-styles.Bi81RebM.mjs"],"names":["style_0"],"mappings":"","x_google_ignoreList":[0,1]} |
|||
@ -1,8 +0,0 @@ |
|||
import { S as SvcAlertBanner_vue_vue_type_style_index_0_scoped_3dd2fb7c_lang } from './dashboard-styles-1.mjs-CFxtv9Pt.mjs'; |
|||
|
|||
const SvcAlertBannerStyles_C9CJuYwV = [ |
|||
SvcAlertBanner_vue_vue_type_style_index_0_scoped_3dd2fb7c_lang |
|||
]; |
|||
|
|||
export { SvcAlertBannerStyles_C9CJuYwV as default }; |
|||
//# sourceMappingURL=SvcAlertBanner-styles.C9CJuYwV.mjs.map
|
|||
@ -1 +0,0 @@ |
|||
{"version":3,"file":"SvcAlertBanner-styles.C9CJuYwV.mjs","sources":["../../../../node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/SvcAlertBanner-styles.C9CJuYwV.mjs"],"names":["style_0"],"mappings":"","x_google_ignoreList":[0]} |
|||
@ -1,537 +0,0 @@ |
|||
import { defineComponent, computed, ref, reactive, watch, unref, mergeProps, useSSRContext } from 'vue'; |
|||
import { ssrRenderAttrs, ssrInterpolate, ssrRenderClass, ssrRenderStyle, ssrRenderAttr, ssrRenderList, ssrRenderComponent, ssrIncludeBooleanAttr, ssrLooseContain, ssrLooseEqual, ssrRenderDynamicModel } from 'vue/server-renderer'; |
|||
import { u as useApi } from './useApi-BNSkSrat.mjs'; |
|||
import { u as useToast } from './useToast-MBvLaNjH.mjs'; |
|||
import { _ as _export_sfc, c as useRoute$1, b as useRouter, a as useAuthStore } from './server.mjs'; |
|||
import { r as regionLabel, n as normalizeRegion, R as REGION_OPTIONS } from './regions-D1dSykUW.mjs'; |
|||
import '../nitro/nitro.mjs'; |
|||
import 'node:http'; |
|||
import 'node:https'; |
|||
import 'node:events'; |
|||
import 'node:buffer'; |
|||
import 'node:fs'; |
|||
import 'node:path'; |
|||
import 'node:crypto'; |
|||
import 'node:url'; |
|||
import '../routes/renderer.mjs'; |
|||
import 'vue-bundle-renderer/runtime'; |
|||
import 'unhead/server'; |
|||
import 'devalue'; |
|||
import 'unhead/utils'; |
|||
import 'pinia'; |
|||
import 'perfect-debounce'; |
|||
|
|||
const _sfc_main$2 = /* @__PURE__ */ defineComponent({ |
|||
__name: "AppDeployTab", |
|||
__ssrInlineRender: true, |
|||
props: { |
|||
appName: {}, |
|||
defaultImage: {}, |
|||
deployments: {}, |
|||
envs: {} |
|||
}, |
|||
emits: ["refresh", "configure"], |
|||
setup(__props, { expose: __expose, emit: __emit }) { |
|||
const props = __props; |
|||
useApi(); |
|||
useToast(); |
|||
useAuthStore(); |
|||
useRouter(); |
|||
function dbName(dsn) { |
|||
const m = (dsn || "").match(/\/([^/?]+)\?/); |
|||
return m ? m[1] : dsn ? "(自定义)" : "未配置"; |
|||
} |
|||
function isPinned(tag) { |
|||
const t = (tag || "").trim(); |
|||
return !!t && t !== "latest"; |
|||
} |
|||
function envName(id) { |
|||
if (!id) return ""; |
|||
return props.envs.find((e) => e.id === id)?.name ?? "#" + id; |
|||
} |
|||
const formDlg = ref(null); |
|||
const dIsEditing = ref(false); |
|||
const dMode = ref("existing"); |
|||
const dForm = reactive({ |
|||
id: 0, |
|||
name: "", |
|||
region: "", |
|||
env_id: 0, |
|||
base_url: "", |
|||
service_dsn: "", |
|||
deploy_dir: "", |
|||
image_name: "", |
|||
image_tag: "", |
|||
remark: "", |
|||
enabled: true |
|||
}); |
|||
const testPassed = ref(false); |
|||
const testing = ref(false); |
|||
const testResult = reactive({ show: false, apiOk: false, apiMsg: "", dbOk: false, dbMsg: "" }); |
|||
const availableRegions = computed(() => { |
|||
const used = new Set( |
|||
props.deployments.filter((d) => d.id !== dForm.id).map((d) => normalizeRegion(d.region)).filter(Boolean) |
|||
); |
|||
return REGION_OPTIONS.filter((r) => !used.has(r.value) || r.value === dForm.region); |
|||
}); |
|||
function resetTest() { |
|||
testPassed.value = false; |
|||
testResult.show = false; |
|||
} |
|||
function openNew() { |
|||
dIsEditing.value = false; |
|||
dMode.value = "existing"; |
|||
Object.assign(dForm, { |
|||
id: 0, |
|||
name: "", |
|||
region: "", |
|||
env_id: 0, |
|||
base_url: "", |
|||
service_dsn: "", |
|||
deploy_dir: "", |
|||
image_name: props.defaultImage, |
|||
image_tag: "", |
|||
remark: "", |
|||
enabled: true |
|||
}); |
|||
resetTest(); |
|||
formDlg.value?.showModal(); |
|||
} |
|||
ref(null); |
|||
ref(null); |
|||
const up = reactive({ |
|||
id: 0, |
|||
label: "", |
|||
envName: "", |
|||
deployDir: "", |
|||
tag: "", |
|||
tags: [], |
|||
tagMode: "list", |
|||
tagsLoading: false, |
|||
tagsError: "", |
|||
log: "", |
|||
show: false, |
|||
running: false, |
|||
ok: false, |
|||
canRun: false, |
|||
btnText: "开始升级" |
|||
}); |
|||
ref(null); |
|||
const az = reactive({ |
|||
appId: 0, |
|||
label: "", |
|||
start: "", |
|||
end: "", |
|||
mode: "", |
|||
steps: [], |
|||
curIndex: 0, |
|||
curTotal: 0, |
|||
curName: "", |
|||
pct: 0, |
|||
errMsg: "", |
|||
report: null, |
|||
running: false, |
|||
btnText: "开始分析" |
|||
}); |
|||
__expose({ openNew }); |
|||
return (_ctx, _push, _parent, _attrs) => { |
|||
_push(`<div${ssrRenderAttrs(_attrs)} data-v-c511dcb4><div class="card" data-v-c511dcb4><div class="card-head" data-v-c511dcb4><div data-v-c511dcb4><div class="card-title" data-v-c511dcb4>区域部署</div><div class="card-desc" data-v-c511dcb4> 每个区域一份部署,各自连自己的业务库。「升级」会 SSH 到绑定的环境节点,在部署目录执行 <span class="font-mono" data-v-c511dcb4>docker compose pull & up -d</span>。 </div></div><button class="btn btn-primary btn-xs text-white shrink-0" data-v-c511dcb4>+ 部署新环境</button></div>`); |
|||
if (!__props.deployments.length) { |
|||
_push(`<div class="py-14 text-center text-slate-400 text-sm" data-v-c511dcb4> 该应用还没有部署,点右上「+ 部署新环境」添加。 </div>`); |
|||
} else { |
|||
_push(`<!---->`); |
|||
} |
|||
_push(`<!--[-->`); |
|||
ssrRenderList(__props.deployments, (d) => { |
|||
_push(`<div class="${ssrRenderClass([{ pending: d.status === "pending" }, "dep"])}" data-v-c511dcb4><div class="min-w-0" data-v-c511dcb4><div class="dep-name" data-v-c511dcb4><span class="chip chip-dep" data-v-c511dcb4>部署</span><span class="truncate" data-v-c511dcb4>${ssrInterpolate(d.name || "部署#" + d.id)}</span>`); |
|||
if (d.status === "pending") { |
|||
_push(`<span class="chip chip-warn" data-v-c511dcb4>待部署</span>`); |
|||
} else { |
|||
_push(`<span class="chip chip-ok" data-v-c511dcb4>已接入</span>`); |
|||
} |
|||
if (!d.enabled) { |
|||
_push(`<span class="chip" data-v-c511dcb4>停用</span>`); |
|||
} else { |
|||
_push(`<!---->`); |
|||
} |
|||
_push(`</div><div class="dep-sub" data-v-c511dcb4>#${ssrInterpolate(d.id)} · ${ssrInterpolate(unref(regionLabel)(d.region))} · 业务库 ${ssrInterpolate(dbName(d.service_dsn))}</div></div><div data-v-c511dcb4><div class="field-l" data-v-c511dcb4>环境节点</div><div class="${ssrRenderClass([d.env_id ? "text-slate-600" : "text-red-500", "text-xs truncate"])}"${ssrRenderAttr("title", envName(d.env_id) || "未绑定")} data-v-c511dcb4>${ssrInterpolate(envName(d.env_id) || "未绑定")}</div></div><div data-v-c511dcb4><div class="field-l" data-v-c511dcb4>当前版本</div><div class="flex items-center gap-1.5" data-v-c511dcb4><span class="${ssrRenderClass([isPinned(d.image_tag) ? "chip-ok" : "chip-warn", "chip chip-mono"])}" data-v-c511dcb4>${ssrInterpolate(d.image_tag || "latest")}</span>`); |
|||
if (!isPinned(d.image_tag)) { |
|||
_push(`<span class="text-[10.5px] text-amber-700" title="latest 是可变 tag,升级后无法从列表看出实际版本" data-v-c511dcb4>未固定</span>`); |
|||
} else { |
|||
_push(`<!---->`); |
|||
} |
|||
_push(`</div></div><div class="min-w-0" data-v-c511dcb4><div class="field-l" data-v-c511dcb4>部署目录</div><div class="${ssrRenderClass([d.deploy_dir ? "text-slate-500" : "text-red-500", "font-mono text-[11px] truncate"])}" data-v-c511dcb4>${ssrInterpolate(d.deploy_dir || "未填")}</div></div><div class="dep-acts" data-v-c511dcb4><button class="btn btn-xs btn-warning" data-v-c511dcb4>升级</button><button class="btn btn-xs" data-v-c511dcb4>配置</button><button class="btn btn-xs btn-ghost text-teal-600"${ssrIncludeBooleanAttr(!d.base_url) ? " disabled" : ""}${ssrRenderAttr("title", d.base_url ? "打开该部署的 Swagger 文档" : "该部署未配置对外地址(base_url)")} data-v-c511dcb4>API 测试</button><button class="btn btn-xs btn-ghost" data-v-c511dcb4>编辑</button><button class="btn btn-xs btn-ghost text-emerald-600"${ssrIncludeBooleanAttr(d.status === "pending") ? " disabled" : ""} data-v-c511dcb4>分析</button><button class="btn btn-xs btn-ghost text-indigo-500"${ssrIncludeBooleanAttr(d.status === "pending") ? " disabled" : ""} data-v-c511dcb4>发事件</button><button class="btn btn-xs btn-ghost text-red-500" data-v-c511dcb4>删除</button></div></div>`); |
|||
}); |
|||
_push(`<!--]--></div><dialog class="modal" data-v-c511dcb4><div class="modal-box max-w-3xl" data-v-c511dcb4><h3 class="font-bold text-lg" data-v-c511dcb4>${ssrInterpolate(dIsEditing.value ? "编辑部署" : "部署新环境")}</h3>`); |
|||
if (!dIsEditing.value) { |
|||
_push(`<div class="tabs tabs-boxed bg-slate-100 w-fit my-3" data-v-c511dcb4><a class="${ssrRenderClass([dMode.value === "existing" ? "tab-active" : "", "tab"])}" data-v-c511dcb4>添加现有</a><a class="${ssrRenderClass([dMode.value === "deploy" ? "tab-active" : "", "tab"])}" data-v-c511dcb4>部署到目标环境</a></div>`); |
|||
} else { |
|||
_push(`<!---->`); |
|||
} |
|||
_push(`<p class="${ssrRenderClass([dIsEditing.value ? "mt-1" : "", "text-xs text-slate-400 mb-4"])}" data-v-c511dcb4>`); |
|||
if (dIsEditing.value) { |
|||
_push(`<!--[-->改好后回列表点「升级」执行远程部署(拉新镜像并重启)。<!--]-->`); |
|||
} else if (dMode.value === "existing") { |
|||
_push(`<!--[-->把「已经部署好的应用区域」加进来:填地址与业务库 DSN,测试通过后保存。<!--]-->`); |
|||
} else { |
|||
_push(`<!--[-->选一个目标环境节点,先建关联并标记<b data-v-c511dcb4>待部署</b>;保存后回列表点「升级」执行首次部署。<!--]-->`); |
|||
} |
|||
_push(`</p><form class="space-y-3" data-v-c511dcb4><div class="grid grid-cols-2 gap-3" data-v-c511dcb4><div class="form-control" data-v-c511dcb4><label class="label py-1" data-v-c511dcb4><span class="label-text text-sm font-medium" data-v-c511dcb4>所属应用</span></label><input${ssrRenderAttr("value", __props.appName)} type="text" class="input input-bordered input-sm bg-slate-100" readonly data-v-c511dcb4></div><div class="form-control" data-v-c511dcb4><label class="label py-1" data-v-c511dcb4><span class="label-text text-sm font-medium" data-v-c511dcb4>部署名称 *</span></label><input${ssrRenderAttr("value", dForm.name)} type="text" class="input input-bordered input-sm" required${ssrRenderAttr("placeholder", `如 ${__props.appName}(国内)`)} data-v-c511dcb4></div></div><div class="grid grid-cols-2 gap-3" data-v-c511dcb4><div class="form-control" data-v-c511dcb4><label class="label py-1" data-v-c511dcb4><span class="label-text text-sm font-medium" data-v-c511dcb4>区域</span></label><select class="select select-bordered select-sm" data-v-c511dcb4><option value="" data-v-c511dcb4${ssrIncludeBooleanAttr(Array.isArray(dForm.region) ? ssrLooseContain(dForm.region, "") : ssrLooseEqual(dForm.region, "")) ? " selected" : ""}>未指定</option><!--[-->`); |
|||
ssrRenderList(availableRegions.value, (r) => { |
|||
_push(`<option${ssrRenderAttr("value", r.value)} data-v-c511dcb4${ssrIncludeBooleanAttr(Array.isArray(dForm.region) ? ssrLooseContain(dForm.region, r.value) : ssrLooseEqual(dForm.region, r.value)) ? " selected" : ""}>${ssrInterpolate(r.label)}</option>`); |
|||
}); |
|||
_push(`<!--]--></select><span class="text-[11px] text-slate-400 mt-1" data-v-c511dcb4>一个应用国内/海外各一份部署,已用的区域不再出现。</span></div><div class="form-control" data-v-c511dcb4><label class="label py-1" data-v-c511dcb4><span class="label-text text-sm font-medium" data-v-c511dcb4>部署环境${ssrInterpolate(dMode.value === "deploy" ? " *" : "")}</span></label><select class="select select-bordered select-sm" data-v-c511dcb4><option${ssrRenderAttr("value", 0)} data-v-c511dcb4${ssrIncludeBooleanAttr(Array.isArray(dForm.env_id) ? ssrLooseContain(dForm.env_id, 0) : ssrLooseEqual(dForm.env_id, 0)) ? " selected" : ""}>${ssrInterpolate(dMode.value === "deploy" ? "请选择目标环境" : "未关联")}</option><!--[-->`); |
|||
ssrRenderList(__props.envs, (e) => { |
|||
_push(`<option${ssrRenderAttr("value", e.id)} data-v-c511dcb4${ssrIncludeBooleanAttr(Array.isArray(dForm.env_id) ? ssrLooseContain(dForm.env_id, e.id) : ssrLooseEqual(dForm.env_id, e.id)) ? " selected" : ""}>${ssrInterpolate(e.name)}(${ssrInterpolate(e.code || "-")})</option>`); |
|||
}); |
|||
_push(`<!--]--></select></div></div><div class="grid grid-cols-3 gap-3" data-v-c511dcb4><div class="form-control" data-v-c511dcb4><label class="label py-1" data-v-c511dcb4><span class="label-text text-sm font-medium" data-v-c511dcb4>部署目录</span></label><input${ssrRenderAttr("value", dForm.deploy_dir)} type="text" class="input input-bordered input-sm font-mono text-xs" placeholder="/home/work/app" data-v-c511dcb4></div><div class="form-control" data-v-c511dcb4><label class="label py-1" data-v-c511dcb4><span class="label-text text-sm font-medium" data-v-c511dcb4>镜像名</span></label><input${ssrRenderAttr("value", dForm.image_name)} type="text" class="input input-bordered input-sm font-mono text-xs"${ssrRenderAttr("placeholder", __props.defaultImage || "默认取应用")} data-v-c511dcb4></div><div class="form-control" data-v-c511dcb4><label class="label py-1" data-v-c511dcb4><span class="label-text text-sm font-medium" data-v-c511dcb4>镜像 Tag</span></label><input${ssrRenderAttr("value", dForm.image_tag)} type="text" class="input input-bordered input-sm font-mono text-xs" placeholder="0.1.1 / latest" data-v-c511dcb4></div></div><div class="form-control" data-v-c511dcb4><label class="label py-1" data-v-c511dcb4><span class="label-text text-sm font-medium" data-v-c511dcb4>业务库 DSN${ssrInterpolate(dMode.value === "existing" ? " *" : "")}</span></label><input${ssrRenderAttr("value", dForm.service_dsn)} type="text" class="input input-bordered input-sm font-mono text-xs" placeholder="root:pwd@tcp(host:3306)/earphone?charset=utf8mb4&parseTime=True&loc=Local" data-v-c511dcb4><span class="text-[11px] text-slate-400 mt-1" data-v-c511dcb4>业务功能配置、会议记录服务配置都写在这个库里。</span></div>`); |
|||
if (dMode.value === "existing") { |
|||
_push(`<!--[--><div class="form-control" data-v-c511dcb4><label class="label py-1" data-v-c511dcb4><span class="label-text text-sm font-medium" data-v-c511dcb4>应用地址 *</span></label><input${ssrRenderAttr("value", dForm.base_url)} type="text" class="input input-bordered input-sm" placeholder="https://api.xxx.com/" data-v-c511dcb4><span class="text-[11px] text-slate-400 mt-1" data-v-c511dcb4>用于通知应用业务服务事件(如配置更新)、打开 Swagger。</span></div>`); |
|||
if (testResult.show) { |
|||
_push(`<div class="text-sm space-y-0.5" data-v-c511dcb4><div class="${ssrRenderClass(testResult.apiOk ? "text-green-700" : "text-red-600")}" data-v-c511dcb4>${ssrInterpolate(testResult.apiOk ? "✓" : "✗")} 应用地址:${ssrInterpolate(testResult.apiMsg)}</div><div class="${ssrRenderClass(testResult.dbOk ? "text-green-700" : "text-red-600")}" data-v-c511dcb4>${ssrInterpolate(testResult.dbOk ? "✓" : "✗")} 业务库:${ssrInterpolate(testResult.dbMsg)}</div></div>`); |
|||
} else { |
|||
_push(`<!---->`); |
|||
} |
|||
_push(`<!--]-->`); |
|||
} else { |
|||
_push(`<!---->`); |
|||
} |
|||
_push(`<div class="form-control" data-v-c511dcb4><label class="label py-1" data-v-c511dcb4><span class="label-text text-sm font-medium" data-v-c511dcb4>备注</span></label><input${ssrRenderAttr("value", dForm.remark)} type="text" class="input input-bordered input-sm" data-v-c511dcb4></div><label class="flex items-center gap-2 cursor-pointer" data-v-c511dcb4><input${ssrIncludeBooleanAttr(Array.isArray(dForm.enabled) ? ssrLooseContain(dForm.enabled, null) : dForm.enabled) ? " checked" : ""} type="checkbox" class="toggle toggle-primary toggle-sm" data-v-c511dcb4><span class="text-sm" data-v-c511dcb4>启用</span></label><div class="modal-action" data-v-c511dcb4><button type="button" class="btn btn-ghost btn-sm" data-v-c511dcb4>取消</button>`); |
|||
if (dMode.value === "existing") { |
|||
_push(`<button type="button" class="btn btn-outline btn-sm"${ssrIncludeBooleanAttr(testing.value) ? " disabled" : ""} data-v-c511dcb4>${ssrInterpolate(testing.value ? "测试中…" : "测试连接")}</button>`); |
|||
} else { |
|||
_push(`<!---->`); |
|||
} |
|||
_push(`<button type="submit" class="btn btn-primary btn-sm text-white"${ssrIncludeBooleanAttr(!dIsEditing.value && dMode.value === "existing" && !testPassed.value) ? " disabled" : ""} data-v-c511dcb4>保存</button></div>`); |
|||
if (!dIsEditing.value && dMode.value === "existing") { |
|||
_push(`<p class="text-[11px] text-slate-400 text-right" data-v-c511dcb4> 需先「测试连接」通过(应用地址可达 + 业务库可连)才能保存。 </p>`); |
|||
} else { |
|||
_push(`<!---->`); |
|||
} |
|||
_push(`</form></div><form method="dialog" class="modal-backdrop" data-v-c511dcb4><button data-v-c511dcb4>close</button></form></dialog><dialog class="modal" data-v-c511dcb4><div class="modal-box max-w-2xl" data-v-c511dcb4><h3 class="font-bold text-lg" data-v-c511dcb4>升级部署</h3><p class="text-sm text-slate-500 mt-1" data-v-c511dcb4>${ssrInterpolate(up.label)}</p><div class="text-xs text-amber-700 mt-3 bg-amber-50 border border-amber-100 rounded-lg p-3 leading-relaxed" data-v-c511dcb4> 将 <b data-v-c511dcb4>SSH 连到该部署绑定的环境节点</b>,进入部署目录执行 <span class="font-mono" data-v-c511dcb4>docker login → compose pull → up -d → 清理旧镜像</span>。<br data-v-c511dcb4> · 需服务器上已维护好 <span class="font-mono" data-v-c511dcb4>docker-compose.yml / .env / confs</span>(本操作不上传真实配置)。<br data-v-c511dcb4> · 会<b data-v-c511dcb4>重启该部署的容器</b>,请确认无误后再执行。 </div><dl class="grid grid-cols-[76px_1fr] gap-x-3 gap-y-1 text-xs mt-4" data-v-c511dcb4><dt class="text-slate-400" data-v-c511dcb4>环境节点</dt><dd class="${ssrRenderClass(up.envName ? "font-medium text-slate-700" : "font-medium text-red-500")}" data-v-c511dcb4>${ssrInterpolate(up.envName || "未绑定 —— 请先在「编辑」里选择环境节点")}</dd><dt class="text-slate-400" data-v-c511dcb4>部署目录</dt><dd class="${ssrRenderClass(up.deployDir ? "font-mono text-slate-700" : "font-medium text-red-500")}" data-v-c511dcb4>${ssrInterpolate(up.deployDir || "未填 —— 请先在「编辑」里填写远端部署目录")}</dd></dl><div class="mt-3" data-v-c511dcb4><div class="flex items-center justify-between mb-1" data-v-c511dcb4><label class="text-xs text-slate-500" data-v-c511dcb4>镜像版本 Tag</label><button type="button" class="text-xs text-indigo-500 hover:underline"${ssrIncludeBooleanAttr(up.running) ? " disabled" : ""} data-v-c511dcb4>${ssrInterpolate(up.tagMode === "list" ? "手动输入…" : "从仓库选择")}</button></div>`); |
|||
if (up.tagMode === "list") { |
|||
_push(`<div class="flex gap-2" data-v-c511dcb4><select class="select select-bordered select-sm flex-1 font-mono"${ssrIncludeBooleanAttr(up.running || up.tagsLoading) ? " disabled" : ""} data-v-c511dcb4><option value="" data-v-c511dcb4${ssrIncludeBooleanAttr(Array.isArray(up.tag) ? ssrLooseContain(up.tag, "") : ssrLooseEqual(up.tag, "")) ? " selected" : ""}>${ssrInterpolate(up.tagsLoading ? "加载可用版本中…" : "请选择版本")}</option>`); |
|||
if (up.tag && !up.tags.includes(up.tag)) { |
|||
_push(`<option${ssrRenderAttr("value", up.tag)} data-v-c511dcb4${ssrIncludeBooleanAttr(Array.isArray(up.tag) ? ssrLooseContain(up.tag, up.tag) : ssrLooseEqual(up.tag, up.tag)) ? " selected" : ""}>${ssrInterpolate(up.tag)}(当前记录)</option>`); |
|||
} else { |
|||
_push(`<!---->`); |
|||
} |
|||
_push(`<!--[-->`); |
|||
ssrRenderList(up.tags, (t) => { |
|||
_push(`<option${ssrRenderAttr("value", t)} data-v-c511dcb4${ssrIncludeBooleanAttr(Array.isArray(up.tag) ? ssrLooseContain(up.tag, t) : ssrLooseEqual(up.tag, t)) ? " selected" : ""}>${ssrInterpolate(t)}${ssrInterpolate(t === "latest" ? " · 不固定,不推荐" : "")}</option>`); |
|||
}); |
|||
_push(`<!--]--></select><button type="button" class="btn btn-ghost btn-sm"${ssrIncludeBooleanAttr(up.running || up.tagsLoading) ? " disabled" : ""} data-v-c511dcb4>刷新</button></div>`); |
|||
} else { |
|||
_push(`<input${ssrRenderAttr("value", up.tag)} type="text" class="input input-bordered input-sm w-full font-mono" placeholder="0.1.1"${ssrIncludeBooleanAttr(up.running) ? " disabled" : ""} data-v-c511dcb4>`); |
|||
} |
|||
if (up.tagsError) { |
|||
_push(`<p class="text-xs text-amber-600 mt-1" data-v-c511dcb4> 拉取仓库版本失败:${ssrInterpolate(up.tagsError)}(可点上方「手动输入」直接填版本号,或点「刷新」重试) </p>`); |
|||
} else if (!isPinned(up.tag)) { |
|||
_push(`<p class="text-xs text-amber-600 mt-1" data-v-c511dcb4> ⚠ 未固定版本,升级后列表无法体现具体版本号,建议选明确版本(如 0.1.1)。 </p>`); |
|||
} else { |
|||
_push(`<!---->`); |
|||
} |
|||
_push(`</div>`); |
|||
if (up.show) { |
|||
_push(`<div class="mt-3" data-v-c511dcb4><div class="flex items-center gap-2 text-xs mb-1" data-v-c511dcb4>`); |
|||
if (up.running) { |
|||
_push(`<span class="loading loading-spinner loading-xs text-amber-500" data-v-c511dcb4></span>`); |
|||
} else if (up.ok) { |
|||
_push(`<span class="text-green-600 font-semibold" data-v-c511dcb4>✓ 部署完成</span>`); |
|||
} else { |
|||
_push(`<span class="text-red-600 font-semibold" data-v-c511dcb4>✗ 部署失败</span>`); |
|||
} |
|||
_push(`<span class="text-slate-400" data-v-c511dcb4>${ssrInterpolate(up.running ? "执行中…" : "")}</span></div><pre class="bg-slate-900 text-slate-100 text-[11px] leading-relaxed rounded-lg p-3 h-64 overflow-auto font-mono whitespace-pre-wrap" data-v-c511dcb4>${ssrInterpolate(up.log || "(等待输出…)")}</pre></div>`); |
|||
} else { |
|||
_push(`<!---->`); |
|||
} |
|||
_push(`<div class="modal-action" data-v-c511dcb4><button class="btn btn-ghost btn-sm"${ssrIncludeBooleanAttr(up.running) ? " disabled" : ""} data-v-c511dcb4>关闭</button><button class="btn btn-warning btn-sm"${ssrIncludeBooleanAttr(up.running) ? " disabled" : ""} data-v-c511dcb4>${ssrInterpolate(up.btnText)}</button></div></div><form method="dialog" class="modal-backdrop" data-v-c511dcb4><button${ssrIncludeBooleanAttr(up.running) ? " disabled" : ""} data-v-c511dcb4>close</button></form></dialog><dialog class="modal" data-v-c511dcb4><div class="modal-box" data-v-c511dcb4><h3 class="font-bold text-lg" data-v-c511dcb4>分析历史数据</h3><p class="text-sm text-slate-500 mt-1" data-v-c511dcb4>${ssrInterpolate(az.label)}</p><div class="text-xs text-amber-700 mt-3 bg-amber-50 border border-amber-100 rounded-lg p-3 leading-relaxed" data-v-c511dcb4> 扫描该应用业务库,按 <b data-v-c511dcb4>天 + 产品 + 区域</b> 生成历史统计(新增用户 / 订单 / 资源发放·使用 / 激活绑定设备),汇入 console 主库。<br data-v-c511dcb4> · <b data-v-c511dcb4>分析前会先清理该应用+区域在所选区间内的旧统计行</b>,避免数据重叠。<br data-v-c511dcb4> · 登录、活跃用户、AI对话等无每日原始记录,历史无法还原(由实时管道往后采集)。<br data-v-c511dcb4> · 仅对实时管道上线前的区间运行。留空 = 全部历史。大库可能耗时。 </div><div class="grid grid-cols-2 gap-3 mt-4" data-v-c511dcb4><div data-v-c511dcb4><label class="text-xs text-slate-500" data-v-c511dcb4>起始日(含)</label><input${ssrRenderAttr("value", az.start)} type="date" class="input input-bordered input-sm w-full" data-v-c511dcb4></div><div data-v-c511dcb4><label class="text-xs text-slate-500" data-v-c511dcb4>结束日(含)</label><input${ssrRenderAttr("value", az.end)} type="date" class="input input-bordered input-sm w-full" data-v-c511dcb4></div></div>`); |
|||
if (az.mode) { |
|||
_push(`<div class="text-sm mt-3" data-v-c511dcb4>`); |
|||
if (az.mode === "progress") { |
|||
_push(`<div class="bg-slate-50 border border-slate-200 rounded-lg p-3" data-v-c511dcb4><div class="flex justify-between items-center text-xs mb-1.5" data-v-c511dcb4><span class="text-slate-600" data-v-c511dcb4>`); |
|||
if (az.curName) { |
|||
_push(`<!--[--><span class="loading loading-spinner loading-xs" data-v-c511dcb4></span> 正在:${ssrInterpolate(az.curName)} (${ssrInterpolate(az.curIndex)}/${ssrInterpolate(az.curTotal)})<!--]-->`); |
|||
} else { |
|||
_push(`<!--[-->准备中...<!--]-->`); |
|||
} |
|||
_push(`</span><span class="font-mono text-slate-400" data-v-c511dcb4>${ssrInterpolate(az.pct)}%</span></div><progress class="progress progress-primary w-full h-2"${ssrRenderAttr("value", az.pct)} max="100" data-v-c511dcb4></progress><div class="mt-2 text-xs space-y-0.5" data-v-c511dcb4><!--[-->`); |
|||
ssrRenderList(az.steps, (nm, i) => { |
|||
_push(`<div class="${ssrRenderClass(i === az.curIndex - 1 ? "text-slate-600" : "text-green-600")}" data-v-c511dcb4>`); |
|||
if (i === az.curIndex - 1) { |
|||
_push(`<!--[--><span class="loading loading-spinner loading-xs" data-v-c511dcb4></span> ${ssrInterpolate(nm)}<!--]-->`); |
|||
} else { |
|||
_push(`<!--[-->✓ ${ssrInterpolate(nm)}<!--]-->`); |
|||
} |
|||
_push(`</div>`); |
|||
}); |
|||
_push(`<!--]--></div></div>`); |
|||
} else if (az.mode === "error") { |
|||
_push(`<div class="text-red-600" data-v-c511dcb4>✗ ${ssrInterpolate(az.errMsg)}</div>`); |
|||
} else if (az.mode === "done" && az.report) { |
|||
_push(`<div class="bg-green-50 border border-green-100 rounded-lg p-3" data-v-c511dcb4><div class="font-semibold text-green-700 mb-2" data-v-c511dcb4>✓ 分析完成</div><div class="grid grid-cols-2 gap-x-4 gap-y-1 text-xs text-slate-600 mb-2" data-v-c511dcb4><div data-v-c511dcb4>应用:<b data-v-c511dcb4>${ssrInterpolate(az.report.app_name || "")}</b></div><div data-v-c511dcb4>区域:${ssrInterpolate(unref(regionLabel)(az.report.region))}</div><div data-v-c511dcb4>区间:${ssrInterpolate((az.report.start_day || "不限") + " ~ " + (az.report.end_day || "不限"))}</div><div data-v-c511dcb4>清理旧行:${ssrInterpolate(az.report.cleared_rows || 0)}</div><div data-v-c511dcb4>写入天数:<b data-v-c511dcb4>${ssrInterpolate(az.report.days_written || 0)}</b></div><div data-v-c511dcb4>写入行数:${ssrInterpolate(az.report.rows_written || 0)}</div></div><div class="border-t border-green-100 pt-2 text-xs" data-v-c511dcb4><!--[-->`); |
|||
ssrRenderList(az.report.steps || [], (s, i) => { |
|||
_push(`<div class="flex justify-between py-0.5" data-v-c511dcb4><span class="text-slate-500" data-v-c511dcb4>${ssrInterpolate(s.name)}</span><span class="font-mono text-slate-700" data-v-c511dcb4>${ssrInterpolate((s.groups || 0) + " 组")}</span></div>`); |
|||
}); |
|||
_push(`<!--]--></div></div>`); |
|||
} else { |
|||
_push(`<!---->`); |
|||
} |
|||
_push(`</div>`); |
|||
} else { |
|||
_push(`<!---->`); |
|||
} |
|||
_push(`<div class="modal-action" data-v-c511dcb4><button class="btn btn-ghost btn-sm"${ssrIncludeBooleanAttr(az.running) ? " disabled" : ""} data-v-c511dcb4>关闭</button><button class="btn btn-primary btn-sm text-white"${ssrIncludeBooleanAttr(az.running) ? " disabled" : ""} data-v-c511dcb4>${ssrInterpolate(az.btnText)}</button></div></div><form method="dialog" class="modal-backdrop" data-v-c511dcb4><button${ssrIncludeBooleanAttr(az.running) ? " disabled" : ""} data-v-c511dcb4>close</button></form></dialog></div>`); |
|||
}; |
|||
} |
|||
}); |
|||
const _sfc_setup$2 = _sfc_main$2.setup; |
|||
_sfc_main$2.setup = (props, ctx) => { |
|||
const ssrContext = useSSRContext(); |
|||
(ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("components/AppDeployTab.vue"); |
|||
return _sfc_setup$2 ? _sfc_setup$2(props, ctx) : void 0; |
|||
}; |
|||
const __nuxt_component_0 = /* @__PURE__ */ Object.assign(_export_sfc(_sfc_main$2, [["__scopeId", "data-v-c511dcb4"]]), { __name: "AppDeployTab" }); |
|||
const _sfc_main$1 = /* @__PURE__ */ defineComponent({ |
|||
__name: "AppModuleTab", |
|||
__ssrInlineRender: true, |
|||
props: { |
|||
appId: {}, |
|||
depName: {} |
|||
}, |
|||
setup(__props) { |
|||
useApi(); |
|||
useToast(); |
|||
const catalog = ref([]); |
|||
const curModule = ref(""); |
|||
const values = reactive({}); |
|||
const dataModules = reactive(/* @__PURE__ */ new Set()); |
|||
const show = reactive({}); |
|||
const loading = ref(false); |
|||
const saving = ref(false); |
|||
const dbError = ref(""); |
|||
const curDef = computed(() => catalog.value.find((m) => m.module === curModule.value) || null); |
|||
const cur = computed(() => values[curModule.value] || {}); |
|||
const groups = computed(() => { |
|||
const order = []; |
|||
const map = /* @__PURE__ */ new Map(); |
|||
for (const m of catalog.value) { |
|||
if (!map.has(m.group)) { |
|||
map.set(m.group, []); |
|||
order.push(m.group); |
|||
} |
|||
map.get(m.group).push(m); |
|||
} |
|||
return order.map((name) => ({ name, modules: map.get(name) })); |
|||
}); |
|||
return (_ctx, _push, _parent, _attrs) => { |
|||
_push(`<div${ssrRenderAttrs(mergeProps({ class: "card" }, _attrs))} data-v-ff0e4b71><div class="card-head" data-v-ff0e4b71><div data-v-ff0e4b71><div class="card-title" data-v-ff0e4b71>业务功能配置</div><div class="card-desc" data-v-ff0e4b71> 登录 / 短信 / 邮件 / 支付等应用独立配置,保存在<b data-v-ff0e4b71>「${ssrInterpolate(__props.depName)}」这个部署的业务库</b>(不进公共库)。密钥字段加密落库,显示时脱敏。 </div></div><button class="btn btn-outline btn-error btn-xs shrink-0"${ssrIncludeBooleanAttr(saving.value || !!dbError.value) ? " disabled" : ""} title="把该部署业务库里所有业务模块的配置,整体还原为业务服务配置文件(yaml)的初始值。用于升级/迁移把库写脏后的整体恢复。" data-v-ff0e4b71>全部重置为配置文件</button></div>`); |
|||
if (dbError.value) { |
|||
_push(`<div class="m-4 alert alert-warning py-2 text-sm" data-v-ff0e4b71><span data-v-ff0e4b71> 无法连接应用业务库:${ssrInterpolate(dbError.value)}<br data-v-ff0e4b71><span class="text-xs opacity-70" data-v-ff0e4b71>待部署的应用先完成部署、或检查业务库 DSN 连通后再配置。</span></span></div>`); |
|||
} else { |
|||
_push(`<!---->`); |
|||
} |
|||
if (loading.value) { |
|||
_push(`<div class="py-14 text-center" data-v-ff0e4b71><span class="loading loading-spinner loading-sm" data-v-ff0e4b71></span></div>`); |
|||
} else { |
|||
_push(`<div class="cfg" data-v-ff0e4b71><aside class="cfg-nav" data-v-ff0e4b71><!--[-->`); |
|||
ssrRenderList(groups.value, (grp) => { |
|||
_push(`<div data-v-ff0e4b71><div class="cfg-group" data-v-ff0e4b71>${ssrInterpolate(grp.name)}</div><!--[-->`); |
|||
ssrRenderList(grp.modules, (m) => { |
|||
_push(`<button class="cfg-item"${ssrRenderAttr("aria-current", curModule.value === m.module)} data-v-ff0e4b71><span data-v-ff0e4b71>${ssrInterpolate(m.name)}</span>`); |
|||
if (dataModules.has(m.module)) { |
|||
_push(`<span class="dot" title="库中已有配置" data-v-ff0e4b71></span>`); |
|||
} else { |
|||
_push(`<!---->`); |
|||
} |
|||
_push(`</button>`); |
|||
}); |
|||
_push(`<!--]--></div>`); |
|||
}); |
|||
_push(`<!--]--></aside><section class="cfg-form" data-v-ff0e4b71>`); |
|||
if (curDef.value) { |
|||
_push(`<!--[--><div class="flex items-start justify-between gap-3 mb-4 flex-wrap" data-v-ff0e4b71><div data-v-ff0e4b71><div class="text-sm font-semibold text-slate-800" data-v-ff0e4b71>${ssrInterpolate(curDef.value.name)}</div>`); |
|||
if (curDef.value.desc) { |
|||
_push(`<div class="text-[11px] text-slate-400 mt-0.5" data-v-ff0e4b71>${ssrInterpolate(curDef.value.desc)}</div>`); |
|||
} else { |
|||
_push(`<!---->`); |
|||
} |
|||
_push(`</div><div class="flex items-center gap-2" data-v-ff0e4b71><button class="btn btn-ghost btn-xs text-amber-600"${ssrIncludeBooleanAttr(saving.value) ? " disabled" : ""} title="丢弃库中该模块的全部配置,改用业务服务配置文件(yaml)里的初始值重新写入。" data-v-ff0e4b71>重置</button>`); |
|||
if (dataModules.has(curModule.value)) { |
|||
_push(`<button class="btn btn-ghost btn-xs text-rose-500"${ssrIncludeBooleanAttr(saving.value) ? " disabled" : ""} data-v-ff0e4b71>清空</button>`); |
|||
} else { |
|||
_push(`<!---->`); |
|||
} |
|||
_push(`<button class="btn btn-primary btn-sm text-white"${ssrIncludeBooleanAttr(saving.value || !!dbError.value) ? " disabled" : ""} data-v-ff0e4b71>${ssrInterpolate(saving.value ? "保存中…" : "保存")}</button></div></div><div class="grid grid-cols-1 gap-3 max-w-2xl" data-v-ff0e4b71><!--[-->`); |
|||
ssrRenderList(curDef.value.fields, (f) => { |
|||
_push(`<div class="form-control" data-v-ff0e4b71><label class="label py-0.5" data-v-ff0e4b71><span class="label-text text-sm" data-v-ff0e4b71>${ssrInterpolate(f.label)} `); |
|||
if (f.required) { |
|||
_push(`<span class="text-rose-400" data-v-ff0e4b71>*</span>`); |
|||
} else { |
|||
_push(`<!---->`); |
|||
} |
|||
if (f.secret) { |
|||
_push(`<span class="lock-tag ml-1" data-v-ff0e4b71>🔒</span>`); |
|||
} else { |
|||
_push(`<!---->`); |
|||
} |
|||
_push(`<span class="text-[10px] font-normal text-slate-300 ml-1 font-mono" data-v-ff0e4b71>${ssrInterpolate(f.key)}</span></span></label>`); |
|||
if (f.type === "bool") { |
|||
_push(`<label class="cursor-pointer flex items-center gap-2" data-v-ff0e4b71><input type="checkbox" class="toggle toggle-sm toggle-primary"${ssrIncludeBooleanAttr(cur.value[f.key] === "true") ? " checked" : ""} data-v-ff0e4b71><span class="text-xs text-slate-500" data-v-ff0e4b71>${ssrInterpolate(cur.value[f.key] === "true" ? "开启" : "关闭")}</span></label>`); |
|||
} else if (f.type === "select") { |
|||
_push(`<select class="select select-bordered select-sm w-full" data-v-ff0e4b71><option value="" data-v-ff0e4b71${ssrIncludeBooleanAttr(Array.isArray(cur.value[f.key]) ? ssrLooseContain(cur.value[f.key], "") : ssrLooseEqual(cur.value[f.key], "")) ? " selected" : ""}>请选择</option><!--[-->`); |
|||
ssrRenderList(f.options, (o) => { |
|||
_push(`<option${ssrRenderAttr("value", o.value)} data-v-ff0e4b71${ssrIncludeBooleanAttr(Array.isArray(cur.value[f.key]) ? ssrLooseContain(cur.value[f.key], o.value) : ssrLooseEqual(cur.value[f.key], o.value)) ? " selected" : ""}>${ssrInterpolate(o.label)}</option>`); |
|||
}); |
|||
_push(`<!--]--></select>`); |
|||
} else if (f.type === "textarea") { |
|||
_push(`<textarea class="textarea textarea-bordered w-full font-mono text-xs" rows="3"${ssrRenderAttr("placeholder", f.secret ? "留空/保持 [encrypted] 则不变" : f.placeholder || "")} data-v-ff0e4b71>${ssrInterpolate(cur.value[f.key])}</textarea>`); |
|||
} else if (f.type === "password") { |
|||
_push(`<div class="relative" data-v-ff0e4b71><input${ssrRenderDynamicModel(show[f.key] ? "text" : "password", cur.value[f.key], null)}${ssrRenderAttr("type", show[f.key] ? "text" : "password")} class="input input-bordered input-sm w-full font-mono text-xs pr-14" placeholder="留空/保持 [encrypted] 则不变" data-v-ff0e4b71><button type="button" class="absolute right-3 top-1/2 -translate-y-1/2 text-xs text-slate-400 hover:text-slate-700" data-v-ff0e4b71>${ssrInterpolate(show[f.key] ? "隐藏" : "显示")}</button></div>`); |
|||
} else { |
|||
_push(`<input${ssrRenderAttr("value", cur.value[f.key])} type="text" class="input input-bordered input-sm w-full font-mono text-xs"${ssrRenderAttr("placeholder", f.placeholder || "")} data-v-ff0e4b71>`); |
|||
} |
|||
if (f.desc) { |
|||
_push(`<span class="text-[11px] text-slate-400 mt-0.5" data-v-ff0e4b71>${ssrInterpolate(f.desc)}</span>`); |
|||
} else { |
|||
_push(`<!---->`); |
|||
} |
|||
_push(`</div>`); |
|||
}); |
|||
_push(`<!--]--></div><!--]-->`); |
|||
} else { |
|||
_push(`<div class="py-10 text-center text-slate-400 text-sm" data-v-ff0e4b71>暂无可配置的业务模块。</div>`); |
|||
} |
|||
_push(`</section></div>`); |
|||
} |
|||
_push(`</div>`); |
|||
}; |
|||
} |
|||
}); |
|||
const _sfc_setup$1 = _sfc_main$1.setup; |
|||
_sfc_main$1.setup = (props, ctx) => { |
|||
const ssrContext = useSSRContext(); |
|||
(ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("components/AppModuleTab.vue"); |
|||
return _sfc_setup$1 ? _sfc_setup$1(props, ctx) : void 0; |
|||
}; |
|||
const __nuxt_component_1 = /* @__PURE__ */ Object.assign(_export_sfc(_sfc_main$1, [["__scopeId", "data-v-ff0e4b71"]]), { __name: "AppModuleTab" }); |
|||
const _sfc_main = /* @__PURE__ */ defineComponent({ |
|||
__name: "[name]", |
|||
__ssrInlineRender: true, |
|||
setup(__props) { |
|||
const { consoleApi } = useApi(); |
|||
const { error } = useToast(); |
|||
const route = useRoute$1(); |
|||
useRouter(); |
|||
const appName = computed(() => String(route.params.name || "")); |
|||
const product = ref(null); |
|||
const deployments = ref([]); |
|||
const envs = ref([]); |
|||
const loading = ref(false); |
|||
const tab = ref(route.query.tab === "modules" ? "modules" : "deps"); |
|||
const curDep = ref(0); |
|||
const deployTab = ref(null); |
|||
const okCount = computed(() => deployments.value.filter((d) => d.status !== "pending").length); |
|||
const pendingCount = computed(() => deployments.value.filter((d) => d.status === "pending").length); |
|||
const curDepName = computed(() => { |
|||
const d = deployments.value.find((x) => x.id === curDep.value); |
|||
return d ? d.name || "部署#" + d.id : ""; |
|||
}); |
|||
const versionSpread = computed(() => { |
|||
const tags = [...new Set(deployments.value.filter((d) => d.status !== "pending").map((d) => d.image_tag || "latest"))]; |
|||
return tags.length ? tags.join(" · ") : "—"; |
|||
}); |
|||
async function loadAll() { |
|||
loading.value = true; |
|||
try { |
|||
const [ps, ds, es] = await Promise.all([ |
|||
consoleApi("products/list", {}), |
|||
consoleApi("apps/list", {}), |
|||
consoleApi("envs/list", {}) |
|||
]); |
|||
product.value = (ps ?? []).find((p) => p.name === appName.value) ?? null; |
|||
deployments.value = (ds ?? []).filter((d) => d.app_name === appName.value); |
|||
envs.value = es ?? []; |
|||
if (!deployments.value.some((d) => d.id === curDep.value)) { |
|||
const first = deployments.value.find((d) => d.status !== "pending") ?? deployments.value[0]; |
|||
curDep.value = first?.id ?? 0; |
|||
} |
|||
} catch (e) { |
|||
error(e?.message ?? "加载应用详情失败"); |
|||
} finally { |
|||
loading.value = false; |
|||
} |
|||
} |
|||
function onConfigure(id) { |
|||
curDep.value = id; |
|||
tab.value = "modules"; |
|||
} |
|||
ref(null); |
|||
const pForm = reactive({ id: 0, name: "", image_name: "", remark: "", enabled: true }); |
|||
watch(appName, loadAll); |
|||
return (_ctx, _push, _parent, _attrs) => { |
|||
const _component_AppDeployTab = __nuxt_component_0; |
|||
const _component_AppModuleTab = __nuxt_component_1; |
|||
_push(`<div${ssrRenderAttrs(_attrs)} data-v-5215c85d><div class="flex items-center gap-2 mb-4 text-sm" data-v-5215c85d><button class="btn btn-ghost btn-xs" data-v-5215c85d>← 应用中心</button><span class="text-slate-300" data-v-5215c85d>/</span><span class="font-semibold text-slate-700" data-v-5215c85d>${ssrInterpolate(appName.value)}</span></div>`); |
|||
if (loading.value) { |
|||
_push(`<div class="bg-white rounded-xl border border-slate-100 py-16 text-center" data-v-5215c85d><span class="loading loading-spinner loading-sm" data-v-5215c85d></span></div>`); |
|||
} else if (!product.value) { |
|||
_push(`<div class="bg-white rounded-xl border border-slate-100 py-16 text-center" data-v-5215c85d><p class="text-slate-500" data-v-5215c85d>找不到应用「${ssrInterpolate(appName.value)}」</p><button class="btn btn-sm mt-4" data-v-5215c85d>返回应用中心</button></div>`); |
|||
} else { |
|||
_push(`<!--[--><div class="hero" data-v-5215c85d><div class="hero-logo" data-v-5215c85d>${ssrInterpolate((product.value.name || "?").charAt(0).toUpperCase())}</div><div class="flex-1 min-w-[240px]" data-v-5215c85d><div class="hero-name" data-v-5215c85d>${ssrInterpolate(product.value.name)} <span class="${ssrRenderClass([product.value.enabled ? "chip-ok" : "", "chip"])}" data-v-5215c85d>${ssrInterpolate(product.value.enabled ? "启用" : "停用")}</span><span class="chip chip-mono" data-v-5215c85d>🐳 ${ssrInterpolate(product.value.image_name || "未设置镜像")}</span></div><div class="text-xs text-slate-500 mt-1.5" data-v-5215c85d>${ssrInterpolate(product.value.remark || "—")}</div></div><div class="flex gap-2" data-v-5215c85d><button class="btn btn-sm" data-v-5215c85d>编辑应用</button><button class="btn btn-primary btn-sm text-white" data-v-5215c85d>+ 部署新环境</button></div></div><div class="kpis" data-v-5215c85d><div class="kpi accent" data-v-5215c85d><div class="kpi-l" data-v-5215c85d>部署</div><div class="kpi-v" data-v-5215c85d>${ssrInterpolate(deployments.value.length)}<small data-v-5215c85d>个区域</small></div></div><div class="kpi ok" data-v-5215c85d><div class="kpi-l" data-v-5215c85d>已接入</div><div class="kpi-v" data-v-5215c85d>${ssrInterpolate(okCount.value)}</div></div><div class="${ssrRenderClass([pendingCount.value ? "warn" : "", "kpi"])}" data-v-5215c85d><div class="kpi-l" data-v-5215c85d>待部署</div><div class="kpi-v" data-v-5215c85d>${ssrInterpolate(pendingCount.value)}</div></div><div class="kpi" data-v-5215c85d><div class="kpi-l" data-v-5215c85d>版本分布</div><div class="kpi-v" style="${ssrRenderStyle({ "font-size": "14px", "padding-top": "5px" })}" data-v-5215c85d>${ssrInterpolate(versionSpread.value)}</div></div></div><div class="tablist" role="tablist" data-v-5215c85d><button class="tab" role="tab"${ssrRenderAttr("aria-selected", tab.value === "deps")} data-v-5215c85d> 部署环境 <span class="tab-n" data-v-5215c85d>${ssrInterpolate(deployments.value.length)}</span></button><button class="tab" role="tab"${ssrRenderAttr("aria-selected", tab.value === "modules")} data-v-5215c85d>业务功能配置</button></div>`); |
|||
if (tab.value === "modules") { |
|||
_push(`<div class="depbar" data-v-5215c85d><span class="text-xs text-slate-500 font-semibold shrink-0" data-v-5215c85d>配置目标</span><div class="flex gap-1.5 flex-wrap" data-v-5215c85d><!--[-->`); |
|||
ssrRenderList(deployments.value, (d) => { |
|||
_push(`<button class="depchip"${ssrRenderAttr("aria-pressed", curDep.value === d.id)}${ssrRenderAttr("title", d.status === "pending" ? "待部署:业务库可能还未就绪" : "")} data-v-5215c85d><span class="${ssrRenderClass([{ pending: d.status === "pending" }, "dot"])}" data-v-5215c85d></span> ${ssrInterpolate(d.region ? unref(regionLabel)(d.region) : d.name || "部署#" + d.id)} <span class="text-[10.5px] text-slate-400 font-mono" data-v-5215c85d>#${ssrInterpolate(d.id)}</span></button>`); |
|||
}); |
|||
_push(`<!--]-->`); |
|||
if (!deployments.value.length) { |
|||
_push(`<span class="text-xs text-slate-400 py-1" data-v-5215c85d>该应用还没有部署,无处存放配置</span>`); |
|||
} else { |
|||
_push(`<!---->`); |
|||
} |
|||
_push(`</div><span class="text-[11px] text-slate-400 ml-auto" data-v-5215c85d>配置存在该部署自己的业务库里,各区域互不影响</span></div>`); |
|||
} else { |
|||
_push(`<!---->`); |
|||
} |
|||
_push(ssrRenderComponent(_component_AppDeployTab, { |
|||
style: tab.value === "deps" ? null : { display: "none" }, |
|||
ref_key: "deployTab", |
|||
ref: deployTab, |
|||
"app-name": appName.value, |
|||
"default-image": product.value.image_name || "", |
|||
deployments: deployments.value, |
|||
envs: envs.value, |
|||
onRefresh: loadAll, |
|||
onConfigure |
|||
}, null, _parent)); |
|||
if (tab.value === "modules" && curDep.value) { |
|||
_push(ssrRenderComponent(_component_AppModuleTab, { |
|||
key: "m" + curDep.value, |
|||
"app-id": curDep.value, |
|||
"dep-name": curDepName.value |
|||
}, null, _parent)); |
|||
} else { |
|||
_push(`<!---->`); |
|||
} |
|||
if (tab.value === "modules" && !curDep.value) { |
|||
_push(`<div class="bg-white rounded-xl border border-slate-100 py-16 text-center text-slate-400" data-v-5215c85d> 先在「部署环境」里创建一个部署,才能配置。 </div>`); |
|||
} else { |
|||
_push(`<!---->`); |
|||
} |
|||
_push(`<!--]-->`); |
|||
} |
|||
_push(`<dialog class="modal" data-v-5215c85d><div class="modal-box max-w-lg" data-v-5215c85d><h3 class="font-bold text-lg" data-v-5215c85d>编辑应用</h3><p class="text-xs text-slate-400 mt-1" data-v-5215c85d> 应用名是关联键:部署、账号作用域、第三方服务配置都按它挂载,改名会断开已有关联。 </p><form class="mt-4 space-y-3" data-v-5215c85d><div class="form-control" data-v-5215c85d><label class="label py-1" data-v-5215c85d><span class="label-text text-sm font-medium" data-v-5215c85d>应用名 *</span></label><input${ssrRenderAttr("value", pForm.name)} type="text" class="input input-bordered input-sm w-full" required data-v-5215c85d></div><div class="form-control" data-v-5215c85d><label class="label py-1" data-v-5215c85d><span class="label-text text-sm font-medium" data-v-5215c85d>默认镜像名</span></label><input${ssrRenderAttr("value", pForm.image_name)} type="text" class="input input-bordered input-sm w-full font-mono text-xs" data-v-5215c85d></div><div class="form-control" data-v-5215c85d><label class="label py-1" data-v-5215c85d><span class="label-text text-sm font-medium" data-v-5215c85d>备注</span></label><input${ssrRenderAttr("value", pForm.remark)} type="text" class="input input-bordered input-sm w-full" data-v-5215c85d></div><label class="flex items-center gap-2 cursor-pointer pt-1" data-v-5215c85d><input${ssrIncludeBooleanAttr(Array.isArray(pForm.enabled) ? ssrLooseContain(pForm.enabled, null) : pForm.enabled) ? " checked" : ""} type="checkbox" class="toggle toggle-primary toggle-sm" data-v-5215c85d><span class="text-sm" data-v-5215c85d>启用</span></label><div class="modal-action" data-v-5215c85d><button type="button" class="btn btn-ghost btn-sm" data-v-5215c85d>取消</button><button type="submit" class="btn btn-primary btn-sm text-white" data-v-5215c85d>保存</button></div></form></div><form method="dialog" class="modal-backdrop" data-v-5215c85d><button data-v-5215c85d>close</button></form></dialog></div>`); |
|||
}; |
|||
} |
|||
}); |
|||
const _sfc_setup = _sfc_main.setup; |
|||
_sfc_main.setup = (props, ctx) => { |
|||
const ssrContext = useSSRContext(); |
|||
(ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("pages/apps/[name].vue"); |
|||
return _sfc_setup ? _sfc_setup(props, ctx) : void 0; |
|||
}; |
|||
const _name_ = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-5215c85d"]]); |
|||
|
|||
export { _name_ as default }; |
|||
//# sourceMappingURL=_name_-CJXf25S4.mjs.map
|
|||
@ -1 +0,0 @@ |
|||
{"version":3,"file":"_name_-CJXf25S4.mjs","sources":["../../../../node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/_name_-CJXf25S4.js"],"names":["useRoute"],"mappings":"","x_google_ignoreList":[0]} |
|||
@ -1,4 +0,0 @@ |
|||
const AppDeployTab_vue_vue_type_style_index_0_scoped_c511dcb4_lang = ".card[data-v-c511dcb4]{background:#fff;border:1px solid #eef2f7;border-radius:14px;box-shadow:0 1px 2px #0f172a0a;overflow:hidden}.card-head[data-v-c511dcb4]{padding:15px 18px;border-bottom:1px solid #eef2f7;display:flex;align-items:flex-start;justify-content:space-between;gap:14px;flex-wrap:wrap}.card-title[data-v-c511dcb4]{font-size:14.5px;font-weight:700;color:#1e293b}.card-desc[data-v-c511dcb4]{font-size:11.5px;color:#64748b;margin-top:3px;max-width:74ch;line-height:1.55}.dep[data-v-c511dcb4]{display:grid;grid-template-columns:1.5fr 1fr 1fr .9fr auto;gap:14px;align-items:center;padding:14px 18px;border-bottom:1px solid #eef2f7}.dep[data-v-c511dcb4]:last-child{border-bottom:0}.dep[data-v-c511dcb4]:hover{background:#fcfcfd}.dep.pending[data-v-c511dcb4]{background:linear-gradient(90deg,#fef3c7,transparent 34%)}.dep-name[data-v-c511dcb4]{font-weight:600;font-size:13.5px;color:#334155;display:flex;align-items:center;gap:7px;flex-wrap:wrap}.dep-sub[data-v-c511dcb4]{font-size:11px;color:#94a3b8;margin-top:3px;font-family:SF Mono,Menlo,monospace}.dep-acts[data-v-c511dcb4]{display:flex;gap:4px;flex-wrap:wrap;justify-content:flex-end}.field-l[data-v-c511dcb4]{font-size:10px;color:#94a3b8;letter-spacing:.04em;text-transform:uppercase;font-weight:600;margin-bottom:3px}.chip[data-v-c511dcb4]{display:inline-flex;align-items:center;font-size:10.5px;font-weight:700;padding:2px 7px;border-radius:5px;background:#f1f5f9;color:#64748b}.chip-dep[data-v-c511dcb4]{background:#ecfeff;color:#0e7490}.chip-ok[data-v-c511dcb4]{background:#dcfce7;color:#15803d}.chip-warn[data-v-c511dcb4]{background:#fef3c7;color:#b45309}.chip-mono[data-v-c511dcb4]{font-family:SF Mono,Menlo,monospace;font-weight:600}@media(max-width:1280px){.dep[data-v-c511dcb4]{grid-template-columns:1fr 1fr}.dep-acts[data-v-c511dcb4]{grid-column:1/-1;justify-content:flex-start}}"; |
|||
|
|||
export { AppDeployTab_vue_vue_type_style_index_0_scoped_c511dcb4_lang as A }; |
|||
//# sourceMappingURL=_name_-styles-1.mjs-BmcUDjex.mjs.map
|
|||
@ -1 +0,0 @@ |
|||
{"version":3,"file":"_name_-styles-1.mjs-BmcUDjex.mjs","sources":["../../../../node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/_name_-styles-1.mjs-BmcUDjex.js"],"names":[],"mappings":"","x_google_ignoreList":[0]} |
|||
@ -1,4 +0,0 @@ |
|||
const AppModuleTab_vue_vue_type_style_index_0_scoped_ff0e4b71_lang = ".card[data-v-ff0e4b71]{background:#fff;border:1px solid #eef2f7;border-radius:14px;box-shadow:0 1px 2px #0f172a0a;overflow:hidden}.card-head[data-v-ff0e4b71]{padding:15px 18px;border-bottom:1px solid #eef2f7;display:flex;align-items:flex-start;justify-content:space-between;gap:14px;flex-wrap:wrap}.card-title[data-v-ff0e4b71]{font-size:14.5px;font-weight:700;color:#1e293b}.card-desc[data-v-ff0e4b71]{font-size:11.5px;color:#64748b;margin-top:3px;max-width:78ch;line-height:1.55}.cfg[data-v-ff0e4b71]{display:grid;grid-template-columns:190px 1fr}.cfg-nav[data-v-ff0e4b71]{border-right:1px solid #eef2f7;padding:12px 10px;background:#fcfcfd}.cfg-group[data-v-ff0e4b71]{font-size:10px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:#94a3b8;padding:10px 8px 4px}.cfg-item[data-v-ff0e4b71]{width:100%;border:0;background:none;font-size:13px;color:#334155;text-align:left;padding:7px 10px;border-radius:8px;cursor:pointer;display:flex;align-items:center;justify-content:space-between;gap:8px}.cfg-item[data-v-ff0e4b71]:hover{background:#f8fafc}.cfg-item[aria-current=true][data-v-ff0e4b71]{background:#eef2ff;color:#4338ca;font-weight:600}.cfg-item .dot[data-v-ff0e4b71]{width:6px;height:6px;border-radius:50%;background:#4ade80;flex-shrink:0}.cfg-form[data-v-ff0e4b71]{padding:16px 20px;min-width:0}.lock-tag[data-v-ff0e4b71]{font-size:10px;font-weight:600;color:#dc2626;background:#fef2f2;padding:1px 5px;border-radius:5px}@media(max-width:900px){.cfg[data-v-ff0e4b71]{grid-template-columns:1fr}.cfg-nav[data-v-ff0e4b71]{border-right:0;border-bottom:1px solid #eef2f7}}"; |
|||
|
|||
export { AppModuleTab_vue_vue_type_style_index_0_scoped_ff0e4b71_lang as A }; |
|||
//# sourceMappingURL=_name_-styles-2.mjs-BXCS7H7R.mjs.map
|
|||
@ -1 +0,0 @@ |
|||
{"version":3,"file":"_name_-styles-2.mjs-BXCS7H7R.mjs","sources":["../../../../node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/_name_-styles-2.mjs-BXCS7H7R.js"],"names":[],"mappings":"","x_google_ignoreList":[0]} |
|||
@ -1,13 +0,0 @@ |
|||
import { A as AppDeployTab_vue_vue_type_style_index_0_scoped_c511dcb4_lang } from './_name_-styles-1.mjs-BmcUDjex.mjs'; |
|||
import { A as AppModuleTab_vue_vue_type_style_index_0_scoped_ff0e4b71_lang } from './_name_-styles-2.mjs-BXCS7H7R.mjs'; |
|||
|
|||
const _name__vue_vue_type_style_index_0_scoped_5215c85d_lang = '.hero[data-v-5215c85d]{background:#fff;border:1px solid #eef2f7;border-radius:16px;padding:20px 22px;margin-bottom:16px;box-shadow:0 1px 2px #0f172a0a,0 4px 16px #0f172a08;display:flex;gap:18px;align-items:center;flex-wrap:wrap}.hero-logo[data-v-5215c85d]{width:58px;height:58px;border-radius:15px;flex-shrink:0;color:#fff;background:linear-gradient(135deg,#4f46e5,#7c3aed);display:grid;place-items:center;font-weight:800;font-size:24px;box-shadow:0 8px 22px #4f46e54d}.hero-name[data-v-5215c85d]{font-size:20px;font-weight:700;color:#1e293b;letter-spacing:-.015em;display:flex;align-items:center;gap:9px;flex-wrap:wrap}.kpis[data-v-5215c85d]{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:12px;margin-bottom:18px}.kpi[data-v-5215c85d]{background:#fff;border:1px solid #eef2f7;border-radius:12px;padding:13px 15px;position:relative;overflow:hidden;box-shadow:0 1px 2px #0f172a0a}.kpi[data-v-5215c85d]:before{content:"";position:absolute;left:0;top:0;bottom:0;width:3px;background:#e2e8f0}.kpi.ok[data-v-5215c85d]:before{background:#16a34a}.kpi.warn[data-v-5215c85d]:before{background:#d97706}.kpi.accent[data-v-5215c85d]:before{background:#4f46e5}.kpi-l[data-v-5215c85d]{font-size:10.5px;color:#94a3b8;letter-spacing:.04em;text-transform:uppercase;font-weight:600}.kpi-v[data-v-5215c85d]{font-size:22px;font-weight:700;color:#1e293b;margin-top:3px;letter-spacing:-.02em;font-family:SF Mono,Menlo,monospace;font-variant-numeric:tabular-nums}.kpi-v small[data-v-5215c85d]{font-size:12px;color:#94a3b8;font-weight:500;margin-left:3px}.tablist[data-v-5215c85d]{display:flex;gap:2px;border-bottom:1px solid #e2e8f0;margin-bottom:18px;overflow-x:auto}.tab[data-v-5215c85d]{border:0;background:none;font-size:13.5px;color:#64748b;padding:10px 15px;cursor:pointer;border-bottom:2px solid transparent;margin-bottom:-1px;white-space:nowrap;display:flex;align-items:center;gap:6px}.tab[data-v-5215c85d]:hover{color:#1e293b}.tab[aria-selected=true][data-v-5215c85d]{color:#4338ca;border-bottom-color:#4f46e5;font-weight:600}.tab-n[data-v-5215c85d]{font-size:10.5px;background:#f8fafc;border:1px solid #eef2f7;color:#64748b;border-radius:20px;padding:0 6px;font-family:SF Mono,Menlo,monospace}.tab[aria-selected=true] .tab-n[data-v-5215c85d]{background:#eef2ff;color:#4338ca;border-color:transparent}.depbar[data-v-5215c85d]{gap:10px;flex-wrap:wrap;background:#f8fafc;border:1px solid #eef2f7;border-radius:11px;padding:10px 13px;margin-bottom:16px}.depbar[data-v-5215c85d],.depchip[data-v-5215c85d]{display:flex;align-items:center}.depchip[data-v-5215c85d]{border:1px solid #e2e8f0;background:#fff;border-radius:20px;padding:4px 12px;font-size:12px;cursor:pointer;color:#334155;gap:6px}.depchip[data-v-5215c85d]:hover{border-color:#0e7490}.depchip[aria-pressed=true][data-v-5215c85d]{background:#ecfeff;border-color:#0e7490;color:#0e7490;font-weight:600}.depchip .dot[data-v-5215c85d]{width:6px;height:6px;border-radius:50%;background:#16a34a}.depchip .dot.pending[data-v-5215c85d]{background:#d97706}.chip[data-v-5215c85d]{display:inline-flex;align-items:center;font-size:10.5px;font-weight:700;padding:2px 7px;border-radius:5px;background:#f1f5f9;color:#64748b}.chip-ok[data-v-5215c85d]{background:#dcfce7;color:#15803d}.chip-mono[data-v-5215c85d]{font-family:SF Mono,Menlo,monospace;font-weight:600}'; |
|||
|
|||
const _name_Styles_CveqLyYu = [ |
|||
AppDeployTab_vue_vue_type_style_index_0_scoped_c511dcb4_lang, |
|||
AppModuleTab_vue_vue_type_style_index_0_scoped_ff0e4b71_lang, |
|||
_name__vue_vue_type_style_index_0_scoped_5215c85d_lang |
|||
]; |
|||
|
|||
export { _name_Styles_CveqLyYu as default }; |
|||
//# sourceMappingURL=_name_-styles.CveqLyYu.mjs.map
|
|||
@ -1 +0,0 @@ |
|||
{"version":3,"file":"_name_-styles.CveqLyYu.mjs","sources":["../../../../node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/_name_-styles-3.mjs-BitgxNQW.js","../../../../node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/_name_-styles.CveqLyYu.mjs"],"names":["style_0","style_1","style_2"],"mappings":"","x_google_ignoreList":[0,1]} |
|||
@ -1,222 +0,0 @@ |
|||
import { defineComponent, ref, computed, reactive, watch, unref, useSSRContext } from 'vue'; |
|||
import { ssrRenderAttrs, ssrRenderStyle, ssrRenderList, ssrInterpolate, ssrRenderClass, ssrRenderAttr, ssrIncludeBooleanAttr, ssrLooseContain, ssrLooseEqual } from 'vue/server-renderer'; |
|||
import { u as useApi } from './useApi-BNSkSrat.mjs'; |
|||
import { u as useToast } from './useToast-MBvLaNjH.mjs'; |
|||
import { _ as _export_sfc, R as ROLE_ACCESS_CEILING, A as ALL_MENU_IDS, M as MENU_GROUPS, D as DEFAULT_ADMIN_ACCESS } from './server.mjs'; |
|||
import { R as REGION_OPTIONS } from './regions-D1dSykUW.mjs'; |
|||
import '../nitro/nitro.mjs'; |
|||
import 'node:http'; |
|||
import 'node:https'; |
|||
import 'node:events'; |
|||
import 'node:buffer'; |
|||
import 'node:fs'; |
|||
import 'node:path'; |
|||
import 'node:crypto'; |
|||
import 'node:url'; |
|||
import '../routes/renderer.mjs'; |
|||
import 'vue-bundle-renderer/runtime'; |
|||
import 'unhead/server'; |
|||
import 'devalue'; |
|||
import 'unhead/utils'; |
|||
import 'pinia'; |
|||
import 'perfect-debounce'; |
|||
|
|||
const _sfc_main = /* @__PURE__ */ defineComponent({ |
|||
__name: "accounts", |
|||
__ssrInlineRender: true, |
|||
setup(__props) { |
|||
useApi(); |
|||
useToast(); |
|||
const ROLE = { 1: "超管", 2: "管理员", 3: "品牌商", 4: "运营", 5: "渠道商" }; |
|||
const ROLE_CLS = { 1: "badge-error", 2: "badge-primary", 3: "badge-warning", 4: "badge-info", 5: "badge-accent" }; |
|||
const view = ref("list"); |
|||
const rows = ref([]); |
|||
const apps = ref([]); |
|||
const appNames = computed( |
|||
() => [...new Set(apps.value.map((a) => a.app_name || a.name).filter(Boolean))].sort() |
|||
); |
|||
const loading = ref(false); |
|||
const submitting = ref(false); |
|||
const editId = ref(0); |
|||
const form = reactive({ |
|||
username: "", |
|||
password: "", |
|||
identity: 2, |
|||
enabled: "1", |
|||
remark: "", |
|||
brandid: 0, |
|||
channelid: "" |
|||
}); |
|||
const roleCeiling = computed(() => ROLE_ACCESS_CEILING[form.identity] ?? null); |
|||
computed(() => roleCeiling.value ?? ALL_MENU_IDS); |
|||
const menuGroupsForRole = computed(() => { |
|||
const ceiling = roleCeiling.value; |
|||
if (!ceiling) return MENU_GROUPS; |
|||
return MENU_GROUPS.map((g) => ({ ...g, items: g.items.filter((m) => ceiling.includes(m.id)) })).filter((g) => g.items.length > 0); |
|||
}); |
|||
const channels = ref([]); |
|||
const accountChannelOptions = computed( |
|||
() => form.brandid ? channels.value.filter((ch) => ch.brandid === form.brandid) : [] |
|||
); |
|||
const sel = reactive({ |
|||
access: [], |
|||
apps: [], |
|||
regions: [], |
|||
products: [] |
|||
}); |
|||
const brands = ref([]); |
|||
const productGroups = ref([]); |
|||
const prodLoading = ref(false); |
|||
function fromCsv(s) { |
|||
return (s || "").split(",").map((x) => x.trim()).filter((x) => x); |
|||
} |
|||
function scopeParts(a) { |
|||
const parts = []; |
|||
if (a.apps) parts.push("应用:" + fromCsv(a.apps).length); |
|||
if (a.regions) parts.push("区域:" + fromCsv(a.regions).length); |
|||
if (a.products) parts.push("产品:" + fromCsv(a.products).length); |
|||
if (a.access) parts.push("页面:" + fromCsv(a.access).length); |
|||
return parts; |
|||
} |
|||
watch(() => form.identity, (idt) => { |
|||
if (idt === 2 && sel.access.length === 0) sel.access = DEFAULT_ADMIN_ACCESS.slice(); |
|||
const ceiling = ROLE_ACCESS_CEILING[idt]; |
|||
if (ceiling) sel.access = sel.access.filter((id) => ceiling.includes(id)); |
|||
}); |
|||
ref(null); |
|||
ref(0); |
|||
const topup = reactive({ |
|||
name: "", |
|||
cur: "", |
|||
vipday: 0, |
|||
trademin: 0, |
|||
meetmin: 0 |
|||
}); |
|||
return (_ctx, _push, _parent, _attrs) => { |
|||
_push(`<div${ssrRenderAttrs(_attrs)} data-v-a2832f1b><div style="${ssrRenderStyle(view.value === "list" ? null : { display: "none" })}" data-v-a2832f1b><div class="flex items-center justify-between mb-4" data-v-a2832f1b><div data-v-a2832f1b><h2 class="text-lg font-bold text-slate-700" data-v-a2832f1b>后台账号</h2><p class="text-xs text-slate-400 mt-0.5" data-v-a2832f1b>超管 / 管理员 / 代理 / 运营。代理·运营可绑定应用·区域·产品,登录后仪表盘按绑定限制。</p></div><button class="btn btn-primary btn-sm text-white" data-v-a2832f1b>+ 新建账号</button></div><div class="bg-white rounded-xl shadow-sm border border-slate-100 overflow-hidden" data-v-a2832f1b><table class="table table-sm" data-v-a2832f1b><thead data-v-a2832f1b><tr class="text-slate-500" data-v-a2832f1b><th data-v-a2832f1b>ID</th><th data-v-a2832f1b>用户名</th><th data-v-a2832f1b>角色</th><th data-v-a2832f1b>状态</th><th data-v-a2832f1b>绑定作用域</th><th data-v-a2832f1b>备注</th><th class="text-right" data-v-a2832f1b>操作</th></tr></thead><tbody data-v-a2832f1b>`); |
|||
if (loading.value) { |
|||
_push(`<tr data-v-a2832f1b><td colspan="7" class="text-center text-slate-400 py-8" data-v-a2832f1b>加载中...</td></tr>`); |
|||
} else if (!rows.value.length) { |
|||
_push(`<tr data-v-a2832f1b><td colspan="7" class="text-center text-slate-400 py-8" data-v-a2832f1b>暂无账号(引导超管不在此列)</td></tr>`); |
|||
} else { |
|||
_push(`<!---->`); |
|||
} |
|||
_push(`<!--[-->`); |
|||
ssrRenderList(rows.value, (a) => { |
|||
_push(`<tr data-v-a2832f1b><td class="font-mono" data-v-a2832f1b>${ssrInterpolate(a.id)}</td><td class="font-medium" data-v-a2832f1b>${ssrInterpolate(a.username || "")}</td><td data-v-a2832f1b><span class="${ssrRenderClass([ROLE_CLS[a.identity] || "", "badge badge-sm"])}" data-v-a2832f1b>${ssrInterpolate(ROLE[a.identity] || a.identity)}</span></td><td data-v-a2832f1b>`); |
|||
if (a.enabled) { |
|||
_push(`<span class="text-green-600 text-xs" data-v-a2832f1b>启用</span>`); |
|||
} else { |
|||
_push(`<span class="text-slate-400 text-xs" data-v-a2832f1b>停用</span>`); |
|||
} |
|||
_push(`</td><td data-v-a2832f1b>`); |
|||
if (a.identity === 3 || a.identity === 4) { |
|||
_push(`<!--[-->`); |
|||
if (scopeParts(a).length) { |
|||
_push(`<span class="text-xs text-slate-500" data-v-a2832f1b>${ssrInterpolate(scopeParts(a).join(" · "))}</span>`); |
|||
} else { |
|||
_push(`<span class="text-xs text-slate-300" data-v-a2832f1b>未绑定(不限)</span>`); |
|||
} |
|||
_push(`<!--]-->`); |
|||
} else if (a.identity === 2) { |
|||
_push(`<!--[-->`); |
|||
if (a.access) { |
|||
_push(`<span class="text-xs text-slate-500" data-v-a2832f1b>菜单:${ssrInterpolate(fromCsv(a.access).length)}</span>`); |
|||
} else { |
|||
_push(`<span class="text-xs text-slate-300" data-v-a2832f1b>默认(除SaaS/系统管理)</span>`); |
|||
} |
|||
_push(`<!--]-->`); |
|||
} else { |
|||
_push(`<span class="text-xs text-slate-300" data-v-a2832f1b>全部权限</span>`); |
|||
} |
|||
if (a.identity === 3) { |
|||
_push(`<div class="text-[11px] text-emerald-600 mt-0.5" data-v-a2832f1b> 余额 VIP${ssrInterpolate(a.balance_vipday || 0)}天 · 翻译${ssrInterpolate(a.balance_trademin || 0)}分 · 会议${ssrInterpolate(a.balance_meetmin || 0)}分 </div>`); |
|||
} else { |
|||
_push(`<!---->`); |
|||
} |
|||
_push(`</td><td class="text-xs text-slate-500" data-v-a2832f1b>${ssrInterpolate(a.remark || "")}</td><td data-v-a2832f1b><div class="flex gap-1 justify-end" data-v-a2832f1b>`); |
|||
if (a.identity === 3) { |
|||
_push(`<button class="btn btn-ghost btn-xs text-emerald-600" data-v-a2832f1b>充值</button>`); |
|||
} else { |
|||
_push(`<!---->`); |
|||
} |
|||
_push(`<button class="btn btn-ghost btn-xs" data-v-a2832f1b>编辑</button><button class="btn btn-ghost btn-xs text-amber-600" data-v-a2832f1b>改密</button><button class="btn btn-ghost btn-xs text-red-500" data-v-a2832f1b>删除</button></div></td></tr>`); |
|||
}); |
|||
_push(`<!--]--></tbody></table></div></div><div style="${ssrRenderStyle(view.value === "form" ? null : { display: "none" })}" data-v-a2832f1b><div class="flex items-center gap-3 mb-5" data-v-a2832f1b><button class="btn btn-ghost btn-sm" data-v-a2832f1b>← 返回列表</button><h2 class="text-lg font-semibold text-slate-800" data-v-a2832f1b>${ssrInterpolate(editId.value ? "编辑账号 #" + editId.value : "新建账号")}</h2></div><div class="bg-white rounded-xl shadow-sm border border-slate-100 p-6 max-w-2xl" data-v-a2832f1b><div class="grid grid-cols-2 gap-3" data-v-a2832f1b><div data-v-a2832f1b><label class="text-xs text-slate-500" data-v-a2832f1b>用户名</label><input${ssrRenderAttr("value", form.username)}${ssrIncludeBooleanAttr(!!editId.value) ? " disabled" : ""} class="input input-bordered input-sm w-full" placeholder="登录用户名" data-v-a2832f1b></div><div style="${ssrRenderStyle(!editId.value ? null : { display: "none" })}" data-v-a2832f1b><label class="text-xs text-slate-500" data-v-a2832f1b>密码</label><input${ssrRenderAttr("value", form.password)} type="password" class="input input-bordered input-sm w-full" placeholder="登录密码" data-v-a2832f1b></div><div data-v-a2832f1b><label class="text-xs text-slate-500" data-v-a2832f1b>角色</label><select class="select select-bordered select-sm w-full" data-v-a2832f1b><option${ssrRenderAttr("value", 2)} data-v-a2832f1b${ssrIncludeBooleanAttr(Array.isArray(form.identity) ? ssrLooseContain(form.identity, 2) : ssrLooseEqual(form.identity, 2)) ? " selected" : ""}>管理员(默认除 SaaS/系统管理外全部)</option><option${ssrRenderAttr("value", 3)} data-v-a2832f1b${ssrIncludeBooleanAttr(Array.isArray(form.identity) ? ssrLooseContain(form.identity, 3) : ssrLooseEqual(form.identity, 3)) ? " selected" : ""}>品牌商(绑定品牌商,见名下全部渠道商)</option><option${ssrRenderAttr("value", 5)} data-v-a2832f1b${ssrIncludeBooleanAttr(Array.isArray(form.identity) ? ssrLooseContain(form.identity, 5) : ssrLooseEqual(form.identity, 5)) ? " selected" : ""}>渠道商(绑定单个渠道商,只见自己数据)</option><option${ssrRenderAttr("value", 4)} data-v-a2832f1b${ssrIncludeBooleanAttr(Array.isArray(form.identity) ? ssrLooseContain(form.identity, 4) : ssrLooseEqual(form.identity, 4)) ? " selected" : ""}>运营(内部,按绑定限制)</option><option${ssrRenderAttr("value", 1)} data-v-a2832f1b${ssrIncludeBooleanAttr(Array.isArray(form.identity) ? ssrLooseContain(form.identity, 1) : ssrLooseEqual(form.identity, 1)) ? " selected" : ""}>超管(全部权限)</option></select></div><div data-v-a2832f1b><label class="text-xs text-slate-500" data-v-a2832f1b>状态</label><select class="select select-bordered select-sm w-full" data-v-a2832f1b><option value="1" data-v-a2832f1b${ssrIncludeBooleanAttr(Array.isArray(form.enabled) ? ssrLooseContain(form.enabled, "1") : ssrLooseEqual(form.enabled, "1")) ? " selected" : ""}>启用</option><option value="0" data-v-a2832f1b${ssrIncludeBooleanAttr(Array.isArray(form.enabled) ? ssrLooseContain(form.enabled, "0") : ssrLooseEqual(form.enabled, "0")) ? " selected" : ""}>停用</option></select></div><div class="col-span-2" data-v-a2832f1b><label class="text-xs text-slate-500" data-v-a2832f1b>备注</label><input${ssrRenderAttr("value", form.remark)} class="input input-bordered input-sm w-full" placeholder="可选" data-v-a2832f1b></div></div><div class="mt-4 border-t border-slate-100 pt-4" style="${ssrRenderStyle(form.identity !== 1 ? null : { display: "none" })}" data-v-a2832f1b><div class="flex items-center justify-between mb-1" data-v-a2832f1b><div class="text-sm font-semibold text-slate-600" data-v-a2832f1b>菜单权限</div><div class="flex gap-1" data-v-a2832f1b>`); |
|||
if (!roleCeiling.value) { |
|||
_push(`<button type="button" class="btn btn-ghost btn-xs" data-v-a2832f1b>管理员默认</button>`); |
|||
} else { |
|||
_push(`<!---->`); |
|||
} |
|||
_push(`<button type="button" class="btn btn-ghost btn-xs" data-v-a2832f1b>全选</button><button type="button" class="btn btn-ghost btn-xs" data-v-a2832f1b>清空</button></div></div>`); |
|||
if (roleCeiling.value) { |
|||
_push(`<p class="text-xs text-slate-400 mb-3" data-v-a2832f1b>该角色为外部账号,可见页面固定在下列范围内(留空即全部开放这些页面)。</p>`); |
|||
} else { |
|||
_push(`<p class="text-xs text-slate-400 mb-3" data-v-a2832f1b>管理员默认开放除「SaaS 管理 / 系统管理」以外的全部菜单(权限留空时按默认生效);代理/运营需显式勾选。</p>`); |
|||
} |
|||
_push(`<!--[-->`); |
|||
ssrRenderList(menuGroupsForRole.value, (g) => { |
|||
_push(`<div class="mb-2.5" data-v-a2832f1b><div class="text-xs text-slate-500 mb-1.5" data-v-a2832f1b>${ssrInterpolate(g.label)}`); |
|||
if (g.restricted) { |
|||
_push(`<span class="text-amber-500 ml-1" data-v-a2832f1b>(管理员默认不开放)</span>`); |
|||
} else { |
|||
_push(`<!---->`); |
|||
} |
|||
_push(`</div><div class="flex flex-wrap gap-2" data-v-a2832f1b><!--[-->`); |
|||
ssrRenderList(g.items, (m) => { |
|||
_push(`<label class="chk" data-v-a2832f1b><input${ssrIncludeBooleanAttr(Array.isArray(sel.access) ? ssrLooseContain(sel.access, m.id) : sel.access) ? " checked" : ""} type="checkbox"${ssrRenderAttr("value", m.id)} data-v-a2832f1b>${ssrInterpolate(m.label)}</label>`); |
|||
}); |
|||
_push(`<!--]--></div></div>`); |
|||
}); |
|||
_push(`<!--]--></div><div class="mt-4 border-t border-slate-100 pt-4" style="${ssrRenderStyle(form.identity === 3 || form.identity === 5 ? null : { display: "none" })}" data-v-a2832f1b><div class="text-sm font-semibold text-slate-600 mb-2" data-v-a2832f1b> 归属绑定 <span class="text-xs text-slate-400 font-normal" data-v-a2832f1b>(品牌商账号只绑品牌商;渠道商账号两者都要绑)</span></div><div class="grid grid-cols-2 gap-3" data-v-a2832f1b><div data-v-a2832f1b><label class="text-xs text-slate-500" data-v-a2832f1b>所属品牌商 *</label><select class="select select-bordered select-sm w-full" data-v-a2832f1b><option${ssrRenderAttr("value", 0)} data-v-a2832f1b${ssrIncludeBooleanAttr(Array.isArray(form.brandid) ? ssrLooseContain(form.brandid, 0) : ssrLooseEqual(form.brandid, 0)) ? " selected" : ""}>请选择品牌商</option><!--[-->`); |
|||
ssrRenderList(brands.value, (b) => { |
|||
_push(`<option${ssrRenderAttr("value", b.id)} data-v-a2832f1b${ssrIncludeBooleanAttr(Array.isArray(form.brandid) ? ssrLooseContain(form.brandid, b.id) : ssrLooseEqual(form.brandid, b.id)) ? " selected" : ""}>${ssrInterpolate(b.brand)}</option>`); |
|||
}); |
|||
_push(`<!--]--></select></div><div style="${ssrRenderStyle(form.identity === 5 ? null : { display: "none" })}" data-v-a2832f1b><label class="text-xs text-slate-500" data-v-a2832f1b>所属渠道商 *</label><select class="select select-bordered select-sm w-full"${ssrIncludeBooleanAttr(!accountChannelOptions.value.length) ? " disabled" : ""} data-v-a2832f1b><option value="" data-v-a2832f1b${ssrIncludeBooleanAttr(Array.isArray(form.channelid) ? ssrLooseContain(form.channelid, "") : ssrLooseEqual(form.channelid, "")) ? " selected" : ""}>${ssrInterpolate(form.brandid ? accountChannelOptions.value.length ? "请选择渠道商" : "该品牌商暂无渠道商" : "请先选择品牌商")}</option><!--[-->`); |
|||
ssrRenderList(accountChannelOptions.value, (ch) => { |
|||
_push(`<option${ssrRenderAttr("value", ch.id)} data-v-a2832f1b${ssrIncludeBooleanAttr(Array.isArray(form.channelid) ? ssrLooseContain(form.channelid, ch.id) : ssrLooseEqual(form.channelid, ch.id)) ? " selected" : ""}>${ssrInterpolate(ch.name)} (${ssrInterpolate(ch.id)})</option>`); |
|||
}); |
|||
_push(`<!--]--></select></div></div><p class="text-xs text-slate-400 mt-2" data-v-a2832f1b> 数据隔离由后端强制:品牌商账号只能看到本品牌商及其名下渠道商的数据,渠道商账号只能看到自己渠道的数据。 </p></div><div class="mt-4 border-t border-slate-100 pt-4" style="${ssrRenderStyle(form.identity === 3 || form.identity === 4 ? null : { display: "none" })}" data-v-a2832f1b><div class="text-sm font-semibold text-slate-600 mb-2" data-v-a2832f1b>作用域绑定 <span class="text-xs text-slate-400 font-normal" data-v-a2832f1b>(代理/运营生效;限制仪表盘数据范围)</span></div><div class="mb-3" data-v-a2832f1b><div class="text-xs text-slate-500 mb-1.5" data-v-a2832f1b>绑定应用 <span class="text-slate-300" data-v-a2832f1b>(仪表盘只显示这些应用数据;不勾=不限)</span></div><div class="flex flex-wrap gap-2" data-v-a2832f1b>`); |
|||
if (appNames.value.length) { |
|||
_push(`<!--[-->`); |
|||
ssrRenderList(appNames.value, (n) => { |
|||
_push(`<label class="chk" data-v-a2832f1b><input${ssrIncludeBooleanAttr(Array.isArray(sel.apps) ? ssrLooseContain(sel.apps, n) : sel.apps) ? " checked" : ""} type="checkbox"${ssrRenderAttr("value", n)} data-v-a2832f1b>${ssrInterpolate(n)}</label>`); |
|||
}); |
|||
_push(`<!--]-->`); |
|||
} else { |
|||
_push(`<span class="text-xs text-slate-300" data-v-a2832f1b>无注册应用</span>`); |
|||
} |
|||
_push(`</div></div><div class="mb-3" data-v-a2832f1b><div class="text-xs text-slate-500 mb-1.5" data-v-a2832f1b>绑定区域 <span class="text-slate-300" data-v-a2832f1b>(不勾=不限)</span></div><div class="flex flex-wrap gap-2" data-v-a2832f1b><!--[-->`); |
|||
ssrRenderList(unref(REGION_OPTIONS), (r) => { |
|||
_push(`<label class="chk" data-v-a2832f1b><input${ssrIncludeBooleanAttr(Array.isArray(sel.regions) ? ssrLooseContain(sel.regions, r.value) : sel.regions) ? " checked" : ""} type="checkbox"${ssrRenderAttr("value", r.value)} data-v-a2832f1b>${ssrInterpolate(r.label)}</label>`); |
|||
}); |
|||
_push(`<!--]--></div></div><div data-v-a2832f1b><div class="text-xs text-slate-500 mb-1.5" data-v-a2832f1b>绑定产品 <span class="text-slate-300" data-v-a2832f1b>(按厂家分组;仪表盘只显示这些产品数据;不勾=不限)</span></div><div class="max-h-56 overflow-y-auto pr-1 border border-slate-100 rounded-lg p-2" data-v-a2832f1b>`); |
|||
if (prodLoading.value) { |
|||
_push(`<span class="text-xs text-slate-300" data-v-a2832f1b>加载产品中...</span>`); |
|||
} else if (!productGroups.value.length) { |
|||
_push(`<span class="text-xs text-slate-300" data-v-a2832f1b>无产品</span>`); |
|||
} else { |
|||
_push(`<!--[-->`); |
|||
ssrRenderList(productGroups.value, (g) => { |
|||
_push(`<div class="mb-2 last:mb-0" data-v-a2832f1b><div class="text-[11px] font-semibold text-slate-500 mb-1 sticky top-0 bg-white py-0.5" data-v-a2832f1b>🏭 ${ssrInterpolate(g.label)}</div><div class="flex flex-wrap gap-2" data-v-a2832f1b><!--[-->`); |
|||
ssrRenderList(g.products, (p) => { |
|||
_push(`<label class="chk" data-v-a2832f1b><input${ssrIncludeBooleanAttr(Array.isArray(sel.products) ? ssrLooseContain(sel.products, String(p.id)) : sel.products) ? " checked" : ""} type="checkbox"${ssrRenderAttr("value", String(p.id))} data-v-a2832f1b>${ssrInterpolate((p.devicename || "产品") + " #" + p.id)}</label>`); |
|||
}); |
|||
_push(`<!--]--></div></div>`); |
|||
}); |
|||
_push(`<!--]-->`); |
|||
} |
|||
_push(`</div></div></div><div class="flex gap-3 justify-end mt-6" data-v-a2832f1b><button class="btn btn-ghost btn-sm" data-v-a2832f1b>取消</button><button class="btn btn-primary btn-sm text-white"${ssrIncludeBooleanAttr(submitting.value) ? " disabled" : ""} data-v-a2832f1b>保存</button></div></div></div><dialog class="modal" data-v-a2832f1b><div class="modal-box max-w-md" data-v-a2832f1b><h3 class="font-bold text-lg mb-1" data-v-a2832f1b>充值 / 调整资源点</h3><p class="text-xs text-slate-400 mb-3" data-v-a2832f1b>代理:<span class="font-medium text-slate-600" data-v-a2832f1b>${ssrInterpolate(topup.name)}</span>。填增量(可填负数下调),当前余额:<span class="text-emerald-600" data-v-a2832f1b>${ssrInterpolate(topup.cur)}</span></p><div class="grid grid-cols-3 gap-3" data-v-a2832f1b><div data-v-a2832f1b><label class="text-xs text-slate-500" data-v-a2832f1b>VIP天数</label><input${ssrRenderAttr("value", topup.vipday)} type="number" class="input input-bordered input-sm w-full" data-v-a2832f1b></div><div data-v-a2832f1b><label class="text-xs text-slate-500" data-v-a2832f1b>翻译分钟</label><input${ssrRenderAttr("value", topup.trademin)} type="number" class="input input-bordered input-sm w-full" data-v-a2832f1b></div><div data-v-a2832f1b><label class="text-xs text-slate-500" data-v-a2832f1b>会议分钟</label><input${ssrRenderAttr("value", topup.meetmin)} type="number" class="input input-bordered input-sm w-full" data-v-a2832f1b></div></div><div class="modal-action" data-v-a2832f1b><button class="btn btn-ghost btn-sm" data-v-a2832f1b>取消</button><button class="btn btn-primary btn-sm text-white" data-v-a2832f1b>确认</button></div></div><form method="dialog" class="modal-backdrop" data-v-a2832f1b><button data-v-a2832f1b>close</button></form></dialog></div>`); |
|||
}; |
|||
} |
|||
}); |
|||
const _sfc_setup = _sfc_main.setup; |
|||
_sfc_main.setup = (props, ctx) => { |
|||
const ssrContext = useSSRContext(); |
|||
(ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("pages/accounts.vue"); |
|||
return _sfc_setup ? _sfc_setup(props, ctx) : void 0; |
|||
}; |
|||
const accounts = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-a2832f1b"]]); |
|||
|
|||
export { accounts as default }; |
|||
//# sourceMappingURL=accounts-CM5YEJ4p.mjs.map
|
|||
@ -1 +0,0 @@ |
|||
{"version":3,"file":"accounts-CM5YEJ4p.mjs","sources":["../../../../node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/accounts-CM5YEJ4p.js"],"names":[],"mappings":"","x_google_ignoreList":[0]} |
|||
@ -1,8 +0,0 @@ |
|||
const accounts_vue_vue_type_style_index_0_scoped_a2832f1b_lang = ".chk[data-v-a2832f1b]{display:flex;align-items:center;gap:6px;padding:5px 9px;border:1px solid #e2e8f0;border-radius:8px;font-size:12px;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none}.chk[data-v-a2832f1b]:hover{background:#f8fafc}.chk input[data-v-a2832f1b]{width:14px;height:14px}"; |
|||
|
|||
const accountsStyles_Bwl6sYRz = [ |
|||
accounts_vue_vue_type_style_index_0_scoped_a2832f1b_lang |
|||
]; |
|||
|
|||
export { accountsStyles_Bwl6sYRz as default }; |
|||
//# sourceMappingURL=accounts-styles.Bwl6sYRz.mjs.map
|
|||
@ -1 +0,0 @@ |
|||
{"version":3,"file":"accounts-styles.Bwl6sYRz.mjs","sources":["../../../../node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/accounts-styles-1.mjs-BqkDag56.js","../../../../node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/accounts-styles.Bwl6sYRz.mjs"],"names":["style_0"],"mappings":"","x_google_ignoreList":[0,1]} |
|||
@ -1,310 +0,0 @@ |
|||
import { defineComponent, ref, reactive, computed, useSSRContext } from 'vue'; |
|||
import { ssrRenderAttrs, ssrIncludeBooleanAttr, ssrLooseContain, ssrLooseEqual, ssrRenderList, ssrRenderAttr, ssrInterpolate, ssrRenderStyle, ssrRenderClass, ssrRenderComponent } from 'vue/server-renderer'; |
|||
import { u as useApi } from './useApi-BNSkSrat.mjs'; |
|||
import { u as useToast } from './useToast-MBvLaNjH.mjs'; |
|||
import { L as LANG_OPTIONS } from './useLangOptions-CXXbv5NM.mjs'; |
|||
import { _ as __nuxt_component_0 } from './LangSelect-Bvw-e1Cn.mjs'; |
|||
import { _ as _export_sfc } from './server.mjs'; |
|||
import '../nitro/nitro.mjs'; |
|||
import 'node:http'; |
|||
import 'node:https'; |
|||
import 'node:events'; |
|||
import 'node:buffer'; |
|||
import 'node:fs'; |
|||
import 'node:path'; |
|||
import 'node:crypto'; |
|||
import 'node:url'; |
|||
import '../routes/renderer.mjs'; |
|||
import 'vue-bundle-renderer/runtime'; |
|||
import 'unhead/server'; |
|||
import 'devalue'; |
|||
import 'unhead/utils'; |
|||
import 'pinia'; |
|||
import 'perfect-debounce'; |
|||
|
|||
const CAT_STT = 1; |
|||
const CAT_TTS = 2; |
|||
const CAT_MT = 3; |
|||
const CAT_AST = 4; |
|||
const CAT_LLM = 5; |
|||
const CAT_STS = 7; |
|||
const CAT_LLM_VISION = 9; |
|||
const CAT_MCP = 10; |
|||
const _sfc_main = /* @__PURE__ */ defineComponent({ |
|||
__name: "agents", |
|||
__ssrInlineRender: true, |
|||
setup(__props) { |
|||
const AGENT_TYPES = [ |
|||
{ value: "chat", label: "chat-agent 对话", icon: "💬", hint: "STT → LLM → TTS 三段拼接", color: "#b45309", bg: "#fef9c3" }, |
|||
{ value: "sts-chat", label: "sts-chat-agent 端到端对话", icon: "⚡", hint: "单个 STS 服务直接完成语音对话", color: "#be185d", bg: "#fce7f3" } |
|||
]; |
|||
const LEGACY_TYPES = { |
|||
translate: { label: "翻译(已下线)", icon: "🧩", color: "#64748b", bg: "#f1f5f9" }, |
|||
"ast-translate": { label: "端到端翻译(已下线)", icon: "🚀", color: "#64748b", bg: "#f1f5f9" } |
|||
}; |
|||
const SLOTS = { |
|||
chat: [ |
|||
{ key: "stt_svc_id", slot: "STT", label: "语音识别", cats: [CAT_STT], color: "#1664ff" }, |
|||
{ key: "llm_svc_id", slot: "LLM", label: "大语言模型", cats: [CAT_LLM, CAT_LLM_VISION], color: "#b45309" }, |
|||
{ key: "tts_svc_id", slot: "TTS", label: "语音合成", cats: [CAT_TTS], color: "#7c3aed" } |
|||
], |
|||
translate: [ |
|||
{ key: "stt_svc_id", slot: "STT", label: "语音识别", cats: [CAT_STT], color: "#1664ff" }, |
|||
{ key: "mt_svc_id", slot: "MT", label: "机器翻译", cats: [CAT_MT], color: "#059669" }, |
|||
{ key: "tts_svc_id", slot: "TTS", label: "语音合成", cats: [CAT_TTS], color: "#7c3aed" } |
|||
], |
|||
"sts-chat": [{ key: "sts_svc_id", slot: "STS", label: "端到端语音对话", cats: [CAT_STS], color: "#be185d" }], |
|||
"ast-translate": [{ key: "ast_svc_id", slot: "AST", label: "端到端语音翻译", cats: [CAT_AST], color: "#f97316" }] |
|||
}; |
|||
function slotsOfType(t) { |
|||
return SLOTS[t] ?? []; |
|||
} |
|||
useApi(); |
|||
useToast(); |
|||
const scopeApp = ref(""); |
|||
const scopeApps = ref([]); |
|||
const agents2 = ref([]); |
|||
const allSvcs = ref([]); |
|||
const ttsVoices = ref([]); |
|||
const modalOpen = ref(false); |
|||
const isEditing = ref(false); |
|||
const submitting = ref(false); |
|||
function emptyForm() { |
|||
return { |
|||
app_name: "", |
|||
id: "", |
|||
name: "", |
|||
type: "chat", |
|||
description: "", |
|||
avatar_url: "", |
|||
enable: true, |
|||
stt_svc_id: "", |
|||
llm_svc_id: "", |
|||
tts_svc_id: "", |
|||
mt_svc_id: "", |
|||
sts_svc_id: "", |
|||
ast_svc_id: "", |
|||
system_prompt: "", |
|||
gender: 0, |
|||
greeting_enabled: false, |
|||
greeting_text: "", |
|||
support_langs: "", |
|||
default_lang: "", |
|||
voice_map: [], |
|||
mcp_svc_ids: [], |
|||
variables: [], |
|||
sort: 0 |
|||
}; |
|||
} |
|||
const form = reactive(emptyForm()); |
|||
const isChatType = computed(() => form.type === "chat" || form.type === "sts-chat"); |
|||
const supportedLangOptions = computed(() => { |
|||
const codes = (form.support_langs || "").split(",").map((x) => x.trim()).filter(Boolean); |
|||
if (!codes.length) return LANG_OPTIONS; |
|||
return LANG_OPTIONS.filter((o) => codes.includes(o.code)); |
|||
}); |
|||
const bySort = (a, b) => (b.sort || 0) - (a.sort || 0) || (a.name || "").localeCompare(b.name || ""); |
|||
const grouped = computed(() => { |
|||
const groups = AGENT_TYPES.map((t) => ({ |
|||
...t, |
|||
type: t.value, |
|||
items: agents2.value.filter((a) => a.type === t.value).sort(bySort) |
|||
})).filter((g) => g.items.length); |
|||
for (const [type, meta] of Object.entries(LEGACY_TYPES)) { |
|||
const items = agents2.value.filter((a) => a.type === type).sort(bySort); |
|||
if (items.length) groups.push({ value: type, type, hint: "已下线的类型,仅供查看与清理", ...meta, items }); |
|||
} |
|||
return groups; |
|||
}); |
|||
const voiceSvcId = computed(() => form.type === "sts-chat" ? form.sts_svc_id : form.tts_svc_id); |
|||
const voiceProvider = computed(() => allSvcs.value.find((s) => s.id === voiceSvcId.value)?.provider ?? ""); |
|||
const voiceTableSupported = computed(() => !!voiceProvider.value && ttsVoices.value.some((v) => v.provider === voiceProvider.value)); |
|||
function voiceOptions(language, gender) { |
|||
const provider = voiceProvider.value; |
|||
if (!provider || !language) return []; |
|||
const base = (language.split("-")[0] || "").toLowerCase(); |
|||
const hit = ttsVoices.value.filter((v) => { |
|||
if (v.provider !== provider) return false; |
|||
if (gender && v.gender !== gender) return false; |
|||
return v.language.toLowerCase() === language.toLowerCase(); |
|||
}); |
|||
if (hit.length) return hit; |
|||
return ttsVoices.value.filter((v) => { |
|||
if (v.provider !== provider) return false; |
|||
if (gender && v.gender !== gender) return false; |
|||
return (v.language.split("-")[0] || "").toLowerCase() === base; |
|||
}); |
|||
} |
|||
const mcpSvcs = computed(() => svcsByCats([CAT_MCP])); |
|||
function svcCats(s) { |
|||
return (s.categories || "").split(",").map(Number); |
|||
} |
|||
function svcsByCats(cats) { |
|||
return allSvcs.value.filter((s) => s.enable && svcCats(s).some((c) => cats.includes(c))); |
|||
} |
|||
function isVisionSvc(s) { |
|||
return svcCats(s).includes(CAT_LLM_VISION); |
|||
} |
|||
function svcName(id) { |
|||
if (!id) return "未配置"; |
|||
const s = allSvcs.value.find((x) => x.id === id); |
|||
return s ? s.name : id; |
|||
} |
|||
function pipelineOf(a) { |
|||
return slotsOfType(a.type).map((s) => ({ slot: s.slot, color: s.color, id: a[s.key] })); |
|||
} |
|||
return (_ctx, _push, _parent, _attrs) => { |
|||
_push(`<div${ssrRenderAttrs(_attrs)} data-v-dcf87e76><div class="flex items-center justify-between mb-5 flex-wrap gap-3" data-v-dcf87e76><div data-v-dcf87e76><h2 class="text-lg font-semibold text-slate-800" data-v-dcf87e76>Agent 配置</h2><p class="text-xs text-slate-400 mt-1" data-v-dcf87e76> 把已配置的第三方服务编排成可下发客户端的智能体。四种类型按需引用不同服务;通话翻译规则只能引用「翻译」与「端到端翻译」两类。 </p></div><div class="flex items-center gap-3" data-v-dcf87e76><span class="text-sm text-slate-500" data-v-dcf87e76>作用域</span><select class="select select-bordered select-sm" data-v-dcf87e76><option value="" data-v-dcf87e76${ssrIncludeBooleanAttr(Array.isArray(scopeApp.value) ? ssrLooseContain(scopeApp.value, "") : ssrLooseEqual(scopeApp.value, "")) ? " selected" : ""}>全局默认</option><!--[-->`); |
|||
ssrRenderList(scopeApps.value, (a) => { |
|||
_push(`<option${ssrRenderAttr("value", a)} data-v-dcf87e76${ssrIncludeBooleanAttr(Array.isArray(scopeApp.value) ? ssrLooseContain(scopeApp.value, a) : ssrLooseEqual(scopeApp.value, a)) ? " selected" : ""}>${ssrInterpolate(a)}</option>`); |
|||
}); |
|||
_push(`<!--]--></select><button class="btn btn-primary btn-sm text-white" data-v-dcf87e76>+ 新建 Agent</button></div></div>`); |
|||
if (!agents2.value.length) { |
|||
_push(`<div class="text-center py-20 text-slate-300" data-v-dcf87e76><div class="text-5xl mb-3" data-v-dcf87e76>🤖</div><p class="text-sm" data-v-dcf87e76>当前作用域下还没有 Agent</p><p class="text-xs mt-1" data-v-dcf87e76>先在「第三方服务配置」里配好服务,再来把它们组装成 Agent</p></div>`); |
|||
} else { |
|||
_push(`<!---->`); |
|||
} |
|||
_push(`<!--[-->`); |
|||
ssrRenderList(grouped.value, (g) => { |
|||
_push(`<div class="mb-6" data-v-dcf87e76><div class="flex items-center gap-2 mb-3" data-v-dcf87e76><span class="type-tag" style="${ssrRenderStyle({ background: g.bg, color: g.color })}" data-v-dcf87e76>${ssrInterpolate(g.icon)} ${ssrInterpolate(g.label)}</span><span class="text-xs text-slate-400" data-v-dcf87e76>${ssrInterpolate(g.hint)}</span><span class="text-xs text-slate-300" data-v-dcf87e76>·</span><span class="text-xs text-slate-400" data-v-dcf87e76>${ssrInterpolate(g.items.length)} 个</span></div><div class="agent-grid" data-v-dcf87e76><!--[-->`); |
|||
ssrRenderList(g.items, (a) => { |
|||
_push(`<div class="agent-card" data-v-dcf87e76><div class="flex items-start justify-between gap-2" data-v-dcf87e76><div class="min-w-0" data-v-dcf87e76><div class="font-semibold text-sm text-slate-800 truncate" data-v-dcf87e76>${ssrInterpolate(a.name || a.id)}</div><div class="text-[11px] text-slate-400 mt-0.5 truncate" data-v-dcf87e76>${ssrInterpolate(a.id)}</div></div><div class="flex items-center gap-1 flex-shrink-0" data-v-dcf87e76>`); |
|||
if (a.enable) { |
|||
_push(`<span class="badge badge-success badge-xs" data-v-dcf87e76>启用</span>`); |
|||
} else { |
|||
_push(`<span class="badge badge-ghost badge-xs" data-v-dcf87e76>停用</span>`); |
|||
} |
|||
_push(`<button class="btn btn-ghost btn-xs text-error" data-v-dcf87e76>删除</button></div></div>`); |
|||
if (a.description) { |
|||
_push(`<p class="text-xs text-slate-500 mt-2 line-clamp-2" data-v-dcf87e76>${ssrInterpolate(a.description)}</p>`); |
|||
} else { |
|||
_push(`<!---->`); |
|||
} |
|||
_push(`<div class="flex flex-wrap items-center gap-1.5 mt-3" data-v-dcf87e76><!--[-->`); |
|||
ssrRenderList(pipelineOf(a), (s) => { |
|||
_push(`<span class="svc-pill" style="${ssrRenderStyle({ background: s.color })}" data-v-dcf87e76>${ssrInterpolate(s.slot)}: ${ssrInterpolate(svcName(s.id))}</span>`); |
|||
}); |
|||
_push(`<!--]--></div>`); |
|||
if (a.support_langs) { |
|||
_push(`<div class="text-[11px] text-slate-400 mt-2 truncate" data-v-dcf87e76> 支持语言:${ssrInterpolate(a.support_langs)}</div>`); |
|||
} else { |
|||
_push(`<!---->`); |
|||
} |
|||
_push(`</div>`); |
|||
}); |
|||
_push(`<!--]--></div></div>`); |
|||
}); |
|||
_push(`<!--]--><div class="ag-overlay" style="${ssrRenderStyle(modalOpen.value ? null : { display: "none" })}" data-v-dcf87e76><div class="ag-box" data-v-dcf87e76><div class="flex items-center justify-between mb-4" data-v-dcf87e76><div class="flex items-center gap-3" data-v-dcf87e76><h3 class="text-base font-semibold text-slate-800" data-v-dcf87e76>${ssrInterpolate(isEditing.value ? "编辑 Agent" : "新建 Agent")}</h3><span class="scope-chip" data-v-dcf87e76>${ssrInterpolate(scopeApp.value || "全局默认")}</span></div><button class="btn btn-ghost btn-xs" data-v-dcf87e76>✕ 关闭</button></div><section class="ed-section" data-v-dcf87e76><div class="ed-section-title" data-v-dcf87e76>类型</div><div class="type-row" data-v-dcf87e76><!--[-->`); |
|||
ssrRenderList(AGENT_TYPES, (t) => { |
|||
_push(`<button type="button" class="${ssrRenderClass([{ on: form.type === t.value, locked: isEditing.value && form.type !== t.value }, "ttab"])}"${ssrIncludeBooleanAttr(isEditing.value) ? " disabled" : ""} data-v-dcf87e76><span class="ttab-title" data-v-dcf87e76>${ssrInterpolate(t.icon)} ${ssrInterpolate(t.label)}</span><span class="ttab-desc" data-v-dcf87e76>${ssrInterpolate(t.hint)}</span></button>`); |
|||
}); |
|||
_push(`<!--]--></div>`); |
|||
if (isEditing.value) { |
|||
_push(`<p class="ed-tip" data-v-dcf87e76>类型创建后不可更改;需要换类型请新建一个 Agent。</p>`); |
|||
} else { |
|||
_push(`<!---->`); |
|||
} |
|||
_push(`</section><section class="ed-section" data-v-dcf87e76><div class="ed-section-title" data-v-dcf87e76>基本信息</div><div class="grid grid-cols-2 gap-3" data-v-dcf87e76><div data-v-dcf87e76><span class="ed-label" data-v-dcf87e76>Agent ID <i class="req" data-v-dcf87e76>*</i></span><input${ssrRenderAttr("value", form.id)}${ssrIncludeBooleanAttr(isEditing.value) ? " disabled" : ""} class="input input-bordered input-sm w-full" placeholder="如 trans-cn-en(作用域内唯一,创建后不可改)" data-v-dcf87e76></div><div data-v-dcf87e76><span class="ed-label" data-v-dcf87e76>名称 <i class="req" data-v-dcf87e76>*</i></span><input${ssrRenderAttr("value", form.name)} class="input input-bordered input-sm w-full" placeholder="展示名,如 中英实时翻译" data-v-dcf87e76></div></div><div class="mt-3" data-v-dcf87e76><span class="ed-label" data-v-dcf87e76>描述</span><input${ssrRenderAttr("value", form.description)} class="input input-bordered input-sm w-full" placeholder="这个 Agent 用在什么场景" data-v-dcf87e76></div><div class="grid grid-cols-3 gap-3 mt-3" data-v-dcf87e76><div data-v-dcf87e76><span class="ed-label" data-v-dcf87e76>头像 URL</span><input${ssrRenderAttr("value", form.avatar_url)} class="input input-bordered input-sm w-full" placeholder="可留空" data-v-dcf87e76></div><div data-v-dcf87e76><span class="ed-label" data-v-dcf87e76>排序(越大越靠前)</span><input${ssrRenderAttr("value", form.sort)} type="number" class="input input-bordered input-sm w-full" data-v-dcf87e76></div><div data-v-dcf87e76><span class="ed-label" data-v-dcf87e76>音色性别偏好</span><select class="select select-bordered select-sm w-full" data-v-dcf87e76><option${ssrRenderAttr("value", 0)} data-v-dcf87e76${ssrIncludeBooleanAttr(Array.isArray(form.gender) ? ssrLooseContain(form.gender, 0) : ssrLooseEqual(form.gender, 0)) ? " selected" : ""}>不限</option><option${ssrRenderAttr("value", 1)} data-v-dcf87e76${ssrIncludeBooleanAttr(Array.isArray(form.gender) ? ssrLooseContain(form.gender, 1) : ssrLooseEqual(form.gender, 1)) ? " selected" : ""}>男</option><option${ssrRenderAttr("value", 2)} data-v-dcf87e76${ssrIncludeBooleanAttr(Array.isArray(form.gender) ? ssrLooseContain(form.gender, 2) : ssrLooseEqual(form.gender, 2)) ? " selected" : ""}>女</option></select></div></div></section><section class="ed-section" data-v-dcf87e76><div class="ed-section-title" data-v-dcf87e76>服务编排</div><div class="slot-row" data-v-dcf87e76><!--[-->`); |
|||
ssrRenderList(slotsOfType(form.type), (s, i) => { |
|||
_push(`<!--[--><div class="slot-item" data-v-dcf87e76><span class="stage-tag" style="${ssrRenderStyle({ background: s.color })}" data-v-dcf87e76>${ssrInterpolate(s.slot)}</span><span class="ed-label inline" data-v-dcf87e76>${ssrInterpolate(s.label)}</span><select class="select select-bordered select-sm w-full" data-v-dcf87e76><option value="" disabled data-v-dcf87e76${ssrIncludeBooleanAttr(Array.isArray(form[s.key]) ? ssrLooseContain(form[s.key], "") : ssrLooseEqual(form[s.key], "")) ? " selected" : ""}>${ssrInterpolate(svcsByCats(s.cats).length ? "请选择服务" : "(无可用服务,请先去第三方服务配置里添加)")}</option><!--[-->`); |
|||
ssrRenderList(svcsByCats(s.cats), (v) => { |
|||
_push(`<option${ssrRenderAttr("value", v.id)} data-v-dcf87e76${ssrIncludeBooleanAttr(Array.isArray(form[s.key]) ? ssrLooseContain(form[s.key], v.id) : ssrLooseEqual(form[s.key], v.id)) ? " selected" : ""}>${ssrInterpolate(v.name)}${ssrInterpolate(isVisionSvc(v) ? " 🖼" : "")}</option>`); |
|||
}); |
|||
_push(`<!--]--></select></div>`); |
|||
if (i < slotsOfType(form.type).length - 1) { |
|||
_push(`<span class="slot-arrow" data-v-dcf87e76>→</span>`); |
|||
} else { |
|||
_push(`<!---->`); |
|||
} |
|||
_push(`<!--]-->`); |
|||
}); |
|||
_push(`<!--]--></div></section><section class="ed-section" data-v-dcf87e76><div class="ed-section-title" data-v-dcf87e76>语言与音色</div><div class="grid grid-cols-2 gap-3" data-v-dcf87e76><div data-v-dcf87e76><span class="ed-label" data-v-dcf87e76>支持语言(多选)</span>`); |
|||
_push(ssrRenderComponent(__nuxt_component_0, { |
|||
modelValue: form.support_langs, |
|||
"onUpdate:modelValue": ($event) => form.support_langs = $event, |
|||
multiple: "" |
|||
}, null, _parent)); |
|||
_push(`</div><div data-v-dcf87e76><span class="ed-label" data-v-dcf87e76>默认语言</span>`); |
|||
_push(ssrRenderComponent(__nuxt_component_0, { |
|||
modelValue: form.default_lang, |
|||
"onUpdate:modelValue": ($event) => form.default_lang = $event, |
|||
options: supportedLangOptions.value |
|||
}, null, _parent)); |
|||
_push(`</div></div><div class="mt-3" data-v-dcf87e76><div class="flex items-center justify-between mb-1" data-v-dcf87e76><span class="ed-label mb-0" data-v-dcf87e76>音色(按语言+性别配,Agent 切语言时自动换音色)</span><div class="flex gap-1" data-v-dcf87e76><button class="btn btn-ghost btn-xs"${ssrIncludeBooleanAttr(!voiceTableSupported.value) ? " disabled" : ""} data-v-dcf87e76>按支持语言补全</button><button class="btn btn-ghost btn-xs" data-v-dcf87e76>+ 添加一行</button></div></div><p class="ed-tip mb-1" data-v-dcf87e76>`); |
|||
if (!voiceSvcId.value) { |
|||
_push(`<!--[-->先在上方选好语音服务,这里才能列出可用音色。<!--]-->`); |
|||
} else if (voiceTableSupported.value) { |
|||
_push(`<!--[--> 候选来自内置音色表(${ssrInterpolate(voiceProvider.value)});同一语言+性别有多个时默认第一个,可在下拉里换。没配到的语言走服务商默认音色。 <!--]-->`); |
|||
} else { |
|||
_push(`<!--[-->「${ssrInterpolate(voiceProvider.value || "该服务商")}」不在内置音色表里,请手填服务商的音色 id。<!--]-->`); |
|||
} |
|||
_push(`</p>`); |
|||
if (!form.voice_map.length) { |
|||
_push(`<div class="text-xs text-slate-300 py-2" data-v-dcf87e76>未设置,全部走服务商默认音色</div>`); |
|||
} else { |
|||
_push(`<!---->`); |
|||
} |
|||
_push(`<!--[-->`); |
|||
ssrRenderList(form.voice_map, (v, i) => { |
|||
_push(`<div class="voice-row" data-v-dcf87e76><select class="select select-bordered select-xs" data-v-dcf87e76><option value="" data-v-dcf87e76${ssrIncludeBooleanAttr(Array.isArray(v.language) ? ssrLooseContain(v.language, "") : ssrLooseEqual(v.language, "")) ? " selected" : ""}>(语言)</option><!--[-->`); |
|||
ssrRenderList(supportedLangOptions.value, (o) => { |
|||
_push(`<option${ssrRenderAttr("value", o.code)} data-v-dcf87e76${ssrIncludeBooleanAttr(Array.isArray(v.language) ? ssrLooseContain(v.language, o.code) : ssrLooseEqual(v.language, o.code)) ? " selected" : ""}>${ssrInterpolate(o.code)} · ${ssrInterpolate(o.name)}</option>`); |
|||
}); |
|||
_push(`<!--]--></select><select class="select select-bordered select-xs" data-v-dcf87e76><option${ssrRenderAttr("value", 0)} data-v-dcf87e76${ssrIncludeBooleanAttr(Array.isArray(v.gender) ? ssrLooseContain(v.gender, 0) : ssrLooseEqual(v.gender, 0)) ? " selected" : ""}>不限</option><option${ssrRenderAttr("value", 1)} data-v-dcf87e76${ssrIncludeBooleanAttr(Array.isArray(v.gender) ? ssrLooseContain(v.gender, 1) : ssrLooseEqual(v.gender, 1)) ? " selected" : ""}>男</option><option${ssrRenderAttr("value", 2)} data-v-dcf87e76${ssrIncludeBooleanAttr(Array.isArray(v.gender) ? ssrLooseContain(v.gender, 2) : ssrLooseEqual(v.gender, 2)) ? " selected" : ""}>女</option></select>`); |
|||
if (voiceTableSupported.value && voiceOptions(v.language, v.gender).length) { |
|||
_push(`<select class="select select-bordered select-xs flex-1" data-v-dcf87e76><!--[-->`); |
|||
ssrRenderList(voiceOptions(v.language, v.gender), (o, oi) => { |
|||
_push(`<option${ssrRenderAttr("value", o.voice_id)} data-v-dcf87e76${ssrIncludeBooleanAttr(Array.isArray(v.voice) ? ssrLooseContain(v.voice, o.voice_id) : ssrLooseEqual(v.voice, o.voice_id)) ? " selected" : ""}>${ssrInterpolate(o.name)} · ${ssrInterpolate(o.voice_id)}${ssrInterpolate(oi === 0 ? "(默认)" : "")}</option>`); |
|||
}); |
|||
_push(`<!--]--></select>`); |
|||
} else { |
|||
_push(`<input${ssrRenderAttr("value", v.voice)} class="input input-bordered input-xs flex-1" placeholder="音色 id,如 zh-CN-XiaoxiaoNeural" data-v-dcf87e76>`); |
|||
} |
|||
_push(`<button class="btn btn-ghost btn-xs text-error" data-v-dcf87e76>删除</button></div>`); |
|||
}); |
|||
_push(`<!--]--></div></section>`); |
|||
if (isChatType.value) { |
|||
_push(`<section class="ed-section" data-v-dcf87e76><div class="ed-section-title" data-v-dcf87e76>对话设定</div><div data-v-dcf87e76><span class="ed-label" data-v-dcf87e76>系统提示词</span><textarea class="textarea textarea-bordered w-full text-xs" rows="3" placeholder="定义这个智能体的人设与行为" data-v-dcf87e76>${ssrInterpolate(form.system_prompt)}</textarea></div><div class="mt-3" data-v-dcf87e76><label class="flex items-center gap-2 text-sm cursor-pointer" data-v-dcf87e76><input${ssrIncludeBooleanAttr(Array.isArray(form.greeting_enabled) ? ssrLooseContain(form.greeting_enabled, null) : form.greeting_enabled) ? " checked" : ""} type="checkbox" class="checkbox checkbox-sm checkbox-primary" data-v-dcf87e76><span data-v-dcf87e76>开场白</span></label>`); |
|||
if (form.greeting_enabled) { |
|||
_push(`<input${ssrRenderAttr("value", form.greeting_text)} class="input input-bordered input-sm w-full mt-2" placeholder="接通后先说的一句话" data-v-dcf87e76>`); |
|||
} else { |
|||
_push(`<!---->`); |
|||
} |
|||
_push(`</div></section>`); |
|||
} else { |
|||
_push(`<!---->`); |
|||
} |
|||
_push(`<section class="ed-section" data-v-dcf87e76><div class="ed-section-title" data-v-dcf87e76>MCP 服务(可选,给 Agent 挂工具)</div>`); |
|||
if (!mcpSvcs.value.length) { |
|||
_push(`<p class="ed-tip" data-v-dcf87e76>还没有启用的 MCP 服务,先去「第三方服务配置 → MCP 服务」添加。</p>`); |
|||
} else { |
|||
_push(`<div class="mcp-grid" data-v-dcf87e76><!--[-->`); |
|||
ssrRenderList(mcpSvcs.value, (m) => { |
|||
_push(`<label class="${ssrRenderClass([{ on: form.mcp_svc_ids.includes(m.id) }, "mcp-item"])}" data-v-dcf87e76><input type="checkbox" class="checkbox checkbox-xs checkbox-primary"${ssrIncludeBooleanAttr(form.mcp_svc_ids.includes(m.id)) ? " checked" : ""} data-v-dcf87e76><span class="min-w-0" data-v-dcf87e76><span class="block truncate" data-v-dcf87e76>${ssrInterpolate(m.name)}</span><span class="block truncate text-[10px] text-slate-400 font-mono" data-v-dcf87e76>${ssrInterpolate(m.id)}</span></span></label>`); |
|||
}); |
|||
_push(`<!--]--></div>`); |
|||
} |
|||
_push(`</section><section class="ed-section" data-v-dcf87e76><div class="flex items-center justify-between mb-1" data-v-dcf87e76><div class="ed-section-title mb-0" data-v-dcf87e76>变量(提示词/开场白里用 {{key}} 占位)</div><button class="btn btn-ghost btn-xs" data-v-dcf87e76>+ 添加变量</button></div>`); |
|||
if (!form.variables.length) { |
|||
_push(`<div class="text-xs text-slate-300 py-2" data-v-dcf87e76>未定义变量</div>`); |
|||
} else { |
|||
_push(`<!---->`); |
|||
} |
|||
_push(`<!--[-->`); |
|||
ssrRenderList(form.variables, (v, i) => { |
|||
_push(`<div class="var-row" data-v-dcf87e76><input${ssrRenderAttr("value", v.key)} class="input input-bordered input-xs" placeholder="key" data-v-dcf87e76><input${ssrRenderAttr("value", v.label)} class="input input-bordered input-xs" placeholder="展示名" data-v-dcf87e76><input${ssrRenderAttr("value", v.def_value)} class="input input-bordered input-xs flex-1" placeholder="默认值(客户端没传时用它)" data-v-dcf87e76><button class="btn btn-ghost btn-xs text-error" data-v-dcf87e76>删除</button></div>`); |
|||
}); |
|||
_push(`<!--]--></section><div class="ed-footer" data-v-dcf87e76><label class="flex items-center gap-2 text-sm cursor-pointer" data-v-dcf87e76><input${ssrIncludeBooleanAttr(Array.isArray(form.enable) ? ssrLooseContain(form.enable, null) : form.enable) ? " checked" : ""} type="checkbox" class="checkbox checkbox-sm checkbox-primary" data-v-dcf87e76><span data-v-dcf87e76>启用</span></label><div class="flex gap-2" data-v-dcf87e76><button class="btn btn-ghost btn-sm" data-v-dcf87e76>取消</button><button class="btn btn-primary btn-sm text-white"${ssrIncludeBooleanAttr(submitting.value) ? " disabled" : ""} data-v-dcf87e76>保存</button></div></div></div></div></div>`); |
|||
}; |
|||
} |
|||
}); |
|||
const _sfc_setup = _sfc_main.setup; |
|||
_sfc_main.setup = (props, ctx) => { |
|||
const ssrContext = useSSRContext(); |
|||
(ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("pages/agents.vue"); |
|||
return _sfc_setup ? _sfc_setup(props, ctx) : void 0; |
|||
}; |
|||
const agents = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-dcf87e76"]]); |
|||
|
|||
export { agents as default }; |
|||
//# sourceMappingURL=agents-Bh_gLb1p.mjs.map
|
|||
@ -1 +0,0 @@ |
|||
{"version":3,"file":"agents-Bh_gLb1p.mjs","sources":["../../../../node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/agents-Bh_gLb1p.js"],"names":[],"mappings":"","x_google_ignoreList":[0]} |
|||
@ -1,8 +0,0 @@ |
|||
const agents_vue_vue_type_style_index_0_scoped_dcf87e76_lang = ".type-tag[data-v-dcf87e76]{font-size:12px;font-weight:700;padding:3px 10px;border-radius:8px}.agent-grid[data-v-dcf87e76]{display:grid;gap:12px;grid-template-columns:repeat(auto-fill,minmax(300px,1fr))}.agent-card[data-v-dcf87e76]{background:#fff;border:1px solid #eef2f7;border-radius:14px;padding:14px 16px;cursor:pointer;transition:all .15s}.agent-card[data-v-dcf87e76]:hover{border-color:#c7d2fe;box-shadow:0 4px 14px #6366f114}.svc-pill[data-v-dcf87e76]{display:inline-flex;align-items:center;font-size:10px;font-weight:600;padding:2px 8px;border-radius:7px;color:#fff}.ag-overlay[data-v-dcf87e76]{position:fixed;inset:0;background:#0f172a73;z-index:100;display:flex;align-items:center;justify-content:center;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);padding:24px}.ag-box[data-v-dcf87e76]{background:#fff;border-radius:18px;padding:24px;width:780px;max-width:96vw;max-height:90vh;overflow-y:auto;box-shadow:0 24px 80px #0000002e}.scope-chip[data-v-dcf87e76]{font-size:11px;font-weight:600;padding:2px 9px;border-radius:6px;background:#eef2ff;color:#4338ca}.ed-section[data-v-dcf87e76]{padding:14px 0;border-top:1px dashed #eef2f7}.ed-section[data-v-dcf87e76]:first-of-type{padding-top:0;border-top:none}.ed-section-title[data-v-dcf87e76]{font-size:11px;font-weight:700;letter-spacing:.04em;color:#94a3b8;margin-bottom:10px}.ed-label[data-v-dcf87e76]{display:block;font-size:11px;color:#64748b;margin-bottom:4px}.ed-label.inline[data-v-dcf87e76]{display:inline-block;margin-left:6px}.ed-tip[data-v-dcf87e76]{font-size:11px;color:#94a3b8;margin-top:8px}.req[data-v-dcf87e76]{color:#dc2626;font-style:normal}.type-row[data-v-dcf87e76]{display:grid;grid-template-columns:repeat(4,1fr);gap:10px}.ttab[data-v-dcf87e76]{display:flex;flex-direction:column;gap:3px;padding:11px 12px;border-radius:10px;border:1.5px solid #e2e8f0;background:#fff;cursor:pointer;transition:all .15s;text-align:left}.ttab[data-v-dcf87e76]:hover:not(:disabled){border-color:#c7d2fe;background:#f8fafc}.ttab.on[data-v-dcf87e76]{border-color:#6366f1;background:linear-gradient(135deg,#eef2ff,#f5f3ff)}.ttab.locked[data-v-dcf87e76]{opacity:.45;cursor:not-allowed}.ttab-title[data-v-dcf87e76]{font-weight:700;font-size:12px;color:#1e293b}.ttab-desc[data-v-dcf87e76]{font-size:10px;color:#94a3b8}.slot-row[data-v-dcf87e76]{display:flex;align-items:flex-end;gap:10px}.slot-item[data-v-dcf87e76]{flex:1;min-width:0}.slot-arrow[data-v-dcf87e76]{color:#cbd5e1;padding-bottom:8px;flex-shrink:0}.stage-tag[data-v-dcf87e76]{display:inline-block;font-size:10px;font-weight:700;padding:1px 7px;border-radius:5px;color:#fff;vertical-align:middle}.var-row[data-v-dcf87e76],.voice-row[data-v-dcf87e76]{display:flex;align-items:center;gap:8px;margin-bottom:6px}.mcp-grid[data-v-dcf87e76]{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:8px}.mcp-item[data-v-dcf87e76]{display:flex;align-items:center;gap:8px;min-width:0;padding:7px 10px;border:1.5px solid #e2e8f0;border-radius:9px;font-size:12.5px;color:#475569;cursor:pointer;transition:all .15s}.mcp-item[data-v-dcf87e76]:hover{border-color:#c7d2fe;background:#f8fafc}.mcp-item.on[data-v-dcf87e76]{border-color:#6366f1;background:#eef2ff;color:#4338ca}.ed-footer[data-v-dcf87e76]{display:flex;align-items:center;justify-content:space-between;gap:12px;padding-top:14px;border-top:1px solid #eef2f7}@media(max-width:860px){.type-row[data-v-dcf87e76]{grid-template-columns:repeat(2,1fr)}.slot-row[data-v-dcf87e76]{flex-direction:column;align-items:stretch}.slot-arrow[data-v-dcf87e76]{display:none}}"; |
|||
|
|||
const agentsStyles_CKxmVBlz = [ |
|||
agents_vue_vue_type_style_index_0_scoped_dcf87e76_lang |
|||
]; |
|||
|
|||
export { agentsStyles_CKxmVBlz as default }; |
|||
//# sourceMappingURL=agents-styles.CKxmVBlz.mjs.map
|
|||
@ -1 +0,0 @@ |
|||
{"version":3,"file":"agents-styles.CKxmVBlz.mjs","sources":["../../../../node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/agents-styles-1.mjs-C8pM4_Q2.js","../../../../node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/agents-styles.CKxmVBlz.mjs"],"names":["style_0"],"mappings":"","x_google_ignoreList":[0,1]} |
|||
@ -1,118 +0,0 @@ |
|||
import { defineComponent, ref, reactive, computed, useSSRContext } from 'vue'; |
|||
import { ssrRenderAttrs, ssrRenderStyle, ssrIncludeBooleanAttr, ssrLooseContain, ssrLooseEqual, ssrRenderList, ssrRenderAttr, ssrInterpolate } from 'vue/server-renderer'; |
|||
import { u as useApi } from './useApi-BNSkSrat.mjs'; |
|||
import { u as useToast } from './useToast-MBvLaNjH.mjs'; |
|||
import { r as regionLabel } from './regions-D1dSykUW.mjs'; |
|||
import './server.mjs'; |
|||
import '../nitro/nitro.mjs'; |
|||
import 'node:http'; |
|||
import 'node:https'; |
|||
import 'node:events'; |
|||
import 'node:buffer'; |
|||
import 'node:fs'; |
|||
import 'node:path'; |
|||
import 'node:crypto'; |
|||
import 'node:url'; |
|||
import '../routes/renderer.mjs'; |
|||
import 'vue-bundle-renderer/runtime'; |
|||
import 'unhead/server'; |
|||
import 'devalue'; |
|||
import 'unhead/utils'; |
|||
import 'pinia'; |
|||
import 'perfect-debounce'; |
|||
|
|||
const _sfc_main = /* @__PURE__ */ defineComponent({ |
|||
__name: "appconfig", |
|||
__ssrInlineRender: true, |
|||
setup(__props) { |
|||
useApi(); |
|||
useToast(); |
|||
const view = ref("list"); |
|||
const apps = ref([]); |
|||
const envs = ref([]); |
|||
const curAppName = ref(""); |
|||
const curApp = ref(0); |
|||
const items = ref([]); |
|||
const loading = ref(false); |
|||
const submitting = ref(false); |
|||
const isEditing = ref(false); |
|||
const keyword = ref(""); |
|||
const form = reactive({ id: 0, group: "", key: "", value: "", description: "" }); |
|||
const appNames = computed( |
|||
() => [...new Set(apps.value.map((a) => a.app_name || a.name).filter(Boolean))].sort() |
|||
); |
|||
const appDeployments = computed( |
|||
() => apps.value.filter((a) => (a.app_name || a.name) === curAppName.value) |
|||
); |
|||
function deployLabel(d) { |
|||
const e = envs.value.find((x) => x.id === d.env_id); |
|||
const envName = e ? e.name || e.code : d.env_id ? `环境#${d.env_id}` : "未关联环境"; |
|||
const suffix = d.status === "pending" ? "(待部署)" : ""; |
|||
return d.region ? `${envName} · ${regionLabel(d.region)}${suffix}` : `${envName}${suffix}`; |
|||
} |
|||
const curAppLabel = computed(() => { |
|||
const a = apps.value.find((x) => x.id === curApp.value); |
|||
return a ? `${a.app_name || a.name} · ${deployLabel(a)}` : ""; |
|||
}); |
|||
const filteredRows = computed(() => { |
|||
const kw = keyword.value.trim().toLowerCase(); |
|||
if (!kw) return items.value; |
|||
return items.value.filter((c) => ((c.group || "") + (c.key || "")).toLowerCase().includes(kw)); |
|||
}); |
|||
const groupedRows = computed(() => { |
|||
const groups = {}; |
|||
filteredRows.value.forEach((c) => { |
|||
const g = c.group || ""; |
|||
(groups[g] = groups[g] || []).push(c); |
|||
}); |
|||
const names = Object.keys(groups).sort((a, b) => { |
|||
if (a === "") return -1; |
|||
if (b === "") return 1; |
|||
return a < b ? -1 : 1; |
|||
}); |
|||
return names.map((g) => ({ key: g, label: g || "未分组", items: groups[g] })); |
|||
}); |
|||
return (_ctx, _push, _parent, _attrs) => { |
|||
_push(`<div${ssrRenderAttrs(_attrs)}><div style="${ssrRenderStyle(view.value === "list" ? null : { display: "none" })}"><div class="flex items-center justify-between mb-5"><div><h2 class="text-lg font-semibold text-slate-800">应用环境配置</h2><p class="text-xs text-slate-400 mt-1">应用自有的 key/value 配置(音乐、OSS 等),直接读写所选应用的业务库。结构同「全局环境配置」但不分区域。</p></div><button class="btn btn-primary btn-sm text-white"${ssrIncludeBooleanAttr(!curApp.value) ? " disabled" : ""}>+ 新增配置</button></div><div class="flex items-center gap-3 mb-4 flex-wrap"><span class="text-sm text-slate-500">应用</span><select class="select select-bordered select-sm min-w-40"><option value="" disabled${ssrIncludeBooleanAttr(Array.isArray(curAppName.value) ? ssrLooseContain(curAppName.value, "") : ssrLooseEqual(curAppName.value, "")) ? " selected" : ""}>请选择应用</option><!--[-->`); |
|||
ssrRenderList(appNames.value, (n) => { |
|||
_push(`<option${ssrRenderAttr("value", n)}${ssrIncludeBooleanAttr(Array.isArray(curAppName.value) ? ssrLooseContain(curAppName.value, n) : ssrLooseEqual(curAppName.value, n)) ? " selected" : ""}>${ssrInterpolate(n)}</option>`); |
|||
}); |
|||
_push(`<!--]--></select><span class="text-sm text-slate-500">部署环境</span><select class="select select-bordered select-sm min-w-48"${ssrIncludeBooleanAttr(!curAppName.value) ? " disabled" : ""}><option${ssrRenderAttr("value", 0)} disabled${ssrIncludeBooleanAttr(Array.isArray(curApp.value) ? ssrLooseContain(curApp.value, 0) : ssrLooseEqual(curApp.value, 0)) ? " selected" : ""}>请选择环境</option><!--[-->`); |
|||
ssrRenderList(appDeployments.value, (d) => { |
|||
_push(`<option${ssrRenderAttr("value", d.id)}${ssrIncludeBooleanAttr(Array.isArray(curApp.value) ? ssrLooseContain(curApp.value, d.id) : ssrLooseEqual(curApp.value, d.id)) ? " selected" : ""}>${ssrInterpolate(deployLabel(d))}</option>`); |
|||
}); |
|||
_push(`<!--]--></select><input${ssrRenderAttr("value", keyword.value)} class="input input-bordered input-sm w-48" placeholder="按分组/键搜索"></div>`); |
|||
if (!curApp.value) { |
|||
_push(`<div class="bg-white rounded-xl shadow-sm border border-slate-100 text-center text-slate-400 py-16"><div class="text-4xl mb-2">🗂️</div><p class="text-sm">${ssrInterpolate(curAppName.value ? "该应用还没有部署环境,请先在「应用中心」为它部署一个环境" : "请先在上方选择应用和部署环境")}</p></div>`); |
|||
} else { |
|||
_push(`<div class="bg-white rounded-xl shadow-sm border border-slate-100"><div class="overflow-x-auto"><table class="table"><thead><tr><th>键</th><th>值</th><th>描述</th><th class="text-right">操作</th></tr></thead><tbody>`); |
|||
if (loading.value) { |
|||
_push(`<tr><td colspan="4" class="text-center py-8"><span class="loading loading-spinner loading-sm"></span></td></tr>`); |
|||
} else if (!filteredRows.value.length) { |
|||
_push(`<tr><td colspan="4" class="text-center text-slate-400 py-8">暂无配置</td></tr>`); |
|||
} else { |
|||
_push(`<!---->`); |
|||
} |
|||
_push(`<!--[-->`); |
|||
ssrRenderList(groupedRows.value, (grp) => { |
|||
_push(`<!--[--><tr class="bg-slate-100/80"><td colspan="4" class="py-2"><span class="font-semibold text-slate-600 text-sm">▸ ${ssrInterpolate(grp.label)}</span><span class="text-xs text-slate-400 ml-2">${ssrInterpolate(grp.items.length)} 项</span></td></tr><!--[-->`); |
|||
ssrRenderList(grp.items, (c) => { |
|||
_push(`<tr class="hover"><td class="font-mono text-sm font-medium">${ssrInterpolate(c.key || "")}</td><td class="text-sm text-slate-500 max-w-xs truncate"${ssrRenderAttr("title", c.value || "")}>${ssrInterpolate(c.value || "")}</td><td class="text-sm text-slate-400">${ssrInterpolate(c.description || "")}</td><td class="text-right"><div class="inline-flex gap-1"><button class="btn btn-ghost btn-xs">编辑</button><button class="btn btn-ghost btn-xs text-red-500">删除</button></div></td></tr>`); |
|||
}); |
|||
_push(`<!--]--><!--]-->`); |
|||
}); |
|||
_push(`<!--]--></tbody></table></div></div>`); |
|||
} |
|||
_push(`</div><div style="${ssrRenderStyle(view.value === "form" ? null : { display: "none" })}"><div class="flex items-center gap-3 mb-5"><button class="btn btn-ghost btn-sm">← 返回列表</button><h2 class="text-lg font-semibold text-slate-800">${ssrInterpolate(isEditing.value ? "编辑配置" : "新增配置")}</h2><span class="text-xs text-slate-400">配置目标:${ssrInterpolate(curAppLabel.value)}</span></div><div class="bg-white rounded-xl shadow-sm border border-slate-100 p-6 max-w-2xl"><form><div class="form-control mb-4"><label class="label"><span class="label-text font-medium">分组 (group)</span></label><input${ssrRenderAttr("value", form.group)} type="text" class="input input-bordered w-full" placeholder="如 music / oss / other"></div><div class="form-control mb-4"><label class="label"><span class="label-text font-medium">键 (key) *</span></label><input${ssrRenderAttr("value", form.key)} type="text" class="input input-bordered w-full" required placeholder="如 oss_access_key"></div><div class="form-control mb-4"><label class="label"><span class="label-text font-medium">值 (value)</span></label><textarea class="textarea textarea-bordered w-full font-mono text-sm" rows="3">${ssrInterpolate(form.value)}</textarea></div><div class="form-control mb-6"><label class="label"><span class="label-text font-medium">描述</span></label><input${ssrRenderAttr("value", form.description)} type="text" class="input input-bordered w-full"></div><div class="flex gap-3"><button type="button" class="btn btn-ghost">取消</button><button type="submit" class="btn btn-primary text-white"${ssrIncludeBooleanAttr(submitting.value) ? " disabled" : ""}>保存</button></div></form></div></div></div>`); |
|||
}; |
|||
} |
|||
}); |
|||
const _sfc_setup = _sfc_main.setup; |
|||
_sfc_main.setup = (props, ctx) => { |
|||
const ssrContext = useSSRContext(); |
|||
(ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("pages/appconfig.vue"); |
|||
return _sfc_setup ? _sfc_setup(props, ctx) : void 0; |
|||
}; |
|||
|
|||
export { _sfc_main as default }; |
|||
//# sourceMappingURL=appconfig-Dq0Q9K6-.mjs.map
|
|||
@ -1 +0,0 @@ |
|||
{"version":3,"file":"appconfig-Dq0Q9K6-.mjs","sources":["../../../../node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/appconfig-Dq0Q9K6-.js"],"names":[],"mappings":"","x_google_ignoreList":[0]} |
|||
@ -1,39 +0,0 @@ |
|||
import { mergeProps, useSSRContext } from 'vue'; |
|||
import { ssrRenderAttrs, ssrRenderSlot } from 'vue/server-renderer'; |
|||
import { _ as _export_sfc } from './server.mjs'; |
|||
import '../nitro/nitro.mjs'; |
|||
import 'node:http'; |
|||
import 'node:https'; |
|||
import 'node:events'; |
|||
import 'node:buffer'; |
|||
import 'node:fs'; |
|||
import 'node:path'; |
|||
import 'node:crypto'; |
|||
import 'node:url'; |
|||
import '../routes/renderer.mjs'; |
|||
import 'vue-bundle-renderer/runtime'; |
|||
import 'unhead/server'; |
|||
import 'devalue'; |
|||
import 'unhead/utils'; |
|||
import 'pinia'; |
|||
import 'perfect-debounce'; |
|||
|
|||
const _sfc_main = {}; |
|||
function _sfc_ssrRender(_ctx, _push, _parent, _attrs) { |
|||
_push(`<div${ssrRenderAttrs(mergeProps({ |
|||
class: "min-h-screen", |
|||
"data-theme": "corporate" |
|||
}, _attrs))}>`);
|
|||
ssrRenderSlot(_ctx.$slots, "default", {}, null, _push, _parent); |
|||
_push(`</div>`); |
|||
} |
|||
const _sfc_setup = _sfc_main.setup; |
|||
_sfc_main.setup = (props, ctx) => { |
|||
const ssrContext = useSSRContext(); |
|||
(ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("layouts/auth.vue"); |
|||
return _sfc_setup ? _sfc_setup(props, ctx) : void 0; |
|||
}; |
|||
const auth = /* @__PURE__ */ _export_sfc(_sfc_main, [["ssrRender", _sfc_ssrRender]]); |
|||
|
|||
export { auth as default }; |
|||
//# sourceMappingURL=auth-DqemnCNa.mjs.map
|
|||
@ -1 +0,0 @@ |
|||
{"version":3,"file":"auth-DqemnCNa.mjs","sources":["../../../../node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/auth-DqemnCNa.js"],"names":[],"mappings":"","x_google_ignoreList":[0]} |
|||
@ -1,266 +0,0 @@ |
|||
import { defineComponent, ref, reactive, computed, useSSRContext } from 'vue'; |
|||
import { ssrRenderAttrs, ssrIncludeBooleanAttr, ssrLooseContain, ssrLooseEqual, ssrRenderList, ssrRenderAttr, ssrInterpolate, ssrRenderStyle, ssrRenderComponent, ssrRenderClass } from 'vue/server-renderer'; |
|||
import { u as useApi } from './useApi-BNSkSrat.mjs'; |
|||
import { u as useToast } from './useToast-MBvLaNjH.mjs'; |
|||
import { l as langName } from './useLangOptions-CXXbv5NM.mjs'; |
|||
import { _ as __nuxt_component_0 } from './LangSelect-Bvw-e1Cn.mjs'; |
|||
import { _ as _export_sfc } from './server.mjs'; |
|||
import '../nitro/nitro.mjs'; |
|||
import 'node:http'; |
|||
import 'node:https'; |
|||
import 'node:events'; |
|||
import 'node:buffer'; |
|||
import 'node:fs'; |
|||
import 'node:path'; |
|||
import 'node:crypto'; |
|||
import 'node:url'; |
|||
import '../routes/renderer.mjs'; |
|||
import 'vue-bundle-renderer/runtime'; |
|||
import 'unhead/server'; |
|||
import 'devalue'; |
|||
import 'unhead/utils'; |
|||
import 'pinia'; |
|||
import 'perfect-debounce'; |
|||
|
|||
const LANG_ANY = "*"; |
|||
const _sfc_main = /* @__PURE__ */ defineComponent({ |
|||
__name: "calltranslate", |
|||
__ssrInlineRender: true, |
|||
setup(__props) { |
|||
const REGIONS = [ |
|||
{ value: 1, label: "中国" }, |
|||
{ value: 2, label: "美国" }, |
|||
{ value: 3, label: "东亚" }, |
|||
{ value: 4, label: "东南亚" }, |
|||
{ value: 5, label: "南亚" }, |
|||
{ value: 6, label: "中东" }, |
|||
{ value: 7, label: "欧洲" }, |
|||
{ value: 8, label: "俄罗斯" }, |
|||
{ value: 9, label: "非洲" }, |
|||
{ value: 10, label: "南美" }, |
|||
{ value: 11, label: "北美" }, |
|||
{ value: 12, label: "大洋洲" }, |
|||
{ value: 13, label: "巴西" }, |
|||
{ value: 14, label: "印度" } |
|||
]; |
|||
function regionLabel(v) { |
|||
return REGIONS.find((x) => x.value === v)?.label ?? "区域" + v; |
|||
} |
|||
const TRANS_TYPES = { |
|||
translate: { label: "🧩 三段式翻译", color: "#059669", bg: "#dcfce7" }, |
|||
"ast-translate": { label: "🚀 端到端翻译", color: "#c2410c", bg: "#fff7ed" } |
|||
}; |
|||
function typeLabel(t) { |
|||
return t && TRANS_TYPES[t] ? TRANS_TYPES[t].label : t || "未知"; |
|||
} |
|||
function typeStyle(t) { |
|||
const s = t ? TRANS_TYPES[t] : void 0; |
|||
return s ? { background: s.bg, color: s.color } : { background: "#f1f5f9", color: "#64748b" }; |
|||
} |
|||
useApi(); |
|||
useToast(); |
|||
const scopeApp = ref(""); |
|||
const scopeApps = ref([]); |
|||
const curRegion = ref(REGIONS[0].value); |
|||
const rules = ref([]); |
|||
const agents = ref([]); |
|||
const editorOpen = ref(false); |
|||
const editing = ref(null); |
|||
ref(null); |
|||
ref(0); |
|||
const ed = reactive({ |
|||
name: "", |
|||
srcLangs: "", |
|||
dstLangs: "", |
|||
srcAny: false, |
|||
dstAny: false, |
|||
bidir: true, |
|||
region: 0, |
|||
priority: 100, |
|||
agentId: "", |
|||
remark: "", |
|||
enable: true |
|||
}); |
|||
const transAgents = computed(() => agents.value.filter((a) => a.type in TRANS_TYPES)); |
|||
const agentGroups = computed( |
|||
() => Object.keys(TRANS_TYPES).map((t) => ({ |
|||
type: t, |
|||
label: TRANS_TYPES[t].label, |
|||
items: transAgents.value.filter((a) => a.type === t) |
|||
})).filter((g) => g.items.length) |
|||
); |
|||
const curAgent = computed(() => agents.value.find((a) => a.id === ed.agentId) || null); |
|||
const langWarn = computed(() => { |
|||
const a = curAgent.value; |
|||
if (!a || !a.support_langs) return ""; |
|||
const sup = a.support_langs.split(",").map((x) => x.trim()).filter(Boolean); |
|||
if (!sup.length) return ""; |
|||
const picked = [ |
|||
...ed.srcAny ? [] : ed.srcLangs.split(","), |
|||
...ed.dstAny ? [] : ed.dstLangs.split(",") |
|||
].map((x) => x.trim()).filter(Boolean); |
|||
const miss = picked.filter((c) => !sup.includes(c)); |
|||
if (!miss.length) return ""; |
|||
return `Agent「${a.name || a.id}」未声明支持:${miss.join("、")}`; |
|||
}); |
|||
function isAny(s) { |
|||
return (s || "").trim() === LANG_ANY; |
|||
} |
|||
function langsLabel(s) { |
|||
if (isAny(s)) return "任意语言"; |
|||
const arr = (s || "").split(",").map((x) => x.trim()).filter(Boolean); |
|||
if (!arr.length) return "—"; |
|||
if (arr.length <= 3) return arr.map((c) => langName(c)).join("、"); |
|||
return arr.slice(0, 3).map((c) => langName(c)).join("、") + ` 等 ${arr.length} 种`; |
|||
} |
|||
function agentName(id) { |
|||
return agents.value.find((a) => a.id === id)?.name || id || "未配置"; |
|||
} |
|||
function agentType(id) { |
|||
return agents.value.find((a) => a.id === id)?.type || ""; |
|||
} |
|||
const syncOpen = ref(false); |
|||
const syncDesc = ref(""); |
|||
const syncTargets = ref([]); |
|||
const syncRegions = computed(() => REGIONS.filter((r) => r.value !== ed.region)); |
|||
const testOpen = ref(false); |
|||
const testSrc = ref("zh-CN"); |
|||
const testDst = ref("en-US"); |
|||
const testResult = ref(null); |
|||
return (_ctx, _push, _parent, _attrs) => { |
|||
_push(`<div${ssrRenderAttrs(_attrs)} data-v-0fc4ec7d><div class="flex items-center justify-between mb-5 flex-wrap gap-3" data-v-0fc4ec7d><div data-v-0fc4ec7d><h2 class="text-lg font-semibold text-slate-800" data-v-0fc4ec7d>通话翻译规则</h2><p class="text-xs text-slate-400 mt-1" data-v-0fc4ec7d> 一条规则覆盖「多源语言 × 多目标语言」,命中后走它指定的 Agent。多条规则按优先级从高到低匹配,第一条命中的生效。 </p></div><div class="flex items-center gap-3 flex-wrap" data-v-0fc4ec7d><span class="text-sm text-slate-500" data-v-0fc4ec7d>作用域</span><select class="select select-bordered select-sm" data-v-0fc4ec7d><option value="" data-v-0fc4ec7d${ssrIncludeBooleanAttr(Array.isArray(scopeApp.value) ? ssrLooseContain(scopeApp.value, "") : ssrLooseEqual(scopeApp.value, "")) ? " selected" : ""}>全局默认</option><!--[-->`); |
|||
ssrRenderList(scopeApps.value, (a) => { |
|||
_push(`<option${ssrRenderAttr("value", a)} data-v-0fc4ec7d${ssrIncludeBooleanAttr(Array.isArray(scopeApp.value) ? ssrLooseContain(scopeApp.value, a) : ssrLooseEqual(scopeApp.value, a)) ? " selected" : ""}>${ssrInterpolate(a)}</option>`); |
|||
}); |
|||
_push(`<!--]--></select><span class="text-sm text-slate-500" data-v-0fc4ec7d>区域</span><select class="select select-bordered select-sm" data-v-0fc4ec7d><!--[-->`); |
|||
ssrRenderList(REGIONS, (r) => { |
|||
_push(`<option${ssrRenderAttr("value", r.value)} data-v-0fc4ec7d${ssrIncludeBooleanAttr(Array.isArray(curRegion.value) ? ssrLooseContain(curRegion.value, r.value) : ssrLooseEqual(curRegion.value, r.value)) ? " selected" : ""}>${ssrInterpolate(r.label)}</option>`); |
|||
}); |
|||
_push(`<!--]--></select><button class="btn btn-ghost btn-sm" data-v-0fc4ec7d>🔍 选路试算</button><button class="btn btn-primary btn-sm text-white" data-v-0fc4ec7d>+ 新增规则</button></div></div><div class="editor-panel" style="${ssrRenderStyle(editorOpen.value ? null : { display: "none" })}" data-v-0fc4ec7d><div class="flex items-center justify-between mb-5" data-v-0fc4ec7d><div class="flex items-center gap-3" data-v-0fc4ec7d><h3 class="font-semibold text-slate-800 text-sm" data-v-0fc4ec7d>${ssrInterpolate(editing.value ? "编辑规则" : "新增规则")}</h3><span class="region-chip" data-v-0fc4ec7d>${ssrInterpolate(scopeApp.value || "全局默认")}</span></div><button class="btn btn-ghost btn-xs" data-v-0fc4ec7d>✕ 关闭</button></div><section class="ed-section" data-v-0fc4ec7d><div class="ed-section-title" data-v-0fc4ec7d>匹配条件</div><div class="lang-row" data-v-0fc4ec7d><div class="lang-field" data-v-0fc4ec7d><div class="flex items-center justify-between" data-v-0fc4ec7d><span class="ed-label" data-v-0fc4ec7d>源语言</span><label class="any-toggle" data-v-0fc4ec7d><input type="checkbox" class="checkbox checkbox-xs checkbox-primary"${ssrIncludeBooleanAttr(ed.srcAny) ? " checked" : ""} data-v-0fc4ec7d> 任意语言 </label></div>`); |
|||
if (ed.srcAny) { |
|||
_push(`<div class="any-box" data-v-0fc4ec7d>任意源语言</div>`); |
|||
} else { |
|||
_push(ssrRenderComponent(__nuxt_component_0, { |
|||
modelValue: ed.srcLangs, |
|||
"onUpdate:modelValue": ($event) => ed.srcLangs = $event, |
|||
multiple: "" |
|||
}, null, _parent)); |
|||
} |
|||
_push(`</div><div class="dir-col" data-v-0fc4ec7d><button type="button" class="${ssrRenderClass([{ on: ed.bidir }, "dir-btn"])}"${ssrRenderAttr("title", ed.bidir ? "点击改为单向" : "点击改为双向(反向也走这条规则)")} data-v-0fc4ec7d>${ssrInterpolate(ed.bidir ? "⇄" : "→")}</button><span class="dir-tip" data-v-0fc4ec7d>${ssrInterpolate(ed.bidir ? "双向互译" : "单向翻译")}</span></div><div class="lang-field" data-v-0fc4ec7d><div class="flex items-center justify-between" data-v-0fc4ec7d><span class="ed-label" data-v-0fc4ec7d>目标语言</span><label class="any-toggle" data-v-0fc4ec7d><input type="checkbox" class="checkbox checkbox-xs checkbox-primary"${ssrIncludeBooleanAttr(ed.dstAny) ? " checked" : ""} data-v-0fc4ec7d> 任意语言 </label></div>`); |
|||
if (ed.dstAny) { |
|||
_push(`<div class="any-box" data-v-0fc4ec7d>任意目标语言</div>`); |
|||
} else { |
|||
_push(ssrRenderComponent(__nuxt_component_0, { |
|||
modelValue: ed.dstLangs, |
|||
"onUpdate:modelValue": ($event) => ed.dstLangs = $event, |
|||
multiple: "" |
|||
}, null, _parent)); |
|||
} |
|||
_push(`</div></div><div class="grid grid-cols-3 gap-3 mt-3" data-v-0fc4ec7d><div data-v-0fc4ec7d><span class="ed-label" data-v-0fc4ec7d>生效区域</span><select class="select select-bordered select-sm w-full" data-v-0fc4ec7d><option${ssrRenderAttr("value", 0)} data-v-0fc4ec7d${ssrIncludeBooleanAttr(Array.isArray(ed.region) ? ssrLooseContain(ed.region, 0) : ssrLooseEqual(ed.region, 0)) ? " selected" : ""}>全部区域(兜底)</option><!--[-->`); |
|||
ssrRenderList(REGIONS, (r) => { |
|||
_push(`<option${ssrRenderAttr("value", r.value)} data-v-0fc4ec7d${ssrIncludeBooleanAttr(Array.isArray(ed.region) ? ssrLooseContain(ed.region, r.value) : ssrLooseEqual(ed.region, r.value)) ? " selected" : ""}>${ssrInterpolate(r.label)}</option>`); |
|||
}); |
|||
_push(`<!--]--></select></div><div data-v-0fc4ec7d><span class="ed-label" data-v-0fc4ec7d>优先级(越大越先匹配)</span><input${ssrRenderAttr("value", ed.priority)} type="number" class="input input-bordered input-sm w-full" data-v-0fc4ec7d></div><div data-v-0fc4ec7d><span class="ed-label" data-v-0fc4ec7d>规则名(便于识别)</span><input${ssrRenderAttr("value", ed.name)} class="input input-bordered input-sm w-full" placeholder="如 中日韩端到端" data-v-0fc4ec7d></div></div></section><section class="ed-section" data-v-0fc4ec7d><div class="ed-section-title" data-v-0fc4ec7d>命中后使用的 Agent</div><div class="grid grid-cols-2 gap-3" data-v-0fc4ec7d><div data-v-0fc4ec7d><span class="ed-label" data-v-0fc4ec7d>翻译 Agent <i class="req" data-v-0fc4ec7d>*</i></span><select class="select select-bordered select-sm w-full" data-v-0fc4ec7d><option value="" disabled data-v-0fc4ec7d${ssrIncludeBooleanAttr(Array.isArray(ed.agentId) ? ssrLooseContain(ed.agentId, "") : ssrLooseEqual(ed.agentId, "")) ? " selected" : ""}>${ssrInterpolate(transAgents.value.length ? "请选择 Agent" : "(无可用 Agent,请先去 Agent 配置里创建)")}</option><!--[-->`); |
|||
ssrRenderList(agentGroups.value, (g) => { |
|||
_push(`<optgroup${ssrRenderAttr("label", g.label)} data-v-0fc4ec7d><!--[-->`); |
|||
ssrRenderList(g.items, (a) => { |
|||
_push(`<option${ssrRenderAttr("value", a.id)} data-v-0fc4ec7d${ssrIncludeBooleanAttr(Array.isArray(ed.agentId) ? ssrLooseContain(ed.agentId, a.id) : ssrLooseEqual(ed.agentId, a.id)) ? " selected" : ""}>${ssrInterpolate(a.name || a.id)}</option>`); |
|||
}); |
|||
_push(`<!--]--></optgroup>`); |
|||
}); |
|||
_push(`<!--]--></select></div><div data-v-0fc4ec7d><span class="ed-label" data-v-0fc4ec7d>备注</span><input${ssrRenderAttr("value", ed.remark)} class="input input-bordered input-sm w-full" placeholder="可留空" data-v-0fc4ec7d></div></div>`); |
|||
if (curAgent.value) { |
|||
_push(`<div class="agent-preview" data-v-0fc4ec7d><span class="type-badge" style="${ssrRenderStyle(typeStyle(curAgent.value.type))}" data-v-0fc4ec7d>${ssrInterpolate(typeLabel(curAgent.value.type))}</span><span class="text-xs text-slate-500" data-v-0fc4ec7d>${ssrInterpolate(curAgent.value.description || "(无描述)")}</span>`); |
|||
if (curAgent.value.support_langs) { |
|||
_push(`<span class="text-[11px] text-slate-400" data-v-0fc4ec7d>支持:${ssrInterpolate(curAgent.value.support_langs)}</span>`); |
|||
} else { |
|||
_push(`<!---->`); |
|||
} |
|||
if (!curAgent.value.enable) { |
|||
_push(`<span class="text-[11px] text-amber-600" data-v-0fc4ec7d>⚠ 该 Agent 当前为停用状态</span>`); |
|||
} else { |
|||
_push(`<!---->`); |
|||
} |
|||
_push(`</div>`); |
|||
} else { |
|||
_push(`<!---->`); |
|||
} |
|||
if (langWarn.value) { |
|||
_push(`<p class="ed-warn" data-v-0fc4ec7d>⚠ ${ssrInterpolate(langWarn.value)}</p>`); |
|||
} else { |
|||
_push(`<!---->`); |
|||
} |
|||
_push(`</section><div class="ed-footer" data-v-0fc4ec7d><label class="flex items-center gap-2 text-sm cursor-pointer" data-v-0fc4ec7d><input${ssrIncludeBooleanAttr(Array.isArray(ed.enable) ? ssrLooseContain(ed.enable, null) : ed.enable) ? " checked" : ""} type="checkbox" class="checkbox checkbox-sm checkbox-primary" data-v-0fc4ec7d><span data-v-0fc4ec7d>启用</span><span class="text-xs text-slate-400" data-v-0fc4ec7d>停用的规则不参与选路</span></label><div class="flex gap-2" data-v-0fc4ec7d><button class="btn btn-ghost btn-sm" data-v-0fc4ec7d>取消</button><button class="btn btn-outline btn-sm" data-v-0fc4ec7d>保存并同步…</button><button class="btn btn-primary btn-sm text-white" data-v-0fc4ec7d>保存</button></div></div></div>`); |
|||
if (!rules.value.length) { |
|||
_push(`<div class="text-center py-20 text-slate-300" data-v-0fc4ec7d><div class="text-5xl mb-3" data-v-0fc4ec7d>🌐</div><p class="text-sm" data-v-0fc4ec7d>当前区域还没有翻译规则</p><p class="text-xs mt-1" data-v-0fc4ec7d>建议先加一条「任意 → 任意」的兜底规则,再往上叠精确规则</p></div>`); |
|||
} else { |
|||
_push(`<div class="rule-list" data-v-0fc4ec7d><div class="rule-head" data-v-0fc4ec7d><span data-v-0fc4ec7d>优先级</span><span data-v-0fc4ec7d>匹配条件</span><span data-v-0fc4ec7d>Agent</span><span data-v-0fc4ec7d>区域</span><span class="text-right" data-v-0fc4ec7d>操作</span></div><!--[-->`); |
|||
ssrRenderList(rules.value, (r, i) => { |
|||
_push(`<div class="${ssrRenderClass([{ off: !r.enable }, "rule-row"])}" data-v-0fc4ec7d><div class="prio-cell" data-v-0fc4ec7d><span class="prio" data-v-0fc4ec7d>${ssrInterpolate(r.priority)}</span><span class="order" data-v-0fc4ec7d>#${ssrInterpolate(i + 1)}</span></div><div class="cond-cell" data-v-0fc4ec7d><div class="flex items-center gap-2 flex-wrap" data-v-0fc4ec7d><span class="${ssrRenderClass([{ any: isAny(r.src_langs) }, "lang-badge"])}" data-v-0fc4ec7d>${ssrInterpolate(langsLabel(r.src_langs))}</span><span class="text-slate-400 font-bold" data-v-0fc4ec7d>${ssrInterpolate(r.bidir ? "⇄" : "→")}</span><span class="${ssrRenderClass([{ any: isAny(r.dst_langs) }, "lang-badge"])}" data-v-0fc4ec7d>${ssrInterpolate(langsLabel(r.dst_langs))}</span></div>`); |
|||
if (r.name || r.remark) { |
|||
_push(`<div class="text-[11px] text-slate-400 mt-1" data-v-0fc4ec7d>${ssrInterpolate(r.name)}`); |
|||
if (r.remark) { |
|||
_push(`<span data-v-0fc4ec7d> · ${ssrInterpolate(r.remark)}</span>`); |
|||
} else { |
|||
_push(`<!---->`); |
|||
} |
|||
_push(`</div>`); |
|||
} else { |
|||
_push(`<!---->`); |
|||
} |
|||
_push(`</div><div class="agent-cell" data-v-0fc4ec7d><span class="type-badge" style="${ssrRenderStyle(typeStyle(agentType(r.agent_id)))}" data-v-0fc4ec7d>${ssrInterpolate(typeLabel(agentType(r.agent_id)))}</span><span class="text-xs text-slate-700" data-v-0fc4ec7d>${ssrInterpolate(agentName(r.agent_id))}</span></div><div class="text-xs text-slate-500" data-v-0fc4ec7d>${ssrInterpolate(r.region === 0 ? "全部区域" : regionLabel(r.region))}</div><div class="text-right" data-v-0fc4ec7d>`); |
|||
if (r.enable) { |
|||
_push(`<span class="badge badge-success badge-xs mr-2" data-v-0fc4ec7d>启用</span>`); |
|||
} else { |
|||
_push(`<span class="badge badge-ghost badge-xs mr-2" data-v-0fc4ec7d>停用</span>`); |
|||
} |
|||
_push(`<button class="btn btn-ghost btn-xs text-error" data-v-0fc4ec7d>删除</button></div></div>`); |
|||
}); |
|||
_push(`<!--]--></div>`); |
|||
} |
|||
_push(`<div class="ct-overlay" style="${ssrRenderStyle(testOpen.value ? null : { display: "none" })}" data-v-0fc4ec7d><div class="ct-box" data-v-0fc4ec7d><h3 class="text-base font-semibold text-slate-800 mb-1" data-v-0fc4ec7d>选路试算</h3><p class="text-xs text-slate-400 mb-4" data-v-0fc4ec7d>用后端运行时同一套匹配逻辑,算一遍这个方向实际会走哪条规则。</p><div class="grid grid-cols-2 gap-3" data-v-0fc4ec7d><div data-v-0fc4ec7d><span class="ed-label" data-v-0fc4ec7d>源语言</span>`); |
|||
_push(ssrRenderComponent(__nuxt_component_0, { |
|||
modelValue: testSrc.value, |
|||
"onUpdate:modelValue": ($event) => testSrc.value = $event |
|||
}, null, _parent)); |
|||
_push(`</div><div data-v-0fc4ec7d><span class="ed-label" data-v-0fc4ec7d>目标语言</span>`); |
|||
_push(ssrRenderComponent(__nuxt_component_0, { |
|||
modelValue: testDst.value, |
|||
"onUpdate:modelValue": ($event) => testDst.value = $event |
|||
}, null, _parent)); |
|||
_push(`</div></div>`); |
|||
if (testResult.value) { |
|||
_push(`<div class="${ssrRenderClass([{ miss: !testResult.value.matched }, "test-result"])}" data-v-0fc4ec7d>`); |
|||
if (testResult.value.matched) { |
|||
_push(`<!--[--><div class="text-sm font-semibold text-slate-800 mb-1" data-v-0fc4ec7d> 命中规则:${ssrInterpolate(testResult.value.rule?.name || "#" + testResult.value.rule?.id)}(优先级 ${ssrInterpolate(testResult.value.rule?.priority)}) </div><div class="text-xs text-slate-600" data-v-0fc4ec7d>${ssrInterpolate(langsLabel(testResult.value.rule?.src_langs))} ${ssrInterpolate(testResult.value.rule?.bidir ? "⇄" : "→")} ${ssrInterpolate(langsLabel(testResult.value.rule?.dst_langs))} · Agent:${ssrInterpolate(testResult.value.agent?.name || testResult.value.rule?.agent_id)} `); |
|||
if (testResult.value.agent) { |
|||
_push(`<span data-v-0fc4ec7d>(${ssrInterpolate(typeLabel(testResult.value.agent.type))})</span>`); |
|||
} else { |
|||
_push(`<!---->`); |
|||
} |
|||
_push(`</div><!--]-->`); |
|||
} else { |
|||
_push(`<div class="text-sm text-amber-700" data-v-0fc4ec7d>没有任何规则命中 —— 这个方向的通话翻译会不可用,建议补一条兜底规则。</div>`); |
|||
} |
|||
_push(`</div>`); |
|||
} else { |
|||
_push(`<!---->`); |
|||
} |
|||
_push(`<div class="flex gap-3 justify-end mt-5" data-v-0fc4ec7d><button class="btn btn-ghost" data-v-0fc4ec7d>关闭</button><button class="btn btn-primary text-white" data-v-0fc4ec7d>试算</button></div></div></div><div class="ct-overlay" style="${ssrRenderStyle(syncOpen.value ? null : { display: "none" })}" data-v-0fc4ec7d><div class="ct-box" data-v-0fc4ec7d><h3 class="text-base font-semibold text-slate-800 mb-1" data-v-0fc4ec7d>同步到其他区域</h3><p class="text-xs text-slate-400 mb-3" data-v-0fc4ec7d>${ssrInterpolate(syncDesc.value)}</p><div class="text-xs px-3 py-2 rounded-lg mb-3" style="${ssrRenderStyle({ "background": "#f0fdf4", "border": "1px solid #bbf7d0", "color": "#15803d" })}" data-v-0fc4ec7d> ✦ 同步内容:语言条件、Agent、优先级、启停状态一并复制到目标区域。 </div><div class="flex items-center justify-between mb-1" data-v-0fc4ec7d><span class="text-xs font-semibold text-slate-500" data-v-0fc4ec7d>选择目标区域</span><div class="flex gap-2" data-v-0fc4ec7d><button class="btn btn-ghost btn-xs" data-v-0fc4ec7d>全选</button><button class="btn btn-ghost btn-xs" data-v-0fc4ec7d>清空</button></div></div><div class="sync-region-grid" data-v-0fc4ec7d><!--[-->`); |
|||
ssrRenderList(syncRegions.value, (r) => { |
|||
_push(`<label class="${ssrRenderClass([{ checked: syncTargets.value.includes(r.value) }, "sync-region-item"])}" data-v-0fc4ec7d><input type="checkbox" class="checkbox checkbox-xs checkbox-primary"${ssrIncludeBooleanAttr(syncTargets.value.includes(r.value)) ? " checked" : ""} data-v-0fc4ec7d><span data-v-0fc4ec7d>${ssrInterpolate(r.label)}</span></label>`); |
|||
}); |
|||
_push(`<!--]--></div><p class="text-[11px] text-slate-400 mb-5" data-v-0fc4ec7d>⚠ 目标区域已有「同 Agent + 同语言条件」的规则则覆盖,否则新建。</p><div class="flex gap-3 justify-end" data-v-0fc4ec7d><button class="btn btn-ghost" data-v-0fc4ec7d>取消</button><button class="btn btn-primary text-white"${ssrIncludeBooleanAttr(!syncTargets.value.length) ? " disabled" : ""} data-v-0fc4ec7d> 保存并同步${ssrInterpolate(syncTargets.value.length ? "(" + syncTargets.value.length + " 个区域)" : "")}</button></div></div></div></div>`); |
|||
}; |
|||
} |
|||
}); |
|||
const _sfc_setup = _sfc_main.setup; |
|||
_sfc_main.setup = (props, ctx) => { |
|||
const ssrContext = useSSRContext(); |
|||
(ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("pages/calltranslate.vue"); |
|||
return _sfc_setup ? _sfc_setup(props, ctx) : void 0; |
|||
}; |
|||
const calltranslate = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-0fc4ec7d"]]); |
|||
|
|||
export { calltranslate as default }; |
|||
//# sourceMappingURL=calltranslate-Typ2E2m-.mjs.map
|
|||
@ -1 +0,0 @@ |
|||
{"version":3,"file":"calltranslate-Typ2E2m-.mjs","sources":["../../../../node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/calltranslate-Typ2E2m-.js"],"names":[],"mappings":"","x_google_ignoreList":[0]} |
|||
@ -1,8 +0,0 @@ |
|||
const calltranslate_vue_vue_type_style_index_0_scoped_0fc4ec7d_lang = ".rule-list[data-v-0fc4ec7d]{background:#fff;border:1px solid #eef2f7;border-radius:14px;overflow:hidden}.rule-head[data-v-0fc4ec7d],.rule-row[data-v-0fc4ec7d]{display:grid;grid-template-columns:92px 1fr 220px 92px 160px;gap:12px;align-items:center;padding:11px 16px}.rule-head[data-v-0fc4ec7d]{font-size:11px;font-weight:700;color:#94a3b8;background:#f8fafc;border-bottom:1px solid #eef2f7}.rule-row[data-v-0fc4ec7d]{border-bottom:1px solid #f6f8fb;cursor:pointer;transition:background .15s}.rule-row[data-v-0fc4ec7d]:last-child{border-bottom:none}.rule-row[data-v-0fc4ec7d]:hover{background:#f8fafc}.rule-row.off[data-v-0fc4ec7d]{opacity:.55}.prio-cell[data-v-0fc4ec7d]{display:flex;align-items:baseline;gap:6px}.prio[data-v-0fc4ec7d]{font-size:15px;font-weight:800;color:#4338ca}.order[data-v-0fc4ec7d]{font-size:10px;color:#cbd5e1}.cond-cell[data-v-0fc4ec7d]{min-width:0}.agent-cell[data-v-0fc4ec7d]{display:flex;align-items:center;gap:6px;min-width:0}.lang-badge[data-v-0fc4ec7d]{font-size:12px;font-weight:700;padding:3px 10px;border-radius:8px;background:#eef2ff;color:#4338ca}.lang-badge.any[data-v-0fc4ec7d]{background:#f1f5f9;color:#64748b;font-style:italic}.type-badge[data-v-0fc4ec7d]{font-size:10px;font-weight:700;padding:2px 7px;border-radius:5px;white-space:nowrap}.editor-panel[data-v-0fc4ec7d]{background:#fff;border-radius:16px;border:1px solid #c7d2fe;box-shadow:0 8px 32px #6366f11a;padding:22px;margin-bottom:16px}.region-chip[data-v-0fc4ec7d]{font-size:11px;font-weight:600;padding:2px 9px;border-radius:6px;background:#eef2ff;color:#4338ca}.ed-section[data-v-0fc4ec7d]{padding:14px 0;border-top:1px dashed #eef2f7}.ed-section[data-v-0fc4ec7d]:first-of-type{padding-top:0;border-top:none}.ed-section-title[data-v-0fc4ec7d]{font-size:11px;font-weight:700;letter-spacing:.04em;color:#94a3b8;margin-bottom:10px}.ed-label[data-v-0fc4ec7d]{display:block;font-size:11px;color:#64748b;margin-bottom:4px}.ed-warn[data-v-0fc4ec7d]{font-size:11px;color:#b45309;margin-top:8px}.req[data-v-0fc4ec7d]{color:#dc2626;font-style:normal}.any-toggle[data-v-0fc4ec7d]{gap:5px;font-size:11px;cursor:pointer}.any-box[data-v-0fc4ec7d],.any-toggle[data-v-0fc4ec7d]{display:flex;align-items:center;color:#64748b}.any-box[data-v-0fc4ec7d]{height:34px;padding:0 12px;border-radius:8px;border:1.5px dashed #cbd5e1;background:#f8fafc;font-size:12px;font-style:italic}.lang-row[data-v-0fc4ec7d]{display:grid;grid-template-columns:1fr 92px 1fr;align-items:start;gap:12px}.lang-field[data-v-0fc4ec7d]{min-width:0}.dir-col[data-v-0fc4ec7d]{display:flex;flex-direction:column;align-items:center;gap:4px;padding-top:22px}.dir-btn[data-v-0fc4ec7d]{width:46px;height:32px;border-radius:9px;border:1.5px solid #e2e8f0;background:#f8fafc;color:#64748b;font-size:17px;line-height:1;cursor:pointer;transition:all .15s}.dir-btn[data-v-0fc4ec7d]:hover{border-color:#c7d2fe;background:#f5f3ff;color:#4338ca}.dir-btn.on[data-v-0fc4ec7d]{border-color:#6366f1;background:#eef2ff;color:#4338ca}.dir-tip[data-v-0fc4ec7d]{font-size:10px;color:#94a3b8;white-space:nowrap}.agent-preview[data-v-0fc4ec7d]{gap:8px;margin-top:10px;padding:8px 12px;border-radius:9px;background:#f8fafc;border:1px solid #eef2f7}.agent-preview[data-v-0fc4ec7d],.ed-footer[data-v-0fc4ec7d]{display:flex;align-items:center;flex-wrap:wrap}.ed-footer[data-v-0fc4ec7d]{justify-content:space-between;gap:12px;padding-top:14px;border-top:1px solid #eef2f7}.ct-overlay[data-v-0fc4ec7d]{position:fixed;inset:0;background:#0f172a73;z-index:100;display:flex;align-items:center;justify-content:center;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);padding:24px}.ct-box[data-v-0fc4ec7d]{background:#fff;border-radius:20px;padding:28px;width:560px;max-width:95vw;box-shadow:0 24px 80px #0000002e}.sync-region-grid[data-v-0fc4ec7d]{display:grid;grid-template-columns:repeat(4,1fr);gap:8px;margin:14px 0}.sync-region-item[data-v-0fc4ec7d]{display:flex;align-items:center;gap:7px;padding:8px 10px;border-radius:9px;border:1.5px solid #e2e8f0;cursor:pointer;transition:all .15s;font-size:13px;font-weight:500;color:#475569}.sync-region-item[data-v-0fc4ec7d]:hover{border-color:#c7d2fe;background:#f5f3ff}.sync-region-item.checked[data-v-0fc4ec7d]{border-color:#6366f1;background:#eef2ff;color:#4338ca}.test-result[data-v-0fc4ec7d]{margin-top:14px;padding:12px 14px;border-radius:10px;background:#eef2ff;border:1px solid #c7d2fe}.test-result.miss[data-v-0fc4ec7d]{background:#fffbeb;border-color:#fde68a}@media(max-width:1000px){.rule-head[data-v-0fc4ec7d],.rule-row[data-v-0fc4ec7d]{grid-template-columns:70px 1fr 150px}.rule-head[data-v-0fc4ec7d]>:nth-child(4),.rule-row[data-v-0fc4ec7d]>:nth-child(4){display:none}}@media(max-width:860px){.lang-row[data-v-0fc4ec7d]{grid-template-columns:1fr}.dir-col[data-v-0fc4ec7d]{flex-direction:row;padding-top:0}}"; |
|||
|
|||
const calltranslateStyles_DejCdNUq = [ |
|||
calltranslate_vue_vue_type_style_index_0_scoped_0fc4ec7d_lang |
|||
]; |
|||
|
|||
export { calltranslateStyles_DejCdNUq as default }; |
|||
//# sourceMappingURL=calltranslate-styles.DejCdNUq.mjs.map
|
|||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue