Merge branch 'feature/2.9.42310.01-工资单发放页面重构' into develop

This commit is contained in:
黎永顺 2023-10-23 18:30:47 +08:00
commit 63dcd77589
23 changed files with 2713 additions and 22 deletions

View File

@ -0,0 +1,89 @@
/*
* Author: 黎永顺
* name: 移动端-工资单预览
* Description:
* Date: 2023/10/19
*/
import React, { Component } from "react";
import { WeaLocaleProvider } from "ecCom";
import { dealTemplate } from "../pcTemplate";
import moment from "moment";
import "./index.less";
const getLabel = WeaLocaleProvider.getLabel;
class Index extends Component {
render() {
const { theme, background, tip, tipPosi, itemTypeList } = this.props;
const { onlyOneGrup, showData } = dealTemplate(itemTypeList, "mobile");
return (
<React.Fragment>
<div className="pbmc-head">{getLabel(111, "薪酬预览")}</div>
<div className="pbmc-body">
<div className="weapp-salary-payroll-mobile-preview">
<div className="bill-container">
<div className="bill-info-header">
<div className="title">{theme || ""}</div>
<div className="time">{moment().format("YYYY-MM-DD HH:mm:ss")}</div>
{
background &&
<div className="img"><img src={`${background}`} alt="logo"/></div>
}
</div>
{
!onlyOneGrup && tipPosi === "1" && tip &&
<div className="corporate-culture-text top" title={tip}>{tip}</div>
}
<div className="salary-detail-table-container">
{
showData.map((groupItem, index) => {
if (!groupItem) return null;
const { groupId, groupName, items = [] } = groupItem;
return (
<div className="salary-group" key={groupId || index}>
{
groupName ? <div className="group-title">{groupName}</div> : null
}
<div className="group-list">
{
(onlyOneGrup && tipPosi === "1" && tip) && (<div className="list-item send-tip top">
<div className="label">{getLabel(111, "发放说明")}</div>
<div className="detail">{tip}</div>
</div>)
}
{
items.map((templatItem, index) => {
const { salaryItemValue, name } = templatItem || {};
return <div className="list-item" key={index}>
<div className="item-name" title={name}><span className="text">{name || ""}</span></div>
<div className="item-count">{salaryItemValue || "100"}</div>
</div>;
})
}
{
(onlyOneGrup && tipPosi === "2" && tip) && (<div className="list-item send-tip bottom">
<div className="label">{getLabel(111, "发放说明")}</div>
<div className="detail">{tip}</div>
</div>)
}
</div>
</div>);
})
}
</div>
{
!onlyOneGrup && tipPosi === "2" && tip &&
<div className="corporate-culture-text footer" title={tip}>{tip}</div>
}
</div>
</div>
</div>
<div className="pbmc-footer">
<div className="pbmcf-indicator"></div>
</div>
</React.Fragment>
);
}
}
export default Index;

View File

@ -0,0 +1,137 @@
.pbmc-head {
height: 50px;
line-height: 50px;
border-bottom: 1px solid #f4f4f4;
text-align: center;
font-size: 14px;
font-weight: 600;
}
.pbmc-body {
height: calc(100% - 150px);
background: #f6f6f6;
overflow: auto;
.weapp-salary-payroll-mobile-preview {
width: 100%;
height: 100%;
overflow-y: auto;
.bill-container {
background: #f6f6f6;
.bill-info-header {
padding-top: 16px;
.title {
padding: 0 16px;
font-size: 19px;
font-weight: 700;
margin-bottom: 12px;
}
.time {
padding: 0 16px;
font-size: 12px;
color: #999;
}
.img {
margin-top: 20px;
width: 100%;
img {
width: 100%;
}
}
}
.top {
padding-bottom: 0;
}
.footer {
padding-top: 8px;
}
.corporate-culture-text {
font-size: 14px;
text-align: left;
color: #111;
padding: 8px 16px;
white-space: pre-wrap;
word-break: break-all;
}
.salary-detail-table-container {
padding-top: 8px;
.salary-group {
border-top: 1px solid #f2f2f2;
margin-bottom: 16px;
.group-title {
background: #fff;
background: var(--base-white);
display: flex;
color: #2780c4;
align-items: center;
min-height: 45px;
padding: 0 16px;
border-bottom: 1px solid #f2f2f2;
font-weight: bolder;
font-size: 16px;
}
.group-list {
.list-item {
display: flex;
min-height: 45px;
border-bottom: 1px solid #f2f2f2;
width: 100%;
background: #fff;
.item-name {
font-size: 16px;
padding: 8px 16px;
width: 40%;
display: flex;
align-items: center;
background: #fbfbfb;
border-right: 1px solid #f2f2f2;
flex-shrink: 0;
color: #2780c4;
font-weight: bolder;
}
.item-count {
display: flex;
align-items: center;
padding: 16px;
white-space: pre-wrap;
word-break: break-all;
}
}
}
}
}
}
}
}
.pbmc-footer {
position: relative;
height: 50px;
.pbmcf-indicator {
position: absolute;
bottom: 16px;
left: 50%;
-webkit-transform: translateX(-50%);
transform: translateX(-50%);
width: 110px;
height: 4px;
background-color: #ebebeb;
border-radius: 2px;
}
}

View File

@ -0,0 +1,111 @@
import React, { Component } from "react";
import { WeaLocaleProvider } from "ecCom";
import moment from "moment";
import "./index.less";
const getLabel = WeaLocaleProvider.getLabel;
class Index extends Component {
render() {
const { theme, background, tip, tipPosi, itemTypeList } = this.props;
const { onlyOneGrup, showData } = dealTemplate(itemTypeList, "pc");
return (
<div className="pbpc-content">
<div className="weapp-salary-sp weapp-salary-payroll-pc-preview">
<div className="salary-preview-container">
<div className="edition-center">
<div className="header">
<div className="header-title">{theme || ""}</div>
<div className="header-salary-date-time">{moment().format("YYYY-MM-DD HH:mm:ss")}</div>
</div>
<div className="body">
{
background &&
<div className="comp-img"><img src={`${background}`} alt="logo"/></div>
}
{
!onlyOneGrup && tipPosi === "1" && tip &&
<div className="corporate-culture-text" title={tip}>{tip}</div>
}
<div className="data-detail">
{
showData.map((groupItem, index) => {
// 如果当前组下没有条目 当前组直接不展示。
if (!groupItem) return null;
const { groupId, groupName, items = [] } = groupItem;
return (
<div className="salary-group" key={groupId || index}>
{
groupName ? <div className="group-title">{groupName}</div> : null
}
<div className="group-list">
{
(onlyOneGrup && tipPosi === "1" && tip) && (<div className="send-tip top">
<div className="label">{getLabel(111, "发放说明")}</div>
<div className="detail">{tip}</div>
</div>)
}
{
items.map((templatItem, index) => {
const { salaryItemValue, name } = templatItem || {};
return <div key={index}
className={`list-item ${index % 2 === 0 ? "even" : "odd"} ${index === 0 ? "zero" : ""} ${index === 1 ? "first" : ""}`}>
<div className="item-name" title={name}>
<span className="text">{name || ""}</span>
</div>
<div className="item-count">{salaryItemValue || ""}</div>
</div>;
})
}
{
(onlyOneGrup && tipPosi === "2" && tip) && (<div className="send-tip bottom">
<div className="label">{getLabel(111, "发放说明")}</div>
<div className="detail">{tip}</div>
</div>)
}
</div>
</div>);
})
}
</div>
{
!onlyOneGrup && tipPosi === "2" && tip &&
<div className="corporate-culture-text" title={tip}>{tip}</div>
}
</div>
</div>
</div>
</div>
</div>
);
}
}
export default Index;
export const dealTemplate = (itemTypeList, type) => {
let cloneItemTypeList = _.cloneDeep(itemTypeList);
let showData = [], onlyOneGrup = false;
cloneItemTypeList.forEach((group) => {
const { items, groupName, groupId } = group;
if (items.length !== 0) {
items.forEach((item) => {
item.salaryItemValue = "100";
});
if (items.length % 2 && type === "pc") items.push({});
// 未分类不展示标题
if (!groupId.includes("222222222222222222")) {
showData.push({ groupId, groupName, items });
} else {
showData.push({ items });
}
}
});
if (cloneItemTypeList.length === 1) {
onlyOneGrup = true;
// 只有一个分组的时候不展示分组名
cloneItemTypeList[0].name = "";
}
return { onlyOneGrup, showData };
};

View File

@ -0,0 +1,153 @@
.pbpc-content {
height: 100%;
border: 1px solid #e5e5e5;
overflow-y: auto;
.weapp-salary-sp {
background: #f6f6f6;
.salary-preview-container {
display: flex;
justify-content: flex-start;
align-items: center;
flex-direction: column;
width: 100%;
.edition-center {
max-width: 1000px;
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
padding-bottom: 32px;
.header {
height: 48px;
padding: 0 16px;
font-size: 12px;
color: #111;
.header-title {
height: 22px;
font-size: 17px;
color: #111;
line-height: 22px;
font-weight: 400;
text-align: center;
}
.header-salary-date-time {
margin-top: 16px;
text-align: center;
height: 14px;
font-size: 14px;
color: #999;
line-height: 14px;
font-weight: 400;
}
}
.body {
width: 100%;
margin-top: 32px;
.comp-img {
text-align: center;
img {
width: 100%;
}
}
.corporate-culture-text {
width: 100%;
margin-top: 16px;
text-align: center;
min-height: 12px;
font-size: 12px;
color: #111;
white-space: pre-wrap;
word-break: break-all;
}
.data-detail {
margin-top: 16px;
.salary-group {
margin-bottom: 16px;
.group-title {
font-size: 14px;
}
.group-list {
margin-top: 16px;
display: flex;
flex-wrap: wrap;
.even {
border-left: 1px solid #e5e5e5;
}
.zero, .first {
border-top: 1px solid #e5e5e5;
}
.list-item {
width: 50%;
display: flex;
justify-content: left;
min-height: 40px;
align-items: center;
border-bottom: 1px solid #e5e5e5;
border-right: 1px solid #e5e5e5;
.item-name {
flex-basis: 170px;
box-sizing: border-box;
width: 170px;
padding: 0 16px;
height: 100%;
background: #fbfbfb;
border-right: 1px solid #e5e5e5;
font-size: 12px;
color: #666;
display: flex;
justify-content: center;
align-items: center;
flex-shrink: 0;
.text {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
text-overflow: ellipsis;
}
}
.item-count {
flex-basis: 328px;
padding-left: 16px;
height: 100%;
line-height: 40px;
background: #fff;
font-size: 12px;
color: #111;
word-break: break-all;
}
}
}
}
}
}
}
}
}
.weapp-salary-payroll-pc-preview {
padding: 32px 0;
height: 100%;
overflow-y: auto;
}
}

