Merge branch 'feature/v2-工资单部分发放和部分撤回-1208' into release

This commit is contained in:
黎永顺 2022-12-07 17:53:13 +08:00
commit a378879fa0
14 changed files with 941 additions and 955 deletions

View File

@ -1,4 +1,5 @@
import { WeaTools } from "ecCom";
import { postFetch } from "../util/request";
//工资单-工资单发放列表
export const getPayrollList = params => {
@ -313,3 +314,16 @@ export const grantProxy = params => {
body: JSON.stringify(params)
}).then(res => res.json());
};
//添加发送和撤回人员范围列表
export const sendRangeList = (params) => {
return postFetch('/api/bs/hrmsalary/salaryBill/send/range/list', params);
}
//创建范围
export const sendRangeSave = (params) => {
return postFetch('/api/bs/hrmsalary/salaryBill/send/range/save', params);
}
//刪除范围
export const sendRangeDelete = (params) => {
return postFetch('/api/bs/hrmsalary/salaryBill/send/range/delete', params);
}

View File

@ -3,8 +3,7 @@ import CustomTable from "../../components/customTable";
class CustomPaginationTable extends PureComponent {
shouldComponentUpdate(nextProps, nextState, nextContext) {
if (nextProps.columnIndex && this.props.columnIndex !== nextProps.columnIndex) return false;
return true;
return !(nextProps.columnIndex && this.props.columnIndex !== nextProps.columnIndex);
}
render() {

View File

@ -1,6 +1,6 @@
import React from "react";
import { inject, observer } from "mobx-react";
import { Dropdown, Menu, message } from "antd";
import { message } from "antd";
import moment from "moment";
import CustomPaginationTable from "../../components/customPaginationTable";
@ -30,12 +30,12 @@ export default class SalarySendList extends React.Component {
handleShowDetail(record) {
window.open(
"/spa/hrmSalary/static/index.html#/main/hrmSalary/payrollDetail?id=" +
record.id
record.id
);
}
// 更新模板
handleUpdateTemplate(record) {
handleUpdateTemplate = (record) => {
let templateRecord = {};
templateRecord.id = record.templateId;
if (!record.templateId) {
@ -43,22 +43,18 @@ export default class SalarySendList extends React.Component {
return;
}
this.props.onEditTemplate && this.props.onEditTemplate(templateRecord);
}
};
// 获取表头数据
getColumns() {
const {
payrollStore: { salarySendTableStore },
taxAgentStore: { showOperateBtn }
} = this.props;
getColumns = () => {
const { payrollStore: { salarySendTableStore }, taxAgentStore: { showOperateBtn } } = this.props;
const { columns } = salarySendTableStore;
if (!columns) {
return [];
}
let result = columns.filter(item => item.hide == "false");
let result = columns.filter(item => item.hide === "false");
result.map(item => {
if (item.dataIndex == "salaryYearMonth") {
if (item.dataIndex === "salaryYearMonth") {
item.render = (text, record) => {
return (
<span>
@ -66,7 +62,7 @@ export default class SalarySendList extends React.Component {
</span>
);
};
} else if (item.dataIndex == "lastSendTime") {
} else if (item.dataIndex === "lastSendTime") {
item.render = (text, record) => {
return (
<span>
@ -82,68 +78,37 @@ export default class SalarySendList extends React.Component {
{
title: "操作",
key: "operate",
render: (text, record) => {
return (
<a
onClick={() => {
this.handleGrant(record);
}}>
发放
</a>
);
}
},
{
title: "",
key: "moreOperate",
dataIndex: "moreOperate",
render: (text, record) => {
const { sendNum, sendTotal } = record;
return (
<Dropdown
overlay={
sendNum !== sendTotal ?
<Menu onClick={({key})=>{
if(key === "1"){
this.handleShowDetail(record)
}else{
this.handleUpdateTemplate(record);
}
}}>
<Menu.Item key="1"> 查看详情 </Menu.Item>
<Menu.Item key="2"> 更新模板 </Menu.Item>
</Menu>:
<Menu onClick={()=>{
this.handleShowDetail(record)
}}>
<Menu.Item key="1"> 查看详情 </Menu.Item>
</Menu>
}>
<i className="icon-coms-more"/>
</Dropdown>
<React.Fragment>
<a href="javascript:void(0);" onClick={() => this.handleGrant(record)}
style={{ marginRight: 10 }}>发放</a>
<a href="javascript:void(0);" onClick={() => this.handleShowDetail(record)}
style={{ marginRight: 10 }}>查看详情</a>
{
sendNum !== sendTotal &&
<a href="javascript:void(0);" onClick={() => this.handleUpdateTemplate(record)}>更新模板</a>
}
</React.Fragment>
);
}
}
]))
:
(result = result.concat([
(result = result.concat([
{
title: "操作",
key: "operate",
render: (text, record) => {
return (
<a
onClick={() => {
this.handleShowDetail(record);
}}>
查看详情
</a>
<a href="javascript:void(0);" onClick={() => this.handleShowDetail(record)}>查看详情</a>
);
}
}
]));
return result;
}
};
render() {
const { payrollStore } = this.props;

View File

@ -6,8 +6,6 @@ import moment from "moment";
import { WeaHelpfulTip, WeaInputSearch, WeaSelect, WeaSlideModal, WeaTop } from "ecCom";
import { renderLoading } from "../../util"; // 渲染form数据的方法因为多个页面都会使用所以抽的公共方法在util中
import CustomTab from "../../components/customTab";
import { columns, tempateColumns } from "./columns";
import StepSlide from "../../components/stepSlide";
import BaseInformForm from "./stepForm/baseInformForm";
import ShowSettingForm from "./stepForm/showSettingForm";
@ -30,7 +28,7 @@ export default class Payroll extends React.Component {
selectedKey: "0",
currentStep: 0,
stepSlideVisible: false,
selectedTab: 0,
selectedTab: "0",
editSlideVisible: false,
initSelected: false,
ledgerOptions: [],
@ -44,44 +42,6 @@ export default class Payroll extends React.Component {
this.recordId = "";
this.salaryYearMonth = [];
this.listPageInfo = { current: 1, pageSize: 10 };
columns.map(item => {
if (item.dataIndex == "cz") {
item.render = (text, record) => {
return (
<div>
<a onClick={() => {
window.open("/spa/hrmSalary/static/index.html#/main/hrmSalary/payrollGrant");
}}>工资单发放</a>
<a onClick={window.open("/spa/hrmSalary/static/index.html#/main/hrmSalary/payrollDetail")}>查看详情</a>
<a onClick={this.handleUpdateTemplate(record)}>更新模板</a>
</div>
);
};
}
});
tempateColumns.map(item => {
if (item.dataIndex == "username") {
item.render = (text) => {
return (
<a onClick={() => {
this.setState({ editSlideVisible: true });
}}>{text}</a>
);
};
} else if (item.dataIndex == "cz") {
item.render = () => {
return (
<div style={{ display: "inline-block" }}>
<a style={{ marginRight: "10px" }}>编辑</a>
<a style={{ marginRight: "10px" }}>复制</a>
<a style={{ marginRight: "10px" }}>删除</a>
{/* <a >操作日志</a> */}
</div>
);
};
}
});
}
// 更新模板
@ -95,19 +55,19 @@ export default class Payroll extends React.Component {
}
// 工资单模板-新建表单变化监听
handleBaseInfoChange(request) {
handleBaseInfoChange = (request) => {
const { payrollStore: { setTemplateBaseData } } = this.props;
setTemplateBaseData(request);
}
};
// 新建保存
handleSave() {
handleSave = () => {
const { payrollStore } = this.props;
const { fetchSavePayroll } = payrollStore;
fetchSavePayroll().then(() => {
this.setState({ currentStep: 0, stepSlideVisible: false });
});
}
};
componentWillMount() {
const { payrollStore } = this.props;
@ -142,7 +102,7 @@ export default class Payroll extends React.Component {
const { getPayrollShowForm } = payrollStore;
this.recordId = record.id;
getPayrollShowForm(record.id);
this.setState({ templateCurrentId: record.id, selectedTab: 0 }, () => {
this.setState({ templateCurrentId: record.id, selectedTab: "0" }, () => {
this.setState({ editSlideVisible: true });
});
}
@ -197,16 +157,16 @@ export default class Payroll extends React.Component {
}
// 预览
handlePreview() {
handlePreview = () => {
const { payrollStore: { templateBaseData, salaryTemplateShowSet, salaryItemSet } } = this.props;
window.localStorage.setItem("templateBaseData", JSON.stringify(templateBaseData));
window.localStorage.setItem("salaryTemplateShowSet", JSON.stringify(salaryTemplateShowSet));
window.localStorage.setItem("salaryItemSet", JSON.stringify(salaryItemSet));
window.open("/spa/hrmSalary/static/index.html#/main/hrmSalary/templatePreview");
}
};
// 更新保存
handleUpdateSave() {
handleUpdateSave = () => {
const { payrollStore } = this.props;
const { fetchUpdatePayroll } = payrollStore;
fetchUpdatePayroll(this.recordId).then(() => {
@ -215,7 +175,7 @@ export default class Payroll extends React.Component {
selectedTab: 0
});
});
}
};
// 发放页面页码跳转
handleListDataPageChange(value, pageInfo) {
@ -233,52 +193,23 @@ export default class Payroll extends React.Component {
render() {
const { payrollStore, taxAgentStore: { showOperateBtn } } = this.props;
const {
loading,
hasRight,
form,
doSearch,
setShowSearchAd,
templateStore,
deletePayroll
} = payrollStore;
const { loading, hasRight, templateStore, deletePayroll } = payrollStore;
const { currentStep, selectedTab, templateSearchValue, templateSelect, startDate, endDate } = this.state;
if (!hasRight && !loading) { // 无权限处理
return renderLoading();
}
const rightMenu = [// 右键菜单
// {
// key: 'BTN_COLUMN',
// icon: <i className='icon-coms-Custom' />,
// content: '显示列定制',
// onClick: this.showColumn
// },
];
const collectParams = { // 收藏功能配置
favname: "工资单发放",
favouritetype: 1,
objid: 0,
link: "wui/index.html#/ns_demo03/index",
importantlevel: 1
};
const adBtn = [ // 高级搜索内部按钮
<Button type="primary" onClick={doSearch}>搜索</Button>,
<Button type="ghost" onClick={() => form.resetForm()}>重置</Button>,
<Button type="ghost" onClick={() => setShowSearchAd(false)}>取消</Button>
];
const topTab = [{
title: "工资单发放",
viewcondition: "0"
},
const topTab = [
{
title: "工资单发放",
viewcondition: "0"
},
{
title: "工资单模板设置",
viewcondition: "1"
}];
}
];
const renderRightOperation = () => {
if (this.state.selectedKey == "0") {
if (this.state.selectedKey === "0") {
return <div style={{ display: "inline-block" }}>
<WeaHelpfulTip
width={200}
@ -306,7 +237,7 @@ export default class Payroll extends React.Component {
/>
</div>
</div>;
} else if (this.state.selectedKey == "1") {
} else if (this.state.selectedKey === "1") {
return (
<div style={{ display: "inline-block" }}>
{
@ -354,29 +285,20 @@ export default class Payroll extends React.Component {
);
}
};
const steps = [
"基础设置",
"显示设置"
];
const steps = ["基础设置", "显示设置"];
const validateStep1 = () => {
const { payrollStore: { templateBaseData } } = this.props;
if (!notNull(templateBaseData.name)) {
message.warning("工资单模板名称不能为空");
return false;
}
if (!notNull(templateBaseData.salarySob)) {
message.warning("薪资账套不能为空");
if (!notNull(templateBaseData.name) || !notNull(templateBaseData.salarySob)) {
Modal.warning({
title: "信息确认",
content: "必要信息不完整,红色*为必填项!"
});
return false;
}
return true;
};
const nextStep = () => {
if (!validateStep1()) {
return;
}
if (!validateStep1()) return;
this.setState({
currentStep: this.state.currentStep + 1
});
@ -395,20 +317,14 @@ export default class Payroll extends React.Component {
icon={<i className="icon-coms-fa"/>} // 左侧图标
iconBgcolor="#F14A2D" // 左侧图标背景色
showDropIcon={false} // 是否显示下拉按钮
dropMenuDatas={rightMenu} // 下拉菜单(和页面的右键菜单相同)
dropMenuProps={{ collectParams }} // 收藏功能: 配置之后显示 收藏、帮助、显示页面地址 这3个功能
>
<CustomTab
topTab={topTab}
searchOperationItem={
renderRightOperation()
}
onChange={(v) => {
this.setState({ selectedKey: v, stepSlideVisible: false, editSlideVisible: false });
}}
<CustomTab topTab={topTab} searchOperationItem={renderRightOperation()}
onChange={(v) => {
this.setState({ selectedKey: v, stepSlideVisible: false, editSlideVisible: false });
}}
/>
{
this.state.selectedKey == 0 &&
this.state.selectedKey === "0" &&
<SalarySendList
onEditTemplate={(record) => {
this.handleTemplateListEdit(record);
@ -424,7 +340,7 @@ export default class Payroll extends React.Component {
}
{
this.state.selectedKey == 1 &&
this.state.selectedKey === "1" &&
<TemplateSettingList
onEdit={(record) => {
this.handleTemplateListEdit(record);
@ -437,7 +353,6 @@ export default class Payroll extends React.Component {
/>
}
</WeaTop>
{
this.state.stepSlideVisible && <StepSlide
visible={this.state.stepSlideVisible}
@ -447,35 +362,29 @@ export default class Payroll extends React.Component {
this.setState({ stepSlideVisible: false });
}}
customOperate={
currentStep == 0 ? [
currentStep === 0 ? [
<Button type="primary" onClick={() => {
nextStep();
}}>下一步</Button>
] : currentStep == 1 ? [
<Button type="default" style={{ marginRight: "10px" }} onClick={() => {
] : currentStep === 1 ? [
<Button type="default" style={{ marginRight: 10 }} onClick={() => {
prevStep();
}}>上一步</Button>,
<Button type="primary" onClick={() => {
this.handleSave();
}}>保存</Button>,
<Button type="default" style={{ marginLeft: "10px" }} onClick={() => {
this.handlePreview();
}}>预览</Button>
<Button type="primary" onClick={this.handleSave}>保存</Button>,
<Button type="default" style={{ marginLeft: 10 }} onClick={this.handlePreview}>预览</Button>
] : []
}
title="新建工资单模板"
content={
<div>
{
currentStep == 0 && <BaseInformForm onChange={(request) => {
this.handleBaseInfoChange(request);
}}/>
currentStep === 0 &&
<BaseInformForm onChange={this.handleBaseInfoChange}/>
}
{
currentStep == 1 && <ShowSettingForm/>
currentStep === 1 && <ShowSettingForm/>
}
</div>
}
/>
}
@ -493,22 +402,16 @@ export default class Payroll extends React.Component {
title={
<SlideModalTitle
subtitle="编辑工资单模板"
tabs={[{ title: "基础设置", key: 0 }, { title: "显示设置", key: 1 }]}
tabs={[{ title: "基础设置", key: "0" }, { title: "显示设置", key: "1" }]}
editable={false}
selectedTab={selectedTab}
showOperateBtn={showOperateBtn}
customOperate={
selectedTab == 0 ? [
<Button type="primary" onClick={() => {
this.handleUpdateSave();
}}>保存</Button>
] : selectedTab == 1 ? [
<Button type="primary" onClick={() => {
this.handleUpdateSave();
}} style={{ marginRight: "10px" }}>保存</Button>,
<Button type="default" onClick={() => {
this.handlePreview();
}}>预览</Button>
selectedTab === "0" ? [
<Button type="primary" onClick={this.handleUpdateSave}>保存</Button>
] : selectedTab === "1" ? [
<Button type="primary" onClick={this.handleUpdateSave} style={{ marginRight: 10 }}>保存</Button>,
<Button type="default" onClick={this.handlePreview}>预览</Button>
] : []
}
subItemChange={
@ -520,13 +423,11 @@ export default class Payroll extends React.Component {
}
content={<div>
{
selectedTab == 0 &&
<BaseInformForm id={this.state.templateCurrentId} onChange={(request) => {
this.handleBaseInfoChange(request);
}}/>
selectedTab === "0" &&
<BaseInformForm id={this.state.templateCurrentId} onChange={this.handleBaseInfoChange}/>
}
{
selectedTab == 1 && <ShowSettingForm id={this.state.templateCurrentId}/>
selectedTab === "1" && <ShowSettingForm id={this.state.templateCurrentId}/>
}
</div>}
onClose={() => this.setState({ editSlideVisible: false }, () => this.setState({ selectedTab: 0 }))}

View File

@ -1,14 +1,15 @@
import React from "react";
import { inject, observer } from "mobx-react";
import { toJS } from "mobx";
import { WeaHelpfulTip, WeaTab, WeaTop } from "ecCom";
import { WeaDropdown, WeaHelpfulTip, WeaTab, WeaTop } from "ecCom";
import { Button, Dropdown, Menu, message } from "antd";
import "./index.less";
import PayrollGrantModal from "./payrollGrantModal";
import PayrollWithdrawModal from "./payrollWithdrawModal";
import { getQueryString } from "../../../util/url";
import { getSearchs } from "../../../util";
import { getSearchs, renderLoading } from "../../../util";
import CustomPaginationTable from "../../../components/customPaginationTable";
import PayrollPartTable from "./payrollPartTable";
const { ButtonSelect } = WeaDropdown;
@inject("payrollStore")
@observer
@ -17,14 +18,20 @@ export default class PayrollGrant extends React.Component {
super(props);
this.state = {
selectedRowKeys: [],
payrollGrantVisible: false,
payrollWithdrawVisible: false,
currentId: ""
currentId: "",
selectedKey: "0",
payrollPartModalParams: {
visible: false,
title: "工资单发放",
grantType: "",
salarySendId: ""
}
};
this.pageInfo = { current: 1, pageSize: 10 };
}
componentWillMount() {
const { selectedKey } = this.state;
let id = getQueryString("id");
this.setState({ currentId: id });
const {
@ -32,113 +39,218 @@ export default class PayrollGrant extends React.Component {
} = this.props;
getPayrollInfo(id);
getInfoList({
salarySendId: id
salarySendId: id,
isGranted: selectedKey !== "0"
});
getPaySa();
}
// 撤回
handleWithdraw(record) {
handleWithdraw = (record) => {
const { payrollStore } = this.props;
const { currentId, selectedKey } = this.state;
const { withdrawPayroll, getInfoList } = payrollStore;
withdrawPayroll({
ids: [record.id],
salarySendId: this.state.currentId
...record,
salarySendId: currentId
}).then(() => {
getInfoList({
salarySendId: this.state.currentId
salarySendId: this.state.currentId,
isGranted: selectedKey !== "0",
current: this.pageInfo.current,
pageSize: this.pageInfo.pageSize
});
this.handleClose();
});
}
};
// 发
handleGrant(record) {
// 发
handleGrant = (record) => {
const { payrollStore } = this.props;
const { currentId, selectedKey } = this.state;
const { grantPayroll, getInfoList } = payrollStore;
grantPayroll({
ids: [record.id],
salarySendId: this.state.currentId
...record,
salarySendId: currentId
}).then(() => {
getInfoList({
salarySendId: this.state.currentId
});
});
}
salarySendId: currentId,
isGranted: selectedKey !== "0",
current: this.pageInfo.current,
pageSize: this.pageInfo.pageSize
});
this.handleClose();
});
};
/*
* Author: 黎永顺
* Description:工资单发放
* Params:
* Date: 2022/12/2
*/
sendPayroll = (key) => {
const { selectedRowKeys, currentId, payrollPartModalParams } = this.state;
switch (key) {
case "ALL":
this.handleGrantAll();
break;
case "SELECT":
if (selectedRowKeys.length === 0) {
message.warning("未选择发放条目");
return;
}
this.fetchGrantPayRoll({
ids: selectedRowKeys,
salarySendId: currentId
});
break;
case "PART":
this.setState({
payrollPartModalParams: {
...payrollPartModalParams,
salarySendId: currentId,
grantType: "grant",
visible: true
}
});
break;
default:
break;
}
};
/*
* Author: 黎永顺
* Description:工资单撤回
* Params:
* Date: 2022/12/2
*/
withdrawalPayroll = (key) => {
const { selectedRowKeys, currentId, payrollPartModalParams } = this.state;
switch (key) {
case "withdrawAll":
this.handleWithdrawAll();
break;
case "recallSelected":
if (selectedRowKeys.length === 0) {
message.warning("未选择撤回条目");
return;
}
this.fetchWithdrawPayroll({
ids: selectedRowKeys,
salarySendId: currentId
});
break;
case "partialWithdrawal":
this.setState({
payrollPartModalParams: {
...payrollPartModalParams,
visible: true,
title: "工资单撤回",
salarySendId: currentId,
grantType: "withdraw"
}
});
break;
default:
break;
}
};
// 全部发送
handleGrantAll() {
handleGrantAll = () => {
const { payrollStore } = this.props;
const { currentId, selectedKey } = this.state;
const { grantPayroll, getInfoList } = payrollStore;
grantPayroll({
ids: [],
salarySendId: this.state.currentId
salarySendId: currentId
}).then(() => {
getInfoList({
salarySendId: this.state.currentId
salarySendId: currentId,
isGranted: selectedKey !== "0"
});
});
}
};
// 发放所选
fetchGrantPayRoll = (payload) => {
const { selectedKey, currentId } = this.state;
const { payrollStore: { grantPayroll, getInfoList } } = this.props;
grantPayroll(payload).then(() => {
getInfoList({
salarySendId: currentId,
isGranted: selectedKey !== "0"
});
this.setState({ selectedRowKeys: [] });
});
};
// 全部撤回
handleWithdrawAll() {
const { payrollStore } = this.props;
const { currentId, selectedKey } = this.state;
const { withdrawPayroll, getInfoList } = payrollStore;
withdrawPayroll({
ids: [],
salarySendId: this.state.currentId
salarySendId: currentId
}).then(() => {
getInfoList({
salarySendId: this.state.currentId
salarySendId: currentId,
isGranted: selectedKey !== "0"
});
});
}
getColumns() {
// 撤回所选
fetchWithdrawPayroll = (payload) => {
const { payrollStore: { withdrawPayroll, getInfoList } } = this.props;
const { currentId, selectedKey } = this.state;
withdrawPayroll(payload).then(() => {
getInfoList({
salarySendId: currentId,
isGranted: selectedKey !== "0"
});
this.setState({ selectedRowKeys: [] });
});
};
getColumns = () => {
const { payrollStore } = this.props;
const { salaryGrantTableStore: columns } = payrollStore;
let result = [
...columns,
{ title: "操作", key: "operation", dataIndex: "operation" }
].map(item => {
item = { ...item };
if (item.dataIndex == "operation") {
item.render = (text, record) => {
if (record.sendStatus == "已发放") {
return [
...toJS(columns),
{
title: "操作",
key: "",
dataIndex: "",
display: true,
render: (text, record) => {
if (record.sendStatus === "已发放") {
return (
<a
onClick={() => {
this.handleWithdraw(record);
}}>
href="javascript:void(0);"
onClick={() => this.handleWithdraw({ ids: [record.id] })}>
撤回
</a>
);
} else {
return (
<a
onClick={() => {
this.handleGrant(record);
}}>
发送
href="javascript:void(0);"
onClick={() => this.handleGrant({ ids: [record.id] })}>
发放
</a>
);
}
};
}
}
return item;
});
return result;
}
];
};
getSearchsAdQuick() {
const { selectedKey } = this.state;
const handleMenuClick = e => {
switch (e.key) {
case "1":
this.setState({ payrollGrantVisible: true });
break;
case "2":
this.setState({ payrollWithdrawVisible: true });
break;
case "3":
this.handleExportAll();
break;
@ -149,37 +261,45 @@ export default class PayrollGrant extends React.Component {
break;
}
};
const menu = (
<Menu onClick={handleMenuClick}>
<Menu.Item key="1">批量发放</Menu.Item>
<Menu.Item key="2">批量撤回</Menu.Item>
<Menu.Item key="3">全部导出</Menu.Item>
<Menu.Item key="4">导出选中</Menu.Item>
{/* <Menu.Item key="3">自定义列</Menu.Item> */}
</Menu>
);
return [
<Button
type="primary"
style={{ marginRight: "10px" }}
onClick={() => {
this.handleGrantAll();
}}>
全部发放
</Button>,
<Button
type="default"
style={{ marginRight: "10px" }}
onClick={() => {
this.handleWithdrawAll();
}}>
全部撤回
</Button>,
<Dropdown.Button style={{ marginRight: "10px" }} overlay={menu}>
更多
</Dropdown.Button>
let btnDom = [
<Dropdown.Button overlay={menu}>
更多
</Dropdown.Button>
];
if (selectedKey === "0") {
btnDom = [
<ButtonSelect
datas={[
{ key: "ALL", show: "全部发放", selected: true },
{ key: "SELECT", show: "发放所选", selected: false },
{ key: "PART", show: "部分发放", selected: false }
]}
btnOnClick={this.sendPayroll}
menuOnClick={(key) => this.sendPayroll(key)}
/>,
...btnDom
];
} else {
btnDom = [
<ButtonSelect
datas={[
{ key: "withdrawAll", show: "全部撤回", selected: true },
{ key: "recallSelected", show: "撤回所选", selected: false },
{ key: "partialWithdrawal", show: "部分撤回", selected: false }
]}
btnOnClick={this.withdrawalPayroll}
menuOnClick={(key) => this.withdrawalPayroll(key)}
/>,
...btnDom
];
}
return btnDom;
}
handleExportAll = () => {
@ -188,11 +308,10 @@ export default class PayrollGrant extends React.Component {
salarySendId: this.state.currentId
});
};
handleExportSelect = () => {
const { selectedRowKeys, currentId } = this.state;
const { payrollStore: { exportPayroll } } = this.props;
if (selectedRowKeys.length == 0) {
if (selectedRowKeys.length === 0) {
message.warning("未选择条目");
return;
}
@ -201,32 +320,37 @@ export default class PayrollGrant extends React.Component {
salarySendId: currentId
});
};
// 分页
handleDataPageChange(value) {
handleDataPageChange = (value) => {
const { payrollStore: { getInfoList } } = this.props;
const { currentId, selectedKey } = this.state;
getInfoList({
salarySendId: this.state.currentId,
salarySendId: currentId,
isGranted: selectedKey !== "0",
...this.pageInfo
});
}
};
handleShowSizeChange(pageInfo) {
const { payrollStore: { getInfoList } } = this.props;
const { currentId, selectedKey } = this.state;
getInfoList({
salarySendId: this.state.currentId,
salarySendId: currentId,
isGranted: selectedKey !== "0",
...pageInfo
});
}
handleSearch=()=> {
handleSearch = () => {
const { payrollStore: { getInfoList, setGrantListShowSearchAd } } = this.props;
const { currentId, selectedKey } = this.state;
setGrantListShowSearchAd(false);
getInfoList({
salarySendId: this.state.currentId,
salarySendId: currentId,
isGranted: selectedKey !== "0",
...this.pageInfo
});
}
};
onSelectChange = value => {
this.setState({
@ -234,26 +358,39 @@ export default class PayrollGrant extends React.Component {
});
};
handleClose = () => {
const { payrollPartModalParams } = this.state;
this.setState({
payrollPartModalParams: {
...payrollPartModalParams,
visible: false,
title: "工资单发放",
grantType: "",
salarySendId: ""
}
});
};
render() {
const { payrollStore } = this.props;
const {
salarySendDetailBaseInfo,
salaryGrantDataSource,
getInfoList,
grantListShowSearchAd,
grantListConditionForm,
grantListCondition,
setGrantListShowSearchAd,
salaryGrantPageInfo
salaryGrantPageInfo,
getInfoList
} = payrollStore;
const { selectedRowKeys } = this.state;
const { selectedRowKeys, selectedKey, currentId, payrollPartModalParams } = this.state;
const rowSelection = {
selectedRowKeys,
onChange: this.onSelectChange
};
const adBtn = [
// 高级搜索内部按钮
<Button type="primary" onClick={()=>this.handleSearch()}>
<Button type="primary" onClick={() => this.handleSearch()}>
搜索
</Button>,
<Button type="ghost" onClick={() => grantListConditionForm.resetForm()}>
@ -263,6 +400,16 @@ export default class PayrollGrant extends React.Component {
取消
</Button>
];
const topTab = [
{
title: "未发送",
viewcondition: "0"
},
{
title: "已发送",
viewcondition: "1"
}
];
return (
<div className="payrollGrant_new">
<WeaTop
@ -274,20 +421,25 @@ export default class PayrollGrant extends React.Component {
/>
<WeaTab
datas={topTab}
keyParam="viewcondition"
selectedKey={selectedKey}
onChange={v =>
this.setState({ selectedKey: v }, () => {
getInfoList({
salarySendId: currentId,
isGranted: v !== "0"
});
})
}
searchType={["base", "advanced"]} // base基础搜索框 advanced显示高级搜索按钮
searchsBasePlaceHolder="请输入姓名"
showSearchAd={grantListShowSearchAd} // 是否展开高级搜索面板
setShowSearchAd={bool => setGrantListShowSearchAd(bool)} //高级搜索面板受控
searchsAd={getSearchs(
grantListConditionForm,
toJS(grantListCondition),
2
)} // 高级搜索内部数据
searchsAd={getSearchs(grantListConditionForm, toJS(grantListCondition), 2)} // 高级搜索内部数据
buttonsAd={adBtn} // 高级搜索内部按钮
onSearch={() => this.handleSearch()} // 点搜索按钮时的回调
// searchsAdQuick={this.getSearchsAdQuick()}
onSearchChange={v =>
grantListConditionForm.updateFields({ username: v })} // 在搜索框中输入的文字改变时的回调: 这里需要同步高级搜索和外部搜索框的值
onSearchChange={v => grantListConditionForm.updateFields({ username: v })} // 在搜索框中输入的文字改变时的回调: 这里需要同步高级搜索和外部搜索框的值
searchsBaseValue={grantListConditionForm.getFormParams().username} // 外部input搜索值受控: 这里和高级搜索的requestname同步
/>
<div className="titleBar">
@ -301,32 +453,7 @@ export default class PayrollGrant extends React.Component {
<WeaHelpfulTip
style={{ marginLeft: "1rem", marginRight: "1rem" }}
width={200}
title={`薪资周期\n
${salarySendDetailBaseInfo.salarySobCycle &&
salarySendDetailBaseInfo.salarySobCycle
.salaryCycle &&
salarySendDetailBaseInfo.salarySobCycle
.salaryCycle
.fromDate} ${salarySendDetailBaseInfo.salarySobCycle &&
salarySendDetailBaseInfo.salarySobCycle.salaryCycle &&
salarySendDetailBaseInfo.salarySobCycle.salaryCycle.endDate}\n
税款所属期\n
${salarySendDetailBaseInfo.salarySobCycle &&
salarySendDetailBaseInfo.salarySobCycle
.taxCycle}\n
考勤取值周期\n
${salarySendDetailBaseInfo.salarySobCycle &&
salarySendDetailBaseInfo.salarySobCycle
.attendCycle &&
salarySendDetailBaseInfo.salarySobCycle
.attendCycle
.fromDate}至${salarySendDetailBaseInfo.salarySobCycle &&
salarySendDetailBaseInfo.salarySobCycle.attendCycle &&
salarySendDetailBaseInfo.salarySobCycle.attendCycle.endDate}\n
福利台账月份\n
引用${salarySendDetailBaseInfo.salarySobCycle &&
salarySendDetailBaseInfo.salarySobCycle
.socialSecurityCycle}的福利台账数据`}
title={<TitleHelp salarySobCycle={salarySendDetailBaseInfo.salarySobCycle}/>}
placement="topLeft"
/>
<span>
@ -343,44 +470,58 @@ export default class PayrollGrant extends React.Component {
</span>
</div>
</div>
<div className="tableWrapper">
<CustomPaginationTable
rowKey="id"
rowSelection={rowSelection}
dataSource={salaryGrantDataSource}
columns={this.getColumns()}
total={salaryGrantPageInfo.total}
current={salaryGrantPageInfo.pageNum}
pageSize={this.pageInfo.pageSize}
onPageChange={value => {
this.pageInfo.current = value;
this.handleDataPageChange(value);
}}
onShowSizeChange={(current, pageSize) => {
this.pageInfo = { current, pageSize };
this.handleShowSizeChange(this.pageInfo);
}}
/>
{
!_.isEmpty(this.getColumns()) ?
<CustomPaginationTable
rowKey="id"
rowSelection={rowSelection}
dataSource={salaryGrantDataSource}
columns={this.getColumns()}
total={salaryGrantPageInfo.total}
current={salaryGrantPageInfo.pageNum}
pageSize={this.pageInfo.pageSize}
onPageChange={value => {
this.pageInfo.current = value;
this.handleDataPageChange(value);
}}
onShowSizeChange={(current, pageSize) => {
this.pageInfo = { current, pageSize };
this.handleShowSizeChange(this.pageInfo);
}}
/> : renderLoading()
}
</div>
{this.state.payrollGrantVisible &&
<PayrollGrantModal
sendId={this.state.currentId}
visible={this.state.payrollGrantVisible}
onCancel={() => {
this.setState({ payrollGrantVisible: false });
}}
/>}
{this.state.payrollWithdrawVisible &&
<PayrollWithdrawModal
sendId={this.state.currentId}
visible={this.state.payrollWithdrawVisible}
onCancel={() => {
this.setState({ payrollWithdrawVisible: false });
}}
/>}
<PayrollPartTable
{...payrollPartModalParams}
onCancel={this.handleClose}
onWithdraw={this.handleWithdraw}
onGrant={this.handleGrant}
/>
</div>
);
}
}
export const TitleHelp = (props) => {
const { salarySobCycle } = props;
const { salaryCycle = {}, attendCycle = {} } = salarySobCycle;
return <div>
<div>
<p>薪资周期</p>
<p>{salaryCycle.fromDate}<span style={{ margin: "0 4px" }}></span>{salaryCycle.endDate}</p>
</div>
<div>
<p>税款所属期</p>
<p>{salarySobCycle.taxCycle}</p>
</div>
<div>
<p>考勤取值周期</p>
<p>{attendCycle.fromDate}<span style={{ margin: "0 4px" }}></span>{attendCycle.endDate}</p>
</div>
<div>
<p>福利台账月份</p>
<p>{`引用${salarySobCycle.socialSecurityCycle}的福利台账数据`}</p>
</div>
</div>;
};

View File

@ -3,31 +3,69 @@
height: 47px;
line-height: 47px;
padding: 0 10px;
.titleBarLeft {
float: left;
}
.titleBarRight {
float: right;
}
}
.tableWrapper {
height: calc(100vh - 180.22px);
overflow: auto;
}
}
.batchReleaseWrapper{
.ant-modal-footer button{
.batchReleaseWrapper {
.ant-modal-footer button {
margin-right: 0 !important;
}
.searchWrapper{
.searchWrapper {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
}
.tableWrpper{
.tableWrpper {
max-height: 500px;
overflow-y: auto;
}
}
.payrollPartModalWrapper {
.wea-select, .ant-select-selection, .ant-select {
width: 100%;
}
.wea-select {
display: inline-block;
position: relative;
}
.ant-select-selection {
height: 30px;
border-radius: 0;
}
}
.payrollPartTableModalWrapper {
.titleWrapper {
display: flex;
align-items: center;
justify-content: space-between;
.rightBtnlist {
display: flex;
align-items: center;
button {
margin-right: 10px;
}
}
}
}

View File

@ -1,62 +0,0 @@
import React from 'react'
import { payrollGrantDetailColumns, dataSource} from '../columns'
export default class PayrollGrantDeatail extends React.Component {
render() {
const handleMenuClick = () => {
}
const menu = (
<Menu onClick={handleMenuClick}>
<Menu.Item key="1">导出选中</Menu.Item>
</Menu>
);
const renderRightOperation = () => {
return (
<div style={{display: "inline-block"}}>
<Dropdown.Button style={{marginRight: "10px"}} overlay={menu}>导出全部</Dropdown.Button>
<WeaInputSearch />
</div>
)
}
return (
<div>
<CustomTab
searchOperationItem={
renderRightOperation()
}
/>
<div className="titleBar">
<div className="titleBarLeft">
<span>薪资所属月2021-11</span>
<WeaHelpfulTip
style={{marginLeft: '10px', marginRight: "10px"}}
width={200}
title="薪资周期\n
2021-11-01至2021-11-30\n
税款所属期\n
2021-12\n
考勤取值周期\n
2021-11-01至2021-11-30\n
福利台账月份\n
引用2021-11的福利台账数据"
placement="topLeft"
/>
<span>工资单模板上海泛微工资单1</span>
</div>
<div className="titleBarRight">
<span>已发放111/<span style={{color: "red"}}>1111</span></span>
<span style={{marginLeft: "10px"}}>未确认111</span>
</div>
</div>
<div>
<Table dataSource={dataSource} columns={payrollGrantDetailColumns} />
</div>
</div>
)
}
}

View File

@ -1,248 +0,0 @@
import React from "react";
import { WeaDialog, WeaHelpfulTip, WeaInputSearch, WeaTable } from "ecCom";
import { Dropdown, Menu, message } from "antd";
import { inject, observer } from "mobx-react";
import "./index.less";
@inject("payrollStore")
@observer
export default class payrollGrantModal extends React.Component {
constructor(props) {
super(props);
this.state = {
selectedRowKeys: [],
current: 1,
searchValue: ""
};
}
// 撤回
handleWithdraw(record) {
const { payrollStore } = this.props;
const { withdrawPayroll, batchSendInfoList } = payrollStore;
withdrawPayroll({
ids: [record.id],
salarySendId: this.props.sendId
}).then(() => {
batchSendInfoList({ salarySendId: this.props.sendId });
});
}
// 发送
handleGrant(record) {
const { payrollStore } = this.props;
const { grantPayroll, batchSendInfoList } = payrollStore;
grantPayroll({
ids: [record.id],
salarySendId: this.props.sendId
}).then(() => {
batchSendInfoList({ salarySendId: this.props.sendId });
});
}
componentWillMount() {
const { payrollStore: { batchSendInfoList } } = this.props;
batchSendInfoList({ salarySendId: this.props.sendId });
}
getColumns() {
const { payrollStore } = this.props;
const { canGrantColumns } = payrollStore;
return [
...canGrantColumns,
{ title: "操作", key: "operation", dataIndex: "operation" }
].map(item => {
if (item.key == "operation") {
item.render = (text, record) => {
if (record.sendStatus == "已发放") {
return (
<a
onClick={() => {
this.handleWithdraw(record);
}}>
撤回
</a>
);
} else {
return (
<a
onClick={() => {
this.handleGrant(record);
}}>
发送
</a>
);
}
};
}
return item;
});
}
onSelectChange = value => {
this.setState({
selectedRowKeys: value
});
};
// 发放
fetchGrantPayRoll(payload) {
const { payrollStore: { grantPayroll } } = this.props;
grantPayroll(payload).then(() => {
const { payrollStore: { getInfoList } } = this.props;
getInfoList({
salarySendId: this.props.sendId
});
this.props.onCancel && this.props.onCancel();
});
}
handleMenuClick(e) {
const { selectedRowKeys } = this.state;
const { payrollStore: { grantPayroll } } = this.props;
if (selectedRowKeys.length == 0) {
message.warning("未选择条目");
return;
}
this.fetchGrantPayRoll({
ids: selectedRowKeys,
salarySendId: this.props.sendId
});
}
handleGrantAll() {
this.fetchGrantPayRoll({ salarySendId: this.props.sendId });
}
handleSearch(value) {
const { payrollStore: { batchSendInfoList } } = this.props;
batchSendInfoList({
salarySendId: this.props.sendId,
keyword: value,
current: this.state.current
});
}
// 分页
handleDataPageChange(value) {
this.setState({ current: value });
const { payrollStore: { batchSendInfoList } } = this.props;
batchSendInfoList({ salarySendId: this.props.sendId, current: value });
}
render() {
const menu = (
<Menu onClick={e => this.handleMenuClick(e)}>
<Menu.Item key="1">发放所选</Menu.Item>
</Menu>
);
const { payrollStore } = this.props;
const {
salarySendDetailBaseInfo,
canGrantDataSource,
canGrantPageInfo
} = payrollStore;
const { selectedRowKeys } = this.state;
const rowSelection = {
selectedRowKeys,
onChange: this.onSelectChange.bind(this)
};
return (
<WeaDialog
style={{ width: 800 }}
initLoadCss
className="batchReleaseWrapper"
title="批量发放"
visible={this.props.visible}
buttons={[
<Dropdown.Button
type="primary"
overlay={menu}
onClick={() => {
this.handleGrantAll();
}}>
全部发放
</Dropdown.Button>
]}
onCancel={() => {
this.props.onCancel();
}}>
<div style={{ padding: "16px 20px" }}>
<div className="searchWrapper">
<div className="titleBarLeft">
<span>
薪资所属月{salarySendDetailBaseInfo.salaryMonth &&
salarySendDetailBaseInfo.salaryMonth
.year}-{salarySendDetailBaseInfo.salaryMonth &&
salarySendDetailBaseInfo.salaryMonth.monthValue}
</span>
<WeaHelpfulTip
style={{ marginLeft: "10px", marginRight: "10px" }}
width={200}
title={`薪资周期\n
${salarySendDetailBaseInfo.salarySobCycle &&
salarySendDetailBaseInfo.salarySobCycle
.salaryCycle &&
salarySendDetailBaseInfo.salarySobCycle
.salaryCycle
.fromDate} ${salarySendDetailBaseInfo.salarySobCycle &&
salarySendDetailBaseInfo.salarySobCycle.salaryCycle &&
salarySendDetailBaseInfo.salarySobCycle.salaryCycle.endDate}\n
税款所属期\n
${salarySendDetailBaseInfo.salarySobCycle &&
salarySendDetailBaseInfo.salarySobCycle
.taxCycle}\n
考勤取值周期\n
${salarySendDetailBaseInfo.salarySobCycle &&
salarySendDetailBaseInfo.salarySobCycle
.attendCycle &&
salarySendDetailBaseInfo.salarySobCycle
.attendCycle
.fromDate}至${salarySendDetailBaseInfo.salarySobCycle &&
salarySendDetailBaseInfo.salarySobCycle.attendCycle &&
salarySendDetailBaseInfo.salarySobCycle.attendCycle.endDate}\n
福利台账月份\n
引用${salarySendDetailBaseInfo.salarySobCycle &&
salarySendDetailBaseInfo.salarySobCycle
.socialSecurityCycle}的福利台账数据`}
placement="topLeft"
/>
<span>
工资单模板{salarySendDetailBaseInfo.template}
</span>
</div>
<WeaInputSearch
value={this.state.searchValue}
onChange={value => {
this.setState({ searchValue: value });
}}
placeholder="请输入姓名"
onSearch={value => {
this.handleSearch(value);
}}
/>
</div>
<div className="tableWrpper">
<WeaTable
rowKey="id"
rowSelection={rowSelection}
dataSource={canGrantDataSource}
columns={this.getColumns()}
pagination={{
onChange: value => {
this.handleDataPageChange(value);
},
total: canGrantPageInfo.total,
current: canGrantPageInfo.pageNum,
showTotal: total => `${total}`
}}
/>
</div>
</div>
</WeaDialog>
);
}
}

View File

@ -0,0 +1,281 @@
/*
* Author: 黎永顺
* name: 工资单部分发放和撤回
* Description:
* Date: 2022/12/2
*/
import React, { Component } from "react";
import { inject, observer } from "mobx-react";
import { WeaBrowser, WeaDialog, WeaFormItem, WeaSearchGroup, WeaSelect } from "ecCom";
import { Button, message, Modal } from "antd";
import { commonEnumList } from "../../../apis/ruleconfig";
import { sendRangeSave } from "../../../apis/payroll";
import "./index.less";
@inject("taxAgentStore")
@observer
class PayrollPartModal extends Component {
constructor(props) {
super(props);
this.state = {
loading: false,
targetTypeList: [],
personalAddItem: [
{
viewAttr: 3,
key: "include",
label: "对象",
targetType: "1",
targetTypeIds: "",
targetTypeIdsNames: ""
},
{
viewAttr: 2,
key: "exclude",
label: "对象中排除",
targetType: "1",
targetTypeIds: "",
targetTypeIdsNames: ""
}
]
};
}
componentDidMount() {
const { taxAgentStore } = this.props;
const { getTaxAgentSelectListAsAdmin } = taxAgentStore;
getTaxAgentSelectListAsAdmin();
}
componentWillReceiveProps(nextProps, nextContext) {
if (nextProps.visible !== this.props.visible) {
nextProps.visible && this.orderRuleEnum();
}
}
orderRuleEnum = () => {
const payload = {
enumClass: "com.engine.salary.enums.salarysend.SalarySendRangeTargetTypeEnum"
};
commonEnumList(payload).then(({ status, data }) => {
if (status) {
this.setState({
targetTypeList: _.map(data, item => {
return {
key: item.value.toString(),
showname: item.defaultLabel
};
})
});
}
});
};
taxAgentRangeSave = () => {
const { grantType, salarySendId, onCancel } = this.props;
const { personalAddItem } = this.state;
let excludeObjParams = [], includeObjParams = [];
if (
_.find(personalAddItem, item => item.viewAttr === 3).targetType !== "0" &&
_.isEmpty(_.find(personalAddItem, item => item.viewAttr === 3).targetTypeIds)
) {
Modal.warning({
title: "信息确认",
content: "必要信息不完整,红色*为必填项!"
});
return;
}
_.map(personalAddItem, it => {
const { key, targetType, targetTypeIds } = it;
if (key === "include") {
if (targetType === "0") {
includeObjParams = [{ targetType, targetId: "" }];
} else {
if (targetTypeIds) {
includeObjParams = _.map(targetTypeIds.split(","), child => ({
targetType, targetId: child
}));
}
}
} else if (key === "exclude") {
if (targetType === "0") {
excludeObjParams = [{ targetType, targetId: "" }];
} else {
if (targetTypeIds) {
excludeObjParams = _.map(targetTypeIds.split(","), child => ({
targetType, targetId: child
}));
}
}
}
});
const payload = {
grantType, salarySendId,
excludeObjParams, includeObjParams
};
this.setState({ loading: true });
sendRangeSave(payload).then(({ status, errormsg }) => {
this.setState({ loading: false });
if (status) {
message.success("保存成功");
this.handleReset();
onCancel();
} else {
message.error(errormsg || "保存失败");
}
}).catch(() => this.setState({ loading: false }));
};
handleChange = (type, value) => {
const { personalAddItem } = this.state;
this.setState({
personalAddItem: _.map(personalAddItem, it => {
if (it.key === type) {
return {
...it,
targetType: value,
targetTypeIds: ""
};
}
return { ...it };
})
});
};
renderBrowser = (item) => {
const { personalAddItem } = this.state;
const { taxAgentStore } = this.props;
const { targetType, targetTypeIds, targetTypeIdsNames, key, viewAttr } = item;
let browserType = {};
if (targetType === "5") {
return <WeaSelect
multiple
viewAttr={viewAttr}
style={{ width: 200 }}
value={targetTypeIds}
options={taxAgentStore.taxAgentAdminOption}
onChange={(targetTypeIds, targetTypeIdsNames) => {
this.setState({
personalAddItem: _.map(personalAddItem, it => {
if (it.key === key) {
return {
...it,
targetTypeIds, targetTypeIdsNames
};
}
return { ...it };
})
});
}}
/>;
} else if (targetType === "0") {
return null;
} else {
switch (targetType) {
case "1":
browserType = { ...browserType, type: 17, title: "人员选择" };
break;
case "2":
browserType = { ...browserType, type: 57, title: "部门选择" };
break;
case "3":
browserType = { ...browserType, type: 164, title: "分部选择" };
break;
case "4":
browserType = { ...browserType, type: 278, title: "岗位选择" };
break;
default:
break;
}
return <WeaBrowser
{...browserType}
viewAttr={viewAttr}
isSingle={false}
value={targetTypeIds}
valueSpan={targetTypeIdsNames}
inputStyle={{ width: 200 }}
onChange={(targetTypeIds, targetTypeIdsNames) => {
this.setState({
personalAddItem: _.map(personalAddItem, it => {
if (it.key === key) {
return {
...it,
targetTypeIds, targetTypeIdsNames
};
}
return { ...it };
})
});
}}
/>;
}
};
handleReset = () => {
this.setState({
personalAddItem: [
{
viewAttr: 3,
key: "include",
label: "对象",
targetType: "1",
targetTypeIds: "",
targetTypeIdsNames: ""
},
{
viewAttr: 2,
key: "exclude",
label: "对象中排除",
targetType: "1",
targetTypeIds: "",
targetTypeIdsNames: ""
}
]
});
};
render() {
const { onCancel, visible } = this.props;
const { targetTypeList, personalAddItem, loading } = this.state;
const buttons = [
<Button type="primary" onClick={this.taxAgentRangeSave} loading={loading}>确定</Button>,
<Button type="ghost" onClick={this.handleReset}>重置</Button>
];
return (
<WeaDialog
initLoadCss
className="payrollPartModalWrapper"
title="添加"
visible={visible}
style={{ width: 600 }}
buttons={buttons}
onCancel={() => {
this.handleReset();
onCancel();
}}
>
<WeaSearchGroup col={1} needTigger title="" showGroup center>
{
_.map(personalAddItem, it => {
const { targetType, key, label } = it;
return <WeaFormItem
key={key}
label={label}
labelCol={{ span: 6 }}
wrapperCol={{ span: 18 }}
>
<div style={{ display: "flex", alignItems: "center" }}>
<WeaSelect
style={{ width: 60, marginRight: 12 }}
value={targetType}
options={targetTypeList}
onChange={(v) => this.handleChange(key, v)}
/>
{this.renderBrowser(it)}
</div>
</WeaFormItem>;
})
}
</WeaSearchGroup>
</WeaDialog>
);
}
}
export default PayrollPartModal;

View File

@ -0,0 +1,201 @@
/*
* Author: 黎永顺
* name: 工资单发放撤回弹框列表
* Description:
* Date: 2022/12/2
*/
import React, { Component } from "react";
import { Button, message, Modal } from "antd";
import { WeaButtonIcon, WeaDialog, WeaInputSearch, WeaTable } from "ecCom";
import { sendRangeDelete, sendRangeList } from "../../../apis/payroll";
import { calcPageNo } from "../../../util";
import PayrollPartModal from "./payrollPartModal";
class PayrollPartTable extends Component {
constructor(props) {
super(props);
this.state = {
searchValue: "",
dialogVisible: false,
loading: {
query: false
},
dataSource: [],
columns: [],
selectedRowKeys: [],
pageInfo: {
current: 1,
pageSize: 10,
total: 0
}
};
}
componentWillReceiveProps(nextProps, nextContext) {
if (nextProps.visible !== this.props.visible) {
nextProps.visible && this.sendRangeList(nextProps);
this.setState({ selectedRowKeys: [] });
}
}
sendRangeList = (props) => {
const { grantType, salarySendId, pageCurrent = {} } = props;
const { pageInfo, loading, searchValue: targetName } = this.state;
const payload = {
grantType,
salarySendId,
targetName,
...pageInfo,
...pageCurrent
};
this.setState({ loading: { ...loading, query: true } });
sendRangeList(payload).then(({ status, data }) => {
this.setState({ loading: { ...loading, query: false } });
if (status) {
const { pageNum: current, pageSize, total, columns, list: dataSource } = data;
this.setState({
pageInfo: { ...pageInfo, current, pageSize, total },
dataSource: _.map(dataSource, it => ({
...it,
includeObj: _.map(it.includeObj, child => child.targetName || child.targetTypeName).join(","),
excludeObj: _.map(it.excludeObj, child => child.targetName || child.targetTypeName).join(",")
})),
columns
});
}
});
};
sendRangeDelete = () => {
const { selectedRowKeys, pageInfo } = this.state;
const { grantType, salarySendId } = this.props;
Modal.confirm({
title: "信息确认",
content: "确认要删除吗?",
onOk: () => {
sendRangeDelete(selectedRowKeys).then(({ status, errormsg }) => {
if (status) {
message.success("刪除成功");
this.setState({ selectedRowKeys: [] }, () => {
this.sendRangeList({
grantType, salarySendId,
pageCurrent: {
current: calcPageNo(pageInfo.total, pageInfo.current, 10, selectedRowKeys.length)
}
});
});
} else {
message.error(errormsg || "刪除失败");
}
});
},
onCancel: () => {
}
});
};
handleOperate = () => {
const { grantType, salarySendId, onWithdraw, onGrant } = this.props;
const { selectedRowKeys } = this.state;
if (_.isEmpty(selectedRowKeys)) {
message.warning("您没有需要处理的对象!");
return;
}
Modal.confirm({
title: "信息确认",
content: `您共选择${selectedRowKeys.length}个对象,确定要${grantType === "grant" ? "发放" : "撤回"}吗?`,
onCancel: () => {
},
onOk: () => {
if (grantType === "grant") {
onGrant({ ids: [salarySendId], salarySendRangeIds: selectedRowKeys });
} else if (grantType === "withdraw") {
onWithdraw({ ids: [salarySendId], salarySendRangeIds: selectedRowKeys });
}
}
});
};
render() {
const { dataSource, columns, pageInfo, loading, selectedRowKeys, dialogVisible, searchValue } = this.state;
const { onCancel, visible, grantType, salarySendId, title } = this.props;
const pagination = {
...pageInfo,
showTotal: total => `${total}`,
showQuickJumper: true,
pageSizeOptions: ["10", "20", "50", "100"],
onChange: current => {
this.setState({
pageInfo: { ...pageInfo, current }
}, () => {
});
}
};
const rowSelection = {
selectedRowKeys,
onChange: (selectedRowKeys) => this.setState({ selectedRowKeys })
};
return (
<WeaDialog
initLoadCss
className="payrollPartTableModalWrapper"
onCancel={() => this.setState({ selectedRowKeys: [] }, () => onCancel())}
title={
<RenderTitle
title={title}
selectedRowKeys={selectedRowKeys}
onAdd={() => this.setState({ dialogVisible: true })}
onDelete={this.sendRangeDelete}
onSave={this.handleOperate}
/>
}
visible={visible}
style={{ width: 700, height: 600 }}
hasScroll
>
<div style={{ display: "flex", justifyContent: "flex-end", margin: "10px 10px 10px 0" }}>
<WeaInputSearch
style={{ width: 220 }}
searchValue={searchValue}
onChange={(searchValue) => this.setState({ searchValue })}
onSearch={() => this.sendRangeList({ grantType, salarySendId })}
placeholder="请输入方案名称"
/>
</div>
<WeaTable
rowKey="id"
rowSelection={rowSelection}
dataSource={dataSource}
pagination={pagination}
loading={loading.query}
columns={columns}
/>
<PayrollPartModal
grantType={grantType}
salarySendId={salarySendId}
visible={dialogVisible}
onCancel={() => this.setState({ dialogVisible: false }, () => {
this.sendRangeList({ grantType, salarySendId });
})}
/>
</WeaDialog>
);
}
}
export default PayrollPartTable;
const RenderTitle = (props) => {
const { title, selectedRowKeys, onAdd, onDelete, onSave } = props;
return <div className="titleWrapper">
<div>{title}</div>
<div className="rightBtnlist">
<Button type="primary" onClick={onSave}>{title.slice(-2)}</Button>
<WeaButtonIcon
buttonType="del"
type="primary"
disabled={_.isEmpty(selectedRowKeys)}
onClick={onDelete}
/>
<WeaButtonIcon buttonType="add" type="primary" onClick={onAdd}/>
</div>
</div>;
};

View File

@ -1,247 +0,0 @@
import React from "react";
import { WeaDialog, WeaHelpfulTip, WeaInputSearch, WeaTable } from "ecCom";
import { Dropdown, Menu } from "antd";
import { inject, observer } from "mobx-react";
@inject("payrollStore")
@observer
export default class PayrollWithdrawModal extends React.Component {
constructor(props) {
super(props);
this.state = {
selectedRowKeys: [],
current: 1
};
}
componentWillMount() {
const { payrollStore } = this.props;
const { batchWithdrawInfoList } = payrollStore;
batchWithdrawInfoList({ salarySendId: this.props.sendId });
}
// 撤回
handleWithdraw(record) {
const { payrollStore } = this.props;
const { withdrawPayroll, batchWithdrawInfoList } = payrollStore;
withdrawPayroll({
ids: [record.id],
salarySendId: this.props.sendId
}).then(() => {
batchWithdrawInfoList({ salarySendId: this.props.sendId });
});
}
// 发送
handleGrant(record) {
const { payrollStore } = this.props;
const { grantPayroll, batchWithdrawInfoList } = payrollStore;
grantPayroll({
ids: [record.id],
salarySendId: this.props.sendId
}).then(() => {
batchWithdrawInfoList({ salarySendId: this.props.sendId });
});
}
getColumns() {
const { payrollStore } = this.props;
const { canWidthdrawColumns } = payrollStore;
return [
...canWidthdrawColumns,
{ title: "操作", key: "operation", dataIndex: "operation" }
].map(item => {
if (item.key == "operation") {
item.render = (text, record) => {
if (record.sendStatus == "已发放") {
return (
<a
onClick={() => {
this.handleWithdraw(record);
}}>
撤回
</a>
);
} else {
return (
<a
onClick={() => {
this.handleGrant(record);
}}>
发送
</a>
);
}
};
}
return item;
});
}
onSelectChange = value => {
this.setState({
selectedRowKeys: value
});
};
// 撤回
fetchWithdrawPayroll(payload) {
const { payrollStore: { grantPayroll, withdrawPayroll } } = this.props;
withdrawPayroll(payload).then(() => {
const { payrollStore: { getInfoList } } = this.props;
getInfoList({
salarySendId: this.props.sendId
});
this.props.onCancel && this.props.onCancel();
});
}
handleMenuClick(e) {
const { selectedRowKeys } = this.state;
const { payrollStore: { grantPayroll } } = this.props;
if (selectedRowKeys.length == 0) {
message.warning("未选择条目");
return;
}
this.fetchWithdrawPayroll({
ids: selectedRowKeys,
salarySendId: this.props.sendId
});
}
handleWithdrawAll() {
this.fetchWithdrawPayroll({ salarySendId: this.props.sendId });
}
// 分页
handleDataPageChange(value) {
this.setState({ current: value });
const { payrollStore } = this.props;
const { batchWithdrawInfoList } = payrollStore;
batchWithdrawInfoList({ salarySendId: this.props.sendId, current: value });
}
handleSearch(value) {
const { payrollStore: { batchWithdrawInfoList } } = this.props;
batchWithdrawInfoList({
salarySendId: this.props.sendId,
keyword: value,
current: this.state.current
});
}
render() {
const menu = (
<Menu onClick={e => this.handleMenuClick(e)}>
<Menu.Item key="1">撤回所选</Menu.Item>
</Menu>
);
const { payrollStore } = this.props;
const {
salarySendDetailBaseInfo,
canWidthdrawColumns,
canWithdrawDataSource,
canWithdrawPageInfo
} = payrollStore;
const { selectedRowKeys } = this.state;
const rowSelection = {
selectedRowKeys,
onChange: this.onSelectChange.bind(this)
};
return (
<WeaDialog
style={{ width: 800 }}
initLoadCss
title="批量撤回"
className="batchReleaseWrapper"
visible={this.props.visible}
buttons={[
<Dropdown.Button
type="primary"
overlay={menu}
onClick={() => {
this.handleWithdrawAll();
}}>
全部撤回
</Dropdown.Button>
]}
onCancel={() => {
this.props.onCancel();
}}>
<div style={{ padding: "16px 20px" }}>
<div className="searchWrapper">
<div className="titleBarLeft">
<span>
薪资所属月{salarySendDetailBaseInfo.salaryMonth &&
salarySendDetailBaseInfo.salaryMonth
.year}-{salarySendDetailBaseInfo.salaryMonth &&
salarySendDetailBaseInfo.salaryMonth.monthValue}
</span>
<WeaHelpfulTip
style={{ marginLeft: "10px", marginRight: "10px" }}
width={200}
title={`薪资周期\n
${salarySendDetailBaseInfo.salarySobCycle &&
salarySendDetailBaseInfo.salarySobCycle
.salaryCycle &&
salarySendDetailBaseInfo.salarySobCycle
.salaryCycle
.fromDate} ${salarySendDetailBaseInfo.salarySobCycle &&
salarySendDetailBaseInfo.salarySobCycle.salaryCycle &&
salarySendDetailBaseInfo.salarySobCycle.salaryCycle.endDate}\n
税款所属期\n
${salarySendDetailBaseInfo.salarySobCycle &&
salarySendDetailBaseInfo.salarySobCycle
.taxCycle}\n
考勤取值周期\n
${salarySendDetailBaseInfo.salarySobCycle &&
salarySendDetailBaseInfo.salarySobCycle
.attendCycle &&
salarySendDetailBaseInfo.salarySobCycle
.attendCycle
.fromDate}至${salarySendDetailBaseInfo.salarySobCycle &&
salarySendDetailBaseInfo.salarySobCycle.attendCycle &&
salarySendDetailBaseInfo.salarySobCycle.attendCycle.endDate}\n
福利台账月份\n
引用${salarySendDetailBaseInfo.salarySobCycle &&
salarySendDetailBaseInfo.salarySobCycle
.socialSecurityCycle}的福利台账数据`}
placement="topLeft"
/>
<span>
工资单模板{salarySendDetailBaseInfo.template}
</span>
</div>
<WeaInputSearch
placeholder="请输入姓名"
value={this.state.searchValue}
onChange={value => {
this.setState({ searchValue: value });
}}
onSearch={value => {
this.handleSearch(value);
}}
/>
</div>
</div>
<div className="tableWrpper">
<WeaTable
rowKey="id"
rowSelection={rowSelection}
dataSource={canWithdrawDataSource}
columns={this.getColumns()}
pagination={{
onChange: value => {
this.handleDataPageChange(value);
},
total: canWithdrawPageInfo.total,
current: canWithdrawPageInfo.pageNum,
showTotal: total => `${total}`
}}
/>
</div>
</WeaDialog>
);
}
}

View File

@ -60,7 +60,7 @@ export default class BaseInformForm extends React.Component {
viewAttr={3}
options={options}
value={salarySob ? salarySob : ""}
style={{ width: "200px" }}
style={{ width: 200 }}
onChange={value => this.hanldeChange({ salarySob: value })}/>
}
</WeaFormItem>

View File

@ -2,6 +2,7 @@ import React from "react";
import { inject, observer } from "mobx-react";
import { Radio, Spin } from "antd";
import { WeaTableNew } from "comsMobx";
const WeaTable = WeaTableNew.WeaTable;
@inject("payrollStore")
@ -76,7 +77,7 @@ export default class TemplateSettingList extends React.Component {
/>
);
default:
return <div dangerouslySetInnerHTML={{ __html: valueSpan }} />;
return <div dangerouslySetInnerHTML={{ __html: valueSpan }}/>;
}
};
return newColumn;
@ -91,15 +92,15 @@ export default class TemplateSettingList extends React.Component {
<div>
{loading
? <div style={{ width: "100%", textAlign: "center" }}>
<Spin />
</div>
<Spin/>
</div>
: <WeaTable // table内部做了loading加载处理页面就不需要再加了
comsWeaTableStore={templateStore} // table store
hasOrder={true} // 是否启用排序
needScroll={true} // 是否启用table内部列表滚动将自适应到父级高度
getColumns={this.getColumns}
onOperatesClick={this.onOperatesClick.bind(this)}
/>}
comsWeaTableStore={templateStore} // table store
hasOrder={true} // 是否启用排序
needScroll={true} // 是否启用table内部列表滚动将自适应到父级高度
getColumns={this.getColumns}
onOperatesClick={this.onOperatesClick.bind(this)}
/>}
</div>
);
}

View File

@ -1,4 +1,4 @@
import { observable, action, toJS } from "mobx";
import { action, observable } from "mobx";
import { message } from "antd";
import { WeaForm, WeaTableNew } from "comsMobx";
@ -160,12 +160,12 @@ export class payrollStore {
this.salarySobOptions = response.salarySobOptions
? response.salarySobOptions.map(item => {
let result = {};
result.showname = item.name;
result.key = item.id + "";
result.selected = false;
return result;
})
let result = {};
result.showname = item.name;
result.key = item.id + "";
result.selected = false;
return result;
})
: [];
resolve({
templateBaseData: this.templateBaseData,
@ -249,11 +249,12 @@ export class payrollStore {
// 工资单模板-新建工资单模板
@action
fetchSavePayroll = () => {
if (!this.validateSalaryTemplateShowSet()) {
return false;
}
let params = this.convertParams();
return new Promise((resolve, reject) => {
if (!this.validateSalaryTemplateShowSet()) {
reject();
return false;
}
API.savePayroll(params).then(res => {
if (res.status) {
message.success("保存成功");
@ -270,12 +271,13 @@ export class payrollStore {
// 工资单模板-更新工资单模板
@action
fetchUpdatePayroll = id => {
if (!this.validateSalaryTemplateShowSet()) {
return false;
}
let params = this.convertParams();
params.id = id;
return new Promise((resolve, reject) => {
if (!this.validateSalaryTemplateShowSet()) {
reject();
return false;
}
API.updatePayroll(params).then(res => {
if (res.status) {
message.success("保存成功");
@ -453,7 +455,7 @@ export class payrollStore {
API.exportDetailList(params);
};
// 工资单发放-导出-工资单发放列表
@action
exportPayroll = (params = {}) => {
API.exportPayroll(params);