import React from 'react';
import { Row, Col, Modal, Input, Button, Field, createEasyForm, Select, DatePicker, TagSelect, RadioGroup, Radio, CheckboxGroup, Checkbox, AutoComplete, Upload } from 'neatui';
import xhr from 'SERVICE/xhr';
import Axios from 'axios';
import QS from 'querystring';
import './index.scss';
import { error, success } from 'UTIL/notification';
import BaseComponent from 'COMPONENT/common/BaseComponent';
import { isArray, getSearchParams, parseData2Url, isImage, setDefaultValue, getBLen, parseFixedParameter } from 'UTIL/util';
import PropTypes from 'prop-types';
import projectConfig from 'CONFIG/projectConfig.json';
import moment from 'moment';
import TreeSelect from 'COMPONENT/common/TreeSelect/TreeSelect';
import 'moment/locale/zh-cn';

const localHost = projectConfig.localhost || [];
localHost.push('localhost');

class Searchtableactionmodal extends BaseComponent {
    propTypes = {
        mode: PropTypes.string.isRequired,
        config: PropTypes.objectOf.isRequired,
        formData: PropTypes.objectOf.isRequired,
        submit: PropTypes.func.isRequired,
        updateFieldValue: PropTypes.func.isRequired
    }

    constructor (props, context) {
        super(props, context);
        this.env = localHost.indexOf(window.location.hostname) > -1 ? 'local.' : '';
        this.searchParams = getSearchParams();
        const { mode, config } = this.props;
        this.config = config || {};
        const forms = this.completionForms(mode);
        const defaultValueMap = {};
        const disabledMap = {};
        const placeholderMap = {};
        const helperTextMap = {};
        const formDataType = {};
        const formMap = {};
        for (let i = 0; i < forms.length; i+=1) {
            const item = forms[i];
            formMap[item.key] = item;
            defaultValueMap[item.key] = setDefaultValue(item.defaultValue);
            placeholderMap[item.key] = item.placeholder || '';
            helperTextMap[item.key] = item.helperText || '';
            disabledMap[item.key] = item.notModify || false;
            formDataType[item.key] = {
                type: item.type,
                ajaxType: item.ajaxType,
                format: item.format
            }
            // TODO 这里需要支持group和groups解析
        }
        this.state = {
            showModal: true,
            mode,
            forms,
            defaultDataMap: {},
            formMap,
            defaultValueMap,
            disabledMap,
            placeholderMap,
            helperTextMap,
            suggest: {},
            formDataType,
            more: {}
        };
    };

    componentDidMount () {
        const mine = this;
        const { updateFieldValue, formData } = this.props;
        const { mode, forms, defaultValueMap, formMap } = mine.state;
        mine.initForm();
        const dataKeys = mine.config[mode] && mine.config[mode].data && mine.config[mode].data.key;
        if (dataKeys) {
            const configParams = {};
            if (isArray(dataKeys)) {
                for (let i = 0; i < dataKeys.length; i += 1) {
                    configParams[dataKeys[i]] = setDefaultValue({...(mine.searchParams || {}), ...(formData || {})}[dataKeys[i]]);
                }
            } else {
                configParams[dataKeys] = setDefaultValue({...(mine.searchParams || {}), ...(formData || {})}[dataKeys]);
            }
            mine.fetchDataHandler(configParams, (data) => {
                for (let i = 0; i < forms.length; i+=1) {
                    const item = forms[i];
                    if (item.nextKey && item.type === 'radio') {
                        mine.radioChange(data[item.key] || item.defaultValue || '', item);
                    }
                    if (!item[`${mine.env}url`] && !item[`${mine.env}nextUrl`]) continue;
                    if (item.type === 'suggest') {
                        mine.inputSuggest(data[item.key] || defaultValueMap[item.key], item);
                    }
                    mine.getSearchFormListHandler(item, data);
                    if (item.nextKey) mine.getSonData(item, data[item.key] || defaultValueMap[item.key]);
                    if (item.nextKeys) {
                        item.nextKeys.map(nextItem => mine.getSearchFormListHandler(formMap[nextItem], data));
                    }
                }
            });
        } else if ((this.config[mode] && this.config[mode].data && this.config[mode].data.type === 'cache' && formData)
        || (this.config[mode] && this.config[mode].setsearch === true && formData)) {
            for (let i = 0; i < forms.length; i+=1) {
                const key = forms[i].key || '';
                if (key) {
                    updateFieldValue(key, formData[key]);
                }
            }
            for (let i = 0; i < forms.length; i+=1) {
                const item = forms[i];
                if (!item[`${mine.env}url`] && !item[`${mine.env}nextUrl`]) continue;
                if (!item.notInit) mine.getSearchFormListHandler(item);
                if (item.nextKey) mine.getSonData(item, defaultValueMap[item.key]);
                if (item.nextKeys) {
                    item.nextKeys.map(nextItem => mine.getSearchFormListHandler(formMap[nextItem]))
                }
            }
        } else {
            for (let i = 0; i < forms.length; i+=1) {
                const item = forms[i];
                if (!item[`${mine.env}url`] && !item[`${mine.env}nextUrl`]) continue;
                if (!item.notInit) mine.getSearchFormListHandler(item);
                if (item.nextKey) mine.getSonData(item, defaultValueMap[item.key]);
                if (item.nextKeys) {
                    item.nextKeys.map(nextItem => mine.getSearchFormListHandler(formMap[nextItem]))
                }
            }
        }
    };

    initForm = () => {
        const { updateFieldValue } = this.props;
        const { forms, defaultValueMap } = this.state;
        for (let i = 0; i < forms.length; i+=1) {
            const item = forms[i] || {};
            if (item.key) {
                if (item.type === 'datepicker') {
                    updateFieldValue(item.key, (defaultValueMap[item.key] ? moment().subtract(item.defaultValue, 'days') : ''));
                } else {
                    updateFieldValue(item.key, defaultValueMap[item.key]);
                }
            }
        }
    }

