diff --git a/pc4mobx/hrmSalary/apis/calculate.js b/pc4mobx/hrmSalary/apis/calculate.js index 013bddee..2ffee227 100644 --- a/pc4mobx/hrmSalary/apis/calculate.js +++ b/pc4mobx/hrmSalary/apis/calculate.js @@ -564,3 +564,7 @@ export const cacheImportField = (params) => { body: JSON.stringify(params) }).then(res => res.json()); }; +//薪资核算-页面查看权限 +export const salaryacctAcctresultCheckAuth = params => { + return WeaTools.callApi("/api/bs/hrmsalary/salaryacct/acctresult/checkAuth", "GET", params); +}; diff --git a/pc4mobx/hrmSalary/apis/declare.js b/pc4mobx/hrmSalary/apis/declare.js index 8cf65377..360c8b62 100644 --- a/pc4mobx/hrmSalary/apis/declare.js +++ b/pc4mobx/hrmSalary/apis/declare.js @@ -1,4 +1,5 @@ import { WeaTools } from 'ecCom'; +import { postFetch } from '../util/request'; //个税申报表-个税申报表列表 export const getDeclareList = params => { @@ -7,7 +8,7 @@ export const getDeclareList = params => { mode: 'cors', headers: { 'Content-Type': 'application/json' - }, + }, body: JSON.stringify(params) }).then(res => res.json()) } @@ -24,7 +25,7 @@ export const saveDeclare = params => { mode: 'cors', headers: { 'Content-Type': 'application/json' - }, + }, body: JSON.stringify(params) }).then(res => res.json()) } @@ -41,7 +42,7 @@ export const getDetailList = params => { mode: 'cors', headers: { 'Content-Type': 'application/json' - }, + }, body: JSON.stringify(params) }).then(res => res.json()) } @@ -52,13 +53,16 @@ export const exportSalaryArchive = (id = "") => { fetch('/api/bs/hrmsalary/taxdeclaration/export?taxDeclarationId=' + id).then(res => res.blob().then(blob => { var filename=`个税申报表.xlsx` var a = document.createElement('a'); - var url = window.URL.createObjectURL(blob); + var url = window.URL.createObjectURL(blob); a.href = url; a.download = filename; a.click(); window.URL.revokeObjectURL(url); })) } - +//个税申报表-撤回申报 +export const withDrawTaxDeclaration = (params) => { + return postFetch('/api/bs/hrmsalary/taxdeclaration/withDrawTaxDeclaration', params); +} diff --git a/pc4mobx/hrmSalary/apis/item.js b/pc4mobx/hrmSalary/apis/item.js index 128cd24f..ccf93af9 100644 --- a/pc4mobx/hrmSalary/apis/item.js +++ b/pc4mobx/hrmSalary/apis/item.js @@ -107,6 +107,10 @@ export const saveSysItem = params => { export const getItemTypeOption = 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); +} // *** 公式 start *** // 获取公式变量类型 diff --git a/pc4mobx/hrmSalary/apis/mySalaryBenefits.js b/pc4mobx/hrmSalary/apis/mySalaryBenefits.js index 7a29d7db..a2f5be7a 100644 --- a/pc4mobx/hrmSalary/apis/mySalaryBenefits.js +++ b/pc4mobx/hrmSalary/apis/mySalaryBenefits.js @@ -1,29 +1,36 @@ -import { WeaTools } from 'ecCom'; +import { WeaTools } from "ecCom"; // 工资单列表 export const mySalaryBillList = params => { - return fetch('/api/bs/hrmsalary/salaryBill/mySalaryBillList', { - method: 'POST', - mode: 'cors', + return fetch("/api/bs/hrmsalary/salaryBill/mySalaryBillList", { + method: "POST", + mode: "cors", headers: { - 'Content-Type': 'application/json' - }, + "Content-Type": "application/json" + }, body: JSON.stringify(params) - }).then(res => res.json()) + }).then(res => res.json()); }; // 社保福利列表 export const welfareList = params => { - return WeaTools.callApi('/api/bs/hrmsalary/report/welfare/list', 'GET', params); + return WeaTools.callApi("/api/bs/hrmsalary/report/welfare/list", "GET", params); }; // 调薪记录列表 export const recordList = params => { - return WeaTools.callApi('/api/bs/hrmsalary/report/record/list', 'GET', params); + return WeaTools.callApi("/api/bs/hrmsalary/report/record/list", "GET", params); }; // 工资查看详情 export const mySalaryBill = params => { - return WeaTools.callApi('/api/bs/hrmsalary/salaryBill/mySalaryBill', 'GET', params); -}; \ No newline at end of file + return WeaTools.callApi("/api/bs/hrmsalary/salaryBill/mySalaryBill", "GET", params); +}; + +export const isNeedSecondPwdVerify = params => { + return WeaTools.callApi("/api/encrypt/secondauthsetting/isNeedSecondAuth", "POST", params); +}; +export const doSecondAuth = params => { + return WeaTools.callApi("/api/encrypt/secondauthsetting/doSecondAuth", "POST", params); +}; diff --git a/pc4mobx/hrmSalary/apis/payroll.js b/pc4mobx/hrmSalary/apis/payroll.js index 58c2ec3d..1f9b1d64 100644 --- a/pc4mobx/hrmSalary/apis/payroll.js +++ b/pc4mobx/hrmSalary/apis/payroll.js @@ -12,6 +12,10 @@ export const getPayrollList = params => { body: JSON.stringify(params) }).then(res => res.json()); }; +// 工资单发放进度条 +export const getPayrollIssuanceProgressBar = (id) => { + return WeaTools.callApi("/api/bs/hrmsalary/progress/getRate?cacheKey=SALARY_GRANT_PROGRESS_" + id, "get", {}); +}; //工资单-获取table提示信息 export const getPayrollInfo = params => { @@ -363,3 +367,24 @@ export const getAvailableSalaryItemSet = (params) => { export const salaryBillSendSum = (params) => { return postFetch("/api/bs/hrmsalary/salaryBill/send/sum", params); }; +//工资单发放-发送短信验证码 +export const sendMobileCode = (params) => { + return postFetch("/api/bs/hrmsalary/salaryBill/sendMobileCode", params); +}; +//工资单-验证方式 +export const payrollCheckType = params => { + return WeaTools.callApi("/api/bs/hrmsalary/salaryBill/payrollCheckType", "GET", params); +}; + +// 工资单基础设置-获取设置列表 +export const getSalaryBillBaseSetForm = (id) => { + return WeaTools.callApi("/api/bs/hrmsalary/salaryBill/baseSet/getForm", "get", {}); +}; +//工资单基础设置-保存工资单基础设置(设置水印) +export const salaryBillBaseSetSave = (params) => { + return postFetch("/api/bs/hrmsalary/salaryBill/baseSet/save", params); +}; +//工资单基础设置-保存工资单基础设置(水印预览) +export const salaryBillBaseSetPreviewWaterMark = (params) => { + return postFetch("/api/bs/hrmsalary/salaryBill/baseSet/previewWaterMark", params); +}; diff --git a/pc4mobx/hrmSalary/apis/payrollFiles.js b/pc4mobx/hrmSalary/apis/payrollFiles.js index 74cf1d72..7ebdb6bb 100644 --- a/pc4mobx/hrmSalary/apis/payrollFiles.js +++ b/pc4mobx/hrmSalary/apis/payrollFiles.js @@ -65,3 +65,11 @@ export const deletePendingTodo = (params) => { export const deleteSuspendTodo = (params) => { return postFetch('/api/bs/hrmsalary/salaryArchive/deleteSuspendTodo', params); } +// 待定薪、停薪员工 是否允许删除薪资档案 +export const salaryArchiveDelete = (params) => { + return WeaTools.callApi('/api/bs/hrmsalary/sys/conf/code?code=salaryArchiveDelete', 'GET', params); +} +// 删除薪资档案 +export const deleteSalaryArchive = (params) => { + return postFetch('/api/bs/hrmsalary/salaryArchive/deleteSalaryArchive', params); +} diff --git a/pc4mobx/hrmSalary/apis/ruleconfig.js b/pc4mobx/hrmSalary/apis/ruleconfig.js index 2e5967fc..2e3c0c4f 100644 --- a/pc4mobx/hrmSalary/apis/ruleconfig.js +++ b/pc4mobx/hrmSalary/apis/ruleconfig.js @@ -1,45 +1,65 @@ -import { WeaTools } from 'ecCom'; -import { postFetch } from '../util/request'; +import { WeaTools } from "ecCom"; +import { postFetch } from "../util/request"; //通用字典表 {enumClass:""} export const commonEnumList = (params) => { - return WeaTools.callApi('/api/bs/hrmsalary/common/enum/list', 'GET', params); -} + return WeaTools.callApi("/api/bs/hrmsalary/common/enum/list", "GET", params); +}; export const sysOrderRule = params => { - return WeaTools.callApi('/api/bs/hrmsalary/sys/orderRule', 'GET', params); -} + return WeaTools.callApi("/api/bs/hrmsalary/sys/orderRule", "GET", params); +}; //保存排序规则 export const updateOrderRule = (params) => { - return postFetch('/api/bs/hrmsalary/sys/updateOrderRule', params); -} + return postFetch("/api/bs/hrmsalary/sys/updateOrderRule", params); +}; //导入规则详情信息 export const sysConfCodeRule = params => { - return WeaTools.callApi('/api/bs/hrmsalary/sys/conf/code', 'GET', params); -} + return WeaTools.callApi("/api/bs/hrmsalary/sys/conf/code", "GET", params); +}; //保存导入规则 export const saveMatchEmployeeModeRule = (params) => { - return postFetch('/api/bs/hrmsalary/sys/saveMatchEmployeeModeRule', params); -} + return postFetch("/api/bs/hrmsalary/sys/saveMatchEmployeeModeRule", params); +}; //应用配置查询 export const queryAppsetting = (params) => { - return WeaTools.callApi('/api/bs/hrmsalary/sys/app/setting', 'GET', params); -} + return WeaTools.callApi("/api/bs/hrmsalary/sys/app/setting", "GET", params); +}; //加密配置保存 export const saveEncryptSetting = (params) => { - return postFetch('/api/bs/hrmsalary/sys/app/setting/saveEncryptSetting', params); -} + return postFetch("/api/bs/hrmsalary/sys/app/setting/saveEncryptSetting", params); +}; //加密配置保存 export const appSettingSave = (params) => { - return postFetch('/api/bs/hrmsalary/sys/app/setting/save', params); -} + return postFetch("/api/bs/hrmsalary/sys/app/setting/save", params); +}; //获取加密进度条 export const getEncryptProgress = params => { - return WeaTools.callApi('/api/bs/hrmsalary/sys/app/getEncryptProgress', 'GET', params); -} + return WeaTools.callApi("/api/bs/hrmsalary/sys/app/getEncryptProgress", "GET", params); +}; //保存报税规则 export const operateTaxDeclarationFunction = (params) => { - return postFetch('/api/bs/hrmsalary/sys/operateTaxDeclarationFunction', params); -} + return postFetch("/api/bs/hrmsalary/sys/operateTaxDeclarationFunction", params); +}; +//保存档案删除规则 +export const saveArchiveDelete = (params) => { + return postFetch("/api/bs/hrmsalary/sys/saveArchiveDelete", params); +}; +//保存个税申报撤回规则 +export const saveWithDrawTaxDeclaration = (params) => { + return postFetch("/api/bs/hrmsalary/sys/saveWithDrawTaxDeclaration", params); +}; +//保存匹配规则 +export const saveSalaryAcctEmployeeRule = (params) => { + return postFetch("/api/bs/hrmsalary/sys/saveSalaryAcctEmployeeRule", params); +}; +//保存薪酬统计报表 +export const reportStatisticsReportSave = (params) => { + return postFetch("/api/bs/hrmsalary/report/statistics/report/save", params); +}; +//薪酬统计维度下拉列表 +export const reportGetForm = params => { + return WeaTools.callApi("/api/bs/hrmsalary/report/statistics/report/getForm", "GET", params); +}; diff --git a/pc4mobx/hrmSalary/apis/statistics.js b/pc4mobx/hrmSalary/apis/statistics.js new file mode 100644 index 00000000..f5f4aff6 --- /dev/null +++ b/pc4mobx/hrmSalary/apis/statistics.js @@ -0,0 +1,80 @@ +import { WeaTools } from "ecCom"; +import { postFetch } from "../util/request"; + +//薪酬统计维度下拉列表 +export const dimensionGetForm = (params) => { + return WeaTools.callApi("/api/bs/hrmsalary/report/statistics/dimension/getForm", "GET", params); +}; +//获取自定义统计项目表单 +export const statisticsItemGetform = (params) => { + return WeaTools.callApi("/api/bs/hrmsalary/report/statistics/item/getForm", "GET", params); +}; +//自定义统计项目列表 +export const statisticsItemList = (params) => { + return WeaTools.callApi("/api/bs/hrmsalary/report/statistics/item/list", "GET", params); +}; +// 保存薪酬统计维度 +export const dimensionSave = (params) => { + return postFetch("/api/bs/hrmsalary/report/statistics/dimension/save", params); +}; +// 薪酬统计维度列表 +export const dimensionList = (params) => { + return postFetch("/api/bs/hrmsalary/report/statistics/dimension/list", params); +}; +// 删除薪酬统计维度 +export const dimensionDelete = (params) => { + return postFetch("/api/bs/hrmsalary/report/statistics/dimension/delete", params); +}; + +//保存薪酬统计报表 +export const reportStatisticsReportList = (params) => { + return postFetch("/api/bs/hrmsalary/report/statistics/report/list", params); +}; +//删除薪酬统计报表 +export const reportStatisticsReportDelete = (params) => { + return postFetch("/api/bs/hrmsalary/report/statistics/report/delete", params); +}; +//获取薪酬统计报表数据 +export const reportStatisticsReportGetData = (params) => { + return postFetch("/api/bs/hrmsalary/report/statistics/report/getData", params); +}; +//保存自定义统计项目 +export const reportStatisticsItemSave = (params) => { + return postFetch("/api/bs/hrmsalary/report/statistics/item/save", params); +}; +//保存数据范围及负责设置 +export const reportStatisticsSaveSearchCondition = (params) => { + return postFetch("/api/bs/hrmsalary/report/statistics/report/saveSearchCondition", params); +}; +//删除自定义统计项目 +export const reportStatisticsItemDelete = (params) => { + return postFetch("/api/bs/hrmsalary/report/statistics/item/delete", params); +}; +//获取薪酬统计报表查询条件 +export const reportStatisticsGetSearchCondition = (params) => { + return WeaTools.callApi("/api/bs/hrmsalary/report/statistics/report/getSearchCondition", "GET", params); +}; +//分析图数据展示范围设置查询 +export const queryRangeSetting = (params) => { + return WeaTools.callApi("/api/bs/hrmsalary/report/statistics/echarts/queryRangeSetting", "GET", params); +}; +//分析图数据展示范围设置删除 +export const deleteRangeSetting = (params) => { + return WeaTools.callApi("/api/bs/hrmsalary/report/statistics/echarts/deleteRangeSetting", "GET", params); +}; +//分析图数据展示范围设置保存 +export const saveRangeSetting = (params) => { + return postFetch("/api/bs/hrmsalary/report/statistics/echarts/saveRangeSetting", params); +}; +//员工列表 +export const statisticsEmployeeList = (params) => { + return postFetch("/api/bs/hrmsalary/report/statistics/employee/list", params); +}; +//员工详情列表 +export const statisticsEmployeeDetailList = (params) => { + return postFetch("/api/bs/hrmsalary/report/statistics/employee/detailList", params); +}; +//数据透视-列表查询 +export const getDataPerspective = (params) => { + return postFetch("/api/bs/hrmsalary/report/statistics/report/getDataPerspective", params); +}; diff --git a/pc4mobx/hrmSalary/apis/welfareArchive.js b/pc4mobx/hrmSalary/apis/welfareArchive.js index 974ed260..a38f22ce 100644 --- a/pc4mobx/hrmSalary/apis/welfareArchive.js +++ b/pc4mobx/hrmSalary/apis/welfareArchive.js @@ -1,146 +1,150 @@ -import { WeaTools } from 'ecCom'; +import { WeaTools } from "ecCom"; import { postFetch } from "../util/request"; export const tips = params => { - return WeaTools.callApi('/api/bs/hrmsalary/archives/tips', 'get', params); + return WeaTools.callApi("/api/bs/hrmsalary/archives/tips", "get", params); }; export const getCondition = params => { - return WeaTools.callApi('/api/bs/hrmsalary/archives/getSearchCondition', 'get', params); + return WeaTools.callApi("/api/bs/hrmsalary/archives/getSearchCondition", "get", params); }; //社保福利档案列表 export const queryList = (params) => { - return postFetch('/api/bs/hrmsalary/archives/getTable', params); + return postFetch("/api/bs/hrmsalary/archives/getTable", params); }; //社保福利档案列表 export const queryInsuranceTabTotal = (params) => { - return WeaTools.callApi('/api/bs/hrmsalary/archives/queryInsuranceTabTotal', params); + return WeaTools.callApi("/api/bs/hrmsalary/archives/queryInsuranceTabTotal", params); }; //删除待办-待增员 export const updateRunStatus = (params) => { - return postFetch('/api/bs/hrmsalary/archives/updateRunStatus', params); + return postFetch("/api/bs/hrmsalary/archives/updateRunStatus", params); }; //删除待办-待减员 export const cancelStayDel = (params) => { - return postFetch('/api/bs/hrmsalary/archives/cancelStayDel', params); + return postFetch("/api/bs/hrmsalary/archives/cancelStayDel", params); }; //全量增员 export const allStayAddToPay = (params) => { - return WeaTools.callApi('/api/bs/hrmsalary/archives/allStayAddToPay', 'GET', params); + return WeaTools.callApi("/api/bs/hrmsalary/archives/allStayAddToPay", "GET", params); }; //全量减员 export const allStayDelToStop = (params) => { - return WeaTools.callApi('/api/bs/hrmsalary/archives/allStayDelToStop', 'GET', params); + return WeaTools.callApi("/api/bs/hrmsalary/archives/allStayDelToStop", "GET", params); }; //增员 export const stayAddToPay = (params) => { - return postFetch('/api/bs/hrmsalary/archives/stayAddToPay', params); + return postFetch("/api/bs/hrmsalary/archives/stayAddToPay", params); }; //减员 export const stayDelToStop = (params) => { - return postFetch('/api/bs/hrmsalary/archives/stayDelToStop', params); + return postFetch("/api/bs/hrmsalary/archives/stayDelToStop", params); +}; +//删除社保档案 +export const deleteArchive = (params) => { + return postFetch("/api/bs/hrmsalary/archives/deleteArchive", params); }; //取消停缴 export const cancelStopPayment = (params) => { - return postFetch('/api/bs/hrmsalary/archives/cancelStopPayment', params); + return postFetch("/api/bs/hrmsalary/archives/cancelStopPayment", params); }; export const getTable = params => { - return fetch('/api/bs/hrmsalary/archives/getTable', { - method: 'POST', - mode: 'cors', - headers: { - 'Content-Type': 'application/json' - }, - body: JSON.stringify(params) - }).then(res => res.json()) + return fetch("/api/bs/hrmsalary/archives/getTable", { + method: "POST", + mode: "cors", + headers: { + "Content-Type": "application/json" + }, + body: JSON.stringify(params) + }).then(res => res.json()); }; export const getBaseForm = params => { - return WeaTools.callApi('/api/bs/hrmsalary/archives/getBaseForm', 'get', params); + return WeaTools.callApi("/api/bs/hrmsalary/archives/getBaseForm", "get", params); }; export const getPaymentForm = params => { - return WeaTools.callApi('/api/bs/hrmsalary/archives/getPaymentForm', 'get', params); + return WeaTools.callApi("/api/bs/hrmsalary/archives/getPaymentForm", "get", params); }; // 保存 export const save = params => { - return fetch('/api/bs/hrmsalary/archives/save', { - method: 'POST', - mode: 'cors', - headers: { - 'Content-Type': 'application/json' - }, - body: JSON.stringify(params) - }).then(res => res.json()) + return fetch("/api/bs/hrmsalary/archives/save", { + method: "POST", + mode: "cors", + headers: { + "Content-Type": "application/json" + }, + body: JSON.stringify(params) + }).then(res => res.json()); }; // 导出档案 export const exportDocument = params => { - return WeaTools.callApi('/api/bs/hrmsalary/archives/export', 'get', params); + return WeaTools.callApi("/api/bs/hrmsalary/archives/export", "get", params); }; // 导入档案 - 获取组件的一些前置参数 export const getImportDocumentParams = params => { - return WeaTools.callApi('/api/bs/hrmsalary/archives/getImportParams', 'get', params); + return WeaTools.callApi("/api/bs/hrmsalary/archives/getImportParams", "get", params); }; // 导入档案- 导出现有数据 export const exportCurData = params => { - fetch('/api/bs/hrmsalary/scheme/template/export',{ - method: 'POST', - mode: 'cors', - headers: { - 'Content-Type': 'application/json' - }, - body: JSON.stringify(params) - }).then(res => res.blob().then(blob => { - var filename=`社保福利档案模板.xlsx` - var a = document.createElement('a'); - var url = window.URL.createObjectURL(blob); - a.href = url; - a.download = filename; - a.click(); - window.URL.revokeObjectURL(url); - })) + fetch("/api/bs/hrmsalary/scheme/template/export", { + method: "POST", + mode: "cors", + headers: { + "Content-Type": "application/json" + }, + body: JSON.stringify(params) + }).then(res => res.blob().then(blob => { + var filename = `社保福利档案模板.xlsx`; + var a = document.createElement("a"); + var url = window.URL.createObjectURL(blob); + a.href = url; + a.download = filename; + a.click(); + window.URL.revokeObjectURL(url); + })); }; // 导入档案-预览 export const previewCurData = (params) => { - return fetch('/api/bs/hrmsalary/scheme/preview', { - method: 'POST', - mode: 'cors', - headers: { - 'Content-Type': 'application/json' - }, - body: JSON.stringify(params) - }).then(res => res.json()) -} + return fetch("/api/bs/hrmsalary/scheme/preview", { + method: "POST", + mode: "cors", + headers: { + "Content-Type": "application/json" + }, + body: JSON.stringify(params) + }).then(res => res.json()); +}; // 档案导入 export const importBatch = (params) => { - return fetch('/api/bs/hrmsalary/scheme/importBatch', { - method: 'POST', - mode: 'cors', - headers: { - 'Content-Type': 'application/json' - }, - body: JSON.stringify(params) - }).then(res => res.json()) -} + return fetch("/api/bs/hrmsalary/scheme/importBatch", { + method: "POST", + mode: "cors", + headers: { + "Content-Type": "application/json" + }, + body: JSON.stringify(params) + }).then(res => res.json()); +}; // 导出档案 export const exportArchives = (ids) => { - fetch('/api/bs/hrmsalary/scheme/export?ids=' + ids).then(res => res.blob().then(blob => { - var filename=`社保福利档案.xlsx` - var a = document.createElement('a'); - var url = window.URL.createObjectURL(blob); - a.href = url; - a.download = filename; - a.click(); - window.URL.revokeObjectURL(url); - })) -} + fetch("/api/bs/hrmsalary/scheme/export?ids=" + ids).then(res => res.blob().then(blob => { + var filename = `社保福利档案.xlsx`; + var a = document.createElement("a"); + var url = window.URL.createObjectURL(blob); + a.href = url; + a.download = filename; + a.click(); + window.URL.revokeObjectURL(url); + })); +}; diff --git a/pc4mobx/hrmSalary/common/Icon-empty-file.svg b/pc4mobx/hrmSalary/common/Icon-empty-file.svg new file mode 100644 index 00000000..cfab82a9 --- /dev/null +++ b/pc4mobx/hrmSalary/common/Icon-empty-file.svg @@ -0,0 +1,38 @@ + + + Icon-empty-file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pc4mobx/hrmSalary/common/leftTree-hide.png b/pc4mobx/hrmSalary/common/leftTree-hide.png new file mode 100644 index 00000000..0a1cadfc Binary files /dev/null and b/pc4mobx/hrmSalary/common/leftTree-hide.png differ diff --git a/pc4mobx/hrmSalary/common/leftTree-show.png b/pc4mobx/hrmSalary/common/leftTree-show.png new file mode 100644 index 00000000..cc791aad Binary files /dev/null and b/pc4mobx/hrmSalary/common/leftTree-show.png differ diff --git a/pc4mobx/hrmSalary/components/UnifiedTable/index.js b/pc4mobx/hrmSalary/components/UnifiedTable/index.js index 8f406f4f..f8cbff97 100644 --- a/pc4mobx/hrmSalary/components/UnifiedTable/index.js +++ b/pc4mobx/hrmSalary/components/UnifiedTable/index.js @@ -13,7 +13,7 @@ class Index extends Component { return { ...item, fixed: "left", width: 176 }; } if (item.dataIndex === "operate") { - return { ...item, fixed: "right", width: "120px" }; + return { ...item, fixed: "right", width: item.width || "120px" }; } return { ...item, width: "33%" }; }); diff --git a/pc4mobx/hrmSalary/components/UnifiedTable/index.less b/pc4mobx/hrmSalary/components/UnifiedTable/index.less index e1dbaf1d..616d16f0 100644 --- a/pc4mobx/hrmSalary/components/UnifiedTable/index.less +++ b/pc4mobx/hrmSalary/components/UnifiedTable/index.less @@ -8,17 +8,17 @@ } .linkWapper { - a { - color: #4d7ad8; - margin-right: 8px; - } + //a { + // color: #4d7ad8; + // margin-right: 8px; + //} i { cursor: pointer; } - a:hover { - text-decoration: none; - } + //a:hover { + // text-decoration: none; + //} } } diff --git a/pc4mobx/hrmSalary/components/captchaModal/index.js b/pc4mobx/hrmSalary/components/captchaModal/index.js new file mode 100644 index 00000000..35661772 --- /dev/null +++ b/pc4mobx/hrmSalary/components/captchaModal/index.js @@ -0,0 +1,94 @@ +/* + * Author: 黎永顺 + * name: 验证码弹框 + * Description: + * Date: 2023/6/16 + */ +import React, { Component } from "react"; +import { WeaDialog, WeaError, WeaFormItem, WeaInput, WeaLocaleProvider, WeaSearchGroup } from "ecCom"; +import { sendMobileCode } from "../../apis/payroll"; +import { Button } from "antd"; +import "./index.less"; + +const { getLabel } = WeaLocaleProvider; + +class Index extends Component { + constructor(props) { + super(props); + this.state = { + captcha: "", + time: 60 + }; + this.timeRef = null; + } + + componentWillUnmount() { + clearInterval(this.timeRef); + } + + componentWillReceiveProps(nextProps, nextContext) { + if (nextProps.visible !== this.props.visible && !nextProps.visible) { + clearInterval(this.timeRef); + this.setState({ captcha: "", time: 60 }); + } + } + + handleSendCaptcha = () => { + sendMobileCode({ id: this.props.id }).then(({ status, data }) => { + if (status) { + console.log(data); + this.timeRef = setInterval(() => { + const { time } = this.state; + this.setState({ time: time - 1 }, () => { + if (this.state.time === -1) { + clearInterval(this.timeRef); + this.setState({ time: 60 }); + } + }); + }, 1000); + } + }); + }; + handleConfirm = () => { + if (!this.state.captcha) { + this.refs.weaError.showError(); + // return + } + this.props.onCancel(); + this.props.onConfirm(); + }; + + render() { + const { captcha, time } = this.state; + return ( + {getLabel(826, "确定")} + ]} + > + + + +
+ this.setState({ captcha })}/> + +
+
+
+
+
+ ); + } +} + +export default Index; diff --git a/pc4mobx/hrmSalary/components/captchaModal/index.less b/pc4mobx/hrmSalary/components/captchaModal/index.less new file mode 100644 index 00000000..4f8d23b7 --- /dev/null +++ b/pc4mobx/hrmSalary/components/captchaModal/index.less @@ -0,0 +1,29 @@ +.captchaWrapper { + .wea-dialog-body { + padding: 30px 20px; + + .wea-form-item-wrapper { + .wea-error { + width: 100%; + + .captchaInputBox { + display: flex; + align-items: center; + + .wea-input-normal { + flex: 1; + } + + button { + padding: 8px 10px; + border-radius: 0; + min-width: 80px; + text-align: center; + height: 30px; + line-height: 15px; + } + } + } + } + } +} diff --git a/pc4mobx/hrmSalary/components/excelEditor/components/codeAction.js b/pc4mobx/hrmSalary/components/excelEditor/components/codeAction.js new file mode 100644 index 00000000..bca61000 --- /dev/null +++ b/pc4mobx/hrmSalary/components/excelEditor/components/codeAction.js @@ -0,0 +1,255 @@ +/* + * Author: 黎永顺 + * name: 公式列表 + * Description: + * Date: 2023/4/25 + */ +import React, { Component } from "react"; +import { WeaInputSearch, WeaLocaleProvider } from "ecCom"; +import { Tree } from "antd"; +import { formualSearchField, formualSearchGroup, getFormulaDes } from "../../../apis/item"; +import "../index.less"; + +const TreeNode = Tree.TreeNode; +const getLabel = WeaLocaleProvider.getLabel; + +class CodeAction extends Component { + constructor(props) { + super(props); + this.state = { + disabled: false, + variableText: "", + funcText: "", + variItemText: "", + variableList: [], //变量列表 + variableExpandedKeys: [], //变量展开的节点 + funcList: [], //函数列表 + funcExpandedKeys: [], //函数展开的节点 + funcHoverItem: {} //选中的函数节点 + }; + } + + componentDidMount() { + const { groupParams = {} } = this.props; + this.getFormulaDes(); + this.formualSearchGroup(groupParams); + } + + componentWillReceiveProps(nextProps, nextContext) { + const { isCustomFunction, isCustomFunctionClick, onChangeCustomFunction } = nextProps; + if (isCustomFunction === "1" && !isCustomFunctionClick) { + this.setState({ disabled: true }); + } else { + this.setState({ disabled: false }, () => { + isCustomFunction === "1" && onChangeCustomFunction("0"); + }); + } + } + + getFormulaDes = () => { + getFormulaDes().then(({ data }) => { + if (!_.isEmpty(data)) this.setState({ funcList: data }); + }); + }; + formualSearchGroup = (payload) => { + formualSearchGroup(payload).then(({ status, data }) => { + if (status) this.setState({ + variableList: _.map(data, item => ({ + ...item, + children: [{ name: "", fieldId: "searchInput" }] + })) + }); + }); + }; + formualSearchField = (sourceId) => { + const { groupParams } = this.props; + const { variableList } = this.state; + formualSearchField({ sourceId, extendParam: { ...groupParams } }).then(({ status, data }) => { + if (status) { + this.setState({ + variableList: _.map(variableList, it => ({ + ...it, + children: sourceId === it.key ? [...it.children, ...data] : [...it.children] + })) + }); + } + }); + }; + handleExpandVari = (variableExpandedKeys, { expanded, node }) => { + const { props: { eventKey } } = node; + const { variableList } = this.state; + this.setState({ variableExpandedKeys }); + if (expanded) { + this.formualSearchField(eventKey); + } else { + this.setState({ + variableList: _.map(variableList, it => ({ + ...it, + children: eventKey === it.key ? [{ name: "", fieldId: "searchInput" }] : [...it.children] + })) + }); + } + }; + handleVariNode = (selectedKeys) => { + const { onVariSelect } = this.props; + const { variableList } = this.state; + const parentNode = _.map(variableList, it => it.key); + if (selectedKeys.join() && selectedKeys.join().indexOf("searchInput") === -1 && + !parentNode.includes(selectedKeys.join())) { + const selectParentNodeKey = selectedKeys.join().split("_")[0]; + const convertStr = _.reduce(variableList, (pre, cur) => { + if (cur.key === selectParentNodeKey) { + return pre + cur.value + "." + _.find(cur.children, child => child.fieldId === selectedKeys.join()).name; + } + return pre; + }, ""); + onVariSelect(convertStr); + } + }; + + render() { + const { + variableList, variableExpandedKeys, variableText, variItemText, + funcList, funcText, funcExpandedKeys, funcHoverItem, disabled + } = this.state; + const { groupParams = {} } = this.props; + const { referenceType } = groupParams; + const variableDatalist = _.filter(variableList, it => it.value.indexOf(variableText) !== -1); + const funcDatalist = _.map(funcList, it => ({ + ...it, + children: _.filter(it.children, child => _.lowerCase(child.name).indexOf(_.lowerCase(funcText)) !== -1) + })); + return ( +
+
+
+
{getLabel(111, "变量")}
+
+
+ this.setState({ variableText })}/> + + { + _.map(variableDatalist, item => { + const { key, value, children = [] } = item; + const itemChildren = _.filter(children.slice(1), it => it.name.indexOf(variItemText) !== -1); + return + { + _.map([...children.slice(0, 1), ...itemChildren], (child, childIndex) => { + const { name, fieldId } = child; + return ( + fieldId === "searchInput" ? + this.setState({ variItemText })} + /> + } + key={fieldId + "_" + childIndex}/> : + + ); + }) + } + ; + }) + } + +
+
+ { + referenceType !== "sql" && + +
+
+
{getLabel(111, "函数")}
+
+
+ this.setState({ funcText })}/> + this.setState({ funcExpandedKeys })} + > + { + _.map(funcDatalist, item => { + const { name, dataType, children = [] } = item; + return + { + _.map(children, (child, childIndex) => { + const { name: childName, chineseName } = child; + return ( + this.props.onFuncSelect(childName)} + onMouseEnter={() => this.setState({ funcHoverItem: child })}> + {childName} + {chineseName} +
+ } + key={childIndex} + /> + ); + }) + } + ; + }) + } + +
+
+
+
+
+ {!_.isEmpty(funcHoverItem) ? funcHoverItem.name : getLabel(111, "提示")} +
+
+
+
+ + } + + ); + } +} + +export default CodeAction; + +const TipList = (props) => { + const { tips } = props; + const { paramDescs = [], formatString, description, example, result } = tips; + return _.isEmpty(tips) ?
+
+ {/*
{getLabel(111, "{C:选项} 用来选择特定选项字段下的备选项")}
*/} + {/*
{getLabel(111, "{U:姓名} 用来选择工作区成员")}
*/} + {/*
{getLabel(111, "{D:数据} 用来选择一个部门")}
*/} +
+
:
+
+
{getLabel(111, "语法")}
+
+
{formatString}
+
{description}
+
+
{getLabel(111, "参数")}
+ { + _.map(paramDescs, it => { + return
+ . + {it} +
; + }) + } +
{getLabel(111, "示例")}
+ {example} +
{getLabel(111, "结果")}
+ {result} +
+
; +}; diff --git a/pc4mobx/hrmSalary/components/excelEditor/constants.js b/pc4mobx/hrmSalary/components/excelEditor/constants.js new file mode 100644 index 00000000..2bb11e58 --- /dev/null +++ b/pc4mobx/hrmSalary/components/excelEditor/constants.js @@ -0,0 +1,16 @@ +export const keyboardBaseBtns=[ + { key:"+", label: "+" }, + { key:"-", label: "-" }, + { key:">", label: ">" }, + { key:">=", label: ">=" }, + { key:"=", label: "=" }, + { key:"*", label: "*" }, + { key:"/", label: "/" }, + { key:"<", label: "<" }, + { key:"<=", label: "<=" }, + { key:"!=", label: "!=" }, + { key:"()", label: "(" }, + { key:")", label: ")" }, + { key:"%", label: "%" }, + { key:" ", label: "space" }, +] diff --git a/pc4mobx/hrmSalary/components/excelEditor/extendCodeMirror.js b/pc4mobx/hrmSalary/components/excelEditor/extendCodeMirror.js new file mode 100644 index 00000000..e70c6967 --- /dev/null +++ b/pc4mobx/hrmSalary/components/excelEditor/extendCodeMirror.js @@ -0,0 +1,112 @@ +// extendCodeMirror.js +/* eslint-disable */ +import * as CodeMirror from "codemirror"; + +CodeMirror.extendMode("css", { + commentStart: "/*", + commentEnd: "*/", + newlineAfterToken: function (type, content) { + return /^[;{}]$/.test(content); + } +}); + +CodeMirror.extendMode("javascript", { + commentStart: "", + commentEnd: "", +// FIXME semicolons inside of for + newlineAfterToken: function (type, content, textAfter, state) { + if (this.jsonMode) { + return /^[\[,{]$/.test(content) || /^}/.test(textAfter) || /^]/.test(textAfter); + } else { + if (content == ";" && state.lexical && state.lexical.type == ")") return false; + return /^[;{}]$/.test(content) && !/^;/.test(textAfter); + } + } +}); + +CodeMirror.extendMode("xml", { + commentStart: "", + newlineAfterToken: function (type, content, textAfter) { + return type == "tag" && />$/.test(content) || /^ -1 && endIndex > -1 && endIndex > startIndex) { + // Take string till comment start + selText = selText.substr(0, startIndex) + // From comment start till comment end + + selText.substring(startIndex + curMode.commentStart.length, endIndex) + // From comment end till string end + + selText.substr(endIndex + curMode.commentEnd.length); + } + cm.replaceRange(selText, from, to); + } + }); +}); + +// Applies automatic mode-aware indentation to the specified range +CodeMirror.defineExtension("autoIndentRange", function (from, to) { + var cmInstance = this; + this.operation(function () { + for (var i = from.line; i <= to.line; i++) { + cmInstance.indentLine(i, "smart"); + } + }); +}); + +// Applies automatic formatting to the specified range +CodeMirror.defineExtension("autoFormatRange", function (from, to) { + var cm = this; + var outer = cm.getMode(), text = cm.getRange(from, to).split("\n"); + var state = CodeMirror.copyState(outer, cm.getTokenAt(from).state); + var tabSize = cm.getOption("tabSize"); + + var out = "", lines = 0, atSol = from.ch == 0; + + function newline() { + out += "\n"; + atSol = true; + ++lines; + } + + for (var i = 0; i < text.length; ++i) { + var stream = new CodeMirror.StringStream(text[i], tabSize); + while (!stream.eol()) { + var inner = CodeMirror.innerMode(outer, state); + var style = outer.token(stream, state), cur = stream.current(); + stream.start = stream.pos; + if (!atSol || /\S/.test(cur)) { + out += cur; + atSol = false; + } + if (!atSol && inner.mode.newlineAfterToken && + inner.mode.newlineAfterToken(style, cur, stream.string.slice(stream.pos) || text[i + 1] || "", inner.state)) + newline(); + } + if (!stream.pos && outer.blankLine) outer.blankLine(state); + if (!atSol) newline(); + } + + cm.operation(function () { + cm.replaceRange(out, from, to); + for (var cur = from.line + 1, end = from.line + lines; cur <= end; ++cur) + cm.indentLine(cur, "smart"); + cm.setSelection(from, cm.getCursor(false)); + }); +}); +// export default CodeMirror; +module.exports = { CodeMirror }; diff --git a/pc4mobx/hrmSalary/components/excelEditor/index.js b/pc4mobx/hrmSalary/components/excelEditor/index.js new file mode 100644 index 00000000..8b0fe4ae --- /dev/null +++ b/pc4mobx/hrmSalary/components/excelEditor/index.js @@ -0,0 +1,175 @@ +import React, { Component } from "react"; +import { Button } from "antd"; +import { WeaLocaleProvider } from "ecCom"; +import { Controlled as CodeMirror } from "react-codemirror2"; +import { keyboardBaseBtns } from "./constants"; +import CodeAction from "./components/codeAction"; +import cs from "classnames"; +import "./index.less"; +import "codemirror/lib/codemirror.css"; +import "codemirror/lib/codemirror.js"; +import "codemirror/mode/javascript/javascript.js"; + +require("./extendCodeMirror"); +const getLabel = WeaLocaleProvider.getLabel; + +class ExcelEditor extends Component { + constructor(props) { + super(props); + this.state = { + value: "", + isFormter: false, + isCustomFunctionClick: false + }; + this.editorRef = null; + this.timer = null; + } + + componentWillReceiveProps(nextProps, nextContext) { + if (nextProps.value !== this.props.value && nextProps.value) this.setState({ value: nextProps.value }); + } + + componentWillUnmount() { + if (this.timer) clearInterval(this.timer); + this.setState({ isCustomFunctionClick: false }); + } + + autoFormatSelection = () => { + const { isFormter } = this.state; + if (isFormter) { + const script_length = this.editorRef.getValue().length; + const startPos = { line: 0, ch: 0, sticky: null }; + const endPos = this.editorRef.doc.posFromIndex(script_length); + this.editorRef.setSelection(startPos, endPos); + this.editorRef.autoFormatRange(startPos, endPos); + this.editorRef.commentRange(true, startPos, endPos); + } else { + this.editorRef.undo(); + // this.editorRef.undo(); + } + }; + insertText = text => { + const cursor = this.editorRef.getCursor(); + this.editorRef.replaceRange(text, cursor); + this.editorRef.refresh(); + this.editorRef.focus(); + }; + replaceToWidget = (editor) => { + editor.getAllMarks().forEach(m => m.clear()); + }; + handleVariSelect = str => this.insertText(`{${str}}`); + handleFuncSelect = str => { + const cursor = this.editorRef.getCursor(); + this.editorRef.replaceRange(`${str}()`, cursor); + this.timer = setTimeout(() => { + const { line, ch } = this.editorRef.getCursor(); + this.editorRef.setCursor({ line, ch: ch - 1 }); + this.editorRef.refresh(); + this.editorRef.focus(); + }, 100); + }; + handleEditorRedo = () => { + const { ch, line } = this.editorRef.getCursor(); + const delStr = this.editorRef.getRange({ line, ch: ch - 1 }, { line, ch }); + const codeValue = this.editorRef.getValue(); + if (delStr === "}") { + if (codeValue.slice(0, ch).lastIndexOf("{") === -1) { + this.editorRef.replaceRange("", { line, ch: ch - 1 }, { line, ch }); + } else { + this.editorRef.replaceRange("", { line, ch: codeValue.slice(0, ch).lastIndexOf("{") }, { line, ch }); + } + } else { + this.editorRef.replaceRange("", { line, ch: ch - 1 }, { line, ch }); + } + this.editorRef.refresh(); + this.editorRef.focus(); + }; + handleBackSpaceRedo = () => { + const { ch, line } = this.editorRef.getCursor(); + const delStr = this.editorRef.getRange({ line, ch: ch - 1 }, { line, ch }); + const codeValue = this.editorRef.getValue(); + if (delStr === "}") { + if (codeValue.slice(0, ch).lastIndexOf("{") === -1) { + this.editorRef.replaceRange("", { line, ch: ch - 1 }, { line, ch }); + } else { + this.editorRef.replaceRange("", { line, ch: codeValue.slice(0, ch).lastIndexOf("{") + 1 }, { line, ch }); + } + } + this.editorRef.refresh(); + this.editorRef.focus(); + }; + + render() { + const { isFormter, isCustomFunctionClick } = this.state; + const { groupParams = {}, isCustomFunction, value, onChangeCustomFunction } = this.props; + const { referenceType } = groupParams; + return ( + +
+
+ this.editorRef = editor} + value={this.state.value} + onBeforeChange={(editor, data, value) => { + this.setState({ value }, () => this.props.onChange(this.state.value)); + }} + onChange={(editor, data, value) => { + this.replaceToWidget(editor, data, value); + }} + options={{ + lineNumbers: false, + mode: "javascript", + autofocus: false, + styleActiveLine: true, + lineWrapping: true, + matchBrackets: true, + lint: false, + indentUnit: 2, + cursorHeight: 0.85, + placeholder: "", + showCursorWhenSelecting: true + }} + onKeyDown={(_, { keyCode }) => keyCode === 8 && this.handleBackSpaceRedo()} + /> +
+ { + referenceType !== "sql" && +
+
+
+ { + _.map(keyboardBaseBtns, item => { + const { key, label } = item; + return ; + }) + } +
+
+ + +
+
+ +
+ } +
+ {/*公式参数列表*/} + +
+ ); + } +} + +export default ExcelEditor; diff --git a/pc4mobx/hrmSalary/components/excelEditor/index.less b/pc4mobx/hrmSalary/components/excelEditor/index.less new file mode 100644 index 00000000..0ea0081a --- /dev/null +++ b/pc4mobx/hrmSalary/components/excelEditor/index.less @@ -0,0 +1,199 @@ +.excel-codeWrap { + width: 100%; + display: flex; + justify-content: space-around; + padding: 0 0 8px; + + .excel-codeBox { + flex: 1; + overflow: auto; + background: #fff; + box-sizing: content-box; + border: 1px solid #e5e5e5; + + span { + font-family: Liberation Mono, LiberationMonoRegular, Courier New, monospace; + } + + .CodeMirror-code { + font-size: 16px; + + + } + + .CodeMirror-scroll { + overflow-x: visible !important; + padding: 4px; + } + + .CodeMirror-sizer { + margin-left: 0 !important; + } + + .CodeMirror-gutters { + border-right: none; + background-color: #f7f7f7; + opacity: 0; + display: none; + } + } + + .excel-codeBox-keyboard { + width: 272px; + min-height: 232px; + padding: 20px; + background: #fff; + border: 1px solid #e5e5e5; + border-left: none; + + .excel-codeBox-keyboard-operate { + display: flex; + + .excel-codeBox-keyboard-operate-content { + display: flex; + flex-wrap: wrap; + flex: 1; + + .excel-codeBox-keyboard-base { + width: 30px; + height: 30px; + text-align: center; + margin: 0 10px 10px 0; + } + + .excel-codeBox-keyboard-space { + width: 70px; + height: 30px; + } + } + + .excel-codeBox-keyboard-operate-clear { + width: 30px; + + .excel-codeBox-keyboard-del { + width: 30px; + height: 70px; + } + + .excel-codeBox-keyboard-clear { + width: 30px; + height: 30px; + margin-top: 10px; + } + } + } + } +} + +.excel-codeAction { + width: 100%; + display: flex; + justify-content: space-between; + + .excel-codeAction-item:last-child { + margin-right: 0; + + .excel-codeAction-header-title { + color: rgb(217, 82, 189); + } + } + + .excel-codeAction-item { + width: 33%; + min-height: 317px; + flex: 1; + background: #fff; + border: 1px solid #e5e5e5; + margin-right: 16px; + display: flex; + flex-direction: column; + + .excel-codeAction-header { + display: flex; + padding: 10px 16px; + border-bottom: 1px solid #e5e5e5; + + .excel-codeAction-header-title { + flex: 1; + font-weight: 600; + } + } + + .excel-codeAction-content { + flex: 1; + overflow: hidden auto; + padding: 0 16px; + max-height: 280px; + position: relative; + + .variableOuterInput { + width: 100%; + margin-top: 10px; + position: sticky; + top: 10px; + background-color: #fff; + z-index: 1; + } + + .variableTree { + li a:hover, li a.ant-tree-node-selected { + background: transparent; + } + + li:first-child { + a { + padding: 2px 5px; + } + } + + li a { + width: calc(100% - 16px); + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + + .ant-tree-title { + display: inline-block; + width: 100%; + + .funcListTitle { + width: 100%; + display: flex; + justify-content: space-between; + + & > span { + display: inline-block; + flex: 1 1; + overflow: hidden; + text-overflow: ellipsis; + word-break: keep-all; + white-space: nowrap; + } + + .functionName { + max-width: 100px; + } + + .functionDesc { + max-width: 100px; + text-align: right; + color: #999; + } + } + } + } + } + + .code-action-list { + padding: 10px 0; + .code-action-tips-title{ + height: 22px; + line-height: 22px; + } + .code-action-tips-info{ + color: #999 + } + } + } + } +} diff --git a/pc4mobx/hrmSalary/components/upload/index.js b/pc4mobx/hrmSalary/components/upload/index.js new file mode 100644 index 00000000..fd7cdd57 --- /dev/null +++ b/pc4mobx/hrmSalary/components/upload/index.js @@ -0,0 +1,84 @@ +import React, { Component } from "react"; +import { WeaLocaleProvider, WeaTools, WeaUpload } from "ecCom"; +import { Icon, Modal } from "antd"; +import "./index.less"; + +const getLabel = WeaLocaleProvider.getLabel; +const { viewer } = WeaTools; + +class ImageUploadList extends Component { + constructor(props) { + super(props); + this.state = { + imageUrl: "" + }; + } + + componentDidMount() { + const { wmImg } = this.props; + if (!_.isEmpty(wmImg)) { + this.setState({ + imageUrl: wmImg[0].imgSrc + }); + } + } + + handleChange = (ids, list) => { + this.setState({ + imageUrl: list[0].imgSrc + }, () => this.props.onChange([{ imgSrc: this.state.imageUrl }])); + }; + handleDelete = () => { + Modal.confirm({ + title: getLabel(111, "信息确认"), + content: getLabel(111, "确认要删除吗?"), + onOk: () => { + this.setState({ + imageUrl: "" + }, () => this.props.onChange(null)); + } + }); + }; + + + render() { + const { imageUrl } = this.state; + const uploadProps = { + uploadUrl: "/api/doc/upload/uploadFile", + listType: "img", + limitType: "jpg,jpeg,png,gif", + category: "string", + maxFilesNumber: 1, + onChange: this.handleChange + }; + const imgPreviewProps = { + src: imageUrl, + width: 100, + height: 100 + }; + return ( +
+ { + imageUrl && +
+ +
+ +
+
+ } + { + !imageUrl && + +
+ +
{getLabel(111, "上传图片")}
+
+
+ } +
+ ); + } +} + +export default ImageUploadList; diff --git a/pc4mobx/hrmSalary/components/upload/index.less b/pc4mobx/hrmSalary/components/upload/index.less new file mode 100644 index 00000000..577de7c7 --- /dev/null +++ b/pc4mobx/hrmSalary/components/upload/index.less @@ -0,0 +1,68 @@ +.textSetting { + .uploadWrapper { + display: flex; + align-items: center; + position: relative; + + .previewWrapper { + border: 1px solid #d9d9d9 !important; + + img { + width: 100%; + height: 100%; + margin-left: 0 !important; + cursor: pointer; + } + + .operateWrapper { + display: none; + } + } + + .previewWrapper:hover { + .operateWrapper { + display: flex; + position: absolute; + align-items: center; + justify-content: flex-end; + width: 30px; + height: 20px; + background-color: rgba(0, 0, 0, 0.3); + bottom: 4px; + right: 13px; + border-radius: 3px; + padding-right: 4px; + } + } + } + + .upload-select-picture-card, .previewWrapper { + border: 1px dashed #d9d9d9; + width: 96px; + height: 96px; + padding: 0; + border-radius: 6px; + background-color: #fbfbfb; + text-align: center; + cursor: pointer; + -webkit-transition: border-color .3s ease; + -o-transition: border-color .3s ease; + transition: border-color .3s ease; + display: flex; + flex-direction: column; + justify-content: center; + margin-right: 8px; + margin-bottom: 8px; + + span.rc-upload { + height: 100%; + display: flex; + align-items: center; + justify-content: center; + } + } + + .upload-select-picture-card:hover { + border-color: #2db7f5; + } +} diff --git a/pc4mobx/hrmSalary/index.js b/pc4mobx/hrmSalary/index.js index 1165659b..d004267c 100644 --- a/pc4mobx/hrmSalary/index.js +++ b/pc4mobx/hrmSalary/index.js @@ -32,6 +32,11 @@ import SysConfig from "./pages/sysConfig"; import RuleConfig from "./pages/ruleConfig"; import Appconfig from "./pages/appConfig"; import FieldManagement from "./pages/fieldManagement"; +import AnalysisOfSalaryStatistics from "./pages/analysisOfSalaryStatistics"; +import EmployeeList from "./pages/employeeView"; +import ReportView from "./pages/reportView"; +import MySalaryView from "./pages/mySalary/mySalaryView"; +import WatermarkPreview from "./pages/payroll/watermarkPreview"; import ExternalPersonManage from "./pages/externalPersonManage"; import stores from "./stores"; @@ -51,6 +56,7 @@ const SocialSecurityBenefits = (props) => props.children; const DataAcquisition = (props) => props.children; // mySalary 我的薪资福利 +// mySalaryView 我的薪资福利-查看工资单 // socialSecurityBenefits 社保福利 // programme 社保福利方案 // archives 社保福利档案 @@ -79,6 +85,8 @@ const DataAcquisition = (props) => props.children; // sysconfig-1 规则配置 // appconfig 应用配置 // fieldManagement 字段管理 +// analysisOfSalaryStatistics 薪酬统计分析 +// reportView 薪酬报表查看 // externalPersonManage 非系统人员管理 const Routes = ( @@ -88,6 +96,7 @@ const Routes = ( onEnter={getLocaleLabel} component={Home}> + + + + + ); diff --git a/pc4mobx/hrmSalary/pages/analysisOfSalaryStatistics/components/conditions.js b/pc4mobx/hrmSalary/pages/analysisOfSalaryStatistics/components/conditions.js new file mode 100644 index 00000000..a622aefb --- /dev/null +++ b/pc4mobx/hrmSalary/pages/analysisOfSalaryStatistics/components/conditions.js @@ -0,0 +1,101 @@ +import { WeaLocaleProvider } from "ecCom"; + +const { getLabel } = WeaLocaleProvider; +export const condition = [ + { + items: [ + { + colSpan: 1, + checkbox: false, + checkboxValue: false, + conditionType: "SELECT", + domkey: ["dimType"], + fieldcol: 14, + label: getLabel(111, "维度类型"), + labelcol: 6, + options: [], + detailtype: 3, + rules: "required|string", + viewAttr: 3 + }, + { + colSpan: 1, + conditionType: "SELECT", + domkey: ["setting4Qualitative"], + fieldcol: 14, + label: getLabel(111, "统计维度"), + labelcol: 6, + options: [], + rules: "required|string", + viewAttr: 3 + }, + { + colSpan: 1, + conditionType: "INPUT", + domkey: ["dimName"], + fieldcol: 14, + label: getLabel(111, "统计维度名称"), + labelcol: 6, + value: "", + rules: "required|string", + viewAttr: 3 + }, + { + colSpan: 1, + conditionType: "SELECT", + domkey: ["dimCode"], + fieldcol: 14, + label: getLabel(111, "分组所属字段"), + labelcol: 6, + options: [], + viewAttr: 2, + helpfulTip: "", + hide: true + }, + { + colSpan: 1, + conditionType: "TEXTAREA", + domkey: ["remark"], + fieldcol: 14, + label: getLabel(111, "描述"), + labelcol: 6, + value: "", + viewAttr: 2 + } + ], + title: getLabel(111, "基础设置"), + defaultshow: true + } +]; +export const reportCondition = [ + { + items: [ + { + colSpan: 1, + conditionType: "INPUT", + domkey: ["reportName"], + fieldcol: 14, + label: getLabel(111, "报表名称"), + labelcol: 6, + value: "", + rules: "required|string", + viewAttr: 3 + }, + { + colSpan: 1, + conditionType: "SELECT", + domkey: ["dimensionIds"], + fieldcol: 14, + label: getLabel(111, "统计维度"), + labelcol: 6, + options: [], + rules: "required|string", + viewAttr: 3, + helpfulTip: "", + hide: true + } + ], + title: "", + defaultshow: true + } +]; diff --git a/pc4mobx/hrmSalary/pages/analysisOfSalaryStatistics/components/dimensionSlide.js b/pc4mobx/hrmSalary/pages/analysisOfSalaryStatistics/components/dimensionSlide.js new file mode 100644 index 00000000..b7bd9c2e --- /dev/null +++ b/pc4mobx/hrmSalary/pages/analysisOfSalaryStatistics/components/dimensionSlide.js @@ -0,0 +1,205 @@ +/* + * Author: 黎永顺 + * name: 新增统计维度弹框 + * Description: + * Date: 2023/4/11 + */ +import React, { Component } from "react"; +import { WeaDialog, WeaLocaleProvider, WeaSearchGroup } from "ecCom"; +import { Button, message, Modal } from "antd"; +import { dimensionGetForm, dimensionSave } from "../../../apis/statistics"; +import { getSearchs } from "../../../util"; +import GroupSpacingEditTable from "./groupSpacingEditTable"; +import GroupIndividualEditTable from "./groupIndividualEditTable"; +import "../index.less"; + +const { getLabel } = WeaLocaleProvider; +const keyObj = { + "RATION_GROUP_SPACING": "setting4RationGroupSpacing", + "RATION_GROUP_INDIVIDUAL": "setting4RationGroupIndividual" +}; + +class DimensionSlide extends Component { + constructor(props) { + super(props); + this.state = { + loading: false, + dimType: "QUALITATIVE", + setting4RationGroupSpacing: [], + setting4RationGroupIndividual: [] + }; + } + + componentDidMount() { + this.props.initCondition(); + } + + componentWillReceiveProps(nextProps, nextContext) { + if (nextProps.visible !== this.props.visible && nextProps.formId) this.dimensionGetForm({ id: nextProps.formId }); + if (nextProps.visible !== this.props.visible && !nextProps.formId) { + nextProps.form.updateFields({ + dimType: "QUALITATIVE" + }); + nextProps.onChangeCondition("QUALITATIVE"); + } + if (nextProps.visible !== this.props.visible && !nextProps.visible) { + this.setState({ + loading: false, + dimType: "QUALITATIVE", + setting4RationGroupSpacing: [], + setting4RationGroupIndividual: [] + }); + } + } + + + dimensionGetForm = (payload) => { + dimensionGetForm(payload).then(({ status, data }) => { + if (status) { + const { baseForm: { data: formData } } = data; + const setting = formData.setting ? JSON.parse(formData.setting) : {}; + this.props.onChangeCondition(formData["dimType"], 1); + this.setState({ + dimType: formData.dimType, + [keyObj[formData["dimType"]]]: setting + }, () => { + const fields = _.map(this.props.condition[0].items, it => { + return it.domkey[0]; + }); + fields.map(item => { + if (item !== "setting4Qualitative") { + this.props.form.updateFields({ + [item]: formData[item] || "" + }); + } else if (item === "setting4Qualitative" && formData.statsDim) { + this.props.form.updateFields({ + setting4Qualitative: formData.statsDim + }); + } + }); + }); + } + }); + }; + handleSave = () => { + const { dimType } = this.state; + const { condition, onCancel, formId } = this.props; + const { setting4Qualitative, dimCode, ...extraParams } = this.props.form.getFormParams(); + let payload = { id: formId, ...extraParams }; + if (dimType === "QUALITATIVE") { + if (!setting4Qualitative || !extraParams.dimName) { + Modal.warning({ + title: getLabel(111, "信息确认"), + content: getLabel(111, "必要信息不完整,红色*为必填项!") + }); + return; + } + const tjOptions = _.find(condition[0].items, item => item.domkey[0] === "setting4Qualitative").options; + const tjObj = _.find(tjOptions, item => item.key === setting4Qualitative); + payload = { ...payload, setting4Qualitative: { id: tjObj.key, name: tjObj.showname } }; + } else { + if (!extraParams.dimName) { + Modal.warning({ + title: getLabel(111, "信息确认"), + content: getLabel(111, "必要信息不完整,红色*为必填项!") + }); + return; + } + if (dimType === "RATION_GROUP_SPACING") { + const { setting4RationGroupSpacing } = this.state; + const bool = _.every(setting4RationGroupSpacing, it => it.startValue !== "" && it.endValue !== "" && it.startValue <= it.endValue); + if (_.isEmpty(setting4RationGroupSpacing) || !bool) { + message.warning(getLabel(111, "请完善分组设置相关数据!分组设置不能为空,起始值结束值必填,且起始值需小于结束值!")); + return; + } else { + payload = { + ...payload, dimCode, + setting4RationGroupSpacing: _.map(setting4RationGroupSpacing, (it, index) => ({ + id: index + 1, + endValue: it.endValue, + startValue: it.startValue, + includeEnd: it.includeEnd === "1", + includeStart: it.includeStart === "1" + })) + }; + } + } else if (dimType === "RATION_GROUP_INDIVIDUAL") { + const { setting4RationGroupIndividual } = this.state; + const bool = _.every(setting4RationGroupIndividual, it => it.value !== ""); + if (_.isEmpty(setting4RationGroupIndividual) || !bool) { + message.warning(getLabel(111, "请完善分组设置相关数据!分组设置不能为空,且数值必填")); + return; + } else { + payload = { + ...payload, dimCode, + setting4RationGroupIndividual: _.map(setting4RationGroupIndividual, (it, index) => ({ id: index + 1, ...it })) + }; + } + } + } + this.setState({ loading: true }); + dimensionSave(payload).then(({ status, errormsg }) => { + this.setState({ loading: false }); + if (status) { + message.success(getLabel(111, "保存成功")); + onCancel(true); + this.props.form.resetForm(); + } else { + message.error(errormsg || getLabel(111, "保存失败")); + } + }).catch(() => this.setState({ loading: false })); + }; + formItemChange = (formObj) => { + const { onChangeCondition } = this.props; + const filedKey = _.keys(formObj)[0]; + if (filedKey === "dimType") { + this.setState({ + dimType: formObj[filedKey].value, + setting4RationGroupSpacing: [], + setting4RationGroupIndividual: [] + }, () => onChangeCondition(formObj[filedKey].value)); + } + }; + handleConvertGroupDatasource = (data) => { + const { dimType } = this.state; + this.setState({ [keyObj[dimType]]: data }); + }; + + render() { + const { loading, dimType, setting4RationGroupSpacing, setting4RationGroupIndividual } = this.state; + const { form, condition, formId } = this.props; + return ( + + {formId ? getLabel(111, "编辑统计维度") : getLabel(111, "新建统计维度")} + + + } + > + {getSearchs(form, condition, 1, false, this.formItemChange)} + { + dimType !== "QUALITATIVE" && + + { + dimType === "RATION_GROUP_SPACING" && + + } + { + dimType === "RATION_GROUP_INDIVIDUAL" && + + } + + } + + ); + } +} + +export default DimensionSlide; diff --git a/pc4mobx/hrmSalary/pages/analysisOfSalaryStatistics/components/dimensionTable.js b/pc4mobx/hrmSalary/pages/analysisOfSalaryStatistics/components/dimensionTable.js new file mode 100644 index 00000000..48eecf43 --- /dev/null +++ b/pc4mobx/hrmSalary/pages/analysisOfSalaryStatistics/components/dimensionTable.js @@ -0,0 +1,121 @@ +/* + * Author: 黎永顺 + * name: 统计维度管理列表 + * Description: + * Date: 2023/4/11 + */ +import React, { Component } from "react"; +import { WeaLocaleProvider, WeaTable } from "ecCom"; +import { message, Modal } from "antd"; +import { dimensionDelete, dimensionList } from "../../../apis/statistics"; +import "../index.less"; + +const { getLabel } = WeaLocaleProvider; + +class DimensionTable extends Component { + constructor(props) { + super(props); + this.state = { + loading: false, + dataSource: [], + pageInfo: { + current: 1, pageSize: 10, total: 0 + } + }; + } + + componentDidMount() { + this.dimensionList(); + } + + dimensionList = (extra = {}) => { + const { pageInfo } = this.state; + this.setState({ loading: true }); + dimensionList({ ...pageInfo, ...extra }).then(({ status, data }) => { + this.setState({ loading: false }); + if (status) { + const { pageNum: current, pageSize, total, list: dataSource } = data; + this.setState({ + dataSource, + pageInfo: { + ...pageInfo, + current, pageSize, total + } + }); + } + }).catch(() => this.setState({ loading: false })); + }; + dimensionDelete = (payload) => { + Modal.confirm({ + title: getLabel(111, "信息确认"), + content: getLabel(111, "确认要删除吗?"), + onOk: () => { + dimensionDelete(payload).then(({ status, errormsg }) => { + if (status) { + message.success(getLabel(111, "删除成功")); + this.dimensionList(); + } else { + message.error(errormsg || getLabel(111, "删除失败")); + } + }); + } + }); + }; + + render() { + const { dataSource, loading, pageInfo } = this.state; + const { onEdit } = this.props; + const pagination = { + ...pageInfo, + showTotal: total => `${getLabel(111, "共")} ${total} ${getLabel(111, "条")}`, + showQuickJumper: true, + showSizeChanger: true, + pageSizeOptions: ["10", "20", "50", "100"], + onShowSizeChange: (current, pageSize) => { + this.setState({ + pageInfo: { ...pageInfo, current, pageSize } + }, () => this.dimensionList()); + }, + onChange: current => { + this.setState({ + pageInfo: { ...pageInfo, current } + }, () => this.dimensionList()); + } + }; + const columns = [ + { dataIndex: "dimName", title: getLabel(111, "统计维度") }, + { dataIndex: "remark", title: getLabel(111, "描述") }, + { dataIndex: "dimType", title: getLabel(111, "维度类型") }, + { + dataIndex: "operate", title: getLabel(111, "操作"), + render: (_, record) => { + return ( + + { + record.canEdit && + onEdit(record.id)}>{getLabel(111, "编辑")} + } + { + record.canDelete && + this.dimensionDelete([record.id])}>{getLabel(111, "删除")} + } + + ); + } + } + ]; + return ( + + ); + } +} + +export default DimensionTable; diff --git a/pc4mobx/hrmSalary/pages/analysisOfSalaryStatistics/components/employeeDetails.js b/pc4mobx/hrmSalary/pages/analysisOfSalaryStatistics/components/employeeDetails.js new file mode 100644 index 00000000..dc89547d --- /dev/null +++ b/pc4mobx/hrmSalary/pages/analysisOfSalaryStatistics/components/employeeDetails.js @@ -0,0 +1,103 @@ +/* + * Author: 黎永顺 + * name: 员工明细列表 + * Description: + * Date: 2023/5/24 + */ +import React, { Component } from "react"; +import { WeaLocaleProvider, WeaTable } from "ecCom"; +import { statisticsEmployeeList } from "../../../apis/statistics"; +import "../index.less"; + +const { getLabel } = WeaLocaleProvider; + +class EmployeeDetails extends Component { + constructor(props) { + super(props); + this.state = { + loading: false, + dataSource: [], + columns: [], + pageInfo: { + current: 1, + pageSize: 10, + total: 0 + } + }; + } + + componentDidMount() { + this.statisticsEmployeeList(); + } + + componentWillReceiveProps(nextProps, nextContext) { + if (nextProps.year !== this.props.year) this.statisticsEmployeeList(nextProps); + } + + statisticsEmployeeList = (props) => { + const { pageInfo } = this.state; + const payload = { + year: props ? props.year : this.props.year, + keyword: props ? props.keyword : this.props.keyword, + ...pageInfo + }; + this.setState({ loading: true }); + statisticsEmployeeList(payload).then(({ status, data }) => { + this.setState({ loading: false }); + if (status) { + const { columns, list: dataSource, pageNum: current, total, pageSize } = data; + this.setState({ + pageInfo: { ...pageInfo, current, pageSize, total }, + dataSource, + columns: [...columns, { + title: "操作", + dataIndex: "operate", + width: 80, + render: (_, record) => { + return {getLabel(111, "查看")}; + } + }] + }); + } + }).catch(() => this.setState({ loading: false })); + }; + + render() { + const { dataSource, loading, columns, pageInfo } = this.state; + const pagination = { + ...pageInfo, + showTotal: total => `${getLabel(111, "共")} ${total} ${getLabel(111, "条")}`, + showQuickJumper: true, + showSizeChanger: true, + pageSizeOptions: ["10", "20", "50", "100"], + onShowSizeChange: (current, pageSize) => { + this.setState({ + pageInfo: { ...pageInfo, current, pageSize } + }, () => { + this.statisticsEmployeeList(); + }); + }, + onChange: current => { + this.setState({ + pageInfo: { ...pageInfo, current } + }, () => { + this.statisticsEmployeeList(); + }); + } + }; + return ( + + ); + } +} + +export default EmployeeDetails; diff --git a/pc4mobx/hrmSalary/pages/analysisOfSalaryStatistics/components/groupIndividualEditTable.js b/pc4mobx/hrmSalary/pages/analysisOfSalaryStatistics/components/groupIndividualEditTable.js new file mode 100644 index 00000000..1d709bc6 --- /dev/null +++ b/pc4mobx/hrmSalary/pages/analysisOfSalaryStatistics/components/groupIndividualEditTable.js @@ -0,0 +1,52 @@ +/* + * Author: 黎永顺 + * name: 分组设置-定量-单项式分组编辑表格 + * Description: + * Date: 2023/4/12 + */ +import React, { Component } from "react"; +import { WeaLocaleProvider, WeaTableEdit } from "ecCom"; + +const { getLabel } = WeaLocaleProvider; +class GroupIndividualEditTable extends Component { + constructor(props) { + super(props); + this.state = { + dataSource: [] + }; + } + + componentDidMount() { + const { setting4RationGroupIndividual } = this.props; + this.setState({ + dataSource: setting4RationGroupIndividual + }); + } + + handleChangeTableData = (dataSource) => { + const { onChange } = this.props; + this.setState({ dataSource }, () => onChange(this.state.dataSource)); + }; + + render() { + const { dataSource } = this.state; + const columns = [ + { + title: getLabel(111, "分组设置值"), + dataIndex: "value", + key: "value", + com: [ + { label: "", key: "value", type: "INPUTNUMBER" } + ] + } + ]; + return ( + + ); + } +} + +export default GroupIndividualEditTable; diff --git a/pc4mobx/hrmSalary/pages/analysisOfSalaryStatistics/components/groupSpacingEditTable.js b/pc4mobx/hrmSalary/pages/analysisOfSalaryStatistics/components/groupSpacingEditTable.js new file mode 100644 index 00000000..c976cd93 --- /dev/null +++ b/pc4mobx/hrmSalary/pages/analysisOfSalaryStatistics/components/groupSpacingEditTable.js @@ -0,0 +1,100 @@ +/* + * Author: 黎永顺 + * name: 分组设置-定量-组距式分组编辑表格 + * Description: + * Date: 2023/4/12 + */ +import React, { Component } from "react"; +import { WeaLocaleProvider, WeaTableEdit } from "ecCom"; + +const { getLabel } = WeaLocaleProvider; + +class GroupSpacingEditTable extends Component { + constructor(props) { + super(props); + this.state = { + dataSource: [] + }; + } + + componentDidMount() { + const { setting4RationGroupSpacing } = this.props; + this.setState({ + dataSource: _.map(setting4RationGroupSpacing, item => { + return { + ...item, + includeStart: item.includeStart ? "1" : "0", + includeEnd: item.includeEnd ? "1" : "0" + }; + }) + }); + } + + handleChangeTableData = (dataSource) => { + const { onChange } = this.props; + this.setState({ dataSource }, () => onChange(this.state.dataSource)); + }; + + render() { + const { dataSource } = this.state; + const columns = [ + { + title: getLabel(111, "起始值"), + dataIndex: "startValue", + key: "startValue", + com: [ + { label: "", key: "startValue", type: "INPUTNUMBER" } + ] + }, + { + title: getLabel(111, "含"), + dataIndex: "includeStart", + key: "includeStart", + com: [ + { + type: "CHECKBOX", + key: "includeStart", + otherParams: { content: getLabel(111, "含") } + } + ] + }, + { + title: getLabel(111, "至"), + dataIndex: "to", + key: "to", + com: [ + { label: "", type: "TEXT" } + ] + }, + { + title: getLabel(111, "结束值"), + dataIndex: "endValue", + key: "endValue", + com: [ + { label: "", key: "endValue", type: "INPUTNUMBER" } + ] + }, + { + title: getLabel(111, "含"), + dataIndex: "includeEnd", + key: "includeEnd", + com: [ + { + type: "CHECKBOX", + key: "includeEnd", + otherParams: { content: getLabel(111, "含") } + } + ] + } + ]; + return ( + ({ ...item, to: getLabel(111, "至") }))} + showCopy={false} onChange={this.handleChangeTableData} + /> + ); + } +} + +export default GroupSpacingEditTable; diff --git a/pc4mobx/hrmSalary/pages/analysisOfSalaryStatistics/components/reportForm.js b/pc4mobx/hrmSalary/pages/analysisOfSalaryStatistics/components/reportForm.js new file mode 100644 index 00000000..0308e2ed --- /dev/null +++ b/pc4mobx/hrmSalary/pages/analysisOfSalaryStatistics/components/reportForm.js @@ -0,0 +1,19 @@ +/* + * Author: 黎永顺 + * name: 报表表单 + * Description: + * Date: 2023/4/17 + */ +import React, { Component } from "react"; +import { getSearchs } from "../../../util"; + +class ReportForm extends Component { + render() { + const { form, condition } = this.props; + return ( + {getSearchs(form, condition, 1, false)} + ); + } +} + +export default ReportForm; diff --git a/pc4mobx/hrmSalary/pages/analysisOfSalaryStatistics/components/reportList.js b/pc4mobx/hrmSalary/pages/analysisOfSalaryStatistics/components/reportList.js new file mode 100644 index 00000000..6510d5b1 --- /dev/null +++ b/pc4mobx/hrmSalary/pages/analysisOfSalaryStatistics/components/reportList.js @@ -0,0 +1,106 @@ +/* + * Author: 黎永顺 + * name: 统计表 + * Description: + * Date: 2023/4/17 + */ +import React, { Component } from "react"; +import { WeaLocaleProvider } from "ecCom"; +import { Button, Col, Dropdown, Menu, message, Modal, Row } from "antd"; +import { reportStatisticsReportDelete, reportStatisticsReportList } from "../../../apis/statistics"; +import "../index.less"; + +const SubMenu = Menu.SubMenu; +const { getLabel } = WeaLocaleProvider; + +class ReportList extends Component { + constructor(props) { + super(props); + this.state = { + dataSource: [] + }; + } + + componentDidMount() { + this.reportStatisticsReportList(); + } + + handleOptsClick = ({ key }, id, dimensionId) => { + if (key === "delete") { + this.reportStatisticsReportDelete(id.split(",")); + } else if (key === "edit") { + this.props.onEdit("addReport", id); + } + }; + reportStatisticsReportDelete = (payload) => { + Modal.confirm({ + title: getLabel(111, "信息确认"), + content: getLabel(111, "确认删除本条数据吗?"), + onOk: () => { + const { reportName = "" } = this.props; + reportStatisticsReportDelete(payload).then(({ status, errormsg }) => { + if (status) { + message.success(getLabel(111, "删除成功")); + this.reportStatisticsReportList({ reportName }); + } else { + message.error(errormsg || getLabel(111, "删除失败")); + } + }); + } + }); + }; + reportStatisticsReportList = (payload = {}) => { + reportStatisticsReportList(payload).then(({ status, data: dataSource }) => { + if (status) { + this.setState({ dataSource }); + } + }); + }; + /* + * Author: 黎永顺 + * Description: 报表查看 + * Params: + * Date: 2023/4/20 + */ + handleGoReportView = (id) => { + window.open(`${window.location.origin}/spa/hrmSalary/static/index.html#/main/hrmSalary/reportView?id=${id}`); + }; + + render() { + const { dataSource } = this.state; + return ( + + { + _.isEmpty(dataSource) ?
{getLabel(111, "暂无数据")}
: + _.map(dataSource, it => { + const { reportName, dimension, id, dimensionId } = it; + return this.handleGoReportView(id)}> +
+
+
+ {reportName} +
+
{getLabel(111, "统计维度")}:
+
{dimension}
+
+
+
+ this.handleOptsClick(e, id, dimensionId)}> + {getLabel(111, "编辑")} + {getLabel(111, "删除")} + + }> + + +
+
+ ; + }) + } +
+ ); + } +} + +export default ReportList; diff --git a/pc4mobx/hrmSalary/pages/analysisOfSalaryStatistics/components/statisticsModal.js b/pc4mobx/hrmSalary/pages/analysisOfSalaryStatistics/components/statisticsModal.js new file mode 100644 index 00000000..c8920887 --- /dev/null +++ b/pc4mobx/hrmSalary/pages/analysisOfSalaryStatistics/components/statisticsModal.js @@ -0,0 +1,70 @@ +/* + * Author: 黎永顺 + * name: 统计弹框 + * Description: + * Date: 2023/4/10 + */ +import React, { Component } from "react"; +import { Button, message, Modal } from "antd"; +import { WeaDialog, WeaLocaleProvider } from "ecCom"; +import { reportStatisticsReportSave } from "../../../apis/ruleconfig"; +import "../index.less"; + +const { getLabel } = WeaLocaleProvider; + +class StatisticsModal extends Component { + constructor(props) { + super(props); + this.state = { + loading: false + }; + } + + handleSaveReportList = () => { + const { form, id, onCancel } = this.props; + form.validateForm().then(f => { + if (f.isValid) { + const { dimensionIds, reportName } = form.getFormParams(); + const payload = { id, reportName, dimensionIds: dimensionIds.split(",") }; + this.setState({ loading: true }); + reportStatisticsReportSave(payload).then(({ status, errormsg }) => { + this.setState({ loading: false }); + if (status) { + onCancel(true); + message.success(getLabel(111, "保存成功")); + form.resetForm(); + } else { + message.error(errormsg || getLabel(111, "保存失败")); + } + }).catch(() => this.setState({ loading: false })); + } else { + Modal.warning({ + title: getLabel(111, "信息确认"), + content: getLabel(111, "必要信息不完整,红色*为必填项!") + }); + } + }); + }; + + render() { + const { loading } = this.state; + const { typeKey, onCancel } = this.props; + const buttons = typeKey === "addReport" ? [ + + ] : []; + return ( + + {this.props.children} + + ); + } +} + +export default StatisticsModal; diff --git a/pc4mobx/hrmSalary/pages/analysisOfSalaryStatistics/index.js b/pc4mobx/hrmSalary/pages/analysisOfSalaryStatistics/index.js new file mode 100644 index 00000000..20748a27 --- /dev/null +++ b/pc4mobx/hrmSalary/pages/analysisOfSalaryStatistics/index.js @@ -0,0 +1,312 @@ +/* + * Author: 黎永顺 + * name: 薪酬统计分析 + * Description: + * Date: 2023/4/10 + */ +import React, { Component } from "react"; +import { inject, observer } from "mobx-react"; +import { WeaDatePicker, WeaInputSearch, WeaLocaleProvider, WeaReqTop } from "ecCom"; +import { Button } from "antd"; +import { condition, reportCondition } from "./components/conditions"; +import { commonEnumList, reportGetForm } from "../../apis/ruleconfig"; +import { dimensionGetForm } from "../../apis/statistics"; +import EmployeeDetails from "./components/employeeDetails"; +import StatisticsModal from "./components/statisticsModal"; +import DimensionSlide from "./components/dimensionSlide"; +import DimensionTable from "./components/dimensionTable"; +import ReportList from "./components/reportList"; +import ReportForm from "./components/reportForm"; +import moment from "moment"; +import "./index.less"; + +const { getLabel } = WeaLocaleProvider; + +@inject("taxAgentStore", "attendanceStore") +@observer +class Index extends Component { + constructor(props) { + super(props); + this.state = { + conditions: [], + convertConditions: [], + reportConditions: [], + selectedKey: "statistics", + reportName: "", + keyword: "", + year: moment().format("YYYY"), + slideReq: { + visible: false, formId: "" + }, + modalReq: { + title: "", visible: false, + typeKey: "", id: "" + } + }; + } + + componentDidMount() { + this.initReportFormCondition(); + } + + initReportFormCondition = (payload = {}) => { + const { attendanceStore: { reportForm } } = this.props; + reportGetForm(payload).then(({ status, data }) => { + if (status) { + const { statsDimOptions, data: detailData } = data; + if (_.isEmpty(payload)) { + this.setState({ + reportConditions: _.map(reportCondition, item => { + return { + ...item, + items: _.map(item.items, child => { + if (child.domkey[0] === "dimensionIds") { + return { + ...child, + options: _.map(statsDimOptions, dimTypeItem => ({ + key: dimTypeItem.id, + showname: dimTypeItem.content + })) + }; + } + return { ...child }; + }) + }; + }) + }, () => { + reportForm.initFormFields(this.state.reportConditions); + }); + } else { + reportForm.updateFields({ + reportName: detailData.reportName, + dimensionIds: detailData.dimension.join(",") + }); + } + } + }); + }; + initCondition = async () => { + const { attendanceStore: { statisticsForm } } = this.props; + const [dimTypeEnum, dimCodeList] = await Promise.all([this.commonEnumList(), this.dimensionGetForm()]); + const { data: dimTypeData } = dimTypeEnum, { data: dimCodeData } = dimCodeList; + const { baseForm: { statsDimOptions, groupDimOptions, data: dimTypeValue } } = dimCodeData; + this.setState({ + conditions: _.map(condition, item => { + return { + ...item, + items: _.map(item.items, child => { + if (child.domkey[0] === "dimType") { + return { + ...child, + value: dimTypeValue.dimType, + options: _.map(dimTypeData, dimTypeItem => ({ + key: dimTypeItem.value, + showname: dimTypeItem.defaultLabel + })) + }; + } + if (child.domkey[0] === "setting4Qualitative") { + return { + ...child, + options: _.map(statsDimOptions, dimCodeItem => ({ + key: dimCodeItem.id, + showname: dimCodeItem.content + })) + }; + } + if (child.domkey[0] === "dimCode") { + return { + ...child, + options: _.map(groupDimOptions, dimCodeItem => ({ + key: dimCodeItem.id, + showname: dimCodeItem.content + })) + }; + } + return { ...child }; + }) + }; + }) + }, () => { + this.setState({ convertConditions: this.state.conditions }); + statisticsForm.initFormFields(this.state.conditions); + }); + }; + commonEnumList = () => { + const payload = { + enumClass: "com.engine.salary.report.enums.SalaryStatisticsDimensionTypeEnum" + }; + return commonEnumList(payload); + }; + dimensionGetForm = () => { + return dimensionGetForm(); + }; + handleChangeCondition = (val, viewAttr) => { + const { attendanceStore: { statisticsForm } } = this.props; + const helpfulTitle = val === "RATION_GROUP_SPACING" ? + "例:\n" + + " 若:所属字段为【工龄】,分组设置为【0-5】,【5-10】;统计项为【税前薪资】,对应的统计规则为【求和】; 则统计结果为:【工龄】为【0-5】的所有人的【税前薪资】求和,【工龄】为【5-10】的所有人的【税前薪资】求和;\n" + + "若:未选择所属字段,分组设置为【0-10,000.00】,【10,000.00-20,000.00】;若统计项为【税前薪资】,对应的统计规则为【计数】; 则统计结果为:【税前薪资】为【0-10,000.00】有多少人,【税前薪资】为【10,000.00-20,000.00】有多少人;" : + val === "RATION_GROUP_INDIVIDUAL" ? + "例:\n" + + " 若:所属字段为【职级】,分组设置为【1】,【2】,【3】;统计项为【税前薪资】,对应的统计规则为【平均值】; 则统计结果为:【职级】为【1】的所有人的【税前薪资】的平均值,【职级】为【2】的所有人的【税前薪资】的平均值;【职级】为【3】的所有人的【税前薪资】的平均值;\n" + + "若:未选择所属字段,分组设置为【1】,【2】,【3】;若统计项为【绩效】,对应的统计规则为【计数】; 则统计结果为:【绩效】为【1】有多少人,绩效为【2】有多少人,绩效为【3】有多少人;" : ""; + + if (val === "QUALITATIVE") { + this.setState({ + conditions: _.map(this.state.convertConditions, item => { + return { + ...item, + items: _.map(_.filter(item.items, child => child.domkey[0] !== "dimCode"), it => { + if (it.domkey[0] === "dimType") { + return { ...it, value: val, viewAttr: viewAttr ? viewAttr : it.viewAttr }; + } + return { ...it }; + }) + }; + }) + }, () => { + statisticsForm.setCondition(this.state.conditions); + }); + } else { + this.setState({ + conditions: _.map(this.state.convertConditions, item => { + return { + ...item, + items: _.map(_.filter(item.items, child => child.domkey[0] !== "setting4Qualitative"), it => { + if (it.domkey[0] === "dimType") { + return { ...it, value: val, viewAttr: viewAttr ? viewAttr : it.viewAttr }; + } else if (it.domkey[0] === "dimCode") { + return { ...it, helpfulTitle }; + } + return { ...it }; + }) + }; + }) + }, () => { + statisticsForm.setCondition(this.state.conditions); + }); + } + }; + handleReqBtnsClick = (key, id = "") => { + if (key === "search") { + const { reportName } = this.state; + this.reportListRef.reportStatisticsReportList({ reportName }); + } else { + const { modalReq } = this.state; + const title = key === "dimension" ? +
+ {getLabel(111, "统计维度管理")} + +
+ : getLabel(111, id ? "编辑报表" : "新建报表"); + this.setState({ + modalReq: { + ...modalReq, id, title, + visible: true, typeKey: key + } + }, () => id && this.initReportFormCondition({ id })); + } + }; + handleCancel = (refresh = false) => { + const { attendanceStore: { reportForm } } = this.props; + const { modalReq } = this.state; + this.setState({ + modalReq: { + ...modalReq, visible: false, id: "" + } + }, () => { + const { selectedKey, reportName, modalReq: { typeKey } } = this.state; + selectedKey === "statistics" && reportForm.resetForm(); + typeKey === "dimension" && this.initReportFormCondition(); + refresh && selectedKey === "statistics" && this.reportListRef.reportStatisticsReportList({ reportName }); + }); + }; + handleAddDimension = (formId = "") => { + const { slideReq } = this.state; + this.setState({ + slideReq: { + ...slideReq, visible: true, + formId + } + }); + }; + handleClose = (initTable = false) => { + const { attendanceStore: { statisticsForm } } = this.props; + const { slideReq } = this.state; + this.setState({ + slideReq: { + ...slideReq, visible: false, formId: "" + } + }, () => { + statisticsForm.resetForm(); + initTable && this.dimensionTableRef.dimensionList(); + }); + }; + + render() { + const { taxAgentStore: { statisticsReportBtn }, attendanceStore: { statisticsForm, reportForm } } = this.props; + const { selectedKey, modalReq, slideReq, conditions, reportConditions, reportName, keyword, year } = this.state; + const buttons = selectedKey === "statistics" ? [ + , + , + this.setState({ reportName })} + onSearch={() => this.handleReqBtnsClick("search")}/> + ] : [ + + {getLabel(111, "年薪资核算人员明细:")} + this.setState({ year })}/> + , + this.setState({ keyword })} + onSearch={() => this.employeeListRef.statisticsEmployeeList()}/> + ]; + const tabs = [ + { key: "statistics", title: getLabel(111, "统计表") }, + { key: "detail", title: getLabel(111, "员工明细") } + ]; + return ( + } selectedKey={selectedKey} + iconBgcolor="#F14A2D" tabDatas={tabs} className="xc_tj_fx_wrapper" showDropIcon={false} + buttons={(!statisticsReportBtn && selectedKey === "statistics") ? buttons.slice(-1) : buttons} buttonSpace={10} + onChange={selectedKey => this.setState({ selectedKey }, () => this.state.selectedKey === "statistics" && this.initReportFormCondition())} + > + { + selectedKey === "statistics" ? + this.reportListRef = dom} + reportName={reportName} + onEdit={this.handleReqBtnsClick} + /> : this.employeeListRef = dom} + keyword={keyword} year={year} + /> + } + + { + modalReq.typeKey === "dimension" && + this.dimensionTableRef = dom} + onEdit={id => this.handleAddDimension(id)} + /> + } + { + modalReq.typeKey === "addReport" && + + } + + + + ); + } +} + +export default Index; diff --git a/pc4mobx/hrmSalary/pages/analysisOfSalaryStatistics/index.less b/pc4mobx/hrmSalary/pages/analysisOfSalaryStatistics/index.less new file mode 100644 index 00000000..e0326f2a --- /dev/null +++ b/pc4mobx/hrmSalary/pages/analysisOfSalaryStatistics/index.less @@ -0,0 +1,178 @@ +.xc_tj_fx_wrapper { + .search { + top: -3px; + margin-right: 10px; + width: 220px; + } + + .employeeYearWrapper { + display: flex; + align-items: center; + + & > span:first-child { + margin-right: 4px; + } + } + + .wea-new-top-req-content { + background: #FFF; + + .reportRow { + padding: 16px; + + .gutter-row { + margin-bottom: 16px; + border-radius: 6px; + + .card-item { + border-radius: 6px; + display: flex; + height: 90px; + justify-content: space-between; + padding: 22px 0 22px 16px; + border: 1px solid #e5e5e5; + + .cardLeft { + display: flex; + align-items: center; + justify-content: center; + + i { + padding: 10px; + color: #FFF; + font-size: 20px; + border-radius: 50%; + background-color: #ff666a; + } + } + + .cardCenter { + display: flex; + flex: 1; + flex-direction: column; + justify-content: space-between; + margin-left: 10px; + + .reportName { + font-size: 14px; + color: #111; + font-weight: 600; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + + .dimension { + display: flex; + + .label { + height: 12px; + font-size: 12px; + color: #999; + line-height: 12px; + font-weight: 400; + } + + .value { + height: 12px; + font-size: 12px; + color: #111; + line-height: 12px; + font-weight: 400; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + } + } + + .cardRight { + display: flex; + align-items: center; + justify-content: center; + + .ant-btn-ghost { + color: #999; + border: 1px solid transparent; + } + + .ant-btn-ghost:focus, .ant-btn-ghost:hover, + .ant-btn-ghost.active, .ant-btn-ghost:active { + color: #2baee9; + background-color: #FFF; + border: 1px solid #e5e5e5; + } + } + } + } + + .card-item:hover { + cursor: pointer; + box-shadow: 0 3px 12px 0 rgba(0, 0, 0, .12); + } + } + + .empty { + font-size: 16px; + width: 100%; + text-align: center; + margin-top: 26px; + } + } +} + + +//统计维度弹框 +.dimensionModalWrapper, .dimensionSlideWrapper { + .dimensionTitle { + width: 100%; + display: flex; + align-items: center; + justify-content: space-between; + } + + .dimensionTableWrapper { + .space10 { + a:first-child { + margin-right: 10px; + } + } + } + +} + +.dimensionSlideWrapper, .dimensionModalWrapper { + .wea-search-group { + .wea-select, .ant-select, .ant-select-selection { + width: 100%; + } + } +} + +//员工明细 +.employeeTableWrapper { + + .operates i.icon-coms-more { + padding: 5px 0; + display: inline-block; + width: 40px; + font-size: 20px; + color: #333; + cursor: pointer; + font-weight: 400; + } +} + +.operatePopover { + .ant-popover-inner { + min-width: 100px !important; + } + + .ant-popover-inner-content { + padding: 0; + + .ant-menu { + border-right: none; + } + } +} diff --git a/pc4mobx/hrmSalary/pages/calculate/index.js b/pc4mobx/hrmSalary/pages/calculate/index.js index fda59a8d..d9a3699a 100644 --- a/pc4mobx/hrmSalary/pages/calculate/index.js +++ b/pc4mobx/hrmSalary/pages/calculate/index.js @@ -1,8 +1,8 @@ import React from "react"; import { inject, observer } from "mobx-react"; import { Button, DatePicker, Dropdown, Menu, message, Modal, Tag } from "antd"; -import { WeaInputSearch, WeaNewScroll, WeaTop } from "ecCom"; -import { renderNoright } from "../../util"; // 渲染form数据的方法:因为多个页面都会使用,所以抽的公共方法在util中 +import { WeaInputSearch, WeaLocaleProvider, WeaNewScroll, WeaTop } from "ecCom"; +import { renderNoright } from "../../util"; import CustomTab from "../../components/customTab"; import moment from "moment"; import BaseFormModal from "./baseFormModal"; @@ -10,6 +10,7 @@ import CustomPaginationTable from "../../components/customPaginationTable"; import ProgressModal from "../../components/progressModal"; import "./index.less"; +const { getLabel } = WeaLocaleProvider; const MonthPicker = DatePicker.MonthPicker; @inject("calculateStore", "taxAgentStore") @@ -185,16 +186,11 @@ export default class Calculate extends React.Component { ; }; } - if (item.title == "操作" && showOperateBtn) { + if (item.dataIndex === "operate" && showOperateBtn) { + item.width = 150; item.render = (text, record) => { - const accountBtn = _.filter( - record.operate, - it => it.text == "核算" || it.text == "重新核算" - ); - const notAccountBtn = _.filter( - record.operate, - it => it.text != "核算" && it.text != "重新核算" - ); + const accountBtn = _.take(record.operate, 2); + const notAccountBtn = _.drop(record.operate, 2); let operateBtn = []; if (!_.isEmpty(accountBtn)) { operateBtn.push( @@ -206,13 +202,8 @@ export default class Calculate extends React.Component { style={{ display: "inline-block", marginRight: 8 }}> { - if (it.text == "核算" || it.text == "重新核算") { - it.text == "核算" - ? this.handleAccount(record) - : this.handleReaccount(record); - } - }}> + style={(idx === 1 && it.text.length === 2) ? { padding: "0 12px" } : {}} + onClick={() => this.handleOperateClick(it.index, record)}> {it.text} @@ -228,31 +219,14 @@ export default class Calculate extends React.Component { {notAccountBtn.map(cz => { - if (cz.text == "核算") { - this.handleAccount(record); - } else if (cz.text == "删除") { - this.handleDeleteItem(record); - } else if (cz.text == "归档") { - this.handleFile(record); - } else if (cz.text == "重新核算") { - this.handleReaccount(record); - } else if (cz.text == "查看") { - this.handleDetail(record); - } else if (cz.text == "回算") { - this.handleBackCalculate(record); - } - }}> + onClick={() => this.handleOperateClick(cz.index, record)}> {cz.text} )} }> - + ); } @@ -260,7 +234,23 @@ export default class Calculate extends React.Component { }; } }); - return showOperateBtn ? columns : _.filter(columns, it => it.title != "操作"); + return showOperateBtn ? columns : _.filter(columns, it => it.title !== "操作"); + }; + + handleOperateClick = (index, record) => { + if (index === "0") { + this.handleAccount(record); + } else if (index === "1") { + this.handleDeleteItem(record); + } else if (index === "2") { + this.handleFile(record); + } else if (index === "4") { + this.handleReaccount(record); + } else if (index === "3") { + this.handleDetail(record); + } else if (index === "5") { + this.handleBackCalculate(record); + } }; // 分页 @@ -290,56 +280,13 @@ export default class Calculate extends React.Component { render() { const { calculateStore, taxAgentStore: { showOperateBtn } } = this.props; - const { - salaryListDataSource, - salaryListColumns, - loading, - hasRight, - form, - condition, - tableStore, - showSearchAd, - getTableDatas, - doSearch, - setShowSearchAd, - salaryListPageInfo - } = calculateStore; + const { salaryListDataSource, loading, hasRight, salaryListPageInfo } = calculateStore; const { modalParam } = this.state; if (!hasRight && !loading) { // 无权限处理 return renderNoright(); } - const rightMenu = [ - // 右键菜单 - { - key: "BTN_COLUMN", - icon: , - content: "显示列定制", - onClick: this.showColumn - } - ]; - const collectParams = { - // 收藏功能配置 - favname: "薪资核算", - favouritetype: 1, - objid: 0, - link: "wui/index.html#/ns_demo03/index", - importantlevel: 1 - }; - const adBtn = [ - // 高级搜索内部按钮 - , - , - - ]; - const renderRightOperation = () => { const { startDate, endDate } = this.state; return ( @@ -393,13 +340,10 @@ export default class Calculate extends React.Component {
{/* 收藏功能: 配置之后显示 收藏、帮助、显示页面地址 这3个功能 */} } // 左侧图标 - iconBgcolor="#F14A2D" // 左侧图标背景色 - showDropIcon={false} // 是否显示下拉按钮 - dropMenuDatas={rightMenu} // 下拉菜单(和页面的右键菜单相同) - dropMenuProps={{ collectParams }}> - {/* 收藏功能: 配置之后显示 收藏、帮助、显示页面地址 这3个功能 */} + title="薪资核算" + icon={} + iconBgcolor="#F14A2D" + showDropIcon={false}>
diff --git a/pc4mobx/hrmSalary/pages/calculate/index.less b/pc4mobx/hrmSalary/pages/calculate/index.less index cec45959..2a274b60 100644 --- a/pc4mobx/hrmSalary/pages/calculate/index.less +++ b/pc4mobx/hrmSalary/pages/calculate/index.less @@ -4,6 +4,12 @@ } .formItem { + display: flex; + + .ant-col-8 { + line-height: 30px; + } + .wea-select, .ant-select { width: 100%; } diff --git a/pc4mobx/hrmSalary/pages/calculateDetail/acctResult/importModal/acctResultImportModal.js b/pc4mobx/hrmSalary/pages/calculateDetail/acctResult/importModal/acctResultImportModal.js index cd2c9c44..b7bc7c27 100644 --- a/pc4mobx/hrmSalary/pages/calculateDetail/acctResult/importModal/acctResultImportModal.js +++ b/pc4mobx/hrmSalary/pages/calculateDetail/acctResult/importModal/acctResultImportModal.js @@ -4,6 +4,8 @@ import { Badge, Button, message } from "antd"; import { inject, observer } from "mobx-react"; import SelectFieldModal from "./selectFieldModal"; import { getQueryString } from "../../../../util/url"; +import AddHeaderFieldsModal from "./addHeaderFieldsModal"; +import { cacheImportField } from "../../../../apis/calculate"; @inject("calculateStore", "standingBookStore") @observer @@ -16,7 +18,10 @@ export default class AcctResultImportModal extends React.Component { salaryItemIds: "" }, step: 0, - selectFieldVisible: false + selectFieldVisible: false, + addHeadFields: { + visible: false, itemsByGroup: [] + } }; } @@ -24,11 +29,6 @@ export default class AcctResultImportModal extends React.Component { const { id } = this.props; if (id) { this.getImportField(); - // let modalParam = { ...this.state.modalParam }; - // modalParam.salaryAcctRecordId = id; - // this.setState({ - // modalParam - // }); } else { this.setState({ modalParam: { ...this.state.modalParam, salaryAcctRecordId: "123" } @@ -36,18 +36,31 @@ export default class AcctResultImportModal extends React.Component { } } - getImportField=()=>{ + getImportField = () => { const { calculateStore: { getImportField }, id } = this.props; + const { addHeadFields } = this.props; getImportField(id).then(data => { this.setState({ - modalParam:{ + addHeadFields: { + ...addHeadFields, + itemsByGroup: _.map(data.itemsByGroup, item => { + return { + ...item, + salaryItems: _.map(item.salaryItems, it => ({ + ...it, + checked: false + })) + }; + }) + }, + modalParam: { ...this.state.modalParam, salaryAcctRecordId: id, salaryItemIds: data.checkItems.join(",") } }); }); - } + }; // 获取模板 handleAccResultTemplateLink() { @@ -98,24 +111,31 @@ export default class AcctResultImportModal extends React.Component { } // 渲染第一步表单 - renderFormComponent() { + renderFormComponent = () => { return - + ; - } + }; // 选择表单字段 - handleSelectedField() { - this.setState({ - selectFieldVisible: true - }); - } + handleSelectedField = () => { + if (window.location.hash.indexOf("calculateDetail") !== -1) { + this.setState({ + addHeadFields: { + ...this.state.addHeadFields, + visible: true + } + }); + } else { + this.setState({ + selectFieldVisible: true + }); + } + }; // 添加表头字段 - handleAdd(fieldDate) { + handleAdd = (fieldDate) => { let salaryItemIdsList = []; if (!_.isEmpty(fieldDate.formulaItems)) { fieldDate.formulaItems.map(item => { @@ -149,7 +169,7 @@ export default class AcctResultImportModal extends React.Component { modalParam }); this.props.onAdd(fieldDate); - } + }; // 初始化Import数据 handleImportModalInit() { @@ -197,7 +217,7 @@ export default class AcctResultImportModal extends React.Component { importInsuranceAcctDetail, importBalanceInsuranceDetail } = standingBookStore; - const { step, selectFieldVisible, modalParam } = this.state; + const { step, modalParam, selectFieldVisible, addHeadFields } = this.state; return (
{ @@ -223,7 +243,7 @@ export default class AcctResultImportModal extends React.Component { !isStandingBook ? fetchImportAcctResult(params) : standingBookType === "difference" ? - importBalanceInsuranceDetail({...params, billMonth}) : + importBalanceInsuranceDetail({ ...params, billMonth }) : importInsuranceAcctDetail(params); }} templateLink={() => { @@ -253,6 +273,24 @@ export default class AcctResultImportModal extends React.Component { }} /> } + this.setState({ addHeadFields: { ...addHeadFields, visible: false } })} + onAdd={(salaryItemIds) => this.setState({ + addHeadFields: { + ...addHeadFields, + visible: false + }, + modalParam: { + ...modalParam, + salaryItemIds: salaryItemIds.join(",") + } + }, () => { + const { salaryItemIds } = this.state.modalParam; + cacheImportField({ + salaryItems: salaryItemIds ? salaryItemIds.split(",") : [] + }).then(); + })} + />
); } diff --git a/pc4mobx/hrmSalary/pages/calculateDetail/acctResult/importModal/addHeaderFieldsModal.js b/pc4mobx/hrmSalary/pages/calculateDetail/acctResult/importModal/addHeaderFieldsModal.js new file mode 100644 index 00000000..66b00e4c --- /dev/null +++ b/pc4mobx/hrmSalary/pages/calculateDetail/acctResult/importModal/addHeaderFieldsModal.js @@ -0,0 +1,105 @@ +/* + * Author: 黎永顺 + * name: 表头字段添加 + * Description: + * Date: 2023/5/17 + */ +import React, { Component } from "react"; +import { Button, Col, Row } from "antd"; +import { WeaCheckbox, WeaDialog, WeaLocaleProvider, WeaSearchGroup } from "ecCom"; +import "./index.less"; + +const { getLabel } = WeaLocaleProvider; + +class AddHeaderFieldsModal 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: nextProps.selectItems ? _.map(nextProps.selectItems.split(","), it => Number(it)) : [] + }); + } + } + + 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 ( + this.props.onAdd(itemsCheckeds)}>{getLabel(111, "添加")}, + + ]} + bottomLeft={} + > + { + _.map(dataSource, item => { + const { salarySobItemGroupName, salaryItems, salarySobItemGroupId } = item; + const value = _.every(salaryItems, it => !!it.checked) ? "1" : "0"; + return this.handleSelectGroupAll(salarySobItemGroupId, val)}/>}> + + { + !_.isEmpty(salaryItems) ? + _.map(salaryItems, it => { + const { salaryItemId, salaryItemName, checked } = it; + return + this.setState({ itemsCheckeds: _.xorWith(itemsCheckeds, [salaryItemId], _.isEqual) })}/> + ; + }) : 暂无数据 + } + + ; + }) + } + + ); + } +} + +export default AddHeaderFieldsModal; diff --git a/pc4mobx/hrmSalary/pages/calculateDetail/acctResult/importModal/index.less b/pc4mobx/hrmSalary/pages/calculateDetail/acctResult/importModal/index.less new file mode 100644 index 00000000..1de6458c --- /dev/null +++ b/pc4mobx/hrmSalary/pages/calculateDetail/acctResult/importModal/index.less @@ -0,0 +1,11 @@ +.addHeaderFieldsWrapper { + .wea-search-group { + .wea-title { + padding-left: 0 !important; + } + + .wea-content { + padding: 8px 16px 0; + } + } +} diff --git a/pc4mobx/hrmSalary/pages/calculateDetail/compareDetail.js b/pc4mobx/hrmSalary/pages/calculateDetail/compareDetail.js index cdb471d8..49085673 100644 --- a/pc4mobx/hrmSalary/pages/calculateDetail/compareDetail.js +++ b/pc4mobx/hrmSalary/pages/calculateDetail/compareDetail.js @@ -6,8 +6,10 @@ import CustomTab from "../../components/customTab"; import { inject, observer } from "mobx-react"; import CompareDetailImportModal from "./compareDetailImportModal"; import CustomPaginationTable from "../../components/customPaginationTable"; +import { salaryacctAcctresultCheckAuth } from "../../apis/calculate"; +import Authority from "../mySalary/authority"; -@inject("calculateStore") +@inject("calculateStore", "taxAgentStore") @observer export default class CompareDetail extends React.Component { constructor(props) { @@ -17,7 +19,8 @@ export default class CompareDetail extends React.Component { onlyDiffEmployee: true, onlyDiffSalaryItem: true, importModalVisible: false, - searchValue: "" + searchValue: "", + calculateAuth: false }; this.pageInfo = { current: 1, pageSize: 10 }; } @@ -33,8 +36,23 @@ export default class CompareDetail extends React.Component { current: 1 }; fetchComparisonResultList(params); + this.salaryacctAcctresultCheckAuth({ salaryAcctRecordId: getQueryString("id") }) } + salaryacctAcctresultCheckAuth = (params) => { + const { taxAgentStore: { getPermission } } = this.props; + getPermission().then(({ data }) => { + const { isOpenDevolution } = data; + if (isOpenDevolution) { + salaryacctAcctresultCheckAuth(params).then(({ status, data }) => { + this.setState({ calculateAuth: data && status }); + }); + } else { + this.setState({ calculateAuth: true }); + } + }); + }; + getColumns = (columns) => { let newColumns = [...columns]; newColumns.map(item => { @@ -56,6 +74,8 @@ export default class CompareDetail extends React.Component {
); }; + } else { + item.fixed = "left"; } }); return newColumns; @@ -167,7 +187,7 @@ export default class CompareDetail extends React.Component { comparisonResultColumns } } = this.props; - const { importModalVisible, searchValue } = this.state; + const { importModalVisible, searchValue, calculateAuth } = this.state; const renderRightOperation = () => { return (
@@ -201,60 +221,63 @@ export default class CompareDetail extends React.Component { ); }; return ( -
- -
-
- 公式= - 系统值;线下值;差值 + +
+ +
+
+ 公式= + 系统值;线下值;差值 +
-
-
- { - this.pageInfo.current = value; - this.handleDataPageChange(value); - }} - onShowSizeChange={(current, pageSize) => { - this.pageInfo = { current, pageSize }; - this.handleShowSizeChange(this.pageInfo); - }} - /> -
+
+ { + this.pageInfo.current = value; + this.handleDataPageChange(value); + }} + onShowSizeChange={(current, pageSize) => { + this.pageInfo = { current, pageSize }; + this.handleShowSizeChange(this.pageInfo); + }} + /> +
- { - importModalVisible && { - this.handleComparisonFinish(); - }} - onCancel={() => { - this.setState({ - importModalVisible: false - }); - }} - /> - } -
+ { + importModalVisible && { + this.handleComparisonFinish(); + }} + onCancel={() => { + this.setState({ + importModalVisible: false + }); + }} + /> + } +
+ ); } } diff --git a/pc4mobx/hrmSalary/pages/calculateDetail/compareDetailImportModal.js b/pc4mobx/hrmSalary/pages/calculateDetail/compareDetailImportModal.js index 1c276127..9fc924e1 100644 --- a/pc4mobx/hrmSalary/pages/calculateDetail/compareDetailImportModal.js +++ b/pc4mobx/hrmSalary/pages/calculateDetail/compareDetailImportModal.js @@ -1,7 +1,7 @@ import React from "react"; import ImportModal from "../../components/importModal"; import { inject, observer } from "mobx-react"; -import { getQueryString } from "../../util/url"; +import { convertToUrlString, getQueryString } from "../../util/url"; @inject("calculateStore", "standingBookStore") @observer @@ -35,7 +35,12 @@ export default class CompareDetailImportModal extends React.Component { if (this.props.id) { url = "/api/bs/hrmsalary/salaryacct/comparisonresult/importtemplate/export?salaryAcctRecordId=" + this.props.id; } else { - url = `/api/bs/hrmsalary/siaccount/comparisonwelfare/importtemplate/export`; + const payload = { + billMonth: getQueryString("billMonth"), + paymentOrganization: getQueryString("paymentOrganization"), + paymentStatus: 0 + }; + url = `/api/bs/hrmsalary/siaccount/comparisonwelfare/importtemplate/export?${convertToUrlString(payload)}`; } window.open(url); } diff --git a/pc4mobx/hrmSalary/pages/calculateDetail/editSalaryDetail.js b/pc4mobx/hrmSalary/pages/calculateDetail/editSalaryDetail.js index 075c55a1..2051451d 100644 --- a/pc4mobx/hrmSalary/pages/calculateDetail/editSalaryDetail.js +++ b/pc4mobx/hrmSalary/pages/calculateDetail/editSalaryDetail.js @@ -1,10 +1,9 @@ import React from "react"; -import { WeaHelpfulTip, WeaInput, WeaTab } from "ecCom"; +import { WeaHelpfulTip, WeaTab } from "ecCom"; import IssuedAndReissueTable from "./issuedAndReissueTable"; -import { Col, Row } from "antd"; +import PayrollItemsTable from "./payrollItemsTable"; import { inject, observer } from "mobx-react"; import { toJS } from "mobx"; -import cs from "classnames"; import "./index.less"; @inject("calculateStore") @@ -22,25 +21,23 @@ export default class EditSalaryDetail extends React.Component { acctresultDetail(this.props.id); } - handleItemValueChange = (field, value, isInput) => { - console.log(field, value, isInput); + handleItemValueChange = (field, value, isInput, groupId) => { const { calculateStore: { acctresultDetailForm, setAcctresultDetailForm } } = this.props; let form = { ...acctresultDetailForm }; - if (isInput === "inputItems") { - form.inputItems = acctresultDetailForm.inputItems.map(item => { - item = { ...item }; - if (item.salaryItemName === field) { - item.resultValue = value; + if (isInput === "itemsByGroup") { + form.itemsByGroup = acctresultDetailForm.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 === "formulaItems") { - form.formulaItems = acctresultDetailForm.formulaItems.map(item => { - item = { ...item }; - if (item.salaryItemName === field) { - item.resultValue = value; - } - return item; + return { ...item }; }); } else if (isInput === "issuedAndReissueItems") { form.issuedAndReissueItems = acctresultDetailForm.issuedAndReissueItems.map(item => { @@ -53,7 +50,6 @@ export default class EditSalaryDetail extends React.Component { } setAcctresultDetailForm(form); }; - renderTableTr = (data, isInput) => { const tables = []; const len = data.length; @@ -77,10 +73,10 @@ export default class EditSalaryDetail extends React.Component { return tables; }; - render() { const { calculateStore: { acctresultDetailForm } } = this.props; const { selectedKey } = this.state; + const { itemsByGroup = [] } = toJS(acctresultDetailForm); const topTab = [ { title: "正常工资薪金所得", @@ -96,14 +92,8 @@ export default class EditSalaryDetail extends React.Component {
基本信息 - +
-
{ !_.isEmpty(acctresultDetailForm.employeeInfos) && @@ -123,69 +113,9 @@ export default class EditSalaryDetail extends React.Component { /> } { - selectedKey === "0" && -
-
- 输入项 -
- - { - acctresultDetailForm.inputItems && acctresultDetailForm.inputItems.map((item, index) => { - const len = acctresultDetailForm.inputItems.length; - return ( - - - {item.salaryItemName} - { - this.handleItemValueChange(item.salaryItemName, value, "inputItems"); - }}/> - - - ); - }) - } - -
-
-
- - 公式项 - - -
- - { - acctresultDetailForm.formulaItems && acctresultDetailForm.formulaItems.map((item, index) => { - const len = acctresultDetailForm.formulaItems.length; - return ( - - - {item.salaryItemName} - { - this.handleItemValueChange(item.salaryItemName, value, "formulaItems"); - }}/> - - - ); - }) - } - -
-
-
+ selectedKey === "0" && _.map(itemsByGroup, item => { + return ; + }) } { selectedKey === "1" && diff --git a/pc4mobx/hrmSalary/pages/calculateDetail/index.js b/pc4mobx/hrmSalary/pages/calculateDetail/index.js index 0f857405..1bc1e55a 100644 --- a/pc4mobx/hrmSalary/pages/calculateDetail/index.js +++ b/pc4mobx/hrmSalary/pages/calculateDetail/index.js @@ -7,10 +7,13 @@ import { WeaBrowser, WeaCheckbox, WeaDropdown, WeaFormItem, WeaInput, WeaSearchG import { convertToUrlString, getQueryString } from "../../util/url"; import AcctResultImportModal from "./acctResult/importModal/acctResultImportModal"; import ProgressModal from "../../components/progressModal"; +import { salaryacctAcctresultCheckAuth } from "../../apis/calculate"; +import Authority from "../mySalary/authority"; + const { ButtonSelect } = WeaDropdown; -@inject("calculateStore", "salaryFileStore") +@inject("calculateStore", "salaryFileStore", "taxAgentStore") @observer export default class CalculateDetail extends React.Component { constructor(props) { @@ -19,10 +22,11 @@ export default class CalculateDetail extends React.Component { showSearchAd: false, searchItemsValue: { employeeName: "", + workcode: "", departmentIds: "", positionIds: "", subcompanyIds: "", - status: "", + statuses: "", consolidatedTaxation: "0" }, selectedKey: "0", @@ -30,37 +34,55 @@ export default class CalculateDetail extends React.Component { acctResultImportVisiable: false, progressVisible: false, progress: 0, - accountIds: [] + accountIds: [], + accountExceptInfo: "", + calculateAuth: false }; this.id = ""; - this.timer; + this.timer = null; } - componentWillMount() { + async componentWillMount() { let id = getQueryString("id"); this.id = id; const { calculateStore: { checkTaxAgent }, salaryFileStore } = this.props; const { commonEnumList } = salaryFileStore; + this.salaryacctAcctresultCheckAuth({ salaryAcctRecordId: id }); checkTaxAgent(this.id); let modalParam = { ...this.state.modalParam, salaryAcctRecordId: id }; this.setState({ modalParam }); commonEnumList("user", { enumClass: "com.engine.salary.enums.salarysob.SalaryEmployeeStatusEnum" }); } + salaryacctAcctresultCheckAuth = (params) => { + const { taxAgentStore: { getPermission } } = this.props; + getPermission().then(({ data }) => { + const { isOpenDevolution } = data; + if (isOpenDevolution) { + salaryacctAcctresultCheckAuth(params).then(({ status, data }) => { + this.setState({ calculateAuth: data && status }); + }); + } else { + this.setState({ calculateAuth: true }); + } + }); + }; + Input = (value, key) => { - const { employeeName } = this.state.searchItemsValue; + const { employeeName, workcode } = this.state.searchItemsValue; return ( - this.setState({ - searchItemsValue: { - ...this.state.searchItemsValue, - [key]: val - } - })}/> + this.setState({ + searchItemsValue: { + ...this.state.searchItemsValue, + [key]: val + } + })}/> ); }; @@ -93,7 +115,7 @@ export default class CalculateDetail extends React.Component { ); }; Select = (value, key) => { - const { status } = this.state.searchItemsValue; + const { statuses } = this.state.searchItemsValue; return ( this.setState({ searchItemsValue: { ...this.state.searchItemsValue, [key]: val } })}/> @@ -160,7 +185,8 @@ export default class CalculateDetail extends React.Component { this.timer = null; this.setState({ progressVisible: false, - accountIds: [] + accountIds: [], + accountExceptInfo: data.message }); message.success("核算完成"); // acctResultList({ salaryAcctRecordId: this.id }); @@ -181,7 +207,8 @@ export default class CalculateDetail extends React.Component { this.timer = null; this.setState({ progressVisible: false, - accountIds: [] + accountIds: [], + accountExceptInfo: data.message }); message.error(data.message); } @@ -189,8 +216,6 @@ export default class CalculateDetail extends React.Component { }); }, 1000); }); - }, - onCancel() { } }); }; @@ -208,8 +233,11 @@ export default class CalculateDetail extends React.Component { this.id ); } else if (e.key == "3") { + const { searchItemsValue } = this.state; + const { consolidatedTaxation, ...extra } = searchItemsValue; + const payload = { ...extra, consolidatedTaxation: consolidatedTaxation === "0" ? "" : consolidatedTaxation }; window.open( - `/api/bs/hrmsalary/salaryacct/acctresult/export?salaryAcctRecordId=${this.id}&ids=&${convertToUrlString(this.state.searchItemsValue)}` + `/api/bs/hrmsalary/salaryacct/acctresult/export?salaryAcctRecordId=${this.id}&ids=&${convertToUrlString(payload)}` ); } }; @@ -246,8 +274,18 @@ export default class CalculateDetail extends React.Component { } } + downloadTxtfile = (value) => { + const element = document.createElement("a"); + const file = new Blob([value], { type: "text/plain" }); + element.href = URL.createObjectURL(file); + element.download = "核算异常信息.txt"; + document.body.appendChild(element); + element.click(); + }; + render() { - const { selectedKey, acctResultImportVisiable, showSearchAd } = this.state; + const { selectedKey, acctResultImportVisiable, showSearchAd, calculateAuth } = this.state; + const { taxAgentStore: { payrollPermission } } = this.props; const menu = ( 导入 @@ -257,7 +295,8 @@ export default class CalculateDetail extends React.Component { ); const renderRightOperation = () => { - return [ + const { accountExceptInfo } = this.state; + let buttons = [ ]; + accountExceptInfo && buttons.unshift(