package com.engine.salary.service.impl; import com.engine.common.util.ServiceUtil; import com.engine.core.impl.Service; import com.engine.salary.entity.datacollection.DataCollectionEmployee; import com.engine.salary.entity.extemp.param.ExtEmpImportParam; import com.engine.salary.entity.extemp.param.ExtEmpQueryParam; import com.engine.salary.entity.extemp.param.ExtEmpSaveParam; import com.engine.salary.entity.extemp.po.ExtEmpPO; import com.engine.salary.entity.hrm.DeptInfo; import com.engine.salary.entity.hrm.SubCompanyInfo; import com.engine.salary.entity.salarysob.param.SalarySobRangeEmpQueryParam; import com.engine.salary.exception.SalaryRunTimeException; import com.engine.salary.mapper.datacollection.EmployMapper; import com.engine.salary.mapper.extemp.ExternalEmployeeMapper; import com.engine.salary.service.ExtEmpService; import com.engine.salary.service.SalaryEmployeeService; import com.engine.salary.util.SalaryDateUtil; import com.engine.salary.util.SalaryI18nUtil; import com.engine.salary.util.db.MapperProxyFactory; import com.engine.salary.util.excel.ExcelComment; import com.engine.salary.util.excel.ExcelParseHelper; import com.engine.salary.util.excel.ExcelSupport; import com.engine.salary.util.excel.ExcelUtilPlus; import com.engine.salary.util.page.PageInfo; import com.engine.salary.util.page.SalaryPageUtil; import com.engine.salary.util.valid.ValidUtil; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import dm.jdbc.util.IdGenerator; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.Validate; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.util.IOUtils; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.springframework.beans.BeanUtils; import weaver.file.ImageFileManager; import weaver.general.Util; import weaver.hrm.User; import java.io.InputStream; import java.util.*; import java.util.stream.Collectors; import static com.engine.salary.util.excel.ExcelSupport.EXCEL_TYPE_XLSX; /** * 累计专项 *

Copyright: Copyright (c) 2022

*

Company: 泛微软件

* * @author qiantao * @version 1.0 **/ public class ExtEmpServiceImpl extends Service implements ExtEmpService { private ExternalEmployeeMapper getExternalEmployeeMapper() { return MapperProxyFactory.getProxy(ExternalEmployeeMapper.class); } private SalaryEmployeeService getSalaryEmployeeService(User user) { return ServiceUtil.getService(SalaryEmployeeServiceImpl.class, user); } private EmployMapper getEmployMapper() { return MapperProxyFactory.getProxy(EmployMapper.class); } @Override public List list(ExtEmpQueryParam param) { return getExternalEmployeeMapper().listSome(ExtEmpPO.builder().username(param.getUsername()).build()); } @Override public PageInfo listPage(ExtEmpQueryParam param) { List extEmpPOS = list(param); return SalaryPageUtil.buildPage(param.getCurrent(), param.getPageSize(), extEmpPOS, ExtEmpPO.class); } @Override public void save(ExtEmpSaveParam param) { List extEmpPOS = getExternalEmployeeMapper().listSome(ExtEmpPO.builder().username(param.getUsername()).build()); if (CollectionUtils.isNotEmpty(extEmpPOS)) { throw new SalaryRunTimeException("姓名已存在!"); } ExtEmpPO po = new ExtEmpPO(); BeanUtils.copyProperties(param, po); po.setId(IdGenerator.generate()); po.setStatus("2"); po.setCreator((long) user.getUID()); po.setModifier((long) user.getUID()); Date now = new Date(); po.setCreateTime(now); po.setUpdateTime(now); po.setDeleteType(0); getExternalEmployeeMapper().insertIgnoreNull(po); } @Override public void update(ExtEmpSaveParam param) { ExtEmpPO oldPO = getExternalEmployeeMapper().getById(param.getId()); if (!StringUtils.equals(oldPO.getUsername(), param.getUsername())) { List extEmpPOS = getExternalEmployeeMapper().listSome(ExtEmpPO.builder().username(param.getUsername()).build()); if (CollectionUtils.isNotEmpty(extEmpPOS)) { throw new SalaryRunTimeException("姓名已存在!"); } } ExtEmpPO po = new ExtEmpPO(); BeanUtils.copyProperties(param, po); po.setModifier((long) user.getUID()); Date now = new Date(); po.setUpdateTime(now); getExternalEmployeeMapper().updateIgnoreNull(po); } @Override public void delete(Collection ids) { if (CollectionUtils.isNotEmpty(ids)) { ids.forEach(getExternalEmployeeMapper()::delete); } } @Override public List getExtEmpByIds(List ids) { if (CollectionUtils.isEmpty(ids)) { return new ArrayList<>(); } List extEmpPOS = new ArrayList<>(); List> partition = Lists.partition(ids, 500); partition.forEach(list -> extEmpPOS.addAll(getExternalEmployeeMapper().listSome(ExtEmpPO.builder().ids(list).build()))); return extEmpPOS; } @Override public DataCollectionEmployee getEmployeeById(Long id) { ExtEmpPO po = getExternalEmployeeMapper().getById(id); return cover(po); } @Override public List getEmployeeByIds(List ids) { if (CollectionUtils.isEmpty(ids)) { return new ArrayList<>(); } List extEmpPOS = new ArrayList<>(); List> partition = Lists.partition(ids, 500); partition.forEach(list -> extEmpPOS.addAll(getExternalEmployeeMapper().listSome(ExtEmpPO.builder().ids(list).build()))); return coverList(extEmpPOS); } @Override public List listByParams(List includeQueryParams) { List emps = new ArrayList<>(); List> partition = Lists.partition(includeQueryParams, 100); partition.forEach(list -> { emps.addAll(getExternalEmployeeMapper().listByParams(list)); }); return emps; } @Override public List listEmployee() { return getExternalEmployeeMapper().listEmployee(); } @Override public Collection getEmployeeByIdsAll(List ids) { List employeeList = new ArrayList<>(); List> partition = Lists.partition(ids, 1000); partition.forEach(e -> { List employeeByIdsAll = getExternalEmployeeMapper().getEmployeeByIdsAll(e); employeeList.addAll(employeeByIdsAll); }); return employeeList; } @Override public Collection listAllForReport() { return getExternalEmployeeMapper().listAllForReport(); } @Override public ExtEmpPO getById(Long id) { ExtEmpPO po = getExternalEmployeeMapper().getById(id); if (po != null) { if (po.getDepartmentId() != null) { List deptInfoList = getSalaryEmployeeService(user).getDeptInfoList(Collections.singletonList(po.getDepartmentId())); if (CollectionUtils.isNotEmpty(deptInfoList)) { po.setDepartmentOrgName(deptInfoList.get(0).getName()); } } if (po.getSubcompanyId() != null) { List subInfoList = getSalaryEmployeeService(user).getSubCompanyInfoList(Collections.singletonList(po.getSubcompanyId())); if (CollectionUtils.isNotEmpty(subInfoList)) { po.setSubcompanyOrgName(subInfoList.get(0).getName()); } } } return po; } public DataCollectionEmployee cover(ExtEmpPO extPo) { if (extPo == null) { return null; } DataCollectionEmployee employee = new DataCollectionEmployee(); BeanUtils.copyProperties(extPo, employee); employee.setEmployeeId(extPo.getId()); employee.setExtEmp(true); return employee; } public List coverList(List extEmps) { if (CollectionUtils.isEmpty(extEmps)) { return new ArrayList<>(); } return extEmps.stream().map(emp -> { DataCollectionEmployee employee = new DataCollectionEmployee(); BeanUtils.copyProperties(emp, employee); employee.setEmployeeId(emp.getId()); employee.setExtEmp(true); return employee; }).collect(Collectors.toList()); } @Override public XSSFWorkbook exportImportTemplate() { // 模板表头 List headerList = Lists.newArrayList( SalaryI18nUtil.getI18nLabel(25034, "姓名"), SalaryI18nUtil.getI18nLabel(27511, "部门"), SalaryI18nUtil.getI18nLabel(33553, "分部"), SalaryI18nUtil.getI18nLabel(1516, "入职日期"), SalaryI18nUtil.getI18nLabel(125238, "手机号"), SalaryI18nUtil.getI18nLabel(1933, "工号"), SalaryI18nUtil.getI18nLabel(1887, "身份证号码"), SalaryI18nUtil.getI18nLabel(0, "本人开户的银行卡卡号"), SalaryI18nUtil.getI18nLabel(0, "本人开户的银行卡开户支行全称")); List dataIndexList = Lists.newArrayList("username", "departmentName", "subcompanyName", "companystartdate", "mobile", "workcode", "idNo", "bankCardNum", "bankName"); // excel导出的数据 List> rows = new ArrayList<>(); rows.add(headerList); // 注释 List excelComments = Lists.newArrayList(); excelComments.add(new ExcelComment(0, 0, 1, 2, SalaryI18nUtil.getI18nLabel(30036, "必填"))); excelComments.add(new ExcelComment(3, 0, 4, 2, SalaryI18nUtil.getI18nLabel(542348, "格式样例为'2022-01-01'、'2022/1/1'"))); String sheetName = "非系统人员导入模板"; return ExcelUtilPlus.genWorkbookV2(rows, sheetName, excelComments); } @Override public Map previewImportExtEmp(ExtEmpImportParam param) { //参数校验 ValidUtil.doValidator(param); Map map = new HashMap<>(); InputStream fileInputStream = null; try { fileInputStream = ImageFileManager.getInputStreamById(Integer.parseInt(param.getImageId())); Sheet sheet = ExcelSupport.parseFile(fileInputStream, 0, EXCEL_TYPE_XLSX); map.put("headers", ExcelSupport.getSheetHeader(sheet, 0)); map.put("list", ExcelParseHelper.parse2List(sheet, 1)); return map; } finally { IOUtils.closeQuietly(fileInputStream); } } @Override public Map importExtEmp(ExtEmpImportParam param){ Map apidatas = new HashMap(); //excel文件id String imageId = Util.null2String(param.getImageId()); Validate.notBlank(imageId, SalaryI18nUtil.getI18nLabel(542127, "imageId为空")); // 失败的数量 int failCount = 0; // 成功的数量 int successCount = 0; InputStream fileInputStream = null; try { fileInputStream = ImageFileManager.getInputStreamById(Integer.parseInt(param.getImageId())); Sheet sheet = ExcelSupport.parseFile(fileInputStream, 0, EXCEL_TYPE_XLSX); //数据库中现有非系统人员集合 List allExtEmpInfo= getExternalEmployeeMapper().listAll(); // 错误提示信息 List excelComments = Lists.newArrayList(); // 存在错误的那行数据 List> errorDatas = Lists.newArrayList(); // 表头 List headers = ExcelSupport.getSheetHeader(sheet, 0); // 处理数值 List> data = ExcelParseHelper.parse2Map(sheet, 1); if (CollectionUtils.isEmpty(headers)) { throw new SalaryRunTimeException("表头为空"); } if (CollectionUtils.isEmpty(data)) { throw new SalaryRunTimeException("无数据"); } //存储待新增和待更新的ExtEmpPO数据 List updateExtEmpPOList = new ArrayList<>(); List insertExtEmpPOList = new ArrayList<>(); //遍历excel表具体数据 for (int i = 0; i < data.size(); i++) { String row = "第" + (i + 1) + "行"; boolean isError = false; Map map = data.get(i); Long employeeId = 0L; String username = (String) map.getOrDefault(SalaryI18nUtil.getI18nLabel(25034, "姓名"), ""); String departmentName = (String) map.getOrDefault(SalaryI18nUtil.getI18nLabel(27511, "部门"), ""); String subcompanyName = (String) map.getOrDefault(SalaryI18nUtil.getI18nLabel(33553, "分部"), ""); String companystartdate = (String) map.getOrDefault(SalaryI18nUtil.getI18nLabel(1516, "入职日期"), ""); //校验姓名 if (StringUtils.isBlank(username)) { //姓名是必填项 isError = true; Map errorMessageMap = Maps.newHashMap(); errorMessageMap.put("message", row + SalaryI18nUtil.getI18nLabel(102838, "姓名不能为空")); excelComments.add(errorMessageMap); } long usernameNum = updateExtEmpPOList.stream().filter(f -> f.getUsername().equals(username)).count() + insertExtEmpPOList.stream().filter(f -> f.getUsername().equals(username)).count(); if (usernameNum > 0) { //excel中姓名相同时,只会录入第一次出现的数据 isError = true; Map errorMessageMap = Maps.newHashMap(); errorMessageMap.put("message", row + SalaryI18nUtil.getI18nLabel(102838, "本次excel文件中已存在该姓名相关数据,本行数据无法录入")); excelComments.add(errorMessageMap); } //校验部门、分部 List subCompanyInfos = new ArrayList<>(); List deptInfos = new ArrayList<>(); if (StringUtils.isNotBlank(subcompanyName)) { subCompanyInfos = getEmployMapper().getSubCompanyInfosByName(subcompanyName); if (subCompanyInfos.size() == 0) { isError = true; Map errorMessageMap = Maps.newHashMap(); errorMessageMap.put("message", row + SalaryI18nUtil.getI18nLabel(0, "分部信息不存在,请检查分部数据是否正确")); excelComments.add(errorMessageMap); } } if (StringUtils.isNotBlank(departmentName)) { deptInfos = getEmployMapper().getDeptInfosByName(departmentName); if (deptInfos.size() == 0) { isError = true; Map errorMessageMap = Maps.newHashMap(); errorMessageMap.put("message", row + SalaryI18nUtil.getI18nLabel(0, "部门信息不存在,请检查部门数据是否正确")); excelComments.add(errorMessageMap); } } if (StringUtils.isNotBlank(companystartdate) && (companystartdate.length() < 10 || !SalaryDateUtil.checkDay(companystartdate.substring(0, 10)))) { isError = true; Map errorMessageMap = Maps.newHashMap(); errorMessageMap.put("message", row + SalaryI18nUtil.getI18nLabel(0, "入职日期格式错误,正确格式为YYYY-MM或者yyyy-MM-dd")); excelComments.add(errorMessageMap); } if (!isError){ //校验当前数据是否有相关数据(姓名相同)存在数据库中,有则更新,无则新建 List targetExtEmpInfoList = allExtEmpInfo.stream().filter(f -> f.getUsername().equals(username)).collect(Collectors.toList()); //校验部门和分部关系 List targetDeptInfos = new ArrayList<>(); List targetSubCompanyInfos = new ArrayList<>(); if (targetExtEmpInfoList.size() == 1) { ExtEmpPO targetExtEmpInfo = targetExtEmpInfoList.get(0); //将库中已有的部门和分布信息取出(excel行未设置对应字段数据时) if (targetExtEmpInfo.getSubcompanyId() != null && subCompanyInfos.size() == 0) { subCompanyInfos.add(SubCompanyInfo.builder().id(targetExtEmpInfo.getSubcompanyId()).name(targetExtEmpInfo.getSubcompanyName()).build()); } if (targetExtEmpInfo.getDepartmentId() != null && deptInfos.size() == 0) { DeptInfo oldDeptInfo = getEmployMapper().getDeptInfoById(targetExtEmpInfo.getDepartmentId()); deptInfos.add(oldDeptInfo); } } //分部结果数为0,部门结果数大于1,则无法匹配 if(subCompanyInfos.size() == 0 && deptInfos.size() > 1) { isError = true; Map errorMessageMap = Maps.newHashMap(); errorMessageMap.put("message", row + SalaryI18nUtil.getI18nLabel(0, "系统中存在重复部门信息,无法指定当前人员关联的唯一部门,请通过填写部门所属的分部信息来缩小部门筛选范围")); excelComments.add(errorMessageMap); } else if (subCompanyInfos.size() > 1 && deptInfos.size() == 0) { //部门结果数为0,分部结果数大于1,则无法匹配 isError = true; Map errorMessageMap = Maps.newHashMap(); errorMessageMap.put("message", row + SalaryI18nUtil.getI18nLabel(0, "系统中存在重复分部信息,无法指定当前人员关联的唯一分部,请通过填写人员所属的部门信息来缩小分部筛选范围")); excelComments.add(errorMessageMap); } else if (subCompanyInfos.size() >= 1 && deptInfos.size() >= 1) { //部门结果数大于等于1,分部结果数大于等于1,筛选出可配对的组合,根据部门的所属分部字段进行配对 for (DeptInfo deptInfo : deptInfos) { if (subCompanyInfos.stream().filter(g -> g.getId().equals(deptInfo.getSubcompanyid1())).count() > 0) { targetDeptInfos.add(deptInfo); } } if (targetDeptInfos.size() == 0) { isError = true; Map errorMessageMap = Maps.newHashMap(); errorMessageMap.put("message", row + SalaryI18nUtil.getI18nLabel(0, "部门与分部无法匹配")); excelComments.add(errorMessageMap); } else if (targetDeptInfos.size() > 1) { isError = true; Map errorMessageMap = Maps.newHashMap(); errorMessageMap.put("message", row + SalaryI18nUtil.getI18nLabel(0, "该组数据中的部门和分部信息在系统中出现多组匹配的部门和分布组合,无法指定唯一的部门和分部组合")); excelComments.add(errorMessageMap); } else { targetSubCompanyInfos = subCompanyInfos.stream().filter(f -> f.getId().equals(targetDeptInfos.get(0).getSubcompanyid1())).collect(Collectors.toList()); } } else if (subCompanyInfos.size() == 0 && deptInfos.size() == 1) { //分部结果数为0,部门结果数为1,可以匹配 targetDeptInfos.add(deptInfos.get(0)); } else if (subCompanyInfos.size() == 1 && deptInfos.size() == 0) { //部门结果数为0,分部结果数为1,可以匹配 targetSubCompanyInfos.add(subCompanyInfos.get(0)); } //收集excel有效数据,并区分新增和更新 DeptInfo finalDeptInfo = targetDeptInfos.size() > 0 ? targetDeptInfos.get(0) : null; SubCompanyInfo finalSubCompanyInfo = targetSubCompanyInfos.size() > 0 ? targetSubCompanyInfos.get(0) : null; if (targetExtEmpInfoList.isEmpty()) { if (!isError) { //添加一条新建数据 insertExtEmpPOList.add(handleExtEmpInfo(null, map, finalDeptInfo, finalSubCompanyInfo)); } } else if (targetExtEmpInfoList.size() > 1) { isError = true; Map errorMessageMap = Maps.newHashMap(); errorMessageMap.put("message", row + SalaryI18nUtil.getI18nLabel(0, "数据库中非系统人员信息存在姓名相同数据,请先确保姓名唯一")); excelComments.add(errorMessageMap); } else { if (!isError) { //添加一条更新数据 updateExtEmpPOList.add(handleExtEmpInfo(targetExtEmpInfoList.get(0), map, finalDeptInfo, finalSubCompanyInfo)); } } } if (isError) { failCount++; errorDatas.add(map); } else { successCount++; } } //更新 for(ExtEmpPO po : updateExtEmpPOList) { getExternalEmployeeMapper().updateIgnoreNull(po); } //新建 for(ExtEmpPO po : insertExtEmpPOList) { getExternalEmployeeMapper().insertIgnoreNull(po); } apidatas.put("successCount", successCount); apidatas.put("errorCount", failCount); apidatas.put("errorData", excelComments); } finally { IOUtils.closeQuietly(fileInputStream); } return apidatas; } public ExtEmpPO handleExtEmpInfo(ExtEmpPO po, Map map, DeptInfo deptInfo, SubCompanyInfo subCompanyInfo) { ExtEmpPO resultPo = new ExtEmpPO(); if (po == null) { //新建 resultPo.setId(IdGenerator.generate()); resultPo.setStatus("2"); resultPo.setCreateTime(new Date()); resultPo.setUpdateTime(new Date()); resultPo.setDeleteType(0); resultPo.setCreator((long) user.getUID()); } else { //更新 BeanUtils.copyProperties(po, resultPo); resultPo.setUpdateTime(new Date()); } String username = (String) map.getOrDefault(SalaryI18nUtil.getI18nLabel(25034, "姓名"), ""); // String departmentName = (String) map.getOrDefault(SalaryI18nUtil.getI18nLabel(27511, "部门"), ""); // String subcompanyName = (String) map.getOrDefault(SalaryI18nUtil.getI18nLabel(33553, "分部"), ""); String companystartdate = (String) map.getOrDefault(SalaryI18nUtil.getI18nLabel(1516, "入职日期"), ""); String mobile = (String) map.getOrDefault(SalaryI18nUtil.getI18nLabel(125238, "手机号"), ""); String workcode = (String) map.getOrDefault(SalaryI18nUtil.getI18nLabel(1933, "工号"), ""); String idNo = (String) map.getOrDefault(SalaryI18nUtil.getI18nLabel(1887, "身份证号码"), ""); String bankCardNum = (String) map.getOrDefault(SalaryI18nUtil.getI18nLabel(0, "本人开户的银行卡卡号"), ""); String bankName = (String) map.getOrDefault(SalaryI18nUtil.getI18nLabel(0, "本人开户的银行卡开户支行全称"), ""); if (StringUtils.isNotBlank(companystartdate)) { resultPo.setCompanystartdate(companystartdate.substring(0, 10)); } if (StringUtils.isNotBlank(username)) { resultPo.setUsername(username); } if (StringUtils.isNotBlank(mobile)) { resultPo.setMobile(mobile); } if (StringUtils.isNotBlank(workcode)) { resultPo.setWorkcode(workcode); } if (StringUtils.isNotBlank(idNo)) { resultPo.setIdNo(idNo); } if (StringUtils.isNotBlank(bankCardNum)) { resultPo.setBankCardNum(bankCardNum); } if (StringUtils.isNotBlank(bankName)) { resultPo.setBankName(bankName); } if (deptInfo != null) { resultPo.setDepartmentName(deptInfo.getName()); resultPo.setDepartmentId(deptInfo.getId()); } if (subCompanyInfo != null) { resultPo.setSubcompanyName(subCompanyInfo.getName()); resultPo.setSubcompanyId(subCompanyInfo.getId()); } if (resultPo.getDepartmentName() == null) { resultPo.setDepartmentName(""); } resultPo.setModifier((long) user.getUID()); return resultPo; } }