208 lines
7.9 KiB
JavaScript
208 lines
7.9 KiB
JavaScript
/*
|
|
* 自定义穿梭框组件
|
|
* 弹框选择
|
|
* @Author: 黎永顺
|
|
* @Date: 2024/8/30
|
|
* @Wechat:
|
|
* @Email: 971387674@qq.com
|
|
* @description:
|
|
*/
|
|
import React, { Component } from "react";
|
|
import { WeaDialog, WeaInputSearch, WeaLocaleProvider, WeaNewScroll } from "ecCom";
|
|
import { Button, Col, Row, Spin } from "antd";
|
|
import CustomBrowserMutiLeft from "./customBrowserMutiLeft";
|
|
import CustomBrowserMutiRight from "./customBrowserMutiRight";
|
|
import CustomBrowserOperation from "./customBrowserOperation";
|
|
import { postFetch } from "../../../util/request";
|
|
import "../index.less";
|
|
|
|
const getLabel = WeaLocaleProvider.getLabel;
|
|
|
|
class CustomTransferDialog extends Component {
|
|
constructor(props) {
|
|
super(props);
|
|
this.state = {
|
|
loading: false, listDatas: [],
|
|
query: { [props.searchParamsKey]: "" },
|
|
leftListSelectedKeys: [], // 左侧table选择的keys
|
|
leftListSelectedData: [], // 左侧table选择的数据
|
|
rightCheckedKeys: [], //右侧选择的keys
|
|
rightDatas: [] // 右侧展示的数据
|
|
};
|
|
this.selectedData = {};
|
|
}
|
|
|
|
componentWillReceiveProps(nextProps, nextContext) {
|
|
if (nextProps.visible !== this.props.visible && nextProps.visible) {
|
|
this.getData(true, nextProps);
|
|
if (nextProps.datas) {
|
|
this.setState({
|
|
leftListSelectedData: _.values(nextProps.datas), rightDatas: _.values(nextProps.datas)
|
|
});
|
|
}
|
|
} else if (nextProps.visible !== this.props.visible && !nextProps.visible) {
|
|
this.setState({
|
|
query: { [this.props.searchParamsKey]: "" },
|
|
rightDatas: [], rightCheckedKeys: [], leftListSelectedData: [], leftListSelectedKeys: []
|
|
});
|
|
this.selectedData = {};
|
|
}
|
|
}
|
|
|
|
getData = (init = false, props) => {
|
|
const { query } = this.state;
|
|
const { completeURL, convertDatasource, dataParams = {} } = props || this.props;
|
|
let payload = { ...dataParams, ...query };
|
|
this.setState({ loading: true });
|
|
postFetch(completeURL, payload).then(({ status, data }) => {
|
|
this.setState({ loading: false });
|
|
if (status && data.list) {
|
|
const { pageNum: current, pageSize, total } = data;
|
|
this.setState({
|
|
listDatas: convertDatasource ? convertDatasource(data.list) : data.list
|
|
});
|
|
} else {
|
|
this.setState({
|
|
listDatas: convertDatasource ? convertDatasource(data).listDatas : [],
|
|
leftListSelectedData: (init && convertDatasource) ? convertDatasource(data).checked : this.state.leftListSelectedData,
|
|
rightDatas: (init && convertDatasource) ? convertDatasource(data).checked : this.state.rightDatas
|
|
});
|
|
}
|
|
});
|
|
};
|
|
handleOk = () => {
|
|
const { rightDatas } = this.state;
|
|
this.props.onChange && this.props.onChange(rightDatas);
|
|
};
|
|
onLeftListCheck = (keys, datas) => {
|
|
const { leftListSelectedData } = this.state;
|
|
let targets = leftListSelectedData.concat(datas);
|
|
targets = _.uniqBy(targets, "id");
|
|
targets = targets.filter((t) => keys.indexOf(t["id"]) > -1);
|
|
this.setState({ leftListSelectedKeys: keys, leftListSelectedData: targets });
|
|
};
|
|
onleftDoubleClick = (data) => {
|
|
const { rightDatas } = this.state;
|
|
this.setState({
|
|
rightDatas: rightDatas.concat(data),
|
|
rightCheckedKeys: [],
|
|
leftListSelectedData: [],
|
|
leftListSelectedKeys: []
|
|
});
|
|
};
|
|
onRightDoubleClick = (key) => {
|
|
const { rightDatas } = this.state;
|
|
const newRightDatas = rightDatas.filter(item => String(item.id) !== key);
|
|
this.setState({ rightDatas: newRightDatas, rightCheckedKeys: [] });
|
|
};
|
|
moveTo = (direction) => {
|
|
const { rightDatas, rightCheckedKeys, listDatas, leftListSelectedData } = this.state;
|
|
if (direction === "right") {
|
|
this.setState({
|
|
rightDatas: rightDatas.concat(leftListSelectedData),
|
|
leftListSelectedData: [],
|
|
leftListSelectedKeys: []
|
|
});
|
|
} else if (direction === "left") {
|
|
this.setState({
|
|
rightDatas: rightDatas.filter(item => !rightCheckedKeys.some(checkedKey => String(item.id) === checkedKey)),
|
|
rightCheckedKeys: []
|
|
});
|
|
} else if (direction === "allToLeft") {
|
|
this.setState({ rightDatas: [], rightCheckedKeys: [] });
|
|
} else if (direction === "allToRight") {
|
|
if (this.leftListAllActive()) {
|
|
this.setState({
|
|
rightDatas: rightDatas.concat(listDatas),
|
|
rightCheckedKeys: [],
|
|
leftListSelectedData: [],
|
|
leftListSelectedKeys: []
|
|
});
|
|
}
|
|
}
|
|
};
|
|
leftListAllActive = () => {
|
|
const { rightDatas, listDatas } = this.state;
|
|
let bool = true;
|
|
if (_.isEmpty(listDatas)) bool = false;
|
|
if (!_.isEmpty(listDatas) && !_.isEmpty(rightDatas)) {
|
|
bool = listDatas.filter((l) => !rightDatas.some(r => l.id === r.id)).length !== 0;
|
|
}
|
|
return bool;
|
|
};
|
|
renderTitle = () => {
|
|
return (<div className="wea-hr-muti-dialog-title">
|
|
<span>{getLabel(111, "数据选择")}</span>
|
|
<div/>
|
|
</div>);
|
|
};
|
|
|
|
render() {
|
|
const { loading, listDatas, query, leftListSelectedKeys, rightDatas, rightCheckedKeys } = this.state;
|
|
const { searchParamsKey, saveLoading } = this.props;
|
|
const buttons = [
|
|
<Button type="primary" loading={saveLoading} onClick={this.handleOk}
|
|
disabled={_.isEmpty(rightDatas)}>{getLabel(111, "确 定")}</Button>,
|
|
<Button type="ghost" onClick={this.props.onCancel}>{getLabel(111, "取 消")}</Button>];
|
|
let rightActive = false, leftActive = false, rightAllActive = false;
|
|
if (leftListSelectedKeys && leftListSelectedKeys.length > 0) rightActive = true;
|
|
if (rightCheckedKeys && rightCheckedKeys.length > 0) leftActive = true;
|
|
if (rightDatas && rightDatas.length > 0) rightAllActive = true;
|
|
let dom = <Spin spinning={loading}>
|
|
<div className="wea-hr-muti-dialog">
|
|
<div className="wea-hr-muti-input-left">
|
|
<Row style={{ height: 35 }}>
|
|
<Col span="24">
|
|
<WeaInputSearch value={query[searchParamsKey]} onSearch={() => this.getData()}
|
|
onChange={value => this.setState({ query: { ...query, [searchParamsKey]: value } })}
|
|
/>
|
|
</Col>
|
|
</Row>
|
|
<div>
|
|
<WeaNewScroll height={this.dialog ? this.dialog.state.height - 51 : 260}>
|
|
<CustomBrowserMutiLeft
|
|
filterData={rightDatas}
|
|
datas={listDatas}
|
|
onDoubleClick={this.onleftDoubleClick}
|
|
onClick={this.onLeftListCheck}
|
|
selectedKeys={leftListSelectedKeys}
|
|
/>
|
|
</WeaNewScroll>
|
|
</div>
|
|
</div>
|
|
<div className="wea-transfer-opration">
|
|
<CustomBrowserOperation
|
|
rightActive={rightActive}
|
|
leftActive={leftActive}
|
|
leftAllActive={this.leftListAllActive()}
|
|
rightAllActive={rightAllActive}
|
|
moveToRight={() => this.moveTo("right")}
|
|
moveToLeft={() => this.moveTo("left")}
|
|
moveAllToRight={() => this.moveTo("allToRight")}
|
|
moveAllToLeft={() => this.moveTo("allToLeft")}
|
|
/>
|
|
</div>
|
|
<div className="wea-hr-muti-input-right">
|
|
<CustomBrowserMutiRight
|
|
height={this.dialog ? this.dialog.state.height - 51 : 260}
|
|
data={rightDatas} checkedKeys={rightCheckedKeys}
|
|
checkedCb={rightCheckedKeys => this.setState({ rightCheckedKeys })}
|
|
onDoubleClick={this.onRightDoubleClick}
|
|
onDrag={(data) => {this.setState({rightDatas: data})}}
|
|
/>
|
|
</div>
|
|
</div>
|
|
</Spin>;
|
|
return (
|
|
<WeaDialog
|
|
{...this.props} initLoadCss ref={dom => this.dialog = dom} title={this.renderTitle()}
|
|
className="custom_browser_dialog" draggable={false} style={{
|
|
width: 784, height: 460, minHeight: 200, minWidth: 380,
|
|
maxHeight: "90%", maxWidth: "90%", overflow: "hidden", transform: "translate(0px, 0px)"
|
|
}} buttons={buttons}>{dom}</WeaDialog>
|
|
);
|
|
}
|
|
}
|
|
|
|
export default CustomTransferDialog;
|