    getSearchFormListHandler = (itemParam, formData) => {
        if (itemParam.notInit) return;
        const postData = {};
        if(itemParam.controled && formData) {
            for (let j = 0; j < item.controled.length; j+=1) {
                postData[itemParam.controled[j].ajaxKey] = setDefaultValue(formData[itemParam.controled[j].valueKey]);
            }
        }
        const mine = this;
        // TODO  关于more的需要重新梳理一下
        const item = JSON.parse(JSON.stringify(itemParam));
        const locationSearch = {};
        if (item.isNeedLocationSearch && isArray(item.isNeedLocationSearch)) {
            for (let i = 0; i < item.isNeedLocationSearch.length; i+=1) {
                const key = item.isNeedLocationSearch[i];
                locationSearch[key] = mine.searchParams[key];
            }
        }
        const { url, data } = parseData2Url({
            ...parseFixedParameter(mine.config.fixedParameter),
            ...parseFixedParameter(item.fixedParameter) || {},
            ...locationSearch,
            ...(postData || {})
        }, item[`${this.env}url`], item.accept, item.urlParams);
        if (url) {
            xhr({
                url,
                method: item.method || 'get',
                data,
                type: 'json',
                contentType: item.contentType,
                notSwitchArrToStr: item.notSwitchArrToStr
            }).then((rs) => {
                if (rs[projectConfig.codeKey] === projectConfig.code) {
                    const cloneState = JSON.parse(JSON.stringify(mine.state));
                    const { defaultDataMap, suggest, more } = cloneState;
                    let responData = [];
                    const { key } = item;
                    if (item.type === 'suggest') {
                        suggest[key] = rs.data || [];
                    } else if (item.responseKey) {
                        if (item.listStr === true) {
                            defaultDataMap[key] = rs.data[item.responseKey] && isArray(rs.data[item.responseKey]) ? rs.data[item.responseKey].map(dItem => { return { "id": dItem, "name": dItem } }) : [];
                        } else {
                            responData = rs.data[item.responseKey] && isArray(rs.data[item.responseKey]) ? rs.data[item.responseKey] : [];
                        }
                    } else if (item.listStr === true) {
                        defaultDataMap[key] = rs.data && isArray(rs.data) ? rs.data.map(dItem => { return { "id": dItem, "name": dItem } }) : [];
                    } else {
                        responData = rs.data && isArray(rs.data) ? rs.data : [];
                    }
                    if (item.moreKey && !item.listStr) {
                        const dData = [];
                        const mData = [];
                        for (let att = 0; att < responData.length; att += 1) {
                            if (responData[att][item.moreKey] === true) {
                                mData.push(responData[att]);
                            } else {
                                dData.push(responData[att]);
                            }
                        }
                        defaultDataMap[key] = dData;
                        more[key] = mData;
                    } else {
                        defaultDataMap[key] = responData || [];
                    }
                    mine.setState({
                        defaultDataMap: {...defaultDataMap},
                        suggest,
                        more
                    });
                } else {
                    error(rs[projectConfig.msg]);
                }
            });
        }
    };

    getSonData = (item, value) => {
        if (item.notInit) return;
        const mine = this;
        const postData = {};
        postData[item.nextAjaxKey] = value;
        
        const locationSearch = {};
        if (item.isNeedLocationSearch && isArray(item.isNeedLocationSearch)) {
            for (let i = 0; i < item.isNeedLocationSearch.length; i+=1) {
                const key = item.isNeedLocationSearch[i];
                locationSearch[key] = mine.searchParams[key];
            }
        }
        const { data, url } = parseData2Url({
            ...parseFixedParameter(mine.config.fixedParameter),
            ...parseFixedParameter(item.fixedParameter),
            ...locationSearch,
            ...(postData || {})
        }, item[`${this.env}nextUrl`] || '', item.accept);
        if (url) {
            xhr({
                url,
                method: item.nextMethod || 'get',
                data,
                type: 'json',
                contentType: item.nextContentType,
                notSwitchArrToStr: item.nextNotSwitchArrToStr
            }).then((rs) => {
                if (rs[projectConfig.codeKey] === projectConfig.code) {
                    const { defaultDataMap, suggest, more } = mine.state;
                    let responData = [];
                    const key = item.nextKey;
                    if (item.type === 'suggest') {
                        suggest[key] = rs.data || [];
                    } else if (item.responseKey) {
                        if (item.listStr === true) {
                            defaultDataMap[key] = rs.data[item.responseKey] && isArray(rs.data[item.responseKey]) ? rs.data[item.responseKey].map(dItem => { return { "id": dItem, "name": dItem } }) : [];
                        } else {
                            responData = rs.data[item.responseKey] && isArray(rs.data[item.responseKey]) ? rs.data[item.responseKey] : [];
                        }
                    } else if (item.listStr === true) {
                        defaultDataMap[key] = rs.data && isArray(rs.data) ? rs.data.map(dItem => { return { "id": dItem, "name": dItem } }) : [];
                    } else {
                        responData = rs.data && isArray(rs.data) ? rs.data : [];
                    }
                    if (item.moreKey && !item.listStr) {
                        const dData = [];
                        const mData = [];
                        for (let att = 0; att < responData.length; att += 1) {
                            if (responData[att][item.moreKey] === true) {
                                mData.push(responData[att]);
                            } else {
                                dData.push(responData[att]);
                            }
                        }
                        defaultDataMap[key] = dData;
                        more[key] = mData;
                    } else {
                        defaultDataMap[key] = responData || [];
                    }
                    mine.setState({
                        defaultDataMap: {...defaultDataMap},
                        suggest,
                        more
                    });
                } else {
                    error(rs[projectConfig.msg]);
                }
            });
        }
    }

