Merge branch 'master' into feature/v2-对接e10个税扣缴义务人设置-1121
# Conflicts: # pc4mobx/hrmSalary/util/index.js
This commit is contained in:
commit
37cb0f050a
|
|
@ -273,14 +273,14 @@ export const importAttendQuoteData = (params) => {
|
|||
};
|
||||
|
||||
// 查看考勤详情
|
||||
export const viewAttendQuote = (ids) => {
|
||||
export const viewAttendQuote = (params) => {
|
||||
return fetch("/api/bs/hrmsalary/attendQuote/view", {
|
||||
method: "POST",
|
||||
mode: "cors",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify(ids),
|
||||
body: JSON.stringify(params),
|
||||
}).then((res) => res.json());
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -333,6 +333,17 @@ export const fileSalaryAcct = (params) => {
|
|||
}
|
||||
}).then(res => res.json());
|
||||
};
|
||||
// 薪资记录-回算
|
||||
export const backCalculate = (params) => {
|
||||
return fetch("/api/bs/hrmsalary/salaryacct/backCalculate", {
|
||||
method: "POST",
|
||||
mode: "cors",
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
body: JSON.stringify(params)
|
||||
}).then(res => res.json());
|
||||
};
|
||||
|
||||
// 薪资记录-重新核算
|
||||
export const reAccounting = (params) => {
|
||||
|
|
@ -498,3 +509,62 @@ export const updateLockStatus = (params) => {
|
|||
body: JSON.stringify(params)
|
||||
}).then(res => res.json());
|
||||
};
|
||||
// 社保福利台账合计接口
|
||||
export const siaccountDetailCommonListSum = (params) => {
|
||||
return fetch("/api/bs/hrmsalary/siaccount/detail/common/list/sum", {
|
||||
method: "POST",
|
||||
mode: "cors",
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
body: JSON.stringify(params)
|
||||
}).then(res => res.json());
|
||||
};
|
||||
// 社保福利台账补缴合计接口
|
||||
export const siaccountDetailSupplementaryListSum = (params) => {
|
||||
return fetch("/api/bs/hrmsalary/siaccount/detail/supplementary/list/sum", {
|
||||
method: "POST",
|
||||
mode: "cors",
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
body: JSON.stringify(params)
|
||||
}).then(res => res.json());
|
||||
};
|
||||
// 社保福利台账退差合计接口
|
||||
export const siaccountDetailRecessionListSum = (params) => {
|
||||
return fetch("/api/bs/hrmsalary/siaccount/detail/recession/list/sum", {
|
||||
method: "POST",
|
||||
mode: "cors",
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
body: JSON.stringify(params)
|
||||
}).then(res => res.json());
|
||||
};
|
||||
// 社保福利台账补差合计接口
|
||||
export const siaccountDetailBalanceListSum = (params) => {
|
||||
return fetch("/api/bs/hrmsalary/siaccount/detail/balance/list/sum", {
|
||||
method: "POST",
|
||||
mode: "cors",
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
body: JSON.stringify(params)
|
||||
}).then(res => res.json());
|
||||
};
|
||||
// 导入薪资核算添加表头字段缓存
|
||||
export const cacheImportField = (params) => {
|
||||
return fetch("/api/bs/hrmsalary/salaryacct/acctresult/cacheImportField", {
|
||||
method: "POST",
|
||||
mode: "cors",
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
body: JSON.stringify(params)
|
||||
}).then(res => res.json());
|
||||
};
|
||||
//薪资核算-页面查看权限
|
||||
export const salaryacctAcctresultCheckAuth = params => {
|
||||
return WeaTools.callApi("/api/bs/hrmsalary/salaryacct/acctresult/checkAuth", "GET", params);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { WeaTools } from "ecCom";
|
||||
import { postFetch } from '../util/request';
|
||||
import { postFetch } from "../util/request";
|
||||
|
||||
//数据采集-累计专项附加扣除列表
|
||||
export const getCumDeductList = (params) => {
|
||||
|
|
@ -7,9 +7,9 @@ export const getCumDeductList = (params) => {
|
|||
method: "POST",
|
||||
mode: "cors",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
body: JSON.stringify(params),
|
||||
body: JSON.stringify(params)
|
||||
}).then((res) => res.json());
|
||||
};
|
||||
|
||||
|
|
@ -52,9 +52,9 @@ export const getCumDeductDetailList = (params) => {
|
|||
method: "POST",
|
||||
mode: "cors",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
body: JSON.stringify(params),
|
||||
body: JSON.stringify(params)
|
||||
}).then((res) => res.json());
|
||||
};
|
||||
|
||||
|
|
@ -62,9 +62,9 @@ export const getCumDeductDetailList = (params) => {
|
|||
export const exportCumDeductDetailList = (id, ids = "") => {
|
||||
fetch(
|
||||
"/api/bs/hrmsalary/addUpDeduction/exportDetail?accumulatedSpecialAdditionalDeductionId=" +
|
||||
id +
|
||||
"&ids=" +
|
||||
ids+ "&taxAgentId=" + taxAgentId
|
||||
id +
|
||||
"&ids=" +
|
||||
ids + "&taxAgentId=" + taxAgentId
|
||||
).then((res) =>
|
||||
res.blob().then((blob) => {
|
||||
var filename = `累计专项附加扣除.xlsx`;
|
||||
|
|
@ -84,9 +84,9 @@ export const importCumDeductParam = (params) => {
|
|||
method: "POST",
|
||||
mode: "cors",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
body: JSON.stringify(params),
|
||||
body: JSON.stringify(params)
|
||||
}).then((res) => res.json());
|
||||
};
|
||||
|
||||
|
|
@ -96,34 +96,44 @@ export const importCumDeductPreview = (params) => {
|
|||
method: "POST",
|
||||
mode: "cors",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
body: JSON.stringify(params),
|
||||
body: JSON.stringify(params)
|
||||
}).then((res) => res.json());
|
||||
};
|
||||
|
||||
|
||||
//新增累计专项附加扣除
|
||||
export const createAddUpDeduction = (params) => {
|
||||
return postFetch('/api/bs/hrmsalary/addUpDeduction/createAddUpDeduction', params);
|
||||
}
|
||||
return postFetch("/api/bs/hrmsalary/addUpDeduction/createAddUpDeduction", params);
|
||||
};
|
||||
//查看信息
|
||||
export const getAddUpDeduction = (params) => {
|
||||
return postFetch('/api/bs/hrmsalary/addUpDeduction/getAddUpDeduction', params);
|
||||
}
|
||||
return postFetch("/api/bs/hrmsalary/addUpDeduction/getAddUpDeduction", params);
|
||||
};
|
||||
//编辑累计专项附加扣除
|
||||
export const editAddUpDeduction = (params) => {
|
||||
return postFetch('/api/bs/hrmsalary/addUpDeduction/editAddUpDeduction', params);
|
||||
}
|
||||
return postFetch("/api/bs/hrmsalary/addUpDeduction/editAddUpDeduction", params);
|
||||
};
|
||||
//批量删除累计专项附加扣除
|
||||
export const deleteSelectAddUpDeduction = (params) => {
|
||||
return postFetch('/api/bs/hrmsalary/addUpDeduction/deleteSelectAddUpDeduction', params);
|
||||
}
|
||||
return postFetch("/api/bs/hrmsalary/addUpDeduction/deleteSelectAddUpDeduction", params);
|
||||
};
|
||||
//一键清空累计专项附加扣除
|
||||
export const deleteAllAddUpDeduction = (params) => {
|
||||
return postFetch('/api/bs/hrmsalary/addUpDeduction/deleteAllAddUpDeduction', params);
|
||||
}
|
||||
return postFetch("/api/bs/hrmsalary/addUpDeduction/deleteAllAddUpDeduction", params);
|
||||
};
|
||||
//一键累计
|
||||
export const autoAddAll = (params) => {
|
||||
return postFetch('/api/bs/hrmsalary/addUpDeduction/autoAddAll', params);
|
||||
}
|
||||
return postFetch("/api/bs/hrmsalary/addUpDeduction/autoAddAll", params);
|
||||
};
|
||||
|
||||
//数据采集列表查询
|
||||
export const getTableDate = ({ url, ...params }) => {
|
||||
return postFetch(url, params);
|
||||
};
|
||||
//数据采集列表详情记录查询
|
||||
export const getTableRecordDate = ({ url, ...params }) => {
|
||||
return postFetch(url, params);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
import { WeaTools } from "ecCom";
|
||||
import { postFetch } from "../util/request";
|
||||
|
||||
//获取编辑详情
|
||||
export const getSalaryFieldForm = (params) => {
|
||||
return WeaTools.callApi("/api/bs/hrmsalary/salaryField/getSalaryForm", "GET", params);
|
||||
};
|
||||
// 字段管理查询
|
||||
export const salaryFieldList = (params) => {
|
||||
return postFetch('/api/bs/hrmsalary/salaryField/list', params);
|
||||
}
|
||||
|
||||
// 字段管理查询
|
||||
export const saveSalaryField = (params) => {
|
||||
return postFetch('/api/bs/hrmsalary/salaryField/save', params);
|
||||
}
|
||||
// 删除字段管理
|
||||
export const deleteSalaryField = (params) => {
|
||||
return postFetch('/api/bs/hrmsalary/salaryField/delete', params);
|
||||
}
|
||||
|
|
@ -70,6 +70,7 @@ export const deleteItemList = params => {
|
|||
|
||||
//薪资项目-新增薪资项目
|
||||
export const saveItem = params => {
|
||||
delete params.formulaContent
|
||||
return fetch('/api/bs/hrmsalary/salaryitem/save', {
|
||||
method: 'POST',
|
||||
mode: 'cors',
|
||||
|
|
@ -106,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 ***
|
||||
// 获取公式变量类型
|
||||
|
|
@ -144,6 +149,17 @@ export const saveFormual = params => {
|
|||
body: JSON.stringify(params)
|
||||
}).then(res => res.json())
|
||||
}
|
||||
// 公式测试
|
||||
export const testFormual = params => {
|
||||
return fetch('/api/bs/hrmsalary/formula/mock', {
|
||||
method: 'POST',
|
||||
mode: 'cors',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify(params)
|
||||
}).then(res => res.json())
|
||||
}
|
||||
|
||||
// 根据id获取formual
|
||||
export const detailFormual = params => {
|
||||
|
|
|
|||
|
|
@ -139,13 +139,32 @@ export const getLedgerItemGroupForm = params => {
|
|||
|
||||
//保存薪资帐套薪资项目
|
||||
export const saveLedgerItem = params => {
|
||||
const { itemGroups, items, ...extra } = params;
|
||||
const payload = {
|
||||
itemGroups: _.map(itemGroups, item => {
|
||||
return {
|
||||
...item,
|
||||
items: _.map(item.items, it => {
|
||||
delete it.formulaContent;
|
||||
return { ...it };
|
||||
})
|
||||
};
|
||||
}),
|
||||
items: _.map(items, child => {
|
||||
delete child.formulaContent;
|
||||
return { ...child };
|
||||
}) || [],
|
||||
...extra
|
||||
};
|
||||
|
||||
|
||||
return fetch("/api/bs/hrmsalary/salarysob/item/save", {
|
||||
method: "POST",
|
||||
mode: "cors",
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
body: JSON.stringify(params)
|
||||
body: JSON.stringify(payload)
|
||||
}).then(res => res.json());
|
||||
};
|
||||
|
||||
|
|
@ -268,3 +287,25 @@ export const listAdjustmentRule = params => {
|
|||
body: JSON.stringify(params)
|
||||
}).then(res => res.json());
|
||||
};
|
||||
|
||||
//获取回算薪资项目
|
||||
export const getAggregate = params => {
|
||||
return WeaTools.callApi("/api/bs/hrmsalary/salarysob/backitem/getAggregate", "GET", params);
|
||||
};
|
||||
|
||||
//编辑回算薪资项目详情
|
||||
export const getBackitemForm = params => {
|
||||
return WeaTools.callApi("/api/bs/hrmsalary/salarysob/backitem/getForm", "GET", params);
|
||||
};
|
||||
//保存回算薪资项目详情
|
||||
export const salarysobBackitemSave = params => {
|
||||
return postFetch("/api/bs/hrmsalary/salarysob/backitem/save", params);
|
||||
};
|
||||
//预览人员范围导入
|
||||
export const salarysobRangePreview = params => {
|
||||
return postFetch("/api/bs/hrmsalary/salarysob/range/preview", params);
|
||||
};
|
||||
//导入人员范围
|
||||
export const salarysobRangeImportData = params => {
|
||||
return postFetch("/api/bs/hrmsalary/salarysob/range/importData", params);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,29 +1,45 @@
|
|||
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);
|
||||
};
|
||||
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 getSecondAuthForm = params => {
|
||||
return WeaTools.callApi("/api/encrypt/secondauthsetting/getSecondAuthForm", "POST", params);
|
||||
};
|
||||
export const doSecondAuth = params => {
|
||||
return WeaTools.callApi("/api/encrypt/secondauthsetting/doSecondAuth", "POST", params);
|
||||
};
|
||||
export const checkPassword = params => {
|
||||
return WeaTools.callApi("/api/hrm/secondarypwd/checkPassword", "POST", params);
|
||||
};
|
||||
export const saveSecondaryPwd = params => {
|
||||
return WeaTools.callApi("/api/hrm/secondarypwd/saveSecondaryPwd", "POST", params);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { WeaTools } from "ecCom";
|
||||
import { postFetch } from "../util/request";
|
||||
|
||||
//工资单-工资单发放列表
|
||||
export const getPayrollList = params => {
|
||||
|
|
@ -11,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 => {
|
||||
|
|
@ -174,13 +179,14 @@ export const savePayroll = params => {
|
|||
|
||||
//工资单-编辑工资单
|
||||
export const updatePayroll = params => {
|
||||
const { background, ...extra } = params;
|
||||
return fetch("/api/bs/hrmsalary/salaryBill/template/update", {
|
||||
method: "POST",
|
||||
mode: "cors",
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
body: JSON.stringify(params)
|
||||
body: JSON.stringify({ background: _.isNil(background) ? "" : background, ...extra })
|
||||
}).then(res => res.json());
|
||||
};
|
||||
|
||||
|
|
@ -313,3 +319,72 @@ export const grantProxy = params => {
|
|||
body: JSON.stringify(params)
|
||||
}).then(res => res.json());
|
||||
};
|
||||
|
||||
// 工资单发放-新建时获取补发工资单模板薪资项目设置
|
||||
export const getReplenishForm = params => {
|
||||
return fetch("/api/bs/hrmsalary/salaryBill/template/getReplenishForm", {
|
||||
method: "POST",
|
||||
mode: "cors",
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
body: JSON.stringify(params)
|
||||
}).then(res => res.json());
|
||||
};
|
||||
|
||||
// 工资单发放-获取规则设置下拉框
|
||||
export const getReplenishRuleSetOptions = ({ salarySobId }) => {
|
||||
return fetch(`/api/bs/hrmsalary/salaryBill/template/getReplenishRuleSetOptions?salarySobId=${salarySobId}`, {
|
||||
method: "GET",
|
||||
mode: "cors",
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
}).then(res => res.json());
|
||||
};
|
||||
|
||||
//添加发送和撤回人员范围列表
|
||||
export const sendRangeList = (params) => {
|
||||
return postFetch("/api/bs/hrmsalary/salaryBill/send/range/list", params);
|
||||
};
|
||||
//创建范围
|
||||
export const sendRangeSave = (params) => {
|
||||
return postFetch("/api/bs/hrmsalary/salaryBill/send/range/save", params);
|
||||
};
|
||||
//刪除范围
|
||||
export const sendRangeDelete = (params) => {
|
||||
return postFetch("/api/bs/hrmsalary/salaryBill/send/range/delete", params);
|
||||
};
|
||||
//工资单模板-获取模板可用的分组
|
||||
export const getAvailableSalaryGroupSet = (params) => {
|
||||
return postFetch("/api/bs/hrmsalary/salaryBill/template/getAvailableSalaryGroupSet", params);
|
||||
};
|
||||
//工资单模板-获取模板分组下可用的薪资项目
|
||||
export const getAvailableSalaryItemSet = (params) => {
|
||||
return postFetch("/api/bs/hrmsalary/salaryBill/template/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);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -202,6 +202,14 @@ export const getWelfareList = () => {
|
|||
{}
|
||||
);
|
||||
};
|
||||
// 补差表单字段对应的接口
|
||||
export const getBalanceWelfareList = () => {
|
||||
return WeaTools.callApi(
|
||||
"/api/bs/hrmsalary/siaccount/getBalanceWelfareList",
|
||||
"get",
|
||||
{}
|
||||
);
|
||||
};
|
||||
|
||||
// 社保福利台账-导入预览
|
||||
export const welfarePreview = (params) => {
|
||||
|
|
@ -226,6 +234,17 @@ export const importInsuranceAcctDetail = (params) => {
|
|||
body: JSON.stringify(params)
|
||||
}).then((res) => res.json());
|
||||
};
|
||||
// 社保福利台账-补差数据导入
|
||||
export const importBalanceInsuranceDetail = (params) => {
|
||||
return fetch("/api/bs/hrmsalary/siaccount/welfare/importBalanceInsuranceDetail", {
|
||||
method: "post",
|
||||
mode: "cors",
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
body: JSON.stringify(params)
|
||||
}).then((res) => res.json());
|
||||
};
|
||||
|
||||
// 社保福利台账-线下对比数据导入
|
||||
export const importExcelInsuranceDetail = (params) => {
|
||||
|
|
@ -251,14 +270,30 @@ export const saveRecession = (params) => {
|
|||
export const recessionList = (params) => {
|
||||
return postFetch("/api/bs/hrmsalary/siaccount/detail/recession/list", params);
|
||||
};
|
||||
//查询补差列表
|
||||
export const balanceList = (params) => {
|
||||
return postFetch("/api/bs/hrmsalary/siaccount/detail/balance/list", params);
|
||||
};
|
||||
//删除退差数据
|
||||
export const delRecession = (params) => {
|
||||
return postFetch("/api/bs/hrmsalary/siaccount/delRecession", params);
|
||||
};
|
||||
//删除补差数据
|
||||
export const delBalance = (params) => {
|
||||
return postFetch("/api/bs/hrmsalary/siaccount/delBalance", params);
|
||||
};
|
||||
//编辑社保福利缴纳数据
|
||||
export const editAccount = (params) => {
|
||||
return postFetch("/api/bs/hrmsalary/siaccount/editAccount", params);
|
||||
};
|
||||
//获取指定月份的福利基数
|
||||
export const getSupplementPaymentForm = (params) => {
|
||||
return postFetch("/api/bs/hrmsalary/siaccount/detail/getSupplementPaymentForm", params);
|
||||
};
|
||||
//获取待编辑的补缴费用相关福利项
|
||||
export const getPaymentGroup = (params) => {
|
||||
return postFetch("/api/bs/hrmsalary/siaccount/detail/getPaymentGroup", params);
|
||||
};
|
||||
//获取核算项个人和公司社保福利缴纳详情
|
||||
export const getPaymentById = ({ id }) => {
|
||||
return fetch(`/api/bs/hrmsalary/siaccount/getPaymentById?id=${id}`, {
|
||||
|
|
@ -266,6 +301,41 @@ export const getPaymentById = ({ id }) => {
|
|||
mode: "cors",
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
}
|
||||
}).then(res => res.json());
|
||||
};
|
||||
//获取社保福利项列表
|
||||
export const compensationCategoryType = ({ id }) => {
|
||||
return fetch(`/api/bs/hrmsalary/siaccount/compensationCategoryType?id=${id}`, {
|
||||
method: "GET",
|
||||
mode: "cors",
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
}).then(res => res.json());
|
||||
};
|
||||
|
||||
//获取调差列表
|
||||
export const getCompensationList = (params) => {
|
||||
return postFetch("/api/bs/hrmsalary/siaccount/compensationList", params);
|
||||
};
|
||||
//获取可调差的人员列表
|
||||
export const getEmployeeListToCompensation = (params) => {
|
||||
return postFetch("/api/bs/hrmsalary/siaccount/getEmployeeListToCompensation", params);
|
||||
};
|
||||
//获取当前调差行-公司方支出总计
|
||||
export const getCompensationComTotal = (params) => {
|
||||
return postFetch("/api/bs/hrmsalary/siaccount/compensationComTotal", params);
|
||||
};
|
||||
//社保调差保存
|
||||
export const compensationSave = (params) => {
|
||||
return postFetch("/api/bs/hrmsalary/siaccount/compensationSave", params);
|
||||
};
|
||||
//社保调差默认配置保存
|
||||
export const compensationConfigSave = (params) => {
|
||||
return postFetch("/api/bs/hrmsalary/siaccount/compensationConfigSave", params);
|
||||
};
|
||||
//撤回调差数据
|
||||
export const compensationBack = (params) => {
|
||||
return postFetch("/api/bs/hrmsalary/siaccount/compensationBack", params);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
};
|
||||
|
|
@ -86,6 +86,14 @@ export const getTaxAgentRangeListExclude = (params) => {
|
|||
export const getTaxAgentRangeForm = (params) => {
|
||||
return postFetch("/api/bs/hrmsalary/taxAgent/range/getForm", params);
|
||||
};
|
||||
//预览个税扣缴义务人中人员范围
|
||||
export const taxAgentRangePreview = (params) => {
|
||||
return postFetch("/api/bs/hrmsalary/taxAgent/range/preview", params);
|
||||
};
|
||||
//导入个税扣缴义务人中人员范围
|
||||
export const taxAgentRangeImportData = (params) => {
|
||||
return postFetch("/api/bs/hrmsalary/taxAgent/range/importData", params);
|
||||
};
|
||||
|
||||
//个税扣缴义务人下拉列表
|
||||
export const getTaxAgentSelectList = (params) => {
|
||||
|
|
|
|||
|
|
@ -1,142 +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);
|
||||
};
|
||||
//全量增员
|
||||
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);
|
||||
}));
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -62,7 +62,15 @@ export const getCustomCategoryForm = params => {
|
|||
return WeaTools.callApi('/api/bs/hrmsalary/sicategory/customCategoryForm', 'get', params);
|
||||
};
|
||||
export const getCustomCategoryList = params => {
|
||||
return WeaTools.callApi('/api/bs/hrmsalary/sicategory/customCategoryList', 'get', params);
|
||||
// return WeaTools.callApi('/api/bs/hrmsalary/sicategory/customCategoryList', 'get', params);
|
||||
return fetch('/api/bs/hrmsalary/sicategory/customCategoryList', {
|
||||
method: 'POST',
|
||||
mode: 'cors',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify(params)
|
||||
}).then(res => res.json())
|
||||
};
|
||||
export const createSICategory = params => {
|
||||
return fetch('/api/bs/hrmsalary/sicategory/createSICategory', {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,38 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="151px" height="150px" viewBox="0 0 151 150" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>Icon-empty-file</title>
|
||||
<defs>
|
||||
<polygon id="path-1" points="0 -0.0002 149.9997 -0.0002 149.9997 31.9998 0 31.9998"></polygon>
|
||||
</defs>
|
||||
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="知识文档" transform="translate(-112.000000, -299.000000)">
|
||||
<g id="Group-40" transform="translate(113.000000, 321.000000)">
|
||||
<g id="Group-3" transform="translate(0.000000, 89.259000)">
|
||||
<mask id="mask-2" fill="white">
|
||||
<use xlink:href="#path-1"></use>
|
||||
</mask>
|
||||
<g id="Clip-2"></g>
|
||||
<path d="M149.9997,15.9998 C149.9997,24.8368 116.4217,31.9998 74.9997,31.9998 C33.5787,31.9998 -0.0003,24.8368 -0.0003,15.9998 C-0.0003,7.1638 33.5787,-0.0002 74.9997,-0.0002 C116.4217,-0.0002 149.9997,7.1638 149.9997,15.9998" id="Fill-1" fill="#E6EFF0" mask="url(#mask-2)"></path>
|
||||
</g>
|
||||
<line x1="116.8337" y1="5.1465" x2="127.1277" y2="5.1465" id="Stroke-4" stroke="#D3D7DC"></line>
|
||||
<line x1="121.9801" y1="0" x2="121.9801" y2="10.294" id="Stroke-6" stroke="#D3D7DC"></line>
|
||||
<line x1="127.1276" y1="39.0801" x2="133.1026" y2="39.0801" id="Stroke-8" stroke="#D3D7DC"></line>
|
||||
<line x1="130.1149" y1="36.0928" x2="130.1149" y2="42.0678" id="Stroke-10" stroke="#D3D7DC"></line>
|
||||
<line x1="17.9655" y1="38.4541" x2="25.1085" y2="38.4541" id="Stroke-12" stroke="#D3D7DC"></line>
|
||||
<line x1="21.5368" y1="34.8828" x2="21.5368" y2="42.0248" id="Stroke-14" stroke="#D3D7DC"></line>
|
||||
<polygon id="Fill-16" fill="#FFFFFF" points="113.029 23.0694 99.885 10.2944 99.091 11.2664 98.32 17.1834 97.716 21.4544 100.529 24.2664 106.842 25.3914 110.675 25.0164 112.842 24.2874"></polygon>
|
||||
<polygon id="Stroke-18" stroke="#CFD0D6" stroke-linecap="round" stroke-linejoin="round" points="113.029 23.0694 99.885 10.2944 99.091 11.2664 98.32 17.1834 97.716 21.4544 100.529 24.2664 106.842 25.3914 110.675 25.0164 112.842 24.2874"></polygon>
|
||||
<path d="M96.6842,106.4366 L42.9702,106.4366 C39.6702,106.4366 36.9702,103.7376 36.9702,100.4366 L36.9702,26.3016 C36.9702,23.0006 39.6702,20.3016 42.9702,20.3016 L96.6842,20.3016 C99.9842,20.3016 102.6842,23.0006 102.6842,26.3016 L102.6842,100.4366 C102.6842,103.7376 99.9842,106.4366 96.6842,106.4366" id="Fill-20" fill="#FFFFFF"></path>
|
||||
<path d="M96.6842,106.4366 L42.9702,106.4366 C39.6702,106.4366 36.9702,103.7376 36.9702,100.4366 L36.9702,26.3016 C36.9702,23.0006 39.6702,20.3016 42.9702,20.3016 L96.6842,20.3016 C99.9842,20.3016 102.6842,23.0006 102.6842,26.3016 L102.6842,100.4366 C102.6842,103.7376 99.9842,106.4366 96.6842,106.4366 Z" id="Stroke-22" stroke="#CFD0D6"></path>
|
||||
<path d="M105.3727,23.5244 C102.1367,23.5244 99.4877,20.8764 99.4877,17.6394 L99.4877,10.2944 L53.2007,10.2944 C49.9637,10.2944 47.3157,12.9424 47.3157,16.1784 L47.3157,90.5454 C47.3157,93.7814 49.9637,96.4294 53.2007,96.4294 L107.1437,96.4294 C110.3817,96.4294 113.0287,93.7814 113.0287,90.5454 L113.0287,23.5244 L105.3727,23.5244 Z" id="Fill-24" fill="#FFFFFF"></path>
|
||||
<path d="M105.3727,23.5244 C102.1367,23.5244 99.4877,20.8764 99.4877,17.6394 L99.4877,10.2944 L53.2007,10.2944 C49.9637,10.2944 47.3157,12.9424 47.3157,16.1784 L47.3157,90.5454 C47.3157,93.7814 49.9637,96.4294 53.2007,96.4294 L107.1437,96.4294 C110.3817,96.4294 113.0287,93.7814 113.0287,90.5454 L113.0287,23.5244 L105.3727,23.5244 Z" id="Stroke-26" stroke="#CFD0D6"></path>
|
||||
<path d="M99.987,36.3116 L60.319,36.3116 C58.944,36.3116 57.819,35.1866 57.819,33.8116 C57.819,32.4366 58.944,31.3116 60.319,31.3116 L99.987,31.3116 C101.362,31.3116 102.487,32.4366 102.487,33.8116 C102.487,35.1866 101.362,36.3116 99.987,36.3116" id="Fill-28" fill="#E9E9E9"></path>
|
||||
<path d="M99.987,48.2158 L60.319,48.2158 C58.944,48.2158 57.819,47.0908 57.819,45.7158 C57.819,44.3408 58.944,43.2158 60.319,43.2158 L99.987,43.2158 C101.362,43.2158 102.487,44.3408 102.487,45.7158 C102.487,47.0908 101.362,48.2158 99.987,48.2158" id="Fill-30" fill="#E9E9E9"></path>
|
||||
<path d="M99.987,60.1192 L60.319,60.1192 C58.944,60.1192 57.819,58.9942 57.819,57.6192 C57.819,56.2442 58.944,55.1192 60.319,55.1192 L99.987,55.1192 C101.362,55.1192 102.487,56.2442 102.487,57.6192 C102.487,58.9942 101.362,60.1192 99.987,60.1192" id="Fill-32" fill="#E9E9E9"></path>
|
||||
<path d="M84.529,72.0235 L60.319,72.0235 C58.944,72.0235 57.819,70.8985 57.819,69.5235 C57.819,68.1485 58.944,67.0235 60.319,67.0235 L84.529,67.0235 C85.904,67.0235 87.029,68.1485 87.029,69.5235 C87.029,70.8985 85.904,72.0235 84.529,72.0235" id="Fill-34" fill="#E9E9E9"></path>
|
||||
<path d="M49.4841,92.169 L49.4651,12.311 C48.4411,13.349 47.8191,14.441 47.8191,16.439 L47.8191,90.587 C47.8191,92.703 49.0641,94.436 50.7221,95.325 C50.0211,94.344 49.4841,93.459 49.4841,92.169" id="Fill-36" fill="#EBF6FF"></path>
|
||||
<path d="M39.1335,102.1446 L39.1965,22.3046 C38.1725,23.3426 37.4685,24.4166 37.4685,26.4146 L37.4685,100.5626 C37.4685,102.6786 38.7435,104.4116 40.4025,105.3006 C39.7005,104.3196 39.1335,103.4346 39.1335,102.1446" id="Fill-38" fill="#EBF6FF"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.4 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 3.2 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 3.2 KiB |
|
|
@ -0,0 +1,227 @@
|
|||
/*
|
||||
* Author: 黎永顺
|
||||
* name: 新增人员范围弹框
|
||||
* Description:
|
||||
* Date: 2022/11/30
|
||||
*/
|
||||
import React, { Component } from "react";
|
||||
import { WeaBrowser, WeaDialog, WeaFormItem, WeaSearchGroup, WeaSelect } from "ecCom";
|
||||
import { Button, message, Modal } from "antd";
|
||||
import { getTaxAgentRangeForm } from "../../apis/taxAgent";
|
||||
import { SelectWithAll } from "../../pages/socialSecurityBenefits/standingBookDetail/components/regAddEmployee";
|
||||
import "./index.less";
|
||||
|
||||
class PersonalScopeModal extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
loading: false,
|
||||
employeeStatus: [],
|
||||
targetTypeList: [],
|
||||
targetType: "EMPLOYEE",
|
||||
targetTypeIds: "",
|
||||
targetTypeIdsNames: "",
|
||||
status: "",
|
||||
statusAll: ""
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const { isTaxgent = true } = this.props;
|
||||
if (isTaxgent) {
|
||||
this.getTaxAgentRangeForm();
|
||||
} else {
|
||||
const employeeStatus = [
|
||||
{ key: "TRIAL", showname: "试用" },
|
||||
{ key: "FORMAL", showname: "正式" },
|
||||
{ key: "TEMPORARY", showname: "临时" },
|
||||
{ key: "DELAY", showname: "试用延期" },
|
||||
{ key: "FIRE", showname: "解雇" },
|
||||
{ key: "DEPARTURE", showname: "离职" },
|
||||
{ key: "RETIRED", showname: "退休" }
|
||||
];
|
||||
const targetTypeList = [
|
||||
{
|
||||
key: "EMPLOYEE",
|
||||
showname: "人员",
|
||||
selected: false
|
||||
},
|
||||
{
|
||||
key: "SUBCOMPANY",
|
||||
showname: "分部",
|
||||
selected: false
|
||||
},
|
||||
{
|
||||
key: "DEPT",
|
||||
showname: "部门",
|
||||
selected: false
|
||||
},
|
||||
{
|
||||
key: "POSITION",
|
||||
showname: "岗位",
|
||||
selected: false
|
||||
}
|
||||
];
|
||||
this.setState({ targetTypeList, employeeStatus });
|
||||
}
|
||||
}
|
||||
|
||||
getTaxAgentRangeForm = () => {
|
||||
getTaxAgentRangeForm().then(({ status, data }) => {
|
||||
if (status) {
|
||||
const { employeeStatus, targetTypeList } = data;
|
||||
this.setState({
|
||||
targetTypeList: _.map(targetTypeList, it => ({ key: it.id, showname: it.name })),
|
||||
employeeStatus: _.map(employeeStatus, it => ({ key: it.id, showname: it.name }))
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
handleSubmit = () => {
|
||||
const { status, targetTypeIds, targetType } = this.state;
|
||||
const { includeType, saveKeyVal, onSuccess, onCancel, APISaveFox } = this.props;
|
||||
if (_.isEmpty(status) || _.isEmpty(targetTypeIds)) {
|
||||
Modal.warning({
|
||||
title: "信息确认",
|
||||
content: "必要信息不完整,红色*为必填项!"
|
||||
});
|
||||
return;
|
||||
}
|
||||
const payload = {
|
||||
employeeStatus: status.split(","),
|
||||
includeType,
|
||||
targetParams: _.map(targetTypeIds.split(","), it => ({ targetType, targetId: it })),
|
||||
[saveKeyVal["key"]]: saveKeyVal["value"],
|
||||
};
|
||||
this.setState({ loading: true });
|
||||
APISaveFox["save"](payload).then(({ status, errormsg }) => {
|
||||
this.setState({ loading: false });
|
||||
if (status) {
|
||||
message.success("保存成功");
|
||||
this.handleReset();
|
||||
onSuccess();
|
||||
onCancel();
|
||||
} else {
|
||||
message.error(errormsg || "保存失败");
|
||||
}
|
||||
}).catch(() => this.setState({ loading: true }));
|
||||
};
|
||||
renderBrowser = () => {
|
||||
const { targetType, targetTypeIds, targetTypeIdsNames } = this.state;
|
||||
let browserType = {};
|
||||
switch (targetType) {
|
||||
case "EMPLOYEE":
|
||||
browserType = { ...browserType, type: 17, title: "人员选择" };
|
||||
break;
|
||||
case "DEPT":
|
||||
browserType = { ...browserType, type: 57, title: "部门选择" };
|
||||
break;
|
||||
case "SUBCOMPANY":
|
||||
browserType = { ...browserType, type: 164, title: "分部选择" };
|
||||
break;
|
||||
case "POSITION":
|
||||
browserType = { ...browserType, type: 278, title: "岗位选择" };
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return <WeaBrowser
|
||||
{...browserType}
|
||||
viewAttr={3}
|
||||
isSingle={false}
|
||||
value={targetTypeIds}
|
||||
valueSpan={targetTypeIdsNames}
|
||||
inputStyle={{ width: 200 }}
|
||||
onChange={(targetTypeIds, targetTypeIdsNames) => {
|
||||
this.setState({ targetTypeIds, targetTypeIdsNames });
|
||||
}}
|
||||
/>;
|
||||
};
|
||||
handleReset = () => {
|
||||
this.setState({
|
||||
targetType: "EMPLOYEE",
|
||||
targetTypeIds: "",
|
||||
status: "",
|
||||
statusAll: ""
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
const { onCancel, title, visible } = this.props;
|
||||
const { employeeStatus, targetTypeList, targetType, status, statusAll, loading } = this.state;
|
||||
const buttons = [
|
||||
<Button type="primary" onClick={this.handleSubmit} loading={loading}>确定</Button>,
|
||||
<Button type="ghost" onClick={this.handleReset}>重置</Button>
|
||||
];
|
||||
return (
|
||||
<WeaDialog
|
||||
initLoadCss
|
||||
className="personalScopeModalWrapper"
|
||||
title={title}
|
||||
visible={visible}
|
||||
style={{ width: 600 }}
|
||||
buttons={buttons}
|
||||
onCancel={() => {
|
||||
this.handleReset();
|
||||
onCancel();
|
||||
}}
|
||||
>
|
||||
<WeaSearchGroup col={1} needTigger title="" showGroup center>
|
||||
<WeaFormItem
|
||||
label="对象类型"
|
||||
labelCol={{ span: 6 }}
|
||||
wrapperCol={{ span: 18 }}
|
||||
>
|
||||
<div style={{ display: "flex", alignItems: "center" }}>
|
||||
<WeaSelect
|
||||
style={{ width: 60, marginRight: 12 }}
|
||||
value={targetType}
|
||||
options={targetTypeList}
|
||||
onChange={(targetType) => this.setState({ targetType })}
|
||||
/>
|
||||
{this.renderBrowser()}
|
||||
</div>
|
||||
</WeaFormItem>
|
||||
{
|
||||
SelectWithAll({
|
||||
label: "选择员工状态",
|
||||
options: employeeStatus,
|
||||
detailtype: 2,
|
||||
valueAll: statusAll,
|
||||
value: status,
|
||||
onChangeAll: ({ selected }) => {
|
||||
if (selected) {
|
||||
this.setState({
|
||||
status: _.map(employeeStatus, it => it.key).join(","),
|
||||
statusAll: selected
|
||||
});
|
||||
} else {
|
||||
this.setState({
|
||||
status: "",
|
||||
statusAll: selected
|
||||
});
|
||||
}
|
||||
},
|
||||
onChange: ({ selected }) => {
|
||||
const bool = _.every(_.map(employeeStatus, it => it.key), item => selected.split(",").includes(item));
|
||||
if (bool) {
|
||||
this.setState({
|
||||
status: selected,
|
||||
statusAll: "0"
|
||||
});
|
||||
} else {
|
||||
this.setState({
|
||||
status: selected,
|
||||
statusAll: ""
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
</WeaSearchGroup>
|
||||
</WeaDialog>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default PersonalScopeModal;
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
//添加关联人员弹框中的下拉框样式
|
||||
.personalScopeModalWrapper{
|
||||
.wea-select,.ant-select-selection,.ant-select{
|
||||
width: 100%;
|
||||
}
|
||||
.wea-select{
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
}
|
||||
.ant-select-selection{
|
||||
height: 30px;
|
||||
border-radius: 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,138 @@
|
|||
/*
|
||||
* Author: 黎永顺
|
||||
* name: 人员范围列表数据
|
||||
* Description:
|
||||
* Date: 2022/11/30
|
||||
*/
|
||||
import React, { Component } from "react";
|
||||
import { WeaTable } from "ecCom";
|
||||
import { calcPageNo } from "../../util";
|
||||
import "./index.less";
|
||||
|
||||
class PersonalScopeTable extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
loading: {
|
||||
query: false
|
||||
},
|
||||
dataSource: [],
|
||||
columns: [],
|
||||
selectedRowKeys: [],
|
||||
pageInfo: {
|
||||
current: 1,
|
||||
pageSize: 10,
|
||||
total: 0
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.getPersonalScopeList();
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps, nextContext) {
|
||||
if (nextProps.tabActive !== this.props.tabActive) {
|
||||
this.setState({ selectedRowKeys: [] }, () => {
|
||||
this.getPersonalScopeList(nextProps.tabActive);
|
||||
nextProps.onChangeSelectKey([]);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
getPersonalScopeList = (tabActive = this.props.tabActive) => {
|
||||
const { searchValue, searchKeyVal, APIFox } = this.props;
|
||||
const { pageInfo, loading } = this.state;
|
||||
const payload = {
|
||||
[searchKeyVal["key"]]: searchKeyVal["value"],
|
||||
targetName: searchValue,
|
||||
...pageInfo
|
||||
};
|
||||
this.setState({ loading: { ...loading, query: true } });
|
||||
APIFox[tabActive](payload).then(({ status, data }) => {
|
||||
this.setState({ loading: { ...loading, query: false } });
|
||||
if (status) {
|
||||
const { pageNum: current, pageSize, total, columns, list: dataSource } = data;
|
||||
this.setState({
|
||||
pageInfo: { ...pageInfo, current, pageSize, total },
|
||||
dataSource,
|
||||
columns: _.map(columns, item => {
|
||||
return {
|
||||
...item,
|
||||
render: (text) => {
|
||||
return <span className="tdEllipsis" title={text}>{text}</span>;
|
||||
}
|
||||
};
|
||||
})
|
||||
});
|
||||
}
|
||||
}).catch(() => {
|
||||
this.setState({ loading: { ...loading, query: false } });
|
||||
});
|
||||
};
|
||||
|
||||
/*
|
||||
* Author: 黎永顺
|
||||
* Description: 清空选中项
|
||||
* Params:
|
||||
* Date: 2022/11/30
|
||||
*/
|
||||
clearRowkeys = () => {
|
||||
const { pageInfo, selectedRowKeys } = this.state;
|
||||
this.setState({
|
||||
selectedRowKeys: [],
|
||||
pageInfo: {
|
||||
...pageInfo,
|
||||
current: calcPageNo(pageInfo.total, pageInfo.current, 10, selectedRowKeys.length)
|
||||
}
|
||||
}, () => {
|
||||
this.getPersonalScopeList();
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
const { dataSource, columns, pageInfo, loading, selectedRowKeys } = this.state;
|
||||
const { onChangeSelectKey } = this.props;
|
||||
const pagination = {
|
||||
...pageInfo,
|
||||
showTotal: total => `共 ${total} 条`,
|
||||
showQuickJumper: true,
|
||||
showSizeChanger: true,
|
||||
pageSizeOptions: ["10", "20", "50", "100"],
|
||||
onShowSizeChange: (current, pageSize) => {
|
||||
this.setState({
|
||||
pageInfo: { ...pageInfo, current, pageSize }
|
||||
}, () => {
|
||||
this.getPersonalScopeList();
|
||||
});
|
||||
},
|
||||
onChange: current => {
|
||||
this.setState({
|
||||
pageInfo: { ...pageInfo, current }
|
||||
}, () => {
|
||||
this.getPersonalScopeList();
|
||||
});
|
||||
}
|
||||
};
|
||||
const rowSelection = {
|
||||
selectedRowKeys,
|
||||
onChange: (selectedRowKeys) => {
|
||||
this.setState({ selectedRowKeys }, () => {
|
||||
onChangeSelectKey(this.state.selectedRowKeys);
|
||||
});
|
||||
}
|
||||
};
|
||||
return (
|
||||
<WeaTable
|
||||
rowKey="id"
|
||||
rowSelection={rowSelection}
|
||||
dataSource={dataSource}
|
||||
pagination={pagination}
|
||||
loading={loading.query}
|
||||
columns={columns}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default PersonalScopeTable;
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
.ledgerWrapper {
|
||||
height: 100%;
|
||||
|
||||
.tdEllipsis {
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
import React, { Component } from "react";
|
||||
import { WeaTable } from "ecCom";
|
||||
import "./index.less";
|
||||
|
||||
class Index extends Component {
|
||||
|
||||
render() {
|
||||
const { columns, xWidth = 1440 } = this.props;
|
||||
const unifiedColumns = _.map(columns, (item, index) => {
|
||||
if (index === 0 || index === 2) {
|
||||
return { ...item, fixed: "left", width: 150 };
|
||||
} else if (index === 1) {
|
||||
return { ...item, fixed: "left", width: 176 };
|
||||
}
|
||||
if (item.dataIndex === "operate") {
|
||||
return { ...item, fixed: "right", width: item.width || "120px" };
|
||||
}
|
||||
return { ...item, width: "33%" };
|
||||
});
|
||||
return (
|
||||
<WeaTable className="unifiedTable" {...this.props} columns={unifiedColumns} scroll={{ x: xWidth }}/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default Index;
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
.unifiedTable {
|
||||
.ellipsis {
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.linkWapper {
|
||||
//a {
|
||||
// color: #4d7ad8;
|
||||
// margin-right: 8px;
|
||||
//}
|
||||
|
||||
i {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
//a:hover {
|
||||
// text-decoration: none;
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
|
@ -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 (
|
||||
<WeaDialog
|
||||
initLoadCss {...this.props} style={{ width: 550 }}
|
||||
className="captchaWrapper" title={getLabel(111, "验证码验证")}
|
||||
buttons={[
|
||||
<Button type="primary" onClick={this.handleConfirm}>{getLabel(826, "确定")}</Button>
|
||||
]}
|
||||
>
|
||||
<WeaSearchGroup needTigger={false} title="" showGroup>
|
||||
<WeaFormItem
|
||||
label={getLabel(111, "验证码")}
|
||||
labelCol={{ span: 8 }}
|
||||
wrapperCol={{ span: 16 }}
|
||||
>
|
||||
<WeaError tipPosition="bottom" ref="weaError" error={getLabel(826, "验证码未填写")}>
|
||||
<div className="captchaInputBox">
|
||||
<WeaInput value={captcha} onChange={captcha => this.setState({ captcha })}/>
|
||||
<Button type="primary" onClick={this.handleSendCaptcha} disabled={time !== 60}>
|
||||
{
|
||||
time === 60 ? getLabel(111, "发送验证码") : `${time}S`
|
||||
}
|
||||
</Button>
|
||||
</div>
|
||||
</WeaError>
|
||||
</WeaFormItem>
|
||||
</WeaSearchGroup>
|
||||
</WeaDialog>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default Index;
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3,8 +3,7 @@ import CustomTable from "../../components/customTable";
|
|||
|
||||
class CustomPaginationTable extends PureComponent {
|
||||
shouldComponentUpdate(nextProps, nextState, nextContext) {
|
||||
if (nextProps.columnIndex && this.props.columnIndex !== nextProps.columnIndex) return false;
|
||||
return true;
|
||||
return !(nextProps.columnIndex && this.props.columnIndex !== nextProps.columnIndex);
|
||||
}
|
||||
|
||||
render() {
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
<div className="excel-codeAction">
|
||||
<div className="excel-codeAction-item">
|
||||
<div className="excel-codeAction-header">
|
||||
<div className="excel-codeAction-header-title">{getLabel(111, "变量")}</div>
|
||||
</div>
|
||||
<div className="excel-codeAction-content">
|
||||
<WeaInputSearch value={variableText} placeholder={getLabel(111, "请输入变量名称")}
|
||||
className="variableOuterInput"
|
||||
onChange={variableText => this.setState({ variableText })}/>
|
||||
<Tree className="variableTree" showLine expandedKeys={variableExpandedKeys}
|
||||
onExpand={this.handleExpandVari} onSelect={this.handleVariNode}
|
||||
>
|
||||
{
|
||||
_.map(variableDatalist, item => {
|
||||
const { key, value, children = [] } = item;
|
||||
const itemChildren = _.filter(children.slice(1), it => it.name.indexOf(variItemText) !== -1);
|
||||
return <TreeNode title={value} key={key}>
|
||||
{
|
||||
_.map([...children.slice(0, 1), ...itemChildren], (child, childIndex) => {
|
||||
const { name, fieldId } = child;
|
||||
return (
|
||||
fieldId === "searchInput" ?
|
||||
<TreeNode
|
||||
title={
|
||||
<WeaInputSearch
|
||||
value={variItemText}
|
||||
placeholder={getLabel(111, "请输入变量名称")}
|
||||
onChange={variItemText => this.setState({ variItemText })}
|
||||
/>
|
||||
}
|
||||
key={fieldId + "_" + childIndex}/> :
|
||||
<TreeNode title={name} key={fieldId}/>
|
||||
);
|
||||
})
|
||||
}
|
||||
</TreeNode>;
|
||||
})
|
||||
}
|
||||
</Tree>
|
||||
</div>
|
||||
</div>
|
||||
{
|
||||
referenceType !== "sql" &&
|
||||
<React.Fragment>
|
||||
<div className="excel-codeAction-item">
|
||||
<div className="excel-codeAction-header">
|
||||
<div className="excel-codeAction-header-title">{getLabel(111, "函数")}</div>
|
||||
</div>
|
||||
<div className="excel-codeAction-content">
|
||||
<WeaInputSearch value={funcText} placeholder={getLabel(111, "请输入函数名称")}
|
||||
className="variableOuterInput"
|
||||
onChange={funcText => this.setState({ funcText })}/>
|
||||
<Tree className="variableTree" showLine expandedKeys={funcExpandedKeys}
|
||||
onExpand={funcExpandedKeys => this.setState({ funcExpandedKeys })}
|
||||
>
|
||||
{
|
||||
_.map(funcDatalist, item => {
|
||||
const { name, dataType, children = [] } = item;
|
||||
return <TreeNode title={name} disabled={disabled} key={dataType}>
|
||||
{
|
||||
_.map(children, (child, childIndex) => {
|
||||
const { name: childName, chineseName } = child;
|
||||
return (
|
||||
<TreeNode
|
||||
disabled={disabled}
|
||||
title={
|
||||
<div className="funcListTitle"
|
||||
onClick={() => this.props.onFuncSelect(childName)}
|
||||
onMouseEnter={() => this.setState({ funcHoverItem: child })}>
|
||||
<span className="functionName" title={childName}>{childName}</span>
|
||||
<span className="functionDesc" title={chineseName}>{chineseName}</span>
|
||||
</div>
|
||||
}
|
||||
key={childIndex}
|
||||
/>
|
||||
);
|
||||
})
|
||||
}
|
||||
</TreeNode>;
|
||||
})
|
||||
}
|
||||
</Tree>
|
||||
</div>
|
||||
</div>
|
||||
<div className="excel-codeAction-item">
|
||||
<div className="excel-codeAction-header">
|
||||
<div className="excel-codeAction-header-title">
|
||||
{!_.isEmpty(funcHoverItem) ? funcHoverItem.name : getLabel(111, "提示")}
|
||||
</div>
|
||||
</div>
|
||||
<div className="excel-codeAction-content"><TipList tips={funcHoverItem}/></div>
|
||||
</div>
|
||||
</React.Fragment>
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default CodeAction;
|
||||
|
||||
const TipList = (props) => {
|
||||
const { tips } = props;
|
||||
const { paramDescs = [], formatString, description, example, result } = tips;
|
||||
return _.isEmpty(tips) ? <div className="code-action-list">
|
||||
<div className="code-action-tips">
|
||||
{/*<div>{getLabel(111, "{C:选项} 用来选择特定选项字段下的备选项")}</div>*/}
|
||||
{/*<div>{getLabel(111, "{U:姓名} 用来选择工作区成员")}</div>*/}
|
||||
{/*<div>{getLabel(111, "{D:数据} 用来选择一个部门")}</div>*/}
|
||||
</div>
|
||||
</div> : <div className="code-action-list">
|
||||
<div className="code-action-tips">
|
||||
<div className="code-action-tips-title">{getLabel(111, "语法")}</div>
|
||||
<div className="code-action-tips-info">
|
||||
<div>{formatString}</div>
|
||||
<div>{description}</div>
|
||||
</div>
|
||||
<div className="code-action-tips-title">{getLabel(111, "参数")}</div>
|
||||
{
|
||||
_.map(paramDescs, it => {
|
||||
return <div className="code-action-tips-info">
|
||||
<span>.</span>
|
||||
<span>{it}</span>
|
||||
</div>;
|
||||
})
|
||||
}
|
||||
<div className="code-action-tips-title">{getLabel(111, "示例")}</div>
|
||||
<span className="code-action-tips-info">{example}</span>
|
||||
<div className="code-action-tips-title">{getLabel(111, "结果")}</div>
|
||||
<span className="code-action-tips-info">{result}</span>
|
||||
</div>
|
||||
</div>;
|
||||
};
|
||||
|
|
@ -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" },
|
||||
]
|
||||
|
|
@ -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: "<!--",
|
||||
commentEnd: "-->",
|
||||
newlineAfterToken: function (type, content, textAfter) {
|
||||
return type == "tag" && />$/.test(content) || /^</.test(textAfter);
|
||||
}
|
||||
});
|
||||
|
||||
// Comment/uncomment the specified range
|
||||
CodeMirror.defineExtension("commentRange", function (isComment, from, to) {
|
||||
var cm = this, curMode = CodeMirror.innerMode(cm.getMode(), cm.getTokenAt(from).state).mode;
|
||||
cm.operation(function () {
|
||||
if (isComment) { // Comment range
|
||||
cm.replaceRange(curMode.commentEnd, to);
|
||||
cm.replaceRange(curMode.commentStart, from);
|
||||
if (from.line == to.line && from.ch == to.ch) // An empty comment inserted - put cursor inside
|
||||
cm.setCursor(from.line, from.ch + curMode.commentStart.length);
|
||||
} else { // Uncomment range
|
||||
var selText = cm.getRange(from, to);
|
||||
var startIndex = selText.indexOf(curMode.commentStart);
|
||||
var endIndex = selText.lastIndexOf(curMode.commentEnd);
|
||||
if (startIndex > -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 };
|
||||
|
|
@ -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 (
|
||||
<React.Fragment>
|
||||
<div className="excel-codeWrap">
|
||||
<div className="excel-codeBox">
|
||||
<CodeMirror
|
||||
editorDidMount={editor => 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()}
|
||||
/>
|
||||
</div>
|
||||
{
|
||||
referenceType !== "sql" &&
|
||||
<div className="excel-codeBox-keyboard">
|
||||
<div className="excel-codeBox-keyboard-operate">
|
||||
<div className="excel-codeBox-keyboard-operate-content">
|
||||
{
|
||||
_.map(keyboardBaseBtns, item => {
|
||||
const { key, label } = item;
|
||||
return <Button
|
||||
key={key} title={label} size="small"
|
||||
className={cs(key === " " ? "excel-codeBox-keyboard-space" : "excel-codeBox-keyboard-base")}
|
||||
onClick={() => this.insertText(key)}
|
||||
>{label}</Button>;
|
||||
})
|
||||
}
|
||||
</div>
|
||||
<div className="excel-codeBox-keyboard-operate-clear">
|
||||
<Button title="←" size="small" className="excel-codeBox-keyboard-del"
|
||||
onClick={this.handleEditorRedo}>←</Button>
|
||||
<Button title="C" size="small" className="excel-codeBox-keyboard-clear"
|
||||
onClick={() => this.setState({ value: "", isCustomFunctionClick: true })}>C</Button>
|
||||
</div>
|
||||
</div>
|
||||
<Button type="ghost"
|
||||
onClick={() => this.setState({ isFormter: !isFormter }, () => this.autoFormatSelection())}>
|
||||
{!isFormter ? getLabel(111, "格式美化") : getLabel(111, "格式还原")}
|
||||
</Button>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
{/*公式参数列表*/}
|
||||
<CodeAction groupParams={groupParams} isCustomFunction={isCustomFunction} onVariSelect={this.handleVariSelect}
|
||||
onFuncSelect={this.handleFuncSelect} codeVal={value} isCustomFunctionClick={isCustomFunctionClick}
|
||||
onChangeCustomFunction={onChangeCustomFunction}
|
||||
/>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default ExcelEditor;
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,20 +1,20 @@
|
|||
import React from "react"
|
||||
import { Button } from "antd"
|
||||
import { WeaCheckbox, WeaHelpfulTip } from "ecCom";
|
||||
import React from "react";
|
||||
import { Button } from "antd";
|
||||
|
||||
export default class HeaderSet extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<div style={{display: "inline-block"}}>
|
||||
<Button type="default" style={{marginLeft: "10px", marginRight: "10px"}} onClick={this.props.onSetClick}>表头设置</Button>
|
||||
<WeaCheckbox style={{marginRight: "10px"}}/>
|
||||
<WeaHelpfulTip
|
||||
className="headSetTips"
|
||||
width={200}
|
||||
title="提示:勾选此项,则导出模板的考勤模块字段自动填充考勤模块的数据,导入时默认为覆盖导入"
|
||||
placement="topLeft"
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<div style={{ display: "inline-block" }}>
|
||||
<Button type="default" style={{ marginLeft: "10px", marginRight: "10px" }} onClick={this.props.onSetClick}
|
||||
loading={this.props.loading}>表头设置</Button>
|
||||
{/*<WeaCheckbox style={{marginRight: "10px"}}/>*/}
|
||||
{/*<WeaHelpfulTip*/}
|
||||
{/* className="headSetTips"*/}
|
||||
{/* width={200}*/}
|
||||
{/* title="提示:勾选此项,则导出模板的考勤模块字段自动填充考勤模块的数据,导入时默认为覆盖导入"*/}
|
||||
{/* placement="topLeft"*/}
|
||||
{/*/>*/}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -107,7 +107,8 @@ export default class ImportModal extends React.Component {
|
|||
localStorage.removeItem("fileList");
|
||||
this.props.onCancel();
|
||||
}}
|
||||
style={{ width: 850 }}
|
||||
style={{ width: 850, height: 600 }}
|
||||
hasScroll
|
||||
className="importModalWrapper"
|
||||
initLoadCss
|
||||
buttons={
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
.importModalWrapper {
|
||||
.wea-dialog-body {
|
||||
height: 80vh;
|
||||
overflow: hidden auto;
|
||||
.ant-modal-body {
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,17 +1,17 @@
|
|||
import React from 'react';
|
||||
import { inject, observer } from 'mobx-react';
|
||||
import { toJS } from 'mobx';
|
||||
import React from "react";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import { toJS } from "mobx";
|
||||
|
||||
import { Button } from 'antd';
|
||||
import { WeaLogView } from 'comsMobx';
|
||||
import { WeaTop, WeaRightMenu, WeaLocaleProvider, WeaNewScroll } from 'ecCom';
|
||||
import { Button } from "antd";
|
||||
import { WeaLogView } from "comsMobx";
|
||||
import { WeaLocaleProvider, WeaNewScroll, WeaTop } from "ecCom";
|
||||
|
||||
import { renderNoright, renderLoading, getSearchs } from '../util'; // 从util文件引入公共的方法
|
||||
import { getSearchs, renderLoading, renderNoright } from "../util"; // 从util文件引入公共的方法
|
||||
|
||||
const getLabel = WeaLocaleProvider.getLabel;
|
||||
const WeaLogViewComp = WeaLogView.Component;
|
||||
|
||||
@inject('baseFormStore')
|
||||
@inject("baseFormStore")
|
||||
@observer
|
||||
export default class BaseForm extends React.Component {
|
||||
componentWillMount() { // 初始化渲染页面
|
||||
|
|
@ -31,24 +31,24 @@ export default class BaseForm extends React.Component {
|
|||
const { baseFormStore: { setLogVisible, saveForm } } = this.props;
|
||||
let btnArr = [
|
||||
{
|
||||
key: 'BTN_SAVE',
|
||||
icon: <i className='icon-coms-Preservation'/>,
|
||||
content : `${getLabel(86,'保存')}`,
|
||||
onClick : () => saveForm()
|
||||
key: "BTN_SAVE",
|
||||
icon: <i className="icon-coms-Preservation"/>,
|
||||
content: `${getLabel(86, "保存")}`,
|
||||
onClick: () => saveForm()
|
||||
},
|
||||
{
|
||||
key: 'log',
|
||||
content: getLabel(83, '日志'),
|
||||
icon: <i className='icon-coms-Print-log' />,
|
||||
onClick: () => setLogVisible(true),
|
||||
},]
|
||||
key: "log",
|
||||
content: getLabel(83, "日志"),
|
||||
icon: <i className="icon-coms-Print-log"/>,
|
||||
onClick: () => setLogVisible(true)
|
||||
}];
|
||||
return btnArr;
|
||||
}
|
||||
|
||||
|
||||
render() {
|
||||
/* 页面渲染说明:
|
||||
1、判断是否无权限: 是显示无权限页面
|
||||
2、渲染form页面:
|
||||
2、渲染form页面:
|
||||
2-1: WeaRightMenu 右键菜单
|
||||
2-2: WeaTop: 顶部: 包括下拉菜单
|
||||
2-3: renderLoading: 加载数据中的loading效果(统一封装在util中)
|
||||
|
|
@ -56,51 +56,56 @@ export default class BaseForm extends React.Component {
|
|||
2-5: 通过getSearchs方法渲染form
|
||||
*/
|
||||
const { baseFormStore } = this.props;
|
||||
const { loading, hasRight, form, condition, logVisible, logStore, saveLoading, setLogVisible, saveForm } = baseFormStore; // 从后台取数据 和 方法
|
||||
|
||||
const {
|
||||
loading,
|
||||
hasRight,
|
||||
form,
|
||||
condition,
|
||||
logVisible,
|
||||
logStore,
|
||||
saveLoading,
|
||||
setLogVisible,
|
||||
saveForm
|
||||
} = baseFormStore; // 从后台取数据 和 方法
|
||||
|
||||
if (!hasRight && !loading) { // 无权限处理
|
||||
return renderNoright();
|
||||
}
|
||||
|
||||
const btns = [ // 顶部按钮
|
||||
<Button type='primary' loading={saveLoading} onClick={() => saveForm()}>保存</Button>,
|
||||
<Button type="primary" loading={saveLoading} onClick={() => saveForm()}>保存</Button>
|
||||
];
|
||||
const collectParams = { // 收藏功能配置
|
||||
favname: '基础表单',
|
||||
favname: "基础表单",
|
||||
favouritetype: 1,
|
||||
objid: 0,
|
||||
link: 'wui/index.html#/ns_demo01/index',
|
||||
importantlevel: 1,
|
||||
link: "wui/index.html#/ns_demo01/index",
|
||||
importantlevel: 1
|
||||
};
|
||||
return (
|
||||
<WeaRightMenu
|
||||
datas={this.getRightMenu()} // 右键菜单
|
||||
collectParams={collectParams} // 收藏功能: 配置之后显示 收藏、帮助、显示页面地址 这3个功能
|
||||
<WeaTop
|
||||
title="基础表单" // title
|
||||
icon={<i className="icon-coms-fa"/>} // 左侧图标
|
||||
iconBgcolor="#F14A2D" // 左侧图标背景色
|
||||
buttons={btns} // 顶部按钮: 这里是保存按钮,不需要可以不显示
|
||||
buttonSpace={10} // 按钮之间的间隔
|
||||
showDropIcon={true} // 是否显示右侧下拉按钮
|
||||
dropMenuDatas={this.getRightMenu()} // 下拉菜单(和页面的右键菜单相同)
|
||||
dropMenuProps={{ collectParams }} // 收藏功能: 配置之后显示 收藏、帮助、显示页面地址 这3个功能
|
||||
>
|
||||
<WeaTop
|
||||
title="基础表单" // title
|
||||
icon={<i className="icon-coms-fa" />} // 左侧图标
|
||||
iconBgcolor='#F14A2D' // 左侧图标背景色
|
||||
buttons={btns} // 顶部按钮: 这里是保存按钮,不需要可以不显示
|
||||
buttonSpace={10} // 按钮之间的间隔
|
||||
showDropIcon={true} // 是否显示右侧下拉按钮
|
||||
dropMenuDatas={this.getRightMenu()} // 下拉菜单(和页面的右键菜单相同)
|
||||
dropMenuProps={{ collectParams }} // 收藏功能: 配置之后显示 收藏、帮助、显示页面地址 这3个功能
|
||||
>
|
||||
{loading ? renderLoading() :
|
||||
<WeaNewScroll height='100%'>
|
||||
{getSearchs(form, toJS(condition), 1)}
|
||||
</WeaNewScroll>
|
||||
}
|
||||
<WeaLogViewComp // 日志功能(一般后端的应用设置是需要的)
|
||||
visible={logVisible} // 日志弹框的显示隐藏
|
||||
onCancel={() => setLogVisible(false)} // 关闭日志弹框时的操作:设置logVisible属性为false
|
||||
logStore={logStore} // 日志的store
|
||||
logType="1" // 模块编码: 该参数要根据模块来给
|
||||
logSmallType="1" // 细分模块编码: 该参数要根据模块来给
|
||||
/>
|
||||
</WeaTop>
|
||||
</WeaRightMenu>
|
||||
)
|
||||
{loading ? renderLoading() :
|
||||
<WeaNewScroll height="100%">
|
||||
{getSearchs(form, toJS(condition), 1)}
|
||||
</WeaNewScroll>
|
||||
}
|
||||
<WeaLogViewComp // 日志功能(一般后端的应用设置是需要的)
|
||||
visible={logVisible} // 日志弹框的显示隐藏
|
||||
onCancel={() => setLogVisible(false)} // 关闭日志弹框时的操作:设置logVisible属性为false
|
||||
logStore={logStore} // 日志的store
|
||||
logType="1" // 模块编码: 该参数要根据模块来给
|
||||
logSmallType="1" // 细分模块编码: 该参数要根据模块来给
|
||||
/>
|
||||
</WeaTop>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,24 +5,11 @@
|
|||
* LastEditTime: 2022-06-29 10:06:13
|
||||
*/
|
||||
import React from "react";
|
||||
import { WeaCheckbox, WeaInputSearch, WeaDialog } from "ecCom";
|
||||
import { Button, Dropdown, Menu, Modal } from "antd";
|
||||
import "../../pages/dataAcquisition/attendance/index.less"
|
||||
import { WeaCheckbox, WeaDialog, WeaInputSearch } from "ecCom";
|
||||
import { Button } from "antd";
|
||||
import "./index.less";
|
||||
|
||||
|
||||
export const items = [
|
||||
{
|
||||
key: "1",
|
||||
title: "测试",
|
||||
checked: false
|
||||
},
|
||||
{
|
||||
key: "2",
|
||||
title: "测试2",
|
||||
checked: true
|
||||
}
|
||||
];
|
||||
|
||||
export default class SelectItemModal extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
@ -31,62 +18,52 @@ export default class SelectItemModal extends React.Component {
|
|||
};
|
||||
}
|
||||
|
||||
handleShowChecked(value) {
|
||||
value = value == 1 ? true : false;
|
||||
this.props.onShowChecked(value);
|
||||
}
|
||||
|
||||
handleMenuClick(e) {
|
||||
if (e.key == "1") { //恢复默认设置
|
||||
this.props.onRestoreDefault();
|
||||
} else if (e.key == "2") {
|
||||
this.props.onSetDefault();
|
||||
} else if (e.key == "3") {
|
||||
|
||||
}
|
||||
componentWillReceiveProps(nextProps, nextContext) {
|
||||
if (
|
||||
nextProps.visible !== this.props.visible &&
|
||||
!nextProps.visible
|
||||
) this.setState({ searchValue: "" });
|
||||
}
|
||||
|
||||
render() {
|
||||
const menu = (
|
||||
<Menu onClick={(e) => this.handleMenuClick(e)}>
|
||||
<Menu.Item key="1">恢复默认设置</Menu.Item>
|
||||
<Menu.Item key="2">设置默认设置</Menu.Item>
|
||||
{/* <Menu.Item key="3">操作日志</Menu.Item> */}
|
||||
</Menu>
|
||||
);
|
||||
const { searchValue } = this.state;
|
||||
const {
|
||||
title, onSearchItemSet, onShowOnlyChecked, children,
|
||||
onMoreOpts, onSave, ...extra
|
||||
} = this.props;
|
||||
const btns = [<Button type="primary" onClick={onSave}>保存</Button>];
|
||||
const moreBtn = {
|
||||
datas: [
|
||||
{
|
||||
key: "recovery",
|
||||
content: "恢复默认设置",
|
||||
icon: <i className="icon-coms-Flow-setting"/>,
|
||||
onClick: key => onMoreOpts(key)
|
||||
},
|
||||
{
|
||||
key: "setting",
|
||||
content: "设为默认设置",
|
||||
icon: <i className="icon-coms-Flow-setting"/>,
|
||||
onClick: key => onMoreOpts(key)
|
||||
}
|
||||
]
|
||||
};
|
||||
const titleComp = <div className="setHeaderWrapper">
|
||||
<span>{title}</span>
|
||||
<WeaInputSearch value={searchValue} onChange={searchValue => this.setState({ searchValue })}
|
||||
placeholder="请输入关键字" style={{ width: 200 }}
|
||||
onSearch={onSearchItemSet}
|
||||
/>
|
||||
</div>;
|
||||
const bottomLeft = <WeaCheckbox content="只显示已选中字段" onChange={onShowOnlyChecked}/>;
|
||||
return (
|
||||
<WeaDialog
|
||||
visible={this.props.visible}
|
||||
style={{width:800}}
|
||||
onCancel={this.props.onCancel}
|
||||
initLoadCss
|
||||
className="fieldSetWrapper"
|
||||
title="导入字段设置"
|
||||
buttons={[
|
||||
<Button type="primary" style={{ marginRight: "10px" }} onClick={() => {
|
||||
this.props.onSave();
|
||||
}}>保存</Button>,
|
||||
<Dropdown.Button overlay={menu}>更多</Dropdown.Button>
|
||||
]}
|
||||
<WeaDialog {...extra} hasScroll title={titleComp}
|
||||
style={{ width: 592, height: 248 }}
|
||||
buttons={btns} moreBtn={moreBtn}
|
||||
initLoadCss className="setWrapper"
|
||||
bottomLeft={bottomLeft}
|
||||
>
|
||||
<div className="searchWrapper">
|
||||
<WeaInputSearch
|
||||
placeholder={"请输入关键字"}
|
||||
value={this.state.searchValue}
|
||||
onChange={(value) => {
|
||||
this.setState({ searchValue: value });
|
||||
}}
|
||||
onSearch={(value) => {
|
||||
this.props.onSearch(value);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
{this.props.children}
|
||||
<div className="allInWrapper">
|
||||
<WeaCheckbox content="只显示已选中字段" onChange={(value) => {
|
||||
this.handleShowChecked(value);
|
||||
}}/>
|
||||
</div>
|
||||
{children}
|
||||
</WeaDialog>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,67 @@
|
|||
.setWrapper {
|
||||
.setHeaderWrapper, .setGroupWrapper {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.wea-title .ant-checkbox-wrapper > span:last-child, .setGroupWrapper > .checkedtitle {
|
||||
color: #111;
|
||||
font-weight: 600;
|
||||
font-size: 12px;
|
||||
padding-right: 8px;
|
||||
}
|
||||
|
||||
.itemContUl {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
|
||||
li {
|
||||
width: 124px;
|
||||
overflow: hidden;
|
||||
padding: 4px 0;
|
||||
|
||||
.wea-checkbox {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.ant-checkbox-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
|
||||
span:last-child {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.itemsWrapper {
|
||||
height: 160px;
|
||||
overflow: scroll;
|
||||
border: 1px solid #e5e5e5;
|
||||
border-radius: 4px;
|
||||
padding: 16px;
|
||||
width: 100%;
|
||||
|
||||
.empty {
|
||||
line-height: 160px;
|
||||
text-align: center;
|
||||
font-size: 14px;
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.wea-more-button {
|
||||
ul > li:last-child {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,78 +1,121 @@
|
|||
import React from "react";
|
||||
import { WeaCheckbox } from "ecCom";
|
||||
import { Col, Icon, Row } from "antd";
|
||||
/*
|
||||
* Author: 黎永顺
|
||||
* name: 设置项目
|
||||
* Description:
|
||||
* Date: 2023/3/6
|
||||
*/
|
||||
import React, { Component } from "react";
|
||||
import { WeaCheckbox, WeaSearchGroup } from "ecCom";
|
||||
|
||||
export default class SelectItemsWrapper extends React.Component {
|
||||
class SelectItemsWrapper extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
showContent: true,
|
||||
checkStatus: false
|
||||
searchVal: "",
|
||||
selectItem: [],
|
||||
groupItem: [],
|
||||
showOnlyChecked: false
|
||||
};
|
||||
}
|
||||
|
||||
handleAllChecked(value) {
|
||||
value = value == 1 ? true : false;
|
||||
let items = [...this.props.items];
|
||||
items.map(item => {
|
||||
item.checked = value;
|
||||
});
|
||||
componentDidMount() {
|
||||
const { dataSource } = this.props
|
||||
this.setState({
|
||||
checkStatus: value
|
||||
selectItem: _.map(_.filter(_.reduce(dataSource, (pre, cur) => {
|
||||
return [...pre, ...cur.items];
|
||||
}, []), item => !!item.checked), it => it.id)
|
||||
});
|
||||
this.props.onChange(items);
|
||||
}
|
||||
|
||||
handleItemChange(value, record) {
|
||||
value = value == 1 ? true : false;
|
||||
let items = [...this.props.items];
|
||||
items.map(item => {
|
||||
if (item.id == record.id) {
|
||||
item.checked = value;
|
||||
handleSearchItemSet = (searchVal) => this.setState({ searchVal });
|
||||
handleShowOnlyChecked = (showOnlyChecked) => this.setState({ showOnlyChecked: !!Number(showOnlyChecked) });
|
||||
handleSelectGroupAll = (groupId, checked) => {
|
||||
const { selectItem, groupItem } = this.state;
|
||||
const { dataSource } = this.props;
|
||||
_.map(dataSource, item => {
|
||||
if (item.groupId === groupId) {
|
||||
if (!!Number(checked)) {
|
||||
this.setState({
|
||||
groupItem: [...groupItem, ..._.map(item.items, child => child.id)]
|
||||
}, () => this.setState({ selectItem: [...selectItem, ...this.state.groupItem] }));
|
||||
} else {
|
||||
this.setState({
|
||||
groupItem: _.differenceWith(groupItem, _.map(item.items, child => child.id), _.isEqual)
|
||||
}, () => this.setState({ selectItem: this.state.groupItem }));
|
||||
}
|
||||
}
|
||||
});
|
||||
this.props.onChange(items);
|
||||
}
|
||||
};
|
||||
handleSelectItem = (id, checked) => {
|
||||
const { selectItem } = this.state;
|
||||
this.setState({
|
||||
selectItem: !!Number(checked) ? [...selectItem, id] : _.xorWith(selectItem, [id], _.isEqual)
|
||||
});
|
||||
};
|
||||
renderTitle = (item) => {
|
||||
const { onSelectGroupAll } = this.props;
|
||||
const { groupName, groupId, items } = item;
|
||||
const number = _.filter(items, it => !!it.checked).length;
|
||||
const value = _.every(items, it => !!it.checked) ? "1" : "0";
|
||||
return <div className="setGroupWrapper">
|
||||
<WeaCheckbox content={groupName} value={value} onChange={(val) => onSelectGroupAll(groupId, val)}/>
|
||||
<span className="checkedtitle">已选择{number}个字段</span>
|
||||
</div>;
|
||||
};
|
||||
|
||||
render() {
|
||||
const { searchVal, selectItem, showOnlyChecked } = this.state;
|
||||
const { onSelectItem, dataSource } = this.props;
|
||||
let setItemList = _.map(dataSource, item => {
|
||||
return {
|
||||
...item,
|
||||
items: _.filter(item.items || [], child => child.name.indexOf(searchVal) !== -1)
|
||||
};
|
||||
});
|
||||
setItemList = _.map(setItemList, item => {
|
||||
return {
|
||||
...item,
|
||||
items: _.map(item.items, child => {
|
||||
return { ...child, checked: selectItem.includes(child.id) };
|
||||
})
|
||||
};
|
||||
});
|
||||
if (showOnlyChecked) {
|
||||
setItemList = _.map(setItemList, item => {
|
||||
return { ...item, items: _.filter(item.items, it => !!it.checked) };
|
||||
});
|
||||
}
|
||||
return (
|
||||
<div>
|
||||
<div style={{ margin: "10px 0", cursor: "pointer" }}>
|
||||
<div style={{ display: "inline-block" }}><WeaCheckbox
|
||||
content={<span style={{ fontWeight: "600" }}>{this.props.title}</span>} onChange={(value) => {
|
||||
this.handleAllChecked(value);
|
||||
}} value={this.state.checkStatus}/></div>
|
||||
<div style={{ float: "right", fontWeight: "600" }} onClick={() => this.setState({
|
||||
showContent: !this.state.showContent
|
||||
})}>已选中{this.props.items ? this.props.items.filter(item => item.checked).length : 0}个字段
|
||||
<span style={{ marginLeft: "10px", fontWeight: "400" }}>
|
||||
{
|
||||
this.state.showContent ? <Icon type="down"/> : <Icon type="left"/>
|
||||
}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<React.Fragment>
|
||||
{
|
||||
this.state.showContent && <div style={{
|
||||
height: "160px",
|
||||
border: "1px solid #eee",
|
||||
padding: "10px",
|
||||
overflowY: "scroll",
|
||||
borderRadius: "5px"
|
||||
}}>
|
||||
<Row>
|
||||
{
|
||||
this.props.items && this.props.items.map(item => (
|
||||
<Col span={6}><WeaCheckbox content={item.name} value={item.checked} onChange={(value) => {
|
||||
this.handleItemChange(value, item);
|
||||
}}/></Col>
|
||||
))
|
||||
}
|
||||
</Row>
|
||||
</div>
|
||||
_.map(setItemList, item => {
|
||||
const { items } = item;
|
||||
return <WeaSearchGroup title={this.renderTitle(item)} showGroup>
|
||||
<div className="itemsWrapper">
|
||||
{
|
||||
_.isEmpty(items) ?
|
||||
<span className="empty">暂无数据</span> :
|
||||
<ul className="itemContUl">
|
||||
{
|
||||
_.map(items, child => {
|
||||
const { name, checked, id } = child;
|
||||
return <li title={name}>
|
||||
<WeaCheckbox
|
||||
content={name} value={checked ? "1" : "0"}
|
||||
onChange={(val) => onSelectItem(id, val)}
|
||||
/>
|
||||
</li>;
|
||||
})
|
||||
}
|
||||
</ul>
|
||||
}
|
||||
</div>
|
||||
</WeaSearchGroup>;
|
||||
})
|
||||
}
|
||||
|
||||
</div>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default SelectItemsWrapper;
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@
|
|||
.btnWrapper {
|
||||
position: absolute;
|
||||
right: 50px;
|
||||
top: 0px;
|
||||
top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -58,5 +58,8 @@
|
|||
.wea-new-top-req-wapper .wea-new-top-req-title>div:last-child{
|
||||
right: 16px!important;
|
||||
}
|
||||
.wea-new-top-req-wapper .wea-new-top-req-title>div:first-child>div:first-child{
|
||||
min-width: 440px!important;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ export default class StepSlide extends React.Component {
|
|||
className='slideOuterWrapper'
|
||||
visible={this.props.visible}
|
||||
top={0}
|
||||
width={40}
|
||||
width={65}
|
||||
height={100}
|
||||
direction={"right"}
|
||||
measure={"%"}
|
||||
|
|
|
|||
|
|
@ -1,28 +1,29 @@
|
|||
import React from 'react';
|
||||
import { WeaSteps } from 'ecCom'
|
||||
import React from "react";
|
||||
import { WeaSteps } from "ecCom";
|
||||
import "./index.less";
|
||||
|
||||
const Step = WeaSteps.Step;
|
||||
import "./index.less"
|
||||
|
||||
export default class StepSlideHeader extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<div className="stepSlideHeader">
|
||||
<div className="headerWrapper">
|
||||
<WeaSteps current={this.props.current}>
|
||||
{
|
||||
this.props.steps && this.props.steps.map(item =>
|
||||
(
|
||||
<Step description={item} />
|
||||
)
|
||||
)
|
||||
}
|
||||
</WeaSteps>
|
||||
</div>
|
||||
<div className="contentWrapper">
|
||||
{this.props.children}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
)
|
||||
}
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<div className="stepSlideHeader">
|
||||
<div className="headerWrapper">
|
||||
<WeaSteps current={this.props.current}>
|
||||
{
|
||||
this.props.steps && this.props.steps.map(item =>
|
||||
(
|
||||
<Step description={item}/>
|
||||
)
|
||||
)
|
||||
}
|
||||
</WeaSteps>
|
||||
</div>
|
||||
<div className="contentWrapper">
|
||||
{this.props.children}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
<div className="uploadWrapper">
|
||||
{
|
||||
imageUrl &&
|
||||
<div className="previewWrapper">
|
||||
<img data-imgsrc={imgPreviewProps.src} {...imgPreviewProps} onClick={viewer} alt=""/>
|
||||
<div className="operateWrapper">
|
||||
<i className="icon-coms-Delete operateIcon" onClick={this.handleDelete}/>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
{
|
||||
!imageUrl &&
|
||||
<WeaUpload {...uploadProps}>
|
||||
<div className="upload-select-picture-card">
|
||||
<Icon type="plus"/>
|
||||
<div className="uploadText">{getLabel(111, "上传图片")}</div>
|
||||
</div>
|
||||
</WeaUpload>
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default ImageUploadList;
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -14,7 +14,7 @@ import OtherDeduct from "./pages/dataAcquisition/otherDeduct";
|
|||
import CumSituation from "./pages/dataAcquisition/cumSituation";
|
||||
import Attendance from "./pages/dataAcquisition/attendance";
|
||||
import SpecialAddDeduction from "./pages/dataAcquisition/specialAddDeduction";
|
||||
import Ledger from "./pages/ledger";
|
||||
import Ledger from "./pages/ledgerPage";
|
||||
import Calculate from "./pages/calculate";
|
||||
import Payroll from "./pages/payroll";
|
||||
import PayrollGrant from "./pages/payroll/payrollGrant";
|
||||
|
|
@ -32,6 +32,12 @@ import MobilePayroll from "./pages/mobilePayroll";
|
|||
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 stores from "./stores";
|
||||
import "./style/index";
|
||||
|
|
@ -50,6 +56,7 @@ const SocialSecurityBenefits = (props) => props.children;
|
|||
const DataAcquisition = (props) => props.children;
|
||||
|
||||
// mySalary 我的薪资福利
|
||||
// mySalaryView 我的薪资福利-查看工资单
|
||||
// socialSecurityBenefits 社保福利
|
||||
// programme 社保福利方案
|
||||
// archives 社保福利档案
|
||||
|
|
@ -77,6 +84,9 @@ const DataAcquisition = (props) => props.children;
|
|||
// sysconfig 系統配置
|
||||
// sysconfig-1 规则配置
|
||||
// appconfig 应用配置
|
||||
// fieldManagement 字段管理
|
||||
// analysisOfSalaryStatistics 薪酬统计分析
|
||||
// reportView 薪酬报表查看
|
||||
|
||||
const Routes = (
|
||||
<Route
|
||||
|
|
@ -85,6 +95,7 @@ const Routes = (
|
|||
onEnter={getLocaleLabel}
|
||||
component={Home}>
|
||||
<Route key="mySalary" path="mySalary" component={MySalary}/>
|
||||
<Route key="mySalaryView" path="mySalary/:salaryInfoId" component={MySalaryView}/>
|
||||
<Route
|
||||
key="socialSecurityBenefits"
|
||||
path="socialSecurityBenefits"
|
||||
|
|
@ -129,6 +140,7 @@ const Routes = (
|
|||
/>
|
||||
<Route key="compareDetail" path="compareDetail" component={CompareDetail}/>
|
||||
<Route key="payroll" path="payroll" component={Payroll}/>
|
||||
<Route key="watermarkPreview" path="payroll/watermark/preview" component={WatermarkPreview}/>
|
||||
<Route key="payrollGrant" path="payrollGrant" component={PayrollGrant}/>
|
||||
<Route key="payrollDetail" path="payrollDetail" component={PayrollDetail}/>
|
||||
<Route
|
||||
|
|
@ -148,6 +160,10 @@ const Routes = (
|
|||
<Route key="sysconfig" path="sysconfig" component={SysConfig}/>
|
||||
<Route key="sysconfig-1" path="sysconfig-1" component={RuleConfig}/>
|
||||
<Route key="appconfig" path="appconfig" component={Appconfig}/>
|
||||
<Route key="fieldManagement" path="fieldManagement" component={FieldManagement}/>
|
||||
<Route key="analysisOfSalaryStatistics" path="analysisOfSalaryStatistics" component={AnalysisOfSalaryStatistics}/>
|
||||
<Route key="analysisOfSalaryStatisticsId" path="analysisOfSalaryStatistics/:employeeId" component={EmployeeList}/>
|
||||
<Route key="reportView" path="reportView" component={ReportView}/>
|
||||
</Route>
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
];
|
||||
|
|
@ -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 (
|
||||
<WeaDialog
|
||||
{...this.props}
|
||||
initLoadCss hasScroll
|
||||
style={{ width: 900, height: 450 }}
|
||||
className="dimensionSlideWrapper"
|
||||
title={
|
||||
<div className="dimensionTitle">
|
||||
<span>{formId ? getLabel(111, "编辑统计维度") : getLabel(111, "新建统计维度")}</span>
|
||||
<Button type="primary" onClick={this.handleSave} loading={loading}>{getLabel(111, "保存")}</Button>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
{getSearchs(form, condition, 1, false, this.formItemChange)}
|
||||
{
|
||||
dimType !== "QUALITATIVE" &&
|
||||
<WeaSearchGroup title={getLabel(111, "分组设置")} showGroup>
|
||||
{
|
||||
dimType === "RATION_GROUP_SPACING" &&
|
||||
<GroupSpacingEditTable onChange={this.handleConvertGroupDatasource}
|
||||
setting4RationGroupSpacing={setting4RationGroupSpacing}/>
|
||||
}
|
||||
{
|
||||
dimType === "RATION_GROUP_INDIVIDUAL" &&
|
||||
<GroupIndividualEditTable onChange={this.handleConvertGroupDatasource}
|
||||
setting4RationGroupIndividual={setting4RationGroupIndividual}/>
|
||||
}
|
||||
</WeaSearchGroup>
|
||||
}
|
||||
</WeaDialog>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default DimensionSlide;
|
||||
|
|
@ -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 (
|
||||
<span className="space10">
|
||||
{
|
||||
record.canEdit &&
|
||||
<a href="javascript: void(0);" onClick={() => onEdit(record.id)}>{getLabel(111, "编辑")}</a>
|
||||
}
|
||||
{
|
||||
record.canDelete &&
|
||||
<a href="javascript: void(0);"
|
||||
onClick={() => this.dimensionDelete([record.id])}>{getLabel(111, "删除")}</a>
|
||||
}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
}
|
||||
];
|
||||
return (
|
||||
<WeaTable
|
||||
rowKey="id"
|
||||
className="dimensionTableWrapper"
|
||||
dataSource={dataSource}
|
||||
pagination={pagination}
|
||||
loading={loading}
|
||||
columns={columns}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default DimensionTable;
|
||||
|
|
@ -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 <a target="_blank"
|
||||
href={`${window.location.origin}/spa/hrmSalary/static/index.html#/main/hrmSalary/analysisOfSalaryStatistics/${record.id}?name=${record.name}&dept=${record.department || ""}`}>{getLabel(111, "查看")}</a>;
|
||||
}
|
||||
}]
|
||||
});
|
||||
}
|
||||
}).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 (
|
||||
<WeaTable
|
||||
rowKey="id"
|
||||
className="employeeTableWrapper"
|
||||
dataSource={dataSource}
|
||||
pagination={pagination}
|
||||
loading={loading}
|
||||
columns={columns}
|
||||
scroll={{ y: `calc(100vh - 174px)` }}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default EmployeeDetails;
|
||||
|
|
@ -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 (
|
||||
<WeaTableEdit
|
||||
draggable={true} columns={columns} datas={dataSource}
|
||||
showCopy={false} deleteConfirm onChange={this.handleChangeTableData}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default GroupIndividualEditTable;
|
||||
|
|
@ -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 (
|
||||
<WeaTableEdit
|
||||
draggable={true} deleteConfirm columns={columns}
|
||||
datas={_.map(dataSource, item => ({ ...item, to: getLabel(111, "至") }))}
|
||||
showCopy={false} onChange={this.handleChangeTableData}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default GroupSpacingEditTable;
|
||||
|
|
@ -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 (
|
||||
<React.Fragment>{getSearchs(form, condition, 1, false)}</React.Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default ReportForm;
|
||||
|
|
@ -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 (
|
||||
<Row gutter={16} className="reportRow">
|
||||
{
|
||||
_.isEmpty(dataSource) ? <div className="empty">{getLabel(111, "暂无数据")}</div> :
|
||||
_.map(dataSource, it => {
|
||||
const { reportName, dimension, id, dimensionId } = it;
|
||||
return <Col className="gutter-row" span={6} onClick={() => this.handleGoReportView(id)}>
|
||||
<div className="card-item">
|
||||
<div className="cardLeft"><i className="icon-coms-fa"/></div>
|
||||
<div className="cardCenter">
|
||||
<span className="reportName">{reportName}</span>
|
||||
<div className="dimension">
|
||||
<div className="label">{getLabel(111, "统计维度")}:</div>
|
||||
<div className="value">{dimension}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="cardRight">
|
||||
<Dropdown overlay={
|
||||
<Menu onClick={e => this.handleOptsClick(e, id, dimensionId)}>
|
||||
<Menu.Item key="edit">{getLabel(111, "编辑")}</Menu.Item>
|
||||
<Menu.Item key="delete">{getLabel(111, "删除")}</Menu.Item>
|
||||
</Menu>
|
||||
}>
|
||||
<Button type="ghost"><i className="icon-coms-more"/></Button>
|
||||
</Dropdown>
|
||||
</div>
|
||||
</div>
|
||||
</Col>;
|
||||
})
|
||||
}
|
||||
</Row>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default ReportList;
|
||||
|
|
@ -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" ? [
|
||||
<Button type="primary" onClick={this.handleSaveReportList} loading={loading}>{getLabel(111, "保存")}</Button>
|
||||
] : [];
|
||||
return (
|
||||
<WeaDialog
|
||||
{...this.props} hasScroll
|
||||
style={typeKey === "addReport" ? { width: 600 } : { width: 640, height: 540 }}
|
||||
buttons={buttons}
|
||||
onCancel={onCancel}
|
||||
initLoadCss
|
||||
className="dimensionModalWrapper"
|
||||
>
|
||||
{this.props.children}
|
||||
</WeaDialog>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default StatisticsModal;
|
||||
|
|
@ -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" ?
|
||||
<div className="dimensionTitle">
|
||||
<span>{getLabel(111, "统计维度管理")}</span>
|
||||
<Button type="primary" onClick={() => this.handleAddDimension()}>{getLabel(111, "新建统计维度")}</Button>
|
||||
</div>
|
||||
: 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" ? [
|
||||
<Button type="primary" onClick={() => this.handleReqBtnsClick("addReport")}>{getLabel(111, "新建报表")}</Button>,
|
||||
<Button type="ghost"
|
||||
onClick={() => this.handleReqBtnsClick("dimension")}>{getLabel(111, "维度统计管理")}</Button>,
|
||||
<WeaInputSearch placeholder={getLabel(111, "请输入报表名称")} className="search"
|
||||
value={reportName}
|
||||
onChange={reportName => this.setState({ reportName })}
|
||||
onSearch={() => this.handleReqBtnsClick("search")}/>
|
||||
] : [
|
||||
<span className="employeeYearWrapper">
|
||||
<span>{getLabel(111, "年薪资核算人员明细:")}</span>
|
||||
<WeaDatePicker value={year} format="YYYY" onChange={year => this.setState({ year })}/>
|
||||
</span>,
|
||||
<WeaInputSearch placeholder={getLabel(111, "请输入姓名、工号、身份证号")} className="search"
|
||||
value={keyword}
|
||||
onChange={keyword => this.setState({ keyword })}
|
||||
onSearch={() => this.employeeListRef.statisticsEmployeeList()}/>
|
||||
];
|
||||
const tabs = [
|
||||
{ key: "statistics", title: getLabel(111, "统计表") },
|
||||
{ key: "detail", title: getLabel(111, "员工明细") }
|
||||
];
|
||||
return (
|
||||
<WeaReqTop
|
||||
title={getLabel(111, "薪酬统计报表")} icon={<i className="icon-coms-fa"/>} 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" ?
|
||||
<ReportList
|
||||
ref={dom => this.reportListRef = dom}
|
||||
reportName={reportName}
|
||||
onEdit={this.handleReqBtnsClick}
|
||||
/> : <EmployeeDetails
|
||||
ref={dom => this.employeeListRef = dom}
|
||||
keyword={keyword} year={year}
|
||||
/>
|
||||
}
|
||||
<StatisticsModal {...modalReq} onCancel={this.handleCancel} form={reportForm}>
|
||||
{
|
||||
modalReq.typeKey === "dimension" &&
|
||||
<DimensionTable ref={dom => this.dimensionTableRef = dom}
|
||||
onEdit={id => this.handleAddDimension(id)}
|
||||
/>
|
||||
}
|
||||
{
|
||||
modalReq.typeKey === "addReport" &&
|
||||
<ReportForm form={reportForm} condition={reportConditions}/>
|
||||
}
|
||||
</StatisticsModal>
|
||||
<DimensionSlide
|
||||
{...slideReq} onCancel={this.handleClose}
|
||||
form={statisticsForm} condition={conditions}
|
||||
initCondition={this.initCondition} onChangeCondition={this.handleChangeCondition}
|
||||
/>
|
||||
</WeaReqTop>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default Index;
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -5,9 +5,19 @@
|
|||
* Date: 2022-09-27 18:17:02
|
||||
*/
|
||||
import React, { Component } from "react";
|
||||
import { WeaCheckbox, WeaDatePicker, WeaFormItem, WeaSearchGroup, WeaTop } from "ecCom";
|
||||
import { WeaCheckbox, WeaDatePicker, WeaFormItem, WeaInput, WeaSearchGroup, WeaTop } from "ecCom";
|
||||
import * as API from "../../apis/ruleconfig";
|
||||
import { Button, message } from "antd";
|
||||
import "./index.less";
|
||||
|
||||
const Input = (props) => {
|
||||
const { label, value } = props;
|
||||
return (
|
||||
<WeaFormItem label={label} labelCol={{ span: 8 }} wrapperCol={{ span: 16 }}>
|
||||
<WeaInput viewAttr={1} value={value}/>
|
||||
</WeaFormItem>
|
||||
);
|
||||
};
|
||||
|
||||
class AppConfig extends Component {
|
||||
constructor(props) {
|
||||
|
|
@ -15,6 +25,9 @@ class AppConfig extends Component {
|
|||
this.state = {
|
||||
openAcctResultSum: "0",
|
||||
displayEmpInfoReport: "0",
|
||||
isLog: "0",
|
||||
openFormulaForcedEditing: "0",
|
||||
version: "",
|
||||
loading: false
|
||||
};
|
||||
}
|
||||
|
|
@ -26,8 +39,13 @@ class AppConfig extends Component {
|
|||
queryAppsetting = () => {
|
||||
API.queryAppsetting().then(({ status, data }) => {
|
||||
if (status) {
|
||||
const { openAcctResultSum, displayEmpInfoReport } = data;
|
||||
this.setState({ openAcctResultSum, displayEmpInfoReport });
|
||||
const { openAcctResultSum, displayEmpInfoReport, isLog, openFormulaForcedEditing, version } = data;
|
||||
this.setState({
|
||||
openAcctResultSum, displayEmpInfoReport,
|
||||
isLog: isLog === "true" ? "1" : "0",
|
||||
openFormulaForcedEditing: openFormulaForcedEditing === "true" ? "1" : "0",
|
||||
version
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
@ -46,9 +64,15 @@ class AppConfig extends Component {
|
|||
};
|
||||
|
||||
render() {
|
||||
const { openAcctResultSum, displayEmpInfoReport, loading } = this.state;
|
||||
const { openAcctResultSum, displayEmpInfoReport, loading, openFormulaForcedEditing, isLog, version } = this.state;
|
||||
const btns = [<Button type="primary" loading={loading} onClick={this.appSettingSave}>保存</Button>];
|
||||
const items = [
|
||||
{
|
||||
com: Input({
|
||||
label: "版本号",
|
||||
value: version
|
||||
})
|
||||
},
|
||||
{
|
||||
com: CheckBox({
|
||||
label: "显示薪资核算结果合计列",
|
||||
|
|
@ -66,6 +90,20 @@ class AppConfig extends Component {
|
|||
this.setState({ displayEmpInfoReport });
|
||||
}
|
||||
})
|
||||
},
|
||||
{
|
||||
com: CheckBox({
|
||||
label: "是否输出日志",
|
||||
disabled: true,
|
||||
value: isLog
|
||||
})
|
||||
},
|
||||
{
|
||||
com: CheckBox({
|
||||
label: "是否可编辑系统公式",
|
||||
disabled: true,
|
||||
value: openFormulaForcedEditing
|
||||
})
|
||||
}
|
||||
];
|
||||
return (
|
||||
|
|
@ -85,10 +123,10 @@ class AppConfig extends Component {
|
|||
export default AppConfig;
|
||||
|
||||
export const CheckBox = payload => {
|
||||
const { label, onChange, value } = payload;
|
||||
const { label, onChange, value, disabled = false } = payload;
|
||||
return (
|
||||
<WeaFormItem label={label} labelCol={{ span: 8 }} wrapperCol={{ span: 16 }}>
|
||||
<WeaCheckbox display="switch" value={value} onChange={onChange}/>
|
||||
<WeaCheckbox display="switch" disabled={disabled} value={value} onChange={onChange}/>
|
||||
</WeaFormItem>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -0,0 +1,11 @@
|
|||
.appConfigWrapper {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.wea-search-group {
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,16 +1,16 @@
|
|||
import React from "react";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import { Button, DatePicker, Dropdown, Menu, message, Modal } from "antd";
|
||||
import { WeaInputSearch, WeaRightMenu, WeaTop } from "ecCom";
|
||||
import { renderNoright } from "../../util"; // 渲染form数据的方法:因为多个页面都会使用,所以抽的公共方法在util中
|
||||
import { Button, DatePicker, Dropdown, Menu, message, Modal, Tag } from "antd";
|
||||
import { WeaInputSearch, WeaLocaleProvider, WeaNewScroll, WeaTop } from "ecCom";
|
||||
import { renderNoright } from "../../util";
|
||||
import CustomTab from "../../components/customTab";
|
||||
|
||||
import { columns } from "./columns";
|
||||
import moment from "moment";
|
||||
import BaseFormModal from "./baseFormModal";
|
||||
import CustomPaginationTable from "../../components/customPaginationTable";
|
||||
import ProgressModal from "../../components/progressModal";
|
||||
import "./index.less";
|
||||
|
||||
const { getLabel } = WeaLocaleProvider;
|
||||
const MonthPicker = DatePicker.MonthPicker;
|
||||
|
||||
@inject("calculateStore", "taxAgentStore")
|
||||
|
|
@ -26,25 +26,7 @@ export default class Calculate extends React.Component {
|
|||
searchValue: "",
|
||||
startDate: moment(new Date()).startOf("year").format("YYYY-MM"),
|
||||
endDate: moment(new Date()).startOf("month").format("YYYY-MM"),
|
||||
current: 1,
|
||||
columns: columns.map(item => {
|
||||
if (item.dataIndex == "cz") {
|
||||
item.render = () =>
|
||||
<div>
|
||||
<a style={{ marginRight: "10px" }}>核算</a>
|
||||
<a style={{ marginRight: "10px" }}>归档</a>
|
||||
<a
|
||||
style={{ marginRight: "10px" }}
|
||||
onClick={() =>
|
||||
window.open(
|
||||
"/spa/hrmSalary/static/index.html#/main/hrmSalary/placeOnFileDetail"
|
||||
)}>
|
||||
查看
|
||||
</a>
|
||||
<a>删除</a>
|
||||
</div>;
|
||||
}
|
||||
})
|
||||
current: 1
|
||||
};
|
||||
this.pageInfo = { current: 1, pageSize: 10 };
|
||||
}
|
||||
|
|
@ -60,16 +42,17 @@ export default class Calculate extends React.Component {
|
|||
}
|
||||
|
||||
// 搜索
|
||||
handleSearch(value) {
|
||||
handleSearch = (value, extra = {}) => {
|
||||
const { calculateStore } = this.props;
|
||||
const { getSalaryAcctList } = calculateStore;
|
||||
getSalaryAcctList({
|
||||
name: value,
|
||||
startMonthStr: this.state.startDate,
|
||||
endMonthStr: this.state.endDate,
|
||||
current: this.state.current
|
||||
current: this.state.current,
|
||||
...extra
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
handleRangePickerChange(type, value) {
|
||||
const { calculateStore: { getSalaryAcctList } } = this.props;
|
||||
|
|
@ -141,6 +124,12 @@ export default class Calculate extends React.Component {
|
|||
message.success("归档成功");
|
||||
this.handleSearch(this.state.searchValue);
|
||||
});
|
||||
}).catch(() => {
|
||||
clearInterval(this.timer);
|
||||
this.setState({
|
||||
progressVisible: false,
|
||||
progress: 0
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -152,6 +141,20 @@ export default class Calculate extends React.Component {
|
|||
});
|
||||
}
|
||||
|
||||
// 回算
|
||||
handleBackCalculate = (record) => {
|
||||
Modal.confirm({
|
||||
title: "信息确认",
|
||||
content: "确定回算吗?\n 回算后,正常核算的数据会被覆盖,正常核算的工资单不能继续发放或撤回!",
|
||||
onOk: () => {
|
||||
const { calculateStore: { backCalculate } } = this.props;
|
||||
backCalculate(record.id).then(() => {
|
||||
this.handleSearch(this.state.searchValue);
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 查看详情回调
|
||||
handleDetail(record) {
|
||||
window.open(
|
||||
|
|
@ -161,23 +164,33 @@ export default class Calculate extends React.Component {
|
|||
}
|
||||
|
||||
// 获取列表
|
||||
getColumns() {
|
||||
getColumns = () => {
|
||||
const {
|
||||
calculateStore: { salaryListColumns },
|
||||
taxAgentStore: { showOperateBtn }
|
||||
} = this.props;
|
||||
let columns = [...salaryListColumns];
|
||||
let columns = [...salaryListColumns].filter(item => item.dataIndex !== "backCalcStatus" && item.dataIndex !== "acctTimes");
|
||||
columns.map(item => {
|
||||
if (item.title == "操作" && showOperateBtn) {
|
||||
if (item.dataIndex === "salarySobName") {
|
||||
item.width = 300;
|
||||
item.render = (text, record) => {
|
||||
const accountBtn = _.filter(
|
||||
record.operate,
|
||||
it => it.text == "核算" || it.text == "重新核算"
|
||||
);
|
||||
const notAccountBtn = _.filter(
|
||||
record.operate,
|
||||
it => it.text != "核算" && it.text != "重新核算"
|
||||
);
|
||||
return <div className="salarySobNameWrapper">
|
||||
<span>{text}</span>
|
||||
<div className="salarySobNameTagWrapper">
|
||||
{
|
||||
record.backCalcStatus === 1 &&
|
||||
<i className="icon-coms-Refresh" title="回算"/>
|
||||
}
|
||||
<Tag color="blue">{`第${record.acctTimes}次`}</Tag>
|
||||
</div>
|
||||
</div>;
|
||||
};
|
||||
}
|
||||
if (item.dataIndex === "operate" && showOperateBtn) {
|
||||
item.width = 150;
|
||||
item.render = (text, record) => {
|
||||
const accountBtn = _.take(record.operate, 2);
|
||||
const notAccountBtn = _.drop(record.operate, 2);
|
||||
let operateBtn = [];
|
||||
if (!_.isEmpty(accountBtn)) {
|
||||
operateBtn.push(
|
||||
|
|
@ -189,13 +202,8 @@ export default class Calculate extends React.Component {
|
|||
style={{ display: "inline-block", marginRight: 8 }}>
|
||||
<a
|
||||
href="javascript:void(0);"
|
||||
onClick={() => {
|
||||
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}
|
||||
</a>
|
||||
</div>
|
||||
|
|
@ -211,29 +219,14 @@ export default class Calculate extends React.Component {
|
|||
{notAccountBtn.map(cz =>
|
||||
<Menu.Item>
|
||||
<a
|
||||
onClick={() => {
|
||||
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);
|
||||
}
|
||||
}}>
|
||||
onClick={() => this.handleOperateClick(cz.index, record)}>
|
||||
{cz.text}
|
||||
</a>
|
||||
</Menu.Item>
|
||||
)}
|
||||
</Menu>
|
||||
}>
|
||||
<i
|
||||
className="icon-coms-more"
|
||||
style={{ color: "#4d7ad8", cursor: "pointer" }}
|
||||
/>
|
||||
<a href="javascript:void(0);"><i className="icon-coms-more"/></a>
|
||||
</Dropdown>
|
||||
);
|
||||
}
|
||||
|
|
@ -241,8 +234,24 @@ 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);
|
||||
}
|
||||
};
|
||||
|
||||
// 分页
|
||||
handleDataPageChange(value) {
|
||||
|
|
@ -271,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: <i className="icon-coms-Custom"/>,
|
||||
content: "显示列定制",
|
||||
onClick: this.showColumn
|
||||
}
|
||||
];
|
||||
const collectParams = {
|
||||
// 收藏功能配置
|
||||
favname: "薪资核算",
|
||||
favouritetype: 1,
|
||||
objid: 0,
|
||||
link: "wui/index.html#/ns_demo03/index",
|
||||
importantlevel: 1
|
||||
};
|
||||
const adBtn = [
|
||||
// 高级搜索内部按钮
|
||||
<Button type="primary" onClick={doSearch}>
|
||||
搜索
|
||||
</Button>,
|
||||
<Button type="ghost" onClick={() => form.resetForm()}>
|
||||
重置
|
||||
</Button>,
|
||||
<Button type="ghost" onClick={() => setShowSearchAd(false)}>
|
||||
取消
|
||||
</Button>
|
||||
];
|
||||
|
||||
const renderRightOperation = () => {
|
||||
const { startDate, endDate } = this.state;
|
||||
return (
|
||||
|
|
@ -363,7 +329,7 @@ export default class Calculate extends React.Component {
|
|||
this.setState({ searchValue: value });
|
||||
}}
|
||||
onSearch={value => {
|
||||
this.handleSearch(value);
|
||||
this.handleSearch(value, { current: 1 });
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
|
@ -372,60 +338,53 @@ export default class Calculate extends React.Component {
|
|||
|
||||
return (
|
||||
<div className="mySalaryBenefitsWrapper">
|
||||
<WeaRightMenu
|
||||
datas={rightMenu} // 右键菜单
|
||||
collectParams={collectParams}>
|
||||
{/* 收藏功能: 配置之后显示 收藏、帮助、显示页面地址 这3个功能 */}
|
||||
<WeaTop
|
||||
title="薪资核算" // 文字
|
||||
icon={<i className="icon-coms-fa"/>} // 左侧图标
|
||||
iconBgcolor="#F14A2D" // 左侧图标背景色
|
||||
showDropIcon={false} // 是否显示下拉按钮
|
||||
dropMenuDatas={rightMenu} // 下拉菜单(和页面的右键菜单相同)
|
||||
dropMenuProps={{ collectParams }}>
|
||||
{/* 收藏功能: 配置之后显示 收藏、帮助、显示页面地址 这3个功能 */}
|
||||
<CustomTab
|
||||
searchOperationItem={renderRightOperation()}
|
||||
onChange={v => {
|
||||
}}
|
||||
/>
|
||||
<CustomPaginationTable
|
||||
loading={loading}
|
||||
columns={this.getColumns()}
|
||||
dataSource={salaryListDataSource}
|
||||
total={salaryListPageInfo.total}
|
||||
current={salaryListPageInfo.pageNum}
|
||||
pageSize={this.pageInfo.pageSize}
|
||||
onPageChange={value => {
|
||||
this.handleDataPageChange(value);
|
||||
}}
|
||||
onShowSizeChange={(current, pageSize) => {
|
||||
this.pageInfo = { current, pageSize };
|
||||
this.handleShowSizeChange(this.pageInfo);
|
||||
}}
|
||||
/>
|
||||
</WeaTop>
|
||||
{/*归档进度条*/}
|
||||
{
|
||||
this.state.progressVisible &&
|
||||
<ProgressModal
|
||||
title="正在归档请稍后"
|
||||
visible={this.state.progressVisible}
|
||||
onCancel={() => {
|
||||
this.setState({ progressVisible: false, progress: 0 });
|
||||
}}
|
||||
progress={this.state.progress}
|
||||
/>
|
||||
}
|
||||
{this.state.baseFormVisible &&
|
||||
<BaseFormModal
|
||||
visible={this.state.baseFormVisible}
|
||||
onRefresh={() => this.handleSearch(this.state.searchValue)}
|
||||
onCancel={() => {
|
||||
this.setState({ baseFormVisible: false });
|
||||
}}
|
||||
/>}
|
||||
</WeaRightMenu>
|
||||
{/* 收藏功能: 配置之后显示 收藏、帮助、显示页面地址 这3个功能 */}
|
||||
<WeaTop
|
||||
title="薪资核算"
|
||||
icon={<i className="icon-coms-fa"/>}
|
||||
iconBgcolor="#F14A2D"
|
||||
showDropIcon={false}>
|
||||
<CustomTab searchOperationItem={renderRightOperation()}/>
|
||||
<div className="tableWrapper">
|
||||
<WeaNewScroll height="100%">
|
||||
<CustomPaginationTable
|
||||
loading={loading}
|
||||
columns={this.getColumns()}
|
||||
dataSource={salaryListDataSource}
|
||||
total={salaryListPageInfo.total}
|
||||
current={salaryListPageInfo.pageNum}
|
||||
pageSize={this.pageInfo.pageSize}
|
||||
onPageChange={value => {
|
||||
this.handleDataPageChange(value);
|
||||
}}
|
||||
onShowSizeChange={(current, pageSize) => {
|
||||
this.pageInfo = { current, pageSize };
|
||||
this.handleShowSizeChange(this.pageInfo);
|
||||
}}
|
||||
/>
|
||||
</WeaNewScroll>
|
||||
</div>
|
||||
</WeaTop>
|
||||
{/*归档进度条*/}
|
||||
{
|
||||
this.state.progressVisible &&
|
||||
<ProgressModal
|
||||
title="正在归档请稍后"
|
||||
visible={this.state.progressVisible}
|
||||
onCancel={() => {
|
||||
this.setState({ progressVisible: false, progress: 0 });
|
||||
}}
|
||||
progress={this.state.progress}
|
||||
/>
|
||||
}
|
||||
{this.state.baseFormVisible &&
|
||||
<BaseFormModal
|
||||
visible={this.state.baseFormVisible}
|
||||
onRefresh={() => this.handleSearch(this.state.searchValue)}
|
||||
onCancel={() => {
|
||||
this.setState({ baseFormVisible: false });
|
||||
}}
|
||||
/>}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,19 @@
|
|||
.dataList-wrapper {
|
||||
.ant-modal-body{
|
||||
.ant-modal-body {
|
||||
padding: 16px 120px
|
||||
}
|
||||
|
||||
.formItem {
|
||||
display: flex;
|
||||
|
||||
.ant-col-8 {
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
.wea-select, .ant-select {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.ant-select-selection {
|
||||
width: 100%;
|
||||
height: 30px;
|
||||
|
|
@ -13,3 +21,25 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.salarySobNameWrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
|
||||
& > span {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.salarySobNameTagWrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
i {
|
||||
color: #5d9cec;
|
||||
margin-right: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,18 +18,17 @@ export default class AcctResultImportModal extends React.Component {
|
|||
salaryItemIds: ""
|
||||
},
|
||||
step: 0,
|
||||
selectFieldVisible: false
|
||||
selectFieldVisible: false,
|
||||
addHeadFields: {
|
||||
visible: false, itemsByGroup: []
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
const { id } = this.props;
|
||||
if (id) {
|
||||
let modalParam = { ...this.state.modalParam };
|
||||
modalParam.salaryAcctRecordId = id;
|
||||
this.setState({
|
||||
modalParam
|
||||
});
|
||||
this.getImportField();
|
||||
} else {
|
||||
this.setState({
|
||||
modalParam: { ...this.state.modalParam, salaryAcctRecordId: "123" }
|
||||
|
|
@ -35,9 +36,35 @@ export default class AcctResultImportModal extends React.Component {
|
|||
}
|
||||
}
|
||||
|
||||
getImportField = () => {
|
||||
const { calculateStore: { getImportField }, id } = this.props;
|
||||
const { addHeadFields } = this.props;
|
||||
getImportField(id).then(data => {
|
||||
this.setState({
|
||||
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() {
|
||||
const { isStandingBook, standingBookTabKey } = this.props;
|
||||
const { isStandingBook, standingBookTabKey, standingBookType } = this.props;
|
||||
let url = "";
|
||||
if (_.isEmpty(this.state.modalParam.salaryItemIds)) {
|
||||
message.warning("请选择表单字段");
|
||||
|
|
@ -52,6 +79,8 @@ export default class AcctResultImportModal extends React.Component {
|
|||
url = `${window.location.origin}/api/bs/hrmsalary/siaccount/welfare/importtemplate/export?welfareNames=${this.state.modalParam.salaryItemIds}&billMonth=${billMonth}&paymentOrganization=${paymentOrganization}`;
|
||||
} else if (standingBookTabKey === "3") {
|
||||
url = `${window.location.origin}/api/bs/hrmsalary/siaccount/welfare/supplyimporttemplate/export?welfareNames=${this.state.modalParam.salaryItemIds}&billMonth=${billMonth}&paymentOrganization=${paymentOrganization}`;
|
||||
} else if (standingBookType === "difference") {
|
||||
url = `${window.location.origin}/api/bs/hrmsalary/siaccount/welfare/balanceimporttemplate/export?welfareNames=${this.state.modalParam.salaryItemIds}&billMonth=${billMonth}&paymentOrganization=${paymentOrganization}`;
|
||||
}
|
||||
}
|
||||
window.open(url, "_self");
|
||||
|
|
@ -82,24 +111,31 @@ export default class AcctResultImportModal extends React.Component {
|
|||
}
|
||||
|
||||
// 渲染第一步表单
|
||||
renderFormComponent() {
|
||||
renderFormComponent = () => {
|
||||
return <Badge
|
||||
count={!_.isEmpty(this.state.modalParam.salaryItemIds) ? this.state.modalParam.salaryItemIds.split(",").length : 0}>
|
||||
<Button onClick={() => {
|
||||
this.handleSelectedField();
|
||||
}}>请选择表单字段</Button>
|
||||
<Button onClick={this.handleSelectedField}>请选择表单字段</Button>
|
||||
</Badge>;
|
||||
}
|
||||
};
|
||||
|
||||
// 选择表单字段
|
||||
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 => {
|
||||
|
|
@ -133,7 +169,7 @@ export default class AcctResultImportModal extends React.Component {
|
|||
modalParam
|
||||
});
|
||||
this.props.onAdd(fieldDate);
|
||||
}
|
||||
};
|
||||
|
||||
// 初始化Import数据
|
||||
handleImportModalInit() {
|
||||
|
|
@ -162,8 +198,10 @@ export default class AcctResultImportModal extends React.Component {
|
|||
}
|
||||
|
||||
render() {
|
||||
const billMonth = getQueryString("billMonth");
|
||||
//isStandingBook: 是否是社保福利台账核算的导入标识
|
||||
const { calculateStore, standingBookStore, isStandingBook, visiable } = this.props;
|
||||
//standingBookType: 是否是补差的导入标识
|
||||
const { calculateStore, standingBookStore, isStandingBook, visiable, standingBookType } = this.props;
|
||||
const {
|
||||
fetchPreviewAcctResult,
|
||||
previewAcctResultColumns,
|
||||
|
|
@ -176,14 +214,16 @@ export default class AcctResultImportModal extends React.Component {
|
|||
previewStandingBookAcctResultColumns,
|
||||
previewStandingBookAcctResultDataSource,
|
||||
importStandingBookAcctResult,
|
||||
importInsuranceAcctDetail
|
||||
importInsuranceAcctDetail,
|
||||
importBalanceInsuranceDetail
|
||||
} = standingBookStore;
|
||||
const { step, selectFieldVisible, modalParam } = this.state;
|
||||
const { step, modalParam, selectFieldVisible, addHeadFields } = this.state;
|
||||
return (
|
||||
<div>
|
||||
{
|
||||
visiable && <ImportModal
|
||||
isStandingBook={isStandingBook}
|
||||
standingBookType={standingBookType}
|
||||
init={() => {
|
||||
this.handleImportModalInit();
|
||||
}}
|
||||
|
|
@ -200,7 +240,11 @@ export default class AcctResultImportModal extends React.Component {
|
|||
!isStandingBook ? fetchPreviewAcctResult(params) : welfarePreview(params);
|
||||
}}
|
||||
importFile={(params) => {
|
||||
!isStandingBook ? fetchImportAcctResult(params) : importInsuranceAcctDetail(params);
|
||||
!isStandingBook ?
|
||||
fetchImportAcctResult(params) :
|
||||
standingBookType === "difference" ?
|
||||
importBalanceInsuranceDetail({ ...params, billMonth }) :
|
||||
importInsuranceAcctDetail(params);
|
||||
}}
|
||||
templateLink={() => {
|
||||
this.handleAccResultTemplateLink();
|
||||
|
|
@ -215,6 +259,7 @@ export default class AcctResultImportModal extends React.Component {
|
|||
{
|
||||
selectFieldVisible && <SelectFieldModal
|
||||
isStandingBook={isStandingBook}
|
||||
standingBookType={standingBookType}
|
||||
id={this.props.id}
|
||||
visible={selectFieldVisible}
|
||||
fieldData={this.props.fieldData}
|
||||
|
|
@ -228,6 +273,24 @@ export default class AcctResultImportModal extends React.Component {
|
|||
}}
|
||||
/>
|
||||
}
|
||||
<AddHeaderFieldsModal {...addHeadFields} selectItems={modalParam.salaryItemIds}
|
||||
onCancel={() => 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();
|
||||
})}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
<WeaDialog
|
||||
{...this.props} hasScroll initLoadCss
|
||||
scalable title={getLabel(111, "添加表头字段")}
|
||||
style={{ width: 700, height: 484 }} className="addHeaderFieldsWrapper"
|
||||
buttons={[
|
||||
<Button type="primary" onClick={() => this.props.onAdd(itemsCheckeds)}>{getLabel(111, "添加")}</Button>,
|
||||
<Button type="ghost" onClick={this.props.onCancel}>{getLabel(111, "取消")}</Button>
|
||||
]}
|
||||
bottomLeft={<WeaCheckbox content={getLabel(111, "只显示已选中字段")}
|
||||
onChange={this.handleShowOnlyChecked}/>}
|
||||
>
|
||||
{
|
||||
_.map(dataSource, item => {
|
||||
const { salarySobItemGroupName, salaryItems, salarySobItemGroupId } = item;
|
||||
const value = _.every(salaryItems, it => !!it.checked) ? "1" : "0";
|
||||
return <WeaSearchGroup showGroup needTigger
|
||||
title={<WeaCheckbox content={salarySobItemGroupName} value={value}
|
||||
onChange={(val) => this.handleSelectGroupAll(salarySobItemGroupId, val)}/>}>
|
||||
<Row gutter={16}>
|
||||
{
|
||||
!_.isEmpty(salaryItems) ?
|
||||
_.map(salaryItems, it => {
|
||||
const { salaryItemId, salaryItemName, checked } = it;
|
||||
return <Col span={8} style={{ marginBottom: 16 }}>
|
||||
<WeaCheckbox content={salaryItemName} value={checked ? "1" : "0"}
|
||||
onChange={() => this.setState({ itemsCheckeds: _.xorWith(itemsCheckeds, [salaryItemId], _.isEqual) })}/>
|
||||
</Col>;
|
||||
}) : <Col span={24} style={{ minHeight: 20, padding: "5%", textAlign: "center" }}>暂无数据</Col>
|
||||
}
|
||||
</Row>
|
||||
</WeaSearchGroup>;
|
||||
})
|
||||
}
|
||||
</WeaDialog>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default AddHeaderFieldsModal;
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
.addHeaderFieldsWrapper {
|
||||
.wea-search-group {
|
||||
.wea-title {
|
||||
padding-left: 0 !important;
|
||||
}
|
||||
|
||||
.wea-content {
|
||||
padding: 8px 16px 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@ import React from "react";
|
|||
import { Button, Col, Row } from "antd";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import { WeaCheckbox, WeaDialog } from "ecCom";
|
||||
import { cacheImportField } from "../../../../apis/calculate";
|
||||
|
||||
@inject("calculateStore", "standingBookStore")
|
||||
@observer
|
||||
|
|
@ -14,7 +15,11 @@ export default class SelectFieldModal extends React.Component {
|
|||
}
|
||||
|
||||
componentWillMount() {
|
||||
const { calculateStore: { getImportField }, standingBookStore: { getWelfareList }, isStandingBook } = this.props;
|
||||
const {
|
||||
calculateStore: { getImportField },
|
||||
standingBookStore: { getWelfareList, getBalanceWelfareList },
|
||||
isStandingBook, standingBookType
|
||||
} = this.props;
|
||||
if (!isStandingBook) {
|
||||
getImportField(this.props.id).then(data => {
|
||||
let fieldData = {};
|
||||
|
|
@ -33,17 +38,30 @@ export default class SelectFieldModal extends React.Component {
|
|||
if (this.props.fieldData.inputItems) {
|
||||
sqlItems = this.props.fieldData.sqlItems;
|
||||
}
|
||||
fieldData.formulaItems = formulaItems;
|
||||
fieldData.inputItems = inputItems;
|
||||
fieldData.sqlItems = sqlItems;
|
||||
|
||||
this.setState({
|
||||
fieldData
|
||||
fieldData.formulaItems = _.map(formulaItems, item => {
|
||||
if (data.checkItems.includes(item.salaryItemId)) {
|
||||
return { ...item, checked: true };
|
||||
}
|
||||
return { ...item };
|
||||
});
|
||||
fieldData.inputItems = _.map(inputItems, item => {
|
||||
if (data.checkItems.includes(item.salaryItemId)) {
|
||||
return { ...item, checked: true };
|
||||
}
|
||||
return { ...item };
|
||||
});
|
||||
fieldData.sqlItems = _.map(sqlItems, item => {
|
||||
if (data.checkItems.includes(item.salaryItemId)) {
|
||||
return { ...item, checked: true };
|
||||
}
|
||||
return { ...item };
|
||||
});
|
||||
this.setState({ fieldData });
|
||||
this.fieldData = fieldData;
|
||||
});
|
||||
} else {
|
||||
getWelfareList().then(result => {
|
||||
const APIFox = standingBookType === "difference" ? getBalanceWelfareList : getWelfareList;
|
||||
APIFox().then(result => {
|
||||
let fieldData = {};
|
||||
let formulaItems = [];
|
||||
formulaItems = _.map(result, it => ({ ...it, salaryItemId: it.salaryItemName }));
|
||||
|
|
@ -90,10 +108,19 @@ export default class SelectFieldModal extends React.Component {
|
|||
}
|
||||
|
||||
// 添加按钮点击回调
|
||||
handleAddClick() {
|
||||
handleAddClick = async () => {
|
||||
//薪资核算详情页面的导入表单字段缓存功能
|
||||
if (window.location.hash.indexOf("calculateDetail") !== -1) {
|
||||
const { status } = await this.cacheImportField();
|
||||
}
|
||||
this.props.onAdd(this.fieldData);
|
||||
this.props.onCancel();
|
||||
}
|
||||
};
|
||||
cacheImportField = () => {
|
||||
const salaryItemList = _.reduce(_.keys(this.fieldData), (pre, cur) => ([...pre, ...this.fieldData[cur]]), []);
|
||||
const salaryItems = _.map(_.filter(salaryItemList, it => !!it.checked), item => item.salaryItemId);
|
||||
return cacheImportField({ salaryItems });
|
||||
};
|
||||
|
||||
// 标题checkbox点击
|
||||
handleTitleCheckboxChange(value, flag) {
|
||||
|
|
@ -146,22 +173,20 @@ export default class SelectFieldModal extends React.Component {
|
|||
const { isStandingBook } = this.props;
|
||||
return (
|
||||
<WeaDialog
|
||||
title='添加表头字段'
|
||||
title="添加表头字段"
|
||||
visible={this.props.visible}
|
||||
style={{width:800}}
|
||||
style={{ width: 800 }}
|
||||
onCancel={() => {
|
||||
this.props.onCancel();
|
||||
}}
|
||||
buttons={[
|
||||
<Button type="primary" onClick={() => {
|
||||
this.handleAddClick();
|
||||
}}>添加</Button>
|
||||
<Button type="primary" onClick={this.handleAddClick}>添加</Button>
|
||||
]}
|
||||
>
|
||||
<div style={{ minHeight: "20vh", maxHeight: "50vh", overflow: "hidden auto", padding: "16px 20px" }}>
|
||||
{
|
||||
!_.isEmpty(fieldData.formulaItems) &&
|
||||
<div >
|
||||
<div>
|
||||
<div style={{ height: "40px", lineHeight: "40px" }}>
|
||||
<WeaCheckbox content={!isStandingBook ? "公式项" : "全选"} onChange={(value) => {
|
||||
this.handleTitleCheckboxChange(value, "formula");
|
||||
|
|
|
|||
|
|
@ -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,15 +19,14 @@ export default class CompareDetail extends React.Component {
|
|||
onlyDiffEmployee: true,
|
||||
onlyDiffSalaryItem: true,
|
||||
importModalVisible: false,
|
||||
searchValue: ""
|
||||
searchValue: "",
|
||||
calculateAuth: false
|
||||
};
|
||||
this.pageInfo = { current: 1, pageSize: 10 };
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
let id = getQueryString("id");
|
||||
this.id = id;
|
||||
|
||||
this.id = getQueryString("id");
|
||||
const { calculateStore: { fetchComparisonResultList } } = this.props;
|
||||
const { onlyDiffEmployee, onlyDiffSalaryItem } = this.state;
|
||||
let params = {
|
||||
|
|
@ -35,27 +36,50 @@ export default class CompareDetail extends React.Component {
|
|||
current: 1
|
||||
};
|
||||
fetchComparisonResultList(params);
|
||||
this.salaryacctAcctresultCheckAuth({ salaryAcctRecordId: getQueryString("id") })
|
||||
}
|
||||
|
||||
getColumns(columns) {
|
||||
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 => {
|
||||
let n = Number(item.dataIndex);
|
||||
if (!isNaN(n)) { // 数字
|
||||
item.render = (text, record) => {
|
||||
const showDifference = record[`${item.dataIndex}_type`] === "number";
|
||||
const { acctResultValue, excelResultValue } = record[item.dataIndex];
|
||||
return (
|
||||
<div>
|
||||
<div>系统值:{record[item.dataIndex].acctResultValue}</div>
|
||||
<div>线下值:{record[item.dataIndex].excelResultValue}</div>
|
||||
<div
|
||||
style={{ color: "red" }}>差值:{calculateCompares(record[item.dataIndex].acctResultValue, record[item.dataIndex].excelResultValue)}</div>
|
||||
<div>系统值:{acctResultValue}</div>
|
||||
<div>线下值:{excelResultValue}</div>
|
||||
{
|
||||
showDifference &&
|
||||
<div style={{ color: "red" }}>
|
||||
差值:{calculateCompares(acctResultValue, excelResultValue)}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
} else {
|
||||
item.fixed = "left";
|
||||
}
|
||||
});
|
||||
return newColumns;
|
||||
}
|
||||
};
|
||||
|
||||
// 导入
|
||||
handleImportClick() {
|
||||
|
|
@ -163,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 (
|
||||
<div style={{ display: "inline-block" }}>
|
||||
|
|
@ -197,70 +221,70 @@ export default class CompareDetail extends React.Component {
|
|||
);
|
||||
};
|
||||
return (
|
||||
<div className="compareDetail">
|
||||
<CustomTab
|
||||
searchOperationItem={
|
||||
renderRightOperation()
|
||||
}
|
||||
leftOperation={
|
||||
renderLeftOperation()
|
||||
}
|
||||
/>
|
||||
<div className="titleBarWrapper">
|
||||
<div className="titleBar">
|
||||
<span className="leftTitle">公式=</span>
|
||||
<span className="rightTitle">系统值;线下值;<span style={{ color: "red" }}>差值</span></span>
|
||||
<Authority ecId={`${this && this.props && this.props.ecId || ""}_Authority@lulowc`}
|
||||
store={{ loading: false, hasRight: calculateAuth }}>
|
||||
<div className="compareDetail">
|
||||
<CustomTab
|
||||
searchOperationItem={
|
||||
renderRightOperation()
|
||||
}
|
||||
leftOperation={
|
||||
renderLeftOperation()
|
||||
}
|
||||
/>
|
||||
<div className="titleBarWrapper">
|
||||
<div className="titleBar">
|
||||
<span className="leftTitle">公式=</span>
|
||||
<span className="rightTitle">系统值;线下值;<span style={{ color: "red" }}>差值</span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="tableWrapper">
|
||||
<CustomPaginationTable
|
||||
loading={loading}
|
||||
dataSource={comparisonResultPageInfo.list ? comparisonResultPageInfo.list : []}
|
||||
columns={this.getColumns(comparisonResultColumns ? comparisonResultColumns : [])}
|
||||
scroll={{ x: this.getColumns(comparisonResultColumns ? comparisonResultColumns : []).length * 150, y: `calc(100vh - 199px)` }}
|
||||
total={comparisonResultPageInfo.total}
|
||||
current={comparisonResultPageInfo.pageNum}
|
||||
pageSize={this.pageInfo.pageSize}
|
||||
onPageChange={(value) => {
|
||||
this.pageInfo.current = value;
|
||||
this.handleDataPageChange(value);
|
||||
}}
|
||||
onShowSizeChange={(current, pageSize) => {
|
||||
this.pageInfo = { current, pageSize };
|
||||
this.handleShowSizeChange(this.pageInfo);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className="tableWrapper">
|
||||
<CustomPaginationTable
|
||||
loading={loading}
|
||||
dataSource={comparisonResultPageInfo.list ? comparisonResultPageInfo.list : []}
|
||||
columns={this.getColumns(comparisonResultColumns ? comparisonResultColumns : [])}
|
||||
scroll={{
|
||||
x: this.getColumns(comparisonResultColumns ? comparisonResultColumns : []).length * 150,
|
||||
y: `calc(100vh - 199px)`
|
||||
}}
|
||||
total={comparisonResultPageInfo.total}
|
||||
current={comparisonResultPageInfo.pageNum}
|
||||
pageSize={this.pageInfo.pageSize}
|
||||
onPageChange={(value) => {
|
||||
this.pageInfo.current = value;
|
||||
this.handleDataPageChange(value);
|
||||
}}
|
||||
onShowSizeChange={(current, pageSize) => {
|
||||
this.pageInfo = { current, pageSize };
|
||||
this.handleShowSizeChange(this.pageInfo);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{
|
||||
importModalVisible && <CompareDetailImportModal
|
||||
visiable={importModalVisible}
|
||||
id={this.id}
|
||||
onFinish={() => {
|
||||
this.handleComparisonFinish();
|
||||
}}
|
||||
onCancel={() => {
|
||||
this.setState({
|
||||
importModalVisible: false
|
||||
});
|
||||
}}
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
{
|
||||
importModalVisible && <CompareDetailImportModal
|
||||
visiable={importModalVisible}
|
||||
id={this.id}
|
||||
onFinish={() => {
|
||||
this.handleComparisonFinish();
|
||||
}}
|
||||
onCancel={() => {
|
||||
this.setState({
|
||||
importModalVisible: false
|
||||
});
|
||||
}}
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
</Authority>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// 计算差值
|
||||
export const calculateCompares=(systemValue, excelValue)=> {
|
||||
if (systemValue == null || excelValue == null) {
|
||||
return "";
|
||||
}
|
||||
let systemNum = Number(systemValue);
|
||||
let excelNum = Number(excelValue);
|
||||
if (!isNaN(systemNum) || !isNaN(excelNum)) { // 数字
|
||||
return (systemNum - excelNum).toFixed(2);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
export const calculateCompares = (systemValue = 0, excelValue = 0) => {
|
||||
const systemNum = Number(systemValue);
|
||||
const excelNum = Number(excelValue);
|
||||
return (systemNum - excelNum).toFixed(2);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,41 +1,55 @@
|
|||
import React from "react";
|
||||
import { WeaHelpfulTip, WeaInput } from "ecCom";
|
||||
import { Col, Row } from "antd";
|
||||
import { WeaHelpfulTip, WeaTab } from "ecCom";
|
||||
import IssuedAndReissueTable from "./issuedAndReissueTable";
|
||||
import PayrollItemsTable from "./payrollItemsTable";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import cs from "classnames";
|
||||
import { toJS } from "mobx";
|
||||
import "./index.less";
|
||||
|
||||
@inject("calculateStore")
|
||||
@observer
|
||||
export default class EditSalaryDetail extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
selectedKey: "0"
|
||||
};
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
const { calculateStore: { acctresultDetail } } = this.props;
|
||||
acctresultDetail(this.props.id);
|
||||
}
|
||||
|
||||
handleItemValueChange(field, value, isInput) {
|
||||
handleItemValueChange = (field, value, isInput, groupId) => {
|
||||
const { calculateStore: { acctresultDetailForm, setAcctresultDetailForm } } = this.props;
|
||||
let form = { ...acctresultDetailForm };
|
||||
if (isInput) {
|
||||
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;
|
||||
return { ...item };
|
||||
});
|
||||
} else {
|
||||
form.formulaItems = acctresultDetailForm.formulaItems.map(item => {
|
||||
} else if (isInput === "issuedAndReissueItems") {
|
||||
form.issuedAndReissueItems = acctresultDetailForm.issuedAndReissueItems.map(item => {
|
||||
item = { ...item };
|
||||
if (item.salaryItemName == field) {
|
||||
if (item.salaryItemName === field) {
|
||||
item.resultValue = value;
|
||||
}
|
||||
return item;
|
||||
});
|
||||
}
|
||||
setAcctresultDetailForm(form);
|
||||
}
|
||||
|
||||
};
|
||||
renderTableTr = (data, isInput) => {
|
||||
const tables = [];
|
||||
const len = data.length;
|
||||
|
|
@ -59,22 +73,27 @@ 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: "正常工资薪金所得",
|
||||
viewcondition: "0"
|
||||
},
|
||||
{
|
||||
title: "已发补发",
|
||||
viewcondition: "1"
|
||||
}
|
||||
];
|
||||
return (
|
||||
<div className="editSalaryDetail">
|
||||
<div className="detailItemWrapper">
|
||||
<div>
|
||||
<span className="itemTitle">基本信息</span>
|
||||
<WeaHelpfulTip
|
||||
style={{ marginLeft: "10px" }}
|
||||
width={200}
|
||||
title="根据账套设置显示"
|
||||
placement="topLeft"
|
||||
/>
|
||||
<WeaHelpfulTip style={{ marginLeft: "10px" }} title="提示:基本信息根据账套设置显示" placement="topLeft"/>
|
||||
</div>
|
||||
|
||||
<div className="itemContent">
|
||||
{
|
||||
!_.isEmpty(acctresultDetailForm.employeeInfos) &&
|
||||
|
|
@ -84,73 +103,27 @@ export default class EditSalaryDetail extends React.Component {
|
|||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div className="detailItemWrapper">
|
||||
<span className="itemTitle">输入项</span>
|
||||
<div className="itemContent">
|
||||
<Row>
|
||||
{
|
||||
acctresultDetailForm.inputItems && acctresultDetailForm.inputItems.map((item, index) => {
|
||||
const len = acctresultDetailForm.inputItems.length;
|
||||
return (
|
||||
<Col span={8}>
|
||||
<Row>
|
||||
<Col span={12}
|
||||
className={cs("itemLabel", { "borderB-none": Math.ceil((index + 1) / 3) === len / 3 })}>{item.salaryItemName}</Col>
|
||||
<Col span={12} className={cs("itemValue", {
|
||||
"borderB-none": Math.ceil((index + 1) / 3) === len / 3,
|
||||
"borderR-none": (index + 1) % 3 === 0
|
||||
})}><WeaInput value={item.resultValue} disabled={!item.canEdit} onChange={(value) => {
|
||||
this.handleItemValueChange(item.salaryItemName, value, true);
|
||||
}}/></Col>
|
||||
</Row>
|
||||
</Col>
|
||||
);
|
||||
})
|
||||
}
|
||||
</Row>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div>
|
||||
<div className="detailItemWrapper">
|
||||
<span className="itemTitle">
|
||||
<span>公式项</span>
|
||||
<WeaHelpfulTip
|
||||
style={{ marginLeft: "10px" }}
|
||||
width={200}
|
||||
title="提示:修改后,若点击核算,将按照公式核算,覆盖修改的数据"
|
||||
placement="topLeft"
|
||||
/>
|
||||
</span>
|
||||
<div className="itemContent">
|
||||
<Row>
|
||||
{
|
||||
acctresultDetailForm.formulaItems && acctresultDetailForm.formulaItems.map((item, index) => {
|
||||
const len = acctresultDetailForm.formulaItems.length;
|
||||
return (
|
||||
<Col span={8}>
|
||||
<Row>
|
||||
<Col span={12}
|
||||
className={cs("itemLabel", { "borderB-none": Math.ceil((index + 1) / 3) === len / 3 })}>{item.salaryItemName}</Col>
|
||||
<Col span={12} className={cs("itemValue", {
|
||||
"borderB-none": Math.ceil((index + 1) / 3) === len / 3,
|
||||
"borderR-none": (index + 1) % 3 === 0
|
||||
})}><WeaInput value={item.resultValue} disabled={!item.canEdit} onChange={(value) => {
|
||||
this.handleItemValueChange(item.salaryItemName, value, false);
|
||||
}}/></Col>
|
||||
</Row>
|
||||
</Col>
|
||||
);
|
||||
})
|
||||
}
|
||||
</Row>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{
|
||||
!_.isEmpty(toJS(acctresultDetailForm.issuedAndReissueItems)) &&
|
||||
<WeaTab
|
||||
datas={topTab}
|
||||
keyParam="viewcondition"
|
||||
selectedKey={selectedKey}
|
||||
onChange={v => this.setState({ selectedKey: v })}
|
||||
/>
|
||||
}
|
||||
{
|
||||
selectedKey === "0" && _.map(itemsByGroup, item => {
|
||||
return <PayrollItemsTable {...item} onChangeIssueReissueValue={this.handleItemValueChange}/>;
|
||||
})
|
||||
}
|
||||
{
|
||||
selectedKey === "1" &&
|
||||
<IssuedAndReissueTable
|
||||
dataSource={toJS(acctresultDetailForm.issuedAndReissueItems)}
|
||||
onChangeIssueReissueValue={this.handleItemValueChange}
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,13 +4,16 @@ import { inject, observer } from "mobx-react";
|
|||
import SalaryDetail from "./salaryDetail";
|
||||
import { Button, Dropdown, Menu, message, Modal } from "antd";
|
||||
import { WeaBrowser, WeaCheckbox, WeaDropdown, WeaFormItem, WeaInput, WeaSearchGroup, WeaSelect, WeaTab } from "ecCom";
|
||||
import { getQueryString } from "../../util/url";
|
||||
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 (
|
||||
<WeaFormItem
|
||||
label={value}
|
||||
labelCol={{ span: 6 }}
|
||||
wrapperCol={{ span: 18 }}
|
||||
>
|
||||
<WeaInput value={employeeName} onChange={(val) => this.setState({
|
||||
searchItemsValue: {
|
||||
...this.state.searchItemsValue,
|
||||
[key]: val
|
||||
}
|
||||
})}/>
|
||||
<WeaInput value={key === "employeeName" ? employeeName : workcode}
|
||||
onChange={(val) => this.setState({
|
||||
searchItemsValue: {
|
||||
...this.state.searchItemsValue,
|
||||
[key]: val
|
||||
}
|
||||
})}/>
|
||||
</WeaFormItem>
|
||||
);
|
||||
};
|
||||
|
|
@ -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 (
|
||||
<WeaFormItem
|
||||
label={value}
|
||||
|
|
@ -101,10 +123,13 @@ export default class CalculateDetail extends React.Component {
|
|||
wrapperCol={{ span: 18 }}
|
||||
>
|
||||
<WeaSelect
|
||||
value={status}
|
||||
multiple
|
||||
value={statuses}
|
||||
options={[
|
||||
{ key: "", showname: "" }, { key: "ALL", showname: "全部" },
|
||||
{ key: "NORMAL", showname: "在职" }, { key: "UNAVAILABLE", showname: "离职" }
|
||||
{ key: "0", showname: "试用" }, { key: "1", showname: "正式" },
|
||||
{ key: "2", showname: "临时" }, { key: "3", showname: "试用延期" },
|
||||
{ key: "4", showname: "解雇" }, { key: "5", showname: "离职" },
|
||||
{ key: "6", showname: "退休" }
|
||||
]}
|
||||
onChange={(val) => this.setState({ searchItemsValue: { ...this.state.searchItemsValue, [key]: val } })}/>
|
||||
</WeaFormItem>
|
||||
|
|
@ -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 });
|
||||
|
|
@ -172,7 +198,7 @@ export default class CalculateDetail extends React.Component {
|
|||
url: "/api/bs/hrmsalary/salaryacct/acctresult/list",
|
||||
selectedRowKeys: [],
|
||||
queryParams: {
|
||||
salaryAcctRecordId,
|
||||
salaryAcctRecordId
|
||||
}
|
||||
};
|
||||
childFrameObj.contentWindow.postMessage(JSON.stringify(payload), "*");
|
||||
|
|
@ -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="
|
||||
`/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 = (
|
||||
<Menu onClick={this.handleMenuClick.bind(this)}>
|
||||
<Menu.Item key="1">导入</Menu.Item>
|
||||
|
|
@ -257,7 +295,8 @@ export default class CalculateDetail extends React.Component {
|
|||
);
|
||||
|
||||
const renderRightOperation = () => {
|
||||
return [
|
||||
const { accountExceptInfo } = this.state;
|
||||
let buttons = [
|
||||
<ButtonSelect
|
||||
datas={[
|
||||
{ key: "ALL", show: "核算所有人", selected: true },
|
||||
|
|
@ -270,6 +309,10 @@ export default class CalculateDetail extends React.Component {
|
|||
更多
|
||||
</Dropdown.Button>
|
||||
];
|
||||
accountExceptInfo && buttons.unshift(<Button type="ghost" shape="circle-outline" icon="download"
|
||||
title="下载核算异常信息"
|
||||
onClick={() => this.downloadTxtfile(accountExceptInfo)}/>);
|
||||
return buttons;
|
||||
};
|
||||
|
||||
const topTab = [
|
||||
|
|
@ -295,9 +338,10 @@ export default class CalculateDetail extends React.Component {
|
|||
<Button type="ghost" onClick={() => this.setState({
|
||||
searchItemsValue: {
|
||||
employeeName: "",
|
||||
workcode: "",
|
||||
departmentIds: "",
|
||||
positionIds: "",
|
||||
status: "",
|
||||
statuses: "",
|
||||
consolidatedTaxation: "0"
|
||||
}
|
||||
})}>
|
||||
|
|
@ -311,66 +355,70 @@ export default class CalculateDetail extends React.Component {
|
|||
const renderSearch = () => {
|
||||
const searchItems = [
|
||||
{ com: this.Input("姓名", "employeeName") },
|
||||
{ com: this.Input("工号", "workcode") },
|
||||
{ com: this.Browser("分部", "subcompanyIds") },
|
||||
{ com: this.Browser("部门", "departmentIds") },
|
||||
{ com: this.Browser("岗位", "positionIds") },
|
||||
{ com: this.Select("状态", "status") },
|
||||
{ com: this.Select("状态", "statuses") },
|
||||
{ com: this.Checkbox("合并计税", "consolidatedTaxation") }
|
||||
];
|
||||
return <WeaSearchGroup title={"基本信息"} items={searchItems} showGroup/>;
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={{ overflowY: "hidden", height: "100%" }}>
|
||||
<WeaTab
|
||||
datas={topTab}
|
||||
selectedKey={selectedKey}
|
||||
keyParam="viewcondition"
|
||||
onChange={v => this.setState({ selectedKey: v })}
|
||||
searchType={selectedKey == 1 ? ["base", "advanced"] : []} // base:基础搜索框 advanced:显示高级搜索按钮
|
||||
showSearchAd={showSearchAd} // 是否展开高级搜索面板
|
||||
setShowSearchAd={(bool) => this.setState({ showSearchAd: bool })} //高级搜索面板受控
|
||||
searchsAd={renderSearch()} // 高级搜索内部数据getSearchs(form, toJS(condition), 2)
|
||||
buttonsAd={adBtn} // 高级搜索内部按钮
|
||||
onSearch={() => this.handleSearch(this.state.searchItemsValue)} // 点搜索按钮时的回调
|
||||
buttons={selectedKey == 1 ? renderRightOperation() : []}
|
||||
searchsBasePlaceHolder={"请输入姓名"}
|
||||
onSearchChange={(v) =>
|
||||
this.setState({
|
||||
searchItemsValue: {
|
||||
...this.state.searchItemsValue,
|
||||
employeeName: v
|
||||
}
|
||||
})
|
||||
} // 在搜索框中输入的文字改变时的回调: 这里需要同步高级搜索和外部搜索框的值form.updateFields({ username: v })
|
||||
searchsBaseValue={this.state.searchItemsValue.employeeName} // 外部input搜索值受控: 这里和高级搜索的requestname同步form.getFormParams().username
|
||||
/>
|
||||
{selectedKey == 0 && <UserSure/>}
|
||||
{selectedKey == 1 && <SalaryDetail onChangeAccountIds={(ids) => this.setState({ accountIds: ids })}
|
||||
employeeName={this.state.searchValue}/>}
|
||||
{acctResultImportVisiable &&
|
||||
<AcctResultImportModal
|
||||
visiable={acctResultImportVisiable}
|
||||
fieldData={this.state.fieldData}
|
||||
onAdd={fieldData => {
|
||||
this.handleAcctModalAdd(fieldData);
|
||||
}}
|
||||
onCancel={() =>
|
||||
<Authority ecId={`${this && this.props && this.props.ecId || ""}_Authority@lulowc`}
|
||||
store={{ loading: false, hasRight: payrollPermission && calculateAuth }}>
|
||||
<div style={{ overflowY: "hidden", height: "100%" }}>
|
||||
<WeaTab
|
||||
datas={topTab}
|
||||
selectedKey={selectedKey}
|
||||
keyParam="viewcondition"
|
||||
onChange={v => this.setState({ selectedKey: v })}
|
||||
searchType={selectedKey == 1 ? ["base", "advanced"] : []} // base:基础搜索框 advanced:显示高级搜索按钮
|
||||
showSearchAd={showSearchAd} // 是否展开高级搜索面板
|
||||
setShowSearchAd={(bool) => this.setState({ showSearchAd: bool })} //高级搜索面板受控
|
||||
searchsAd={renderSearch()} // 高级搜索内部数据getSearchs(form, toJS(condition), 2)
|
||||
buttonsAd={adBtn} // 高级搜索内部按钮
|
||||
onSearch={() => this.handleSearch(this.state.searchItemsValue)} // 点搜索按钮时的回调
|
||||
buttons={selectedKey == 1 ? renderRightOperation() : []}
|
||||
searchsBasePlaceHolder={"请输入姓名"}
|
||||
onSearchChange={(v) =>
|
||||
this.setState({
|
||||
acctResultImportVisiable: false,
|
||||
fieldData: {}
|
||||
})}
|
||||
id={this.id}
|
||||
/>}
|
||||
{this.state.progressVisible &&
|
||||
<ProgressModal
|
||||
visible={this.state.progressVisible}
|
||||
onCancel={() => {
|
||||
this.setState({ progressVisible: false, progress: 0 });
|
||||
}}
|
||||
progress={this.state.progress}
|
||||
/>}
|
||||
</div>
|
||||
searchItemsValue: {
|
||||
...this.state.searchItemsValue,
|
||||
employeeName: v
|
||||
}
|
||||
})
|
||||
} // 在搜索框中输入的文字改变时的回调: 这里需要同步高级搜索和外部搜索框的值form.updateFields({ username: v })
|
||||
searchsBaseValue={this.state.searchItemsValue.employeeName} // 外部input搜索值受控: 这里和高级搜索的requestname同步form.getFormParams().username
|
||||
/>
|
||||
{selectedKey == 0 && <UserSure/>}
|
||||
{selectedKey == 1 && <SalaryDetail onChangeAccountIds={(ids) => this.setState({ accountIds: ids })}
|
||||
employeeName={this.state.searchItemsValue}/>}
|
||||
{acctResultImportVisiable &&
|
||||
<AcctResultImportModal
|
||||
visiable={acctResultImportVisiable}
|
||||
fieldData={this.state.fieldData}
|
||||
onAdd={fieldData => {
|
||||
this.handleAcctModalAdd(fieldData);
|
||||
}}
|
||||
onCancel={() =>
|
||||
this.setState({
|
||||
acctResultImportVisiable: false,
|
||||
fieldData: {}
|
||||
})}
|
||||
id={this.id}
|
||||
/>}
|
||||
{this.state.progressVisible &&
|
||||
<ProgressModal
|
||||
visible={this.state.progressVisible}
|
||||
onCancel={() => {
|
||||
this.setState({ progressVisible: false, progress: 0 });
|
||||
}}
|
||||
progress={this.state.progress}
|
||||
/>}
|
||||
</div>
|
||||
</Authority>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -80,8 +80,7 @@
|
|||
}
|
||||
|
||||
.editSalaryDetail {
|
||||
padding: 20px;
|
||||
padding-bottom: 40px;
|
||||
padding: 20px 20px 40px;
|
||||
|
||||
.detailItemWrapper {
|
||||
.itemTitle {
|
||||
|
|
@ -127,43 +126,15 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
& > .ant-row {
|
||||
border: 1px solid rgba(0, 0, 0, .06);
|
||||
}
|
||||
|
||||
.itemLabel {
|
||||
background-color: #fafafa;
|
||||
padding: 12px 6px;
|
||||
height: 45px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
border-right: 1px solid rgba(0, 0, 0, .06);
|
||||
border-bottom: 1px solid rgba(0, 0, 0, .06);
|
||||
}
|
||||
|
||||
.borderB-none {
|
||||
border-bottom: none !important;
|
||||
}
|
||||
|
||||
.borderR-none {
|
||||
border-right: none !important;
|
||||
}
|
||||
|
||||
.itemValue {
|
||||
padding: 12px 6px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 45px;
|
||||
border-right: 1px solid rgba(0, 0, 0, .06);
|
||||
border-bottom: 1px solid rgba(0, 0, 0, .06);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.itemRow {
|
||||
line-height: 40px;
|
||||
.wea-search-group {
|
||||
padding: 0 !important;
|
||||
|
||||
.wea-title {
|
||||
padding: 0 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -178,7 +149,9 @@
|
|||
}
|
||||
|
||||
.tableWrapper {
|
||||
margin-top: 10px;
|
||||
padding: 10px;
|
||||
height: calc(100vh - 121px);
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -252,7 +225,6 @@
|
|||
z-index: 99;
|
||||
top: 10px !important;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@media (min-width: 1260px) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Author: 黎永顺
|
||||
* name: 已发补发列表
|
||||
* Description:
|
||||
* Date: 2022/12/14
|
||||
*/
|
||||
import React, { Component } from "react";
|
||||
import { WeaHelpfulTip, WeaInputNumber, WeaTable } from "ecCom";
|
||||
|
||||
class IssuedAndReissueTable extends Component {
|
||||
render() {
|
||||
const { dataSource, onChangeIssueReissueValue } = this.props;
|
||||
const columns = [
|
||||
{
|
||||
dataIndex: "salaryItemName",
|
||||
title: "薪资项目",
|
||||
render: (text) => {
|
||||
return <span className="tdEllipsis" title={text}>{text}</span>;
|
||||
}
|
||||
},
|
||||
{
|
||||
dataIndex: "resultValue",
|
||||
title: <span>
|
||||
<span style={{ marginRight: 8 }}>项目值</span>
|
||||
<WeaHelpfulTip
|
||||
title="若薪资项目有公式,手动编辑项目值后,需点击锁定图标输入值才生效;点击锁定图标,解锁手动编辑的项目值,公式生效,点击保存按照公式重新核算;重新核算后,不显示解锁图标。"
|
||||
placement="bottom"
|
||||
width={200}
|
||||
/>
|
||||
</span>,
|
||||
render: (text, record) => {
|
||||
const { canEdit } = record;
|
||||
return <WeaInputNumber
|
||||
disabled={!canEdit}
|
||||
min={0}
|
||||
precision={2}
|
||||
value={text || 0}
|
||||
onChange={(value) => onChangeIssueReissueValue(record.salaryItemName, value, "issuedAndReissueItems")}
|
||||
/>;
|
||||
}
|
||||
},
|
||||
{
|
||||
dataIndex: "itemFormulaContent",
|
||||
title: <span>
|
||||
<span style={{ marginRight: 8 }}>核算公式</span>
|
||||
<WeaHelpfulTip
|
||||
title="若薪资项目有公式,且项目值手动编辑修改过并点击锁定图标,则公式失效;若解除锁定,则项目公式重新生效;"
|
||||
placement="bottom"
|
||||
width={200}
|
||||
/>
|
||||
</span>,
|
||||
render: (text, record) => {
|
||||
return <span className="tdEllipsis" title={text}>{_.isNil(text) ? "输入" : text}</span>;
|
||||
}
|
||||
}
|
||||
];
|
||||
return (
|
||||
<WeaTable
|
||||
rowKey="id"
|
||||
dataSource={dataSource}
|
||||
columns={columns}
|
||||
pagination={false}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default IssuedAndReissueTable;
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* Author: 黎永顺
|
||||
* name: 薪资项目表格
|
||||
* Description:
|
||||
* Date: 2023/5/16
|
||||
*/
|
||||
import React, { Component } from "react";
|
||||
import { WeaHelpfulTip, WeaInput, WeaInputNumber, WeaLocaleProvider, WeaSearchGroup, WeaTable } from "ecCom";
|
||||
|
||||
const { getLabel } = WeaLocaleProvider;
|
||||
|
||||
class PayrollItemsTable extends Component {
|
||||
render() {
|
||||
const {
|
||||
salarySobItemGroupId,
|
||||
salarySobItemGroupName,
|
||||
salaryItems: dataSource,
|
||||
onChangeIssueReissueValue
|
||||
} = this.props;
|
||||
const columns = [
|
||||
{
|
||||
dataIndex: "salaryItemName",
|
||||
title: getLabel(111, "薪资项目"),
|
||||
width: "15%",
|
||||
render: (text) => {
|
||||
return <span className="tdEllipsis" title={text}>{text}</span>;
|
||||
}
|
||||
},
|
||||
{
|
||||
dataIndex: "resultValue",
|
||||
title: <span>
|
||||
<span style={{ marginRight: 8 }}>{getLabel(111, "项目值")}</span>
|
||||
<WeaHelpfulTip
|
||||
title={getLabel(111, "1.若薪资项目有公式,手动编辑项目值后,则默认将手动编辑的项目值锁定;点击锁定图标,解锁手动编辑的项目值,公式生效,点击保存按照公式重新核算;重新核算后,不显示解锁图标。")}
|
||||
placement="top" width={250}
|
||||
/>
|
||||
</span>,
|
||||
width: "20%",
|
||||
render: (text, record) => {
|
||||
const { canEdit, dataType } = record;
|
||||
return dataType === "number" ? <WeaInputNumber
|
||||
disabled={!canEdit}
|
||||
precision={2}
|
||||
value={text || 0}
|
||||
onChange={(value) => onChangeIssueReissueValue(record.salaryItemId, value, "itemsByGroup", salarySobItemGroupId)}
|
||||
/> : <WeaInput
|
||||
disabled={!canEdit}
|
||||
value={text}
|
||||
onChange={(value) => onChangeIssueReissueValue(record.salaryItemId, value, "itemsByGroup", salarySobItemGroupId)}
|
||||
/>;
|
||||
}
|
||||
},
|
||||
{
|
||||
dataIndex: "itemFormulaContent",
|
||||
title: <span>
|
||||
<span style={{ marginRight: 8 }}>{getLabel(111, "核算公式")}</span>
|
||||
<WeaHelpfulTip
|
||||
title={getLabel(111, "若薪资项目有公式,且项目值手动编辑修改过并点击锁定图标,则公式失效;若解除锁定,则项目公式重新生效;")}
|
||||
placement="top" width={250}
|
||||
/>
|
||||
</span>,
|
||||
width: "65%",
|
||||
render: (text, record) => {
|
||||
return <span className="tdEllipsis" title={text}>{_.isNil(text) ? "输入" : text}</span>;
|
||||
}
|
||||
}
|
||||
];
|
||||
return (
|
||||
<WeaSearchGroup title={salarySobItemGroupName} showGroup needTigger>
|
||||
<WeaTable
|
||||
rowKey="salaryItemId"
|
||||
dataSource={dataSource}
|
||||
columns={columns}
|
||||
bordered
|
||||
pagination={false}
|
||||
/>
|
||||
</WeaSearchGroup>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default PayrollItemsTable;
|
||||
|
|
@ -1,144 +1,119 @@
|
|||
import React from "react";
|
||||
import { toJS } from "mobx";
|
||||
import CustomTab from "../../components/customTab";
|
||||
import { Dropdown, Menu, message } from "antd";
|
||||
import { WeaHelpfulTip, WeaInputSearch, WeaSlideModal } from "ecCom";
|
||||
import { placeOnFileColumns } from "./columns";
|
||||
import SlideModalTitle from "../../components/slideModalTitle";
|
||||
import FileMergeDetail from "./fileMergeDetail";
|
||||
import { getQueryString } from "../../util/url";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import CustomPaginationTable from "../../components/customPaginationTable";
|
||||
import { renderLoading } from "../../util";
|
||||
import "./index.less";
|
||||
|
||||
@inject("calculateStore")
|
||||
@observer
|
||||
export default class PlaceOnFileDetail extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
placeOnFileColumns.map(item => {
|
||||
if (item.dataIndex == "username") {
|
||||
item.render = (text, record) => (
|
||||
<a onClick={() => {
|
||||
this.onDetail();
|
||||
}}>{text}</a>
|
||||
);
|
||||
}
|
||||
});
|
||||
this.state = {
|
||||
slideVisiable: false,
|
||||
selectedRowKeys: [],
|
||||
searchValue: ""
|
||||
searchValue: "",
|
||||
columnIndex: ""
|
||||
};
|
||||
this.id = "";
|
||||
this.length = 0;
|
||||
this.pageInfo = {
|
||||
current: 1,
|
||||
pageSize: 10
|
||||
};
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
let id = getQueryString("id");
|
||||
this.id = id;
|
||||
const { calculateStore: { getSalarySobCycle, acctResultList } } = this.props;
|
||||
getSalarySobCycle(id);
|
||||
acctResultList({ salaryAcctRecordId: id });
|
||||
this.id = getQueryString("id");
|
||||
const { calculateStore: { getSalarySobCycle } } = this.props;
|
||||
getSalarySobCycle(this.id);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
window.addEventListener("message", this.handleClick, false);
|
||||
}
|
||||
|
||||
// 获取列表的列
|
||||
getColumns() {
|
||||
const { calculateStore: { acctResultListTableStore, acctResultListColumns } } = this.props;
|
||||
let columns = acctResultListColumns ? acctResultListColumns : [];
|
||||
columns = columns.filter(item => item.hide == "FALSE").map(item => {
|
||||
let result = { ...item };
|
||||
result.title = item.text;
|
||||
result.dataIndex = item.column;
|
||||
result.oldWidth = result.width;
|
||||
result.width = null;
|
||||
this.length = 0;
|
||||
if (result.children) {
|
||||
result.children.map(child => {
|
||||
child.width = 150;
|
||||
child.title = child.text;
|
||||
child.dataIndex = child.column;
|
||||
this.length++;
|
||||
});
|
||||
} else {
|
||||
this.length++;
|
||||
result.width = 150;
|
||||
componentWillUnmount() {
|
||||
window.removeEventListener("message", this.handleClick, false);
|
||||
}
|
||||
|
||||
handleClick = ({ data }) => {
|
||||
const childFrameObj = document.getElementById("atdTable");
|
||||
const salaryAcctRecordId = getQueryString("id");
|
||||
const { type, data: { id, data: record, extraId = "" } = {} } = data;
|
||||
if (type === "PR") {
|
||||
if (id === "BATCHDELETE") {
|
||||
this.setState({ selectedRowKeys: record });
|
||||
} else if (id === "PAGEINFO") {
|
||||
const { pageNum: current, size: pageSize } = record;
|
||||
this.pageInfo = { current, pageSize };
|
||||
const payload = {
|
||||
type: "PR",
|
||||
listType: "",
|
||||
hasOperate: false,
|
||||
url: "/api/bs/hrmsalary/salaryacct/acctresult/list",
|
||||
queryParams: {
|
||||
salaryAcctRecordId,
|
||||
employeeName: this.state.searchValue,
|
||||
current, pageSize
|
||||
}
|
||||
};
|
||||
childFrameObj.contentWindow.postMessage(JSON.stringify(payload), "*");
|
||||
} else if (id === "COLUMNINDEX") {
|
||||
if (!extraId) {
|
||||
this.setState({ columnIndex: record });
|
||||
}
|
||||
}
|
||||
return result;
|
||||
});
|
||||
columns.push({
|
||||
title: "操作",
|
||||
key: "cz",
|
||||
render: (text, record) => {
|
||||
return <a onClick={() => {
|
||||
this.handleEdit(record);
|
||||
}}>编辑</a>;
|
||||
} else {
|
||||
const payload = {
|
||||
type: "PR",
|
||||
listType: "",
|
||||
hasOperate: false,
|
||||
url: "/api/bs/hrmsalary/salaryacct/acctresult/list",
|
||||
queryParams: {
|
||||
salaryAcctRecordId,
|
||||
employeeName: this.state.searchValue
|
||||
}
|
||||
};
|
||||
type && childFrameObj.contentWindow.postMessage(JSON.stringify(payload), "*");
|
||||
}
|
||||
};
|
||||
|
||||
handleSearch = (employeeName) => {
|
||||
const childFrameObj = document.getElementById("atdTable");
|
||||
const salaryAcctRecordId = getQueryString("id");
|
||||
const payload = {
|
||||
type: "PR",
|
||||
listType: "",
|
||||
hasOperate: false,
|
||||
url: "/api/bs/hrmsalary/salaryacct/acctresult/list",
|
||||
queryParams: {
|
||||
salaryAcctRecordId,
|
||||
employeeName
|
||||
}
|
||||
});
|
||||
return columns;
|
||||
}
|
||||
|
||||
onDetail() {
|
||||
this.setState({ slideVisiable: true });
|
||||
}
|
||||
|
||||
handleSearch(employeeName) {
|
||||
const { calculateStore: { acctResultList } } = this.props;
|
||||
acctResultList({ salaryAcctRecordId: this.id, employeeName, ...this.pageInfo, current: 1 });
|
||||
}
|
||||
|
||||
// 分页
|
||||
handleDataPageChange(current) {
|
||||
const { calculateStore: { acctResultList } } = this.props;
|
||||
acctResultList({ salaryAcctRecordId: this.id, employeeName: this.state.searchValue, ...this.pageInfo, current });
|
||||
}
|
||||
|
||||
handleShowSizeChange(pageInfo) {
|
||||
const { calculateStore: { acctResultList } } = this.props;
|
||||
acctResultList({
|
||||
salaryAcctRecordId: this.id,
|
||||
employeeName: this.state.searchValue, ...this.pageInfo, ...pageInfo
|
||||
});
|
||||
}
|
||||
};
|
||||
childFrameObj.contentWindow.postMessage(JSON.stringify(payload), "*");
|
||||
};
|
||||
|
||||
handleMenuClick() {
|
||||
const { calculateStore: { exportAll } } = this.props;
|
||||
const { selectedRowKeys } = this.state;
|
||||
if (selectedRowKeys.length == 0) {
|
||||
if (selectedRowKeys.length === 0) {
|
||||
message.warning("未选择条目");
|
||||
return;
|
||||
}
|
||||
exportAll(this.id, selectedRowKeys.join(","));
|
||||
}
|
||||
|
||||
handleExportAll() {
|
||||
handleExportAll = () => {
|
||||
const { calculateStore: { exportAll } } = this.props;
|
||||
exportAll(this.id);
|
||||
}
|
||||
|
||||
onSelectChange = selectedRowKeys => {
|
||||
this.setState({ selectedRowKeys });
|
||||
};
|
||||
|
||||
|
||||
render() {
|
||||
|
||||
const { calculateStore } = this.props;
|
||||
const {
|
||||
baseSalarySobCycle,
|
||||
acctResultListDateSource,
|
||||
acctResultListPageInfo
|
||||
} = calculateStore;
|
||||
const { selectedRowKeys, slideVisiable } = this.state;
|
||||
|
||||
const rowSelection = {
|
||||
selectedRowKeys,
|
||||
onChange: this.onSelectChange
|
||||
};
|
||||
const { baseSalarySobCycle, columnDescList } = calculateStore;
|
||||
const { slideVisiable, columnIndex } = this.state;
|
||||
|
||||
const menu = (
|
||||
<Menu onClick={(e) => this.handleMenuClick(e)}>
|
||||
|
|
@ -161,9 +136,6 @@ export default class PlaceOnFileDetail extends React.Component {
|
|||
);
|
||||
};
|
||||
|
||||
if (this.getColumns().length === 1) { // 无权限处理
|
||||
return renderLoading();
|
||||
}
|
||||
return (
|
||||
|
||||
<div className="placeOnFileDetail">
|
||||
|
|
@ -172,7 +144,7 @@ export default class PlaceOnFileDetail extends React.Component {
|
|||
renderRightOperation()
|
||||
}
|
||||
/>
|
||||
<div className="tabWrapper">
|
||||
<div className="tabWrapper" style={{ borderBottom: "none" }}>
|
||||
<span>薪资所属月:{baseSalarySobCycle.salaryMonth}</span>
|
||||
<WeaHelpfulTip
|
||||
width={100}
|
||||
|
|
@ -187,43 +159,37 @@ export default class PlaceOnFileDetail extends React.Component {
|
|||
placement="topLeft"
|
||||
/>
|
||||
</div>
|
||||
<div className="tabWrapper">
|
||||
<span>公式=</span>
|
||||
<span>{toJS(columnDescList)[columnIndex] && toJS(columnDescList)[columnIndex].formulaContent}</span>
|
||||
</div>
|
||||
<div className="tableWrapper">
|
||||
<CustomPaginationTable
|
||||
columns={this.getColumns()}
|
||||
scroll={{ x: this.length * 150 }}
|
||||
dataSource={acctResultListDateSource}
|
||||
rowSelection={rowSelection}
|
||||
total={acctResultListPageInfo.total}
|
||||
current={acctResultListPageInfo.pageNum}
|
||||
pageSize={this.pageInfo.pageSize}
|
||||
onPageChange={(value) => {
|
||||
this.pageInfo.current = value;
|
||||
this.handleDataPageChange(value);
|
||||
}}
|
||||
onShowSizeChange={(current, pageSize) => {
|
||||
this.pageInfo = { current, pageSize };
|
||||
this.handleShowSizeChange(this.pageInfo);
|
||||
}}
|
||||
<iframe
|
||||
style={{ border: 0, width: "100%", height: "100%" }}
|
||||
// src="http://localhost:7607/#/atdTable"
|
||||
src="/spa/hrmSalary/hrmSalaryCalculateDetail/index.html#/atdTable"
|
||||
id="atdTable"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{
|
||||
slideVisiable && <WeaSlideModal visible={slideVisiable}
|
||||
top={0}
|
||||
width={40}
|
||||
height={100}
|
||||
direction={"right"}
|
||||
measure={"%"}
|
||||
title={
|
||||
<SlideModalTitle
|
||||
subtitle={"合并计税详情"}
|
||||
editable={true}
|
||||
/>
|
||||
}
|
||||
content={(<FileMergeDetail/>)}
|
||||
onClose={() => this.setState({ slideVisiable: false })}
|
||||
showMask={true}
|
||||
closeMaskOnClick={() => this.setState({ slideVisiable: false })}/>
|
||||
slideVisiable &&
|
||||
<WeaSlideModal
|
||||
visible={slideVisiable}
|
||||
top={0}
|
||||
width={40}
|
||||
height={100}
|
||||
direction={"right"}
|
||||
measure={"%"}
|
||||
title={
|
||||
<SlideModalTitle
|
||||
subtitle={"合并计税详情"}
|
||||
editable={true}
|
||||
/>
|
||||
}
|
||||
content={(<FileMergeDetail/>)}
|
||||
onClose={() => this.setState({ slideVisiable: false })}
|
||||
showMask={true}
|
||||
closeMaskOnClick={() => this.setState({ slideVisiable: false })}/>
|
||||
}
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ export default class SalaryDetail extends React.Component {
|
|||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
loading: false,
|
||||
progressVisible: false,
|
||||
progress: 0,
|
||||
columnIndex: "",
|
||||
|
|
@ -52,6 +53,8 @@ export default class SalaryDetail extends React.Component {
|
|||
if (type === "PR") {
|
||||
if (id === "EDIT") {
|
||||
this.handleEdit(record);
|
||||
} else if (id === "COSTCENTER") {
|
||||
window.open(record ? record.url : "", "_blank");
|
||||
} else if (id === "COLUMNINDEX") {
|
||||
if (!extraId) {
|
||||
this.setState({ columnIndex: record });
|
||||
|
|
@ -91,7 +94,7 @@ export default class SalaryDetail extends React.Component {
|
|||
url: "/api/bs/hrmsalary/salaryacct/acctresult/list",
|
||||
queryParams: {
|
||||
salaryAcctRecordId,
|
||||
employeeName: this.props.employeeName,
|
||||
...this.props.employeeName,
|
||||
current, pageSize
|
||||
}
|
||||
};
|
||||
|
|
@ -106,10 +109,10 @@ export default class SalaryDetail extends React.Component {
|
|||
url: "/api/bs/hrmsalary/salaryacct/acctresult/list",
|
||||
queryParams: {
|
||||
salaryAcctRecordId,
|
||||
employeeName: this.props.employeeName
|
||||
...this.props.employeeName
|
||||
}
|
||||
};
|
||||
childFrameObj.contentWindow.postMessage(JSON.stringify(payload), "*");
|
||||
type && childFrameObj.contentWindow.postMessage(JSON.stringify(payload), "*");
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -155,7 +158,7 @@ export default class SalaryDetail extends React.Component {
|
|||
url: "/api/bs/hrmsalary/salaryacct/acctresult/list",
|
||||
queryParams: {
|
||||
salaryAcctRecordId,
|
||||
employeeName: this.props.employeeName
|
||||
...this.props.employeeName
|
||||
}
|
||||
};
|
||||
childFrameObj.contentWindow.postMessage(JSON.stringify(payload), "*");
|
||||
|
|
@ -175,13 +178,12 @@ export default class SalaryDetail extends React.Component {
|
|||
}
|
||||
|
||||
// 侧边栏保存
|
||||
handleEditSlideSave() {
|
||||
handleEditSlideSave = () => {
|
||||
const { calculateStore } = this.props;
|
||||
const { saveAcctResult } = calculateStore;
|
||||
this.setState({
|
||||
slideVisiable: false
|
||||
});
|
||||
this.setState({ loading: true });
|
||||
saveAcctResult(this.recordId).then(() => {
|
||||
this.setState({ loading: false });
|
||||
const childFrameObj = document.getElementById("atdTable");
|
||||
const salaryAcctRecordId = getQueryString("id");
|
||||
const payload = {
|
||||
|
|
@ -190,17 +192,17 @@ export default class SalaryDetail extends React.Component {
|
|||
url: "/api/bs/hrmsalary/salaryacct/acctresult/list",
|
||||
queryParams: {
|
||||
salaryAcctRecordId,
|
||||
employeeName: this.props.employeeName
|
||||
...this.props.employeeName
|
||||
}
|
||||
};
|
||||
childFrameObj.contentWindow.postMessage(JSON.stringify(payload), "*");
|
||||
// acctResultList({ salaryAcctRecordId: this.id });
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
render() {
|
||||
const { slideVisiable, columnIndex } = this.state;
|
||||
const { slideVisiable, columnIndex, loading } = this.state;
|
||||
const { calculateStore, taxAgentStore: { showOperateBtn } } = this.props;
|
||||
const { baseSalarySobCycle, columnDescList } = calculateStore;
|
||||
|
||||
|
|
@ -266,10 +268,11 @@ export default class SalaryDetail extends React.Component {
|
|||
measure={"%"}
|
||||
title={
|
||||
<SlideModalTitle
|
||||
subtitle={"编辑薪资"}
|
||||
subtitle="编辑薪资"
|
||||
editable={true}
|
||||
showOperateBtn={showOperateBtn}
|
||||
onSave={() => this.handleEditSlideSave()}
|
||||
onSave={this.handleEditSlideSave}
|
||||
loading={loading}
|
||||
/>
|
||||
}
|
||||
content={<EditSalaryDetail id={this.recordId}/>}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import { WeaBrowser, WeaFormItem, WeaHelpfulTip, WeaInput, WeaSearchGroup, WeaSe
|
|||
import { inject, observer } from "mobx-react";
|
||||
import "./index.less";
|
||||
import { getQueryString } from "../../util/url";
|
||||
import { calcPageNo } from "../../util";
|
||||
|
||||
@inject("calculateStore", "salaryFileStore")
|
||||
@observer
|
||||
|
|
@ -15,9 +14,10 @@ export default class UserSure extends React.Component {
|
|||
showSearchAd: false,
|
||||
searchItemsValue: {
|
||||
employeeName: "",
|
||||
workcode: "",
|
||||
departmentIds: "",
|
||||
positionIds: "",
|
||||
status: ""
|
||||
statuses: ""
|
||||
},
|
||||
selectedKey: "0",
|
||||
selectedRowKeys: [], // table 选中项
|
||||
|
|
@ -42,19 +42,20 @@ export default class UserSure extends React.Component {
|
|||
}
|
||||
|
||||
Input = (value, key) => {
|
||||
const { employeeName } = this.state.searchItemsValue;
|
||||
const { employeeName, workcode } = this.state.searchItemsValue;
|
||||
return (
|
||||
<WeaFormItem
|
||||
label={value}
|
||||
labelCol={{ span: 6 }}
|
||||
wrapperCol={{ span: 18 }}
|
||||
>
|
||||
<WeaInput value={employeeName} onChange={(val) => this.setState({
|
||||
searchItemsValue: {
|
||||
...this.state.searchItemsValue,
|
||||
[key]: val
|
||||
}
|
||||
})}/>
|
||||
<WeaInput value={key === "employeeName" ? employeeName : workcode}
|
||||
onChange={(val) => this.setState({
|
||||
searchItemsValue: {
|
||||
...this.state.searchItemsValue,
|
||||
[key]: val
|
||||
}
|
||||
})}/>
|
||||
</WeaFormItem>
|
||||
);
|
||||
};
|
||||
|
|
@ -77,7 +78,7 @@ export default class UserSure extends React.Component {
|
|||
);
|
||||
};
|
||||
Select = (value, key) => {
|
||||
const { status } = this.state.searchItemsValue;
|
||||
const { statuses } = this.state.searchItemsValue;
|
||||
return (
|
||||
<WeaFormItem
|
||||
label={value}
|
||||
|
|
@ -85,10 +86,13 @@ export default class UserSure extends React.Component {
|
|||
wrapperCol={{ span: 18 }}
|
||||
>
|
||||
<WeaSelect
|
||||
value={String(status)}
|
||||
multiple
|
||||
value={String(statuses)}
|
||||
options={[
|
||||
{ key: "", showname: "" }, {key: "ALL", showname: "全部"},
|
||||
{ key: "NORMAL", showname: "在职" }, {key: "UNAVAILABLE", showname: "离职"}
|
||||
{ key: "0", showname: "试用" }, { key: "1", showname: "正式" },
|
||||
{ key: "2", showname: "临时" }, { key: "3", showname: "试用延期" },
|
||||
{ key: "4", showname: "解雇" }, { key: "5", showname: "离职" },
|
||||
{ key: "6", showname: "退休" }
|
||||
]}
|
||||
onChange={(val) => this.setState({ searchItemsValue: { ...this.state.searchItemsValue, [key]: val } })}/>
|
||||
</WeaFormItem>
|
||||
|
|
@ -116,12 +120,14 @@ export default class UserSure extends React.Component {
|
|||
url: "/api/bs/hrmsalary/salaryacct/acctemployee/list",
|
||||
queryParams: {
|
||||
salaryAcctRecordId,
|
||||
employeeName: this.state.userListSearchValue
|
||||
...this.state.searchItemsValue,
|
||||
}
|
||||
};
|
||||
childFrameObj.contentWindow.postMessage(JSON.stringify(payload), "*"); //window.postMessage
|
||||
} else if (id === "DELETE") {
|
||||
this.handleDeleteItem(record);
|
||||
} else if (id === "COSTCENTER") {
|
||||
window.open(record.url, "_blank");
|
||||
} else if (id === "BATCHDELETE") {
|
||||
this.onSelectChange(record);
|
||||
} else if (id === "PAGEINFO") {
|
||||
|
|
@ -134,7 +140,7 @@ export default class UserSure extends React.Component {
|
|||
url: "/api/bs/hrmsalary/salaryacct/acctemployee/list",
|
||||
queryParams: {
|
||||
salaryAcctRecordId,
|
||||
employeeName: this.state.userListSearchValue,
|
||||
...this.state.searchItemsValue,
|
||||
current,
|
||||
pageSize
|
||||
}
|
||||
|
|
@ -144,10 +150,10 @@ export default class UserSure extends React.Component {
|
|||
const payload = {
|
||||
type: "PC",
|
||||
listType: "MA",
|
||||
url: this.state.selectedKey === '1'?"/api/bs/hrmsalary/salaryacct/reducedemployee/list":"/api/bs/hrmsalary/salaryacct/addedemployee/list",
|
||||
url: this.state.selectedKey === "1" ? "/api/bs/hrmsalary/salaryacct/reducedemployee/list" : "/api/bs/hrmsalary/salaryacct/addedemployee/list",
|
||||
queryParams: {
|
||||
salaryAcctRecordId,
|
||||
employeeName: this.state.userListSearchValue,
|
||||
...this.state.searchItemsValue,
|
||||
current, pageSize
|
||||
}
|
||||
};
|
||||
|
|
@ -174,7 +180,7 @@ export default class UserSure extends React.Component {
|
|||
url: "/api/bs/hrmsalary/salaryacct/acctemployee/list",
|
||||
queryParams: {
|
||||
salaryAcctRecordId,
|
||||
employeeName: this.state.userListSearchValue,
|
||||
...this.state.searchItemsValue,
|
||||
...this.pageInfo
|
||||
}
|
||||
};
|
||||
|
|
@ -221,9 +227,9 @@ export default class UserSure extends React.Component {
|
|||
url: "/api/bs/hrmsalary/salaryacct/acctemployee/list",
|
||||
queryParams: {
|
||||
salaryAcctRecordId,
|
||||
employeeName: this.state.userListSearchValue,
|
||||
...this.state.searchItemsValue,
|
||||
...this.pageInfo,
|
||||
current: 1,
|
||||
current: 1
|
||||
}
|
||||
};
|
||||
childFrameObj.contentWindow.postMessage(JSON.stringify(payload), "*");
|
||||
|
|
@ -252,8 +258,8 @@ export default class UserSure extends React.Component {
|
|||
url: "/api/bs/hrmsalary/salaryacct/acctemployee/list",
|
||||
queryParams: {
|
||||
salaryAcctRecordId,
|
||||
employeeName: this.state.userListSearchValue,
|
||||
...this.pageInfo,
|
||||
...this.state.searchItemsValue,
|
||||
...this.pageInfo
|
||||
}
|
||||
};
|
||||
childFrameObj.contentWindow.postMessage(JSON.stringify(payload), "*");
|
||||
|
|
@ -278,7 +284,7 @@ export default class UserSure extends React.Component {
|
|||
url: "/api/bs/hrmsalary/salaryacct/acctemployee/list",
|
||||
queryParams: {
|
||||
salaryAcctRecordId,
|
||||
employeeName: this.state.userListSearchValue,
|
||||
...this.state.searchItemsValue,
|
||||
...this.pageInfo
|
||||
}
|
||||
};
|
||||
|
|
@ -339,7 +345,7 @@ export default class UserSure extends React.Component {
|
|||
employeeName: "",
|
||||
departmentIds: "",
|
||||
positionIds: "",
|
||||
status: ""
|
||||
statuses: ""
|
||||
}
|
||||
})}>
|
||||
重置
|
||||
|
|
@ -352,9 +358,10 @@ export default class UserSure extends React.Component {
|
|||
const renderSearch = () => {
|
||||
const searchItems = [
|
||||
{ com: this.Input("姓名", "employeeName") },
|
||||
{ com: this.Input("工号", "workcode") },
|
||||
{ com: this.Browser("部门", "departmentIds") },
|
||||
{ com: this.Browser("岗位", "positionIds") },
|
||||
{ com: this.Select("状态", "status") }
|
||||
{ com: this.Select("状态", "statuses") }
|
||||
];
|
||||
return <WeaSearchGroup title={"基本信息"} items={searchItems} showGroup/>;
|
||||
};
|
||||
|
|
@ -423,7 +430,7 @@ export default class UserSure extends React.Component {
|
|||
url: "/api/bs/hrmsalary/salaryacct/acctemployee/list",
|
||||
queryParams: {
|
||||
salaryAcctRecordId,
|
||||
employeeName: this.state.userListSearchValue
|
||||
...this.state.searchItemsValue,
|
||||
}
|
||||
};
|
||||
childFrameObj.contentWindow.postMessage(JSON.stringify(payload), "*"); //window.postMessage
|
||||
|
|
@ -453,7 +460,7 @@ export default class UserSure extends React.Component {
|
|||
url: "/api/bs/hrmsalary/salaryacct/reducedemployee/list",
|
||||
queryParams: {
|
||||
salaryAcctRecordId,
|
||||
employeeName: this.state.userListSearchValue
|
||||
...this.state.searchItemsValue,
|
||||
}
|
||||
};
|
||||
childFrameObj.contentWindow.postMessage(JSON.stringify(payload), "*");
|
||||
|
|
@ -483,7 +490,7 @@ export default class UserSure extends React.Component {
|
|||
url: "/api/bs/hrmsalary/salaryacct/addedemployee/list",
|
||||
queryParams: {
|
||||
salaryAcctRecordId,
|
||||
employeeName: this.state.userListSearchValue
|
||||
...this.state.searchItemsValue,
|
||||
}
|
||||
};
|
||||
childFrameObj.contentWindow.postMessage(JSON.stringify(payload), "*");
|
||||
|
|
@ -570,6 +577,7 @@ export default class UserSure extends React.Component {
|
|||
<div style={{ width: "100%", height: "calc(100vh - 261px)" }}>
|
||||
<iframe
|
||||
style={{ border: 0, width: "100%", height: "100%" }}
|
||||
// src="http://localhost:7607/#/atdTable"
|
||||
src="/spa/hrmSalary/hrmSalaryCalculateDetail/index.html#/atdTable"
|
||||
id="atdTable"
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -27,12 +27,33 @@ class AddItems extends Component {
|
|||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.setState({
|
||||
baseInfo: {
|
||||
...this.state.baseInfo,
|
||||
declareMonth: this.props.editId.declareMonth || this.props.editId.taxYearMonth,
|
||||
taxAgentId: this.props.editId.taxAgentId,
|
||||
taxAgentName: this.props.editId.taxAgentName,
|
||||
employeeId: this.props.editId.employeeId,
|
||||
employeeName: this.props.editId.username
|
||||
}
|
||||
});
|
||||
const fields = _.map(this.props.condition[0].items, it => {
|
||||
return it.domkey[0];
|
||||
});
|
||||
fields.map(item => {
|
||||
this.props.form.updateFields({
|
||||
[item]: this.props.editId[item] || ""
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps, nextContext) {
|
||||
if (nextProps.editId !== this.props.editId) {
|
||||
this.setState({
|
||||
baseInfo: {
|
||||
...this.state.baseInfo,
|
||||
declareMonth: nextProps.editId.declareMonth,
|
||||
declareMonth: nextProps.editId.declareMonth || nextProps.editId.taxYearMonth,
|
||||
taxAgentId: nextProps.editId.taxAgentId,
|
||||
taxAgentName: nextProps.editId.taxAgentName,
|
||||
employeeId: nextProps.editId.employeeId,
|
||||
|
|
@ -165,9 +186,10 @@ class AddItems extends Component {
|
|||
return (
|
||||
<div className="addItemsWrapper">
|
||||
<WeaSearchGroup
|
||||
className="baseForm"
|
||||
title="基础信息"
|
||||
items={!isCum ? items : baseInfo.personArea === "ORGANIZATION" ? [...cumSituationitems, ...insider] : baseInfo.personArea === "EXT_EMPLOYEE" ? [...cumSituationitems, ...noSysPerson] : cumSituationitems}
|
||||
needTigger showGroup center/>
|
||||
needTigger showGroup col={1}/>
|
||||
{
|
||||
getSearchs(form, condition, 2)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,191 +1,213 @@
|
|||
import { Switch } from 'antd'
|
||||
|
||||
export const columns = [
|
||||
{
|
||||
title: "姓名",
|
||||
dataIndex: 'username',
|
||||
key: 'username',
|
||||
},
|
||||
{
|
||||
title: "个税扣缴义务人",
|
||||
dataIndex: 'ywr',
|
||||
key: 'ywr',
|
||||
},
|
||||
{
|
||||
title: "部门",
|
||||
dataIndex: 'bm',
|
||||
key: 'title',
|
||||
},
|
||||
{
|
||||
title: "手机号",
|
||||
dataIndex: 'sjh',
|
||||
key: 'sjh',
|
||||
},
|
||||
{
|
||||
title: "工号",
|
||||
dataIndex: 'gh',
|
||||
key: 'gh',
|
||||
},
|
||||
{
|
||||
title: "证件号码",
|
||||
dataIndex: 'sfzh',
|
||||
key: 'sfzh',
|
||||
},
|
||||
{
|
||||
title: "入职日期",
|
||||
dataIndex: 'rzrq',
|
||||
key: 'rzrq',
|
||||
},
|
||||
{
|
||||
title: "累计子女教育",
|
||||
dataIndex: 'ljznjy',
|
||||
key: 'ljznjy',
|
||||
},
|
||||
{
|
||||
title: "累计继续教育",
|
||||
dataIndex: 'ljjxjy',
|
||||
key: 'ljjxjy',
|
||||
},
|
||||
{
|
||||
title: "累计住房贷款利息",
|
||||
dataIndex: 'ljzfdklx',
|
||||
key: 'ljfdklx',
|
||||
},
|
||||
{
|
||||
title: "累计住房租金",
|
||||
dataIndex: 'ljzfzj',
|
||||
key: 'ljzfzj',
|
||||
},
|
||||
{
|
||||
title: "累计赡养老人",
|
||||
dataIndex: 'ljsylr',
|
||||
key: 'ljsylr',
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
dataIndex: 'cz',
|
||||
key: 'cz',
|
||||
render: (text, record) => {
|
||||
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
export const tab2Columns = [
|
||||
{
|
||||
title: "字段名称",
|
||||
dataIndex: 'username',
|
||||
key: 'username'
|
||||
},
|
||||
{
|
||||
title: "来源",
|
||||
dataIndex: 'username',
|
||||
key: 'username'
|
||||
},
|
||||
{
|
||||
title: "类型",
|
||||
dataIndex: 'username',
|
||||
key: 'username'
|
||||
},
|
||||
{
|
||||
title: "是否启用",
|
||||
render: (text) => {
|
||||
return <Switch defaultChecked={false}/>
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "备注",
|
||||
dataIndex: 'username',
|
||||
key: 'username'
|
||||
}
|
||||
]
|
||||
|
||||
export const slideColumns = [
|
||||
{
|
||||
title: "姓名",
|
||||
dataIndex: 'username',
|
||||
key: 'username'
|
||||
},
|
||||
{
|
||||
title: "部门",
|
||||
dataIndex: 'username',
|
||||
key: 'username'
|
||||
},
|
||||
{
|
||||
title: "手机号",
|
||||
dataIndex: 'username',
|
||||
key: 'username'
|
||||
},
|
||||
{
|
||||
title: "工号",
|
||||
dataIndex: 'username',
|
||||
key: 'username'
|
||||
},
|
||||
{
|
||||
title: "在职计薪天数",
|
||||
dataIndex: 'username',
|
||||
key: 'username'
|
||||
},
|
||||
{
|
||||
title: "非在职计薪天数",
|
||||
dataIndex: 'username',
|
||||
key: 'username'
|
||||
},
|
||||
{
|
||||
title: "应出勤天数(不含节假日)",
|
||||
dataIndex: 'username',
|
||||
key: 'username'
|
||||
},
|
||||
{
|
||||
title: "实际出勤天数",
|
||||
dataIndex: 'username',
|
||||
key: 'username'
|
||||
},
|
||||
{
|
||||
title: "工作日加班",
|
||||
dataIndex: 'username',
|
||||
key: 'username'
|
||||
},
|
||||
{
|
||||
title: "双休日日加班",
|
||||
dataIndex: 'username',
|
||||
key: 'username'
|
||||
},
|
||||
{
|
||||
title: "事假时长",
|
||||
dataIndex: 'username',
|
||||
key: 'username'
|
||||
},
|
||||
{
|
||||
title: "病假时长",
|
||||
dataIndex: 'username',
|
||||
key: 'username'
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
export const slideDataSource = [{
|
||||
username: "测试"
|
||||
}]
|
||||
|
||||
export const dataSource = [
|
||||
{
|
||||
username: "测试",
|
||||
ywr: "测试",
|
||||
bm: "测试",
|
||||
sjh: "测试",
|
||||
gh: "测试",
|
||||
sfzh: "测试",
|
||||
rzrq: "测试",
|
||||
ljznjy: "测试",
|
||||
ljjxjy: "测试",
|
||||
ljzfdklx: "测试",
|
||||
ljzfzj: "测试",
|
||||
ljsylr: "测试"
|
||||
{
|
||||
title: "姓名",
|
||||
dataIndex: "username",
|
||||
key: "username"
|
||||
},
|
||||
{
|
||||
title: "个税扣缴义务人",
|
||||
dataIndex: "ywr",
|
||||
key: "ywr"
|
||||
},
|
||||
{
|
||||
title: "部门",
|
||||
dataIndex: "bm",
|
||||
key: "title"
|
||||
},
|
||||
{
|
||||
title: "手机号",
|
||||
dataIndex: "sjh",
|
||||
key: "sjh"
|
||||
},
|
||||
{
|
||||
title: "工号",
|
||||
dataIndex: "gh",
|
||||
key: "gh"
|
||||
},
|
||||
{
|
||||
title: "证件号码",
|
||||
dataIndex: "sfzh",
|
||||
key: "sfzh"
|
||||
},
|
||||
{
|
||||
title: "入职日期",
|
||||
dataIndex: "rzrq",
|
||||
key: "rzrq"
|
||||
},
|
||||
{
|
||||
title: "累计子女教育",
|
||||
dataIndex: "ljznjy",
|
||||
key: "ljznjy"
|
||||
},
|
||||
{
|
||||
title: "累计继续教育",
|
||||
dataIndex: "ljjxjy",
|
||||
key: "ljjxjy"
|
||||
},
|
||||
{
|
||||
title: "累计住房贷款利息",
|
||||
dataIndex: "ljzfdklx",
|
||||
key: "ljfdklx"
|
||||
},
|
||||
{
|
||||
title: "累计住房租金",
|
||||
dataIndex: "ljzfzj",
|
||||
key: "ljzfzj"
|
||||
},
|
||||
{
|
||||
title: "累计赡养老人",
|
||||
dataIndex: "ljsylr",
|
||||
key: "ljsylr"
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
dataIndex: "cz",
|
||||
key: "cz",
|
||||
render: (text, record) => {
|
||||
|
||||
}
|
||||
}
|
||||
];
|
||||
export const fieldsColumns = [
|
||||
{
|
||||
title: "id",
|
||||
dataIndex: "id",
|
||||
key: "id",
|
||||
display: true
|
||||
},
|
||||
{
|
||||
title: "字段名称",
|
||||
dataIndex: "fieldName",
|
||||
key: "fieldName",
|
||||
display: true
|
||||
},
|
||||
{
|
||||
title: "来源",
|
||||
dataIndex: "sourceType",
|
||||
key: "sourceType",
|
||||
display: true
|
||||
},
|
||||
{
|
||||
title: "类型",
|
||||
dataIndex: "fieldType",
|
||||
key: "fieldType",
|
||||
display: true
|
||||
},
|
||||
{
|
||||
title: "是否启用",
|
||||
dataIndex: "enableStatus",
|
||||
key: "enableStatus",
|
||||
display: true
|
||||
},
|
||||
{
|
||||
title: "备注",
|
||||
dataIndex: "description",
|
||||
key: "description",
|
||||
display: true
|
||||
}
|
||||
];
|
||||
export const conditions = [
|
||||
{
|
||||
items: [
|
||||
{
|
||||
colSpan: 1,
|
||||
conditionType: "INPUT",
|
||||
domkey: ["fieldName"],
|
||||
fieldcol: 14,
|
||||
rules: "required|string",
|
||||
label: "字段名称",
|
||||
labelcol: 6,
|
||||
value: "",
|
||||
viewAttr: 3
|
||||
},
|
||||
{
|
||||
colSpan: 1,
|
||||
conditionType: "SELECT",
|
||||
domkey: ["fieldType"],
|
||||
fieldcol: 14,
|
||||
isQuickSearch: false,
|
||||
label: "类型",
|
||||
labelcol: 6,
|
||||
valueList:[],
|
||||
options: [
|
||||
{
|
||||
key: "NUMBER",
|
||||
selected: true,
|
||||
showname: "数值"
|
||||
},
|
||||
{
|
||||
key: "TEXT",
|
||||
selected: false,
|
||||
showname: "文本"
|
||||
}
|
||||
],
|
||||
rules: "required|string",
|
||||
viewAttr: 3
|
||||
},
|
||||
{
|
||||
colSpan: 1,
|
||||
conditionType: "SWITCH",
|
||||
domkey: ["enableStatus"],
|
||||
fieldcol: 14,
|
||||
label: "是否启用",
|
||||
labelcol: 6,
|
||||
viewAttr: 3,
|
||||
rules: "required"
|
||||
},
|
||||
{
|
||||
colSpan: 1,
|
||||
conditionType: "INPUT",
|
||||
domkey: ["description"],
|
||||
fieldcol: 14,
|
||||
label: "备注",
|
||||
labelcol: 6,
|
||||
value: "",
|
||||
viewAttr: 2
|
||||
}
|
||||
],
|
||||
defaultshow: true
|
||||
}
|
||||
];
|
||||
export const reFrenceConditions = [
|
||||
{
|
||||
items: [
|
||||
{
|
||||
colSpan: 1,
|
||||
conditionType: "MONTHPICKER",
|
||||
domkey: ["salaryYearMonth"],
|
||||
fieldcol: 18,
|
||||
rules: "required|string",
|
||||
label: "薪资所属月",
|
||||
labelcol: 6,
|
||||
value: "",
|
||||
viewAttr: 3
|
||||
},
|
||||
{
|
||||
colSpan: 1,
|
||||
conditionType: "SELECT",
|
||||
domkey: ["salarySobId"],
|
||||
fieldcol: 18,
|
||||
isQuickSearch: false,
|
||||
label: "薪资账套",
|
||||
labelcol: 6,
|
||||
valueList:[],
|
||||
options: [],
|
||||
rules: "required|string",
|
||||
viewAttr: 3
|
||||
},
|
||||
{
|
||||
colSpan: 1,
|
||||
conditionType: "INPUT",
|
||||
domkey: ["description"],
|
||||
fieldcol: 18,
|
||||
label: "备注",
|
||||
labelcol: 6,
|
||||
value: "",
|
||||
viewAttr: 2
|
||||
}
|
||||
],
|
||||
defaultshow: true
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* Author: 黎永顺
|
||||
* name: 新建考勤自定义字段
|
||||
* Description:
|
||||
* Date: 2023/3/1
|
||||
*/
|
||||
import React, { Component } from "react";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import { WeaDialog } from "ecCom";
|
||||
import { Button, message } from "antd";
|
||||
import { conditions } from "../columns";
|
||||
import { getSearchs } from "../../../../util";
|
||||
import { saveAttendanceField } from "../../../../apis/attendance";
|
||||
import "./index.less";
|
||||
|
||||
@inject("attendanceStore")
|
||||
@observer
|
||||
class AttendanceCustomFieldsModal extends Component {
|
||||
componentDidMount() {
|
||||
const { attendanceStore: { form } } = this.props;
|
||||
form.initFormFields(conditions);
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps, nextContext) {
|
||||
if (nextProps.visible !== this.props.visible && nextProps.visible) this.handleResetForm();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Author: 黎永顺
|
||||
* Description: 保存考勤字段
|
||||
* Params:
|
||||
* Date: 2023/3/1
|
||||
*/
|
||||
handleSubmitFields = () => {
|
||||
const { attendanceStore: { form }, onRefresh, onCancel } = this.props;
|
||||
form.validateForm().then(f => {
|
||||
if (f.isValid) {
|
||||
const payload = form.getFormParams();
|
||||
saveAttendanceField(payload).then(({ status, errormsg }) => {
|
||||
if (status) {
|
||||
message.success("新增成功");
|
||||
onCancel();
|
||||
onRefresh();
|
||||
} else {
|
||||
message.error(errormsg || "新增失败");
|
||||
}
|
||||
});
|
||||
} else {
|
||||
f.showErrors();
|
||||
}
|
||||
});
|
||||
};
|
||||
handleResetForm = () => {
|
||||
const { attendanceStore: { form } } = this.props;
|
||||
form.updateFields({ fieldName: "", fieldType: "NUMBER", enableStatus: "0", description: "" });
|
||||
};
|
||||
|
||||
render() {
|
||||
const { attendanceStore: { form } } = this.props;
|
||||
const buttons = [
|
||||
<Button type="primary" onClick={this.handleSubmitFields}>保存</Button>
|
||||
];
|
||||
return (
|
||||
<WeaDialog
|
||||
{...this.props} style={{ width: 440, height: 202 }}
|
||||
buttons={buttons} hasScroll initLoadCss
|
||||
className="modalWrapper"
|
||||
>
|
||||
{getSearchs(form, conditions, 1)}
|
||||
</WeaDialog>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default AttendanceCustomFieldsModal;
|
||||
|
|
@ -0,0 +1,419 @@
|
|||
/*
|
||||
* Author: 黎永顺
|
||||
* name: 考勤数据
|
||||
* Description:
|
||||
* Date: 2023/2/24
|
||||
*/
|
||||
import React, { Component } from "react";
|
||||
import { WeaTable } from "ecCom";
|
||||
import { message, Modal } from "antd";
|
||||
import {
|
||||
deleteAttendance,
|
||||
getAttendanceFieldSettingList,
|
||||
getAttendanceList,
|
||||
getLedgerList,
|
||||
getSalaryCycleAndAttendCycle,
|
||||
importAttendQuoteData,
|
||||
previewAttendQuote,
|
||||
returnToAttendanceFieldSettingDefault,
|
||||
saveAttendanceFieldSetting,
|
||||
saveAttendanceFieldSettingAsDefault
|
||||
} from "../../../../apis/attendance";
|
||||
import ImportModal from "../../../../components/importModal";
|
||||
import HeaderSet from "../../../../components/importModal/headerSet";
|
||||
import ImportFormOptions from "./importFormOptions";
|
||||
import SelectItemModal from "../../../../components/selectItemsModal";
|
||||
import moment from "moment";
|
||||
import SelectItemsWrapper from "../../../../components/selectItemsModal/selectItemsWrapper";
|
||||
import AttendanceRefrenceDataModal from "./attendanceRefrenceDataModal";
|
||||
import AttendanceDataViewSlide from "./attendanceDataViewSlide";
|
||||
|
||||
class AttendanceDataComp extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
loading: {
|
||||
query: false,
|
||||
headset: false
|
||||
},
|
||||
dataSource: [],
|
||||
columns: [],
|
||||
pageInfo: {
|
||||
current: 1,
|
||||
pageSize: 10,
|
||||
total: 0
|
||||
},
|
||||
importData: {
|
||||
visiable: false, params: {}, step: 0,
|
||||
columns: [], slideDataSource: [], importResult: []
|
||||
},
|
||||
importFormPayload: {
|
||||
salaryYearMonth: moment().format("YYYY-MM"), salarySobList: [],
|
||||
salarySobId: "", salaryCycle: "", attendCycle: ""
|
||||
},
|
||||
fieldSetPayload: { visible: false, title: "", children: null },
|
||||
attendanceReferencePayload: { visible: false, title: "" },
|
||||
attendanceViewPayload: { visible: false, attendQuoteId: "", salaryYearMonth: "" }
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.getAttendanceList();
|
||||
}
|
||||
|
||||
getAttendanceList = (extraPayload) => {
|
||||
const { loading, pageInfo } = this.state;
|
||||
const module = { ...pageInfo, ...extraPayload };
|
||||
this.setState({ loading: { ...loading, query: true } });
|
||||
getAttendanceList(module).then(({ status, data }) => {
|
||||
this.setState({ loading: { ...loading, query: false } });
|
||||
if (status) {
|
||||
const { columns, list: dataSource, pageNum: current, pageSize, total } = data;
|
||||
this.setState({
|
||||
pageInfo: { ...pageInfo, current, pageSize, total },
|
||||
dataSource,
|
||||
columns: _.map(columns, item => {
|
||||
if (item.dataIndex === "salaryYearMonth") {
|
||||
return {
|
||||
...item,
|
||||
render: (text) => <span>{moment(text).format("YYYY-MM")}</span>
|
||||
};
|
||||
}
|
||||
return { ...item };
|
||||
})
|
||||
});
|
||||
}
|
||||
}).catch(() => this.setState({ loading: { ...loading, query: false } }));
|
||||
};
|
||||
getLedgerList = () => {
|
||||
const { importFormPayload } = this.state;
|
||||
getLedgerList().then(({ status, data }) => {
|
||||
if (status) {
|
||||
this.setState({
|
||||
importFormPayload: {
|
||||
...importFormPayload,
|
||||
salarySobList: _.map(data, it => ({ key: it.id, showname: it.content }))
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
handleChangeImportPayload = (key, value) => {
|
||||
const { importFormPayload, importData } = this.state;
|
||||
const { params } = importData;
|
||||
this.setState({
|
||||
importFormPayload: {
|
||||
...importFormPayload,
|
||||
[key]: value
|
||||
},
|
||||
importData: { ...importData, params: { ...params, [key]: value } }
|
||||
}, () => {
|
||||
if (this.state.importFormPayload.salaryYearMonth && this.state.importFormPayload.salarySobId) {
|
||||
const payload = {
|
||||
salaryYearMonthStr: this.state.importFormPayload.salaryYearMonth,
|
||||
salarySobId: this.state.importFormPayload.salarySobId
|
||||
};
|
||||
getSalaryCycleAndAttendCycle(payload).then(({ status, data }) => {
|
||||
if (status) {
|
||||
this.setState({
|
||||
importFormPayload: {
|
||||
...this.state.importFormPayload,
|
||||
...data
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
handleDeleteAttendanceData = ({ id }) => {
|
||||
Modal.confirm({
|
||||
title: "信息确认",
|
||||
content: "确认要删除吗?",
|
||||
onOk: () => {
|
||||
deleteAttendance([id]).then(({ status, errormsg }) => {
|
||||
if (status) {
|
||||
message.success("删除成功");
|
||||
this.getAttendanceList();
|
||||
} else {
|
||||
message.error(errormsg || "删除失败");
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
handleViewAttendanceData = ({ id, attendCycle }) => {
|
||||
const { attendanceViewPayload } = this.state;
|
||||
this.setState({
|
||||
attendanceViewPayload: {
|
||||
...attendanceViewPayload,
|
||||
visible: true, attendQuoteId: id,
|
||||
salaryYearMonth: attendCycle
|
||||
}
|
||||
});
|
||||
};
|
||||
handleImportAttendanceData = (importData) => {
|
||||
const { importFormPayload } = this.state;
|
||||
const { salaryYearMonth, salarySobId } = importFormPayload;
|
||||
this.getLedgerList();
|
||||
this.setState({ importData: { ...importData, params: { salaryYearMonth, salarySobId } } });
|
||||
};
|
||||
setStep = step => this.setState({ importData: { ...this.state.importData, step } });
|
||||
handleFinish = () => {
|
||||
const { importData } = this.state;
|
||||
const { step } = importData;
|
||||
this.setState({
|
||||
importData: {
|
||||
...importData, visiable: false, params: {}, step: 0,
|
||||
columns: [], slideDataSource: [], importResult: []
|
||||
}
|
||||
});
|
||||
step === 2 && this.getAttendanceList();
|
||||
};
|
||||
handlePreviewImport = (params) => {
|
||||
const { importData } = this.state;
|
||||
previewAttendQuote(params).then(({ status, data }) => {
|
||||
if (status) {
|
||||
const { headers, list } = data;
|
||||
this.setState({
|
||||
importData: {
|
||||
...importData,
|
||||
columns: _.map(headers, (it, dataIndex) => ({ title: it, dataIndex })),
|
||||
slideDataSource: _.map(list, item => {
|
||||
return _.reduce(item, (pre, cur, key) => (_.assign(pre, { [key]: cur })), {});
|
||||
})
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
handleImport = (params) => {
|
||||
const { importData } = this.state;
|
||||
const { step } = importData;
|
||||
importAttendQuoteData(params).then(({ status, data }) => {
|
||||
if (status) {
|
||||
this.setState({
|
||||
importData: {
|
||||
...importData,
|
||||
step: step + 1,
|
||||
importResult: data
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
handleTemplateLinkClick = () => {
|
||||
const { importFormPayload } = this.state;
|
||||
const { salarySobId, salaryYearMonth } = importFormPayload;
|
||||
if (!salarySobId || !salaryYearMonth) {
|
||||
message.warning("请完善导入选项,再下载");
|
||||
return;
|
||||
}
|
||||
window.open(`/api/bs/hrmsalary/attendQuote/downloadTemplate?salaryYearMonth=${salaryYearMonth}&salarySobId=${salarySobId}`);
|
||||
};
|
||||
/*
|
||||
* Author: 黎永顺
|
||||
* Description: 表头设置
|
||||
* Params:
|
||||
* Date: 2023/3/6
|
||||
*/
|
||||
handleHeaderSettings = (params) => {
|
||||
const { fieldSetPayload, loading } = this.state;
|
||||
this.setState({ loading: { ...loading, headset: true } });
|
||||
getAttendanceFieldSettingList(params).then(({ status, data }) => {
|
||||
this.setState({ loading: { ...loading, headset: false } });
|
||||
if (status) {
|
||||
this.setState({
|
||||
fieldSetPayload: {
|
||||
...fieldSetPayload,
|
||||
visible: true, title: "导入字段设置",
|
||||
children: <SelectItemsWrapper
|
||||
ref={dom => this.setItemRef = dom}
|
||||
dataSource={data}
|
||||
onSelectGroupAll={this.handleSelectGroupAll}
|
||||
onSelectItem={this.handleSelectItem}
|
||||
/>
|
||||
}
|
||||
});
|
||||
}
|
||||
}).catch(() => this.setState({ loading: { ...loading, headset: false } }));
|
||||
};
|
||||
handleCloseSettings = () => {
|
||||
const { fieldSetPayload } = this.state;
|
||||
this.setState({
|
||||
fieldSetPayload: {
|
||||
...fieldSetPayload,
|
||||
visible: false, title: "", children: null
|
||||
}
|
||||
});
|
||||
};
|
||||
handleSearchItemSet = (val) => this.setItemRef.handleSearchItemSet(val);
|
||||
handleShowOnlyChecked = (checked) => this.setItemRef.handleShowOnlyChecked(checked);
|
||||
handleSelectGroupAll = (groupId, checked) => this.setItemRef.handleSelectGroupAll(groupId, checked);
|
||||
handleSelectItem = (id, checked) => this.setItemRef.handleSelectItem(id, checked);
|
||||
handleMoreOpts = (key) => {
|
||||
switch (key) {
|
||||
case "recovery":
|
||||
returnToAttendanceFieldSettingDefault({ sourceType: "IMPORT" }).then(({ status, errormsg }) => {
|
||||
if (status) {
|
||||
message.success("操作成功");
|
||||
this.handleHeaderSettings({ sourceType: "IMPORT" });
|
||||
} else {
|
||||
message.error(errormsg || "操作失败");
|
||||
}
|
||||
});
|
||||
break;
|
||||
case "setting":
|
||||
const { state, props } = this.setItemRef;
|
||||
let currentSettingFields = [];
|
||||
const { selectItem } = state, { dataSource } = props;
|
||||
_.forEach(dataSource, item => {
|
||||
currentSettingFields = _.map([...currentSettingFields, ...item.items], child => {
|
||||
return {
|
||||
id: child.id,
|
||||
checked: selectItem.includes(child.id)
|
||||
};
|
||||
});
|
||||
});
|
||||
const payload = { currentSettingFields, sourceType: "IMPORT" };
|
||||
saveAttendanceFieldSettingAsDefault(payload).then(({ status, errormsg }) => {
|
||||
if (status) {
|
||||
message.success("操作成功");
|
||||
} else {
|
||||
message.error(errormsg || "操作失败");
|
||||
}
|
||||
});
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
handleSave = () => {
|
||||
const { state, props } = this.setItemRef;
|
||||
let currentSettingFields = [];
|
||||
const { selectItem } = state, { dataSource } = props;
|
||||
_.forEach(dataSource, item => {
|
||||
currentSettingFields = _.map([...currentSettingFields, ...item.items], child => {
|
||||
return {
|
||||
id: child.id,
|
||||
checked: selectItem.includes(child.id)
|
||||
};
|
||||
});
|
||||
});
|
||||
const payload = { currentSettingFields, sourceType: "IMPORT" };
|
||||
saveAttendanceFieldSetting(payload).then(({ status, errormsg }) => {
|
||||
if (status) {
|
||||
message.success("保存成功");
|
||||
this.handleCloseSettings();
|
||||
} else {
|
||||
message.error(errormsg || "保存失败");
|
||||
}
|
||||
});
|
||||
};
|
||||
/*
|
||||
* Author: 黎永顺
|
||||
* Description: 考勤数据引用
|
||||
* Params:
|
||||
* Date: 2023/3/7
|
||||
*/
|
||||
handleQuoteAttendanceData = (payload) => {
|
||||
const { attendanceReferencePayload } = this.state;
|
||||
this.setState({ attendanceReferencePayload: { ...attendanceReferencePayload, ...payload } });
|
||||
};
|
||||
handleCloseQuoteModal = (isRefresh) => {
|
||||
const { attendanceReferencePayload } = this.state;
|
||||
this.setState({ attendanceReferencePayload: { ...attendanceReferencePayload, visible: false } }, () => {
|
||||
isRefresh && this.getAttendanceList();
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
const {
|
||||
dataSource, columns, pageInfo, loading, importData, importFormPayload, fieldSetPayload,
|
||||
attendanceReferencePayload, attendanceViewPayload
|
||||
} = this.state;
|
||||
const { showOperateBtn, salaryYearMonth } = this.props;
|
||||
const pagination = {
|
||||
...pageInfo,
|
||||
showTotal: total => `共 ${total} 条`,
|
||||
showQuickJumper: true,
|
||||
showSizeChanger: true,
|
||||
pageSizeOptions: ["10", "20", "50", "100"],
|
||||
onShowSizeChange: (current, pageSize) => {
|
||||
this.setState({
|
||||
pageInfo: { ...pageInfo, current, pageSize }
|
||||
}, () => this.getAttendanceList({ salaryYearMonth: _.compact(salaryYearMonth) }));
|
||||
},
|
||||
onChange: current => {
|
||||
this.setState({
|
||||
pageInfo: { ...pageInfo, current }
|
||||
}, () => this.getAttendanceList({ salaryYearMonth: _.compact(salaryYearMonth) }));
|
||||
}
|
||||
};
|
||||
return (
|
||||
<React.Fragment>
|
||||
<WeaTable
|
||||
columns={[
|
||||
...columns,
|
||||
{
|
||||
title: "操作",
|
||||
width: 120,
|
||||
dataIndex: "operate",
|
||||
render: (_, record) => {
|
||||
return (
|
||||
<div className="linkWapper">
|
||||
<a href="javascript: void(0);" onClick={() => this.handleViewAttendanceData(record)}>查看</a>
|
||||
{showOperateBtn &&
|
||||
<a href="javascript: void(0);" onClick={() => this.handleDeleteAttendanceData(record)}>删除</a>
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
]}
|
||||
dataSource={dataSource}
|
||||
pagination={pagination}
|
||||
loading={loading.query}
|
||||
/>
|
||||
{/* 考勤引用导入 */}
|
||||
<ImportModal {...importData} setStep={this.setStep} onFinish={this.handleFinish}
|
||||
previewImport={this.handlePreviewImport} importFile={this.handleImport}
|
||||
templateLink={this.handleTemplateLinkClick} onCancel={this.handleFinish}
|
||||
headerSetCompoent={<HeaderSet
|
||||
loading={loading.headset}
|
||||
onSetClick={() => this.handleHeaderSettings({ sourceType: "IMPORT" })}/>}
|
||||
renderFormComponent={() => <ImportFormOptions
|
||||
{...importFormPayload}
|
||||
onChangeImportForm={this.handleChangeImportPayload}/>
|
||||
}
|
||||
/>
|
||||
{/* 表头设置 */}
|
||||
<SelectItemModal {...fieldSetPayload}
|
||||
onCancel={this.handleCloseSettings}
|
||||
onSearchItemSet={this.handleSearchItemSet}
|
||||
onShowOnlyChecked={this.handleShowOnlyChecked}
|
||||
onMoreOpts={this.handleMoreOpts} onSave={this.handleSave}
|
||||
/>
|
||||
{/* 考勤数据引用 */}
|
||||
<AttendanceRefrenceDataModal
|
||||
{...attendanceReferencePayload}
|
||||
onCancel={this.handleCloseQuoteModal}
|
||||
/>
|
||||
{/* 考勤数据查看 */}
|
||||
<AttendanceDataViewSlide
|
||||
{...attendanceViewPayload}
|
||||
showOperateBtn={showOperateBtn}
|
||||
onClose={() => this.setState({
|
||||
attendanceViewPayload: {
|
||||
...attendanceViewPayload,
|
||||
visible: false,
|
||||
attendQuoteId: ""
|
||||
}
|
||||
})}
|
||||
/>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default AttendanceDataComp;
|
||||
|
|
@ -0,0 +1,143 @@
|
|||
/*
|
||||
* Author: 黎永顺
|
||||
* name: 考勤引用数据查看
|
||||
* Description:
|
||||
* Date: 2023/3/7
|
||||
*/
|
||||
import React, { Component } from "react";
|
||||
import { WeaFormItem, WeaInput, WeaInputSearch, WeaSlideModal } from "ecCom";
|
||||
import { Button } from "antd";
|
||||
import SlideModalTitle from "../../../../components/slideModalTitle";
|
||||
import { viewAttendQuote } from "../../../../apis/attendance";
|
||||
import UnifiedTable from "../../../../components/UnifiedTable";
|
||||
import "./index.less";
|
||||
|
||||
class AttendanceDataViewSlide extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
loading: {
|
||||
query: false
|
||||
},
|
||||
keyword: "",
|
||||
dataSource: [],
|
||||
columns: [],
|
||||
pageInfo: {
|
||||
current: 1, pageSize: 10, total: 0
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps, nextContext) {
|
||||
if (nextProps.visible !== this.props.visible && nextProps.visible) this.viewAttendQuote({}, nextProps);
|
||||
}
|
||||
|
||||
viewAttendQuote = (extraPayload = {}, props) => {
|
||||
const { loading, pageInfo, keyword } = this.state;
|
||||
const { attendQuoteId } = props;
|
||||
this.setState({ loading: { ...loading, query: true } });
|
||||
viewAttendQuote({ ...pageInfo, attendQuoteId, keyword, ...extraPayload }).then(({ status, data }) => {
|
||||
this.setState({ loading: { ...loading, query: false } });
|
||||
if (status) {
|
||||
const { columns, list: dataSource, pageNum: current, pageSize, total } = data.pageInfo;
|
||||
this.setState({
|
||||
pageInfo: { ...pageInfo, current, pageSize, total },
|
||||
dataSource,
|
||||
columns
|
||||
});
|
||||
}
|
||||
}).catch(() => this.setState({ loading: { ...loading, query: false } }));
|
||||
};
|
||||
renderCustomOperate = () => {
|
||||
const { keyword } = this.state;
|
||||
const { showOperateBtn } = this.props;
|
||||
return ([
|
||||
<div style={{ display: "inline-block" }}>
|
||||
{showOperateBtn && <Button type="primary" onClick={this.handleExportAttendQuote}>导出全部</Button>}
|
||||
<WeaInputSearch
|
||||
value={keyword}
|
||||
style={{ marginLeft: 10 }}
|
||||
placeholder="请输入姓名/部门/工号/手机号"
|
||||
onChange={keyword => this.setState({ keyword })}
|
||||
onSearch={() => this.viewAttendQuote({ current: 1 }, this.props)}
|
||||
/>
|
||||
</div>
|
||||
]);
|
||||
};
|
||||
handleExportAttendQuote = () => {
|
||||
if (!this.handleDebounce) {
|
||||
this.handleDebounce = _.debounce(() => {
|
||||
const { attendQuoteId } = this.props;
|
||||
const url = `${window.location.origin}/api/bs/hrmsalary/attendQuote/export?attendQuoteId=${attendQuoteId}`;
|
||||
window.open(url, "_self");
|
||||
this.handleDebounce = null;
|
||||
}, 500);
|
||||
}
|
||||
this.handleDebounce();
|
||||
};
|
||||
|
||||
render() {
|
||||
const { showOperateBtn, salaryYearMonth, ...extra } = this.props;
|
||||
const { columns, dataSource, loading, pageInfo } = this.state;
|
||||
const pagination = {
|
||||
...pageInfo,
|
||||
showTotal: (total) => `共 ${total} 条`,
|
||||
pageSizeOptions: ["10", "20", "50", "100"],
|
||||
showSizeChanger: true,
|
||||
showQuickJumper: true,
|
||||
onShowSizeChange: (current, pageSize) => {
|
||||
this.setState({
|
||||
pageInfo: { ...pageInfo, current, pageSize }
|
||||
}, () => this.viewAttendQuote({}, this.props));
|
||||
},
|
||||
onChange: (current) => {
|
||||
this.setState({
|
||||
pageInfo: { ...pageInfo, current }
|
||||
}, () => this.viewAttendQuote({}, this.props));
|
||||
}
|
||||
};
|
||||
return (
|
||||
<WeaSlideModal
|
||||
{...extra}
|
||||
className="attendanceSlideWrapper"
|
||||
top={0}
|
||||
measureT="%"
|
||||
width={80}
|
||||
measureX="%"
|
||||
height={100}
|
||||
measureY="%"
|
||||
direction="right"
|
||||
title={
|
||||
<SlideModalTitle
|
||||
subtitle="考勤数据"
|
||||
editable={false}
|
||||
showOperateBtn={showOperateBtn}
|
||||
customOperate={this.renderCustomOperate()}
|
||||
/>
|
||||
}
|
||||
content={
|
||||
<div>
|
||||
<WeaFormItem label="考勤周期" labelCol={{ span: 4 }} wrapperCol={{ span: 20 }} underline>
|
||||
<WeaInput value={salaryYearMonth} viewAttr={1}/>
|
||||
</WeaFormItem>
|
||||
<UnifiedTable
|
||||
rowKey="id"
|
||||
columns={_.map(columns, item => ({
|
||||
...item,
|
||||
render: (text) => {
|
||||
return <span className="ellipsis" title={text}> {text} </span>;
|
||||
}
|
||||
}))}
|
||||
dataSource={dataSource}
|
||||
pagination={pagination}
|
||||
loading={loading.query}
|
||||
xWidth={columns.length * 180}
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default AttendanceDataViewSlide;
|
||||
|
|
@ -0,0 +1,230 @@
|
|||
/*
|
||||
* Author: 黎永顺
|
||||
* name: 考勤数据引用
|
||||
* Description:
|
||||
* Date: 2023/3/1
|
||||
*/
|
||||
import React, { Component } from "react";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import { WeaDialog } from "ecCom";
|
||||
import { Button, message } from "antd";
|
||||
import { reFrenceConditions } from "../columns";
|
||||
import { getSearchs } from "../../../../util";
|
||||
import {
|
||||
checkOperation,
|
||||
getAttendanceFieldSettingList,
|
||||
getLedgerList, returnToAttendanceFieldSettingDefault, saveAttendanceFieldSetting, saveAttendanceFieldSettingAsDefault,
|
||||
syncAttendanceRefer
|
||||
} from "../../../../apis/attendance";
|
||||
import SelectItemModal from "../../../../components/selectItemsModal";
|
||||
import SelectItemsWrapper from "../../../../components/selectItemsModal/selectItemsWrapper";
|
||||
import "./index.less";
|
||||
|
||||
@inject("attendanceStore")
|
||||
@observer
|
||||
class AttendanceRefrenceDataModal extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
loading: false,
|
||||
headerSetLoading: false,
|
||||
condition: [],
|
||||
headerSetPayload: { visible: false, title: "", children: null }
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.getLedgerList();
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps, nextContext) {
|
||||
if (nextProps.visible !== this.props.visible && nextProps.visible) this.handleResetForm();
|
||||
}
|
||||
|
||||
getLedgerList = () => {
|
||||
const { attendanceStore: { refenceform } } = this.props;
|
||||
getLedgerList().then(({ status, data }) => {
|
||||
if (status) {
|
||||
this.setState({
|
||||
condition: _.map(reFrenceConditions, (item) => {
|
||||
const { items } = item;
|
||||
return {
|
||||
...item,
|
||||
items: _.map(items, child => {
|
||||
const { domkey } = child;
|
||||
if (domkey[0] === "salarySobId") {
|
||||
return { ...child, options: _.map(data, it => ({ key: it.id, showname: it.content })) };
|
||||
}
|
||||
return { ...child };
|
||||
})
|
||||
};
|
||||
})
|
||||
}, () => refenceform.initFormFields(this.state.condition));
|
||||
}
|
||||
});
|
||||
};
|
||||
/*
|
||||
* Author: 黎永顺
|
||||
* Description: 同步考勤数据
|
||||
* Params:
|
||||
* Date: 2023/3/1
|
||||
*/
|
||||
handleSubmitFields = () => {
|
||||
const { attendanceStore: { refenceform }, onCancel } = this.props;
|
||||
refenceform.validateForm().then(f => {
|
||||
if (f.isValid) {
|
||||
const payload = refenceform.getFormParams();
|
||||
const checkPayload = { salaryYearMonthStr: payload.salaryYearMonth, salarySobId: payload.salarySobId };
|
||||
this.setState({ loading: true });
|
||||
checkOperation(checkPayload).then(({ status, errormsg: errormessage }) => {
|
||||
if (status) {
|
||||
syncAttendanceRefer(payload).then(({ status, errormsg }) => {
|
||||
this.setState({ loading: false });
|
||||
if (status) {
|
||||
message.success("同步成功");
|
||||
onCancel(true);
|
||||
} else {
|
||||
message.error(errormsg || "同步失败");
|
||||
}
|
||||
}).catch(() => this.setState({ loading: false }));
|
||||
} else {
|
||||
this.setState({ loading: false });
|
||||
message.error(errormessage);
|
||||
}
|
||||
}).catch(() => this.setState({ loading: false }));
|
||||
} else {
|
||||
f.showErrors();
|
||||
}
|
||||
});
|
||||
};
|
||||
handleResetForm = () => {
|
||||
const { attendanceStore: { refenceform } } = this.props;
|
||||
refenceform.resetForm();
|
||||
};
|
||||
/*
|
||||
* Author: 黎永顺
|
||||
* Description: 表头设置
|
||||
* Params:
|
||||
* Date: 2023/3/8
|
||||
*/
|
||||
handleHeaderSetting = () => {
|
||||
const { headerSetPayload } = this.state;
|
||||
this.setState({ headerSetLoading: true });
|
||||
getAttendanceFieldSettingList({ sourceType: "QUOTE" }).then(({ status, data }) => {
|
||||
this.setState({ headerSetLoading: false });
|
||||
if (status) {
|
||||
this.setState({
|
||||
headerSetPayload: {
|
||||
...headerSetPayload,
|
||||
visible: true, title: "引用考勤字段设置",
|
||||
children: <SelectItemsWrapper
|
||||
ref={dom => this.setItemRef = dom}
|
||||
dataSource={data}
|
||||
onSelectGroupAll={this.handleSelectGroupAll}
|
||||
onSelectItem={this.handleSelectItem}
|
||||
/>
|
||||
}
|
||||
});
|
||||
}
|
||||
}).catch(() => this.setState({ headerSetLoading: false }));
|
||||
};
|
||||
handleCloseSettings = () => {
|
||||
const { headerSetPayload } = this.state;
|
||||
this.setState({
|
||||
headerSetPayload: {
|
||||
...headerSetPayload,
|
||||
visible: false, title: "", children: null
|
||||
}
|
||||
});
|
||||
};
|
||||
handleSearchItemSet = (val) => this.setItemRef.handleSearchItemSet(val);
|
||||
handleShowOnlyChecked = (checked) => this.setItemRef.handleShowOnlyChecked(checked);
|
||||
handleSelectGroupAll = (groupId, checked) => this.setItemRef.handleSelectGroupAll(groupId, checked);
|
||||
handleSelectItem = (id, checked) => this.setItemRef.handleSelectItem(id, checked);
|
||||
handleMoreOpts = (key) => {
|
||||
switch (key) {
|
||||
case "recovery":
|
||||
returnToAttendanceFieldSettingDefault({ sourceType: "QUOTE" }).then(({ status, errormsg }) => {
|
||||
if (status) {
|
||||
message.success("操作成功");
|
||||
this.handleHeaderSetting({ sourceType: "QUOTE" });
|
||||
} else {
|
||||
message.error(errormsg || "操作失败");
|
||||
}
|
||||
});
|
||||
break;
|
||||
case "setting":
|
||||
const { state, props } = this.setItemRef;
|
||||
let currentSettingFields = [];
|
||||
const { selectItem } = state, { dataSource } = props;
|
||||
_.forEach(dataSource, item => {
|
||||
currentSettingFields = _.map([...currentSettingFields, ...item.items], child => {
|
||||
return {
|
||||
id: child.id,
|
||||
checked: selectItem.includes(child.id)
|
||||
};
|
||||
});
|
||||
});
|
||||
const payload = { currentSettingFields, sourceType: "QUOTE" };
|
||||
saveAttendanceFieldSettingAsDefault(payload).then(({ status, errormsg }) => {
|
||||
if (status) {
|
||||
message.success("操作成功");
|
||||
} else {
|
||||
message.error(errormsg || "操作失败");
|
||||
}
|
||||
});
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
handleSave = () => {
|
||||
const { state, props } = this.setItemRef;
|
||||
let currentSettingFields = [];
|
||||
const { selectItem } = state, { dataSource } = props;
|
||||
_.forEach(dataSource, item => {
|
||||
currentSettingFields = _.map([...currentSettingFields, ...item.items], child => {
|
||||
return {
|
||||
id: child.id,
|
||||
checked: selectItem.includes(child.id)
|
||||
};
|
||||
});
|
||||
});
|
||||
const payload = { currentSettingFields, sourceType: "QUOTE" };
|
||||
saveAttendanceFieldSetting(payload).then(({ status, errormsg }) => {
|
||||
if (status) {
|
||||
message.success("保存成功");
|
||||
this.handleCloseSettings();
|
||||
} else {
|
||||
message.error(errormsg || "保存失败");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
const { condition, loading, headerSetLoading, headerSetPayload } = this.state;
|
||||
const { attendanceStore: { refenceform } } = this.props;
|
||||
const buttons = [
|
||||
<Button type="primary" onClick={this.handleSubmitFields} loading={loading}>同步</Button>,
|
||||
<Button type="ghost" onClick={this.handleHeaderSetting} loading={headerSetLoading}>表头设置</Button>
|
||||
];
|
||||
return (
|
||||
<WeaDialog
|
||||
{...this.props} style={{ width: 440, height: 156 }}
|
||||
buttons={buttons} hasScroll initLoadCss
|
||||
className="modalWrapper"
|
||||
>
|
||||
{getSearchs(refenceform, condition, 1)}
|
||||
{/* 表头设置 */}
|
||||
<SelectItemModal {...headerSetPayload}
|
||||
onCancel={this.handleCloseSettings}
|
||||
onSearchItemSet={this.handleSearchItemSet}
|
||||
onShowOnlyChecked={this.handleShowOnlyChecked}
|
||||
onMoreOpts={this.handleMoreOpts} onSave={this.handleSave}
|
||||
/>
|
||||
</WeaDialog>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default AttendanceRefrenceDataModal;
|
||||
|
|
@ -0,0 +1,139 @@
|
|||
/*
|
||||
* Author: 黎永顺
|
||||
* name:字段管理
|
||||
* Description:
|
||||
* Date: 2023/2/24
|
||||
*/
|
||||
import React, { Component } from "react";
|
||||
import { WeaCheckbox, WeaTable } from "ecCom";
|
||||
import { Col, message, Row } from "antd";
|
||||
import AttendanceCustomFieldsModal from "./attendanceCustomFieldsModal";
|
||||
import { getAttendanceFieldList, updateAttendanceFieldStatus } from "../../../../apis/attendance";
|
||||
import TipLabel from "../../../../components/TipLabel";
|
||||
import { fieldsColumns } from "../columns";
|
||||
|
||||
class FieldMangComp extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
loading: {
|
||||
query: false
|
||||
},
|
||||
dataSource: [{}],
|
||||
columns: fieldsColumns,
|
||||
pageInfo: {
|
||||
current: 1,
|
||||
pageSize: 10,
|
||||
total: 0
|
||||
},
|
||||
addPayload: {
|
||||
visible: false,
|
||||
title: "新建考勤自定义字段"
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.getAttendanceFieldList();
|
||||
}
|
||||
|
||||
getAttendanceFieldList = (extraPayload = {}) => {
|
||||
const { loading, pageInfo } = this.state;
|
||||
const module = { ...pageInfo, ...extraPayload };
|
||||
this.setState({ loading: { ...loading, query: true } });
|
||||
getAttendanceFieldList(module).then(({ status, data }) => {
|
||||
this.setState({ loading: { ...loading, query: false } });
|
||||
if (status) {
|
||||
const { pageInfo: pageInfoData } = data;
|
||||
const { list: dataSource, columns, pageNum: current, pageSize, total } = pageInfoData;
|
||||
this.setState({
|
||||
pageInfo: { ...pageInfo, current, pageSize, total },
|
||||
dataSource, columns
|
||||
});
|
||||
}
|
||||
}).catch(() => this.setState({ loading: { ...loading, query: false } }));
|
||||
};
|
||||
handleTriggerAttendFileds = () => {
|
||||
const { addPayload } = this.state;
|
||||
this.setState({ addPayload: { ...addPayload, visible: !addPayload.visible } });
|
||||
};
|
||||
handleAttendanceFieldSwitch = ({ id }, enableStatus) => {
|
||||
const payload = { id, enableStatus: enableStatus === "1" };
|
||||
updateAttendanceFieldStatus(payload).then(({ status, errormsg }) => {
|
||||
if (status) {
|
||||
message.success("操作成功");
|
||||
this.getAttendanceFieldList();
|
||||
} else {
|
||||
message.error(errormsg || "操作失败");
|
||||
}
|
||||
});
|
||||
};
|
||||
getColumns = () => {
|
||||
const { columns } = this.state;
|
||||
const { showOperateBtn } = this.props;
|
||||
return _.map(_.filter(columns, item => !!item.display), child => ({
|
||||
...child,
|
||||
render: (text, record) => {
|
||||
switch (child.dataIndex) {
|
||||
case "enableStatus":
|
||||
return (
|
||||
<WeaCheckbox
|
||||
value={text} display="switch" disabled={!showOperateBtn}
|
||||
onChange={value => this.handleAttendanceFieldSwitch(record, value)}
|
||||
/>
|
||||
);
|
||||
default:
|
||||
return <div dangerouslySetInnerHTML={{ __html: text }}/>;
|
||||
}
|
||||
}
|
||||
}));
|
||||
};
|
||||
|
||||
render() {
|
||||
const { dataSource, pageInfo, loading, addPayload } = this.state;
|
||||
const { fieldName } = this.props;
|
||||
const pagination = {
|
||||
...pageInfo,
|
||||
showTotal: total => `共 ${total} 条`,
|
||||
showQuickJumper: true,
|
||||
showSizeChanger: true,
|
||||
pageSizeOptions: ["10", "20", "50", "100"],
|
||||
onShowSizeChange: (current, pageSize) => {
|
||||
this.setState({
|
||||
pageInfo: { ...pageInfo, current, pageSize }
|
||||
}, () => this.getAttendanceFieldList({ fieldName }));
|
||||
},
|
||||
onChange: current => {
|
||||
this.setState({
|
||||
pageInfo: { ...pageInfo, current }
|
||||
}, () => this.getAttendanceFieldList({ fieldName }));
|
||||
}
|
||||
};
|
||||
return (
|
||||
<Row gutter={20}>
|
||||
<Col xs={24} sm={24} md={16} lg={18}>
|
||||
<WeaTable
|
||||
columns={this.getColumns()}
|
||||
dataSource={dataSource}
|
||||
pagination={pagination}
|
||||
loading={loading.query}
|
||||
/>
|
||||
<AttendanceCustomFieldsModal
|
||||
{...addPayload} onCancel={this.handleTriggerAttendFileds}
|
||||
onRefresh={this.getAttendanceFieldList}
|
||||
/>
|
||||
</Col>
|
||||
<Col xs={24} sm={24} md={8} lg={6}>
|
||||
<TipLabel
|
||||
tipList={[
|
||||
"1、考勤字段包含自定义字段和考勤模块的统计字段,所有字段不可重名;",
|
||||
"2、停用自定义字段将影响其参与计算的账套核算;"
|
||||
]}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default FieldMangComp;
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Author: 黎永顺
|
||||
* name: 考情数据导入的,表单选项
|
||||
* Description:
|
||||
* Date: 2023/3/3
|
||||
*/
|
||||
import React, { Component } from "react";
|
||||
import { WeaFormItem, WeaInput, WeaSearchGroup } from "ecCom";
|
||||
import { DataCollectionDatePicker, DataCollectionSelect } from "../../cumDeduct";
|
||||
import "./index.less";
|
||||
|
||||
const Input = (label, value, labelCol = 8, wrapperCol = 16) => {
|
||||
return (
|
||||
<WeaFormItem label={label} labelCol={{ span: labelCol }} wrapperCol={{ span: wrapperCol }}>
|
||||
<WeaInput viewAttr={1} value={value}/>
|
||||
</WeaFormItem>
|
||||
);
|
||||
};
|
||||
|
||||
class ImportFormOptions extends Component {
|
||||
screenChange = ({ key, value }) => {
|
||||
const { onChangeImportForm } = this.props;
|
||||
onChangeImportForm(key, value);
|
||||
};
|
||||
|
||||
render() {
|
||||
const { salarySobList = [], salaryYearMonth, salarySobId, salaryCycle, attendCycle } = this.props;
|
||||
const items = [
|
||||
{
|
||||
com: DataCollectionDatePicker({
|
||||
label: "薪资所属月",
|
||||
value: salaryYearMonth,
|
||||
onChange: this.screenChange,
|
||||
key: "salaryYearMonth",
|
||||
screen: false
|
||||
})
|
||||
},
|
||||
{
|
||||
com: DataCollectionSelect({
|
||||
label: "薪资账套",
|
||||
value: salarySobId || "",
|
||||
onChange: this.screenChange,
|
||||
options: [{ key: "", showname: "" }, ...salarySobList],
|
||||
key: "salarySobId"
|
||||
})
|
||||
},
|
||||
{ com: Input("薪资周期", salaryCycle) },
|
||||
{ com: Input("考勤周期", attendCycle, 10, 14) }
|
||||
];
|
||||
return (
|
||||
<WeaSearchGroup className="attendanceFormWrapper" showGroup needTigger={false} items={items}
|
||||
col={2}/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default ImportFormOptions;
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
.modalWrapper {
|
||||
.wea-select, .ant-select-selection, .ant-select {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.wea-date-picker {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.wea-select {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.ant-select-selection {
|
||||
height: 30px;
|
||||
border-radius: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.attendanceFormWrapper {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.attendanceSlideWrapper {
|
||||
.wea-slide-modal-title {
|
||||
height: initial;
|
||||
line-height: initial;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.rodal-close {
|
||||
z-index: 99;
|
||||
top: 10px !important;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@media (min-width: 1260px) {
|
||||
.attendanceSlideWrapper {
|
||||
.reqTopWrapper .wea-new-top-req-title > div:first-child > div {
|
||||
max-width: 100% !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 1060px) and (max-width: 1260px) {
|
||||
.attendanceSlideWrapper {
|
||||
.reqTopWrapper .wea-new-top-req-title > div:first-child > div {
|
||||
max-width: calc(100% - 96px) !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,115 +0,0 @@
|
|||
import React from "react";
|
||||
import { Row, Col, Table, DatePicker } from "antd";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import {
|
||||
WeaInput,
|
||||
WeaTextarea,
|
||||
WeaSearchGroup,
|
||||
WeaSelect,
|
||||
WeaCheckbox,
|
||||
WeaTable
|
||||
} from "ecCom";
|
||||
import { slideColumns, slideDataSource, columns } from "./columns";
|
||||
import "./editSlideContent.less";
|
||||
|
||||
// import { WeaTableNew } from "comsMobx"
|
||||
// const WeaTable = WeaTableNew.WeaTable;
|
||||
import moment from "moment";
|
||||
|
||||
const { MonthPicker } = DatePicker;
|
||||
|
||||
let emptyItem = {
|
||||
incomeLowerLimit: "0.00",
|
||||
incomeUpperLimit: "0.00",
|
||||
dutyFreeValue: "0.00",
|
||||
dutyFreeRate: "0.00",
|
||||
taxableIncomeLl: "0.00",
|
||||
taxableIncomeUl: "0.00",
|
||||
taxRate: "0.00",
|
||||
taxDeduction: "0.00"
|
||||
};
|
||||
|
||||
@inject("attendanceStore")
|
||||
@observer
|
||||
export default class EditSlideContent extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
// 初始化渲染页面
|
||||
const { attendanceStore: { viewAttendQuote } } = this.props;
|
||||
viewAttendQuote({ attendQuoteId: this.props.id });
|
||||
}
|
||||
|
||||
getColumns(columns) {
|
||||
let result = [...columns];
|
||||
return result.filter(item => item.hide == "false");
|
||||
}
|
||||
|
||||
getScrollWidth() {
|
||||
const { attendanceStore } = this.props;
|
||||
const { attendQuoteDetailTableStore } = attendanceStore;
|
||||
return (
|
||||
this.getColumns(
|
||||
attendQuoteDetailTableStore.columns
|
||||
? attendQuoteDetailTableStore.columns
|
||||
: []
|
||||
).length * 150
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
attendanceStore,
|
||||
attendanceStore: { viewAttendQuote }
|
||||
} = this.props;
|
||||
const {
|
||||
attendQuoteDetailPageInfo,
|
||||
attendQuoteDetailTableStore
|
||||
} = attendanceStore;
|
||||
|
||||
const pagination = {
|
||||
total: attendQuoteDetailPageInfo.total,
|
||||
showTotal: total => `共 ${total} 条`,
|
||||
showSizeChanger: true,
|
||||
pageSizeOptions: ["10", "20", "50", "100"],
|
||||
onShowSizeChange: (current, pageSize) => {
|
||||
viewAttendQuote({ attendQuoteId: this.props.id, current, pageSize });
|
||||
},
|
||||
onChange: current => {
|
||||
viewAttendQuote({
|
||||
attendQuoteId: this.props.id,
|
||||
current,
|
||||
pageSize: attendQuoteDetailPageInfo.pageSize
|
||||
});
|
||||
}
|
||||
};
|
||||
return (
|
||||
<div className="attendSlide">
|
||||
<div className="titleWrapper">
|
||||
{this.props.salaryYearMonth != "" &&
|
||||
<div className="slideLeftTitle">
|
||||
考勤周期: {this.props.salaryYearMonth}
|
||||
</div>}
|
||||
</div>
|
||||
<div>
|
||||
<WeaTable
|
||||
columns={this.getColumns(
|
||||
attendQuoteDetailTableStore.columns
|
||||
? attendQuoteDetailTableStore.columns
|
||||
: []
|
||||
)}
|
||||
dataSource={
|
||||
attendQuoteDetailPageInfo.list
|
||||
? attendQuoteDetailPageInfo.list
|
||||
: []
|
||||
}
|
||||
pagination={pagination}
|
||||
scroll={{ x: this.getScrollWidth() }}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
.attendSlide {
|
||||
.titleWrapper {
|
||||
height: 47px;
|
||||
line-height: 47px;
|
||||
overflow: hidden;
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
.slideLeftTitle {
|
||||
float: left;
|
||||
}
|
||||
.rightTitle {
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
.weaRangePickerWrapper {
|
||||
display: inline-block;
|
||||
.monthPickerWrapper {
|
||||
width: 100px;
|
||||
display: inline-block;
|
||||
}
|
||||
.betweenLable {
|
||||
margin-left: 10px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
import React from 'react'
|
||||
import { Modal } from 'antd'
|
||||
import SelectItemModal, { items } from '../../../components/selectItemsModal/selectItemsWrapper';
|
||||
|
||||
|
||||
export default class HeaderSetModal extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<Modal width={800} visible={this.props.visible} onCancel={this.props.onCancel}>
|
||||
<SelectItemsWrapper items={items} title={"考勤模块"}/>
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,33 +1,66 @@
|
|||
.attendenceImportWrapper{
|
||||
.wea-dialog-body{
|
||||
.attendanceRefWrapper {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.wea-form-item {
|
||||
padding: 8px 16px;
|
||||
|
||||
.to {
|
||||
padding: 0 10px
|
||||
}
|
||||
}
|
||||
|
||||
.tableWrapper {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.linkWapper {
|
||||
& > a:first-child {
|
||||
padding-right: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.attendenceImportWrapper {
|
||||
.wea-dialog-body {
|
||||
padding: 16px 120px;
|
||||
.wea-select, .ant-select, .ant-select-selection{
|
||||
|
||||
.wea-select, .ant-select, .ant-select-selection {
|
||||
width: 100%;
|
||||
}
|
||||
.ant-select-selection{
|
||||
|
||||
.ant-select-selection {
|
||||
border-radius: 0;
|
||||
height: 30px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//导入字段设置
|
||||
.fieldSetWrapper{
|
||||
.wea-dialog-body{
|
||||
.fieldSetWrapper {
|
||||
.wea-dialog-body {
|
||||
padding: 16px 20px;
|
||||
}
|
||||
.ant-modal-footer button{
|
||||
margin-right: 0!important;
|
||||
|
||||
.ant-modal-footer button {
|
||||
margin-right: 0 !important;
|
||||
}
|
||||
.ant-btn-group{
|
||||
margin-left: 10px!important;
|
||||
|
||||
.ant-btn-group {
|
||||
margin-left: 10px !important;
|
||||
}
|
||||
.searchWrapper{
|
||||
|
||||
.searchWrapper {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.allInWrapper{
|
||||
|
||||
.allInWrapper {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
margin-top: 10px;
|
||||
|
|
@ -35,15 +68,17 @@
|
|||
}
|
||||
|
||||
//新建考勤自定义字段弹框
|
||||
.itemManageModalWrapper{
|
||||
.wea-select,.ant-select-selection,.ant-select{
|
||||
.itemManageModalWrapper {
|
||||
.wea-select, .ant-select-selection, .ant-select {
|
||||
width: 100%;
|
||||
}
|
||||
.wea-select{
|
||||
|
||||
.wea-select {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
}
|
||||
.ant-select-selection{
|
||||
|
||||
.ant-select-selection {
|
||||
height: 30px;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,124 +0,0 @@
|
|||
import React from "react";
|
||||
import { Button, Col, Row, Switch } from "antd";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import { WeaDialog, WeaInput, WeaSelect } from "ecCom";
|
||||
import "./index.less";
|
||||
|
||||
@inject("attendanceStore")
|
||||
@observer
|
||||
export default class ItemMangeFormModal extends React.Component {
|
||||
componentWillMount() {
|
||||
const { attendanceStore: { currentItem, currentItemOperate } } = this.props;
|
||||
if (currentItemOperate == "add") {
|
||||
this.state = {
|
||||
request: {
|
||||
fieldName: "",
|
||||
fieldType: "1",
|
||||
enableStatus: 0,
|
||||
description: ""
|
||||
}
|
||||
};
|
||||
} else {
|
||||
this.state = {
|
||||
request: currentItem
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
handleChange(params) {
|
||||
const { request } = this.state;
|
||||
let result = { ...request, ...params };
|
||||
this.setState({ request: result });
|
||||
}
|
||||
|
||||
convertFieldType = (fileTypeStr) => {
|
||||
if (fileTypeStr == "数值") {
|
||||
return "1";
|
||||
} else if (fileTypeStr == "文本") {
|
||||
return "2";
|
||||
} else if (fileTypeStr == "1" || fileTypeStr == "2") {
|
||||
return fileTypeStr;
|
||||
}
|
||||
return "";
|
||||
};
|
||||
|
||||
render() {
|
||||
const options = [
|
||||
{
|
||||
key: "1",
|
||||
selected: true,
|
||||
showname: "数值"
|
||||
},
|
||||
{
|
||||
key: "2",
|
||||
selected: false,
|
||||
showname: "文本"
|
||||
}
|
||||
];
|
||||
const { request } = this.state;
|
||||
const { fieldName, fieldType, enableStatus, description } = request;
|
||||
let fileTypeKey = this.convertFieldType(fieldType);
|
||||
const { attendanceStore: { currentItemOperate } } = this.props;
|
||||
return (
|
||||
<WeaDialog style={{ width: 600 }} visible={this.props.visible} onCancel={this.props.onCancel}
|
||||
title="新建考勤自定义字段"
|
||||
initLoadCss
|
||||
className="itemManageModalWrapper"
|
||||
buttons={[
|
||||
<Button type="primary" onClick={() => {
|
||||
currentItemOperate == "add" ? this.props.onSave(this.state.request) :
|
||||
this.props.onUpdate(this.state.request);
|
||||
}
|
||||
}>保存</Button>
|
||||
]}>
|
||||
<div style={{ padding: "16px 120px" }}>
|
||||
<Row gutter={[10, 10]} style={{ marginBottom: "10px" }}>
|
||||
<Col span={8}>
|
||||
字段名称
|
||||
</Col>
|
||||
<Col span={16}>
|
||||
<WeaInput viewAttr={3} style={{ width: "200px" }} value={fieldName} onChange={(v) => {
|
||||
this.handleChange({ fieldName: v });
|
||||
}}/>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row gutter={[10, 10]} style={{ marginBottom: "10px" }}>
|
||||
<Col span={8}>
|
||||
类型
|
||||
</Col>
|
||||
<Col span={16}>
|
||||
<WeaSelect style={{ width: "200px" }} options={options} value={fileTypeKey}
|
||||
onChange={(v) => this.handleChange({ fieldType: v })}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row gutter={[10, 10]} style={{ marginBottom: "10px" }}>
|
||||
<Col span={8}>
|
||||
是否启用
|
||||
</Col>
|
||||
<Col span={16}>
|
||||
<Switch checked={enableStatus == 1} onChange={(value) => {
|
||||
let enableStatus = 0;
|
||||
if (value) {
|
||||
enableStatus = 1;
|
||||
}
|
||||
this.handleChange({ enableStatus });
|
||||
}}/>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row gutter={[10, 10]} style={{ marginBottom: "10px" }}>
|
||||
<Col span={8}>
|
||||
备注
|
||||
</Col>
|
||||
<Col span={16}>
|
||||
<WeaInput style={{ width: "200px" }} value={description} onChange={(v) => {
|
||||
this.handleChange({ description: v });
|
||||
}}/>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
|
||||
</WeaDialog>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,195 +0,0 @@
|
|||
import React from "react";
|
||||
import { Button, Col, message, Row, Select } from "antd";
|
||||
import moment from "moment";
|
||||
import { WeaDatePicker, WeaDialog, WeaError, WeaInput, WeaSelect } from "ecCom";
|
||||
import SelectItemModal from "../../../components/selectItemsModal";
|
||||
import SelectItemsWrapper from "../../../components/selectItemsModal/selectItemsWrapper";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import { notNull } from "../../../util/validate";
|
||||
|
||||
const { Option } = Select;
|
||||
|
||||
@inject("attendanceStore")
|
||||
@observer
|
||||
export default class RefereAttendFormModal extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
headerSetVisible: false,
|
||||
inited: false,
|
||||
request: {
|
||||
salarySobId: "",
|
||||
salaryYearMonth: moment(new Date()).format("YYYY-MM"),
|
||||
employeeIds: [],
|
||||
description: ""
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
handleHeaderSet() {
|
||||
this.setState({ headerSetVisible: true });
|
||||
this.props.onHeaderSet();
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
const { attendanceStore: { getLedgerList } } = this.props;
|
||||
getLedgerList().then(() => {
|
||||
this.setState({
|
||||
inited: true
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// 请求参数改变事件
|
||||
handleRequestChange(params) {
|
||||
const { request } = this.state;
|
||||
let result = { ...request, ...params };
|
||||
this.setState({ request: result });
|
||||
}
|
||||
|
||||
|
||||
// 同步点击回调
|
||||
handleSync() {
|
||||
const { attendanceStore: { syncAttendanceRefer, checkOperation } } = this.props;
|
||||
if (!this.validate()) {
|
||||
return;
|
||||
}
|
||||
const { salarySobId, salaryYearMonth: salaryYearMonthStr } = this.state.request;
|
||||
const payload = {
|
||||
salaryYearMonthStr,
|
||||
salarySobId
|
||||
};
|
||||
checkOperation(payload).then(({ status, data, errorMsg }) => {
|
||||
if (status && data) {
|
||||
syncAttendanceRefer(this.state.request).then(() => {
|
||||
this.props.onCancel();
|
||||
});
|
||||
} else {
|
||||
message.warning("已经核算过不可操作");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 校验数据
|
||||
validate() {
|
||||
const { request } = this.state;
|
||||
if (!notNull(request.salarySobId) && !notNull(request.salaryYearMonth)) {
|
||||
this.refs.weaError.showError();
|
||||
this.refs.weaError1.showError();
|
||||
return false;
|
||||
}
|
||||
if (!notNull(request.salarySobId)) {
|
||||
this.refs.weaError1.showError();
|
||||
return false;
|
||||
}
|
||||
if (!notNull(request.salaryYearMonth)) {
|
||||
this.refs.weaError.showError();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
render() {
|
||||
const { attendanceStore: { importLedgerList } } = this.props;
|
||||
return (
|
||||
<WeaDialog
|
||||
initLoadCss
|
||||
className="attendenceImportWrapper"
|
||||
style={{ width: 600 }}
|
||||
title="引用考勤数据"
|
||||
buttons={[
|
||||
<Button type="primary" onClick={() => {
|
||||
this.handleSync();
|
||||
}}>同步</Button>,
|
||||
<Button type="default" onClick={() => {
|
||||
this.handleHeaderSet();
|
||||
}}>表头设置</Button>
|
||||
]}
|
||||
visible={this.props.visible}
|
||||
onCancel={this.props.onCancel}>
|
||||
<Row style={{ marginBottom: "10px" }}>
|
||||
<Col span={8}>薪资所属月:</Col>
|
||||
<Col span={16}>
|
||||
<WeaError
|
||||
style={{ width: "100%" }}
|
||||
tipPosition="bottom"
|
||||
ref="weaError"
|
||||
error="请选择薪资所属月">
|
||||
<WeaDatePicker
|
||||
viewAttr={3}
|
||||
format="YYYY-MM"
|
||||
style={{ width: "100%" }}
|
||||
value={this.state.request.salaryYearMonth}
|
||||
onChange={(value) => {
|
||||
if (value === "") this.refs.weaError.showError();
|
||||
this.handleRequestChange({ salaryYearMonth: value });
|
||||
}}
|
||||
/>
|
||||
</WeaError>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row style={{ marginBottom: "10px" }}>
|
||||
<Col span={8}>薪资账套:</Col>
|
||||
<Col span={16}>
|
||||
{
|
||||
this.state.inited &&
|
||||
<WeaError
|
||||
style={{ width: "100%" }}
|
||||
tipPosition="bottom"
|
||||
ref="weaError1"
|
||||
error="请选择薪资账套">
|
||||
<WeaSelect
|
||||
viewAttr={3}
|
||||
value={this.state.request.salarySobId}
|
||||
style={{ width: "100%" }}
|
||||
options={
|
||||
_.isEmpty(importLedgerList) ? [{ key: "", showname: "" }] :
|
||||
[{ key: "", showname: "" }, ..._.map(importLedgerList, it => ({
|
||||
key: it.id,
|
||||
showname: it.content
|
||||
}))]
|
||||
}
|
||||
onChange={(value) => {
|
||||
if (value === "") this.refs.weaError1.showError();
|
||||
this.handleRequestChange({ salarySobId: value });
|
||||
}}/>
|
||||
</WeaError>
|
||||
}
|
||||
</Col>
|
||||
</Row>
|
||||
<Row style={{ marginBottom: "10px" }}>
|
||||
<Col span={8}>备注</Col>
|
||||
<Col span={16}>
|
||||
<WeaInput style={{ width: "100%" }} value={this.state.request.description} onChange={(value) => {
|
||||
this.handleRequestChange({ description: value });
|
||||
}}/>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
|
||||
<SelectItemModal
|
||||
onShowChecked={(value) => {
|
||||
this.props.onShowChecked(value);
|
||||
}}
|
||||
onRestoreDefault={() => {
|
||||
this.props.onRestoreDefault();
|
||||
}}
|
||||
onSetDefault={() => {
|
||||
this.props.onSetDefault();
|
||||
}}
|
||||
onSearch={(value) => {
|
||||
this.props.onSearch(value);
|
||||
}}
|
||||
onSave={(value) => {
|
||||
this.props.onSave(value);
|
||||
}}
|
||||
visible={this.state.headerSetVisible} onCancel={() => this.setState({ headerSetVisible: false })}>
|
||||
<SelectItemsWrapper items={this.props.items} title={"考勤模块"} onChange={(value) => {
|
||||
this.props.onChange(value);
|
||||
}}/>
|
||||
</SelectItemModal>
|
||||
</WeaDialog>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
.tableRecordWrapper {
|
||||
.accumulated {
|
||||
.wea-form-cell-wrapper {
|
||||
& > div:first-child {
|
||||
height: 46px !important;
|
||||
line-height: 46px;
|
||||
}
|
||||
|
||||
& > div:nth-child(2) {
|
||||
//width: 40% !important;
|
||||
|
||||
.wea-form-item-wrapper {
|
||||
display: flex !important;
|
||||
align-items: center;
|
||||
|
||||
.to {
|
||||
padding: 0 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
& > div:last-child {
|
||||
//width: 40% !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,207 @@
|
|||
/*
|
||||
* Author: 黎永顺
|
||||
* name: 数据采集-详情记录页面
|
||||
* Description:
|
||||
* Date: 2023/2/20
|
||||
*/
|
||||
import React, { Component } from "react";
|
||||
import { WeaSearchGroup } from "ecCom";
|
||||
import UnifiedTable from "../../../components/UnifiedTable";
|
||||
import { getTableRecordDate } from "../../../apis/cumDeduct";
|
||||
import { DataCollectionDateRangePick, DataCollectionSelect, Input } from "../cumDeduct";
|
||||
import "./index.less";
|
||||
|
||||
class TableRecord extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
loading: {
|
||||
query: false
|
||||
},
|
||||
width: 0,
|
||||
dataSource: [],
|
||||
columns: [],
|
||||
selectedRowKeys: [],
|
||||
pageInfo: {
|
||||
current: 1, pageSize: 10, total: 0
|
||||
},
|
||||
recordPayload: {
|
||||
accumulatedSpecialAdditionalDeductionId: "",
|
||||
otherTaxExemptDeductionId: "",
|
||||
accumulatedSituationId: "",
|
||||
specialAddDeductionId: "",
|
||||
taxAgentId: "",
|
||||
declareMonth: null,
|
||||
taxYearMonth: null
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.setState({ width: window.innerWidth });
|
||||
this.convertData(this.props);
|
||||
window.addEventListener("resize", this.resizeWidth);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
window.removeEventListener("resize", this.resizeWidth);
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps, nextContext) {
|
||||
this.convertData(nextProps);
|
||||
}
|
||||
|
||||
resizeWidth = (e) => {
|
||||
this.setState({ width: e.target.innerWidth });
|
||||
};
|
||||
|
||||
convertData = (props) => {
|
||||
const { recordPayload } = this.state;
|
||||
const { record, screenParams } = props;
|
||||
const modules = _.reduce(screenParams, (pre, cur) => (_.assign(pre, {
|
||||
[cur]: record[cur],
|
||||
[screenParams[0]]: record.id
|
||||
})), {});
|
||||
this.setState({
|
||||
recordPayload: {
|
||||
...recordPayload,
|
||||
...modules
|
||||
},
|
||||
pageInfo: {
|
||||
current: 1, pageSize: 10, total: 0
|
||||
}
|
||||
}, () => this.getTableRecordData());
|
||||
};
|
||||
|
||||
getTableRecordData = () => {
|
||||
const { loading, pageInfo, recordPayload } = this.state;
|
||||
const { url, screenParams } = this.props;
|
||||
const monthkey = screenParams[screenParams.length - 1];
|
||||
const module = {
|
||||
...pageInfo, ...recordPayload, url,
|
||||
[monthkey]: Object.prototype.toString.call(recordPayload[monthkey]) === "[object Array]" ? _.compact(recordPayload[monthkey]) : recordPayload[monthkey]
|
||||
};
|
||||
this.setState({ loading: { ...loading, query: true } });
|
||||
getTableRecordDate(_.pick(module, [...screenParams, "current", "pageSize", "url"])).then(({ status, data }) => {
|
||||
this.setState({ loading: { ...loading, query: false } });
|
||||
if (status) {
|
||||
const { columns, list: dataSource, pageNum: current, pageSize, total } = data;
|
||||
this.setState({
|
||||
pageInfo: { ...pageInfo, current, pageSize, total },
|
||||
dataSource,
|
||||
columns
|
||||
});
|
||||
}
|
||||
}).catch(() => this.setState({ loading: { ...loading, query: false } }));
|
||||
};
|
||||
|
||||
/*
|
||||
* Author: 黎永顺
|
||||
* Description: 详情页面-筛选操作
|
||||
* Params:
|
||||
* Date: 2023/2/20
|
||||
*/
|
||||
handleTablerecordScreen = ({ key, value }) => {
|
||||
const { recordPayload } = this.state;
|
||||
this.setState({
|
||||
recordPayload: {
|
||||
...recordPayload,
|
||||
[key]: value
|
||||
}
|
||||
}, () => this.getTableRecordData());
|
||||
};
|
||||
handleResetSelectKeys = () => {
|
||||
this.setState({
|
||||
selectedRowKeys: [],
|
||||
recordPayload: {
|
||||
accumulatedSpecialAdditionalDeductionId: "",
|
||||
otherTaxExemptDeductionId: "",
|
||||
accumulatedSituationId: "",
|
||||
specialAddDeductionId: "",
|
||||
taxAgentId: "",
|
||||
declareMonth: null,
|
||||
taxYearMonth: null
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
const { className, screenParams, taxAgentOption, record } = this.props;
|
||||
const { columns, dataSource, loading, selectedRowKeys, pageInfo, recordPayload, width } = this.state;
|
||||
const rowSelection = {
|
||||
selectedRowKeys,
|
||||
onChange: (selectedRowKeys) => this.setState({ selectedRowKeys })
|
||||
};
|
||||
const pagination = {
|
||||
...pageInfo,
|
||||
showTotal: (total) => `共 ${total} 条`,
|
||||
pageSizeOptions: ["10", "20", "50", "100"],
|
||||
showSizeChanger: true,
|
||||
showQuickJumper: true,
|
||||
onShowSizeChange: (current, pageSize) => {
|
||||
this.setState({
|
||||
pageInfo: { ...pageInfo, current, pageSize }
|
||||
}, () => {
|
||||
this.getTableRecordData();
|
||||
});
|
||||
},
|
||||
onChange: (current) => {
|
||||
this.setState({
|
||||
pageInfo: { ...pageInfo, current }
|
||||
}, () => {
|
||||
this.getTableRecordData();
|
||||
});
|
||||
}
|
||||
};
|
||||
const items = screenParams.length === 1 ? [
|
||||
{
|
||||
com: Input({ value: record.username })
|
||||
}
|
||||
] : [
|
||||
{
|
||||
com: Input({ value: record.username })
|
||||
},
|
||||
{
|
||||
com: DataCollectionDateRangePick({
|
||||
label: "税款所属期",
|
||||
range: recordPayload[screenParams[screenParams.length - 1]] || [],
|
||||
onChange: this.handleTablerecordScreen,
|
||||
key: screenParams[screenParams.length - 1]
|
||||
})
|
||||
},
|
||||
{
|
||||
com: DataCollectionSelect({
|
||||
label: "个税扣缴义务人",
|
||||
value: !_.isNil(recordPayload.taxAgentId) ? recordPayload.taxAgentId.toString() : "",
|
||||
options: [{ key: "", showname: "全部" }, ...taxAgentOption],
|
||||
onChange: this.handleTablerecordScreen,
|
||||
key: "taxAgentId"
|
||||
})
|
||||
}
|
||||
];
|
||||
return (
|
||||
<div className="tableRecordWrapper">
|
||||
{
|
||||
!_.isEmpty(screenParams) &&
|
||||
<WeaSearchGroup className={className} showGroup needTigger={false} items={items} col={width > 1280 ? 3 : 2}/>
|
||||
}
|
||||
<UnifiedTable
|
||||
rowKey="id"
|
||||
rowSelection={rowSelection}
|
||||
columns={_.map(columns, item => ({
|
||||
...item,
|
||||
render: (text) => {
|
||||
return <span className="ellipsis" title={text}> {text} </span>;
|
||||
}
|
||||
}))}
|
||||
dataSource={dataSource}
|
||||
pagination={pagination}
|
||||
loading={loading.query}
|
||||
xWidth={columns.length * 180}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default TableRecord;
|
||||
|
|
@ -211,6 +211,186 @@ export const specialModalColumns = [
|
|||
key: "seriousIllnessTreatment"
|
||||
}
|
||||
];
|
||||
export const otherModalColumns = [
|
||||
{
|
||||
title: "姓名",
|
||||
dataIndex: "username",
|
||||
key: "username"
|
||||
},
|
||||
{
|
||||
title: "个税扣缴义务人",
|
||||
dataIndex: "taxAgentName",
|
||||
key: "taxAgentName"
|
||||
},
|
||||
{
|
||||
title: "部门",
|
||||
dataIndex: "departmentName",
|
||||
key: "departmentName"
|
||||
},
|
||||
{
|
||||
title: "手机号",
|
||||
dataIndex: "mobile",
|
||||
key: "mobile"
|
||||
},
|
||||
{
|
||||
title: "工号",
|
||||
dataIndex: "jobNum",
|
||||
key: "jobNum"
|
||||
},
|
||||
{
|
||||
title: "证件号码",
|
||||
dataIndex: "idNo",
|
||||
key: "idNo"
|
||||
},
|
||||
{
|
||||
title: "入职日期",
|
||||
dataIndex: "hiredate",
|
||||
key: "hiredate"
|
||||
},
|
||||
{
|
||||
title: "商业健康保险",
|
||||
dataIndex: "businessHealthyInsurance",
|
||||
key: "businessHealthyInsurance"
|
||||
},
|
||||
{
|
||||
title: "税延养老保险",
|
||||
dataIndex: "taxDelayEndowmentInsurance",
|
||||
key: "taxDelayEndowmentInsurance"
|
||||
},
|
||||
{
|
||||
title: "其他",
|
||||
dataIndex: "otherDeduction",
|
||||
key: "otherDeduction"
|
||||
},
|
||||
{
|
||||
title: "准予扣除的捐赠额",
|
||||
dataIndex: "deductionAllowedDonation",
|
||||
key: "deductionAllowedDonation"
|
||||
}
|
||||
];
|
||||
export const situationModalColumns = [
|
||||
{
|
||||
title: "姓名",
|
||||
dataIndex: "username",
|
||||
key: "username"
|
||||
},
|
||||
{
|
||||
title: "个税扣缴义务人",
|
||||
dataIndex: "taxAgentName",
|
||||
key: "taxAgentName"
|
||||
},
|
||||
{
|
||||
title: "部门",
|
||||
dataIndex: "departmentName",
|
||||
key: "departmentName"
|
||||
},
|
||||
{
|
||||
title: "手机号",
|
||||
dataIndex: "mobile",
|
||||
key: "mobile"
|
||||
},
|
||||
{
|
||||
title: "工号",
|
||||
dataIndex: "jobNum",
|
||||
key: "jobNum"
|
||||
},
|
||||
{
|
||||
title: "证件号码",
|
||||
dataIndex: "idNo",
|
||||
key: "idNo"
|
||||
},
|
||||
{
|
||||
title: "入职日期",
|
||||
dataIndex: "hiredate",
|
||||
key: "hiredate"
|
||||
},
|
||||
{
|
||||
title: "累计收入额",
|
||||
dataIndex: "addUpIncome",
|
||||
key: "addUpIncome"
|
||||
},
|
||||
{
|
||||
title: "累计减除费用",
|
||||
dataIndex: "addUpSubtraction",
|
||||
key: "addUpSubtraction"
|
||||
},
|
||||
{
|
||||
title: "累计社保个人合计",
|
||||
dataIndex: "addUpSocialSecurityTotal",
|
||||
key: "addUpSocialSecurityTotal"
|
||||
},
|
||||
{
|
||||
title: "累计公积金个人合计",
|
||||
dataIndex: "addUpAccumulationFundTotal",
|
||||
key: "addUpAccumulationFundTotal"
|
||||
},
|
||||
{
|
||||
title: "累计子女教育",
|
||||
dataIndex: "addUpChildEducation",
|
||||
key: "addUpChildEducation"
|
||||
},
|
||||
{
|
||||
title: "累计继续教育",
|
||||
dataIndex: "addUpContinuingEducation",
|
||||
key: "addUpContinuingEducation"
|
||||
},
|
||||
{
|
||||
title: "累计住房贷款利息",
|
||||
dataIndex: "addUpHousingLoanInterest",
|
||||
key: "addUpHousingLoanInterest"
|
||||
},
|
||||
{
|
||||
title: "累计住房租金",
|
||||
dataIndex: "addUpHousingRent",
|
||||
key: "addUpHousingRent"
|
||||
},
|
||||
{
|
||||
title: "累计赡养老人",
|
||||
dataIndex: "addUpSupportElderly",
|
||||
key: "addUpSupportElderly"
|
||||
},
|
||||
{
|
||||
title: "累计企业(职业)年金及其他福利",
|
||||
dataIndex: "addUpEnterpriseAndOther",
|
||||
key: "addUpEnterpriseAndOther"
|
||||
},
|
||||
{
|
||||
title: "累计其他免税扣除",
|
||||
dataIndex: "addUpOtherDeduction",
|
||||
key: "addUpOtherDeduction"
|
||||
},
|
||||
{
|
||||
title: "累计免税收入",
|
||||
dataIndex: "addUpTaxExemptIncome",
|
||||
key: "addUpTaxExemptIncome"
|
||||
},
|
||||
{
|
||||
title: "累计准予扣除的捐赠额",
|
||||
dataIndex: "addUpAllowedDonation",
|
||||
key: "addUpAllowedDonation"
|
||||
},
|
||||
{
|
||||
title: "累计减免税额",
|
||||
dataIndex: "addUpTaxSavings",
|
||||
key: "addUpTaxSavings"
|
||||
},
|
||||
{
|
||||
title: "累计已预扣预缴税额",
|
||||
dataIndex: "addUpAdvanceTax",
|
||||
key: "addUpAdvanceTax"
|
||||
},
|
||||
{
|
||||
title: "累计婴幼儿照护",
|
||||
dataIndex: "addUpInfantCare",
|
||||
key: "addUpInfantCare"
|
||||
},
|
||||
{
|
||||
title: "累计大病医疗",
|
||||
dataIndex: "addUpIllnessMedical",
|
||||
key: "addUpIllnessMedical"
|
||||
}
|
||||
|
||||
];
|
||||
|
||||
|
||||
export const dataSource = [];
|
||||
|
|
@ -219,66 +399,73 @@ export const dataCollectCondition = [
|
|||
{
|
||||
items: [
|
||||
{
|
||||
conditionType: "INPUT",
|
||||
conditionType: "INPUTNUMBER",
|
||||
domkey: ["addUpChildEducation"],
|
||||
fieldcol: 14,
|
||||
label: "累计子女教育",
|
||||
labelcol: 8,
|
||||
value: "",
|
||||
precision: 2,
|
||||
viewAttr: 2
|
||||
},
|
||||
{
|
||||
conditionType: "INPUT",
|
||||
conditionType: "INPUTNUMBER",
|
||||
domkey: ["addUpContinuingEducation"],
|
||||
fieldcol: 14,
|
||||
label: "累计继续教育",
|
||||
labelcol: 8,
|
||||
value: "",
|
||||
precision: 2,
|
||||
viewAttr: 2
|
||||
},
|
||||
{
|
||||
conditionType: "INPUT",
|
||||
conditionType: "INPUTNUMBER",
|
||||
domkey: ["addUpHousingLoanInterest"],
|
||||
fieldcol: 14,
|
||||
label: "累计住房贷款利息",
|
||||
labelcol: 8,
|
||||
value: "",
|
||||
precision: 2,
|
||||
viewAttr: 2
|
||||
},
|
||||
{
|
||||
conditionType: "INPUT",
|
||||
conditionType: "INPUTNUMBER",
|
||||
domkey: ["addUpHousingRent"],
|
||||
fieldcol: 14,
|
||||
label: "累计住房租金",
|
||||
labelcol: 8,
|
||||
value: "",
|
||||
precision: 2,
|
||||
viewAttr: 2
|
||||
},
|
||||
{
|
||||
conditionType: "INPUT",
|
||||
conditionType: "INPUTNUMBER",
|
||||
domkey: ["addUpSupportElderly"],
|
||||
fieldcol: 14,
|
||||
label: "累计赡养老人",
|
||||
labelcol: 8,
|
||||
value: "",
|
||||
precision: 2,
|
||||
viewAttr: 2
|
||||
},
|
||||
{
|
||||
conditionType: "INPUT",
|
||||
conditionType: "INPUTNUMBER",
|
||||
domkey: ["addUpIllnessMedical"],
|
||||
fieldcol: 14,
|
||||
label: "累计大病医疗",
|
||||
labelcol: 8,
|
||||
value: "",
|
||||
precision: 2,
|
||||
viewAttr: 2
|
||||
},
|
||||
{
|
||||
conditionType: "INPUT",
|
||||
conditionType: "INPUTNUMBER",
|
||||
domkey: ["addUpInfantCare"],
|
||||
fieldcol: 14,
|
||||
label: "累计婴幼儿照护",
|
||||
labelcol: 8,
|
||||
value: "",
|
||||
precision: 2,
|
||||
viewAttr: 2
|
||||
}
|
||||
],
|
||||
|
|
|
|||
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Author: 黎永顺
|
||||
* name: 数据采集-导入选项
|
||||
* Description:
|
||||
* Date: 2023/2/20
|
||||
*/
|
||||
import React, { Component } from "react";
|
||||
import { WeaSearchGroup } from "ecCom";
|
||||
import { DataCollectionDatePicker, DataCollectionSelect } from "../index";
|
||||
|
||||
class ImportFormCom extends Component {
|
||||
screenChange = ({ key, value }) => {
|
||||
const { onChangeImportForm } = this.props;
|
||||
onChangeImportForm(key, value);
|
||||
};
|
||||
|
||||
render() {
|
||||
const { taxAgentOption = [], declareMonth, taxAgentId } = this.props;
|
||||
const items = [
|
||||
{
|
||||
com: DataCollectionDatePicker({
|
||||
label: "税款所属期",
|
||||
value: declareMonth,
|
||||
onChange: this.screenChange,
|
||||
key: "declareMonth",
|
||||
screen: false
|
||||
})
|
||||
},
|
||||
{
|
||||
com: DataCollectionSelect({
|
||||
label: "个税扣缴义务人",
|
||||
value: taxAgentId || "",
|
||||
onChange: this.screenChange,
|
||||
options: [{ key: "", showname: "全部" }, ...taxAgentOption],
|
||||
key: "taxAgentId"
|
||||
})
|
||||
}
|
||||
];
|
||||
!declareMonth && items.shift();
|
||||
_.isNil(taxAgentId) && items.pop();
|
||||
return (
|
||||
<WeaSearchGroup className="screenWrapper" showGroup needTigger={false} items={items}
|
||||
col={2}/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default ImportFormCom;
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,4 +1,15 @@
|
|||
.cumDeductWrapper {
|
||||
.cumDeductWrapper, .payrollDistributionWrapper {
|
||||
.wea-new-top-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
|
||||
.tableWrapper {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
.weaTabWrapper {
|
||||
position: relative;
|
||||
|
||||
|
|
@ -34,18 +45,18 @@
|
|||
}
|
||||
|
||||
.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;
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -65,287 +65,177 @@ export const columns = [
|
|||
key: "title"
|
||||
}
|
||||
];
|
||||
|
||||
export const modalColumns = [
|
||||
{
|
||||
title: "姓名",
|
||||
dataIndex: "username",
|
||||
key: "username"
|
||||
},
|
||||
{
|
||||
title: "个税扣缴义务人",
|
||||
dataIndex: "taxAgentName",
|
||||
key: "taxAgentName"
|
||||
},
|
||||
{
|
||||
title: "部门",
|
||||
dataIndex: "departmentName",
|
||||
key: "departmentName"
|
||||
},
|
||||
{
|
||||
title: "手机号",
|
||||
dataIndex: "mobile",
|
||||
key: "mobile"
|
||||
},
|
||||
{
|
||||
title: "工号",
|
||||
dataIndex: "jobNum",
|
||||
key: "jobNum"
|
||||
},
|
||||
{
|
||||
title: "证件号码",
|
||||
dataIndex: "idNo",
|
||||
key: "idNo"
|
||||
},
|
||||
{
|
||||
title: "入职日期",
|
||||
dataIndex: "hiredate",
|
||||
key: "hiredate"
|
||||
},
|
||||
{
|
||||
title: "累计收入额",
|
||||
dataIndex: "addUpIncome",
|
||||
key: "addUpIncome"
|
||||
},
|
||||
{
|
||||
title: "累计减除费用",
|
||||
dataIndex: "addUpSubtraction",
|
||||
key: "addUpSubtraction"
|
||||
},
|
||||
{
|
||||
title: "累计社保个人合计",
|
||||
dataIndex: "addUpSocialSecurityTotal",
|
||||
key: "addUpSocialSecurityTotal"
|
||||
},
|
||||
{
|
||||
title: "累计公积金个人合计",
|
||||
dataIndex: "addUpAccumulationFundTotal",
|
||||
key: "addUpAccumulationFundTotal"
|
||||
},
|
||||
{
|
||||
title: "累计子女教育",
|
||||
dataIndex: "addUpChildEducation",
|
||||
key: "addUpChildEducation"
|
||||
},
|
||||
{
|
||||
title: "累计继续教育",
|
||||
dataIndex: "addUpContinuingEducation",
|
||||
key: "addUpContinuingEducation"
|
||||
},
|
||||
{
|
||||
title: "累计住房贷款利息",
|
||||
dataIndex: "addUpHousingLoanInterest",
|
||||
key: "addUpHousingLoanInterest"
|
||||
},
|
||||
{
|
||||
title: "累计住房租金",
|
||||
dataIndex: "addUpHousingRent",
|
||||
key: "addUpHousingRent"
|
||||
},
|
||||
{
|
||||
title: "累计赡养老人",
|
||||
dataIndex: "addUpSupportElderly",
|
||||
key: "addUpSupportElderly"
|
||||
},
|
||||
{
|
||||
title: "累计企业(职业)年金及其他福利",
|
||||
dataIndex: "addUpEnterpriseAndOther",
|
||||
key: "addUpEnterpriseAndOther"
|
||||
},
|
||||
{
|
||||
title: "累计其他免税扣除",
|
||||
dataIndex: "addUpOtherDeduction",
|
||||
key: "addUpOtherDeduction"
|
||||
},
|
||||
{
|
||||
title: "累计免税收入",
|
||||
dataIndex: "addUpTaxExemptIncome",
|
||||
key: "addUpTaxExemptIncome"
|
||||
},
|
||||
{
|
||||
title: "累计准予扣除的捐赠额",
|
||||
dataIndex: "addUpAllowedDonation",
|
||||
key: "addUpAllowedDonation"
|
||||
},
|
||||
{
|
||||
title: "累计减免税额",
|
||||
dataIndex: "addUpTaxSavings",
|
||||
key: "addUpTaxSavings"
|
||||
},
|
||||
{
|
||||
title: "累计已预扣预缴税额",
|
||||
dataIndex: "addUpAdvanceTax",
|
||||
key: "addUpAdvanceTax"
|
||||
},
|
||||
{
|
||||
title: "累计婴幼儿照护",
|
||||
dataIndex: "addUpInfantCare",
|
||||
key: "addUpInfantCare"
|
||||
},
|
||||
{
|
||||
title: "累计大病医疗",
|
||||
dataIndex: "addUpIllnessMedical",
|
||||
key: "addUpIllnessMedical"
|
||||
}
|
||||
|
||||
];
|
||||
|
||||
export const dataSource = [];
|
||||
|
||||
export const dataCollectCondition = [
|
||||
{
|
||||
items: [
|
||||
{
|
||||
conditionType: "INPUT",
|
||||
conditionType: "INPUTNUMBER",
|
||||
domkey: ["addUpIncome"],
|
||||
fieldcol: 14,
|
||||
label: "累计收入额",
|
||||
labelcol: 8,
|
||||
value: "",
|
||||
precision: 2,
|
||||
viewAttr: 2
|
||||
},
|
||||
{
|
||||
conditionType: "INPUT",
|
||||
conditionType: "INPUTNUMBER",
|
||||
domkey: ["addUpSubtraction"],
|
||||
fieldcol: 14,
|
||||
label: "累计减除费用",
|
||||
labelcol: 8,
|
||||
value: "",
|
||||
precision: 2,
|
||||
viewAttr: 2
|
||||
},
|
||||
{
|
||||
conditionType: "INPUT",
|
||||
conditionType: "INPUTNUMBER",
|
||||
domkey: ["addUpSocialSecurityTotal"],
|
||||
fieldcol: 14,
|
||||
label: "累计社保个人合计",
|
||||
labelcol: 8,
|
||||
value: "",
|
||||
precision: 2,
|
||||
viewAttr: 2
|
||||
},
|
||||
{
|
||||
conditionType: "INPUT",
|
||||
conditionType: "INPUTNUMBER",
|
||||
domkey: ["addUpAccumulationFundTotal"],
|
||||
fieldcol: 14,
|
||||
label: "累计公积金个人合计",
|
||||
labelcol: 8,
|
||||
value: "",
|
||||
precision: 2,
|
||||
viewAttr: 2
|
||||
},
|
||||
{
|
||||
conditionType: "INPUT",
|
||||
conditionType: "INPUTNUMBER",
|
||||
domkey: ["addUpChildEducation"],
|
||||
fieldcol: 14,
|
||||
label: "累计子女教育",
|
||||
labelcol: 8,
|
||||
value: "",
|
||||
precision: 2,
|
||||
viewAttr: 2
|
||||
},
|
||||
{
|
||||
conditionType: "INPUT",
|
||||
conditionType: "INPUTNUMBER",
|
||||
domkey: ["addUpContinuingEducation"],
|
||||
fieldcol: 14,
|
||||
label: "累计继续教育",
|
||||
labelcol: 8,
|
||||
value: "",
|
||||
precision: 2,
|
||||
viewAttr: 2
|
||||
},
|
||||
{
|
||||
conditionType: "INPUT",
|
||||
conditionType: "INPUTNUMBER",
|
||||
domkey: ["addUpHousingLoanInterest"],
|
||||
fieldcol: 14,
|
||||
label: "累计住房贷款利息",
|
||||
labelcol: 8,
|
||||
value: "",
|
||||
precision: 2,
|
||||
viewAttr: 2
|
||||
},
|
||||
{
|
||||
conditionType: "INPUT",
|
||||
conditionType: "INPUTNUMBER",
|
||||
domkey: ["addUpHousingRent"],
|
||||
fieldcol: 14,
|
||||
label: "累计住房租金",
|
||||
labelcol: 8,
|
||||
value: "",
|
||||
precision: 2,
|
||||
viewAttr: 2
|
||||
},
|
||||
{
|
||||
conditionType: "INPUT",
|
||||
conditionType: "INPUTNUMBER",
|
||||
domkey: ["addUpSupportElderly"],
|
||||
fieldcol: 14,
|
||||
label: "累计赡养老人",
|
||||
labelcol: 8,
|
||||
value: "",
|
||||
precision: 2,
|
||||
viewAttr: 2
|
||||
},
|
||||
{
|
||||
conditionType: "INPUT",
|
||||
conditionType: "INPUTNUMBER",
|
||||
domkey: ["addUpIllnessMedical"],
|
||||
fieldcol: 14,
|
||||
label: "累计大病医疗",
|
||||
labelcol: 8,
|
||||
value: "",
|
||||
precision: 2,
|
||||
viewAttr: 2
|
||||
},
|
||||
{
|
||||
conditionType: "INPUT",
|
||||
conditionType: "INPUTNUMBER",
|
||||
domkey: ["addUpEnterpriseAndOther"],
|
||||
fieldcol: 14,
|
||||
label: "累计企业(职业)年金及其他福利",
|
||||
labelcol: 8,
|
||||
value: "",
|
||||
precision: 2,
|
||||
viewAttr: 2
|
||||
},
|
||||
{
|
||||
conditionType: "INPUT",
|
||||
conditionType: "INPUTNUMBER",
|
||||
domkey: ["addUpOtherDeduction"],
|
||||
fieldcol: 14,
|
||||
label: "累计其他免税扣除",
|
||||
labelcol: 8,
|
||||
value: "",
|
||||
precision: 2,
|
||||
viewAttr: 2
|
||||
},
|
||||
{
|
||||
conditionType: "INPUT",
|
||||
conditionType: "INPUTNUMBER",
|
||||
domkey: ["addUpTaxExemptIncome"],
|
||||
fieldcol: 14,
|
||||
label: "累计免税收入",
|
||||
labelcol: 8,
|
||||
value: "",
|
||||
precision: 2,
|
||||
viewAttr: 2
|
||||
},
|
||||
{
|
||||
conditionType: "INPUT",
|
||||
conditionType: "INPUTNUMBER",
|
||||
domkey: ["addUpAllowedDonation"],
|
||||
fieldcol: 14,
|
||||
label: "累计准予扣除的捐赠额",
|
||||
labelcol: 8,
|
||||
value: "",
|
||||
precision: 2,
|
||||
viewAttr: 2
|
||||
},
|
||||
{
|
||||
conditionType: "INPUT",
|
||||
conditionType: "INPUTNUMBER",
|
||||
domkey: ["addUpTaxSavings"],
|
||||
fieldcol: 14,
|
||||
label: "累计减免税额",
|
||||
labelcol: 8,
|
||||
value: "",
|
||||
precision: 2,
|
||||
viewAttr: 2
|
||||
},
|
||||
{
|
||||
conditionType: "INPUT",
|
||||
conditionType: "INPUTNUMBER",
|
||||
domkey: ["addUpAdvanceTax"],
|
||||
fieldcol: 14,
|
||||
label: "累计已预扣预缴税额",
|
||||
labelcol: 8,
|
||||
value: "",
|
||||
precision: 2,
|
||||
viewAttr: 2
|
||||
},
|
||||
{
|
||||
conditionType: "INPUT",
|
||||
conditionType: "INPUTNUMBER",
|
||||
domkey: ["addUpInfantCare"],
|
||||
fieldcol: 14,
|
||||
label: "累计婴幼儿照护",
|
||||
labelcol: 8,
|
||||
value: "",
|
||||
precision: 2,
|
||||
viewAttr: 2
|
||||
}
|
||||
],
|
||||
|
|
@ -353,11 +243,10 @@ export const dataCollectCondition = [
|
|||
defaultshow: true
|
||||
}
|
||||
];
|
||||
|
||||
export const taxOptions = [
|
||||
{
|
||||
key: "01",
|
||||
showname: "一月",
|
||||
showname: "一月"
|
||||
},
|
||||
{
|
||||
key: "02",
|
||||
|
|
@ -402,5 +291,5 @@ export const taxOptions = [
|
|||
{
|
||||
key: "12",
|
||||
showname: "十二月"
|
||||
},
|
||||
}
|
||||
];
|
||||
|
|
|
|||
|
|
@ -1,201 +0,0 @@
|
|||
import React from "react";
|
||||
import { Col, DatePicker, Row } from "antd";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import { WeaTable } from "ecCom";
|
||||
import "./editSlideContent.less";
|
||||
import moment from "moment";
|
||||
|
||||
const { MonthPicker } = DatePicker;
|
||||
|
||||
let emptyItem = {
|
||||
incomeLowerLimit: "0.00",
|
||||
incomeUpperLimit: "0.00",
|
||||
dutyFreeValue: "0.00",
|
||||
dutyFreeRate: "0.00",
|
||||
taxableIncomeLl: "0.00",
|
||||
taxableIncomeUl: "0.00",
|
||||
taxRate: "0.00",
|
||||
taxDeduction: "0.00"
|
||||
};
|
||||
|
||||
@inject("cumSituationStore", "taxAgentStore")
|
||||
@observer
|
||||
export default class EditSlideContent extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
taxAgentId: "",
|
||||
startDate: "",
|
||||
endDate: "",
|
||||
editable:
|
||||
this.props.editable === undefined ? "true" : this.props.editable
|
||||
};
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
// 初始化渲染页面
|
||||
const {
|
||||
taxAgentStore: { fetchTaxAgentOption }
|
||||
} = this.props;
|
||||
fetchTaxAgentOption();
|
||||
}
|
||||
|
||||
addItem() {
|
||||
const {
|
||||
taxRateStore: { setDataSource }
|
||||
} = this.props;
|
||||
let dataSource = [...this.props.taxRateStore.dataSource];
|
||||
let indexNum = 1;
|
||||
if (dataSource.length > 0) {
|
||||
indexNum = dataSource[dataSource.length - 1].indexNum + 1;
|
||||
}
|
||||
let item = { ...emptyItem };
|
||||
item.indexNum = indexNum;
|
||||
dataSource.push(item);
|
||||
setDataSource(dataSource);
|
||||
}
|
||||
|
||||
fetchCumDeductDetailList(param) {
|
||||
const { cumSituationStore } = this.props;
|
||||
const { getCumDeductDetailList, currentRecord } = cumSituationStore;
|
||||
getCumDeductDetailList(currentRecord.id, param);
|
||||
}
|
||||
|
||||
// 日期格式变化加载数据
|
||||
handleFetchCumDeductDetailList(startDate, endDate, taxAgentId) {
|
||||
let declareMonth = [];
|
||||
if (startDate != "" && startDate != undefined) {
|
||||
declareMonth.push(startDate);
|
||||
}
|
||||
|
||||
if (endDate != "" && endDate != undefined) {
|
||||
declareMonth.push(endDate);
|
||||
}
|
||||
let item = {
|
||||
taxAgentId: taxAgentId
|
||||
};
|
||||
if (declareMonth.length != 0) {
|
||||
item.taxYearMonth = declareMonth;
|
||||
}
|
||||
this.fetchCumDeductDetailList(item);
|
||||
}
|
||||
|
||||
onSelectChange = (val) => {
|
||||
const { onChangeSlideSelectKey } = this.props;
|
||||
onChangeSlideSelectKey && onChangeSlideSelectKey(val);
|
||||
};
|
||||
|
||||
render() {
|
||||
const { cumSituationStore } = this.props;
|
||||
const { startDate, endDate, taxAgentId } = this.state;
|
||||
const {
|
||||
getCumDeductDetailList,
|
||||
currentRecord,
|
||||
slideColumns,
|
||||
slidePageObj,
|
||||
slideTableDataSource,
|
||||
setSlidePageObj,
|
||||
slideLoading
|
||||
} = cumSituationStore;
|
||||
const declareMonth = [startDate, endDate];
|
||||
|
||||
const pagination = {
|
||||
current: slidePageObj.current,
|
||||
pageSize: slidePageObj.pageSize,
|
||||
total: slidePageObj.total,
|
||||
showTotal: (total) => `共 ${total} 条`,
|
||||
showSizeChanger: true,
|
||||
onShowSizeChange(current, pageSize) {
|
||||
setSlidePageObj({ ...slidePageObj, current, pageSize });
|
||||
getCumDeductDetailList(currentRecord.id, {
|
||||
...slidePageObj,
|
||||
current,
|
||||
pageSize,taxAgentId:currentRecord.taxAgentId,
|
||||
declareMonth: _.filter(declareMonth, item => item)
|
||||
});
|
||||
},
|
||||
onChange(current) {
|
||||
setSlidePageObj({
|
||||
...slidePageObj,
|
||||
current,taxAgentId:currentRecord.taxAgentId,
|
||||
pageSize: slidePageObj.pageSize
|
||||
});
|
||||
getCumDeductDetailList(currentRecord.id, {
|
||||
...slidePageObj,
|
||||
current,
|
||||
pageSize,
|
||||
declareMonth: _.filter(declareMonth, item => item)
|
||||
});
|
||||
}
|
||||
};
|
||||
const newColumns = _.map([...slideColumns], (item) => ({ ...item }));
|
||||
const rowSelection = {
|
||||
selectedRowKeys: this.props.slideSelectedKey,
|
||||
onChange: this.onSelectChange
|
||||
};
|
||||
return (
|
||||
<div className="cumDeductSlide">
|
||||
<Row className="topLabelBar">
|
||||
<Col span={4}>
|
||||
<span className="username">{currentRecord.username}</span>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<span className="formLabel">申报月份</span>
|
||||
<div className="weaRangePickerWrapper">
|
||||
<div className="monthPickerWrapper">
|
||||
<MonthPicker
|
||||
width={100}
|
||||
format="YYYY-MM"
|
||||
value={startDate}
|
||||
onChange={(v) => {
|
||||
let startDate = "";
|
||||
if (v != "" && v != undefined) {
|
||||
startDate = moment(v).format("YYYY-MM");
|
||||
}
|
||||
this.setState({ startDate });
|
||||
this.handleFetchCumDeductDetailList(
|
||||
startDate,
|
||||
endDate,
|
||||
taxAgentId
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<span className="betweenLable">至</span>
|
||||
<div className="monthPickerWrapper">
|
||||
<MonthPicker
|
||||
width={100}
|
||||
value={endDate}
|
||||
onChange={(v) => {
|
||||
let endDate = "";
|
||||
if (v != "" && v != undefined) {
|
||||
endDate = moment(v).format("YYYY-MM");
|
||||
}
|
||||
this.setState({ endDate });
|
||||
this.handleFetchCumDeductDetailList(
|
||||
startDate,
|
||||
endDate,
|
||||
currentRecord.taxAgentId
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
<div>
|
||||
<WeaTable
|
||||
rowKey="id"
|
||||
rowSelection={rowSelection}
|
||||
columns={newColumns}
|
||||
dataSource={slideTableDataSource}
|
||||
pagination={pagination}
|
||||
loading={slideLoading}
|
||||
scroll={{ x: newColumns ? newColumns.length * 150 : 900 }}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
.cumDeductSlide {
|
||||
.topLabelBar {
|
||||
padding: 10px 20px;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.formLabel {
|
||||
margin-right: 10px;
|
||||
}
|
||||
.weaRangePickerWrapper {
|
||||
display: inline-block;
|
||||
.monthPickerWrapper {
|
||||
width: 100px;
|
||||
display: inline-block;
|
||||
}
|
||||
.betweenLable {
|
||||
margin-left: 10px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue