|
|
@@ -1,23 +1,37 @@
|
|
|
-import { MEMBER_TYPE_COLORS, MEMBER_TYPE_LABELS, STATUS_DISABLED, STATUS_ENABLED } from '@/defines';
|
|
|
+import {
|
|
|
+ MEMBER_TYPE_COLORS,
|
|
|
+ MEMBER_TYPE_LABELS,
|
|
|
+ STATUS_DISABLED,
|
|
|
+ STATUS_ENABLED,
|
|
|
+ STATUS_OPTIONS,
|
|
|
+} from '@/defines';
|
|
|
import { BindRolesDrawer } from '@/pages/Admin/_shared/BindRolesDrawer';
|
|
|
import { UserPermDrawer } from '@/pages/Admin/_shared/UserPermDrawer';
|
|
|
import {
|
|
|
useProductRolesBase,
|
|
|
useUserProductRoles,
|
|
|
} from '@/pages/Admin/_shared/useUserProductRoles';
|
|
|
+import { fetchDeptTree } from '@/services/dept';
|
|
|
import { fetchUpdateUserStatus, fetchUserList } from '@/services/user';
|
|
|
import { unixTimeFormat } from '@/utils/timeUtils';
|
|
|
import { StopOutlined } from '@ant-design/icons';
|
|
|
import { ActionType, PageContainer, ProColumns, ProTable } from '@ant-design/pro-components';
|
|
|
import { useIntl } from '@umijs/max';
|
|
|
import { Button, Popconfirm, Tag, message } from 'antd';
|
|
|
-import { useMemo, useRef, useState } from 'react';
|
|
|
+import { useEffect, useMemo, useRef, useState } from 'react';
|
|
|
import { UserForm } from './components/Form';
|
|
|
|
|
|
+const flattenDeptTree = (items: API.DeptItem[]): { label: string; value: number }[] =>
|
|
|
+ items.flatMap((d) => [
|
|
|
+ { label: d.name, value: d.id },
|
|
|
+ ...(d.children ? flattenDeptTree(d.children) : []),
|
|
|
+ ]);
|
|
|
+
|
|
|
export default function UserPage() {
|
|
|
const intl = useIntl();
|
|
|
const actionRef = useRef<ActionType>();
|
|
|
const [pageUsers, setPageUsers] = useState<API.UserItem[]>([]);
|
|
|
+ const [deptOptions, setDeptOptions] = useState<{ label: string; value: number }[]>([]);
|
|
|
const [rolesDrawer, setRolesDrawer] = useState<{ open: boolean; userId: number }>({
|
|
|
open: false,
|
|
|
userId: 0,
|
|
|
@@ -28,6 +42,12 @@ export default function UserPage() {
|
|
|
});
|
|
|
const [refreshKey, setRefreshKey] = useState(0);
|
|
|
|
|
|
+ useEffect(() => {
|
|
|
+ fetchDeptTree().then((res) => {
|
|
|
+ setDeptOptions([{ label: '无部门', value: 0 }, ...flattenDeptTree(res.data ?? [])]);
|
|
|
+ });
|
|
|
+ }, []);
|
|
|
+
|
|
|
const userIds = useMemo(() => pageUsers.map((u) => u.id), [pageUsers]);
|
|
|
const productRolesBase = useProductRolesBase();
|
|
|
const { userProductInfo } = useUserProductRoles(userIds, productRolesBase, refreshKey);
|
|
|
@@ -49,15 +69,31 @@ export default function UserPage() {
|
|
|
title: '状态',
|
|
|
dataIndex: 'status',
|
|
|
width: 80,
|
|
|
+ valueType: 'select',
|
|
|
+ fieldProps: { options: STATUS_OPTIONS },
|
|
|
render: (_, r) => (
|
|
|
<Tag color={r.status === STATUS_ENABLED ? 'success' : 'error'}>
|
|
|
{r.status === STATUS_ENABLED ? '启用' : '禁用'}
|
|
|
</Tag>
|
|
|
),
|
|
|
},
|
|
|
+ {
|
|
|
+ title: '部门',
|
|
|
+ dataIndex: 'deptId',
|
|
|
+ width: 150,
|
|
|
+ valueType: 'select',
|
|
|
+ fieldProps: { options: deptOptions, showSearch: true },
|
|
|
+ render: (_, r) => {
|
|
|
+ const dept = deptOptions.find((d) => d.value === r.deptId);
|
|
|
+ return (
|
|
|
+ dept?.label ?? <span className="text-(--ant-color-text-quaternary) text-xs">无</span>
|
|
|
+ );
|
|
|
+ },
|
|
|
+ },
|
|
|
{
|
|
|
title: '产品角色',
|
|
|
key: 'productRoles',
|
|
|
+ search: false,
|
|
|
render: (_, r) => {
|
|
|
const info = userProductInfo.get(r.id) ?? [];
|
|
|
if (info.length === 0)
|
|
|
@@ -104,6 +140,7 @@ export default function UserPage() {
|
|
|
title: '创建时间',
|
|
|
dataIndex: 'createTime',
|
|
|
width: 180,
|
|
|
+ search: false,
|
|
|
render: (_, r) => unixTimeFormat(r.createTime),
|
|
|
},
|
|
|
{
|
|
|
@@ -154,7 +191,7 @@ export default function UserPage() {
|
|
|
actionRef={actionRef}
|
|
|
columns={columns}
|
|
|
rowKey="id"
|
|
|
- search={false}
|
|
|
+ search={{ span: { xs: 24, sm: 12, md: 8, lg: 6, xl: 4, xxl: 4 } }}
|
|
|
request={fetchUserList}
|
|
|
onDataSourceChange={setPageUsers}
|
|
|
scroll={{ x: 1220 }}
|