import React from 'react';

import {Provider} from 'mobx-react';
import TableCtxMenuStore from '../Table/tableCtxMenuStore';
import {findDOMNode} from 'react-dom';
import {
  createObject,
  extendObject,
  anyChanged,
  isObjectShallowModified,
  isVisible,
  getPropValue,
  qsstringify,
  qsparse,
  isArrayChildrenModified,
  // Aug
  isMobile,
  uuid,
  findTree
} from '../../utils/helper';
import {IColumn, ITableStore} from '../../store/table';
import {QuickFilter} from './components/Filter';
import {Action} from '../../types';
import {ScopedContext, IScopedContext} from '../../Scoped';
import cloneDeep from 'lodash/cloneDeep';
import pick from 'lodash/pick';
import debounce from 'lodash/debounce';
import {expressLabels} from '../Lion/ExpressPrint/ExpressPrint';
import {
  message,
  Modal,
  Select as AntdSelect,
  Button as AntdButton,
  Spin,
  Progress,
  Input,
  Select,
  Popconfirm,
  Popover,
  Checkbox,
  Tag,
  Space
} from 'antd';
import {ItemSelection} from './components/Selection';
import {CrudBody} from './components/CrudBody';
import FilterModal from './components/Modals/FilterModal';
import SecondFilterDrawer from './components/Modals/SecondFilterDrawer';
import {Spinner} from '../../components';
import {ModalPrint} from '../Lion/LabelPrint';
import ModalFlow from '../../components/Mobileprocess/Workflow';
import OfflineComponent from './components/Offline';
import {Icon} from '../../components/icons';
import ExportModal from './components/Modals/ExportModal';
import {
  CRUDProps,
  CRUDState,
  filterTpl,
  CRUDToolbarChild,
  CRUDToolbarObject,
  CRUDBultinToolbarType,
  PrintType
} from './types';
import {defaultPropList, defaultProps, defaulState} from './defaultProperty';
import {evalExpression, filter} from '../../utils/tpl';
import {
  isEffectiveApi,
  isApiOutdated,
  str2function,
  normalizeApi
} from '../../utils/api';
import {templateDesign} from '../../utils/print';
import {buildLabelTemplate} from '../../utils/print/util';
import isEqual from 'lodash/isEqual';
import {EventEnum, EventSub} from '../../utils/sub';
import {makeTranslator, setDefaultLocale} from '../../locale';
import {
  isPureVariable,
  resolveVariableAndFilter
} from '../../utils/tpl-builtin';
import {
  advancefilterValueIsLegalEmptyValue,
  computeFilterTpl,
  dealAdvacedCondition,
  getInitParam,
  getTableRowsData,
  getTableSelectedRowsData,
  handleExportDefault,
  handlePrefix,
  handleSelectStructure,
  hasBulkActions,
  headerCanShow,
  openImageEnlarge,
  unitBulkActions
} from './utils';
import {getLodop} from '../../utils/print/LodopFuncs';
import {CommonModal} from './components/Modals/CommonModal';
import {Renderer} from '../..';
import {CRUDStore} from '../../store/crud';

interface CheckPictureType {
  addr: string;
  name: string;
  preview: string;
  thumbnailAddr?: string;
}

class CRUD extends React.Component<CRUDProps, CRUDState> {
  static propsList: Array<keyof CRUDProps> = defaultPropList;
  static defaultProps = defaultProps(isMobile());

  tableStore: ITableStore | null = null;
  crudRef: React.RefObject<HTMLDivElement> | null = React.createRef();
  tableInstance: any;
  searchTimer: ReturnType<typeof setTimeout>;
  mounted: boolean;
  /**
   * 高级查询弹窗类型
   * normal: 默认不弹窗且显示所有查询
   * popup-normal: 默认弹窗且显示所有查询
   * condition: 默认不弹窗且只显示条件查询
   * popup-condition: 默认弹窗且只显示条件查询
   */
  advancedMode?: 'normal' | 'popup-normal' | 'condition' | 'popup-condition';
  lastQuery: any;
  //记录itemAction传下来的高级查询参数
  itemActionData: any;
  filterForm: any;
  advanceFilterForm: any;
  // chencicsy
  setBorder?: boolean;
  advancedFilterData = new Map<string, any[]>();
  filtertpl: Array<filterTpl>; //高级查询展示在form中的内容
  sort: boolean;
  currentSelectedRow = 0;
  offlineData: Array<obj>; //离线数据集
  //离线的原始数据，用于重置按钮
  originOfflineData = [];
  preSortAble?: boolean;
  fingerprintModalData = undefined;
  originFilterData = {}; // 静态的过滤数据备份
  codeEvent: Function; //红外线扫码
  hasToolBars = false; //是否有工具栏判断

  /**
   * 初始是否拉取
   * @deprecated 建议用 api 的 sendOn 代替。
   */
  initFetch?: boolean;
  /**
   * 顶部工具栏
   */
  headerToolbar?: Array<
    (CRUDToolbarChild & CRUDToolbarObject) | CRUDBultinToolbarType
  >;

  constructor(props: CRUDProps) {
    super(props);
    this.state = defaulState(props, isMobile());

    this.advancedMode = props.advancedMode ?? 'normal';
    const {
      location,
      store,
      pageField,
      perPageField,
      syncLocation,
      loadDataOnce
    } = props;
    this.mounted = true;

    if (syncLocation && location && (location.query || location.search)) {
      store.updateQuery(
        qsparse(location.search.substring(1)),
        undefined,
        pageField,
        perPageField
      );
    } else if (syncLocation && !location && window.location.search) {
      store.updateQuery(
        qsparse(window.location.search.substring(1)) as object,
        undefined,
        pageField,
        perPageField
      );
    }

    this.props.store.setFilterTogglable(
      !!this.props.filterTogglable,
      this.props.filterDefaultVisible
    );

    // 如果有 api，data 里面先写个 空数组，面得继承外层的 items
    // 比如 crud 打开一个弹框，里面也是个 crud，默认一开始其实显示
    // 的是外层 crud 的数据，等接口回来后就会变成新的。
    // 加上这个就是为了解决这种情况
    if (this.props.api) {
      this.props.store.updateData({items: [], itemsRaw: []});
    }

    if (this.props.isStatic) {
      this.props.store.initStaticData(this.props.data as any, {
        page: 1,
        perPage: this.props.perPage || 20
      });
    }
  }

  componentWillUnmount() {
    this.mounted = false;
    this.quickEditDataCheck = () => null; // 重置 防止发生相互引用
    this.crudRef = null;
    this.tableStore = null;
    this.control = null;
    delete this.tableInstance;
    delete this.filterForm;
    // 清空子store  清空缓存数据
    this.props.store.clearChildStore();
    this.props.store.clearCacheData();
    this.codeEvent?.();
    clearTimeout(this.searchTimer);
  }
  componentDidMount() {
    const store = this.props.store;
    const {useMobileUI} = this.props;
    const mobileUI = isMobile() && useMobileUI;
    this.hasToolBars = !!this.crudRef?.current?.querySelector(
      "[class*='headToolbar']"
    );
    // 判断是否在小弹窗中
    if (localStorage.getItem('g_user_lang') == 'en_US') {
      setDefaultLocale('en-US');
    }
    if (localStorage.getItem('g_user_lang') == 'zh_CN') {
      setDefaultLocale('zh-CN');
    }

    if (mobileUI && this.advanceFilterForm?.props?.store?.data) {
      const data = this.advanceFilterForm.props.store.data;
      const existAdvancedFilterSub = Object.keys(
        dealAdvacedCondition(data?.advancedFilterSub) || {}
      ).length;
      const existAdvancedFilter = Object.keys(
        dealAdvacedCondition(data?.advancedFilter) || {}
      ).length;
      const existAdvancedHeader = Object.keys(
        data?.advancedHeader || {}
      ).length;
      const existFilterParam = Object.keys(data?.filterParam || {}).length;
      const exist =
        existAdvancedFilter +
        existAdvancedHeader +
        existFilterParam +
        existAdvancedFilterSub;
      if (exist > 0) {
        this.setState({filterExist: true, filtercont: cloneDeep(data)});
      }
    }

    if (this.props.perPage) {
      store.changePage(
        store.page,
        isMobile()
          ? this.props.perPage < 20
            ? 20
            : this.props.perPage
          : this.props.perPage
      );
    }

    if (
      !this.props.filter ||
      (store.filterTogggable && !store.filterVisible) ||
      mobileUI
    ) {
      let filterParam = {};
      if (
        !this.props.filter ||
        (store.filterTogggable && !store.filterVisible)
      ) {
        filterParam = {};
      } else if (mobileUI) {
        //解决移动端初始化没有携带普通查询的默认值
        if (
          this.props.advancedMode !== 'popup-normal' &&
          this.props.advancedMode !== 'popup-condition'
        ) {
          filterParam = getInitParam(this.props.translate, this.props.filter);
        } else {
          filterParam = {};
        }
      }
      this.handleFilterInit(filterParam, undefined, true);
    }

    let val: any;
    if (this.props.pickerMode && (val = getPropValue(this.props))) {
      store.setSelectedItems(val);
    }
  }

