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
Rodger-Wang 1 month ago
parent
commit
2f81aaef93
  1. 12
      .gitignore
  2. 15
      apps/admin/.output/nitro.json
  3. 15
      apps/admin/.output/public/_nuxt/0CGOegeu.js
  4. 1
      apps/admin/.output/public/_nuxt/32XpWsQL.js
  5. 4
      apps/admin/.output/public/_nuxt/6O01ZZML.js
  6. 1
      apps/admin/.output/public/_nuxt/7m3DvxFn.js
  7. 1
      apps/admin/.output/public/_nuxt/AeilnnXP.js
  8. 1
      apps/admin/.output/public/_nuxt/B-G7qD0T.js
  9. 1
      apps/admin/.output/public/_nuxt/BCmMvQNl.js
  10. 1
      apps/admin/.output/public/_nuxt/BIYq6SKh.js
  11. 1
      apps/admin/.output/public/_nuxt/BNW9rRgN.js
  12. 1
      apps/admin/.output/public/_nuxt/BSXoR6Yx.js
  13. 1
      apps/admin/.output/public/_nuxt/BZR1IKC1.js
  14. 1
      apps/admin/.output/public/_nuxt/BgasD__e.js
  15. 1
      apps/admin/.output/public/_nuxt/BqBJfKQo.js
  16. 1
      apps/admin/.output/public/_nuxt/BrJ9pewm.js
  17. 1
      apps/admin/.output/public/_nuxt/BvvkbLjV.js
  18. 1
      apps/admin/.output/public/_nuxt/C8kc9IUa.js
  19. 4
      apps/admin/.output/public/_nuxt/CAhwHUW5.js
  20. 1
      apps/admin/.output/public/_nuxt/CDB8L8go.js
  21. 1
      apps/admin/.output/public/_nuxt/CEFq2Pq9.js
  22. 1
      apps/admin/.output/public/_nuxt/CPoAe5lL.js
  23. 2
      apps/admin/.output/public/_nuxt/CS9TbzfM.js
  24. 1
      apps/admin/.output/public/_nuxt/CasIUDzx.js
  25. 1
      apps/admin/.output/public/_nuxt/CkLfApYf.js
  26. 1
      apps/admin/.output/public/_nuxt/DC2vBYza.js
  27. 1
      apps/admin/.output/public/_nuxt/DD3V9C6_.js
  28. 1
      apps/admin/.output/public/_nuxt/DDe4k6KN.js
  29. 2
      apps/admin/.output/public/_nuxt/DPKLCcBs.js
  30. 1
      apps/admin/.output/public/_nuxt/DQ6zmqs4.js
  31. 29
      apps/admin/.output/public/_nuxt/DRVBzPRY.js
  32. 1
      apps/admin/.output/public/_nuxt/DT3lD2sm.js
  33. 1
      apps/admin/.output/public/_nuxt/DTVoyhwb.js
  34. 1
      apps/admin/.output/public/_nuxt/DZfr_EfO.js
  35. 1
      apps/admin/.output/public/_nuxt/Dehik56a.js
  36. 1
      apps/admin/.output/public/_nuxt/DlMn1R4f.js
  37. 1
      apps/admin/.output/public/_nuxt/LangSelect.Dkm6e8RK.css
  38. 1
      apps/admin/.output/public/_nuxt/PN667bHc.js
  39. 1
      apps/admin/.output/public/_nuxt/VxS1tujf.js
  40. 1
      apps/admin/.output/public/_nuxt/_name_.Dk1VjRtn.css
  41. 1
      apps/admin/.output/public/_nuxt/_yKEhqk3.js
  42. 1
      apps/admin/.output/public/_nuxt/accounts.B-g1r2A7.css
  43. 1
      apps/admin/.output/public/_nuxt/agents.DyZqnyeq.css
  44. 1
      apps/admin/.output/public/_nuxt/builds/latest.json
  45. 1
      apps/admin/.output/public/_nuxt/builds/meta/15e7ab28-16d6-4f4e-8edd-c6a8122f81cf.json
  46. 1
      apps/admin/.output/public/_nuxt/calltranslate.blzoinPN.css
  47. 1
      apps/admin/.output/public/_nuxt/channels.DbnY_8Am.css
  48. 1
      apps/admin/.output/public/_nuxt/dashboard.CuNO2Lt5.css
  49. 1
      apps/admin/.output/public/_nuxt/default.miyQHb0v.css
  50. 1
      apps/admin/.output/public/_nuxt/entry.B1mQ-Tl2.css
  51. 1
      apps/admin/.output/public/_nuxt/error-404.Dm-MYrAh.css
  52. 1
      apps/admin/.output/public/_nuxt/error-500.DM8oqBl3.css
  53. 1
      apps/admin/.output/public/_nuxt/index.B6hNDrw5.css
  54. 1
      apps/admin/.output/public/_nuxt/index.dJfvJhMb.css
  55. 1
      apps/admin/.output/public/_nuxt/meetingsvc.DgYSEQUA.css
  56. 1
      apps/admin/.output/public/_nuxt/meettemplates.DBfDdqB2.css
  57. 1
      apps/admin/.output/public/_nuxt/oWVa2rll.js
  58. 1
      apps/admin/.output/public/_nuxt/q-Oqovwl.js
  59. 1
      apps/admin/.output/public/_nuxt/serviceconfig.UIJazB1z.css
  60. 1
      apps/admin/.output/public/_nuxt/statlog.DNW5XZ2N.css
  61. 1
      apps/admin/.output/public/_nuxt/svcinspect.H9TdRqZ5.css
  62. 1
      apps/admin/.output/public/_nuxt/systemconfig.MaL8_AEr.css
  63. 1
      apps/admin/.output/public/_nuxt/xsgK-Nup.js
  64. 19
      apps/admin/.output/server/chunks/_/error-500.mjs
  65. 1
      apps/admin/.output/server/chunks/_/error-500.mjs.map
  66. 38
      apps/admin/.output/server/chunks/build/AccountCredentialDialog-D37zgaXm.mjs
  67. 1
      apps/admin/.output/server/chunks/build/AccountCredentialDialog-D37zgaXm.mjs.map
  68. 8
      apps/admin/.output/server/chunks/build/AppDeployTab-styles.4FdVYf2u.mjs
  69. 1
      apps/admin/.output/server/chunks/build/AppDeployTab-styles.4FdVYf2u.mjs.map
  70. 8
      apps/admin/.output/server/chunks/build/AppModuleTab-styles._m-oVrlE.mjs
  71. 1
      apps/admin/.output/server/chunks/build/AppModuleTab-styles._m-oVrlE.mjs.map
  72. 69
      apps/admin/.output/server/chunks/build/LangSelect-Bvw-e1Cn.mjs
  73. 1
      apps/admin/.output/server/chunks/build/LangSelect-Bvw-e1Cn.mjs.map
  74. 8
      apps/admin/.output/server/chunks/build/LangSelect-styles.Bi81RebM.mjs
  75. 1
      apps/admin/.output/server/chunks/build/LangSelect-styles.Bi81RebM.mjs.map
  76. 8
      apps/admin/.output/server/chunks/build/SvcAlertBanner-styles.C9CJuYwV.mjs
  77. 1
      apps/admin/.output/server/chunks/build/SvcAlertBanner-styles.C9CJuYwV.mjs.map
  78. 537
      apps/admin/.output/server/chunks/build/_name_-CJXf25S4.mjs
  79. 1
      apps/admin/.output/server/chunks/build/_name_-CJXf25S4.mjs.map
  80. 4
      apps/admin/.output/server/chunks/build/_name_-styles-1.mjs-BmcUDjex.mjs
  81. 1
      apps/admin/.output/server/chunks/build/_name_-styles-1.mjs-BmcUDjex.mjs.map
  82. 4
      apps/admin/.output/server/chunks/build/_name_-styles-2.mjs-BXCS7H7R.mjs
  83. 1
      apps/admin/.output/server/chunks/build/_name_-styles-2.mjs-BXCS7H7R.mjs.map
  84. 13
      apps/admin/.output/server/chunks/build/_name_-styles.CveqLyYu.mjs
  85. 1
      apps/admin/.output/server/chunks/build/_name_-styles.CveqLyYu.mjs.map
  86. 222
      apps/admin/.output/server/chunks/build/accounts-CM5YEJ4p.mjs
  87. 1
      apps/admin/.output/server/chunks/build/accounts-CM5YEJ4p.mjs.map
  88. 8
      apps/admin/.output/server/chunks/build/accounts-styles.Bwl6sYRz.mjs
  89. 1
      apps/admin/.output/server/chunks/build/accounts-styles.Bwl6sYRz.mjs.map
  90. 310
      apps/admin/.output/server/chunks/build/agents-Bh_gLb1p.mjs
  91. 1
      apps/admin/.output/server/chunks/build/agents-Bh_gLb1p.mjs.map
  92. 8
      apps/admin/.output/server/chunks/build/agents-styles.CKxmVBlz.mjs
  93. 1
      apps/admin/.output/server/chunks/build/agents-styles.CKxmVBlz.mjs.map
  94. 118
      apps/admin/.output/server/chunks/build/appconfig-Dq0Q9K6-.mjs
  95. 1
      apps/admin/.output/server/chunks/build/appconfig-Dq0Q9K6-.mjs.map
  96. 39
      apps/admin/.output/server/chunks/build/auth-DqemnCNa.mjs
  97. 1
      apps/admin/.output/server/chunks/build/auth-DqemnCNa.mjs.map
  98. 266
      apps/admin/.output/server/chunks/build/calltranslate-Typ2E2m-.mjs
  99. 1
      apps/admin/.output/server/chunks/build/calltranslate-Typ2E2m-.mjs.map
  100. 8
      apps/admin/.output/server/chunks/build/calltranslate-styles.DejCdNUq.mjs

