Merge branch 'release/2.9.42310.01' into feature/V2-dev合并多语言

# Conflicts:
#	pc4mobx/hrmSalary/components/PersonalScopeModal/index.js
#	pc4mobx/hrmSalary/pages/analysisOfSalaryStatistics/components/reportList.js
#	pc4mobx/hrmSalary/pages/calculateDetail/index.js
#	pc4mobx/hrmSalary/pages/calculateDetail/placeOnFileDetail.js
#	pc4mobx/hrmSalary/pages/calculateDetail/salaryDetail.js
#	pc4mobx/hrmSalary/pages/calculateDetail/userSure.js
#	pc4mobx/hrmSalary/pages/ledgerPage/components/ledgerSalaryItemNormal.js
#	pc4mobx/hrmSalary/pages/payroll/index.js
#	pc4mobx/hrmSalary/pages/payroll/payrollGrant/index.js
#	pc4mobx/hrmSalary/pages/payrollFiles/components/allWithoutPay.js
#	pc4mobx/hrmSalary/pages/payrollFiles/index.js
#	pc4mobx/hrmSalary/pages/reportView/components/customStatisticsItemsModal.js
#	pc4mobx/hrmSalary/pages/reportView/components/rightOptions.js
#	pc4mobx/hrmSalary/pages/reportView/components/statisticalMicroSettingsSlide.js
#	pc4mobx/hrmSalary/pages/reportView/index.js
#	pc4mobx/hrmSalary/pages/salaryFile/salaryItemChangeList.js
#	pc4mobx/hrmSalary/pages/salaryItem/formalFormModal.js
#	pc4mobx/hrmSalary/pages/socialSecurityBenefits/archives/index.js
#	pc4mobx/hrmSalary/pages/socialSecurityBenefits/programme/columns.js
#	pc4mobx/hrmSalary/pages/socialSecurityBenefits/programme/index.js
#	pc4mobx/hrmSalary/pages/socialSecurityBenefits/standingBookDetail/components/adjustmentSlide.js
This commit is contained in:
黎永顺 2023-10-09 18:38:26 +08:00
commit b9e98f2b41
116 changed files with 6100 additions and 1259 deletions

View File