  componentDidUpdate(prevProps: CRUDProps, prevState: CRUDState) {
    const props = this.props;
    const store = prevProps.store;
    this.originFilterData = store.filterData; // 保证原始值不变

    if (anyChanged(['data'], prevProps, props) && props.itemAction) {
      //itemAction中的某个字段在当前表格中不存在，会被赋值为undefined传到目标组件，导致目标组件获取不到该字段
      const queryParam = createObject(props.data, props.store.query, {}, true);
      const TableData = getTableRowsData(this.props.store, this.tableStore);
      const ctx = createObject(
        queryParam,
        TableData?.[this.state.currentSelectedRow] || TableData?.[0],
        {},
        true
      );
      props.itemAction &&
        props.data?.items.length &&
        setTimeout(
          () =>
            this.handleAction(
              undefined,
              props.itemAction,
              ctx,
              undefined,
              undefined,
              true
            ),
          50
        );
    }

    let val: any;
    if (
      this.props.pickerMode &&
      isArrayChildrenModified(
        (val = getPropValue(this.props)),
        getPropValue(prevProps)
      )
    ) {
      store.setSelectedItems(val);
    }

    if (this.props.filterTogglable !== prevProps.filterTogglable) {
      store.setFilterTogglable(
        !!props.filterTogglable,
        props.filterDefaultVisible
      );
    }

    let dataInvalid = false;

    if (
      prevProps.syncLocation &&
      prevProps.location &&
      prevProps.location.search !== props.location.search
    ) {
      // 同步地址栏，那么直接检测 query 是否变了，变了就重新拉数据
      store.updateQuery(
        qsparse(props.location.search.substring(1)),
        undefined,
        props.pageField,
        props.perPageField
      );
      dataInvalid = !!(
        props.api && isObjectShallowModified(store.query, this.lastQuery, false)
      );
    }

    if (dataInvalid) {
      // 要同步数据
    } else if (
      prevProps.api &&
      props.api &&
      isApiOutdated(
        prevProps.api,
        props.api,
        store.fetchCtxOf(prevProps.data, {
          pageField: prevProps.pageField,
          perPageField: prevProps.perPageField
        }),
        store.fetchCtxOf(props.data, {
          pageField: props.pageField,
          perPageField: props.perPageField
        })
      )
    ) {
      dataInvalid = true;
    } else if (!props.api && isPureVariable(props.source)) {
      const prev = resolveVariableAndFilter(
        prevProps.source,
        prevProps.data,
        '| raw'
      );
      const next = resolveVariableAndFilter(props.source, props.data, '| raw');

      if (prev !== next) {
        store.initFromScope(props.data, props.source);
      }
    }

    if (dataInvalid && !this.sort) {
      this.search();
    }
    this.sort = false;
  }

  receive(values: object) {
    // 根据是否需要根据主表缓存数据，决定在由主表触发reload的时候是否要进行强制刷新
    this.handleQuery(values, !this.props.openCache);
  }

  // 当itemaction触发的时候 subpath query ctx 都会有 走的是this.receive的逻辑
  reload(subpath?: string, query?: any, ctx?: any, isItemAction?: boolean) {
    if (isItemAction && this.tableInstance?.props?.store.modified > 0) {
      this.showTableEditWarmModal();
      return;
    }
    // 我被触发了
    this.handleScrollToTop();
    if (this.props.api) {
      if (ctx === null) {
        this.props?.store?.clearData();
        this.props?.setTotalNum?.(
          this.props.totalTab?.key,
          0,
          this.props.name,
          this.props.bodyName
        );
      } else {
        if (query) {
          if (isItemAction) {
            this.itemActionData = query;
          }
          // 讨巧写法，同步方法中带有把参数合并的方法 handlequery 等同步代码执行完了再执行静默更新，保证查询条件时同步的
          setTimeout(() => {
            // 初始化查询条件之后在进行获取缓存
            if (this.props.openCache && this.props.api) {
              this.props.store.preFetchDataSlience(this.props.api, ctx, {
                forceReload: false,
                loadDataOnce: this.props.loadDataOnce,
                pageField: this.props.pageField,
                perPageField: this.props.perPageField,
                source: this.props.source,
                syncResponse2Query: this.props.syncResponse2Query
              });
            }
          }, 100);
          return this.receive(isMobile() ? {...query, page: 1} : query);
        } else {
          const advanceFilter = this.advanceFilterForm?.confirmAdvancedFilter();
          const postData = advanceFilter
            ? {
                ...advanceFilter,
                filterParam: this.props.store?.query?.filterParam
              }
            : undefined;
          // reload时候的快速查询条件会因为 已经有高级查询条件导致条件被固定，产生问题
          this.search(
            isMobile() ? {page: 1} : undefined,
            undefined,
            true,
            true,
            this.afterSearchFn,
            undefined,
            undefined,
            postData
          );
        }
      }
    } else if (ctx.items) {
      // 没有api的情况下用其他的方式init
      this.props.store.reInitData({items: ctx.items}, true);
    }
  }

  reloadTarget(target: string, data: any) {
    // implement this.
  }

  closeTarget(target: string) {
    // implement this.
  }

  // 多选按钮是否展示条件
  hasBulkActions = () => {
    const {headerBulkActions, footerBulkActions, itemActions, store} =
      this.props;

    return hasBulkActions(
      {
        headerBulkActions,
        footerBulkActions,
        itemActions
      },
      store,
      this.tableStore
    );
  };

  getRootClassName = (
    isLoading: boolean,
    tableRotate: boolean,
    className?: string
  ) => {
    const {classnames: cx} = this.props;
    return cx('Crud', className, {
      'is-loading': isLoading,
      tableRotate
    });
  };

  shouldRenderHeader = (): boolean => {
    const {header, filter} = this.props;
    const {filtercont} = this.state;
    return (
      !isMobile() || headerCanShow(header, filter, filtercont, this.tableStore)
    );
  };

  // ui控制相关
  setLoading = (loading: boolean) => {
    this.props.store?.markFetching?.(loading);
  };
  // 表单控制器相关
  control: any; // 控制实例
  controlRef = (control: any) => {
    // 因为 control 有可能被 n 层 hoc 包裹。
    while (control && control.getWrappedInstance) {
      control = control.getWrappedInstance();
    }

    this.control = control;
  };

  setTotal = (total: number) => {
    this.props.store.changeTotal(total);
  };

  showTableEditWarmModal = () => {
    const {env, translate: __} = this.props;
    Modal.warning({
      title: (
        <div>
          提示
          <div
            style={{
              position: 'absolute',
              right: '10px',
              top: '10px',
              fontSize: '12px',
              cursor: 'pointer'
            }}
            onClick={() => {
              Modal.destroyAll();
            }}
          >
            <Icon icon="close" className="icon" />
          </div>
        </div>
      ),
      content: '当前表格存在已修改的数据，请先提交或放弃，再进行其他操作!',
      getContainer: env.getModalContainer,
      zIndex: 1020,
      okText: __('confirm')
    });
  };
  //点击离线按钮，切换离线状态
  handleClickOffline = async () => {
    Modal.confirm({
      content: '是否确认进入离线模式？',
      okText: '确定',
      cancelText: '取消',
      onOk: async () => {
        this.setState({offlineMode: true});
      }
    });
  };

  // 点击高级查询按钮
  handleFilterAdvanced = () => {
    if (
      !isMobile() &&
      !this.props?.advancedFilter?.body?.some((item: any) => item?.body)
    ) {
      message.error('暂无查询条件');
      return;
    }
    this.setState({advancedFilterVisible: true});
  };

  openFeedback = (dialog: any, ctx: any) => {
    return new Promise(resolve => {
      const {store} = this.props;
      store.setCurrentAction({
        type: 'button',
        actionType: 'dialog',
        dialog: dialog
      });
      store.openDialog(ctx, undefined, confirmed => {
        resolve(confirmed);
      });
    });
  };