12
.gitignore

@ -40,3 +40,15 @@ apps/services/console
apps/services/mcp
apps/services/migu
apps/services/timer
# macOS
.DS_Store
# 构建产物与依赖目录
# 2026-08-29 从版本管理中移出:此前 apps/admin/.output 与 apps/admin/node_modules/.cache
# 被误纳入跟踪,每次 nuxt build 都会产生数百个哈希文件的增删,把真实代码 diff 淹没。
# 部署不依赖仓库里这份产物——apps/admin/Dockerfile 是 COPY . . 后 RUN pnpm build 重新构建,
# 且 .dockerignore 已排除 node_modules/.nuxt/.output。
node_modules/
.output/
.nuxt/

15
apps/admin/.output/nitro.json

@ -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": {}
}

15
apps/admin/.output/public/_nuxt/0CGOegeu.js

File diff suppressed because one or more lines are too long

1
apps/admin/.output/public/_nuxt/32XpWsQL.js

File diff suppressed because one or more lines are too long

4
apps/admin/.output/public/_nuxt/6O01ZZML.js

File diff suppressed because one or more lines are too long

1
apps/admin/.output/public/_nuxt/7m3DvxFn.js

@ -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};

1
apps/admin/.output/public/_nuxt/AeilnnXP.js

File diff suppressed because one or more lines are too long