@ -1,141 +1,5 @@
import { WeaTools } from "ecCom";
//薪资核算-薪资核算列表
export const getCalcList = params => {
return WeaTools.callApi("/api/bs/hrmsalary/salaryAcct/list", "POST", params);
};
//薪资核算-删除薪资核算记录
export const deleteCalc = params => {
return WeaTools.callApi("/api/bs/hrmsalary/salaryAcct/delete", "POST", params);
};
//薪资核算-归档薪资核算记录
export const fileCalc = params => {
return WeaTools.callApi("/api/bs/hrmsalary/salaryAcct/file", "POST", params);
};
//薪资核算-薪资核算详情
export const getCalcForm = params => {
return WeaTools.callApi("/api/bs/hrmsalary/salaryAcct/getForm", "get", params);
};
//薪资核算-保存薪资核算的基本信息
export const saveCalc = params => {
return WeaTools.callApi("/api/bs/hrmsalary/salaryAcct/basic/save", "POST", params);
};
//薪资核算-获取薪资核算提示信息
export const getCalcInfo = params => {
return WeaTools.callApi("/api/bs/hrmsalary/salaryAcct/getSalarySobCycle", "get", params);
};
//薪资核算-薪资核算人员确认列表
export const getCalcPersonList = params => {
return WeaTools.callApi("/api/bs/hrmsalary/salaryAcct/acctEmployee/list", "POST", params);
};
//薪资核算-薪资核算人员高级搜索
export const getCalcPersonSa = params => {
return WeaTools.callApi("/api/bs/hrmsalary/salaryAcct/acctEmployee/getSearchCondition", "get", params);
};
//薪资核算-删除薪资核算人员
export const deleteCalcPerson = params => {
return WeaTools.callApi("/api/bs/hrmsalary/salaryAcct/acctEmployee/delete", "POST", params);
};
//薪资核算-添加薪资核算人员
export const saveCalcPerson = params => {
return WeaTools.callApi("/api/bs/hrmsalary/salaryAcct/acctEmployee/save", "POST", params);
};
//薪资核算-导出人员范围
export const exportCalcPerson = params => {
return WeaTools.callApi("/api/bs/hrmsalary/salaryAcct/acctEmployee/export", "POST", params);
};
//薪资核算-薪资核算环比上期减少人员列表
export const getCalcPersonSubList = params => {
return WeaTools.callApi("/api/bs/hrmsalary/salaryAcct/reducedEmployee/list", "POST", params);
};
//薪资核算-导出环比减少人员
export const exportCalcPersonSub = params => {
return WeaTools.callApi("/api/bs/hrmsalary/salaryAcct/reducedEmployee/export", "POST", params);
};
//薪资核算-执行薪资核算
export const doScCalc = params => {
return WeaTools.callApi("/api/bs/hrmsalary/salaryAcct/acctResult/accounting", "POST", params);
};
//薪资核算-获取薪资核算结果高级搜索
export const getScSa = params => {
return WeaTools.callApi("/api/bs/hrmsalary/salaryAcct/acctResult/getSearchCondition", "get", params);
};
//薪资核算-薪资核算结果列表
export const getScList = params => {
return WeaTools.callApi("/api/bs/hrmsalary/salaryAcct/acctResult/list", "post", params);
};
//薪资核算-导出薪资核算
export const exportSc = params => {
return WeaTools.callApi("/api/bs/hrmsalary/salaryAcct/acctResult/export", "post", params);
};
//薪资核算-导出线下对比结果
export const exportOc = params => {
return WeaTools.callApi("/api/bs/hrmsalary/salaryAcct/comparisonResult/export", "post", params);
};
//薪资核算-薪资核算结果详情
export const getScDetail = params => {
return WeaTools.callApi("/api/bs/hrmsalary/salaryAcct/acctResult/detail", "get", params);
};
//薪资核算-薪资核算合并计税详情
export const getScMergeTaxDetail = params => {
return WeaTools.callApi("/api/bs/hrmsalary/salaryAcct/acctResult/getConsolidatedTaxDetail", "get", params);
};
//薪资核算-编辑薪资核算结果
export const editScResult = params => {
return WeaTools.callApi("/api/bs/hrmsalary/salaryAcct/acctResult/save", "post", params);
};
//薪资核算-薪资核算结果校验
export const checkScResult = params => {
return WeaTools.callApi("/api/bs/hrmsalary/salaryAcct/acctResult/check", "post", params);
};
//薪资核算-获取校验结果(异常)总数
export const getScResultExceptionCount = params => {
return WeaTools.callApi("/api/bs/hrmsalary/salaryAcct/checkResult/getCount", "get", params);
};
//薪资核算-校验结果列表
export const getCheckResultList = params => {
return WeaTools.callApi("/api/bs/hrmsalary/salaryAcct/checkResult/list", "POST", params);
};
//薪资核算-校验结果明细列表
export const getCheckResultDetailList = params => {
return WeaTools.callApi("/api/bs/hrmsalary/salaryAcct/checkResultRecord/list", "POST", params);
};
//薪资核算-获取导入组件前置参数
export const getImportParams = params => {
return WeaTools.callApi("/api/bs/hrmsalary/salaryAcct/checkResultRecord/list", "POST", params);
};
// 薪资记录--薪资核算列表
export const getSalaryAcctList = params => {
return fetch("/api/bs/hrmsalary/salaryacct/list", {
@ -176,6 +40,17 @@ export const reducedemployeeList = params => {
body: JSON.stringify(params)
}).then(res => res.json());
};
// 核算人员--薪资核算环比上月增加人员
export const addedemployeeList = params => {
return fetch("/api/bs/hrmsalary/salaryacct/addedemployee/list", {
method: "POST",
mode: "cors",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(params)
}).then(res => res.json());
};
// 核算人员--薪资核算人员确认列表
export const acctemployeeList = params => {
@ -206,7 +81,6 @@ export const getSalarySobCycle = params => {
return WeaTools.callApi("/api/bs/hrmsalary/salaryacct/getSalarySobCycle", "GET", params);
};
// 核算人员--添加薪资核算人员
export const saveAcctemployee = params => {
return fetch("/api/bs/hrmsalary/salaryacct/acctemployee/save", {
@ -232,7 +106,6 @@ export const exportReducedEmployee = (id) => {
}));
};
// 核算人员--导出人员范围
export const exportAcctEmployee = (id) => {
fetch("/api/bs/hrmsalary/salaryacct/acctemployee/export?salaryAcctRecordId=" + id).then(res => res.blob().then(blob => {
@ -374,7 +247,6 @@ export const getImportField = (params) => {
return WeaTools.callApi("/api/bs/hrmsalary/salaryacct/acctresult/importField", "GET", params);
};
// 核算结果-导入模板
export const getImportTemplate = (salaryItemIds, salaryAcctRecordId) => {
fetch("/api/bs/hrmsalary/salaryacct/acctresult/importtemplate/export?salaryItemIds=" + salaryItemIds + "&salaryAcctRecordId=" + salaryAcctRecordId).then(res => res.blob().then(blob => {
@ -412,7 +284,6 @@ export const importAcctResult = (params) => {
}).then(res => res.json());
};
// 核算结果-导出全部
export const exportAcctResult = (salaryAcctRecordId, ids) => {
fetch("/api/bs/hrmsalary/salaryacct/acctresult/export?salaryAcctRecordId=" + salaryAcctRecordId + "&ids=" + ids).then(res => res.blob().then(blob => {
@ -509,50 +380,6 @@ export const updateLockStatus = (params) => {
body: JSON.stringify(params)
}).then(res => res.json());
};
// 社保福利台账合计接口
export const siaccountDetailCommonListSum = (params) => {
return fetch("/api/bs/hrmsalary/siaccount/detail/common/list/sum", {
method: "POST",
mode: "cors",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(params)
}).then(res => res.json());
};
// 社保福利台账补缴合计接口
export const siaccountDetailSupplementaryListSum = (params) => {
return fetch("/api/bs/hrmsalary/siaccount/detail/supplementary/list/sum", {
method: "POST",
mode: "cors",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(params)
}).then(res => res.json());
};
// 社保福利台账退差合计接口
export const siaccountDetailRecessionListSum = (params) => {
return fetch("/api/bs/hrmsalary/siaccount/detail/recession/list/sum", {
method: "POST",
mode: "cors",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(params)
}).then(res => res.json());
};
// 社保福利台账补差合计接口
export const siaccountDetailBalanceListSum = (params) => {
return fetch("/api/bs/hrmsalary/siaccount/detail/balance/list/sum", {
method: "POST",
mode: "cors",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(params)
}).then(res => res.json());
};
// 导入薪资核算添加表头字段缓存
export const cacheImportField = (params) => {
return fetch("/api/bs/hrmsalary/salaryacct/acctresult/cacheImportField", {

View File

@ -1,4 +1,4 @@
import { WeaTools } from 'ecCom';
import { WeaTools } from "ecCom";
/**
* 薪资项目api
@ -7,171 +7,171 @@ import { WeaTools } from 'ecCom';
// 薪资项目-获取列表
export const getItemList = params => {
return fetch('/api/bs/hrmsalary/salaryitem/list', {
method: 'POST',
mode: 'cors',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(params)
}).then(res => res.json())
return fetch("/api/bs/hrmsalary/salaryitem/list", {
method: "POST",
mode: "cors",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(params)
}).then(res => res.json());
};
//薪资项目的高级搜索
export const getSaCondition = params => {
return WeaTools.callApi('/api/bs/hrmsalary/salaryitem/getSearchCondition', 'GET', params);
return WeaTools.callApi("/api/bs/hrmsalary/salaryitem/getSearchCondition", "GET", params);
};
//数据源列表字典项
export const formulaDatasourceList = params => {
return WeaTools.callApi('/api/bs/hrmsalary/formula/datasource/list', 'GET', params);
return WeaTools.callApi("/api/bs/hrmsalary/formula/datasource/list", "GET", params);
};
//薪资项目-系统薪资项目列表
export const getSysItemList = params => {
return fetch('/api/bs/hrmsalary/salaryitem/sysList', {
method: 'POST',
mode: 'cors',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(params)
}).then(res => res.json())
return fetch("/api/bs/hrmsalary/salaryitem/sysList", {
method: "POST",
mode: "cors",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(params)
}).then(res => res.json());
};
//系统薪资项目的高级搜索
export const getSysSaCondition = params => {
return WeaTools.callApi('/api/bs/hrmsalary/salaryitem/getSysSearchCondition', 'GET', params);
}
return WeaTools.callApi("/api/bs/hrmsalary/salaryitem/getSysSearchCondition", "GET", params);
};
//薪资项目-批量删除薪资项目
export const deleteItem = params => {
return fetch('/api/bs/hrmsalary/salaryitem/delete', {
method: 'POST',
mode: 'cors',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(params)
}).then(res => res.json())
}
return fetch("/api/bs/hrmsalary/salaryitem/delete", {
method: "POST",
mode: "cors",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(params)
}).then(res => res.json());
};
//薪资项目-批量删除列表
export const deleteItemList = params => {
return fetch('/api/bs/hrmsalary/salaryitem/listCanDelete', {
method: 'POST',
mode: 'cors',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(params)
}).then(res => res.json())
}
return fetch("/api/bs/hrmsalary/salaryitem/listCanDelete", {
method: "POST",
mode: "cors",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(params)
}).then(res => res.json());
};
//薪资项目-新增薪资项目
export const saveItem = params => {
delete params.formulaContent
return fetch('/api/bs/hrmsalary/salaryitem/save', {
method: 'POST',
mode: 'cors',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(params)
}).then(res => res.json())
}
delete params.formulaContent;
return fetch("/api/bs/hrmsalary/salaryitem/save", {
method: "POST",
mode: "cors",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(params)
}).then(res => res.json());
};
//薪资项目-更新薪资项目
export const updateItem = params => {
return WeaTools.callApi('/api/bs/hrmsalary/salaryitem/update', 'POST', params);
}
return WeaTools.callApi("/api/bs/hrmsalary/salaryitem/update", "POST", params);
};
//薪资项目-薪资项目详情
export const getItemForm = params => {
return WeaTools.callApi('/api/bs/hrmsalary/salaryitem/getSalaryForm', 'GET', params);
}
return WeaTools.callApi("/api/bs/hrmsalary/salaryitem/getSalaryForm", "GET", params);
};
//薪资项目-添加系统薪资项目
export const saveSysItem = params => {
return fetch('/api/bs/hrmsalary/salaryitem/saveSys', {
method: 'POST',
mode: 'cors',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(params)
}).then(res => res.json())
}
return fetch("/api/bs/hrmsalary/salaryitem/saveSys", {
method: "POST",
mode: "cors",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(params)
}).then(res => res.json());
};
//获取薪资项目可选的类型(与属性有联动)
export const getItemTypeOption = params => {
return WeaTools.callApi('/api/bs/hrmsalary/salaryitem/listSalaryItemTypeOption', 'GET', params);
}
return WeaTools.callApi("/api/bs/hrmsalary/salaryitem/listSalaryItemTypeOption", "GET", params);
};
//获取公式描述
export const getFormulaDes = params => {
return WeaTools.callApi('/api/bs/hrmsalary/formula/des', 'GET', params);
}
return WeaTools.callApi("/api/bs/hrmsalary/formula/des", "GET", params);
};
// *** 公式 start ***
// 获取公式变量类型
export const formualSearchGroup = params => {
return fetch('/api/bs/hrmsalary/formula/search/group', {
method: 'POST',
mode: 'cors',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(params)
}).then(res => res.json())
}
return fetch("/api/bs/hrmsalary/formula/search/group", {
method: "POST",
mode: "cors",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(params)
}).then(res => res.json());
};
//获取公式变量字段
export const formualSearchField = params => {
return fetch('/api/bs/hrmsalary/formula/search/field', {
method: 'POST',
mode: 'cors',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(params)
}).then(res => res.json())
}
return fetch("/api/bs/hrmsalary/formula/search/field", {
method: "POST",
mode: "cors",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(params)
}).then(res => res.json());
};
// /api/bs/hrmsalary/formula/save
// 保存公式
export const saveFormual = params => {
return fetch('/api/bs/hrmsalary/formula/save', {
method: 'POST',
mode: 'cors',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(params)
}).then(res => res.json())
}
return fetch("/api/bs/hrmsalary/formula/save", {
method: "POST",
mode: "cors",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(params)
}).then(res => res.json());
};
// 公式测试
export const testFormual = params => {
return fetch('/api/bs/hrmsalary/formula/mock', {
method: 'POST',
mode: 'cors',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(params)
}).then(res => res.json())
}
return fetch("/api/bs/hrmsalary/formula/mock", {
method: "POST",
mode: "cors",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(params)
}).then(res => res.json());
};
// 根据id获取formual
export const detailFormual = params => {
return fetch('/api/bs/hrmsalary/formula/detail', {
method: 'POST',
mode: 'cors',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(params)
}).then(res => res.json())
}
return fetch("/api/bs/hrmsalary/formula/detail", {
method: "POST",
mode: "cors",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(params)
}).then(res => res.json());
};
// *** 公式 end ***
@ -179,14 +179,28 @@ export const detailFormual = params => {
// 列出可以删除的薪资项目
export const listCanDelete = params => {
return fetch('/api/bs/hrmsalary/salaryitem/listCanDelete', {
method: 'POST',
mode: 'cors',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(params)
}).then(res => res.json())
}
return fetch("/api/bs/hrmsalary/salaryitem/listCanDelete", {
method: "POST",
mode: "cors",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(params)
}).then(res => res.json());
};
//获取哪些账套中使用了该薪资项目
export const getSalarySobBySalaryItem = params => {
return WeaTools.callApi("/api/bs/hrmsalary/salaryitem/getSalarySobBySalaryItem", "GET", params);
};
// 同步到薪资账套
export const syncSalaryItemToSalarySobItem = params => {
return fetch("/api/bs/hrmsalary/salaryitem/syncSalaryItemToSalarySobItem ", {
method: "POST",
mode: "cors",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(params)
}).then(res => res.json());
};

View File

@ -1,4 +1,5 @@
import { WeaTools } from "ecCom";
import { convertToUrlString } from "../util/url";
// 工资单列表
export const mySalaryBillList = params => {
@ -25,7 +26,13 @@ export const recordList = params => {
// 工资查看详情
export const mySalaryBill = params => {
return WeaTools.callApi("/api/bs/hrmsalary/salaryBill/mySalaryBill", "GET", params);
return fetch(`/api/bs/hrmsalary/salaryBill/mySalaryBill?${convertToUrlString(params)}`, {
method: "GET",
mode: "cors",
headers: {
"Content-Type": "application/json"
}
}).then(res => res.json());
};
export const isNeedSecondPwdVerify = params => {

View File

@ -78,3 +78,31 @@ export const statisticsEmployeeDetailList = (params) => {
export const getDataPerspective = (params) => {
return postFetch("/api/bs/hrmsalary/report/statistics/report/getDataPerspective", params);
};
//报表分享-确认分享
export const salaryStatisticsPushSendMsg = (params) => {
return postFetch("/api/bs/salaryreport/salary/statistics/push/sendMsg", params);
};
//报表分享-表单数据
export const salaryStatisticsPushGetForm = (params) => {
return WeaTools.callApi("/api/bs/salaryreport/salary/statistics/push/getForm", "GET", params);
};
//报表记录-全部撤回
export const salaryStatisticsPushcancelAll = (params) => {
return WeaTools.callApi("/api/bs/salaryreport/salary/statistics/push/cancelAll", "GET", params);
};
//报表记录-撤回单条记录
export const salaryStatisticsPushcancel = (params) => {
return WeaTools.callApi("/api/bs/salaryreport/salary/statistics/push/cancel", "GET", params);
};
//报表记录-列表数据
export const salaryStatisticsPushGetTable = (params) => {
return postFetch("/api/bs/salaryreport/salary/statistics/push/getTable", params);
};
//报表记录-查看分享记录详情
export const salaryStatisticsPushGetDetail = (params) => {
return postFetch("/api/bs/salaryreport/salary/statistics/push/getDetail", params);
};
//报表记录-追加被分享人
export const salaryStatisticsPushAddSharedSendMsg = (params) => {
return postFetch("/api/bs/salaryreport/salary/statistics/push/addSharedSendMsg", params);
};

View File

@ -1,5 +1,5 @@
import { WeaTools } from "ecCom";
import { formPost, postFetch } from "../util/request";
import { postFetch } from "../util/request";
//个税扣缴义务人列表
export const getTaxAgentList = (params) => {
@ -7,9 +7,9 @@ export const getTaxAgentList = (params) => {
method: "POST",
mode: "cors",
headers: {
"Content-Type": "application/json",
"Content-Type": "application/json"
},
body: JSON.stringify(params),
body: JSON.stringify(params)
}).then((res) => res.json());
};
//同步人员范围
@ -18,9 +18,9 @@ export const taxAgentRangeSync = (params) => {
method: "POST",
mode: "cors",
headers: {
"Content-Type": "application/json",
"Content-Type": "application/json"
},
body: JSON.stringify(params),
body: JSON.stringify(params)
}).then((res) => res.json());
};
@ -108,12 +108,8 @@ export const taxAgentRangeImportData = (params) => {
};
//个税扣缴义务人下拉列表
export const getTaxAgentSelectList = (params) => {
return WeaTools.callApi(
"/api/bs/hrmsalary/taxAgent/selectList",
"GET",
params
);
export const getTaxAgentSelectList = (isShare = false) => {
return WeaTools.callApi("/api/bs/hrmsalary/taxAgent/selectList", "GET", { isShare });
};
//当前登录人个税扣缴义务人下拉列表

View File

@ -13,6 +13,10 @@ export const getCondition = params => {
export const queryList = (params) => {
return postFetch("/api/bs/hrmsalary/archives/getTable", params);
};
//社保福利档案_非系统人员列表
export const getExtTable = (params) => {
return postFetch("/api/bs/hrmsalary/archives/getExtTable", params);
};
//社保福利档案列表
export const queryInsuranceTabTotal = (params) => {
return WeaTools.callApi("/api/bs/hrmsalary/archives/queryInsuranceTabTotal", params);

View File

@ -8,6 +8,7 @@ import React, { Component } from "react";
import { WeaBrowser, WeaDialog, WeaFormItem, WeaSearchGroup, WeaSelect, WeaLocaleProvider } from "ecCom";
import { Button, message, Modal } from "antd";
import { getTaxAgentRangeForm } from "../../apis/taxAgent";
import { commonEnumList } from "../../apis/ruleconfig";
import { SelectWithAll } from "../../pages/socialSecurityBenefits/standingBookDetail/components/regAddEmployee";
import "./index.less";
@ -32,41 +33,74 @@ class PersonalScopeModal extends Component {
if (isTaxgent) {
this.getTaxAgentRangeForm();
} else {
const employeeStatus = [
{ key: "TRIAL", showname: getLabel(18883, "试用") },
{ key: "FORMAL", showname: getLabel(15711, "正式") },
{ key: "TEMPORARY", showname: getLabel(480, "临时") },
{ key: "DELAY", showname: getLabel(15844, "试用延期") },
{ key: "FIRE", showname: getLabel(542707, "解雇") },
{ key: "DEPARTURE", showname: getLabel(6091, "离职") },
{ key: "RETIRED", showname: getLabel(6092, "退休") }
];
const targetTypeList = [
{
key: "EMPLOYEE",
showname: getLabel(30042, "人员"),
selected: false
},
{
key: "SUBCOMPANY",
showname: getLabel(33553, "分部"),
selected: false
},
{
key: "DEPT",
showname: getLabel(27511, "部门"),
selected: false
},
{
key: "POSITION",
showname: getLabel(6086, "岗位"),
selected: false
}
];
this.setState({ targetTypeList, employeeStatus });
this.commonEnumList();
// const employeeStatus = [
// { key: "TRIAL", showname: "试用" },
// { key: "FORMAL", showname: "正式" },
// { key: "TEMPORARY", showname: "临时" },
// { key: "DELAY", showname: "试用延期" },
// { key: "FIRE", showname: "解雇" },
// { key: "DEPARTURE", showname: "离职" },
// { key: "RETIRED", showname: "退休" }
// ];
// const targetTypeList = [
// {
// key: "EMPLOYEE",
// showname: "人员",
// selected: false
// },
// {
// key: "SUBCOMPANY",
// showname: "分部",
// selected: false
// },
// {
// key: "DEPT",
// showname: "部门",
// selected: false
// },
// {
// key: "POSITION",
// showname: "岗位",
// selected: false
// }
// ];
// this.setState({ targetTypeList, employeeStatus });
}
}
commonEnumList = () => {
commonEnumList({ enumClass: "com.engine.salary.enums.UserStatusEnum" }).then(({ status, data }) => {
if (status) {
const targetTypeList = [
{
key: "EMPLOYEE",
showname: "人员",
selected: false
},
{
key: "SUBCOMPANY",
showname: "分部",
selected: false
},
{
key: "DEPT",
showname: "部门",
selected: false
},
{
key: "POSITION",
showname: "岗位",
selected: false
}
];
this.setState({
targetTypeList,
employeeStatus: _.map(_.filter(data, o => o.value !== 7), it => ({ key: it.enum, showname: it.defaultLabel }))
});
}
});
};
getTaxAgentRangeForm = () => {
getTaxAgentRangeForm().then(({ status, data }) => {
if (status) {
@ -92,7 +126,7 @@ class PersonalScopeModal extends Component {
employeeStatus: status.split(","),
includeType,
targetParams: _.map(targetTypeIds.split(","), it => ({ targetType, targetId: it })),
[saveKeyVal["key"]]: saveKeyVal["value"],
[saveKeyVal["key"]]: saveKeyVal["value"]
};
this.setState({ loading: true });
APISaveFox["save"](payload).then(({ status, errormsg }) => {

View File

@ -0,0 +1,94 @@
/*
* Author: 黎永顺
* name: 导入-步骤一
* Description:
* Date: 2023/8/11
*/
import React, { Component } from "react";
import { WeaLocaleProvider } from "ecCom";
import { Icon, message, Upload } from "antd";
const Dragger = Upload.Dragger;
const { getLabel } = WeaLocaleProvider;
class ImpStep1 extends Component {
constructor(props) {
super(props);
this.state = {
fileList: []
};
}
handleChange = (data) => {
const { fileList, file } = data;
if (file.response && typeof (file.response) != "undefined" && file.status !== "removed") message.success(getLabel(111, "上传成功"));
this.setState({ fileList: fileList.slice(-1) });
};
render() {
const { fileList } = this.state;
const dragger = {
accept: ".xlsx",
name: "file",
multiple: false,
action: "/api/doc/upload/uploadFile",
fileList,
onChange: this.handleChange
};
return (
<div className="weapp-batch-impsteps-picker-content-imp-step1">
{/* 导入选项 */}
{
this.props.importParams &&
<div className="weapp-salary-tb-border-bottom import-option">
<div>{getLabel(543201, "导入选项")}</div>
{this.props.importParams}
</div>
}
<div className="title">{getLabel(543202, "导入Excel")}</div>
<p className="draggerUploadWrapper">
<Dragger {...dragger}>
<div>
<p className="iconUpload"><Icon type="inbox"/></p>
<p className="uplaod-title">{getLabel(543203, "点击或将文件拖拽到此区域上传")}</p>
<p
className="uplaod-subTitle">{getLabel(543204, "支持单个或批量上传,严禁上传公司内部资料及其他违禁文件")}</p>
</div>
</Dragger>
</p>
<div className="bottom-border">
<div>{getLabel(27577, "操作步骤")}</div>
<p>
<span>{`1. ${getLabel(30907, "第一步")},${getLabel(543205, "请选择导出的Excel文件或")}`}</span>&nbsp;&nbsp;
{
typeof this.props.link === "string" ?
<a href={this.props.link} className="weapp-salary-link"
target="_blank">{getLabel(543207, "点击这里下载模板")}</a> :
<a className="weapp-salary-link"
onClick={this.props.link}
>{getLabel(543207, "点击这里下载模板")}</a>
}
&nbsp;&nbsp;
{this.props.exportDataDom}
</p>
<p>{`2. ${getLabel(543211, "第二步")},${getLabel(543212, "请一定要确定Excel文档中的格式是模板中的格式")},${getLabel(543213, "没有被修改掉")}`}</p>
<p>{`3. ${getLabel(543216, "第三步")},${getLabel(543215, "选择填写好的Excel文档")},${getLabel(543214, "点击“下一步”按钮进行数据预览")}`}</p>
<p>
{`4. ${getLabel(543217, "第四步")},${getLabel(543218, "如果以上步骤和Excel文档正确的话")},${getLabel(543219, "导入成功会有提示")},${getLabel(543220, "数据会被正确导入")}${getLabel(543221, "如果有问题")},${getLabel(543222, "则会提示Excel文档的错误之处")}`}
</p>
</div>
<div className="description">
<div>{getLabel(543223, "Excel文件说明")}</div>
<p>{`1. ${getLabel(543224, "后缀名为xls或者xlsx")};`}</p>
<p>{`2. ${getLabel(543225, "数据请勿放在合并的单元格中")};`}</p>
<p><span>{`3. ${getLabel(543226, "账单月份格式必须为")}:YYYY-MM`}</span></p>
</div>
</div>
);
}
}
export default ImpStep1;

View File

@ -0,0 +1,49 @@
/*
* Author: 黎永顺
* name: 导入-步骤二
* Description:
* Date: 2023/9/5
*/
import React, { Component } from "react";
import { WeaTable } from "ecCom";
import { postFetch } from "../../../util/request";
class ImpStep2 extends Component {
constructor(props) {
super(props);
this.state = {
loading: false, columns: [], dataSource: []
};
}
componentDidMount() {
this.init();
}
init = () => {
const { previewUrl, imageId, extraPreview = {} } = this.props;
const payload = { imageId, ...extraPreview };
this.setState({ loading: true });
postFetch(previewUrl, payload).then(({ status, data }) => {
this.setState({ loading: false });
if (status) {
const { headers, list } = data;
this.setState({
columns: _.map(headers, (item, index) => ({ title: item, dataIndex: index + "", width: 120 })),
dataSource: _.map(list, item => {
return _.reduce(item, (pre, cur, key) => (_.assign(pre, { [key]: cur })), {});
})
});
}
}).catch(() => this.setState({ loading: false }));
};
render() {
const { dataSource, columns, loading } = this.state;
return (
<WeaTable dataSource={dataSource} columns={columns} pagination={false} loading={loading} scroll={{ x: 800 }}/>
);
}
}
export default ImpStep2;

View File

@ -0,0 +1,51 @@
/*
* Author: 黎永顺
* name: 导入-步骤3
* Description:
* Date: 2023/8/11
*/
import React, { Component } from "react";
import { WeaLocaleProvider, WeaTable } from "ecCom";
import successImg from "../../importModal/success.svg";
const getLabel = WeaLocaleProvider.getLabel;
class ImpStep3 extends Component {
render() {
const { importResult } = this.props;
return (
<div className="weapp-batch-impsteps-picker-content-imp-step3">
{
!_.isEmpty(importResult) ?
<div className="weapp-batch-impsteps-picker-spinText">
<p><img src={successImg} alt=""/></p>
<p>
<span>{getLabel(389249, "已导入")}</span>
<span style={{ color: "green" }}> {importResult.successCount}</span>&nbsp;&nbsp;
<span>{`${getLabel(30690, "条数据")},${getLabel(25009, "失败")}`}</span>
<span style={{ color: "red" }}> {importResult.errorCount}&nbsp;&nbsp;</span>{getLabel(30690, "")}
</p>
</div> :
<div className="weapp-batch-impsteps-picker-spinText">
<p>{getLabel(111, "导入失败")}</p>
</div>
}
{
!_.isEmpty(importResult.errorData) &&
<WeaTable
columns={[
{
title: getLabel(25700, "错误信息"),
dataIndex: "message"
}
]}
dataSource={importResult.errorData} pagination={false}
scroll={{ y: `calc(100vh - 387px)` }}
/>
}
</div>
);
}
}
export default ImpStep3;

View File

@ -0,0 +1,153 @@
/*
* Author: 黎永顺
* name: 导入弹框-步骤条
* Description:
* Date: 2023/8/11
*/
import React, { Component } from "react";
import { Button, message, Modal } from "antd";
import { WeaDialog, WeaLocaleProvider, WeaSteps } from "ecCom";
import ImpStep1 from "./components/impStep1";
import ImpStep2 from "./components/impStep2";
import ImpStep3 from "./components/impStep3";
import "./index.less";
const { getLabel } = WeaLocaleProvider;
const Step = WeaSteps.Step;
class Index extends Component {
constructor(props) {
super(props);
this.state = {
current: 0
};
}
componentWillReceiveProps(nextProps, nextContext) {
if (JSON.stringify(nextProps.importResult) !== JSON.stringify(this.props.importResult) && !_.isEmpty(nextProps.importResult)) {
this.setState({
current: this.state.current + 1
});
}
if (nextProps.visible !== this.props.visible && !nextProps.visible) this.setState({ current: 0 });
}
renderChildren = () => {
const { current } = this.state;
const { importParams, link, excludeKey, importResult, exportDataDom = null } = this.props;
let CurrentDom = null;
switch (current) {
case 0:
CurrentDom = <ImpStep1 importParams={importParams} link={link} exportDataDom={exportDataDom}
ref={dom => this.step1Ref = dom}/>;
break;
case 1:
CurrentDom = <ImpStep2 {...this.props}/>;
if (excludeKey) {
CurrentDom = <ImpStep3 importResult={importResult}/>;
}
break;
case 2:
CurrentDom = <ImpStep3 importResult={importResult}/>;
break;
default:
CurrentDom = null;
break;
}
return CurrentDom;
};
/*
* Author: 黎永顺
* Description: 上一步
* Params:
* Date: 2023/9/5
*/
handlePreviousStep = () => {
Modal.confirm({
title: getLabel(131329, "信息确认"),
content: getLabel(111, "是否放弃已上传的文件?"),
onOk: () => this.setState({ current: this.state.current - 1 }, () => this.props.onResetImportResult())
});
};
/*
* Author: 黎永顺
* Description: 下一步
* Params:
* Date: 2023/8/11
*/
handleNext = () => {
const { params, importResult } = this.props;
if (_.isEmpty(importResult)) {
const { fileList } = this.step1Ref.state;
if (!_.isEmpty(params)) {
if (!Object.values(params).every(o => !!o)) {
Modal.warning({
title: getLabel(131329, "信息确认"),
content: getLabel(518702, "必要信息不完整,红色*为必填项!")
});
return;
}
}
if (_.isEmpty(fileList)) {
message.warning(getLabel(111, "请先上传EXCEL文件"));
return;
}
const [file] = fileList;
const { response } = file;
this.props.nextCallback(response.data.fileid);
} else {
this.setState({ current: this.state.current + 1 });
}
};
render() {
const { current } = this.state;
const stepData = [
{ key: 0, label: getLabel(543202, "上传EXCEL") },
{ key: 1, label: getLabel(543200, "数据预览") },
{ key: 2, label: getLabel(502835, "导入数据") }
];
const btns = [
<Button type="ghost" onClick={this.handlePreviousStep}>{getLabel(1876, "上一步")}</Button>,
<Button type="primary" onClick={this.handleNext}
loading={this.props.nextloading}>{getLabel(1402, "下一步")}</Button>,
<Button type="primary" onClick={() => this.props.onCancel(true)}>{getLabel(555, "完成")}</Button>
];
return (
<WeaDialog
{...this.props}
scalable hasScroll className="importBox" initLoadCss
buttons={current === 0 ? _.nth(btns, 1) : (!this.props.excludeKey && current === 1) ? _.take(btns, 2) : _.takeRight(btns)}
style={{
width: 800,
height: 606.6,
minHeight: 200,
minWidth: 380,
maxHeight: "90%",
maxWidth: "90%",
overflow: "hidden",
transform: "translate(0px, 0px)"
}}
>
<div className="importCont">
<div className="weapp-batch-impsteps-picker-content-imp-steps">
<WeaSteps current={current}>
{/*this.props.key: 不需要展示的步骤*/}
{
_.map(_.filter(stepData, item => item.key !== this.props.excludeKey), it => (
<Step key={it.key} description={it.label}/>))
}
</WeaSteps>
</div>
<div className="weapp-batch-impsteps-picker">
{
this.renderChildren()
}
</div>
</div>
</WeaDialog>
);
}
}
export default Index;

View File

@ -0,0 +1,143 @@
.importBox {
.importCont {
padding: 16px 8px;
.weapp-batch-impsteps-picker-content-imp-steps {
width: 80%;
margin: 0 auto;
}
.weapp-batch-impsteps-picker {
margin: 16px auto;
.weapp-batch-impsteps-picker-content-imp-step1 {
width: 98%;
background-color: #fff;
margin: 8px auto;
border-radius: 3px;
padding: 1px 12px;
.weapp-batch-impsteps-picker-content-imp-step1 div {
color: #111;
line-height: 22px;
}
.weapp-salary-tb-border-bottom .weapp-salary-tb-filter.weapp-salary-import-param {
box-sizing: border-box;
padding: 16px;
height: auto;
flex-wrap: wrap;
width: 100%;
}
.weapp-salary-import-param {
border: 1px solid #ebedf0;
padding: 8px;
margin: 4px 0 14px;
}
.weapp-salary-tb-filter {
display: flex;
flex-wrap: wrap;
align-items: center;
height: 46px;
}
.weapp-salary-tb-border-bottom .weapp-salary-tb-filter.weapp-salary-import-param .tbf-item {
display: flex;
justify-content: flex-start !important;
}
.weapp-salary-tb-filter .tbf-item {
padding: 0 20px 0 0;
display: flex;
align-items: center;
font-size: 12px;
color: #111;
height: 40px;
}
.weapp-salary-tb-filter .tbf-item > .tbfi-label {
flex-basis: 100px;
flex-shrink: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
padding-right: 10px;
color: #666;
}
.draggerUploadWrapper {
margin: 16px 0 0;
.ant-upload-drag-container {
padding: 24px 0 16px;
.iconUpload {
i {
color: #5d9cec;
font-size: 43px;
}
}
.uplaod-title {
font-size: 14px;
color: #333;
height: 24px;
line-height: 24px;
margin-top: 8px;
}
.uplaod-subTitle {
height: 22px;
font-size: 12px;
color: #666;
text-align: center;
line-height: 22px;
}
}
}
.bottom-border, .description {
margin-top: 12px;
p {
font-size: 12px;
color: #666;
line-height: 15px;
margin: 12px 0;
}
}
.bottom-border {
border-bottom: 1px solid #e5e5e5;
.weapp-salary-link {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
color: #5d9cec;
}
}
}
}
.weapp-batch-impsteps-picker-content-imp-step3 {
.weapp-batch-impsteps-picker-spinText {
position: relative;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
text-align: center;
p {
margin: 14px 0;
}
}
}
}
}

View File

@ -25,6 +25,8 @@ import TaxAgent from "./pages/taxAgent";
import CalculateDetail from "./pages/calculateDetail";
import PlaceOnFileDetail from "./pages/calculateDetail/placeOnFileDetail";
import CompareDetail from "./pages/calculateDetail/compareDetail";
import DoCalcDetail from "./pages/calculate/doCalc";
import OfflineCompare from "./pages/calculate/calcOc";
import GenerateDeclarationDetail from "./pages/declare/generateDeclarationDetail";
import TemplatePreview from "./pages/payroll/templatePreview";
import MobilePayroll from "./pages/mobilePayroll";
@ -73,6 +75,8 @@ const DataAcquisition = (props) => props.children;
// ledger 薪资账套
// calculate 薪资核算
// calculateDetail 核算详情
// DoCalcDetail 核算详情页面-新
// OfflineCompare 薪资核算线下对比-新
// placeOnFileDetail 核算归档详情
// compareDetail 线下线上对比
// payroll 工资单发放
@ -129,16 +133,10 @@ const Routes = (
</Route>
<Route key="ledger" path="ledger" component={Ledger}/>
<Route key="calculate" path="calculate" component={Calculate}/>
<Route
key="calculateDetail"
path="calculateDetail"
component={CalculateDetail}
/>
<Route
key="placeOnFileDetail"
path="placeOnFileDetail"
component={PlaceOnFileDetail}
/>
<Route key="calculateDetail" path="calculateDetail" component={CalculateDetail}/>
<Route key="doCalc" path="calculate/:salaryAcctRecordId" component={DoCalcDetail}/>
<Route key="calcOc" path="calcOc/:salaryAcctRecordId" component={OfflineCompare}/>
<Route key="placeOnFileDetail" path="placeOnFileDetail" component={PlaceOnFileDetail}/>
<Route key="compareDetail" path="compareDetail" component={CompareDetail}/>
<Route key="payroll" path="payroll" component={Payroll}/>
<Route key="watermarkPreview" path="payroll/watermark/preview" component={WatermarkPreview}/>

View File

@ -54,7 +54,6 @@ export const condition = [
options: [],
viewAttr: 2,
helpfulTip: "",
hide: true
},
{
colSpan: 1,
@ -99,7 +98,6 @@ export const reportCondition = [
rules: "required|string",
viewAttr: 3,
helpfulTip: "",
hide: true
}
],
title: "",

View File

@ -73,7 +73,7 @@ class ReportList extends Component {
{
_.isEmpty(dataSource) ? <div className="empty">{getLabel(83553, "暂无数据")}</div> :
_.map(dataSource, it => {
const { reportName, dimension, id, dimensionId } = it;
const { reportName, dimension, id, dimensionId, isShare } = it;
return <Col className="gutter-row" span={6} onClick={() => this.handleGoReportView(id)}>
<div className="card-item">
<div className="cardLeft"><i className="icon-coms-fa"/></div>
@ -85,15 +85,25 @@ class ReportList extends Component {
</div>
</div>
<div className="cardRight">
<Dropdown overlay={
<Menu onClick={e => this.handleOptsClick(e, id, dimensionId)}>
<Menu.Item key="edit">{getLabel(501169, "编辑")}</Menu.Item>
<Menu.Item key="delete">{getLabel(535052, "删除")}</Menu.Item>
</Menu>
}>
<Button type="ghost"><i className="icon-coms-more"/></Button>
</Dropdown>
{
!isShare &&
<Dropdown overlay={
<Menu onClick={e => this.handleOptsClick(e, id, dimensionId)}>
<Menu.Item key="edit">{getLabel(501169, "编辑")}</Menu.Item>
<Menu.Item key="delete">{getLabel(535052, "删除")}</Menu.Item>
</Menu>
}>
<Button type="ghost"><i className="icon-coms-more"/></Button>
</Dropdown>
}
</div>
{
isShare &&
<div className="ant-ribbon ant-ribbon-placement-end">
<span className="ant-ribbon-text">{getLabel(111, "被分享")}</span>
<div className="ant-ribbon-corner"></div>
</div>
}
</div>
</Col>;
})

View File

@ -31,6 +31,47 @@
justify-content: space-between;
padding: 22px 0 22px 16px;
border: 1px solid #e5e5e5;
position: relative;
.ant-ribbon {
padding: 0 8px;
color: #1677ff;
font-size: 12px;
line-height: 22px;
list-style: none;
position: absolute;
top: 0;
white-space: nowrap;
background-color: #1677ff;
border-radius: 4px;
.ant-ribbon-text {
color: #FFF;
}
.ant-ribbon-corner {
position: absolute;
top: 100%;
width: 8px;
height: 8px;
color: currentcolor;
border: 4px solid;
transform: scaleY(.75);
transform-origin: top;
filter: brightness(75%);
}
}
.ant-ribbon-placement-end {
inset-inline-end: -8px;
border-end-end-radius: 0;
.ant-ribbon-corner {
inset-inline-end: 0;
border-inline-end-color: transparent;
border-block-end-color: transparent;
}
}
.cardLeft {
display: flex;

View File

@ -0,0 +1,71 @@
/*
* Author: 黎永顺
* name: 薪資核算-线下对比导入
* Description:
* Date: 2023/9/27
*/
import React, { Component } from "react";
import { WeaLocaleProvider } from "ecCom";
import ImportDialog from "../../../../components/importDialog";
import { importComparisonExcelAcctResult } from "../../../../apis/calculate";
const getLabel = WeaLocaleProvider.getLabel;
class SalaryCalcOcImport extends Component {
constructor(props) {
super(props);
this.state = {
importDialog: {
visible: false, title: "", nextloading: false, importResult: {}, imageId: "",
link: "/api/bs/hrmsalary/salaryacct/comparisonresult/importtemplate/export?salaryAcctRecordId=",
previewUrl: "/api/bs/hrmsalary/salaryacct/comparisonresult/preview",
extraPreview: { salaryAcctRecordId: "" }
}
};
}
componentWillReceiveProps(nextProps, nextContext) {
if (nextProps.visible !== this.props.visible) {
const { importDialog } = this.state;
this.setState({
importDialog: {
...this.state.importDialog,
link: `${importDialog.link}${nextProps.salaryAcctRecordId}`,
visible: nextProps.visible, importResult: {},
title: nextProps.title, imageId: "",
extraPreview: { salaryAcctRecordId: nextProps.salaryAcctRecordId }
}
});
}
}
handleImport = (payload) => {
const { importDialog } = this.state;
const { salaryAcctRecordId } = this.props;
this.setState({ importDialog: { ...importDialog, nextloading: true } });
importComparisonExcelAcctResult({ ...payload, salaryAcctRecordId })
.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;
return (
<ImportDialog
{...importDialog} onCancel={this.props.onCancel} exportDataDom={null}
onResetImportResult={() => this.setState(({
importDialog: { ...importDialog, importResult: {}, imageId: "" }
}))}
nextCallback={imageId => this.handleImport({ imageId })}
/>
);
}
}
export default SalaryCalcOcImport;

View File

@ -0,0 +1,126 @@
/*
* Author: 黎永顺
* name: 薪资核算-线下对比列表
* Description:
* Date: 2023/9/26
*/
import React, { Component } from "react";
import { WeaLocaleProvider, WeaTable } from "ecCom";
import { Alert } from "antd";
import { comparisonResultList } from "../../../../apis/calculate";
const getLabel = WeaLocaleProvider.getLabel;
class SalaryCalcOcList extends Component {
constructor(props) {
super(props);
this.state = {
loading: false, pageInfo: { current: 1, pageSize: 10, total: 0 },
columns: [], dataSource: [], formulaDesc: ""
};
}
componentDidMount() {
this.comparisonResultList(this.props);
}
componentWillReceiveProps(nextProps, nextContext) {
if (
(nextProps.form.onlyDiffEmployee !== this.props.form.onlyDiffEmployee) ||
(nextProps.form.onlyDiffSalaryItem !== this.props.form.onlyDiffSalaryItem) ||
(nextProps.searchBool !== this.props.searchBool)
) {
this.comparisonResultList(nextProps);
}
}
comparisonResultList = (props) => {
const { form, routeParams: { salaryAcctRecordId } } = props;
const { pageInfo } = this.state;
this.setState({ loading: true });
const payload = { ...pageInfo, ...form, salaryAcctRecordId };
comparisonResultList(payload).then(({ status, data }) => {
this.setState({ loading: false });
if (status) {
const { list: dataSource, columns, pageNum: current, pageSize, total } = data;
this.setState({
dataSource, columns,
pageInfo: { ...pageInfo, current, pageSize, total }
});
}
}).catch(() => this.setState({ loading: false }));
};
render() {
const { dataSource, loading, columns, pageInfo, formulaDesc } = this.state;
const pagination = {
...pageInfo,
showTotal: total => `${getLabel(18609, "共")} ${total} ${getLabel(18256, "条")}`,
showQuickJumper: true,
showSizeChanger: true,
pageSizeOptions: ["10", "20", "50", "100"],
onShowSizeChange: (current, pageSize) => {
this.setState({
pageInfo: { ...pageInfo, current, pageSize }
}, () => this.comparisonResultList(this.props));
},
onChange: current => {
this.setState({
pageInfo: { ...pageInfo, current }
}, () => this.comparisonResultList(this.props));
}
};
return (
<React.Fragment>
<Alert message={`${getLabel(18125, "公式")}${formulaDesc}`} type="info"/>
<WeaTable
rowKey="id" pagination={pagination} loading={loading} dataSource={dataSource}
scroll={{ x: 840, y: "calc(100vh - 246px)" }}
columns={_.map(columns, (o, i) => {
if (i > 1) {
if (i > 2) {
return {
...o, width: 180,
render: (__, record) => {
const formulaDesc = record["customParameters"][`${o["dataIndex"]}`];
const showDifference = record[`${o["dataIndex"]}_type`] === "number";
const { acctResultValue, excelResultValue } = record[o["dataIndex"]];
return <div className="comparison-column-item-container"
onClick={() => this.setState({ formulaDesc })}>
<div className="comparison-single-row">
<span>{getLabel(543280, "系统值")}</span>
<span>{acctResultValue}</span>
</div>
<div className="comparison-single-row">
<span>{getLabel(543281, "线下值")}</span>
<span>{excelResultValue}</span>
</div>
{
showDifference &&
<div className="comparison-single-row danger">
<span>{getLabel(543282, "差值")}</span>
<span>{calculateDifference(acctResultValue, excelResultValue)}</span>
</div>
}
</div>;
}
};
}
return { ...o, width: 180 };
}
return { ...o, width: 150, fixed: "left" };
})}
/>
</React.Fragment>
);
}
}
export default SalaryCalcOcList;
// 计算差值
const calculateDifference = (systemValue, excelValue) => {
if (_.isNil(systemValue) || _.isNil(excelValue)) return "";
const systemNum = Number(systemValue);
const excelNum = Number(excelValue);
return (systemNum - excelNum).toFixed(2);
};

View File

@ -0,0 +1,85 @@
/*
* Author: 黎永顺
* name: 薪资核算-线下对比
* Description:
* Date: 2023/9/26
*/
import React, { Component } from "react";
import { Button } from "antd";
import { WeaCheckbox, WeaInputSearch, WeaLocaleProvider } from "ecCom";
import SalaryCalcOcList from "./components/salaryCalcOcList";
import SalaryCalcOcImport from "./components/salaryCalcOcImport";
import Layout from "../doCalc/layout";
import "./index.less";
const getLabel = WeaLocaleProvider.getLabel;
class Index extends Component {
constructor(props) {
super(props);
this.state = {
salaryOcImpDialog: { visible: false, title: "", salaryAcctRecordId: "" },
form: {
onlyDiffEmployee: true, onlyDiffSalaryItem: true,
employeeName: ""
}, searchBool: false
};
}
handleFiledChange = (key, value) => {
const { form } = this.state;
this.setState({
form: { ...form, [key]: value }
});
};
handleExportClick = () => {
const { routeParams: { salaryAcctRecordId } } = this.props;
window.open(`/api/bs/hrmsalary/salaryacct/comparisonresult/export?salaryAcctRecordId=${salaryAcctRecordId}`, "_blank");
};
handleImportClick = () => {
const { routeParams: { salaryAcctRecordId } } = this.props;
this.setState({
salaryOcImpDialog: { visible: true, title: getLabel(24023, "数据导入"), salaryAcctRecordId }
});
};
render() {
const { form, searchBool, salaryOcImpDialog } = this.state;
return (
<Layout {...this.props}>
<div className="salary-calc-oc">
<div className="compare-header header-border-bottom">
<div className="left-search">
<WeaCheckbox content={getLabel(543283, "只显示有差异的人员")}
value={form["onlyDiffEmployee"] ? "1" : "0"}
onChange={v => this.handleFiledChange("onlyDiffEmployee", v === "1")}/>
<WeaCheckbox content={getLabel(543284, "只显示有差异的薪资项目")}
value={form["onlyDiffSalaryItem"] ? "1" : "0"}
onChange={v => this.handleFiledChange("onlyDiffSalaryItem", v === "1")}/>
</div>
<div className="weapp-salary-btn-flex header">
<Button type="primary" onClick={this.handleImportClick}>{getLabel(32935, "导入")}</Button>
<Button type="ghost" onClick={this.handleExportClick}>{getLabel(17416, "导出")}</Button>
<WeaInputSearch placeholder={getLabel(26919, "请输入姓名")} value={form["employeeName"]}
onChange={v => this.handleFiledChange("employeeName", v)}
onSearch={() => this.setState({ searchBool: !searchBool })}/>
</div>
</div>
<div className="salary-calc-oc-body">
<SalaryCalcOcList {...this.props} form={form} searchBool={searchBool}/>
<SalaryCalcOcImport
{...salaryOcImpDialog}
onCancel={(isFresh) => this.setState({
salaryOcImpDialog: { ...salaryOcImpDialog, visible: false },
searchBool: typeof isFresh === "boolean" ? !searchBool : searchBool
})}
/>
</div>
</div>
</Layout>
);
}
}
export default Index;

View File

@ -0,0 +1,83 @@
.salary-calc-oc {
width: 100%;
height: 100%;
overflow: hidden;
background: #f6f6f6;
display: flex;
flex-direction: column;
.compare-header {
padding-left: 16px;
display: flex;
justify-content: space-between;
align-items: center;
.left-search {
display: flex;
align-items: center;
}
.weapp-salary-btn-flex {
display: flex;
align-items: center;
justify-content: flex-end;
cursor: auto;
& > button {
margin-right: 10px;
}
.wea-input-focus {
background: #f6f6f6;
margin-top: -4px;
.ant-input {
background: #f6f6f6;
}
}
}
.header {
height: 48px;
padding: 0 16px;
font-size: 12px;
color: #111;
}
}
.header-border-bottom {
border-bottom: 1px solid #e5e5e5;
}
.salary-calc-oc-body {
flex: 1;
padding: 16px;
overflow-y: hidden;
.wea-new-table {
background: #FFF;
height: calc(100% - 44px);
.ant-table-tbody {
td {
width: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
.comparison-column-item-container {
cursor: pointer;
.comparison-single-row {
margin: 4px 0;
}
.danger {
color: #ff4d4f;
}
}
}
}
}

View File

@ -0,0 +1,27 @@
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("calculateStore")
@observer
class Index extends Component {
render() {
const { calculateStore: { ECSearchForm } } = this.props;
return (
<div className="advance-search">
<WeaInputSearch value={ECSearchForm.getFormParams().employeeName}
onChange={v => ECSearchForm.updateFields({ employeeName: v })}
onSearch={this.props.onAdvanceSearch}
/>
<Button type="ghost" className="wea-advanced-search text-elli"
onClick={this.props.onOpenAdvanceSearch}>{getLabel(111, "高级搜索")}</Button>
</div>
);
}
}
export default Index;

View File

@ -0,0 +1,28 @@
.advance-search {
display: flex;
align-items: center;
position: relative;
top: -2.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;
}
}

View File

@ -0,0 +1,138 @@
/*
* Author: 黎永顺
* name: 薪资核算-自定义导出
* Description:
* Date: 2023/9/18
*/
import React, { Component } from "react";
import { Button, Col, message, Row } from "antd";
import { inject, observer } from "mobx-react";
import { WeaCheckbox, WeaDialog, WeaLocaleProvider, WeaSearchGroup } from "ecCom";
import { customCacheExportField } from "../../../../../apis/calculate";
import { convertToUrlString } from "../../../../../util/url";
const { getLabel } = WeaLocaleProvider;
@inject("calculateStore")
@observer
class Index extends Component {
constructor(props) {
super(props);
this.state = {
itemsCheckeds: [],
showOnlyChecked: false
};
}
componentWillReceiveProps(nextProps, nextContext) {
if (nextProps.visible !== this.props.visible && nextProps.visible) {
this.setState({
itemsCheckeds: !_.isEmpty(nextProps.checkItems) ? nextProps.checkItems : []
});
}
}
customExportClick = () => {
const { calculateStore: { ECSearchForm }, salaryAcctRecordId } = this.props;
const { itemsCheckeds } = this.state;
customCacheExportField({ salaryItems: _.map(itemsCheckeds, it => it.toString()) }).then(({ status, errorMsg }) => {
if (status) {
const { consolidatedTaxation = "0", ...extra } = ECSearchForm.getFormParams();
const payload = { ...extra, consolidatedTaxation: consolidatedTaxation === "0" ? "" : consolidatedTaxation };
window.open(
`/api/bs/hrmsalary/salaryacct/acctresult/exportWithCustomFields?salaryAcctRecordId=${salaryAcctRecordId}&ids=&${convertToUrlString(payload)}&salaryItemIds=${itemsCheckeds.join(",")}`
);
} else {
message.error(errorMsg);
}
});
};
handleShowOnlyChecked = (showOnlyChecked) => this.setState({ showOnlyChecked: !!Number(showOnlyChecked) });
handleSelectGroupAll = (groupId, checked) => {
const { itemsCheckeds } = this.state;
const { itemsByGroup } = this.props;
_.map(itemsByGroup, item => {
if (item.salarySobItemGroupId === groupId) {
if (!!Number(checked)) {
this.setState({
itemsCheckeds: [...itemsCheckeds, ..._.map(item.salaryItems, child => child.salaryItemId)]
});
} else {
this.setState({
itemsCheckeds: _.differenceWith(itemsCheckeds, _.map(item.salaryItems, child => child.salaryItemId), _.isEqual)
});
}
}
});
};
render() {
const { showOnlyChecked, itemsCheckeds } = this.state;
const { itemsByGroup } = this.props;
let dataSource = _.map(itemsByGroup, item => {
return {
...item,
salaryItems: _.map(item.salaryItems, child => {
return { ...child, checked: itemsCheckeds.includes(child.salaryItemId) };
})
};
});
if (showOnlyChecked) {
dataSource = _.map(dataSource, item => {
return { ...item, salaryItems: _.filter(item.salaryItems, it => !!it.checked) };
});
}
return (
<WeaDialog
{...this.props} hasScroll initLoadCss
scalable title={getLabel(111, "选择字段")}
style={{
width: 700,
height: 606.6,
minHeight: 200,
minWidth: 380,
maxHeight: "70%",
maxWidth: "90%",
overflow: "hidden",
transform: "translate(0px, 0px)"
}}
buttons={[
<Button type="primary" onClick={this.customExportClick}>{getLabel(17416, "导出")}</Button>,
<Button type="ghost" onClick={this.props.onCancel}>{getLabel(31129, "取消")}</Button>
]}
bottomLeft={<WeaCheckbox content={getLabel(543378, "只显示已选中字段")}
onChange={this.handleShowOnlyChecked}/>}
>
{
_.map(dataSource, item => {
const { salarySobItemGroupName, salaryItems, salarySobItemGroupId } = item;
const value = _.every(salaryItems, it => !!it.checked) ? "1" : "0";
return <WeaSearchGroup showGroup needTigger
title={<WeaCheckbox content={salarySobItemGroupName} value={value}
onChange={(val) => this.handleSelectGroupAll(salarySobItemGroupId, val)}/>}>
<Row gutter={16}>
{
!_.isEmpty(salaryItems) ?
_.map(salaryItems, it => {
const { salaryItemId, salaryItemName, checked } = it;
return <Col span={8} style={{ marginBottom: 16 }}>
<WeaCheckbox content={salaryItemName} value={checked ? "1" : "0"}
onChange={() => this.setState({ itemsCheckeds: _.xorWith(itemsCheckeds, [salaryItemId], _.isEqual) })}/>
</Col>;
}) : <Col span={24} style={{
minHeight: 20,
padding: "5%",
textAlign: "center"
}}>{getLabel(83553, "暂无数据")}</Col>
}
</Row>
</WeaSearchGroup>;
})
}
</WeaDialog>
);
}
}
export default Index;

View File

@ -0,0 +1,75 @@
/*
* Author: 黎永顺
* name: 人员信息确认-基础信息
* Description:
* Date: 2023/9/13
*/
import React, { Component } from "react";
import { WeaHelpfulTip, WeaLocaleProvider, WeaSearchGroup } from "ecCom";
import SalaryMonthTip from "../salaryMonthTip";
import { getSalarySobCycle, salaryacctGetForm } from "../../../../../apis/calculate";
import { Col, Row } from "antd";
import "./index.less";
const getLabel = WeaLocaleProvider.getLabel;
class BaseInfo extends Component {
constructor(props) {
super(props);
this.state = {
salaryInfo: {}, salarySobCycle: {}
};
}
componentDidMount() {
const promise = this.init();
}
init = async () => {
const { routeParams: { salaryAcctRecordId } } = this.props;
const [salaryInfo, salarySobCycle] = await Promise.all([salaryacctGetForm({ id: salaryAcctRecordId }), getSalarySobCycle({ salaryAcctRecordId })]);
if (salaryInfo.status && salarySobCycle.status) {
this.setState({
salaryInfo: salaryInfo.data, salarySobCycle: salarySobCycle.data
});
}
};
render() {
const { salaryInfo, salarySobCycle } = this.state;
const { formDTO } = salaryInfo || {};
return (
<WeaSearchGroup title={getLabel(82743, "基础信息")} needTigger showGroup className="docalc-baseinfo-layout">
<Row type="flex" className="docalc-baseinfo">
<Col span={12}>
<Row>
<Col span={6}>
<span className="label">{getLabel(542604, "薪资所属月")}</span>
<WeaHelpfulTip
width={200} placement="topLeft"
title={<SalaryMonthTip {...salarySobCycle}/>}
style={{ marginLeft: 10 }}
/>
</Col>
<Col span={18}><span className="value">{formDTO && formDTO.salaryMonth}</span></Col>
</Row>
</Col>
<Col span={12}>
<Row>
<Col span={6}><span className="label">{getLabel(519146, "核算账套")}</span></Col>
<Col span={18}><span className="value">{formDTO && formDTO.salarySobName}</span></Col>
</Row>
</Col>
<Col span={24}>
<Row>
<Col span={3}><span className="label">{getLabel(536726, "备注")}</span></Col>
<Col span={21}><span className="value">{formDTO && formDTO.description}</span></Col>
</Row>
</Col>
</Row>
</WeaSearchGroup>
);
}
}
export default BaseInfo;

View File

@ -0,0 +1,104 @@
export const personConfirmSearchConditions = [
{
items: [
{
colSpan: 2,
conditionType: "INPUT",
domkey: ["employeeName"],
fieldcol: 12,
label: "姓名",
lanId: 25034,
labelcol: 6,
value: "",
viewAttr: 2
},
{
colSpan: 2,
conditionType: "INPUT",
domkey: ["workcode"],
fieldcol: 12,
label: "工号",
lanId: 1933,
labelcol: 6,
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: "57",
viewAttr: 2
},
colSpan: 2,
conditionType: "BROWSER",
domkey: ["departmentIds"],
fieldcol: 12,
label: "部门",
lanId: 27511,
labelcol: 6,
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
},
colSpan: 2,
conditionType: "BROWSER",
domkey: ["positionIds"],
fieldcol: 12,
label: "岗位",
lanId: 6086,
labelcol: 6,
viewAttr: 2
},
{
colSpan: 2,
conditionType: "SELECT",
domkey: ["statuses"],
fieldcol: 12,
multiple: true,
label: "状态",
lanId: 535101,
labelcol: 6,
options: [],
viewAttr: 2
}
],
defaultshow: true,
title: "常用条件"
}
];

View File

@ -0,0 +1,287 @@
/*
* Author: 黎永顺
* name: 人员确认
* Description:
* Date: 2023/9/13
*/
import React, { Component } from "react";
import { WeaBrowser, WeaButtonIcon, WeaHelpfulTip, WeaLocaleProvider, WeaTab, WeaTable, WeaTools } from "ecCom";
import { inject, observer } from "mobx-react";
import { Button, message, Modal } from "antd";
import BaseInfo from "./baseInfo";
import {
acctemployeeList,
addedemployeeList,
deleteAcctemployee,
reducedemployeeList,
saveAcctemployee
} from "../../../../../apis/calculate";
import { personConfirmSearchConditions } from "./condition";
import { getSearchs } from "../../../../../util";
import { convertToUrlString } from "../../../../../util/url";
const getKey = WeaTools.getKey;
const getLabel = WeaLocaleProvider.getLabel;
const api = {
range: acctemployeeList,
sub: reducedemployeeList,
add: addedemployeeList
};
@inject("calculateStore")
@observer
class Index extends Component {
constructor(props) {
super(props);
this.state = {
selectedKey: "range", showSearchAd: false,
searchConditions: [], loading: false,
pageInfo: { current: 1, pageSize: 10, total: 0 },
selectedRowKeys: [], dataSource: [], columns: []
};
}
componentDidMount() {
if ($) {
const domTabInnerList = $(".salary-calculate-do-calc-content .ant-tabs-tab-inner");
domTabInnerList[0].setAttribute("title", "");
domTabInnerList[1].setAttribute("title", "");
domTabInnerList[2].setAttribute("title", "");
}
this.setState({
searchConditions: _.map(personConfirmSearchConditions, item => {
return {
...item,
items: _.map(item.items, o => {
if (getKey(o) === "statuses") {
return {
...o,
options: [
{ key: "0", showname: getLabel(18883, "试用") }, { key: "1", showname: getLabel(15711, "正式") },
{ key: "2", showname: getLabel(480, "临时") }, { key: "3", showname: getLabel(15844, "试用延期") },
{ key: "4", showname: getLabel(542707, "解雇") }, { key: "5", showname: getLabel(6091, "离职") },
{ key: "6", showname: getLabel(6092, "退休") }
]
};
}
return { ...o };
}),
title: getLabel(32905, "常用条件")
};
})
}, () => {
const { calculateStore: { PCSearchForm } } = this.props;
PCSearchForm.initFormFields(this.state.searchConditions);
this.queryPCList();
});
}
renderTabBtns = () => {
const { selectedKey, selectedRowKeys } = this.state;
let tabBtns = [];
switch (selectedKey) {
case "range":
tabBtns = [
<WeaButtonIcon buttonType="del" type="primary" title={getLabel(111, "批量删除")}
disabled={_.isEmpty(selectedRowKeys)}
onClick={() => this.handleDeletePCitem()}/>,
<WeaBrowser type={17} title={getLabel(383694, "添加人员")} isSingle={false} customized
onChange={ids => ids && this.handleUserBrowserChange(ids.split(","))}
>
<WeaButtonIcon buttonType="add" type="primary" title={getLabel(1421, "新增")}/>
</WeaBrowser>,
<Button type="primary" onClick={this.handleExport}>{getLabel(17416, "导出")}</Button>
];
break;
case "add":
case "sub":
tabBtns = [
<Button type="primary" onClick={this.handleExport}>{getLabel(17416, "导出")}</Button>
];
break;
default:
break;
}
return tabBtns;
};
queryPCList = () => {
const { pageInfo, selectedKey } = this.state;
const { calculateStore: { PCSearchForm }, routeParams: { salaryAcctRecordId } } = this.props;
const { departmentIds, positionIds, statuses, ...extra } = PCSearchForm.getFormParams();
const payload = {
salaryAcctRecordId, ...pageInfo, ...extra,
departmentIds: !_.isEmpty(departmentIds) ? departmentIds.split(",") : [],
positionIds: !_.isEmpty(positionIds) ? positionIds.split(",") : [],
statuses: !_.isEmpty(statuses) ? statuses.split(",") : []
};
this.setState({ loading: true });
api[selectedKey](payload).then(({ status, data }) => {
this.setState({ loading: false });
if (status) {
const { columns, list: dataSource = [], pageNum: current, pageSize, total } = data;
this.setState({
columns, dataSource, pageInfo: { ...pageInfo, current, pageSize, total }
});
}
}).catch(() => this.setState({ loading: false }));
};
handleDeletePCitem = (ids) => {
Modal.confirm({
title: getLabel(131329, "信息确认"),
content: getLabel(388758, "确认要删除吗?"),
onOk: () => {
const { selectedRowKeys } = this.state;
const { routeParams: { salaryAcctRecordId } } = this.props;
deleteAcctemployee({ salaryAcctRecordId, ids: !_.isEmpty(ids) ? ids : selectedRowKeys })
.then(({ status, errormsg }) => {
if (status) {
message.success(getLabel(502230, "删除成功!"));
this.queryPCList();
_.isNil(ids) && this.setState({ selectedRowKeys: [] });
} else {
message.error(errormsg || getLabel(20462, "删除失败!"));
}
});
}
});
};
/*
* Author: 黎永顺
* Description: 人员确认导出
* Params:
* Date: 2023/9/14
*/
handleExport = () => {
let url = "";
const { routeParams: { salaryAcctRecordId }, calculateStore: { PCSearchForm } } = this.props;
if (this.state.selectedKey === "range") {
url = `${window.location.origin}/api/bs/hrmsalary/salaryacct/acctemployee/export?salaryAcctRecordId=${salaryAcctRecordId}&${convertToUrlString(PCSearchForm.getFormParams())}`;
} else if (this.state.selectedKey === "sub") {
url = `${window.location.origin}/api/bs/hrmsalary/salaryacct/reducedemployee/export?salaryAcctRecordId=${salaryAcctRecordId}&${convertToUrlString(PCSearchForm.getFormParams())}`;
} else {
url = `${window.location.origin}/api/bs/hrmsalary/salaryacct/addedemployee/export?salaryAcctRecordId=${salaryAcctRecordId}&${convertToUrlString(PCSearchForm.getFormParams())}`;
}
window.open(url, "_blank");
};
/*
* Author: 黎永顺
* Description: 添加人员确认
* Params:
* Date: 2023/9/14
*/
handleUserBrowserChange = (employeeIds) => {
const { routeParams: { salaryAcctRecordId } } = this.props;
saveAcctemployee({ salaryAcctRecordId, employeeIds }).then(({ status, errormsg }) => {
if (status) {
message.success(getLabel(541531, "添加成功!"));
this.queryPCList();
} else {
message.error(errormsg || getLabel(111, "添加失败!"));
}
});
};
render() {
const { calculateStore: { PCSearchForm } } = this.props;
const {
selectedKey, showSearchAd, searchConditions, pageInfo, loading, selectedRowKeys,
columns, dataSource
} = this.state;
const tabDatas = [
{
title: <React.Fragment>
<span>{getLabel(542307, "核算人员范围")}</span>
<WeaHelpfulTip
width={200} placement="topLeft"
title={getLabel(543551, "核算完若薪资档案中个税扣缴义务人发生调整,需先刷新【核算人员范围】再到【薪资核算】中重新核算")}
style={{ marginLeft: 8 }}
/>
</React.Fragment>, viewcondition: "range"
},
{
title: <React.Fragment>
<span>{getLabel(542308, "环比上月减少人员")}</span>
<WeaHelpfulTip
width={200} placement="topLeft"
title={getLabel(543552, "提示:环比上期当前选择的账套归档的各个税扣缴义务人下减少的人员")}
style={{ marginLeft: 8 }}
/>
</React.Fragment>, viewcondition: "sub"
},
{
title: <React.Fragment>
<span>{getLabel(542308, "环比上月增加人员")}</span>
<WeaHelpfulTip
width={200} placement="topLeft"
title={getLabel(543553, "提示:环比上期当前选择的账套归档的各个税扣缴义务人下增加的人员")}
style={{ marginLeft: 8 }}
/>
</React.Fragment>, viewcondition: "add"
}
];
const pagination = {
...pageInfo,
showTotal: total => `${getLabel(18609, "共")} ${total} ${getLabel(18256, "条")}`,
showQuickJumper: true,
showSizeChanger: true,
pageSizeOptions: ["10", "20", "50", "100"],
onShowSizeChange: (current, pageSize) => {
this.setState({ pageInfo: { ...pageInfo, current, pageSize } }, () => this.queryPCList());
},
onChange: current => {
this.setState({ pageInfo: { ...pageInfo, current } }, () => this.queryPCList());
}
};
const rowSelection = {
columnWidth: 80,
selectedRowKeys,
onChange: selectedRowKeys => this.setState({ selectedRowKeys })
};
return (
<div className="person-confirm-layout">
<BaseInfo {...this.props}/>
<WeaTab
datas={tabDatas} keyParam="viewcondition" selectedKey={selectedKey}
onChange={v => this.setState({ selectedKey: v }, () => this.queryPCList())}
buttons={this.renderTabBtns()} searchType={["base", "advanced"]} advanceHeight={220}
showSearchAd={showSearchAd} setShowSearchAd={bool => this.setState({ showSearchAd: bool })}
searchsAd={getSearchs(PCSearchForm, searchConditions, 2, false)}
onSearchChange={(v) => PCSearchForm.updateFields({ employeeName: v })}
searchsBaseValue={PCSearchForm.getFormParams().employeeName}
onSearch={this.queryPCList} onAdSearch={this.queryPCList}
onAdReset={() => PCSearchForm.resetForm()} autoCalculateWidth
/>
<WeaTable
dataSource={dataSource} loading={loading} rowSelection={rowSelection} pagination={pagination}
scroll={{ y: `calc(100vh - 365px)` }} rowKey="id"
columns={[..._.map(columns, item => {
let width = "";
const { dataIndex } = item;
switch (dataIndex) {
case "taxAgentName":
case "departmentName":
width = "15%";
break;
default:
width = "10%";
break;
}
return { ...item, width };
}),
{
dataIndex: "operate",
title: getLabel(30585, "操作"),
width: 120,
render: (_, record) => (
<a href="javascript:void(0);"
onClick={() => this.handleDeletePCitem([record.id])}>{getLabel(535052, "删除")}</a>
)
}
]}
/>
</div>
);
}
}
export default Index;

View File

@ -0,0 +1,47 @@
.person-confirm-layout {
.wea-tab .wea-tab-right, .wea-input-focus {
background: transparent;
}
.wea-new-table {
background: #fff;
}
}
.docalc-baseinfo-layout {
padding: 0;
.wea-title {
border-bottom: none;
padding-left: 0;
}
.wea-content.pt15 {
padding-top: 0;
}
.docalc-baseinfo {
background: #fff;
border: 1px solid #e5e5e5;
border-right: none;
.ant-col-24 {
border-top: 1px solid #e5e5e5;
}
.label {
color: #666;
}
.value {
color: #111;
}
& > div {
border-right: 1px solid #e5e5e5;
line-height: 30px;
padding: 5px 16px;
}
}
}

View File

@ -0,0 +1,59 @@
/*
* Author: 黎永顺
* name: 薪资基本信息
* Description:
* Date: 2023/9/25
*/
import React, { Component } from "react";
import { WeaHelpfulTip, WeaLocaleProvider, WeaSearchGroup } from "ecCom";
import cs from "classnames";
import { Col, Row } from "antd";
import "./index.less";
const getLabel = WeaLocaleProvider.getLabel;
class EditSalaryBaseInfo extends Component {
render() {
const { baseInfo } = this.props;
return (
<WeaSearchGroup
needTigger showGroup className="esf-base-info-form"
title={
<div>
<span>{getLabel(82743, "基础信息")}</span>
<WeaHelpfulTip
width={200} placement="topLeft"
title={getLabel(111, "提示:基本信息根据账套设置显示")}
style={{ marginLeft: 10 }}
/>
</div>
}
>
<Row type="flex" className="esf-form-content">
{
_.map(baseInfo, (item, index) => {
const { fieldName, fieldValue } = item;
return (
<Col span={(index === baseInfo.length - 1 && (index + 1) % 2 === 1) ? 24 : 12}>
<Row className={cs("esf-form-item", {
"esf-form-odd-item": index % 2 === 0,
"esf-form-last-item": (index === baseInfo.length - 1 && (index + 1) % 2 === 1)
})}>
<Col span={(index === baseInfo.length - 1 && (index + 1) % 2 === 1) ? 3 : 6}>
<span className="label">{fieldName}</span>
</Col>
<Col span={(index === baseInfo.length - 1 && (index + 1) % 2 === 1) ? 21 : 18}>
<span className="value">{fieldValue}</span>
</Col>
</Row>
</Col>
);
})
}
</Row>
</WeaSearchGroup>
);
}
}
export default EditSalaryBaseInfo;

View File

@ -0,0 +1,145 @@
export const editCalcSearchConditions = [
{
items: [
{
colSpan: 2,
conditionType: "INPUT",
domkey: ["employeeName"],
fieldcol: 12,
label: "姓名",
lanId: 25034,
labelcol: 6,
value: "",
viewAttr: 2
},
{
colSpan: 2,
conditionType: "INPUT",
domkey: ["workcode"],
fieldcol: 12,
label: "工号",
lanId: 1933,
labelcol: 6,
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: 12,
label: "分部",
lanId: 33553,
labelcol: 6,
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
},
colSpan: 2,
conditionType: "BROWSER",
domkey: ["departmentIds"],
fieldcol: 12,
label: "部门",
lanId: 27511,
labelcol: 6,
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
},
colSpan: 2,
conditionType: "BROWSER",
domkey: ["positionIds"],
fieldcol: 12,
label: "岗位",
lanId: 6086,
labelcol: 6,
viewAttr: 2
},
{
colSpan: 2,
conditionType: "SELECT",
domkey: ["statuses"],
fieldcol: 12,
multiple: true,
label: "状态",
lanId: 535101,
labelcol: 6,
options: [],
viewAttr: 2
},
{
colSpan: 2,
conditionType: "CHECKBOX",
domkey: ["consolidatedTaxation"],
fieldcol: 12,
isQuickSearch: false,
label: "合并计税",
labelcol: 6,
viewAttr: 2
}
],
defaultshow: true,
title: "常用条件"
}
];

View File

@ -0,0 +1,206 @@
/*
* Author: 黎永顺
* name: 薪资核算-高级搜索面板
* Description:
* Date: 2023/9/14
*/
import React, { Component } from "react";
import { WeaFormItem, WeaInput, WeaLocaleProvider, WeaSearchGroup, WeaSelect, WeaTools } from "ecCom";
import { Button, Col, Row } from "antd";
import { inject, observer } from "mobx-react";
import uuidV4 from "uuid/v4";
import { editCalcSearchConditions } from "./condition";
import { getExportField } from "../../../../../apis/calculate";
import { commonEnumList } from "../../../../../apis/ruleconfig";
import { getSearchs } from "../../../../../util";
const getKey = WeaTools.getKey;
const getLabel = WeaLocaleProvider.getLabel;
@inject("calculateStore")
@observer
class EditCalcAdvanceSearchPannel extends Component {
constructor(props) {
super(props);
this.state = {
searchConditions: [], salaryItems: [],
customSearchConditions: [], filterEnum: []
};
}
componentDidMount() {
this.getExportField();
this.getFilterEnumList();
this.setState({
searchConditions: _.map(editCalcSearchConditions, item => {
return {
...item,
items: _.map(item.items, o => {
if (getKey(o) === "statuses") {
return {
...o,
options: [
{ key: "0", showname: getLabel(18883, "试用") }, { key: "1", showname: getLabel(15711, "正式") },
{ key: "2", showname: getLabel(480, "临时") }, { key: "3", showname: getLabel(15844, "试用延期") },
{ key: "4", showname: getLabel(542707, "解雇") }, { key: "5", showname: getLabel(6091, "离职") },
{ key: "6", showname: getLabel(6092, "退休") }
]
};
}
return { ...o };
}),
title: getLabel(32905, "常用条件")
};
})
}, () => {
const { calculateStore: { ECSearchForm } } = this.props;
ECSearchForm.initFormFields(this.state.searchConditions);
});
}
getFilterEnumList = () => {
commonEnumList({ enumClass: "com.engine.salary.enums.common.FilterEnum" })
.then(({ status, data }) => {
if (status) {
this.setState({
filterEnum: _.map(data, item => ({
key: item.value,
showname: item.defaultLabel
}))
});
}
});
};
getExportField = () => {
getExportField({ salaryAcctRecordId: this.props.salaryAcctRecordId })
.then(({ status, data }) => {
if (status) {
const { itemsByGroup } = data;
this.setState({
salaryItems: _.map(itemsByGroup, item => ({
key: item.salarySobItemGroupId.toString(),
label: item.salarySobItemGroupName,
options: _.map(item.salaryItems, o => ({
key: o.salaryItemId.toString(), showname: o.salaryItemName
}))
}))
});
}
});
};
handleAddCustomSearchForm = () => {
const { calculateStore: { setOtherConditions } } = this.props;
const { customSearchConditions, salaryItems, filterEnum } = this.state;
const uuid = uuidV4();
this.setState({
customSearchConditions: [
...customSearchConditions,
{
com: CustomFormFields({
uuid, salaryItems, filterEnum, onDelete: this.handleDelete, onChange: this.handleChange
}),
uuid, itemId: "", filter: "", params: ""
}
]
}, () => {
setOtherConditions(_.map(this.state.customSearchConditions, o => ({
itemId: o.itemId, filter: o.filter, params: o.params
})));
});
};
handleChange = (uuid, params) => {
const { calculateStore: { setOtherConditions } } = this.props;
const { customSearchConditions } = this.state;
this.setState({
customSearchConditions: _.map(customSearchConditions, o => {
if (o.uuid === uuid) {
return { ...o, ...params };
}
return { ...o };
})
}, () => {
setOtherConditions(_.map(this.state.customSearchConditions, o => ({
itemId: o.itemId, filter: o.filter, params: o.params
})));
});
};
handleDelete = (uuid) => {
const { calculateStore: { setOtherConditions } } = this.props;
const { customSearchConditions } = this.state;
this.setState({
customSearchConditions: _.filter(customSearchConditions, o => o.uuid !== uuid)
}, () => {
setOtherConditions(_.map(this.state.customSearchConditions, o => ({
itemId: o.itemId, filter: o.filter, params: o.params
})));
});
};
render() {
const { searchConditions, customSearchConditions } = this.state;
const { calculateStore: { ECSearchForm, setOtherConditions } } = this.props;
return (
<React.Fragment>
<div className="wea-advanced-searchsAd">
{getSearchs(ECSearchForm, searchConditions, 2, false)}
<WeaSearchGroup needTigger showGroup title={getLabel(32843, "其他条件")} items={customSearchConditions}
col={2}/>
<div className="custom-advance-largeSpacing">
<Button className="link" icon="plus"
onClick={this.handleAddCustomSearchForm}>{getLabel(111, "添加搜索条件")}</Button>
</div>
<div className="searchAdvanced-commonSelect">
{/*<Button type="ghost">{getLabel(111, "保存常用筛选")}</Button>*/}
</div>
</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={() => {
this.setState({
customSearchConditions: []
}, () => {
ECSearchForm.resetForm();
setOtherConditions([]);
});
}}>{getLabel(2022, "重置")}</Button></span>
<span style={{ marginLeft: 15 }}><Button type="ghost"
onClick={this.props.onToggleSwitch}>{getLabel(31129, "取消")}</Button></span>
</div>
</div>
</React.Fragment>
);
}
}
export default EditCalcAdvanceSearchPannel;
const CustomFormFields = (props) => {
const { uuid, onDelete, salaryItems, filterEnum, onChange } = props;
return <WeaFormItem labelCol={{ span: 0 }} wrapperCol={{ span: 18 }}>
<Row>
<Col span={6} style={{ paddingRight: 10 }}>
<WeaSelect
options={salaryItems} detailtype={5} showSearch optionFilterProp="children"
onChange={v => onChange(uuid, { itemId: v })}
/>
</Col>
<Col span={18}>
<Row>
<Col span={12} style={{ paddingRight: 10 }}>
<WeaSelect options={filterEnum} onChange={v => onChange(uuid, { filter: v })}/>
</Col>
<Col span={12} style={{ position: "relative" }}>
<WeaInput onChange={v => onChange(uuid, { params: v })}/>
<Button
type="ghost" icon="cross" className="formItem-delete" shape="circle"
onClick={() => onDelete(uuid)}
/>
</Col>
</Row>
</Col>
</Row>
</WeaFormItem>;
};

View File

@ -0,0 +1,213 @@
/*
* Author: 黎永顺
* name: 薪资核算-列表数据
* Description:
* Date: 2023/9/14
*/
import React, { Component } from "react";
import { WeaLocaleProvider } from "ecCom";
import { message, Modal, Spin } from "antd";
import { inject, observer } from "mobx-react";
import { acctResultList, updateLockStatus } from "../../../../../apis/calculate";
import ProgressModal from "../../../../../components/progressModal";
import EditSalaryCalcSlide from "./editSalaryCalcSlide";
const getLabel = WeaLocaleProvider.getLabel;
@inject("calculateStore")
@observer
class EditCalcTable extends Component {
constructor(props) {
super(props);
this.state = {
loading: false, pageInfo: { current: 1, pageSize: 10, total: 0 },
selectedRowKeys: [], progressVisible: false, progress: 0,
salaryCalcSlide: { visible: false, id: "" }
};
this.timerLock = null;
}
componentDidMount() {
window.addEventListener("message", this.handleReceive, false);
}
handleReceive = async ({ data }) => {
const { type, payload: { id, params } = {} } = data;
if (type === "init") {
this.queryCalcResultList();
} else if (type === "turn") {
switch (id) {
case "PAGEINFO":
const { size: pageSize, pageNum: current } = params;
this.setState({ pageInfo: { ...this.state.pageInfo, current, pageSize } }, () => this.queryCalcResultList());
break;
case "CHECKBOX":
const { selectedRowKeys } = params;
this.setState({ selectedRowKeys });
break;
case "FORMULA":
const { dataIndex } = params;
this.props.onShowFormulaTd(dataIndex);
break;
case "LOCKING":
const { salaryItemId, lockType: lockStatus } = params;
this.updateLockStatus({ lockStatus, salaryItemId });
break;
case "EDIT":
const { id: salaryCalcId } = params;
this.setState({
salaryCalcSlide: { visible: true, id: salaryCalcId }
});
break;
default:
break;
}
}
};
updateLockStatus = (payload) => {
const { lockStatus } = payload;
Modal.confirm({
title: getLabel(131329, "信息确认"),
content: <div>
<div style={{ textAlign: "center" }}>
{lockStatus === "LOCK" ? getLabel(543554, "确定要批量锁定项目值吗?") : getLabel(543556, "确定要批量解锁项目值吗?")}
</div>
<div style={{ textAlign: "center" }}>
{lockStatus === "LOCK" ? getLabel(543555, "确定后,则项目输入值锁定,项目公式失效;点击核算将按锁定的输入值重新核算!") :
getLabel(543557, "确定后,则项目公式生效,页面仍显示手动修改的项目值;点击核算将按公式重新核算,不再显示解锁标识!")}
</div>
</div>,
onOk: () => {
this.setState({
progressVisible: true
}, () => {
this.timerLock = setInterval(() => {
if (this.state.progress !== 100) {
this.setState({
progress: this.state.progress + 1
});
} else {
clearInterval(this.timerLock);
this.setState({
progressVisible: false,
progress: 0
});
}
}, 500);
});
const { routeParams: { salaryAcctRecordId } } = this.props;
updateLockStatus({ ...payload, salaryAcctRecordId }).then(({ status, errormsg }) => {
if (status) {
clearInterval(this.timerLock);
this.setState({
progressVisible: false,
progress: 0
}, () => this.queryCalcResultList());
} else {
message.error(errormsg);
}
});
}
});
};
componentWillUnmount() {
window.removeEventListener("message", this.handleReceive, false);
}
postMessageToChild = (payload = {}) => {
const i18n = {
"操作": getLabel(30585, "操作"), "编辑": getLabel(501169, "编辑"),
"点击锁定所有解锁的项目值": getLabel(543649, "点击锁定所有解锁的项目值"),
"点击解锁所有锁定的项目值": getLabel(543648, "点击解锁所有锁定的项目值"),
"锁定的项目值": getLabel(543647, "锁定的项目值"),
"当前状态锁定,点击解锁": getLabel(111, "当前状态锁定,点击解锁"),
"当前状态未锁定,点击锁定": getLabel(111, "当前状态未锁定,点击锁定"),
"共": getLabel(18609, "共"), "条": getLabel(18256, "条"),
"总计": getLabel(523, "总计"), "批量解锁": getLabel(111, "批量解锁"),
"批量锁定": getLabel(111, "批量锁定")
};
const childFrameObj = document.getElementById("atdTable");
childFrameObj.contentWindow.postMessage(JSON.stringify({ ...payload, i18n }), "*");
};
queryCalcResultList = () => {
const { pageInfo } = this.state;
const { calculateStore: { ECSearchForm, otherConditions }, routeParams: { salaryAcctRecordId } } = this.props;
const { subcompanyIds, departmentIds, positionIds, statuses, ...extra } = ECSearchForm.getFormParams();
const payload = {
salaryAcctRecordId, ...pageInfo, ...extra, otherConditions,
departmentIds: !_.isEmpty(departmentIds) ? departmentIds.split(",") : [],
positionIds: !_.isEmpty(positionIds) ? positionIds.split(",") : [],
subcompanyIds: !_.isEmpty(subcompanyIds) ? subcompanyIds.split(",") : [],
statuses: !_.isEmpty(statuses) ? statuses.split(",") : []
};
this.setState({ loading: true });
acctResultList(payload).then(({ status, data }) => {
this.setState({ loading: false });
if (status) {
const { columns, pageInfo: list } = data;
const { list: dataSource, pageNum: current, pageSize, total } = list;
this.setState({ pageInfo: { ...pageInfo, current, pageSize, total } }, () => {
const { pageInfo, selectedRowKeys } = this.state;
const sumRowlistUrl = this.props.showTotalCell ? "/api/bs/hrmsalary/salaryacct/acctresult/sum" : "";
this.postMessageToChild({
dataSource, pageInfo, selectedRowKeys, showTotalCell: this.props.showTotalCell, sumRowlistUrl, payload,
columns: _.map(traverse(columns), (it, idx) => ({ ...it, fixed: idx < 2 ? "left" : false }))
});
});
}
}).catch(() => this.setState({ loading: false }));
};
render() {
const { loading, progressVisible, progress, salaryCalcSlide } = this.state;
return (
<div className="editCalcTable-layout">
<Spin spinning={loading}>
<iframe
style={{ border: 0, width: "100%", height: "100%" }}
// src="http://localhost:7607/#/calcTable"
src="/spa/hrmSalary/hrmSalaryCalculateDetail/index.html#/calcTable"
id="atdTable"
/>
<EditSalaryCalcSlide {...salaryCalcSlide}
onClose={(isFresh) => this.setState({
salaryCalcSlide: {
visible: false,
id: ""
}
}, () => isFresh === "true" && this.queryCalcResultList())}/>
{
progressVisible &&
<ProgressModal
title={getLabel(543558, "正在加锁/解锁请稍后")} visible={progressVisible} progress={progress}
onCancel={() => {
this.setState({ progressVisible: false, progress: 0 }, () => {
clearInterval(this.timerLock);
});
}}
/>
}
</Spin>
</div>
);
}
}
export default EditCalcTable;
const traverse = (arr) => {
return _.map(arr, item => {
if (!_.isEmpty(item.children)) {
return {
title: item.text, width: item.width + "px", ellipsis: true,
dataIndex: item.column, children: traverse(item.children)
};
} else {
return {
title: item.text, width: item.width + "px",
dataIndex: item.column, ellipsis: true, lockStatus: item.lockStatus
};
}
});
};

View File

@ -0,0 +1,160 @@
/*
* Author: 黎永顺
* name: 编辑弹框
* Description:
* Date: 2023/9/25
*/
import React, { Component } from "react";
import { Button, message } from "antd";
import { WeaLocaleProvider, WeaSlideModal, WeaTab } from "ecCom";
import EditSalaryBaseInfo from "./baseInfo";
import PayrollItemsTable from "../../../../calculateDetail/payrollItemsTable";
import IssuedAndReissueTable from "../../../../calculateDetail/issuedAndReissueTable";
import { acctresultDetail, saveAcctResult } from "../../../../../apis/calculate";
import { toDecimal_n } from "../../../../../util";
import "./index.less";
const getLabel = WeaLocaleProvider.getLabel;
class EditSalaryCalcSlide extends Component {
constructor(props) {
super(props);
this.state = {
baseInfo: [], selectedKey: "0", loading: false,
issuedAndReissueItems: [], //已发补发薪资项目
itemsByGroup: [] //正常发放薪资项目所得薪资项目
};
}
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" });
}
acctresultDetail = (id) => {
acctresultDetail({ id }).then(({ status, data }) => {
if (status) {
const { employeeInfos, issuedAndReissueItems, itemsByGroup } = data;
this.setState({
baseInfo: employeeInfos, issuedAndReissueItems, itemsByGroup
});
}
});
};
renderTitle = () => {
const { loading } = this.state;
return <div className="titleDialog">
<div className="titleCol titleLeftBox">
<div className="titleIcon"><i className="icon-coms-fa"/></div>
<div className="title">{getLabel(543559, "编辑薪资")}</div>
</div>
<div className="titleCol titleRightBox">
<Button type="primary" onClick={this.save} loading={loading}>{getLabel(111, "保存并核算")}</Button>
</div>
</div>;
};
handleItemValueChange = (field, value, isInput, groupId) => {
const { issuedAndReissueItems, itemsByGroup } = this.state;
if (isInput === "itemsByGroup") {
this.setState({
itemsByGroup: itemsByGroup.map(item => {
if (item.salarySobItemGroupId === groupId) {
return {
...item,
salaryItems: _.map(item.salaryItems, it => {
if (it.salaryItemId === field) {
return { ...it, resultValue: value };
}
return { ...it };
})
};
}
return { ...item };
})
});
} else if (isInput === "issuedAndReissueItems") {
this.setState({
issuedAndReissueItems: issuedAndReissueItems.map(item => {
item = { ...item };
if (item.salaryItemName === field) {
item.resultValue = value;
}
return item;
})
});
}
};
save = () => {
const { id: salaryAcctEmpId } = this.props;
const { issuedAndReissueItems, itemsByGroup } = this.state;
const payload = {
salaryAcctEmpId,
items: [
..._.reduce(itemsByGroup, (pre, cur) => {
return [
...pre,
..._.map(cur.salaryItems, it => {
return {
salaryItemId: it.salaryItemId,
resultValue: (it.dataType === "number" && !!it.resultValue) ? toDecimal_n(it.resultValue, it.pattern || 2) : it.resultValue
};
})
];
}, []),
...issuedAndReissueItems.map(item => ({
salaryItemId: item.salaryItemId,
resultValue: (item.dataType === "number" && !!item.resultValue) ? toDecimal_n(item.resultValue, item.pattern || 2) : item.resultValue
}))
]
};
this.setState({ loading: true });
saveAcctResult(payload).then(({ status, errormsg }) => {
this.setState({ loading: false });
if (status) {
message.success(getLabel(30700, "操作成功!"));
this.props.onClose("true");
} else {
message.error(errormsg);
}
}).catch(() => this.setState({ loading: false }));
};
render() {
const { baseInfo, selectedKey, itemsByGroup, issuedAndReissueItems } = this.state;
const topTab = [
{ title: getLabel(542704, "正常工资薪金所得"), viewcondition: "0" },
{ title: getLabel(542651, "已发补发"), viewcondition: "1" }
];
return (
<React.Fragment>
<WeaSlideModal
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">
<EditSalaryBaseInfo baseInfo={baseInfo}/>
<WeaTab keyParam="viewcondition" className="calc-esf-tab"
selectedKey={selectedKey} onChange={v => this.setState({ selectedKey: v })}
datas={!_.isEmpty(issuedAndReissueItems) ? topTab : topTab.slice(0, 1)}
/>
{
selectedKey === "0" && _.map(itemsByGroup, item => {
return <PayrollItemsTable {...item} onChangeIssueReissueValue={this.handleItemValueChange}/>;
})
}
{
selectedKey === "1" &&
<IssuedAndReissueTable
dataSource={issuedAndReissueItems}
onChangeIssueReissueValue={this.handleItemValueChange}
/>
}
</div>}
/>
</React.Fragment>
);
}
}
export default EditSalaryCalcSlide;

View File

@ -0,0 +1,97 @@
/*
* Author: 黎永顺
* name: 薪资核算
* Description:
* Date: 2023/9/14
*/
import React, { Component } from "react";
import { WeaHelpfulTip, WeaLocaleProvider } from "ecCom";
import { Alert } from "antd";
import { getColumnDesc, getSalarySobCycle } from "../../../../../apis/calculate";
import { sysConfCodeRule } from "../../../../../apis/ruleconfig";
import EditCalcAdvanceSearchPannel from "./editCalcAdvanceSearchPannel";
import EditCalcTable from "./editCalcTable";
import SalaryMonthTip from "../salaryMonthTip";
import cs from "classnames";
import "./index.less";
const getLabel = WeaLocaleProvider.getLabel;
class Index extends Component {
constructor(props) {
super(props);
this.state = {
salarySobCycle: {}, showSearchAd: false,
columnDesc: {}, formulaTd: "", showTotalCell: false
};
}
componentDidMount() {
const promise = this.init();
}
openAdvanceSearch = () => this.setState({ showSearchAd: !this.state.showSearchAd });
onAdSearch = (bool = true) => {
this.calcTableRef.wrappedInstance.queryCalcResultList();
bool && this.openAdvanceSearch();
};
init = async () => {
const { routeParams: { salaryAcctRecordId } } = this.props;
const [salarySobCycle, columnDesc, confCode] = await Promise.all([
getSalarySobCycle({ salaryAcctRecordId }), getColumnDesc({ salaryAcctRecordId }),
sysConfCodeRule({ code: "OPEN_ACCT_RESULT_SUM" })
]);
if (salarySobCycle.status && columnDesc.status && confCode.status) {
this.setState({
salarySobCycle: salarySobCycle.data,
columnDesc: columnDesc.data, showTotalCell: confCode.data === "1"
});
}
};
handleShowFormulaTa = (dataIndex) => this.setState({ formulaTd: dataIndex });
render() {
const { salarySobCycle, showSearchAd, formulaTd, columnDesc, showTotalCell } = this.state;
const { accountExceptInfo, routeParams: { salaryAcctRecordId } } = this.props;
const formulaObj = _.get(columnDesc, [formulaTd]) || {};
return (
<div className="salary-edit-calc-content">
{
accountExceptInfo &&
<Alert message="" description={accountExceptInfo} type="error" closable/>
}
<div className="salary-flex-between weapp-salary-tb-tip">
<div>
<span>{getLabel(542604, "薪资所属月")}</span>
<span>{salarySobCycle.salaryMonth}</span>
<WeaHelpfulTip
width={200} placement="topLeft"
title={<SalaryMonthTip {...salarySobCycle}/>}
style={{ marginLeft: 10 }}
/>
</div>
<div></div>
</div>
<div className="salary-flex-between formula-detail-area">
<div className="formula-detail">
<span>{getLabel(18125, "公式")}=</span>
<span>{formulaObj.formulaContent}</span>
</div>
<div></div>
</div>
<div className={cs("searchAdvanced-condition-container", { "searchAdvanced-condition-hide": !showSearchAd })}>
<EditCalcAdvanceSearchPannel
salaryAcctRecordId={salaryAcctRecordId}
onToggleSwitch={this.openAdvanceSearch}
onAdSearch={this.onAdSearch}
/>
</div>
<EditCalcTable ref={dom => this.calcTableRef = dom}
{...this.props} showTotalCell={showTotalCell}
onShowFormulaTd={this.handleShowFormulaTa}/>
</div>
);
}
}
export default Index;

View File

@ -0,0 +1,183 @@
.salary-edit-calc-content {
height: 100%;
display: flex;
flex-direction: column;
.salary-flex-between {
display: flex;
justify-content: space-between;
align-items: center;
}
.weapp-salary-tb-tip {
padding-top: 0;
padding-bottom: 0;
height: 46px;
margin-bottom: 0;
}
.formula-detail-area {
background: #fff;
height: 46px;
.formula-detail {
padding-left: 8px;
flex-grow: 1;
flex-shrink: 1;
min-height: 46px;
display: flex;
align-items: center;
width: 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: 320px;
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
}
}
}
}
.editCalcTable-layout {
flex: 1;
.ant-spin-nested-loading, .ant-spin-container {
height: 100%;
}
}
}
.salary-calculate-esf-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;
}
}
.wea-slide-modal-title {
border-bottom: 1px solid #e5e5e5 !important;
}
.wea-slide-modal-content {
height: 100%;
.salary-calculate-esf-area {
background: #f6f6f6;
height: 100%;
overflow-y: auto;
padding: 16px;
.esf-base-info-form, .wea-title, .wea-content {
padding: 0;
}
.esf-form-content {
background: #fff;
border: 1px solid #e5e5e5;
border-top: none;
border-bottom: none;
.esf-form-item {
border-bottom: 1px solid #e5e5e5;
}
.esf-form-last-item {
border-right: none !important;
}
.esf-form-odd-item {
border-right: 1px solid #e5e5e5;
}
.label {
color: #666;
}
.label, .value {
display: inline-block;
line-height: 24px;
padding: 8px 16px;
}
}
.wea-new-table {
background: #FFF;
}
.wea-search-group {
padding: 0;
}
}
}
}

View File

@ -0,0 +1,166 @@
/*
* Author: 黎永顺
* name: 薪资核算-导入
* Description:
* Date: 2023/9/18
*/
import React, { Component } from "react";
import { WeaCheckbox, WeaLocaleProvider } from "ecCom";
import { Badge, Button, message } from "antd";
import ImportDialog from "../../../../../components/importDialog";
import { cacheImportField, getImportField, importAcctResult } from "../../../../../apis/calculate";
import AddHeaderFieldsModal from "../../../../calculateDetail/acctResult/importModal/addHeaderFieldsModal";
import { convertToUrlString, getURLParameters } from "../../../../../util/url";
const getLabel = WeaLocaleProvider.getLabel;
class Index extends Component {
constructor(props) {
super(props);
this.state = {
salaryItemIds: "", //选择的导入表单项
exportTempUrl: "", //导出模板url
headerFieldsDialog: { visible: false, itemsByGroup: [], selectItems: "" },
importDialog: {
visible: false, title: "", nextloading: false,
link: null, importResult: {}, imageId: "",
previewUrl: "/api/bs/hrmsalary/salaryacct/acctresult/preview",
extraPreview: { salaryAcctRecordId: "", salaryItemIds: "" }
}
};
}
async componentWillReceiveProps(nextProps, nextContext) {
if (nextProps.visible !== this.props.visible) {
if (nextProps.salaryAcctRecordId && nextProps.visible) {
const { data } = await getImportField({ salaryAcctRecordId: nextProps.salaryAcctRecordId });
const { checkItems, itemsByGroup } = data;
const payload = {
exportData: false, salaryAcctRecordId: nextProps.salaryAcctRecordId,
salaryItemIds: checkItems.join(",")
};
this.setState({
exportTempUrl: `/api/bs/hrmsalary/salaryacct/acctresult/importtemplate/export?${convertToUrlString(payload)}`,
importDialog: {
...this.state.importDialog,
extraPreview: { salaryAcctRecordId: nextProps.salaryAcctRecordId, salaryItemIds: checkItems.join(",") }
},
headerFieldsDialog: {
...this.state.headerFieldsDialog,
selectItems: checkItems.join(","),
itemsByGroup: _.map(itemsByGroup, item => {
return {
...item,
salaryItems: _.map(item.salaryItems, it => ({
...it,
checked: false
}))
};
})
}
});
}
this.setState({
importDialog: {
...this.state.importDialog, link: this.handleExportTemp,
visible: nextProps.visible, title: nextProps.title
}
});
}
}
handleImport = (payload) => {
const { headerFieldsDialog: { selectItems: salaryItemIds }, importDialog } = this.state;
const { salaryAcctRecordId } = this.props;
this.setState({ importDialog: { ...importDialog, nextloading: true } });
importAcctResult({ ...payload, salaryItemIds, salaryAcctRecordId })
.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 } }));
};
handleExportTemp = () => {
const { headerFieldsDialog: { selectItems }, exportTempUrl } = this.state;
if (!selectItems) {
message.error(getLabel(111, "请选择表头字段"));
} else {
window.open(exportTempUrl, "_blank");
}
};
handleSelectedField = () => {
this.setState({
headerFieldsDialog: {
...this.state.headerFieldsDialog, visible: true
}
});
};
/*
* Author: 黎永顺
* Description:表单选项
* Params:
* Date: 2023/9/18
*/
renderFormComponent = () => {
const { selectItems } = this.state.headerFieldsDialog;
return <div style={{ padding: "8px 16px", border: "1px solid #e5e5e5", margin: "4px 0" }}>
<Badge
count={!_.isEmpty(selectItems) ? selectItems.split(",").length : 0}>
<Button onClick={this.handleSelectedField}>{getLabel(111, "请选择表头字段")}</Button>
</Badge>
</div>;
};
render() {
const { importDialog, headerFieldsDialog, exportTempUrl } = this.state;
const { salaryAcctRecordId } = this.props;
return (
<React.Fragment>
<ImportDialog
{...importDialog} onCancel={this.props.onCancel}
importParams={this.renderFormComponent()}
onResetImportResult={() => this.setState(({
importDialog: { ...importDialog, importResult: {}, imageId: "" }
}))}
exportDataDom={
<WeaCheckbox
content={getLabel(543208, "导出现有数据")}
value={getURLParameters(exportTempUrl).exportData === "true" ? "1" : "0"}
helpfulTip={getLabel(111, "提示:建议先导出现有最新数据,修改后再导入")}
onChange={val => {
const payload = {
exportData: val === "1", salaryAcctRecordId,
salaryItemIds: headerFieldsDialog.selectItems
};
this.setState(({
exportTempUrl: `/api/bs/hrmsalary/salaryacct/acctresult/importtemplate/export?${convertToUrlString(payload)}`
}));
}}
/>
}
nextCallback={imageId => this.handleImport({ imageId })}
/>
<AddHeaderFieldsModal
{...headerFieldsDialog}
onCancel={() => this.setState({
headerFieldsDialog: { ...headerFieldsDialog, visible: false }
})}
onAdd={selectItems => this.setState({
headerFieldsDialog: {
...headerFieldsDialog,
visible: false, selectItems: selectItems.join(",")
}
}, () => {
const { selectItems: salaryItems } = this.state.headerFieldsDialog;
cacheImportField({ salaryItems: salaryItems ? salaryItems.split(",") : [] }).then();
})}
/>
</React.Fragment>
);
}
}
export default Index;

View File

@ -0,0 +1,42 @@
/*
* Author: 黎永顺
* name: 薪资所属月提示语
* Description:
* Date: 2023/9/13
*/
import React, { Component } from "react";
import { WeaLocaleProvider } from "ecCom";
import "./index.less";
const getLabel = WeaLocaleProvider.getLabel;
class Index extends Component {
render() {
const { attendCycle, salaryCycle, salaryMonth, socialSecurityCycle } = this.props;
const { fromDate: attendFromDate, endDate: attendEndDate } = attendCycle,
{ fromDate: salaryFromDate, endDate: salaryEndDate } = salaryCycle;
return (
<div className="salary-month-tip">
<div className="line">
<div className="lable">{getLabel(543375, "薪资周期")}</div>
<div className="value">{`${salaryFromDate}${getLabel(15322, "至")}${salaryEndDate}`}</div>
</div>
<div className="line">
<div className="lable">{getLabel(542240, "税款所属期")}</div>
<div className="value">{salaryMonth}</div>
</div>
<div className="line">
<div className="lable">{getLabel(543475, "考勤取值周期")}</div>
<div className="value">{`${attendFromDate}${getLabel(15322, "至")}${attendEndDate}`}</div>
</div>
<div className="line">
<div className="lable">{getLabel(543466, "福利台账月份")}</div>
<div
className="value">{`${getLabel(19422, "引用")}${socialSecurityCycle}${getLabel(543476, "的福利台账数据")}`}</div>
</div>
</div>
);
}
}
export default Index;

View File

@ -0,0 +1,11 @@
.salary-month-tip {
.line {
.label {
color: #666;
}
.value {
color: #111;
}
}
}

View File

@ -0,0 +1,232 @@
/*
* Author: 黎永顺
* name: 薪资核算详情
* Description:
* Date: 2023/9/13
*/
import React, { Component } from "react";
import { WeaLocaleProvider, WeaReqTop } from "ecCom";
import { Button, Dropdown, Menu, message, Modal } from "antd";
import { inject, observer } from "mobx-react";
import Layout from "./layout";
import { acctresultAccounting, getCalculateProgress, getExportField } from "../../../apis/calculate";
import AdvanceInputBtn from "./components/advanceInputBtn";
import SalaryCalcPersonConfirm from "./components/salaryCalcPersonConfirm";
import SalaryEditCalc from "./components/salaryEditCalc";
import ProgressModal from "../../../components/progressModal";
import CustomCalcExportDialog from "./components/customCalcExportDialog";
import SalaryEditCalcImport from "./components/salaryEditCalcImport";
import { convertToUrlString } from "../../../util/url";
import "./index.less";
const getLabel = WeaLocaleProvider.getLabel;
@inject("calculateStore")
@observer
class Index extends Component {
constructor(props) {
super(props);
this.state = {
selectedKey: "person", progressVisible: false, progress: 0,
customExpDialog: { visible: false, salaryAcctRecordId: "", checkItems: [], itemsByGroup: [] },
salaryImpDialog: { visible: false, title: "", salaryAcctRecordId: "" },
accountExceptInfo: "" //核算报错信息,
};
this.calc = null;
this.timer = null;
}
handleMenuClick = ({ key }) => {
switch (key) {
case "calc_selected":
const { selectedRowKeys } = this.calc.calcTableRef.wrappedInstance.state;
if (_.isEmpty(selectedRowKeys)) {
message.warning(getLabel(543303, "请选择表格数据!"));
return;
}
this.doCacl(key, selectedRowKeys);
break;
default:
break;
}
};
doCacl = (key, selectedRowKeys = []) => {
Modal.confirm({
title: getLabel(131329, "信息确认"),
content: getLabel(543544, "点击核算,公式项将按照公式逻辑核算,核算结果将覆盖原数据"),
onOk: () => {
const { routeParams: { salaryAcctRecordId } } = this.props;
this.setState({ progress: 0 });
let payload = { salaryAcctRecordId };
if (key === "calc_selected") payload = _.assign(payload, { ids: selectedRowKeys });
acctresultAccounting(payload).then(() => {
this.setState({ progressVisible: true });
if (this.timer) clearInterval(this.timer);
this.timer = setInterval(() => {
getCalculateProgress(salaryAcctRecordId).then(({ data }) => {
let progress = data.progress;
if (progress === 1 && this.timer) {
clearInterval(this.timer);
this.timer = null;
this.setState({
progressVisible: false,
accountExceptInfo: data.message
});
message.success(getLabel(542321, "核算完成"));
this.calc.onAdSearch(false);
} else if (!data.status) {
clearInterval(this.timer);
this.timer = null;
this.setState({
progressVisible: false,
accountExceptInfo: data.message
});
message.error(data.message);
}
this.setState({ progress: Number(progress) * 100 });
});
}, 1000);
});
}
});
};
handleMoreMenuClick = ({ key }) => {
const { calculateStore: { ECSearchForm }, routeParams: { salaryAcctRecordId } } = this.props;
switch (key) {
case "exportAll":
const { consolidatedTaxation, ...extra } = ECSearchForm.getFormParams();
const payload = { ...extra, consolidatedTaxation: consolidatedTaxation === "0" ? "" : consolidatedTaxation };
const url = `/api/bs/hrmsalary/salaryacct/acctresult/export?salaryAcctRecordId=${salaryAcctRecordId}&ids=&${convertToUrlString(payload)}`;
window.open(`${window.ecologyContentPath || ""}${url}`, "_blank");
break;
case "export_custom":
getExportField({ salaryAcctRecordId }).then(({ status, data }) => {
if (status) {
const { checkItems, itemsByGroup } = data;
this.setState({
customExpDialog: {
...this.state.customExpDialog, visible: true, salaryAcctRecordId,
checkItems, itemsByGroup
}
});
}
});
break;
case "import":
this.setState({
salaryImpDialog: {
...this.state.salaryImpDialog,
salaryAcctRecordId, visible: true,
title: getLabel(111, "薪资导入")
}
});
break;
case "offlineCompare":
window.open(`/spa/hrmSalary/static/index.html#/main/hrmSalary/calcOc/${salaryAcctRecordId}`, "_blank");
break;
default:
break;
}
};
renderReqBtns = () => {
const { selectedKey } = this.state;
let reqBtns = [];
switch (selectedKey) {
case "calc":
const menu = (
<Menu onClick={this.handleMenuClick}>
<Menu.Item key="calc_selected">{getLabel(543546, "核算所选人员")}</Menu.Item>
</Menu>
);
const moreMenu = (
<Menu onClick={this.handleMoreMenuClick}>
<Menu.Item key="import">{getLabel(32935, "导入")}</Menu.Item>
<Menu.Item key="exportAll">{getLabel(81272, "导出全部")}</Menu.Item>
<Menu.Item key="export_custom">{getLabel(544270, "自定义导出")}</Menu.Item>
<Menu.Item key="offlineCompare">{getLabel(543249, "线下对比")}</Menu.Item>
</Menu>
);
reqBtns = [
<Dropdown.Button onClick={() => this.doCacl("ALL")} overlay={menu} type="primary">
{getLabel(543545, "核算所有人")}
</Dropdown.Button>,
<Dropdown overlay={moreMenu}><Button type="ghost">{getLabel(17499, "更多")}</Button></Dropdown>,
<AdvanceInputBtn onOpenAdvanceSearch={() => this.calc.openAdvanceSearch()}
onAdvanceSearch={() => this.calc.onAdSearch(false)}/>
];
break;
default:
break;
}
return reqBtns;
};
renderContent = () => {
const { selectedKey, accountExceptInfo } = this.state;
let dom = null;
switch (selectedKey) {
case "person":
dom = <SalaryCalcPersonConfirm {...this.props}/>;
break;
case "calc":
dom = <SalaryEditCalc {...this.props} accountExceptInfo={accountExceptInfo} ref={dom => this.calc = dom}/>;
break;
default:
break;
}
return dom;
};
render() {
const tabs = [
{ key: "person", title: getLabel(543547, "人员确认") },
{ key: "calc", title: getLabel(538011, "薪资核算") }
];
const { calculateStore: { setOtherConditions } } = this.props;
const { selectedKey, progressVisible, progress, customExpDialog, salaryImpDialog } = this.state;
return (
<Layout {...this.props}>
<div className="salary-calculate-do-calc">
<WeaReqTop
title={getLabel(538011, "薪资核算")} tabDatas={tabs} selectedKey={selectedKey}
buttonSpace={10} icon={<i className="icon-coms-fa"/>} iconBgcolor="#F14A2D"
onChange={key => this.setState({ selectedKey: key }, () => setOtherConditions([]))}
buttons={this.renderReqBtns()}
>
<div className="salary-calculate-do-calc-content">{this.renderContent()}</div>
{
progressVisible &&
<ProgressModal
visible={progressVisible}
onCancel={() => {
this.setState({ progressVisible: false, progress: 0 }, () => clearInterval(this.timer));
}}
progress={parseFloat(progress).toFixed(2)}
/>
}
{/* 薪资核算-自定义导出*/}
<CustomCalcExportDialog
{...customExpDialog}
onCancel={() => {
this.setState({
customExpDialog: { ...customExpDialog, visible: false }
});
}}
/>
{/* 薪资核算-导入*/}
<SalaryEditCalcImport
{...salaryImpDialog}
onCancel={(isFresh) => {
this.setState({
salaryImpDialog: { ...salaryImpDialog, visible: false }
}, () => isFresh && this.calc.onAdSearch(false));
}}
/>
</WeaReqTop>
</div>
</Layout>
);
}
}
export default Index;

View File

@ -0,0 +1,20 @@
.salary-calculate-do-calc {
min-width: 1000px;
overflow: auto;
width: 100%;
height: 100%;
background: #f6f6f6;
.wea-new-top-req {
z-index: 0 !important;
}
.wea-new-top-req-wapper .wea-new-top-req-title > div:last-child {
right: 16px;
}
.salary-calculate-do-calc-content {
padding: 8px 16px;
height: 100%;
}
}

View File

@ -0,0 +1,46 @@
import React, { Component } from "react";
import { inject, observer } from "mobx-react";
import Authority from "../../mySalary/authority";
import { salaryacctAcctresultCheckAuth } from "../../../apis/calculate";
@inject("taxAgentStore")
@observer
class Layout extends Component {
constructor(props) {
super(props);
this.state = {
store: { loading: false, hasRight: false }
};
}
componentDidMount() {
this.salaryacctAcctresultCheckAuth();
}
salaryacctAcctresultCheckAuth = () => {
const { taxAgentStore: { getPermission } } = this.props;
this.setState({ store: { ...this.state.store, loading: true } });
getPermission().then(({ data }) => {
const { isOpenDevolution } = data;
if (isOpenDevolution) {
const { routeParams: { salaryAcctRecordId } } = this.props;
salaryacctAcctresultCheckAuth({ salaryAcctRecordId }).then(({ status, data }) => {
this.setState({ store: { ...this.state.store, loading: false, hasRight: status && data } });
});
} else {
this.setState({ store: { ...this.state.store, loading: false, hasRight: true } });
}
}).catch(() => this.setState({ store: { ...this.state.store, loading: false } }));
};
render() {
return (
<Authority ecId={`${this && this.props && this.props.ecId || ""}_Authority@lulowc`}
store={{ ...this.state.store }}>
{this.props.children}
</Authority>
);
}
}
export default Layout;

View File

@ -352,18 +352,10 @@ export default class CalculateDetail extends React.Component {
onClick={() => this.downloadTxtfile(accountExceptInfo)}/>);
return buttons;
};
const topTab = [
{
title: getLabel(543547, "人员确认"),
viewcondition: "0"
},
{
title: getLabel(538011, "薪资核算"),
viewcondition: "1"
}
{ title: getLabel(543547, "人员确认"), viewcondition: "0" },
{ title: getLabel(538011, "薪资核算"), viewcondition: "1" }
];
const adBtn = [
// 高级搜索内部按钮
<Button type="primary" onClick={() => {
@ -406,19 +398,19 @@ export default class CalculateDetail extends React.Component {
return (
<Authority ecId={`${this && this.props && this.props.ecId || ""}_Authority@lulowc`}
store={{ loading: false, hasRight: payrollPermission && calculateAuth }}>
<div style={{ overflowY: "hidden", height: "100%" }}>
<div className="calculate-layout">
<WeaTab
datas={topTab}
selectedKey={selectedKey}
keyParam="viewcondition"
onChange={v => this.setState({ selectedKey: v })}
searchType={selectedKey == 1 ? ["base", "advanced"] : []} // base基础搜索框 advanced显示高级搜索按钮
searchType={selectedKey === "1" ? ["base", "advanced"] : []} // base基础搜索框 advanced显示高级搜索按钮
showSearchAd={showSearchAd} // 是否展开高级搜索面板
setShowSearchAd={(bool) => this.setState({ showSearchAd: bool })} //高级搜索面板受控
searchsAd={renderSearch()} // 高级搜索内部数据getSearchs(form, toJS(condition), 2)
buttonsAd={adBtn} // 高级搜索内部按钮
onSearch={() => this.handleSearch(this.state.searchItemsValue)} // 点搜索按钮时的回调
buttons={selectedKey == 1 ? renderRightOperation() : []}
buttons={selectedKey === "1" ? renderRightOperation() : []}
searchsBasePlaceHolder={getLabel(26919, "请输入姓名")}
onSearchChange={(v) =>
this.setState({
@ -430,9 +422,9 @@ export default class CalculateDetail extends React.Component {
} // 在搜索框中输入的文字改变时的回调: 这里需要同步高级搜索和外部搜索框的值form.updateFields({ username: v })
searchsBaseValue={this.state.searchItemsValue.employeeName} // 外部input搜索值受控: 这里和高级搜索的requestname同步form.getFormParams().username
/>
{selectedKey == 0 && <UserSure/>}
{selectedKey == 1 && <SalaryDetail onChangeAccountIds={(ids) => this.setState({ accountIds: ids })}
employeeName={this.state.searchItemsValue}/>}
{selectedKey === "0" && <UserSure/>}
{selectedKey === "1" && <SalaryDetail onChangeAccountIds={(ids) => this.setState({ accountIds: ids })}
employeeName={this.state.searchItemsValue}/>}
{acctResultImportVisiable &&
<AcctResultImportModal
visiable={acctResultImportVisiable}

View File

@ -1,3 +1,17 @@
.calculate-layout {
height: 100%;
overflow-y: hidden;
background: #f6f6f6;
.wea-tab .wea-tab-right {
background: #f6f6f6;
}
.wea-input-focus {
background: transparent;
}
}
.userSure {
padding: 20px;
@ -8,7 +22,20 @@
.formWrapper {
line-height: 40px;
border-bottom: 1px solid #eee;
border: 1px solid #eee;
background: #fff;
.ant-col-12 {
padding: 0 16px;
}
& > div:first-child {
border-bottom: 1px solid #eee;
& > div:first-child {
border-right: 1px solid #e5e5e5;
}
}
}
.operateBarWrapper {
@ -59,8 +86,8 @@
}
.salaryDetail {
padding: 10px 20px;
overflow-y: scroll;
padding: 10px;
overflow-y: auto;
.salaryBarWrapper {
padding: 10px;
@ -140,7 +167,8 @@
.placeOnFileDetail {
height: 100%;
overflow-y: auto;
overflow-y: hidden;
background: #f6f6f6;
.tabWrapper {
height: 47px;
@ -242,3 +270,9 @@
}
}
}
.salaryMonthTip-layout{
display: flex;
flex-direction: column;
}

View File

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

View File

@ -37,10 +37,10 @@ class PayrollItemsTable extends Component {
</span>,
width: "20%",
render: (text, record) => {
const { canEdit, dataType } = record;
const { canEdit, dataType, pattern } = record;
return dataType === "number" ? <WeaInputNumber
disabled={!canEdit}
precision={2}
precision={pattern || 2}
value={text || 0}
onChange={(value) => onChangeIssueReissueValue(record.salaryItemId, value, "itemsByGroup", salarySobItemGroupId)}
/> : <WeaInput

View File

@ -209,7 +209,6 @@ export default class PlaceOnFileDetail extends React.Component {
};
return (
<div className="placeOnFileDetail">
<CustomTab
searchOperationItem={
@ -217,7 +216,7 @@ export default class PlaceOnFileDetail extends React.Component {
}
/>
<div className="tabWrapper" style={{ borderBottom: "none" }}>
<span>{getLabel(542604, "薪资所属月")}{baseSalarySobCycle.salaryMonth}</span>
<span style={{ marginRight: 10 }}>{getLabel(542604, "薪资所属月")}{baseSalarySobCycle.salaryMonth}</span>
<WeaHelpfulTip
width={100}
title={`${getLabel(543375, "薪资周期")}\n

View File

@ -6,9 +6,10 @@ import EditSalaryDetail from "./editSalaryDetail";
import SlideModalTitle from "../../components/slideModalTitle";
import { getQueryString } from "../../util/url";
import { inject, observer } from "mobx-react";
import ProgressModal from "../../components/progressModal";
import { SalaryMonthTip } from "./userSure";
import { toJS } from "mobx";
import "./index.less";
import ProgressModal from "../../components/progressModal";
const getLabel = WeaLocaleProvider.getLabel;
@ -199,6 +200,7 @@ export default class SalaryDetail extends React.Component {
progressVisible: false,
progress: 0
}, () => {
const { current, pageSize } = this.pageInfo;
const childFrameObj = document.getElementById("atdTable");
const payload = {
type: "PR",
@ -206,7 +208,8 @@ export default class SalaryDetail extends React.Component {
url: "/api/bs/hrmsalary/salaryacct/acctresult/list",
queryParams: {
salaryAcctRecordId,
...this.props.employeeName
...this.props.employeeName,
current, pageSize
}
};
childFrameObj.contentWindow.postMessage(JSON.stringify(payload), "*");
@ -257,13 +260,15 @@ export default class SalaryDetail extends React.Component {
this.setState({ loading: false });
const childFrameObj = document.getElementById("atdTable");
const salaryAcctRecordId = getQueryString("id");
const { current, pageSize } = this.pageInfo;
const payload = {
type: "PR",
listType: "", i18n,
url: "/api/bs/hrmsalary/salaryacct/acctresult/list",
queryParams: {
salaryAcctRecordId,
...this.props.employeeName
...this.props.employeeName,
current, pageSize
}
};
childFrameObj.contentWindow.postMessage(JSON.stringify(payload), "*");
@ -282,17 +287,9 @@ export default class SalaryDetail extends React.Component {
<div className="salaryBarWrapper">
<span>{getLabel(542604, "薪资所属月")}{baseSalarySobCycle.salaryMonth}</span>
<WeaHelpfulTip
style={{ marginLeft: "10px" }}
width={200}
title={
`${getLabel(543375, "薪资周期")}\n
${baseSalarySobCycle.salaryCycle && baseSalarySobCycle.salaryCycle.fromDate}${getLabel(15322, "至")}${baseSalarySobCycle.salaryCycle && baseSalarySobCycle.salaryCycle.endDate}\n
${getLabel(542240, "税款所属期")}\n
${baseSalarySobCycle.taxCycle}\n
${getLabel(543475, "考勤取值周期")}\n
${baseSalarySobCycle.attendCycle && baseSalarySobCycle.attendCycle.fromDate}${getLabel(15322, "至")}${baseSalarySobCycle.attendCycle && baseSalarySobCycle.attendCycle.endDate}\n
${getLabel(543466, "福利台账月份")}\n
${getLabel(19422, "引用")}${baseSalarySobCycle.socialSecurityCycle}${getLabel(543476, "的福利台账数据")}`}
style={{ marginLeft: 10 }}
title={!_.isEmpty(baseSalarySobCycle) ?
<SalaryMonthTip baseSalarySobCycle={baseSalarySobCycle}/> : ""}
placement="topLeft"
/>
{/*暂时隐藏*/}

View File

@ -11,11 +11,10 @@ import {
WeaTab
} from "ecCom";
import { inject, observer } from "mobx-react";
import "./index.less";
import { getQueryString } from "../../util/url";
import "./index.less";
const getLabel = WeaLocaleProvider.getLabel;
const { getLabel } = WeaLocaleProvider;
@inject("calculateStore", "salaryFileStore")
@observer
export default class UserSure extends React.Component {
@ -154,7 +153,7 @@ export default class UserSure extends React.Component {
url: "/api/bs/hrmsalary/salaryacct/acctemployee/list",
queryParams: {
salaryAcctRecordId,
...this.state.searchItemsValue,
...this.state.searchItemsValue
}
};
childFrameObj.contentWindow.postMessage(JSON.stringify(payload), "*"); //window.postMessage
@ -547,12 +546,8 @@ export default class UserSure extends React.Component {
<Row>
<Col span={6}>
{getLabel(543549, "薪资所属月:")}<WeaHelpfulTip
width={100}
title={`${getLabel(543375, "薪资周期")}\n${baseSalarySobCycle.salaryCycle &&
baseSalarySobCycle.salaryCycle.fromDate}${getLabel(15322, "至")}${baseSalarySobCycle.salaryCycle &&
baseSalarySobCycle.salaryCycle.endDate}\n${getLabel(542240, "税款所属期")}\n${baseSalarySobCycle.taxCycle}\n${getLabel(543475, "考勤取值周期")}\n${baseSalarySobCycle.attendCycle &&
baseSalarySobCycle.attendCycle.fromDate}${getLabel(15322, "至")}${baseSalarySobCycle.attendCycle &&
baseSalarySobCycle.attendCycle.endDate}\n${getLabel(543466, "福利台账月份")}\n${getLabel(19422, "引用")}${baseSalarySobCycle.socialSecurityCycle}${getLabel(543476, "的福利台账数据")}`}
title={!_.isEmpty(baseSalarySobCycle) ?
<SalaryMonthTip baseSalarySobCycle={baseSalarySobCycle}/> : ""}
placement="topLeft"
/>
</Col>
@ -602,7 +597,7 @@ export default class UserSure extends React.Component {
url: "/api/bs/hrmsalary/salaryacct/acctemployee/list",
queryParams: {
salaryAcctRecordId,
...this.state.searchItemsValue,
...this.state.searchItemsValue
}
};
childFrameObj.contentWindow.postMessage(JSON.stringify(payload), "*"); //window.postMessage
@ -632,7 +627,7 @@ export default class UserSure extends React.Component {
url: "/api/bs/hrmsalary/salaryacct/reducedemployee/list",
queryParams: {
salaryAcctRecordId,
...this.state.searchItemsValue,
...this.state.searchItemsValue
}
};
childFrameObj.contentWindow.postMessage(JSON.stringify(payload), "*");
@ -662,7 +657,7 @@ export default class UserSure extends React.Component {
url: "/api/bs/hrmsalary/salaryacct/addedemployee/list",
queryParams: {
salaryAcctRecordId,
...this.state.searchItemsValue,
...this.state.searchItemsValue
}
};
childFrameObj.contentWindow.postMessage(JSON.stringify(payload), "*");
@ -759,3 +754,32 @@ export default class UserSure extends React.Component {
);
}
}
export const SalaryMonthTip = (props) => {
const { baseSalarySobCycle } = props;
const { salaryCycle, taxCycle, attendCycle, socialSecurityCycle } = baseSalarySobCycle;
const { fromDate: salaryCycleFromDate, endDate: salaryCycleEndDate } = salaryCycle;
const { fromDate: attendCycleFromDate, endDate: attendCycleEndDate } = attendCycle;
return (
<div className="salaryMonthTip-layout">
<div className="salaryMonthTipItem">
<div className="label">{getLabel(543375, "薪资周期")}</div>
<div className="value">{`${salaryCycleFromDate}${getLabel(15322, "至")}${salaryCycleEndDate}`}</div>
</div>
<div className="salaryMonthTipItem">
<div className="label">{getLabel(542240, "税款所属期")}</div>
<div className="value">{taxCycle}</div>
</div>
<div className="salaryMonthTipItem">
<div className="label">{getLabel(543475, "考勤取值周期")}</div>
<div className="value">{`${attendCycleFromDate}${getLabel(15322, "至")}${attendCycleEndDate}`}</div>
</div>
<div className="salaryMonthTipItem">
<div className="label">{getLabel(543466, "福利台账月份")}</div>
<div className="value">
{`${getLabel(19422, "引用")}${socialSecurityCycle}${getLabel(543476, "的福利台账数据")}`}
</div>
</div>
</div>
);
};

View File

@ -35,6 +35,7 @@ class FieldSlide extends Component {
name: "",
useInEmployeeSalary: "1",
useDefault: "0",
hideDefault: "0",
sharedType: "0",
shareTypeList: [],
taxAgentIds: "",

View File

@ -23,7 +23,7 @@ class LedgerSalaryItemEditSlide extends Component {
const key = Object.keys(params)[0];
this.props.onUpdateRequest(request, key);
};
handleShowFormal = () => this.props.onEditFormnul();
handleShowFormal = (salaryItemName) => this.props.onEditFormnul(salaryItemName);
render() {
return (

View File

@ -147,7 +147,7 @@ class LedgerSalaryItemNormal extends Component {
const newDateSource = _.map(dataSource, item => {
return {
...item,
items: _.filter(item.items || [], child => child.name.indexOf(salaryItemKeywords) !== -1)
items: _.filter(item.items || [], child => (child.name.indexOf(salaryItemKeywords) !== -1 || child.formulaContent.indexOf(salaryItemKeywords) !== -1))
};
});
return (
@ -262,7 +262,7 @@ const TitleComp = (props) => {
<Button type="ghost" onClick={() => onAddCategory()} style={{ marginRight: 10 }}>{getLabel(515324, "新增分类")}</Button>
}
<WeaInputSearch value={salaryItemKeywords} onChange={onChange}
placeholder={getLabel(543534, "请输入薪资项目名称")}
placeholder={getLabel(543534, "请输入薪资项目名称或者公式名称")}
/>
</div>
</div>;

View File

@ -28,7 +28,8 @@ class LedgerSalaryItemTable extends Component {
visible: false,
formulaId: "",
valueType: "",
dataType: ""
dataType: "",
name: ""
}
};
}
@ -163,13 +164,13 @@ class LedgerSalaryItemTable extends Component {
originSqlContent: ((valueType.toString() === "2" && (!originFormulaContent || originFormulaContent === " ")) || (valueType.toString() === "1") || (valueType.toString() === "2" && originFormulaContent)) ? " " : originSqlContent
}, salaryItemId);
};
handleEditFormnul = () => {
handleEditFormnul = (salaryItemName) => {
const { salaryItemPayload, editFormulModal } = this.state;
const { record } = salaryItemPayload;
const { valueType, formulaId, dataType, originFormulaContent, originSqlContent } = record;
this.setState({
editFormulModal: {
...editFormulModal, visible: true, valueType, dataType,
...editFormulModal, visible: true, valueType, dataType, name: salaryItemName,
formulaId: ((valueType.toString() === "2" && (originFormulaContent || originFormulaContent !== " ")) || valueType.toString() === "3" && (originSqlContent || originSqlContent === " ")) ? formulaId : ""
}
});
@ -180,7 +181,7 @@ class LedgerSalaryItemTable extends Component {
editFormulModal: {
...editFormulModal,
visible: false,
formulaId: "",
formulaId: "", name: "",
valueType: "", dataType: ""
}
});
@ -255,9 +256,9 @@ class LedgerSalaryItemTable extends Component {
dataIndex: "valueType",
key: "valueType",
render: (e, record) => {
const { valueType } = record;
const { valueType, formulaContent } = record;
const key = !_.isNil(valueType) ? valueType : "";
return <span> {key.toString() === "1" ? "输入" : key.toString() === "2" ? "自定义公式" : key.toString() === "3" ? "SQL" : ""} </span>;
return <span> {key.toString() === "1" ? "输入" : key.toString() === "2" ? formulaContent : key.toString() === "3" ? formulaContent : ""} </span>;
}
},
{

View File

@ -92,7 +92,7 @@ export default class MobilePayroll extends React.Component {
const params = this.getUrlkey();
const payload = {
salaryInfoId,
..._.omit(params, ["id", "_key", "type"])
..._.pick(params, ["recipient"])
};
getMySalaryBill(payload).then(result => {
this.setState({
@ -188,7 +188,7 @@ export default class MobilePayroll extends React.Component {
salaryItemSet={!_.isEmpty(salaryGroups) ? JSON.stringify([employeeInformation, ...salaryGroups]) : []}
>
{
(_.isNil(mySalaryBillData.confirmStatus) || mySalaryBillData.confirmStatus === "0") &&
(!_.isEmpty(salaryGroups) && (_.isNil(mySalaryBillData.confirmStatus) || mySalaryBillData.confirmStatus === "0")) &&
<ConfirmBtns
confirmSalaryBill={this.confirmSalaryBill}
goFeedback={this.handleGoFeedback}
@ -209,7 +209,7 @@ export default class MobilePayroll extends React.Component {
salaryItemSet={!_.isEmpty(salaryGroups) ? JSON.stringify([employeeInformation, ...salaryGroups]) : JSON.stringify([])}
>
{
(_.isNil(mySalaryBillData.confirmStatus) || mySalaryBillData.confirmStatus === "0") &&
(!_.isEmpty(salaryGroups) && (_.isNil(mySalaryBillData.confirmStatus) || mySalaryBillData.confirmStatus === "0")) &&
<ConfirmBtns
confirmSalaryBill={this.confirmSalaryBill}
goFeedback={this.handleGoFeedback}

View File

@ -2,11 +2,11 @@ import React from "react";
import { inject, observer } from "mobx-react";
import { DatePicker } from "antd";
import { WeaLocaleProvider, WeaNewScroll, WeaTop } from "ecCom";
import { renderNoright } from "../../util"; // 渲染form数据的方法因为多个页面都会使用所以抽的公共方法在util中
import CustomTab from "../../components/customTab";
import moment from "moment";
import PayrollModal from "./payrollModal";
import CustomPaginationTable from "../../components/customPaginationTable";
import Authority from "./authority";
import "./index.less";
const { getLabel } = WeaLocaleProvider;
@ -87,8 +87,8 @@ export default class MySalary extends React.Component {
handleTabChange = (selectedKey) => {
if (selectedKey === "2") {
const { mySalaryStore: { getRecordList } } = this.props;
getRecordList();
const { mySalaryStore: { initRecordData } } = this.props;
initRecordData();
}
};
@ -176,21 +176,24 @@ export default class MySalary extends React.Component {
}
{
this.state.selectedKey === "2" &&
<CustomPaginationTable
columns={recordListColumns}
dataSource={recordListDataSource}
total={recordListPageInfo.total}
current={recordListPageInfo.pageNum}
pageSize={this.historyPageInfo.pageSize}
onPageChange={(value) => {
this.historyPageInfo.current = value;
this.handleHistoryPageChange();
}}
onShowSizeChange={(current, pageSize) => {
this.historyPageInfo = { current, pageSize };
this.handleHistoryPageChange();
}}
/>
<Authority ecId={`${this && this.props && this.props.ecId || ""}_Authority@lulowc`}
store={this.props.mySalaryStore}>
<CustomPaginationTable
columns={recordListColumns}
dataSource={recordListDataSource}
total={recordListPageInfo.total}
current={recordListPageInfo.pageNum}
pageSize={this.historyPageInfo.pageSize}
onPageChange={(value) => {
this.historyPageInfo.current = value;
this.handleHistoryPageChange();
}}
onShowSizeChange={(current, pageSize) => {
this.historyPageInfo = { current, pageSize };
this.handleHistoryPageChange();
}}
/>
</Authority>
}
</WeaNewScroll>
</div>

View File

@ -99,7 +99,7 @@ class MySalaryView extends Component {
salaryItemSet={!_.isEmpty(salaryGroups) ? JSON.stringify([employeeInformation, ...salaryGroups]) : []}
>
{
(_.isNil(mySalaryStore.confirmStatus) || mySalaryStore.confirmStatus === "0") &&
(!_.isEmpty(salaryGroups) && (_.isNil(mySalaryStore.confirmStatus) || mySalaryStore.confirmStatus === "0")) &&
<ConfirmBtns
confirmSalaryBill={this.confirmSalaryBill}
goFeedback={this.handleGoFeedback}

View File

@ -286,7 +286,7 @@ export default class Payroll extends React.Component {
viewcondition: "1"
},
{
title: getLabel(543849, "工资单模板基础设置"),
title: getLabel(111, "工资单基础设置"),
viewcondition: "2"
}
];

View File

@ -19,4 +19,16 @@
margin-top: -10px;
}
}
.agingBox {
display: flex;
align-items: center;
padding: 5px 16px;
border-bottom: 1px solid #e5e5e5;
.wea-input-number {
width: 80px !important;
margin: 0 10px;
}
}
}

View File

@ -182,7 +182,7 @@ export default class PayrollDetail extends React.Component {
<Button type="ghost" onClick={() => setDetailListShowSearchAd(false)}>{getLabel(31129, "取消")}</Button>
];
return (
<div className="payrollGrant">
<div className="payrollDetail">
<WeaTab
searchType={["base", "advanced"]} searchsBasePlaceHolder={getLabel(26919, "请输入姓名")}
buttons={[<Button type="primary" onClick={this.handleExportAll}>{getLabel(81272, "导出全部")}</Button>]}

View File

@ -1,12 +1,17 @@
.payrollGrant {
.payrollDetail {
display: flex;
flex-direction: column;
height: 100%;
background: #f6f6f6;
.wea-tab .wea-tab-right, .wea-input-focus {
background: #f6f6f6;
}
.titleBar {
height: 47px;
line-height: 47px;
padding: 0 10px;
padding: 0 16px;
.titleBarLeft {
float: left;
@ -19,6 +24,7 @@
.tableWrapper {
flex: 1;
padding: 0 16px;
.ant-spin-nested-loading, .ant-spin-container {
height: 100%;

View File

@ -305,7 +305,6 @@ export default class PayrollGrant extends React.Component {
const { selectedKey, showFeedbackColumn } = this.state;
const { payrollStore } = this.props;
const { salaryGrantTableStore: columns, salarySendDetailBaseInfo } = payrollStore;
const notShowGrantOrWithdraw = salarySendDetailBaseInfo.haveBackCalc === 1 && salarySendDetailBaseInfo.salaryAcctType === "0";
return _.map([
..._.filter(toJS(columns), it => ((selectedKey === "0" && it.dataIndex !== "billReadStatus" && it.dataIndex !== "billConfirmStatus") || (selectedKey === "1" && !showFeedbackColumn && it.dataIndex !== "billReadStatus" && it.dataIndex !== "billConfirmStatus") || (selectedKey === "1" && showFeedbackColumn))),
{
@ -314,14 +313,43 @@ export default class PayrollGrant extends React.Component {
dataIndex: "",
display: true,
render: (text, record) => {
if (record.sendStatus === "1" && salarySendDetailBaseInfo.canSend) {
return (
<a
href="javascript:void(0);"
onClick={() => this.handleWithdraw({ ids: [record.id] })}>
{getLabel(32025, "撤回")}
</a>
);
if (record.sendStatus === "1") {
if (salarySendDetailBaseInfo.canSend) {
return (
<React.Fragment>
<a
href="javascript:void(0);" style={{ marginRight: 10 }}
onClick={() => this.handleWithdraw({ ids: [record.id] })}>
{getLabel(32025, "撤回")}
</a>
{
salarySendDetailBaseInfo.showPdfBtn &&
<a
href="javascript:void(0);"
onClick={() => {
window.open(`${window.ecologyContentPath || ""}/api/bs/hrmsalary/salaryBill/exportPdf?id=${record.id}&salarySendId=${getQueryString("id")}`, "_blank");
}}>
{getLabel(111, "导出PDF")}
</a>
}
</React.Fragment>
);
} else {
return (
<React.Fragment>
{
salarySendDetailBaseInfo.showPdfBtn &&
<a
href="javascript:void(0);"
onClick={() => {
window.open(`${window.ecologyContentPath || ""}/api/bs/hrmsalary/salaryBill/exportPdf?id=${record.id}&salarySendId=${getQueryString("id")}`, "_blank");
}}>
{getLabel(111, "导出PDF")}
</a>
}
</React.Fragment>
);
}
} else if (salarySendDetailBaseInfo.canSend) {
return (
<a
@ -349,7 +377,6 @@ export default class PayrollGrant extends React.Component {
getSearchsAdQuick() {
const { payrollStore } = this.props;
const { salarySendDetailBaseInfo, btnLoading } = payrollStore;
const notShowGrantOrWithdraw = salarySendDetailBaseInfo.haveBackCalc === 1 && salarySendDetailBaseInfo.salaryAcctType === "0";
const { selectedKey } = this.state;
const handleMenuClick = e => {
switch (e.key) {
@ -359,6 +386,9 @@ export default class PayrollGrant extends React.Component {
case "4":
this.handleExportSelect();
break;
case "5":
window.open(`${window.ecologyContentPath || ""}/api/bs/hrmsalary/salaryBill/exportPdf?salarySendId=${getQueryString("id")}&id=`, "_blank");
break;
default:
break;
}
@ -367,6 +397,10 @@ export default class PayrollGrant extends React.Component {
<Menu onClick={handleMenuClick}>
<Menu.Item key="3">{getLabel(125595, "全部导出")}</Menu.Item>
<Menu.Item key="4">{getLabel(512938, "导出选中")}</Menu.Item>
{
selectedKey === "1" && salarySendDetailBaseInfo.showPdfBtn &&
<Menu.Item key="5">{getLabel(111, "导出PDF")}</Menu.Item>
}
</Menu>
);
let btnDom = [
@ -594,6 +628,7 @@ export default class PayrollGrant extends React.Component {
this.pageInfo = { current, pageSize };
this.handleShowSizeChange(this.pageInfo);
}}
scroll={{ y: `calc(100vh - 236px)` }}
/> : renderLoading()
}
</div>

View File

@ -1,8 +1,15 @@
.payrollGrant_new {
background: #f6f6f6;
height: 100%;
.wea-tab .wea-tab-right, .wea-input-focus {
background: #f6f6f6;
}
.titleBar {
height: 47px;
line-height: 47px;
padding: 0 10px;
padding: 0 16px;
.titleBarLeft {
float: left;
@ -14,8 +21,11 @@
}
.tableWrapper {
height: calc(100vh - 180.22px);
overflow: auto;
padding: 0 16px;
.wea-new-table {
background: #FFF;
}
}
}

View File

@ -117,6 +117,7 @@ export default class BaseInformForm extends React.Component {
{
this.state.inited &&
<WeaSelect
disabled={this.props.id}
viewAttr={3}
options={options}
value={salarySob ? salarySob : ""}

View File

@ -87,9 +87,11 @@ class SalaryItemSettings extends Component {
}
});
this.setState({
dataList: resultSalaryItemSet
dataList: resultSalaryItemSet,
itemShowNamesetting: _.filter(this.state.itemShowNamesetting, it => it.salaryItemId !== item.id)
}, () => {
this.props.onChangeSalaryItem(resultSalaryItemSet);
this.props.onChangeSalaryItemShowNamesetting(this.state.itemShowNamesetting);
});
};
handleCloseModal = () => {

View File

@ -36,6 +36,9 @@ class TemplateBaseSettings extends Component {
ackStatus: "0",
autoAckDays: 7,
feedBackUrl: ""
},
salaryBillViewingLimitSetting: {
limitMonth: 0
}
};
}
@ -48,9 +51,12 @@ class TemplateBaseSettings extends Component {
const { watermarkSet } = this.state;
getSalaryBillBaseSetForm().then(({ status, data }) => {
if (status) {
const { watermarkStatus, watermark = "DEFAULT", watermarkSetting, ackFeedbackSetting } = data;
const {
watermarkStatus, watermark = "DEFAULT", watermarkSetting,
ackFeedbackSetting, salaryBillViewingLimitSetting = {}
} = data;
this.setState({
watermark, watermarkStatus: watermarkStatus ? "1" : "0", ackFeedbackSetting,
watermark, watermarkStatus: watermarkStatus ? "1" : "0", ackFeedbackSetting, salaryBillViewingLimitSetting,
wmSetting: { wmSetting: watermarkSetting },
watermarkSet: {
...watermarkSet,
@ -61,7 +67,7 @@ class TemplateBaseSettings extends Component {
});
};
salaryBillBaseSetSave = () => {
const { watermark, watermarkStatus, wmSetting, ackFeedbackSetting } = this.state;
const { watermark, watermarkStatus, wmSetting, ackFeedbackSetting, salaryBillViewingLimitSetting } = this.state;
const { feedBackUrl } = ackFeedbackSetting;
if (!feedBackUrl) {
Modal.warning({
@ -70,7 +76,10 @@ class TemplateBaseSettings extends Component {
});
return;
}
let payload = { watermarkStatus: watermarkStatus === "1", ackFeedbackSetting: { ...ackFeedbackSetting } };
let payload = {
watermarkStatus: watermarkStatus === "1", ackFeedbackSetting: { ...ackFeedbackSetting },
salaryBillViewingLimitSetting: { ...salaryBillViewingLimitSetting }
};
if (watermarkStatus === "1") payload = { ...payload, watermark };
if (!_.isNil(wmSetting)) payload = { ...payload, watermark, ...wmSetting };
this.props.onChangeLoading(true);
@ -86,8 +95,9 @@ class TemplateBaseSettings extends Component {
};
render() {
const { watermarkStatus, watermark, watermarkSet, ackFeedbackSetting } = this.state;
const { watermarkStatus, watermark, watermarkSet, ackFeedbackSetting, salaryBillViewingLimitSetting } = this.state;
const { ackStatus, autoAckDays, feedBackUrl } = ackFeedbackSetting;
const { limitMonth = 0 } = salaryBillViewingLimitSetting;
return (
<React.Fragment>
<WeaSearchGroup title={getLabel(538702, "水印设置")} showGroup needTigger className="waterMarkWrapper">
@ -160,6 +170,22 @@ class TemplateBaseSettings extends Component {
</React.Fragment>
}
</WeaSearchGroup>
<WeaSearchGroup title={getLabel(111, "工资单时效设置")} showGroup needTigger className="waterMarkWrapper">
<div className="agingBox">
<span>{getLabel(111, "仅可查看")}</span>
<WeaInputNumber min={0} value={limitMonth}
onChange={limitMonth => this.setState({
salaryBillViewingLimitSetting: {
...salaryBillViewingLimitSetting, limitMonth
}
})}/>
<span>{getLabel(111, "个月内的工资单")}</span>
<WeaHelpfulTip
title={getLabel(111, "0表示不控制")}
style={{ marginLeft: 10 }}
placement="top"/>
</div>
</WeaSearchGroup>
</React.Fragment>
);
}

View File

@ -94,7 +94,7 @@ export default class ComputerTemplate extends React.Component {
<div className="sobItemWrapper">
{
salaryItemSet.length > 0 &&
salaryItemSet.map((group, index) => {
_.filter(salaryItemSet, it => (!_.isNil(it) && !_.isEmpty(it))).map((group, index) => {
return <div className="sobItem">
<div className="descript-title">{group.groupName}</div>
<div className="descriptions-view">

View File

@ -75,7 +75,7 @@ export default class PhoneTemplate extends React.Component {
<div className="sobItemWrapper">
{
salaryItemSet.length > 0 &&
salaryItemSet.map((group, index) => (
_.filter(salaryItemSet, it => (!_.isNil(it) && !_.isEmpty(it))).map((group, index) => (
<div className="sobItem">
<div className="descript-title">{group.groupName}</div>
<div className="descriptions-view">

View File

@ -14,9 +14,10 @@ class AllWithoutPay extends Component {
message.warning(getLabel(543306, "未选择条目"));
return;
}
API.gotoStop(selectedRowKeys).then(({ status, errormsg }) => {
API.gotoStop(selectedRowKeys).then(({ status, data, errormsg }) => {
if (status) {
message.success(getLabel(30700, "操作成功"));
const { msg } = data;
message.info(msg || getLabel(30700, "操作成功"));
refreshList();
} else {
message.error(errormsg || getLabel(30651, "操作失败"));

View File

@ -4,6 +4,7 @@ import ImportModal from "../../../components/importModal";
import * as API from "../../../apis/payrollFiles";
import { Menu, Modal } from "antd";
import "../index.less";
import { convertToUrlString } from "../../../util/url";
const getLabel = WeaLocaleProvider.getLabel;
@ -117,7 +118,7 @@ class ImportMenu extends Component {
};
render() {
const { importType, refreshList, isExtEmp } = this.props;
const { importType, refreshList, isExtEmp, searchItemsValue = {} } = this.props;
const { importParams, previewColumns, previewDataSource } = this.state;
let params = "";
if (importParams.importType === "init" || importParams.importType === "salaryItemAdjust") {
@ -156,8 +157,7 @@ class ImportMenu extends Component {
}}
previewImport={(params) => this.salaryArchivePreview(params)}
importFile={(params) => this.handleImportFile(params)}
templateLink={
"/api/bs/hrmsalary/salaryArchive/downloadTemplate?importType=" + params
templateLink={`/api/bs/hrmsalary/salaryArchive/downloadTemplate?importType=${params}&${convertToUrlString(searchItemsValue)}`
}
visiable={importParams.visible}
onCancel={() => {

View File

@ -31,8 +31,8 @@ import AllWithoutPay from "./components/allWithoutPay";
import BatchSuspendsPay from "./components/batchSuspendsPay";
import SlideModalTitle from "../../components/slideModalTitle";
import SalaryFileViewSlide from "../salaryFile/saralyFileViewSlide";
import ChangeSalaryModal from "../salaryFile/changeSalaryModal";
import { sysinfo } from "../../apis/ruleconfig";
import SalaryArchiveEditAdjLogRecord from "../salaryFile/salaryArchiveEditAdjLogRecord";
import "./index.less";
const getLabel = WeaLocaleProvider.getLabel;
@ -78,7 +78,9 @@ class Index extends Component {
subcompanyIds: ""
},
salaryAdjustmentInfo: {},
changeSalaryVisible: false,
adjLogRecordDialog: {
visible: false, title: "", id: "", salaryArchiveId: ""
},
noPayDate: "",
slideParams: {
visible: false,
@ -422,160 +424,148 @@ class Index extends Component {
const { selectedKey, importType, selectedRowKeys, searchItemsValue, pageInfo } = this.state;
const { taxAgentStore: { showOperateBtn } } = this.props;
if (languageidweaver == "8") {
if (selectedKey === "pending" && showOperateBtn) {
return [
<Dropdown overlay={<ExportMenu selectedKey={selectedKey} selectedRowKeys={selectedRowKeys}
searchItemsValue={searchItemsValue}/>}>
<Button type="primary">{getLabel(17416, "导出")}<i className="icon-coms-down2" style={{
marginLeft: 8,
verticalAlign: "middle"
}}/></Button>
</Dropdown>,
<Dropdown overlay={<Menu>
<Menu.Item>
<div
onClick={() => this.importRef.handleMenuClick({ key: "PENDING" })}>{getLabel(32935, "导入")}</div>
</Menu.Item>
<Menu.Item>
<div onClick={this.allGotoFixed}>{getLabel(543304, "全部设为发薪人员")}</div>
</Menu.Item>
<Menu.Item>
<div
onClick={() => this.handleClick({ key: "batchSet" })}>{getLabel(543305, "批量设为发薪员工")}</div>
</Menu.Item>
<Menu.Item>
<div
onClick={() => this.handleClick({ key: "batchDelete" })}>{getLabel(543186, "批量删除待办")}</div>
</Menu.Item>
</Menu>}>
<Button type="primary" style={{ marginLeft: 8 }}>
{getLabel(17499, "更多")} <Icon type="down"/>
</Button>
</Dropdown>
];
} else if (selectedKey === "fixed" && showOperateBtn) {
return [
<WeaHelpfulTip
width={300}
title={<HelpfulDiv/>}
placement="topLeft"
/>,
<Dropdown overlay={
<ImportMenu
importType={importType}
refreshList={() => {
this.query();
this.setState({ selectedRowKeys: [] });
}}/>
}>
<Button type="primary">{getLabel(32935, "导入")}<i className="icon-coms-down2" style={{
marginLeft: 8,
verticalAlign: "middle"
}}/></Button>
</Dropdown>,
<Dropdown overlay={<ExportMenu selectedKey={selectedKey} selectedRowKeys={selectedRowKeys}
searchItemsValue={searchItemsValue}/>}>
<Button type="primary">{getLabel(17416, "导出")}<i className="icon-coms-down2" style={{
marginLeft: 8,
verticalAlign: "middle"
}}/></Button>
</Dropdown>
];
} else if (selectedKey === "suspend" && showOperateBtn) {
return [
<Dropdown overlay={
<AllWithoutPay
pageInfo={pageInfo}
selectedRowKeys={selectedRowKeys}
refreshList={() => {
this.queryTabTotal();
this.query();
this.setState({ selectedRowKeys: [] });
}}
/>
}>
<Button type="primary" style={{ marginLeft: 8 }}>{getLabel(543326, "全部停薪")}<i
className="icon-coms-down2"
style={{
marginLeft: 8,
verticalAlign: "middle"
}}/></Button>
</Dropdown>,
<Dropdown overlay={<ExportMenu selectedKey={selectedKey} selectedRowKeys={selectedRowKeys}
searchItemsValue={searchItemsValue}/>}>
<Button type="primary">{getLabel(17416, "导出")}<i className="icon-coms-down2" style={{
marginLeft: 8,
verticalAlign: "middle"
}}/></Button>
</Dropdown>,
<Dropdown overlay={<Menu>
<Menu.Item>
<div onClick={() => {
const { selectedRowKeys } = this.state;
if (selectedRowKeys.length === 0) {
message.warning(getLabel(543306, "未选择条目"));
return;
}
this.deleteSuspendTodo(selectedRowKeys);
}}>{getLabel(543186, "批量删除待办")}</div>
</Menu.Item>
<Menu.Item>
<div onClick={() => this.importRef.handleMenuClick({ key: "SUSPEND" })}>{getLabel(32935, "导入")}</div>
</Menu.Item>
</Menu>}>
<Button type="primary" style={{ marginLeft: 8 }}>
{getLabel(17499, "更多")} <Icon type="down"/>
</Button>
</Dropdown>
];
} else if (selectedKey === "stop" && showOperateBtn) {
return [
<Dropdown overlay={
<BatchSuspendsPay
selectedRowKeys={selectedRowKeys}
refreshList={() => {
this.queryTabTotal();
this.query();
this.setState({ selectedRowKeys: [] });
}}
/>
}>
<Button type="primary">{getLabel(543307, "批量取消停薪")}<i className="icon-coms-down2" style={{
marginLeft: 8,
verticalAlign: "middle"
}}/></Button>
</Dropdown>,
<Dropdown overlay={<ExportMenu selectedKey={selectedKey} selectedRowKeys={selectedRowKeys}
searchItemsValue={searchItemsValue}/>}>
<Button type="primary">{getLabel(17416, "导出")}<i className="icon-coms-down2" style={{
marginLeft: 8,
verticalAlign: "middle"
}}/></Button>
</Dropdown>
];
} else if (selectedKey === "ext" && showOperateBtn) {
return [
<WeaHelpfulTip
width={300}
title={<HelpfulDiv/>}
placement="topLeft"
/>,
<Dropdown overlay={
<ImportMenu
isExtEmp importType={importType}
refreshList={() => {
this.query();
this.setState({ selectedRowKeys: [] });
}}/>
}>
<Button type="primary">{getLabel(32935, "导入")}<i className="icon-coms-down2" style={{
marginLeft: 8,
verticalAlign: "middle"
}}/></Button>
</Dropdown>
];
}
return [];
if (selectedKey === "pending" && showOperateBtn) {
return [
<Button type="primary" onClick={() => {
this.importRef.handleMenuClick({ key: "PENDING" });
}}>导入</Button>,
<Dropdown overlay={<ExportMenu selectedKey={selectedKey} selectedRowKeys={selectedRowKeys}
searchItemsValue={searchItemsValue}/>}>
<Button type="primary">{getLabel(17416, "导出")}<i className="icon-coms-down2" style={{
marginLeft: 8,
verticalAlign: "middle"
}}/></Button>
</Dropdown>,
<Button type="ghost" onClick={this.allGotoFixed}>{getLabel(543304, "全部设为发薪人员")}</Button>,
<Dropdown
overlay={
<Menu className="dropdownMenuWrapper" onClick={this.handleClick}>
<Menu.Item key="batchSet">{getLabel(543305, "批量设为发薪员工")}</Menu.Item>
<Menu.Item key="batchDelete">{getLabel(543186, "批量删除待办")}</Menu.Item>
</Menu>
}
>
<Button type="primary">{getLabel(17499, "更多")} <i className="icon-coms-down2" style={{
marginLeft: 8,
verticalAlign: "middle"
}}/></Button>
</Dropdown>
];
} else if (selectedKey === "fixed" && showOperateBtn) {
return [
<WeaHelpfulTip
width={300}
title={<HelpfulDiv/>}
placement="topLeft"
/>,
<Dropdown overlay={
<ImportMenu
importType={importType}
searchItemsValue={searchItemsValue}
refreshList={() => {
this.query();
this.setState({ selectedRowKeys: [] });
}}/>
}>
<Button type="primary">{getLabel(32935, "导入")}<i className="icon-coms-down2" style={{
marginLeft: 8,
verticalAlign: "middle"
}}/></Button>
</Dropdown>,
<Dropdown overlay={<ExportMenu selectedKey={selectedKey} selectedRowKeys={selectedRowKeys}
searchItemsValue={searchItemsValue}/>}>
<Button type="primary">{getLabel(17416, "导出")}<i className="icon-coms-down2" style={{
marginLeft: 8,
verticalAlign: "middle"
}}/></Button>
</Dropdown>
];
} else if (selectedKey === "suspend" && showOperateBtn) {
return [
<Dropdown overlay={
<AllWithoutPay
pageInfo={pageInfo}
selectedRowKeys={selectedRowKeys}
refreshList={() => {
this.queryTabTotal();
this.query();
this.setState({ selectedRowKeys: [] });
}}
/>
}>
<Button type="primary" style={{ marginLeft: 8 }}>{getLabel(543326, "全部停薪")}<i className="icon-coms-down2" style={{
marginLeft: 8,
verticalAlign: "middle"
}}/></Button>
</Dropdown>,
<Button type="ghost" onClick={() => {
const { selectedRowKeys } = this.state;
if (selectedRowKeys.length === 0) {
message.warning({getLabel(543306, "未选择条目")});
return;
}
this.deleteSuspendTodo(selectedRowKeys);
}}>批量删除待办</Button>,
<Button type="primary" onClick={() => {
this.importRef.handleMenuClick({ key: "SUSPEND" });
}}>导入</Button>,
<Dropdown overlay={<ExportMenu selectedKey={selectedKey} selectedRowKeys={selectedRowKeys}
searchItemsValue={searchItemsValue}/>}>
<Button type="primary">{getLabel(17416, "导出")}<i className="icon-coms-down2" style={{
marginLeft: 8,
verticalAlign: "middle"
}}/></Button>
</Dropdown>
];
} else if (selectedKey === "stop" && showOperateBtn) {
return [
<Dropdown overlay={
<BatchSuspendsPay
selectedRowKeys={selectedRowKeys}
refreshList={() => {
this.queryTabTotal();
this.query();
this.setState({ selectedRowKeys: [] });
}}
/>
}>
<Button type="primary">{getLabel(543307, "批量取消停薪")}<i className="icon-coms-down2" style={{
marginLeft: 8,
verticalAlign: "middle"
}}/></Button>
</Dropdown>,
<Dropdown overlay={<ExportMenu selectedKey={selectedKey} selectedRowKeys={selectedRowKeys}
searchItemsValue={searchItemsValue}/>}>
<Button type="primary">{getLabel(17416, "导出")}<i className="icon-coms-down2" style={{
marginLeft: 8,
verticalAlign: "middle"
}}/></Button>
</Dropdown>
];
} else if (selectedKey === "ext" && showOperateBtn) {
return [
<WeaHelpfulTip
width={300}
title={<HelpfulDiv/>}
placement="topLeft"
/>,
<Dropdown overlay={
<ImportMenu
isExtEmp importType={importType}
searchItemsValue={searchItemsValue}
refreshList={() => {
this.query();
this.setState({ selectedRowKeys: [] });
}}/>
}>
<Button type="primary">{getLabel(32935, "导入")}<i className="icon-coms-down2" style={{
marginLeft: 8,
verticalAlign: "middle"
}}/></Button>
</Dropdown>
];
}
return [];
} else {
if (selectedKey === "pending" && showOperateBtn) {
return [
@ -806,7 +796,12 @@ class Index extends Component {
}
if (showOperateBtn && (selectedKey === "fixed" || selectedKey === "ext")) {
arrList.push(<Button type="primary" onClick={() => {
this.setState({ changeSalaryVisible: true });
this.setState({
adjLogRecordDialog: {
...this.state.adjLogRecordDialog,
visible: true, title: getLabel(542686, "调薪"), salaryArchiveId: this.state.slideParams.id
}
});
}}>{getLabel(542686, "调薪")}</Button>);
}
selectedKey !== "stop" && arrList.push(<Button type="primary"
@ -902,7 +897,7 @@ class Index extends Component {
pageInfo,
showSearchAd,
slideParams,
changeSalaryVisible,
adjLogRecordDialog,
paysetParams,
extEmpsWitch
} = this.state;
@ -1023,6 +1018,7 @@ class Index extends Component {
<div style={{ display: "none" }}>
<ImportMenu
ref={(dom) => this.importRef = dom}
searchItemsValue={this.state.searchItemsValue}
refreshList={() => {
this.query();
this.setState({ selectedRowKeys: [] });
@ -1070,15 +1066,14 @@ class Index extends Component {
}}
/>
)}
{changeSalaryVisible && (
<ChangeSalaryModal
currentId={slideParams.id}
visible={changeSalaryVisible}
onCancel={() => {
this.setState({ changeSalaryVisible: false });
}}
/>
)}
<SalaryArchiveEditAdjLogRecord
{...adjLogRecordDialog}
onCancel={() => this.setState({
adjLogRecordDialog: {
adjLogRecordDialog, visible: false, title: "", id: "", salaryArchiveId: ""
}
})}
/>
</div>
);
}

View File

@ -152,6 +152,195 @@ export const condition = [
defaultshow: true
}
];
export const shareCondition = [
{
items: [
{
colSpan: 1,
checkbox: false,
checkboxValue: false,
conditionType: "SELECT",
domkey: ["reportIds"],
fieldcol: 12,
label: "分享报表",
lanId: 111,
labelcol: 6,
options: [],
multiple: true,
rules: "required|string",
viewAttr: 3
},
{
colSpan: 1,
checkbox: false,
checkboxValue: false,
conditionType: "INPUT",
domkey: ["pushTitle"],
fieldcol: 18,
label: "主题",
lanId: 111,
labelcol: 6,
rules: "required|string",
viewAttr: 3
},
{
browserConditionParam: {
completeParams: {},
conditionDataParams: {},
dataParams: {},
destDataParams: {},
hasAddBtn: false,
hasAdvanceSerach: true,
idSeparator: ",",
isAutoComplete: 1,
isDetail: 0,
isMultCheckbox: false,
isSingle: false,
linkUrl: "",
pageSize: 10,
quickSearchName: "",
replaceDatas: [],
type: "17",
viewAttr: 3
},
colSpan: 1,
conditionType: "BROWSER",
domkey: ["sharedBy"],
fieldcol: 14,
isQuickSearch: false,
label: "被分享人",
lanId: 111,
labelcol: 6,
rules: "required|string",
viewAttr: 3
},
{
colSpan: 2,
conditionType: "DATEPICKER",
domkey: ["startTime"],
fieldcol: 12,
label: "报表查看有效开始时间",
lanId: 111,
labelcol: 6,
value: "",
viewAttr: 2
},
{
colSpan: 2,
conditionType: "DATEPICKER",
domkey: ["endTime"],
fieldcol: 12,
label: "报表查看有效结束时间",
lanId: 111,
labelcol: 6,
value: "",
viewAttr: 2
},
{
colSpan: 1,
checkbox: false,
checkboxValue: false,
conditionType: "INPUT",
domkey: ["mark"],
fieldcol: 18,
label: "分享说明",
lanId: 111,
labelcol: 6,
viewAttr: 2
}
// {
// colSpan: 1,
// conditionType: "SWITCH",
// domkey: ["remind"],
// fieldcol: 12,
// isQuickSearch: false,
// label: "已查看提醒",
// lanId: 111,
// labelcol: 6,
// viewAttr: 2
// }
],
title: "",
defaultshow: true
}
];
export const sharePersonCondition = [
{
items: [
{
browserConditionParam: {
completeParams: {},
conditionDataParams: {},
dataParams: {},
destDataParams: {},
hasAddBtn: false,
hasAdvanceSerach: true,
idSeparator: ",",
isAutoComplete: 1,
isDetail: 0,
isMultCheckbox: false,
isSingle: false,
linkUrl: "",
pageSize: 10,
quickSearchName: "",
replaceDatas: [],
type: "17",
viewAttr: 3
},
colSpan: 1,
conditionType: "BROWSER",
domkey: ["sharedBy"],
fieldcol: 14,
isQuickSearch: false,
label: "被分享人",
lanId: 111,
labelcol: 6,
rules: "required|string",
viewAttr: 3
}
],
title: "",
defaultshow: true
}
];
export const shareLogCondition = [
{
items: [
{
colSpan: 1,
conditionType: "INPUT",
domkey: ["reportName"],
fieldcol: 12,
label: "分享报表",
lanId: 111,
labelcol: 6,
viewAttr: 1
},
{
colSpan: 1,
conditionType: "INPUT",
domkey: ["effectiveTime"],
fieldcol: 12,
label: "报表查看有效时间",
lanId: 111,
labelcol: 6,
viewAttr: 1
},
{
colSpan: 1,
conditionType: "INPUT",
domkey: ["remark"],
fieldcol: 12,
label: "分享说明",
lanId: 111,
labelcol: 6,
viewAttr: 1
}
],
title: "",
defaultshow: true
}
];
const colorList = ["#709DF7", "#73DEB3", "#7585A2", "#F7C739", "#5FC3E3", "#AEE279", "#FF7F81"];
export const mapBarOptions = (params) => ({
@ -292,7 +481,7 @@ export const mapBarOptions = (params) => ({
{
type: "slider",
show: true,
bottom: 20,
bottom: 20
}
]
});

View File

@ -269,7 +269,7 @@ class CustomStatisticsItemsModal extends Component {
render() {
const { loading, columns, dataSource, formData } = this.state;
const { itemName, itemValue, itemValueSpan } = formData;
const { statisticsItemId } = this.props;
const { statisticsItemId, isShare } = this.props;
const cols = _.map(columns, it => {
const { text, column } = it;
if (column === "ruleName" || column === "ratio" || column === "m2m" || column === "y2y") {
@ -278,6 +278,7 @@ class CustomStatisticsItemsModal extends Component {
...it,
title: <span>
<WeaCheckbox
disabled={isShare}
value={_.every(dataSource, child => !!child[`${key}Value`])}
onChange={val => this.handleChangeColumnAllChecked(`${key}Value`, val)}
/>
@ -286,6 +287,7 @@ class CustomStatisticsItemsModal extends Component {
render: (txt, record) => {
return <span>
<WeaCheckbox
disabled={isShare}
value={record[`${key}Value`].toString()}
onChange={val => this.handleChangeColumnCheckBox(`${key}Value`, val, record.id)}
/>
@ -305,6 +307,7 @@ class CustomStatisticsItemsModal extends Component {
</span>,
render: (txt, record) => {
return !!record["m2mValue"] && <IntervalSettingsComp
isShare={isShare}
LowerLimit={record[`${column.replace("Limit", "")}LowerLimit`]}
UpperLimit={record[`${column.replace("Limit", "")}UpperLimit`]}
onChange={(type, val) => this.handleChangeColumnM2MValue(`${column.replace("Limit", "")}${type === "min" ? "LowerLimit" : "UpperLimit"}`, val, record.id)}
@ -321,6 +324,7 @@ class CustomStatisticsItemsModal extends Component {
</span>,
render: (txt, record) => {
return !!record["y2yValue"] && <IntervalSettingsComp
isShare={isShare}
LowerLimit={record[`${column.replace("Limit", "")}LowerLimit`]}
UpperLimit={record[`${column.replace("Limit", "")}UpperLimit`]}
onChange={(type, val) => this.handleChangeColumnM2MValue(`${column.replace("Limit", "")}${type === "min" ? "LowerLimit" : "UpperLimit"}`, val, record.id)}
@ -348,7 +352,7 @@ class CustomStatisticsItemsModal extends Component {
<WeaBrowser
title={getLabel(386275, "统计项目")}
type={162}
viewAttr={3}
viewAttr={!isShare ? 3 : 1}
isSingle={false}
value={itemValue}
replaceDatas={itemValue ? _.map(itemValue.split(","), (it, idx) => ({
@ -406,7 +410,7 @@ export default CustomStatisticsItemsModal;
* Date: 2023/4/23
*/
const IntervalSettingsComp = (props) => {
const { LowerLimit, UpperLimit, onChange } = props;
const { LowerLimit, UpperLimit, onChange, isShare } = props;
return <div className="intervalSettingsCompWrapper">
<WeaInputNumber value={LowerLimit} precision={2} onChange={val => onChange("min", val)}/>
<span className="increaseTitle">{`% <${getLabel(543394, "增幅")}<`}</span>

View File

@ -63,3 +63,134 @@
height: 100%;
}
}
.shareDialogWrapper {
.wea-dialog-body {
background: #f6f6f6;
overflow-y: hidden;
}
.wea-search-group {
border: 1px solid #e5e5e5;
border-bottom: none;
background: #FFF;
}
.wea-search-group, .wea-content, .wea-form-cell {
padding: 0;
}
.wea-form-item {
padding: 8px 16px;
border-bottom: 1px solid #e5e5e5;
}
.wea-select, .ant-select, .ant-select-selection {
width: 100%;
}
.wea-select .wea-select-input .arrow {
position: absolute;
right: 4px;
top: 8px;
color: #666;
}
.wea-select .wdb {
word-break: break-all !important;
word-wrap: break-word !important;
}
.wea-select .wea-select-input {
height: 30px;
white-space: nowrap;
min-width: 100px;
max-width: 345px;
width: 100%;
display: inline-block;
padding: 4px 17px 4px 4px;
position: relative;
min-height: 30px;
border: 1px solid #d9d9d9;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
-o-text-overflow: ellipsis;
text-overflow: ellipsis;
overflow: hidden;
}
.shareLogGroupWrapper {
margin-top: 16px;
.logtitleHeader {
display: flex;
align-items: center;
justify-content: space-between;
.right {
display: flex;
align-items: center;
}
}
}
}
.shareRecordWrapper {
z-index: 111;
.wea-slide-modal-title {
height: auto !important;
line-height: normal !important;
}
.titleDialog {
display: flex;
padding: 10px 16px 10px 0;
position: relative;
background-color: #FFF;
border-bottom: 1px solid #e5e5e5;
.titleCol {
flex: 1;
.titleLeftBox {
display: flex;
height: 100%;
align-items: center;
padding-left: 16px;
.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;
}
}
}
}
.ant-table-tbody {
& > tr {
& > td {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
}
}
}

View File

@ -35,8 +35,8 @@ class PovitpivotChartModal extends Component {
componentWillReceiveProps(nextProps, nextContext) {
if (nextProps.visible !== this.props.visible && nextProps.visible) {
const { id, dimensionId, dimensionValue } = nextProps;
this.getDataPerspective({ id, dimensionId, dimensionValue });
const { id, dimensionId, dimensionValue, isShare } = nextProps;
this.getDataPerspective({ id, dimensionId, dimensionValue, isShare });
} else {
this.setState({
dataSource: [],
@ -63,13 +63,11 @@ class PovitpivotChartModal extends Component {
});
} else if (type === "turn") {
if (id === "PAGEINFO") {
const { id, dimensionId, dimensionValue } = this.props;
const { id, dimensionId, dimensionValue, isShare } = this.props;
const { pageNum: current, size: pageSize } = params;
this.setState({ pageInfo: { ...pageInfo, current, pageSize } }, () =>
this.getDataPerspective({
id,
dimensionId,
dimensionValue
id, dimensionId, dimensionValue, isShare
}));
}
}

View File

@ -28,7 +28,7 @@ class ReportContent extends Component {
chartsType: "0",
chartsInfo: {},
povitView: {
visible: false, id: "",
visible: false, id: "", isShare: false,
dimensionId: "", dimensionValue: ""
},
rangSet: {
@ -45,7 +45,7 @@ class ReportContent extends Component {
componentWillReceiveProps(nextProps, nextContext) {
if (nextProps.report !== this.props.report && nextProps.report.dimensionId) {
this.reportStatisticsReportGetData(nextProps.report.id, nextProps.report.dimensionId);
this.reportStatisticsReportGetData(nextProps.report.id, nextProps.report.dimensionId, nextProps.report.isShare);
this.setState({ viewType: "dataView", chartsInfo: {} });
}
}
@ -67,10 +67,10 @@ class ReportContent extends Component {
if (id === "PIVOTCHART") {
const { record } = params;
const { dimension: dimensionValue } = record;
const { id: pivotId, dimensionId } = this.props.report;
const { id: pivotId, dimensionId, isShare } = this.props.report;
this.setState({
povitView: {
visible: true, id: pivotId, dimensionId, dimensionValue
visible: true, id: pivotId, dimensionId, dimensionValue, isShare
}
});
}
@ -106,8 +106,8 @@ class ReportContent extends Component {
dataSource, columns, showSum, countResult, i18n
}), "*");
};
reportStatisticsReportGetData = (id, dimensionId) => {
const payload = { id, dimensionId };
reportStatisticsReportGetData = (id, dimensionId, isShare) => {
const payload = { id, dimensionId, isShare };
this.setState({ loading: true });
reportStatisticsReportGetData(payload).then(({ status, data }) => {
this.setState({ loading: false });
@ -216,13 +216,13 @@ class ReportContent extends Component {
handleChangeChartOpts = (chartsType, viewType) => {
this.setState({ chartsInfo: {} });
if (this.refs.chart && viewType !== "setting" && viewType !== "dataView" && !this.state.rangSet.visible) this.refs.chart.clear();
const { report: { id: reportId, dimensionId } } = this.props;
const { report: { id: reportId, dimensionId, isShare } } = this.props;
const { rangSet } = this.state;
viewType !== "setting" && this.setState({ chartsType, viewType }, () => {
const { viewType, chartsType } = this.state;
viewType !== "dataView" ?
this.queryRangeSetting({ reportId, chartsType }, true) :
this.reportStatisticsReportGetData(reportId, dimensionId);
this.reportStatisticsReportGetData(reportId, dimensionId, isShare);
});
viewType === "setting" && this.setState({ rangSet: { ...rangSet, visible: true, reportId } }, () => {
this.queryRangeSetting({ reportId, chartsType });
@ -238,8 +238,8 @@ class ReportContent extends Component {
};
handleGetData = () => {
const { report } = this.props;
const { id, dimensionId } = report;
this.setState({ viewType: "dataView" }, () => this.reportStatisticsReportGetData(id, dimensionId));
const { id, dimensionId, isShare } = report;
this.setState({ viewType: "dataView" }, () => this.reportStatisticsReportGetData(id, dimensionId, isShare));
};
renderCharts = () => {
const { chartsInfo, viewType } = this.state;
@ -254,6 +254,8 @@ class ReportContent extends Component {
render() {
const { loading, viewType, rangSet, columns, povitView } = this.state;
const { report } = this.props;
const { isShare } = report;
return (
<div className="layoutContent">
<div className="layoutBox">
@ -270,7 +272,7 @@ class ReportContent extends Component {
</Spin>
</div>
{/*侧边栏*/}
<RightOptions onChange={this.handleChangeChartOpts}/>
<RightOptions isShare={isShare} onChange={this.handleChangeChartOpts}/>
{/* 图表范围数据设置框 */}
<ChartsRangeSettingsModal
{...rangSet}
@ -284,7 +286,8 @@ class ReportContent extends Component {
{...povitView}
onCancel={() => this.setState({
povitView: {
visible: false, id: "", dimensionId: "", dimensionValue: ""
visible: false, id: "", dimensionId: "", dimensionValue: "",
isShare: false
}
})}
/>

View File

@ -19,7 +19,7 @@ class RightOptions extends Component {
}
render() {
const { onChange } = this.props;
const { onChange, isShare } = this.props;
const { show } = this.state;
return (
<div className="layoutSide" style={{ width: show ? "30px" : 0 }}>
@ -32,8 +32,11 @@ class RightOptions extends Component {
onClick={() => onChange("1", "bar")}/>
<i className="icon-coms-Line" title={getLabel(32615, "折线图")} onClick={() => onChange("2", "line")}/>
<i className="icon-coms-Pie" title={getLabel(84377, "饼图")} onClick={() => onChange("0", "pie")}/>
<i className="icon-coms-Flow-setting" title={getLabel(30747, "设置")}
onClick={() => onChange("1", "setting")}/>
{
!isShare &&
<i className="icon-coms-Flow-setting" title={getLabel(30747, "设置")}
onClick={() => onChange("1", "setting")}/>
}
</div>
</div>
<span className="show-btn-right"

View File

@ -0,0 +1,139 @@
/*
* Author: 黎永顺
* name: 分享记录
* Description:
* Date: 2023/9/19
*/
import React, { Component } from "react";
import { inject, observer } from "mobx-react";
import { WeaDialog, WeaLocaleProvider, WeaTools } from "ecCom";
import { Button, message } from "antd";
import { shareCondition } from "./condition";
import { getSearchs } from "../../../util";
import { salaryStatisticsPushGetForm, salaryStatisticsPushSendMsg } from "../../../apis/statistics";
import "./index.less";
const getKey = WeaTools.getKey;
const { getLabel } = WeaLocaleProvider;
@inject("attendanceStore")
@observer
class SalaryStatisticsDetailShareDialog extends Component {
constructor(props) {
super(props);
this.state = {
conditions: [], loading: false
};
}
componentWillReceiveProps(nextProps, nextContext) {
const { attendanceStore: { initShareForm } } = nextProps;
if (nextProps.visible !== this.props.visible && nextProps.visible) {
this.salaryStatisticsPushGetForm(nextProps);
} else {
initShareForm();
}
}
salaryStatisticsPushGetForm = (props) => {
const { attendanceStore: { shareForm } } = props;
salaryStatisticsPushGetForm().then(({ status, data }) => {
if (status) {
const { reportOptions } = data;
this.setState({
conditions: _.map(shareCondition, item => {
return {
...item,
items: _.map(item.items, o => {
if (getKey(o) === "sharedBy") {
return {
...o,
helpfulTitle: getLabel(111, "被分享人收到您分享的报表后,会默认赋予您的数据权限,但还需要有【薪酬统计分析】的菜单权限才可以查看报表。菜单权限设置路径:后台管理中心-【权限管理中心】-【角色设置】,建议创建一个仅查看报表的角色,这个角色只有薪酬管理模块的【薪酬统计分析】菜单权限。\n" +
"为了避免所选的人同名导致选错人,可在后台管理中心-【组织架构设置】-【浏览框显示字段定义】中人员浏览框的显示字段多勾选几个能区别人员的字段")
};
} else if (getKey(o) === "startTime__endTime") {
return {
...o,
helpfulTitle: getLabel(111, "有效时间之外,被分享人无法查看您分享的报表")
};
} else if (getKey(o) === "remind") {
return {
...o,
helpfulTitle: getLabel(111, "开启后,被分享人查看报表时,系统自动通过系统消息提醒分享人。")
};
} else if (getKey(o) === "reportIds") {
return {
...o,
options: _.map(reportOptions, it => ({ key: it.id, showname: it.reportName }))
};
}
return { ...o };
})
};
})
}, () => {
shareForm.initFormFields(this.state.conditions);
shareForm.updateFields({ pushTitle: data["pushTitle"] || "" });
shareForm.updateFields({ mark: data["mark"] || "" });
});
}
});
};
salaryStatisticsPushSendMsg = () => {
const { attendanceStore: { shareForm } } = this.props;
shareForm.validateForm().then(f => {
if (f.isValid) {
const { sharedBy, reportIds, ...extraFormparams } = shareForm.getFormParams();
const payload = {
sharedBy: sharedBy.split(","),
reportIds: reportIds.split(","),
...extraFormparams
};
this.setState({ loading: true });
salaryStatisticsPushSendMsg(payload).then(({ status, errormsg }) => {
this.setState({ loading: false });
if (status) {
message.success(getLabel(111, "分享成功"));
this.props.onCancel();
} else {
message.error(errormsg);
}
}).catch(() => this.setState({ loading: false }));
} else {
f.showErrors();
}
});
};
render() {
const { attendanceStore: { shareForm } } = this.props;
const { conditions, loading } = this.state;
return (
<WeaDialog
{...this.props}
hasScroll initLoadCss title={getLabel(111, "分享报表")}
buttons={[
<Button type="primary" onClick={this.salaryStatisticsPushSendMsg}
loading={loading}>{getLabel(111, "确认分享")}</Button>
]}
className="shareDialogWrapper"
style={{
width: 750,
height: 375.6,
minHeight: 200,
minWidth: 380,
maxHeight: "60%",
maxWidth: "60%",
overflow: "hidden",
transform: "translate(0px, 0px)"
}}
>
<div style={{ padding: 16, overflowY: "auto" }}>
{getSearchs(shareForm, conditions, 1, false)}
</div>
</WeaDialog>
);
}
}
export default SalaryStatisticsDetailShareDialog;

View File

@ -0,0 +1,189 @@
/*
* Author: 黎永顺
* name: 分享记录-查看分享记录详情
* Description:
* Date: 2023/9/19
*/
import React, { Component } from "react";
import { inject, observer } from "mobx-react";
import {
WeaButtonIcon,
WeaDialog,
WeaHelpfulTip,
WeaInputSearch,
WeaLocaleProvider,
WeaSearchGroup,
WeaTable,
WeaTools
} from "ecCom";
import { message, Modal } from "antd";
import { shareLogCondition } from "./condition";
import { getConditionDomkeys, getSearchs } from "../../../util";
import { salaryStatisticsPushcancel, salaryStatisticsPushGetDetail } from "../../../apis/statistics";
import SalaryStatisticsDetailSharePersonDialog from "./salaryStatisticsDetailSharePersonDialog";
import "./index.less";
const getKey = WeaTools.getKey;
const { getLabel } = WeaLocaleProvider;
@inject("attendanceStore")
@observer
class SalaryStatisticsDetailShareLogDialog extends Component {
constructor(props) {
super(props);
this.state = {
conditions: [], loading: false, dataSource: [], columns: [],
userNameSearch: "", sharePerDialog: { visible: false, id: "" }
};
}
componentWillReceiveProps(nextProps, nextContext) {
const { attendanceStore: { initShareLogForm } } = nextProps;
if (nextProps.visible !== this.props.visible && nextProps.visible) {
this.salaryStatisticsPushGetDetail(nextProps);
} else if (nextProps.visible !== this.props.visible && !nextProps.visible) {
initShareLogForm();
}
}
renderShareLogTitle = () => {
return <div className="logtitleHeader">
<div className="titleText">
<span style={{ marginRight: 10 }}>{getLabel(111, "被分享人")}</span>
<WeaHelpfulTip width={200} placement="topLeft"
title={getLabel(111, "被分享人收到您分享的报表后,会默认赋予您的数据权限,但还需要有【薪酬统计分析】的菜单权限才可以查看报表。菜单权限设置路径:后台管理中心-【权限管理中心】-【角色设置】,建议创建一个仅查看报表的角色,这个角色只有薪酬管理模块的【薪酬统计分析】菜单权限。\n" +
"为了避免所选的人同名导致选错人,可在后台管理中心-【组织架构设置】-【浏览框显示字段定义】中人员浏览框的显示字段多勾选几个能区别人员的字段")}
/>
</div>
<div className="right">
<WeaButtonIcon buttonType="add" type="primary" style={{ marginRight: 10 }}
onClick={() => this.setState({
sharePerDialog: {
...this.state.sharePerDialog,
visible: true, id: this.props.id
}
})}/>
<WeaInputSearch value={this.state.userNameSearch} onChange={v => this.setState({ userNameSearch: v })}
onSearch={() => this.salaryStatisticsPushGetDetail(this.props)}
/>
</div>
</div>;
};
salaryStatisticsPushGetDetail = (props) => {
const { userNameSearch } = this.state;
const { attendanceStore: { shareLogForm }, id } = props;
this.setState({ loading: true });
salaryStatisticsPushGetDetail({ id, userNameSearch }).then(({ status, data }) => {
this.setState({ loading: false });
if (status) {
const { detailForm, detailTable } = data;
const { columns, list: dataSource } = detailTable;
this.setState({
columns, dataSource,
conditions: _.map(shareLogCondition, item => {
return {
...item,
items: _.map(item.items, o => {
if (getKey(o) === "effectiveTime") {
return {
...o,
helpfulTitle: getLabel(111, "有效时间之外,被分享人无法查看您分享的报表")
};
}
return { ...o };
})
};
})
}, () => {
shareLogForm.initFormFields(this.state.conditions);
getConditionDomkeys(this.state.conditions).map(key => {
shareLogForm.updateFields({
[key]: detailForm[key] || ""
});
});
});
}
}).catch(() => this.setState({ loading: false }));
};
salaryStatisticsPushcancel = (id) => {
Modal.confirm({
title: getLabel(131329, "信息确认"),
content: getLabel(111, "确定要全部撤回吗?"),
onOk: () => {
salaryStatisticsPushcancel({ id }).then(({ status, errormsg }) => {
if (status) {
message.success(getLabel(505793, "撤回成功!"));
this.salaryStatisticsPushGetDetail(this.props);
this.props.onGetTable();
} else {
message.error(errormsg);
}
});
}
});
};
render() {
const { attendanceStore: { shareLogForm } } = this.props;
const { conditions, dataSource, columns, loading, sharePerDialog } = this.state;
return (
<WeaDialog
{...this.props}
hasScroll initLoadCss title={getLabel(111, "查看分享记录详情")}
className="shareDialogWrapper"
style={{
width: 850,
height: 506.6,
minHeight: 200,
minWidth: 380,
maxHeight: "60%",
maxWidth: "60%",
overflow: "hidden",
transform: "translate(0px, 0px)"
}}
>
<div style={{ padding: 16, overflowY: "auto" }}>
{getSearchs(shareLogForm, conditions, 1, false)}
<WeaSearchGroup title={this.renderShareLogTitle()} showGroup needTigger className="shareLogGroupWrapper">
<WeaTable
rowKey="id" dataSource={dataSource} pagination={false} loading={loading}
columns={[
...columns,
{
dataIndex: "operate",
width: 120,
title: <React.Fragment>
<span style={{ marginRight: 10 }}>{getLabel(30585, "操作")}</span>
<WeaHelpfulTip width={200} placement="topLeft"
title={
<div>
<p>{getLabel(111, "1、分享状态为成功且撤回状态为空时可操作撤回")}</p>
{/*<p>{getLabel(111, "2、撤回后不可重新分享")}</p>*/}
{/*<p>{getLabel(111, "3、分享状态为失败可操作重新分享")}</p>*/}
{/*<p>{getLabel(111, "4、重新分享以当前分享记录的分享报表、有效时间、渠道和说明重新分享分享后自动刷新分享时间和分享状态")}</p>*/}
</div>
}
/>
</React.Fragment>,
render: (__, record) => (_.isEmpty(record.rebackStatus) ?
<a href="javascript:void(0);"
onClick={() => this.salaryStatisticsPushcancel(record.id)}>{getLabel(32025, "撤回")}</a> : null)
}
]}
/>
<SalaryStatisticsDetailSharePersonDialog
{...sharePerDialog}
onCancel={() => this.setState({ sharePerDialog: { ...sharePerDialog, visible: false, id: "" } })}
onGetTable={() => {
this.salaryStatisticsPushGetDetail(this.props);
this.props.onGetTable();
}}
/>
</WeaSearchGroup>
</div>
</WeaDialog>
);
}
}
export default SalaryStatisticsDetailShareLogDialog;

View File

@ -0,0 +1,74 @@
import React, { Component } from "react";
import { inject, observer } from "mobx-react";
import { WeaDialog, WeaLocaleProvider } from "ecCom";
import { Button, message } from "antd";
import { salaryStatisticsPushAddSharedSendMsg } from "../../../apis/statistics";
import { sharePersonCondition } from "./condition";
import { getSearchs } from "../../../util";
import "./index.less";
const { getLabel } = WeaLocaleProvider;
@inject("attendanceStore")
@observer
class SalaryStatisticsDetailSharePersonDialog extends Component {
constructor(props) {
super(props);
this.state = {
conditions: [], loading: false
};
}
componentWillReceiveProps(nextProps, nextContext) {
const { attendanceStore: { initSharePerForm, sharePerForm } } = nextProps;
if (nextProps.visible !== this.props.visible && nextProps.visible) {
sharePerForm.initFormFields(sharePersonCondition);
} else {
initSharePerForm();
}
}
save = () => {
const { attendanceStore: { sharePerForm }, id } = this.props;
sharePerForm.validateForm().then(f => {
if (f.isValid) {
const { sharedBy } = sharePerForm.getFormParams();
const payload = {
id, sharedBy: sharedBy.split(",")
};
salaryStatisticsPushAddSharedSendMsg(payload)
.then(({ status, errormsg }) => {
this.setState({ loading: false });
if (status) {
message.success(getLabel(30700, "操作成功!"));
this.props.onCancel();
this.props.onGetTable();
} else {
message.error(errormsg);
}
})
.catch(() => this.setState({ loading: false }));
} else {
f.showErrors();
}
});
};
render() {
const { attendanceStore: { sharePerForm }, loading } = this.props;
return (
<WeaDialog
{...this.props}
hasScroll initLoadCss title={getLabel(111, "追加被分享人")}
buttons={[
<Button type="primary" onClick={this.save} loading={loading}>{getLabel(111, "保存并分享")}</Button>
]}
style={{ width: 600, height: 100 }}
>
{getSearchs(sharePerForm, sharePersonCondition, 1, false)}
</WeaDialog>
);
}
}
export default SalaryStatisticsDetailSharePersonDialog;

View File

@ -0,0 +1,132 @@
/*
* Author: 黎永顺
* name: 统计报表-分享记录
* Description:
* Date: 2023/9/19
*/
import React, { Component } from "react";
import { WeaLocaleProvider, WeaSlideModal, WeaTable } from "ecCom";
import { message, Modal } from "antd";
import { salaryStatisticsPushcancelAll, salaryStatisticsPushGetTable } from "../../../apis/statistics";
import SalaryStatisticsDetailShareLogDialog from "./salaryStatisticsDetailShareLogDialog";
const { getLabel } = WeaLocaleProvider;
class SalaryStatisticsDetailShareRecord extends Component {
constructor(props) {
super(props);
this.state = {
loading: false, dataSource: [], columns: [],
pageInfo: { current: 1, pageSize: 10, total: 0 },
shareLogDialog: {
visible: false, id: ""
}
};
}
componentWillReceiveProps(nextProps, nextContext) {
if (nextProps.visible !== this.props.visible && nextProps.visible) this.salaryStatisticsPushGetTable();
}
salaryStatisticsPushGetTable = () => {
this.setState({ loading: true });
salaryStatisticsPushGetTable({ ...this.state.pageInfo })
.then(({ status, data }) => {
this.setState({ loading: false });
if (status) {
const { columns, list: dataSource, pageNum: current, pageSize, total } = data;
this.setState({
columns, dataSource,
pageInfo: { ...this.state.pageInfo, current, pageSize, total }
});
}
}).catch(() => this.setState({ loading: false }));
};
handleWithdrawAll = (id) => {
Modal.confirm({
title: getLabel(131329, "信息确认"),
content: getLabel(111, "确定要全部撤回吗?"),
onOk: () => {
salaryStatisticsPushcancelAll({ id }).then(({ status, errormsg }) => {
if (status) {
message.success(getLabel(30700, "操作成功!"));
this.salaryStatisticsPushGetTable();
} else {
message.error(errormsg);
}
});
}
});
};
render() {
const { dataSource, columns, loading, pageInfo, shareLogDialog } = this.state;
const pagination = {
...pageInfo,
showTotal: total => `${getLabel(18609, "共")} ${total} ${getLabel(18256, "条")}`,
showQuickJumper: true, showSizeChanger: true,
pageSizeOptions: ["10", "20", "50", "100"],
onShowSizeChange: (current, pageSize) => {
this.setState({
pageInfo: { ...pageInfo, current, pageSize }
}, () => {
this.salaryStatisticsPushGetTable();
});
},
onChange: current => {
this.setState({
pageInfo: { ...pageInfo, current }
}, () => {
this.salaryStatisticsPushGetTable();
});
}
};
return (
<WeaSlideModal
{...this.props} className="shareRecordWrapper"
direction="right" top={0} width={800} height={100}
measureT="%" measureX="px" measureY="%"
title={<div className="titleDialog">
<div className="titleCol">
<div className="titleLeftBox">
<div className="titleIcon"><i className="icon-coms-fa"/></div>
<div className="title">{getLabel(111, "分享记录")}</div>
</div>
</div>
<div></div>
</div>}
content={(
<WeaTable
rowKey="id" dataSource={dataSource} pagination={pagination} loading={loading}
columns={[
...columns,
{
dataIndex: "operate",
width: 150,
title: getLabel(30585, "操作"),
render: (__, record) => (
<React.Fragment>
<a href="javascript:void(0);" style={{ marginRight: 10 }}
onClick={() => this.setState({
shareLogDialog: { visible: true, id: record.id }
})}>{getLabel(111, "查询详情")}</a>
<a href="javascript:void(0);"
onClick={() => this.handleWithdrawAll(record.id)}>{getLabel(111, "全部撤回")}</a>
<SalaryStatisticsDetailShareLogDialog
{...shareLogDialog}
onGetTable={() => this.salaryStatisticsPushGetTable()}
onCancel={() => this.setState({
shareLogDialog: { visible: false, id: "" }
})}
/>
</React.Fragment>
)
}
]}
/>
)}/>
);
}
}
export default SalaryStatisticsDetailShareRecord;

View File

@ -5,7 +5,6 @@
* Date: 2023/4/21
*/
import React, { Component } from "react";
import { toJS } from "mobx";
import {
WeaButtonIcon,
WeaDatePicker,
@ -16,12 +15,12 @@ import {
WeaSearchGroup,
WeaSelect,
WeaSlideModal,
WeaTable
WeaTable,
WeaTools
} from "ecCom";
import CustomStatisticsItemsModal from "./customStatisticsItemsModal";
import moment from "moment";
import { Button, message, Modal } from "antd";
import { condition } from "./condition";
import { getSearchs } from "../../../util";
import {
deleteRangeSetting,
@ -31,8 +30,11 @@ import {
statisticsItemList
} from "../../../apis/statistics";
import { commonEnumList } from "../../../apis/ruleconfig";
import { getTaxAgentSelectList } from "../../../apis/taxAgent";
import { condition } from "./condition";
import "../index.less";
const getKey = WeaTools.getKey;
const { getLabel } = WeaLocaleProvider;
class StatisticalMicroSettingsSlide extends Component {
@ -47,32 +49,14 @@ class StatisticalMicroSettingsSlide extends Component {
salaryMonth: [],
statisticalItemPayload: {
visible: false, id: "", dimension: "",
statisticsItemId: ""
statisticsItemId: "", isShare: false
}
};
}
componentWillReceiveProps(nextProps, nextContext) {
if (nextProps.taxAgentAdminOption !== this.props.taxAgentAdminOption && !_.isEmpty(nextProps.taxAgentAdminOption)) {
const conditions = _.map(condition, item => {
return {
...item,
items: _.map(item.items, child => {
if (child.domkey[0] === "taxAgent") {
return {
...child,
options: toJS(nextProps.taxAgentAdminOption)
};
}
return { ...child };
})
};
});
this.setState({ conditions });
nextProps.form.initFormFields(condition);
}
if (nextProps.visible !== this.props.visible && nextProps.visible) this.getTaxAgentSelectList(nextProps);
if (nextProps.id !== this.props.id && !_.isEmpty(nextProps.id)) {
this.reportStatisticsGetSearchCondition(nextProps.id);
this.statisticsItemList(nextProps.id).then(r => {
});
}
@ -82,6 +66,31 @@ class StatisticalMicroSettingsSlide extends Component {
}
}
getTaxAgentSelectList = (props) => {
getTaxAgentSelectList(props.isShare).then(({ status, data }) => {
if (status) {
const conditions = _.map(condition, item => {
return {
...item,
items: _.map(item.items, child => {
if (getKey(child) === "taxAgent") {
return {
...child, viewAttr: props.isShare ? 1 : child.viewAttr,
options: _.map(data, o => ({ key: o.id, showname: o.content }))
};
}
return { ...child, viewAttr: props.isShare ? 1 : child.viewAttr };
})
};
});
this.setState({ conditions }, () => {
props.form.initFormFields(this.state.conditions);
props.id && this.reportStatisticsGetSearchCondition(props.id);
});
}
});
};
reportStatisticsGetSearchCondition = (id) => {
const { conditions } = this.state;
const { form } = this.props;
@ -189,7 +198,7 @@ class StatisticalMicroSettingsSlide extends Component {
};
renderProjectTitle = () => {
const { selectedRowKeys } = this.state;
const { id, dimension } = this.props;
const { id, dimension, isShare } = this.props;
return <div className="groupPorjectTitleWrapper">
<div>
<span>{getLabel(386275, "统计项目")}</span>
@ -198,19 +207,25 @@ class StatisticalMicroSettingsSlide extends Component {
/>
</div>
<div>
<WeaButtonIcon
buttonType="del" type="primary" disabled={_.isEmpty(selectedRowKeys)}
onClick={this.reportStatisticsItemDelete}
/>
<WeaButtonIcon
buttonType="add" type="primary"
onClick={() => this.setState({
statisticalItemPayload: {
visible: true, id, dimension,
statisticsItemId: ""
}
})}
/>
{
!isShare &&
<WeaButtonIcon
buttonType="del" type="primary" disabled={_.isEmpty(selectedRowKeys)}
onClick={this.reportStatisticsItemDelete}
/>
}
{
!isShare &&
<WeaButtonIcon
buttonType="add" type="primary"
onClick={() => this.setState({
statisticalItemPayload: {
visible: true, id, dimension,
statisticsItemId: "", isShare
}
})}
/>
}
</div>
</div>;
};
@ -220,16 +235,18 @@ class StatisticalMicroSettingsSlide extends Component {
salaryMonth, conditions, selectedRowKeys, loading,
statisticalItemPayload, dataSource, unitTypeList
} = this.state;
const { id, dimension } = this.props;
const { id, dimension, isShare } = this.props;
const columns = [
{
title: "统计项名称",
dataIndex: "itemName",
render: (txt, record) => {
return (
<a href="javascript: void(0);" onClick={() => this.setState({
statisticalItemPayload: { visible: true, id, dimension, statisticsItemId: record.id }
})}>{txt}</a>
<a href="javascript: void(0);" onClick={() => {
this.setState({
statisticalItemPayload: { visible: true, id, dimension, statisticsItemId: record.id, isShare }
});
}}>{txt}</a>
);
}
},
@ -238,7 +255,7 @@ class StatisticalMicroSettingsSlide extends Component {
dataIndex: "unitType",
render: (txt, record) => {
return <WeaSelect
value={!_.isNil(txt) ? txt.toString() : ""} options={unitTypeList} style={{ width: 150 }}
value={!_.isNil(txt) ? txt.toString() : ""} options={unitTypeList} style={{ width: 150 }} disabled={isShare}
onChange={unitType => this.customStatisticsItemsRef.reportStatisticsItemSave({ id: record.id, unitType })}
/>;
}
@ -248,7 +265,10 @@ class StatisticalMicroSettingsSlide extends Component {
selectedRowKeys,
onChange: (selectedRowKeys) => {
this.setState({ selectedRowKeys });
}
},
getCheckboxProps: record => ({
disabled: isShare
})
};
return (
<WeaSlideModal
@ -262,13 +282,13 @@ class StatisticalMicroSettingsSlide extends Component {
height={100}
measureY="%"
direction={"right"}
title={<TitleDialog loading={loading} onSave={this.reportStatisticsSaveSearchCondition}/>}
title={<TitleDialog loading={loading} isShare={isShare} onSave={this.reportStatisticsSaveSearchCondition}/>}
content={
<React.Fragment>
<WeaSearchGroup title={getLabel(532504, "统计时间范围")} col={2} showGroup needTigger>
<WeaFormItem label={getLabel(542604, "薪资所属月")} labelCol={{ span: 8 }} wrapperCol={{ span: 16 }}>
<WeaError tipPosition="bottom" ref="weaError" error={getLabel(385869, "此项必填")}>
<MonthRangePicker viewAttr={3} dateRange={salaryMonth}
<MonthRangePicker viewAttr={3} dateRange={salaryMonth} disabled={isShare}
onChange={v => this.setState({ salaryMonth: v })}/>
</WeaError>
</WeaFormItem>
@ -294,10 +314,8 @@ class StatisticalMicroSettingsSlide extends Component {
{...statisticalItemPayload}
onCancel={(isRefresh) => this.setState({
statisticalItemPayload: {
visible: false,
id: "",
dimension: "",
statisticsItemId: ""
visible: false, id: "", dimension: "",
statisticsItemId: "", isShare: false
}
}, () => isRefresh && this.statisticsItemList(this.props.id))}
/>
@ -319,16 +337,19 @@ const TitleDialog = (props) => {
</div>
</div>
<div className="titleCol titleRightBox">
<Button type="primary" loading={props.loading} onClick={props.onSave}>{getLabel(537558, "保存")}</Button>
{
!props.isShare &&
<Button type="primary" loading={props.loading} onClick={props.onSave}>{getLabel(537558, "保存")}</Button>
}
</div>
</div>;
};
export const MonthRangePicker = (props) => {
const { dateRange, onChange, viewAttr } = props;
const { dateRange, onChange, viewAttr, disabled = false } = props;
const [startDate, endDate] = dateRange || [];
return <div className="rangePickerBox">
<WeaDatePicker
value={startDate}
value={startDate} disabled={disabled}
disabledDate={(current) => {
return current && endDate && current.getTime() > new Date(endDate).getTime();
}}
@ -338,7 +359,7 @@ export const MonthRangePicker = (props) => {
/>
<span className="to" style={{ margin: "0 10px" }}></span>
<WeaDatePicker
value={endDate}
value={endDate} disabled={disabled}
disabledDate={(current) => {
return current && startDate && current.getTime() < new Date(startDate).getTime();
}}

View File

@ -0,0 +1,54 @@
import React, { Component } from "react";
import { WeaLocaleProvider } from "ecCom";
import { Button } from "antd";
import SalaryStatisticsDetailShareDialog from "./salaryStatisticsDetailShareDialog";
import SalaryStatisticsDetailShareRecord from "./salaryStatisticsDetailShareRecord";
const { getLabel } = WeaLocaleProvider;
class TopBtns extends Component {
constructor(props) {
super(props);
this.state = {
shareDialog: {
visible: false
},
shareRecordDialog: {
visible: false
}
};
}
handleShare = () => {
this.setState({
shareDialog: { visible: true }
});
};
handleShareRecord = () => {
this.setState({
shareRecordDialog: { visible: true }
});
};
render() {
const { shareDialog, shareRecordDialog } = this.state;
return [
<Button type="ghost" style={{ marginRight: 10 }} onClick={this.handleShare}>{getLabel(111, "分享报表")}</Button>,
<Button type="ghost" onClick={this.handleShareRecord}>{getLabel(111, "分享记录")}</Button>,
<SalaryStatisticsDetailShareDialog
{...shareDialog}
onCancel={() => this.setState({
shareDialog: { visible: false }
})}
/>,
<SalaryStatisticsDetailShareRecord
{...shareRecordDialog}
onClose={() => this.setState({
shareRecordDialog: { visible: false }
})}
/>
];
}
}
export default TopBtns;

View File

@ -11,9 +11,11 @@ import { message, Modal } from "antd";
import LeftTab from "./components/leftTab";
import ReportContent from "./components/reportContent";
import StatisticalMicroSettingsSlide from "./components/statisticalMicroSettingsSlide";
import TopBtns from "./components/topBtns";
import { reportGetForm, reportStatisticsReportSave } from "../../apis/ruleconfig";
import "./index.less";
const { getLabel } = WeaLocaleProvider;
@inject("taxAgentStore", "attendanceStore")
@ -31,9 +33,7 @@ class Index extends Component {
}
componentDidMount() {
const { taxAgentStore: { fetchTaxAgentOption } } = this.props;
this.reportGetForm();
fetchTaxAgentOption();
}
reportGetForm = () => {
@ -92,20 +92,19 @@ class Index extends Component {
*/
exportData = () => {
const { report } = this.state;
const { id, dimensionId } = report;
window.open(`${window.location.origin}/api/bs/hrmsalary/report/statistics/report/exportData?id=${id}&dimensionId=${dimensionId}`, "_self");
const { id, dimensionId, isShare } = report;
window.open(`${window.location.origin}/api/bs/hrmsalary/report/statistics/report/exportData?id=${id}&dimensionId=${dimensionId}&isShare=${isShare}`, "_blank");
};
render() {
const { report, dimensionList, statisticalPayload } = this.state;
const { attendanceStore: { settingForm }, taxAgentStore: { taxAgentOption } } = this.props;
const { isShare } = report;
const { attendanceStore: { settingForm }, taxAgentStore: { taxAgentOption, showOperateBtn } } = this.props;
return (
<WeaTop
title={getLabel(20829, "报表查看")}
icon={<i className="icon-coms-fa"/>}
iconBgcolor="#F14A2D"
showDropIcon={false}
className="reportViewWrapper"
title={getLabel(20829, "报表查看")} icon={<i className="icon-coms-fa"/>}
iconBgcolor="#F14A2D" className="reportViewWrapper"
buttons={(showOperateBtn && !isShare) ? [<TopBtns/>] : []}
>
<WeaLeftRightLayout
leftWidth={210}
@ -128,7 +127,7 @@ class Index extends Component {
<div className="rightColTitle">
<div className="dimension">
<span>{getLabel(506800, "统计维度")}</span>
<WeaSelect value={report.dimensionId} options={dimensionList}
<WeaSelect value={report.dimensionId} options={dimensionList} disabled={isShare}
onChange={(key, showname) => this.handleChangeDimension(key, showname)}/>
</div>
<div className="iconWrapper">
@ -150,10 +149,10 @@ class Index extends Component {
{/*统计数据范围及规则设置弹框*/}
<StatisticalMicroSettingsSlide
{...statisticalPayload} form={settingForm}
taxAgentAdminOption={taxAgentOption}
taxAgentAdminOption={taxAgentOption} isShare={isShare}
onClose={(isRefresh) => this.setState({
statisticalPayload: { visible: false, id: "", dimension: "" }
}, () => isRefresh && this.reportRef.reportStatisticsReportGetData(report.id, report.dimensionId))}
}, () => isRefresh && this.reportRef.reportStatisticsReportGetData(report.id, report.dimensionId, report.isShare))}
/>
</div>
</div>

View File

@ -204,6 +204,18 @@
.microSlideWrapper {
z-index: 999;
.wea-form-item-wrapper {
display: flex !important;
.wea-browser {
width: 100%;
}
}
.wea-form-item .wea-form-item-wrapper .wea-field-readonly {
white-space: pre-wrap !important;
}
.wea-slide-modal-title {
height: auto !important;
line-height: normal !important;

View File

@ -23,7 +23,7 @@ export default class Index extends Component {
orderRule: "",
ascOrDesc: "",
rule: "",
enctry: "",
enctry: "1",
operateTaxDeclaration: "1",
matchRule: "",
confValue: "0",
@ -56,7 +56,7 @@ export default class Index extends Component {
ascOrDesc = "", orderRule = "", showEncryptOperationButton, matchEmployeeMode: rule = "",
taxDeclarationFunction: operateTaxDeclaration = "1", salaryArchiveDelete: confValue,
salaryAcctEmployeeRule: matchRule, WITHDRAW_TAX_DECLARATION: withDrawTaxDeclaration = "0",
OPEN_APPLICATION_ENCRYPT: enctry = "0", extEmpsWitch = "0"
OPEN_APPLICATION_ENCRYPT: enctry = "1", extEmpsWitch = "0"
}
} = sysInfo;
// const { data: { ascOrDesc, orderRule } } = orderRules;
@ -76,8 +76,8 @@ export default class Index extends Component {
showEncryptOperationButton,
saveParams: {
...saveParams,
ascOrDesc, orderRule, rule, enctry, operateTaxDeclaration, matchRule, confValue, withDrawTaxDeclaration,
extEmpsWitch
ascOrDesc, orderRule, rule, enctry, matchRule, confValue, withDrawTaxDeclaration,
extEmpsWitch, operateTaxDeclaration: (operateTaxDeclaration && operateTaxDeclaration !== "0") ? "1" : "0"
}
});
}

View File

@ -1,175 +1,203 @@
export const columns = [
{
title: "姓名",
dataIndex: 'title',
key: 'title',
},
{
title: "个税扣缴义务人",
dataIndex: 'title',
key: 'title',
},
{
title: "部门",
dataIndex: 'title',
key: 'title',
},
{
title: "手机号",
dataIndex: 'title',
key: 'title',
},
{
title: "员工状态",
dataIndex: 'title',
key: 'title',
},
{
title: "基本工资",
dataIndex: 'title',
key: 'title',
},
{
title: "操作",
dataIndex: 'cz',
key: 'cz',
}
]
{
title: "姓名",
dataIndex: "title",
key: "title"
},
{
title: "个税扣缴义务人",
dataIndex: "title",
key: "title"
},
{
title: "部门",
dataIndex: "title",
key: "title"
},
{
title: "手机号",
dataIndex: "title",
key: "title"
},
{
title: "员工状态",
dataIndex: "title",
key: "title"
},
{
title: "基本工资",
dataIndex: "title",
key: "title"
},
{
title: "操作",
dataIndex: "cz",
key: "cz"
}
];
export const changeSalaryModalColumns = [
{
title: '薪资项目',
dataIndex: 'title',
key: 'title'
},
{
title: '调整前',
dataIndex: 'title',
key: 'title'
},
{
title: '调整后',
dataIndex: 'title',
key: 'title'
}
]
export const adjCondition = [
{
items: [
{
colSpan: 1,
conditionType: "DATEPICKER",
domkey: ["effectiveTime"],
fieldcol: 18,
label: "生效日期",
lanId: 19548,
labelcol: 6,
rules: "required",
value: "",
viewAttr: 3
},
{
colSpan: 1,
checkbox: false,
checkboxValue: false,
conditionType: "SELECT",
domkey: ["adjustReason"],
fieldcol: 18,
label: "调整原因",
lanId: 1897,
labelcol: 6,
options: [],
rules: "required",
viewAttr: 3
},
{
colSpan: 1,
conditionType: "INPUT",
domkey: ["description"],
fieldcol: 18,
label: "说明",
lanId: 25734,
labelcol: 6,
value: "",
viewAttr: 2
}
],
title: "调薪信息",
defaultshow: true
}
];
export const slideSalaryItemColumns = [
{
title: "姓名",
dataIndex: 'title',
key: 'title'
},
{
title: "员工状态",
dataIndex: 'title',
key: 'title'
},
{
title: "部门",
dataIndex: 'title',
key: 'title'
},
{
title: "薪资项目",
dataIndex: 'title',
key: 'title'
},
{
title: "调整前",
dataIndex: 'title',
key: 'title'
},
{
title: "调整后",
dataIndex: 'title',
key: 'title'
},
{
title: "调整原因",
dataIndex: 'title',
key: 'title'
},
{
title: "生效日期",
dataIndex: 'title',
key: 'title'
},
{
title: "操作人",
dataIndex: 'title',
key: 'title'
},
{
title: "操作日期",
dataIndex: 'title',
key: 'title'
},
{
title: "说明",
dataIndex: 'title',
key: 'title'
}
]
{
title: "姓名",
dataIndex: "title",
key: "title"
},
{
title: "员工状态",
dataIndex: "title",
key: "title"
},
{
title: "部门",
dataIndex: "title",
key: "title"
},
{
title: "薪资项目",
dataIndex: "title",
key: "title"
},
{
title: "调整前",
dataIndex: "title",
key: "title"
},
{
title: "调整后",
dataIndex: "title",
key: "title"
},
{
title: "调整原因",
dataIndex: "title",
key: "title"
},
{
title: "生效日期",
dataIndex: "title",
key: "title"
},
{
title: "操作人",
dataIndex: "title",
key: "title"
},
{
title: "操作日期",
dataIndex: "title",
key: "title"
},
{
title: "说明",
dataIndex: "title",
key: "title"
}
];
export const slieAgentColumns = [
{
title: "姓名",
dataIndex: 'title',
key: 'title'
},
{
title: "员工状态",
dataIndex: 'title',
key: 'title'
},
{
title: "部门",
dataIndex: 'title',
key: 'title'
},
{
title: "调整前",
dataIndex: 'title',
key: 'title'
},
{
title: "调整后",
dataIndex: 'title',
key: 'title'
},
{
title: "调整原因",
dataIndex: 'title',
key: 'title'
},
{
title: "生效日期",
dataIndex: 'title',
key: 'title'
},
{
title: "操作人",
dataIndex: 'title',
key: 'title'
},
{
title: "操作日期",
dataIndex: 'title',
key: 'title'
},
{
title: "说明",
dataIndex: 'title',
key: 'title'
}
]
{
title: "姓名",
dataIndex: "title",
key: "title"
},
{
title: "员工状态",
dataIndex: "title",
key: "title"
},
{
title: "部门",
dataIndex: "title",
key: "title"
},
{
title: "调整前",
dataIndex: "title",
key: "title"
},
{
title: "调整后",
dataIndex: "title",
key: "title"
},
{
title: "调整原因",
dataIndex: "title",
key: "title"
},
{
title: "生效日期",
dataIndex: "title",
key: "title"
},
{
title: "操作人",
dataIndex: "title",
key: "title"
},
{
title: "操作日期",
dataIndex: "title",
key: "title"
},
{
title: "说明",
dataIndex: "title",
key: "title"
}
];
export const dataSource = [
{
title: "测试"
}
{
title: "测试"
}
];

View File

@ -73,7 +73,6 @@
}
}
.salaryFileSlide {
padding: 10px 20px;
@ -125,7 +124,6 @@
}
}
.salaryFileTabWrapper {
.searchPanel {
position: absolute;
@ -169,3 +167,55 @@
}
}
}
.adjustItem-layout {
.ant-table-fixed td {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
.adjLogRecordDialogContent {
background: #f6f6f6;
padding: 16px;
height: 100%;
overflow-y: auto;
.empty {
text-align: center;
background: transparent;
margin-bottom: 20px;
padding: 30px 50px;
}
.wea-search-group:first-child {
margin-bottom: 16px;
}
.wea-search-group {
background: #FFF;
padding: 0;
border: 1px solid #e5e5e5;
border-bottom: none;
}
.wea-content, .wea-form-cell {
padding: 0;
}
.wea-form-item {
padding: 5px 16px;
border-bottom: 1px solid #e5e5e5;
}
.wea-select, .ant-select {
width: 100%;
}
.ant-select-selection {
width: 100%;
height: 30px;
border-radius: 0;
}
}

View File

@ -0,0 +1,221 @@
/*
* Author: 黎永顺
* name: 薪资档案-调薪
* Description:
* Date: 2023/9/4
*/
import React, { Component } from "react";
import { WeaDialog, WeaLocaleProvider, WeaSearchGroup, WeaTableEdit, WeaTools } from "ecCom";
import { Button, message, Spin } from "antd";
import {
editSingleSalaryItem,
getSalaryItemAdjustBeforeValue,
getSalaryItemForm,
getSingleSalaryItemInfo,
saveSalaryItem
} from "../../apis/archive";
import { inject, observer } from "mobx-react";
import { adjCondition } from "./columns";
import { getDomkes, getSearchs } from "../../util";
import moment from "moment";
const { getLabel } = WeaLocaleProvider;
const getKey = WeaTools.getKey;
const APIFox = {
save: saveSalaryItem,
edit: editSingleSalaryItem,
saveForm: getSalaryItemForm,
editForm: getSingleSalaryItemInfo
};
@inject("salaryFileStore")
@observer
class SalaryArchiveEditAdjLogRecordDialog extends Component {
constructor(props) {
super(props);
this.state = {
conditions: [], loading: false, saveLoading: false,
salaryArchiveItemDetail: {}, canOperator: false
};
}
componentWillReceiveProps(nextProps, nextContext) {
const { id, visible, salaryFileStore: { adjForm, initAdjForm } } = nextProps;
if (nextProps.visible !== this.props.visible && visible) {
this.getSingleSalaryItemInfo(nextProps);
} else {
adjForm.resetForm();
initAdjForm();
}
}
getSingleSalaryItemInfo = (props) => {
const { salaryFileStore: { adjForm }, id, salaryArchiveId: salaryArchiveItemId } = props;
this.setState({ loading: true });
APIFox[id ? "editForm" : "saveForm"](id ? { id } : { salaryArchiveItemId })
.then(({ status, data }) => {
this.setState({ loading: false });
if (status) {
const { salaryArchiveItemForm, salaryArchiveItemDetail, canOperator } = data;
const { adjustReasonList } = salaryArchiveItemForm;
this.setState({
canOperator, salaryArchiveItemDetail,
conditions: _.map(adjCondition, item => {
return {
...item,
title: getLabel(111, "调薪信息"),
items: _.map(item.items, o => {
if (getKey(o) === "adjustReason") {
return {
...o,
options: _.map(adjustReasonList, it => ({ key: it.id, showname: it.content }))
};
}
return { ...o };
})
};
})
}, () => {
adjForm.initFormFields(this.state.conditions);
_.map(getDomkes(this.state.conditions), domkey => {
adjForm.updateFields({
[domkey]: salaryArchiveItemForm[domkey] || ""
});
});
});
}
}).catch(() => this.setState({ loading: false }));
};
getSalaryItemAdjustBeforeValue = (salaryItemId) => {
const payload = {
salaryArchiveId: this.props.salaryArchiveId,
salaryItemId
};
getSalaryItemAdjustBeforeValue(payload).then(({ status, data }) => {
if (status) {
const { salaryArchiveItemDetail } = this.state;
const { list } = salaryArchiveItemDetail;
this.setState({
salaryArchiveItemDetail: {
...salaryArchiveItemDetail,
list: _.map(list, o => {
if (o.salaryItem === salaryItemId) {
return { ...o, salaryBefore: data };
}
return { ...o };
})
}
});
}
});
};
save = () => {
const { salaryFileStore: { adjForm, fetchSingleSalaryItemList, getArchiveForm } } = this.props;
const { pass } = this.tableEdit.refs.edit.doRequiredCheck();
adjForm.validateForm().then(f => {
if (f.isValid) {
if (!pass) return;
const { salaryArchiveId, id: salaryArchiveItemId } = this.props;
const { salaryArchiveItemDetail, canOperator } = this.state;
const { list } = salaryArchiveItemDetail;
let payload = {
...adjForm.getFormParams(), salaryArchiveId,
effectiveTime: moment(new Date(adjForm.getFormParams().effectiveTime)).format("YYYY-MM-DD"),
salaryArchiveItems: _.map(list, o => ({ salaryItemId: o.salaryItem, adjustValue: o.adjustAfter }))
};
if (salaryArchiveItemId) {
payload = { ...payload, canOperator, salaryArchiveItemId };
}
this.setState({ saveLoading: true });
APIFox[salaryArchiveItemId ? "edit" : "save"](payload).then(({ status, errormsg }) => {
this.setState({ saveLoading: false });
if (status) {
message.success(getLabel(22619, "保存成功!"));
this.props.onCancel();
fetchSingleSalaryItemList({ salaryArchiveId });
getArchiveForm(salaryArchiveId);
} else {
message.error(errormsg);
}
}).catch(() => this.setState({ saveLoading: false }));
} else {
f.showErrors();
}
});
};
render() {
const { salaryFileStore: { adjForm }, id } = this.props;
const { loading, saveLoading, salaryArchiveItemDetail, conditions } = this.state;
const { salaryItemList, list } = salaryArchiveItemDetail;
const adjColumns = [
{
title: "薪资项目",
dataIndex: "salaryItem",
key: "salaryItem",
com: [{
options: _.map(salaryItemList, o => ({ key: o.id, showname: o.content })),
type: "SELECT", viewAttr: id ? 1 : 3, key: "salaryItem",
onChange: (v) => this.getSalaryItemAdjustBeforeValue(v)
}],
colSpan: 1,
width: "40%"
},
{
title: getLabel(111, "调整前"),
dataIndex: "salaryBefore",
key: "salaryBefore",
com: [{ label: "", type: "INPUT", viewAttr: 1, key: "salaryBefore" }],
colSpan: 1,
width: "30%"
},
{
title: getLabel(111, "调整后"),
dataIndex: "adjustAfter",
key: "adjustAfter",
com: [{ label: "", type: "INPUTNUMBER", otherParams: { precision: 3 }, viewAttr: 3, key: "adjustAfter" }],
colSpan: 1,
width: "30%"
}
];
return (
<WeaDialog
{...this.props}
scalable hasScroll className="declareResultDialog" initLoadCss
style={{
width: 800,
height: 406.6,
minHeight: 200,
minWidth: 380,
maxHeight: "80%",
maxWidth: "80%",
overflow: "hidden",
transform: "translate(0px, 0px)"
}}
buttons={[<Button type="primary" onClick={this.save} loading={saveLoading}>{getLabel(537558, "保存")}</Button>]}
>
<div className="adjLogRecordDialogContent">
{
!loading ? <React.Fragment>
{getSearchs(adjForm, conditions, 1)}
<WeaSearchGroup title={getLabel(543333, "调薪明细")} showGroup needTigger={false}>
<WeaTableEdit
ref={dom => this.tableEdit = dom} deleteConfirm
columns={adjColumns} datas={list} showCopy={false}
showAdd={!id} showDelete={!id}
onChange={o => this.setState({
salaryArchiveItemDetail: {
...salaryArchiveItemDetail, list: o
}
})}
/>
</WeaSearchGroup>
</React.Fragment> : <div className="empty"><Spin/></div>
}
</div>
</WeaDialog>
);
}
}
export default SalaryArchiveEditAdjLogRecordDialog;

View File

@ -1,12 +1,11 @@
import React from "react";
import { Menu, message, Modal, Popover } from "antd";
import { WeaLocaleProvider } from "ecCom";
import { WeaLocaleProvider, WeaTable } from "ecCom";
import { inject, observer } from "mobx-react";
import ChangeSalaryModal from "./changeSalaryModal";
import { deleteSalaryItem } from "../../apis/archive";
import UnifiedTable from "../../components/UnifiedTable";
import SalaryArchiveEditAdjLogRecord from "./salaryArchiveEditAdjLogRecord";
const getLabel = WeaLocaleProvider.getLabel;
const { getLabel } = WeaLocaleProvider;
@inject("salaryFileStore")
@observer
export default class SalaryItemChangeList extends React.Component {
@ -14,6 +13,9 @@ export default class SalaryItemChangeList extends React.Component {
super(props);
this.state = {
changeSalaryVisible: false,
adjLogRecordDialog: {
visible: false, title: "", id: "", salaryArchiveId: ""
},
recordId: ""
};
this.searchParams = {};
@ -27,11 +29,11 @@ export default class SalaryItemChangeList extends React.Component {
handleEdit = (record) => {
this.setState({
recordId: record.id
}, () => {
this.setState({
changeSalaryVisible: true
});
adjLogRecordDialog: {
...this.state.adjLogRecordDialog,
visible: true, title: getLabel(542686, "调薪"), id: record.id,
salaryArchiveId: this.props.id
}
});
};
deleteSalaryItem = (salaryArchiveItemId) => {
@ -60,22 +62,35 @@ export default class SalaryItemChangeList extends React.Component {
const { salaryFileStore: { singleSalaryItemList }, selectedKey } = this.props;
let columns = [];
if (singleSalaryItemList.columns) {
columns = [...singleSalaryItemList.columns];
columns = _.map([...singleSalaryItemList.columns], o => {
const { dataIndex } = o;
if (dataIndex === "adjustItem") {
return { ...o, width: 100, fixed: "left", render: text => (<span title={text}>{text}</span>) };
}
let width = "";
switch (o) {
case "adjustBefore":
case "adjustAfter":
case "operateTime":
width = "20%";
break;
case "effectiveTime":
width = "15%";
break;
default:
width = "10%";
break;
}
return { ...o, width, render: text => (<span title={text}>{text}</span>) };
});
if (selectedKey === "fixed") {
columns = [...columns, {
dataIndex: "operate",
title: getLabel(30585, "操作"),
dataIndex: "operate", fixed: "right", width: 120, title: getLabel(30585, "操作"),
render: (text, record) => {
return <div className="optWrapper">
<a href="javascript:void(0);" className="mr10" onClick={() => this.handleEdit(record)}>{getLabel(501169, "编辑")}</a>
<Popover
overlayClassName="moreIconWrapper"
placement="bottomRight"
content={<Menu onClick={(e) => this.deleteSalaryItem(record.id)}>
<Menu.Item key="delete">{getLabel(535052, "删除")}</Menu.Item>
</Menu>} title="">
<i className="icon-coms-more"/>
</Popover>
<a href="javascript:void(0);"
onClick={() => this.deleteSalaryItem(record.id)}>{getLabel(535052, "删除")}</a>
</div>;
}
}];
@ -92,45 +107,29 @@ export default class SalaryItemChangeList extends React.Component {
}
render() {
const { salaryFileStore } = this.props;
const { salaryFileStore } = this.props, { adjLogRecordDialog } = this.state;
const { singleSalaryItemList } = salaryFileStore;
const pageInfo = { current: singleSalaryItemList.pageNum, pageSize: 10, total: singleSalaryItemList.total };
const pagination = {
...pageInfo,
showTotal: total => `${getLabel(18609, "共")} ${total} ${getLabel(18256, "条")}`,
showQuickJumper: true,
onChange: current => this.handlePageChange(current)
};
return (
<div>
<UnifiedTable
columns={
_.map(this.getColumns(), item => {
if (item.dataIndex !== "operate") {
return {
...item,
render: (text) => {
return <span className="ellipsis" title={text}>{text}</span>;
}
};
}
return { ...item };
})
}
dataSource={singleSalaryItemList.list ? singleSalaryItemList.list : []}
pagination={{
onChange: (value) => {
this.handlePageChange(value);
},
total: singleSalaryItemList.total,
showTotal: total => `${getLabel(83698, "共")} ${total} ${getLabel(18256, "条")}`,
current: singleSalaryItemList.pageNum
}}
xWidth={this.getColumns().length * 100}
<WeaTable
columns={this.getColumns()} dataSource={singleSalaryItemList.list ? singleSalaryItemList.list : []}
pagination={pagination} scroll={{ x: 800 }} className="adjustItem-layout"
/>
<SalaryArchiveEditAdjLogRecord
{...adjLogRecordDialog}
onCancel={() => this.setState({
adjLogRecordDialog: {
adjLogRecordDialog, visible: false, title: "", id: "", salaryArchiveId: ""
}
})}
/>
{
this.state.changeSalaryVisible && <ChangeSalaryModal
currentId={this.props.id}
recordId={this.state.recordId}
visible={this.state.changeSalaryVisible}
onCancel={() => {
this.setState({ changeSalaryVisible: false });
}}
/>
}
</div>
);
}

View File

@ -153,7 +153,7 @@ export default class SalaryFileViewSlide extends React.Component {
item.dataType === "number" ?
<WeaInputNumber
value={!_.isNil(item.value) ? item.value : 0}
precision={2}
precision={item.pattern || 2}
viewAttr={selectedKey === "pending" ? 2 : 1}
onChange={value => {
item.value = value;

View File

@ -159,6 +159,27 @@ export const valTakeOptions = [
{ key: "2", showname: getLabel(18125, "公式"), lanId: 18125 },
{ key: "3", showname: "SQL", lanId: 111 }
];
export const salarySetConditions = [
{
items: [{
colSpan: 1,
checkbox: false,
checkboxValue: false,
conditionType: "SELECT",
domkey: ["salarySobIds"],
fieldcol: 18,
label: "薪资账套",
lanId: 538010,
labelcol: 6,
options: [],
rules: "required|string",
multiple: true,
viewAttr: 3
}],
title: "",
defaultshow: true
}
];

View File

@ -8,7 +8,8 @@ export default class CustomSalaryItemSlide extends React.Component {
super(props);
this.state = {
showForm: false,
formalModalVisible: false
formalModalVisible: false,
salaryItemName: ""
};
}
@ -16,9 +17,10 @@ export default class CustomSalaryItemSlide extends React.Component {
this.props.onChange({ ...this.props.request, ...params });
};
handleShowFormal = () => {
handleShowFormal = (salaryItemName) => {
this.setState({
formalModalVisible: true
formalModalVisible: true,
salaryItemName
});
};
@ -34,12 +36,13 @@ export default class CustomSalaryItemSlide extends React.Component {
render() {
const { request } = this.props;
const { valueType, dataType, formulaId } = request;
const { formalModalVisible } = this.state;
const { formalModalVisible, salaryItemName } = this.state;
return (
<div className="customSalaryItemSlide">
<SalaryItemForm {...this.props} onChangeFieldsItem={this.handleChange} onShowFormal={this.handleShowFormal}/>
{formalModalVisible &&
<FormalFormModal
name={salaryItemName}
formulaId={formulaId}
visible={formalModalVisible}
valueType={valueType}
@ -49,7 +52,8 @@ export default class CustomSalaryItemSlide extends React.Component {
}}
onCancel={() =>
this.setState({
formalModalVisible: false
formalModalVisible: false,
salaryItemName: ""
})}
/>}
</div>

View File

@ -209,7 +209,7 @@ export default class FormalFormModal extends React.Component {
});
this.parameters = result;
let params = {
name: getLabel(543514, "公式1"),
name: this.props.name || getLabel(543514, "公式1"),
description: getLabel(536726, "备注"),
module: "salary",
useFor: "salaryitem",

View File

@ -9,6 +9,7 @@ import { columns } from "./columns";
import SlideModalTitle from "../../components/slideModalTitle";
import CustomSalaryItemSlide from "./customSalaryItemSlide";
import CustomPaginationTable from "../../components/customPaginationTable";
import SyncToSalaryAccountSetDialog from "./syncToSalaryAccountSetDialog";
import "../socialSecurityBenefits/programme/index.less";
const { getLabel } = WeaLocaleProvider;
@ -25,7 +26,8 @@ export default class SalaryItem extends React.Component {
searchValue: "",
formalModalVisible: false,
searchParams: { current: 1, pageSize: 10, total: 0 },
selectedRowKeys: []
selectedRowKeys: [],
syncSalarySetDialog: { visible: false, title: "", id: "" }
};
columns.map(item => {
if (item.dataIndex == "refere") {
@ -69,7 +71,10 @@ export default class SalaryItem extends React.Component {
onEditItem = (record, isedit) => {
this.record = record;
const { salaryItemStore: { getItemForm, setEditSlideVisible } } = this.props;
this.setState({ editable: isedit, isAdd: false });
this.setState({
editable: isedit, isAdd: false,
syncSalarySetDialog: { ...this.state.syncSalarySetDialog, id: record.id }
});
getItemForm(record.id).then(() => {
setEditSlideVisible(true);
}).catch(({ errormsg }) => {
@ -310,6 +315,15 @@ export default class SalaryItem extends React.Component {
];
} else if (this.state.editable) {
arrList = [
<Button type="ghost"
onClick={() => this.setState({
syncSalarySetDialog: {
...this.state.syncSalarySetDialog,
visible: true,
title: getLabel(111, "请选择薪资账套")
}
})}
>{getLabel(111, "同步到薪资账套")}</Button>,
<Button type="primary" onClick={() => {
handleSlideSave(false);
}}>{getLabel(537558, "保存")}</Button>
@ -367,6 +381,15 @@ export default class SalaryItem extends React.Component {
</WeaNewScroll>
</div>
</WeaTop>
<SyncToSalaryAccountSetDialog
{...this.state.syncSalarySetDialog}
onCancel={() => this.setState({
syncSalarySetDialog: {
...this.state.syncSalarySetDialog,
visible: false, title: ""
}
})}
/>
{
systemItemVisible &&

View File

@ -102,3 +102,43 @@
}
}
}
.salarySetDialog {
.salarySetDialogContent {
.wea-select, .ant-select, .ant-select-selection {
width: 100%;
}
.wea-select .wea-select-input .arrow {
position: absolute;
right: 4px;
top: 8px;
color: #666;
}
.wea-select .wdb {
word-break: break-all !important;
word-wrap: break-word !important;
}
.wea-select .wea-select-input {
height: 30px;
white-space: nowrap;
min-width: 100px;
max-width: 345px;
width: 100%;
display: inline-block;
padding: 4px 17px 4px 4px;
position: relative;
min-height: 30px;
border: 1px solid #d9d9d9;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
-o-text-overflow: ellipsis;
text-overflow: ellipsis;
overflow: hidden;
}
}
}

View File

@ -36,7 +36,6 @@ class SalaryItemForm extends Component {
const { key, lanId, label } = item;
switch (key) {
case "useDefault":
case "sortedIndex":
case "dataType":
case "description":
return {
@ -45,6 +44,8 @@ class SalaryItemForm extends Component {
display: !isLedger,
label: getLabel(lanId, label)
};
case "sortedIndex":
return { ...item };
case "useInEmployeeSalary":
return {
...item,
@ -141,7 +142,7 @@ class SalaryItemForm extends Component {
(type === "INPUT" && display) ?
<WeaFormItem label={label} labelCol={{ span: 6 }} wrapperCol={{ span: 12 }}>
<WeaInput viewAttr={viewAttr} value={value}
onClick={() => (key === "originSqlContent" || key === "originFormulaContent") && onShowFormal()}
onClick={() => (key === "originSqlContent" || key === "originFormulaContent") && onShowFormal(request["name"])}
onChange={v => this.handleChangeSalaryFiledItems(key, v)}/></WeaFormItem> :
(type === "SWITCH" && display) ?
<WeaFormItem label={label} labelCol={{ span: 6 }} wrapperCol={{ span: 12 }}>

View File

@ -0,0 +1,95 @@
/*
* Author: 黎永顺
* name: 同步到薪资账套
* Description:
* Date: 2023/8/31
*/
import React, { Component } from "react";
import { inject, observer } from "mobx-react";
import { WeaDialog, WeaLocaleProvider } from "ecCom";
import { Button, message } from "antd";
import { getSearchs } from "../../util";
import { getSalarySobBySalaryItem, syncSalaryItemToSalarySobItem } from "../../apis/item";
import { salarySetConditions } from "./columns";
const getLabel = WeaLocaleProvider.getLabel;
@inject("salaryItemStore")
@observer
class SyncToSalaryAccountSetDialog extends Component {
constructor(props) {
super(props);
this.state = {
loading: false,
conditions: []
};
}
componentWillReceiveProps(nextProps, nextContext) {
const { salaryItemStore: { salarySetform } } = nextProps;
if (nextProps.visible !== this.props.visible && nextProps.visible) this.getSalarySobBySalaryItem(nextProps);
if (nextProps.visible !== this.props.visible && !nextProps.visible) salarySetform.resetForm();
}
getSalarySobBySalaryItem = (props) => {
const { id, salaryItemStore: { salarySetform } } = props;
getSalarySobBySalaryItem({ id }).then(({ status, data }) => {
if (status) {
this.setState({
conditions: _.map(salarySetConditions, item => {
return {
...item,
items: _.map(item.items, o => ({
...o,
options: _.map(data, it => ({ key: it.id, showname: it.content }))
}))
};
})
}, () => {
salarySetform.initFormFields(this.state.conditions);
});
}
});
};
save = () => {
const { salaryItemStore: { salarySetform }, id: salaryItemId } = this.props;
salarySetform.validateForm().then(f => {
if (f.isValid) {
const { salarySobIds } = salarySetform.getFormParams();
this.setState({ loading: true });
syncSalaryItemToSalarySobItem({ salaryItemId, salarySobIds: salarySobIds.split(",") })
.then(({ status, errormsg }) => {
this.setState({ loading: false });
if (status) {
message.success(getLabel(38462, "同步成功!"));
this.props.onCancel();
} else {
message.error(errormsg || getLabel(81556, "同步失败!"));
}
}).catch(() => this.setState({ loading: false }));
} else {
f.showErrors();
}
});
};
render() {
const { salaryItemStore: { salarySetform } } = this.props;
const { conditions } = this.state;
return (
<WeaDialog
{...this.props} className="salarySetDialog" initLoadCss
style={{ width: 550 }}
buttons={[<Button type="primary" onClick={this.save}
loading={this.state.loading}>{getLabel(537558, "确定")}</Button>]}
>
<div className="salarySetDialogContent">
{getSearchs(salarySetform, conditions, 1)}
</div>
</WeaDialog>
);
}
}
export default SyncToSalaryAccountSetDialog;

View File

@ -33,5 +33,12 @@ export const tabCondition = [
title: getLabel(542505, "停缴员工"),
lanId: 542505,
viewcondition: "stop"
}
},
{
color: "#000000",
groupid: "ext",
showcount: true,
title: "非系统人员",
viewcondition: "ext"
},
];

View File

@ -2,7 +2,7 @@ import React from "react";
import { inject, observer } from "mobx-react";
import { toJS } from "mobx";
import { Button, Dropdown, Icon, Menu, message, Modal, Popover } from "antd";
import { WeaHelpfulTip, WeaLocaleProvider, WeaNewScroll, WeaSlideModal, WeaTab, WeaTools, WeaTop } from "ecCom";
import { WeaCheckbox, WeaHelpfulTip, WeaLocaleProvider, WeaNewScroll, WeaSlideModal, WeaTab, WeaTools, WeaTop } from "ecCom";
import { getSearchs, renderLoading } from "../../../util";
import BaseForm from "./baseForm";
import SlideModalTitle from "../../../components/slideModalTitle";
@ -14,11 +14,16 @@ import * as API from "../../../apis/welfareArchive";
import ImportModal from "../../../components/importModal";
import TipLabel from "../../../components/TipLabel";
import UnifiedTable from "../../../components/UnifiedTable";
import { convertToUrlString } from "../../../util/url";
import { convertToUrlString, getURLParameters } from "../../../util/url";
import { salaryArchiveDelete } from "../../../apis/payrollFiles";
import ImportDialog from "../../../components/importDialog";
import "./index.less";
const getLabel = WeaLocaleProvider.getLabel;
const APILIST = {
runStatuses: API["queryList"],
extWelArchiveList: API["getExtTable"]
};
@inject("archivesStore", "taxAgentStore")
@observer
export default class Archives extends React.Component {
@ -46,14 +51,20 @@ export default class Archives extends React.Component {
stayAdd: 0,
paying: 0,
stayDel: 0,
stopPay: 0
stopPay: 0,
ext: 0
},
pageInfo: {
current: 1,
pageSize: 10,
total: 0
},
salaryArchiveDelete: "" //待定薪、停薪员工 是否允许删除薪资档案 0 否, 1
salaryArchiveDelete: "", //待定薪、停薪员工 是否允许删除薪资档案 0 否, 1
importDialog: {
visible: false, title: "", nextloading: false,
link: "", importResult: {}, imageId: "",
previewUrl: "/api/bs/hrmsalary/scheme/preview"
}
};
this.record = {};
}
@ -78,7 +89,7 @@ export default class Archives extends React.Component {
const formParams = form.getFormParams() || {};
const payload = { ...pageInfo };
this.setState({ loading: { ...loading, query: true } });
API.queryList({ ...formParams, ...payload, ...params }).then(({ data, status }) => {
APILIST[_.keys(params)[0]]({ ...formParams, ...payload, ...params }).then(({ data, status }) => {
this.setState({ loading: { ...loading, query: false } });
if (status) {
const { pageInfo: paganition, columns, datas: dataSource } = data;
@ -294,8 +305,10 @@ export default class Archives extends React.Component {
// 模板点击
handleTemplateLinkClick = (exportData) => {
const { archivesStore: { form } } = this.props;
const formParams = form.getFormParams() || {};
const { selectedKey } = this.state;
let url = `/api/bs/hrmsalary/scheme/template/export?exportData=${exportData}&runStatuses=${selectedKey === "pending" ? "1" : "2,3"}`;
let url = `/api/bs/hrmsalary/scheme/template/export?exportData=${exportData}&runStatuses=${selectedKey === "pending" ? "1" : "2,3"}&${convertToUrlString(formParams)}`;
window.open(`${window.location.origin}${url}`);
};
@ -308,8 +321,19 @@ export default class Archives extends React.Component {
// 导入
handleImport = (params) => {
const { archivesStore: { importBatch } } = this.props;
const { runStatus } = this.state;
importBatch({ ...params, runStatus });
const { runStatus, importDialog } = this.state;
this.setState(({
importDialog: {
...importDialog, nextloading: true, ...params
}
}));
importBatch({ ...params, runStatus }).then(({ status, data }) => {
this.setState(({
importDialog: {
...importDialog, nextloading: false, importResult: data, ...params
}
}));
});
};
// 导入完成
@ -374,9 +398,12 @@ export default class Archives extends React.Component {
case "suspend":
this.queryList({ runStatuses: ["3"] });
break;
default:
case "stop":
this.queryList({ runStatuses: ["4", "5"] });
break;
default:
this.queryList({ extWelArchiveList: true });
break;
}
};
handleMenuBtnClick = () => {
@ -563,13 +590,15 @@ export default class Archives extends React.Component {
{/*<div>4、数据进入【待减员】规则的第四种情况下若还需要在当前个税扣缴义务人下进行缴纳的话当前该员工的【待减员】数据进行【删除待办】操作即可若不在该个税扣缴义务人下继续缴纳维护好最后缴纳月后进行【减员】操作员工进入【停缴员工】</div>*/}
</div>;
break;
default:
case "stop":
dom = <div>
<div>{getLabel(544354, "1、不需要缴纳社保福利的员工保存在【停缴员工】")}</div>
{/*<div>2、【停缴员工】点击取消停缴数据会回退到上次的位置从【待减员】减员到停缴员工的点击停缴返回到【在缴员工】不返回到【待减员】</div>*/}
{/*<div>3、若员工的社保福利从一个个税扣缴义务人下转到另一个个税扣缴义务人下去缴纳则在转后的个税扣缴义务人的【待增员】中进行增员操作成功后员工进入待【在缴员工】而在原个税扣缴义务人下的【停缴员工】中该员工数据将会被删除是否开启分权员工的档案数据都只保存一份</div>*/}
</div>;
break;
default:
break;
}
return dom;
};
@ -584,7 +613,8 @@ export default class Archives extends React.Component {
dataSource: dataSourceActive,
pageInfo,
tabCount,
loading
loading,
importDialog
} = this.state;
const {
form, condition, showSearchAd, setShowSearchAd,
@ -654,161 +684,95 @@ export default class Archives extends React.Component {
}
window.open(url, "_self");
};
let btns = [];
if (languageidweaver == "8") {
const menus = selectedKey === "fixed" ?
(
<Menu>
<Menu.Item><span onClick={() => this.handleBtnImport("2")}>{getLabel(32935, "导入")}</span></Menu.Item>
<Menu.Item><span onClick={handleMenuClick}>{getLabel(512938, "导出选中")}</span></Menu.Item>
<Menu.Item><span onClick={handleButtonClick}>{getLabel(81272, "导出全部")}</span></Menu.Item>
</Menu>
) : selectedKey === "pending" ?
(
<Menu>
<Menu.Item><span onClick={this.handleMenuBtnClick}>{getLabel(543185, "全量增员")}</span></Menu.Item>
<Menu.Item><span
onClick={() => this.handleMenuItemClick({ key: "1" })}>{getLabel(543187, "批量增员")}</span></Menu.Item>
<Menu.Item><span
onClick={() => this.handleMenuItemClick({ key: "4" })}>{getLabel(543186, "批量删除待办")}</span></Menu.Item>
<Menu.Item><span onClick={() => this.handleBtnImport("1")}>{getLabel(32935, "导入")}</span></Menu.Item>
<Menu.Item><span onClick={handleMenuClick}>{getLabel(512938, "导出选中")}</span></Menu.Item>
<Menu.Item><span onClick={handleButtonClick}>{getLabel(81272, "导出全部")}</span></Menu.Item>
</Menu>
) : selectedKey === "suspend" ?
(
<Menu>
<Menu.Item onClick={this.handleMenuBtnClick}><span>{getLabel(543189, "全量减员")}</span></Menu.Item>
<Menu.Item><span
onClick={() => this.handleMenuItemClick({ key: "1" })}>{getLabel(543188, "批量减员")}</span></Menu.Item>
<Menu.Item><span
onClick={() => this.handleMenuItemClick({ key: "2" })}>{getLabel(543186, "批量删除待办")}</span></Menu.Item>
<Menu.Item><span onClick={handleMenuClick}>{getLabel(512938, "导出选中")}</span></Menu.Item>
<Menu.Item><span onClick={handleButtonClick}>{getLabel(81272, "导出全部")}</span></Menu.Item>
</Menu>
) : (
<Menu>
<Menu.Item><span
onClick={() => this.cancelStopPayment(selectedRowKeys)}>{getLabel(543190, "批量取消停缴")}</span></Menu.Item>
<Menu.Item><span onClick={handleMenuClick}>{getLabel(512938, "导出选中")}</span></Menu.Item>
<Menu.Item><span onClick={handleButtonClick}>{getLabel(81272, "导出全部")}</span></Menu.Item>
</Menu>
);
btns = [
<Dropdown overlay={menus}>
<Button type="primary" style={{ marginLeft: 8 }}>
{getLabel(17499, "更多")} <Icon type="down"/>
</Button>
</Dropdown>
];
selectedKey === "pending" && btns.unshift(<WeaHelpfulTip
const btns = selectedKey === "fixed" ? [
<Button type="primary" onClick={() => {
this.handleBtnImport("2");
}}>导入</Button>,
<Dropdown.Button onClick={handleButtonClick} overlay={
<Menu onClick={handleMenuClick}>
<Menu.Item key="1">导出选中</Menu.Item>
</Menu>
} type="ghost">
导出全部
</Dropdown.Button>
] : selectedKey === "pending" ? [
<WeaHelpfulTip
width={300}
title={
<div>
{getLabel(544348, "提示:缴纳月份区间包含起始缴纳月,不包含最后缴纳月; 若员工离职时还未增员进入在缴员工,则数据会自动清除,因此若确认缴纳,请及时维护档案数据并增员操作。若清除后还需缴纳,需先在个税扣缴义务人菜单将员工按离职状态添加回来,会重新出现在待增员。")}
</div>
}
title={<div>提示缴纳月份区间包含起始缴纳月不包含最后缴纳月 若员工离职时还未增员进入在缴员工则数据会自动清除
因此若确认缴纳请及时维护档案数据并增员操作若清除后还需缴纳需先在个税扣缴义务人菜单将员工按离职状态添加回来会重新出现在待增员</div>}
placement="topLeft"
/>);
selectedKey === "suspend" && btns.unshift(<WeaHelpfulTip
/>,
<Dropdown.Button
onClick={this.handleMenuBtnClick}
overlay={
<Menu onClick={this.handleMenuItemClick}>
<Menu.Item key="1">批量增员</Menu.Item>
<Menu.Item key="4">批量删除待办</Menu.Item>
</Menu>
} type="ghost"
>
全量增员
</Dropdown.Button>,
<Button type="primary" onClick={() => {
this.handleBtnImport("1");
}}>导入</Button>,
<Dropdown.Button onClick={handleButtonClick} overlay={
<Menu onClick={handleMenuClick}>
<Menu.Item key="1">导出选中</Menu.Item>
</Menu>
} type="ghost">
导出全部
</Dropdown.Button>
] : selectedKey === "suspend" ? [
<WeaHelpfulTip
width={300}
title={<HelpfulDiv/>}
placement="topLeft"
/>);
selectedKey === "stop" && btns.unshift(<WeaHelpfulTip
/>,
<Dropdown.Button
onClick={this.handleMenuBtnClick}
overlay={
<Menu onClick={this.handleMenuItemClick}>
<Menu.Item key="1">批量减员</Menu.Item>
<Menu.Item key="2">批量删除待办</Menu.Item>
</Menu>
}
type="primary"
>
全量减员
</Dropdown.Button>,
<Dropdown.Button onClick={handleButtonClick} overlay={
<Menu onClick={handleMenuClick}>
<Menu.Item key="1">导出选中</Menu.Item>
</Menu>
} type="ghost">
导出全部
</Dropdown.Button>
] : selectedKey === "stop" ? [
<WeaHelpfulTip
width={300}
title={<CancelHelpfulDiv/>}
placement="topLeft"
/>);
} else {
btns = selectedKey === "fixed" ?
[
<Button type="primary" onClick={() => {
this.handleBtnImport("2");
}}>{getLabel(32935, "导入")}</Button>,
<Dropdown.Button onClick={handleButtonClick} overlay={
<Menu onClick={handleMenuClick}>
<Menu.Item key="1">{getLabel(512938, "导出选中")}</Menu.Item>
</Menu>
} type="ghost">
{getLabel(81272, "导出全部")}
</Dropdown.Button>
] : selectedKey === "pending" ?
[
<WeaHelpfulTip
width={300}
title={
<div>
{getLabel(544348, "提示:缴纳月份区间包含起始缴纳月,不包含最后缴纳月; 若员工离职时还未增员进入在缴员工,则数据会自动清除,因此若确认缴纳,请及时维护档案数据并增员操作。若清除后还需缴纳,需先在个税扣缴义务人菜单将员工按离职状态添加回来,会重新出现在待增员。")}
</div>
}
placement="topLeft"
/>,
<Dropdown.Button
onClick={this.handleMenuBtnClick}
overlay={
<Menu onClick={this.handleMenuItemClick}>
<Menu.Item key="1">{getLabel(543187, "批量增员")}</Menu.Item>
<Menu.Item key="4">{getLabel(543186, "批量删除待办")}</Menu.Item>
</Menu>
} type="ghost"
>
{getLabel(543185, "全量增员")}
</Dropdown.Button>,
<Button type="primary" onClick={() => {
this.handleBtnImport("1");
}}>{getLabel(32935, "导入")}</Button>,
<Dropdown.Button onClick={handleButtonClick} overlay={
<Menu onClick={handleMenuClick}>
<Menu.Item key="1">{getLabel(512938, "导出选中")}</Menu.Item>
</Menu>
} type="ghost">
{getLabel(81272, "导出全部")}
</Dropdown.Button>
] : selectedKey === "suspend" ?
[
<WeaHelpfulTip
width={300}
title={<HelpfulDiv/>}
placement="topLeft"
/>,
<Dropdown.Button
onClick={this.handleMenuBtnClick}
overlay={
<Menu onClick={this.handleMenuItemClick}>
<Menu.Item key="1">{getLabel(543188, "批量减员")}</Menu.Item>
<Menu.Item key="2">{getLabel(543186, "批量删除待办")}</Menu.Item>
</Menu>
}
type="primary"
>
{getLabel(543189, "全量减员")}
</Dropdown.Button>,
<Dropdown.Button onClick={handleButtonClick} overlay={
<Menu onClick={handleMenuClick}>
<Menu.Item key="1">{getLabel(512938, "导出选中")}</Menu.Item>
</Menu>
} type="ghost">
{getLabel(81272, "导出全部")}
</Dropdown.Button>
] :
[
<WeaHelpfulTip
width={300}
title={<CancelHelpfulDiv/>}
placement="topLeft"
/>,
<Button type="primary"
onClick={() => this.cancelStopPayment(selectedRowKeys)}>{getLabel(543190, "批量取消停缴")}</Button>,
<Dropdown.Button onClick={handleButtonClick} overlay={
<Menu onClick={handleMenuClick}>
<Menu.Item key="1">{getLabel(512938, "导出选中")}</Menu.Item>
</Menu>
} type="ghost">
{getLabel(81272, "导出全部")}
</Dropdown.Button>
];
}
/>,
<Button type="primary" onClick={() => this.cancelStopPayment(selectedRowKeys)}>批量取消停缴</Button>,
<Dropdown.Button onClick={handleButtonClick} overlay={
<Menu onClick={handleMenuClick}>
<Menu.Item key="1">导出选中</Menu.Item>
</Menu>
} type="ghost">
导出全部
</Dropdown.Button>
] : [<Button type="primary"
onClick={() => this.setState(({
runStatus: "2",
importDialog: {
...importDialog,
visible: true, title: getLabel(111, "非系统人员导入"),
link: "/api/bs/hrmsalary/scheme/template/export?extWelArchiveList=true"
}
}))}>导入</Button>
];
const pagination = {
current: pageInfo.current,
@ -851,6 +815,7 @@ export default class Archives extends React.Component {
keyParam="viewcondition" //主键
selectedKey={selectedKey}
onChange={this.handleChangeTab}
autoCalculateWidth
searchType={["base", "advanced"]} // base基础搜索框 advanced显示高级搜索按钮
showSearchAd={showSearchAd} // 是否展开高级搜索面板
setShowSearchAd={bool => setShowSearchAd(bool)} //高级搜索面板受控
@ -883,7 +848,7 @@ export default class Archives extends React.Component {
xWidth={this.getColumns().length * 120}
/>
{
!_.isEmpty(this.getColumns()) &&
!_.isEmpty(this.getColumns()) && selectedKey !== "ext" &&
<TipLabel>{this.getTipChildren()}</TipLabel>
}
</WeaNewScroll>
@ -958,6 +923,36 @@ export default class Archives extends React.Component {
this.setState({ selectedTab: "0" });
})}/>
}
<ImportDialog
{...importDialog}
onCancel={(isFresh) => this.setState({
importDialog: {
...importDialog,
visible: false, title: "", nextloading: false,
link: "", importResult: {}, imageId: ""
}
}, () => isFresh && this.query())}
onResetImportResult={() => this.setState(({
importDialog: { ...importDialog, importResult: {}, imageId: "" }
}))}
exportDataDom={
<WeaCheckbox content={getLabel(543208, "导出现有数据")}
value={getURLParameters(importDialog.link).exportData === "true" ? "1" : "0"}
helpfulTip={getLabel(111, "提示:建议先导出现有最新数据,修改后再导入")}
onChange={val => {
const formParams = form.getFormParams() || {};
const payload = { exportData: val === "1", ...formParams };
this.setState(({
importDialog: {
...importDialog,
link: `/api/bs/hrmsalary/scheme/template/export?extWelArchiveList=true&${convertToUrlString(payload)}`
}
}));
}}
/>
}
nextCallback={imageId => this.handleImport({ imageId })}
/>
{
this.state.importVisible && <ImportModal
init={() => {

View File

@ -83,8 +83,39 @@ export const insertUpdateColumns = [
}
];
export const dataSource = [];
export const conditons = [
{
items: [
{
colSpan: 2,
conditionType: "INPUT",
domkey: ["schemeName"],
fieldcol: 12,
isQuickSearch: true,
label: "方案名称",
lanId: 33162,
labelcol: 6,
value: "",
viewAttr: 2
},
{
colSpan: 2,
conditionType: "SELECT",
domkey: ["paymentTypeEnum"],
fieldcol: 12,
isQuickSearch: true,
label: "缴纳类型",
lanId: 543163,
labelcol: 6,
value: "",
options: [],
viewAttr: 2
}
],
title: "",
defaultshow: true
}
];

View File

@ -144,6 +144,11 @@ export default class DefaultSlideForm extends React.Component {
key: "2",
selected: true,
showname: "2"
},
{
key: "3",
selected: false,
showname: "3"
}
];
item.render = (text, record) => {
@ -208,7 +213,7 @@ export default class DefaultSlideForm extends React.Component {
return (
<WeaInputNumber
min={0}
precision={3}
precision={4}
value={text}
onChange={v => {
this.updateDataSource(record, v, "paymentProportion");

View File

@ -2,9 +2,8 @@ import React from "react";
import { inject, observer } from "mobx-react";
import { toJS } from "mobx";
import { Button, Dropdown, Menu, message, Modal } from "antd";
import { WeaLocaleProvider, WeaNewScroll, WeaSelect, WeaSlideModal, WeaTop } from "ecCom";
import { renderNoright } from "../../../util";
import CustomTab from "../../../components/customTab";
import { WeaLocaleProvider, WeaNewScroll, WeaSelect, WeaSlideModal, WeaTab, WeaTools, WeaTop } from "ecCom";
import { getSearchs, renderNoright } from "../../../util";
import SlideModalTitle from "../../../components/slideModalTitle";
import TipLabel from "../../../components/TipLabel";
import DefaultSlideForm from "./defaultSlideForm";
@ -14,8 +13,10 @@ import CustomPaginationTable from "../../../components/customPaginationTable";
import TwoColContent from "../../../components/twoColContent";
import CopySchemaModal from "./copySchemaModal";
import CustomBenefitsTable from "./customBenefitsTable";
import { conditons } from "./columns";
import "./index.less";
const getKey = WeaTools.getKey;
const { getLabel } = WeaLocaleProvider;
@inject("programmeStore", "taxAgentStore", "salaryFileStore")
@observer
@ -30,7 +31,8 @@ export default class Programme extends React.Component {
copyModalValue: "",
copyId: "",
customNewVisible: false,
customEdit: false
customEdit: false,
showSearchAd: false
};
this.pageInfo = { current: 1, pageSize: 10 };
@ -38,12 +40,29 @@ export default class Programme extends React.Component {
componentWillMount() {
const { programmeStore, salaryFileStore, taxAgentStore } = this.props;
const { doInit } = programmeStore;
const { doInit, planSearchForm } = programmeStore;
doInit();
const { commonEnumList } = salaryFileStore;
commonEnumList("user", { enumClass: "com.engine.salary.enums.sicategory.SharedTypeEnum" });
const { getTaxAgentSelectListAsAdmin } = taxAgentStore;
getTaxAgentSelectListAsAdmin();
planSearchForm.initFormFields(_.map(conditons, item => {
return {
...item,
items: _.map(item.items, o => {
if (getKey(o) === "paymentTypeEnum") {
return {
...o,
options: [
{ key: "SCHEME_TOWN", showname: getLabel(19702, "城镇") },
{ key: "SCHEME_VILLAGE", showname: getLabel(19703, "农村") }
]
};
}
return { ...o };
})
};
}));
}
// 增加编辑功能重写columns绑定事件
@ -173,6 +192,7 @@ export default class Programme extends React.Component {
}
render() {
const { showSearchAd } = this.state;
const { programmeStore, taxAgentStore: { showOperateBtn } } = this.props;
const { loading, hasRight, form, getTableDatas } = programmeStore;
const {
@ -187,7 +207,8 @@ export default class Programme extends React.Component {
customNewVisible,
tableDataSource,
tableColumns,
tablePageInfo
tablePageInfo,
planSearchForm
} = programmeStore;
if (!hasRight && !loading) return renderNoright();
@ -317,59 +338,65 @@ export default class Programme extends React.Component {
const { programmeStore: { initSlideParms } } = this.props;
initSlideParms();
};
const customButtons = [
<WeaSelect
options={options}
value={customSelectkey}
style={{ width: "150px" }}
onChange={v => {
setCustomSelectkey(v);
this.customBenefitsTableRef.getCustomCategoryList({ current: 1, welfareTypeEnum: v });
}}
/>
];
const tabButtons = [
<Button type="primary" onClick={() => {
selectedKey === "custom" ? handleCustomNewClick() : handleNewClick();
}}>{getLabel(365, "新建")}</Button>
];
return (
<div className="socialSecurityAndWelfareSchemeWrapper">
<WeaTop
title={getLabel(538000, "社保福利方案")} // 文字
icon={<i className="icon-coms-fa"/>} // 左侧图标
iconBgcolor="#F14A2D" // 左侧图标背景色
showDropIcon={false} // 是否显示下拉按钮
title={getLabel(538000, "社保福利方案")} icon={<i className="icon-coms-fa"/>}
iconBgcolor="#F14A2D" showDropIcon={false}
>
<CustomTab
topTab={topTab}
searchOperationItem={
<div>
{/* 操作按钮权限 */}
{showOperateBtn &&
<Button
type="primary"
style={{ marginRight: "10px" }}
onClick={() => {
if (selectedKey == "custom") {
handleCustomNewClick();
} else {
handleNewClick();
}
}}>
{getLabel(365, "新建")}
</Button>}
{selectedKey == "custom" &&
<WeaSelect
options={options}
value={customSelectkey}
style={{ width: "150px" }}
onChange={v => {
setCustomSelectkey(v);
this.customBenefitsTableRef.getCustomCategoryList({ current: 1, welfareTypeEnum: v });
}}
/>}
</div>
}
<WeaTab
datas={topTab} keyParam="viewcondition" selectedKey={selectedKey}
searchType={selectedKey !== "custom" ? ["base", "advanced"] : []}
showSearchAd={showSearchAd}
setShowSearchAd={bool => this.setState({ showSearchAd: bool })}
advanceHeight={200} searchsAd={getSearchs(planSearchForm, _.map(conditons, item => {
return {
...item,
items: _.map(item.items, o => {
if (getKey(o) === "paymentTypeEnum") {
return {
...o,
options: [
{ key: "SCHEME_TOWN", showname: getLabel(19702, "城镇") },
{ key: "SCHEME_VILLAGE", showname: getLabel(19703, "农村") }
]
};
}
return { ...o };
})
};
}), 2, false)}
onAdSearch={() => getTableDatas(selectedKey)}
onAdReset={v => planSearchForm.resetForm()}
onSearch={() => getTableDatas(selectedKey)}
onChange={v => {
setSelectedKey(v);
handleSlideClose();
if (v == "custom") {
// 自定义福利
} else {
getTableDatas(v);
}
v !== "custom" && getTableDatas(v);
}}
onSearchChange={v => planSearchForm.updateFields({ schemeName: v })} // 在搜索框中输入的文字改变时的回调: 这里需要同步高级搜索和外部搜索框的值
searchsBaseValue={planSearchForm.getFormParams().schemeName}
buttons={!showOperateBtn ? [] : selectedKey !== "custom" ? tabButtons : [...tabButtons, ...customButtons]}
/>
<div className="tableWrapper">
<WeaNewScroll height="100%">
{selectedKey == "custom"
{selectedKey === "custom"
? <TwoColContent
leftContent={
<CustomBenefitsTable

Some files were not shown because too many files have changed in this diff Show More