浏览代码

Merge branch 'online' of http://git.dayaedu.com/yonge/cooleshow into zx_online_cbs

# Conflicts:
#	cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/CbsMusicSheetServiceImpl.java
#	cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/TenantAlbumMusicServiceImpl.java
zouxuan 10 月之前
父节点
当前提交
e4cc818141
共有 55 个文件被更改,包括 1316 次插入242 次删除
  1. 11 0
      cooleshow-api/src/main/java/com/yonge/cooleshow/api/feign/AdminFeignService.java
  2. 13 0
      cooleshow-api/src/main/java/com/yonge/cooleshow/api/feign/fallback/AdminFeignServiceFallback.java
  3. 36 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/EmployeeController.java
  4. 5 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/TeacherController.java
  5. 0 4
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/open/ImController.java
  6. 12 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/StudentController.java
  7. 14 2
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/TenantAlbumSheetController.java
  8. 12 3
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/TeacherController.java
  9. 3 2
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/TenantAlbumSheetController.java
  10. 12 3
      cooleshow-app/src/main/java/com/yonge/cooleshow/tenant/controller/StudentController.java
  11. 3 2
      cooleshow-app/src/main/java/com/yonge/cooleshow/tenant/controller/TenantAlbumSheetController.java
  12. 12 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/website/controller/StudentController.java
  13. 19 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/website/controller/TeacherController.java
  14. 11 13
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/service/impl/SysUserServiceImpl.java
  15. 5 0
      cooleshow-common/src/main/java/com/yonge/cooleshow/common/constant/SysConfigConstant.java
  16. 12 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/TeacherDao.java
  17. 14 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/EmployeeDto.java
  18. 11 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/search/EmployeeSearch.java
  19. 8 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/search/TeacherSearch.java
  20. 9 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/CustomerServiceBatchSending.java
  21. 12 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/Employee.java
  22. 20 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/Student.java
  23. 28 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/Teacher.java
  24. 4 3
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/ClientEnum.java
  25. 1 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/im/EImSendStatus.java
  26. 7 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/EmployeeService.java
  27. 0 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/ImUserFriendService.java
  28. 6 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/StudentService.java
  29. 20 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/TeacherService.java
  30. 4 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/TenantAlbumMusicService.java
  31. 6 2
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/im/ImGroupCoreService.java
  32. 55 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/im/impl/ImGroupCoreServiceImpl.java
  33. 41 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/CbsMusicSheetServiceImpl.java
  34. 1 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/CourseScheduleServiceImpl.java
  35. 221 104
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/CustomerServiceBatchSendingServiceImpl.java
  36. 79 12
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/EmployeeServiceImpl.java
  37. 15 38
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/ImGroupServiceImpl.java
  38. 15 3
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/ImUserFriendServiceImpl.java
  39. 1 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/PaymentDivMemberRecordServiceImpl.java
  40. 58 7
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/StudentServiceImpl.java
  41. 113 25
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/TeacherServiceImpl.java
  42. 142 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/TenantAlbumMusicServiceImpl.java
  43. 22 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/vo/EmployeeVo.java
  44. 11 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/vo/StudentHomeVo.java
  45. 11 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/vo/StudentVo.java
  46. 10 3
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/vo/TeacherHomeVo.java
  47. 11 3
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/vo/TeacherVo.java
  48. 120 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/LessonCoursewareDetailWrapper.java
  49. 3 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/im/CustomerService.java
  50. 1 0
      cooleshow-user/user-biz/src/main/resources/config/mybatis/CourseGroupMapper.xml
  51. 11 1
      cooleshow-user/user-biz/src/main/resources/config/mybatis/CustomerServiceBatchSendingMapper.xml
  52. 10 2
      cooleshow-user/user-biz/src/main/resources/config/mybatis/EmployeeMapper.xml
  53. 6 6
      cooleshow-user/user-biz/src/main/resources/config/mybatis/MusicSheetAuthRecordMapper.xml
  54. 1 0
      cooleshow-user/user-biz/src/main/resources/config/mybatis/StudentMapper.xml
  55. 28 0
      cooleshow-user/user-biz/src/main/resources/config/mybatis/TeacherMapper.xml

+ 11 - 0
cooleshow-api/src/main/java/com/yonge/cooleshow/api/feign/AdminFeignService.java

@@ -217,4 +217,15 @@ public interface AdminFeignService {
 
     @PostMapping("/sysUser/logoffQuitImGroup")
     HttpResponseResult<Boolean> logoffQuitImGroup(@RequestParam(value = "phone") String phone);
+
+    /**
+     * 清除客服绑定关系
+     * @param userId 用户ID
+     * @param sysUserType 用户类型
+     *
+     * @return HttpResponseResult<Boolean>
+     */
+    @GetMapping("/employee/clearCustomerService")
+    HttpResponseResult<Boolean> clearCustomerService(@RequestParam(value = "userId") Long userId,
+                                                     @RequestParam("sysUserType") String sysUserType);
 }

+ 13 - 0
cooleshow-api/src/main/java/com/yonge/cooleshow/api/feign/fallback/AdminFeignServiceFallback.java

@@ -215,4 +215,17 @@ public class AdminFeignServiceFallback implements AdminFeignService {
     public HttpResponseResult<Boolean> logoffQuitImGroup(String phone) {
         return null;
     }
+
+    /**
+     * 清除客服绑定关系
+     *
+     * @param userId      用户ID
+     * @param sysUserType 用户类型
+     *
+     * @return HttpResponseResult<Boolean>
+     */
+    @Override
+    public HttpResponseResult<Boolean> clearCustomerService(Long userId, String sysUserType) {
+        return null;
+    }
 }

+ 36 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/EmployeeController.java

@@ -1,15 +1,19 @@
 package com.yonge.cooleshow.admin.controller;
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.microsvc.toolkit.common.webportal.exception.BizException;
 import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
 import com.yonge.cooleshow.auth.api.entity.SysUser;
 import com.yonge.cooleshow.biz.dal.dao.EmployeeDao;
 import com.yonge.cooleshow.biz.dal.dto.EmployeeDto;
 import com.yonge.cooleshow.biz.dal.dto.search.EmployeeSearch;
 import com.yonge.cooleshow.biz.dal.entity.Employee;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
 import com.yonge.cooleshow.biz.dal.enums.GenderEnum;
 import com.yonge.cooleshow.biz.dal.service.EmployeeService;
+import com.yonge.cooleshow.biz.dal.service.im.ImGroupCoreService;
 import com.yonge.cooleshow.biz.dal.vo.EmployeeVo;
+import com.yonge.cooleshow.biz.dal.wrapper.im.ImGroupWrapper;
 import com.yonge.cooleshow.common.controller.BaseController;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import com.yonge.cooleshow.common.enums.UserLockFlag;
@@ -30,11 +34,13 @@ import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 
 import javax.validation.Valid;
 import java.util.Date;
 import java.util.List;
+import java.util.Objects;
 
 @RequestMapping("${app-config.url.admin:}/employee")
 @Api(tags = "员工管理")
