feature/2.9.42309.01-薪资核算详情页面列表改造(页面编辑)

This commit is contained in:
黎永顺 2023-09-14 10:25:22 +08:00
parent f5d42d8f75
commit 8a90d58196
19 changed files with 1155 additions and 3 deletions

View File

@ -0,0 +1,87 @@
/*
* Author: 黎永顺
* name: 导入-步骤一
* Description:
* Date: 2023/8/11
*/
import React, { Component } from "react";
import { WeaLocaleProvider } from "ecCom";
import { Icon, message, Upload } from "antd";
const Dragger = Upload.Dragger;
const { getLabel } = WeaLocaleProvider;
class ImpStep1 extends Component {
constructor(props) {
super(props);
this.state = {
fileList: []
};
}
handleChange = (data) => {
const { fileList, file } = data;
if (file.response && typeof (file.response) != "undefined" && file.status !== "removed") message.success(getLabel(111, "上传成功"));
this.setState({ fileList: fileList.slice(-1) });
};
render() {
const { fileList } = this.state;
const dragger = {
accept: ".xlsx",
name: "file",
multiple: false,
action: "/api/doc/upload/uploadFile",
fileList,
onChange: this.handleChange
};
return (
<div className="weapp-batch-impsteps-picker-content-imp-step1">
{/* 导入选项 */}
{
this.props.importParams &&
<div className="weapp-salary-tb-border-bottom import-option">
<div>{getLabel(543201, "导入选项")}</div>
{this.props.importParams}
</div>
}
<div className="title">{getLabel(543202, "导入Excel")}</div>
<p className="draggerUploadWrapper">
<Dragger {...dragger}>
<div>
<p className="iconUpload"><Icon type="inbox"/></p>
<p className="uplaod-title">{getLabel(543203, "点击或将文件拖拽到此区域上传")}</p>
<p
className="uplaod-subTitle">{getLabel(543204, "支持单个或批量上传,严禁上传公司内部资料及其他违禁文件")}</p>
</div>
</Dragger>
</p>
<div className="bottom-border">
<div>{getLabel(27577, "操作步骤")}</div>
<p>
<span>{`1. ${getLabel(30907, "第一步")},${getLabel(543205, "请选择导出的Excel文件或")}`}</span>&nbsp;&nbsp;
<a href={this.props.link} className="weapp-salary-link"
target="_blank">{getLabel(543207, "点击这里下载模板")}</a>&nbsp;&nbsp;
{this.props.exportDataDom}
</p>
<p>{`2. ${getLabel(543211, "第二步")},${getLabel(543212, "请一定要确定Excel文档中的格式是模板中的格式")},${getLabel(543213, "没有被修改掉")}`}</p>
<p>{`3. ${getLabel(543216, "第三步")},${getLabel(543215, "选择填写好的Excel文档")},${getLabel(543214, "点击“下一步”按钮进行数据预览")}`}</p>
<p>
{`4. ${getLabel(543217, "第四步")},${getLabel(543218, "如果以上步骤和Excel文档正确的话")},${getLabel(543219, "导入成功会有提示")},${getLabel(543220, "数据会被正确导入")}${getLabel(543221, "如果有问题")},${getLabel(543222, "则会提示Excel文档的错误之处")}`}
</p>
</div>
<div className="description">
<div>{getLabel(543223, "Excel文件说明")}</div>
<p>{`1. ${getLabel(543224, "后缀名为xls或者xlsx")};`}</p>
<p>{`2. ${getLabel(543225, "数据请勿放在合并的单元格中")};`}</p>
<p><span>{`3. ${getLabel(543226, "账单月份格式必须为")}:YYYY-MM`}</span></p>
</div>
</div>
);
}
}
export default ImpStep1;

View File