View File

@ -17,7 +17,8 @@ import SpecialAddDeduction from "./pages/dataAcquisition/specialAddDeduction";
import Ledger from "./pages/ledgerPage";
// import Calculate from "./pages/calculate";
import Calculate from "./pages/calculate/calculate"; //重构的薪资核算页面
import Payroll from "./pages/payroll";
// import Payroll from "./pages/payroll";
import Payroll from "./pages/payrollRelease"; //重构的工资单发放页面
import PayrollGrant from "./pages/payroll/payrollGrant";
import PayrollDetail from "./pages/payroll/payrollDetail";
// import Declare from "./pages/declare";
@ -31,6 +32,7 @@ import DoCalcDetail from "./pages/calculate/doCalc";
import OfflineCompare from "./pages/calculate/calcOc";
import GenerateDeclarationDetail from "./pages/declare/generateDeclarationDetail";
import TemplatePreview from "./pages/payroll/templatePreview";
import PayrollTemplatePreview from "./pages/payroll/templatePreview/tmpPreview"; //重构的工资单模板预览页面
import MobilePayroll from "./pages/mobilePayroll";
import SysConfig from "./pages/sysConfig";
import RuleConfig from "./pages/ruleConfig";
@ -147,11 +149,8 @@ const Routes = (
<Route key="watermarkPreview" path="payroll/watermark/preview" component={WatermarkPreview}/>
<Route key="payrollGrant" path="payrollGrant" component={PayrollGrant}/>
<Route key="payrollDetail" path="payrollDetail" component={PayrollDetail}/>
<Route
key="templatePreview"
path="templatePreview"
component={TemplatePreview}
/>
<Route key="templatePreview" path="templatePreview" component={TemplatePreview}/>
<Route key="payrollinfo" path="payrollinfo" component={PayrollTemplatePreview}/>
<Route key="declare" path="declare" component={Declare}/>
<Route
key="generateDeclarationDetail"

View File

@ -262,7 +262,7 @@ export default class BaseInformForm extends React.Component {
}
}
const SendTimeComp = (props) => {
export const SendTimeComp = (props) => {
const { value, onChange, salaryMonthOptions } = props;
const { autoSendDayOfMonth, autoSendTimeOfDay, autoSendCycleType } = value;

View File

@ -152,3 +152,68 @@
}
}
}
//工资单发放-重构页面-工资单模板预览
.salary-payroll-preview {
width: 100%;
height: 100%;
background: #f6f6f6;
display: flex;
flex-direction: column;
.p-header {
height: 50px;
background-color: #0470C1;
.ph-switch {
height: 100%;
margin: 0 auto;
text-align: center;
.active, .phs-btn:hover {
background-color: rgba(0, 0, 0, .15);
transition: all .15s linear;
}
.phs-btn {
height: 50px;
min-width: 88px;
line-height: 50px;
display: inline-block;
color: #fff;
padding: 0 15px;
cursor: pointer;
img {
width: 28px
}
}
}
}
.p-body {
flex: 1;
overflow-y: auto;
.pb-pc-container {
width: 800px;
height: calc(100% - 40px);
margin: 20px auto;
padding: 10px;
background-color: #fff;
box-shadow: 0 0 14px 0 hsla(0, 0%, 84%, .5);
border-radius: 5px;
}
.pb-mobile-container {
position: relative;
width: 430px;
height: calc(100vh - 170px);
background-color: #fff;
box-shadow: 0 0 14px 0 hsla(0, 0%, 84%, .5);
border-radius: 24px;
margin: 60px auto;
}
}
}

View File

@ -0,0 +1,81 @@
/*
* Author: 黎永顺
* name:工资单发放-重构页面-工资单模板预览
* Description:
* Date: 2023/10/18
*/
import React, { Component } from "react";
import { WeaLocaleProvider } from "ecCom";
import { message } from "antd";
import moment from "moment";
import computer from "./computer.png";
import phone from "./phone_new.png";
import PcTemplate from "../../../components/pcTemplate";
import MobileTemplate from "../../../components/mobileTemplate";
import cs from "classnames";
import "./index.less";
const getLabel = WeaLocaleProvider.getLabel;
class TmpPreview extends Component {
constructor(props) {
super(props);
this.state = {
active: "0", theme: "", tip: "", background: "", tipPosi: "", itemTypeList: [],
phsImgList: [
{ key: "0", src: computer },
{ key: "1", src: phone }
]
};
}
componentDidMount() {
const dataStr = window.localStorage.getItem("weapp-salary-payroll-preview-data");
if (!dataStr) {
message.warning(getLabel(111, "参数异常!"));
return;
}
const data = JSON.parse(dataStr);
let theme = data.theme || "";
theme = theme.replaceAll("${salaryMonth}", moment().format("YYYY-MM"));
this.setState({
theme, tip: data.textContent || "",
background: data.background || "",
tipPosi: data.textContentPosition || "",
itemTypeList: data.salaryItemSetting || []
});
if (theme.indexOf("${companyName}") !== -1) {
const themeAccount = window.localStorage.getItem("theme-account") || {};
if (themeAccount)
this.setState({ theme: theme.replaceAll("${companyName}", JSON.parse(themeAccount).subcompanyname) });
}
}
render() {
const { phsImgList, active } = this.state;
return (
<div className="salary-payroll-preview">
<div className="p-header">
<div className="ph-switch">
{
_.map(phsImgList, o => (
<div className={cs("phs-btn", { "active": active === o.key })}
onClick={() => this.setState({ active: o.key })}><img src={o.src} alt=""/>
</div>))
}
</div>
</div>
<div className="p-body">
<div className="pb-pc-container" style={{ display: active === "0" ? "block" : "none" }}>
<PcTemplate {...this.state}/>
</div>
<div className="pb-mobile-container" style={{ display: active === "1" ? "block" : "none" }}>
<MobileTemplate {...this.state}/>
</div>
</div>
</div>
);
}
}
export default TmpPreview;

View File

@ -0,0 +1,275 @@
export const copyConditions = [
{
items: [
{
colSpan: 1,
conditionType: "INPUT",
domkey: ["name"],
fieldcol: 14,
label: "工资单名称",
lanId: 536726,
labelcol: 6,
value: "",
rules: "required|string",
viewAttr: 3
}
],
defaultshow: true,
title: ""
}
];
export const tempBaseSetConditions = [
{
items: [
{
colSpan: 1,
conditionType: "SELECT",
domkey: ["salarySob"],
fieldcol: 14,
label: "薪资账套",
lanId: 538010,
labelcol: 6,
options: [],
value: "",
rules: "required|string",
viewAttr: 3
},
{
colSpan: 1,
conditionType: "INPUT",
domkey: ["name"],
fieldcol: 14,
label: "工资单模板名称",
rules: "required|string",
lanId: 543584,
labelcol: 6,
value: "",
viewAttr: 3
},
{
colSpan: 1,
conditionType: "INPUT",
domkey: ["replenishName"],
fieldcol: 14,
label: "补发工资单模板名称",
lanId: 543585,
labelcol: 6,
rules: "required|string",
value: "",
viewAttr: 3
},
{
colSpan: 1,
conditionType: "SELECT",
domkey: ["reissueRule"],
fieldcol: 14,
label: "补发工资单名单生成规则",
lanId: 543586,
labelcol: 6,
options: [],
value: "0",
detailtype: 3,
rules: "required|string",
viewAttr: 3
},
{
colSpan: 1,
conditionType: "SELECT",
domkey: ["replenishRule"],
fieldcol: 14,
label: "规则设置",
lanId: 126876,
labelcol: 6,
options: [],
value: "",
hide: true
},
{
colSpan: 1,
conditionType: "INPUT",
domkey: ["description"],
fieldcol: 14,
label: "备注",
lanId: 536726,
labelcol: 6,
value: "",
viewAttr: 2
}
],
defaultshow: true,
title: "baseSet"
},
{
items: [
{
colSpan: 1,
conditionType: "SWITCH",
domkey: ["msgStatus"],
fieldcol: 2,
label: "系统消息",
lanId: 543707,
labelcol: 6,
value: "1",
viewAttr: 2
},
{
colSpan: 1,
conditionType: "SWITCH",
domkey: ["emailStatus"],
fieldcol: 2,
label: "邮件",
lanId: 71,
labelcol: 6,
value: "0",
viewAttr: 2
},
{
colSpan: 1,
conditionType: "SWITCH",
domkey: ["autoSendStatus"],
fieldcol: 2,
label: "定时发送",
lanId: 32028,
labelcol: 6,
value: "0",
viewAttr: 2
}
],
defaultshow: true,
title: "sendSet"
}
];
export const tempBaseSetFbConditions = [
{
items: [
{
colSpan: 1,
conditionType: "SWITCH",
domkey: ["ackFeedbackStatus"],
fieldcol: 2,
label: "启用工资单确认",
lanId: 544094,
labelcol: 6,
value: "1",
viewAttr: 2
},
{
colSpan: 1,
conditionType: "INPUTNUMBER",
domkey: ["autoAckDays"],
fieldcol: 14,
label: "自动确认超时天数",
lanId: 544095,
labelcol: 6,
value: 7,
viewAttr: 3,
hide: false,
rules: "required"
},
{
colSpan: 1,
conditionType: "INPUT",
domkey: ["feedbackUrl"],
fieldcol: 14,
label: "反馈流程地址",
lanId: 544096,
labelcol: 6,
value: "/",
viewAttr: 3,
hide: false,
rules: "required|string"
}
],
defaultshow: true,
title: "feedbackSet"
}
];
//正常工资单模板主题设置
export const tempNormalSetConditions = [
{
items: [
{
colSpan: 1,
conditionType: "INPUT",
domkey: ["theme"],
fieldcol: 10,
label: "工资单标题",
lanId: 543588,
labelcol: 6,
value: "",
rules: "required|string",
viewAttr: 3
},
{
colSpan: 1,
conditionType: "UPLOAD",
domkey: ["background"],
fieldcol: 10,
label: "工资单图片",
lanId: 543589,
labelcol: 6,
value: "",
showClearAll: false,
showListBottom: false,
showListTop: false,
// listType: "img",
limitType: "jpg,jpeg,png",
uploadUrl: "/api/doc/upload/uploadFile",
category: "string",
maxFilesNumber: 1,
viewAttr: 2
},
{
colSpan: 1,
conditionType: "INPUT",
domkey: ["textContent"],
fieldcol: 14,
label: "文本内容",
lanId: 20749,
labelcol: 6,
value: "",
viewAttr: 2
},
{
colSpan: 1,
conditionType: "SELECT",
domkey: ["textContentPosition"],
fieldcol: 14,
label: "文本内容位置",
lanId: 543590,
labelcol: 6,
options: [],
value: "",
detailtype: 3,
viewAttr: 2
},
{
colSpan: 1,
conditionType: "SWITCH",
domkey: ["salaryItemNullStatus"],
fieldcol: 2,
label: "薪资项为空时不显示",
lanId: 543591,
labelcol: 6,
value: "",
viewAttr: 2
},
{
colSpan: 1,
conditionType: "SWITCH",
domkey: ["salaryItemZeroStatus"],
fieldcol: 2,
label: "薪资项为0时不显示",
lanId: 543592,
labelcol: 6,
value: "",
viewAttr: 2
}
],
defaultshow: true,
title: "themeSet"
}
];

