532 lines
19 KiB
JavaScript
532 lines
19 KiB
JavaScript
import React from "react";
|
||
import { inject, observer } from "mobx-react";
|
||
import { toJS } from "mobx";
|
||
import { Button, DatePicker, message, Modal } from "antd";
|
||
import moment from "moment";
|
||
import { WeaHelpfulTip, WeaInputSearch, WeaSelect, WeaSlideModal, WeaTop } from "ecCom";
|
||
import { renderLoading } from "../../util"; // 渲染form数据的方法:因为多个页面都会使用,所以抽的公共方法在util中
|
||
import CustomTab from "../../components/customTab";
|
||
import StepSlide from "../../components/stepSlide";
|
||
import BaseInformForm from "./stepForm/baseInformForm";
|
||
import ShowSettingForm from "./stepForm/showSettingForm";
|
||
import SlideModalTitle from "../../components/slideModalTitle";
|
||
import TemplateSettingList from "./templateSettingList";
|
||
import TemplateSettingForm from "./stepForm/tmplateSettingForm";
|
||
import CopyModal from "./copyModal";
|
||
import SalarySendList from "./SalarySendList";
|
||
import { getReplenishForm } from "../../apis/payroll";
|
||
import "../dataAcquisition/cumDeduct/index.less";
|
||
|
||
const { MonthPicker } = DatePicker;
|
||
|
||
@inject("payrollStore", "taxAgentStore")
|
||
@observer
|
||
export default class Payroll extends React.Component {
|
||
constructor(props) {
|
||
super(props);
|
||
this.state = {
|
||
value: "",
|
||
selectedKey: "0",
|
||
currentStep: 0,
|
||
stepSlideVisible: false,
|
||
selectedTab: 0,
|
||
editSlideVisible: false,
|
||
initSelected: false,
|
||
ledgerOptions: [],
|
||
templateSearchValue: "", // 工资单模板列表-搜索条件-名称
|
||
templateSelect: "", // 工资单模板列表-搜索条件-账套下拉选中值
|
||
templateCurrentId: "",
|
||
copyModalVisible: false,
|
||
startDate: moment(new Date()).startOf("year").format("YYYY-MM"),
|
||
endDate: moment(new Date()).startOf("month").format("YYYY-MM")
|
||
};
|
||
this.recordId = "";
|
||
this.salaryYearMonth = [moment(new Date()).startOf("year").format("YYYY-MM"), moment(new Date()).startOf("month").format("YYYY-MM")];
|
||
this.listPageInfo = { current: 1, pageSize: 10 };
|
||
}
|
||
|
||
// 工资单模板-新建表单变化监听
|
||
handleBaseInfoChange = (request) => {
|
||
const { payrollStore: { setTemplateBaseData } } = this.props;
|
||
setTemplateBaseData(request);
|
||
};
|
||
|
||
getReplenishForm = (isEdit = false, params = {}) => {
|
||
const { payrollStore } = this.props;
|
||
const { templateBaseData, salaryTemplateShowSet, setReplenishSalaryTemplateSalaryItemSet } = payrollStore;
|
||
if (!salaryTemplateShowSet.theme && !isEdit) {
|
||
Modal.warning({
|
||
title: "信息确认",
|
||
content: "必要信息不完整,红色*为必填项!"
|
||
});
|
||
return;
|
||
}
|
||
getReplenishForm({ salarySobId: templateBaseData.salarySob, ...params }).then(({ status, data }) => {
|
||
if (status) {
|
||
if (!isEdit) {
|
||
this.setState({ currentStep: this.state.currentStep + 1 }, () => {
|
||
setReplenishSalaryTemplateSalaryItemSet(data.replenishSalaryTemplateSalaryItemSet);
|
||
window.localStorage.setItem("salary-showset", JSON.stringify(salaryTemplateShowSet));
|
||
});
|
||
} else {
|
||
setReplenishSalaryTemplateSalaryItemSet(data.replenishSalaryTemplateSalaryItemSet);
|
||
window.localStorage.setItem("salary-showset", JSON.stringify(salaryTemplateShowSet));
|
||
}
|
||
}
|
||
});
|
||
};
|
||
// 新建保存
|
||
handleSave = () => {
|
||
const { payrollStore } = this.props;
|
||
const { fetchSavePayroll } = payrollStore;
|
||
fetchSavePayroll().then(() => {
|
||
window.localStorage.removeItem("template-basedata");
|
||
window.localStorage.removeItem("salary-showset");
|
||
this.setState({ currentStep: 0, stepSlideVisible: false });
|
||
});
|
||
};
|
||
|
||
componentWillMount() {
|
||
const { payrollStore } = this.props;
|
||
const { getPayrollTemplateLedgerList } = payrollStore;
|
||
// 获取薪资账套下拉列表
|
||
getPayrollTemplateLedgerList().then((options) => {
|
||
this.setState({
|
||
initSelected: true,
|
||
ledgerOptions: [{ key: "", showname: "" }, ...options]
|
||
});
|
||
});
|
||
}
|
||
|
||
// 模板搜索
|
||
handleTemplateSearch() {
|
||
const { templateSearchValue, templateSelect } = this.state;
|
||
let params = { name: templateSearchValue, salarySobId: templateSelect,current: 1 };
|
||
const { payrollStore: { getPayrollTemplateList } } = this.props;
|
||
getPayrollTemplateList(params);
|
||
}
|
||
|
||
// 模板选择框下拉改变事件
|
||
handleTemplateSelectChange(value) {
|
||
this.setState({ templateSelect: value }, () => {
|
||
this.handleTemplateSearch();
|
||
});
|
||
}
|
||
|
||
// 模板列表编辑
|
||
handleTemplateListEdit(record) {
|
||
const { payrollStore } = this.props;
|
||
const { getPayrollShowForm } = payrollStore;
|
||
this.recordId = record.id;
|
||
getPayrollShowForm(record.id);
|
||
this.setState({ templateCurrentId: record.id, selectedTab: 0 }, () => {
|
||
this.setState({ editSlideVisible: true });
|
||
});
|
||
}
|
||
|
||
// 模板列表复制
|
||
handleTemplateListCopy(record) {
|
||
this.setState({
|
||
templateCurrentId: record.id
|
||
}, () => {
|
||
this.setState({
|
||
copyModalVisible: true
|
||
});
|
||
});
|
||
}
|
||
|
||
// 复制模板保存事件监听
|
||
handleCopyModalSave(value) {
|
||
const { payrollStore } = this.props;
|
||
const { duplicatePayroll } = payrollStore;
|
||
duplicatePayroll(this.state.templateCurrentId, value).then(() => {
|
||
this.setState({
|
||
copyModalVisible: false
|
||
});
|
||
});
|
||
}
|
||
|
||
// 模板列表删除
|
||
handleTemplateListDelete(record) {
|
||
const { payrollStore: { deletePayroll } } = this.props;
|
||
Modal.confirm({
|
||
title: "信息确认",
|
||
content: "确认删除",
|
||
onOk: () => {
|
||
deletePayroll([record.id]);
|
||
}
|
||
});
|
||
}
|
||
|
||
|
||
handleRangePickerChange(type, value) {
|
||
const { payrollStore: { getPayrollList } } = this.props;
|
||
this.setState({
|
||
[type]: value ? moment(value).format("YYYY-MM") : moment().format("YYYY-MM")
|
||
}, () => {
|
||
const { startDate, endDate } = this.state;
|
||
this.salaryYearMonth = [startDate, endDate];
|
||
getPayrollList({ salaryYearMonth: [startDate, endDate], ...this.listPageInfo });
|
||
});
|
||
}
|
||
|
||
// 预览
|
||
handlePreview = () => {
|
||
const { payrollStore: { templateBaseData, salaryTemplateShowSet, salaryItemSet } } = this.props;
|
||
window.localStorage.setItem("template-basedata", JSON.stringify(templateBaseData));
|
||
window.localStorage.setItem("salary-showset", JSON.stringify(salaryTemplateShowSet));
|
||
window.localStorage.setItem("salaryItemSet", JSON.stringify(salaryItemSet));
|
||
window.open("/spa/hrmSalary/static/index.html#/main/hrmSalary/templatePreview");
|
||
};
|
||
|
||
// 更新保存
|
||
handleUpdateSave = () => {
|
||
const { selectedTab } = this.state;
|
||
const { payrollStore } = this.props;
|
||
const { fetchUpdatePayroll } = payrollStore;
|
||
if (selectedTab === 0) {
|
||
if (!this.validateStep1()) {
|
||
Modal.warning({
|
||
title: "信息确认",
|
||
content: "必要信息不完整,红色*为必填项!"
|
||
});
|
||
return;
|
||
}
|
||
} else if (selectedTab === 1) {
|
||
const { salaryTemplateShowSet } = payrollStore;
|
||
if (!salaryTemplateShowSet.theme) {
|
||
Modal.warning({
|
||
title: "信息确认",
|
||
content: "必要信息不完整,红色*为必填项!"
|
||
});
|
||
return;
|
||
}
|
||
}
|
||
|
||
|
||
fetchUpdatePayroll(this.recordId).then(() => {
|
||
this.setState({
|
||
editSlideVisible: false,
|
||
selectedTab: 0
|
||
}, () => {
|
||
window.localStorage.removeItem("template-basedata");
|
||
window.localStorage.removeItem("salary-showset");
|
||
});
|
||
});
|
||
};
|
||
|
||
// 发放页面页码跳转
|
||
handleListDataPageChange(value, pageInfo) {
|
||
const { payrollStore: { getPayrollList } } = this.props;
|
||
this.listPageInfo = pageInfo;
|
||
getPayrollList({ salaryYearMonth: this.salaryYearMonth, ...pageInfo });
|
||
}
|
||
|
||
// 发放页面每页条数
|
||
handleListShowSizeChange(pageInfo) {
|
||
const { payrollStore: { getPayrollList } } = this.props;
|
||
this.listPageInfo = pageInfo;
|
||
getPayrollList({ salaryYearMonth: this.salaryYearMonth, ...pageInfo });
|
||
}
|
||
|
||
validateStep1 = () => {
|
||
const { payrollStore: { templateBaseData } } = this.props;
|
||
const { reissueRule = "0" } = templateBaseData;
|
||
const validList = reissueRule === "0" ? ["name", "replenishName", "salarySob"] : ["name", "replenishName", "salarySob", "replenishRule"];
|
||
if (_.every(validList, it => !!templateBaseData[it])) {
|
||
window.localStorage.setItem("template-basedata", JSON.stringify(templateBaseData));
|
||
} else {
|
||
window.localStorage.removeItem("template-basedata");
|
||
}
|
||
return _.every(validList, it => !!templateBaseData[it]);
|
||
};
|
||
|
||
render() {
|
||
const { payrollStore, taxAgentStore: { showOperateBtn } } = this.props;
|
||
const { loading, hasRight, templateStore, deletePayroll, templateBaseData } = payrollStore;
|
||
const { currentStep, selectedTab, templateSearchValue, templateSelect, startDate, endDate } = this.state;
|
||
if (!hasRight && !loading) { // 无权限处理
|
||
return renderLoading();
|
||
}
|
||
const topTab = [
|
||
{
|
||
title: "工资单发放",
|
||
viewcondition: "0"
|
||
},
|
||
{
|
||
title: "工资单模板设置",
|
||
viewcondition: "1"
|
||
}
|
||
];
|
||
const renderRightOperation = () => {
|
||
if (this.state.selectedKey === "0") {
|
||
return <div style={{ display: "inline-block" }}>
|
||
<WeaHelpfulTip
|
||
width={200}
|
||
title="提示:无工资单模板无法发放工资单,请先设置一个默认使用的工资单模板"
|
||
placement="topLeft"
|
||
/>
|
||
<div style={{ display: "inline-block", marginLeft: "10px" }}>
|
||
<MonthPicker
|
||
value={startDate}
|
||
disabledDate={(current) => {
|
||
return current && endDate && current.getTime() > new Date(endDate).getTime();
|
||
}}
|
||
format="YYYY-MM"
|
||
onChange={(val) => this.handleRangePickerChange("startDate", val)}
|
||
/>
|
||
<span className="to" style={{ margin: "0 10px" }}>至</span>
|
||
<MonthPicker
|
||
value={endDate}
|
||
disabledDate={(current) => {
|
||
return current && startDate && current.getTime() < new Date(startDate).getTime();
|
||
}}
|
||
getCalendarContainer={trigger => trigger.parentNode}
|
||
format="YYYY-MM"
|
||
onChange={(val) => this.handleRangePickerChange("endDate", val)}
|
||
/>
|
||
</div>
|
||
</div>;
|
||
} else if (this.state.selectedKey === "1") {
|
||
return (
|
||
<div style={{ display: "inline-block" }}>
|
||
{
|
||
showOperateBtn &&
|
||
<Button type="primary" onClick={() => {
|
||
this.setState({ stepSlideVisible: true });
|
||
}}>新建</Button>
|
||
}
|
||
{
|
||
showOperateBtn &&
|
||
<Button
|
||
style={{ marginLeft: 10 }}
|
||
type="ghost"
|
||
onClick={() => {
|
||
const selectedRowKeys = toJS(templateStore.selectedRowKeys);
|
||
if (!selectedRowKeys.length) {
|
||
message.info("未选中任何数据!");
|
||
return;
|
||
}
|
||
Modal.confirm({
|
||
title: "信息确认",
|
||
content: `确定要将所选的工资单模板(共${selectedRowKeys.length}条数据)删除吗?`,
|
||
onOk: () => {
|
||
deletePayroll(selectedRowKeys);
|
||
}
|
||
});
|
||
}}
|
||
>批量删除工资单模板</Button>
|
||
}
|
||
{
|
||
this.state.initSelected && <WeaSelect options={this.state.ledgerOptions}
|
||
placeholder="请选择账套"
|
||
style={{ width: "200px", marginLeft: "10px", marginRight: "10px" }}
|
||
value={templateSelect} onChange={(value) => {
|
||
this.handleTemplateSelectChange(value);
|
||
}}/>
|
||
}
|
||
<WeaInputSearch style={{ marginleft: "10px" }} placeholder="请输入工资单名称" value={templateSearchValue}
|
||
onChange={(value) => {
|
||
this.setState({ templateSearchValue: value });
|
||
}} onSearch={(value) => {
|
||
this.handleTemplateSearch(value);
|
||
}}/>
|
||
</div>
|
||
);
|
||
}
|
||
};
|
||
const steps = ["基础设置", "正常核算工资单模板", "补发工资单模版"];
|
||
const nextStep = () => {
|
||
if (!this.validateStep1()) {
|
||
Modal.warning({
|
||
title: "信息确认",
|
||
content: "必要信息不完整,红色*为必填项!"
|
||
});
|
||
return;
|
||
}
|
||
if(templateBaseData.replenishName === templateBaseData.name){
|
||
message.error("工资单模板名称和补发工资单模板名称不可相同")
|
||
return;
|
||
}
|
||
this.setState({
|
||
currentStep: this.state.currentStep + 1
|
||
});
|
||
};
|
||
// 上一步
|
||
const prevStep = () => {
|
||
this.setState({
|
||
currentStep: this.state.currentStep - 1
|
||
});
|
||
};
|
||
|
||
return (
|
||
<div>
|
||
<WeaTop
|
||
title="工资单发放" // 文字
|
||
icon={<i className="icon-coms-fa"/>} // 左侧图标
|
||
iconBgcolor="#F14A2D" // 左侧图标背景色
|
||
showDropIcon={false} // 是否显示下拉按钮
|
||
>
|
||
<CustomTab
|
||
topTab={topTab}
|
||
searchOperationItem={renderRightOperation()}
|
||
onChange={(v) => {
|
||
this.setState({ selectedKey: v, stepSlideVisible: false, editSlideVisible: false });
|
||
}}
|
||
/>
|
||
{
|
||
this.state.selectedKey === "0" &&
|
||
<SalarySendList
|
||
onEditTemplate={(record) => {
|
||
this.handleTemplateListEdit(record);
|
||
}}
|
||
salaryYearMonth={this.salaryYearMonth}
|
||
handleListDataPageChange={(value, pageInfo) => {
|
||
this.handleListDataPageChange(value, pageInfo);
|
||
}}
|
||
handleListShowSizeChange={(pageInfo) => {
|
||
this.handleListShowSizeChange(pageInfo);
|
||
}}
|
||
/>
|
||
}
|
||
|
||
{
|
||
this.state.selectedKey === "1" &&
|
||
<TemplateSettingList
|
||
onEdit={(record) => {
|
||
this.handleTemplateListEdit(record);
|
||
}}
|
||
onCopy={(record) => {
|
||
this.handleTemplateListCopy(record);
|
||
}}
|
||
showOperateBtn={showOperateBtn}
|
||
onDelete={(record) => this.handleTemplateListDelete(record)}
|
||
/>
|
||
}
|
||
</WeaTop>
|
||
{
|
||
this.state.stepSlideVisible && <StepSlide
|
||
visible={this.state.stepSlideVisible}
|
||
currentStep={currentStep}
|
||
steps={steps}
|
||
onCancel={() => {
|
||
window.localStorage.removeItem("template-basedata");
|
||
window.localStorage.removeItem("salary-showset");
|
||
this.setState({ stepSlideVisible: false });
|
||
}}
|
||
customOperate={
|
||
currentStep === 0 ? [
|
||
<Button type="primary" onClick={() => {
|
||
nextStep();
|
||
}}>下一步</Button>
|
||
] : currentStep === 1 ? [
|
||
<Button type="default" onClick={() => {
|
||
prevStep();
|
||
}}>上一步</Button>,
|
||
<Button type="primary" onClick={() => this.getReplenishForm()}>下一步</Button>,
|
||
<Button type="default" onClick={() => {
|
||
this.handlePreview();
|
||
}}>预览</Button>
|
||
] : currentStep === 2 ? [
|
||
<Button type="default" onClick={() => {
|
||
prevStep();
|
||
}}>上一步</Button>,
|
||
<Button type="primary" onClick={this.handleSave}>保存</Button>
|
||
] :
|
||
[]
|
||
}
|
||
title="新建工资单模板"
|
||
content={
|
||
<div>
|
||
{
|
||
currentStep === 0 && <BaseInformForm onChange={(request) => this.handleBaseInfoChange(request)}/>
|
||
}
|
||
{
|
||
currentStep === 1 && <ShowSettingForm/>
|
||
}
|
||
{
|
||
currentStep === 2 && <TemplateSettingForm/>
|
||
}
|
||
</div>
|
||
}
|
||
/>
|
||
}
|
||
|
||
{
|
||
this.state.editSlideVisible &&
|
||
<WeaSlideModal
|
||
className="slideOuterWrapper"
|
||
visible={this.state.editSlideVisible}
|
||
top={0}
|
||
width={50}
|
||
height={100}
|
||
direction="right"
|
||
measure="%"
|
||
title={
|
||
<SlideModalTitle
|
||
subtitle="编辑工资单模板"
|
||
tabs={[
|
||
{ title: "基础设置", key: 0 },
|
||
{ title: "正常核算工资单模板", key: 1 },
|
||
{ title: "补发工资单模版", key: 2 }
|
||
]}
|
||
editable={false}
|
||
selectedTab={selectedTab}
|
||
showOperateBtn={showOperateBtn}
|
||
customOperate={
|
||
selectedTab === 0 ? [
|
||
<Button type="primary" onClick={() => {
|
||
this.handleUpdateSave();
|
||
}}>保存</Button>
|
||
] : selectedTab === 1 ? [
|
||
<Button type="primary" onClick={() => {
|
||
this.handleUpdateSave();
|
||
}}>保存</Button>,
|
||
<Button type="default" onClick={this.handlePreview}>预览</Button>
|
||
] : [
|
||
<Button type="primary" onClick={() => {
|
||
this.handleUpdateSave();
|
||
}}>保存</Button>
|
||
]
|
||
}
|
||
subItemChange={(selectedTab) => {
|
||
this.setState({ selectedTab: Number(selectedTab) }, () => {
|
||
if (this.state.selectedTab === 2) this.getReplenishForm(true, { id: this.state.templateCurrentId });
|
||
});
|
||
}}
|
||
/>
|
||
}
|
||
content={<div>
|
||
{
|
||
selectedTab === 0 &&
|
||
<BaseInformForm id={this.state.templateCurrentId}
|
||
onChange={(request) => this.handleBaseInfoChange(request)}/>
|
||
}
|
||
{
|
||
selectedTab === 1 && <ShowSettingForm id={this.state.templateCurrentId}/>
|
||
}
|
||
{
|
||
selectedTab === 2 && <TemplateSettingForm id={this.state.templateCurrentId}/>
|
||
}
|
||
</div>}
|
||
onClose={() => this.setState({ editSlideVisible: false }, () => {
|
||
window.localStorage.removeItem("template-basedata");
|
||
window.localStorage.removeItem("salary-showset");
|
||
this.setState({ selectedTab: 0 });
|
||
})}
|
||
/>
|
||
}
|
||
{
|
||
this.state.copyModalVisible &&
|
||
<CopyModal
|
||
onSave={(value) => this.handleCopyModalSave(value)}
|
||
visible={this.state.copyModalVisible}
|
||
onCancel={() => {
|
||
this.setState({ copyModalVisible: false });
|
||
}}/>
|
||
}
|
||
</div>
|
||
);
|
||
}
|
||
}
|