Forráskód Böngészése

Merge branch 'saas' of http://git.dayaedu.com/yonge/mec into zx_saas_homework

zouxuan 1 éve
szülő
commit
c4e558857d
42 módosított fájl, 1265 hozzáadás és 371 törlés
  1. 2 1
      mec-application/src/main/java/com/ym/mec/config/ResourceServerConfig.java
  2. 98 0
      mec-application/src/main/java/com/ym/mec/student/controller/StudentCoursewarePlayRecordController.java
  3. 1 1
      mec-application/src/main/java/com/ym/mec/student/controller/StudentVipGroupController.java
  4. 19 29
      mec-application/src/main/java/com/ym/mec/teacher/controller/ClassGroupController.java
  5. 1 1
      mec-application/src/main/java/com/ym/mec/teacher/controller/TeacherCourseScheduleController.java
  6. 25 22
      mec-application/src/main/java/com/ym/mec/web/controller/EmployeeController.java
  7. 140 0
      mec-application/src/main/java/com/ym/mec/web/controller/StudentCoursewarePlayRecordController.java
  8. 19 26
      mec-application/src/main/java/com/ym/mec/web/controller/education/ImGroupNoticeController.java
  9. 9 1
      mec-application/src/main/resources/exportColumnMapper.ini
  10. 3 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/CourseScheduleDao.java
  11. 8 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/ImGroupDao.java
  12. 3 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/ImGroupNoticeDao.java
  13. 6 6
      mec-biz/src/main/java/com/ym/mec/biz/dal/dto/TeacherClassCourseSchudeleDto.java
  14. 52 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/entity/StudentCoursewarePlayRecord.java
  15. 2 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/enums/ExportEnum.java
  16. 2 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/enums/ExportTypeEnum.java
  17. 34 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/mapper/StudentCoursewarePlayRecordMapper.java
  18. 177 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/wrapper/StudentCoursewarePlayRecordWrapper.java
  19. 1 1
      mec-biz/src/main/java/com/ym/mec/biz/service/ClassGroupService.java
  20. 1 1
      mec-biz/src/main/java/com/ym/mec/biz/service/CourseScheduleService.java
  21. 2 1
      mec-biz/src/main/java/com/ym/mec/biz/service/EmployeeService.java
  22. 5 0
      mec-biz/src/main/java/com/ym/mec/biz/service/ImGroupNoticeService.java
  23. 50 0
      mec-biz/src/main/java/com/ym/mec/biz/service/StudentCoursewarePlayRecordService.java
  24. 11 4
      mec-biz/src/main/java/com/ym/mec/biz/service/im/impl/ImGroupCoreServiceImpl.java
  25. 5 5
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/ClassGroupServiceImpl.java
  26. 49 7
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/CourseScheduleServiceImpl.java
  27. 178 197
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/EmployeeServiceImpl.java
  28. 22 0
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/ExportServiceImpl.java
  29. 0 2
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/GroupClassServiceImpl.java
  30. 28 9
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/ImGroupNoticeServiceImpl.java
  31. 0 6
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/ImGroupServiceImpl.java
  32. 1 1
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/IndexBaseMonthDataServiceImpl.java
  33. 132 0
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/StudentCoursewarePlayRecordServiceImpl.java
  34. 1 1
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/StudentPaymentOrderServiceImpl.java
  35. 1 1
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/SysMessageServiceImpl.java
  36. 1 1
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/UserMusicServiceImpl.java
  37. 16 4
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/VipGroupServiceImpl.java
  38. 4 3
      mec-biz/src/main/resources/config/mybatis/ClassGroupMapper.xml
  39. 61 37
      mec-biz/src/main/resources/config/mybatis/CourseScheduleMapper.xml
  40. 20 1
      mec-biz/src/main/resources/config/mybatis/ImGroupMapper.xml
  41. 5 2
      mec-biz/src/main/resources/config/mybatis/ImGroupNoticeMapper.xml
  42. 70 0
      mec-biz/src/main/resources/config/mybatis/StudentCoursewarePlayRecordMapper.xml

+ 2 - 1
mec-application/src/main/java/com/ym/mec/config/ResourceServerConfig.java

@@ -52,7 +52,8 @@ public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
 
                 //teacher
                         "/api-teacher/teacher/queryStudentApply", "/api-teacher/teacher/querySubByMusicGroupId", "/api-teacher/studentRegistration/updateSubject",
-                        "/api-teacher/studyReport/createEvaluate", "/api-teacher/teacherOrder/*", "/api-teacher/teacher/getRegisterOrPreList", "/api-teacher/teacherContract/callback", "/api-teacher/eduPracticeGroup/queryOrderInfo",
+                        "/api-teacher/studyReport/createEvaluate", "/api-teacher/teacherOrder/*", "/api-teacher/teacher/getRegisterOrPreList",
+                        "/api-teacher/teacherContract/callback", "/api-teacher/eduPracticeGroup/queryOrderInfo", "/api-teacher/open/**",
 
                 //web
                         "/api-web/classGroup/highClassGroups", "/api-web/api/*", "/api-web/appVersionInfo/queryByPlatform", "/api-web/eduDegree/*",

+ 98 - 0
mec-application/src/main/java/com/ym/mec/student/controller/StudentCoursewarePlayRecordController.java

@@ -0,0 +1,98 @@
+package com.ym.mec.student.controller;
+
+
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.microsvc.toolkit.common.response.paging.QueryInfo;
+import com.ym.mec.auth.api.client.SysUserFeignService;
+import com.ym.mec.auth.api.entity.SysUser;
+import com.ym.mec.biz.dal.entity.StudentCoursewarePlayRecord;
+import com.ym.mec.biz.dal.wrapper.StudentCoursewarePlayRecordWrapper;
+import com.ym.mec.biz.service.StudentCoursewarePlayRecordService;
+import com.ym.mec.common.controller.BaseController;
+import com.ym.mec.common.entity.HttpResponseResult;
+import com.ym.mec.common.page.PageInfo;
+import com.ym.mec.common.page.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+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.annotation.Resource;
+
+@Slf4j
+@Validated
+@RestController
+@RequestMapping("${app-config.url.student:}/studentCoursewarePlayRecord")
+@Api(tags = "学生课件播放统计记录")
+public class StudentCoursewarePlayRecordController extends BaseController {
+
+    @Resource
+    private SysUserFeignService sysUserFeignService;
+
+    @Autowired
+    private StudentCoursewarePlayRecordService studentCoursewarePlayRecordService;
+
+    @ApiOperation(value = "详情", notes = "学生课件播放统计记录-根据详情ID查询单条, 传入id")
+    @PreAuthorize("@pcs.hasPermissions('studentCoursewarePlayRecord/detail')")
+//    @GetMapping("/detail/{id}")
+    public HttpResponseResult<StudentCoursewarePlayRecord> detail(@PathVariable("id") Long id) {
+
+        StudentCoursewarePlayRecord wrapper = studentCoursewarePlayRecordService.detail(id);
+
+        return succeed(wrapper);
+    }
+
+    @ApiOperation(value = "查询分页", notes = "学生课件播放统计记录- 传入 StudentCoursewarePlayRecordWrapper.StudentCoursewarePlayRecordQuery")
+    @PreAuthorize("@pcs.hasPermissions('studentCoursewarePlayRecord/page')")
+//    @PostMapping("/page")
+    public HttpResponseResult<PageInfo<StudentCoursewarePlayRecord>> page(@RequestBody StudentCoursewarePlayRecordWrapper.StudentCoursewarePlayRecordQuery query) {
+
+        IPage<StudentCoursewarePlayRecord> pages = studentCoursewarePlayRecordService.selectPage(QueryInfo.getPage(query), query);
+
+        return succeed(PageUtil.pageInfo(pages));
+    }
+
+    @ApiOperation(value = "新增", notes = "学生课件播放统计记录- 传入 StudentCoursewarePlayRecordWrapper.StudentCoursewarePlayRecord")
+    @PostMapping("/save")
+    public HttpResponseResult<JSONObject> add(@Validated @RequestBody StudentCoursewarePlayRecordWrapper.StudentCoursewarePlayRecordSave studentCoursewarePlayRecord) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed("用户信息获取失败");
+        }
+        studentCoursewarePlayRecord.setUserId(sysUser.getId());
+        studentCoursewarePlayRecord.setOrganizationId(sysUser.getOrganId());
+        // 新增数据
+        studentCoursewarePlayRecordService.save(studentCoursewarePlayRecord);
+
+        return succeed();
+    }
+
+    @ApiOperation(value = "修改", notes = "学生课件播放统计记录- 传入 StudentCoursewarePlayRecordWrapper.StudentCoursewarePlayRecord")
+    @PreAuthorize("@pcs.hasPermissions('studentCoursewarePlayRecord/update')")
+//    @PostMapping("/update")
+    public HttpResponseResult<JSONObject> update(@Validated @RequestBody StudentCoursewarePlayRecord studentCoursewarePlayRecord) {
+
+        // 更新数据
+        studentCoursewarePlayRecordService.updateById(studentCoursewarePlayRecord);
+
+        return succeed();
+    }
+
+    @ApiOperation(value = "删除", notes = "学生课件播放统计记录- 传入id")
+    @PreAuthorize("@pcs.hasPermissions('studentCoursewarePlayRecord/remove')")
+//    @PostMapping("/remove")
+    public HttpResponseResult<Boolean> remove(@RequestParam Long id) {
+
+        return succeed(studentCoursewarePlayRecordService.removeById(id));
+    }
+}

+ 1 - 1
mec-application/src/main/java/com/ym/mec/student/controller/StudentVipGroupController.java

