package com.mzl.flower.schedule; import com.aliyuncs.exceptions.ClientException; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.mzl.flower.constant.Constants; import com.mzl.flower.constant.LockConstants; import com.mzl.flower.dto.response.member.MemberGrowthRecordVO; import com.mzl.flower.dto.response.payment.OrderSettlementDetailDTO; import com.mzl.flower.entity.flower.FlowerCategory; import com.mzl.flower.entity.partner.Partner; import com.mzl.flower.entity.payment.Order; import com.mzl.flower.entity.payment.Transfer; import com.mzl.flower.entity.wallet.WalletBillRecordDO; import com.mzl.flower.entity.wallet.WalletDO; import com.mzl.flower.mapper.flower.FlowerCategoryMapper; import com.mzl.flower.mapper.member.MemberGrowthRecordMapper; import com.mzl.flower.mapper.partner.PartnerMapper; import com.mzl.flower.mapper.payment.OrderMapper; import com.mzl.flower.mapper.payment.OrderSettlementDetailMapper; import com.mzl.flower.mapper.wallet.WalletBillRecordMapper; import com.mzl.flower.mapper.wallet.WalletMapper; import com.mzl.flower.service.BaseService; import com.mzl.flower.service.coupon.CouponRecordService; import com.mzl.flower.service.coupon.CouponTemplateService2; import com.mzl.flower.service.flower.FlowerCategoryService; import com.mzl.flower.service.menber.impl.GrowthValueDealService; import com.mzl.flower.service.payment.*; import com.mzl.flower.service.wallet.WalletBillRecordService; import com.mzl.flower.service.wallet.WalletService; import com.mzl.flower.thread.FlowerCategoryPriceThread; import com.mzl.flower.utils.SmsUtil; import com.mzl.flower.utils.UUIDGenerator; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.time.DateFormatUtils; import org.redisson.api.RLock; import org.redisson.api.RedissonClient; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Profile; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; import java.math.BigDecimal; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; @Component @Slf4j public class ScheduleService { @Autowired private FlowerCategoryMapper categoryMapper; @Autowired private PartnerMapper partnerMapper; @Autowired private OrderMapper orderMapper; @Autowired private UserPaymentV3Service paymentV3Service; @Autowired private OrderService orderService; @Autowired private OrderSettlementService settlementService; @Autowired private FlowerCategoryService categoryService; @Autowired private BillService billService; @Autowired private OrderItemSettlementService orderItemSettlementService; @Autowired private GrowthValueDealService growthValueDealService; @Autowired private CouponRecordService couponRecordService; @Autowired private MemberGrowthRecordMapper memberGrowthRecordMapper; @Autowired private CouponTemplateService2 couponTemplateService2; @Autowired private FlowerCategoryPriceThread thread; @Autowired private BaseService baseService; @Autowired private WalletBillRecordService walletBillRecordService; @Autowired private OrderSettlementDetailMapper orderSettlementDetailMapper; @Autowired private WalletService walletService; @Autowired private RedissonClient redissonClient; @Autowired private WalletBillRecordMapper walletBillRecordMapper; @Autowired private WalletMapper walletMapper; @Scheduled(cron = "1 1 0/2 * * ?") public void calculateAvePrice() { log.info("均价计算开始:" + DateFormatUtils.format(System.currentTimeMillis(), "yyyy-MM-dd HH:mm:ss")); thread.run(); log.info("均价计算结束:" + DateFormatUtils.format(System.currentTimeMillis(), "yyyy-MM-dd HH:mm:ss")); } @Scheduled(cron = "1 1/30 * * * ?") public void calculateCategoryPriceRange() { log.info("分类加价缓存开始:" + DateFormatUtils.format(System.currentTimeMillis(), "yyyy-MM-dd HH:mm:ss")); List cLs = categoryMapper.selectList(new QueryWrapper() .isNotNull("parent_id")); if(cLs != null && cLs.size() > 0){ List ls = partnerMapper.selectList(new QueryWrapper().eq("status", "P")); for(FlowerCategory c : cLs){ categoryService.calculateCategoryPriceRange(c.getId(), null); if(ls != null && ls.size() > 0){ for(Partner p : ls){ categoryService.calculateCategoryPriceRange(c.getId(), p.getId()); } } } } log.info("分类加价缓存结束:" + DateFormatUtils.format(System.currentTimeMillis(), "yyyy-MM-dd HH:mm:ss")); } // @Scheduled(cron = "0 0/5 * * * ?") @Scheduled(cron = "0 0/15 * * * ?") public void checkPrepayOrder() {//五分钟未付款自动取消 log.info("未付款确认开始:" + DateFormatUtils.format(System.currentTimeMillis(), "yyyy-MM-dd HH:mm:ss")); List ls = orderMapper.selectList(new QueryWrapper() .eq("status", Constants.ORDER_STATUS_BACKEND.PENDING.name()) .eq("deleted", 0)); if(ls != null && ls.size() > 0){ for(Order o : ls){ try { LocalDateTime createdTime = o.getCreateTime().plusMinutes(15); if (createdTime.isBefore(LocalDateTime.now())) { boolean f = paymentV3Service.checkOrderStatus(o.getId()); if(!f){ paymentV3Service.cancelOrder(o.getId()); } } } catch (Exception e) { log.error(e.getMessage(), e); } } } log.info("未付款确认结束:" + DateFormatUtils.format(System.currentTimeMillis(), "yyyy-MM-dd HH:mm:ss")); } @Scheduled(cron = "0 10 0 1 * ?") public void calculateSupplierSaleNum(){ log.info("计算上月供应商销售数量开始:" + DateFormatUtils.format(System.currentTimeMillis(), "yyyy-MM-dd HH:mm:ss")); orderService.calculateSupplierSaleNum(); log.info("计算上月供应商销售数量结束:" + DateFormatUtils.format(System.currentTimeMillis(), "yyyy-MM-dd HH:mm:ss")); } @Scheduled(cron = "1 20 0/1 * * ?") public void autoReceive() { log.info("自动收货开始:" + DateFormatUtils.format(System.currentTimeMillis(), "yyyy-MM-dd HH:mm:ss")); List ls = orderService.autoReceive(); if(ls != null && ls.size() > 0){ for(Order o : ls){ orderService.processAfterReceive(o); } } log.info("自动收货结束:" + DateFormatUtils.format(System.currentTimeMillis(), "yyyy-MM-dd HH:mm:ss")); } @Scheduled(cron = "1 0 0 * * ?") public void doSettlement() { log.info("结算开始:" + DateFormatUtils.format(System.currentTimeMillis(), "yyyy-MM-dd HH:mm:ss")); //settlementService.doSettlement(); //新结算 List ls = settlementService.getOrders4Settlement(); if(ls != null && ls.size() > 0){ List orderIds = new ArrayList<>(); for(Order o : ls){ orderIds.add(o.getId()); } orderItemSettlementService.saveItemSettlementInfo(orderIds); settlementService.doSettlementNew(ls); } log.info("结算结束:" + DateFormatUtils.format(System.currentTimeMillis(), "yyyy-MM-dd HH:mm:ss")); } @Scheduled(cron = "2 0/10 * * * ?") public void checkTransfer() { log.info("确认转账开始:" + DateFormatUtils.format(System.currentTimeMillis(), "yyyy-MM-dd HH:mm:ss")); List ls = paymentV3Service.getUnCompletedTransfer(); if(ls != null && ls.size() > 0){ for(Transfer t : ls){ try { paymentV3Service.checkTransferStatus(t); settlementService.updateSettlementStatus(t.getId()); //2024-10-24更新钱包提现信息 walletBillRecordService.updateTransferStatus(t.getId()); } catch (Exception e) { log.error(e.getMessage(), e); } } } log.info("确认转账结束:" + DateFormatUtils.format(System.currentTimeMillis(), "yyyy-MM-dd HH:mm:ss")); } @Scheduled(cron = "1 30 0 * * ?") public void generateBill() { log.info("账单开始:" + DateFormatUtils.format(System.currentTimeMillis(), "yyyy-MM-dd HH:mm:ss")); LocalDate date = LocalDate.now(); billService.generateBill(date.plusDays(-1)); log.info("账单结束:" + DateFormatUtils.format(System.currentTimeMillis(), "yyyy-MM-dd HH:mm:ss")); } //成长值降级定时任务 @Scheduled(cron = "0 0 5 * * ?") public void deductGrowthValue() { log.info("成长值扣除开始:" + DateFormatUtils.format(System.currentTimeMillis(), "yyyy-MM-dd HH:mm:ss")); //获取当前员工 List orderList = orderMapper.getOrderInfoByReceiveTime(); if(!CollectionUtils.isEmpty(orderList)){ orderList.forEach(o->{ try { LocalDateTime now = LocalDateTime.now(); LocalDate nowDate = now.toLocalDate(); List memberGrowthRecordVOS = memberGrowthRecordMapper.selectDowngradingByUserId(o.getCreateBy(), nowDate); if (CollectionUtils.isEmpty(memberGrowthRecordVOS)) { growthValueDealService.deductionGrowthValue(o); } } catch (Exception e) { // 记录错误信息,例如将错误信息写入日志 log.info("处理订单 " + o.getId() + " 时出错: " + e.getMessage()); } }); } log.info("成长值扣除结束:" + DateFormatUtils.format(System.currentTimeMillis(), "yyyy-MM-dd HH:mm:ss")); } @Scheduled(cron = "0 30 0 1 * ?") public void grantVipCouponRecordList() { log.info("会员优惠券开始:" + DateFormatUtils.format(System.currentTimeMillis(), "yyyy-MM-dd HH:mm:ss")); couponRecordService.grantVipCouponRecordList(); log.info("会员优惠券结束:" + DateFormatUtils.format(System.currentTimeMillis(), "yyyy-MM-dd HH:mm:ss")); } @Scheduled(cron = "0 30 0 1 * ?") public void expiredCouponRecordLastMon() { log.info("会员优惠券开始:" + DateFormatUtils.format(System.currentTimeMillis(), "yyyy-MM-dd HH:mm:ss")); couponRecordService.expiredCouponRecordLastMon(); log.info("会员优惠券结束:" + DateFormatUtils.format(System.currentTimeMillis(), "yyyy-MM-dd HH:mm:ss")); } @Scheduled(cron = "0 0/5 * * * ?") public void expireActivityCouponTemplateAll() { log.info("优惠券模版过期下架开始:" + DateFormatUtils.format(System.currentTimeMillis(), "yyyy-MM-dd HH:mm:ss")); // 下架有所的过期的优惠券 couponTemplateService2.expireActivityCouponTemplateAll(); log.info("优惠券模版过期下架开始:" + DateFormatUtils.format(System.currentTimeMillis(), "yyyy-MM-dd HH:mm:ss")); } @Scheduled(cron = "0 0/5 * * * ?") public void expireCouponRecordAll() { log.info("优惠券记录过期开始:" + DateFormatUtils.format(System.currentTimeMillis(), "yyyy-MM-dd HH:mm:ss")); // 下架有所的过期的优惠券 couponRecordService.expireCouponRecordAll(); log.info("优惠券记录过期开始:" + DateFormatUtils.format(System.currentTimeMillis(), "yyyy-MM-dd HH:mm:ss")); } @Scheduled(cron = "0 15 17 * * ?") @Profile("prod") public void DealSendMessageInfoBySupplier() { log.info("供应商下单供货提示开始:" + DateFormatUtils.format(System.currentTimeMillis(), "yyyy-MM-dd HH:mm:ss")); // 获取当前日期 LocalDate currentDate = LocalDate.now(); // 设置开始时间为前一天的17点以后 LocalDateTime startDateTime = LocalDateTime.of(currentDate.minusDays(1), LocalTime.of(17, 0)); // 设置结束时间为当前日期的17点 LocalDateTime endDateTime = LocalDateTime.of(currentDate, LocalTime.of(17, 0)); System.out.println("开始时间: " + startDateTime); System.out.println("结束时间: " + endDateTime); List sends = orderMapper.getWaitSendMessageInfoBySupplier("COLLECTION", startDateTime, endDateTime); if(CollectionUtils.isNotEmpty(sends)) { sends.forEach(s -> { try { SmsUtil.sendSms(s, "SMS_474905508", null); } catch (ClientException e) { log.error("发送短信失败,手机号:" + s, e); } }); } log.info("供应商下单供货提示结束:" + DateFormatUtils.format(System.currentTimeMillis(), "yyyy-MM-dd HH:mm:ss")); } public void dealHistoryAmount() { log.info("处理历史结算金额开始:" + DateFormatUtils.format(System.currentTimeMillis(), "yyyy-MM-dd HH:mm:ss")); List orderSettlementDetailDTOS = orderSettlementDetailMapper.selectSettlementDetailLists(); orderSettlementDetailDTOS.forEach(o->{ BigDecimal totalAmount = new BigDecimal(0);//交易合计 BigDecimal checkFee = new BigDecimal(0);//降级扣款 BigDecimal lackFee = new BigDecimal(0);//缺货扣款 BigDecimal replaceFee = new BigDecimal(0);//补货扣款 BigDecimal stationFee = new BigDecimal(0);//集货站运费 BigDecimal salesFee = new BigDecimal(0);//售后理赔 totalAmount = totalAmount.add(o.getTotalAmount()); checkFee = checkFee.add(o.getCheckFee()); lackFee = lackFee.add(o.getLackFee() == null ? new BigDecimal(0): o.getLackFee()); replaceFee = replaceFee.add(o.getReplaceFee() == null ? new BigDecimal(0): o.getReplaceFee()); stationFee = stationFee.add(o.getStationFee()); salesFee = salesFee.add(o.getSalesFee()); BigDecimal settlementAmount = totalAmount.subtract(checkFee).subtract(lackFee).subtract(replaceFee) .subtract(salesFee).subtract(stationFee);//结算金额 WalletDO walletDO = walletService.getOrCreateBySupplierId(o.getSupplierId()); RLock lock = redissonClient.getLock(String.format(LockConstants.WALLET_ID_KEY, walletDO.getId())); try { if (lock.tryLock(10, 30, TimeUnit.SECONDS)) { try { if(settlementAmount.compareTo(BigDecimal.ZERO) > 0) { WalletBillRecordDO walletBillRecord = new WalletBillRecordDO(); walletBillRecord.setId(UUIDGenerator.getUUID()); WalletDO walletDOInfo = walletService.getBySupplierId(o.getSupplierId()); //增加供应商结算金额保存到钱包 walletBillRecord.setSupplierId(o.getSupplierId()); walletBillRecord.setWalletId(walletDOInfo.getId()); walletBillRecord.setSettlementId(o.getSettlementId()); walletBillRecord.setOrderItemId(o.getOrderItemId()); //变动金额等于供应商收入 walletBillRecord.setTotalAmount(settlementAmount); walletBillRecord.setType(Constants.BILL_CHANGE_TYPE.settlement.name()); walletBillRecord.setMethod(Constants.BILL_CHANGE_METHOD.add.name()); walletBillRecord.setOriginalAmount(walletDOInfo.getTotalAmount()); walletBillRecord.setChangeAmount(settlementAmount); walletBillRecord.setBalance(walletDOInfo.getWithdrawableAmount().add(settlementAmount)); Order order = orderMapper.selectById(o.getOrderId()); if (!ObjectUtils.isEmpty(order)) { walletBillRecord.setRemark("订单完成(订单号" + order.getOrderNo() + ")" + ",获得收入"); walletBillRecord.setOrderNo(order.getOrderNo()); } //更新钱包 //可提现金额=钱包余额=结算金额 walletDOInfo.setWithdrawableAmount(walletDOInfo.getWithdrawableAmount().add(settlementAmount)); walletDOInfo.setTotalAmount(walletDOInfo.getWithdrawableAmount()); //已结算金额 walletDOInfo.setSettledAmount(walletDOInfo.getSettledAmount().add(settlementAmount)); walletMapper.updateById(walletDOInfo); walletBillRecord.create(); walletBillRecordMapper.insert(walletBillRecord); } } finally { lock.unlock(); } } } catch (InterruptedException e) { throw new RuntimeException(e); } }); log.info("处理历史结算金额完成:" + DateFormatUtils.format(System.currentTimeMillis(), "yyyy-MM-dd HH:mm:ss")); } }