@@ -47,6 +53,9 @@ public class EmployeeController extends BaseController {
     @Autowired
     private EmployeeDao employeeDao;
 
+    @Autowired
+    private ImGroupCoreService imGroupCoreService;
+
     @GetMapping("/detail/{id}")
     @ApiOperation(value = "详情", notes = "传入student")
     @ApiImplicitParams({
@@ -128,6 +137,26 @@ public class EmployeeController extends BaseController {
             employeeVo.setRoleIds(employeeDao.queryUserRole(sysUser.getId()));
             employeeVo.setSysUser(sysUser);
 
+            try {
+                ImGroupWrapper.ImUserInfo register = imGroupCoreService.register(
+                    employeeVo.getUserId().toString(),
+                    ClientEnum.SYSTEM.getCode(),
+                    employeeVo.getUsername(),
+                    employeeVo.getAvatar()
+                );
+
+                // 设置客服标记
+                if (Objects.isNull(employeeVo.getCustomerService())) {
+                    employeeVo.setCustomerService(false);
+                }
+                // 获取IMToken
+                employeeVo.setImToken(register.getImToken());
+                // 获取IM用户ID
+                employeeVo.setImUserId(imGroupCoreService.getImUserId(employeeVo.getUserId().toString(), ClientEnum.SYSTEM.getCode()));
+            } catch (Exception e) {
+                throw new BizException("获取IMToken失败");
+            }
+
             BeanUtils.copyProperties(sysUser, employeeVo, "gender");
             employeeVo.setGender(GenderEnum.valueOf(sysUser.getGender()));
             return succeed(employeeVo);
@@ -135,4 +164,11 @@ public class EmployeeController extends BaseController {
         return failed("获取用户信息失败");
     }
 
+    @ApiOperation(value = "员工客服绑定关系清除")
+    @GetMapping("/clearCustomerService")
+    public HttpResponseResult<Boolean> clearCustomerService(@RequestParam("userId") Long userId,
+                                                            @RequestParam("sysUserType") String sysUserType) {
+        // 清除客服绑定关系
+        return succeed(employeeService.clearCustomerService(userId, sysUserType));
+    }
 }

+ 5 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/TeacherController.java

@@ -60,6 +60,7 @@ import javax.servlet.http.HttpServletResponse;
 import javax.validation.Valid;
 import java.io.IOException;
 import java.io.OutputStream;
+import java.util.Arrays;
 import java.util.Date;
 import java.util.List;
 import java.util.Optional;
@@ -116,6 +117,10 @@ public class TeacherController extends BaseController {
     @ApiOperation(value = "查询分页", notes = "传入teacher")
     @PreAuthorize("@pcs.hasPermissions('teacher/page')")
     public HttpResponseResult<PageInfo<TeacherVo>> page(@RequestBody TeacherSearch query) {
+
+        if (StringUtils.isNotBlank(query.getSubjectIdList())) {
+            query.setSubjectIds(Arrays.stream(query.getSubjectIdList().split(",")).map(Long::parseLong).collect(Collectors.toList()));
+        }
     	
     	if(StringUtils.isNotBlank(query.getUserStatus())){
     		switch (query.getUserStatus()) {

+ 0 - 4
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/open/ImController.java

@@ -2,7 +2,6 @@ package com.yonge.cooleshow.admin.controller.open;
 
 import com.alibaba.fastjson.JSON;
 import com.google.common.collect.Lists;
-import com.microsvc.toolkit.middleware.im.properties.ImConfigProperties;
 import com.microsvc.toolkit.middleware.live.LivePluginContext;
 import com.microsvc.toolkit.middleware.live.LivePluginService;
 import com.microsvc.toolkit.middleware.live.impl.TencentCloudLivePlugin;
@@ -71,9 +70,6 @@ public class ImController extends BaseController {
     @Autowired
     private ImGroupService imGroupService;
 
-    @Autowired
-    private ImConfigProperties imConfig;
-
 
     @ApiOperation("新用户添加客服")
     @PostMapping(value = "/im/customerService")

+ 12 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/StudentController.java

@@ -103,6 +103,18 @@ public class StudentController extends BaseController {
         return succeed(studentService.queryUserInfo(user));
     }
 
+    @ApiOperation(value = "设置系统默认客服")
+    @GetMapping("/updateUserCustomerService")
+    public HttpResponseResult<String> updateUserCustomerService() {
+
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+
+        return succeed(studentService.updateUserCustomerService(user));
+    }
+
     @ApiOperation(value = "设置声部")
     @GetMapping("/setSubject")
     public HttpResponseResult setSubject(@ApiParam(value = "声部主键集合", required = true) @RequestParam("subjectIds") String subjectIds) {

+ 14 - 2
cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/TenantAlbumSheetController.java

@@ -2,16 +2,21 @@ package com.yonge.cooleshow.student.controller;
 
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.dayaedu.cbs.common.enums.school.EKnowledgeType;
 import com.dayaedu.cbs.openfeign.client.CoursewareFeignService;
 import com.dayaedu.cbs.openfeign.wrapper.courseware.CbsLessonCoursewareDetailWrapper;
 import com.dayaedu.cbs.openfeign.wrapper.courseware.CbsLessonCoursewareWrapper;
+import com.dayaedu.cbs.openfeign.wrapper.courseware.CbsMaterialRefWrapper;
 import com.microsvc.toolkit.common.response.paging.QueryInfo;
 import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
 import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.entity.MusicSheet;
 import com.yonge.cooleshow.biz.dal.entity.Student;
 import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.service.MusicSheetService;
 import com.yonge.cooleshow.biz.dal.service.StudentService;
 import com.yonge.cooleshow.biz.dal.service.TenantAlbumMusicService;
+import com.yonge.cooleshow.biz.dal.wrapper.LessonCoursewareDetailWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.LessonCoursewareWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.TenantAlbumMusicWrapper;
 import com.yonge.cooleshow.common.controller.BaseController;
@@ -31,6 +36,8 @@ import org.springframework.web.bind.annotation.*;
 import javax.validation.Valid;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
 
 /**
  * 专辑表 web 控制层
@@ -55,6 +62,9 @@ public class TenantAlbumSheetController extends BaseController {
     @Autowired
     private CoursewareFeignService coursewareFeignService;
 
+    @Autowired
+    private MusicSheetService musicSheetService;
+
     @ApiOperation(value = "查询条件")
     @PostMapping("/selectCondition")
     public HttpResponseResult<TenantAlbumMusicWrapper.TenantAlbumMusicSelectData> selectCondition(@RequestBody TenantAlbumMusicWrapper.TenantAlbumMusicSelect query) {
@@ -128,8 +138,10 @@ public class TenantAlbumSheetController extends BaseController {
 
     @ApiOperation(value = "获取课程详情")
     @GetMapping("/getLessonCourseDetail/{id}")
-    public HttpResponseResult<CbsLessonCoursewareDetailWrapper.LessonCoursewareDetail> getLessonCourseDetail(@PathVariable("id") String id){
-        return succeed(coursewareFeignService.lessonCoursewareDetailDetail(Long.parseLong(id)).feignData());
+    public HttpResponseResult<LessonCoursewareDetailWrapper.LessonCoursewareDetail> getLessonCourseDetail(@PathVariable("id") String id) {
+
+        return succeed(tenantAlbumMusicService.getLessonCourseDetail(id));
+
     }
 
 }

+ 12 - 3
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/TeacherController.java

@@ -32,14 +32,11 @@ import com.yonge.toolset.base.util.StringUtil;
 import com.yonge.toolset.mybatis.support.PageUtil;
 import com.yonge.toolset.utils.idcard.IdcardInfoExtractor;
 import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiImplicitParam;
-import io.swagger.annotations.ApiImplicitParams;
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiParam;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.HttpStatus;
-import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.util.CollectionUtils;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.GetMapping;
@@ -90,6 +87,18 @@ public class TeacherController extends BaseController {
         return teacherService.queryUserInfo(user.getId());
     }
 
+    @ApiOperation(value = "设置系统默认客服")
+    @GetMapping("/updateUserCustomerService")
+    public HttpResponseResult<String> updateUserCustomerService() {
+
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+
+        return succeed(teacherService.updateUserCustomerService(user.getId()));
+    }
+
 
     /**
      * 查询单条

+ 3 - 2
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/TenantAlbumSheetController.java

@@ -12,6 +12,7 @@ import com.yonge.cooleshow.biz.dal.entity.Teacher;
 import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
 import com.yonge.cooleshow.biz.dal.service.TeacherService;
 import com.yonge.cooleshow.biz.dal.service.TenantAlbumMusicService;
+import com.yonge.cooleshow.biz.dal.wrapper.LessonCoursewareDetailWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.LessonCoursewareWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.TenantAlbumMusicWrapper;
 import com.yonge.cooleshow.common.controller.BaseController;
@@ -100,8 +101,8 @@ public class TenantAlbumSheetController extends BaseController {
 
     @ApiOperation(value = "获取课程详情")
     @GetMapping("/getLessonCourseDetail/{id}")
-    public HttpResponseResult<CbsLessonCoursewareDetailWrapper.LessonCoursewareDetail> getLessonCourseDetail(@PathVariable("id") String id){
-        return succeed(coursewareFeignService.lessonCoursewareDetailDetail(Long.parseLong(id)).feignData());
+    public HttpResponseResult<LessonCoursewareDetailWrapper.LessonCoursewareDetail> getLessonCourseDetail(@PathVariable("id") String id){
+        return succeed(tenantAlbumMusicService.getLessonCourseDetail(id));
     }
 
 }

+ 12 - 3
cooleshow-app/src/main/java/com/yonge/cooleshow/tenant/controller/StudentController.java

@@ -12,10 +12,8 @@ import com.yonge.cooleshow.biz.dal.entity.TenantGroup;
 import com.yonge.cooleshow.biz.dal.entity.TenantGroupAlbum;
 import com.yonge.cooleshow.biz.dal.entity.TenantInfo;
 import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
-import com.yonge.cooleshow.biz.dal.service.ImUserFriendService;
 import com.yonge.cooleshow.biz.dal.service.OssFileService;
 import com.yonge.cooleshow.biz.dal.service.StudentService;
-import com.yonge.cooleshow.biz.dal.service.TeacherService;
 import com.yonge.cooleshow.biz.dal.service.TenantActivationCodeService;
 import com.yonge.cooleshow.biz.dal.service.TenantAlbumPurchaseService;
 import com.yonge.cooleshow.biz.dal.service.TenantGroupAlbumService;
@@ -57,7 +55,6 @@ import org.springframework.web.multipart.MultipartFile;
 import javax.annotation.Resource;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
@@ -307,4 +304,16 @@ public class StudentController extends BaseController {
         }
         return succeed(studentService.queryUserInfo(user));
     }
+
+    @ApiOperation(value = "设置系统默认客服")
+    @GetMapping("/updateUserCustomerService")
+    public HttpResponseResult<String> updateUserCustomerService() {
+
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+
+        return succeed(studentService.updateUserCustomerService(user));
+    }
 }

+ 3 - 2
cooleshow-app/src/main/java/com/yonge/cooleshow/tenant/controller/TenantAlbumSheetController.java

@@ -10,6 +10,7 @@ import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
 import com.yonge.cooleshow.auth.api.entity.SysUser;
 import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
 import com.yonge.cooleshow.biz.dal.service.TenantAlbumMusicService;
+import com.yonge.cooleshow.biz.dal.wrapper.LessonCoursewareDetailWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.LessonCoursewareWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.TenantAlbumMusicWrapper;
 import com.yonge.cooleshow.common.controller.BaseController;
@@ -108,8 +109,8 @@ public class TenantAlbumSheetController extends BaseController {
 
     @ApiOperation(value = "获取课程详情")
     @GetMapping("/getLessonCourseDetail/{id}")
-    public HttpResponseResult<CbsLessonCoursewareDetailWrapper.LessonCoursewareDetail> getLessonCourseDetail(@PathVariable("id") String id){
-        return succeed(coursewareFeignService.lessonCoursewareDetailDetail(Long.parseLong(id)).feignData());
+    public HttpResponseResult<LessonCoursewareDetailWrapper.LessonCoursewareDetail> getLessonCourseDetail(@PathVariable("id") String id){
+        return succeed(tenantAlbumMusicService.getLessonCourseDetail(id));
     }
 
 

+ 12 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/website/controller/StudentController.java

@@ -65,6 +65,18 @@ public class StudentController extends BaseController {
         return succeed(studentService.queryUserInfo(user));
     }
 
+    @ApiOperation(value = "设置系统默认客服")
+    @GetMapping("/updateUserCustomerService")
+    public HttpResponseResult<String> updateUserCustomerService() {
+
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+
+        return succeed(studentService.updateUserCustomerService(user));
+    }
+
     @ApiOperation(value = "设置声部")
     @GetMapping("/setSubject")
     public HttpResponseResult setSubject(@ApiParam(value = "声部主键集合", required = true) @RequestParam("subjectIds") String subjectIds) {

+ 19 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/website/controller/TeacherController.java

@@ -1,6 +1,8 @@
 package com.yonge.cooleshow.website.controller;
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
 import com.yonge.cooleshow.biz.dal.dto.TeacherDto;
 import com.yonge.cooleshow.biz.dal.entity.Subject;
 import com.yonge.cooleshow.biz.dal.service.StudentStarService;
@@ -20,6 +22,8 @@ import com.yonge.toolset.mybatis.support.PageUtil;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiParam;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
 import org.springframework.web.bind.annotation.*;
 
 import javax.annotation.Resource;
@@ -38,12 +42,27 @@ public class TeacherController extends BaseController {
     @Resource
     private SysUserService sysUserService;
 
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
     @ApiOperation(value = "我的-查询教师基本信息")
     @GetMapping("/queryUserInfo")
     public HttpResponseResult<TeacherHomeVo> queryUserInfo() {
         return teacherService.queryUserInfo(sysUserService.getUserId());
     }
 
+    @ApiOperation(value = "设置系统默认客服")
+    @GetMapping("/updateUserCustomerService")
+    public HttpResponseResult<String> updateUserCustomerService() {
+
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+
+        return succeed(teacherService.updateUserCustomerService(user.getId()));
+    }
+
     @ApiOperation(value = "开通直播")
     @GetMapping("/openLive")
     public HttpResponseResult<Boolean> openLive() {

+ 11 - 13
cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/service/impl/SysUserServiceImpl.java

@@ -1,10 +1,6 @@
 package com.yonge.cooleshow.auth.service.impl;
 
-import com.alibaba.fastjson.JSON;
-import com.google.common.collect.Lists;
 import com.yonge.cooleshow.api.feign.AdminFeignService;
-import com.yonge.cooleshow.api.feign.TeacherFeignService;
-import com.yonge.cooleshow.api.feign.dto.UserFriendInfoVO;
 import com.yonge.cooleshow.auth.api.dto.QRLoginDto;
 import com.yonge.cooleshow.auth.api.dto.RealnameAuthReq;
 import com.yonge.cooleshow.auth.api.dto.SysUserInfo;
@@ -12,7 +8,6 @@ import com.yonge.cooleshow.auth.api.dto.SysUserQueryInfo;
 import com.yonge.cooleshow.auth.api.dto.UserSetReq;
 import com.yonge.cooleshow.auth.api.entity.SysUser;
 import com.yonge.cooleshow.auth.api.vo.UserSetVo;
-import com.yonge.cooleshow.auth.config.CustomerServiceConfig;
 import com.yonge.cooleshow.auth.config.RongCloudConfig;
 import com.yonge.cooleshow.auth.core.service.CustomTokenServices;
 import com.yonge.cooleshow.auth.dal.dao.SysUserDao;
@@ -27,8 +22,8 @@ import com.yonge.cooleshow.common.entity.ImUserModel;
 import com.yonge.cooleshow.common.enums.CacheNameEnum;
 import com.yonge.cooleshow.common.enums.SysUserType;
 import com.yonge.cooleshow.common.enums.UserFirstTimeTypeEnum;
+import com.yonge.cooleshow.common.enums.YesOrNoEnum;
 import com.yonge.toolset.base.exception.BizException;
-import com.yonge.toolset.base.util.ThreadPool;
 import com.yonge.toolset.mybatis.dal.BaseDAO;
 import com.yonge.toolset.mybatis.service.impl.BaseServiceImpl;
 import io.rong.models.response.TokenResult;
@@ -44,12 +39,9 @@ import org.springframework.util.CollectionUtils;
 
 import javax.annotation.Resource;
 import java.text.MessageFormat;
-import java.util.Arrays;
 import java.util.List;
 import java.util.Objects;
 import java.util.Optional;
-import java.util.Random;
-import java.util.stream.Collectors;
 
 @Slf4j
 @Service
@@ -68,8 +60,7 @@ public class SysUserServiceImpl extends BaseServiceImpl<Long, SysUser> implement
     private RedissonClient redissonClient;
     @Resource
     private AdminFeignService adminFeignService;
-    @Autowired
-    private CustomerServiceConfig customerServiceConfig;
+
     @Resource
     private CustomTokenServices tokenService;
 
@@ -215,7 +206,7 @@ public class SysUserServiceImpl extends BaseServiceImpl<Long, SysUser> implement
      */
     public void sendSysCustomerServiceFriendMessage(SysUser sysUser, String clientType) {
 
-        try {
+        /*try {
 
             ThreadPool.getExecutor().submit(() -> {
 
@@ -234,7 +225,7 @@ public class SysUserServiceImpl extends BaseServiceImpl<Long, SysUser> implement
 
         } catch (Exception e) {
             log.error("sendSysCustomerServiceFriendMessage userId={}", sysUser.getId(), e);
-        }
+        }*/
 
     }
 
@@ -359,9 +350,16 @@ public class SysUserServiceImpl extends BaseServiceImpl<Long, SysUser> implement
         sysUserDao.logoffById(id, maxVersion);
     }
 
+    @Transactional(rollbackFor = Exception.class)
     @Override
     public void updateLockStatus(Long userId, Integer lockFlag, String sysUserType) {
         sysUserDao.updateLockStatus(userId, lockFlag, sysUserType);
+
+        // 系统员工锁定,清除客服绑定关系
+        if (lockFlag == YesOrNoEnum.YES.getCode().intValue() && SysUserType.SYSTEM.getCode().equals(sysUserType)) {
+            // 清除客服绑定关系
+            adminFeignService.clearCustomerService(userId, sysUserType);
+        }
     }
 
     /**

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

@@ -450,4 +450,9 @@ public interface SysConfigConstant {
      * 消息发送频率限制
      */
     String MESSAGE_SEND_LIMIT = "message_send_limit";
+
+    /**
+     * 默认曲目所属人
+     */
+    String DEFAULT_MUSIC_USER_ID = "default_music_user_id";
 }

+ 12 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/TeacherDao.java

@@ -120,4 +120,16 @@ public interface TeacherDao extends BaseMapper<Teacher> {
     Teacher getCustomerServiceByFriendLeast();
 
     List<TeacherWrapper.TeacherFriend> getCustomerServiceFriendNums();
+
+    /**
+     * 查询系统客服列表
+     * @return List<Teacher>
+     */
+    List<Teacher> selectCustomerServiceV2();
+
+    /**
+     * 客服好友数量统计
+     * @return List<StatGroupWrapper>
+     */
+    List<StatGroupWrapper> countCustomerServiceMemberNum();
 }

+ 14 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/EmployeeDto.java

@@ -1,5 +1,6 @@
 package com.yonge.cooleshow.biz.dal.dto;
 
+import com.baomidou.mybatisplus.annotation.TableField;
 import com.fasterxml.jackson.annotation.JsonFormat;
 import com.yonge.cooleshow.biz.dal.entity.Employee;
 import com.yonge.cooleshow.biz.dal.enums.GenderEnum;
@@ -38,6 +39,10 @@ public class EmployeeDto extends Employee{
     @ApiModelProperty(value = "角色id列表")
     private List<Long> roleIds;
 
+    @ApiModelProperty("是否是客服")
+    @TableField(value = "customer_service_")
+    private Boolean customerService;
+
     public String getUsername() {
         return username;
     }
@@ -86,4 +91,13 @@ public class EmployeeDto extends Employee{
         this.entryDate = entryDate;
     }
 
+    @Override
+    public Boolean getCustomerService() {
+        return customerService;
+    }
+
+    @Override
+    public void setCustomerService(Boolean customerService) {
+        this.customerService = customerService;
+    }
 }

+ 11 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/search/EmployeeSearch.java

@@ -42,6 +42,9 @@ public class EmployeeSearch extends QueryInfo{
     @ApiModelProperty("用户状态")
     private String userStatus;
 
+    @ApiModelProperty("是否客服")
+    private Boolean customerService;
+
     public String getSearch() {
         return search;
     }
@@ -111,4 +114,12 @@ public class EmployeeSearch extends QueryInfo{
 	public void setUserStatus(String userStatus) {
 		this.userStatus = userStatus;
 	}
+
+    public Boolean getCustomerService() {
+        return customerService;
+    }
+
+    public void setCustomerService(Boolean customerService) {
+        this.customerService = customerService;
+    }
 }

+ 8 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/search/TeacherSearch.java

@@ -12,6 +12,7 @@ import lombok.Data;
 import org.springframework.format.annotation.DateTimeFormat;
 
 import java.util.Date;
+import java.util.List;
 
 /**
  * @Author: liweifan
@@ -41,6 +42,13 @@ public class TeacherSearch extends QueryInfo{
     
     @ApiModelProperty("声部编号")
     private Long subjectId;
+
+
+    @ApiModelProperty("声部编号 不做真实查询")
+    private String subjectIdList;
+
+    @ApiModelProperty("声部编号")
+    private List<Long> subjectIds;
 	
     @ApiModelProperty("是否结算")
 	private Boolean isSettlement;

+ 9 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/CustomerServiceBatchSending.java

@@ -56,10 +56,19 @@ public class CustomerServiceBatchSending implements Serializable {
 	@TableField(value = "send_status_")
     private EImSendStatus sendStatus;
 
+    @ApiModelProperty("是否发送")
+    @TableField(value = "send_flag_")
+    private Boolean sendFlag;
+
     @ApiModelProperty("发送时间") 
 	@TableField(value = "send_time_")
     private Date sendTime;
 
+
+    @ApiModelProperty("发送完成时间")
+    @TableField(value = "send_end_time_")
+    private Date sendEndTime;
+
     @ApiModelProperty("发送条件")
     @TableField(value = "condition_")
     private String condition;

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

@@ -65,6 +65,10 @@ public class Employee implements Serializable {
 	@TableField(value = "lock_flag_")
 	private UserLockFlag lockFlag;
 
+	@ApiModelProperty("是否是客服")
+	@TableField(value = "customer_service_")
+	private Boolean customerService;
+
 	public Long getUserId() {
 		return userId;
 	}
@@ -168,4 +172,12 @@ public class Employee implements Serializable {
 	public void setLockFlag(UserLockFlag lockFlag) {
 		this.lockFlag = lockFlag;
 	}
+
+	public Boolean getCustomerService() {
+		return customerService;
+	}
+
+	public void setCustomerService(Boolean customerService) {
+		this.customerService = customerService;
+	}
 }

+ 20 - 1
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/Student.java

@@ -4,7 +4,6 @@ import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
 import com.fasterxml.jackson.annotation.JsonFormat;
-import com.yonge.cooleshow.common.enums.ESettlementFrom;
 import com.yonge.cooleshow.common.enums.UserLockFlag;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
@@ -116,6 +115,10 @@ public class Student implements Serializable {
     @TableField(value = "customer_id_")
     private Long customerId;
 
+    @ApiModelProperty("专属IM客服ID")
+    @TableField(value = "im_customer_id_")
+    private String imCustomerId;
+
     public Long getTenantId() {
         return tenantId;
     }
@@ -243,4 +246,20 @@ public class Student implements Serializable {
     public void setAvatar(String avatar) {
         this.avatar = avatar;
     }
+
+    public Long getCustomerId() {
+        return customerId;
+    }
+
+    public void setCustomerId(Long customerId) {
+        this.customerId = customerId;
+    }
+
+    public String getImCustomerId() {
+        return imCustomerId;
+    }
+
+    public void setImCustomerId(String imCustomerId) {
+        this.imCustomerId = imCustomerId;
+    }
 }

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

@@ -259,6 +259,10 @@ public class Teacher implements Serializable {
     @TableField(value = "customer_id_")
     private Long customerId;
 
+    @ApiModelProperty("专属IM客服ID")
+    @TableField(value = "im_customer_id_")
+    private String imCustomerId;
+
     public ESettlementFrom getSettlementFrom() {
         return settlementFrom;
     }
@@ -579,4 +583,28 @@ public class Teacher implements Serializable {
     public void setEvaluateTime(Long evaluateTime) {
         this.evaluateTime = evaluateTime;
     }
+
+    public Boolean getCustomerService() {
+        return customerService;
+    }
+
+    public void setCustomerService(Boolean customerService) {
+        this.customerService = customerService;
+    }
+
+    public Long getCustomerId() {
+        return customerId;
+    }
+
+    public void setCustomerId(Long customerId) {
+        this.customerId = customerId;
+    }
+
+    public String getImCustomerId() {
+        return imCustomerId;
+    }
+
+    public void setImCustomerId(String imCustomerId) {
+        this.imCustomerId = imCustomerId;
+    }
 }

+ 4 - 3
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/ClientEnum.java

@@ -10,9 +10,10 @@ import com.yonge.toolset.base.enums.BaseEnum;
  * @date 2022-04-28
  */
 public enum ClientEnum implements BaseEnum<String, ClientEnum> {
-    TEACHER("老师端"),
-    STUDENT("学生端"),
-    TENANT_STUDENT("机构-学生端"),
+    TEACHER("平台老师"),
+    STUDENT("平台学生"),
+    TENANT_STUDENT("机构学生"),
+    TENANT_TEACHER("机构老师"),
     ORGANIZATION("机构-小程序"),
     SYSTEM("平台端"),
     WEBSITE("官网"),

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

@@ -12,6 +12,7 @@ import lombok.Getter;
 public enum EImSendStatus implements BaseEnum<String, EImSendStatus> {
 
     WAIT("待发送"),
+    SENDING("发送中"),
     SEND("已发送"),
     DISABLE("已停用"),
     EXPIRE("已失效"),

+ 7 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/EmployeeService.java

@@ -58,4 +58,11 @@ public interface EmployeeService extends BaseService<Long, Employee> {
 
     int insertSysRole(SysRole sysRole);
 
+    /**
+     * 清除客服绑定关系
+     * @param userId 用户ID
+     * @param sysUserType 用户类型
+     * @return Boolean
+     */
+    Boolean clearCustomerService(Long userId, String sysUserType);
 }

+ 0 - 1
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/ImUserFriendService.java

@@ -8,7 +8,6 @@ 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;
-import org.springframework.transaction.annotation.Transactional;
 
 import java.util.List;
 import java.util.Map;

+ 6 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/StudentService.java

@@ -134,4 +134,10 @@ public interface StudentService extends IService<Student> {
 
     Map<Long,Student> getMapByIds(List<Long> userIds);
 
+    /**
+     * 设置系统默认客服
+     * @param user 用户信息
+     * @return String
+     */
+    String updateUserCustomerService(SysUser user);
 }

+ 20 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/TeacherService.java

@@ -13,6 +13,7 @@ import com.yonge.cooleshow.biz.dal.entity.TeacherStyleVideo;
 import com.yonge.cooleshow.biz.dal.enums.TeacherTagEnum;
 import com.yonge.cooleshow.biz.dal.queryInfo.TeacherQueryInfo;
 import com.yonge.cooleshow.biz.dal.vo.*;
+import com.yonge.cooleshow.biz.dal.wrapper.StatGroupWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.teacher.TeacherWrapper;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
@@ -191,4 +192,23 @@ public interface TeacherService extends IService<Teacher> {
     List<Teacher> getCustomerService();
 
     void updateLock(SysUser sysUser, Long teacherId);
+
+    /**
+     * 系统默认客服用户
+     * @return List<Teacher>
+     */
+    List<Teacher> getCustomerServiceV2();
+
+    /**
+     * 查询客服好友数量
+     * @return List<StatGroupWrapper>
+     */
+    List<StatGroupWrapper> getCustomerServiceMemberNums();
+
+    /**
+     * 更新用户客服
+     * @param userId 用户ID
+     * @return String
+     */
+    String updateUserCustomerService(Long userId);
 }

+ 4 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/TenantAlbumMusicService.java

@@ -2,7 +2,9 @@ package com.yonge.cooleshow.biz.dal.service;
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.dayaedu.cbs.openfeign.wrapper.courseware.CbsLessonCoursewareDetailWrapper;
 import com.yonge.cooleshow.biz.dal.enums.SubjectTypeEnum;
+import com.yonge.cooleshow.biz.dal.wrapper.LessonCoursewareDetailWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.LessonCoursewareWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.TenantAlbumMusicWrapper;
 import com.yonge.cooleshow.biz.dal.entity.TenantAlbumMusic;
@@ -66,4 +68,6 @@ public interface TenantAlbumMusicService extends IService<TenantAlbumMusic>  {
     List<Long> getMusicIdsByTenantIds(Long tenantId);
 
     LessonCoursewareWrapper.LessonCourseware getLessonCoursewareDetail(LessonCoursewareWrapper.LessonCourseQuery query);
+
+    LessonCoursewareDetailWrapper.LessonCoursewareDetail getLessonCourseDetail(String lessoncoursewareDetailId);
 }

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

@@ -1,14 +1,12 @@
 package com.yonge.cooleshow.biz.dal.service.im;
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
-import com.microsvc.toolkit.common.response.paging.PageInfo;
 import com.microsvc.toolkit.middleware.im.message.GroupMemberWrapper;
 import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
 import com.yonge.cooleshow.biz.dal.enums.RoleEnum;
 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 org.apache.poi.ss.formula.functions.T;
 
 import java.util.List;
 
@@ -197,4 +195,10 @@ public interface ImGroupCoreService {
     IPage<ImGroupMemberWrapper.ImGroupMember> imGroupMemberPage(IPage<ImGroupMemberWrapper.ImGroupMember> page, ImGroupMemberWrapper.ImGroupMemberQuery query);
 
     void groupMemberRole(ImGroupMemberWrapper.GroupMemberRole member);
+
+    /**
+     * 获取系统随机默认客服
+     * @return String
+     */
+    String getSysRandomCustomerService();
 }

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

@@ -7,15 +7,18 @@ 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;
 import com.microsvc.toolkit.middleware.im.message.GroupMemberWrapper;
 import com.microsvc.toolkit.middleware.im.properties.ImConfigProperties;
+import com.yonge.cooleshow.biz.dal.dao.TeacherDao;
 import com.yonge.cooleshow.biz.dal.entity.ImGroup;
 import com.yonge.cooleshow.biz.dal.entity.ImGroupMember;
 import com.yonge.cooleshow.biz.dal.entity.ImGroupMemberAudit;
 import com.yonge.cooleshow.biz.dal.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.entity.Teacher;
 import com.yonge.cooleshow.biz.dal.enums.AuditStatusEnum;
 import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
 import com.yonge.cooleshow.biz.dal.enums.RoleEnum;
@@ -25,6 +28,7 @@ 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.StatGroupWrapper;
 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;
@@ -61,6 +65,9 @@ public class ImGroupCoreServiceImpl implements ImGroupCoreService {
     @Autowired
     private SysUserService sysUserService;
 
+    @Autowired
+    private TeacherDao teacherDao;
+
     private static final String IM_USER_ID_SPLIT = "_";
 
 
@@ -1047,4 +1054,52 @@ public class ImGroupCoreServiceImpl implements ImGroupCoreService {
             }
         }
     }
+
+    /**
+     * 获取系统随机默认客服
+     *
+     * @return String
+     */
+    @Override
+    public String getSysRandomCustomerService() {
+
+        // 获取系统客服列表
+        List<Teacher> teachers = teacherDao.selectCustomerServiceV2();
+        if (CollectionUtils.isEmpty(teachers)) {
+            return "";
+        }
+
+        // IM客服ID列表
+        List<String> customerServiceIds = teachers.stream()
+            .map(Teacher::getImCustomerId)
+            .map(x -> {
+                String[] splits = x.split("_");
+                return getImUserId(splits[0], splits[1]);
+            }).collect(Collectors.toList());
+
+        // 获取客服关联用户数量
+        Map<String, Integer> collect = teacherDao.countCustomerServiceMemberNum().stream()
+            .collect(Collectors.toMap(StatGroupWrapper::getGid, StatGroupWrapper::getTotal, (o, n) -> n));
+
+        Map<String, Integer> customerServiceMap = Maps.newHashMap();
+        for (String item : customerServiceIds) {
+            customerServiceMap.put(item, collect.getOrDefault(item, 0));
+        }
+
+        // 按客服好友数量分组
+        Map<Integer, List<String>> group = customerServiceMap.entrySet().stream()
+            .collect(Collectors.groupingBy(Map.Entry::getValue, Collectors.mapping(Map.Entry::getKey, Collectors.toList())));
+
+        // 客服好友数按升序排序,获取一个客服
+        List<String> customerServiceList = group.entrySet().stream()
+            .sorted(Comparator.comparingInt(Map.Entry::getKey))
+            .map(Map.Entry::getValue)
+            .findFirst().orElse(Lists.newArrayList());
+
+        if (CollectionUtils.isEmpty(customerServiceList)) {
+            return "";
+        }
+        // 获取一个客服
+        return customerServiceList.get(0);
+    }
 }

+ 41 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/CbsMusicSheetServiceImpl.java

@@ -3,6 +3,8 @@ package com.yonge.cooleshow.biz.dal.service.impl;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
 import com.dayaedu.cbs.common.enums.music.EMusicSourceType;
+import com.dayaedu.cbs.common.enums.school.EMusicSheetType;
+import com.dayaedu.cbs.openfeign.properties.OpenFeignClientConfigProperties;
 import com.dayaedu.cbs.openfeign.service.CbsMusicSheetService;
 import com.dayaedu.cbs.openfeign.wrapper.music.*;
 import com.microsvc.toolkit.common.response.paging.PageInfo;
@@ -12,10 +14,13 @@ import com.yonge.cooleshow.biz.dal.entity.Subject;
 import com.yonge.cooleshow.biz.dal.service.MusicSheetService;
 import com.yonge.cooleshow.biz.dal.service.MusicTagService;
 import com.yonge.cooleshow.biz.dal.service.SubjectService;
+import com.yonge.cooleshow.biz.dal.service.SysConfigService;
+import com.yonge.cooleshow.common.constant.SysConfigConstant;
 import com.yonge.toolset.base.exception.BizException;
 import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
@@ -35,12 +40,23 @@ public class CbsMusicSheetServiceImpl implements CbsMusicSheetService {
     @Resource
     private SubjectService subjectService;
 
+    @Autowired
+    private SysConfigService sysConfigService;
+    @Resource
+    private OpenFeignClientConfigProperties openFeignClientConfigProperties;
+
     @Override
     @Transactional(rollbackFor = Exception.class)
     public Boolean saveApplicationExtend(List<CbsMusicSheetApplicationExtendWrapper.MusicSheetApplicationExtend> addMusicSheet) {
         if (com.baomidou.mybatisplus.core.toolkit.CollectionUtils.isEmpty(addMusicSheet)) {
             throw new BizException("请选择曲目信息");
         }
+        String configValue = sysConfigService.findConfigValue(SysConfigConstant.DEFAULT_MUSIC_USER_ID);
+        Long userId = 3L;
+        if (StringUtils.isNotBlank(configValue)) {
+            userId = Long.parseLong(configValue);
+        }
+
         List<Long> cbsMusicSheetIds = addMusicSheet.stream().map(e -> e.getMusicSheetId()).collect(Collectors.toList());
         for (CbsMusicSheetApplicationExtendWrapper.MusicSheetApplicationExtend extend : addMusicSheet) {
             CbsMusicSheetApiWrapper.MusicSheetUpdate musicSheetUpdate = extend.getMusicSheetUpdate();
@@ -50,6 +66,16 @@ public class CbsMusicSheetServiceImpl implements CbsMusicSheetService {
                     musicSheetUpdate.setSubjectIds(subjectIds.stream().map(e -> e.getId().toString()).collect(Collectors.joining(",")));
                 }
             }
+            // 如果所属人存在,判断是否是当前应用的曲目 不是,设置默认所属用户
+            if (musicSheetUpdate.getUserId() != null && musicSheetUpdate.getUserApplicationId() !=null) {
+                if (musicSheetUpdate.getUserApplicationId().equals(Long.parseLong(openFeignClientConfigProperties.getAppId()))) {
+                    musicSheetUpdate.setUserId(extend.getMusicSheetUpdate().getUserId());
+                } else {
+                    musicSheetUpdate.setUserId(userId);
+                }
+            } else {
+                musicSheetUpdate.setUserId(userId);
+            }
         }
         //需要修改的曲目
         List<MusicSheet> musicSheets = musicSheetService.lambdaQuery()
@@ -113,6 +139,21 @@ public class CbsMusicSheetServiceImpl implements CbsMusicSheetService {
                 musicSheetUpdate.setSubjectIds(subjectIds.stream().map(e -> e.getId().toString()).collect(Collectors.joining(",")));
             }
         }
+        // 如果所属人存在,判断是否是当前应用的曲目 不是,设置默认所属用户
+        String configValue = sysConfigService.findConfigValue(SysConfigConstant.DEFAULT_MUSIC_USER_ID);
+        Long userId = 3L;
+        if (StringUtils.isNotBlank(configValue)) {
+            userId = Long.parseLong(configValue);
+        }
+        if (musicSheetUpdate.getUserId() != null && musicSheetUpdate.getUserApplicationId() !=null) {
+            if (musicSheetUpdate.getUserApplicationId().equals(Long.parseLong(openFeignClientConfigProperties.getAppId()))) {
+                musicSheetUpdate.setUserId(musicSheetUpdate.getUserId());
+            } else {
+                musicSheetUpdate.setUserId(userId);
+            }
+        } else {
+            musicSheetUpdate.setUserId(userId);
+        }
         musicSheetService.getDao().updateMusicSheet(musicSheetUpdate);
         return true;
     }

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

@@ -1202,7 +1202,7 @@ public class CourseScheduleServiceImpl extends ServiceImpl<CourseScheduleDao, Co
         studentIds.add(studentId);
         try {
             imUserFriendService.saveUserFriend(teacherId, studentIds, EImUserFriendSourceForm.TEACHER);
-            imUserFriendService.refreshCustomer(teacherId, ClientEnum.TEACHER, new ArrayList<>(studentIds), ClientEnum.STUDENT);
+            //imUserFriendService.refreshCustomer(teacherId, ClientEnum.TEACHER, new ArrayList<>(studentIds), ClientEnum.STUDENT);
             log.info("保存用户通讯录成功,teacherId:{},studentIds:{}", teacherId, studentIds);
         } catch (Exception e) {
             log.error("保存用户通讯录失败,teacherId:{},studentIds:{},e:{}", teacherId, studentIds, e);

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

@@ -25,6 +25,7 @@ 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.redisson.RedissonMessageService;
 import com.yonge.cooleshow.biz.dal.service.CustomerServiceBatchSendingService;
 import com.yonge.cooleshow.biz.dal.service.CustomerServiceReceiveService;
 import com.yonge.cooleshow.biz.dal.service.ImGroupService;
@@ -34,6 +35,7 @@ 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.biz.dal.wrapper.liveroom.LiveRoomWrapper;
 import com.yonge.cooleshow.common.constant.SysConfigConstant;
 import com.yonge.toolset.base.exception.BizException;
 import com.yonge.toolset.base.util.ImUtil;
@@ -48,11 +50,14 @@ import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.joda.time.DateTime;
+import org.redisson.api.RBucket;
+import org.redisson.api.RLock;
 import org.redisson.api.RedissonClient;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import javax.annotation.PostConstruct;
 import java.text.MessageFormat;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -96,6 +101,8 @@ public class CustomerServiceBatchSendingServiceImpl extends ServiceImpl<Customer
     @Autowired
     private SysConfigService sysConfigService;
 
+    @Autowired
+    private RedissonMessageService redissonMessageService;
 	/**
      * 查询详情
      * @param id 详情ID
@@ -161,6 +168,7 @@ public class CustomerServiceBatchSendingServiceImpl extends ServiceImpl<Customer
 
         // 声部信息
         List<Long> subjectIds = sendings.stream()
+                .filter(x -> StringUtils.isNotEmpty(x.getSendSubject()))
                 .flatMap(x -> Arrays.stream(x.getSendSubject().split(",")))
                 .map(Long::parseLong).distinct().collect(Collectors.toList());
 
@@ -195,6 +203,7 @@ public class CustomerServiceBatchSendingServiceImpl extends ServiceImpl<Customer
             }
 
             List<Long> collect = Arrays.stream(Optional.ofNullable(item.getSendSubject()).orElse("").split(","))
+                .filter(StringUtils::isNotBlank)
                     .map(Long::parseLong).distinct().collect(Collectors.toList());
 
             // 发送声部
@@ -303,12 +312,40 @@ public class CustomerServiceBatchSendingServiceImpl extends ServiceImpl<Customer
             info.setSendNumber(0);
             List<Integer> receiveNums = Lists.newCopyOnWriteArrayList();
             // 条件匹配的老师、学生数量
-            query.getClientTypes().parallelStream().forEach(item -> {
+            Arrays.stream(query.getTargetGroup().split(",")).parallel().forEach(item -> {
+
+                // TEACHER: '平台老师',
+                //      STUDENT: '平台学生',
+                //      TENANT_TEACHER: '机构老师',
+                //      TENANT_STUDENT: '机构学生',
+                boolean tenantFlag = false;
+                switch (item) {
+                    case "TEACHER":
+                        item = "TEACHER";
+                        break;
+                    case "STUDENT":
+                        item = "STUDENT";
+                        break;
+                    case "TENANT_TEACHER":
+                        item = "TEACHER";
+                        tenantFlag = true;
+                        break;
+                    case "TENANT_STUDENT":
+                        item = "STUDENT";
+                        tenantFlag = true;
+                        break;
+                }
 
                 CustomerService.NotifyMessage receiveQuery = CustomerService.NotifyMessage.builder()
-                        .clientType(ClientEnum.valueOf(item))
-                        .subjectIds(Arrays.stream(info.getSendSubject().split(",")).collect(Collectors.toList()))
-                        .build();
+                    .clientType(ClientEnum.valueOf(item))
+                    .tenantFlag(tenantFlag)
+                    .delFlag(0)
+                    .lockFlag(0)
+                    //.subjectIds(Arrays.stream(info.getSendSubject().split(",")).collect(Collectors.toList()))
+                    .build();
+                if (StringUtils.isNotEmpty(info.getSendSubject())) {
+                    receiveQuery.setSubjectIds(Arrays.stream(info.getSendSubject().split(",")).collect(Collectors.toList()));
+                }
 
                 Page<CustomerService.MessageReceives> page = PageUtil.getPage(1, 10);
                 // 统计当前匹配用户数量
@@ -425,130 +462,209 @@ public class CustomerServiceBatchSendingServiceImpl extends ServiceImpl<Customer
      * @param info CustomerServiceBatchSending
      */
     private void asyncBatchSendingMessage(CustomerServiceBatchSending info) {
-        String lockName = MessageFormat.format("batchSending:{0}", String.valueOf(info.getId()));
-        // 消息状态判定,且不能重复发送
-        DistributedLock.of(redissonClient).runIfLockCanGet(lockName, () -> {
-
-            // 异步发送消息且同步更新已发送人数,稍后可在页面刷新查看已发送用户数
-            ThreadPool.getExecutor().submit(() -> {
-                // 接收消息用户数
-                List<Integer> receiveNums = Lists.newCopyOnWriteArrayList();
-                // 分页数限制
-                int limit = 500;
-
-                try {
-
-                    // 消息发送数量,默认只发送1类消息(文字或图片)
-                    int messageNum = 1;
-                    if (StringUtils.isNoneBlank(info.getTextMessage(), info.getImgMessage())) {
-                        // 同时发送图片和文字消息
-                        messageNum += 1;
-                    }
 
-                    int messageSendLimit; // 默认发送10000/分钟
-                    // 群发消息频率限制
-                    SysConfig config = sysConfigService.findByParamName(SysConfigConstant.MESSAGE_SEND_LIMIT);
-                    // 群发消息频率限制不能超过10000/分钟,超过当前值默认取值为10000
-                    if (config != null && config.getParamValue().matches("\\d+")) {
-                        int sendLimit = Integer.parseInt(config.getParamValue());
-                        if (sendLimit > 0 && sendLimit < 10000) {
-                            // 消息发送频率限制
-                            messageSendLimit = Integer.parseInt(config.getParamValue());
-                        } else {
-                            // 默认发送10000/分钟
-                            messageSendLimit = 10000;
-                        }
-                    } else {
-                        // 默认发送10000/分钟
-                        messageSendLimit = 10000;
-                    }
+        // 改状态为发送中,标记为发送中但是未发送
+        if (info.getId() == null) {
+            return;
+        }
 
-                    int finalMessageNum = messageNum;
-                    if (EImReceiveType.ALL == info.getReceiveType()) {
+        CustomerServiceBatchSending byId = getById(info.getId());
+        if (byId == null) {
+            return;
+        }else if (byId.getSendStatus() == EImSendStatus.SEND) {
+            return;
+        } else if (byId.getSendStatus() == EImSendStatus.SENDING && byId.getSendFlag()) {
+            return;
+        }
 
-                        // 推送消息给匹配用户
-                        List<String> targetGroups = Arrays.stream(info.getTargetGroup().split(",")).collect(Collectors.toList());
+        CustomerServiceBatchSending customerServiceBatchSending = new CustomerServiceBatchSending();
+        customerServiceBatchSending.setId(info.getId());
+        customerServiceBatchSending.setSendFlag(false);
+        customerServiceBatchSending.setSendTime(new Date());
+        customerServiceBatchSending.setSendStatus(EImSendStatus.SENDING);
+        updateById(customerServiceBatchSending);
+
+        // 如果有发送中,不再发送
+        Integer count = lambdaQuery()
+            .eq(CustomerServiceBatchSending::getSendStatus, EImSendStatus.SENDING)
+            .eq(CustomerServiceBatchSending::getSendFlag, 1)
+            .count();
+        if (count > 0) {
+            return;
+        }
 
-                        targetGroups.forEach(clientType -> {
+        // 异步发送消息且同步更新已发送人数,稍后可在页面刷新查看已发送用户数
+        ThreadPool.getExecutor().submit(() -> {
 
-                            CustomerService.NotifyMessage receiveQuery = CustomerService.NotifyMessage.builder()
-                                    .clientType(ClientEnum.valueOf(clientType))
-                                    .subjectIds(Arrays.stream(info.getSendSubject().split(",")).collect(Collectors.toList()))
-                                    .build();
+            // 加锁, 同时只能有一个在发送
 
-                            Page<CustomerService.MessageReceives> page = PageUtil.getPage(1, 10);
-                            // 统计当前匹配用户数量
-                            getBaseMapper().selectMessageReceives(page, receiveQuery);
+            String lockName = MessageFormat.format("batchSending:{0}", String.valueOf(info.getId()));
+            // 消息状态判定,且不能重复发送
 
-                            // 计算总页数
-                            int pages = (int) (page.getTotal() - 1) / limit + 1;
 
-                            List<Integer> collect = IntStream.iterate(1, i -> i + 1).limit(pages).boxed().collect(Collectors.toList());
+            DistributedLock.of(redissonClient).runIfLockCanGet(lockName, () -> sendMessage(info), 30L, TimeUnit.MINUTES);
 
-                            // 线程休眠计算器
-                            int sleepCount = 0;
-                            for (Integer pageNum : collect) {
 
-                                List<String> receiveUserIds = getBaseMapper().selectMessageReceives(PageUtil.getPage(pageNum, limit), receiveQuery).stream()
-                                        .map(x -> String.valueOf(x.getUserId()))
-                                        .collect(Collectors.toList());
+        });
+    }
 
-                                receiveUserIds = receiveUserIds.stream()
-                                        .map(x -> imGroupService.getImUserId(x, clientType))
-                                        .collect(Collectors.toList());
+    private void sendMessage(CustomerServiceBatchSending info) {
 
-                                // 累加线程休眠计算器,若大于指定阀值时,线程休眠1分钟
-                                sleepCount = messageSendSleepCondition(info, sleepCount, receiveUserIds.size(), finalMessageNum, messageSendLimit);
 
-                                batchSendCustomerServiceMessage(info, receiveNums, receiveUserIds);
-                            }
-                        });
+        // 接收消息用户数
+        List<Integer> receiveNums = Lists.newCopyOnWriteArrayList();
+        // 分页数限制
+        int limit = 500;
 
-                    } else {
+        try {
 
-                        // 查询条件
-                        CustomerServiceReceiveWrapper.CustomerServiceReceiveQuery receiveQuery = CustomerServiceReceiveWrapper.CustomerServiceReceiveQuery
-                                .builder().batchSendingId(info.getId()).build();
+            lambdaUpdate()
+                .eq(CustomerServiceBatchSending::getId, info.getId())
+                .set(CustomerServiceBatchSending::getSendFlag, 1)
+                .update();
 
-                        Page<CustomerServiceReceiveWrapper.CustomerServiceReceive> page = PageUtil.getPage(1, 10);
-                        // 推送消息给指定用户
-                        customerServiceReceiveService.selectPage(page, receiveQuery);
+            // 消息发送数量,默认只发送1类消息(文字或图片)
+            int messageNum = 1;
+            if (StringUtils.isNoneBlank(info.getTextMessage(), info.getImgMessage())) {
+                // 同时发送图片和文字消息
+                messageNum += 1;
+            }
 
-                        // 计算总页数
-                        int pages = (int) (page.getTotal() - 1) / limit + 1;
+            int messageSendLimit; // 默认发送10000/分钟
+            // 群发消息频率限制
+            SysConfig config = sysConfigService.findByParamName(SysConfigConstant.MESSAGE_SEND_LIMIT);
+            // 群发消息频率限制不能超过10000/分钟,超过当前值默认取值为10000
+            if (config != null && config.getParamValue().matches("\\d+")) {
+                int sendLimit = Integer.parseInt(config.getParamValue());
+                if (sendLimit > 0 && sendLimit < 10000) {
+                    // 消息发送频率限制
+                    messageSendLimit = Integer.parseInt(config.getParamValue());
+                } else {
+                    // 默认发送10000/分钟
+                    messageSendLimit = 10000;
+                }
+            } else {
+                // 默认发送10000/分钟
+                messageSendLimit = 10000;
+            }
 
-                        List<Integer> collect = IntStream.iterate(1, i -> i + 1).limit(pages).boxed().collect(Collectors.toList());
+            int finalMessageNum = messageNum;
+            if (EImReceiveType.ALL == info.getReceiveType()) {
+
+                // 推送消息给匹配用户
+                List<String> targetGroups = Arrays.stream(info.getTargetGroup().split(",")).collect(Collectors.toList());
+
+                targetGroups.forEach(clientType -> {
+                    boolean tenantFlag = false;
+                    switch (clientType) {
+                        case "TEACHER":
+                            clientType = "TEACHER";
+                            break;
+                        case "STUDENT":
+                            clientType = "STUDENT";
+                            break;
+                        case "TENANT_TEACHER":
+                            clientType = "TEACHER";
+                            tenantFlag = true;
+                            break;
+                        case "TENANT_STUDENT":
+                            clientType = "STUDENT";
+                            tenantFlag = true;
+                            break;
+                    }
 
-                        // 线程休眠计算器
-                        int sleepCount = 0;
-                        for (Integer pageNum : collect) {
+                    CustomerService.NotifyMessage receiveQuery = CustomerService.NotifyMessage.builder()
+                        .clientType(ClientEnum.valueOf(clientType))
+                        .tenantFlag(tenantFlag)
+                        .lockFlag(0)
+                        .delFlag(0)
+                        //.subjectIds(Arrays.stream(info.getSendSubject().split(",")).collect(Collectors.toList()))
+                        .build();
+                    if (StringUtils.isNotBlank(info.getSendSubject())) {
+                        receiveQuery.setSubjectIds(Arrays.stream(info.getSendSubject().split(",")).collect(Collectors.toList()));
+                    }
 
-                            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());
+                    Page<CustomerService.MessageReceives> page = PageUtil.getPage(1, 10);
+                    // 统计当前匹配用户数量
+                    getBaseMapper().selectMessageReceives(page, receiveQuery);
 
-                            // 累加线程休眠计算器,若大于指定阀值时,线程休眠1分钟
-                            sleepCount = messageSendSleepCondition(info, sleepCount, receiveUserIds.size(), finalMessageNum, messageSendLimit);
+                    // 计算总页数
+                    int pages = (int) (page.getTotal() - 1) / limit + 1;
 
-                            batchSendCustomerServiceMessage(info, receiveNums, receiveUserIds);
-                        }
+                    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()
+                                .map(x -> String.valueOf(x.getUserId()))
+                                .collect(Collectors.toList());
+
+                        String finalClientType = clientType;
+                        receiveUserIds = receiveUserIds.stream()
+                                .map(x -> imGroupService.getImUserId(x, finalClientType))
+                                .collect(Collectors.toList());
+
+                        // 累加线程休眠计算器,若大于指定阀值时,线程休眠1分钟
+                        sleepCount = messageSendSleepCondition(info, sleepCount, receiveUserIds.size(), finalMessageNum, messageSendLimit);
+
+                        batchSendCustomerServiceMessage(info, receiveNums, receiveUserIds);
                     }
+                });
+
+            } else {
+
+                // 查询条件
+                CustomerServiceReceiveWrapper.CustomerServiceReceiveQuery receiveQuery = CustomerServiceReceiveWrapper.CustomerServiceReceiveQuery
+                        .builder().batchSendingId(info.getId()).build();
+
+                Page<CustomerServiceReceiveWrapper.CustomerServiceReceive> page = PageUtil.getPage(1, 10);
+                // 推送消息给指定用户
+                customerServiceReceiveService.selectPage(page, receiveQuery);
+
+                // 计算总页数
+                int pages = (int) (page.getTotal() - 1) / limit + 1;
 
-                    // 更新消息状态为已发送
-                    lambdaUpdate()
-                            .eq(CustomerServiceBatchSending::getId, info.getId())
-                            .set(CustomerServiceBatchSending::getSendStatus, EImSendStatus.SEND)
-                            .set(CustomerServiceBatchSending::getReceiveNumber, receiveNums.stream().mapToInt(Integer::intValue).sum())
-                            .set(CustomerServiceBatchSending::getSendTime, DateTime.now().toDate())
-                            .update();
+                List<Integer> collect = IntStream.iterate(1, i -> i + 1).limit(pages).boxed().collect(Collectors.toList());
 
-                } catch (Exception e) {
-                    log.error("sendMessage id={}", info.getId(), e);
+                // 线程休眠计算器
+                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);
                 }
+            }
 
-            });
 
-        }, 30L, TimeUnit.MINUTES);
+        } catch (Exception e) {
+            log.error("sendMessage id={}", info.getId(), e);
+        } finally {
+            // 更新消息状态为已发送
+            lambdaUpdate()
+                .eq(CustomerServiceBatchSending::getId, info.getId())
+                .set(CustomerServiceBatchSending::getSendStatus, EImSendStatus.SEND)
+                .set(CustomerServiceBatchSending::getReceiveNumber, receiveNums.stream().mapToInt(Integer::intValue).sum())
+                .set(CustomerServiceBatchSending::getSendEndTime, DateTime.now().toDate())
+                .update();
+        }
+
+        CustomerServiceBatchSending one = lambdaQuery()
+            .eq(CustomerServiceBatchSending::getSendStatus, EImSendStatus.SENDING)
+            .eq(CustomerServiceBatchSending::getSendFlag, 0)
+            .orderByAsc(CustomerServiceBatchSending::getId)
+            .last("limit 1")
+            .one();
+        if (one !=null) {
+            sendMessage(one);
+        }
     }
 
     /**
@@ -736,9 +852,10 @@ public class CustomerServiceBatchSendingServiceImpl extends ServiceImpl<Customer
             Date endTime = DateTime.now().toDate();
 
             List<CustomerServiceBatchSending> batchSendings = lambdaQuery()
-                    .between(CustomerServiceBatchSending::getSendTime, startTime, endTime)
-                    .eq(CustomerServiceBatchSending::getSendType, EImSendType.SCHEDULED)
-                    .eq(CustomerServiceBatchSending::getSendStatus, EImSendStatus.WAIT)
+                    .lt(CustomerServiceBatchSending::getSendTime, endTime)
+//                    .eq(CustomerServiceBatchSending::getSendType, EImSendType.SCHEDULED)
+                    .in(CustomerServiceBatchSending::getSendStatus, EImSendStatus.WAIT,EImSendStatus.SENDING)
+                    .eq(CustomerServiceBatchSending::getSendFlag,0)
                     .list();
 
             if (CollectionUtils.isNotEmpty(batchSendings)) {
@@ -746,7 +863,7 @@ public class CustomerServiceBatchSendingServiceImpl extends ServiceImpl<Customer
 
                 for (List<CustomerServiceBatchSending> item : Lists.partition(batchSendings, 10)) {
 
-                    item.parallelStream().forEach(x -> sendMessage(x.getId()));
+                    item.forEach(x -> sendMessage(x.getId()));
                 }
 
             }

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

@@ -1,18 +1,27 @@
 package com.yonge.cooleshow.biz.dal.service.impl;
 
-import java.util.Date;
-import java.util.List;
-
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.auth.api.entity.SysRole;
 import com.yonge.cooleshow.auth.api.entity.SysUser;
-import com.yonge.cooleshow.biz.dal.service.SysConfigService;
-import com.yonge.cooleshow.common.constant.SysConfigConstant;
-import com.yonge.cooleshow.common.enums.SysUserType;
+import com.yonge.cooleshow.biz.dal.dao.EmployeeDao;
 import com.yonge.cooleshow.biz.dal.dto.EmployeeDto;
 import com.yonge.cooleshow.biz.dal.dto.search.EmployeeSearch;
+import com.yonge.cooleshow.biz.dal.entity.Employee;
+import com.yonge.cooleshow.biz.dal.entity.Student;
+import com.yonge.cooleshow.biz.dal.entity.Teacher;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.service.EmployeeService;
+import com.yonge.cooleshow.biz.dal.service.StudentService;
+import com.yonge.cooleshow.biz.dal.service.SysConfigService;
+import com.yonge.cooleshow.biz.dal.service.TeacherService;
+import com.yonge.cooleshow.biz.dal.service.im.ImGroupCoreService;
 import com.yonge.cooleshow.biz.dal.vo.EmployeeVo;
+import com.yonge.cooleshow.common.constant.SysConfigConstant;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
-
+import com.yonge.cooleshow.common.enums.SysUserType;
+import com.yonge.cooleshow.common.enums.UserLockFlag;
+import com.yonge.cooleshow.common.enums.YesOrNoEnum;
+import com.yonge.toolset.mybatis.dal.BaseDAO;
 import com.yonge.toolset.mybatis.service.impl.BaseServiceImpl;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.BeanUtils;
@@ -21,11 +30,9 @@ import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
-import com.yonge.cooleshow.auth.api.entity.SysRole;
-import com.yonge.cooleshow.biz.dal.dao.EmployeeDao;
-import com.yonge.cooleshow.biz.dal.entity.Employee;
-import com.yonge.cooleshow.biz.dal.service.EmployeeService;
-import com.yonge.toolset.mybatis.dal.BaseDAO;
+import java.util.Date;
+import java.util.List;
+import java.util.Optional;
 
 @Service
 public class EmployeeServiceImpl extends BaseServiceImpl<Long, Employee> implements EmployeeService {
@@ -35,6 +42,15 @@ public class EmployeeServiceImpl extends BaseServiceImpl<Long, Employee> impleme
     @Autowired
     private SysConfigService sysConfigService;
 
+    @Autowired
+    private ImGroupCoreService imGroupCoreService;
+
+    @Autowired
+    private TeacherService teacherService;
+
+    @Autowired
+    private StudentService studentService;
+
     @Override
     public BaseDAO<Long, Employee> getDAO() {
         return employeeDao;
@@ -92,6 +108,13 @@ public class EmployeeServiceImpl extends BaseServiceImpl<Long, Employee> impleme
         //新增员工表
         param.setUserId(sysUser.getId());
         employeeDao.insert(param);
+
+        // 员工设置为客服时,同步IM账号到三方
+        if (Optional.ofNullable(param.getCustomerService()).orElse(false)) {
+            imGroupCoreService.register(String.valueOf(param.getUserId()), ClientEnum.SYSTEM.getCode(),
+                param.getUsername(), sysUser.getAvatar());
+        }
+
         return HttpResponseResult.succeed(param);
     }
 
@@ -115,6 +138,21 @@ public class EmployeeServiceImpl extends BaseServiceImpl<Long, Employee> impleme
         employeeDao.batchAddEmployeeRole(employee.getUserId(), param.getRoleIds());
 
         employeeDao.update(param);
+
+        // 员工设置为客服时,同步IM账号到三方
+        if (Optional.ofNullable(param.getCustomerService()).orElse(false)) {
+            imGroupCoreService.register(String.valueOf(param.getUserId()), ClientEnum.SYSTEM.getCode(),
+                param.getUsername(), sysUser.getAvatar());
+        } else {
+            // 员工设置为非客服时,删除IM账号
+            if (Optional.ofNullable(employee.getCustomerService()).orElse(false)
+                || sysUser.getLockFlag().equals(YesOrNoEnum.YES.getCode())
+                || employee.getLockFlag() == UserLockFlag.LOCKED) {
+
+                // 清除客服绑定关系
+                clearCustomerService(param.getUserId(), SysUserType.SYSTEM.getCode());
+            }
+        }
         return HttpResponseResult.succeed(param);
     }
 
@@ -150,4 +188,33 @@ public class EmployeeServiceImpl extends BaseServiceImpl<Long, Employee> impleme
         return employeeDao.insertSysRole(sysRole);
     }
 
+    /**
+     * 清除客服绑定关系
+     *
+     * @param userId      用户ID
+     * @param sysUserType 用户类型
+     * @return Boolean
+     */
+    @Override
+    public Boolean clearCustomerService(Long userId, String sysUserType) {
+        // 清除客服绑定关系
+        String imCustomerServiceId = imGroupCoreService.getImUserId(String.valueOf(userId), sysUserType);
+
+        // 更新老师表的客服ID
+        teacherService.lambdaUpdate()
+            .eq(Teacher::getImCustomerId, imCustomerServiceId)
+            .set(Teacher::getCustomerId, null)
+            .set(Teacher::getImCustomerId, "")
+            .update();
+
+        // 更新学生表的客服ID
+        studentService.lambdaUpdate()
+            .eq(Student::getImCustomerId, imCustomerServiceId)
+            .set(Student::getCustomerId, null)
+            .set(Student::getImCustomerId, "")
+            .update();
+
+        return true;
+    }
+
 }

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

@@ -2,8 +2,6 @@ package com.yonge.cooleshow.biz.dal.service.impl;
 
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
-import com.alibaba.fastjson.JSON;
-import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.IdWorker;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@@ -24,39 +22,35 @@ import com.yonge.cooleshow.auth.api.entity.SysUser;
 import com.yonge.cooleshow.auth.config.AppGlobalServiceConfig;
 import com.yonge.cooleshow.biz.dal.dao.CourseScheduleStudentPaymentDao;
 import com.yonge.cooleshow.biz.dal.dao.ImGroupDao;
-import com.yonge.cooleshow.biz.dal.dao.ImGroupMemberAuditDao;
 import com.yonge.cooleshow.biz.dal.dao.TeacherDao;
 import com.yonge.cooleshow.biz.dal.dto.BasicUserInfo;
 import com.yonge.cooleshow.biz.dal.dto.ImGroupResultDto;
 import com.yonge.cooleshow.biz.dal.dto.ImGroupSearchDto;
-import com.yonge.cooleshow.biz.dal.entity.*;
 import com.yonge.cooleshow.biz.dal.dto.search.StudentSearch;
 import com.yonge.cooleshow.biz.dal.dto.search.TeacherSearch;
-import com.yonge.cooleshow.biz.dal.entity.*;
-import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
-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;
 import com.yonge.cooleshow.biz.dal.entity.ImGroupMember;
 import com.yonge.cooleshow.biz.dal.entity.ImHistoryMessage;
 import com.yonge.cooleshow.biz.dal.entity.StudentStar;
+import com.yonge.cooleshow.biz.dal.entity.SysConfig;
 import com.yonge.cooleshow.biz.dal.entity.Teacher;
 import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+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.CourseGroupService;
 import com.yonge.cooleshow.biz.dal.service.ImGroupMemberService;
 import com.yonge.cooleshow.biz.dal.service.ImGroupService;
 import com.yonge.cooleshow.biz.dal.service.ImUserFriendService;
+import com.yonge.cooleshow.biz.dal.service.StudentService;
 import com.yonge.cooleshow.biz.dal.service.StudentStarService;
+import com.yonge.cooleshow.biz.dal.service.SysConfigService;
 import com.yonge.cooleshow.biz.dal.service.SysUserService;
 import com.yonge.cooleshow.biz.dal.service.TeacherService;
-import com.yonge.cooleshow.biz.dal.wrapper.im.ImGroupWrapper;
+import com.yonge.cooleshow.biz.dal.service.UploadFileService;
 import com.yonge.cooleshow.biz.dal.service.im.ImGroupCoreService;
 import com.yonge.cooleshow.biz.dal.support.IMHelper;
 import com.yonge.cooleshow.biz.dal.vo.StudentVo;
@@ -67,18 +61,14 @@ import com.yonge.cooleshow.common.constant.SysConfigConstant;
 import com.yonge.cooleshow.common.entity.UploadReturnBean;
 import com.yonge.toolset.base.exception.BizException;
 import com.yonge.toolset.base.util.ThreadPool;
-import com.yonge.toolset.payment.util.DistributedLock;
-import com.yonge.toolset.utils.date.DateUtil;
-import io.rong.RongCloud;
-import io.rong.methods.message.history.History;
 import com.yonge.toolset.mybatis.support.PageUtil;
+import com.yonge.toolset.payment.util.DistributedLock;
 import io.rong.RongCloud;
 import io.rong.methods.message.history.History;
 import io.rong.models.Result;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.lang3.StringUtils;
 import org.joda.time.DateTime;
 import org.redisson.api.RBucket;
 import org.redisson.api.RedissonClient;
@@ -86,19 +76,15 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
-import org.springframework.beans.factory.annotation.Value;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import javax.annotation.Resource;
-import java.io.*;
-import java.net.URL;
-import java.nio.charset.StandardCharsets;
 import javax.imageio.ImageIO;
 import java.awt.image.BufferedImage;
-import java.io.*;
 import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
@@ -106,11 +92,10 @@ import java.io.InputStreamReader;
 import java.net.URL;
 import java.nio.charset.StandardCharsets;
 import java.text.MessageFormat;
-import java.util.*;
-import java.util.stream.Collectors;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Base64;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.Date;
@@ -118,6 +103,7 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Objects;
 import java.util.Optional;
+import java.util.Random;
 import java.util.Set;
 import java.util.UUID;
 import java.util.concurrent.TimeUnit;
@@ -125,10 +111,6 @@ import java.util.stream.Collectors;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipFile;
 import java.util.zip.ZipInputStream;
-import java.util.stream.Collectors;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipFile;
-import java.util.zip.ZipInputStream;
 
 /**
  * 即时通讯群组(ImGroup)表服务实现类
@@ -147,8 +129,7 @@ public class ImGroupServiceImpl extends ServiceImpl<ImGroupDao, ImGroup> impleme
     private ImUserFriendService imUserFriendService;
     @Resource
     private ImGroupMemberService imGroupMemberService;
-    @Resource
-    private ImGroupMemberAuditDao imGroupMemberAuditDao;
+
     @Resource
     private SysUserService sysUserService;
     @Autowired
@@ -174,10 +155,6 @@ public class ImGroupServiceImpl extends ServiceImpl<ImGroupDao, ImGroup> impleme
     private String appSecret;
 
     @Autowired
-    private CustomerServiceBatchSendingService customerServiceBatchSendingService;
-
-
-    @Autowired
     private ImPluginContext imPluginContext;
 
     @Autowired
@@ -395,7 +372,7 @@ public class ImGroupServiceImpl extends ServiceImpl<ImGroupDao, ImGroup> impleme
                     teacherList.forEach(teacher ->
                             {
                                 imUserFriendService.saveUserFriend(teacher.getUserId(), studentIdList, EImUserFriendSourceForm.TEACHER);
-                                imUserFriendService.refreshCustomer(teacher.getUserId(), ClientEnum.TEACHER, new ArrayList<>(studentIdList), ClientEnum.STUDENT);
+                                //imUserFriendService.refreshCustomer(teacher.getUserId(), ClientEnum.TEACHER, new ArrayList<>(studentIdList), ClientEnum.STUDENT);
                             }
                     );
                 }
@@ -428,7 +405,7 @@ public class ImGroupServiceImpl extends ServiceImpl<ImGroupDao, ImGroup> impleme
         Long teacherId = courseGroup.getTeacherId();
         //保存老师学员关联的通讯录xz
         imUserFriendService.saveUserFriend(teacherId, Sets.newHashSet(studentIds),EImUserFriendSourceForm.TEACHER);
-        imUserFriendService.refreshCustomer(teacherId, ClientEnum.TEACHER, new ArrayList<>(studentIds), ClientEnum.STUDENT);
+        //imUserFriendService.refreshCustomer(teacherId, ClientEnum.TEACHER, new ArrayList<>(studentIds), ClientEnum.STUDENT);
 
 
         // 直播课、琴房课校验群成员人数限制

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

@@ -288,6 +288,13 @@ public class ImUserFriendServiceImpl extends ServiceImpl<ImUserFriendDao, ImUser
      */
     @Override
     public Integer registerUserBindCustomerService(Long userId, List<Long> friendIds, ClientEnum clientType) {
+
+        // 不在加客服好友
+        if (true) {
+            // TODO: 忽略后续流程不执行
+            return 0;
+        }
+
         if(userId == null || CollectionUtils.isEmpty(friendIds)){
             return 0;
         }
@@ -323,7 +330,7 @@ public class ImUserFriendServiceImpl extends ServiceImpl<ImUserFriendDao, ImUser
                 saveUserFriend(teacherId, Sets.newHashSet(userId), sourceForm);
                 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), sourceForm);
+                //saveUserTeacherFriend(teacherId, Sets.newHashSet(userId), sourceForm);
                 teacherDao.update(null, new UpdateWrapper<Teacher>().lambda().eq(Teacher::getUserId, userId).set(Teacher::getCustomerId, teacherId));
             }
 
@@ -414,6 +421,11 @@ public class ImUserFriendServiceImpl extends ServiceImpl<ImUserFriendDao, ImUser
             return;
         }
 
+        // 客服不加好友
+        if (true) {
+            return;
+        }
+
         try {
             if (StringUtils.isEmpty(sendMessage)) {
                 sendMessage = MK.IM_SYS_FRIEND;
@@ -627,7 +639,7 @@ public class ImUserFriendServiceImpl extends ServiceImpl<ImUserFriendDao, ImUser
     @Override
     public void refreshCustomer(Long userId, ClientEnum userClientType, List<Long> friendIds, ClientEnum friendClientType) {
 
-        this.lambdaUpdate()
+        /*this.lambdaUpdate()
                 .set(ImUserFriend::getSourceForm, EImUserFriendSourceForm.TEACHER)
                 .eq(ImUserFriend::getUserId, userId)
                 .eq(ImUserFriend::getClientType, userClientType)
@@ -641,7 +653,7 @@ public class ImUserFriendServiceImpl extends ServiceImpl<ImUserFriendDao, ImUser
                 .eq(ImUserFriend::getClientType, friendClientType)
                 .eq(ImUserFriend::getFriendId, userId)
                 .eq(ImUserFriend::getFriendType, userClientType)
-                .update();
+                .update();*/
     }
 }
 

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

@@ -465,7 +465,7 @@ public class PaymentDivMemberRecordServiceImpl extends ServiceImpl<PaymentDivMem
         studentIds.add(studentId);
         try {
             imUserFriendService.saveUserFriend(teacherId, studentIds, EImUserFriendSourceForm.TEACHER);
-            imUserFriendService.refreshCustomer(teacherId, ClientEnum.TEACHER, new ArrayList<>(studentIds), ClientEnum.STUDENT);
+            //imUserFriendService.refreshCustomer(teacherId, ClientEnum.TEACHER, new ArrayList<>(studentIds), ClientEnum.STUDENT);
             log.info("保存用户通讯录成功,teacherId:{},studentIds:{}", teacherId, studentIds);
         } catch (Exception e) {
             log.error("保存用户通讯录失败,teacherId:{},studentIds:{},e:{}", teacherId, studentIds, e);

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

@@ -34,11 +34,11 @@ import com.yonge.cooleshow.biz.dal.vo.TeacherVo;
 import com.yonge.cooleshow.biz.dal.wrapper.StudentWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.VipCardRecordWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.im.ImGroupWrapper;
-import com.yonge.cooleshow.biz.dal.wrapper.teacher.TeacherWrapper;
 import com.yonge.cooleshow.common.constant.SysConfigConstant;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import com.yonge.cooleshow.common.enums.CacheNameEnum;
 import com.yonge.cooleshow.common.enums.UserLockFlag;
+import com.yonge.cooleshow.common.enums.UserStatusEnum;
 import com.yonge.cooleshow.common.enums.YesOrNoEnum;
 import com.yonge.toolset.base.util.StringUtil;
 import com.yonge.toolset.mybatis.support.PageUtil;
@@ -147,6 +147,20 @@ public class StudentServiceImpl extends ServiceImpl<StudentDao, Student> impleme
             VipCardRecordWrapper.UserVipInfo vipType = curVipMap.getOrDefault(userId, new VipCardRecordWrapper.UserVipInfo());
             detail.setMembershipEndTime(vipType.getCurrentVipSvipEndTime());
             detail.setVipType(vipType.getCurrentVipType());
+
+            // 系统客服数量
+            detail.setCustomerServiceNum(teacherDao.selectCustomerServiceV2().size());
+
+            // 设置老师帐号状态
+            if(detail.getDelFlag() == YesOrNoEnum.YES){
+                detail.setUserStatus(UserStatusEnum.CLOSED);
+            }else{
+                if(detail.getLockFlag() == UserLockFlag.LOCKED){
+                    detail.setUserStatus(UserStatusEnum.LOCKED);
+                }else{
+                    detail.setUserStatus(UserStatusEnum.NORMAL);
+                }
+            }
         }
         return detail;
     }
@@ -387,7 +401,7 @@ public class StudentServiceImpl extends ServiceImpl<StudentDao, Student> impleme
             studentIds.add(studentVo.getUserId());
             imUserFriendService.saveUserFriend(userId, studentIds, EImUserFriendSourceForm.TEACHER);
         }
-        imUserFriendService.refreshCustomer(userId, ClientEnum.TEACHER, Collections.singletonList(studentVo.getUserId()), ClientEnum.STUDENT);
+        //imUserFriendService.refreshCustomer(userId, ClientEnum.TEACHER, Collections.singletonList(studentVo.getUserId()), ClientEnum.STUDENT);
 //        }
         resMap.put("now", detail);
         return HttpResponseResult.succeed(resMap);
@@ -650,7 +664,7 @@ public class StudentServiceImpl extends ServiceImpl<StudentDao, Student> impleme
                 HashSet<Long> studentIds = new HashSet<>();
                 studentIds.add(student.getUserId());
                 imUserFriendService.saveUserFriend(teacher.getUserId(), studentIds, EImUserFriendSourceForm.TEACHER);
-                imUserFriendService.refreshCustomer(teacher.getUserId(), ClientEnum.TEACHER, new ArrayList<>(studentIds), ClientEnum.STUDENT);
+                //imUserFriendService.refreshCustomer(teacher.getUserId(), ClientEnum.TEACHER, new ArrayList<>(studentIds), ClientEnum.STUDENT);
             }
             addBindUnBindRecord(student.getUserId(),student.getTenantId(),true);
         }