  search = (
    values?: any,
    silent?: boolean,
    clearSelection?: boolean,
    forceReload = false,
    resolve?: (value: any) => void,
    reject?: (error: any) => void,
    isChild?: boolean,
    postData?: any, // Jay
    init?: boolean
  ) => {
    const {
      store,
      api,
      messages,
      pageField,
      perPageField,
      interval,
      syncLocation,
      syncResponse2Query,
      keepItemSelectionOnPageChange,
      pickerMode,
      env,
      loadDataOnce,
      loadDataOnceFetchOnFilter,
      source
    } = this.props;
    // Jay
    //这里原先的备注是：
    //     Jay  Jay, 9个月前   (4 26th, 2022 4:49 下午)
    // 优化CRUD-filter的submit按钮target重复查询、查询条件问题
    //但是实测没有起到优化的效果，并且会导致左右页面的一个bug，回车提交查询主表数据为空时，从表数据没有更新
    // if (store.searching) return
    // reload 需要清空用户选择。
    if (keepItemSelectionOnPageChange && clearSelection && !pickerMode) {
      store.setSelectedItems([]);
      store.setUnSelectedItems([]);
    }

    let loadDataMode = '';
    if (values && typeof values.loadDataMode === 'string') {
      loadDataMode = 'load-more';
      delete values.loadDataMode;
    }

    clearTimeout(this.searchTimer);
    values &&
      store.updateQuery(
        values,
        !loadDataMode && syncLocation && env && env.updateLocation
          ? env.updateLocation
          : undefined,
        pageField,
        perPageField
      );
    this.lastQuery = store.query;
    let data = postData ?? createObject(store.data, store.query); // Jay
    if (!postData && Object.keys(this.state.filtercont || {}).length) {
      data.advancedFilter = this.state.filtercont?.advancedFilter;
      data.advancedHeader = this.state.filtercont?.advancedHeader;
      data.advancedFilterSub = this.state.filtercont?.advancedFilterSub;
      data.optionsParam = this.state.filtercont?.optionsParam;
      if (this.state.filtercont?.limitParam?.limitStatus) {
        data.topN = this.state.filtercont.limitParam.topN;
      }
      if (isMobile()) {
        if (init) {
          data.filterParam = getInitParam(
            this.props.translate,
            this.state.filtercont?.filterParam
          );
          if (Object.keys(data.filterParam)) {
            data.filterParam = this.state.filtercont?.filterParam;
          }
        } else {
          data.filterParam = this.state.filtercont?.filterParam;
        }
      }
      // if (this.state.filtercont?.filterOptionData) {
      //   const { optionsParam } = this.state.filtercont?.filterOptionData;
      //   data.optionsParam = optionsParam
      // }
    } else if (postData !== undefined && postData.filterOptionData) {
      const {optionsParam} = postData.filterOptionData;
      data.optionsParam = optionsParam;
    }
    if (data.advancedFilterSub) {
      data.advancedFilterSub = dealAdvacedCondition(data.advancedFilterSub);
    }
    if (data.advancedFilter) {
      data.advancedFilter = dealAdvacedCondition(data.advancedFilter);
    }

    try {
      if (this.props.isStatic) {
        store.initStaticData(undefined, values);
      } else {
        // ai-tool 的查询条件
        this.props.aiQuery && (data = createObject(data, this.props.aiQuery));
        // 清空子表格的列表宽度
        this.tableStore?.setTextWidth({});
        isEffectiveApi(api, data)
          ? store
              .fetchInitData(api, data, {
                successMessage: messages && messages.fetchSuccess,
                errorMessage: messages && messages.fetchFailed,
                autoAppend: true,
                forceReload,
                loadDataOnce,
                loadDataOnceFetchOnFilter,
                source,
                silent,
                openCache: this.props.openCache,
                pageField,
                perPageField,
                loadDataMode,
                syncResponse2Query
              })
              .then(value => {
                // Jay
                // WithStore.tsx: else if (props.data && (props.data as any).__super) 中的 store.hasRemoteData
                // 若不设置，store.initData不会合并之前的store.data.items（items:请求回来的data.items）
                this.setState({filterData: data});
                // this.tableStore?.clearOrderColumn?.();
                store.setHasRemoteData();
                if (!this.state.hasFetch) this.setState({hasFetch: true});
                this.props.setTotalNum &&
                  this.props.setTotalNum(
                    this.props.totalTab?.key,
                    value?.data?.total,
                    this.props.name,
                    this.props.bodyName
                  );
                resolve && resolve(value);
                this.props.onAiFinished?.();

                interval &&
                  this.mounted &&
                  (this.searchTimer = setTimeout(
                    this.search.bind(
                      this,
                      undefined,
                      undefined,
                      undefined,
                      true
                    ),
                    Math.max(interval, 1000)
                  ));
                return value;
              })
          : source && store.initFromScope(data, source);
      }
    } catch (err) {
      reject && reject(err);
      return;
    }
  };

  afterSearchFn = () => {
    const items = this.tableStore?.handleMutilSort(this.props.loadDataOnce);
    if (this.props.loadDataOnce && Array.isArray(items))
      this.setTotal(items.length);
  };

  handleExportDefault = (
    keepDataFormat: boolean,
    exportType: 'column' | 'template',
    exportRangeAll: boolean,
    exportFields?: string[]
  ) =>
    handleExportDefault(
      this.tableStore!,
      this.props.aliasTitle,
      keepDataFormat,
      exportType,
      exportRangeAll,
      exportFields
    );

