8 Commits

58 changed files with 261 additions and 163 deletions

View File

@@ -1 +1 @@
0.3.31 0.3.40

View File

@@ -1 +1 @@
0.3.31 0.3.34

View File

@@ -1,4 +1,4 @@
import{x as qu,m as $_,h as Ce,B as Hg,d as q_,o as K_,a as Tt,c as Nt,K as ml,L as _l,b as Q,F as Vr,r as Gr,f as $t,w as qt,e as Oe,v as Ka,j as Hr,i as Q_,t as wt,n as Nc,y as Ei,l as zc,p as J_,E as j_,u as t1}from"./index-DT1mRj5t.js";import{a as e1,h as r1,c as i1,i as n1,j as a1,t as o1,_ as s1}from"./_plugin-vue_export-helper-1Z-znrfZ.js";import l1 from"./CloudConfig-CgJ44DuS.js";import u1 from"./SystemConfig-BeJ_jebO.js";import f1 from"./SaveRecords-CZh2kRyW.js";import"./index-Bn7NwETH.js";import"./CloudBadge-BEGriYUm.js";/*! ***************************************************************************** import{x as qu,m as $_,h as Ce,B as Hg,d as q_,o as K_,a as Tt,c as Nt,K as ml,L as _l,b as Q,F as Vr,r as Gr,f as $t,w as qt,e as Oe,v as Ka,j as Hr,i as Q_,t as wt,n as Nc,y as Ei,l as zc,p as J_,E as j_,u as t1}from"./index-hm1O9sxT.js";import{a as e1,h as r1,c as i1,i as n1,j as a1,t as o1,_ as s1}from"./_plugin-vue_export-helper-D4DENoBS.js";import l1 from"./CloudConfig-Dl6za0gm.js";import u1 from"./SystemConfig-CwYIM6EH.js";import f1 from"./SaveRecords-DQrV5BWq.js";import"./index-Bn7NwETH.js";import"./CloudBadge-CNjyd2IF.js";/*! *****************************************************************************
Copyright (c) Microsoft Corporation. Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any Permission to use, copy, modify, and/or distribute this software for any

View File

@@ -1 +1 @@
import{d as B,o as N,a as V,c as I,b as n,t as c,f as e,w as t,h as g,v as y,j as u,k as r,C as M,l,D as T,G as j,H as q,I as z,J as A,u as D,z as H}from"./index-DT1mRj5t.js";import{a as L,_ as R}from"./_plugin-vue_export-helper-1Z-znrfZ.js";const E={class:"admin-layout"},G={class:"admin-sidebar"},J={class:"sidebar-brand"},W={class:"sidebar-brand-text"},F={class:"sidebar-version"},K={class:"admin-content"},O={class:"content-header"},P={class:"content-breadcrumb"},Q={class:"breadcrumb-current"},U={class:"content-actions"},X={class:"content-body"},Y=B({__name:"AdminLayout",setup(Z){const d=D(),f=H(),m=g(""),_=g(""),b={dashboard:"仪表盘","cloud-configs-toggle":"网盘设置及授权","cloud-configs-cleanup":"存储清理","sys-site":"网站设置","sys-services":"外部服务 & 缓存","sys-strategy":"性能配置","sys-password":"修改管理员密码","sys-notify":"消息推送","sys-daily-report":"每日汇报","save-records":"转存日志"},p=y(()=>{const o=f.name;return o==="admin-cloud-configs"?"cloud-configs-toggle":o==="admin-cleanup"?"cloud-configs-cleanup":o==="admin-system"?f.query.section||"sys-site":o==="admin-save-records"?"save-records":"dashboard"}),x=y(()=>b[p.value]||"仪表盘");function w(o){o==="dashboard"?d.push("/admin/dashboard"):o==="cloud-configs-toggle"?d.push("/admin/cloud-configs"):o==="cloud-configs-cleanup"?d.push("/admin/cleanup"):o.startsWith("sys-")?d.push({path:"/admin/system",query:{section:o}}):o==="save-records"?d.push("/admin/save-records"):o==="logout"&&(localStorage.removeItem("admin_token"),d.push("/admin/login"))}function h(){d.push("/")}return N(async()=>{try{const o=await L();m.value=o.site_name||""}catch{}try{const s=await(await fetch("/health")).json();_.value=s.version}catch{}}),(o,s)=>{const i=u("el-icon"),a=u("el-menu-item"),v=u("el-sub-menu"),C=u("el-menu"),k=u("el-button"),S=u("router-view");return V(),I("div",E,[n("aside",G,[n("div",J,[s[1]||(s[1]=n("div",{class:"sidebar-logo"},"☁️",-1)),n("div",W,[n("h2",null,c(m.value||"CloudSearch"),1),s[0]||(s[0]=n("p",null,"管理控制台",-1))])]),e(C,{"default-active":p.value,class:"sidebar-menu",onSelect:w},{default:t(()=>[e(a,{index:"dashboard"},{default:t(()=>[e(i,null,{default:t(()=>[e(r(M))]),_:1}),s[2]||(s[2]=n("span",null,"仪表盘",-1))]),_:1}),e(v,{index:"cloud-configs"},{title:t(()=>[e(i,null,{default:t(()=>[e(r(T))]),_:1}),s[3]||(s[3]=n("span",null,"网盘管理",-1))]),default:t(()=>[e(a,{index:"cloud-configs-toggle"},{default:t(()=>[...s[4]||(s[4]=[l("📋 设置及授权",-1)])]),_:1}),e(a,{index:"cloud-configs-cleanup"},{default:t(()=>[...s[5]||(s[5]=[l("🧹 存储清理",-1)])]),_:1})]),_:1}),e(v,{index:"system"},{title:t(()=>[e(i,null,{default:t(()=>[e(r(j))]),_:1}),s[6]||(s[6]=n("span",null,"系统设置",-1))]),default:t(()=>[e(a,{index:"sys-site"},{default:t(()=>[...s[7]||(s[7]=[l("🌐 网站设置",-1)])]),_:1}),e(a,{index:"sys-services"},{default:t(()=>[...s[8]||(s[8]=[l("🔗 外部服务 & 缓存",-1)])]),_:1}),e(a,{index:"sys-strategy"},{default:t(()=>[...s[9]||(s[9]=[l("⚡ 性能配置",-1)])]),_:1}),e(a,{index:"sys-password"},{default:t(()=>[...s[10]||(s[10]=[l("🔑 修改密码",-1)])]),_:1}),e(a,{index:"sys-notify"},{default:t(()=>[...s[11]||(s[11]=[l("📬 消息推送",-1)])]),_:1}),e(a,{index:"sys-daily-report"},{default:t(()=>[...s[12]||(s[12]=[l("📊 每日汇报",-1)])]),_:1})]),_:1}),e(a,{index:"save-records"},{default:t(()=>[e(i,null,{default:t(()=>[e(r(q))]),_:1}),s[13]||(s[13]=n("span",null,"转存日志",-1))]),_:1}),s[15]||(s[15]=n("div",{class:"sidebar-spacer"},null,-1)),n("div",F,"v"+c(_.value),1),e(a,{index:"logout"},{default:t(()=>[e(i,null,{default:t(()=>[e(r(z))]),_:1}),s[14]||(s[14]=n("span",null,"退出登录",-1))]),_:1})]),_:1},8,["default-active"])]),n("div",K,[n("header",O,[n("div",P,[n("span",Q,c(x.value),1)]),n("div",U,[e(k,{text:"",size:"small",onClick:h},{default:t(()=>[e(i,null,{default:t(()=>[e(r(A))]),_:1}),s[16]||(s[16]=l(" 返回前台 ",-1))]),_:1})])]),n("main",X,[e(S)])])])}}}),es=R(Y,[["__scopeId","data-v-647abf08"]]);export{es as default}; import{d as B,o as N,a as V,c as I,b as n,t as c,f as e,w as t,h as g,v as y,j as u,k as r,C as M,l,D as T,G as j,H as q,I as z,J as A,u as D,z as H}from"./index-hm1O9sxT.js";import{a as L,_ as R}from"./_plugin-vue_export-helper-D4DENoBS.js";const E={class:"admin-layout"},G={class:"admin-sidebar"},J={class:"sidebar-brand"},W={class:"sidebar-brand-text"},F={class:"sidebar-version"},K={class:"admin-content"},O={class:"content-header"},P={class:"content-breadcrumb"},Q={class:"breadcrumb-current"},U={class:"content-actions"},X={class:"content-body"},Y=B({__name:"AdminLayout",setup(Z){const d=D(),f=H(),m=g(""),_=g(""),b={dashboard:"仪表盘","cloud-configs-toggle":"网盘设置及授权","cloud-configs-cleanup":"存储清理","sys-site":"网站设置","sys-services":"外部服务 & 缓存","sys-strategy":"性能配置","sys-password":"修改管理员密码","sys-notify":"消息推送","sys-daily-report":"每日汇报","save-records":"转存日志"},p=y(()=>{const o=f.name;return o==="admin-cloud-configs"?"cloud-configs-toggle":o==="admin-cleanup"?"cloud-configs-cleanup":o==="admin-system"?f.query.section||"sys-site":o==="admin-save-records"?"save-records":"dashboard"}),x=y(()=>b[p.value]||"仪表盘");function w(o){o==="dashboard"?d.push("/admin/dashboard"):o==="cloud-configs-toggle"?d.push("/admin/cloud-configs"):o==="cloud-configs-cleanup"?d.push("/admin/cleanup"):o.startsWith("sys-")?d.push({path:"/admin/system",query:{section:o}}):o==="save-records"?d.push("/admin/save-records"):o==="logout"&&(localStorage.removeItem("admin_token"),d.push("/admin/login"))}function h(){d.push("/")}return N(async()=>{try{const o=await L();m.value=o.site_name||""}catch{}try{const s=await(await fetch("/health")).json();_.value=s.version}catch{}}),(o,s)=>{const i=u("el-icon"),a=u("el-menu-item"),v=u("el-sub-menu"),C=u("el-menu"),k=u("el-button"),S=u("router-view");return V(),I("div",E,[n("aside",G,[n("div",J,[s[1]||(s[1]=n("div",{class:"sidebar-logo"},"☁️",-1)),n("div",W,[n("h2",null,c(m.value||"CloudSearch"),1),s[0]||(s[0]=n("p",null,"管理控制台",-1))])]),e(C,{"default-active":p.value,class:"sidebar-menu",onSelect:w},{default:t(()=>[e(a,{index:"dashboard"},{default:t(()=>[e(i,null,{default:t(()=>[e(r(M))]),_:1}),s[2]||(s[2]=n("span",null,"仪表盘",-1))]),_:1}),e(v,{index:"cloud-configs"},{title:t(()=>[e(i,null,{default:t(()=>[e(r(T))]),_:1}),s[3]||(s[3]=n("span",null,"网盘管理",-1))]),default:t(()=>[e(a,{index:"cloud-configs-toggle"},{default:t(()=>[...s[4]||(s[4]=[l("📋 设置及授权",-1)])]),_:1}),e(a,{index:"cloud-configs-cleanup"},{default:t(()=>[...s[5]||(s[5]=[l("🧹 存储清理",-1)])]),_:1})]),_:1}),e(v,{index:"system"},{title:t(()=>[e(i,null,{default:t(()=>[e(r(j))]),_:1}),s[6]||(s[6]=n("span",null,"系统设置",-1))]),default:t(()=>[e(a,{index:"sys-site"},{default:t(()=>[...s[7]||(s[7]=[l("🌐 网站设置",-1)])]),_:1}),e(a,{index:"sys-services"},{default:t(()=>[...s[8]||(s[8]=[l("🔗 外部服务 & 缓存",-1)])]),_:1}),e(a,{index:"sys-strategy"},{default:t(()=>[...s[9]||(s[9]=[l("⚡ 性能配置",-1)])]),_:1}),e(a,{index:"sys-password"},{default:t(()=>[...s[10]||(s[10]=[l("🔑 修改密码",-1)])]),_:1}),e(a,{index:"sys-notify"},{default:t(()=>[...s[11]||(s[11]=[l("📬 消息推送",-1)])]),_:1}),e(a,{index:"sys-daily-report"},{default:t(()=>[...s[12]||(s[12]=[l("📊 每日汇报",-1)])]),_:1})]),_:1}),e(a,{index:"save-records"},{default:t(()=>[e(i,null,{default:t(()=>[e(r(q))]),_:1}),s[13]||(s[13]=n("span",null,"转存日志",-1))]),_:1}),s[15]||(s[15]=n("div",{class:"sidebar-spacer"},null,-1)),n("div",F,"v"+c(_.value),1),e(a,{index:"logout"},{default:t(()=>[e(i,null,{default:t(()=>[e(r(z))]),_:1}),s[14]||(s[14]=n("span",null,"退出登录",-1))]),_:1})]),_:1},8,["default-active"])]),n("div",K,[n("header",O,[n("div",P,[n("span",Q,c(x.value),1)]),n("div",U,[e(k,{text:"",size:"small",onClick:h},{default:t(()=>[e(i,null,{default:t(()=>[e(r(A))]),_:1}),s[16]||(s[16]=l(" 返回前台 ",-1))]),_:1})])]),n("main",X,[e(S)])])])}}}),es=R(Y,[["__scopeId","data-v-647abf08"]]);export{es as default};

View File

@@ -1 +1 @@
import{d as k,o as C,a as w,c as y,b as a,t as m,f as t,w as i,g as x,e as L,h as d,j as p,l as N,i as S,E as B}from"./index-DT1mRj5t.js";import{a as E,d as M,_ as U}from"./_plugin-vue_export-helper-1Z-znrfZ.js";const j={class:"admin-login-page"},q={class:"login-card"},A={class:"login-brand"},I={class:"login-title"},K={key:0,class:"error-msg"},R={class:"login-footer"},z=k({__name:"AdminLogin",setup(D){const f=d(),u=d(!1),c=d(""),g=d(""),v=d("");E().then(l=>{l.site_name&&(g.value=l.site_name)}).catch(()=>{});const s=S({username:"",password:""}),b={username:[{required:!0,message:"请输入用户名",trigger:"blur"}],password:[{required:!0,message:"请输入密码",trigger:"blur"}]};async function h(){var e,r,n;if(await((e=f.value)==null?void 0:e.validate().catch(()=>!1))){u.value=!0,c.value="";try{const o=await M(s.username,s.password);localStorage.setItem("admin_token",o.token),B.success("登录成功"),window.location.href="/admin"}catch(o){c.value=((n=(r=o==null?void 0:o.response)==null?void 0:r.data)==null?void 0:n.message)||(o==null?void 0:o.message)||"登录失败"}finally{u.value=!1}}}return C(async()=>{try{const e=await(await fetch("/health")).json();v.value=e.version||""}catch{}}),(l,e)=>{const r=p("el-input"),n=p("el-form-item"),o=p("el-button"),V=p("el-form");return w(),y("div",j,[e[4]||(e[4]=a("div",{class:"login-bg-pattern"},null,-1)),a("div",q,[a("div",A,[e[2]||(e[2]=a("div",{class:"login-logo"},"☁️",-1)),a("h1",I,m(g.value||"CloudSearch"),1),e[3]||(e[3]=a("p",{class:"login-subtitle"},"管理后台",-1))]),t(V,{ref_key:"formRef",ref:f,model:s,rules:b,"label-width":"0",size:"large",onKeyup:x(h,["enter"])},{default:i(()=>[t(n,{prop:"username"},{default:i(()=>[t(r,{modelValue:s.username,"onUpdate:modelValue":e[0]||(e[0]=_=>s.username=_),placeholder:"用户名","prefix-icon":"User"},null,8,["modelValue"])]),_:1}),t(n,{prop:"password"},{default:i(()=>[t(r,{modelValue:s.password,"onUpdate:modelValue":e[1]||(e[1]=_=>s.password=_),type:"password",placeholder:"密码","prefix-icon":"Lock","show-password":""},null,8,["modelValue"])]),_:1}),t(n,null,{default:i(()=>[t(o,{type:"primary",loading:u.value,class:"login-btn",onClick:h},{default:i(()=>[N(m(u.value?"登录中...":"登 录"),1)]),_:1},8,["loading"])]),_:1})]),_:1},8,["model"]),c.value?(w(),y("p",K,m(c.value),1)):L("",!0),a("p",R,"CloudSearch v"+m(v.value),1)])])}}}),G=U(z,[["__scopeId","data-v-bd0b6672"]]);export{G as default}; import{d as k,o as C,a as w,c as y,b as a,t as m,f as t,w as i,g as x,e as L,h as d,j as p,l as N,i as S,E as B}from"./index-hm1O9sxT.js";import{a as E,d as M,_ as U}from"./_plugin-vue_export-helper-D4DENoBS.js";const j={class:"admin-login-page"},q={class:"login-card"},A={class:"login-brand"},I={class:"login-title"},K={key:0,class:"error-msg"},R={class:"login-footer"},z=k({__name:"AdminLogin",setup(D){const f=d(),u=d(!1),c=d(""),g=d(""),v=d("");E().then(l=>{l.site_name&&(g.value=l.site_name)}).catch(()=>{});const s=S({username:"",password:""}),b={username:[{required:!0,message:"请输入用户名",trigger:"blur"}],password:[{required:!0,message:"请输入密码",trigger:"blur"}]};async function h(){var e,r,n;if(await((e=f.value)==null?void 0:e.validate().catch(()=>!1))){u.value=!0,c.value="";try{const o=await M(s.username,s.password);localStorage.setItem("admin_token",o.token),B.success("登录成功"),window.location.href="/admin"}catch(o){c.value=((n=(r=o==null?void 0:o.response)==null?void 0:r.data)==null?void 0:n.message)||(o==null?void 0:o.message)||"登录失败"}finally{u.value=!1}}}return C(async()=>{try{const e=await(await fetch("/health")).json();v.value=e.version||""}catch{}}),(l,e)=>{const r=p("el-input"),n=p("el-form-item"),o=p("el-button"),V=p("el-form");return w(),y("div",j,[e[4]||(e[4]=a("div",{class:"login-bg-pattern"},null,-1)),a("div",q,[a("div",A,[e[2]||(e[2]=a("div",{class:"login-logo"},"☁️",-1)),a("h1",I,m(g.value||"CloudSearch"),1),e[3]||(e[3]=a("p",{class:"login-subtitle"},"管理后台",-1))]),t(V,{ref_key:"formRef",ref:f,model:s,rules:b,"label-width":"0",size:"large",onKeyup:x(h,["enter"])},{default:i(()=>[t(n,{prop:"username"},{default:i(()=>[t(r,{modelValue:s.username,"onUpdate:modelValue":e[0]||(e[0]=_=>s.username=_),placeholder:"用户名","prefix-icon":"User"},null,8,["modelValue"])]),_:1}),t(n,{prop:"password"},{default:i(()=>[t(r,{modelValue:s.password,"onUpdate:modelValue":e[1]||(e[1]=_=>s.password=_),type:"password",placeholder:"密码","prefix-icon":"Lock","show-password":""},null,8,["modelValue"])]),_:1}),t(n,null,{default:i(()=>[t(o,{type:"primary",loading:u.value,class:"login-btn",onClick:h},{default:i(()=>[N(m(u.value?"登录中...":"登 录"),1)]),_:1},8,["loading"])]),_:1})]),_:1},8,["model"]),c.value?(w(),y("p",K,m(c.value),1)):L("",!0),a("p",R,"CloudSearch v"+m(v.value),1)])])}}}),G=U(z,[["__scopeId","data-v-bd0b6672"]]);export{G as default};

View File

@@ -1 +1 @@
import{C as s,b as a,a as n}from"./index-Bn7NwETH.js";import{d as l,a as t,c,p as d,k as o,e as r,l as u,t as m}from"./index-DT1mRj5t.js";import{_}from"./_plugin-vue_export-helper-1Z-znrfZ.js";const p=["src"],i=l({__name:"CloudBadge",props:{cloud_type:{},showIcon:{type:Boolean}},setup(e){return(C,y)=>(t(),c("span",{class:"cloud-badge",style:d({background:o(s)[e.cloud_type]})},[e.showIcon&&o(a)[e.cloud_type]?(t(),c("img",{key:0,src:o(a)[e.cloud_type],class:"badge-icon"},null,8,p)):r("",!0),u(" "+m(o(n)[e.cloud_type]),1)],4))}}),L=_(i,[["__scopeId","data-v-9106805f"]]);export{L as C}; import{C as s,b as a,a as n}from"./index-Bn7NwETH.js";import{d as l,a as t,c,p as d,k as o,e as r,l as u,t as m}from"./index-hm1O9sxT.js";import{_}from"./_plugin-vue_export-helper-D4DENoBS.js";const p=["src"],i=l({__name:"CloudBadge",props:{cloud_type:{},showIcon:{type:Boolean}},setup(e){return(C,y)=>(t(),c("span",{class:"cloud-badge",style:d({background:o(s)[e.cloud_type]})},[e.showIcon&&o(a)[e.cloud_type]?(t(),c("img",{key:0,src:o(a)[e.cloud_type],class:"badge-icon"},null,8,p)):r("",!0),u(" "+m(o(n)[e.cloud_type]),1)],4))}}),L=_(i,[["__scopeId","data-v-9106805f"]]);export{L as C};

View File

@@ -1,4 +1,4 @@
import{d as ke,o as L,m as ve,E as _,a as c,c as k,f as n,w as a,b as r,h as C,j as p,i as be,F as R,r as K,t as v,y as g,l as d,e as A,k as Ce,M as he,p as xe,n as H,K as Be,L as Te,v as h}from"./index-DT1mRj5t.js";import{a as x}from"./index-Bn7NwETH.js";import{c as we,k as Fe,h as Ne,l as G,t as Ve,u as P,m as ze,n as Se,o as $e,_ as Ue}from"./_plugin-vue_export-helper-1Z-znrfZ.js";import{C as De}from"./CloudBadge-BEGriYUm.js";const Ie={class:"cloud-config"},Me={class:"cloud-toggle-grid"},Oe=["src"],qe={class:"cloud-label"},Ee={class:"toolbar"},Le={key:0,class:"nickname-text"},Re={key:0,class:"promotion-text"},Ke={key:0,class:"uid-cell"},Ae={key:0,class:"verifying"},He={key:0,class:"storage-cell"},Ge={class:"storage-bar-wrap"},Pe={class:"storage-text"},je={class:"storage-used"},Je={class:"storage-total"},Qe={class:"storage-free"},We={key:0,class:"save-count"},Xe={style:{"line-height":"1.6"}},Ye={class:"cookie-tips-header"},Ze={class:"cookie-tips-title"},et=["innerHTML"],tt=ke({__name:"CloudConfig",setup(ot){const z=C([]),D=C(),F=C([]),B=C(!1),T=C(!1),b=C(null),l=be({cloud_type:"",nickname:"",promotion_account:"",is_transfer_enabled:!1,cookie:"",_verifying:!1,_storageUsed:"",_storageTotal:""}),j=h(()=>({cloud_type:[{required:!0,message:"请选择网盘类型",trigger:"change"}],nickname:[{required:!1,message:"请填写昵称(区分多个同类型网盘)",trigger:"blur"}],promotion_account:[{required:!0,message:"请填写推广平台及账号",trigger:"blur"}]})),J=h(()=>Object.entries(x)),Q=h(()=>{if(!l.cloud_type)return"请先选择网盘类型";const t=l.cloud_type;return t==="quark"||t==="baidu"?`请输入 ${x[t]||t} 的完整 Cookie`:b.value?"留空则保持原有":"输入完整 Cookie"}),W=h(()=>x[l.cloud_type]||l.cloud_type||""),X=h(()=>{const t=l.cloud_type;return t?{quark:`<li>在电脑上打开 <a href="https://pan.quark.cn" target="_blank">pan.quark.cn</a> 并登录你的夸克账号</li> import{d as ke,o as L,m as ve,E as _,a as c,c as k,f as n,w as a,b as r,h as C,j as p,i as be,F as R,r as K,t as v,y as g,l as d,e as A,k as Ce,M as he,p as xe,n as H,K as Be,L as Te,v as h}from"./index-hm1O9sxT.js";import{a as x}from"./index-Bn7NwETH.js";import{c as we,k as Fe,h as Ne,l as G,t as Ve,u as P,m as ze,n as Se,o as $e,_ as Ue}from"./_plugin-vue_export-helper-D4DENoBS.js";import{C as De}from"./CloudBadge-CNjyd2IF.js";const Ie={class:"cloud-config"},Me={class:"cloud-toggle-grid"},Oe=["src"],qe={class:"cloud-label"},Ee={class:"toolbar"},Le={key:0,class:"nickname-text"},Re={key:0,class:"promotion-text"},Ke={key:0,class:"uid-cell"},Ae={key:0,class:"verifying"},He={key:0,class:"storage-cell"},Ge={class:"storage-bar-wrap"},Pe={class:"storage-text"},je={class:"storage-used"},Je={class:"storage-total"},Qe={class:"storage-free"},We={key:0,class:"save-count"},Xe={style:{"line-height":"1.6"}},Ye={class:"cookie-tips-header"},Ze={class:"cookie-tips-title"},et=["innerHTML"],tt=ke({__name:"CloudConfig",setup(ot){const z=C([]),D=C(),F=C([]),B=C(!1),T=C(!1),b=C(null),l=be({cloud_type:"",nickname:"",promotion_account:"",is_transfer_enabled:!1,cookie:"",_verifying:!1,_storageUsed:"",_storageTotal:""}),j=h(()=>({cloud_type:[{required:!0,message:"请选择网盘类型",trigger:"change"}],nickname:[{required:!1,message:"请填写昵称(区分多个同类型网盘)",trigger:"blur"}],promotion_account:[{required:!0,message:"请填写推广平台及账号",trigger:"blur"}]})),J=h(()=>Object.entries(x)),Q=h(()=>{if(!l.cloud_type)return"请先选择网盘类型";const t=l.cloud_type;return t==="quark"||t==="baidu"?`请输入 ${x[t]||t} 的完整 Cookie`:b.value?"留空则保持原有":"输入完整 Cookie"}),W=h(()=>x[l.cloud_type]||l.cloud_type||""),X=h(()=>{const t=l.cloud_type;return t?{quark:`<li>在电脑上打开 <a href="https://pan.quark.cn" target="_blank">pan.quark.cn</a> 并登录你的夸克账号</li>
<li> <code>F12</code> <strong> (Network)</strong> </li> <li> <code>F12</code> <strong> (Network)</strong> </li>
<li>刷新页面在请求列表中点击任意一个请求 <code>account/info</code></li> <li>刷新页面在请求列表中点击任意一个请求 <code>account/info</code></li>
<li>在右侧 <strong>请求头 (Request Headers)</strong> <code>Cookie</code> </li> <li>在右侧 <strong>请求头 (Request Headers)</strong> <code>Cookie</code> </li>

View File

@@ -1 +0,0 @@
.el-card[data-v-1e3ebf03]{margin-bottom:20px}.el-card[data-v-1e3ebf03] .el-card__header{font-weight:600;font-size:15px}[data-v-1e3ebf03] .el-divider__text.is-left{left:0;padding-left:0}.form-tip[data-v-1e3ebf03]{font-size:12px;color:#909399;margin-top:4px}.fallback-upload-wrap[data-v-1e3ebf03]{display:flex;flex-direction:column;gap:12px}.fallback-upload-row[data-v-1e3ebf03]{display:flex;align-items:center;flex-wrap:wrap}.fallback-preview[data-v-1e3ebf03]{display:flex;align-items:center;gap:12px;flex-wrap:wrap}.fallback-preview img[data-v-1e3ebf03]{max-width:100%;height:auto;max-height:120px;border-radius:8px;border:1px solid var(--border-color);background:#f0f0f0;object-fit:contain}.strategy-grid[data-v-1e3ebf03]{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:12px 16px}.grid-cell[data-v-1e3ebf03]{display:flex;flex-direction:column;gap:4px}.strategy-section[data-v-1e3ebf03]{padding:0 4px}.field-block[data-v-1e3ebf03]{margin:12px 0}.field-label-row[data-v-1e3ebf03]{display:flex;align-items:center;gap:10px;flex-wrap:wrap}.field-label[data-v-1e3ebf03]{font-size:14px;font-weight:500;color:#303133;white-space:nowrap}.field-desc[data-v-1e3ebf03]{font-size:12px;color:#909399;margin:3px 0 0;line-height:1.5}.keyword-input-row[data-v-1e3ebf03]{display:flex;gap:8px;flex:1;min-width:200px}.tag-list[data-v-1e3ebf03]{display:flex;flex-wrap:wrap;gap:6px;margin-top:8px}.tag-empty[data-v-1e3ebf03]{font-size:13px;color:#c0c4cc;margin-top:8px}.filter-rule-help[data-v-1e3ebf03]{margin-top:8px;padding:10px 12px;background:#f8f9fa;border-radius:8px;border:1px solid #e8e8e8}.filter-rule-help .help-title[data-v-1e3ebf03]{font-weight:600;font-size:13px;margin:8px 0 4px;color:#333}.filter-rule-help .help-title[data-v-1e3ebf03]:first-child{margin-top:0}.filter-rule-help .help-row[data-v-1e3ebf03]{font-size:12px;color:#555;margin:3px 0;line-height:1.6}.filter-rule-help .help-row code[data-v-1e3ebf03]{background:#eef1f5;padding:1px 5px;border-radius:3px;font-size:11px;font-family:monospace}.filter-rules-help[data-v-1e3ebf03]{margin-top:8px;padding:12px;background:#f8f9fa;border-radius:8px;border:1px solid #e8e8e8}.help-title[data-v-1e3ebf03]{font-weight:600;font-size:13px;margin:10px 0 6px;color:#333}.help-title[data-v-1e3ebf03]:first-child{margin-top:0}.help-row[data-v-1e3ebf03]{font-size:12px;color:#555;margin:3px 0;line-height:1.6}.help-row code[data-v-1e3ebf03]{background:#eef1f5;padding:1px 5px;border-radius:3px;font-size:11px;font-family:monospace}.help-sample[data-v-1e3ebf03]{background:#1e1e1e;color:#d4d4d4;padding:10px 14px;border-radius:6px;font-size:12px;line-height:1.6;overflow-x:auto;white-space:pre;margin:6px 0 0;font-family:monospace}.help-preview-row[data-v-1e3ebf03]{font-size:13px;margin:4px 0;display:flex;align-items:center;gap:6px}.help-preview-label[data-v-1e3ebf03]{color:#888;min-width:70px;font-size:12px}.help-preview-original[data-v-1e3ebf03]{color:#e74c3c}.help-preview-filtered[data-v-1e3ebf03]{color:#27ae60;font-weight:500}.filter-input-row[data-v-1e3ebf03]{display:flex;gap:8px;width:100%;margin-bottom:8px}.filter-tag-list[data-v-1e3ebf03]{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:8px}.filter-empty[data-v-1e3ebf03]{font-size:13px;color:#c0c4cc;padding:8px 0;margin-bottom:8px}.db-status-grid[data-v-1e3ebf03]{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:12px;margin-top:8px}.db-stat-item[data-v-1e3ebf03]{background:#f8f9fa;border-radius:10px;padding:16px 12px;text-align:center;border:1px solid #eee;transition:transform .15s,box-shadow .15s}.db-stat-item[data-v-1e3ebf03]:hover{transform:translateY(-2px);box-shadow:0 4px 12px #0000000f}.db-stat-value[data-v-1e3ebf03]{white-space:nowrap;font-size:24px;font-weight:700;color:#303133;margin-bottom:4px}.db-stat-value.text-success[data-v-1e3ebf03]{color:#67c23a}.db-stat-value.text-warning[data-v-1e3ebf03]{color:#e6a23c}.db-stat-label[data-v-1e3ebf03]{font-size:12px;color:#909399}@media (max-width: 900px){.strategy-grid[data-v-1e3ebf03]{grid-template-columns:1fr 1fr}}@media (max-width: 600px){.strategy-grid[data-v-1e3ebf03]{grid-template-columns:1fr}}.pansou-status-grid[data-v-1e3ebf03]{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:12px;margin-top:8px}.status-dot[data-v-1e3ebf03]{width:8px;height:8px;border-radius:50%;display:inline-block}.dot-ok[data-v-1e3ebf03]{background:#67c23a}.dot-err[data-v-1e3ebf03]{background:#f56c6c}

View File

@@ -0,0 +1 @@
.el-card[data-v-21262a13]{margin-bottom:20px}.el-card[data-v-21262a13] .el-card__header{font-weight:600;font-size:15px}[data-v-21262a13] .el-divider__text.is-left{left:0;padding-left:0}.form-tip[data-v-21262a13]{font-size:12px;color:#909399;margin-top:4px}.fallback-upload-wrap[data-v-21262a13]{display:flex;flex-direction:column;gap:12px}.fallback-upload-row[data-v-21262a13]{display:flex;align-items:center;flex-wrap:wrap}.fallback-preview[data-v-21262a13]{display:flex;align-items:center;gap:12px;flex-wrap:wrap}.fallback-preview img[data-v-21262a13]{max-width:100%;height:auto;max-height:120px;border-radius:8px;border:1px solid var(--border-color);background:#f0f0f0;object-fit:contain}.strategy-grid[data-v-21262a13]{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:12px 16px}.grid-cell[data-v-21262a13]{display:flex;flex-direction:column;gap:4px}.strategy-section[data-v-21262a13]{padding:0 4px}.field-block[data-v-21262a13]{margin:12px 0}.field-label-row[data-v-21262a13]{display:flex;align-items:center;gap:10px;flex-wrap:wrap}.field-label[data-v-21262a13]{font-size:14px;font-weight:500;color:#303133;white-space:nowrap}.field-desc[data-v-21262a13]{font-size:12px;color:#909399;margin:3px 0 0;line-height:1.5}.keyword-input-row[data-v-21262a13]{display:flex;gap:8px;flex:1;min-width:200px}.tag-list[data-v-21262a13]{display:flex;flex-wrap:wrap;gap:6px;margin-top:8px}.tag-empty[data-v-21262a13]{font-size:13px;color:#c0c4cc;margin-top:8px}.filter-rule-help[data-v-21262a13]{margin-top:8px;padding:10px 12px;background:#f8f9fa;border-radius:8px;border:1px solid #e8e8e8}.filter-rule-help .help-title[data-v-21262a13]{font-weight:600;font-size:13px;margin:8px 0 4px;color:#333}.filter-rule-help .help-title[data-v-21262a13]:first-child{margin-top:0}.filter-rule-help .help-row[data-v-21262a13]{font-size:12px;color:#555;margin:3px 0;line-height:1.6}.filter-rule-help .help-row code[data-v-21262a13]{background:#eef1f5;padding:1px 5px;border-radius:3px;font-size:11px;font-family:monospace}.filter-rules-help[data-v-21262a13]{margin-top:8px;padding:12px;background:#f8f9fa;border-radius:8px;border:1px solid #e8e8e8}.help-title[data-v-21262a13]{font-weight:600;font-size:13px;margin:10px 0 6px;color:#333}.help-title[data-v-21262a13]:first-child{margin-top:0}.help-row[data-v-21262a13]{font-size:12px;color:#555;margin:3px 0;line-height:1.6}.help-row code[data-v-21262a13]{background:#eef1f5;padding:1px 5px;border-radius:3px;font-size:11px;font-family:monospace}.help-sample[data-v-21262a13]{background:#1e1e1e;color:#d4d4d4;padding:10px 14px;border-radius:6px;font-size:12px;line-height:1.6;overflow-x:auto;white-space:pre;margin:6px 0 0;font-family:monospace}.help-preview-row[data-v-21262a13]{font-size:13px;margin:4px 0;display:flex;align-items:center;gap:6px}.help-preview-label[data-v-21262a13]{color:#888;min-width:70px;font-size:12px}.help-preview-original[data-v-21262a13]{color:#e74c3c}.help-preview-filtered[data-v-21262a13]{color:#27ae60;font-weight:500}.filter-input-row[data-v-21262a13]{display:flex;gap:8px;width:100%;margin-bottom:8px}.filter-tag-list[data-v-21262a13]{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:8px}.filter-empty[data-v-21262a13]{font-size:13px;color:#c0c4cc;padding:8px 0;margin-bottom:8px}.db-status-grid[data-v-21262a13]{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:12px;margin-top:8px}.db-stat-item[data-v-21262a13]{background:#f8f9fa;border-radius:10px;padding:16px 12px;text-align:center;border:1px solid #eee;transition:transform .15s,box-shadow .15s}.db-stat-item[data-v-21262a13]:hover{transform:translateY(-2px);box-shadow:0 4px 12px #0000000f}.db-stat-value[data-v-21262a13]{white-space:nowrap;font-size:24px;font-weight:700;color:#303133;margin-bottom:4px}.db-stat-value.text-success[data-v-21262a13]{color:#67c23a}.db-stat-value.text-warning[data-v-21262a13]{color:#e6a23c}.db-stat-label[data-v-21262a13]{font-size:12px;color:#909399}@media (max-width: 900px){.strategy-grid[data-v-21262a13]{grid-template-columns:1fr 1fr}}@media (max-width: 600px){.strategy-grid[data-v-21262a13]{grid-template-columns:1fr}}.pansou-status-grid[data-v-21262a13]{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:12px;margin-top:8px}.status-dot[data-v-21262a13]{width:8px;height:8px;border-radius:50%;display:inline-block}.dot-ok[data-v-21262a13]{background:#67c23a}.dot-err[data-v-21262a13]{background:#f56c6c}.event-card.active[data-v-21262a13]{border-color:var(--el-color-primary)!important;background:var(--el-color-primary-light-9)}.event-card[data-v-21262a13]{cursor:default}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -21,7 +21,7 @@
} }
})(); })();
</script> </script>
<script type="module" crossorigin src="/assets/index-DT1mRj5t.js"></script> <script type="module" crossorigin src="/assets/index-hm1O9sxT.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-Ekbe64zQ.css"> <link rel="stylesheet" crossorigin href="/assets/index-Ekbe64zQ.css">
</head> </head>
<body> <body>

View File

@@ -346,9 +346,10 @@ export async function getAllNotifierProviders(): Promise<Record<string, { name:
export async function testNotifyChannel( export async function testNotifyChannel(
channelType: string, channelType: string,
configId?: number configId?: number,
params?: Record<string, any>
): Promise<{ success: boolean; message: string }> { ): Promise<{ success: boolean; message: string }> {
const { data } = await api.post('/admin/notify/test', { channelType, configId }) const { data } = await api.post('/admin/notify/test', { channelType, configId, params })
return data return data
} }

View File

@@ -158,21 +158,18 @@
</div> </div>
</el-form-item> </el-form-item>
<el-form-item label="IP 归属地查询"> <el-form-item label="IP 归属地查询">
<div style="display: flex; gap: 8px; align-items: center; width: 100%;"> <div style="display:flex; flex-direction:column; gap:8px; width:100%;">
<el-input <el-select v-model="configs.ip_geo_provider" placeholder="选择接口" style="max-width:260px">
v-model="configs.ip_geo_api_url" <el-option label="接口盒子 (apihz.cn)" value="apihz" />
placeholder="https://cn.apihz.cn/api/ip/chaapi.php?id=xxx&key=***&ip={ip}&td=0" </el-select>
style="max-width: 360px" <template v-if="configs.ip_geo_provider === 'apihz'">
/> <el-input v-model="configs.ip_geo_api_id" placeholder="API ID10014356" style="max-width:360px" />
<el-button type="primary" :loading="ipGeoTesting" @click="handleTestIpGeo" size="default" style="width: 100px;"> <el-input v-model="configs.ip_geo_api_key" placeholder="API Key" type="password" show-password style="max-width:360px" />
</template>
<el-button type="primary" :loading="ipGeoTesting" @click="handleTestIpGeo" size="small" style="width:100px">
{{ ipGeoTesting ? "测试中..." : "验证接口" }} {{ ipGeoTesting ? "测试中..." : "验证接口" }}
</el-button> </el-button>
</div> <div class="form-tip">用于查询用户 IP 归属地搜索/转存记录中显示留空则不做 IP 归属地查询</div>
<div class="form-tip" style="margin-top: 4px;">
IP 归属地查询 API 地址<code>{ip}</code> 会被替换为实际 IP
</div>
<div style="color: var(--el-color-warning); font-size: 13px; margin-top: 2px; width: 100%;">
当前仅支持 接口盒子(apihz.cn) 格式
</div> </div>
</el-form-item> </el-form-item>
<el-divider content-position="left">Redis 缓存</el-divider> <el-divider content-position="left">Redis 缓存</el-divider>
@@ -522,24 +519,52 @@
</div> </div>
</div> </div>
<el-divider content-position="left">全局事件开关</el-divider> <el-divider content-position="left">全局事件开关</el-divider>
<div style="display:flex; flex-direction:column; gap:6px;"> <div style="display:grid; grid-template-columns:repeat(2,1fr); gap:10px;">
<div style="display:flex; align-items:center; gap:8px;"> <div class="event-card" :class="{ active: globalNotifyForm.events.on_save_success }" style="padding:10px 14px; border-radius:8px; border:1px solid var(--el-border-color-light); transition:all .2s;">
<el-switch v-model="globalNotifyForm.events.on_save_success" active-text="转存成功" /> <div style="display:flex; align-items:center; justify-content:space-between;">
<span style="display:flex; align-items:center; gap:6px; font-size:14px; font-weight:500;">
<span></span> 转存成功
</span>
<el-switch v-model="globalNotifyForm.events.on_save_success" size="small" />
</div>
<div style="margin-top:4px;">
<el-button size="small" text type="primary" @click="openTemplateEditor('on_save_success')"> 编辑模板</el-button> <el-button size="small" text type="primary" @click="openTemplateEditor('on_save_success')"> 编辑模板</el-button>
</div> </div>
<div style="display:flex; align-items:center; gap:8px;"> </div>
<el-switch v-model="globalNotifyForm.events.on_save_fail" active-text="转存失败" /> <div class="event-card" :class="{ active: globalNotifyForm.events.on_save_fail }" style="padding:10px 14px; border-radius:8px; border:1px solid var(--el-border-color-light); transition:all .2s;">
<div style="display:flex; align-items:center; justify-content:space-between;">
<span style="display:flex; align-items:center; gap:6px; font-size:14px; font-weight:500;">
<span></span> 转存失败
</span>
<el-switch v-model="globalNotifyForm.events.on_save_fail" size="small" />
</div>
<div style="margin-top:4px;">
<el-button size="small" text type="primary" @click="openTemplateEditor('on_save_fail')"> 编辑模板</el-button> <el-button size="small" text type="primary" @click="openTemplateEditor('on_save_fail')"> 编辑模板</el-button>
</div> </div>
<div style="display:flex; align-items:center; gap:8px;"> </div>
<el-switch v-model="globalNotifyForm.events.on_cookie_expire" active-text="Cookie过期" /> <div class="event-card" :class="{ active: globalNotifyForm.events.on_cookie_expire }" style="padding:10px 14px; border-radius:8px; border:1px solid var(--el-border-color-light); transition:all .2s;">
<div style="display:flex; align-items:center; justify-content:space-between;">
<span style="display:flex; align-items:center; gap:6px; font-size:14px; font-weight:500;">
<span>🍪</span> Cookie过期
</span>
<el-switch v-model="globalNotifyForm.events.on_cookie_expire" size="small" />
</div>
<div style="margin-top:4px;">
<el-button size="small" text type="primary" @click="openTemplateEditor('on_cookie_expire')"> 编辑模板</el-button> <el-button size="small" text type="primary" @click="openTemplateEditor('on_cookie_expire')"> 编辑模板</el-button>
</div> </div>
<div style="display:flex; align-items:center; gap:8px;"> </div>
<el-switch v-model="globalNotifyForm.events.on_cleanup" active-text="清理完成" /> <div class="event-card" :class="{ active: globalNotifyForm.events.on_cleanup }" style="padding:10px 14px; border-radius:8px; border:1px solid var(--el-border-color-light); transition:all .2s;">
<div style="display:flex; align-items:center; justify-content:space-between;">
<span style="display:flex; align-items:center; gap:6px; font-size:14px; font-weight:500;">
<span>🧹</span> 清理完成
</span>
<el-switch v-model="globalNotifyForm.events.on_cleanup" size="small" />
</div>
<div style="margin-top:4px;">
<el-button size="small" text type="primary" @click="openTemplateEditor('on_cleanup')"> 编辑模板</el-button> <el-button size="small" text type="primary" @click="openTemplateEditor('on_cleanup')"> 编辑模板</el-button>
</div> </div>
</div> </div>
</div>
<div class="form-tip" style="margin-top:8px;">全局推送作为兜底通道设置了推送用户的网盘配置走用户推送未设置的走全局推送</div> <div class="form-tip" style="margin-top:8px;">全局推送作为兜底通道设置了推送用户的网盘配置走用户推送未设置的走全局推送</div>
</el-form> </el-form>
</div> </div>
@@ -683,6 +708,12 @@
<el-switch v-model="dailyReportForm.includeUsers" active-text="用户数" :disabled="!dailyReportForm.enabled" /> <el-switch v-model="dailyReportForm.includeUsers" active-text="用户数" :disabled="!dailyReportForm.enabled" />
</div> </div>
</el-form-item> </el-form-item>
<el-form-item label="推送通道">
<el-select v-model="dailyReportForm.channels" multiple placeholder="留空=全部全局通道" :disabled="!dailyReportForm.enabled" style="width:100%;max-width:480px">
<el-option v-for="(np, nk) in notifyProviders" :key="nk" :label="np.label" :value="nk" />
</el-select>
<div class="form-tip">留空则发送至全部已启用的全局通道</div>
</el-form-item>
<el-form-item label="上次发送"> <el-form-item label="上次发送">
<span>{{ dailyReportLastRun || '从未发送' }}</span> <span>{{ dailyReportLastRun || '从未发送' }}</span>
</el-form-item> </el-form-item>
@@ -812,6 +843,7 @@ const dailyReportForm = reactive({
includeSaves: true, includeSaves: true,
includeStorage: true, includeStorage: true,
includeUsers: true, includeUsers: true,
channels: [] as string[],
}) })
const dailyReportPreviewing = ref(false) const dailyReportPreviewing = ref(false)
const dailyReportSending = ref(false) const dailyReportSending = ref(false)
@@ -1187,7 +1219,12 @@ async function testGlobalChannel(channelName: string) {
if (!ch || !ch._enabled) return if (!ch || !ch._enabled) return
ch._testing = true ch._testing = true
try { try {
const result = await testNotifyChannel(channelName) // 过滤掉前端标记字段,只传实际参数
const params: Record<string, any> = {}
for (const [k, v] of Object.entries(ch)) {
if (!k.startsWith('_')) params[k] = v
}
const result = await testNotifyChannel(channelName, undefined, params)
if (result.success) { if (result.success) {
ElMessage.success(result.message) ElMessage.success(result.message)
} else { } else {
@@ -1407,12 +1444,12 @@ async function handleTestProxy() {
async function handleTestIpGeo() { async function handleTestIpGeo() {
ipGeoTesting.value = true ipGeoTesting.value = true
try { try {
const url = String(configs.ip_geo_api_url || "") const apiId = String(configs.ip_geo_api_id || "")
if (!url) { if (!apiId) {
ElMessage.warning("请先输入 IP 归属地查询 API 地址") ElMessage.warning("请先输入 API ID")
return return
} }
const result = await testExternalService({ type: "ip_geo", url }) const result = await testExternalService({ type: "ip_geo", url: apiId })
if (result.ok) { if (result.ok) {
ElMessage.success("✅ IP 归属地接口可用 — " + result.info) ElMessage.success("✅ IP 归属地接口可用 — " + result.info)
} else { } else {
@@ -1993,5 +2030,14 @@ async function handleRemoveLogo() {
.dot-ok { background: #67c23a; } .dot-ok { background: #67c23a; }
.dot-err { background: #f56c6c; } .dot-err { background: #f56c6c; }
/* 事件开关卡片高亮 */
.event-card.active {
border-color: var(--el-color-primary) !important;
background: var(--el-color-primary-light-9);
}
.event-card {
cursor: default;
}
</style> </style>