@@ -742,7 +756,7 @@ public class StudentServiceImpl extends ServiceImpl<StudentDao, Student> impleme
                 HashSet<Long> studentIds = new HashSet<>();
                 studentIds.add(student.getUserId());
                 imUserFriendService.saveUserFriend(teacher.getUserId(), studentIds,EImUserFriendSourceForm.TEACHER);
-                imUserFriendService.refreshCustomer(teacher.getUserId(), ClientEnum.TEACHER, new ArrayList<>(studentIds), ClientEnum.STUDENT);
+                //imUserFriendService.refreshCustomer(teacher.getUserId(), ClientEnum.TEACHER, new ArrayList<>(studentIds), ClientEnum.STUDENT);
             }
 
             addBindUnBindRecord(student.getUserId(),studentInfo.getTenantId(),true);
@@ -892,12 +906,13 @@ public class StudentServiceImpl extends ServiceImpl<StudentDao, Student> impleme
 
         save(student);
         //  与好友数量最少的客服建立好友关系
-        List<TeacherWrapper.TeacherFriend> customerServiceFriendNums = teacherDao.getCustomerServiceFriendNums();
+        /*List<TeacherWrapper.TeacherFriend> customerServiceFriendNums = teacherDao.getCustomerServiceFriendNums();
         if (!customerServiceFriendNums.isEmpty()) {
             Long teacherId = customerServiceFriendNums.get(0).getTeacherId();
             imUserFriendService.registerUserBindCustomerService(student.getUserId(),
                     Collections.singletonList(teacherId), ClientEnum.STUDENT);
-        }
+        }*/
+
         try {
             // 注册IM
             imGroupCoreService.register(String.valueOf(student.getUserId()),ClientEnum.STUDENT.getCode(), sysUser.getUsername(), avatar);
@@ -914,7 +929,7 @@ public class StudentServiceImpl extends ServiceImpl<StudentDao, Student> impleme
             teacherList.forEach(next ->
                     {
                         imUserFriendService.saveUserFriend(next.getUserId(), new HashSet<>(ImmutableList.of(sysUser.getId())), EImUserFriendSourceForm.TEACHER);
-                        imUserFriendService.refreshCustomer(next.getUserId(), ClientEnum.TEACHER, Collections.singletonList(sysUser.getId()), ClientEnum.STUDENT);
+                        //imUserFriendService.refreshCustomer(next.getUserId(), ClientEnum.TEACHER, Collections.singletonList(sysUser.getId()), ClientEnum.STUDENT);
                     }
             );
 
@@ -1049,4 +1064,40 @@ public class StudentServiceImpl extends ServiceImpl<StudentDao, Student> impleme
         bindRecord.setBindTime(new Date());
         userTenantBindRecordMapper.add(bindRecord);
     }
