薪资账套页面重构

This commit is contained in:
黎永顺 2022-12-14 15:37:55 +08:00
parent a193ed6690
commit bbb91b438a
14 changed files with 1190 additions and 29 deletions

View File

@ -0,0 +1,79 @@
/*
* Author: 黎永顺
* name: 复制账套
* Description:
* Date: 2022/12/8
*/
import React, { Component } from "react";
import { inject, observer } from "mobx-react";
import { categoryConditions } from "../config";
import { WeaDialog } from "ecCom";
import { Button } from "antd";
import { getSearchs } from "../../../util";
@inject("ledgerStore")
@observer
class CategoryAddModal extends Component {
constructor(props) {
super(props);
this.state = {
loading: false
};
}
componentDidMount() {
this.getFormFields();
}
componentWillReceiveProps(nextProps, nextContext) {
if (nextProps.visible !== this.props.visible && nextProps.visible) {
const { ledgerStore, name = "" } = nextProps;
const { categoryForm: form } = ledgerStore;
form.updateFields({
name: { value: name }
});
}
}
getFormFields = () => {
const { ledgerStore } = this.props;
const { categoryForm: form } = ledgerStore;
form.initFormFields(categoryConditions);
};
handleSubmit = () => {
const { ledgerStore, id, onSaveCategory, onCancel } = this.props;
const { categoryForm: form } = ledgerStore;
form.validateForm().then(f => {
if (f.isValid) {
const payload = form.getFormParams();
onSaveCategory({ ...payload, id });
onCancel();
} else {
f.showErrors();
}
});
};
render() {
const { onCancel, ledgerStore, ...extra } = this.props;
const { loading } = this.state;
const { categoryForm: form } = ledgerStore;
const buttons = [
<Button type="primary" onClick={this.handleSubmit} loading={loading}>保存</Button>,
<Button type="ghost" onClick={onCancel}> 取消 </Button>
];
return (
<WeaDialog
{...extra}
style={{ width: 600 }}
buttons={buttons}
onCancel={onCancel}
>
{getSearchs(form, categoryConditions, 1)}
</WeaDialog>
);
}
}
export default CategoryAddModal;

View File

@ -148,3 +148,63 @@
}
}
}
//薪资项目
.ledgerSalaryItemWrapper {
.userInfoWrapper {
margin-top: 10px;
margin-bottom: 10px;
padding: 10px;
border: 1px solid #ebedf0;
border-radius: 5px;
display: flex;
align-items: center;
.wea-sortable-grid-item {
display: inline-block;
border: none;
padding: 0;
}
}
.categroyListWrapper {
.titleNormalWrapper {
display: flex;
justify-content: space-between;
align-items: center;
.titleWrapper, .titleBtnWrapper{
display: flex;
align-items: center;
width: inherit;
}
.titleWrapper{
i{
font-size: 16px;
color: #333;
margin-left: 8px;
}
}
.titleBtnWrapper{
.wea-button-icon{
margin-left: 12px;
}
}
}
}
.titleWrapper {
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
.titleLeft {
display: flex;
align-items: center;
& > span {
margin-right: 8px;
}
}
}
}

View File

