美文网首页
react+antd4实现一个树级搜索选择框

react+antd4实现一个树级搜索选择框

作者: 甘道夫老矣 | 来源:发表于2023-04-18 09:48 被阅读0次
image.png
import React from "react";
import { remote } from "electron";
import moment from "moment";
import { getUrlProps } from "../service/main";
import { Route, Switch } from "react-router-dom";
import { Tree, Card, notification, Col, Row, Button, Input, Divider, Popconfirm, Form, message, Modal, Avatar, Drawer, Descriptions, Empty, Table, Tooltip } from "antd";
import { GlobalOutlined, PlusSquareOutlined, EditTwoTone, PlusOutlined } from "@ant-design/icons";
import BaseComponent from "../components/base.component";
import { SplitPane } from "react-collapse-pane";
import AppContext from "../components/context";
import * as service from "../service/organizational.structure";
import routers from "../routers";
const { Search } = Input;
const { TreeNode } = Tree;

const getParentKey = (key, tree) => {
    let parentKey;
    for (let i = 0; i < tree.length; i++) {
        const node = tree[i];
        if (node.children) {
            if (node.children.some(item => item.key === key)) {
                parentKey = node.key;
            } else if (getParentKey(key, node.children)) {
                parentKey = getParentKey(key, node.children);
            }
        }
    }
    return parentKey;
};

export default class OrganizationalStructure extends BaseComponent {
    formRefSearch = React.createRef();
    constructor(props) {
        super(props);
        this.state = {
            userUUid: remote.getGlobal("userInfo").uuid,
            drawerVisible: false,
            hasChild: false,
            drawerTitle: "编辑",
            drawerPlacement: "right",
            loading: false,
            organizations: [],
            record: [],

            treeAllData: [],
            treeData: [], //部门树,
            expandedKeys: [], //展开指定的树
            autoExpandParent: true,
            nowDepartment: null, //当前选中的部门
            defaultSelectedKeys: [],
            searchValue: [],
            personsTableData: [],
        };
    }

    static contextType = AppContext;

    async componentDidMount() {
        // let search = window.location.search.split('?')[1];
        // let oiUuid = search.split('=')[1];
        this.setState({ oiUuid: getUrlProps().orgUuid });

        this.getAllData(getUrlProps().orgUuid);
        this.getTableData();
    }

    getAllData = async (oiUuid) => {
        this.setState({ loading: true });
        let res = await service.allOrganizationInformations(oiUuid);
        // console.log(res);
        if (res.statusCode !== 0) {
            this.setState({ loading: false });
            return notification["error"]({
                message: "获取组织数据时发生错误",
                description: res.message + ": " + (Array.isArray(res.result) ? res.result.join(", ") : res.result)
            });
        }
        if (res.result.nodes.length > 0) {
            this.setState({ organizations: res.result.nodes[0] });
        } else {
            this.setState({ organizations: [] });
        }
        this.setState({ loading: false });
    };

    //加载组织架构
    getTableData = async () => {
        let res = await service.getAllStructures();
        if (res.statusCode !== 0) return message.warn(res.message);
        //console.log(res.result.nodes);
        let arr = this.transformTree(res.result.nodes);
        //console.log(arr);
        this.setState({
            treeData: arr,
            treeAllData: res.result.nodes,
            nowDepartment: null,
            personsTableData: [],
            defaultSelectedKeys: [],
        });
    };

    transformTree = (list) => {
        let tree = [];
        for (let i = 0, len = list.length; i < len; i++) {
            if (!list[i].osPaid) {
                let item = this.queryChildren(list[i], list);
                item.title = item.osName;
                item.key = item.osSeno;
                tree.push(item);
            }
        }
        return tree;
    };

    queryChildren = (parent, list) => {
        let children = [];
        for (let i = 0, len = list.length; i < len; i++) {
            if (list[i].osPaid === parent.osSeno) {
                let item = this.queryChildren(list[i], list);
                item.title = item.osName;
                item.key = item.osSeno;
                children.push(item);
            }
        }
        if (children.length) {
            parent.children = children;
        }
        return parent;
    };