+
+    /**
+     * 设置系统默认客服
+     *
+     * @param user 用户信息
+     * @return String
+     */
+    @Override
+    public String updateUserCustomerService(SysUser user) {
+
+        StudentVo detail = detail(user.getId());
+        if (Objects.isNull(detail)) {
+            throw new BizException("学生信息不存在");
+        }
+
+        // 学生已绑定客服,直接近回
+        if (StringUtils.isNotBlank(detail.getImCustomerId())) {
+            return detail.getImCustomerId();
+        }
+
+        // 随机分配系统客服
+        String imCustomerServiceId = imGroupCoreService.getSysRandomCustomerService();
+        if (StringUtils.isBlank(imCustomerServiceId)) {
+            throw new BizException("系统客服不存在");
+        }
+        String customerServiceId = imGroupCoreService.analysisImUserId(imCustomerServiceId);
+
+        // 更新用户绑定客服
+        lambdaUpdate()
+            .eq(Student::getUserId, user.getId())
+            .set(Student::getCustomerId, customerServiceId)
+            .set(Student::getImCustomerId, imCustomerServiceId)
+            .update();
+
+        return imCustomerServiceId;
+    }
 }

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

@@ -11,7 +11,6 @@ import com.google.common.collect.Lists;
 import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
 import com.yonge.cooleshow.auth.api.dto.RealnameAuthReq;
 import com.yonge.cooleshow.auth.api.entity.SysUser;