@ -29,8 +29,9 @@ class LedgerAdjustRuleAddModal extends Component {
}
listSalarySobItem = (salarySobId) => {
const { salaryRuleItemsList } = this.props;
const payload = {
excludeSalaryItemIds: [],
excludeSalaryItemIds: _.map(salaryRuleItemsList, item => item.salaryItemId),
salarySobId
};
listSalarySobItem(payload).then(({ status, data }) => {
@ -53,7 +54,7 @@ class LedgerAdjustRuleAddModal extends Component {
}
const items = {
...extraItems,
salaryItemName: this.state.salaryItemName,
salaryItemName: this.state.salaryItemName
};
this.handleReset();
onSave([...salaryRuleItemsList, items]);

View File

@ -85,7 +85,7 @@ class LedgerAssociatedPersonnel extends Component {
render() {
const { selectedKey, searchValue, rowKeys, personalAddModal } = this.state;
const { taxAgentStore: { showOperateBtn }, editId } = this.props;
const { taxAgentStore: { showOperateBtn }, editId, saveSalarySobId } = this.props;
const topTab = [
{
title: "关联人员范围",
@ -129,7 +129,7 @@ class LedgerAssociatedPersonnel extends Component {
/>
<PersonalScopeTable
ref={dom => this.personalScopeTableRef = dom}
searchKeyVal={{ key: "salarySobId", value: editId }}
searchKeyVal={{ key: "salarySobId", value: editId || saveSalarySobId }}
APIFox={APIFox}
tabActive={selectedKey}
searchValue={searchValue}

View File

@ -42,9 +42,9 @@ class LedgerBackCalculatedSalaryItem extends Component {
}
getAggregate = () => {
const { editId: salarySobId } = this.props;
const { editId: salarySobId, saveSalarySobId } = this.props;
const { backCalcItems } = this.state;
getAggregate({ salarySobId }).then(({ status, data }) => {
getAggregate({ salarySobId: salarySobId || saveSalarySobId }).then(({ status, data }) => {
if (status) {
this.setState({
backCalcItems: _.map(backCalcItems, item => {

View File

@ -31,8 +31,8 @@ class LedgerSalaryAdjustmentRules extends Component {
}
listAdjustmentRule = () => {
const { editId: salarySobId } = this.props;
listAdjustmentRule({ salarySobId }).then(({ status, data }) => {
const { editId: salarySobId, saveSalarySobId } = this.props;
listAdjustmentRule({ salarySobId: salarySobId || saveSalarySobId }).then(({ status, data }) => {
if (status) {
this.setState({
dataSource: data
@ -46,12 +46,12 @@ class LedgerSalaryAdjustmentRules extends Component {
};
handleAddAdjustRule = () => {
const { adjustRuleAddModal } = this.state;
const { editId } = this.props;
const { editId, saveSalarySobId } = this.props;
this.setState({
adjustRuleAddModal: {
...adjustRuleAddModal,
visible: true,
salarySobId: editId
salarySobId: editId || saveSalarySobId
}
});
};

View File

@ -0,0 +1,301 @@
/*
* Author: 黎永顺
* name: 薪资项目
* Description:
* Date: 2022/12/13
*/
import React, { Component } from "react";
import LedgerSalaryItemBaseInfo from "./ledgerSalaryItemBaseInfo";
import LedgerSalaryItemNormal from "./ledgerSalaryItemNormal";
import { getLedgerItemForm } from "../../../apis/ledger";
import "./index.less";
class LedgerSalaryItem extends Component {
constructor(props) {
super(props);
this.state = {
empFields: [], //员工基本信息
itemGroups: [] //正常工资薪金所得项
};
}
componentDidMount() {
this.getLedgerItemForm();
}
/*
* Author: 黎永顺
* Description: 薪资项目以及员工基本信息查询
* Params:
* Date: 2022/12/14
*/
getLedgerItemForm = () => {
const { editId: salarySobId, saveSalarySobId } = this.props;
getLedgerItemForm({ salarySobId: salarySobId || saveSalarySobId }).then(({ status, data }) => {
if (status) {
const { empFields, itemGroups, items } = data;
const obj = {
id: itemGroups.length,
itemHide: null,
items,
name: "未分类",
salarySobId,
sortedIndex: itemGroups.length
};
this.setState({ empFields, itemGroups: [...itemGroups, obj] }, () => {
const { empFields, itemGroups } = this.state;
const { onSaveSalaryItem } = this.props;
onSaveSalaryItem(empFields, itemGroups);
});
}
});
};
/*
* Author: 黎永顺
* Description: 员工基本信息排序
* Params:
* Date: 2022/12/14
*/
handleChangeSortableList = (empFields) => {
this.setState({ empFields }, () => {
const { empFields, itemGroups } = this.state;
const { onSaveSalaryItem } = this.props;
onSaveSalaryItem(empFields, itemGroups);
});
};
/*
* Author: 黎永顺
* Description:编辑保存性子项目分类
* Params:
* Date: 2022/12/13
*/
handleSaveCateGory = (payload) => {
const { itemGroups } = this.state;
if (payload.id) {
this.setState({
itemGroups: _.map(itemGroups, it => {
if (it.id === payload.id) {
return { ...it, name: payload.name };
}
return { ...it };
})
});
} else {
const obj = {
id: itemGroups.length,
itemHide: null,
items: [],
name: payload.name
};
this.setState({
itemGroups: _.map([obj, ...itemGroups], (it, idx) => ({ ...it, sortedIndex: idx }))
}, () => {
const { empFields, itemGroups } = this.state;
const { onSaveSalaryItem } = this.props;
onSaveSalaryItem(empFields, itemGroups);
});
}
};
/*
* Author: 黎永顺
* Description: 删除分类
* Params:
* Date: 2022/12/14
*/
handleDeleteCategroy = (id) => {
const { itemGroups } = this.state;
this.setState({
itemGroups: _.filter(itemGroups, it => it.id !== id)
}, () => {
const { empFields, itemGroups } = this.state;
const { onSaveSalaryItem } = this.props;
onSaveSalaryItem(empFields, itemGroups);
});
};
/*
* Author: 黎永顺
* Description: 删除分类项下的列表数据
* Params:
* Date: 2022/12/14
*/
handleDeleteCategroyItems = (id, selectedRowKeys) => {
const { itemGroups } = this.state;
this.setState({
itemGroups: _.map(itemGroups, item => {
if (item.id === id) {
return {
...item,
items: _.filter(item.items, it => !selectedRowKeys.includes(it.id))
};
}
return { ...item };
})
}, () => {
const { empFields, itemGroups } = this.state;
const { onSaveSalaryItem } = this.props;
onSaveSalaryItem(empFields, itemGroups);
});
};
/*
* Author: 黎永顺
* Description: 修改信息项目分类的顺序-向上移动
* Params:
* Date: 2022/12/14
*/
handleUpgo = (index) => {
const { itemGroups } = this.state;
let newItemGroups = [...itemGroups];
if (index !== 0) {
newItemGroups[index] = newItemGroups.splice(index - 1, 1, newItemGroups[index])[0];
} else {
newItemGroups.push(newItemGroups.shift());
}
this.setState({
itemGroups: _.map(newItemGroups, (it, idx) => ({
...it,
sortedIndex: idx
}))
}, () => {
const { empFields, itemGroups } = this.state;
const { onSaveSalaryItem } = this.props;
onSaveSalaryItem(empFields, itemGroups);
});
};
/*
* Author: 黎永顺
* Description: 修改信息项目分类的顺序-向下移动
* Params:
* Date: 2022/12/14
*/
handleDowngo = (index) => {
const { itemGroups } = this.state;
let newItemGroups = [...itemGroups];
if (index !== newItemGroups.length - 1) {
newItemGroups[index] = newItemGroups.splice(index + 1, 1, newItemGroups[index])[0];
} else {
newItemGroups.unshift(newItemGroups.splice(index, 1)[0]);
}
this.setState({
itemGroups: _.map(newItemGroups, (it, idx) => ({
...it,
sortedIndex: idx
}))
}, () => {
const { empFields, itemGroups } = this.state;
const { onSaveSalaryItem } = this.props;
onSaveSalaryItem(empFields, itemGroups);
});
};
/*
* Author: 黎永顺
* Description: 移動分类下的列表数据\切换薪资分类-隐藏复选框
* Params:
* Date: 2022/12/14
*/
handleDropCategroyItem = (filed, data) => {
const { itemGroups } = this.state;
this.setState({
itemGroups: _.map(itemGroups, it => {
if (filed.id === it.id) {
return { ...it, items: data };
}
return { ...it };
})
}, () => {
const { empFields, itemGroups } = this.state;
const { onSaveSalaryItem } = this.props;
onSaveSalaryItem(empFields, itemGroups);
});
};
/*
* Author: 黎永顺
* Description: 薪资分类选中复选框
* Params:
* Date: 2022/12/14
*/
handleChangeSelectedRowKeys = (filed, data) => {
const { itemGroups } = this.state;
this.setState({
itemGroups: _.map(itemGroups, it => {
if (filed.id === it.id) {
return { ...it, selectedRowKeys: data };
}
return { ...it };
})
}, () => {
const { empFields, itemGroups } = this.state;
const { onSaveSalaryItem } = this.props;
onSaveSalaryItem(empFields, itemGroups);
});
};
/*
* Author: 黎永顺
* Description: 薪资项目-新增项
* Params:
* Date: 2022/12/14
*/
handleAddSalaryItems = (id, items) => {
const { itemGroups } = this.state;
this.setState({
itemGroups: _.map(itemGroups, it => {
if (id === it.id) {
return { ...it, items: [...it.items, ...items] };
}
return { ...it };
})
}, () => {
const { empFields, itemGroups } = this.state;
const { onSaveSalaryItem } = this.props;
onSaveSalaryItem(empFields, itemGroups);
});
};
/*
* Author: 黎永顺
* Description: 保存薪资项目公式
* Params:
* Date: 2022/12/14
*/
handleSaveFormnul = (id, items) => {
const { itemGroups } = this.state;
this.setState({
itemGroups: _.map(itemGroups, it => {
if (id === it.id) {
return { ...it, items };
}
return { ...it };
})
}, () => {
const { empFields, itemGroups } = this.state;
const { onSaveSalaryItem } = this.props;
onSaveSalaryItem(empFields, itemGroups);
});
};
render() {
const { empFields, itemGroups } = this.state;
return (
<div className="ledgerSalaryItemWrapper">
<LedgerSalaryItemBaseInfo
{...this.props} dataSource={empFields}
onChangeSortableList={this.handleChangeSortableList}
/>
<LedgerSalaryItemNormal
ref={dom => this.ledgerSalaryItemNormalRef = dom}
{...this.props} dataSource={itemGroups}
onSaveCategory={this.handleSaveCateGory}
onDeleteCategroy={this.handleDeleteCategroy}
onDeleteCategroyItems={this.handleDeleteCategroyItems}
onUpgo={this.handleUpgo}
onDowngo={this.handleDowngo}
onDropCategoryItem={this.handleDropCategroyItem}
onHandleItemhide={this.handleDropCategroyItem}
onChangeSelectedRowKeys={this.handleChangeSelectedRowKeys}
onAddSalaryItems={this.handleAddSalaryItems}
onSaveFormnul={this.handleSaveFormnul}
/>
</div>
);
}
}
export default LedgerSalaryItem;

View File

@ -0,0 +1,150 @@
import React from "react";
import { Button, Switch } from "antd";
import { WeaDialog, WeaInputSearch, WeaTable } from "ecCom";
import { listSalaryItem } from "../../../apis/ledger";
export default class LedgerSalaryItemAddModal extends React.Component {
constructor(props) {
super(props);
this.state = {
loading: {
query: false
},
name: "",
selectedRowKeys: [],
dataSource: [],
columns: [],
pageInfo: {
current: 1,
pageSize: 10,
total: 0
}
};
}
componentWillReceiveProps(nextProps, nextContext) {
if (nextProps.visible !== this.props.visivle && nextProps.visible) {
this.setState({ selectedRowKeys: [] }, () => {
this.listSalaryItem();
});
}
}
listSalaryItem = () => {
const { itemGroups } = this.props;
const { name, pageInfo, loading } = this.state;
let excludeIds = [];
itemGroups.map(item => {
item.items && item.items.map(i => {
excludeIds.push(i.salaryItemId);
});
});
const payload = {
excludeIds,
name,
...pageInfo
};
this.setState({ loading: { ...loading, query: true } });
listSalaryItem(payload).then(({ status, data }) => {
this.setState({ loading: { ...loading, query: false } });
if (status) {
const { pageNum: current, pageSize, total, columns, list: dataSource } = data;
this.setState({
pageInfo: { ...pageInfo, current, pageSize, total },
dataSource,
columns
});
}
}).catch(() => {
this.setState({ loading: { ...loading, query: false } });
});
};
getSalaryItemAddColumns = () => {
const { columns } = this.state;
let newColumns = [];
newColumns = columns.map(column => {
let newColumn = column;
newColumn.render = (text, record, index) => { //前端元素转义
let valueSpan = record[newColumn.dataIndex + "span"] !== undefined ? record[newColumn.dataIndex + "span"] : record[newColumn.dataIndex];
switch (newColumn.dataIndex) {
case "useDefault":
case "useInEmployeeSalary":
return <Switch checked={text == 1}/>;
default:
return <div dangerouslySetInnerHTML={{ __html: valueSpan }}/>;
}
};
return newColumn;
});
return newColumns;
};
handleAdd = () => {
const { dataSource, selectedRowKeys } = this.state;
const { onAddSalaryItems, id, onCancel } = this.props;
let selectItems = [];
dataSource.map(item => {
item = { ...item };
selectedRowKeys.map(key => {
if (item.id === key) {
item.salaryItemId = item.id;
item.key = item.id;
selectItems.push(item);
}
});
});
onCancel();
onAddSalaryItems(id, selectItems);
};
render() {
const { onCancel, visible } = this.props;
const { name, selectedRowKeys, pageInfo, dataSource, loading } = this.state;
const pagination = {
...pageInfo,
showTotal: total => `${total}`,
showQuickJumper: true,
pageSizeOptions: ["10", "20", "50", "100"],
onChange: current => {
this.setState({
pageInfo: { ...pageInfo, current }
}, () => {
this.listSalaryItem();
});
}
};
const rowSelection = {
selectedRowKeys,
onChange: (selectedRowKeys) => {
this.setState({ selectedRowKeys }, () => {
});
}
};
return (
<WeaDialog
visible={visible}
onCancel={onCancel}
title="添加薪资项目"
style={{ width: "80vw", height: 600 }}
buttons={[<Button type="primary" onClick={this.handleAdd} disabled={_.isEmpty(selectedRowKeys)}>添加</Button>]}
>
<div style={{ display: "flex", justifyContent: "flex-end", alignItems: "center", padding: 20 }}>
<WeaInputSearch
placeholder="请输入薪资项目名称"
value={name}
onChange={(name) => this.setState({ name })}
onSearch={() => this.listSalaryItem()}
/>
</div>
<WeaTable
rowKey="id"
rowSelection={rowSelection}
dataSource={dataSource}
pagination={pagination}
loading={loading.query}
columns={this.getSalaryItemAddColumns()}
/>
</WeaDialog>
);
}
}

View File

@ -0,0 +1,103 @@
/*
* Author: 黎永顺
* name: 薪资项目-员工基本信息
* Description:
* Date: 2022/12/13
*/
import React, { Component } from "react";
import { WeaHelpfulTip, WeaSearchGroup, WeaSelect, WeaSortable } from "ecCom";
import { Button, Icon } from "antd";
import { empFieldList } from "../../../apis/ledger";
class LedgerSalaryItemBaseInfo extends Component {
constructor(props) {
super(props);
this.state = {
empFieldListOptions: []
};
}
componentDidMount() {
this.empFieldList();
}
empFieldList = () => {
empFieldList().then(({ status, data }) => {
if (status) {
const dataFilter = _.filter(data, it => !["taxAgentName", "username", "departmentName"].includes(it.id));
this.setState({
empFieldListOptions: _.map(dataFilter, it => ({ key: it.id, showname: it.name }))
});
}
});
};
handleAddEmpList = (key, showname) => {
const { dataSource, onChangeSortableList } = this.props;
const obj = {
canDelete: true,
fieldId: key,
fieldName: showname,
id: dataSource.length,
salarySobId: "",
sortedIndex: dataSource.length
};
onChangeSortableList([...dataSource, obj]);
};
handleDeleteEmplist = (item) => {
const { dataSource, onChangeSortableList } = this.props;
onChangeSortableList(_.xorWith(dataSource, [item], _.isEqual));
};
render() {
const { dataSource, onChangeSortableList } = this.props;
const { empFieldListOptions } = this.state;
return (
<WeaSearchGroup needTigger={false} showGroup title={<TitleComp/>}>
<div className="userInfoWrapper">
<WeaSortable
datas={dataSource}
draggableType="icon"
onChange={onChangeSortableList}
renderNodeItem={(item) => {
const { fieldName, canDelete } = item;
return <div style={{ display: "inline-block", paddingLeft: "10px", paddingRight: "10px" }}>
<span className="selectedItem" onBlur>{fieldName}</span>
{
canDelete &&
<Icon
style={{ cursor: "pointer", marginLeft: "5px", fontWeight: "600" }}
type="cross"
onClick={() => this.handleDeleteEmplist(item)}
/>
}
</div>;
}}
className="wea-sortable-grid-item"
/>
<WeaSelect
showSearch
options={empFieldListOptions}
style={{ width: 150 }}
onChange={this.handleAddEmpList}
/>
</div>
</WeaSearchGroup>
);
}
}
export default LedgerSalaryItemBaseInfo;
const TitleComp = () => {
return <div className="titleWrapper">
<div className="titleLeft">
<span>员工基本信息</span>
<WeaHelpfulTip
width={300}
title="姓名、部门、个税扣缴义务人为必须项,不可删除"
placement="topLeft"
/>
</div>
<Button type="ghost">预览</Button>
</div>;
};

View File

@ -0,0 +1,252 @@
/*
* Author: 黎永顺
* name: 薪资项目-正常薪资所得
* Description:
* Date: 2022/12/13
*/
import React, { Component } from "react";
import { inject, observer } from "mobx-react";
import { WeaButtonIcon, WeaSearchGroup } from "ecCom";
import { Button, Modal } from "antd";
import CategoryAddModal from "./categoryAddModal";
import LedgerSalaryItemAddModal from "./ledgerSalaryItemAddModal";
import LedgerSalaryItemTable from "./ledgerSalaryItemTable";
import "./index.less";
import FormalFormModal from "../../salaryItem/formalFormModal";
@inject("ledgerStore")
@observer
class LedgerSalaryItemNormal extends Component {
constructor(props) {
super(props);
this.state = {
addCategoryItemsVisible: false,
categoryModal: {
visible: false,
title: "新增分类",
name: "",
id: ""
},
editFormulModal: {
visible: false,
formulaId: "",
valueType: "",
dataType: ""
},
//公式保存数据
formnulField: {},
formnulId: ""
};
}
componentWillUnmount() {
this.handleResetFormnul();
}
handleEditFormnul = (field, record) => {
const { valueType, formulaId, dateType: dataType, id } = record;
const { editFormulModal } = this.state;
this.setState({
editFormulModal: {
...editFormulModal,
visible: true,
valueType, formulaId, dataType
},
formnulField: field,
formnulId: id
});
};
handleSaveFormnul = (data) => {
const { onSaveFormnul } = this.props;
const { formnulField, formnulId } = this.state;
const tmpV = _.cloneDeep(formnulField.items);
const formnulData = _.map(tmpV, it => {
if (it.id === formnulId) {
return { ...it, formulaId: data.id, formulaContent: data.formula };
}
return { ...it };
});
onSaveFormnul(formnulField.id, formnulData);
};
handleAddCategory = (name = "", id = "") => {
const { categoryModal } = this.state;
this.setState({
categoryModal: {
...categoryModal,
visible: true,
name,
title: name ? "编辑分类" : "新增分类",
id
}
});
};
handleDeleteCategory = (id) => {
const { onDeleteCategroy } = this.props;
Modal.confirm({
title: "信息确认",
content: "确认要删除吗?",
onOk: () => {
onDeleteCategroy(id);
}
});
};
handleDeleteCategoryItems = (id, selectedRowKeys) => {
const { onDeleteCategroyItems } = this.props;
Modal.confirm({
title: "信息确认",
content: "确认删除所选薪资项目吗?删除后此项目下的进位规则/保留小数位/公式内容会一起被清除!",
onOk: () => {
onDeleteCategroyItems(id, selectedRowKeys);
}
});
};
handleUpgo = (sortedIndex) => {
const { onUpgo } = this.props;
onUpgo(sortedIndex);
};
handleDowngo = (sortedIndex) => {
const { onDowngo } = this.props;
onDowngo(sortedIndex);
};
handleClose = () => {
const { ledgerStore } = this.props;
const { categoryForm: form } = ledgerStore;
const { categoryModal } = this.state;
this.setState({
categoryModal: {
...categoryModal,
visible: false,
title: "新增分类",
name: "",
id: ""
}
}, () => form.resetForm());
};
handleCloseFormnul = () => {
const { editFormulModal } = this.state;
this.setState({
editFormulModal: {
...editFormulModal,
visible: false,
formulaId: "",
valueType: "", dataType: ""
}
});
};
handleResetFormnul = () => {
this.setState({
formnulField: {},
formnulId: ""
});
};
render() {
const {
dataSource,
onSaveCategory,
onDropCategoryItem,
onHandleItemhide,
onChangeSelectedRowKeys,
onAddSalaryItems
} = this.props;
const { categoryModal, addCategoryItemsVisible, editFormulModal } = this.state;
return (
<WeaSearchGroup needTigger={false} showGroup title={<TitleComp onAddCategory={this.handleAddCategory}/>}>
<div className="categroyListWrapper">
{
_.map(dataSource, field => {
const { items } = field;
return <WeaSearchGroup
needTigger showGroup
title={
<TitleNormalComp
{...field}
dataSourceLen={dataSource.length}
onEditCategory={this.handleAddCategory}
onDeleteCategory={this.handleDeleteCategory}
onDeleteCategoryItems={this.handleDeleteCategoryItems}
onAddCategoryItems={(id) => this.setState({ addCategoryItemsVisible: { visible: true, id } })}
onUpgo={this.handleUpgo}
onDowngo={this.handleDowngo}
/>
}
>
<LedgerSalaryItemTable
dataSource={items}
onDropCategoryItem={(data) => onDropCategoryItem(field, data)}
onHandleItemhide={(data) => onHandleItemhide(field, data)}
onChangeSelectedRowKeys={(data) => onChangeSelectedRowKeys(field, data)}
onEditFormnul={(data) => this.handleEditFormnul(field, data)}
/>
</WeaSearchGroup>;
})
}
<LedgerSalaryItemAddModal
{...addCategoryItemsVisible}
itemGroups={dataSource}
onCancel={() => this.setState({ addCategoryItemsVisible: { visible: false, id: "" } })}
onAddSalaryItems={onAddSalaryItems}
/>
<CategoryAddModal
{...categoryModal}
onSaveCategory={onSaveCategory}
onCancel={this.handleClose}
/>
{/*公式编辑*/}
{
editFormulModal.visible &&
<FormalFormModal
{...editFormulModal}
onSaveFormal={this.handleSaveFormnul}
onCancel={this.handleCloseFormnul}
/>
}
</div>
</WeaSearchGroup>
);
}
}
export default LedgerSalaryItemNormal;
const TitleNormalComp = (props) => {
const {
name, onEditCategory, onDeleteCategory,
sortedIndex, dataSourceLen, id, onUpgo,
onDowngo, selectedRowKeys = [], onDeleteCategoryItems,
onAddCategoryItems
} = props;
return <div className="titleNormalWrapper">
<div className="titleWrapper">
<span>{name}</span>
{
name !== "未分类" &&
<i className="icon-coms-edit" title="编辑" onClick={() => onEditCategory(name, id)}/>
}
{
name !== "未分类" &&
<i className="icon-coms-Delete" title="删除" onClick={() => onDeleteCategory(id)}/>
}
{
sortedIndex !== 0 &&
<i className="icon-coms-Reverse" title="向上移动" onClick={() => onUpgo(sortedIndex)}/>
}
{
sortedIndex !== dataSourceLen - 1 &&
<i className="icon-coms-positive-sequence" title="向下移动" onClick={() => onDowngo(sortedIndex)}/>
}
</div>
<div className="titleBtnWrapper">
<WeaButtonIcon buttonType="del" type="primary" disabled={_.isEmpty(selectedRowKeys)}
onClick={() => onDeleteCategoryItems(id, selectedRowKeys)}/>
<WeaButtonIcon buttonType="add" type="primary" onClick={() => onAddCategoryItems(id)}/>
</div>
</div>;
};
const TitleComp = (props) => {
const { onAddCategory } = props;
return <div className="titleWrapper">
<span>正常工资薪金所得</span>
<Button type="ghost" onClick={() => onAddCategory()}>新增分类</Button>
</div>;
};

View File

@ -0,0 +1,135 @@
/*
* Author: 黎永顺
* name: 薪资项目-列表数据
* Description:
* Date: 2022/12/13
*/
import React, { Component } from "react";
import { WeaCheckbox, WeaHelpfulTip, WeaTable } from "ecCom";
class LedgerSalaryItemTable extends Component {
constructor(props) {
super(props);
this.state = {
selectedRowKeys: []
};
}
/*
* Author: 黎永顺
* Description: 列表操作隐藏复选框
* Params:
* Date: 2022/12/14
*/
handleChangeItem = (value, id) => {
const { dataSource, onHandleItemhide } = this.props;
onHandleItemhide(
_.map([...dataSource], item => {
if (id === item.id) {
return {
...item,
itemHide: String(value)
};
}
return { ...item };
})
);
};
handleChangeAllItem = (value) => {
const { dataSource, onHandleItemhide } = this.props;
onHandleItemhide(
_.map([...dataSource], item => {
return {
...item,
itemHide: String(value)
};
})
);
};
render() {
const { dataSource, onDropCategoryItem, onChangeSelectedRowKeys, onEditFormnul } = this.props;
const { selectedRowKeys } = this.state;
const rowSelection = {
selectedRowKeys,
onChange: (selectedRowKeys) => this.setState({ selectedRowKeys }, () => {
onChangeSelectedRowKeys(this.state.selectedRowKeys);
}),
getCheckboxProps: record => ({
disabled: !record.canDelete
})
};
const checkValue = _.every(dataSource, it => it.itemHide && it.itemHide === "1") ? "1" : "0";
const columns = [
{
title: "名称",
dataIndex: "name",
key: "name"
},
{
title: <span>
<span style={{ marginRight: 8 }}>核算公式</span>
<WeaHelpfulTip title={<HelpContent/>} placement="bottom" width={200}/>
</span>,
dataIndex: "formulaContent",
key: "formulaContent",
render: (text, record) => {
if (record.canEdit) {
return (
<span className="linkWapper">
<a href="javascript: void(0);" onClick={() => onEditFormnul(record)}> {text} </a>
</span>
);
} else {
return <span> {text} </span>;
}
}
},
{
title: "个税申请表对应字段",
dataIndex: "taxDeclarationColumn",
key: "taxDeclarationColumn"
},
{
title: <span>
<WeaCheckbox
value={checkValue}
onChange={value => this.handleChangeAllItem(value)}
/>
<span style={{ marginLeft: 8 }}>隐藏</span>
</span>,
dataIndex: "itemHide",
key: "itemHide",
render: (text, record) => <WeaCheckbox
value={text ? String(text) : !text ? "0" : "1"}
onChange={value => this.handleChangeItem(value, record.id)}
/>
}
];
return (
<WeaTable
rowKey="id"
rowSelection={rowSelection}
dataSource={dataSource}
columns={columns}
onRow={(record, index) => ({
index,
moveRow: record
})}
pagination={false}
onDrop={onDropCategoryItem}
draggable={true}
/>
);
}
}
export default LedgerSalaryItemTable;
const HelpContent = () => {
return <span>
<span>1新建薪资账套时核算公式与薪资项目管理菜单一致</span><br/>
<span>2取值方式为公式的薪资项目核算公式显示为具体公式点击公式可编辑公式核算时按照当前薪资项目的公式进行核算</span><br/>
<span>3薪资账套内的薪资项目的公式或SQL的修改或公式的修改都不影响薪资项目管理菜单的薪资项目取值方式或公式只对当前账套生效</span><br/>
</span>;
};

View File

@ -13,7 +13,8 @@ import LedgerBaseSetting from "./ledgerBaseSetting";
import LedgerAssociatedPersonnel from "./ledgerAssociatedPersonnel";
import LedgerSalaryAdjustmentRules from "./ledgerSalaryAdjustmentRules";
import LedgerBackCalculatedSalaryItem from "./ledgerBackCalculatedSalaryItem";
import { saveAdjustmentRule, saveLedgerBasic } from "../../../apis/ledger";
import LedgerSalaryItem from "./ledgerSalaryItem";
import { saveAdjustmentRule, saveLedgerBasic, saveLedgerItem } from "../../../apis/ledger";
import "./index.less";
const Step = WeaSteps.Step;
@ -34,10 +35,19 @@ class LedgerSlide extends Component {
current: 0,
loading: false,
baseSettingInfo: {},
adjustRules: []
adjustRules: [],
empFields: [], itemGroups: [],
saveSalarySobId: ""
};
}
componentWillUnmount() {
alert(1111);
this.setState({
saveSalarySobId: ""
});
}
/*
* Author: 黎永顺
* Description: 保存基本信息
@ -57,13 +67,13 @@ class LedgerSlide extends Component {
return false;
}
this.setState({ loading: true });
saveLedgerBasic({ ...extra, description, id: editId }).then(({ status, errormsg }) => {
saveLedgerBasic({ ...extra, description, id: editId }).then(({ status, data, errormsg }) => {
this.setState({ loading: false });
if (status) {
const { onRefreshList } = this.props;
message.success("保存成功");
onRefreshList();
!editId && this.setState({ current: current + 1 });
!editId && this.setState({ current: current + 1, saveSalarySobId: data });
} else {
message.error(errormsg || "保存失败");
}
@ -76,9 +86,9 @@ class LedgerSlide extends Component {
* Date: 2022/12/12
*/
saveLedgerAdjustRule = () => {
const { adjustRules } = this.state;
const { adjustRules, saveSalarySobId } = this.state;
const payload = {
salarySobId: this.props.editId,
salarySobId: this.props.editId || saveSalarySobId,
ruleParams: adjustRules
};
this.setState({ loading: true });
@ -86,12 +96,37 @@ class LedgerSlide extends Component {
this.setState({ loading: false });
if (status) {
message.success("保存成功");
this.handleClose();
} else {
message.success(errormsg || "保存失败");
}
}).catch(() => this.setState({ loading: false }));
}
;
};
/*
* Author: 黎永顺
* Description: 薪资项目保存
* Params:
* Date: 2022/12/14
*/
saveLedgerItem = () => {
const { empFields, itemGroups, saveSalarySobId } = this.state;
const { editId: salarySobId } = this.props;
const payload = {
empFields,
itemGroups: _.filter(itemGroups, it => it.name !== "未分类"),
items: _.find(itemGroups, it => it.name === "未分类").items || [],
salarySobId: salarySobId || saveSalarySobId
};
this.setState({ loading: true });
saveLedgerItem(payload).then(({ status, errormsg }) => {
this.setState({ loading: false });
if (status) {
message.success("保存成功");
} else {
message.error(errormsg || "保存失败");
}
}).catch(() => this.setState({ loading: false }));
};
handleChangeSlideTab = (current) => {
this.setState({ current: Number(current) });
};
@ -107,22 +142,36 @@ class LedgerSlide extends Component {
handleChangeSaveParams = (baseSettingInfo) => {
this.setState({ baseSettingInfo });
};
/*
* Author: 黎永顺
* Description: 薪资项目保存数据
* Params:
* Date: 2022/12/14
*/
handleSaveSalaryItemParams = (empFields, itemGroups) => {
this.setState({ empFields, itemGroups });
};
renderChildren = () => {
const { current } = this.state;
const { current, saveSalarySobId } = this.state;
let CurrentDom = null;
switch (current) {
case 0:
CurrentDom = <LedgerBaseSetting {...this.props} onSaveParams={this.handleChangeSaveParams}/>;
break;
case 1:
CurrentDom = <LedgerAssociatedPersonnel {...this.props}/>;
CurrentDom = <LedgerAssociatedPersonnel {...this.props} saveSalarySobId={saveSalarySobId}/>;
break;
case 2:
CurrentDom = <LedgerSalaryItem {...this.props} saveSalarySobId={saveSalarySobId}
onSaveSalaryItem={this.handleSaveSalaryItemParams}/>;
break;
case 3:
CurrentDom = <LedgerBackCalculatedSalaryItem {...this.props}/>;
CurrentDom = <LedgerBackCalculatedSalaryItem {...this.props} saveSalarySobId={saveSalarySobId}/>;
break;
case 4:
CurrentDom =
<LedgerSalaryAdjustmentRules {...this.props} onSaveParams={(adjustRules) => this.setState({ adjustRules })}/>;
<LedgerSalaryAdjustmentRules {...this.props} saveSalarySobId={saveSalarySobId}
onSaveParams={(adjustRules) => this.setState({ adjustRules })}/>;
break;
default:
CurrentDom = null;
@ -148,23 +197,34 @@ class LedgerSlide extends Component {
break;
case 1:
CurrentDom = !editId ? [
<Button type="ghost">完成跳过所有步骤</Button>,
<Button type="ghost" onClick={this.handleClose}>完成跳过所有步骤</Button>,
<Button type="primary" onClick={() => this.setState({ current: current + 1 })}>下一步</Button>
] : [];
break;
case 2:
CurrentDom = !editId ?
[
<Button type="ghost">完成跳过所有步骤</Button>,
<Button type="ghost" onClick={this.handleClose}>完成跳过所有步骤</Button>,
<Button type="ghost" onClick={() => this.setState({ current: current - 1 })}>上一步</Button>,
<Button type="primary">下一步</Button>
] : [];
<Button
type="primary"
loading={loading}
onClick={() => {
this.setState({ current: current + 1 }, () => {
this.saveLedgerItem();
});
}}
>保存并进入下一步</Button>
] : [
<Button type="primary" loading={loading} onClick={this.saveLedgerItem}>保存</Button>
];
break;
case 3:
CurrentDom = !editId ?
[
<Button type="ghost" onClick={this.handleClose}>完成跳过所有步骤</Button>,
<Button type="ghost" onClick={() => this.setState({ current: current - 1 })}>上一步</Button>,
<Button type="primary">下一步</Button>
<Button type="primary" onClick={() => this.setState({ current: current + 1 })}>下一步</Button>
] : [];
break;
case 4:

View File

@ -27,6 +27,24 @@ export const copyConditions = [
defaultshow: true
}
];
export const categoryConditions = [
{
items: [
{
colSpan: 1,
conditionType: "INPUT",
domkey: ["name"],
fieldcol: 14,
rules: "required|string",
label: "名称",
labelcol: 6,
value: "",
viewAttr: 3
}
],
defaultshow: true
}
];
export const baseSettingFormItem = [
{
key: "name",
@ -720,7 +738,7 @@ export const roundingRules = [
key: "UP_EVEN",
selected: false,
showname: "向上求偶"
},
}
];
export const keepDecimalPlaces = [
{

View File

@ -4,12 +4,14 @@ import { WeaForm, WeaTableNew } from "comsMobx";
import * as API from "../apis/ledger"; // 引入API接口文件
import { notNull } from "../util/validate";
import { categoryConditions } from "../pages/ledgerPage/config";
const { TableStore } = WeaTableNew;
export class LedgerStore {
//重构薪资账套
@observable copyForm = new WeaForm(); // nrew 一个form
@observable copyForm = new WeaForm(); // 复制form
@observable categoryForm = new WeaForm(); // 新增分类form
/*******************************************************/