2026-06-15 10:43:53 +08:00

276 lines
9.8 KiB
JavaScript

import Add from "@mui/icons-material/Add";
import { AdminSwitch } from "@/shared/ui/AdminSwitch.jsx";
import TextField from "@mui/material/TextField";
import { formatMillis } from "@/shared/utils/time.js";
import { DataState } from "@/shared/ui/DataState.jsx";
import { bdStatusFilters } from "@/features/host-org/constants.js";
import { HostOrgActionModal } from "@/features/host-org/components/HostOrgActionModal.jsx";
import { HostOrgPerson, hostOrgRegionName } from "@/features/host-org/components/HostOrgIdentity.jsx";
import { HostOrgSortHeader } from "@/features/host-org/components/HostOrgSortHeader.jsx";
import { SalaryWalletAdjustButton, SalaryWalletCell } from "@/features/host-org/components/SalaryWalletControls.jsx";
import { HostOrgTable } from "@/features/host-org/components/HostOrgTable.jsx";
import { HostOrgToolbar } from "@/features/host-org/components/HostOrgToolbar.jsx";
import { useHostBdsPage } from "@/features/host-org/hooks/useHostBdsPage.js";
import { AdminRowActions } from "@/shared/ui/AdminListLayout.jsx";
import { createOptionsColumnFilter, createTextColumnFilter } from "@/shared/ui/tableFilters.js";
import styles from "@/features/host-org/host-org.module.css";
const bdColumns = [
{
key: "user",
label: "用户",
render: (item) => <BDUser item={item} />,
width: "minmax(220px, 1.25fr)",
},
{ key: "role", label: "角色", width: "minmax(100px, 0.65fr)" },
{
key: "salaryWallet",
label: "工资钱包",
sortable: true,
sortField: "salary_wallet",
render: (item) => (
<SalaryWalletCell role="bd" userId={item.userId} userLabel={bdUserLabel(item)} wallet={item.salaryWallet} />
),
width: "minmax(140px, 0.85fr)",
},
{
key: "parentLeaderUserId",
label: "上级 Leader",
render: (item) => <ParentLeader item={item} />,
width: "minmax(220px, 1.25fr)",
},
{
key: "regionId",
label: "区域",
render: (item, _index, context) => hostOrgRegionName(item, context?.regionOptions),
width: "minmax(130px, 0.75fr)",
},
{
key: "status",
label: "状态",
render: (item, _index, context) => <BDStatusSwitch item={item} page={context?.page} />,
width: "minmax(90px, 0.7fr)",
},
{
key: "createdByUserId",
label: "创建人",
render: (item) => <Creator item={item} />,
width: "minmax(180px, 1fr)",
},
{
key: "createdAtMs",
label: "创建时间",
render: (item) => formatMillis(item.createdAtMs),
width: "minmax(170px, 1fr)",
},
{
key: "updatedAtMs",
label: "更新时间",
render: (item) => formatMillis(item.updatedAtMs),
width: "minmax(170px, 1fr)",
},
];
export function HostBdsPage() {
const page = useHostBdsPage({ profileType: "bd" });
const createDisabled = !page.abilities.canCreate;
const items = page.data.items || [];
const total = page.data.total || 0;
const toolbarActions = [
page.abilities.canCreate
? { icon: <Add fontSize="small" />, label: "创建 BD", onClick: page.openBDForm, variant: "primary" }
: null,
].filter(Boolean);
const columns = [
...bdColumns,
page.abilities.canSalaryAdjust
? {
key: "actions",
label: "操作",
render: (item, _index, context) => <BDActions item={item} page={context?.page} />,
width: "minmax(80px, 0.45fr)",
}
: null,
]
.filter(Boolean)
.map((column) => {
if (column.key === "user") {
return {
...column,
filter: createTextColumnFilter({
placeholder: "搜索用户 ID、展示 ID、用户名",
value: page.query,
onChange: page.changeQuery,
}),
};
}
if (column.key === "parentLeaderUserId") {
return {
...column,
filter: createTextColumnFilter({
placeholder: "搜索 Leader 用户 ID",
value: page.parentLeaderUserId,
onChange: page.changeParentLeaderUserId,
}),
};
}
if (column.key === "status") {
return {
...column,
filter: createOptionsColumnFilter({
options: bdStatusFilters,
placeholder: "搜索状态",
value: page.status,
onChange: page.changeStatus,
}),
};
}
if (column.sortable) {
return {
...column,
header: (
<HostOrgSortHeader
field={column.sortField}
label={column.label}
sortBy={page.sortBy}
sortDirection={page.sortDirection}
onToggle={page.changeSort}
/>
),
};
}
return column;
});
return (
<section className={styles.root}>
<div className={styles.contentPanel}>
<HostOrgToolbar actions={toolbarActions} />
<DataState error={page.error} loading={page.loading} onRetry={page.reload}>
<div className={styles.listBlock}>
<HostOrgTable
columns={columns}
context={{ page, regionOptions: page.regionOptions }}
items={items}
minWidth="1440px"
pagination={
total > 0
? {
page: page.page,
pageSize: page.data.pageSize || 50,
total,
onPageChange: page.setPage,
}
: undefined
}
rowKey={(item) => `bd-${item.userId}`}
/>
</div>
</DataState>
</div>
<HostOrgActionModal
disabled={createDisabled}
loading={page.loadingAction === "bd"}
open={page.activeAction === "bd"}
sectionTitle="BD 信息"
onClose={page.closeAction}
onSubmit={page.submitBD}
title="创建 BD"
>
<TextField
disabled={createDisabled}
label="用户短 ID"
required
type="number"
value={page.bdForm.targetUserId}
onChange={(event) => page.setBDForm({ ...page.bdForm, targetUserId: event.target.value })}
/>
<TextField
disabled={createDisabled}
label="上级 Leader 短 ID"
type="number"
value={page.bdForm.parentLeaderUserId}
onChange={(event) => page.setBDForm({ ...page.bdForm, parentLeaderUserId: event.target.value })}
/>
<TextField
disabled={createDisabled}
label="原因"
multiline
minRows={2}
value={page.bdForm.reason}
onChange={(event) => page.setBDForm({ ...page.bdForm, reason: event.target.value })}
/>
</HostOrgActionModal>
</section>
);
}
function BDUser({ item }) {
return (
<HostOrgPerson
avatar={item.avatar}
displayUserId={item.displayUserId}
fallbackId={item.userId}
username={item.username}
/>
);
}
function ParentLeader({ item }) {
if (!item.parentLeaderUserId) {
return "-";
}
return (
<HostOrgPerson
avatar={item.parentLeaderAvatar}
displayUserId={item.parentLeaderDisplayUserId}
fallbackId={item.parentLeaderUserId}
username={item.parentLeaderUsername || "Leader"}
/>
);
}
function BDStatusSwitch({ item, page }) {
return (
<AdminSwitch
checked={item.status === "active"}
disabled={!page?.abilities.canUpdate || page.loadingAction === `bd-status-${item.userId}`}
inputProps={{ "aria-label": item.status === "active" ? "停用 BD" : "启用 BD" }}
onChange={(event) => page.toggleBD(item, event.target.checked)}
/>
);
}
function Creator({ item }) {
if (!item.createdByUserId && !item.createdByDisplayUserId && !item.createdByUsername) {
return "-";
}
return (
<HostOrgPerson
avatar={item.createdByAvatar}
displayUserId={item.createdByDisplayUserId}
fallbackId={item.createdByUserId}
username={item.createdByUsername || "创建人"}
/>
);
}
function BDActions({ item, page }) {
return (
<AdminRowActions>
<SalaryWalletAdjustButton
role="bd"
userId={item.userId}
userLabel={bdUserLabel(item)}
onAdjusted={page?.reload}
/>
</AdminRowActions>
);
}
function bdUserLabel(item) {
return item.displayUserId || item.username || item.userId;
}