-import com.yonge.cooleshow.auth.config.CustomerServiceConfig;
 import com.yonge.cooleshow.biz.dal.dao.EmployeeDao;
 import com.yonge.cooleshow.biz.dal.dao.StudentStarDao;
 import com.yonge.cooleshow.biz.dal.dao.TeacherDao;
@@ -27,7 +26,6 @@ import com.yonge.cooleshow.biz.dal.enums.ImGroupType;
 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;
@@ -70,6 +68,7 @@ import com.yonge.cooleshow.common.enums.ESettlementFrom;
 import com.yonge.cooleshow.common.enums.ETenantUnBindAuditStatus;
 import com.yonge.cooleshow.common.enums.UserFirstTimeTypeEnum;
 import com.yonge.cooleshow.common.enums.UserLockFlag;
+import com.yonge.cooleshow.common.enums.UserStatusEnum;
 import com.yonge.cooleshow.common.enums.YesOrNoEnum;
 import com.yonge.toolset.base.exception.BizException;
 import com.yonge.toolset.base.util.StringUtil;
@@ -184,9 +183,6 @@ public class TeacherServiceImpl extends ServiceImpl<TeacherDao, Teacher> impleme
     private RealnameAuthenticationPlugin realnameAuthenticationPlugin;
 
     @Autowired