    inputSuggest = (value, item) => {
        const mine = this;
        const { suggest } = mine.state;
        const postData = {};
        if (item.ajaxKey) postData[item.ajaxKey] = value;

        const locationSearch = {};
        if (item.isNeedLocationSearch && isArray(item.isNeedLocationSearch)) {
            for (let i = 0; i < item.isNeedLocationSearch.length; i+=1) {
                const key = item.isNeedLocationSearch[i];
                locationSearch[key] = mine.searchParams[key];
            }
        }
        const { data, url } = parseData2Url({
            ...parseFixedParameter(mine.config.fixedParameter),
            ...parseFixedParameter(item.fixedParameter),
            ...locationSearch,
            ...(postData || {})
        }, item[`${this.env}url`] || '', item.accept);

        if (url && !item.cache) {
            xhr({
                url,
                method: item.method || 'get',
                data,
                type: 'json',
                contentType: item.contentType,
                notSwitchArrToStr: item.notSwitchArrToStr
            }).then((rs) => {
                if (rs[projectConfig.codeKey] === projectConfig.code) {
                    suggest[item.key] = rs.data || [];
                    mine.setState({
                        suggest
                    });
                } else {
                    error(rs[projectConfig.msg]);
                }
            });
        }
    }

    fetchDataHandler = (configParams, callback) => {
        const mine = this;
        const { forms, mode } = mine.state;
        const dataConfig = mine.config[mode].data;
        const method = dataConfig.method || 'get';
        const locationSearch = {};
        if (dataConfig.isNeedLocationSearch && isArray(dataConfig.isNeedLocationSearch)) {
            for (let i = 0; i < dataConfig.isNeedLocationSearch.length; i+=1) {
                const key = dataConfig.isNeedLocationSearch[i];
                locationSearch[key] = mine.searchParams[key];
            }
        }
        const { data, url } = parseData2Url({
                    ...parseFixedParameter(mine.config.fixedParameter),
                    ...parseFixedParameter(dataConfig.fixedParameter),
                    ...locationSearch,
                    ...configParams
                }, dataConfig[`${mine.env}url`] || '', dataConfig.accept, dataConfig.urlParams);
        if (url)
            xhr({
                url,
                method,
                data,
                type: 'json',
                contentType: dataConfig.contentType,
                notSwitchArrToStr: dataConfig.notSwitchArrToStr
            }).then((rs) => {
                if (rs[projectConfig.codeKey] === projectConfig.code) {
                    const modifyData = rs.data || {};
                    if (callback) callback(modifyData);
                    for (let i = 0; i < forms.length; i+=1) {
                        const key = forms[i].key || '';
                        const type = forms[i].type || '';
                        const echoType = forms[i].echoType || '';
                        if (key) {
                            if (echoType === 'Array') {
                                mine.props.updateFieldValue(key, ((modifyData[key] === null || modifyData[key] === undefined) ? '' : modifyData[key]).split(','));
                            } else if (type === 'datepicker') {
                                mine.props.updateFieldValue(key, (modifyData[key] === null || modifyData[key] === undefined) ? '' : moment(modifyData[key]));
                            } else if (type === 'uploadimage') {
                                mine.props.updateFieldValue(key, isImage(modifyData[key]) ? [{url: modifyData[key]}] : '');
                            } else {
                                mine.props.updateFieldValue(key, (modifyData[key] === null || modifyData[key] === undefined) ? '' : modifyData[key]);
                            }
                        }
                    }
                    mine.props.validateAll();
                } else {
                    error(rs[projectConfig.msg]);
                }
            });
    }

    completionForms = (mode) => {
        if (this.config[mode] && this.config[mode].forms)
            return [...(this.config[mode].forms || []), ...(this.config.forms || [])];
        return this.config.forms;
    }

    showOrHideModalHandler = (bool) => {
        this.setState({
            showModal: bool
        });
    };

    cancelHandler = () => {
       this.showOrHideModalHandler(false);
    };

    parseData = (data) => {
        /*
            可单独对数据做处理，对比 createField 的过滤内容
         */
        const postData = {};
        const { formDataType, forms } = this.state;
        for (let d = 0; d < forms.length; d+=1) {
            const formItemKey = forms[d].key;
            if ((forms[d].conKey &&
                (isArray(forms[d].conValue) && forms[d].conValue.includes(data[forms[d].conKey]) ||
                !isArray(forms[d].conValue) && data[forms[d].conKey] === forms[d].conValue)
            ) ||
            !forms[d].conKey)
            {
                postData[formItemKey] = data[formItemKey];
            }
            if (formDataType[formItemKey] && formDataType[formItemKey].ajaxType === 'none') {
                delete postData[formItemKey];
                continue;
            }
            if (formDataType[formItemKey] && formDataType[formItemKey].type === "uploadimage") {
                postData[formItemKey] = data[formItemKey].length > 0 ? data[formItemKey][0].url : '';
            }
            if (formDataType[formItemKey] && formDataType[formItemKey].type === "multuploadimage") {
                postData[formItemKey] = data[formItemKey].map(item => item.url);
            }
            if (formDataType[formItemKey] && formDataType[formItemKey].type === "uploadfiles") {
                postData[formItemKey] = data[formItemKey].map(item => item.name);
            }
            if (formDataType[formItemKey] && formDataType[formItemKey].type === "uploadNosFile") {
                postData[formItemKey] = data[formItemKey].map(item => { return {
                    fileKey: item.fileKey,
                    fileName: item.fileName
                }})
            }
            if (formDataType[formItemKey] && formDataType[formItemKey].ajaxType === 'timestamp') {
                postData[formItemKey] = moment(data[formItemKey]).valueOf();
            } else if (formDataType[formItemKey] && formDataType[formItemKey].ajaxType === 'second') {
                postData[formItemKey] = parseInt(moment(data[formItemKey]).valueOf() / 1000, 10);
            } else if (formDataType[formItemKey] && formDataType[formItemKey].ajaxType === 'time') {
                postData[formItemKey] = data[formItemKey].format(formDataType[formItemKey].format);
            } else if (formDataType[formItemKey] && formDataType[formItemKey].ajaxType === 'number') {
                postData[formItemKey] = Number(data[formItemKey]);
            } else if (formDataType[formItemKey] && formDataType[formItemKey].ajaxType === 'json2Str') {
                postData[formItemKey] = JSON.stringify(data[formItemKey])
            } else if (formDataType[formItemKey] && formDataType[formItemKey].ajaxType === 'str2Json') {
                postData[formItemKey] = JSON.parse(data[formItemKey])
            }
        }
        return postData;
    }

