index.tsx 4.91 KB
/*
 * @Author: wangqiang@feewee.cn
 * @Date: 2022-05-25 09:14:31
 * @LastEditors: wangqiang@feewee.cn
 * @LastEditTime: 2022-10-08 16:36:39
 */
import useInitial from "@/hooks/useInitail";
import { Tag } from "antd";
import React, {
  forwardRef,
  Ref,
  useCallback,
  useEffect,
  useImperativeHandle,
  useState,
} from "react";
import {
  Value,
  getShopListChooseOptionsApi,
  getShopListApi,
  ShopSelectNewOptions,
} from "./api";
import Close from "./components/Close";
import ShopModal from "./components/ShopModal";
import "./style.less";

interface Props {
  style?: React.CSSProperties;
  value?: Value[];
  onChange?: Function;
  multiple?: boolean;
  disabled?: boolean;
  placeholder?: string;
  type?: 1 | 2; // 1 集团维度 2 自定义门店维度
  shopIds?: number[]; // 仅查询门店ID列表,与 type = 2 时搭配使用
  /**
   * 默认筛选参数,下拉框中不可删除;
   * 用于特殊业务,例如 售前CRM-零售任务 选择门店时,需要默认查询 新车销售 的门店信息,则传入 
      defaultOptions={{
        bizTypes: "1",
      }}
   */
  defaultOptions?: ShopSelectNewOptions;
}

export interface ShopSelectNewRef {
  reset: () => void;
}

export default forwardRef(ShopSelectNew);

function ShopSelectNew(
  {
    style,
    value = [],
    onChange,
    multiple = false,
    placeholder = "请选择门店",
    type = 1,
    disabled = false,
    shopIds,
    defaultOptions = {},
  }: Props,
  ref: Ref<ShopSelectNewRef>
) {
  const [visible, setVisible] = useState(false);
  const [delay, setDelay] = useState(type === 2);
  const optionInitial = useInitial(
    getShopListChooseOptionsApi,
    {},
    { type },
    delay
  );
  const listInitial = useInitial(
    getShopListApi,
    [],
    {
      type,
      ...defaultOptions,
    },
    delay
  );
  const [selected, setSelected] = useState<Value[]>([]);
  const [tableType, setTableType] = useState<"列表" | "选择">("列表");
  const [checkInfo, setCheckInfo] = useState({
    indeterminate: false,
    checkAll: false,
  }); // 全选按钮的信息,indeterminate 半选中状态,checkAll 全选状态

  useEffect(() => {
    if (visible) {
      setTableType("列表");
      delay && setDelay(false);
      const params: any = { type };
      if (type === 2 && shopIds?.length) {
        params.shops = shopIds.join(",");
      }
      optionInitial.setParams(params, true);
      listInitial.setParams(params, true);
    }
  }, [visible, delay, shopIds]);

  useEffect(() => {
    setCheckInfo({
      indeterminate:
        selected.length > 0 && listInitial.data.length !== selected.length,
      checkAll:
        selected.length > 0 && listInitial.data.length === selected.length,
    });
  }, [selected, listInitial.data]);

  useImperativeHandle(ref, () => ({
    reset: () => {
      setSelected([]);
      setCheckInfo({
        indeterminate: false,
        checkAll: false,
      });
    },
  }));

  const del = (item: Value) => {
    onChange && onChange(value.filter((i) => i.value !== item.value));
  };

  const deleteAll = () => {
    setSelected([]);
    onChange && onChange([]);
  };

  const openModal = useCallback(() => {
    if (value.length > 0) {
      // 为了使查看当前项展示完整表格数据,需要将selected处理
      const ids = value.map((v) => v.value);
      setSelected(
        listInitial.data
          .filter((item) => ids.includes(item.shopId))
          .map((item) => ({
            ...item,
            value: item.shopId,
            label: item.shopShortName,
          }))
      );
    }
    setVisible(true);
  }, [value, listInitial.data]);

  return (
    <div style={style}>
      <span
        className="ant-input-affix-wrapper"
        onClick={disabled ? undefined : openModal}
      >
        <div className="ShopSelectNew_Container">
          {value?.length ? (
            multiple ? (
              value.map((item) => (
                <Tag
                  className="tag"
                  closable={!disabled}
                  key={item.value}
                  onClose={() => del(item)}
                >
                  {item.label}
                </Tag>
              ))
            ) : (
              // @ts-ignore
              <span>{value[0].label || "-"}</span>
            )
          ) : (
            <span className="placeholder">{placeholder}</span>
          )}
        </div>
        {!disabled && value?.length ? <Close deleteAll={deleteAll} /> : null}
      </span>
      {disabled ? null : (
        <ShopModal
          onChange={onChange}
          type={type}
          multiple={multiple}
          tableType={tableType}
          setTableType={setTableType}
          selected={selected}
          setSelected={setSelected}
          checkInfo={checkInfo}
          visible={visible}
          setVisible={setVisible}
          optionInitial={optionInitial}
          listInitial={listInitial}
          defaultOptions={defaultOptions}
        />
      )}
    </div>
  );
}