View File

@@ -1,4 +1,4 @@
import{x as qu,m as $_,h as Ce,B as Hg,d as q_,o as K_,a as Tt,c as Nt,K as ml,L as _l,b as Q,F as Vr,r as Gr,f as $t,w as qt,e as Oe,v as Ka,j as Hr,i as Q_,t as wt,n as Nc,y as Ei,l as zc,p as J_,E as j_,u as t1}from"./index-DT1mRj5t.js";import{a as e1,h as r1,c as i1,i as n1,j as a1,t as o1,_ as s1}from"./_plugin-vue_export-helper-1Z-znrfZ.js";import l1 from"./CloudConfig-CgJ44DuS.js";import u1 from"./SystemConfig-BeJ_jebO.js";import f1 from"./SaveRecords-CZh2kRyW.js";import"./index-Bn7NwETH.js";import"./CloudBadge-BEGriYUm.js";/*! ***************************************************************************** import{x as qu,m as $_,h as Ce,B as Hg,d as q_,o as K_,a as Tt,c as Nt,K as ml,L as _l,b as Q,F as Vr,r as Gr,f as $t,w as qt,e as Oe,v as Ka,j as Hr,i as Q_,t as wt,n as Nc,y as Ei,l as zc,p as J_,E as j_,u as t1}from"./index-hm1O9sxT.js";import{a as e1,h as r1,c as i1,i as n1,j as a1,t as o1,_ as s1}from"./_plugin-vue_export-helper-D4DENoBS.js";import l1 from"./CloudConfig-Dl6za0gm.js";import u1 from"./SystemConfig-CwYIM6EH.js";import f1 from"./SaveRecords-DQrV5BWq.js";import"./index-Bn7NwETH.js";import"./CloudBadge-CNjyd2IF.js";/*! *****************************************************************************
Copyright (c) Microsoft Corporation. Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any Permission to use, copy, modify, and/or distribute this software for any

View File

@@ -1 +1 @@
import{d as B,o as N,a as V,c as I,b as n,t as c,f as e,w as t,h as g,v as y,j as u,k as r,C as M,l,D as T,G as j,H as q,I as z,J as A,u as D,z as H}from"./index-DT1mRj5t.js";import{a as L,_ as R}from"./_plugin-vue_export-helper-1Z-znrfZ.js";const E={class:"admin-layout"},G={class:"admin-sidebar"},J={class:"sidebar-brand"},W={class:"sidebar-brand-text"},F={class:"sidebar-version"},K={class:"admin-content"},O={class:"content-header"},P={class:"content-breadcrumb"},Q={class:"breadcrumb-current"},U={class:"content-actions"},X={class:"content-body"},Y=B({__name:"AdminLayout",setup(Z){const d=D(),f=H(),m=g(""),_=g(""),b={dashboard:"仪表盘","cloud-configs-toggle":"网盘设置及授权","cloud-configs-cleanup":"存储清理","sys-site":"网站设置","sys-services":"外部服务 & 缓存","sys-strategy":"性能配置","sys-password":"修改管理员密码","sys-notify":"消息推送","sys-daily-report":"每日汇报","save-records":"转存日志"},p=y(()=>{const o=f.name;return o==="admin-cloud-configs"?"cloud-configs-toggle":o==="admin-cleanup"?"cloud-configs-cleanup":o==="admin-system"?f.query.section||"sys-site":o==="admin-save-records"?"save-records":"dashboard"}),x=y(()=>b[p.value]||"仪表盘");function w(o){o==="dashboard"?d.push("/admin/dashboard"):o==="cloud-configs-toggle"?d.push("/admin/cloud-configs"):o==="cloud-configs-cleanup"?d.push("/admin/cleanup"):o.startsWith("sys-")?d.push({path:"/admin/system",query:{section:o}}):o==="save-records"?d.push("/admin/save-records"):o==="logout"&&(localStorage.removeItem("admin_token"),d.push("/admin/login"))}function h(){d.push("/")}return N(async()=>{try{const o=await L();m.value=o.site_name||""}catch{}try{const s=await(await fetch("/health")).json();_.value=s.version}catch{}}),(o,s)=>{const i=u("el-icon"),a=u("el-menu-item"),v=u("el-sub-menu"),C=u("el-menu"),k=u("el-button"),S=u("router-view");return V(),I("div",E,[n("aside",G,[n("div",J,[s[1]||(s[1]=n("div",{class:"sidebar-logo"},"☁️",-1)),n("div",W,[n("h2",null,c(m.value||"CloudSearch"),1),s[0]||(s[0]=n("p",null,"管理控制台",-1))])]),e(C,{"default-active":p.value,class:"sidebar-menu",onSelect:w},{default:t(()=>[e(a,{index:"dashboard"},{default:t(()=>[e(i,null,{default:t(()=>[e(r(M))]),_:1}),s[2]||(s[2]=n("span",null,"仪表盘",-1))]),_:1}),e(v,{index:"cloud-configs"},{title:t(()=>[e(i,null,{default:t(()=>[e(r(T))]),_:1}),s[3]||(s[3]=n("span",null,"网盘管理",-1))]),default:t(()=>[e(a,{index:"cloud-configs-toggle"},{default:t(()=>[...s[4]||(s[4]=[l("📋 设置及授权",-1)])]),_:1}),e(a,{index:"cloud-configs-cleanup"},{default:t(()=>[...s[5]||(s[5]=[l("🧹 存储清理",-1)])]),_:1})]),_:1}),e(v,{index:"system"},{title:t(()=>[e(i,null,{default:t(()=>[e(r(j))]),_:1}),s[6]||(s[6]=n("span",null,"系统设置",-1))]),default:t(()=>[e(a,{index:"sys-site"},{default:t(()=>[...s[7]||(s[7]=[l("🌐 网站设置",-1)])]),_:1}),e(a,{index:"sys-services"},{default:t(()=>[...s[8]||(s[8]=[l("🔗 外部服务 & 缓存",-1)])]),_:1}),e(a,{index:"sys-strategy"},{default:t(()=>[...s[9]||(s[9]=[l("⚡ 性能配置",-1)])]),_:1}),e(a,{index:"sys-password"},{default:t(()=>[...s[10]||(s[10]=[l("🔑 修改密码",-1)])]),_:1}),e(a,{index:"sys-notify"},{default:t(()=>[...s[11]||(s[11]=[l("📬 消息推送",-1)])]),_:1}),e(a,{index:"sys-daily-report"},{default:t(()=>[...s[12]||(s[12]=[l("📊 每日汇报",-1)])]),_:1})]),_:1}),e(a,{index:"save-records"},{default:t(()=>[e(i,null,{default:t(()=>[e(r(q))]),_:1}),s[13]||(s[13]=n("span",null,"转存日志",-1))]),_:1}),s[15]||(s[15]=n("div",{class:"sidebar-spacer"},null,-1)),n("div",F,"v"+c(_.value),1),e(a,{index:"logout"},{default:t(()=>[e(i,null,{default:t(()=>[e(r(z))]),_:1}),s[14]||(s[14]=n("span",null,"退出登录",-1))]),_:1})]),_:1},8,["default-active"])]),n("div",K,[n("header",O,[n("div",P,[n("span",Q,c(x.value),1)]),n("div",U,[e(k,{text:"",size:"small",onClick:h},{default:t(()=>[e(i,null,{default:t(()=>[e(r(A))]),_:1}),s[16]||(s[16]=l(" 返回前台 ",-1))]),_:1})])]),n("main",X,[e(S)])])])}}}),es=R(Y,[["__scopeId","data-v-647abf08"]]);export{es as default}; import{d as B,o as N,a as V,c as I,b as n,t as c,f as e,w as t,h as g,v as y,j as u,k as r,C as M,l,D as T,G as j,H as q,I as z,J as A,u as D,z as H}from"./index-hm1O9sxT.js";import{a as L,_ as R}from"./_plugin-vue_export-helper-D4DENoBS.js";const E={class:"admin-layout"},G={class:"admin-sidebar"},J={class:"sidebar-brand"},W={class:"sidebar-brand-text"},F={class:"sidebar-version"},K={class:"admin-content"},O={class:"content-header"},P={class:"content-breadcrumb"},Q={class:"breadcrumb-current"},U={class:"content-actions"},X={class:"content-body"},Y=B({__name:"AdminLayout",setup(Z){const d=D(),f=H(),m=g(""),_=g(""),b={dashboard:"仪表盘","cloud-configs-toggle":"网盘设置及授权","cloud-configs-cleanup":"存储清理","sys-site":"网站设置","sys-services":"外部服务 & 缓存","sys-strategy":"性能配置","sys-password":"修改管理员密码","sys-notify":"消息推送","sys-daily-report":"每日汇报","save-records":"转存日志"},p=y(()=>{const o=f.name;return o==="admin-cloud-configs"?"cloud-configs-toggle":o==="admin-cleanup"?"cloud-configs-cleanup":o==="admin-system"?f.query.section||"sys-site":o==="admin-save-records"?"save-records":"dashboard"}),x=y(()=>b[p.value]||"仪表盘");function w(o){o==="dashboard"?d.push("/admin/dashboard"):o==="cloud-configs-toggle"?d.push("/admin/cloud-configs"):o==="cloud-configs-cleanup"?d.push("/admin/cleanup"):o.startsWith("sys-")?d.push({path:"/admin/system",query:{section:o}}):o==="save-records"?d.push("/admin/save-records"):o==="logout"&&(localStorage.removeItem("admin_token"),d.push("/admin/login"))}function h(){d.push("/")}return N(async()=>{try{const o=await L();m.value=o.site_name||""}catch{}try{const s=await(await fetch("/health")).json();_.value=s.version}catch{}}),(o,s)=>{const i=u("el-icon"),a=u("el-menu-item"),v=u("el-sub-menu"),C=u("el-menu"),k=u("el-button"),S=u("router-view");return V(),I("div",E,[n("aside",G,[n("div",J,[s[1]||(s[1]=n("div",{class:"sidebar-logo"},"☁️",-1)),n("div",W,[n("h2",null,c(m.value||"CloudSearch"),1),s[0]||(s[0]=n("p",null,"管理控制台",-1))])]),e(C,{"default-active":p.value,class:"sidebar-menu",onSelect:w},{default:t(()=>[e(a,{index:"dashboard"},{default:t(()=>[e(i,null,{default:t(()=>[e(r(M))]),_:1}),s[2]||(s[2]=n("span",null,"仪表盘",-1))]),_:1}),e(v,{index:"cloud-configs"},{title:t(()=>[e(i,null,{default:t(()=>[e(r(T))]),_:1}),s[3]||(s[3]=n("span",null,"网盘管理",-1))]),default:t(()=>[e(a,{index:"cloud-configs-toggle"},{default:t(()=>[...s[4]||(s[4]=[l("📋 设置及授权",-1)])]),_:1}),e(a,{index:"cloud-configs-cleanup"},{default:t(()=>[...s[5]||(s[5]=[l("🧹 存储清理",-1)])]),_:1})]),_:1}),e(v,{index:"system"},{title:t(()=>[e(i,null,{default:t(()=>[e(r(j))]),_:1}),s[6]||(s[6]=n("span",null,"系统设置",-1))]),default:t(()=>[e(a,{index:"sys-site"},{default:t(()=>[...s[7]||(s[7]=[l("🌐 网站设置",-1)])]),_:1}),e(a,{index:"sys-services"},{default:t(()=>[...s[8]||(s[8]=[l("🔗 外部服务 & 缓存",-1)])]),_:1}),e(a,{index:"sys-strategy"},{default:t(()=>[...s[9]||(s[9]=[l("⚡ 性能配置",-1)])]),_:1}),e(a,{index:"sys-password"},{default:t(()=>[...s[10]||(s[10]=[l("🔑 修改密码",-1)])]),_:1}),e(a,{index:"sys-notify"},{default:t(()=>[...s[11]||(s[11]=[l("📬 消息推送",-1)])]),_:1}),e(a,{index:"sys-daily-report"},{default:t(()=>[...s[12]||(s[12]=[l("📊 每日汇报",-1)])]),_:1})]),_:1}),e(a,{index:"save-records"},{default:t(()=>[e(i,null,{default:t(()=>[e(r(q))]),_:1}),s[13]||(s[13]=n("span",null,"转存日志",-1))]),_:1}),s[15]||(s[15]=n("div",{class:"sidebar-spacer"},null,-1)),n("div",F,"v"+c(_.value),1),e(a,{index:"logout"},{default:t(()=>[e(i,null,{default:t(()=>[e(r(z))]),_:1}),s[14]||(s[14]=n("span",null,"退出登录",-1))]),_:1})]),_:1},8,["default-active"])]),n("div",K,[n("header",O,[n("div",P,[n("span",Q,c(x.value),1)]),n("div",U,[e(k,{text:"",size:"small",onClick:h},{default:t(()=>[e(i,null,{default:t(()=>[e(r(A))]),_:1}),s[16]||(s[16]=l(" 返回前台 ",-1))]),_:1})])]),n("main",X,[e(S)])])])}}}),es=R(Y,[["__scopeId","data-v-647abf08"]]);export{es as default};

View File

@@ -1 +1 @@
import{d as k,o as C,a as w,c as y,b as a,t as m,f as t,w as i,g as x,e as L,h as d,j as p,l as N,i as S,E as B}from"./index-DT1mRj5t.js";import{a as E,d as M,_ as U}from"./_plugin-vue_export-helper-1Z-znrfZ.js";const j={class:"admin-login-page"},q={class:"login-card"},A={class:"login-brand"},I={class:"login-title"},K={key:0,class:"error-msg"},R={class:"login-footer"},z=k({__name:"AdminLogin",setup(D){const f=d(),u=d(!1),c=d(""),g=d(""),v=d("");E().then(l=>{l.site_name&&(g.value=l.site_name)}).catch(()=>{});const s=S({username:"",password:""}),b={username:[{required:!0,message:"请输入用户名",trigger:"blur"}],password:[{required:!0,message:"请输入密码",trigger:"blur"}]};async function h(){var e,r,n;if(await((e=f.value)==null?void 0:e.validate().catch(()=>!1))){u.value=!0,c.value="";try{const o=await M(s.username,s.password);localStorage.setItem("admin_token",o.token),B.success("登录成功"),window.location.href="/admin"}catch(o){c.value=((n=(r=o==null?void 0:o.response)==null?void 0:r.data)==null?void 0:n.message)||(o==null?void 0:o.message)||"登录失败"}finally{u.value=!1}}}return C(async()=>{try{const e=await(await fetch("/health")).json();v.value=e.version||""}catch{}}),(l,e)=>{const r=p("el-input"),n=p("el-form-item"),o=p("el-button"),V=p("el-form");return w(),y("div",j,[e[4]||(e[4]=a("div",{class:"login-bg-pattern"},null,-1)),a("div",q,[a("div",A,[e[2]||(e[2]=a("div",{class:"login-logo"},"☁️",-1)),a("h1",I,m(g.value||"CloudSearch"),1),e[3]||(e[3]=a("p",{class:"login-subtitle"},"管理后台",-1))]),t(V,{ref_key:"formRef",ref:f,model:s,rules:b,"label-width":"0",size:"large",onKeyup:x(h,["enter"])},{default:i(()=>[t(n,{prop:"username"},{default:i(()=>[t(r,{modelValue:s.username,"onUpdate:modelValue":e[0]||(e[0]=_=>s.username=_),placeholder:"用户名","prefix-icon":"User"},null,8,["modelValue"])]),_:1}),t(n,{prop:"password"},{default:i(()=>[t(r,{modelValue:s.password,"onUpdate:modelValue":e[1]||(e[1]=_=>s.password=_),type:"password",placeholder:"密码","prefix-icon":"Lock","show-password":""},null,8,["modelValue"])]),_:1}),t(n,null,{default:i(()=>[t(o,{type:"primary",loading:u.value,class:"login-btn",onClick:h},{default:i(()=>[N(m(u.value?"登录中...":"登 录"),1)]),_:1},8,["loading"])]),_:1})]),_:1},8,["model"]),c.value?(w(),y("p",K,m(c.value),1)):L("",!0),a("p",R,"CloudSearch v"+m(v.value),1)])])}}}),G=U(z,[["__scopeId","data-v-bd0b6672"]]);export{G as default}; import{d as k,o as C,a as w,c as y,b as a,t as m,f as t,w as i,g as x,e as L,h as d,j as p,l as N,i as S,E as B}from"./index-hm1O9sxT.js";import{a as E,d as M,_ as U}from"./_plugin-vue_export-helper-D4DENoBS.js";const j={class:"admin-login-page"},q={class:"login-card"},A={class:"login-brand"},I={class:"login-title"},K={key:0,class:"error-msg"},R={class:"login-footer"},z=k({__name:"AdminLogin",setup(D){const f=d(),u=d(!1),c=d(""),g=d(""),v=d("");E().then(l=>{l.site_name&&(g.value=l.site_name)}).catch(()=>{});const s=S({username:"",password:""}),b={username:[{required:!0,message:"请输入用户名",trigger:"blur"}],password:[{required:!0,message:"请输入密码",trigger:"blur"}]};async function h(){var e,r,n;if(await((e=f.value)==null?void 0:e.validate().catch(()=>!1))){u.value=!0,c.value="";try{const o=await M(s.username,s.password);localStorage.setItem("admin_token",o.token),B.success("登录成功"),window.location.href="/admin"}catch(o){c.value=((n=(r=o==null?void 0:o.response)==null?void 0:r.data)==null?void 0:n.message)||(o==null?void 0:o.message)||"登录失败"}finally{u.value=!1}}}return C(async()=>{try{const e=await(await fetch("/health")).json();v.value=e.version||""}catch{}}),(l,e)=>{const r=p("el-input"),n=p("el-form-item"),o=p("el-button"),V=p("el-form");return w(),y("div",j,[e[4]||(e[4]=a("div",{class:"login-bg-pattern"},null,-1)),a("div",q,[a("div",A,[e[2]||(e[2]=a("div",{class:"login-logo"},"☁️",-1)),a("h1",I,m(g.value||"CloudSearch"),1),e[3]||(e[3]=a("p",{class:"login-subtitle"},"管理后台",-1))]),t(V,{ref_key:"formRef",ref:f,model:s,rules:b,"label-width":"0",size:"large",onKeyup:x(h,["enter"])},{default:i(()=>[t(n,{prop:"username"},{default:i(()=>[t(r,{modelValue:s.username,"onUpdate:modelValue":e[0]||(e[0]=_=>s.username=_),placeholder:"用户名","prefix-icon":"User"},null,8,["modelValue"])]),_:1}),t(n,{prop:"password"},{default:i(()=>[t(r,{modelValue:s.password,"onUpdate:modelValue":e[1]||(e[1]=_=>s.password=_),type:"password",placeholder:"密码","prefix-icon":"Lock","show-password":""},null,8,["modelValue"])]),_:1}),t(n,null,{default:i(()=>[t(o,{type:"primary",loading:u.value,class:"login-btn",onClick:h},{default:i(()=>[N(m(u.value?"登录中...":"登 录"),1)]),_:1},8,["loading"])]),_:1})]),_:1},8,["model"]),c.value?(w(),y("p",K,m(c.value),1)):L("",!0),a("p",R,"CloudSearch v"+m(v.value),1)])])}}}),G=U(z,[["__scopeId","data-v-bd0b6672"]]);export{G as default};

View File

@@ -1 +1 @@
import{C as s,b as a,a as n}from"./index-Bn7NwETH.js";import{d as l,a as t,c,p as d,k as o,e as r,l as u,t as m}from"./index-DT1mRj5t.js";import{_}from"./_plugin-vue_export-helper-1Z-znrfZ.js";const p=["src"],i=l({__name:"CloudBadge",props:{cloud_type:{},showIcon:{type:Boolean}},setup(e){return(C,y)=>(t(),c("span",{class:"cloud-badge",style:d({background:o(s)[e.cloud_type]})},[e.showIcon&&o(a)[e.cloud_type]?(t(),c("img",{key:0,src:o(a)[e.cloud_type],class:"badge-icon"},null,8,p)):r("",!0),u(" "+m(o(n)[e.cloud_type]),1)],4))}}),L=_(i,[["__scopeId","data-v-9106805f"]]);export{L as C}; import{C as s,b as a,a as n}from"./index-Bn7NwETH.js";import{d as l,a as t,c,p as d,k as o,e as r,l as u,t as m}from"./index-hm1O9sxT.js";import{_}from"./_plugin-vue_export-helper-D4DENoBS.js";const p=["src"],i=l({__name:"CloudBadge",props:{cloud_type:{},showIcon:{type:Boolean}},setup(e){return(C,y)=>(t(),c("span",{class:"cloud-badge",style:d({background:o(s)[e.cloud_type]})},[e.showIcon&&o(a)[e.cloud_type]?(t(),c("img",{key:0,src:o(a)[e.cloud_type],class:"badge-icon"},null,8,p)):r("",!0),u(" "+m(o(n)[e.cloud_type]),1)],4))}}),L=_(i,[["__scopeId","data-v-9106805f"]]);export{L as C};

View File

@@ -1,4 +1,4 @@
import{d as ke,o as L,m as ve,E as _,a as c,c as k,f as n,w as a,b as r,h as C,j as p,i as be,F as R,r as K,t as v,y as g,l as d,e as A,k as Ce,M as he,p as xe,n as H,K as Be,L as Te,v as h}from"./index-DT1mRj5t.js";import{a as x}from"./index-Bn7NwETH.js";import{c as we,k as Fe,h as Ne,l as G,t as Ve,u as P,m as ze,n as Se,o as $e,_ as Ue}from"./_plugin-vue_export-helper-1Z-znrfZ.js";import{C as De}from"./CloudBadge-BEGriYUm.js";const Ie={class:"cloud-config"},Me={class:"cloud-toggle-grid"},Oe=["src"],qe={class:"cloud-label"},Ee={class:"toolbar"},Le={key:0,class:"nickname-text"},Re={key:0,class:"promotion-text"},Ke={key:0,class:"uid-cell"},Ae={key:0,class:"verifying"},He={key:0,class:"storage-cell"},Ge={class:"storage-bar-wrap"},Pe={class:"storage-text"},je={class:"storage-used"},Je={class:"storage-total"},Qe={class:"storage-free"},We={key:0,class:"save-count"},Xe={style:{"line-height":"1.6"}},Ye={class:"cookie-tips-header"},Ze={class:"cookie-tips-title"},et=["innerHTML"],tt=ke({__name:"CloudConfig",setup(ot){const z=C([]),D=C(),F=C([]),B=C(!1),T=C(!1),b=C(null),l=be({cloud_type:"",nickname:"",promotion_account:"",is_transfer_enabled:!1,cookie:"",_verifying:!1,_storageUsed:"",_storageTotal:""}),j=h(()=>({cloud_type:[{required:!0,message:"请选择网盘类型",trigger:"change"}],nickname:[{required:!1,message:"请填写昵称(区分多个同类型网盘)",trigger:"blur"}],promotion_account:[{required:!0,message:"请填写推广平台及账号",trigger:"blur"}]})),J=h(()=>Object.entries(x)),Q=h(()=>{if(!l.cloud_type)return"请先选择网盘类型";const t=l.cloud_type;return t==="quark"||t==="baidu"?`请输入 ${x[t]||t} 的完整 Cookie`:b.value?"留空则保持原有":"输入完整 Cookie"}),W=h(()=>x[l.cloud_type]||l.cloud_type||""),X=h(()=>{const t=l.cloud_type;return t?{quark:`<li>在电脑上打开 <a href="https://pan.quark.cn" target="_blank">pan.quark.cn</a> 并登录你的夸克账号</li> import{d as ke,o as L,m as ve,E as _,a as c,c as k,f as n,w as a,b as r,h as C,j as p,i as be,F as R,r as K,t as v,y as g,l as d,e as A,k as Ce,M as he,p as xe,n as H,K as Be,L as Te,v as h}from"./index-hm1O9sxT.js";import{a as x}from"./index-Bn7NwETH.js";import{c as we,k as Fe,h as Ne,l as G,t as Ve,u as P,m as ze,n as Se,o as $e,_ as Ue}from"./_plugin-vue_export-helper-D4DENoBS.js";import{C as De}from"./CloudBadge-CNjyd2IF.js";const Ie={class:"cloud-config"},Me={class:"cloud-toggle-grid"},Oe=["src"],qe={class:"cloud-label"},Ee={class:"toolbar"},Le={key:0,class:"nickname-text"},Re={key:0,class:"promotion-text"},Ke={key:0,class:"uid-cell"},Ae={key:0,class:"verifying"},He={key:0,class:"storage-cell"},Ge={class:"storage-bar-wrap"},Pe={class:"storage-text"},je={class:"storage-used"},Je={class:"storage-total"},Qe={class:"storage-free"},We={key:0,class:"save-count"},Xe={style:{"line-height":"1.6"}},Ye={class:"cookie-tips-header"},Ze={class:"cookie-tips-title"},et=["innerHTML"],tt=ke({__name:"CloudConfig",setup(ot){const z=C([]),D=C(),F=C([]),B=C(!1),T=C(!1),b=C(null),l=be({cloud_type:"",nickname:"",promotion_account:"",is_transfer_enabled:!1,cookie:"",_verifying:!1,_storageUsed:"",_storageTotal:""}),j=h(()=>({cloud_type:[{required:!0,message:"请选择网盘类型",trigger:"change"}],nickname:[{required:!1,message:"请填写昵称(区分多个同类型网盘)",trigger:"blur"}],promotion_account:[{required:!0,message:"请填写推广平台及账号",trigger:"blur"}]})),J=h(()=>Object.entries(x)),Q=h(()=>{if(!l.cloud_type)return"请先选择网盘类型";const t=l.cloud_type;return t==="quark"||t==="baidu"?`请输入 ${x[t]||t} 的完整 Cookie`:b.value?"留空则保持原有":"输入完整 Cookie"}),W=h(()=>x[l.cloud_type]||l.cloud_type||""),X=h(()=>{const t=l.cloud_type;return t?{quark:`<li>在电脑上打开 <a href="https://pan.quark.cn" target="_blank">pan.quark.cn</a> 并登录你的夸克账号</li>
<li> <code>F12</code> <strong> (Network)</strong> </li> <li> <code>F12</code> <strong> (Network)</strong> </li>
<li>刷新页面在请求列表中点击任意一个请求 <code>account/info</code></li> <li>刷新页面在请求列表中点击任意一个请求 <code>account/info</code></li>
<li>在右侧 <strong>请求头 (Request Headers)</strong> <code>Cookie</code> </li> <li>在右侧 <strong>请求头 (Request Headers)</strong> <code>Cookie</code> </li>

View File

@@ -1 +0,0 @@
.el-card[data-v-1e3ebf03]{margin-bottom:20px}.el-card[data-v-1e3ebf03] .el-card__header{font-weight:600;font-size:15px}[data-v-1e3ebf03] .el-divider__text.is-left{left:0;padding-left:0}.form-tip[data-v-1e3ebf03]{font-size:12px;color:#909399;margin-top:4px}.fallback-upload-wrap[data-v-1e3ebf03]{display:flex;flex-direction:column;gap:12px}.fallback-upload-row[data-v-1e3ebf03]{display:flex;align-items:center;flex-wrap:wrap}.fallback-preview[data-v-1e3ebf03]{display:flex;align-items:center;gap:12px;flex-wrap:wrap}.fallback-preview img[data-v-1e3ebf03]{max-width:100%;height:auto;max-height:120px;border-radius:8px;border:1px solid var(--border-color);background:#f0f0f0;object-fit:contain}.strategy-grid[data-v-1e3ebf03]{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:12px 16px}.grid-cell[data-v-1e3ebf03]{display:flex;flex-direction:column;gap:4px}.strategy-section[data-v-1e3ebf03]{padding:0 4px}.field-block[data-v-1e3ebf03]{margin:12px 0}.field-label-row[data-v-1e3ebf03]{display:flex;align-items:center;gap:10px;flex-wrap:wrap}.field-label[data-v-1e3ebf03]{font-size:14px;font-weight:500;color:#303133;white-space:nowrap}.field-desc[data-v-1e3ebf03]{font-size:12px;color:#909399;margin:3px 0 0;line-height:1.5}.keyword-input-row[data-v-1e3ebf03]{display:flex;gap:8px;flex:1;min-width:200px}.tag-list[data-v-1e3ebf03]{display:flex;flex-wrap:wrap;gap:6px;margin-top:8px}.tag-empty[data-v-1e3ebf03]{font-size:13px;color:#c0c4cc;margin-top:8px}.filter-rule-help[data-v-1e3ebf03]{margin-top:8px;padding:10px 12px;background:#f8f9fa;border-radius:8px;border:1px solid #e8e8e8}.filter-rule-help .help-title[data-v-1e3ebf03]{font-weight:600;font-size:13px;margin:8px 0 4px;color:#333}.filter-rule-help .help-title[data-v-1e3ebf03]:first-child{margin-top:0}.filter-rule-help .help-row[data-v-1e3ebf03]{font-size:12px;color:#555;margin:3px 0;line-height:1.6}.filter-rule-help .help-row code[data-v-1e3ebf03]{background:#eef1f5;padding:1px 5px;border-radius:3px;font-size:11px;font-family:monospace}.filter-rules-help[data-v-1e3ebf03]{margin-top:8px;padding:12px;background:#f8f9fa;border-radius:8px;border:1px solid #e8e8e8}.help-title[data-v-1e3ebf03]{font-weight:600;font-size:13px;margin:10px 0 6px;color:#333}.help-title[data-v-1e3ebf03]:first-child{margin-top:0}.help-row[data-v-1e3ebf03]{font-size:12px;color:#555;margin:3px 0;line-height:1.6}.help-row code[data-v-1e3ebf03]{background:#eef1f5;padding:1px 5px;border-radius:3px;font-size:11px;font-family:monospace}.help-sample[data-v-1e3ebf03]{background:#1e1e1e;color:#d4d4d4;padding:10px 14px;border-radius:6px;font-size:12px;line-height:1.6;overflow-x:auto;white-space:pre;margin:6px 0 0;font-family:monospace}.help-preview-row[data-v-1e3ebf03]{font-size:13px;margin:4px 0;display:flex;align-items:center;gap:6px}.help-preview-label[data-v-1e3ebf03]{color:#888;min-width:70px;font-size:12px}.help-preview-original[data-v-1e3ebf03]{color:#e74c3c}.help-preview-filtered[data-v-1e3ebf03]{color:#27ae60;font-weight:500}.filter-input-row[data-v-1e3ebf03]{display:flex;gap:8px;width:100%;margin-bottom:8px}.filter-tag-list[data-v-1e3ebf03]{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:8px}.filter-empty[data-v-1e3ebf03]{font-size:13px;color:#c0c4cc;padding:8px 0;margin-bottom:8px}.db-status-grid[data-v-1e3ebf03]{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:12px;margin-top:8px}.db-stat-item[data-v-1e3ebf03]{background:#f8f9fa;border-radius:10px;padding:16px 12px;text-align:center;border:1px solid #eee;transition:transform .15s,box-shadow .15s}.db-stat-item[data-v-1e3ebf03]:hover{transform:translateY(-2px);box-shadow:0 4px 12px #0000000f}.db-stat-value[data-v-1e3ebf03]{white-space:nowrap;font-size:24px;font-weight:700;color:#303133;margin-bottom:4px}.db-stat-value.text-success[data-v-1e3ebf03]{color:#67c23a}.db-stat-value.text-warning[data-v-1e3ebf03]{color:#e6a23c}.db-stat-label[data-v-1e3ebf03]{font-size:12px;color:#909399}@media (max-width: 900px){.strategy-grid[data-v-1e3ebf03]{grid-template-columns:1fr 1fr}}@media (max-width: 600px){.strategy-grid[data-v-1e3ebf03]{grid-template-columns:1fr}}.pansou-status-grid[data-v-1e3ebf03]{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:12px;margin-top:8px}.status-dot[data-v-1e3ebf03]{width:8px;height:8px;border-radius:50%;display:inline-block}.dot-ok[data-v-1e3ebf03]{background:#67c23a}.dot-err[data-v-1e3ebf03]{background:#f56c6c}

View File

@@ -0,0 +1 @@
.el-card[data-v-21262a13]{margin-bottom:20px}.el-card[data-v-21262a13] .el-card__header{font-weight:600;font-size:15px}[data-v-21262a13] .el-divider__text.is-left{left:0;padding-left:0}.form-tip[data-v-21262a13]{font-size:12px;color:#909399;margin-top:4px}.fallback-upload-wrap[data-v-21262a13]{display:flex;flex-direction:column;gap:12px}.fallback-upload-row[data-v-21262a13]{display:flex;align-items:center;flex-wrap:wrap}.fallback-preview[data-v-21262a13]{display:flex;align-items:center;gap:12px;flex-wrap:wrap}.fallback-preview img[data-v-21262a13]{max-width:100%;height:auto;max-height:120px;border-radius:8px;border:1px solid var(--border-color);background:#f0f0f0;object-fit:contain}.strategy-grid[data-v-21262a13]{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:12px 16px}.grid-cell[data-v-21262a13]{display:flex;flex-direction:column;gap:4px}.strategy-section[data-v-21262a13]{padding:0 4px}.field-block[data-v-21262a13]{margin:12px 0}.field-label-row[data-v-21262a13]{display:flex;align-items:center;gap:10px;flex-wrap:wrap}.field-label[data-v-21262a13]{font-size:14px;font-weight:500;color:#303133;white-space:nowrap}.field-desc[data-v-21262a13]{font-size:12px;color:#909399;margin:3px 0 0;line-height:1.5}.keyword-input-row[data-v-21262a13]{display:flex;gap:8px;flex:1;min-width:200px}.tag-list[data-v-21262a13]{display:flex;flex-wrap:wrap;gap:6px;margin-top:8px}.tag-empty[data-v-21262a13]{font-size:13px;color:#c0c4cc;margin-top:8px}.filter-rule-help[data-v-21262a13]{margin-top:8px;padding:10px 12px;background:#f8f9fa;border-radius:8px;border:1px solid #e8e8e8}.filter-rule-help .help-title[data-v-21262a13]{font-weight:600;font-size:13px;margin:8px 0 4px;color:#333}.filter-rule-help .help-title[data-v-21262a13]:first-child{margin-top:0}.filter-rule-help .help-row[data-v-21262a13]{font-size:12px;color:#555;margin:3px 0;line-height:1.6}.filter-rule-help .help-row code[data-v-21262a13]{background:#eef1f5;padding:1px 5px;border-radius:3px;font-size:11px;font-family:monospace}.filter-rules-help[data-v-21262a13]{margin-top:8px;padding:12px;background:#f8f9fa;border-radius:8px;border:1px solid #e8e8e8}.help-title[data-v-21262a13]{font-weight:600;font-size:13px;margin:10px 0 6px;color:#333}.help-title[data-v-21262a13]:first-child{margin-top:0}.help-row[data-v-21262a13]{font-size:12px;color:#555;margin:3px 0;line-height:1.6}.help-row code[data-v-21262a13]{background:#eef1f5;padding:1px 5px;border-radius:3px;font-size:11px;font-family:monospace}.help-sample[data-v-21262a13]{background:#1e1e1e;color:#d4d4d4;padding:10px 14px;border-radius:6px;font-size:12px;line-height:1.6;overflow-x:auto;white-space:pre;margin:6px 0 0;font-family:monospace}.help-preview-row[data-v-21262a13]{font-size:13px;margin:4px 0;display:flex;align-items:center;gap:6px}.help-preview-label[data-v-21262a13]{color:#888;min-width:70px;font-size:12px}.help-preview-original[data-v-21262a13]{color:#e74c3c}.help-preview-filtered[data-v-21262a13]{color:#27ae60;font-weight:500}.filter-input-row[data-v-21262a13]{display:flex;gap:8px;width:100%;margin-bottom:8px}.filter-tag-list[data-v-21262a13]{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:8px}.filter-empty[data-v-21262a13]{font-size:13px;color:#c0c4cc;padding:8px 0;margin-bottom:8px}.db-status-grid[data-v-21262a13]{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:12px;margin-top:8px}.db-stat-item[data-v-21262a13]{background:#f8f9fa;border-radius:10px;padding:16px 12px;text-align:center;border:1px solid #eee;transition:transform .15s,box-shadow .15s}.db-stat-item[data-v-21262a13]:hover{transform:translateY(-2px);box-shadow:0 4px 12px #0000000f}.db-stat-value[data-v-21262a13]{white-space:nowrap;font-size:24px;font-weight:700;color:#303133;margin-bottom:4px}.db-stat-value.text-success[data-v-21262a13]{color:#67c23a}.db-stat-value.text-warning[data-v-21262a13]{color:#e6a23c}.db-stat-label[data-v-21262a13]{font-size:12px;color:#909399}@media (max-width: 900px){.strategy-grid[data-v-21262a13]{grid-template-columns:1fr 1fr}}@media (max-width: 600px){.strategy-grid[data-v-21262a13]{grid-template-columns:1fr}}.pansou-status-grid[data-v-21262a13]{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:12px;margin-top:8px}.status-dot[data-v-21262a13]{width:8px;height:8px;border-radius:50%;display:inline-block}.dot-ok[data-v-21262a13]{background:#67c23a}.dot-err[data-v-21262a13]{background:#f56c6c}.event-card.active[data-v-21262a13]{border-color:var(--el-color-primary)!important;background:var(--el-color-primary-light-9)}.event-card[data-v-21262a13]{cursor:default}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -21,7 +21,7 @@
} }
})(); })();
</script> </script>
<script type="module" crossorigin src="/assets/index-DT1mRj5t.js"></script> <script type="module" crossorigin src="/assets/index-hm1O9sxT.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-Ekbe64zQ.css"> <link rel="stylesheet" crossorigin href="/assets/index-Ekbe64zQ.css">
</head> </head>
<body> <body>

View File

@@ -382,6 +382,7 @@ export async function getAndValidateCredential(cloudType: string): Promise<Crede
}; };
} }
config.cookie = cookie;
return { return {
valid: true, valid: true,
config, config,

View File

@@ -1,4 +1,46 @@
// @ts-nocheck // @ts-nocheck
import crypto from "crypto";
const HOMOPHONE_MAP = {
// 网盘热门番名 — 谐音替换 (same sound, different char)
'斗': '陡', '破': '坡', '苍': '仓', '穹': '穷',
'完': '玩', '美': '每', '世': '士', '界': '介',
'凡': '烦', '人': '仁', '修': '休', '罗': '络',
'仙': '先', '逆': '腻', '遮': '折', '天': '添',
'吞': '屯', '噬': '逝', '大': '达', '主': '嘱', '宰': '崽',
'星': '惺', '辰': '晨', '变': '便', '一': '伊', '念': '捻',
'永': '泳', '恒': '横', '神': '申', '墓': '暮', '长': '尝', '生': '甥',
'剑': '箭', '来': '莱', '诡': '鬼', '秘': '蜜',
'全': '泉', '职': '值', '盘': '磐', '龙': '笼',
'雪': '血', '鹰': '莺', '莽': '蟒', '荒': '慌', '纪': '记',
'珠': '株', '王': '亡', '座': '坐', '牧': '木', '记': '计',
'沧': '舱', '元': '圆', '图': '涂', '紫': '仔', '川': '串',
'百': '白', '炼': '恋', '成': '程', '饶': '绕', '命': '冥',
// 通用谐音替换
'的': '得', '了': '啦', '是': '事', '不': '布', '我': '窝',
'你': '尼', '他': '她', '有': '友', '和': '合', '与': '予',
'上': '尚', '下': '夏', '中': '忠', '第': '弟', '集': '级',
'话': '划', '季': '际', '年': '念', '月': '阅', '日': '曰',
'新': '心', '版': '板', '高': '糕', '清': '青', '原': '源',
'小': '晓', '片': '篇', '视': '市', '频': '贫', '道': '到',
'动': '洞', '画': '话', '声': '升', '音': '因', '文': '闻',
'明': '名', '暗': '黯', '光': '广', '影': '映', '色': '瑟',
'风': '疯', '雨': '语', '花': '华', '国': '果', '家': '佳',
'战': '站', '争': '挣', '士': '仕', '兵': '宾',
'皇': '惶', '帝': '谛', '魔': '磨', '鬼': '诡', '怪': '乖',
'精': '经', '灵': '铃', '妖': '夭', '武': '舞', '侠': '狭',
'杀': '刹', '血': '雪', '刀': '叨', '枪': '呛', '炮': '泡',
'时': '石', '空': '孔', '前': '钱', '后': '厚', '东': '冬',
'南': '难', '西': '夕', '北': '备', '开': '凯', '关': '官',
'出': '初', '进': '近', '去': '趣',
'短': '短', '多': '多', '少': '少', '真': '贞', '假': '价',
'好': '郝', '坏': '怀', '对': '队', '错': '措', '以': '已',
'从': '从', '被': '被', '把': '把', '将': '将', '在': '在',
'但': '但', '就': '就', '才': '才', '也': '也', '很': '狠',
'又': '又', '再': '再', '更': '更', '最': '最', '总': '总',
'共': '共', '只': '只', '各': '各', '每': '每', '任': '任',
'所': '所', '该': '该', '本': '本',
};
const NOISE_CJK = '的了在是不有会可对所之也同与及但或如且乃而岂乎焉兮哉亦犹尚乃其若故盖诸焉欤' + const NOISE_CJK = '的了在是不有会可对所之也同与及但或如且乃而岂乎焉兮哉亦犹尚乃其若故盖诸焉欤' +
'么个着过把对为从以到说时要就这那和上人家下能出得发来年心开物力些长样吧啊哦嗯嚯哇咯呗哟嘿呵哈'; '么个着过把对为从以到说时要就这那和上人家下能出得发来年心开物力些长样吧啊哦嗯嚯哇咯呗哟嘿呵哈';
// ==================== Helpers ==================== // ==================== Helpers ====================

View File

@@ -10,9 +10,10 @@ export async function lookupIpLocation(ip: string): Promise<string | null> {
return null; return null;
} }
try { try {
const apiUrlTemplate = getSystemConfig('ip_geo_api_url'); const apiId = getSystemConfig('ip_geo_api_id');
if (!apiUrlTemplate) return null; const apiKey = getSystemConfig('ip_geo_api_key');
const url = apiUrlTemplate.replace('{ip}', encodeURIComponent(ip)); if (!apiId || !apiKey) return null;
const url = `https://cn.apihz.cn/api/ip/chaapi.php?id=${encodeURIComponent(apiId)}&key=${encodeURIComponent(apiKey)}&ip=${encodeURIComponent(ip)}&td=0`;
const res = await fetch(url, { signal: AbortSignal.timeout(5000) }); const res = await fetch(url, { signal: AbortSignal.timeout(5000) });
if (!res.ok) return null; if (!res.ok) return null;

View File

@@ -24,7 +24,7 @@ export function getGlobalNotifyConfig(): Record<string, any> {
try { return JSON.parse(raw); } catch { return {}; } try { return JSON.parse(raw); } catch { return {}; }
} }
function getGlobalNotifyConfigs(): NotifyChannel[] { export function getGlobalNotifyConfigs(): NotifyChannel[] {
const raw = getSystemConfig('global_notify_config') || '{}'; const raw = getSystemConfig('global_notify_config') || '{}';
let globalConfig: any = {}; let globalConfig: any = {};
try { globalConfig = JSON.parse(raw); } catch {} try { globalConfig = JSON.parse(raw); } catch {}
@@ -56,7 +56,7 @@ function checkEventEnabled(eventName: string): boolean {
// ======================== Core send ======================== // ======================== Core send ========================
async function sendToChannels(channels: NotifyChannel[], title: string, content: string, level: NotifyLevel): Promise<void> { export async function sendToChannels(channels: NotifyChannel[], title: string, content: string, level: NotifyLevel): Promise<void> {
for (const ch of channels) { for (const ch of channels) {
try { try {
await notifyWith(ch.name, { await notifyWith(ch.name, {
@@ -92,7 +92,7 @@ export function notifyInfo(title: string, detail: string): void {
} }
function applyTemplate(template: string, vars: Record<string, string>): string { function applyTemplate(template: string, vars: Record<string, string>): string {
return template.replace(/\{([^}]+)\}/g, (_, key) => vars[key] || '{' + key + '}'); return template.replace(/\{([^}]+)\}/g, (_, key) => vars[key] ?? '{' + key + '}');
} }
function getEventTemplates(): Record<string, { title?: string; content: string }> { function getEventTemplates(): Record<string, { title?: string; content: string }> {
@@ -141,7 +141,7 @@ export function notifyConfigEvent(
// Find matching push user by cloud_configs.promotion_account // Find matching push user by cloud_configs.promotion_account
const pushUser = findPushUserForConfig(configId); const pushUser = findPushUserForConfig(configId);
if (!pushUser) { if (!pushUser) {
notifyEvent(eventName, title, content, level); notifyEvent(eventName, title, content, level, templateVars);
return; return;
} }
@@ -160,7 +160,7 @@ export function notifyConfigEvent(
if (userChannels.length > 0) { if (userChannels.length > 0) {
sendToChannels(userChannels, title, content, level).catch(() => {}); sendToChannels(userChannels, title, content, level).catch(() => {});
} else { } else {
notifyEvent(eventName, title, content, level); notifyEvent(eventName, title, content, level, templateVars);
} }
} }

View File

@@ -3,8 +3,7 @@ import { Notifier, NotifyParams, NotifyResult, NotifierParam } from './notifier.
const params: NotifierParam[] = [ const params: NotifierParam[] = [
{ key: 'key', label: 'Bark Key', type: 'text', required: true, placeholder: 'xxxxxxxxxxxxxxxxx' }, { key: 'key', label: 'Bark Key', type: 'text', required: true, placeholder: 'xxxxxxxxxxxxxxxxx' },
{ key: 'server', label: '服务器', type: 'url', default: 'https://api.day.app', required: false, placeholder: 'https://api.day.app' }, { key: 'server', label: '服务器', type: 'url', default: 'https://api.day.app', required: false, placeholder: 'https://api.day.app' },
{ key: 'title', label: '标题', type: 'text', default: 'CloudSearch 通知', required: false },
{ key: 'content', label: '内容', type: 'text', required: true }
]; ];
export const barkNotifier: Notifier = { export const barkNotifier: Notifier = {

View File

@@ -2,8 +2,7 @@ import { Notifier, NotifyParams, NotifyResult, NotifierParam } from './notifier.
const params: NotifierParam[] = [ const params: NotifierParam[] = [
{ key: 'webhook_url', label: 'Webhook URL', type: 'url', required: true, placeholder: 'https://oapi.dingtalk.com/robot/send?access_token=xxx' }, { key: 'webhook_url', label: 'Webhook URL', type: 'url', required: true, placeholder: 'https://oapi.dingtalk.com/robot/send?access_token=xxx' },
{ key: 'title', label: '标题', type: 'text', default: 'CloudSearch', required: false },
{ key: 'content', label: '内容', type: 'text', required: true }
]; ];
export const dingtalkNotifier: Notifier = { export const dingtalkNotifier: Notifier = {

View File

@@ -2,8 +2,7 @@ import { Notifier, NotifyParams, NotifyResult, NotifierParam } from './notifier.
const params: NotifierParam[] = [ const params: NotifierParam[] = [
{ key: 'webhook_url', label: 'Webhook URL', type: 'url', required: true, placeholder: 'https://discord.com/api/webhooks/...' }, { key: 'webhook_url', label: 'Webhook URL', type: 'url', required: true, placeholder: 'https://discord.com/api/webhooks/...' },
{ key: 'title', label: '标题', type: 'text', default: 'CloudSearch', required: false },
{ key: 'content', label: '内容', type: 'text', required: true }
]; ];
export const discordNotifier: Notifier = { export const discordNotifier: Notifier = {

View File

@@ -3,8 +3,7 @@ import { Notifier, NotifyParams, NotifyResult, NotifierParam } from './notifier.
const params: NotifierParam[] = [ const params: NotifierParam[] = [
{ key: 'server', label: '服务器地址', type: 'url', required: true, placeholder: 'https://gotify.example.com' }, { key: 'server', label: '服务器地址', type: 'url', required: true, placeholder: 'https://gotify.example.com' },
{ key: 'token', label: 'App Token', type: 'password', required: true, placeholder: 'Gotify App Token' }, { key: 'token', label: 'App Token', type: 'password', required: true, placeholder: 'Gotify App Token' },
{ key: 'title', label: '标题', type: 'text', default: 'CloudSearch', required: false },
{ key: 'content', label: '内容', type: 'text', required: true }
]; ];
export const gotifyNotifier: Notifier = { export const gotifyNotifier: Notifier = {

View File

@@ -2,8 +2,7 @@ import { Notifier, NotifyParams, NotifyResult, NotifierParam } from './notifier.
const params: NotifierParam[] = [ const params: NotifierParam[] = [
{ key: 'webhook_url', label: 'Webhook URL', type: 'url', required: true, placeholder: 'https://open.feishu.cn/open-apis/bot/v2/hook/xxx' }, { key: 'webhook_url', label: 'Webhook URL', type: 'url', required: true, placeholder: 'https://open.feishu.cn/open-apis/bot/v2/hook/xxx' },
{ key: 'title', label: '\u6807\u9898', type: 'text', default: 'CloudSearch', required: false },
{ key: 'content', label: '\u5185\u5bb9', type: 'text', required: true }
]; ];
export const larkNotifier: Notifier = { export const larkNotifier: Notifier = {

View File

@@ -3,8 +3,7 @@ import { Notifier, NotifyParams, NotifyResult, NotifierParam } from './notifier.
const params: NotifierParam[] = [ const params: NotifierParam[] = [
{ key: 'topic', label: 'Topic', type: 'text', required: true, placeholder: 'my-notification-topic' }, { key: 'topic', label: 'Topic', type: 'text', required: true, placeholder: 'my-notification-topic' },
{ key: 'server', label: '服务器', type: 'url', default: 'https://ntfy.sh', required: false, placeholder: 'https://ntfy.sh' }, { key: 'server', label: '服务器', type: 'url', default: 'https://ntfy.sh', required: false, placeholder: 'https://ntfy.sh' },
{ key: 'title', label: '标题', type: 'text', default: 'CloudSearch', required: false },
{ key: 'content', label: '内容', type: 'text', required: true }
]; ];
export const ntfyNotifier: Notifier = { export const ntfyNotifier: Notifier = {

View File

@@ -2,8 +2,7 @@ import { Notifier, NotifyParams, NotifyResult, NotifierParam } from './notifier.
const params: NotifierParam[] = [ const params: NotifierParam[] = [
{ key: 'token', label: 'Token', type: 'password', required: true, placeholder: 'pushplus token' }, { key: 'token', label: 'Token', type: 'password', required: true, placeholder: 'pushplus token' },
{ key: 'title', label: '标题', type: 'text', default: 'CloudSearch', required: false },
{ key: 'content', label: '内容', type: 'text', required: true }
]; ];
export const pushplusNotifier: Notifier = { export const pushplusNotifier: Notifier = {

View File

@@ -3,8 +3,7 @@ import { Notifier, NotifyParams, NotifyResult, NotifierParam } from './notifier.
const params: NotifierParam[] = [ const params: NotifierParam[] = [
{ key: 'key', label: 'API Key', type: 'password', required: true, placeholder: 'Qmsg API Key' }, { key: 'key', label: 'API Key', type: 'password', required: true, placeholder: 'Qmsg API Key' },
{ key: 'qq', label: 'QQ 号', type: 'text', required: false, placeholder: '留空则推送到所有绑定QQ' }, { key: 'qq', label: 'QQ 号', type: 'text', required: false, placeholder: '留空则推送到所有绑定QQ' },
{ key: 'title', label: '标题', type: 'text', default: 'CloudSearch', required: false },
{ key: 'content', label: '内容', type: 'text', required: true }
]; ];
export const qmsgNotifier: Notifier = { export const qmsgNotifier: Notifier = {

View File

@@ -2,8 +2,7 @@ import { Notifier, NotifyParams, NotifyResult, NotifierParam } from './notifier.
const params: NotifierParam[] = [ const params: NotifierParam[] = [
{ key: 'sendkey', label: 'SendKey', type: 'password', required: true, placeholder: 'Server酱 SendKey' }, { key: 'sendkey', label: 'SendKey', type: 'password', required: true, placeholder: 'Server酱 SendKey' },
{ key: 'title', label: '标题', type: 'text', default: 'CloudSearch', required: false },
{ key: 'content', label: '内容', type: 'text', required: true }
]; ];
export const serverchanNotifier: Notifier = { export const serverchanNotifier: Notifier = {

View File

@@ -2,8 +2,7 @@ import { Notifier, NotifyParams, NotifyResult, NotifierParam } from './notifier.
const params: NotifierParam[] = [ const params: NotifierParam[] = [
{ key: 'sendkey', label: 'SendKey', type: 'password', required: true, placeholder: 'Server酱 Turbo SendKey' }, { key: 'sendkey', label: 'SendKey', type: 'password', required: true, placeholder: 'Server酱 Turbo SendKey' },
{ key: 'title', label: '标题', type: 'text', default: 'CloudSearch', required: false },
{ key: 'content', label: '内容', type: 'text', required: true }
]; ];
export const serverchanturboNotifier: Notifier = { export const serverchanturboNotifier: Notifier = {

View File

@@ -8,8 +8,7 @@ const params: NotifierParam[] = [
{ key: 'pass', label: '密码/授权码', type: 'password', required: true, placeholder: 'SMTP 授权码' }, { key: 'pass', label: '密码/授权码', type: 'password', required: true, placeholder: 'SMTP 授权码' },
{ key: 'from', label: '发件人', type: 'text', required: true, placeholder: 'sender@example.com' }, { key: 'from', label: '发件人', type: 'text', required: true, placeholder: 'sender@example.com' },
{ key: 'to', label: '收件人', type: 'text', required: true, placeholder: 'receiver@example.com' }, { key: 'to', label: '收件人', type: 'text', required: true, placeholder: 'receiver@example.com' },
{ key: 'title', label: '标题', type: 'text', default: 'CloudSearch', required: false },
{ key: 'content', label: '内容', type: 'text', required: true }
]; ];
export const smtpNotifier: Notifier = { export const smtpNotifier: Notifier = {

View File

@@ -3,8 +3,7 @@ import { Notifier, NotifyParams, NotifyResult, NotifierParam } from './notifier.
const params: NotifierParam[] = [ const params: NotifierParam[] = [
{ key: 'token', label: 'Bot Token', type: 'password', required: true, placeholder: '123456:ABC-def' }, { key: 'token', label: 'Bot Token', type: 'password', required: true, placeholder: '123456:ABC-def' },
{ key: 'chat_id', label: 'Chat ID', type: 'text', required: true, placeholder: '@频道 或 -1001234567890' }, { key: 'chat_id', label: 'Chat ID', type: 'text', required: true, placeholder: '@频道 或 -1001234567890' },
{ key: 'title', label: '标题', type: 'text', default: 'CloudSearch', required: false },
{ key: 'content', label: '内容', type: 'text', required: true }
]; ];
export const telegramNotifier: Notifier = { export const telegramNotifier: Notifier = {

View File

@@ -2,8 +2,7 @@ import { Notifier, NotifyParams, NotifyResult, NotifierParam } from './notifier.
const params: NotifierParam[] = [ const params: NotifierParam[] = [
{ key: 'url', label: 'Webhook URL', type: 'url', required: true, placeholder: 'https://example.com/webhook' }, { key: 'url', label: 'Webhook URL', type: 'url', required: true, placeholder: 'https://example.com/webhook' },
{ key: 'title', label: '\u6807\u9898', type: 'text', default: 'CloudSearch', required: false },
{ key: 'content', label: '\u5185\u5bb9', type: 'text', required: true }
]; ];
export const webhookNotifier: Notifier = { export const webhookNotifier: Notifier = {

View File

@@ -2,8 +2,7 @@ import { Notifier, NotifyParams, NotifyResult, NotifierParam } from './notifier.
const params: NotifierParam[] = [ const params: NotifierParam[] = [
{ key: 'webhook_url', label: 'Webhook URL', type: 'url', required: true, placeholder: 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxx' }, { key: 'webhook_url', label: 'Webhook URL', type: 'url', required: true, placeholder: 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxx' },
{ key: 'title', label: '标题', type: 'text', default: 'CloudSearch', required: false },
{ key: 'content', label: '内容', type: 'text', required: true }
]; ];
export const wechatWorkBotNotifier: Notifier = { export const wechatWorkBotNotifier: Notifier = {

View File

@@ -535,16 +535,17 @@ router.post('/admin/test-external-service', async (req: Request, res: Response)
break; break;
} }
case 'ip_geo': { case 'ip_geo': {
const geoUrl = url || getSystemConfig('ip_geo_api_url') || ''; const apiId = url || getSystemConfig('ip_geo_api_id') || '';
if (!geoUrl) { const apiKey = getSystemConfig('ip_geo_api_key') || '';
res.json({ ok: false, info: '请先输入 IP 归属地查询 API 地址' }); if (!apiId || !apiKey) {
res.json({ ok: false, info: '请先配置 IP 归属地 API ID 和 Key' });
return; return;
} }
const testUrl = geoUrl.replace('{ip}', '8.8.8.8'); const testUrl = `https://cn.apihz.cn/api/ip/chaapi.php?id=${encodeURIComponent(apiId)}&key=${encodeURIComponent(apiKey)}&ip=8.8.8.8&td=0`;
const response = await fetch(testUrl, { signal: AbortSignal.timeout(8000) }); const response = await fetch(testUrl, { signal: AbortSignal.timeout(8000) });
const data: any = await response.json(); const data: any = await response.json();
const latency = Date.now() - start; const latency = Date.now() - start;
const valid = !!(data?.country || data?.region || data?.city || data?.countryCode); const valid = data?.code === 200;
res.json({ ok: valid, latency, info: valid ? '连接成功' : '响应格式不符' }); res.json({ ok: valid, latency, info: valid ? '连接成功' : '响应格式不符' });
break; break;
} }

View File

@@ -5,7 +5,7 @@
import { getDb } from '../database/database'; import { getDb } from '../database/database';
import { getSystemConfig } from '../admin/system-config.service'; import { getSystemConfig } from '../admin/system-config.service';
import { getCloudConfigs } from '../cloud/credential.service'; import { getCloudConfigs } from '../cloud/credential.service';
import { notify } from '../cloud/notification.service'; import { notify, getGlobalNotifyConfigs, sendToChannels } from '../cloud/notification.service';
import { CLOUD_LABELS } from '../config/cloud-constants'; import { CLOUD_LABELS } from '../config/cloud-constants';
// ═══════════════════════════════════════════════ // ═══════════════════════════════════════════════
@@ -19,6 +19,7 @@ export interface DailyReportConfig {
includeSaves: boolean; includeSaves: boolean;
includeStorage: boolean; includeStorage: boolean;
includeUsers: boolean; includeUsers: boolean;
channels?: string[]; // 指定推送通道,空=全部全局通道
} }
export interface DailyReport { export interface DailyReport {
@@ -53,6 +54,7 @@ export function getDailyReportConfig(): DailyReportConfig {
includeSaves: parsed.includeSaves !== false, includeSaves: parsed.includeSaves !== false,
includeStorage: parsed.includeStorage !== false, includeStorage: parsed.includeStorage !== false,
includeUsers: parsed.includeUsers !== false, includeUsers: parsed.includeUsers !== false,
channels: parsed.channels || [],
}; };
} }
@@ -286,7 +288,16 @@ export async function runDailyReportIfScheduled(): Promise<void> {
cfg.includeUsers cfg.includeUsers
); );
// 通道过滤:如果配置了 channels 则只发指定通道
if (cfg.channels && cfg.channels.length > 0) {
const allChannels = getGlobalNotifyConfigs();
const filtered = allChannels.filter(c => cfg.channels!.includes(c.name));
if (filtered.length > 0) {
sendToChannels(filtered, 'CloudSearch 每日汇报', content, 'info').catch(() => {});
}
} else {
notify('CloudSearch 每日汇报', content, 'info'); notify('CloudSearch 每日汇报', content, 'info');
}
// Record last run // Record last run
const { getDb } = require('../database/database'); const { getDb } = require('../database/database');
@@ -332,6 +343,15 @@ export async function sendTestDailyReport(): Promise<{ success: boolean; report:
cfg.includeStorage, cfg.includeStorage,
cfg.includeUsers cfg.includeUsers
); );
const tcfg = getDailyReportConfig();
if (tcfg.channels && tcfg.channels.length > 0) {
const allChannels = getGlobalNotifyConfigs();
const filtered = allChannels.filter(c => tcfg.channels!.includes(c.name));
if (filtered.length > 0) {
sendToChannels(filtered, 'CloudSearch 每日汇报 [测试]', content, 'info').catch(() => {});
}
} else {
notify('CloudSearch 每日汇报 [测试]', content, 'info'); notify('CloudSearch 每日汇报 [测试]', content, 'info');
}
return { success: true, report }; return { success: true, report };
} }