@ -0,0 +1,49 @@
/*
* Author: 黎永顺
* name: 导入-步骤二
* Description:
* Date: 2023/9/5
*/
import React, { Component } from "react";
import { WeaTable } from "ecCom";
import { postFetch } from "../../../util/request";
class ImpStep2 extends Component {
constructor(props) {
super(props);
this.state = {
loading: false, columns: [], dataSource: []
};
}
componentDidMount() {
this.init();
}
init = () => {
const { previewUrl, imageId } = this.props;
const payload = { imageId };
this.setState({ loading: true });
postFetch(previewUrl, payload).then(({ status, data }) => {
this.setState({ loading: false });
if (status) {
const { headers, list } = data;
this.setState({
columns: _.map(headers, (item, index) => ({ title: item, dataIndex: index + "", width: 120 })),
dataSource: _.map(list, item => {
return _.reduce(item, (pre, cur, key) => (_.assign(pre, { [key]: cur })), {});
})
});
}
}).catch(() => this.setState({ loading: false }));
};
render() {
const { dataSource, columns, loading } = this.state;
return (
<WeaTable dataSource={dataSource} columns={columns} pagination={false} loading={loading} scroll={{ x: 800 }}/>
);
}
}
export default ImpStep2;

View File

@ -0,0 +1,51 @@
/*
* Author: 黎永顺
* name: 导入-步骤3
* Description:
* Date: 2023/8/11
*/
import React, { Component } from "react";
import { WeaLocaleProvider, WeaTable } from "ecCom";
import successImg from "../../importModal/success.svg";
const getLabel = WeaLocaleProvider.getLabel;
class ImpStep3 extends Component {
render() {
const { importResult } = this.props;
return (
<div className="weapp-batch-impsteps-picker-content-imp-step3">
{
!_.isEmpty(importResult) ?
<div className="weapp-batch-impsteps-picker-spinText">
<p><img src={successImg} alt=""/></p>
<p>
<span>{getLabel(389249, "已导入")}</span>
<span style={{ color: "green" }}> {importResult.successCount}</span>&nbsp;&nbsp;
<span>{`${getLabel(30690, "条数据")},${getLabel(25009, "失败")}`}</span>
<span style={{ color: "red" }}> {importResult.errorCount}&nbsp;&nbsp;</span>{getLabel(30690, "")}
</p>
</div> :
<div className="weapp-batch-impsteps-picker-spinText">
<p>{getLabel(111, "导入失败")}</p>
</div>
}
{
!_.isEmpty(importResult.errorData) &&
<WeaTable
columns={[
{
title: getLabel(25700, "错误信息"),
dataIndex: "message"
}
]}
dataSource={importResult.errorData} pagination={false}
scroll={{ y: `calc(100vh - 387px)` }}
/>
}
</div>
);
}
}
export default ImpStep3;

View File