    //添加新的组织
    addDepartment = () => {
        const { history } = this.props;
        this.setState({
            drawerVisible: true,
            hasChild: true,
            drawerTitle: "添加职能部门",
        });
        history.replace({
            pathname: "/organizational_structure/add_next",
        });
    };


    //搜索检索
    onChange = (e) => {
        const { value } = e.target;

        const { treeAllData, treeData } = this.state;

        const expandedKeys = treeAllData
            .map((item) => {
                if (item.title.indexOf(value) > -1) {
                    return getParentKey(item.key, treeData);
                }
                return null;
            })
            .filter((item, i, self) => item && self.indexOf(item) === i);
        // console.log(value);
        // console.log(expandedKeys);
        this.setState({
            expandedKeys,
            searchValue: value,
            autoExpandParent: true,
        });
    };

    //节点展开
    onExpand = (expandedKeys, info) => {
        // console.log(info);
        this.setState({
            expandedKeys,
            autoExpandParent: false,
        });
    };

    //点击树节点触发
    onSelect = (selectedKeys, info) => {
        if (selectedKeys.length === 0) {
            this.setState({
                nowDepartment: null,
                personsTableData: [],
            });
        } else {
            this.setState({
                nowDepartment: info.node.dataRef,
                defaultSelectedKeys: selectedKeys,
            });
            this.getPersonsData(Number(selectedKeys[0]));
        }
    };

    //加载treedome树
    loop = (data) =>
        data.map((item) => {
            let { searchValue } = this.state;
            const index = item.title.indexOf(searchValue);
            const beforeStr = item.title.substr(0, index);
            const afterStr = item.title.substr(index + searchValue.length);
            const title =
                index > -1 ? (
                    <span>
                        {beforeStr}
                        <span style={{ color: "#f50" }}>{searchValue}</span>
                        {afterStr}
                    </span>
                ) : (
                        <span>{item.title}</span>
                    );
            if (item.children) {
                return { dataRef: item, title, key: item.key, children: this.loop(item.children) };
            }
            return {
                dataRef: item,
                title,
                key: item.key,
            };
        });

    //调用获取人员
    getPersonsData = async (osSeno) => {
        this.setState({
            loading: true,
        });

        let res = await service.getUserDataByOsSeno(osSeno);

        this.setState({
            loading: false,
        });
        if (res.statusCode !== 0) return message.warn(res.message);
        this.setState({
            personsTableData: res.result.nodes,
        });
    };

    //删除员工
    handleDeletePersons = async (record) => {
        let res = await service.deletePersons(record.osEmid, record.osSeno);
        if (res.statusCode !== 0) {
            return message.error("移除人员失败!" + res.message);
        }
        message.success("删除人员成功!");
        this.getPersonsData(record.osSeno);
    };

    //删除部门信息
    handleDeleteDepartment = async () => {
        const { nowDepartment } = this.state;
        // console.log(nowDepartment)
        let res = await service.deleteStructure(nowDepartment.osSeno);
        //console.log(res)
        if (res.statusCode !== 0) {
            return message.error("删除机构信息失败!" + res.message);
        }
        message.success("删除机构信息成功!");
        this.getTableData();
    };

    //编辑部门信息
    handleEdit = () => {
        const { nowDepartment } = this.state;
        const { history } = this.props;
        this.setState({
            drawerVisible: true,
            hasChild: true,
            drawerTitle: "编辑职能部门信息",
        });
        // console.log(nowDepartment);
        history.replace({
            pathname: "/organizational_structure/edit_department",
            state: {
                record: nowDepartment,
            },
        });
    };

    //编辑人员信息
    handleMan = () => {
        const { personsTableData, nowDepartment } = this.state;
        const { history } = this.props;
        this.setState({
            drawerVisible: true,
            hasChild: true,
            drawerTitle: "添加部门人员",
        });

        history.replace({
            pathname: "/organizational_structure/add_persons",
            state: {
                record: nowDepartment,
                personsTableData: personsTableData,
            },
        });
    };

