Merge branch 'feature/V2-薪资账套页面重构-1208' into develop

# Conflicts:
#	pc4mobx/hrmSalary/pages/salaryItem/formalFormModal.js
This commit is contained in:
黎永顺 2022-12-14 19:41:43 +08:00
commit 0cdca9c448
15 changed files with 309 additions and 80 deletions

View File

@ -333,6 +333,17 @@ export const fileSalaryAcct = (params) => {
}
}).then(res => res.json());
};
// 薪资记录-回算
export const backCalculate = (params) => {
return fetch("/api/bs/hrmsalary/salaryacct/backCalculate", {
method: "POST",
mode: "cors",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(params)
}).then(res => res.json());
};
// 薪资记录-重新核算
export const reAccounting = (params) => {

View File

@ -152,6 +152,14 @@ export default class Calculate extends React.Component {
});
}
// 回算
handleBackCalculate = (record) => {
const { calculateStore: { backCalculate } } = this.props;
backCalculate(record.id).then(() => {
this.handleSearch(this.state.searchValue);
});
};
// 查看详情回调
handleDetail(record) {
window.open(
@ -222,6 +230,8 @@ export default class Calculate extends React.Component {
this.handleReaccount(record);
} else if (cz.text == "查看") {
this.handleDetail(record);
} else if (cz.text == "回算") {
this.handleBackCalculate(record);
}
}}>
{cz.text}

View File

