34 lines
13 KiB
JavaScript
34 lines
13 KiB
JavaScript
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/index-BxnC8qm_.js","assets/index-kfEUZTBu.css"])))=>i.map(i=>d[i]);
|
||
import{c as o,u as me,d as ue,_ as he,f as I,$ as F,r as i,g as p,j as e,E as y,B as n,a0 as Y,m as c,k as ee,a1 as se,T as ae,P as pe,I as b,l as ve,F as je,a2 as ge,a3 as ye,a4 as be,a5 as ke,a6 as fe,a7 as Ne,a8 as _e,a9 as Ce}from"./index-BxnC8qm_.js";import{C as q,a as T,b as D}from"./card-DI4NY5IV.js";/**
|
||
* @license lucide-react v0.475.0 - ISC
|
||
*
|
||
* This source code is licensed under the ISC license.
|
||
* See the LICENSE file in the root directory of this source tree.
|
||
*/const we=[["path",{d:"M20 6 9 17l-5-5",key:"1gmf2c"}]],te=o("Check",we);/**
|
||
* @license lucide-react v0.475.0 - ISC
|
||
*
|
||
* This source code is licensed under the ISC license.
|
||
* See the LICENSE file in the root directory of this source tree.
|
||
*/const ze=[["rect",{width:"14",height:"14",x:"8",y:"8",rx:"2",ry:"2",key:"17jyea"}],["path",{d:"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2",key:"zix9uf"}]],Me=o("Copy",ze);/**
|
||
* @license lucide-react v0.475.0 - ISC
|
||
*
|
||
* This source code is licensed under the ISC license.
|
||
* See the LICENSE file in the root directory of this source tree.
|
||
*/const Se=[["path",{d:"M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8",key:"v9h5vc"}],["path",{d:"M21 3v5h-5",key:"1q7to0"}],["path",{d:"M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16",key:"3uifl3"}],["path",{d:"M8 16H3v5",key:"1cv678"}]],Ee=o("RefreshCw",Se);/**
|
||
* @license lucide-react v0.475.0 - ISC
|
||
*
|
||
* This source code is licensed under the ISC license.
|
||
* See the LICENSE file in the root directory of this source tree.
|
||
*/const Ie=[["path",{d:"M2 9a3 3 0 0 1 0 6v2a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-2a3 3 0 0 1 0-6V7a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2Z",key:"qn84l0"}],["path",{d:"m9 12 2 2 4-4",key:"dzmm74"}]],Fe=o("TicketCheck",Ie);/**
|
||
* @license lucide-react v0.475.0 - ISC
|
||
*
|
||
* This source code is licensed under the ISC license.
|
||
* See the LICENSE file in the root directory of this source tree.
|
||
*/const qe=[["path",{d:"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3",key:"wmoenq"}],["path",{d:"M12 9v4",key:"juzpu7"}],["path",{d:"M12 17h.01",key:"p32p05"}]],ne=o("TriangleAlert",qe);/**
|
||
* @license lucide-react v0.475.0 - ISC
|
||
*
|
||
* This source code is licensed under the ISC license.
|
||
* See the LICENSE file in the root directory of this source tree.
|
||
*/const Te=[["path",{d:"M18 21a8 8 0 0 0-16 0",key:"3ypg7q"}],["circle",{cx:"10",cy:"8",r:"5",key:"o932ke"}],["path",{d:"M22 20c0-3.37-2-6.5-4-8a5 5 0 0 0-.45-8.3",key:"10s06x"}]],ie=o("UsersRound",Te);function De({i:d}){return d.used_by?e.jsx(c,{color:"var(--text-3)",children:"已使用"}):d.valid?e.jsx(c,{color:"var(--success)",children:"可用"}):e.jsx(c,{color:"var(--warning)",children:"已停用"})}function Re(){var V,G,W,X,U,Z;const d=me(),re=ue(),r=he(),k=I({queryKey:["me-admin"],queryFn:async()=>(await Ne(()=>import("./index-BxnC8qm_.js").then(t=>t.ai),__vite__mapDeps([0,1]))).serverMe(r),enabled:!!F()}),x=I({queryKey:["admin-users"],queryFn:()=>_e(r),enabled:!!F()}),f=I({queryKey:["admin-invites"],queryFn:()=>Ce(r),enabled:!!F()}),[P,l]=i.useState(""),[le,Q]=i.useState(null),[de,N]=i.useState(!1),[v,_]=i.useState(""),[R,C]=i.useState(""),[ce,m]=i.useState(null),[w,z]=i.useState(""),[u,oe]=i.useState("all"),[a,j]=i.useState(null),[K,M]=i.useState(""),g=()=>{d.invalidateQueries({queryKey:["admin-invites"]})},h=s=>l(s.message||"操作失败"),A=p({mutationFn:s=>fe(s,r),onSuccess:s=>{d.invalidateQueries({queryKey:["admin-users"]}),j(null),M(""),l(""),re("success","用户「"+s.username+"」及其全部数据已删除")},onError:h}),L=p({mutationFn:()=>ge(5,r),onSuccess:s=>{g(),l(""),navigator.clipboard.writeText(s.codes.join(`
|
||
`)).catch(()=>{})},onError:h}),S=p({mutationFn:()=>ye(v.trim(),R.trim(),r),onSuccess:()=>{g(),N(!1),_(""),C(""),l("")},onError:h}),E=p({mutationFn:s=>be(s.id,s.patch,r),onSuccess:()=>{g(),m(null),l("")},onError:h}),xe=p({mutationFn:s=>ke(s,r),onSuccess:()=>{g(),l("")},onError:h}),$=i.useMemo(()=>{var s;return((s=f.data)==null?void 0:s.invites)??[]},[f.data]),O=((V=x.data)==null?void 0:V.users)??[],B=i.useMemo(()=>$.filter(s=>u==="valid"?s.valid&&!s.used_by:u==="used"?!!s.used_by:u==="disabled"?!s.valid&&!s.used_by:!0),[$,u]);if(k.data&&!k.data.is_admin)return e.jsx(y,{title:"需要管理员账号",description:"当前登录账号不是管理员。"});const H=s=>{navigator.clipboard.writeText(s.code),Q(s.id),setTimeout(()=>Q(t=>t===s.id?null:t),1500)};return e.jsxs("div",{className:"mx-auto max-w-[1080px] px-3 py-4 sm:px-6 sm:py-5",children:[e.jsxs("div",{className:"mb-4 flex items-center justify-between",children:[e.jsx("h2",{className:"text-[15px] font-semibold text-ink-1",children:"管理"}),e.jsxs(n,{variant:"secondary",onClick:()=>{d.invalidateQueries()},children:[e.jsx(Ee,{size:13})," 刷新"]})]}),P&&e.jsxs("div",{className:"mb-3 flex items-center justify-between rounded-md border border-danger/30 bg-danger-subtle px-3 py-2 text-[12px] text-danger",children:[e.jsx("span",{children:P}),e.jsx("button",{className:"rounded p-0.5 hover:bg-surface-3",onClick:()=>l(""),"aria-label":"关闭",children:e.jsx(Y,{size:13})})]}),e.jsxs(q,{children:[e.jsx(T,{title:"用户管理("+(((G=x.data)==null?void 0:G.total)??0)+")",extra:e.jsx(ie,{size:14,className:"text-ink-3"})}),e.jsx(D,{className:"p-0",children:e.jsxs("div",{className:"divide-y divide-line",children:[(((W=x.data)==null?void 0:W.users)??[]).map(s=>{var J;const t=String(s.id)===String(((J=k.data)==null?void 0:J.user_id)??"");return e.jsxs("div",{className:"flex items-center gap-3 px-4 py-2.5",children:[e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"truncate text-[13px] font-medium text-ink-1",children:s.username}),s.is_admin&&e.jsx(c,{color:"var(--brand-text)",children:"管理员"}),t&&e.jsx(c,{color:"var(--text-3)",children:"当前登录"})]}),e.jsxs("div",{className:"num mt-0.5 text-[11px] text-ink-3",children:[ee(s.created_at)," · 记录 ",s.records," · 附件 ",s.attachments,"(",se(s.attachment_bytes||0),")"]})]}),!t&&e.jsxs(n,{size:"sm",variant:"ghost",className:"text-danger hover:bg-danger-subtle",onClick:()=>{j({id:s.id,username:s.username}),M("")},children:[e.jsx(ae,{size:13})," 删除"]})]},s.id)}),!(((X=x.data)==null?void 0:X.users)??[]).length&&e.jsx(y,{title:"暂无用户"})]})})]}),e.jsxs("div",{className:"grid grid-cols-1 gap-4 lg:grid-cols-2",children:[e.jsxs(q,{children:[e.jsx(T,{title:"邀请码("+(((U=f.data)==null?void 0:U.total)??0)+")",extra:e.jsxs("div",{className:"flex gap-1.5",children:[e.jsxs(n,{size:"sm",variant:"secondary",onClick:()=>{N(s=>!s),l("")},children:[e.jsx(pe,{size:13})," 新建"]}),e.jsx(n,{size:"sm",variant:"primary",disabled:L.isPending,onClick:()=>L.mutate(),children:"批量生成 5 个"})]})}),e.jsxs(D,{className:"p-0",children:[de&&e.jsxs("div",{className:"flex flex-wrap items-end gap-2 border-b border-line bg-surface-2 px-4 py-3",children:[e.jsxs("label",{className:"flex flex-col gap-1",children:[e.jsx("span",{className:"text-[11px] font-medium text-ink-3",children:"邀请码(4-32 位字母数字-_)"}),e.jsx(b,{className:"w-[210px]",value:v,placeholder:"如 XIONG-2025",onChange:s=>_(s.target.value)})]}),e.jsxs("label",{className:"flex flex-col gap-1",children:[e.jsx("span",{className:"text-[11px] font-medium text-ink-3",children:"备注(可选)"}),e.jsx(b,{className:"w-[180px]",value:R,placeholder:"发给谁 / 用途",onChange:s=>C(s.target.value),onKeyDown:s=>{s.key==="Enter"&&v.trim()&&S.mutate()}})]}),e.jsxs("div",{className:"flex gap-1.5 pb-0.5",children:[e.jsx(n,{size:"sm",variant:"primary",disabled:!v.trim()||S.isPending,onClick:()=>S.mutate(),children:"创建"}),e.jsx(n,{size:"sm",variant:"ghost",onClick:()=>{N(!1),_(""),C("")},children:"取消"})]})]}),e.jsx("div",{className:"flex gap-1 border-b border-line px-4 py-2 text-[12px]",children:[["all","全部"],["valid","可用"],["used","已使用"],["disabled","已停用"]].map(([s,t])=>e.jsx("button",{className:"rounded-md px-2.5 py-1 transition-colors "+(u===s?"bg-brand-subtle font-medium text-brand-text":"text-ink-3 hover:bg-surface-3"),onClick:()=>oe(s),children:t},s))}),B.length?e.jsx("div",{className:"divide-y divide-line max-h-[430px] overflow-y-auto",children:B.map(s=>e.jsxs("div",{className:"flex flex-wrap items-center gap-2 px-4 py-2.5 text-[12.5px]",children:[e.jsx("button",{className:"num shrink-0 cursor-pointer rounded-sm bg-surface-3 px-1.5 py-0.5 font-mono text-[12px] text-ink-1 transition-colors hover:bg-brand-subtle hover:text-brand-text",title:"点击复制",onClick:()=>H(s),children:le===s.id?e.jsxs("span",{className:"inline-flex items-center gap-1 text-success",children:[e.jsx(te,{size:11}),"已复制"]}):s.code}),e.jsx(De,{i:s}),ce===s.id?e.jsxs("span",{className:"ml-1 flex min-w-0 flex-1 items-center gap-1",children:[e.jsx(b,{className:"h-7 flex-1 text-[12px]",value:w,autoFocus:!0,placeholder:"备注(64 字以内)",onChange:t=>z(t.target.value),onKeyDown:t=>{t.key==="Enter"&&E.mutate({id:s.id,patch:{remark:w}}),t.key==="Escape"&&m(null)}}),e.jsx(n,{size:"icon-sm",variant:"ghost","aria-label":"保存备注",className:"text-success",onClick:()=>E.mutate({id:s.id,patch:{remark:w}}),children:e.jsx(te,{size:13})}),e.jsx(n,{size:"icon-sm",variant:"ghost","aria-label":"取消",className:"text-ink-3",onClick:()=>m(null),children:e.jsx(Y,{size:13})})]}):e.jsx("button",{className:"min-w-0 flex-1 truncate text-left text-[12px] text-ink-3 hover:text-ink-2",title:s.remark?"点击编辑备注":s.created_by_name?"由 "+s.created_by_name+" 创建 · 点击添加备注":"点击添加备注",onClick:()=>{m(s.id),z(s.remark??"")},children:s.remark||(s.created_by_name?"由 "+s.created_by_name+" 创建":e.jsx("span",{className:"opacity-60",children:"添加备注…"}))}),s.used_by_name&&e.jsxs("span",{className:"shrink-0 text-ink-3",children:["被 ",s.used_by_name," 使用于 ",ee(s.used_at)]}),e.jsxs("span",{className:"ml-auto flex shrink-0 items-center gap-0.5",children:[e.jsx(n,{size:"icon-sm",variant:"ghost","aria-label":"复制",className:"text-ink-3",onClick:()=>H(s),children:e.jsx(Me,{size:13})}),!s.used_by&&e.jsxs(e.Fragment,{children:[e.jsx(n,{size:"icon-sm",variant:"ghost","aria-label":"编辑备注",className:"text-ink-3",onClick:()=>{m(s.id),z(s.remark??"")},children:e.jsx(ve,{size:13})}),e.jsx(n,{size:"sm",variant:"ghost",className:s.valid?"text-ink-3 hover:text-warning":"text-ink-3 hover:text-success",onClick:()=>E.mutate({id:s.id,patch:{valid:!s.valid}}),children:s.valid?"停用":"启用"})]}),e.jsx(n,{size:"icon-sm",variant:"ghost","aria-label":"删除",className:"text-ink-3 hover:text-danger",onClick:()=>{window.confirm("删除邀请码 "+s.code+"?此操作不可恢复。")&&xe.mutate(s.id)},children:e.jsx(ae,{size:13})})]})]},s.id))}):e.jsx(y,{icon:e.jsx(Fe,{size:32,strokeWidth:1.5}),title:"暂无符合条件的邀请码",description:"新建自定义邀请码,或批量生成后发给需要注册的用户。"})]})]}),e.jsxs(q,{children:[e.jsx(T,{title:"用户("+(((Z=x.data)==null?void 0:Z.total)??0)+")"}),e.jsx(D,{className:"p-0",children:O.length?e.jsx("div",{className:"divide-y divide-line max-h-[520px] overflow-y-auto",children:O.map(s=>e.jsxs("div",{className:"flex flex-wrap items-center gap-2 px-4 py-2.5 text-[12.5px]",children:[e.jsx("span",{className:"font-medium text-ink-1",children:s.username}),s.is_admin&&e.jsx(c,{color:"var(--brand-text)",children:"管理员"}),e.jsxs("span",{className:"num ml-auto text-ink-3",children:[s.devices," 设备 · ",s.records," 记录 · ",se(s.attachment_bytes)]})]},s.id))}):e.jsx(y,{icon:e.jsx(ie,{size:32,strokeWidth:1.5}),title:"暂无用户"})})]})]}),e.jsx(je,{open:!!a,onClose:()=>j(null),width:460,title:"删除用户(高危操作)",footer:e.jsxs(e.Fragment,{children:[e.jsx(n,{variant:"ghost",onClick:()=>j(null),children:"取消"}),e.jsxs(n,{variant:"primary",className:"!bg-danger !text-white",disabled:K!==(a==null?void 0:a.username)||A.isPending,onClick:()=>a&&A.mutate(a.id),children:[e.jsx(ne,{size:13})," 永久删除"]})]}),children:e.jsxs("div",{className:"flex flex-col gap-3 text-[12.5px]",children:[e.jsxs("div",{className:"flex items-start gap-2 rounded-md border border-danger/30 bg-danger-subtle px-3 py-2.5 text-danger",children:[e.jsx(ne,{size:15,className:"mt-0.5 shrink-0"}),e.jsxs("div",{children:[e.jsx("b",{children:"此操作不可撤销!"}),"将永久删除用户「",a==null?void 0:a.username,"」的全部数据:",e.jsxs("ul",{className:"mt-1 list-disc pl-4 text-[12px] leading-relaxed",children:[e.jsx("li",{children:"账号与登录会话(所有设备将被登出)"}),e.jsx("li",{children:"全部记录、成绩、维度与统计数据"}),e.jsx("li",{children:"全部附件文件(服务器本地与图床 COS 上的副本)"})]})]})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"mb-1.5 text-ink-2",children:["请输入用户名 ",e.jsx("b",{className:"text-danger",children:a==null?void 0:a.username})," 以确认:"]}),e.jsx(b,{value:K,onChange:s=>M(s.target.value),placeholder:(a==null?void 0:a.username)??"",autoFocus:!0})]})]})})]})}export{Re as AdminPage};
|