247 lines
9.8 KiB
JavaScript
247 lines
9.8 KiB
JavaScript
import PasswordOutlined from "@mui/icons-material/PasswordOutlined";
|
|
import PersonAddAltOutlined from "@mui/icons-material/PersonAddAltOutlined";
|
|
import OpenInNewOutlined from "@mui/icons-material/OpenInNewOutlined";
|
|
import AdminPanelSettingsOutlined from "@mui/icons-material/AdminPanelSettingsOutlined";
|
|
import { ExternalAdminPermissionDrawer } from "@/features/external-admin-users/components/ExternalAdminPermissionDrawer.jsx";
|
|
import { ExternalAdminUserFormDialog } from "@/features/external-admin-users/components/ExternalAdminUserFormDialog.jsx";
|
|
import { ExternalAdminUserPasswordDialog } from "@/features/external-admin-users/components/ExternalAdminUserPasswordDialog.jsx";
|
|
import styles from "@/features/external-admin-users/external-admin-users.module.css";
|
|
import { useExternalAdminUsersPage } from "@/features/external-admin-users/hooks/useExternalAdminUsersPage.js";
|
|
import {
|
|
AdminActionIconButton,
|
|
AdminFilterResetButton,
|
|
AdminFilterSelect,
|
|
AdminListBody,
|
|
AdminListPage,
|
|
AdminListToolbar,
|
|
AdminRowActions,
|
|
AdminSearchBox,
|
|
} from "@/shared/ui/AdminListLayout.jsx";
|
|
import { AdminSwitch } from "@/shared/ui/AdminSwitch.jsx";
|
|
import { AdminUserIdentity } from "@/shared/ui/AdminUserIdentity.jsx";
|
|
import { DataState } from "@/shared/ui/DataState.jsx";
|
|
import { DataTable } from "@/shared/ui/DataTable.jsx";
|
|
import { formatMillis } from "@/shared/utils/time.js";
|
|
|
|
const statusOptions = [
|
|
["", "全部状态"],
|
|
["active", "启用"],
|
|
["disabled", "停用"],
|
|
];
|
|
|
|
const columns = [
|
|
{
|
|
key: "linkedUser",
|
|
label: "绑定 App 用户",
|
|
render: (item) => (
|
|
<AdminUserIdentity
|
|
openInAppUserDetail
|
|
rows={[item.linkedUser?.displayUserId, item.linkedUser?.userId]}
|
|
user={item.linkedUser}
|
|
/>
|
|
),
|
|
width: "minmax(250px, 1.2fr)",
|
|
},
|
|
{
|
|
key: "username",
|
|
label: "外管账号",
|
|
render: (item) => (
|
|
<div className={styles.accountCell}>
|
|
<span className={styles.accountName}>{item.username || "-"}</span>
|
|
<span className={styles.accountMeta}>ID {item.id || "-"}</span>
|
|
</div>
|
|
),
|
|
width: "minmax(190px, 0.95fr)",
|
|
},
|
|
{
|
|
key: "status",
|
|
label: "状态",
|
|
render: (item, _index, context) => {
|
|
const page = context?.page;
|
|
// 外管状态、密码和权限都是账号级敏感写操作;同页串行化可避免多个请求互相覆盖全局 loading 状态。
|
|
const accountActionInFlight = Boolean(page?.loadingAction);
|
|
return (
|
|
<AdminSwitch
|
|
checked={item.status === "active"}
|
|
checkedLabel="启用"
|
|
disabled={!page?.abilities.canStatus || accountActionInFlight}
|
|
label={item.status === "active" ? "停用外管用户" : "启用外管用户"}
|
|
uncheckedLabel="停用"
|
|
onChange={() => page.toggleStatus(item)}
|
|
/>
|
|
);
|
|
},
|
|
width: "minmax(120px, 0.65fr)",
|
|
},
|
|
{
|
|
key: "permissions",
|
|
label: "外管权限",
|
|
render: (item) => `${item.permissions?.length || 0} 项`,
|
|
width: "minmax(120px, 0.65fr)",
|
|
},
|
|
{
|
|
key: "createdByAdminId",
|
|
label: "创建人",
|
|
render: (item) => item.createdByAdminId || "-",
|
|
width: "minmax(130px, 0.7fr)",
|
|
},
|
|
{
|
|
key: "lastLoginAtMs",
|
|
label: "最近登录",
|
|
render: (item) => formatMillis(item.lastLoginAtMs),
|
|
width: "minmax(170px, 0.85fr)",
|
|
},
|
|
{
|
|
key: "createdAtMs",
|
|
label: "创建时间",
|
|
render: (item) => formatMillis(item.createdAtMs),
|
|
width: "minmax(170px, 0.85fr)",
|
|
},
|
|
{
|
|
key: "actions",
|
|
label: "操作",
|
|
render: (item, _index, context) => {
|
|
const page = context?.page;
|
|
return (
|
|
<AdminRowActions>
|
|
<AdminActionIconButton
|
|
disabled={!page?.abilities.canManagePermissions || Boolean(page.loadingAction)}
|
|
label="配置权限"
|
|
onClick={() => page.openPermissions(item)}
|
|
>
|
|
<AdminPanelSettingsOutlined fontSize="small" />
|
|
</AdminActionIconButton>
|
|
<AdminActionIconButton
|
|
disabled={!page?.abilities.canResetPassword || Boolean(page.loadingAction)}
|
|
label="重置密码"
|
|
onClick={() => page.openPassword(item)}
|
|
>
|
|
<PasswordOutlined fontSize="small" />
|
|
</AdminActionIconButton>
|
|
</AdminRowActions>
|
|
);
|
|
},
|
|
resizable: false,
|
|
width: "132px",
|
|
},
|
|
];
|
|
|
|
export function ExternalAdminUsersPage() {
|
|
const page = useExternalAdminUsersPage();
|
|
const items = page.data.items || [];
|
|
const total = Number(page.data.total || 0);
|
|
|
|
return (
|
|
<AdminListPage>
|
|
<AdminListToolbar
|
|
actions={
|
|
<>
|
|
<AdminActionIconButton
|
|
component="a"
|
|
href="/external-admin/"
|
|
label="打开外管后台"
|
|
rel="noopener noreferrer"
|
|
target="_blank"
|
|
>
|
|
<OpenInNewOutlined fontSize="small" />
|
|
</AdminActionIconButton>
|
|
{page.abilities.canCreate ? (
|
|
<AdminActionIconButton
|
|
disabled={Boolean(page.loadingAction)}
|
|
label="创建外管用户"
|
|
primary
|
|
onClick={page.openCreate}
|
|
>
|
|
<PersonAddAltOutlined fontSize="small" />
|
|
</AdminActionIconButton>
|
|
) : null}
|
|
</>
|
|
}
|
|
filters={
|
|
<>
|
|
<AdminSearchBox
|
|
label="搜索"
|
|
placeholder="外管账号、短 ID"
|
|
value={page.keyword}
|
|
onChange={page.setKeyword}
|
|
/>
|
|
<AdminFilterSelect
|
|
label="状态"
|
|
options={statusOptions}
|
|
value={page.status}
|
|
onChange={page.setStatus}
|
|
/>
|
|
<AdminFilterResetButton
|
|
disabled={!page.keyword && !page.status}
|
|
onClick={page.resetFilters}
|
|
/>
|
|
</>
|
|
}
|
|
/>
|
|
<DataState error={page.error} loading={page.loading} onRetry={page.reload}>
|
|
<AdminListBody>
|
|
<DataTable
|
|
columns={columns}
|
|
context={{ page }}
|
|
items={items}
|
|
minWidth="1350px"
|
|
pagination={
|
|
total > 0
|
|
? {
|
|
onPageChange: page.setPage,
|
|
page: page.page,
|
|
pageSize: page.data.pageSize || page.pageSize,
|
|
total,
|
|
}
|
|
: undefined
|
|
}
|
|
rowKey={(item) => item.id || `${item.appCode}-${item.username}`}
|
|
/>
|
|
</AdminListBody>
|
|
</DataState>
|
|
<ExternalAdminUserFormDialog
|
|
abilities={page.abilities}
|
|
catalog={page.permissionCatalog.items || []}
|
|
catalogError={page.catalogError}
|
|
catalogLoading={page.catalogLoading}
|
|
form={page.createForm}
|
|
loading={page.loadingAction === "create"}
|
|
lookupLoading={page.lookupLoading}
|
|
open={page.createOpen}
|
|
targetUser={page.targetUser}
|
|
onClose={page.closeCreate}
|
|
onDisplayUserIdChange={page.setDisplayUserId}
|
|
onFormChange={page.setCreateForm}
|
|
onLookup={page.lookupTarget}
|
|
onReloadCatalog={page.reloadPermissionCatalog}
|
|
onSubmit={page.submitCreate}
|
|
/>
|
|
<ExternalAdminPermissionDrawer
|
|
abilities={page.abilities}
|
|
catalog={page.permissionCatalog.items || []}
|
|
catalogError={page.catalogError}
|
|
catalogLoading={page.catalogLoading}
|
|
error={page.permissionError}
|
|
loading={page.loadingAction.startsWith("permissions:")}
|
|
permissions={page.permissionForm.permissions}
|
|
permissionsLoading={page.permissionLoading}
|
|
user={page.permissionUser}
|
|
onChange={page.setPermissions}
|
|
onClose={page.closePermissions}
|
|
onReloadCatalog={page.reloadPermissionCatalog}
|
|
onRetry={page.retryPermissions}
|
|
onSubmit={page.submitPermissions}
|
|
/>
|
|
<ExternalAdminUserPasswordDialog
|
|
abilities={page.abilities}
|
|
form={page.passwordForm}
|
|
loading={page.loadingAction.startsWith("password:")}
|
|
user={page.passwordUser}
|
|
onClose={page.closePassword}
|
|
onFormChange={page.setPasswordForm}
|
|
onSubmit={page.submitPassword}
|
|
/>
|
|
</AdminListPage>
|
|
);
|
|
}
|