Merge branch 'release/2.12.1.2403.02' into hotfix/2.12.1.2403.02

This commit is contained in:
黎永顺 2024-03-27 13:49:29 +08:00
commit 618c0edfb2
17 changed files with 747 additions and 24 deletions

View File

@ -39,4 +39,7 @@ export const getDetailChanges = params => {
export const getSalarysobListAll = params => {
return postFetch("/api/bs/hrmsalary/salarysob/listAll", params);
};
//补算
export const supplementAcctRecord = (params) => {
return postFetch("/api/bs/hrmsalary/salaryacct/supplementAcctRecord", params);
};

View File

@ -1,5 +1,5 @@
import { WeaTools } from "ecCom";
import { postFetch } from "../util/request";
import { postExportFetch, postFetch } from "../util/request";
//薪酬统计维度下拉列表
export const dimensionGetForm = (params) => {
@ -122,3 +122,15 @@ export const getExpandFieldSettings = (params) => {
export const statisticsReportDuplicate = (params) => {
return WeaTools.callApi("/api/bs/hrmsalary/report/statistics/report/duplicate", "GET", params);
};
//薪酬统计报表-薪资明细列表
export const getSalaryList = (params) => {
return postFetch("/api/bs/hrmsalary/report/statistics/employee/salaryList", params);
};
//薪酬统计报表-薪资明细列表总计行
export const getSalaryListSum = (params) => {
return postFetch("/api/bs/hrmsalary/report/statistics/employee/salaryListSum", params);
};
// 薪酬统计报表-薪资明细导出
export const exportSalaryList = (params) => {
return postExportFetch("/api/bs/hrmsalary/report/statistics/employee/exportSalaryList", params);
};

View File

@ -51,6 +51,7 @@ import WatermarkPreview from "./pages/payroll/watermarkPreview";
import ExternalPersonManage from "./pages/externalPersonManage";
import AdjustSalaryManage from "./pages/adjustSalaryManage";
import TopologyMap from "./pages/topologyMap";
import SupplementaryCalc from "./pages/supplementaryCalc";
import stores from "./stores";
import "./style/index";
@ -110,6 +111,7 @@ const DataAcquisition = (props) => props.children;
// reportView 薪酬报表查看
// externalPersonManage 非系统人员管理
// adjustSalaryManage 档案管理
// supplementaryCalc 补算
const Routes = (
<Route
@ -185,6 +187,7 @@ const Routes = (
<Route key="reportView" path="reportView" component={ReportView}/>
<Route key="externalPersonManage" path="externalPersonManage" component={ExternalPersonManage}/>
<Route key="topologyView" path="topologyView/:salarySobId/:salaryItemId" component={TopologyMap}/>
<Route key="supplementaryCalc" path="supplementaryCalc" component={SupplementaryCalc}/>
</Route>
);

View File

@ -0,0 +1,33 @@
/*
* Author: 黎永顺
* name:薪酬统计报表-高级搜索
* Description:
* Date: 2024/3/26
*/
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("attendanceStore")
@observer
class Index extends Component {
render() {
const { attendanceStore: { salaryDetailSearchForm } } = this.props;
return (
<div className="achrive-advance-search">
<WeaInputSearch value={salaryDetailSearchForm.getFormParams().keyword}
onChange={v => salaryDetailSearchForm.updateFields({ keyword: v })}
onSearch={this.props.onAdvanceSearch}
/>
<Button type="ghost" className="wea-advanced-search text-elli"
onClick={this.props.onOpenAdvanceSearch}>{getLabel(545754, "高级搜索")}</Button>
</div>
);
}
}
export default Index;

View File

@ -0,0 +1,29 @@
.achrive-advance-search {
display: flex;
align-items: center;
position: relative;
top: -1.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;
top: 1px;
}
}

View File

@ -1,3 +1,4 @@
import React from "react";
import { WeaLocaleProvider } from "ecCom";
const { getLabel } = WeaLocaleProvider;
@ -131,3 +132,90 @@ export const extensionCondition = [
defaultshow: true
}
];
export const salaryDetailSearchConditions = [
{
items: [
{
conditionType: "INPUT",
domkey: ["keyword"],
fieldcol: 16,
label: getLabel(111, "姓名/工号"),
labelcol: 8,
value: "",
viewAttr: 2
},
{
conditionType: "SELECT",
domkey: ["taxAgentIds"],
fieldcol: 16,
label: getLabel(537996, "个税扣缴义务人"),
labelcol: 8,
options: [],
multiple: true,
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: 16,
label: getLabel(33553, "分部"),
labelcol: 8,
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
},
conditionType: "BROWSER",
domkey: ["departmentIds"],
fieldcol: 16,
label: getLabel(27511, "部门"),
labelcol: 8,
viewAttr: 2
}
],
defaultshow: true,
title: getLabel(1361, "基本信息"),
col: 2
}
];

View File

@ -0,0 +1,150 @@
/*
* Author: 黎永顺
* name:薪资明细列表
* Description:
* Date: 2024/3/26
*/
import React, { Component } from "react";
import { inject, observer } from "mobx-react";
import { toJS } from "mobx";
import { WeaLoadingGlobal, WeaLocaleProvider } from "ecCom";
import { WeaTableNew } from "comsMobx";
import { message, Spin } from "antd";
import * as API from "../../../apis/statistics";
import { getIframeParentHeight } from "../../../util";
import { sysConfCodeRule } from "../../../apis/ruleconfig";
import "../index.less";
const WeaTableComx = WeaTableNew.WeaTable;
const { getLabel } = WeaLocaleProvider;
@inject("attendanceStore")
@observer
class SalaryDetails extends Component {
constructor(props) {
super(props);
this.state = {
loading: false, dataSource: [], columns: [], selectedRowKeys: [],
pageInfo: { current: 1, pageSize: 10, total: 0 }, payload: {},
countResult: {}, showTotalCell: false
};
}
componentDidMount() {
this.getSalaryList(this.props);
window.addEventListener("message", this.handleReceive, false);
}
componentWillReceiveProps(nextProps, nextContext) {
if (nextProps.isQuery !== this.props.isQuery) this.setState({
pageInfo: { ...this.state.pageInfo, current: 1 }
}, () => this.getSalaryList(nextProps));
}
componentWillUnmount() {
window.removeEventListener("message", this.handleReceive, false);
this.setState(({ selectedRowKeys: [] }));
}
handleReceive = ({ data }) => {
const { type, payload: { id, params } = {} } = data;
const { pageInfo } = this.state;
if (type === "init") {
this.getColumns();
} else if (type === "turn") {
if (id === "PAGEINFO") {
const { pageNum: current, size: pageSize } = params;
this.setState({ pageInfo: { ...pageInfo, current, pageSize } }, () => this.getSalaryList(this.props));
} else if (id === "CHECKBOX") {
const { selectedRowKeys: checkBox } = params;
this.setState({ selectedRowKeys: checkBox });
}
}
};
postMessageToChild = (payload) => {
const i18n = {
"共": getLabel(18609, "共"), "条": getLabel(18256, "条"),
"总计": getLabel(523, "总计")
};
const childFrameObj = document.getElementById("atdTable");
childFrameObj && childFrameObj.contentWindow.postMessage(JSON.stringify({ ...payload, i18n }), "*");
};
getSalaryList = (props) => {
const { attendanceStore: { salaryDetailSearchForm, tableStore }, dateRange } = props;
const [startDateStr, endDateStr] = dateRange;
const { taxAgentIds, subcompanyIds, departmentIds, ...extra } = salaryDetailSearchForm.getFormParams();
const { pageInfo } = this.state;
const payload = {
taxAgentIds: taxAgentIds ? taxAgentIds.split(",") : [],
departmentIds: departmentIds ? departmentIds.split(",") : [],
subcompanyIds: subcompanyIds ? subcompanyIds.split(",") : [],
...extra, ...pageInfo, startDateStr, endDateStr
};
this.setState({ loading: true });
API.getSalaryList(payload).then(async ({ status, data }) => {
const [{ data: sumData }, { data: confCode }] = await Promise.all([API.getSalaryListSum(payload), sysConfCodeRule({ code: "OPEN_ACCT_RESULT_SUM" })]);
this.setState({ loading: false });
if (status) {
const { dataKey, pageInfo: pageparams } = data;
const { list: dataSource, pageNum: current, total, pageSize } = pageparams;
this.setState({
dataSource, pageInfo: { ...pageInfo, current, total, pageSize }, payload,
countResult: sumData.sumRow, showTotalCell: confCode === "1"
}, () => tableStore.getDatas(dataKey.datas));
}
}).catch(() => this.setState({ loading: false }));
};
handleExportSalaryList = (key) => {
let { selectedRowKeys, payload } = this.state;
if (key === "SELECTED" && selectedRowKeys.length === 0) {
message.warning(getLabel(543345, "请选择需要导出的数据!"));
return;
}
WeaLoadingGlobal.start();
const promise = API.exportSalaryList({ ...payload, ids: selectedRowKeys });
};
getColumns = () => {
const { attendanceStore: { tableStore } } = this.props;
const { dataSource, pageInfo, selectedRowKeys, countResult, showTotalCell } = this.state;
const columns = _.filter(toJS(tableStore.columns), (item) => item.display === "true" && item.dataIndex !== "acctTimes");
if (!_.isEmpty(columns)) {
this.postMessageToChild({
dataSource, pageInfo, selectedRowKeys, showTotalCell, calcDetail: true, tableScrollHeight: 154,
sumRow: countResult,
columns: _.map(columns, (it, idx) => ({
...it,
width: (it.dataIndex === "taxAgent" || it.dataIndex === "salarySob") ? 176 : it.oldWidth,
fixed: (idx === 1 || idx === 0 || idx === 2) ? "left" : "",
ellipsis: true
}))
});
}
return [];
};
render() {
const { loading, dataSource } = this.state;
const { attendanceStore: { tableStore } } = this.props;
return (
<div className="table-layout"
style={{ height: getIframeParentHeight(".wea-new-top-req-content", dataSource.length, 0) + "px" }}>
<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"
/>
</Spin>
<WeaTableComx
style={{ display: "none" }}
comsWeaTableStore={tableStore}
needScroll={true}
columns={this.getColumns()}
/>
</div>
);
}
}
export default SalaryDetails;

View File

@ -0,0 +1,77 @@
/*
* Author: 黎永顺
* name:薪酬统计报薪资明细-高级查询
* Description:
* Date: 2024/3/26
*/
import React, { Component } from "react";
import { WeaLocaleProvider, WeaTools } from "ecCom";
import { Button } from "antd";
import { inject, observer } from "mobx-react";
import { getSearchs } from "../../../../util";
import { salaryDetailSearchConditions } from "../conditions";
import { getTaxAgentSelectList } from "../../../../apis/taxAgent";
const getLabel = WeaLocaleProvider.getLabel;
const getKey = WeaTools.getKey;
@inject("attendanceStore")
@observer
class SalaryDetailAdvanceSearchPannel extends Component {
constructor(props) {
super(props);
this.state = {
searchConditions: []
};
}
async componentDidMount() {
const [{ data: taxAgentList }] = await Promise.all([getTaxAgentSelectList()]);
this.setState({
searchConditions: _.map(salaryDetailSearchConditions, item => {
return {
...item,
items: _.map(item.items, child => {
if (getKey(child) === "taxAgentIds") {
return {
...child, options: _.map(taxAgentList, o => ({ key: o.id, showname: o.content }))
};
}
return { ...child };
})
};
})
}, () => {
const { attendanceStore: { salaryDetailSearchForm } } = this.props;
salaryDetailSearchForm.initFormFields(this.state.searchConditions);
});
}
render() {
const { searchConditions } = this.state;
const { attendanceStore: { salaryDetailSearchForm } } = this.props;
return (
<React.Fragment>
<div className="wea-advanced-searchsAd">
{getSearchs(salaryDetailSearchForm, searchConditions, 2, false)}
</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={() => salaryDetailSearchForm.resetForm()}>{getLabel(2022, "重置")}</Button>
</span>
<span style={{ marginLeft: 15 }}>
<Button type="ghost" onClick={this.props.onCancel}>{getLabel(31129, "取消")}</Button>
</span>
</div>
</div>
</React.Fragment>
);
}
}
export default SalaryDetailAdvanceSearchPannel;

View File

@ -7,19 +7,24 @@
import React, { Component } from "react";
import { inject, observer } from "mobx-react";
import { WeaDatePicker, WeaInputSearch, WeaLocaleProvider, WeaReqTop } from "ecCom";
import { Button } from "antd";
import { Button, Dropdown, Menu } from "antd";
import { condition, reportCondition } from "./components/conditions";
import { commonEnumList, reportGetForm } from "../../apis/ruleconfig";
import { dimensionGetForm } from "../../apis/statistics";
import EmployeeDetails from "./components/employeeDetails";
import SalaryDetails from "./components/salaryDetails";
import StatisticsModal from "./components/statisticsModal";
import DimensionSlide from "./components/dimensionSlide";
import DimensionTable from "./components/dimensionTable";
import ReportList from "./components/reportList";
import ReportForm from "./components/reportForm";
import moment from "moment";
import "./index.less";
import LogDialog from "../../components/logViewModal";
import { MonthRangePicker } from "../reportView/components/statisticalMicroSettingsSlide";
import AdvanceInputBtn from "./components/advanceInputBtn";
import SearchPannel from "./components/searchPannel";
import moment from "moment";
import cs from "classnames";
import "./index.less";
const { getLabel } = WeaLocaleProvider;
@ -36,6 +41,12 @@ class Index extends Component {
reportName: "",
keyword: "",
year: moment().format("YYYY"),
dateRange: [
moment(new Date()).subtract(1, "year").startOf("year").format("YYYY-MM"),
moment(new Date()).endOf("year").format("YYYY-MM")
],
showSearchAd: false,
isQuery: false,
slideReq: {
visible: false, formId: ""
},
@ -257,12 +268,20 @@ class Index extends Component {
break;
}
};
handleOpenAdvanceSearch = () => this.setState({ showSearchAd: true });
handleAdvanceSearch = () => this.setState({ isQuery: !this.state.isQuery });
onAdSearch = () => this.setState({ showSearchAd: false, isQuery: !this.state.isQuery });
handleExportSalaryList = (key) => this.salaryRef.wrappedInstance.handleExportSalaryList(key);
render() {
const { taxAgentStore: { statisticsReportBtn }, attendanceStore: { statisticsForm, reportForm } } = this.props;
const {
taxAgentStore: { statisticsReportBtn },
attendanceStore: { statisticsForm, reportForm, tableStore }
} = this.props;
const {
selectedKey, modalReq, slideReq, conditions, reportConditions,
reportName, keyword, year, logDialogVisible, filterConditions
reportName, keyword, year, logDialogVisible, filterConditions,
dateRange, showSearchAd, isQuery
} = this.state;
const buttons = selectedKey === "statistics" ? [
<Button type="primary" onClick={() => this.handleReqBtnsClick("addReport")}>{getLabel(111, "新建报表")}</Button>,
@ -272,7 +291,7 @@ class Index extends Component {
value={reportName}
onChange={reportName => this.setState({ reportName })}
onSearch={() => this.handleReqBtnsClick("search")}/>
] : [
] : selectedKey === "statistics" ? [
<span className="employeeYearWrapper">
<span>{getLabel(111, "年薪资核算人员明细:")}</span>
<WeaDatePicker value={year} format="YYYY" onChange={year => this.setState({ year })}/>
@ -281,10 +300,38 @@ class Index extends Component {
value={keyword}
onChange={keyword => this.setState({ keyword })}
onSearch={() => this.employeeListRef.statisticsEmployeeList()}/>
] : [
<Dropdown.Button type="primary"
onClick={() => this.handleExportSalaryList("ALL")}
overlay={<Menu
onClick={({ key }) => this.handleExportSalaryList(key)}>
<Menu.Item
key="SELECTED">{getLabel(543715, "导出所选")}</Menu.Item>
</Menu>}>{getLabel(81272, "")}</Dropdown.Button>,
<MonthRangePicker dateRange={dateRange} viewAttr={2}
onChange={v => this.setState({ dateRange: v }, () => this.handleAdvanceSearch())}/>,
<AdvanceInputBtn onOpenAdvanceSearch={this.handleOpenAdvanceSearch}
onAdvanceSearch={this.handleAdvanceSearch}/>
];
const dropMenuDatas = [
{
key: "log", icon: <i className="iconfont icon-caozuorizhi32"/>,
content: getLabel(545781, "操作日志")
},
{
key: "BTN_COLUMN",
icon: <i className="icon-coms-Custom"/>,
content: getLabel(111, "显示列定制"),
onClick: () => {
tableStore.setColSetVisible(true);
tableStore.tableColSet(true);
}
}
];
const tabs = [
{ key: "statistics", title: getLabel(111, "统计表") },
{ key: "detail", title: getLabel(111, "员工明细") }
{ key: "detail", title: getLabel(111, "员工明细") },
{ key: "salaryDetail", title: getLabel(111, "薪资明细") }
];
return (
<WeaReqTop
@ -293,13 +340,11 @@ class Index extends Component {
buttons={(!statisticsReportBtn && selectedKey === "statistics") ? buttons.slice(-1) : buttons} buttonSpace={10}
onChange={selectedKey => this.setState({ selectedKey }, () => this.state.selectedKey === "statistics" && this.initReportFormCondition())}
onDropMenuClick={this.onDropMenuClick}
dropMenuDatas={[
{
key: "log", icon: <i className="iconfont icon-caozuorizhi32"/>,
content: getLabel(545781, "操作日志")
}
]}
dropMenuDatas={selectedKey !== "salaryDetail" ? _.filter(dropMenuDatas, o => o.key !== "BTN_COLUMN") : dropMenuDatas}
>
<div className={cs("searchAdvanced-condition-container", { "searchAdvanced-condition-hide": !showSearchAd })}>
<SearchPannel onCancel={() => this.setState({ showSearchAd: false })} onAdSearch={this.onAdSearch}/>
</div>
{
selectedKey === "statistics" ?
<ReportList
@ -307,11 +352,11 @@ class Index extends Component {
reportName={reportName}
onEdit={this.handleReqBtnsClick}
onFilterLog={(type, targetid) => this.onDropMenuClick(type, targetid)}
/> : <EmployeeDetails
/> : selectedKey === "detail" ? <EmployeeDetails
ref={dom => this.employeeListRef = dom}
keyword={keyword} year={year}
onFilterLog={(type, targetid) => this.onDropMenuClick(type, targetid)}
/>
/> : <SalaryDetails ref={dom => this.salaryRef = dom} dateRange={dateRange} isQuery={isQuery}/>
}
<StatisticsModal {...modalReq} onCancel={this.handleCancel} form={reportForm} onClose={this.handleCancel}
onAddDimension={this.handleAddDimension}

View File

@ -15,10 +15,13 @@
}
.wea-new-top-req-content {
background: #FFF;
padding: 16px;
.wea-new-table {
background: #FFF;
}
.reportRow {
padding: 16px;
.gutter-row {
margin-bottom: 16px;
@ -32,6 +35,7 @@
padding: 22px 0 22px 16px;
border: 1px solid #e5e5e5;
position: relative;
background: #FFF;
.ant-ribbon {
padding: 0 8px;
@ -161,6 +165,56 @@
margin-top: 26px;
}
}
.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: 155px;
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
}
}
}
}
.table-layout {
.ant-spin-nested-loading, .ant-spin-container {
height: 100%;
}
}
}
.zIndex0-statistics {

View File

@ -151,6 +151,19 @@ export const condition = [
labelcol: 6,
viewAttr: 2
},
{
colSpan: 2,
checkbox: false,
checkboxValue: false,
conditionType: "SELECT",
domkey: ["status"],
fieldcol: 18,
label: getLabel(111, "人事状态"),
labelcol: 6,
options: [],
multiple: true,
viewAttr: 2
},
{
colSpan: 2,
conditionType: "RANGEPICKER",

View File

@ -70,7 +70,7 @@ class StatisticalMicroSettingsSlide extends Component {
}
getTaxAgentSelectList = async (props) => {
const { data: salarySobList } = await getSalarysobListAll();
const [salarySobList, empStatusList] = await Promise.all([getSalarysobListAll(), commonEnumList({ enumClass: "com.engine.salary.enums.salarysob.SalaryEmployeeStatusEnum" })]);
getTaxAgentSelectList(true).then(({ status, data }) => {
if (status) {
const conditions = _.map(condition, item => {
@ -85,7 +85,12 @@ class StatisticalMicroSettingsSlide extends Component {
} else if (getKey(child) === "salarySob") {
return {
...child, viewAttr: props.isShare ? 1 : child.viewAttr,
options: _.map(salarySobList, o => ({ key: String(o.id), showname: o.name }))
options: _.map(salarySobList.data, o => ({ key: String(o.id), showname: o.name }))
};
} else if (getKey(child) === "status") {
return {
...child, viewAttr: props.isShare ? 1 : child.viewAttr,
options: _.map(empStatusList.data, o => ({ key: o.value.toString(), showname: o.defaultLabel }))
};
}
return { ...child, viewAttr: props.isShare ? 1 : child.viewAttr };
@ -131,8 +136,9 @@ class StatisticalMicroSettingsSlide extends Component {
const { salaryMonth, timeType, dataSource } = this.state;
const { form, id, dimension, onClose } = this.props;
const [salaryStartMonth, salaryEndMonth] = salaryMonth;
const { department, employee, position, subCompany, taxAgent, salarySob, ...extra } = form.getFormDatas();
const { department, employee, position, subCompany, taxAgent, salarySob, status, ...extra } = form.getFormDatas();
const { value, valueSpan } = taxAgent;
const { value: statusVal, valueSpan: statusValSpan } = status;
const { value: sobValue, valueSpan: sobValueSpan } = salarySob;
if (!salaryEndMonth || !salaryStartMonth) {
this.refs.weaError.showError();
@ -146,6 +152,10 @@ class StatisticalMicroSettingsSlide extends Component {
// position: _.map(position.valueObj, it => ({ id: it.id, name: it.name })),
subCompany: _.map(subCompany.valueObj, it => ({ id: it.id, name: it.name })),
taxAgent: value ? _.map(value.split(","), (it, idx) => ({ id: it, name: valueSpan.split(",")[idx] })) : [],
status: statusVal ? _.map(statusVal.split(","), (it, idx) => ({
id: it,
name: statusValSpan.split(",")[idx]
})) : [],
salarySob: sobValue ? _.map(sobValue.split(","), (it, idx) => ({
id: it,
name: sobValueSpan.split(",")[idx]

View File

@ -43,6 +43,11 @@ class RuleConfig extends Component {
return { ...o, options: _.map(optionsList[getKey(o)], g => ({ key: g.value, showname: g.defaultLabel })) };
} else if (getKey(o) === "OPEN_APPLICATION_ENCRYPT") {
return { ...o, viewAttr: sysinfo.showEncryptOperationButton === "true" ? 2 : 1 };
} else if (getKey(o) === "taxDeclarationFunction") {
return {
...o,
viewAttr: (_.isNil(sysinfo.taxDeclarationFunction) || sysinfo.taxDeclarationFunction !== "0") ? 2 : 1
};
}
return { ...o };
})
@ -189,6 +194,7 @@ class RuleConfig extends Component {
API.operateTaxDeclarationFunction({ operateTaxDeclaration }).then(({ status, errormsg }) => {
if (status) {
message.success(getLabel(22619, "保存成功!"));
const promise = this.init();
} else {
message.error(errormsg || getLabel(22620, "保存失败!"));
}

View File

@ -0,0 +1,190 @@
/*
* Author: 黎永顺
* name: 补算
* Description:
* Date: 2024/3/26
*/
import React, { Component } from "react";
import { Button, message } from "antd";
import { WeaBrowser, WeaError, WeaFormItem, WeaLocaleProvider, WeaSearchGroup, WeaSelect, WeaTop } from "ecCom";
import { supplementAcctRecord } from "../../apis";
import "./index.less";
const { getLabel } = WeaLocaleProvider;
class Index extends Component {
constructor(props) {
super(props);
this.state = {
type: "sob", salaryItemIds: "", salarySobIds: "",
salaryAcctRecordIds: "", loading: false
};
}
handleChangeItems = (key, value) => {
this.setState({ [key]: value });
};
handleSubmit = () => {
const { salaryItemIds, salarySobIds, salaryAcctRecordIds, type } = this.state;
if (!salaryItemIds && !salarySobIds && type === "sob") {
this.refs.salaryItemError.showError();
this.refs.salarySobError.showError();
return;
}
if (!salaryItemIds && !salaryAcctRecordIds && type === "record") {
this.refs.salaryItemError.showError();
this.refs.salaryPigeonholeError.showError();
return;
}
if (!salaryItemIds) {
this.refs.salaryItemError.showError();
return;
}
if (!salaryAcctRecordIds && type === "record") {
this.refs.salaryPigeonholeError.showError();
return;
}
if (!salarySobIds && type === "sob") {
this.refs.salarySobError.showError();
return;
}
this.setState({ loading: true });
supplementAcctRecord({
type,
salaryAcctRecordIds: salaryAcctRecordIds ? salaryAcctRecordIds.split(",") : [],
salarySobIds: salarySobIds ? salarySobIds.split(",") : [],
salaryItemIds: salaryItemIds ? salaryItemIds.split(",") : []
}).then(({ status, errormsg }) => {
this.setState({ loading: false });
if (status) {
message.success(getLabel(111, "补算成功"));
} else {
message.error(errormsg || getLabel(111, "补算失败"));
}
}).catch(() => this.setState({ loading: false }));
};
render() {
const { type, salaryItemIds, salarySobIds, salaryAcctRecordIds, loading } = this.state;
return (
<WeaTop
title={getLabel(111, "补算")} iconBgcolor="#F14A2D" showDropIcon={false}
icon={<i className="icon-coms-fa"/>}
buttons={[
<Button type="primary" onClick={this.handleSubmit} loading={loading}>{getLabel(111, "补算")}</Button>
]}
>
<div className="retroactiveWrapper">
<WeaSearchGroup showGroup needTigger={false} center>
<WeaFormItem label={getLabel(111, "补算维度")} labelCol={{ span: 6 }} wrapperCol={{ span: 18 }}>
<WeaError tipPosition="bottom" ref="typeError" error={getLabel(111, "此项必填")}>
<WeaSelect
options={[
{ key: "sob", showname: "按薪资账套维度" },
{ key: "record", showname: "按核算记录维度" }
]}
detailtype={3} value={type} viewAttr={3}
onChange={type => this.setState({ type }, () => {
this.setState({ salarySobIds: "", salaryAcctRecordIds: "", salaryItemIds: "" });
})}
/>
</WeaError>
</WeaFormItem>
{
type === "sob" ?
<WeaFormItem label={getLabel(111, "薪资账套")} labelCol={{ span: 6 }} wrapperCol={{ span: 18 }}>
<WeaError tipPosition="bottom" ref="salarySobError" error={getLabel(111, "此项必填")}>
<WeaBrowser
title={getLabel(111, "薪资账套")}
type={162} viewAttr={3} isSingle={false}
value={salarySobIds} isMultCheckbox
completeParams={{
type: 162,
fielddbtype: "browser.salarySobBrowser",
f_weaver_belongto_usertype: "0"
}}
conditionDataParams={{
type: "browser.salarySobBrowser",
fielddbtype: "browser.salarySobBrowser",
f_weaver_belongto_usertype: "0"
}}
dataParams={{
type: "browser.salarySobBrowser",
f_weaver_belongto_usertype: "0"
}}
destDataParams={{
type: "browser.salarySobBrowser",
f_weaver_belongto_usertype: "0"
}}
inputStyle={{ width: "100%" }}
onChange={(salarySobIds) => this.handleChangeItems("salarySobIds", salarySobIds)}
/>
</WeaError>
</WeaFormItem> :
<WeaFormItem label={getLabel(111, "薪资核算归档记录")} labelCol={{ span: 6 }} wrapperCol={{ span: 18 }}>
<WeaError tipPosition="bottom" ref="salaryPigeonholeError" error={getLabel(111, "此项必填")}>
<WeaBrowser
title={getLabel(111, "薪资核算归档记录")}
type={162} viewAttr={3} isSingle={false}
value={salaryAcctRecordIds} isMultCheckbox
completeParams={{
type: 162,
fielddbtype: "browser.salaryAcctArchivedRecordBrowser",
f_weaver_belongto_usertype: "0"
}}
conditionDataParams={{
type: "browser.salaryAcctArchivedRecordBrowser",
fielddbtype: "browser.salaryAcctArchivedRecordBrowser",
f_weaver_belongto_usertype: "0"
}}
dataParams={{
type: "browser.salaryAcctArchivedRecordBrowser",
f_weaver_belongto_usertype: "0"
}}
destDataParams={{
type: "browser.salaryAcctArchivedRecordBrowser",
f_weaver_belongto_usertype: "0"
}}
inputStyle={{ width: "100%" }}
onChange={(salaryAcctRecordIds) => this.handleChangeItems("salaryAcctRecordIds", salaryAcctRecordIds)}
/>
</WeaError>
</WeaFormItem>
}
<WeaFormItem label={getLabel(111, "薪资项目")} labelCol={{ span: 6 }} wrapperCol={{ span: 18 }}>
<WeaError tipPosition="bottom" ref="salaryItemError" error={getLabel(111, "此项必填")}>
<WeaBrowser
title={getLabel(111, "薪资项目")}
type={162} viewAttr={3} isSingle={false}
value={salaryItemIds} isMultCheckbox
completeParams={{
type: 162,
fielddbtype: "browser.salaryItemBrowser",
f_weaver_belongto_usertype: "0"
}}
conditionDataParams={{
type: "browser.salaryItemBrowser",
fielddbtype: "browser.salaryItemBrowser",
f_weaver_belongto_usertype: "0"
}}
dataParams={{
type: "browser.salaryItemBrowser",
f_weaver_belongto_usertype: "0"
}}
destDataParams={{
type: "browser.salaryItemBrowser",
f_weaver_belongto_usertype: "0"
}}
inputStyle={{ width: "100%" }}
onChange={(salaryItemIds) => this.handleChangeItems("salaryItemIds", salaryItemIds)}
/>
</WeaError>
</WeaFormItem>
</WeaSearchGroup>
</div>
</WeaTop>
);
}
}
export default Index;

View File

@ -0,0 +1,7 @@
.retroactiveWrapper {
height: 100%;
.wea-error {
width: 100%;
}
}

View File

@ -1,6 +1,7 @@
import { action, observable } from "mobx";
import { WeaForm } from "comsMobx";
import { WeaForm, WeaTableNew } from "comsMobx";
const { TableStore } = WeaTableNew;
export class AttendanceStore {
@observable form = new WeaForm();
@ -13,6 +14,8 @@ export class AttendanceStore {
//报表查看 统计数据范围及规则设置form
@observable settingForm = new WeaForm();
//报表查看 分享报表
@observable salaryDetailSearchForm = new WeaForm();
@observable tableStore = new TableStore();//薪资明细表格仓库
@observable shareForm = new WeaForm();
@observable shareLogForm = new WeaForm();
@observable sharePerForm = new WeaForm();

View File

@ -138,7 +138,7 @@ export const getIframeParentHeight = (selector, total, extraHeight) => {
const dom = document.querySelector(selector);
let height = 280;
if (dom && total > 0) {
height = (parseFloat(dom.style.height) > 620 && total === 10) ? total * 48 + 108: total < 10 ? total * 48 + 108 : parseFloat(dom.style.height) - extraHeight;
height = (parseFloat(dom.style.height) > 620 && total === 10) ? total * 48 + 108 : total < 10 ? (total + 1) * 48 + 108 : parseFloat(dom.style.height) - extraHeight;
}
return height;
};