  handleAction = (
    e: React.UIEvent<any> | undefined,
    action: Action,
    ctx: any,
    throwErrors: boolean = false,
    delegate?: IScopedContext,
    isItemAction: boolean = false
  ): any => {
    const {
      onAction,
      store,
      messages,
      pickerMode,
      env,
      pageField,
      columns,
      data
    } = this.props;
    // 如果有有编辑的按钮，并且不是itemaction的action 直接返回 并且展示弹窗
    if (this.tableInstance?.props?.store.modified > 0 && !isItemAction) {
      this.showTableEditWarmModal();
      return;
    }

    if (['dialog', 'drawer'].includes(action.actionType || '')) {
      const replace: any = {};
      store.setCurrentAction(action);
      if (action.drawer?.showLoading) store.markBusying(true);
      const idx: number = (ctx as any)?.index;
      const tableRows = getTableRowsData(store, this.tableStore);
      const length = tableRows.length;
      const openContainerFunction = {
        dialog: store.openDialog,
        drawer: store.openDrawer
      }[action.actionType as 'dialog' | 'drawer'];

      openContainerFunction(ctx, {
        hasNext: idx < length - 1,
        nextIndex: idx + 1,
        hasPrev: idx > 0,
        prevIndex: idx - 1,
        index: idx
      });
      if (action.drawer?.showLoading) store.markBusying(false);
      const ctxId = tableRows?.findIndex((item: any) => isEqual(item, ctx));
      replace.current = ctx;
      if (ctxId == 0) {
        replace.next = tableRows[ctxId + 1];
        replace.revious = undefined;
      } else if (ctxId == length) {
        replace.revious = tableRows[ctxId - 1];
        replace.revious = undefined;
      } else {
        replace.revious = tableRows[ctxId - 1];
        replace.next = tableRows[ctxId + 1];
      }
      if (!isEqual(replace, store.replace) && Object.keys(replace).length) {
        store.replaceDialog(replace);
      }
    } else if (action.actionType === 'advanced-filter') {
      this.handleFilterAdvanced();
    } else if (action.actionType === 'ajax') {
      store.setCurrentAction(action);
      const data = ctx;
      // 由于 ajax 一段时间后再弹出，肯定被浏览器给阻止掉的，所以提前弹。
      const redirect = action.redirect && filter(action.redirect, data);
      redirect && action.blank && env.jumpTo(redirect, action);

      return store
        .saveRemote(action.api!, data, {
          successMessage:
            (action.messages && action.messages.success) ||
            (messages && messages.saveSuccess),
          errorMessage:
            (action.messages && action.messages.failed) ||
            (messages && messages.saveFailed)
        })
        .then(async (payload: object) => {
          const data = createObject(ctx, payload);

          // Jay 菜鸟预览 预览按钮是放在操作列，actionType 为 'ajax'，根据状态码判断
          if ((data as any)?.status === 20002) {
            expressLabels(data as any, env.fetcher, this.props.translate);
            if (!action.redirect && !action.reload && !action.close) return;
          }

          if (action.feedback && isVisible(action.feedback, data)) {
            await this.openFeedback(action.feedback, data);
          }
          const redirect = action.redirect && filter(action.redirect, data);
          redirect && !action.blank && env.jumpTo(redirect, action);
          action.reload
            ? this.reloadTarget(action.reload, data)
            : redirect
            ? null
            : this.search(undefined, undefined, true, true, this.afterSearchFn);
          action.close && this.closeTarget(action.close);
          return null;
        })
        .catch(() => {});
    } else if (
      pickerMode &&
      (action.actionType === 'confirm' || action.actionType === 'submit')
    ) {
      store.setCurrentAction(action);
      return Promise.resolve({items: store.selectedItems.concat()});
    } else if (action.onClick) {
      store.setCurrentAction(action);
      let onClick = action.onClick;
      if (typeof onClick === 'string') {
        onClick = str2function(onClick, 'event', 'props', 'data');
      }
      onClick && onClick(e, this.props, ctx);
    } else if (action.actionType === 'label-design') {
      templateDesign(ctx, value => {
        Modal.confirm({
          title: '确认提交该模板吗？',
          okText: '确认',
          cancelText: '取消',
          getContainer: env.getModalContainer,
          onOk: () => {
            if (action.api) {
              const labelTemplate = buildLabelTemplate(value);
              const tableFields = labelTemplate.labelTables
                .map(table => table.fieldName ?? '')
                .join(',');
              env
                .fetcher(action.api, {
                  tableFields,
                  tempId: ctx.TEMP_ID,
                  content: value
                })
                .then(res => {
                  if (res.status === 0) {
                    message.success(res.msg);
                    // 重新获取数据列表
                    this.search(undefined, undefined, true, true);
                  } else {
                    message.error(res.msg);
                  }
                });
            }
          }
        });
      });
    } else if (action.actionType === 'export') {
      if (this.props.isStatic || this.props.mode === 'cross') {
        this.setState({staticExportShow: true});
        return;
      }
      store.setCurrentAction(action);
      let exportData: any = {};
      let _ids: string = '';
      let _selectedItems: any[] = getTableSelectedRowsData(
        store,
        this.tableStore
      );

      const optionsParam =
        this.state.filtercont?.filterOptionData?.optionsParam;

      const advancedFilter = dealAdvacedCondition(
        this.state.filtercont?.advancedFilter
      );
      const advancedFilterSub = dealAdvacedCondition(
        this.state.filtercont?.advancedFilterSub
      );
      const advancedHeader = this.state.filtercont?.advancedHeader;

      _selectedItems.map((_select: any) => {
        _ids += _select.hasOwnProperty(this.props.primaryField)
          ? _select[this.props.primaryField] + ','
          : '';
      });

      exportData = {
        ...exportData,
        ...this.props?.store?.query,
        pageId: this.props.name
      };
      exportData.selectedItems = _selectedItems;
      exportData.primaryField = this.props.primaryField;
      exportData.ids = _ids.slice(0, _ids.length - 1);
      exportData.tempIds = ctx[this.props.primaryField as any];
      if (this.state.filtercont?.limitParam?.limitStatus === true) {
        exportData.topN = this.state.filtercont?.limitParam?.topN;
      }
      if (!this.itemActionData) {
        exportData.optionsParam = optionsParam;
        exportData.advancedFilter = advancedFilter;
        exportData.advancedHeader = advancedHeader;
        exportData.advancedFilterSub = advancedFilterSub;
      }
      const exportSetColumnFields: string[] = [];
      this.tableInstance?.sortCols.forEach((col: any) => {
        if (!col?.hidden && col.name && col.name !== 'operation') {
          exportSetColumnFields.push(col.name);
        }
      });
      exportData.exportSetColumnFields = exportSetColumnFields;
      const orderBy = this.tableStore?.orderColumnsParam();
      orderBy && (exportData.orderBy = orderBy);
      store.openLionExport(
        this.itemActionData
          ? createObject(
              this.itemActionData,
              {
                ...exportData,
                ...ctx,
                handleExportDefault: this.handleExportDefault
              },
              {},
              true
            )
          : {
              ...exportData,
              ...ctx,
              handleExportDefault: this.handleExportDefault
            },
        env,
        undefined,
        isReload => {
          if (isReload) {
            action.reload && this.reloadTarget(action.reload, {});
          }
        }
      );
      return false;
    } else if (action.actionType === 'loginAmazon') {
      store.setCurrentAction(action);
      store.openAmazonLoginPage(ctx, env);
    } else if (
      action.actionType === 'label-print' ||
      action.actionType === 'bill-print' ||
      action.actionType === 'report-print' ||
      action.actionType === 'batch-print'
    ) {
      // Jay
      store.setCurrentAction(action);
      const {primaryField} = this.props;
      const {translate: __} = this.props;
      const LODOP = getLodop();
      const ids = getTableSelectedRowsData(store, this.tableStore)
        .map(item =>
          item.hasOwnProperty(primaryField)
            ? item[primaryField as string]
            : null
        )
        .filter(item => item)
        .join(',');
      if (LODOP) {
        this.setState({
          ModalProps: {
            ...action,
            show: true,
            ctx: {
              ...ctx.__super,
              ...ctx,
              primaryField,
              ids: ids || ctx?.[primaryField]
            }
          },
          printType: action.actionType.slice(
            0,
            action.actionType.indexOf('-')
          ) as any
        });
      }
    } else if (action.actionType === 'bpm_detail') {
      if (action.api) {
        this.setState({flowModalVisible: true});
        env.fetcher(action.api, ctx).then(res => {
          if (res.status === 0) {
            this.setState({flowModalProps: {flowDetail: res.data, ctx}});
          } else {
            message.error(res.msg);
            this.setState({flowModalVisible: false});
          }
        });
      }
    } else if (action.actionType === 'batch-image-view') {
      // Aug 批量查看图片
      const {onImageEnlarge} = this.props;
      if (!onImageEnlarge) return;
      if (!isMobile()) {
        onImageEnlarge({
          src: '',
          originalSrc: '',
          index: 0,
          list: []
        });
      }
      store.setCurrentAction(action);
      store
        .saveRemote(action.api as string, ctx, {
          errorMessage:
            (action.messages && action.messages.failed) ||
            (messages && messages.saveSuccess)
        })
        .then(async res => {
          const {onImageEnlarge} = this.props;
          const baseURL =
            env?.axiosInstance?.defaults?.baseURL || env?.ajaxApi || '';
          let prints: CheckPictureType[] = [];
          res.prints.forEach((item: CheckPictureType) => {
            if (item.thumbnailAddr) {
              prints.push(item);
            }
          });
          openImageEnlarge(prints, baseURL, onImageEnlarge, env);
          // this.imageViewData()
        })
        .catch(() => {});
    } else if (action.actionType?.includes('scale')) {
      const {foldColumns} = this.state;
      if (foldColumns?.includes(action.actionType)) {
        let newFoldCols = foldColumns?.filter(
          (col: string) => col != action.actionType
        );
        this.setState({foldColumns: newFoldCols});
      } else {
        this.setState({foldColumns: [...foldColumns, action.actionType]});
      }
    } else {
      // 这个就是刷新对应action的方法
      onAction(
        e,
        action,
        ctx,
        throwErrors,
        delegate || this.context,
        this.props.name,
        isItemAction
      );
    }
  };

  handleFilterReset = (values: object, action: any) => {
    const {store, syncLocation, env, pageField, perPageField} = this.props;
    store.updateQuery(
      store.pristineQuery,
      syncLocation && env && env.updateLocation
        ? (location: any) => env.updateLocation(location)
        : undefined,
      pageField,
      perPageField,
      true
    );
    this.lastQuery = store.query;
    if (action.type == 'reset') {
      return;
    }

    this.search();
  };