1
apps/admin/.output/public/_nuxt/B-G7qD0T.js

File diff suppressed because one or more lines are too long

1
apps/admin/.output/public/_nuxt/BCmMvQNl.js

File diff suppressed because one or more lines are too long

1
apps/admin/.output/public/_nuxt/BIYq6SKh.js

@ -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};

1
apps/admin/.output/public/_nuxt/BNW9rRgN.js

File diff suppressed because one or more lines are too long

1
apps/admin/.output/public/_nuxt/BSXoR6Yx.js

File diff suppressed because one or more lines are too long

1
apps/admin/.output/public/_nuxt/BZR1IKC1.js

File diff suppressed because one or more lines are too long

1
apps/admin/.output/public/_nuxt/BgasD__e.js

@ -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};

1
apps/admin/.output/public/_nuxt/BqBJfKQo.js

File diff suppressed because one or more lines are too long

1
apps/admin/.output/public/_nuxt/BrJ9pewm.js

@ -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
apps/admin/.output/public/_nuxt/BvvkbLjV.js

@ -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};

1
apps/admin/.output/public/_nuxt/C8kc9IUa.js

File diff suppressed because one or more lines are too long

4
apps/admin/.output/public/_nuxt/CAhwHUW5.js

@ -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};

1
apps/admin/.output/public/_nuxt/CDB8L8go.js

