# MSearchAdvanced 高级搜索

- 来源：[E10 UI 组件库](https://www.e-cology.com.cn/ui/mobile/search-advanced/freepass)
- 平台：移动端
- 维护者：蒋贝贝
- Issue：http://gitlab.ecology10.cn/FRONTEND/weapp-ui/-/issues?state=all&search=[MSearchAdvanced]

## 代码演示

### 基础用法

直接引入组件进行使用

```jsx
import { Component } from 'react';
import {
  constants, MSearchAdvanced,
  FormItemProps, FormDatas, FormLayoutType, SearchDatas,
  SearchAdvancedStore, MSearchAdvancedProps, utils, SnapDataType,
  SelectValueType,
} from '@weapp/ui';
import { RouteComponentProps, withRouter } from 'react-router-dom';
import { request, RequestOptionConfig, RequestResult } from '@weapp/utils';

const prefixCls = `${constants.uiPcClsPrefix}-demo-searchAdvanced`;

const { formatParentPath } = utils;

const initItem: FormItemProps ={
  'input': {
    itemType: "INPUT",
    value: '1',
    rules: 'required',
    placeholder: '请输入',
  },
  'inputProp': {
    itemType: "SELECT",
    data: [
      { id: 'contain', content: '包含' },
      { id: 'ncontain', content: '不包含' },
    ],
    placeholder: '请选择',
    condition: true,
  },
  'select': {
    itemType: "SELECT",
    placeholder: '请选择',
    data: [
      { id: 'op1', content: '选项一' },
      { id: 'op2', content: '选项二' },
    ],
  },
  'text': {
    itemType: 'TEXTAREA',
    maxLength: 230,
    placeholder: '多行文本框',
    rows: 5,
  },
  'inputnumber': {
    itemType: 'INPUTNUMBER',
    passport: true
  },
  'radio': {
    itemType: "RADIO",
    fieldName: "苹果",
    form: true,
    data: [
      { id: 'op3', content: '单选1' },
      { id: 'op1', content: '单选2' },
    ],
  },
  'checkbox': {
    itemType: 'CHECKBOX',
    data: [
      { id: 'op1', content: '苹果' },
      { id: 'op2', content: '香蕉' },
      { id: 'op3', content: '橘子' }
    ],
    otherParams: {
      form: true,
      fieldName: "苹果",
    }
  },
  'rate': {
    itemType: 'RATE',
    otherParams: {
      label: '评分',
      isHoldRight: true,
    }
  },
  'rate_disabled': {
    itemType: 'RATE',
    disabled: true,
    otherParams: {
      label: '评分',
      isHoldRight: true,
    }
  },
  'date': {
    itemType: 'DATETIMEPICKER',
  },
  'switch': {
    itemType: 'SWITCH',
    value: true,
    otherParams: {
      isHoldRight: true,
    }
  },
  'scope': {
    itemType: 'SCOPE',
    placeholder: '请输入',
  },
  'browser': {
    itemType: 'BROWSER',
  },
  'typesBrowser': {
    itemType: 'TYPESBROWSER',
    typesBrowserBean: {
      type: 'hrm',
      module: 'hrm',
      options: [
        { id: "resource", content: "人员" },
        { id: "department", content: "部门" },
        { id: "subCompany", content: "分部" },
      ],
    }
  },
  'search': {
    itemType: 'INPUT',
  },
  'colorpicker': {
    itemType: 'COLORPICKER',
  },
  'colorpicker1': {
    itemType: 'COLORPICKER',
  },
  'colorpicker2': {
    itemType: 'COLORPICKER',
  },
  'colorpicker3': {
    itemType: 'COLORPICKER',
  },
  'custom': {
    itemType: 'CUSTOM', // CUSTOM为自定义的内容，数据及内部布局不在form内部处理
  },
  'upload': {
    itemType: 'UPLOAD',
    otherParams: {
      uploadParams: {
        module: "document"
      },
    },
  },
  'richtext': {
    itemType: 'RICHTEXT',
    otherParams: {
      id: "simpleDemoFormMobile_basic",
    },
  },
  'input_readonly': {
    itemType: 'INPUT',
    readOnly: true,
  },
  'select_disabled': {
    itemType: "SELECT",
    placeholder: '请选择',
    disabled: true,
    data: [
      { id: 'op1', content: '选项一' },
      { id: 'op2', content: '选项二' },
    ],
  },
  'money': {
    itemType: 'INPUT',
    placeholder: '请输入金额',
    otherParams: {
      type: 'money',
      moneyKeyboardAlign: "left",
      suffix: '人民币',
    }
  },
  'slider': {
    itemType: 'SLIDER',
  },
  'signature': {
    itemType: 'SIGNATURE',
    otherParams: {
      inForm: true,
    }
  },
  'iconselection': {
    itemType: 'ICONSELECTION',
  },
  'dateRange': {
    itemType: 'DATETIMEPICKER',
    otherParams: {
      isRange: true
    }
  },
  'filterButtons': {
    itemType: 'FILTERBUTTONS',
    data: [{ content: '上海上海上海', id: "shanghai" }, { content: '广州', id: "guangzhou" },
    { content: '深圳', id: "shenzhen" }, { content: '北京', id: "beijing" },
    { content: '西安西安西安西', id: "xian" }, { content: '南京', id: "nanjing" },
    { content: '武汉', id: "wuhan" }, { content: '邯郸', id: "handan" },
    { content: '郑州', id: "zhengzhou" }, { content: '苏州', id: "suzhou" }
    ],
  }
}
const initLayout: Array<FormLayoutType> = [
  [
    { id: '1', label: '单行文本', items: ['inputProp', 'input'], labelSpan:8, hide: false, classNames: "", groupId: 'commonGroup',  needQuickSearch: true },
  ],
  [
    { id: '2', label: '多行文本', items: ['text'], labelSpan:8, hide: false, groupId: 'commonGroup',  needQuickSearch: true },
  ],
  [
    { id: '3', label: '文本输入框', items: ['input'], labelSpan:8, hide: false, classNames: "", helpfulTip: '提示信息', groupId: 'commonGroup',  needQuickSearch: true },
  ],
  [
    { id: '4', label: '单选', items: ['radio'], labelSpan:8, hide: false, groupId: 'commonGroup',  needQuickSearch: true },
  ],
  [
    { id: '5', label: '复选', items: ['checkbox'], labelSpan:8, hide: false, groupId: 'commonGroup',  needQuickSearch: true },
  ],
  [
    { id: '6', label: '下拉选择框', items: ['select'], labelSpan:8, hide: false, groupId: 'commonGroup',  needQuickSearch: true },
  ],
  // [
  //   { id: '7', label: '单行文本(只读)', items: ['input_readonly'], labelSpan:8, hide: false, groupId: 'commonGroup',  needQuickSearch: true },
  // ],
  [
    { id: '8', label: '下拉框(禁用)', items: ['select_disabled'], labelSpan:8, hide: false, groupId: 'commonGroup',  needQuickSearch: true }
  ],
  [
    { id: '9', label: '数字输入', items: ['inputnumber'], labelSpan:8, hide: false, groupId: 'commonGroup',  needQuickSearch: true },
  ],
  [
    { id: '10', label: '请假时间', items: ['date'], labelSpan:8, hide: false,  groupId: 'commonGroup',  needQuickSearch: true},
  ],
  [
    { id: '11', label: '金额', items: ['money'], labelSpan:8, hide: false, groupId: 'commonGroup',  needQuickSearch: true },
  ],
  [
    { id: '12', label: '评分', items: ['rate'], labelSpan:8, hide: false,  groupId: 'commonGroup' },
  ],
  [
    { id: '13', label: '评分(禁用)', items: ['rate_disabled'], labelSpan:8, hide: false ,groupId: 'commonGroup' },
  ],
  [
    { id: '14', label: '开关', items: ['switch'], labelSpan: 8, hide: false, groupId: 'commonGroup' },
  ],
  [
    { id: '15', label: '区间', items: ['scope'], labelSpan:8, hide: false, groupId: 'commonGroup' },
  ],
  [
    { id: '16', label: '浏览框', items: ['browser'], labelSpan:8, hide: false,groupId: 'commonGroup'  },
  ],
  // [
  //   { id: '17', label: '搜索框', items: ['search'], labelSpan:8, hide: false, },
  // ],
  [
    { id: '18', label: '颜色选择器', items: ['colorpicker'], labelSpan:8, hide: false,groupId: 'commonGroup'  },
  ],
  // [
  //   { id: '19', label: '自定义组件', items: ['custom'], labelSpan:8, hide: false, },
  // ],
  [
    { id: '20', label: '上传', items: ['upload'], labelSpan:8, hide: false, groupId: 'commonGroup' },
  ],
  [
    { id: '21', label: '多类型浏览框', items: ['typesBrowser'], labelSpan:8, hide: false, groupId: 'commonGroup' },
  ],
  [
    { id: '22', label: '富文本', items: ['richtext'], labelSpan:8, hide: false, groupId: 'commonGroup' },
  ],
  [
    { id: '23', label: '滑块', items: ['slider'], labelSpan:8, hide: false, groupId: 'commonGroup'  },
  ],
  [
    { id: '24', label: '签批', items: ['signature'], labelSpan:8, hide: false, groupId: 'commonGroup'  },
  ],
  [
    { id: '25', label: '自定义图标选择', items: ['iconselection'], labelSpan:8, hide: false, groupId: 'commonGroup'  },
  ],
  [
    { id: '26', label: '日期范围', items: ['dateRange'], labelSpan:8, hide: false, groupId: 'commonGroup'  },
  ],
  [
    { id: '27', label: '筛选按钮', items: ['filterButtons'], labelSpan:8, hide: false, groupId: 'commonGroup'  },
  ],
  [
    { id: '28', label: '颜色选择器1', items: ['colorpicker1'], labelSpan:8, hide: false,groupId: 'commonGroup'  },
  ],
  [
    { id: '29', label: '颜色选择器2', items: ['colorpicker2'], labelSpan:8, hide: false,groupId: 'commonGroup'  },
  ],
  [
    { id: '30', label: '颜色选择器3', items: ['colorpicker3'], labelSpan:8, hide: false, groupId: 'commonGroup' },
  ],
]

const groups = [
  {
    "id": "commonGroup",
    "title": "常用分组",
    "visible": true,
    "custom": false
  },
  {
    "id": "otherGroup",
    "title": "其他条件",
    "visible": true,
    "custom": true
  },
]

interface MSearchAdvancedDemoProps extends RouteComponentProps, MSearchAdvancedProps {

}

class CustomTopContent extends Component<any> {
  render() {
    return (<div style={{ marginTop: 10, marginLeft: 24 }}>自定义内容</div>)
  }
}
class SearchAdvancedDemo extends Component<MSearchAdvancedDemoProps> {
  searchAdvancedStore: SearchAdvancedStore = new SearchAdvancedStore();
  fetchData = (options: RequestOptionConfig) => {
    // options内输出的url内容在network对应可抓到
    return request({
      ...options, headers: {
        ...options.headers,
        testHeaderId: '1',
      }
    });
  }
  componentDidMount() {
    // this.searchAdvancedStore.setVisible(true); // 默认展开面板或配置defaultVisible
    this.searchAdvancedStore.setState({ initAfterGetField: false }); // demo没有接口，临时屏蔽自定义行为
    setTimeout(() => {
      this.searchAdvancedStore.init({
        data: {
          inputProp: 'contain',
        }, items: initItem, layout: initLayout, groups, module: 'bcw', conditionId: '1',
        fetchData: this.fetchData
      })
    }, 1000);

  }

  onVisibleChange = (visible?: boolean) => { // 面板显示/隐藏状态切换回调事件
    console.log('onVisibleChange', visible);
  }

  // 搜索
  onSearch = (datas: SearchDatas) => console.log('onSearch', datas);

  // 重置
  onReset = (datas?: FormDatas) => console.log(datas);

  // 取消
  onCancel = () => { }

  onBlur = (value?: FormDatas, otherParams?: any) => {
    console.log('onBlur', value, otherParams);
  }
  onChange = (value?: FormDatas, otherParams?: any) => {
    console.log('onChange', value, otherParams);
  }
  afterSaveSnaps = (result: any) => { console.log('afterSaveSnaps', result) }
  afterDeleteSnaps = (result: any) => { console.log('afterDeleteSnaps', result) }
  onChooseSnap = (id: string, params: SnapDataType, datas: RequestResult<any>) => {
    this.searchAdvancedStore.commonFilterStore.updateSnapes(datas); // 更新表单
    this.props.history.go(-1);
    console.log('searchData', this.searchAdvancedStore.getSearchValue());
  }
  onRangeChange = (value: SelectValueType) => {
    console.log('onRangeChange', value);
  }
  render() {
    const conditionId = '1'; // 高级搜索唯一值
    // const menuData = [
    //   { id: 'tab1', content: '类型' },
    //   { id: 'tab2', content: '类别', children: [{ id: 'tab2_1', content: '子菜单' }] },
    // ]
    const searchBarProps = {
      // prepend: (
      //   <MMenu type='menu' data={menuData} value='tab1' expandKeys={[]} />
      // )
    }
    return (
      <div className={prefixCls}>
        <MSearchAdvanced
          onVisibleChange={this.onVisibleChange}
          className={"test"}
          module={'bcw'}
          conditionId={conditionId}
          searchAdvancedStore={this.searchAdvancedStore}
          onSearch={this.onSearch}
          searchBarProps={searchBarProps}
          // path="/ui/demo/searchadvanced/demo-0"
          path={formatParentPath(this.props as any)}
          needRange={true}
          onChange={this.onChange}
          onBlur={this.onBlur}
          // disableCommonFilter
          saveAsPublic
          setUseScope
          afterSaveSnaps={this.afterSaveSnaps}
          afterDeleteSnaps={this.afterDeleteSnaps}
          onChooseSnap={this.onChooseSnap} // 自定义常用筛选选中逻辑
          fetchData={this.fetchData}
          rangeSelectProps={{
            placeholder: '1',
          }}
          onRangeChange={this.onRangeChange}
          // hideSearchBtn={true}
          // buttons={[
          //   { id: 'reset', content: '自定义', onClick: this.onReset },
          // ]}
        />
      </div>
    );
  }
}

export default withRouter(SearchAdvancedDemo);
```

### 快捷搜索框(简易模式)

快捷搜索框(简易模式)，不耦合表单数据

```jsx
import { Component } from 'react';
import {
  constants, MSearchAdvanced, FormDatas, SearchDatas,
  SearchAdvancedStore, MSearchAdvancedProps, utils,
} from '@weapp/ui';
import { RouteComponentProps, withRouter } from 'react-router-dom';

const prefixCls = `${constants.uiPcClsPrefix}-demo-searchAdvanced`;
const { formatParentPath } = utils;

interface MSearchAdvancedDemoProps extends RouteComponentProps, MSearchAdvancedProps {

}
class SearchAdvancedDemo extends Component<MSearchAdvancedDemoProps> {
  searchAdvancedStore: SearchAdvancedStore = new SearchAdvancedStore();
  componentDidMount() {
    const apiTimeout = setTimeout(() => { // 模拟接口
      this.searchAdvancedStore.setState({ initAfterGetField: false }); // demo没有接口，临时屏蔽自定义行为
      this.searchAdvancedStore.init({
        data: {}, items: {}, layout: [], groups: [], module: 'common', conditionId: '1',
      })
      if (apiTimeout) clearTimeout(apiTimeout);
    }, 500);
  }
  // 搜索
  onSearch = (datas: SearchDatas) => console.log('onSearch', datas);

  render() {
    const conditionId = '1'; // 高级搜索唯一值
    const searchBarProps = {
      suffix: null,
      placeholder: '请输入'
    }

    return (
      <div className={prefixCls}>
        <MSearchAdvanced
          className={"test"}
          module={'common'}
          conditionId={conditionId}
          searchAdvancedStore={this.searchAdvancedStore}
          onSearch={this.onSearch}
          searchBarProps={searchBarProps}
          path={formatParentPath(this.props as any)}
          quickSearchKey="test"
          disableHistorySearch={true}
          disableCommonFilter={true}
        />
      </div>
    );
  }
}

export default withRouter(SearchAdvancedDemo);
```

### 搜索面板

直接返回搜索面板:开启参数 hiddenQuickSearch , usePanel={true}

```jsx
import { Component } from 'react';
import {
  constants, MSearchAdvanced,
  FormItemProps, FormDatas, FormLayoutType, SearchDatas,
  SearchAdvancedStore, MSearchAdvancedProps, utils, SnapDataType,
} from '@weapp/ui';
import { RouteComponentProps, withRouter } from 'react-router-dom';
import { request, RequestOptionConfig, RequestResult } from '@weapp/utils';

const prefixCls = `${constants.uiPcClsPrefix}-demo-searchAdvanced`;

const { formatParentPath } = utils;

const initItem: FormItemProps ={
  'input': {
    itemType: "INPUT",
    value: '1',
    rules: 'required',
    placeholder: '请输入',
  },
  'inputProp': {
    itemType: "SELECT",
    data: [
      { id: 'contain', content: '包含' },
      { id: 'ncontain', content: '不包含' },
    ],
    placeholder: '请选择',
  },
  'select': {
    itemType: "SELECT",
    placeholder: '请选择',
    data: [
      { id: 'op1', content: '选项一' },
      { id: 'op2', content: '选项二' },
    ],
  },
  'text': {
    itemType: 'TEXTAREA',
    maxLength: 230,
    placeholder: '多行文本框',
    rows: 5,
  },
  'inputnumber': {
    itemType: 'INPUTNUMBER',
    passport: true
  },
  'radio': {
    itemType: "RADIO",
    fieldName: "苹果",
    form: true,
    data: [
      { id: 'op3', content: '单选1' },
      { id: 'op1', content: '单选2' },
    ],
  },
  'checkbox': {
    itemType: 'CHECKBOX',
    data: [
      { id: 'op1', content: '苹果' },
      { id: 'op2', content: '香蕉' },
      { id: 'op3', content: '橘子' }
    ],
    otherParams: {
      form: true,
      fieldName: "苹果",
    }
  },
  'rate': {
    itemType: 'RATE',
    otherParams: {
      label: '评分',
      isHoldRight: true,
    }
  },
  'rate_disabled': {
    itemType: 'RATE',
    disabled: true,
    otherParams: {
      label: '评分',
      isHoldRight: true,
    }
  },
  'date': {
    itemType: 'DATETIMEPICKER',
  },
  'switch': {
    itemType: 'SWITCH',
    value: true,
    otherParams: {
      isHoldRight: true,
    }
  },
  'scope': {
    itemType: 'SCOPE',
    placeholder: '请输入',
  },
  'browser': {
    itemType: 'BROWSER',
  },
  'typesBrowser': {
    itemType: 'TYPESBROWSER',
    typesBrowserBean: {
      type: 'hrm',
      module: 'hrm',
      options: [
        { id: "resource", content: "人员" },
        { id: "department", content: "部门" },
        { id: "subCompany", content: "分部" },
      ],
    }
  },
  'search': {
    itemType: 'INPUT',
  },
  'colorpicker': {
    itemType: 'COLORPICKER',
  },
  'colorpicker1': {
    itemType: 'COLORPICKER',
  },
  'colorpicker2': {
    itemType: 'COLORPICKER',
  },
  'colorpicker3': {
    itemType: 'COLORPICKER',
  },
  'custom': {
    itemType: 'CUSTOM', // CUSTOM为自定义的内容，数据及内部布局不在form内部处理
  },
  'upload': {
    itemType: 'UPLOAD',
    otherParams: {
      uploadParams: {
        module: "document"
      },
    },
  },
  'richtext': {
    itemType: 'RICHTEXT',
    otherParams: {
      id: "simpleDemoFormMobile_basic",
    },
  },
  'input_readonly': {
    itemType: 'INPUT',
    readOnly: true,
  },
  'select_disabled': {
    itemType: "SELECT",
    placeholder: '请选择',
    disabled: true,
    data: [
      { id: 'op1', content: '选项一' },
      { id: 'op2', content: '选项二' },
    ],
  },
  'money': {
    itemType: 'INPUT',
    placeholder: '请输入金额',
    otherParams: {
      type: 'money',
      moneyKeyboardAlign: "left",
      suffix: '人民币',
    }
  },
  'slider': {
    itemType: 'SLIDER',
  },
  'signature': {
    itemType: 'SIGNATURE',
    otherParams: {
      inForm: true,
    }
  },
  'iconselection': {
    itemType: 'ICONSELECTION',
  },
  'dateRange': {
    itemType: 'DATETIMEPICKER',
    otherParams: {
      isRange: true
    }
  },
  'filterButtons': {
    itemType: 'FILTERBUTTONS',
    data: [{ content: '上海上海上海', id: "shanghai" }, { content: '广州', id: "guangzhou" },
    { content: '深圳', id: "shenzhen" }, { content: '北京', id: "beijing" },
    { content: '西安西安西安西', id: "xian" }, { content: '南京', id: "nanjing" },
    { content: '武汉', id: "wuhan" }, { content: '邯郸', id: "handan" },
    { content: '郑州', id: "zhengzhou" }, { content: '苏州', id: "suzhou" }
    ],
  }
}
const initLayout: Array<FormLayoutType> = [
  [
    { id: '2', label: '多行文本', items: ['text'], labelSpan:8, hide: false, groupId: 'commonGroup',  needQuickSearch: true },
  ],
  [
    { id: '3', label: '文本输入框', items: ['input'], labelSpan:8, hide: false, classNames: "", helpfulTip: '提示信息', groupId: 'commonGroup',  needQuickSearch: true },
  ],
  [
    { id: '4', label: '单选', items: ['radio'], labelSpan:8, hide: false, groupId: 'commonGroup',  needQuickSearch: true },
  ],
  [
    { id: '5', label: '复选', items: ['checkbox'], labelSpan:8, hide: false, groupId: 'commonGroup',  needQuickSearch: true },
  ],
  [
    { id: '6', label: '下拉选择框', items: ['select'], labelSpan:8, hide: false, groupId: 'commonGroup',  needQuickSearch: true },
  ],
  // [
  //   { id: '7', label: '单行文本(只读)', items: ['input_readonly'], labelSpan:8, hide: false, groupId: 'commonGroup',  needQuickSearch: true },
  // ],
  [
    { id: '8', label: '下拉框(禁用)', items: ['select_disabled'], labelSpan:8, hide: false, groupId: 'commonGroup',  needQuickSearch: true }
  ],
  [
    { id: '1', label: '单行文本', items: ['inputProp', 'input'], labelSpan:8, hide: false, classNames: "", groupId: 'commonGroup',  needQuickSearch: true },
  ],
  [
    { id: '9', label: '数字输入', items: ['inputnumber'], labelSpan:8, hide: false, groupId: 'commonGroup',  needQuickSearch: true },
  ],
  [
    { id: '10', label: '请假时间', items: ['date'], labelSpan:8, hide: false,  groupId: 'commonGroup',  needQuickSearch: true},
  ],
  [
    { id: '11', label: '金额', items: ['money'], labelSpan:8, hide: false, groupId: 'commonGroup',  needQuickSearch: true },
  ],
  [
    { id: '12', label: '评分', items: ['rate'], labelSpan:8, hide: false,  groupId: 'commonGroup' },
  ],
  [
    { id: '13', label: '评分(禁用)', items: ['rate_disabled'], labelSpan:8, hide: false ,groupId: 'commonGroup' },
  ],
  [
    { id: '14', label: '开关', items: ['switch'], labelSpan: 8, hide: false, groupId: 'commonGroup' },
  ],
  [
    { id: '15', label: '区间', items: ['scope'], labelSpan:8, hide: false, groupId: 'commonGroup' },
  ],
  [
    { id: '16', label: '浏览框', items: ['browser'], labelSpan:8, hide: false,groupId: 'commonGroup'  },
  ],
  // [
  //   { id: '17', label: '搜索框', items: ['search'], labelSpan:8, hide: false, },
  // ],
  [
    { id: '18', label: '颜色选择器', items: ['colorpicker'], labelSpan:8, hide: false,groupId: 'commonGroup'  },
  ],
  // [
  //   { id: '19', label: '自定义组件', items: ['custom'], labelSpan:8, hide: false, },
  // ],
  [
    { id: '20', label: '上传', items: ['upload'], labelSpan:8, hide: false, groupId: 'commonGroup' },
  ],
  [
    { id: '21', label: '多类型浏览框', items: ['typesBrowser'], labelSpan:8, hide: false, groupId: 'commonGroup' },
  ],
  [
    { id: '22', label: '富文本', items: ['richtext'], labelSpan:8, hide: false, groupId: 'commonGroup' },
  ],
  [
    { id: '23', label: '滑块', items: ['slider'], labelSpan:8, hide: false, groupId: 'commonGroup'  },
  ],
  [
    { id: '24', label: '签批', items: ['signature'], labelSpan:8, hide: false, groupId: 'commonGroup'  },
  ],
  [
    { id: '25', label: '自定义图标选择', items: ['iconselection'], labelSpan:8, hide: false, groupId: 'commonGroup'  },
  ],
  [
    { id: '26', label: '日期范围', items: ['dateRange'], labelSpan:8, hide: false, groupId: 'commonGroup'  },
  ],
  [
    { id: '27', label: '筛选按钮', items: ['filterButtons'], labelSpan:8, hide: false, groupId: 'commonGroup'  },
  ],
  [
    { id: '28', label: '颜色选择器1', items: ['colorpicker1'], labelSpan:8, hide: false,groupId: 'commonGroup'  },
  ],
  [
    { id: '29', label: '颜色选择器2', items: ['colorpicker2'], labelSpan:8, hide: false,groupId: 'commonGroup'  },
  ],
  [
    { id: '30', label: '颜色选择器3', items: ['colorpicker3'], labelSpan:8, hide: false, groupId: 'commonGroup' },
  ],
]

const groups = [
  {
    "id": "commonGroup",
    "title": "常用分组",
    "visible": true,
    "custom": false
  },
  {
    "id": "otherGroup",
    "title": "其他条件",
    "visible": true,
    "custom": true
  },
]

interface MSearchAdvancedDemoProps extends RouteComponentProps, MSearchAdvancedProps {

}

class CustomTopContent extends Component<any> {
  render() {
    return (<div style={{ marginTop: 10, marginLeft: 24 }}>自定义内容</div>)
  }
}
class SearchAdvancedDemo extends Component<MSearchAdvancedDemoProps> {
  searchAdvancedStore: SearchAdvancedStore = new SearchAdvancedStore();
  fetchData = (options: RequestOptionConfig) => {
    // options内输出的url内容在network对应可抓到
    return request({
      ...options, headers: {
        ...options.headers,
        testHeaderId: '1',
      }
    });
  }
  componentDidMount() {
    // this.searchAdvancedStore.setVisible(true); // 默认展开面板或配置defaultVisible
    // this.searchAdvancedStore.setState({ initAfterGetField: false }); // demo没有接口，临时屏蔽自定义行为
    setTimeout(() => {
      this.searchAdvancedStore.init({
        data: {
          inputProp: 'contain',
        }, items: initItem, layout: initLayout, groups, module: 'bcw', conditionId: '1',
        fetchData: this.fetchData
      })
    }, 1000);

  }

  onVisibleChange = (visible?: boolean) => { // 面板显示/隐藏状态切换回调事件
    console.log('onVisibleChange', visible);
  }

  // 搜索
  onSearch = (datas: SearchDatas) => console.log('onSearch', datas);

  // 重置
  onReset = (datas?: FormDatas) => console.log(datas);

  // 取消
  onCancel = () => { }

  onBlur = (value?: FormDatas, otherParams?: any) => {
    console.log('onBlur', value, otherParams);
  }
  onChange = (value?: FormDatas, otherParams?: any) => {
    console.log('onChange', value, otherParams);
  }
  afterSaveSnaps = (result: any) => { console.log('afterSaveSnaps', result) }
  afterDeleteSnaps = (result: any) => { console.log('afterDeleteSnaps', result) }
  onChooseSnap = (id: string, params: SnapDataType, datas: RequestResult<any>) => {
    this.searchAdvancedStore.commonFilterStore.updateSnapes(datas); // 更新表单
    this.props.history.go(-1);
    console.log('searchData', this.searchAdvancedStore.getSearchValue());
  }
  render() {
    const conditionId = '1'; // 高级搜索唯一值
    // const menuData = [
    //   { id: 'tab1', content: '类型' },
    //   { id: 'tab2', content: '类别', children: [{ id: 'tab2_1', content: '子菜单' }] },
    // ]
    const searchBarProps = {
      // prepend: (
      //   <MMenu type='menu' data={menuData} value='tab1' expandKeys={[]} />
      // )
    }
    return (
      <div className={prefixCls}>
        <MSearchAdvanced
          hiddenQuickSearch
          usePanel={true}
          onVisibleChange={this.onVisibleChange}
          className={"test"}
          module={'bcw'}
          conditionId={conditionId}
          searchAdvancedStore={this.searchAdvancedStore}
          onSearch={this.onSearch}
          searchBarProps={searchBarProps}
          // path="/ui/demo/searchadvanced/demo-0"
          path={formatParentPath(this.props as any)}
          needRange={true}
          onChange={this.onChange}
          onBlur={this.onBlur}
          // disableCommonFilter
          saveAsPublic
          setUseScope
          afterSaveSnaps={this.afterSaveSnaps}
          afterDeleteSnaps={this.afterDeleteSnaps}
          onChooseSnap={this.onChooseSnap} // 自定义常用筛选选中逻辑
          fetchData={this.fetchData}
          rangeSelectProps={{
            placeholder: '1',
          }}
          // buttons={[
          //   { id: 'reset', content: '自定义', onClick: this.onReset },
          // ]}
        />
      </div>
    );
  }
}

export default withRouter(SearchAdvancedDemo);
```

## API

### 参数说明如下：

##### groups、items、layout 、data 数据格式与 Form 组件相同

| 参数 | 说明 | 类型 | 是否必填 | 默认值 |
| --- | --- | --- | --- | --- |
| searchAdvancedStore | 高级搜索 store | SearchAdvancedStore |  |  |
| onVisibleChange | 面板显示隐藏的回调 | (visible?: boolean) => void |  |  |
| needRange | 是否需要筛选条件范围 | boolean |  |  |
| onSearch | 搜索事件 | (data: SearchDatas ) => void |  |  |
| onReset | 重置事件 | (data?: FormDatas) => void |  |  |
| onCancel | 取消事件 | (data?: FormDatas) => void |  |  |
| conditionId | 高级搜索唯一标识 | string | 是 |  |
| searchBarProps | 搜索栏组件配置 | MSearchBarProps | 否 |  |
| module | 高级搜索模块接口标识 | string | 是 |  |
| requestHeaderParams | 高级搜索模块接口headers参数 | AnyObj | 是 |  |
| onChange | 字段值改变事件 | (value?: FormDatas, otherParams?: any) => void | 否 |  |
| onBlur | 字段值失去焦点事件 | (value?: FormDatas, otherParams?: any) => void | 否 |  |
| formProps | 表单自定义属性设置 | FormCustomProps | 否 |  |
| disableHistorySearch | 屏蔽历史搜索功能 | boolean | 否 |  |
| disableCommonFilter | 屏蔽常用筛选功能 | boolean | 否 |  |
| needRange | 是否需要满足全部/任一条件选项 | boolean | 否 |  |
| saveAsPublic | 启用常用筛选存为公用功能 | boolean | 否 | false |
| saveAsDefault | 启用常用筛选存为默认功能 | boolean | 否 | false |
| currentModule | 指定当前模块（公用常用筛选权限校验, 对应window.TEAMS.modules） | string | 否 |  |
| setUseScope | 启用常用筛选使用范围功能 | boolean | 否 |  |
| disableQuickSearchSetting | 屏蔽快捷搜索字段设置功能 | boolean | 否 |  |
| afterPressEnter | 搜索框回车事件 | () => void | 否 |  |
| afterSaveSnaps | 保存常用筛选回调事件 | (result: any, otherParams: any) => void | 否 |  |
| afterDeleteSnaps | 保存常用筛选回调事件 | (result: any) => void | 否 |  |
| onlyShowIcon | 快捷搜索输入框仅展示图标 | boolean | 否 |  |
| disabledCustomDateSaveFormat | 禁用自定义日期保存格式功能 | boolean | 否 | true |
| buttons | 自定义底部按钮组 | MDialogButtonProps[] | 否 | \  |
| disabledCommonConditionSetting | 禁用常用条件设置功能 | boolean | 否 |  |
| quickSearchPlaceHolder | 快捷搜索提示信息（简易模式可设置） | string | 否 |  |
| onChooseSnap | 常用筛选项自定义选中回调事件 | (id: string, params: SnapDataType, datas: RequestResult<any>)  => void | 否 |  |
| unChooseSnap | 常用筛选项自定义取消选中回调事件 | (id: string, params: SnapDataType)  => void | 否 |  |
| historicalSearchExtras | 历史搜索额外内容 | historicalSearchExtras?: ReactNode \| (() => ReactNode) | 否 |  |
| customRenderRange | 自定义渲染条件范围设置区 | (_: any, ele: ReactNode) => ReactNode | 否 |  |
| fetchData | 自定义请求数据 | (options: RequestOptionConfig) => RequestPromise | 否 |  |
| usePanel | 是否使用面板组件 | boolean | 否 | false |
| panelName | 自定义搜索面板路由 | string | 否 |  |
| panelTitle | 自定义搜索面板标题 | ReactNode | 否 |  |
| historicalSearchInputProps | 历史搜索页面输入框自定义属性设置 | InputProps | 否 |  |
| hideCondition | 隐藏条件关系字段 | boolean | 否 |  |
| name | 自定义图标 | IconNames | 否 |  |
| useOnDemandRequest | 是否使用按需请求数据 | boolean | 否 | false |
| hideSearchBtn | 隐藏搜索按钮 | boolean | 否 | true |
| onRangeChange | 自定义条件范围选项更新回调事件 | (value: SelectValueType) => void | 否 |  |
| rangeSelectProps | 自定义条件范围选择组件配置 | SelectProps | 否 |  |
#### SearchAdvanced Store API 说明

| 参数 | 说明 | 类型 | 是否必填 | 默认值 |
| --- | --- | --- | --- | --- |
| init | 初始化高级搜索面板 | (allDatas: SearchAdvancedInitAllDatas) => Promise | 是 |  |
| getSearchValue | 获取高级搜索面板数据 |  |  |  |
| filterUselessDatas | 过滤不展示的datas数据(用于getSearchValue) | boolean | 否 | true |
| setState | 更新store内参数 | (params: Partial) => void | 否 |  |
#### SearchAdvanced Store 实例化属性

| 参数 | 说明 | 类型 | 是否必填 | 默认值 |
| --- | --- | --- | --- | --- |
| setSnapSavingCondition | 设置常用筛选保存条件(能否触发保存) | ((store: SearchAdvancedStoreType) => boolean) \| undefined | 否 |  |
##### filterUselessDatas具体说明

```
1.filterUselessDatas默认为true，作用于getSearchValue方法
2.filterUselessDatas为true，getSearchValue方法返回的数据会过滤掉当前布局未展示的字段值
3.如业务有需求搜索时需带出当前未展示的数据，可通过setState({ filterUselessDatas: false })修改默认配置
```

#### SearchAdvancedInitAllDatas 说明

```
interface SearchAdvancedInitAllDatas extends FormInitAllDatas {
  module: string,
  conditionId: string,
  requestHeaderParams?: AnyObj;
  layout: Array<SearchAdvancedFormLayoutType>,
  fetchData?: (options: RequestOptionConfig) => RequestPromise;
}
SearchAdvancedInitAllDatas继承FormInitAllDatas的所有配置，与Form组件一致，需要layout、items、groups、data，另新增module(模块标识)、conditionId(高级搜索标识)、requestHeaderParams(接口headers参数)、fetchData(自定义请求数据)
```

#### 一、layout 及 items 需支持配置字段别名及自定义参数集合

##### layout、items、group、data 参数配置基本规则与 Form 组件一致，新增特性如下：

##### layout 仅支持别名配置

```
通过customParameterName配置layout的别名
[
  [
    { id: '1', label: '单行文本', items: ['inputProp', 'input'], labelSpan: 6, groupId: 'g1', hide: false, needQuickSearch: true, customParameterName: 'title' },
  ]
]
```

##### items 支持配置字段别名及自定义参数集合

```
通过customParameterName配置items的别名，通过customParameters设置items的自定义参数集合
{
  'input': {
    itemType: "INPUT",
    customParameterName: 'wfTitle',
    customParameters: {
      specialValue: '1',
    }
  }
}
```

#### 二、layout 数据中设置 custom=true，表示该字段仅在其他搜索条件内出现

#### 三、关于高级搜索布局样式处理

```
1.常用分组需实现删除常用条件设置项，实现各条件自动补位，可通过配置布局处理，具体请参考demo。仅需将常用分组的所有布局放置一个数组内即可，通过colSpan来处理布局
2.高级搜索包含/不包含等条件项，需在对应的items配置中设置condition: true，代表该字段为条件关系(条件关系在高级搜索判空处理时会视作非高级搜索条件字段)
3.常用分组的groupId必须为commonGroup，请按照后端接口规定处理
```

#### 四、关于高级搜索表单重置功能的说明

```
1、一般情况重置：支持表单恢复到初始化状态(与Form一致)
2、选中高级搜索数据时重置：恢复到选中常用筛选的情况，即重置后展现为当前选中的常用筛选保存的布局和数据，非默认初始化布局和数据。
3、高级搜索快捷输入框右边的图标说明：
（1）颜色区分：默认颜色代表表单面板未展示，蓝色代表面板展示。对于移动端，能够看到图标的均为未打开面板的情况，因此颜色也用作区分表单值是否被改变功能。
（2）图标区分：图标用于区分当前表单字段值是否有被改变，即不同于默认值。
```

#### 五、关于高级搜索老数据兼容方案

注意：前端组件仅提供布局转换方案，数据转换需接口配合处理

```
1.转换方法统一在searchAdvancedStore.transDatasStore内实现
2.transOldDatas方法：et高级搜索常用筛选老数据转换(仅处理布局) 
  2.1 et 老数据格式例子
    {
      createTimes: [ // createTimes --- layout的id
        { value: ['2021-07-01'] } // value ---- items的key
      ]
    }
  2.2 老数据转换后会自动调用内部的saveOldData方法，存储数据至常用筛选(主要用于常用筛选)，若不需要，则第二个参数(disabledUpdateData)传true
3.transCustomLayout方法：常用筛选自定义布局转换
  3.1常用筛选保存默认layout、items、groups及所有的datas数据
  3.2数据量过大，影响接口速度，则自定义布局从datas内推
  3.3自定义布局指分组custom=true对应的layout布局
  3.4若业务转换的老数据格式与常用筛选默认布局格式一致，则可采用该方法生成其他条件组的自定义布局
  3.5该方法返回生存的其他条件组布局及当前最新的items，因此调用者需自行更新当前表单
    const {
       searchAdvancedStore: {
        formStore: { initForm, setAllCustomLayout },
        transDatasStore: { transCustomLayout },
      },
    } = this.props;
    const { customLayout, items } = transCustomLayout(content); // 转换布局
    initForm({ ...content, items }); // 初始化表单
    customLayout && setAllCustomLayout(customLayout, true); // 更新其他条件组自定义布局
```

#### searchAdvancedStore.transDatasStore API说明

| 参数 | 说明 | 类型 | 是否必填 | 默认值 |
| --- | --- | --- | --- | --- |
| transOldDatas | et高级搜索常用筛选老数据转换(仅处理布局) | (oldDatas: AnyObj, disabledUpdateData?: boolean) => void | 否 |  |
| transCustomLayout | 常用筛选自定义布局转换 | (content: FormInitAllDatas) => { customLayout, items } | 否 |  |
| enableLatestFormConfig | 是否启用最新布局及字段配置(用于常用筛选数据回显) | boolean | 否 | 默认存为版本 |
##### enableLatestFormConfig说明

```
1.用于常用筛选数据回显
2.默认常用筛选数据存为版本，再次选择时布局及字段配置（layout、items）数据为当时保存的内容
3.通过searchAdvancedStore.transDatasStore.setState({ enableLatestFormConfig: true }) 启用最新布局及字段配置后，选中常用筛选，数据展示以当前最新的默认布局及字段配置为准
4.使用场景：如高级搜索保存常用后修改字段名称(layout配置中的label参数)，之后再查看常用条件的字段名称需显示当前最新的字段名称
```

#### 六、关于高级搜索conditionId、module、requestHeaderParams和fetchData的设置说明

```
一、组件结构简单介绍
1.高级搜索组件内部拆分多个小组件，每个组件处理独立的需求，但各个组件内部数据有关联，因此通过searchAdvancedStore统一管理
2.保存常用条件排序、默认显示等用户自定义行为的请求与初始化高级搜索表单之前处理，因此于searchAdvancedStore.init方法内处理

二、关于conditionId的使用
1.业务层面使用，conditionId为接口返回，存在首次获取历史搜索记录及常用筛选数据不准确的问题(未能在didmount的时候获取conditionId)。
  因此组件内部做了受控，当传给组件的conditionId前后有变化后，会更新conditionId，并重新获取历史搜索记录及常用筛选数据。

三、由于用户自定义行为的接口需要module及conditionId，因此，处理通过props传入module、conditionId，init方法内部也需要传入相应的参数

四、requestHeaderParams和fetchData同module
```

#### searchAdvancedStore.commonFilterStore API说明

| 参数 | 说明 | 类型 | 是否必填 | 默认值 |
| --- | --- | --- | --- | --- |
| needSaveSearchValue | 常用筛选存储searchValue数据 | boolean | 否 | false |
| snapCustomData | 常用筛选保存自定义数据 | any | 否 |  |
| setState | 更新数据 | (params: Partial<CommonFilterStoreType>) => void | 否 |  |
| checkSnaps | 选中常用筛选数据 | (id: string) => Promise<any> | 否 |  |
| unCheckSnaps | 取消选中常用筛选 | () => void | 否 |  |