View File

@ -0,0 +1,159 @@
/*
* Author: 黎永顺
* name: 工资单发放重构-工资单发放列表
* Description:
* Date: 2023/10/12
*/
import React, { Component } from "react";
import { inject, observer } from "mobx-react";
import { WeaLocaleProvider, WeaTable } from "ecCom";
import { Dropdown, Menu, Tag } from "antd";
import { getPayrollList } from "../../../../apis/payroll";
import moment from "moment";
const getLabel = WeaLocaleProvider.getLabel;
@inject("taxAgentStore")
@observer
class Index extends Component {
constructor(props) {
super(props);
this.state = {
loading: false, columns: [], dataSource: [],
pageInfo: { current: 1, pageSize: 10, total: 0 }
};
}
componentDidMount() {
this.getPayrollList(this.props);
}
componentWillReceiveProps(nextProps, nextContext) {
if (nextProps.isRefresh !== this.props.isRefresh) this.getPayrollList(nextProps);
}
getPayrollList = (props) => {
const { pageInfo } = this.state;
const { queryParams } = props;
const { dateRange: salaryYearMonth } = queryParams;
const params = { salaryYearMonth };
const payload = { ...pageInfo, ...params };
this.setState({ loading: true });
getPayrollList(payload).then(({ status, data }) => {
this.setState({ loading: false });
if (status) {
const { columns, pageInfo: { pageNum, pageSize, total, list: dataSource } } = data;
this.setState({
dataSource, pageInfo: { ...pageInfo, pageNum, pageSize, total },
columns: _.map(_.filter(columns, it => it.column !== "acctTimes"), o => {
const { column } = o;
if (column === "salarySob") {
return {
dataIndex: o.column, title: o.text, width: o.width,
render: (text, record) => {
const { acctTimes, salaryAcctType } = record;
return <div className="salarySobNameWrapper">
<span title={text}>{text}</span>
<div className="salarySobNameTagWrapper">
{
salaryAcctType === 1 &&
<Tag color="yellow">补发</Tag>
}
<Tag color="blue">{`${getLabel(15323, "第")}${acctTimes}${getLabel(18929, "次")}`}</Tag>
</div>
</div>;
}
};
}
if (column === "salaryYearMonth" || column === "lastSendTime") {
return {
dataIndex: o.column, title: o.text, width: o.width,
render: (text) => {
const time = moment(parseInt(text)).format("YYYY-MM");
return <span title={time}>{time}</span>;
}
};
}
return { dataIndex: o.column, title: o.text, width: o.width };
})
});
}
}).catch(() => this.setState({ loading: false }));
};
handleOpts = ({ key }, record) => {
const { id, templateId } = record;
switch (key) {
case "template":
console.log(templateId);
break;
default:
break;
}
};
render() {
const { loading, dataSource, columns, pageInfo } = this.state;
const { taxAgentStore: { showOperateBtn } } = this.props;
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.getPayrollList(this.props));
},
onChange: current => {
this.setState({
pageInfo: { ...pageInfo, current }
}, () => this.getPayrollList(this.props));
}
};
return (
<WeaTable
rowKey="id"
dataSource={dataSource} loading={loading} pagination={pagination}
columns={[
...columns,
{
dataIndex: "operate", title: getLabel(30585, "操作"), width: 170,
render: (__, record) => {
const { canSeeDetail, sendNum, sendTotal, haveBackCalc, salaryAcctType, id, ackFeedbackStatus } = record;
//显示更新模板
const showGrant = haveBackCalc === 1 && salaryAcctType === 0;
return <React.Fragment>
{
showOperateBtn &&
<a
href={`/spa/hrmSalary/static/index.html#/main/hrmSalary/payrollGrant?id=${id}&ackFeedbackStatus=${ackFeedbackStatus}`}
style={{ marginRight: 10 }} target="_blank">{getLabel(542702, "发放")}</a>
}
{
canSeeDetail &&
<a href={`/spa/hrmSalary/static/index.html#/main/hrmSalary/payrollDetail?id=${id}`}
style={{ marginRight: 10 }} target="_blank"
>{getLabel(83110, "查看详情")}</a>
}
{
sendNum !== sendTotal && !showGrant &&
<Dropdown
overlay={<Menu onClick={e => this.handleOpts(e, record)}>
<Menu.Item key="template">{getLabel(543603, "更新模板")}</Menu.Item>
</Menu>
}
>
<a href="javascript:void(0);"><i className="icon-coms-more"/></a>
</Dropdown>
}
</React.Fragment>;
}
}
]}
/>
);
}
}
export default Index;

View File

@ -0,0 +1,69 @@
/*
* Author: 黎永顺
* name:工资单发放-重构页面-工资单模板复制
* Description:
* Date: 2023/10/13
*/
import React, { Component } from "react";
import { inject, observer } from "mobx-react";
import { WeaDialog, WeaLocaleProvider } from "ecCom";
import { Button, message } from "antd";
import { getSearchs } from "../../../../util";
import { copyConditions } from "../conditions";
import { duplicatePayroll } from "../../../../apis/payroll";
const getLabel = WeaLocaleProvider.getLabel;
@inject("payrollStore")
@observer
class Index extends Component {
constructor(props) {
super(props);
this.state = {
loading: false
};
}
componentWillReceiveProps(nextProps, nextContext) {
if (nextProps.visible !== this.props.visible && nextProps.visible) nextProps.payrollStore.payrollCopyForm.initFormFields(copyConditions);
if (nextProps.visible !== this.props.visible && !nextProps.visible) nextProps.payrollStore.initPayrollCopyForm();
}
save = () => {
const { payrollStore: { payrollCopyForm }, copyId: id } = this.props;
payrollCopyForm.validateForm().then(f => {
if (f.isValid) {
const payload = payrollCopyForm.getFormParams();
this.setState({ loading: true });
duplicatePayroll({ id, ...payload }).then(({ status, errormsg }) => {
this.setState({ loading: false });
if (status) {
message.success(getLabel(30700, "操作成功!"));
this.props.onCancel("refresh");
} else {
message.error(errormsg);
}
});
} else {
f.showErrors();
}
}).catch(() => this.setState({ loading: false }));
};
render() {
const { loading } = this.state;
const { payrollStore: { payrollCopyForm } } = this.props;
return (
<WeaDialog
{...this.props} style={{ width: 480 }} initLoadCss
buttons={[
<Button type="primary" onClick={this.save} loading={loading}>{getLabel(537558, "保存")}</Button>
]}
>
<div className="payroll-dialog-layout">{getSearchs(payrollCopyForm, copyConditions, 1, false)}</div>
</WeaDialog>
);
}
}
export default Index;

View File

