package com.cyksj.task; import cn.hutool.core.date.DateField; import cn.hutool.core.date.DateTime; import cn.hutool.core.date.DateUtil; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.cyksj.common.exception.BusinessRuntimeException; import com.cyksj.common.util.Jsons; import com.cyksj.dto.RedisKey; import com.cyksj.mapper.*; import com.cyksj.mapper.manage.distribute.DistributeWaitingSendPointsMapper; import com.cyksj.model.dto.WxMpTemplateData; import com.cyksj.model.dto.WxMpTemplateMessage; import com.cyksj.model.entity.*; import com.cyksj.redis.RedisService; import com.cyksj.service.order.OrderDonService; import com.cyksj.service.register.RegisterOrderDonService; import com.cyksj.service.register.SpotifyService; import com.cyksj.service.wechat.WeChatService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.dao.DuplicateKeyException; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; import java.util.*; import java.util.stream.Collectors; import static com.cyksj.common.constant.WeChatTemplateConst.EXPIRY_TEMPLATE; @Component @Slf4j @RequiredArgsConstructor public class Scheduler { private final GoodsDonMapper donMapper; private final GroupsMapper groupsMapper; private final OrderDonService orderDonService; private final GroupsRelationMapper groupsRelationMapper; private final UserMapper userMapper; private final GoodsDonSkuMapper skuMapper; private final WeChatService weChatService; private final AccountMapper accountMapper; private final CustomerServiceMapper customerServiceMapper; private final SpotifyService spotifyService; private final RegisterOrderDonMapper registerOrderDonMapper; private final RedisService redisService; private final SysConfigMapper sysConfigMapper; private final DistributeWaitingSendPointsMapper distributeWaitingSendPointsMapper; private final RegisterOrderDonService registerOrderDonService; private final AppleAutoRegisterDataMapper appleAutoRegisterDataMapper; private final RealGoodsInterestUserMapper realGoodsInterestUserMapper; /** * 每5分钟清理过期账号 */ @Scheduled(cron = "0 0/5 * * * ?") @Transactional(rollbackFor = Throwable.class) public void clearExpiry() { DateTime now = new DateTime(); List expiryList = groupsRelationMapper.selectList(Wrappers.lambdaQuery(GroupsRelation.class).le(GroupsRelation::getExpiryTime, now)); log.info("定时清理过期账号start ===> 数量:{}", expiryList.size()); //过期账号清楚有效期 expiryList.forEach(relation -> delRelation(relation)); } @Scheduled(cron = "0 0 9 * * ?") public void expiryWxMsg() throws Exception { DateTime now = new DateTime(); DateTime zero = DateUtil.offset(now, DateField.HOUR, -9); DateTime time = DateUtil.offset(zero, DateField.DAY_OF_MONTH, 5); List groupsRelations = groupsRelationMapper.selectList(Wrappers.lambdaQuery(GroupsRelation.class).le(GroupsRelation::getExpiryTime, time)); for (GroupsRelation relation : groupsRelations) { User user = userMapper.selectById(relation.getUserId()); WxMpTemplateMessage templateMessage = new WxMpTemplateMessage() .setToUser(user.getOpenId()) .setTemplateId(EXPIRY_TEMPLATE) .setUrl(" "); /** * 您的账号即将到期 * 账号名称:Netflix账号 * 平台:Netflix * 失效日期:5天后 * 异常原因:账号即将到期 * 请尽快续费,以免影响使用 */ GroupsTrips groupsTrips = groupsMapper.selectById(relation.getGroupsId()); GoodsDonSku donSku = skuMapper.selectById(groupsTrips.getSkuId()); GoodsDon goodsDon = donMapper.selectById(donSku.getGoodsId()); WxMpTemplateMessage.TemplateData data = templateMessage.getData(); data.setFirst(new WxMpTemplateData("您的账号即将到期")); data.setKeyword1(new WxMpTemplateData(goodsDon.getTitle())); data.setKeyword2(new WxMpTemplateData(goodsDon.getTitle())); data.setKeyword3(new WxMpTemplateData(DateUtil.format(relation.getExpiryTime(), "yyyy-MM-dd HH:mm:ss"))); data.setKeyword4(new WxMpTemplateData("账号即将到期")); data.setRemark(new WxMpTemplateData("请尽快续费,以免影响使用")); log.info("发送账号即将到期消息至用户:{}", user.getId()); weChatService.sendTemplateMessage(weChatService.getAccessToken(), Jsons.toJson(templateMessage)); List accounts = accountMapper.selectList(Wrappers.lambdaQuery(Account.class).le(Account::getExpiryTime, time)); List customerServices = customerServiceMapper.selectList(null); if(!accounts.isEmpty()){ for (CustomerService customerService : customerServices) { WxMpTemplateMessage manageMessage = new WxMpTemplateMessage() .setToUser(customerService.getOpenId()) .setTemplateId(EXPIRY_TEMPLATE) .setUrl(" "); WxMpTemplateMessage.TemplateData data2 = manageMessage.getData(); data2.setFirst(new WxMpTemplateData("您有" + accounts.size() + "个主账号即将到期")); data2.setKeyword1(new WxMpTemplateData("车队主账号")); data2.setKeyword2(new WxMpTemplateData("车队主账号")); data2.setKeyword3(new WxMpTemplateData("5天后")); data2.setKeyword4(new WxMpTemplateData("账号即将到期")); data2.setRemark(new WxMpTemplateData("请尽快登录后台-在账号管理中查看")); log.info("发送账号即将到期消息至客服:{}", customerService.getNickName()); weChatService.sendTemplateMessage(weChatService.getAccessToken(),Jsons.toJson(manageMessage)); } } } } private void delRelation(GroupsRelation relation) { Date expireTime = relation.getExpiryTime(); relation.setStartTime(null); relation.setExpiryTime(null); relation.setUserId(0l); relation.setStatus(GroupsRelation.Status.none); relation.setIsHandle(false); relation.setRenewStatus(false); relation.setAccount(null); Integer success = groupsRelationMapper.updateExpiryTime(relation, expireTime); if (success == 1) { log.info("开始清除过期子账号,座位号:{}", relation.getId()); int count = groupsMapper.incrAvailableNum(relation.getGroupsId()); if (count == 0) { log.error("车位异常 groupId:{}", relation.getGroupsId()); throw new BusinessRuntimeException("车位异常"); } } } /** * 定时关闭订单 */ @Scheduled(cron = "0 0/5 * * * ?") public void closeOrder() { //获取为支付订单 DateTime now = new DateTime(); Date newDate = DateUtil.offset(now, DateField.MINUTE, -5); List list = orderDonService.list(Wrappers.lambdaQuery(OrderDon.class).eq(OrderDon::getStatus, OrderDon.Status.noPayment).le(OrderDon::getCreatedTime,newDate)); log.info("定时任务 关闭 订单数:{}",list.size()); list.forEach((orderDon)->{ orderDonService.closeOrder(orderDon.getId()); }); } /** * spotify 注册 */ // @Scheduled(cron = "0 0/5 * * * ?") public void spotify() { List spotify = registerOrderDonMapper.selectList(Wrappers.lambdaQuery(RegisterOrderDon.class) .select(RegisterOrderDon::getId) .eq(RegisterOrderDon::getPlatform, "spotify") .eq(RegisterOrderDon::getStatus, RegisterOrderDon.Status.hasPayment)); for (RegisterOrderDon orderDon : spotify) { spotifyService.register(orderDon.getId()); } } /** * 每日免单重置 */ @Scheduled(cron = "0 0 0 * * ?") public void freeReset() { log.info("每日重置 spotify 免单账户数 [start]"); SysConfig register_free_num = sysConfigMapper.selectOne(Wrappers.lambdaQuery(SysConfig.class).eq(SysConfig::getSysKey, "register_free_num")); redisService.set(RedisKey.SPOTIFY_FREE_NUM, Long.parseLong(register_free_num.getSysValue())); log.info("每日重置 spotify 免单账户数 [end] 数量:{}",register_free_num.getSysValue()); } /** * 分销订单积分奖励分发 */ @Scheduled(cron = "0 0 0/2 * * ?") @Transactional(rollbackFor = Throwable.class) public void distributeOrdersSendPoints() { List waitingSendPoints = Optional.ofNullable(distributeWaitingSendPointsMapper.selectList(Wrappers.lambdaQuery(DistributeWaitingSendPoints.class) .eq(DistributeWaitingSendPoints::getSendStatus, DistributeWaitingSendPoints.Status.waiting) .lt(DistributeWaitingSendPoints::getSendTime, DateTime.now()) .select(DistributeWaitingSendPoints::getId, DistributeWaitingSendPoints::getOrderId, DistributeWaitingSendPoints::getPoints, DistributeWaitingSendPoints::getUserId, DistributeWaitingSendPoints::getSharedId, DistributeWaitingSendPoints::getSendTime))).orElse(new ArrayList<>()); log.info("查询分销订单积分分发记录开始,条数:{}=======》", waitingSendPoints.size()); waitingSendPoints.forEach(wait -> { //积分待发人 Long sharedId = wait.getSharedId(); User user = userMapper.selectById(sharedId); if (user == null) { wait.setSendStatus(DistributeWaitingSendPoints.Status.not_exist); log.info("分销订单,发送积分用户不存在"); distributeWaitingSendPointsMapper.updateById(wait); } else { wait.setSendStatus(DistributeWaitingSendPoints.Status.success); log.info("更新用户积分开始=====>"); while (true) { user = userMapper.selectById(sharedId); if (user == null) { break; } Integer update = userMapper.updatePoints(user.getId(), user.getPoints(), wait.getPoints()); if (update == 1) { distributeWaitingSendPointsMapper.updateById(wait); log.info("分销积分表订单id:{}发放积分success", wait.getOrderId()); break; } } } }); } /** * 定时更新未支付AppleID自动注册订单 */ @Scheduled(cron = "0 0/5 * * * ?") public void updateAppleAutoStatus() { //获取为支付订单 DateTime now = new DateTime(); Date newDate = DateUtil.offset(now, DateField.MINUTE, -5); List orderDons = appleAutoRegisterDataMapper.getAllNoPayOrders(newDate); log.info("定时更新未支付AppleID自动注册订单 订单数:{}",orderDons.size()); orderDons.forEach((orderId)->{ registerOrderDonService.updateAppleAutoStatus(orderId); }); } /** * 实物订单意愿数据 */ @Scheduled(cron = "0 0/5 * * * ?") public void realGoodsInterestUser() { Optional.ofNullable(orderDonService.selectNoPaymentRealGoods()).ifPresent(list -> { if (list.size() > 0) { Map> collect = list.stream().collect(Collectors.groupingBy(RealGoodsInterestUser::getGroupBy)); log.info("实物订单意愿数据同步开始"); collect.forEach((k, data) -> { RealGoodsInterestUser realGoodsInterestUser = null; if (data.size() == 0) { realGoodsInterestUser = data.get(0); } else { List high = data.stream().sorted(Comparator.comparing(RealGoodsInterestUser::getMoney).thenComparing(RealGoodsInterestUser::getOrderCreatedTime).reversed()).collect(Collectors.toList()); realGoodsInterestUser = high.get(0); } try { realGoodsInterestUserMapper.insert(realGoodsInterestUser); } catch (DuplicateKeyException e) { log.info("重复插入用户相同实物商品记录"); } }); log.info("实物订单意愿数据同步结束"); } } ); Integer update = orderDonService.updateHasPaymentInterestRealGoods(); orderDonService.updateHasPaymentInterestRealGoodsPayTime(); if (update > 0) { log.info("更新用户记录:{}已购买实物意愿商品状态成功", update); } } }