  handleFilterSubmit = async (
    values: any,
    jumpToFirstPage: boolean = true,
    replaceLocation: boolean = false,
    search: boolean = true,
    isChild?: boolean,
    init?: boolean
  ) => {
    const {
      store,
      syncLocation,
      env,
      pageField,
      perPageField,
      loadDataOnceFetchOnFilter
    } = this.props;
    // 添加filterParam的校验

    if (!init && this.filterForm) {
      try {
        const res = await this.filterForm?.validate?.();
        if (!res) {
          return Promise.reject();
        }
      } catch {}
    }

    values = syncLocation
      ? qsparse(qsstringify(values, undefined, true))
      : values;

    if (values.filterParam) {
      values.filterParam = Object.keys(values.filterParam).reduce<
        Record<string, any>
      >((acc, key) => {
        if (values.filterParam[key] !== '') {
          acc[key] = values.filterParam[key];
        }
        return acc;
      }, {});
    }

    store.updateQuery(
      {
        ...values,
        [pageField || 'page']: jumpToFirstPage ? 1 : store.page
      },
      syncLocation && env && env.updateLocation
        ? (location: any) => env.updateLocation(location, replaceLocation)
        : undefined,
      pageField,
      perPageField
    );
    this.lastQuery = store.query;
    search &&
      this.search(
        undefined,
        undefined,
        undefined,
        loadDataOnceFetchOnFilter,
        this.afterSearchFn,
        undefined,
        isChild,
        undefined,
        init
      );
  };

  handleFilterInit = async (
    values: object,
    isChild: boolean = false,
    init?: boolean
  ) => {
    const {defaultParams, data, store} = this.props;
    if (this.props?.advancedFilterApi) {
      await this.defaultAdvancedQuery(1);
    }
    this.handleFilterSubmit(
      {
        ...defaultParams,
        ...values,
        ...store.query
      },
      false,
      true,
      this.props.initFetch !== false,
      isChild,
      init
    );

    store.setPristineQuery();

    const {pickerMode, options} = this.props;

    pickerMode &&
      store.updateData({
        items: options || []
      });
  };

  handleSaveAdvancedFilterData = (val: string, cont: any[]) => {
    if (val.includes('advancedFilter')) {
      const name = val.split('.');
      if (name[name.length - 1].includes('--')) {
        if (
          !!this.advancedFilterData.set(
            name[name.length - 1].split('--')[0],
            cont
          )
        ) {
          this.advancedFilterData.set(
            name[name.length - 1].split('--')[0],
            cont
          );
        }
      } else this.advancedFilterData.set(name[name.length - 1], cont);
    } else {
      this.advancedFilterData.set(val, cont);
    }
  };

  // 高级查询内容展示
  handlefilters = () => {
    const {advancedFilter, advancedQueryFields} = this.props;
    const {filtercont} = this.state;

    // 调用纯函数计算
    const filtertpl = computeFilterTpl({
      advancedFilter,
      advancedQueryFields,
      filtercont,
      advancedFilterData: this.advancedFilterData,
      advanceFilterFormState: this.advanceFilterForm?.state
    });

    this.setState({filtertpl});
  };

  handlePrefix = (filter: obj) =>
    handlePrefix(
      filter,
      this.props.advancedQueryFields!,
      this.props.advancedFilter
    );

  // 查询1
  // selectApi
  // 修改2
  // modifyApi
  // 删除3
  // deleteApi
  defaultAdvancedQuery = async (
    val = 1 | 2 | 3,
    body?: any,
    senior?: boolean
  ) => {
    const {
      env,
      advancedFilterApi: {selectApi, modifyApi, deleteApi}
    } = this.props;
    const {defaultTempKey, defaultList} = this.state;
    try {
      if (val == 1) {
        let filter;
        if (body && defaultList.some(item => body.tempKey == item.tempKey)) {
          filter = defaultList.find(
            item => body.tempKey == item.tempKey
          ).columnInfo;
          const list = defaultList.find(item => body.tempKey == item.tempKey);
          this.setState(
            {
              filtercont: {...this.state.filtercont, ...filter},
              multipleDefault: list.tempName,
              defaultTempKey: list.tempKey
            },
            () => {
              this.handlefilters();
            }
          );
          if (
            this.advancedMode == 'condition' ||
            this.advancedMode == 'popup-condition'
          ) {
            filter.optionsParam = undefined;
          }
          const data = this.handlePrefix(filter);
          this.advanceFilterForm?.handleFiltersArr(data);
        } else {
          const api = selectApi;
          if (!api) return true;
          const res = await env.fetcher(api);
          if (res.status == 0 && res.data) {
            const body = res.data;
            if (Array.isArray(body)) {
              filter = cloneDeep(body[0].columnInfo);
              const options = filter.optionsParam;
              //过滤掉不存在的字段
              if (Array.isArray(filter.advancedFilter)) {
                let filterBody = this.props.advancedFilter?.body;
                filterBody = Array.isArray(filterBody)
                  ? filterBody
                  : filterBody
                  ? [filterBody]
                  : [];
                const filters = filterBody.find(
                  (item: any) => item.name === 'advancedFilter'
                )?.body;
                filter.advancedFilter = filter.advancedFilter.filter(
                  (item: any) => {
                    const isInside = !!filters.find(
                      (col: any) => col.name === `advancedFilter.${item.field}`
                    );
                    return isInside;
                  }
                );

                filter.advancedFilterSub = filter.advancedFilterSub.filter(
                  (item: any) => {
                    const isInside = !!filters.find(
                      (col: any) =>
                        col.name === `advancedFilterSub.${item.field}`
                    );
                    return isInside;
                  }
                );
              }
              if (
                this.advancedMode == 'condition' ||
                this.advancedMode == 'popup-condition'
              ) {
                filter.optionsParam = undefined;
              } else if (options) {
                if (
                  options.itemCount === false &&
                  options.itemRepeat === false &&
                  options.itemSumCount === false &&
                  options.section === false &&
                  options.showFields?.length === 0 &&
                  options.sortFields?.length === 0 &&
                  options.groupByFields?.length === 0
                ) {
                  filter.optionsParam = undefined;
                }
              }
              const defaultBody = body.map(item => {
                if (!item?.tempKey) {
                  return {
                    columnInfo: item,
                    tempKey: item?.tempKey ?? uuid(),
                    tempName: item?.tempName ?? '默认设置'
                  };
                }
                return item;
              });

              this.setState({
                defaultList: defaultBody,
                multipleDefault: body[0].tempName,
                defaultTempKey: body[0].tempKey,
                defaultTempValue: body[0].tempKey ?? 'defaultQuery'
              });
            } else {
              if (res.data?.columnInfo) {
                filter = cloneDeep(res.data.columnInfo);
              } else {
                filter = cloneDeep(res.data);
                this.setState({defaultList: []});
              }
              if (
                this.advancedMode == 'condition' ||
                this.advancedMode == 'popup-condition'
              ) {
                filter.optionsParam = undefined;
              }
              this.setState({
                defaultList: [
                  {
                    columnInfo: filter,
                    tempKey: res.data?.tempKey ?? uuid(),
                    tempName: res.data?.tempName ?? '默认设置'
                  }
                ]
              });
            }
            // const filter = cloneDeep(res.data.columnInfo)
            this.setState(
              {
                filtercont: {
                  ...this.state.filtercont,
                  ...filter,
                  optionsParam: filter.optionsParam
                }
              },
              () => {
                this.handlefilters();
              }
            );
            const data = handlePrefix(
              filter,
              this.props.advancedQueryFields!,
              this.props.advancedFilter
            );
            this.advanceFilterForm?.handleFiltersArr(data);
          } else {
            this.setState(
              {defaultTempValue: 'defaultQuery'},
              this.advanceFilterForm?.resetDefaultQuery()
            );
          }
        }
      } else if (val == 2) {
        const api = modifyApi;
        if (!api) return true;
        const queryParams: any =
          this.advanceFilterForm?.confirmAdvancedFilter(true);
        const rawShowFields = queryParams?.filterOptionData?.rawShowFields;
        const optionsParam = queryParams?.filterOptionData?.optionsParam;
        if (rawShowFields?.length == 0) {
          message.warning('显示字段不能为空');
          return true;
        }
        queryParams.optionsParam = optionsParam;
        //初始化的时候，高级查询中的select取不到对应的label，所以传给后端，保存起来
        if (queryParams.advancedFilter?.length > 0) {
          const newAdvancedFilter = queryParams.advancedFilter.map(
            (filterItem: any) => {
              const optionsData = this.advancedFilterData.get(filterItem.field);
              let data = filterItem.values;
              if (optionsData && optionsData?.length > 0) {
                if (
                  typeof filterItem?.values == 'string' &&
                  filterItem?.values?.indexOf(',') !== -1
                ) {
                  data = filterItem.values
                    .split(',')
                    .map(
                      (name_item: any) =>
                        findTree(
                          optionsData,
                          current => current.value == name_item
                        )?.label
                    )
                    ?.join(',');
                } else {
                  data = findTree(
                    optionsData,
                    item => item.value == filterItem.values
                  )?.label;
                }
              }
              return {...filterItem, valuesAlia: data};
            }
          );
          queryParams.advancedFilter = newAdvancedFilter;
        }
        if (body) {
          const url: any = {
            method: 'post',
            url: api?.url || '',
            data: {
              tempName: '${tempName |default:undefined}',
              tempKey: '${tempKey |default:undefined}',
              columnInfo: {
                advancedFilter: '${advancedFilter |default:undefined}',
                advancedFilterSub: '${advancedFilterSub |default:undefined}',
                advancedHeader: '${advancedHeader |default:undefined}',
                optionsParam: '${optionsParam |default:undefined}',
                limitParam: '${limitParam |default:undefined}'
              }
            }
          };

          let columnInfo;
          let data;
          if (
            !senior &&
            defaultList.length > 0 &&
            !!defaultList.find(item => body.tempKey == item.tempKey)
          ) {
            columnInfo = defaultList.find(
              item => body.tempKey == item.tempKey
            ).columnInfo;
          } else if (senior) {
            columnInfo = queryParams;
          }

          if (!!defaultTempKey && columnInfo) {
            data = {...body, ...columnInfo};
          } else if (columnInfo) {
            data = {...body, ...columnInfo};
          } else {
            data = {...body, ...queryParams};
          }
          const {msg} = await env.fetcher(url, data);
          message.info(msg);
          this.defaultAdvancedQuery(1);
        } else {
          const res = await env.fetcher(api, queryParams);
          if (res.status == 0) {
            message.success(res.msg);
          }
          this.defaultAdvancedQuery(1);
        }
      } else if (val == 3) {
        const api = deleteApi;
        if (!api) return true;
        const url: any = {
          method: api.method,
          url: api.url + '&tempKey=' + body || ''
        };
        const res = await env.fetcher(url, {tempKey: body});
        if (res.status == 0) {
          message.success(res.msg);
          this.setState(
            {defaultList: defaultList.filter(item => item.tempKey !== body)},
            () => {
              const list = defaultList.filter(item => item.tempKey !== body);
              if (list.length == 0) {
                this.setState({selectTmpShow: false});
              }
            }
          );
        }
        this.defaultAdvancedQuery(1);
      }
      return true;
    } catch {
      return true;
    }
  };

