Browse Source

群聊客服逻辑调整

yuanliang 9 months ago
parent
commit
bfd71fbb6d
14 changed files with 236 additions and 36 deletions
  1. 13 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/ImUserFriend.java
  2. 12 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/Student.java
  3. 4 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/Teacher.java
  4. 32 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/im/EImUserFriendSourceForm.java
  5. 3 2
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/ImUserFriendService.java
  6. 2 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/CourseScheduleServiceImpl.java
  7. 3 2
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/ImGroupServiceImpl.java
  8. 21 5
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/ImUserFriendServiceImpl.java
  9. 2 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/PaymentDivMemberRecordServiceImpl.java
  10. 13 11
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/StudentServiceImpl.java
  11. 123 12
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/TeacherServiceImpl.java
  12. 4 2
      cooleshow-user/user-biz/src/main/resources/config/mybatis/ImUserFriendMapper.xml
  13. 2 0
      cooleshow-user/user-biz/src/main/resources/config/mybatis/StudentMapper.xml
  14. 2 0
      cooleshow-user/user-biz/src/main/resources/config/mybatis/TeacherMapper.xml

+ 13 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/ImUserFriend.java

@@ -6,6 +6,7 @@ import java.util.Date;
 import com.baomidou.mybatisplus.annotation.IdType;
 import com.baomidou.mybatisplus.annotation.TableField;
 import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.enums.im.EImUserFriendSourceForm;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import com.baomidou.mybatisplus.annotation.TableId;
