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

300 lines
12 KiB
JavaScript

/*
* 自定义浏览框组件
* 弹框选择
* @Author: 黎永顺
* @Date: 2024/8/30
* @Wechat:
* @Email: 971387674@qq.com
* @description:
*/
import React, { Component } from "react";
import { WeaDialog, WeaInputSearch, WeaLocaleProvider, WeaNewScroll, WeaTable, WeaTransfer } 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";
const WeaTransferList = WeaTransfer.list;
const getLabel = WeaLocaleProvider.getLabel;
class CustomBrowserDialog extends Component {
constructor(props) {
super(props);
this.state = {
loading: false, listDatas: [], pageInfo: { current: 1, pageSize: 10, total: 0 }, selectedRowKeys: [],
query: { [props.searchParamsKey]: "" }, singleFilterVal: "",
leftListSelectedKeys: [], // 左侧table选择的keys
leftListSelectedData: [], // 左侧table选择的数据
rightCheckedKeys: [], //右侧选择的keys
rightDatas: [] // 右侧展示的数据
};
this.selectedData = {};
}
componentWillReceiveProps(nextProps, nextContext) {
if (nextProps.visible !== this.props.visible && nextProps.visible) {
this.getData();
this.setState({
selectedRowKeys: nextProps.selectedValues,
leftListSelectedData: _.values(nextProps.datas), rightDatas: _.values(nextProps.datas)
});
} else {
this.setState({
pageInfo: { current: 1, pageSize: 10, total: 0 }, query: { [this.props.searchParamsKey]: "" },
rightDatas: [], rightCheckedKeys: [], leftListSelectedData: [], leftListSelectedKeys: []
});
this.selectedData = {};
}
}
getData = () => {
const { pageInfo, query } = this.state;
const { dialogType, completeURL, convertDatasource, dataParams = {} } = this.props;
let payload = { ...dataParams, ...query };
dialogType === "table" && (payload = { ...pageInfo, ...payload, ...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,
pageInfo: { ...pageInfo, current, pageSize, total }
});
} else {
this.setState({ listDatas: _.map(data, o => ({ ...o, id: String(o.id) })) });
}
});
};
handleRowClick = record => {
if (!this.props.isSingle) return;
const values = [record.id];
const selectedData = { [record["id"]]: record };
this.props.onCancel();
this.props.onChange && this.props.onChange(values, selectedData);
};
handleClear = () => {
this.props.onCancel();
this.props.onChange && this.props.onChange([], {});
};
handleOk = () => {
const { selectedRowKeys, rightDatas } = this.state, { dialogType } = this.props;
const convertSelectedRowKeys = dialogType !== "table" ? rightDatas.map((v) => v.id) : selectedRowKeys;
convertSelectedRowKeys.forEach((v) => {
let item = this.getItemById(v);
if (item) this.selectedData[v] = item;
});
this.props.onChange && this.props.onChange(convertSelectedRowKeys, this.selectedData);
this.props.onCancel && this.props.onCancel();
};
getItemById = (id) => {
const { listDatas } = this.state;
if (this.selectedData[id]) return this.selectedData[id];
if (!_.isEmpty(listDatas)) {
for (let i = 0; i < listDatas.length; i++) {
if (String(id) === String(listDatas[i].id)) return listDatas[i];
}
}
};
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 = () => {
const { dialogType, searchParamsKey, isSingle } = this.props, {
query, pageInfo, selectedRowKeys, singleFilterVal
} = this.state;
return (<div className="wea-hr-muti-dialog-title">
<span>{getLabel(111, "数据选择")}</span>
{
dialogType === "table" ?
<WeaInputSearch
value={query[searchParamsKey]} style={{ width: 220 }}
onChange={value => this.setState({ query: { ...query, [searchParamsKey]: value } })}
onSearch={() => {
this.setState({ pageInfo: { ...pageInfo, current: 1 } }, () => {
this.getData();
selectedRowKeys.forEach((v) => {
let item = this.getItemById(v);
if (item) this.selectedData[v] = item;
});
});
}}/> : isSingle ?
<WeaInputSearch value={singleFilterVal} onChange={singleFilterVal => this.setState({ singleFilterVal })}/> :
<div/>
}
</div>);
};
render() {
const {
loading, listDatas, pageInfo, selectedRowKeys, query, leftListSelectedKeys, rightDatas, rightCheckedKeys,
singleFilterVal
} = this.state;
const { dialogType, tableProps: { rowKey, columns }, isSingle, searchParamsKey } = this.props;
const sheight = this.dialog ? this.dialog.state.height - 116 : 260;
const buttons = [
<Button type="primary" onClick={this.handleOk}
disabled={dialogType !== "table" && _.isEmpty(rightDatas)}>{getLabel(111, "确 定")}</Button>,
<Button type="ghost" onClick={this.handleClear}>{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">
{
!isSingle ? <React.Fragment>
<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}
/>
</div>
</React.Fragment> :
<WeaTransferList height={this.dialog ? this.dialog.state.height - 16 : 260} checkedKeys={[]}
checkedCb={([id]) => this.handleRowClick(_.find(listDatas, item => item.id === id))}
data={listDatas.filter((item) => item.name.indexOf(_.trim(singleFilterVal)) > -1)}/>
}
</div>
</Spin>;
if (dialogType === "table") {
const pagination = {
...pageInfo,
showTotal: total => `${getLabel(18609, "共")} ${total} ${getLabel(18256, "条")}`,
showQuickJumper: true,
showSizeChanger: true,
pageSizeOptions: ["10", "20", "50", "100"],
onShowSizeChange: (current, pageSize) => {
this.setState({
pageInfo: { ...pageInfo, current, pageSize }
}, () => {
this.getData();
selectedRowKeys.forEach((v) => {
let item = this.getItemById(v);
if (item) this.selectedData[v] = item;
});
});
},
onChange: current => {
this.setState({ pageInfo: { ...pageInfo, current } }, () => {
this.getData();
selectedRowKeys.forEach((v) => {
let item = this.getItemById(v);
if (item) this.selectedData[v] = item;
});
});
}
};
const rowSelection = {
selectedRowKeys,
onChange: selectedRowKeys => this.setState({ selectedRowKeys })
};
dom = <div className="wea-hr-muti-input-table">
<WeaTable dataSource={listDatas} loading={loading} pagination={pagination} scroll={{ y: sheight }}
onRowClick={this.handleRowClick} rowSelection={!isSingle ? rowSelection : null}
rowKey={rowKey || "id"} columns={columns}/>
</div>;
}
dialogType === "table" && isSingle && buttons.splice(0, 1);
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 CustomBrowserDialog;