@ -0,0 +1,297 @@
/*
* Author: 黎永顺
* name:工资单发放-重构页面新建编辑模板基础设置
* Description:
* Date: 2023/10/13
*/
import React, { Component } from "react";
import { toJS } from "mobx";
import { WeaFormItem, WeaLocaleProvider, WeaTools } from "ecCom";
import { tempBaseSetConditions, tempBaseSetFbConditions } from "../conditions";
import { getSearchs } from "../../../../util";
import { getPayrollBaseForm, getReplenishRuleSetOptions } from "../../../../apis/payroll";
import { commonEnumList } from "../../../../apis/archive";
import { SendTimeComp } from "../../../payroll/stepForm/baseInformForm";
const getKey = WeaTools.getKey;
const getLabel = WeaLocaleProvider.getLabel;
class Index extends Component {
constructor(props) {
super(props);
this.state = {
conditions: [], salaryMonthOptions: [], fbConditions: [],
formData: {
autoSendDayOfMonth: "1",
autoSendTimeOfDay: "09:00",
autoSendCycleType: "1"
}
};
}
componentDidMount() {
this.commonEnumList();
this.props.visible && this.getPayrollBaseForm(this.props);
}
componentWillReceiveProps(nextProps, nextContext) {
if (nextProps.visible !== this.props.visible && nextProps.visible) this.getPayrollBaseForm(nextProps);
if (nextProps.visible !== this.props.visible && !nextProps.visible) {
nextProps.payrollStore.setTmplDataSource({});
nextProps.payrollStore.initPayrollTempForm();
nextProps.payrollStore.initPayrollTempFeedbackForm();
}
}
commonEnumList = () => {
commonEnumList({ enumClass: "com.engine.salary.enums.salarysend.SalaryAutoSendCycleTypeEnum" })
.then(({ status, data }) => {
if (status && !_.isEmpty(data)) {
this.setState({
salaryMonthOptions: _.map(data, it => ({ key: it.value.toString(), showname: it.defaultLabel }))
});
}
});
};
getPayrollBaseForm = (props) => {
const { tmplId: id, payrollStore: { payrollTempForm, payrollTempFeedbackForm, tmplDataSource } } = props;
getPayrollBaseForm({ id }).then(async ({ status, data }) => {
if (status) {
const { salaryTemplateBaseSet: { salarySobOptions, data: result } } = data;
const {
autoSendDayOfMonth = "1", autoSendTimeOfDay = "09:00", autoSendCycleType = "1",
...fieldsEchoData
} = {
...result, ...toJS(tmplDataSource),
reissueRule: (
(!id && (_.isEmpty(toJS(tmplDataSource)) || (!_.isEmpty(toJS(tmplDataSource)) && toJS(tmplDataSource).replenishRule === "ALL"))) ||
(id && ((_.isEmpty(toJS(tmplDataSource)) && !result.replenishRule) || (!_.isEmpty(toJS(tmplDataSource)) && toJS(tmplDataSource).replenishRule === "ALL")))
) ? "0" : "1"
};
const { data: replenishRuleOptions } = (fieldsEchoData["reissueRule"] === "1" && fieldsEchoData["salarySob"]) ? await getReplenishRuleSetOptions({ salarySobId: fieldsEchoData["salarySob"] }) : [];
this.setState({
conditions: _.map(tempBaseSetConditions, it => {
if (it.title === "baseSet") {
return {
...it, title: getLabel(82743, "基础信息"),
items: _.map(it.items, o => {
if (getKey(o) === "salarySob") {
return {
...o, options: _.map(salarySobOptions, g => ({ key: g.id.toString(), showname: g.name }))
};
} else if (getKey(o) === "reissueRule") {
return {
...o, options: [
{ key: "0", showname: getLabel(332, "全部") },
{ key: "1", showname: getLabel(542696, "按规则") }
]
};
} else if (getKey(o) === "replenishRule") {
return {
...o, hide: (_.isNil(fieldsEchoData["reissueRule"]) || fieldsEchoData["reissueRule"] === "0"),
options: _.map(replenishRuleOptions, t => ({ key: t.id, showname: t.content }))
};
}
return { ...o };
})
};
} else if (it.title === "sendSet") {
return {
...it, title: getLabel(18905, "发送设置"),
items: _.map(it.items, o => {
if (getKey(o) === "autoSendStatus") {
return {
...o,
helpfulTitle: getLabel(544272, "开启后,还需在计划任务中配置定时任务,执行工资单定时发送任务;")
};
}
return { ...o };
})
};
}
}),
fbConditions: _.map(tempBaseSetFbConditions, it => {
if (it.title === "feedbackSet") {
return {
...it, title: getLabel(544092, "工资单确认反馈设置"),
items: _.map(it.items, o => {
if (getKey(o) === "autoAckDays") {
return {
...o,
hide: _.isNil(fieldsEchoData["ackFeedbackStatus"]) ? o.hide : !fieldsEchoData["ackFeedbackStatus"],
helpfulTitle: getLabel(544273, "开启后,还需在计划任务中配置定时任务,执行自动确认任务;邮箱端查看工资单暂不支持确认及反馈;")
};
} else if (getKey(o) === "feedbackUrl") {
return {
...o,
hide: _.isNil(fieldsEchoData["ackFeedbackStatus"]) ? o.hide : !fieldsEchoData["ackFeedbackStatus"]
};
}
return { ...o };
})
};
}
})
}, () => {
payrollTempForm.initFormFields(this.state.conditions);
payrollTempFeedbackForm.initFormFields(this.state.fbConditions);
//字段回显
const tempBaseSetDomkeys = _.reduce(tempBaseSetConditions, (pre, cur) => ([...pre, ..._.map(cur.items, o => getKey(o))]), []),
tempBaseSetFbDomkeys = _.reduce(tempBaseSetFbConditions, (pre, cur) => ([...pre, ..._.map(cur.items, o => getKey(o))]), []);
_.map(tempBaseSetDomkeys, it => {
switch (it) {
case "msgStatus":
payrollTempForm.updateFields({ [it]: _.isNil(fieldsEchoData[it]) ? "1" : fieldsEchoData[it] ? "1" : "0" });
break;
case "reissueRule":
payrollTempForm.updateFields({ [it]: fieldsEchoData[it] ? fieldsEchoData[it] : "0" });
break;
case "emailStatus":
case "autoSendStatus":
payrollTempForm.updateFields({ [it]: fieldsEchoData[it] ? "1" : "0" });
break;
default:
payrollTempForm.updateFields({ [it]: fieldsEchoData[it] ? fieldsEchoData[it].toString() : "" });
break;
}
});
_.map(tempBaseSetFbDomkeys, it => {
if (it === "ackFeedbackStatus") {
payrollTempFeedbackForm.updateFields({ [it]: fieldsEchoData[it] ? "1" : "0" });
} else {
payrollTempFeedbackForm.updateFields({ [it]: fieldsEchoData[it] ? fieldsEchoData[it].toString() : "" });
}
});
this.setState({
formData: {
...this.state.formData,
autoSendDayOfMonth: !_.isNil(autoSendDayOfMonth) ? autoSendDayOfMonth : "1",
autoSendTimeOfDay: !_.isNil(autoSendTimeOfDay) ? autoSendTimeOfDay : "09:00",
autoSendCycleType: !_.isNil(autoSendCycleType) ? autoSendCycleType : "1"
}
});
this.forceUpdate();
});
}
});
};
handleChange = async (params) => {
const { payrollStore: { payrollTempForm, setHasBeenModify } } = this.props;
const key = _.keys(params)[0], salarySobId = payrollTempForm.getFormParams().salarySob,
reissueRule = payrollTempForm.getFormParams().reissueRule;
const { data: replenishRuleOptions } = (reissueRule === "1" && salarySobId) ? await getReplenishRuleSetOptions({ salarySobId }) : [];
if (key === "reissueRule") {
this.setState({
conditions: _.map(this.state.conditions, it => {
if (it.title === getLabel(82743, "基础信息")) {
return {
...it, items: _.map(it.items, o => {
if (getKey(o) === "replenishRule") {
return {
...o, hide: params[key].value === "0",
rules: (!_.isEmpty(replenishRuleOptions) && reissueRule === "1") ? "required|string" : "",
viewAttr: (!_.isEmpty(replenishRuleOptions) && reissueRule === "1") ? 3 : 2,
options: _.map(replenishRuleOptions, t => ({ key: t.id, showname: t.content }))
};
}
return { ...o };
})
};
}
return { ...it };
})
}, () => {
payrollTempForm.initFormFields(this.state.conditions);
this.resetRequiredForm();
});
} else if (key === "salarySob") {
this.setState({
conditions: _.map(this.state.conditions, it => {
if (it.title === getLabel(82743, "基础信息")) {
return {
...it, items: _.map(it.items, o => {
if (getKey(o) === "replenishRule") {
return {
...o, options: _.map(replenishRuleOptions, t => ({ key: t.id, showname: t.content })),
rules: (!_.isEmpty(replenishRuleOptions) && reissueRule === "1") ? "required|string" : "",
viewAttr: (!_.isEmpty(replenishRuleOptions) && reissueRule === "1") ? 3 : 2
};
}
return { ...o };
})
};
}
return { ...it };
})
}, () => {
payrollTempForm.initFormFields(this.state.conditions);
const salarySob = payrollTempForm.getFormDatas().salarySob;
payrollTempForm.updateFields({
name: salarySob.valueSpan,
replenishName: salarySob.valueSpan + "-补发工资单"
});
this.resetRequiredForm();
});
}
setHasBeenModify(true);
this.forceUpdate();
};
resetRequiredForm = () => {
const { payrollStore: { payrollTempForm } } = this.props;
const reissueRule = payrollTempForm.getFormParams().reissueRule;
if (reissueRule === "0") payrollTempForm.updateFields({ replenishRule: "0" });
if (reissueRule === "1") payrollTempForm.updateFields({ replenishRule: "" });
};
handleFbChange = (params) => {
const { payrollStore: { payrollTempFeedbackForm, setHasBeenModify } } = this.props;
const key = _.keys(params)[0];
if (key === "ackFeedbackStatus") {
this.setState({
fbConditions: _.map(this.state.fbConditions, it => {
if (it.title === getLabel(544092, "工资单确认反馈设置")) {
return {
...it, items: _.map(it.items, o => {
if (getKey(o) === "autoAckDays" || getKey(o) === "feedbackUrl") {
return {
...o, hide: params[key].value === "0"
};
}
return { ...o };
})
};
}
return { ...it };
})
}, () => {
payrollTempFeedbackForm.initFormFields(this.state.fbConditions);
const ackFeedbackStatus = payrollTempFeedbackForm.getFormParams().ackFeedbackStatus;
if (ackFeedbackStatus === "0") payrollTempFeedbackForm.updateFields({ autoAckDays: "7", feedbackUrl: "/" });
});
}
setHasBeenModify(true);
this.forceUpdate();
};
render() {
const { conditions, fbConditions, formData, salaryMonthOptions } = this.state;
const { payrollStore: { payrollTempForm, payrollTempFeedbackForm } } = this.props;
const autoSendStatus = payrollTempForm.getFormParams().autoSendStatus;
return (
<React.Fragment>
{!_.isEmpty(fbConditions) && getSearchs(payrollTempForm, conditions, 1, false, this.handleChange)}
{
autoSendStatus === "1" &&
<WeaFormItem className="sendTime-outer" label={getLabel(18961, "发送时间")} labelCol={{ span: 6 }}
wrapperCol={{ span: 16 }}>
<SendTimeComp salaryMonthOptions={salaryMonthOptions} value={{ ...formData }}
onChange={(v) => this.setState({ formData: { ...formData, ...v } })}
/>
</WeaFormItem>
}
{!_.isEmpty(fbConditions) && getSearchs(payrollTempFeedbackForm, fbConditions, 1, false, this.handleFbChange)}
</React.Fragment>
);
}
}
export default Index;

View File

