Merge branch 'release/2.19.1.2501.01' into custom-美锦能源

This commit is contained in:
lys 2025-04-17 17:18:56 +08:00
commit 5c662df657
37 changed files with 493 additions and 84 deletions

View File

@ -210,18 +210,26 @@ export const payrollCheckType = params => {
return WeaTools.callApi("/api/bs/hrmsalary/salaryBill/payrollCheckType", "GET", params);
};
//工资单-反馈验证
export const feedBackSalaryBill = params => {
export const feedBackSalaryBill = async params => {
const { header, ...payload } = params;
return fetch(`/api/bs/hrmsalary/salaryBill/feedBackSalaryBill?${convertToUrlString(payload)}`, {
const res = await fetch(`/api/bs/hrmsalary/salaryBill/feedBackSalaryBill?${convertToUrlString(payload)}`, {
method: "GET",
mode: "cors",
headers: { "Content-Type": "application/json", ...header }
}).then(res => res.json());
});
return await res.json();
// return WeaTools.callApi("/api/bs/hrmsalary/salaryBill/feedBackSalaryBill", "GET", params);
};
//工资单-确认
export const confirmSalaryBill = params => {
return WeaTools.callApi("/api/bs/hrmsalary/salaryBill/confirmSalaryBill", "GET", params);
export const confirmSalaryBill = async params => {
const { header, ...payload } = params;
const res = await fetch(`/api/bs/hrmsalary/salaryBill/confirmSalaryBill?${convertToUrlString(payload)}`, {
method: "GET",
mode: "cors",
headers: { "Content-Type": "application/json", ...header }
});
return await res.json();
// return WeaTools.callApi("/api/bs/hrmsalary/salaryBill/confirmSalaryBill", "GET", params);
};
// 工资单基础设置-获取设置列表

View File

@ -142,6 +142,10 @@ export const savePageListSetting = (params) => {
export const savePageListTemplate = (params) => {
return postFetch("/api/bs/hrmsalary/common/pageList/template/save", params);
};
// 薪酬统计报表-导出模板示例下载
export const downloadPageListTemplate = (params) => {
return postExportFetch("/api/bs/hrmsalary/common/pageList/template/file/download", params);
};
//薪酬统计报表-获取页面模板
export const getPageListTemplatelist = (params) => {
return postFetch("/api/bs/hrmsalary/common/pageList/template/list", params);

View File

@ -67,7 +67,7 @@ export default class FormInfo extends Component {
}
}
coms != null && formItems.push({
com: (<WeaFormItem {...itemProps}>{coms}</WeaFormItem>),
com: (<WeaFormItem {...itemProps}>{coms}</WeaFormItem>), hide: field.hide,
col
});

View File

@ -155,13 +155,14 @@
.item-count {
//flex-basis: 328px;
flex: 1;
padding-left: 16px;
padding: 12px 16px;
height: 100%;
line-height: 40px;
background: #fff;
font-size: 12px;
color: #5F5F5F;
word-break: break-all;
display: flex;
align-items: center;
}
}
}

View File

@ -22,6 +22,8 @@ class Layout extends Component {
componentWillReceiveProps(nextProps, nextContext) {
if (window.e9LibsConfigCustomF && _.some(window.e9LibsConfigCustomF, o => (_.some(o, k => k === "h_hrmSalary")))) {
stores.baseFormStore.initForm();
stores.baseFormStore.initFormExtra();
if (window.location.hash.indexOf("payroll") !== -1) {
window.localStorage.removeItem("template-basedata");
window.localStorage.removeItem("salary-showset");

View File

@ -153,6 +153,36 @@ export const salaryDetailSearchConditions = [
multiple: true,
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: "17",
viewAttr: 2
},
colSpan: 1,
conditionType: "BROWSER",
domkey: ["employeeIds"],
fieldcol: 16,
label: getLabel(111, "人员"),
labelcol: 8,
viewAttr: 2
},
{
browserConditionParam: {
completeParams: {},
@ -232,6 +262,25 @@ export const tempCondition = [
rules: "required|string",
viewAttr: 3
},
{
conditionType: "UPLOAD",
domkey: ["fileId"],
fieldcol: 14,
label: "导出模板",
lanId: 111,
labelcol: 6,
value: "",
datas: [],
multiSelection: false,
showClearAll: false,
showListBottom: true,
showListTop: true,
maxFilesNumber: 1,
limitType: "xlsx",
uploadUrl: "/api/doc/upload/uploadFile",
category: "111",
viewAttr: 2
},
{
conditionType: "SELECT",
domkey: ["sharedType"],

View File

@ -32,7 +32,8 @@ class SalaryDetails extends Component {
this.state = {
loading: false, dataSource: [], columns: [], selectedRowKeys: [], tempPageList: [], sumRow: {},
pageInfo: { current: 1, pageSize: 10, total: 0 }, payload: {}, templateId: "", tempManageQuery: false,
showTotalCell: false, updateSum: true, tempDialog: { visible: false, setting: [], id: "", template: {} },
showTotalCell: false, updateSum: true,
tempDialog: { visible: false, setting: [], heads: [], id: "", template: {} },
transferDialog: {
visible: false, searchParamsKey: "name", saveLoading: false,
dataParams: { page: "salary_details_report" },
@ -108,12 +109,13 @@ class SalaryDetails extends Component {
getSalaryList = (props) => {
const { attendanceStore: { salaryDetailSearchForm, tableStore }, dateRange } = props || this.props;
const [startDateStr, endDateStr] = dateRange;
const { taxAgentIds, subcompanyIds, departmentIds, ...extra } = salaryDetailSearchForm.getFormParams();
const { taxAgentIds, subcompanyIds, departmentIds, employeeIds, ...extra } = salaryDetailSearchForm.getFormParams();
const { pageInfo, transferDialog, updateSum } = this.state;
const payload = {
taxAgentIds: taxAgentIds ? taxAgentIds.split(",") : [],
departmentIds: departmentIds ? departmentIds.split(",") : [],
subcompanyIds: subcompanyIds ? subcompanyIds.split(",") : [],
employeeIds: employeeIds ? employeeIds.split(",") : [],
...extra, ...pageInfo, startDateStr, endDateStr
};
this.setState({ loading: true });
@ -200,9 +202,14 @@ class SalaryDetails extends Component {
};
handelAddTemp = (templateId = "") => {
const { tempDialog, tempPageList } = this.state;
if (_.isEmpty(this.transferRef.state.rightDatas)) {
message.warning(getLabel(111, "请选择设置!"));
return;
}
this.setState({
tempDialog: {
...tempDialog, visible: true, setting: _.map(this.transferRef.state.rightDatas, o => o.id)
...tempDialog, visible: true, setting: _.map(this.transferRef.state.rightDatas, o => o.id),
heads: _.map(this.transferRef.state.rightDatas, o => o.name)
// template: _.find(tempPageList, o => o.key === templateId)
}
});
@ -303,7 +310,7 @@ class SalaryDetails extends Component {
{/*薪资明细模板设置*/}
<SalaryDetailsTempDialog {...tempDialog}
onCancel={callback => this.setState({
tempDialog: { ...tempDialog, visible: false, setting: [] }
tempDialog: { ...tempDialog, visible: false, setting: [], heads: [] }
}, () => callback && callback())}
onSuccess={this.getPageListTemplatelist}/>
{/*薪资明细自定义列模板管理*/}

View File

@ -9,10 +9,11 @@
*/
import React, { Component } from "react";
import { inject, observer } from "mobx-react";
import { WeaDialog, WeaLocaleProvider, WeaTools } from "ecCom";
import { WeaDialog, WeaLoadingGlobal, WeaLocaleProvider, WeaTools } from "ecCom";
import { tempCondition } from "./conditions";
import { getTaxAgentSelectList } from "../../../apis/taxAgent";
import * as API from "../../../apis/statistics";
import { downloadPageListTemplate } from "../../../apis/statistics";
import { Button, message } from "antd";
import { getSearchs } from "../../../util";
@ -57,6 +58,13 @@ class SalaryDetailTempDialog extends Component {
value: id ? template["limitIds"].join(",") : "",
options: _.map(data, o => ({ key: o.id, showname: o.content }))
};
} else if (getKey(o) === "fileId") {
return {
...o, label: getLabel(o.lanId, o.label), value: id ? template[getKey(o)] : "",
datas: id && template[getKey(o)] ? [
{ fileid: template[getKey(o)], filename: template["fileName"], showDelete: true }
] : [], labelExtra: getLabel(111, "下载示例"), labelType: "download"
};
}
return { ...o, label: getLabel(o.lanId, o.label), value: id ? template[getKey(o)] : "" };
})
@ -73,12 +81,13 @@ class SalaryDetailTempDialog extends Component {
tempForm.validateForm().then(f => {
if (f.isValid) {
this.setState({ loading: true });
const { limitIds, ...formVal } = tempForm.getFormParams();
const { limitIds, fileId, ...formVal } = tempForm.getFormParams();
const payload = {
page: "salary_details_report", setting, id, ...formVal,
limitIds: !_.isEmpty(limitIds) ? limitIds.split(",") : []
};
API.savePageListTemplate(payload).then(({ status, errormsg }) => {
API.savePageListTemplate(_.assign(payload, fileId ? { fileId } : {})).then(({ status, errormsg }) => {
this.setState({ loading: false });
if (status) {
message.success(getLabel(111, "操作成功!"));
this.props.onCancel(this.props.onSuccess());
@ -92,6 +101,12 @@ class SalaryDetailTempDialog extends Component {
}).catch(() => this.setState({ loading: false }));
};
formFieldChange = (field) => {
if (field === "download") {
const { setting, heads } = this.props;
WeaLoadingGlobal.start();
const promise = downloadPageListTemplate({ setting, heads });
return;
}
const key = Object.keys(field)[0], value = field[key].value;
this.setState({
conditions: _.map(this.state.conditions, item => ({
@ -101,6 +116,12 @@ class SalaryDetailTempDialog extends Component {
...o, hide: value !== "0", viewAttr: value === "0" ? 3 : 1,
rules: value === "0" ? "required|string" : ""
};
} else if (key === "fileId" && getKey(o) === "fileId") {
return {
...o, value, datas: value ? _.map(field[key].valueSpan, o => ({
fileid: o.fileid, filename: o.filename, showDelete: true
})) : []
};
}
return { ...o };
})
@ -118,7 +139,8 @@ class SalaryDetailTempDialog extends Component {
<WeaDialog
{...this.props} style={{ width: 480, height: 127 }} initLoadCss title={getLabel(111, "模板保存")}
buttons={[<Button type="primary" onClick={this.save} loading={loading}>{getLabel(537558, "保存")}</Button>]}>
<div className="form-dialog-layout">{getSearchs(tempForm, conditions, 1, false, this.formFieldChange)}</div>
<div
className="form-dialog-layout tempDialog">{getSearchs(tempForm, conditions, 1, false, this.formFieldChange)}</div>
</WeaDialog>
);
}

View File

@ -40,6 +40,11 @@ class SalaryTempAdminDialog extends Component {
render() {
const { dataSource, selectedKeys } = this.state, { dataParams } = this.props;
const heads = _.reduce(selectedKeys, (pre, cur) => {
const item = dataSource.find(data => data.id === cur);
if (item) pre.push(item.name);
return pre;
}, []);
return (<WeaDialog
{...this.props} initLoadCss ref={dom => this.dialog = dom} title={getLabel(111, "模板管理")}
className="temp_admin_dialog" style={{
@ -47,7 +52,7 @@ class SalaryTempAdminDialog extends Component {
maxHeight: "90%", maxWidth: "90%", overflow: "hidden", transform: "translate(0px, 0px)"
}} buttons={[
<Button type="primary"
onClick={() => this.props.onAddTemp(dataParams.id, selectedKeys)}>{getLabel(111, "确 定")}</Button>,
onClick={() => this.props.onAddTemp(dataParams.id, selectedKeys, heads)}>{getLabel(111, "确 定")}</Button>,
<Button type="ghost" onClick={this.props.onCancel}>{getLabel(111, "取 消")}</Button>
]}>
<WeaTransfer data={dataSource} selectedKeys={selectedKeys} onChange={v => this.setState({ selectedKeys: v })}

View File

@ -20,7 +20,7 @@ class SalaryTempMangerDialog extends Component {
super(props);
this.state = {
selectedRowKeys: [], tempAdminDialog: { visible: false, dataParams: { page: "salary_details_report" } },
tempDialog: { visible: false, setting: [], id: "", template: {} }
tempDialog: { visible: false, setting: [], heads: [], id: "", template: {} }
};
}
@ -31,10 +31,10 @@ class SalaryTempMangerDialog extends Component {
handleTempAdminCols = (params = {}) => this.setState({
tempAdminDialog: { visible: true, dataParams: { ...this.state.tempAdminDialog.dataParams, ...params } }
});
handelAddTemp = (id = "", setting = []) => {
handelAddTemp = (id = "", setting = [], heads = []) => {
this.setState({
tempDialog: {
visible: true, setting, id, template: _.find(this.tempManageRef.state.listDatas, o => o.id === id)
visible: true, setting, heads, id, template: _.find(this.tempManageRef.state.listDatas, o => o.id === id)
}
});
};
@ -76,7 +76,7 @@ class SalaryTempMangerDialog extends Component {
{/*薪资明细模板设置*/}
<SalaryDetailsTempDialog {...tempDialog}
onCancel={callback => this.setState({
tempDialog: { ...tempDialog, visible: false, setting: [] }
tempDialog: { ...tempDialog, visible: false, setting: [], heads: [] }
}, () => callback && callback())}
onSuccess={() => this.setState({
tempAdminDialog: { visible: false, dataParams: { page: "salary_details_report" } }

View File

@ -182,7 +182,7 @@
}
.wea-advanced-searchsAd {
height: 155px;
height: 200px;
overflow: hidden auto;
.formItem-delete {
@ -382,3 +382,17 @@
}
}
.tempDialog {
.wea-form-item-label {
min-height: 50px;
}
.wea-form-item-label-extra {
position: absolute;
left: 0;
bottom: 0;
cursor: pointer;
color: #4d7ad8;
}
}

View File

@ -46,7 +46,8 @@ class EditSalaryBaseInfo extends Component {
default:
break;
}
return <WeaBrowser {...browserType} viewAttr={3} value={value} valueSpan={valueSpan} inputStyle={{ width: 200 }}
return <WeaBrowser {...browserType} viewAttr={this.props.viewAttr === 1 ? 1 : 3}
value={value} valueSpan={valueSpan} inputStyle={{ width: 200 }}
onChange={(value, valueSpan) => this.props.onChange(_.map(this.props.baseInfo, it => {
if (fieldCode === it.fieldCode) {
return { ...it, fieldValue: value, fieldValueObj: { id: value, name: valueSpan } };

View File

@ -0,0 +1,110 @@
/*
* 核算编辑
* 数据查看锚点
* @Author: 黎永顺
* @Date: 2025/2/10
* @Wechat:
* @Email: 971387674@qq.com
* @description:
*/
import React, { Component } from "react";
import { WeaLocaleProvider } from "ecCom";
import classnames from "classnames";
const getLabel = WeaLocaleProvider.getLabel;
class CalcAnchorList extends Component {
constructor(props) {
super(props);
this.state = {
collapsed: false, currentIndex: 0
};
this.isClickRef = null;
this.timerRef = null;
}
componentDidMount() {
document.getElementById("salary_anchor_area").addEventListener("scroll", this.handlerScroll);
}
componentWillReceiveProps(nextProps, nextContext) {
if (nextProps.visible !== this.props.visible && !nextProps.visible) this.setState({
collapsed: false,
currentIndex: 0
});
}
componentWillUnmount() {
document.getElementById("salary_anchor_area").removeEventListener("scroll", this.handlerScroll);
}
handlerScroll = () => {
// 点击锚点时,不执行滚动函数
if (this.isClickRef) return;
// 获取滚动容器的滚动高度(这里相对于#salary_anchor_area滚动的
const scrollTop = document.getElementById("salary_anchor_area").scrollTop;
// 获取所有wea-search-group anchor_开头的元素集合
const contentList = document.querySelectorAll("[class^='wea-search-group anchor_']");
const offsetTopArr = [];
contentList.forEach((item) => {
// 获取每个wea-search-group anchor_开头的元素的offsetTop
offsetTopArr.push(item.offsetTop);
});
for (let i = 0; i < offsetTopArr.length; i++) {
// 当滚动条高度达到对应wea-search-group anchor_开头的元素的滚动高度、则将锚点设置为高亮状态
if (scrollTop + 190 >= offsetTopArr[i]) this.setState({ currentIndex: i });
}
};
onClickAnchor = (item, index) => {
const anchorElement = document.getElementById("salary_anchor_area");
const el = document.querySelector(`.anchor_${item.salarySobItemGroupId}`);
if (el) {
anchorElement.scroll({ top: el.offsetTop, behavior: "smooth" });
}
this.setState({ currentIndex: index });
// 点击时设置为true,为了防止同时执行滚动事件
this.isClickRef = true;
// 清除定时器,防止滚动事件触发、出现走马灯闪烁问题
if (this.timerRef) clearTimeout(this.timerRef);
this.timerRef = setTimeout(() => {
this.isClickRef = false;
}, 1000);
};
render() {
const { collapsed, currentIndex } = this.state, { datas } = this.props;
return (
<div id="anchorList-contianer" style={{ position: "sticky", top: 8, zIndex: 10086 }}>
<div className={classnames("anchor-list-wrapper", { "anchor-list-collapsed": collapsed })}>
{
collapsed ?
<div className="anchor-list-collapsed-btn">
<i className="icon-coms02-Initialize-template"
onClick={() => this.setState({ collapsed: !collapsed })}/>
</div> :
<React.Fragment>
<div className="anchor-list-header">
<i className="icon-coms-right" onClick={() => this.setState({ collapsed: !collapsed })}/>
</div>
<div className="anchor-list">
<div className="anchor-list-ink">
<span className="anchor-list-ink-ball visible"
style={{ top: `${2.5 + currentIndex * 27.7}px`, height: 23 }}/>
</div>
{_.map(datas, (o, i) => (
<div className={classnames("anchor-list-link", { "anchor-list-link-active": currentIndex === i })}
onClick={() => this.onClickAnchor(o, i)}>
<span
className={classnames("anchor-list-link-title", { "anchor-list-link-title-active": currentIndex === i })}>{o.salarySobItemGroupName}</span>
</div>)
)}
</div>
</React.Fragment>
}
</div>
</div>
);
}
}
export default CalcAnchorList;

View File

@ -30,7 +30,7 @@ class EditCalcTable extends Component {
this.state = {
loading: false, pageInfo: { current: 1, pageSize: 10, total: 0 },
selectedRowKeys: [], progressVisible: false, progress: 0,
salaryCalcSlide: { visible: false, id: "" }, originPayloadData: {},
salaryCalcSlide: { visible: false, id: "", viewAttr: 2 }, originPayloadData: {},
batchUpdateDialog: {
visible: false, salaryAcctRecordId: "", idList: [], salaryItemId: "",
conditions: [], pattern: 0, dataType: ""
@ -73,9 +73,9 @@ class EditCalcTable extends Component {
this.updateEmpLockStatus({ ...params });
break;
case "EDIT":
const { id: salaryCalcId } = params;
const { id: salaryCalcId, showSee } = params;
this.setState({
salaryCalcSlide: { visible: true, id: salaryCalcId }
salaryCalcSlide: { visible: true, id: salaryCalcId, viewAttr: showSee ? 1 : 2 }
});
break;
case "DIAGRAM":
@ -238,7 +238,7 @@ class EditCalcTable extends Component {
"总计": getLabel(523, "总计"), "批量解锁": getLabel(111, "批量解锁"),
"批量锁定": getLabel(111, "批量锁定"), "批量更新": getLabel(111, "批量更新"),
"查看拓扑图": getLabel(111, "查看拓扑图"), "锁定": getLabel(111, "锁定"),
"解锁": getLabel(111, "解锁")
"解锁": getLabel(111, "解锁"), "查看": getLabel(111, "查看")
};
this.setState({ originPayloadData: { ...payload, i18n } });
const childFrameObj = document.getElementById("atdTable");
@ -269,7 +269,7 @@ class EditCalcTable extends Component {
const sumRowlistUrl = this.props.showTotalCell ? "/api/bs/hrmsalary/salaryacct/acctresult/sum" : "";
this.postMessageToChild({
dataSource, pageInfo, selectedRowKeys, showTotalCell: this.props.showTotalCell, sumRowlistUrl, payload,
calcDetail,
calcDetail, showSee: calcDetail,
columns: _.every(traverse(columns, calcDetail), (it, idx) => !it.fixed) ? _.map(traverse(columns, calcDetail), (it, idx) => ({
...it,
fixed: idx < 2 ? "left" : false
@ -304,10 +304,7 @@ class EditCalcTable extends Component {
/>
<EditSalaryCalcSlide {...salaryCalcSlide}
onClose={(isFresh) => this.setState({
salaryCalcSlide: {
visible: false,
id: ""
}
salaryCalcSlide: { visible: false, id: "", viewAttr: 2 }
}, () => isFresh === "true" && this.queryCalcResultList())}/>
{
progressVisible &&

View File

@ -12,9 +12,9 @@ import PayrollItemsTable from "../../../../calculateDetail/payrollItemsTable";
import IssuedAndReissueTable from "../../../../calculateDetail/issuedAndReissueTable";
import { acctresultDetail, saveAcctResult } from "../../../../../apis/calculate";
import { toDecimal_n } from "../../../../../util";
import CalcAnchorList from "./calcAnchorList";
import "./index.less";
const getLabel = WeaLocaleProvider.getLabel;
class EditSalaryCalcSlide extends Component {
@ -29,7 +29,7 @@ class EditSalaryCalcSlide extends Component {
componentWillReceiveProps(nextProps, nextContext) {
if (nextProps.visible !== this.props.visible && nextProps.visible) this.acctresultDetail(nextProps.id);
if (nextProps.visible !== this.props.visible && !nextProps.visible) this.setState({ selectedKey: "0" });
if (nextProps.visible !== this.props.visible && !nextProps.visible) this.setState({ selectedKey: "0" }, () => document.getElementById("salary_anchor_area").scrollTop = 0);
}
acctresultDetail = (id) => {
@ -43,14 +43,17 @@ class EditSalaryCalcSlide extends Component {
});
};
renderTitle = () => {
const { loading } = this.state;
const { loading } = this.state, { viewAttr } = this.props;
return <div className="titleDialog">
<div className="titleCol titleLeftBox">
<div className="titleIcon"><i className="icon-coms-fa"/></div>
<div className="title">{getLabel(543559, "编辑薪资")}</div>
<div className="title">{viewAttr === 2 ? getLabel(543559, "编辑薪资") : getLabel(111, "查看薪资")}</div>
</div>
<div className="titleCol titleRightBox">
<Button type="primary" onClick={this.save} loading={loading}>{getLabel(537558, "保存")}</Button>
{
viewAttr === 2 &&
<Button type="primary" onClick={this.save} loading={loading}>{getLabel(537558, "保存")}</Button>
}
</div>
</div>;
};
@ -88,7 +91,7 @@ class EditSalaryCalcSlide extends Component {
save = () => {
const { id: salaryAcctEmpId } = this.props;
const { issuedAndReissueItems, itemsByGroup, baseInfo } = this.state;
if (_.every(baseInfo, it => !it.canEdit || (it.canEdit && !it.fieldValue))) {
if (!_.every(baseInfo, (item) => (!item.canEdit || !!item.fieldValue))) {
Modal.warning({
title: getLabel(131329, "信息确认"),
content: getLabel(518702, "必要信息不完整,红色*为必填项!")
@ -96,7 +99,8 @@ class EditSalaryCalcSlide extends Component {
return;
}
const payload = {
salaryAcctEmpId, employeeInfos: baseInfo,
salaryAcctEmpId,
employeeInfos: _.map(baseInfo, o => ({ ...o, fieldValue: o.fieldValue.id || o.fieldValue })),
items: [
..._.reduce(itemsByGroup, (pre, cur) => {
return [
@ -139,7 +143,9 @@ class EditSalaryCalcSlide extends Component {
className="salary-calculate-esf-layout" {...this.props}
top={0} width={60} height={100} measure={"%"}
direction={"right"} title={this.renderTitle()}
content={<div className="salary-calculate-esf-area">
content={<div className="salary-calculate-esf-area" id="salary_anchor_area">
{/*锚点*/}
<CalcAnchorList datas={itemsByGroup} visible={this.props.visible}/>
<EditSalaryBaseInfo {...this.props} baseInfo={baseInfo}
onChange={baseInfo => this.setState({ baseInfo })}/>
<WeaTab keyParam="viewcondition" className="calc-esf-tab"
@ -148,12 +154,14 @@ class EditSalaryCalcSlide extends Component {
/>
{
selectedKey === "0" && _.map(itemsByGroup, item => {
return <PayrollItemsTable {...item} onChangeIssueReissueValue={this.handleItemValueChange}/>;
return <PayrollItemsTable {...this.props} {...item}
onChangeIssueReissueValue={this.handleItemValueChange}/>;
})
}
{
selectedKey === "1" &&
<IssuedAndReissueTable
{...this.props}
dataSource={issuedAndReissueItems}
onChangeIssueReissueValue={this.handleItemValueChange}
/>

View File

@ -142,6 +142,7 @@
height: 100%;
.salary-calculate-esf-area {
position: relative;
background: #f6f6f6;
height: 100%;
overflow-y: auto;
@ -149,6 +150,10 @@
.esf-base-info-form, .wea-title, .wea-content {
padding: 0;
.ant-row {
height: 100%;
}
}
.esf-form-content {
@ -191,6 +196,109 @@
.wea-search-group {
padding: 0;
}
//锚点按钮
.anchor-list-collapsed {
padding: 0 !important;
}
.anchor-list-wrapper {
position: absolute;
right: 0;
margin: 10px 15px 20px;
padding: 8px 10px;
overflow: auto;
background-color: #fff;
box-shadow: 0 3px 12px 0 rgba(0, 0, 0, .12);
border-radius: 3px;
cursor: pointer;
.anchor-list-collapsed-btn {
opacity: .5;
background: #000;
color: #fff;
border-radius: 3px;
width: 30px;
height: 30px;
display: flex;
align-items: center;
justify-content: center;
font-size: 16px;
}
.anchor-list-header {
display: flex;
align-items: center;
justify-content: flex-end;
min-width: 130px;
padding: 5px;
}
.anchor-list {
padding: 0 10px;
position: relative;
margin-top: 10px;
transition: margin-top .3s;
.anchor-list-ink {
position: absolute;
top: 0;
left: 5px;
height: 100%;
.anchor-list-ink-ball.visible {
display: inline-block;
}
.anchor-list-ink-ball {
position: absolute;
left: 50%;
display: none;
width: 3px;
height: 8px;
background-color: #5d9cec;
border: 1.5px solid #5d9cec;
border-radius: 8px;
transform: translateX(-50%);
transition: top .3s ease-in-out;
}
}
.anchor-list-ink:before {
position: relative;
display: block;
width: 1px;
height: 100%;
margin: 0 auto;
background-color: #f0f0f0;
content: " ";
}
.anchor-list-link {
padding: 7px 0 7px 10px;
line-height: 1.143;
.anchor-list-link-title {
position: relative;
display: block;
overflow: hidden;
color: #666;
white-space: nowrap;
text-overflow: ellipsis;
transition: all .3s;
cursor: pointer;
outline: none;
text-decoration: none;
background-color: transparent;
}
}
.anchor-list-link-active > .anchor-list-link-title {
color: #5d9cec;
}
}
}
}
}
}

View File

@ -29,10 +29,11 @@ class IssuedAndReissueTable extends Component {
/>
</span>,
render: (text, record) => {
const { canEdit, pattern } = record;
const { canEdit, pattern } = record, { viewAttr } = this.props;
return <WeaInputNumber
disabled={!canEdit}
min={0}
viewAttr={viewAttr}
precision={pattern || 2}
value={text || 0}
onChange={(value) => onChangeIssueReissueValue(record.salaryItemName, value, "issuedAndReissueItems")}

View File

@ -37,8 +37,9 @@ class PayrollItemsTable extends Component {
</span>,
width: "20%",
render: (text, record) => {
const { canEdit, dataType, pattern } = record;
const { canEdit, dataType, pattern } = record, { viewAttr } = this.props;
return dataType === "number" ? <WeaInputNumber
viewAttr={viewAttr}
disabled={!canEdit}
precision={!_.isNil(pattern) ? pattern : 0}
value={text || 0}
@ -46,6 +47,7 @@ class PayrollItemsTable extends Component {
/> : <WeaInput
disabled={!canEdit}
value={text}
viewAttr={viewAttr}
onChange={(value) => onChangeIssueReissueValue(record.salaryItemId, value, "itemsByGroup", salarySobItemGroupId)}
/>;
}
@ -66,7 +68,7 @@ class PayrollItemsTable extends Component {
}
];
return (
<WeaSearchGroup title={salarySobItemGroupName} showGroup needTigger>
<WeaSearchGroup title={salarySobItemGroupName} showGroup needTigger className={`anchor_${salarySobItemGroupId}`}>
<WeaTable
rowKey="salaryItemId"
dataSource={dataSource}

View File

@ -5,11 +5,13 @@
* Date: 2023/2/20
*/
import React, { Component } from "react";
import { WeaSearchGroup, WeaTable } from "ecCom";
import { WeaLocaleProvider, WeaSearchGroup, WeaTable } from "ecCom";
import { getTableRecordDate } from "../../../apis/cumDeduct";
import { DataCollectionDateRangePick, DataCollectionSelect, Input } from "../cumDeduct";
import "./index.less";
const getLabel = WeaLocaleProvider.getLabel;
class TableRecord extends Component {
constructor(props) {
super(props);
@ -167,11 +169,11 @@ class TableRecord extends Component {
};
const items = screenParams.length === 1 ? [
{
com: Input({ value: record.username })
com: Input({ label: getLabel(111, "姓名"), value: record.username })
}
] : [
{
com: Input({ value: record.username })
com: Input({ label: getLabel(111, "姓名"), value: record.username })
},
{
com: DataCollectionSelect({

View File

@ -557,8 +557,10 @@ export const DataCollectionSelect = (props) => {
};
export const Input = (props) => {
const { value } = props;
return (<WeaInput value={value} viewAttr={1}/>);
const { value, label } = props;
return (<WeaFormItem label={label} labelCol={{ span: 8 }} wrapperCol={{ span: 16 }}>
<WeaInput value={value} viewAttr={1}/>
</WeaFormItem>);
};
export const DataCollectionDateRangePick = (props) => {
const { range, label, onChange, format = "YYYY-MM", key } = props;

View File

@ -12,6 +12,7 @@ import { getSearchs } from "../../../../util";
import { getTaxAgentSelectListAsAdmin } from "../../../../apis/taxAgent";
import { saveDeclare } from "../../../../apis/declare";
import { declareConditions } from "./condition";
import * as API from "../../../../apis/ruleconfig";
const getKey = WeaTools.getKey;
const getLabel = WeaLocaleProvider.getLabel;
@ -31,7 +32,8 @@ class Index extends Component {
if (nextProps.visible !== this.props.visible && !nextProps.visible) this.props.declareStore.initDeclareForm();
}
getTaxAgentSelectListAsAdmin = (props) => {
getTaxAgentSelectListAsAdmin = async (props) => {
const { data: sysinfo } = await API.sysinfo();
const { declareStore: { declareForm } } = props;
getTaxAgentSelectListAsAdmin().then(({ status, data }) => {
if (status) {
@ -44,6 +46,11 @@ class Index extends Component {
...o, options: _.map(data, g => ({ key: g.id, showname: g.content }))
// helpfulTitle: getLabel(563420, "提示:可选择单个个税扣缴义务人进行申报,若不选择,则批量对管理下的所有个税扣缴义务人进行申报;")
};
} else if (getKey(o) === "salaryMonthStr") {
return {
...o,
label: sysinfo["TAX_DECLARATION_DATE_TYPE"] === "1" ? getLabel(111, "税款所属期") : getLabel(111, "薪资所属月")
};
}
return { ...o };
})
@ -58,7 +65,9 @@ class Index extends Component {
if (f.isValid) {
const payload = declareForm.getFormParams();
this.setState({ loading: true });
saveDeclare({ ...payload }).then(({ status, errormsg }) => {
saveDeclare({
...payload, taxCycle: `${payload.salaryMonthStr}-01`, salaryDate: `${payload.salaryMonthStr}-01`
}).then(({ status, errormsg }) => {
this.setState({ loading: false });
if (status) {
message.success(getLabel(30700, "操作成功"));

View File

@ -41,6 +41,10 @@
.baseSettingWrapper {
padding: 12px 12px 12px 20px;
.wea-form-item-wrapper {
display: inline-block !important;
}
.baseSettingLeft {
border: 1px solid #ebedf0;
padding: 0 !important;
@ -249,7 +253,7 @@
padding: 0;
background: transparent;
border: none;
font-size: 20px!important;
font-size: 20px !important;
line-height: 20px;
}

View File

@ -46,7 +46,7 @@ class LedgerSalaryItemBaseInfo extends Component {
};
handleDeleteEmplist = (item) => {
const { dataSource, onChangeSortableList } = this.props;
onChangeSortableList(_.xorWith(dataSource, [item], _.isEqual));
onChangeSortableList(_.filter(dataSource, o => o.id !== item.id));
};
render() {

View File

@ -182,7 +182,7 @@ class LedgerSalaryItemNormal extends Component {
>
<LedgerSalaryItemTable
tableData={items}
dataSource={_.find(newDateSource, childItem => childItem.uuid === uuid).items}
dataSource={_.find(dataSource, childItem => childItem.uuid === uuid).items}
salarySobId={editId || saveSalarySobId}
selectedRowKeys={field.selectedRowKeys || []}
onDropCategoryItem={(data) => onDropCategoryItem(field, data)}

View File

@ -144,14 +144,16 @@ export default class MobilePayroll extends React.Component {
return params;
};
confirmSalaryBill = () => {
confirmSalaryBill({ salaryInfoId: getQueryString("id") }).then(({ status, errormsg }) => {
if (status) {
message.success(getLabel(30700, "操作成功"));
this.getMySalaryBill(getQueryString("id"));
} else {
message.error(errormsg || getLabel(30651, "操作失败"));
}
});
const { salaryBillToken } = this.state;
confirmSalaryBill({ salaryInfoId: getQueryString("id"), header: salaryBillToken })
.then(({ status, errormsg }) => {
if (status) {
message.success(getLabel(30700, "操作成功"));
this.getMySalaryBill(getQueryString("id"));
} else {
message.error(errormsg || getLabel(30651, "操作失败"));
}
});
};
handleGoFeedback = () => {
Modal.confirm({

View File

@ -32,10 +32,10 @@ class PayrollPartTable extends Component {
}
componentWillReceiveProps(nextProps, nextContext) {
if (nextProps.visible !== this.props.visible) {
nextProps.visible && this.sendRangeList(nextProps);
this.setState({ selectedRowKeys: [] });
}
if (nextProps.visible !== this.props.visible && nextProps.visible) this.sendRangeList(nextProps);
if (nextProps.visible !== this.props.visible && !nextProps.visible) this.setState({
selectedRowKeys: [], pageInfo: { current: 1, pageSize: 10, total: 0 }
});
}
sendRangeList = (props) => {
@ -52,9 +52,9 @@ class PayrollPartTable extends Component {
sendRangeList(payload).then(({ status, data }) => {
this.setState({ loading: { ...loading, query: false } });
if (status) {
const { pageNum: current, pageSize, total, columns, list: dataSource } = data;
const { pageNum: current, total, columns, list: dataSource } = data;
this.setState({
pageInfo: { ...pageInfo, current, pageSize, total },
pageInfo: { ...pageInfo, current, total },
dataSource: _.map(dataSource, it => ({
...it,
includeObj: _.map(it.includeObj, child => child.targetName || child.targetTypeName).join(","),
@ -125,8 +125,7 @@ class PayrollPartTable extends Component {
onChange: current => {
this.setState({
pageInfo: { ...pageInfo, current }
}, () => {
});
}, () => this.sendRangeList({ grantType, salarySendId }));
}
};
const rowSelection = {

View File

@ -407,7 +407,7 @@ export const salaryFilesConditions = [
domkey: ["position"],
fieldcol: 14,
label: "岗位",
lanId: 6086,
lanId: 111,
labelcol: 10,
value: "",
viewAttr: 1

View File

@ -53,6 +53,10 @@ class Index extends Component {
} = payrollTempForm.getFormParams(),
{ ackFeedbackStatus, feedbackStatus, autoAckDays, ...extraFb } = payrollTempFeedbackForm.getFormParams(),
{ formData, smsSettingDialog } = this.tmpBaseSetRef.state;
if (autoSendStatus !== "1" && emailStatus !== "1" && msgStatus !== "1" && smsStatus !== 1) {
message.warning(getLabel(111, "工资单模板至少开启一个发送通道"));
return;
}
const payload = {
...toJS(tmplDataSource), ...extraFb, ...formData, ...extraBs,
ackFeedbackStatus: ackFeedbackStatus === "1",

View File

@ -20,6 +20,10 @@
}
}
.wea-new-top-req {
z-index: 0 !important;
}
.wea-new-top-req-wapper .wea-new-top-req-title > div:last-child {
right: 16px;
}

View File

@ -193,7 +193,16 @@ export const conditions = [
conditionType: "SWITCH",
domkey: ["SHOT_EMP_BTN"],
fieldcol: 10,
label: "启用组织快照",
label: "启用人事信息快照",
lanId: 111,
labelcol: 8,
viewAttr: 2
},
{
conditionType: "SWITCH",
domkey: ["SALARY_ACCT_SYNC_TYPE"],
fieldcol: 10,
label: "是否采用线程池",
lanId: 111,
labelcol: 8,
viewAttr: 2
@ -222,6 +231,16 @@ export const conditions = [
lanId: 111,
labelcol: 8,
viewAttr: 2
},
{
conditionType: "SELECT",
domkey: ["TAX_DECLARATION_DATE_TYPE"],
fieldcol: 10,
label: "申报日期类型",
lanId: 111,
labelcol: 8,
options: [],
viewAttr: 2
}
],
title: "算税规则",

View File

@ -25,8 +25,8 @@ export const renderRuleForm = (form, condition, onChange) => {
tipPosition="bottom">
<WeaSwitch
fieldConfig={fields} form={form} formParams={formParams}
onChange={v => getKey(fields) !== "salaryAcctFixedColumns" && onChange(v)}
onBlur={(v) => getKey(fields) === "salaryAcctFixedColumns" && onChange({ salaryAcctFixedColumns: { value: v } })}
onChange={v => !["INPUT", "INPUTNUMBER", "TEXTAREA"].includes(fields.conditionType) && onChange(v)}
onBlur={v => ["INPUT", "INPUTNUMBER", "TEXTAREA"].includes(fields.conditionType) && onChange({ [getKey(fields)]: { value: v } })}
/>
</WeaFormItem>),
colSpan: 1,

View File

@ -73,6 +73,13 @@ class RuleConfig extends Component {
...o,
hide: sysinfo["SALARY_APPROVAL_STATUS"] === "0" || _.isNil(sysinfo["SALARY_APPROVAL_STATUS"])
};
} else if (getKey(o) === "TAX_DECLARATION_DATE_TYPE") {
return {
...o, options: [
{ key: "0", showname: getLabel(111, "薪资所属月"), selected: true },
{ key: "1", showname: getLabel(111, "税款所属期"), selected: false }
]
};
}
return { ...o };
})
@ -97,7 +104,7 @@ class RuleConfig extends Component {
form.updateFields({ [item]: { value: sysinfo[item] === "0" ? "0" : (sysinfo[item] || "0") } });
} else if (item === "taxAgentShowStatus" || item === "salaryShowStatus" || item === "adjustShowStatus") {
form.updateFields({ [item]: { value: sysinfo[item] || "1" } });
} else if (item === "OPEN_APPLICATION_ENCRYPT") {
} else if (item === "OPEN_APPLICATION_ENCRYPT" || item === "SALARY_ACCT_SYNC_TYPE") {
form.updateFields({ [item]: { value: _.isNil(sysinfo[item]) ? "1" : (sysinfo[item] || "") } });
} else if (
item === "APPROVAL_CAN_MANUAL_FILE_STATUS" || item === "APPROVAL_CAN_RE_CALC_STATUS" || item === "APPROVAL_CAN_EDIT_RESULT_STATUS"
@ -154,7 +161,9 @@ class RuleConfig extends Component {
case "APPROVAL_CAN_RE_CALC_STATUS":
case "APPROVAL_CAN_EDIT_RESULT_STATUS":
case "ATTENDANCE_SERIAL_COLLECTION_BTN":
case "TAX_DECLARATION_DATE_TYPE":
case "SHOT_EMP_BTN":
case "SALARY_ACCT_SYNC_TYPE":
if (!this.handleDebounce) {
this.handleDebounce = _.debounce(() => {
const confTitle = {
@ -173,7 +182,9 @@ class RuleConfig extends Component {
APPROVAL_CAN_RE_CALC_STATUS: getLabel(111, "开启审批的核算记录允许重新核算"),
APPROVAL_CAN_EDIT_RESULT_STATUS: getLabel(111, "审批流程发起后允许修改核算数据"),
ATTENDANCE_SERIAL_COLLECTION_BTN: getLabel(111, "考勤引用是否采集班次数据"),
SHOT_EMP_BTN: getLabel(111, "启用组织快照")
TAX_DECLARATION_DATE_TYPE: getLabel(111, "申报日期类型"),
SHOT_EMP_BTN: getLabel(111, "启用组织快照"),
SALARY_ACCT_SYNC_TYPE: getLabel(111, "是否采用线程池")
};
this.unifiedSettings(key, confTitle[key]);
this.handleDebounce = null;

View File

@ -187,6 +187,7 @@
border: 1px solid #e5e5e5 !important;
padding: 4px 8px !important;
min-height: 70px !important;
word-wrap: break-word;
}
}
}

View File

@ -103,6 +103,14 @@
}
.welfare-plan-edit-layout {
.ant-table-content {
padding-left: 208px !important;
.ant-table-fixed-left {
top: 1px;
}
}
.flex-center {
display: flex;
align-items: center;

View File

@ -96,7 +96,9 @@ class Index extends Component {
<ImportDialog
{...this.props} {...importDialog}
onResetImportResult={() => this.setState({
importDialog: { ...importDialog, importResult: {}, imageId: "", link: null }
importDialog: {
...importDialog, importResult: {}, imageId: "", link: "/api/bs/hrmsalary/variableSalary/downloadTemplate"
}
})}
importParams={this.renderFormComponent()}
exportDataDom={

View File

@ -10,12 +10,9 @@ const getLabel = WeaLocaleProvider.getLabel;
export class BaseFormStore {
@observable form = new WeaForm(); // 规则渲染form
@observable logStore = new LogStore();
@observable condition = []; // 存储后台得到的form数据
@observable saveLoading = false; // 保存状态处理:保证保存的时候接口只走一次
@observable loading = true; // 页面初始化的loading状态数据加载成功前后前使用
@observable hasRight = true; // 判断用户是有权限查看当前页面: 没有权限渲染无权限页面,有权限渲染数据
@action("初始化form表单") initForm = () => this.form = new WeaForm();
@observable formExtra = new WeaForm(); // 规则渲染form
@action("初始化form表单") initFormExtra = () => this.formExtra = new WeaForm();
@observable logVisible = false; // 控制日志弹框的显影
@action // 初始化操作: 一般用来初始化获取后台数据

View File

@ -36,7 +36,13 @@ export const getSearchs = (form, condition, col, isCenter, onChange = () => void
items.push({
com: (
<WeaFormItem
label={`${fields.label}`} // label 标签的文本
label={<span>
<span>{`${fields.label}`}</span>
{
fields.labelExtra && <span className="wea-form-item-label-extra"
onClick={() => onChange(fields.labelType)}>{fields.labelExtra}</span>
}
</span>} // label 标签的文本
labelCol={{ span: `${fields.labelcol}` }} // label标签占一行比例
wrapperCol={{ span: `${fields.fieldcol}` }} // 右侧控件占一行比例
error={form.getError(fields)} // 错误提示: 处理表单中有必填项,保存的校验