salary-management-front/pc4mobx/hrmSalary/components/CustomBrowser/components/associativeSearchMult.js

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;