live-sfu-demo/internal/server/static/assets/users-DA_5fDuj.js

1 line
7.0 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import{B as e,C as t,H as n,K as r,M as i,P as a,R as o,W as s,Y as c,_ as l,d as u,h as d,k as f,l as p,m,n as h,r as g,t as _,v,w as y,x as b}from"./ui-CzB-gjVP.js";import{n as x,t as S}from"./user-round-BkRPX9Ri.js";import{t as C}from"./shield-check-PAk2q1NC.js";import{n as w}from"./index-BTRwyDO1.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=e=>o(v,r(e,{iconNode:T,name:`shield`})),D=f(`<div class="flex flex-wrap items-start justify-between gap-4"><div><p class="mono-label text-muted-foreground">users / rbac</p><h1 class="display mt-2 text-4xl sm:text-5xl">用户与角色</h1><p class="mt-3 max-w-xl text-sm text-muted-foreground">基于 Casbin RBAC + 状态管理。对标 SyncTV Root/Admin 分层:仅 Root 可授予 Root;Admin 仅可管理 Viewer/Publisher;封禁用户无法登录与刷新。</p></div><div class="flex items-center gap-2">`),O=f(`<span class="flex items-center gap-2">当前账号已被封禁,部分操作将受限。请联系超管解封。`),k=f(`<div class="flex items-center gap-2 px-5 py-8 text-sm text-muted-foreground">暂无用户数据`),A=f(`<div class="border border-line bg-card/50"><div class="hidden grid-cols-[minmax(0,1fr)_7rem_7rem_16rem] gap-4 border-b border-line/80 px-5 py-3 sm:grid"><span class="micro-label text-muted-foreground">username</span><span class="micro-label text-muted-foreground">role</span><span class="micro-label text-muted-foreground">status</span><span class="micro-label text-right text-muted-foreground">action`),j=f(`<div class="mx-auto max-w-[1400px] space-y-8 px-4 py-8 sm:px-6 sm:py-10">`),M=f(`<span class="flex items-center gap-2">无权限:需要 user:list(管理员及以上)`),N=f(`<span class="inline-flex size-1.5 rounded-full bg-amber-500">`),P=f(`<div><div class="flex min-w-0 items-center gap-3"><span></span><div class=min-w-0><p class="flex items-center gap-2 truncate font-mono text-sm font-medium"></p><p class="micro-label mt-1 text-muted-foreground"></p></div></div><div></div><div class="flex items-center justify-end gap-2">`),F=f(`<span class="flex items-center gap-1 text-xs text-muted-foreground/60">无权操作`),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[r,f]=s([]),[v,T]=s(``),[R,z]=s(``),B=async()=>{try{let e=await l.listUsers();f(e.users||[]),T(``)}catch(e){T(String(e?.message||e))}};e(()=>{m.can(`user:list`)&&B()}),c(()=>{m.isAuthed()&&B()});let V=async(e,t)=>{z(e);try{await l.updateUserRole(e,t),f(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 l.unbanUser(e.username):await l.banUser(e.username),await B()}catch(e){T(String(e?.message||e))}finally{z(``)}}},U=()=>m.role(),W=e=>{let t=U();return t===`root`?e.role!==`root`:t===`admin`?e.role===`viewer`||e.role===`publisher`:!1};return(()=>{var e=j();return t(e,o(p,{get children(){var e=D(),n=e.firstChild.nextSibling;return t(n,o(h,{variant:`outline`,class:`gap-1`,get children(){return[o(E,{class:`size-3`}),y(()=>d.user()?.username||`guest`),` · `,y(()=>U())]}}),null),t(n,o(g,{variant:`outline`,class:`h-8`,onClick:B,get disabled(){return!!R()},children:`刷新`}),null),e}}),null),t(e,o(a,{get when(){return m.isBanned()},get children(){return o(_,{tone:`error`,get children(){var e=O(),n=e.firstChild;return t(e,o(w,{class:`size-4`}),n),e}})}}),null),t(e,o(a,{get when(){return m.can(`user:list`)},get fallback(){return o(_,{tone:`warning`,get children(){var e=M(),n=e.firstChild;return t(e,o(x,{class:`size-4`}),n),e}})},get children(){return o(p,{delay:1,get children(){var e=A(),s=e.firstChild;return t(e,o(a,{get when(){return v()},get children(){return o(_,{tone:`error`,class:`border-x-0 border-t-0`,get children(){return v()}})}}),s),t(e,o(i,{get each(){return r()},children:(e,i)=>{let s=I[e.role]||I.guest,c=e.status===`banned`,l=L(U()),d=m.can(`user:manage`)&&m.canManage(e.role)&&l.length>0;return(()=>{var f=P(),p=f.firstChild,_=p.firstChild,v=_.nextSibling.firstChild,x=v.nextSibling,C=p.nextSibling,w=C.nextSibling;return t(_,()=>(e.username[0]??`?`).toUpperCase()),t(v,()=>e.username,null),t(v,o(a,{get when(){return e.role===`root`},get children(){return N()}}),null),t(x,()=>s.label),t(f,o(h,{get class(){return s.badge},get children(){return e.role}}),C),t(C,o(a,{when:c,get fallback(){return o(h,{variant:`outline`,class:`border-success/30 text-success`,children:`active`})},get children(){return o(h,{variant:`outline`,class:`border-destructive/40 bg-destructive/10 text-destructive`,children:`banned`})}})),t(w,o(a,{when:d,get fallback(){return(()=>{var e=F(),n=e.firstChild;return t(e,o(S,{class:`size-3.5`}),n),e})()},get children(){return o(u,{class:`w-28`,get value(){return e.role},get"aria-label"(){return`调整 ${e.username} 的角色`},onChange:t=>V(e.username,t),get options(){return l.map(e=>({value:e,label:e}))},get disabled(){return!!R()||c}})}}),null),t(w,o(a,{get when(){return y(()=>!!m.can(`user:manage`))()&&W(e)},get children(){return o(g,{variant:c?`outline`:`ghost`,class:`h-7 px-2 text-xs ${c?`border-success/30 text-success hover:bg-success/10`:`text-destructive hover:bg-destructive/10`}`,get disabled(){return R()===e.username},onClick:()=>H(e),children:c?`解封`:`封禁`})}}),null),n(e=>{var t=`grid grid-cols-1 items-center gap-3 px-5 py-4 sm:grid-cols-[minmax(0,1fr)_7rem_7rem_16rem] sm:gap-4 ${i()<r().length-1?`border-b border-line/70`:``} ${c?`bg-destructive/5`:``}`,n=`flex size-8 shrink-0 items-center justify-center border font-mono text-xs font-bold ${s.avatar}`;return t!==e.e&&b(f,e.e=t),n!==e.t&&b(_,e.t=n),e},{e:void 0,t:void 0}),f})()}}),null),t(e,o(a,{get when(){return y(()=>r().length===0)()&&!v()},get children(){var e=k(),n=e.firstChild;return t(e,o(C,{class:`size-4 text-success`}),n),e}}),null),e}})}}),null),t(e,o(_,{tone:`info`,class:`text-xs leading-relaxed`,children:`提示:Root 拥有全部权限且可封禁/解封任意非 Root 用户;Admin 仅可调整 viewer/publisher 并封禁同级以下用户;被封禁者即使持有有效 JWT 也会在鉴权校验时被拒绝(后端 VerifyToken 拦截)。`}),null),e})()};export{R as Users};