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.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.SpotifyService; import com.cyksj.service.wechat.WeChatService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; import java.util.Date; import java.util.List; 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; /** * 每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); 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() { synchronized (this){ List spotify = registerOrderDonMapper.selectList(Wrappers.lambdaQuery(RegisterOrderDon.class) .select(RegisterOrderDon::getId) .eq(RegisterOrderDon::getPlatform, "spotify") .eq(RegisterOrderDon::getStatus, RegisterOrderDon.Status.hasPayment)); spotify.forEach((orderDon)->{ 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()); } }