feat: 搜索组件: 基础信息字典获取
parent
44647bee3b
commit
76a3c3c94d
@ -0,0 +1,133 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { Select } from 'antd';
|
||||||
|
import querystring from 'querystring';
|
||||||
|
// import * as oMapper from 'object-mapper';
|
||||||
|
import { fetchJSON } from './../../utils/request';
|
||||||
|
import { observer } from 'mobx-react';
|
||||||
|
import { objectMapper } from './../../utils/commons';
|
||||||
|
|
||||||
|
const { Option } = Select;
|
||||||
|
|
||||||
|
let timeout;
|
||||||
|
let currentValue;
|
||||||
|
|
||||||
|
function curl(opts, callback) {
|
||||||
|
if (timeout) {
|
||||||
|
clearTimeout(timeout);
|
||||||
|
timeout = null;
|
||||||
|
}
|
||||||
|
currentValue = opts.value;
|
||||||
|
|
||||||
|
function fake() {
|
||||||
|
// console.log(currentValue, opts.value);
|
||||||
|
if (currentValue === opts.value && opts.value === '空') {
|
||||||
|
const _p = [{ 'key': '0', 'label': '空' }];
|
||||||
|
return callback(_p);
|
||||||
|
}
|
||||||
|
const param = {
|
||||||
|
code: 'utf-8',
|
||||||
|
q: opts.value,
|
||||||
|
};
|
||||||
|
// const str = new URLSearchParams({
|
||||||
|
// code: 'utf-8',
|
||||||
|
// q: opts.value,
|
||||||
|
// }).toString();
|
||||||
|
|
||||||
|
fetchJSON(`${opts.url}`, param)
|
||||||
|
.then(d => {
|
||||||
|
if (currentValue === opts.value) {
|
||||||
|
const result = objectMapper(d.result, opts.map) || [];
|
||||||
|
callback(result);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
timeout = setTimeout(fake, 300);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 异步请求的下拉菜单, 可搜索
|
||||||
|
* @property {array} defaultOptions 默认选项 [{key: '', label: '' }]
|
||||||
|
* @property {string} url
|
||||||
|
* @property {object} map 异步结果的字段转换定义
|
||||||
|
* @property {boolean} autoGet 首次默认请求
|
||||||
|
* @property {string} resultkey 结果的根字段
|
||||||
|
*/
|
||||||
|
class SearchInput extends React.Component {
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
data: this.props.defaultOptions || [],
|
||||||
|
value: undefined,
|
||||||
|
autoData: this.props.defaultOptions || [],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
if (this.props.autoGet === true) {
|
||||||
|
const { map, resultkey } = this.props;
|
||||||
|
const mapKey = Object.keys(map).reduce((r, v) => ({ ...r, [v]: { key: map[v] } }), {});
|
||||||
|
curl({ value: '', url: this.props.url || '', map: mapKey, resultkey }, (data) =>
|
||||||
|
this.setState({ data, autoData: data }, () => (typeof this.props.onSearchAfter === 'function' ? this.props.onSearchAfter(data, this.state.value) : ''))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidUpdate(prevProps) {
|
||||||
|
if (this.props.value !== prevProps.value) {
|
||||||
|
this.setState({ value: undefined });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handleClear = () => {
|
||||||
|
this.setState({ data: this.state.autoData });
|
||||||
|
};
|
||||||
|
|
||||||
|
handleSearch = value => {
|
||||||
|
if ( ! this.props.url && this.props.defaultOptions?.length) {
|
||||||
|
const f = this.props.defaultOptions.filter(r => String(r.label).indexOf(value) !== -1);
|
||||||
|
this.setState({ data: f || [] });
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const { map, resultkey } = this.props;
|
||||||
|
const mapKey = Object.keys(map).reduce((r, v) => ({ ...r, [v]: { key: map[v] } }), {});
|
||||||
|
if (value) {
|
||||||
|
curl({ value, url: this.props.url || '', map: mapKey, resultkey }, (data) =>
|
||||||
|
this.setState({ data }, () => (typeof this.props.onSearchAfter === 'function' ? this.props.onSearchAfter(data, this.state.value) : ''))
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
this.setState({ data: this.state.autoData || [] });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
handleChange = (value, option) => {
|
||||||
|
this.setState({ value }, () => this.props.onChange(value, option));
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const options = this.state.data.map(d => <Option key={d.key} extradata={d.options}>{d.label}</Option>);
|
||||||
|
const { onSearchAfter, defaultOptions, autoGet, ...props } = this.props;
|
||||||
|
return (
|
||||||
|
<Select
|
||||||
|
{...props}
|
||||||
|
style={this.props.style || { width: '100%' }}
|
||||||
|
showSearch
|
||||||
|
labelInValue
|
||||||
|
value={this.state.value || this.props.value}
|
||||||
|
placeholder={this.props.placeholder}
|
||||||
|
defaultActiveFirstOption={false}
|
||||||
|
showArrow={false}
|
||||||
|
filterOption={false}
|
||||||
|
onSearch={this.handleSearch}
|
||||||
|
onChange={this.handleChange}
|
||||||
|
notFoundContent={null}
|
||||||
|
allowClear={true}
|
||||||
|
onClear={this.handleClear}
|
||||||
|
>
|
||||||
|
{options}
|
||||||
|
</Select>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default observer(SearchInput);
|
Loading…
Reference in New Issue