瀏覽代碼

Merge branch 'feature/0729-group-message' into develop-new

# Conflicts:
#	cooleshow-common/src/main/java/com/yonge/cooleshow/common/constant/SysConfigConstant.java
Eric 1 年之前
父節點
當前提交
74ab4ead6d
共有 13 個文件被更改,包括 225 次插入90 次删除
  1. 4 0
      cooleshow-common/src/main/java/com/yonge/cooleshow/common/constant/SysConfigConstant.java
  2. 2 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/im/ImGroupCoreService.java
  3. 12 10
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/im/impl/ImGroupCoreServiceImpl.java
  4. 77 10
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/CustomerServiceBatchSendingServiceImpl.java
  5. 17 17
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/ImGroupServiceImpl.java
  6. 5 3
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/MemberPriceSettingsServiceImpl.java
  7. 10 8
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/StudentServiceImpl.java
  8. 5 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/TeacherServiceImpl.java
  9. 5 4
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/TenantGroupServiceImpl.java
  10. 34 8
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/VipCardRecordServiceImpl.java
  11. 2 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/VipCardRecordWrapper.java
  12. 26 11
      cooleshow-user/user-biz/src/main/resources/config/mybatis/VipCardRecordMapper.xml
  13. 26 18
      toolset/utils/src/main/java/com/yonge/toolset/utils/date/DateUtil.java

+ 4 - 0
cooleshow-common/src/main/java/com/yonge/cooleshow/common/constant/SysConfigConstant.java

@@ -456,4 +456,8 @@ public interface SysConfigConstant {
      */
     String CUSTOMER_SERVICE_ADD_MSG_TITLE = "customer_service_add_msg_title";
 
+    /**
+     * 消息发送频率限制
+     */
+    String MESSAGE_SEND_LIMIT = "message_send_limit";
 }

+ 2 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/im/ImGroupCoreService.java

