salary-management-front/pc4mobx/hrmSalary/pages/payrollFiles/index.js

821 lines
28 KiB
JavaScript
Raw Normal View History

/*
* Author: 黎永顺
* name:薪资档案
* Description:
* Date: 2022-10-10 17:53:44
*/
import React, { Component } from "react";
import { toJS } from "mobx";
import { inject, observer } from "mobx-react";
import { tabCondition } from "./config";
import * as API from "../../apis/payrollFiles";
import {
WeaBrowser,
WeaFormItem,
WeaHelpfulTip,
WeaInput,
WeaSearchGroup,
WeaSelect,
WeaSlideModal,
WeaTab,
WeaTable,
WeaTop
} from "ecCom";
import { WeaTableNew } from "comsMobx";
import { Button, Dropdown, Menu, message, Modal, Popover } from "antd";
import ImportMenu from "./components/importMenu";
import ExportMenu from "./components/exportMenu";
import AllWithoutPay from "./components/allWithoutPay";
import BatchSuspendsPay from "./components/batchSuspendsPay";
import SlideModalTitle from "../../components/slideModalTitle";
import SalaryFileViewSlide from "../salaryFile/saralyFileViewSlide";
import ChangeSalaryModal from "../salaryFile/changeSalaryModal";
import "./index.less";
const WeaTableComx = WeaTableNew.WeaTable;
@inject("payrollFilesStore", "taxAgentStore", "salaryFileStore")
@observer
class Index extends Component {
constructor(props) {
super(props);
this.state = {
selectedKey: "pending",
showSearchAd: false,
dataSource: [],
archiveStatusList: [],
userStatusList: [],
importType: [],
selectedRowKeys: [],
tabCount: {
SUSPEND: 0,
STOP: 0,
FIXED: 0,
PENDING: 0
},
loading: {
query: false,
add: false,
update: false
},
pageInfo: {
current: 1,
pageSize: 10,
total: 0
},
searchItemsValue: {
username: "",
departmentIds: "",
positionIds: "",
userstatus: "",
// archiveStatus: "EFFICIENT",
taxAgentId: "",
subcompanyIds: ""
},
salaryAdjustmentInfo: {},
changeSalaryVisible: false,
noPayDate: "",
slideParams: {
visible: false,
id: ""
},
paysetParams: {
payStartDate: "",
payEndDate: ""
}
};
}
Input = (value, key) => {
const { username } = this.state.searchItemsValue;
return (
<WeaFormItem
label={value}
labelCol={{ span: 6 }}
wrapperCol={{ span: 18 }}
>
<WeaInput value={username} onChange={(val) => this.setState({
searchItemsValue: {
...this.state.searchItemsValue,
[key]: val
}
})}/>
</WeaFormItem>
);
};
Browser = (value, key) => {
const { positionIds, departmentIds, subcompanyIds } = this.state.searchItemsValue;
return (
<WeaFormItem
label={value}
labelCol={{ span: 6 }}
wrapperCol={{ span: 18 }}
>
<WeaBrowser
isSingle={false}
value={key === "departmentIds" ? departmentIds : key === "subcompanyIds" ? subcompanyIds : positionIds}
type={key === "departmentIds" ? 57 : key === "subcompanyIds" ? 164 : 278}
onChange={(val) => {
this.setState({ searchItemsValue: { ...this.state.searchItemsValue, [key]: val } });
}}/>
</WeaFormItem>
);
};
Select = (value, key) => {
const { taxAgentStore } = this.props;
const { userstatus, archiveStatus, taxAgentId } = this.state.searchItemsValue;
const { archiveStatusList, userStatusList } = this.state;
const { taxAgentAdminOption } = taxAgentStore;
return (
<WeaFormItem
label={value}
labelCol={{ span: 6 }}
wrapperCol={{ span: 18 }}
>
<WeaSelect
value={key === "userstatus" ? userstatus : key === "taxAgentId" ? taxAgentId : archiveStatus}
options={key === "userstatus" ? userStatusList : key === "taxAgentId" ? [{
key: "",
showname: ""
}, ...taxAgentAdminOption] : archiveStatusList}
onChange={(val) => this.setState({ searchItemsValue: { ...this.state.searchItemsValue, [key]: val } })}/>
</WeaFormItem>
);
};
componentDidMount() {
const { taxAgentStore } = this.props;
const { getTaxAgentSelectListAsAdmin } = taxAgentStore;
getTaxAgentSelectListAsAdmin();
const init = this.init();
this.queryList("/api/bs/hrmsalary/salaryArchive/pendingList");
}
init = async () => {
const { data: archiveStatusList } = await this.commonEnumList({ enumClass: "com.engine.salary.enums.salaryarchive.ArchiveStatusEnum" });
const { data: userStatusList } = await this.commonEnumList({ enumClass: "com.engine.salary.enums.UserStatusEnum" });
this.setState({
archiveStatusList: [{
key: "",
showname: ""
}, ..._.map(archiveStatusList, it => ({
key: String(it.value),
showname: it.defaultLabel
}))],
userStatusList: [{
key: "",
showname: ""
}, ..._.map(userStatusList, it => ({
key: String(it.value),
showname: it.defaultLabel
}))]
}, () =>
this.getImportTypes());
};
salaryAdjustmentInfo = () => {
API.salaryAdjustmentInfo().then(({ status, data }) => {
if (status) {
this.setState({ salaryAdjustmentInfo: data });
}
});
};
queryTabTotal = () => {
API.queryTabTotal().then(({ data = {}, status }) => {
if (status) {
this.setState({ tabCount: { ...this.state.tabCount, ...data } });
}
});
};
queryList = (url) => {
const { loading, pageInfo, searchItemsValue } = this.state;
const { payrollFilesStore: { tableStore, queryList } } = this.props;
const payload = { ...pageInfo };
this.setState({ loading: { ...loading, query: true } });
queryList(payload, searchItemsValue, url).then(({ data, status }) => {
this.setState({ loading: { ...loading, query: false } });
if (status) {
const { pageInfo: paganition } = data;
const { list: dataSource, total, pageNum: current, pageSize } = paganition;
this.setState({
dataSource,
pageInfo: {
...pageInfo,
total,
current,
pageSize
}
});
this.queryTabTotal();
}
});
};
//一键全部设为定薪员工
allGotoFixed = () => {
const { pageInfo } = this.state;
if (pageInfo.total === 0) {
message.warning("您没有需要处理的待定薪人员!");
return;
}
Modal.warning({
title: "信息确认",
content: `确定要将所有待定薪人员(共${pageInfo.total}条数据)设为发薪人员吗?`,
onOk: () => {
API.allGotoFixed({}).then(({ status, data, errormsg }) => {
if (status) {
const { msg }= data;
message.info(msg || "操作成功!");
this.query();
} else {
message.error(errormsg || "操作失败!");
}
}).catch(err => {
console.log(err);
});
}
});
};
commonEnumList = (params) => {
return API.commonEnumList(params);
};
getImportTypes = () => {
API.getImportTypes().then(({ data, status }) => {
if (status) {
this.setState({
importType: data
});
}
});
};
//取消停薪
cancelStop = (id) => {
API.cancelStop([id]).then(({ status, errormsg }) => {
if (status) {
message.success("操作成功!");
this.query();
} else {
message.error(errormsg || "操作失败!");
}
});
};
//待定薪删除待办
deletePendingTodo = (params) => {
API.deletePendingTodo(params).then(({ status, errormsg }) => {
if (status) {
message.success("操作成功!");
this.setState({
selectedRowKeys: []
}, () => {
this.query();
});
} else {
message.error(errormsg || "操作失败!");
}
});
};
//待停薪删除待办
deleteSuspendTodo = (params) => {
API.deleteSuspendTodo(params).then(({ status, errormsg }) => {
if (status) {
message.success("操作成功!");
this.setState({
selectedRowKeys: []
}, () => {
this.query();
});
} else {
message.error(errormsg || "操作失败!");
}
});
};
getRightOptionBtns = () => {
const { selectedKey, importType, selectedRowKeys, searchItemsValue, pageInfo } = this.state;
const { taxAgentStore: { showOperateBtn } } = this.props;
if (selectedKey === "pending" && showOperateBtn) {
return [
<Dropdown overlay={
<ImportMenu
importType={_.filter(importType, it => it.id !== "salaryItemAdjust")}
refreshList={() => {
this.query();
this.setState({ selectedRowKeys: [] });
}}/>}>
<Button type="primary" style={{ marginLeft: 8 }}>导入<i className="icon-coms-down2" style={{
marginLeft: 8,
verticalAlign: "middle"
}}/></Button>
</Dropdown>,
<Dropdown overlay={<ExportMenu selectedKey={selectedKey} selectedRowKeys={selectedRowKeys} searchItemsValue={searchItemsValue}/>}>
<Button type="primary" style={{ marginLeft: 8 }}>导出<i className="icon-coms-down2" style={{
marginLeft: 8,
verticalAlign: "middle"
}}/></Button>
</Dropdown>,
<Button type="ghost" onClick={this.allGotoFixed}>全部设为发薪人员</Button>
];
} else if (selectedKey === "fixed" && showOperateBtn) {
return [
<WeaHelpfulTip
width={300}
title={<HelpfulDiv/>}
placement="topLeft"
/>,
<Dropdown overlay={
<ImportMenu
importType={importType}
refreshList={() => {
this.query();
this.setState({ selectedRowKeys: [] });
}}/>
}>
<Button type="primary" style={{ marginLeft: 8 }}>导入<i className="icon-coms-down2" style={{
marginLeft: 8,
verticalAlign: "middle"
}}/></Button>
</Dropdown>,
<Dropdown overlay={<ExportMenu selectedKey={selectedKey} selectedRowKeys={selectedRowKeys} searchItemsValue={searchItemsValue}/>}>
<Button type="primary" style={{ marginLeft: 8 }}>导出<i className="icon-coms-down2" style={{
marginLeft: 8,
verticalAlign: "middle"
}}/></Button>
</Dropdown>
];
} else if (selectedKey === "suspend" && showOperateBtn) {
return [
<Dropdown overlay={
<AllWithoutPay
pageInfo={pageInfo}
selectedRowKeys={selectedRowKeys}
refreshList={() => {
this.query();
this.setState({ selectedRowKeys: [] });
}}
/>
}>
<Button type="primary" style={{ marginLeft: 8 }}>全部停薪<i className="icon-coms-down2" style={{
marginLeft: 8,
verticalAlign: "middle"
}}/></Button>
</Dropdown>,
<Button type="ghost" onClick={() => {
const { selectedRowKeys } = this.state;
if (selectedRowKeys.length === 0) {
message.warning("未选择条目");
return;
}
this.deleteSuspendTodo(selectedRowKeys);
}}>批量删除待办</Button>,
<Dropdown overlay={
<ImportMenu
importType={_.filter(importType, it => it.id !== "salaryItemAdjust")}
refreshList={() => {
this.query();
this.setState({ selectedRowKeys: [] });
}}/>
}>
<Button type="primary" style={{ marginLeft: 8 }}>导入<i className="icon-coms-down2" style={{
marginLeft: 8,
verticalAlign: "middle"
}}/></Button>
</Dropdown>,
<Dropdown overlay={<ExportMenu selectedKey={selectedKey} selectedRowKeys={selectedRowKeys} searchItemsValue={searchItemsValue}/>}>
<Button type="primary" style={{ marginLeft: 8 }}>导出<i className="icon-coms-down2" style={{
marginLeft: 8,
verticalAlign: "middle"
}}/></Button>
</Dropdown>
];
} else if (selectedKey === "stop" && showOperateBtn) {
return [
<Dropdown overlay={
<BatchSuspendsPay
selectedRowKeys={selectedRowKeys}
refreshList={() => {
this.query();
this.setState({ selectedRowKeys: [] });
}}
/>
}>
<Button type="primary" style={{ marginLeft: 8 }}>批量取消停薪<i className="icon-coms-down2" style={{
marginLeft: 8,
verticalAlign: "middle"
}}/></Button>
</Dropdown>,
<Dropdown overlay={<ExportMenu selectedKey={selectedKey} selectedRowKeys={selectedRowKeys} searchItemsValue={searchItemsValue}/>}>
<Button type="primary" style={{ marginLeft: 8 }}>导出<i className="icon-coms-down2" style={{
marginLeft: 8,
verticalAlign: "middle"
}}/></Button>
</Dropdown>
];
}
return [];
};
getColumns = () => {
const { pageInfo, selectedKey } = this.state;
const { payrollFilesStore: { tableStore }, taxAgentStore: { showOperateBtn } } = this.props;
let columns = _.filter(toJS(tableStore.columns), (item) => item.display === "true");
return _.map([{
title: "序号",
dataIndex: "index",
align: "left",
oldWidth: 60,
render: (text, record, index) => {
const { current, pageSize } = pageInfo;
return (current - 1) * pageSize + index + 1;
}
}, ...columns], (item, index) => {
if (index === 0) {
return { ...item, width: item.oldWidth, fixed: "left" };
}
if (item.dataIndex === "operate") {
return {
...item, fixed: "right",
width: 150,
render: (text, record) => {
if(!showOperateBtn){
return <div className="optWrapper">
<a href="javascript:void(0);" onClick={() => this.handleEdit(record)}>查看</a>
</div>;
}else{
if (selectedKey === "pending") {
return <div className="optWrapper">
<a href="javascript:void(0);" className="mr10" onClick={() => this.handleEdit(record)}>编辑</a>
<Popover
overlayClassName="moreIconWrapper"
placement="bottomRight"
content={<Menu onClick={(e) => this.handleMenuClick(e, record.id)}>
<Menu.Item key="payroll">设为发薪人员</Menu.Item>
<Menu.Item key="deletePendingTodo">删除待办</Menu.Item>
</Menu>} title="">
<i className="icon-coms-more"/>
</Popover>
</div>;
} else if (selectedKey === "fixed") {
return <a onClick={() => this.handleEdit(record)}>调薪</a>;
} else if (selectedKey === "suspend") {
return <div className="optWrapper">
<a href="javascript:void(0);" className="mr10" onClick={() => this.handleEdit(record)}>编辑</a>
<Popover
overlayClassName="moreIconWrapper"
placement="bottomRight"
content={<Menu onClick={(e) => this.handleMenuClick(e, record.id)}>
<Menu.Item key="stopSalary">停薪</Menu.Item>
<Menu.Item key="deleteSuspendTodo">删除待办</Menu.Item>
</Menu>} title="">
<i className="icon-coms-more"/>
</Popover>
</div>;
} else {
return <div className="optWrapper">
<a href="javascript:void(0);" className="mr10" onClick={() => this.cancelStop(record.id)}>取消停薪</a>
<Popover
overlayClassName="moreIconWrapper"
placement="bottomRight"
content={<Menu onClick={(e) => this.handleMenuClick(e, record)}>
<Menu.Item key="view">查看</Menu.Item>
</Menu>} title="">
<i className="icon-coms-more"/>
</Popover>
</div>;
}
}
}
};
}
return { ...item, width: item.oldWidth };
});
};
handleEdit = (record) => {
const { selectedKey } = this.state;
this.setState({
slideParams: {
...this.state.slideParams,
visible: true,
id: record.id
}
}, () => selectedKey === "fixed" && this.salaryAdjustmentInfo());
};
//列表操作
handleMenuClick = (e, id) => {
const { key } = e;
if (key === "payroll") {
//设为定薪员工
API.gotoFixed([id]).then(({ status, errormsg }) => {
if (status) {
message.success("操作成功!");
this.query();
} else {
message.error(errormsg || "操作失败!");
}
});
} else if (key === "stopSalary") {
//停薪
API.gotoStop([id]).then(({ status, errormsg }) => {
if (status) {
message.success("操作成功!");
this.query();
} else {
message.error(errormsg || "操作失败!");
}
});
} else if (key === "deletePendingTodo") {
this.deletePendingTodo([id]);
} else if (key === "deleteSuspendTodo") {
this.deleteSuspendTodo([id]);
} else if (key === "view") {
this.handleEdit(id);
}
};
// 查看 Slide 头部操作按钮
renderEditSlideOperate = () => {
const { taxAgentStore: { showOperateBtn } } = this.props;
const { slideParams: { id }, salaryAdjustmentInfo, selectedKey } = this.state;
const { isShow, url } = salaryAdjustmentInfo;
let arrList = [];
if (showOperateBtn && isShow === "true" && selectedKey === "fixed") {
arrList.push(<Button type="primary" onClick={() => {
window.open(`${url}&salaryArchiveId=${id}`);
}}>发起调薪</Button>);
}
if (showOperateBtn && selectedKey === "fixed") {
arrList.push(<Button type="primary" onClick={() => {
this.setState({ changeSalaryVisible: true });
}}>调薪</Button>);
}
selectedKey !== "stop" && arrList.push(<Button type="primary" onClick={this.handleSave}>保存</Button>);
return arrList;
};
//切换tab
handleChangeTab = (selectedKey) => {
const { slideParams, pageInfo } = this.state;
this.setState({
slideParams: { ...slideParams, visible: false, id: "" },
selectedKey,
pageInfo: {
...pageInfo,
current: 1,
pageSize: 10
}
}, () => this.query());
};
//编辑保存
handleSave = () => {
const { paysetParams, selectedKey } = this.state;
const { salaryFileStore: { adjustSalaryItems, detailForm } } = this.props;
if ((selectedKey === "pending" && _.isEmpty(paysetParams.payStartDate)) || (selectedKey !== "pending" && _.isEmpty(paysetParams.payEndDate))) {
Modal.warning({
title: "信息确认",
content: "必要信息不完整,红色*为必填项!"
});
return;
}
const payload = {
...paysetParams,
salaryArchiveId: detailForm.id,
salaryArchiveItems: _.map(toJS(adjustSalaryItems), it => ({
salaryItemId: it.id,
adjustValue: String(it.value || "")
})),
status: _.upperCase(selectedKey)
};
API.savePaySet(payload).then(({ status, errormsg }) => {
if (status) {
message.success("操作成功!");
this.query();
} else {
message.error(errormsg || "保存失败!");
}
});
};
//发薪设置
handleSetpay = (params) => {
const { type, date } = params;
const { paysetParams } = this.state;
if (type === "起始发薪日期") {
this.setState({ paysetParams: { ...paysetParams, payStartDate: date } });
} else if (type === "最后发薪日期") {
this.setState({ paysetParams: { ...paysetParams, payEndDate: date } });
}
};
query = () => {
const { selectedKey } = this.state;
switch (selectedKey) {
case "pending":
this.queryList("/api/bs/hrmsalary/salaryArchive/pendingList");
break;
case "fixed":
this.queryList("/api/bs/hrmsalary/salaryArchive/fixedList");
break;
case "suspend":
this.queryList("/api/bs/hrmsalary/salaryArchive/suspendList");
break;
default:
this.queryList("/api/bs/hrmsalary/salaryArchive/stopList");
break;
}
};
render() {
const {
tabCount,
selectedKey,
loading,
dataSource,
pageInfo,
showSearchAd,
selectedRowKeys,
slideParams,
changeSalaryVisible,
paysetParams
} = this.state;
const { payrollFilesStore: { tableStore } } = this.props;
const pagination = {
current: pageInfo.current,
pageSize: pageInfo.pageSize,
total: pageInfo.total,
showTotal: total => `${total}`,
showQuickJumper: true,
showSizeChanger: true,
pageSizeOptions: ["10", "20", "50", "100"],
onShowSizeChange: (current, pageSize) => {
this.setState({ pageInfo: { ...pageInfo, current, pageSize } }, () => {
this.query();
});
},
onChange: current => {
this.setState({ pageInfo: { ...pageInfo, current } }, () => {
this.query();
});
}
};
const renderSearch = () => {
const searchItems = [
{ com: this.Input("姓名", "username") },
{ com: this.Browser("分部", "subcompanyIds") },
{ com: this.Browser("部门", "departmentIds") },
{ com: this.Browser("岗位", "positionIds") },
{ com: this.Select("人员状态", "userstatus") },
// { com: this.Select("档案状态", "archiveStatus") },
{ com: this.Select("个税扣缴义务人", "taxAgentId") }
];
return <WeaSearchGroup title={"基本信息"} items={searchItems} showGroup/>;
};
const adBtn = [
// 高级搜索内部按钮
<Button type="primary" onClick={() => {
this.setState({ showSearchAd: false }, () => this.query());
}}> 搜索 </Button>,
<Button type="ghost" onClick={() => this.setState({
searchItemsValue: {
username: "",
departmentIds: "",
positionIds: "",
userstatus: "",
archiveStatus: ""
}
})}> 重置 </Button>,
<Button type="ghost" onClick={() => this.setState({ showSearchAd: false })}> 取消 </Button>
];
const rightMenu = [
// 右键菜单
{
key: "BTN_COLUMN",
icon: <i className="icon-coms-Custom"/>,
content: "显示列定制",
onClick: () => {
tableStore.setColSetVisible(true);
tableStore.tableColSet(true);
}
}
];
const rowSelection = {
selectedRowKeys,
onChange: (selectedRowKeys) => this.setState({ selectedRowKeys })
};
return (
<div className="payrollFilesWrapper">
<WeaTop
title="薪资档案" // 文字
icon={<i className="icon-coms-fa"/>} // 左侧图标
iconBgcolor="#F14A2D" // 左侧图标背景色
showDropIcon={true} // 是否显示下拉按钮
dropMenuDatas={rightMenu} // 下拉菜单(和页面的右键菜单相同)
>
<WeaTab
datas={tabCondition}
counts={tabCount}
className="payrollFilesTab"
keyParam="viewcondition" //主键
countParam="groupid" //数量
// autoCalculateWidth={true}
leftStyle={{ paddingRight: $(".payrollFilesTab-right").width() }}
selectedKey={selectedKey}
onChange={this.handleChangeTab}
buttons={this.getRightOptionBtns()}
searchType={["base", "advanced"]} // base基础搜索框 advanced显示高级搜索按钮
showSearchAd={showSearchAd} // 是否展开高级搜索面板
setShowSearchAd={(bool) => this.setState({ showSearchAd: bool })} //高级搜索面板受控
searchsAd={renderSearch()} // 高级搜索内部数据g1etSearchs(form, toJS(condition), 2)
buttonsAd={adBtn} // 高级搜索内部按钮
onSearch={this.query} // 点搜索按钮时的回调this.handleSearch()
searchsBasePlaceHolder={"请输入姓名"}
onSearchChange={(v) => this.setState({
searchItemsValue: {
...this.state.searchItemsValue,
username: v
}
})} // 在搜索框中输入的文字改变时的回调: 这里需要同步高级搜索和外部搜索框的值form.updateFields({ username: v })
searchsBaseValue={this.state.searchItemsValue.username}
/>
<WeaTable
loading={loading.query}
rowKey="id"
columns={this.getColumns()} dataSource={dataSource} pagination={pagination}
// rowClassName={(record) => record.archiveStatus === "ARCHIVE" ? "archiveRow" : ""}
rowSelection={rowSelection}
scroll={{ x: 1200 }}
/>
<WeaTableComx
style={{ display: "none" }}
comsWeaTableStore={tableStore}
needScroll={true}
/>
</WeaTop>
{slideParams.visible && (
<WeaSlideModal
className="slideOuterWrapper"
visible={slideParams.visible}
top={0}
width={55}
height={100}
direction={"right"}
measure={"%"}
title={
<SlideModalTitle
subtitle="员工薪资档案"
editable={false}
customOperate={this.renderEditSlideOperate()}
/>
}
content={
<SalaryFileViewSlide
id={slideParams.id}
selectedKey={selectedKey}
handleSetpay={this.handleSetpay}
paysetParams={paysetParams}
onChangePaySetParams={(res) => {
this.setState({
paysetParams: {
...paysetParams,
...res
}
});
}}
/>
}
onClose={() => {
this.setState({
paysetParams: { payStartDate: "", payEndDate: "" },
slideParams: { ...slideParams, visible: false, id: "" }
});
}}
showMask={true}
closeMaskOnClick={() => {
this.setState({
paysetParams: { payStartDate: "", payEndDate: "" },
slideParams: { ...slideParams, visible: false, id: "" }
});
}}
/>
)}
{changeSalaryVisible && (
<ChangeSalaryModal
currentId={slideParams.id}
visible={changeSalaryVisible}
onCancel={() => {
this.setState({ changeSalaryVisible: false });
}}
/>
)}
</div>
);
}
}
export default Index;
const HelpfulDiv = () => {
return <div className="helpWrapper">
<span>导入按钮使用场景说明</span>
<span>1.档案初始化</span>
<span className="pl10">
<span>a.初次使用薪酬模块全量导入员工的薪资档案数据</span>
<span>b.员工入职导入新入职的员工的薪资档案数据若导入表格中的人员已存在在薪资档案中初始化导入会将档案中该人员的数据清除再导入</span>
<span>c.返聘人员使用调薪功能调整薪资档案值或使用调整个税扣缴</span>
</span>
<span>2.调薪档案中已存在的人员批量调整薪资项目值包括返聘人员的情况</span>
<span>3.调整个税扣缴义务人档案中已存在的人员批量调整个税扣缴义务人包括返聘人员的情况</span>
</div>;
};