Merge branch 'feature/2.9.10.2312.02-薪资档案页面重构' into release/2.9.10.2312.02

This commit is contained in:
黎永顺 2024-01-15 18:20:11 +08:00
commit f4ac281c11
16 changed files with 1740 additions and 31 deletions

View File

@ -4,13 +4,14 @@ import { WeaLocaleProvider } from "ecCom";
import MySalaryMobile from "./pages/mySalaryMobile";
import MySalary from "./pages/mySalaryBenefits";
import Programme from "./pages/socialSecurityBenefits/programme";
import Archivess from "./pages/socialSecurityBenefits/archives";
// import Archivess from "./pages/socialSecurityBenefits/archives";
import Archives from "./pages/socialSecurityBenefits/welfareArchive"; //社保福利档案重构页面
import StandingBook from "./pages/socialSecurityBenefits/standingBook";
import StandingBookDetail from "./pages/socialSecurityBenefits/standingBookDetail";
import StandingBookOfflineComparison from "./pages/socialSecurityBenefits/standingBookOfflineComparison";
import SalaryItem from "./pages/salaryItem";
import PayrollFiles from "./pages/payrollFiles";
import SalaryFiles from "./pages/payrollFiles/salaryFiles";
import CumDeduct from "./pages/dataAcquisition/cumDeduct";
import OtherDeduct from "./pages/dataAcquisition/otherDeduct";
import CumSituation from "./pages/dataAcquisition/cumSituation";
@ -120,7 +121,7 @@ const Routes = (
component={SocialSecurityBenefits}>
<Route key="programme" path="programme" component={Programme}/>
<Route key="archives" path="archives" component={Archives}/>
<Route key="archives_demo" path="archives_demo" component={Archivess}/>
{/*<Route key="archives_demo" path="archives_demo" component={Archivess}/>*/}
<Route key="standingBook" path="standingBook" component={StandingBook}/>
<Route
key="standingBookDetail"
@ -134,7 +135,8 @@ const Routes = (
/>
</Route>
<Route key="salaryItem" path="salaryItem" component={SalaryItem}/>
<Route key="salaryFile" path="salaryFile" component={PayrollFiles}/>
<Route key="salaryFile" path="salaryFile" component={SalaryFiles}/>
<Route key="salaryFile-reconfig" path="salaryFile-reconfig" component={PayrollFiles}/>
<Route key="adjustSalaryManage" path="adjustSalaryManage" component={AdjustSalaryManage}/>
<Route
key="dataAcquisition"

View File

@ -0,0 +1,33 @@
/*
* Author: 黎永顺
* name:薪资档案页面重构-高级搜索
* Description:
* Date: 2024/1/8
*/
import React, { Component } from "react";
import { inject, observer } from "mobx-react";
import { Button } from "antd";
import { WeaInputSearch, WeaLocaleProvider } from "ecCom";
import "./index.less";
const getLabel = WeaLocaleProvider.getLabel;
@inject("payrollFilesStore")
@observer
class Index extends Component {
render() {
const { payrollFilesStore: { salaryFileQueryForm } } = this.props;
return (
<div className="achrive-advance-search">
<WeaInputSearch value={salaryFileQueryForm.getFormParams().username}
onChange={v => salaryFileQueryForm.updateFields({ username: v })}
onSearch={this.props.onAdvanceSearch}
/>
<Button type="ghost" className="wea-advanced-search text-elli"
onClick={this.props.onOpenAdvanceSearch}>{getLabel(545754, "高级搜索")}</Button>
</div>
);
}
}
export default Index;

View File

@ -0,0 +1,29 @@
.achrive-advance-search {
display: flex;
align-items: center;
position: relative;
top: -1.5px;
.wea-advanced-search {
top: 2px;
left: -1px;
height: 28px;
line-height: 1;
border-radius: 0;
position: relative;
color: #474747;
padding: 4px 15px;
}
.wea-advanced-search:hover {
border: 1px solid #dadada;
color: #474747;
}
.text-elli {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
top: 1px;
}
}

View File

@ -0,0 +1,87 @@
/*
* Author: 黎永顺
* name: 薪资档案页面重构-高级查询
* Description:
* Date: 2024/1/8
*/
import React, { Component } from "react";
import { WeaLocaleProvider, WeaTools } from "ecCom";
import { Button } from "antd";
import { inject, observer } from "mobx-react";
import { getSearchs } from "../../../../util";
import * as API from "../../../../apis/payrollFiles";
import { salaryFileSearchConditions } from "../../config";
import { getTaxAgentSelectList } from "../../../../apis/taxAgent";
const getLabel = WeaLocaleProvider.getLabel;
const getKey = WeaTools.getKey;
@inject("payrollFilesStore")
@observer
class salaryFileAdvanceSearchPannel extends Component {
constructor(props) {
super(props);
this.state = {
searchConditions: []
};
}
async componentDidMount() {
const [{ data: userStatusList }, { data: taxAgentList }] = await Promise.all([
API.commonEnumList({ enumClass: "com.engine.salary.enums.UserStatusEnum" }),
getTaxAgentSelectList()
]);
this.setState({
searchConditions: _.map(salaryFileSearchConditions, item => {
return {
...item,
items: _.map(item.items, child => {
if (getKey(child) === "statuses") {
return {
...child,
options: _.map(userStatusList, o => ({ key: String(o.value), showname: o.defaultLabel }))
};
} else if (getKey(child) === "taxAgentId") {
return {
...child,
options: _.map(taxAgentList, o => ({ key: o.id, showname: o.content }))
};
}
return { ...child };
})
};
})
}, () => {
const { payrollFilesStore: { salaryFileQueryForm } } = this.props;
salaryFileQueryForm.initFormFields(this.state.searchConditions);
});
}
render() {
const { searchConditions } = this.state;
const { payrollFilesStore: { salaryFileQueryForm } } = this.props;
return (
<React.Fragment>
<div className="wea-advanced-searchsAd">
{getSearchs(salaryFileQueryForm, searchConditions, 2, false)}
</div>
<div className="wea-search-buttons">
<div style={{ textAlign: "center" }}>
<span style={{ marginLeft: 15 }}>
<Button type="primary" onClick={this.props.onAdSearch}>{getLabel(388113, "搜索")}</Button>
</span>
<span style={{ marginLeft: 15 }}>
<Button type="ghost" onClick={() => salaryFileQueryForm.resetForm()}>{getLabel(2022, "重置")}</Button>
</span>
<span style={{ marginLeft: 15 }}>
<Button type="ghost" onClick={this.props.onCancel}>{getLabel(31129, "取消")}</Button>
</span>
</div>
</div>
</React.Fragment>
);
}
}
export default salaryFileAdvanceSearchPannel;

View File

@ -0,0 +1,117 @@
/*
* Author: 黎永顺
* name: 薪资档案页面重构-导入弹窗
* Description:
* Date: 2024/1/9
*/
import React, { Component } from "react";
import { inject, observer } from "mobx-react";
import { WeaCheckbox, WeaLocaleProvider } from "ecCom";
import ImportDialog from "../../../.././components/importDialog";
import { convertToUrlString, getURLParameters } from "../../../../util/url";
import { importSalaryArchive } from "../../../../apis/payrollFiles";
const getLabel = WeaLocaleProvider.getLabel;
@inject("payrollFilesStore")
@observer
class Index extends Component {
constructor(props) {
super(props);
this.state = {
importDialog: {
nextloading: false, link: "", importResult: {}, imageId: "",
previewUrl: "/api/bs/hrmsalary/salaryArchive/preview",
extraPreview: {}
}
};
}
componentWillReceiveProps(nextProps, nextContext) {
if (nextProps.visible !== this.props.visible && nextProps.visible) {
const { payrollFilesStore: { salaryFileQueryForm }, importType, isExtEmp } = nextProps;
let payload = {}, extraPreview = {};
if (importType !== "init" && importType !== "salaryItemAdjust") {
extraPreview = {
importType: "", listType: importType
};
payload = {
importType: "", listType: importType,
...salaryFileQueryForm.getFormParams()
};
} else {
extraPreview = {
importType: importType, listType: "FIXED"
};
payload = {
importType: importType, listType: "FIXED",
...salaryFileQueryForm.getFormParams()
};
}
if (isExtEmp) payload = { ...payload, extSalaryArchiveList: true };
this.setState({
importDialog: {
...this.state.importDialog, extraPreview,
link: `/api/bs/hrmsalary/salaryArchive/downloadTemplate?${convertToUrlString(payload)}`
}
});
} else {
this.setState({
importDialog: {
nextloading: false, link: "", importResult: {}, imageId: "",
previewUrl: "/api/bs/hrmsalary/salaryArchive/preview",
extraPreview: {}
}
});
}
}
handleImport = (payload) => {
const { importDialog } = this.state, { isExtEmp } = this.props;
const { extraPreview } = importDialog;
this.setState({ importDialog: { ...importDialog, nextloading: true } });
importSalaryArchive({ ...payload, ...extraPreview, isExtEmp }).then(({ data, status }) => {
this.setState({ importDialog: { ...importDialog, nextloading: false } });
if (status) {
this.setState({
importDialog: { ...importDialog, ...payload, importResult: data }
});
}
}).catch(() => this.setState({ importDialog: { ...importDialog, nextloading: false } }));
};
render() {
const { importDialog } = this.state;
const { link } = importDialog;
return (
<ImportDialog
{...this.props} {...importDialog}
onResetImportResult={() => this.setState({
importDialog: {
...importDialog, importResult: {}, imageId: "", link: ""
}
})}
exportDataDom={
<WeaCheckbox
value={getURLParameters(link)["hasData"] === "true" ? "1" : "0"}
content={getLabel(543208, "导出现有数据")}
helpfulTip={getLabel(111, "提示:建议先导出现有最新数据,修改后再导入")}
onChange={val => {
let payload = { ...getURLParameters(link), hasData: val === "1" };
this.setState({
importDialog: {
...importDialog,
link: `/api/bs/hrmsalary/salaryArchive/downloadTemplate?${convertToUrlString(payload)}`
}
});
}}
/>
}
nextCallback={imageId => this.setState({ importDialog: { ...importDialog, imageId } })}
nextUplaodCallback={imageId => this.handleImport({ imageId })}
/>
);
}
}
export default Index;

View File

@ -0,0 +1,223 @@
/*
* Author: 黎永顺
* name: 薪资档案页面重构-列表
* Description:
* Date: 2024/1/8
*/
import React, { Component } from "react";
import { inject, observer } from "mobx-react";
import { WeaLoadingGlobal, WeaLocaleProvider } from "ecCom";
import { WeaTableNew } from "comsMobx";
import SalaryFilesEditSlide from "../salaryFilesEditSlide";
import { toJS } from "mobx";
import { message, Spin } from "antd";
import * as API from "../../../../apis/payrollFiles";
const WeaTableComx = WeaTableNew.WeaTable;
const getLabel = WeaLocaleProvider.getLabel;
const URLLIST = {
pending: "/api/bs/hrmsalary/salaryArchive/pendingList",
fixed: "/api/bs/hrmsalary/salaryArchive/fixedList",
suspend: "/api/bs/hrmsalary/salaryArchive/suspendList",
stop: "/api/bs/hrmsalary/salaryArchive/stopList",
ext: "/api/bs/hrmsalary/salaryArchive/extList"
};
const APILIST = {
addToSalarypayment: API.gotoFixed, //设为发薪员工
delPenditngToDo: API.deletePendingTodo, //待定薪删除待办
delSalaryFiles: API.deleteSalaryArchive, //删除薪资档案
salarySuspension: API.gotoStop, //停薪
delSuspendToDo: API.deleteSuspendTodo, //待停薪删除待办
cancelSalarySuspension: API.cancelStop //取消停薪
};
@inject("payrollFilesStore", "taxAgentStore")
@observer
class Index extends Component {
constructor(props) {
super(props);
this.state = {
dataSource: [], columns: [], loading: false, selectedRowKeys: [],
pageInfo: { current: 1, pageSize: 10, total: 0 },
salaryFilesEditSlide: { visible: false, salaryArchiveId: "" }
};
this.SFSlideRef = null;
}
componentDidMount() {
this.getSalaryFileList(this.props);
window.addEventListener("message", this.handleReceive, false);
window.addEventListener("resize", this.handleResize, false);
}
handleResize = () => {
this.forceUpdate();
};
componentWillReceiveProps(nextProps, nextContext) {
if ((nextProps.selectedKey !== this.props.selectedKey) || (nextProps.isQuery !== this.props.isQuery)) {
this.setState({
pageInfo: { ...this.state.pageInfo, current: 1, pageSize: 10, total: 0 }
}, () => this.getSalaryFileList(nextProps));
}
if ((nextProps.selectedKey !== this.props.selectedKey)) {
this.setState({
dataSource: [], columns: [], loading: false, selectedRowKeys: [],
salaryFilesEditSlide: { ...this.state.salaryFilesEditSlide, visible: false }
});
}
}
componentWillUnmount() {
window.removeEventListener("message", this.handleReceive, false);
window.removeEventListener("resize", this.handleResize, false);
}
handleReceive = async ({ data }) => {
const { type, payload: { id, params } = {} } = data;
if (type === "init") {
this.getColumns();
} else if (type === "turn") {
switch (id) {
case "PAGEINFO":
this.setState({
pageInfo: { ...this.state.pageInfo, ...params }
}, () => this.getSalaryFileList(this.props));
break;
case "ROWSELECTION":
const { selectedRowKeys } = params;
this.setState({ selectedRowKeys });
break;
case "ADD-TO-SALARYPAYMENT":
case "DEL-PENDITNG-TO-DO":
case "DEL-SALARY-FILES":
case "SALARY-SUSPENSION":
case "DEL-SUSPEND-TO-DO":
case "CANCEL-SALARY-SUSPENSION":
const { interfaceParams } = params;
this.handleSalaryOpts(_.camelCase(id), interfaceParams);
break;
case "CHANGE-SALARY":
case "VIEW":
case "EDIT":
const { taxAgentStore: { showOperateBtn } } = this.props;
const { record: { id: salaryArchiveId } } = params;
this.setState({
salaryFilesEditSlide: {
...this.state.salaryFilesEditSlide, visible: true, salaryArchiveId,
runStatuses: this.props.selectedKey, showOperateBtn
}
});
break;
default:
break;
}
}
};
handleSalaryOpts = (type, payload) => {
WeaLoadingGlobal.start();
APILIST[type](payload).then(({ status, data = {}, errormsg }) => {
WeaLoadingGlobal.destroy();
if (status) {
const { msg, type } = data;
if (type === "fail" || type === "info") {
message.error(msg);
} else if (type === "success") {
message.success(msg);
this.getSalaryFileList(this.props);
this.setState({ selectedRowKeys: [] });
} else {
message.success(getLabel(30700, "操作成功!"));
this.getSalaryFileList(this.props);
this.setState({ selectedRowKeys: [] });
}
} else {
message.error(errormsg);
}
});
};
postMessageToChild = (payload = {}) => {
const i18n = {
"操作": getLabel(30585, "操作"), "调薪": getLabel(542686, "调薪"),
"增员": getLabel(543180, "增员"), "删除档案": getLabel(23238, "删除档案"),
"删除待办": getLabel(543181, "删除待办"), "查看": getLabel(33564, "查看"),
"取消停薪": getLabel(543309, "取消停薪"), "共": getLabel(18609, "共"),
"条": getLabel(18256, "条"), "设为发薪人员": getLabel(543308, "设为发薪人员"),
"停薪": getLabel(542692, "停薪"), "编辑": getLabel(501169, "编辑")
};
const childFrameObj = document.getElementById("atdTable");
childFrameObj.contentWindow.postMessage(JSON.stringify({ ...payload, i18n }), "*");
};
getSalaryFileList = (props) => {
const { pageInfo } = this.state;
const {
payrollFilesStore: { salaryFileQueryForm, queryList }, selectedKey, onChangeTopTabCount
} = props;
this.setState({ loading: true });
queryList(pageInfo, salaryFileQueryForm.getFormParams(), URLLIST[selectedKey]).then(({ status, data }) => {
this.setState({ loading: false });
if (status) {
const { pageInfo: result } = data;
const { list: dataSource, total, pageNum: current, pageSize } = result;
this.setState({
pageInfo: { ...pageInfo, current, pageSize, total }, dataSource
}, () => {
onChangeTopTabCount(selectedKey, total);
});
}
}).catch(() => this.setState({ loading: false }));
};
getColumns = () => {
const { payrollFilesStore: { tableStore }, taxAgentStore: { showOperateBtn } } = this.props;
const columns = _.map(_.filter(toJS(tableStore.columns), (item) => item.display === "true"), (it, idx) => ({
dataIndex: it.dataIndex, title: it.title, align: "left",
width: (it.dataIndex === "taxAgentName" || it.dataIndex === "operate") ? 185 : 150,
fixed: it.dataIndex === "username" ? "left" : it.dataIndex === "operate" ? "right" : "",
ellipsis: true
}));
if (!_.isEmpty(columns)) {
this.postMessageToChild({
columns, showOperateBtn, selectedKey: this.props.selectedKey,
showDelSalaryFileBtn: this.props.showDelSalaryFileBtn,
dataSource: this.state.dataSource, selectedRowKeys: this.state.selectedRowKeys,
showSum: false, pageInfo: this.state.pageInfo
});
}
};
render() {
const { loading, dataSource, salaryFilesEditSlide } = this.state;
const { payrollFilesStore: { tableStore } } = this.props;
const dom = document.querySelector(".wea-new-top-req-content");
let height = 280;
if (dom && dataSource.length > 0) {
height = (parseFloat(dom.style.height) > 620 && dataSource.length === 10) ? dataSource.length * 39 + 113 : dataSource.length < 10 ? dataSource.length * 39 + 113 : parseFloat(dom.style.height) - 16;
}
return (
<div className="table-layout" style={{ height: height + "px" }}>
<Spin spinning={loading}>
<iframe
style={{ border: 0, width: "100%", height: "100%" }}
// src="http://localhost:7607/#/salaryFileTable"
src="/spa/hrmSalary/hrmSalaryCalculateDetail/index.html#/salaryFileTable"
id="atdTable"
/>
</Spin>
<WeaTableComx
style={{ display: "none" }}
comsWeaTableStore={tableStore}
needScroll={true}
columns={this.getColumns()}
/>
{/* 编辑查看员工薪资档案*/}
<SalaryFilesEditSlide {...salaryFilesEditSlide} ref={dom => this.SFSlideRef = dom}
onClose={(isFresh) => this.setState({
salaryFilesEditSlide: { ...salaryFilesEditSlide, visible: isFresh }
}, () => isFresh && this.getSalaryFileList(this.props))}
/>
</div>
);
}
}
export default Index;

View File

@ -0,0 +1,42 @@
import React from "react";
import { WeaFormItem, WeaHelpfulTip, WeaSearchGroup } from "ecCom";
import { WeaSwitch } from "comsMobx";
export const renderSalaryFilesForm = (form, condition, setHasBeenModify) => {
const { isFormInit } = form;
const formParams = form.getFormParams();
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"
>
<WeaSwitch fieldConfig={fields} form={form} formParams={formParams}
onChange={() => setHasBeenModify(true)}/>
</WeaFormItem>),
colSpan: 1,
hide: fields.hide
});
});
!_.isEmpty(items) && group.push(
<WeaSearchGroup col={c.col} needTigger={true} showGroup={c.defaultshow} items={items} center={false}
className={c.col === 3 ? "basic-salary-file-wrapper" : (c.col === 2 || c.col === 1) ? "twoColumns-salary-file-wrapper" : ""}
title={
<span>
<span>{c.title}</span>
{
c.titleHelpful &&
<WeaHelpfulTip width={200} title={c.titleHelpful} placement="topLeft"
style={{ marginLeft: 8 }}/>
}
</span>
}
/>);
});
return group;
};

