package com.engine.salary.service.impl; import cn.hutool.core.lang.Validator; import com.alibaba.fastjson.JSON; 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.SalaryArchiveConstant; import com.engine.salary.constant.SalaryItemConstant; import com.engine.salary.constant.SalaryTemplateSalaryItemSetGroupConstant; import com.engine.salary.encrypt.EncryptUtil; import com.engine.salary.entity.datacollection.DataCollectionEmployee; import com.engine.salary.entity.salaryBill.bo.SalaryBillBO; 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.SalaryAcctFormulaBO; import com.engine.salary.entity.salaryacct.bo.SalaryAcctResultBO; import com.engine.salary.entity.salaryacct.param.SalaryAcctResultQueryParam; 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.salaryitem.po.SalaryItemPO; import com.engine.salary.entity.salarysob.dto.SalarySobCycleDTO; import com.engine.salary.entity.salarysob.po.SalarySobBackItemPO; import com.engine.salary.entity.salarysob.po.SalarySobItemPO; 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.salaryarchive.SalaryArchiveFieldTypeEnum; import com.engine.salary.enums.salarybill.BillConfimStatusEnum; import com.engine.salary.enums.salarybill.BillReadStatusEnum; import com.engine.salary.enums.salarybill.SalarySendStatusEnum; import com.engine.salary.enums.salarybill.SalaryTemplateReplenishRuleEnum; import com.engine.salary.enums.salaryitem.SalaryDataTypeEnum; 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.ObjectUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.math.NumberUtils; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import weaver.common.MessageUtil; import weaver.hrm.User; import weaver.hrm.company.SubCompanyComInfo; import weaver.hrm.resource.ResourceComInfo; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.math.BigDecimal; import java.text.SimpleDateFormat; import java.time.LocalDateTime; import java.time.ZoneOffset; import java.util.*; import java.util.stream.Collectors; import static com.engine.salary.cache.SalaryCacheKey.SALARY_CACHE_SMS_CODE; /** * @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 EncryptUtil encryptUtil = new EncryptUtil(); 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); } private SalarySobService getSalarySobService(User user) { return ServiceUtil.getService(SalarySobServiceImpl.class, user); } private SalaryItemService getSalaryItemService(User user) { return ServiceUtil.getService(SalaryItemServiceImpl.class, user); } private SalaryAcctEmployeeService getSalaryAcctEmployeeService(User user) { return ServiceUtil.getService(SalaryAcctEmployeeServiceImpl.class, user); } private SalaryAcctResultService getSalaryAcctResultService(User user) { return ServiceUtil.getService(SalaryAcctResultServiceImpl.class, user); } private SalarySobItemService getSalarySobItemService(User user) { return ServiceUtil.getService(SalarySobItemServiceImpl.class, user); } private SalarySobBackItemService getSalarySobBackItemService(User user) { return ServiceUtil.getService(SalarySobBackItemServiceImpl.class, user); } private SalaryBillService getSalaryBillService(User user) { return ServiceUtil.getService(SalaryBillServiceImpl.class, user); } private SalaryCacheService getSalaryCacheService(User user) { return ServiceUtil.getService(SalaryCacheServiceImpl.class, user); } @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, "核算记录不存在")); } List salaryAcctEmployees = getSalaryAcctEmployeeService(user).listBySalaryAcctRecordIds(Collections.singletonList(salaryAccountingId)); // 根据人员id去重 salaryAcctEmployees = salaryAcctEmployees.stream() .collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(SalaryAcctEmployeePO::getEmployeeId))), ArrayList::new)); // 1.回算:如果是回算,todo 要等原始核算发完或者上一个回算记录发完才行,目前最多只有一个回算记录 if (Objects.equals(acctRecords.get(0).getBackCalcStatus(), (NumberUtils.INTEGER_ONE))) { SalarySendPO sendPO = new SalarySendPO(); sendPO.setDeleteType(0); sendPO.setSalaryAccountingId(salaryAccountingId); List salarySends = mapper.listSome(sendPO); if (CollectionUtils.isEmpty(salarySends)) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(139700, "还没有正常核算,不能进行回算")); } // todo 一般只有一个未冻结,同一个原始核算id,后面如果有多级回算,就会换成不同核算id SalarySendPO salarySend = salarySends.stream().filter(s -> s.getSendStatus().equals(NumberUtils.INTEGER_ZERO)).findFirst().orElse(null); // 根据工资单补发模板规则过滤人员,已发补发的合计项目不等于0的进行过滤 SalarySobPO salarySob = getSalarySobService(user).getById(acctRecords.get(0).getSalarySobId()); List salaryTemplates = getSalaryTemplateService(user) .getDefaultTemplates(Arrays.asList(acctRecords.get(0).getSalarySobId(), salarySob == null ? 0L : salarySob.getId())); // 如果有默认模板,且规则不是全部 if (CollectionUtils.isNotEmpty(salaryTemplates) && StringUtils.isEmpty(salaryTemplates.get(0).getReplenishRule())) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(140649, "请维护补发工资单模板信息")); } Long backCalcItemId = CollectionUtils.isNotEmpty(salaryTemplates) && !SalaryTemplateReplenishRuleEnum.ALL.getValue().equals(salaryTemplates.get(0).getReplenishRule()) ? Long .parseLong(salaryTemplates.get(0).getReplenishRule()) : 0L; SalaryItemPO salaryItem = getSalaryItemService(user).getById(backCalcItemId); if (salaryItem != null && salaryItem.getDataType().equals(SalaryArchiveFieldTypeEnum.NUMBER.getValue())) { // 目前是单个薪资项目 List salaryAcctResultValues = getSalaryAcctResultService(user).listBySalaryAcctRecordIdsAndSalaryItemIds(Collections.singleton(salaryAccountingId), Collections.singleton(backCalcItemId)); Set salaryAcctEmployeeIds = salaryAcctResultValues.stream() .filter(salaryAcctResultPO -> SalaryEntityUtil.empty2Zero(salaryAcctResultPO.getResultValue()).compareTo(BigDecimal.ZERO) != 0) .map(SalaryAcctResultPO::getSalaryAcctEmpId) .collect(Collectors.toSet()); salaryAcctEmployees = salaryAcctEmployees.stream().filter(se -> salaryAcctEmployeeIds.contains(se.getId())).collect(Collectors.toList()); } // 将未冻结的给冻结掉 if (salarySend != null) { salarySend.setSendStatus(NumberUtils.INTEGER_ONE); mapper.updateById(salarySend); } // 2.正常核算 } else { 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, "工资单已生成过,不可再重复生成")); } } Long salarySendId = IdGenerator.generate(); SalaryAcctRecordPO salaryAcctRecord = acctRecords.get(0); // 工资单模板类型:0,正常核算,1是回算,todo 后续可能还有别的算,需要改这里 Integer templateType = salaryAcctRecord.getBackCalcStatus(); // 构建工资单发放数据 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("") .salaryAcctType(templateType) .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()) .sendStatus(NumberUtils.INTEGER_ZERO) // 未冻结 .salaryAcctType(templateType) .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(SalaryAcctRecordPO salaryAcctRecord) { // 校验salaryAccountingId // if (salaryAcctRecord == null) { // throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100497, "核算id必传")); // } // // SalaryAcctRecordPO po = SalaryAcctRecordPO.builder().id(salaryAccountingId).build(); // List acctRecords = getSalaryAcctRecordMapper().listSome(po); // 检查核算的归档记录 if (salaryAcctRecord == null) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100498, "核算记录不存在")); } SalarySendPO build = SalarySendPO.builder().salaryAccountingId(salaryAcctRecord.getId()).deleteType(0).build(); List salarySends = getSalarySendMapper().listSome(build); if (CollectionUtils.isEmpty(salarySends)) { return; // throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100505, "工资单不存在")); } SalarySendPO salarySend; if (salaryAcctRecord.getBackCalcStatus() != null && salaryAcctRecord.getBackCalcStatus().equals(NumberUtils.INTEGER_ONE)) { // todo 一般只有一个未冻结,同一个原始核算id,后面如果有多级回算,就会换成不同核算id salarySend = salarySends.stream().filter(s -> s.getSendStatus().equals(NumberUtils.INTEGER_ZERO)).findFirst().orElse(null); // if (salarySend != null && salarySend.getSendNum() < salarySend.getSendTotal()) { // throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(139702, "正常原始核算或上一个回算尚未全部发送完成,不能进行撤回")); // } if (salarySend != null) { // 将上一版本未冻结的给冻结掉 salarySend.setSendStatus(NumberUtils.INTEGER_ONE); getSalarySendMapper().updateIgnoreNull(salarySend); } // 已经回算的删除 todo 以后多级回算注意要修改 salarySend = salarySends.stream().filter(s -> s.getSalaryAcctType() != null && s.getSalaryAcctType().equals(NumberUtils.INTEGER_ONE)).findFirst().orElse(null); handleDelSalaryBill(salarySend); // 2.正常核算处理 } else { salarySend = salarySends.stream().filter(s -> s.getSendStatus().equals(NumberUtils.INTEGER_ZERO)).findFirst().orElse(null); handleDelSalaryBill(salarySend); } } private void handleDelSalaryBill(SalarySendPO salarySend) { if (salarySend == null) { return; } // 已发送工资单 SalarySendInfoPO sendInfo = SalarySendInfoPO.builder() .deleteType(0) .salarySendId(salarySend.getId()) .sendStatus(SalarySendStatusEnum.ALREADYSEND.getValue()) .salaryAcctType(NumberUtils.INTEGER_ZERO).build(); List salarySendInfos = getSalarySendInfoMapper().listSome(sendInfo); if ((salarySend.getSendNum() > 0 || CollectionUtils.isNotEmpty(salarySendInfos)) && Objects.equals(salarySend.getSalaryAcctType(), NumberUtils.INTEGER_ONE)) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100507, "补发工资单已经发放,不可进行回算")); } else 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)) { // 是否是回算 if (Objects.equals(salarySend.getSalaryAcctType(), NumberUtils.INTEGER_ONE)) { template = salaryTemplates.get(0).getReplenishName(); } else { template = salaryTemplates.get(0).getName(); } } Boolean canSend = true; SalaryAcctRecordPO acctRecord = getSalaryAcctRecordService(user).getById(salaryAcctId); // 回算过,但是查看的是普通工资单(不能发);回算过,但是查看的是回算工资单(可以发);记录没回算过(可以发) if(Objects.equals(acctRecord.getBackCalcStatus(), NumberUtils.INTEGER_ONE) && Objects.equals(salarySend.getSalaryAcctType(),NumberUtils.INTEGER_ZERO)){ canSend = false; } return SalarySendBaseInfoDTO.builder() .salaryMonth(salarySobCycleDTO.getSalaryMonth()) .template(template) .salarySobCycle(salarySobCycleDTO) .sendNum(salarySend.getSendNum()) .sendTotal(salarySend.getSendTotal()) .canSend(canSend) // .salaryAcctType(salarySend.getSalaryAcctType().toString()) // .haveBackCalc(haveBackCalc ? NumberUtils.INTEGER_ONE : NumberUtils.INTEGER_ZERO) .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(); if (salaryInfoId == null) { throw new SalaryRunTimeException("工资单记录不存在!"); } 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, "工资单信息不存在")); } if(currentEmployeeId.compareTo(salarySendInfos.get(0).getEmployeeId()) != 0){ throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100511, "当前账号无法查看此工资单")); } SalarySendInfoPO salarySendInfo = salarySendInfos.get(0); // 获取默认模板信息 SalarySendPO salarySendPO = getSalarySendMapper().getById(salarySendInfo.getSalarySendId()); if(ObjectUtils.isEmpty(salarySendPO)) throw new SalaryRunTimeException("工资单不存在"); // 更新查看状态 if (salarySendInfo.getBillReadStatus() == null || NumberUtils.compare(salarySendInfo.getBillReadStatus(),BillReadStatusEnum.UNREAD.getValue()) == 0) { salarySendInfo.setBillReadStatus(BillReadStatusEnum.READED.getValue()); salarySendInfo.setUpdateTime(new Date()); getSalarySendInfoMapper().updateIgnoreNull(salarySendInfo); } // 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); // 判断是否是补发 boolean isReplenish = NumberUtils.INTEGER_ONE.equals(salarySendInfo.getSalaryAcctType()); // 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); encryptUtil.decryptList(salaryAcctResultPOS, SalaryAcctResultPO.class); SalaryAcctRecordPO salaryAcctRecordPO = getSalaryAcctRecordService(user).getById(salarySendInfo.getSalaryAcctRecordId()); if (salaryAcctRecordPO == null) { throw new SalaryRunTimeException("薪资核算记录不存在!"); } List> salaryAcctResultS = null; if (Objects.equals(salaryAcctRecordPO.getBackCalcStatus(), NumberUtils.INTEGER_ONE) && !isReplenish) { // 该记录回算过,并且获取的不是回算后的工资单 salaryAcctResultS = salaryAcctResultPOS.stream().map(m -> { Map map = new LinkedHashMap<>(); map.put("salaryItemId", m.getSalaryItemId()); map.put("resultValue", m.getOriginResultValue()); return map; }).collect(Collectors.toList()); } else { 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(isReplenish ? salaryTemplate.getReplenishSalaryItemSetting() : 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()); List> finalSalaryAcctResultS = salaryAcctResultS; itemSetListDTOS.stream().forEach(item -> { item.getItems() .forEach(e -> { if (CollectionUtils.isEmpty(finalSalaryAcctResultS)) { e.setSalaryItemValue(""); } else { Object o = finalSalaryAcctResultS.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)); // 工资单水印文本型动态变量 == 处理 handleSalaryWatermark(salaryTemplate, salarySendInfo, currentEmployeeId); map.put("salaryTemplate", salaryTemplate); map.put("salaryAcctResult", salaryAcctResultS); // 工资单发送人、是否已确认 if (NumberUtils.compare(salaryTemplate.getAckFeedbackStatus(),1) == 0) { map.put("confirmStatus", salarySendInfo.getBillConfirmStatus() == null ? "0" : salarySendInfo.getBillConfirmStatus().toString()); map.put("sendEmployeeId", salarySendInfo.getSendEmployeeId()); }else{ map.put("confirmStatus", "1"); } return map; } /** * 工资单水印文本型动态变量 == 处理 * * @param salaryTemplate * @param salarySendInfo */ private void handleSalaryWatermark(SalaryTemplatePO salaryTemplate, SalarySendInfoPO salarySendInfo, Long currentEmployeeId) { SalaryBillWatermarkDTO salaryBillWatermark = JsonUtil.parseObject(salaryTemplate.getSalaryWatermark(), SalaryBillWatermarkDTO.class); if (Objects.isNull(salaryBillWatermark) || Boolean.FALSE.equals(salaryBillWatermark.getWatermarkStatus()) ) { return; } // 发送时已经处理好变量字段,可直接获取判断 List wmTextFieldIds = (List) salaryBillWatermark.getWmSetting().getOrDefault("wmSelectedFieldIds", Lists.newArrayList()); if (CollectionUtils.isEmpty(wmTextFieldIds)) { return; } boolean needQueryEmp = (boolean) salaryBillWatermark.getWmSetting().getOrDefault("needQueryEmp", false); DataCollectionEmployee simpleEmployee = null; if (needQueryEmp) { simpleEmployee = getSalaryEmployeeService(user).getEmployeeById(currentEmployeeId); } String wmText = salaryBillWatermark.getWmSetting().getOrDefault("wmText", StringUtils.EMPTY).toString(); wmText = SalaryBillBO.handleWmText(wmText, wmTextFieldIds, simpleEmployee); // 重新设回水印 salaryBillWatermark.getWmSetting().put("wmText", wmText); salaryTemplate.setSalaryWatermark(JSON.toJSONString(salaryBillWatermark)); } @Override public PageInfo salarySendInfoListPage(SalarySendInfoQueryParam queryParam) { //排序配置 OrderRuleVO orderRule = getSalarySysConfService(user).orderRule(); queryParam.setOrderRule(orderRule); List page = salarySendInfoMapper.list(queryParam); PageInfo pageInfo = SalaryPageUtil.buildPage(queryParam.getCurrent(), queryParam.getPageSize(), page, SalarySendInfoListDTO.class); SalarySendPO salarySendPO = getSalarySendMapper().getById(queryParam.getSalarySendId()); if (ObjectUtils.isEmpty(salarySendPO)) throw new SalaryRunTimeException("工资单不存在或已被删除"); List salaryTemplates = getSalaryTemplateService(user).getDefaultTemplates(Collections.singletonList(salarySendPO.getSalarySobId())); Integer ackFeedbackStatus = salaryTemplates.get(0).getAckFeedbackStatus(); if (ackFeedbackStatus!=null && NumberUtils.compare(ackFeedbackStatus,1) == 0) { // 默认为空时,未读未确认 pageInfo.getList().stream().forEach(obj -> { SalarySendInfoListDTO dto = (SalarySendInfoListDTO) obj; if (StringUtils.isBlank( dto.getBillReadStatus() )){ dto.setBillReadStatus(BillReadStatusEnum.UNREAD.getDefaultLabel()); } else { dto.setBillReadStatus(BillReadStatusEnum.getDefaultLabelByValue( Integer.valueOf(dto.getBillReadStatus()) )); } if (StringUtils.isBlank(dto.getBillConfirmStatus())){ dto.setBillConfirmStatus(BillConfimStatusEnum.UNCONFIRMED.getDefaultLabel()); } else { dto.setBillConfirmStatus(BillConfimStatusEnum.getDefaultLabelByValue( Integer.valueOf(dto.getBillConfirmStatus()) )); } }); } return pageInfo; } @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); pageInfo.setTotal(list.size()); pageInfo.setPageNum(queryParam.getCurrent()); pageInfo.setPageSize(queryParam.getPageSize()); 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<>(); } } List list = MapperProxyFactory.getProxy(SalarySendInfoMapper.class).detailList(queryParam, otherSalaryAcctRecordIds); return SalaryPageUtil.buildPage(queryParam.getCurrent(), queryParam.getPageSize(), list, SalarySendDetailListDTO.class); } /** * 获取工资单标题 * * @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, "月"); String companyName = ""; if (currentEmployeeId != null) { ResourceComInfo resourceComInfo = null; SubCompanyComInfo subCompanyComInfo = new SubCompanyComInfo(); try { resourceComInfo = new ResourceComInfo(); subCompanyComInfo = new SubCompanyComInfo(); } catch (Exception e) { log.error("资源异常", e); } companyName = subCompanyComInfo.getSubCompanyname(resourceComInfo.getSubCompanyID(currentEmployeeId + "")); } return theme .replace("${companyName}", 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())) .ackFeedbackStatus(Integer.valueOf(map.getOrDefault("ackFeedbackStatus", "0").toString())) .autoAckDays(Integer.valueOf(map.getOrDefault("autoAckDays", "0").toString())) .feedbackUrl(map.getOrDefault("feedbackUrl", "").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())) .salaryWatermark(map.getOrDefault("salaryWatermark", StringUtils.EMPTY).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()) .replenishName(map.getOrDefault("replenishName", "").toString()) .replenishSalaryItemSetting(map.getOrDefault("replenishSalaryItemSetting", "").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()) .workcode(StringUtils.isEmpty(simpleEmployee.getWorkcode()) ? "" : simpleEmployee.getWorkcode()) .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); encryptUtil.decryptList(salaryAccountingResults, SalaryAcctResultPO.class); // 动态列 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 list * @param salaryAcctResultValues * @return */ @Override public List> buildDetailList(List list, List salaryAcctEmployees, List salaryAcctResultValues) { List> listMaps = new ArrayList<>(); if (CollectionUtils.isEmpty(list)) { return listMaps; } // 所有个税扣缴义务人 // Map taxAgentMap = SalaryEntityUtil.convert2Map(getTaxAgentService(user).listAll(), TaxAgentPO::getId, TaxAgentPO::getName); // 按人员分组核算数据 // Map> relationSalaryAcctEmployeeMap = SalaryEntityUtil.group2Map(salaryAcctEmployees, SalaryAcctEmployeePO::getEmployeeId); Map salaryAcctEmployeeMap = SalaryEntityUtil.convert2Map(salaryAcctEmployees, salaryAcctEmployee -> salaryAcctEmployee.getEmployeeId() + "-" + salaryAcctEmployee.getTaxAgentId()); Map> singleEmpAcctMap = SalaryEntityUtil.group2Map(salaryAcctResultValues, SalaryAcctResultPO::getSalaryAcctEmpId); List employeeIds = list.stream().map(SalarySendInfoListDTO::getEmployeeId).distinct().collect(Collectors.toList()); // 查询分部 查询部门 List comInfos = getSalaryEmployeeService(user).getEmployeeByIdsAll(employeeIds); Map empComMap = SalaryEntityUtil.convert2Map(comInfos, DataCollectionEmployee::getEmployeeId); // 当前查询核算记录是回算,但是发放不是回算的,那么就取源头核算结果 boolean isOrigin = false; SalaryAcctRecordPO salaryAcctRecord = CollectionUtils.isEmpty(list) ? null : getSalaryAcctRecordService(user).getById(list.get(0).getSalaryAcctRecordId()); if (Objects.nonNull(salaryAcctRecord) && Objects.nonNull(salaryAcctRecord.getBackCalcStatus())) { isOrigin = !NumberUtils.INTEGER_ONE.equals(list.get(0).getSalaryAcctType()) && salaryAcctRecord.getBackCalcStatus().equals(NumberUtils.INTEGER_ONE); } // 动态列 long l = System.currentTimeMillis(); Map finalEmpSubComMap = empComMap; boolean finalIsOrigin = isOrigin; list.forEach(e -> { Map map = new LinkedHashMap<>(); map.put("id", e.getId() + ""); DataCollectionEmployee hrmDepartmentComInfo = finalEmpSubComMap.get(e.getEmployeeId()); if (hrmDepartmentComInfo != null) { map.put("subCompanyName", hrmDepartmentComInfo.getSubcompanyName()); } else { map.put("subCompanyName", ""); } if (hrmDepartmentComInfo != null) { map.put("department", e.getDepartment()); } map.put("employeeId", e.getEmployeeId() + ""); map.put("username", e.getUsername()); map.put("mobile", e.getMobile()); map.put("jobNum", e.getJobNum()); map.put("email", e.getEmail()); // map.put("employeeType", SalarySendEmployeeTypeEnum.getNameByValue(e.getEmployeeType())); // 单个人的核算数据 List resultValues = Lists.newArrayList(); // 个税扣缴义务人 // if (incomeCategorys.size() > 1) { // List acctEmployees = relationSalaryAcctEmployeeMap.getOrDefault(e.getEmployeeId(), Collections.emptyList()); // for (SalaryAcctEmployeePO salaryAcctEmployee : acctEmployees) { // if (singleEmpAcctMap.containsKey(salaryAcctEmployee.getId())) { // resultValues.add(singleEmpAcctMap.get(salaryAcctEmployee.getId())); // } // } // } else { // SalaryAcctEmployeePO salaryAcctEmployee = salaryAcctEmployeeMap.get(e.getEmployeeId() + "-" + e.getTaxAgent()); // if (salaryAcctEmployee != null && singleEmpAcctMap.containsKey(salaryAcctEmployee.getId())) { // resultValues.add(singleEmpAcctMap.get(salaryAcctEmployee.getId())); // } // } SalaryAcctEmployeePO salaryAcctEmployee = salaryAcctEmployeeMap.get(e.getEmployeeId() + "-" + e.getTaxAgentId()); if (salaryAcctEmployee != null && singleEmpAcctMap.containsKey(salaryAcctEmployee.getId())) { resultValues.addAll(singleEmpAcctMap.get(salaryAcctEmployee.getId())); } // 薪资项目 // singleEmpAcctResultList.forEach(i-> map.put(i.getSalaryItemId() + SalaryArchiveConstant.DYNAMIC_SUFFIX, i.getResultValue())); for (SalaryAcctResultPO salaryAcctResultValue : resultValues) { if (finalIsOrigin) { map.put(salaryAcctResultValue.getSalaryItemId() + SalaryArchiveConstant.DYNAMIC_SUFFIX, salaryAcctResultValue.getResultValue()); } else { map.put(salaryAcctResultValue.getSalaryItemId() + SalaryArchiveConstant.DYNAMIC_SUFFIX, salaryAcctResultValue.getResultValue()); } } listMaps.add(map); }); log.info("工资单详情构建总耗时:{}毫秒", System.currentTimeMillis() - l); return listMaps; } /** * 通过薪资账套获取模板的薪资项目 * * @param salaryTemplate * @return */ @Override public List getSalaryItemsSetting(SalaryTemplatePO salaryTemplate, boolean isReplenish) { List salaryItems = new ArrayList<>(); if (salaryTemplate == null) { return salaryItems; } // 正常模板 if (!isReplenish && 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()); }); } // 补发模板 if (isReplenish && StringUtils.isNotEmpty(salaryTemplate.getReplenishSalaryItemSetting())) { List salaryTemplateShowSetData = JsonUtil.parseList(salaryTemplate.getReplenishSalaryItemSetting(), 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, "工资单发放不存在")); } // 已经冻结不能操作 if (Objects.equals(salarySend.getSendStatus(), NumberUtils.INTEGER_ONE)) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(0, "工资单已冻结")); } // 获取默认模板 List salaryTemplates = getSalaryTemplateService(user).getDefaultTemplates(Collections.singletonList(salarySend.getSalarySobId())); if (CollectionUtils.isEmpty(salaryTemplates)) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100518, "没有默认模板,无法发送")); } SalaryTemplatePO templatePO = salaryTemplates.get(0); Date sendTime = new Date(); // 获取可发送的列表 List> enableSendList = getEnableSendList(salarySend, ids, templatePO); // 1.发放 SalarySendInfoPO po = new SalarySendInfoPO(); po.setSendStatus(SalarySendStatusEnum.ALREADYSEND.getValue()); po.setSendTime(sendTime); po.setSalaryTemplate(JsonUtil.toJsonString(templatePO)); po.setBillReadStatus(BillReadStatusEnum.UNREAD.getValue()); po.setBillConfirmStatus(BillConfimStatusEnum.UNCONFIRMED.getValue()); po.setSendEmployeeId(Long.valueOf(user.getUID())); salarySendInfoMapper.updateGrantWithdraw(po, salarySendId, Arrays.asList(SalarySendStatusEnum.UNSEND.getValue(), SalarySendStatusEnum.WITHDRAW.getValue()), ids); List list = salarySendInfoMapper.listSome(SalarySendInfoPO.builder().salarySendId(salarySendId).build()); //需要发送工资的人 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 needSendList = Lists.newArrayList(); enableSendList.forEach(map -> { sendList.forEach(item -> { if (item.getId() == Long.valueOf(map.get("id").toString()).longValue()) { needSendList.add(item); } }); }); // 发送消息 param.setTemplate(templatePO); 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) { new Thread() { public void run() { List pos = list; if (CollectionUtils.isNotEmpty(param.getIds())) { pos = list.stream().filter(f -> param.getIds().contains(f.getId())).collect(Collectors.toList()); } pos.forEach(po -> { Long employeeId = po.getEmployeeId(); if (sendFlag) { sendPayRollEMMessage(po, param.getTemplate(), employeeId); } else { withdrawPayrollEMMessage(po, employeeId); } }); } }.start(); } /** * 发送Em消息 */ private void sendPayRollEMMessage(SalarySendInfoPO po, SalaryTemplatePO template, Long employeeId) { // try { // MessageUtil.sendSMS(mobile, content); // } catch (Exception e) { // kqLog.info("SendSMS error.resourceId:" + resourceId + ">>>>>>mobile>>>>>>" + mobile); // log.writeLog(e); // } Long id = po.getId(); String background = template.getBackground(); String billTitle = getBillTitle(template.getTheme(), po.getSalaryMonth(), employeeId); MessageType messageType = MessageType.newInstance(499); // 消息来源(见文档第四点补充 必填) Set userIdList = new HashSet<>(); // 接收人id 必填 userIdList.add(employeeId.toString()); String title = billTitle; // 标题 String context = "点击查看详情"; // 内容 // PC端链接 String linkUrl = weaver.general.GCONST.getContextPath() + "/spa/hrmSalary/static/index.html#/main/hrmSalary/mobilepayroll?id=" + id + "&recipient=" + employeeId; // 移动端链接 String linkMobileUrl = weaver.general.GCONST.getContextPath() + "/spa/hrmSalary/static/index.html#/main/hrmSalary/mobilepayroll?type=phone&id=" + id + "&recipient=" + employeeId; 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需要修改消息为已处理等状态时传入 if (StringUtils.isNotBlank(background)) { messageBean.setPictureUrl(background); } else { messageBean.setPictureUrl("/hrm/hrm_e9/images/payroll.jpg?pictype=jpg"); } Util_Message.store(messageBean); } catch (IOException e) { e.printStackTrace(); } } /** * 撤回EM消息 * * @param po */ private void withdrawPayrollEMMessage(SalarySendInfoPO po, Long employeeId) { try { MessageBean messageBean = Util_Message.createMessage(); messageBean.setUserList(new HashSet<>());//接收人id messageBean.setUserId(employeeId.intValue()); messageBean.setTargetId("499|" + po.getId()); //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.根据模板获取薪资项目设置 SalaryAcctRecordPO salaryAcctRecord = getSalaryAcctRecordService(user).getById(salarySend.getSalaryAccountingId()); boolean isReplenish = salaryAcctRecord != null && Objects.equals(salaryAcctRecord.getBackCalcStatus(), (NumberUtils.INTEGER_ONE)); List salaryItems = getSalaryItemsSetting(salaryTemplate, isReplenish); 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, "工资单发放不存在")); } // 撤回 SalarySendInfoPO po = new SalarySendInfoPO(); po.setSendStatus(SalarySendStatusEnum.WITHDRAW.getValue()); po.setBillReadStatus(BillReadStatusEnum.UNREAD.getValue()); po.setBillConfirmStatus(BillConfimStatusEnum.UNCONFIRMED.getValue()); List statusList = new ArrayList<>(); statusList.add(SalarySendStatusEnum.ALREADYSEND.getValue()); salarySendInfoMapper.updateGrantWithdraw(po, salarySendId, statusList, ids); 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); // 记录日志 // 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); 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.根据模板获取薪资项目设置 SalaryAcctRecordPO salaryAcctRecord = getSalaryAcctRecordService(user).getById(salarySend.getSalaryAccountingId()); boolean isReplenish = salaryAcctRecord != null && Objects.equals(salaryAcctRecord.getBackCalcStatus(), (NumberUtils.INTEGER_ONE)); List salaryTemplates = getSalaryTemplateService(user).getDefaultTemplates(Collections.singletonList(salarySend.getSalarySobId())); List salaryItems = getSalaryItemsSetting(CollectionUtils.isNotEmpty(salaryTemplates) ? salaryTemplates.get(0) : null, isReplenish); // 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("department")); 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); } @Override public List getSalarySendCheckResult(Set salaryAcctRecordIds) { if (CollectionUtils.isEmpty(salaryAcctRecordIds)) { return Collections.emptyList(); } Map condition = new HashMap<>(); condition.put("salaryAccountingIds", salaryAcctRecordIds); List salarySendPOS = getSalarySendMapper().listSomeWithCondition(condition); Map map = SalaryEntityUtil.convert2Map(salarySendPOS, SalarySendPO::getSalaryAccountingId); return salaryAcctRecordIds.stream().map(m -> { SalarySendPO salarySend = map.get(m); SalarySendCheckDTO salarySendCheck = new SalarySendCheckDTO(); salarySendCheck.setSalaryAcctId(m); // 是否存在已经发送 salarySendCheck.setAlreadySend(salarySend != null && salarySend.getSendNum() > 0); // 是否已经发送完成 salarySendCheck.setSendFinished(salarySend != null && Objects.equals(salarySend.getSendNum(), salarySend.getSendTotal())); return salarySendCheck; }).collect(Collectors.toList()); } @Override public void handleHistory() { mapper.batchHandleSendStatusHistory(); mapper.batchHandleSalaryAcctTypeHistory(); } // // @BatchExportHandler("exportSalarySendDetail") // public void salarySendDetailExportHandler() { // BatchCallbackMessage message = BatchExportContext.getBatchCallbackMessage(); // System.out.println("接受到导出的结果" + JSONObject.toJSONString(message)); // } @Override public Map sumRow(SalarySendInfoQueryParam param) { Long salarySendId = param.getSalarySendId(); // 获取薪资核算ID SalarySendPO salarySendPO = getById(salarySendId); if (Objects.isNull(salarySendPO)) { throw new SalaryRunTimeException("工资发放记录不存在或已被删除"); } SalaryAcctResultQueryParam queryParam = SalaryAcctResultQueryParam.builder().salaryAcctRecordId(salarySendPO.getSalaryAccountingId()).build(); // 查询薪资核算人员 List salaryAcctEmployeePOS = getSalaryAcctEmployeeService(user) .listByResultQueryParam(queryParam); if (org.apache.commons.collections4.CollectionUtils.isEmpty(salaryAcctEmployeePOS)) { return Collections.emptyMap(); } // 查询薪资核算记录 SalaryAcctRecordPO salaryAcctRecordPO = getSalaryAcctRecordService(user).getById(queryParam.getSalaryAcctRecordId()); if (Objects.isNull(salaryAcctRecordPO)) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(98747, "薪资核算记录不存在或已被删除")); } // 查询薪资核算所用薪资账套的薪资项目 List salarySobItemPOS = getSalarySobItemService(user).listBySalarySobId(salaryAcctRecordPO.getSalarySobId()); Set salaryItemIds = SalaryEntityUtil.properties(salarySobItemPOS, SalarySobItemPO::getSalaryItemId); if (Objects.equals(salaryAcctRecordPO.getBackCalcStatus(), NumberUtils.INTEGER_ONE)) { // 是回算,获取回算项 List salarySobBackItemPOS = getSalarySobBackItemService(user).listBySalarySobId(salaryAcctRecordPO.getSalarySobId()); salaryItemIds.addAll(salarySobBackItemPOS.stream().map(SalarySobBackItemPO::getSalaryItemId).collect(Collectors.toList())); } List salaryItemPOS = getSalaryItemService(user).listByIds(salaryItemIds); // 查询薪资核算结果 List salaryAcctEmployeeIds = SalaryEntityUtil.properties(salaryAcctEmployeePOS, SalaryAcctEmployeePO::getId, Collectors.toList()); List salaryAcctResultPOS = getSalaryAcctResultService(user).listBySalaryAcctEmployeeIds(salaryAcctEmployeeIds); // 是否是补发工资单 List salarySendInfoPOS = getSalarySendInfoMapper().listSome(SalarySendInfoPO.builder().salarySendId(salarySendId).build()); List sendEmployeeIds = salarySendInfoPOS.stream().map(SalarySendInfoPO::getEmployeeId).collect(Collectors.toList()); salaryAcctResultPOS = salaryAcctResultPOS.stream().filter(po -> sendEmployeeIds.contains(po.getEmployeeId())).collect(Collectors.toList()); Map map = new HashMap<>(); Map> acctResultMap = SalaryEntityUtil.group2Map(salaryAcctResultPOS, SalaryAcctResultPO::getSalaryItemId); salaryItemPOS.stream().filter(item -> SalaryDataTypeEnum.NUMBER.getValue().equals(item.getDataType())).forEach(item -> { BigDecimal sum = Optional.ofNullable(acctResultMap.get(item.getId())) .orElse(new ArrayList<>()) .stream() .map(SalaryAcctResultPO::getResultValue) .filter(NumberUtils::isCreatable) .map(BigDecimal::new) .reduce(BigDecimal.ZERO, BigDecimal::add); map.put(item.getId().toString(), SalaryAcctFormulaBO.roundResultValue(sum.toString(), item, Collections.emptyList(), Collections.emptyMap())); }); return map; } @Override public void deleteBySalaryAcctRecordIds(Collection ids) { if (CollectionUtils.isNotEmpty(ids)) { getSalarySendMapper().deleteBySalaryAcctRecordIds(ids); getSalarySendInfoMapper().deleteBySalaryAcctRecordIds(ids); } } @Override public void sendMobileCode(SMSCodeSendParam param) { Long id = param.getId(); SalarySendInfoPO po = getSalarySendInfoMapper().getById(id); if (po == null) { throw new SalaryRunTimeException("未获取工资单发放信息"); } Long employeeId = po.getEmployeeId(); DataCollectionEmployee employee = getSalaryEmployeeService(user).getEmployeeById(employeeId); if (employee == null) { throw new SalaryRunTimeException("未获取人员信息"); } String mobile = employee.getMobile(); if (Validator.isMobile(mobile)) { throw new SalaryRunTimeException("手机号信息有误"); } boolean checkSendSMS = MessageUtil.checkSendSMS(); if (!checkSendSMS) { throw new SalaryRunTimeException("短信服务异常"); } //1、生成6位验证码 String mobileCode = (int) ((Math.random() * 9 + 1) * 100000) + ""; //失效时间 long expirationTime = LocalDateTime.now().plusMinutes(10L).toInstant(ZoneOffset.ofHours(8)).toEpochMilli(); String cacheValue = mobileCode + "_" + expirationTime; //2、验证码缓存,10分钟失效 getSalaryCacheService(user).set(SALARY_CACHE_SMS_CODE + "_" + id, cacheValue); //3、发送短信 MessageUtil.sendSMS(mobile, "验证码:" + mobileCode + "有效时间10分钟,用于查看工资单,请不要告诉他人。"); } @Override public Boolean checkMobileCode(SMSCodeCheckParam param) { Long id = param.getId(); String mobileCode = param.getMobileCode(); //取出验证码 String cacheValue = getSalaryCacheService(user).get(SALARY_CACHE_SMS_CODE + "_" + id); String[] cache = cacheValue.split("_"); String code = cache[0]; //失效时间 long expirationTime = Long.parseLong(cache[1]); long nowTime = LocalDateTime.now().toInstant(ZoneOffset.ofHours(8)).toEpochMilli(); if (nowTime > expirationTime) { throw new SalaryRunTimeException("验证码已失效,请重新发送"); } if (!StringUtils.equals(code, mobileCode)) { throw new SalaryRunTimeException("验证码错误"); } return true; } @Override public List getNeedSendInfoList(List salarySendIds) { if(CollectionUtils.isEmpty(salarySendIds)){ return Collections.emptyList(); } return getSalarySendInfoMapper().getNeedSendInfoList(salarySendIds); } @Override public List getNeedSendListBySalarySobIds(List salarySobIds) { if(CollectionUtils.isEmpty(salarySobIds)){ return Collections.emptyList(); } return getSalarySendMapper().getNeedSendListBySalarySobIds(salarySobIds); } @Override public List listUnConfirmedSendInfo(List salarySobIds) { if(CollectionUtils.isEmpty(salarySobIds)) return Collections.emptyList(); return getSalarySendInfoMapper().listUnConfirmedSendInfo(salarySobIds); } @Override public void autoConfirmSalaryBill(List needAutoSendIds) { if(CollectionUtils.isEmpty(needAutoSendIds)){ return; } List> partition = Lists.partition((List) needAutoSendIds, 500); partition.forEach(getSalarySendInfoMapper()::autoConfirmSalaryBill); } @Override public List getByIds(List salarySendId) { if(CollectionUtils.isEmpty(salarySendId)){ return Collections.emptyList(); } return getSalarySendMapper().getByIds(salarySendId); } }