  getFilterForm = (form: any) => {
    this.filterForm = form;
  };

  // 获取普通查寻的数据
  handleFilterOptions = (value: any) => {
    this.setState({filterOptions: value});
  };

  // 删除高级查询条件
  handledelVisible = (
    value: any,
    whole = false,
    e?: React.MouseEvent<HTMLElement>,
    delIndex?: number
  ) => {
    e?.preventDefault();
    let filtercont: any = cloneDeep(this.state.filtercont);
    filtercont.filterParam = cloneDeep(this.state.filterOptions.filterParam);
    if (whole) {
      filtercont.advancedFilter = [];
      filtercont.advancedFilterSub = [];
      filtercont.advancedHeader = {};
      this.advanceFilterForm?.handlerenew?.(whole);
    } else {
      const head = value.name.split('.')[0];
      const name = value.name.split('.')[1];
      if (
        head.includes('advancedFilter') ||
        head.includes('advancedFilterSub')
      ) {
        let newList = [...filtercont[head]];
        if (delIndex !== undefined) {
          newList.splice(delIndex, 1);
        } else {
          newList = filtercont[head].filter((item: any) => item.field != name);
        }
        filtercont[head] = newList;
      } else {
        let replacement: any = {};
        for (const key in filtercont[head]) {
          if (key !== name) {
            replacement[key] = filtercont[head]?.[key];
          }
        }
        filtercont[head] = replacement;
      }
      this.advanceFilterForm?.handlerenew?.(whole, value.name, value.keyName);
    }

    this.setState(
      {
        filtercont: filtercont
      },
      () => {
        this.handlefilters();
      }
    );
  };
  // 判断是否有高级查询的数据将基础查询重置
  handleReset = () => {
    let filtercont: any = cloneDeep(this.state.filtercont);
    if (Object.keys(filtercont).length) {
      filtercont.filterParam = cloneDeep(this.state.filterOptions.filterParam);
      this.setState({filtercont: filtercont});
    }
  };

  // 检查数据预留的方法-会被替换掉
  quickEditDataCheck = () => {};
  // 注册检查数据预留的方法
  dataCheckRegist = (fn: any) => (this.quickEditDataCheck = fn);
  handleQuery = (values: obj, forceReload: boolean = false) => {
    const {store, syncLocation, env, pageField, perPageField, loadDataOnce} =
      this.props;
    const saveFilter = values['filterParam'] == null;
    // Jay crud filter是点击submit按钮才更新query，现在需要拿到实时的form的data
    const tmpValues: any = {
      ...values,
      [pageField || 'page']: 1
    };
    const temp = this.filterForm?.props.store.data[this.props.filter?.name];
    if (temp) {
      tmpValues[this.props.filter!.name] = temp;
    }

    store.updateQuery(
      tmpValues,
      syncLocation && env && env.updateLocation
        ? env.updateLocation
        : undefined,
      pageField,
      perPageField
    );
    // 如果需要缓存数据 阐释静默加载数据进缓存

    this.search(
      undefined,
      undefined,
      undefined,
      forceReload,
      saveFilter
        ? this.afterSearchFn
        : () => {
            this.tableStore?.filterColumns?.clear();
            this.setState({showColumnsFilter: false}, () => {
              const orderColumns = this.tableStore?.orderColumns;
              if (orderColumns?.size > 0) {
                this.tableStore?.handleMutilSort(loadDataOnce);
              }
            });
          }
    );
  };

  handleSaveOrder = (moved: Array<object>, rows: Array<object>) => {
    const {store, saveOrderApi, orderField, primaryField, env, reload} =
      this.props;

    if (!saveOrderApi) {
      env && env.alert('CRUD saveOrderApi is required!');
      return;
    }

    const model: {
      insertAfter?: any;
      insertBefore?: any;
      idMap?: any;
      rows?: any;
      ids?: any;
      order?: any;
    } = createObject(store.data);

    let insertAfter: any;
    let insertBefore: any;
    const holding: Array<object> = [];
    const hasIdField =
      primaryField &&
      rows[0] &&
      (rows[0] as object).hasOwnProperty(primaryField);

    hasIdField || (model.idMap = {});

    model.insertAfter = {};
    rows.forEach((item: any) => {
      if (~moved.indexOf(item)) {
        if (insertAfter) {
          let insertAfterId = hasIdField
            ? (insertAfter as any)[primaryField as string]
            : rows.indexOf(insertAfter);
          model.insertAfter[insertAfterId] =
            (model as any).insertAfter[insertAfterId] || [];

          hasIdField || (model.idMap[insertAfterId] = insertAfter);
          model.insertAfter[insertAfterId].push(
            hasIdField ? item[primaryField as string] : item
          );
        } else {
          holding.push(item);
        }
      } else {
        insertAfter = item;
        insertBefore = insertBefore || item;
      }
    });

    if (insertBefore && holding.length) {
      let insertBeforeId = hasIdField
        ? insertBefore[primaryField as string]
        : rows.indexOf(insertBefore);
      hasIdField || (model.idMap[insertBeforeId] = insertBefore);
      model.insertBefore = {};
      model.insertBefore[insertBeforeId] = holding.map((item: any) =>
        hasIdField ? item[primaryField as string] : item
      );
    } else if (holding.length) {
      const first: any = holding[0];
      const firstId = hasIdField
        ? first[primaryField as string]
        : rows.indexOf(first);

      hasIdField || (model.idMap[firstId] = first);
      model.insertAfter[firstId] = holding
        .slice(1)
        .map((item: any) => (hasIdField ? item[primaryField as string] : item));
    }

    if (orderField) {
      const start = (store.page - 1) * store.perPage || 0;
      rows = rows.map((item, key) =>
        extendObject(item, {
          [orderField]: start + key + 1
        })
      );
    }

    model.rows = rows.concat();
    hasIdField &&
      (model.ids = rows
        .map((item: any) => item[primaryField as string])
        .join(','));
    hasIdField &&
      orderField &&
      (model.order = rows.map(item =>
        pick(item, [primaryField as string, orderField])
      ));

    isEffectiveApi(saveOrderApi, model) &&
      store
        .saveRemote(saveOrderApi, model)
        .then(() => {
          reload && this.reloadTarget(reload, model);
          this.search(undefined, undefined, true, true);
        })
        .catch(() => {});
  };

