import{B as e,C as t,E as n,H as r,I as i,J as a,K as o,P as s,T as c,W as l,Z as u,b as d,c as f,g as p,j as m,m as h,n as g,p as _,r as v,t as y,u as b}from"./ui-CBKBDzcl.js";import{n as x,t as S}from"./user-round-3UDfHwDp.js";import{t as C}from"./shield-check-CMgIbfEy.js";import{r as w}from"./index-Cfr72k3j.js";var T=[[`path`,{d:`M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z`,key:`oel41y`}]],E=t=>e(d,a(t,{iconNode:T,name:`shield`})),D=m(`
users / rbac
用户与角色
基于 Casbin RBAC + 状态管理。对标 SyncTV Root/Admin 分层:仅 Root 可授予 Root;Admin 仅可管理 Viewer/Publisher;封禁用户无法登录与刷新。
`),O=m(`
当前账号已被封禁,部分操作将受限。请联系超管解封。`),k=m(`暂无用户数据`),A=m(`
usernamerolestatusaction`),j=m(``),M=m(`
无权限:需要 user:list(管理员及以上)`),N=m(``),P=m(``),F=m(`
无权操作`),I={root:{label:`超管`,badge:`border-amber-500/40 bg-amber-500/10 text-amber-600`,avatar:`border-amber-500/40 bg-amber-500/10 text-amber-600`},admin:{label:`管理员`,badge:`border-acid-magenta/30 bg-acid-magenta/10 text-acid-magenta`,avatar:`border-acid-magenta/40 bg-acid-magenta/10 text-acid-magenta`},publisher:{label:`发布者`,badge:`border-warning/30 bg-warning/10 text-warning`,avatar:`border-warning/40 bg-warning/10 text-warning`},viewer:{label:`观看者`,badge:`border-acid-cyan/30 bg-acid-cyan/10 text-acid-cyan`,avatar:`border-acid-cyan/40 bg-acid-cyan/10 text-acid-cyan`},guest:{label:`访客`,badge:`border-line bg-transparent text-muted-foreground`,avatar:`border-line bg-muted text-muted-foreground`}};function L(e){return e===`root`?[`viewer`,`publisher`,`admin`,`root`]:e===`admin`?[`viewer`,`publisher`]:[]}var R=()=>{let[a,d]=o([]),[m,T]=o(``),[R,z]=o(``),B=async()=>{try{let e=await p.listUsers();d(e.users||[]),T(``)}catch(e){T(String(e?.message||e))}};r(()=>{_.can(`user:list`)&&B()}),u(()=>{_.isAuthed()&&B()});let V=async(e,t)=>{z(e);try{await p.updateUserRole(e,t),d(n=>n.map(n=>n.username===e?{...n,role:t}:n)),T(``)}catch(e){T(String(e?.message||e))}finally{z(``)}},H=async e=>{let t=e.status===`banned`;if(confirm(t?`解封 ${e.username} ?`:`封禁 ${e.username} ? 封禁后该用户将无法登录`)){z(e.username);try{t?await p.unbanUser(e.username):await p.banUser(e.username),await B()}catch(e){T(String(e?.message||e))}finally{z(``)}}},U=()=>_.role(),W=e=>{let t=U();return t===`root`?e.role!==`root`:t===`admin`?e.role===`viewer`||e.role===`publisher`:!1};return(()=>{var r=j();return c(r,e(f,{get children(){var t=D(),r=t.firstChild.nextSibling;return c(r,e(g,{variant:`outline`,class:`gap-1`,get children(){return[e(E,{class:`size-3`}),n(()=>h.user()?.username||`guest`),` · `,n(()=>U())]}}),null),c(r,e(v,{variant:`outline`,class:`h-8`,onClick:B,get disabled(){return!!R()},children:`刷新`}),null),t}}),null),c(r,e(i,{get when(){return _.isBanned()},get children(){return e(y,{tone:`error`,get children(){var t=O(),n=t.firstChild;return c(t,e(w,{class:`size-4`}),n),t}})}}),null),c(r,e(i,{get when(){return _.can(`user:list`)},get fallback(){return e(y,{tone:`warning`,get children(){var t=M(),n=t.firstChild;return c(t,e(x,{class:`size-4`}),n),t}})},get children(){return e(f,{delay:1,get children(){var r=A(),o=r.firstChild;return c(r,e(i,{get when(){return m()},get children(){return e(y,{tone:`error`,class:`border-x-0 border-t-0`,get children(){return m()}})}}),o),c(r,e(s,{get each(){return a()},children:(r,o)=>{let s=I[r.role]||I.guest,u=r.status===`banned`,d=L(U()),f=_.can(`user:manage`)&&_.canManage(r.role)&&d.length>0;return(()=>{var p=P(),m=p.firstChild,h=m.firstChild,y=h.nextSibling.firstChild,x=y.nextSibling,C=m.nextSibling,w=C.nextSibling;return c(h,()=>(r.username[0]??`?`).toUpperCase()),c(y,()=>r.username,null),c(y,e(i,{get when(){return r.role===`root`},get children(){return N()}}),null),c(x,()=>s.label),c(p,e(g,{get class(){return s.badge},get children(){return r.role}}),C),c(C,e(i,{when:u,get fallback(){return e(g,{variant:`outline`,class:`border-success/30 text-success`,children:`active`})},get children(){return e(g,{variant:`outline`,class:`border-destructive/40 bg-destructive/10 text-destructive`,children:`banned`})}})),c(w,e(i,{when:f,get fallback(){return(()=>{var t=F(),n=t.firstChild;return c(t,e(S,{class:`size-3.5`}),n),t})()},get children(){return e(b,{class:`w-28`,get value(){return r.role},get"aria-label"(){return`调整 ${r.username} 的角色`},onChange:e=>V(r.username,e),get options(){return d.map(e=>({value:e,label:e}))},get disabled(){return!!R()||u}})}}),null),c(w,e(i,{get when(){return n(()=>!!_.can(`user:manage`))()&&W(r)},get children(){return e(v,{variant:u?`outline`:`ghost`,class:`h-7 px-2 text-xs ${u?`border-success/30 text-success hover:bg-success/10`:`text-destructive hover:bg-destructive/10`}`,get disabled(){return R()===r.username},onClick:()=>H(r),children:u?`解封`:`封禁`})}}),null),l(e=>{var n=`grid grid-cols-1 items-center gap-3 px-5 py-4 sm:grid-cols-[minmax(0,1fr)_7rem_7rem_16rem] sm:gap-4 ${o()a().length===0)()&&!m()},get children(){var t=k(),n=t.firstChild;return c(t,e(C,{class:`size-4 text-success`}),n),t}}),null),r}})}}),null),c(r,e(y,{tone:`info`,class:`text-xs leading-relaxed`,children:`提示:Root 拥有全部权限且可封禁/解封任意非 Root 用户;Admin 仅可调整 viewer/publisher 并封禁同级以下用户;被封禁者即使持有有效 JWT 也会在鉴权校验时被拒绝(后端 VerifyToken 拦截)。`}),null),r})()};export{R as Users};