工资单模板添加新增薪资项目大类的功能

This commit is contained in:
黎永顺 2023-02-02 18:59:55 +08:00
parent 7ea4a6f6a8
commit a1f7537337
7 changed files with 248 additions and 187 deletions

View File

@ -350,3 +350,11 @@ export const sendRangeSave = (params) => {
export const sendRangeDelete = (params) => {
return postFetch('/api/bs/hrmsalary/salaryBill/send/range/delete', params);
}
//工资单模板-获取模板可用的分组
export const getAvailableSalaryGroupSet = (params) => {
return postFetch('/api/bs/hrmsalary/salaryBill/template/getAvailableSalaryGroupSet', params);
}
//工资单模板-获取模板分组下可用的薪资项目
export const getAvailableSalaryItemSet = (params) => {
return postFetch('/api/bs/hrmsalary/salaryBill/template/getAvailableSalaryItemSet', params);
}

View File

@ -101,7 +101,7 @@ export default class Payroll extends React.Component {
// 模板搜索
handleTemplateSearch() {
const { templateSearchValue, templateSelect } = this.state;
let params = { name: templateSearchValue, salarySobId: templateSelect,current: 1 };
let params = { name: templateSearchValue, salarySobId: templateSelect, current: 1 };
const { payrollStore: { getPayrollTemplateList } } = this.props;
getPayrollTemplateList(params);
}
@ -344,8 +344,8 @@ export default class Payroll extends React.Component {
});
return;
}
if(templateBaseData.replenishName === templateBaseData.name){
message.error("工资单模板名称和补发工资单模板名称不可相同")
if (templateBaseData.replenishName === templateBaseData.name) {
message.error("工资单模板名称和补发工资单模板名称不可相同");
return;
}
this.setState({

View File

@ -197,3 +197,8 @@
}
}
}
.salaryItemModalWrapper{
.modalContent{
padding: 16px;
}
}

View File

@ -0,0 +1,35 @@
/*
* Author: 黎永顺
* name: 工资单模板-新增编辑薪资项目项
* Description:
* Date: 2023/2/2
*/
import React, { Component } from "react";
import { WeaDialog } from "ecCom";
import { Button } from "antd";
class SalaryItemModal extends Component {
render() {
const { visible, title, onCancel, onConfirm } = this.props;
const buttons = [
<Button type="primary" onClick={onConfirm}>确定</Button>,
<Button type="ghost" onClick={onCancel}>取消</Button>
];
return (
<WeaDialog
onCancel={onCancel}
title={title}
visible={visible}
style={{ width: 500 }}
hasScroll
buttons={buttons}
initLoadCss
className="salaryItemModalWrapper"
>
{this.props.children}
</WeaDialog>
);
}
}
export default SalaryItemModal;

View File