@@ -82,7 +82,7 @@ public class StudentVipGroupController extends BaseController {
 
     @ApiOperation(value = "检测vip课成能否购买")
     @GetMapping(value = "/enableBuyGroup")
-    public HttpResponseResult enableBuyGroup(Long vipGroupId, String groupType){
+    public HttpResponseResult<Object> enableBuyGroup(Long vipGroupId, String groupType){
         vipGroupService.enableBuyVipGroup(vipGroupId,sysUserService.getUserId(),groupType);
         return succeed();
     }

+ 19 - 29
mec-application/src/main/java/com/ym/mec/teacher/controller/ClassGroupController.java

@@ -1,30 +1,24 @@
 package com.ym.mec.teacher.controller;
 
-import com.ym.mec.auth.api.client.SysUserFeignService;
-import com.ym.mec.auth.api.entity.SysUser;
 import com.ym.mec.biz.dal.dao.CourseScheduleStudentPaymentDao;
-import com.ym.mec.biz.dal.dto.BasicUserDto;
-import com.ym.mec.biz.dal.dto.StudentSubjectDto;
+import com.ym.mec.biz.dal.dto.*;
 import com.ym.mec.biz.dal.entity.CourseScheduleEvaluate;
 import com.ym.mec.biz.dal.page.CourseScheduleQueryInfo;
 import com.ym.mec.biz.dal.page.ImGroupNoticeQueryInfo;
-import com.ym.mec.biz.service.ClassGroupService;
-import com.ym.mec.biz.service.CourseScheduleEvaluateService;
-import com.ym.mec.biz.service.ImGroupNoticeService;
-import com.ym.mec.biz.service.SubjectService;
+import com.ym.mec.biz.service.*;
 import com.ym.mec.common.controller.BaseController;
 import com.ym.mec.common.entity.HttpResponseResult;
+import com.ym.mec.common.page.PageInfo;
 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.util.CollectionUtils;
 import org.springframework.web.bind.annotation.*;
 
+import javax.annotation.Resource;
 import java.util.List;
 import java.util.Map;
-import java.util.Objects;
 import java.util.Set;
 import java.util.stream.Collectors;
 
@@ -36,34 +30,34 @@ import java.util.stream.Collectors;
 @RequestMapping("${app-config.url.teacher:}/classGroup")
 @RestController
 public class ClassGroupController extends BaseController {
-    @Autowired
+    @Resource
     private ClassGroupService classGroupService;
-    @Autowired
+    @Resource
     private CourseScheduleEvaluateService courseScheduleEvaluateService;
-    @Autowired
-    private SysUserFeignService sysUserFeignService;
-    @Autowired
+    @Resource
+    private SysUserService sysUserService;
+    @Resource
     private ImGroupNoticeService imGroupNoticeService;
-    @Autowired
+    @Resource
     private CourseScheduleStudentPaymentDao courseScheduleStudentPaymentDao;
-    @Autowired
+    @Resource
     private SubjectService subjectService;
 
     @ApiOperation(value = "教师关联班级获取")
     @GetMapping("/findTeacherClassGroups")
-    public Object findTeacherClassGroups(String type,String status, String groupName){
+    public HttpResponseResult<List<TeacherClassGroupDto>> findTeacherClassGroups(String type, String status, String groupName){
         return succeed(classGroupService.findTeacherClassGroups(type,status,groupName));
     }
 
     @ApiOperation(value = "获取教师班级详情界面头部信息")
     @GetMapping("/findTeacherClassGroupInfo")
-    public Object findTeacherClassGroupInfo(@ApiParam(value = "班级编号", required = true)Integer classGroupId){
+    public HttpResponseResult<TeacherClassHeadInfo> findTeacherClassGroupInfo(@ApiParam(value = "班级编号", required = true)Integer classGroupId){
         return succeed(classGroupService.findTeacherClassGroupInfo(classGroupId));
     }
 
     @ApiOperation(value = "获取班级对应学生列表")
     @GetMapping("/findTeacherClassStudents")
-    public Object findTeacherClassStudents(CourseScheduleQueryInfo queryInfo){
+    public HttpResponseResult<PageInfo<TeacherClassStudentDto>> findTeacherClassStudents(CourseScheduleQueryInfo queryInfo){
         return succeed(classGroupService.findTeacherClassStudents(queryInfo));
     }
 
@@ -93,24 +87,20 @@ public class ClassGroupController extends BaseController {
 
     @ApiOperation(value = "提交陪练报告")
     @PostMapping(value = "/addStudyReport")
-    public HttpResponseResult addStudyReport(@RequestBody CourseScheduleEvaluate courseScheduleEvaluate) {
-        SysUser sysUser = sysUserFeignService.queryUserInfo();
-        if(Objects.isNull(sysUser)){
-            return failed(HttpStatus.FORBIDDEN,"请登录");
-        }
+    public HttpResponseResult<Boolean> addStudyReport(@RequestBody CourseScheduleEvaluate courseScheduleEvaluate) {
         if(courseScheduleEvaluate.getClassGroupId()==null || courseScheduleEvaluate.getClassGroupId()<0){
             return failed(HttpStatus.BAD_REQUEST,"班级id必须大于0");
         }
         if(courseScheduleEvaluate.getItem()==null || courseScheduleEvaluate.getItem().isEmpty()){
             return failed(HttpStatus.BAD_REQUEST,"课程评价选项不能为空");
         }
-        courseScheduleEvaluate.setTeacherId(sysUser.getId());
+        courseScheduleEvaluate.setTeacherId(sysUserService.getUserId());
         return succeed(courseScheduleEvaluateService.addStudyReport(courseScheduleEvaluate));
     }
 
     @ApiOperation(value = "根据群编号,获取用户群名片")
     @GetMapping("/getUserInfoWithUserId")
-    public Object getUserInfoWithUserId(Integer groupId,Integer userId) {
+    public HttpResponseResult<Map<String,Object>> getUserInfoWithUserId(Integer groupId,Integer userId) {
         if (groupId == null || userId == null) {
             return failed("参数校验错误");
         }
@@ -119,13 +109,13 @@ public class ClassGroupController extends BaseController {
 
     @ApiOperation(value = "获取最新一条群公告")
     @RequestMapping("/getNewNotice")
-    public Object getNewNotice(String groupId) {
+    public HttpResponseResult<ImGroupNoticeDto> getNewNotice(String groupId) {
         return succeed(imGroupNoticeService.queryLatestNotice(groupId));
     }
 
     @ApiOperation(value = "获取群公告列表")
     @RequestMapping("/queryNoticePage")
-    public Object queryPage(ImGroupNoticeQueryInfo queryInfo) {
+    public HttpResponseResult<PageInfo<ImGroupNoticeDto>> queryPage(ImGroupNoticeQueryInfo queryInfo) {
         return succeed(imGroupNoticeService.queryPage(queryInfo));
     }
 

+ 1 - 1
mec-application/src/main/java/com/ym/mec/teacher/controller/TeacherCourseScheduleController.java

@@ -201,7 +201,7 @@ public class TeacherCourseScheduleController extends BaseController {
     @ApiOperation(value = "获取老师指定班级的排课")
     @GetMapping("/queryTeacherVipClassCourseSchedule")
     public Object queryTeacherVipClassCourseSchedule(CourseScheduleQueryInfo queryInfo){
-        Map<String,Object> result = new HashMap<>();
+        Map<String,Object> result = new HashMap<>(2);
         queryInfo.setUserId(sysUserService.getUserId().longValue());
         result.put("rows",scheduleService.queryTeacherVipClassCourseSchedule(queryInfo));
         result.put("appealHoursRange",4);

+ 25 - 22
mec-application/src/main/java/com/ym/mec/web/controller/EmployeeController.java

@@ -2,8 +2,10 @@ package com.ym.mec.web.controller;
 
 import com.ym.mec.auth.api.entity.SysUser;
 import com.ym.mec.biz.dal.dao.EmployeeDao;
+import com.ym.mec.biz.dal.dto.EmployeeDto;
 import com.ym.mec.biz.dal.dto.EmployeeLevelDto;
 import com.ym.mec.biz.dal.dto.SysEmployeePositionDto;
+import com.ym.mec.biz.dal.dto.SysUserDto;
 import com.ym.mec.biz.dal.entity.Employee;
 import com.ym.mec.biz.dal.enums.EmployeeOperateEnum;
 import com.ym.mec.biz.dal.enums.ParamEnum;
@@ -21,14 +23,15 @@ import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
 import org.springframework.web.bind.annotation.*;
 
+import javax.annotation.Resource;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.stream.Collectors;
 
 /**
@@ -41,25 +44,25 @@ import java.util.stream.Collectors;
 @RestController
 public class EmployeeController extends BaseController {
 
-    @Autowired
+    @Resource
     private EmployeeService employeeService;
-    @Autowired
+    @Resource
     private SysUserService sysUserService;
-    @Autowired
+    @Resource
     private StudentManageService studentManageService;
-    @Autowired
+    @Resource
     private OrganizationService organizationService;
-    @Autowired
+    @Resource
     private EmployeeDao employeeDao;
-    @Autowired
+    @Resource
     private SysEmployeePositionService sysEmployeePositionService;
-    @Autowired
+    @Resource
     private ImGroupCoreService imGroupCoreService;
 
     @ApiOperation(value = "获取员工列表(基本信息)")
     @GetMapping("/queryEmployeeBasicInfo")
     @PreAuthorize("@pcs.hasPermissions('employee/queryEmployeeBasicInfo')")
-    public Object queryEmployeeBasicInfo(UserBasicQueryInfo queryInfo){
+    public HttpResponseResult<PageInfo<SysUserDto>> queryEmployeeBasicInfo(UserBasicQueryInfo queryInfo){
         queryInfo.setOrganId(organizationService.getEmployeeOrgan(queryInfo.getOrganId()));
         return succeed(employeeService.queryEmployeeBasicInfo(queryInfo));
     }
@@ -67,7 +70,7 @@ public class EmployeeController extends BaseController {
     @ApiOperation(value = "根据部门获取下面的员工")
     @GetMapping("/queryEmployByOrganId")
     @PreAuthorize("@pcs.hasPermissions('employee/queryEmployByOrganId')")
-    public HttpResponseResult<PageInfo> queryEmployByOrganId(EmployeeQueryInfo queryInfo) throws Exception {
+    public HttpResponseResult<PageInfo<EmployeeDto>> queryEmployByOrganId(EmployeeQueryInfo queryInfo) throws Exception {
         queryInfo.setOrganId(organizationService.getEmployeeOrgan(queryInfo.getOrganId()));
         return succeed(employeeService.queryEmployByOrganId(queryInfo));
     }
@@ -75,7 +78,7 @@ public class EmployeeController extends BaseController {
     @ApiOperation(value = "获取平台的员工")
     @GetMapping("/queryPlatformEmploy")
     @PreAuthorize("@pcs.hasPermissions('employee/queryPlatformEmploy')")
-    public Object queryPlatformEmploy(EmployeeQueryInfo queryInfo) throws Exception {
+    public HttpResponseResult<PageInfo<EmployeeDto>> queryPlatformEmploy(EmployeeQueryInfo queryInfo) throws Exception {
         queryInfo.setOrganId(null);
         queryInfo.setTenantId(-1);
         return succeed(employeeService.queryEmployByOrganId(queryInfo));
@@ -84,7 +87,7 @@ public class EmployeeController extends BaseController {
     @ApiOperation(value = "员工操作")
     @PostMapping("/employeeOperate")
     @PreAuthorize("@pcs.hasPermissions('employee/employeeOperate')")
-    public HttpResponseResult employeeOperate(Integer employeeId, EmployeeOperateEnum operate){
+    public HttpResponseResult<Object> employeeOperate(Integer employeeId, EmployeeOperateEnum operate){
         employeeService.employeeOperate(employeeId,operate);
         return succeed();
     }
@@ -92,7 +95,7 @@ public class EmployeeController extends BaseController {
     @ApiOperation(value = "密码重置")
     @PostMapping("/resetPassword")
     @PreAuthorize("@pcs.hasPermissions('employee/resetPassword')")
-    public HttpResponseResult resetPassword(Integer userId){
+    public HttpResponseResult<Object> resetPassword(Integer userId){
         employeeService.resetPassword(userId);
         return succeed();
     }
@@ -107,7 +110,7 @@ public class EmployeeController extends BaseController {
     @ApiOperation(value = "修改指定的教务老师关联")
     @PostMapping("/updateEducationTeacherId")
     @PreAuthorize("@pcs.hasPermissions('employee/updateEducationTeacherId')")
-    public HttpResponseResult updateEducationTeacherId(Integer currentUserId,Integer targetUserId){
+    public HttpResponseResult<Object> updateEducationTeacherId(Integer currentUserId, Integer targetUserId){
         employeeService.updateEducationTeacherId(currentUserId,targetUserId);
         return succeed();
     }
@@ -115,7 +118,7 @@ public class EmployeeController extends BaseController {
     @ApiOperation(value = "新增员工")
     @PostMapping("/add")
     @PreAuthorize("@pcs.hasPermissions('employee/add')")
-    public HttpResponseResult add(@RequestBody Employee employee) throws Exception {
+    public HttpResponseResult<Object> add(@RequestBody Employee employee) throws Exception {
         employeeService.add(employee);
         return succeed();
     }
@@ -123,7 +126,7 @@ public class EmployeeController extends BaseController {
     @ApiOperation(value = "修改员工")
     @PostMapping("/update")
     @PreAuthorize("@pcs.hasPermissions('employee/update')")
-    public Object update(@RequestBody Employee employee) {
+    public HttpResponseResult<Object> update(@RequestBody Employee employee) {
         TenantContextHolder.setTenantId(employee.getTenantId());
         employee.setUpdateTime(new Date());
         employeeService.updateEmployee(employee);
@@ -133,7 +136,7 @@ public class EmployeeController extends BaseController {
     @ApiOperation(value = "修改员工角色")
     @PostMapping("/updateRole")
     @PreAuthorize("@pcs.hasPermissions('employee/updateRole')")
-    public Object updateRole(@RequestBody Employee employee) {
+    public HttpResponseResult<Object> updateRole(@RequestBody Employee employee) {
         TenantContextHolder.setTenantId(employee.getTenantId());
         employee.setUpdateTime(new Date());
         employeeService.updateEmployeeRole(employee);
@@ -143,14 +146,14 @@ public class EmployeeController extends BaseController {
     @ApiOperation(value = "修改员工")
     @PostMapping("/simpleUpdate")
     @PreAuthorize("@pcs.hasPermissions('employee/simpleUpdate')")
-    public HttpResponseResult simpleUpdate(@RequestBody Employee employee) {
+    public HttpResponseResult<Object> simpleUpdate(@RequestBody Employee employee) {
         employeeService.simpleUpdate(employee);
         return succeed();
     }
 
     @ApiOperation(value = "修改用户")
     @PostMapping("/updateUser")
-    public HttpResponseResult update(SysUser sysUser) {
+    public HttpResponseResult<Object> update(SysUser sysUser) {
         SysUser user = sysUserService.getUser();
         Date date = new Date();
         sysUser.setId(user.getId());
@@ -168,7 +171,7 @@ public class EmployeeController extends BaseController {
 
     @ApiOperation(value = "获取用户信息")
     @GetMapping("/queryUserInfo")
-    public HttpResponseResult apiQueryUserInfo() {
+    public HttpResponseResult<SysUser> apiQueryUserInfo() {
         SysUser sysUser = sysUserService.getUser();
         Employee employee = employeeService.get(sysUser.getId());
         sysUser.setOrganName(organizationService.getOrganName(employee.getOrganIdList()));
@@ -221,14 +224,14 @@ public class EmployeeController extends BaseController {
     @ApiOperation(value = "获取所选用户离职所需交接信息")
     @GetMapping("/levelDetail")
     @PreAuthorize("@pcs.hasPermissions('employee/levelDetail')")
-    public HttpResponseResult levelDetail(Integer userId){
+    public HttpResponseResult<Map<String, Object>> levelDetail(Integer userId){
         return succeed(employeeService.levelDetail(userId));
     }
 
     @ApiOperation(value = "员工离职交接")
     @PostMapping("/level")
     @PreAuthorize("@pcs.hasPermissions('employee/level')")
-    public HttpResponseResult level(@RequestBody List<EmployeeLevelDto> employeeLevelDtos){
+    public HttpResponseResult<Object> level(@RequestBody List<EmployeeLevelDto> employeeLevelDtos){
         employeeService.level(employeeLevelDtos);
         return succeed();
     }

+ 140 - 0
mec-application/src/main/java/com/ym/mec/web/controller/StudentCoursewarePlayRecordController.java

@@ -0,0 +1,140 @@
+package com.ym.mec.web.controller;
+
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.microsvc.toolkit.common.response.paging.QueryInfo;
+import com.ym.mec.biz.dal.entity.StudentCoursewarePlayRecord;
+import com.ym.mec.biz.dal.enums.ExportEnum;
+import com.ym.mec.biz.dal.wrapper.StudentCoursewarePlayRecordWrapper;
+import com.ym.mec.biz.service.ExportService;
+import com.ym.mec.biz.service.OrganizationService;
+import com.ym.mec.biz.service.StudentCoursewarePlayRecordService;
+import com.ym.mec.common.controller.BaseController;
+import com.ym.mec.common.entity.HttpResponseResult;
+import com.ym.mec.common.page.PageInfo;
+import com.ym.mec.common.page.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.beanutils.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+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.servlet.http.HttpServletResponse;
+import java.util.List;
+import java.util.Map;
+
+@Slf4j
+@Validated
+@RestController
+@RequestMapping("${app-config.url.web:}/studentCoursewarePlayRecord")
+@Api(tags = "学生课件播放统计记录")
+public class StudentCoursewarePlayRecordController extends BaseController {
+
+    @Autowired
+    private StudentCoursewarePlayRecordService studentCoursewarePlayRecordService;
+
+    @Autowired
+    private ExportService exportService;
+
+    @Autowired
+    private OrganizationService organizationService;
+
+    @ApiOperation(value = "详情", notes = "学生课件播放统计记录-根据详情ID查询单条, 传入id")
+    @PreAuthorize("@pcs.hasPermissions('studentCoursewarePlayRecord/detail')")
+//    @GetMapping("/detail/{id}")
+    public HttpResponseResult<StudentCoursewarePlayRecord> detail(@PathVariable("id") Long id) {
+
+        StudentCoursewarePlayRecord wrapper = studentCoursewarePlayRecordService.detail(id);
+
+        return succeed(wrapper);
+    }
+
+    @ApiOperation(value = "查询分页", notes = "学生课件播放统计记录- 传入 StudentCoursewarePlayRecordWrapper.StudentCoursewarePlayRecordQuery")
+    @PreAuthorize("@pcs.hasPermissions('studentCoursewarePlayRecord/page')")
+//    @PostMapping("/page")
+    public HttpResponseResult<PageInfo<StudentCoursewarePlayRecord>> page(@RequestBody StudentCoursewarePlayRecordWrapper.StudentCoursewarePlayRecordQuery query) {
+
+        IPage<StudentCoursewarePlayRecord> pages = studentCoursewarePlayRecordService.selectPage(QueryInfo.getPage(query), query);
+
+        return succeed(PageUtil.pageInfo(pages));
+    }
+
+    @ApiOperation(value = "新增", notes = "学生课件播放统计记录- 传入 StudentCoursewarePlayRecordWrapper.StudentCoursewarePlayRecord")
+    @PreAuthorize("@pcs.hasPermissions('studentCoursewarePlayRecord/save')")
+//    @PostMapping("/save")
+    public HttpResponseResult<JSONObject> add(@Validated @RequestBody StudentCoursewarePlayRecordWrapper.StudentCoursewarePlayRecord studentCoursewarePlayRecord) {
+        return succeed();
+    }
+
+    @ApiOperation(value = "修改", notes = "学生课件播放统计记录- 传入 StudentCoursewarePlayRecordWrapper.StudentCoursewarePlayRecord")
+    @PreAuthorize("@pcs.hasPermissions('studentCoursewarePlayRecord/update')")
+//    @PostMapping("/update")
+    public HttpResponseResult<JSONObject> update(@Validated @RequestBody StudentCoursewarePlayRecord studentCoursewarePlayRecord) {
+
+        // 更新数据
+        studentCoursewarePlayRecordService.updateById(studentCoursewarePlayRecord);
+
+        return succeed();
+    }
+
+    @ApiOperation(value = "删除", notes = "学生课件播放统计记录- 传入id")
+    @PreAuthorize("@pcs.hasPermissions('studentCoursewarePlayRecord/remove')")
+//    @PostMapping("/remove")
+    public HttpResponseResult<Boolean> remove(@RequestParam Long id) {
+
+        return succeed(studentCoursewarePlayRecordService.removeById(id));
+    }
+
+    /**
+     * 练习统计
+     */
+    @PostMapping("/statList")
+    @PreAuthorize("@pcs.hasPermissions('studentCoursewarePlayRecord/statList')")
+    public HttpResponseResult<List<StudentCoursewarePlayRecordWrapper.StatQueryData>> statList(@RequestBody StudentCoursewarePlayRecordWrapper.StatQuery statQuery) {
+        statQuery.setOrganizationId(organizationService.getEmployeeOrgan(statQuery.getOrganizationId()));
+        return succeed(studentCoursewarePlayRecordService.statList(statQuery));
+    }
+
+
+    /**
+     * 练习统计导出
+     */
+    @PostMapping("/exportStatList")
+    @PreAuthorize("@pcs.hasPermissions('studentCoursewarePlayRecord/exportStatList')")
+    public HttpResponseResult exportStatList(@RequestBody StudentCoursewarePlayRecordWrapper.StatQuery statQuery) {
+        statQuery.setOrganizationId(organizationService.getEmployeeOrgan(statQuery.getOrganizationId()));
+        return exportService.getExportManageFuncMap().get(ExportEnum.VIDEO_PLAY_STAT).apply(JSON.parseObject(JSON.toJSONString(statQuery), Map.class));
+    }
+
+
+    /**
+     * 练习详情统计
+     */
+    @PostMapping("/statDetailPage")
+    @PreAuthorize("@pcs.hasPermissions('studentCoursewarePlayRecord/statDetailPage')")
+    public HttpResponseResult<PageInfo<StudentCoursewarePlayRecordWrapper.StatQueryData>> statDetailPage(@RequestBody StudentCoursewarePlayRecordWrapper.StatQuery statQuery) {
+        return succeed(PageUtil.pageInfo(studentCoursewarePlayRecordService.statDetailPage(statQuery)));
+    }
+
+    /**
+     * 练习统计详情导出
+     */
+    @PostMapping("/exportStatDetailPage")
+    @PreAuthorize("@pcs.hasPermissions('studentCoursewarePlayRecord/exportStatDetailPage')")
+    public HttpResponseResult exportStatDetailPage(@RequestBody StudentCoursewarePlayRecordWrapper.StatQuery statQuery) {
+        statQuery.setPage(1);
+        statQuery.setRows(9999);
+        return exportService.getExportManageFuncMap().get(ExportEnum.VIDEO_PLAY_DETAIL_STAT).apply(JSON.parseObject(JSON.toJSONString(statQuery), Map.class));
+    }
+}

+ 19 - 26
mec-application/src/main/java/com/ym/mec/web/controller/education/ImGroupNoticeController.java

@@ -1,17 +1,19 @@
 package com.ym.mec.web.controller.education;
 
-import com.ym.mec.auth.api.client.SysUserFeignService;
-import com.ym.mec.auth.api.entity.SysUser;
+import com.ym.mec.biz.dal.dto.ImGroupNoticeDto;
 import com.ym.mec.biz.dal.entity.ImGroupNotice;
 import com.ym.mec.biz.dal.page.ImGroupNoticeQueryInfo;
 import com.ym.mec.biz.service.ImGroupNoticeService;
+import com.ym.mec.biz.service.SysUserService;
 import com.ym.mec.common.controller.BaseController;
+import com.ym.mec.common.entity.HttpResponseResult;
+import com.ym.mec.common.page.PageInfo;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
+import javax.annotation.Resource;
 import java.util.Date;
 
 /**
@@ -23,55 +25,46 @@ import java.util.Date;
 @RestController
 public class ImGroupNoticeController extends BaseController {
 
-    @Autowired
+    @Resource
     private ImGroupNoticeService imGroupNoticeService;
-    @Autowired
-    private SysUserFeignService sysUserFeignService;
+    @Resource
+    private SysUserService sysUserService;
 
     @ApiOperation(value = "新增")
     @RequestMapping("/add")
-//    @PreAuthorize("@pcs.hasPermissions('imGroupNotice/add','system')")
-    public Object add(ImGroupNotice imGroupNotice ) {
-        SysUser sysUser = sysUserFeignService.queryUserInfo();
-        if(sysUser == null){
-            return failed("获取用户信息失败");
+    public HttpResponseResult<Long> add(ImGroupNotice imGroupNotice ) {
+        imGroupNotice.setOperatorId(sysUserService.getUserId().longValue());
+        if(imGroupNotice.isIsTop()){
+            //置顶取消
+            imGroupNoticeService.getDao().updateTop(imGroupNotice.getImGroupId(),false);
         }
-        imGroupNotice.setOperatorId(sysUser.getId().longValue());
         return succeed(imGroupNoticeService.insert(imGroupNotice));
     }
 
     @ApiOperation(value = "修改")
     @RequestMapping("/update")
-//    @PreAuthorize("@pcs.hasPermissions('imGroupNotice/update','system')")
-    public Object update(ImGroupNotice imGroupNotice ) {
-        SysUser sysUser = sysUserFeignService.queryUserInfo();
-        if(sysUser == null){
-            return failed("获取用户信息失败");
-        }
-        imGroupNotice.setOperatorId(sysUser.getId().longValue());
+    public HttpResponseResult<Object> update(ImGroupNotice imGroupNotice ) {
+        imGroupNotice.setOperatorId(sysUserService.getUserId().longValue());
         imGroupNotice.setUpdateTime(new Date());
-        imGroupNoticeService.update(imGroupNotice);
+        imGroupNoticeService.modify(imGroupNotice);
         return succeed();
     }
 
     @ApiOperation(value = "获取最新一条群公告")
     @RequestMapping("/getNewNotice")
-//    @PreAuthorize("@pcs.hasPermissions('imGroupNotice/getNewNotice','system')")
-    public Object getNewNotice(String groupId) {
+    public HttpResponseResult<ImGroupNoticeDto> getNewNotice(String groupId) {
         return succeed(imGroupNoticeService.queryLatestNotice(groupId));
     }
 
     @ApiOperation(value = "获取群公告列表")
     @RequestMapping("/queryNoticePage")
-//    @PreAuthorize("@pcs.hasPermissions('imGroupNotice/queryNoticePage','system')")
-    public Object queryPage(ImGroupNoticeQueryInfo queryInfo) {
+    public HttpResponseResult<PageInfo<ImGroupNoticeDto>> queryPage(ImGroupNoticeQueryInfo queryInfo) {
         return succeed(imGroupNoticeService.queryPage(queryInfo));
     }
 
     @ApiOperation(value = "删除")
     @RequestMapping("/del")
-//    @PreAuthorize("@pcs.hasPermissions('imGroupNotice/del','system')")
-    public Object del(Long id) {
+    public HttpResponseResult<Object> del(Long id) {
         imGroupNoticeService.delete(id);
         return succeed();
     }

+ 9 - 1
mec-application/src/main/resources/exportColumnMapper.ini

@@ -400,4 +400,12 @@ fieldColumns = ["organName","musicGroupId","musicGroupName","studentId","student
 
 [平衡关系(分表)-乐团退团学员]
 headColumns = ["分部","乐团编号","乐团名称","学员编号","学员名称"]
-fieldColumns = ["organName","musicGroupId","musicGroupName","studentId","studentName"]
+fieldColumns = ["organName","musicGroupId","musicGroupName","studentId","studentName"]
+
+[云课堂统计导出]
+headColumns = ["分部名称","会员人数","无练习人数","0-10分钟","10-60分钟","60-120分钟","120-240分钟",">240分钟","平均时长(分钟)"]
+fieldColumns = ["organizationName","memberNum","noPlayNum","playTimeLess10","playTimeLess60","playTimeLess120","playTimeLess240","playTimeRather240","avgPlayTime"]
+
+[云课堂统计详情导出]
+headColumns = ["声部老师","会员人数","无练习人数","0-10分钟","10-60分钟","60-120分钟","120-240分钟",">240分钟","平均时长(分钟)"]
+fieldColumns = ["teacherName","memberNum","noPlayNum","playTimeLess10","playTimeLess60","playTimeLess120","playTimeLess240","playTimeRather240","avgPlayTime"]

+ 3 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/CourseScheduleDao.java

@@ -2096,4 +2096,7 @@ public interface CourseScheduleDao extends BaseDAO<Long, CourseSchedule> {
 
     //获取最近的一节线下课
     CourseScheduleDto getRecentCourseSchedule(@Param("userId") Integer userId, @Param("courseId") Long courseId);
+
+    //获取老师可以查看的班级课程列表
+    List<Long> queryTeacherCanViewClassCourseSchedule(@Param("classGroupId") Long classGroupId, @Param("userId") Long userId);
 }

+ 8 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/ImGroupDao.java

@@ -7,8 +7,10 @@ import com.ym.mec.biz.dal.entity.ImHistoryMessage;
 import com.ym.mec.biz.dal.enums.EFriendRoleType;
 import com.ym.mec.biz.dal.wrapper.ImGroupWrapper;
 import com.ym.mec.common.dal.BaseDAO;
+import com.ym.mec.common.entity.ImGroupModel;
 import org.apache.ibatis.annotations.Param;
 
+import java.util.Collection;
 import java.util.List;
 
 public interface ImGroupDao extends BaseDAO<String, ImGroup> {
@@ -98,4 +100,10 @@ public interface ImGroupDao extends BaseDAO<String, ImGroup> {
      * @param info
      */
     void updateStatus(@Param("info") List<ImHistoryMessage> info);
+
+    //获取相应角色的衔接群
+    List<ImGroupModel> queryUserGroupList(@Param("transferUserId") Integer transferUserId,
+                                          @Param("userId") Integer userId,
+                                          @Param("roleType") String roleType,
+                                          @Param("organId") Integer organId);
 }

+ 3 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/ImGroupNoticeDao.java

@@ -6,6 +6,7 @@ import java.util.Map;
 import com.ym.mec.biz.dal.dto.ImGroupNoticeDto;
 import com.ym.mec.biz.dal.entity.ImGroupNotice;
 import com.ym.mec.common.dal.BaseDAO;
+import org.apache.ibatis.annotations.Param;
 
 public interface ImGroupNoticeDao extends BaseDAO<Long, ImGroupNotice> {
 
@@ -19,4 +20,6 @@ public interface ImGroupNoticeDao extends BaseDAO<Long, ImGroupNotice> {
 	List<ImGroupNoticeDto> queryForPage(Map<String, Object> params);
 	
 	int deleteByImGroupId(String imGroupId);
+
+    void updateTop(@Param("imGroupId") String imGroupId, @Param("topFlag") boolean topFlag);
 }

+ 6 - 6
mec-biz/src/main/java/com/ym/mec/biz/dal/dto/TeacherClassCourseSchudeleDto.java

@@ -17,7 +17,7 @@ public class TeacherClassCourseSchudeleDto {
     private Long id;
 
     @ApiModelProperty(value = "班级编号", required = false)
-    private Long classGroupId;
+    private Integer classGroupId;
 
     @ApiModelProperty(value = "课程编号")
     private Long courseScheduleId;
@@ -38,7 +38,7 @@ public class TeacherClassCourseSchudeleDto {
     private java.util.Date endClassTime;
 
     @ApiModelProperty(value = "实际上课教师")
-    private Long actualTeacherId;
+    private Integer actualTeacherId;
 
     @ApiModelProperty(value = "实际上课教师名称")
     private String actualTeacherName;
@@ -201,11 +201,11 @@ public class TeacherClassCourseSchudeleDto {
         this.leaveStudentNum = leaveStudentNum;
     }
 
-    public Long getClassGroupId() {
+    public Integer getClassGroupId() {
         return classGroupId;
     }
 
-    public void setClassGroupId(Long classGroupId) {
+    public void setClassGroupId(Integer classGroupId) {
         this.classGroupId = classGroupId;
     }
 
@@ -257,11 +257,11 @@ public class TeacherClassCourseSchudeleDto {
         this.endClassTime = endClassTime;
     }
 
-    public Long getActualTeacherId() {
+    public Integer getActualTeacherId() {
         return actualTeacherId;
     }
 
-    public void setActualTeacherId(Long actualTeacherId) {
+    public void setActualTeacherId(Integer actualTeacherId) {
         this.actualTeacherId = actualTeacherId;
     }
 

+ 52 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/entity/StudentCoursewarePlayRecord.java

@@ -0,0 +1,52 @@
+package com.ym.mec.biz.dal.entity;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Date;
+
+
+/**
+ * 学生课件播放统计记录
+ * 2024-07-04 14:48:14
+ */
+@Data
+@ApiModel(" StudentCoursewarePlayRecord-学生课件播放统计记录")
+@TableName("student_courseware_play_record")
+public class StudentCoursewarePlayRecord implements Serializable {
+
+    @ApiModelProperty("主键ID")
+    @TableId(value = "id_")
+    private Long id;
+
+    @ApiModelProperty("分部ID")
+    @TableField(value = "organization_id_")
+    private Integer organizationId;
+
+    @ApiModelProperty("用户编号")
+    @TableField(value = "user_id_")
+    private Integer userId;
+
+    @ApiModelProperty("播放时长,单位为秒")
+    @TableField(value = "play_time_")
+    private BigDecimal playTime;
+
+    @ApiModelProperty("创建的天")
+    @TableField(value = "create_date_")
+    private String createDate;
+
+    @ApiModelProperty("更新时间")
+    @TableField(value = "update_time_")
+    private Date updateTime;
+
+    @ApiModelProperty("创建时间")
+    @TableField(value = "create_time_")
+    private Date createTime;
+
+}

+ 2 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/enums/ExportEnum.java

@@ -103,6 +103,8 @@ public enum ExportEnum implements BaseEnum<String, ExportEnum> {
     EXPORT_BALANCED_RELATIONSHIP_STUDENT_INFO("EXPORT_BALANCED_RELATIONSHIP_STUDENT_INFO","平衡关系-学员情况总表"),
     EXPORT_BALANCED_RELATIONSHIP_STUDENT_NORMAL_DETAIL("EXPORT_BALANCED_RELATIONSHIP_STUDENT_NORMAL_DETAIL","平衡关系(分表)-乐团在读学员"),
     EXPORT_BALANCED_RELATIONSHIP_STUDENT_QUIT_DETAIL("EXPORT_BALANCED_RELATIONSHIP_STUDENT_QUIT_DETAIL","平衡关系(分表)-乐团退团学员"),
+    VIDEO_PLAY_STAT("VIDEO_PLAY_STAT","云课堂统计导出"),
+    VIDEO_PLAY_DETAIL_STAT("VIDEO_PLAY_DETAIL_STAT","云课堂统计详情导出"),
     ;
 
     private String code;

+ 2 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/enums/ExportTypeEnum.java

@@ -41,6 +41,8 @@ public enum ExportTypeEnum implements BaseEnum<Integer, ExportTypeEnum> {
 	EXPORT_BALANCED_RELATIONSHIP_STUDENT_INFO(34,"平衡关系-学员情况总表"),
 	EXPORT_BALANCED_RELATIONSHIP_STUDENT_NORMAL_DETAIL(35,"平衡关系(分表)-乐团在读学员"),
 	EXPORT_BALANCED_RELATIONSHIP_STUDENT_QUIT_DETAIL(36,"平衡关系(分表)-乐团退团学员"),
+	VIDEO_PLAY_STAT(37,"云课堂统计导出"),
+	VIDEO_PLAY_DETAIL_STAT(38,"云课堂统计详情导出"),
 	;
 
 	private Integer code;

+ 34 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/mapper/StudentCoursewarePlayRecordMapper.java

@@ -0,0 +1,34 @@
+package com.ym.mec.biz.dal.mapper;
+
+import java.util.List;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import org.apache.ibatis.annotations.Param;
+import org.springframework.stereotype.Repository;
+import com.ym.mec.biz.dal.entity.StudentCoursewarePlayRecord;
+import com.ym.mec.biz.dal.wrapper.StudentCoursewarePlayRecordWrapper;
+
+/**
+ * 学生课件播放统计记录
+ * 2024-07-04 14:48:14
+ */
+@Repository
+public interface StudentCoursewarePlayRecordMapper extends BaseMapper<StudentCoursewarePlayRecord> {
+
+    /**
+     * 分页查询
+     *
+     * @param page  IPage<StudentCoursewarePlayRecordWrapper.StudentCoursewarePlayRecord>
+     * @param param StudentCoursewarePlayRecordWrapper.StudentCoursewarePlayRecordQuery
+     * @return List<StudentCoursewarePlayRecordWrapper.StudentCoursewarePlayRecord>
+     */
+    List<StudentCoursewarePlayRecord> selectPage(@Param("page") IPage<StudentCoursewarePlayRecord> page, @Param("param") StudentCoursewarePlayRecordWrapper.StudentCoursewarePlayRecordQuery param);
+
+    void save(@Param("record") StudentCoursewarePlayRecord record);
+
+    List<StudentCoursewarePlayRecordWrapper.StatQueryData> statList(@Param("statQuery") StudentCoursewarePlayRecordWrapper.StatQuery statQuery);
+
+    List<StudentCoursewarePlayRecordWrapper.StatQueryData> statDetailPage(@Param("page") IPage<StudentCoursewarePlayRecordWrapper.StatQueryData> page,
+                                                                          @Param("statQuery") StudentCoursewarePlayRecordWrapper.StatQuery statQuery);
+}

+ 177 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/wrapper/StudentCoursewarePlayRecordWrapper.java

@@ -0,0 +1,177 @@
+package com.ym.mec.biz.dal.wrapper;
+
+import com.alibaba.fastjson.JSON;
+import com.microsvc.toolkit.common.response.paging.QueryInfo;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.math.BigDecimal;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+import java.util.Optional;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.apache.commons.lang3.StringUtils;
+
+import javax.validation.constraints.NotNull;
+
+/**
+ * 学生课件播放统计记录
+ * 2024-07-04 14:48:14
+ */
+@ApiModel(value = "StudentCoursewarePlayRecordWrapper对象", description = "学生课件播放统计记录查询对象")
+public class StudentCoursewarePlayRecordWrapper {
+
+    @Data
+    @Builder
+    @NoArgsConstructor
+    @AllArgsConstructor
+    @ApiModel(" StudentCoursewarePlayRecordQuery-学生课件播放统计记录")
+    public static class StudentCoursewarePlayRecordQuery implements QueryInfo {
+
+        @ApiModelProperty("当前页")
+        private Integer page;
+
+        @ApiModelProperty("分页行数")
+        private Integer rows;
+
+        @ApiModelProperty("关键字匹配")
+        private String keyword;
+
+        public String getKeyword() {
+            return Optional.ofNullable(keyword).filter(StringUtils::isNotBlank).orElse(null);
+        }
+
+        public String jsonString() {
+            return JSON.toJSONString(this);
+        }
+
+        public static StudentCoursewarePlayRecordQuery from(String json) {
+            return JSON.parseObject(json, StudentCoursewarePlayRecordQuery.class);
+        }
+    }
+
+
+    @Data
+    @ApiModel(" StudentCoursewarePlayRecord-学生课件播放统计记录")
+    public static class StudentCoursewarePlayRecord {
+
+        @ApiModelProperty("乐团ID")
+        private String musicGroupId;
+
+        @ApiModelProperty("用户编号")
+        private Long userId;
+
+        @ApiModelProperty("在读状态")
+        private Boolean readingStatus;
+
+        @ApiModelProperty("播放时长,单位为秒")
+        private Float playTime;
+
+        public String jsonString() {
+            return JSON.toJSONString(this);
+        }
+
+        public static StudentCoursewarePlayRecord from(String json) {
+            return JSON.parseObject(json, StudentCoursewarePlayRecord.class);
+        }
+    }
+
+    @Data
+    @ApiModel(" StudentCoursewarePlayRecord-学生课件播放统计记录")
+    public static class StudentCoursewarePlayRecordSave {
+
+        @ApiModelProperty(value = "用户编号",hidden = true)
+        private Integer userId;
+
+        @ApiModelProperty(hidden = true)
+        private Integer organizationId;
+
+        @ApiModelProperty("播放时长,单位为秒")
+        @NotNull
+        private BigDecimal playTime;
+
+    }
+
+
+    @Data
+    @ApiModel("云课堂观看统计查询")
+    public static class StatQuery implements QueryInfo {
+
+        @ApiModelProperty("当前页")
+        private Integer page;
+
+        @ApiModelProperty("分页行数")
+        private Integer rows;
+
+        @ApiModelProperty("开始时间")
+        private Date startTime;
+
+        @ApiModelProperty("结束时间")
+        private Date endTime;
+
+        @ApiModelProperty("分部ID")
+        private String organizationId;
+
+        @ApiModelProperty("排序值,1:会员,2:无练习,3:10分钟,4:60分钟,5:120分钟,6:240分钟,7:>240分钟,8:平均时长")
+        private Integer sort = 1;
+
+        @ApiModelProperty("声降序,true:升序,false:降序")
+        private Boolean asc = false;
+
+        @ApiModelProperty(hidden = true)
+        private String sortBy;
+
+        @ApiModelProperty(hidden = true)
+        private static List<String> sortKeys = Arrays.asList("memberNum", "noPlayNum", "playTimeLess10", "playTimeLess60", "playTimeLess120", "playTimeLess240", "playTimeRather240", "avgPlayTime");
+
+        public String getSortBy() {
+            String key = sortKeys.get(getSort() > sortKeys.size() ? 0 : getSort() - 1);
+            return key + (asc ? " asc" : " desc");
+        }
+    }
+
+    @Data
+    @ApiModel("云课堂观看统计查询结果")
+    public static class StatQueryData {
+
+        @ApiModelProperty("分部ID")
+        private Long organizationId;
+
+        @ApiModelProperty("分部名称")
+        private String organizationName;
+
+        @ApiModelProperty("声部老师")
+        private String teacherName;
+
+        @ApiModelProperty("会员数量")
+        private Integer memberNum;
+
+        @ApiModelProperty("无练习人数")
+        private Integer noPlayNum;
+
+        @ApiModelProperty("练习时长少于等于10分钟")
+        private Integer playTimeLess10;
+
+        @ApiModelProperty("练习时长少于等于60分钟")
+        private Integer playTimeLess60;
+
+        @ApiModelProperty("练习时长少于等于120分钟")
+        private Integer playTimeLess120;
+
+        @ApiModelProperty("练习时长少于等于240")
+        private Integer playTimeLess240;
+
+        @ApiModelProperty("练习时长大于240")
+        private Integer playTimeRather240;
+
+        @ApiModelProperty("平均练习时长")
+        private BigDecimal avgPlayTime;
+
+    }
+
+}

+ 1 - 1
mec-biz/src/main/java/com/ym/mec/biz/service/ClassGroupService.java

@@ -260,7 +260,7 @@ public interface ClassGroupService extends BaseService<Integer, ClassGroup> {
      * @param queryInfo:
      * @return org.snaker.engine.access.Page
      */
-    PageInfo findTeacherClassStudents(CourseScheduleQueryInfo queryInfo);
+    PageInfo<TeacherClassStudentDto> findTeacherClassStudents(CourseScheduleQueryInfo queryInfo);
 
     /**
      * @describe 根据班级获取点名列表

+ 1 - 1
mec-biz/src/main/java/com/ym/mec/biz/service/CourseScheduleService.java

@@ -411,7 +411,7 @@ public interface CourseScheduleService extends BaseService<Long, CourseSchedule>
 	PageInfo queryTeacherClassCourseSchedule(CourseScheduleQueryInfo queryInfo);
 
 
-	PageInfo queryTeacherVipClassCourseSchedule(CourseScheduleQueryInfo queryInfo);
+	PageInfo<TeacherClassCourseSchudeleDto> queryTeacherVipClassCourseSchedule(CourseScheduleQueryInfo queryInfo);
 
 	/**
 	 * @describe 获取点名详情界面头部信息

+ 2 - 1
mec-biz/src/main/java/com/ym/mec/biz/service/EmployeeService.java

@@ -1,6 +1,7 @@
 package com.ym.mec.biz.service;
 
 import com.ym.mec.auth.api.entity.SysRole;
+import com.ym.mec.biz.dal.dto.EmployeeDto;
 import com.ym.mec.biz.dal.dto.EmployeeLevelDto;
 import com.ym.mec.biz.dal.dto.SimpleUserDto;
 import com.ym.mec.biz.dal.dto.SysUserDto;
@@ -23,7 +24,7 @@ public interface EmployeeService extends BaseService<Integer, Employee> {
      * @Date: 2019/9/17
      * 根据部门获取下面的员工
      */
-    PageInfo queryEmployByOrganId(EmployeeQueryInfo queryInfo) throws Exception;
+    PageInfo<EmployeeDto> queryEmployByOrganId(EmployeeQueryInfo queryInfo) throws Exception;
 
     /**
      * @Author: Joburgess

+ 5 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/ImGroupNoticeService.java

@@ -1,5 +1,6 @@
 package com.ym.mec.biz.service;
 
+import com.ym.mec.biz.dal.dao.ImGroupNoticeDao;
 import com.ym.mec.biz.dal.dto.ImGroupNoticeDto;
 import com.ym.mec.biz.dal.entity.ImGroupNotice;
 import com.ym.mec.biz.dal.page.ImGroupNoticeQueryInfo;
@@ -16,4 +17,8 @@ public interface ImGroupNoticeService extends BaseService<Long, ImGroupNotice> {
 	 * @return
 	 */
 	ImGroupNoticeDto queryLatestNotice(String imGroupId);
+
+	void modify(ImGroupNotice imGroupNotice);
+
+	ImGroupNoticeDao getDao();
 }

+ 50 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/StudentCoursewarePlayRecordService.java

@@ -0,0 +1,50 @@
+package com.ym.mec.biz.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.ym.mec.biz.dal.wrapper.StudentCoursewarePlayRecordWrapper;
+import com.ym.mec.biz.dal.entity.StudentCoursewarePlayRecord;
+
+import java.util.List;
+
+/**
+ * 学生课件播放统计记录
+ * 2024-07-04 14:48:14
+ */
+public interface StudentCoursewarePlayRecordService extends IService<StudentCoursewarePlayRecord>  {
+
+    /**
+     * 查询详情
+     * @param id 详情ID
+     * @return StudentCoursewarePlayRecord
+     */
+    StudentCoursewarePlayRecord detail(Long id);
+
+    /**
+     * 分页查询
+     * @param page IPage<StudentCoursewarePlayRecord>
+     * @param query StudentCoursewarePlayRecordWrapper.StudentCoursewarePlayRecordQuery
+     * @return IPage<StudentCoursewarePlayRecord>
+     */
+    IPage<StudentCoursewarePlayRecord> selectPage(IPage<StudentCoursewarePlayRecord> page, StudentCoursewarePlayRecordWrapper.StudentCoursewarePlayRecordQuery query);
+
+    /**
+     * 添加
+     * @param studentCoursewarePlayRecord StudentCoursewarePlayRecordWrapper.StudentCoursewarePlayRecord
+     * @return Boolean
+     */
+    Boolean add(StudentCoursewarePlayRecordWrapper.StudentCoursewarePlayRecord studentCoursewarePlayRecord);
+
+    /**
+     * 更新
+     * @param studentCoursewarePlayRecord StudentCoursewarePlayRecordWrapper.StudentCoursewarePlayRecord
+     * @return Boolean
+     */
+    Boolean update(StudentCoursewarePlayRecordWrapper.StudentCoursewarePlayRecord studentCoursewarePlayRecord);
+
+    void save(StudentCoursewarePlayRecordWrapper.StudentCoursewarePlayRecordSave studentCoursewarePlayRecord);
+
+    List<StudentCoursewarePlayRecordWrapper.StatQueryData> statList(StudentCoursewarePlayRecordWrapper.StatQuery statQuery);
+
+    IPage<StudentCoursewarePlayRecordWrapper.StatQueryData> statDetailPage(StudentCoursewarePlayRecordWrapper.StatQuery statQuery);
+}

+ 11 - 4
mec-biz/src/main/java/com/ym/mec/biz/service/im/impl/ImGroupCoreServiceImpl.java

@@ -7,6 +7,7 @@ import com.google.common.collect.Lists;
 import com.microsvc.toolkit.common.tools.ThreadPool;
 import com.microsvc.toolkit.middleware.im.ImPluginContext;
 import com.microsvc.toolkit.middleware.im.message.GroupMemberWrapper;
+import com.ym.mec.biz.dal.dao.ImGroupNoticeDao;
 import com.microsvc.toolkit.middleware.im.message.TencentWrapper;
 import com.ym.mec.biz.dal.entity.ImGroupMemberPlus;
 import com.ym.mec.biz.dal.entity.ImGroupPlus;
@@ -26,6 +27,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import javax.annotation.Resource;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Objects;
@@ -40,13 +42,15 @@ import java.util.stream.Collectors;
 @Service
 public class ImGroupCoreServiceImpl implements ImGroupCoreService {
 
-    @Autowired
+    @Resource
     private ImPluginContext imPluginContext;
-    @Autowired
+    @Resource
     private ImGroupPlusService imGroupService;
-    @Autowired
+    @Resource
     private ImGroupMemberPlusService imGroupMemberPlusService;
-    @Autowired
+    @Resource
+    private ImGroupNoticeDao imGroupNoticeDao;
+    @Resource
     private ImGroupMemberService imGroupMemberService;
 
     /**
@@ -291,6 +295,9 @@ public class ImGroupCoreServiceImpl implements ImGroupCoreService {
         // 删除群组成员
         imGroupMemberPlusService.remove(Wrappers.<ImGroupMemberPlus>lambdaQuery().eq(ImGroupMemberPlus::getImGroupId, groupId));
 
+        // 删除群公告
+        imGroupNoticeDao.deleteByImGroupId(groupId);
+
         // 解散群
         imPluginContext.getPluginService().groupDismiss(groupId, getImGroupMembers(groupMembers));
 

+ 5 - 5
mec-biz/src/main/java/com/ym/mec/biz/service/impl/ClassGroupServiceImpl.java

@@ -1785,7 +1785,7 @@ public class ClassGroupServiceImpl extends BaseServiceImpl<Integer, ClassGroup>
             throw new BizException("请指定班级");
         }
 
-        ClassGroup classGroup = classGroupDao.get(classGroupId.intValue());
+        ClassGroup classGroup = classGroupDao.get(classGroupId);
 
         if (Objects.isNull(classGroup)) {
             throw new BizException("未找到该班级");
@@ -1800,9 +1800,9 @@ public class ClassGroupServiceImpl extends BaseServiceImpl<Integer, ClassGroup>
 
         if (onlineCourseNum > 0 && offlineCourseNum <= 0) {
             teacherClassHeadInfo.setTeachMode("1");
-        } else if (onlineCourseNum > 0 && offlineCourseNum > 0) {
+        } else if (onlineCourseNum > 0) {
             teacherClassHeadInfo.setTeachMode("3");
-        } else if (onlineCourseNum <= 0 && offlineCourseNum > 0) {
+        } else if (offlineCourseNum > 0) {
             teacherClassHeadInfo.setTeachMode("2");
         } else {
             teacherClassHeadInfo.setTeachMode("0");
@@ -1850,8 +1850,8 @@ public class ClassGroupServiceImpl extends BaseServiceImpl<Integer, ClassGroup>
     }
 
     @Override
-    public PageInfo findTeacherClassStudents(CourseScheduleQueryInfo queryInfo) {
-        PageInfo pageInfo = new PageInfo<>(queryInfo.getPage(), queryInfo.getRows());
+    public PageInfo<TeacherClassStudentDto> findTeacherClassStudents(CourseScheduleQueryInfo queryInfo) {
+        PageInfo<TeacherClassStudentDto> pageInfo = new PageInfo<>(queryInfo.getPage(), queryInfo.getRows());
         Map<String, Object> params = new HashMap<>();
         MapUtil.populateMap(params, queryInfo);
         List<TeacherClassStudentDto> dataList = null;

+ 49 - 7
mec-biz/src/main/java/com/ym/mec/biz/service/impl/CourseScheduleServiceImpl.java

@@ -3940,7 +3940,25 @@ public class CourseScheduleServiceImpl extends BaseServiceImpl<Long, CourseSched
             } else {
                 dataList = courseScheduleDao.queryTeacherHistoryClassCourseSchedule(params);
             }
-            dataList.forEach(e -> {
+			//获取老师姓名
+			List<Integer> teacherIds = dataList.stream().map(e -> e.getActualTeacherId()).distinct().collect(Collectors.toList());
+			List<SimpleUserDto> teacherDtos = teacherDao.getUsersSimpleInfo(teacherIds);
+			Map<Integer, String> teacherDtoMap = teacherDtos.stream().collect(Collectors.toMap(SimpleUserDto::getUserId, SimpleUserDto::getRealName));
+			//获取学校名称
+			List<Integer> schoolIds = dataList.stream().map(e -> e.getSchoolId()).distinct().collect(Collectors.toList());
+			List<School> schoolList = schoolDao.getSchools(schoolIds);
+			Map<Integer, String> schoolMap = schoolList.stream().collect(Collectors.toMap(School::getId, School::getName));
+			//获取班级信息
+			List<Integer> classGroupIds = dataList.stream().map(e -> e.getClassGroupId()).distinct().collect(Collectors.toList());
+			List<ClassGroup> classGroups = classGroupDao.findByClassGroupIds(classGroupIds, null);
+			Map<Integer, ClassGroup> classGroupMap = classGroups.stream().collect(Collectors.toMap(ClassGroup::getId, Function.identity()));
+			dataList.forEach(e -> {
+				ClassGroup classGroup = classGroupMap.get(e.getClassGroupId());
+				if (classGroup != null) {
+					e.setTotalClassTimes(classGroup.getTotalClassTimes());
+				}
+				e.setSchoolName(schoolMap.get(e.getSchoolId()));
+				e.setActualTeacherName(teacherDtoMap.get(e.getActualTeacherId()));
                 e.setCurrentClassTimes(courseScheduleDao.countCurrentTimes(e.getClassGroupId().intValue(),new Date()));
                 e.setTotalClassTimes(courseScheduleDao.countCurrentCourseTime(e.getCourseScheduleId()));
             });
@@ -3953,7 +3971,7 @@ public class CourseScheduleServiceImpl extends BaseServiceImpl<Long, CourseSched
     }
 
 	@Override
-	public PageInfo queryTeacherVipClassCourseSchedule(CourseScheduleQueryInfo queryInfo) {
+	public PageInfo<TeacherClassCourseSchudeleDto> queryTeacherVipClassCourseSchedule(CourseScheduleQueryInfo queryInfo) {
 		SysUser user = sysUserService.getUser();
 		if (null == user.getTenantId()) {
 			throw new BizException("用户机构信息异常");
@@ -3961,7 +3979,7 @@ public class CourseScheduleServiceImpl extends BaseServiceImpl<Long, CourseSched
 		if(!queryInfo.getFindTotal()){
 			queryInfo.setUserId(user.getId().longValue());
 		}
-		PageInfo pageInfo = new PageInfo<>(queryInfo.getPage(), queryInfo.getRows());
+		PageInfo<TeacherClassCourseSchudeleDto> pageInfo = new PageInfo<>(queryInfo.getPage(), queryInfo.getRows());
 
 		if (Objects.isNull(queryInfo.getDate())) {
 			queryInfo.setDate(new Date());
@@ -3977,9 +3995,16 @@ public class CourseScheduleServiceImpl extends BaseServiceImpl<Long, CourseSched
             ClassGroup classGroup = classGroupDao.get(queryInfo.getClassGroupId().intValue());
             params.put("groupType", classGroup.getGroupType().name());
         }
-
+		//获取老师可以查看的班级课程
+		if(queryInfo.getClassGroupId() != null && queryInfo.getUserId() != null){
+			List<Long> courseIds = courseScheduleDao.queryTeacherCanViewClassCourseSchedule(queryInfo.getClassGroupId(),queryInfo.getUserId());
+			if(CollectionUtils.isEmpty(courseIds)){
+				return pageInfo;
+			}
+			params.put("courseIds", courseIds);
+		}
 		List<TeacherClassCourseSchudeleDto> dataList = null;
-		int count = 0;
+		int count;
 		if (Objects.isNull(queryInfo.getOnlyHistory()) || queryInfo.getOnlyHistory() == 0) {
 			count = courseScheduleDao.countTeacherClassCourseSchedule(params);
 		} else {
@@ -3993,8 +4018,19 @@ public class CourseScheduleServiceImpl extends BaseServiceImpl<Long, CourseSched
 			} else {
 				dataList = courseScheduleDao.queryTeacherHistoryClassCourseSchedule(params);
 			}
+			//获取老师姓名
+			List<Integer> teacherIds = dataList.stream().map(e -> e.getActualTeacherId()).distinct().collect(Collectors.toList());
+			List<SimpleUserDto> teacherDtos = teacherDao.getUsersSimpleInfo(teacherIds);
+			Map<Integer, String> teacherDtoMap = teacherDtos.stream().collect(Collectors.toMap(SimpleUserDto::getUserId, SimpleUserDto::getRealName));
+			//获取学校名称
+			List<Integer> schoolIds = dataList.stream().map(e -> e.getSchoolId()).distinct().collect(Collectors.toList());
+			List<School> schoolList = schoolDao.getSchools(schoolIds);
+			Map<Integer, String> schoolMap = schoolList.stream().collect(Collectors.toMap(School::getId, School::getName));
+			//获取班级信息
+			List<Integer> classGroupIds = dataList.stream().map(e -> e.getClassGroupId()).distinct().collect(Collectors.toList());
+			List<ClassGroup> classGroups = classGroupDao.findByClassGroupIds(classGroupIds, null);
+			Map<Integer, ClassGroup> classGroupMap = classGroups.stream().collect(Collectors.toMap(ClassGroup::getId, Function.identity()));
 
-			List<Integer> classGroupIds = dataList.stream().map(e->e.getClassGroupId().intValue()).collect(Collectors.toList());
 			List<Map<Integer, Integer>> classGroupStudentNumMaps = classGroupStudentMapperDao.countClassGroupsStudentNum(classGroupIds, ClassGroupStudentStatusEnum.NORMAL);
 			Map<Integer, Long> classGroupStudentNumMap = MapUtil.convertIntegerMap(classGroupStudentNumMaps);
 
@@ -4018,7 +4054,13 @@ public class CourseScheduleServiceImpl extends BaseServiceImpl<Long, CourseSched
 
 			ImLiveBroadcastRoomDto liveRoom;
 			for (TeacherClassCourseSchudeleDto e : dataList) {
-				e.setCurrentClassTimes(courseScheduleDao.countCurrentTimes(e.getClassGroupId().intValue(),new Date()));
+				ClassGroup classGroup = classGroupMap.get(e.getClassGroupId());
+				if (classGroup != null) {
+					e.setTotalClassTimes(classGroup.getTotalClassTimes());
+				}
+				e.setSchoolName(schoolMap.get(e.getSchoolId()));
+				e.setActualTeacherName(teacherDtoMap.get(e.getActualTeacherId()));
+				e.setCurrentClassTimes(courseScheduleDao.countCurrentTimes(e.getClassGroupId(),new Date()));
 				e.setTotalClassTimes(courseScheduleDao.countCurrentCourseTime(e.getCourseScheduleId()));
 
 				Long leaveStudentNum = courseLeaveStudentNumMap.get(e.getCourseScheduleId());

+ 178 - 197
mec-biz/src/main/java/com/ym/mec/biz/service/impl/EmployeeServiceImpl.java

@@ -1,79 +1,37 @@
 package com.ym.mec.biz.service.impl;
 
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Optional;
-import java.util.Set;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.TimeUnit;
-import java.util.stream.Collectors;
-
 import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.google.common.collect.Lists;
 import com.microsvc.toolkit.middleware.im.ImPluginContext;
 import com.microsvc.toolkit.middleware.im.impl.RongCloudImPlugin;
 import com.microsvc.toolkit.middleware.im.message.GroupMemberWrapper;
-import com.ym.mec.biz.dal.dto.SimpleUserDto;
-import com.ym.mec.biz.dal.enums.EFriendRoleType;
-import com.ym.mec.biz.dal.enums.im.ClientEnum;
-import com.ym.mec.biz.dal.enums.im.EImGroupRoleType;
-import com.ym.mec.biz.dal.wrapper.ImGroupMemberWrapper;
-import com.ym.mec.biz.dal.wrapper.ImGroupWrapper;
-import com.ym.mec.biz.service.*;
-import com.ym.mec.biz.service.im.ImGroupCoreService;
-import com.ym.mec.common.page.QueryInfo;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.lang3.StringUtils;
-import org.joda.time.DateTime;
-import org.redisson.api.RBucket;
-import org.redisson.api.RedissonClient;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.dao.DuplicateKeyException;
-import org.springframework.security.authentication.LockedException;
-import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-import org.springframework.util.CollectionUtils;
-
-import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.ym.mec.auth.api.client.SysUserFeignService;
 import com.ym.mec.auth.api.entity.SysRole;
 import com.ym.mec.auth.api.entity.SysUser;
-import com.ym.mec.biz.dal.dao.ClassGroupDao;
-import com.ym.mec.biz.dal.dao.CooperationOrganDao;
-import com.ym.mec.biz.dal.dao.EmployeeDao;
-import com.ym.mec.biz.dal.dao.ImGroupDao;
-import com.ym.mec.biz.dal.dao.OrganizationDao;
-import com.ym.mec.biz.dal.dao.SysEmployeePositionDao;
-import com.ym.mec.biz.dal.dao.SysUserCashAccountDao;
-import com.ym.mec.biz.dal.dao.TeacherDao;
+import com.ym.mec.biz.dal.dao.*;
 import com.ym.mec.biz.dal.dto.EmployeeDto;
 import com.ym.mec.biz.dal.dto.EmployeeLevelDto;
 import com.ym.mec.biz.dal.dto.SysUserDto;
-import com.ym.mec.biz.dal.entity.Employee;
-import com.ym.mec.biz.dal.entity.Organization;
-import com.ym.mec.biz.dal.entity.SysUserCashAccount;
-import com.ym.mec.biz.dal.entity.SysUserTenant;
-import com.ym.mec.biz.dal.entity.TenantInfo;
+import com.ym.mec.biz.dal.entity.*;
+import com.ym.mec.biz.dal.enums.EFriendRoleType;
 import com.ym.mec.biz.dal.enums.EmployeeOperateEnum;
 import com.ym.mec.biz.dal.enums.GroupType;
 import com.ym.mec.biz.dal.enums.ParamEnum;
+import com.ym.mec.biz.dal.enums.im.ClientEnum;
 import com.ym.mec.biz.dal.page.EmployeeQueryInfo;
 import com.ym.mec.biz.dal.page.UserBasicQueryInfo;
+import com.ym.mec.biz.dal.wrapper.ImGroupMemberWrapper;
+import com.ym.mec.biz.dal.wrapper.ImGroupWrapper;
+import com.ym.mec.biz.service.*;
+import com.ym.mec.biz.service.im.ImGroupCoreService;
 import com.ym.mec.common.dal.BaseDAO;
 import com.ym.mec.common.entity.ImGroupModel;
 import com.ym.mec.common.entity.ImResult;
 import com.ym.mec.common.entity.ImUserModel;
 import com.ym.mec.common.exception.BizException;
 import com.ym.mec.common.page.PageInfo;
+import com.ym.mec.common.page.QueryInfo;
 import com.ym.mec.common.page.WrapperUtil;
 import com.ym.mec.common.service.impl.BaseServiceImpl;
 import com.ym.mec.common.tenant.TenantContextHolder;
@@ -81,53 +39,74 @@ import com.ym.mec.im.ImFeignService;
 import com.ym.mec.im.entity.GroupMember;
 import com.ym.mec.im.entity.GroupModel;
 import com.ym.mec.util.collection.MapUtil;
+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.RedissonClient;
+import org.springframework.dao.DuplicateKeyException;
+import org.springframework.security.authentication.LockedException;
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import javax.annotation.Resource;
+import java.util.*;
+import java.util.concurrent.*;
+import java.util.stream.Collectors;
 
 @Slf4j
 @Service
 public class EmployeeServiceImpl extends BaseServiceImpl<Integer, Employee> implements EmployeeService {
 
-    @Autowired
+    @Resource
     private EmployeeDao employeeDao;
-    @Autowired
+    @Resource
     private ImFeignService imFeignService;
-    @Autowired
+    @Resource
     private ImGroupMemberService imGroupMemberService;
-    @Autowired
+    @Resource
     private SysUserFeignService sysUserFeignService;
-    @Autowired
+    @Resource
     private TeacherDao teacherDao;
-    @Autowired
+    @Resource
     private SysUserCashAccountDao sysUserCashAccountDao;
-    @Autowired
+    @Resource
     private ClassGroupDao classGroupDao;
-    @Autowired
+    @Resource
     private ImUserFriendService imUserFriendService;
-    @Autowired
+    @Resource
     private OrganizationDao organizationDao;
-    @Autowired
+    @Resource
     private ImGroupDao imGroupDao;
-    @Autowired
+    @Resource
     private CooperationOrganDao cooperationOrganDao;
-    @Autowired
+    @Resource
     private OaUserService oaUserService;
-    @Autowired
+    @Resource
     private TenantInfoService tenantInfoService;
-    @Autowired
+    @Resource
     private SysEmployeePositionService employeePositionService;
-    @Autowired
+    @Resource
     private SysEmployeePositionDao employeePositionDao;
-    @Autowired
+    @Resource
     private SysUserTenantService sysUserTenantService;
-    @Autowired
+    @Resource
     private RedissonClient redissonClient;
-    @Autowired
+    @Resource
     private ImGroupCoreService imGroupCoreService;
-    @Autowired
+    @Resource
     private ImPluginContext imPluginContext;
-
-    @Autowired
+    @Resource
     private SysUserService sysUserService;
 
+    private static final ExecutorService exportExecutorService = new ThreadPoolExecutor(
+            5, 20, 0L, TimeUnit.MILLISECONDS,
+            new LinkedBlockingQueue<>(),
+            Executors.defaultThreadFactory(),
+            new ThreadPoolExecutor.CallerRunsPolicy()
+    );
+
     @Override
     public BaseDAO<Integer, Employee> getDAO() {
         return employeeDao;
@@ -350,7 +329,7 @@ public class EmployeeServiceImpl extends BaseServiceImpl<Integer, Employee> impl
     }
 
     @Override
-    public PageInfo queryEmployByOrganId(EmployeeQueryInfo queryInfo) {
+    public PageInfo<EmployeeDto> queryEmployByOrganId(EmployeeQueryInfo queryInfo) {
         SysUser user = sysUserFeignService.queryUserInfo();
         if (user == null) {
             throw new BizException("获取用户信息失败");
@@ -421,12 +400,14 @@ public class EmployeeServiceImpl extends BaseServiceImpl<Integer, Employee> impl
                     sysUserFeignService.exitByPhone("teacher", sysUser.getPhone());
                 } else if (sysUser.getUserType().contains("SYSTEM")) {
                     sysUserFeignService.exitByPhone("system", sysUser.getPhone());
+                    sysUserFeignService.exitByPhone("education", sysUser.getPhone());
                 }
                 break;
             case DEMISSION:
                 employeeDao.updateUserLock(employeeId, 1);
                 employeeDao.updateUserDemissionDate(employeeId);
                 sysUserFeignService.exitByPhone("system", sysUser.getPhone());
+                sysUserFeignService.exitByPhone("education", sysUser.getPhone());
 
                 //更新OA信息
                 oaUserService.delOaUser(employee.getUserId());
@@ -490,7 +471,7 @@ public class EmployeeServiceImpl extends BaseServiceImpl<Integer, Employee> impl
             for (Integer organId : organIds) {
                 List<EmployeeLevelDto> levelDtoList = organIdMap.get(organId);
                 for (EmployeeLevelDto employeeLevelDto : levelDtoList) {
-                    if (employeeLevelDto.getLevelUserId() == employeeLevelDto.getTransferUserId()) {
+                    if (Objects.equals(employeeLevelDto.getLevelUserId(), employeeLevelDto.getTransferUserId())) {
                         throw new BizException("交接人校验失败,请重新填写");
                     }
                     userIds.add(employeeLevelDto.getTransferUserId());
@@ -502,6 +483,8 @@ public class EmployeeServiceImpl extends BaseServiceImpl<Integer, Employee> impl
                             cooperationOrganDao.batchUpdateEduId(employeeLevelDto.getTransferUserId(), levelUserId, organId);
                             //教务老师所需加入的群组
                             educationGroupModels.addAll(classGroupDao.queryEducationGroups(employeeLevelDto.getTransferUserId(), levelUserId, organId));
+                            //获取当前用户所在的衔接群
+                            educationGroupModels.addAll(imGroupDao.queryUserGroupList(employeeLevelDto.getTransferUserId(), levelUserId, "乐团主管", organId));
                             break;
                         case "teamTeacher":
                             //运营主管所需加入的群组
@@ -515,177 +498,175 @@ public class EmployeeServiceImpl extends BaseServiceImpl<Integer, Employee> impl
                 }
             }
         }
-        Date date = new Date();
-        if (educationGroupModels.size() > 0) {
-            Map<Integer, String> realNameMap = MapUtil.convertIntegerMap(teacherDao.queryNameByIdList(new ArrayList<>(userIds)));
-            //❤️用户加群
-            List<com.ym.mec.biz.dal.entity.ImGroupMember> imGroupMemberList = new ArrayList<>();
-            List<GroupModel> groupModelList = new ArrayList<>();
-
-            List<ImGroupMemberWrapper.ImGroupMember> groupMembers = Lists.newArrayList();
-            for (ImGroupModel imGroupModel : educationGroupModels) {
-                String userId = imGroupModel.getMemberList().get(0).getId();
-                com.ym.mec.biz.dal.entity.ImGroupMember imGroupMember = new com.ym.mec.biz.dal.entity.ImGroupMember();
-                imGroupMember.setCreateTime(date);
-                imGroupMember.setImGroupId(imGroupModel.getId());
-                imGroupMember.setIsAdmin(false);
-                imGroupMember.setRoleType(imGroupModel.getUserRole());
-                if(StringUtils.isNotEmpty(imGroupModel.getUserRole())){
-                    imGroupMember.setType(EFriendRoleType.getByName(imGroupModel.getUserRole()).name());
+        if (CollectionUtils.isNotEmpty(educationGroupModels)) {
+            CompletableFuture.runAsync(() -> {
+                Date date = new Date();
+                Map<Integer, String> realNameMap = MapUtil.convertIntegerMap(teacherDao.queryNameByIdList(new ArrayList<>(userIds)));
+                //❤️用户加群
+                List<com.ym.mec.biz.dal.entity.ImGroupMember> imGroupMemberList = new ArrayList<>();
+                List<GroupModel> groupModelList = new ArrayList<>();
+
+                List<ImGroupMemberWrapper.ImGroupMember> groupMembers = Lists.newArrayList();
+                for (ImGroupModel imGroupModel : educationGroupModels) {
+                    String userId = imGroupModel.getMemberList().get(0).getId();
+                    com.ym.mec.biz.dal.entity.ImGroupMember imGroupMember = new com.ym.mec.biz.dal.entity.ImGroupMember();
+                    imGroupMember.setCreateTime(date);
+                    imGroupMember.setImGroupId(imGroupModel.getId());
+                    imGroupMember.setIsAdmin(false);
+                    imGroupMember.setRoleType(imGroupModel.getUserRole());
+                    if (StringUtils.isNotEmpty(imGroupModel.getUserRole())) {
+                        imGroupMember.setType(EFriendRoleType.getByName(imGroupModel.getUserRole()).name());
+                    }
+                    imGroupMember.setUpdateTime(date);
+                    imGroupMember.setUserId(Integer.parseInt(userId));
+                    imGroupMember.setNickname(realNameMap.get(imGroupMember.getUserId()));
+                    imGroupMemberList.add(imGroupMember);
+                    GroupMember groupMember = new GroupMember(userId, imGroupModel.getId());
+                    GroupModel groupModel = new GroupModel(imGroupModel.getId(), new GroupMember[]{groupMember}, imGroupModel.getName());
+                    groupModelList.add(groupModel);
+
+                    // 腾讯云IM用户加群
+                    groupMembers.add(ImGroupMemberWrapper.ImGroupMember.builder()
+                            .groupId(imGroupModel.getId())
+                            .roleType(imGroupModel.getUserRole())
+                            .isAdmin(false)
+                            .userId(Long.valueOf(userId))
+                            .imUserId(userId)
+                            .groupRoleType(imGroupMember.getGroupRoleType())
+                            .nickname(realNameMap.get(imGroupMember.getUserId()))
+                            .updateTime(DateTime.now().toDate())
+                            .createTime(DateTime.now().toDate())
+                            .build());
                 }
-                imGroupMember.setUpdateTime(date);
-                imGroupMember.setUserId(Integer.parseInt(userId));
-                imGroupMember.setNickname(realNameMap.get(imGroupMember.getUserId()));
-                imGroupMemberList.add(imGroupMember);
-                GroupMember groupMember = new GroupMember(userId, imGroupModel.getId());
-                GroupModel groupModel = new GroupModel(imGroupModel.getId(), new GroupMember[]{groupMember}, imGroupModel.getName());
-                groupModelList.add(groupModel);
-
-                // 腾讯云IM用户加群
-                groupMembers.add(ImGroupMemberWrapper.ImGroupMember.builder()
-                    .groupId(imGroupModel.getId())
-                    .roleType(imGroupModel.getUserRole())
-                    .isAdmin(false)
-                    .userId(Long.valueOf(userId))
-                    .imUserId(userId)
-                    .groupRoleType(imGroupMember.getGroupRoleType())
-                    .nickname(realNameMap.get(imGroupMember.getUserId()))
-                    .updateTime(DateTime.now().toDate())
-                    .createTime(DateTime.now().toDate())
-                    .build());
-            }
-            imGroupMemberService.batchInsert(imGroupMemberList);
+                imGroupMemberService.batchInsert(imGroupMemberList);
 
-            if (RongCloudImPlugin.PLUGIN_NAME.equals(imPluginContext.defaultService())) {
-                // 融云IM用户加群
-                imFeignService.groupBatchJoin(groupModelList);
-            } else {
-                // 腾讯云IM用户加群
-                if (org.apache.commons.collections.CollectionUtils.isNotEmpty(groupMembers)) {
-                    Map<String, List<ImGroupMemberWrapper.ImGroupMember>> imGroupMembers = groupMembers.stream()
-                        .collect(Collectors.groupingBy(ImGroupMemberWrapper.ImGroupMember::getGroupId));
+                if (RongCloudImPlugin.PLUGIN_NAME.equals(imPluginContext.defaultService())) {
+                    // 融云IM用户加群
+                    imFeignService.groupBatchJoin(groupModelList);
+                } else {
+                    // 腾讯云IM用户加群
+                    if (org.apache.commons.collections.CollectionUtils.isNotEmpty(groupMembers)) {
+                        Map<String, List<ImGroupMemberWrapper.ImGroupMember>> imGroupMembers = groupMembers.stream()
+                                .collect(Collectors.groupingBy(ImGroupMemberWrapper.ImGroupMember::getGroupId));
 
-                    for (Map.Entry<String, List<ImGroupMemberWrapper.ImGroupMember>> entry : imGroupMembers.entrySet()) {
+                        for (Map.Entry<String, List<ImGroupMemberWrapper.ImGroupMember>> entry : imGroupMembers.entrySet()) {
 
-                        try {
                             // 设置用户默认头象
                             for (ImGroupMemberWrapper.ImGroupMember member : entry.getValue()) {
 //                                member.setAvatar(avatarMap.getOrDefault(member.getUserId().intValue(), ""));
                                 SysUser user = teacherDao.getUser(member.getUserId().intValue());
                                 // 用户头像
                                 member.setAvatar(sysUserService.getImAvatar(user));
-                                if(StringUtils.isNotEmpty(member.getRoleType())){
-                                    member.setNickname(StringUtils.isEmpty(user.getRealName())?user.getUsername():user.getRealName());
-                                }else {
-                                    member.setNickname(StringUtils.isEmpty(user.getUsername())?user.getRealName():user.getUsername());
+                                if (StringUtils.isNotEmpty(member.getRoleType())) {
+                                    member.setNickname(StringUtils.isEmpty(user.getRealName()) ? user.getUsername() : user.getRealName());
+                                } else {
+                                    member.setNickname(StringUtils.isEmpty(user.getUsername()) ? user.getRealName() : user.getUsername());
                                 }
                             }
-                            // 腾讯云用户加群
-                            imGroupCoreService.groupMemberJoin(entry.getKey(), entry.getValue());
-                        } catch (Exception e) {
-                            log.error("腾讯云IM用户加群失败,groupId:{}, members={}", entry.getKey(), JSON.toJSONString(entry.getValue()), e);
+                            try {
+                                // 腾讯云用户加群
+                                imGroupCoreService.groupMemberJoin(entry.getKey(), entry.getValue());
+                            } catch (Exception e) {
+                                log.error("腾讯云IM用户加群失败,groupId:{}, members={}", entry.getKey(), JSON.toJSONString(entry.getValue()), e);
+                            }
                         }
                     }
                 }
-            }
+            });
         }
         //原有员工退群
-        List<ImGroupModel> groupModels = classGroupDao.queryTeacherQuitGroups(levelUserId);
-        //原有员工退预报名群
-        groupModels.addAll(classGroupDao.queryQuitApplyGroups(levelUserId));
-        if (groupModels.size() > 0) {
-            List<com.ym.mec.biz.dal.entity.ImGroupMember> imGroupMemberList = new ArrayList<>();
-            // 融支IM用户退群
-            List<GroupModel> groupModelList = new ArrayList<>();
-            // 腾讯云IM用户退群
-            List<GroupMemberWrapper.ImGroupMember> imGroupMembers = Lists.newArrayList();
-            for (ImGroupModel imGroupModel : groupModels) {
-                com.ym.mec.biz.dal.entity.ImGroupMember imGroupMember = new com.ym.mec.biz.dal.entity.ImGroupMember();
-                imGroupMember.setImGroupId(imGroupModel.getId());
-                imGroupMember.setUserId(Integer.parseInt(imGroupModel.getMemberList().get(0).getId()));
-                imGroupMemberList.add(imGroupMember);
-
-                GroupMember groupMember = new GroupMember(imGroupMember.getUserId().toString(), imGroupModel.getId());
-                GroupModel groupModel = new GroupModel(imGroupModel.getId(), new GroupMember[]{groupMember}, imGroupModel.getName());
-                groupModelList.add(groupModel);
-
-                // 腾讯云
-                imGroupMembers.add(GroupMemberWrapper.ImGroupMember.builder()
-                    .groupId(imGroupModel.getId())
-                    .userId(imGroupMember.getUserId().longValue())
-                    .imUserId(imGroupMember.getUserId().toString())
-                    .build());
-            }
-            imGroupMemberService.batchDeleteByGroupIdAndUserId(imGroupMemberList);
-            // 用户批量退出群组
-            if (RongCloudImPlugin.PLUGIN_NAME.equals(imPluginContext.defaultService())) {
-                // 融云退群
-                imFeignService.groupBatchQuit(groupModelList);
-            } else {
-                // 腾讯云退群
-                if (org.apache.commons.collections.CollectionUtils.isNotEmpty(imGroupMembers)) {
-
-                    Map<String, List<GroupMemberWrapper.ImGroupMember>> groupMembers = imGroupMembers.stream()
-                        .collect(Collectors.groupingBy(GroupMemberWrapper.ImGroupMember::getGroupId));
-
-                    for (Map.Entry<String, List<GroupMemberWrapper.ImGroupMember>> entry : groupMembers.entrySet()) {
-
-                        try {
-                            // 用户退群
-                            imGroupCoreService.groupQuit(entry.getValue(), entry.getKey());
-                        } catch (Exception e) {
-                            log.error("腾讯云IM用户退群失败,groupId:{}, members={}", entry.getKey(), JSON.toJSONString(entry.getValue()), e);
+        CompletableFuture.runAsync(() -> {
+            List<ImGroupModel> groupModels = classGroupDao.queryTeacherQuitGroups(levelUserId);
+            //原有员工退预报名群
+            groupModels.addAll(classGroupDao.queryQuitApplyGroups(levelUserId));
+            //获取当前用户所在的衔接群
+            groupModels.addAll(imGroupDao.queryUserGroupList(levelUserId, levelUserId, "乐团主管", null));
+            if (CollectionUtils.isNotEmpty(groupModels)) {
+                List<com.ym.mec.biz.dal.entity.ImGroupMember> imGroupMemberList = new ArrayList<>();
+                // 融支IM用户退群
+                List<GroupModel> groupModelList = new ArrayList<>();
+                // 腾讯云IM用户退群
+                List<GroupMemberWrapper.ImGroupMember> imGroupMembers = Lists.newArrayList();
+                for (ImGroupModel imGroupModel : groupModels) {
+                    com.ym.mec.biz.dal.entity.ImGroupMember imGroupMember = new com.ym.mec.biz.dal.entity.ImGroupMember();
+                    imGroupMember.setImGroupId(imGroupModel.getId());
+                    imGroupMember.setUserId(Integer.parseInt(imGroupModel.getMemberList().get(0).getId()));
+                    imGroupMemberList.add(imGroupMember);
+
+                    GroupMember groupMember = new GroupMember(imGroupMember.getUserId().toString(), imGroupModel.getId());
+                    GroupModel groupModel = new GroupModel(imGroupModel.getId(), new GroupMember[]{groupMember}, imGroupModel.getName());
+                    groupModelList.add(groupModel);
+
+                    // 腾讯云
+                    imGroupMembers.add(GroupMemberWrapper.ImGroupMember.builder()
+                            .groupId(imGroupModel.getId())
+                            .userId(imGroupMember.getUserId().longValue())
+                            .imUserId(imGroupMember.getUserId().toString())
+                            .build());
+                }
+                imGroupMemberService.batchDeleteByGroupIdAndUserId(imGroupMemberList);
+                // 用户批量退出群组
+                if (RongCloudImPlugin.PLUGIN_NAME.equals(imPluginContext.defaultService())) {
+                    // 融云退群
+                    imFeignService.groupBatchQuit(groupModelList);
+                } else {
+                    // 腾讯云退群
+                    if (org.apache.commons.collections.CollectionUtils.isNotEmpty(imGroupMembers)) {
+
+                        Map<String, List<GroupMemberWrapper.ImGroupMember>> groupMembers = imGroupMembers.stream()
+                                .collect(Collectors.groupingBy(GroupMemberWrapper.ImGroupMember::getGroupId));
+
+                        for (Map.Entry<String, List<GroupMemberWrapper.ImGroupMember>> entry : groupMembers.entrySet()) {
+
+                            try {
+                                // 用户退群
+                                imGroupCoreService.groupQuit(entry.getValue(), entry.getKey());
+                            } catch (Exception e) {
+                                log.error("腾讯云IM用户退群失败,groupId:{}, members={}", entry.getKey(), JSON.toJSONString(entry.getValue()), e);
+                            }
                         }
                     }
                 }
             }
-
-        }
+        });
         //更换教务老师等数据
         employeeDao.employeeLevel(employeeLevelDtos);
         //新增离职时间
         employeeDao.updateUserDemissionDate(levelUserId);
         //冻结用户
         employeeDao.updateUserLock(levelUserId, 1);
-        ExecutorService executor = Executors.newCachedThreadPool();
-        CompletableFuture<Boolean> refreshUserFriend = CompletableFuture.supplyAsync(() -> {
+        //用户退出登陆
+        sysUserFeignService.exitByPhone("system", teacherDao.getUser(levelUserId).getPhone());
+        sysUserFeignService.exitByPhone("education", teacherDao.getUser(levelUserId).getPhone());
+        CompletableFuture.runAsync(() -> {
             //获取用户担任教务老师、维修技师的所有乐团列表
             List<String> musicGroupIds = employeeDao.queryMusicGroupIdByUserId(levelUserId);
             //获取用户担任教务老师的所有网管课列表
             List<String> practiceGroupIds = employeeDao.queryPracticeGroupIdByUserId(levelUserId);
             //获取用户担任教务老师的所有VIP课列表
             List<String> vipGroupIds = employeeDao.queryVipGroupIdByUserId(levelUserId);
-            boolean refreshFlag = false;
-            if (musicGroupIds.size() > 0) {
+            if (CollectionUtils.isNotEmpty(musicGroupIds)) {
                 for (String musicGroupId : musicGroupIds) {
                     imUserFriendService.refreshGroupImUserFriend(musicGroupId, GroupType.MUSIC);
                 }
-                refreshFlag = true;
             }
-            if (practiceGroupIds.size() > 0) {
+            if (CollectionUtils.isNotEmpty(practiceGroupIds)) {
                 for (String musicGroupId : practiceGroupIds) {
                     imUserFriendService.refreshGroupImUserFriend(musicGroupId, GroupType.PRACTICE);
                 }
-                refreshFlag = true;
             }
-            if (vipGroupIds.size() > 0) {
+            if (CollectionUtils.isNotEmpty(vipGroupIds)) {
                 for (String musicGroupId : vipGroupIds) {
                     imUserFriendService.refreshGroupImUserFriend(musicGroupId, GroupType.VIP);
                 }
-                refreshFlag = true;
             }
-            return refreshFlag;
-        }, executor);
-        Boolean join = refreshUserFriend.join();
-        if (join) {
-            refreshUserFriend.thenRun(() -> {
+            if (CollectionUtils.isNotEmpty(musicGroupIds) || CollectionUtils.isNotEmpty(practiceGroupIds) || CollectionUtils.isNotEmpty(vipGroupIds)) {
                 //更新群成员数量
                 imGroupDao.updateMemberNum();
                 //删除重复的群成员
                 imGroupMemberService.delRepeat();
-            });
-        }
-        executor.shutdown();
+            }
+        }, exportExecutorService);
     }
 
     @Override

+ 22 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/impl/ExportServiceImpl.java

@@ -11,6 +11,7 @@ import com.ym.mec.biz.dal.entity.*;
 import com.ym.mec.biz.dal.enums.*;
 import com.ym.mec.biz.dal.page.*;
 import com.ym.mec.biz.dal.vo.TeacherCloudCourseReportDto;
+import com.ym.mec.biz.dal.wrapper.StudentCoursewarePlayRecordWrapper;
 import com.ym.mec.biz.service.*;
 import com.ym.mec.common.constant.CommonConstants;
 import com.ym.mec.common.controller.BaseController;
@@ -180,6 +181,9 @@ public class ExportServiceImpl implements ExportService {
     @Resource
     private HfMerchantConfigService hfMerchantConfigService;
 
+    @Resource
+    private StudentCoursewarePlayRecordService studentCoursewarePlayRecordService;
+
     private static final ExecutorService exportExecutorService = Executors.newFixedThreadPool(10);
 
     @Value("${spring.profiles.active:dev}")
@@ -384,6 +388,24 @@ public class ExportServiceImpl implements ExportService {
         exportManageFuncMap.put(ExportEnum.EXPORT_BALANCED_RELATIONSHIP_STUDENT_INFO, this::exportBalancedRelationshipStudentInfo);
         exportManageFuncMap.put(ExportEnum.EXPORT_BALANCED_RELATIONSHIP_STUDENT_NORMAL_DETAIL, this::exportBalancedRelationshipStudentNormalDetail);
         exportManageFuncMap.put(ExportEnum.EXPORT_BALANCED_RELATIONSHIP_STUDENT_QUIT_DETAIL, this::exportBalancedRelationshipStudentQuitDetail);
+        exportManageFuncMap.put(ExportEnum.VIDEO_PLAY_STAT, this::exportVideoPlayStat);
+        exportManageFuncMap.put(ExportEnum.VIDEO_PLAY_DETAIL_STAT, this::exportVideoPlayDetailStat);
+    }
+
+    private HttpResponseResult<String> exportVideoPlayStat(Map<String, Object> info) {
+        StudentCoursewarePlayRecordWrapper.StatQuery queryInfo = JSONObject.parseObject(JSONObject.toJSONString(info), StudentCoursewarePlayRecordWrapper.StatQuery.class);
+        SysUser sysUser = sysUserService.getUser();
+        ManagerDownload managerDownload = saveManagerDownload(ExportTypeEnum.VIDEO_PLAY_STAT, sysUser.getId());
+        return this.asyncExport(() -> this.initExportInfo(studentCoursewarePlayRecordService.statList(queryInfo), managerDownload, ExportEnum.VIDEO_PLAY_STAT),
+                managerDownload.getName());
+    }
+
+    private HttpResponseResult<String> exportVideoPlayDetailStat(Map<String, Object> info) {
+        StudentCoursewarePlayRecordWrapper.StatQuery queryInfo = JSONObject.parseObject(JSONObject.toJSONString(info), StudentCoursewarePlayRecordWrapper.StatQuery.class);
+        SysUser sysUser = sysUserService.getUser();
+        ManagerDownload managerDownload = saveManagerDownload(ExportTypeEnum.VIDEO_PLAY_DETAIL_STAT, sysUser.getId());
+        return this.asyncExport(() -> this.initExportInfo(studentCoursewarePlayRecordService.statDetailPage(queryInfo).getRecords(), managerDownload, ExportEnum.VIDEO_PLAY_DETAIL_STAT),
+                managerDownload.getName());
     }
 
     private HttpResponseResult<String> exportOaSummaryExpenses(Map<String, Object> info) {

+ 0 - 2
mec-biz/src/main/java/com/ym/mec/biz/service/impl/GroupClassServiceImpl.java

@@ -65,8 +65,6 @@ public class GroupClassServiceImpl implements GroupClassService {
     @Autowired
     private SysTenantAccountService sysTenantAccountService;
     @Autowired
-    private ActivityUserMapperService activityUserMapperService;
-    @Autowired
     private StudentDao studentDao;
     @Autowired
     private PracticeGroupService practiceGroupService;

+ 28 - 9
mec-biz/src/main/java/com/ym/mec/biz/service/impl/ImGroupNoticeServiceImpl.java

@@ -1,22 +1,23 @@
 package com.ym.mec.biz.service.impl;
 
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-
 import com.ym.mec.biz.dal.dao.ImGroupNoticeDao;
 import com.ym.mec.biz.dal.dto.ImGroupNoticeDto;
 import com.ym.mec.biz.dal.entity.ImGroupNotice;
 import com.ym.mec.biz.dal.page.ImGroupNoticeQueryInfo;
 import com.ym.mec.biz.service.ImGroupNoticeService;
 import com.ym.mec.common.dal.BaseDAO;
+import com.ym.mec.common.exception.BizException;
 import com.ym.mec.common.page.PageInfo;
 import com.ym.mec.common.service.impl.BaseServiceImpl;
 import com.ym.mec.util.collection.MapUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 @Service
 public class ImGroupNoticeServiceImpl extends BaseServiceImpl<Long, ImGroupNotice>  implements ImGroupNoticeService {
@@ -53,5 +54,23 @@ public class ImGroupNoticeServiceImpl extends BaseServiceImpl<Long, ImGroupNotic
 	public ImGroupNoticeDto queryLatestNotice(String imGroupId) {
 		return imGroupNoticeDao.queryLatestNotice(imGroupId);
 	}
-	
+
+    @Override
+	@Transactional(rollbackFor = Exception.class)
+    public void modify(ImGroupNotice imGroupNotice) {
+        if (imGroupNotice.getId() == null) {
+			throw new BizException("id不能为空");
+		}
+		if(imGroupNotice.isIsTop()){
+			//置顶取消
+			imGroupNoticeDao.updateTop(imGroupNotice.getImGroupId(),false);
+		}
+		imGroupNoticeDao.update(imGroupNotice);
+	}
+
+	@Override
+	public ImGroupNoticeDao getDao() {
+		return imGroupNoticeDao;
+	}
+
 }

+ 0 - 6
mec-biz/src/main/java/com/ym/mec/biz/service/impl/ImGroupServiceImpl.java

@@ -281,12 +281,6 @@ public class ImGroupServiceImpl extends BaseServiceImpl<String, ImGroup> impleme
     @Override
     @Transactional(rollbackFor = Exception.class)
     public boolean cancel(String imGroupId) {
-        // 删除群成员
-        imGroupMemberDao.deleteByImGroupId(imGroupId);
-        // 删除群公告
-        imGroupNoticeDao.deleteByImGroupId(imGroupId);
-        // 删除群信息
-        imGroupDao.delete(imGroupId);
         try {
             imGroupCoreService.groupDismiss(imGroupId);
         } catch (Exception e) {

+ 1 - 1
mec-biz/src/main/java/com/ym/mec/biz/service/impl/IndexBaseMonthDataServiceImpl.java

@@ -75,7 +75,7 @@ public class IndexBaseMonthDataServiceImpl extends BaseServiceImpl<Long, IndexBa
 			new LinkedBlockingQueue<>(),
 			Executors.defaultThreadFactory(),
 			new ThreadPoolExecutor.CallerRunsPolicy()
-	);;
+	);
 	private static final Logger businessLogger = LoggerFactory.getLogger(IndexBaseMonthDataServiceImpl.class);
 
 	private static ThreadLocal<Set<Integer>> organIds = new ThreadLocal<Set<Integer>>(){

+ 132 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/impl/StudentCoursewarePlayRecordServiceImpl.java

@@ -0,0 +1,132 @@
+package com.ym.mec.biz.service.impl;
+
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.microsvc.toolkit.common.response.paging.QueryInfo;
+import com.ym.mec.biz.dal.dao.MusicGroupDao;
+import com.ym.mec.biz.dal.dao.StudentDao;
+import com.ym.mec.biz.dal.dao.StudentRegistrationDao;
+import com.ym.mec.biz.dal.entity.Student;
+import com.ym.mec.biz.dal.entity.StudentRegistration;
+import com.ym.mec.biz.service.StudentServeService;
+import com.ym.mec.common.page.PageInfo;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import lombok.extern.slf4j.Slf4j;
+import com.ym.mec.biz.dal.entity.StudentCoursewarePlayRecord;
+import com.ym.mec.biz.dal.wrapper.StudentCoursewarePlayRecordWrapper;
+import com.ym.mec.biz.dal.mapper.StudentCoursewarePlayRecordMapper;
+import com.ym.mec.biz.service.StudentCoursewarePlayRecordService;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.math.RoundingMode;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * 学生课件播放统计记录
+ * 2024-07-04 14:48:14
+ */
+@Slf4j
+@Service
+public class StudentCoursewarePlayRecordServiceImpl extends ServiceImpl<StudentCoursewarePlayRecordMapper, StudentCoursewarePlayRecord> implements StudentCoursewarePlayRecordService {
+
+    @Autowired
+    private StudentDao studentDao;
+
+    @Autowired
+    private StudentRegistrationDao studentRegistrationDao;
+
+    @Autowired
+    private MusicGroupDao musicGroupDao;
+
+    /**
+     * 查询详情
+     *
+     * @param id 详情ID
+     * @return StudentCoursewarePlayRecord
+     */
+    @Override
+    public StudentCoursewarePlayRecord detail(Long id) {
+
+        return baseMapper.selectById(id);
+    }
+
+    /**
+     * 分页查询
+     *
+     * @param page  IPage<StudentCoursewarePlayRecord>
+     * @param query StudentCoursewarePlayRecordWrapper.StudentCoursewarePlayRecordQuery
+     * @return IPage<StudentCoursewarePlayRecord>
+     */
+    @Override
+    public IPage<StudentCoursewarePlayRecord> selectPage(IPage<StudentCoursewarePlayRecord> page, StudentCoursewarePlayRecordWrapper.StudentCoursewarePlayRecordQuery query) {
+
+        return page.setRecords(baseMapper.selectPage(page, query));
+    }
+
+    /**
+     * 添加
+     *
+     * @param studentCoursewarePlayRecord StudentCoursewarePlayRecordWrapper.StudentCoursewarePlayRecord
+     * @return Boolean
+     */
+    @Override
+    public Boolean add(StudentCoursewarePlayRecordWrapper.StudentCoursewarePlayRecord studentCoursewarePlayRecord) {
+
+        return this.save(JSON.parseObject(studentCoursewarePlayRecord.jsonString(), StudentCoursewarePlayRecord.class));
+    }
+
+    /**
+     * 更新
+     *
+     * @param studentCoursewarePlayRecord StudentCoursewarePlayRecordWrapper.StudentCoursewarePlayRecord
+     * @return Boolean
+     */
+    @Override
+    public Boolean update(StudentCoursewarePlayRecordWrapper.StudentCoursewarePlayRecord studentCoursewarePlayRecord) {
+
+        return this.updateById(JSON.parseObject(studentCoursewarePlayRecord.jsonString(), StudentCoursewarePlayRecord.class));
+    }
+
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void save(StudentCoursewarePlayRecordWrapper.StudentCoursewarePlayRecordSave studentCoursewarePlayRecord) {
+        Integer userId = studentCoursewarePlayRecord.getUserId();
+        Student student = studentDao.get(userId);
+        if (student == null) {
+            return;
+        }
+
+        StudentCoursewarePlayRecord record = new StudentCoursewarePlayRecord();
+        record.setOrganizationId(studentCoursewarePlayRecord.getOrganizationId());
+        record.setUserId(studentCoursewarePlayRecord.getUserId());
+        record.setPlayTime(studentCoursewarePlayRecord.getPlayTime());
+        record.setCreateDate(new SimpleDateFormat("yyyyMMdd").format(new Date()));
+        baseMapper.save(record);
+    }
+
+    @Override
+    public List<StudentCoursewarePlayRecordWrapper.StatQueryData> statList(StudentCoursewarePlayRecordWrapper.StatQuery statQuery) {
+        List<StudentCoursewarePlayRecordWrapper.StatQueryData> list = baseMapper.statList(statQuery);
+        list.forEach(n -> n.setAvgPlayTime(n.getAvgPlayTime().setScale(2, RoundingMode.HALF_UP)));
+        return list;
+    }
+
+    @Override
+    public IPage<StudentCoursewarePlayRecordWrapper.StatQueryData> statDetailPage(StudentCoursewarePlayRecordWrapper.StatQuery statQuery) {
+        IPage<StudentCoursewarePlayRecordWrapper.StatQueryData> page = QueryInfo.getPage(statQuery);
+        List<StudentCoursewarePlayRecordWrapper.StatQueryData> statQueryData = baseMapper.statDetailPage(page, statQuery);
+        statQueryData.forEach(n -> n.setAvgPlayTime(n.getAvgPlayTime().setScale(2, RoundingMode.HALF_UP)));
+        page.setRecords(statQueryData);
+        return page;
+    }
+
+
+}

+ 1 - 1
mec-biz/src/main/java/com/ym/mec/biz/service/impl/StudentPaymentOrderServiceImpl.java

@@ -1047,7 +1047,7 @@ public class StudentPaymentOrderServiceImpl extends BaseServiceImpl<Long, Studen
         if (payStatus == PayStatus.SUCCESSED) {
             throw new BizException("订单已支付成功,请勿重复支付");
         }
-        if (repeatPay == false && payStatus == PayStatus.PAYING) {
+        if (!repeatPay && payStatus == PayStatus.PAYING) {
             return BaseController.failed(HttpStatus.CONTINUE, "您有支付中的订单,是否继续支付");
         }
         //处理关闭订单

+ 1 - 1
mec-biz/src/main/java/com/ym/mec/biz/service/impl/SysMessageServiceImpl.java

@@ -524,7 +524,7 @@ public class SysMessageServiceImpl extends BaseServiceImpl<Long, SysMessage> imp
 			LOGGER.error("接收地址不能为空");
 			return;
 		}
-		if("STUDENT".equals(jpushType) && type != STUDENT_PUSH_VIP_BUY){
+		if(messageSender == MessageSender.JIGUANG && "STUDENT".equals(jpushType) && type != STUDENT_PUSH_VIP_BUY){
 			//如果不是缴费信息
 			int hour = DateUtil.getHour(new Date());
 			//如果当前时间在22点之后

+ 1 - 1
mec-biz/src/main/java/com/ym/mec/biz/service/impl/UserMusicServiceImpl.java

@@ -299,7 +299,7 @@ public class UserMusicServiceImpl extends ServiceImpl<UserMusicMapper, UserMusic
         for (UserMusicWrapper.UserMusic record : records) {
             SysUser sysUser = userMap.get(record.getUserId());
             if (sysUser != null) {
-                record.setUsername(sysUser.getUsername());
+                record.setUsername(StringUtils.isBlank(sysUser.getUsername())?sysUser.getRealName():sysUser.getUsername());
                 record.setAvatar(sysUser.getAvatar());
             }
             if (record.getClientType() == ClientEnum.STUDENT) {

+ 16 - 4
mec-biz/src/main/java/com/ym/mec/biz/service/impl/VipGroupServiceImpl.java

@@ -1,7 +1,6 @@
 package com.ym.mec.biz.service.impl;
 
 import com.alibaba.fastjson.JSON;
-import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -35,6 +34,7 @@ import com.ym.mec.util.date.DateConvertor;
 import com.ym.mec.util.date.DateUtil;
 import com.ym.mec.util.string.MessageFormatter;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.collections.MapUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.joda.time.DateTime;
@@ -50,7 +50,6 @@ import org.springframework.transaction.annotation.Isolation;
 import org.springframework.transaction.annotation.Propagation;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.transaction.interceptor.TransactionAspectSupport;
-import org.springframework.util.CollectionUtils;
 
 import java.math.BigDecimal;
 import java.text.MessageFormat;
@@ -1774,6 +1773,9 @@ public class VipGroupServiceImpl extends BaseServiceImpl<Long, VipGroup> impleme
         }
         vipGroup.setStatus(VipGroupStatusEnum.DELETE);
         vipGroupDao.update(vipGroup);
+        ClassGroup classGroup = classGroupDao.findByVipGroup(vipGroupId, VIP.getCode());
+        //解散群聊
+        imGroupService.cancel(classGroup.getId().toString());
         groupClassService.hideGroupInfo(vipGroupId.toString(), "VIP".equals(vipGroup.getGroupType())?GroupType.VIP:GroupType.LIVE);
     }
 
@@ -2645,7 +2647,6 @@ public class VipGroupServiceImpl extends BaseServiceImpl<Long, VipGroup> impleme
         if(Objects.isNull(vipGroup)){
             throw new BizException("课程信息不存在");
         }
-
         ClassGroup classGroup = classGroupDao.findByMusicGroupAndType(vipGroupBuyParams.getVipGroupId().toString(),vipGroup.getGroupType());
         if (Objects.isNull(classGroup)) {
             throw new BizException("班级信息错误");
@@ -2674,7 +2675,7 @@ public class VipGroupServiceImpl extends BaseServiceImpl<Long, VipGroup> impleme
                         DealStatusEnum.ING,
                         orderTypeEnum);
 
-        if (list.size() > 0) {
+        if (CollectionUtils.isNotEmpty(list)) {
             StudentPaymentOrder applyOrder = list.get(list.size() - 1);
             //校验重复支付
             HttpResponseResult result = studentPaymentOrderService.checkRepeatPay(applyOrder, vipGroupBuyParams.isRepeatPay());
@@ -3067,6 +3068,8 @@ public class VipGroupServiceImpl extends BaseServiceImpl<Long, VipGroup> impleme
 
             classGroup.setStudentNum(classGroup.getStudentNum() - 1);
             classGroupDao.update(classGroup);
+            //学员退出班级群
+            imGroupMemberService.quit(classGroup.getId().toString(), studentId);
             return BaseController.succeed();
         }
 
@@ -3908,6 +3911,7 @@ public class VipGroupServiceImpl extends BaseServiceImpl<Long, VipGroup> impleme
                 courseScheduleTeacherSalaryDao.batchDeleteByCourseScheduleIds(courseScheduleIds);
             }
             teacherPush(vipGroup);
+            imGroupService.cancel(classGroup.getId().toString());
             return;
         }
 
@@ -3928,6 +3932,7 @@ public class VipGroupServiceImpl extends BaseServiceImpl<Long, VipGroup> impleme
             classGroupDao.update(classGroup);
             teacherPush(vipGroup);
 //			stopVipPush(vipGroup.getId(),vipGroup.getName());
+            imGroupService.cancel(classGroup.getId().toString());
             return;
         }
 
@@ -3969,6 +3974,8 @@ public class VipGroupServiceImpl extends BaseServiceImpl<Long, VipGroup> impleme
         courseScheduleStudentPaymentDao.deleteByCourseSchedule(courseScheduleIds);
         teacherAttendanceDao.batchDeleteByCourseSchedules(courseScheduleIds);
         teacherPush(vipGroup);
+        //解散群聊
+        imGroupService.cancel(classGroup.getId().toString());
     }
 
     private void teacherPush(VipGroup vipGroup) {
@@ -5302,6 +5309,11 @@ public class VipGroupServiceImpl extends BaseServiceImpl<Long, VipGroup> impleme
             throw new BizException("当前课程组已排课");
         }
         vipGroupDao.del(id);
+        //解散群
+        ClassGroup classGroup = classGroupDao.findByMusicGroupAndType(id.toString(), vipGroup.getGroupType());
+        if (Objects.nonNull(classGroup)) {
+            imGroupService.cancel(classGroup.getId().toString());
+        }
         return true;
     }
 

+ 4 - 3
mec-biz/src/main/resources/config/mybatis/ClassGroupMapper.xml

@@ -541,7 +541,7 @@
         LEFT JOIN courses_group csg ON csg.id_ = cg.music_group_id_
         WHERE cg.del_flag_ = 0 AND
         ((mg.status_ IN ('PROGRESS','PAUSE') AND cg.group_type_ = 'MUSIC' AND (cgtm.user_id_ = #{userId} OR mg.team_teacher_id_ = #{userId} OR mg.educational_teacher_id_ = #{userId} OR mg.director_user_id_ = #{userId}))
-        OR (vg.group_status_ IN (2,6) AND cg.group_type_ = 'VIP' AND vg.educational_teacher_id_ =  #{userId})
+        OR (vg.group_status_ IN (2,6) AND cg.group_type_ IN ('VIP','LIVE') AND vg.educational_teacher_id_ =  #{userId})
         OR (csg.status_ = 'NORMAL' AND cg.group_type_ = 'COMM' AND csg.educational_teacher_id_ =  #{userId}))
         <if test="search != null">
             AND (cg.name_ LIKE CONCAT('%',#{search},'%') OR cg.group_name_ LIKE CONCAT('%',#{search},'%')
@@ -558,7 +558,7 @@
         LEFT JOIN vip_group vg ON vg.id_ = cg.music_group_id_
         LEFT JOIN courses_group csg ON csg.id_ = cg.music_group_id_
         WHERE cgtm.user_id_ != #{userId} AND cg.del_flag_ = 0
-        AND ((vg.educational_teacher_id_ =  #{userId} AND vg.group_status_ IN (2,6) AND cg.group_type_ = 'VIP')
+        AND ((vg.educational_teacher_id_ =  #{userId} AND vg.group_status_ IN (2,6) AND cg.group_type_ IN ('VIP','LIVE'))
         OR (mg.status_ IN ('PROGRESS','PAUSE','PREPARE') AND cg.group_type_ = 'MUSIC' AND (mg.team_teacher_id_ = #{userId} OR mg.educational_teacher_id_ = #{userId} OR mg.director_user_id_ = #{userId}))
         OR (csg.educational_teacher_id_ =  #{userId} AND csg.status_ = 'NORMAL' AND cg.group_type_ = 'COMM'))
         GROUP BY cg.id_
@@ -594,7 +594,7 @@
         LEFT JOIN vip_group vg ON vg.id_ = cg.music_group_id_
         LEFT JOIN courses_group csg ON csg.id_ = cg.music_group_id_
         WHERE cg.del_flag_ = 0 AND
-        ((vg.group_status_ IN (2,6) AND cg.group_type_ = 'VIP' AND vg.educational_teacher_id_ =  #{userId} AND vg.organ_id_ = #{organId})
+        ((vg.group_status_ IN (2,6) AND cg.group_type_ IN ('VIP','LIVE') AND vg.educational_teacher_id_ =  #{userId} AND vg.organ_id_ = #{organId})
         OR (mg.status_ IN ('PROGRESS','PAUSE','PREPARE') AND cg.group_type_ = 'MUSIC' AND mg.educational_teacher_id_ =  #{userId} AND mg.organ_id_ = #{organId})
         OR (csg.status_ = 'NORMAL' AND cg.group_type_ = 'COMM' AND csg.educational_teacher_id_ =  #{userId} AND csg.organ_id_ = #{organId}))
         GROUP BY cg.id_
@@ -1308,6 +1308,7 @@
         <result property="id" column="class_group_id_"/>
         <collection property="members" ofType="com.ym.mec.common.entity.ImGroupMember">
             <result property="id" column="user_id_"/>
+            <result property="groupId" column="class_group_id_"/>
         </collection>
     </resultMap>
 

+ 61 - 37
mec-biz/src/main/resources/config/mybatis/CourseScheduleMapper.xml

@@ -1574,8 +1574,16 @@
         <where>
             cs.del_flag_ = '0' AND cs.is_lock_ = 0
             AND cs.class_group_id_ = #{classGroupId} AND cs.pre_course_flag_ != 1
-            <if test="userId != null">
-                AND csts.user_id_ = #{userId}
+            <if test="courseIds == null or courseIds.size == 0">
+                <if test="userId != null">
+                    AND csts.user_id_ = #{userId}
+                </if>
+            </if>
+            <if test="courseIds != null and courseIds.size > 0">
+                AND cs.id_ IN
+                <foreach collection="courseIds" item="courseId" open="(" close=")" separator=",">
+                    #{courseId}
+                </foreach>
             </if>
             <if test="onlyHistory!=null and onlyHistory==1">
                 AND CONCAT( cs.class_date_, ' ', cs.end_class_time_ )&lt;now()
@@ -1621,30 +1629,27 @@
         cs.status_,
         cs.actual_teacher_id_,
         cs.teach_mode_,
-        su.real_name_ username_,
-        cg.total_class_times_,
         cs.schoole_id_ school_id_,
         cs.teaching_content_,
         cs.teaching_point_,
         cs.music_group_id_,
         cs.live_room_id_,
-        s.name_ school_name_,
         ch.expiry_date_
-        FROM
-        course_schedule_teacher_salary csts
-        LEFT JOIN course_schedule cs ON cs.id_ = csts.course_schedule_id_
+        FROM course_schedule cs
         LEFT JOIN course_homework ch ON ch.course_schedule_id_ = cs.id_
-        LEFT JOIN class_group cg ON cs.class_group_id_=cg.id_
-        LEFT JOIN sys_user su ON cs.actual_teacher_id_ = su.id_
-        LEFT JOIN school s ON cs.schoole_id_=s.id_
+        <if test="courseIds == null or courseIds.size == 0">
+            <if test="userId != null">
+                LEFT JOIN course_schedule_teacher_salary csts ON cs.id_ = csts.course_schedule_id_
+            </if>
+        </if>
         <include refid="teacherClassCourseScheduleQueryCondition"/>
-        ORDER BY start_class_time_
+        ORDER BY cs.start_class_time_
         <include refid="global.limit"/>
     </select>
 
     <sql id="teacherGroupCourseQueryCondition">
         <where>
-            cs.actual_teacher_id_=#{teacherId} AND cs.pre_course_flag_ != 1
+            cs.actual_teacher_id_ = #{teacherId} AND cs.pre_course_flag_ != 1
             AND cs.music_group_id_ = #{groupId}
             AND cs.group_type_ = #{groupType}
         </where>
@@ -1692,28 +1697,28 @@
         cs.status_,
         cs.actual_teacher_id_,
         cs.teach_mode_,
-        su.username_,
-        cg.total_class_times_,
         GROUP_CONCAT(IF(sa.status_='NORMAL',ssu.username_,NULL)) student_names_,
         MAX(sa.current_class_times_) current_class_times_,
         cs.schoole_id_ school_id_,
         ch.expiry_date_,
         cs.teaching_content_,
         cs.teaching_point_,
-        cs.music_group_id_,
-        s.name_ school_name_
-        FROM
-        student_attendance sa
-        LEFT JOIN course_schedule cs ON cs.id_ = sa.course_schedule_id_
+        cs.music_group_id_
+        FROM course_schedule cs
         LEFT JOIN course_homework ch ON ch.course_schedule_id_ = cs.id_
-        LEFT JOIN class_group cg ON cs.class_group_id_=cg.id_
-        LEFT JOIN sys_user su ON cs.actual_teacher_id_ = su.id_
-        LEFT JOIN sys_user ssu ON sa.user_id_=ssu.id_
-        LEFT JOIN school s ON cs.schoole_id_ = s.id_
+        LEFT JOIN student_attendance sa ON sa.course_schedule_id_ = cs.id_
         WHERE cs.del_flag_ = '0' AND cs.pre_course_flag_ != 1
         AND sa.class_group_id_=#{classGroupId}
-        <if test="userId != null">
-            AND sa.teacher_id_=#{userId}
+        <if test="courseIds == null or courseIds.size == 0">
+            <if test="userId != null">
+                AND sa.teacher_id_ = #{userId}
+            </if>
+        </if>
+        <if test="courseIds != null and courseIds.size > 0">
+            AND cs.id_ IN
+            <foreach collection="courseIds" item="courseId" open="(" close=")" separator=",">
+                #{courseId}
+            </foreach>
         </if>
         <if test="status!=null">
             AND cs.status_ = #{status,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler}
@@ -1731,22 +1736,36 @@
 
     <select id="countTeacherClassCourseSchedule" resultType="int">
         SELECT
-        COUNT(cs.id_)
-        FROM
-        course_schedule_teacher_salary csts
-        LEFT JOIN course_schedule cs ON cs.id_ = csts.course_schedule_id_
+        COUNT(distinct cs.id_)
+        FROM course_schedule cs
+        <if test="courseIds == null or courseIds.size == 0">
+            <if test="userId != null">
+                LEFT JOIN course_schedule_teacher_salary csts ON cs.id_ = csts.course_schedule_id_
+            </if>
+        </if>
         <include refid="teacherClassCourseScheduleQueryCondition"/>
     </select>
     <select id="countTeacherHistoryClassCourseSchedule" resultType="int">
         SELECT
-        COUNT(DISTINCT sa.class_group_id_)
-        FROM
-        student_attendance sa
-        LEFT JOIN course_schedule cs ON sa.course_schedule_id_=cs.id_
+        COUNT(DISTINCT cs.class_group_id_)
+        FROM course_schedule cs
+        <if test="courseIds == null or courseIds.size == 0">
+            <if test="userId != null">
+                LEFT JOIN student_attendance sa ON sa.course_schedule_id_ = cs.id_
+            </if>
+        </if>
         WHERE cs.del_flag_ = '0' AND cs.pre_course_flag_ != 1
-        AND sa.class_group_id_=#{classGroupId}
-        <if test="userId != null">
-            AND sa.teacher_id_=#{userId}
+        AND cs.class_group_id_ = #{classGroupId}
+        <if test="courseIds == null or courseIds.size == 0">
+            <if test="userId != null">
+                AND sa.teacher_id_ = #{userId}
+            </if>
+        </if>
+        <if test="courseIds != null and courseIds.size > 0">
+            AND cs.id_ IN
+            <foreach collection="courseIds" item="courseId" open="(" close=")" separator=",">
+                #{courseId}
+            </foreach>
         </if>
         <if test="status!=null">
             AND cs.status_ = #{status,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler}
@@ -4581,4 +4600,9 @@
         and CONCAT(class_date_,' ',end_class_time_) &gt;= date_format(date_add(now(),interval -1 day),'%Y-%m-%d')
         and CONCAT(class_date_,' ',end_class_time_) &lt;= date_format(now(),'%Y-%m-%d %H:%i:%s')
     </select>
+    <select id="queryTeacherCanViewClassCourseSchedule" resultType="java.lang.Long">
+        select distinct csts.course_schedule_id_ from class_group_teacher_mapper cgtm
+        left join course_schedule_teacher_salary csts ON csts.class_group_id_ = cgtm.class_group_id_
+        where cgtm.class_group_id_ = #{classGroupId} AND (cgtm.user_id_ = #{userId} OR csts.user_id_ = #{userId})
+    </select>
 </mapper>

+ 20 - 1
mec-biz/src/main/resources/config/mybatis/ImGroupMapper.xml

@@ -326,7 +326,26 @@
 
 	</select>
 
-	<update id="updateSchoolRoleType">
+	<resultMap id="imGroupModel" type="com.ym.mec.common.entity.ImGroupModel">
+		<result column="group_id_" property="id"/>
+		<result column="group_name_" property="name"/>
+		<result column="group_name_" property="groupName"/>
+		<result column="user_role_" property="userRole"/>
+		<collection property="memberList" ofType="com.ym.mec.common.entity.ImGroupMember">
+			<result property="id" column="user_id_"/>
+		</collection>
+	</resultMap>
+    <select id="queryUserGroupList" resultMap="imGroupModel">
+		select ig.id_ group_id_,ig.name_ group_name_,#{transferUserId} user_id_,igm.role_type_ user_role_ from im_group ig
+		left join im_group_member igm ON igm.im_group_id_ = ig.id_
+		left join cooperation_organ co ON co.id_ = ig.school_id_
+		where ig.group_type_ = 'SCHOOL' and igm.role_type_ = #{roleType} and igm.user_id_ = #{userId}
+		<if test="organId != null">
+			and co.organ_id_ = #{organId}
+		</if>
+	</select>
+
+    <update id="updateSchoolRoleType">
         update im_group_member set role_type_ = #{userType.msg} ,type_ = #{userType.name}  where user_id_ = #{userId}
     </update>
 

+ 5 - 2
mec-biz/src/main/resources/config/mybatis/ImGroupNoticeMapper.xml

@@ -69,8 +69,11 @@
 		update_time_ = NOW()
 		</set> WHERE id_ = #{id} and tenant_id_ = #{tenantId}
 	</update>
-	
-	<!-- 根据主键删除一条记录 -->
+    <update id="updateTop">
+		UPDATE im_group_notice SET is_top_ = #{topFlag} WHERE im_group_id_ = #{imGroupId}
+	</update>
+
+    <!-- 根据主键删除一条记录 -->
 	<delete id="delete" >
 		DELETE FROM im_group_notice WHERE id_ = #{id} 
 	</delete>

+ 70 - 0
mec-biz/src/main/resources/config/mybatis/StudentCoursewarePlayRecordMapper.xml

@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE  mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
+<mapper namespace="com.ym.mec.biz.dal.mapper.StudentCoursewarePlayRecordMapper">
+    <select id="selectPage" resultType="com.ym.mec.biz.dal.entity.StudentCoursewarePlayRecord">
+        SELECT t.*
+        FROM student_courseware_play_record t
+    </select>
+
+    <insert id="save">
+        INSERT INTO student_courseware_play_record (organization_id_, user_id_, play_time_, create_date_, update_time_, create_time_)
+        VALUES (#{record.organizationId}, #{record.userId}, #{record.playTime}, #{record.createDate}, NOW(), NOW())
+        ON DUPLICATE KEY UPDATE play_time_ = (ifnull(play_time_, 0) + #{record.playTime})
+    </insert>
+
+    <select id="statList" resultType="com.ym.mec.biz.dal.wrapper.StudentCoursewarePlayRecordWrapper$StatQueryData">
+        select o.id_                                                                                             as organizationId
+             , o.name_                                                                                           as organizationName
+             , count(distinct s.user_id_)                                                                        as memberNum
+             , (count(distinct s.user_id_) - count(distinct pr.user_id_))                                        as noPlayNum
+             , count(distinct if(10 * 60 >= pr.play_time_, pr.user_id_, null))                                   as playTimeLess10
+             , count(distinct if(pr.play_time_ > 10 * 60 and 60 * 60 >= pr.play_time_, pr.user_id_, null))       as playTimeLess60
+             , count(distinct if(pr.play_time_ > 60 * 60 and 120 * 60 >= pr.play_time_, pr.user_id_, null))      as playTimeLess120
+             , count(distinct if(pr.play_time_ > 120 * 60 and 240 * 60 >= pr.play_time_, pr.user_id_, null))     as playTimeLess240
+             , count(distinct if(pr.play_time_ > 240 * 60, pr.user_id_, null))                                   as playTimeRather240
+             , if(count(distinct pr.user_id_) = 0, 0, (sum(pr.play_time_) / (count(distinct pr.user_id_) * 60))) as avgPlayTime
+        from organization o
+                 left join sys_user su on o.id_ = su.organ_id_
+                 left join student s on s.user_id_ = su.id_
+                 left join (select user_id_, sum(play_time_) play_time_
+                            from student_courseware_play_record
+                            where create_time_ > #{statQuery.startTime}
+                              and #{statQuery.endTime} > create_time_
+                            group by user_id_) pr on s.user_id_ = pr.user_id_
+        <where>
+            s.membership_end_time_ >= now()
+            <if test="statQuery.organizationId != null and statQuery.organizationId.trim() !=''">
+                and find_in_set(o.id_,#{statQuery.organizationId})
+            </if>
+        </where>
+        group by o.id_
+        order by ${statQuery.sortBy}
+    </select>
+    <select id="statDetailPage" resultType="com.ym.mec.biz.dal.wrapper.StudentCoursewarePlayRecordWrapper$StatQueryData">
+        select o.id_                                                                                             as organizationId
+             , o.name_                                                                                           as organizationName
+             , su2.username_                                                                                     as teacherName
+             , count(distinct s.user_id_)                                                                        as memberNum
+             , (count(distinct s.user_id_) - count(distinct pr.user_id_))                                        as noPlayNum
+             , count(distinct if(10 * 60 >= pr.play_time_, pr.user_id_, null))                                   as playTimeLess10
+             , count(distinct if(pr.play_time_ > 10 * 60 and 60 * 60 >= pr.play_time_, pr.user_id_, null))       as playTimeLess60
+             , count(distinct if(pr.play_time_ > 60 * 60 and 120 * 60 >= pr.play_time_, pr.user_id_, null))      as playTimeLess120
+             , count(distinct if(pr.play_time_ > 120 * 60 and 240 * 60 >= pr.play_time_, pr.user_id_, null))     as playTimeLess240
+             , count(distinct if(pr.play_time_ > 240 * 60, pr.user_id_, null))                                   as playTimeRather240
+             , if(count(distinct pr.user_id_) = 0, 0, (sum(pr.play_time_) / (count(distinct pr.user_id_) * 60))) as avgPlayTime
+        from organization o
+                 left join sys_user su on su.organ_id_ = o.id_
+                 left join student s on s.user_id_ = su.id_
+                 left join student_teacher_mapper stm on stm.student_id_ = s.user_id_
+                 left join sys_user su2 on su2.id_ = stm.teacher_id_
+                 left join (select user_id_, sum(play_time_) play_time_
+                            from student_courseware_play_record
+                            where create_time_ > #{statQuery.startTime}
+                              and #{statQuery.endTime} > create_time_
+                            group by user_id_) pr on s.user_id_ = pr.user_id_
+        where o.id_ = #{statQuery.organizationId}
+          and s.membership_end_time_ >= now() and stm.id_ is not null
+        group by stm.teacher_id_
+        order by ${statQuery.sortBy}
+    </select>
+</mapper>