File diff suppressed because one or more lines are too long

1
apps/admin/.output/public/_nuxt/CEFq2Pq9.js

File diff suppressed because one or more lines are too long

1
apps/admin/.output/public/_nuxt/CPoAe5lL.js

File diff suppressed because one or more lines are too long

2
apps/admin/.output/public/_nuxt/CS9TbzfM.js

File diff suppressed because one or more lines are too long

1
apps/admin/.output/public/_nuxt/CasIUDzx.js

File diff suppressed because one or more lines are too long

1
apps/admin/.output/public/_nuxt/CkLfApYf.js

@ -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};

1
apps/admin/.output/public/_nuxt/DC2vBYza.js

File diff suppressed because one or more lines are too long

1
apps/admin/.output/public/_nuxt/DD3V9C6_.js

@ -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
apps/admin/.output/public/_nuxt/DDe4k6KN.js

@ -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};

2
apps/admin/.output/public/_nuxt/DPKLCcBs.js

@ -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 _};

1
apps/admin/.output/public/_nuxt/DQ6zmqs4.js

File diff suppressed because one or more lines are too long

29
apps/admin/.output/public/_nuxt/DRVBzPRY.js

File diff suppressed because one or more lines are too long

1
apps/admin/.output/public/_nuxt/DT3lD2sm.js

File diff suppressed because one or more lines are too long

1
apps/admin/.output/public/_nuxt/DTVoyhwb.js

File diff suppressed because one or more lines are too long

1
apps/admin/.output/public/_nuxt/DZfr_EfO.js

File diff suppressed because one or more lines are too long

1
apps/admin/.output/public/_nuxt/Dehik56a.js

File diff suppressed because one or more lines are too long

1
apps/admin/.output/public/_nuxt/DlMn1R4f.js

File diff suppressed because one or more lines are too long

1
apps/admin/.output/public/_nuxt/LangSelect.Dkm6e8RK.css

@ -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
apps/admin/.output/public/_nuxt/PN667bHc.js

@ -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};

1
apps/admin/.output/public/_nuxt/VxS1tujf.js

File diff suppressed because one or more lines are too long

1
apps/admin/.output/public/_nuxt/_name_.Dk1VjRtn.css

File diff suppressed because one or more lines are too long

1
apps/admin/.output/public/_nuxt/_yKEhqk3.js

@ -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
apps/admin/.output/public/_nuxt/accounts.B-g1r2A7.css

@ -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
apps/admin/.output/public/_nuxt/agents.DyZqnyeq.css

@ -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
apps/admin/.output/public/_nuxt/builds/latest.json

@ -1 +0,0 @@
{"id":"15e7ab28-16d6-4f4e-8edd-c6a8122f81cf","timestamp":1786784834591}

1
apps/admin/.output/public/_nuxt/builds/meta/15e7ab28-16d6-4f4e-8edd-c6a8122f81cf.json

@ -1 +0,0 @@
{"id":"15e7ab28-16d6-4f4e-8edd-c6a8122f81cf","timestamp":1786784834591,"prerendered":[]}

1
apps/admin/.output/public/_nuxt/calltranslate.blzoinPN.css

@ -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
apps/admin/.output/public/_nuxt/channels.DbnY_8Am.css

@ -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)}}

1
apps/admin/.output/public/_nuxt/dashboard.CuNO2Lt5.css

File diff suppressed because one or more lines are too long

1
apps/admin/.output/public/_nuxt/default.miyQHb0v.css

@ -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}

1
apps/admin/.output/public/_nuxt/entry.B1mQ-Tl2.css

File diff suppressed because one or more lines are too long

1
apps/admin/.output/public/_nuxt/error-404.Dm-MYrAh.css

@ -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
apps/admin/.output/public/_nuxt/error-500.DM8oqBl3.css

@ -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
apps/admin/.output/public/_nuxt/index.B6hNDrw5.css

@ -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
apps/admin/.output/public/_nuxt/index.dJfvJhMb.css