@ -0,0 +1,153 @@
/*
* Author: 黎永顺
* name: 导入弹框-步骤条
* Description:
* Date: 2023/8/11
*/
import React, { Component } from "react";
import { Button, message, Modal } from "antd";
import { WeaDialog, WeaLocaleProvider, WeaSteps } from "ecCom";
import ImpStep1 from "./components/impStep1";
import ImpStep2 from "./components/impStep2";
import ImpStep3 from "./components/impStep3";
import "./index.less";
const { getLabel } = WeaLocaleProvider;
const Step = WeaSteps.Step;
class Index extends Component {
constructor(props) {
super(props);
this.state = {
current: 0
};
}
componentWillReceiveProps(nextProps, nextContext) {
if (JSON.stringify(nextProps.importResult) !== JSON.stringify(this.props.importResult) && !_.isEmpty(nextProps.importResult)) {
this.setState({
current: this.state.current + 1
});
}
if (nextProps.visible !== this.props.visible && !nextProps.visible) this.setState({ current: 0 });
}
renderChildren = () => {
const { current } = this.state;
const { importParams, link, excludeKey, importResult, exportDataDom = null } = this.props;
let CurrentDom = null;
switch (current) {
case 0:
CurrentDom = <ImpStep1 importParams={importParams} link={link} exportDataDom={exportDataDom}
ref={dom => this.step1Ref = dom}/>;
break;
case 1:
CurrentDom = <ImpStep2 {...this.props}/>;
if (excludeKey) {
CurrentDom = <ImpStep3 importResult={importResult}/>;
}
break;
case 2:
CurrentDom = <ImpStep3 importResult={importResult}/>;
break;
default:
CurrentDom = null;
break;
}
return CurrentDom;
};
/*
* Author: 黎永顺
* Description: 上一步
* Params:
* Date: 2023/9/5
*/
handlePreviousStep = () => {
Modal.confirm({
title: getLabel(131329, "信息确认"),
content: getLabel(111, "是否放弃已上传的文件?"),
onOk: () => this.setState({ current: this.state.current - 1 }, () => this.props.onResetImportResult())
});
};
/*
* Author: 黎永顺
* Description: 下一步
* Params:
* Date: 2023/8/11
*/
handleNext = () => {
const { params, importResult } = this.props;
if (_.isEmpty(importResult)) {
const { fileList } = this.step1Ref.state;
if (!_.isEmpty(params)) {
if (!Object.values(params).every(o => !!o)) {
Modal.warning({
title: getLabel(131329, "信息确认"),
content: getLabel(518702, "必要信息不完整,红色*为必填项!")
});
return;
}
}
if (_.isEmpty(fileList)) {
message.warning(getLabel(111, "请先上传EXCEL文件"));
return;
}
const [file] = fileList;
const { response } = file;
this.props.nextCallback(response.data.fileid);
} else {
this.setState({ current: this.state.current + 1 });
}
};
render() {
const { current } = this.state;
const stepData = [
{ key: 0, label: getLabel(543202, "上传EXCEL") },
{ key: 1, label: getLabel(543200, "数据预览") },
{ key: 2, label: getLabel(502835, "导入数据") }
];
const btns = [
<Button type="ghost" onClick={this.handlePreviousStep}>{getLabel(1876, "上一步")}</Button>,
<Button type="primary" onClick={this.handleNext}
loading={this.props.nextloading}>{getLabel(1402, "下一步")}</Button>,
<Button type="primary" onClick={() => this.props.onCancel(true)}>{getLabel(555, "完成")}</Button>
];
return (
<WeaDialog
{...this.props}
scalable hasScroll className="importBox" initLoadCss
buttons={current === 0 ? _.nth(btns, 1) : (!this.props.excludeKey && current === 1) ? _.take(btns, 2) : _.takeRight(btns)}
style={{
width: 800,
height: 606.6,
minHeight: 200,
minWidth: 380,
maxHeight: "90%",
maxWidth: "90%",
overflow: "hidden",
transform: "translate(0px, 0px)"
}}
>
<div className="importCont">
<div className="weapp-batch-impsteps-picker-content-imp-steps">
<WeaSteps current={current}>
{/*this.props.key: 不需要展示的步骤*/}
{
_.map(_.filter(stepData, item => item.key !== this.props.excludeKey), it => (
<Step key={it.key} description={it.label}/>))
}
</WeaSteps>
</div>
<div className="weapp-batch-impsteps-picker">
{
this.renderChildren()
}
</div>
</div>
</WeaDialog>
);
}
}
export default Index;

View File

