166 lines
5.5 KiB
JavaScript
166 lines
5.5 KiB
JavaScript
/*
|
|
* 自定义浏览框组件
|
|
* 多选
|
|
* @Author: 黎永顺
|
|
* @Date: 2024/8/29
|
|
* @Wechat:
|
|
* @Email: 971387674@qq.com
|
|
* @description:
|
|
*/
|
|
import React, { Component } from "react";
|
|
import { WeaLocaleProvider } from "ecCom";
|
|
import { Button, Icon, Select } from "antd";
|
|
import { postFetch } from "../../../util/request";
|
|
import classNames from "classnames";
|
|
|
|
const getLabel = WeaLocaleProvider.getLabel;
|
|
const Option = Select.Option;
|
|
|
|
class AssociativeSearchMult extends Component {
|
|
constructor(props) {
|
|
super(props);
|
|
this.state = {
|
|
loading: false, data: [], activeKey: "", dropdownWidth: 200
|
|
};
|
|
this.selectedData = {};
|
|
}
|
|
|
|
componentDidMount() {
|
|
const { dropdownWidth } = this.state;
|
|
const w = $(this.refs.searchWrapperMui).outerWidth();
|
|
if (dropdownWidth < w) {
|
|
this.setState({ dropdownWidth: w });
|
|
}
|
|
}
|
|
|
|
handleSearch = (value) => {
|
|
this.setState({ loading: true });
|
|
this.getData(value);
|
|
};
|
|
getData = (name = "") => {
|
|
const { browserConditionParam } = this.props;
|
|
const {
|
|
completeURL, filterByName, searchParamsKey, convertDatasource, dataParams = {}
|
|
} = browserConditionParam;
|
|
if (_.trim(name)) {
|
|
let payload = { ...dataParams };
|
|
searchParamsKey && (payload = { ...payload, [searchParamsKey]: name, current: 1, pageSize: 9999 });
|
|
postFetch(completeURL, payload).then(({ status, data }) => {
|
|
this.setState({ loading: false });
|
|
if (status && data.list) {
|
|
this.setState({
|
|
data: convertDatasource ? convertDatasource(data.list) : data.list,
|
|
activeKey: this.getActiveKey(convertDatasource ? convertDatasource(data.list) : data.list)
|
|
});
|
|
} else {
|
|
this.setState({
|
|
data: filterByName ? _.filter(_.map(data, o => ({
|
|
...o, id: String(o.id), name: o.name
|
|
})), k => k.name.indexOf(name) !== -1) : _.map(data, o => ({ ...o, id: String(o.id), name: o.name })),
|
|
activeKey: this.getActiveKey(data)
|
|
});
|
|
}
|
|
});
|
|
} else {
|
|
this.setState({ data: [], loading: false, activeKey: "" });
|
|
}
|
|
};
|
|
getActiveKey = (data) => {
|
|
const { selectedValues = [] } = this.props;
|
|
let v = "";
|
|
if (data && data.length > 0) {
|
|
let target = data.filter((d) => selectedValues.indexOf(d.id) === -1);
|
|
if (!_.isEmpty(target)) v = String(target[0].id);
|
|
}
|
|
return v;
|
|
};
|
|
getItemById = (id) => {
|
|
const { data } = this.state, { datas } = this.props;
|
|
if (datas[id]) return datas[id];
|
|
if (!_.isEmpty(data)) {
|
|
for (let i = 0; i < data.length; i++) {
|
|
if (id === data[i].id) return data[i];
|
|
}
|
|
}
|
|
};
|
|
handleChange = (values) => {
|
|
this.selectedData = {};
|
|
values.forEach((v) => {
|
|
let item = this.getItemById(v);
|
|
if (item) this.selectedData[v] = item;
|
|
});
|
|
this.props.onChange && this.props.onChange(values, this.selectedData);
|
|
this.setState({ activeKey: "" });
|
|
};
|
|
handleBlur = () => this.setState({ data: [], activeKey: "" });
|
|
handleClick = (e) => {
|
|
e && e.preventDefault();
|
|
const { datas, selectedValues } = this.props;
|
|
if (this.props.clickCallback) this.props.clickCallback(selectedValues, datas);
|
|
};
|
|
isReadOnly = () => {
|
|
const { viewAttr } = this.props;
|
|
return viewAttr === 1 || viewAttr === "1";
|
|
};
|
|
|
|
render() {
|
|
const { data, dropdownWidth } = this.state;
|
|
const { viewAttr, selectedValues, datas, isSingle, browserConditionParam = {} } = this.props;
|
|
const clsname = classNames({
|
|
"required": (viewAttr === 3 || viewAttr === "3") && _.isEmpty(selectedValues),
|
|
"mr12": viewAttr === "3" && _.isEmpty(selectedValues),
|
|
"wea-associative-single": (isSingle || browserConditionParam.isSingle),
|
|
"wea-associative-search-mult": !(isSingle || browserConditionParam.isSingle)
|
|
});
|
|
if (this.isReadOnly()) {
|
|
let arr = [];
|
|
selectedValues && selectedValues.map(v => {
|
|
let item = datas[v].name;
|
|
if (_.isString(item)) {
|
|
arr.push(<a className="child-item wdb">{item}</a>);
|
|
} else {
|
|
arr.push(<a className="child-item wdb" dangerouslySetInnerHTML={{ __html: item }}> </a>);
|
|
}
|
|
});
|
|
return (
|
|
<span className={`wea-associative-search wea-field-readonly ${clsname} `} ref="searchWrapperMui">{arr}</span>
|
|
);
|
|
}
|
|
let options = data.map(d => <Option key={d.id} title={d.name}>{d.name}</Option>);
|
|
selectedValues && selectedValues.map((v) => {
|
|
v && options.unshift(<Option key={v} title={datas[v].name}>{datas[v].name}</Option>);
|
|
});
|
|
const select = <Select
|
|
{...this.props}
|
|
hasScroll={false}
|
|
hideSelected={true}
|
|
transitionName=""
|
|
animation=""
|
|
multiple={true}
|
|
notFoundContent=""
|
|
defaultActiveFirstOption={true}
|
|
showArrow={false}
|
|
filterOption={false}
|
|
defaultValue={selectedValues}
|
|
value={selectedValues}
|
|
dropdownStyle={{ minWidth: dropdownWidth }}
|
|
onSearch={_.debounce(this.handleSearch, 400)}
|
|
onChange={this.handleChange}
|
|
onBlur={this.handleBlur}
|
|
>
|
|
{options}
|
|
</Select>;
|
|
return (
|
|
<div className={`wea-associative-search ${clsname}`} ref="searchWrapperMui">
|
|
{select}
|
|
<Icon type="loading" style={{ display: this.state.loading ? "block" : "none" }}/>
|
|
<div className="ant-input-group-wrap">
|
|
<Button type="ghost" icon="search" onClick={this.handleClick}/>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
}
|
|
|
|
export default AssociativeSearchMult;
|