@ -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}

1
apps/admin/.output/public/_nuxt/meetingsvc.DgYSEQUA.css

File diff suppressed because one or more lines are too long

1
apps/admin/.output/public/_nuxt/meettemplates.DBfDdqB2.css

@ -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
apps/admin/.output/public/_nuxt/oWVa2rll.js

@ -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};

1
apps/admin/.output/public/_nuxt/q-Oqovwl.js

File diff suppressed because one or more lines are too long

1
apps/admin/.output/public/_nuxt/serviceconfig.UIJazB1z.css

File diff suppressed because one or more lines are too long

1
apps/admin/.output/public/_nuxt/statlog.DNW5XZ2N.css

@ -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
apps/admin/.output/public/_nuxt/svcinspect.H9TdRqZ5.css

@ -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
apps/admin/.output/public/_nuxt/systemconfig.MaL8_AEr.css

@ -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
apps/admin/.output/public/_nuxt/xsgK-Nup.js

@ -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};

19
apps/admin/.output/server/chunks/_/error-500.mjs

@ -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
apps/admin/.output/server/chunks/_/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]}

38
apps/admin/.output/server/chunks/build/AccountCredentialDialog-D37zgaXm.mjs

@ -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
apps/admin/.output/server/chunks/build/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]}

8
apps/admin/.output/server/chunks/build/AppDeployTab-styles.4FdVYf2u.mjs

@ -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
apps/admin/.output/server/chunks/build/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]}

8
apps/admin/.output/server/chunks/build/AppModuleTab-styles._m-oVrlE.mjs

@ -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
apps/admin/.output/server/chunks/build/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]}

69
apps/admin/.output/server/chunks/build/LangSelect-Bvw-e1Cn.mjs

@ -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
apps/admin/.output/server/chunks/build/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]}

8
apps/admin/.output/server/chunks/build/LangSelect-styles.Bi81RebM.mjs

@ -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
apps/admin/.output/server/chunks/build/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]}

8
apps/admin/.output/server/chunks/build/SvcAlertBanner-styles.C9CJuYwV.mjs

@ -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
apps/admin/.output/server/chunks/build/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]}

537
apps/admin/.output/server/chunks/build/_name_-CJXf25S4.mjs

@ -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 &amp; 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&amp;parseTime=True&amp;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
apps/admin/.output/server/chunks/build/_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]}

4
apps/admin/.output/server/chunks/build/_name_-styles-1.mjs-BmcUDjex.mjs

@ -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
apps/admin/.output/server/chunks/build/_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]}

4
apps/admin/.output/server/chunks/build/_name_-styles-2.mjs-BXCS7H7R.mjs

@ -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
apps/admin/.output/server/chunks/build/_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]}

13
apps/admin/.output/server/chunks/build/_name_-styles.CveqLyYu.mjs

@ -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
apps/admin/.output/server/chunks/build/_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]}

222
apps/admin/.output/server/chunks/build/accounts-CM5YEJ4p.mjs

@ -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
apps/admin/.output/server/chunks/build/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]}

8
apps/admin/.output/server/chunks/build/accounts-styles.Bwl6sYRz.mjs

@ -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
apps/admin/.output/server/chunks/build/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]}

310
apps/admin/.output/server/chunks/build/agents-Bh_gLb1p.mjs

@ -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
apps/admin/.output/server/chunks/build/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]}

8
apps/admin/.output/server/chunks/build/agents-styles.CKxmVBlz.mjs

@ -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
apps/admin/.output/server/chunks/build/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]}

118
apps/admin/.output/server/chunks/build/appconfig-Dq0Q9K6-.mjs

@ -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
apps/admin/.output/server/chunks/build/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]}

39
apps/admin/.output/server/chunks/build/auth-DqemnCNa.mjs

@ -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
apps/admin/.output/server/chunks/build/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]}

266
apps/admin/.output/server/chunks/build/calltranslate-Typ2E2m-.mjs

@ -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
apps/admin/.output/server/chunks/build/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]}

8
apps/admin/.output/server/chunks/build/calltranslate-styles.DejCdNUq.mjs

@ -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…
Cancel
Save