@ -0,0 +1,68 @@
import { WeaSwitch } from "comsMobx";
import { WeaButtonIcon, WeaFormItem, WeaLocaleProvider, WeaSearchGroup, WeaTools } from "ecCom";
const getLabel = WeaLocaleProvider.getLabel;
const getKey = WeaTools.getKey;
export const payrollTempNormalSetForm = (form, condition, background, onChange = () => void (0), insertVar = () => void (0)) => {
const { isFormInit } = form;
const formParams = form.getFormParams();
const img1Props = {
src: background,
width: 100,
height: 100
};
let group = [];
isFormInit && condition && condition.map(c => {
let items = [];
c.items.map(fields => {
items.push({
com: (
<WeaFormItem
label={`${fields.label}`}
labelCol={{ span: `${fields.labelcol}` }}
wrapperCol={{ span: `${fields.fieldcol}` }}
error={form.getError(fields)}
tipPosition="bottom"
>
{
(getKey(fields) === "background" && background) ?
<React.Fragment>
<WeaButtonIcon buttonType="del" type="primary" onClick={() => insertVar("background", "")}/>
<img {...img1Props} alt=""/>
</React.Fragment>
:
<WeaSwitch
fieldConfig={fields}
form={form}
formParams={formParams}
onChange={onChange}
/>
}
{
getKey(fields) === "theme" &&
<div className="sft-variables">
<span className="sftv-tip">{getLabel(500143, "插入变量")}</span>
<a className="sftv-item"
onClick={() => insertVar("theme", "${companyName}")}>{getLabel(1976, "公司名称")}</a>
<a className="sftv-item"
onClick={() => insertVar("theme", "${salaryMonth}")}>{getLabel(542604, "薪资所属月")}</a>
</div>
}
</WeaFormItem>),
colSpan: 1,
hide: fields.hide
});
});
group.push(
<WeaSearchGroup
col={1}
needTigger={true}
title={c.title}
showGroup={c.defaultshow}
items={items}
center={false}
/>);
});
return group;
};

View File

@ -0,0 +1,181 @@
/*
* Author: 黎永顺
* name:工资单发放-重构页面正常核算工资单模板
* Description:
* Date: 2023/10/17
*/
import React, { Component } from "react";
import { inject, observer } from "mobx-react";
import { toJS } from "mobx";
import { WeaButtonIcon, WeaLocaleProvider, WeaSearchGroup, WeaTools } from "ecCom";
import { getPayrollItemList, getPayrollShowForm } from "../../../../apis/payroll";
import { tempNormalSetConditions } from "../conditions";
import { payrollTempNormalSetForm } from "./formRender";
import SalaryItemSettings from "../../../payroll/stepForm/salaryItemSettings";
const getKey = WeaTools.getKey;
const getLabel = WeaLocaleProvider.getLabel;
@inject("payrollStore")
@observer
class Index extends Component {
constructor(props) {
super(props);
this.state = {
conditions: [], salaryBillItemNameSet: {}, salaryItemSet: []
};
}
componentDidMount() {
this.getPayrollShowForm();
}
componentWillUnmount() {
const { payrollStore: { initPayrollTempNormalForm } } = this.props;
initPayrollTempNormalForm();
}
getPayrollShowForm = () => {
const { tmplId: id, payrollStore: { payrollTempNormalForm, tmplDataSource, setTmplDataSource } } = this.props;
getPayrollShowForm({ id }).then(async ({ status, data }) => {
if (status) {
const { salaryTemplateShowSet, salaryTemplateSalaryItemSet: salaryItemSet, salaryBillItemNameSet } = data;
const { data: result } = salaryTemplateShowSet;
const fieldsEchoData = { ...result, ...toJS(tmplDataSource) };
if (!id && !fieldsEchoData.salaryItemSetting) this.getPayrollItemList();
if (id && !fieldsEchoData.salaryItemSetting) {
setTmplDataSource({ salaryItemSetting: salaryItemSet, ...fieldsEchoData });
this.setState({ salaryItemSet });
}
if (fieldsEchoData.salaryItemSetting) {
setTmplDataSource({
salaryItemSetting: _.map(toJS(fieldsEchoData.salaryItemSetting), o => ({
...o,
items: _.map(o.items, it => ({ ...it, viewAttr: 1 }))
})), ...fieldsEchoData
});
this.setState({
salaryItemSet: _.map(toJS(fieldsEchoData.salaryItemSetting), o => ({
...o,
items: _.map(o.items, it => ({ ...it, viewAttr: 1 }))
}))
});
}
this.setState({
conditions: _.map(tempNormalSetConditions, it => {
if (it.title === "themeSet") {
return {
...it, title: getLabel(543587, "主题及其他设置"),
items: _.map(it.items, o => {
if (getKey(o) === "textContentPosition") {
return {
...o, label: getLabel(o.lanId, o.label),
options: [
{ key: "1", showname: getLabel(542697, "薪资项目前") },
{ key: "2", showname: getLabel(542698, "薪资项目后") }
]
};
} else if (getKey(o) === "background") {
return {
...o, title: getLabel(20001, "上传图片")
};
}
return { ...o, label: getLabel(o.lanId, o.label) };
})
};
}
}),
salaryBillItemNameSet
}, () => {
payrollTempNormalForm.initFormFields(this.state.conditions);
//字段回显
const tempBaseSetDomkeys = _.reduce(tempNormalSetConditions, (pre, cur) => ([...pre, ..._.map(cur.items, o => getKey(o))]), []);
_.map(tempBaseSetDomkeys, it => {
switch (it) {
case "salaryItemZeroStatus":
case "salaryItemNullStatus":
payrollTempNormalForm.updateFields({ [it]: fieldsEchoData[it] ? "1" : "0" });
break;
default:
payrollTempNormalForm.updateFields({ [it]: fieldsEchoData[it] ? fieldsEchoData[it].toString() : "" });
break;
}
});
});
}
});
};
getPayrollItemList = () => {
const { salaryItemSet } = this.state;
const { payrollStore: { tmplDataSource, setTmplDataSource } } = this.props;
getPayrollItemList({ salarySobId: toJS(tmplDataSource).salarySob }).then(({ status, data }) => {
if (status && _.isEmpty(salaryItemSet)) {
this.setState({ salaryItemSet: data }, () => {
setTmplDataSource({ ...toJS(tmplDataSource), salaryItemSetting: data });
});
}
});
};
handleChange = (params) => {
const { payrollStore: { payrollTempNormalForm, setTmplDataSource, tmplDataSource } } = this.props;
const key = _.keys(params)[0];
if (key === "background") {
const background = payrollTempNormalForm.getFormDatas().background.valueObj[0].acclink;
setTmplDataSource({ ...toJS(tmplDataSource), background });
}
};
handleInsertVar = (key, themeVar) => {
const { payrollStore: { payrollTempNormalForm, setTmplDataSource, tmplDataSource } } = this.props;
const theme = payrollTempNormalForm.getFormParams().theme;
if (key === "background") {
setTmplDataSource({ ...toJS(tmplDataSource), background: themeVar });
} else {
payrollTempNormalForm.updateFields({ [key]: `${theme}${themeVar}` });
}
};
handleChangeSalaryItem = (resultSet) => {
const { payrollStore: { setTmplDataSource, tmplDataSource } } = this.props;
setTmplDataSource({ ...toJS(tmplDataSource), salaryItemSetting: resultSet });
this.setState({ salaryItemSet: resultSet });
};
handleChangeSalaryItemShowNamesetting = (itemShowNamesetting) => {
const { payrollStore: { setSalaryBillItemNameSetting, salaryBillItemNameSetting } } = this.props;
setSalaryBillItemNameSetting(_.map(salaryBillItemNameSetting, it => {
if (it.salaryBillType === 0) {
return { ...it, salaryTemplateId: this.props.tmplId, itemShowNameSetting: itemShowNamesetting };
}
return { ...it, salaryTemplateId: this.props.tmplId };
}));
};
render() {
const { conditions, salaryBillItemNameSet, salaryItemSet } = this.state;
const { payrollStore: { payrollTempNormalForm, tmplDataSource } } = this.props;
return (
<React.Fragment>
{!_.isEmpty(conditions) && payrollTempNormalSetForm(payrollTempNormalForm, conditions, toJS(tmplDataSource).background, this.handleChange, this.handleInsertVar)}
<WeaSearchGroup
title={
<div className="salarySetTitle">
<span>{getLabel(543593, "薪资项目设置")}</span>
<WeaButtonIcon buttonType="add" type="primary"
onClick={() => this.salaryItemSettingsRef.handleOpenModal(toJS(tmplDataSource).salarySob, getLabel(543594, "添加分类"))}/>
</div>
}
items={[]} needTigger showGroup
>
<SalaryItemSettings
ref={dom => this.salaryItemSettingsRef = dom}
dataSource={salaryItemSet} salaryTemplateId={this.props.tmplId || ""}
onChangeSalaryItem={this.handleChangeSalaryItem}
onChangeSalaryItemShowNamesetting={this.handleChangeSalaryItemShowNamesetting}
salarySobId={toJS(tmplDataSource).salarySob}
isReplenish={false} salaryBillItemNameSet={salaryBillItemNameSet}
/>
</WeaSearchGroup>
</React.Fragment>
);
}
}
export default Index;

View File

@ -0,0 +1,97 @@
/*
* Author: 黎永顺
* name:工资单发放-重构页面补发工资单模板
* Description:
* Date: 2023/10/17
*/
import React, { Component } from "react";
import { toJS } from "mobx";
import { WeaButtonIcon, WeaLocaleProvider, WeaSearchGroup } from "ecCom";
import SalaryItemSettings from "../../../payroll/stepForm/salaryItemSettings";
import { getReplenishForm } from "../../../../apis/payroll";
const getLabel = WeaLocaleProvider.getLabel;
class Index extends Component {
constructor(props) {
super(props);
this.state = {
replenishSalaryTemplateSalaryItemSet: [], salaryBillItemNameSet: {}
};
}
componentDidMount() {
const { payrollStore: { tmplDataSource } } = this.props;
if (!toJS(tmplDataSource.replenishSalaryItemSetting)) {
this.getReplenishForm();
} else {
this.setState({
replenishSalaryTemplateSalaryItemSet: _.map(toJS(tmplDataSource.replenishSalaryItemSetting), o => ({
...o,
items: _.map(o.items, it => ({ ...it, viewAttr: 1 }))
}))
});
}
}
getReplenishForm = () => {
const { payrollStore: { tmplDataSource, setTmplDataSource }, tmplId: id } = this.props;
const salarySobId = toJS(tmplDataSource).salarySob;
getReplenishForm({ salarySobId, id }).then(({ status, data }) => {
if (status) {
const { replenishSalaryTemplateSalaryItemSet, salaryBillItemNameSet } = data;
this.setState({
replenishSalaryTemplateSalaryItemSet, salaryBillItemNameSet
}, () => {
setTmplDataSource({
...toJS(tmplDataSource),
replenishSalaryItemSetting: replenishSalaryTemplateSalaryItemSet
});
});
}
});
};
handleChangeSalaryItem = (resultSet) => {
const { payrollStore: { setTmplDataSource, tmplDataSource } } = this.props;
setTmplDataSource({ ...toJS(tmplDataSource), replenishSalaryItemSetting: resultSet });
this.setState({ replenishSalaryTemplateSalaryItemSet: resultSet });
};
handleChangeSalaryItemShowNamesetting = (itemShowNamesetting) => {
const { payrollStore: { setSalaryBillItemNameSetting, salaryBillItemNameSetting } } = this.props;
setSalaryBillItemNameSetting(_.map(salaryBillItemNameSetting, it => {
if (it.salaryBillType === 1) {
return { ...it, salaryTemplateId: this.props.tmplId, itemShowNameSetting: itemShowNamesetting };
}
return { ...it, salaryTemplateId: this.props.tmplId };
}));
};
render() {
const { payrollStore: { tmplDataSource } } = this.props;
const { replenishSalaryTemplateSalaryItemSet, salaryBillItemNameSet } = this.state;
return (
<WeaSearchGroup
title={
<div className="salarySetTitle">
<span>{getLabel(543593, "薪资项目设置")}</span>
<WeaButtonIcon buttonType="add" type="primary"
onClick={() => this.salaryItemSettingsRef.handleOpenModal(toJS(tmplDataSource).salarySob, getLabel(543594, "添加分类"))}/>
</div>
}
items={[]} needTigger showGroup>
<SalaryItemSettings
ref={dom => this.salaryItemSettingsRef = dom}
dataSource={replenishSalaryTemplateSalaryItemSet}
onChangeSalaryItem={this.handleChangeSalaryItem}
onChangeSalaryItemShowNamesetting={this.handleChangeSalaryItemShowNamesetting}
salarySobId={toJS(tmplDataSource).salarySob}
salaryTemplateId={this.props.tmplId || ""}
isReplenish={true} salaryBillItemNameSet={salaryBillItemNameSet}
/>
</WeaSearchGroup>
);
}
}
export default Index;