@ -6,26 +6,38 @@
*/
import React, { Component } from "react";
import { toJS } from "mobx";
import { WeaSortable } from "ecCom";
import { WeaFormItem, WeaInput, WeaSelect, WeaSortable } from "ecCom";
import { Icon, Modal } from "antd";
import SalaryItemModal from "./salaryItemModal";
import { getAvailableSalaryGroupSet, getAvailableSalaryItemSet } from "../../../apis/payroll";
class SalaryItemSettings extends Component {
constructor(props) {
super(props);
this.state = {
dataList: []
dataList: [],
checkedValue: "",
modalPayload: {
visible: false,
title: "",
groupId: "",
groupName: "",
options: []
}
};
}
componentDidMount() {
this.setState({
dataList: _.map(toJS(this.props.dataSource), item => {
return {
...item,
id: item.groupId
};
})
});
componentWillReceiveProps(nextProps, nextContext) {
if (nextProps.dataSource !== this.props.dataSource) {
this.setState({
dataList: _.map(toJS(nextProps.dataSource), item => {
return {
...item,
id: item.groupId
};
})
});
}
}
/*
@ -39,7 +51,7 @@ class SalaryItemSettings extends Component {
title: "信息确认",
content: "确认删除",
onOk: () => {
let resultSalaryItemSet = [...toJS(this.props.dataSource)];
let resultSalaryItemSet = [...this.state.dataList];
resultSalaryItemSet.map((sourceGroup, index) => {
if (sourceGroup.groupId === group.groupId) {
resultSalaryItemSet.splice(index, 1);
@ -60,7 +72,7 @@ class SalaryItemSettings extends Component {
* Date: 2023/2/2
*/
handleDeleteSalaryItem = (group, item) => {
let resultSalaryItemSet = [...toJS(this.props.dataSource)];
let resultSalaryItemSet = [...this.state.dataList];
resultSalaryItemSet.map(sourceGroup => {
if (sourceGroup.groupId === group.groupId) {
sourceGroup.items.map((sourceItem, index) => {
@ -76,10 +88,133 @@ class SalaryItemSettings extends Component {
this.props.onChangeSalaryItem(resultSalaryItemSet);
});
};
handleCloseModal = () => {
const { modalPayload } = this.state;
this.setState({
checkedValue: "",
modalPayload: {
...modalPayload,
visible: false,
title: "",
groupId: "",
groupName: "",
options: []
}
});
};
handleOpenModal = (record, title, isItem) => {
if (title === "分类名称编辑") {
const { modalPayload } = this.state;
this.setState({
modalPayload: {
...modalPayload,
visible: true,
title,
groupId: record.groupId,
groupName: record.groupName
}
});
} else {
isItem ? this.getAvailableSalaryItemSet(record, title) : this.getAvailableSalaryGroupSet(record, title);
}
};
getAvailableSalaryItemSet = (record, title) => {
const payload = {
salarySobId: this.props.salarySobId,
existSalaryItemIds: _.map(record.items, it => it.id),
groupId: record.groupId,
isReplenish: this.props.isReplenish
};
getAvailableSalaryItemSet(payload).then(({ status, data }) => {
if (status) {
const { modalPayload } = this.state;
this.setState({
modalPayload: {
...modalPayload,
visible: true,
title,
groupId: record.groupId,
options: _.map(data, it => ({ ...it, showname: it.name, key: it.salaryItemId }))
}
});
}
});
};
getAvailableSalaryGroupSet = (salarySobId, title) => {
const { dataList } = this.state;
const payload = {
salarySobId,
existSalaryGroupIds: _.map(dataList, it => it.groupId),
isReplenish: this.props.isReplenish
};
getAvailableSalaryGroupSet(payload).then(({ status, data }) => {
if (status) {
const { modalPayload } = this.state;
this.setState({
modalPayload: {
...modalPayload,
visible: true,
title,
options: _.map(data, it => ({ ...it, showname: it.groupName, key: it.groupId }))
}
});
}
});
};
handleChangeClassName = (groupName) => {
const { modalPayload } = this.state;
this.setState({
modalPayload: {
...modalPayload,
groupName
}
});
};
/*
* Author: 黎永顺
* Description:添加薪资项目项
* Params:
* Date: 2023/2/2
*/
handleConfirm = () => {
const { modalPayload, checkedValue, dataList } = this.state;
const { options = [], groupId, groupName } = modalPayload;
if (groupName) {
this.setState({
dataList: _.map(dataList, it => {
if (it.groupId === groupId) {
return {
...it,
groupName
};
}
return { ...it };
})
}, () => {
this.props.onChangeSalaryItem(this.state.dataList);
this.handleCloseModal();
});
} else {
this.setState({
dataList: groupId ? _.map(dataList, it => {
if (it.groupId === groupId) {
return {
...it,
items: [...it.items, ..._.filter(options, child => checkedValue.split(",").includes(child.salaryItemId))]
};
}
return { ...it };
}) : [...dataList, ..._.filter(options, child => checkedValue.split(",").includes(child.groupId))]
}, () => {
this.props.onChangeSalaryItem(this.state.dataList);
this.handleCloseModal();
});
}
};
render() {
const { onChangeSalaryItem } = this.props;
const { dataList } = this.state;
const { dataList, modalPayload, checkedValue } = this.state;
return (
<div className="salaryItemSettingWrapper">
<WeaSortable
@ -91,11 +226,11 @@ class SalaryItemSettings extends Component {
<span className="titleWrapper">
<span className="salaryClassTitle">{item.groupName}</span>
<span className="iconWrapper">
<i className="icon-coms-edit" onClick={() => alert(1)}/>
<i className="icon-coms-edit" onClick={() => this.handleOpenModal(item, "分类名称编辑")}/>
<i className="icon-coms-Delete" onClick={() => this.handleDeleteClick(item)}/>
</span>
</span>
<i className="icon-coms-Add-to" onClick={() => alert(2)}/>
<i className="icon-coms-Add-to" onClick={() => this.handleOpenModal(item, "请选择薪资项目", true)}/>
</div>
<div className="salaryItemContent">
{
@ -127,6 +262,23 @@ class SalaryItemSettings extends Component {
}}
className="wea-sortable-salary-item"
/>
<SalaryItemModal {...modalPayload} onCancel={this.handleCloseModal} onConfirm={this.handleConfirm}>
<div className="modalContent">
{
modalPayload.title === "分类名称编辑" ?
<WeaFormItem label="分类名称" labelCol={{ span: 6 }} wrapperCol={{ span: 18 }}>
<WeaInput value={modalPayload.groupName} onChange={this.handleChangeClassName}/>
</WeaFormItem>
: <WeaSelect
multiple
style={{ width: "100%" }}
value={checkedValue}
options={modalPayload.options}
onChange={v => this.setState({ checkedValue: v })}
/>
}
</div>
</SalaryItemModal>
</div>
);
}

View File

@ -1,7 +1,8 @@
import React from "react";
import { Modal, Radio, Switch } from "antd";
import { Radio, Switch } from "antd";
import { WeaButtonIcon, WeaFormItem, WeaInput, WeaSearchGroup } from "ecCom";
import { inject, observer } from "mobx-react";
import { toJS } from "mobx";
import BackgroundUpload from "../components/backgroundUpload";
import SalaryItemSettings from "./salaryItemSettings";
import "./index.less";
@ -38,27 +39,11 @@ export default class ShowSettingForm extends React.Component {
setSalaryItemSet(resultSet);
};
handleDeleteItem = (group, item) => {
const { payrollStore: { salaryItemSet, setSalaryItemSet } } = this.props;
let resultSalaryItemSet = [...salaryItemSet];
resultSalaryItemSet.map(sourceGroup => {
if (sourceGroup.groupId === group.groupId) {
sourceGroup.items.map((sourceItem, index) => {
if (sourceItem.id === item.id) {
sourceGroup.items.splice(index, 1);
}
});
}
});
setSalaryItemSet(resultSalaryItemSet);
};
render() {
const { payrollStore, id } = this.props;
const salaryTemplateShowSetStorage = id ? "{}" : window.localStorage.getItem("salary-showset") || "{}";
const { salaryTemplateShowSet } = payrollStore;
const { salaryItemSet } = payrollStore;
const { salaryItemSet, templateBaseData } = payrollStore;
const {
theme,
background,
@ -142,64 +127,19 @@ export default class ShowSettingForm extends React.Component {
title={
<div className="salarySetTitle">
<span>薪资项目设置</span>
<WeaButtonIcon buttonType="add" type="primary"/>
<WeaButtonIcon buttonType="add" type="primary"
onClick={() => this.salaryItemSettingsRef.handleOpenModal(toJS(templateBaseData).salarySob, "添加分类")}/>
</div>
}
items={[]}
needTigger
showGroup
items={[]} needTigger showGroup
>
<SalaryItemSettings
ref={dom => this.salaryItemSettingsRef = dom}
dataSource={salaryItemSet}
onChangeSalaryItem={this.handleChangeSalaryItem}
salarySobId={toJS(templateBaseData).salarySob}
isReplenish={true}
/>
{/*{*/}
{/* salaryItemSet.map((group, index) => (*/}
{/* <div className="configItemWrapper">*/}
{/* <div className="configTitle">{group.groupName}*/}
{/* {*/}
{/* index < salaryItemSet.length - 1 &&*/}
{/* <Icon*/}
{/* type="caret-down"*/}
{/* style={{ marginLeft: "10px", cursor: "pointer", color: "#666" }}*/}
{/* onClick={() => {*/}
{/* this.handleDownClick(index);*/}
{/* }}*/}
{/* />*/}
{/* }*/}
{/* {*/}
{/* index > 0 &&*/}
{/* <Icon*/}
{/* type="caret-up"*/}
{/* style={{ marginLeft: "10px", cursor: "pointer", color: "#666" }}*/}
{/* onClick={() => {*/}
{/* this.handleUpClick(index);*/}
{/* }}*/}
{/* />*/}
{/* }*/}
{/* <i*/}
{/* className="icon-coms-Delete"*/}
{/* style={{ cursor: "pointer", color: "#666", marginLeft: "10px" }}*/}
{/* onClick={() => {*/}
{/* this.handleDeleteClick(index);*/}
{/* }}*/}
{/* />*/}
{/* </div>*/}
{/* <div className="configContent">*/}
{/* {group.items.map(item => (*/}
{/* <span className="editItem">{item.name}*/}
{/* <Icon*/}
{/* type="cross" style={{ cursor: "pointer" }}*/}
{/* onClick={() => {*/}
{/* this.handleDeleteItem(group, item);*/}
{/* }}*/}
{/* />*/}
{/* </span>*/}
{/* ))}*/}
{/* </div>*/}
{/* </div>*/}
{/* ))*/}
{/*}*/}
</WeaSearchGroup>
</div>
);

View File

@ -1,119 +1,40 @@
import React from "react";
import { Icon, Modal } from "antd";
import { WeaSearchGroup } from "ecCom";
import { WeaButtonIcon, WeaSearchGroup } from "ecCom";
import { inject, observer } from "mobx-react";
import { toJS } from "mobx";
import "./index.less";
import SalaryItemSettings from "./salaryItemSettings";
@inject("payrollStore")
@observer
export default class TemplateSettingForm extends React.Component {
handleDownClick = (index) => {
const { payrollStore: { replenishSalaryTemplateSalaryItemSet, setReplenishSalaryTemplateSalaryItemSet } } = this.props;
let downItem = replenishSalaryTemplateSalaryItemSet[index + 1];
let thisItem = replenishSalaryTemplateSalaryItemSet[index];
let resultSet = [...replenishSalaryTemplateSalaryItemSet];
resultSet[index] = downItem;
resultSet[index + 1] = thisItem;
handleChangeSalaryItem = (resultSet) => {
const { payrollStore: { setReplenishSalaryTemplateSalaryItemSet } } = this.props;
setReplenishSalaryTemplateSalaryItemSet(resultSet);
};
handleUpClick = (index) => {
const { payrollStore: { replenishSalaryTemplateSalaryItemSet, setReplenishSalaryTemplateSalaryItemSet } } = this.props;
let upItem = replenishSalaryTemplateSalaryItemSet[index - 1];
let thisItem = replenishSalaryTemplateSalaryItemSet[index];
let resultSet = [...replenishSalaryTemplateSalaryItemSet];
resultSet[index] = upItem;
resultSet[index - 1] = thisItem;
setReplenishSalaryTemplateSalaryItemSet(resultSet);
};
handleDeleteItem = (group, item) => {
const { payrollStore: { replenishSalaryTemplateSalaryItemSet, setReplenishSalaryTemplateSalaryItemSet } } = this.props;
let resultSalaryItemSet = [...replenishSalaryTemplateSalaryItemSet];
resultSalaryItemSet.map(sourceGroup => {
if (sourceGroup.id === group.id) {
sourceGroup.items.map((sourceItem, index) => {
if (sourceItem.id === item.id) {
sourceGroup.items.splice(index, 1);
}
});
}
});
setReplenishSalaryTemplateSalaryItemSet(resultSalaryItemSet);
};
handleDeleteClick = (index) => {
Modal.confirm({
title: "信息确认",
content: "确认删除",
onOk: () => {
const { payrollStore: { replenishSalaryTemplateSalaryItemSet, setReplenishSalaryTemplateSalaryItemSet } } = this.props;
let resultSalaryItemSet = [...replenishSalaryTemplateSalaryItemSet];
resultSalaryItemSet.splice(index, 1);
setReplenishSalaryTemplateSalaryItemSet(resultSalaryItemSet);
},
onCancel: () => {
}
});
};
render() {
const { payrollStore } = this.props;
const { replenishSalaryTemplateSalaryItemSet } = payrollStore;
const { replenishSalaryTemplateSalaryItemSet, templateBaseData } = payrollStore;
return (
<div className="showSettingForm">
<WeaSearchGroup title="薪资项目设置" items={[]} needTigger showGroup>
{
!_.isEmpty(toJS(replenishSalaryTemplateSalaryItemSet)) &&
replenishSalaryTemplateSalaryItemSet.map((group, index) => (
<div className="configItemWrapper">
<div className="configTitle">{group.groupName}
{
index < replenishSalaryTemplateSalaryItemSet.length - 1 &&
<Icon
type="caret-down"
style={{ marginLeft: "10px", cursor: "pointer", color: "#666" }}
onClick={() => {
this.handleDownClick(index);
}}
/>
}
{
index > 0 &&
<Icon
type="caret-up"
style={{ marginLeft: "10px", cursor: "pointer", color: "#666" }}
onClick={() => {
this.handleUpClick(index);
}}
/>
}
<i
className="icon-coms-Delete"
style={{ cursor: "pointer", color: "#666", marginLeft: "10px" }}
onClick={() => {
this.handleDeleteClick(index);
}}
/>
</div>
<div className="configContent">
{group.items.map(item => (
<span className="editItem">{item.name}
<Icon
type="cross" style={{ cursor: "pointer" }}
onClick={() => {
this.handleDeleteItem(group, item);
}}
/>
</span>
))}
</div>
</div>
))
<WeaSearchGroup
title={
<div className="salarySetTitle">
<span>薪资项目设置</span>
<WeaButtonIcon buttonType="add" type="primary"
onClick={() => this.salaryItemSettingsRef.handleOpenModal(toJS(templateBaseData).salarySob, "添加分类")}/>
</div>
}
items={[]} needTigger showGroup>
<SalaryItemSettings
ref={dom => this.salaryItemSettingsRef = dom}
dataSource={replenishSalaryTemplateSalaryItemSet}
onChangeSalaryItem={this.handleChangeSalaryItem}
salarySobId={toJS(templateBaseData).salarySob}
isReplenish={true}
/>
</WeaSearchGroup>
</div>
);