-    private CustomerServiceConfig customerServiceConfig;
-
-    @Autowired
     private SysUserMapper sysUserMapper;
 
     @Autowired
@@ -240,6 +236,25 @@ public class TeacherServiceImpl extends ServiceImpl<TeacherDao, Teacher> impleme
         VipCardRecordWrapper.UserVipInfo vipType = curVipMap.getOrDefault(userId, new VipCardRecordWrapper.UserVipInfo());
         detail.setMembershipEndTime(vipType.getCurrentVipSvipEndTime());
         detail.setVipType(vipType.getCurrentVipType());
+
+        // 设置老师帐号状态
+        if(detail.getDelFlag() == YesOrNoEnum.YES){
+            detail.setUserStatus(UserStatusEnum.CLOSED);
+        }else{
+            if(detail.getLockFlag() == UserLockFlag.LOCKED){
+                detail.setUserStatus(UserStatusEnum.LOCKED);
+            }else{
+                detail.setUserStatus(UserStatusEnum.NORMAL);
+            }
+        }
+
+        // 系统客服数量
+        detail.setCustomerServiceNum(baseMapper.selectCustomerServiceV2().size());
+        if (Optional.ofNullable(detail.getCustomerService()).orElse(false)) {
+            // 老师本身是客服,不显示客服入口;重置客服数量为0
+            detail.setCustomerServiceNum(0);
+        }
+
         return detail;
     }
 
@@ -335,8 +350,7 @@ public class TeacherServiceImpl extends ServiceImpl<TeacherDao, Teacher> impleme
         if (tenantId != null && tenantId > 0 && Boolean.TRUE.equals(customerService)) {
             throw new BizException("客服不能有机构老师身份");
         }