    submitHandler = (data, itemConfig, result) => {
        const mine = this;
        const { defaultValueMap } = mine.state;
        const method = itemConfig.method || 'post';
        const msg = itemConfig.msg || '操作成功';
        const locationSearch = {};
        if (itemConfig.isNeedLocationSearch && isArray(itemConfig.isNeedLocationSearch)) {
            for (let i = 0; i < itemConfig.isNeedLocationSearch.length; i+=1) {
                const key = itemConfig.isNeedLocationSearch[i];
                locationSearch[key] = mine.searchParams[key];
            }
        }
        const dataURLObj = parseData2Url({
                    ...parseFixedParameter(mine.config.fixedParameter),
                    ...parseFixedParameter(itemConfig.fixedParameter),
                    ...locationSearch,
                    ...defaultValueMap,
                    ...data
                }, itemConfig[`${mine.env}url`] || '', itemConfig.accept, itemConfig.urlParams);
        
        if (dataURLObj.url) {
            xhr({
                url: dataURLObj.url,
                method,
                data: this.parseData(dataURLObj.data),
                type: 'json',
                contentType: itemConfig.contentType,
                notSwitchArrToStr: itemConfig.notSwitchArrToStr
            }).then((rs) => {
                if (rs[projectConfig.codeKey] === projectConfig.code) {
                    this.setState({showModal: false});
                    success(msg);
                    if (result.type === 'link') {
                        window.open(result.address);
                    } else if (result.type === 'route') {
                        this.props.history.push(result.address);
                    } else {
                        mine.props.refreshTable(1);
                    }
                } else {
                    error(rs[projectConfig.msg]);
                }
            });
        }
    };

    beforeUpload = file => {
        const data = new FormData();
        const uploadUrl = `http://upfile.m.163.com/nos/upload/pub`;
        if (!/(gif|png|jpe?g)$/.test(file.type)) {
            error(`${file.name || ''}文件类型错误！`);
            return false;
        }
        data.append('myfile', file);
        return Axios.post(uploadUrl, data).then(res => {
            if (res.data.status === 1) {
                return {url: res.data.url};
            }
            return false;
        });
    }

    beforeUploadFiles = (file, config) => {
        const { values } = this.props;
        if (config.len && values[config.key] && values[config.key].length > config.len) {
            error(`${config.label || config.key || ''}最多上传${config.len}个文件！`);
            return false;
        }
        const data = new FormData();
        const uploadUrl = `http://upfile.m.163.com/nos/upload/pub`;
        if (config.acceptType && config.acceptType.indexOf(file.type) === -1) {
            error(`${file.name || ''}文件类型错误！`);
            console.log(`上传文件格式为：${file.type}，如果支持，请添加到acceptType配置上。`);
            return false;
        }
        data.append('myfile', file);
        return Axios.post(uploadUrl, data).then(res => {
            if (res.data.status === 1) {
                return {name: res.data.url};
            }
            return false;
        });
    }

    cropSure = base64 => {
        const data = new FormData();
        const uploadUrl = `http://upload.buzz.163.com/picupload`;
        data.append('from', 'push');
        data.append('uploadtype', 'base64');
        data.append('body', base64);
        return Axios.post(uploadUrl, data).then(res => {
            if (res.data.code === 200) {
                return {url: res.data.data.url};
            }
            return false;
        });
    }

    beforeUploadNosFile = file => {
        const { name } = file;
        const uploadUrl = '/fileUpload/buildUpLoadPolicy';
        const fileName = `163/newcmslog/${name}`;
        const params = {nosObject: fileName};
        return Axios.request({
            url: uploadUrl,
            method: "POST",
            data: QS.stringify(params),
            headers: {
                "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8" 
            }
        }).then(res => {
            if (res.data && res.data.code === 200) {
                const token = res.data.data;
                const uploader = Uploader({ // eslint-disable-line no-undef
                    onError: (errObj) => {
                        error(errObj.errMsg || '上传出错！');
                    }
                }); 
                uploader.addFile(file);
                const param = {
                    bucketName: "static163",
                    objectName: fileName,
                    token
                }
                return new Promise((resolve) => {
                    uploader.upload(param, curFile => {
                        const { fileKey } = curFile;
                        if(fileKey) resolve({ fileKey, fileName, name });
                    });
                }) 
            }
            return false;
        });
    }

    radioChange = (value, item) => {
        const mine = this;
        const { placeholderMap, helperTextMap, forms, defaultValueMap } = mine.state;
        const placeholder = {};
        const helperText = {};
        if (item.nextKey) {
            placeholder[item.nextKey] = item.nextPlaceholder[value];
            helperText[item.nextKey] = item.nextHelperText[value];
            mine.setState({
                placeholderMap: {
                    ...placeholderMap,
                    ...placeholder
                },
                helperTextMap: {
                    ...helperTextMap,
                    ...helperText
                }
            });
        }
        const { updateFieldValue } = this.props;
        for (let i = 0; i < forms.length; i+=1) {
            const formItem = forms[i] || {};
            if (formItem.key && formItem.conKey && formItem.conKey === item.key) {
                if (formItem.type === 'datepicker') {
                    updateFieldValue(formItem.key, (defaultValueMap[formItem.key] ? moment().subtract(formItem.defaultValue, 'days') : ''));
                } else {
                    updateFieldValue(formItem.key, defaultValueMap[formItem.key]);
                }
            }
        }
    }

    // more less map  维护
    showMore = (item) => {
        const cloneState = JSON.parse(JSON.stringify(this.state));
        const { more } = cloneState;
        more[item.key] = [...(item.more || []), ...(more[item.key] || [])];
        this.setState({
            more
        });
    }