@@ -64,6 +65,10 @@ public class ImUserFriend implements Serializable {
     @ApiModelProperty(value = "修改时间;")
     private Date updateTime;
 
+    @TableField("source_form_")
+    @ApiModelProperty(value = "建立好友时,标记建立身份,TEACHER:以老师身份建立,CUSTOMER:以客服身份建立")
+    private EImUserFriendSourceForm sourceForm;
+
     public String getFriendAvatar() {
         return friendAvatar;
     }
@@ -157,5 +162,13 @@ public class ImUserFriend implements Serializable {
     public void setFriendType(ClientEnum friendType) {
         this.friendType = friendType;
     }
+
+    public EImUserFriendSourceForm getSourceForm() {
+        return sourceForm;
+    }
+
+    public void setSourceForm(EImUserFriendSourceForm sourceForm) {
+        this.sourceForm = sourceForm;
+    }
 }
 

+ 12 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/Student.java

@@ -112,6 +112,10 @@ public class Student implements Serializable {
     @TableField(value = "im_device_id_")
     private String imDeviceId;
 
+    @ApiModelProperty("专属客服ID")
+    @TableField(value = "customer_id_")
+    private Long customerId;
+
     public Long getTenantId() {
         return tenantId;
     }
@@ -231,4 +235,12 @@ public class Student implements Serializable {
     public void setHideFlag(Integer hideFlag) {
         this.hideFlag = hideFlag;
     }
+
+    public String getAvatar() {
+        return avatar;
+    }
+
+    public void setAvatar(String avatar) {
+        this.avatar = avatar;
+    }
 }

+ 4 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/Teacher.java

@@ -255,6 +255,10 @@ public class Teacher implements Serializable {
     @TableField(value = "customer_service_")
     private Boolean customerService;
 
+    @ApiModelProperty("专属客服ID")
+    @TableField(value = "customer_id_")
+    private Long customerId;
+
     public ESettlementFrom getSettlementFrom() {
         return settlementFrom;
     }

+ 32 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/im/EImUserFriendSourceForm.java

@@ -0,0 +1,32 @@
+package com.yonge.cooleshow.biz.dal.enums.im;
+
+import com.baomidou.mybatisplus.annotation.EnumValue;
+import com.yonge.toolset.base.enums.BaseEnum;
+
+/**
+ * 用户会员类型
+ */
+public enum EImUserFriendSourceForm implements BaseEnum<String, EImUserFriendSourceForm> {
+
+    TEACHER("老师身份"),
+    CUSTOMER("客服"),
+
+    ;
+    @EnumValue
+    private String code;
+    private String name;
+
+    EImUserFriendSourceForm(String name) {
+        this.code = this.name();
+        this.name = name;
+    }
+
+    @Override
+    public String getCode() {
+        return this.code;
+    }
+
+    public String getName() {
+        return name;
+    }
+}

+ 3 - 2
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/ImUserFriendService.java

@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.extension.service.IService;
 import com.yonge.cooleshow.biz.dal.dao.ImUserFriendDao;
 import com.yonge.cooleshow.biz.dal.entity.ImUserFriend;
 import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.enums.im.EImUserFriendSourceForm;
 import com.yonge.cooleshow.biz.dal.vo.im.ImUserFriendVO;
 import com.yonge.cooleshow.biz.dal.wrapper.im.CustomerService;
 import com.yonge.cooleshow.biz.dal.wrapper.im.ImUserWrapper;
@@ -31,9 +32,9 @@ public interface ImUserFriendService extends IService<ImUserFriend> {
     * @author zx
     * @date 2022/3/24 10:06
     */
-    void saveUserFriend(Long teacherId, Set<Long> studentIds);
+    void saveUserFriend(Long teacherId, Set<Long> studentIds, EImUserFriendSourceForm sourceForm);
 
-    void saveUserTeacherFriend(Long teacherId, Set<Long> teacherIds);
+    void saveUserTeacherFriend(Long teacherId, Set<Long> teacherIds, EImUserFriendSourceForm sourceForm);
 
     /**
     * @description: 获取用户详情

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

@@ -23,6 +23,7 @@ import com.yonge.cooleshow.biz.dal.dto.search.MyCourseSearch;
 import com.yonge.cooleshow.biz.dal.dto.search.PracticeTeacherSearch;
 import com.yonge.cooleshow.biz.dal.entity.*;
 import com.yonge.cooleshow.biz.dal.enums.*;
+import com.yonge.cooleshow.biz.dal.enums.im.EImUserFriendSourceForm;
 import com.yonge.cooleshow.biz.dal.service.*;
 import com.yonge.cooleshow.biz.dal.wrapper.course.CourseScheduleWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.liveroom.LiveRoomWrapper;
@@ -1200,7 +1201,7 @@ public class CourseScheduleServiceImpl extends ServiceImpl<CourseScheduleDao, Co
         Set<Long> studentIds = new HashSet();
         studentIds.add(studentId);
         try {
-            imUserFriendService.saveUserFriend(teacherId, studentIds);
+            imUserFriendService.saveUserFriend(teacherId, studentIds, EImUserFriendSourceForm.TEACHER);
             log.info("保存用户通讯录成功,teacherId:{},studentIds:{}", teacherId, studentIds);
         } catch (Exception e) {
             log.error("保存用户通讯录失败,teacherId:{},studentIds:{},e:{}", teacherId, studentIds, e);

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

@@ -38,6 +38,7 @@ import com.yonge.cooleshow.biz.dal.enums.CourseScheduleEnum;
 import com.yonge.cooleshow.biz.dal.enums.ImGroupMemberRoleType;
 import com.yonge.cooleshow.biz.dal.enums.ImGroupType;
 import com.yonge.cooleshow.biz.dal.enums.RoleEnum;
+import com.yonge.cooleshow.biz.dal.enums.im.EImUserFriendSourceForm;
 import com.yonge.cooleshow.biz.dal.service.*;
 import com.yonge.cooleshow.biz.dal.entity.CourseGroup;
 import com.yonge.cooleshow.biz.dal.entity.ImGroup;
@@ -391,7 +392,7 @@ public class ImGroupServiceImpl extends ServiceImpl<ImGroupDao, ImGroup> impleme
                         .eq(ImGroupMember::getGroupId, groupId)
                         .eq(ImGroupMember::getRoleType, ImGroupMemberRoleType.TEACHER)
                         .list();
-                    teacherList.forEach(teacher -> imUserFriendService.saveUserFriend(teacher.getUserId(), studentIdList));
+                    teacherList.forEach(teacher -> imUserFriendService.saveUserFriend(teacher.getUserId(), studentIdList, EImUserFriendSourceForm.TEACHER));
                 }
             } catch (Exception e) {
                 log.error("加入群组失败,{}", e.getMessage(), e);
@@ -421,7 +422,7 @@ public class ImGroupServiceImpl extends ServiceImpl<ImGroupDao, ImGroup> impleme
         Date now = new Date();
         Long teacherId = courseGroup.getTeacherId();
         //保存老师学员关联的通讯录xz
-        imUserFriendService.saveUserFriend(teacherId, Sets.newHashSet(studentIds));
+        imUserFriendService.saveUserFriend(teacherId, Sets.newHashSet(studentIds),EImUserFriendSourceForm.TEACHER);
 
         // 直播课、琴房课校验群成员人数限制
         if (CourseScheduleEnum.PIANO_ROOM_CLASS.getCode().equals(courseGroupType)

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

@@ -2,6 +2,7 @@ package com.yonge.cooleshow.biz.dal.service.impl;
 
 import com.alibaba.fastjson.JSON;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.google.common.collect.Lists;
@@ -19,9 +20,12 @@ import com.yonge.cooleshow.biz.dal.dao.StudentDao;
 import com.yonge.cooleshow.biz.dal.dao.TeacherDao;
 import com.yonge.cooleshow.biz.dal.dto.BasicUserInfo;
 import com.yonge.cooleshow.biz.dal.entity.ImUserFriend;
+import com.yonge.cooleshow.biz.dal.entity.Student;
 import com.yonge.cooleshow.biz.dal.entity.Subject;
+import com.yonge.cooleshow.biz.dal.entity.Teacher;
 import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
 import com.yonge.cooleshow.biz.dal.enums.MK;
+import com.yonge.cooleshow.biz.dal.enums.im.EImUserFriendSourceForm;
 import com.yonge.cooleshow.biz.dal.mapper.SysUserMapper;
 import com.yonge.cooleshow.biz.dal.service.ImGroupService;
 import com.yonge.cooleshow.biz.dal.service.ImUserFriendService;
@@ -98,9 +102,15 @@ public class ImUserFriendServiceImpl extends ServiceImpl<ImUserFriendDao, ImUser
         return this.baseMapper;
     }
 
+    /**
+     *
+     * @param teacherId 老师ID
+     * @param studentIds  学生列表
+     * @param sourceForm 建立关系方式,TEACHER:已老师身份添加或更新关系,CUSTOMER:以客服身份添加或者更新关系
+     */
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public void saveUserFriend(Long teacherId, Set<Long> studentIds) {
+    public void saveUserFriend(Long teacherId, Set<Long> studentIds, EImUserFriendSourceForm sourceForm) {
         if (CollectionUtils.isEmpty(studentIds)) {
             return;
         }
@@ -134,6 +144,7 @@ public class ImUserFriendServiceImpl extends ServiceImpl<ImUserFriendDao, ImUser
             teacherFriend.setFriendId(studentId);
             teacherFriend.setFriendType(ClientEnum.STUDENT);
             teacherFriend.setUserId(teacherId);
+            teacherFriend.setSourceForm(sourceForm);
             teacherFriend.setCreateTime(now);
             teacherFriend.setUpdateTime(now);
 
@@ -141,6 +152,7 @@ public class ImUserFriendServiceImpl extends ServiceImpl<ImUserFriendDao, ImUser
             studentFriend.setFriendId(teacherId);
             studentFriend.setFriendType(ClientEnum.TEACHER);
             studentFriend.setUserId(studentId);
+            studentFriend.setSourceForm(sourceForm);
             studentFriend.setCreateTime(now);
             studentFriend.setUpdateTime(now);
             imUserFriends.add(teacherFriend);
@@ -151,7 +163,7 @@ public class ImUserFriendServiceImpl extends ServiceImpl<ImUserFriendDao, ImUser
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public void saveUserTeacherFriend(Long teacherId, Set<Long> teacherIds) {
+    public void saveUserTeacherFriend(Long teacherId, Set<Long> teacherIds, EImUserFriendSourceForm sourceForm) {
         if (CollectionUtils.isEmpty(teacherIds)) {
             return;
         }
@@ -181,6 +193,7 @@ public class ImUserFriendServiceImpl extends ServiceImpl<ImUserFriendDao, ImUser
             teacherFriend.setFriendId(studentId);
             teacherFriend.setFriendType(ClientEnum.TEACHER);
             teacherFriend.setUserId(teacherId);
+            teacherFriend.setSourceForm(sourceForm);
             teacherFriend.setCreateTime(now);
             teacherFriend.setUpdateTime(now);
 
@@ -188,6 +201,7 @@ public class ImUserFriendServiceImpl extends ServiceImpl<ImUserFriendDao, ImUser
             studentFriend.setFriendId(teacherId);
             studentFriend.setFriendType(ClientEnum.TEACHER);
             studentFriend.setUserId(studentId);
+            studentFriend.setSourceForm(sourceForm);
             studentFriend.setCreateTime(now);
             studentFriend.setUpdateTime(now);
             imUserFriends.add(teacherFriend);
@@ -269,7 +283,7 @@ public class ImUserFriendServiceImpl extends ServiceImpl<ImUserFriendDao, ImUser
      * 新用户自动添加客服
      *
      * @param userId     新用户ID
-     * @param friendIds  好友ID
+     * @param friendIds  好友ID,客服ID
      * @param clientType 客户端类型
      * @return Integer
      */
@@ -286,9 +300,11 @@ public class ImUserFriendServiceImpl extends ServiceImpl<ImUserFriendDao, ImUser
         // 添加新用户好友,客服默认为老师身份
         for (Long teacherId : friendIds) {
             if (ClientEnum.STUDENT == clientType) {
-                saveUserFriend(teacherId, Sets.newHashSet(userId));
+                saveUserFriend(teacherId, Sets.newHashSet(userId), EImUserFriendSourceForm.CUSTOMER);
+                studentDao.update(null, new UpdateWrapper<Student>().lambda().eq(Student::getUserId, userId).set(Student::getCustomerId, teacherId));
             } else if (ClientEnum.TEACHER == clientType) {
-                saveUserTeacherFriend(teacherId, Sets.newHashSet(userId));
+                saveUserTeacherFriend(teacherId, Sets.newHashSet(userId), EImUserFriendSourceForm.CUSTOMER);
+                teacherDao.update(null, new UpdateWrapper<Teacher>().lambda().eq(Teacher::getUserId, userId).set(Teacher::getCustomerId, teacherId));
             }
 
             // 新注册用户为老师身份时,更新好友关系为老师身份

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

@@ -22,6 +22,7 @@ import com.yonge.cooleshow.biz.dal.entity.*;
 import com.yonge.cooleshow.biz.dal.enums.*;
 import com.yonge.cooleshow.biz.dal.enums.album.PurchaseRecordTypeEnum;
 import com.yonge.cooleshow.biz.dal.enums.course.CourseRelationTypeEnum;
+import com.yonge.cooleshow.biz.dal.enums.im.EImUserFriendSourceForm;
 import com.yonge.cooleshow.biz.dal.mapper.PaymentDivMemberRecordMapper;
 import com.yonge.cooleshow.biz.dal.service.*;
 import com.yonge.cooleshow.biz.dal.support.WrapperUtil;
@@ -463,7 +464,7 @@ public class PaymentDivMemberRecordServiceImpl extends ServiceImpl<PaymentDivMem
         Set<Long> studentIds = new HashSet();
         studentIds.add(studentId);
         try {
-            imUserFriendService.saveUserFriend(teacherId, studentIds);
+            imUserFriendService.saveUserFriend(teacherId, studentIds, EImUserFriendSourceForm.TEACHER);
             log.info("保存用户通讯录成功,teacherId:{},studentIds:{}", teacherId, studentIds);
         } catch (Exception e) {
             log.error("保存用户通讯录失败,teacherId:{},studentIds:{},e:{}", teacherId, studentIds, e);

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

@@ -18,6 +18,7 @@ import com.yonge.cooleshow.biz.dal.dto.search.QueryMyFollowSearch;
 import com.yonge.cooleshow.biz.dal.dto.search.StudentSearch;
 import com.yonge.cooleshow.biz.dal.entity.*;
 import com.yonge.cooleshow.biz.dal.enums.*;
+import com.yonge.cooleshow.biz.dal.enums.im.EImUserFriendSourceForm;
 import com.yonge.cooleshow.biz.dal.mapper.SysUserMapper;
 import com.yonge.cooleshow.biz.dal.mapper.TenantAlbumMapper;
 import com.yonge.cooleshow.biz.dal.mapper.TenantAlbumRefMapper;
@@ -383,7 +384,7 @@ public class StudentServiceImpl extends ServiceImpl<StudentDao, Student> impleme
             //学生老师增加好友关系
             Set<Long> studentIds = new HashSet<>();
             studentIds.add(studentVo.getUserId());
-            imUserFriendService.saveUserFriend(userId, studentIds);
+            imUserFriendService.saveUserFriend(userId, studentIds, EImUserFriendSourceForm.TEACHER);
         }
         resMap.put("now", detail);
         return HttpResponseResult.succeed(resMap);
@@ -645,7 +646,7 @@ public class StudentServiceImpl extends ServiceImpl<StudentDao, Student> impleme
             for (Teacher teacher : teachers) {
                 HashSet<Long> studentIds = new HashSet<>();
                 studentIds.add(student.getUserId());
-                imUserFriendService.saveUserFriend(teacher.getUserId(), studentIds);
+                imUserFriendService.saveUserFriend(teacher.getUserId(), studentIds, EImUserFriendSourceForm.TEACHER);
             }
             addBindUnBindRecord(student.getUserId(),student.getTenantId(),true);
         }
@@ -736,7 +737,7 @@ public class StudentServiceImpl extends ServiceImpl<StudentDao, Student> impleme
             for (Teacher teacher : teachers) {
                 HashSet<Long> studentIds = new HashSet<>();
                 studentIds.add(student.getUserId());
-                imUserFriendService.saveUserFriend(teacher.getUserId(), studentIds);
+                imUserFriendService.saveUserFriend(teacher.getUserId(), studentIds,EImUserFriendSourceForm.TEACHER);
             }
 
             addBindUnBindRecord(student.getUserId(),studentInfo.getTenantId(),true);
@@ -884,6 +885,14 @@ public class StudentServiceImpl extends ServiceImpl<StudentDao, Student> impleme
         student.setLockFlag(UserLockFlag.NORMAL);
         student.setTenantGroupId(studentInfo.getTenantGroupId());
 
+        //  与好友数量最少的客服建立好友关系
+        Teacher customerService = teacherDao.getCustomerServiceByFriendLeast();
+        if (customerService != null) {
+            imUserFriendService.registerUserBindCustomerService(student.getUserId(),
+                    Collections.singletonList(customerService.getUserId()), ClientEnum.STUDENT);
+            student.setCustomerId(customerService.getUserId());
+        }
+
         save(student);
         try {
             // 注册IM
@@ -899,18 +908,11 @@ public class StudentServiceImpl extends ServiceImpl<StudentDao, Student> impleme
             queryWrapper.lambda().eq(Teacher::getTenantId, student.getTenantId());
             List<Teacher> teacherList = teacherDao.selectList(queryWrapper);
             teacherList.forEach(next -> imUserFriendService.saveUserFriend(next.getUserId(),
-                    new HashSet<>(ImmutableList.of(sysUser.getId()))));
+                    new HashSet<>(ImmutableList.of(sysUser.getId())),EImUserFriendSourceForm.TEACHER));
 
             addBindUnBindRecord(student.getUserId(), student.getTenantId(), true);
         }
 
-        //  与好友数量最少的客服建立好友关系
-        Teacher customerService = teacherDao.getCustomerServiceByFriendLeast();
-        if (customerService != null) {
-            imUserFriendService.registerUserBindCustomerService(student.getUserId(),
-                    Collections.singletonList(customerService.getUserId()), ClientEnum.STUDENT);
-        }
-
         // 加入机构小组群
 //        if (studentInfo.getTenantGroupId() != -1L) {
 //            add2TenantGroupIM(student.getTenantGroupId(), student.getUserId());

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

@@ -27,6 +27,7 @@ import com.yonge.cooleshow.biz.dal.enums.MessageTypeEnum;
 import com.yonge.cooleshow.biz.dal.enums.TeacherTagEnum;
 import com.yonge.cooleshow.biz.dal.enums.TeacherTypeEnum;
 import com.yonge.cooleshow.biz.dal.enums.im.EImGroupMemberRoleType;
+import com.yonge.cooleshow.biz.dal.enums.im.EImUserFriendSourceForm;
 import com.yonge.cooleshow.biz.dal.mapper.TenantGroupMapper;
 import com.yonge.cooleshow.biz.dal.mapper.UserTenantBindRecordMapper;
 import com.yonge.cooleshow.biz.dal.queryInfo.TeacherQueryInfo;
@@ -329,7 +330,7 @@ public class TeacherServiceImpl extends ServiceImpl<TeacherDao, Teacher> impleme
     @Transactional(rollbackFor = Exception.class)
     public HttpResponseResult<Boolean> submit(TeacherSubmitReq teacherSubmitReq) throws BizException {
         // todo 暂时不上客服相关
-        teacherSubmitReq.setCustomerService(null);
+//        teacherSubmitReq.setCustomerService(null);
         if (null == teacherSubmitReq.getUserId()) {
 
             if (StringUtils.isNoneBlank(teacherSubmitReq.getPhone(), teacherSubmitReq.getCode())) {
@@ -540,7 +541,7 @@ public class TeacherServiceImpl extends ServiceImpl<TeacherDao, Teacher> impleme
                     .eq(Student::getTenantId, teacher.getTenantId()).list().stream()
                     .map(Student::getUserId).collect(Collectors.toSet());
 
-            imUserFriendService.saveUserFriend(teacher.getUserId(), collect);
+            imUserFriendService.saveUserFriend(teacher.getUserId(), collect, EImUserFriendSourceForm.TEACHER);
 
         }
 
@@ -630,6 +631,7 @@ public class TeacherServiceImpl extends ServiceImpl<TeacherDao, Teacher> impleme
                 if (customerServiceTeacher != null) {
                     imUserFriendService.registerUserBindCustomerService(teacher.getUserId(),
                             Collections.singletonList(customerServiceTeacher.getUserId()), ClientEnum.TEACHER);
+                    teacher.setCustomerId(customerServiceTeacher.getUserId());
                 }
             }
         } else {
@@ -637,7 +639,7 @@ public class TeacherServiceImpl extends ServiceImpl<TeacherDao, Teacher> impleme
             Boolean customerService = teacher.getCustomerService();
             List<TeacherWrapper.CustomerServiceSendMsg2User> customerServiceSendMsg2User = new ArrayList<>();
             if (Boolean.TRUE.equals(customerService) && Boolean.FALSE.equals(teacherSubmitReq.getCustomerService())) {
-                customerServiceSendMsg2User.addAll(transferFriend(teacher.getUserId(), true));
+                customerServiceSendMsg2User.addAll(transferFriendV2(teacher.getUserId(), true));
             }
             // 如果机构解绑,更新机构ID为-1
             if (Boolean.TRUE.equals(teacherSubmitReq.getBindTenant())) {
@@ -846,7 +848,7 @@ public class TeacherServiceImpl extends ServiceImpl<TeacherDao, Teacher> impleme
         }
 
         teacherFriendMap.forEach((teacherId, teacherIds) -> {
-            imUserFriendService.saveUserTeacherFriend(teacherId, teacherIds);
+            imUserFriendService.saveUserTeacherFriend(teacherId, teacherIds,EImUserFriendSourceForm.CUSTOMER);
             // 发送消息
             TeacherWrapper.CustomerServiceSendMsg2User customerServiceSendMsg2User = new TeacherWrapper.CustomerServiceSendMsg2User();
             customerServiceSendMsg2User.setCustomerId(teacherId);
@@ -855,7 +857,7 @@ public class TeacherServiceImpl extends ServiceImpl<TeacherDao, Teacher> impleme
 //            imUserFriendService.sendCustomerServiceAddFriendMessage(teacherId, customerTitle, customerMessage, new ArrayList<>(teacherIds), ClientEnum.TEACHER);
         });
         studentFriendMap.forEach((teacherId, studentIds) -> {
-            imUserFriendService.saveUserFriend(teacherId, studentIds);
+            imUserFriendService.saveUserFriend(teacherId, studentIds,EImUserFriendSourceForm.CUSTOMER);
             TeacherWrapper.CustomerServiceSendMsg2User customerServiceSendMsg2User = new TeacherWrapper.CustomerServiceSendMsg2User();
             customerServiceSendMsg2User.setCustomerId(teacherId);
             customerServiceSendMsg2User.getTeacherIds().addAll(studentIds);
@@ -865,6 +867,117 @@ public class TeacherServiceImpl extends ServiceImpl<TeacherDao, Teacher> impleme
         return result;
     }
 
+    private List<TeacherWrapper.CustomerServiceSendMsg2User> transferFriendV2(Long userId, boolean saveGroupFriend){
+        List<TeacherWrapper.CustomerServiceSendMsg2User> result = new ArrayList<>();
+        // 所有的好友
+        List<ImUserFriend> userFriendList = imUserFriendService.lambdaQuery()
+                .eq(ImUserFriend::getUserId, userId)
+                .eq(ImUserFriend::getClientType, ClientEnum.TEACHER)
+                .list();
+
+        // 其他客服
+        List<TeacherWrapper.TeacherFriend> customerServiceFriendNums = this.getBaseMapper().getCustomerServiceFriendNums();
+        customerServiceFriendNums.removeIf(n -> n.getTeacherId().equals(userId));
+        List<Long> customerIds = customerServiceFriendNums.stream().map(TeacherWrapper.TeacherFriend::getTeacherId).collect(Collectors.toList());
+        userFriendList.removeIf(n -> customerIds.contains(n.getFriendId()) && ClientEnum.TEACHER.equals(n.getFriendType()));
+        if (userFriendList.isEmpty()) { // 没有好友
+            return result;
+        }
+
+        // 好友保留
+        userFriendList.stream().filter(n -> Boolean.FALSE.equals(saveGroupFriend) || EImUserFriendSourceForm.CUSTOMER.equals(n.getSourceForm()))
+                .collect(Collectors.groupingBy(ImUserFriend::getFriendType)).forEach((client, friends) -> {
+                    List<Long> friendIds = friends.stream().map(ImUserFriend::getFriendId).collect(Collectors.toList());
+                    imUserFriendService.lambdaUpdate()
+                            .eq(ImUserFriend::getUserId, userId)
+                            .eq(ImUserFriend::getClientType, ClientEnum.TEACHER)
+                            .in(ImUserFriend::getFriendId, friendIds)
+                            .eq(ImUserFriend::getFriendType, client)
+                            .remove();
+
+                    imUserFriendService.lambdaUpdate()
+                            .eq(ImUserFriend::getFriendId, userId)
+                            .eq(ImUserFriend::getFriendType, ClientEnum.TEACHER)
+                            .in(ImUserFriend::getUserId, friendIds)
+                            .eq(ImUserFriend::getClientType, client)
+                            .remove();
+                });
+
+        if (customerIds.isEmpty()) {
+            return result;
+        }
+
+        // 好友分配
+        // 存在专属客服的好友不需要分配
+        List<ImUserFriend> teacherFriends = userFriendList.stream().filter(n -> ClientEnum.TEACHER.equals(n.getFriendType())).collect(Collectors.toList());
+        if (!teacherFriends.isEmpty()) {
+            String teacherFriendIds = teacherFriends.stream().map(n -> n.getFriendId().toString()).distinct().collect(Collectors.joining(","));
+            List<Long> existFriendIds = this.lambdaQuery()
+                    .in(Teacher::getUserId, teacherFriendIds)
+                    .list()
+                    .stream()
+                    .filter(n -> customerIds.contains(n.getCustomerId()))
+                    .map(Teacher::getUserId)
+                    .collect(Collectors.toList());
+            userFriendList.removeIf(n -> ClientEnum.TEACHER.equals(n.getFriendType()) && existFriendIds.contains(n.getFriendId()));
+        }
+
+        List<ImUserFriend> studentFriends = userFriendList.stream().filter(n -> ClientEnum.STUDENT.equals(n.getFriendType())).collect(Collectors.toList());
+        if (!studentFriends.isEmpty()) {
+            String studentFriendIds = studentFriends.stream().map(n -> n.getFriendId().toString()).distinct().collect(Collectors.joining(","));
+            List<Long> existFriendIds = studentService.lambdaQuery()
+                    .in(Student::getUserId, studentFriendIds)
+                    .list()
+                    .stream()
+                    .filter(n -> customerIds.contains(n.getCustomerId()))
+                    .map(Student::getUserId)
+                    .collect(Collectors.toList());
+            userFriendList.removeIf(n -> ClientEnum.STUDENT.equals(n.getFriendType()) && existFriendIds.contains(n.getFriendId()));
+        }
+
+        if (userFriendList.isEmpty()) {
+            return result;
+        }
+
+        // 好友交接
+        Map<Long, Set<Long>> teacherFriendMap = new LinkedHashMap<>();
+        Map<Long, Set<Long>> studentFriendMap = new LinkedHashMap<>();
+        for (ImUserFriend imUserFriend : userFriendList) {
+            TeacherWrapper.TeacherFriend teacherFriend = customerServiceFriendNums.get(0);
+            if (ClientEnum.TEACHER.equals(imUserFriend.getFriendType())) {
+                Set<Long> set = teacherFriendMap.getOrDefault(teacherFriend.getTeacherId(), new HashSet<>());
+                set.add(imUserFriend.getFriendId());
+                teacherFriendMap.put(teacherFriend.getTeacherId(), set);
+            } else if (ClientEnum.STUDENT.equals(imUserFriend.getFriendType())) {
+                Set<Long> set = studentFriendMap.getOrDefault(teacherFriend.getTeacherId(), new HashSet<>());
+                set.add(imUserFriend.getFriendId());
+                studentFriendMap.put(teacherFriend.getTeacherId(), set);
+            }
+            teacherFriend.setFriendNums(teacherFriend.getFriendNums() + 1);
+            Collections.sort(customerServiceFriendNums);
+        }
+
+        teacherFriendMap.forEach((teacherId, teacherIds) -> {
+            imUserFriendService.saveUserTeacherFriend(teacherId, teacherIds,EImUserFriendSourceForm.CUSTOMER);
+            this.lambdaUpdate().set(Teacher::getCustomerId,teacherId).in(Teacher::getUserId,teacherIds).update();
+            // 发送消息
+            TeacherWrapper.CustomerServiceSendMsg2User customerServiceSendMsg2User = new TeacherWrapper.CustomerServiceSendMsg2User();
+            customerServiceSendMsg2User.setCustomerId(teacherId);
+            customerServiceSendMsg2User.getTeacherIds().addAll(teacherIds);
+            result.add(customerServiceSendMsg2User);
+//            imUserFriendService.sendCustomerServiceAddFriendMessage(teacherId, customerTitle, customerMessage, new ArrayList<>(teacherIds), ClientEnum.TEACHER);
+        });
+        studentFriendMap.forEach((teacherId, studentIds) -> {
+            imUserFriendService.saveUserFriend(teacherId, studentIds, EImUserFriendSourceForm.CUSTOMER);
+            studentService.lambdaUpdate().set(Student::getCustomerId, teacherId).in(Student::getUserId, studentIds).update();
+            TeacherWrapper.CustomerServiceSendMsg2User customerServiceSendMsg2User = new TeacherWrapper.CustomerServiceSendMsg2User();
+            customerServiceSendMsg2User.setCustomerId(teacherId);
+            customerServiceSendMsg2User.getTeacherIds().addAll(studentIds);
+            result.add(customerServiceSendMsg2User);
+//            imUserFriendService.sendCustomerServiceAddFriendMessage(teacherId, customerTitle, customerMessage, new ArrayList<>(studentIds), ClientEnum.STUDENT);
+        });
+        return result;
+    }
     /***
      * 封装用户信息
      * @author liweifan
@@ -1363,7 +1476,7 @@ public class TeacherServiceImpl extends ServiceImpl<TeacherDao, Teacher> impleme
                     .collect(Collectors.toSet());
 
             if (!collect.isEmpty()) {
-                imUserFriendService.saveUserFriend(teacher.getUserId(), collect);
+                imUserFriendService.saveUserFriend(teacher.getUserId(), collect,EImUserFriendSourceForm.TEACHER);
             }
             addBindUnBindRecord(teacher.getUserId(),updateTenant.getTenantId(),true);
             SysUser sysUser = sysUserMapper.getByUserId(teacher.getUserId());
@@ -1512,15 +1625,13 @@ public class TeacherServiceImpl extends ServiceImpl<TeacherDao, Teacher> impleme
             throw new BizException("无效的老师账号");
         }
 
-        // todo 暂时不上,逻辑调整
         // 冻结客服,移交好友给其他客服
-//        Boolean customerService = teacher.getCustomerService();
-        Boolean customerService = null;
+        Boolean customerService = teacher.getCustomerService();
         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);
-            String customerTitle = sysConfigService.findConfigValue(SysConfigConstant.CUSTOMER_SERVICE_ADD_MSG_TITLE);
+            List<TeacherWrapper.CustomerServiceSendMsg2User> customerServiceSendMsg2User = transferFriendV2(teacherId, false);
             for (TeacherWrapper.CustomerServiceSendMsg2User serviceSendMsg2User : customerServiceSendMsg2User) {
+                String customerMessage = sysConfigService.findConfigValue(SysConfigConstant.CUSTOMER_SERVICE_ADD_MSG);
+                String customerTitle = sysConfigService.findConfigValue(SysConfigConstant.CUSTOMER_SERVICE_ADD_MSG_TITLE);
                 imUserFriendService.sendCustomerServiceAddFriendMessage(serviceSendMsg2User.getCustomerId(), customerTitle, customerMessage, serviceSendMsg2User.getTeacherIds(),
                         ClientEnum.TEACHER);
                 imUserFriendService.sendCustomerServiceAddFriendMessage(serviceSendMsg2User.getCustomerId(), customerTitle, customerMessage, serviceSendMsg2User.getStudentIds(),

+ 4 - 2
cooleshow-user/user-biz/src/main/resources/config/mybatis/ImUserFriendMapper.xml

@@ -8,6 +8,7 @@
         <result column="friend_nickname_" jdbcType="VARCHAR" property="friendNickname"/>
         <result column="friend_avatar_" jdbcType="VARCHAR" property="friendAvatar"/>
         <result column="memo_" jdbcType="VARCHAR" property="memo"/>
+        <result column="source_form_" jdbcType="VARCHAR" property="sourceForm"/>
         <result column="create_time_" jdbcType="TIMESTAMP" property="createTime"/>
         <result column="update_time_" jdbcType="TIMESTAMP" property="updateTime"/>
     </resultMap>
@@ -18,9 +19,10 @@
 
     <insert id="insertBatch" keyColumn="id_" keyProperty="id" useGeneratedKeys="true"
             parameterType="com.yonge.cooleshow.biz.dal.entity.ImUserFriend">
-        INSERT INTO im_user_friend(user_id_, client_type_, friend_id_, friend_type_, friend_nickname_,friend_avatar_, memo_, create_time_, update_time_) VALUES
+        INSERT INTO im_user_friend(user_id_, client_type_, friend_id_, friend_type_, friend_nickname_,friend_avatar_, memo_, source_form_, create_time_, update_time_) VALUES
         <foreach collection="entities" item="entity" separator=",">
-            (#{entity.userId}, #{entity.clientType}, #{entity.friendId}, #{entity.friendType}, #{entity.friendNickname}, #{entity.friendAvatar}, #{entity.memo}, #{entity.createTime}, #{entity.updateTime})
+            (#{entity.userId}, #{entity.clientType}, #{entity.friendId}, #{entity.friendType}, #{entity.friendNickname}, #{entity.friendAvatar}, #{entity.memo},
+            #{entity.sourceForm},#{entity.createTime}, #{entity.updateTime})
         </foreach>
         ON DUPLICATE KEY UPDATE user_id_ = VALUES(user_id_), client_type_ = VALUES(client_type_), friend_id_ = VALUES(friend_id_), friend_type_ = VALUES(friend_type_)
     </insert>

+ 2 - 0
cooleshow-user/user-biz/src/main/resources/config/mybatis/StudentMapper.xml

@@ -16,6 +16,7 @@
         <result column="avatar_" property="avatar"/>
         <result column="tenant_group_id_" property="tenantGroupId"/>
         <result column="im_device_id_" property="imDeviceId"/>
+        <result column="customer_id_" property="customerId"/>
     </resultMap>
 
     <!-- 表字段 -->
@@ -35,6 +36,7 @@
         , t.update_time_ as `updateTime`
         , t.tenant_group_id_ as `tenantGroupId`
         , t.im_device_id_ as imDeviceId
+        , t.customer_id_ as customerId
         </sql>
     <update id="setSubject">
         update student set subject_id_ = #{subjectIds},update_time_ = now() where user_id_ = #{id}

+ 2 - 0
cooleshow-user/user-biz/src/main/resources/config/mybatis/TeacherMapper.xml

@@ -41,6 +41,7 @@
         <result column="update_time_" property="updateTime"/>
         <result column="im_device_id_" property="imDeviceId"/>
         <result column="customer_service_" property="customerService"/>
+        <result column="customer_id_" property="customerId"/>
     </resultMap>
 
     <resultMap id="HotTeacherVoMap" type="com.yonge.cooleshow.biz.dal.vo.HotTeacherVo">
@@ -93,6 +94,7 @@
         , t.settlement_from_ as settlementFrom
         , t.im_device_id_ as imDeviceId
         , t.customer_service_ as customerService
+        , t.customer_id_ as customerId
     </sql>
 
     <!-- 分页查询 -->