  handleChildPopOverOpen = (popOver: any) => {
    if (
      this.props.interval &&
      popOver &&
      ~['dialog', 'drawer'].indexOf(popOver.mode)
    ) {
      this.props.store.setInnerModalOpened(true);
    }
  };

  handleChildPopOverClose = (popOver: any) => {
    if (popOver && ~['dialog', 'drawer'].indexOf(popOver.mode)) {
      this.props.store.setInnerModalOpened(false);
    }
  };

  handleFakeAnimation = debounce(() => {
    // // 加载假动画 在线上没问题amis上有问题
    setTimeout(() => {
      this.control?.props?.setLoading?.(true);
    }, 0);
    setTimeout(() => {
      this.control?.props?.setLoading?.(false);
    }, 1000);
  }, 1000);

  handleLoadMore = () => {
    // if (!this.props.loadDataOnce) {
    this.search({page: this.props.store.page + 1, loadDataMode: 'load-more'});
    // }
  };

  //移动端刷新或查询时需要滚动到顶部，不然会逐页请求数据
  handleScrollToTop = () => {
    if (isMobile()) {
      const {classPrefix} = this.props;
      const crud = findDOMNode(this) as HTMLElement;
      const container = crud.querySelector(
        `.${classPrefix}Table-content`
      ) as HTMLElement;
      if (container) {
        container.scrollTo({top: 0});
      }
      const Listitems = crud.querySelector(
        `.${classPrefix}List-items`
      ) as HTMLElement;
      if (Listitems) {
        Listitems.scrollTo({top: 0});
      }
    }
  };
  //刷新数据，带查询条件
  handleResetData = () => {
    this.handleScrollToTop();
    this.search({page: 1});
  };

  markSort = () => {
    this.sort = true;
  };

  // Jay
  getTableStore = (store: any) => {
    this.tableStore = store;
    this.forceUpdate(); // 中间状态更新了强制刷新视图，不写state是因为这个不是ui值，但是这个更新在视图更新之后
  };
  getAdvancedFilterForm = (form: any) => {
    // 避免进行重复设置
    if (!this.advanceFilterForm) this.advanceFilterForm = form;
    this.forceUpdate(); // 中间状态更新了强制刷新视图，不写state是因为这个不是ui值，但是这个更新在视图更新之后
  };
  getTableInstance = (table: any) => {
    this.tableInstance = table;
    this.props.getTableInstance?.(table);
    this.forceUpdate(); // 中间状态更新了强制刷新视图，不写state是因为这个不是ui值，但是这个更新在视图更新之后
  };

  clearSelectedItems = () => {
    this.props.store.setSelectedItems([]);
  };

  handleJump = (body: any) => {
    if (body.redirectType === '2') {
      this.props.env.fetcher(body.linkUrl, body.bodydata).then(res => {
        if (res.ok && res.data != null) {
          this.setState({
            flowModalProps: {flowDetail: res.data},
            flowModalVisible: true
          });
        } else {
          message.error(res.msg);
        }
      });
      return;
    }
    const types = isMobile() ? 'drawer' : 'dialog';
    const action: any = {
      type: 'action',
      actionType: types,
      close: true
    };
    action[types] = {
      showLoading: isMobile(),
      title: body.linkTitle,
      type: types,
      size: body.linkSize ?? 'lg',
      bodyClassName: `overflow-y-auto max-h-nestSide-${types}`,
      className: 'h-full',
      actions: [],
      overlay: isMobile() ? false : true,
      body: {
        schemaApi: {
          method: 'get',
          url: body.linkUrl
        },
        type: 'service'
      }
    };
    this.handleAction(this.props.e, action, body.bodydata);
  };

  // ==================== 渲染区域 ====================
  renderPcAlert = () => {
    const {header, render, useMobileUI} = this.props;

    if (!header || (useMobileUI && isMobile())) return null;

    return render('alert', header, {
      style: {
        marginBottom: !this.crudRef?.current?.querySelector(
          "[class*='headToolbar']"
        )
          ? 'unset'
          : '10px'
      }
    });
  };

  setCrudState = (value: any, callback?: () => void) => {
    console.log('子组件设置', value);
    this.setState(value, callback);
  };

  renderHeader = () => {
    const {classnames: cx} = this.props;
    if (!this.shouldRenderHeader()) return null;

    return (
      <div className={cx('Crud-head')}>
        {this.renderPcAlert()}
        {this.renderFilter()}
      </div>
    );
  }; // 展示头部判断

  renderFilter = (isFilter = false) => {
    const {filtercont, filtertpl, useMobileUI} = this.state;
    if (useMobileUI && isMobile()) return null;
    return (
      <QuickFilter
        props={this.props}
        useMobileUI={useMobileUI}
        filterExist={false}
        filtercont={filtercont}
        filtertpl={filtertpl}
        handleFilterReset={this.handleFilterReset}
        handleFilterSubmit={this.handleFilterSubmit}
        handleFilterInit={this.handleFilterInit}
        defaultAdvancedQuery={this.defaultAdvancedQuery}
        getFilterForm={this.getFilterForm}
        handleFilterAdvanced={this.handleFilterAdvanced}
        handleFilterOptions={this.handleFilterOptions}
        handledelVisible={this.handledelVisible}
        handleReset={this.handleReset}
        search={this.search}
        afterSearchFn={this.afterSearchFn}
        isFilter={isFilter}
      />
    );
  };

  // ==================== 主体区域渲染 ====================
  renderBody = () => {
    const {name, saveColApi, columnInfo, tabsdefer, initFetch, preSortAble} =
      this.props;
    const {
      tableRotate,
      currentSelectedRow,
      foldColumns,
      filtercont,
      showColumnsFilter,
      hasFetch,
      filterData
    } = this.state;
    return (
      <CrudBody
        props={this.props}
        foldColumns={foldColumns}
        tableRotate={tableRotate}
        showColumnsFilter={showColumnsFilter}
        hasFetch={hasFetch}
        controlRef={this.controlRef}
        tableStore={this.tableStore}
        // 函数方法
        setLoading={this.setLoading}
        renderFilter={this.renderFilter}
        handleAction={this.handleAction}
        dataCheckRegist={this.dataCheckRegist}
        handleSaveOrder={this.handleSaveOrder}
        handleQuery={this.handleQuery}
        handleChildPopOverOpen={this.handleChildPopOverOpen}
        handleChildPopOverClose={this.handleChildPopOverClose}
        handleFilterReset={this.handleFilterReset}
        handleFilterSubmit={this.handleFilterSubmit}
        handleFilterInit={this.handleFilterInit}
        markSort={this.markSort}
        handleLoadMore={this.handleLoadMore}
        handleResetData={this.handleResetData}
        getTableStore={this.getTableStore}
        getTableInstance={this.getTableInstance}
        setTotal={this.setTotal}
        clearSelectedItems={this.clearSelectedItems}
        handleClickOffline={this.handleClickOffline}
        handleJump={this.handleJump}
        hasBulkActions={this.hasBulkActions}
        crudRef={this.crudRef}
        currentSelectedRow={currentSelectedRow}
        filtercont={filtercont}
        saveColApi={saveColApi}
        columnInfo={columnInfo}
        tabsdefer={tabsdefer}
        initFetch={initFetch}
        name={name}
        preSortAble={preSortAble}
        handleFakeAnimation={this.handleFakeAnimation}
        tableInstance={this.tableInstance}
        search={this.search}
        reload={this.reload}
        setCrudState={this.setCrudState}
        quickEditDataCheck={this.quickEditDataCheck}
        advanceFilterForm={this.advanceFilterForm}
        afterSearchFn={this.afterSearchFn}
        control={this.control}
        originFilterData={this.originFilterData}
        filterData={filterData}
        showTableEditWarmModal={this.showTableEditWarmModal}
        openFeedback={this.openFeedback}
        reloadTarget={this.reloadTarget}
        closeTarget={this.closeTarget}
        context={this.context}
      ></CrudBody>
    );
  };

  // ==================== 底部区域渲染 ====================
  renderFooter = () => {
    const {footer, render, classnames: cx, store} = this.props;
    const showFooter = footer && !isMobile();

    if (!showFooter) return null;

    return render('alert', footer, {
      cx,
      pageUniqueMark: this.props.name + 'footer',
      data: store.data
    });
  };