View File

@ -0,0 +1,223 @@
/*
* Author: 黎永顺
* name: 薪资档案页面重构-薪资档案编辑与查看
* Description:
* Date: 2024/1/11
*/
import React, { Component } from "react";
import { inject, observer } from "mobx-react";
import { WeaLocaleProvider, WeaSearchGroup, WeaSlideModal, WeaTools } from "ecCom";
import { Button, message, Modal } from "antd";
import { renderSalaryFilesForm } from "./form";
import { salaryFilesConditions } from "../../config";
import { getConditionDomkeys, toDecimal_n } from "../../../../util";
import * as API from "../../../../apis/archive";
import { savePaySet } from "../../../../apis/payrollFiles";
import SalaryItemChangeList from "../../../salaryFile/salaryItemChangeList";
import SalaryArchiveEditAdjLogRecord from "../../../salaryFile/salaryArchiveEditAdjLogRecord";
const getKey = WeaTools.getKey;
const getLabel = WeaLocaleProvider.getLabel;
@inject("payrollFilesStore")
@observer
class Index extends Component {
constructor(props) {
super(props);
this.state = {
loading: false, conditions: [], formData: {}, salaryAdjustmentInfo: {},
salaryArchiveItems: [], //薪资档案项目
adjLogRecordDialog: { //薪资档案-调薪
visible: false, title: "", salaryArchiveId: ""
}
};
}
componentWillReceiveProps(nextProps, nextContext) {
if (nextProps.visible !== this.props.visible && nextProps.visible) {
document.querySelector(".salary-files-wrapper").classList.add("zIndex0-welfare-archive");
this.getArchiveForm(nextProps);
} else if (nextProps.visible !== this.props.visible && !nextProps.visible) {
document.querySelector(".salary-files-wrapper").classList.remove("zIndex0-welfare-archive");
}
}
getArchiveForm = async (props) => {
const { payrollFilesStore: { salaryFileForm }, salaryArchiveId, runStatuses, showOperateBtn } = props;
const { data: salaryAdjustmentInfo } = (runStatuses === "fixed") ? await API.salaryAdjustmentInfo() : { data: {} };
const payload = { salaryArchiveId };
API.getArchiveForm(payload).then(({ status, data }) => {
if (status) {
const { baseInfo: { employee }, paySet: { data: paySetData }, adjustSalaryItems = [] } = data;
const adjustSalaryItemsFormData = _.reduce(adjustSalaryItems, (pre, cur) => ({
...pre, [cur["id"]]: cur["value"]
}), {});
const formData = { ...paySetData, ...employee, ...adjustSalaryItemsFormData };
this.setState({
salaryAdjustmentInfo,
salaryArchiveItems: _.map(adjustSalaryItems, o => ({
adjustValue: o.value, salaryItemId: o.id, pattern: o.pattern, dataType: o.dataType
})),
conditions: _.map(salaryFilesConditions, o => {
if (o.salaryFile) {
return {
...o, items: _.map(adjustSalaryItems, g => {
const otherParams = g.dataType === "number" ? { precision: g.pattern } : {};
return {
colSpan: 3, fieldcol: 14, label: g.name, labelcol: 10, ...otherParams,
conditionType: g.dataType === "number" ? "INPUTNUMBER" : "INPUT",
domkey: [g.id + ""], viewAttr: (runStatuses === "pending" && showOperateBtn) ? 2 : 1
};
})
};
}
return {
...o, items: _.map(o.items, g => {
if (getKey(g) === "payStartDate") {
return {
...g, label: getLabel(g.lanId, g.label),
viewAttr: ((runStatuses === "pending" || runStatuses === "ext") && showOperateBtn) ? g.viewAttr : 1
};
} else if (getKey(g) === "payEndDate") {
return {
...g, label: getLabel(g.lanId, g.label),
viewAttr: (runStatuses === "stop" || !showOperateBtn) ? 1 : (runStatuses === "suspend" && showOperateBtn) ? 3 : g.viewAttr,
rules: (runStatuses === "suspend" && showOperateBtn) ? "required|string" : ""
};
}
return {
...g, label: getLabel(g.lanId, g.label)
};
})
};
})
}, () => {
salaryFileForm.initFormFields(this.state.conditions);
_.map(getConditionDomkeys(this.state.conditions), k => {
salaryFileForm.updateFields({ [k]: formData[k] || "" });
});
});
}
});
};
save = async () => {
const { salaryArchiveItems } = this.state;
const {
payrollFilesStore: { salaryFileForm, setHasBeenModify },
salaryArchiveId, runStatuses
} = this.props;
const [salaryForm] = await Promise.all([salaryFileForm.validateForm()]);
if (salaryForm.isValid) {
const { payStartDate, payEndDate, ...extraParams } = salaryForm.getFormParams();
const payload = {
salaryArchiveId, status: _.toUpper(runStatuses),
payStartDate, payEndDate,
salaryArchiveItems: _.map(salaryArchiveItems, o => ({
salaryItemId: o.salaryItemId,
adjustValue: (o.dataType === "number" && (extraParams[o.salaryItemId] || extraParams[o.salaryItemId] === 0)) ? toDecimal_n(extraParams[o.salaryItemId], o.pattern || 2) : extraParams[o.salaryItemId]
}))
};
this.setState({ loading: true });
savePaySet(payload).then(({ status, errormsg }) => {
this.setState({ loading: false });
if (status) {
setHasBeenModify(false);
message.success(getLabel(30700, "操作成功!"));
this.props.onClose(true);
} else {
message.error(errormsg);
}
}).catch(() => this.setState({ loading: false }));
} else {
salaryForm.showErrors();
this.forceUpdate();
}
};
renderTitle = () => {
const { loading, salaryAdjustmentInfo } = this.state, { runStatuses, showOperateBtn, salaryArchiveId } = this.props;
const { isShow, url } = salaryAdjustmentInfo;
return <div className="titleDialog">
<div className="titleCol titleLeftBox">
<div className="titleIcon"><i className="icon-coms-fa"/></div>
<div className="title">{getLabel(543312, "员工薪资档案")}</div>
</div>
<div className="titleCol titleRightBox">
{
runStatuses === "fixed" && showOperateBtn && isShow === "true" &&
<Button type="ghost" onClick={() => {
const linkUrl = url.indexOf("http") !== -1 ? url : `${window.location.origin}${url}`;
window.open(`${linkUrl}&salaryArchiveId=${salaryArchiveId}`, "_blank");
}}>{getLabel(543310, "发起调薪")}</Button>
}
{
runStatuses === "fixed" && showOperateBtn &&
<Button type="ghost" onClick={() => {
this.setState({
adjLogRecordDialog: {
...this.state.adjLogRecordDialog,
visible: true, title: getLabel(542686, "调薪"), salaryArchiveId
}
});
}}>{getLabel(542686, "调薪")}</Button>
}
{
runStatuses !== "stop" && showOperateBtn &&
<Button type="primary" loading={loading} onClick={this.save}>{getLabel(537558, "保存")}</Button>
}
</div>
</div>;
};
handleClose = (visible = false) => {
const { payrollFilesStore: { hasBeenModify, setHasBeenModify }, onClose } = this.props;
if (hasBeenModify) {
Modal.confirm({
title: getLabel(131329, "信息确认"),
content: getLabel(545770, "确定放弃填写吗?放弃后数据将不会被保存!"),
onOk: () => {
onClose(visible);
setHasBeenModify(false);
}
});
} else {
onClose(visible);
setHasBeenModify(false);
}
};
render() {
const {
payrollFilesStore: { salaryFileForm, setHasBeenModify }, runStatuses, salaryArchiveId,
showOperateBtn, visible
} = this.props;
const { conditions, adjLogRecordDialog } = this.state;
return (
<WeaSlideModal
className="salary-files-edit-layout" {...this.props}
top={0} width={800} height={100} measureT="%" measureX="px" measureY="%"
direction={"right"} title={this.renderTitle()} onClose={() => this.handleClose(false)}
content={<div className="salary-files-edit-area">
{
renderSalaryFilesForm(salaryFileForm, conditions, setHasBeenModify)
}
{
runStatuses !== "pending" && visible &&
<WeaSearchGroup title={getLabel(543328, "薪资调整记录")} items={[]} needTigger showGroup>
<SalaryItemChangeList id={salaryArchiveId} selectedKey={runStatuses} showOperateBtn={showOperateBtn}/>
</WeaSearchGroup>
}
<SalaryArchiveEditAdjLogRecord
{...adjLogRecordDialog}
onCancel={() => this.setState({
adjLogRecordDialog: {
adjLogRecordDialog, visible: false, title: "", salaryArchiveId: ""
}
})}
/>
</div>}
/>
);
}
}
export default Index;