-        // todo 暂时不上客服相关
-//        teacherSubmitReq.setCustomerService(null);
+
         if (null == teacherSubmitReq.getUserId()) {
 
             if (StringUtils.isNoneBlank(teacherSubmitReq.getPhone(), teacherSubmitReq.getCode())) {
@@ -632,25 +646,29 @@ public class TeacherServiceImpl extends ServiceImpl<TeacherDao, Teacher> impleme
             sendBindUnBindSMS(teacher.getUserId(), teacherSubmitReq.getPhone(), MessageTypeEnum.TEACHER_BIND_TENANT, teacher.getTenantId());
 
             //  与客服建立好友
-            if (!Boolean.TRUE.equals(teacher.getCustomerService())) {
+            /*if (!Boolean.TRUE.equals(teacher.getCustomerService())) {
                 List<TeacherWrapper.TeacherFriend> customerServiceFriendNums = this.getBaseMapper().getCustomerServiceFriendNums();
                 if (!customerServiceFriendNums.isEmpty()) {
                     Long teacherId = customerServiceFriendNums.get(0).getTeacherId();
                     imUserFriendService.registerUserBindCustomerService(teacher.getUserId(),
                             Collections.singletonList(teacherId), ClientEnum.TEACHER);
                 }
-            }
+            }*/
         } else {
             // 客服状态变更,移交好友信息
             Boolean customerService = teacher.getCustomerService();
-            List<TeacherWrapper.CustomerServiceSendMsg2User> customerServiceSendMsg2User = new ArrayList<>();
+            //List<TeacherWrapper.CustomerServiceSendMsg2User> customerServiceSendMsg2User = new ArrayList<>();
             if (Boolean.TRUE.equals(customerService) && Boolean.FALSE.equals(teacherSubmitReq.getCustomerService())) {
-                customerServiceSendMsg2User.addAll(transferFriendV2(teacher.getUserId(), true));
+                //customerServiceSendMsg2User.addAll(transferFriendV2(teacher.getUserId(), true));
+
+                // 清除客服绑定关系
                 clearUserCustomerRelation(teacherSubmitReq.getUserId());
+
+                // 重置客服关系
                 this.update(null, new UpdateWrapper<Teacher>().lambda()
                         .set(Teacher::getCustomerId, null)
+                        .set(Teacher::getImCustomerId, "")
                         .eq(Teacher::getUserId, teacherSubmitReq.getUserId()));
-                teacher.setCustomerId(null);
             }
             // 如果机构解绑,更新机构ID为-1
             if (Boolean.TRUE.equals(teacherSubmitReq.getBindTenant())) {
@@ -687,7 +705,7 @@ public class TeacherServiceImpl extends ServiceImpl<TeacherDao, Teacher> impleme
 
 
             // 交接后的客服发送消息
-            if (Boolean.TRUE.equals(customerService) && Boolean.FALSE.equals(teacherSubmitReq.getCustomerService())) {
+            /*if (Boolean.TRUE.equals(customerService) && Boolean.FALSE.equals(teacherSubmitReq.getCustomerService())) {
                 String customerMessage = sysConfigService.findConfigValue(SysConfigConstant.CUSTOMER_SERVICE_ADD_MSG);
                 String customerTitle = sysConfigService.findConfigValue(SysConfigConstant.CUSTOMER_SERVICE_ADD_MSG_TITLE);
                 for (TeacherWrapper.CustomerServiceSendMsg2User serviceSendMsg2User : customerServiceSendMsg2User) {
@@ -696,7 +714,7 @@ public class TeacherServiceImpl extends ServiceImpl<TeacherDao, Teacher> impleme
                     imUserFriendService.sendCustomerServiceAddFriendMessage(serviceSendMsg2User.getCustomerId(), customerTitle, customerMessage, serviceSendMsg2User.getStudentIds(),
                             ClientEnum.STUDENT);
                 }
-            }
+            }*/
 
         }
 
@@ -705,15 +723,23 @@ public class TeacherServiceImpl extends ServiceImpl<TeacherDao, Teacher> impleme
 
     // 清除专属客服信息
     private void clearUserCustomerRelation(Long userId) {
+
+        String imCustomerServiceId = imGroupCoreService.getImUserId(String.valueOf(userId), ClientEnum.TEACHER.getCode());
+
+        // 重置老师关联客服绑定
         this.update(null, new UpdateWrapper<Teacher>().lambda()
-                .eq(Teacher::getCustomerId, userId)
+                .eq(Teacher::getImCustomerId, imCustomerServiceId)
+                .set(Teacher::getImCustomerId, "")
                 .set(Teacher::getCustomerId, null));
+
+        // 重置学生关联客服绑定
         studentService.update(null, new UpdateWrapper<Student>().lambda()
-                .eq(Student::getCustomerId, userId)
+                .eq(Student::getImCustomerId, imCustomerServiceId)
+                .set(Student::getImCustomerId, "")
                 .set(Student::getCustomerId, null));
     }
 
-    private List<TeacherWrapper.CustomerServiceSendMsg2User> transferFriendV2(Long userId, boolean saveGroupFriend){
+    /*private List<TeacherWrapper.CustomerServiceSendMsg2User> transferFriendV2(Long userId, boolean saveGroupFriend){
         List<TeacherWrapper.CustomerServiceSendMsg2User> result = new ArrayList<>();
         // 所有的好友
         List<ImUserFriend> userFriendList = imUserFriendService.lambdaQuery()
@@ -839,9 +865,9 @@ public class TeacherServiceImpl extends ServiceImpl<TeacherDao, Teacher> impleme
 //            imUserFriendService.sendCustomerServiceAddFriendMessage(teacherId, customerTitle, customerMessage, new ArrayList<>(studentIds), ClientEnum.STUDENT);
         });
         return result;
-    }
+    }*/
 
-    private List<Long> getSameTenant(Long teacherId, Set<Long> userIds, ClientEnum clientEnum) {
+    /*private List<Long> getSameTenant(Long teacherId, Set<Long> userIds, ClientEnum clientEnum) {
         Teacher teacher = this.getById(teacherId);
         Long tenantId = teacher.getTenantId();
         if (tenantId == null || tenantId <= 0) {
@@ -858,7 +884,8 @@ public class TeacherServiceImpl extends ServiceImpl<TeacherDao, Teacher> impleme
                     .map(Teacher::getUserId).collect(Collectors.toList());
         }
         return new ArrayList<>();
-    }
+    }*/
+
     /***
      * 封装用户信息
      * @author liweifan
@@ -1355,7 +1382,7 @@ public class TeacherServiceImpl extends ServiceImpl<TeacherDao, Teacher> impleme
 
             if (!collect.isEmpty()) {
                 imUserFriendService.saveUserFriend(teacher.getUserId(), collect, EImUserFriendSourceForm.TEACHER);
-                imUserFriendService.refreshCustomer(teacher.getUserId(), ClientEnum.TEACHER, new ArrayList<>(collect), ClientEnum.STUDENT);
+                //imUserFriendService.refreshCustomer(teacher.getUserId(), ClientEnum.TEACHER, new ArrayList<>(collect), ClientEnum.STUDENT);
             }
             addBindUnBindRecord(teacher.getUserId(),updateTenant.getTenantId(),true);
             SysUser sysUser = sysUserMapper.getByUserId(teacher.getUserId());
@@ -1511,22 +1538,83 @@ public class TeacherServiceImpl extends ServiceImpl<TeacherDao, Teacher> impleme
 
         // 冻结客服,移交好友给其他客服
         if (UserLockFlag.NORMAL.equals(teacher.getLockFlag()) && Boolean.TRUE.equals(customerService)) {
-            List<TeacherWrapper.CustomerServiceSendMsg2User> customerServiceSendMsg2User = transferFriendV2(teacherId, false);
+            // List<TeacherWrapper.CustomerServiceSendMsg2User> customerServiceSendMsg2User = transferFriendV2(teacherId, false);
+
+            // 清除客服绑定关系
             clearUserCustomerRelation(teacherId);
+
+            // 重置数据
             this.update(null, new UpdateWrapper<Teacher>().lambda()
                     .set(Teacher::getCustomerId, null)
+                    .set(Teacher::getImCustomerId, "")
                     .eq(Teacher::getUserId, teacherId));
-            teacher.setCustomerId(null);
-            for (TeacherWrapper.CustomerServiceSendMsg2User serviceSendMsg2User : customerServiceSendMsg2User) {
+
+            /*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(),
                         ClientEnum.STUDENT);
-            }
+            }*/
         }
         teacher.setLockFlag(UserLockFlag.NORMAL.equals(teacher.getLockFlag()) ? UserLockFlag.LOCKED : UserLockFlag.NORMAL);
         this.updateById(teacher);
     }
+
+    /**
+     * 系统默认客服用户
+     *
+     * @return List<Teacher>
+     */
+    @Override
+    public List<Teacher> getCustomerServiceV2() {
+        return baseMapper.selectCustomerServiceV2();
+    }
+
+    /**
+     * 查询客服好友数量
+     *
+     * @return List<StatGroupWrapper>
+     */
+    @Override
+    public List<StatGroupWrapper> getCustomerServiceMemberNums() {
+        return baseMapper.countCustomerServiceMemberNum();
+    }
+
+    /**
+     * 更新用户客服
+     *
+     * @param userId 用户ID
+     * @return String
+     */
+    @Override
+    public String updateUserCustomerService(Long userId) {
+
+        TeacherVo teacher = detail(userId);
+        if (Objects.isNull(teacher)) {
+            throw new BizException("老师不存在");
+        }
+
+        // 学生已绑定客服,直接近回
+        if (StringUtils.isNotBlank(teacher.getImCustomerId())) {
+            return teacher.getImCustomerId();
+        }
+
+        // 随机分配系统客服
+        String imCustomerServiceId = imGroupCoreService.getSysRandomCustomerService();
+        if (StringUtils.isBlank(imCustomerServiceId)) {
+            throw new BizException("系统客服不存在");
+        }
+        String customerServiceId = imGroupCoreService.analysisImUserId(imCustomerServiceId);
+
+        // 更新用户绑定客服
+        lambdaUpdate()
+            .eq(Teacher::getUserId, userId)
+            .set(Teacher::getCustomerId, customerServiceId)
+            .set(Teacher::getImCustomerId, imCustomerServiceId)
+            .update();
+
+        return imCustomerServiceId;
+    }
 }

+ 142 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/TenantAlbumMusicServiceImpl.java

@@ -5,9 +5,13 @@ import com.alibaba.fastjson.JSON;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.dayaedu.cbs.common.enums.school.ECourseType;
+import com.dayaedu.cbs.common.enums.school.EKnowledgeType;
+import com.dayaedu.cbs.common.enums.school.EMaterialType;
 import com.dayaedu.cbs.openfeign.client.CoursewareFeignService;
 import com.dayaedu.cbs.openfeign.wrapper.courseware.CbsCourseTypeWrapper;
+import com.dayaedu.cbs.openfeign.wrapper.courseware.CbsLessonCoursewareDetailWrapper;
 import com.dayaedu.cbs.openfeign.wrapper.courseware.CbsLessonCoursewareWrapper;
+import com.dayaedu.cbs.openfeign.wrapper.courseware.CbsMaterialRefWrapper;
 import com.dayaedu.cbs.openfeign.wrapper.music.CbsMusicSheetWrapper;
 import com.microsvc.toolkit.common.response.paging.PageInfo;
 import com.yonge.cooleshow.biz.dal.entity.*;
@@ -15,6 +19,8 @@ import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
 import com.yonge.cooleshow.biz.dal.enums.SubjectTypeEnum;
 import com.yonge.cooleshow.biz.dal.mapper.TenantAlbumMusicMapper;
 import com.yonge.cooleshow.biz.dal.service.*;
+import com.yonge.cooleshow.biz.dal.service.cbs.CbsMusicScoreService;
+import com.yonge.cooleshow.biz.dal.wrapper.LessonCoursewareDetailWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.LessonCoursewareWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.TenantAlbumMusicWrapper;
 import com.yonge.toolset.base.exception.BizException;
@@ -418,4 +424,140 @@ public class TenantAlbumMusicServiceImpl extends ServiceImpl<TenantAlbumMusicMap
 
         return lessonCoursewareDto;
     }
+
+    @Override
+    public LessonCoursewareDetailWrapper.LessonCoursewareDetail getLessonCourseDetail(String lessonCoursewareDetailId) {
+        CbsLessonCoursewareDetailWrapper.LessonCoursewareDetail cbsLessonCoursewareDetail = coursewareFeignService.lessonCoursewareDetailDetail(Long.parseLong(lessonCoursewareDetailId)).feignData();
+        if (cbsLessonCoursewareDetail == null) {
+            throw new BizException("课件不存在");
+        }
+        LessonCoursewareDetailWrapper.LessonCoursewareDetail lessonCoursewareDetail = JSON.parseObject(JSON.toJSONString(cbsLessonCoursewareDetail), LessonCoursewareDetailWrapper.LessonCoursewareDetail.class);
+
+
+        // 过滤调未应用到项目的去练习曲目
+        List<LessonCoursewareDetailWrapper.KnowledgePointSmall> knowledgePointList = lessonCoursewareDetail.getKnowledgePointList();
+        List<LessonCoursewareDetailWrapper.AddMaterialRef> addMaterialRefs = getMaterialRefList(knowledgePointList);
+        List<LessonCoursewareDetailWrapper.MaterialSmall> musicMaterialSmalls = getMaterialSmalls(knowledgePointList);
+        if (CollectionUtils.isNotEmpty(musicMaterialSmalls)) {
+            List<Long> cbsMaterialMusicIds = musicMaterialSmalls.stream().map(LessonCoursewareDetailWrapper.MaterialSmall::getContent)
+                .filter(StringUtils::isNotBlank).map(Long::parseLong).collect(Collectors.toList());
+            Map<Long, Long> idMap = musicSheetService.lambdaQuery()
+                .in(MusicSheet::getCbsMusicSheetId, cbsMaterialMusicIds)
+                .eq(MusicSheet::getDelFlag, false)
+                .eq(MusicSheet::getState, 1)
+                .list()
+                .stream()
+                .collect(Collectors.toMap(MusicSheet::getCbsMusicSheetId, MusicSheet::getId,(o1,o2)->o1));
+
+            // 过滤掉没有对应的曲目
+            filterMusicMaterialList(knowledgePointList,new ArrayList<>(idMap.keySet()));
+            for (LessonCoursewareDetailWrapper.MaterialSmall musicMaterialSmall : musicMaterialSmalls) {
+                musicMaterialSmall.setContent(idMap.getOrDefault(Long.parseLong(musicMaterialSmall.getContent()),-1L).toString());
+            }
+        }
+        List<Long> cbsMusicSheetIdList =
+            addMaterialRefs.stream().filter(next -> EKnowledgeType.MUSIC.equals(next.getKnowledgeType()))
+                .map(LessonCoursewareDetailWrapper.AddMaterialRef::getResourceId).distinct().collect(Collectors.toList());
+        if (!org.springframework.util.CollectionUtils.isEmpty(cbsMusicSheetIdList)) {
+            Map<Long, Long> idMap = musicSheetService.lambdaQuery()
+                .in(MusicSheet::getCbsMusicSheetId, cbsMusicSheetIdList)
+                .eq(MusicSheet::getDelFlag, false)
+                .eq(MusicSheet::getState, 1)
+                .list()
+                .stream()
+                .collect(Collectors.toMap(MusicSheet::getCbsMusicSheetId, MusicSheet::getId,(o1,o2)->o1));
+
+            for (LessonCoursewareDetailWrapper.AddMaterialRef addMaterialRef : addMaterialRefs) {
+                Long resourceId = addMaterialRef.getResourceId();
+                if (idMap.containsKey(resourceId)) {
+                    addMaterialRef.setResourceId(idMap.get(resourceId));
+                    addMaterialRef.setResourceIdStr(idMap.getOrDefault(resourceId,-1L).toString());
+                }
+            }
+            // 过滤掉没有对应的曲目
+            filterMaterialRefList(knowledgePointList,new ArrayList<>(idMap.values()));
+        }
+
+        return lessonCoursewareDetail;
+    }
+
+    private void filterMusicMaterialList(List<LessonCoursewareDetailWrapper.KnowledgePointSmall> knowledgePointList, List<Long> cbsMusicSheetIds) {
+        if (CollectionUtils.isNotEmpty(knowledgePointList)) {
+            for (LessonCoursewareDetailWrapper.KnowledgePointSmall knowledgePointSmall : knowledgePointList) {
+
+                if (CollectionUtils.isNotEmpty(knowledgePointSmall.getChildren())) {
+                    filterMusicMaterialList(knowledgePointSmall.getChildren(),cbsMusicSheetIds);
+                }
+                List<LessonCoursewareDetailWrapper.MaterialSmall> materialList = knowledgePointSmall.getMaterialList();
+                if (CollectionUtils.isNotEmpty(materialList)) {
+                    materialList.removeIf(next -> (EMaterialType.SONG.equals(next.getType()) && !cbsMusicSheetIds.contains(Long.parseLong(next.getContent()))));
+                    knowledgePointSmall.setMaterialList(materialList);
+                }
+            }
+        }
+    }
+
+    private List<LessonCoursewareDetailWrapper.MaterialSmall> getMaterialSmalls(List<LessonCoursewareDetailWrapper.KnowledgePointSmall> knowledgePointList) {
+        List<LessonCoursewareDetailWrapper.MaterialSmall> materialRefList = new ArrayList<>();
+        if (CollectionUtils.isNotEmpty(knowledgePointList)) {
+            for (LessonCoursewareDetailWrapper.KnowledgePointSmall knowledgePointSmall : knowledgePointList) {
+
+                if (CollectionUtils.isNotEmpty(knowledgePointSmall.getChildren())) {
+                    materialRefList.addAll(getMaterialSmalls(knowledgePointSmall.getChildren()));
+                }
+                List<LessonCoursewareDetailWrapper.MaterialSmall> materialList = knowledgePointSmall.getMaterialList();
+                if (CollectionUtils.isNotEmpty(materialList)) {
+                    for (LessonCoursewareDetailWrapper.MaterialSmall materialSmall : materialList) {
+                        if (materialSmall.getType() == EMaterialType.SONG) {
+                            materialRefList.add(materialSmall);
+                        }
+                    }
+                }
+            }
+        }
+        return materialRefList;
+    }
+
+    private void filterMaterialRefList(List<LessonCoursewareDetailWrapper.KnowledgePointSmall> knowledgePointList,List<Long> cbsMusicSheetIds) {
+        if (CollectionUtils.isNotEmpty(knowledgePointList)) {
+            for (LessonCoursewareDetailWrapper.KnowledgePointSmall knowledgePointSmall : knowledgePointList) {
+
+                if (CollectionUtils.isNotEmpty(knowledgePointSmall.getChildren())) {
+                    filterMaterialRefList(knowledgePointSmall.getChildren(),cbsMusicSheetIds);
+                }
+                List<LessonCoursewareDetailWrapper.MaterialSmall> materialList = knowledgePointSmall.getMaterialList();
+                if (CollectionUtils.isNotEmpty(materialList)) {
+                    for (LessonCoursewareDetailWrapper.MaterialSmall materialSmall : materialList) {
+                        if (CollectionUtils.isNotEmpty(materialSmall.getMaterialRefs())) {
+                            List<LessonCoursewareDetailWrapper.AddMaterialRef> refList = materialSmall.getMaterialRefs().stream()
+                                .filter(next -> !(EKnowledgeType.MUSIC.equals(next.getKnowledgeType()) && !cbsMusicSheetIds.contains(next.getResourceId())))
+                                .collect(Collectors.toList());
+                            materialSmall.setMaterialRefs(refList);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    private List<LessonCoursewareDetailWrapper.AddMaterialRef> getMaterialRefList(List<LessonCoursewareDetailWrapper.KnowledgePointSmall> knowledgePointList) {
+        List<LessonCoursewareDetailWrapper.AddMaterialRef> materialRefList = new ArrayList<>();
+        if (CollectionUtils.isNotEmpty(knowledgePointList)) {
+            for (LessonCoursewareDetailWrapper.KnowledgePointSmall knowledgePointSmall : knowledgePointList) {
+
+                if (CollectionUtils.isNotEmpty(knowledgePointSmall.getChildren())) {
+                    materialRefList.addAll(getMaterialRefList(knowledgePointSmall.getChildren()));
+                }
+                List<LessonCoursewareDetailWrapper.MaterialSmall> materialList = knowledgePointSmall.getMaterialList();
+                if (CollectionUtils.isNotEmpty(materialList)) {
+                    for (LessonCoursewareDetailWrapper.MaterialSmall materialSmall : materialList) {
+                        if (CollectionUtils.isNotEmpty(materialSmall.getMaterialRefs())) {
+                            materialRefList.addAll(materialSmall.getMaterialRefs());
+                        }
+                    }
+                }
+            }
+        }
+        return materialRefList;
+    }
 }

+ 22 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/vo/EmployeeVo.java

@@ -39,6 +39,12 @@ public class EmployeeVo extends Employee {
     @ApiModelProperty(value = "用户状态 NORMAL-正常   LOCKED-冻结  CLOSED-关闭")
     private UserStatusEnum userStatus;
 
+    @ApiModelProperty(value = "imToken")
+    private String imToken;
+
+    @ApiModelProperty("im用户id")
+    private String imUserId;
+
     public String getUsername() {
         return username;
     }
@@ -115,4 +121,20 @@ public class EmployeeVo extends Employee {
 	public void setUserStatus(UserStatusEnum userStatus) {
 		this.userStatus = userStatus;
 	}
+
+    public String getImToken() {
+        return imToken;
+    }
+
+    public void setImToken(String imToken) {
+        this.imToken = imToken;
+    }
+
+    public String getImUserId() {
+        return imUserId;
+    }
+
+    public void setImUserId(String imUserId) {
+        this.imUserId = imUserId;
+    }
 }

+ 11 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/vo/StudentHomeVo.java

@@ -97,6 +97,9 @@ public class StudentHomeVo extends Student {
     @ApiModelProperty(value = "机构小组名称")
     private String tenantGroupName;
 
+    @ApiModelProperty("客服数量")
+    private Integer customerServiceNum;
+
     public YesOrNoEnum getTenantAlbumFlag() {
         return tenantAlbumFlag;
     }
@@ -302,4 +305,12 @@ public class StudentHomeVo extends Student {
     public void setImToken(String imToken) {
         this.imToken = imToken;
     }
+
+    public Integer getCustomerServiceNum() {
+        return customerServiceNum;
+    }
+
+    public void setCustomerServiceNum(Integer customerServiceNum) {
+        this.customerServiceNum = customerServiceNum;
+    }
 }

+ 11 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/vo/StudentVo.java

@@ -100,6 +100,9 @@ public class StudentVo extends Student {
     @ApiModelProperty(value = "会员结束时间字符传")
     private String membershipEndTimeStr;
 
+    @ApiModelProperty("客服数量")
+    private Integer customerServiceNum;
+
     public YesOrNoEnum getDelFlag() {
         return delFlag;
     }
@@ -238,4 +241,12 @@ public class StudentVo extends Student {
         }
         return "";
     }
+
+    public Integer getCustomerServiceNum() {
+        return customerServiceNum;
+    }
+
+    public void setCustomerServiceNum(Integer customerServiceNum) {
+        this.customerServiceNum = customerServiceNum;
+    }
 }

+ 10 - 3
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/vo/TeacherHomeVo.java

@@ -103,9 +103,8 @@ public class TeacherHomeVo extends Teacher implements Serializable {
     @ApiModelProperty(value = "imToken")
     private String imToken;
 
-    @ApiModelProperty("是否是客服")
-    private Boolean customerService;
-
+    @ApiModelProperty("客服数量")
+    private Integer customerServiceNum;
 
     public String getTenantName() {
         return tenantName;
@@ -383,4 +382,12 @@ public class TeacherHomeVo extends Teacher implements Serializable {
     public void setTenantAlbumStatus(Integer tenantAlbumStatus) {
         this.tenantAlbumStatus = tenantAlbumStatus;
     }
+
+    public Integer getCustomerServiceNum() {
+        return customerServiceNum;
+    }
+
+    public void setCustomerServiceNum(Integer customerServiceNum) {
+        this.customerServiceNum = customerServiceNum;
+    }
 }

+ 11 - 3
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/vo/TeacherVo.java

@@ -122,12 +122,12 @@ public class TeacherVo extends Teacher {
     @ApiModelProperty("svip结束时间")
     private Date perSvipEndTime;
 
-    @ApiModelProperty("是否客服")
-    private Boolean customerService;
-
     @ApiModelProperty(value = "会员结束时间字符传")
     private String membershipEndTimeStr;
 
+    @ApiModelProperty("客服数量")
+    private Integer customerServiceNum;
+
     public YesOrNoEnum getDelFlag() {
         return delFlag;
     }
@@ -399,4 +399,12 @@ public class TeacherVo extends Teacher {
         }
         return "";
     }
+
+    public Integer getCustomerServiceNum() {
+        return customerServiceNum;
+    }
+
+    public void setCustomerServiceNum(Integer customerServiceNum) {
+        this.customerServiceNum = customerServiceNum;
+    }
 }

+ 120 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/LessonCoursewareDetailWrapper.java

@@ -0,0 +1,120 @@
+package com.yonge.cooleshow.biz.dal.wrapper;
+
+import com.dayaedu.cbs.common.enums.school.EKnowledgeType;
+import com.dayaedu.cbs.common.enums.school.EMaterialRefType;
+import com.dayaedu.cbs.common.enums.school.EMaterialType;
+import com.dayaedu.cbs.openfeign.wrapper.courseware.CbsMaterialRefWrapper;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.Date;
+import java.util.List;
+
+public class LessonCoursewareDetailWrapper {
+
+
+    @Data
+    @ApiModel(" LessonCoursewareDetail-课件内容")
+    public static class LessonCoursewareDetail {
+        @ApiModelProperty("主键ID")
+        private String id;
+        @ApiModelProperty("课件编号")
+        private Long lessonCoursewareId;
+        @ApiModelProperty("课时名称")
+        private String name;
+        @ApiModelProperty("课时目标描述")
+        private String lessonTargetDesc;
+        @ApiModelProperty("课后训练编号")
+        private Long lessonTrainingId;
+        @ApiModelProperty("课后训练名称")
+        private String lessonTrainingName;
+        @ApiModelProperty("课程时长(秒)")
+        private Integer lessonDurationSecond;
+        @ApiModelProperty("课程排序")
+        private Integer lessonOrder;
+        @ApiModelProperty("是否锁定")
+        private Boolean lockFlag;
+        @ApiModelProperty("是否需要锁定课件")
+        private Boolean lockEnable;
+        @ApiModelProperty("创建时间")
+        private Date createTime;
+        @ApiModelProperty("更新时间")
+        private Date updateTime;
+        private String knowledgePointIds;
+        @ApiModelProperty("可见范围,0:所有人课件,1:仅VIP学生可见")
+        private Integer accessScope;
+        @ApiModelProperty("知识点")
+        private List<KnowledgePointSmall> knowledgePointList;
+        private List<Long> lessonCoursewareIds;
+        private List<Long> lessonCoursewareDetailIds;
+    }
+
+    @Data
+    @ApiModel(" KnowledgePointSmall-知识点")
+    public static class KnowledgePointSmall {
+        @ApiModelProperty("知识点编号")
+        private Long id;
+        @ApiModelProperty("排序")
+        private Integer sortNo;
+        @ApiModelProperty("知识点名称")
+        private String name;
+        @ApiModelProperty("建议学习时长")
+        private Integer totalMaterialTimeSecond = 0;
+        @ApiModelProperty("素材")
+        private List<MaterialSmall> materialList;
+        @ApiModelProperty("子节点")
+        private List<KnowledgePointSmall> children;
+    }
+
+    @Data
+    @ApiModel(" MaterialSmall-素材")
+    public static class MaterialSmall {
+        @ApiModelProperty("素材编号")
+        private Long id;
+        @ApiModelProperty("素材知识点关联编号")
+        private Long knowledgePointMaterialRelationId;
+        @ApiModelProperty("知识点编号")
+        private Long knowledgePointId;
+        @ApiModelProperty("素材名称")
+        private String name;
+        @ApiModelProperty("分段编号")
+        private String sn;
+        @ApiModelProperty("课程类型")
+        private String courseTypeCode;
+        @ApiModelProperty("素材时长")
+        private Integer adviseStudyTimeSecond;
+        @ApiModelProperty("素材类型")
+        private EMaterialType type;
+        @ApiModelProperty("素材类型-兼容管乐迷")
+        private String typeCode;
+        @ApiModelProperty("视频、图片链接或者是曲目编号")
+        private String content;
+        @ApiModelProperty("更新时间")
+        private Date updateTime;
+
+        @ApiModelProperty("关联资源数据")
+        private List<AddMaterialRef> materialRefs;
+
+//        @ApiModelProperty("状态")
+//        private boolean status = true;
+    }
+
+    @Data
+    @ApiModel(" AddMaterialRef-素材关联")
+    public static class AddMaterialRef {
+        @ApiModelProperty("关联素材ID")
+        private Long resourceId;
+        @ApiModelProperty("类型,MUSIC,MATERIAL")
+        private EKnowledgeType knowledgeType;
+        @ApiModelProperty("关联类型,强:STRONG,弱:WEAK")
+        private EMaterialRefType refType;
+        @ApiModelProperty("资源名称")
+        private String resourceName;
+        @ApiModelProperty("资源信息")
+        private CbsMaterialRefWrapper.RelateMaterialInfo relateMaterialInfo;
+
+        @ApiModelProperty("关联素材ID")
+        private String resourceIdStr;
+    }
+}

+ 3 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/im/CustomerService.java

@@ -29,12 +29,15 @@ public class CustomerService {
         private List<String> receives;
         private ClientEnum clientType;
         private String subjectId;
+        private Integer lockFlag;
+        private Integer delFlag;
         private List<String> subjectIds;
 
         private String title;
         private String txtMessage;
         private String imgMessage;
         private String imgUrl;
+        boolean tenantFlag;
 
         public static NotifyMessage from(String recv) {
 

+ 1 - 0
cooleshow-user/user-biz/src/main/resources/config/mybatis/CourseGroupMapper.xml

@@ -181,6 +181,7 @@
             <if test="param.search != null and param.search !=''">
                 and  (
                     cg.id_ like concat('%',#{param.search},'%')
+                    or cg.name_ like concat('%',#{param.search},'%')
                     or su.id_ like concat('%',#{param.search},'%')
                     or su.username_ like concat('%',#{param.search},'%')
                     or su.phone_  like concat('%',#{param.search},'%')

+ 11 - 1
cooleshow-user/user-biz/src/main/resources/config/mybatis/CustomerServiceBatchSendingMapper.xml

@@ -15,12 +15,14 @@
         , t.send_type_ AS sendType
         , t.send_status_ AS sendStatus
         , t.send_time_ AS sendTime
+        , t.send_end_time_ AS sendEndTime
         , t.condition_ AS `condition`
         , t.title_ AS title
         , t.text_message_ AS textMessage
         , t.img_message_ AS imgMessage
         , t.img_url_ AS imgUrl
         , t.sender_id_ AS senderId
+        , t.send_flag_ AS sendFlag
         , t.create_by_ AS createBy
         , t.create_time_ AS createTime
     </sql>
@@ -61,12 +63,20 @@
         SELECT t1.id_ AS userId, t1.username_ FROM sys_user t1
         <if test="param.clientType != null">
             <if test="param.clientType.code == 'TEACHER'"> LEFT JOIN teacher t2 ON (t1.id_ = t2.user_id_)</if>
-            <if test="param.clientType.code == 'STUDENT'"> LEFT JOIN student t2 ON (t1.id_ = t2.user_id_)</if>
+            <if test="param.clientType.code == 'STUDENT'"> LEFT JOIN student t2 ON (t1.id_ = t2.user_id_ and t2.hide_flag_ = 0)</if>
         </if>
         <where>
             <if test="param.subjectIds != null">
                 AND (<foreach collection="param.subjectIds" separator="OR" item="item"> FIND_IN_SET(#{item}, t2.subject_id_) </foreach>)
             </if>
+            <if test="param.tenantFlag != null">
+                <if test="param.tenantFlag == 1">
+                    AND t2.tenant_id_  != -1
+                </if>
+                <if test="param.tenantFlag == 0">
+                    AND t2.tenant_id_ = -1
+                </if>
+            </if>
         </where>
     </select>
     <!--客服消息接收者-->

+ 10 - 2
cooleshow-user/user-biz/src/main/resources/config/mybatis/EmployeeMapper.xml

@@ -20,6 +20,7 @@
         <result column="demission_date_" property="demissionDate"/>
         <result column="contact_address_" property="contactAddress"/>
         <result column="lock_flag_" property="lockFlag" />
+        <result column="customer_service_" property="customerService" />
     </resultMap>
 
     <resultMap type="com.yonge.cooleshow.auth.api.entity.SysUser" id="SysUser">
@@ -59,6 +60,7 @@
         , t.introduction_ as "introduction"
         , t.demission_date_ as "demissionDate"
         , t.contact_address_ as "contactAddress"
+        , t.customer_service_ as "customerService"
     </sql>
 
     <select id="detail" resultType="com.yonge.cooleshow.biz.dal.vo.EmployeeVo">
@@ -105,6 +107,9 @@
             <if test="null != param.delFlag">
                 and u.del_flag_ = #{param.delFlag}
             </if>
+            <if test="param.customerService != null">
+                AND t.customer_service_ = #{param.customerService}
+            </if>
         </where>
     </select>
 
@@ -188,9 +193,9 @@
             keyProperty="id">
         INSERT INTO employee
         (user_id_,job_nature_,is_probation_period_,education_background_,graduate_school_,technical_titles_,
-        entry_date_,update_time_,create_time_,introduction_,demission_date_,contact_address_)
+        entry_date_,update_time_,create_time_,introduction_,demission_date_,contact_address_,customer_service_)
         VALUES(#{userId},#{jobNature},#{isProbationPeriod},#{educationBackground},#{graduateSchool},
-        #{technicalTitles},#{entryDate},now(),now(),#{introduction},#{demissionDate},#{contactAddress})
+        #{technicalTitles},#{entryDate},now(),now(),#{introduction},#{demissionDate},#{contactAddress},#{customerService})
     </insert>
 
     <update id="update" parameterType="com.yonge.cooleshow.biz.dal.entity.Employee">
@@ -229,6 +234,9 @@
             <if test="lockFlag != null">
                 lock_flag_ = #{lockFlag},
             </if>
+            <if test="customerService != null">
+                customer_service_ = #{customerService},
+            </if>
         </set>
         WHERE user_id_ = #{userId}
     </update>

+ 6 - 6
cooleshow-user/user-biz/src/main/resources/config/mybatis/MusicSheetAuthRecordMapper.xml

@@ -67,12 +67,12 @@
             </if>
             <if test="param.authStatus != null">
                 and msar.audit_state_ = #{param.authStatus}
-                <if test="param.authStatus == 'PASS'">
-                    AND ms.state_ = 1
-                </if>
-                <if test="param.authStatus == 'OUT_SALE'">
-                    AND ms.state_ = 0
-                </if>
+<!--                <if test="param.authStatus == 'PASS'">-->
+<!--                    AND ms.state_ = 1-->
+<!--                </if>-->
+<!--                <if test="param.authStatus == 'OUT_SALE'">-->
+<!--                    AND ms.state_ = 0-->
+<!--                </if>-->
             </if>
             <if test="param.createBy != null">
                 and ms.create_by_ = #{param.createBy}

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

@@ -37,6 +37,7 @@
         , t.tenant_group_id_ as `tenantGroupId`
         , t.im_device_id_ as imDeviceId
         , t.customer_id_ as customerId
+        , t.im_customer_id_ AS imCustomerId
         </sql>
     <update id="setSubject">
         update student set subject_id_ = #{subjectIds},update_time_ = now() where user_id_ = #{id}

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

@@ -95,6 +95,7 @@
         , t.im_device_id_ as imDeviceId
         , t.customer_service_ as customerService
         , t.customer_id_ as customerId
+        , t.im_customer_id_ AS imCustomerId
     </sql>
 
     <!-- 分页查询 -->
@@ -178,6 +179,13 @@
             <if test="param.subjectId != null">
                 and find_in_set(#{param.subjectId},t.subject_id_)
             </if>
+            <if test="param.subjectIds != null and param.subjectIds.size() != 0">
+                and (
+                <foreach collection="param.subjectIds" item="subjectId" separator=" or " open="(" close=")">
+                    find_in_set(#{subjectId},t.subject_id_)
+                </foreach>
+                )
+            </if>
             <if test="param.isSettlement != null">
                 and t.is_settlement_ = #{param.isSettlement}
             </if>
@@ -471,4 +479,24 @@
         group by te.user_id_
         order by friendNums
     </select>
+
+    <!--系统客服列表-->
+    <select id="selectCustomerServiceV2" resultType="com.yonge.cooleshow.biz.dal.entity.Teacher">
+        SELECT t.im_customer_id_ AS imCustomerId FROM (
+          SELECT CONCAT(t1.user_id_, '_TEACHER') AS im_customer_id_ FROM teacher t1 LEFT JOIN sys_user t2 ON t1.user_id_ = t2.id_ WHERE t1.customer_service_ = 1 AND t1.lock_flag_ = 0  AND t2.lock_flag_ = 0
+          UNION ALL
+          SELECT CONCAT(t1.user_id_, '_SYSTEM') AS im_customer_id_ FROM employee t1 LEFT JOIN sys_user t2 ON t1.user_id_ = t2.id_ WHERE t1.customer_service_ = 1 AND t1.lock_flag_ = 0 AND t2.lock_flag_ = 0
+        ) t
+    </select>
+
+    <!--系统客服好友统计-->
+    <select id="countCustomerServiceMemberNum"
+            resultType="com.yonge.cooleshow.biz.dal.wrapper.StatGroupWrapper">
+        SELECT t.im_customer_id_ AS gid, COUNT(t.user_id_) AS total FROM (
+             SELECT t1.im_customer_id_, t1.user_id_ FROM teacher t1 WHERE t1.im_customer_id_ != '' AND t1.customer_service_ = 0
+             UNION ALL
+             SELECT t1.im_customer_id_, t1.user_id_ FROM student t1 WHERE t1.im_customer_id_ != ''
+         ) t GROUP BY t.im_customer_id_
+    </select>
+
 </mapper>