FinanceJob.java 15.8 KB
package com.order.erp.job;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.order.erp.common.constant.Constant;
import com.order.erp.common.utils.EmailSendUtils;
import com.order.erp.common.utils.RedisUtils;
import com.order.erp.domain.ApplyStatusEnum;
import com.order.erp.domain.FinanceEnum;
import com.order.erp.domain.FinanceOverEnum;
import com.order.erp.domain.dto.BaseDO;
import com.order.erp.domain.dto.admin.AdminUserDO;
import com.order.erp.domain.dto.admin.AdminUserRoleDO;
import com.order.erp.domain.dto.order.InvoiceBillOrderDO;
import com.order.erp.domain.dto.order.ProducePaymentCheckBillOrderDO;
import com.order.erp.domain.vo.order.FinanceEventJobVO;
import com.order.erp.service.admin.AdminUserRoleService;
import com.order.erp.service.admin.AdminUserService;
import com.order.erp.service.order.InvoiceBillOrderService;
import com.order.erp.service.order.ProducePaymentCheckBillOrderService;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Slf4j
@Component
public class FinanceJob {
    @Resource
    private EmailSendUtils emailSendUtils;
    @Resource
    private InvoiceBillOrderService invoiceBillOrderService;
    @Resource
    private ProducePaymentCheckBillOrderService producePaymentCheckBillOrderService;
    @Resource
    private AdminUserRoleService adminUserRoleService;
    @Resource
    private AdminUserService adminUserService;
    @Resource
    private RedisUtils redisService;
    //每天的7:15执行一次
//    @Scheduled(cron = "0 15 7 * * ?", zone = "Asia/Shanghai")

    //每分钟执行一次
//    @Scheduled(cron = "0 * * * * ?", zone = "Asia/Shanghai")
    public void financeJob() {
        List<InvoiceBillOrderDO> eventInvoiceBillOrderDO=invoiceBillOrderService.getOverEvnetList();
        List<ProducePaymentCheckBillOrderDO> eventProducePaymentCheckBillOrderDO= producePaymentCheckBillOrderService.getOverEventList();
       LocalDate today = LocalDate.now();
        List<InvoiceBillOrderDO> invoiceBillOrderDOList = eventInvoiceBillOrderDO.stream().filter(invoice -> invoice.getBackRefundDate() != null && Strings.isNotEmpty(invoice.getBackRefundDate()))
                .collect(Collectors.toList());
        Set<String> emailList= new HashSet<>();
        Set<String> twoEmail = new HashSet<>();
        //获取所有用户。
        List<AdminUserDO> allUser = adminUserService.list(new LambdaQueryWrapper<AdminUserDO>()
                .eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN));
        Map<Long, AdminUserDO> adminUserDOMap = allUser.stream().collect(Collectors.toMap(AdminUserDO::getId, AdminUserDO -> AdminUserDO, (existing, replacement) -> existing));
        Map<String, AdminUserDO> userName = allUser.stream().collect(Collectors.toMap(AdminUserDO::getUserName, AdminUserDO -> AdminUserDO, (existing, replacement) -> existing));
        //获取财务邮箱。
        List<AdminUserRoleDO> list = adminUserRoleService.list(new LambdaQueryWrapper<AdminUserRoleDO>()
                .eq(AdminUserRoleDO::getRoleId, Constant.SEVEN));
        Set<Long> userIds= list.stream().map(AdminUserRoleDO::getUserId).collect(Collectors.toSet());
        //获取所有财务角色的邮箱。
        List<String> financeEmailList = userIds.stream()
                .map(userId -> Optional.ofNullable(adminUserDOMap.get(userId))
                        .map(AdminUserDO::getEmail)
                        .filter(Strings::isNotEmpty)
                        .orElse(null))
                .filter(Objects::nonNull)
                .collect(Collectors.toList());

