skyouc
2024-12-21 c635d78b479510ebe2556a420948effcd30a0731
zy-asrs-flow/src/pages/system/user/index.jsx
@@ -1,747 +1,747 @@
import React, { useState, useRef, useEffect } from 'react';
import { Button, message, Modal, Row, Col, Card, Tree, Input, Tag, Skeleton } from 'antd';
import {
    FooterToolbar,
    PageContainer,
    ProTable,
    LightFilter,
    TableDropdown
} from '@ant-design/pro-components';
import { FormattedMessage, useIntl } from '@umijs/max';
import { PlusOutlined, ExportOutlined, DownOutlined, DeleteOutlined, ExclamationCircleOutlined } from '@ant-design/icons';
import Http from '@/utils/http';
import Edit from './components/edit'
import Pwd from './components/pwd'
import AssignRole from './components/assignRole'
import { TextFilter, SelectFilter, DatetimeRangeFilter, LinkFilter } from '@/components/TableSearch'
import { transformTreeData, getTreeAllKeys } from '@/utils/tree-util'
import { statusMap } from '@/utils/enum-util'
import { repairBug } from '@/utils/common-util';
const TABLE_KEY = "pro-table-user";
const handleSave = async (val, intl) => {
    const hide = message.loading(intl.formatMessage({ id: 'page.adding', defaultMessage: '正在添加' }));
    try {
        const resp = await Http.doPost('api/user/save', val);
        if (resp.code === 200) {
            message.success(intl.formatMessage({ id: 'page.add.success', defaultMessage: '添加成功' }));
            return true;
        } else {
            message.error(resp.msg);
            return false;
        }
    } catch (error) {
        message.error(intl.formatMessage({ id: 'page.add.fail', defaultMessage: '添加失败请重试!' }));
        return false;
    } finally {
        hide();
    }
};
const handleUpdate = async (val, intl) => {
    const hide = message.loading(intl.formatMessage({ id: 'page.updating', defaultMessage: '正在更新' }));
    try {
        const resp = await Http.doPost('api/user/update', val);
        if (resp.code === 200) {
            message.success(intl.formatMessage({ id: 'page.update.success', defaultMessage: '更新成功' }));
            return true;
        } else {
            message.error(resp.msg);
            return false;
        }
    } catch (error) {
        message.error(intl.formatMessage({ id: 'page.update.fail', defaultMessage: '更新失败请重试!' }));
        return false;
    } finally {
        hide();
    }
};
const handleRemove = async (rows, intl) => {
    if (!rows) return true;
    const hide = message.loading(intl.formatMessage({ id: 'page.deleting', defaultMessage: '正在删除' }));
    try {
        const resp = await Http.doPost('api/user/remove/' + rows.map((row) => row.id).join(','));
        if (resp.code === 200) {
            message.success(intl.formatMessage({ id: 'page.delete.success', defaultMessage: '删除成功' }));
            return true;
        } else {
            message.error(resp.msg);
            return false;
        }
    } catch (error) {
        message.error(intl.formatMessage({ id: 'page.delete.fail', defaultMessage: '删除失败,请重试!' }));
        return false;
    } finally {
        hide();
    }
};
const handleExport = async (intl) => {
    const hide = message.loading(intl.formatMessage({ id: 'page.exporting', defaultMessage: '正在导出' }));
    try {
        const resp = await Http.doPostBlob('api/user/export');
        const blob = new Blob([resp], { type: 'application/vnd.ms-excel' });
        window.location.href = window.URL.createObjectURL(blob);
        message.success(intl.formatMessage({ id: 'page.export.success', defaultMessage: '导出成功' }));
        return true;
    } catch (error) {
        message.error(intl.formatMessage({ id: 'page.export.fail', defaultMessage: '导出失败,请重试' }));
        return false;
    } finally {
        hide();
    }
};
const handlePwd = async (val, intl) => {
    const hide = message.loading(intl.formatMessage({ id: 'page.resetting', defaultMessage: '正在重置' }));
    try {
        const resp = await Http.doPost('api/user/reset/pwd', val);
        if (resp.code === 200) {
            message.success(intl.formatMessage({ id: 'page.reset.success', defaultMessage: '重置成功' }));
            return true;
        } else {
            message.error(resp.msg);
            return false;
        }
    } catch (error) {
        message.error(intl.formatMessage({ id: 'page.reset.fail', defaultMessage: '重置失败请重试!' }));
        return false;
    } finally {
        hide();
    }
};
const Main = () => {
    const intl = useIntl();
    const formTableRef = useRef();
    const actionRef = useRef();
    const [selectedRows, setSelectedRows] = useState([]);
    const [modalVisible, setModalVisible] = useState(false);
    const [currentRow, setCurrentRow] = useState();
    const [searchParam, setSearchParam] = useState({});
    const [boxHeight, setBoxHeight] = useState();
    const [deptTreeLoading, setDeptTreeLoading] = useState(false);
    const [deptTreeData, setDeptTreeData] = useState([]);
    const [deptExpandedKeys, setDeptExpandedKeys] = useState([]);
    const [pwdModalVisible, setPwdModalVisible] = useState(false);
    const [assignModalVisible, setAssignModalVisible] = useState(false);
    const loadDeptTreeData = (param) => {
        setDeptTreeLoading(true);
        Http.doPostPromise('/api/dept/tree', param, (res) => {
            setDeptTreeLoading(false);
            const rootMenu = { id: 0, name: '全部', value: 0, children: [] };
            rootMenu.children = res.data;
            // const treeData = transformTreeData([rootMenu]);
            const treeData = transformTreeData(res.data);
            setDeptTreeData(treeData);
            const treeAllKeys = getTreeAllKeys(treeData);
            setDeptExpandedKeys(treeAllKeys);
        }).catch((err) => {
            console.error(err);
            setDeptTreeLoading(false);
        })
    }
    useEffect(() => {
        const handleResize = () => setBoxHeight(window.innerHeight - 320);
        window.addEventListener('resize', handleResize);
        handleResize();
        loadDeptTreeData();
        return () => window.removeEventListener('resize', handleResize);
    }, []);
    const columns = [
        {
            title: intl.formatMessage({
                id: 'page.table.no',
                defaultMessage: 'No'
            }),
            dataIndex: 'index',
            valueType: 'indexBorder',
            width: 48,
        },
        {
            title: '部门',
            dataIndex: 'deptId$',
            valueType: 'text',
            hidden: false,
            render: (_, record) => {
                if (_ && _ !== '-') {
                    return <Tag color={""}>{_}</Tag>
                } else {
                    return '-'
                }
            },
            // filterDropdown: (props) => <LinkFilter
            //     name='deptId'
            //     major='dept'
            //     {...props}
            //     actionRef={actionRef}
            //     setSearchParam={setSearchParam}
            // />,
        },
        {
            title: '登录账号',
            dataIndex: 'username',
            valueType: 'text',
            hidden: false,
            copyable: true,
            filterDropdown: (props) => <TextFilter
                name='username'
                {...props}
                actionRef={actionRef}
                setSearchParam={setSearchParam}
            />,
            render: (_, record) => {
                return <span style={{ fontWeight: "bold" }}>{_}</span>
            }
        },
        {
            title: '名称',
            dataIndex: 'nickname',
            valueType: 'text',
            hidden: false,
            filterDropdown: (props) => <TextFilter
                name='nickname'
                {...props}
                actionRef={actionRef}
                setSearchParam={setSearchParam}
            />,
            render: (_, record) => {
                return <span style={{ fontWeight: "bold" }}>{_}</span>
            }
        },
        {
            title: '密码',
            dataIndex: 'password',
            valueType: 'password',
            hidden: false,
            filterDropdown: (props) => <TextFilter
                name='password'
                {...props}
                actionRef={actionRef}
                setSearchParam={setSearchParam}
            />,
        },
        {
            title: '头像',
            dataIndex: 'avatar',
            valueType: 'text',
            hidden: false,
            filterDropdown: (props) => <TextFilter
                name='avatar'
                {...props}
                actionRef={actionRef}
                setSearchParam={setSearchParam}
            />,
        },
        {
            title: '工号',
            dataIndex: 'code',
            valueType: 'text',
            hidden: false,
            filterDropdown: (props) => <TextFilter
                name='code'
                {...props}
                actionRef={actionRef}
                setSearchParam={setSearchParam}
            />,
        },
        {
            title: '性别',
            dataIndex: 'sex$',
            valueType: 'text',
            hidden: false,
            filterDropdown: (props) => <SelectFilter
                name='sex'
                {...props}
                actionRef={actionRef}
                setSearchParam={setSearchParam}
                data={[
                    { label: '未知', value: 0 },
                    { label: '男', value: 1 },
                    { label: '女', value: 2 },
                ]}
            />,
        },
        {
            title: '手机号',
            dataIndex: 'phone',
            valueType: 'text',
            hidden: false,
            filterDropdown: (props) => <TextFilter
                name='phone'
                {...props}
                actionRef={actionRef}
                setSearchParam={setSearchParam}
            />,
        },
        {
            title: '邮箱',
            dataIndex: 'email',
            valueType: 'text',
            hidden: false,
            filterDropdown: (props) => <TextFilter
                name='email'
                {...props}
                actionRef={actionRef}
                setSearchParam={setSearchParam}
            />,
        },
        {
            title: '邮箱验证',
            dataIndex: 'emailVerified$',
            valueType: 'text',
            hidden: false,
            filterDropdown: (props) => <SelectFilter
                name='emailVerified'
                {...props}
                actionRef={actionRef}
                setSearchParam={setSearchParam}
                data={[
                    { label: '否', value: 0 },
                    { label: '是', value: 1 },
                ]}
            />,
        },
        {
            title: '真实姓名',
            dataIndex: 'realName',
            valueType: 'text',
            hidden: false,
            filterDropdown: (props) => <TextFilter
                name='realName'
                {...props}
                actionRef={actionRef}
                setSearchParam={setSearchParam}
            />,
        },
        {
            title: '身份证号',
            dataIndex: 'idCard',
            valueType: 'text',
            hidden: false,
            filterDropdown: (props) => <TextFilter
                name='idCard'
                {...props}
                actionRef={actionRef}
                setSearchParam={setSearchParam}
            />,
        },
        {
            title: '出生日期',
            dataIndex: 'birthday',
            valueType: 'text',
            hidden: false,
            filterDropdown: (props) => <TextFilter
                name='birthday'
                {...props}
                actionRef={actionRef}
                setSearchParam={setSearchParam}
            />,
        },
        {
            title: '个人简介',
            dataIndex: 'introduction',
            valueType: 'text',
            hidden: false,
            filterDropdown: (props) => <TextFilter
                name='introduction'
                {...props}
                actionRef={actionRef}
                setSearchParam={setSearchParam}
            />,
        },
        {
            title: '状态',
            dataIndex: 'status$',
            valueType: 'text',
            hidden: false,
            render: (_, record) => {
                const status = statusMap[record.status]
                return <Tag color={status.color}>{status.text}</Tag>
            },
            filterDropdown: (props) => <SelectFilter
                name='status'
                {...props}
                actionRef={actionRef}
                setSearchParam={setSearchParam}
                data={[
                    { label: '正常', value: 1 },
                    { label: '禁用', value: 0 },
                ]}
            />,
        },
        {
            title: '添加时间',
            dataIndex: 'createTime$',
            valueType: 'text',
            hidden: false,
            filterDropdown: (props) => <DatetimeRangeFilter
                name='createTime'
                {...props}
                actionRef={actionRef}
                setSearchParam={setSearchParam}
            />,
        },
        {
            title: '修改时间',
            dataIndex: 'updateTime$',
            valueType: 'text',
            hidden: false,
            filterDropdown: (props) => <DatetimeRangeFilter
                name='updateTime'
                {...props}
                actionRef={actionRef}
                setSearchParam={setSearchParam}
            />,
        },
        {
            title: '修改人员',
            dataIndex: 'updateBy$',
            valueType: 'text',
            hidden: false,
            filterDropdown: (props) => <LinkFilter
                name='updateBy'
                major='user'
                {...props}
                actionRef={actionRef}
                setSearchParam={setSearchParam}
            />,
        },
        {
            title: '备注',
            dataIndex: 'memo',
            valueType: 'text',
            hidden: false,
            filterDropdown: (props) => <TextFilter
                name='memo'
                {...props}
                actionRef={actionRef}
                setSearchParam={setSearchParam}
            />,
        },
        {
            title: '操作',
            dataIndex: 'option',
            valueType: 'option',
            width: 180,
            render: (_, record) => [
                <Button
                    type="link"
                    key="edit"
                    style={{ padding: '2px 3px' }}
                    onClick={() => {
                        setModalVisible(true);
                        setCurrentRow(record);
                    }}
                >
                    <FormattedMessage id='page.edit' defaultMessage='编辑' />
                </Button>,
                <Button
                    type="link"
                    key="pwd"
                    style={{ padding: '2px 2px' }}
                    onClick={() => {
                        setPwdModalVisible(true);
                        setCurrentRow(record);
                    }}
                >
                    <FormattedMessage id='page.reset.pwd' defaultMessage='重置密码' />
                </Button>,
                <Button
                    type="link"
                    danger
                    style={{ padding: '4px' }}
                    key="remove"
                    onClick={async () => {
                        Modal.confirm({
                            title: intl.formatMessage({ id: 'page.delete', defaultMessage: '删除' }),
                            content: intl.formatMessage({ id: 'page.delete.confirm', defaultMessage: '确定删除该项吗?' }),
                            onOk: async () => {
                                const success = await handleRemove([record], intl);
                                if (success) {
                                    if (actionRef.current) {
                                        actionRef.current.reload();
                                    }
                                }
                            },
                        });
                    }}
                >
                    <FormattedMessage id='page.delete' defaultMessage='删除' />
                </Button>,
                <TableDropdown
                    key="actionGroup"
                    name="dropdown"
                    onSelect={(key) => {
                        if (key === 'assign') {
                            setAssignModalVisible(true);
                            setCurrentRow(record);
                        }
                    }}
                    menus={[
                        { key: 'assign', name: intl.formatMessage({ id: 'page.assign.role', defaultMessage: '分配角色' }) },
                    ]}
                />,
            ],
        },
    ];
    return (
        <PageContainer
            header={{
                breadcrumb: {},
            }}
        >
            <Row gutter={[16, 24]}>
                <Col lg={6} md={24}>
                    <Card
                        title={intl.formatMessage({ id: 'system.dept', defaultMessage: '部门' })}
                        style={{ width: '100%', height: 'calc(100vh - 160px)' }}
                    >
                        <Input
                            style={{ marginBottom: 10 }}
                            placeholder={intl.formatMessage({ id: 'commont.enter', defaultMessage: '请输入' })}
                            onChange={(e) => {
                                const { value } = e.target;
                                loadDeptTreeData({
                                    condition: value
                                })
                            }}
                        />
                        <div style={{ height: 'calc(100vh - 325px)', overflowY: 'auto' }}>
                            {deptTreeLoading ? (
                                <Skeleton active />
                            ) : (
                                <Tree
                                    showLine
                                    blockNode
                                    defaultExpandAll    // 异步加载失效
                                    expandedKeys={deptExpandedKeys}
                                    onExpand={setDeptExpandedKeys}
                                    treeData={deptTreeData}
                                    switcherIcon={<DownOutlined />}
                                    onSelect={(selectedKeys, info) => {
                                        const deptId = selectedKeys[0];
                                        setSearchParam(prevState => ({
                                            ...prevState,
                                            deptId: deptId
                                        }));
                                        actionRef.current?.reload();
                                    }}
                                />
                            )}
                        </div>
                    </Card>
                </Col>
                <Col lg={18} md={24}>
                    <ProTable
                        key="user"
                        rowKey="id"
                        actionRef={actionRef}
                        formRef={formTableRef}
                        columns={columns}
                        cardBordered
                        size='small'
                        // scroll={{ y: boxHeight }}
                        dateFormatter="string"
                        pagination={{ pageSize: 12 }}
                        search={false}
                        toolbar={{
                            search: {
                                onSearch: (value) => {
                                    setSearchParam(prevState => ({
                                        ...prevState,
                                        condition: value
                                    }));
                                    actionRef.current?.reload();
                                },
                            },
                            filter: (
                                <LightFilter
                                    onValuesChange={(val) => {
                                    }}
                                >
                                </LightFilter>
                            ),
                            actions: [
                                <Button
                                    type="primary"
                                    danger
                                    key="removeBatch"
                                    hidden={selectedRows?.length === 0}
                                    onClick={async () => {
                                        Modal.confirm({
                                            title: intl.formatMessage({ id: 'page.delete', defaultMessage: '删除' }),
                                            content: intl.formatMessage({ id: 'page.delete.confirm', defaultMessage: '确定删除该项吗?' }),
                                            icon: <ExclamationCircleOutlined />,
                                            async onOk() {
                                                const success = await handleRemove(selectedRows, intl);
                                                if (success) {
                                                    setSelectedRows([]);
                                                    actionRef.current.reload();
                                                }
                                            },
                                            onCancel() { },
                                        });
                                    }}
                                >
                                    <DeleteOutlined />
                                    <FormattedMessage id='page.delete' defaultMessage='删除' />
                                </Button>,
                                <Button
                                    type="primary"
                                    key="save"
                                    onClick={async () => {
                                        setModalVisible(true)
                                    }}
                                >
                                    <PlusOutlined />
                                    <FormattedMessage id='page.add' defaultMessage='添加' />
                                </Button>,
                                <Button
                                    key="export"
                                    onClick={async () => {
                                        handleExport(intl);
                                    }}
                                >
                                    <ExportOutlined />
                                    <FormattedMessage id='page.export' defaultMessage='导出' />
                                </Button>,
                            ],
                        }}
                        request={(params, sorter, filter) =>
                            Http.doPostPromise('/api/user/page1', { ...params, ...searchParam }, (res) => {
                                return {
                                    data: res.data.records,
                                    total: res.data.total,
                                    success: true,
                                }
                            })
                        }
                        tableAlertRender={false}
                        rowSelection={{
                            onChange: (ids, rows) => {
                                setSelectedRows(rows);
                            }
                        }}
                        columnsState={{
                            persistenceKey: TABLE_KEY,
                            persistenceType: 'localStorage',
                            defaultValue: {
                                password: { show: repairBug(TABLE_KEY, 'password', false) },
                                avatar: { show: repairBug(TABLE_KEY, 'avatar', false) },
                                code: { show: repairBug(TABLE_KEY, 'code', false) },
                                phone: { show: repairBug(TABLE_KEY, 'phone', false) },
                                email: { show: repairBug(TABLE_KEY, 'email', false) },
                                emailVerified$: { show: repairBug(TABLE_KEY, 'emailVerified$', false) },
                                realName: { show: repairBug(TABLE_KEY, 'realName', false) },
                                idCard: { show: repairBug(TABLE_KEY, 'idCard', false) },
                                birthday: { show: repairBug(TABLE_KEY, 'birthday', false) },
                                introduction: { show: repairBug(TABLE_KEY, 'introduction', false) },
                                createTime$: { show: repairBug(TABLE_KEY, 'createTime$', false) },
                                updateTime$: { show: repairBug(TABLE_KEY, 'updateTime$', false) },
                                updateBy$: { show: repairBug(TABLE_KEY, 'updateBy$', false) },
                                memo: { show: repairBug(TABLE_KEY, 'memo', false) },
                                option: { fixed: 'right', disable: true },
                            },
                            onChange(value) {
                            },
                        }}
                    />
                </Col>
            </Row>
            <Edit
                open={modalVisible}
                values={currentRow || {}}
                treeData={deptTreeData}
                onCancel={
                    () => {
                        setModalVisible(false);
                        setCurrentRow(undefined);
                    }
                }
                onSubmit={async (values) => {
                    let ok = false;
                    if (values.id) {
                        ok = await handleUpdate({ ...values }, intl)
                    } else {
                        ok = await handleSave({ ...values }, intl)
                    }
                    if (ok) {
                        setModalVisible(false);
                        setCurrentRow(undefined);
                        if (actionRef.current) {
                            actionRef.current.reload();
                        }
                    }
                }
                }
            />
            <Pwd
                open={pwdModalVisible}
                values={currentRow || {}}
                onCancel={
                    () => {
                        setPwdModalVisible(false);
                        setCurrentRow(undefined);
                    }
                }
                onSubmit={async (values) => {
                    let ok = false;
                    if (values.id) {
                        ok = await handlePwd({ ...values }, intl)
                    }
                    if (ok) {
                        setPwdModalVisible(false);
                        setCurrentRow(undefined);
                        if (actionRef.current) {
                            actionRef.current.reload();
                        }
                    }
                }
                }
            />
            <AssignRole
                open={assignModalVisible}
                values={currentRow || {}}
                onCancel={
                    () => {
                        setAssignModalVisible(false);
                        setCurrentRow(undefined);
                    }
                }
                onSubmit={async (values) => {
                    let ok = false;
                    if (values.id) {
                        ok = await handleUpdate({ ...values }, intl)
                    }
                    if (ok) {
                        setAssignModalVisible(false);
                        setCurrentRow(undefined);
                        if (actionRef.current) {
                            actionRef.current.reload();
                        }
                    }
                }}
            />
        </PageContainer>
    );
};
export default Main;
import React, { useState, useRef, useEffect } from 'react';
import { Button, message, Modal, Row, Col, Card, Tree, Input, Tag, Skeleton } from 'antd';
import {
    FooterToolbar,
    PageContainer,
    ProTable,
    LightFilter,
    TableDropdown
} from '@ant-design/pro-components';
import { FormattedMessage, useIntl } from '@umijs/max';
import { PlusOutlined, ExportOutlined, DownOutlined, DeleteOutlined, ExclamationCircleOutlined } from '@ant-design/icons';
import Http from '@/utils/http';
import Edit from './components/edit'
import Pwd from './components/pwd'
import AssignRole from './components/assignRole'
import { TextFilter, SelectFilter, DatetimeRangeFilter, LinkFilter } from '@/components/TableSearch'
import { transformTreeData, getTreeAllKeys } from '@/utils/tree-util'
import { statusMap } from '@/utils/enum-util'
import { repairBug } from '@/utils/common-util';
const TABLE_KEY = "pro-table-user";
const handleSave = async (val, intl) => {
    const hide = message.loading(intl.formatMessage({ id: 'page.adding', defaultMessage: '正在添加' }));
    try {
        const resp = await Http.doPost('api/user/save', val);
        if (resp.code === 200) {
            message.success(intl.formatMessage({ id: 'page.add.success', defaultMessage: '添加成功' }));
            return true;
        } else {
            message.error(resp.msg);
            return false;
        }
    } catch (error) {
        message.error(intl.formatMessage({ id: 'page.add.fail', defaultMessage: '添加失败请重试!' }));
        return false;
    } finally {
        hide();
    }
};
const handleUpdate = async (val, intl) => {
    const hide = message.loading(intl.formatMessage({ id: 'page.updating', defaultMessage: '正在更新' }));
    try {
        const resp = await Http.doPost('api/user/update', val);
        if (resp.code === 200) {
            message.success(intl.formatMessage({ id: 'page.update.success', defaultMessage: '更新成功' }));
            return true;
        } else {
            message.error(resp.msg);
            return false;
        }
    } catch (error) {
        message.error(intl.formatMessage({ id: 'page.update.fail', defaultMessage: '更新失败请重试!' }));
        return false;
    } finally {
        hide();
    }
};
const handleRemove = async (rows, intl) => {
    if (!rows) return true;
    const hide = message.loading(intl.formatMessage({ id: 'page.deleting', defaultMessage: '正在删除' }));
    try {
        const resp = await Http.doPost('api/user/remove/' + rows.map((row) => row.id).join(','));
        if (resp.code === 200) {
            message.success(intl.formatMessage({ id: 'page.delete.success', defaultMessage: '删除成功' }));
            return true;
        } else {
            message.error(resp.msg);
            return false;
        }
    } catch (error) {
        message.error(intl.formatMessage({ id: 'page.delete.fail', defaultMessage: '删除失败,请重试!' }));
        return false;
    } finally {
        hide();
    }
};
const handleExport = async (intl) => {
    const hide = message.loading(intl.formatMessage({ id: 'page.exporting', defaultMessage: '正在导出' }));
    try {
        const resp = await Http.doPostBlob('api/user/export');
        const blob = new Blob([resp], { type: 'application/vnd.ms-excel' });
        window.location.href = window.URL.createObjectURL(blob);
        message.success(intl.formatMessage({ id: 'page.export.success', defaultMessage: '导出成功' }));
        return true;
    } catch (error) {
        message.error(intl.formatMessage({ id: 'page.export.fail', defaultMessage: '导出失败,请重试' }));
        return false;
    } finally {
        hide();
    }
};
const handlePwd = async (val, intl) => {
    const hide = message.loading(intl.formatMessage({ id: 'page.resetting', defaultMessage: '正在重置' }));
    try {
        const resp = await Http.doPost('api/user/reset/pwd', val);
        if (resp.code === 200) {
            message.success(intl.formatMessage({ id: 'page.reset.success', defaultMessage: '重置成功' }));
            return true;
        } else {
            message.error(resp.msg);
            return false;
        }
    } catch (error) {
        message.error(intl.formatMessage({ id: 'page.reset.fail', defaultMessage: '重置失败请重试!' }));
        return false;
    } finally {
        hide();
    }
};
const Main = () => {
    const intl = useIntl();
    const formTableRef = useRef();
    const actionRef = useRef();
    const [selectedRows, setSelectedRows] = useState([]);
    const [modalVisible, setModalVisible] = useState(false);
    const [currentRow, setCurrentRow] = useState();
    const [searchParam, setSearchParam] = useState({});
    const [boxHeight, setBoxHeight] = useState();
    const [deptTreeLoading, setDeptTreeLoading] = useState(false);
    const [deptTreeData, setDeptTreeData] = useState([]);
    const [deptExpandedKeys, setDeptExpandedKeys] = useState([]);
    const [pwdModalVisible, setPwdModalVisible] = useState(false);
    const [assignModalVisible, setAssignModalVisible] = useState(false);
    const loadDeptTreeData = (param) => {
        setDeptTreeLoading(true);
        Http.doPostPromise('/api/dept/tree', param, (res) => {
            setDeptTreeLoading(false);
            const rootMenu = { id: 0, name: '全部', value: 0, children: [] };
            rootMenu.children = res.data;
            // const treeData = transformTreeData([rootMenu]);
            const treeData = transformTreeData(res.data);
            setDeptTreeData(treeData);
            const treeAllKeys = getTreeAllKeys(treeData);
            setDeptExpandedKeys(treeAllKeys);
        }).catch((err) => {
            console.error(err);
            setDeptTreeLoading(false);
        })
    }
    useEffect(() => {
        const handleResize = () => setBoxHeight(window.innerHeight - 320);
        window.addEventListener('resize', handleResize);
        handleResize();
        loadDeptTreeData();
        return () => window.removeEventListener('resize', handleResize);
    }, []);
    const columns = [
        {
            title: intl.formatMessage({
                id: 'page.table.no',
                defaultMessage: 'No'
            }),
            dataIndex: 'index',
            valueType: 'indexBorder',
            width: 48,
        },
        {
            title: '部门',
            dataIndex: 'deptId$',
            valueType: 'text',
            hidden: false,
            render: (_, record) => {
                if (_ && _ !== '-') {
                    return <Tag color={""}>{_}</Tag>
                } else {
                    return '-'
                }
            },
            // filterDropdown: (props) => <LinkFilter
            //     name='deptId'
            //     major='dept'
            //     {...props}
            //     actionRef={actionRef}
            //     setSearchParam={setSearchParam}
            // />,
        },
        {
            title: '登录账号',
            dataIndex: 'username',
            valueType: 'text',
            hidden: false,
            copyable: true,
            filterDropdown: (props) => <TextFilter
                name='username'
                {...props}
                actionRef={actionRef}
                setSearchParam={setSearchParam}
            />,
            render: (_, record) => {
                return <span style={{ fontWeight: "bold" }}>{_}</span>
            }
        },
        {
            title: '名称',
            dataIndex: 'nickname',
            valueType: 'text',
            hidden: false,
            filterDropdown: (props) => <TextFilter
                name='nickname'
                {...props}
                actionRef={actionRef}
                setSearchParam={setSearchParam}
            />,
            render: (_, record) => {
                return <span style={{ fontWeight: "bold" }}>{_}</span>
            }
        },
        {
            title: '密码',
            dataIndex: 'password',
            valueType: 'password',
            hidden: false,
            filterDropdown: (props) => <TextFilter
                name='password'
                {...props}
                actionRef={actionRef}
                setSearchParam={setSearchParam}
            />,
        },
        {
            title: '头像',
            dataIndex: 'avatar',
            valueType: 'text',
            hidden: false,
            filterDropdown: (props) => <TextFilter
                name='avatar'
                {...props}
                actionRef={actionRef}
                setSearchParam={setSearchParam}
            />,
        },
        {
            title: '工号',
            dataIndex: 'code',
            valueType: 'text',
            hidden: false,
            filterDropdown: (props) => <TextFilter
                name='code'
                {...props}
                actionRef={actionRef}
                setSearchParam={setSearchParam}
            />,
        },
        {
            title: '性别',
            dataIndex: 'sex$',
            valueType: 'text',
            hidden: false,
            filterDropdown: (props) => <SelectFilter
                name='sex'
                {...props}
                actionRef={actionRef}
                setSearchParam={setSearchParam}
                data={[
                    { label: '未知', value: 0 },
                    { label: '男', value: 1 },
                    { label: '女', value: 2 },
                ]}
            />,
        },
        {
            title: '手机号',
            dataIndex: 'phone',
            valueType: 'text',
            hidden: false,
            filterDropdown: (props) => <TextFilter
                name='phone'
                {...props}
                actionRef={actionRef}
                setSearchParam={setSearchParam}
            />,
        },
        {
            title: '邮箱',
            dataIndex: 'email',
            valueType: 'text',
            hidden: false,
            filterDropdown: (props) => <TextFilter
                name='email'
                {...props}
                actionRef={actionRef}
                setSearchParam={setSearchParam}
            />,
        },
        {
            title: '邮箱验证',
            dataIndex: 'emailVerified$',
            valueType: 'text',
            hidden: false,
            filterDropdown: (props) => <SelectFilter
                name='emailVerified'
                {...props}
                actionRef={actionRef}
                setSearchParam={setSearchParam}
                data={[
                    { label: '否', value: 0 },
                    { label: '是', value: 1 },
                ]}
            />,
        },
        {
            title: '真实姓名',
            dataIndex: 'realName',
            valueType: 'text',
            hidden: false,
            filterDropdown: (props) => <TextFilter
                name='realName'
                {...props}
                actionRef={actionRef}
                setSearchParam={setSearchParam}
            />,
        },
        {
            title: '身份证号',
            dataIndex: 'idCard',
            valueType: 'text',
            hidden: false,
            filterDropdown: (props) => <TextFilter
                name='idCard'
                {...props}
                actionRef={actionRef}
                setSearchParam={setSearchParam}
            />,
        },
        {
            title: '出生日期',
            dataIndex: 'birthday',
            valueType: 'text',
            hidden: false,
            filterDropdown: (props) => <TextFilter
                name='birthday'
                {...props}
                actionRef={actionRef}
                setSearchParam={setSearchParam}
            />,
        },
        {
            title: '个人简介',
            dataIndex: 'introduction',
            valueType: 'text',
            hidden: false,
            filterDropdown: (props) => <TextFilter
                name='introduction'
                {...props}
                actionRef={actionRef}
                setSearchParam={setSearchParam}
            />,
        },
        {
            title: '状态',
            dataIndex: 'status$',
            valueType: 'text',
            hidden: false,
            render: (_, record) => {
                const status = statusMap[record.status]
                return <Tag color={status.color}>{status.text}</Tag>
            },
            filterDropdown: (props) => <SelectFilter
                name='status'
                {...props}
                actionRef={actionRef}
                setSearchParam={setSearchParam}
                data={[
                    { label: '正常', value: 1 },
                    { label: '禁用', value: 0 },
                ]}
            />,
        },
        {
            title: '添加时间',
            dataIndex: 'createTime$',
            valueType: 'text',
            hidden: false,
            filterDropdown: (props) => <DatetimeRangeFilter
                name='createTime'
                {...props}
                actionRef={actionRef}
                setSearchParam={setSearchParam}
            />,
        },
        {
            title: '修改时间',
            dataIndex: 'updateTime$',
            valueType: 'text',
            hidden: false,
            filterDropdown: (props) => <DatetimeRangeFilter
                name='updateTime'
                {...props}
                actionRef={actionRef}
                setSearchParam={setSearchParam}
            />,
        },
        {
            title: '修改人员',
            dataIndex: 'updateBy$',
            valueType: 'text',
            hidden: false,
            filterDropdown: (props) => <LinkFilter
                name='updateBy'
                major='user'
                {...props}
                actionRef={actionRef}
                setSearchParam={setSearchParam}
            />,
        },
        {
            title: '备注',
            dataIndex: 'memo',
            valueType: 'text',
            hidden: false,
            filterDropdown: (props) => <TextFilter
                name='memo'
                {...props}
                actionRef={actionRef}
                setSearchParam={setSearchParam}
            />,
        },
        {
            title: '操作',
            dataIndex: 'option',
            valueType: 'option',
            width: 180,
            render: (_, record) => [
                <Button
                    type="link"
                    key="edit"
                    style={{ padding: '2px 3px' }}
                    onClick={() => {
                        setModalVisible(true);
                        setCurrentRow(record);
                    }}
                >
                    <FormattedMessage id='page.edit' defaultMessage='编辑' />
                </Button>,
                <Button
                    type="link"
                    key="pwd"
                    style={{ padding: '2px 2px' }}
                    onClick={() => {
                        setPwdModalVisible(true);
                        setCurrentRow(record);
                    }}
                >
                    <FormattedMessage id='page.reset.pwd' defaultMessage='重置密码' />
                </Button>,
                <Button
                    type="link"
                    danger
                    style={{ padding: '4px' }}
                    key="remove"
                    onClick={async () => {
                        Modal.confirm({
                            title: intl.formatMessage({ id: 'page.delete', defaultMessage: '删除' }),
                            content: intl.formatMessage({ id: 'page.delete.confirm', defaultMessage: '确定删除该项吗?' }),
                            onOk: async () => {
                                const success = await handleRemove([record], intl);
                                if (success) {
                                    if (actionRef.current) {
                                        actionRef.current.reload();
                                    }
                                }
                            },
                        });
                    }}
                >
                    <FormattedMessage id='page.delete' defaultMessage='删除' />
                </Button>,
                <TableDropdown
                    key="actionGroup"
                    name="dropdown"
                    onSelect={(key) => {
                        if (key === 'assign') {
                            setAssignModalVisible(true);
                            setCurrentRow(record);
                        }
                    }}
                    menus={[
                        { key: 'assign', name: intl.formatMessage({ id: 'page.assign.role', defaultMessage: '分配角色' }) },
                    ]}
                />,
            ],
        },
    ];
    return (
        <PageContainer
            header={{
                breadcrumb: {},
            }}
        >
            <Row gutter={[16, 24]}>
                <Col lg={6} md={24}>
                    <Card
                        title={intl.formatMessage({ id: 'system.dept', defaultMessage: '部门' })}
                        style={{ width: '100%', height: 'calc(100vh - 160px)' }}
                    >
                        <Input
                            style={{ marginBottom: 10 }}
                            placeholder={intl.formatMessage({ id: 'commont.enter', defaultMessage: '请输入' })}
                            onChange={(e) => {
                                const { value } = e.target;
                                loadDeptTreeData({
                                    condition: value
                                })
                            }}
                        />
                        <div style={{ height: 'calc(100vh - 325px)', overflowY: 'auto' }}>
                            {deptTreeLoading ? (
                                <Skeleton active />
                            ) : (
                                <Tree
                                    showLine
                                    blockNode
                                    defaultExpandAll    // 异步加载失效
                                    expandedKeys={deptExpandedKeys}
                                    onExpand={setDeptExpandedKeys}
                                    treeData={deptTreeData}
                                    switcherIcon={<DownOutlined />}
                                    onSelect={(selectedKeys, info) => {
                                        const deptId = selectedKeys[0];
                                        setSearchParam(prevState => ({
                                            ...prevState,
                                            deptId: deptId
                                        }));
                                        actionRef.current?.reload();
                                    }}
                                />
                            )}
                        </div>
                    </Card>
                </Col>
                <Col lg={18} md={24}>
                    <ProTable
                        key="user"
                        rowKey="id"
                        actionRef={actionRef}
                        formRef={formTableRef}
                        columns={columns}
                        cardBordered
                        size='small'
                        // scroll={{ y: boxHeight }}
                        dateFormatter="string"
                        pagination={{ pageSize: 12 }}
                        search={false}
                        toolbar={{
                            search: {
                                onSearch: (value) => {
                                    setSearchParam(prevState => ({
                                        ...prevState,
                                        condition: value
                                    }));
                                    actionRef.current?.reload();
                                },
                            },
                            filter: (
                                <LightFilter
                                    onValuesChange={(val) => {
                                    }}
                                >
                                </LightFilter>
                            ),
                            actions: [
                                <Button
                                    type="primary"
                                    danger
                                    key="removeBatch"
                                    hidden={selectedRows?.length === 0}
                                    onClick={async () => {
                                        Modal.confirm({
                                            title: intl.formatMessage({ id: 'page.delete', defaultMessage: '删除' }),
                                            content: intl.formatMessage({ id: 'page.delete.confirm', defaultMessage: '确定删除该项吗?' }),
                                            icon: <ExclamationCircleOutlined />,
                                            async onOk() {
                                                const success = await handleRemove(selectedRows, intl);
                                                if (success) {
                                                    setSelectedRows([]);
                                                    actionRef.current.reload();
                                                }
                                            },
                                            onCancel() { },
                                        });
                                    }}
                                >
                                    <DeleteOutlined />
                                    <FormattedMessage id='page.delete' defaultMessage='删除' />
                                </Button>,
                                <Button
                                    type="primary"
                                    key="save"
                                    onClick={async () => {
                                        setModalVisible(true)
                                    }}
                                >
                                    <PlusOutlined />
                                    <FormattedMessage id='page.add' defaultMessage='添加' />
                                </Button>,
                                <Button
                                    key="export"
                                    onClick={async () => {
                                        handleExport(intl);
                                    }}
                                >
                                    <ExportOutlined />
                                    <FormattedMessage id='page.export' defaultMessage='导出' />
                                </Button>,
                            ],
                        }}
                        request={(params, sorter, filter) =>
                            Http.doPostPromise('/api/user/page1', { ...params, ...searchParam }, (res) => {
                                return {
                                    data: res.data.records,
                                    total: res.data.total,
                                    success: true,
                                }
                            })
                        }
                        tableAlertRender={false}
                        rowSelection={{
                            onChange: (ids, rows) => {
                                setSelectedRows(rows);
                            }
                        }}
                        columnsState={{
                            persistenceKey: TABLE_KEY,
                            persistenceType: 'localStorage',
                            defaultValue: {
                                password: { show: repairBug(TABLE_KEY, 'password', false) },
                                avatar: { show: repairBug(TABLE_KEY, 'avatar', false) },
                                code: { show: repairBug(TABLE_KEY, 'code', false) },
                                phone: { show: repairBug(TABLE_KEY, 'phone', false) },
                                email: { show: repairBug(TABLE_KEY, 'email', false) },
                                emailVerified$: { show: repairBug(TABLE_KEY, 'emailVerified$', false) },
                                realName: { show: repairBug(TABLE_KEY, 'realName', false) },
                                idCard: { show: repairBug(TABLE_KEY, 'idCard', false) },
                                birthday: { show: repairBug(TABLE_KEY, 'birthday', false) },
                                introduction: { show: repairBug(TABLE_KEY, 'introduction', false) },
                                createTime$: { show: repairBug(TABLE_KEY, 'createTime$', false) },
                                updateTime$: { show: repairBug(TABLE_KEY, 'updateTime$', false) },
                                updateBy$: { show: repairBug(TABLE_KEY, 'updateBy$', false) },
                                memo: { show: repairBug(TABLE_KEY, 'memo', false) },
                                option: { fixed: 'right', disable: true },
                            },
                            onChange(value) {
                            },
                        }}
                    />
                </Col>
            </Row>
            <Edit
                open={modalVisible}
                values={currentRow || {}}
                treeData={deptTreeData}
                onCancel={
                    () => {
                        setModalVisible(false);
                        setCurrentRow(undefined);
                    }
                }
                onSubmit={async (values) => {
                    let ok = false;
                    if (values.id) {
                        ok = await handleUpdate({ ...values }, intl)
                    } else {
                        ok = await handleSave({ ...values }, intl)
                    }
                    if (ok) {
                        setModalVisible(false);
                        setCurrentRow(undefined);
                        if (actionRef.current) {
                            actionRef.current.reload();
                        }
                    }
                }
                }
            />
            <Pwd
                open={pwdModalVisible}
                values={currentRow || {}}
                onCancel={
                    () => {
                        setPwdModalVisible(false);
                        setCurrentRow(undefined);
                    }
                }
                onSubmit={async (values) => {
                    let ok = false;
                    if (values.id) {
                        ok = await handlePwd({ ...values }, intl)
                    }
                    if (ok) {
                        setPwdModalVisible(false);
                        setCurrentRow(undefined);
                        if (actionRef.current) {
                            actionRef.current.reload();
                        }
                    }
                }
                }
            />
            <AssignRole
                open={assignModalVisible}
                values={currentRow || {}}
                onCancel={
                    () => {
                        setAssignModalVisible(false);
                        setCurrentRow(undefined);
                    }
                }
                onSubmit={async (values) => {
                    let ok = false;
                    if (values.id) {
                        ok = await handleUpdate({ ...values }, intl)
                    }
                    if (ok) {
                        setAssignModalVisible(false);
                        setCurrentRow(undefined);
                        if (actionRef.current) {
                            actionRef.current.reload();
                        }
                    }
                }}
            />
        </PageContainer>
    );
};
export default Main;