    //添加下级
    addNext = () => {
        const { nowDepartment } = this.state;
        const { history } = this.props;
        this.setState({
            drawerVisible: true,
            hasChild: true,
            drawerTitle: "添加下级机构",
        });
        history.replace({
            pathname: "/organizational_structure/add_next",
            state: {
                record: nowDepartment,
            },
        });
    };

    render() {
        const { ipfsUrl } = this.context;
        const { loading, organizations, autoExpandParent, expandedKeys, defaultSelectedKeys, treeData, nowDepartment, personsTableData } = this.state;
        const columns = [
            {
                title: "员工姓名",
                dataIndex: "omName",
                key: "omName",
                align: "center",
                render: (text) => {
                    return text.omName;
                },
            },
            {
                title: "操作",
                dataIndex: "caozuo",
                key: "caozuo",
                align: "center",
                render: (text, record) => {
                    return (
                        <Popconfirm
                            title="您要移除该人员吗?"
                            onConfirm={() => {
                                this.handleDeletePersons(record);
                            }}
                        >
                            <a>删除</a>
                        </Popconfirm>
                    );
                },
            },
        ];
        return (
            <div className="desc-info" style={{ position: "relative", overflowX: "hidden", overflowY: "auto", height: "100%" }}>
                <Card title="组织信息" size="small" bordered={false}>
                    {Object.keys(organizations).length > 0 && (
                        <Card
                            size="small"
                            style={{ marginTop: 1 }}
                            title={
                                <span>
                                    <Avatar shape="square" size="large" src={organizations.oiOrlo ? ipfsUrl + organizations.oiOrlo : null} icon={<GlobalOutlined />} style={{ marginLeft: 18 }} />
                                    <Descriptions size="small" bordered={false} column={{ xxl: 2, xl: 2, lg: 2, md: 2, sm: 2, xs: 2 }} style={{ padding: 16, marginTop: 1 }}>
                                        <Descriptions.Item label="组织全称">{organizations.oiOrna}</Descriptions.Item>
                                        <Descriptions.Item label="组织简称">{organizations.oiOrab}</Descriptions.Item>
                                        <Descriptions.Item label="组织网址">{organizations.oiOwad}</Descriptions.Item>
                                        <Descriptions.Item label="组织地址">{organizations.oiOtad}</Descriptions.Item>
                                        <Descriptions.Item label="上级组织">{organizations.oiSuna}</Descriptions.Item>
                                    </Descriptions>
                                </span>
                            }
                            bordered={false}
                            hoverable={false}
                            extra={
                                <span>
                                    <a
                                        title="编辑组织信息"
                                        onClick={e => {
                                            this.setState({ drawerPlacement: "right", drawerTitle: "编辑组织信息" });
                                            this.props.history.replace({
                                                pathname: '/organizational_structure/edite',
                                                state: { record: organizations }
                                            });
                                            this.showDrawer();
                                        }}
                                    >
                                        <EditTwoTone twoToneColor="#52c41a" /> 编辑
                                </a>
                                </span>
                            }
                        >
                        </Card>
                    )}
                </Card>

                <Row span={24} style={{ marginLeft: 10 }}>
                    <Col span={6} style={{ borderRight: "1px solid #e8e8e8", height: "78vh", overflowY: "scroll", paddingRight: 10 }}>
                        <Row span={24} >
                            <Col span={24} style={{ marginBottom: 8, textAlign: "center" }} >
                                <div>
                                    <Search style={{ width: "82%", float: "left" }} placeholder="查询部门" onChange={this.onChange} />
                                </div>
                                <Tooltip title="添加职能部门">  <Button type="primary" style={{ height: 30.5, float: "right" }} onClick={this.addDepartment} icon={<PlusOutlined style={{ fontSize: 20 }} />}></Button></Tooltip>
                            </Col>
                            <Col span={24}>
                                {treeData ? (
                                    <Tree
                                        autoExpandParent
                                        autoExpandParent={autoExpandParent}
                                        onSelect={this.onSelect}
                                        expandedKeys={expandedKeys}
                                        defaultSelectedKeys={defaultSelectedKeys}
                                        onExpand={this.onExpand}
                                        treeData={this.loop(treeData)}
                                    />
                                ) : (
                                        <div
                                            style={{
                                                width: "300px",
                                                height: "300px",
                                                margin: "50px auto",
                                                // paddingTop: 50,
                                                textAlign: "center",
                                            }}
                                        >
                                            <Spin size="large" />
                                        </div>
                                    )}
                            </Col>
                        </Row>


                    </Col>
                    <Col span={18} style={{ paddingLeft: 10 }}>
                        <Card
                            title="当前部门信息"
                            size="small"
                            extra={
                                nowDepartment ? (
                                    <span>
                                        <a onClick={this.handleEdit}>编辑</a>
                                        <Divider type="vertical" />
                                        <a onClick={this.handleMan}>添加部门人员</a>
                                        <Divider type="vertical" />
                                        <a onClick={this.addNext}>添加下级</a>
                                        <Divider type="vertical" />
                                        <Popconfirm
                                            title="您要删除该机构信息吗?"
                                            onConfirm={() => {
                                                this.handleDeleteDepartment();
                                            }}
                                        >
                                            <a>删除</a>
                                        </Popconfirm>
                                    </span>
                                ) : null
                            }
                        >
                            {nowDepartment ? (
                                <Descriptions>
                                    <Descriptions.Item label="启用状态">{nowDepartment.osIsus ? "启用" : "未启用"}</Descriptions.Item>
                                    <Descriptions.Item label="说明">{nowDepartment.osRema && nowDepartment.osRema}</Descriptions.Item>
                                </Descriptions>
                            ) : (
                                    <Empty description="请先选择部门" />
                                )}
                        </Card>
                        {/* 人员信息 */}
                        <Table
                            style={{ marginTop: 20 }}
                            bordered
                            title={() => "当前部门人员信息"}
                            loading={loading}
                            size="middle"
                            pagination={false}
                            columns={columns}
                            rowKey={(record) => record.osSeno + record.osEmid + record.osPoid}
                            dataSource={personsTableData}
                        />
                    </Col>
                </Row>
                {/*右部弹出栏*/}
                {
                    this.state.record &&
                    <Drawer
                        title={this.state.drawerTitle}
                        placement="right"
                        visible={this.state.drawerVisible}
                        width={700}
                        onClose={this.handleDrawerClose}
                    >
                        <Switch>
                            {routers.OrganizationalStructureDrawer.menuItems.map((item, index) => {
                                if (item.path && item.page) {
                                    let RouterPage = require(`../pages/${item.page}`).default;
                                    return (
                                        <Route key={index} path={item.path} render={() =>
                                            this.state.hasChild && <RouterPage closeFun={this.handleDrawerClose}  {...this.props} />}
                                        />
                                    );
                                }
                            })}
                        </Switch>
                    </Drawer>
                }
            </div>
        );
    }
    Refresh = () => {
        this.componentDidMount()
    }

    //打开drawer
    showDrawer = () => {
        this.setState({ drawerVisible: true, hasChild: true });
    };

    //弹出框的关闭
    handleDrawerClose = async (value, prames) => {
        if (value === 1) {
            this.getPersonsData(prames);
        }
        if (value === 2) {
            this.getTableData();
        }
        if (value === 3) {
            let res = await service.getAllStructures();
            if (res.statusCode !== 0) return message.warn(res.message);
            let arr = this.transformTree(res.result.nodes);
            //console.log(arr);

            let obj = {};
            res.result.nodes.forEach((item) => {
                if (item.osSeno === prames) {
                    obj = item;
                }
            });
            //console.log(obj);
            this.setState({
                treeData: arr,
                nowDepartment: obj,
            });
        }
        if (value === 4) {
            this.componentDidMount()
        }
        this.setState({
            drawerVisible: false,
            record: [],
            hasChild: false
        });
    };
}

相关文章

网友评论

      本文标题:react+antd4实现一个树级搜索选择框

      本文链接:https://www.haomeiwen.com/subject/rztcwltx.html