  // 多选按钮渲染
  renderSelection = () => {
    const {multiple, keepItemSelectionOnPageChange, mobileUI} = this.props;
    if (
      !(
        (this.hasBulkActions() || multiple) &&
        keepItemSelectionOnPageChange &&
        !mobileUI
      )
    )
      return null;

    // 实际渲染逻辑...
    return <ItemSelection props={this.props} control={this.control} />;
  };

  // 打印标签弹窗
  renderModalPrint = () => {
    const {store} = this.props;
    return (
      this.state.printType && (
        <ModalPrint
          printType={this.state.printType}
          {...this.props}
          {...this.state.ModalProps}
          onHide={() => {
            this.setState({printType: undefined});
          }}
          columns={this.tableStore?.filteredColumns ?? this.props.columns}
          query={{
            ...store.query,
            ...this.state.filtercont,
            advancedFilter: this.state.filtercont?.advancedFilter?.filter(
              (item: any) => !advancefilterValueIsLegalEmptyValue(item)
            )
          }}
          orderParam={this.tableStore?.orderColumnsParam()}
        />
      )
    );
  };

  // 流程弹窗
  renderFlowModal = () => {
    const {flowModalProps, flowModalVisible} = this.state;
    const {onImageEnlarge, classnames: cx, env, render} = this.props;
    const language = makeTranslator();
    return (
      <ModalFlow
        visible={flowModalVisible}
        onClose={reload => {
          this.setState({
            flowModalVisible: false,
            flowModalProps: {flowDetail: undefined}
          });
          if (reload) {
            this.search(undefined, undefined, true, true);
          }
        }}
        env={env}
        render={render}
        onImageEnlarge={onImageEnlarge}
        language={language}
        classnames={cx}
        {...flowModalProps}
      />
    );
  };

  // 渲染查询区域--组件化 打开高级查询的逻辑完全不用CRUD去做，画蛇添足
  renderFilterModal = () => {
    const {
      advancedFilterVisible,
      filterExist,
      advancedFilterAction,
      filtercont,
      filtertpl,
      defaultVisible,
      defaultList,
      multipleDefault,
      templateSwitch,
      defaultTempKey,
      defaultTempValue,
      filterOptions,
      selectTmpShow
    } = this.state;

    return (
      <FilterModal
        props={this.props}
        filterOptions={filterOptions}
        advanceFilterForm={this.advanceFilterForm}
        filterForm={this.filterForm}
        templateSwitch={templateSwitch}
        tableStore={this.tableStore}
        advancedFilterVisible={advancedFilterVisible}
        filterExist={filterExist}
        advancedFilterAction={advancedFilterAction}
        filtercont={filtercont}
        filtertpl={filtertpl}
        defaultVisible={defaultVisible}
        defaultList={defaultList}
        multipleDefault={multipleDefault}
        defaultTempKey={defaultTempKey}
        defaultTempValue={defaultTempValue}
        selectTmpShow={selectTmpShow}
        handleFilterInit={this.handleFilterInit}
        handlePrefix={this.handlePrefix}
        getAdvancedFilterForm={this.getAdvancedFilterForm}
        handleSaveAdvancedFilterData={this.handleSaveAdvancedFilterData}
        defaultAdvancedQuery={this.defaultAdvancedQuery}
        handleFilterSubmit={this.handleFilterSubmit}
        handleScrollToTop={this.handleScrollToTop}
        getFilterForm={this.getFilterForm}
        handleFilterOptions={this.handleFilterOptions}
        handledelVisible={this.handledelVisible}
        handlefilters={this.handlefilters}
        handleReset={this.handleReset}
        handleFilterReset={this.handleFilterReset}
        setCrudState={this.setCrudState}
        search={this.search}
      ></FilterModal>
    );
  };

  // 渲染二次过滤区域
  renderSecondFilterDrawer = () => {
    return (
      <SecondFilterDrawer
        props={this.props}
        filterDrawerVisible={this.state.filterDrawerVisible}
        showColumnsFilter={this.state.showColumnsFilter}
        tableStore={this.tableStore}
        setCrudState={states => {
          this.setState(states);
        }}
        setTotal={this.setTotal}
        handleAction={this.handleAction}
      ></SecondFilterDrawer>
    );
  };

  // 渲染离线报文
  rendeOfflineSchema = () => {
    const {
      aliasTitle,
      tableLayout,
      offlineSchema,
      menuName,
      env,
      translate,
      store,
      render,
      primaryField,
      columns,
      classPrefix
    } = this.props;
    const {offlineMode, filtercont} = this.state;
    if (!this.props.offlineSchema) return null;
    return (
      <OfflineComponent
        offlineMode={offlineMode}
        offlineSchema={offlineSchema}
        store={store}
        render={render}
        env={env}
        aliasTitle={aliasTitle}
        menuName={menuName}
        primaryField={primaryField}
        name={this.props.name}
        filtercont={filtercont}
        translate={translate}
        classPrefix={classPrefix}
        columns={columns}
        tableLayout={tableLayout}
        search={this.search}
        curdRef={this.crudRef}
      />
    );
  };

  // 渲染导出
  renderStaticExportModal = () => {
    if (!this.state.staticExportShow || isMobile()) return null;
    return (
      <ExportModal
        props={this.props}
        tableStore={this.tableStore}
        staticExportShow={this.state.staticExportShow}
        setCrudState={this.setCrudState}
      ></ExportModal>
    );
  };

  // 弹窗 抽屉渲染
  renderModalAndDrawer = () => {
    return (
      <CommonModal
        dialogShow={this.props.store.dialogOpen}
        drawerShow={this.props.store.drawerOpen}
        props={this.props}
        tableStore={this.tableStore}
        crudRef={this.crudRef}
        handleAction={this.handleAction}
        showTableEditWarmModal={this.showTableEditWarmModal}
        search={this.search}
        searchTimer={this.searchTimer}
        afterSearchFn={this.afterSearchFn}
        reloadTarget={this.reloadTarget}
      ></CommonModal>
    );
  };

  // ==================== 主渲染函数 ====================
  render() {
    const {className, store} = this.props;
    const {tableRotate, useMobileUI} = this.state;
    const isLoading = !useMobileUI && store.loading;

    return (
      <div
        ref={this.crudRef}
        className={this.getRootClassName(isLoading, tableRotate, className)}
      >
        <Provider tableCtxMenuStore={TableCtxMenuStore}>
          {this.renderHeader()}
          {this.renderSelection()}
          {this.renderBody()}
          {this.renderFooter()}
          <Spinner
            overlay
            size={this.props.formStore ? undefined : 'md'}
            key="info"
            show={store.loading || store.filterLoading}
            className={`${tableRotate ? 'horizontal-mode' : ''}`}
          />
          {this.renderModalPrint()}
          {this.renderFlowModal()}
          {this.renderFilterModal()}
          {this.renderSecondFilterDrawer()}
          {this.rendeOfflineSchema()}
          {this.renderStaticExportModal()}
          {this.renderModalAndDrawer()}
        </Provider>
      </div>
    );
  }
}

@Renderer({
  type: 'crud',
  storeType: CRUDStore.name,
  isolateScope: true
})
export default class CRUDRenderer extends CRUD {
  static contextType = ScopedContext;

  constructor(props: CRUDProps, context: IScopedContext) {
    super(props);
    const scoped = context;
    EventSub.emit(EventEnum.ClearMappingAcahe, this?.props?.name);
    EventSub.emit(EventEnum.ClearSelectCache, this?.props?.name);
    scoped.registerComponent(this);
  }

  componentWillUnmount() {
    super.componentWillUnmount();
    const scoped = this.context as IScopedContext;
    scoped.unRegisterComponent(this);
    // 卸载的时候清除定时器
  }

  reload = (
    subpath?: string,
    query?: any,
    ctx?: any,
    isItemAction?: boolean
  ) => {
    const scoped = this.context as IScopedContext;
    if (subpath) {
      return scoped.reload(
        query ? `${subpath}?${qsstringify(query)}` : subpath,
        ctx
      );
    }

    return super.reload(subpath, query, ctx, isItemAction);
  };

  receive = (values: any, subPath?: string) => {
    const scoped = this.context as IScopedContext;
    if (subPath) {
      return scoped.send(subPath, values);
    }

    return super.receive(values);
  };

  reloadTarget = (target: string, data: any) => {
    const scoped = this.context as IScopedContext;
    scoped.reload(target, data);
  };

  closeTarget = (target: string) => {
    const scoped = this.context as IScopedContext;
    scoped.close(target);
  };
}