    showLess = (item) => {
        const { values } = this.props;
        const cloneState = JSON.parse(JSON.stringify(this.state));
        const { more, defaultDataMap } = cloneState;
        delete more[item.key];
        this.setState({
            more
        }, () => {
            const { updateFieldValue } = this.props;
            let flag = false;
            const parseData = [...(item.data || []), ...(defaultDataMap[item.key] || [])];
            for (let i = 0; i < parseData.length; i += 1) {
                if (parseData[i][item.dataKey || 'id'] === values[item.key] || (values[item.key] || '').indexOf(parseData[i][item.dataKey || 'id']) > -1) {
                    flag = true;
                    break;
                }
            }
            if (flag) updateFieldValue(item.key, values[item.key]);
            else updateFieldValue(item.key, (item.defaultValue !== '' ? item.defaultValue : ''));
        });
    }

    handleSearch = (value, item) => {
        const mine = this;
        const postData = {};
        if (item.ajaxKey) postData[item.ajaxKey] = value;
        const locationSearch = {};
        if (item.isNeedLocationSearch && isArray(item.isNeedLocationSearch)) {
            for (let i = 0; i < item.isNeedLocationSearch.length; i+=1) {
                const key = item.isNeedLocationSearch[i];
                locationSearch[key] = mine.searchParams[key];
            }
        }
        const { data, url } = parseData2Url({
            ...parseFixedParameter(mine.config.fixedParameter),
            ...parseFixedParameter(item.fixedParameter),
            ...locationSearch,
            ...(postData || {})
        }, item[`${this.env}url`] || '', item.accept);
        if (url) {
            xhr({
                url,
                method: item.method || 'get',
                data,
                type: 'json',
                contentType: item.contentType,
                notSwitchArrToStr: item.notSwitchArrToStr
            }).then((rs) => {
                if (rs[projectConfig.codeKey] === projectConfig.code) {
                    const { defaultDataMap } = mine.state;
                    const { key } = item;
                    if (item.responseKey) {
                        if (item.listStr === true) {
                            defaultDataMap[key] = rs.data[item.responseKey] && isArray(rs.data[item.responseKey]) ? rs.data[item.responseKey].map(dItem => { return { "id": dItem, "name": dItem } }) : [];
                        } else {
                            defaultDataMap[key] = rs.data[item.responseKey] && isArray(rs.data[item.responseKey]) ? rs.data[item.responseKey] : [];
                        }
                    } else if (item.listStr === true) {
                        defaultDataMap[key] = rs.data && isArray(rs.data) ? rs.data.map(dItem => { return { "id": dItem, "name": dItem } }) : [];
                    } else {
                        defaultDataMap[key] = rs.data && isArray(rs.data) ? rs.data : [];
                    }
                    mine.setState({
                        defaultDataMap: {...defaultDataMap}
                    });
                } else {
                    error(rs[projectConfig.msg]);
                }
            });
        }
    };