View File

@ -0,0 +1,193 @@
/*
* Author: 黎永顺
* name:工资单发放-重构页面-工资单模板设置
* Description:
* Date: 2023/10/13
*/
import React, { Component } from "react";
import { inject, observer } from "mobx-react";
import { WeaLocaleProvider, WeaSelect, WeaTable } from "ecCom";
import { Dropdown, Menu, message, Modal } from "antd";
import { changePayrollDefaultUse, deletePayroll, getPayrollTemplateList } from "../../../../apis/payroll";
import PayrollCopyDialog from "../payrollCopyDialog";
import UpdatePayrollTemplateSlide from "../updatePayrollTemplateSlide";
const getLabel = WeaLocaleProvider.getLabel;
@inject("taxAgentStore")
@observer
class Index extends Component {
constructor(props) {
super(props);
this.state = {
loading: false, columns: [], dataSource: [], selectedRowKeys: [],
pageInfo: { current: 1, pageSize: 10, total: 0 }, delLoading: false,
copyDialog: { visible: false, title: "", copyId: "" },
tmplSlide: {
visible: false, tmplId: "", top: 0, width: 792, height: 100,
measureT: "%", measureX: "px", measureY: "%"
}
};
}
componentDidMount() {
this.getPayrollTemplateList(this.props);
}
componentWillReceiveProps(nextProps, nextContext) {
if (nextProps.isRefresh !== this.props.isRefresh) this.getPayrollTemplateList(nextProps);
}
getPayrollTemplateList = (props) => {
const { pageInfo } = this.state;
const { queryParams } = props;
const { salarySobId, name } = queryParams;
const payload = { ...pageInfo, salarySobId, name };
this.setState({ loading: true });
getPayrollTemplateList(payload).then(({ status, data }) => {
this.setState({ loading: false });
if (status) {
const { columns, list: dataSource, pageNum, pageSize, total } = data;
this.setState({
dataSource, pageInfo: { ...pageInfo, pageNum, pageSize, total },
columns: _.map(_.filter(columns, it => !!it.display), o => {
const { dataIndex } = o;
if (dataIndex === "useType") {
return {
...o, width: "20%", render: (useType, record) => {
return <WeaSelect detailtype={3} value={useType || "0"} options={[{ key: "1", showname: "" }]}
onChange={v => this.handleSwitchUsetype(v, record)}
/>;
}
};
}
return { ...o, width: "20%" };
})
});
}
}).catch(() => this.setState({ loading: false }));
};
handleSwitchUsetype = (v, record) => {
const { id } = record;
changePayrollDefaultUse({ id }).then(({ status, errormsg }) => {
if (status) {
message.success(getLabel(30700, "操作成功!"));
this.getPayrollTemplateList(this.props);
} else {
message.error(errormsg);
}
});
};
handleOpts = ({ key }, record) => {
const { copyDialog, tmplSlide, selectedRowKeys } = this.state;
const { id } = record;
switch (key) {
case "edit":
this.setState({
tmplSlide: { ...tmplSlide, visible: true, tmplId: id }
});
break;
case "copy":
this.setState({
copyDialog: { ...copyDialog, visible: true, copyId: id, title: getLabel(543599, "复制工资单") }
});
break;
case "del":
Modal.confirm({
title: getLabel(131329, "信息确认"),
content: getLabel(388758, "确认要删除吗?"),
onOk: () => {
this.setState({ delLoading: true });
const payload = id ? [id] : selectedRowKeys;
deletePayroll(payload).then(({ status, errormsg }) => {
this.setState({ delLoading: false });
if (status) {
message.success(getLabel(502230, "删除成功!"));
this.getPayrollTemplateList(this.props);
!_.isEmpty(selectedRowKeys) && this.setState({ selectedRowKeys: [] });
} else {
message.error(errormsg);
}
}).catch(() => this.setState({ delLoading: false }));
}
});
break;
default:
break;
}
};
render() {
const { loading, dataSource, columns, pageInfo, copyDialog, tmplSlide, selectedRowKeys } = this.state;
const { taxAgentStore: { showOperateBtn }, forceUpdate } = this.props;
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.getPayrollTemplateList(this.props));
},
onChange: current => {
this.setState({
pageInfo: { ...pageInfo, current }
}, () => this.getPayrollTemplateList(this.props));
}
};
const rowSelection = {
selectedRowKeys,
onChange: selectedRowKeys => this.setState({ selectedRowKeys }, () => forceUpdate())
};
return (
<React.Fragment>
<WeaTable
rowKey="id" rowSelection={rowSelection}
dataSource={dataSource} loading={loading} pagination={pagination}
columns={[
...columns,
{
dataIndex: "operate", title: getLabel(30585, "操作"), width: 170,
render: (__, record) => {
const {} = record;
//显示更新模板
return showOperateBtn ? <React.Fragment>
<a href="javascript:void(0);" onClick={() => this.handleOpts({ key: "edit" }, record)}
style={{ marginRight: 10 }}>{getLabel(501169, "编辑")}</a>
<a href="javascript:void(0);" style={{ marginRight: 10 }}
onClick={() => this.handleOpts({ key: "copy" }, record)}
>{getLabel(77, "复制")}</a>
<Dropdown
overlay={<Menu onClick={e => this.handleOpts(e, record)}>
<Menu.Item key="del">{getLabel(535052, "删除")}</Menu.Item>
</Menu>
}
>
<a href="javascript:void(0);"><i className="icon-coms-more"/></a>
</Dropdown>
</React.Fragment> : <a href="javascript:void(0);">{getLabel(83110, "")}</a>;
}
}
]}
/>
{/*复制工资单模板*/}
<PayrollCopyDialog {...copyDialog}
onCancel={v => this.setState({
copyDialog: { ...copyDialog, visible: false, copyId: "" }
}, () => v === "refresh" && this.getPayrollTemplateList(this.props))}
/>
{/* 新建编辑工资单模板*/}
<UpdatePayrollTemplateSlide {...tmplSlide}
onClose={v => this.setState({
tmplSlide: { ...tmplSlide, visible: false, tmplId: "" }
}, () => v === "refresh" && this.getPayrollTemplateList(this.props))}
/>
</React.Fragment>
);
}
}
export default Index;

View File

@ -0,0 +1,30 @@
/*
* Author: 黎永顺
* name: 工资单发放重构-工资单查询
* Description:
* Date: 2023/10/12
*/
import React, { Component } from "react";
import { WeaHelpfulTip, WeaLocaleProvider } from "ecCom";
import { MonthRangePicker } from "../../../reportView/components/statisticalMicroSettingsSlide";
const getLabel = WeaLocaleProvider.getLabel;
class GrantQuery extends Component {
render() {
const { queryParams } = this.props;
const { dateRange } = queryParams;
return (
<div className="payroll-btn-flex">
<WeaHelpfulTip
width={200} placement="topLeft" style={{ marginRight: 10 }}
title={getLabel(543576, "提示:无工资单模板无法发放工资单,请先设置一个默认使用的工资单模板")}
/>
<MonthRangePicker dateRange={dateRange} viewAttr={2}
onChange={v => this.props.onChange({ dateRange: v })}/>
</div>
);
}
}
export default GrantQuery;

View File

@ -0,0 +1,53 @@
/*
* Author: 黎永顺
* name: 工资单发放重构-工资单模板查询
* Description:
* Date: 2023/10/12
*/
import React, { Component } from "react";
import { WeaInputSearch, WeaLocaleProvider, WeaSelect } from "ecCom";
import { getPayrollTemplateLedgerList } from "../../../../apis/payroll";
const getLabel = WeaLocaleProvider.getLabel;
class TemplateQuery extends Component {
constructor(props) {
super(props);
this.state = {
salarySobOptions: []
};
}
componentDidMount() {
this.getPayrollTemplateLedgerList();
}
getPayrollTemplateLedgerList = () => {
getPayrollTemplateLedgerList().then(({ status, data }) => {
if (status) {
this.setState({
salarySobOptions: _.map(data, o => ({ key: o.id, showname: o.content }))
});
}
});
};
render() {
const { salarySobOptions } = this.state;
const { queryParams } = this.props;
const { salarySobId, name } = queryParams;
return (
<div className="payroll-btn-flex">
<WeaSelect value={salarySobId} options={salarySobOptions} style={{ width: 200 }}
onChange={v => this.props.onChange({ salarySobId: v })}/>
<WeaInputSearch value={name} style={{ marginLeft: 10 }}
placeholder={getLabel(111, "请输入工资单模板名称")}
onChange={v => this.props.onChange({ name: v })}
onSearch={this.props.onSearch}
/>
</div>
);
}
}
export default TemplateQuery;

