产品-薪酬统计分析管理

This commit is contained in:
黎永顺 2023-04-23 11:28:18 +08:00
parent 7c60a44e66
commit 8f3320ae11
13 changed files with 1004 additions and 10 deletions

View File

@ -5,6 +5,14 @@ import { postFetch } from "../util/request";
export const dimensionGetForm = (params) => {
return WeaTools.callApi("/api/bs/hrmsalary/report/statistics/dimension/getForm", "GET", params);
};
//获取自定义统计项目表单
export const statisticsItemGetform = (params) => {
return WeaTools.callApi("/api/bs/hrmsalary/report/statistics/item/getForm", "GET", params);
};
//自定义统计项目列表
export const statisticsItemList = (params) => {
return WeaTools.callApi("/api/bs/hrmsalary/report/statistics/item/list", "GET", params);
};
// 保存薪酬统计维度
export const dimensionSave = (params) => {
return postFetch("/api/bs/hrmsalary/report/statistics/dimension/save", params);
@ -30,3 +38,7 @@ export const reportStatisticsReportDelete = (params) => {
export const reportStatisticsReportGetData = (params) => {
return postFetch("/api/bs/hrmsalary/report/statistics/report/getData", params);
};
//保存自定义统计项目
export const reportStatisticsItemSave = (params) => {
return postFetch("/api/bs/hrmsalary/report/statistics/item/save", params);
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@ -0,0 +1,153 @@
import { WeaLocaleProvider } from "ecCom";
const { getLabel } = WeaLocaleProvider;
export const condition = [
{
items: [
{
colSpan: 2,
checkbox: false,
checkboxValue: false,
conditionType: "SELECT",
domkey: ["taxAgent"],
fieldcol: 18,
label: getLabel(111, "个税扣缴义务人"),
labelcol: 6,
options: [],
multiple: true,
viewAttr: 2
},
{
browserConditionParam: {
completeParams: {},
conditionDataParams: {},
dataParams: {},
destDataParams: {},
hasAddBtn: false,
hasAdvanceSerach: true,
idSeparator: ",",
isAutoComplete: 1,
isDetail: 0,
isMultCheckbox: false,
isSingle: false,
linkUrl: "",
pageSize: 10,
quickSearchName: "",
replaceDatas: [],
title: getLabel(111, "分部"),
type: "164",
viewAttr: 2
},
colSpan: 2,
conditionType: "BROWSER",
domkey: ["subCompany"],
fieldcol: 18,
isQuickSearch: false,
label: getLabel(111, "分部"),
labelcol: 6,
viewAttr: 2
},
{
browserConditionParam: {
completeParams: {},
conditionDataParams: {},
dataParams: {},
destDataParams: {},
hasAddBtn: false,
hasAdvanceSerach: true,
idSeparator: ",",
isAutoComplete: 1,
isDetail: 0,
isMultCheckbox: false,
isSingle: false,
linkUrl: "",
pageSize: 10,
quickSearchName: "",
replaceDatas: [],
title: getLabel(111, "部门"),
type: "57",
viewAttr: 2
},
colSpan: 2,
conditionType: "BROWSER",
domkey: ["department"],
fieldcol: 18,
isQuickSearch: false,
label: getLabel(111, "部门"),
labelcol: 6,
viewAttr: 2
},
{
browserConditionParam: {
completeParams: {},
conditionDataParams: {},
dataParams: {},
destDataParams: {},
hasAddBtn: false,
hasAdvanceSerach: true,
idSeparator: ",",
isAutoComplete: 1,
isDetail: 0,
isMultCheckbox: false,
isSingle: false,
linkUrl: "",
pageSize: 10,
quickSearchName: "",
replaceDatas: [],
title: getLabel(111, "岗位"),
type: "278",
viewAttr: 2
},
colSpan: 2,
conditionType: "BROWSER",
domkey: ["position"],
fieldcol: 18,
isQuickSearch: false,
label: getLabel(111, "岗位"),
labelcol: 6,
viewAttr: 2
},
{
browserConditionParam: {
completeParams: {},
conditionDataParams: {},
dataParams: {},
destDataParams: {},
hasAddBtn: false,
hasAdvanceSerach: true,
idSeparator: ",",
isAutoComplete: 1,
isDetail: 0,
isMultCheckbox: false,
isSingle: false,
linkUrl: "",
pageSize: 10,
quickSearchName: "",
replaceDatas: [],
title: getLabel(111, "人员"),
type: "17",
viewAttr: 2
},
colSpan: 2,
conditionType: "BROWSER",
domkey: ["employee"],
fieldcol: 18,
isQuickSearch: false,
label: getLabel(111, "人员"),
labelcol: 6,
viewAttr: 2
},
{
colSpan: 2,
conditionType: "RANGEPICKER",
domkey: ["hiredate"],
fieldcol: 18,
label: getLabel(111, "入职日期"),
labelcol: 6,
viewAttr: 2
}
],
title: "",
defaultshow: true
}
];

View File

@ -0,0 +1,205 @@
/*
* Author: 黎永顺
* name: 新建自定义统计项目弹框
* Description:
* Date: 2023/4/10
*/
import React, { Component } from "react";
import { Button } from "antd";
import {
WeaCheckbox,
WeaDialog,
WeaError,
WeaFormItem,
WeaHelpfulTip,
WeaInput,
WeaInputNumber,
WeaLocaleProvider,
WeaTable
} from "ecCom";
import { statisticsItemGetform } from "../../../apis/statistics";
import "../index.less";
const { getLabel } = WeaLocaleProvider;
class CustomStatisticsItemsModal extends Component {
constructor(props) {
super(props);
this.state = {
loading: false,
columns: [],
dataSource: [],
formData: {}
};
}
componentWillReceiveProps(nextProps, nextContext) {
if (nextProps.visible !== this.props.visible && nextProps.visible) {
this.statisticsItemGetform();
}
}
statisticsItemGetform = (payload) => {
statisticsItemGetform(payload).then(({ status, data }) => {
if (status) {
const { ruleData } = data;
const { columns, data: dataSource } = ruleData;
this.setState({ columns, dataSource });
}
});
};
handleChangeColumnCheckBox = (key, value, id) => {
const { dataSource } = this.state;
this.setState({
dataSource: _.map(dataSource, it => {
if (it.id === id) {
return {
...it,
[key]: Number(value)
};
}
return { ...it };
})
});
};
handleChangeColumnAllChecked = (key, val) => {
const { dataSource } = this.state;
this.setState({
dataSource: _.map(dataSource, it => {
return {
...it,
[key]: Number(val)
};
})
});
};
handleChangeColumnM2MValue = (key, value, id) => {
const { dataSource } = this.state;
this.setState({
dataSource: _.map(dataSource, it => {
if (it.id === id) {
return {
...it,
[key]: value
};
}
return { ...it };
})
});
};
render() {
const { loading, columns, dataSource, formData } = this.state;
const { itemName } = formData;
const cols = _.map(columns, it => {
const { text, column } = it;
if (column === "ruleName" || column === "ratio" || column === "m2m" || column === "y2y") {
const key = column === "ruleName" ? "total" : column;
return {
...it,
title: <span>
<WeaCheckbox
value={_.every(dataSource, child => !!child[`${key}Value`])}
onChange={val => this.handleChangeColumnAllChecked(`${key}Value`, val)}
/>
<span style={{ marginLeft: 8 }}>{text}</span>
</span>,
render: (txt, record) => {
return <span>
<WeaCheckbox
value={record[`${key}Value`].toString()}
onChange={val => this.handleChangeColumnCheckBox(`${key}Value`, val, record.id)}
/>
<span style={{ marginLeft: 8 }}>
{column === "ruleName" ? record["ruleName"] : text}
</span>
</span>;
}
};
} else if (column === "m2mLimit") {
return {
...it,
title: <span>
<span style={{ marginRight: 8 }}>{text}</span>
<WeaHelpfulTip title={getLabel(111, "如:增幅>10%,差值和增幅标记为红色,增幅<-10%标记为绿色")}
placement="top" width={200}/>
</span>,
render: (txt, record) => {
return !!record["m2mValue"] && <IntervalSettingsComp
LowerLimit={record[`${column.replace("Limit", "")}LowerLimit`]}
UpperLimit={record[`${column.replace("Limit", "")}UpperLimit`]}
onChange={(type, val) => this.handleChangeColumnM2MValue(`${column.replace("Limit", "")}${type === "min" ? "LowerLimit" : "UpperLimit"}`, val, record.id)}
/>;
}
};
} else if (column === "y2yLimit") {
return {
...it,
title: <span>
<span style={{ marginRight: 8 }}>{text}</span>
<WeaHelpfulTip title={getLabel(111, "如:增幅>10%,差值和增幅标记为红色,增幅<-10%标记为绿色")}
placement="top" width={200}/>
</span>,
render: (txt, record) => {
return !!record["y2yValue"] && <IntervalSettingsComp
LowerLimit={record[`${column.replace("Limit", "")}LowerLimit`]}
UpperLimit={record[`${column.replace("Limit", "")}UpperLimit`]}
onChange={(type, val) => this.handleChangeColumnM2MValue(`${column.replace("Limit", "")}${type === "min" ? "LowerLimit" : "UpperLimit"}`, val, record.id)}
/>;
}
};
}
});
return (
<WeaDialog
{...this.props} hasScroll buttons={[]} initLoadCss
title={
<div className="itemsTitle">
<span>{getLabel(111, "新建自定义统计项目")}</span>
<Button type="primary" loading={loading}>{getLabel(111, "保存")}</Button>
</div>
}
style={{ width: 900, height: 500 }}
className="statisticItemsWrapper"
>
<div className="statisticItemsBox">
<WeaFormItem label={getLabel(111, "统计项目")} labelCol={{ span: 6 }} wrapperCol={{ span: 18 }}>
<WeaError tipPosition="bottom" ref="proError" error={getLabel(111, "此项必填")}>
</WeaError>
</WeaFormItem>
<WeaFormItem label={getLabel(111, "统计项名称")} labelCol={{ span: 6 }} wrapperCol={{ span: 18 }}>
<WeaError tipPosition="bottom" ref="nameError" error={getLabel(111, "此项必填")}>
<WeaInput
value={itemName}
viewAttr={3}/>
</WeaError>
</WeaFormItem>
<div className="customRuleTableWrapper">
<WeaTable
dataSource={dataSource}
columns={cols}
pagination={false}
/>
</div>
</div>
</WeaDialog>
);
}
}
export default CustomStatisticsItemsModal;
/*
* Author: 黎永顺
* Description: 区间设置
* Params:
* Date: 2023/4/23
*/
const IntervalSettingsComp = (props) => {
const { LowerLimit, UpperLimit, onChange } = props;
return <div className="intervalSettingsCompWrapper">
<WeaInputNumber value={LowerLimit} precision={2} onChange={val => onChange("min", val)}/>
<span className="increaseTitle">{`% <${getLabel(111, "增幅")}<`}</span>
<WeaInputNumber value={UpperLimit} precision={2} onChange={val => onChange("max", val)}/>
<span className="pecentTitle">%</span>
</div>;
};

View File

@ -37,6 +37,17 @@ class LeftTab extends Component {
});
});
};
updateReportList = (report) => {
const { reportList } = this.state;
this.setState({
reportList: _.reduce(reportList, (pre, cur) => {
if (report.id === cur.id) {
return [...pre, report];
}
return [...pre, cur];
}, [])
});
};
render() {
const { reportName, selectedKeys, reportList } = this.state;

View File

@ -0,0 +1,99 @@
/*
* Author: 黎永顺
* name: 报表内容区
* Description:
* Date: 2023/4/21
*/
import React, { Component } from "react";
import { Spin } from "antd";
import RightOptions from "./rightOptions";
import { reportStatisticsReportGetData } from "../../../apis/statistics";
import "../index.less";
class ReportContent extends Component {
constructor(props) {
super(props);
this.state = {
columns: [],
dataSource: [],
countResult: {},
loading: false
};
}
componentDidMount() {
window.addEventListener("message", this.handleReceive, false);
}
componentWillReceiveProps(nextProps, nextContext) {
if (nextProps.report !== this.props.report && nextProps.report.dimensionId) {
this.reportStatisticsReportGetData(nextProps.report.id, nextProps.report.dimensionId);
}
}
componentWillUnmount() {
window.removeEventListener("message", this.handleReceive, false);
}
handleReceive = ({ data }) => {
const { type } = data;
if (type === "init") {
const { columns, countResult, dataSource } = this.state;
this.postMessageToChild({
columns, countResult, dataSource,
showSum: !_.isEmpty(countResult)
});
} else if (type === "turn") {
}
};
postMessageToChild = (payload) => {
const childFrameObj = document.getElementById("atdTable");
const { dataSource, columns, showSum, countResult } = payload;
childFrameObj.contentWindow.postMessage(JSON.stringify({
dataSource, columns, showSum, countResult
}), "*");
};
reportStatisticsReportGetData = (id, dimensionId) => {
const payload = { id, dimensionId };
this.setState({ loading: true });
reportStatisticsReportGetData(payload).then(({ status, data }) => {
this.setState({ loading: false });
if (status) {
const { countResult, columns, pageInfo: { list } } = data;
this.setState({
countResult,
columns: _.map(columns, it => ({ ...it, dataIndex: it.column, title: it.text, align: "center" })),
dataSource: list || []
}, () => {
this.postMessageToChild({
columns: this.state.columns, countResult: this.state.countResult,
dataSource: this.state.dataSource,
showSum: !_.isEmpty(this.state.countResult)
});
});
}
}).catch(() => this.setState({ loading: false }));
};
render() {
const { loading } = this.state;
return (
<div className="layoutContent">
<div className="layoutBox">
<Spin spinning={loading}>
<iframe
style={{ border: 0, width: "100%", height: "100%" }}
src="http://localhost:7607/#/reportTable"
// src="/spa/hrmSalary/hrmSalaryCalculateDetail/index.html#/reportTable"
id="atdTable"
/>
</Spin>
</div>
<RightOptions/>
</div>
);
}
}
export default ReportContent;

View File

@ -0,0 +1,45 @@
/*
* Author: 黎永顺
* name: 内容操作按钮区
* Description:
* Date: 2023/4/21
*/
import React, { Component } from "react";
import "../index.less";
class RightOptions extends Component {
constructor(props) {
super(props);
this.state = {
show: true
};
}
render() {
const { show } = this.state;
return (
<div className="layoutSide" style={{ width: show ? "30px" : 0 }}>
<div className="sideBox">
<div className="sideMain">
<div className="toll-bar-container" style={{ alignItems: show && "center" }}>
<i className="icon-coms-background" title="数据视图"/>
<i className="icon-portal-reportform-o" title="柱状图"/>
<i className="icon-coms-Line" title="折线图"/>
<i className="icon-coms-Pie" title="饼图"/>
<i className="icon-coms-Flow-setting" title="设置"/>
</div>
</div>
<span className="show-btn-right"
onClick={() => this.setState({ show: !show })}>
{
show ? <img src={require("../../../common/leftTree-show.png")} alt=""/> :
<img src={require("../../../common/leftTree-hide.png")} alt=""/>
}
</span>
</div>
</div>
);
}
}
export default RightOptions;

View File

@ -0,0 +1,206 @@
/*
* Author: 黎永顺
* name: 统计数据范围及规则设置
* Description:
* Date: 2023/4/21
*/
import React, { Component } from "react";
import { toJS } from "mobx";
import {
WeaButtonIcon,
WeaError,
WeaFormItem,
WeaHelpfulTip,
WeaLocaleProvider,
WeaRangePicker,
WeaSearchGroup,
WeaSelect,
WeaSlideModal,
WeaTable
} from "ecCom";
import CustomStatisticsItemsModal from "./customStatisticsItemsModal";
import moment from "moment";
import { Button } from "antd";
import { condition } from "./condition";
import { getSearchs } from "../../../util";
import { reportStatisticsItemSave } from "../../../apis/statistics";
import "../index.less";
const { getLabel } = WeaLocaleProvider;
class StatisticalMicroSettingsSlide extends Component {
constructor(props) {
super(props);
this.state = {
loading: false,
selectedRowKeys: [],
conditions: [],
salaryMonth: [moment().startOf("year").format("YYYY-MM"), moment().format("YYYY-MM")],
statisticalItemPayload: {
visible: false, id: "", dimension: ""
}
};
}
componentWillReceiveProps(nextProps, nextContext) {
if (nextProps.taxAgentAdminOption !== this.props.taxAgentAdminOption && !_.isEmpty(nextProps.taxAgentAdminOption)) {
const conditions = _.map(condition, item => {
return {
...item,
items: _.map(item.items, child => {
if (child.domkey[0] === "taxAgent") {
return {
...child,
options: toJS(nextProps.taxAgentAdminOption)
};
}
return { ...child };
})
};
});
this.setState({ conditions });
nextProps.form.initFormFields(condition);
}
}
reportStatisticsItemSave = () => {
const { salaryMonth } = this.state;
const { form, id, dimension } = this.props;
const [salaryStartMonth, salaryEndMonth] = salaryMonth;
const { hiredate, ...extra } = form.getFormDatas();
if (!salaryEndMonth && !salaryStartMonth) {
this.refs.weaError.showError();
return;
}
const payload = {
dimension, id,
hiredate: hiredate.value, items: [],
salaryEndMonth,
salaryStartMonth
};
console.log(payload, extra);
return;
this.setState({ loading: true });
reportStatisticsItemSave(payload).then(({ status, data }) => {
this.setState({ loading: false });
console.log(status, data);
}).catch(() => this.setState({ loading: false }));
};
renderGroupTitle = () => {
return <div className="groupTitleWrapper">
<span>{getLabel(111, "统计数据范围")}</span>
<span>{getLabel(111, "统计满足以下所有条件的人员薪资核算数据,不选则默认为选择全部")}</span>
</div>;
};
renderProjectTitle = () => {
const { id, dimension } = this.props;
return <div className="groupPorjectTitleWrapper">
<div>
<span>{getLabel(111, "统计项目")}</span>
<WeaHelpfulTip width={200} placement="topLeft"
title={getLabel(111, "统计列表的统计项排序与本列表统计项的顺序一致")}
/>
</div>
<div>
<WeaButtonIcon buttonType="del" type="primary"/>
<WeaButtonIcon
buttonType="add" type="primary"
onClick={() => this.setState({
statisticalItemPayload: { visible: true, id, dimension }
})}
/>
</div>
</div>;
};
drop = datas => {
console.log("datas", datas);
};
render() {
const { salaryMonth, conditions, selectedRowKeys, loading, statisticalItemPayload } = this.state;
const columns = [
{
title: "统计项名称",
dataIndex: "itemName"
},
{
title: "统计单位",
dataIndex: "unitType",
render: () => {
return <WeaSelect options={[]} style={{ width: 150 }}/>;
}
}
];
const rowSelection = {
selectedRowKeys,
onChange: (selectedRowKeys) => {
this.setState({ selectedRowKeys }, () => {
});
}
};
return (
<WeaSlideModal
className="microSlideWrapper"
{...this.props}
top={0}
measureT="%"
width={800}
measureX="px"
height={100}
measureY="%"
direction={"right"}
title={<TitleDialog loading={loading} onSave={this.reportStatisticsItemSave}/>}
content={
<React.Fragment>
<WeaSearchGroup title={getLabel(111, "统计时间范围")} col={2} showGroup needTigger>
<WeaFormItem label={getLabel(111, "薪资所属月")} labelCol={{ span: 8 }} wrapperCol={{ span: 16 }}>
<WeaError tipPosition="bottom" ref="weaError" error={getLabel(111, "此项必填")}>
<WeaRangePicker
value={salaryMonth} viewAttr={3} format="YYYY-MM"
onChange={v => this.setState({ salaryMonth: v })}
/>
</WeaError>
</WeaFormItem>
</WeaSearchGroup>
{
getSearchs(this.props.form, conditions, 2, false, () => {
}, this.renderGroupTitle())
}
<WeaSearchGroup title={this.renderProjectTitle()} showGroup needTigger>
<WeaTable
columns={columns}
dataSource={[{}]}
draggable={true}
onDrop={this.drop}
pagination={false}
rowSelection={rowSelection}
/>
<CustomStatisticsItemsModal {...statisticalItemPayload}
onCancel={() => this.setState({
statisticalItemPayload: { visible: false, id: "", dimension: "" }
})}
/>
</WeaSearchGroup>
</React.Fragment>
}
/>
);
}
}
export default StatisticalMicroSettingsSlide;
const TitleDialog = (props) => {
return <div className="titleDialog">
<div className="titleCol">
<div className="titleLeftBox">
<div className="titleIcon"><i className="icon-coms-fa"/></div>
<div className="title">{getLabel(111, "统计数据范围及规则设置")}</div>
</div>
</div>
<div className="titleCol titleRightBox">
<Button type="primary" loading={props.loading} onClick={props.onSave}>{getLabel(111, "保存")}</Button>
</div>
</div>;
};

View File

@ -5,25 +5,35 @@
* Date: 2023/4/20
*/
import React, { Component } from "react";
import { inject, observer } from "mobx-react";
import { WeaLeftRightLayout, WeaLocaleProvider, WeaSelect, WeaTop } from "ecCom";
import { message, Modal } from "antd";
import LeftTab from "./components/leftTab";
import { reportGetForm } from "../../apis/ruleconfig";
import ReportContent from "./components/reportContent";
import StatisticalMicroSettingsSlide from "./components/statisticalMicroSettingsSlide";
import { reportGetForm, reportStatisticsReportSave } from "../../apis/ruleconfig";
import "./index.less";
const { getLabel } = WeaLocaleProvider;
@inject("taxAgentStore", "attendanceStore")
@observer
class Index extends Component {
constructor(props) {
super(props);
this.state = {
report: {},
dimensionList: []
dimensionList: [],
statisticalPayload: {
visible: false, id: "", dimension: ""
}
};
}
componentDidMount() {
const { taxAgentStore: { getTaxAgentSelectListAsAdmin } } = this.props;
this.reportGetForm();
getTaxAgentSelectListAsAdmin();
}
reportGetForm = () => {
@ -36,9 +46,48 @@ class Index extends Component {
}
});
};
/*
* Author: 黎永顺
* Description: 统计维度切换
* Params:
* Date: 2023/4/20
*/
handleChangeDimension = (dimensionId, dimension) => {
const { report } = this.state;
Modal.confirm({
title: getLabel(111, "信息确认"),
content: getLabel(111, "确认要更改统计维度吗?"),
onOk: () => {
const payload = {
id: report.id,
reportName: report.reportName,
dimensionIds: dimensionId.split(",")
};
reportStatisticsReportSave(payload).then(({ status, errormsg }) => {
this.setState({ loading: false });
if (status) {
message.success(getLabel(111, "切换成功"));
this.setState({
report: {
...report, dimensionId,
dimension
}
}, () => this.leftTabRef.updateReportList(this.state.report));
} else {
message.error(errormsg || getLabel(111, "切换失败"));
this.setState({ report: { ...report } });
}
});
},
onCancel: () => {
this.setState({ report: { ...report } });
}
});
};
render() {
const { report, dimensionList } = this.state;
const { report, dimensionList, statisticalPayload } = this.state;
const { attendanceStore: { settingForm }, taxAgentStore: { taxAgentAdminOption } } = this.props;
return (
<WeaTop
title={getLabel(111, "报表查看")}
@ -49,7 +98,7 @@ class Index extends Component {
>
<WeaLeftRightLayout
leftWidth={210}
leftCom={<LeftTab onChangeTab={report => this.setState({ report })}/>}
leftCom={<LeftTab ref={dom => this.leftTabRef = dom} onChangeTab={report => this.setState({ report })}/>}
>
<div className="rightLayout">
<div className="layoutHeader">
@ -59,15 +108,31 @@ class Index extends Component {
<div className="rightColTitle">
<div className="dimension">
<span>{getLabel(111, "统计维度")}</span>
<WeaSelect value={report.dimensionId} options={dimensionList}/>
<WeaSelect value={report.dimensionId} options={dimensionList}
onChange={(key, showname) => this.handleChangeDimension(key, showname)}/>
</div>
<div className="iconWrapper"><i className="icon-coms02-currency"/></div>
<div className="iconWrapper">
<i
className="icon-coms02-currency"
onClick={() => this.setState({
statisticalPayload: { visible: true, id: report.id, dimension: report.dimensionId }
})}
/>
</div>
{/*统计数据范围及规则设置弹框*/}
<StatisticalMicroSettingsSlide
{...statisticalPayload} form={settingForm}
taxAgentAdminOption={taxAgentAdminOption}
onClose={() => this.setState({
statisticalPayload: { visible: false, id: "", dimension: "" }
})}
/>
</div>
</div>
</div>
</div>
{/* 内容区 */}
<ReportContent ref={dom => this.reportRef = dom} report={report}/>
</div>
</WeaLeftRightLayout>
</WeaTop>

View File

@ -43,6 +43,10 @@
}
.rightLayout {
display: flex;
flex-direction: column;
height: 100%;
.layoutHeader {
height: 50px;
@ -95,6 +99,198 @@
}
}
}
.layoutContent {
flex: 1;
display: flex;
justify-content: space-between;
width: 100%;
height: 100%;
.layoutBox {
flex: 1;
padding: 16px;
.ant-spin-nested-loading, .ant-spin-container {
height: 100%;
}
}
.layoutSide {
position: relative;
transition: width .3s cubic-bezier(.645, .045, .355, 1), height .3s cubic-bezier(.645, .045, .355, 1);
min-height: 1px;
.sideBox {
position: relative;
height: 100%;
width: 100%;
.sideMain {
width: 100%;
.toll-bar-container {
margin-top: 16px;
background-color: #fff;
border: 1px solid #e5e5e5;
height: 180px;
display: flex;
flex-direction: column;
justify-content: space-around;
i {
font-size: 16px;
color: #2db7f5 !important;
cursor: pointer;
}
}
}
.show-btn-right {
position: absolute;
cursor: pointer;
z-index: 100;
top: 60px;
left: -17px;
transform: rotate(180deg);
}
}
}
}
}
}
}
//统计数据范围及规则设置
.microSlideWrapper {
z-index: 999;
.wea-slide-modal-title {
height: auto !important;
line-height: normal !important;
}
.titleDialog {
display: flex;
padding: 10px 16px 10px 0;
position: relative;
background-color: #f6f6f6;
border-bottom: 1px solid #e5e5e5;
.titleCol {
flex: 1;
.titleLeftBox {
display: flex;
height: 100%;
align-items: center;
padding-left: 16px;
.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 {
display: flex;
justify-content: flex-end;
align-items: center;
padding-right: 30px;
}
}
.groupTitleWrapper {
display: flex;
justify-content: space-between;
& > span:last-child {
color: #666
}
}
.groupPorjectTitleWrapper {
display: flex;
justify-content: space-between;
align-items: center;
& > div:first-child {
display: flex;
align-items: center;
& > span:first-child {
padding-right: 8px;
}
}
& > div:last-child {
display: flex;
align-items: center;
.wea-button-icon:first-child {
margin-right: 10px;
}
}
}
}
//新建自定义统计项目
.statisticItemsWrapper {
.itemsTitle {
display: flex;
align-items: center;
justify-content: space-between;
}
.statisticItemsBox {
padding: 16px;
.wea-error {
width: 100%;
}
.wea-form-item {
padding: 5px 16px;
border: 1px solid #e5e5e5;
}
.wea-form-item:first-child {
border-bottom: none;
}
}
.customRuleTableWrapper {
margin-top: 16px;
.intervalSettingsCompWrapper {
display: flex;
align-items: center;
span.increaseTitle {
padding: 0 8px;
display: inline-block;
width: 220px;
}
span.pecentTitle {
padding-left: 8px;
}
}
}
}

View File

@ -8,4 +8,6 @@ export class AttendanceStore {
//薪酬统计 新增form
@observable statisticsForm = new WeaForm();
@observable reportForm = new WeaForm();
//报表查看 统计数据范围及规则设置form
@observable settingForm = new WeaForm();
}

View File

@ -17,7 +17,7 @@ export const getConditionDomkeys = (condition) => {
};
// 渲染form表单: 一般对form的渲染都统一使用该方法
export const getSearchs = (form, condition, col, isCenter, onChange = () => void (0)) => {
export const getSearchs = (form, condition, col, isCenter, onChange = () => void (0), title) => {
const { isFormInit } = form;
const formParams = form.getFormParams();
let group = [];
@ -51,7 +51,7 @@ export const getSearchs = (form, condition, col, isCenter, onChange = () => void
<WeaSearchGroup
col={col || 1} // 高级搜索列布局列数
needTigger={true} // 是否开启收缩
title={c.title || ""} // 高级搜索标题
title={c.title || title} // 高级搜索标题
showGroup={c.defaultshow} // 是否开启面板
items={items} // 条目数组数据
center={isCenter || false} // 内容是否居中:一般弹框需要