View File

@ -1,3 +1,10 @@
import React from "react";
import { WeaHelpfulTip, WeaLocaleProvider } from "ecCom";
import { Button, Dropdown, Menu } from "antd";
import AdvanceInputBtn from "../components/advanceInputBtn";
const getLabel = WeaLocaleProvider.getLabel;
export const tabCondition = [
{
color: "#000000",
@ -35,3 +42,428 @@ export const tabCondition = [
viewcondition: "ext"
}
];
export const tabList = [
{ viewcondition: "pending", title: getLabel(542689, "待定薪"), showcount: true, groupid: "PENDING" },
{ viewcondition: "fixed", title: getLabel(544638, "发薪员工"), showcount: true, groupid: "FIXED" },
{ viewcondition: "suspend", title: getLabel(542691, "待停薪"), showcount: true, groupid: "SUSPEND" },
{ viewcondition: "stop", title: getLabel(544637, "停薪员工"), showcount: true, groupid: "STOP" },
{ viewcondition: "ext", title: getLabel(542679, "非系统人员"), showcount: true, groupid: "EXT" }
];
export const renderReqBtns = (selectedKey, salaryImportTypes, onSalaryOpts, showOperateBtn) => {
let reqBtns = [
<Button type="primary" onClick={() => onSalaryOpts("IMPORT")}>{getLabel(32935, "导入")}</Button>,
<AdvanceInputBtn
onOpenAdvanceSearch={() => onSalaryOpts("OPEN")} onAdvanceSearch={() => onSalaryOpts("SEARCH")}
/>
];
switch (selectedKey) {
case "pending":
!showOperateBtn && reqBtns.shift();
showOperateBtn && reqBtns.splice(1, 0, <Button type="ghost" onClick={() => onSalaryOpts("ALL-GO-TO-FIXED")}>
{getLabel(543304, "全部设为发薪人员")}
</Button>);
break;
case "suspend":
!showOperateBtn && reqBtns.shift();
break;
case "fixed":
case "ext":
reqBtns.shift();
showOperateBtn && reqBtns.unshift(
<Dropdown overlay={
<Menu className="dropdownMenuWrapper" onClick={({ key }) => onSalaryOpts("IMPORT", key)}>
{salaryImportTypes.map((item) => (
<Menu.Item key={item.id}>{item.content}</Menu.Item>
))}
</Menu>
}>
<Button type="primary">{getLabel(32935, "导入")}</Button>
</Dropdown>
);
showOperateBtn && reqBtns.unshift(<WeaHelpfulTip
width={300} placement="topLeft"
title={<HelpfulDiv/>}
/>);
break;
case "stop":
reqBtns.shift();
showOperateBtn && reqBtns.unshift(<Button type="primary"
onClick={() => onSalaryOpts("CANCEL-SALARY-SUSPENSION")}>{getLabel(543307, "批量取消停薪")}</Button>);
break;
default:
break;
}
return reqBtns;
};
export const renderDropMenuDatas = (selectedKey, showOperateBtn) => {
let menus = [{
key: "custom_cols",
icon: <i className="icon-coms-Custom"/>,
content: getLabel(32535, "显示列定制")
}];
switch (selectedKey) {
case "pending":
menus = [
{
key: "ADD-TO-SALARYPAYMENT",
icon: <i className="icon-coms-BatchEditing-Hot"/>,
content: getLabel(543305, "批量设为发薪员工")
},
{
key: "DEL-PENDITNG-TO-DO",
icon: <i className="iconfont icon-piliangshanchu"/>,
content: getLabel(543186, "批量删除待办")
},
{
key: "exportAll",
icon: <i className="iconfont icon-daochu"/>,
content: getLabel(81272, "导出全部")
},
{
key: "exportSelected",
icon: <i className="iconfont icon-piliangdaochu"/>,
content: getLabel(512938, "导出选中")
},
...menus
];
break;
case "fixed":
menus = [
{
key: "exportAll",
icon: <i className="iconfont icon-daochu"/>,
content: getLabel(81272, "导出全部")
},
{
key: "exportSelected",
icon: <i className="iconfont icon-piliangdaochu"/>,
content: getLabel(512938, "导出选中")
},
...menus
];
break;
case "suspend":
menus = [
{
key: "FULL-SALARY-SUSPENSION",
icon: <i className="icon-coms02-all"/>,
content: getLabel(543326, "全部停薪")
},
{
key: "SALARY-SUSPENSION",
icon: <i className="icon-coms-BatchEditing-Hot"/>,
content: getLabel(543724, "批量停薪")
},
{
key: "DEL-SUSPEND-TO-DO",
icon: <i className="iconfont icon-piliangshanchu"/>,
content: getLabel(543186, "批量删除待办")
},
{
key: "exportAll",
icon: <i className="iconfont icon-daochu"/>,
content: getLabel(81272, "导出全部")
},
{
key: "exportSelected",
icon: <i className="iconfont icon-piliangdaochu"/>,
content: getLabel(512938, "导出选中")
},
...menus
];
break;
case "stop":
menus = [
{
key: "exportAll",
icon: <i className="iconfont icon-daochu"/>,
content: getLabel(81272, "导出全部")
},
{
key: "exportSelected",
icon: <i className="iconfont icon-piliangdaochu"/>,
content: getLabel(512938, "导出选中")
},
...menus
];
break;
default:
break;
}
return showOperateBtn ? menus : _.filter(menus, o => o.key === "custom_cols");
};
export const salaryFileSearchConditions = [
{
items: [
{
conditionType: "INPUT",
domkey: ["username"],
fieldcol: 16,
label: getLabel(25034, "姓名"),
labelcol: 8,
value: "",
viewAttr: 2
},
{
browserConditionParam: {
completeParams: {},
conditionDataParams: {},
dataParams: {},
destDataParams: {},
hasAddBtn: false,
hasAdvanceSerach: false,
idSeparator: ",",
isAutoComplete: 1,
isDetail: 0,
isMultCheckbox: false,
isSingle: false,
icon: "icon-coms-hrm",
linkUrl: "",
pageSize: 10,
quickSearchName: "",
replaceDatas: [],
title: "",
type: "164",
viewAttr: 2
},
colSpan: 1,
conditionType: "BROWSER",
domkey: ["subcompanyIds"],
fieldcol: 16,
label: getLabel(33553, "分部"),
labelcol: 8,
viewAttr: 2
},
{
browserConditionParam: {
completeParams: {},
conditionDataParams: {},
dataParams: {},
destDataParams: {},
hasAddBtn: false,
hasAdvanceSerach: false,
idSeparator: ",",
isAutoComplete: 1,
isDetail: 0,
isMultCheckbox: false,
isSingle: false,
icon: "icon-coms-hrm",
linkUrl: "",
pageSize: 10,
quickSearchName: "",
replaceDatas: [],
title: "",
type: "57",
viewAttr: 2
},
conditionType: "BROWSER",
domkey: ["departmentIds"],
fieldcol: 16,
label: getLabel(27511, "部门"),
labelcol: 8,
viewAttr: 2
},
{
browserConditionParam: {
completeParams: {},
conditionDataParams: {},
dataParams: {},
destDataParams: {},
hasAddBtn: false,
hasAdvanceSerach: false,
idSeparator: ",",
isAutoComplete: 1,
isDetail: 0,
isMultCheckbox: false,
isSingle: false,
icon: "icon-coms-hrm",
linkUrl: "",
pageSize: 10,
quickSearchName: "",
replaceDatas: [],
title: "",
type: "24",
viewAttr: 2
},
conditionType: "BROWSER",
domkey: ["positionIds"],
fieldcol: 16,
label: getLabel(6086, "岗位"),
labelcol: 8,
viewAttr: 2
},
{
conditionType: "SELECT",
domkey: ["statuses"],
fieldcol: 16,
label: getLabel(382300, "人员状态"),
labelcol: 8,
options: [],
multiple: true,
viewAttr: 2
},
{
conditionType: "SELECT",
domkey: ["taxAgentId"],
fieldcol: 16,
label: getLabel(537996, "个税扣缴义务人"),
labelcol: 8,
options: [],
viewAttr: 2
},
{
conditionType: "INPUT",
domkey: ["workcode"],
fieldcol: 16,
label: getLabel(1933, "工号"),
labelcol: 8,
value: "",
viewAttr: 2
},
{
conditionType: "RANGEPICKER",
domkey: ["payStartDateStartDateStr", "payStartDateEndDateStr"],
fieldcol: 16,
label: getLabel(542346, "起始发薪日期"),
labelcol: 8,
value: "",
viewAttr: 2
},
{
conditionType: "RANGEPICKER",
domkey: ["payEndDateStartDateStr", "payEndDateEndDateStr"],
fieldcol: 16,
label: getLabel(542347, "最后发薪日期"),
labelcol: 8,
value: "",
viewAttr: 2
}
],
defaultshow: true,
title: getLabel(1361, "基本信息"),
col: 2
}
];
export const salaryFilesConditions = [
{
defaultshow: true, title: getLabel(1361, "基本信息"),
col: 3,
items: [
{
colSpan: 3,
conditionType: "INPUT",
domkey: ["username"],
fieldcol: 14,
label: "姓名",
lanId: 25034,
labelcol: 10,
value: "",
viewAttr: 1
},
{
colSpan: 3,
conditionType: "INPUT",
domkey: ["department"],
fieldcol: 14,
label: "部门",
lanId: 27511,
labelcol: 10,
value: "",
viewAttr: 1
},
{
colSpan: 3,
conditionType: "INPUT",
domkey: ["position"],
fieldcol: 14,
label: "岗位",
lanId: 6086,
labelcol: 10,
value: "",
viewAttr: 1
},
{
colSpan: 3,
conditionType: "INPUT",
domkey: ["hiredate"],
fieldcol: 14,
label: "入职时间",
lanId: 1908,
labelcol: 10,
value: "",
viewAttr: 1
},
{
colSpan: 3,
conditionType: "INPUT",
domkey: ["mobile"],
fieldcol: 14,
label: "手机号",
lanId: 125238,
labelcol: 10,
value: "",
viewAttr: 1
},
{
colSpan: 3,
conditionType: "INPUT",
domkey: ["taxAgent"],
fieldcol: 14,
label: "个税扣缴义务人",
lanId: 537996,
labelcol: 10,
value: "",
viewAttr: 1
}
]
},
{
defaultshow: true, title: getLabel(543329, "发薪设置"),
col: 1,
items: [
{
colSpan: 1,
conditionType: "DATEPICKER",
domkey: ["payStartDate"],
fieldcol: 16,
label: "起始发薪日期",
lanId: 542346,
labelcol: 8,
value: "",
rules: "required|string",
viewAttr: 3
},
{
colSpan: 1,
conditionType: "DATEPICKER",
domkey: ["payEndDate"],
fieldcol: 16,
label: "最后发薪日期",
lanId: 542347,
labelcol: 8,
value: "",
viewAttr: 2
}
]
},
{
defaultshow: true, title: getLabel(538004, "薪资档案"),
titleHelpful: getLabel(543330, "提示:显示已生效的最新数据"),
col: 2, salaryFile: true,
items: []
}
];
const HelpfulDiv = () => {
return <div className="helpWrapper">
<span>{getLabel(544742, "导入按钮使用场景说明:")}</span>
<span>{getLabel(544743, "1.档案初始化:")}</span>
<span className="pl10">
<span>{getLabel(544744, "a.初次使用薪酬模块,全量导入员工的薪资档案数据;")}</span>
<span>{getLabel(544745, "b.员工入职,导入新入职的员工的薪资档案数据(若导入表格中的人员已存在在薪资档案中,初始化导入会将档案中该人员的数据清除再导入);")}</span>
<span>{getLabel(544746, "c.返聘人员使用调薪功能调整薪资档案值或使用调整个税扣缴;")}</span>
</span>
<span>{getLabel(545755, "2.调薪:档案中已存在的人员批量调整薪资项目值(包括返聘人员的情况);")}</span>
<span>{getLabel(545756, "3.调整个税扣缴义务人:档案中已存在的人员批量调整个税扣缴义务人(包括返聘人员的情况);")}</span>
</div>;
};

View File

@ -111,3 +111,201 @@
}
}
}
//薪资档案页面重构
.salary-files-wrapper {
min-width: 1000px;
overflow: auto;
width: 100%;
height: 100%;
background: #f6f6f6;
.wea-new-top-req-title > div:first-child > div > div {
padding-left: 0 !important;
.wea-tab {
border-bottom: none;
}
}
.salary-files-content {
padding: 8px 16px;
display: flex;
flex-direction: column;
.table-layout {
.ant-spin-nested-loading, .ant-spin-container {
height: 100%;
}
}
.searchAdvanced-condition-hide {
display: none;
}
.searchAdvanced-condition-container {
background: #FFF;
margin-bottom: 10px;
border: 1px solid #e5e5e5;
.wea-search-buttons {
border-top: 1px solid #dadada;
padding: 15px 0;
}
.wea-advanced-searchsAd {
height: 246px;
overflow: hidden auto;
.formItem-delete {
position: absolute;
top: 0;
right: -40px;
}
.searchAdvanced-commonSelect {
border-top: 1px solid #ebebeb;
margin: 0 25px;
padding: 10px 0;
}
.custom-advance-largeSpacing {
padding-left: 26px;
.link {
border: none;
border-radius: 0;
padding: 12px 10px 12px 26px;
color: #2db7f5
}
}
}
}
}
}
//薪资档案页面重构-编辑查看抽屉页面
.salary-files-edit-layout {
.titleDialog {
display: flex;
justify-content: space-between;
align-items: center;
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:last-child {
margin-left: 10px;
}
}
}
.wea-slide-modal-title {
border-bottom: 1px solid #e5e5e5 !important;
}
.wea-slide-modal-content {
height: 100%;
.salary-files-edit-area {
background: #f6f6f6;
height: 100%;
overflow-y: auto;
padding: 16px;
.basic-salary-file-wrapper {
.wea-form-cell-wrapper {
.wea-field-readonly {
vertical-align: bottom;
span.child-item {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
max-width: 125px;
}
}
& > div {
border-right: 1px solid #e5e5e5;
border-bottom: 1px solid #e5e5e5;
}
& > div:nth-child(3) {
border-bottom: 1px solid #e5e5e5;
}
& > div:nth-child(4), & > div:nth-child(5) {
border-right: 1px solid #e5e5e5;
}
}
}
.twoColumns-salary-file-wrapper {
.wea-form-cell-wrapper {
& > div {
border-right: 1px solid #e5e5e5;
border-bottom: 1px solid #e5e5e5;
}
& > div:nth-child(2n) {
border-right: none;
}
& > div:last-child {
border-bottom: none;
}
}
}
.wea-search-group, .wea-form-cell {
padding: 0;
.wea-form-item {
padding: 5px 16px;
.wea-form-item-label {
color: #666;
}
}
}
.wea-form-cell-wrapper {
background: #FFF;
border: 1px solid #e5e5e5;
}
}
}
}