@ -0,0 +1,143 @@
.importBox {
.importCont {
padding: 16px 8px;
.weapp-batch-impsteps-picker-content-imp-steps {
width: 80%;
margin: 0 auto;
}
.weapp-batch-impsteps-picker {
margin: 16px auto;
.weapp-batch-impsteps-picker-content-imp-step1 {
width: 98%;
background-color: #fff;
margin: 8px auto;
border-radius: 3px;
padding: 1px 12px;
.weapp-batch-impsteps-picker-content-imp-step1 div {
color: #111;
line-height: 22px;
}
.weapp-salary-tb-border-bottom .weapp-salary-tb-filter.weapp-salary-import-param {
box-sizing: border-box;
padding: 16px;
height: auto;
flex-wrap: wrap;
width: 100%;
}
.weapp-salary-import-param {
border: 1px solid #ebedf0;
padding: 8px;
margin: 4px 0 14px;
}
.weapp-salary-tb-filter {
display: flex;
flex-wrap: wrap;
align-items: center;
height: 46px;
}
.weapp-salary-tb-border-bottom .weapp-salary-tb-filter.weapp-salary-import-param .tbf-item {
display: flex;
justify-content: flex-start !important;
}
.weapp-salary-tb-filter .tbf-item {
padding: 0 20px 0 0;
display: flex;
align-items: center;
font-size: 12px;
color: #111;
height: 40px;
}
.weapp-salary-tb-filter .tbf-item > .tbfi-label {
flex-basis: 100px;
flex-shrink: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
padding-right: 10px;
color: #666;
}
.draggerUploadWrapper {
margin: 16px 0 0;
.ant-upload-drag-container {
padding: 24px 0 16px;
.iconUpload {
i {
color: #5d9cec;
font-size: 43px;
}
}
.uplaod-title {
font-size: 14px;
color: #333;
height: 24px;
line-height: 24px;
margin-top: 8px;
}
.uplaod-subTitle {
height: 22px;
font-size: 12px;
color: #666;
text-align: center;
line-height: 22px;
}
}
}
.bottom-border, .description {
margin-top: 12px;
p {
font-size: 12px;
color: #666;
line-height: 15px;
margin: 12px 0;
}
}
.bottom-border {
border-bottom: 1px solid #e5e5e5;
.weapp-salary-link {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
color: #5d9cec;
}
}
}
}
.weapp-batch-impsteps-picker-content-imp-step3 {
.weapp-batch-impsteps-picker-spinText {
position: relative;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
text-align: center;
p {
margin: 14px 0;
}
}
}
}
}

View File

@ -25,6 +25,7 @@ import TaxAgent from "./pages/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 GenerateDeclarationDetail from "./pages/declare/generateDeclarationDetail";
import TemplatePreview from "./pages/payroll/templatePreview";
import MobilePayroll from "./pages/mobilePayroll";
@ -73,6 +74,7 @@ const DataAcquisition = (props) => props.children;
// ledger 薪资账套
// calculate 薪资核算
// calculateDetail 核算详情
// DoCalcDetail 新核算详情页面
// placeOnFileDetail 核算归档详情
// compareDetail 线下线上对比
// payroll 工资单发放
@ -130,6 +132,7 @@ 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="placeOnFileDetail" path="placeOnFileDetail" component={PlaceOnFileDetail}/>
<Route key="compareDetail" path="compareDetail" component={CompareDetail}/>
<Route key="payroll" path="payroll" component={Payroll}/>

View File

@ -0,0 +1,19 @@
import React, { Component } from "react";
import { WeaInputSearch, WeaLocaleProvider } from "ecCom";
import { Button } from "antd";
import "./index.less";
const getLabel = WeaLocaleProvider.getLabel;
class Index extends Component {
render() {
return (
<div className="advance-search">
<WeaInputSearch/>
<Button type="ghost" className="wea-advanced-search text-elli">{getLabel(111, "高级搜索")}</Button>
</div>
);
}
}
export default Index;

View File

@ -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;
}
}

View File

@ -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;

View File

@ -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: "常用条件"
}
];

View File

@ -0,0 +1,177 @@
/*
* Author: 黎永顺
* name: 人员确认
* Description:
* Date: 2023/9/13
*/
import React, { Component } from "react";
import { WeaButtonIcon, WeaHelpfulTip, WeaLocaleProvider, WeaTab, WeaTools } from "ecCom";
import { inject, observer } from "mobx-react";
import { Button } from "antd";
import BaseInfo from "./baseInfo";
import { acctemployeeList } from "../../../../../apis/calculate";
import { personConfirmSearchConditions } from "./condition";
import { getSearchs } from "../../../../../util";
const getKey = WeaTools.getKey;
const getLabel = WeaLocaleProvider.getLabel;
@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: []
};
}
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.acctemployeeList();
});
}
renderTabBtns = () => {
const { selectedKey } = this.state;
let tabBtns = [];
switch (selectedKey) {
case "range":
tabBtns = [
<WeaButtonIcon buttonType="del" type="primary" title={getLabel(111, "批量删除")}/>,
<WeaButtonIcon buttonType="add" type="primary" title={getLabel(1421, "新增")}/>,
<Button type="primary">{getLabel(17416, "导出")}</Button>
];
break;
case "add":
case "sub":
tabBtns = [
<Button type="primary">{getLabel(17416, "导出")}</Button>
];
break;
default:
break;
}
return tabBtns;
};
acctemployeeList = () => {
const { pageInfo } = 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(",") : []
};
acctemployeeList(payload).then(({ status, data }) => {
if (status) {
console.log(data);
}
});
};
render() {
const { calculateStore: { PCSearchForm } } = this.props;
const { selectedKey, showSearchAd, searchConditions, pageInfo, loading, selectedRowKeys } = 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.queryList());
},
onChange: current => {
this.setState({ pageInfo: { ...pageInfo, current } }, () => this.queryList());
}
};
const rowSelection = {
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 })} advanceHeight={220}
buttons={this.renderTabBtns()} searchType={["base", "advanced"]}
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.acctemployeeList} onAdSearch={this.acctemployeeList}
onAdReset={() => PCSearchForm.resetForm()}
/>
</div>
);
}
}
export default Index;

