Admin-CHGgcpnY.js 27 KB

1
  1. import{a as e,n as t,r as n}from"./react-dom-stZKkA6x.js";import{a as r,c as i,d as a,r as o,u as s}from"./theme-DNlqAiGO.js";import{G as c,M as l,i as u,kt as d,n as f,t as p}from"./jsx-runtime-dm82oUI8.js";import{a as m,i as h,o as g}from"./grid-DcIFgt5N.js";import{n as _,t as v}from"./table-CHt5qwx3.js";import{n as y,r as b,t as x}from"./StatusPill-Bcw_ne6L.js";import{t as S}from"./input-number-5vwSxUlw.js";import{t as C}from"./descriptions-vs1os_w7.js";import{t as w}from"./form-BRrMNJiX.js";import{t as T}from"./input-0_Xo22Fl.js";import{t as E}from"./list-B3SBzx24.js";import{t as D}from"./modal-BNBPl4Qp.js";import{t as O}from"./switch-CsMGEdLR.js";import{t as k}from"./EllipsisOutlined-Bk3Ymyne.js";import{t as A}from"./ReloadOutlined-Cq8HKCaL.js";import{_ as j,a as M,h as ee,l as N,m as te,n as ne,p as re,t as P,y as F}from"./index-CBPGvhVC.js";import{t as I}from"./EmptyState-rI31ioMm.js";var L=n((e=>{Object.defineProperty(e,"__esModule",{value:!0}),e.default={icon:{tag:`svg`,attrs:{viewBox:`64 64 896 896`,focusable:`false`},children:[{tag:`path`,attrs:{d:`M759 335c0-137-111-248-248-248S263 198 263 335c0 82.8 40.6 156.2 103 201.2-.4.2-.7.3-.9.4-44.7 18.9-84.8 46-119.3 80.6a373.42 373.42 0 00-80.4 119.5A373.6 373.6 0 00136 874.8a8 8 0 008 8.2h59.9c4.3 0 7.9-3.5 8-7.8 2-77.2 32.9-149.5 87.6-204.3C356 614.2 431 583 511 583c137 0 248-111 248-248zM511 507c-95 0-172-77-172-172s77-172 172-172 172 77 172 172-77 172-172 172zm105 221h264c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H703.5l47.2-60.1a8.1 8.1 0 001.7-4.9c0-4.4-3.6-8-8-8h-72.6c-4.9 0-9.5 2.3-12.6 6.1l-68.5 87.1c-4.4 5.6-6.8 12.6-6.8 19.8.1 17.7 14.4 32 32.1 32zm240 64H592c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h176.5l-47.2 60.1a8.1 8.1 0 00-1.7 4.9c0 4.4 3.6 8 8 8h72.6c4.9 0 9.5-2.3 12.6-6.1l68.5-87.1c4.4-5.6 6.8-12.6 6.8-19.8-.1-17.7-14.4-32-32.1-32z`}}]},name:`user-switch`,theme:`outlined`}})),R=e(t()),z=e(L());function B(){return B=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},B.apply(this,arguments)}var ie=R.forwardRef((e,t)=>R.createElement(s,B({},e,{ref:t,icon:z.default}))),ae={pending_email:{label:`待验证邮箱`,color:`gold`},pending_review:{label:`待管理员审核`,color:`blue`},active:{label:`正常`,color:`green`},disabled:{label:`已禁用`,color:`red`}},oe=[[`domains`,`域名`],[`dnsCredentials`,`DNS 凭据`],[`apiTokens`,`API 密钥`],[`inboundMailboxes`,`收信邮箱`],[`inboundMessages`,`入站邮件`],[`sendEvents`,`发送记录`],[`smtpCredential`,`SMTP 凭据`]];function se(e){return ae[e]||{label:String(e||`未知`),color:`default`}}function ce(e,t){return`MERGE ${e?.username||e?.id||``} INTO ${t?.username||t?.id||``}`}function le(e){let t=e?.selectedCounts||{};return oe.map(([e,n])=>({key:e,label:n,count:Number(t[e]||0)}))}function ue(e){let t=fe({host:e?.host,port:e?.port===``||e?.port==null?void 0:Number(e.port),secure:e?.secure,username:e?.username,password:e?.password,fromEmail:e?.fromEmail});return typeof t.password==`string`&&t.password.trim()===``&&delete t.password,t}function de(e){let t=new URLSearchParams;for(let[n,r]of Object.entries(e||{}))r===``||r==null||t.set(n,String(r));return t.toString()}function fe(e){return Object.fromEntries(Object.entries(e).filter(([,e])=>e!==``&&e!=null))}var V=p(),pe=[`pending_email`,`pending_review`,`active`,`disabled`],me=[`user`,`admin`],H=[`users`,`resources`,`migration`,`system-email`,`audit-logs`],he=[[`transferDomains`,`迁移域名`,`Transfer domains`],[`transferDnsCredentials`,`迁移 DNS 凭据`,`Transfer DNS credentials`],[`transferApiTokens`,`迁移 API 密钥`,`Transfer API keys`],[`transferSendEvents`,`迁移发送记录`,`Transfer sending activity`],[`transferSmtpCredential`,`迁移 SMTP 凭据`,`Transfer SMTP credential`],[`disableSource`,`禁用源用户`,`Disable source user`]];function ge(){let{message:e,modal:t}=a.useApp(),{locale:n,t:i}=r(),{user:s}=ne(),c=re(),l=te(),[p,h]=ee(),g=p.toString(),_=H.includes(l.section)?l.section:`users`,[v,x]=(0,R.useState)([]),[S,C]=(0,R.useState)(null),[w,T]=(0,R.useState)(null),[E,D]=(0,R.useState)([]),[O,k]=(0,R.useState)(!1),[j,M]=(0,R.useState)(()=>new Set),N=(0,R.useRef)(new Set),P=(0,R.useRef)(0);if((0,R.useEffect)(()=>{(!l.section||!H.includes(l.section))&&c(`/admin/users`,{replace:!0})},[c,l.section]),(0,R.useEffect)(()=>(s?.role===`admin`&&F(_,_===`audit-logs`,g),()=>{_===`audit-logs`&&(P.current+=1)}),[_,g,s?.role]),s?.role!==`admin`)return(0,V.jsxs)(u,{direction:`vertical`,size:20,className:`full-width admin-page`,children:[(0,V.jsx)(b,{title:i(`nav.adminCenter`)}),(0,V.jsx)(y,{children:(0,V.jsx)(f.Text,{type:`secondary`,children:i(`settings.noPermission`)})})]});async function F(t,r=!1,i=g,a=!0){if(!r&&N.current.has(t)){a&&k(!1);return}let s=null;a&&k(!0);try{if(t===`users`||t===`migration`){let e=await o.adminUsers();x(e.users||[])}else if(t===`resources`){let[e,t]=await Promise.all([o.adminUsers(),o.adminResources()]);x(e.users||[]),C(t.inventory||null)}else if(t===`system-email`){let e=await o.adminSystemEmail();T(e.settings||null)}else if(t===`audit-logs`){s=++P.current;let[e,t]=await Promise.all([o.adminUsers(),o.adminAuditLogs(i)]);if(s!==P.current)return;x(e.users||[]),D(t.logs||[])}N.current.add(t)}catch(t){if(s!==null&&s!==P.current)return;e.error(t instanceof Error?t.message:Q(n,`管理员数据加载失败`,`Failed to load admin data`))}finally{a&&(s===null||s===P.current)&&k(!1)}}async function I(t,r,i,a=!0){M(e=>new Set(e).add(t));try{await r(),e.success(i),a&&await F(_,!0,g,!1)}catch(t){e.error(t instanceof Error?t.message:Q(n,`操作失败`,`Operation failed`))}finally{M(e=>{let n=new Set(e);return n.delete(t),n})}}function L(e,n){t.confirm({title:e,okText:i(`common.confirm`),cancelText:i(`common.cancel`),onOk:n})}async function z(e){let t=new URLSearchParams(e),n=t.toString();if(n===g){await F(`audit-logs`,!0,n);return}h(t)}let B=[{key:`users`,label:i(`admin.users`),children:(0,V.jsx)(_e,{users:v,loading:O,actionKeys:j,onApprove:e=>L(Q(n,`确认审批用户 ${e.username}?`,`Approve user ${e.username}?`),()=>I(`approve:${e.id}`,()=>o.approveAdminUser(e.id),Q(n,`用户已审批`,`User approved`))),onResendVerification:e=>I(`resend:${e.id}`,()=>o.resendAdminVerification(e.id),Q(n,`验证邮件请求已提交`,`Verification email requested`)),onPasswordReset:e=>L(Q(n,`确认给 ${e.email} 发送密码重置邮件?`,`Send a password reset email to ${e.email}?`),()=>I(`reset:${e.id}`,()=>o.sendAdminPasswordReset(e.id),Q(n,`密码重置邮件请求已提交`,`Password reset email requested`))),onTemporaryPassword:(e,t)=>L(Q(n,`确认为用户 ${e.username} 设置临时密码?`,`Set a temporary password for ${e.username}?`),()=>I(`temporary-password:${e.id}`,()=>o.setAdminTemporaryPassword(e.id,t),Q(n,`临时密码已设置`,`Temporary password set`))),onUpdateUser:(e,t)=>L(Q(n,`确认更新用户 ${e.username}?`,`Update user ${e.username}?`),()=>I(`update:${e.id}`,()=>o.updateAdminUser(e.id,t),Q(n,`用户已更新`,`User updated`)))})},{key:`resources`,label:i(`admin.resources`),children:(0,V.jsx)(ve,{users:v,inventory:S,loading:O,actionKeys:j,onTransferDomain:(e,t)=>I(`transfer-domain:${e}`,()=>o.transferAdminDomain(e,t),Q(n,`域名已迁移`,`Domain transferred`)),onTransferDnsCredential:(e,t)=>I(`transfer-dns:${e}`,()=>o.transferAdminDnsCredential(e,t),Q(n,`DNS 凭据已迁移`,`DNS credential transferred`)),onTransferApiTokens:e=>I(`transfer-token`,()=>o.transferAdminApiTokens(e),Q(n,`API 密钥已迁移`,`API keys transferred`))})},{key:`migration`,label:i(`admin.migration`),children:(0,V.jsx)(be,{users:v,loading:O,actionKeys:j,onPreview:e=>o.previewUserMerge(e),onExecute:e=>I(`merge`,()=>o.executeUserMerge(e),Q(n,`用户资源已合并`,`User resources merged`))})},{key:`system-email`,label:i(`admin.systemEmail`),children:(0,V.jsx)(xe,{settings:w,loading:O,actionKeys:j,onSave:e=>I(`system-email:save`,()=>o.saveAdminSystemEmail(e),Q(n,`系统邮件配置已保存`,`System email settings saved`)),onTest:e=>I(`system-email:test`,()=>o.testAdminSystemEmail(e),Q(n,`测试邮件请求已提交`,`Test email requested`),!1)})},{key:`audit-logs`,label:i(`admin.auditLogs`),children:(0,V.jsx)(Se,{logs:E,users:v,query:g,loading:O,onSearch:z})}];return(0,V.jsxs)(u,{direction:`vertical`,size:20,className:`full-width admin-page`,children:[(0,V.jsx)(b,{title:i(`nav.adminCenter`),extra:(0,V.jsx)(d,{icon:(0,V.jsx)(A,{}),loading:O,onClick:()=>void F(_,!0),children:i(`common.refresh`)})}),(0,V.jsx)(y,{className:`admin-center-card`,children:(0,V.jsx)(m,{className:`admin-center-tabs`,activeKey:_,items:B,destroyOnHidden:!0,onChange:e=>c(`/admin/${e}`)})})]})}function _e({users:e,loading:t,actionKeys:n,onApprove:i,onResendVerification:a,onPasswordReset:o,onTemporaryPassword:s,onUpdateUser:c}){let{locale:l}=r(),u=P(`(min-width: 768px)`),[d,p]=(0,R.useState)(null),[m]=w.useForm(),g=[{title:`ID`,dataIndex:`id`,width:72},{title:Q(l,`用户`,`User`),width:260,className:`admin-user-column`,render:(e,t)=>(0,V.jsx)(U,{user:t})},{title:Q(l,`状态`,`Status`),dataIndex:`status`,width:200,render:(e,t)=>(0,V.jsx)(W,{user:t,actionKeys:n,onUpdateUser:c})},{title:Q(l,`角色`,`Role`),dataIndex:`role`,width:152,render:(e,t)=>(0,V.jsx)(G,{user:t,actionKeys:n,onUpdateUser:c})},{title:Q(l,`资源`,`Resources`),width:340,render:(e,t)=>(0,V.jsx)(q,{counts:t.resourceCounts})},{title:Q(l,`创建时间`,`Created at`),dataIndex:`createdAt`,width:190,render:J},{title:Q(l,`操作`,`Actions`),width:72,fixed:`right`,align:`center`,render:(e,t)=>(0,V.jsx)(K,{user:t,actionKeys:n,onApprove:i,onResendVerification:a,onPasswordReset:o,onTemporaryPassword:()=>p(t)})}];async function _(){if(!d)return;let e=await m.validateFields();s(d,e.password),p(null),m.resetFields()}return(0,V.jsxs)(V.Fragment,{children:[u?(0,V.jsx)(v,{className:`admin-users-table`,rowKey:`id`,columns:g,dataSource:e,loading:t,tableLayout:`fixed`,scroll:{x:1280}}):(0,V.jsx)(E,{className:`admin-users-list`,dataSource:e,loading:t,renderItem:e=>(0,V.jsx)(E.Item,{children:(0,V.jsxs)(h,{className:`admin-user-card`,size:`small`,children:[(0,V.jsxs)(`div`,{className:`admin-user-card__header`,children:[(0,V.jsx)(U,{user:e}),(0,V.jsx)(K,{user:e,actionKeys:n,onApprove:i,onResendVerification:a,onPasswordReset:o,onTemporaryPassword:()=>p(e)})]}),(0,V.jsxs)(f.Text,{type:`secondary`,className:`admin-user-card__meta`,children:[`ID #`,e.id,` · `,J(e.createdAt)]}),(0,V.jsxs)(`div`,{className:`admin-user-card__fields`,children:[(0,V.jsxs)(`div`,{className:`admin-user-card__field`,children:[(0,V.jsx)(f.Text,{type:`secondary`,children:Q(l,`状态`,`Status`)}),(0,V.jsx)(W,{user:e,actionKeys:n,onUpdateUser:c})]}),(0,V.jsxs)(`div`,{className:`admin-user-card__field`,children:[(0,V.jsx)(f.Text,{type:`secondary`,children:Q(l,`角色`,`Role`)}),(0,V.jsx)(G,{user:e,actionKeys:n,onUpdateUser:c})]})]}),(0,V.jsxs)(`div`,{className:`admin-user-card__resources`,children:[(0,V.jsx)(f.Text,{type:`secondary`,children:Q(l,`资源`,`Resources`)}),(0,V.jsx)(q,{counts:e.resourceCounts})]})]})})}),(0,V.jsx)(D,{title:d?`${Q(l,`设置临时密码`,`Set temporary password`)} · ${d.username}`:Q(l,`设置临时密码`,`Set temporary password`),open:!!d,confirmLoading:n.has(`temporary-password:${d?.id}`),onCancel:()=>p(null),onOk:_,children:(0,V.jsx)(w,{form:m,layout:`vertical`,children:(0,V.jsx)(w.Item,{name:`password`,label:Q(l,`临时密码`,`Temporary password`),rules:[{required:!0,min:8,message:Q(l,`密码至少需要 8 位。`,`Password must be at least 8 characters.`)}],children:(0,V.jsx)(T.Password,{autoComplete:`new-password`})})})})]})}function U({user:e}){return(0,V.jsxs)(`div`,{className:`admin-user-identity`,children:[(0,V.jsx)(f.Text,{strong:!0,className:`admin-user-identity__line`,ellipsis:{tooltip:e.username},children:e.username}),(0,V.jsx)(f.Text,{type:`secondary`,className:`admin-user-identity__line`,ellipsis:{tooltip:e.email},children:e.email})]})}function W({user:e,actionKeys:t,onUpdateUser:n}){let{locale:i}=r();return(0,V.jsx)(c,{"aria-label":Q(i,`用户状态 · ${e.username}`,`Status · ${e.username}`),value:e.status,loading:t.has(`update:${e.id}`),disabled:Y(t,e.id),options:pe.map(e=>({value:e,label:$(e,i)})),onChange:t=>n(e,{status:t}),className:`table-select admin-user-select`})}function G({user:e,actionKeys:t,onUpdateUser:n}){let{locale:i}=r();return(0,V.jsx)(c,{"aria-label":Q(i,`用户角色 · ${e.username}`,`Role · ${e.username}`),value:e.role,loading:t.has(`update:${e.id}`),disabled:Y(t,e.id),options:me.map(e=>({value:e,label:e})),onChange:t=>n(e,{role:t}),className:`table-select admin-user-select`})}function K({user:e,actionKeys:t,onApprove:n,onResendVerification:a,onPasswordReset:o,onTemporaryPassword:s}){let{locale:c}=r(),u=Y(t,e.id),f=Q(c,`用户操作 · ${e.username}`,`User actions · ${e.username}`),p=[{key:`approve`,icon:(0,V.jsx)(N,{}),label:Q(c,`审批`,`Approve`),disabled:u||e.status!==`pending_review`},{key:`resend`,icon:(0,V.jsx)(i,{}),label:Q(c,`重发验证`,`Resend verification`),disabled:u||e.status!==`pending_email`},{type:`divider`},{key:`reset`,icon:(0,V.jsx)(M,{}),label:Q(c,`重置邮件`,`Reset email`),danger:!0,disabled:u},{key:`temporary-password`,icon:(0,V.jsx)(ie,{}),label:Q(c,`临时密码`,`Temporary password`),danger:!0,disabled:u}];function m(t){t===`approve`?n(e):t===`resend`?a(e):t===`reset`?o(e):t===`temporary-password`&&s()}return(0,V.jsx)(l,{title:f,children:(0,V.jsx)(F,{trigger:[`click`],placement:`bottomRight`,menu:{items:p,onClick:({key:e})=>m(e)},disabled:u,children:(0,V.jsx)(d,{"aria-label":f,icon:(0,V.jsx)(k,{}),loading:u,disabled:u,className:`admin-user-actions-trigger`})})})}function ve({users:e,inventory:t,loading:n,actionKeys:i,onTransferDomain:a,onTransferDnsCredential:o,onTransferApiTokens:s}){let{locale:l}=r(),[p]=w.useForm(),[m]=w.useForm(),[h]=w.useForm(),_=w.useWatch(`domainId`,p),b=w.useWatch(`credentialId`,m),S=t?.users||[],C=e.filter(e=>e.status!==`disabled`).map(e=>({value:e.id,label:`${e.username} (#${e.id})`})),T=S.flatMap(e=>e.domains.map(t=>({...t,owner:e.user}))),E=S.flatMap(e=>e.dnsCredentials.map(t=>({...t,owner:e.user}))),O=S.flatMap(e=>e.apiTokens.map(t=>({...t,owner:e.user}))),k=[{title:Q(l,`用户`,`User`),width:260,render:(e,t)=>(0,V.jsxs)(`div`,{className:`admin-resource-owner`,children:[(0,V.jsx)(f.Text,{strong:!0,ellipsis:{tooltip:t.user.username},children:t.user.username}),(0,V.jsx)(Ce,{status:t.user.status})]})},{title:Q(l,`资源`,`Resources`),width:360,render:(e,t)=>(0,V.jsx)(q,{counts:t.user.resourceCounts})},{title:Q(l,`发送记录`,`Sending activity`),dataIndex:`sendEventCount`,width:120},{title:Q(l,`入站邮件`,`Inbound mail`),dataIndex:`inboundMessageCount`,width:120},{title:`SMTP`,width:120,render:(e,t)=>t.smtpCredential?(0,V.jsx)(x,{tone:`success`,children:Q(l,`已配置`,`Configured`)}):(0,V.jsx)(x,{tone:`neutral`,children:Q(l,`无`,`None`)})}];async function A(e){D.confirm({title:Q(l,`确认迁移该域名?`,`Transfer this domain?`),onOk:async()=>{await a(e.domainId,{targetUserId:e.targetUserId,dnsCredentialMode:e.dnsCredentialMode}),p.resetFields()}})}async function j(e){D.confirm({title:Q(l,`确认迁移该 DNS 凭据?`,`Transfer this DNS credential?`),onOk:async()=>{await o(e.credentialId,{targetUserId:e.targetUserId}),m.resetFields()}})}async function M(e){D.confirm({title:Q(l,`确认迁移 ${e.tokenIds.length} 个 API 密钥?`,`Transfer ${e.tokenIds.length} API keys?`),onOk:async()=>{await s({tokenIds:e.tokenIds,targetUserId:e.targetUserId}),h.resetFields()}})}return(0,V.jsxs)(u,{direction:`vertical`,size:16,className:`full-width`,children:[t?.warnings?.length?(0,V.jsx)(g,{type:`warning`,showIcon:!0,message:Q(l,`发现 ${t.warnings.length} 个 DNS 凭据归属不一致的域名`,`${t.warnings.length} domains have mismatched DNS credential ownership`)}):null,(0,V.jsxs)(`div`,{className:`form-grid three`,children:[(0,V.jsx)(y,{title:Q(l,`迁移域名`,`Transfer domain`),children:(0,V.jsxs)(w,{form:p,layout:`vertical`,onFinish:A,disabled:n||i.has(`transfer-domain:${_}`),children:[(0,V.jsx)(w.Item,{name:`domainId`,label:Q(l,`域名`,`Domain`),rules:[{required:!0}],children:(0,V.jsx)(c,{showSearch:!0,optionFilterProp:`label`,options:T.map(e=>({value:e.id,label:`${e.domain} · ${e.owner.username}`}))})}),(0,V.jsx)(w.Item,{name:`targetUserId`,label:Q(l,`目标用户`,`Target user`),rules:[{required:!0}],children:(0,V.jsx)(c,{options:C})}),(0,V.jsx)(w.Item,{name:`dnsCredentialMode`,label:Q(l,`DNS 凭据`,`DNS credential`),initialValue:`domain_only`,children:(0,V.jsx)(c,{options:[{value:`domain_only`,label:Q(l,`仅迁移域名`,`Domain only`)},{value:`with_dns_credential`,label:Q(l,`连同 DNS 凭据迁移`,`Include DNS credential`)},{value:`clear_dns_credential`,label:Q(l,`清空 DNS 凭据绑定`,`Clear DNS credential binding`)}]})}),(0,V.jsx)(d,{type:`primary`,htmlType:`submit`,loading:i.has(`transfer-domain:${_}`),children:Q(l,`执行迁移`,`Transfer`)})]})}),(0,V.jsx)(y,{title:Q(l,`迁移 DNS 凭据`,`Transfer DNS credential`),children:(0,V.jsxs)(w,{form:m,layout:`vertical`,onFinish:j,disabled:n||i.has(`transfer-dns:${b}`),children:[(0,V.jsx)(w.Item,{name:`credentialId`,label:Q(l,`DNS 凭据`,`DNS credential`),rules:[{required:!0}],children:(0,V.jsx)(c,{showSearch:!0,optionFilterProp:`label`,options:E.map(e=>({value:e.id,label:`${e.name} · ${e.zoneName} · ${e.owner.username}`}))})}),(0,V.jsx)(w.Item,{name:`targetUserId`,label:Q(l,`目标用户`,`Target user`),rules:[{required:!0}],children:(0,V.jsx)(c,{options:C})}),(0,V.jsx)(d,{htmlType:`submit`,loading:i.has(`transfer-dns:${b}`),children:Q(l,`执行迁移`,`Transfer`)})]})}),(0,V.jsx)(y,{title:Q(l,`迁移 API 密钥`,`Transfer API keys`),children:(0,V.jsxs)(w,{form:h,layout:`vertical`,onFinish:M,disabled:n||i.has(`transfer-token`),children:[(0,V.jsx)(w.Item,{name:`tokenIds`,label:Q(l,`API 密钥`,`API key`),rules:[{required:!0}],children:(0,V.jsx)(c,{mode:`multiple`,optionFilterProp:`label`,options:O.map(e=>({value:e.id,label:`${e.name} · ${e.tokenPrefix} · ${e.owner.username}`}))})}),(0,V.jsx)(w.Item,{name:`targetUserId`,label:Q(l,`目标用户`,`Target user`),rules:[{required:!0}],children:(0,V.jsx)(c,{options:C})}),(0,V.jsx)(d,{htmlType:`submit`,loading:i.has(`transfer-token`),children:Q(l,`执行迁移`,`Transfer`)})]})})]}),(0,V.jsx)(y,{title:Q(l,`资源归属`,`Resource ownership`),children:(0,V.jsx)(v,{rowKey:e=>e.user.id,columns:k,dataSource:S,loading:n,expandable:{expandedRowRender:e=>(0,V.jsx)(ye,{group:e})},scroll:{x:980}})})]})}function ye({group:e}){let{locale:t}=r();return(0,V.jsxs)(u,{direction:`vertical`,size:16,className:`full-width`,children:[(0,V.jsxs)(C,{size:`small`,column:2,className:`admin-resource-descriptions`,children:[(0,V.jsx)(C.Item,{label:Q(t,`邮箱`,`Email`),children:(0,V.jsx)(`span`,{className:`admin-breakable-text`,children:e.user.email})}),(0,V.jsx)(C.Item,{label:Q(t,`角色`,`Role`),children:e.user.role})]}),(0,V.jsx)(v,{size:`small`,rowKey:`id`,pagination:!1,dataSource:e.domains,columns:[{title:Q(t,`域名`,`Domain`),dataIndex:`domain`},{title:Q(t,`发信主机`,`Sending host`),dataIndex:`senderHost`},{title:Q(t,`DNS 凭据 ID`,`DNS credential ID`),dataIndex:`dnsCredentialId`}],scroll:{x:640}}),(0,V.jsx)(v,{size:`small`,rowKey:`id`,pagination:!1,dataSource:e.dnsCredentials,columns:[{title:Q(t,`DNS 凭据`,`DNS credential`),dataIndex:`name`},{title:`Provider`,dataIndex:`provider`},{title:`Zone`,dataIndex:`zoneName`}],scroll:{x:520}}),(0,V.jsx)(v,{size:`small`,rowKey:`id`,pagination:!1,dataSource:e.apiTokens,columns:[{title:Q(t,`API 密钥`,`API key`),dataIndex:`name`},{title:Q(t,`前缀`,`Prefix`),dataIndex:`tokenPrefix`},{title:Q(t,`创建时间`,`Created at`),dataIndex:`createdAt`,render:J}],scroll:{x:580}})]})}function be({users:e,loading:t,actionKeys:n,onPreview:i,onExecute:o}){let{message:s}=a.useApp(),{locale:l}=r(),[p]=w.useForm(),[m,h]=(0,R.useState)(null),[v,b]=(0,R.useState)({}),[S,E]=(0,R.useState)(``),[D,O]=(0,R.useState)(!1),k=e.map(e=>({value:e.id,label:`${e.username} (#${e.id})`}));async function A(e){O(!0);try{let t=await i(e);h(t.preview),b(t.preview.defaultOptions),E(``)}catch(e){s.error(e instanceof Error?e.message:Q(l,`预览失败`,`Preview failed`))}finally{O(!1)}}async function j(){m&&(await o({sourceUserId:m.sourceUser.id,targetUserId:m.targetUser.id,options:v,confirmation:S}),h(null),p.resetFields(),E(``))}let M=m?ce(m.sourceUser,m.targetUser):``;return(0,V.jsxs)(u,{direction:`vertical`,size:16,className:`full-width`,children:[(0,V.jsx)(y,{title:Q(l,`合并预览`,`Merge preview`),children:(0,V.jsxs)(w,{form:p,layout:`inline`,onFinish:A,disabled:t,className:`admin-inline-form`,children:[(0,V.jsx)(w.Item,{name:`sourceUserId`,label:Q(l,`源用户`,`Source user`),rules:[{required:!0}],children:(0,V.jsx)(c,{options:k,className:`toolbar-select`})}),(0,V.jsx)(w.Item,{name:`targetUserId`,label:Q(l,`目标用户`,`Target user`),rules:[{required:!0}],children:(0,V.jsx)(c,{options:k,className:`toolbar-select`})}),(0,V.jsx)(d,{type:m?`default`:`primary`,htmlType:`submit`,loading:D,children:Q(l,`预览`,`Preview`)})]})}),m?(0,V.jsx)(y,{title:`${m.sourceUser.username} → ${m.targetUser.username}`,children:(0,V.jsxs)(u,{direction:`vertical`,size:16,className:`full-width`,children:[m.warnings.length?(0,V.jsx)(g,{type:`warning`,showIcon:!0,message:m.warnings.map(e=>e.message||e.type).join(`;`)}):null,(0,V.jsx)(u,{wrap:!0,children:le(m).map(e=>(0,V.jsxs)(x,{tone:`neutral`,children:[Te(e.key,l),`: `,e.count]},e.key))}),(0,V.jsx)(`div`,{className:`form-grid two`,children:he.map(([e,t,n])=>(0,V.jsx)(_,{checked:v[e]!==!1,onChange:t=>b(n=>({...n,[e]:t.target.checked})),children:Q(l,t,n)},e))}),(0,V.jsx)(C,{column:1,bordered:!0,size:`small`,children:(0,V.jsx)(C.Item,{label:Q(l,`确认文本`,`Confirmation text`),children:(0,V.jsx)(f.Text,{code:!0,children:M})})}),(0,V.jsx)(T,{value:S,onChange:e=>E(e.target.value),placeholder:M}),(0,V.jsx)(d,{danger:!0,type:`primary`,loading:n.has(`merge`),disabled:S!==M,onClick:j,children:Q(l,`执行合并`,`Merge users`)})]})}):(0,V.jsx)(I,{description:Q(l,`暂无预览`,`No preview yet`)})]})}function xe({settings:e,loading:t,actionKeys:n,onSave:i,onTest:a}){let{locale:o}=r(),[s]=w.useForm();(0,R.useEffect)(()=>{e&&s.setFieldsValue(e)},[s,e]);async function c(e){await i(ue(e)),s.setFieldValue(`password`,``)}return(0,V.jsx)(y,{title:Q(o,`系统邮件服务器`,`System email server`),children:(0,V.jsxs)(w,{form:s,layout:`vertical`,onFinish:c,disabled:t,children:[(0,V.jsxs)(`div`,{className:`form-grid two`,children:[(0,V.jsx)(w.Item,{name:`host`,label:`SMTP Host`,rules:[{required:!0}],children:(0,V.jsx)(T,{})}),(0,V.jsx)(w.Item,{name:`port`,label:`SMTP Port`,rules:[{required:!0}],children:(0,V.jsx)(S,{min:1,max:65535,className:`full-width`})}),(0,V.jsx)(w.Item,{name:`secure`,label:`SSL / TLS`,valuePropName:`checked`,children:(0,V.jsx)(O,{})}),(0,V.jsx)(w.Item,{name:`helo`,label:`HELO`,children:(0,V.jsx)(T,{})}),(0,V.jsx)(w.Item,{name:`username`,label:`Username`,children:(0,V.jsx)(T,{autoComplete:`off`})}),(0,V.jsx)(w.Item,{name:`password`,label:e?.passwordSet?Q(o,`Password(留空保留)`,`Password (leave blank to keep)`):`Password`,children:(0,V.jsx)(T.Password,{autoComplete:`new-password`})}),(0,V.jsx)(w.Item,{name:`fromEmail`,label:`From Email`,rules:[{required:!0,type:`email`}],children:(0,V.jsx)(T,{})}),(0,V.jsx)(w.Item,{name:`fromName`,label:`From Name`,children:(0,V.jsx)(T,{})}),(0,V.jsx)(w.Item,{name:`testRecipient`,label:`Test Recipient`,children:(0,V.jsx)(T,{})})]}),(0,V.jsxs)(u,{wrap:!0,children:[(0,V.jsx)(d,{type:`primary`,htmlType:`submit`,loading:n.has(`system-email:save`),children:Q(o,`保存配置`,`Save settings`)}),(0,V.jsx)(d,{onClick:()=>a(s.getFieldValue(`testRecipient`)),loading:n.has(`system-email:test`),children:Q(o,`发送测试`,`Send test`)})]})]})})}function Se({logs:e,users:t,query:n,loading:i,onSearch:a}){let{locale:o}=r(),[s]=w.useForm(),l=t.map(e=>({value:e.id,label:`${e.username} (#${e.id})`}));(0,R.useEffect)(()=>{s.setFieldsValue(X(n))},[s,n]);let p=[{title:Q(o,`时间`,`Time`),dataIndex:`createdAt`,width:190,render:J},{title:Q(o,`动作`,`Action`),dataIndex:`action`,width:220},{title:Q(o,`操作者`,`Actor`),dataIndex:`actorUserId`,width:130,render:e=>e??`system`},{title:Q(o,`目标用户`,`Target user`),dataIndex:`targetUserId`,width:130,render:e=>e??`-`},{title:Q(o,`目标`,`Target`),render:(e,t)=>`${t.targetType}:${t.targetId||`-`}`,width:180},{title:Q(o,`摘要`,`Summary`),dataIndex:`summary`,render:e=>(0,V.jsx)(f.Text,{code:!0,ellipsis:!0,children:JSON.stringify(e)})}];async function m(e){await a(de(e))}return(0,V.jsxs)(u,{direction:`vertical`,size:16,className:`full-width`,children:[(0,V.jsx)(y,{className:`admin-audit-toolbar-card`,children:(0,V.jsxs)(w,{form:s,layout:`inline`,onFinish:m,disabled:i,className:`admin-inline-form`,children:[(0,V.jsx)(w.Item,{name:`actorUserId`,label:Q(o,`操作者`,`Actor`),children:(0,V.jsx)(c,{allowClear:!0,options:[{value:`system`,label:`system`},...l],className:`toolbar-select`})}),(0,V.jsx)(w.Item,{name:`targetUserId`,label:Q(o,`目标用户`,`Target user`),children:(0,V.jsx)(c,{allowClear:!0,options:l,className:`toolbar-select`})}),(0,V.jsx)(w.Item,{name:`action`,label:Q(o,`动作`,`Action`),children:(0,V.jsx)(T,{placeholder:`admin.user_merge`})}),(0,V.jsx)(w.Item,{name:`from`,label:Q(o,`开始`,`From`),children:(0,V.jsx)(T,{placeholder:`2026-07-08`})}),(0,V.jsx)(w.Item,{name:`to`,label:Q(o,`结束`,`To`),children:(0,V.jsx)(T,{placeholder:`2026-07-09`})}),(0,V.jsx)(d,{type:`primary`,htmlType:`submit`,loading:i,children:Q(o,`查询`,`Search`)})]})}),(0,V.jsx)(v,{rowKey:`id`,columns:p,dataSource:e,loading:i,scroll:{x:1100}})]})}function q({counts:e}){let{locale:t}=r();return e?(0,V.jsxs)(u,{wrap:!0,children:[(0,V.jsxs)(j,{children:[Q(t,`域名`,`Domains`),` `,e.domains]}),(0,V.jsxs)(j,{children:[`DNS `,e.dnsCredentials]}),(0,V.jsxs)(j,{children:[`Token `,e.apiTokens]}),(0,V.jsxs)(j,{children:[Q(t,`收信`,`Mailboxes`),` `,e.inboundMailboxes]}),(0,V.jsxs)(j,{children:[Q(t,`入站`,`Inbound`),` `,e.inboundMessages]}),(0,V.jsxs)(j,{children:[Q(t,`记录`,`Events`),` `,e.sendEvents]}),(0,V.jsxs)(j,{children:[`SMTP `,e.smtpCredential]})]}):(0,V.jsx)(j,{children:Q(t,`无资源`,`No resources`)})}function Ce({status:e}){let t=se(e),{locale:n}=r();return(0,V.jsx)(x,{tone:we(t.color),children:$(e,n)})}function we(e){return e===`green`||e===`success`?`success`:e===`gold`||e===`orange`||e===`warning`?`warning`:e===`red`||e===`error`||e===`volcano`?`error`:e===`blue`||e===`processing`||e===`cyan`?`info`:`neutral`}function J(e){return e?new Date(e).toLocaleString():`-`}function Y(e,t){return[`update:${t}`,`approve:${t}`,`resend:${t}`,`reset:${t}`,`temporary-password:${t}`].some(t=>e.has(t))}function X(e){let t=new URLSearchParams(e),n=t.get(`actorUserId`),r=t.get(`targetUserId`);return{actorUserId:n===`system`?n:Z(n),targetUserId:Z(r),action:t.get(`action`)||void 0,from:t.get(`from`)||void 0,to:t.get(`to`)||void 0}}function Z(e){let t=Number(e);return Number.isInteger(t)&&t>0?t:void 0}function Q(e,t,n){return e.startsWith(`en`)?n:t}function $(e,t){let n={pending_email:[`待验证邮箱`,`Email verification pending`],pending_review:[`待管理员审核`,`Admin review pending`],active:[`正常`,`Active`],disabled:[`已禁用`,`Disabled`]}[e];return n?Q(t,n[0],n[1]):e}function Te(e,t){let n={domains:[`域名`,`Domains`],dnsCredentials:[`DNS 凭据`,`DNS credentials`],apiTokens:[`API 密钥`,`API keys`],inboundMailboxes:[`收信邮箱`,`Mailboxes`],inboundMessages:[`入站邮件`,`Inbound mail`],sendEvents:[`发送记录`,`Sending activity`],smtpCredential:[`SMTP 凭据`,`SMTP credential`]}[e];return n?Q(t,n[0],n[1]):e}export{ge as default};