View File

@ -0,0 +1,278 @@
/*
* Author: 黎永顺
* name: 薪资档案页面-重构
* Description:
* Date: 2024/1/8
*/
import React, { Component } from "react";
import { WeaLoadingGlobal, WeaLocaleProvider, WeaReqTop, WeaTab } from "ecCom";
import { message, Modal } from "antd";
import { inject, observer } from "mobx-react";
import { renderDropMenuDatas, renderReqBtns, tabList } from "./config";
import SalaryFileAdvanceSearchPannel from "./components/salaryFileAdvanceSearchPannel";
import SalaryFileImportDialog from "./components/salaryFileImportDialog";
import SalaryFileList from "./components/salaryFileList";
import * as API from "../../apis/payrollFiles";
import { sysinfo } from "../../apis/ruleconfig";
import { convertToUrlString } from "../../util/url";
import cs from "classnames";
import "./index.less";
const getLabel = WeaLocaleProvider.getLabel;
@inject("payrollFilesStore", "taxAgentStore")
@observer
class SalaryFiles extends Component {
constructor(props) {
super(props);
this.state = {
selectedKey: "pending", showSearchAd: false, isQuery: false, showDelSalaryFileBtn: false,
topTabCount: { PENDING: 0, FIXED: 0, SUSPEND: 0, STOP: 0, EXT: 0 }, showExtEmpsWitch: false,
salaryFileImpDialog: { visible: false, title: getLabel(24023, "数据导入"), importType: "", isExtEmp: false },
salaryImportTypes: []
};
this.salaryFileListRef = null;
}
async componentDidMount() {
// salaryArchiveDelete, //待定薪、停薪员工 是否允许删除薪资档案 0 否, 1 是,
// extEmpsWitch //非系统人员开关, 1 开启, 0关闭
const [{ data: salaryFileDelFlag }, { data: { extEmpsWitch } }, { data: salaryImportTypes }] =
await Promise.all([API.salaryArchiveDelete(), sysinfo(), API.getImportTypes()]);
this.setState({
showDelSalaryFileBtn: salaryFileDelFlag === "1", showExtEmpsWitch: extEmpsWitch === "1",
salaryImportTypes: _.filter(salaryImportTypes, it => it.id !== "taxAgentAdjust")
});
}
handleOpenAdvanceSearch = () => this.setState({ showSearchAd: true });
handleAdvanceSearch = () => this.setState({ isQuery: !this.state.isQuery });
onAdSearch = () => this.setState({ showSearchAd: false, isQuery: !this.state.isQuery });
onDropMenuClick = (key) => {
const { state, handleSalaryOpts } = this.salaryFileListRef.wrappedInstance || {};
switch (key) {
case "custom_cols":
const { payrollFilesStore: { tableStore } } = this.props;
tableStore.setColSetVisible(true);
tableStore.tableColSet(true);
break;
case "FULL-SALARY-SUSPENSION":
this.allGotoStop();
break;
case "ADD-TO-SALARYPAYMENT":
case "DEL-PENDITNG-TO-DO":
case "SALARY-SUSPENSION":
case "DEL-SUSPEND-TO-DO":
const { selectedRowKeys = [] } = state;
if (_.isEmpty(selectedRowKeys)) {
message.warning(getLabel(543303, "请选择表格数据!"));
return;
}
handleSalaryOpts && handleSalaryOpts(_.camelCase(key), selectedRowKeys);
break;
case "exportAll":
case "exportSelected":
this.handleExport(key);
break;
default:
break;
}
};
queryInsuranceTabTotal = (active, total) => {
API.queryTabTotal().then(({ status, data }) => {
if (status) {
const key = _.find(tabList, o => o.viewcondition === active).groupid;
this.setState({
topTabCount: { ...this.state.topTabCount, ...data, [key]: total }
});
}
});
};
handleReqBtnsCLick = (type, importType) => {
const { state, handleSalaryOpts } = this.salaryFileListRef.wrappedInstance || {};
switch (type) {
case "OPEN":
this.handleOpenAdvanceSearch();
break;
case "SEARCH":
this.handleAdvanceSearch();
break;
case "IMPORT":
this.setState({
salaryFileImpDialog: {
...this.state.salaryFileImpDialog, visible: true,
importType: importType || _.upperCase(this.state.selectedKey),
isExtEmp: this.state.selectedKey === "ext"
}
});
break;
case "ALL-GO-TO-FIXED":
this.allGotoFixed();
break;
case "CANCEL-SALARY-SUSPENSION":
const { selectedRowKeys = [] } = state;
if (_.isEmpty(selectedRowKeys)) {
message.warning(getLabel(543303, "请选择表格数据!"));
return;
}
handleSalaryOpts && handleSalaryOpts(_.camelCase(type), selectedRowKeys);
break;
default:
break;
}
};
/*
* Author: 黎永顺
* Description: 全部设为发薪员工
* Params:
* Date: 2024/1/9
*/
allGotoFixed = () => {
const { state } = this.salaryFileListRef.wrappedInstance || {};
const { pageInfo } = state;
if (pageInfo && pageInfo.total === 0) {
message.warning(getLabel(543300, "您没有需要处理的待定薪人员!"));
return;
}
Modal.warning({
title: getLabel(131329, "信息确认"),
content: `${getLabel(543301, "确定要将所有待定薪人员")}(${getLabel(18609, "共")}${pageInfo.total}${getLabel(30690, "条数据")}${getLabel(543302, "设为发薪人员吗")}`,
onOk: () => {
WeaLoadingGlobal.start();
API.allGotoFixed({}).then(({ status, data, errormsg }) => {
WeaLoadingGlobal.destroy();
if (status) {
const { msg } = data;
message.info(msg || getLabel(30700, "操作成功!"));
this.handleAdvanceSearch();
} else {
message.error(errormsg || getLabel(30651, "操作失败!"));
}
});
}
});
};
/*
* Author: 黎永顺
* Description: 全部停薪
* Params:
* Date: 2024/1/9
*/
allGotoStop = () => {
const { state } = this.salaryFileListRef.wrappedInstance || {};
const { pageInfo } = state;
if (pageInfo && pageInfo.total === 0) {
message.warning(getLabel(543325, "您没有需要处理的待停薪人员!"));
return;
}
Modal.warning({
title: getLabel(131329, "信息确认"),
content: `${getLabel(543723, "确定要将所有待停薪人员")}${getLabel(18609, "共")}${pageInfo.total}${getLabel(30690, "条数据")}${getLabel(543327, "设为停薪人员吗")}`,
onOk: () => {
WeaLoadingGlobal.start();
API.allGotoStop({}).then(({ status, data, errormsg }) => {
WeaLoadingGlobal.destroy();
if (status) {
const { msg } = data;
message.info(msg || getLabel(30700, "操作成功!"));
this.handleAdvanceSearch();
} else {
message.error(errormsg || getLabel(30651, "操作失败!"));
}
});
}
});
};
/*
* Author: 黎永顺
* Description: 导出薪资档案文件
* Params:
* Date: 2024/1/9
*/
handleExport = (type) => {
const { payrollFilesStore: { salaryFileQueryForm } } = this.props;
const { selectedKey } = this.state;
let url = `${window.location.origin}/api/bs/hrmsalary/salaryArchive/exportList`;
let payload = {}, runStatusList = _.upperCase(selectedKey);
const { state } = this.salaryFileListRef.wrappedInstance || {};
const { selectedRowKeys = [] } = state;
switch (selectedKey) {
case "pending":
case "suspend":
runStatusList = _.upperCase(selectedKey);
break;
case "fixed":
runStatusList = "FIXED,SUSPEND";
break;
case "stop":
runStatusList = "STOP_FROM_PENDING,STOP_FROM_SUSPEND";
break;
default:
break;
}
if (type === "exportAll") {
payload = { ids: "", runStatusList, ...salaryFileQueryForm.getFormParams() };
} else {
if (selectedRowKeys.length === 0) {
message.warning(getLabel(543345, "请选择需要导出的数据!"));
return;
}
payload = { ids: selectedRowKeys.join(",") };
}
window.open(`${url}?${convertToUrlString(payload)}`, "_blank");
};
render() {
const {
selectedKey, topTabCount, showSearchAd, isQuery, showDelSalaryFileBtn, showExtEmpsWitch,
salaryFileImpDialog, salaryImportTypes
} = this.state;
const { taxAgentStore: { showOperateBtn } } = this.props;
return (
<div className="salary-files-wrapper">
<WeaReqTop
title={getLabel(538004, "薪资档案")} buttonSpace={10} icon={<i className="icon-coms-fa"/>}
iconBgcolor="#F14A2D" showDropIcon dropMenuDatas={renderDropMenuDatas(selectedKey, showOperateBtn)}
onDropMenuClick={this.onDropMenuClick}
buttons={renderReqBtns(selectedKey, salaryImportTypes, this.handleReqBtnsCLick, showOperateBtn)}
replaceTab={
<WeaTab
datas={!showExtEmpsWitch ? _.dropRight(tabList) : tabList} autoCalculateWidth
keyParam="viewcondition" selectedKey={selectedKey} counts={topTabCount} countParam="groupid"
onChange={key => this.setState({ selectedKey: key })}
/>
}
>
<div className="salary-files-content">
<div
className={cs("searchAdvanced-condition-container", { "searchAdvanced-condition-hide": !showSearchAd })}>
<SalaryFileAdvanceSearchPannel
onCancel={() => this.setState({ showSearchAd: false })}
onAdSearch={this.onAdSearch}
/>
</div>
{/*列表*/}
<SalaryFileList isQuery={isQuery} ref={dom => this.salaryFileListRef = dom}
selectedKey={selectedKey} showOperateBtn={showOperateBtn}
showDelSalaryFileBtn={showDelSalaryFileBtn}
onChangeTopTabCount={this.queryInsuranceTabTotal}
/>
{/* 导入*/}
<SalaryFileImportDialog {...salaryFileImpDialog}
onCancel={(isFresh) => {
this.setState({
isQuery: isFresh ? !isQuery : isQuery,
salaryFileImpDialog: {
...salaryFileImpDialog, visible: false,
importType: "", isExtEmp: false
}
});
}}/>
</div>
</WeaReqTop>
</div>
);
}
}
export default SalaryFiles;