View File

@ -0,0 +1,42 @@
.person-confirm-layout {
.wea-tab .wea-tab-right, .wea-input-focus {
background: transparent;
}
}
.docalc-baseinfo-layout {
padding: 0;
.wea-title {
border-bottom: none;
}
.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;
}
}
}

View File

@ -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;

View File

@ -0,0 +1,11 @@
.salary-month-tip {
.line {
.label {
color: #666;
}
.value {
color: #111;
}
}
}

View File

@ -0,0 +1,105 @@
/*
* Author: 黎永顺
* name: 薪资核算详情
* Description:
* Date: 2023/9/13
*/
import React, { Component } from "react";
import { WeaLocaleProvider, WeaReqTop } from "ecCom";
import { Button, Dropdown, Menu } from "antd";
import Layout from "./layout";
import AdvanceInputBtn from "./components/advanceInputBtn";
import SalaryCalcPersonConfirm from "./components/salaryCalcPersonConfirm";
import "./index.less";
const getLabel = WeaLocaleProvider.getLabel;
class Index extends Component {
constructor(props) {
super(props);
this.state = {
selectedKey: "person"
};
}
componentDidMount() {
console.log(this.props);
}
handleButtonClick = () => {
console.log("核算所有人");
};
handleMenuClick = ({ key }) => {
console.log(key);
};
handleMoreMenuClick = ({ key }) => {
console.log(key);
};
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.handleButtonClick} overlay={menu} type="primary">
{getLabel(543545, "核算所有人")}
</Dropdown.Button>,
<Dropdown overlay={moreMenu}><Button type="ghost">{getLabel(17499, "更多")}</Button></Dropdown>,
<AdvanceInputBtn/>
];
break;
default:
break;
}
return reqBtns;
};
renderContent = () => {
const { selectedKey } = this.state;
let dom = null;
switch (selectedKey) {
case "person":
dom = <SalaryCalcPersonConfirm {...this.props}/>;
break;
default:
break;
}
return dom;
};
render() {
const tabs = [
{ key: "person", title: getLabel(543547, "人员确认") },
{ key: "calc", title: getLabel(538011, "薪资核算") }
];
const { selectedKey } = 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 })}
buttons={this.renderReqBtns()}
>
<div className="salary-calculate-do-calc-content">{this.renderContent()}</div>
</WeaReqTop>
</div>
</Layout>
);
}
}
export default Index;

View File

@ -0,0 +1,15 @@
.salary-calculate-do-calc {
min-width: 1000px;
overflow: auto;
width: 100%;
height: 100%;
background: #f6f6f6;
.wea-new-top-req-wapper .wea-new-top-req-title > div:last-child {
right: 16px;
}
.salary-calculate-do-calc-content {
padding: 8px 16px;
}
}

View File

@ -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;

View File

@ -8,6 +8,9 @@ import { toDecimal_n } from "../util";
const { TableStore } = WeaTableNew;
export class calculateStore {
@observable PCSearchForm = new WeaForm(); //人员确认-form
@observable tableStore = new TableStore(); // new table
@observable form = new WeaForm(); // nrew 一个form
@observable condition = []; // 存储后台得到的form数据

View File

@ -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;
@ -149,12 +148,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());
});
};
// 人员范围列表