zoujiajian преди 3 години
родител
ревизия
9a3fdbf09b

+ 9 - 0
netflix-dao/src/main/java/com/cyksj/mapper/UserTicketClearedRecordMapper.java

@@ -1,7 +1,11 @@
 package com.cyksj.mapper;
 
+import cn.hutool.core.date.DateTime;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.cyksj.model.entity.UserTicketClearedRecord;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
 
 /*
  *项目名: netflix
@@ -10,4 +14,9 @@ import com.cyksj.model.entity.UserTicketClearedRecord;
  *创建时间:2023/2/2 16:51
  */
 public interface UserTicketClearedRecordMapper extends BaseMapper<UserTicketClearedRecord> {
+
+	List<UserTicketClearedRecord> selectClearedRecord(@Param("first") DateTime first, @Param("end") DateTime end);
+
+
+	List<UserTicketClearedRecord> selectClearedRecord2(@Param("first") DateTime first, @Param("end") DateTime end);
 }

+ 6 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/UserTicketClearedRecord.java

@@ -1,5 +1,7 @@
 package com.cyksj.model.entity;
 
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.ejlchina.searcher.bean.DbIgnore;
 import lombok.Getter;
 import lombok.Setter;
 
@@ -37,6 +39,10 @@ public class UserTicketClearedRecord extends BaseEntity{
 
 	private Boolean deleted;
 
+	@TableField(exist = false)
+	@DbIgnore
+	private String externalUserid;
+
 	@Getter
 	public enum Source{
 		self("自购"),

+ 32 - 0
netflix-dao/src/main/resources/mapper/UserTicketClearedRecordMapper.xml

@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.cyksj.mapper.UserTicketClearedRecordMapper">
+
+    <select id="selectClearedRecord" resultType="com.cyksj.model.entity.UserTicketClearedRecord">
+        select ur.id, ur.user_id, ur.sku_id, ur.expiry_time, ca.external_userid
+        from `user_ticket_cleared_record` ur
+                 inner join user u on u.id = ur.user_id and u.unionid != ''
+			inner join corp_user cu
+        on cu.unionid = u.unionid
+            inner join corp_user_auth ca on ca.corp_user_id = cu.id and ca.wx_corp_id = 2
+        where ur.created_time between #{first}
+          and #{end}
+          and ur.source = 'self'
+    </select>
+
+    <select id="selectClearedRecord2" resultType="com.cyksj.model.entity.UserTicketClearedRecord">
+        select s.*,ca.external_userid
+        from (select ur.id, ur.user_id, ur.sku_id, ur.expiry_time, login_phone
+              from `user_ticket_cleared_record` ur
+                       inner join user u on u.id = ur.user_id and u.unionid = ''
+
+              where ur.created_time between '2023-04-16' and '2023-04-21 12:00:00'
+                and ur.source = 'self'
+                and u.login_phone != '') s
+                 inner join user_bind_detail ud on ud.phone = s.login_phone
+                 inner join user u2 on u2.id = ud.user_id and u2.unionid != ''
+			inner join corp_user cu
+        on cu.unionid = u2.unionid
+            inner join corp_user_auth ca on ca.corp_user_id = cu.id and ca.wx_corp_id = 2
+    </select>
+</mapper>

+ 316 - 316
netflix-service/src/main/java/com/cyksj/task/Scheduler.java

@@ -1,318 +1,318 @@
-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.constant.TemplateEnum;
-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.model.manage.views.AccountView;
-import com.cyksj.model.views.CmsUserVO;
-import com.cyksj.model.views.WxAppTemplateView;
-import com.cyksj.redis.RedisService;
-import com.cyksj.service.mange.CmsAccountService;
-import com.cyksj.service.order.OrderDonService;
-import com.cyksj.service.register.RegisterOrderDonService;
-import com.cyksj.service.register.SpotifyService;
-import com.cyksj.service.relation.GroupRelationClearService;
-import com.cyksj.service.template.TemplateCommonService;
-import com.cyksj.service.wechat.WeChatService;
-import com.ejlchina.searcher.BeanSearcher;
-import com.ejlchina.searcher.param.Operator;
-import com.ejlchina.searcher.util.MapUtils;
-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;
-
-@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 BeanSearcher beanSearcher;
-
-        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;
-
-        private final TemplateCommonService templateCommonService;
-
-        private final GroupRelationClearService groupRelationClearService;
-
-        private final CmsAccountService cmsAccountService;
-
-
-    /**
-     * 每5分钟清理过期账号
-     */
-    @Scheduled(cron = "0 0/5 * * * ?")
-    @Transactional(rollbackFor = Throwable.class)
-    public void clearExpiry() {
-        DateTime now = new DateTime();
-        List<GroupsRelation> expiryList = groupsRelationMapper.selectList(Wrappers.lambdaQuery(GroupsRelation.class).le(GroupsRelation::getExpiryTime, now));
-        log.info("定时清理过期账号start ===> 数量:{}", expiryList.size());
-        //过期账号清楚有效期
-        expiryList.forEach(relation -> groupRelationClearService.clearTicket(relation, UserTicketClearedRecord.Source.self));
-    }
-
-    @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<GroupsRelation> groupsRelations = groupsRelationMapper.selectList(Wrappers.lambdaQuery(GroupsRelation.class).le(GroupsRelation::getExpiryTime, time));
-        for (GroupsRelation relation : groupsRelations) {
-            User user = userMapper.selectById(relation.getUserId());
-            Long userId = user.getId();
-            WxAppTemplateView wxAppTemplateView = templateCommonService.getWxAppByUserId(userId, TemplateEnum.EXPIRY_TEMPLATE.getDesc());
-            if (wxAppTemplateView != null) {
-                String openId = user.getOpenId();
-                WxMpTemplateMessage templateMessage = new WxMpTemplateMessage()
-                        .setToUser(Optional.ofNullable(wxAppTemplateView.getOpenId()).orElse(openId))
-                        .setTemplateId(wxAppTemplateView.getTemplateId())
-                        .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(wxAppTemplateView.getAppId()), Jsons.toJson(templateMessage));
-
-//                List<Account> accounts = accountMapper.selectList(Wrappers.lambdaQuery(Account.class).le(Account::getExpiryTime, time));
-//                List<CustomerService> customerServices = customerServiceMapper.selectList(null);
-//                if(!accounts.isEmpty()){
-//                    for (CustomerService customerService : customerServices) {
-//                        openId = customerService.getOpenId();
-//                        WxMpTemplateMessage manageMessage = new WxMpTemplateMessage()
-//                                .setToUser(openId)
-//                                .setTemplateId(wxAppTemplateView.getTemplateId())
-//                                .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));
+//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.constant.TemplateEnum;
+//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.model.manage.views.AccountView;
+//import com.cyksj.model.views.CmsUserVO;
+//import com.cyksj.model.views.WxAppTemplateView;
+//import com.cyksj.redis.RedisService;
+//import com.cyksj.service.mange.CmsAccountService;
+//import com.cyksj.service.order.OrderDonService;
+//import com.cyksj.service.register.RegisterOrderDonService;
+//import com.cyksj.service.register.SpotifyService;
+//import com.cyksj.service.relation.GroupRelationClearService;
+//import com.cyksj.service.template.TemplateCommonService;
+//import com.cyksj.service.wechat.WeChatService;
+//import com.ejlchina.searcher.BeanSearcher;
+//import com.ejlchina.searcher.param.Operator;
+//import com.ejlchina.searcher.util.MapUtils;
+//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;
+//
+//@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 BeanSearcher beanSearcher;
+//
+//        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;
+//
+//        private final TemplateCommonService templateCommonService;
+//
+//        private final GroupRelationClearService groupRelationClearService;
+//
+//        private final CmsAccountService cmsAccountService;
+//
+//
+//    /**
+//     * 每5分钟清理过期账号
+//     */
+//    @Scheduled(cron = "0 0/5 * * * ?")
+//    @Transactional(rollbackFor = Throwable.class)
+//    public void clearExpiry() {
+//        DateTime now = new DateTime();
+//        List<GroupsRelation> expiryList = groupsRelationMapper.selectList(Wrappers.lambdaQuery(GroupsRelation.class).le(GroupsRelation::getExpiryTime, now));
+//        log.info("定时清理过期账号start ===> 数量:{}", expiryList.size());
+//        //过期账号清楚有效期
+//        expiryList.forEach(relation -> groupRelationClearService.clearTicket(relation, UserTicketClearedRecord.Source.self));
+//    }
+//
+//    @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<GroupsRelation> groupsRelations = groupsRelationMapper.selectList(Wrappers.lambdaQuery(GroupsRelation.class).le(GroupsRelation::getExpiryTime, time));
+//        for (GroupsRelation relation : groupsRelations) {
+//            User user = userMapper.selectById(relation.getUserId());
+//            Long userId = user.getId();
+//            WxAppTemplateView wxAppTemplateView = templateCommonService.getWxAppByUserId(userId, TemplateEnum.EXPIRY_TEMPLATE.getDesc());
+//            if (wxAppTemplateView != null) {
+//                String openId = user.getOpenId();
+//                WxMpTemplateMessage templateMessage = new WxMpTemplateMessage()
+//                        .setToUser(Optional.ofNullable(wxAppTemplateView.getOpenId()).orElse(openId))
+//                        .setTemplateId(wxAppTemplateView.getTemplateId())
+//                        .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(wxAppTemplateView.getAppId()), Jsons.toJson(templateMessage));
+//
+////                List<Account> accounts = accountMapper.selectList(Wrappers.lambdaQuery(Account.class).le(Account::getExpiryTime, time));
+////                List<CustomerService> customerServices = customerServiceMapper.selectList(null);
+////                if(!accounts.isEmpty()){
+////                    for (CustomerService customerService : customerServices) {
+////                        openId = customerService.getOpenId();
+////                        WxMpTemplateMessage manageMessage = new WxMpTemplateMessage()
+////                                .setToUser(openId)
+////                                .setTemplateId(wxAppTemplateView.getTemplateId())
+////                                .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));
+////                    }
+////                }
+//            }
+//        }
+//
+//
+//    }
+//
+//    /**
+//     * 定时关闭订单
+//     */
+//    @Scheduled(cron = "0 0/5 * * * ?")
+//    public void closeOrder() {
+//        //获取为支付订单
+//        DateTime now = new DateTime();
+//        Date newDate = DateUtil.offset(now, DateField.MINUTE, -5);
+//        List<OrderDon> 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/15 * * * ?")
+//    public void spotify() {
+//        List<RegisterOrderDon> 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<DistributeWaitingSendPoints> 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<Long> 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<String, List<RealGoodsInterestUser>> 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<RealGoodsInterestUser> 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("实物订单意愿数据同步结束");
 //                    }
 //                }
-            }
-        }
-
-
-    }
-
-    /**
-     * 定时关闭订单
-     */
-    @Scheduled(cron = "0 0/5 * * * ?")
-    public void closeOrder() {
-        //获取为支付订单
-        DateTime now = new DateTime();
-        Date newDate = DateUtil.offset(now, DateField.MINUTE, -5);
-        List<OrderDon> 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/15 * * * ?")
-    public void spotify() {
-        List<RegisterOrderDon> 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<DistributeWaitingSendPoints> 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<Long> 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<String, List<RealGoodsInterestUser>> 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<RealGoodsInterestUser> 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);
-        }
-    }
-
-    /**
-     * 统计昨日过期账号 分配给客服
-     */
-    @Scheduled(cron = "0 30 8 * * ?")
-    public void assignNeedUpdateExpiredAccount() {
-        DateTime beginOfDay = DateUtil.beginOfDay(DateTime.now());
-        List<AccountView> accountViews = beanSearcher.searchAll(AccountView.class, MapUtils.builder()
-                .field(AccountView::getExpiryCount, 0).op(Operator.GreaterThan)
-                .field(AccountView::getCustomerServiceId, 0)
-                .put("yesTime", String.format("and ur.created_time < '%s'", beginOfDay))
-                .build());
-        if (accountViews.size() > 0) {
-            int accountSize = accountViews.size();
-            log.info("开始给客服分配过期账号,过期账号数量:{}", accountSize);
-            List<CmsUserVO> customers = beanSearcher.searchAll(CmsUserVO.class, MapUtils.builder().field(CmsUserVO::getRoleNames, "客服").op(Operator.Contain).build());
-            if (customers.isEmpty()) {
-                log.info("暂无客服");
-                return;
-            }
-            //分配过期账号
-            cmsAccountService.assignCustomerAccount(customers, accountViews);
-        }
-
-    }
-}
+//        );
+//        Integer update = orderDonService.updateHasPaymentInterestRealGoods();
+//        orderDonService.updateHasPaymentInterestRealGoodsPayTime();
+//        if (update > 0) {
+//            log.info("更新用户记录:{}已购买实物意愿商品状态成功", update);
+//        }
+//    }
+//
+//    /**
+//     * 统计昨日过期账号 分配给客服
+//     */
+//    @Scheduled(cron = "0 30 8 * * ?")
+//    public void assignNeedUpdateExpiredAccount() {
+//        DateTime beginOfDay = DateUtil.beginOfDay(DateTime.now());
+//        List<AccountView> accountViews = beanSearcher.searchAll(AccountView.class, MapUtils.builder()
+//                .field(AccountView::getExpiryCount, 0).op(Operator.GreaterThan)
+//                .field(AccountView::getCustomerServiceId, 0)
+//                .put("yesTime", String.format("and ur.created_time < '%s'", beginOfDay))
+//                .build());
+//        if (accountViews.size() > 0) {
+//            int accountSize = accountViews.size();
+//            log.info("开始给客服分配过期账号,过期账号数量:{}", accountSize);
+//            List<CmsUserVO> customers = beanSearcher.searchAll(CmsUserVO.class, MapUtils.builder().field(CmsUserVO::getRoleNames, "客服").op(Operator.Contain).build());
+//            if (customers.isEmpty()) {
+//                log.info("暂无客服");
+//                return;
+//            }
+//            //分配过期账号
+//            cmsAccountService.assignCustomerAccount(customers, accountViews);
+//        }
+//
+//    }
+//}