View File

@ -0,0 +1,280 @@
/*
* Author: 黎永顺
* name: 工资单发放-重构页面编辑模板
* Description:
* Date: 2023/10/13
*/
import React, { Component } from "react";
import { toJS } from "mobx";
import { inject, observer } from "mobx-react";
import { WeaLocaleProvider, WeaSlideModal, WeaSteps } from "ecCom";
import { Button, message, Modal } from "antd";
import PayrollTempBaseSet from "../payrollTempBaseSet";
import PayrollTempNormalSet from "../payrollTempNormalSet";
import PayrollTempReissueSet from "../payrollTempReissueSet";
import { savePayroll, updatePayroll } from "../../../../apis/payroll";
const Step = WeaSteps.Step;
const getLabel = WeaLocaleProvider.getLabel;
const APIFox = { save: savePayroll, update: updatePayroll };
@inject("payrollStore")
@observer
class Index extends Component {
constructor(props) {
super(props);
this.state = {
current: 0, loading: false
};
this.tmpBaseSetRef = null;
}
componentWillReceiveProps(nextProps, nextContext) {
if (nextProps.visible !== this.props.visible && !nextProps.visible) nextProps.payrollStore.setHasBeenModify(false);
}
save = async () => {
const {
payrollStore: {
payrollTempForm, payrollTempFeedbackForm, initPayrollTempForm,
initPayrollTempFeedbackForm, setTmplDataSource, tmplDataSource,
setHasBeenModify
}
} = this.props;
const [tempFormm, fbForm] = await Promise.all([payrollTempForm.validateForm(), payrollTempFeedbackForm.validateForm()]);
if (tempFormm.isValid && fbForm.isValid) {
const { replenishRule, autoSendStatus, emailStatus, msgStatus, ...extraBs } = payrollTempForm.getFormParams(),
{ ackFeedbackStatus, autoAckDays, ...extraFb } = payrollTempFeedbackForm.getFormParams(),
{ formData } = this.tmpBaseSetRef.state;
const payload = {
...toJS(tmplDataSource), ...extraFb, ...formData, ...extraBs,
ackFeedbackStatus: ackFeedbackStatus === "1",
autoSendStatus: autoSendStatus === "1",
emailStatus: emailStatus === "1",
msgStatus: msgStatus === "1",
autoAckDays: Number(autoAckDays),
replenishRule: (replenishRule === "0" || !replenishRule) ? "ALL" : replenishRule
};
setTmplDataSource(payload);
this.setState({ current: this.state.current + 1 }, () => {
initPayrollTempForm();
initPayrollTempFeedbackForm();
setHasBeenModify(true);
});
} else {
tempFormm.showErrors();
fbForm.showErrors();
this.forceUpdate();
}
};
normalSave = () => {
const { payrollStore: { payrollTempNormalForm, setTmplDataSource, tmplDataSource } } = this.props;
payrollTempNormalForm.validateForm().then(f => {
if (f.isValid) {
const {
salaryItemNullStatus,
salaryItemZeroStatus,
background,
...extra
} = payrollTempNormalForm.getFormParams();
const payload = {
...toJS(tmplDataSource), ...extra,
salaryItemZeroStatus: salaryItemZeroStatus === "1",
salaryItemNullStatus: salaryItemNullStatus === "1"
};
setTmplDataSource(payload);
this.setState({ current: this.state.current + 1 });
} else {
f.showErrors();
this.forceUpdate();
}
});
};
savePayroll = () => {
const { payrollStore: { tmplDataSource, salaryBillItemNameSetting, setHasBeenModify }, tmplId: id } = this.props;
const payload = {
...toJS(tmplDataSource), id,
salarySobId: toJS(tmplDataSource).salarySob,
salaryBillItemNameSetting: toJS(salaryBillItemNameSetting)
};
this.setState({ loading: true });
const API = APIFox[id ? "update" : "save"];
API(payload).then(({ status, errormsg }) => {
this.setState({ loading: false });
if (status) {
message.success(getLabel(30700, "操作成功!"));
setHasBeenModify(false);
this.handleClose("refresh");
} else {
message.error(errormsg);
}
}).catch(() => this.setState({ loading: false }));
};
renderTitle = () => {
const { tmplId } = this.props, { current, loading } = this.state;
const { payrollStore: { payrollTempNormalForm, setTmplDataSource, tmplDataSource } } = this.props;
return <div className="payroll-title-flex titleDialog">
<div className="titleCol titleLeftBox">
<div className="titleIcon"><i className="icon-coms-fa"/></div>
<div className="title">{tmplId ? getLabel(543583, "编辑工资单模板") : getLabel(543582, "新建工资单模板")}</div>
</div>
<div className="titleCol titleRightBox">
{
current === 0 ?
<Button type="primary" onClick={this.save}>{getLabel(1402, "下一步")}</Button> :
current === 1 ?
<React.Fragment>
<Button type="ghost"
onClick={() => {
const {
salaryItemNullStatus, salaryItemZeroStatus,
background, ...extra
} = payrollTempNormalForm.getFormParams();
const payload = {
...toJS(tmplDataSource), ...extra,
salaryItemZeroStatus: salaryItemZeroStatus === "1",
salaryItemNullStatus: salaryItemNullStatus === "1"
};
setTmplDataSource(payload);
this.setState({ current: current - 1 });
}}>{getLabel(1876, "上一步")}</Button>
<Button type="primary" onClick={this.normalSave}>{getLabel(1402, "下一步")}</Button>
<Button type="ghost" onClick={this.handlePreview}>{getLabel(221, "预览")}</Button>
</React.Fragment> :
<React.Fragment>
<Button type="ghost"
onClick={() => this.setState({ current: current - 1 })}>{getLabel(1876, "上一步")}</Button>
<Button type="primary" loading={loading} onClick={this.savePayroll}>{getLabel(537558, "保存")}</Button>
</React.Fragment>
}
</div>
</div>;
};
renderSlideContent = () => {
const { current } = this.state;
let dom = null;
switch (current) {
case 0:
dom = <PayrollTempBaseSet {...this.props} ref={dom => this.tmpBaseSetRef = dom}/>;
break;
case 1:
dom = <PayrollTempNormalSet {...this.props} />;
break;
case 2:
dom = <PayrollTempReissueSet {...this.props} />;
break;
default:
break;
}
return dom;
};
handleClose = (type) => {
const {
payrollStore: {
initPayrollTempForm, initPayrollTempFeedbackForm, setSalaryBillItemNameSetting,
initPayrollTempNormalForm, setTmplDataSource, hasBeenModify
}, onClose
} = this.props;
if (hasBeenModify) {
Modal.confirm({
title: getLabel(131329, "信息确认"),
content: getLabel(111, "确定放弃填写吗?放弃后数据将不会被保存!"),
onOk: () => {
initPayrollTempForm();
initPayrollTempFeedbackForm();
initPayrollTempNormalForm();
setTmplDataSource({});
setSalaryBillItemNameSetting([
{
salaryTemplateId: "",
salaryBillType: 0,
itemShowNameSetting: []
},
{
salaryTemplateId: "",
salaryBillType: 1,
itemShowNameSetting: []
}
]);
this.setState({ current: 0 });
onClose(type);
}
});
} else {
initPayrollTempForm();
initPayrollTempFeedbackForm();
initPayrollTempNormalForm();
setTmplDataSource({});
setSalaryBillItemNameSetting([
{
salaryTemplateId: "",
salaryBillType: 0,
itemShowNameSetting: []
},
{
salaryTemplateId: "",
salaryBillType: 1,
itemShowNameSetting: []
}
]);
this.setState({ current: 0 });
onClose(type);
}
};
handlePreview = () => {
const { payrollStore: { payrollTempNormalForm, tmplDataSource } } = this.props;
window.localStorage.removeItem("weapp-salary-payroll-preview-data");
payrollTempNormalForm.validateForm().then(f => {
if (f.isValid) {
const {
salaryItemNullStatus, salaryItemZeroStatus, background, ...extra
} = payrollTempNormalForm.getFormParams();
const { textContentPosition, textContent } = extra;
const bkView = toJS(tmplDataSource).background;
const payload = {
...toJS(tmplDataSource), ...extra, background: bkView,
salaryItemZeroStatus: salaryItemZeroStatus === "1",
salaryItemNullStatus: salaryItemNullStatus === "1"
};
if (textContentPosition !== "0" && ((textContentPosition && !textContent) || (!textContentPosition && textContent))) {
message.warning(getLabel(111, "请完善文本内容与文本内容位置设置!"));
return;
}
window.localStorage.setItem("weapp-salary-payroll-preview-data", JSON.stringify(payload));
setTimeout(() => {
window.open("/spa/hrmSalary/static/index.html#/main/hrmSalary/payrollinfo");
}, 300);
} else {
f.showErrors();
this.forceUpdate();
}
});
};
render() {
const { current } = this.state;
const tabs = [
{ key: 0, title: getLabel(82751, "基础设置") },
{ key: 1, title: getLabel(543579, "正常核算工资单模板") },
{ key: 2, title: getLabel(543580, "补发工资单模版") }
];
return (
<WeaSlideModal {...this.props} title={this.renderTitle()} className="payroll-tmpl-layout"
onClose={() => this.handleClose(null)}
content={(<div className="payroll-tmpl-content">
<WeaSteps current={current} style={{ margin: "0 0 20px 0" }}>
{
_.map(tabs, item => {
const { key, title } = item;
return <Step description={title} key={key}/>;
})
}
</WeaSteps>
{this.renderSlideContent()}
</div>)}
/>
);
}
}
export default Index;

View File