@ -1,13 +1,22 @@
import React from "react";
import { WeaHelpfulTip, WeaInput } from "ecCom";
import { WeaHelpfulTip, WeaInput, WeaTab } from "ecCom";
import IssuedAndReissueTable from "./issuedAndReissueTable";
import { Col, Row } from "antd";
import { inject, observer } from "mobx-react";
import { toJS } from "mobx";
import cs from "classnames";
import "./index.less";
@inject("calculateStore")
@observer
export default class EditSalaryDetail extends React.Component {
constructor(props) {
super(props);
this.state = {
selectedKey: "0"
};
}
componentWillMount() {
const { calculateStore: { acctresultDetail } } = this.props;
acctresultDetail(this.props.id);
@ -62,6 +71,17 @@ export default class EditSalaryDetail extends React.Component {
render() {
const { calculateStore: { acctresultDetailForm } } = this.props;
const { selectedKey } = this.state;
const topTab = [
{
title: "正常工资薪金所得",
viewcondition: "0"
},
{
title: "已发补发",
viewcondition: "1"
}
];
return (
<div className="editSalaryDetail">
<div className="detailItemWrapper">
@ -84,39 +104,45 @@ export default class EditSalaryDetail extends React.Component {
}
</div>
</div>
<div>
<div className="detailItemWrapper">
<span className="itemTitle">输入项</span>
<div className="itemContent">
<Row>
{
acctresultDetailForm.inputItems && acctresultDetailForm.inputItems.map((item, index) => {
const len = acctresultDetailForm.inputItems.length;
return (
<Col span={8}>
<Row>
<Col span={12}
className={cs("itemLabel", { "borderB-none": Math.ceil((index + 1) / 3) === len / 3 })}>{item.salaryItemName}</Col>
<Col span={12} className={cs("itemValue", {
"borderB-none": Math.ceil((index + 1) / 3) === len / 3,
"borderR-none": (index + 1) % 3 === 0
})}><WeaInput value={item.resultValue} disabled={!item.canEdit} onChange={(value) => {
this.handleItemValueChange(item.salaryItemName, value, true);
}}/></Col>
</Row>
</Col>
);
})
}
</Row>
{
!_.isEmpty(toJS(acctresultDetailForm.issuedAndReissueItems)) &&
<WeaTab
datas={topTab}
keyParam="viewcondition"
selectedKey={selectedKey}
onChange={v => this.setState({ selectedKey: v })}
/>
}
{
selectedKey === "0" &&
<div>
<div className="detailItemWrapper">
<span className="itemTitle">输入项</span>
<div className="itemContent">
<Row>
{
acctresultDetailForm.inputItems && acctresultDetailForm.inputItems.map((item, index) => {
const len = acctresultDetailForm.inputItems.length;
return (
<Col span={8}>
<Row>
<Col span={12}
className={cs("itemLabel", { "borderB-none": Math.ceil((index + 1) / 3) === len / 3 })}>{item.salaryItemName}</Col>
<Col span={12} className={cs("itemValue", {
"borderB-none": Math.ceil((index + 1) / 3) === len / 3,
"borderR-none": (index + 1) % 3 === 0
})}><WeaInput value={item.resultValue} disabled={!item.canEdit} onChange={(value) => {
this.handleItemValueChange(item.salaryItemName, value, true);
}}/></Col>
</Row>
</Col>
);
})
}
</Row>
</div>
</div>
</div>
</div>
<div>
<div className="detailItemWrapper">
<div className="detailItemWrapper">
<span className="itemTitle">
<span>公式项</span>
<WeaHelpfulTip
@ -126,31 +152,36 @@ export default class EditSalaryDetail extends React.Component {
placement="topLeft"
/>
</span>
<div className="itemContent">
<Row>
{
acctresultDetailForm.formulaItems && acctresultDetailForm.formulaItems.map((item, index) => {
const len = acctresultDetailForm.formulaItems.length;
return (
<Col span={8}>
<Row>
<Col span={12}
className={cs("itemLabel", { "borderB-none": Math.ceil((index + 1) / 3) === len / 3 })}>{item.salaryItemName}</Col>
<Col span={12} className={cs("itemValue", {
"borderB-none": Math.ceil((index + 1) / 3) === len / 3,
"borderR-none": (index + 1) % 3 === 0
})}><WeaInput value={item.resultValue} disabled={!item.canEdit} onChange={(value) => {
this.handleItemValueChange(item.salaryItemName, value, false);
}}/></Col>
</Row>
</Col>
);
})
}
</Row>
<div className="itemContent">
<Row>
{
acctresultDetailForm.formulaItems && acctresultDetailForm.formulaItems.map((item, index) => {
const len = acctresultDetailForm.formulaItems.length;
return (
<Col span={8}>
<Row>
<Col span={12}
className={cs("itemLabel", { "borderB-none": Math.ceil((index + 1) / 3) === len / 3 })}>{item.salaryItemName}</Col>
<Col span={12} className={cs("itemValue", {
"borderB-none": Math.ceil((index + 1) / 3) === len / 3,
"borderR-none": (index + 1) % 3 === 0
})}><WeaInput value={item.resultValue} disabled={!item.canEdit} onChange={(value) => {
this.handleItemValueChange(item.salaryItemName, value, false);
}}/></Col>
</Row>
</Col>
);
})
}
</Row>
</div>
</div>
</div>
</div>
}
{
selectedKey === "1" &&
<IssuedAndReissueTable dataSource={toJS(acctresultDetailForm.issuedAndReissueItems)}/>
}
</div>
);
}

View File

@ -0,0 +1,70 @@
/*
* Author: 黎永顺
* name: 已发补发列表
* Description:
* Date: 2022/12/14
*/
import React, { Component } from "react";
import { WeaHelpfulTip, WeaInputNumber, WeaTable } from "ecCom";
class IssuedAndReissueTable extends Component {
render() {
const { dataSource } = this.props;
const columns = [
{
dataIndex: "salaryItemName",
title: "薪资项目",
render: (text) => {
return <span className="tdEllipsis" title={text}>{text}</span>;
}
},
{
dataIndex: "resultValue",
title: <span>
<span style={{ marginRight: 8 }}>项目值</span>
<WeaHelpfulTip
title="若薪资项目有公式,手动编辑项目值后,则默认将手动编辑的项目值锁定;点击锁定图标,解锁手动编辑的项目值,公式生效,点击保存按照公式重新核算;重新核算后,不显示解锁图标。"
placement="bottom"
width={200}
/>
</span>,
render: (text, record) => {
const { canEdit } = record;
return <WeaInputNumber
disabled={!canEdit}
min={0}
precision={2}
value={text || 0}
onChange={(value) => {
console.log(value);
}}
/>;
}
},
{
dataIndex: "salaryBackItemFormula",
title: <span>
<span style={{ marginRight: 8 }}>核算公式</span>
<WeaHelpfulTip
title="若薪资项目有公式,且项目值手动编辑修改过,则公式失效;若解除锁定,则项目公式重新生效;"
placement="bottom"
width={200}
/>
</span>,
render: (text, record) => {
return <span className="tdEllipsis" title={text}>{_.isNil(text) ? "输入" : text}</span>;
}
}
];
return (
<WeaTable
rowKey="id"
dataSource={dataSource}
columns={columns}
pagination={false}
/>
);
}
}
export default IssuedAndReissueTable;

View File

@ -19,20 +19,22 @@ class LedgerBackCalculatedSalaryItemTable extends Component {
visible: false,
title: "编辑薪资项目",
id: "",
salaryItemId: ""
salaryItemId: "",
backCalcType: ""
}
};
}
handleEditBackCalc = (record) => {
const { id, salaryItemId } = record;
const { id, salaryItemId, backCalcType } = record;
const { backCalcEditSlide } = this.state;
this.setState({
backCalcEditSlide: {
...backCalcEditSlide,
visible: true,
id,
salaryItemId
salaryItemId,
backCalcType
}
});
};
@ -44,7 +46,8 @@ class LedgerBackCalculatedSalaryItemTable extends Component {
...backCalcEditSlide,
visible: false,
id: "",
salaryItemId: ""
salaryItemId: "",
backCalcType: ""
}
}, () => {
isRefresh && onRefresh();
@ -53,7 +56,7 @@ class LedgerBackCalculatedSalaryItemTable extends Component {
render() {
const { backCalcEditSlide } = this.state;
const { taxAgentStore: { showOperateBtn }, dataSource, editId } = this.props;
const { taxAgentStore: { showOperateBtn }, dataSource, editId, saveSalarySobId, key } = this.props;
const columns = [
{
dataIndex: "name",
@ -76,7 +79,8 @@ class LedgerBackCalculatedSalaryItemTable extends Component {
render: (text, record, index) => {
const { canEdit } = record;
return (showOperateBtn && canEdit) ?
<a href="javascript: void(0);" onClick={() => this.handleEditBackCalc(record)}>编辑</a> : <span></span>;
<a href="javascript: void(0);" onClick={() => this.handleEditBackCalc(record)}>编辑</a> :
<span></span>;
}
}
];
@ -90,7 +94,7 @@ class LedgerBackCalculatedSalaryItemTable extends Component {
/>
<LedgerBackCalcEditSlide
{...backCalcEditSlide}
editId={editId}
editId={editId || saveSalarySobId}
showOperateBtn={showOperateBtn}
onCancle={this.handleClose}
/>

View File

@ -27,7 +27,8 @@ class LedgerBackCalcEditSlide extends Component {
backCalcEditFormulModal: {
visible: false,
valueType: "",
dataType: ""
dataType: "",
backCalcType: ""
}
};
}
@ -72,13 +73,15 @@ class LedgerBackCalcEditSlide extends Component {
}).catch(() => this.setState({ loading: false }));
};
handleEditFormnul = () => {
const { backCalcType } = this.props;
const { backCalcEditFormulModal, valueType, dataType } = this.state;
this.setState({
backCalcEditFormulModal: {
...backCalcEditFormulModal,
visible: true,
valueType,
dataType: _.lowerCase(dataType)
dataType: _.lowerCase(dataType),
backCalcType
}
});
};
@ -89,7 +92,8 @@ class LedgerBackCalcEditSlide extends Component {
...backCalcEditFormulModal,
visible: false,
valueType: "",
dataType: ""
dataType: "",
backCalcType: ""
}
});
};