        if(CollectionUtils.isNotEmpty(invoiceBillOrderDOList)){
           invoiceBillOrderDOList.forEach(invoiceBillOrderDO -> {
               if(today.toString().equals(invoiceBillOrderDO.getBackRefundDate())) {
                   emailList.clear();
                   String redisKey = "invoice:" + invoiceBillOrderDO.getId()+invoiceBillOrderDO.getInvoiceNo();
                   //判断redis中是否有这个值,如果没有就发送邮件,如果有的话就不用发送邮件。
                   if(!redisService.hasKey(redisKey)){
                       if (CollectionUtils.isNotEmpty(financeEmailList)) {
                           emailList.addAll(financeEmailList);
                       }
                       Set<String> userSet = new HashSet<>();
                       userSet.add(invoiceBillOrderDO.getTrackerUser());
                       userSet.add(invoiceBillOrderDO.getBusinesPerson());
                       List<String> emails = userSet.stream()
                               .map(userName::get)
                               .filter(Objects::nonNull)  // 确保 AdminUserDO 不为 null
                               .map(AdminUserDO::getEmail) // 获取邮箱
                               .filter(Strings::isNotEmpty) // 确保邮箱不为空
                               .collect(Collectors.toList());
                       if (CollectionUtils.isNotEmpty(emails)) {
                           emailList.addAll(emails);
                       }
                       FinanceEventJobVO eventJobVO = new FinanceEventJobVO();
                       eventJobVO.setInvoiceBillOrderDO(invoiceBillOrderDO);
                       emailSendUtils.sendEmail(FinanceOverEnum.INVOICE_OVERTIME, new ArrayList<>(emailList), eventJobVO);
                       boolean set = redisService.set(redisKey, invoiceBillOrderDO, Constant.HUNDREDANDFIVE, TimeUnit.DAYS);// 设置为105天后过期
                       if(set){
                           redisService.saddWithExpiry(Constant.REDISKEY,redisKey, Constant.HUNDREDANDFIVE, TimeUnit.DAYS);
                       }
                   }
               }
           });
       }
      List<ProducePaymentCheckBillOrderDO> producePaymentCheckBillOrderDOList= eventProducePaymentCheckBillOrderDO.stream().filter(producePaymentCheckBillOrderDO -> producePaymentCheckBillOrderDO.getPayedDate()!=null && Strings.isNotEmpty(producePaymentCheckBillOrderDO.getPayedDate()))
               .collect(Collectors.toList());
       if(CollectionUtils.isNotEmpty(producePaymentCheckBillOrderDOList)){
           producePaymentCheckBillOrderDOList.forEach(producePaymentCheckBillOrderDO -> {
               if(today.toString().equals(producePaymentCheckBillOrderDO.getPayedDate())){
                   emailList.clear();  // 每次清除 uniqueEmails
                   String redisKey = "check:" + producePaymentCheckBillOrderDO.getId()+producePaymentCheckBillOrderDO.getCheckNo();
                   if(!redisService.hasKey(redisKey)) {
                       if (CollectionUtils.isNotEmpty(financeEmailList)) {
                           emailList.addAll(financeEmailList);
                       }
                       //发送邮件
                       Set<String> userSet = new HashSet<>();
                       //获取业务,财务,管理员
                       userSet.add(producePaymentCheckBillOrderDO.getTrackerUser());
                       userSet.add(producePaymentCheckBillOrderDO.getBusinesPerson());
                       List<String> emails = userSet.stream()
                               .map(userName::get)
                               .filter(Objects::nonNull)  // 确保 AdminUserDO 不为 null
                               .map(AdminUserDO::getEmail) // 获取邮箱
                               .filter(Strings::isNotEmpty) // 确保邮箱不为空
                               .collect(Collectors.toList());

                       if (CollectionUtils.isNotEmpty(emails)) {
                           emailList.addAll(emails);
                       }
                       FinanceEventJobVO eventJobVO = new FinanceEventJobVO();
                       eventJobVO.setProducePaymentCheckBillOrderDO(producePaymentCheckBillOrderDO);
                       emailSendUtils.sendEmail(FinanceOverEnum.PRODUCE_PAYMENT_CHECK_OVERTIME, new ArrayList<>(emailList), eventJobVO);
                       boolean set = redisService.set(redisKey, producePaymentCheckBillOrderDO, Constant.HUNDREDANDFIVE, TimeUnit.DAYS);// 设置为21天后过期
                       if(set){
                           redisService.saddWithExpiry(Constant.REDISKEY,redisKey, Constant.HUNDREDANDFIVE, TimeUnit.DAYS);
                       }
                   }
                   }
           });
       }

