Provinces.tsx 3.33 KB
/* eslint-disable @typescript-eslint/no-shadow */
import React from 'react';
import type { CascaderProps } from 'antd';
import { Cascader } from 'antd'

import { requestCode } from '@/services/server';

/**
 * @span 省市区三级联动选择组件
 */
export interface ProvincesCacaderPorps extends Partial<CascaderProps> {
  dept?: number;      // 联动层级
}

export default class ProvincesCacader extends React.Component<ProvincesCacaderPorps> {
  state = {
    options: [],
  };

  componentDidMount() {
    this.getLoadData()([]);
  }

  render() {
    const { value, onChange } = this.props;
    const { options } = this.state;

    const loadData = this.getLoadData();

    if (options.length && value && value[0]) {
      const keys: any[] = value;
      const node = [];
      let [data]: any = options.filter((item: any) => item.id === keys[0]);
      if (value && data) {
        // eslint-disable-next-line no-plusplus
        for (let i = 1; i < value.length; i++) {
          if (data.children) {
            [data] = data.children.filter((item: any) => item.id === keys[i]);
            if (!data) break;
            node.push(data);
          } else {
            node.push(data);
            loadData(node);
            break;
          }
        }
      }
    }



    return (
      <Cascader
        allowClear
        fieldNames={{
          label: 'name',
          value: 'id',
        }}
        defaultValue={this.props.value}
        loadData={loadData}
        onChange={(values: any[], options?: any[]) => {
          this.setState({ value: values });
          if(onChange) onChange(values, options);
        }}
        placeholder="请选择位置"
        {...this.props}
        options={options}
      ></Cascader>
    );
  }


  getLoadData() {
    let loadData;
    const { dept } = this.props;
    const { options } = this.state;

    // eslint-disable-next-line prefer-const
    loadData = (node: any) => {
      const option = node[node.length - 1] || {};
      if (option.loading) return;
      option.loading = true;
      // eslint-disable-next-line default-case
      switch (node.length) {
        case 0:
          requestCode('bdt.basic.province.search',{
            pageSize: 0,
            countryId: 86,
          }).then((res: any) => {
            this.setState({
              options: res.result.map((item: any) => {
                return {
                  ...item,
                  isLeaf: dept === 1,
                };
              }),
            });
          });
          break;
        case 1:
          requestCode('bdt.basic.city.search', { provinceId: option.id, pageSize: 0 }).then((res: any) => {
            option.loading = false;
            option.children = res.result.map((item: any) => {
              return {
                ...item,
                isLeaf: dept === 2,
              };
            });
            this.setState({ options });
          });
          break;
        case 2:
          requestCode('bdt.basic.district.search', { cityId: option.id, pageSize: 0 }).then((res: any) => {
            option.loading = false;
            option.children = res.result.map((item: any) => {
              return {
                ...item,
                isLeaf: true,
              };
            });
            this.setState({ options });
          });
          break;
      }
    }

    return loadData;

  }

}