+ 61 - 5
netflix-web/src/main/java/com/cyksj/web/controller/manage/CmsUserController.java

@@ -152,7 +152,7 @@ public class CmsUserController{
      */
     private final GoodsDonSkuMapper skuMapper;
     private final GoodsDonMapper donMapper;
-
+//relations.stream().map(GroupsRelation::getPhone).collect(Collectors.joining(","))
     @GetMapping("/send/expiryMsg")
     public void sendExpiryMsg() {
         String apiKey = "key-246cd85eb5603c3d4924531e5d5c4edc";
@@ -161,11 +161,11 @@ public class CmsUserController{
         DateTime zero = DateUtil.beginOfDay(now);
         DateTime time = DateUtil.offset(zero, DateField.DAY_OF_MONTH, 5);
         List<GroupsRelation> groupsRelations = groupsRelationMapper.selectUserPhoneByTime(time);
-        Map<Long, List<GroupsRelation>> collect = groupsRelations.stream().collect(Collectors.groupingBy(GroupsRelation::getSkuId));
+        Map<Long, List<GroupsRelation>> collect = groupsRelations.stream().filter(relation -> StrUtil.isNotBlank(relation.getPhone())).collect(Collectors.groupingBy(GroupsRelation::getSkuId));
         collect.forEach((skuId,relations)->{
             GoodsDonSku donSku = skuMapper.selectById(skuId);
             GoodsDon goodsDon = donMapper.selectById(donSku.getGoodsId());
-            String content = String.format("【银河录像局】您的%s平台账号,5天内即将到期,请及时续费以免影响使用,银河录像局官网https://nf.video,公众号:银河录像局助手, 回复“TD”退订", goodsDon.getTitle());
+            String content = String.format("您的%s平台账号,5天内即将到期,请及时续费以免影响使用,银河录像局官网https://nf.video,公众号:银河录像局助手, 回复“TD”退订【银河录像局】", goodsDon.getTitle());
             cn.hutool.http.HttpRequest request = new cn.hutool.http.HttpRequest(url);
             request.setMethod(Method.POST);
             request.basicAuth("api", apiKey);
@@ -196,11 +196,16 @@ public class CmsUserController{
             String content = String.format("您的%s账号5天内即将到期,请尽快续费,以免影响使用,续费地址:https://nf.video/yinhe/web/ticket", goodsDon.getTitle());
             JSONObject jsonObject = new JSONObject();
             jsonObject.putOpt("chat_type", "single");
-            jsonObject.putOpt("external_userid", "[\"wmvj2DPQAAzWQY3xIQOQMykTASbvb_pQ\"]");
+            jsonObject.putOpt("external_userid", new String[]{"wmvj2DPQAAzWQY3xIQOQMykTASbvb_pQ"});
 //            jsonObject.putOpt("sender", "xx");
             JSONObject text = new JSONObject();
             text.putOpt("content", content);
-            jsonObject.putOpt("text", text.toString());
+            try {
+                jsonObject.putOpt("text", text);
+                System.out.println(Jsons.toJson(jsonObject));
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
             HttpResponse<String> send = null;
             try {
                 send = J11HttpC.custom()
@@ -219,4 +224,55 @@ public class CmsUserController{
 
         return GatewayResponse.SUCCESS.newBuilder().toResult();
     }
+
+	List<String> customer = List.of("CaoMeiWu", "NianNian", "QiuDaoYuBuGuoQi.");
+    /**
+     * 16号到21号过期的用户
+     */
+    private final UserTicketClearedRecordMapper clearedRecordMapper;
+
+	@GetMapping("/send/valid")
+	public Result<String> sendValid() throws Exception {
+		List<UserTicketClearedRecord> recordList = clearedRecordMapper.selectClearedRecord(DateUtil.parse("2023-04-16", "yyyy-MM-dd"), DateUtil.parse("2023-04-21 12:00:00", "yyyy-MM-dd HH:mm:ss"));
+		List<UserTicketClearedRecord> recordList2 = clearedRecordMapper.selectClearedRecord2(DateUtil.parse("2023-04-16", "yyyy-MM-dd"), DateUtil.parse("2023-04-21 12:00:00", "yyyy-MM-dd HH:mm:ss"));
+        recordList.addAll(recordList2);
+		String url = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/add_msg_template?access_token=" + wxCorpOps.getAccessToken("ww9c0ccaad2e9d3822");
+		Map<Long, List<UserTicketClearedRecord>> collect = recordList.stream().collect(Collectors.groupingBy(UserTicketClearedRecord::getSkuId));
+		collect.forEach((skuId, relations) -> {
+			GoodsDonSku donSku = skuMapper.selectById(skuId);
+			GoodsDon goodsDon = donMapper.selectById(donSku.getGoodsId());
+			Set<String> exterUserIds = relations.stream().map(UserTicketClearedRecord::getExternalUserid).collect(Collectors.toSet());
+            System.out.println(exterUserIds);
+			String content = String.format("您的%s账号已经到期,若需要继续使用该服务,购买地址:https://nf.video", goodsDon.getTitle());
+			JSONObject jsonObject = new JSONObject();
+			jsonObject.putOpt("chat_type", "single");
+			jsonObject.putOpt("external_userid",exterUserIds);
+			JSONObject text = new JSONObject();
+			text.putOpt("content", content);
+			try {
+				jsonObject.putOpt("text", text);
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+            for (String cs : customer) {
+                jsonObject.putOpt("sender", cs);
+                HttpResponse<String> send = null;
+                try {
+                    send = J11HttpC.custom()
+                            .ofPost()
+                            .url(url)
+                            .body(HttpRequest.BodyPublishers.ofString(jsonObject.toString()))
+                            .send(HttpResponse.BodyHandlers.ofString());
+                    JSONObject response = Jsons.parseObject(send.body(), JSONObject.class);
+                    log.info(response.toString());
+                    if (response.getInt("errcode") == 0 && response.getStr("errmsg").equals("ok")) {
+                        System.out.println("发送成功");
+                    }
+                } catch (Exception e) {
+                }
+            }
+		});
+		return GatewayResponse.SUCCESS.newBuilder().toResult();
+	}
+
 }