View File

@ -77,7 +77,7 @@ class LedgerBackCalculatedSalaryItem extends Component {
>
<LedgerBackCalculatedSalaryItemTable
{...this.props} dataSource={dataSource}
onRefresh={this.getAggregate}
key={key} onRefresh={this.getAggregate}
/>
</WeaSearchGroup>);
})

View File

@ -11,6 +11,7 @@ import { inject, observer } from "mobx-react";
import { baseSettingFormItem } from "../config";
import { getLedgerBasicForm } from "../../../apis/ledger";
import { getAddMonthYearMonth, getCurrentYearMonth, getSubtractMonthYearMonth } from "../../../util/date";
import moment from "moment";
import "./index.less";
@inject("taxAgentStore")

View File

@ -7,6 +7,7 @@
import React, { Component } from "react";
import LedgerSalaryItemBaseInfo from "./ledgerSalaryItemBaseInfo";
import LedgerSalaryItemNormal from "./ledgerSalaryItemNormal";
import LedgerSalaryItemPreviewModal from "./ledgerSalaryItemPreviewModal";
import { getLedgerItemForm } from "../../../apis/ledger";
import "./index.less";
@ -14,6 +15,7 @@ class LedgerSalaryItem extends Component {
constructor(props) {
super(props);
this.state = {
previewVisible: false, //预览标识
empFields: [], //员工基本信息
itemGroups: [] //正常工资薪金所得项
};
@ -125,7 +127,8 @@ class LedgerSalaryItem extends Component {
if (item.id === id) {
return {
...item,
items: _.filter(item.items, it => !selectedRowKeys.includes(it.id))
items: _.filter(item.items, it => !selectedRowKeys.includes(it.id)),
selectedRowKeys: []
};
}
return { ...item };
@ -271,13 +274,29 @@ class LedgerSalaryItem extends Component {
});
};
/*
* Author: 黎永顺
* Description: 员工基本信息-预览
* Params:
* Date: 2022/12/14
*/
handlePreview = () => {
this.setState({ previewVisible: true });
};
render() {
const { empFields, itemGroups } = this.state;
const { empFields, itemGroups, previewVisible } = this.state;
return (
<div className="ledgerSalaryItemWrapper">
<LedgerSalaryItemBaseInfo
{...this.props} dataSource={empFields}
onChangeSortableList={this.handleChangeSortableList}
onPreview={this.handlePreview}
/>
<LedgerSalaryItemPreviewModal
visible={previewVisible}
empFields={empFields} itemGroups={itemGroups}
onCancel={() => this.setState({ previewVisible: false })}
/>
<LedgerSalaryItemNormal
ref={dom => this.ledgerSalaryItemNormalRef = dom}

View File

@ -83,12 +83,13 @@ export default class LedgerSalaryItemAddModal extends React.Component {
const { dataSource, selectedRowKeys } = this.state;
const { onAddSalaryItems, id, onCancel } = this.props;
let selectItems = [];
dataSource.map(item => {
dataSource.map((item, index) => {
item = { ...item };
selectedRowKeys.map(key => {
if (item.id === key) {
item.salaryItemId = item.id;
item.key = item.id;
item.sortedIndex = index;
selectItems.push(item);
}
});

View File

@ -50,10 +50,10 @@ class LedgerSalaryItemBaseInfo extends Component {
};
render() {
const { dataSource, onChangeSortableList } = this.props;
const { dataSource, onChangeSortableList, onPreview } = this.props;
const { empFieldListOptions } = this.state;
return (
<WeaSearchGroup needTigger={false} showGroup title={<TitleComp/>}>
<WeaSearchGroup needTigger={false} showGroup title={<TitleComp onPreview={onPreview}/>}>
<div className="userInfoWrapper">
<WeaSortable
datas={dataSource}
@ -88,7 +88,8 @@ class LedgerSalaryItemBaseInfo extends Component {
}
export default LedgerSalaryItemBaseInfo;
const TitleComp = () => {
const TitleComp = (props) => {
const { onPreview } = props;
return <div className="titleWrapper">
<div className="titleLeft">
<span>员工基本信息</span>
@ -98,6 +99,6 @@ const TitleComp = () => {
placement="topLeft"
/>
</div>
<Button type="ghost">预览</Button>
<Button type="ghost" onClick={onPreview}>预览</Button>
</div>;
};

View File

@ -0,0 +1,63 @@
import React from "react";
import { WeaDialog, WeaTable } from "ecCom";
export default class LedgerSalaryItemPreviewModal extends React.Component {
getColumns = () => {
const { empFields, itemGroups } = this.props;
let columns = [];
let length = 0;
empFields.map(item => {
columns.push({
title: item.fieldName,
key: item.fieldId,
width: 150
});
length++;
});
itemGroups.map(item => {
if (item.id !== "default") {
let columnItem = {
title: item.name,
children: item.items.map(i => {
return {
title: i.name,
key: i.id,
width: 150
};
length++;
})
};
columns.push(columnItem);
}
});
itemGroups.map(item => {
if (item.id === "default") {
item.items.map(i => {
columns.push({
title: i.name,
key: i.id,
width: 150
});
length++;
});
}
});
return { columns, length };
};
render() {
const { onCancel, visible } = this.props;
return (
<WeaDialog
visible={visible}
title="预览"
style={{ width: "80vw", height: 200 }}
onCancel={onCancel}
>
<WeaTable columns={this.getColumns().columns} dataSource={[]} scroll={{ x: this.getColumns().length * 150 }}/>
</WeaDialog>
);
}
}

View File

@ -42,7 +42,6 @@ class LedgerSlide extends Component {
}
componentWillUnmount() {
alert(1111);
this.setState({
saveSalarySobId: ""
});

View File

@ -38,8 +38,8 @@ export default class FormalFormModal extends React.Component {
detailFormual(this.props.formulaId).then(data => {
this.setState({
value: data.formula,
validateType: data.validateType,
returnType: data.returnType,
validateType: data.validateType
});
this.parameters = data.parameters;
this.referenceType = data.referenceType;
@ -72,8 +72,8 @@ export default class FormalFormModal extends React.Component {
if (this.props.valueType == "3") {
groupParams = { "referenceType": "sql" };
} else if (this.props.valueType === "FORMULA") {
groupParams = { "referenceType": "backCalc" };
this.referenceType = "backCalc";
groupParams = this.props.backCalcType === "issuedItems" ? { "referenceType": "backCalc" } : {};
this.referenceType = "formula";
this.setState({
value: this.props.formulaContent
});
@ -196,7 +196,7 @@ export default class FormalFormModal extends React.Component {
module: "salary",
useFor: "salaryitem",
returnType: this.props.dataType || this.state.returnType,
validateType: this.props.dataType|| this.state.validateType,
validateType: this.props.dataType || this.state.returnType,
extendParam: JSON.stringify(this.state.extendParam),
formula: this.state.value,
parameters: this.parameters,

View File

@ -3,6 +3,7 @@ import { message } from "antd";
import { WeaForm, WeaTableNew } from "comsMobx";
import * as API from "../apis/calculate";
import { backCalculate } from "../apis/calculate";
const { TableStore } = WeaTableNew;
@ -466,7 +467,21 @@ export class calculateStore {
}
});
});
};
// 薪资记录-回算
@action
backCalculate = (salaryAcctRecordId) => {
return new Promise((resolve, reject) => {
API.backCalculate({ salaryAcctRecordId }).then(res => {
if (res.status) {
message.success("回算成功");
resolve();
} else {
message.error(res.errormsg || "回算失败");
reject();
}
});
});
};
// 薪资结果-编辑表单保存