UNPKG

ttk-app-core

Version:
508 lines (464 loc) 18.8 kB
import React, { Component } from 'react' import ReactDOM from 'react-dom' import classNames from 'classnames' import { Map, List, fromJS } from 'immutable' import Button from '../button/index' import { action as MetaAction, AppLoader } from 'edf-meta-engine' import clonedeep from 'lodash.clonedeep' import SearchForm from './SearchForm' import normalSearchFuc from './normalSearch' import AssistForm from './AssistForm' class SearchComponent extends Component { state = { data: Map({ initMeta: '', initData: '', className: '', visible: false, displayText: '', childVisible: false }) } constructor(props) { super(props) this.state = { data: this.computeState(this.props), visible: false, searchValue: clonedeep(props.moreSearch), key: '', height: 10000, normalSearch: props.normalSearchValue ? clonedeep(props.normalSearchValue) : {}, count: 0, containerHeight: 500 } this.value = {} this.datePickerRandom = Math.floor(Math.random() * 100000000) this.props.didMount && this.props.didMount(this) this.props.moreSearchItem && this.props.moreSearchItem.map(item => { if ( item.pre && item.pre.type && item.pre.type.includes('DatePicker') && item.next && item.next.type && item.next.type.includes('DatePicker') ) { this.state[`showDateWin_${item.pre.name}`] = false } }) } componentWillReceiveProps(nextProps) { this.setState(this.computeState(nextProps)) this.setState({ searchValue: clonedeep(nextProps.moreSearch), normalSearch: clonedeep(nextProps.normalSearchValue) }) } computeState(props) { let { data } = this.state let { value, height, width, style, className, placement, refName, child, okText, cancelText, resetText, btnTextAlign, loadApp } = props if (!Map.isMap(value) && !List.isList(value) && (typeof value == 'object')) { value = fromJS(value) } data = data.set('value', value) data = data.set('height', height) data = data.set('width', width) data = data.set('style', style) data = data.set('className', className) data = data.set('placement', placement) data = data.set('refName', refName) data = data.set('child', child) data = data.set('okText', okText) data = data.set('cancelText', cancelText) data = data.set('resetText', resetText) data = data.set('btnTextAlign', btnTextAlign) data = data.set('loadApp', loadApp) this.oldValue = value return data } componentDidMount() { this.setState({ height: document.getElementsByClassName('mk-search-high-search')[0].offsetHeight + 300 }) this.showPickerDidMount() this.computed() window.addEventListener('resize', this.computed, false) } componentWillUnmount() { window.removeEventListener('resize', this.computed, false) } dateWindowChange = (type, status, key) => { if (type == 'next') { this.setState({ [key]: status }) } if (type == 'next' && status == false) { // 采用异步是因为datePicker的onchange事件晚于onOpenChange触发 } } showPickerDidMount = () => { const { normalSearch } = this.props if (!normalSearch || normalSearch.length == 0) { return } const flag = normalSearch.find(item => item.type == 'DatePicker.RangePicker') if (!flag) { return } const dateDom = document.getElementsByClassName(this.datePickerRandom)[0] if (!dateDom) { setTimeout(() => { this.showPickerDidMount() }, 50) return } dateDom.addEventListener('click', this.rangePickerClick, false) } getPopupContainer() { return document.querySelector('.app-proof-of-list') } get(propertyName) { if (!propertyName || propertyName === '') { return this.state.data } return this.state.data.getIn(propertyName.split('.')) } set(propertyName, value) { let data = this.state.data if (!propertyName || propertyName === '') { return data.merge(value) } if (typeof value === 'object') { return data.mergeIn(propertyName.split('.'), value) } else { return data.setIn(propertyName.split('.'), value) } } showMoreSearch = (bol) => { let { data, count } = this.state data = this.set(null, { childVisible: bol }) this.setState({ data, count: 1 }) } confirmClick = () => { const { searchClick, moreSearchRules } = this.props const _this = this this.form.validateFields((err, values) => { if (err) { return } let flag = true let option if (_this.props.moreSearchItem.findIndex(item => item.type == 'AssistForm') > -1) { flag = _this.assistForm.verify() if (flag) { const getValue = _this.assistForm.getValue() values.groupStr = this.sortAssitItem(getValue.option, getValue.selectValue) values.whereStr = _this.getWhereStr(getValue.option, getValue.selectValue) option = getValue } } if (moreSearchRules) { flag = moreSearchRules(values, _this.form) } if (!flag) { return } _this.showMoreSearch(false) if (searchClick) { setTimeout(() => { if (_this.props.moreSearchItem.findIndex(item => item.type == 'AssistForm') > -1) { searchClick(values, option) } else { searchClick(values) } }, 800) } }) } // 对辅助项参数进行排序 sortAssitItem = (data, selectValue) => { const arr = [] data.forEach(item => { if (selectValue.includes(item.key)) { arr.push(item.key) } }) return arr.join(',') } //修改辅助项参数 getWhereStr = (option, selectLabel) => { let arr = [] option.forEach(item => { if (item.value && item.value.length > 0 && selectLabel.includes(item.key)) { arr.push(`${item.key}:${item.value.join(',')}`) } }) return arr.join(';') } cancelClick = () => { const { cancelClick } = this.props this.showMoreSearch(false) this.setState({ searchValue: clonedeep(this.props.moreSearch), key: Math.random() }) cancelClick && cancelClick() } clearClick = () => { const { clearClick } = this.props const value = this.clearValue('clear') clearClick && clearClick(value) } clearValue = (status) => { const { searchValue } = this.state const { clearClick, moreSearchItem } = this.props let clearValue = {} moreSearchItem.forEach(item => { if (item.range) { if (!item.pre.noClear) { clearValue[item.pre.name] = null } if (!item.next.noClear) { clearValue[item.next.name] = null } } else if (!item.noClear) { clearValue[item.name] = null // if (status == 'clear' && item.allowClear) item.allowClear = false } }) this.setState({ searchValue: { ...searchValue, ...clearValue }, key: Math.random() }) return { ...searchValue, ...clearValue } } normalSearchChange = (name, e, type, bol) => { const { normalSearch } = this.state let value = e && e.target ? e.target.value : e normalSearch[name] = value this.setState({ normalSearch }) if (name == 'date' && !bol) { // if (this.state.normalSearch[name] == value && this.props.normalSearchChange) { // let initValue = this.clearValue() // this.props.normalSearchChange(name, value, initValue, type) // } return } // 测试说简单搜索的情况下要清空高级搜索的内容 setTimeout(() => { if (this.state.normalSearch[name] == value && this.props.normalSearchChange) { let initValue = this.clearValue() this.props.normalSearchChange(name, value, initValue, type) } }, 1000) } renderNormalSearch = () => { const { normalSearch } = this.props if (!normalSearch) { return null } const normalSearchValue = this.state.normalSearch return normalSearch.map((item) => { item.value = normalSearchValue[item.name] return normalSearchFuc(item, this) }) } trantoNumber = (num) => { if (!num) { return 0 } try { return parseInt(num.format('YYYYMM')) } catch (err) { console.log(err) return 0 } } someChange = (key, value) => { try { const { searchValue } = this.state searchValue[key] = value if (this.state[`showDateWin_${key}`] != undefined) { let nextKey this.props.moreSearchItem.forEach(item => { if (item.next && item.pre && item.pre.name == key) { nextKey = item.next.name } if (this.trantoNumber(value) > this.trantoNumber(searchValue[nextKey])) { searchValue[nextKey] = value } }) this.setState({ [`showDateWin_${key}`]: true }) } this.setState({ searchValue }) } catch (err) { console.log(err) } } normalSelectDate = () => { let name = 'date' const { normalSearch } = this.state let value = normalSearch.date this.setState({ DatePickerOpen: false }) if (this.state.normalSearch[name] == value && this.props.normalSearchChange) { let initValue = this.clearValue() this.props.normalSearchChange(name, value, initValue) } } rangePickerClick = () => { this.setState({ DatePickerOpen: true }) } render() { let data = this.state.data.get('value') && this.state.data.get('value').get('data') data = data && data.size ? data : fromJS(data) const { confirmBtn, cancelBtn, clearBtn, refreshBtn } = this.props const { containerHeight } = this.state let This = this const moreSearchItem = this.props.moreSearchItem ? this.props.moreSearchItem.filter(item => { if (item.pre && item.next && item.pre.type.includes('DatePicker') && item.next.type.includes('DatePicker')) { return { ...item, next: { ...item.next, onOpenChange: (status) => this.dateWindowChange('next', status, `showDateWin_${item.pre.name}`), open: this.state[`showDateWin_${item.pre.name}`] }, pre: { ...item.pre, onOpenChange: (status) => this.dateWindowChange('pre', status, `showDateWin_${item.pre.name}`) } } } if (!item.visible) return item }) : null return ( <div ref='retrieveWrap' className='retrieveWrap mk-search' style={{ position: 'relative' }}> <div className="mk-normal-search" style={{ display: 'flex', justifyContent: 'space-between' }}> <div className="mk-normal-search-left" style={{ display: 'flex' }}> {this.props.selectDate ? this.props.selectDate : null} {this.renderNormalSearch()} {this.props.normalSearcChildren ? this.props.normalSearcChildren : null} {this.props.moreSearchItem ? <span className='mk-span' onClick={this.showMoreSearch.bind(this, true)} style={{ zIndex: '3', fontSize: '14px', display: 'flex', marginRight: '6px', flexDirection: 'column', justifyContent: 'center' }}> <a className="searchBtn">高级查询</a> </span> : null} {refreshBtn} {this.props.leftMenuBtn ? this.props.leftMenuBtn : null} </div> <div className="mk-title-otherBtn"> {this.props.menuBtn} </div> </div> <div style={{ width: '100%', height: '0', position: 'absolute', top: '0px', zIndex: '101', background: '#fff', boxShadow: '0 0 5px #999', display: `${this.state.count == 1 ? 'block' : 'none'}` }} > <div style={{ width: '100%', maxHeight: `${containerHeight}px` // top: `${this.state.data.get('childVisible') ? '0' : `-${this.state.height}px`}` }} className={`mk-search-high-search animated ${this.state.data.get('childVisible') ? 'slideInDown' : 'slideOutUp'}`} > <h2> <div>高级查询</div> </h2> <div className="search-form-contaienr" style={{ maxHeight: `${containerHeight - 90}px` }}> {this.props.treeSelect ? this.props.treeSelect : null} {this.props.moreSearchItem && <SearchForm target={this} onChange={this.someChange} item={moreSearchItem} key={Math.random()} ref={(form) => { this.form = form }} values={this.state.searchValue} />} {this.props.assistForm ? ( <AssistForm ref={form => this.assistForm = form} option={this.props.assistFormOption} selectValue={this.props.assistFormSelectValue} /> ) : null} </div> <div className="mk-search-high-search-bottomBtn" style={{ textAlign: This.get('btnTextAlign') }}> <span id='btnClick'> { cancelBtn && cancelBtn.hidden ? null : ( <Button onClick={this.cancelClick} className='cancel'> {cancelBtn && cancelBtn.text ? cancelBtn.text : '取消'} </Button> ) } { clearBtn && clearBtn.hidden ? null : ( <Button onClick={this.clearClick} className='clear_btn' style={{ marginLeft: '8px' }}> {clearBtn && clearBtn.text ? clearBtn.text : '清空'} </Button> ) } { confirmBtn && confirmBtn.hidden ? null : ( <Button onClick={this.confirmClick} className='query' type="primary" style={{ marginLeft: '8px' }}> {confirmBtn && confirmBtn.text ? confirmBtn.text : '查询'} </Button> ) } </span> </div> </div> </div> </div> ) } getAbsPoint = (e) => { var x = e.offsetLeft var y = e.offsetTop while (e = e.offsetParent) { x += e.offsetLeft y += e.offsetTop } return { x, y } } computed = () => { let table = ReactDOM.findDOMNode(this) if (table) { const point = this.getAbsPoint(table) let height = window.innerHeight - point.y this.setState({ containerHeight: height - 5 }) } } } export default SearchComponent