View File

@ -41,7 +41,8 @@ class Index extends Component {
const { data: taxAgentList } = await getTaxAgentSelectList();
const {
archivesStore: { welfareProfileForm }, socialBase, fundBase, otherBase, runStatuses,
employeeId, paymentOrganization, socialBaseData, fundBaseData, othersBaseData
employeeId, paymentOrganization, socialBaseData, fundBaseData, othersBaseData,
showOperateBtn
} = props;
let socialComData = {}, fundComData = {}, otherComData = {};
if (!_.isNil(socialBase.comItems) && !_.isNil(socialBase.comData)) {
@ -83,7 +84,7 @@ class Index extends Component {
if (o.title === "basic") {
return {
...o, title: getLabel(542699, "员工基本信息"),
viewAttr: runStatuses === "4,5" ? 1 : o.viewAttr,
viewAttr: (runStatuses === "4,5" || !showOperateBtn) ? 1 : o.viewAttr,
items: _.map(o.items, g => {
return { ...g, label: getLabel(g.lanId, g.label) };
})
@ -107,13 +108,13 @@ class Index extends Component {
const key = _.lowerCase(getKey(g)).indexOf("take") !== -1 ? "underTake" : getKey(g);
return {
...g, label: getLabel(g.lanId, g.label),
viewAttr: runStatuses === "4,5" ? 1 : g.viewAttr,
viewAttr: (runStatuses === "4,5" || !showOperateBtn) ? 1 : g.viewAttr,
options: _.find(props[`${o.title}Items`], j => j.domkey[0] === key).options
};
}
return {
...g, label: getLabel(g.lanId, g.label),
viewAttr: runStatuses === "4,5" ? 1 : g.viewAttr
viewAttr: (runStatuses === "4,5" || !showOperateBtn) ? 1 : g.viewAttr
};
})
};
@ -122,7 +123,7 @@ class Index extends Component {
...o, items: _.map(o.items, g => {
return {
...g, label: getLabel(g.lanId, g.label),
viewAttr: runStatuses === "4,5" ? 1 : g.viewAttr
viewAttr: (runStatuses === "4,5" || !showOperateBtn) ? 1 : g.viewAttr
};
})
};
@ -202,7 +203,11 @@ class Index extends Component {
updateFormData = (baseData) => this.setState({ formData: { ...this.state.formData, ...baseData } });
handleFormChange = (val) => {
const changeKey = _.keys(val)[0], changeVal = val[changeKey].value;
const { archivesStore: { setHasBeenModify }, onChangeProgramme, employeeId, paymentOrganization } = this.props;
const {
archivesStore: { setHasBeenModify },
onChangeProgramme, employeeId,
paymentOrganization, showOperateBtn
} = this.props;
setHasBeenModify(true);
if (changeKey === "socialSchemeId" || changeKey === "fundSchemeId" || changeKey === "otherSchemeId") {
this.setState({
@ -216,7 +221,7 @@ class Index extends Component {
...o, items: _.map(o.items, g => {
if (getKey(g).indexOf("StartTime") !== -1) {
return {
...g, viewAttr: changeVal ? 3 : g.viewAttr
...g, viewAttr: (changeVal && showOperateBtn) ? 3 : g.viewAttr
};
}
return { ...g };
@ -257,7 +262,7 @@ class Index extends Component {
});
renderTitle = () => {
const { loading } = this.state;
const { runStatuses } = this.props;
const { runStatuses, showOperateBtn } = this.props;
return <div className="titleDialog">
<div className="titleCol titleLeftBox">
<div className="titleIcon"><i className="icon-coms-fa"/></div>
@ -265,7 +270,7 @@ class Index extends Component {
</div>
<div className="titleCol titleRightBox">
{
runStatuses !== "4,5" &&
runStatuses !== "4,5" && showOperateBtn &&
<Button type="primary" onClick={this.save} loading={loading}>{getLabel(537558, "保存")}</Button>
}
</div>
@ -287,7 +292,7 @@ class Index extends Component {
};
render() {
const { archivesStore: { welfareProfileForm } } = this.props;
const { archivesStore: { welfareProfileForm }, showOperateBtn } = this.props;
const { conditions, formData } = this.state;
return (
<WeaSlideModal
@ -298,7 +303,7 @@ class Index extends Component {
{
getWelfareSearchsForm(
welfareProfileForm, conditions, this.handleFormChange, this.handleNoPaymentChange, this.handleExtraChange,
this.handleSameChange, formData, this.props
this.handleSameChange, formData, this.props, showOperateBtn
)
}
</div>}

View File

@ -71,7 +71,7 @@ class Index extends Component {
this.getWelfareList(this.props);
} else if (type === "turn") {
const { record: { baseInfo, employeeId, paymentOrganization } = {}, interfaceParams = {} } = params;
const { runStatuses } = this.props;
const { runStatuses, showOperateBtn } = this.props;
switch (id) {
case "PAGEINFO":
this.setState({
@ -116,7 +116,7 @@ class Index extends Component {
]);
this.setState({
welfareEditSlide: {
...this.state.welfareEditSlide, visible: true,
...this.state.welfareEditSlide, visible: true, showOperateBtn,
socialBase: socialBase.data, fundBase: fundBase.data, otherBase: otherBase.data
}
});
@ -289,7 +289,7 @@ class Index extends Component {
id="atdTable"
/>
</Spin>
{/* 编辑看员工福利档案*/}
{/* 编辑看员工福利档案*/}
<WelfareEditArchiveSlide {...welfareEditSlide} ref={dom => this.archiveSlideRef = dom}
onClose={(isFresh) => this.setState({
welfareEditSlide: { ...welfareEditSlide, visible: false }

View File

@ -660,13 +660,16 @@ export const welfareConditions = [
]
}
];
export const getWelfareSearchsForm = (form, condition, onChange = () => void (0), onNoPaymentChange = () => void (0), onExtraChange = () => void (0), onSameChange = () => void (0), payload, extraFormField) => {
export const getWelfareSearchsForm = (
form, condition, onChange = () => void (0),
onNoPaymentChange = () => void (0), onExtraChange = () => void (0), onSameChange = () => void (0),
payload, extraFormField, showOperateBtn) => {
const CustomComponent = ({ type }) => {
const value = payload[type].nonPayment ? payload[type].nonPayment.toString() : "";
return <WeaCheckbox
value={value} content={getLabel(543196, "暂不缴纳")}
onChange={v => onNoPaymentChange(type, v)}
disabled={runStatuses === "4,5"}
disabled={runStatuses === "4,5" || !showOperateBtn}
/>;
};
const { socialBase, fundBase, otherBase, runStatuses } = extraFormField;
@ -703,18 +706,24 @@ export const getWelfareSearchsForm = (form, condition, onChange = () => void (0)
...pre, cur,
<BenefitBaseComponent
dataSource={_.map(socialBase.items, o => ({ ...o, title: `${o.title}${getLabel(500201, "个人")}` }))}
value={payload} onChange={onExtraChange} onSameChange={onSameChange} runStatuses={runStatuses}/>,
value={payload} onChange={onExtraChange} onSameChange={onSameChange} runStatuses={runStatuses}
showOperateBtn={showOperateBtn}
/>,
<BenefitBaseComponent
dataSource={_.map(socialBase.comItems, o => ({
...o, title: `${o.title}${getLabel(1851, "公司")}`,
items: _.map(o.items, g => ({ ...g, domkey: [`${getKey(g)}_com`] }))
}))}
value={payload} onChange={onExtraChange} onSameChange={onSameChange} runStatuses={runStatuses}/>
value={payload} onChange={onExtraChange} onSameChange={onSameChange} runStatuses={runStatuses}
showOperateBtn={showOperateBtn}
/>
];
} else {
return [...pre, cur,
<BenefitBaseComponent dataSource={socialBase.items} value={payload}
onChange={onExtraChange} onSameChange={onSameChange} runStatuses={runStatuses}/>];
onChange={onExtraChange} onSameChange={onSameChange} runStatuses={runStatuses}
showOperateBtn={showOperateBtn}
/>];
}
} else if (cur.props.title === getLabel(543197, "公积金基础信息") && _.every(fundBase.items, o => o.items.length > 0)) {
if (!_.isNil(fundBase.comItems) && _.every(fundBase.comItems, o => o.items.length > 0)) {
@ -722,18 +731,24 @@ export const getWelfareSearchsForm = (form, condition, onChange = () => void (0)
...pre, cur,
<BenefitBaseComponent
dataSource={_.map(fundBase.items, o => ({ ...o, title: `${o.title}${getLabel(500201, "个人")}` }))}
value={payload} onChange={onExtraChange} onSameChange={onSameChange} runStatuses={runStatuses}/>,
value={payload} onChange={onExtraChange} onSameChange={onSameChange} runStatuses={runStatuses}
showOperateBtn={showOperateBtn}
/>,
<BenefitBaseComponent
dataSource={_.map(fundBase.comItems, o => ({
...o, title: `${o.title}${getLabel(1851, "公司")}`,
items: _.map(o.items, g => ({ ...g, domkey: [`${getKey(g)}_com`] }))
}))}
value={payload} onChange={onExtraChange} onSameChange={onSameChange} runStatuses={runStatuses}/>
value={payload} onChange={onExtraChange} onSameChange={onSameChange} runStatuses={runStatuses}
showOperateBtn={showOperateBtn}
/>
];
} else {
return [...pre, cur,
<BenefitBaseComponent dataSource={fundBase.items} value={payload} onChange={onExtraChange}
onSameChange={onSameChange} runStatuses={runStatuses}/>];
onSameChange={onSameChange} runStatuses={runStatuses}
showOperateBtn={showOperateBtn}
/>];
}
} else if (cur.props.title === getLabel(543198, "其他福利基础信息") && _.every(otherBase.items, o => o.items.length > 0)) {
if (!_.isNil(otherBase.comItems) && _.every(otherBase.comItems, o => o.items.length > 0)) {
@ -741,18 +756,24 @@ export const getWelfareSearchsForm = (form, condition, onChange = () => void (0)
...pre, cur,
<BenefitBaseComponent
dataSource={_.map(otherBase.items, o => ({ ...o, title: `${o.title}${getLabel(500201, "个人")}` }))}
value={payload} onChange={onExtraChange} onSameChange={onSameChange} runStatuses={runStatuses}/>,
value={payload} onChange={onExtraChange} onSameChange={onSameChange} runStatuses={runStatuses}
showOperateBtn={showOperateBtn}
/>,
<BenefitBaseComponent
dataSource={_.map(otherBase.comItems, o => ({
...o, title: `${o.title}${getLabel(1851, "公司")}`,
items: _.map(o.items, g => ({ ...g, domkey: [`${getKey(g)}_com`] }))
}))}
value={payload} onChange={onExtraChange} onSameChange={onSameChange} runStatuses={runStatuses}/>
value={payload} onChange={onExtraChange} onSameChange={onSameChange} runStatuses={runStatuses}
showOperateBtn={showOperateBtn}
/>
];
} else {
return [...pre, cur,
<BenefitBaseComponent dataSource={otherBase.items} value={payload} onChange={onExtraChange}
onSameChange={onSameChange} runStatuses={runStatuses}/>];
onSameChange={onSameChange} runStatuses={runStatuses}
showOperateBtn={showOperateBtn}
/>];
}
}
return [...pre, cur];
@ -760,7 +781,7 @@ export const getWelfareSearchsForm = (form, condition, onChange = () => void (0)
};
const BenefitBaseComponent = (props) => {
const { dataSource, value, onChange, onSameChange, runStatuses } = props;
const { dataSource, value, onChange, onSameChange, runStatuses, showOperateBtn } = props;
return <React.Fragment>
{
_.map(dataSource, item => {
@ -773,14 +794,14 @@ const BenefitBaseComponent = (props) => {
min={child.min !== "0.000" ? child.min : -999999999999999}
max={child.max !== "0.000" ? child.max : 999999999999999}
onChange={v => onChange(getKey(child), v)}
viewAttr={runStatuses === "4,5" ? 1 : 2}
viewAttr={(runStatuses === "4,5" || !showOperateBtn) ? 1 : 2}
/>
</WeaFormItem>
}))}
customComponent={<div className="welfare-same-box">
<span>{getLabel(543195, "各项福利基数一致")}</span>
<WeaInputNumber style={{ width: 100 }} onBlur={v => onSameChange(items, v)}
disabled={runStatuses === "4,5"}/>
disabled={runStatuses === "4,5" || !showOperateBtn}/>
</div>}
title={title} col={2} showGroup className="twoColumns-welfare-info-wrapper"
/>;

View File

@ -157,6 +157,17 @@
.basic-welfare-info-wrapper {
.wea-form-cell-wrapper {
.wea-field-readonly {
vertical-align: bottom;
span.child-item {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
max-width: 125px;
}
}
& > div:nth-child(1), & > div:nth-child(2) {
border-right: 1px solid #e5e5e5;
border-bottom: 1px solid #e5e5e5;

View File

@ -12,6 +12,14 @@ export class PayrollFilesStore {
@observable pivotTableStore = new TableStore();
@observable adjustForm = new WeaForm(); //调薪记录-核算form
@action initAdjustForm = () => this.adjustForm = new WeaForm();//调薪记录-初始化核算form
/*薪资档案页面重构*/
@observable salaryFileQueryForm = new WeaForm(); // 薪资档案查询form
@observable salaryFileForm = new WeaForm(); // 薪资档案form
@action initSalaryFileForm = () => this.salaryFileForm = new WeaForm(); // 薪资档案form初始化
@observable hasBeenModify = false; //薪资档案-员工薪资档案-是否修改过
@action setHasBeenModify = (v) => this.hasBeenModify = v;//薪资档案-员工薪资档案数据
/*薪资档案页面重构*/
@action("薪资档案-列表查询")
queryList = (payload = {}, searchItemsValue = {}, url = "") => {