package com.engine.salary.service.impl; import cn.hutool.core.date.DateUtil; import com.alibaba.fastjson.JSONArray; import com.api.formmode.mybatis.util.SqlProxyHandle; import com.cloudstore.dev.api.bean.MessageBean; import com.cloudstore.dev.api.bean.MessageType; import com.cloudstore.dev.api.util.Util_Message; import com.engine.common.util.ServiceUtil; import com.engine.core.impl.Service; import com.engine.salary.biz.SalarySendBiz; import com.engine.salary.biz.SalarySendInfoBiz; import com.engine.salary.constant.SalaryItemConstant; import com.engine.salary.constant.SalaryTemplateSalaryItemSetGroupConstant; import com.engine.salary.encrypt.salaryacct.SalaryAcctResultPOEncrypt; import com.engine.salary.entity.datacollection.DataCollectionEmployee; import com.engine.salary.entity.salaryBill.dto.*; import com.engine.salary.entity.salaryBill.param.*; import com.engine.salary.entity.salaryBill.po.SalarySendInfoPO; import com.engine.salary.entity.salaryBill.po.SalarySendPO; import com.engine.salary.entity.salaryBill.po.SalaryTemplatePO; import com.engine.salary.entity.salaryacct.bo.SalaryAcctResultBO; import com.engine.salary.entity.salaryacct.po.SalaryAcctEmployeePO; import com.engine.salary.entity.salaryacct.po.SalaryAcctRecordPO; import com.engine.salary.entity.salaryacct.po.SalaryAcctResultPO; import com.engine.salary.entity.salaryformula.dto.SalaryFormulaEmployeeDTO; import com.engine.salary.entity.salarysob.dto.SalarySobCycleDTO; import com.engine.salary.entity.salarysob.po.SalarySobPO; import com.engine.salary.entity.taxagent.po.TaxAgentPO; import com.engine.salary.enums.salaryaccounting.SalaryAcctRecordStatusEnum; import com.engine.salary.enums.salarybill.SalarySendStatusEnum; import com.engine.salary.enums.salarysend.SalarySendGrantTypeEnum; import com.engine.salary.exception.SalaryRunTimeException; import com.engine.salary.mapper.salaryacct.SalaryAcctEmployeeMapper; import com.engine.salary.mapper.salaryacct.SalaryAcctRecordMapper; import com.engine.salary.mapper.salaryacct.SalaryAcctResultMapper; import com.engine.salary.mapper.salarybill.SalarySendInfoMapper; import com.engine.salary.mapper.salarybill.SalarySendMapper; import com.engine.salary.service.*; import com.engine.salary.sys.entity.vo.OrderRuleVO; import com.engine.salary.sys.service.SalarySysConfService; import com.engine.salary.sys.service.impl.SalarySysConfServiceImpl; import com.engine.salary.util.JsonUtil; import com.engine.salary.util.SalaryDateUtil; import com.engine.salary.util.SalaryEntityUtil; import com.engine.salary.util.SalaryI18nUtil; import com.engine.salary.util.db.MapperProxyFactory; import com.engine.salary.util.excel.ExcelUtil; import com.engine.salary.util.page.PageInfo; import com.engine.salary.util.page.SalaryPageUtil; import com.google.common.collect.Lists; import dm.jdbc.util.IdGenerator; import org.apache.commons.beanutils.BeanUtils; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import weaver.hrm.User; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.math.BigDecimal; import java.text.SimpleDateFormat; import java.util.*; import java.util.stream.Collectors; /** * @Description: 工资单发放 * @Author: wangxiangzhong * @Date: 2021-12-11 11:28 */ public class SalarySendServiceImpl extends Service implements SalarySendService { private static final Logger log = LoggerFactory.getLogger(SalarySendServiceImpl.class); private SalarySendBiz mapper = new SalarySendBiz(); private SalarySendInfoBiz salarySendInfoMapper = new SalarySendInfoBiz(); private SalarySendRangeService getSalarySendRangeService(User user) { return ServiceUtil.getService(SalarySendRangeServiceImpl.class, user); } private SalaryTemplateService getSalaryTemplateService(User user) { return ServiceUtil.getService(SalaryTemplateServiceImpl.class, user); } private SalarySendMapper getSalarySendMapper() { return SqlProxyHandle.getProxy(SalarySendMapper.class); } private SalaryAcctRecordService getSalaryAcctRecordService(User user) { return ServiceUtil.getService(SalaryAcctRecordServiceImpl.class, user); } private SalaryAcctRecordMapper getSalaryAcctRecordMapper() { return SqlProxyHandle.getProxy(SalaryAcctRecordMapper.class); } private SalaryAcctEmployeeMapper getSalaryAcctEmployeeMapper() { return SqlProxyHandle.getProxy(SalaryAcctEmployeeMapper.class); } // private SalaryAcctResultMapper getSalaryAcctResultMapper() { return SqlProxyHandle.getProxy(SalaryAcctResultMapper.class); } private TaxAgentService getTaxAgentService(User user) { return ServiceUtil.getService(TaxAgentServiceImpl.class, user); } private SalaryEmployeeService getSalaryEmployeeService(User user) { return ServiceUtil.getService(SalaryEmployeeServiceImpl.class, user); } private SalarySendInfoMapper getSalarySendInfoMapper() { return SqlProxyHandle.getProxy(SalarySendInfoMapper.class); } private SalarySysConfService getSalarySysConfService(User user) { return ServiceUtil.getService(SalarySysConfServiceImpl.class, user); } // @RpcReference // private FileDownloadClient fileDownloadClient; // /** // * 同步用RpcReference // */ // @RpcReference // private SystemMessageRest systemMessageRest; // /** // * 异步用Autowired // */ // @Autowired // private AsyncSystemMessageRest asyncSystemMessageRest; // @RpcReference // private MailBaseService mailBaseService; // // private SalaryBatchService salaryBatchService; // @Autowired // private LoggerTemplate salarySendLoggerTemplate; // @Autowired // private HrmCommonEmployeeService hrmCommonEmployeeService; // @Autowired // private ExecutorService taskExecutor; @Override public SalarySendPO getById(Long salarySendId) { return mapper.getById(salarySendId); } @Override public List findReAccountingIdsByAcctIds(List salaryAccountingIds, String tenantKey) { // 校验salaryAccountingId if (CollectionUtils.isEmpty(salaryAccountingIds)) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100497, "核算id必传")); } // List salarySends = new LambdaQueryChainWrapper<>(mapper) // .eq(SalarySendPO::getDeleteType, 0) // .eq(SalarySendPO::getSendNum, 0) // .in(SalarySendPO::getSalaryAccountingId, salaryAccountingIds) // .list(); Map condition = new HashMap<>(); condition.put("deleteType", 0); condition.put("sendNum", 0); condition.put("salaryAccountingIds", salaryAccountingIds); List salarySends = mapper.listSomeWithCondition(condition); return salarySends.stream().map(SalarySendPO::getSalaryAccountingId).collect(Collectors.toList()); } @Override public String generateSalaryBill(Long salaryAccountingId) { // 校验salaryAccountingId if (salaryAccountingId == null) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100497, "核算id必传")); } SalaryAcctRecordPO recordPo = new SalaryAcctRecordPO(); recordPo.setDeleteType(0); recordPo.setId(salaryAccountingId); recordPo.setStatus(SalaryAcctRecordStatusEnum.ARCHIVED.getValue()); List acctRecords = getSalaryAcctRecordMapper().listSome(recordPo); // 检查核算的归档记录 if (CollectionUtils.isEmpty(acctRecords)) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100498, "核算记录不存在")); } SalarySendPO sendPO = new SalarySendPO(); sendPO.setDeleteType(0); sendPO.setSalaryAccountingId(salaryAccountingId); List salarySends = mapper.listSome(sendPO); if (CollectionUtils.isNotEmpty(salarySends)) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100499, "工资单已生成过,不可再重复生成")); } SalaryAcctEmployeePO employeePO = new SalaryAcctEmployeePO(); employeePO.setDeleteType(0); employeePO.setSalaryAcctRecordId(salaryAccountingId); List salaryAcctEmployees = getSalaryAcctEmployeeMapper().listSome(employeePO); Long salarySendId = IdGenerator.generate(); SalaryAcctRecordPO salaryAcctRecord = acctRecords.get(0); List salarySendInfos = salaryAcctEmployees.stream().map(m -> SalarySendInfoPO.builder() .id(IdGenerator.generate()) .salarySendId(salarySendId) .employeeId(m.getEmployeeId()) .salaryMonth(m.getSalaryMonth()) .taxAgentId(m.getTaxAgentId()) .salaryAcctRecordId(m.getSalaryAcctRecordId()) .sendStatus(SalarySendStatusEnum.UNSEND.getValue()) .salaryTemplate("") .creator((long) user.getUID()) .createTime(new Date()) .updateTime(new Date()) .build() ).collect(Collectors.toList()); SalarySendPO salarySend = SalarySendPO.builder() .id(salarySendId) .salaryMonth(salaryAcctRecord.getSalaryMonth()) .salaryAccountingId(salaryAccountingId) .salarySobId(salaryAcctRecord.getSalarySobId()) .sendNum(0) .sendTotal(salarySendInfos.size()) .lastSendTime(new Date()) .creator((long) user.getUID()) .createTime(new Date()) .updateTime(new Date()) .build(); // 插入工资单发放记录 mapper.insert(salarySend); // 插入工资单人员记录 salarySendInfoMapper.batchInsert(salarySendInfos); return ""; } @Override public void revokeSalaryBill(Long salaryAccountingId) { // 校验salaryAccountingId if (salaryAccountingId == null) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100497, "核算id必传")); } SalaryAcctRecordPO po = SalaryAcctRecordPO.builder().id(salaryAccountingId).build(); List acctRecords = getSalaryAcctRecordMapper().listSome(po); // 检查核算的归档记录 if (CollectionUtils.isEmpty(acctRecords)) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100498, "核算记录不存在")); } SalarySendPO build = SalarySendPO.builder().salaryAccountingId(salaryAccountingId).deleteType(0).build(); List salarySends = getSalarySendMapper().listSome(build); if (CollectionUtils.isEmpty(salarySends)) { return; // throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100505, "工资单不存在")); } SalarySendPO salarySend = salarySends.get(0); // 已发送工资单 SalarySendInfoPO sendInfo = SalarySendInfoPO.builder() .deleteType(0) .salarySendId(salarySend.getId()) .sendStatus(SalarySendStatusEnum.ALREADYSEND.getValue()).build(); List salarySendInfos = getSalarySendInfoMapper().listSome(sendInfo); if (salarySend.getSendNum() > 0 || CollectionUtils.isNotEmpty(salarySendInfos)) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100507, "工资单已经发放,不可撤销")); } // 删除工资单 SalarySendPO salarySendPO = SalarySendPO.builder() .id(salarySend.getId()) .sendNum(0) .deleteType(1) .build(); getSalarySendMapper().updateIgnoreNull(salarySendPO); // 删除工资单发放 SalarySendInfoPO infoPO = SalarySendInfoPO.builder() .salarySendId(salarySend.getId()) .deleteType(1) .build(); getSalarySendInfoMapper().updateGrantWithdraw(infoPO, salarySend.getId(), null, null); } @Override public PageInfo listPage(SalarySendQueryParam queryParam) { List list = mapper.list(queryParam); PageInfo pageInfo = new PageInfo<>(list, SalarySendListDTO.class); return pageInfo; } @Override public SalarySendBaseInfoDTO getBaseInfo(Long id) { SalarySendPO salarySend = mapper.getById(id); if (salarySend == null) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100512, "工资单发放不存在")); } Long salaryAcctId = salarySend.getSalaryAccountingId(); SalarySobCycleDTO salarySobCycleDTO = getSalaryAcctRecordService(user).getSalarySobCycleById(salaryAcctId); String template = ""; // 获取默认模板 List salaryTemplates = getSalaryTemplateService(user).getDefaultTemplates(Collections.singletonList(salarySend.getSalarySobId())); if (CollectionUtils.isNotEmpty(salaryTemplates)) { template = salaryTemplates.get(0).getName(); } return SalarySendBaseInfoDTO.builder() .salaryMonth(salarySobCycleDTO == null ? null : salarySobCycleDTO.getSalaryMonth()) .template(template) .salarySobCycle(salarySobCycleDTO) .sendNum(salarySend.getSendNum()) .sendTotal(salarySend.getSendTotal()) .build(); } @Override public Map mySalaryBill(Long salaryInfoId, Long currentEmployeeId) { // List salarySendInfos = new LambdaQueryChainWrapper<>(salarySendInfoMapper) // .eq(SalarySendInfoPO::getDeleteType, 0) // .eq(SalarySendInfoPO::getTenantKey, currentTenantKey) // .eq(SalarySendInfoPO::getId, salaryInfoId).list(); SalarySendInfoPO po = new SalarySendInfoPO(); po.setDeleteType(0); po.setId(salaryInfoId); List salarySendInfos = salarySendInfoMapper.listSome(po); if (CollectionUtils.isEmpty(salarySendInfos)) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100511, "工资单信息不存在")); } SalarySendInfoPO salarySendInfo = salarySendInfos.get(0); // List salarySends = new LambdaQueryChainWrapper<>(mapper) // .eq(SalarySendPO::getDeleteType, 0) // .eq(SalarySendPO::getTenantKey, currentTenantKey) // .eq(SalarySendPO::getId, salarySendInfo.getSalarySendId()).list(); SalarySendPO sendPo = new SalarySendPO(); sendPo.setDeleteType(0); sendPo.setId(salarySendInfo.getSalarySendId()); List salarySends = mapper.listSome(sendPo); if (CollectionUtils.isEmpty(salarySends)) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100512, "工资单发放不存在")); } SalarySendPO salarySend = salarySends.get(0); Date salaryMonth = salarySend.getSalaryMonth(); // 获取模板 String salaryTemplateContent = salarySendInfo.getSalaryTemplate(); if (StringUtils.isBlank(salaryTemplateContent)) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100513, "没有默认模板,无法查看")); } SalaryTemplatePO salaryTemplate = buildSalaryTemplateContent(salaryTemplateContent); // if (StringUtils.isNotBlank(salaryTemplate.getBackground())) { // FileData fileByte = fileDownloadClient.getFileByte(Long.valueOf(salaryTemplate.getBackground()), currentTenantKey); // String encode = Base64Encoder.encode(fileByte.getData()); // salaryTemplate.setBackground(encode); // } // 获取薪资项目数据 SalaryAcctResultPO acctPo = new SalaryAcctResultPO(); acctPo.setDeleteType(0); acctPo.setSalaryAcctRecordId(salarySendInfo.getSalaryAcctRecordId()); acctPo.setEmployeeId(currentEmployeeId); List salaryAcctResultPOS = getSalaryAcctResultMapper().listSome(acctPo); SalaryAcctResultPOEncrypt.decryptList(salaryAcctResultPOS); List> salaryAcctResultS = salaryAcctResultPOS.stream().map(m -> { Map map = new LinkedHashMap<>(); map.put("salaryItemId", m.getSalaryItemId()); map.put("resultValue", m.getResultValue()); return map; }).collect(Collectors.toList()); Map map = new LinkedHashMap<>(); map.put("tenantName", ""); map.put("sendTime", SalaryDateUtil.getFormatLocalDateTime(salarySendInfo.getSendTime())); List listDTOS = JSONArray.parseArray(salaryTemplate.getSalaryItemSetting(), SalaryTemplateSalaryItemSetListDTO.class); Optional optionalEmployeeInformation = listDTOS.stream().filter(e -> SalaryTemplateSalaryItemSetGroupConstant.EMPLOYEE_INFO_GROUP_ID.equals(e.getGroupId())).findFirst(); SalaryTemplateSalaryItemSetListDTO employeeInformation = optionalEmployeeInformation.orElse(null); List itemSetListDTOS = listDTOS.stream().filter(e -> !SalaryTemplateSalaryItemSetGroupConstant.EMPLOYEE_INFO_GROUP_ID.equals(e.getGroupId())).collect(Collectors.toList()); itemSetListDTOS.stream().forEach(item -> { item.getItems() .forEach(e -> { if (CollectionUtils.isEmpty(salaryAcctResultS)) { e.setSalaryItemValue(""); } else { Object o = salaryAcctResultS.stream() .filter(f -> f.get("salaryItemId") != null && String.valueOf(f.get("salaryItemId")).equals(e.getSalaryItemId())).findFirst() .orElse(new HashMap<>()) .get("resultValue"); e.setSalaryItemValue(o == null ? "" : (String) o); } }); }); /** * 过滤空 */ if (Objects.equals(1, salaryTemplate.getSalaryItemNullStatus())) { for (SalaryTemplateSalaryItemSetListDTO itemSetListDTO : itemSetListDTOS) { List items = itemSetListDTO.getItems(); List collect = items.stream().filter(item -> StringUtils.isNotBlank(item.getSalaryItemValue())).collect(Collectors.toList()); itemSetListDTO.setItems(collect); } } /** * 过滤0 */ if (Objects.equals(1, salaryTemplate.getSalaryItemZeroStatus())) { for (SalaryTemplateSalaryItemSetListDTO itemSetListDTO : itemSetListDTOS) { List items = itemSetListDTO.getItems(); List collect = items.stream() .filter(item -> SalaryEntityUtil.string2BigDecimal(item.getSalaryItemValue()) == null || BigDecimal.ZERO.compareTo(SalaryEntityUtil.string2BigDecimal(item.getSalaryItemValue())) != 0) .collect(Collectors.toList()); itemSetListDTO.setItems(collect); } } TaxAgentPO taxAgentPO = getTaxAgentService(user).getById(salarySendInfo.getTaxAgentId()); DataCollectionEmployee simpleEmployee = getSalaryEmployeeService(user).getEmployeeById(salarySendInfo.getEmployeeId()); buildEmployeeInfo(employeeInformation, simpleEmployee, taxAgentPO.getName(), SalaryAcctResultBO.buildEmployeeFieldName()); map.put("employeeInformation", employeeInformation); map.put("salaryGroups", itemSetListDTOS); salaryTemplate.setTheme(getBillTitle(salaryTemplate.getTheme(), salaryMonth, currentEmployeeId)); map.put("salaryTemplate", salaryTemplate); map.put("salaryAcctResult", salaryAcctResultS); return map; } @Override public PageInfo salarySendInfoListPage(SalarySendInfoQueryParam queryParam) { //排序配置 OrderRuleVO orderRule = getSalarySysConfService(user).orderRule(); queryParam.setOrderRule(orderRule); SalaryPageUtil.start(queryParam.getCurrent(), queryParam.getPageSize()); List page = salarySendInfoMapper.list(queryParam); PageInfo result = new PageInfo<>(page, SalarySendInfoListDTO.class); return result; } @Override public List salarySendInfoList(Long salarySendId) { return salarySendInfoMapper.list(SalarySendInfoQueryParam.builder().salarySendId(salarySendId).build()); } @Override public PageInfo mySalaryBillListPage(SalaryBillQueryParam queryParam) { List list = salarySendInfoMapper.mySalaryBillList(queryParam); PageInfo pageInfo = new PageInfo<>(list, SalaryMySalaryBillListDTO.class); return pageInfo; } @Override public PageInfo salarySendInfoDetailListPage(SalarySendDetailQueryParam queryParam) { //排序配置 OrderRuleVO orderRule = getSalarySysConfService(user).orderRule(); queryParam.setOrderRule(orderRule); Set otherSalaryAcctRecordIds = null; if (queryParam.getMergeCountTax() != null && queryParam.getMergeCountTax()) { //查询关联的核酸id,这里认为一次发放只对应一条核算记录 Long salaryAccRecordId = salarySendInfoMapper.listSalaryAccRecordIds(queryParam).stream().findFirst().orElse(null); // 查询合并计税的其他薪资核算记录 List otherSalaryAcctRecordPOS = getSalaryAcctRecordService(user).listById4OtherConsolidatedTax(salaryAccRecordId); if (CollectionUtils.isEmpty(otherSalaryAcctRecordPOS)) { return new PageInfo<>(); } // 查询合并计税的薪资核算人员 otherSalaryAcctRecordIds = SalaryEntityUtil.properties(otherSalaryAcctRecordPOS, SalaryAcctRecordPO::getId); if (otherSalaryAcctRecordIds.isEmpty()) { return new PageInfo<>(); } } SalaryPageUtil.start(queryParam.getCurrent(), queryParam.getPageSize()); List list = MapperProxyFactory.getProxy(SalarySendInfoMapper.class).detailList(queryParam, otherSalaryAcctRecordIds); PageInfo pageInfo = new PageInfo<>(list, SalarySendDetailListDTO.class); return pageInfo; } /** * 获取工资单标题 * * @param theme * @param salaryMonth * @param currentEmployeeId * @return */ private String getBillTitle(String theme, Date salaryMonth, Long currentEmployeeId) { String yearI18n = SalaryI18nUtil.getI18nLabel(100325, "年"); String monthI18n = SalaryI18nUtil.getI18nLabel(100326, "月"); return theme // TODO 设置租户名称 .replace("${companyName}", "") .replace("${salaryMonth}", new SimpleDateFormat("yyyy年MM月").format(salaryMonth)); } /** * 根据模板内容转为工资单模板对象 * 注意:不要通过反序列化,可能会因为历史原因修改字段名称而无法序列化 * * @param salaryTemplateContent * @return */ private SalaryTemplatePO buildSalaryTemplateContent(String salaryTemplateContent) { Map map = JsonUtil.parseMap(salaryTemplateContent, Object.class); return SalaryTemplatePO.builder() .id(Long.valueOf(map.getOrDefault("id", "0").toString())) .name(map.getOrDefault("name", "").toString()) .salarySobId(Long.valueOf(map.getOrDefault("salarySobId", "0").toString())) .useType(Integer.valueOf(map.getOrDefault("useType", "0").toString())) .description(map.getOrDefault("description", "").toString()) .emailStatus(Integer.valueOf(map.getOrDefault("emailStatus", "0").toString())) .sendEmailId(Long.valueOf(map.getOrDefault("sendEmailId", "0").toString())) .msgStatus(Integer.valueOf(map.getOrDefault("msgStatus", "0").toString())) .theme(map.getOrDefault("theme", "").toString()) .background(map.getOrDefault("background", "").toString()) .textContent(map.getOrDefault("textContent", "").toString()) .textContentPosition(Integer.valueOf(map.getOrDefault("textContentPosition", "0").toString())) .salaryItemNullStatus(Integer.valueOf(map.getOrDefault("salaryItemNullStatus", "0").toString())) .salaryItemZeroStatus(Integer.valueOf(map.getOrDefault("salaryItemZeroStatus", "0").toString())) .salaryItemSetting(map.getOrDefault("salaryItemSetting", "").toString()) .build(); } /** * 构建工资单中的人员信息 * * @param employeeInformation * @param simpleEmployee * @param taxAgentName * @param employeeField */ private void buildEmployeeInfo(SalaryTemplateSalaryItemSetListDTO employeeInformation, DataCollectionEmployee simpleEmployee, String taxAgentName, Map employeeField) { if (employeeInformation == null) { return; } if (CollectionUtils.isNotEmpty(employeeInformation.getItems())) { //获取员工信息的字段名和中文描述的map关系 SalaryFormulaEmployeeDTO salaryFormulaEmployeeDTO = SalaryFormulaEmployeeDTO.builder().employeeId(simpleEmployee.getEmployeeId()) .birthday(simpleEmployee.getBirthday()) .departmentName(simpleEmployee.getDepartmentName()) .email(StringUtils.isEmpty(simpleEmployee.getEmail()) ? "" : simpleEmployee.getEmail()) .jobcall(simpleEmployee.getJobcall()) .companystartdate(simpleEmployee.getCompanystartdate()) .sex("0".equals(simpleEmployee.getSex()) ? "男" : "女") .mobile(StringUtils.isEmpty(simpleEmployee.getMobile()) ? "" : simpleEmployee.getMobile()) .jobtitleName(simpleEmployee.getJobtitleName()) .status(simpleEmployee.getStatus() == null ? "" : simpleEmployee.getStatus()) .telephone(StringUtils.isEmpty(simpleEmployee.getTelephone()) ? "" : simpleEmployee.getTelephone()) .username(StringUtils.isEmpty(simpleEmployee.getUsername()) ? "" : simpleEmployee.getUsername()) .taxAgentName(taxAgentName) .build(); List items = employeeInformation.getItems(); Set> entries = employeeField.entrySet(); for (SalaryTemplateSalaryItemListDTO e : items) { Optional> entry = entries.stream().filter(f -> Objects.equals(e.getName(), f.getValue())).findFirst(); if (entry.isPresent()) { String key = entry.get().getKey(); if (StringUtils.isNotBlank(key)) { String getter = "get" + key.substring(0, 1).toUpperCase() + key.substring(1); try { Method method = salaryFormulaEmployeeDTO.getClass().getMethod(getter); Object invoke = method.invoke(salaryFormulaEmployeeDTO); e.setSalaryItemValue((String) invoke); } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException ex) { log.error("no such method", e); } } } } } } /** * 组装详情数据 * * @param salaryItems * @param list * @param salaryAccountingId */ @Override public List> buildDetailList(List salaryItems, List list, Long salaryAccountingId) { List> listMaps = new ArrayList<>(); if (CollectionUtils.isEmpty(list)) { return listMaps; } // 获取薪资项目数据 // List salaryAccountingResults = new LambdaQueryChainWrapper<>(salaryAcctResultMapper) // .eq(SalaryAcctResultPO::getDeleteType, 0) // .eq(SalaryAcctResultPO::getSalaryAcctRecordId, salaryAccountingId).list(); SalaryAcctResultPO po = new SalaryAcctResultPO(); po.setDeleteType(0); po.setSalaryAcctRecordId(salaryAccountingId); po.setEmployeeIds(list.stream().map(SalarySendDetailListDTO::getEmployeeId).collect(Collectors.toList())); List salaryAccountingResults = getSalaryAcctResultMapper().listSome(po); SalaryAcctResultPOEncrypt.decryptList(salaryAccountingResults); // 动态列 list.forEach(e -> { Map map = new LinkedHashMap<>(); map.put("id", e.getId()); map.put("employeeId", e.getEmployeeId()); map.put("username", e.getUsername()); map.put("taxAgent", e.getTaxAgent()); map.put("department", e.getDepartment()); map.put("mobile", e.getMobile()); map.put("jobNum", e.getJobNum()); map.put("email", e.getEmail()); salaryItems.forEach(i -> { Optional optional = salaryAccountingResults.stream() .filter(r -> r.getEmployeeId().equals(e.getEmployeeId()) && r.getSalaryItemId().equals(Long.valueOf(i.getSalaryItemId()))).findFirst(); map.put(i.getSalaryItemId() + SalaryItemConstant.DYNAMIC_SUFFIX, optional.isPresent() ? optional.get().getResultValue() : ""); }); listMaps.add(map); }); return listMaps; } /** * 通过薪资账套获取模板的薪资项目 * * @param salaryTemplate * @return */ @Override public List getSalaryItemsSetting(SalaryTemplatePO salaryTemplate) { List salaryItems = new ArrayList<>(); if (salaryTemplate == null) { return salaryItems; } if (StringUtils.isNotEmpty(salaryTemplate.getSalaryItemSetting())) { List salaryTemplateShowSetData = JsonUtil.parseList(salaryTemplate.getSalaryItemSetting(), SalaryTemplateSalaryItemSetListDTO.class); salaryTemplateShowSetData.stream().filter(f -> !f.getGroupId().equals(SalaryTemplateSalaryItemSetGroupConstant.EMPLOYEE_INFO_GROUP_ID)).forEach(e -> { salaryItems.addAll(e.getItems()); }); } return salaryItems; } @Override public Map grant(SalarySendGrantParam param) { if (param.getSalarySendId() == null) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100327, "工资单发放Id必传")); } Long salarySendId = param.getSalarySendId(); Collection ids = param.getIds(); if (param.getSalarySendRangeIds() != null) { //如果传了范围id,则使用范围id发放 ids = getSalarySendRangeService(user) .getSendInfoIdsBySendId(salarySendId, param.getSalarySendRangeIds(), SalarySendGrantTypeEnum.GRANT); if (ids.isEmpty()) {// 由于查出来是空的,会导致全部发放,在此进行拦截 throw new SalaryRunTimeException("工资发放范围内没有匹配员工"); } } SalarySendPO salarySend = mapper.getById(salarySendId); if (salarySend == null) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100512, "工资单发放不存在")); } // 获取默认模板 List salaryTemplates = getSalaryTemplateService(user).getDefaultTemplates(Collections.singletonList(salarySend.getSalarySobId())); if (CollectionUtils.isEmpty(salaryTemplates)) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100518, "没有默认模板,无法发送")); } Date sendTime = new Date(); // 获取可发送的列表 List> enableSendList = getEnableSendList(salarySend, ids, salaryTemplates.get(0)); // 1.发放 SalarySendInfoPO po = new SalarySendInfoPO(); po.setSendStatus(SalarySendStatusEnum.ALREADYSEND.getValue()); po.setSendTime(sendTime); po.setSalaryTemplate(JsonUtil.toJsonString(salaryTemplates.get(0))); salarySendInfoMapper.updateGrantWithdraw(po, salarySendId, Arrays.asList(SalarySendStatusEnum.UNSEND.getValue(), SalarySendStatusEnum.WITHDRAW.getValue()), ids); // 2.更新数量 po = new SalarySendInfoPO(); po.setDeleteType(0); po.setSalarySendId(salarySendId); List list = salarySendInfoMapper.listSome(po); //需要发送工资的人 List sendList = list.stream().filter(e -> e.getSendStatus().equals(SalarySendStatusEnum.ALREADYSEND.getValue())).collect(Collectors.toList()); int sendNum = sendList.size(); int sendTotal = list.size(); SalarySendPO salarySendNew = new SalarySendPO(); try { BeanUtils.copyProperties(salarySendNew, salarySend); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } salarySendNew.setSendNum(sendNum); salarySendNew.setSendTotal(sendTotal); salarySendNew.setLastSendTime(sendTime); mapper.updateById(salarySendNew); // List salarySobs = new LambdaQueryChainWrapper<>(salarySobMapper) // .eq(SalarySobPO::getTenantKey, TenantContext.getCurrentTenantKey()) // .eq(SalarySobPO::getDeleteType, 0) // .eq(SalarySobPO::getId, salarySend.getSalarySobId()) // .list(); SalarySobPO salarySobPO = new SalarySobPO(); salarySobPO.setDeleteType(0); salarySobPO.setId(salarySend.getSalarySobId()); // List salarySobs = salarySobMapper.listSome(salarySobPO); // 记录日志 // SalaryLoggerUtil.recordUpdateSingleLog(salarySendLoggerTemplate, // salarySend.getId(), // salarySend.getSalaryMonth() + "-" + (CollectionUtils.isNotEmpty(salarySobs) ? salarySobs.get(0).getName() : ""), // SalaryI18nUtil.getI18nLabel(currentTenantKey, currentEmployeeId, 93215, "工资单发放"), // SalaryI18nUtil.getI18nLabel(currentTenantKey, currentEmployeeId, 93215, "工资单发放"), // salarySend, // salarySendNew); // 3.异步发送消息:先修改数据再发消息,避免出错后无法撤回 // TODO 异步发送消息 // String tenantName = TenantContext.getCurrentTenant().getTenantName(); // taskExecutor.execute(() -> { // try { // DSTenantKeyThreadVar.tenantKey.set(currentTenantKey); // sendMessage(salarySend, enableSendList, salaryTemplates.get(0), tenantName, currentEmployeeId, currentTenantKey); // } finally { // DSTenantKeyThreadVar.tenantKey.remove(); // } // }); List needSendList = Lists.newArrayList(); enableSendList.forEach(map -> { sendList.forEach(item -> { if (item.getId() == Long.valueOf(map.get("id").toString()).longValue()) { needSendList.add(item); } }); }); // 发送消息 sendMessage(true, needSendList, param, salarySend); Map map = new HashMap<>(2); map.put("sendNum", sendNum); map.put("sendTotal", sendTotal); return map; } /** * 发送消息 * * @param sendFlag true 发送 false 撤回 * @param list * @param param * @param salarySend */ private void sendMessage(boolean sendFlag, List list, SalarySendGrantParam param, SalarySendPO salarySend) { Date salaryMonth = salarySend.getSalaryMonth(); String month = DateUtil.format(salaryMonth, "yyyy-MM"); new Thread() { public void run() { List collect = new ArrayList<>(); if (CollectionUtils.isNotEmpty(param.getIds())) { collect = new ArrayList<>(param.getIds()); } else { collect = list.stream().map(item -> item.getId()).collect(Collectors.toList()); } collect.forEach(item -> { SalarySendInfoPO po = SalarySendInfoPO.builder().id(item).build(); List salarySendInfoPOS = salarySendInfoMapper.listSome(po); if (CollectionUtils.isNotEmpty(salarySendInfoPOS)) { Long employeeId = salarySendInfoPOS.get(0).getEmployeeId(); if (sendFlag) { sendPayRollEMMessage(item, employeeId, month); } else { withdrawPayrollEMMessage(item, employeeId); } } }); } }.start(); } /** * 发送Em消息 */ private void sendPayRollEMMessage(Long id, Long employeeId, String month) { MessageType messageType = MessageType.newInstance(499); // 消息来源(见文档第四点补充 必填) Set userIdList = new HashSet<>(); // 接收人id 必填 userIdList.add(employeeId.toString()); String title = month + " 工资单"; // 标题 String context = "点击查看详情"; // 内容 String linkUrl = weaver.general.GCONST.getContextPath() + "/spa/hrmSalary/static/index.html#/main/hrmSalary/mobilepayroll?id=" + id; // PC端链接 String linkMobileUrl = weaver.general.GCONST.getContextPath() + "/spa/hrmSalary/static/index.html#/main/hrmSalary/mobilepayroll?type=phone&id=" + id; // 移动端链接 try { MessageBean messageBean = Util_Message.createMessage(messageType, userIdList, title, context, linkUrl, linkMobileUrl); messageBean.setCreater(user.getUID());// 创建人id messageBean.setBizState("0");// 需要修改消息为已处理等状态时传入,表示消息最初状态为待处理 messageBean.setTargetId("499|" + id); //消息来源code +“|”+业务id需要修改消息为已处理等状态时传入 Util_Message.store(messageBean); } catch (IOException e) { e.printStackTrace(); } } /** * 撤回EM消息 * * @param id */ private void withdrawPayrollEMMessage(Long id, Long employeeId) { try { MessageBean messageBean = Util_Message.createMessage(); messageBean.setUserList(new HashSet<>());//接收人id messageBean.setUserId(employeeId.intValue()); messageBean.setTargetId("499|" + id); //code + “|” + 业务id //messageBean.setMessageType(MessageType.newInstance(121));//消息来源code(传了代表code也做为删除时的条件,默认不传) Util_Message.delMessageTargetid(messageBean); } catch (Exception e) { e.printStackTrace(); } } private List> getEnableSendList(SalarySendPO salarySend, Collection ids, SalaryTemplatePO salaryTemplate) { // 1.根据模板获取薪资项目设置 List salaryItems = getSalaryItemsSetting(salaryTemplate); SalarySendDetailQueryParam queryParam = new SalarySendDetailQueryParam(); queryParam.setSalarySendId(salarySend.getId()); // 空就是所有 queryParam.setIds(ids); queryParam.setSendStatuss(Arrays.asList(SalarySendStatusEnum.UNSEND.getValue(), SalarySendStatusEnum.WITHDRAW.getValue())); // 2.获取基本数据 List list = salarySendInfoMapper.detailList(queryParam, null); // 3.组装详情数据 List> listMaps = buildDetailList(salaryItems, list, salarySend.getSalaryAccountingId()); return listMaps; } // /** // * 发送消息 // * // * @param salarySend // * @param enableSendList // * @param salaryTemplate // * @param currentTenantKey // */ // private void sendMessage(SalarySendPO salarySend, List> enableSendList, SalaryTemplatePO salaryTemplate, String tenantName, Long currentEmployeeId, String currentTenantKey) { // if (StringUtils.isNotBlank(salaryTemplate.getBackground())) { // FileData fileByte = fileDownloadClient.getFileByte(Long.valueOf(salaryTemplate.getBackground()), currentTenantKey); // String encode = Base64Encoder.encode(fileByte.getData()); // salaryTemplate.setBackground(encode); // } // // 邮箱打开 // boolean isEmailOpen = salaryTemplate.getEmailStatus().equals(SalaryTemplateWhetherEnum.TRUE.getValue()); // // LocalDate salaryMonth = salarySend.getSalaryMonth(); // String yearI18n = SalaryI18nUtil.getI18nLabel(currentTenantKey, currentEmployeeId, 100325, "年"); // String monthI18n = SalaryI18nUtil.getI18nLabel(currentTenantKey, currentEmployeeId, 100326, "月"); // String text = salaryMonth.getYear() + // yearI18n + // salaryMonth.getMonth().getValue() + // monthI18n + // SalaryI18nUtil.getI18nLabel(currentTenantKey, currentEmployeeId, 100520, "工资待发明细"); // // UserEntity sendUser = null; // // 标题 // String title = getBillTitle(salaryTemplate.getTheme(), salaryMonth, tenantName, currentEmployeeId, currentTenantKey); // // // 获取所有人员信息 // List ids = enableSendList.stream().map(e->Long.valueOf(e.get("employeeId").toString())).collect(Collectors.toList()); // List allEmployees = hrmCommonEmployeeService.getEmployeeByIds(ids, currentTenantKey); // List listDTOS = JSONArray.parseArray(salaryTemplate.getSalaryItemSetting(), SalaryTemplateSalaryItemSetListDTO.class); // Optional optionalEmployeeInformation = listDTOS.stream().filter(e -> SalaryTemplateSalaryItemSetGroupConstant.EMPLOYEE_INFO_GROUP_ID.equals(e.getGroupId())).findFirst(); // SalaryTemplateSalaryItemSetListDTO employeeInformation = optionalEmployeeInformation.orElse(null); // Map employeeField = SalaryAcctResultBO.buildEmployeeFieldName(); // enableSendList.forEach(e -> { // Optional optionalSimpleEmployee = allEmployees.stream().filter(f->f.getEmployeeId().equals(Long.valueOf(e.get("employeeId").toString()))).findFirst(); // if (optionalSimpleEmployee.isPresent()) { // buildEmployeeInfo(employeeInformation, optionalSimpleEmployee.get(), e.get("taxAgent").toString(), employeeField); // } // // List receivers = Collections.singletonList( // SalarySendBO.buildUser(Long.valueOf(e.get("employeeId").toString()), e.get("email") == null ? "" : e.get("email").toString(), currentTenantKey)); // Entity entity = SalarySendBO.buildEntity(e.get("id").toString(), SalaryI18nUtil.getI18nLabel(currentTenantKey, currentEmployeeId, 94626, "工资单")); // EmailEntity emailInfo = new EmailEntity(); // // 邮箱打开 // if (isEmailOpen) { // String emailContent = SalarySendBO.buildEmailContent(e, employeeInformation, title, salaryTemplate); // emailInfo = SalarySendBO.buildEmailInfo(text, emailContent, salaryTemplate.getSendEmailId()); // } // SendMessageEntity message = SalarySendBO.buildSendMessageEntity(text, sendUser, receivers, entity, emailInfo); // log.info("开始发送============:{}", JsonUtil.toJsonString(message)); // // 开始发送 // log.info("发送结果===:{}", JsonUtil.toJsonString(asyncSystemMessageRest.sendMsg(message))); // }); // } @Override public Map withdraw(SalarySendWithdrawParam param) { if (param.getSalarySendId() == null) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100327, "工资单发放Id必传")); } Long salarySendId = param.getSalarySendId(); Collection ids = param.getIds(); if (param.getSalarySendRangeIds() != null) { //如果传了范围id,则使用范围id撤回 ids = getSalarySendRangeService(user) .getSendInfoIdsBySendId(salarySendId, param.getSalarySendRangeIds(), SalarySendGrantTypeEnum.WITHDRAW); if (ids.isEmpty()) {// 由于查出来是空的,会导致全部发放,在此进行拦截 throw new SalaryRunTimeException("工资撤回范围内没有匹配的员工"); } } SalarySendPO salarySend = mapper.getById(salarySendId); if (salarySend == null) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100512, "工资单发放不存在")); } // // 获取可撤回的工资单 // List enableWithdrawList = new LambdaQueryChainWrapper<>(salarySendInfoMapper) // .eq(SalarySendInfoPO::getDeleteType, 0) // .eq(SalarySendInfoPO::getTenantKey, currentTenantKey) // .eq(SalarySendInfoPO::getSalarySendId, salarySendId) // .eq(SalarySendInfoPO::getSendStatus, SalarySendStatusEnum.ALREADYSEND.getValue()) // .in(CollectionUtils.isNotEmpty(ids), SalarySendInfoPO::getId, ids) // .list(); // 撤回 // new LambdaUpdateChainWrapper<>(salarySendInfoMapper) // .eq(SalarySendInfoPO::getDeleteType, 0) // .eq(SalarySendInfoPO::getSalarySendId, salarySendId) // .eq(SalarySendInfoPO::getSendStatus, SalarySendStatusEnum.ALREADYSEND.getValue()) // .in(CollectionUtils.isNotEmpty(ids), SalarySendInfoPO::getId, ids) // .set(SalarySendInfoPO::getSendStatus, SalarySendStatusEnum.WITHDRAW.getValue()) // .update(); SalarySendInfoPO po = new SalarySendInfoPO(); po.setSendStatus(SalarySendStatusEnum.WITHDRAW.getValue()); List statusList = new ArrayList<>(); statusList.add(SalarySendStatusEnum.ALREADYSEND.getValue()); salarySendInfoMapper.updateGrantWithdraw(po, salarySendId, statusList, ids); // List list = new LambdaQueryChainWrapper<>(salarySendInfoMapper) // .eq(SalarySendInfoPO::getDeleteType, 0) // .eq(SalarySendInfoPO::getTenantKey, currentTenantKey) // .eq(SalarySendInfoPO::getSalarySendId, salarySendId).list(); po = new SalarySendInfoPO(); po.setDeleteType(0); po.setSalarySendId(salarySendId); List list = salarySendInfoMapper.listSome(po); int sendNum = (int) list.stream().filter(e -> e.getSendStatus().equals(SalarySendStatusEnum.ALREADYSEND.getValue())).count(); int sendTotal = list.size(); SalarySendPO salarySendNew = new SalarySendPO(); try { BeanUtils.copyProperties(salarySendNew, salarySend); } catch (Exception e) { throw new SalaryRunTimeException("数据转换异常, " + e.getMessage()); } salarySendNew.setSendNum(sendNum); salarySendNew.setSendTotal(sendTotal); mapper.updateById(salarySendNew); // List salarySobs = new LambdaQueryChainWrapper<>(salarySobMapper) // .eq(SalarySobPO::getTenantKey, TenantContext.getCurrentTenantKey()) // .eq(SalarySobPO::getDeleteType, 0) // .eq(SalarySobPO::getId, salarySend.getSalarySobId()) // .list(); // 记录日志 // SalaryLoggerUtil.recordUpdateSingleLog(salarySendLoggerTemplate, // salarySend.getId(), // salarySend.getSalaryMonth() + "-" + (CollectionUtils.isNotEmpty(salarySobs) ? salarySobs.get(0).getName() : ""), // SalaryI18nUtil.getI18nLabel(currentTenantKey, currentEmployeeId, 100521, "撤回工资单发放"), // SalaryI18nUtil.getI18nLabel(currentTenantKey, currentEmployeeId, 100521, "撤回工资单发放"), // salarySend, // salarySendNew); SalarySendGrantParam grantParam = SalarySendGrantParam.builder().ids(param.getIds()).salarySendId(param.getSalarySendId()).build(); // 撤回消息 sendMessage(false, list, grantParam, salarySend); // // 3.异步发送消息:先修改数据再发消息,避免出错后无法撤回 // taskExecutor.execute(() -> { // try { // DSTenantKeyThreadVar.tenantKey.set(currentTenantKey); // // String text = "工资单撤回测试消息文案,不好意思,弄错了"; // String title = SalaryI18nUtil.getI18nLabel(currentTenantKey, currentEmployeeId, 94626, "工资单"); // enableWithdrawList.forEach(e->{ // CancleMessageEntity cme = SalarySendBO.buildCancleMessageEntity(e.getEmployeeId(), // e.getMsgId(), // text, // title, // currentEmployeeId, // currentTenantKey); // log.info("撤回结果===:{}", JsonUtil.toJsonString(asyncSystemMessageRest.cancleMsg(cme))); // }); // } finally { // DSTenantKeyThreadVar.tenantKey.remove(); // } // }); Map map = new HashMap<>(2); map.put("sendNum", sendNum); map.put("sendTotal", sendTotal); return map; } @Override public XSSFWorkbook exportInfoList(SalarySendInfoQueryParam queryParam) { // 1.工作簿名称 String sheetName = SalaryI18nUtil.getI18nLabel(100528, "工资单发放信息"); List header = new ArrayList<>(); header.add(SalaryI18nUtil.getI18nLabel(85429, "姓名")); header.add(SalaryI18nUtil.getI18nLabel(86184, "个税扣缴义务人")); header.add(SalaryI18nUtil.getI18nLabel(86185, "部门")); header.add(SalaryI18nUtil.getI18nLabel(86186, "手机号")); header.add(SalaryI18nUtil.getI18nLabel(86317, "工号")); header.add(SalaryI18nUtil.getI18nLabel(86317, "发送状态")); List> rows = new ArrayList<>(); // 2.表头 rows.add(header); // 校验 SalarySendInfoQueryParam.checkParam(queryParam); // 获取行数据 //排序配置 OrderRuleVO orderRule = getSalarySysConfService(user).orderRule(); queryParam.setOrderRule(orderRule); List list = salarySendInfoMapper.list(queryParam); list.forEach(e -> { // 发放状态 e.setSendStatus(SalarySendStatusEnum.getDefaultLabelByValue(Integer.valueOf(e.getSendStatus()))); }); // 3.添加行记录 // 3.表数据 for (SalarySendInfoListDTO dto : list) { List row = new ArrayList<>(); row.add(dto.getUsername()); row.add(dto.getTaxAgent()); row.add(dto.getDepartment()); row.add(dto.getMobile()); row.add(dto.getJobNum()); row.add(dto.getSendStatus()); rows.add(row); } return ExcelUtil.genWorkbookV2(rows, sheetName); } // @BatchExportHandler("exportSalarySendInfo") // public void salarySendInfoExportHandler() { // BatchCallbackMessage message = BatchExportContext.getBatchCallbackMessage(); // System.out.println("接受到导出的结果" + JSONObject.toJSONString(message)); // } @Override public XSSFWorkbook exportDetailList(SalarySendPO salarySend, SalarySendDetailQueryParam queryParam) { // 1.根据模板获取薪资项目设置 List salaryTemplates = getSalaryTemplateService(user).getDefaultTemplates(Collections.singletonList(salarySend.getSalarySobId())); List salaryItems = getSalaryItemsSetting(CollectionUtils.isNotEmpty(salaryTemplates) ? salaryTemplates.get(0) : null); // 2.获取基本数据 //排序配置 OrderRuleVO orderRule = getSalarySysConfService(user).orderRule(); queryParam.setOrderRule(orderRule); List list = salarySendInfoMapper.detailList(queryParam, null); // 3.组装详情数据 List> listMaps = buildDetailList(salaryItems, list, salarySend.getSalaryAccountingId()); // 1.工作簿名称 String sheetName = SalaryI18nUtil.getI18nLabel(97036, "工资单发放详情"); List header = new ArrayList<>(); header.add(SalaryI18nUtil.getI18nLabel(85429, "姓名")); header.add(SalaryI18nUtil.getI18nLabel(86185, "部门")); header.add(SalaryI18nUtil.getI18nLabel(86186, "手机号")); header.add(SalaryI18nUtil.getI18nLabel(86317, "工号")); // 动态列 if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(salaryItems)) { for (SalaryTemplateSalaryItemListDTO salaryItem : salaryItems) { header.add(salaryItem.getName()); } } List> rows = new ArrayList<>(); // 2.表头 rows.add(header); // 3.表数据 for (Map dto : listMaps) { List row = new ArrayList<>(); row.add(dto.get("username")); row.add(dto.get("departmentName")); row.add(dto.get("mobile")); row.add(dto.get("jobNum")); // 动态列 Map mapColumn = listMaps.get(0); for (SalaryTemplateSalaryItemListDTO salaryItem : salaryItems) { if (mapColumn.containsKey(salaryItem.getId() + SalaryItemConstant.DYNAMIC_SUFFIX)) { row.add(dto.get(salaryItem.getId() + SalaryItemConstant.DYNAMIC_SUFFIX)); } } rows.add(row); } return ExcelUtil.genWorkbookV2(rows, sheetName); } // // @BatchExportHandler("exportSalarySendDetail") // public void salarySendDetailExportHandler() { // BatchCallbackMessage message = BatchExportContext.getBatchCallbackMessage(); // System.out.println("接受到导出的结果" + JSONObject.toJSONString(message)); // } }