Scheduler.java 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. package com.cyksj.task;
  2. import cn.hutool.core.date.DateField;
  3. import cn.hutool.core.date.DateTime;
  4. import cn.hutool.core.date.DateUtil;
  5. import com.baomidou.mybatisplus.core.toolkit.Wrappers;
  6. import com.cyksj.common.exception.BusinessRuntimeException;
  7. import com.cyksj.common.util.Jsons;
  8. import com.cyksj.dto.RedisKey;
  9. import com.cyksj.mapper.*;
  10. import com.cyksj.mapper.manage.distribute.DistributeWaitingSendPointsMapper;
  11. import com.cyksj.model.dto.WxMpTemplateData;
  12. import com.cyksj.model.dto.WxMpTemplateMessage;
  13. import com.cyksj.model.entity.*;
  14. import com.cyksj.redis.RedisService;
  15. import com.cyksj.service.order.OrderDonService;
  16. import com.cyksj.service.register.RegisterOrderDonService;
  17. import com.cyksj.service.register.SpotifyService;
  18. import com.cyksj.service.wechat.WeChatService;
  19. import lombok.RequiredArgsConstructor;
  20. import lombok.extern.slf4j.Slf4j;
  21. import org.springframework.dao.DuplicateKeyException;
  22. import org.springframework.scheduling.annotation.Scheduled;
  23. import org.springframework.stereotype.Component;
  24. import org.springframework.transaction.annotation.Transactional;
  25. import java.util.*;
  26. import java.util.stream.Collectors;
  27. import static com.cyksj.common.constant.WeChatTemplateConst.EXPIRY_TEMPLATE;
  28. @Component
  29. @Slf4j
  30. @RequiredArgsConstructor
  31. public class Scheduler {
  32. private final GoodsDonMapper donMapper;
  33. private final GroupsMapper groupsMapper;
  34. private final OrderDonService orderDonService;
  35. private final GroupsRelationMapper groupsRelationMapper;
  36. private final UserMapper userMapper;
  37. private final GoodsDonSkuMapper skuMapper;
  38. private final WeChatService weChatService;
  39. private final AccountMapper accountMapper;
  40. private final CustomerServiceMapper customerServiceMapper;
  41. private final SpotifyService spotifyService;
  42. private final RegisterOrderDonMapper registerOrderDonMapper;
  43. private final RedisService redisService;
  44. private final SysConfigMapper sysConfigMapper;
  45. private final DistributeWaitingSendPointsMapper distributeWaitingSendPointsMapper;
  46. private final RegisterOrderDonService registerOrderDonService;
  47. private final AppleAutoRegisterDataMapper appleAutoRegisterDataMapper;
  48. private final RealGoodsInterestUserMapper realGoodsInterestUserMapper;
  49. /**
  50. * 每5分钟清理过期账号
  51. */
  52. @Scheduled(cron = "0 0/5 * * * ?")
  53. @Transactional(rollbackFor = Throwable.class)
  54. public void clearExpiry() {
  55. DateTime now = new DateTime();
  56. List<GroupsRelation> expiryList = groupsRelationMapper.selectList(Wrappers.lambdaQuery(GroupsRelation.class).le(GroupsRelation::getExpiryTime, now));
  57. log.info("定时清理过期账号start ===> 数量:{}", expiryList.size());
  58. //过期账号清楚有效期
  59. expiryList.forEach(relation -> delRelation(relation));
  60. }
  61. @Scheduled(cron = "0 0 9 * * ?")
  62. public void expiryWxMsg() throws Exception {
  63. DateTime now = new DateTime();
  64. DateTime zero = DateUtil.offset(now, DateField.HOUR, -9);
  65. DateTime time = DateUtil.offset(zero, DateField.DAY_OF_MONTH, 5);
  66. List<GroupsRelation> groupsRelations = groupsRelationMapper.selectList(Wrappers.lambdaQuery(GroupsRelation.class).le(GroupsRelation::getExpiryTime, time));
  67. for (GroupsRelation relation : groupsRelations) {
  68. User user = userMapper.selectById(relation.getUserId());
  69. WxMpTemplateMessage templateMessage = new WxMpTemplateMessage()
  70. .setToUser(user.getOpenId())
  71. .setTemplateId(EXPIRY_TEMPLATE)
  72. .setUrl(" ");
  73. /**
  74. * 您的账号即将到期
  75. * 账号名称:Netflix账号
  76. * 平台:Netflix
  77. * 失效日期:5天后
  78. * 异常原因:账号即将到期
  79. * 请尽快续费,以免影响使用
  80. */
  81. GroupsTrips groupsTrips = groupsMapper.selectById(relation.getGroupsId());
  82. GoodsDonSku donSku = skuMapper.selectById(groupsTrips.getSkuId());
  83. GoodsDon goodsDon = donMapper.selectById(donSku.getGoodsId());
  84. WxMpTemplateMessage.TemplateData data = templateMessage.getData();
  85. data.setFirst(new WxMpTemplateData("您的账号即将到期"));
  86. data.setKeyword1(new WxMpTemplateData(goodsDon.getTitle()));
  87. data.setKeyword2(new WxMpTemplateData(goodsDon.getTitle()));
  88. data.setKeyword3(new WxMpTemplateData(DateUtil.format(relation.getExpiryTime(), "yyyy-MM-dd HH:mm:ss")));
  89. data.setKeyword4(new WxMpTemplateData("账号即将到期"));
  90. data.setRemark(new WxMpTemplateData("请尽快续费,以免影响使用"));
  91. log.info("发送账号即将到期消息至用户:{}", user.getId());
  92. weChatService.sendTemplateMessage(weChatService.getAccessToken(), Jsons.toJson(templateMessage));
  93. List<Account> accounts = accountMapper.selectList(Wrappers.lambdaQuery(Account.class).le(Account::getExpiryTime, time));
  94. List<CustomerService> customerServices = customerServiceMapper.selectList(null);
  95. if(!accounts.isEmpty()){
  96. for (CustomerService customerService : customerServices) {
  97. WxMpTemplateMessage manageMessage = new WxMpTemplateMessage()
  98. .setToUser(customerService.getOpenId())
  99. .setTemplateId(EXPIRY_TEMPLATE)
  100. .setUrl(" ");
  101. WxMpTemplateMessage.TemplateData data2 = manageMessage.getData();
  102. data2.setFirst(new WxMpTemplateData("您有" + accounts.size() + "个主账号即将到期"));
  103. data2.setKeyword1(new WxMpTemplateData("车队主账号"));
  104. data2.setKeyword2(new WxMpTemplateData("车队主账号"));
  105. data2.setKeyword3(new WxMpTemplateData("5天后"));
  106. data2.setKeyword4(new WxMpTemplateData("账号即将到期"));
  107. data2.setRemark(new WxMpTemplateData("请尽快登录后台-在账号管理中查看"));
  108. log.info("发送账号即将到期消息至客服:{}", customerService.getNickName());
  109. weChatService.sendTemplateMessage(weChatService.getAccessToken(),Jsons.toJson(manageMessage));
  110. }
  111. }
  112. }
  113. }
  114. private void delRelation(GroupsRelation relation) {
  115. Date expireTime = relation.getExpiryTime();
  116. relation.setStartTime(null);
  117. relation.setExpiryTime(null);
  118. relation.setUserId(0l);
  119. relation.setStatus(GroupsRelation.Status.none);
  120. relation.setIsHandle(false);
  121. relation.setRenewStatus(false);
  122. relation.setAccount(null);
  123. Integer success = groupsRelationMapper.updateExpiryTime(relation, expireTime);
  124. if (success == 1) {
  125. log.info("开始清除过期子账号,座位号:{}", relation.getId());
  126. int count = groupsMapper.incrAvailableNum(relation.getGroupsId());
  127. if (count == 0) {
  128. log.error("车位异常 groupId:{}", relation.getGroupsId());
  129. throw new BusinessRuntimeException("车位异常");
  130. }
  131. }
  132. }
  133. /**
  134. * 定时关闭订单
  135. */
  136. @Scheduled(cron = "0 0/5 * * * ?")
  137. public void closeOrder() {
  138. //获取为支付订单
  139. DateTime now = new DateTime();
  140. Date newDate = DateUtil.offset(now, DateField.MINUTE, -5);
  141. List<OrderDon> list = orderDonService.list(Wrappers.lambdaQuery(OrderDon.class).eq(OrderDon::getStatus, OrderDon.Status.noPayment).le(OrderDon::getCreatedTime,newDate));
  142. log.info("定时任务 关闭 订单数:{}",list.size());
  143. list.forEach((orderDon)->{
  144. orderDonService.closeOrder(orderDon.getId());
  145. });
  146. }
  147. /**
  148. * spotify 注册
  149. */
  150. // @Scheduled(cron = "0 0/5 * * * ?")
  151. public void spotify() {
  152. List<RegisterOrderDon> spotify = registerOrderDonMapper.selectList(Wrappers.lambdaQuery(RegisterOrderDon.class)
  153. .select(RegisterOrderDon::getId)
  154. .eq(RegisterOrderDon::getPlatform, "spotify")
  155. .eq(RegisterOrderDon::getStatus, RegisterOrderDon.Status.hasPayment));
  156. for (RegisterOrderDon orderDon : spotify) {
  157. spotifyService.register(orderDon.getId());
  158. }
  159. }
  160. /**
  161. * 每日免单重置
  162. */
  163. @Scheduled(cron = "0 0 0 * * ?")
  164. public void freeReset() {
  165. log.info("每日重置 spotify 免单账户数 [start]");
  166. SysConfig register_free_num = sysConfigMapper.selectOne(Wrappers.lambdaQuery(SysConfig.class).eq(SysConfig::getSysKey, "register_free_num"));
  167. redisService.set(RedisKey.SPOTIFY_FREE_NUM, Long.parseLong(register_free_num.getSysValue()));
  168. log.info("每日重置 spotify 免单账户数 [end] 数量:{}",register_free_num.getSysValue());
  169. }
  170. /**
  171. * 分销订单积分奖励分发
  172. */
  173. @Scheduled(cron = "0 0 0/2 * * ?")
  174. @Transactional(rollbackFor = Throwable.class)
  175. public void distributeOrdersSendPoints() {
  176. List<DistributeWaitingSendPoints> waitingSendPoints = Optional.ofNullable(distributeWaitingSendPointsMapper.selectList(Wrappers.lambdaQuery(DistributeWaitingSendPoints.class)
  177. .eq(DistributeWaitingSendPoints::getSendStatus, DistributeWaitingSendPoints.Status.waiting)
  178. .lt(DistributeWaitingSendPoints::getSendTime, DateTime.now())
  179. .select(DistributeWaitingSendPoints::getId,
  180. DistributeWaitingSendPoints::getOrderId,
  181. DistributeWaitingSendPoints::getPoints,
  182. DistributeWaitingSendPoints::getUserId,
  183. DistributeWaitingSendPoints::getSharedId,
  184. DistributeWaitingSendPoints::getSendTime))).orElse(new ArrayList<>());
  185. log.info("查询分销订单积分分发记录开始,条数:{}=======》", waitingSendPoints.size());
  186. waitingSendPoints.forEach(wait -> {
  187. //积分待发人
  188. Long sharedId = wait.getSharedId();
  189. User user = userMapper.selectById(sharedId);
  190. if (user == null) {
  191. wait.setSendStatus(DistributeWaitingSendPoints.Status.not_exist);
  192. log.info("分销订单,发送积分用户不存在");
  193. distributeWaitingSendPointsMapper.updateById(wait);
  194. } else {
  195. wait.setSendStatus(DistributeWaitingSendPoints.Status.success);
  196. log.info("更新用户积分开始=====>");
  197. while (true) {
  198. user = userMapper.selectById(sharedId);
  199. if (user == null) {
  200. break;
  201. }
  202. Integer update = userMapper.updatePoints(user.getId(), user.getPoints(), wait.getPoints());
  203. if (update == 1) {
  204. distributeWaitingSendPointsMapper.updateById(wait);
  205. log.info("分销积分表订单id:{}发放积分success", wait.getOrderId());
  206. break;
  207. }
  208. }
  209. }
  210. });
  211. }
  212. /**
  213. * 定时更新未支付AppleID自动注册订单
  214. */
  215. @Scheduled(cron = "0 0/5 * * * ?")
  216. public void updateAppleAutoStatus() {
  217. //获取为支付订单
  218. DateTime now = new DateTime();
  219. Date newDate = DateUtil.offset(now, DateField.MINUTE, -5);
  220. List<Long> orderDons = appleAutoRegisterDataMapper.getAllNoPayOrders(newDate);
  221. log.info("定时更新未支付AppleID自动注册订单 订单数:{}",orderDons.size());
  222. orderDons.forEach((orderId)->{
  223. registerOrderDonService.updateAppleAutoStatus(orderId);
  224. });
  225. }
  226. /**
  227. * 实物订单意愿数据
  228. */
  229. @Scheduled(cron = "0 0/5 * * * ?")
  230. public void realGoodsInterestUser() {
  231. Optional.ofNullable(orderDonService.selectNoPaymentRealGoods()).ifPresent(list -> {
  232. if (list.size() > 0) {
  233. Map<String, List<RealGoodsInterestUser>> collect = list.stream().collect(Collectors.groupingBy(RealGoodsInterestUser::getGroupBy));
  234. log.info("实物订单意愿数据同步开始");
  235. collect.forEach((k, data) -> {
  236. RealGoodsInterestUser realGoodsInterestUser = null;
  237. if (data.size() == 0) {
  238. realGoodsInterestUser = data.get(0);
  239. } else {
  240. List<RealGoodsInterestUser> high = data.stream().sorted(Comparator.comparing(RealGoodsInterestUser::getMoney).thenComparing(RealGoodsInterestUser::getOrderCreatedTime).reversed()).collect(Collectors.toList());
  241. realGoodsInterestUser = high.get(0);
  242. }
  243. try {
  244. realGoodsInterestUserMapper.insert(realGoodsInterestUser);
  245. } catch (DuplicateKeyException e) {
  246. log.info("重复插入用户相同实物商品记录");
  247. }
  248. });
  249. log.info("实物订单意愿数据同步结束");
  250. }
  251. }
  252. );
  253. Integer update = orderDonService.updateHasPaymentInterestRealGoods();
  254. orderDonService.updateHasPaymentInterestRealGoodsPayTime();
  255. if (update > 0) {
  256. log.info("更新用户记录:{}已购买实物意愿商品状态成功", update);
  257. }
  258. }
  259. }