From 840042d301500cc139ffff2a24cfe138353c127b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 4 Feb 2026 05:35:55 +0000 Subject: [PATCH] chore: auto-build WebUI [skip ci] --- static/admin/assets/{index-C7aw1GYL.js => index-cwfNH6yZ.js} | 2 +- static/admin/index.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename static/admin/assets/{index-C7aw1GYL.js => index-cwfNH6yZ.js} (92%) diff --git a/static/admin/assets/index-C7aw1GYL.js b/static/admin/assets/index-cwfNH6yZ.js similarity index 92% rename from static/admin/assets/index-C7aw1GYL.js rename to static/admin/assets/index-cwfNH6yZ.js index 9b576a6..e915f3f 100644 --- a/static/admin/assets/index-C7aw1GYL.js +++ b/static/admin/assets/index-cwfNH6yZ.js @@ -269,4 +269,4 @@ Please change the parent to {(async()=>{try{const f=await x("/admin/vercel/config");if(f.ok){const d=await f.json();v(d),d.project_id&&o(d.project_id),d.team_id&&i(d.team_id)}}catch(f){console.error("Failed to load preconfig:",f)}})()},[]);const w=async()=>{if(!(h!=null&&h.has_token&&!n?"__USE_PRECONFIG__":n)&&!(h!=null&&h.has_token)){e("error","需要 Vercel 访问令牌");return}if(!l){e("error","需要项目 ID");return}c(!0),p(null);try{const f=await x("/admin/vercel/sync",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({vercel_token:n,project_id:l,team_id:s||void 0})}),d=await f.json();f.ok?(p({...d,success:!0}),e("success",d.message)):(p({...d,success:!1}),e("error",d.detail||"同步失败"))}catch{e("error","网络错误")}finally{c(!1)}};return a.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-8 max-w-5xl mx-auto h-[calc(100vh-140px)]",children:[a.jsxs("div",{className:"bg-card border border-border rounded-xl shadow-sm p-6 space-y-6",children:[a.jsxs("div",{className:"border-b border-border pb-6",children:[a.jsxs("h2",{className:"text-xl font-semibold flex items-center gap-2",children:[a.jsx(zd,{className:"w-6 h-6 text-primary"}),"Vercel 部署"]}),a.jsx("p",{className:"text-muted-foreground text-sm mt-1",children:"将当前密钥和账号配置直接同步到 Vercel 环境变量中。"})]}),a.jsxs("div",{className:"space-y-4",children:[a.jsxs("div",{className:"space-y-2",children:[a.jsxs("label",{className:"text-sm font-medium flex items-center justify-between",children:["Vercel 访问令牌",a.jsxs("a",{href:"https://vercel.com/account/tokens",target:"_blank",rel:"noopener noreferrer",className:"text-xs text-primary hover:underline flex items-center gap-1",children:["获取令牌 ",a.jsx(Ja,{className:"w-3 h-3"})]})]}),a.jsxs("div",{className:"relative",children:[a.jsx("input",{type:"password",className:"w-full h-10 px-3 bg-background border border-border rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-ring focus:border-ring transition-all pr-10",placeholder:h!=null&&h.has_token?"正在使用预配置的令牌":"输入 Vercel 访问令牌",value:n,onChange:N=>r(N.target.value)}),(h==null?void 0:h.has_token)&&!n&&a.jsx("div",{className:"absolute right-3 top-2.5 text-emerald-500",children:a.jsx(Dl,{className:"w-5 h-5"})})]})]}),a.jsxs("div",{className:"space-y-2",children:[a.jsx("label",{className:"text-sm font-medium",children:"项目 ID"}),a.jsx("input",{type:"text",className:"w-full h-10 px-3 bg-background border border-border rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-ring focus:border-ring transition-all",placeholder:"prj_xxxxxxxxxxxx or Project Name",value:l,onChange:N=>o(N.target.value)}),a.jsx("p",{className:"text-xs text-muted-foreground",children:"可在项目设置 (Project Settings) → 常规 (General) 中找到"})]}),a.jsxs("div",{className:"space-y-2",children:[a.jsxs("label",{className:"text-sm font-medium flex items-center gap-2",children:["团队 ID ",a.jsx("span",{className:"text-xs text-muted-foreground font-normal",children:"(可选)"})]}),a.jsx("input",{type:"text",className:"w-full h-10 px-3 bg-background border border-border rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-ring focus:border-ring transition-all",placeholder:"team_xxxxxxxxxxxx",value:s,onChange:N=>i(N.target.value)})]})]}),a.jsxs("div",{className:"pt-4",children:[a.jsx("button",{onClick:w,disabled:u,className:"w-full flex items-center justify-center gap-2 py-3 bg-primary text-primary-foreground rounded-lg hover:bg-primary/90 transition-all font-medium text-sm shadow-sm hover:shadow-md disabled:opacity-50 disabled:shadow-none",children:u?a.jsxs("span",{className:"flex items-center gap-2",children:[a.jsx("span",{className:"w-4 h-4 border-2 border-current border-t-transparent rounded-full animate-spin"}),"正在同步..."]}):a.jsxs("span",{className:"flex items-center gap-2",children:["同步并重新部署 ",a.jsx(Td,{className:"w-4 h-4"})]})}),a.jsx("p",{className:"text-xs text-center text-muted-foreground mt-4",children:"这将触发 Vercel 的重新部署,大约需要 30-60 秒。"})]})]}),a.jsxs("div",{className:"space-y-6",children:[y&&a.jsx("div",{className:`p-6 rounded-xl border ${y.success?"bg-emerald-500/10 border-emerald-500/20":"bg-destructive/10 border-destructive/20"} animate-in fade-in slide-in-from-right-4`,children:a.jsxs("div",{className:"flex items-start gap-4",children:[y.success?a.jsx("div",{className:"p-2 bg-emerald-500 text-white rounded-full shadow-lg shadow-emerald-500/30",children:a.jsx(Dl,{className:"w-6 h-6"})}):a.jsx("div",{className:"p-2 bg-destructive text-white rounded-full shadow-lg shadow-destructive/30",children:a.jsx(ny,{className:"w-6 h-6"})}),a.jsxs("div",{className:"space-y-1",children:[a.jsx("h3",{className:`font-semibold text-lg ${y.success?"text-emerald-500":"text-destructive"}`,children:y.success?"同步成功":"同步失败"}),a.jsx("p",{className:"text-sm opacity-90",children:y.message}),y.deployment_url&&a.jsx("div",{className:"pt-3 mt-3 border-t border-emerald-500/20",children:a.jsxs("a",{href:`https://${y.deployment_url}`,target:"_blank",rel:"noopener noreferrer",className:"inline-flex items-center gap-1 text-sm font-medium hover:underline",children:["访问部署地址 ",a.jsx(Ja,{className:"w-3 h-3"})]})})]})]})}),a.jsxs("div",{className:"bg-secondary/20 border border-border rounded-xl p-6",children:[a.jsxs("h3",{className:"font-semibold flex items-center gap-2 mb-4",children:[a.jsx(py,{className:"w-5 h-5 text-primary"}),"工作原理"]}),a.jsxs("ul",{className:"space-y-4",children:[a.jsxs("li",{className:"flex gap-3",children:[a.jsx("span",{className:"shrink-0 w-6 h-6 rounded-full bg-background border border-border flex items-center justify-center text-xs font-bold text-muted-foreground",children:"1"}),a.jsx("p",{className:"text-sm text-muted-foreground",children:"当前配置 (密钥和账号) 被导出为 JSON 字符串。"})]}),a.jsxs("li",{className:"flex gap-3",children:[a.jsx("span",{className:"shrink-0 w-6 h-6 rounded-full bg-background border border-border flex items-center justify-center text-xs font-bold text-muted-foreground",children:"2"}),a.jsx("p",{className:"text-sm text-muted-foreground",children:"JSON 被编码为 Base64 以确保格式兼容性。"})]}),a.jsxs("li",{className:"flex gap-3",children:[a.jsx("span",{className:"shrink-0 w-6 h-6 rounded-full bg-background border border-border flex items-center justify-center text-xs font-bold text-muted-foreground",children:"3"}),a.jsxs("p",{className:"text-sm text-muted-foreground",children:["更新 Vercel 项目中的 ",a.jsx("code",{className:"bg-background px-1 py-0.5 rounded border border-border text-xs",children:"DS2API_CONFIG_JSON"})," 环境变量。"]})]}),a.jsxs("li",{className:"flex gap-3",children:[a.jsx("span",{className:"shrink-0 w-6 h-6 rounded-full bg-background border border-border flex items-center justify-center text-xs font-bold text-muted-foreground",children:"4"}),a.jsx("p",{className:"text-sm text-muted-foreground",children:"触发重新部署以应用新的环境变量。"})]})]})]})]})]})}function tg({onLogin:e,onMessage:t}){const[n,r]=g.useState(""),[l,o]=g.useState(!1),[s,i]=g.useState(!0),u=async c=>{if(c.preventDefault(),!!n.trim()){o(!0);try{const y=await fetch("/admin/login",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({admin_key:n})}),p=await y.json();if(y.ok&&p.success){const h=s?localStorage:sessionStorage;h.setItem("ds2api_token",p.token),h.setItem("ds2api_token_expires",Date.now()+p.expires_in*1e3),e(p.token),p.message&&t("warning",p.message)}else t("error",p.detail||"登录失败")}catch(y){t("error","网络错误: "+y.message)}finally{o(!1)}}};return a.jsx("div",{className:"min-h-screen w-full flex flex-col items-center justify-center p-4 bg-background text-foreground",children:a.jsxs("div",{className:"w-full max-w-[400px] relative z-10 animate-in fade-in zoom-in-95 duration-200",children:[a.jsxs("div",{className:"w-full bg-card border border-border rounded-xl p-8 shadow-sm",children:[a.jsxs("div",{className:"text-center space-y-2 mb-8 animate-in fade-in slide-in-from-top-4 duration-500",children:[a.jsx("div",{className:"inline-flex items-center justify-center w-12 h-12 rounded-xl bg-primary/10 text-primary mb-2",children:a.jsx(wy,{className:"w-6 h-6"})}),a.jsx("h1",{className:"text-3xl font-bold tracking-tight text-foreground",children:"欢迎回来"}),a.jsx("p",{className:"text-sm text-muted-foreground/80",children:"请输入管理员密钥以继续"})]}),a.jsxs("form",{onSubmit:u,className:"space-y-5 animate-in fade-in slide-in-from-bottom-4 duration-700 delay-150",children:[a.jsxs("div",{className:"space-y-2",children:[a.jsx("label",{className:"text-xs font-semibold text-muted-foreground uppercase tracking-widest ml-1",children:"管理员密钥"}),a.jsxs("div",{className:"relative group",children:[a.jsx("div",{className:"absolute inset-y-0 left-0 pl-3.5 flex items-center pointer-events-none text-muted-foreground group-focus-within:text-primary transition-colors",children:a.jsx(hy,{className:"w-4 h-4"})}),a.jsx("input",{type:"password",className:"w-full bg-[#09090b] border border-border rounded-xl pl-10 pr-4 py-3 text-sm focus:ring-2 focus:ring-primary/20 focus:border-primary transition-all placeholder:text-muted-foreground/30 text-foreground",placeholder:"输入您的管理员密钥...",value:n,onChange:c=>r(c.target.value),autoFocus:!0})]})]}),a.jsx("div",{className:"flex items-center justify-between px-1",children:a.jsxs("label",{className:"flex items-center gap-2.5 cursor-pointer group",children:[a.jsxs("div",{className:"relative flex items-center",children:[a.jsx("input",{type:"checkbox",className:"peer sr-only",checked:s,onChange:c=>i(c.target.checked)}),a.jsx("div",{className:"w-4.5 h-4.5 bg-secondary border border-border rounded-md peer-checked:bg-primary peer-checked:border-primary transition-all shadow-sm"}),a.jsx(Il,{className:"absolute w-3 h-3 text-primary-foreground opacity-0 peer-checked:opacity-100 left-0.5 transition-opacity"})]}),a.jsx("span",{className:"text-xs font-medium text-muted-foreground group-hover:text-foreground transition-colors",children:"记住登录状态"})]})}),a.jsx("button",{type:"submit",disabled:l,className:"w-full h-12 flex items-center justify-center gap-2 bg-primary text-primary-foreground rounded-xl hover:bg-primary/90 transition-all font-semibold text-sm shadow-lg shadow-primary/20 hover:shadow-primary/30 disabled:opacity-50 disabled:shadow-none",children:l?a.jsx("div",{className:"w-5 h-5 border-2 border-primary-foreground/30 border-t-primary-foreground rounded-full animate-spin"}):a.jsxs("div",{className:"flex items-center gap-2",children:[a.jsx("span",{children:"登录"}),a.jsx(Td,{className:"w-4 h-4"})]})})]}),a.jsx("div",{className:"mt-6 pt-6 border-t border-border flex justify-center",children:a.jsxs("div",{className:"flex items-center gap-1.5 text-[10px] text-muted-foreground/60 font-medium tracking-wide uppercase",children:[a.jsx(Dd,{className:"w-3 h-3"}),a.jsx("span",{children:"安全连接"})]})})]}),a.jsx("div",{className:"mt-8 text-center",children:a.jsx("p",{className:"text-[10px] text-muted-foreground/30 font-mono text-center",children:"DS2API 管理员门户"})})]})})}const To=[{id:"accounts",label:"账号管理",icon:Qy,description:"管理 DeepSeek 账号池"},{id:"test",label:"API 测试",icon:Id,description:"测试 API 连接与响应"},{id:"import",label:"批量导入",icon:bd,description:"批量导入账号配置"},{id:"vercel",label:"Vercel 同步",icon:zd,description:"同步配置到 Vercel"}];function ng({token:e,onLogout:t,config:n,fetchConfig:r,showMessage:l,message:o}){var x,w,N,f;const[s,i]=g.useState("accounts"),[u,c]=g.useState(!1),[y,p]=g.useState(!1),h=async(d,m={})=>{const k={...m.headers,Authorization:`Bearer ${e}`},S=await fetch(d,{...m,headers:k});if(S.status===401)throw t(),new Error("认证已过期,请重新登录");return S},v=()=>{switch(s){case"accounts":return a.jsx(Gy,{config:n,onRefresh:r,onMessage:l,authFetch:h});case"test":return a.jsx(Zy,{config:n,onMessage:l,authFetch:h});case"import":return a.jsx(qy,{onRefresh:r,onMessage:l,authFetch:h});case"vercel":return a.jsx(eg,{onMessage:l,authFetch:h});default:return null}};return a.jsxs("div",{className:"flex h-screen bg-background overflow-hidden text-foreground",children:[u&&a.jsx("div",{className:"fixed inset-0 bg-background/80 backdrop-blur-sm z-40 lg:hidden",onClick:()=>c(!1)}),a.jsxs("aside",{className:ee("fixed lg:static inset-y-0 left-0 z-50 w-64 bg-card border-r border-border transition-transform duration-300 ease-in-out lg:transform-none flex flex-col shadow-2xl lg:shadow-none",u?"translate-x-0":"-translate-x-full"),children:[a.jsxs("div",{className:"p-6",children:[a.jsxs("div",{className:"flex items-center gap-2.5 font-bold text-xl text-foreground tracking-tight",children:[a.jsx("div",{className:"w-8 h-8 rounded-lg bg-primary flex items-center justify-center text-primary-foreground shadow-lg shadow-primary/20",children:a.jsx(Ya,{className:"w-5 h-5"})}),a.jsx("span",{children:"DS2API"})]}),a.jsx("p",{className:"text-[10px] text-muted-foreground mt-2 font-semibold tracking-[0.1em] uppercase opacity-60 px-1",children:"在线管理面板"})]}),a.jsx("nav",{className:"flex-1 px-3 space-y-1 overflow-y-auto pt-2",children:To.map(d=>{const m=d.icon,k=s===d.id;return a.jsxs("button",{onClick:()=>{i(d.id),c(!1)},className:ee("w-full flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm font-medium transition-all duration-200 group border",k?"bg-secondary text-primary border-border shadow-sm":"text-muted-foreground border-transparent hover:bg-secondary/80 hover:text-foreground"),children:[a.jsx(m,{className:ee("w-4 h-4 transition-colors",k?"text-primary":"text-muted-foreground group-hover:text-foreground")}),a.jsx("span",{className:"flex-1 text-left",children:d.label}),k&&a.jsx("div",{className:"w-1.5 h-1.5 rounded-full bg-primary"})]},d.id)})}),a.jsx("div",{className:"p-4 border-t border-border bg-card",children:a.jsxs("div",{className:"space-y-4",children:[a.jsxs("div",{className:"flex items-center justify-between text-sm px-1",children:[a.jsx("span",{className:"text-muted-foreground font-semibold text-[10px] uppercase tracking-wider",children:"系统状态"}),a.jsxs("span",{className:"flex items-center gap-1.5 text-[10px] font-bold text-emerald-500 bg-emerald-500/10 px-2 py-0.5 rounded-full border border-emerald-500/20",children:[a.jsx("span",{className:"w-1.5 h-1.5 rounded-full bg-emerald-500 animate-pulse"}),"在线"]})]}),a.jsxs("div",{className:"grid grid-cols-2 gap-2",children:[a.jsxs("div",{className:"bg-background rounded-lg p-3 border border-border shadow-sm",children:[a.jsx("div",{className:"text-[9px] text-muted-foreground font-bold uppercase tracking-wider mb-0.5 opacity-70",children:"账号"}),a.jsx("div",{className:"text-lg font-bold text-foreground leading-tight",children:((x=n.accounts)==null?void 0:x.length)||0})]}),a.jsxs("div",{className:"bg-background rounded-lg p-3 border border-border shadow-sm",children:[a.jsx("div",{className:"text-[9px] text-muted-foreground font-bold uppercase tracking-wider mb-0.5 opacity-70",children:"密钥"}),a.jsx("div",{className:"text-lg font-bold text-foreground",children:((w=n.keys)==null?void 0:w.length)||0})]})]}),a.jsxs("button",{onClick:t,className:"w-full h-10 flex items-center justify-center gap-2 rounded-lg border border-border text-xs font-medium text-muted-foreground hover:bg-destructive/10 hover:text-destructive hover:border-destructive/20 transition-all",children:[a.jsx(Ny,{className:"w-3.5 h-3.5"}),"退出登录"]})]})})]}),a.jsxs("main",{className:"flex-1 flex flex-col min-w-0 overflow-hidden relative",children:[a.jsxs("header",{className:"lg:hidden h-14 flex items-center justify-between px-4 border-b border-border bg-card",children:[a.jsxs("div",{className:"flex items-center gap-2",children:[a.jsx("div",{className:"w-6 h-6 rounded bg-primary flex items-center justify-center text-primary-foreground text-[10px]",children:a.jsx(Ya,{className:"w-3.5 h-3.5"})}),a.jsx("span",{className:"font-semibold text-sm",children:"DS2API"})]}),a.jsx("button",{onClick:()=>c(!0),className:"p-2 -mr-2 text-muted-foreground hover:text-foreground",children:a.jsx(jy,{className:"w-5 h-5"})})]}),a.jsx("div",{className:"flex-1 overflow-auto bg-background p-4 lg:p-10",children:a.jsxs("div",{className:"max-w-6xl mx-auto space-y-4 lg:space-y-6",children:[a.jsxs("div",{className:"hidden lg:block mb-8",children:[a.jsx("h1",{className:"text-3xl font-bold tracking-tight mb-2",children:(N=To.find(d=>d.id===s))==null?void 0:N.label}),a.jsx("p",{className:"text-muted-foreground",children:(f=To.find(d=>d.id===s))==null?void 0:f.description})]}),o&&a.jsxs("div",{className:ee("p-4 rounded-lg border flex items-center gap-3 animate-in fade-in slide-in-from-top-2",o.type==="error"?"bg-destructive/10 border-destructive/20 text-destructive":"bg-emerald-500/10 border-emerald-500/20 text-emerald-500"),children:[o.type==="error"?a.jsx(Ps,{className:"w-5 h-5"}):a.jsx("div",{className:"w-5 h-5 rounded-full border-2 border-emerald-500 flex items-center justify-center text-[10px]",children:"✓"}),o.text]}),a.jsx("div",{className:"animate-in fade-in duration-500",children:v()})]})})]})]})}function rg(){Ci();const e=ht(),[t,n]=g.useState({keys:[],accounts:[]}),[r,l]=g.useState(!0),[o,s]=g.useState(null),[i,u]=g.useState(null),[c,y]=g.useState(!0),p=!0,h=e.pathname.startsWith("/admin")||p;g.useEffect(()=>{(async()=>{const d=localStorage.getItem("ds2api_token")||sessionStorage.getItem("ds2api_token"),m=parseInt(localStorage.getItem("ds2api_token_expires")||sessionStorage.getItem("ds2api_token_expires")||"0");if(d&&m>Date.now())try{(await fetch("/admin/verify",{headers:{Authorization:`Bearer ${d}`}})).ok?u(d):N()}catch{u(d)}y(!1)})()},[h]);const v=async()=>{if(i)try{l(!0);const f=await fetch("/admin/config",{headers:{Authorization:`Bearer ${i}`}});if(f.ok){const d=await f.json();n(d)}}catch(f){console.error("获取配置失败:",f),x("error",f.message)}finally{l(!1)}};g.useEffect(()=>{i&&v()},[i]);const x=(f,d)=>{s({type:f,text:d}),setTimeout(()=>s(null),5e3)},w=f=>{u(f)},N=()=>{u(null),localStorage.removeItem("ds2api_token"),localStorage.removeItem("ds2api_token_expires"),sessionStorage.removeItem("ds2api_token"),sessionStorage.removeItem("ds2api_token_expires")};return c?a.jsx("div",{className:"min-h-screen flex items-center justify-center bg-background",children:a.jsxs("div",{className:"flex flex-col items-center gap-4",children:[a.jsx("div",{className:"w-8 h-8 border-4 border-primary border-t-transparent rounded-full animate-spin"}),a.jsx("p",{className:"text-muted-foreground animate-pulse",children:"正在检查登录状态..."})]})}):a.jsxs(ch,{children:[!p,a.jsx(Cs,{path:"/",element:i?a.jsx(ng,{token:i,onLogout:N,config:t,fetchConfig:v,showMessage:x,message:o}):a.jsxs("div",{className:"min-h-screen flex flex-col bg-background relative overflow-hidden",children:[a.jsxs("div",{className:"absolute top-0 left-0 w-full h-full overflow-hidden pointer-events-none z-0",children:[a.jsx("div",{className:"absolute top-[-10%] right-[-10%] w-[50%] h-[50%] bg-primary/5 rounded-full blur-[120px]"}),a.jsx("div",{className:"absolute bottom-[-10%] left-[-10%] w-[50%] h-[50%] bg-accent/5 rounded-full blur-[120px]"})]}),o&&a.jsx("div",{className:ee("fixed top-4 right-4 z-50 px-4 py-3 rounded-lg shadow-lg border animate-in slide-in-from-top-2 fade-in",o.type==="error"?"bg-destructive/10 border-destructive/20 text-destructive":"bg-primary/10 border-primary/20 text-primary"),children:o.text}),a.jsx(tg,{onLogin:w,onMessage:x})]})}),a.jsx(Cs,{path:"*",element:a.jsx(ah,{to:"/",replace:!0})})]})}const lg="/admin";zo.createRoot(document.getElementById("root")).render(a.jsx(ef.StrictMode,{children:a.jsx(Ih,{basename:lg,children:a.jsx(rg,{})})})); +}`,spellCheck:!1})}),i&&a.jsx("div",{className:ee("p-4 border-t",i.imported_keys||i.imported_accounts?"bg-emerald-500/10 border-emerald-500/20":"bg-destructive/10 border-destructive/20"),children:a.jsxs("div",{className:"flex items-start gap-3",children:[i.imported_keys||i.imported_accounts?a.jsx(Il,{className:"w-5 h-5 text-emerald-500 mt-0.5"}):a.jsx(Uy,{className:"w-5 h-5 text-destructive mt-0.5"}),a.jsxs("div",{children:[a.jsx("h4",{className:ee("font-medium",i.imported_keys||i.imported_accounts?"text-emerald-500":"text-destructive"),children:"导入操作已完成"}),a.jsxs("p",{className:"text-sm opacity-80 mt-1",children:["成功导入了 ",i.imported_keys," 个 API 密钥,并更新了 ",i.imported_accounts," 个账号。"]})]})]})})]})]})}function eg({onMessage:e,authFetch:t}){const[n,r]=g.useState(""),[l,o]=g.useState(""),[s,i]=g.useState(""),[u,c]=g.useState(!1),[y,p]=g.useState(null),[h,v]=g.useState(null),x=t||fetch;g.useEffect(()=>{(async()=>{try{const f=await x("/admin/vercel/config");if(f.ok){const d=await f.json();v(d),d.project_id&&o(d.project_id),d.team_id&&i(d.team_id)}}catch(f){console.error("Failed to load preconfig:",f)}})()},[]);const w=async()=>{const N=h!=null&&h.has_token&&!n?"__USE_PRECONFIG__":n;if(!N&&!(h!=null&&h.has_token)){e("error","需要 Vercel 访问令牌");return}if(!l){e("error","需要项目 ID");return}c(!0),p(null);try{const f=await x("/admin/vercel/sync",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({vercel_token:N,project_id:l,team_id:s||void 0})}),d=await f.json();f.ok?(p({...d,success:!0}),e("success",d.message)):(p({...d,success:!1}),e("error",d.detail||"同步失败"))}catch{e("error","网络错误")}finally{c(!1)}};return a.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-8 max-w-5xl mx-auto h-[calc(100vh-140px)]",children:[a.jsxs("div",{className:"bg-card border border-border rounded-xl shadow-sm p-6 space-y-6",children:[a.jsxs("div",{className:"border-b border-border pb-6",children:[a.jsxs("h2",{className:"text-xl font-semibold flex items-center gap-2",children:[a.jsx(zd,{className:"w-6 h-6 text-primary"}),"Vercel 部署"]}),a.jsx("p",{className:"text-muted-foreground text-sm mt-1",children:"将当前密钥和账号配置直接同步到 Vercel 环境变量中。"})]}),a.jsxs("div",{className:"space-y-4",children:[a.jsxs("div",{className:"space-y-2",children:[a.jsxs("label",{className:"text-sm font-medium flex items-center justify-between",children:["Vercel 访问令牌",a.jsxs("a",{href:"https://vercel.com/account/tokens",target:"_blank",rel:"noopener noreferrer",className:"text-xs text-primary hover:underline flex items-center gap-1",children:["获取令牌 ",a.jsx(Ja,{className:"w-3 h-3"})]})]}),a.jsxs("div",{className:"relative",children:[a.jsx("input",{type:"password",className:"w-full h-10 px-3 bg-background border border-border rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-ring focus:border-ring transition-all pr-10",placeholder:h!=null&&h.has_token?"正在使用预配置的令牌":"输入 Vercel 访问令牌",value:n,onChange:N=>r(N.target.value)}),(h==null?void 0:h.has_token)&&!n&&a.jsx("div",{className:"absolute right-3 top-2.5 text-emerald-500",children:a.jsx(Dl,{className:"w-5 h-5"})})]})]}),a.jsxs("div",{className:"space-y-2",children:[a.jsx("label",{className:"text-sm font-medium",children:"项目 ID"}),a.jsx("input",{type:"text",className:"w-full h-10 px-3 bg-background border border-border rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-ring focus:border-ring transition-all",placeholder:"prj_xxxxxxxxxxxx or Project Name",value:l,onChange:N=>o(N.target.value)}),a.jsx("p",{className:"text-xs text-muted-foreground",children:"可在项目设置 (Project Settings) → 常规 (General) 中找到"})]}),a.jsxs("div",{className:"space-y-2",children:[a.jsxs("label",{className:"text-sm font-medium flex items-center gap-2",children:["团队 ID ",a.jsx("span",{className:"text-xs text-muted-foreground font-normal",children:"(可选)"})]}),a.jsx("input",{type:"text",className:"w-full h-10 px-3 bg-background border border-border rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-ring focus:border-ring transition-all",placeholder:"team_xxxxxxxxxxxx",value:s,onChange:N=>i(N.target.value)})]})]}),a.jsxs("div",{className:"pt-4",children:[a.jsx("button",{onClick:w,disabled:u,className:"w-full flex items-center justify-center gap-2 py-3 bg-primary text-primary-foreground rounded-lg hover:bg-primary/90 transition-all font-medium text-sm shadow-sm hover:shadow-md disabled:opacity-50 disabled:shadow-none",children:u?a.jsxs("span",{className:"flex items-center gap-2",children:[a.jsx("span",{className:"w-4 h-4 border-2 border-current border-t-transparent rounded-full animate-spin"}),"正在同步..."]}):a.jsxs("span",{className:"flex items-center gap-2",children:["同步并重新部署 ",a.jsx(Td,{className:"w-4 h-4"})]})}),a.jsx("p",{className:"text-xs text-center text-muted-foreground mt-4",children:"这将触发 Vercel 的重新部署,大约需要 30-60 秒。"})]})]}),a.jsxs("div",{className:"space-y-6",children:[y&&a.jsx("div",{className:`p-6 rounded-xl border ${y.success?"bg-emerald-500/10 border-emerald-500/20":"bg-destructive/10 border-destructive/20"} animate-in fade-in slide-in-from-right-4`,children:a.jsxs("div",{className:"flex items-start gap-4",children:[y.success?a.jsx("div",{className:"p-2 bg-emerald-500 text-white rounded-full shadow-lg shadow-emerald-500/30",children:a.jsx(Dl,{className:"w-6 h-6"})}):a.jsx("div",{className:"p-2 bg-destructive text-white rounded-full shadow-lg shadow-destructive/30",children:a.jsx(ny,{className:"w-6 h-6"})}),a.jsxs("div",{className:"space-y-1",children:[a.jsx("h3",{className:`font-semibold text-lg ${y.success?"text-emerald-500":"text-destructive"}`,children:y.success?"同步成功":"同步失败"}),a.jsx("p",{className:"text-sm opacity-90",children:y.message}),y.deployment_url&&a.jsx("div",{className:"pt-3 mt-3 border-t border-emerald-500/20",children:a.jsxs("a",{href:`https://${y.deployment_url}`,target:"_blank",rel:"noopener noreferrer",className:"inline-flex items-center gap-1 text-sm font-medium hover:underline",children:["访问部署地址 ",a.jsx(Ja,{className:"w-3 h-3"})]})})]})]})}),a.jsxs("div",{className:"bg-secondary/20 border border-border rounded-xl p-6",children:[a.jsxs("h3",{className:"font-semibold flex items-center gap-2 mb-4",children:[a.jsx(py,{className:"w-5 h-5 text-primary"}),"工作原理"]}),a.jsxs("ul",{className:"space-y-4",children:[a.jsxs("li",{className:"flex gap-3",children:[a.jsx("span",{className:"shrink-0 w-6 h-6 rounded-full bg-background border border-border flex items-center justify-center text-xs font-bold text-muted-foreground",children:"1"}),a.jsx("p",{className:"text-sm text-muted-foreground",children:"当前配置 (密钥和账号) 被导出为 JSON 字符串。"})]}),a.jsxs("li",{className:"flex gap-3",children:[a.jsx("span",{className:"shrink-0 w-6 h-6 rounded-full bg-background border border-border flex items-center justify-center text-xs font-bold text-muted-foreground",children:"2"}),a.jsx("p",{className:"text-sm text-muted-foreground",children:"JSON 被编码为 Base64 以确保格式兼容性。"})]}),a.jsxs("li",{className:"flex gap-3",children:[a.jsx("span",{className:"shrink-0 w-6 h-6 rounded-full bg-background border border-border flex items-center justify-center text-xs font-bold text-muted-foreground",children:"3"}),a.jsxs("p",{className:"text-sm text-muted-foreground",children:["更新 Vercel 项目中的 ",a.jsx("code",{className:"bg-background px-1 py-0.5 rounded border border-border text-xs",children:"DS2API_CONFIG_JSON"})," 环境变量。"]})]}),a.jsxs("li",{className:"flex gap-3",children:[a.jsx("span",{className:"shrink-0 w-6 h-6 rounded-full bg-background border border-border flex items-center justify-center text-xs font-bold text-muted-foreground",children:"4"}),a.jsx("p",{className:"text-sm text-muted-foreground",children:"触发重新部署以应用新的环境变量。"})]})]})]})]})]})}function tg({onLogin:e,onMessage:t}){const[n,r]=g.useState(""),[l,o]=g.useState(!1),[s,i]=g.useState(!0),u=async c=>{if(c.preventDefault(),!!n.trim()){o(!0);try{const y=await fetch("/admin/login",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({admin_key:n})}),p=await y.json();if(y.ok&&p.success){const h=s?localStorage:sessionStorage;h.setItem("ds2api_token",p.token),h.setItem("ds2api_token_expires",Date.now()+p.expires_in*1e3),e(p.token),p.message&&t("warning",p.message)}else t("error",p.detail||"登录失败")}catch(y){t("error","网络错误: "+y.message)}finally{o(!1)}}};return a.jsx("div",{className:"min-h-screen w-full flex flex-col items-center justify-center p-4 bg-background text-foreground",children:a.jsxs("div",{className:"w-full max-w-[400px] relative z-10 animate-in fade-in zoom-in-95 duration-200",children:[a.jsxs("div",{className:"w-full bg-card border border-border rounded-xl p-8 shadow-sm",children:[a.jsxs("div",{className:"text-center space-y-2 mb-8 animate-in fade-in slide-in-from-top-4 duration-500",children:[a.jsx("div",{className:"inline-flex items-center justify-center w-12 h-12 rounded-xl bg-primary/10 text-primary mb-2",children:a.jsx(wy,{className:"w-6 h-6"})}),a.jsx("h1",{className:"text-3xl font-bold tracking-tight text-foreground",children:"欢迎回来"}),a.jsx("p",{className:"text-sm text-muted-foreground/80",children:"请输入管理员密钥以继续"})]}),a.jsxs("form",{onSubmit:u,className:"space-y-5 animate-in fade-in slide-in-from-bottom-4 duration-700 delay-150",children:[a.jsxs("div",{className:"space-y-2",children:[a.jsx("label",{className:"text-xs font-semibold text-muted-foreground uppercase tracking-widest ml-1",children:"管理员密钥"}),a.jsxs("div",{className:"relative group",children:[a.jsx("div",{className:"absolute inset-y-0 left-0 pl-3.5 flex items-center pointer-events-none text-muted-foreground group-focus-within:text-primary transition-colors",children:a.jsx(hy,{className:"w-4 h-4"})}),a.jsx("input",{type:"password",className:"w-full bg-[#09090b] border border-border rounded-xl pl-10 pr-4 py-3 text-sm focus:ring-2 focus:ring-primary/20 focus:border-primary transition-all placeholder:text-muted-foreground/30 text-foreground",placeholder:"输入您的管理员密钥...",value:n,onChange:c=>r(c.target.value),autoFocus:!0})]})]}),a.jsx("div",{className:"flex items-center justify-between px-1",children:a.jsxs("label",{className:"flex items-center gap-2.5 cursor-pointer group",children:[a.jsxs("div",{className:"relative flex items-center",children:[a.jsx("input",{type:"checkbox",className:"peer sr-only",checked:s,onChange:c=>i(c.target.checked)}),a.jsx("div",{className:"w-4.5 h-4.5 bg-secondary border border-border rounded-md peer-checked:bg-primary peer-checked:border-primary transition-all shadow-sm"}),a.jsx(Il,{className:"absolute w-3 h-3 text-primary-foreground opacity-0 peer-checked:opacity-100 left-0.5 transition-opacity"})]}),a.jsx("span",{className:"text-xs font-medium text-muted-foreground group-hover:text-foreground transition-colors",children:"记住登录状态"})]})}),a.jsx("button",{type:"submit",disabled:l,className:"w-full h-12 flex items-center justify-center gap-2 bg-primary text-primary-foreground rounded-xl hover:bg-primary/90 transition-all font-semibold text-sm shadow-lg shadow-primary/20 hover:shadow-primary/30 disabled:opacity-50 disabled:shadow-none",children:l?a.jsx("div",{className:"w-5 h-5 border-2 border-primary-foreground/30 border-t-primary-foreground rounded-full animate-spin"}):a.jsxs("div",{className:"flex items-center gap-2",children:[a.jsx("span",{children:"登录"}),a.jsx(Td,{className:"w-4 h-4"})]})})]}),a.jsx("div",{className:"mt-6 pt-6 border-t border-border flex justify-center",children:a.jsxs("div",{className:"flex items-center gap-1.5 text-[10px] text-muted-foreground/60 font-medium tracking-wide uppercase",children:[a.jsx(Dd,{className:"w-3 h-3"}),a.jsx("span",{children:"安全连接"})]})})]}),a.jsx("div",{className:"mt-8 text-center",children:a.jsx("p",{className:"text-[10px] text-muted-foreground/30 font-mono text-center",children:"DS2API 管理员门户"})})]})})}const To=[{id:"accounts",label:"账号管理",icon:Qy,description:"管理 DeepSeek 账号池"},{id:"test",label:"API 测试",icon:Id,description:"测试 API 连接与响应"},{id:"import",label:"批量导入",icon:bd,description:"批量导入账号配置"},{id:"vercel",label:"Vercel 同步",icon:zd,description:"同步配置到 Vercel"}];function ng({token:e,onLogout:t,config:n,fetchConfig:r,showMessage:l,message:o}){var x,w,N,f;const[s,i]=g.useState("accounts"),[u,c]=g.useState(!1),[y,p]=g.useState(!1),h=async(d,m={})=>{const k={...m.headers,Authorization:`Bearer ${e}`},S=await fetch(d,{...m,headers:k});if(S.status===401)throw t(),new Error("认证已过期,请重新登录");return S},v=()=>{switch(s){case"accounts":return a.jsx(Gy,{config:n,onRefresh:r,onMessage:l,authFetch:h});case"test":return a.jsx(Zy,{config:n,onMessage:l,authFetch:h});case"import":return a.jsx(qy,{onRefresh:r,onMessage:l,authFetch:h});case"vercel":return a.jsx(eg,{onMessage:l,authFetch:h});default:return null}};return a.jsxs("div",{className:"flex h-screen bg-background overflow-hidden text-foreground",children:[u&&a.jsx("div",{className:"fixed inset-0 bg-background/80 backdrop-blur-sm z-40 lg:hidden",onClick:()=>c(!1)}),a.jsxs("aside",{className:ee("fixed lg:static inset-y-0 left-0 z-50 w-64 bg-card border-r border-border transition-transform duration-300 ease-in-out lg:transform-none flex flex-col shadow-2xl lg:shadow-none",u?"translate-x-0":"-translate-x-full"),children:[a.jsxs("div",{className:"p-6",children:[a.jsxs("div",{className:"flex items-center gap-2.5 font-bold text-xl text-foreground tracking-tight",children:[a.jsx("div",{className:"w-8 h-8 rounded-lg bg-primary flex items-center justify-center text-primary-foreground shadow-lg shadow-primary/20",children:a.jsx(Ya,{className:"w-5 h-5"})}),a.jsx("span",{children:"DS2API"})]}),a.jsx("p",{className:"text-[10px] text-muted-foreground mt-2 font-semibold tracking-[0.1em] uppercase opacity-60 px-1",children:"在线管理面板"})]}),a.jsx("nav",{className:"flex-1 px-3 space-y-1 overflow-y-auto pt-2",children:To.map(d=>{const m=d.icon,k=s===d.id;return a.jsxs("button",{onClick:()=>{i(d.id),c(!1)},className:ee("w-full flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm font-medium transition-all duration-200 group border",k?"bg-secondary text-primary border-border shadow-sm":"text-muted-foreground border-transparent hover:bg-secondary/80 hover:text-foreground"),children:[a.jsx(m,{className:ee("w-4 h-4 transition-colors",k?"text-primary":"text-muted-foreground group-hover:text-foreground")}),a.jsx("span",{className:"flex-1 text-left",children:d.label}),k&&a.jsx("div",{className:"w-1.5 h-1.5 rounded-full bg-primary"})]},d.id)})}),a.jsx("div",{className:"p-4 border-t border-border bg-card",children:a.jsxs("div",{className:"space-y-4",children:[a.jsxs("div",{className:"flex items-center justify-between text-sm px-1",children:[a.jsx("span",{className:"text-muted-foreground font-semibold text-[10px] uppercase tracking-wider",children:"系统状态"}),a.jsxs("span",{className:"flex items-center gap-1.5 text-[10px] font-bold text-emerald-500 bg-emerald-500/10 px-2 py-0.5 rounded-full border border-emerald-500/20",children:[a.jsx("span",{className:"w-1.5 h-1.5 rounded-full bg-emerald-500 animate-pulse"}),"在线"]})]}),a.jsxs("div",{className:"grid grid-cols-2 gap-2",children:[a.jsxs("div",{className:"bg-background rounded-lg p-3 border border-border shadow-sm",children:[a.jsx("div",{className:"text-[9px] text-muted-foreground font-bold uppercase tracking-wider mb-0.5 opacity-70",children:"账号"}),a.jsx("div",{className:"text-lg font-bold text-foreground leading-tight",children:((x=n.accounts)==null?void 0:x.length)||0})]}),a.jsxs("div",{className:"bg-background rounded-lg p-3 border border-border shadow-sm",children:[a.jsx("div",{className:"text-[9px] text-muted-foreground font-bold uppercase tracking-wider mb-0.5 opacity-70",children:"密钥"}),a.jsx("div",{className:"text-lg font-bold text-foreground",children:((w=n.keys)==null?void 0:w.length)||0})]})]}),a.jsxs("button",{onClick:t,className:"w-full h-10 flex items-center justify-center gap-2 rounded-lg border border-border text-xs font-medium text-muted-foreground hover:bg-destructive/10 hover:text-destructive hover:border-destructive/20 transition-all",children:[a.jsx(Ny,{className:"w-3.5 h-3.5"}),"退出登录"]})]})})]}),a.jsxs("main",{className:"flex-1 flex flex-col min-w-0 overflow-hidden relative",children:[a.jsxs("header",{className:"lg:hidden h-14 flex items-center justify-between px-4 border-b border-border bg-card",children:[a.jsxs("div",{className:"flex items-center gap-2",children:[a.jsx("div",{className:"w-6 h-6 rounded bg-primary flex items-center justify-center text-primary-foreground text-[10px]",children:a.jsx(Ya,{className:"w-3.5 h-3.5"})}),a.jsx("span",{className:"font-semibold text-sm",children:"DS2API"})]}),a.jsx("button",{onClick:()=>c(!0),className:"p-2 -mr-2 text-muted-foreground hover:text-foreground",children:a.jsx(jy,{className:"w-5 h-5"})})]}),a.jsx("div",{className:"flex-1 overflow-auto bg-background p-4 lg:p-10",children:a.jsxs("div",{className:"max-w-6xl mx-auto space-y-4 lg:space-y-6",children:[a.jsxs("div",{className:"hidden lg:block mb-8",children:[a.jsx("h1",{className:"text-3xl font-bold tracking-tight mb-2",children:(N=To.find(d=>d.id===s))==null?void 0:N.label}),a.jsx("p",{className:"text-muted-foreground",children:(f=To.find(d=>d.id===s))==null?void 0:f.description})]}),o&&a.jsxs("div",{className:ee("p-4 rounded-lg border flex items-center gap-3 animate-in fade-in slide-in-from-top-2",o.type==="error"?"bg-destructive/10 border-destructive/20 text-destructive":"bg-emerald-500/10 border-emerald-500/20 text-emerald-500"),children:[o.type==="error"?a.jsx(Ps,{className:"w-5 h-5"}):a.jsx("div",{className:"w-5 h-5 rounded-full border-2 border-emerald-500 flex items-center justify-center text-[10px]",children:"✓"}),o.text]}),a.jsx("div",{className:"animate-in fade-in duration-500",children:v()})]})})]})]})}function rg(){Ci();const e=ht(),[t,n]=g.useState({keys:[],accounts:[]}),[r,l]=g.useState(!0),[o,s]=g.useState(null),[i,u]=g.useState(null),[c,y]=g.useState(!0),p=!0,h=e.pathname.startsWith("/admin")||p;g.useEffect(()=>{(async()=>{const d=localStorage.getItem("ds2api_token")||sessionStorage.getItem("ds2api_token"),m=parseInt(localStorage.getItem("ds2api_token_expires")||sessionStorage.getItem("ds2api_token_expires")||"0");if(d&&m>Date.now())try{(await fetch("/admin/verify",{headers:{Authorization:`Bearer ${d}`}})).ok?u(d):N()}catch{u(d)}y(!1)})()},[h]);const v=async()=>{if(i)try{l(!0);const f=await fetch("/admin/config",{headers:{Authorization:`Bearer ${i}`}});if(f.ok){const d=await f.json();n(d)}}catch(f){console.error("获取配置失败:",f),x("error",f.message)}finally{l(!1)}};g.useEffect(()=>{i&&v()},[i]);const x=(f,d)=>{s({type:f,text:d}),setTimeout(()=>s(null),5e3)},w=f=>{u(f)},N=()=>{u(null),localStorage.removeItem("ds2api_token"),localStorage.removeItem("ds2api_token_expires"),sessionStorage.removeItem("ds2api_token"),sessionStorage.removeItem("ds2api_token_expires")};return c?a.jsx("div",{className:"min-h-screen flex items-center justify-center bg-background",children:a.jsxs("div",{className:"flex flex-col items-center gap-4",children:[a.jsx("div",{className:"w-8 h-8 border-4 border-primary border-t-transparent rounded-full animate-spin"}),a.jsx("p",{className:"text-muted-foreground animate-pulse",children:"正在检查登录状态..."})]})}):a.jsxs(ch,{children:[!p,a.jsx(Cs,{path:"/",element:i?a.jsx(ng,{token:i,onLogout:N,config:t,fetchConfig:v,showMessage:x,message:o}):a.jsxs("div",{className:"min-h-screen flex flex-col bg-background relative overflow-hidden",children:[a.jsxs("div",{className:"absolute top-0 left-0 w-full h-full overflow-hidden pointer-events-none z-0",children:[a.jsx("div",{className:"absolute top-[-10%] right-[-10%] w-[50%] h-[50%] bg-primary/5 rounded-full blur-[120px]"}),a.jsx("div",{className:"absolute bottom-[-10%] left-[-10%] w-[50%] h-[50%] bg-accent/5 rounded-full blur-[120px]"})]}),o&&a.jsx("div",{className:ee("fixed top-4 right-4 z-50 px-4 py-3 rounded-lg shadow-lg border animate-in slide-in-from-top-2 fade-in",o.type==="error"?"bg-destructive/10 border-destructive/20 text-destructive":"bg-primary/10 border-primary/20 text-primary"),children:o.text}),a.jsx(tg,{onLogin:w,onMessage:x})]})}),a.jsx(Cs,{path:"*",element:a.jsx(ah,{to:"/",replace:!0})})]})}const lg="/admin";zo.createRoot(document.getElementById("root")).render(a.jsx(ef.StrictMode,{children:a.jsx(Ih,{basename:lg,children:a.jsx(rg,{})})})); diff --git a/static/admin/index.html b/static/admin/index.html index 76e4e9d..16993f2 100644 --- a/static/admin/index.html +++ b/static/admin/index.html @@ -32,7 +32,7 @@ - +