    createField = (forms) => {
        const { values, aliasArrMap } = this.props;
        const { defaultDataMap, suggest, disabledMap, placeholderMap, helperTextMap, more } = this.state;
        const result = [];
        for (let i = 0; i < forms.length; i+=1) {
            const item = forms[i];
            if ((isArray(item.conValue) && !item.conValue.includes(values[item.conKey])) || (!isArray(item.conValue) && values[item.conKey] !== item.conValue)) {
                continue;
            }
            if (item.disabledKey && item.disabledValue) {
                const initDisabled = disabledMap[item.key];
                if ((values[item.disabledKey] === item.disabledValue)) {
                    disabledMap[item.key] = true;
                } else {
                    disabledMap[item.key] = initDisabled;
                }
            }
            if (item.type === 'span') {
                result.push(<Field
                    className="fastform-field"
                    style={Object.assign({ marginBottom: 35 }, item.style)}
                    label={<span>{item.rule && item.rule.isMust ? <span className="required">*</span> : ''}{item.label}</span>}
                    name={item.key}
                    helperText={helperTextMap[item.key]}
                    validateTrigger='onBlur'
                    nativeStatusIcon
                    labelLayout={{ size: item.labelLayout || 8 }}
                    contentLayout={{ size: item.contentLayout || 16 }}>
                    <span>{values[item.key] || ''}</span>
                </Field>);
            } else if (item.type === 'suggest') {
                result.push(<Field
                    className="fastform-field"
                    style={Object.assign({ marginBottom: 35 }, item.style)}
                    label={<span>{item.rule && item.rule.isMust ? <span className="required">*</span> : ''}{item.label}</span>}
                    name={item.key}
                    helperText={helperTextMap[item.key]}
                    validateTrigger='onChange'
                    nativeStatusIcon
                    onChange={(value) => { this.inputSuggest(value, item); }}
                    labelLayout={{ size: item.labelLayout || 8 }}
                    contentLayout={{ size: item.contentLayout || 16 }}>
                        <AutoComplete fullWidth suggestions={ suggest[item.key] || [] } defaultValue={values[item.key] || ''} disabled={disabledMap[item.key]} placeholder={ placeholderMap[item.key] || `请输入${item.label}` } />
                </Field>);
            } else if (item.type === 'input') {
                result.push(<Field
                    className="fastform-field"
                    style={Object.assign({ marginBottom: 35 }, item.style)}
                    label={<span>{item.rule && item.rule.isMust ? <span className="required">*</span> : ''}{item.label}</span>}
                    name={item.key}
                    helperText={`${helperTextMap[item.key] || ''}${item.rule && item.rule.needLen ? '当前长度' : ''}${item.rule && item.rule.needLen ? getBLen(values[item.key]) : ''}`}
                    validateTrigger='onChange'
                    nativeStatusIcon
                    labelLayout={{ size: item.labelLayout || 8 }}
                    contentLayout={{ size: item.contentLayout || 16 }}>
                        <Input autoComplete="off" clearable={!disabledMap[item.key]} type={item.inputType || 'text'} disabled={disabledMap[item.key]} placeholder={placeholderMap[item.key] || `请输入${item.label}`} />
                </Field>);
            } else if (item.type === 'multinput') {
                result.push(<Field
                    className="fastform-field"
                    style={Object.assign({ marginBottom: 35 }, item.style)}
                    label={<span>{item.rule && item.rule.isMust ? <span className="required">*</span> : ''}{item.label}</span>}
                    name={item.key}
                    helperText={`${helperTextMap[item.key]}${item.rule && item.rule.needLen ? '当前长度' : ''}${item.rule && item.rule.needLen ? getBLen(values[item.key]) : ''}`}
                    validateTrigger='onChange'
                    nativeStatusIcon
                    labelLayout={{ size: item.labelLayout || 8 }}
                    contentLayout={{ size: item.contentLayout || 16 }}>
                    <Input disabled={disabledMap[item.key]} autoComplete="off" multiline rows={item.rows || 5} placeholder={placeholderMap[item.key] || `请输入${item.label}`}/>
                </Field>);
            } else if (item.type === 'select') {
                const data = [].concat(item.data || []).concat(item.alias && aliasArrMap ? ((aliasArrMap[item.alias] || []).map(aliasItem => { return { id: item.aliasType === 'number' ? parseInt(aliasItem.id, 10) : aliasItem.id, name: aliasItem.name } }) || []) : []).concat(defaultDataMap[item.key] || []);
                let checkName = '';
                const selectItems = data.map(selectItem => {if (values[item.key] === selectItem[item.dataKey || 'id']) checkName = selectItem[item.dataLabel || 'name']; return { 'label': selectItem[item.dataLabel || 'name'], 'value': selectItem[item.dataKey || 'id'] }});
                result.push(<Field
                        className="fastform-field"
                        style={Object.assign({ marginBottom: 35 }, item.style)}
                        label={<span>{item.rule && item.rule.isMust ? <span className="required">*</span> : ''}{item.label}</span>}
                        name={item.key}
                        helperText={helperTextMap[item.key]}
                        validateTrigger='onChange'
                        valuePropName='defaultValue'
                        nativeStatusIcon
                        labelLayout={{ size: item.labelLayout || 8 }}
                        contentLayout={{ size: item.contentLayout || 16 }}>
                        {
                            disabledMap[item.key] ? <Input disabled value={checkName || ''} /> : <Select
                                placeholder={placeholderMap[item.key] || `请选择${item.label}`}
                                options={item.notAll ? [...selectItems] : [{ label: '全部', value: '' }, ...selectItems]}
                                onSearch={(e, value) => {if (item.searchable) this.handleSearch(value, item)}}
                                searchable
                                needReceive={item.searchable || false}
                            ></Select>
                        }
                    </Field>);
            } else if (item.type === 'multselect') {
                const data = [].concat(item.data || []).concat(item.alias && aliasArrMap ? ((aliasArrMap[item.alias] || []).map(aliasItem => { return { id: item.aliasType === 'number' ? parseInt(aliasItem.id, 10) : aliasItem.id, name: aliasItem.name } }) || []) : []).concat(defaultDataMap[item.key] || []);
                const selectItems = data.map(selectItem => {return { 'label': selectItem[item.dataLabel || 'name'], 'value': selectItem[item.dataKey || 'id'] }});
                result.push(<Field
                        className="fastform-field"
                        style={Object.assign({ marginBottom: 35 }, item.style)}
                        label={<span>{item.rule && item.rule.isMust ? <span className="required">*</span> : ''}{item.label}</span>}
                        name={item.key}
                        helperText={helperTextMap[item.key]}
                        validateTrigger='onChange'
                        valuePropName='defaultValue'
                        nativeStatusIcon
                        labelLayout={{ size: item.labelLayout || 8 }}
                        contentLayout={{ size: item.contentLayout || 16 }}>
                        <Select
                            searchable
                            multiple
                            placeholder={placeholderMap[item.key] || `请选择${item.label}`}
                            options={item.notAll ? [...selectItems] : [{ label: '全部', value: '' }, ...selectItems]}
                        >
                        </Select>
                    </Field>);
            } else if (item.type === 'tags') {
                const data = [].concat(item.data || []).concat(item.alias && aliasArrMap ? ((aliasArrMap[item.alias] || []).map(aliasItem => { return { id: item.aliasType === 'number' ? parseInt(aliasItem.id, 10) : aliasItem.id, name: aliasItem.name } }) || []) : []).concat(defaultDataMap[item.key] || []);
                const selectItems = data.map(selectItem => {return { 'label': selectItem[item.dataLabel || 'name'], 'value': selectItem[item.dataKey || 'id'] }});
                result.push(<Field
                        className="fastform-field"
                        style={Object.assign({ marginBottom: 35 }, item.style)}
                        label={<span>{item.rule && item.rule.isMust ? <span className="required">*</span> : ''}{item.label}</span>}
                        name={item.key}
                        helperText={helperTextMap[item.key]}
                        validateTrigger='onChange'
                        valuePropName='defaultValue'
                        nativeStatusIcon
                        labelLayout={{ size: item.labelLayout || 8 }}
                        contentLayout={{ size: item.contentLayout || 16 }}>
                            <TagSelect
                                triggerKey={item.keyCode || 32}
                                placeholder={placeholderMap[item.key] || `请选择/输入${item.label}`}
                                options={item.notAll ? [...selectItems] : [{ label: '全部', value: '' }, ...selectItems]}
                            >
                            </TagSelect>
                    </Field>);
            } else if (item.type === 'radio') {
                const data = [].concat(item.data || []).concat(item.alias && aliasArrMap ? ((aliasArrMap[item.alias] || []).map(aliasItem => { return { id: item.aliasType === 'number' ? parseInt(aliasItem.id, 10) : aliasItem.id, name: aliasItem.name } }) || []) : []).concat(defaultDataMap[item.key] || []).concat(more[item.key] || []);
                const hasMore = !more[item.key] ? <Button variant="contained" color={item.moreprimary || item.primary || 'primary'} onClick={() => {this.showMore(item)}}>展开</Button>
                            : <Button variant="contained" color={item.lessprimary || item.primary || 'primary'} onClick={() => {this.showLess(item)}}>收起</Button>;
                result.push(<Field
                        className="fastform-field"
                        style={Object.assign({ marginBottom: 35 }, item.style)}
                        label={<span>{item.rule && item.rule.isMust ? <span className="required">*</span> : ''}{item.label}</span>}
                        name={item.key}
                        helperText={helperTextMap[item.key]}
                        validateTrigger='onChange'
                        valuePropName='value'
                        onChange={(e, value) => { this.radioChange(value, item); }}
                        nativeStatusIcon
                        labelLayout={{ size: item.labelLayout || 8 }}
                        contentLayout={{ size: item.contentLayout || 16 }}>
                        <RadioGroup disabled={disabledMap[item.key]}>
                            {
                            data.map(radioItem => <Radio label={radioItem[item.dataLabel || 'name']} value={radioItem[item.dataKey || 'id']} key={radioItem[item.dataKey || 'id']} /> )
                        }
                        {
                            item.more ? hasMore : ''
                        }
                        </RadioGroup>
                    </Field>);
            } else if (item.type === 'check') {
                const data = [].concat(item.data || []).concat(item.alias && aliasArrMap ? ((aliasArrMap[item.alias] || []).map(aliasItem => { return { id: item.aliasType === 'number' ? parseInt(aliasItem.id, 10) : aliasItem.id, name: aliasItem.name } }) || []) : []).concat(defaultDataMap[item.key] || []).concat(more[item.key] || []);
                const hasMore = !more[item.key] ? <Button variant="contained" color={item.moreprimary || item.primary || 'primary'} onClick={() => {this.showMore(item)}}>展开</Button>
                            : <Button variant="contained" color={item.lessprimary || item.primary || 'primary'} onClick={() => {this.showLess(item)}}>收起</Button>;
                result.push(<Field
                    className="fastform-field"
                    style={Object.assign({ marginBottom: 35 }, item.style)}
                    label={<span>{item.rule && item.rule.isMust ? <span className="required">*</span> : ''}{item.label}</span>}
                    name={item.key}
                    helperText={helperTextMap[item.key]}
                    validateTrigger='onChange'
                    valuePropName='value'
                    nativeStatusIcon
                    labelLayout={{ size: item.labelLayout || 8 }}
                    contentLayout={{ size: item.contentLayout || 16 }}>
                    <CheckboxGroup disabled={disabledMap[item.key]}>
                        {
                            data.map(checkItem => <Checkbox label={checkItem[item.dataLabel || 'name']} value={checkItem[item.dataKey || 'id']} key={checkItem[item.dataKey || 'id']} /> )
                        }
                        {
                            item.more ? hasMore : ''
                        }
                    </CheckboxGroup>
                </Field>);
            } else if (item.type === 'uploadimage') {
                result.push(<Field
                    className="fastform-field fastform-field-uploadimage"
                    style={Object.assign({ marginBottom: 35 }, item.style)}
                    label={<span>{item.rule && item.rule.isMust ? <span className="required">*</span> : ''}{item.label}</span>}
                    name={item.key}
                    helperText={helperTextMap[item.key]}
                    validateTrigger='onChange'
                    valuePropName='defaultFiles'
                    nativeStatusIcon
                    labelLayout={{ size: item.labelLayout || 8 }}
                    contentLayout={{ size: item.contentLayout || 16 }}>
                        <Upload
                            disabled={disabledMap[item.key]}
                            single
                            radioList={[
                                <Radio label="600*600" value="600*600" key="600*600" />,
                                <Radio label="600*400" value="600*400" key="600*400" />
                            ]}
                            radioDefault="600*600"
                            beforeUpload={this.beforeUpload}
                            cropSure={this.cropSure}>
                                <Button>上传本地</Button>
                        </Upload>
                </Field>);
            } else if (item.type === 'multuploadimage') {
                result.push(<Field
                    className="fastform-field fastform-field-multuploadimage"
                    style={Object.assign({ marginBottom: 35 }, item.style)}
                    label={<span>{item.rule && item.rule.isMust ? <span className="required">*</span> : ''}{item.label}</span>}
                    name={item.key}
                    helperText={helperTextMap[item.key]}
                    validateTrigger='onChange'
                    valuePropName='defaultFiles'
                    nativeStatusIcon
                    labelLayout={{ size: item.labelLayout || 8 }}
                    contentLayout={{ size: item.contentLayout || 16 }}>
                        <Upload
                            disabled={disabledMap[item.key]}
                            multiple
                            gallery
                            radioList={[
                                <Radio label="600*600" value="600*600" key="600*600" />,
                                <Radio label="600*400" value="600*400" key="600*400" />
                            ]}
                            radioDefault="600*600"
                            beforeUpload={this.beforeUpload}
                            cropSure={this.cropSure} >
                                <Button>上传本地</Button>
                        </Upload>
                </Field>);
            } else if (item.type === 'uploadfiles') {
                result.push(<Field
                    className="fastform-field fastform-field-uploadfiles"
                    style={Object.assign({ marginBottom: 35 }, item.style)}
                    label={<span>{item.rule && item.rule.isMust ? <span className="required">*</span> : ''}{item.label}</span>}
                    name={item.key}
                    helperText={helperTextMap[item.key]}
                    validateTrigger='onChange'
                    valuePropName='defaultFiles'
                    nativeStatusIcon
                    labelLayout={{ size: item.labelLayout || 8 }}
                    contentLayout={{ size: item.contentLayout || 16 }}>
                        <Upload
                            disabled={disabledMap[item.key]}
                            multiple
                            beforeUpload={(file) => this.beforeUploadFiles(file, item)} >
                                <Button>上传本地</Button>
                        </Upload>
                </Field>);
            } else if (item.type === 'uploadNosFile') {
                result.push(<Field
                    className="fastform-field fastform-field-uploadfile"
                    style={Object.assign({ marginBottom: 35 }, item.style)}
                    label={<span>{item.rule && item.rule.isMust ? <span className="required">*</span> : ''}{item.label}</span>}
                    name={item.key}
                    helperText={helperTextMap[item.key]}
                    validateTrigger='onChange'
                    valuePropName='defaultFiles'
                    nativeStatusIcon
                    labelLayout={{ size: item.labelLayout || 8 }}
                    contentLayout={{ size: item.contentLayout || 16 }}>
                        <Upload
                            disabled={disabledMap[item.key]}
                            multiple
                            beforeUpload={this.beforeUploadNosFile} >
                                <Button>上传本地</Button>
                        </Upload>
                </Field>);
            } else if (item.type === 'datepicker') {
                const datePickProps = Object.assign({
                    type: 'date',
                    format: item.format || 'YYYY-MM-DD HH:mm:ss',
                    selectType: 'date',
                    clearable: true,
                    showTime: item.showTime || false
                }, item.option || {});
                result.push(<Field
                        className="fastform-field"
                        style={Object.assign({ marginBottom: 35 }, item.style)}
                        label={<span>{item.rule && item.rule.isMust ? <span className="required">*</span> : ''}{item.label}</span>}
                        name={item.key}
                        helperText={helperTextMap[item.key]}
                        validateTrigger='onChange'
                        valuePropName='defaultValue'
                        nativeStatusIcon
                        labelLayout={{ size: item.labelLayout || 8 }}
                        contentLayout={{ size: item.contentLayout || 16 }}>
                        <DatePicker
                            { ...datePickProps }
                        />
                    </Field>);
            } else if (item.type === 'treeselect'){
                const treeData = defaultDataMap[item.key] || item.data || [];
                result.push(<Field 
                    className="fastform-field"
                    style={Object.assign({ marginBottom: 35 }, item.style)}
                    label={<span>{item.rule && item.rule.isMust ? <span className="required">*</span> : ''}{item.label}</span>}
                    name={item.key}
                    helperText={helperTextMap[item.key]}
                    validateTrigger='onChange'
                    nativeStatusIcon
                    labelLayout={{ size: item.labelLayout || 8 }}
                    contentLayout={{ size: item.contentLayout || 16 }}>
                    <TreeSelect 
                        multiple={ false }
                        options={ treeData }
                    />
                </Field>);
            } else if (item.type === 'multtreeselect'){
                const treeData = defaultDataMap[item.key] || item.data || [];
                result.push(<Field 
                    className="fastform-field"
                    style={Object.assign({ marginBottom: 35 }, item.style)}
                    label={<span>{item.rule && item.rule.isMust ? <span className="required">*</span> : ''}{item.label}</span>}
                    name={item.key}
                    helperText={helperTextMap[item.key]}
                    validateTrigger='onChange'
                    nativeStatusIcon
                    labelLayout={{ size: item.labelLayout || 8 }}
                    contentLayout={{ size: item.contentLayout || 16 }}>
                    <TreeSelect 
                        showCheckedStrategy={ item.showCheckedStrategy || "all" }
                        multiple
                        options={ treeData }
                    />
                </Field>);
            } else if (item.type === 'todo') {
                result.push(<Field
                    className="fastform-field"
                    style={Object.assign({ marginBottom: 35 }, item.style)}
                    label={<span>{item.rule && item.rule.isMust ? <span className="required">*</span> : ''}{item.label}</span>}
                    name={item.key}
                    helperText={helperTextMap[item.key]}
                    labelLayout={{ size: item.labelLayout || 8 }}
                    contentLayout={{ size: item.contentLayout || 16 }}>
                        <div>TODO这里还没有配置</div>
                </Field>);
            } else if (item.type  === 'group') {
                result.push(<Row>
                    <Col size={item.labelLayout || 8} style={{ textAlign: "right", lineHeight: "32px" }}>{
                        item.label ? <span>{item.rule && item.rule.isMust ? <span className="required">*</span> : ''}{item.label}</span> : ''}</Col>
                    <Col size={item.contentLayout || 16}><div style={{ display: "flex" }}>{ this.createField(item.group) }</div></Col>
                </Row>);
            } else {
                result.push(<Field
                    className="fastform-field"
                    style={Object.assign({ marginBottom: 35 }, item.style)}
                    label={<span>{item.rule && item.rule.isMust ? <span className="required">*</span> : ''}{item.label}</span>}
                    name={item.key}
                    helperText={helperTextMap[item.key]}
                    labelLayout={{ size: item.labelLayout || 8 }}
                    contentLayout={{ size: item.contentLayout || 16 }}>
                        <div>这里是错误类型</div>
                </Field>);
            }
        }
        return result;
    };