        Map<String, List<Long>> stringListMap = byKeysGetValue();
        if (stringListMap != null) {
            // 获取 InvoiceBillOrderDO 类型的 ID 列表
            List<Long> invoiceBillOrderIds = stringListMap.get("InvoiceBillOrderDO");
            List<InvoiceBillOrderDO> filteredInvoiceList = new ArrayList<>();
            Set<String> seenInvoices=new HashSet<>();
            List<ProducePaymentCheckBillOrderDO> filteredCheckList = new ArrayList<>();
            Set<String> seenChecks=new HashSet<>();
            if (invoiceBillOrderIds != null && !invoiceBillOrderIds.isEmpty()) {
                List<InvoiceBillOrderDO> invoiceBillOrderDOS = invoiceBillOrderService.listByIds(invoiceBillOrderIds);
                if (CollectionUtils.isNotEmpty(invoiceBillOrderDOS)) {
                    for(InvoiceBillOrderDO order : invoiceBillOrderDOS){
                        if (order != null && order.getInvoiceNo() != null && seenInvoices.add(order.getInvoiceNo())) {
                            // 确保 order 和 order.getInvoice() 非空后再处理
                            filteredInvoiceList.add(order);
                        }
                    }
                }
                if(CollectionUtils.isNotEmpty(filteredInvoiceList)) {
                    filteredInvoiceList.forEach(x -> {
                        if (FinanceEnum.UNPAID_PAYMENTS.getStatus() == x.getStatus()) {
                            twoEmail.clear();
                            twoEmail.addAll(financeEmailList);
                            Set<String> userSet = new HashSet<>();
                            userSet.add(x.getCreateBy());
                            userSet.add(x.getBusinesPerson());
                            List<String> emails = userSet.stream()
                                    .map(userName::get)
                                    .filter(Objects::nonNull)  // 确保 AdminUserDO 不为 null
                                    .map(AdminUserDO::getEmail) // 获取邮箱
                                    .filter(Strings::isNotEmpty) // 确保邮箱不为空
                                    .collect(Collectors.toList());

                            if (CollectionUtils.isNotEmpty(emails)) {
                                twoEmail.addAll(emails);
                            }
                            FinanceEventJobVO eventJobVO = new FinanceEventJobVO();
                            eventJobVO.setInvoiceBillOrderDO(x);
                            emailSendUtils.sendEmail(FinanceOverEnum.INVOICE_OVERTIME, new ArrayList<>(twoEmail), eventJobVO);
                        }
                    });
                }
            }
            // 获取 ProducePaymentCheckBillOrderDO 类型的 ID 列表
            List<Long> producePaymentCheckBillIds = stringListMap.get("ProducePaymentCheckBillOrderDO");
            if (producePaymentCheckBillIds != null && !producePaymentCheckBillIds.isEmpty()) {
                List<ProducePaymentCheckBillOrderDO> producePaymentCheckBillOrderDOS = producePaymentCheckBillOrderService.listByIds(producePaymentCheckBillIds);
                if (CollectionUtils.isNotEmpty(producePaymentCheckBillOrderDOS)) {
                    for (ProducePaymentCheckBillOrderDO order : producePaymentCheckBillOrderDOS) {
                        if (order != null && order.getCheckNo() != null && seenChecks.add(order.getCheckNo())) {
                            filteredCheckList.add(order);
                        }
                    }
                }
                if (CollectionUtils.isNotEmpty(filteredCheckList)) {
                    filteredCheckList.forEach(x -> {
                        if (FinanceEnum.UNPAID_PAYMENTS.getStatus() == x.getStatus()) {
                            twoEmail.clear();
                            twoEmail.addAll(financeEmailList);
                            Set<String> userSet = new HashSet<>();
                            userSet.add(x.getCreateBy());
                            userSet.add(x.getBusinesPerson());
                            List<String> emails = userSet.stream()
                                    .map(userName::get)
                                    .filter(Objects::nonNull)  // 确保 AdminUserDO 不为 null
                                    .map(AdminUserDO::getEmail) // 获取邮箱
                                    .filter(Strings::isNotEmpty) // 确保邮箱不为空
                                    .collect(Collectors.toList());
                            if (CollectionUtils.isNotEmpty(emails)) {
                                twoEmail.addAll(emails);
                            }
                            FinanceEventJobVO eventJobVO = new FinanceEventJobVO();
                            eventJobVO.setProducePaymentCheckBillOrderDO(x);
                            emailSendUtils.sendEmail(FinanceOverEnum.PRODUCE_PAYMENT_CHECK_OVERTIME, new ArrayList<>(twoEmail), eventJobVO);
                        }
                    });
                }
            }
        }
    }

    public Map<String, List<Long>> byKeysGetValue() {
        Map<String, List<Long>> resultMap = new HashMap<>();
        List<Long> producePaymentCheckBillIds = new ArrayList<>();
        List<Long> invoiceBillOrderIds = new ArrayList<>();
        // 获取所有的 keys对应的value。
        Set<Object> redisKeySet = redisService.getSetValues(Constant.REDISKEY);
        if (CollectionUtils.isNotEmpty(redisKeySet)) {
            List<Object> validKeys = new ArrayList<>();

            // 遍历所有 keys,检查每个 key 的过期时间
            for (Object key :redisKeySet) {
                Long expireTime = redisService.getExpire(key); // 获取过期时间(单位:秒)

                if (expireTime != null && expireTime > 0) { // 确保 expireTime 有值且大于 0
                    long daysRemaining = TimeUnit.SECONDS.toDays(expireTime);
                    // 每隔7天检查一下,如果是7的倍数,则获取里面的值,查看
                    if (Constant.ZERO==daysRemaining % 7) {
                        validKeys.add(key); // 满足条件,加入有效的 keys 列表
                    }
                }
            }
            // 如果存在有效的 keys,获取其对应的值
            if (CollectionUtils.isNotEmpty(validKeys)) {
                List<Object> values = redisService.multiGet(validKeys);
                if (CollectionUtils.isNotEmpty(values)) {
                    // 遍历每个 value,按类型分别收集 ID
                    for (Object item : values) {
                        if (item instanceof ProducePaymentCheckBillOrderDO) {
                            ProducePaymentCheckBillOrderDO producePaymentCheckBillOrderDO = (ProducePaymentCheckBillOrderDO) item;
                            producePaymentCheckBillIds.add(producePaymentCheckBillOrderDO.getId());
                        } else if (item instanceof InvoiceBillOrderDO) {
                            InvoiceBillOrderDO invoiceBillOrderDO = (InvoiceBillOrderDO) item;
                            invoiceBillOrderIds.add(invoiceBillOrderDO.getId());
                        }
                    }
                }
                // 将结果放入 resultMap
                resultMap.put("ProducePaymentCheckBillOrderDO", producePaymentCheckBillIds);
                resultMap.put("InvoiceBillOrderDO", invoiceBillOrderIds);
            }
        }
        return resultMap;
    }

}