Files
wx-win-agent/control-plane/web/dist/assets/AdminViews-WbIASOAn.js
T
rogee a977902b25
Build web service image / build (push) Successful in 1m29s
fix(web): isolate UI reads and improve mobile messages
2026-09-28 06:36:25 +08:00

2 lines
9.2 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{r,X as K,_ as V,Y as T,n as y,E as e,V as R,I as u,F as H,Z as o,J as Z,$ as G,a0 as J,L as b,a1 as F,Q as P,U as I,A as z,a2 as Q,T as W,P as C,S as X,G as Y}from"./index-CSGym-Bq.js";import{A as $,P as O,S as ee,M as se,a as ae}from"./Table-B79wm3oj.js";import"./index-Di2wY8BS.js";var te={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M608 112c-167.9 0-304 136.1-304 304 0 70.3 23.9 135 63.9 186.5L255.8 713.6l-62.3-62.3a8.19 8.19 0 00-11.4 0l-39.8 39.8a8.19 8.19 0 000 11.4l62.3 62.3-44.9 44.9-62.3-62.3a8.19 8.19 0 00-11.4 0l-39.8 39.8a8.19 8.19 0 000 11.4l110.3 111.2c3.1 3.1 8.2 3.1 11.3 0l253.6-253.6A304.1 304.1 0 00608 720c167.9 0 304-136.1 304-304S775.9 112 608 112m161.2 465.2C726.2 620.3 668.9 644 608 644s-118.2-23.7-161.2-66.8C403.7 534.2 380 476.9 380 416s23.7-118.2 66.8-161.2c43-43.1 100.3-66.8 161.2-66.8s118.2 23.7 161.2 66.8c43.1 43 66.8 100.3 66.8 161.2s-23.7 118.2-66.8 161.2"}}]},name:"key",theme:"outlined"},ne=function(m,i){return r.createElement(K,V({},m,{ref:i,icon:te}))},re=r.forwardRef(ne);const{Text:h}=W;function ie({token:l,currentUser:m,nodes:i,onChanged:j}){const{message:d}=T.useApp(),[f,k]=r.useState([]),[S,w]=r.useState(!1),[N,x]=r.useState(!1),[a,n]=r.useState(null),[p,A]=r.useState(null),[g]=o.useForm(),[v]=o.useForm(),_=r.useCallback(async()=>{w(!0);try{const s=await y("/v1/users",{token:l});k(s.users||[])}catch(s){d.error(s.message)}finally{w(!1)}},[d,l]);r.useEffect(()=>{_()},[_]);const D=r.useMemo(()=>new Map(i.map(s=>[s.node_id,s])),[i]),E=()=>{n(null),g.resetFields(),g.setFieldsValue({role:"member",active:!0,node_ids:[]}),x(!0)},M=s=>{n(s),g.resetFields(),g.setFieldsValue({username:s.username,display_name:s.display_name,role:s.role,active:s.active,node_ids:s.node_ids||[]}),x(!0)},U=async s=>{const t={username:s.username,display_name:s.display_name,role:s.role,active:s.active,node_ids:s.role==="member"?s.node_ids||[]:[]};try{a?await y(`/v1/users/${encodeURIComponent(a.id)}`,{token:l,method:"PATCH",body:{display_name:t.display_name,role:t.role,active:t.active,node_ids:t.node_ids}}):await y("/v1/users",{token:l,method:"POST",body:{...t,password:s.password}}),d.success(a?"用户权限已更新":"用户已创建"),x(!1),await _(),j==null||j()}catch(c){d.error(c.message)}},q=async(s,t)=>{try{await y(`/v1/users/${encodeURIComponent(s.id)}`,{token:l,method:"PATCH",body:{display_name:s.display_name,role:s.role,active:t,node_ids:s.node_ids||[]}}),d.success(t?"用户已启用":"用户已停用,现有会话已撤销"),await _()}catch(c){d.error(c.message)}},B=async s=>{try{await y(`/v1/users/${encodeURIComponent(p.id)}/password`,{token:l,method:"POST",body:{password:s.password}}),d.success("密码已重置,该用户的现有会话已撤销"),A(null),v.resetFields()}catch(t){d.error(t.message)}},L=[{title:"用户",dataIndex:"username",key:"user",render:(s,t)=>{var c;return e.jsxs(I,{children:[e.jsx(z,{size:"small",icon:e.jsx(Y,{}),children:(c=t.display_name)==null?void 0:c.slice(0,1)}),e.jsxs("span",{children:[e.jsx(h,{strong:!0,children:t.display_name}),e.jsx("br",{}),e.jsx(h,{type:"secondary",children:t.username})]})]})}},{title:"角色",dataIndex:"role",width:130,render:s=>e.jsx(C,{color:s==="admin"?"blue":"default",children:s==="admin"?"管理员":"成员"})},{title:"可访问 Desktop Agent / Node",dataIndex:"node_ids",render:(s,t)=>t.role==="admin"?e.jsx(h,{type:"secondary",children:"全部 Node"}):s!=null&&s.length?e.jsx(I,{wrap:!0,children:s.map(c=>e.jsx(C,{color:D.has(c)?"geekblue":"default",children:c},c))}):e.jsx(h,{type:"secondary",children:"尚未分配"})},{title:"状态",dataIndex:"active",width:100,render:s=>e.jsx(C,{color:s?"success":"default",children:s?"启用":"停用"})},{title:"创建时间",dataIndex:"created_at",width:175,render:R},{title:"操作",key:"actions",width:230,valueType:"option",render:(s,t)=>e.jsxs(I,{size:4,children:[e.jsx(u,{type:"link",size:"small",onClick:()=>M(t),children:"编辑与分配"}),e.jsx(u,{type:"link",size:"small",icon:e.jsx(re,{}),onClick:()=>{A(t),v.resetFields()},children:"重置密码"}),e.jsx(ae,{title:t.active?"停用此账号?":"重新启用此账号?",description:t.active?"该用户的现有会话将被撤销。":void 0,onConfirm:()=>void q(t,!t.active),disabled:t.id===m.id,children:e.jsx(u,{type:"link",size:"small",disabled:t.id===m.id,children:t.active?"停用":"启用"})})]})}];return e.jsxs("div",{className:"admin-page-stack",children:[e.jsx($,{type:"info",showIcon:!0,message:"用户与 Node 权限使用真实控制面数据库",description:"管理员拥有全部 Node 访问权;成员只可访问明确分配的 Desktop Agent / Node。环境变量中的旧 Web 账号仅在用户表首次初始化时导入为管理员。"}),e.jsx(O,{rowKey:"id",headerTitle:`控制面用户 · ${f.length}`,columns:L,dataSource:f,loading:S,search:!1,options:!1,scroll:{x:"max-content",y:"max(100px, calc(100dvh - 500px))"},pagination:{pageSize:10,showSizeChanger:!0},toolBarRender:()=>[e.jsx(u,{icon:e.jsx(Z,{}),onClick:()=>void _(),children:"刷新"},"reload"),e.jsx(u,{type:"primary",icon:e.jsx(G,{}),onClick:E,children:"创建用户"},"create")]}),e.jsx(J,{title:a?"编辑用户与 Node 分配":"创建控制面用户",width:520,open:N,onClose:()=>x(!1),destroyOnClose:!0,children:e.jsxs(o,{form:g,layout:"vertical",onFinish:U,requiredMark:"optional",children:[e.jsx(o.Item,{name:"username",label:"用户名",rules:[{required:!0,min:3,max:64,pattern:/^[A-Za-z0-9._@-]+$/,message:"使用 3–64 位字母、数字或 . _ @ -"}],children:e.jsx(b,{disabled:!!a,autoComplete:"username"})}),e.jsx(o.Item,{name:"display_name",label:"显示名称",rules:[{required:!0,max:120}],children:e.jsx(b,{maxLength:120})}),!a&&e.jsx(o.Item,{name:"password",label:"初始密码",rules:[{required:!0,min:12,message:"密码至少 12 个字符"}],children:e.jsx(b.Password,{autoComplete:"new-password"})}),e.jsx(o.Item,{name:"role",label:"角色",rules:[{required:!0}],children:e.jsx(F,{options:[{value:"member",label:"成员(按分配 Node 隔离)"},{value:"admin",label:"管理员(可管理用户并访问全部 Node)"}],disabled:(a==null?void 0:a.id)===m.id})}),e.jsx(o.Item,{noStyle:!0,shouldUpdate:(s,t)=>s.role!==t.role,children:({getFieldValue:s})=>s("role")==="member"?e.jsx(o.Item,{name:"node_ids",label:"分配 Desktop Agent / Node",children:e.jsx(F,{mode:"multiple",allowClear:!0,showSearch:!0,optionFilterProp:"label",placeholder:"选择此成员可访问的 Node",options:i.map(t=>({value:t.node_id,label:`${t.node_id} · ${P(t.status)}`}))})}):e.jsx($,{type:"info",showIcon:!0,message:"管理员可访问全部 Node;管理员账号不使用成员分配列表。"})}),a&&e.jsx(o.Item,{name:"active",label:"账号状态",valuePropName:"checked",children:e.jsx(ee,{checkedChildren:"启用",unCheckedChildren:"停用",disabled:a.id===m.id})}),e.jsxs("div",{className:"drawer-footer",children:[e.jsx(u,{onClick:()=>x(!1),children:"取消"}),e.jsx(u,{type:"primary",htmlType:"submit",children:a?"保存变更":"创建用户"})]})]})}),e.jsx(se,{title:`重置密码 · ${(p==null?void 0:p.username)||""}`,open:!!p,onCancel:()=>A(null),onOk:()=>v.submit(),okText:"重置并撤销会话",destroyOnClose:!0,children:e.jsx(o,{form:v,layout:"vertical",onFinish:B,children:e.jsx(o.Item,{name:"password",label:"新密码",rules:[{required:!0,min:12,message:"密码至少 12 个字符"}],children:e.jsx(b.Password,{autoComplete:"new-password"})})})})]})}function ce({token:l,nodes:m,isAdmin:i,onGoUsers:j}){const{message:d}=T.useApp(),[f,k]=r.useState([]),[S,w]=r.useState(!1);r.useEffect(()=>{if(!i)return;let a=!0;return w(!0),y("/v1/users",{token:l}).then(n=>{a&&k(n.users||[])}).catch(n=>d.error(n.message)).finally(()=>{a&&w(!1)}),()=>{a=!1}},[i,d,l]);const N=r.useMemo(()=>{const a=new Map;for(const n of f)if(!(n.role!=="member"||!n.active))for(const p of n.node_ids||[])a.set(p,[...a.get(p)||[],n.display_name||n.username]);return a},[f]),x=[{title:"Desktop Agent / Node",dataIndex:"node_id",key:"node_id",render:a=>e.jsxs(I,{children:[e.jsx(z,{size:"small",icon:e.jsx(Q,{})})," ",e.jsx(h,{strong:!0,children:a})]})},{title:"连接状态",dataIndex:"status",width:130,render:a=>e.jsx(C,{color:X(a),children:P(a)})},{title:"活动账号",dataIndex:"active_account_id",render:a=>a||e.jsx(h,{type:"secondary",children:"未确认"})},{title:"最近心跳",dataIndex:"last_heartbeat_at",width:180,render:R},{title:"Agent 版本",dataIndex:"agent_version",width:150,render:a=>a||"—"},{title:"账号",dataIndex:"accounts",width:90,render:a=>(a==null?void 0:a.length)||0},...i?[{title:"已分配成员",dataIndex:"node_id",render:a=>{var n;return S?"读取中…":((n=N.get(a))==null?void 0:n.join("、"))||e.jsx(h,{type:"secondary",children:"未分配"})}}]:[]];return e.jsxs("div",{className:"admin-page-stack",children:[e.jsx($,{type:"info",showIcon:!0,message:"这里管理的是已连接的 Desktop Agent / Node",description:"成员分配按 Node 生效,并同时约束该 Node 下已授权微信账号的消息、通讯录、事件与任务接口。AI Flow 不是本页面中的 Desktop Agent。"}),e.jsx(O,{rowKey:"node_id",headerTitle:`已授权节点 · ${m.length}`,columns:x,dataSource:m,search:!1,options:!1,scroll:{x:"max-content",y:"max(100px, calc(100dvh - 500px))"},pagination:{pageSize:10},toolBarRender:i?()=>[e.jsx(u,{icon:e.jsx(H,{}),onClick:j,children:"管理用户分配"},"users")]:!1})]})}export{ce as NodesView,ie as UsersView};