    createFunBtns = () => {
        const { submit, values } = this.props;
        const { mode } = this.state;
        const resultBtns = [];
        const modeConfig = this.config[mode];
        const { funBtns, result = {} } = modeConfig;
        for (let i = 0; i < (funBtns || []).length; i += 1) {
            const itemKey = funBtns[i].key || '';
            const itemConfig = modeConfig[itemKey] || '';
            if (itemKey && itemConfig) {
                if (!itemConfig.notValidate === true)
                    resultBtns.push ( <Button style={Object.assign(funBtns[i].style || {}, modeConfig[itemKey].style || {})}
                                variant="contained" color={modeConfig[itemKey].primary || 'primary'}
                                onClick={submit(data => this.submitHandler(data, itemConfig, result), err => console.log(err))}>{modeConfig[itemKey].label || funBtns[i].label}</Button> );
                else
                    resultBtns.push ( <Button style={Object.assign(funBtns[i].style || {}, modeConfig[itemKey].style || {})}
                                variant="contained" color={modeConfig[itemKey].primary || 'primary'}
                                onClick={() => this.submitHandler(values, itemConfig, result)}>{modeConfig[itemKey].label || funBtns[i].label}</Button> );
            }
        }
        return resultBtns;
    }

    render() {
        const { mode } = this.props;
        const { showModal, forms } = this.state;
        return (
            <Modal
                size={this.config[mode].modalWidth ? `custom${this.config[mode].modalWidth}` : 'large'}
                isOpen={showModal}
                onClose={this.cancelHandler}
                disableBackdropClick
                disableEscapeKeyDown
                actions={[
                    ...this.createFunBtns(),
                    <Button onClick={ this.cancelHandler }>取消</Button>
                ]}
                title={this.config[mode].label || '操作'}
            >
                {this.createField(forms)}
            </Modal>
        );
    }
}

const FilterItemBaseForm = createEasyForm()(Searchtableactionmodal);
export default FilterItemBaseForm;
