4 lines
38 KiB
JavaScript
4 lines
38 KiB
JavaScript
import{_ as e,t}from"./VSelect-BvR-yyLS.js";import{n,t as r}from"./VRow-rmSa_q-C.js";import{$ as i,$t as ee,Ar as a,Dr as o,Dt as s,Er as c,Et as te,L as l,Nr as ne,Or as u,Ot as re,Tr as d,Tt as f,Wr as p,Yr as m,_ as ie,_i as h,b as g,br as ae,g as oe,h as se,in as _,jr as v,kt as y,q as ce,qr as b,ri as x,u as le,ui as S,v as C,wr as w,xi as T,xr as E,y as D}from"./index-CDcgx9V8.js";import{t as O}from"./usePageActivateRefresh-CqHSpagO.js";import{t as ue}from"./useSnackbar-u_XK4ZNm.js";import{i as k,n as A,o as j,t as M}from"./VCard-pmpQR9O7.js";import{t as N}from"./VTextField-B-BnrJAQ.js";import{t as de}from"./VDialog-nKJcjfNL.js";import{n as P,r as F,t as fe}from"./validation-BMzYTJL4.js";import{t as I}from"./VForm-uEqKaHHF.js";import{t as pe}from"./VSwitch-VDVIZTO7.js";import{t as me}from"./VTextarea-PzNEhaMZ.js";import{i as he,r as ge}from"./useTerminalQuickCommands-DKqOac6p.js";var L={key:1,class:`text-medium-emphasis text-body-2 mb-4`},_e={class:`text-caption text-medium-emphasis mr-2`,style:{"min-width":`1.5rem`}},R={class:`d-flex flex-wrap ga-2`},ve=ne({__name:`TerminalQuickCommandsSettings`,setup(e){let t=ue(),{commands:n,loading:r,load:ee,create:s,update:te,remove:ne,reorder:re,customCommands:f,builtinCommands:_}=ge(),y=S(!1),w=S(null),O=S(``),P=S(``),F=S(!1),fe=S(!1),I=S(!1),pe=S(null),me=S(``);function ve(){w.value=null,O.value=``,P.value=``,y.value=!0}function ye(e){w.value=e.id,O.value=e.name,P.value=e.cmd.replace(/\r$/,``),y.value=!0}async function be(){if(!O.value.trim()||!P.value.trim()){t(`名称和命令不能为空`,`warning`);return}let e=P.value.trim();F.value=!0;try{w.value?await te(w.value,O.value,e):await s(O.value,e),y.value=!1,t(`已保存`)}catch(e){t(e instanceof Error?e.message:`保存失败`,`error`)}finally{F.value=!1}}function xe(e){pe.value=e.id,me.value=e.name,I.value=!0}async function Se(){if(pe.value){F.value=!0;try{await ne(pe.value),I.value=!1,t(`已删除`)}catch(e){t(e instanceof Error?e.message:`删除失败`,`error`)}finally{F.value=!1}}}async function Ce(e){let t=f();if(e<=0)return;let n=t.map(e=>e.id),r=n[e-1];n[e-1]=n[e],n[e]=r,await Te(n)}async function we(e){let t=f();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 Te(n)}async function Te(e){fe.value=!0;try{await re(e)}catch(e){t(e instanceof Error?e.message:`排序失败`,`error`)}finally{fe.value=!1}}return p(()=>{ee().catch(e=>t(e.message,`error`))}),(e,t)=>(b(),c(M,{id:`terminal-quick-commands`,elevation:`0`,border:``,rounded:`lg`,class:`mb-4`},{default:x(()=>[v(k,{class:`d-flex align-center flex-wrap ga-2`},{default:x(()=>[v(i,{class:`mr-1`},{default:x(()=>[...t[6]||=[a(`mdi-flash`,-1)]]),_:1}),t[8]||=a(` 终端快捷命令 `,-1),v(C),v(l,{size:`small`,color:`primary`,variant:`flat`,"prepend-icon":`mdi-plus`,onClick:ve},{default:x(()=>[...t[7]||=[a(` 添加命令 `,-1)]]),_:1})]),_:1}),v(D),v(A,null,{default:x(()=>[t[9]||=d(`div`,{class:`text-body-2 text-medium-emphasis mb-4`},` 自定义命令显示在终端栏最前(优先级最高)。终端页仅可点击执行;在此添加、编辑、删除与调整顺序。 `,-1),h(r)?(b(),c(ce,{key:0,indeterminate:``,color:`primary`,class:`mb-3`})):o(``,!0),h(f)().length===0&&!h(r)?(b(),u(`div`,L,` 暂无自定义命令,点击「添加命令」创建。 `)):o(``,!0),h(f)().length?(b(),c(le,{key:2,density:`compact`,class:`mb-4 pa-0`},{default:x(()=>[(b(!0),u(E,null,m(h(f)(),(e,t)=>(b(),c(se,{key:e.id,border:``,rounded:`lg`,class:`mb-2`},{prepend:x(()=>[d(`span`,_e,T(t+1),1)]),append:x(()=>[v(l,{icon:`mdi-arrow-up`,size:`x-small`,variant:`text`,disabled:t===0||fe.value,onClick:ae(e=>Ce(t),[`stop`])},null,8,[`disabled`,`onClick`]),v(l,{icon:`mdi-arrow-down`,size:`x-small`,variant:`text`,disabled:t===h(f)().length-1||fe.value,onClick:ae(e=>we(t),[`stop`])},null,8,[`disabled`,`onClick`]),v(l,{icon:`mdi-pencil`,size:`x-small`,variant:`text`,onClick:ae(t=>ye(e),[`stop`])},null,8,[`onClick`]),v(l,{icon:`mdi-delete`,size:`x-small`,variant:`text`,color:`error`,onClick:ae(t=>xe(e),[`stop`])},null,8,[`onClick`])]),default:x(()=>[v(oe,null,{default:x(()=>[a(T(e.name),1)]),_:2},1024),v(ie,{class:`font-mono text-truncate`},{default:x(()=>[a(T(e.cmd),1)]),_:2},1024)]),_:2},1024))),128))]),_:1})):o(``,!0),t[10]||=d(`div`,{class:`text-subtitle-2 mb-2`},`系统内置(不可编辑)`,-1),d(`div`,R,[(b(!0),u(E,null,m(h(_)(),e=>(b(),c(g,{key:e.id,size:`small`,variant:`outlined`,label:``},{default:x(()=>[a(T(e.name),1)]),_:2},1024))),128))])]),_:1}),v(de,{modelValue:y.value,"onUpdate:modelValue":t[3]||=e=>y.value=e,"max-width":`520`},{default:x(()=>[v(M,{border:``},{default:x(()=>[v(k,null,{default:x(()=>[a(T(w.value?`编辑命令`:`添加快捷命令`),1)]),_:1}),v(A,null,{default:x(()=>[v(N,{modelValue:O.value,"onUpdate:modelValue":t[0]||=e=>O.value=e,label:`显示名称`,variant:`outlined`,density:`compact`,class:`mb-3`},null,8,[`modelValue`]),t[11]||=d(`div`,{class:`text-body-2 text-medium-emphasis mb-2`},`命令内容(发送时自动追加回车)`,-1),v(he,{modelValue:P.value,"onUpdate:modelValue":t[1]||=e=>P.value=e,multiline:``,rows:4,placeholder:`systemctl status nginx`},null,8,[`modelValue`])]),_:1}),v(j,null,{default:x(()=>[v(C),v(l,{variant:`text`,onClick:t[2]||=e=>y.value=!1},{default:x(()=>[...t[12]||=[a(`取消`,-1)]]),_:1}),v(l,{color:`primary`,variant:`flat`,loading:F.value,onClick:be},{default:x(()=>[...t[13]||=[a(`保存`,-1)]]),_:1},8,[`loading`])]),_:1})]),_:1})]),_:1},8,[`modelValue`]),v(de,{modelValue:I.value,"onUpdate:modelValue":t[5]||=e=>I.value=e,"max-width":`400`},{default:x(()=>[v(M,{border:``},{default:x(()=>[v(k,null,{default:x(()=>[...t[14]||=[a(`删除命令`,-1)]]),_:1}),v(A,null,{default:x(()=>[a(`确定删除「`+T(me.value)+`」?`,1)]),_:1}),v(j,null,{default:x(()=>[v(C),v(l,{variant:`text`,onClick:t[4]||=e=>I.value=!1},{default:x(()=>[...t[15]||=[a(`取消`,-1)]]),_:1}),v(l,{color:`error`,variant:`flat`,loading:F.value,onClick:Se},{default:x(()=>[...t[16]||=[a(`删除`,-1)]]),_:1},8,[`loading`])]),_:1})]),_:1})]),_:1},8,[`modelValue`])]),_:1}))}}),ye=[{key:`notify_alert_cpu`,label:`CPU 超阈值告警`,desc:`CPU 超阈值或恢复时推送;关闭则该类告警与恢复均不通知`,group:`服务器资源`},{key:`notify_alert_mem`,label:`内存超阈值告警`,desc:`内存超阈值或恢复时推送;关闭则该类告警与恢复均不通知`,group:`服务器资源`},{key:`notify_alert_disk`,label:`磁盘超阈值告警`,desc:`磁盘超阈值或恢复时推送;关闭则该类告警与恢复均不通知`,group:`服务器资源`},{key:`notify_recovery`,label:`资源恢复正常`,desc:`CPU/内存/磁盘回落正常时推送(须总开关开启且对应资源开关未关)`,group:`服务器资源`},{key:`notify_alert_offline`,label:`子机离线告警`,desc:`Agent 心跳丢失、子机由在线变为离线时推送一次;可在下方配置专用 Telegram Bot`,group:`服务器`},{key:`notify_time_drift`,label:`时钟偏差严重 (≥60s)`,desc:`子机与主机时间偏差过大影响 TOTP/cron`,group:`服务器`},{key:`notify_system_redis`,label:`Redis 连接异常 / 恢复`,desc:`Redis 不可达或恢复时推送`,group:`系统`},{key:`notify_system_mysql`,label:`MySQL 连接异常 / 恢复`,desc:`MySQL 不可达或恢复时推送`,group:`系统`},{key:`notify_restart`,label:`Nexus 后端重启`,desc:`Python 服务崩溃重启成功/失败时推送`,group:`系统`},{key:`notify_script_complete`,label:`脚本执行完成`,desc:`脚本批量执行结束时推送汇总与看板链接(不含失败明细)`,group:`运维`}],be={class:`d-flex flex-wrap ga-2 mb-4`},xe={class:`text-caption text-medium-emphasis font-weight-medium mt-2 mb-1`},Se={class:`d-flex flex-wrap ga-2 mb-2`},Ce={class:`d-flex flex-wrap align-center ga-2 mb-3`},we={class:`d-flex flex-wrap ga-2`},Te={key:2,class:`text-caption text-medium-emphasis mt-2 mb-0`},Ee={class:`d-flex align-center mb-3`},De={key:0,class:`text-center mb-3`},Oe=[`src`],ke={key:0,class:`d-flex align-center justify-center ga-2 mt-2`},Ae={class:`text-caption pa-1 bg-grey-lighten-4 rounded`,style:{"user-select":`all`}},je={key:1},Me={key:1,class:`d-flex ga-2 align-center`},Ne={class:`d-flex align-center ga-2`},Pe={class:`d-flex flex-wrap ga-2 mb-3`},Fe={key:0,class:`mb-4`},Ie={class:`text-caption text-medium-emphasis mb-2`},Le={key:0},Re={class:`d-flex flex-wrap ga-1`},ze={key:1,class:`text-caption text-medium-emphasis mb-4`},Be={class:`text-caption text-medium-emphasis`},Ve={class:`text-body-2 mb-2`},He={class:`d-flex flex-wrap ga-1 mb-2`,style:{"max-height":`240px`,"overflow-y":`auto`}},Ue={key:0,class:`text-body-2 text-medium-emphasis`},z=ne({name:`SettingsPage`,__name:`SettingsPage`,setup(ne){let p=ue(),{saveToServer:ie,previewSound:oe}=te(),{saveToServer:he,previewSound:ge}=f(),L=ee(),_e=re,R=S(s),z=S(!1),B=S(s),V=S(!1),We=S(!1),H=S({system_name:``,system_title:``,cpu_alert_threshold:80,mem_alert_threshold:80,disk_alert_threshold:80,alert_streak_required:3,db_pool_size:10,db_max_overflow:20,telegram_bot_token:``,telegram_chat_id:``,telegram_offline_chat_id:``}),U=S(``),W=S(!1),G=S(``),K=S(!1),q=S(!1),Ge=S(!1),Ke=S(!1),qe=S(!1),Je=S(`default`),Ye=S(!1),Xe=S(null),Ze=S(!1),Qe=S(!1),J=S(!1),$e=S([]),Y=S(!1),et=S(!1),tt=S({}),nt=S(null),X=S(null),rt=S(!1),it=S(!1),at=w(()=>{let e={};for(let t of ye)e[t.group]||(e[t.group]=[]),e[t.group].push(t);return e});function ot(e){return{private:`私聊`,group:`群组`,supergroup:`群组`,channel:`频道`}[e]||e}function st(e){let t=String(e??`true`).trim().toLowerCase();return![`false`,`0`,`no`,`off`].includes(t)}let Z=S({current:``,new_pw:``,confirm:``,totp_code:``}),ct=S(!1),lt=S(``),ut=S(``),dt=S(``),ft=S(!1),pt=S(!1),mt=S(``),ht=S(``),gt=S(!1),Q=S(!1),_t=S(``),vt=S(!1),yt=S(!1),bt=S(!1),xt=S(``),St=S(``),$=S([]),Ct=S(null),wt=S(0),Tt=S(!1),Et=S(!1),Dt=S(!1),Ot=S([]),kt=w(()=>$.value.slice(0,24));async function At(e=!1){e||(We.value=!0);try{let e=await _.get(`/settings/`),t=Array.isArray(e)?e:[],n=Object.keys(H.value);for(let e of t){let t=e.key;if(t===`telegram_bot_token`){W.value=!!e.value_set,U.value=``;continue}if(t===`telegram_offline_bot_token`){K.value=!!e.value_set,G.value=``;continue}if(t===`script_exec_complete_sound`){R.value=y(e.value);continue}if(t===`push_complete_sound`){B.value=y(e.value);continue}if(t&&ye.some(e=>e.key===t)){tt.value[t]=st(e.value);continue}if(t&&n.includes(t)){let n=e.value;typeof n==`string`&&/^\d+(\.\d+)?$/.test(n)?H.value[t]=Number(n):H.value[t]=n}}}catch{p(`加载设置失败`,`error`)}finally{e||(We.value=!1)}}async function jt(e=!1){try{let e=await _.get(`/settings/ip-allowlist`);bt.value=e.enabled||!1,xt.value=e.subscription_url||``,St.value=(e.manual_ips||[]).join(`
|
||
`),$.value=e.subscription_ips||[],Ct.value=e.last_refresh||null,wt.value=e.total_count??new Set([...e.manual_ips||[],...e.subscription_ips||[]]).size}catch{e||p(`加载白名单失败`,`error`)}}async function Mt(){let e=Xe.value;if(e){let{valid:t}=await e.validate();if(!t)return}Ye.value=!0;try{let e=Object.entries(H.value).filter(([e])=>[`system_name`,`system_title`,`cpu_alert_threshold`,`mem_alert_threshold`,`disk_alert_threshold`,`alert_streak_required`,`db_pool_size`,`db_max_overflow`].includes(e));for(let[t,n]of e)await _.put(`/settings/${t}`,{value:String(n??``)});p(`设置已保存`)}catch(e){p(e instanceof Error?e.message:`保存失败`,`error`)}finally{Ye.value=!1}}async function Nt(e){let t=U.value.trim(),n=String(H.value.telegram_chat_id||``).trim();return e?.requireToken&&!t&&!W.value?(p(`请先填写 Bot Token`,`error`),!1):e?.requireChatId&&!n?(p(`请先填写或检测 Chat ID`,`error`),!1):(t&&(await _.put(`/settings/telegram_bot_token`,{value:t}),W.value=!0,U.value=``,Y.value=!1),n&&await _.put(`/settings/telegram_chat_id`,{value:n}),!0)}async function Pt(e=!1){e||(rt.value=!0);try{X.value=await _.get(`/settings/ops-patrol/status`)}catch{X.value=null}finally{e||(rt.value=!1)}}async function Ft(){it.value=!0;try{if(!await Nt({requireToken:!0,requireChatId:!0}))return;let e=await _.post(`/settings/ops-patrol/sync-telegram`,{});X.value={...X.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},p(`巡检 Telegram 已同步至 .env`),await Pt()}catch(e){p(e instanceof Error?e.message:`同步失败`,`error`)}finally{it.value=!1}}async function It(){et.value=!0;try{let e=U.value.trim(),t=String(H.value.telegram_chat_id||``).trim();if(!e&&!t&&!W.value){p(`请先填写 Bot Token 或 Chat ID`,`warning`);return}await Nt(),await Pt(),p(`Telegram 配置已保存`)}catch(e){p(e instanceof Error?e.message:`保存失败`,`error`)}finally{et.value=!1}}async function Lt(e){let t=G.value.trim(),n=String(H.value.telegram_offline_chat_id||``).trim();return e?.requireToken&&!t&&!K.value?(p(`请先填写离线告警 Bot Token`,`error`),!1):e?.requireChatId&&!n?(p(`请先填写或检测离线告警 Chat ID`,`error`),!1):(t&&(await _.put(`/settings/telegram_offline_bot_token`,{value:t}),K.value=!0,G.value=``,q.value=!1),n&&await _.put(`/settings/telegram_offline_chat_id`,{value:n}),!0)}async function Rt(){Ge.value=!0;try{let e=G.value.trim(),t=String(H.value.telegram_offline_chat_id||``).trim();if(!e&&!t&&!K.value){p(`请先填写离线 Bot Token 或 Chat ID`,`warning`);return}await Lt(),p(`离线告警 Bot 已保存`)}catch(e){p(e instanceof Error?e.message:`保存失败`,`error`)}finally{Ge.value=!1}}async function zt(){Ke.value=!0;try{if(!await Lt({requireToken:!0,requireChatId:!0}))return;await _.post(`/settings/telegram/offline/test`),p(`离线通道测试消息已发送`)}catch(e){p(e instanceof Error?e.message:`发送失败`,`error`)}finally{Ke.value=!1}}async function Bt(){qe.value=!0;try{if(!await Lt({requireToken:!0}))return;if($e.value=(await _.get(`/settings/telegram/offline/chats`)).chats||[],!$e.value.length){p(`未检测到对话:私聊发消息,或群聊拉入 Bot 后发送 /start@Bot用户名`,`warning`);return}Je.value=`offline`,J.value=!0}catch(e){p(e instanceof Error?e.message:`检测失败`,`error`)}finally{qe.value=!1}}async function Vt(){if(q.value){q.value=!1,K.value&&(G.value=``);return}if(G.value.trim()){q.value=!0;return}if(!K.value){q.value=!0;return}yt.value=!0;try{G.value=(await _.post(`/settings/telegram/offline/reveal-token`,{})).value,q.value=!0}catch(e){p(e instanceof Error?e.message:`获取离线 Bot Token 失败`,`error`)}finally{yt.value=!1}}async function Ht(e){if(!e||z.value)return;let t=R.value;R.value=e,z.value=!0;try{await ie(e),p(`提示音设置已保存`)}catch(e){R.value=t,p(e instanceof Error?e.message:`保存失败`,`error`)}finally{z.value=!1}}function Ut(){oe(R.value)}async function Wt(e){if(!e||V.value)return;let t=B.value;B.value=e,V.value=!0;try{await he(e),p(`推送提示音设置已保存`)}catch(e){B.value=t,p(e instanceof Error?e.message:`保存失败`,`error`)}finally{V.value=!1}}function Gt(){ge(B.value)}async function Kt(e,t){let n=tt.value[e];tt.value[e]=t,nt.value=e;try{await _.put(`/settings/${e}`,{value:t?`true`:`false`})}catch(t){tt.value[e]=n,p(t instanceof Error?t.message:`保存失败,已撤销`,`error`)}finally{nt.value=null}}async function qt(){Ze.value=!0;try{if(!await Nt({requireToken:!0,requireChatId:!0}))return;await _.post(`/settings/telegram/test`),p(`测试消息已发送`)}catch(e){p(e instanceof Error?e.message:`发送失败`,`error`)}finally{Ze.value=!1}}async function Jt(){Qe.value=!0;try{if(!await Nt({requireToken:!0}))return;if($e.value=(await _.get(`/settings/telegram/chats`)).chats||[],!$e.value.length){p(`未检测到对话:私聊发消息,或群聊拉入 Bot 后发送 /start@Bot用户名`,`warning`);return}Je.value=`default`,J.value=!0}catch(e){p(e instanceof Error?e.message:`检测失败`,`error`)}finally{Qe.value=!1}}async function Yt(e){let t=String(e.id),n=Je.value===`offline`;n?H.value.telegram_offline_chat_id=t:H.value.telegram_chat_id=t,J.value=!1;try{let e=n?`telegram_offline_chat_id`:`telegram_chat_id`;await _.put(`/settings/${e}`,{value:t}),p(`已选择 Chat ID: ${t}`)}catch(e){p(e instanceof Error?e.message:`保存 Chat ID 失败`,`error`)}}async function Xt(){if(Z.value.new_pw!==Z.value.confirm){p(`两次密码不一致`,`error`);return}ct.value=!0;try{let e={current_password:Z.value.current,new_password:Z.value.new_pw};L.admin?.totp_enabled&&Z.value.totp_code&&(e.totp_code=Z.value.totp_code),await _.put(`/auth/password`,e),Z.value={current:``,new_pw:``,confirm:``,totp_code:``},p(`密码已修改`)}catch(e){p(e instanceof Error?e.message:`修改失败`,`error`)}finally{ct.value=!1}}async function Zt(){try{let e=await _.post(`/auth/totp/setup`);lt.value=e.qr_code,ut.value=e.secret||``}catch(e){p(e instanceof Error?e.message:`生成失败`,`error`)}}async function Qt(){ft.value=!0;try{await _.post(`/auth/totp/enable`,{code:dt.value}),await L.fetchProfile(),lt.value=``,dt.value=``,p(`TOTP 已启用`)}catch(e){p(e.message||`启用失败`,`error`)}finally{ft.value=!1}}function $t(){pt.value=!0}async function en(){gt.value=!0;try{await _.post(`/auth/totp/disable`,{admin_id:L.admin?.id,current_password:mt.value,totp_code:ht.value}),await L.fetchProfile(),pt.value=!1,mt.value=``,ht.value=``,p(`TOTP 已禁用`)}catch(e){p(e.message||`禁用失败`,`error`)}finally{gt.value=!1}}function tn(){ut.value&&(navigator.clipboard.writeText(ut.value),p(`密钥已复制`))}async function nn(){if(Q.value){Q.value=!1;return}vt.value=!0;try{_t.value=(await _.post(`/settings/api-key/reveal`,{})).value,Q.value=!0}catch(e){p(e instanceof Error?e.message:`获取 API Key 失败`,`error`)}finally{vt.value=!1}}async function rn(){if(Y.value){Y.value=!1,W.value&&(U.value=``);return}if(U.value.trim()){Y.value=!0;return}if(!W.value){Y.value=!0;return}yt.value=!0;try{U.value=(await _.post(`/settings/telegram/reveal-token`,{})).value,Y.value=!0}catch(e){p(e instanceof Error?e.message:`获取 Bot Token 失败`,`error`)}finally{yt.value=!1}}function an(){if(!Q.value||!_t.value){p(`请先点击眼睛图标显示 API Key`,`warning`);return}navigator.clipboard.writeText(_t.value),p(`已复制到剪贴板`)}async function on(){try{await _.post(`/settings/ip-allowlist/toggle?enabled=${bt.value?`true`:`false`}`)}catch(e){p(e instanceof Error?e.message:`操作失败`,`error`)}}async function sn(){let e=xt.value.trim();if(!e){p(`请先填写订阅 URL`,`error`);return}Et.value=!0;try{if(Ot.value=(await _.post(`/settings/ip-allowlist/parse-subscription`,{url:e})).hosts||[],!Ot.value.length){p(`未能解析出任何节点`,`warning`);return}Dt.value=!0}catch(e){p(e instanceof Error?e.message:`解析失败`,`error`)}finally{Et.value=!1}}async function cn(){Tt.value=!0;try{let e=St.value.split(`
|
||
`).map(e=>e.trim()).filter(Boolean),t={manual_ips:e,subscription_url:xt.value.trim(),enabled:bt.value},n=await _.post(`/settings/ip-allowlist`,t);n.refresh_ok===!1&&n.refresh_error?(p(`白名单已保存,但订阅刷新失败:${n.refresh_error}`,`warning`),await jt(!0)):($.value=n.subscription_ips||[],Ct.value=n.last_refresh||null,wt.value=new Set([...n.subscription_ips||[],...e]).size,p(`白名单已保存`)),Dt.value=!1}catch(e){p(e instanceof Error?e.message:`保存失败`,`error`)}finally{Tt.value=!1}}async function ln(e=!1){await Promise.all([At(e),jt(),Pt(e),L.fetchProfile()])}return O(e=>ln(e)),(ee,s)=>(b(),c(e,{fluid:``,class:`pa-6`},{default:x(()=>[v(r,null,{default:x(()=>[v(n,{cols:`12`,lg:`6`},{default:x(()=>[v(M,{elevation:`0`,border:``,rounded:`lg`,class:`mb-4`},{default:x(()=>[v(k,{class:`d-flex align-center`},{default:x(()=>[v(i,{class:`mr-2`},{default:x(()=>[...s[31]||=[a(`mdi-cog`,-1)]]),_:1}),s[32]||=a(` 系统设置 `,-1)]),_:1}),We.value?(b(),c(ce,{key:0,indeterminate:``,color:`primary`})):o(``,!0),v(D),v(I,{ref_key:`systemSettingsFormRef`,ref:Xe,onSubmit:ae(Mt,[`prevent`])},{default:x(()=>[v(A,null,{default:x(()=>[v(N,{modelValue:H.value.system_name,"onUpdate:modelValue":s[0]||=e=>H.value.system_name=e,label:`系统名称`,variant:`outlined`,density:`compact`,class:`mb-3`,rules:[h(F)(`系统名称`)]},null,8,[`modelValue`,`rules`]),v(N,{modelValue:H.value.system_title,"onUpdate:modelValue":s[1]||=e=>H.value.system_title=e,label:`系统标题`,variant:`outlined`,density:`compact`,class:`mb-3`,rules:[h(F)(`系统标题`)]},null,8,[`modelValue`,`rules`]),v(D,{class:`my-4`}),s[33]||=d(`div`,{class:`text-subtitle-2 mb-3`},`告警阈值`,-1),v(r,{dense:``},{default:x(()=>[v(n,{cols:`4`},{default:x(()=>[v(N,{modelValue:H.value.cpu_alert_threshold,"onUpdate:modelValue":s[2]||=e=>H.value.cpu_alert_threshold=e,label:`CPU %`,variant:`outlined`,density:`compact`,type:`number`,rules:[h(F)(`阈值`),h(P)(1,100,`阈值`)]},null,8,[`modelValue`,`rules`])]),_:1}),v(n,{cols:`4`},{default:x(()=>[v(N,{modelValue:H.value.mem_alert_threshold,"onUpdate:modelValue":s[3]||=e=>H.value.mem_alert_threshold=e,label:`内存 %`,variant:`outlined`,density:`compact`,type:`number`,rules:[h(F)(`阈值`),h(P)(1,100,`阈值`)]},null,8,[`modelValue`,`rules`])]),_:1}),v(n,{cols:`4`},{default:x(()=>[v(N,{modelValue:H.value.disk_alert_threshold,"onUpdate:modelValue":s[4]||=e=>H.value.disk_alert_threshold=e,label:`磁盘 %`,variant:`outlined`,density:`compact`,type:`number`,rules:[h(F)(`阈值`),h(P)(1,100,`阈值`)]},null,8,[`modelValue`,`rules`])]),_:1})]),_:1}),v(N,{modelValue:H.value.alert_streak_required,"onUpdate:modelValue":s[5]||=e=>H.value.alert_streak_required=e,label:`连续超阈次数`,hint:`默认 3:常态 60s 心跳约 3 分钟才告警;设为 1 则立即告警`,"persistent-hint":``,variant:`outlined`,density:`compact`,type:`number`,class:`mt-3`,rules:[h(F)(`连续次数`),h(P)(1,20,`连续次数`)]},null,8,[`modelValue`,`rules`]),v(D,{class:`my-4`}),s[34]||=d(`div`,{class:`text-subtitle-2 mb-3`},`连接池`,-1),v(r,{dense:``},{default:x(()=>[v(n,{cols:`6`},{default:x(()=>[v(N,{modelValue:H.value.db_pool_size,"onUpdate:modelValue":s[6]||=e=>H.value.db_pool_size=e,label:`连接池大小`,variant:`outlined`,density:`compact`,type:`number`,rules:[h(F)(`连接池大小`),h(P)(1,1e3,`连接池大小`)]},null,8,[`modelValue`,`rules`])]),_:1}),v(n,{cols:`6`},{default:x(()=>[v(N,{modelValue:H.value.db_max_overflow,"onUpdate:modelValue":s[7]||=e=>H.value.db_max_overflow=e,label:`溢出连接数`,variant:`outlined`,density:`compact`,type:`number`,rules:[h(F)(`溢出连接数`),h(P)(1,1e3,`溢出连接数`)]},null,8,[`modelValue`,`rules`])]),_:1})]),_:1})]),_:1}),v(j,{class:`px-4 pb-4`},{default:x(()=>[v(C),v(l,{type:`submit`,color:`primary`,variant:`flat`,loading:Ye.value},{default:x(()=>[...s[35]||=[a(`保存设置`,-1)]]),_:1},8,[`loading`])]),_:1})]),_:1},512)]),_:1}),v(ve),v(M,{elevation:`0`,border:``,rounded:`lg`,class:`mb-4`},{default:x(()=>[v(k,{class:`d-flex align-center`},{default:x(()=>[v(i,{class:`mr-2`},{default:x(()=>[...s[36]||=[a(`mdi-bell-ring-outline`,-1)]]),_:1}),s[37]||=a(` 界面提示 `,-1)]),_:1}),v(D),v(A,null,{default:x(()=>[s[40]||=d(`p`,{class:`text-caption text-medium-emphasis mb-3`},` 脚本批量执行全部结束时,在浏览器播放提示音(仅当前登录的管理员会话,与 Telegram 推送无关)。 `,-1),v(t,{modelValue:R.value,"onUpdate:modelValue":[s[8]||=e=>R.value=e,Ht],items:h(_e),"item-title":`title`,"item-value":`value`,label:`脚本执行完成提示音`,variant:`outlined`,density:`compact`,"hide-details":``,class:`mb-3`,loading:z.value,disabled:z.value},null,8,[`modelValue`,`items`,`loading`,`disabled`]),v(l,{size:`small`,variant:`tonal`,"prepend-icon":`mdi-volume-high`,disabled:R.value===`off`||z.value,onClick:Ut},{default:x(()=>[...s[38]||=[a(` 试听 `,-1)]]),_:1},8,[`disabled`]),v(D,{class:`my-4`}),s[41]||=d(`p`,{class:`text-caption text-medium-emphasis mb-3`},` 文件推送批次结束且至少一台成功时,在浏览器播放提示音(与脚本提示音独立配置)。 `,-1),v(t,{modelValue:B.value,"onUpdate:modelValue":[s[9]||=e=>B.value=e,Wt],items:h(_e),"item-title":`title`,"item-value":`value`,label:`文件推送完成提示音`,variant:`outlined`,density:`compact`,"hide-details":``,class:`mb-3`,loading:V.value,disabled:V.value},null,8,[`modelValue`,`items`,`loading`,`disabled`]),v(l,{size:`small`,variant:`tonal`,"prepend-icon":`mdi-volume-high`,disabled:B.value===`off`||V.value,onClick:Gt},{default:x(()=>[...s[39]||=[a(` 试听 `,-1)]]),_:1},8,[`disabled`])]),_:1})]),_:1}),v(M,{elevation:`0`,border:``,rounded:`lg`},{default:x(()=>[v(k,{class:`d-flex align-center`},{default:x(()=>[v(i,{class:`mr-2`},{default:x(()=>[...s[42]||=[a(`mdi-send`,-1)]]),_:1}),s[43]||=a(` Telegram 推送 `,-1)]),_:1}),v(D),v(A,null,{default:x(()=>[v(N,{modelValue:U.value,"onUpdate:modelValue":s[10]||=e=>U.value=e,label:`Bot Token`,variant:`outlined`,density:`compact`,class:`mb-3`,placeholder:W.value?`已配置(留空保持不变)`:`输入 Bot Token`,type:Y.value?`text`:`password`,"append-inner-icon":Y.value?`mdi-eye-off`:`mdi-eye`,"onClick:appendInner":rn},null,8,[`modelValue`,`placeholder`,`type`,`append-inner-icon`]),W.value&&!U.value?(b(),c(g,{key:0,size:`small`,color:`success`,variant:`tonal`,class:`mb-3`},{default:x(()=>[...s[44]||=[a(`Token 已配置`,-1)]]),_:1})):o(``,!0),v(N,{modelValue:H.value.telegram_chat_id,"onUpdate:modelValue":s[11]||=e=>H.value.telegram_chat_id=e,label:`Chat ID`,variant:`outlined`,density:`compact`,class:`mb-3`},null,8,[`modelValue`]),s[56]||=d(`p`,{class:`text-caption text-medium-emphasis mb-3`},[a(` 私聊:向 Bot 发送任意消息。群聊:将 Bot 拉入群后发送 `),d(`code`,null,`/start@你的Bot用户名`),a(`(或 @提及 Bot),再点击下方检测。 `)],-1),d(`div`,be,[v(l,{size:`small`,variant:`tonal`,"prepend-icon":`mdi-radar`,onClick:Jt,loading:Qe.value},{default:x(()=>[...s[45]||=[a(`检测 Chat ID`,-1)]]),_:1},8,[`loading`]),v(l,{size:`small`,variant:`tonal`,"prepend-icon":`mdi-message-text`,onClick:qt,loading:Ze.value},{default:x(()=>[...s[46]||=[a(`发送测试消息`,-1)]]),_:1},8,[`loading`]),v(l,{size:`small`,variant:`tonal`,color:`primary`,"prepend-icon":`mdi-content-save`,onClick:It,loading:et.value},{default:x(()=>[...s[47]||=[a(`保存 Telegram 配置`,-1)]]),_:1},8,[`loading`])]),v(D,{class:`my-3`}),s[57]||=d(`div`,{class:`text-subtitle-2 mb-1`},`告警通知项目`,-1),s[58]||=d(`p`,{class:`text-caption text-medium-emphasis mb-3`},` 关闭后该类告警仍记录日志,但不发送 Telegram 消息。Bot Token 未配置时全部静默。 `,-1),(b(!0),u(E,null,m(at.value,(e,t)=>(b(),u(E,{key:t},[d(`div`,xe,T(t),1),(b(!0),u(E,null,m(e,e=>(b(),c(pe,{key:e.key,"model-value":tt.value[e.key]??!0,label:e.label,hint:e.desc,"persistent-hint":``,color:`primary`,density:`compact`,"hide-details":`auto`,class:`mb-1`,disabled:nt.value===e.key,"onUpdate:modelValue":t=>Kt(e.key,!!t)},null,8,[`model-value`,`label`,`hint`,`disabled`,`onUpdate:modelValue`]))),128))],64))),128)),v(D,{class:`my-3`}),s[59]||=d(`div`,{class:`text-subtitle-2 mb-1`},`子机离线告警专用 Bot(可选)`,-1),s[60]||=d(`p`,{class:`text-caption text-medium-emphasis mb-3`},` 与上方默认 Bot 分离:仅「子机离线告警」走此通道。Bot Token 与 Chat ID 均填写后生效;留空则离线告警仍走默认 Bot。 `,-1),v(N,{modelValue:G.value,"onUpdate:modelValue":s[12]||=e=>G.value=e,label:`离线告警 Bot Token`,variant:`outlined`,density:`compact`,class:`mb-3`,placeholder:K.value?`已配置(留空保持不变)`:`输入专用 Bot Token`,type:q.value?`text`:`password`,"append-inner-icon":q.value?`mdi-eye-off`:`mdi-eye`,"onClick:appendInner":Vt},null,8,[`modelValue`,`placeholder`,`type`,`append-inner-icon`]),K.value&&!G.value?(b(),c(g,{key:1,size:`small`,color:`success`,variant:`tonal`,class:`mb-3`},{default:x(()=>[...s[48]||=[a(` 离线 Token 已配置 `,-1)]]),_:1})):o(``,!0),v(N,{modelValue:H.value.telegram_offline_chat_id,"onUpdate:modelValue":s[13]||=e=>H.value.telegram_offline_chat_id=e,label:`离线告警 Chat ID`,variant:`outlined`,density:`compact`,class:`mb-3`},null,8,[`modelValue`]),s[61]||=d(`p`,{class:`text-caption text-medium-emphasis mb-3`},[a(` 检测规则与默认 Bot 相同:群聊需拉入专用 Bot 后在群内发送 `),d(`code`,null,`/start@Bot用户名`),a(`。 `)],-1),d(`div`,Se,[v(l,{size:`small`,variant:`tonal`,"prepend-icon":`mdi-radar`,loading:qe.value,onClick:Bt},{default:x(()=>[...s[49]||=[a(` 检测离线 Chat ID `,-1)]]),_:1},8,[`loading`]),v(l,{size:`small`,variant:`tonal`,"prepend-icon":`mdi-message-text`,loading:Ke.value,onClick:zt},{default:x(()=>[...s[50]||=[a(` 测试离线通道 `,-1)]]),_:1},8,[`loading`]),v(l,{size:`small`,variant:`tonal`,color:`primary`,"prepend-icon":`mdi-content-save`,loading:Ge.value,onClick:Rt},{default:x(()=>[...s[51]||=[a(` 保存离线 Bot `,-1)]]),_:1},8,[`loading`])]),v(D,{class:`my-4`}),s[62]||=d(`div`,{class:`text-subtitle-2 mb-1`},`Layer 3 宿主机巡检`,-1),s[63]||=d(`p`,{class:`text-caption text-medium-emphasis mb-3`},[a(` 每分钟由宿主机 cron 执行 `),d(`code`,null,`health_monitor.sh`),a(`:连续 3 次 /health 失败则自动重启并推送 Telegram。 配置保存后会自动同步至 .env;亦可手动同步。未同步时脚本会从数据库读取 Telegram 配置。 `)],-1),d(`div`,Ce,[v(g,{size:`small`,color:X.value?.telegram_layer3_ready?`success`:`warning`,variant:`tonal`},{default:x(()=>[a(T(X.value?.telegram_layer3_ready?`巡检 Telegram 就绪`:`请先配置 Telegram`),1)]),_:1},8,[`color`]),X.value?(b(),c(g,{key:0,size:`small`,color:X.value.telegram_env_synced?`success`:`grey`,variant:`tonal`},{default:x(()=>[a(T(X.value.telegram_env_synced?`.env 已同步`:`.env 未同步(可用 DB 回退)`),1)]),_:1},8,[`color`])):o(``,!0)]),d(`div`,we,[v(l,{size:`small`,variant:`tonal`,"prepend-icon":`mdi-sync`,onClick:Ft,loading:it.value,disabled:!X.value?.telegram_app_configured},{default:x(()=>[...s[52]||=[a(` 同步巡检 Telegram `,-1)]]),_:1},8,[`loading`,`disabled`]),v(l,{size:`small`,variant:`text`,"prepend-icon":`mdi-refresh`,onClick:Pt,loading:rt.value},{default:x(()=>[...s[53]||=[a(` 刷新状态 `,-1)]]),_:1},8,[`loading`])]),X.value?(b(),u(`p`,Te,[s[54]||=a(` 宿主机安装 cron:`,-1),d(`code`,null,T(X.value.cron_install_command),1),s[55]||=a(` · 日志:`,-1),d(`code`,null,T(X.value.health_log_path),1)])):o(``,!0)]),_:1})]),_:1})]),_:1}),v(n,{cols:`12`,lg:`6`},{default:x(()=>[v(M,{elevation:`0`,border:``,rounded:`lg`,class:`mb-4`},{default:x(()=>[v(k,{class:`d-flex align-center`},{default:x(()=>[v(i,{class:`mr-2`},{default:x(()=>[...s[64]||=[a(`mdi-lock`,-1)]]),_:1}),s[65]||=a(` 修改密码 `,-1)]),_:1}),v(D),v(A,null,{default:x(()=>[v(N,{modelValue:Z.value.current,"onUpdate:modelValue":s[14]||=e=>Z.value.current=e,label:`当前密码`,variant:`outlined`,density:`compact`,type:`password`,class:`mb-3`,rules:[h(F)(`密码`)]},null,8,[`modelValue`,`rules`]),v(N,{modelValue:Z.value.new_pw,"onUpdate:modelValue":s[15]||=e=>Z.value.new_pw=e,label:`新密码`,variant:`outlined`,density:`compact`,type:`password`,class:`mb-3`,rules:[h(F)(`密码`)]},null,8,[`modelValue`,`rules`]),v(N,{modelValue:Z.value.confirm,"onUpdate:modelValue":s[16]||=e=>Z.value.confirm=e,label:`确认新密码`,variant:`outlined`,density:`compact`,type:`password`,class:`mb-3`,rules:[h(F)(`确认密码`),h(fe)(()=>Z.value.new_pw)]},null,8,[`modelValue`,`rules`]),h(L).admin?.totp_enabled?(b(),c(N,{key:0,modelValue:Z.value.totp_code,"onUpdate:modelValue":s[17]||=e=>Z.value.totp_code=e,label:`TOTP 验证码`,variant:`outlined`,density:`compact`,type:`text`,inputmode:`numeric`,maxlength:`6`,class:`mb-3`,rules:h(L).admin?.totp_enabled?[h(F)(`验证码`)]:[]},null,8,[`modelValue`,`rules`])):o(``,!0)]),_:1}),v(j,{class:`px-4 pb-4`},{default:x(()=>[v(C),v(l,{color:`primary`,variant:`flat`,onClick:Xt,loading:ct.value},{default:x(()=>[...s[66]||=[a(`修改密码`,-1)]]),_:1},8,[`loading`])]),_:1})]),_:1}),v(M,{elevation:`0`,border:``,rounded:`lg`,class:`mb-4`},{default:x(()=>[v(k,{class:`d-flex align-center`},{default:x(()=>[v(i,{class:`mr-2`},{default:x(()=>[...s[67]||=[a(`mdi-shield-key`,-1)]]),_:1}),s[68]||=a(` 双因素认证 (TOTP) `,-1)]),_:1}),v(D),v(A,null,{default:x(()=>[d(`div`,Ee,[s[69]||=d(`span`,{class:`text-body-2`},`状态:`,-1),v(g,{color:h(L).admin?.totp_enabled?`success`:`grey`,size:`small`,variant:`tonal`,label:``,class:`ml-2`},{default:x(()=>[a(T(h(L).admin?.totp_enabled?`已启用`:`未启用`),1)]),_:1},8,[`color`])]),lt.value?(b(),u(`div`,De,[d(`img`,{src:lt.value,alt:`TOTP QR`,style:{"max-width":`200px`}},null,8,Oe),ut.value?(b(),u(`div`,ke,[d(`code`,Ae,T(ut.value),1),v(l,{size:`x-small`,variant:`text`,icon:`mdi-content-copy`,onClick:tn})])):o(``,!0),s[70]||=d(`div`,{class:`text-caption text-medium-emphasis mt-1`},`用认证器 App 扫描二维码或手动输入密钥`,-1)])):o(``,!0),h(L).admin?.totp_enabled?(b(),c(l,{key:2,size:`small`,variant:`tonal`,color:`error`,"prepend-icon":`mdi-shield-off`,onClick:$t},{default:x(()=>[...s[73]||=[a(`禁用 TOTP`,-1)]]),_:1})):(b(),u(`div`,je,[lt.value?(b(),u(`div`,Me,[v(N,{modelValue:dt.value,"onUpdate:modelValue":s[18]||=e=>dt.value=e,label:`验证码`,variant:`outlined`,density:`compact`,style:{"max-width":`160px`}},null,8,[`modelValue`]),v(l,{color:`primary`,variant:`flat`,size:`small`,onClick:Qt,loading:ft.value},{default:x(()=>[...s[72]||=[a(`启用`,-1)]]),_:1},8,[`loading`])])):(b(),c(l,{key:0,size:`small`,variant:`tonal`,"prepend-icon":`mdi-qrcode`,onClick:Zt},{default:x(()=>[...s[71]||=[a(`生成二维码`,-1)]]),_:1}))]))]),_:1})]),_:1}),v(M,{elevation:`0`,border:``,rounded:`lg`,class:`mb-4`},{default:x(()=>[v(k,{class:`d-flex align-center`},{default:x(()=>[v(i,{class:`mr-2`},{default:x(()=>[...s[74]||=[a(`mdi-key`,-1)]]),_:1}),s[75]||=a(` API Key `,-1)]),_:1}),v(D),v(A,null,{default:x(()=>[d(`div`,Ne,[v(N,{"model-value":Q.value?_t.value:`••••••••`,label:`API Key`,variant:`outlined`,density:`compact`,readonly:``,type:Q.value?`text`:`password`,style:{"max-width":`320px`}},null,8,[`model-value`,`type`]),v(l,{variant:`text`,size:`small`,icon:Q.value?`mdi-eye-off`:`mdi-eye`,onClick:nn,loading:vt.value},null,8,[`icon`,`loading`]),v(l,{variant:`text`,size:`small`,icon:`mdi-content-copy`,onClick:an})])]),_:1})]),_:1}),v(M,{elevation:`0`,border:``,rounded:`lg`},{default:x(()=>[v(k,{class:`d-flex align-center`},{default:x(()=>[v(i,{class:`mr-2`},{default:x(()=>[...s[76]||=[a(`mdi-ip-network`,-1)]]),_:1}),s[77]||=a(` 登录 IP 白名单 `,-1)]),_:1}),v(D),v(A,null,{default:x(()=>[v(pe,{modelValue:bt.value,"onUpdate:modelValue":[s[19]||=e=>bt.value=e,on],label:`启用 IP 白名单(仅白名单 IP 可登录)`,color:`primary`,density:`compact`,"hide-details":``,class:`mb-4`},null,8,[`modelValue`]),s[80]||=d(`div`,{class:`text-subtitle-2 mb-2`},`代理订阅`,-1),s[81]||=d(`p`,{class:`text-caption text-medium-emphasis mb-2`},` 填写 SS/VMess/VLESS 等订阅链接,保存后每 2 小时自动刷新节点 IP 并合并进白名单。 `,-1),v(N,{modelValue:xt.value,"onUpdate:modelValue":s[20]||=e=>xt.value=e,label:`订阅 URL`,variant:`outlined`,density:`compact`,class:`mb-2`,placeholder:`https://example.com/sub?token=...`},null,8,[`modelValue`]),d(`div`,Pe,[v(l,{size:`small`,variant:`tonal`,"prepend-icon":`mdi-cloud-download`,onClick:sn,loading:Et.value},{default:x(()=>[...s[78]||=[a(`解析预览`,-1)]]),_:1},8,[`loading`]),v(l,{size:`small`,variant:`tonal`,color:`primary`,"prepend-icon":`mdi-content-save`,onClick:cn,loading:Tt.value},{default:x(()=>[...s[79]||=[a(`保存白名单`,-1)]]),_:1},8,[`loading`])]),$.value.length?(b(),u(`div`,Fe,[d(`div`,Ie,[a(` 订阅节点 `+T($.value.length)+` 个 `,1),Ct.value?(b(),u(`span`,Le,` · 上次刷新 `+T(Ct.value),1)):o(``,!0)]),d(`div`,Re,[(b(!0),u(E,null,m(kt.value,e=>(b(),c(g,{key:e,size:`x-small`,variant:`tonal`,label:``},{default:x(()=>[a(T(e),1)]),_:2},1024))),128)),$.value.length>kt.value.length?(b(),c(g,{key:0,size:`x-small`,variant:`text`,label:``},{default:x(()=>[a(` +`+T($.value.length-kt.value.length)+` 更多 `,1)]),_:1})):o(``,!0)])])):xt.value?(b(),u(`div`,ze,T(Ct.value?`上次刷新 ${Ct.value},暂无节点`:`等待首次刷新…保存订阅 URL 后将自动拉取`),1)):o(``,!0),v(D,{class:`my-3`}),s[82]||=d(`div`,{class:`text-subtitle-2 mb-2`},`手动 IP`,-1),v(me,{modelValue:St.value,"onUpdate:modelValue":s[21]||=e=>St.value=e,label:`手动 IP / CIDR(每行一个)`,variant:`outlined`,density:`compact`,rows:`4`,class:`mb-2`,placeholder:`1.2.3.4
|
||
10.0.0.0/24`},null,8,[`modelValue`]),d(`div`,Be,` 手动 IP 与订阅节点合并生效;共 `+T(wt.value)+` 条(去重后)。 `,1)]),_:1})]),_:1})]),_:1})]),_:1}),v(de,{modelValue:Dt.value,"onUpdate:modelValue":s[24]||=e=>Dt.value=e,"max-width":`520`},{default:x(()=>[v(M,{border:``},{default:x(()=>[v(k,null,{default:x(()=>[...s[83]||=[a(`订阅解析预览`,-1)]]),_:1}),v(A,null,{default:x(()=>[d(`div`,Ve,[s[84]||=a(`共解析出 `,-1),d(`strong`,null,T(Ot.value.length),1),s[85]||=a(` 个节点 IP / 域名:`,-1)]),d(`div`,He,[(b(!0),u(E,null,m(Ot.value,e=>(b(),c(g,{key:e,size:`small`,variant:`tonal`,label:``},{default:x(()=>[a(T(e),1)]),_:2},1024))),128))]),s[86]||=d(`div`,{class:`text-caption text-medium-emphasis`},`点击「保存白名单」后才会写入订阅 URL 并触发后台刷新。`,-1)]),_:1}),v(j,null,{default:x(()=>[v(C),v(l,{variant:`text`,onClick:s[22]||=e=>Dt.value=!1},{default:x(()=>[...s[87]||=[a(`关闭`,-1)]]),_:1}),v(l,{color:`primary`,variant:`flat`,onClick:s[23]||=e=>{Dt.value=!1,cn()}},{default:x(()=>[...s[88]||=[a(`保存白名单`,-1)]]),_:1})]),_:1})]),_:1})]),_:1},8,[`modelValue`]),v(de,{modelValue:J.value,"onUpdate:modelValue":s[26]||=e=>J.value=e,"max-width":`480`},{default:x(()=>[v(M,{border:``},{default:x(()=>[v(k,null,{default:x(()=>[...s[89]||=[a(`选择 Chat ID`,-1)]]),_:1}),v(A,null,{default:x(()=>[$e.value.length?(b(),c(le,{key:1,density:`compact`,lines:`two`},{default:x(()=>[(b(!0),u(E,null,m($e.value,e=>(b(),c(se,{key:e.id,title:e.title||e.username||`Chat ${e.id}`,subtitle:`${ot(e.type)}${e.username?` · @`+e.username:``} · ID ${e.id}`,onClick:t=>Yt(e)},null,8,[`title`,`subtitle`,`onClick`]))),128))]),_:1})):(b(),u(`div`,Ue,[...s[90]||=[a(` 未检测到对话。私聊请向 Bot 发消息;群聊请将 Bot 拉入群后在群内发送 `,-1),d(`code`,null,`/start@Bot用户名`,-1),a(`,然后重新检测。 `,-1)]]))]),_:1}),v(j,null,{default:x(()=>[v(C),v(l,{variant:`text`,onClick:s[25]||=e=>J.value=!1},{default:x(()=>[...s[91]||=[a(`关闭`,-1)]]),_:1})]),_:1})]),_:1})]),_:1},8,[`modelValue`]),v(de,{modelValue:pt.value,"onUpdate:modelValue":s[30]||=e=>pt.value=e,"max-width":`400`},{default:x(()=>[v(M,{border:``},{default:x(()=>[v(k,null,{default:x(()=>[...s[92]||=[a(`禁用 TOTP`,-1)]]),_:1}),v(A,null,{default:x(()=>[v(N,{modelValue:mt.value,"onUpdate:modelValue":s[27]||=e=>mt.value=e,label:`当前密码`,variant:`outlined`,density:`compact`,type:`password`,class:`mb-2`,rules:[h(F)()]},null,8,[`modelValue`,`rules`]),v(N,{modelValue:ht.value,"onUpdate:modelValue":s[28]||=e=>ht.value=e,label:`验证码`,variant:`outlined`,density:`compact`,rules:[h(F)()]},null,8,[`modelValue`,`rules`])]),_:1}),v(j,null,{default:x(()=>[v(C),v(l,{variant:`text`,onClick:s[29]||=e=>pt.value=!1},{default:x(()=>[...s[93]||=[a(`取消`,-1)]]),_:1}),v(l,{color:`error`,variant:`flat`,onClick:en,loading:gt.value},{default:x(()=>[...s[94]||=[a(`禁用`,-1)]]),_:1},8,[`loading`])]),_:1})]),_:1})]),_:1},8,[`modelValue`])]),_:1}))}});export{z as default}; |