dialog.tsx 9.43 KB
import * as React from 'react';
import { useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react';
import type { SearchUserData } from './service';
import { Col, Modal, Row, Tabs, Tag, Tooltip } from 'antd';
import { InfoCircleOutlined, UserOutlined } from '@ant-design/icons';
import OrgCore from '../../qx-org-selector/src/core';
import PosCore from '../../qx-pos-selector/src/core';
import GroupCore from '../../qx-group-selector/src/core';
import Role from './components/role';
import UserList from './components/user-list';

export type UserItem = { id: string; name: string; code?: string; relName?: string };

type UserSelectorDialogProps = {
  appId?: string; //如果按角色查人,必须有appId
  title?: string;
  visible: boolean;
  onCancel: () => void;
  multiple?: boolean; //默认不是多选
  max?: number;
  onOk: (selectedKeys: string[], selectedData: UserItem[]) => void;
  selectedData?: UserItem[]; //已选人员数据
  params?: { org: any; pos: any; user: any; range: string[] } | null; //请求body参数
  showRole?: boolean; //是否按角色筛选
  request: any;
  dRef?: any;
  modalClassName?: string | undefined; // 弹框类名自定义 用于自定义以及覆盖样式
};
const SELECTOR_TABS = {
  ORG: '按部门',
  POSITION: '按岗位',
  GROUP: '按群组',
  ROLE: '按角色',
};

const UserSelectorDialog: React.FC<UserSelectorDialogProps> = (props) => {
  const [currentTab, setCurrentTab] = useState(props?.params?.range ? '' : 'ORG');
  const [range, setRange] = useState({ org: true, pos: true, group: !props?.params?.range });

  const pageParamRef = useRef({
    pageNum: 1,
    relType: 'ORG',
    relId: null,
  });

  const userListRef = useRef({
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    searchUser: (data: SearchUserData) => {},
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    remove: (index: number, id: string) => {},
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    setSelected: (ids: string[], data?: UserItem[]) => {},
    focusSearch: () => {},
  });

  const [selectUsers, setSelectUsers] = useState<UserItem[]>([]);
  const [selectIds, setSelectIds] = useState<string[]>([]);

  useEffect(() => {
    if (props?.params?.range && props?.params?.range?.length > 0) {
      let hasOrg = false;
      let hasPos = false;
      if (props?.params?.org) {
        hasOrg = true;
      }
      if (props?.params?.pos) {
        hasPos = true;
      }

      if (!hasOrg && hasPos) {
        setCurrentTab('POSITION');
      } else {
        setCurrentTab('ORG');
      }

      setRange({ org: hasOrg, pos: hasPos, group: false });
    }
  }, [props?.params]);

  // useEffect(() => {
  //   if (props.selectedData) {
  //     const selectedData = [...props.selectedData];
  //     const keys: string[] = [];
  //     selectedData?.forEach((item) => {
  //       keys.push(item.id);
  //     });
  //     setSelectIds(keys);
  //     setSelectUsers(selectedData);

  //     userListRef.current.setSelected(keys, selectedData);
  //   }
  // }, [props.selectedData]);

  useEffect(() => {
    if (props.visible) {
      const selectedData = Array.isArray(props.selectedData) ? [...props.selectedData] : [];
      const keys: string[] = [];
      selectedData?.forEach((item) => {
        keys.push(item.id);
      });
      setSelectIds(keys);
      setSelectUsers(selectedData);
      userListRef.current.setSelected(keys, selectedData);
      userListRef.current.focusSearch();
    }
  }, [props.visible]);

  const getUserData = (params: any) => {
    const _param = { ...pageParamRef.current, ...params };
    pageParamRef.current = _param;
    userListRef.current.searchUser(_param);
  };

  const handleOk = () => {
    props.onOk(selectIds, selectUsers);
  };
  const handleCancel = () => {
    props.onCancel();
  };

  const changeTabs = (activeKey: string | string[]) => {
    if (typeof activeKey !== 'string') {
      return;
    }
    setCurrentTab(activeKey);
  };

  const handleSelectOrg = (keys: string[], selectedData: any[], include?: boolean) => {
    getUserData({
      pageNum: 1,
      includeChild: !!include,
      relType: 'ORG',
      relId: keys[0] + '',
    });
  };

  const handleSelectPos = (keys: string[]) => {
    getUserData({
      pageNum: 1,
      relType: 'POSITION',
      relId: keys[0] + '',
    });
  };

  const handleSelectRole = (selectedKeys: string[]) => {
    // const selectKey = selectedKeys[0];
    // const keyArr = selectKey.split(':');
    getUserData({
      pageNum: 1,
      relType: 'ROLE',
      relId: selectedKeys[0],
    });
  };

  const handleSelectGroup = (selectedKeys: string[]) => {
    getUserData({
      pageNum: 1,
      relType: 'GROUP',
      relId: selectedKeys[0],
    });
  };

  const removeUser = (index: number) => {
    const _selectUsersKey = [...selectIds];
    const _selectUsers = [...selectUsers];
    const key = _selectUsersKey.splice(index, 1);
    _selectUsers.splice(index, 1);
    setSelectIds(_selectUsersKey);
    setSelectUsers(_selectUsers);

    userListRef.current.remove(index, key[0]);
  };

  const dialogTitle = useMemo(() => {
    return (
      <div
        style={{
          display: 'flex',
          alignItems: 'center',
          justifyContent: 'space-between',
          marginRight: '34px',
        }}
      >
        <div>
          <UserOutlined /> {props.title || '选择人员'}
        </div>
        <Tooltip
          placement="top"
          title={
            <div style={{
              fontSize: 14,
              fontWeight: 400,
            }}>
              搜索规则
              <br />
              1、在按部门状态下,搜索的是人员的:姓名,工号或岗位 <br />
              2、在按岗位的状态,搜索的是人员的姓名,工号和部门名称
              <br />
              {props.showRole ? (
                <>
                  3、按角色的状态下搜索的是人员的名称,工号和岗位名称,部门名称
                  <br />
                </>
              ) : null}
            </div>
          }
          getPopupContainer={(triggerNode) => triggerNode}
        >
          <InfoCircleOutlined />
        </Tooltip>
      </div>
    );
  }, [props.title, props.showRole]);

  const onSelectUser = (keys: string[], data: UserItem[]) => {
    setSelectIds(keys);
    setSelectUsers(data);
  };

  useImperativeHandle(props.dRef, () => ({
    onSelectUser,
  }));

  return props.visible ? (
    <Modal
      title={dialogTitle}
      width={700}
      open={props.visible}
      className={'qx-user-selector__dialog'}
      onOk={handleOk}
      onCancel={handleCancel}
      wrapClassName={props?.modalClassName || ''}
    >
      <div className={'qx-user-selected__temp'}>
        {selectUsers
          ? selectUsers.map((user: UserItem, index: number) => {
              if (!user.name) {
                return null;
              }
              return (
                <Tag color="blue" key={user.id} closable onClose={() => removeUser(index)}>
                  {user.name}
                </Tag>
              );
            })
          : null}
      </div>
      <div className={'qx-selector-tab'} style={{ position: 'relative' }}>
        <Tabs activeKey={currentTab} centered onChange={changeTabs}>
          {Object.keys(SELECTOR_TABS).map((key) => {
            if (key === 'ORG' && !range.org) {
              console.log();
              return null;
            }
            if (key === 'POSITION' && !range.pos) {
              return null;
            }
            if (key === 'GROUP' && !range.group) {
              return null;
            }
            if (key === 'ROLE' && (typeof props.showRole === 'undefined' || !props.showRole)) {
              return null;
            }
            return <Tabs.TabPane tab={SELECTOR_TABS[key]} key={key} />;
          })}
        </Tabs>
      </div>
      <Row className={'qx-user-selector__content'}>
        <Col span={10} className="qx-user-selector__left">
          {currentTab === 'ORG' && props.visible && range.org ? (
            <OrgCore
              request={props.request}
              selectFirstNode
              hasInclude={true}
              params={props.params && props.params.org}
              onSelect={handleSelectOrg}
            />
          ) : null}
          {currentTab === 'POSITION' && props.visible ? (
            <PosCore
              request={props.request}
              params={props.params && props.params.pos}
              onSelect={handleSelectPos}
            />
          ) : null}
          {currentTab === 'ROLE' && props.visible && range.group ? (
            <Role
              request={props.request}
              params={{ appId: props.appId || '' }}
              onSelect={handleSelectRole}
            />
          ) : null}
          {currentTab === 'GROUP' && props.visible ? (
            // <Role
            //   request={props.request}
            //   params={{ appId: props.appId || '' }}
            //   onSelect={handleSelectRole}
            // />
            <GroupCore
              request={props.request}
              params={{ appId: props.appId || '' }}
              onSelect={handleSelectGroup}
            />
          ) : null}
        </Col>
        <Col span={14} className="qx-user-selector__right">
          <UserList
            request={props.request}
            cRef={userListRef}
            onSelect={onSelectUser}
            max={props.max}
          />
        </Col>
      </Row>
    </Modal>
  ) : null;
};

export default UserSelectorDialog;