salary-management-front/pc4mobx/hrmSalary/pages/salaryFile/index.js

753 lines
23 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React, { Fragment } from "react";
import { inject, observer } from "mobx-react";
import { WeaTableNew } from "comsMobx";
import { Button, Dropdown, Menu, message, Modal } from "antd";
import {
WeaBrowser,
WeaCheckbox,
WeaDatePicker,
WeaError,
WeaFormItem,
WeaHelpfulTip,
WeaInput,
WeaRightMenu,
WeaSearchGroup,
WeaSelect,
WeaSlideModal,
WeaTab,
WeaTop
} from "ecCom";
import { renderNoright } from "../../util"; // 渲染form数据的方法因为多个页面都会使用所以抽的公共方法在util中
import ChangeSalaryModal from "./changeSalaryModal";
import EditAgentModal from "./editAgentModal";
import SlideModalTitle from "../../components/slideModalTitle";
import SlideSalaryItem from "./slideSalaryItem";
import SlideAgent from "./slideAgent";
import ImportModal from "../../components/importModal";
import SalaryFileViewSlide from "./saralyFileViewSlide";
import CustomPaginationTable from "../../components/customPaginationTable";
import "./index.less";
const WeaTableComx = WeaTableNew.WeaTable;
@inject("salaryFileStore", "taxAgentStore")
@observer
export default class SalaryFile extends React.Component {
constructor(props) {
super(props);
this.state = {
value: "",
selectedKey: "0",
changeSalaryVisible: false,
editAgentVisible: false,
selectedTab: 0,
editSlideVisible: false,
importType: "",
isInit: false, //是否是初始化导入
modalVisiable: false,
step: 0,
recordSlideVisible: false,
selectedRowKeys: [],
showSearchBar: false,
importResult: {},
searchValue: "",
searchItemsValue: {
username: "",
departmentIds: "",
positionIds: "",
userstatus: "",
archiveStatus: "EFFICIENT",
taxAgentId: "",
subcompanyIds: ""
},
noPayDate: "" //最后停薪日期
};
this.pageInfo = { current: 1, pageSize: 10 };
}
Input = (value, key) => {
const { username } = this.state.searchItemsValue;
return (
<WeaFormItem
label={value}
labelCol={{ span: 6 }}
wrapperCol={{ span: 18 }}
>
<WeaInput value={username} onChange={(val) => this.setState({
searchItemsValue: {
...this.state.searchItemsValue,
[key]: val
}
})}/>
</WeaFormItem>
);
};
Browser = (value, key) => {
const { positionIds, departmentIds, subcompanyIds } = this.state.searchItemsValue;
return (
<WeaFormItem
label={value}
labelCol={{ span: 6 }}
wrapperCol={{ span: 18 }}
>
<WeaBrowser
isSingle={false}
value={key === "departmentIds" ? departmentIds : key === "subcompanyIds" ? subcompanyIds : positionIds}
tabs={key === "departmentIds" ? [
{
dataParams: null,
dataURL: null,
isSearch: false,
key: "2",
name: "组织结构",
selected: false,
showOrder: 0
},
{
dataParams: { list: "1" },
dataURL: null,
isSearch: true,
key: "1",
name: "按列表",
selected: false,
showOrder: 0
}
] : null}
type={key === "departmentIds" ? 57 : key === "subcompanyIds" ? 164 : 278}
onChange={(val) => {
this.setState({ searchItemsValue: { ...this.state.searchItemsValue, [key]: val } });
}}/>
</WeaFormItem>
);
};
Select = (value, key) => {
const { salaryFileStore, taxAgentStore } = this.props;
const { userstatus, archiveStatus, taxAgentId } = this.state.searchItemsValue;
const { archiveStatusList, userStatusList } = salaryFileStore;
const { taxAgentAdminOption } = taxAgentStore;
return (
<WeaFormItem
label={value}
labelCol={{ span: 6 }}
wrapperCol={{ span: 18 }}
>
<WeaSelect
value={key === "userstatus" ? userstatus : key === "taxAgentId" ? taxAgentId : archiveStatus}
options={key === "userstatus" ? userStatusList : key === "taxAgentId" ? [{
key: "",
showname: ""
}, ...taxAgentAdminOption] : archiveStatusList}
onChange={(val) => this.setState({ searchItemsValue: { ...this.state.searchItemsValue, [key]: val } })}/>
</WeaFormItem>
);
};
componentWillMount() {
const { salaryFileStore: { doInit }, taxAgentStore: { getTaxAgentSelectListAsAdmin } } = this.props;
doInit({ ...this.state.searchItemsValue });
getTaxAgentSelectListAsAdmin();
}
// 设置导入步数
setStep(step) {
this.setState({ step });
}
// 渲染导入模板附加元素
renderFormComponent() {
return (
<div style={{ display: "inline-block" }}>
<WeaCheckbox id="importData" content="导出现有数据"/>
<WeaHelpfulTip
width={200}
title="提示:建议先导出现有最新数据,修改后再导入"
placement="topLeft"
/>
</div>
);
}
// 导入预览
handlePreviewImport(params) {
const {
salaryFileStore: { importPreview }
} = this.props;
params.importType = this.state.importType;
importPreview(params);
}
// 导入档案
handleImportFile(params) {
const {
salaryFileStore: { importSalaryArchive }
} = this.props;
params.importType = this.state.importType;
importSalaryArchive(params, this.state.searchItemsValue).then((data) => {
data.errorData = data.errorNotice;
this.setState({
importResult: data
});
});
}
// 导入完成按钮操作
handleImportFinish() {
this.setState({ modalVisiable: false, step: 0 });
}
// 导出全部
handleExportAll=()=> {
let url = `${window.location.origin}/api/bs/hrmsalary/salaryArchive/exportList?ids=`;
const { searchItemsValue } = this.state;
const fileds= Object.keys(searchItemsValue);
_.forEach(fileds, it => {
url= `${url}&${it}=${searchItemsValue[it]}`
})
window.open(url, "_self");
}
// 定制列
getColumns() {
const {
salaryFileStore: { tableStore }
} = this.props;
return tableStore.columns
.filter((item) => item.display == "true")
.map((item) => {
item.width = item.oldWidth;
if (item.dataIndex == "operate") {
item.render = (text, record) => (
<a onClick={() => this.handleEdit(record)}>查看</a>
);
item.fixed = "right";
} else if (item.dataIndex == "username") {
item.fixed = "left";
}
return item;
});
}
// 编辑行
handleEdit(record) {
this.setState({ editSlideVisible: true });
const {
salaryFileStore: { setCurrentId }
} = this.props;
setCurrentId(record.id);
}
// 停薪
handleNoPay = () => {
const {
salaryFileStore: { stopSalary, getTableDatas }
} = this.props;
Modal.confirm({
title: "停薪确认",
content: <WeaFormItem
label="最后发薪日期"
labelCol={{ span: 6 }}
wrapperCol={{ span: 18 }}
>
<WeaDatePicker
value={this.state.noPayDate}
viewAttr={3}
style={{ width: "100%" }}
onChange={noPayDate => this.setState({ noPayDate })}
/>
</WeaFormItem>,
width: 516,
onOk: () => {
if (_.isEmpty(this.state.noPayDate)) {
message.warning("请选择最后发薪日期")
return false;
}
stopSalary(this.state.noPayDate).then(() => {
getTableDatas({ ...this.state.searchItemsValue });
});
},
onCancel: () => {
}
})
};
// 查看 Slide 头部操作按钮
renderEditSlideOperate = () => {
const { taxAgentStore: { showOperateBtn }, salaryFileStore: { salaryIncreaseUrl, currentId } } = this.props;
const { isShow, url } = salaryIncreaseUrl;
let arrList = [];
if (showOperateBtn && isShow === "true") {
arrList.push(<Button type="primary" onClick={() => {
window.open(`${url}&salaryArchiveId=${currentId}`);
}}>发起调薪</Button>);
}
if (showOperateBtn) {
arrList.push(<Button type="primary" onClick={() => {
this.setState({ changeSalaryVisible: true });
}}>调薪</Button>);
arrList.push(<Button type="primary" onClick={this.handleNoPay}>停薪</Button>);
}
return arrList;
};
// table选中条目
onSelectChange = (selectedRowKeys) => {
this.setState({ selectedRowKeys });
};
// 显示影响搜索面板
handleShowSearchBar = () => {
this.setState({
showSearchBar: !this.state.showSearchBar
});
};
// 页面跳转
handlePageChange = (value) => {
const { salaryFileStore: { getTableDatas, form } } = this.props;
this.pageInfo.current = value;
getTableDatas({ ...this.state.searchItemsValue, ...this.pageInfo });
};
handleShowSizeChange(pageInfo) {
const { salaryFileStore: { getTableDatas, form } } = this.props;
getTableDatas({ ...this.state.searchItemsValue, ...pageInfo });
}
// 搜索
handleSearch(value) {
const {
salaryFileStore: { getTableDatas, form }
} = this.props;
getTableDatas({ username: value });
}
// 初始化导入参数
handleInitModal() {
const {
salaryFileStore: { setPreviewDataSource }
} = this.props;
setPreviewDataSource([]);
this.setState({
importResult: {}
});
}
showColumn = () => {
const { salaryFileStore: { tableStore } } = this.props;
// console.log("showColumn:", tableStore.setColSetVisible(true));
tableStore.setColSetVisible(true);
tableStore.tableColSet(true);
// console.log("showColumn:");
};
render() {
const { salaryFileStore, taxAgentStore: { showOperateBtn } } = this.props;
const {
loading,
hasRight,
form,
condition,
tableStore,
showSearchAd,
getTableDatas,
doSearch,
setShowSearchAd,
setSalaryIncreaseUrl
} = salaryFileStore;
const {
importType,
previewColumns,
previewDataSource,
dataSource,
currentId,
editAgentVisible,
setEditAgentVisible,
pageInfo
} = salaryFileStore;
const { selectedTab, step, selectedRowKeys } = this.state;
if (!hasRight && !loading) {
// 无权限处理
return renderNoright();
}
const rightMenu = [
// 右键菜单
{
key: "BTN_COLUMN",
icon: <i className="icon-coms-Custom"/>,
content: "显示列定制",
onClick: this.showColumn
}
];
const collectParams = {
// 收藏功能配置
favname: "薪资档案",
favouritetype: 1,
objid: 0,
link: "wui/index.html#/ns_demo03/index",
importantlevel: 1
};
const adBtn = [
// 高级搜索内部按钮
<Button type="primary" onClick={() => doSearch(this.state.searchItemsValue)}>
搜索
</Button>,
<Button type="ghost" onClick={() => this.setState({
searchItemsValue: {
username: "",
departmentIds: "",
positionIds: "",
userstatus: "",
archiveStatus: ""
}
})}>
重置
</Button>,
<Button type="ghost" onClick={() => setShowSearchAd(false)}>
取消
</Button>
];
const topTab = [];
const renderSearchOperationItem = () => {
};
const handleMenuClick = (e) => {
const { key } = e;
if (key === "init") {
Modal.confirm({
title: "信息确认",
content: `若导入表格中的人员已存在在薪资档案中,初始化导入会将档案中该人员的数据清除再导入,点击确定继续导入`,
onOk: () => {
this.setState({ importType: e.key, isInit: true, modalVisiable: true, step: 0 });
},
onCancel() {
}
});
} else {
this.setState({ importType: e.key, isInit: true, modalVisiable: true, step: 0 });
}
};
const handleMenuClick2 = () => {
const { electedRowKeys } = this.state;
if (selectedRowKeys.length == 0) {
message.warning("未选择条目");
return;
}
// const {
// salaryFileStore: { exportSalaryArchive }
// } = this.props;
// exportSalaryArchive(selectedRowKeys.join(","));
const url = `${window.location.origin}/api/bs/hrmsalary/salaryArchive/exportList?ids=${selectedRowKeys.join(",")}`;
window.open(url, "_self");
};
const menu = (
<Menu onClick={handleMenuClick}>
{/*暂时去掉调整个税扣缴义务人导入按钮*/}
{_.filter(importType, it => it.id !== "taxAgentAdjust").map((item) => (
<Menu.Item key={item.id}>{item.content}</Menu.Item>
))}
</Menu>
);
const menu2 = (
<Menu onClick={handleMenuClick2}>
<Menu.Item key="1">导出所选</Menu.Item>
</Menu>
);
const renderRightOperation = () => {
return (
<div
style={{
marginTop: 10
}}
className="salaryFileTabWrapper">
{
showOperateBtn &&
<Fragment>
<WeaHelpfulTip
style={{ marginRight: "10px" }}
width={300}
title="导入按钮使用场景说明:<br/>
1.档案初始化:<br/>
a.初次使用薪酬模块,全量导入员工的薪资档案数据;<br/>
b.员工入职,导入新入职的员工的薪资档案数据(若导入表格中的人员已存在在薪资档案中,初始化导入会将档案中该人员的数据清除再导入);<br/>
c.返聘人员使用调薪功能调整薪资档案值或使用调整个税扣缴;<br/>
2.调薪:档案中已存在的人员批量调整薪资项目值(包括返聘人员的情况);<br/>
3.调整个税扣缴义务人:档案中已存在的人员批量调整个税扣缴义务人(包括返聘人员的情况);<br/>"
placement="topLeft"
/>
<Dropdown.Button
type="primary"
style={{ marginRight: "10px" }}
overlay={menu}>
导入
</Dropdown.Button>
<Dropdown.Button
style={{ marginRight: "10px" }}
overlay={menu2}
onClick={() => {
this.handleExportAll();
}}>
导出全部
</Dropdown.Button>
</Fragment>
}
{/*暂时隐藏*/}
{/*<Button*/}
{/* type="default"*/}
{/* style={{ marginRight: "10px" }}*/}
{/* onClick={() => {*/}
{/* this.setState({ recordSlideVisible: true });*/}
{/* }}>*/}
{/* 调薪记录*/}
{/*</Button>*/}
{/*<WeaInputSearch*/}
{/* value={this.state.searchValue}*/}
{/* onChange={(value) => {*/}
{/* this.setState({*/}
{/* searchValue: value*/}
{/* });*/}
{/* }}*/}
{/* onSearch={(value) => {*/}
{/* this.handleSearch(value);*/}
{/* }}*/}
{/*/>*/}
{/* <Button type="default" onClick={() =>{this.handleShowSearchBar()}}>高级搜索</Button> */}
</div>
);
};
const renderSearch = () => {
const searchItems = [
{ com: this.Input("姓名", "username") },
{ com: this.Browser("分部", "subcompanyIds") },
{ com: this.Browser("部门", "departmentIds") },
{ com: this.Browser("岗位", "positionIds") },
{ com: this.Select("人员状态", "userstatus") },
{ com: this.Select("档案状态", "archiveStatus") },
{ com: this.Select("个税扣缴义务人", "taxAgentId") }
];
return <WeaSearchGroup title={"基本信息"} items={searchItems} showGroup/>;
};
const handleSlideMoreMenuClick = () => {
};
const slideMoreMenu = (
<Menu onClick={handleSlideMoreMenuClick}>
<Menu.Item key="1">导出全部</Menu.Item>
</Menu>
);
const renderCustomOperate = () => {
return (
<div style={{ display: "inline-block" }}>
<Dropdown.Button type="primary" overlay={slideMoreMenu}>
导出
</Dropdown.Button>
<Button type="default">自定义列</Button>
</div>
);
};
const rowSelection = {
selectedRowKeys,
onChange: this.onSelectChange
};
return (
<div className="mySalaryBenefitsWrapper">
<WeaRightMenu
datas={rightMenu} // 右键菜单
collectParams={collectParams} // 收藏功能: 配置之后显示 收藏、帮助、显示页面地址 这3个功能
>
<WeaTop
title="薪资档案" // 文字
icon={<i className="icon-coms-fa"/>} // 左侧图标
iconBgcolor="#F14A2D" // 左侧图标背景色
showDropIcon={true} // 是否显示下拉按钮
dropMenuDatas={rightMenu} // 下拉菜单(和页面的右键菜单相同)
dropMenuProps={{ collectParams }} // 收藏功能: 配置之后显示 收藏、帮助、显示页面地址 这3个功能
>
<WeaTab
searchType={["base", "advanced"]} // base基础搜索框 advanced显示高级搜索按钮
showSearchAd={showSearchAd} // 是否展开高级搜索面板
setShowSearchAd={(bool) => setShowSearchAd(bool)} //高级搜索面板受控
searchsAd={renderSearch()} // 高级搜索内部数据getSearchs(form, toJS(condition), 2)
buttonsAd={adBtn} // 高级搜索内部按钮
onSearch={() => doSearch(this.state.searchItemsValue)} // 点搜索按钮时的回调this.handleSearch()
searchsAdQuick={renderRightOperation()}
searchsBasePlaceHolder={"请输入姓名"}
onSearchChange={(v) =>
this.setState({
searchItemsValue: {
...this.state.searchItemsValue,
username: v
}
})} // 在搜索框中输入的文字改变时的回调: 这里需要同步高级搜索和外部搜索框的值form.updateFields({ username: v })
searchsBaseValue={this.state.searchItemsValue.username} // 外部input搜索值受控: 这里和高级搜索的requestname同步form.getFormParams().username
/>
<WeaTableComx
style={{ display: "none" }}
comsWeaTableStore={tableStore}
needScroll={true}
/>
<CustomPaginationTable
loading={loading}
className="wea-antd-wrapper"
rowSelection={rowSelection}
columns={this.getColumns()}
dataSource={dataSource}
total={pageInfo.total}
current={pageInfo.pageNum}
pageSize={this.pageInfo.pageSize}
rowClassName={(record) => record.archiveStatus === "ARCHIVE" ? "archiveRow" : ""}
scroll={{ x: this.getColumns().length ? this.getColumns().length * 150 : 1200 }}
onPageChange={(value) => {
this.handlePageChange(value);
}}
onShowSizeChange={(current, pageSize) => {
this.pageInfo = { current, pageSize };
this.handleShowSizeChange(this.pageInfo);
}}
/>
</WeaTop>
</WeaRightMenu>
{this.state.modalVisiable && (
<ImportModal
init={() => {
this.handleInitModal();
}}
isInit={this.state.isInit}
params={{}}
columns={previewColumns}
step={step}
setStep={this.setStep.bind(this)}
slideDataSource={previewDataSource}
importResult={this.state.importResult}
onFinish={() => {
this.handleImportFinish();
}}
previewImport={(params) => {
this.handlePreviewImport(params);
}}
importFile={(params) => {
this.handleImportFile(params);
}}
templateLink={
"/api/bs/hrmsalary/salaryArchive/downloadTemplate?importType=" +
this.state.importType
}
renderFormComponent={() => {
this.renderFormComponent();
}}
visiable={this.state.modalVisiable}
onCancel={() => {
this.setState({ modalVisiable: false });
}}
/>
)}
{this.state.changeSalaryVisible && (
<ChangeSalaryModal
currentId={currentId}
visible={this.state.changeSalaryVisible}
onCancel={() => {
this.setState({ changeSalaryVisible: false });
}}
/>
)}
{editAgentVisible && (
<EditAgentModal
currentId={currentId}
visible={editAgentVisible}
onCancel={() => {
setEditAgentVisible(false);
}}
/>
)}
{/* 操作记录 */}
{this.state.recordSlideVisible && (
<WeaSlideModal
visible={this.state.recordSlideVisible}
top={0}
width={40}
height={100}
direction={"right"}
measure={"%"}
title={
<SlideModalTitle
subtitle={"操作记录"}
tabs={[
{ title: "薪资项目", key: 0 }
// { title: "个税扣缴义务人", key: 1 },
]}
editable={false}
showOperateBtn={showOperateBtn}
selectedTab={selectedTab}
customOperate={() => {
renderCustomOperate();
}}
subItemChange={(item) => {
this.setState({ selectedTab: item.key });
}}
/>
}
content={
<div>
{selectedTab == 0 && <SlideSalaryItem/>}
{selectedTab == 1 && <SlideAgent/>}
</div>
}
onClose={() => this.setState({ recordSlideVisible: false })}
showMask={true}
closeMaskOnClick={() =>
this.setState({ recordSlideVisible: false })
}
/>
)}
{this.state.editSlideVisible && (
<WeaSlideModal
className="slideOuterWrapper"
visible={this.state.editSlideVisible}
top={0}
width={40}
height={100}
direction={"right"}
measure={"%"}
title={
<SlideModalTitle
subtitle={"员工薪资档案"}
editable={false}
customOperate={this.renderEditSlideOperate()}
/>
}
content={<SalaryFileViewSlide id={currentId}/>}
onClose={() => {
this.setState({ editSlideVisible: false });
setSalaryIncreaseUrl({});
}}
showMask={true}
closeMaskOnClick={() => {
setSalaryIncreaseUrl({});
this.setState({ editSlideVisible: false });
}}
/>
)}
</div>
);
}
}