Files
Nexus/web/app/assets/SettingsPage-DOiv3Gx0.js
T

4 lines
30 KiB
JavaScript
Raw Normal View History

import{$n as e,A as t,F as n,Ft as r,L as i,Lr as a,M as o,N as s,P as c,Vr as l,Y as ee,Z as u,Zn as d,ar as f,er as p,gr as m,j as h,jr as g,k as te,mr as ne,nr as _,or as v,rr as y,sr as b,t as x,tr as S,vr as C,w as re,wr as w,z as T,zt as E}from"./index-AmyXDl4i.js";import{o as ie,t as ae}from"./VContainer-Dqw80qLq.js";import{t as D}from"./VChip-D3vZhJU3.js";import{n as O,t as oe}from"./VRow-BOFF76XF.js";import{t as k}from"./VSpacer-e_QpSKFJ.js";import{i as A,n as se,r as j,t as ce}from"./validation-DMwOxx4a.js";import{t as M}from"./VDialog-hWg6_Knl.js";import{t as N}from"./VTextarea-CV8U5DbY.js";import{t as P}from"./VSwitch-DsvYP8mQ.js";import{n as le,r as F}from"./useTerminalQuickCommands-DicDOVOw.js";var I={key:1,class:`text-medium-emphasis text-body-2 mb-4`},L={class:`text-caption text-medium-emphasis mr-2`,style:{"min-width":`1.5rem`}},ue={class:`d-flex flex-wrap ga-2`},R=b({__name:`TerminalQuickCommandsSettings`,setup(e){let r=ie(),{commands:b,loading:E,load:ae,create:O,update:oe,remove:A,reorder:se,customCommands:j,builtinCommands:ce}=le(),N=g(!1),P=g(null),R=g(``),z=g(``),B=g(!1),V=g(!1),H=g(!1),de=g(null),fe=g(``);function pe(){P.value=null,R.value=``,z.value=``,N.value=!0}function me(e){P.value=e.id,R.value=e.name,z.value=e.cmd.replace(/\r$/,``),N.value=!0}async function he(){if(!R.value.trim()||!z.value.trim()){r(`名称和命令不能为空`,`warning`);return}let e=z.value.trim();e.endsWith(`\r`)||(e+=`\r`),B.value=!0;try{P.value?await oe(P.value,R.value,e):await O(R.value,e),N.value=!1,r(`已保存`)}catch(e){r(e instanceof Error?e.message:`保存失败`,`error`)}finally{B.value=!1}}function ge(e){de.value=e.id,fe.value=e.name,H.value=!0}async function _e(){if(de.value){B.value=!0;try{await A(de.value),H.value=!1,r(`已删除`)}catch(e){r(e instanceof Error?e.message:`删除失败`,`error`)}finally{B.value=!1}}}async function ve(e){let t=j();if(e<=0)return;let n=t.map(e=>e.id),r=n[e-1];n[e-1]=n[e],n[e]=r,await be(n)}async function ye(e){let t=j();if(e>=t.length-1)return;let n=t.map(e=>e.id),r=n[e+1];n[e+1]=n[e],n[e]=r,await be(n)}async function be(e){V.value=!0;try{await se(e)}catch(e){r(e instanceof Error?e.message:`排序失败`,`error`)}finally{V.value=!1}}return ne(()=>{ae().catch(e=>r(e.message,`error`))}),(e,r)=>(m(),S(s,{id:`terminal-quick-commands`,elevation:`0`,border:``,rounded:`lg`,class:`mb-4`},{default:w(()=>[v(n,{class:`d-flex align-center flex-wrap ga-2`},{default:w(()=>[v(u,{class:`mr-1`},{default:w(()=>[...r[6]||=[f(`mdi-flash`,-1)]]),_:1}),r[8]||=f(` 终端快捷命令 `,-1),v(k),v(T,{size:`small`,color:`primary`,variant:`flat`,"prepend-icon":`mdi-plus`,onClick:pe},{default:w(()=>[...r[7]||=[f(` 添加命令 `,-1)]]),_:1})]),_:1}),v(o),v(c,null,{default:w(()=>[r[9]||=p(`div`,{class:`text-body-2 text-medium-emphasis mb-4`},` 自定义命令显示在终端栏最前(优先级最高)。终端页仅可点击执行;在此添加、编辑、删除与调整顺序。 `,-1),a(E)?(m(),S(ee,{key:0,indeterminate:``,color:`primary`,class:`mb-3`})):_(``,!0),a(j)().length===0&&!a(E)?(m(),y(`div`,I,` 暂无自定义命令,点击「添加命令」创建。 `)):_(``,!0),a(j)().length?(m(),S(re,{key:2,density:`compact`,class:`mb-4 pa-0`},{default:w(()=>[(m(!0),y(d,null,C(a(j)(),(e,n)=>(m(),S(te,{key:e.id,border:``,rounded:`lg`,class:`mb-2`},{prepend:w(()=>[p(`span`,L,l(n+1),1)]),append:w(()=>[v(T,{icon:`mdi-arrow-up`,size:`x-small`,variant:`text`,disabled:n===0||V.value,onClick:e=>ve(n)},null,8,[`disabled`,`onClick`]),v(T,{icon:`mdi-arrow-down`,size:`x-small`,variant:`text`,disabled:n===a(j)().length-1||V.value,onClick:e=>ye(n)},null,8,[`disabled`,`onClick`]),v(T,{icon:`mdi-pencil`,size:`x-small`,variant:`text`,onClick:t=>me(e)},null,8,[`onClick`]),v(T,{icon:`mdi-delete`,size:`x-small`,variant:`text`,color:`error`,onClick:t=>ge(e)},null,8,[`onClick`])]),default:w(()=>[v(t,null,{default:w(()=>[f(l(e.name),1)]),_:2},1024),v(h,{class:`font-mono text-truncate`},{default:w(()=>[f(l(e.cmd),1)]),_:2},1024)]),_:2},1024))),128))]),_:1})):_(``,!0),r[10]||=p(`div`,{class:`text-subtitle-2 mb-2`},`系统内置
`),Q.value=e.subscription_ips||[],Qe.value=e.last_refresh||null,$e.value=e.total_count??new Set([...e.manual_ips||[],...e.subscription_ips||[]]).size}catch{h(`加载白名单失败`,`error`)}}async function ot(){ue.value=!0;try{let e=Object.entries(F.value).filter(([e])=>[`system_name`,`system_title`,`cpu_alert_threshold`,`mem_alert_threshold`,`disk_alert_threshold`,`db_pool_size`,`db_max_overflow`].includes(e));for(let[t,n]of e)await E.put(`/settings/${t}`,{value:n});h(`设置已保存`)}catch(e){h(e instanceof Error?e.message:`保存失败`,`error`)}finally{ue.value=!1}}async function st(e){let t=I.value.trim(),n=String(F.value.telegram_chat_id||``).trim();return e?.requireToken&&!t&&!L.value?(h(`请先填写 Bot Token`,`error`),!1):e?.requireChatId&&!n?(h(`请先填写或检测 Chat ID`,`error`),!1):(t&&(await E.put(`/settings/telegram_bot_token`,{value:t}),L.value=!0,I.value=``,U.value=!1),n&&await E.put(`/settings/telegram_chat_id`,{value:n}),!0)}async function ct(){Le.value=!0;try{G.value=await E.get(`/settings/ops-patrol/status`)}catch{G.value=null}finally{Le.value=!1}}async function lt(){Re.value=!0;try{if(!await st({requireToken:!0,requireChatId:!0}))return;let e=await E.post(`/settings/ops-patrol/sync-telegram`,{});G.value={...G.value||{},telegram_layer3_ready:e.telegram_layer3_ready,telegram_env_synced:e.env_status.env_synced,env_status:e.env_status,telegram_app_configured:!0},h(`巡检 Telegram 已同步至 .env`),await ct()}catch(e){h(e instanceof Error?e.message:`同步失败`,`error`)}finally{Re.value=!1}}async function ut(){Fe.value=!0;try{let e=I.value.trim(),t=String(F.value.telegram_chat_id||``).trim();if(!e&&!t&&!L.value){h(`请先填写 Bot Token 或 Chat ID`,`warning`);return}await st(),await ct(),h(`Telegram 配置已保存`)}catch(e){h(e instanceof Error?e.message:`保存失败`,`error`)}finally{Fe.value=!1}}async function dt(e,t){let n=W.value[e];W.value[e]=t,Ie.value=e;try{await E.put(`/settings/${e}`,{value:t?`true`:`false`})}catch(t){W.value[e]=n,h(t instanceof Error?t.message:`保存失败,已撤销`,`error`)}finally{Ie.value=null}}async function ft(){je.value=!0;try{if(!await st({requireToken:!0,requireChatId:!0}))return;await E.post(`/settings/telegram/test`),h(`测试消息已发送`)}catch(e){h(e instanceof Error?e.message:`发送失败`,`error`)}finally{je.value=!1}}async function pt(){Me.value=!0;try{if(!await st({requireToken:!0}))return;if(Pe.value=(await E.get(`/settings/telegram/chats`)).chats||[],!Pe.value.length){h(`未检测到对话,请先向 Bot 发送一条消息后再试`,`warning`);return}Ne.value=!0}catch(e){h(e instanceof Error?e.message:`检测失败`,`error`)}finally{Me.value=!1}}async function mt(e){let t=String(e.id);F.value.telegram_chat_id=t,Ne.value=!1;try{await E.put(`/settings/telegram_chat_id`,{value:t}),h(`已选择 Chat ID: ${t}`)}catch(e){h(e instanceof Error?e.message:`保存 Chat ID 失败`,`error`)}}async function ht(){if(K.value.new_pw!==K.value.confirm){h(`两次密码不一致`,`error`);return}Ve.value=!0;try{let e={current_password:K.value.current,new_password:K.value.new_pw};b.admin?.totp_enabled&&K.value.totp_code&&(e.totp_code=K.value.totp_code),await E.put(`/auth/password`,e),K.value={current:``,new_pw:``,confirm:``,totp_code:``},h(`密码已修改`)}catch(e){h(e instanceof Error?e.message:`修改失败`,`error`)}finally{Ve.value=!1}}async function gt(){try{let e=await E.post(`/auth/totp/setup`);q.value=e.qr_code,J.value=e.secret||``}catch(e){h(e instanceof Error?e.message:`生成失败`,`error`)}}async function _t(){Ue.value=!0;try{await E.post(`/auth/totp/enable`,{code:He.value}),await b.fetchProfile(),q.value=``,He.value=``,h(`TOTP 已启用`)}catch(e){h(e.message||`启用失败`,`error`)}finally{Ue.value=!1}}function vt(){Y.value=!0}async function yt(){Ke.value=!0;try{await E.post(`/auth/totp/disable`,{admin_id:b.admin?.id,current_password:We.value,totp_code:Ge.value}),await b.fetchProfile(),Y.value=!1,We.value=``,Ge.value=``,h(`TOTP 已禁用`)}catch(e){h(e.message||`禁用失败`,`error`)}finally{Ke.value=!1}}function bt(){J.value&&(navig
`).map(e=>e.trim()).filter(Boolean),subscription_url:Z.value.trim(),enabled:Xe.value};await E.post(`/settings/ip-allowlist`,e),h(`白名单已保存`),$.value=!1,await at()}catch(e){h(e instanceof Error?e.message:`保存失败`,`error`)}finally{et.value=!1}}return ne(()=>{it(),at(),ct(),b.fetchProfile()}),(e,t)=>(m(),S(ae,{fluid:``,class:`pa-6`},{default:w(()=>[v(oe,null,{default:w(()=>[v(O,{cols:`12`,lg:`6`},{default:w(()=>[v(s,{elevation:`0`,border:``,rounded:`lg`,class:`mb-4`},{default:w(()=>[v(n,{class:`d-flex align-center`},{default:w(()=>[v(u,{class:`mr-2`},{default:w(()=>[...t[26]||=[f(`mdi-cog`,-1)]]),_:1}),t[27]||=f(` 系统设置 `,-1)]),_:1}),le.value?(m(),S(ee,{key:0,indeterminate:``,color:`primary`})):_(``,!0),v(o),v(c,null,{default:w(()=>[v(x,{modelValue:F.value.system_name,"onUpdate:modelValue":t[0]||=e=>F.value.system_name=e,label:`系统名称`,variant:`outlined`,density:`compact`,class:`mb-3`,rules:[a(A)(`系统名称`)]},null,8,[`modelValue`,`rules`]),v(x,{modelValue:F.value.system_title,"onUpdate:modelValue":t[1]||=e=>F.value.system_title=e,label:`系统标题`,variant:`outlined`,density:`compact`,class:`mb-3`,rules:[a(A)(`系统标题`)]},null,8,[`modelValue`,`rules`]),v(o,{class:`my-4`}),t[28]||=p(`div`,{class:`text-subtitle-2 mb-3`},`告警阈值`,-1),v(oe,{dense:``},{default:w(()=>[v(O,{cols:`4`},{default:w(()=>[v(x,{modelValue:F.value.cpu_alert_threshold,"onUpdate:modelValue":t[2]||=e=>F.value.cpu_alert_threshold=e,label:`CPU %`,variant:`outlined`,density:`compact`,type:`number`,rules:[a(A)(`阈值`),a(j)(1,100,`阈值`)]},null,8,[`modelValue`,`rules`])]),_:1}),v(O,{cols:`4`},{default:w(()=>[v(x,{modelValue:F.value.mem_alert_threshold,"onUpdate:modelValue":t[3]||=e=>F.value.mem_alert_threshold=e,label:`内存 %`,variant:`outlined`,density:`compact`,type:`number`,rules:[a(A)(`阈值`),a(j)(1,100,`阈值`)]},null,8,[`modelValue`,`rules`])]),_:1}),v(O,{cols:`4`},{default:w(()=>[v(x,{modelValue:F.value.disk_alert_threshold,"onUpdate:modelValue":t[4]||=e=>F.value.disk_alert_threshold=e,label:`磁盘 %`,variant:`outlined`,density:`compact`,type:`number`,rules:[a(A)(`阈值`),a(j)(1,100,`阈值`)]},null,8,[`modelValue`,`rules`])]),_:1})]),_:1}),v(o,{class:`my-4`}),t[29]||=p(`div`,{class:`text-subtitle-2 mb-3`},`连接池`,-1),v(oe,{dense:``},{default:w(()=>[v(O,{cols:`6`},{default:w(()=>[v(x,{modelValue:F.value.db_pool_size,"onUpdate:modelValue":t[5]||=e=>F.value.db_pool_size=e,label:`连接池大小`,variant:`outlined`,density:`compact`,type:`number`,rules:[a(A)(),a(ce)()]},null,8,[`modelValue`,`rules`])]),_:1}),v(O,{cols:`6`},{default:w(()=>[v(x,{modelValue:F.value.db_max_overflow,"onUpdate:modelValue":t[6]||=e=>F.value.db_max_overflow=e,label:`溢出连接数`,variant:`outlined`,density:`compact`,type:`number`,rules:[a(A)(),a(ce)()]},null,8,[`modelValue`,`rules`])]),_:1})]),_:1})]),_:1}),v(i,{class:`px-4 pb-4`},{default:w(()=>[v(k),v(T,{color:`primary`,variant:`flat`,onClick:ot,loading:ue.value},{default:w(()=>[...t[30]||=[f(`保存设置`,-1)]]),_:1},8,[`loading`])]),_:1})]),_:1}),v(R),v(s,{elevation:`0`,border:``,rounded:`lg`},{default:w(()=>[v(n,{class:`d-flex align-center`},{default:w(()=>[v(u,{class:`mr-2`},{default:w(()=>[...t[31]||=[f(`mdi-send`,-1)]]),_:1}),t[32]||=f(` Telegram 推送 `,-1)]),_:1}),v(o),v(c,null,{default:w(()=>[v(x,{modelValue:I.value,"onUpdate:modelValue":t[7]||=e=>I.value=e,label:`Bot Token`,variant:`outlined`,density:`compact`,class:`mb-3`,placeholder:L.value?`已配置留空保持不变`:`输入 Bot Token`,type:U.value?`text`:`password`,"append-inner-icon":U.value?`mdi-eye-off`:`mdi-eye`,"onClick:appendInner":St},null,8,[`modelValue`,`placeholder`,`type`,`append-inner-icon`]),L.value&&!I.value?(m(),S(D,{key:0,size:`small`,color:`success`,variant:`tonal`,class:`mb-3`},{default:w(()=>[...t[33]||=[f(`Token 已配置`,-1)]]),_:1})):_(``,!0),v(x,{modelValue:F.value.telegram_chat_id,"onUpdate:modelValue":t[8]||=e=>F.value.telegram_chat_id=e,label:`Chat ID`,variant:`outlined`,density:`compact`,class:`mb-3`},null,8,[`modelValue`]),t[41]||=p(`p`,{class:`text-caption text-me
10.0.0.0/24`},null,8,[`modelValue`]),p(`div`,De,` 手动 IP 与订阅节点合并生效 `+l($e.value)+` 去重后)。 `,1)]),_:1})]),_:1})]),_:1})]),_:1}),v(M,{modelValue:$.value,"onUpdate:modelValue":t[19]||=e=>$.value=e,"max-width":`520`},{default:w(()=>[v(s,{border:``},{default:w(()=>[v(n,null,{default:w(()=>[...t[65]||=[f(`订阅解析预览`,-1)]]),_:1}),v(c,null,{default:w(()=>[p(`div`,Oe,[t[66]||=f(`共解析出 `,-1),p(`strong`,null,l(nt.value.length),1),t[67]||=f(` 个节点 IP / 域名`,-1)]),p(`div`,ke,[(m(!0),y(d,null,C(nt.value,e=>(m(),S(D,{key:e,size:`small`,variant:`tonal`,label:``},{default:w(()=>[f(l(e),1)]),_:2},1024))),128))]),t[68]||=p(`div`,{class:`text-caption text-medium-emphasis`},`点击保存白名单后才会写入订阅 URL 并触发后台刷新`,-1)]),_:1}),v(i,null,{default:w(()=>[v(k),v(T,{variant:`text`,onClick:t[17]||=e=>$.value=!1},{default:w(()=>[...t[69]||=[f(`关闭`,-1)]]),_:1}),v(T,{color:`primary`,variant:`flat`,onClick:t[18]||=e=>{$.value=!1,Et()}},{default:w(()=>[...t[70]||=[f(`保存白名单`,-1)]]),_:1})]),_:1})]),_:1})]),_:1},8,[`modelValue`]),v(M,{modelValue:Ne.value,"onUpdate:modelValue":t[21]||=e=>Ne.value=e,"max-width":`480`},{default:w(()=>[v(s,{border:``},{default:w(()=>[v(n,null,{default:w(()=>[...t[71]||=[f(`选择 Chat ID`,-1)]]),_:1}),v(c,null,{default:w(()=>[Pe.value.length?(m(),S(re,{key:1,density:`compact`,lines:`two`},{default:w(()=>[(m(!0),y(d,null,C(Pe.value,e=>(m(),S(te,{key:e.id,title:e.title||e.username||`Chat ${e.id}`,subtitle:`${e.type}${e.username?` · @`+e.username:``} · ID ${e.id}`,onClick:t=>mt(e)},null,8,[`title`,`subtitle`,`onClick`]))),128))]),_:1})):(m(),y(`div`,Ae,` 未检测到对话请先在 Telegram Bot 发送一条消息然后重新检测 `))]),_:1}),v(i,null,{default:w(()=>[v(k),v(T,{variant:`text`,onClick:t[20]||=e=>Ne.value=!1},{default:w(()=>[...t[72]||=[f(`关闭`,-1)]]),_:1})]),_:1})]),_:1})]),_:1},8,[`modelValue`]),v(M,{modelValue:Y.value,"onUpdate:modelValue":t[25]||=e=>Y.value=e,"max-width":`400`},{default:w(()=>[v(s,{border:``},{default:w(()=>[v(n,null,{default:w(()=>[...t[73]||=[f(`禁用 TOTP`,-1)]]),_:1}),v(c,null,{default:w(()=>[v(x,{modelValue:We.value,"onUpdate:modelValue":t[22]||=e=>We.value=e,label:`当前密码`,variant:`outlined`,density:`compact`,type:`password`,class:`mb-2`,rules:[a(A)()]},null,8,[`modelValue`,`rules`]),v(x,{modelValue:Ge.value,"onUpdate:modelValue":t[23]||=e=>Ge.value=e,label:`验证码`,variant:`outlined`,density:`compact`,rules:[a(A)()]},null,8,[`modelValue`,`rules`])]),_:1}),v(i,null,{default:w(()=>[v(k),v(T,{variant:`text`,onClick:t[24]||=e=>Y.value=!1},{default:w(()=>[...t[74]||=[f(`取消`,-1)]]),_:1}),v(T,{color:`error`,variant:`flat`,onClick:yt,loading:Ke.value},{default:w(()=>[...t[75]||=[f(`禁用`,-1)]]),_:1},8,[`loading`])]),_:1})]),_:1})]),_:1},8,[`modelValue`])]),_:1}))}});export{je as default};