389 lines
16 KiB
JavaScript
389 lines
16 KiB
JavaScript
/*
|
||
* Author: 黎永顺
|
||
* name: 薪酬统计分析
|
||
* Description:
|
||
* Date: 2023/4/10
|
||
*/
|
||
import React, { Component } from "react";
|
||
import { inject, observer } from "mobx-react";
|
||
import { WeaDatePicker, WeaInputSearch, WeaLocaleProvider, WeaReqTop } from "ecCom";
|
||
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 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;
|
||
|
||
@inject("taxAgentStore", "attendanceStore")
|
||
@observer
|
||
class Index extends Component {
|
||
constructor(props) {
|
||
super(props);
|
||
this.state = {
|
||
conditions: [],
|
||
convertConditions: [],
|
||
reportConditions: [],
|
||
selectedKey: "statistics",
|
||
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: ""
|
||
},
|
||
modalReq: {
|
||
title: "", visible: false,
|
||
typeKey: "", id: ""
|
||
},
|
||
logDialogVisible: false, filterConditions: "[]"
|
||
};
|
||
}
|
||
|
||
componentDidMount() {
|
||
this.initReportFormCondition();
|
||
}
|
||
|
||
initReportFormCondition = (payload = {}) => {
|
||
const { attendanceStore: { reportForm } } = this.props;
|
||
reportGetForm(payload).then(({ status, data }) => {
|
||
if (status) {
|
||
const { statsDimOptions, data: detailData } = data;
|
||
if (_.isEmpty(payload)) {
|
||
this.setState({
|
||
reportConditions: _.map(reportCondition, item => {
|
||
return {
|
||
...item,
|
||
items: _.map(item.items, child => {
|
||
if (child.domkey[0] === "dimensionIds") {
|
||
return {
|
||
...child,
|
||
options: _.map(statsDimOptions, dimTypeItem => ({
|
||
key: dimTypeItem.id,
|
||
showname: dimTypeItem.content
|
||
}))
|
||
};
|
||
}
|
||
return { ...child };
|
||
})
|
||
};
|
||
})
|
||
}, () => {
|
||
reportForm.initFormFields(this.state.reportConditions);
|
||
});
|
||
} else {
|
||
reportForm.updateFields({
|
||
reportName: detailData.reportName,
|
||
dimensionIds: detailData.dimension.join(",")
|
||
});
|
||
}
|
||
}
|
||
});
|
||
};
|
||
initCondition = async () => {
|
||
const { attendanceStore: { statisticsForm } } = this.props;
|
||
const [dimTypeEnum, dimCodeList] = await Promise.all([this.commonEnumList(), this.dimensionGetForm()]);
|
||
const { data: dimTypeData } = dimTypeEnum, { data: dimCodeData } = dimCodeList;
|
||
const { baseForm: { statsDimOptions, groupDimOptions, data: dimTypeValue } } = dimCodeData;
|
||
this.setState({
|
||
conditions: _.map(condition, item => {
|
||
return {
|
||
...item,
|
||
items: _.map(item.items, child => {
|
||
if (child.domkey[0] === "dimType") {
|
||
return {
|
||
...child,
|
||
value: dimTypeValue.dimType,
|
||
options: _.map(dimTypeData, dimTypeItem => ({
|
||
key: dimTypeItem.value,
|
||
showname: dimTypeItem.defaultLabel
|
||
}))
|
||
};
|
||
}
|
||
if (child.domkey[0] === "setting4Qualitative") {
|
||
return {
|
||
...child,
|
||
options: _.map(statsDimOptions, dimCodeItem => ({
|
||
key: dimCodeItem.id,
|
||
showname: dimCodeItem.content
|
||
}))
|
||
};
|
||
}
|
||
if (child.domkey[0] === "dimCode") {
|
||
return {
|
||
...child,
|
||
options: _.map(groupDimOptions, dimCodeItem => ({
|
||
key: dimCodeItem.id,
|
||
showname: dimCodeItem.content
|
||
}))
|
||
};
|
||
}
|
||
return { ...child };
|
||
})
|
||
};
|
||
})
|
||
}, () => {
|
||
this.setState({ convertConditions: this.state.conditions });
|
||
statisticsForm.initFormFields(this.state.conditions);
|
||
});
|
||
};
|
||
commonEnumList = () => {
|
||
const payload = {
|
||
enumClass: "com.engine.salary.report.enums.SalaryStatisticsDimensionTypeEnum"
|
||
};
|
||
return commonEnumList(payload);
|
||
};
|
||
dimensionGetForm = () => {
|
||
return dimensionGetForm();
|
||
};
|
||
handleChangeCondition = (val, viewAttr) => {
|
||
const { attendanceStore: { statisticsForm } } = this.props;
|
||
const helpfulTitle = val === "RATION_GROUP_SPACING" ?
|
||
"例:\n" +
|
||
" 若:所属字段为【工龄】,分组设置为【0-5】,【5-10】;统计项为【税前薪资】,对应的统计规则为【求和】; 则统计结果为:【工龄】为【0-5】的所有人的【税前薪资】求和,【工龄】为【5-10】的所有人的【税前薪资】求和;\n" +
|
||
"若:未选择所属字段,分组设置为【0-10,000.00】,【10,000.00-20,000.00】;若统计项为【税前薪资】,对应的统计规则为【计数】; 则统计结果为:【税前薪资】为【0-10,000.00】有多少人,【税前薪资】为【10,000.00-20,000.00】有多少人;" :
|
||
val === "RATION_GROUP_INDIVIDUAL" ?
|
||
"例:\n" +
|
||
" 若:所属字段为【职级】,分组设置为【1】,【2】,【3】;统计项为【税前薪资】,对应的统计规则为【平均值】; 则统计结果为:【职级】为【1】的所有人的【税前薪资】的平均值,【职级】为【2】的所有人的【税前薪资】的平均值;【职级】为【3】的所有人的【税前薪资】的平均值;\n" +
|
||
"若:未选择所属字段,分组设置为【1】,【2】,【3】;若统计项为【绩效】,对应的统计规则为【计数】; 则统计结果为:【绩效】为【1】有多少人,绩效为【2】有多少人,绩效为【3】有多少人;" : "";
|
||
|
||
if (val === "QUALITATIVE") {
|
||
this.setState({
|
||
conditions: _.map(this.state.convertConditions, item => {
|
||
return {
|
||
...item,
|
||
items: _.map(_.filter(item.items, child => child.domkey[0] !== "dimCode"), it => {
|
||
if (it.domkey[0] === "dimType") {
|
||
return { ...it, value: val, viewAttr: viewAttr ? viewAttr : it.viewAttr };
|
||
}
|
||
return { ...it };
|
||
})
|
||
};
|
||
})
|
||
}, () => {
|
||
statisticsForm.setCondition(this.state.conditions);
|
||
});
|
||
} else {
|
||
this.setState({
|
||
conditions: _.map(this.state.convertConditions, item => {
|
||
return {
|
||
...item,
|
||
items: _.map(_.filter(item.items, child => child.domkey[0] !== "setting4Qualitative"), it => {
|
||
if (it.domkey[0] === "dimType") {
|
||
return { ...it, value: val, viewAttr: viewAttr ? viewAttr : it.viewAttr };
|
||
} else if (it.domkey[0] === "dimCode") {
|
||
return { ...it, helpfulTitle };
|
||
}
|
||
return { ...it };
|
||
})
|
||
};
|
||
})
|
||
}, () => {
|
||
statisticsForm.setCondition(this.state.conditions);
|
||
});
|
||
}
|
||
};
|
||
handleReqBtnsClick = (key, id = "") => {
|
||
if (key === "search") {
|
||
const { reportName } = this.state;
|
||
this.reportListRef.reportStatisticsReportList({ reportName });
|
||
} else {
|
||
const { modalReq } = this.state;
|
||
const title = key === "dimension" ?
|
||
<div className="dimensionTitle">
|
||
<span>{getLabel(111, "统计维度管理")}</span>
|
||
<Button type="primary" onClick={() => this.handleAddDimension()}>{getLabel(111, "新建统计维度")}</Button>
|
||
</div>
|
||
: getLabel(111, id ? "编辑报表" : "新建报表");
|
||
this.setState({
|
||
modalReq: {
|
||
...modalReq, id, title,
|
||
visible: true, typeKey: key
|
||
}
|
||
}, () => id && this.initReportFormCondition({ id }));
|
||
}
|
||
};
|
||
handleCancel = (refresh = false) => {
|
||
const { attendanceStore: { reportForm } } = this.props;
|
||
const { modalReq } = this.state;
|
||
this.setState({
|
||
modalReq: {
|
||
...modalReq, visible: false, id: ""
|
||
}
|
||
}, () => {
|
||
const { selectedKey, reportName, modalReq: { typeKey } } = this.state;
|
||
selectedKey === "statistics" && reportForm.resetForm();
|
||
typeKey === "dimension" && this.initReportFormCondition();
|
||
refresh && selectedKey === "statistics" && this.reportListRef.reportStatisticsReportList({ reportName });
|
||
});
|
||
};
|
||
handleAddDimension = (formId = "") => {
|
||
const { slideReq } = this.state;
|
||
this.setState({
|
||
slideReq: {
|
||
...slideReq, visible: true,
|
||
formId
|
||
}
|
||
});
|
||
};
|
||
handleClose = (initTable = false) => {
|
||
const { attendanceStore: { statisticsForm } } = this.props;
|
||
const { slideReq } = this.state;
|
||
this.setState({
|
||
slideReq: {
|
||
...slideReq, visible: false, formId: ""
|
||
}
|
||
}, () => {
|
||
statisticsForm.resetForm();
|
||
initTable && this.dimensionTableRef.dimensionList();
|
||
});
|
||
};
|
||
onDropMenuClick = (key, targetid = "") => {
|
||
switch (key) {
|
||
case "log":
|
||
this.setState({
|
||
logDialogVisible: true,
|
||
filterConditions: targetid ? `[{\"connectCondition\":\"AND\",\"columIndex\":\"targetid\",\"type\":\"=\",\"value\":\"${targetid}\"}]` : "[]"
|
||
});
|
||
break;
|
||
default:
|
||
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, tableStore }
|
||
} = this.props;
|
||
const {
|
||
selectedKey, modalReq, slideReq, conditions, reportConditions,
|
||
reportName, keyword, year, logDialogVisible, filterConditions,
|
||
dateRange, showSearchAd, isQuery
|
||
} = this.state;
|
||
const buttons = selectedKey === "statistics" ? [
|
||
<Button type="primary" onClick={() => this.handleReqBtnsClick("addReport")}>{getLabel(111, "新建报表")}</Button>,
|
||
<Button type="ghost"
|
||
onClick={() => this.handleReqBtnsClick("dimension")}>{getLabel(111, "维度统计管理")}</Button>,
|
||
<WeaInputSearch placeholder={getLabel(111, "请输入报表名称")} className="search"
|
||
value={reportName}
|
||
onChange={reportName => this.setState({ reportName })}
|
||
onSearch={() => this.handleReqBtnsClick("search")}/>
|
||
] : selectedKey === "detail" ? [
|
||
<span className="employeeYearWrapper">
|
||
<span>{getLabel(111, "年薪资核算人员明细:")}</span>
|
||
<WeaDatePicker value={year} format="YYYY" onChange={year => this.setState({ year })}/>
|
||
</span>,
|
||
<WeaInputSearch placeholder={getLabel(111, "请输入姓名、工号、身份证号")} className="search"
|
||
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: "salaryDetail", title: getLabel(111, "薪资明细") }
|
||
];
|
||
return (
|
||
<WeaReqTop
|
||
title={getLabel(111, "薪酬统计报表")} icon={<i className="icon-coms-fa"/>} selectedKey={selectedKey}
|
||
iconBgcolor="#F14A2D" tabDatas={tabs} className="xc_tj_fx_wrapper"
|
||
buttons={(!statisticsReportBtn && selectedKey === "statistics") ? buttons.slice(-1) : buttons} buttonSpace={10}
|
||
onChange={selectedKey => this.setState({ selectedKey }, () => this.state.selectedKey === "statistics" && this.initReportFormCondition())}
|
||
showDropIcon={selectedKey !== "detail"} onDropMenuClick={this.onDropMenuClick}
|
||
dropMenuDatas={selectedKey === "salaryDetail" ? dropMenuDatas.slice(-1) : dropMenuDatas.slice(0, 1)}
|
||
>
|
||
<div className={cs("searchAdvanced-condition-container", { "searchAdvanced-condition-hide": !showSearchAd })}>
|
||
<SearchPannel onCancel={() => this.setState({ showSearchAd: false })} onAdSearch={this.onAdSearch}/>
|
||
</div>
|
||
{
|
||
selectedKey === "statistics" ?
|
||
<ReportList
|
||
ref={dom => this.reportListRef = dom}
|
||
reportName={reportName}
|
||
onEdit={this.handleReqBtnsClick}
|
||
onFilterLog={(type, targetid) => this.onDropMenuClick(type, targetid)}
|
||
/> : 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}
|
||
>
|
||
{
|
||
modalReq.typeKey === "dimension" &&
|
||
<DimensionTable ref={dom => this.dimensionTableRef = dom}
|
||
onEdit={id => this.handleAddDimension(id)}
|
||
/>
|
||
}
|
||
{
|
||
modalReq.typeKey === "addReport" &&
|
||
<ReportForm form={reportForm} condition={reportConditions}/>
|
||
}
|
||
</StatisticsModal>
|
||
<DimensionSlide
|
||
{...slideReq} onCancel={this.handleClose}
|
||
form={statisticsForm} condition={conditions}
|
||
initCondition={this.initCondition} onChangeCondition={this.handleChangeCondition}
|
||
/>
|
||
{/*操作日志*/}
|
||
<LogDialog visible={logDialogVisible} logFunction="statreport" filterConditions={filterConditions}
|
||
onCancel={() => this.setState({ logDialogVisible: false })}/>
|
||
</WeaReqTop>
|
||
);
|
||
}
|
||
}
|
||
|
||
export default Index;
|