@@ -48,6 +48,8 @@ public interface ImGroupCoreService {
     String analysisImUserId(String imUserId);
 
 
+    String analysisImUser(String imUserId);
+
     /**
      * 检测imUserid
      *

+ 12 - 10
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/im/impl/ImGroupCoreServiceImpl.java

@@ -7,7 +7,6 @@ import com.baomidou.mybatisplus.core.toolkit.IdWorker;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.dayaedu.cbs.common.enums.EClientType;
 import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
 import com.microsvc.toolkit.common.tools.ThreadPool;
 import com.microsvc.toolkit.middleware.im.ImPluginContext;
 import com.microsvc.toolkit.middleware.im.ImPluginService;
@@ -19,7 +18,6 @@ import com.yonge.cooleshow.biz.dal.entity.ImGroupMemberAudit;
 import com.yonge.cooleshow.biz.dal.entity.SysUser;
 import com.yonge.cooleshow.biz.dal.enums.AuditStatusEnum;
 import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
-import com.yonge.cooleshow.biz.dal.enums.ImGroupMemberRoleType;
 import com.yonge.cooleshow.biz.dal.enums.RoleEnum;
 import com.yonge.cooleshow.biz.dal.enums.im.EImGroupMemberRoleType;
 import com.yonge.cooleshow.biz.dal.service.ImGroupMemberAuditService;
@@ -27,14 +25,12 @@ import com.yonge.cooleshow.biz.dal.service.ImGroupMemberService;
 import com.yonge.cooleshow.biz.dal.service.ImGroupService;
 import com.yonge.cooleshow.biz.dal.service.SysUserService;
 import com.yonge.cooleshow.biz.dal.service.im.ImGroupCoreService;
-import com.yonge.cooleshow.biz.dal.wrapper.TenantActivationCodeWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.im.ImGroupMemberAuditWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.im.ImGroupMemberWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.im.ImGroupWrapper;
 import com.yonge.toolset.base.exception.BizException;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections.CollectionUtils;
-import org.apache.commons.collections.MapUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -120,7 +116,7 @@ public class ImGroupCoreServiceImpl implements ImGroupCoreService {
             clientType = "TEACHER";
         }
         if (StringUtils.isNotBlank(imConfig.getAppPrefix()) && !imUserId.startsWith(imConfig.getAppPrefix())) {
-            imUserId = MessageFormat.format("{0}_{1}_{2}", imConfig.getAppPrefix(), userId, clientType);
+            imUserId = MessageFormat.format("{0}_{1}_{2}", imConfig.getAppPrefix(), userId.toString(), clientType);
         }
         return imUserId;
     }
@@ -133,7 +129,7 @@ public class ImGroupCoreServiceImpl implements ImGroupCoreService {
             clientType = "TEACHER";
         }
         if (StringUtils.isNotBlank(imConfig.getAppPrefix()) && !imUserId.startsWith(imConfig.getAppPrefix())) {
-            imUserId = MessageFormat.format("{0}_{1}_{2}", imConfig.getAppPrefix(), userId, clientType);
+            imUserId = MessageFormat.format("{0}_{1}_{2}", imConfig.getAppPrefix(), userId.toString(), clientType);
         }
         return imUserId;
     }
@@ -152,6 +148,13 @@ public class ImGroupCoreServiceImpl implements ImGroupCoreService {
         }
         return imUserId;
     }
+    @Override
+    public String analysisImUser(String imUserId) {
+        if (StringUtils.isNotBlank(imConfig.getAppPrefix()) && imUserId.startsWith(imConfig.getAppPrefix())) {
+            return imUserId.replace(imConfig.getAppPrefix() + "_", "");
+        }
+        return imUserId;
+    }
 
 
     /**
@@ -738,7 +741,6 @@ public class ImGroupCoreServiceImpl implements ImGroupCoreService {
      */
     @Override
     public void changeGroupOwner(String groupId, String newOwner, String oldOwner) throws Exception {
-
         try {
             if (newOwner.equals(oldOwner)) {
                 throw new BizException("不能转让给自己");
@@ -746,7 +748,7 @@ public class ImGroupCoreServiceImpl implements ImGroupCoreService {
 
             {
                 // 判断旧群主
-                String[] values = analysisImUserId(oldOwner).split(IM_USER_ID_SPLIT);
+                String[] values = analysisImUser(oldOwner).split(IM_USER_ID_SPLIT);
 
                 // 新群主ID和身份
                 long userId = Long.parseLong(values[0]);
@@ -765,7 +767,7 @@ public class ImGroupCoreServiceImpl implements ImGroupCoreService {
 
             {
                 // 判定新群主是否为禁言状态,需要先解除禁言
-                String[] values = analysisImUserId(newOwner).split(IM_USER_ID_SPLIT);
+                String[] values = analysisImUser(newOwner).split(IM_USER_ID_SPLIT);
 
                 // 新群主ID和身份
                 long userId = Long.parseLong(values[0]);
@@ -1016,7 +1018,7 @@ public class ImGroupCoreServiceImpl implements ImGroupCoreService {
      * @param isAdmin 群主标记
      */
     private void updateGroupOwner(String groupId, String groupMember, Boolean isAdmin) {
-        String[] values = analysisImUserId(groupMember).split(IM_USER_ID_SPLIT);
+        String[] values = analysisImUser(groupMember).split(IM_USER_ID_SPLIT);
 
         // 新群主ID和身份
         long userId = Long.parseLong(values[0]);

+ 77 - 10
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/CustomerServiceBatchSendingServiceImpl.java

@@ -12,10 +12,10 @@ import com.microsvc.toolkit.middleware.im.ImPluginContext;
 import com.microsvc.toolkit.middleware.im.impl.TencentCloudImPlugin;
 import com.microsvc.toolkit.middleware.im.message.MessageWrapper;
 import com.microsvc.toolkit.middleware.im.message.TencentRequest;
-import com.yonge.cooleshow.auth.config.CustomerServiceConfig;
 import com.yonge.cooleshow.biz.dal.entity.CustomerServiceBatchSending;
 import com.yonge.cooleshow.biz.dal.entity.CustomerServiceReceive;
 import com.yonge.cooleshow.biz.dal.entity.Subject;
+import com.yonge.cooleshow.biz.dal.entity.SysConfig;
 import com.yonge.cooleshow.biz.dal.entity.SysUser;
 import com.yonge.cooleshow.biz.dal.entity.Teacher;
 import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
@@ -25,10 +25,16 @@ import com.yonge.cooleshow.biz.dal.enums.im.EImSendStatus;
 import com.yonge.cooleshow.biz.dal.enums.im.EImSendType;
 import com.yonge.cooleshow.biz.dal.mapper.CustomerServiceBatchSendingMapper;
 import com.yonge.cooleshow.biz.dal.mapper.SysUserMapper;
-import com.yonge.cooleshow.biz.dal.service.*;
+import com.yonge.cooleshow.biz.dal.service.CustomerServiceBatchSendingService;
+import com.yonge.cooleshow.biz.dal.service.CustomerServiceReceiveService;
+import com.yonge.cooleshow.biz.dal.service.ImGroupService;
+import com.yonge.cooleshow.biz.dal.service.SubjectService;
+import com.yonge.cooleshow.biz.dal.service.SysConfigService;
+import com.yonge.cooleshow.biz.dal.service.TeacherService;
 import com.yonge.cooleshow.biz.dal.wrapper.im.CustomerService;
 import com.yonge.cooleshow.biz.dal.wrapper.im.CustomerServiceBatchSendingWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.im.CustomerServiceReceiveWrapper;
+import com.yonge.cooleshow.common.constant.SysConfigConstant;
 import com.yonge.toolset.base.exception.BizException;
 import com.yonge.toolset.base.util.ImUtil;
 import com.yonge.toolset.base.util.ThreadPool;
@@ -37,9 +43,7 @@ import com.yonge.toolset.payment.util.DistributedLock;
 import io.rong.messages.BaseMessage;
 import io.rong.messages.ImgMessage;
 import io.rong.messages.TxtMessage;
-import io.rong.models.message.PrivateMessage;
 import io.rong.models.message.PushExt;
-import io.rong.models.response.ResponseResult;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.lang3.StringUtils;
@@ -50,7 +54,14 @@ import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import java.text.MessageFormat;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Random;
 import java.util.function.Function;
 import java.util.stream.Collectors;
 import java.util.stream.IntStream;
@@ -67,8 +78,7 @@ public class CustomerServiceBatchSendingServiceImpl extends ServiceImpl<Customer
     private CustomerServiceReceiveService customerServiceReceiveService;
     @Autowired
     private SubjectService subjectService;
-    @Autowired
-    private CustomerServiceConfig customerServiceConfig;
+
     @Autowired
     private SysUserMapper sysUserMapper;
     @Autowired
@@ -82,6 +92,9 @@ public class CustomerServiceBatchSendingServiceImpl extends ServiceImpl<Customer
     @Autowired
     private ImGroupService imGroupService;
 
+    @Autowired
+    private SysConfigService sysConfigService;
+
 	/**
      * 查询详情
      * @param id 详情ID
@@ -424,12 +437,31 @@ public class CustomerServiceBatchSendingServiceImpl extends ServiceImpl<Customer
 
                 try {
 
+                    // 消息发送数量,默认只发送1类消息(文字或图片)
+                    int messageNum = 1;
+                    if (StringUtils.isNoneBlank(info.getTextMessage(), info.getImgMessage())) {
+                        // 同时发送图片和文字消息
+                        messageNum += 1;
+                    }
+
+                    int messageSendLimit; // 默认发送11000/分钟
+                    // 群发消息频率限制
+                    SysConfig config = sysConfigService.findByParamName(SysConfigConstant.MESSAGE_SEND_LIMIT);
+                    // 群发消息频率限制不能超过11000/分钟,超过当前值默认取值为11000
+                    if (config != null && config.getParamValue().matches("\\d+")
+                        && Integer.parseInt(config.getParamValue()) < 11000) {
+                        messageSendLimit = Integer.parseInt(config.getParamValue());
+                    } else {
+                        messageSendLimit = 11000;
+                    }
+
+                    int finalMessageNum = messageNum;
                     if (EImReceiveType.ALL == info.getReceiveType()) {
 
                         // 推送消息给匹配用户
-                        List<String> targetGroupes = Arrays.stream(info.getTargetGroup().split(",")).collect(Collectors.toList());
+                        List<String> targetGroups = Arrays.stream(info.getTargetGroup().split(",")).collect(Collectors.toList());
 
-                        targetGroupes.parallelStream().forEach(clientType -> {
+                        targetGroups.parallelStream().forEach(clientType -> {
 
                             CustomerService.NotifyMessage receiveQuery = CustomerService.NotifyMessage.builder()
                                     .clientType(ClientEnum.valueOf(clientType))
@@ -445,6 +477,8 @@ public class CustomerServiceBatchSendingServiceImpl extends ServiceImpl<Customer
 
                             List<Integer> collect = IntStream.iterate(1, i -> i + 1).limit(pages).boxed().collect(Collectors.toList());
 
+                            // 线程休眠计算器
+                            int sleepCount = 0;
                             for (Integer pageNum : collect) {
 
                                 List<String> receiveUserIds = getBaseMapper().selectMessageReceives(PageUtil.getPage(pageNum, limit), receiveQuery).stream()
@@ -455,6 +489,8 @@ public class CustomerServiceBatchSendingServiceImpl extends ServiceImpl<Customer
                                         .map(x -> imGroupService.getImUserId(x, clientType))
                                         .collect(Collectors.toList());
 
+                                sleepCount = messageSendSleepCondition(info, sleepCount, receiveUserIds.size(), finalMessageNum, messageSendLimit);
+
                                 batchSendCustomerServiceMessage(info, receiveNums, receiveUserIds);
                             }
                         });
@@ -474,12 +510,17 @@ public class CustomerServiceBatchSendingServiceImpl extends ServiceImpl<Customer
 
                         List<Integer> collect = IntStream.iterate(1, i -> i + 1).limit(pages).boxed().collect(Collectors.toList());
 
+                        // 线程休眠计算器
+                        int sleepCount = 0;
                         for (Integer pageNum : collect) {
 
                             List<String> receiveUserIds = customerServiceReceiveService.selectPage(PageUtil.getPage(pageNum, limit), receiveQuery).getRecords().stream()
                                     .map(x -> imGroupService.getImUserId(String.valueOf(x.getUserId()), x.getClientType()))
                                     .collect(Collectors.toList());
 
+                            // 累加线程休眠计算器,若大于指定阀值时,线程休眠1分钟
+                            sleepCount = messageSendSleepCondition(info, sleepCount, receiveUserIds.size(), finalMessageNum, messageSendLimit);
+
                             batchSendCustomerServiceMessage(info, receiveNums, receiveUserIds);
                         }
                     }
@@ -502,6 +543,33 @@ public class CustomerServiceBatchSendingServiceImpl extends ServiceImpl<Customer
     }
 
     /**
+     * 消息发送休眠条件
+     * @param info CustomerServiceBatchSending
+     * @param sleepCount 休眠次数统计
+     * @param receiveSize 发送人数
+     * @param finalMessageNum 发送消息数
+     * @param messageSendLimit 消息休眠频率限制
+     * @return int
+     */
+    private static int messageSendSleepCondition(CustomerServiceBatchSending info, int sleepCount,
+                                                 int receiveSize, int finalMessageNum, int messageSendLimit) {
+        // 累加线程休眠计算器,若大于指定阀值时,线程休眠1分钟
+        sleepCount += receiveSize * finalMessageNum;
+        if (sleepCount > messageSendLimit) {
+            try {
+                // 线程休眠1分钟
+                Thread.sleep(1000 * 60);
+                log.info("messageSendSleepCondition THREAD_SLEEP END");
+            } catch (InterruptedException e) {
+                log.error("messageSendSleepCondition THREAD_SLEEP EX id={}", info.getId(), e);
+            }
+            // 重置线程休眠计算器
+            sleepCount = 0;
+        }
+        return sleepCount;
+    }
+
+    /**
      * 批量发送客服消息
      * @param info CustomerServiceBatchSending
      * @param receiveNums 接收消息用户数
@@ -563,7 +631,6 @@ public class CustomerServiceBatchSendingServiceImpl extends ServiceImpl<Customer
     /**
      * 推送消息类型
      * @param info CustomerServiceBatchSending
-     * @return List<BaseMessage>
      */
     private static void getReceiveMessage(CustomerServiceBatchSending info, List<BaseMessage> messages, List<TencentRequest.MessageBody> tencentMessages) {
 

+ 17 - 17
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/ImGroupServiceImpl.java

@@ -433,23 +433,6 @@ public class ImGroupServiceImpl extends ServiceImpl<ImGroupDao, ImGroup> impleme
         //保存老师学员关联的通讯录xz
         imUserFriendService.saveUserFriend(teacherId, Sets.newHashSet(studentIds));
 
-        //创建群聊
-        ImGroup imGroup = new ImGroup();
-        imGroup.setCreateBy(teacherId);
-        imGroup.setAutoPassFlag(false);
-        imGroup.setMemberNum(studentIds.size() + 1);
-        imGroup.setName(courseGroup.getName());
-        imGroup.setType(ImGroupType.COURSE);
-        imGroup.setImg(sysConfigService.findConfigValue(SysConfigConstant.ICON_COURSE_GROUP_DEFAULT));
-        imGroup.setCreateTime(now);
-        imGroup.setUpdateTime(now);
-//        String imGroupId = UUID.randomUUID() + imGroup.getType().getCode();
-//        imGroup.setId(imGroupId);
-        imGroup.setCourseGroupId(courseGroupId);
-//        this.baseMapper.insert(imGroup);
-
-        String groupId = createImGroup(imGroup);
-
         // 直播课、琴房课校验群成员人数限制
         if (CourseScheduleEnum.PIANO_ROOM_CLASS.getCode().equals(courseGroupType)
             || CourseScheduleEnum.LIVE.getCode().equals(courseGroupType)) {
@@ -472,6 +455,23 @@ public class ImGroupServiceImpl extends ServiceImpl<ImGroupDao, ImGroup> impleme
             }
         }
 
+        //创建群聊
+        ImGroup imGroup = new ImGroup();
+        imGroup.setCreateBy(teacherId);
+        imGroup.setAutoPassFlag(false);
+        imGroup.setMemberNum(studentIds.size() + 1);
+        imGroup.setName(courseGroup.getName());
+        imGroup.setType(ImGroupType.COURSE);
+        imGroup.setImg(sysConfigService.findConfigValue(SysConfigConstant.ICON_COURSE_GROUP_DEFAULT));
+        imGroup.setCreateTime(now);
+        imGroup.setUpdateTime(now);
+//        String imGroupId = UUID.randomUUID() + imGroup.getType().getCode();
+//        imGroup.setId(imGroupId);
+        imGroup.setCourseGroupId(courseGroupId);
+//        this.baseMapper.insert(imGroup);
+
+        String groupId = createImGroup(imGroup);
+
         if (!studentIds.isEmpty()) {
             // 添加学生
             List<ImGroupMember> groupMembers = imGroupMemberService.initGroupMembers(groupId, Sets.newHashSet(studentIds), ImGroupMemberRoleType.STUDENT);

+ 5 - 3
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/MemberPriceSettingsServiceImpl.java

@@ -224,17 +224,19 @@ public class MemberPriceSettingsServiceImpl extends ServiceImpl<MemberPriceSetti
         addVipCardRecord.setOrderNo(orderDetailVo.getOrderNo());
         addVipCardRecord.setSubOrderNo(orderDetailVo.getSubOrderNo());
         addVipCardRecord.setVipCardId(orderDetailVo.getBizId());
+        addVipCardRecord.setOrderFlag(true);
 
         // 判断转换天数
 
         VipCardRecordWrapper.UserVip userVip = vipCardRecordService.userVipInfo(orderDetailVo.getUserId(), orderDetailVo.getOrderClient());
         int svipDays = getSvipDays(detail, orderDetailVo.getGoodNum(), userVip);
-        if (userVip.getVipType() == EVipType.VIP) {
-            userVip.setVipEndDays(Math.max(userVip.getVipEndDays()-1,0));
-        }
         if (detail.getVipType() == EVipType.SVIP &&userVip.getVipEndDays() !=null && svipDays >=userVip.getVipEndDays()) {
             addVipCardRecord.setVipDays(userVip.getVipEndDays());
+            if (userVip.getVipType() == EVipType.VIP) {
+                addVipCardRecord.setVipDays(Math.max(userVip.getVipEndDays()-1,0));
+            }
         }
+
         addVipCardRecord.setReason("会员购买");
         vipCardRecordService.add(addVipCardRecord);
 

+ 10 - 8
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/StudentServiceImpl.java

@@ -136,14 +136,16 @@ public class StudentServiceImpl extends ServiceImpl<StudentDao, Student> impleme
     @Override
     public StudentVo detail(Long userId) {
         StudentVo detail = baseMapper.detail(userId);
-        VipCardRecordWrapper.UserVip userVip = vipCardRecordService.userVipInfo(userId, ClientEnum.STUDENT);
-        detail.setUserVip(userVip);
-        detail.setVipType(EUserVipType.NORMAL);
-        List<VipCardRecordWrapper.UserVipInfo> userVipInfos = vipCardRecordService.queryUserVipInfo(Collections.singletonList(userId), ClientEnum.STUDENT.getCode());
-        Map<Long, VipCardRecordWrapper.UserVipInfo> curVipMap = userVipInfos.stream().collect(Collectors.toMap(VipCardRecordWrapper.UserVipInfo::getUserId, Function.identity()));
-        VipCardRecordWrapper.UserVipInfo vipType = curVipMap.getOrDefault(userId, new VipCardRecordWrapper.UserVipInfo());
-        detail.setMembershipEndTime(vipType.getCurrentVipSvipEndTime());
-        detail.setVipType(vipType.getCurrentVipType());
+        if (detail != null) {
+            VipCardRecordWrapper.UserVip userVip = vipCardRecordService.userVipInfo(userId, ClientEnum.STUDENT);
+            detail.setUserVip(userVip);
+            detail.setVipType(EUserVipType.NORMAL);
+            List<VipCardRecordWrapper.UserVipInfo> userVipInfos = vipCardRecordService.queryUserVipInfo(Collections.singletonList(userId), ClientEnum.STUDENT.getCode());
+            Map<Long, VipCardRecordWrapper.UserVipInfo> curVipMap = userVipInfos.stream().collect(Collectors.toMap(VipCardRecordWrapper.UserVipInfo::getUserId, Function.identity()));
+            VipCardRecordWrapper.UserVipInfo vipType = curVipMap.getOrDefault(userId, new VipCardRecordWrapper.UserVipInfo());
+            detail.setMembershipEndTime(vipType.getCurrentVipSvipEndTime());
+            detail.setVipType(vipType.getCurrentVipType());
+        }
         return detail;
     }
 

+ 5 - 1
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/TeacherServiceImpl.java

@@ -328,6 +328,8 @@ public class TeacherServiceImpl extends ServiceImpl<TeacherDao, Teacher> impleme
     @Override
     @Transactional(rollbackFor = Exception.class)
     public HttpResponseResult<Boolean> submit(TeacherSubmitReq teacherSubmitReq) throws BizException {
+        // todo 暂时不上客服相关
+        teacherSubmitReq.setCustomerService(null);
         if (null == teacherSubmitReq.getUserId()) {
 
             if (StringUtils.isNoneBlank(teacherSubmitReq.getPhone(), teacherSubmitReq.getCode())) {
@@ -1510,8 +1512,10 @@ public class TeacherServiceImpl extends ServiceImpl<TeacherDao, Teacher> impleme
             throw new BizException("无效的老师账号");
         }
 
+        // todo 暂时不上,逻辑调整
         // 冻结客服,移交好友给其他客服
-        Boolean customerService = teacher.getCustomerService();
+//        Boolean customerService = teacher.getCustomerService();
+        Boolean customerService = null;
         if (UserLockFlag.NORMAL.equals(teacher.getLockFlag()) && Boolean.TRUE.equals(customerService)) {
             List<TeacherWrapper.CustomerServiceSendMsg2User> customerServiceSendMsg2User = transferFriend(teacherId, false);
             String customerMessage = sysConfigService.findConfigValue(SysConfigConstant.CUSTOMER_SERVICE_ADD_MSG);

+ 5 - 4
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/TenantGroupServiceImpl.java

@@ -8,6 +8,7 @@ import com.baomidou.mybatisplus.core.toolkit.IdWorker;
 import com.baomidou.mybatisplus.core.toolkit.StringUtils;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.dayaedu.cbs.common.enums.EClientType;
 import com.yonge.cooleshow.auth.api.entity.SysUser;
 import com.yonge.cooleshow.biz.dal.dao.StudentDao;
 import com.yonge.cooleshow.biz.dal.dao.SubjectDao;
@@ -447,8 +448,8 @@ public class TenantGroupServiceImpl extends ServiceImpl<TenantGroupMapper, Tenan
                     }
 
                     try {
-                        imGroupCoreService.changeGroupOwner(imGroupId, String.valueOf(toTeacher),
-                                String.valueOf(teacherId));
+                        imGroupCoreService.changeGroupOwner(imGroupId, imGroupCoreService.getImUserId(toTeacher, ClientEnum.TEACHER),
+                                imGroupCoreService.getImUserId(teacherId, ClientEnum.TEACHER));
                         imGroupCoreService.groupQuit(teacherId, ClientEnum.TEACHER.getCode(),
                                 imGroupId, true);
                         imGroupService.lambdaUpdate()
@@ -553,8 +554,8 @@ public class TenantGroupServiceImpl extends ServiceImpl<TenantGroupMapper, Tenan
 
         try {
             imGroupCoreService.changeGroupOwner(imGroupId,
-                    String.valueOf(newGroup.getAdminId()),
-                    String.valueOf(admin.getUserId()));
+                    imGroupCoreService.getImUserId(newGroup.getAdminId(), ClientEnum.TEACHER),
+                    imGroupCoreService.getImUserId(admin.getUserId(), ClientEnum.TEACHER));
             imGroupCoreService.groupQuit(admin.getUserId(), ClientEnum.TEACHER.getCode(), imGroupId, true);
             imGroupService.lambdaUpdate()
                     .set(ImGroup::getCreateBy, newGroup.getAdminId())

+ 34 - 8
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/VipCardRecordServiceImpl.java

@@ -321,15 +321,21 @@ public class VipCardRecordServiceImpl extends ServiceImpl<VipCardRecordDao, VipC
         } else {
             // 存在没有结束时间的SVIP记录 永久SVIP
             List<VipCardRecord> svipList = vipCardRecords.stream().filter(o -> o.getVipType() == EVipType.SVIP).collect(Collectors.toList());
+            Date svipEndDate = null;
             if (CollectionUtils.isNotEmpty(svipList)) {
                 userVip.setVipType(EVipType.SVIP);
 
                 Optional<VipCardRecord> first = svipList.stream().filter(o ->o.getType()==PeriodEnum.PERPETUAL).findFirst();
                 if (first.isPresent()) {
                     userVip.setVipType(EVipType.PERMANENT_SVIP);
-                } else {
-                    Optional<VipCardRecord> max = svipList.stream().max(Comparator.comparing(VipCardRecord::getEndTime));
-                    max.ifPresent(vipCardRecord -> userVip.setSvipEndDate(vipCardRecord.getEndTime()));
+                }
+//                else {
+                Optional<VipCardRecord> max = svipList.stream().filter(o -> !PeriodEnum.PERPETUAL.equals(o.getType())).max(Comparator.comparing(VipCardRecord::getEndTime));
+                max.ifPresent(vipCardRecord -> userVip.setSvipEndDate(vipCardRecord.getEndTime()));
+//                }
+                Optional<VipCardRecord> max1 = svipList.stream().max(Comparator.comparing(VipCardRecord::getEndTime));
+                if (max1.isPresent()) {
+                    svipEndDate = max1.get().getEndTime();
                 }
             } else {
                 Integer svipCount = this.lambdaQuery()
@@ -359,8 +365,8 @@ public class VipCardRecordServiceImpl extends ServiceImpl<VipCardRecordDao, VipC
                 // 设置VIP剩余天数
                 if (userVip.getVipEndDate() != null) {
                     int num;
-                    if (userVip.getSvipEndDate() != null && userVip.getSvipEndDate().after(new Date())) {
-                        num = DateUtil.daysBetween(userVip.getSvipEndDate(), userVip.getVipEndDate());
+                    if (svipEndDate != null && svipEndDate.after(new Date())) {
+                        num = DateUtil.daysBetween(svipEndDate, userVip.getVipEndDate());
                     } else if (minDate != null && minDate.after(new Date())){
                         num = DateUtil.daysBetween(minDate, userVip.getVipEndDate());
                     } else {
@@ -591,7 +597,17 @@ public class VipCardRecordServiceImpl extends ServiceImpl<VipCardRecordDao, VipC
 
     @Override
     public List<VipCardRecordWrapper.UserVipInfo> queryUserVipInfo(List<Long> userIdList, String clientType) {
-        return baseMapper.queryUserVipInfo(userIdList, clientType);
+        List<VipCardRecordWrapper.UserVipInfo> userVipInfos = baseMapper.queryUserVipInfo(userIdList, clientType);
+        Set<Long> userIds = new HashSet<>();
+        List<VipCardRecordWrapper.UserVipInfo> newUserVipInfos = new ArrayList<>();
+        for (VipCardRecordWrapper.UserVipInfo userVipInfo : userVipInfos) {
+            if (userIds.contains(userVipInfo.getUserId())) {
+                continue;
+            }
+            newUserVipInfos.add(userVipInfo);
+            userIds.add(userVipInfo.getUserId());
+        }
+        return newUserVipInfos;
     }
 
 
@@ -618,7 +634,8 @@ public class VipCardRecordServiceImpl extends ServiceImpl<VipCardRecordDao, VipC
         }
 
         // 扣减非永久
-        List<VipCardRecord> collect = vipCardRecordList.stream().filter(n -> n.getVipType().equals(addVipCardRecord.getVipType())).collect(Collectors.toList());
+        List<VipCardRecord> collect = vipCardRecordList.stream()
+                .filter(n -> n.getVipType().equals(addVipCardRecord.getVipType()) && !PeriodEnum.PERPETUAL.equals(n.getType())).collect(Collectors.toList());
         if (collect.isEmpty()) {
             throw new BizException("剩余扣减数量不足");
         }
@@ -653,6 +670,13 @@ public class VipCardRecordServiceImpl extends ServiceImpl<VipCardRecordDao, VipC
         if (deductedStartDate.before(minStartTime)) {
             double day = (minStartTime.getTime() - deductedStartDate.getTime()) * 1.0D / (24 * 60 * 60 * 1000);
             if (day > 1.0D) {
+                if (addVipCardRecord.isOrderFlag()) {
+                    collect.stream().forEach(o->o.setEfficientFlag(false));
+
+                    this.updateBatchById(collect, 100);
+                    return null;
+                }
+
                 throw new BizException("剩余扣减数量不足");
             }
 //            deductedStartDate = minStartTime;
@@ -694,7 +718,7 @@ public class VipCardRecordServiceImpl extends ServiceImpl<VipCardRecordDao, VipC
                 deductMills = endTime.getTime() - deductedStartDate.getTime();
                 endDeductMills = endTime.getTime() - formatEnd(deductedStartDate).getTime();
             } else {
-                if (vipCardRecord.getVipType().equals(vipType)) {
+                if (vipCardRecord.getVipType().equals(vipType) && !PeriodEnum.PERPETUAL.equals(vipCardRecord.getType())) {
                     deductMills = endTime.getTime() - deductedStartDate.getTime();
                     endDeductMills = endTime.getTime() - formatEnd(deductedStartDate).getTime();
                 } else {
@@ -773,9 +797,11 @@ public class VipCardRecordServiceImpl extends ServiceImpl<VipCardRecordDao, VipC
                     newRecord.setStartTime(new Date(newRecord.getStartTime().getTime() - deductMills));
                     giveFlag = true;
                 } else {
+                    endDeductMills = vipCardRecord.getStartTime().getTime() - (lastEndUnPereutalDate.getTime() +1000);
                     newRecord.setStartTime(new Date(newRecord.getStartTime().getTime() - endDeductMills));
                 }
                 newRecord.setEndTime(new Date(newRecord.getEndTime().getTime() - endDeductMills));
+                lastEndUnPereutalDate = newRecord.getEndTime();
                 save(newRecord);
                 Long refId = newRecord.getId();
 

+ 2 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/VipCardRecordWrapper.java

@@ -97,6 +97,8 @@ public class VipCardRecordWrapper {
         private String orderNo;
         private Long vipCardId;
         private String subOrderNo;
+
+        private boolean orderFlag = false;
     }
 
     @Data

+ 26 - 11
cooleshow-user/user-biz/src/main/resources/config/mybatis/VipCardRecordMapper.xml

@@ -81,10 +81,18 @@
             <include refid="baseColumns"/>,
             u.phone_ as phone
         from (
-            select any_value(id_) id_
-            from (
-            select * from vip_card_record where efficient_flag_ = 1 and end_time_ &gt;= now() and end_time_ &lt; DATE_ADD(now(),INTERVAL 3 DAY) order by end_time_ desc
-            ) t group by t.user_id_,t.client_type_,t.vip_type_
+        select
+        any_value(id_) id_
+        , max(if(vip_type_ = 'VIP', end_time_, null))  vipEndTime
+        , max(if(vip_type_ = 'SVIP', end_time_, null)) svipEndTime
+        from (select id_,user_id_,client_type_,vip_type_,end_time_
+        from vip_card_record
+        where efficient_flag_ = 1
+        and end_time_ > now()
+        having 1
+        order by end_time_ desc) t
+        group by t.user_id_, t.client_type_, t.vip_type_
+        having (DATE_ADD(now(), INTERVAL 3 DAY) > vipEndTime or DATE_ADD(now(), INTERVAL 3 DAY) > svipEndTime)
         ) a
         left join vip_card_record t on a.id_ = t.id_
         left join sys_user u on t.user_id_ = u.id_
@@ -97,16 +105,22 @@
             <include refid="baseColumns"/>,
             u.phone_ as phone
         from (
-            select any_value(id_) id_
-            from (
-            select * from vip_card_record where efficient_flag_ = 1 order by end_time_ desc
-            ) t group by t.user_id_,t.client_type_,t.vip_type_
+            select
+            any_value(id_) id_
+            ,user_id_
+            , max(if(vip_type_ = 'VIP', end_time_, null))  vipEndTime
+            , max(if(vip_type_ = 'SVIP', end_time_, null)) svipEndTime
+            from (select id_,user_id_,client_type_,vip_type_,end_time_
+            from vip_card_record
+            where efficient_flag_ = 1
+            and msg_status_ in (0,1)
+            having 1
+            order by end_time_ desc) t
+            group by t.user_id_, t.client_type_, t.vip_type_
+            having ( now() > vipEndTime or now()> svipEndTime)
         ) a
         left join vip_card_record t on a.id_ = t.id_
         left join sys_user u on t.user_id_ = u.id_
-        where t.efficient_flag_ = 1
-        and t.end_time_ &lt;= now()
-        and msg_status_ in (0,1)
         order by end_time_ desc
     </select>
 
@@ -161,5 +175,6 @@
         and t.efficient_flag_ = 1
         group by t.user_id_) m
         left join vip_card_record vcr on m.userId = vcr.user_id_ and vcr.end_time_ > now() and now() >= vcr.start_time_ and efficient_flag_ = 1 and vcr.client_type_ = #{clientType}
+        order by vcr.end_time_ desc
     </select>
 </mapper>

+ 26 - 18
toolset/utils/src/main/java/com/yonge/toolset/utils/date/DateUtil.java

@@ -7,6 +7,7 @@ import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.time.DayOfWeek;
 import java.time.LocalDate;
+import java.time.LocalDateTime;
 import java.time.ZoneId;
 import java.time.format.DateTimeFormatter;
 import java.time.temporal.ChronoUnit;
@@ -560,11 +561,15 @@ public class DateUtil {
 		if(null == early || null == late){
 			return 0;
 		}
-		Calendar c1 = Calendar.getInstance();
-		Calendar c2 = Calendar.getInstance();
-		c1.setTime(early);
-		c2.setTime(late);
-		return dateToJulianDay(c2.getTime()) - dateToJulianDay(c1.getTime());
+
+        long epochSecond = early.toInstant().getEpochSecond();
+        long epochSecond1 = late.toInstant().getEpochSecond();
+        return (int) (epochSecond1 - epochSecond +1)/(24*60*60)  ;
+//		Calendar c1 = Calendar.getInstance();
+//		Calendar c2 = Calendar.getInstance();
+//		c1.setTime(early);
+//		c2.setTime(late);
+//		return dateToJulianDay(c2.getTime()) - dateToJulianDay(c1.getTime());
 	}
 
 	/**
@@ -1511,19 +1516,22 @@ public class DateUtil {
 	}
 
 	public static void main(String[] args) throws ParseException {
+        Date from = Date.from(LocalDateTime.of(2024, 7, 27, 23, 59, 59).atZone(ZoneId.systemDefault()).toInstant());
+        Date start = Date.from(LocalDateTime.of(2024, 7, 26, 0, 0, 0).atZone(ZoneId.systemDefault()).toInstant());
+        System.out.println(daysBetween(start, from));
 		// DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
-		DateFormat df1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
-//		 System.out.println(daysBetween(df.parse("2017-07-20 10:07:42"), df.parse(df.format(new Date()))));
-		System.out.println(getWeekMondayWithDate(new Date()));
-		System.out.println(getNextWeekMonday(new Date()));
-		System.out.println(getNextWeekSunday(new Date()));
-		System.out.println(dayEnd(new Date()));
-		System.out.println(format(getLastDayOfMonth(new Date()),CHINESE_DATA_FORMAT));
-		System.out.println(monthsBetween(df1.parse("2020-01-18 12:00:00"),df1.parse("2020-04-19 12:00:00")));
-		System.out.println(getNextWeekMonday(new Date()));
-
-		System.out.println(getMonthDiff(
-				DateUtil.parse("2022-01-05",DEFAULT_PATTERN),
-				DateUtil.parse("2022-02-04",DEFAULT_PATTERN)));
+//		DateFormat df1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+////		 System.out.println(daysBetween(df.parse("2017-07-20 10:07:42"), df.parse(df.format(new Date()))));
+//		System.out.println(getWeekMondayWithDate(new Date()));
+//		System.out.println(getNextWeekMonday(new Date()));
+//		System.out.println(getNextWeekSunday(new Date()));
+//		System.out.println(dayEnd(new Date()));
+//		System.out.println(format(getLastDayOfMonth(new Date()),CHINESE_DATA_FORMAT));
+//		System.out.println(monthsBetween(df1.parse("2020-01-18 12:00:00"),df1.parse("2020-04-19 12:00:00")));
+//		System.out.println(getNextWeekMonday(new Date()));
+//
+//		System.out.println(getMonthDiff(
+//				DateUtil.parse("2022-01-05",DEFAULT_PATTERN),
+//				DateUtil.parse("2022-02-04",DEFAULT_PATTERN)));
 	}
 }