@ -0,0 +1,134 @@
/*
* Author: 黎永顺
* name: 工资单发放-重构页面
* Description:
* Date: 2023/10/12
*/
import React, { Component } from "react";
import { inject, observer } from "mobx-react";
import { WeaLocaleProvider, WeaReqTop } from "ecCom";
import GrantQuery from "./components/reqQuery/grantQuery";
import TemplateQuery from "./components/reqQuery/templateQuery";
import GrantTableList from "./components/grantTableList";
import PayrollTemplateTableList from "./components/payrollTemplateTableList";
import TemplateBaseSettings from "../payroll/templateBaseSettings";
import { Button } from "antd";
import moment from "moment";
import "./index.less";
const getLabel = WeaLocaleProvider.getLabel;
@inject("taxAgentStore")
@observer
class Index extends Component {
constructor(props) {
super(props);
this.state = {
selectedKey: "grant", isRefresh: false, baseSetSaveLoading: false,
queryParams: {
salarySobId: "", name: "",
dateRange: [
moment(new Date()).startOf("year").format("YYYY-MM"),
moment(new Date()).startOf("month").format("YYYY-MM")
]
}
};
this.templateRef = null;
this.baseSetRef = null;
}
renderReqBtns = () => {
const { taxAgentStore: { showOperateBtn } } = this.props;
const { selectedKey, isRefresh, queryParams } = this.state;
let reqBtns = [];
switch (selectedKey) {
case "grant":
reqBtns = [
<GrantQuery queryParams={queryParams}
onChange={v => this.setState({
isRefresh: !isRefresh,
queryParams: { ...queryParams, ...v }
})}/>
];
break;
case "template":
const loading = this.templateRef ? this.templateRef.wrappedInstance.state.delLoading : false;
const delDisabled = !this.templateRef || _.isEmpty(this.templateRef.wrappedInstance.state.selectedRowKeys);
const btns = [
<Button type="primary" onClick={() => {
this.templateRef.wrappedInstance.handleOpts({ key: "edit" }, {});
}}>{getLabel(365, "新建")}</Button>,
<Button type="ghost" loading={loading} disabled={delDisabled} onClick={() => {
this.templateRef.wrappedInstance.handleOpts({ key: "del" }, {});
}}>{getLabel(32136, "批量删除")}</Button>
];
const queryBtns = [
<TemplateQuery queryParams={queryParams} onSearch={() => this.setState({ isRefresh: !isRefresh })}
onChange={v => this.setState({
isRefresh: _.keys(v)[0] === "name" ? isRefresh : !isRefresh,
queryParams: { ...queryParams, ...v }
})}/>
];
reqBtns = showOperateBtn ? [...btns, ...queryBtns] : [...queryBtns];
break;
case "watermark":
const { baseSetSaveLoading } = this.state;
reqBtns = [
<Button type="primary" loading={baseSetSaveLoading}
onClick={() => this.baseSetRef.salaryBillBaseSetSave()}>{getLabel(537558, "保存")}</Button>
];
break;
default:
break;
}
return reqBtns;
};
renderContent = () => {
const { selectedKey, queryParams, isRefresh } = this.state;
let dom = null;
switch (selectedKey) {
case "grant":
dom = <GrantTableList queryParams={queryParams} isRefresh={isRefresh}/>;
break;
case "template":
dom = <PayrollTemplateTableList ref={dom => this.templateRef = dom} queryParams={queryParams}
isRefresh={isRefresh} forceUpdate={() => this.forceUpdate()}/>;
break;
case "watermark":
dom = <TemplateBaseSettings
ref={dom => this.baseSetRef = dom}
onChangeLoading={loading => this.setState({ baseSetSaveLoading: loading })}
/>;
break;
default:
break;
}
return dom;
};
render() {
const { selectedKey, queryParams } = this.state;
const tabs = [
{ key: "grant", title: getLabel(538012, "工资单发放") },
{ key: "template", title: getLabel(543575, "工资单模板设置") },
{ key: "watermark", title: getLabel(545285, "工资单基础设置") }
];
return (
<div className="salary-payroll-main-page">
<WeaReqTop
title={getLabel(538012, "工资单发放")} tabDatas={tabs} selectedKey={selectedKey}
buttonSpace={10} icon={<i className="icon-coms-fa"/>} iconBgcolor="#F14A2D"
onChange={key => this.setState({
selectedKey: key,
queryParams: { ...queryParams, name: "", salarySobId: "" }
})}
buttons={this.renderReqBtns()}
>
<div className="salary-payroll-content">{this.renderContent()}</div>
</WeaReqTop>
</div>
);
}
}
export default Index;

View File

@ -0,0 +1,202 @@
.salary-payroll-main-page {
min-width: 1000px;
overflow: auto;
width: 100%;
height: 100%;
background: #f6f6f6;
.payroll-btn-flex {
display: flex;
align-items: center;
.wea-input-focus {
margin-top: -4px;
}
}
.wea-new-top-req {
z-index: 0 !important;
}
.wea-new-top-req-wapper .wea-new-top-req-title > div:last-child {
right: 16px;
}
.salary-payroll-content {
padding: 8px 16px;
height: 100%;
& > .wea-search-group {
background: #FFF;
}
.wea-new-table {
background: #fff;
}
.payroll-title-flex {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 46px 0 16px;
.titleCol {
flex: 1;
display: flex;
align-items: center;
}
.titleLeftBox {
.titleIcon {
color: #fff;
margin: 0;
width: 40px;
height: 40px;
line-height: 40px;
font-size: 22px;
display: flex;
align-items: center;
justify-content: center;
background: #F14A2D;
border-radius: 50%;
}
.title {
font-size: 14px;
color: #333;
padding-left: 6px;
}
}
.titleRightBox {
justify-content: flex-end;
& > button:not(:last-child) {
margin-right: 10px;
}
}
}
.payroll-tmpl-layout .clipper {
background: #f6f6f6;
}
.payroll-tmpl-content {
padding: 16px;
border-top: 1px solid #e5e5e5;
background: #f6f6f6;
.wea-search-group {
background: #FFF;
padding: 0;
.wea-title {
background: #F6F6F6;
border-bottom: none;
}
.wea-form-cell {
padding: 0;
}
.wea-content {
padding: 0;
.wea-form-cell-wrapper {
border: 1px solid #e5e5e5;
border-bottom: none;
.wea-form-item {
padding: 5px 16px;
border-bottom: 1px solid #e5e5e5;
}
}
}
}
.sendTime-outer {
background: #fff;
padding: 5px 16px;
border-bottom: 1px solid #e5e5e5;
border-left: 1px solid #e5e5e5;
border-right: 1px solid #e5e5e5;
.customTimeCompWrapper {
display: flex;
justify-content: flex-start;
& > div {
margin-right: 10px;
display: flex;
align-items: center;
.wea-select {
width: 80px;
margin: 0 10px;
}
}
}
}
.sft-variables {
display: flex;
align-items: center;
margin-left: 10px;
position: absolute;
top: 25%;
right: -208px;
margin-top: -2px;
.sftv-item {
margin-right: 8px;
padding: 0;
color: #5d9cec;
background-color: transparent;
}
}
.salarySetTitle {
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
}
}
}
}
.payroll-dialog-layout {
background: #f6f6f6;
.wea-search-group {
padding: 16px;
}
.wea-select, .ant-select-selection, .ant-select {
width: 100%;
}
.wea-select {
display: inline-block;
position: relative;
}
.ant-select-selection {
height: 30px;
border-radius: 0;
}
.wea-content {
padding: 0;
.wea-form-cell-wrapper {
background: #FFF;
border: 1px solid #e5e5e5;
border-bottom: none;
.wea-form-cell {
border-bottom: 1px solid #e5e5e5;
}
}
}
}

View File

@ -9,6 +9,36 @@ import { removePropertyCondition } from "../util/response";
const { TableStore } = WeaTableNew;
export class payrollStore {
//工资单重构页面
@observable payrollCopyForm = new WeaForm(); //模板复制form
@action initPayrollCopyForm = () => this.payrollCopyForm = new WeaForm();
@observable payrollTempForm = new WeaForm(); //新建编辑工资单模板form
@action initPayrollTempForm = () => this.payrollTempForm = new WeaForm();
@observable payrollTempFeedbackForm = new WeaForm(); //新建编辑工资单模板-工资单确认反馈设置form
@action initPayrollTempFeedbackForm = () => this.payrollTempFeedbackForm = new WeaForm();
@observable tmplDataSource = {}; //工资单模板数据
@action setTmplDataSource = (v) => this.tmplDataSource = v;//设置工资单模板数据
@observable hasBeenModify = false; //工资单模板数据-是否修改过
@action setHasBeenModify = (v) => this.hasBeenModify = v;//设置工资单模板数据
@observable payrollTempNormalForm = new WeaForm(); //新建编辑工资单模板-主题设置form
@action initPayrollTempNormalForm = () => this.payrollTempNormalForm = new WeaForm();
@observable salaryBillItemNameSetting = [
{
salaryTemplateId: "",
salaryBillType: 0,
itemShowNameSetting: []
},
{
salaryTemplateId: "",
salaryBillType: 1,
itemShowNameSetting: []
}
]; // 工资单模板薪资项目名称修改列表
@action
setSalaryBillItemNameSetting = salaryBillItemNameSetting => (this.salaryBillItemNameSetting = salaryBillItemNameSetting);
@observable tableStore = new TableStore(); // new table
@observable form = new WeaForm(); // nrew 一个form
@observable condition = []; // 存储后台得到的form数据
@ -26,18 +56,7 @@ export class payrollStore {
@observable salaryTemplateShowSet = {}; // 显示设置基础表单
@observable replenishSalaryTemplateSalaryItemSet = []; // 补发工资单模版基础表单
@observable salaryItemSet = []; // 显示设置薪资项
@observable salaryBillItemNameSetting = [
{
salaryTemplateId: "",
salaryBillType: 0,
itemShowNameSetting: []
},
{
salaryTemplateId: "",
salaryBillType: 1,
itemShowNameSetting: []
}
]; // 工资单模板薪资项目名称修改列表
@observable salaryBillItemNameSet = {}; // 工资单模板薪资项目名称修改列表
// **** 工资单页面 ****
@ -102,8 +121,6 @@ export class payrollStore {
setSalaryItemSet = salaryItemSet => (this.salaryItemSet = salaryItemSet);
@action
setSalaryBillItemNameSet = salaryBillItemNameSet => (this.salaryBillItemNameSet = salaryBillItemNameSet);
@action
setSalaryBillItemNameSetting = salaryBillItemNameSetting => (this.salaryBillItemNameSetting = salaryBillItemNameSetting);
@action("工资单模板分页信息修改")
setTemplateTablePageInfo = (pageInfo, callback) => {

View File

@ -45,7 +45,8 @@ export const getSearchs = (form, condition, col, isCenter, onChange = () => void
<WeaHelpfulTip title={fields.helpfulTitle} style={{ position: "absolute", right: "-20px", top: "25%" }}/>
}
</WeaFormItem>),
colSpan: 1
colSpan: 1,
hide: fields.hide
});
});
group.push(