Merge branch 'release/2.9.42310.01' into release/2.9.42310.01-个税
This commit is contained in:
commit
f3e1e1e166
|
|
@ -1,141 +1,5 @@
|
|||
import { WeaTools } from "ecCom";
|
||||
|
||||
//薪资核算-薪资核算列表
|
||||
export const getCalcList = params => {
|
||||
return WeaTools.callApi("/api/bs/hrmsalary/salaryAcct/list", "POST", params);
|
||||
};
|
||||
|
||||
|
||||
//薪资核算-删除薪资核算记录
|
||||
export const deleteCalc = params => {
|
||||
return WeaTools.callApi("/api/bs/hrmsalary/salaryAcct/delete", "POST", params);
|
||||
};
|
||||
|
||||
//薪资核算-归档薪资核算记录
|
||||
export const fileCalc = params => {
|
||||
return WeaTools.callApi("/api/bs/hrmsalary/salaryAcct/file", "POST", params);
|
||||
};
|
||||
|
||||
//薪资核算-薪资核算详情
|
||||
export const getCalcForm = params => {
|
||||
return WeaTools.callApi("/api/bs/hrmsalary/salaryAcct/getForm", "get", params);
|
||||
};
|
||||
|
||||
//薪资核算-保存薪资核算的基本信息
|
||||
export const saveCalc = params => {
|
||||
return WeaTools.callApi("/api/bs/hrmsalary/salaryAcct/basic/save", "POST", params);
|
||||
};
|
||||
|
||||
//薪资核算-获取薪资核算提示信息
|
||||
export const getCalcInfo = params => {
|
||||
return WeaTools.callApi("/api/bs/hrmsalary/salaryAcct/getSalarySobCycle", "get", params);
|
||||
};
|
||||
|
||||
//薪资核算-薪资核算人员确认列表
|
||||
export const getCalcPersonList = params => {
|
||||
return WeaTools.callApi("/api/bs/hrmsalary/salaryAcct/acctEmployee/list", "POST", params);
|
||||
};
|
||||
|
||||
//薪资核算-薪资核算人员高级搜索
|
||||
export const getCalcPersonSa = params => {
|
||||
return WeaTools.callApi("/api/bs/hrmsalary/salaryAcct/acctEmployee/getSearchCondition", "get", params);
|
||||
};
|
||||
|
||||
//薪资核算-删除薪资核算人员
|
||||
export const deleteCalcPerson = params => {
|
||||
return WeaTools.callApi("/api/bs/hrmsalary/salaryAcct/acctEmployee/delete", "POST", params);
|
||||
};
|
||||
|
||||
//薪资核算-添加薪资核算人员
|
||||
export const saveCalcPerson = params => {
|
||||
return WeaTools.callApi("/api/bs/hrmsalary/salaryAcct/acctEmployee/save", "POST", params);
|
||||
};
|
||||
|
||||
//薪资核算-导出人员范围
|
||||
export const exportCalcPerson = params => {
|
||||
return WeaTools.callApi("/api/bs/hrmsalary/salaryAcct/acctEmployee/export", "POST", params);
|
||||
};
|
||||
|
||||
//薪资核算-薪资核算环比上期减少人员列表
|
||||
export const getCalcPersonSubList = params => {
|
||||
return WeaTools.callApi("/api/bs/hrmsalary/salaryAcct/reducedEmployee/list", "POST", params);
|
||||
};
|
||||
|
||||
//薪资核算-导出环比减少人员
|
||||
export const exportCalcPersonSub = params => {
|
||||
return WeaTools.callApi("/api/bs/hrmsalary/salaryAcct/reducedEmployee/export", "POST", params);
|
||||
};
|
||||
|
||||
|
||||
//薪资核算-执行薪资核算
|
||||
export const doScCalc = params => {
|
||||
return WeaTools.callApi("/api/bs/hrmsalary/salaryAcct/acctResult/accounting", "POST", params);
|
||||
};
|
||||
|
||||
|
||||
//薪资核算-获取薪资核算结果高级搜索
|
||||
export const getScSa = params => {
|
||||
return WeaTools.callApi("/api/bs/hrmsalary/salaryAcct/acctResult/getSearchCondition", "get", params);
|
||||
};
|
||||
|
||||
//薪资核算-薪资核算结果列表
|
||||
export const getScList = params => {
|
||||
return WeaTools.callApi("/api/bs/hrmsalary/salaryAcct/acctResult/list", "post", params);
|
||||
};
|
||||
|
||||
|
||||
//薪资核算-导出薪资核算
|
||||
export const exportSc = params => {
|
||||
return WeaTools.callApi("/api/bs/hrmsalary/salaryAcct/acctResult/export", "post", params);
|
||||
};
|
||||
|
||||
//薪资核算-导出线下对比结果
|
||||
export const exportOc = params => {
|
||||
return WeaTools.callApi("/api/bs/hrmsalary/salaryAcct/comparisonResult/export", "post", params);
|
||||
};
|
||||
|
||||
|
||||
//薪资核算-薪资核算结果详情
|
||||
export const getScDetail = params => {
|
||||
return WeaTools.callApi("/api/bs/hrmsalary/salaryAcct/acctResult/detail", "get", params);
|
||||
};
|
||||
|
||||
//薪资核算-薪资核算合并计税详情
|
||||
export const getScMergeTaxDetail = params => {
|
||||
return WeaTools.callApi("/api/bs/hrmsalary/salaryAcct/acctResult/getConsolidatedTaxDetail", "get", params);
|
||||
};
|
||||
|
||||
//薪资核算-编辑薪资核算结果
|
||||
export const editScResult = params => {
|
||||
return WeaTools.callApi("/api/bs/hrmsalary/salaryAcct/acctResult/save", "post", params);
|
||||
};
|
||||
|
||||
//薪资核算-薪资核算结果校验
|
||||
export const checkScResult = params => {
|
||||
return WeaTools.callApi("/api/bs/hrmsalary/salaryAcct/acctResult/check", "post", params);
|
||||
};
|
||||
|
||||
|
||||
//薪资核算-获取校验结果(异常)总数
|
||||
export const getScResultExceptionCount = params => {
|
||||
return WeaTools.callApi("/api/bs/hrmsalary/salaryAcct/checkResult/getCount", "get", params);
|
||||
};
|
||||
|
||||
//薪资核算-校验结果列表
|
||||
export const getCheckResultList = params => {
|
||||
return WeaTools.callApi("/api/bs/hrmsalary/salaryAcct/checkResult/list", "POST", params);
|
||||
};
|
||||
|
||||
//薪资核算-校验结果明细列表
|
||||
export const getCheckResultDetailList = params => {
|
||||
return WeaTools.callApi("/api/bs/hrmsalary/salaryAcct/checkResultRecord/list", "POST", params);
|
||||
};
|
||||
|
||||
//薪资核算-获取导入组件前置参数
|
||||
export const getImportParams = params => {
|
||||
return WeaTools.callApi("/api/bs/hrmsalary/salaryAcct/checkResultRecord/list", "POST", params);
|
||||
};
|
||||
|
||||
// 薪资记录--薪资核算列表
|
||||
export const getSalaryAcctList = params => {
|
||||
return fetch("/api/bs/hrmsalary/salaryacct/list", {
|
||||
|
|
@ -176,6 +40,17 @@ export const reducedemployeeList = params => {
|
|||
body: JSON.stringify(params)
|
||||
}).then(res => res.json());
|
||||
};
|
||||
// 核算人员--薪资核算环比上月增加人员
|
||||
export const addedemployeeList = params => {
|
||||
return fetch("/api/bs/hrmsalary/salaryacct/addedemployee/list", {
|
||||
method: "POST",
|
||||
mode: "cors",
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
body: JSON.stringify(params)
|
||||
}).then(res => res.json());
|
||||
};
|
||||
|
||||
// 核算人员--薪资核算人员确认列表
|
||||
export const acctemployeeList = params => {
|
||||
|
|
@ -206,7 +81,6 @@ export const getSalarySobCycle = params => {
|
|||
return WeaTools.callApi("/api/bs/hrmsalary/salaryacct/getSalarySobCycle", "GET", params);
|
||||
};
|
||||
|
||||
|
||||
// 核算人员--添加薪资核算人员
|
||||
export const saveAcctemployee = params => {
|
||||
return fetch("/api/bs/hrmsalary/salaryacct/acctemployee/save", {
|
||||
|
|
@ -232,7 +106,6 @@ export const exportReducedEmployee = (id) => {
|
|||
}));
|
||||
};
|
||||
|
||||
|
||||
// 核算人员--导出人员范围
|
||||
export const exportAcctEmployee = (id) => {
|
||||
fetch("/api/bs/hrmsalary/salaryacct/acctemployee/export?salaryAcctRecordId=" + id).then(res => res.blob().then(blob => {
|
||||
|
|
@ -374,7 +247,6 @@ export const getImportField = (params) => {
|
|||
return WeaTools.callApi("/api/bs/hrmsalary/salaryacct/acctresult/importField", "GET", params);
|
||||
};
|
||||
|
||||
|
||||
// 核算结果-导入模板
|
||||
export const getImportTemplate = (salaryItemIds, salaryAcctRecordId) => {
|
||||
fetch("/api/bs/hrmsalary/salaryacct/acctresult/importtemplate/export?salaryItemIds=" + salaryItemIds + "&salaryAcctRecordId=" + salaryAcctRecordId).then(res => res.blob().then(blob => {
|
||||
|
|
@ -412,7 +284,6 @@ export const importAcctResult = (params) => {
|
|||
}).then(res => res.json());
|
||||
};
|
||||
|
||||
|
||||
// 核算结果-导出全部
|
||||
export const exportAcctResult = (salaryAcctRecordId, ids) => {
|
||||
fetch("/api/bs/hrmsalary/salaryacct/acctresult/export?salaryAcctRecordId=" + salaryAcctRecordId + "&ids=" + ids).then(res => res.blob().then(blob => {
|
||||
|
|
@ -509,50 +380,6 @@ export const updateLockStatus = (params) => {
|
|||
body: JSON.stringify(params)
|
||||
}).then(res => res.json());
|
||||
};
|
||||
// 社保福利台账合计接口
|
||||
export const siaccountDetailCommonListSum = (params) => {
|
||||
return fetch("/api/bs/hrmsalary/siaccount/detail/common/list/sum", {
|
||||
method: "POST",
|
||||
mode: "cors",
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
body: JSON.stringify(params)
|
||||
}).then(res => res.json());
|
||||
};
|
||||
// 社保福利台账补缴合计接口
|
||||
export const siaccountDetailSupplementaryListSum = (params) => {
|
||||
return fetch("/api/bs/hrmsalary/siaccount/detail/supplementary/list/sum", {
|
||||
method: "POST",
|
||||
mode: "cors",
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
body: JSON.stringify(params)
|
||||
}).then(res => res.json());
|
||||
};
|
||||
// 社保福利台账退差合计接口
|
||||
export const siaccountDetailRecessionListSum = (params) => {
|
||||
return fetch("/api/bs/hrmsalary/siaccount/detail/recession/list/sum", {
|
||||
method: "POST",
|
||||
mode: "cors",
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
body: JSON.stringify(params)
|
||||
}).then(res => res.json());
|
||||
};
|
||||
// 社保福利台账补差合计接口
|
||||
export const siaccountDetailBalanceListSum = (params) => {
|
||||
return fetch("/api/bs/hrmsalary/siaccount/detail/balance/list/sum", {
|
||||
method: "POST",
|
||||
mode: "cors",
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
body: JSON.stringify(params)
|
||||
}).then(res => res.json());
|
||||
};
|
||||
// 导入薪资核算添加表头字段缓存
|
||||
export const cacheImportField = (params) => {
|
||||
return fetch("/api/bs/hrmsalary/salaryacct/acctresult/cacheImportField", {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { WeaTools } from "ecCom";
|
||||
import { convertToUrlString } from "../util/url";
|
||||
|
||||
// 工资单列表
|
||||
export const mySalaryBillList = params => {
|
||||
|
|
@ -25,7 +26,13 @@ export const recordList = params => {
|
|||
|
||||
// 工资查看详情
|
||||
export const mySalaryBill = params => {
|
||||
return WeaTools.callApi("/api/bs/hrmsalary/salaryBill/mySalaryBill", "GET", params);
|
||||
return fetch(`/api/bs/hrmsalary/salaryBill/mySalaryBill?${convertToUrlString(params)}`, {
|
||||
method: "GET",
|
||||
mode: "cors",
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
}).then(res => res.json());
|
||||
};
|
||||
|
||||
export const isNeedSecondPwdVerify = params => {
|
||||
|
|
|
|||
|
|
@ -61,8 +61,15 @@ class ImpStep1 extends Component {
|
|||
<div>{getLabel(27577, "操作步骤")}</div>
|
||||
<p>
|
||||
<span>{`1. ${getLabel(30907, "第一步")},${getLabel(543205, "请选择导出的Excel文件或")}`}</span>
|
||||
<a href={this.props.link} className="weapp-salary-link"
|
||||
target="_blank">{getLabel(543207, "点击这里下载模板")}</a>
|
||||
{
|
||||
typeof this.props.link === "string" ?
|
||||
<a href={this.props.link} className="weapp-salary-link"
|
||||
target="_blank">{getLabel(543207, "点击这里下载模板")}</a> :
|
||||
<a className="weapp-salary-link"
|
||||
onClick={this.props.link}
|
||||
>{getLabel(543207, "点击这里下载模板")}</a>
|
||||
}
|
||||
|
||||
{this.props.exportDataDom}
|
||||
</p>
|
||||
<p>{`2. ${getLabel(543211, "第二步")},${getLabel(543212, "请一定要确定Excel文档中的格式是模板中的格式")},${getLabel(543213, "没有被修改掉")};`}</p>
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@ class ImpStep2 extends Component {
|
|||
}
|
||||
|
||||
init = () => {
|
||||
const { previewUrl, imageId } = this.props;
|
||||
const payload = { imageId };
|
||||
const { previewUrl, imageId, extraPreview = {} } = this.props;
|
||||
const payload = { imageId, ...extraPreview };
|
||||
this.setState({ loading: true });
|
||||
postFetch(previewUrl, payload).then(({ status, data }) => {
|
||||
this.setState({ loading: false });
|
||||
|
|
|
|||
|
|
@ -31,6 +31,8 @@ import TaxAgent from "./pages/salary/taxAgent";
|
|||
import CalculateDetail from "./pages/calculateDetail";
|
||||
import PlaceOnFileDetail from "./pages/calculateDetail/placeOnFileDetail";
|
||||
import CompareDetail from "./pages/calculateDetail/compareDetail";
|
||||
import DoCalcDetail from "./pages/calculate/doCalc";
|
||||
import OfflineCompare from "./pages/calculate/calcOc";
|
||||
import GenerateDeclarationDetail from "./pages/declare/generateDeclarationDetail";
|
||||
import TemplatePreview from "./pages/payroll/templatePreview";
|
||||
import MobilePayroll from "./pages/mobilePayroll";
|
||||
|
|
@ -80,6 +82,8 @@ const DataAcquisition = (props) => props.children;
|
|||
// ledger 薪资账套
|
||||
// calculate 薪资核算
|
||||
// calculateDetail 核算详情
|
||||
// DoCalcDetail 核算详情页面-新
|
||||
// OfflineCompare 薪资核算线下对比-新
|
||||
// placeOnFileDetail 核算归档详情
|
||||
// compareDetail 线下线上对比
|
||||
// payroll 工资单发放
|
||||
|
|
@ -140,6 +144,8 @@ const Routes = (
|
|||
<Route key="ledger" path="ledger" component={Ledger}/>
|
||||
<Route key="calculate" path="calculate" component={Calculate}/>
|
||||
<Route key="calculateDetail" path="calculateDetail" component={CalculateDetail}/>
|
||||
<Route key="doCalc" path="calculate/:salaryAcctRecordId" component={DoCalcDetail}/>
|
||||
<Route key="calcOc" path="calcOc/:salaryAcctRecordId" component={OfflineCompare}/>
|
||||
<Route key="placeOnFileDetail" path="placeOnFileDetail" component={PlaceOnFileDetail}/>
|
||||
<Route key="compareDetail" path="compareDetail" component={CompareDetail}/>
|
||||
<Route key="payroll" path="payroll" component={Payroll}/>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Author: 黎永顺
|
||||
* name: 薪資核算-线下对比导入
|
||||
* Description:
|
||||
* Date: 2023/9/27
|
||||
*/
|
||||
import React, { Component } from "react";
|
||||
import { WeaLocaleProvider } from "ecCom";
|
||||
import ImportDialog from "../../../../components/importDialog";
|
||||
import { importComparisonExcelAcctResult } from "../../../../apis/calculate";
|
||||
|
||||
const getLabel = WeaLocaleProvider.getLabel;
|
||||
|
||||
class SalaryCalcOcImport extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
importDialog: {
|
||||
visible: false, title: "", nextloading: false, importResult: {}, imageId: "",
|
||||
link: "/api/bs/hrmsalary/salaryacct/comparisonresult/importtemplate/export?salaryAcctRecordId=",
|
||||
previewUrl: "/api/bs/hrmsalary/salaryacct/comparisonresult/preview",
|
||||
extraPreview: { salaryAcctRecordId: "" }
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps, nextContext) {
|
||||
if (nextProps.visible !== this.props.visible) {
|
||||
const { importDialog } = this.state;
|
||||
this.setState({
|
||||
importDialog: {
|
||||
...this.state.importDialog,
|
||||
link: `${importDialog.link}${nextProps.salaryAcctRecordId}`,
|
||||
visible: nextProps.visible, importResult: {},
|
||||
title: nextProps.title, imageId: "",
|
||||
extraPreview: { salaryAcctRecordId: nextProps.salaryAcctRecordId }
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
handleImport = (payload) => {
|
||||
const { importDialog } = this.state;
|
||||
const { salaryAcctRecordId } = this.props;
|
||||
this.setState({ importDialog: { ...importDialog, nextloading: true } });
|
||||
importComparisonExcelAcctResult({ ...payload, salaryAcctRecordId })
|
||||
.then(({ data, status }) => {
|
||||
this.setState({ importDialog: { ...importDialog, nextloading: false } });
|
||||
if (status) {
|
||||
this.setState({
|
||||
importDialog: { ...importDialog, ...payload, importResult: data }
|
||||
});
|
||||
}
|
||||
}).catch(() => this.setState({ importDialog: { ...importDialog, nextloading: false } }));
|
||||
};
|
||||
|
||||
render() {
|
||||
const { importDialog } = this.state;
|
||||
return (
|
||||
<ImportDialog
|
||||
{...importDialog} onCancel={this.props.onCancel} exportDataDom={null}
|
||||
onResetImportResult={() => this.setState(({
|
||||
importDialog: { ...importDialog, importResult: {}, imageId: "" }
|
||||
}))}
|
||||
nextCallback={imageId => this.handleImport({ imageId })}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default SalaryCalcOcImport;
|
||||
|
|
@ -0,0 +1,126 @@
|
|||
/*
|
||||
* Author: 黎永顺
|
||||
* name: 薪资核算-线下对比列表
|
||||
* Description:
|
||||
* Date: 2023/9/26
|
||||
*/
|
||||
import React, { Component } from "react";
|
||||
import { WeaLocaleProvider, WeaTable } from "ecCom";
|
||||
import { Alert } from "antd";
|
||||
import { comparisonResultList } from "../../../../apis/calculate";
|
||||
|
||||
const getLabel = WeaLocaleProvider.getLabel;
|
||||
|
||||
class SalaryCalcOcList extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
loading: false, pageInfo: { current: 1, pageSize: 10, total: 0 },
|
||||
columns: [], dataSource: [], formulaDesc: ""
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.comparisonResultList(this.props);
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps, nextContext) {
|
||||
if (
|
||||
(nextProps.form.onlyDiffEmployee !== this.props.form.onlyDiffEmployee) ||
|
||||
(nextProps.form.onlyDiffSalaryItem !== this.props.form.onlyDiffSalaryItem) ||
|
||||
(nextProps.searchBool !== this.props.searchBool)
|
||||
) {
|
||||
this.comparisonResultList(nextProps);
|
||||
}
|
||||
}
|
||||
|
||||
comparisonResultList = (props) => {
|
||||
const { form, routeParams: { salaryAcctRecordId } } = props;
|
||||
const { pageInfo } = this.state;
|
||||
this.setState({ loading: true });
|
||||
const payload = { ...pageInfo, ...form, salaryAcctRecordId };
|
||||
comparisonResultList(payload).then(({ status, data }) => {
|
||||
this.setState({ loading: false });
|
||||
if (status) {
|
||||
const { list: dataSource, columns, pageNum: current, pageSize, total } = data;
|
||||
this.setState({
|
||||
dataSource, columns,
|
||||
pageInfo: { ...pageInfo, current, pageSize, total }
|
||||
});
|
||||
}
|
||||
}).catch(() => this.setState({ loading: false }));
|
||||
};
|
||||
|
||||
render() {
|
||||
const { dataSource, loading, columns, pageInfo, formulaDesc } = this.state;
|
||||
const pagination = {
|
||||
...pageInfo,
|
||||
showTotal: total => `${getLabel(18609, "共")} ${total} ${getLabel(18256, "条")}`,
|
||||
showQuickJumper: true,
|
||||
showSizeChanger: true,
|
||||
pageSizeOptions: ["10", "20", "50", "100"],
|
||||
onShowSizeChange: (current, pageSize) => {
|
||||
this.setState({
|
||||
pageInfo: { ...pageInfo, current, pageSize }
|
||||
}, () => this.comparisonResultList(this.props));
|
||||
},
|
||||
onChange: current => {
|
||||
this.setState({
|
||||
pageInfo: { ...pageInfo, current }
|
||||
}, () => this.comparisonResultList(this.props));
|
||||
}
|
||||
};
|
||||
return (
|
||||
<React.Fragment>
|
||||
<Alert message={`${getLabel(18125, "公式")}:${formulaDesc}`} type="info"/>
|
||||
<WeaTable
|
||||
rowKey="id" pagination={pagination} loading={loading} dataSource={dataSource}
|
||||
scroll={{ x: 840, y: "calc(100vh - 246px)" }}
|
||||
columns={_.map(columns, (o, i) => {
|
||||
if (i > 1) {
|
||||
if (i > 2) {
|
||||
return {
|
||||
...o, width: 180,
|
||||
render: (__, record) => {
|
||||
const formulaDesc = record["customParameters"][`${o["dataIndex"]}`];
|
||||
const showDifference = record[`${o["dataIndex"]}_type`] === "number";
|
||||
const { acctResultValue, excelResultValue } = record[o["dataIndex"]];
|
||||
return <div className="comparison-column-item-container"
|
||||
onClick={() => this.setState({ formulaDesc })}>
|
||||
<div className="comparison-single-row">
|
||||
<span>{getLabel(543280, "系统值")}:</span>
|
||||
<span>{acctResultValue}</span>
|
||||
</div>
|
||||
<div className="comparison-single-row">
|
||||
<span>{getLabel(543281, "线下值")}:</span>
|
||||
<span>{excelResultValue}</span>
|
||||
</div>
|
||||
{
|
||||
showDifference &&
|
||||
<div className="comparison-single-row danger">
|
||||
<span>{getLabel(543282, "差值")}:</span>
|
||||
<span>{calculateDifference(acctResultValue, excelResultValue)}</span>
|
||||
</div>
|
||||
}
|
||||
</div>;
|
||||
}
|
||||
};
|
||||
}
|
||||
return { ...o, width: 180 };
|
||||
}
|
||||
return { ...o, width: 150, fixed: "left" };
|
||||
})}
|
||||
/>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default SalaryCalcOcList;
|
||||
// 计算差值
|
||||
const calculateDifference = (systemValue, excelValue) => {
|
||||
if (_.isNil(systemValue) || _.isNil(excelValue)) return "";
|
||||
const systemNum = Number(systemValue);
|
||||
const excelNum = Number(excelValue);
|
||||
return (systemNum - excelNum).toFixed(2);
|
||||
};
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* Author: 黎永顺
|
||||
* name: 薪资核算-线下对比
|
||||
* Description:
|
||||
* Date: 2023/9/26
|
||||
*/
|
||||
import React, { Component } from "react";
|
||||
import { Button } from "antd";
|
||||
import { WeaCheckbox, WeaInputSearch, WeaLocaleProvider } from "ecCom";
|
||||
import SalaryCalcOcList from "./components/salaryCalcOcList";
|
||||
import SalaryCalcOcImport from "./components/salaryCalcOcImport";
|
||||
import Layout from "../doCalc/layout";
|
||||
import "./index.less";
|
||||
|
||||
const getLabel = WeaLocaleProvider.getLabel;
|
||||
|
||||
class Index extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
salaryOcImpDialog: { visible: false, title: "", salaryAcctRecordId: "" },
|
||||
form: {
|
||||
onlyDiffEmployee: true, onlyDiffSalaryItem: true,
|
||||
employeeName: ""
|
||||
}, searchBool: false
|
||||
};
|
||||
}
|
||||
|
||||
handleFiledChange = (key, value) => {
|
||||
const { form } = this.state;
|
||||
this.setState({
|
||||
form: { ...form, [key]: value }
|
||||
});
|
||||
};
|
||||
|
||||
handleExportClick = () => {
|
||||
const { routeParams: { salaryAcctRecordId } } = this.props;
|
||||
window.open(`/api/bs/hrmsalary/salaryacct/comparisonresult/export?salaryAcctRecordId=${salaryAcctRecordId}`, "_blank");
|
||||
};
|
||||
handleImportClick = () => {
|
||||
const { routeParams: { salaryAcctRecordId } } = this.props;
|
||||
this.setState({
|
||||
salaryOcImpDialog: { visible: true, title: getLabel(24023, "数据导入"), salaryAcctRecordId }
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
const { form, searchBool, salaryOcImpDialog } = this.state;
|
||||
return (
|
||||
<Layout {...this.props}>
|
||||
<div className="salary-calc-oc">
|
||||
<div className="compare-header header-border-bottom">
|
||||
<div className="left-search">
|
||||
<WeaCheckbox content={getLabel(543283, "只显示有差异的人员")}
|
||||
value={form["onlyDiffEmployee"] ? "1" : "0"}
|
||||
onChange={v => this.handleFiledChange("onlyDiffEmployee", v === "1")}/>
|
||||
<WeaCheckbox content={getLabel(543284, "只显示有差异的薪资项目")}
|
||||
value={form["onlyDiffSalaryItem"] ? "1" : "0"}
|
||||
onChange={v => this.handleFiledChange("onlyDiffSalaryItem", v === "1")}/>
|
||||
</div>
|
||||
<div className="weapp-salary-btn-flex header">
|
||||
<Button type="primary" onClick={this.handleImportClick}>{getLabel(32935, "导入")}</Button>
|
||||
<Button type="ghost" onClick={this.handleExportClick}>{getLabel(17416, "导出")}</Button>
|
||||
<WeaInputSearch placeholder={getLabel(26919, "请输入姓名")} value={form["employeeName"]}
|
||||
onChange={v => this.handleFiledChange("employeeName", v)}
|
||||
onSearch={() => this.setState({ searchBool: !searchBool })}/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="salary-calc-oc-body">
|
||||
<SalaryCalcOcList {...this.props} form={form} searchBool={searchBool}/>
|
||||
<SalaryCalcOcImport
|
||||
{...salaryOcImpDialog}
|
||||
onCancel={(isFresh) => this.setState({
|
||||
salaryOcImpDialog: { ...salaryOcImpDialog, visible: false },
|
||||
searchBool: typeof isFresh === "boolean" ? !searchBool : searchBool
|
||||
})}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default Index;
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
.salary-calc-oc {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
background: #f6f6f6;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.compare-header {
|
||||
padding-left: 16px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
.left-search {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.weapp-salary-btn-flex {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
cursor: auto;
|
||||
|
||||
& > button {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.wea-input-focus {
|
||||
background: #f6f6f6;
|
||||
margin-top: -4px;
|
||||
|
||||
.ant-input {
|
||||
background: #f6f6f6;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.header {
|
||||
height: 48px;
|
||||
padding: 0 16px;
|
||||
font-size: 12px;
|
||||
color: #111;
|
||||
}
|
||||
}
|
||||
|
||||
.header-border-bottom {
|
||||
border-bottom: 1px solid #e5e5e5;
|
||||
}
|
||||
|
||||
.salary-calc-oc-body {
|
||||
flex: 1;
|
||||
padding: 16px;
|
||||
overflow-y: hidden;
|
||||
|
||||
.wea-new-table {
|
||||
background: #FFF;
|
||||
height: calc(100% - 44px);
|
||||
|
||||
.ant-table-tbody {
|
||||
td {
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
.comparison-column-item-container {
|
||||
cursor: pointer;
|
||||
|
||||
.comparison-single-row {
|
||||
margin: 4px 0;
|
||||
}
|
||||
|
||||
.danger {
|
||||
color: #ff4d4f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
import React, { Component } from "react";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import { Button } from "antd";
|
||||
import { WeaInputSearch, WeaLocaleProvider } from "ecCom";
|
||||
import "./index.less";
|
||||
|
||||
const getLabel = WeaLocaleProvider.getLabel;
|
||||
|
||||
@inject("calculateStore")
|
||||
@observer
|
||||
class Index extends Component {
|
||||
render() {
|
||||
const { calculateStore: { ECSearchForm } } = this.props;
|
||||
return (
|
||||
<div className="advance-search">
|
||||
<WeaInputSearch value={ECSearchForm.getFormParams().employeeName}
|
||||
onChange={v => ECSearchForm.updateFields({ employeeName: v })}
|
||||
onSearch={this.props.onAdvanceSearch}
|
||||
/>
|
||||
<Button type="ghost" className="wea-advanced-search text-elli"
|
||||
onClick={this.props.onOpenAdvanceSearch}>{getLabel(111, "高级搜索")}</Button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default Index;
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
.advance-search {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
top: -2.5px;
|
||||
|
||||
.wea-advanced-search {
|
||||
top: 2px;
|
||||
left: -1px;
|
||||
height: 28px;
|
||||
line-height: 1;
|
||||
border-radius: 0;
|
||||
position: relative;
|
||||
color: #474747;
|
||||
padding: 4px 15px;
|
||||
}
|
||||
|
||||
.wea-advanced-search:hover {
|
||||
border: 1px solid #dadada;
|
||||
color: #474747;
|
||||
}
|
||||
|
||||
.text-elli {
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,138 @@
|
|||
/*
|
||||
* Author: 黎永顺
|
||||
* name: 薪资核算-自定义导出
|
||||
* Description:
|
||||
* Date: 2023/9/18
|
||||
*/
|
||||
|
||||
import React, { Component } from "react";
|
||||
import { Button, Col, message, Row } from "antd";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import { WeaCheckbox, WeaDialog, WeaLocaleProvider, WeaSearchGroup } from "ecCom";
|
||||
import { customCacheExportField } from "../../../../../apis/calculate";
|
||||
import { convertToUrlString } from "../../../../../util/url";
|
||||
|
||||
const { getLabel } = WeaLocaleProvider;
|
||||
|
||||
@inject("calculateStore")
|
||||
@observer
|
||||
class Index extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
itemsCheckeds: [],
|
||||
showOnlyChecked: false
|
||||
};
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps, nextContext) {
|
||||
if (nextProps.visible !== this.props.visible && nextProps.visible) {
|
||||
this.setState({
|
||||
itemsCheckeds: !_.isEmpty(nextProps.checkItems) ? nextProps.checkItems : []
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
customExportClick = () => {
|
||||
const { calculateStore: { ECSearchForm }, salaryAcctRecordId } = this.props;
|
||||
const { itemsCheckeds } = this.state;
|
||||
customCacheExportField({ salaryItems: _.map(itemsCheckeds, it => it.toString()) }).then(({ status, errorMsg }) => {
|
||||
if (status) {
|
||||
const { consolidatedTaxation = "0", ...extra } = ECSearchForm.getFormParams();
|
||||
const payload = { ...extra, consolidatedTaxation: consolidatedTaxation === "0" ? "" : consolidatedTaxation };
|
||||
window.open(
|
||||
`/api/bs/hrmsalary/salaryacct/acctresult/exportWithCustomFields?salaryAcctRecordId=${salaryAcctRecordId}&ids=&${convertToUrlString(payload)}&salaryItemIds=${itemsCheckeds.join(",")}`
|
||||
);
|
||||
} else {
|
||||
message.error(errorMsg);
|
||||
}
|
||||
});
|
||||
};
|
||||
handleShowOnlyChecked = (showOnlyChecked) => this.setState({ showOnlyChecked: !!Number(showOnlyChecked) });
|
||||
handleSelectGroupAll = (groupId, checked) => {
|
||||
const { itemsCheckeds } = this.state;
|
||||
const { itemsByGroup } = this.props;
|
||||
_.map(itemsByGroup, item => {
|
||||
if (item.salarySobItemGroupId === groupId) {
|
||||
if (!!Number(checked)) {
|
||||
this.setState({
|
||||
itemsCheckeds: [...itemsCheckeds, ..._.map(item.salaryItems, child => child.salaryItemId)]
|
||||
});
|
||||
} else {
|
||||
this.setState({
|
||||
itemsCheckeds: _.differenceWith(itemsCheckeds, _.map(item.salaryItems, child => child.salaryItemId), _.isEqual)
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
const { showOnlyChecked, itemsCheckeds } = this.state;
|
||||
const { itemsByGroup } = this.props;
|
||||
let dataSource = _.map(itemsByGroup, item => {
|
||||
return {
|
||||
...item,
|
||||
salaryItems: _.map(item.salaryItems, child => {
|
||||
return { ...child, checked: itemsCheckeds.includes(child.salaryItemId) };
|
||||
})
|
||||
};
|
||||
});
|
||||
if (showOnlyChecked) {
|
||||
dataSource = _.map(dataSource, item => {
|
||||
return { ...item, salaryItems: _.filter(item.salaryItems, it => !!it.checked) };
|
||||
});
|
||||
}
|
||||
return (
|
||||
<WeaDialog
|
||||
{...this.props} hasScroll initLoadCss
|
||||
scalable title={getLabel(111, "选择字段")}
|
||||
style={{
|
||||
width: 700,
|
||||
height: 606.6,
|
||||
minHeight: 200,
|
||||
minWidth: 380,
|
||||
maxHeight: "70%",
|
||||
maxWidth: "90%",
|
||||
overflow: "hidden",
|
||||
transform: "translate(0px, 0px)"
|
||||
}}
|
||||
buttons={[
|
||||
<Button type="primary" onClick={this.customExportClick}>{getLabel(17416, "导出")}</Button>,
|
||||
<Button type="ghost" onClick={this.props.onCancel}>{getLabel(31129, "取消")}</Button>
|
||||
]}
|
||||
bottomLeft={<WeaCheckbox content={getLabel(543378, "只显示已选中字段")}
|
||||
onChange={this.handleShowOnlyChecked}/>}
|
||||
>
|
||||
{
|
||||
_.map(dataSource, item => {
|
||||
const { salarySobItemGroupName, salaryItems, salarySobItemGroupId } = item;
|
||||
const value = _.every(salaryItems, it => !!it.checked) ? "1" : "0";
|
||||
return <WeaSearchGroup showGroup needTigger
|
||||
title={<WeaCheckbox content={salarySobItemGroupName} value={value}
|
||||
onChange={(val) => this.handleSelectGroupAll(salarySobItemGroupId, val)}/>}>
|
||||
<Row gutter={16}>
|
||||
{
|
||||
!_.isEmpty(salaryItems) ?
|
||||
_.map(salaryItems, it => {
|
||||
const { salaryItemId, salaryItemName, checked } = it;
|
||||
return <Col span={8} style={{ marginBottom: 16 }}>
|
||||
<WeaCheckbox content={salaryItemName} value={checked ? "1" : "0"}
|
||||
onChange={() => this.setState({ itemsCheckeds: _.xorWith(itemsCheckeds, [salaryItemId], _.isEqual) })}/>
|
||||
</Col>;
|
||||
}) : <Col span={24} style={{
|
||||
minHeight: 20,
|
||||
padding: "5%",
|
||||
textAlign: "center"
|
||||
}}>{getLabel(83553, "暂无数据")}</Col>
|
||||
}
|
||||
</Row>
|
||||
</WeaSearchGroup>;
|
||||
})
|
||||
}
|
||||
</WeaDialog>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default Index;
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* Author: 黎永顺
|
||||
* name: 人员信息确认-基础信息
|
||||
* Description:
|
||||
* Date: 2023/9/13
|
||||
*/
|
||||
import React, { Component } from "react";
|
||||
import { WeaHelpfulTip, WeaLocaleProvider, WeaSearchGroup } from "ecCom";
|
||||
import SalaryMonthTip from "../salaryMonthTip";
|
||||
import { getSalarySobCycle, salaryacctGetForm } from "../../../../../apis/calculate";
|
||||
import { Col, Row } from "antd";
|
||||
import "./index.less";
|
||||
|
||||
const getLabel = WeaLocaleProvider.getLabel;
|
||||
|
||||
class BaseInfo extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
salaryInfo: {}, salarySobCycle: {}
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const promise = this.init();
|
||||
}
|
||||
|
||||
init = async () => {
|
||||
const { routeParams: { salaryAcctRecordId } } = this.props;
|
||||
const [salaryInfo, salarySobCycle] = await Promise.all([salaryacctGetForm({ id: salaryAcctRecordId }), getSalarySobCycle({ salaryAcctRecordId })]);
|
||||
if (salaryInfo.status && salarySobCycle.status) {
|
||||
this.setState({
|
||||
salaryInfo: salaryInfo.data, salarySobCycle: salarySobCycle.data
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const { salaryInfo, salarySobCycle } = this.state;
|
||||
const { formDTO } = salaryInfo || {};
|
||||
return (
|
||||
<WeaSearchGroup title={getLabel(82743, "基础信息")} needTigger showGroup className="docalc-baseinfo-layout">
|
||||
<Row type="flex" className="docalc-baseinfo">
|
||||
<Col span={12}>
|
||||
<Row>
|
||||
<Col span={6}>
|
||||
<span className="label">{getLabel(542604, "薪资所属月")}</span>
|
||||
<WeaHelpfulTip
|
||||
width={200} placement="topLeft"
|
||||
title={<SalaryMonthTip {...salarySobCycle}/>}
|
||||
style={{ marginLeft: 10 }}
|
||||
/>
|
||||
</Col>
|
||||
<Col span={18}><span className="value">{formDTO && formDTO.salaryMonth}</span></Col>
|
||||
</Row>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Row>
|
||||
<Col span={6}><span className="label">{getLabel(519146, "核算账套")}</span></Col>
|
||||
<Col span={18}><span className="value">{formDTO && formDTO.salarySobName}</span></Col>
|
||||
</Row>
|
||||
</Col>
|
||||
<Col span={24}>
|
||||
<Row>
|
||||
<Col span={3}><span className="label">{getLabel(536726, "备注")}</span></Col>
|
||||
<Col span={21}><span className="value">{formDTO && formDTO.description}</span></Col>
|
||||
</Row>
|
||||
</Col>
|
||||
</Row>
|
||||
</WeaSearchGroup>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default BaseInfo;
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
export const personConfirmSearchConditions = [
|
||||
{
|
||||
items: [
|
||||
{
|
||||
colSpan: 2,
|
||||
conditionType: "INPUT",
|
||||
domkey: ["employeeName"],
|
||||
fieldcol: 12,
|
||||
label: "姓名",
|
||||
lanId: 25034,
|
||||
labelcol: 6,
|
||||
value: "",
|
||||
viewAttr: 2
|
||||
},
|
||||
{
|
||||
colSpan: 2,
|
||||
conditionType: "INPUT",
|
||||
domkey: ["workcode"],
|
||||
fieldcol: 12,
|
||||
label: "工号",
|
||||
lanId: 1933,
|
||||
labelcol: 6,
|
||||
value: "",
|
||||
viewAttr: 2
|
||||
},
|
||||
{
|
||||
browserConditionParam: {
|
||||
completeParams: {},
|
||||
conditionDataParams: {},
|
||||
dataParams: {},
|
||||
destDataParams: {},
|
||||
hasAddBtn: false,
|
||||
hasAdvanceSerach: false,
|
||||
idSeparator: ",",
|
||||
isAutoComplete: 1,
|
||||
isDetail: 0,
|
||||
isMultCheckbox: false,
|
||||
isSingle: false,
|
||||
icon: "icon-coms-hrm",
|
||||
linkUrl: "",
|
||||
pageSize: 10,
|
||||
quickSearchName: "",
|
||||
replaceDatas: [],
|
||||
title: "",
|
||||
type: "57",
|
||||
viewAttr: 2
|
||||
},
|
||||
colSpan: 2,
|
||||
conditionType: "BROWSER",
|
||||
domkey: ["departmentIds"],
|
||||
fieldcol: 12,
|
||||
label: "部门",
|
||||
lanId: 27511,
|
||||
labelcol: 6,
|
||||
viewAttr: 2
|
||||
},
|
||||
{
|
||||
browserConditionParam: {
|
||||
completeParams: {},
|
||||
conditionDataParams: {},
|
||||
dataParams: {},
|
||||
destDataParams: {},
|
||||
hasAddBtn: false,
|
||||
hasAdvanceSerach: false,
|
||||
idSeparator: ",",
|
||||
isAutoComplete: 1,
|
||||
isDetail: 0,
|
||||
isMultCheckbox: false,
|
||||
isSingle: false,
|
||||
icon: "icon-coms-hrm",
|
||||
linkUrl: "",
|
||||
pageSize: 10,
|
||||
quickSearchName: "",
|
||||
replaceDatas: [],
|
||||
title: "",
|
||||
type: "24",
|
||||
viewAttr: 2
|
||||
},
|
||||
colSpan: 2,
|
||||
conditionType: "BROWSER",
|
||||
domkey: ["positionIds"],
|
||||
fieldcol: 12,
|
||||
label: "岗位",
|
||||
lanId: 6086,
|
||||
labelcol: 6,
|
||||
viewAttr: 2
|
||||
},
|
||||
{
|
||||
colSpan: 2,
|
||||
conditionType: "SELECT",
|
||||
domkey: ["statuses"],
|
||||
fieldcol: 12,
|
||||
multiple: true,
|
||||
label: "状态",
|
||||
lanId: 535101,
|
||||
labelcol: 6,
|
||||
options: [],
|
||||
viewAttr: 2
|
||||
}
|
||||
],
|
||||
defaultshow: true,
|
||||
title: "常用条件"
|
||||
}
|
||||
];
|
||||
|
|
@ -0,0 +1,287 @@
|
|||
/*
|
||||
* Author: 黎永顺
|
||||
* name: 人员确认
|
||||
* Description:
|
||||
* Date: 2023/9/13
|
||||
*/
|
||||
import React, { Component } from "react";
|
||||
import { WeaBrowser, WeaButtonIcon, WeaHelpfulTip, WeaLocaleProvider, WeaTab, WeaTable, WeaTools } from "ecCom";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import { Button, message, Modal } from "antd";
|
||||
import BaseInfo from "./baseInfo";
|
||||
import {
|
||||
acctemployeeList,
|
||||
addedemployeeList,
|
||||
deleteAcctemployee,
|
||||
reducedemployeeList,
|
||||
saveAcctemployee
|
||||
} from "../../../../../apis/calculate";
|
||||
import { personConfirmSearchConditions } from "./condition";
|
||||
import { getSearchs } from "../../../../../util";
|
||||
import { convertToUrlString } from "../../../../../util/url";
|
||||
|
||||
const getKey = WeaTools.getKey;
|
||||
const getLabel = WeaLocaleProvider.getLabel;
|
||||
const api = {
|
||||
range: acctemployeeList,
|
||||
sub: reducedemployeeList,
|
||||
add: addedemployeeList
|
||||
};
|
||||
|
||||
@inject("calculateStore")
|
||||
@observer
|
||||
class Index extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
selectedKey: "range", showSearchAd: false,
|
||||
searchConditions: [], loading: false,
|
||||
pageInfo: { current: 1, pageSize: 10, total: 0 },
|
||||
selectedRowKeys: [], dataSource: [], columns: []
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
if ($) {
|
||||
const domTabInnerList = $(".salary-calculate-do-calc-content .ant-tabs-tab-inner");
|
||||
domTabInnerList[0].setAttribute("title", "");
|
||||
domTabInnerList[1].setAttribute("title", "");
|
||||
domTabInnerList[2].setAttribute("title", "");
|
||||
}
|
||||
this.setState({
|
||||
searchConditions: _.map(personConfirmSearchConditions, item => {
|
||||
return {
|
||||
...item,
|
||||
items: _.map(item.items, o => {
|
||||
if (getKey(o) === "statuses") {
|
||||
return {
|
||||
...o,
|
||||
options: [
|
||||
{ key: "0", showname: getLabel(18883, "试用") }, { key: "1", showname: getLabel(15711, "正式") },
|
||||
{ key: "2", showname: getLabel(480, "临时") }, { key: "3", showname: getLabel(15844, "试用延期") },
|
||||
{ key: "4", showname: getLabel(542707, "解雇") }, { key: "5", showname: getLabel(6091, "离职") },
|
||||
{ key: "6", showname: getLabel(6092, "退休") }
|
||||
]
|
||||
};
|
||||
}
|
||||
return { ...o };
|
||||
}),
|
||||
title: getLabel(32905, "常用条件")
|
||||
};
|
||||
})
|
||||
}, () => {
|
||||
const { calculateStore: { PCSearchForm } } = this.props;
|
||||
PCSearchForm.initFormFields(this.state.searchConditions);
|
||||
this.queryPCList();
|
||||
});
|
||||
}
|
||||
|
||||
renderTabBtns = () => {
|
||||
const { selectedKey, selectedRowKeys } = this.state;
|
||||
let tabBtns = [];
|
||||
switch (selectedKey) {
|
||||
case "range":
|
||||
tabBtns = [
|
||||
<WeaButtonIcon buttonType="del" type="primary" title={getLabel(111, "批量删除")}
|
||||
disabled={_.isEmpty(selectedRowKeys)}
|
||||
onClick={() => this.handleDeletePCitem()}/>,
|
||||
<WeaBrowser type={17} title={getLabel(383694, "添加人员")} isSingle={false} customized
|
||||
onChange={ids => ids && this.handleUserBrowserChange(ids.split(","))}
|
||||
>
|
||||
<WeaButtonIcon buttonType="add" type="primary" title={getLabel(1421, "新增")}/>
|
||||
</WeaBrowser>,
|
||||
<Button type="primary" onClick={this.handleExport}>{getLabel(17416, "导出")}</Button>
|
||||
];
|
||||
break;
|
||||
case "add":
|
||||
case "sub":
|
||||
tabBtns = [
|
||||
<Button type="primary" onClick={this.handleExport}>{getLabel(17416, "导出")}</Button>
|
||||
];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return tabBtns;
|
||||
};
|
||||
queryPCList = () => {
|
||||
const { pageInfo, selectedKey } = this.state;
|
||||
const { calculateStore: { PCSearchForm }, routeParams: { salaryAcctRecordId } } = this.props;
|
||||
const { departmentIds, positionIds, statuses, ...extra } = PCSearchForm.getFormParams();
|
||||
const payload = {
|
||||
salaryAcctRecordId, ...pageInfo, ...extra,
|
||||
departmentIds: !_.isEmpty(departmentIds) ? departmentIds.split(",") : [],
|
||||
positionIds: !_.isEmpty(positionIds) ? positionIds.split(",") : [],
|
||||
statuses: !_.isEmpty(statuses) ? statuses.split(",") : []
|
||||
};
|
||||
this.setState({ loading: true });
|
||||
api[selectedKey](payload).then(({ status, data }) => {
|
||||
this.setState({ loading: false });
|
||||
if (status) {
|
||||
const { columns, list: dataSource = [], pageNum: current, pageSize, total } = data;
|
||||
this.setState({
|
||||
columns, dataSource, pageInfo: { ...pageInfo, current, pageSize, total }
|
||||
});
|
||||
}
|
||||
}).catch(() => this.setState({ loading: false }));
|
||||
};
|
||||
handleDeletePCitem = (ids) => {
|
||||
Modal.confirm({
|
||||
title: getLabel(131329, "信息确认"),
|
||||
content: getLabel(388758, "确认要删除吗?"),
|
||||
onOk: () => {
|
||||
const { selectedRowKeys } = this.state;
|
||||
const { routeParams: { salaryAcctRecordId } } = this.props;
|
||||
deleteAcctemployee({ salaryAcctRecordId, ids: !_.isEmpty(ids) ? ids : selectedRowKeys })
|
||||
.then(({ status, errormsg }) => {
|
||||
if (status) {
|
||||
message.success(getLabel(502230, "删除成功!"));
|
||||
this.queryPCList();
|
||||
_.isNil(ids) && this.setState({ selectedRowKeys: [] });
|
||||
} else {
|
||||
message.error(errormsg || getLabel(20462, "删除失败!"));
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
/*
|
||||
* Author: 黎永顺
|
||||
* Description: 人员确认导出
|
||||
* Params:
|
||||
* Date: 2023/9/14
|
||||
*/
|
||||
handleExport = () => {
|
||||
let url = "";
|
||||
const { routeParams: { salaryAcctRecordId }, calculateStore: { PCSearchForm } } = this.props;
|
||||
if (this.state.selectedKey === "range") {
|
||||
url = `${window.location.origin}/api/bs/hrmsalary/salaryacct/acctemployee/export?salaryAcctRecordId=${salaryAcctRecordId}&${convertToUrlString(PCSearchForm.getFormParams())}`;
|
||||
} else if (this.state.selectedKey === "sub") {
|
||||
url = `${window.location.origin}/api/bs/hrmsalary/salaryacct/reducedemployee/export?salaryAcctRecordId=${salaryAcctRecordId}&${convertToUrlString(PCSearchForm.getFormParams())}`;
|
||||
} else {
|
||||
url = `${window.location.origin}/api/bs/hrmsalary/salaryacct/addedemployee/export?salaryAcctRecordId=${salaryAcctRecordId}&${convertToUrlString(PCSearchForm.getFormParams())}`;
|
||||
}
|
||||
window.open(url, "_blank");
|
||||
};
|
||||
/*
|
||||
* Author: 黎永顺
|
||||
* Description: 添加人员确认
|
||||
* Params:
|
||||
* Date: 2023/9/14
|
||||
*/
|
||||
handleUserBrowserChange = (employeeIds) => {
|
||||
const { routeParams: { salaryAcctRecordId } } = this.props;
|
||||
saveAcctemployee({ salaryAcctRecordId, employeeIds }).then(({ status, errormsg }) => {
|
||||
if (status) {
|
||||
message.success(getLabel(541531, "添加成功!"));
|
||||
this.queryPCList();
|
||||
} else {
|
||||
message.error(errormsg || getLabel(111, "添加失败!"));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
const { calculateStore: { PCSearchForm } } = this.props;
|
||||
const {
|
||||
selectedKey, showSearchAd, searchConditions, pageInfo, loading, selectedRowKeys,
|
||||
columns, dataSource
|
||||
} = this.state;
|
||||
const tabDatas = [
|
||||
{
|
||||
title: <React.Fragment>
|
||||
<span>{getLabel(542307, "核算人员范围")}</span>
|
||||
<WeaHelpfulTip
|
||||
width={200} placement="topLeft"
|
||||
title={getLabel(543551, "核算完若薪资档案中个税扣缴义务人发生调整,需先刷新【核算人员范围】再到【薪资核算】中重新核算")}
|
||||
style={{ marginLeft: 8 }}
|
||||
/>
|
||||
</React.Fragment>, viewcondition: "range"
|
||||
},
|
||||
{
|
||||
title: <React.Fragment>
|
||||
<span>{getLabel(542308, "环比上月减少人员")}</span>
|
||||
<WeaHelpfulTip
|
||||
width={200} placement="topLeft"
|
||||
title={getLabel(543552, "提示:环比上期当前选择的账套归档的各个税扣缴义务人下减少的人员")}
|
||||
style={{ marginLeft: 8 }}
|
||||
/>
|
||||
</React.Fragment>, viewcondition: "sub"
|
||||
},
|
||||
{
|
||||
title: <React.Fragment>
|
||||
<span>{getLabel(542308, "环比上月增加人员")}</span>
|
||||
<WeaHelpfulTip
|
||||
width={200} placement="topLeft"
|
||||
title={getLabel(543553, "提示:环比上期当前选择的账套归档的各个税扣缴义务人下增加的人员")}
|
||||
style={{ marginLeft: 8 }}
|
||||
/>
|
||||
</React.Fragment>, viewcondition: "add"
|
||||
}
|
||||
];
|
||||
const pagination = {
|
||||
...pageInfo,
|
||||
showTotal: total => `${getLabel(18609, "共")} ${total} ${getLabel(18256, "条")}`,
|
||||
showQuickJumper: true,
|
||||
showSizeChanger: true,
|
||||
pageSizeOptions: ["10", "20", "50", "100"],
|
||||
onShowSizeChange: (current, pageSize) => {
|
||||
this.setState({ pageInfo: { ...pageInfo, current, pageSize } }, () => this.queryPCList());
|
||||
},
|
||||
onChange: current => {
|
||||
this.setState({ pageInfo: { ...pageInfo, current } }, () => this.queryPCList());
|
||||
}
|
||||
};
|
||||
const rowSelection = {
|
||||
columnWidth: 80,
|
||||
selectedRowKeys,
|
||||
onChange: selectedRowKeys => this.setState({ selectedRowKeys })
|
||||
};
|
||||
return (
|
||||
<div className="person-confirm-layout">
|
||||
<BaseInfo {...this.props}/>
|
||||
<WeaTab
|
||||
datas={tabDatas} keyParam="viewcondition" selectedKey={selectedKey}
|
||||
onChange={v => this.setState({ selectedKey: v }, () => this.queryPCList())}
|
||||
buttons={this.renderTabBtns()} searchType={["base", "advanced"]} advanceHeight={220}
|
||||
showSearchAd={showSearchAd} setShowSearchAd={bool => this.setState({ showSearchAd: bool })}
|
||||
searchsAd={getSearchs(PCSearchForm, searchConditions, 2, false)}
|
||||
onSearchChange={(v) => PCSearchForm.updateFields({ employeeName: v })}
|
||||
searchsBaseValue={PCSearchForm.getFormParams().employeeName}
|
||||
onSearch={this.queryPCList} onAdSearch={this.queryPCList}
|
||||
onAdReset={() => PCSearchForm.resetForm()} autoCalculateWidth
|
||||
/>
|
||||
<WeaTable
|
||||
dataSource={dataSource} loading={loading} rowSelection={rowSelection} pagination={pagination}
|
||||
scroll={{ y: `calc(100vh - 365px)` }} rowKey="id"
|
||||
columns={[..._.map(columns, item => {
|
||||
let width = "";
|
||||
const { dataIndex } = item;
|
||||
switch (dataIndex) {
|
||||
case "taxAgentName":
|
||||
case "departmentName":
|
||||
width = "15%";
|
||||
break;
|
||||
default:
|
||||
width = "10%";
|
||||
break;
|
||||
}
|
||||
return { ...item, width };
|
||||
}),
|
||||
{
|
||||
dataIndex: "operate",
|
||||
title: getLabel(30585, "操作"),
|
||||
width: 120,
|
||||
render: (_, record) => (
|
||||
<a href="javascript:void(0);"
|
||||
onClick={() => this.handleDeletePCitem([record.id])}>{getLabel(535052, "删除")}</a>
|
||||
)
|
||||
}
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default Index;
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
.person-confirm-layout {
|
||||
.wea-tab .wea-tab-right, .wea-input-focus {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.wea-new-table {
|
||||
background: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
.docalc-baseinfo-layout {
|
||||
padding: 0;
|
||||
|
||||
.wea-title {
|
||||
border-bottom: none;
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.wea-content.pt15 {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.docalc-baseinfo {
|
||||
background: #fff;
|
||||
border: 1px solid #e5e5e5;
|
||||
border-right: none;
|
||||
|
||||
.ant-col-24 {
|
||||
border-top: 1px solid #e5e5e5;
|
||||
}
|
||||
|
||||
.label {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.value {
|
||||
color: #111;
|
||||
}
|
||||
|
||||
& > div {
|
||||
border-right: 1px solid #e5e5e5;
|
||||
line-height: 30px;
|
||||
padding: 5px 16px;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Author: 黎永顺
|
||||
* name: 薪资基本信息
|
||||
* Description:
|
||||
* Date: 2023/9/25
|
||||
*/
|
||||
import React, { Component } from "react";
|
||||
import { WeaHelpfulTip, WeaLocaleProvider, WeaSearchGroup } from "ecCom";
|
||||
import cs from "classnames";
|
||||
import { Col, Row } from "antd";
|
||||
import "./index.less";
|
||||
|
||||
const getLabel = WeaLocaleProvider.getLabel;
|
||||
|
||||
class EditSalaryBaseInfo extends Component {
|
||||
render() {
|
||||
const { baseInfo } = this.props;
|
||||
return (
|
||||
<WeaSearchGroup
|
||||
needTigger showGroup className="esf-base-info-form"
|
||||
title={
|
||||
<div>
|
||||
<span>{getLabel(82743, "基础信息")}</span>
|
||||
<WeaHelpfulTip
|
||||
width={200} placement="topLeft"
|
||||
title={getLabel(111, "提示:基本信息根据账套设置显示")}
|
||||
style={{ marginLeft: 10 }}
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<Row type="flex" className="esf-form-content">
|
||||
{
|
||||
_.map(baseInfo, (item, index) => {
|
||||
const { fieldName, fieldValue } = item;
|
||||
return (
|
||||
<Col span={(index === baseInfo.length - 1 && (index + 1) % 2 === 1) ? 24 : 12}>
|
||||
<Row className={cs("esf-form-item", {
|
||||
"esf-form-odd-item": index % 2 === 0,
|
||||
"esf-form-last-item": (index === baseInfo.length - 1 && (index + 1) % 2 === 1)
|
||||
})}>
|
||||
<Col span={(index === baseInfo.length - 1 && (index + 1) % 2 === 1) ? 3 : 6}>
|
||||
<span className="label">{fieldName}</span>
|
||||
</Col>
|
||||
<Col span={(index === baseInfo.length - 1 && (index + 1) % 2 === 1) ? 21 : 18}>
|
||||
<span className="value">{fieldValue}</span>
|
||||
</Col>
|
||||
</Row>
|
||||
</Col>
|
||||
);
|
||||
})
|
||||
}
|
||||
</Row>
|
||||
</WeaSearchGroup>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default EditSalaryBaseInfo;
|
||||
|
|
@ -0,0 +1,145 @@
|
|||
export const editCalcSearchConditions = [
|
||||
{
|
||||
items: [
|
||||
{
|
||||
colSpan: 2,
|
||||
conditionType: "INPUT",
|
||||
domkey: ["employeeName"],
|
||||
fieldcol: 12,
|
||||
label: "姓名",
|
||||
lanId: 25034,
|
||||
labelcol: 6,
|
||||
value: "",
|
||||
viewAttr: 2
|
||||
},
|
||||
{
|
||||
colSpan: 2,
|
||||
conditionType: "INPUT",
|
||||
domkey: ["workcode"],
|
||||
fieldcol: 12,
|
||||
label: "工号",
|
||||
lanId: 1933,
|
||||
labelcol: 6,
|
||||
value: "",
|
||||
viewAttr: 2
|
||||
},
|
||||
{
|
||||
browserConditionParam: {
|
||||
completeParams: {},
|
||||
conditionDataParams: {},
|
||||
dataParams: {},
|
||||
destDataParams: {},
|
||||
hasAddBtn: false,
|
||||
hasAdvanceSerach: false,
|
||||
idSeparator: ",",
|
||||
isAutoComplete: 1,
|
||||
isDetail: 0,
|
||||
isMultCheckbox: false,
|
||||
isSingle: false,
|
||||
icon: "icon-coms-hrm",
|
||||
linkUrl: "",
|
||||
pageSize: 10,
|
||||
quickSearchName: "",
|
||||
replaceDatas: [],
|
||||
title: "",
|
||||
type: "164",
|
||||
viewAttr: 2
|
||||
},
|
||||
colSpan: 1,
|
||||
conditionType: "BROWSER",
|
||||
domkey: ["subcompanyIds"],
|
||||
fieldcol: 12,
|
||||
label: "分部",
|
||||
lanId: 33553,
|
||||
labelcol: 6,
|
||||
viewAttr: 2
|
||||
},
|
||||
{
|
||||
browserConditionParam: {
|
||||
completeParams: {},
|
||||
conditionDataParams: {},
|
||||
dataParams: {},
|
||||
destDataParams: {},
|
||||
hasAddBtn: false,
|
||||
hasAdvanceSerach: false,
|
||||
idSeparator: ",",
|
||||
isAutoComplete: 1,
|
||||
isDetail: 0,
|
||||
isMultCheckbox: false,
|
||||
isSingle: false,
|
||||
icon: "icon-coms-hrm",
|
||||
linkUrl: "",
|
||||
pageSize: 10,
|
||||
quickSearchName: "",
|
||||
replaceDatas: [],
|
||||
title: "",
|
||||
type: "57",
|
||||
viewAttr: 2
|
||||
},
|
||||
colSpan: 2,
|
||||
conditionType: "BROWSER",
|
||||
domkey: ["departmentIds"],
|
||||
fieldcol: 12,
|
||||
label: "部门",
|
||||
lanId: 27511,
|
||||
labelcol: 6,
|
||||
viewAttr: 2
|
||||
},
|
||||
{
|
||||
browserConditionParam: {
|
||||
completeParams: {},
|
||||
conditionDataParams: {},
|
||||
dataParams: {},
|
||||
destDataParams: {},
|
||||
hasAddBtn: false,
|
||||
hasAdvanceSerach: false,
|
||||
idSeparator: ",",
|
||||
isAutoComplete: 1,
|
||||
isDetail: 0,
|
||||
isMultCheckbox: false,
|
||||
isSingle: false,
|
||||
icon: "icon-coms-hrm",
|
||||
linkUrl: "",
|
||||
pageSize: 10,
|
||||
quickSearchName: "",
|
||||
replaceDatas: [],
|
||||
title: "",
|
||||
type: "24",
|
||||
viewAttr: 2
|
||||
},
|
||||
colSpan: 2,
|
||||
conditionType: "BROWSER",
|
||||
domkey: ["positionIds"],
|
||||
fieldcol: 12,
|
||||
label: "岗位",
|
||||
lanId: 6086,
|
||||
labelcol: 6,
|
||||
viewAttr: 2
|
||||
},
|
||||
{
|
||||
colSpan: 2,
|
||||
conditionType: "SELECT",
|
||||
domkey: ["statuses"],
|
||||
fieldcol: 12,
|
||||
multiple: true,
|
||||
label: "状态",
|
||||
lanId: 535101,
|
||||
labelcol: 6,
|
||||
options: [],
|
||||
viewAttr: 2
|
||||
},
|
||||
{
|
||||
colSpan: 2,
|
||||
conditionType: "CHECKBOX",
|
||||
domkey: ["consolidatedTaxation"],
|
||||
fieldcol: 12,
|
||||
isQuickSearch: false,
|
||||
label: "合并计税",
|
||||
labelcol: 6,
|
||||
viewAttr: 2
|
||||
}
|
||||
],
|
||||
defaultshow: true,
|
||||
title: "常用条件"
|
||||
}
|
||||
];
|
||||
|
|
@ -0,0 +1,206 @@
|
|||
/*
|
||||
* Author: 黎永顺
|
||||
* name: 薪资核算-高级搜索面板
|
||||
* Description:
|
||||
* Date: 2023/9/14
|
||||
*/
|
||||
import React, { Component } from "react";
|
||||
import { WeaFormItem, WeaInput, WeaLocaleProvider, WeaSearchGroup, WeaSelect, WeaTools } from "ecCom";
|
||||
import { Button, Col, Row } from "antd";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import uuidV4 from "uuid/v4";
|
||||
import { editCalcSearchConditions } from "./condition";
|
||||
import { getExportField } from "../../../../../apis/calculate";
|
||||
import { commonEnumList } from "../../../../../apis/ruleconfig";
|
||||
import { getSearchs } from "../../../../../util";
|
||||
|
||||
const getKey = WeaTools.getKey;
|
||||
const getLabel = WeaLocaleProvider.getLabel;
|
||||
|
||||
@inject("calculateStore")
|
||||
@observer
|
||||
class EditCalcAdvanceSearchPannel extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
searchConditions: [], salaryItems: [],
|
||||
customSearchConditions: [], filterEnum: []
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.getExportField();
|
||||
this.getFilterEnumList();
|
||||
this.setState({
|
||||
searchConditions: _.map(editCalcSearchConditions, item => {
|
||||
return {
|
||||
...item,
|
||||
items: _.map(item.items, o => {
|
||||
if (getKey(o) === "statuses") {
|
||||
return {
|
||||
...o,
|
||||
options: [
|
||||
{ key: "0", showname: getLabel(18883, "试用") }, { key: "1", showname: getLabel(15711, "正式") },
|
||||
{ key: "2", showname: getLabel(480, "临时") }, { key: "3", showname: getLabel(15844, "试用延期") },
|
||||
{ key: "4", showname: getLabel(542707, "解雇") }, { key: "5", showname: getLabel(6091, "离职") },
|
||||
{ key: "6", showname: getLabel(6092, "退休") }
|
||||
]
|
||||
};
|
||||
}
|
||||
return { ...o };
|
||||
}),
|
||||
title: getLabel(32905, "常用条件")
|
||||
};
|
||||
})
|
||||
}, () => {
|
||||
const { calculateStore: { ECSearchForm } } = this.props;
|
||||
ECSearchForm.initFormFields(this.state.searchConditions);
|
||||
});
|
||||
}
|
||||
|
||||
getFilterEnumList = () => {
|
||||
commonEnumList({ enumClass: "com.engine.salary.enums.common.FilterEnum" })
|
||||
.then(({ status, data }) => {
|
||||
if (status) {
|
||||
this.setState({
|
||||
filterEnum: _.map(data, item => ({
|
||||
key: item.value,
|
||||
showname: item.defaultLabel
|
||||
}))
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
getExportField = () => {
|
||||
getExportField({ salaryAcctRecordId: this.props.salaryAcctRecordId })
|
||||
.then(({ status, data }) => {
|
||||
if (status) {
|
||||
const { itemsByGroup } = data;
|
||||
this.setState({
|
||||
salaryItems: _.map(itemsByGroup, item => ({
|
||||
key: item.salarySobItemGroupId.toString(),
|
||||
label: item.salarySobItemGroupName,
|
||||
options: _.map(item.salaryItems, o => ({
|
||||
key: o.salaryItemId.toString(), showname: o.salaryItemName
|
||||
}))
|
||||
}))
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
handleAddCustomSearchForm = () => {
|
||||
const { calculateStore: { setOtherConditions } } = this.props;
|
||||
const { customSearchConditions, salaryItems, filterEnum } = this.state;
|
||||
const uuid = uuidV4();
|
||||
this.setState({
|
||||
customSearchConditions: [
|
||||
...customSearchConditions,
|
||||
{
|
||||
com: CustomFormFields({
|
||||
uuid, salaryItems, filterEnum, onDelete: this.handleDelete, onChange: this.handleChange
|
||||
}),
|
||||
uuid, itemId: "", filter: "", params: ""
|
||||
}
|
||||
]
|
||||
}, () => {
|
||||
setOtherConditions(_.map(this.state.customSearchConditions, o => ({
|
||||
itemId: o.itemId, filter: o.filter, params: o.params
|
||||
})));
|
||||
});
|
||||
};
|
||||
handleChange = (uuid, params) => {
|
||||
const { calculateStore: { setOtherConditions } } = this.props;
|
||||
const { customSearchConditions } = this.state;
|
||||
this.setState({
|
||||
customSearchConditions: _.map(customSearchConditions, o => {
|
||||
if (o.uuid === uuid) {
|
||||
return { ...o, ...params };
|
||||
}
|
||||
return { ...o };
|
||||
})
|
||||
}, () => {
|
||||
setOtherConditions(_.map(this.state.customSearchConditions, o => ({
|
||||
itemId: o.itemId, filter: o.filter, params: o.params
|
||||
})));
|
||||
});
|
||||
};
|
||||
handleDelete = (uuid) => {
|
||||
const { calculateStore: { setOtherConditions } } = this.props;
|
||||
const { customSearchConditions } = this.state;
|
||||
this.setState({
|
||||
customSearchConditions: _.filter(customSearchConditions, o => o.uuid !== uuid)
|
||||
}, () => {
|
||||
setOtherConditions(_.map(this.state.customSearchConditions, o => ({
|
||||
itemId: o.itemId, filter: o.filter, params: o.params
|
||||
})));
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
const { searchConditions, customSearchConditions } = this.state;
|
||||
const { calculateStore: { ECSearchForm, setOtherConditions } } = this.props;
|
||||
return (
|
||||
<React.Fragment>
|
||||
<div className="wea-advanced-searchsAd">
|
||||
{getSearchs(ECSearchForm, searchConditions, 2, false)}
|
||||
<WeaSearchGroup needTigger showGroup title={getLabel(32843, "其他条件")} items={customSearchConditions}
|
||||
col={2}/>
|
||||
<div className="custom-advance-largeSpacing">
|
||||
<Button className="link" icon="plus"
|
||||
onClick={this.handleAddCustomSearchForm}>{getLabel(111, "添加搜索条件")}</Button>
|
||||
</div>
|
||||
<div className="searchAdvanced-commonSelect">
|
||||
{/*<Button type="ghost">{getLabel(111, "保存常用筛选")}</Button>*/}
|
||||
</div>
|
||||
</div>
|
||||
<div className="wea-search-buttons">
|
||||
<div style={{ textAlign: "center" }}>
|
||||
<span style={{ marginLeft: 15 }}><Button type="primary"
|
||||
onClick={this.props.onAdSearch}>{getLabel(388113, "搜索")}</Button></span>
|
||||
<span style={{ marginLeft: 15 }}><Button type="ghost"
|
||||
onClick={() => {
|
||||
this.setState({
|
||||
customSearchConditions: []
|
||||
}, () => {
|
||||
ECSearchForm.resetForm();
|
||||
setOtherConditions([]);
|
||||
});
|
||||
}}>{getLabel(2022, "重置")}</Button></span>
|
||||
<span style={{ marginLeft: 15 }}><Button type="ghost"
|
||||
onClick={this.props.onToggleSwitch}>{getLabel(31129, "取消")}</Button></span>
|
||||
</div>
|
||||
</div>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default EditCalcAdvanceSearchPannel;
|
||||
|
||||
const CustomFormFields = (props) => {
|
||||
const { uuid, onDelete, salaryItems, filterEnum, onChange } = props;
|
||||
return <WeaFormItem labelCol={{ span: 0 }} wrapperCol={{ span: 18 }}>
|
||||
<Row>
|
||||
<Col span={6} style={{ paddingRight: 10 }}>
|
||||
<WeaSelect
|
||||
options={salaryItems} detailtype={5} showSearch optionFilterProp="children"
|
||||
onChange={v => onChange(uuid, { itemId: v })}
|
||||
/>
|
||||
</Col>
|
||||
<Col span={18}>
|
||||
<Row>
|
||||
<Col span={12} style={{ paddingRight: 10 }}>
|
||||
<WeaSelect options={filterEnum} onChange={v => onChange(uuid, { filter: v })}/>
|
||||
</Col>
|
||||
<Col span={12} style={{ position: "relative" }}>
|
||||
<WeaInput onChange={v => onChange(uuid, { params: v })}/>
|
||||
<Button
|
||||
type="ghost" icon="cross" className="formItem-delete" shape="circle"
|
||||
onClick={() => onDelete(uuid)}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
</Col>
|
||||
</Row>
|
||||
</WeaFormItem>;
|
||||
};
|
||||
|
|
@ -0,0 +1,213 @@
|
|||
/*
|
||||
* Author: 黎永顺
|
||||
* name: 薪资核算-列表数据
|
||||
* Description:
|
||||
* Date: 2023/9/14
|
||||
*/
|
||||
import React, { Component } from "react";
|
||||
import { WeaLocaleProvider } from "ecCom";
|
||||
import { message, Modal, Spin } from "antd";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import { acctResultList, updateLockStatus } from "../../../../../apis/calculate";
|
||||
import ProgressModal from "../../../../../components/progressModal";
|
||||
import EditSalaryCalcSlide from "./editSalaryCalcSlide";
|
||||
|
||||
const getLabel = WeaLocaleProvider.getLabel;
|
||||
|
||||
@inject("calculateStore")
|
||||
@observer
|
||||
class EditCalcTable extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
loading: false, pageInfo: { current: 1, pageSize: 10, total: 0 },
|
||||
selectedRowKeys: [], progressVisible: false, progress: 0,
|
||||
salaryCalcSlide: { visible: false, id: "" }
|
||||
};
|
||||
this.timerLock = null;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
window.addEventListener("message", this.handleReceive, false);
|
||||
}
|
||||
|
||||
handleReceive = async ({ data }) => {
|
||||
const { type, payload: { id, params } = {} } = data;
|
||||
if (type === "init") {
|
||||
this.queryCalcResultList();
|
||||
} else if (type === "turn") {
|
||||
switch (id) {
|
||||
case "PAGEINFO":
|
||||
const { size: pageSize, pageNum: current } = params;
|
||||
this.setState({ pageInfo: { ...this.state.pageInfo, current, pageSize } }, () => this.queryCalcResultList());
|
||||
break;
|
||||
case "CHECKBOX":
|
||||
const { selectedRowKeys } = params;
|
||||
this.setState({ selectedRowKeys });
|
||||
break;
|
||||
case "FORMULA":
|
||||
const { dataIndex } = params;
|
||||
this.props.onShowFormulaTd(dataIndex);
|
||||
break;
|
||||
case "LOCKING":
|
||||
const { salaryItemId, lockType: lockStatus } = params;
|
||||
this.updateLockStatus({ lockStatus, salaryItemId });
|
||||
break;
|
||||
case "EDIT":
|
||||
const { id: salaryCalcId } = params;
|
||||
this.setState({
|
||||
salaryCalcSlide: { visible: true, id: salaryCalcId }
|
||||
});
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
updateLockStatus = (payload) => {
|
||||
const { lockStatus } = payload;
|
||||
Modal.confirm({
|
||||
title: getLabel(131329, "信息确认"),
|
||||
content: <div>
|
||||
<div style={{ textAlign: "center" }}>
|
||||
{lockStatus === "LOCK" ? getLabel(543554, "确定要批量锁定项目值吗?") : getLabel(543556, "确定要批量解锁项目值吗?")}
|
||||
</div>
|
||||
<div style={{ textAlign: "center" }}>
|
||||
{lockStatus === "LOCK" ? getLabel(543555, "确定后,则项目输入值锁定,项目公式失效;点击核算将按锁定的输入值重新核算!") :
|
||||
getLabel(543557, "确定后,则项目公式生效,页面仍显示手动修改的项目值;点击核算将按公式重新核算,不再显示解锁标识!")}
|
||||
</div>
|
||||
</div>,
|
||||
onOk: () => {
|
||||
this.setState({
|
||||
progressVisible: true
|
||||
}, () => {
|
||||
this.timerLock = setInterval(() => {
|
||||
if (this.state.progress !== 100) {
|
||||
this.setState({
|
||||
progress: this.state.progress + 1
|
||||
});
|
||||
} else {
|
||||
clearInterval(this.timerLock);
|
||||
this.setState({
|
||||
progressVisible: false,
|
||||
progress: 0
|
||||
});
|
||||
}
|
||||
}, 500);
|
||||
});
|
||||
const { routeParams: { salaryAcctRecordId } } = this.props;
|
||||
updateLockStatus({ ...payload, salaryAcctRecordId }).then(({ status, errormsg }) => {
|
||||
if (status) {
|
||||
clearInterval(this.timerLock);
|
||||
this.setState({
|
||||
progressVisible: false,
|
||||
progress: 0
|
||||
}, () => this.queryCalcResultList());
|
||||
} else {
|
||||
message.error(errormsg);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
componentWillUnmount() {
|
||||
window.removeEventListener("message", this.handleReceive, false);
|
||||
}
|
||||
|
||||
postMessageToChild = (payload = {}) => {
|
||||
const i18n = {
|
||||
"操作": getLabel(30585, "操作"), "编辑": getLabel(501169, "编辑"),
|
||||
"点击锁定所有解锁的项目值": getLabel(543649, "点击锁定所有解锁的项目值"),
|
||||
"点击解锁所有锁定的项目值": getLabel(543648, "点击解锁所有锁定的项目值"),
|
||||
"锁定的项目值": getLabel(543647, "锁定的项目值"),
|
||||
"当前状态锁定,点击解锁": getLabel(111, "当前状态锁定,点击解锁"),
|
||||
"当前状态未锁定,点击锁定": getLabel(111, "当前状态未锁定,点击锁定"),
|
||||
"共": getLabel(18609, "共"), "条": getLabel(18256, "条"),
|
||||
"总计": getLabel(523, "总计"), "批量解锁": getLabel(111, "批量解锁"),
|
||||
"批量锁定": getLabel(111, "批量锁定")
|
||||
};
|
||||
const childFrameObj = document.getElementById("atdTable");
|
||||
childFrameObj.contentWindow.postMessage(JSON.stringify({ ...payload, i18n }), "*");
|
||||
};
|
||||
queryCalcResultList = () => {
|
||||
const { pageInfo } = this.state;
|
||||
const { calculateStore: { ECSearchForm, otherConditions }, routeParams: { salaryAcctRecordId } } = this.props;
|
||||
const { subcompanyIds, departmentIds, positionIds, statuses, ...extra } = ECSearchForm.getFormParams();
|
||||
const payload = {
|
||||
salaryAcctRecordId, ...pageInfo, ...extra, otherConditions,
|
||||
departmentIds: !_.isEmpty(departmentIds) ? departmentIds.split(",") : [],
|
||||
positionIds: !_.isEmpty(positionIds) ? positionIds.split(",") : [],
|
||||
subcompanyIds: !_.isEmpty(subcompanyIds) ? subcompanyIds.split(",") : [],
|
||||
statuses: !_.isEmpty(statuses) ? statuses.split(",") : []
|
||||
};
|
||||
this.setState({ loading: true });
|
||||
acctResultList(payload).then(({ status, data }) => {
|
||||
this.setState({ loading: false });
|
||||
if (status) {
|
||||
const { columns, pageInfo: list } = data;
|
||||
const { list: dataSource, pageNum: current, pageSize, total } = list;
|
||||
this.setState({ pageInfo: { ...pageInfo, current, pageSize, total } }, () => {
|
||||
const { pageInfo, selectedRowKeys } = this.state;
|
||||
const sumRowlistUrl = this.props.showTotalCell ? "/api/bs/hrmsalary/salaryacct/acctresult/sum" : "";
|
||||
this.postMessageToChild({
|
||||
dataSource, pageInfo, selectedRowKeys, showTotalCell: this.props.showTotalCell, sumRowlistUrl, payload,
|
||||
columns: _.map(traverse(columns), (it, idx) => ({ ...it, fixed: idx < 2 ? "left" : false }))
|
||||
});
|
||||
});
|
||||
}
|
||||
}).catch(() => this.setState({ loading: false }));
|
||||
};
|
||||
|
||||
render() {
|
||||
const { loading, progressVisible, progress, salaryCalcSlide } = this.state;
|
||||
return (
|
||||
<div className="editCalcTable-layout">
|
||||
<Spin spinning={loading}>
|
||||
<iframe
|
||||
style={{ border: 0, width: "100%", height: "100%" }}
|
||||
// src="http://localhost:7607/#/calcTable"
|
||||
src="/spa/hrmSalary/hrmSalaryCalculateDetail/index.html#/calcTable"
|
||||
id="atdTable"
|
||||
/>
|
||||
<EditSalaryCalcSlide {...salaryCalcSlide}
|
||||
onClose={(isFresh) => this.setState({
|
||||
salaryCalcSlide: {
|
||||
visible: false,
|
||||
id: ""
|
||||
}
|
||||
}, () => isFresh === "true" && this.queryCalcResultList())}/>
|
||||
{
|
||||
progressVisible &&
|
||||
<ProgressModal
|
||||
title={getLabel(543558, "正在加锁/解锁请稍后")} visible={progressVisible} progress={progress}
|
||||
onCancel={() => {
|
||||
this.setState({ progressVisible: false, progress: 0 }, () => {
|
||||
clearInterval(this.timerLock);
|
||||
});
|
||||
}}
|
||||
/>
|
||||
}
|
||||
</Spin>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default EditCalcTable;
|
||||
|
||||
const traverse = (arr) => {
|
||||
return _.map(arr, item => {
|
||||
if (!_.isEmpty(item.children)) {
|
||||
return {
|
||||
title: item.text, width: item.width + "px", ellipsis: true,
|
||||
dataIndex: item.column, children: traverse(item.children)
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
title: item.text, width: item.width + "px",
|
||||
dataIndex: item.column, ellipsis: true, lockStatus: item.lockStatus
|
||||
};
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
@ -0,0 +1,160 @@
|
|||
/*
|
||||
* Author: 黎永顺
|
||||
* name: 编辑弹框
|
||||
* Description:
|
||||
* Date: 2023/9/25
|
||||
*/
|
||||
import React, { Component } from "react";
|
||||
import { Button, message } from "antd";
|
||||
import { WeaLocaleProvider, WeaSlideModal, WeaTab } from "ecCom";
|
||||
import EditSalaryBaseInfo from "./baseInfo";
|
||||
import PayrollItemsTable from "../../../../calculateDetail/payrollItemsTable";
|
||||
import IssuedAndReissueTable from "../../../../calculateDetail/issuedAndReissueTable";
|
||||
import { acctresultDetail, saveAcctResult } from "../../../../../apis/calculate";
|
||||
import { toDecimal_n } from "../../../../../util";
|
||||
import "./index.less";
|
||||
|
||||
|
||||
const getLabel = WeaLocaleProvider.getLabel;
|
||||
|
||||
class EditSalaryCalcSlide extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
baseInfo: [], selectedKey: "0", loading: false,
|
||||
issuedAndReissueItems: [], //已发补发薪资项目
|
||||
itemsByGroup: [] //正常发放薪资项目所得薪资项目
|
||||
};
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps, nextContext) {
|
||||
if (nextProps.visible !== this.props.visible && nextProps.visible) this.acctresultDetail(nextProps.id);
|
||||
if (nextProps.visible !== this.props.visible && !nextProps.visible) this.setState({ selectedKey: "0" });
|
||||
}
|
||||
|
||||
acctresultDetail = (id) => {
|
||||
acctresultDetail({ id }).then(({ status, data }) => {
|
||||
if (status) {
|
||||
const { employeeInfos, issuedAndReissueItems, itemsByGroup } = data;
|
||||
this.setState({
|
||||
baseInfo: employeeInfos, issuedAndReissueItems, itemsByGroup
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
renderTitle = () => {
|
||||
const { loading } = this.state;
|
||||
return <div className="titleDialog">
|
||||
<div className="titleCol titleLeftBox">
|
||||
<div className="titleIcon"><i className="icon-coms-fa"/></div>
|
||||
<div className="title">{getLabel(543559, "编辑薪资")}</div>
|
||||
</div>
|
||||
<div className="titleCol titleRightBox">
|
||||
<Button type="primary" onClick={this.save} loading={loading}>{getLabel(111, "保存并核算")}</Button>
|
||||
</div>
|
||||
</div>;
|
||||
};
|
||||
handleItemValueChange = (field, value, isInput, groupId) => {
|
||||
const { issuedAndReissueItems, itemsByGroup } = this.state;
|
||||
if (isInput === "itemsByGroup") {
|
||||
this.setState({
|
||||
itemsByGroup: itemsByGroup.map(item => {
|
||||
if (item.salarySobItemGroupId === groupId) {
|
||||
return {
|
||||
...item,
|
||||
salaryItems: _.map(item.salaryItems, it => {
|
||||
if (it.salaryItemId === field) {
|
||||
return { ...it, resultValue: value };
|
||||
}
|
||||
return { ...it };
|
||||
})
|
||||
};
|
||||
}
|
||||
return { ...item };
|
||||
})
|
||||
});
|
||||
} else if (isInput === "issuedAndReissueItems") {
|
||||
this.setState({
|
||||
issuedAndReissueItems: issuedAndReissueItems.map(item => {
|
||||
item = { ...item };
|
||||
if (item.salaryItemName === field) {
|
||||
item.resultValue = value;
|
||||
}
|
||||
return item;
|
||||
})
|
||||
});
|
||||
}
|
||||
};
|
||||
save = () => {
|
||||
const { id: salaryAcctEmpId } = this.props;
|
||||
const { issuedAndReissueItems, itemsByGroup } = this.state;
|
||||
const payload = {
|
||||
salaryAcctEmpId,
|
||||
items: [
|
||||
..._.reduce(itemsByGroup, (pre, cur) => {
|
||||
return [
|
||||
...pre,
|
||||
..._.map(cur.salaryItems, it => {
|
||||
return {
|
||||
salaryItemId: it.salaryItemId,
|
||||
resultValue: (it.dataType === "number" && !!it.resultValue) ? toDecimal_n(it.resultValue, it.pattern || 2) : it.resultValue
|
||||
};
|
||||
})
|
||||
];
|
||||
}, []),
|
||||
...issuedAndReissueItems.map(item => ({
|
||||
salaryItemId: item.salaryItemId,
|
||||
resultValue: (item.dataType === "number" && !!item.resultValue) ? toDecimal_n(item.resultValue, item.pattern || 2) : item.resultValue
|
||||
}))
|
||||
]
|
||||
};
|
||||
this.setState({ loading: true });
|
||||
saveAcctResult(payload).then(({ status, errormsg }) => {
|
||||
this.setState({ loading: false });
|
||||
if (status) {
|
||||
message.success(getLabel(30700, "操作成功!"));
|
||||
this.props.onClose("true");
|
||||
} else {
|
||||
message.error(errormsg);
|
||||
}
|
||||
}).catch(() => this.setState({ loading: false }));
|
||||
};
|
||||
|
||||
render() {
|
||||
const { baseInfo, selectedKey, itemsByGroup, issuedAndReissueItems } = this.state;
|
||||
const topTab = [
|
||||
{ title: getLabel(542704, "正常工资薪金所得"), viewcondition: "0" },
|
||||
{ title: getLabel(542651, "已发补发"), viewcondition: "1" }
|
||||
];
|
||||
return (
|
||||
<React.Fragment>
|
||||
<WeaSlideModal
|
||||
className="salary-calculate-esf-layout" {...this.props}
|
||||
top={0} width={60} height={100} measure={"%"}
|
||||
direction={"right"} title={this.renderTitle()}
|
||||
content={<div className="salary-calculate-esf-area">
|
||||
<EditSalaryBaseInfo baseInfo={baseInfo}/>
|
||||
<WeaTab keyParam="viewcondition" className="calc-esf-tab"
|
||||
selectedKey={selectedKey} onChange={v => this.setState({ selectedKey: v })}
|
||||
datas={!_.isEmpty(issuedAndReissueItems) ? topTab : topTab.slice(0, 1)}
|
||||
/>
|
||||
{
|
||||
selectedKey === "0" && _.map(itemsByGroup, item => {
|
||||
return <PayrollItemsTable {...item} onChangeIssueReissueValue={this.handleItemValueChange}/>;
|
||||
})
|
||||
}
|
||||
{
|
||||
selectedKey === "1" &&
|
||||
<IssuedAndReissueTable
|
||||
dataSource={issuedAndReissueItems}
|
||||
onChangeIssueReissueValue={this.handleItemValueChange}
|
||||
/>
|
||||
}
|
||||
</div>}
|
||||
/>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default EditSalaryCalcSlide;
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* Author: 黎永顺
|
||||
* name: 薪资核算
|
||||
* Description:
|
||||
* Date: 2023/9/14
|
||||
*/
|
||||
import React, { Component } from "react";
|
||||
import { WeaHelpfulTip, WeaLocaleProvider } from "ecCom";
|
||||
import { Alert } from "antd";
|
||||
import { getColumnDesc, getSalarySobCycle } from "../../../../../apis/calculate";
|
||||
import { sysConfCodeRule } from "../../../../../apis/ruleconfig";
|
||||
import EditCalcAdvanceSearchPannel from "./editCalcAdvanceSearchPannel";
|
||||
import EditCalcTable from "./editCalcTable";
|
||||
import SalaryMonthTip from "../salaryMonthTip";
|
||||
import cs from "classnames";
|
||||
import "./index.less";
|
||||
|
||||
const getLabel = WeaLocaleProvider.getLabel;
|
||||
|
||||
class Index extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
salarySobCycle: {}, showSearchAd: false,
|
||||
columnDesc: {}, formulaTd: "", showTotalCell: false
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const promise = this.init();
|
||||
}
|
||||
|
||||
openAdvanceSearch = () => this.setState({ showSearchAd: !this.state.showSearchAd });
|
||||
onAdSearch = (bool = true) => {
|
||||
this.calcTableRef.wrappedInstance.queryCalcResultList();
|
||||
bool && this.openAdvanceSearch();
|
||||
};
|
||||
init = async () => {
|
||||
const { routeParams: { salaryAcctRecordId } } = this.props;
|
||||
const [salarySobCycle, columnDesc, confCode] = await Promise.all([
|
||||
getSalarySobCycle({ salaryAcctRecordId }), getColumnDesc({ salaryAcctRecordId }),
|
||||
sysConfCodeRule({ code: "OPEN_ACCT_RESULT_SUM" })
|
||||
]);
|
||||
if (salarySobCycle.status && columnDesc.status && confCode.status) {
|
||||
this.setState({
|
||||
salarySobCycle: salarySobCycle.data,
|
||||
columnDesc: columnDesc.data, showTotalCell: confCode.data === "1"
|
||||
});
|
||||
}
|
||||
};
|
||||
handleShowFormulaTa = (dataIndex) => this.setState({ formulaTd: dataIndex });
|
||||
|
||||
render() {
|
||||
const { salarySobCycle, showSearchAd, formulaTd, columnDesc, showTotalCell } = this.state;
|
||||
const { accountExceptInfo, routeParams: { salaryAcctRecordId } } = this.props;
|
||||
const formulaObj = _.get(columnDesc, [formulaTd]) || {};
|
||||
return (
|
||||
<div className="salary-edit-calc-content">
|
||||
{
|
||||
accountExceptInfo &&
|
||||
<Alert message="" description={accountExceptInfo} type="error" closable/>
|
||||
}
|
||||
<div className="salary-flex-between weapp-salary-tb-tip">
|
||||
<div>
|
||||
<span>{getLabel(542604, "薪资所属月")}:</span>
|
||||
<span>{salarySobCycle.salaryMonth}</span>
|
||||
<WeaHelpfulTip
|
||||
width={200} placement="topLeft"
|
||||
title={<SalaryMonthTip {...salarySobCycle}/>}
|
||||
style={{ marginLeft: 10 }}
|
||||
/>
|
||||
</div>
|
||||
<div></div>
|
||||
</div>
|
||||
<div className="salary-flex-between formula-detail-area">
|
||||
<div className="formula-detail">
|
||||
<span>{getLabel(18125, "公式")}=</span>
|
||||
<span>{formulaObj.formulaContent}</span>
|
||||
</div>
|
||||
<div></div>
|
||||
</div>
|
||||
<div className={cs("searchAdvanced-condition-container", { "searchAdvanced-condition-hide": !showSearchAd })}>
|
||||
<EditCalcAdvanceSearchPannel
|
||||
salaryAcctRecordId={salaryAcctRecordId}
|
||||
onToggleSwitch={this.openAdvanceSearch}
|
||||
onAdSearch={this.onAdSearch}
|
||||
/>
|
||||
</div>
|
||||
<EditCalcTable ref={dom => this.calcTableRef = dom}
|
||||
{...this.props} showTotalCell={showTotalCell}
|
||||
onShowFormulaTd={this.handleShowFormulaTa}/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default Index;
|
||||
|
|
@ -0,0 +1,183 @@
|
|||
.salary-edit-calc-content {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.salary-flex-between {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.weapp-salary-tb-tip {
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
height: 46px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.formula-detail-area {
|
||||
background: #fff;
|
||||
height: 46px;
|
||||
|
||||
.formula-detail {
|
||||
padding-left: 8px;
|
||||
flex-grow: 1;
|
||||
flex-shrink: 1;
|
||||
min-height: 46px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.searchAdvanced-condition-hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.searchAdvanced-condition-container {
|
||||
background: #FFF;
|
||||
margin-bottom: 10px;
|
||||
border: 1px solid #e5e5e5;
|
||||
|
||||
.wea-search-buttons {
|
||||
border-top: 1px solid #dadada;
|
||||
padding: 15px 0;
|
||||
}
|
||||
|
||||
.wea-advanced-searchsAd {
|
||||
height: 320px;
|
||||
overflow: hidden auto;
|
||||
|
||||
.formItem-delete {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: -40px;
|
||||
}
|
||||
|
||||
.searchAdvanced-commonSelect {
|
||||
border-top: 1px solid #ebebeb;
|
||||
margin: 0 25px;
|
||||
padding: 10px 0;
|
||||
}
|
||||
|
||||
.custom-advance-largeSpacing {
|
||||
padding-left: 26px;
|
||||
|
||||
.link {
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
padding: 12px 10px 12px 26px;
|
||||
color: #2db7f5
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.editCalcTable-layout {
|
||||
flex: 1;
|
||||
|
||||
.ant-spin-nested-loading, .ant-spin-container {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.salary-calculate-esf-layout {
|
||||
|
||||
.titleDialog {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 0 46px 0 16px;
|
||||
|
||||
.titleCol {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.titleLeftBox {
|
||||
.titleIcon {
|
||||
color: #fff;
|
||||
margin: 0;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
font-size: 22px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: #F14A2D;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
padding-left: 6px;
|
||||
}
|
||||
}
|
||||
|
||||
.titleRightBox {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
}
|
||||
|
||||
.wea-slide-modal-title {
|
||||
border-bottom: 1px solid #e5e5e5 !important;
|
||||
}
|
||||
|
||||
.wea-slide-modal-content {
|
||||
height: 100%;
|
||||
|
||||
.salary-calculate-esf-area {
|
||||
background: #f6f6f6;
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
padding: 16px;
|
||||
|
||||
.esf-base-info-form, .wea-title, .wea-content {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.esf-form-content {
|
||||
background: #fff;
|
||||
border: 1px solid #e5e5e5;
|
||||
border-top: none;
|
||||
border-bottom: none;
|
||||
|
||||
.esf-form-item {
|
||||
border-bottom: 1px solid #e5e5e5;
|
||||
}
|
||||
|
||||
.esf-form-last-item {
|
||||
border-right: none !important;
|
||||
}
|
||||
|
||||
.esf-form-odd-item {
|
||||
border-right: 1px solid #e5e5e5;
|
||||
}
|
||||
|
||||
.label {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.label, .value {
|
||||
display: inline-block;
|
||||
line-height: 24px;
|
||||
padding: 8px 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.wea-new-table {
|
||||
background: #FFF;
|
||||
}
|
||||
|
||||
.wea-search-group {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,166 @@
|
|||
/*
|
||||
* Author: 黎永顺
|
||||
* name: 薪资核算-导入
|
||||
* Description:
|
||||
* Date: 2023/9/18
|
||||
*/
|
||||
import React, { Component } from "react";
|
||||
import { WeaCheckbox, WeaLocaleProvider } from "ecCom";
|
||||
import { Badge, Button, message } from "antd";
|
||||
import ImportDialog from "../../../../../components/importDialog";
|
||||
import { cacheImportField, getImportField, importAcctResult } from "../../../../../apis/calculate";
|
||||
import AddHeaderFieldsModal from "../../../../calculateDetail/acctResult/importModal/addHeaderFieldsModal";
|
||||
import { convertToUrlString, getURLParameters } from "../../../../../util/url";
|
||||
|
||||
const getLabel = WeaLocaleProvider.getLabel;
|
||||
|
||||
class Index extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
salaryItemIds: "", //选择的导入表单项
|
||||
exportTempUrl: "", //导出模板url
|
||||
headerFieldsDialog: { visible: false, itemsByGroup: [], selectItems: "" },
|
||||
importDialog: {
|
||||
visible: false, title: "", nextloading: false,
|
||||
link: null, importResult: {}, imageId: "",
|
||||
previewUrl: "/api/bs/hrmsalary/salaryacct/acctresult/preview",
|
||||
extraPreview: { salaryAcctRecordId: "", salaryItemIds: "" }
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
async componentWillReceiveProps(nextProps, nextContext) {
|
||||
if (nextProps.visible !== this.props.visible) {
|
||||
if (nextProps.salaryAcctRecordId && nextProps.visible) {
|
||||
const { data } = await getImportField({ salaryAcctRecordId: nextProps.salaryAcctRecordId });
|
||||
const { checkItems, itemsByGroup } = data;
|
||||
const payload = {
|
||||
exportData: false, salaryAcctRecordId: nextProps.salaryAcctRecordId,
|
||||
salaryItemIds: checkItems.join(",")
|
||||
};
|
||||
this.setState({
|
||||
exportTempUrl: `/api/bs/hrmsalary/salaryacct/acctresult/importtemplate/export?${convertToUrlString(payload)}`,
|
||||
importDialog: {
|
||||
...this.state.importDialog,
|
||||
extraPreview: { salaryAcctRecordId: nextProps.salaryAcctRecordId, salaryItemIds: checkItems.join(",") }
|
||||
},
|
||||
headerFieldsDialog: {
|
||||
...this.state.headerFieldsDialog,
|
||||
selectItems: checkItems.join(","),
|
||||
itemsByGroup: _.map(itemsByGroup, item => {
|
||||
return {
|
||||
...item,
|
||||
salaryItems: _.map(item.salaryItems, it => ({
|
||||
...it,
|
||||
checked: false
|
||||
}))
|
||||
};
|
||||
})
|
||||
}
|
||||
});
|
||||
}
|
||||
this.setState({
|
||||
importDialog: {
|
||||
...this.state.importDialog, link: this.handleExportTemp,
|
||||
visible: nextProps.visible, title: nextProps.title
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
handleImport = (payload) => {
|
||||
const { headerFieldsDialog: { selectItems: salaryItemIds }, importDialog } = this.state;
|
||||
const { salaryAcctRecordId } = this.props;
|
||||
this.setState({ importDialog: { ...importDialog, nextloading: true } });
|
||||
importAcctResult({ ...payload, salaryItemIds, salaryAcctRecordId })
|
||||
.then(({ data, status }) => {
|
||||
this.setState({ importDialog: { ...importDialog, nextloading: false } });
|
||||
if (status) {
|
||||
this.setState({
|
||||
importDialog: { ...importDialog, ...payload, importResult: data }
|
||||
});
|
||||
}
|
||||
}).catch(() => this.setState({ importDialog: { ...importDialog, nextloading: false } }));
|
||||
};
|
||||
handleExportTemp = () => {
|
||||
const { headerFieldsDialog: { selectItems }, exportTempUrl } = this.state;
|
||||
if (!selectItems) {
|
||||
message.error(getLabel(111, "请选择表头字段"));
|
||||
} else {
|
||||
window.open(exportTempUrl, "_blank");
|
||||
}
|
||||
};
|
||||
handleSelectedField = () => {
|
||||
this.setState({
|
||||
headerFieldsDialog: {
|
||||
...this.state.headerFieldsDialog, visible: true
|
||||
}
|
||||
});
|
||||
};
|
||||
/*
|
||||
* Author: 黎永顺
|
||||
* Description:表单选项
|
||||
* Params:
|
||||
* Date: 2023/9/18
|
||||
*/
|
||||
renderFormComponent = () => {
|
||||
const { selectItems } = this.state.headerFieldsDialog;
|
||||
return <div style={{ padding: "8px 16px", border: "1px solid #e5e5e5", margin: "4px 0" }}>
|
||||
<Badge
|
||||
count={!_.isEmpty(selectItems) ? selectItems.split(",").length : 0}>
|
||||
<Button onClick={this.handleSelectedField}>{getLabel(111, "请选择表头字段")}</Button>
|
||||
</Badge>
|
||||
</div>;
|
||||
};
|
||||
|
||||
render() {
|
||||
const { importDialog, headerFieldsDialog, exportTempUrl } = this.state;
|
||||
const { salaryAcctRecordId } = this.props;
|
||||
return (
|
||||
<React.Fragment>
|
||||
<ImportDialog
|
||||
{...importDialog} onCancel={this.props.onCancel}
|
||||
importParams={this.renderFormComponent()}
|
||||
onResetImportResult={() => this.setState(({
|
||||
importDialog: { ...importDialog, importResult: {}, imageId: "" }
|
||||
}))}
|
||||
exportDataDom={
|
||||
<WeaCheckbox
|
||||
content={getLabel(543208, "导出现有数据")}
|
||||
value={getURLParameters(exportTempUrl).exportData === "true" ? "1" : "0"}
|
||||
helpfulTip={getLabel(111, "提示:建议先导出现有最新数据,修改后再导入")}
|
||||
onChange={val => {
|
||||
const payload = {
|
||||
exportData: val === "1", salaryAcctRecordId,
|
||||
salaryItemIds: headerFieldsDialog.selectItems
|
||||
};
|
||||
this.setState(({
|
||||
exportTempUrl: `/api/bs/hrmsalary/salaryacct/acctresult/importtemplate/export?${convertToUrlString(payload)}`
|
||||
}));
|
||||
}}
|
||||
/>
|
||||
}
|
||||
nextCallback={imageId => this.handleImport({ imageId })}
|
||||
/>
|
||||
<AddHeaderFieldsModal
|
||||
{...headerFieldsDialog}
|
||||
onCancel={() => this.setState({
|
||||
headerFieldsDialog: { ...headerFieldsDialog, visible: false }
|
||||
})}
|
||||
onAdd={selectItems => this.setState({
|
||||
headerFieldsDialog: {
|
||||
...headerFieldsDialog,
|
||||
visible: false, selectItems: selectItems.join(",")
|
||||
}
|
||||
}, () => {
|
||||
const { selectItems: salaryItems } = this.state.headerFieldsDialog;
|
||||
cacheImportField({ salaryItems: salaryItems ? salaryItems.split(",") : [] }).then();
|
||||
})}
|
||||
/>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default Index;
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Author: 黎永顺
|
||||
* name: 薪资所属月提示语
|
||||
* Description:
|
||||
* Date: 2023/9/13
|
||||
*/
|
||||
import React, { Component } from "react";
|
||||
import { WeaLocaleProvider } from "ecCom";
|
||||
import "./index.less";
|
||||
|
||||
const getLabel = WeaLocaleProvider.getLabel;
|
||||
|
||||
class Index extends Component {
|
||||
render() {
|
||||
const { attendCycle, salaryCycle, salaryMonth, socialSecurityCycle } = this.props;
|
||||
const { fromDate: attendFromDate, endDate: attendEndDate } = attendCycle,
|
||||
{ fromDate: salaryFromDate, endDate: salaryEndDate } = salaryCycle;
|
||||
return (
|
||||
<div className="salary-month-tip">
|
||||
<div className="line">
|
||||
<div className="lable">{getLabel(543375, "薪资周期")}</div>
|
||||
<div className="value">{`${salaryFromDate}${getLabel(15322, "至")}${salaryEndDate}`}</div>
|
||||
</div>
|
||||
<div className="line">
|
||||
<div className="lable">{getLabel(542240, "税款所属期")}</div>
|
||||
<div className="value">{salaryMonth}</div>
|
||||
</div>
|
||||
<div className="line">
|
||||
<div className="lable">{getLabel(543475, "考勤取值周期")}</div>
|
||||
<div className="value">{`${attendFromDate}${getLabel(15322, "至")}${attendEndDate}`}</div>
|
||||
</div>
|
||||
<div className="line">
|
||||
<div className="lable">{getLabel(543466, "福利台账月份")}</div>
|
||||
<div
|
||||
className="value">{`${getLabel(19422, "引用")}${socialSecurityCycle}${getLabel(543476, "的福利台账数据")}`}</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default Index;
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
.salary-month-tip {
|
||||
.line {
|
||||
.label {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.value {
|
||||
color: #111;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,232 @@
|
|||
/*
|
||||
* Author: 黎永顺
|
||||
* name: 薪资核算详情
|
||||
* Description:
|
||||
* Date: 2023/9/13
|
||||
*/
|
||||
import React, { Component } from "react";
|
||||
import { WeaLocaleProvider, WeaReqTop } from "ecCom";
|
||||
import { Button, Dropdown, Menu, message, Modal } from "antd";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import Layout from "./layout";
|
||||
import { acctresultAccounting, getCalculateProgress, getExportField } from "../../../apis/calculate";
|
||||
import AdvanceInputBtn from "./components/advanceInputBtn";
|
||||
import SalaryCalcPersonConfirm from "./components/salaryCalcPersonConfirm";
|
||||
import SalaryEditCalc from "./components/salaryEditCalc";
|
||||
import ProgressModal from "../../../components/progressModal";
|
||||
import CustomCalcExportDialog from "./components/customCalcExportDialog";
|
||||
import SalaryEditCalcImport from "./components/salaryEditCalcImport";
|
||||
import { convertToUrlString } from "../../../util/url";
|
||||
import "./index.less";
|
||||
|
||||
const getLabel = WeaLocaleProvider.getLabel;
|
||||
|
||||
@inject("calculateStore")
|
||||
@observer
|
||||
class Index extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
selectedKey: "person", progressVisible: false, progress: 0,
|
||||
customExpDialog: { visible: false, salaryAcctRecordId: "", checkItems: [], itemsByGroup: [] },
|
||||
salaryImpDialog: { visible: false, title: "", salaryAcctRecordId: "" },
|
||||
accountExceptInfo: "" //核算报错信息,
|
||||
|
||||
};
|
||||
this.calc = null;
|
||||
this.timer = null;
|
||||
}
|
||||
|
||||
handleMenuClick = ({ key }) => {
|
||||
switch (key) {
|
||||
case "calc_selected":
|
||||
const { selectedRowKeys } = this.calc.calcTableRef.wrappedInstance.state;
|
||||
if (_.isEmpty(selectedRowKeys)) {
|
||||
message.warning(getLabel(543303, "请选择表格数据!"));
|
||||
return;
|
||||
}
|
||||
this.doCacl(key, selectedRowKeys);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
doCacl = (key, selectedRowKeys = []) => {
|
||||
Modal.confirm({
|
||||
title: getLabel(131329, "信息确认"),
|
||||
content: getLabel(543544, "点击核算,公式项将按照公式逻辑核算,核算结果将覆盖原数据"),
|
||||
onOk: () => {
|
||||
const { routeParams: { salaryAcctRecordId } } = this.props;
|
||||
this.setState({ progress: 0 });
|
||||
let payload = { salaryAcctRecordId };
|
||||
if (key === "calc_selected") payload = _.assign(payload, { ids: selectedRowKeys });
|
||||
acctresultAccounting(payload).then(() => {
|
||||
this.setState({ progressVisible: true });
|
||||
if (this.timer) clearInterval(this.timer);
|
||||
this.timer = setInterval(() => {
|
||||
getCalculateProgress(salaryAcctRecordId).then(({ data }) => {
|
||||
let progress = data.progress;
|
||||
if (progress === 1 && this.timer) {
|
||||
clearInterval(this.timer);
|
||||
this.timer = null;
|
||||
this.setState({
|
||||
progressVisible: false,
|
||||
accountExceptInfo: data.message
|
||||
});
|
||||
message.success(getLabel(542321, "核算完成"));
|
||||
this.calc.onAdSearch(false);
|
||||
} else if (!data.status) {
|
||||
clearInterval(this.timer);
|
||||
this.timer = null;
|
||||
this.setState({
|
||||
progressVisible: false,
|
||||
accountExceptInfo: data.message
|
||||
});
|
||||
message.error(data.message);
|
||||
}
|
||||
this.setState({ progress: Number(progress) * 100 });
|
||||
});
|
||||
}, 1000);
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
handleMoreMenuClick = ({ key }) => {
|
||||
const { calculateStore: { ECSearchForm }, routeParams: { salaryAcctRecordId } } = this.props;
|
||||
switch (key) {
|
||||
case "exportAll":
|
||||
const { consolidatedTaxation, ...extra } = ECSearchForm.getFormParams();
|
||||
const payload = { ...extra, consolidatedTaxation: consolidatedTaxation === "0" ? "" : consolidatedTaxation };
|
||||
const url = `/api/bs/hrmsalary/salaryacct/acctresult/export?salaryAcctRecordId=${salaryAcctRecordId}&ids=&${convertToUrlString(payload)}`;
|
||||
window.open(`${window.ecologyContentPath || ""}${url}`, "_blank");
|
||||
break;
|
||||
case "export_custom":
|
||||
getExportField({ salaryAcctRecordId }).then(({ status, data }) => {
|
||||
if (status) {
|
||||
const { checkItems, itemsByGroup } = data;
|
||||
this.setState({
|
||||
customExpDialog: {
|
||||
...this.state.customExpDialog, visible: true, salaryAcctRecordId,
|
||||
checkItems, itemsByGroup
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
break;
|
||||
case "import":
|
||||
this.setState({
|
||||
salaryImpDialog: {
|
||||
...this.state.salaryImpDialog,
|
||||
salaryAcctRecordId, visible: true,
|
||||
title: getLabel(111, "薪资导入")
|
||||
}
|
||||
});
|
||||
break;
|
||||
case "offlineCompare":
|
||||
window.open(`/spa/hrmSalary/static/index.html#/main/hrmSalary/calcOc/${salaryAcctRecordId}`, "_blank");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
renderReqBtns = () => {
|
||||
const { selectedKey } = this.state;
|
||||
let reqBtns = [];
|
||||
switch (selectedKey) {
|
||||
case "calc":
|
||||
const menu = (
|
||||
<Menu onClick={this.handleMenuClick}>
|
||||
<Menu.Item key="calc_selected">{getLabel(543546, "核算所选人员")}</Menu.Item>
|
||||
</Menu>
|
||||
);
|
||||
const moreMenu = (
|
||||
<Menu onClick={this.handleMoreMenuClick}>
|
||||
<Menu.Item key="import">{getLabel(32935, "导入")}</Menu.Item>
|
||||
<Menu.Item key="exportAll">{getLabel(81272, "导出全部")}</Menu.Item>
|
||||
<Menu.Item key="export_custom">{getLabel(544270, "自定义导出")}</Menu.Item>
|
||||
<Menu.Item key="offlineCompare">{getLabel(543249, "线下对比")}</Menu.Item>
|
||||
</Menu>
|
||||
);
|
||||
reqBtns = [
|
||||
<Dropdown.Button onClick={() => this.doCacl("ALL")} overlay={menu} type="primary">
|
||||
{getLabel(543545, "核算所有人")}
|
||||
</Dropdown.Button>,
|
||||
<Dropdown overlay={moreMenu}><Button type="ghost">{getLabel(17499, "更多")}</Button></Dropdown>,
|
||||
<AdvanceInputBtn onOpenAdvanceSearch={() => this.calc.openAdvanceSearch()}
|
||||
onAdvanceSearch={() => this.calc.onAdSearch(false)}/>
|
||||
];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return reqBtns;
|
||||
};
|
||||
renderContent = () => {
|
||||
const { selectedKey, accountExceptInfo } = this.state;
|
||||
let dom = null;
|
||||
switch (selectedKey) {
|
||||
case "person":
|
||||
dom = <SalaryCalcPersonConfirm {...this.props}/>;
|
||||
break;
|
||||
case "calc":
|
||||
dom = <SalaryEditCalc {...this.props} accountExceptInfo={accountExceptInfo} ref={dom => this.calc = dom}/>;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return dom;
|
||||
};
|
||||
|
||||
render() {
|
||||
const tabs = [
|
||||
{ key: "person", title: getLabel(543547, "人员确认") },
|
||||
{ key: "calc", title: getLabel(538011, "薪资核算") }
|
||||
];
|
||||
const { calculateStore: { setOtherConditions } } = this.props;
|
||||
const { selectedKey, progressVisible, progress, customExpDialog, salaryImpDialog } = this.state;
|
||||
return (
|
||||
<Layout {...this.props}>
|
||||
<div className="salary-calculate-do-calc">
|
||||
<WeaReqTop
|
||||
title={getLabel(538011, "薪资核算")} tabDatas={tabs} selectedKey={selectedKey}
|
||||
buttonSpace={10} icon={<i className="icon-coms-fa"/>} iconBgcolor="#F14A2D"
|
||||
onChange={key => this.setState({ selectedKey: key }, () => setOtherConditions([]))}
|
||||
buttons={this.renderReqBtns()}
|
||||
>
|
||||
<div className="salary-calculate-do-calc-content">{this.renderContent()}</div>
|
||||
{
|
||||
progressVisible &&
|
||||
<ProgressModal
|
||||
visible={progressVisible}
|
||||
onCancel={() => {
|
||||
this.setState({ progressVisible: false, progress: 0 }, () => clearInterval(this.timer));
|
||||
}}
|
||||
progress={parseFloat(progress).toFixed(2)}
|
||||
/>
|
||||
}
|
||||
{/* 薪资核算-自定义导出*/}
|
||||
<CustomCalcExportDialog
|
||||
{...customExpDialog}
|
||||
onCancel={() => {
|
||||
this.setState({
|
||||
customExpDialog: { ...customExpDialog, visible: false }
|
||||
});
|
||||
}}
|
||||
/>
|
||||
{/* 薪资核算-导入*/}
|
||||
<SalaryEditCalcImport
|
||||
{...salaryImpDialog}
|
||||
onCancel={(isFresh) => {
|
||||
this.setState({
|
||||
salaryImpDialog: { ...salaryImpDialog, visible: false }
|
||||
}, () => isFresh && this.calc.onAdSearch(false));
|
||||
}}
|
||||
/>
|
||||
</WeaReqTop>
|
||||
</div>
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default Index;
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
.salary-calculate-do-calc {
|
||||
min-width: 1000px;
|
||||
overflow: auto;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #f6f6f6;
|
||||
|
||||
.wea-new-top-req {
|
||||
z-index: 0 !important;
|
||||
}
|
||||
|
||||
.wea-new-top-req-wapper .wea-new-top-req-title > div:last-child {
|
||||
right: 16px;
|
||||
}
|
||||
|
||||
.salary-calculate-do-calc-content {
|
||||
padding: 8px 16px;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
import React, { Component } from "react";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import Authority from "../../mySalary/authority";
|
||||
import { salaryacctAcctresultCheckAuth } from "../../../apis/calculate";
|
||||
|
||||
@inject("taxAgentStore")
|
||||
@observer
|
||||
class Layout extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
store: { loading: false, hasRight: false }
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.salaryacctAcctresultCheckAuth();
|
||||
}
|
||||
|
||||
salaryacctAcctresultCheckAuth = () => {
|
||||
const { taxAgentStore: { getPermission } } = this.props;
|
||||
this.setState({ store: { ...this.state.store, loading: true } });
|
||||
getPermission().then(({ data }) => {
|
||||
const { isOpenDevolution } = data;
|
||||
if (isOpenDevolution) {
|
||||
const { routeParams: { salaryAcctRecordId } } = this.props;
|
||||
salaryacctAcctresultCheckAuth({ salaryAcctRecordId }).then(({ status, data }) => {
|
||||
this.setState({ store: { ...this.state.store, loading: false, hasRight: status && data } });
|
||||
});
|
||||
} else {
|
||||
this.setState({ store: { ...this.state.store, loading: false, hasRight: true } });
|
||||
}
|
||||
}).catch(() => this.setState({ store: { ...this.state.store, loading: false } }));
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Authority ecId={`${this && this.props && this.props.ecId || ""}_Authority@lulowc`}
|
||||
store={{ ...this.state.store }}>
|
||||
{this.props.children}
|
||||
</Authority>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default Layout;
|
||||
|
|
@ -71,9 +71,13 @@ export default class Calculate extends React.Component {
|
|||
// 列表项核算回调
|
||||
handleAccount(record) {
|
||||
window.open(
|
||||
"/spa/hrmSalary/static/index.html#/main/hrmSalary/calculateDetail?id=" +
|
||||
"/spa/hrmSalary/static/index.html#/main/hrmSalary/calculate/" +
|
||||
record.id
|
||||
);
|
||||
// window.open(
|
||||
// "/spa/hrmSalary/static/index.html#/main/hrmSalary/calculateDetail?id=" +
|
||||
// record.id
|
||||
// );
|
||||
}
|
||||
|
||||
// 列表项删除回调
|
||||
|
|
|
|||
|
|
@ -286,7 +286,7 @@ export default class Payroll extends React.Component {
|
|||
viewcondition: "1"
|
||||
},
|
||||
{
|
||||
title: getLabel(111, "工资单模板基础设置"),
|
||||
title: getLabel(111, "工资单基础设置"),
|
||||
viewcondition: "2"
|
||||
}
|
||||
];
|
||||
|
|
|
|||
|
|
@ -19,4 +19,16 @@
|
|||
margin-top: -10px;
|
||||
}
|
||||
}
|
||||
|
||||
.agingBox {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 5px 16px;
|
||||
border-bottom: 1px solid #e5e5e5;
|
||||
|
||||
.wea-input-number {
|
||||
width: 80px !important;
|
||||
margin: 0 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -306,7 +306,6 @@ export default class PayrollGrant extends React.Component {
|
|||
const { selectedKey, showFeedbackColumn } = this.state;
|
||||
const { payrollStore } = this.props;
|
||||
const { salaryGrantTableStore: columns, salarySendDetailBaseInfo } = payrollStore;
|
||||
const notShowGrantOrWithdraw = salarySendDetailBaseInfo.haveBackCalc === 1 && salarySendDetailBaseInfo.salaryAcctType === "0";
|
||||
return _.map([
|
||||
..._.filter(toJS(columns), it => ((selectedKey === "0" && it.dataIndex !== "billReadStatus" && it.dataIndex !== "billConfirmStatus") || (selectedKey === "1" && !showFeedbackColumn && it.dataIndex !== "billReadStatus" && it.dataIndex !== "billConfirmStatus") || (selectedKey === "1" && showFeedbackColumn))),
|
||||
{
|
||||
|
|
@ -315,14 +314,43 @@ export default class PayrollGrant extends React.Component {
|
|||
dataIndex: "",
|
||||
display: true,
|
||||
render: (text, record) => {
|
||||
if (record.sendStatus === "1" && salarySendDetailBaseInfo.canSend) {
|
||||
return (
|
||||
<a
|
||||
href="javascript:void(0);"
|
||||
onClick={() => this.handleWithdraw({ ids: [record.id] })}>
|
||||
撤回
|
||||
</a>
|
||||
);
|
||||
if (record.sendStatus === "1") {
|
||||
if (salarySendDetailBaseInfo.canSend) {
|
||||
return (
|
||||
<React.Fragment>
|
||||
<a
|
||||
href="javascript:void(0);" style={{ marginRight: 10 }}
|
||||
onClick={() => this.handleWithdraw({ ids: [record.id] })}>
|
||||
撤回
|
||||
</a>
|
||||
{
|
||||
salarySendDetailBaseInfo.showPdfBtn &&
|
||||
<a
|
||||
href="javascript:void(0);"
|
||||
onClick={() => {
|
||||
window.open(`${window.ecologyContentPath || ""}/api/bs/hrmsalary/salaryBill/exportPdf?id=${record.id}&salarySendId=${getQueryString("id")}`, "_blank");
|
||||
}}>
|
||||
{getLabel(111, "导出PDF")}
|
||||
</a>
|
||||
}
|
||||
</React.Fragment>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<React.Fragment>
|
||||
{
|
||||
salarySendDetailBaseInfo.showPdfBtn &&
|
||||
<a
|
||||
href="javascript:void(0);"
|
||||
onClick={() => {
|
||||
window.open(`${window.ecologyContentPath || ""}/api/bs/hrmsalary/salaryBill/exportPdf?id=${record.id}&salarySendId=${getQueryString("id")}`, "_blank");
|
||||
}}>
|
||||
{getLabel(111, "导出PDF")}
|
||||
</a>
|
||||
}
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
} else if (salarySendDetailBaseInfo.canSend) {
|
||||
return (
|
||||
<a
|
||||
|
|
@ -350,7 +378,6 @@ export default class PayrollGrant extends React.Component {
|
|||
getSearchsAdQuick() {
|
||||
const { payrollStore } = this.props;
|
||||
const { salarySendDetailBaseInfo, btnLoading } = payrollStore;
|
||||
const notShowGrantOrWithdraw = salarySendDetailBaseInfo.haveBackCalc === 1 && salarySendDetailBaseInfo.salaryAcctType === "0";
|
||||
const { selectedKey } = this.state;
|
||||
const handleMenuClick = e => {
|
||||
switch (e.key) {
|
||||
|
|
@ -360,6 +387,9 @@ export default class PayrollGrant extends React.Component {
|
|||
case "4":
|
||||
this.handleExportSelect();
|
||||
break;
|
||||
case "5":
|
||||
window.open(`${window.ecologyContentPath || ""}/api/bs/hrmsalary/salaryBill/exportPdf?salarySendId=${getQueryString("id")}&id=`, "_blank");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -368,6 +398,10 @@ export default class PayrollGrant extends React.Component {
|
|||
<Menu onClick={handleMenuClick}>
|
||||
<Menu.Item key="3">全部导出</Menu.Item>
|
||||
<Menu.Item key="4">导出选中</Menu.Item>
|
||||
{
|
||||
selectedKey === "1" && salarySendDetailBaseInfo.showPdfBtn &&
|
||||
<Menu.Item key="5">{getLabel(111, "导出PDF")}</Menu.Item>
|
||||
}
|
||||
</Menu>
|
||||
);
|
||||
let btnDom = [
|
||||
|
|
|
|||
|
|
@ -36,6 +36,9 @@ class TemplateBaseSettings extends Component {
|
|||
ackStatus: "0",
|
||||
autoAckDays: 7,
|
||||
feedBackUrl: ""
|
||||
},
|
||||
salaryBillViewingLimitSetting: {
|
||||
limitMonth: 0
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
@ -48,9 +51,12 @@ class TemplateBaseSettings extends Component {
|
|||
const { watermarkSet } = this.state;
|
||||
getSalaryBillBaseSetForm().then(({ status, data }) => {
|
||||
if (status) {
|
||||
const { watermarkStatus, watermark = "DEFAULT", watermarkSetting, ackFeedbackSetting } = data;
|
||||
const {
|
||||
watermarkStatus, watermark = "DEFAULT", watermarkSetting,
|
||||
ackFeedbackSetting, salaryBillViewingLimitSetting = {}
|
||||
} = data;
|
||||
this.setState({
|
||||
watermark, watermarkStatus: watermarkStatus ? "1" : "0", ackFeedbackSetting,
|
||||
watermark, watermarkStatus: watermarkStatus ? "1" : "0", ackFeedbackSetting, salaryBillViewingLimitSetting,
|
||||
wmSetting: { wmSetting: watermarkSetting },
|
||||
watermarkSet: {
|
||||
...watermarkSet,
|
||||
|
|
@ -61,7 +67,7 @@ class TemplateBaseSettings extends Component {
|
|||
});
|
||||
};
|
||||
salaryBillBaseSetSave = () => {
|
||||
const { watermark, watermarkStatus, wmSetting, ackFeedbackSetting } = this.state;
|
||||
const { watermark, watermarkStatus, wmSetting, ackFeedbackSetting, salaryBillViewingLimitSetting } = this.state;
|
||||
const { feedBackUrl } = ackFeedbackSetting;
|
||||
if (!feedBackUrl) {
|
||||
Modal.warning({
|
||||
|
|
@ -70,7 +76,10 @@ class TemplateBaseSettings extends Component {
|
|||
});
|
||||
return;
|
||||
}
|
||||
let payload = { watermarkStatus: watermarkStatus === "1", ackFeedbackSetting: { ...ackFeedbackSetting } };
|
||||
let payload = {
|
||||
watermarkStatus: watermarkStatus === "1", ackFeedbackSetting: { ...ackFeedbackSetting },
|
||||
salaryBillViewingLimitSetting: { ...salaryBillViewingLimitSetting }
|
||||
};
|
||||
if (watermarkStatus === "1") payload = { ...payload, watermark };
|
||||
if (!_.isNil(wmSetting)) payload = { ...payload, watermark, ...wmSetting };
|
||||
this.props.onChangeLoading(true);
|
||||
|
|
@ -86,8 +95,9 @@ class TemplateBaseSettings extends Component {
|
|||
};
|
||||
|
||||
render() {
|
||||
const { watermarkStatus, watermark, watermarkSet, ackFeedbackSetting } = this.state;
|
||||
const { watermarkStatus, watermark, watermarkSet, ackFeedbackSetting, salaryBillViewingLimitSetting } = this.state;
|
||||
const { ackStatus, autoAckDays, feedBackUrl } = ackFeedbackSetting;
|
||||
const { limitMonth = 0 } = salaryBillViewingLimitSetting;
|
||||
return (
|
||||
<React.Fragment>
|
||||
<WeaSearchGroup title={getLabel(111, "水印设置")} showGroup needTigger className="waterMarkWrapper">
|
||||
|
|
@ -160,6 +170,22 @@ class TemplateBaseSettings extends Component {
|
|||
</React.Fragment>
|
||||
}
|
||||
</WeaSearchGroup>
|
||||
<WeaSearchGroup title={getLabel(111, "工资单时效设置")} showGroup needTigger className="waterMarkWrapper">
|
||||
<div className="agingBox">
|
||||
<span>{getLabel(111, "仅可查看")}</span>
|
||||
<WeaInputNumber min={0} value={limitMonth}
|
||||
onChange={limitMonth => this.setState({
|
||||
salaryBillViewingLimitSetting: {
|
||||
...salaryBillViewingLimitSetting, limitMonth
|
||||
}
|
||||
})}/>
|
||||
<span>{getLabel(111, "个月内的工资单")}</span>
|
||||
<WeaHelpfulTip
|
||||
title={getLabel(111, "0表示不控制!")}
|
||||
style={{ marginLeft: 10 }}
|
||||
placement="top"/>
|
||||
</div>
|
||||
</WeaSearchGroup>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,11 @@ import { toDecimal_n } from "../util";
|
|||
const { TableStore } = WeaTableNew;
|
||||
|
||||
export class calculateStore {
|
||||
@observable PCSearchForm = new WeaForm(); //人员确认-form
|
||||
@observable ECSearchForm = new WeaForm(); //薪资核算-form
|
||||
@observable otherConditions = []; //薪资核算-其他查询条件
|
||||
|
||||
|
||||
@observable tableStore = new TableStore(); // new table
|
||||
@observable form = new WeaForm(); // nrew 一个form
|
||||
@observable condition = []; // 存储后台得到的form数据
|
||||
|
|
@ -63,6 +68,10 @@ export class calculateStore {
|
|||
@observable columnDescList = {};
|
||||
|
||||
|
||||
// ** 薪资核算-其他条件查询 **
|
||||
@action
|
||||
setOtherConditions = (otherConditions) => this.otherConditions = otherConditions;
|
||||
|
||||
// ** 设置导入参数 **
|
||||
@action
|
||||
setPreviewAcctResultColumns = (previewAcctResultColumns) => {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import { WeaForm, WeaTableNew } from "comsMobx";
|
|||
|
||||
import * as API from "../apis/taxAgent"; // 引入API接口文件
|
||||
import { decentralizationConditions, editConditions } from "../pages/taxAgent/editConditions";
|
||||
import { taxAgentRangeExtDelete } from "../apis/taxAgent";
|
||||
|
||||
const { TableStore } = WeaTableNew;
|
||||
|
||||
|
|
@ -156,12 +155,12 @@ export class TaxAgentStore {
|
|||
//薪酬统计报表权限
|
||||
this.setStatisticsReportBtn(!isOpenDevolution ? true : !!(isAdminEnable || isChief));
|
||||
//薪资核算详情页面查看权限
|
||||
this.setPayrollPermission(isAdminEnable && isOpenDevolution || !isOpenDevolution);
|
||||
this.setPayrollPermission((isOpenDevolution && isAdminEnable) || !isOpenDevolution);
|
||||
resolve({ status, data });
|
||||
} else {
|
||||
reject();
|
||||
}
|
||||
});
|
||||
}).catch(() => reject());
|
||||
});
|
||||
};
|
||||
// 人员范围列表
|
||||
|
|
|
|||
Loading…
Reference in New Issue